1
0
mirror of https://github.com/PDP-10/stacken.git synced 2026-03-01 01:19:17 +00:00
Files
Lars Brinkhoff 6e18f5ebef Extract files from tape images.
Some tapes could not be extracted.
2021-01-29 10:47:33 +01:00

576 lines
19 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
TITLE SWPSER - HANDLES I/O FOR SWAPPER - V1205
SUBTTL SWPSER R.KRASIN/AW/CMF/AF/DJB/DAL 31-MAY-88
SEARCH F,S,DEVPRM
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION
; 1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986,1988.
;ALL RIGHTS RESERVED.
.CPYRT<1973,1988>
XP VSWPSR,1205
ENTRY SWPSER
SWPSER::
EXTERN JBYSUN,JBYLKN
;THIS CODE SERVES AS AN INTERFACE BETWEEN THE SWAPPER (SCHED1) AND
;I/O CODE FOR SWAPPING DEVICES (FILSER)
IDLEUN==1 ;LOOKING FOR AN IDLE UNIT IF 0
;HERE TO START PAGING/SWAPPING I/O IN A MONITOR WHICH INCLUDES VM
SQIN::
SQOUT:: MOVEI F,SWPDDB## ;SWAPPING DDB
AOS DEVDMP##(F) ;INSURE DEVDMP NON-ZERO SO ERROR RECOVERY WILL HAPPEN
AOS T1,SQREQ ;COUNT UP THE NUMBER OF PAGING/SWAPPING I/O REQUESTS
SOJE T1,SWAPIO## ;START SWAPPING/PAGING I/O IF NOT ALREADY GOING
PJRST DOPOPJ## ;I/O IN PROGRESS, GO AWAY
;HERE WHEN PAGING/SWAPPING I/O IS DONE IN A MONITOR WHICH INCLUDES VM
SWPINT::SOSGE SQREQ ;COUNT DOWN THE NUMBER OF PAGING/SWAPPING I/O
; REQUESTS OUTSTANDING
STOPCD CPOPJ##,DEBUG,SWN,;++SQREQ WENT NEGATIVE
PUSHJ P,SAVE2## ;SAVE P1,P2
MOVE P2,(P1) ;P2 = THE SWPLST ENTRY
SUBI P1,SWPLST## ;P1 = RELATIVE ADDRESS INTO SWPLST OF ENTRY
TLC P2,(SL.SIO+SL.IPC) ;JUST SWAP OUT THE "IN" QUEUE?
TLCN P2,(SL.SIO+SL.IPC)
JRST SWPI4A ;YES, JUST GO FINISH UP
HRRZ J,SW3LST##(P1) ;SEGMENT NUMBER SWAPPING/PAGING IS DONE FOR
TLNE P2,(SL.SIO) ;SWAPPING I/O?
JRST SWPIN2 ;YES
TLNN P2,(SL.DIO) ;PAGE OUT?
JRST [PUSHJ P,ZERSLE## ;NO, RETURN THE DISK SPACE
JRST SWPIN1] ;PROCEED
PUSHJ P,SVEUB## ;MAKE THE UPMP ADDRESSABLE
MOVSI T1,(UP.PGB) ;INDICATE PAGES OUT BUT NOT GIVEN BACK TO
IORM T1,.USBTS ; FREE CORE YET
SWPIN1: MOVE T1,J ;PAGING I/O, JOB NUMBER TO T1 STPIOD
PUSHJ P,STPIOD## ;PUT JOB INTO PAGE I/O SATISFIED STATE
JRST SWPIN6 ;PROCEED
SWPIN2: TLNN P2,(SL.DIO) ;SWAP OUT?
CAILE J,JOBMAX## ;NO, HIGH SEGMENT SWAP IN?
JRST SWPIN3 ;YES, PROCEED
HRRZ T2,JBTUPM##(J) ;ADDRESS OF THE PAGE ALLOCATED TO THE UPMP
SE1ENT ;MUST BE IN SECTION 1 TO REFERENCE PAGTAB
SSX T2,MS.MEM ;PAGTAB SECTION
LDB T1,[POINT SL.SPN,SWPLST##(P1),<^L<SL.PPN>+SL.SPN-1>] ;ASSUME NOT FRAGD
SKIPL T3,SWPLST##(P1) ;FRAGMENTED?
SKIPA T2,PAGTAB(T2)
LDB T1,[POINT SL.SPN,1(T3),<^L<SL.PPN>+SL.SPN-1>] ;UPT IS SECOND ENTRY OF FRAGMENT IF IT IS
CAIE T1,(T2) ;SWAPPING IN THE UPMP?
JRST SWPIN3 ;NO
MOVE T3,.CPMAP##
HRRZ T1,JBTUPM##(J)
TLO T1,(<PM.DCD>B2+PM.WRT+PM.PUB+IFE FTMP,<PM.CSH>)
MOVE T2,JBTSWP##(J) ;PAGE WE LEFT OFF AT
TLO T2,(<PM.DCD>B2+PM.WRT+PM.PUB+IFE FTMP,<PM.CSH>)
MOVEM T1,.ECKSM/PAGSIZ(T3)
CLRPGT ;FLUSH THE HARDWARE P.T.
IFN FTKL10&FTMP,<
SKIPN [M.CPU##-1] ;SINGLE KL-10 MONITOR
TDO T1,[PM.CSH] ;YES, CACHE THE UPMP
>
TLO T1,(PM.COR)
MOVEM T1,.ECKSM+.UMUPT
MOVEM T2,.ECKSM+.UMJDT
MOVE T2,T1 ;SAVE STATE OF THE CACHE BIT
TLO T1,(PM.CSH)
MOVEM T1,.ECKSM+.UMUUP
SSX T1,MS.MEM ;PAGTAB SECTION
HRR T2,PAGTAB(T1)
TLO T2,(PM.COR)
MOVEM T2,.ECKSM+.UMUPM
TLO T2,(PM.PUB+PM.CSH) ;USER MAP WILL DECIDE PUBLIC/CONCEALED
MOVEM T2,.ECKSM+SECTAB
SETZM .ECKSM+.UPWLP ;NO WRITE LOCKED PAGES YET
MOVEI T1,UP.NVS ;NOT VIRTUAL ON SWAPIN BIT
ANDCAM T1,.ECKSM+.UPBTS;ASSUME IT ISN'T
SKIPN .ECKSM+.UPWLC ;DON'T DIDDLE IF USER HAS WRITE-LOCKED PAGES
SKIPN .ECKSM+.UPVRT ;IS JOB VIRTUAL?
CAIA ;NOT VIRTUAL OR USER HAS WRITE-LOCKED PAGES
IORM T1,.ECKSM+.UPBTS;YES, REMEMBER THAT
JRST SWPIN7
SWPIN3: SKIPGE JBTSWP##(J) ;RUN OUT OF CORE BLOCKS DURING FRAGMENTED SWAP IN?
TLNE P2,(SL.DIO) ;(ONLY IF SWAPIN)
JRST SWPI3A ;NO, GET ADDRESS OF SEGMENT
CAIG J,JOBMAX## ;THIS CASE CAN ONLY COME UP FOR A LOW SEG
JRST SWPIN7 ;YES, SWAP IN NEXT FRAGMENT
SWPI3A: MOVE T1,JBTADR##(J)
SWPIN4: TLNN P2,(SL.DIO) ;IF INPUT
SOSL SINCNT## ;DECREMENT SWAPPING INPUTS IN PROGRESS
SWPI4A: SOSGE SPRCNT## ;DECREMENT SWAP IN PROGRESS COUNT
STOPCD CPOPJ##,DEBUG,SNI, ;++SWAPPING NOT IN PROGRESS
TLNE P2,(SL.ERR+SL.CHN+SL.CHK+SL.IPC) ;I/O ERROR OR "IN" QUEUE SWAP OUT?
JRST SWPIN5 ;YES
PUSHJ P,GETCHK## ;MAKE THE CHECKSUM ADDRESSABLE
HRRZS T1 ;CLEAR POSSIBLE JUNK
MOVE T1,(T1) ;GET THE CHECKSUM WORD
TLNE P2,(SL.DIO) ;SWAPPING OUT?
JRST [MOVEM T1,JBTCHK##(J) ;YES, STORE THE CHECKSUM WORD
JRST SWPIN5] ;AND PROCEED
MOVSI T2,(SL.CHK) ;ASSUME AN ERROR OCCURED
CAME T1,JBTCHK##(J) ;CHECKSUM THE SAME AS ON THE WAY OUT?
JRST [IORM T2,SWPLST##(P1) ;NO, INDICATE AN ERROR
JRST SWPIN5] ;CONTINUE
LDB T1,NZSSCN## ;# OF NZS MAPS
JUMPE T1,SWPIN5
PUSHJ P,SVEUB## ;MAP JOB
SKIPGE T1,.USBTS ;REALLY BIG YET?
TLNN T1,(UP.NZS) ;AND NEED TO CALL BISLST?
JRST SWPIN5 ;NO
AOS SINCNT
AOS SPRCNT ;READJUST COUNTS
JRST SWPN7A ;CALL BISLST YET AGAIN
SWPIN5: MOVSI T1,(SL.DFM) ;ALLOW FNDSLE TO FIND THIS ENTRY
ANDCAB T1,SWPLST##(P1) ;SWPCNT AND SWPLST AGREE
TLC T1,(SL.FRG!SL.DIO)
TLCN T1,(SL.FRG!SL.DIO) ;WAS THIS FRAGMENTED OUTPUT?
TLNE T1,(SL.IPC) ;AND NOT THE PAGING QUEUE OR IPCF?
JRST SWPINA ;NO
PUSHJ P,SVEUB## ;POINT TO JOB
SKIPE T2,.USLPS ;RETURN VIRTUAL POINTER IF IT EXISTS
PUSHJ P,RTNVPN## ;(CAN'T ZERO SLOT AS IT'S NON-ZERO ON DISK)
SWPINA::
AOS SWPCNT## ;FLAG FOR CLOCK-LEVEL
SWPIN6: MOVE S,DEVIOS(F) ;SWAPPING DDB STATUS
SKIPN SQREQ ;STILL MORE SWAPPING OR PAGING I/O TO DO?
TRZ S,IOACT ;NO, THE DDB IS NO LONGER I/O ACTIVE
PUSHJ P,STOIOS## ;REMEMBER THAT IN THE DDB
PJRST NJBTST## ;START THE SCHEDULAR IF THE NULL JOB IS RUNNING
SWPIN7: PUSHJ P,SVEUB## ;MAKE JOB ADDRESSABLE
SWPN7A: CAMN J,.USJOB ;RIGHT JOB?
TDZA P2,P2 ;YES
MOVSI P2,(SL.CHK) ;NO, SWAP READ ERROR
IOR P2,SWPLST##(P1) ;RESTORE P2 WITH POSSIBLE ERROR BIT
TLNN P2,(SL.ERR+SL.CHN+SL.CHK) ;DON'T CLEAR SL.SIO IF ERROR
TLZ P2,(SL.SIO) ;CLEAR A BIT SO DLTSLE
MOVEM P2,SWPLST##(P1) ; WON'T SOS SWPCNT
TLNE P2,(SL.ERR+SL.CHN+SL.CHK) ;I/O ERRORS?
JRST SWPIN4 ;SET I/O DONE SO ERROR WILL BE NOTICED
PUSHJ P,ZERSLE## ;RETURN THE DISK SPACE
S0PSHJ DLTSLE## ;DELETE THE SWPLST ENTRY
PUSHJ P,BISLST## ;SETUP MEMTAB FOR LOW SEGMENT SWAP IN
AOS SQREQ ;ONE MONE SWAPPING REQUEST TO DO
POPJ P, ;RETURN TO FILIO
RELABP==40000
;SUBROUTINE TO FIND SPACE ON SWAPPING DEVICE
;ARG U=NUMBER 1K BLOCKS NEEDED
;CALL MOVEI U,1K BLOCKS NEEDED, PG.SLO=1 IF SWAP IN SLOW SWAP SPACE
; PUSHJ P,SWPSPC
; ERROR RETURN - SPACE NOT AVAILABLE
; OK RETURN - DEV ADDR STORED IN LH JBTSWP(J) AND IN T1
; DEV ADDR WILL NOT BE STORED IN JBTSWP(J) IF J=0
SWPSPC::PUSHJ P,SAVE4## ;SAVE GLOBAL ACS
IFN FTXMON,<
PUSHJ P,SSEC1## ;MUST BE IN A NON-ZERO SECTION TO ADDRESS SATS
PUSH P,R ;RELOCATION (SECTION NUMBER)
HRRZS J ;MAKE SURE NO BITS
>
MOVE P2,U ;P2=NUMBER 1K BLOCKS NEEDED
HLRZ U,NXTSUN## ;GET ADDR OF NEXT UNIT FOR SWAPPING
HRRZ P4,SWPUN2## ;CLASS WHICH "SLOW" SWAPPING UNITS BELONG TO
SKIPN P4 ;IF "SLOW" UNITS ARE IN CLASS 0
TLZ P2,(PG.SLO) ; IGNORE REQUEST FOR "SLOW" SPACE
HLLZ P4,P2 ;REMEMBER PG.SLO
TLZE P2,(PG.SLO) ;SLOW (DISK) SWAP SPACE WANTED?
HLRZ U,SWPUN2## ;YES, GET UNIT OF FIRST SLOW DISK IN ASL
;LOOP TO SCAN NEXT CLASS OF SWAPPING UNIT
GT1: SETZB P3,T3
LDB P1,UNYCFS## ;GET CLASS FOR SWAPPING
HRL P1,U ;SAVE ADDR WHERE WE STARTED
;LOOP TO SCAN NEXT UNIT IN ACTIVE SWAPPING LIST IN THIS CLASS
GT2:
IFN FTMP,<
PUSHJ P,GETCAM## ;GET THE CPU ACCESSABILITY MASK FOR THIS UNIT
SKIPN MOFLPG## ;IF SETTING MONITOR MEMORY OFF LINE, ONLY
JRST GT2A ; ALLOCATE ON A UNIT ACCESSIBLE ON THE BOOT CPU
MOVN T2,BOOTCP## ;NEGATIVE OF BOOT CPU'S CPU NUMBER
TDNE T1,BITTBL##+^D35(T2) ;IS THE UNIT ACCESSIBLE ON THE BOOT?
GT2A: PUSHJ P,[PUSHJ P,CPUOK## ;YES, UNIT ACCESSIBLE ON A RUNNING CPU?
POPJ P, ;NO, NEXT UNIT
JRST CPOPJ1##] ;YES, SEE IF IT HAS SPACE
JRST GT4 ;NEXT UNIT
>; END IFN FTMP
LDB T2,UNYCFS## ;GET CLASS FOR SWAPPING OF THIS UNIT
CAIE T2,(P1) ;SKIP IF STILL SAME CLASS
JRST GT5 ;NO
TLNN T3,IDLEUN ;IF 1ST TIME
SKIPN UNISTS(U) ; USE UNIT IF IDLE
CAMLE P2,UNIFKS(U) ;SKIP IF ENOUGH ROOM ON THIS UNIT
JRST GT4 ;FORGET IT FOR NOW
MOVE T1,P2 ;T1 = NUMBER 1K BLOCKS NEEDED
PUSHJ P,GXSAT ;SEE IF CONTIGUOUS SPACE AVAILABLE
JRST GT3 ;NO
JRST FOUND ;YES
;HERE IF ENOUGH ROOM ON THIS UNIT, BUT NOT CONTIGUOUS
GT3: TLNE T3,IDLEUN
CAML P3,UNIFKS(U) ;SKIP IF THIS UNIT HAS MOST ROOM
JRST GT4 ;SOMEBODY BETTER IN THIS CLASS
MOVE P3,UNIFKS(U) ;REMEMBER SPACE ON BEST UNIT
HRR T3,U ;AND ITS ADDR
;HERE TO CHECK NEXT UNIT IN THIS CLASS
GT4: HLRZ U,UNISWP(U) ;NEXT UNIT FOR SWAPPING
MOVSS P1 ;UNIT SCAN WAS STARTED AT
TLNE T3,IDLEUN ;IF NOT FIRST PASS,
CAIE U,(P1) ;DON'T LOOK FUTHER IF ALL UNITS IN THIS CLASS SCANNED
JUMPN U,[MOVSS P1 ;PUT CURRENT CLASS BACK IN THE RH
JRST GT2] ;LOOK AT NEXT UNIT FOR SWAPPING
MOVSS P1 ;CURRENT CLASS
GT5: TLOE T3,IDLEUN ;1ST PASS?
JRST GT6 ;NO. NO CONTIGUOUS SPACE
PUSHJ P,FNDFUC ;YES, RESET U
JRST GT2 ; AND SETTLE FOR ANY UNIT
;HERE IF END OF THIS CLASS AND NO UNIT HAD CONTIGUOUS SPACE
GT6: HRRZ U,T3 ;SET U TO ADDR OF UNIT WITH MOST ROOM
CAMG P2,P3 ;SKIP IF NOT ENOUGH ROOM ON UNIT WITH MOST ROOM
JRST FOUND1 ;WE HAVE A WINNER
PUSHJ P,FNDFUC ;RESET ADDR OF 1ST UNIT THIS CLASS
;HERE TO SEE IF BY DELETING DORMANT SEGMENTS WE CAN CREATE ENOUGH
;SPACE ON A UNIT IN THE CURRENT CLASS
GT7: LDB T1,UNYCFS## ;GET CLASS FOR SWAPPING OF THIS UNIT
CAIE T1,(P1) ;SEE IF STILL SAME CLASS
JRST GT1 ;NO
PUSHJ P,IFDELE## ;FIND OUT IF BY DELETING DORMANT SEGS CAN DO IT
JRST GT8 ;NO
PUSHJ P,DODELE## ;RIGHT ON!
JRST GT8 ;THERE WAS JUST ROOM!
;HERE IF HAD TO DELETE DORMANT SEGMENTS - MAY NOW HAVE CONTIGUOUS SPACE
MOVE T1,P2 ;T1=1K BLOCKS NEEDED
PUSHJ P,GXSAT ;SEE IF CONTIGUOUS SPACE AVAILABLE
JRST FOUND1 ;NO
JRST FOUND ;YES!
;HERE IF DELETING DORMANT SEGMENTS DOESN'T HELP THIS UNIT
GT8: HLRZ U,UNISWP(U) ;TRY NEXT
JUMPN U,GT7
HLRZ U,SWPUNI## ;NO GOOD, MUST FRAGMENT ACROSS UNITS
PUSHJ P,DODELE## ;DELETE ALL DORMANT SEGS ON 1ST UNIT
JFCL ;PROBABLY WONT MAKE IT
JRST FOUND1 ;GET AS MUCH AS POSSIBLE ON THIS UNIT.
;FOUND1 WILL MOVE TO NEXT UNIT IF NECESSARY
;SUBROUTINE TO RESET U TO THE FIRST UNIT IN CLASS (P1)
FNDFUC: MOVEI U,SWPUNI##-UNISWP
FNDFU1: HLRZ U,UNISWP(U) ;NEXT UNIT IN ASL
LDB T2,UNYCFS## ;SWAPPING CLASS
CAIE T2,(P1) ;FIRST UNIT IN THIS CLASS?
JRST FNDFU1 ;NO, LOOK AT THE NEXT UNIT
POPJ P, ;YES, RETURN U
;HERE IF CONTIGUOUS SPACE AVAILABLE ON UNIT WHOSE ADDR IS IN U
;T2 = FIRST LOGICAL PAGE NUMBER, P2=T1=NUMBER NEEDED
FOUND: CAILE P2,777 ;ONLY 9 BITS TO STORE # BLOCKS IN SWPLST
JRST FOUND1 ;SO FRAGMENT REQUEST IF MORE NEEDED
PUSH P,T2
PUSHJ P,FNDU ;FIND U IN SWPTAB
.CREF JBTSWP
DPB T2,[POINT 3,(P),17] ;STORE IT
.CREF JBYSUN
LDB T2,[POINT 18,(P),35] ;K NUMBER
.CREF JBYLKN
PUSHJ P,MRKALC ;MARK AS ALLOCATED
JRST SPCEX ;SET T1 AND OK RETURN FROM SWPSER
;HERE IF ROOM BUT HAVE TO FRAGMENT
FOUND1: MOVEI T2,4 ;WORDS NEEDED
CAIE P2,1 ;CAN'T FRAGMENT 1 PAGE
PUSHJ P,GETWDS## ;GET FREE LOCS
IFE FTXMON,<POPJ P,> ;CANT - ABORT
IFN FTXMON,<JRST RPOPJ##> ;ABORT
SETZM 3(T1) ;ENSURE THAT THE LINK-WORD IS 0
MOVE P3,T1 ;P3=ADDR OF CORE BLOCKS
TLO T1,FRGSEG ;MARK AS FRAGMENTED
PUSH P,T1 ;SAVE ADDR
HRLI P3,-4 ;KEEP POINTER TO FREE CORE
FND11: MOVE T3,P2 ;T3=SPACE STILL NEEDED
MOVE T1,T3
PUSHJ P,FNDU ;FIND U IN SWPTAB
HRR P4,T2 ;SAVE INDEX IN P4, DON'T WIPE OUT LH BITS
FND12: CAILE T1,777 ;ONLY GET 777 PAGES IN 1 REQUEST
MOVEI T1,777 ; SINCE ONLY 9 BITS IN SWPLST
PUSHJ P,GXSAT
JRST FND14 ;DIDN'T MAKE IT, T1=SPACE AVAILABLE
FND13: SETZM (P3) ;CLEAR JUNK
DPB T1,FRGCP3## ;AMOUNT ALLOCATED
DPB T2,FRGAP3## ;FIRST LOGICAL PAGE NUM
PUSHJ P,MRKALC ;MARK AS ALLOCATED
DPB P4,FRGUP3## ;SET UNIT
PUSHJ P,BMPAC3
SUBB T3,T1 ;DECREMENT AMOUNT NEEDED, PUT IN T1
JUMPG T1,FND12 ;STILL NEED MORE
SETZM (P3) ;END UP WITH A ZERO
SPCEX: HLRZ U,UNISWP(U) ;NEXT UNIT IN LIST
TLNE P4,(PG.SLO) ;SLOW SWAPPING ALLOCATION?
JRST SPCEX1 ;YES, LEAVE JXTSUN AS IS
LDB T1,UNYCFS## ;CLASS TO WHICH THE UNIT BELONGS
SKIPE U ;END OF THE CHAIN?
CAILE T1,(P1) ;NO, IF NEXT UNIT IS IN A HIGHER CLASS, OR
HLRZ U,SWPUNI## ; OR END OF CHAIN, START OVER NEXT TIME
HRLM U,NXTSUN## ;STORE FOR NEXT ALLOCATOR
SPCEX1: POP P,T1 ;RESET T1 FOR EXIT
SKIPLE J ;STORE IN JBTSWP TOO?
MOVEM T1,JBTSWP##(J)
IFN FTXMON,<
POP P,R ;RESTORE R
>
JRST CPOPJ1##
FND14: JUMPE T1,NXUN ;JUMP IF NO MORE ROOM THIS UNIT
FND15:
PUSHJ P,GXSAT ;GET THAT MUCH SPACE
STOPCD .,STOP,SSD, ;++SWAP SPACE DISAPPEARED
JRST FND13
;HERE IF FILLED CURRENT UNIT AND NEED MORE SPACE
; (ONLY IF FORCED TO FRAGMENT OVER UNITS)
NXUN: HLRZ U,UNISWP(U) ;NEXT SWAPPING UNIT
SKIPN U
STOPCD .,STOP,SRO, ;STOP IF NO MORE UNITS - SPACE RAN OUT
MOVE P2,T3 ;P2=NUMBER 1K BLOCKS STILL NEEDED
PUSHJ P,DODELE## ;DELETE AS MUCH AS YOU CAN
JFCL ;MAY NOT BE ENOUGH YET
JRST FND11 ;RIGHT ON
;SUBROUTINE TO FIND ADDR CONTAINED IN U IN SWPTAB
;ARGS U=ADDRESS OF A UNIT DATA BLOCK
;CALL MOVEI U,ADDR
; PUSHJ P,FNDU
; RETURN - T2 SET UP. ADDR MUST BE IN THE TABLE
;VALUE T2=INDEX IN SWPTAB OF UNIT IN U
FNDU: SETZ T2,
CAME U,SWPTAB##(T2)
AOJA T2,.-1
POPJ P,
;SUBROUTINE TO MARK BLOCKS ALLOCATED IN A UNIT'S SWAPPING AREA
;ARGS T1=HOW MANY TO ALLOCATE
; T2=1ST TO ALLOCATE
;PRESERVES T3,T1
MRKALC: PUSH P,T1
PUSH P,T3
SUBM T1,UNIFKS(U) ;DECREMENT FREE J FOR SWAPPING
MOVNS UNIFKS(U) ;COMES OUT NEGATIVE THAT WAY
IDIVI T2,^D36 ;T2=FULL WORDS, T3=BITS IN PARTIAL WORD
HRRZ T4,UNIPTR(U)
ADD T4,T2 ;COMPUTE ADDR OF 1ST BIT
MOVEI T2,^D36
SUB T2,T3 ;36-POSITION IN WORD=DESIRED QUANTITY
HRL T4,T2 ; IN LH OF T4
MOVE T3,T1 ;T3=HOW MANY
IFN FTXMON,<
LDB R,UNYSNS## ;SECTION NUMBER CONTAINING THE SATS
MOVSS R ;MAKE AN ADDRESS
TLO T3,RELABP ;ADDRESS IS RELATIVE TO THE SAT
>
PUSHJ P,CSETOS## ;MARK ONES
POP P,T3
JRST TPOPJ## ;RESTORE T1 AND RETURN
;SUBROUTINE TO STEP P3 TO NEXT LOCATION OF TABLE BEING BUILT
BMPGET: MOVEI T2,4 ;WORDS NEEDED
PUSHJ P,GETWDS## ;GET MORE CELLS
SOJA P3,UNDD ;ABORT
SETZM 3(T1) ;CLEAR THE LINK-WORD
HRLI P3,-4
CAIN T1,(P3) ;ARE THEY CONTIGUOUS ?
JRST BMPACX ;YES, RETURN.
MOVE T2,-1(P3) ;NO, CONVERT LAST GOOD LOCATION
HRROM T1,-1(P3) ; TO A POINTER TO NEXT PART OF TABLE
MOVEM T2,(T1) ;STORE GOOD DATA IN FIRST WORD OF NEW PART
HRR P3,T1 ;NEW TABLE LOC
JRST BMPACL
BMPAC3: PUSH P,T1
PUSH P,T3
BMPACL: AOBJP P3,BMPGET ;COUNT WORD AND RETURN
JRST BMPACX
UNDD: LDB T1,FRGAP3## ;RETURN LAST CHUNK OF SWAP SPACE
LDB U,FRGCP3##
SETZM (P3) ;AND CLEAR
PUSHJ P,FXSAT1 ; END OF LIST MARKER
MOVE T1,-3(P) ;JBTSWP WORD
PUSHJ P,FXSAT ;RETURN SWAPPING SPACE
POP P,T1 ;***THROW AWAY SO THAT EXIT EXITS SWAPPER
POP P,(P) ;MORE JUNK
IFN FTXMON,<
MOVE R,-2(P) ;RESTORE R IN CASE SOMEONE CARES
POP P,(P) ;MORE JUNK
>
BMPACX: POP P,T3
JRST TPOPJ## ;EXIT
;SUBROUTINE "GXSAT" IS CALLED TO FIND A SERIES OF CONSECUTIVE FREE BLOCKS ON
; THE DISK TO SWAP SOME JOB OUT ONTO. IT IS CALLED AT CLOCK LEVEL.
;ARGS U=ADDRESS OF UNIT DATA BLOCK TO CHECK
; T1=NUMBER 1K BLOCK NEEDED
;VALUES T1=NUMBER 1K BLOCKS CAN ALLOCATE (BIGGEST HOLE IF LESS THAN REQUEST)
; T2=1ST LOGICAL PAGE NUM IF REQUEST CAN BE SATISFIED
;CALLING SEQUENCE ---
; MOVEI T1,1K BLOCKS NEEDED
; MOVEI U,ADDR
; PUSHJ P,GXSAT
; ERROR EXIT -- THE DISK IS FULL, NO SWAPPING SPACE AVAILABLE.
; NORMAL EXIT
;ACCUMULATORS T4, T1, T2 ARE DESTROYED BY THIS SUBROUTINE.
GXSAT:: PUSH P,T3 ;THIS ROUTINE SAVES AND RESTORES ACCUMULATOR "T3".
MOVE T3,T1
MOVE T1,UNIPTR(U) ;AOBJN POINTER TO SWAPPING SAT TABLES
SETZ T2,
MOVE T4,UNIUST(U) ;IF NO NEW ACCESSES FOR THIS UNIT,
TLNE T4,UNPNNA+UNPRSS
JRST GXSAT1 ;CANT GET ANY SPACE ON IT
IFN FTXMON,<
LDB R,UNYSNS## ;GET SECTION NUMBER FOR SATS
MOVSS R ;MAKE INTO A RELOCATION ADDRESS
TLO T3,RELABP ;SAT POINTER IS RELATIVE TO THE SECTION
>
PUSHJ P,CLGETZ## ;CALL ROUTINE IN FILSER TO SEARCH FOR 0 BITS
JRST GXSAT1 ;NOT ENOUGH
AOS -1(P) ;OK, SKIP RETURN
IFN FTXMON,<
HRRZS T3 ;CLEAR RELABP
>
HRRZ T1,UNIPTR(U) ;COMPUTE LOGICAL PAGE NUM FROM POSITION IN TABLE
MOVEI T2,1(T4)
SUB T2,T1 ;FULL WORDS FROM BEGINNING OF TABLE+1
IMULI T2,^D36 ;TIMES 36 BITS
HLRZ T1,T4
SUB T2,T1 ;-POSITION IN WORD
SKIPA T1,T3
GXSAT1: MOVE T1,T2
JRST T3POPJ## ;RESTORE T3
;SUBROUTINE "FXSAT" IS CALLED TO RETURN A SERIES OF CONSECUTIVE DISK BLOCKS TO
; THE FREE STORAGE POOL, THUS MAKING THEM AVAILABLE FOR RE-USE IN HANDLING
; FUTURE SWAPPING REQUESTS. IT IS CALLED AT CLOCK LEVEL.
;CALLING SEQUENCE ---
; PUSHJ P,FXSAT
; NORMAL EXIT
;ENTRY CONDITIONS ---
; C(T1) = LOGICAL BLOCK NUMBER OF THE FIRST DISK BLOCK IN THE
; SERIES WHICH IS TO BE MADE AVAILABLE.
; C(U) = NUMBER OF CONSECUTIVE 1K BLOCKS OF DISK SPACE WHICH
; ARE TO BE MADE AVAILABLE.
;EXIT CONDITIONS ---
; THE REQUESTED BITS IN THE SWAPPING SPACE AVAILABILITY TABLE
; (NAMELY, SWPTAB) HAVE BEEN CLEARED TO ZERO.
;ACCUMULATORS U, T1, T2, ARE DESTROYED BY THIS SUBROUTINE.
FXSAT:: TLZN T1,FRGSEG ;FRAGMENTED ?
JRST FXSAT1 ;NO, NO HASSLE HERE
PUSHJ P,SAVE2## ;SAVE P1
FRAGBK: HRRZ P2,T1 ;YES, LOC OF TABLE IN P1
FRGBK1: HRRZ P1,P2
SKIPG (P1) ;NEXT POINTER?
AOBJP P2,FRGBK2 ;OR DONE?
LDB T1,FRGAP1## ;GET ADDRESS
LDB U,FRGCP1## ;AND SIZE
PUSHJ P,FXSAT1 ;GIVE UP THE DISK SPACE FOR THIS PART
AOBJP P2,FRGBK1 ;COUNT WORD OF TABLE, GET NEXT
FRGBK2: HRRZ T2,P2 ;LOC OF TABLE
HLRZ T1,P2 ;T1=NUMBER OF WDS IN TABLE
SUB T2,T1 ;T2=1ST WORD OF BLOCK
MOVE P2,(P1)
PUSHJ P,GIVWDS## ;GIVE UP FREE CORE
SKIPE T1,P2 ;END OF TABLE ?
JRST FRAGBK ;NO, GO CHASE NEXT PART
POPJ P, ;YES, DONE
FXSAT1::SKIPN T2,U ;T2=NUMBER 1K BLOCKS TO RETURN
POPJ P, ;THERE AREN'T REALLY ANY (DUMMY SWPLST ENTRY
;FOR NZS)
LDB U,SSUNT1## ;GET INDEX OF UNIT IN SWPTAB
SKIPG U,SWPTAB##(U) ;GET ADDR OF UNIT DATA BLOCK
POPJ P, ;UNIT WAS REMOVED
EXCH T1,T2 ;T1=HOW MANY, T2=START LOC
HRRZS T2 ;CLEAR OUT UNIT INDEX
.CREF SSUNT1 ;(REFERENCE UNIT VALUE)
; PJRST CSETZS ;CLEAR BITS AND INCREMENT UNIFKS
;SUBROUTINE TO MARK 0'S IN SWAPPING SAT TABLE
;ARGS T1=HOW MANY
; T2=1ST LOGICAL PAGE NUMBER
;CLOBBERS T3,T4
CSETZS:
MOVE T3,UNIUST(U) ;IF NO NEW ACCESSES FOR THIS UNIT (GOING DOWN SOON),
TLNN T3,UNPNNA+UNPRSS ; DONT CHANGE UNIFKS (=0)
ADDM T1,UNIFKS(U) ;INCREMENT COUNT OF FREE PAGES FOR SWAPPING
IDIVI T2,^D36 ;GET FULL WORDS IN TABLE
HRLS T2 ;BOTH HALVES
ADD T2,UNIPTR(U) ;POINTER TO FIRST WORD TO MODIFY
IFE FTXMON,<
PJRST SETZRS##
>
IFN FTXMON,<
PUSHJ P,SSEC1## ;CAN'T ADDRESS SWAPPING SATS IN SECTION 0
PUSH P,R ;SOMEONE MAY CARE
PUSH P,P3 ;TO INDICATE AOBJN POINTER RELATIVE TO TABLE
MOVSI P3,RELABP ;(R) + (T2)
LDB R,UNYSNS## ;SECTION NUMBER FOR SWAPPING SATS
MOVSS R ;RELOCATION BY ADDRESS WITHIN SECTION
PUSHJ P,SETZRP## ;ZERO THE BITS TABLE RELATIVE
POP P,P3 ;RESTORE P3
POP P,R ;AND R
POPJ P, ;RETURN
>
;DATA ASSOCIATED WITH THE SWPSER LOGIC ---
$LOW
SQREQ:: Z ;C(LH)=NEGATIVE OF SIZE OF READ/WRITE
; C(RH)=LOCATION OF FIRST WORD TO READ/WRITE
$HIGH
$LIT
SWPEND: END