[comp.sys.m6809] direct page variable documentation

ingoldsby@calgary.UUCP (Terry Ingoldsby) (01/20/87)

Some time ago I was asking for explanations of the direct page variables.
A friend of mine who is an OS9 guru whipped up the following informal
(and not guaranteed) information.  I'm posting it to the net since others
may be interested.

Also, I've had no answers to my questions on the ACIA device driver found
in Peter Dibble's book.  Peter, are you listening?

Anyway, thanks to Caveh Jalali, here are the DP docs:


************************************************************
*
*     direct page variable definitions
*
* i'll try to clarify a few variables by appending a :1 or :2 to indicate a 2
* byte quantity respectively e.g.  d.fmbm:2 refers to a 16 bit value (ptr in
* this case) and d.fmbm+2:2 is also a 16 bit quantity but at d.fmbm+2.
* also, i may refer to os9 level 1 as L1 and level1 revision 2.0.0 as L1r2
*
* i'll mention system mode and user mode quite frequently.
* on the coco, these are software concenpts only; the hardware is too stupid
* (cheap?) to make a distinction between the two.  System mode refers to
* the cpu when it is running kernel code such as device drivers, interrupt
* handlers, executing system calls, and so on -- basically anything which
* the user relies on as being there before he runs his own code.
* when a user program is executing, we are in the user mode.
* being in the system mode allows you to execute a few extra system calls
* which are considered 'privileged', as well as changing the action of a
* few system calls -- it is erroneous to beleive that a system call
* behaves identically in ... say a device driver (system mode) and a
* user program (user state).
* there are many instances where os9 switches between user/system mode.
* here are a few such events:
* - beginning of every system call
* - end of every system call
* - beginning of every interrupt servicing routine
* - end of interrup servicing routine
* as far as doing a state transition for interrupt servicing, it is not
* done automatically.  that is why it is important to user f$poll to install
* a irq service routine -- f$poll takes care of the state switching for you.
*
* what's actually involved in state switches?
* basically, os9 changes the interrupt vector (IRQ), and the system
* call vectors to different routines, so that os9 doesn't do something
* as stupid as switching from system state to system state, or user->user.
* also, the system call vectors are changed, since some system calls
* must behave somewhat differently in the system state than user state.
* this is done by changing a pointer to the approprate table, not changing
* each entry in the table of system call entry points.
*
*


 org $20 reserve first 32 bytes
d.fmbm rmb 4 free memory bit map pointers
    d.fmbm:2 is the start of table
    d.fmbm+2:2 is end of table
    these are the bounds of a (32 byte table - 256 bits on Level1)
    which are used for memory allocation and deallocation -- each bit
    corresponds to a os9 (256 byte)page.  Think of this as being
    manipulated by f$delbit, f$allbit, etc. even tho this is not
    always the case.

d.mlim rmb 2 memory limit
    probably intended to be the upper bound of RAM.  On the coco, it is
    initially the base address where the os9 kernel resides (ie os9,
    os9p2, init & boot), but at some point becomes the base address where
    the os9boot file is loaded -- this is probably done by the boot module.

d.moddir rmb 4 module directory
    d.moddir:2 starting address of module directory.
    d.moddir+2:2 end address of module directory
    this is essentially an array of the following structure
    struct moddir_entry {
        module  *address;       // if zero, this is an empty slot
        char    unused;         // always 0
        char    link_count;
    }

d.init rmb 2 rom base address
    address of init module.  Would be same as register U after f$link
    to init.

