Trailing-Edge
-
PDP-10 Archives
-
bb-d868b-bm_tops20_v3a_2020_dist
-
3a-sources/cspmem.mac
There are 4 other files named cspmem.mac in the archive. Click here to see a list.
TITLE CSPMEM -- Memory Interface for "Friends of QUASAR"
SUBTTL Chuck O'Toole 20 Apr 76
SEARCH QSRMAC ;PARAMETER FILE
PROLOGUE(QSRMEM) ;GENERATE THE NECESSARY SYMBOLS
;COPYRIGHT (C) 1977 BY
;DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;
;
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;
;
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
COMMENT\
Entry points found in CSPMEM
M$INIT Initialization entry point
M$ACQP Acquire a page from the page map
M$RELP Return page 'AP' to the page map
M$IPSN Notification that IPCF send of page 'AP' is about to occur
M$NXPG Get a non-existant page for an IPCF receive
M$IPRC Notification that IPCF receive of a page has occurred
M$IPRM Make room for IPCF page we couldn't fit in core
M$AQNP Acquire N contiguous pages from the map
M$RLNP Release pages acquired from M$AQNP
M$CLNC Clean Core For Cusps About To Go Dormant
STOPCDs found in CSPMEM
ASE ADDRESSING SPACE EXHAUSTED
BPN BAD PAGE NUMBER
CCP CANNOT CREATE PAGE
CFN CANNOT FIND N CONTINUOUS PAGES
CGA CANNOT GIVE ACCESS TO PAGE
CRC CANNOT REDUCE CORE
FCE FREE COUNT EXCEEDS FREINI
FCN FREE COUNT NEGATIVE
NTS NOTHING TO SWAP OUT
PAF PAGE ACCESS CHECK FAILED
PDF PAGE DESTROY FAILED
PIF PAGE IN FAILURE
POF PAGE OUT FAILURE
RFP RELEASING FREE PAGE
RNP RECEIVED NON-EXISTANT PAGE
UPF UNKNOWN PAGE FAULT TYPE
\
SUBTTL Initialization Entry Point
;CALLED BY CSPINI AT FIRST START-UP TO INITIALIZE THE MEMORY MANAGER
;ALL REGISTERS ARE AVAILABLE AT THIS TIME
INTERN M$INIT
M$INIT: HLRZ AP,.JBSA## ;SIZE OF LOW SEGMENT
ADDI AP,777 ;ROUND TO A PAGE BOUNDRY
ADR2PG AP ;COMPUTE FIRST AVAILABLE PAGE
MOVEM AP,PAGSTA ;STORE FOR PAGE SEARCHING LOOPS
MOVEI S1,^D512 ;NOW COMPUTE THE REMAINING ADDRESS SPACE
SUB S1,AP ;OFFSET FOR LOW SEGMENT CODE
HRRZ AP,.JBHRL## ;LAST LOCATION IN THE HIGH SEGMENT
ADR2PG AP ;WORKS ONLY FOR TRADITIONAL ONES
SKIPE AP ;IS THERE A HIGH SEGMENT
SUBI AP,377 ;YES, COMPUTE NUMBER OF PAGES THERE
SUB S1,AP ;OFFSET FOR HIGH SEGMENT CODE
MOVEM S1,FREPGS ;SAVE FOR M$NXPG CHECK
MOVEM S1,FREINI ;SAVE INITIAL VALUE FOR CHECKS
ZERO PAGTBL ;START WITH A CLEAR PAGE MAP
MOVE S1,[PAGTBL,,PAGTBL+1] ;SET UP FOR THE BLT
BLT S1,PAGTBL+^D511 ;CLEAR THE WHOLE THING
JUMPE AP,INIT.1 ;DONE IF NO HIGH SEGMENT
MOVX S1,PT.USE ;GET THE USE BIT
MOVEM S1,PAGTBL+377(AP) ;SET FOR EACH PAGE IN THE HIGH SEGMENT
SOJG AP,.-1 ;TO PREVENT USAGE, PAGING
INIT.1:
IFN FTUUOS,< ;TOPS10 INITIALIZATION
MOVE S1,[PFHEND,,PFHBGN] ;PAGE FAULT HANDLER POINTERS
MOVE S2,PFHBGN ;TOUCH THE FIRST LOCATION AND THE LAST
MOVE S2,PFHEND ;TO GUARANTEE PFH IS IN CORE
MOVEM S1,.JBPFH## ;NOW SET UP OUR OWN HANDLER
MOVE S1,[.STTVM,,^D5000] ;SET VIRTUAL TIME TRAP
SETUUO S1, ;SET TO GIVE A PAGE FAULT
JFCL ;OH WELL, WE'LL JUST RUN A LITTLE SLOWER
MOVE AP,PAGSTA ;GET THE STARTING PAGE NUMBER
DECR AP ;IT GETS AOS'ED LATER
MOVEM AP,SWPSTA ;START OF THE SWAPPING TABLE
PG2ADR AP ;CONVERT TO ADDRESS
MOVEI AP,777(AP) ;LAST LOCATION WE KNOW ABOUT
CORE AP, ;DON'T CARE ABOUT ANYTHING ELSE
STOPCD(CRC,FATAL) ;++CANNOT REDUCE CORE
SETZM INMEMF ;CLEAR A FLAG
> ;END OF IFN FTUUOS
POPJ P, ;AND RETURN
SUBTTL Page Management Subroutines
;ROUTINE TO ACQUIRE 'N' CONTIGUOUS PAGES FROM THE MAP
;CALL S1 = NUMBER REQUESTED (MAY BE 1 BUT NOT 0)
; PUSHJ P,M$AQNP
; RETURNS AP = THE FIRST OF 'N'
;DESTROYS S1
;CALLS M$ACQP (ENTERS VIA ACQP.1)
INTERN M$AQNP
M$AQNP: JUMPE S1,S..CFN ;GIVE AN ERROR IF WANTS 0
CAIN S1,1 ;WANT ONLY 1
PJRST M$ACQP ;YES, USE ACQP INSTEAD
PUSHJ P,PFHOFF ;DON'T ALLOW TIMER TRAPS
PUSHJ P,.SAVE3## ;SAVE A COUPLE FIRST
MOVEI P1,(S1) ;GET THE NUMBER REQUESTED
MOVE AP,PAGSTA ;FIRST PAGE TO TRY FOR
MOVEI P2,-1(P1) ;COPY THE COUNT FOR THE LOOP BELOW
PUSHJ P,AQNP.3 ;GET ONE
AQNP.1: MOVEI P3,(AP) ;SAVE THAT NUMBER
PUSHJ P,AQNP.4 ;GET ANOTHER
CAIE AP,1(P3) ;ARE THEY CONTIGUOUS?
MOVEI P2,(P1) ;NO, RESET LOOP COUNT
SOJG P2,AQNP.1 ;GET MORE IF REQUIRED
AQNP.2: PUSHJ P,ACQP.1 ;CREATE PAGE "AP"
SOJLE P1,.POPJ## ;RETURN IF ALL DONE
SOJA AP,AQNP.2 ;ELSE BACK DOWN TO THE NEXT ONE
AQNP.3: CAIL AP,^D512 ;ONLY WANT PAGES THAT ARE UNUSED
STOPCD(CFN,FATAL) ;++CANNOT FIND N CONTINUOUS PAGES
LOAD S1,PAGTBL(AP),PT.USE ;THIS ONE USED
PJUMPE S1,.POPJ## ;NO, TAKE THIS ONE
AQNP.4: AOJA AP,AQNP.3 ;TRY ANOTHER
;ROUTINE TO RELEASE 'N' CONTIGUOUS PAGES (NORMALLY ONES FROM M$AQNP)
;CALL S1 = NUMBER TO RELEASE
; AP = THE FIRST PAGE
; PUSHJ P,M$RLNP
;DESTROYS S2, AP
;CALLS M$RELP
INTERN M$RLNP
M$RLNP: MOVEI S2,(S1) ;M$RELP WILL KLUNK S1
RLNP.1: PUSHJ P,M$RELP ;RELEASE PAGE 'AP'
SOJLE S2,.POPJ## ;RETURN IF DONE
AOJA AP,RLNP.1 ;ELSE RELEASE THE NEXT ONE
;ROUTINE TO ACQUIRE A FRESH PAGE FROM THE PAGE MAP
;CALL PUSHJ P,M$ACQP
; RETURNS AP = PAGE NUMBER
;DESTROYS S1
;CALLS FNDPAG, PGSOUT, PGSDES, ANYOUT
INTERN M$ACQP
M$ACQP: PUSHJ P,PFHOFF ;DON'T ALLOW TIMER TRAPS
PUSHJ P,FNDPAG ;FIND THE BEST AVAILABLE PAGE
SKIPN AP ;SKIP IF ONE FOUND
STOPCD(ASE,FATAL) ;++ADDRESSING SPACE EXHAUSTED
IFN FTJSYS,<
ACQP.1: MOVX S1,PT.USE!PT.WRK!PT.ADR ;GET ALL THE BITS
IORM S1,PAGTBL(AP) ;INCLUDE THEM
PJRST REDUCE ;REDUCE COUNT OF FREE CORE AND RETURN
> ;END OF IFN FTJSYS
IFN FTUUOS,<
ACQP.1: PUSHJ P,REDUCE ;REDUCE COUNT OF FREE PAGES
MOVX S1,PT.USE ;GET THE INUSE BIT
IORB S1,PAGTBL(AP) ;SET IN USE, GET THE OTHERS
TXNE S1,PT.ADR ;IS IT ADDRESSABLE
POPJ P, ;YES, RETURN (MAY PAGE FAULT IT IN LATER)
PUSHJ P,.SAVE3## ;SAVE P1-P3
ACQP.2: MOVEI P3,(AP) ;ARGUMENT FOR CREATE A PAGE
MOVEI P2,1 ;ONLY 1 ARGUMENT
MOVE P1,[.PAGCD,,P2] ;FUNCTION CREATE/DESTROY,,ARGUMENTS
PAGE. P1, ;TRY THE CREATE
JRST ACQP.3 ;ANALYZE THE ERROR
MOVX S1,PT.WRK!PT.ADR ;IN THE WORKING SET, ADDRESSABLE
IORM S1,PAGTBL(AP) ;INCLUDE THE FLAG
POPJ P, ;AND RETURN
ACQP.3: PUSH P,AP ;SAVE THE PAGE WE'RE TRYING TO CREATE
CAIE P1,PAGNS% ;OUT OF SWAPPING SPACE
JRST ACQP.4 ;NO, LOOK AGAIN
MOVEI AP,5 ;TAKE A QUICK NAP FIRST
SLEEP AP, ;IN CASE SOME FREES UP
PUSHJ P,PGSDES ;FREE SOME SWAPPING SPACE
POP P,AP ;RESTORE AP
JRST ACQP.2 ;AND RETRY THE CREATE
ACQP.4: CAIE P1,PAGLE% ;MY LIMIT EXCEEDED
STOPCD(CCP,FATAL) ;++CANNOT CREATE PAGE
PUSHJ P,ANYOUT ;SWAP OUT ANYTHING
POP P,AP ;RESTORE AP
JRST ACQP.2 ;RETRY THE CREATE
> ;END OF IFN FTUUOS
;ROUTINE TO ACQUIRE A FRESH (UNADDRESSABLE) PAGE FROM THE PAGE MAP FOR IPCF
;CALL PUSHJ P,M$NXPG
; RETURNS AP = THE PAGE NUMBER AVAILABLE FOR IPCF RECEIVE
; 0 IF NONE AVAILABLE (NO CORE AVB)
; NORMALLY, A CALL TO M$IPRC FOLLOWS THE RECEIVE AND THE PAGE IS INCLUDED
; IN FACT, THE CALL TO M$IPRC IS REQUIRED TO KEEP FREPGS STRAIGHT
;DESTROYS S1
;CALLS FNDPAG, PGSOUT, PGSDES
INTERN M$NXPG
M$NXPG: PUSHJ P,PFHOFF ;DON'T ALLOW TIMER TRAPS
MOVE S1,FREPGS ;GET FREE CORE LEFT
CAIL S1,^D5 ;INSURE IPCF WON'T FILL OUR SPACE
JRST NXPG.1 ;GO TRY TO GET ONE
NXPG.0: ZERO AP ;RETURN A ZERO
POPJ P, ;THAT WILL SHUT IT OFF
IFN FTJSYS,< ;TOPS20 WILL REPLACE ANY EXISTING PAGE WITH THE MESSAGE
NXPG.1: PUSHJ P,FNDPAG ;ESSENTUALLY DUPLICATE M$ACQP
PJUMPE AP,.POPJ## ;RETURN 0 IF CANT GET ONE NOW
MOVX S1,PT.USE ;SET THE TEMP STATE
IORM S1,PAGTBL(AP) ;OF INUSE BUT NOT ADDRESSABLE
POPJ P, ;AND RETURN
> ;END OF IFN FTJSYS
IFN FTUUOS,< ;TOPS10 REQUIRES A NON-EXISTANT PAGE
NXPG.1: PUSHJ P,NXPG.3 ;FIND A COMPLETELY MISSING PAGE
JUMPN AP,NXPG.2 ;TAKE THIS ONE
PUSHJ P,.SAVE3## ;SAVE P1-P3
PUSHJ P,PGSDES ;DESTROY ALL I CAN
PUSHJ P,NXPG.3 ;NOW TRY TO FIND ONE
PJUMPE AP,.POPJ## ;RETURN 0 IF CANT GET ONE NOW
NXPG.2: MOVX S1,PT.USE ;SET THE TEMP STATE
IORM S1,PAGTBL(AP) ;OF INUSE BUT NOT ADDRESSABLE
POPJ P, ;AND RETURN
NXPG.3: MOVE AP,PAGSTA ;START AT THE FIRST AVAILABLE PAGE
NXPG.4: CAIL AP,^D512 ;END OF THE ADDRESSING SPACE
JRST NXPG.0 ;YES, RETURN A ZERO
MOVE S1,PAGTBL(AP) ;GET THE TABLE ENTRY
TXNN S1,PT.USE!PT.WRK!PT.ADR ;IS THIS PAGE THERE
POPJ P, ;NO BITS MEANS NON-EXISTANT
AOJA AP,NXPG.4 ;WELL, TRY THE NEXT
> ;END OF IFN FTUUOS
;ROUTINE TO RETURN A PAGE TO THE PAGE MAP
;CALL AP = PAGE NUMBER
; PUSHJ P,M$RELP
;DESTROYS S1
INTERN M$RELP
M$RELP: PUSHJ P,VALPAG ;CONSISTENCY CHECK 'AP'
MOVE S1,PAGTBL(AP) ;GET THE FLAGS
TXZN S1,PT.USE ;CLEAR IN USE
STOPCD(RFP,FATAL) ;++RELEASING FREE PAGE
TXNE S1,PT.ADR ;IS THIS THE ONE IPCF'ED AWAY
JRST RELP.1 ;NO, GO FIX THE COUNTS
ZERO PAGTBL(AP) ;CLEAR THE ENTRY
POPJ P, ;AND RETURN
RELP.1: MOVEM S1,PAGTBL(AP) ;STORE NEW SETTINGS
PJRST INCLUD ;BUMP FREE PAGE COUNT AND RETURN
;ROUTINE TO SET NOTIFICATION OF A PAGE BEING IPCF'ed FROM OUR ADDRESSING SPACE
;CALL AP = PAGE NUMBER
; PUSHJ P,M$IPSN
;DESTORYS S1
INTERN M$IPSN
M$IPSN: PUSHJ P,VALPAG ;CONSISTENCY CHECK 'AP'
MOVX S1,PT.WRK!PT.ADR ;CLEAR IN THE WORKING SET, ADDRESSABLE
ANDCAM S1,PAGTBL(AP) ;SO THAT WE DON'T GET CONFUSED
PJRST INCLUD ;BUMP FREE PAGE COUNT AND RETURN
;ROUTINE TO INCLUDE A PAGE RECEIVED BY IPCF INTO OUR ADDRESSING SPACE
;CALL AP = THE PAGE NUMBER
; PUSHJ P,M$IPRC
;DESTROYS S1,S2
INTERN M$IPRC
IFN FTUUOS,< ;NOW NEED TO KNOW IF THE PAGE IS IN THE WORKING SET
M$IPRC: PUSHJ P,VALPAG ;CONSISTENCY CHECK 'AP'
MOVEI S2,(AP) ;FOR PAGE 'AP'
HRLI S2,.PAGCA ;CHECK ITS ACCESS BITS
PAGE. S2, ;SEE IF THE PAGE IS SWAPPED OUT
STOPCD(PAF,FATAL) ;++PAGE ACCESS CHECK FAILED
MOVX S1,PT.WRK!PT.ADR ;IN THE WORKING SET, ADDRESSABLE
TXNE S2,PA.GNE ;PAGE DOESN'T EXIST
STOPCD(RNP,FATAL) ;++RECEIVED NON-EXISTANT PAGE
TXNE S2,PA.GPO ;IS IT PAGED OUT
TXZ S1,PT.WRK ;YES, CLEAR IN THE WORKING SET
IORM S1,PAGTBL(AP) ;INCLUDE THE FLAG(S)
PJRST REDUCE ;REDUCE COUNT OF FREE PAGES AND RETURN
> ;END OF IFN FTUUOS
IFN FTJSYS,<
M$IPRC: PUSHJ P,VALPAG ;CONSISTENCY CHECK 'AP'
MOVX S1,PT.WRK!PT.ADR ;IN THE WORKING SET, ADDRESSABLE
IORM S1,PAGTBL(AP) ;INCLUDE THE FLAGS
PJRST REDUCE ;REDUCE COUNT OF FREE PAGES AND RETURN
> ;END OF IFN FTJSYS
;ROUTINE TO SEARCH THE PAGE MAP FOR THE BEST PAGE FOR M$ACQP TO USE
; "BEST" IS THE FIRST OF
; AN INCORE FREE PAGE
; OR A SWAPPED OUT FREE PAGE
; OR A NON-EXISTANT PAGE
;CALL PUSHJ P,FNDPAG
; RETURNS AP = THE PAGE OR 0 IF OUT OF ADDRESSING SPACE
;DESTROYS S1,S2
FNDPAG: MOVE AP,PAGSTA ;FIRST AVAILABLE PAGE
ZERO S2 ;LH = NON-EXIST , RH = SWAPPED OUT
FNDP.1: CAIL AP,^D512 ;OFF THE END
JRST FNDP.2 ;YES, DIDN'T FIND OUR FIRST CHOICE
MOVE S1,PAGTBL(AP) ;GET THE TABLE ENTRY
TXNE S1,PT.USE ;THIS ONE IN USE
AOJA AP,FNDP.1 ;YES, DON'T EVEN BOTHER
TXCN S1,PT.WRK!PT.ADR ;FLIP, P.S. DOES THIS PAGE EXIST
TLNE S2,-1 ;NO, BUT HAVE I ALREADY FOUND ONE
SKIPA ;EXISTS OR ONE OF THAT TYPE FOUND ALREADY
HRLI S2,(AP) ;REMEMBER NON-EXISTANT PAGE FOR LATER
TXCN S1,PT.WRK!PT.ADR ;BACK, P.S. IS IT INCORE AND FREE
POPJ P, ;CAN'T GET ANY BETTER THAN THAT
TXNE S1,PT.ADR ;IS IT ADDRESSABLE
HRRI S2,(AP) ;YES, REMEMBER THAT TOO
AOJA AP,FNDP.1 ;AND LOOP
FNDP.2: MOVEI AP,(S2) ;GET 2ND BEST TYPE
PJUMPN AP,.POPJ## ;RETURN IF THERE WAS ONE
HLRZ AP,S2 ;GET LAST CHOICE
POPJ P, ;RETURN ANYWAY
;CONSISTENCY CHECKS ON THE NUMBER OF FREE PAGES IN OUR ADDRESSING SPACE
;"REDUCE" DECREMENTS THE FREE PAGE COUNT , "INCLUD" ADDS A FREE PAGE
;
;INCLUD DESTROYS S1
REDUCE: SOSGE FREPGS ;DECREMENT COUNT OF FREE PAGES
STOPCD(FCN,FATAL) ;++FREE COUNT NEGATIVE
POPJ P, ;RETURN IF OK
INCLUD: AOS S1,FREPGS ;ADD A FREE PAGE
CAMLE S1,FREINI ;MORE THAN WE STARTED OUT WITH
STOPCD(FCE,FATAL) ;++FREE COUNT EXCEEDS FREINI
POPJ P, ;RETURN IF OK STILL
;CONSISTENCY CHECK ON 'AP', THE PAGE NUMBER ARGUMENT TO
; M$RELP, M$IPSN, M$IPRC
VALPAG: CAIG AP,^D511 ;OVER THE TOP OF THE WORLD
CAMGE AP,PAGSTA ;OR UNDER THE INITIAL VALUE
STOPCD(BPN,FATAL) ;++BAD PAGE NUMBER
POPJ P, ;RETURN, 'AP' IS IN RANGE
SUBTTL The Page Fault Handler
;THIS IS THE ROUTINE CALLED BY THE TOPS10 SYSTEM SO THAT A USER MAY PROCESS
;HIS OWN PAGE FAULTS. .JBPFH CONTAINS THE STARTING ADDRESS OF THE ROUTINE
;AND IS CALLED WHEN EITHER A FAGE FAULT OCCURS OR THE .STTVM TIMER HAS EXPIRED
IFN FTUUOS,< ;THIS CODE EXISTS ONLY FOR THE TOPS10 MONITOR
PFHBGN: JRST PFHSTA ;ENTERED HERE
PFH.PC: 0 ;PC AT TIME OF TRAP
PFH.PN: 0 ;PAGE FAULT WORD
PFH.TI: 0 ;VIRTUAL AGE OF THE PAGE FAULT HANDLER
PFH.RA: 0 ;CURRENT PAGING RATE
BLOCK 4 ;ROOM FOR FUTURE EXPANSION
PFHSTA: MOVEM P,PFHS.P ;SAVE SOMEBODY'S P
MOVE P,[IOWD PF.PSZ,PF.PDL] ;GET MY OWN PDL
PUSH P,P1 ;BEGIN TO SAVE SEVERAL REGISTERS
PUSH P,P2 ;CAUSE I'M GOING TO CALL SUBROUTINES
PUSH P,P3 ;FOR SWAPPING AND SEARCHING
PUSH P,AP ;AND THESE ARE THE ARGUMENTS
LOAD P2,PFH.PN,PF.HFC ;THE FAULT TYPE
CAIG P2,PFHDCT ;RANGE CHECK
JRST PFHDSP(P2) ;DISPATCH THE FAULT
PFHDSP: JRST PFHILL ;PAGE FAULT CODE = 0 OR TOO BIG
JRST PFHGVA ;.PFHNA = 1 = NO ACCESS
JRST PFHSWI ;.PFHNI = 2 = NOT IN CORE
JRST PFHSWI ;.PFHUU = 3 = NOT IN CORE FOR UUO
JRST PFHTIM ;.PFHTI = 4 = VM TIMER TRAP
PFHDCT==.-PFHDSP-1 ;DISPATCH LENGTH (0-n)
PFHILL: STOPCD (UPF,FATAL) ;++UNKNOWN PAGE FAULT TYPE
PFHSWI: LOAD P3,PFH.PN,PF.HPN ;GET THE PAGE THAT CAUSED THE FAULT
MOVEI P2,1 ;ONLY 1 PAGE
MOVE P1,[.PAGIO,,P2] ;FUNCTION PAGE IO,,ARGUMENT BLOCK
PAGE. P1, ;SWAP IT IN
JRST PFHSWF ;FAILED, SEE WHY
MOVX P1,PT.WRK ;THE WORKING SET BIT
IORM P1,PAGTBL(P3) ;PAGE IS NOW IN CORE
JRST PFHXIT ;DISMISS THE FAULT
PFHSWF: CAIE P1,PAGLE% ;IS MY CORE LIMIT EXCEEDED
STOPCD(PIF,FATAL) ;++PAGE IN FAILURE
PUSHJ P,ANYOUT ;SWAP OUT SOMETHING (ANYTHING)
JRST PFHSWI ;TRY THE SWAPIN NOW
;;;CODE IS CONTINUED ON THE NEXT PAGE AND STILL UNDER FTUUOS CONDITIONAL
;HERE TO GIVE ACCESS TO A PAGE (CAN ONLY HAPPEN IF LOADED VIA GET.SHR)
PFHGVA: LOAD P3,PFH.PN,PF.HPN ;GET THE PAGE NUMBER WE CAN'T ACCESS
TXO P3,1B0 ;SET TO ALLOW ACCESS
MOVEI P2,1 ;ONLY ONE ARG
MOVE P1,[.PAGAA,,P2] ;GIVE ACCESS,,ARGS
PAGE. P1, ;SET ACCESS ALLOWED ON THAT PAGE
STOPCD(CGA,FATAL) ;++CANNOT GIVE ACCESS TO PAGE
JRST PFHXIT ;AND EXIT FROM THE PAGE FAULT HANDLER
;HERE ON A TIMER TRAP, SEE IF WE CAN CLEAN UP SOME CORE
PFHTIM: SKIPN INMEMF ;SOMEBODY FOOLING WITH THE PAGE TABLE
PUSHJ P,PGSDES ;NO, DESTROY ANY JUNK PAGES
PFHXIT: POP P,AP ;RESTORE AP
POP P,P3 ;...
POP P,P2 ;...
POP P,P1 ;...
MOVE P,PFHS.P ;RESTORE THE OLD AC P
JRSTF @PFH.PC ;DISMISS THE FAULT
PFHS.P: BLOCK 1 ;SAVED P
PF.PDL: BLOCK ^D12 ;PDL FOR USE IN THE PAGE FAULT HANDLER
PF.PSZ==.-PF.PDL ;SIZE OF THE LIST
;ROUTINE TO DESTROY AS MANY PAGES THAT ARE SWAPPED OUT OR UNUSED
;CALL PUSHJ P,PGSDES
; RETURNS AFTER DESTROYING AS MANY AS POSSIBLE
;DESTORYS AP,P1-P3 WITHOUT SAVING
INTERN M$CLNC
M$CLNC: PUSHJ P,.SAVE3## ;SAVE P1-P3
SAVE AP ;SAVE AP AND FALL INTO PGSDES
PGSDES: MOVE AP,PAGSTA ;THE FIRST AVAILABLE PAGE
PGSD.1: CAIL AP,^D512 ;OFF THE END OF THE WORLD
POPJ P, ;YES, RETURN
MOVE P1,PAGTBL(AP) ;GET THE TABLE ENTRY
TXC P1,PT.ADR ;NEED CHECK FOR BOTH SO FLIP
TXNN P1,PT.USE!PT.ADR ;USED OR NOT ADDRESSABEL
PUSHJ P,DESTRY ;DESTROY THE PAGE (COULD BE PAGED OUT)
AOJA AP,PGSD.1 ;AND CONTINUE LOOPING
DESTRY: MOVEI P3,(AP) ;WANT IT IN P3
TXO P3,1B0 ;SET TO DESTROY
MOVEI P2,1 ;1 ARGUMENT
MOVE P1,[.PAGCD,,P2] ;CREATE/DESTROY,,ARGUMENT
PAGE. P1, ;TRY TO DESTROY IT
STOPCD(PDF,FATAL) ;++PAGE DESTROY FAILED
ZERO PAGTBL(AP) ;CLEAR THE PAGE MAP ENTRY
POPJ P, ;RETURN
;;;CODE IS CONTINUED ON THE NEXT PAGE AND STILL UNDER FTUUOS CONDITIONAL
;ROUTINE TO SWAP OUT ANYTHING POSSIBLE SO THAT A PAGEIN CAN OCCUR
;CALL PUSHJ P,ANYOUT
; RETURNS AFTER A PAGE HAS BEEN SUCCESSFULLY PAGED OUT
;DESTROYS AP, P1-P3 WITHOUT SAVING
;COULD EXIT THROUGH DESTRY
INTERN M$IPRM
M$IPRM: PUSHJ P,.SAVE3## ;SAVE P1-P3
SAVE AP ;AND AP AND FALL INTO ANYOUT
ANYOUT: MOVE AP,PAGSTA ;FIRST MAKE A PASS LOOKING FOR ANY FREE
ANYO.1: PUSHJ P,ANYO.4 ;PAGES THAT CAN BE DESTROYED
JUMPE AP,ANYO.2 ;NONE, PAGE SOMETHING OUT
TXNE P1,PT.USE ;IS THIS IN-CORE PAGE USED
AOJA AP,ANYO.1 ;YES, LOOK FOR ANOTHER
PJRST DESTRY ;NO, DESTROY IT NOW AN SAVE A SWAP
ANYO.2: AOS AP,SWPSTA ;START WHERE WE LEFT OFF
PUSHJ P,ANYO.4 ;FIND A SWAPPED IN PAGE
JUMPN AP,ANYO.3 ;SWAP IT OUT
MOVE AP,PAGSTA ;RE-START AT THE FIRST
PUSHJ P,ANYO.4 ;TRY NOW
JUMPN AP,ANYO.3 ;FOUND ONE, SWAP IT OUT
STOPCD (NTS,FATAL) ;++NOTHING TO SWAP OUT
ANYO.3: MOVEM AP,SWPSTA ;REMEMBER FOR LATER
MOVEI P3,(AP) ;COPY THE PAGE NUMBER
TXO P3,1B0 ;SET TO SWAP OUT INSTEAD OF SWAP IN
MOVEI P2,1 ;ONLY 1 PAGE FOR NOW
MOVE P1,[.PAGIO,,P2] ;FUNCTION SWAP,,ARGUMENT BLOCK
PAGE. P1, ;OUT IT GOES
STOPCD(POF,FATAL) ;++PAGE OUT FAILURE
MOVX P1,PT.WRK ;GET THE WORKING SET BIT
ANDCAM P1,PAGTBL(P3) ;NOT THERE ANY MORE
POPJ P, ;AND RETURN FOR ANY RETRIES
ANYO.4: CAIL AP,^D512 ;OVER THE TOP
JRST ANYO.5 ;YES, RETURN A ZERO
MOVE P1,PAGTBL(AP) ;GET THE STATUS FLAGS
TXNE P1,PT.ADR ;IS IT ADDRESSABLE
TXNN P1,PT.WRK ;YES, IS IT IN THE WORKING SET
AOJA AP,ANYO.4 ;TRY THE NEXT PAGE
POPJ P, ;YES, A CANDIDATE FOR SWAP OUT
ANYO.5: ZERO AP ;RETURN 0 IF NONE FOUND
POPJ P, ;RETURN
SWPSTA: BLOCK 1 ;PAGE NUMBER FOR START OF SWAP OUT SEARCH
PFHEND: ;THE LAST LOCATION WITHIN THE PAGE FAULT HANDLER
;;;CODE IS CONTINUED ON THE NEXT PAGE AND STILL UNDER FTUUOS CONDITIONAL
;CO-ROUTINE TO SET FLAG DISALLOWING PAGE FAULT TIMER TRAPS
; THE FLAG INDICATES THAT SOME ROUTINE IS GOING TO RELY ON
; THE SETTINGS OF THE PAGE TABLE FLAGS AND THAT PGSDES SHOULD NOT
; BE CALLED BY THE PAGE FAULT HANDLER.
PFHOFF: SKIPE INMEMF ;RE-CURSIVE CALL
POPJ P, ;YES, WAIT FOR ORIGINAL CALLER TO RETURN
POP P,INMEMF ;REMOVE CALL, SET FLAG NON-ZERO
PUSHJ P,@INMEMF ;CALL THE CALLER
SKIPA ;NON-SKIP RETURN
AOS (P) ;PROPOGATE THE SKIP RETURN
SETZM INMEMF ;ALLOW TRAPS NOW
POPJ P, ;AND RETURN
INMEMF: BLOCK 1 ;FLAG INDICATING INSIDE MEMORY MANAGER
> ;END OF IFN FTUUOS
IFN FTJSYS,< ;SOME THINGS NOT NEEDED ON TOPS20
M$CLNC:: ;DON'T NEED TO CLEAN CORE OF UNUSED PAGES
PFHOFF: ;NO PAGE FAULTS TO WORRY ABOUT
POPJ P, ;TURN THEM INTO NOP'S
> ;END OF IFN FTJSYS
SUBTTL Constants and Other Things
XLIST ;FORCED OUT LITERAL POOL HERE
LIT
LIST
SALL
FREPGS: BLOCK 1 ;COUNT OF FREE PAGES LEFT IN ADDRESSING SPACE
FREINI: BLOCK 1 ;THE INITIAL VALUE OF FREPGS FOR CONSISTENCY CHECKS
PAGSTA: BLOCK 1 ;THE STARTING POINT FOR PAGSRC SEARCHES
PAGTBL:: BLOCK ^D512 ;THE PAGE MAP
END