.title Auto .ident /X08/ ;+ ; **-Auto-Autoload overlay loading and mapping routine ; ; Version X08 ; ; Wayne E. Baisley April 13, 1982 ; ; Modified to disable AST's while segment descriptors are changing. ; ; This routine is called from the autoload transfer vectors set up by ; the Task Builder in the $$ALVC psect. The autoload vectors have the ; following format: ; ; ; +-------------------------------+ ; 0 | | ; +-- JSR @#$AUTO --+ ; 2 | | ; +-------------------------------+ ; 4 | Segment Descriptor Address | ; +-------------------------------+ ; 6 | Virtual Entry Point Address | ; +-------------------------------+ ; ; Inputs: ; ; 0(sp)=Address of 2nd half of autoload vector ; 2(sp)=Return address of caller of autoloaded routine ; ; Outputs: ; ; Loads and maps the routine, if required, and cleans the stack ; .page ; ; The Segment Descriptors, which are created by the Task Builder in the ; $$SGD0 psect, have the following format : ; ; +--------+----------------------+ ; 0 | Status | Relative Disk Address| s.stat ; +--------+----------------------+ ; 2 | Load Address | s.addr ; +-------------------------------+ ; 4 | Length in Bytes | s.size ; +-------------------------------+ ; 6 | Link Up (away from root) | s.lkup ; +-------------------------------+ ; 10 | Link Down (toward root) | s.lkdn ; +-------------------------------+ ; 12 | Link Next (to neighbor) | s.lknt ; +-------------------------------+ ; 14 | Segment Name | s.name * ; +--- in ---+ ; 16 | Radix-50 | ; +-------------------------------+ ; 20 | Window Descriptor Address | s.pwdb * ; +-------------------------------+ ; ; * - The Segment Name is appended only if the manual load routine ; ($Load) is used or if memory-resident overlays are included, ; in which case the Window Descriptor Address is also appended. ; ; The status nibble is composed of the following flag bits : ; ; 100000 = Always set to 1 ; 40000 = (ss.nal) Segment has no disk allocation ; 20000 = (ss.dsk) Segment has been loaded from disk ; 10000 = (ss.nld) Segment is not loaded ; .page ; ; The Window Descriptors, which are created by the Task Builder in the ; $$WNDS psect, have the following format : ; ; +---------------+---------------+ ; 0, 1 | Base APR | Window ID | w.nid, w.napr ; +---------------+---------------+ ; 2 | Virtual Base Address | w.nbas ; +-------------------------------+ ; 4 | Window Size in 64-byte blocks | w.nsiz ; +-------------------------------+ ; 6 | Region ID | w.nrid ; +-------------------------------+ ; 10 | Offset in Partition | w.noff ; +-------------------------------+ ; 12 | Length to Map | w.nlen ; +-------------------------------+ ; 14 | Status Word | w.nsts ; +-------------------------------+ ; 16 | Send/Receive Buffer Addr = 0 | w.nsrb ; +-------------------------------+ ; 20 | Flags Word | w.nflg * ; +-------------------------------+ ; 22 | Region Descriptor Address | w.nrda * ; +-------------------------------+ ; ; The first eight words of the Window Descriptor structure constitute ; a standard RSX-11M/M+ Window Descriptor Block, which is used in the ; window mapping directives for memory-resident overlays. If an over- ; lay is part of the task, the Region ID is zero, and the Region Des- ; criptor Address is zero if one has not (yet?) been allocated. For a ; memory-resident overlay in a shared region, there will be a Region ; Descriptor and the Region ID is copied from it whenever the region ; is attached. ; ; * - The Flags Word and Region Descriptor Address are always included ; in this structure by the Task Builder. The flag WF.MAP (bit 15) is ; set whenever this window (and consequently its region) is mapped. ; .page ; ; The Region Descriptors, which are created by the Task Builder in the ; $$RGDS psect, have the following format : ; ; +-------------------------------+ ; 0 | Region ID | r.gid ; +-------------------------------+ ; 2 | Region Size in 64-byte blocks | r.gsiz ; +-------------------------------+ ; 4 | Region Name | r.gnam ; +--- in ---+ ; 6 | Radix-50 | ; +-------------------------------+ ; 10 | Partition Name | r.gpar ; +--- in ---+ ; 12 | Radix-50 | ; +-------------------------------+ ; 14 | Region Status | r.gsts ; +-------------------------------+ ; 16 | Protection Codes = 0 | r.gpro ; +-------------------------------+ ; 20 | Flags Word | r.gflg * ; +-------------------------------+ ; ; * - The Flags Word is always included in this structure by the ; Task Builder. The flag RF.MAP (bit 15) is set whenever this ; region is mapped. ;- .mcall alodf$, ioerr$, dsar$s, enar$s alodf$ ;define the segment descriptor symbols ioerr$ ;define the I/O error codes (IS.SUC) .list meb .psect $$auto .enabl lsb $auto:: mov @(sp),-(sp) ;fetch the segment descriptor address bit #ss.nld,@(sp)+ ;is this segment not mapped or loaded ? bne 20$ ;if ne no, we must do so add #2,(sp) ;otherwise, point to the routine's addr $albp1:: mov @(sp)+,pc ;jump very indirectly .page ; ; Load we must ; 20$: jsr r5,$savrg ;save the non-volatile registers (3-5) dsar$s ;don't let any AST's disturb us mov @#$dsw,-(sp) ;save the status for later on mov r2,-(sp) ;save r2 also mov 14(sp),r5 ;fetch the saved autoload vector addr mov (r5)+,r2 ;pick up the segment descriptor address mov (r5),14(sp) ;set up the routine's addr for return call $markr ;unmap anything that's in the way ; ; Map every segment we need ; 40$: clr r3 ;let $rdseg use the default Event Flag clr r4 ;let $rdseg use the default IOSB clr r5 ;let $rdseg use the default AST tst s.size(r2) ;is this a zero-length segment ? bne 60$ ;if ne obviously not bic #ss.nld,(r2) ;otherwise, it's as good as loaded br 80$ ;go on to the next neighbor 60$: call $rdseg ;attempt to load and/or map the segment bcc 80$ ;if cc we have done so mov @#n.ovpt,r3 ;fetch the overlay work area address call @n.aler(r3) ;call the error handling routine br 40$ ;if we return it must not have been bad 80$: mov s.lkdn(r2),r2 ;move a step closer to the window's root beq 100$ ;if eq we've already done the root bit #ss.nld,(r2) ;is this segment loaded and mapped ? bne 40$ ;if ne no, go do this one also br 80$ ;otherwise, look deeper 100$: mov (sp)+,r2 ;restore r2 cmp (sp)+,#is.suc ;did we really disable AST's earlier ? bne $albp2 ;if ne no; must have been in an AST enar$s ;otherwise, unleash them $albp2:: return ;clean up the stack and call the routine .psect $$mrks ro,ovr $markr: ;sneaky non-reference to $markr routine .psect $$rdsg ro,ovr $rdseg: ;sneaky non-reference to $$rdsg code .end