* the next few are interrupt vectors.  no mysteries here, i hope.
* maybe i'll say that on L1r2, the hardware (rom) vectors point to the
* fexx page, from there, we branch to the 01xx page (where the hardware
* vectors used to point, and then from there, we do an indirect jump
* thru the d.xxxx vectors

d.swi3 rmb 2 swi3 vector
d.swi2 rmb 2 swi2 vector
d.firq rmb 2 firq vector
d.irq rmb 2 irq vector
d.swi rmb 2 swi vector
d.nmi rmb 2 nmi vector

d.svcirq rmb 2 interrupt service entry
    interrupt handling routine.  this vector changes depending on whether os9
    is in system mode or user mode.-- ie it is loaded with d.sysirq whenever
    you do a system call/or an interrupt is serviced, and when a user program
    is executing, it contains the value of d.usrirq.

d.poll rmb 2 interrupt polling routine
    interrupt polling routine.  called by the same "moment" as the clock
    routine.

d.usrirq rmb 2 user irq routine
    d.usrirq interrupt servicing routine when a user process is running.

d.sysirq rmb 2 system irq routine
    d.sysirq interrupt servicing routine when os9 is not running a user
    process (this includes executing a system call issued by a user)
    essentially, this inhibits the context-switching code from running,
    as well as doing a user -> sys state stransition, since you are
    already in system mode (particularly when servicing interrupts)
    Note: let me emphasize that NO context switches occur while os9 is
    running in the system state, unless specifically requested (for
    example, by a f$sleep)

d.usrsvc rmb 2 user service request routine
    routine which picks the post-byte from the swi instruction and interprets
    it as the system call number by using it as an index into an array
    of pointers to the respective functions.  Note that a user<->system state
    transition also occurs for the duration of the system call.

d.syssvc rmb 2 system service request routine
    as above, but does not do a user->system state transition.
    (and back to user after system call is done)

d.usrdis rmb 2 user service request dispatch table
    points to an array of pointers which are pointers to the system call
    handling routines each element in the array points to a particular
    handling routine; the index into the array is determined by the system
    call number.

d.sysdis rmb 2 system service request dispatch table
    as above, but points to a different array, which points to the system
    state system calls.  OS9 distinguishes between some system calls
    depending on whether they were issued in user mode or system mode.
    for example i$open returns a path number in the range of 0..15, which
    is an index into the process descriptor, from which the system path
    number is obtained.  if you were already in system mode, i$open
    would return the system path number, not the index into the process
    descriptor.  then there are the privileged system calls.  they only
    appear in array pointed to by d.sysdis.
    if the pointer in the d.sysdis array is 0, then the system call
    does not exist -- appropriate error returned, of course.

d.slice rmb 1 process time slice count
    number of ticks the current process has been alotted since it was
    made active.

d.prcdbt rmb 2 process descriptor block address
    pointer to the 0-block of the process descriptors... see f$all64,
    f$ret64, f$find64 for description of the structure(s) involved.

d.proc rmb 2 process descriptor address
    pointer to the process descriptor of the current process.
    if 0, no process running (may infer from this that the cpu is idle,
    or in the process of switching between processes)

d.aprocq rmb 2 active process queue
    linked list of processes which are in the "run" state

d.wprocq rmb 2 waiting process queue
    linked list of procs in the "waiting" state ie just done a f$wait
    these procs are awakened when their child proc exits

d.sprocq rmb 2 sleeping process queue
    sleeping proc.  process is either sleeping indefinitely or is doing
    a timed sleep.  register X on that procs's stack is used as the actual
    counter for the sleeping process.  there is a process state bit which
    indicates whether the process is sleeping indefinitely or not.

NOTE: unlink UNIX, where you just look thru an array of proc structures,
    on OS9, you have to go thru these 3 linked lists to find all the
    processes on the system, which still does not include your own process,
    as your process ptr is in d.proc.  Whenever a process is pointed to
    by d.proc, it is not in any of these lists.

d.time equ . time
d.year rmb 1
d.month rmb 1
d.day rmb 1
d.hour rmb 1
d.min rmb 1
d.sec rmb 1
d.tick rmb 1
    more precise counter for d.sec. on the coco 60 of these cause an inc
    of d.sec

d.tsec rmb 1 ticks / second
    60 ticks/sec

d.tslice rmb 1 ticks / time-slice
    process will get a maximun of d.tslice ticks before another process is
    considered to be made active.  this is 6 on the coco... so every
    100ms, another process is run (if there is another active process)
    this value puts a lower bound on the nubmer of context switches that
    occur in a second.  It does not force an exact number of context
    switches, since a (essentially) every time a process goes to sleep
    it forces a context switch.
    Note:  a value of 6 is pretty silly on the coco.  If you want some
    decent keyboard response when you have more than 1 procses running,
    it is a very good idea to set this value to ... say 3.
    If the process happens to be ding disk IO on the RS floppy controller,
    you won't get (much) keyboard response no matter what you do; but for
    those who are have their coco set up with a 56K/448K ramdisk, or a
    decent disk controller (hard disk?) you can just change this value
    at any time without consequence.

d.ioml rmb 2 i/o mgr free memory low bound
    not used to my knowledge

d.iomh rmb 2 i/o mgr free memory hi  bound
    not used to my knowledge

d.devtbl rmb 2 device driver table addr
    pointer to device table.  array of (9 on coco) elements.  each element
    is a device table.  essentially every open device has an entry here
    (one/device driver, not per device as such)

d.poltbl rmb 2 irq polling table addr
    array which is interpreted by interrupt polling routine to check
    on the hardware bits desired

d.pthdbt rmb 2 path descriptor block table addr
    pointer to 0-block of the path descriptors.   f$all64/f$del64/f$find64
    are used with this pointer to get to the correct path descriptor.

d.btlo rmb 2 bootstrap low address
    base address where os9boot file was loaded.
    no module beyond this address will get removed from module directory.

d.bthi rmb 2 bootstrap hi address
    highest address where os9boot file was loaded

d.dmareq rmb 1 dma in use flag
    You see a dma chip in the coco?  HINT: there isn't one.

d.altirq rmb 2 alternate irq vector (cc)
    used by ccio -- this stuff is a bit messy.  if i remember correctly
    ccio jumps thru here to get to the next link of the daisy-chained
    interrupt servicing routines.

d.kbdsta rmb 2 keyboard scanner static storage (cc)
    value of U register pointing to the static storage of ccio (V.xxx region)

d.dsktmr rmb 2 disk motor timer (cc)
    counter for disk motor... probably made obsolete by f$virq.  i don't
    use it in my disk drvier since f$virq came on the scene, but RS may
    still use it?
    NOTE: i had to put f$virq in ioman, so that it would be "there" before
    the ccdisk was initialized; normally it is installed by sysgo.

d.cbstrt rmb 16 reserved for cc warmstart ($71)
    color basic rom looks in this are for a pair of nop's, also contains
    code which switches to 64K mode, as well as jumping to the appropriate
    address in the kernel for a reboot? right into os9, i think.

d.clock rmb 2 address of clock tick routine (cc)
    i think this is actually the scheduler, not the clock routine... anyway
    called every 1/60 sec.

d.boot rmb 1 bootstrap attempted flag
    new flag.  it seems this is used to flag a failed boot... ie if there
    is a failure to boot, this flag is set, so that os9 doesn't try to
    reboot at infinidum???

d.urtoss rmb 2 address of user to system routine (virq)
    new with L1r2.  routine which switches from user mode to system mode.

d.cltb rmb 2 pointer to clock interrupt table (virq)
    virq entries go here.



---end---

							caveh.


````````````````````````````````````````````````````````````````````
                                       Terry Ingoldsby
...!ihnp4!alberta!calgary!ingoldsby