TITLE CSPMEM -- Memory Interface for "Friends of QUASAR" SUBTTL Chuck O'Toole 20 Apr 76 ;***Copyright (C) 1974, 1975, 1976, Digital Equipment Corp., Maynard, Mass.*** SEARCH QSRMAC ;PARAMETER FILE PROLOGUE(QSRMEM) ;GENERATE THE NECESSARY SYMBOLS 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