.title Autout .ident /X01.06/ ;+ ; **-Autout-Autoload overlay loading and mapping routine with logging ; ; Version X01.06 ; ; Wayne E. Baisley April 21, 1982 ; ; This module is Auto with the addition of code to log every autoload ; call via the AUT... task. ; ; 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$, orddf$, owddf$ .mcall clef$s, dsar$s, enar$s, rdaf$s, sdat$s, setf$s, stse$s, wtse$s alodf$ ;define the segment descriptor symbols ioerr$ ;define the I/O error codes (IS.SUC) orddf$ ;define the autoload rdb symbols owddf$ ;define the autoload wdb symbols autflg = 31. ;overlay load event flag, borrowed for - ;synchronization with the AUT... task .list meb .page ; ; The logging section sends AUT... a packet with the following data : ; ; +-------------------------------+ ; 0 | Status | Segment, Window and Region ; +-------------------------------+ ; 2 | Autoload Vector Address | ; +-------------------------------+ ; 4 | Called Entry Point | ; +-------------------------------+ ; 6 | Segment Name | ; +--- in ---+ ; 10 | Radix-50 | ; +-------------------------------+ ; 12 | Region Name | If applicable ; +--- in ---+ ; 14 | Radix-50 | ; +-------------------------------+ ; 16 | Directive Status Word | ; +-------------------------------+ ; 20 | Task Local | ; +--- Event ---+ ; 22 | Flags | ; +-------------------------------+ ; 24 | Global | ; +--- Event ---+ ; 26 | Flags | ; +-------------------------------+ ; 30 | Synchronization Event Flag # | ; +-------------------------------+ ; ; The status word is composed of the following flag bits : ; ; 100000 = Routine is being called from AST level ; 40000 = Segment is not disk-resident ; 20000 = Segment is currently in memory ; 10000 = Segment is not loaded and/or not mapped ; 4000 = Segment has an external window ; 2000 = This segment's window is mapped ; 1000 = This segment's region is mapped ; ; After sending off the data message, this routine waits for ; AUT... to set the overlay load event flag (31.). This ac- ; tion avoids excessive pool usage. ; .psect aut... aut...: .rad50 *AUT...* ;receiver's task name .page .psect $$auto .enabl lsb $auto:: ; ; Send off a message to AUT... ; mov r0,-(sp) ;free a register - mov r1,-(sp) ;or two mov 4(sp),r1 ;get the autoload vector 2nd half address tst -(sp) ;make room for the dsar$s status later mov #autflg,-(sp) ;plug in the flag we're waiting on sub #<4*2>,sp ;make room for the event flags mov sp,r0 ;copy the address mov @#$dsw,-(sp) ;record the current directive status dsar$s ;disable AST's for now mov @#$dsw,<6*2>(sp) ;remember whether they were already so rdaf$s r0 ;get the event flags clr -(sp) ;blank the segment and region name areas ... clr -(sp) ; clr -(sp) ; clr -(sp) ; mov 2(r1),-(sp) ;copy the target routine's virtual address mov r1,-(sp) ;set up the original autoload - sub #4,(sp) ;transfer vector address mov (r1),r1 ;pick up the segment descriptor address mov (r1),-(sp) ;copy the segment's status bic #ss.rda!100000,(sp) ;wipe out the disk address field and trash mov @#n.ovpt,r0 ;pick up the work area address mov n.szsg(r0),r0 ;determine how much optional - sub #s.name,r0 ;data we have beq 40$ ;if eq there is none; no region name, etc. mov s.name+0(r1), 6(sp) ;otherwise, copy the segment name ... mov s.name+2(r1),10(sp) ; cmp r0,#s.lgth-s.name ;were any wdb's allocated ? blo 40$ ;if lo no, we're done mov s.pwdb(r1),r1 ;pick up the wdb address beq 40$ ;if eq there isn't one bis #4000,(sp) ;otherwise, indicate the extra data bit #wf.map,w.nflg(r1) ;is this window mapped ? beq 20$ ;if eq no bis #2000,(sp) ;otherwise, mark it for the send 20$: .page mov w.nrda(r1),r1 ;pick up the rdb address beq 40$ ;if eq there isn't one mov r.gnam+0(r1),12(sp) ;otherwise, copy the region name ... mov r.gnam+2(r1),14(sp) ; bit #rf.map,r.gflg(r1) ;is this region mapped ? beq 40$ ;if eq no bis #1000,(sp) ;otherwise, mark it for the send 40$: mov sp,r0 ;copy the send data buffer address setf$s #autflg ;set the event flag stse$s #autflg ;stop for the event flag bcc 60$ ;if cc we didn't stop for long bis #100000,(sp) ;otherwise, we must be at AST state 60$: clef$s #autflg ;clear the event flag sdat$s #aut...,r0 ;ship it off bcs 80$ ;if cs AUT... must not be installed wtse$s #autflg ;otherwise, wait for AUT... to wake us 80$: add #<13.*2>,sp ;clean up our mess cmp (sp)+,#is.suc ;were AST's previously disabled ? bne 100$ ;if ne no enar$s ;otherwise, re-enable them 100$: mov (sp)+,r1 ;restore the registers ... mov (sp)+,r0 ; .dsabl lsb .enabl lsb ; ; Now do the normal autoload magic ... ; mov @(sp),-(sp) ;fetch the segment descriptor address tst @(sp) ;does this look like a segment descriptor ? bmi 10$ ;if mi yes iot ;otherwise, ego thneisko ! 10$: 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