;+ ; TITLE: OV??? - COMMON SECTION FOR THE VARIOUS OVERLAY ; CONTROL ROUTINES : ; OVCTA -- ALL OVERLAYS, CLUSTERS AND AST/SST ; OVCTC -- ALL OVERLAYS AND CLUSTER LIBRARIES ; OVCTE -- DISK-RESIDENT AND AST/SST OVERLAYS ; OVCTL -- DISK-RESIDENT OVERLAYS ONLY ; OVCTR -- DISK- AND MEMORY-RESIDENT OVERLAYS ; OVIDA -- OVCTA FOR SEPARATE I- AND D-SPACE ; OVIDC -- OVCTC FOR SEPARATE I- AND D-SPACE ; OVIDE -- OVCTE FOR SEPARATE I- AND D-SPACE ; OVIDL -- OVCTL FOR SEPARATE I- AND D-SPACE ; OVIDR -- OVCTR FOR SEPARATE I- AND D-SPACE ; VERSION: X15.05 ; SOFTWARE TREE: ZSYSLB.STS ; SYSTEM: Development System ; SUBSYSTEM: SYSTEM LIBRARIES ; SOURCE FILE: OVCOM.MAC ; PROGRAMMER: Wayne E. Baisley ; DATE: March 13, 1984 ; ; ; REVISION DATE PROGRAMMER DESCRIPTION ; -------- -------- -------------- ----------------------------- ; ; 1) WB100 01/31/83 W. E. Baisley Modified to shove the I/O status ; into $DSW on fatal errors, so it ; will be displayed by $ALERR. ; ; 2) WB120 03/12/84 W. E. Baisley Completely new release based on ; RSX-11M V4.1/M+ V2.1. ; ; 3) WB140 03/13/84 W. E. Baisley Merge OVCTC/OVCTL/OVCTR/OVIDC/- ; OVIDL/OVIDR into one conditionally- ; assembled source file. ; ; 4) 11/12/84 W. E. Baisley Add ENTRAP conditional code (Modules ; OVCTA/OVCTE/OVIDA/OVIDE) ; ; 5) 11/30/84 W. E. Baisley Fix CLUSTER and ENTRAP conditionalization ; (it must be done DEC's way and mine). ; ; Notes: There are several conditional-assembly flags for this module, to ; support the 10 varieties needed : ; ; PLAS Defined if memory-resident overlays are supported ; ; ENTRAP Defined if overlaid AST/SST routines are supported ; ; CLUSTER Defined if Cluster libraries are supported (PLAS ; must be defined for this flag to have any effect.) ; ; IDSPACE Defined if separate I- and D-Spaces are supported ; (May be used with any valid combination of PLAS and ; CLUSTER.) ; ; There are several "internal" conditional-assembly flags which control ; the optimization of various instruction sequences for this module. ; These sequences will likely have to change for future versions : ; ; FLAGS Defined if the Flags Word extensions to the Window and ; Region Descriptors contain a single flag and can thus ; be manipulated on a word basis. ; ; LOWER Defined if the varieties of support produced by this ; module should check for use by tasks built for a ; lesser level of support. That is, the PLAS versions ; should not assume that the calling task was built with ; Region Descriptors that are (at least) 9 words long. ; This flag should be defined if a version of this ; module is to be made the common version in a resident ; (unoverlaid!) library. ;- .nlist toc .Sbttl Version X15.05 .if df PLAS .if df CLUSTER .if df IDSPACE .if df ENTRAP .list .Title OVIDA .nlist .iff ;if df ENTRAP .list .Title OVIDC .nlist .endc ;if df ENTRAP .iff ;if df IDSPACE .if df ENTRAP .list .Title OVCTA .nlist .iff ;if df ENTRAP .list .Title OVCTC .nlist .endc ;if df ENTRAP .endc ;if df IDSPACE .iff ;if df CLUSTER .if df IDSPACE .list .Title OVIDR .nlist .iff ;if df IDSPACE .list .Title OVCTR .nlist .endc ;if df IDSPACE .endc ;if df CLUSTER .iff ;if df PLAS .if df IDSPACE .if df ENTRAP .list .Title OVIDE .nlist .iff ;if df ENTRAP .list .Title OVIDL .nlist .endc ;if df ENTRAP .iff ;if df IDSPACE .if df ENTRAP .list .Title OVCTE .nlist .iff ;if df ENTRAP .list .Title OVCTL .nlist .endc ;if df ENTRAP .endc ;if df IDSPACE .endc ;if df PLAS .list .Ident /X15.05/ ;+ .nlist .if df PLAS .if df CLUSTER .if df IDSPACE .if df ENTRAP .list ; TITLE: OVIDA - OVERLAY CONTROL ROUTINES FOR (UN)LOADING ; AND (UN)MAPPING SEGMENTS FOR TASKS WITH MEMORY- ; RESIDENT OVERLAYS, CLUSTER LIBRARIES, OVERLAID ; AST/SST ROUTINES, AND SEPARATE I- AND D-SPACES .nlist .iff ;if df ENTRAP .list ; TITLE: OVIDC - OVERLAY CONTROL ROUTINES FOR (UN)LOADING ; AND (UN)MAPPING SEGMENTS FOR TASKS WITH MEMORY- ; RESIDENT OVERLAYS, CLUSTER LIBRARIES, AND SEPARATE ; I- AND D-SPACES .nlist .endc ;if df ENTRAP .iff ;if df IDSPACE .if df ENTRAP .list ; TITLE: OVCTA - OVERLAY CONTROL ROUTINES FOR (UN)LOADING ; AND (UN)MAPPING SEGMENTS FOR TASKS WITH MEMORY- ; RESIDENT OVERLAYS, CLUSTER LIBRARIES AND OVERLAID ; AST/SST ROUTINES, BUT WITHOUT SEPARATE I- ; AND D-SPACES .nlist .iff ;if df ENTRAP .list ; TITLE: OVCTC - OVERLAY CONTROL ROUTINES FOR (UN)LOADING ; AND (UN)MAPPING SEGMENTS FOR TASKS WITH MEMORY- ; RESIDENT OVERLAYS AND CLUSTER LIBRARIES, BUT ; WITHOUT SEPARATE I- AND D-SPACES .nlist .endc ;if df ENTRAP .endc ;if df IDSPACE .iff ;if df CLUSTER .if df IDSPACE .list ; TITLE: OVIDR - OVERLAY CONTROL ROUTINES FOR (UN)LOADING ; AND (UN)MAPPING SEGMENTS FOR TASKS WITH MEMORY- ; RESIDENT OVERLAYS AND SEPARATE I- AND D-SPACES, ; BUT WITHOUT CLUSTER LIBRARIES .nlist .iff ;if df IDSPACE .list ; TITLE: OVCTR - OVERLAY CONTROL ROUTINES FOR (UN)LOADING ; AND (UN)MAPPING SEGMENTS FOR TASKS WITH MEMORY- ; RESIDENT OVERLAYS, BUT WITHOUT SEPARATE I- AND D- ; SPACES OR CLUSTER LIBRARIES .nlist .endc ;if df IDSPACE .endc ;if df CLUSTER .iff ;if df PLAS .if df IDSPACE .if df ENTRAP .list ; TITLE: OVIDE - OVERLAY CONTROL ROUTINES FOR LOADING ; AND UNLOADING SEGMENTS FOR TASKS WITH SEPARATE ; I- AND D-SPACES AND OVERLAID AST/SST ROUTINES, ; BUT WITHOUT MEMORY-RESIDENT OVERLAYS OR CLUSTER ; LIBRARIES ; .nlist .iff ;if df ENTRAP .list ; TITLE: OVIDL - OVERLAY CONTROL ROUTINES FOR LOADING ; AND UNLOADING SEGMENTS FOR TASKS WITH SEPARATE ; I- AND D-SPACES, BUT WITHOUT MEMORY-RESIDENT ; OVERLAYS OR CLUSTER LIBRARIES ; .nlist .endc ;if df ENTRAP .iff ;if df IDSPACE .if df ENTRAP .list ; TITLE: OVCTE - OVERLAY CONTROL ROUTINES FOR LOADING ; AND UNLOADING SEGMENTS FOR TASKS WITH OVERLAID ; AST/SST ROUTINES, BUT WITH NO MEMORY-RESIDENT ; OVERLAYS OR CLUSTER LIBRARIES, AND NO SEPARATE ; I- AND D-SPACES .nlist .iff ;if df ENTRAP .list ; TITLE: OVCTL - OVERLAY CONTROL ROUTINES FOR LOADING ; AND UNLOADING SEGMENTS FOR TASKS WITH NO MEMORY- ; RESIDENT OVERLAYS OR CLUSTER LIBRARIES, AND NO ; SEPARATE I- AND D-SPACES .nlist .endc ;if df ENTRAP .endc ;if df IDSPACE .endc ;if df PLAS .list ; VERSION: X15.05 ; SOFTWARE TREE: ZSYSLB.STS ; SYSTEM: Development System ; SUBSYSTEM: SYSTEM LIBRARIES .nlist .if df PLAS .if df CLUSTER .if df IDSPACE .if df ENTRAP .list ; SOURCE FILES: OVIDA.MAC, OVCOM.MAC .nlist .iff ;if df ENTRAP .list ; SOURCE FILES: OVIDC.MAC, OVCOM.MAC .nlist .endc ;if df ENTRAP .iff ;if df IDSPACE .if df ENTRAP .list ; SOURCE FILES: OVCTA.MAC, OVCOM.MAC .nlist .iff ;if df ENTRAP .list ; SOURCE FILES: OVCTC.MAC, OVCOM.MAC .nlist .endc ;if df ENTRAP .endc ;if df IDSPACE .iff ;if df CLUSTER .if df IDSPACE .list ; SOURCE FILES: OVIDR.MAC, OVCOM.MAC .nlist .iff ;if df IDSPACE .list ; SOURCE FILES: OVCTR.MAC, OVCOM.MAC .nlist .endc ;if df IDSPACE .endc ;if df CLUSTER .iff ;if df PLAS .if df IDSPACE .if df ENTRAP .list ; SOURCE FILES: OVIDE.MAC, OVCOM.MAC .nlist .iff ;if df ENTRAP .list ; SOURCE FILES: OVIDL.MAC, OVCOM.MAC .nlist .endc ;if df ENTRAP .iff ;if df IDSPACE .if df ENTRAP .list ; SOURCE FILES: OVCTE.MAC, OVCOM.MAC .nlist .iff ;if df ENTRAP .list ; SOURCE FILES: OVCTL.MAC, OVCOM.MAC .nlist .endc ;if df ENTRAP .endc ;if df IDSPACE .endc ;if df PLAS .list ; PROGRAMMER: Wayne E. Baisley ; DATE: March 19, 1984 ; ; REVISION DATE PROGRAMMER DESCRIPTION ; -------- -------- -------------- ----------------------------- ; ; 0) 11/12/84 W. E. Baisley Completely new release based on ; RSX-11M V4.1/RSX-11M-Plus V2.1. ; ; 1) 11/30/84 W. E. Baisley Fix CLUSTER and ENTRAP conditionalization ; (it must be done DEC's way and mine). ; .page ; ; This module contains three routines which are called by one of the various forms ; of the $auto routine : ; .nlist .if df PLAS .if df CLUSTER .if df IDSPACE .if df ENTRAP .list ; 1) $Marda - Find and unload all disk- and memory-resident and I- and D-Space ; segments which are in the way, preserving the Cluster Library and ; AST/SST overlay context where appropriate .nlist .iff ;if df ENTRAP .list ; 1) $Mardc - Find and unload all disk- and memory-resident and I- and D-Space ; segments which are in the way, preserving the Cluster Library ; overlay context where appropriate .nlist .endc ;if df ENTRAP .iff ;if df IDSPACE .if df ENTRAP .list ; 1) $Marka - Find and unload all disk- and memory-resident segments which are ; in the way, preserving the Cluster Library and AST/SST overlay ; context where appropriate .nlist .iff ;if df ENTRAP .list ; 1) $Markc - Find and unload all disk- and memory-resident segments which are ; in the way, preserving the Cluster Library overlay context where ; appropriate .nlist .endc ;if df ENTRAP .endc ;if df IDSPACE .iff ;if df CLUSTER .if df IDSPACE .list ; 1) $Mardr - Find and unload all disk- and memory-resident and I- and D-Space ; segments which are in the way .nlist .iff ;if df IDSPACE .list ; 1) $Markr - Find and unload all disk- and memory-resident segments which are ; in the way .nlist .endc ;if df IDSPACE .endc ;if df CLUSTER .iff ;if df PLAS .if df IDSPACE .if df ENTRAP .list ; 1) $Marde - Find and unload all disk-resident and I- and D-Space segments which ; are in the way, preserving the AST/SST overlay context where ; appropriate .nlist .iff ;if df ENTRAP .list ; 1) $Mards - Find and unload all disk-resident and I- and D-Space segments which ; are in the way .nlist .endc ;if df ENTRAP .iff ;if df IDSPACE .if df ENTRAP .list ; 1) $Marke - Find and unload all disk-resident segments which are in the way, ; preserving the AST/SST overlay context where appropriate .nlist .iff ;if df ENTRAP .list ; 1) $Marks - Find and unload all disk-resident segments which are in the way .nlist .endc ;if df ENTRAP .endc ;if df IDSPACE .endc ;if df PLAS .list ; ; Inputs: ; ; R1=Overlay impure work area address from N.OVPT ; R2=Overlay segment descriptor address for segment which is to be loaded .nlist .if df PLAS .list ; and/or mapped .nlist .iftf ;if df PLAS .list ; ; Outputs: ; ; None - All registers are preserved. ; .nlist .ift ;if df PLAS .list ; 2) $Rdseg - Load and/or map a specified segment (Path-loading is a function of the .nlist .iff ;if df PLAS .list ; 2) $Rdseg - Load a specified segment (Path-loading is a function of the .nlist .iftf ;if df PLAS .list ; $auto routine, not this routine) ; ; Inputs: ; ; R1=Overlay impure work area address from N.OVPT ; R2=Overlay segment descriptor address for segment which is to be loaded .nlist .ift ;if df PLAS .list ; and/or mapped .nlist .endc ;if df PLAS .if df IDSPACE .list ; ; Note : The default Event Flag and IOSB from the overlay run-time system work ; area are used for all Load Overlay QIO calls. .nlist .iff ;if df IDSPACE .list ; R3=Optional event flag number for the Load Overlay QIO ; R4=Optional I/O Status Block address for the Load Overlay QIO ; R5=Optional AST routine address for the Load Overlay QIO ; ; If R3 is zero, the default Event Flag (number 31.) is used. If both R3 and R4 ; are zero, the I/O Status Block in the overlay run-time system work area is used. .nlist .endc ;if df IDSPACE .list ; ; Outputs: ; ; The Carry Bit is set if an error is detected, in which case the $DSW has ; the directive error code (or the I/O error code, if the high byte is clear). ; .nlist .if df CLUSTER .if df ENTRAP .list ; 3) $Pdls - Push the displaced Cluster Library segment descriptor or the ; descriptor displaced by an AST/SST service routine on the segment ; stack, and restore the original overlay context on return from the ; Cluster Library or AST/SST service routine call .nlist .iff ;if df ENTRAP .list ; 3) $Pdls - Push the displaced Cluster Library segment descriptor on the segment ; stack, and restore the original overlay context on return from the ; Cluster Library call .nlist .iftf ;if df ENTRAP .list ; ; Inputs: ; ; R1=Overlay impure work area address from N.OVPT .nlist .ift ;if df ENTRAP .list ; R2=Overlay segment descriptor displaced by the Cluster Library or AST/SST call .nlist .iff ;if df ENTRAP .list ; R2=Overlay segment descriptor which was displaced by the Cluster Library call .nlist .endc ;if df ENTRAP .list ; ; Outputs: ; ; The Carry Bit returned by the Cluster Library routine is returned to the original ; caller after the original overlay context is restored .nlist .iff ;if df CLUSTER .if df PLAS .list ; 3) $Pdls - Call the $Alerr routine to report an Overlay Error (IE.OVR) .nlist .iff ;if df PLAS .if df ENTRAP .list ; 3) $Pdls - Push the segment descriptor displaced by an AST/SST service routine ; on the segment stack, and restore the original overlay context on ; return from the AST/SST service routine call ; ; Inputs: ; ; R1=Overlay impure work area address from N.OVPT ; R2=Overlay segment descriptor displaced by the AST/SST call ; ; Outputs: ; ; None .nlist .endc ;if df ENTRAP .endc ;if df PLAS .endc ;if df CLUSTER .list ; .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 .nlist .if df IDSPACE .list ; +--------+------------------+---+ ; 2 | Virtual Load Address | F | s.addr ! ; +---------------------------+---+ .nlist .iff ;if df IDSPACE .list ; +--------+----------------------+ ; 2 | Virtual Load Address | s.addr ; +-------------------------------+ .nlist .endc ;if df IDSPACE .list ; 4 | Segment 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 ; +-------------------------------+ .nlist .if df PLAS .list ; 14 | Segment Name | s.name .nlist .iff ;if df PLAS .if df IDSPACE .list ; 14 | Segment Name | s.name .nlist .iff ;if df IDSPACE .list ; 14 | Segment Name | s.name * .nlist .endc ;if df IDSPACE .iftf ;if df PLAS .list ; +--- in ---+ ; 16 | Radix-50 | ; +-------------------------------+ .nlist .ift ;if df PLAS .list ; 20 | Window Descriptor Address | s.pwdb * ; +-------------------------------+ .nlist .iff ;if df PLAS .if df IDSPACE .list ; 20 | Window Descriptor Address | s.pwdb * ; +-------------------------------+ .nlist .endc ;if df IDSPACE .iftf ;if df PLAS .if df IDSPACE .list ; ; For all task segments (as opposed to external region segments) a segment ; descriptor D-Space extension is provided : ; ; +--------+----------------------+ ; 22 | Unused | D-Space Disk Address | s.dsta ; +--------+----------------------+ ; 24 | D-Space Virtual Load Address | s.dadr ; +-------------------------------+ ; 26 |D-Space Segment Length in Bytes| s.dsiz + ; +-------------------------------+ ; 30 | D-Space Window Descriptor Addr| s.dwdb * ; +-------------------------------+ .nlist .endc ;if df IDSPACE .list ; ; The status nibble (in s.stat) is composed of the following flag bits : ; ; 100000 = Task-resident flag (Always set to 1) ; 40000 = (ss.nal) Segment has no disk allocation .nlist .ift ;if df PLAS .list ; 20000 = (ss.dsk) Segment has been loaded from disk ; 10000 = (ss.nld) Segment is neither loaded nor mapped .nlist .iff ;if df PLAS .list ; 10000 = (ss.nld) Segment is not loaded .nlist .iftf ;if df PLAS .if df IDSPACE .list ; ; ! - Bit 0 (sa.dsp) of the Virtual Load Address word (s.addr) is set if ; the segment descriptor has a D-Space portion, which is true for all ; task segments, false for all external segments. The D-Space portion ; may well be zero-length. .nlist .endc ;if df IDSPACE .ift ;if df PLAS .if df IDSPACE .list ; ; * - The Window Descriptor and D-Space Window Descriptor Addresses are ; zero for disk-resident task segments. .nlist .iff ;if df IDSPACE .list ; ; * - The Window Descriptor Address is zero for disk-resident task segments. .nlist .endc ;if df IDSPACE .iff ;if df PLAS .if df IDSPACE .list ; ; * - The Window Descriptor and D-Space Window Descriptor Addresses are ; included, but are unused and always zero .nlist .iff ;if df IDSPACE .list ; ; * - The Segment Name is appended only if the manual load routine ($Load) ; is used .nlist .endc ;if df IDSPACE .iftf ;if df PLAS .if df IDSPACE .list ; ; + - The D-Space Segment Length is zero if this segment is I-space only. .nlist .endc ;if df IDSPACE .ift ;if df PLAS .list ; .page ; ; The Window Descriptors, which are created by the Task Builder in the ; $$WNDS psect, have the following format : ; ; +---------------+---------------+ ; 1, 0 | Base APR | Window ID | w.napr, w.nid ; +---------------+---------------+ ; 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 overlay is part ; of the task, the Region ID is zero. For a memory-resident overlay in an ; external 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 is mapped (and consequently its region is attached). ; .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 ; +-------------------------------+ ; +--- 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 ; attached. .nlist .endc ;if df PLAS .list ;- .nlist FLAGS = 1 .list .page .enabl mcl alodf$ ;define the segment descriptor symbols .nlist .if ne s.stat .list .error s.stat ;segment descriptor status word offset is non-zero .nlist .endc ;if ne s.stat .list filio$ ;define the QIO symbols .nlist .if df PLAS .list ioerr$ ;define the I/O error symbols orddf$ ;define the autoload rdb symbols owddf$ ;define the autoload wdb symbols .nlist .iftf ;if df PLAS .if df CLUSTER ! ENTRAP .list exddf$ ;define the extended autoload impure data area symbols .globl .ndtds ;force the data area extension to load .nlist .iff ;if df CLUSTER ! ENTRAP .list ovddf$ ;define the autoload impure data area symbols .nlist .endc ;if df CLUSTER ! ENTRAP .list deflag = 31. ;default Event Flag for overlay QIO's .nlist .if df IDSPACE .list qiow = 3.+<12.*400> ;QIOW directive code ;IDSPACE .nlist .iff ;if df IDSPACE .list qio = 1.+<12.*400> ;QIO directive code .nlist .endc ;if df IDSPACE .list .list meb .psect $$mrks ro,ovr .enabl lsb .nlist .if df IDSPACE .list $mards:: .nlist .if df ENTRAP .list $marde:: .nlist .endc ;if df ENTRAP .endc ;if df IDSPACE .list $marks:: .nlist .if df ENTRAP .list $marke:: .nlist .endc ;if df ENTRAP .ift ;if df PLAS .if df IDSPACE .list $mardr:: .nlist .endc ;if df IDSPACE .list $markr:: .nlist .if df CLUSTER .if df IDSPACE .list $mardc:: .nlist .if df ENTRAP .list $marda:: .nlist .endc ;if df ENTRAP .endc ;if df IDSPACE .list $markc:: .nlist .if df ENTRAP .list $marka:: .nlist .endc ;if df ENTRAP .endc ;if df CLUSTER .if df LOWER .list clr r4 ;assume no memory-resident overlays cmpb n.szsg(r1),#s.pwdb+2 ;is this a good assumption ? blo 10$ ;if lo yes (TKB won't do this unless forced to) .nlist .iftf ;if df LOWER .list mov s.pwdb(r2),r4 ;pick up the window descriptor address .nlist .ift ;if df LOWER .list 10$: .nlist .endc ;if df LOWER .iftf ;if df PLAS .if df CLUSTER ! ENTRAP .list clr n.dtds(r1) ;reset the saved descriptor address ;CLUSTER .nlist .endc ;if df CLUSTER ! ENTRAP .list mov r2,-(sp) ;save the segment descriptor address for return ; ; Trace back all loaded segments for this window ; 20$: bit #ss.nld,(r2) ;is this target segment loaded and/or mapped ? beq 200$ ;if eq yes, needn't look further on this level tst s.lkdn(r2) ;is this the root descriptor ? beq 220$ ;if eq yes, no need to go further mov r2,-(sp) ;otherwise, save the current address mov r2,-(sp) ;make another copy to play with, also ; ; Check all other segments on this level ; 40$: mov s.lknt(r2),r2 ;pick up our neighbor segment's address cmp r2,(sp) ;have we looked at everyone on this level ? beq 180$ ;if eq yes, go on to a lower level .nlist .iff ;if df PLAS .list ; ; Unload a conflicting segment and all its subordinates ; 60$: bit #ss.nld,(r2) ;is this segment loaded ? bne 40$ ;if ne no, look at another neighbor bis #ss.nld,(r2) ;otherwise, unload it. Simple, no ? .nlist .ift ;if df PLAS .list ; ; Unload/unmap a conflicting segment and all its subordinates ; 60$: bit #ss.nld,(r2) ;is this segment loaded and/or mapped ? bne 120$ ;if ne no, handle a special case bis #ss.nld,(r2) ;otherwise, unload/map it. Simple, no ? .nlist .iftf ;if df PLAS .if df ENTRAP .list ; ; Preserve the overlay context across AST/SST calls ; tstb n.cast(r1) ;is this an AST/SST call ? ;AST/SST .nlist .if df CLUSTER .list beq 70$ ;if eq no ;CLUSTER .nlist .iff ;if df CLUSTER .list beq 160$ ;if eq no ;AST/SST .nlist .iftf ;if df CLUSTER .list mov r2,n.dtds(r1) ;otherwise, record this segment address ;AST/SST .nlist .ift ;if df CLUSTER .list 70$: ;CLUSTER .nlist .endc ;if df CLUSTER .endc ;if df ENTRAP .ift ;if df PLAS .list tst r4 ;does the target segment have a WDB ? beq 140$ ;if eq no tst s.size(r2) ;does this segment have meaning ? .nlist .if df IDSPACE .list beq 100$ ;if eq no, check the D-Space portion .nlist .iff ;if df IDSPACE .list beq 160$ ;if eq no .nlist .endc ;if df IDSPACE .list mov s.pwdb(r2),r3 ;get the conflicting segment's WDB beq 140$ ;if eq this segment hasn't one .nlist .if df CLUSTER .list ; ; Preserve the overlay context across clustered library calls ; cmp w.nrda(r3),w.nrda(r4) ;are they the same region ? ;CLUSTER beq 80$ ;if eq yes, then it's not a cluster call;CLUSTER mov r2,n.dtds(r1) ;otherwise, record this segment address ;CLUSTER 80$: ;CLUSTER .nlist .endc ;if df CLUSTER .list cmp r3,r4 ;are they the same window ? beq 140$ ;if eq yes, don't eliminate it .nlist .if df FLAGS .list clr w.nflg(r3) ;mark the window as non-existent .nlist .iff ;if df FLAGS .if eq > .list tst w.nflg(r3) ;is this window mapped ? .nlist .if df IDSPACE .list bpl 100$ ;if pl no, check the D-Space portion .nlist .iff ;if df IDSPACE .list bpl 160$ ;if pl no, skip it .nlist .endc ;if df IDSPACE .iff ;if eq > .list bit #wf.map,w.nflg(r3) ;is this window mapped ? .nlist .if df IDSPACE .list beq 100$ ;if eq no, check the D-Space portion .nlist .iff ;if df IDSPACE .list beq 160$ ;if eq no, skip it .nlist .endc ;if df IDSPACE .endc ;if eq > .list ; elaw$s r3 ;otherwise, make the national debt go away bic #wf.map,w.nflg(r3) ;mark the window as non-existent .nlist .endc ;if df FLAGS .if df IDSPACE .list ; ; Unload/unmap a conflicting segment's D-Space portion ; 100$: bit #sa.dsx,s.addr(r2) ;does this segment have D-Space, too ? ;IDSPACE beq 160$ ;if eq no ;IDSPACE tst s.dsiz(r2) ;otherwise, is it worth fussing over ? ;IDSPACE beq 160$ ;if eq no, skip it ;IDSPACE mov s.dwdb(r2),r3 ;get the conflicting segment's WDB ;IDSPACE beq 160$ ;if eq this segment hasn't one ;IDSPACE .nlist .if df FLAGS .list clr w.nflg(r3) ;mark the window as non-existent ;IDSPACE .nlist .iff ;if df FLAGS .if eq > .list tst w.nflg(r3) ;is this window mapped ? ;IDSPACE bpl 160$ ;if pl no, skip it ;IDSPACE .nlist .iff ;if eq > .list bit #wf.map,w.nflg(r3) ;is this window mapped ? ;IDSPACE beq 160$ ;if eq no, skip it ;IDSPACE .nlist .endc ;if eq > .list ; elaw$s r3 ;otherwise, make it go away ;IDSPACE bic #wf.map,w.nflg(r3) ;mark the window as non-existent ;IDSPACE .nlist .endc ;if df FLAGS .endc ;if df IDSPACE .list br 160$ ;proceed ; ; Check for a disk-resident segment loaded in the unmapped window we want ; 120$: tst r4 ;does the target segment have a WDB ? beq 40$ ;if eq no cmp s.pwdb(r2),r4 ;do we have a conflict with it ? bne 40$ ;if ne no 140$: bit #ss.dsk,(r2) ;was this segment loaded ? beq 40$ ;if eq no, look further on this level bic #ss.dsk,(r2) ;otherwise, just close your eyes and your ;problems will disappear as if by magic ... .nlist .iftf ;if df PLAS .list ; ; Do "Path Unloading" for higher segments ; .nlist .if df PLAS ! ENTRAP .list 160$: .nlist .endc ;if df PLAS ! ENTRAP .list mov s.lkup(r2),r2 ;having found a loaded and/or mapped segment, look - mov r2,(sp) ;for any higher segments on this branch bne 60$ ;if ne we found another level, look at all entries ; ; We have gone as high as we can go ; 180$: tst (sp)+ ;clean up the stack mov (sp)+,r2 ;restore the original descriptor address ; ; Continue looking lower ... ; 200$: mov s.lkdn(r2),r2 ;move one level deeper (towards the root) bne 20$ ;if ne go check everything on that level 220$: mov (sp)+,r2 ;restore the segment descriptor address return .dsabl lsb .page .psect $$rdsg ro,ovr .enabl lsb ; .nlist .iff ;if df PLAS .list ; Load a requested segment .nlist .ift ;if df PLAS .list ; Map and/or load a requested segment .nlist .iftf ;if df PLAS .list ; $rdseg:: .nlist .iff ;if df PLAS .if df IDSPACE .list clc ;make sure the carry bit is clear .nlist .iff ;if df IDSPACE .list tst s.size(r2) ;is this a real segment ? beq 260$ ;if eq no (carry is cleared by tst) .nlist .endc ;if df IDSPACE .ift ;if df PLAS .list tst s.size(r2) ;is this a real segment ? .nlist .if df IDSPACE .list beq 100$ ;if eq no (carry is cleared by tst) .nlist .iff ;if df IDSPACE .list beq 240$ ;if eq no (carry is cleared by tst) .nlist .iftf ;if df IDSPACE .if df LOWER .list cmpb #s.pwdb+2,n.szsg(r1) ;are we a task without mem-res overlays ? bhi 150$ ;if hi yes (TKB won't do this unless forced to) .nlist .endc ;if df LOWER .iff ;if df IDSPACE .list mov r3,-(sp) ;save a couple of registers ... mov r4,-(sp) ; .nlist .endc ;if df IDSPACE .list mov s.pwdb(r2),r3 ;pick up the segment's wdb .nlist .if df IDSPACE .list beq 100$ ;if eq this segment is disk-resident .nlist .iff ;if df IDSPACE .list beq 140$ ;if eq this segment is disk-resident .nlist .endc ;if df IDSPACE .list ; ; Attach to the appropriate region, if necessary ; .nlist .if df FLAGS .list tst w.nflg(r3) ;is this window already mapped ? .nlist .if df IDSPACE .list bne 100$ ;if ne yes, we must already be attached .nlist .iff ;if df IDSPACE .list bne 140$ ;if ne yes, we must already be attached .nlist .endc ;if df IDSPACE .iff ;if df FLAGS .if eq > .list tst w.nflg(r3) ;is this window already mapped ? .nlist .if df IDSPACE .list bmi 100$ ;if mi yes, we must already be attached .nlist .iff ;if df IDSPACE .list bmi 140$ ;if mi yes, we must already be attached .nlist .endc ;if df IDSPACE .iff ;if eq > .list bit #wf.map,w.nflg(r3) ;is this window already mapped ? .nlist .if df IDSPACE .list bne 100$ ;if ne yes, we must already be attached .nlist .iff ;if df IDSPACE .list bne 140$ ;if ne yes, we must already be attached .nlist .endc ;if df IDSPACE .endc ;if eq > .iftf ;if df FLAGS .list mov w.nrda(r3),r4 ;otherwise, get the region descriptor addr beq 60$ ;if eq there isn't one .nlist .ift ;if df FLAGS .list tst r.gflg(r4) ;if there is, are we already attached ? bne 40$ ;if ne yes .nlist .iff ;if df FLAGS .if eq > .list tst r.gflg(r4) ;if there is, are we already attached ? bmi 40$ ;if mi yes .nlist .iff ;if eq > .list bit #rf.map,r.gflg(r4) ;if there is, are we already attached ? bne 40$ ;if ne yes .nlist .endc ;if eq > .endc ;if df FLAGS .list clr r.gsts(r4) ;reset the status word atrg$s r4 ;try to get the region ID .nlist .if df CLUSTER .list bcc 20$ ;if cc we did so ;CLUSTER .nlist .if eq .list inc r.gsts(r4) ;otherwise, attach for read access ;CLUSTER .nlist .iff ;if eq .list bis #rs.red,r.gsts(r4) ;otherwise, attach for read access ;CLUSTER .nlist .endc ;if eq .list atrg$s r4 ;form an attachment ;CLUSTER .nlist .if df IDSPACE .list bcs 280$ ;if cs we couldn't .nlist .iff ;if df IDSPACE .list bcs 140$ ;if cs we couldn't .nlist .endc ;if df IDSPACE .list 20$: ;CLUSTER .nlist .iff ;if df CLUSTER .if df IDSPACE .list bcs 280$ ;if cs we couldn't .nlist .iff ;if df IDSPACE .list bcs 140$ ;if cs we couldn't .nlist .endc ;if df IDSPACE .endc ;if df CLUSTER .if df FLAGS .list dec r.gflg(r4) ;having done so, mark the region as attached .nlist .iff ;if df FLAGS .list bis #rf.map,r.gflg(r4) ;having done so, mark the region as attached .nlist .endc ;if df FLAGS .list ; ; Create and map the address window, if necessary ; 40$: .nlist .if ne r.gid .list mov r.gid(r4),w.nrid(r3) ;copy the region id to the wdb .nlist .iff ;if ne r.gid .list mov (r4),w.nrid(r3) ;copy the region id to the wdb .nlist .endc ;if ne r.gid .list 60$: craw$s r3 ;create and map the address window bcc 80$ ;if cc we did it bic #ws.wrt,w.nsts(r3) ;otherwise, try it without write access craw$s r3 ; .nlist .if df IDSPACE .list bcs 280$ ;if cs we couldn't do that either .nlist .iff ;if df IDSPACE .list bcs 140$ ;if cs we couldn't do that either .nlist .endc ;if df IDSPACE .list 80$: .nlist .if df FLAGS .list dec w.nflg(r4) ;tell ourself we have the window mapped .nlist .iff ;if df FLAGS .list bis #wf.map,w.nflg(r3) ;tell ourself we have the window mapped .nlist .endc ;if df FLAGS .if df IDSPACE .list ; ; Map the segment's D-Space portion ; 100$: bit #sa.dsx,s.addr(r2) ;does this segment have D-Space, too ? ;IDSPACE beq 140$ ;if eq no ;IDSPACE tst s.dsiz(r2) ;otherwise, is it worth fussing over ? ;IDSPACE beq 140$ ;if eq no, skip it ;IDSPACE mov s.dwdb(r2),r3 ;get the conflicting segment's WDB ;IDSPACE beq 140$ ;if eq this segment hasn't one ;IDSPACE .nlist .if df FLAGS .list tst w.nflg(r3) ;is this window mapped ? ;IDSPACE bne 140$ ;if ne yes, skip it ;IDSPACE .nlist .iff ;if df FLAGS .if eq > .list tst w.nflg(r3) ;is this window mapped ? ;IDSPACE bmi 140$ ;if mi yes, skip it ;IDSPACE .nlist .iff ;if eq > .list bit #wf.map,w.nflg(r3) ;is this window mapped ? ;IDSPACE bne 140$ ;if ne yes, skip it ;IDSPACE .nlist .endc ;if eq > .endc ;if df FLAGS .list tst w.nrda(r3) ;has this window a region descriptor ? ;IDSPACE bne 220$ ;if ne yes, D-Spaces aren't supposed to ;IDSPACE craw$s r3 ;create and map the address window ;IDSPACE bcc 120$ ;if cc we did it ;IDSPACE bic #ws.wrt,w.nsts(r3) ;otherwise, try it without write access ;IDSPACE craw$s r3 ; ;IDSPACE bcs 280$ ;if cs we couldn't do that either ;IDSPACE 120$: .nlist .if df FLAGS .list dec w.nflg(r4) ;tell ourself we have the window mapped ;IDSPACE .nlist .iff ;if df FLAGS .list bis #wf.map,w.nflg(r3) ;tell ourself we have the window mapped ;IDSPACE .nlist .endc ;if df FLAGS .iftf ;if df IDSPACE .list 140$: .nlist .iff ;if df IDSPACE .list mov (sp)+,r4 ;restore the saved registers ... mov (sp)+,r3 ; bcs 280$ ;if cs one of the directives failed .nlist .endc ;if df IDSPACE .iftf ;if df PLAS .list ; ; Load an overlay from disk, where needed ; .nlist .ift ;if df PLAS .if df LOWER .list 150$: .nlist .endc ;if df LOWER .list bit #ss.nal!ss.dsk,(r2) ;is there something to load that isn't already ? .nlist .iff ;if df PLAS .list bit #ss.nal,(r2) ;is there an allocation for this segment ? .nlist .iftf ;if df PLAS .list bne 260$ ;if ne no, just mark it available .nlist .if df IDSPACE .list tst s.size(r2) ;is this a real segment ? beq 200$ ;if eq no, try the D-Space portion .nlist .iftf ;if df IDSPACE .list clr -(sp) ;no sixth QIO parameter mov (r2),-(sp) ;isolate the overlay's relative disk - bic #^c,(sp) ;block address for the fifth parameter clr -(sp) ;no fourth QIO parameter clr -(sp) ;no third QIO parameter mov s.size(r2),-(sp) ;set up the size of the segment to be read mov s.addr(r2),-(sp) ;set up the virtual address to write to .nlist .ift ;if df IDSPACE .list bic #sa.dsx,(sp) ;hide the D-Space extension bit ;IDSPACE clr -(sp) ;no AST routine mov r1,r4 ;copy the work area address add #n.iost,r4 ;point to the work area's IOSB mov r4,-(sp) ;set it up in the QIO list mov #deflag,-(sp) ;set up the event flag number .nlist .iff ;if df IDSPACE .list mov r5,-(sp) ;use the caller's AST routine, if any mov r4,-(sp) ;set up the caller's IOSB address bne 160$ ;if ne the caller did specify one tstb r3 ;did the caller provide an Event Flag ? bne 160$ ;if ne yes, use it mov r1,r4 ;copy the work area address add #n.iost,r4 ;point to the work area's IOSB mov r4,(sp) ;use that one instead of nothing 160$: mov r3,-(sp) ;set up the user's Event Flag bne 180$ ;if ne there is one mov #deflag,(sp) ;otherwise, use one of our own invention 180$: .nlist .iftf ;if df IDSPACE .if eq n.ovly .list mov (r1),-(sp) ;use the LUN from the work area .nlist .iff ;if eq n.ovly .list mov n.ovly(r1),-(sp) ;use the LUN from the work area .nlist .endc ;if eq n.ovly .list mov #io.lov,-(sp) ;ask the loader to treat us special .nlist .ift ;if df IDSPACE .list dir$ #qiow ;attempt the load .nlist .iff ;if df IDSPACE .list dir$ #qio ;attempt the load .nlist .iftf ;if df IDSPACE .list bcs 280$ ;if cs the system didn't like our call .nlist .iff ;if df IDSPACE .list tstb r3 ;are we using our own Event Flag ? .nlist .if df PLAS .list bne 240$ ;if ne no, let the caller do the rest .nlist .iff ;if df PLAS .list bne 260$ ;if ne no, let the caller do the rest .nlist .endc ;if df PLAS .list wtse$s #deflag ;otherwise, wait for the load to complete .nlist ; bcs 280$ ;if cs the wait failed !? .iftf ;if df IDSPACE .list movb (r4),@#$dsw ;make the I/O status code visible .nlist .ift ;if df IDSPACE .list bmi 220$ ;if mi we've got a problem ;IDSPACE 200$: bit #sa.dsx,s.addr(r2) ;does this segment have D-Space, too ? ;IDSPACE .nlist .if df PLAS .list beq 240$ ;if eq no ;IDSPACE .nlist .iff ;if df PLAS .list beq 260$ ;if eq no ;IDSPACE .nlist .endc ;if df PLAS .list tst s.dsiz(r2) ;otherwise, is it worth fussing over ? ;IDSPACE .nlist .if df PLAS .list beq 240$ ;if eq no, skip it ;IDSPACE .nlist .iff ;if df PLAS .list beq 260$ ;if eq no, skip it ;IDSPACE .nlist .endc ;if df PLAS .list clr -(sp) ;no sixth QIO parameter ;IDSPACE mov s.dblk(r2),-(sp) ;set up the disk block addr parameter ;IDSPACE clr -(sp) ;no fourth QIO parameter ;IDSPACE clr -(sp) ;no third QIO parameter ;IDSPACE mov s.dsiz(r2),-(sp) ;set up the size of the segment to read ;IDSPACE mov s.dadd(r2),-(sp) ;set up the virtual address to write to ;IDSPACE clr -(sp) ;no AST routine ;IDSPACE mov r1,r4 ;copy the work area address ;IDSPACE add #n.iost,r4 ;point to the work area's IOSB ;IDSPACE mov r4,-(sp) ;set it up in the QIO list ;IDSPACE mov #deflag,-(sp) ;set up the event flag number ;IDSPACE .nlist .if eq n.ovly .list mov (r1),-(sp) ;use the LUN from the work area ;IDSPACE .nlist .iff ;if eq n.ovly .list mov n.ovly(r1),-(sp) ;use the LUN from the work area ;IDSPACE .nlist .endc ;if eq n.ovly .list mov #io.ldo,-(sp) ;ask the loader to treat us special ;IDSPACE dir$ #qiow ;attempt the load ;IDSPACE bcs 280$ ;if cs the system didn't like our call ;IDSPACE movb (r4),@#$dsw ;make the I/O status code visible ;IDSPACE .nlist .endc ;if df IDSPACE .ift ;if df PLAS .list bpl 240$ ;if pl everything went just fine .nlist .iff ;if df PLAS .list bpl 260$ ;if pl everything went just fine .nlist .iftf ;if df PLAS .if df IDSPACE .list 220$: .nlist .endc ;if df IDSPACE .list sec ;advertise our disappointment br 280$ .nlist .ift ;if df PLAS .list 240$: bis #ss.dsk,(r2) ;indicate a successful loading .nlist .iftf ;if df PLAS .list 260$: bic #ss.nld,(r2) ;this segment is now ready to use 280$: return .nlist .endc ;if df PLAS .if df CLUSTER ! ENTRAP .if df CLUSTER .if df ENTRAP .list ; ; Cache the descriptor and return address displaced by the Cluster Library ; or AST/SST service routine call ; .nlist .iff ;if df ENTRAP .list ; ; Cache the Clustered Library's displaced descriptor and return address ; .nlist .endc ;if df ENTRAP .iff ;if df CLUSTER .list ; ; Cache the descriptor and return address displaced by the AST/SST service ; routine call ; .nlist .endc ;if df CLUSTER .iff ;if df CLUSTER ! ENTRAP .if df PLAS .list ; ; Report a Cluster Library overlay attempt failure ; .nlist .iff ;if df PLAS .list ; ; Provide a Cluster Library interface routine reference for completeness' sake ; .nlist .endc ;if df PLAS .iftf ;if df CLUSTER ! ENTRAP .list .psect $$pdls ro,ovr $pdls: .nlist .iff ;if df CLUSTER ! ENTRAP .if df PLAS .list mov #ie.ovr&^O<377>,@#$dsw ;can't support Cluster Libraries jmp n.aler(r1) ;complain out loud .nlist .iff ;if df PLAS .list return ;this case doesn't do anything .nlist .endc ;if df PLAS .ift ;if df CLUSTER ! ENTRAP .list mov n.stpt(r1),r3 ;pick up the cluster stack address ;CLS/AST mov r2,-(r3) ;push the displaced segment descriptor ;CLS/AST mov 16(sp),-(r3) ;push the caller's return address ;CLS/AST cmp r3,n.stlm(r3) ;have we gone too far ? ;CLS/AST blos crash ;if los yes, we've blown our stack ;CLS/AST mov r3,n.stpt(r1) ;otherwise, save the new stack address ;CLS/AST mov pc,r2 ;compute the clean-up routine's return -;CLS/AST add #cleanup-.,r2 ;address in a position-independent way ;CLS/AST mov r2,16(sp) ;substitute it for the caller's address ;CLS/AST jmp enar ;re-enable ast's and call the routine ;CLS/AST ; ; Restore the clustered library's overlay context and return ; cleanup: mov #170000,-(sp) ;push a fake PSW (both modes = USER) ;CLS/AST adc (sp) ;record the returned carry bit ;CLS/AST tst -(sp) ;make room for the caller's return addr ;CLS/AST mov pc,-(sp) ;push the final clean-up return - ;CLS/AST add #final-.,(sp) ;address in a position-independent way ;CLS/AST jsr r5,.savr1 ;save registers 1 - 5 ;CLS/AST mov @#n.ovpt,r1 ;get the work area address ;CLS/AST call dsar ;disable ast recognition ;CLS/AST mov n.stpt(r1),r3 ;pick up the cluster stack address ;CLS/AST mov (r3)+,16(sp) ;set up the caller's address for return ;CLS/AST mov (r3)+,r2 ;recall the displaced segment descriptor;CLS/AST mov r3,n.stpt(r1) ;record the new stack address ;CLS/AST call @n.mrks(r1) ;unmap any newly-conflicting segments ;CLS/AST clr n.dtds(r1) ;don't get recalled for restoring a seg.;CLS/AST jmp $albpl ;return after a fashion ;CLS/AST final: rti ;restore the saved carry bit and return ;CLS/AST crash: iot ;Go down loudly ;CLS/AST .psect $$rtq ro,ovr,gbl dsar: ;sneaky non-reference to dsar .psect $$rtr ro,ovr,gbl enar: ;sneaky non-reference to enar .nlist .endc ;if df CLUSTER ! ENTRAP .list .end