;<135-TENEX>PAGEM.MAC;254 17-DEC-75 15:16:30 EDIT BY ROSENBERG ; PUT A "COPY" OF ONRQ IN-LINE IN MAKPGA TO AVOID NESTED PIOFFS/PIONS ;<135-TENEX>PAGEM.MAC;253 20-NOV-75 14:54:58 EDIT BY ROSENBERG ; MAKE MRPAC JSYS CORRECT FOR RESIDENT MONITOR MAPPING EITHER ON OR OFF ;<134-TENEX>PAGEM.MAC;252 4-NOV-75 11:15:57 EDIT BY ALLEN ; BE SURE SCHED SEES PSI SET AT RELMP4 ;<134-TENEX>PAGEM.MAC;251 15-SEP-75 17:27:50 EDIT BY PLUMMER ; REMOVE .PLOCK ;<134-TENEX>PAGEM.MAC;250 2-SEP-75 09:45:48 EDIT BY PLUMMER ;<134-TENEX>PAGEM.MAC;248 28-AUG-75 16:05:29 EDIT BY PLUMMER ; FORBID SETPT FROM FORMING INDIRECT MAP LOOPS ;<134-TENEX>PAGEM.MAC;246 18-AUG-75 11:17:10 EDIT BY PLUMMER ; FIX ASOFAI AGAIN ;<134-TENEX>PAGEM.MAC;244 5-AUG-75 11:44:57 EDIT BY CLEMENTS ; CHANGE "P2" TO "PATCH2" TO AVOID CONFLICT WITH NEW AC NAME ;<134-TENEX>PAGEM.MAC;243 8-JUL-75 09:31:15 EDIT BY PLUMMER ; FORCE DDUMP TO RUN IN ASOFAI ;<134-TENEX>NPAGEM.MAC;2 22-MAY-75 15:53:30 EDIT BY ALLEN ; PGRINI NO LONGER COMPUTES DRMIN0,1,2 BUT TAKES VALUES FROM ; PARAMS. ;<134-TENEX>NPAGEM.MAC;1 15-MAY-75 12:33:12 EDIT BY ALLEN ; FIX SETPT RACE CONDITION. RELMPG NOW SKIPS IF SUCCESSFUL AND ALWAYS ; RETURNS NOSKED ;<134-TENEX>PAGEM.MAC;240 21-APR-75 16:44:52 EDIT BY TOMLINSON ; extern DISE ;<134-TENEX>PAGEM.MAC;239 21-APR-75 16:39:35 EDIT BY TOMLINSON ; Correct spelling of FSHBAL in asofn edit below ;<134-TENEX>PAGEM.MAC;238 16-APR-75 17:57:56 EDIT BY PLUMMER ;<134-TENEX>PAGEM.MAC;237 16-APR-75 12:56:59 EDIT BY PLUMMER ; MAKE ASOFN TRY SECOND TIME AFTER GC BEFORE FAILING ;<134-TENEX>PAGEM.MAC;236 3-MAR-75 17:29:35 EDIT BY CLEMENTS ; MOVE RECURSIVE TRAP CHECK IN GC LOGIC (PDL OV IN RS04 DRIVER) ;<134-TENEX>PAGEM.MAC;235 28-FEB-75 15:43:27 EDIT BY CLEMENTS ; REVERSE ORDER OF PAGER OPS AT PGRRST, IN CASE LITERALS ABOVE 77777 ;<134-TENEX>PAGEM.MAC;234 11-FEB-75 17:19:39 EDIT BY ALLEN ; FIX (HOPEFULLY) FOR SUMNRX INCORRECT BUG ;<134-TENEX>PAGEM.MAC;233 11-FEB-75 17:02:50 EDIT BY ALLEN ; BRING GCCOR UP TO DATE IN TESTING FOR WAITLIST FORK ;<133-TENEX>PAGEM.MAC;232 17-DEC-74 17:20:09 EDIT BY ALLEN ; BUG FIX IN SETPPG SEARCH PROLOG TITLE PAGEM ;TENEX PAGE MANAGEMENT MODULE - D. MURPHY INTERN MAKPGU,MAKPGA,PLCKT INTERN ASOFN,RELOFN,SETMPG,READB,MRPACS,MSPACS,MRMAP,NOFN INTERN MLKPG,MULKPG,FPTA,MRPT,SETPT,DISKP,DRUMP,RWX,SWPCOR INTERN DDMP,DELOFN,MONCOR,COPYB,SPT,SPTH,CORWB,SPC1,SWPZPG INTERN MULKCR,MULKMP,CST0,CST1,CST2,CST3,MLKMA INTERN .MRPAC,PRELDF,SWRSAF,POSPGF,.RWSET INTERN SWPINT INTERN SWPDON,DWRBIT,SWPERR INTERN DSKRT,GCALC,PGRRST,PRELD,PGRTRP,SWPIN0,ASSPT,DESPT INTERN SWPRT,SETPPG,GCCOR,XGC,SWPRST,POSTPG,ICAPT,PGRINI INTERN MKSHRP,SETDVP ;LINKAGE TO PISRV AND SCHED EXTERN BHC,BITS,BLOCK1,BUGCHK,BUGHLT,DEVMPE,PSISV2,RSKEDN,PNDING EXTERN DISGE,DISLT,DRMRD,DRMWR,DSKRD,DSKWR,ETIME,FKCNO,FKJOB,FKNR,CGFLG EXTERN BSBITS,RLBITS,BKGFLG,EDISMS,DISL EXTERN FKPGS,FKPT,FKWSP,FORKX,FRECB,FSHBAL,ILIST,FKPT6M,MAXQ EXTERN INDFLG,INSKED,ISKED,ITRAP,JOBNAM,LSTERR,MAXNRX,MENTR,MINNR EXTERN MRETN,MSTKOV,NBPROC,NGCLCT,PPCLCT,NPMAX,NRPLQ,NRPMIN,JOBRTT EXTERN PATCH2,PPG,PSIRQ,PSIRQ0,PSKED,R,RJAV,RJQNT,RPLQ,RSKP,TOPTRP EXTERN SCHEDP,SCHEDR,SJSIZ,GCCR,SNPMAX,SPFLTS,PTRAP,STIME,SUMNRX EXTERN TODCLK,TOTRC,WTLST,WTSPT,WTSPTT,POTEN EXTERN RUNLST,RUNLSB,FKFLGS,WTFK,NOSK,FORCEM,BLST,WTCLCT,RNLS,ZIFA,NOFLT ; LINKAGE TO DSK AND DRM EXTERN GDSTX,DRMASN,DSKASN,DASDRM,DEDSK,DRMFRE EXTERN CVDSK,UDSKIO EXTERN DRMIO,DSKIO ; LINKAGE TO DISC AND FILE SYSTEM EXTERN JFNOFN,OFNJFN,JFNDCR,OPNX16,OPNX9,OPNX10 ;PARAMETERS DISKP: 1 ;DISK ON SYSTEM DRUMP: IFDEF DRMCHN,<1> ;1 = DRUM AVAIL, IFNDEF DRMCHN,<0> ;0 = USE DISK, -1 = USE NOTHING PRELDF: 0 ;NO PRELOADING IF 0 SWRSAF: 0 ;REASSIGN SWAP ADDRESSES IF .G. 0 POSPGF: 0 ;POST PURGE IF .G. 0 LS NHIPG,1 ;HIGEST PAGE USED BY SWAPPER LS SPTC,1 ;COUNT OF SPT (EXCLUDING OFN) ENTRIES IN SPT LS NOF,1 ;COUNT OF ENTRIES IN OFN PART OF SPT LS FRESPT,1 ;FREE SPT LIST LS MAXSPL,1 ;MAX NUMBER OF PROBES TO SPTH LS MMSPTN,1 ;OFN OF MONITOR MAP GS LOKPGS,1 ;COUNT OF LOCKED PAGES, VIA MLKPG GS LOKSUM,1 ;NET NUMBER OF LOCKS, MLKPG-MULKPG GS MAXLOK,1 ;MAX NUMBER OF PAGES TO BE LOCKED GS NXTDMP,1 ;FLAG TO CAUSE DDMP ACTION GS DDTIME,1 ;TIME NEXT DDMP DUE LS IOIP,1 ;SWAP WRITES IN PROGRESS GS DRMIN0,1 ;DO NOT PERMIT NEW JOB IF DRUM SPACE LT THIS GS DRMIN1,1 ;DDMP DELETES DRUM ADDRESSES IF DRUM SPACE ;FALLS BELOW THIS GS DRMIN2,1 ;SWPOUT WILL NOT ASSIGN NEW DRUM ADDRESSES ;FOR PAGES WITH DISK ADDRESSES ;IF DRUM SPACE FALLS BELOW THIS GS PRELRQ,1 ;PRELOADING SWAPIN IF NON-0 GS JDSPTP,1 ;SPT INDEX FOR NORMAL JSYS DISPATCH VECTOR ; FOLLOWING CELLS USED IN REMOVING PAGES FROM SWAPPABLE STORE GS PGELCT,1 ; COUNT OF LOCKED PAGES FOUND TRYING TO REMOVE PAGES SPC0: EXP *5/6 SPC1: EXP SSPT-NOFN-40 ;INITIALIZATION, SPT, CST, ETC. PGRINI: SETZM SPTC SETZM NOF SETZM MAXSPL MOVEI 1,SPT+NOFN MOVEI 2,SSPT-NOFN CALL ILIST ;MAKE LIST OF FREE SPT ENTRIES MOVEM 1,FRESPT SETZM SPTH MOVE 1,[XWD SPTH,SPTH+1] BLT 1,SPTH+NOFN-1 ;ZERO OUT SPTH CALL ASSPT ;ASSIGN SPT SLOT FOR MMAP MOVE 2,[XWD 1B31,MMAP/1000] MOVEM 2,SPT(1) MOVEM 1,MMSPTN MOVSI 2,0(1) SETZ 1, ;START WITH CORE PAGE 0 MOVSI 3,400000 MOVSI 4,RWXB PGRI1: MOVEM 1,MMAP(2) ;MAKE MAPPED MON EQUIVALENT TO UNMAPPED HLLM 4,MMAP(2) ;PRIVATE POINTER, ALL ACCESS MOVEM 3,CST0(1) ;LEGAL AGE WORD MOVEM 1,CST1(1) ;BACKUP ADDRESS IS SELF MOVEM 2,CST2(1) ;OFN.PN ADDI 1,1 CAMGE 1,SWPCOR ;FILL TO END OF RES MON AOJA 2,PGRI1 MOVSI 4,010000 PGRI2: MOVEM 4,CST0(1) ; MAKE REST OF CORE UNAVAILABLE SETZM CST1(1) SETZM CST2(1) SETZM CST3(1) CAIGE 1,MAXCOR-1 AOJA 1,PGRI2 MOVSI 4,WRITEB ANDCAM 4,MMAP+1 ;PROTECT JSYS TABLE MOVEI 3,PATCH2+777 LSH 3,-^D9 ;FIRST PAGE OF RES MON IFE JTRPSW-1,< ;IF MAPPING RES MON FOR JSYS TRAPS JRST PGRI6 ;DON'T WRITE PROTECT RES MON > ;TEMPORARY TO ALLOW BUGCHK AND BUGHLT PGRI5: CAIGE 3,100 ;DON'T PROTECT PAGES ALWAYS MAPPED ANDCAM 4,MMAP(3) ;WRITE PROTECT RES MON ADDI 3,2 CAMGE 3,MONCOR ;MON WILL BE WRITE PROTECTED IF SOJA 3,PGRI5 ;MAPRESMON FLOP MANUALLY TURNED ON IFE JTRPSW-1,< PGRI6: > ;TO AVOID WRITE PROTECT ADDI 2,MMAP+2 HRLI 2,-1(2) SETZM -1(2) BLT 2,MMAP+PJMPG-1 ;ZERO REMAINDER OF MON MAP SETZM TOTRC SETZM NRPLQ MOVE 2,[XWD RPLQ,RPLQ] MOVEM 2,RPLQ ;REPLACEMENT QUEUE EMPTY SETZM PNDING SETZM SUMNRX MOVE 1,[DRMII2] ;INITIAL VALUE FOR DRMIN2 MOVEM 1,DRMIN2 ;NO NEW DRUM ASSIGNMENTS BELOW THIS MOVE 1,[DRMII1] ;INITIAL VALUE FOR DRMIN1 MOVEM 1,DRMIN1 ;DEASSIGN PAGES TRICKLED TO DISK ;IF DRMFRE FALLS BELOW THIS MOVE 1,[DRMII0] ;INITIAL VALUE FOR DRMIN0 MOVEM 1,DRMIN0 ;NO NEW JOBS ;IF DRMFRE FALLS BELOW THIS SETZM PGR71 MOVSI 1,400000 MOVEM 1,PGR72 CALL PGRRST MOVE 1,SWPCOR MOVEI 2,MAXCOR-1 CALL MAKPGA ; MAKE ALL PAGES AVAILABLE MOVE 1,NRPMX ;INITIALIZE NRPMIN MOVEM 1,NRPMIN CALL ASSPT ;GET SPT SLOT FOR JSYS DISP VECTOR MOVEI 2,NJDVPG DPB 2,[POINT 22,SPT(1),35] ;SET SPT WORD TO PT TO PAGE MOVEM 1,JDSPTP ;SAVE SPT INDEX FOR PAGE RET PGRRST: PGRCLD ; .. (CONO 0) AND DATAO PROT + REL PGRON ;TURN ON AND LOAD PAGER. (CONO 6) RET NRPMX: 5 ;RPLQ MIN, SHOULD BE .G. MINNR ;BOUNDARIES SET BY POSTLD MONCOR: 0 ;NUMBER PAGES OF RES MON SWPCOR: 0 ;FIRST PAGE OF REAL CORE FOR SWAPPING ;RESTART SWAPPER - REINITIATE IO OPERATIONS IN PROGRESS AT TIME OF CRASH SWPRST: SETZM IOIP MOVE 6,SWPCOR ;SCAN CST AND CHECK STATE OF PAGES SWPRS1: LDB 1,[POINT 6,CST0(6),5] ;GET STATE CODE CAIN 1,06 ;READ IN PROGRESS? JRST SWPRSR ;YES, GO RESTART IT CAIN 1,04 ;WRITE? JRST SWPRSW ;YES SWPRS2: CAMGE 6,NHIPG ;LOOKED AT ALL PAGES? AOJA 6,SWPRS1 ;NO RET SWPRSW: MOVSI 1,DWRBIT ;WRITE OPERATION AOSA IOIP ;COUNT WRITES IN PROGRESS SWPRSR: SETZ 1, ;READ OPERATION HRRI 1,0(6) MOVE 2,CST1(6) ;BACKUP ADDRESS TLNE 2,10 ;DISK? JRST SWPRS3 ;YES TLNN 2,16 ;DRUM? BUG(HLT,) CALL DRMIO JRST SWPRS2 SWPRS3: CALL DSKIO JRST SWPRS2 ;PERIODIC ROUTINE TO TRICKLE PAGES TO DISK DDMP: MOVE 1,TODCLK CAMGE 1,DDTIME ;TIME YET? RET ;NO SKIPE DISKP ;DISK ON SYSTEM, AND SKIPE NXTDMP ;DUMP REQUESTED? RET ;NO ADDI 1,^D60000 ;NEXT ONE DUE IN 30 SEC. MOVEM 1,DDTIME SETZ 0, ;CLEAR FLAGS MOVE 1,DRMFRE CAMGE 1,DRMIN1 ;ENOUGH DRUM SPACE? TLO 0,(1B0) ;NO, TAKE SPECIAL ACTION AOS NXTDMP ;TO DETECT REQUESTS DURING ROUTINE MOVE 11,FORKX ;CONSTRUCT HANDLE FOR DDPG2 HRLZ 11,FKPGS(11) HRRI 11,DDPG2 ;WILL BE USED LATER MOVSI 10,-NOFN ;PREPARE TO SCAN ALL OFN'S AOBJN 10,.+1 ;0 NOT USED DDMP9: NOSKED MOVE 1,SPTH(10) ;GET HASH WORD FOR THIS OFN JUMPLE 1,DDMP1S ;NOT IN USE MOVE 1,SPT(10) ;IN USE, GET CURRENT ADR TLNE 1,10 ;XB ON DISK? JRST DDMP1E ;FORGET IT MOVSI 2,SPTLKB IORM 2,SPTH(10) ;LOCK OFN AGAINST RELEASE MOVEI 1,0(10) ;MAP THE XB MOVE 2,[XWD RWX,DDPG1A] CALL SETMPG SETZ 6, PUSH P,6 CALL DDMPXA ;GET XB DISK ADDRESS MOVEM 6,0(P) ; SAVE WRITE FLAG FOR XB CAIGE 7,DST+NDST ;IN DST? CAIGE 7,DST JRST .+3 ;NO MOVSI 3,BWRBIT ;YES, CLEAR BACKUP WRITE BIT ANDCAM 3,0(7) OKSKED MOVE 2,[XWD DDPG2A,DDPG2A+1] SETZM DDPG2A ;ZERO A PAGE TO GET THE BACKUP XB BLT 2,DDPG2A+777 MOVSI 7,-1000 ;SCAN ALL WORDS OF XB DDMP8: MOVE 1,DDPG1A(7) ;WORD FROM XB JUMPE 1,DDMP61 ;QUICK CHECK FOR NULL NOSKED DDMP81: MOVE 1,DDPG1A(7) ;WORD FROM XB JUMPE 1,DDMP6 ;NOT IN USE TLNN 1,SHRBIT ;SHARE POINTER? JRST DDMP4 ;NO, PRIVATE LSH 1,-^D9 ;GET SPT NUMBER ANDI 1,SPTM MOVE 1,SPT(1) TLZ 1,-1B31 ;FLUSH SHARE COUNT JRST DDMP4 DDMP6: OKSKED JRST DDMP61 DDMP1E: TLNE 1,-1B31 ;SHARE COUNT 0? JRST DDMP1S ;NO SETOM SPTH(10) ;YES, RELEASE OFN SOS NOF DDMP1S: OKSKED JRST DDMP1 DDMPXA: MOVE 1,SPT(10) ;SET ABOUT FINDING DISK ADDRESS TLNE 1,17 JRST DDMPX1 ;IN DST MOVE 7,CST2(1) CAIE 7,0(10) ;ALL CONSISTENT? JRST DDBAD1 ;NO MOVE 7,CST0(1) ;GET CORE WRITE BIT TLNE 7,(CORMB) ;WRITTEN IN CORE? SETO 6, ;YES MOVEI 7,CST1(1) ;IF IN CST, REMEMBER WHERE DDMPX2: MOVE 1,0(7) TLNE 1,10 ;DISK? RET ;YES, DONE DDMPX1: MOVE 2,1 CALL GDSTX MOVE 7,DST(2) ;GET DRUM WRITE BIT TLNE 7,BWRBIT ;WRITTEN ON DRUM? SETO 6, ;YES MOVEI 7,DST(2) ;REMEMBER WHERE DISK ADDRESS IS JRST DDMPX2 DDMP4: TLNE 1,617700 ;ANY STRANGE BITS? JRST DDBAD ;YES, SKIP IT TLNE 1,10 ;DISK? JRST DDMP3 ;YES, ALL SET TLNN 1,16 ;DRUM TLNN 1,17 ;OR CORE? JRST DDMP5 ;YES, PROCESS IT JRST DDMP6 ;UNASSIGNED, IGNORE IT DDMP3: OKSKED TLNN 1,10 ;JUST MAKE SURE WE HAVE DISK ADR JRST DDBAD MOVEM 1,DDPG2A(7) ;STORE DISK ADDRESS IS XB COPY LDB 1,[POINT 12,DDPG1A(7),13] ;GET ACCESS BITS FROM ORIG PTR DPB 1,[POINT 14,DDPG2A(7),13] ;STORE THEM IN XB COPY DDMP61: AOBJN 7,DDMP8 ;SCAN OVER WORDS IN XB DDMPXB: NOSKED POP P,1 ;GET XB WRITE FLAG JUMPE 1,DDMPX3 ;DON'T WRITE XB IF NOT CHANGED MOVE 1,11 ;GET ID OF COPY PAGE CALL MLKPG ;LOCK THE PAGE PUSH P,1 ;SAVE CORE PAGE NUMBER CALL DDMPXA ;GET XB DISK ADDRESS MOVE 2,[1B14+1000] ;DISK IO CONTROL WORD, WRITE+1000 WORDS TLZE 1,NEWFB ;CLEAR NEW FILE BIT MOVEM 1,0(7) OKSKED PUSH P,2 CALL CVDSK ;CONVERT TO HARDWARE FORMAT POP P,2 POP P,3 ;CORE PAGE NUMBER LSH 3,^D9 CALL UDSKIO ;OPERATE DISK AOS DSKWR ;COUNT OPERATIONS MOVE 6,1 ;SAVE ERROR BITS MOVE 1,11 CALL MULKPG ;UNLOCK PAGE JUMPN 6,.+1 ;NON-ZERO MEANS ERRORS NOSKED DDMPX3: MOVSI 2,SPTLKB ANDCAM 2,SPTH(10) ;UNLOCK OFN MOVE 1,DDPG1A ;MAKE SURE XB IN CORE BEFORE UNMAPPING SETZ 1, MOVEI 2,DDPG1A CALL SETMPG ;UNMAP XB OKSKED DDMP1: AOBJN 10,DDMP9 ;COUNT OFN'S MOVNS NXTDMP ;RESET IF NO INTERVENING REQUESTS SETOM CGFLG ;REQUEST GARBAGE COLLECTION RET DDMP5: TLNN 1,17 ;IN CORE? JRST DDMP52 ;YES MOVE 2,1 ;ON DRUM, GET DST WORD CALL GDSTX MOVE 1,DST(2) TLNN 1,BWRBIT ;CHANGED FROM BACKUP? JUMPGE 0,DDMP3 ;NO, IGNORE IF NOT LOW ON DRUM SPACE MOVE 1,DDPG1A(7) ;GET PAGE SWAPPED IN TLNE 1,SHRBIT JRST DDMP51 ;SHARE POINTER, GET SPTN MOVSI 1,0(10) ;CONSTRUCT OFN.PN HRRI 1,0(7) DDMP53: PUSH P,7 CALL SWPINW ;SWAP IN PAGE AND WAIT POP P,7 JRST DDMP81 ;NOW PAGE IS IN CORE DDMP51: LSH 1,-^D9 ;GET SPTN ANDI 1,SPTM JRST DDMP53 DDMP52: TRNE 1,-MAXCOR ;LIKELY PAGE? JRST DDBAD ;NO MOVSI 6,400000 ;FLAG TO NOTE IF WRITING NEEDED AND 6,0 ;INIT TO DRUM SPACE FLAG MOVE 2,CST0(1) TLNE 2,(CORMB) ;PAGE WRITTEN WHILE IN CORE? SETO 6, ;YES MOVE 2,CST1(1) ;GET BACKUP ADR TLNE 2,10 ;DISK? JRST DDMP54 ;YES CALL GDSTX MOVE 2,DST(2) ;GET NEXT BACKUP ADR TLNE 2,BWRBIT ;CHANGED ON DRUM? SETO 6, ;YES DDMP54: JUMPE 6,DDMP55 ;DISK ADR NOW IN 2, WRITING NEEDED? PUSH P,7 CALL AGESET ;YES POP P,7 MOVSI 3,DSKSWB IORB 3,CST3(1) ;REQUEST DISK SWAP AT NEXT SWAP TIME CALL SWPOT0 ;SWAP IT OUT NOW SETOM 0(P) ;FORCE WRITING OF XB TOO DDMP55: MOVE 1,2 JRST DDMP3 ;LOSSAGE PRINTOUT DDBAD1: POP P,1 DDBAD: POP P,1 ;FLUSH JUNK SETZM NSKED HRROI 1,[ASCIZ / *****BAD INDEX BLOCK, OFN /] PSOUT MOVEI 1,101 MOVEI 2,0(10) MOVEI 3,^D8 NOUT JFCL MOVEI 1,EOL PBOUT MOVSI 2,SPTLKB ANDCAM 2,SPTH(10) ;UNLOCK OFN JRST DDMP1 ;ASSIGN OFN ; AC1/ 14-35 INDEX BLOCK FILE ADDRESS (DISK, DRUM OR CORE) ; 5-13 CLASS FIELD (IF DISK) ; 1 WRITE BIT ; 2 THAWED BIT ; 3 NEW FILE BIT ;RETURN SKIP WITH OFN IN AC1 IF PROPER OPENING ;RETURN NO-SKIP IF ILLEGAL SHARED OPENING (ILLEGAL CONFIGURATION ; OF THAWED AND WRITE BITS) ASOFN: TLNN 1,10 ;DISK? RET ;NO, RETURN BAD MOVEI 7,1 ;SAY NO GC HAS BEEN DONE YET ASOF0: NOSKED PUSH P,1 TLZ 1,-1B31 ;FLUSH CLASS AND BITS MOVE 6,1 MOVE 4,MAXSPL ;MAX NUMBER OF PROBES INTO SPTH SETO 5, SETZ 1, ;START SEARCH WITH 0 ASOF1: ADDI 1,1 ;LOOK LINEARLY MOVEI 3,0(1) REPEAT 0,< ;THIS IS HASH LOOKUP NOT CURRENTLY USED IMUL 1,[5654123] ;HASH INDEX BLOCK ADDRESS HLRZS 3,1 ;USE LEFT HALF ANDI 3,NOFN-1 ;MAX NUMBER OPEN FILES JUMPE 3,ASOF1 ;DON'T USE SLOT 0 > MOVE 2,SPTH(3) ;GET ENTRY JUMPLE 2,ASOF2 ;0 IS FREE, -1 IS DELETED TLZ 2,-1B31 ;FLUSH BITS CAMN 2,6 ;COMPARE ADDRESSES JRST ASOF3 ;FOUND ASOF7: SOJG 4,ASOF1 ;COUNT TRYS AND PROBE AGAIN JUMPGE 5,ASOF6 ;NOT FOUND. DELETED ENTRY ENCOUNTERED? CAIL 1,NOFN-1 ;NO, OFN TABLE FULL? JRST ASOFAI ;MAYBE TRY AGAIN AFTER CORE GC AOS MAXSPL ;NO, INCREASE MAX LOOK COUNT JRST ASOF1 ;KEEP LOOKING FOR USABLE SLOT ASOF2: JUMPE 2,ASOF4 ;FREE => NOT FOUND JUMPGE 5,ASOF7 ;FIRST DELETED ENCOUNTERED? MOVE 5,3 ;YES, SAVE IT JRST ASOF7 ;ASOFN (CONT.) ASOF4: JUMPL 5,.+2 ;DELETED ENCOUNTERED? ASOF6: MOVE 3,5 ;YES, USE IT POP P,1 ;RECOVER CLASS AND BITS TLZE 1,1B21 ;NEWLY ASSIGNED XB? TLO 6,NEWFB ;YES, INDICATE IN DISK ADDRESS MOVEM 1,SPTH(3) MOVEM 6,SPT(3) ;PUT ADDRESS IN SPT AOS NOF ;COUNT OPEN FILES MOVSI 1,1B31 ADDM 1,SPT(3) ;BUMP SHARE COUNT PUSH P,3 ;SAVE OFN CALL SETXB1 ;MAP XB POP P,3 OKSKED ;PREVENT PAGE-FAULT WHILE NOSKED .. DCA MOVE 1,CXBPGA ;GET XB IN CORE NOSKED ;GO NOSKED AGAIN .. DCA MOVE 1,SPT(3) ;CORE ADDRESS MOVSI 2,SWPERR TDNE 2,CST3(1) ;DISK ERROR IN XB? JRST ASCHK3 ;YES, DON'T OPEN MOVSI 1,-1000 ;SETUP TO SCAN XB ASCHK1: MOVE 2,CXBPGA(1) ;GET WORD FROM XB JUMPE 2,ASCHK2 ;NOT IN USE TLC 2,ACCESB+10 ;MUST HAVE ACCESS AND DISK BITS ON, TLNE 2,777770-RWX ;RWX AND OTHER ADDRESS BITS DONT CARE, JRST ASCHK3 ;OTHERS ALL OFF, OTHERWISE DONT OPEN ASCHK2: AOBJN 1,ASCHK1 CALL RELCXB ;OK, RELEASE XB JRST ASOF9 ASCHK3: CALL RELCXB ;FILE NO GOOD, RELEASE XB MOVE 1,SPT(3) ;CLEAR OFN AND CORE PAGE SETOM SPTH(3) SOS NOF CALL DECOR SETZM CST2(1) JSP 4,ONRQ MOVEI 1,OPNX16 ;ERROR NUMBER FOR BAD XB SKORET: OKSKED RET ;RETURN BAD ;SHARED OPEN, CHECK WRITE AND THAWED BITS FOR LEGAL COMBINATION ASOF3: MOVSI 2,SPTLKB TDNE 2,SPTH(3) ;LOCKED BY DDMP? JRST ASOFW1 ;YES POP P,2 ;RECOVER CLASS AND BITS MOVSI 1,-1B31 TDNN 1,SPT(3) ;SHARE COUNT 0? JRST ASOF8 ;YES (FILE EFFECTIVELY NOT OPEN) MOVE 1,SPTH(3) ;GET EXISTING BITS XOR 1,2 ;XOR PRODUCES 0 IF BITS THE SAME TLNE 1,THAWB ;THAWED BITS EQUAL? JRST ASOFB ;NO, ILLEGAL OPEN MOVE 1,SPTH(3) IOR 1,2 TLNN 1,FILWB ;BOTH WRITE BITS 0? JRST ASOF5 ;YES, LEGAL OPENING, NO CHANGE TO WB TLNN 1,THAWB ;THAWED BITS 1? JRST ASOFB ;NO, ILLEGAL TO HAVE SHARED WRITING AND 2,[XWD FILWB,0] ;LEGAL OPENING, THAWED BITS BOTH 1 IORM 2,SPTH(3) ;IOR WRITE BITS ASOF5: MOVSI 1,1B31 ;INCREMENT SHARE COUNT ADDM 1,SPT(3) ASOF9: OKSKED MOVEI 1,0(3) ;RETURN OFN (SPT INDEX) JRST RSKP ASOF8: MOVE 1,SPT(3) TLNE 1,17 ;NOW IN CORE? JRST ASOF81 ;NO MOVSI 4,DWRBIT ;YES, WAIT FOR ANY WRITE TO COMPLETE TDNE 4,CST3(1) JRST ASOFW2 ASOF81: XOR 2,SPTH(3) ;SET THAW AND WRITE BITS TO GIVEN AND 2,[XWD FILWB+THAWB,0] XORM 2,SPTH(3) JRST ASOF5 ;RETURN OK ASOFB: MOVEI 1,OPNX9 ;ERROR NUMBER FOR FILE BUSY JRST SKORET ASOFW2: SKIPA 1,2 ASOFW1: POP P,1 OKSKED ;HAVE TO WAIT FOR SOMETHING CAIA ;WAIT A LITTLE WHILE, THEN TRY JRST ASOFN ;AGAIN FROM THE TOP JSYS BLOCK1 ;THIS RETURNS .-1 ASOFAI: SOJL 7,ASOFA1 ;BEEN HERE BEFORE? OKSKED MOVEI 1,FSHBAL ;POS. NUMBER MOVEM 1,FSHBAL ;REQUEST TO GC CORE BUT KEEP ONLINE CALL DISE## ;WAIT FOR IT TO HAPPEN SETZM NXTDMP SETZM DDTIME ;CAUSE DDUMP TO RUN AOS JB0FLG## MOVEI 1,NXTDMP CALL DISL## ;WAIT FOR IT TO BE DONE POP P,1 ;RECOVER ARG JRST ASOF0 ;TRY ONCE MORE ASOFA1: POP P,1 ;FLUSH ARG MOVEI 1,OPNX10 ;"NO ROOM" JRST SKORET ;OKSKED AND RETURN ;RELEASE OPEN FILE NUMBER, OFN IN AC1 RELOFN: CALL CKSPLK ; CHEK IF SPT LOCKED BY DDMP. RET NOSKED MOVEI 3,0(1) CALL SETXB1 ;MAP INDEX BLOCK LDB 2,[POINT 14,SPT(1),13] ;GET SHARE COUNT SETO 4, ;RETURN -1 IF NOT COMPLETELY CLOSED CAIE 2,1 ;IS THIS FINAL CLOSE? JRST RELOF1 ;NO MOVSI 3,-1000 ;SCAN XB SETZ 4, ;INIT COUNT OF IN-USE PAGES RELOF3: MOVE 2,CXBPGA(3) ;GET XB WORD JUMPE 2,RELOF2 ;EMPTY TLNN 2,10 ;ADDRESS OK IF ON DISK OR IN CORE TLNN 2,16 TLNE 2,SHRBIT+INDBIT ;POINTER TYPE OK IF PRIVATE JRST RELBAD TLNN 2,10 TLNN 2,17 ;UNREFERENCED PAGE? AOJA 4,RELOF2 ;NO, COUNT IN-USE PAGE SETZM CXBPGA(3) RELOF2: AOBJN 3,RELOF3 RELOF1: MOVSI 2,-1B31 ;REDUCE SHARE COUNT OF XB ONCE MORE ADDM 2,SPT(1) ;FOR CLOSING MOVE 1,SPT(1) TLNN 1,-1B31 ;STILL IN USE? CALL SWPOT0 ;NO, SWAP OUT MOVE 1,4 CALL RELCXB ;RELEASE TEMP MAPPING OKSKED RET RELBAD: BUG(CHK,) MOVE 2,SPT(1) MOVSI 3,SWPERR IORM 3,CST3(2) ;INDICATE ERROR IN PAGE SO IT WON'T JRST RELOF1 ;BE WRITTEN ON DISK CKSPLK: NOSKED MOVSI 2,SPTLKB TDNN 2,SPTH(1) RET OKSKED HRLZS 1 HRRI 1,SPLTST JSYS EDISMS HLRZS 1 JRST CKSPLK SPLTST: MOVSI 2,SPTLKB TDNN 2,SPTH(1) JRST 1(4) JRST 0(4) ;ASSIGN PSB FOR NEW PROCESS ASPSB: NOSKED CALL ASSPT JRST SKORET ASSPT: SKIPG 1,FRESPT ;ANY FREE CELLS? BUG(HLT,) MOVE 1,0(1) EXCH 1,FRESPT SUBI 1,SPT AOS SPTC ;ASSIGN SPT SLOT MOVSI 2,1B31+1 MOVEM 2,SPT(1) ;SHARE COUNT OF 1, NO ADDRESS SETZM SPTH(1) RET ;DEASSIGN SPT AND RELEASE STORAGE DESPTN: NOSKED CALL DESPT JRST SKORET DESPT: MOVSI 2,-1B31 ADDB 2,SPT(1) ;REDUCE SHARE COUNT TLNE 2,-1B31 ;NOW ZERO? BUG(HLT,) MOVE 3,2 PUSH P,1 CALL REMFP1 ;RELEASE CORE AND/OR DRUM POP P,1 ADDI 1,SPT EXCH 1,FRESPT ;PUT ON FREE LIST EXCH 1,@FRESPT SOS SPTC RET ;DELETE XB ASSOCIATED WITH OFN ;LAST STAGE OF DELETE FILE DELOFN: CALL WTSPT ;WAIT FOR SPT TO BE UNSHARED NOSKED JSP 4,WTSPTT ;SHARE COUNT NOW 1? JRST DELO1 ;NO, GO WAIT SOME MORE MOVSI 2,-1B31 ;SHARE COUNT SHOULD NOW BE 1 ADDB 2,SPT(1) ;FOR LAST OPENING TLNE 2,-1B31 ;NOW 0? BUG(HLT,) MOVE 3,2 SETOM SPTH(1) PUSH P,1 CALL REMFP1 ;DELETE ALL STORAGE POP P,1 SOS NOF OKSKED RET DELO1: OKSKED JRST DELOFN ;READ MAP GIVEN VIRTUAL ADDRESS MRMAP: CALL FPTA ;GET PAGE TABLE ADDRESS ;GENERAL MAP READ ;ENTER HAVING PTN.PN IN 1 ; RETURN +1 IF PTN.PN ; RETURN +2 IF OFN.PN MRPT: CALL SETCPT MOVE 2,CPTPGA(1) ;GET MAP WORD JUMPE 2,RDMQ5 ;EMPTY PUSH P,1 ;SAVE ORIG IDENT PUSH P,2 TLNN 2,SHRBIT+INDBIT ;PRIVATE? JRST MRMP ;YES TLNN 2,SHRBIT ;SHARED OR INDIRECT JRST MRMI ;INDIRECT LSH 2,-^D9 ;GET SPT NUMBER ANDI 2,SPTM CAIL 2,NOFN ;INDEX BLOCK? MOVE 2,SPTH(2) ;NO, GET OFN.PN MRM1: MOVE 1,2 HLRZ 2,1 CAIL 2,NOFN ;OWNED BY OFN? JRST MRMQ ;NO AOS -2(P) ;YES, SKIP RETURN MRMQ1: POP P,2 ;ORIGINAL POINTER POP P,3 ;FLUSH ORIG IDENT AND 2,[XWD RWX+TRAPUB+COPYB,0] TLO 2,1B23 ;EXISTS BIT JRST RELCPT MRMI: LSHC 2,-^D9 ;RE-FORMAT INTO OFN.PN OR PTN.PN ANDI 2,SPTM LSH 3,-^D9 LSHC 2,^D18 JRST MRM1 MRMP3: SUB P,BHC+3 ;CLEAR STACK RDMQ5: SETZB 1,2 ;RETURN 0 JRST RELCPT MRMQ: CAME 1,-1(P) ;OWNED BY ORIG IDENT? JRST MRMQ1 ;NO MRMP: PUSH P,1 HLRZ 2,1 CAMN 2,MMSPTN ;SWP MON MAP? JRST MRMP1 ;YES, DON'T PUT IN PMF CALL RELCPT SKIPGE 1,JOBPMF ;ASSIGN NEW PAGE FROM PMF JRST MRMP3 ;DON'T HAVE ONE, RETURN 0 FFFFP CALL JFNOFN BUG(HLT,) MOVSI 3,RWX ;PUT PAGE IN PMF WITH ALL ACCESS MOVE 2,1 EXCH 1,0(P) CALL SETPT ;PUT PAGE IN PMF MRMP1: POP P,2 ;OFN.PN OF NEW PAGE JRST MRM1 ;READ PAGE ACCESSIBILITY ; CALL: IN 1 ; PTN.PN ; CALL MRPACS ; RETURNS: ; IN 1 ; PAGE ACCESS PER RPACS SPEC ; IN 3 ; LAST PAGE TABLE ENTRY (MEANINGLESS UNLESS USRLKB) ; CLOBBERS AC 2 MRPACS: PUSH P,[0] PUSH P,[XWD RWXB+TRAPUB+COPYB+USRLKB,0] MRP4: HLRZ 3,1 ;SOURCE PTN CAIG 3,0 BUG(HLT,) CALL SETXB1 ;MAP PT MOVE 3,CXBPGA(1) ;GET MAP WORD SKIPN -1(P) ;FIRST MAP WORD? HLRZM 3,-1(P) ;YES, SAVE FIRST PT ACCESS TLC 3,TRAPUB+COPYB+USRLKB ;FOR THESE BITS, WE'RE AND'ING 0'S ANDM 3,0(P) ;COMPUTE AND OF ALL MAP WORDS TLNN 3,INDBIT ;INDIRECT? JRST MRP2 ;NO, SHARED OR PRIVATE CALL RELCXB ROTC 2,-^D9 ;REFORMAT INTO PTN.PN ANDI 3,SPTM LSH 3,^D9 ROTC 2,^D9 MOVE 1,3 JRST MRP4 MRP2: POP P,1 ;AND OF ALL MAP WORDS POP P,2 ;FIRST POINTER ACCESS TLC 1,TRAPUB+COPYB+USRLKB ;BITS FOR WHICH AND'ING 0'S JUMPE 2,RELCXB ;RETURN 0 IF FIRST POINTER WAS 0 TRNN 2,SHRBIT+INDBIT ;FIRST PTR PRIVATE? TLO 1,(1B10) ;YES, SO INDICATE TLZE 1,ACCESB ;ANY ACCESS? TLO 1,(1B5) ;YES, SET BIT IN RESULT TRNE 2,INDBIT ;FIRST POINTER INDIRECT? TLO 1,(1B6) ;YES, NOTE ANDI 2,RWX+TRAPUB+COPYB+USRLKB ;BITS OF ORIG PTR TO GIVE TO USER HRRI 1,1B23(2) ;ORIG PTR ACCESS WITH EXISTS BIT TO RH TLNN 3,SHRBIT ; SHARE POINTER? JRST RELCXB ;RELEASE PT AND RETURN LSH 3,-9 ; YES, EXTRACT ANDI 3,SPTM ; SPT INDEX MOVE 3,SPT(3) TLNN 3,16 ; DISC OR DRUM? TLNN 3,1 ; NO -- NON-EXISTENT JRST RELCXB ; EXISTS, DONE TLZ 1,(1B5) ; NON-EXISTENT, CLEAR "EXISTS" BIT JRST RELCXB ;MRPAC - JSYS FOR MONITOR DDT .MRPAC: JSYS MENTR MOVE 2,0(P) ;RETURN PC TLNE 2,UMODF ;FROM MONITOR? JRST ITRAP ;NO, ILLEGAL FROM USER TLNE 1,400000 ;USER? JRST [ CALL FPTA ;YES, GET PTN.PN JRST MRPC3] MOVEI 2,0(1) ;MONITOR, GET ADDRESS CAIL 2,100000 ;RESIDENT MON? JRST MRPC5 ;NO. REPEAT 1,< ;REMOVE THIS CODE TO ASSUME RESIDENT MON IS NEVER MAPPED NOSKED ;YES. SEE IF THE RESIDENT MON IS MAPPED SETCM 3,PGR72 ;PICK UP NOT-(THE CURRENT AGE REGISTER) TLO 3,100000 ;MAKE SURE THAT IT WON'T CAUSE A TRAP EXCH 3,CST0/1000+CST0 ;NOW THE AGE OF CST0 IS NOT CURRENT MONCLR (/1000) ;CLEAR AR'S USED FOR MAPPING CST0 EXCH 3,CST0/1000+CST0 ;GET THE (UPDATED?) CST0 ENTRY FOR CST0 XOR 3,PGR72 ;COMPARE WITH THE PAGER AGE REGISTER OKSKED TLNN 3,777000 ;HAS THE CST0 ENTRY BEEN UPDATED? JRST MRPC6 ;YES. THE RESIDENT MON IS BEING MAPPED > ;END OF CODE TO DETERMINE WHETHER RESIDENT MON IS MAPPED MOVSI 1,RWX+1B28 ;NO. MEANS PRIVATE AND ALL ACCESS JRST MRPC2 MRPC5: CAIGE 2,PPRMA ;NON-RES MON? JRST MRPC6 ;NO. MAPPED RESIDENT MONITOR CAIL 2,CXBPGA ;CHECK SPECIAL PAGES CAILE 2,CPYPGA ;SETPT, ETC. PAGES? CAIGE 2,PPRMA+NRSPG*1000 ;SWAPPER PAGES? JRST MRPC1 ;YES, RETURN NO-ACCESS CALL FPTA MRPC3: CALL MRPACS MRPC2: UMOVEM 1,2 ;RETURN RESULT IN 2 LIKE RPACS JRST MRETN MRPC1: MOVSI 1,(1B10) ;NO-ACCESS JRST MRPC2 MRPC6: LSH 2,-^D9 ;HERE FOR MAPPED RESIDENT MONITOR SKIPE 1,MMAP(2) ;REQUESTED PAGE EXISTS? TLO 1,1B28 ;YES JRST MRPC2 ;RETURN CONTENTS OF MMAP ;SET PAGE ACCESSIBILITY MSPACS: PUSH P,2 ; SAVE DESIRED PAGE ACCESS CALL SETCPT ;MAP PT POP P,2 SKIPN 3,CPTPGA(1) ;PAGE EXISTS? JRST RELCPT ; NO. IGNORE CALL CAMGE 1,[NOFN,,0] ; FILE PAGE TLZ 2,TRAPUB+COPYB+USRLKB ; YES, DISALLOW THESE TLNE 3,INDBIT!SHRBIT ; NOT PRIVATE POINTER? TLZ 2,USRLKB ; YES, FORBID USER LOCK XOR 3,2 ; GET BITS THAT ARE BEING CHANGED AND 3,[XWD RWX+TRAPUB+COPYB+USRLKB,0] XORM 3,CPTPGA(1) ; CHANGE THE ONES WE WANT TLNN 3,USRLKB ; CHANGE USRLKB? JRST RELCPT ; NO, DONE TLNN 2,USRLKB ; NOW LOCKED? JRST MULKPG ; NO, UNLOCK THE PAGE JRST MLKPG ; YES, LOCK THE PAGE ;SET PAGE IN MONITOR OR USER MAP (INTERNAL MONITOR CALL) ; AC1/ OFN,,PN (OFN IS SPT POINTER, PN IS 0-777) ; AC2/ 18-35 VIRTUAL ADDRESS OF PAGE (NOT PAGE NUMBER) ; 0 1 => USER MAP, 0 => MONITOR MAP ; 2-4, 8, 9 READ, WRITE, XCT ALLOW BITS (SAME AS PAGER MAP WORD) SETMPG: ADD P,BHC+7 ;SAVE AC'S JUMPGE P,MSTKOV MOVEM 1,-6(P) ;THIS IS FASTER THAN BLT OR PUSH MOVEM 2,-5(P) MOVEM 3,-4(P) MOVEM 4,-3(P) MOVEM 5,-2(P) MOVEM 6,-1(P) MOVEM 7,0(P) HLLZ 3,2 ;GET ACCESS AND DISPOSAL PUSH P,3 EXCH 1,2 CALL FPTA ;CONVERT ADDRESS TO PTN.PN JRST SETP8 ;SET PAGE TABLE (FOR PROCESS OR FILE) ; AC1/ SOURCE IDENTIFIER ; AC2/ DESTINATION IDENTIFIER ; AC3/ 2-4, 8, 9 ACCESS PERMISSION, 15-17 DISPOSAL ;IDENT IS OFN.PN (PAGE IN FILE), 0.OFN (INDEX BLOCK), ; PTN.PN (PAGE IN PROCESS), OR 0.PTN (PROCESS PT) SETPT: ADD P,BHC+7 ;SAVE AC'S JUMPGE P,MSTKOV MOVEM 1,-6(P) MOVEM 2,-5(P) MOVEM 3,-4(P) MOVEM 4,-3(P) MOVEM 5,-2(P) MOVEM 6,-1(P) MOVEM 7,0(P) PUSH P,3 ;SAVE ACCESS BITS EXCH 1,2 SETP8: CALL RELMPG ;RELEASE EXISTING PAGE JRST SETPT1 ; RELMPG FAILED JUMPE 2,SETPT1 ;NO NEW PAGE TO SET SETP5A: CAMN 1,2 ;DON'T ALLOW MAP TO SELF JRST SETPF1 HLRZ 3,2 ;GET OFN JUMPE 3,SETMXB ;OFN=0 MEANS SPTN IN RH TDNE 2,[XWD -SPTM-1,777000] ;LEGAL PTN AND PN? BUG(HLT,) CALL SETXB1 ;MAP INDEX BLOCK SETP72: MOVE 3,CXBPGA(2) ;GET WORD FROM XB HLRZ 4,1 ;GET DESTINATION PTN CAIGE 4,NOFN ;FILE? JRST SETP7 ;YES HLRZ 4,2 ;GET SOURCE PTN CAIL 4,NOFN ;PROCESS? JRST SETP5 ;YES, GO SETUP INDIRECT POINTER TLNE 3,SHRBIT+INDBIT ;PRIVATE? JRST SETMP3 ;NO TLNN 3,ACCESB ;PAGE EXISTS? JRST SETP3 ;NO, GO CREATE IT SETP4: MOVE 4,SPTC ;YES CAMGE 4,SPC0 ;ROOM IN SPT? (SPT < C FULL) JRST SETMP6 ;YES SETCM 4,3 ;GET ACCESS OF SOURCE TLNE 4,RWX ;ALL POSSIBLE? SKIPG FRESPT ;NO, SHOULDN'T USE IND PTR JRST SETP5 ;USE IND PTR JRST SETMP6 ;USE SHR PTR ;HERE, WE ARE SUPPOSED TO RETURN AN INDIRECT POINTER. ;1/ DESTINATION ID (PTN,,PN) ;2/ SOURCE ID (PTN,,PN) ;3/ CONTENTS ON SOURCE PAGE TABLE SETP5: SKIPGE INDFLG ;ALLOWING USE OF INDIRECT POINTERS? JRST SETPF2 ;NO, GO TRY ALTERNATIVES REPEAT 0,< ;OLD CODE TLNE 3,INDBIT ;SOURCE CONTAINS IND PTR? JFCL [ CALL RELCXB ;YES, TRACE DOWN ;;; REMOVED DUE TO ACCESS CK FAILING ROTC 2,-^D9 ;CONSTRUCT IDENT OF PAGE POINTED ANDI 3,SPTM ;TO BY IND PTR LSH 2,-^D9 ROTC 2,-^D18 JRST SETP5A] ;AND USE THAT AS SOURCE > REPEAT 1,< ;NEW CODE ;CHECK TO FORBID INDIRECT POINTER LOOP. EVERY VIRTUAL ADDRESS MUST ;EVENTUALLY POINT TO A PHYSICAL STORAGE ADDRESS. INDIRECT LOOP IS ;CHECKED BY TRACING THE CHAIN TO SEE IF IT EVER POINTS AT THE ;MAP ENTRY WHERE THE NEW POINTER WILL BE PLACED. MOVE 5,2 ;SAVE FOR SETP58 TLNN 3,INDBIT ;SOURCE PT CONTAINS AN @ PTR? JRST SETP58 ;NO. PRIVATE, SHARED, OR EMPTY SETP51: LDB 2,[POINT 13,3,26] ;GET @ PTN ANDI 3,777 ;GET @ PN MOVSS 2 IORI 2,0(3) ;FORM @ PTN,,PN ID CAMN 2,1 ;SAME AS DESTINATION JRST SETPF1 ;YES. THIS PMAP WOULD FORM LOOP IF ;ALLOWED TO FINISH. HLRZ 3,2 ;GET PTN FOR SETXB1 JUMPE 3,SETP58 ;SPT -- OK. CALL SETXB1 ;MAP IT OKSKED SKIP CXBPGA NOSKED MOVE 3,CXBPGA(2) ;GET CONTENTS OF @ PT WORD HLRZ 4,3 ;GET OFN/PTN CAML 4,[NOFN,,0] ;IF @ TO FILE PAGE, GET OUT (OK) TLNN 3,INDBIT ;IF NOT ANOTHER @, OK TOO. CAIA JRST SETP51 ;LOOP THROUGH ANOTHER @ LINK SETP58: MOVE 2,5 > LSHC 2,-^D9 ;CONSTRUCT INDIRECT POINTER LSH 2,-^D9 LSHC 2,^D9 TLO 2,ACCESB+INDBIT SETMP4: LDB 3,[POINT 13,2,26] ;GET OFN OF INDEX BLOCK SETMP5: MOVSI 4,1B31 CAIE 3,0 ;IF NO OWNING PT ADDM 4,SPT(3) ;INCREMENT SHARE COUNT OF INDEX BLOCK POP P,3 ;RECOVER ACCESS BITS XOR 2,3 ;PUT ACCESS BITS IN PTR TLZ 2,RWX+TRAPUB+COPYB ;USER ALLOWED TO SPECIFY THESE XOR 2,3 MOVEM 2,CPTPGA(1) ;PUT MAP WORD IN MAP SETPT2: CALL RELCPT ;RELEASE PT MAPPING CALL SWPCXB ;GET RID OF INDEX BLOCK MOVE 1,-6(P) MOVE 2,-5(P) MOVE 3,-4(P) MOVE 4,-3(P) MOVE 5,-2(P) MOVE 6,-1(P) MOVE 7,0(P) SUB P,BHC+7 CALL RELCXB OKSKED RET SETPT1: POP P,3 ;FLUSH ACCESS BITS JRST SETPT2 SETP3: MOVSI 3,RWXB+1 SETP3A: MOVEM 3,CXBPGA(2) ;PUT IN XB JRST SETP4 ;SETMPG (CONT.) SETPF2: TLNE 3,SHRBIT+INDBIT ;SHARED NOW? JRST SETMP3 ;YES, USE SAME POINTER JUMPE 3,[MOVSI 3,RWXB+1 ;IF SOURCE CURRENTLY EMPTY, JRST SETP3A] ;USE UNASSIGNED ADDRESS INDICATION SKIPLE FRESPT ;ANY SPT SPACE AT ALL? JRST SETMP6 ;YES, GO ASSIGN A SLOT MOVEI 1, ;GIVE ERROR INDICATION JRST SETPTE SETMP3: MOVE 2,3 ;ALREADY SHARED, USE SAME POINTER TLNE 2,INDBIT ;INDIRECT? JRST SETMP4 ;YES SETMP7: LDB 3,[POINT 13,2,26] MOVSI 4,1B31 ;SHARED, ADDM 4,SPT(3) ;INCREMENT SHARE COUNT IN SPT HLRZ 3,SPTH(3) ;GET OFN FOR THIS PAGE JRST SETMP5 ;GO INCREMENT SHARE COUNT OF XB SETMP6: SKIPG 4,FRESPT ;ASSIGN NEW SPT SLOT BUG(HLT,) MOVE 4,0(4) ;GET CDR EXCH 4,FRESPT ;LIST OF FREE SLOTS SUBI 4,SPT ;MAKE RELATIVE AOS SPTC ;COUNT OF USED SPT ENTRIES TLNE 3,17 ;IN CORE? JRST SETP2 CAME 2,CST2(3) ;CHECK OLD OWNERSHIP BUG(HLT,) MOVEM 4,CST2(3) ;RECORD NEW LOCATION OF CORE ADDRESS HLRZ 6,2 ;YES, UPDATE LOCK COUNT FOR MOVE 6,SPT(6) ;OWNING PT MOVSI 5,-PLKV ;REDUCE IT, BECAUSE IT WILL HAVE ADDM 5,CST1(6) ;ONE LESS CORE ADDRESS IN IT SETP2: TLZ 3,-1B31 ;FLUSH BITS IN ORIGINAL POINTER MOVEM 3,SPT(4) ;PUT IT IN SPT MOVEM 2,SPTH(4) ;PUT OFN.PN IN SPTH HLRZ 3,2 ;SAVE OFN LSH 4,^D9 ;CONSTRUCT SHARE POINTER TLO 4,SHRBIT XOR 4,CXBPGA(2) ;WITH PROTECTION BITS FROM PT TLZ 4,RWXB XORB 4,CXBPGA(2) ;PUT CONSTRUCTED SHARE POINTER IN PT MOVE 2,4 ;AS WELL AS PROCESS MAP MOVSI 4,1B31 ;BUMP SHARE COUNT FOR POINTER PUT ADDM 4,SPT(3) ;IN XB JRST SETMP7 ;GO INCREMENT SHARE COUNTS, ETC. SETMXB: CAIL 2,SSPT ;LEGAL NUMBER? BUG(HLT,) HLRZ 3,1 ;GET DESTINATION PTN CAIGE 3,NOFN ;FILE? BUG(HLT,) MOVEI 3,0(2) ;REQUEST WAS FOR INDEX BLOCK LSH 2,^D9 ;MAKE IT INTO SHARE POINTER TLO 2,SHRBIT+RWXB JRST SETMP5 ;DESTINATION IS FILE SETP7: HLRZ 4,2 ;GET SOURCE PTN CAIGE 4,NOFN ;IS FILE? JRST SETPF1 ;YES, ERROR TLNE 3,SHRBIT+INDBIT ;NOT PRIVATE? JRST SETPF ;YES JUMPE 3,SETP7K ;PAGE NEVER REFERENCED TLNE 3,10 ;NOW ON DISK? JRST SETP71 ;YES TLNE 3,16 ;NOW ON DRUM? JRST SETP7D ;YES, GO ADJUST DRUM BACKUP ADR PUSH P,1 ;IN CORE, MOVEI 1,0(3) CALL AGESET ;FIX PAGE POP P,1 MOVSI 4,PLKV ;IN CORE, ADDB 4,CST1(3) ;GET BACKUP ADR AND LOCK PAGE TLNE 4,10 ;DISK? JRST SETP7C ;YES TLNE 4,16 ;DRUM? JRST SETP7E ;YES MOVEI 4,CST1(3) ;NOT ASSIGNED, PUT BACKUP ADR IN CST1 CALL SETP7A ;ASSIGN BACKUP ADR AND STORE IT SETP7C: PUSH P,3 MOVEM 1,CST2(3) ;IN CORE, ADJUST CST MOVSI 4,-PLKV ADDM 4,CST1(3) ;UNLOCK PAGE HLRZ 4,2 ;SOURCE PTN MOVE 4,SPT(4) MOVSI 3,-PLKV ADDM 3,CST1(4) ;REDUCE LOCK COUNT OF PT HLRZ 4,1 MOVE 4,SPT(4) MOVSI 3,PLKV ADDM 3,CST1(4) ;INCREASE LOCK COUNT OF XB POP P,3 SETP71: SETZM CXBPGA(2) ;PUT SOURCE PTR IN DEST MAP HLRZ 4,0(P) ;GET USER SPECIFIED ACCESS ANDI 4,RWX TLZ 3,-1B31 TLO 3,ACCESB(4) ;PUT ACCESS AND ACCESS BIT IN PTR MOVEM 3,CPTPGA(1) EXCH 1,2 ;EXCHANGE SOURCE AND DESTINATION PT'S MOVE 3,PSB+CPTPG EXCH 3,PSB+CXBPG MOVEM 3,PSB+CPTPG MONCLR CPTPG ;CLEAR AR'S FOR LOCAL MAPPING MONCLR CXBPG ; (SECOND DOES NOTHING ON KA10) JRST SETP72 ;NOW AS IF PAGE WAS IN FILE SETP7K: MOVSI 3,RWXB+1 ;NEW PAGE, SETUP POINTER JRST SETP71 SETP7D: MOVE 4,3 SETP7E: PUSH P,2 PUSH P,3 MOVE 2,4 ;DRUM ADDRESS CALL GDSTX ;GET DST INDEX MOVEI 4,DST(2) ;WHERE TO STORE ADDRESS POP P,3 POP P,2 MOVE 5,0(4) ;PRESENT BACKUP TLNN 5,10 ;DISK? SETP73: CALL SETP7A ;NO, ASSIGN DISK ADDRESS AND STORE IT TLNN 3,17 JRST SETP7C JRST SETP71 SETP7A: HLRZ 5,1 ;GET OFN OF DESTINATION FILE PUSH P,1 ;SAVE STUFF PUSH P,2 PUSH P,3 PUSH P,4 MOVE 1,SPTH(5) ;GET XB ADRESS AND CLASS CALL DSKASN ;ASSIGN DISK ADDRESS FOR PAGE JRST SETP7X ;DISK FULL SETP7Y: MOVE 5,1 POP P,4 POP P,3 POP P,2 POP P,1 DPB 5,[POINT 22,0(4),35] ;STORE ADDRESS WHERE GIVEN RET SETP7X: SUB P,BHC+4+1 ;FLUSH 4 TEMPS AND 1 RETURN MOVEI 1,OPNX10 ;'NO ROOM' MOVEM 1,LSTERR MOVEI 1,^D20 ;SIZE EXCEEDED PSI CALL PSIRQ0 JRST SETPT1 ;POINTER NOW IN SPT OWNED BY FORK. MOVE IT TO FILE SETPF: LDB 4,[POINT 13,3,26] ;GET SPTN CAMN 2,SPTH(4) ;IS OWNED BY SOURCE? TLNE 3,INDBIT ;AND NOT INDIRECT? JRST SETPF1 ;SORRY, CAN'T GIVE AWAY UNOWNED PAGES MOVEM 1,SPTH(4) ;SET NEW OWNERSHIP MOVSI 5,-1B31 AND 5,SPT(4) ;GET CURRENT SHARE COUNT HLRZ 4,1 ADDM 5,SPT(4) ;TRANSFER SHARE COUNT TO NEW OWNING PT MOVN 5,5 HLRZ 4,2 ADDM 5,SPT(4) ;AWAY FROM OLD PT JRST SETMP3 ;NOW SETUP SHARE POINTER IN DEST SETPF1: MOVEI 1, ;ILLEGAL PAGE TO FILE ATTEMPTED SETPTE: MOVEM 1,LSTERR MOVEI 1,^D11 ;IO ERROR CHANNEL CALL PSIRQ0 RESKD1 JRST SETPT1 ;CLEAN UP AND EXIT ;PUT INDEX BLOCK IN FIXED PAGE (CXBPG) OF PP MAP FOR TEMP USE SETXB1: CALL RELCXB ;RELEASE CURRENT ONE NOINT ;NO INTERRUPTS WHILE XB MAPPED LSH 3,^D9 TLO 3,RWXB-XCTB+SHRBIT ;MAKE INTO SHARE POINTER, NO XCT MOVEM 3,PSB+CXBPG ;PUT INTO CURRENT X BLOCK PAGE RET ;RELEASE INDEX BLOCK NOW IN FIXED PAGE RELCXB: SKIPN PSB+CXBPG RET ;NONE THERE NOW SETZM PSB+CXBPG ;CLEAR MAP MONCLR CXBPG ;CLEAR MONITOR AR'S OKINT RET SWPCXB: PUSH P,1 LDB 1,[POINT 13,PSB+CXBPG,26] CAIL 1,1 ;IS OFN? CAIL 1,NOFN JRST .+3 ;NO, IGNORE IT MOVE 1,SPT(1) ;YES, INITIATE SWPOUT CALL SWPOT0 POP1: POP P,1 RET ;MAP CURRENT PAGE TABLE FOR TEMP USE SETCPT: CALL RELCPT ;RELEASE CURRENT ONE NOINT HLRZ 2,1 ;MAKE SHARE POINTER LSH 2,^D9 TLO 2,RWXB-XCTB+SHRBIT MOVEM 2,PSB+CPTPG RET ;RELEASE CURRENT PT MAPPING RELCPT: SKIPN PSB+CPTPG ;ANYTHING THERE? RET ;NO SETZM PSB+CPTPG ;CLEAR MAP MONCLR CPTPG ;CLEAR AR'S OKINT RET ;RELEASE PAGE FROM MAP ; AC1/ OFN.PN OF PAGE ; RETURNS +1 IF UNSUCCESSFUL ; RETURNS +2 IF SUCCESSFUL ; IN EITHER CASE, RETURNS NOSKED RELMPG: NOSKED PUSH P,3 PUSH P,2 CALL SETCPT RELMP7: PUSH P,1 RELMP5: MOVE 2,CPTPGA(1) ;GET MAP WORD JUMPE 2,RELMPR ;EMPTY PGRCLD ;CLEAR AR'S TLNN 2,SHRBIT+INDBIT ;PRIVATE POINTER? JRST RELP3 RELMP1: HLRZ 3,1 ;GET PTN TLNE 2,INDBIT ;INDIRECT POINTER JRST RELMP3 ;THAT'S OK CAIGE 3,NOFN ;OWNED BY FILE? JRST RELMP4 ;CAN'T DELETE FILE PAGE STILL SHARED LDB 3,[POINT 13,2,26] ;GET SPTN CAMN 1,SPTH(3) ;OWNER TRYING TO DELETE? JRST RELMP4 ;MUST WAIT TILL UNSHARED RELMP3: SETZM CPTPGA(1) ;CLEAR MAP WORD MOVE 3,2 ;SAVE POINTER LSH 2,-^D9 ANDI 2,SPTM ;GET SPT INDEX MOVSI 1,-1B31 CAIGE 2,NOFN ; OFN OR INDIRECT THRU OFN? JRST RELMP6 TLNE 3,INDBIT ;INDIRECT POINTER JRST RELP1 ; YES, JUST DECREMENT SHARE CNT HLRZ 3,SPTH(2) ;IS SHARE POINTER, GET OFN JUMPE 3,RELP1 ;IF UNOWNED SPTN ADD 1,SPT(2) ;SEE IF SHARE COUNT OF PG IS GOING TO 0 .. DCA TLNE 1,-1B31 ;COUNT NOW 0? JRST [MOVSI 1,-1B31 ;NO, REDUCE SHR CTS OF OFN AND PG ADDM 1,SPT(3) ADDB 1,SPT(2) JRST RELMPR] ;MAP THE OWNING XB, GO OKSKED, TOUCH THE PAGE, GO NOSKED AND ;THEN RETEST THE SHARE COUNT TO SEE IF IT IS STILL GOING TO 0 .. DCA PUSH P,3 ;SAVE 3. SETXB1 CLOBBERS IT .. DCA CALL SETXB1 ;MAP THE OWNING XB POP P,3 ;RESTORE 3 ;NOTE THAT SETXB1 DOES NOT INCREMENT THE SHARE COUNT IN THE ;SPT ENTRY FOR THE XB. THIS CODE DEPENDS ON THE FACT THAT THE ;CURRENT PROCESS HAS THE FILE OPEN AND THUS THE SHARE COUNT CANNOT ;REACH 0 WHILE OKSKED. SETXB1 DOES A NOINT AND THUS THE CURRENT PROCESS ;CANNOT ITSELF CLOSE THE FILE IN RESPONSE TO A PSI. OKSKED ;PREPARE TO TOUCH THE PAGE SKIP CXBPGA NOSKED MOVSI 1,-1B31 ;NOW REDUCE SHR COUNTS FOR REAL .. DCA ADDM 1,SPT(3) ADDB 1,SPT(2) TLNE 1,-1B31 ;IS SHR COUNT NOW 0? JRST [CALL RELCXB ;NO JRST RELMPR] TLNE 1,17 ;CORE? JRST RELMP2 ;NO CALL AGESET ;IN CORE, SET AGE MOVSI 4,PLKV ADDM 4,CST1(1) ;AND LOCK WHILE ADJUSTING RELMP2: MOVSI 4,-1B31 ADDM 4,SPT(3) ;REDUCE SHARE COUNT OF XB MOVE 4,SPTH(2) ;GET OWNING PTN.PN XOR 1,CXBPGA(4) ;PUT ADDRESS BACK IN XB WITH ORIGINAL TLZ 1,-1B31-SHRBIT-INDBIT XORB 1,CXBPGA(4) ;ACCESS BITS TLNN 1,16 ;UNREFERENCED DISK ADR? TLNN 1,17 CAIA ;NO SETZM CXBPGA(4) ;YES, DELETE IT CALL RELCXB ;RELEASE XB MOVE 3,2 ADDI 2,SPT EXCH 2,FRESPT ;RETURN SPT SLOT TO FREE LIST MOVEM 2,@FRESPT SOS SPTC TLNE 1,17 ;PAGE IN CORE? JRST RELP4 ;NO CAME 3,CST2(1) ;CONFIRM OLD OWNERSHIP BUG(HLT,) MOVEM 4,CST2(1) ;YES, CHANGE RECORD OF OWNING PT HLRZ 4,4 ;PTN OF OWNING PT MOVE 4,SPT(4) ;CORE ADDRESS OF IT MOVSI 2,PLKV ADDM 2,CST1(4) ;INCREMENT LOCK COUNT MOVSI 4,-PLKV ADDM 4,CST1(1) ;UNLOCK PAGE JRST RELP2 RELMP6: MOVE 1,2 OKSKED ; RESCHEDULING IS NOW PERMISSIBLE CALL RELOFN JFCL NOSKED JRST RELMPX RELP4: TLNN 1,10 ;DISK ADR? TLNN 1,16 ;NOT ASSIGNED? JRST RELMPR ;YES MOVE 1,4 CALL SWPINP ;GET IT OFF DRUM RELP2: CALL AGESET ;MAKE PAGE IN USE HLRZ 2,CST2(1) ;SEE WHO OWNS PAGE CAIG 2,NFDIB+3 ;SYSTEM FILE? (DIR OR BITTAB) JRST [ CALL DECOR ;YES, DEASSIGN BUT DON'T SWAPOUT IMMED JRST RELMPR] CALL SWPOT0 ;SWAP IT OUT RELMPR: RELMPX: POP P,1 SKIPE CPTPGA(1) ;MAP WORD STILL EMPTY? JRST RELMP7 ;NO, TRY AGAIN POP P,2 POP P,3 JRST RSKP RELP3: TLNE 2,17 ;IN CORE? JRST RELP32 ;NO, CAN RELEASE ALL. TLNE 2,USRLKB ; LOCKED BY USER? CALL MULK1 ; YES, UNLOCK THE PAGE MOVE 1,0(P) MOVSI 3,DWRBIT ;YES, WRITE IN PROGRESS? TDNN 3,CST3(2) JRST RELP32 ;NO, NO PROBLEM MOVEI 1,DWRTST ;YES, MUST WAIT FOR COMPLETION HRLI 1,0(2) JSYS SCHEDR NOSKED MOVE 1,0(P) ;RECOVER OFN.PN JRST RELMP5 ;GO TRY AGAIN RELP32: CALL REMFPG ;RELEASE ALL STORAGE JRST RELMPR DWRTST: MOVSI 2,DWRBIT ;SCHED TEST FOR WRITE COMPLETED TDNE 2,CST3(1) JRST 0(4) JRST 1(4) ; SCHEDULER TEST FOR PAGE UNLOCKED PLCKT: MOVSI 2,-PLKV TDNE 2,CST1(1) JRST 0(4) JRST 1(4) RELP1: ADDM 1,SPT(2) JRST RELMPR RELMP4: SUB P,BHC+3 ;FLUSH TEMPS MOVEI 1, ;ILLEG UNMAPPING MOVEM 1,LSTERR MOVEI 1,^D11 CALL PSIRQ0 ;GENERATE ITRAP RESKD1 ;MAKE SURE SCHED SEES PSI SETZB 1,2 RET ;REMOVE PAGE FROM SYSTEM (DELETE PERMANENT AND TEMPORARY ADDRESSES) REMFPG: MOVE 3,CPTPGA(1) ;GET MAP WORD SETZM CPTPGA(1) ;CLEAR MAP WORD REMFP1: TLNE 3,10 ;DISK? JRST REMFF ;YES TLNE 3,16 ;DRUM? JRST REMFD ;YES TLNE 3,17 ;CORE? RET ;DONE MOVEI 1,0(3) CAMG 1,NHIPG ;LEGAL PAGE? CAMGE 1,SWPCOR BUG(HLT,) CALL AGESET CALL DECOR HLRZ 2,CST2(1) ;GET PTN OF OWNING PT JUMPE 2,REMFP2 ;NONE, SPT MOVE 3,SPT(2) ;GET ADR OF OWNING PT MOVSI 4,-PLKV ADDM 4,CST1(3) ;DECREMENT LOCK COUNT REMFP2: MOVE 2,TODCLK ;SETUP OVERDUE TIME ADDI 2,^D2000 ;AS 2 SEC FROM NOW REMFP4: MOVSI 3,(77B5) MOVSI 4,-PLKV PIOFF SETZM CST2(1) ;FLUSH SOURCE TDNE 3,CST0(1) ;PAGE NOW ON RPLQ? TDNE 4,CST1(1) ;LOCKED? JRST REMF21 ;YES, IS OR WILL BE PUT ON RPLQ MOVSI 3,DWRBIT TDNE 3,CST3(1) ;BEING WRITTEN? JRST REMFP3 ;YES, MUST WAIT PION REMFP5: JSP 4,ONRQ ;PUT PAGE ON RPLQ REMF22: MOVSI 3,-PLKV AND 3,CST1(1) ;FLUSH BACKUP ADDRESS, LEAVE LK CNT EXCH 3,CST1(1) ;GET BACKUP ADDRESS JRST REMFP1 REMFP3: PION CAML 2,TODCLK ;WAITED LONG ENOUGH? JRST REMFP4 ;NO, KEEP WAITING BUG(CHK,) ANDCAM 3,CST3(1) ;FORCE COMPLETION JRST REMFP5 REMF21: PION JRST REMF22 REMFD: MOVE 1,3 PUSH P,1 CALL DASDRM ;DEASSIGN DRUM ADDRESS POP P,2 CALL GDSTX MOVE 3,DST(2) ;GET BACKUP ADDRESS SETOM DST(2) ;MAKE DST SLOT EMPTY JRST REMFP1 REMFF: MOVE 1,3 CALL DEDSK ;DEASSIGN DISK ADDRESS RET ;CONSTRUCT PTN.PN FOR ;ADDRESS GIVEN IN 18-35 OF AC1 ;BIT 0 OF AC1 SAYS USER (IF 1) OR MONITOR (IF 0) ADDRESS ;RETURN WITH PTN.PN IN AC1 FPTA: PUSH P,1 MOVEI 1,0(1) ;CLEAR LH LSH 1,-^D9 ;GET PAGE NUMBER EXCH 1,0(P) ;GET ARG, SAVE PN JUMPL 1,FPTAU ;USER MODE IF BIT 0 IS 1 MOVE 1,0(P) CAIL 1,PPMPG ;WHICH PART OF MONITOR? JRST FPTA1 ;PRIVATE PER PROCESS CAIL 1,PJMPG JRST FPTA2 ;PRIVATE PER JOB CAIL 1,PPRMPG JRST FPTA3 ;PRIVATE PER PROCESSOR AND SWAPPABLE BUG(HLT,) FPTA1: CAIGE 1,DDPG1 ;DISALLOW SPECIAL PAGES BUG(HLT,) FPTA5: MOVE 1,FORKX ;GET SPTN OF PSB JRST FPTA4 FPTAU: MOVE 1,FORKX ;GET SPTN OF UPT OR IF NONE, PSB HLL 1,FKPGS(1) TLNN 1,-1 FPTA4: HRLZ 1,FKPGS(1) FPTAR: HLLM 1,0(P) ;COMBINE WITH PAGE NUMBER JRST POP1 ;POP TO 1 AND RETURN FPTA2: CAIG 1,JSBPG JRST FPTA5 ;JSB OR JDV, NOT INDIRECT PTR LDB 1,[POINT 13,PSB+JSBPG,26] ;SPTN OF JSB HRLM 1,0(P) HRREI 1,-PJMPG+JOBMAP-JSB ;FIRST JOB PAGE MAPPED BY JOBMAP+0 ADDM 1,0(P) JRST POP1 FPTA3: HRL 1,MMSPTN ;PERMANENT SPTN OF MON MAP JRST FPTAR ;MAKE PRIVATE PAGE IN EXECUTING FORK'S ADDRESS SPACE SHARABLE PAGE. ;1/ ADDRESS OF THE PAGE ;RET WITH 1/ SPT INDEX FOR THE PAGE MKSHRP: PUSH P,2 PUSH P,3 PUSH P,1 CALL ASSPT ;ASSIGN SPT SLOT MOVSI 2,1B31 ;INCREMENT SHARE COUNT ADDM 2,SPT(1) EXCH 1,0(P) ;1=ADDRESS,0(P)=SPT SLOT CALL FPTA ;GET PTN,,PN FOR PAGE PUSH P,1 CALL MLKPG ;LOCK THE PAGE IN CORE POP P,1 ;RESTORE 1 SMASHED BY MLKPG CALL SETCPT ;MAP THE PAGE TABLE MOVE 2,0(P) ;2=SPT SLOT MOVE 3,CPTPGA(1) ;3=PAGE TABLE ENTRY FOR PAGE TLNE 3,SHRBIT+INDBIT ;IS PAGE PRIVATE? BUG(HLT,) TLNE 3,17 ;IS IT REALLY IN CORE? BUG(HLT,) NOSKED DPB 3,[POINT 22,SPT(2),35] MOVEM 2,CST2(3) ;RESET CORE PAGES HOME ADDRESS TLO 3,SHRBIT ;MAKE 3 A SHARE PTR TO PAGE DPB 2,[POINT 13,3,26] MOVEM 3,CPTPGA(1) ;AND PUT IT INTO PAGE TABLE OKSKED CALL RELCPT ;UNMAP THE PAGE TABLE CALL MULKPG ;UNLOCK THE PAGE HLRZS 1 ;NOW UNLOCK PREVIOUS OWNING MOVE 1,SPT(1) ;PAGE TABLE (LOCKED AS A SIDE MOVSI 2,-PLKV ;EFFECT OF MLKPG AND NOT ADDM 2,CST1(1) ;UNLOCKED BY MULKPG SINCE ;OWNERSHIP CHANGED). POP P,1 ;1=SPT INDEX POP P,3 POP P,2 RET ;SET A FORK'S JSYS DISPATCH VECTOR PAGE ;IF SHARE COUNT OF OLD PAGE GOES TO 1 ITS SPT SLOT IS RELEASED ;SAME ARGUMENTS AS SETPT: ;1/ SOURCE IDENTIFIER ;2/ DESTIN IDENTIFIER ;3/ ACCESS SETDVP: PUSH P,1 PUSH P,4 MOVE 1,2 CALL SETCPT ;MAP PAGE TABLE FOR PAGE MOVE 4,CPTPGA(1) TLNE 4,SHRBIT ;MAKE SURE IT IS A SHARE PAGE TLNE 4,INDBIT BUG(HLT,) LDB 4,[POINT 13,4,26] ;4=SPT INDEX CALL RELCPT MOVE 2,1 MOVE 1,-1(P) CALL SETPT ;SET FORK'S MAP MOVEI 1,(4) LDB 4,[POINT 14,SPT(1),13] ;4=SHARE COUNT OF OLD PAGE CAIN 4,1 ;HAS IT REACHED 1? CALL DESPT ;YES, RELEASE THE SPT ENTRY POP P,4 POP P,1 RET ;GET CORE PAGE GIVEN ADDRESS OR IDENTIFIER ;CLOBBERS 2 GETCPA::CALL FPTA ;CONVERT ADDRESS TO IDENTIFIER GETCPP: HLRZ 2,1 ;PT OF IDENT MOVE 2,SPT(2) ;ADDRESS OF IT TLNE 2,17 ;IN CORE? BUG(HLT,) CALL MOVRCA ;MOVE 1,PT(1) TLNN 1,SHRBIT+INDBIT ;PRIVATE POINTER? RET ;YES TLNN 1,INDBIT ;NO. INDIRECT? JRST [ LDB 2,[POINT 13,1,26] ;SHARED. GET SPT IDX MOVE 1,SPT(2) RET] LSHC 1,-^D9 ;REFORMAT INTO PTN.PN ANDI 1,SPTM ; .. LSH 1,^D9 LSHC 1,^D9 JRST GETCPP ;GIVEN A CORE PAGE IN 2, AND N IN 1, FETCH NTH WORD FROM PAGE ;KI VERSION IS IN KISRV ;CAN BE CALLED AT ANY PI LEVEL IFN KAFLG,< MOVRCA: HRLI 2,RWXB ;CONSTRUCT POINTER PIOFF MOVEM 2,MMAP+PIPG CONO PGR,1 ;CLEAR MON AR'S MOVE 1,PIPGA(1) PION RET ;GIVEN A CORE PAGE IN 3, AND N IN 2, STORE 4 IN NTH WORD ; OF THE PAGE. KI VERSION NOT YET WRITTEN, WILL BE IN KISRV ; CAN BE CALLED AT ANY PI LEVEL ; USED TO CORRECT THE "CORRECTABLE DATA CHECKS" OF THE 3330. INTERN XRMRCA XRMRCA: HRLI C,RWXB ;CONSTRUCT POINTER PUSH P,A ;SAVE WORK AC MOVSI A,(1B0) ;LEGAL AGE FOR DISK PAGE BEING READ PIOFF MOVEM C,MMAP+PIPG EXCH A,CST0(C) ;SET LEGAL AGE CONO PGR,1 ;CLEAR MONITOR AR'S XORM 4,PIPGA(B) ;STORE WORD IN PAGE MOVEM A,CST0(C) ;PUT RIGHT AGE BACK PION POP P,A RET > IFN KIFLG,< EXTERN MOVRCA,MVMRCA > ;GET OWNING PAGE TABLE ;GIVEN PTN.PN, LOCATE PT CURRENTLY HAVING ADDRESS OF PAGE GETONT: CALL SETCPT ;MAP GIVEN PAGE TABLE MOVE 2,CPTPGA(1) ;REF BEFORE NOSKED NOSKED MOVE 2,CPTPGA(1) ;GET MAP WORD TLNN 2,SHRBIT+INDBIT ;PRIVATE POINTER? JRST RELCPT ;YES, RELEASE CPT AND RETURN TLNN 2,INDBIT ;INDIRECT POINTER? JRST GETON1 ;NO, SHARE POINTER. OKSKED LSHC 2,-^D9 ;REFORMAT INTO PTN.PN ANDI 2,SPTM LSH 2,^D9 LSHC 2,^D9 CALL RELCPT ;RELEASE CPT MOVE 1,2 JRST GETONT ;TRY AGAIN GETON1: LDB 1,[POINT 13,2,26] ;FOR SHARE POINTER, RETURN SPTN MOVE 2,SPT(1) ;AND CURRENT ADDRESS JRST RELCPT ;RELEASE CPT AND RETURN ;SETUP PAGER FOR PROCESS SETPPG: HRRZ 1,FKPGS(7) ;GET PSB MOVE 1,SPT(1) TLNE 1,17 ;MUST BE IN CORE BUG(HLT,) HRRZM 1,PGR71 ;LEAVE CORE PAGE NUMBER FOR PAGER HLRZ 1,FKPGS(7) ;GET PT MOVE 1,SPT(1) TLNE 1,17 ;MUST BE IN CORE BUG(HLT,) SETPG1: HRLM 1,PGR71 ;LEAVE FOR PAGER HRRZ 1,FKCNO(7) MOVE 2,BITS-^D9(1) ;PROCESS USE BIT HLRZ 1,FKNR(7) ;GET PROCESS AGE ROTC 1,-^D9 MOVEM 2,PGR72 PGRCLD ;LOAD PAGER FROM 71,72 MOVE 1,ACBAS ;SET AC BASE REGISTER SETACB 1 RET ;PRELOAD PAGES FOR FORK, FORKX IN 7 PRELD: SKIPE PGR71 ;PAGER INITIALIZED? SKIPN PRELDF ;PRELOADING IN OPERATION? JRST PREL2 ;NO SETOM PRELRQ ;SET FLAG NOTING PRELOADING SWAPS PUSH P,10 HRRZ 11,FKNR(7) ;CURRENT WS SIZE SUBI 11,4 ;LESS PSB, UPT, AND 2 RESERVE HRRZ 1,FKPGS(7) ;PSB LSH 1,^D9 ;MAP IT WITH SHARE PTR TLO 1,RWXB+SHRBIT MOVEM 1,MMAP+FITPG HLRZ 1,FKPGS(7) ;PAGE TABLE LSH 1,^D9 TLO 1,RWXB+SHRBIT MOVEM 1,MMAP+PRLPG ;MAP IT MONCLR PRLPG MOVSI 10,-NWSPGS ;SETUP TO SCAN WS BIT WORDS PREL1: SKIPE 5,XWSPGS(10) ;ANY PAGES THIS WORD? PREL6: JFFO 5,PREL3 ;YES AOBJN 10,PREL1 PREL7: POP P,10 PREL2: SETZM PRELRQ RET PREL3: ANDCM 5,BITS(6) ;REMOVE BIT FOR PAGE JUST FOUND PUSH P,5 ;SAVE PARTIAL BIT WORD MOVEI 5,0(10) ;COMPUTE PAGE NUMBER IN UPT IMULI 5,^D36 ADDI 6,0(5) SKIPE 2,PRLPGA(6) ;GET POINTER FROM UPT TLNE 2,INDBIT ;INDIRECT? JRST PREL4 ;YES, NOT INTERESTED HLLZ 1,FKPGS(7) ;CONSTRUCT IDENTIFIER FOR PRIVATE CASE HRRI 1,0(6) ;PTN.PN TLNE 2,SHRBIT ;SHARE PTR? JRST [ LSH 2,-^D9 ;YES, GET SPT INDEX ANDI 2,SPTM MOVEI 1,0(2) ;THAT WILL BE IDENTIFIER MOVE 2,SPT(1) ;AND SPT CONTAINS ADDRESS JRST .+1] TLNE 2,17 ;PAGE NOW IN CORE? JRST [ SKIPLE NRPLQ ;MAKE SURE THERE'S ROOM TLNN 2,16 ;AND PAGE IS ASSIGNED JRST PREL4 CALL SWPIN ;NO, SWAP IT IN JRST PREL4] LDB 1,[POINT 6,CST0(2),5] ;PAGE IS IN CORE, SEE WHAT STATE JUMPE 1,PREL5 ;ON REPLACABLE CAIE 1,4 ;BEING WRITTEN? JRST PREL4 ;NO, ANYTHING ELSE IS OK MOVSI 1,(2B5) EXCH 1,CST0(2) ;SET NEW STATE, GET OLD TLNN 1,(77B5) ;NOW ON REPLACABLE? JRST PREL5 ;YES SOS IOIP ;NO, HAVE NOW DISABLED COMPLETION ACTION PREL4: POP P,5 ;RECOVER PARTIAL BIT WORD SOJG 11,PREL6 ;KEEP GOING UNLESS WS EXHAUSTED JRST PREL7 ;QUIT PREL5: SOS NRPLQ ;TAKE PAGE OFF REPLACABLE PIOFF MOVE 1,CST3(2) HLLM 1,0(1) MOVS 1,1 HLRM 1,0(1) PION SETZM CST3(2) MOVSI 1,(2B5) ;SET PAGE TO READ COMPLETE STATE HRRI 1,0(7) ;INCLUDE FORK NO MOVEM 1,CST0(2) ;IN CASE PROCESS DOES NOT REF IT JRST PREL4 ;CHECK WS BITS AS PROCESS LEAVES BALSET POSTPG: PUSH P,1 JSP 4,STIME ;TIME THIS HRRZ 1,FKPGS(7) LSH 1,^D9 ;MAP PSB TLO 1,RWXB+SHRBIT MOVEM 1,MMAP+FITPG HLRZ 1,FKPGS(7) ;PAGE TABLE LSH 1,^D9 ;MAP IT VIA SHR PTR TLO 1,RWXB+SHRBIT MOVEM 1,MMAP+PRLPG MONCLR MOVSI 6,-NWSPGS ;SCAN WS BIT WORDS SETZ 3, ;COUNTING BITS REMB2: SKIPE 4,XWSPGS(6) ;ANY BITS HERE? REMB7: JFFO 4,REMB5 ;YES, FIND ONE AOBJN 6,REMB2 ADDI 3,3 ;PAGES IN WS PLUS 3 FOR MON OVHD CAIGE 3,6 ;SET NR TO: MAX(6,SIZ,WSBITS+3) MOVEI 3,6 HRRZ 2,FKWSP(7) ;SIZE CAIGE 3,0(2) MOVEI 3,0(2) HRRZ 2,FKNR(7) ;CURRENT NR CAILE 3,0(2) ;ABOVE .G. CURRENT? MOVEI 3,0(2) ;YES, KEEP CURRENT HRRM 3,FKNR(7) ;SET NEW NR JSP 4,ETIME ;GET TIME SPENT HERE ADDM 1,PPG ;ACCUMULATE IT AOS PPG+1 ;COUNT OCCURRENCES POP P,1 RET ;SWAP OUT PURGED PAGE GCSWP: MOVE 2,CST1(1) TLNE 2,-PLKV RET MOVSI 2,DWRBIT TDNE 2,CST3(1) ;DON'T SWAP PAGE IF NOW BEING WRITTEN RET MOVE 2,CST0(1) TLNN 2,(7B2) ;NOW ASSIGNED? RET ;NO, DO NOTHING TDNE 2,BSBITS ;BEING SHARED BY SOMEONE IN BALSET? RET ;YES, DON'T COLLECT HLRZ 2,CST3(1) ;GET PROCESS ASSIGNMENT ANDI 2,7777 CAIE 2,0(7) ;ASSIGNED TO THIS PROCESS? RET ;NO, DON'T TOUCH IT PUSH P,1 CALL SOSWS2 ;YES, DEASSIGN IT POP P,1 SOS POTEN AOS PPCLCT ;COUNT PAGES COLLECTED BY POSTPG JRST SWPOUT ;SWAP OUT PAGE ;LOOK AT PAGE IN WS REMB5: ANDCM 4,BITS(5) ;REMOVE BIT FROM TEMP WORD MOVEI 1,0(6) ;COMPUTE PAGE NUMBER IN PT IMULI 1,^D36 ADDI 1,0(5) SKIPE 1,PRLPGA(1) ;PAGE NOW EMPTY? TLNE 1,INDBIT ;OR INDIRECT? JRST REMB6 ;YES, FORGET IT TLNE 1,SHRBIT ;SHR PTR? JRST [ LSH 1,-^D9 ANDI 1,SPTM ;YES, GET ADDRESS FROM SPT MOVE 1,SPT(1) JRST .+1] TLNE 1,17 ;PAGE NOW IN CORE? JRST REMB6 ;NO, FORGET IT MOVE 2,CST0(1) TLNN 2,(7B2) ;PAGE IN USE? JRST [ TLC 2,(02B5) ;NO, BUT IS READ COMPLETED? TLNE 2,(77B5) JRST REMB6 ;NO, FLUSH IT JRST .+1] ;YES, KEEP IT PUSH P,3 PUSH P,4 SKIPG SWRSAF ;PAGE IS TO BE KEPT. REASSIGNING ADRS? JRST POSTP1 ;NO MOVE 2,CST1(1) ;YES, GET OLD ADDRESS TLNN 2,10 ;DRUM? TLNN 2,16 JRST POSTP1 ;NO CALL GDSTX ;GET DST INDEX FOR OLD DRUM ADR PUSH P,DST(2) ;SAVE BACKUP ADR SETOM DST(2) ;CLEAR OLD DST SLOT PUSH P,1 ;SAVE CORE ADDRESS MOVE 1,CST1(1) CALL DASDRM ;DEASSIGN OLD DRUM ADR SETO 1, CALL DRMASN ;ASSIGN NEW DRUM ADR IN SEQUENCE BUG(HLT,) TLO 1,1 ;NOTE NEW ADDRESS MOVE 2,1 POP P,1 DPB 2,[POINT 22,CST1(1),35] ;STORE NEW DRUM ADR CALL GDSTX POP P,DST(2) ;PUT BACKUP ADR IN NEW DST SLOT POSTP1: SKIPLE POSPGF ;POST PURGING REQUESTED? CALL GCSWP ;YES, SWAP OUT THE PAGE POP P,4 POP P,3 AOJA 3,REMB7 ;COUNT PAGE AND CONTINUE REMB6: SKIPN -1(P) ;FORK WAS DISMISSED OR FORCED OUT? AOJA 3,REMB7 ;FORCED OUT, DON'T FLUSH UNREF PGS MOVE 2,BITS(5) ANDCAM 2,XWSPGS(6) ;DISMISSED, FLUSH UNREF PAGES JRST REMB7 ;DEASSIGN CORE DECOR: PUSH P,3 ;MUST BE TRANSPARENT TO AC'S PUSH P,2 TLNE 1,17 ;GIVEN MAP WORD, NOW IN CORE? JRST DECRR ;NO, NOTHING TO DO MOVE 3,CST0(1) TLNN 3,(70B5) ;PAGE IN USE? JRST DECRR ;NO HLRZ 2,CST3(1) ;GET PROCESS ASSIGNMENT ANDI 2,7777 CAIL 2,NFKS ;ASSIGNED? JRST DECRR ;NO, NOTHING ELSE TO DO PUSH P,1 CALL SOSWSP ;REDUCE N FOR THIS PROCESS POP P,1 MOVSI 2,7777 IORM 2,CST3(1) ;MAKE PAGE UNASSIGNED DECRR: POP P,2 POP P,3 RET ;GARBAGE COLLECT CORE, REMOVE PAGES OF PROCESSES NOT IN BAL SET GCCOR0: SKIPL BKGFLG ;DONT CALL IF BACKGROUND JSP 4,STIME ; ENTER HERE TO DEPG ALL RPLQ MOVE 1,NRPLQ ; INSPECT N PAGES JUMPE 1,GCPC2 ;N MAY BE 0 ... HRRZ 7,RPLQ ;ON REPLACABLE QUEUE GCPC1: MOVEI 3,0(7) SUBI 3,CST3 ;GET PAGE NUMBER CALL DEPG ;UNDO POINTER AND FLUSH BACK PTR, SETZM CST2(3) ;THUS UNLOCKING OWNING PT HRRZ 7,0(7) SOJG 1,GCPC1 JRST GCPC2 GCCOR: SKIPL BKGFLG ;DONT CALL IF BACKGROUND JSP 4,STIME ;TIME GCCOR ACTIVITY GCPC2: SETZM POTEN ;RESET POTENTIAL PAGE COUNTER MOVE 11,BSBITS ;MASK OF BALSET PROCS MOVE 12,RLBITS ;MASK OF RUNLIST PROCS GCCOR2: MOVE 6,SWPCOR ;START AFTER RES MON GCC2: LDB 1,[POINT 6,CST0(6),5] ;CODE FIELD CAIN 1,2 ;READ COMPLETED? JRST [HRRZ 2,CST0(6) ;YES, GET INDEX OF OWNING FORK CAIL 2,NFKS ;VALID FORK INDEX? JRST GCC4 ;NO MOVSI 1,WTCLCT ;GET FKFLGS AND INDICATE GCCOR'D ANDCAB 1,FKFLGS(2) TLNE 1,BLST ;IN BALSET? TLNE 1,FORCEM ;BEING FORCED OUT? SKIPA 2,CST1(6) JRST GCC1 ;DONT COLLECT TLNE 2,-PLKV ;LOCKED? JRST GCC1 ;YES, CANT COLLECT AOS PNDING AOS SUMNRX JRST GCCS1] ;COLLECT IT CAIGE 1,10 ;PAGE IN USE JRST GCC1 ;NO HLRZ 2,CST3(6) ;GET PROCESS ASSIGNMENT ANDI 2,7777 CAIL 2,NFKS ;PAGE NOW ASSIGNED? JRST GCCS ;NO, COLLECT IT MOVSI 3,WTCLCT ;INDICATE FORK GCCOR'D ANDCAB 3,FKFLGS(2) SKIPGE FKPT(2) ;HAS FORK BEEN DELETED? JRST GCCS ;YES, COLLECT TLNE 3,WTLS## ; OWNER ON WAIT LIST? JRST GCCS ; YES. COLLECT IT MOVE 1,12 ;PROCESS BITS NOT TO BE CLEARED ANDB 1,CST0(6) ;CLEAR ALL OTHERS TDNE 1,11 ;ANY USERS IN BALSET? JRST GCC1 ;DONT COLLECT GCCS: MOVE 2,CST1(6) ;BACKUP ADDRESS TLNE 2,-PLKV ;PAGE LOCKED? JRST GCCQ ;YES, LEAVE IT MOVSI 2,DWRBIT TDNE 2,CST3(6) ;PAGE BEING WRITTEN? JRST GCCQ ;YES, LEAVE IT MOVE 1,CST0(6) TLNN 1,(7B2) ;PAGE ASSIGNED? JRST GCCS1 ;NO HLRZ 2,CST3(6) ;GET PROCESS ASSIGNMENT ANDI 2,7777 CAIL 2,NFKS ;ASSIGNED? JRST GCCS1 ;NO CALL SOSWSP GCCS1: MOVEI 1,0(6) ;SWAPOUT CALL SWPOUT SKIPL BKGFLG ;DONT COUNT IF BKGND AOS NGCLCT ;COUNT PAGES COLLECTED GCC1: CAMGE 6,NHIPG ;STOP AFTER HIGHEST KNOWN PAGE AOJA 6,GCC2 SETZM CGFLG ;INDICATE GCCOR REQUEST SATISFIED GCC3: SKIPGE BKGFLG ;TAKE STATS ONLY IN NON-BACKGROUND RET JSP 4,ETIME ;END TIMING OF GCCOR ADDM 1,GCCR ;CLOCK FOR GCCOR TIME AOS GCCR+1 ;COUNT OCCURRENCES RET GCC4: BUG (CHK,) AOS PNDING AOS SUMNRX JRST GCCS ;COLLECT AND PRAY GCCQ: HLRZ 2,CST3(6) ;GET FORK ASSIGNMENT ANDI 2,7777 CAIGE 2,NFKS ;NONE? SKIPL FKPT(2) ;OR CURRENTLY EXISTENT FORK? JRST GCC1 ;YES CALL SOSWSP MOVSI 1,7777 ;PAGE ASSIGNED TO DELETED FORK IORM 1,CST3(6) ;REMOVE ASSIGNMENT JRST GCC1 ;DECREMENT WSP AND RELEASE CORE NUMBER IF WSP 0 SOSWSP: MOVE 1,FKFLGS(2) ;IS FORK IN BAL SET? TLNE 1,BLST TLNE 1,FORCEM CAIA SOS FKNR(2) ;YES, REDUCE FKNR TOO SOSWS2: AOS PNDING ;PAGE AWAITS COLLECTION SOS 1,FKWSP(2) TRNE 1,777777 ;WSP NOW 0? RET ;NO MOVE 1,FKFLGS(2) ;GET FLAG WORD TLNE 1,RNLS ;PROCESS STILL ACTIVE? RET ;YES, DON'T RELEASE NUMBER HRRZ 1,FKCNO(2) JUMPE 1,R ;NO NUMBER (?) HLLZS FKCNO(2) MOVE 1,BITS(1) IORM 1,FRECB RET ;PAGER TRAP PGRTRP: XWD TRAPPC,.+1 SKIPN INSKED CONSZ PI,177B27 ;FROM PI ROUTINE? BUG(HLT,) AOSLE NSKED AOSGE INTDF BUG(HLT,) AOSE TRAPC ;FIRST TRAP? JRST PGRT4 ;NO, GO CHECK RECURSIVE OR ITERATIVE MOVEM P,TRAPAP ;SAVE AC-P MOVE P,TRAPSP ;SETUP TRAP STACK AOS UTRPCT ;COUNT TRAPS (BUT NOT RECURSIVE ONES) PUSH P,7 ;SAVE AC'S 1-7 PGRT2: ADD P,BHC+6 JUMPGE P,MSTKOV ;STACK OVERFLOW? MOVEM 1,-5(P) ;FASTER THAN BLT OR PUSH MOVEM 2,-4(P) MOVEM 3,-3(P) MOVEM 4,-2(P) MOVEM 5,-1(P) MOVEM 6,0(P) MOVE 1,TRAPPC ;RETURN PUSH P,1 ;SAVE IT TLNE 1,UMODF ;FROM USER? MOVEM 1,UPDL ;YES, LEAVE IT WHERE IT CAN BE FOUND PGRT3: SKIPE TRAPC ;IF RECURSIVE TRAP, PUSH P,TRAPSW ;OLD STATUS WORD PUSH P,TRAPWD ;WRITE DATA MOVE 1,TRAPS0 ;GET TRAP STATUS WORD FROM WHERE ;PAGER LEAVES IT TLNE 1,(1B10+1B12) ;PI CYC OR NXM? BUG(HLT,) MOVEM 1,TRAPSW ;TO SAFE PLACE SKIPE TRAPC JRST PGRTE ;NESTED TRAP, DON'T COUNT TIME TWICE MOVE 3,FKRT ;GET CURRENT PROCESS TIME SO WE ADD 3,JOBRTT ;CAN TIME THIS CODE PUSH P,3 IFN KIFLG,< PUSH P,KIMAC1 ;SAVE MUUO TEMPS HERE PUSH P,KIMAC2> PGRTE: SETZM TRAPPC ;ALLOW SCHEDULING PGRTD: HLLZ 1,TRAPSW ;GET TRAP STATUS TLNE 1,(1B9) ;PARITY ERROR? JRST PGRME ;YES SETZ 2, ROTC 1,2 ;GET TOP 2 BITS MOVE 3,TABA(2) ;APPROPRIATE DISPATCH TABLE JFFO 1,.+2 ;FIND TRAP-CAUSING BIT BUG(HLT,) MOVE 7,FORKX ;GET FORK AND PROCESS NUMBER JRST 0(3) PGRT4: PUSH P,7 ;TRAPSK ALREADY EXISTS HRRZ 7,TRAPPC ;CHECK TRAP PC FOR EITHER OF THE CAIE 7,PGMV1+1 ;WRITE INSTRUCTIONS DONE TO CAIN 7,PGMV2+1 ;FINISH UP A WRITE TRAP SOSA TRAPC ;TRAP IS ITERATIVE NOT RECURSIVE JRST PGRT2 ;TRUE RECURSIVE TRAP SOS NSKED ;UNDO EFFECTS OF ENTERING TRAP CODE SOS INTDF POP P,7 ;ADJUST VARIABLES AND REPROCESS TRAP JRST PGRT3 PGRME: MOVE 2,[SIXBIT /PAGER/] MOVEM 2,DEVMPE ;REQUEST CORE SCAN ISB APRCHN BUG(CHK,) JRST PGUNTP ;TRY AGAIN ;DISPATCH PROCEDURE FOR TRAP STATUS BITS TABA: EXP TRP0,TRP1,TRP2,TRP3 TRP1: CAIL 2,7 BUG(HLT,) XCT TAB1(2) TAB1: BUG(HLT,) JRST NIC ;SHARED NOT IN CORE JRST NIC ;PAGE TABLE NOT IN CORE JRST NIC ;2ND INDIRECT PRIV NOT IN CORE JRST NIC ;INDIRECT SHARED NOT IN CORE JRST NIC ;IND PT NIC JRST ILIND ;EXCESSIVE IND. TRP2: TRP3: CAIL 2,7 ;INDIRECT OR ORIGINAL PT EQUIVALENT BUG(HLT,) XCT TAB2(2) TAB2: JRST NIC ;PRIVATE NOT IN CORE JRST WCPY ;WRITE COPY TRAP JRST UTRP ;USER TRAP JRST NPG ;ACCESS (OR BIT 10-11 = 3) JRST ILRD ;ILLEGAL READ OR XCT JRST ILWR ;ILLEGAL WRITE BUG(HLT,) ;TRAP CODE 0, CST WORD BITS 0-2 = 0 TRP0: CALL GETTPD ;DECODE EFFECTIVE ADDRESS TLNE 2,17 ;PAGE MUST BE IN CORE BUG(HLT,) HLRZ 1,CST0(2) ;GET AGE CODE LSH 1,-^D12 CAIL 1,10 JRST NIC ;CHANGED STATE RECENTLY TRP0A: CAIN 1,6 ;READ IN PROGRESS? JRST TRP0R ;YES, WAIT FOR IT TO FINISH CAIN 1,2 ;READ COMPLETED? JRST NICN ;YES, GO GET IT JRST NIC ;NO, GO AHEAD TRAPSP: IOWD NTSK,TRAPSK ;POINTER TO LOCAL STACK ;ASSIGN PAGE AND SET AGE AGESET: MOVE 7,FORKX AGESN: PUSH P,2 MOVEI 2,0(1) AGES1: HLRZ 1,CST0(2) LSH 1,-^D12 CAIL 1,10 ;NOW ASSIGNED? JRST [ HLRZ 1,CST3(2) ;YES, FIND OUT WHERE ANDI 1,7777 CAML 2,SWPCOR ;NOT SWAPPABLE PAGE? OR CAIN 1,0(7) ;THIS PROCESS? JRST AGES2 ;YES, OK SOS PNDING ;DO THIS BECAUSE PAGE WAS EITHER ;AWAITING COLLECTION OR SOSWSP ;WILL AOS THIS COUNTER SOS SUMNRX CAIL 1,NFKS ;ANY PROCESS? JRST ATP1 ;NO PUSH P,2 MOVEI 2,0(1) CALL SOSWSP ;REDUCE WSP POP P,2 JRST ATP1] ;GO ASSIGN TO THIS PROCESS AGESX: XCT TRP0T(1) AGES2: MOVEI 1,0(2) POP P,2 RET TRP0T: JRST ATP0 ;AVAILABLE AND ON REPLACABLE QUEUE BUG(HLT,) JRST ATP1R ;READ COMPLETED BUG(HLT,) JRST ATP4 ;WRITE IN PROGRESS BUG(HLT,) JRST ATP2 ;READ IN PROGRESS BUG(HLT,) TRP0R: MOVSI 1,0(2) HRRI 1,SWPRT CALL PGIWT ;WAIT FOR PAGE AND ACCOUNT JRST NICN ATP1R: MOVSI 1,SWPERR ;CHECK FOR ERROR ON READ TDNN 1,CST3(2) JRST ATP1 ;NO ERROR PUSH P,2 MOVEI 1,^D11 ;FILE DATA ERROR PSI CHANNEL MOVEI 2,0(7) ;GET FORK NUMBER CALL PSIRQ ;INTERRUPT THE FORK RESKD1 POP P,2 JRST ATP1 ATP2: MOVSI 1,0(2) HRRI 1,SWPRT ;READ NOW IN PROGRESS OR COMPLETED JSYS SCHEDP ;RESCHEDULE UNTIL AVAILABLE JRST AGES1 ;CHECK AGE AGAIN ATP4: PIOFF LDB 1,[POINT 6,CST0(2),5] ;GET GUARANTEED UP TO DATE STATE CAIE 1,4 ;WRITE IN PROGRESS? JRST [ PION ;NO, GO LOOK AT STATE AGAIN JRST AGES1] SETZM CST0(2) ;INHIBIT COMPLETION ACTION SOS PNDING SOS SUMNRX PION SOS IOIP JRST ATP1 ATP0: SOS NRPLQ ;ONE LESS PAGE ON REPLACABLE PIOFF MOVE 1,CST3(2) ;UNQUEUE PAGE FROM REPLACABLE HLLM 1,0(1) MOVS 1,1 HLRM 1,0(1) PION SETZM CST3(2) ATP1: AOS 1,FKWSP(7) ;INCREASE OWNERSHIP COUNT PUSH P,2 MOVEI 1,0(1) PUSH P,1 MOVE 2,FKFLGS(7) TLNE 2,BLST ;IN BALANCE SET? TLNE 2,FORCEM ;HALF REMOVED PROCESS? JRST [AOS SUMNRX ;YES, TREAT LIKE NON-BALSET AOS POTEN JRST ATP1A] HRRZ 1,FKNR(7) ;GET CURRENT RESERVE CAML 1,0(P) ;LESS THAN CURRENT SIZE? JRST ATP1A ;NO, OK SUB 1,0(P) ;YES, CALCULATE DIFFERENCE MOVN 1,1 ADDM 1,FKNR(7) ;INCREASE RESERVE ADDM 1,SUMNRX ATP1A: SUB P,BHC+1 ;FLUSH GARBAGE HLRZ 1,FKNR(7) ;GET UPDATED AGE POP P,2 ;RESTORE PAGE NUMBER DPB 1,[POINT 9,CST0(2),8] ;NEW AGE OF PAGE DPB 7,[POINT 12,CST3(2),17] ;ASSIGN PAGE TO PROCESS MOVSI 1,(777B8!CORMB) ;PRESERVE AGE AND CORMB ANDM 1,CST0(2) ;AND CLEAR ALL PROCESS USE BITS JRST AGES2 ;ILLEGAL REFERENCE TRAPS ILRD: MOVEI 1,^D16 ;MR TRAP CHANNEL MOVE 2,TRAPSW TLNE 2,2 ;EXECUTE REFERENCE? MOVEI 1,^D18 ;YES, MX ILRF: CALL PSIRQ0 ;REQUEST INTERRUPT, THIS FORK RESKD1 MOVE 1,TRAPSW MOVEM 1,UTRSW ;IN CASE USER WANTS TRAP STATUS MOVE 2,-1(P) ;WRITE DATA (ASSUMING TOP-LEVEL TRAP) MOVEM 2,UTRWD MOVE 2,-2(P) ;PC TLNN 2,UMODF ;USER? SKIPGE INTDF ;OR INTERRUPTABLE? JRST .+3 ;YES TLNE 1,12 ;MUST DEFER INTERRUPT, READ REF? AOS -2(P) ;YES, DONOT RESTART INSTRUCTION TLO 1,12 ;SET BITS TO PREVENT WRITE-COMPLETION MOVEM 1,TRAPSW ;ACTION ON UNTRAP JRST PGUNTP ILWR: MOVE 1,TRAPSW TLNE 1,1 ;MON REF BELOW 400000? TRNE 1,400000 SKIPA 1,[^D17] ;NO, INITIATE MW INTERRUPT BUG(HLT,) JRST ILRF ILIND: MOVE 1,TRAPSW ;SEE IF READ OR WRITE TLNE 1,12 JRST ILRD ;GIVE READ TRAP INTERRUPT JRST ILWR ;OR WRITE TRAP INTERRUPT UTRP: MOVEI 3,TRAPUB CALL GETTD1 ;FIND PAGE WITH TRAPUB SET HLRZ 6,1 CAIGE 6,NOFN ;COULDN'T BE IN FILE XB BUG(HLT,) CALL SETSPG ;MAP PT HOLDING PTR MOVSI 2,TRAPUB ANDCAM 2,CSWPGA(1) ;CLEAR THE BIT CALL RELSPG MOVEI 1,^D21 CALL PSIRQ0 ;INTERRUPT ON CHN 21 RESKD1 MOVE 1,TRAPSW MOVEM 1,UTRSW ;SAVE TRAP STATUS WORD ONLY JRST PGUNTP ;FINISH UP WRITE IF ANY AND UNTRAP ;PAGE NOT IN EXISTANCE TRAPS NPG: MOVE 1,TRAPSW TLNE 1,1 ;MONITOR? JRST [ MOVEI 1,0(1) ;YES, LEGAL PAGE? CAIL 1,JSB CAIL 1,JSB+1000 CAIA JRST MILRF1 CAIL 1,PPMA CAIL 1,DDPG1A JRST NPG1 ;YES JRST MILRF1] ;MONITOR MALFUNCTION NPG1: CALL GETTPD ;NEW PAGE NEEDED HLRZ 6,1 ;GET PT NUMBER CAIGE 6,NOFN ;MUST BE PT, NOT OFN JRST NPG2 CALL SETSPG ;MAP IT SKIPE 2,CSWPGA(1) ;BE SURE PT SLOT NOW EMPTY JRST NPGBAD ;IT'S NOT, PROBABLY SPURIOUS TRAP MOVSI 2,RWXB+1 MOVEM 2,CSWPGA(1) ;SETUP NULL POINTER CALL RELSPG ;RELEASE MAP MOVE 1,PSICHM MOVE 2,TRAPSW TLNN 2,1 ;USER MAP, AND TRNN 1,1B22 ;CHANNEL 22 ON? JRST NICFQ ;NO MOVEI 1,^D22 ;YES, REQUEST INTERRUPT CALL PSIRQ0 RESKD1 MOVE 1,TRAPSW MOVEM 1,UTRSW NICFQ: MOVE 1,DRMFRE## ;SEE IF DRUM IS FULL CAILE 1,100 ;TO DEFEND SYSTEM FROM DEATH JRST NICFQX ;OK MOVEI 1,^D20 ;FULL. GIVE MACH SIZE EXCEEDED PSI CALL PSIRQ0 ; TO CURRENT PROCESS RESKD1 ;MAKE HIM SEE IT, THEN GO ON. NICFQX: JRST NIC MILRF1: BUG(HLT,) NPGBAD: TLNN 2,ACCESB ;ACCESS BIT ON? BUG(HLT,) BUG(CHK,) CALL RELSPG ;CLEAN UP JRST PGUNTP ;GO UNTRAP AND TRY AGAIN ;THIS COULD CONCEIVABLY HAPPEN ON AN IND PTR TO A FILE FROM WHICH ;THE PAGE WAS REMOVED NPG2: JRST ILIND ;CAN ONLY GIVE TRAP TO USER ;COPY-ON-WRITE TRAP WCPY: MOVE 1,TRAPSW TLNE 1,(1B4+1B6) ;OTHER TRAPS ALSO? JRST [ TLZ 1,(1B3) ;YES, CLEAR WRITE COPY MOVEM 1,TRAPSW ;FROM TRAP CAUSE JRST PGRTD] ;AND GO HANDLE THE OTHER CAUSE WCPY6: CALL GETTPD TLNE 2,17 ;ACTUAL PAGE IN CORE? JRST NIC ;NO, GET IT IN FIRST JUMPE 2,ILWR ;ERROR IF PAGE DOES NOT EXIST AT ALL LDB 3,[POINT 6,CST0(2),5] ;AGE FIELD CAIN 3,6 ;IN PROCESS OF BEING READ? JRST WCPY5 ;YES. WAIT FOR IT. MOVEI 3,COPYB CALL GETTD1 ;WILL STOP ON FIRST POINTER WITH COPYB HLRZ 6,1 ;PTN CAIG 6,NOFN BUG(HLT,) CALL SETSPG ;MAP THE PT MOVSI 2,RWX AND 2,CSWPGA(1) ;GET ACCESS OF SOURCE PAGE IOR 2,[XWD WRITEB+ACCESB+1,1] ;MAKE PRIV PTR WITH UNASS ADR EXCH 2,CSWPGA(1) ;EXCH IT WITH THE WC POINTER TLNN 2,SHRBIT+INDBIT ;IT SHOULD BE SHARED OR INDIRECT JRST WCPY4 ;BUT IT'S NOT TLO 2,READB ;MAKE SURE WE CAN READ FROM THE PAGE MOVEM 2,PSB+CPYPG ;PUT THE ORIG POINTER IN MON MAP CALL RELSPG PUSH P,1 ;SAVE ORIG PTN.PN WCPY2: MOVEI 1,CPYPG ;CONSTRUCT IDENT FOR COPY SOURCE PAGE HRL 1,FKPGS(7) CALL GETPGD ;TRACK IT DOWN TLNE 2,17 ;IN CORE? BUG(HLT,) MOVEI 1,0(2) CALL AGESET ;FIX THE PAGE MOVSI 3,PLKV ADDM 3,CST1(1) ;AND LOCK IT DURING NEXT SWAPIN EXCH 1,0(P) ;SAVE CORE PN, GET ORIG PTN.PN CALL SWPINP ;THIS WILL COPY FROM CPYPG TO A NEW PAGE POP P,1 MOVSI 3,-PLKV ADDM 3,CST1(1) ;UNLOCK THE SOURCE PAGE MOVEI 1,CPYPG HRL 1,FKPGS(7) CALL MRPT ;GET IDENT OF SHARE PAGE BEING RELEASED SETZ 1, ;INDIRECT TO FORK PUSH P,1 OKSKED MOVEI 1,CPYPG HRL 1,FKPGS(7) CALL RELMPG ;RELEASE THE ORIG PAGE FROM MON MAP BUG (HLT,) OKSKED CALL RELCPT ;CLEANUP FROM RELMPG POP P,1 JUMPE 1,WCPY3 ;IGNORE INDIRECT TO FORK PTR MOVE 5,0 MOVE 6,11 ;SAVE AC'S USED BY OFNJFN CALL JFNDCR ;DECREMENT MAP COUNT FOR JFN MOVE 0,5 MOVE 11,6 ;RESTORE AC'S WCPY3: NOSKED JRST NIC ;UPDATE STATS AND CONTINUE WCPY4: TLZ 2,COPYB ;MAKE IT LOOK LIKE WE COPIED IT TLO 2,WRITEB MOVEM 2,CSWPGA(1) CALL RELSPG JRST NIC2 WCPY5: MOVSI 1,(2) ;WAIT FOR THIS PAGE HRRI 1,SWPRT ;READ COMPLETE TEST JSYS SCHEDR ;WAIT AND GO OKSKED NOSKED JRST WCPY6 ;TRY AGAIN ;NOT IN CORE TRAP NIC: MOVE 1,FKFLGS(7) ;SEE IF THERE IS A REQUEST TO CLEAR IFAV TLZE 1,ZIFA ;REQUEST TO ZERO INTERFAULT AV? SETZM IFAV NICN2: TLZ 1,NOFLT ;INDICATE SCHED CAN ADJUST FKNR IF NO PAGE FAULTS OCCUR MOVEM 1,FKFLGS(7) MOVE 1,IFAV ;UPDATE INTERFAULT AV FMPR 1,IFAVC0 ;AV' = (C*AV + TIME)/(C+1) SETZ 2, EXCH 2,IFTIM ;ACCUMULATED TIME SINCE LAST FAULT ADD 2,JOBRTT ;GET IFTIM UP TO DATE FSC 2,233 ;FLOAT IT FADR 1,2 FDVR 1,IFAVC1 MOVEM 1,IFAV MOVE 2,JOBNO HRRZ 2,JOBNAM(2) ;GET SUBSYSTEM INDEX AOS SPFLTS(2) ;ACCOUNT PAGE FAULTS FOR SUBSYSTEM NICN: SKIPE TRAPC ;IS THIS A RECURSIVE TRAP? JRST NIC2 ;YES, AVOID PDL OV IN ANY GC LOGIC LDB 1,[POINT 9,FKNR(7),8] ;GET LAST XGC AGE LDB 2,[POINT 9,FKNR(7),17] ;CURRENT AGE SUBI 2,0(1) ;NOW-THEN CAIGE 2,0 ;WRAPAROUND? ADDI 2,1000-100 ;YES CAML 2,GCRATE ;TIME FOR ANOTHER XGC? JRST NICMG ;YES NICMG1: CALL NICCKS ;CHECK FOR ALLOWABLE SIZE NIC2: MOVE 3,TRAPSW TLNN 3,1 ;USER MAP REF? JRST [ LSH 3,-^D9 ;YES, UPDATE WS BITS ANDI 3,777 IDIVI 3,^D36 MOVE 4,BITS(4) IORM 4,WSPGS(3) JRST .+1] CALL GETTPD ;DECODE TRAP ADDRESS TLNE 2,17 ;PAGE IN CORE? JRST NIC6 ;NO MOVEI 1,0(2) ;YES CALL AGESET ;SET AGE JRST PGUNTP ;RESUME PROCESS NIC6: TLNN 2,16 ;UNASSIGNED ADR? JRST NIC6A ;YES NIC8: CALL SWPINW ;SWAP IN THE PAGE JRST NIC2 ;ADJUST CAPT IF NECESSARY, THEN DO CORE MGT NICMG: MOVE 1,IFAV ;CURRENT INTERFAULT AVERAGE MOVE 2,CAPT ;CURRENT WINDOW SIZE MOVE 3,2 ASH 3,-4 ;ADJUST UP OR DOWN BY 1/16 CAMGE 1,IFALO ;IFAV NOW TOO LOW? ADD 2,3 ;YES, MAKE CAPT LARGER CAML 1,IFAHI ;IFAV NOW TOO HIGH? SUB 2,3 ;YES, MAKE CAPT SMALLER CAMLE 2,CAPTMX ;SEE IF CAPT WITHIN LIMITS MOVE 2,CAPTMX CAMGE 2,CAPTMN MOVE 2,CAPTMN MOVEM 2,CAPT MOVEI 1,0(2) ;USE CURRENT CAPT CALL XGC JRST NICMG1 ;RETURN ;AVERAGE SWAP LATENCY * 2 - CONTROLS DESIRED INTERFAULT AVERAGE SWPLAT: 40.0 ;2 * 20MS FOR BRYANT DRUM IFAMEA: 40.0 ;IDEAL IFAV ;WE WOULD LIKE TO KEEP PROCESSES OPERATING WITH ; IFALO .LT. IFAV .LT. IFAHI IFAHI: 60.0 ;1.5*IFAMEA IFALO: 20.0 ;.5*IFAMEA AGTICK==^D20 ;MILLISECONDS PER TICK OF AGE REGISTER ICAPT: ^D1000/AGTICK ;WINDOW SIZE IN TICKS CAPTMX: ^D1500/AGTICK ;MAX CAPT CAPTMN: ^D500/AGTICK ;MIN CAPT GCRATE: ^D1000/AGTICK ;RECIPROCAL OF GC FREQUENCY ;DECAY CONSTANT FOR INTERFAULT AVERAGE IFAVC0: EXP 10.0 ;LARGER C IMPLIES SLOWER IFAV CHANGE IFAVC1: EXP 11.0 ;IFAVC0+1 NIC6A: TLNE 1,-1 ;IN SPT? JRST [ HLRZ 6,1 ;NO, GET XB CAIL 6,NOFN ;OFN? JRST NIC8 ;NO CALL SETSPG MOVSI 2,PLKV ADDM 2,CST1(6) ;LOCK PT WHILE ASSIGNING CALL RELSPG HLRZ 2,1 JRST NIC6C] HLRZ 2,SPTH(1) ;GET OWNING PT JUMPE 2,NIC8 ;IGNORE IF NONE OR NOT OFN CAIL 2,NOFN JRST NIC8 NIC6C: PUSH P,1 MOVE 1,SPTH(2) ;CLASS, TRACK, ETC. CALL DSKASN ;ASSIGN DISK ADDRESS FOR FILE PAGE JRST NIC6D ;RAN OUT TLO 1,NEWFB ;INDICATE PAGE NEVER PREVIOUSLY WRITTEN MOVE 2,1 POP P,1 TLNN 1,-1 ;IN SPT? JRST [ DPB 2,[POINT 22,SPT(1),35] ;YES, STORE NEW ADDRESS JRST NIC8] ;NOW GO SWAP IN PAGE HLRZ 6,1 CALL SETSPG ;MAP XB DPB 2,[POINT 22,CSWPGA(1),35] ;STORE NEW ADDRESS IN XB MOVSI 2,-PLKV ADDM 2,CST1(6) ;UNDO LOCK ABOVE CALL RELSPG JRST NIC8 ;NOW PROCEED WITH SWAP NIC6D: POP P,1 TLNN 1,-1 ;IN SPT? JRST NIC6E ;YES HLRZ 6,1 ;NO, MUST UNDO LOCK CALL SETSPG MOVSI 2,-PLKV ADDM 2,CST1(6) CALL RELSPG NIC6E: MOVEI 1,OPNX10 ;'NO ROOM' MOVEM 1,LSTERR MOVEI 1,^D20 ;MACH SIZE EXCEEDED INT CHANNEL JRST ILRF ;GENERATE ILLEG REF INT ;CHECK OVERALL SIZE FOR PHYSICAL CORE LIMITS NICCKS: MOVE 1,IFAV ;GET INTERFAULT AV. CAMGE 1,IFALO ;IS HE RUNNING WELL? JRST NICCK2 ;NO, DON'T REDUCE HIS FKNR HRRZ 1,FKNR(7) ;HE IS RUNNING WELL, SET FKNR TO FKWSP+1 HRRZ 2,FKWSP(7) SUBI 2,-1(1) ;-(FKNR-(FKWSP+1)) ADDM 2,SUMNRX ADDM 2,FKNR(7) NICCK2: MOVE 1,CAPT ;INIT WINDOW SIZE FOR POSSIBLE XGC ASH 1,-3 ;IS 1/8 REG CAPT NIC3B: PUSH P,1 NIC3A: HRRZ 1,FKNR(7) HRRZ 3,FKWSP(7) CAIG 1,0(3) ;RESERVE GREATER THAN CURRENT ASSMT? JRST NIC3C ;NO, GO MAKE IT SO NIC3G: MOVE 2,NBPROC ;IS THIS THE ONLY PROC IN BALSET? CAIN 2,1 JRST [MOVE 3,NRPLQ ;YES, BETTER SEE HOW RPLQ IS DOING ADD 3,IOIP CAML 3,NRPMIN JRST .+1 JRST NIC3] ;NOT SO WELL, MAKE HIM PAGE AGINST HISSELF CAML 1,NPMAX ;DEFINITELY TOO BIG? JRST NIC3 ;YES CAMGE 1,SNPMAX ;DEFINITELY NOT TOO BIG? JRST NIC3E ;YES ;MAYBE TOO BIG -- YES IF OTHER CAILE 2,1 ;PROCESSES IN BALSET JRST NIC3 JRST NIC3E NIC3: CALL GCPG ;TRY COLLECTING JUST 1 PAGE JRST .+2 ;FAILED, MAYBE NO USER MAP PAGES JRST NIC3A MOVE 1,0(P) ;GET WINDOW SIZE CALL XGC ;DO GC POP P,1 JUMPE 1,R ;JUST CANT GET ANYMORE, AVOID LOOPING ASH 1,-1 ;IF ANOTHER GC NECESSARY, USE JRST NIC3B ;SMALLER WINDOW NIC3E: POP P,1 ;FLUSH TEMP RET NIC3C: MOVE 2,RJAV CAMGE 2,[2.0] ;LESS THAN 2 FORKS AV? JRST NIC3F ;YES, ALLOW NR GROWTH MOVE 1,IFAV CAMG 1,IFAMEA ;PROCESS FAULT AV .G. DESIRED? JRST NIC3F ;NO, ALLOW CALL GCPG ;YES, REMOVE 1 PAGE JRST NIC3F ;COULDN'T, HAVE TO ALLOW NR INCREASE JRST NIC3A NIC3F: HRRZ 1,FKNR(7) HRRZ 3,FKWSP(7) SUBI 3,-1(1) ;SET RESERVE TO BE CURRENT SIZE +1 ADDM 3,SUMNRX ADDM 3,FKNR(7) JRST NIC3G ;REMOVE 1 PAGE FROM PROCESS. SELECT FIRST PAGE OLDER THAN CAPT, ;OR OLDEST PAGE GCPG: MOVSI 6,-NWSPGS ;SET TO SCAN WS BIT TABLE PUSH P,[0] ;WILL REMEMBER OLDEST PAGE FOUND LDB 3,[POINT 9,FKNR(7),17] ;PROCESS AGE NOW PUSH P,3 SUB 3,CAPT ;CUTOFF AGE PUSH P,3 MOVE 3,-1(P) ;USE CURRENT AGE AS INIT MIN AGE GCPG2: SKIPE 4,WSPGS(6) GCPG3: JFFO 4,GCPG1 ;FIND PAGE IN USE AOBJN 6,GCPG2 SUB P,BHC+2 ;DIDN'T FIND PAGE OLDER THAN CAPT POP P,1 ;USE OLDEST PAGE SEEN JUMPE 1,R ;DIDN'T FIND COLLECTABLE PAGE JRST GCPG4 ;COLLECT IT GCPG1: ANDCM 4,BITS(5) MOVEI 1,0(6) IMULI 1,^D36 ;COMPUTE MAP PAGE NUMBER ADDI 1,0(5) SKIPE 1,UPTA(1) ;GET MAP WORD TLNE 1,INDBIT JRST GCPG3 ;IGNORE EMPTY OR INDIRECT TLNE 1,SHRBIT ;SHARE PTR? JRST [ LSH 1,-^D9 ;YES, TRACE ANDI 1,SPTM MOVE 1,SPT(1) JRST .+1] TLNE 1,17 ;IN CORE? JRST GCPG3 ;NO HLRZ 2,CST0(1) TRNN 2,(7B2) ;ASSIGNED? JRST GCPG3 ;NO HLRZ 5,CST3(1) ;YES, TO THIS PROCESS? ANDI 5,7777 CAIE 5,0(7) JRST GCPG3 ;NO LSH 2,-^D9 ;YES, GET AGE CAMLE 2,-1(P) ;CHECK WRAPAROUND SUBI 2,1000-100 CAMLE 2,0(P) ;OUTSIDE CAPT WINDOW? JRST [ MOVE 5,2 ;NO, SAVE AGE CAMGE 2,3 ;OLDEST PAGE SEEN? CALL SWPCHK ;SWAPPABLE? JRST GCPG3 ;NO MOVE 3,5 ;YES, REMEMBER OLDEST AGE MOVEM 1,-2(P) ;AND PAGE JRST GCPG3] CALL SWPCHK ;CAN SWAPOUT PAGE? JRST GCPG3 ;NO SUB P,BHC+3 ;YES, FLUSH TEMPS GCPG4: SOS FKWSP(7) ;DEASSIGN PAGE SOS FKNR(7) AOS PNDING ;COUNT PAGE AWAITING COLLECTION CALL SWPOUT ;SWAP IT AOS 0(P) ;RETURN GOOD RET ;CHECK IF PAGE IS SWAPPABLE NOW SWPCHK: MOVE 2,CST1(1) TLNE 2,-PLKV RET ;PAGE IS LOCKED OR HAS NO SWAP ADR MOVSI 2,DWRBIT TDNN 2,CST3(1) ;BEING WRITTEN? AOS 0(P) ;NO, OK RET ;COLLECT OLD PAGES FOR THIS PROCESS, CALLED WITH CUTOFF DIFFERENCE IN 1 ;THE PAGES ASSIGNED TO THIS PROCESS ARE ASSUMED TO HAVE AGES RANGING ;FROM M1 TO M2. M2 IS THE CURRENT AGE, LH OF FKNR. WE WISH TO ;FLUSH ALL PAGES OLDER THAN M, WHERE M1> ;HAS BEN REFERENCED ONLY ONCE, THE AGES WOULD BE EVENLY DISTRIBUTED ;BETWEEN M1 AND M2. HOWEVER, PAGES ACTIVELY BEING USED SHOULD ;HAVE AGES CLOSER TO M2. THEREFORE, WE PICK A CUTOFF AGE BY ;SUBTRACTING A SMALL NUMBER FROM M2. TO PREVENT EXCESSIVE COLLECTION ;WHERE ALL PAGES HAVE BEEN REFERENCED RECENTLY, WE SET A LIMIT ;ON THE TOTAL NUMBER OF PAGES WHICH CAN BE FLUSHED, AND STOP ;IF WE HIT THIS LIMIT. ALSO, SINCE AGES CAN WRAP AROUND THE 9-BIT ;FIELD, AGES GREATER THAN M2 ARE ASSUMED TO BE LEFT FROM THE PREVIOUS ;WRAP AROUND AND ARE ADJUSTED ACCORDINGLY. XGC: HRRZ 4,FKCNO(7) PUSH P,BITS(4) ;PROCESS USE BIT FOR THIS PROCESS MOVE 6,SWPCOR ;FIRST SWAPPING PAGE HRRZ 4,FKWSP(7) ;NUMBER PAGES NOW IN CORE ; ASH 4,-1 ;COMPUTE 1/2 CURRENT SIZE PUSH P,4 ;MAX NUMBER OF PAGES TO COLLECT LDB 3,[POINT 9,FKNR(7),17] ;CURRENT AGE CLOCK DPB 3,[POINT 9,FKNR(7),8] ;REMEMBER 'TIME' OF LAST XGC PUSH P,3 SUBI 3,0(1) ;CUTOFF AGE, 'OLD'=NOW-DIFFERENCE PUSH P,3 XGC2: HLRZ 1,CST0(6) TRNN 1,700000 ;PAGE IN USE? JRST XGC1 ;NO HLRZ 2,CST3(6) ANDI 2,7777 CAIE 2,0(7) ;ASSIGNED TO THIS PROCESS? JRST XGC1 ;NO LSH 1,-^D9 ;YES, GET AGE FIELD MOVE 2,-3(P) ;PROCESS USE BIT ANDCA 2,CST0(6) ;LOOK AT OTHER PROCESS USE BITS TDNE 2,[377777777] ;IF ANY ON, MEANS REFERENCES BY OTHER MOVE 1,-1(P) ;PROCESSE, AGE INVALID SO USE CURRENT CAMLE 1,-1(P) ;IF .G. NOW, MUST NOT HAVE WRAPPED SUBI 1,1000-100 ;SO WRAP IT CAMLE 1,0(P) ;.G. OLD? JRST XGC1 ;YES, SAVE IT MOVE 2,CST1(6) TLNE 2,-PLKV ;DON'T SWAP PAGE IF LOCKED JRST XGC1 MOVSI 2,DWRBIT TDNE 2,CST3(6) ;DON'T SWAP PAGE IF NOW BEING WRITTEN JRST XGC1 SOS FKWSP(7) ;DEASSIGN PAGE FROM THIS PROCESS SOS FKNR(7) AOS PNDING MOVEI 1,0(6) CALL SWPOUT ;SWAP IT OUT SOSG -2(P) ;COLLECTED ENOUGH PAGES? JRST XGC3 ;YES OKSKED ;DON'T HOG MACHINE FOR TOO LONG NOSKED XGC1: CAMGE 6,NHIPG ;STOP AFTER HIGHEST KNOWN PAGE AOJA 6,XGC2 ;NO, LOOK AT NEXT PAGE XGC3: SUB P,BHC+4 ;FLUSH STACK PGRCLD ;CLEAR AR'S SETZ 3, MOVSI 6,-NWSPGS ;SETUP TO UPDATE WS BITS XGC5: SKIPE 4,WSPGS(6) XGC6: JFFO 4,XGC4 ;FOUND BIT FOR PAGE AOBJN 6,XGC5 RET XGC4: ANDCM 4,BITS(5) ;DON'T FIND THAT BIT NEXT TIME MOVEI 1,0(6) ;COMPUTE PAGE NUMBER IMULI 1,^D36 ADDI 1,0(5) SKIPE 1,UPTA(1) ;PAGE DELETED? TLNE 1,INDBIT ;OR INDIRECT? JRST XGC7 ;YES, FORGET IT TLNE 1,SHRBIT ;SHR PTR? JRST [ LSH 1,-^D9 ;YES, GET ACTUAL ADDRESS ANDI 1,SPTM MOVE 1,SPT(1) JRST .+1] TLNE 1,17 ;PAGE NOW IN CORE? JRST XGC7 ;NO, FLUSH IT MOVE 2,CST0(1) TLNE 2,(7B2) ;STILL IN USE? AOJA 3,XGC6 ;YES, COUNT IT AND LEAVE IT TLC 2,(02B5) ;READ COMPLETED? TLNE 2,(77B5) JRST XGC7 ;NO CALL AGESET AOJA 3,XGC6 ;COUNT PAGE AND KEEP IT XGC7: MOVE 1,BITS(5) ANDCAM 1,WSPGS(6) ;CLEAR BIT FOR PAGE NO LONGER IN WS JRST XGC6 ;RELEASE WORKING SET JSYS .RWSET: JSYS MENTR NOSKED MOVE 7,FORKX SETZ 1, ;USE 0 WINDOW SIZE CALL XGC ;COLLECT ALL PAGES HRRZ 1,FKWSP(7) ;SET NEW NR TO MAX(6,SIZE) CAIGE 1,6 ;SIZE .GE. 6? MOVEI 1,6 ;NO, USE 6 AS NEW NR HRRZ 2,FKNR(7) SUBI 1,0(2) ADDM 1,FKNR(7) ADDM 1,SUMNRX OKSKED JRST MRETN ;RESUME PROCESS AFTER PAGER TRAP PGUNTP: SKIPE TRAPC ;OUTER LEVEL TRAP? JRST PGU4 ;NO IFN KIFLG,< POP P,KIMAC2 POP P,KIMAC1> ;RESTORE KI-10 MUUO TEMPS POP P,1 ;PROCESS TIME AT TIME OF ENTRY MOVE 2,FKRT ADD 2,JOBRTT ;2=CURRENT PROCESS TIME SUB 2,1 ;TIME OF TRAP CODE ADDM 2,PTTIM ;PAGE TRAP TIME FOR THIS FORK ADDM 2,PTRAP ;PAGE TRAP TIME FOR SYSTEM AOS TOPTRP ;COUNT TOP LEVEL TRAPS PGU4: AOS PTRAP+1 ;COUNT TRAPS IFN KAFLG,< CONO PGR,0> ;LOAD WITH NEW AGE POP P,2 ;RECOVER WRITE DATA MOVE 3,TRAPSW ;GET TRAP BITS SKIPE TRAPC ;IF RECURSIVE TRAP, POP P,TRAPSW ;RESTORE OLD STATUS WORD TLNE 3,12 ;READ OR XCT? JRST PGU1 ;YES, RESTART INSTRUCTION TLNE 3,1 ;USER OR MONITOR? JRST PGU2 ;MONITOR PGMV1: UMOVEM 2,0(3) ;USER PGU1: POP P,1 ;GET RETURN TLNN 1,UMODF ;TO USER? JRST PGU3 ;NO, MONITOR MOVEM 1,FPC ;USER, CAN PUT RETURN IN FPC MOVE 7,-6(P) MOVE 1,-5(P) MOVE 2,-4(P) MOVE 3,-3(P) MOVE 4,-2(P) MOVE 5,-1(P) MOVE 6,0(P) MOVE P,TRAPAP ;USER MODE, SO MUST BE TOP LEVEL TRAP SETOM TRAPC SETOM INTDF ;FOR USER, MUST BE -1 OKSKED XCT MJRSTF ;RETURN, WILL GET DEFERRED INTERRUPT TOO PGMV2: PGU2: MOVEM 2,0(3) ;STORE MONITOR WRITE DATA JRST PGU1 PGU3: MOVEM 1,PGURET ;SET UP RETURN MOVE 7,-6(P) MOVE 1,-5(P) MOVE 2,-4(P) MOVE 3,-3(P) MOVE 4,-2(P) MOVE 5,-1(P) MOVE 6,0(P) SUB P,BHC+7 SOSGE TRAPC ;TOP LEVEL TRAP? MOVE P,TRAPAP ;RESTORE AC-P OKSKED ;TURN SCHEDULER BACK ON (WILL ALSO PICK ;UP PENDING PSI'S) OKINT ;TURN PSIS BACK ON AND PICK UP ANY THAT ;WERE DEFERRED JRSTF @PGURET ;RETURN ;GET PAGE DATA ;TRACES PTN.PN IN 1 TO NOT IN CORE OR CORE PAGE NUMBER OR WRITE COPY ;RETURN AS GETTPD GETPGD: HLRZ 2,1 ;PTN TO 2 MOVEI 1,0(1) ;PN TO 1 SETZ 3, ;NO SPECIAL BITS TO STOP ON JRST GETPD1 ;FOLLOW LIKE IND POINTER ;GET TRAP DATA ;RETURNS OFN.PN OR 0.SPTN IN 1 ; MAP WORD IN 2 GETTPD: SETZ 3, ;NO SPECIAL BITS TO STOP ON GETTD1: HRRZ 1,TRAPSW ;TRAP EFFECTIVE ADDRESS LSH 1,-^D9 ;PAGE NUMBER HLRZ 2,TRAPSW ;TRAP BITS TRNE 2,1 ;USER OR MONITOR? JRST NIC4 ;MONITOR HLL 1,FKPGS(7) ;USER, GET PAGE TABLE SPTN MOVE 2,UPTA(1) NICI2: TLNE 2,0(3) ;REQUESTED BIT ON? RET ;YES, STOP HERE TLNE 2,INDBIT ;INDIRECT POINTER? JRST NICI ;YES TLNN 2,SHRBIT ;SHARE POINTER? RET ;NO, PRIVATE LSH 2,-^D9 ;YES, SHIFT TO B35 ANDI 2,SPTM ;FLUSH BITS NICI1: MOVEI 1,0(2) MOVE 2,SPT(1) RET NICI: SETZ 1, ;INDIRECT POINTER. ROTC 1,-^D9 ;GET OFN TO 2, PN TO 1 ROT 1,^D9 ANDI 2,SPTM GETPD1: MOVE 6,SPT(2) ;GET PAGE TABLE ADDRESS TLNE 6,17 ;IN CORE? JRST NICI1 ;NO, THAT'S THE TROUBLE. HRLI 1,0(2) ;YES, PUT OFN IN 1 MOVEI 6,0(2) CALL SETSPG ;MAP PT MOVE 2,CSWPGA(1) ;GET MAP WORD CALL RELSPG ;CLEAR TEMPORARY MAP WORD JRST NICI2 ;GO ANALYZE THIS POINTER NIC4: CAIL 1,PJMPG ;MONITOR MAP, WHICH ONE? JRST NIC4A ;IN PSB CAIL 1,PPRMPG+NRSPG JRST NIC4B ;IN RES MON IFE JTRPSW-1,< CAIN 1,NJDVPG ;IF MAPPING RES MON IS PAGE JSYS DSP? JRST NIC4B > ;YES. BUG(HLT,) NIC4A: HRL 1,FKPGS(7) ;PSB MOVE 2,PSB(1) JRST NICI2 NIC4B: HRL 1,MMSPTN ;PERMANENT SWP MON OFN MOVE 2,MMAP(1) JRST NICI2 ;SWAP IN PAGE TABLE OR PSB ;CALLED FROM SCHED SWPIN0: TLNE 1,-1 ;SPTN? JRST SWP01 ;NO MOVE 3,SPT(1) ;YES, GET CURRENT ADDRESS TLNE 3,17 ;OUT OF CORE? JRST SWP01 ;YES LDB 2,[POINT 6,CST0(3),5] ;AGE CODE CAIE 2,2 ;BEING READ OR COMPLETED? CAIN 2,6 JRST SWP03 ;YES MOVEI 1,0(3) CALL AGESN ;GRAB PAGE OFF RPLQ SWP03: MOVSI 1,0(3) ;ALREADY IN CORE JRST SWP02 SWP01: CALL SWPIN HLRZ 3,1 SWP02: MOVSI 2,PLKV ADDM 2,CST1(3) ;LOCK PAGE RET ;SWAPIN AND WAIT AND STAY NOSKED SWPINP: NOSKED CALL SWPINW OKSKED RET ;WAIT FOR PAGE AND ACCOUNT PGIWT: JSYS SCHEDR MOVNI 2,5 ;CHARGE 5 MS PER PAGE FAULT ADDM 2,RJQNT ;CHARGE AGAINST QUANTUM NOSKED RET ;SWAP IN AND WAIT FOR COMPLETION SWPINW: MOVE 7,FORKX AOS USWPCT ;COUNT SWAPS TLNE 1,-1 ;PT? JRST SWPIW2 ;YES CALL SWPIN ;SWAPIN AND WAIT FOR COMPLETION SWPIW1: CALL PGIWT HLRZ 1,1 ;RESTORE PAGE NO TO R.H. RET SWPIW2: PUSH P,1 ;SAVE ORIG REQUEST HLRZ 1,1 ;GET PT MOVE 3,SPT(1) TLNE 3,17 ;CORE? JRST SWPIW3 ;NO MOVEI 1,0(3) CALL AGESET ;FIX PAGE MOVSI 3,PLKV ADDM 3,CST1(1) ;SO IT DOESN'T SNEAK AWAY SWPIW4: EXCH 1,0(P) ;SAVE CORE PAGE NUMBER, GET ORIG OFN.PN CALL SWPIN ;SWAP THE ORIG PAGE EXCH 1,0(P) ;GET PT CORE PAGE NUMBER MOVSI 3,-PLKV ADDM 3,CST1(1) ;UNLOCK IT POP P,1 JRST SWPIW1 SWPIW3: NOSKED CALL SWPIN ;SWAP IN THE PT OKSKED HLRZ 2,1 MOVSI 3,PLKV ADDM 3,CST1(2) ;LOCK IT HRRI 1,SWPRT JSYS SCHEDP ;WAIT TO FINISH HLRZ 1,1 CALL AGESET JRST SWPIW4 ;NOW GO GET THE PAGE ;SWAP IN PAGE ;AC1/ OFN.PN OR 0.SPTN ;RETURNS AC1/ CORE PAGE NO IN LH SWPIN: MOVE 3,NRPLQ ;NUMBER OF REPLACABLE PAGES JUMPE 3,SWPQT ;GO WAIT IF NONE SWPIL1: SOS NRPLQ HRRZ 3,RPLQ ;YES, REMOVE FROM QUEUE SUBI 3,CST3 PIOFF MOVE 4,CST3(3) HLLM 4,0(4) MOVS 4,4 HLRM 4,0(4) PION SETZM CST3(3) CALL DEPG ;RESET PREVIOUS OWNERSHIP TLNE 1,-1 ;NEW PAGE FROM PT OR SPT? JRST SWPI3 ;PT MOVE 4,SPT(1) ;SPT, GET ADDRESS TLNN 4,17 BUG(HLT,) DPB 3,[POINT 22,SPT(1),35] ;STORE NEW (CORE) ADDRESS SWPI4: TLZ 4,-1B31 ;FLUSH BITS MOVEM 4,CST1(3) ;STORE BACKUP ADDRESS MOVEM 1,CST2(3) ;STORE LOCATION OF OWNING PT TLNE 4,16 ;BACKUP ADDRESS ASSIGNED? JRST SWPI5 ;YES, GO READ IN PAGE MOVSI 1,400000 ;SET LEGAL AGE SO PAGER DOESN'T TRAP MOVEM 1,CST0(3) TLO 3,RWXB ;NO, ZERO OUT PAGE MOVEM 3,MMAP+CSWPG SETZM CSWPGA MOVEI 1,CSWPGA+1 HRLI 1,-1(1) TRNE 4,1 ;SPECIAL UNASSIGNED POINTER? MOVE 1,[XWD CPYPGA,CSWPGA] ;YES, COPY FROM CPYPG BLT 1,CSWPGA+777 CALL RELSPG MOVSI 1,(2B5+CORMB) ;SET STATUS OF PAGE TO READ COMPLETED HRRI 1,0(7) ;INCLUDE FORK NUMBER MOVEM 1,CST0(3) MOVSI 1,0(3) ;RETURN PAGE NUMBER HRRI 1,SWPRT ;RETURN APPROPRIATE SCHED TEST RET SWPI3: HLRZ 6,1 ;GET OWNING PT OFN CALL SETSPG ;MAP PT MOVSI 4,PLKV ADDM 4,CST1(6) ;INCREMENT LOCK COUNT MOVE 4,CSWPGA(1) TLNN 4,17 BUG(HLT,) DPB 3,[POINT 22,CSWPGA(1),35] ;STORE NEW (CORE) ADDRESS CALL RELSPG JRST SWPI4 SWPQT: PUSH P,1 ;SAVE REQUESTED PAGE IDENT MOVEI 1,SWPWTT ;RESCHEDULE UNTIL NRPLQ NON-0 JSYS SCHEDP POP P,1 JRST SWPIN SWPWTT: SKIPLE NRPLQ JRST 1(4) SETOM CGFLG ;REQUEST GARBAGE COLLECT JRST 0(4) SWPI5: MOVEI 1,0(3) MOVE 2,CST2(1) ;FIGURE OUT IF PAGE IS MAYBE A PT TLNE 2,-1 ;IN SPT? JRST SWPI6 ;NO, COULDN'T BE PAGE TABLE CAIL 2,NOFN ;PAGE IS PAGE TABLE IF IT IS FILE XB, SKIPN SPTH(2) ;OR IF IT IS SHARED BUT DOES NOT JRST .+2 ;BELONG TO ANY PT OR XB JRST SWPI6 MOVEI 2,0(1) ;BEFORE INITIATING SWAP OF PT, TLO 2,RWXB ;FILL THE ENTIRE CORE PAGE WITH MOVEM 2,MMAP+CSWPG ;PTRS WHICH WILL CAUSE THE PAGER TO MOVSI 2,400000 ;TRAP IN A SAFE WAY SHOULD IT HAPPEN MOVEM 2,CST0(1) ;TO INTERPRET AN INDIRECT PTR WHICH MOVE 2,[XWD CSWPGA,CSWPGA+1] ;GOES THROUGH THIS PT BEFORE MOVSI 3,RWXB+1 ;THE READ IS COMPLETED. THIS IS DONE MOVEM 3,-1(2) ;BECAUSE THE PAGER DOES NOT CHECK BLT 2,CSWPGA+777 ;CST0 WHEN READING A PTR FROM AN IND CALL RELSPG ;PT AND SO DOESN'T NOTICE IF THE PAGE SWPI6: MOVSI 2,(6B5) ;IS BEING SWAPPED IN. HRRI 2,0(7) ;INCLUDE FORK NO. MOVEM 2,CST0(1) ;PUT READ-IN-PROGRESS CODE IN CST0 TLNE 4,10 ;DISK? JRST SWPIK ;YES TLNE 4,14 ;DRUM? BUG(HLT,) CALL DRMIO ;YES, INITIATE READ AOS DRMRD ;COUNT DRUM READS FOR STATISTICS MOVSI 1,0(1) HRRI 1,SWPRT ;RETURN APPROPRIATE SCHED TEST RET SWPIK: TLNE 4,NEWFB ;NEWLY ASSIGNED PAGE? JRST [ CALL SWPZPG ;YES, ZERO IT MOVSI 2,NEWFB ANDCAM 2,CST1(1) MOVSI 2,(2B5+CORMB) HLLM 2,CST0(1) ;SET TO READ COMPLETED AND MODIFIED JRST .+2] CALL DSKIO ;INITIATE DISK READ AOS DSKRD ;COUNT DISK READS FOR STATISTICS MOVSI 1,0(1) ;RETURN APPROPRIATE SCHED TEST HRRI 1,DSKRT RET DEPG: MOVE 4,CST2(3) ;GET LOCATION OF PT OWNING OLD CONTENTS JUMPE 4,R ;0 => WAS NONE MOVE 5,CST1(3) ;GET BACKUP ADDRESS TLNE 4,-1 ;PT OR SPT JRST SWPI1 ;PT DPB 5,[POINT 22,SPT(4),35] ;SPT, RESTORE BACKUP ADDRESS MOVSI 6,-1B31 CAIGE 4,NOFN ;FILE XB? TDNE 6,SPT(4) ;WITH SHARE COUNT NOW 0? RET ;NO SETOM SPTH(4) ;DELETE OFN SOS NOF RET SWPI1: HLRZ 6,4 CALL SETSPG ;MAP PT MOVE 2,CST0(6) ; GET PUB TLO 2,(CORMB) ; BE SURE CORMB IS SET DPB 5,[POINT 22,CSWPGA(4),35] ;STORE BACKUP ADDRESS MOVEM 2,CST0(6) ; RESTORE PUB MOVSI 2,-PLKV ADDB 2,CST1(6) ;DECREMENT LOCK COUNT CALL RELSPG ;RELEASE TEMPORARY MAP WORD RET SETSPG: PUSH P,1 MOVE 1,SPT(6) ;GET ADDRESS TDNE 1,[XWD 17,-MAXCOR] BUG(HLT,) HLL 1,CST0(1) ;CHECK AGE TLNN 1,(7B2) ;NOW ASSIGNED? CALL AGESN ;NO, SET AGE LSH 6,^D9 ;MAKE SHARE POINTER FROM OFN IN 6 TLO 6,RWXB-XCTB+SHRBIT MOVEM 6,MMAP+CSWPG ;PUT IN PAGE RESERVED FOR SWAPPER MOVEI 6,0(1) ;RETURN CORE ADR POP P,1 RET RELSPG: SETZM MMAP+CSWPG ;CLEAR MAP WORD MONCLR CSWPG ;CLEAR MON AR'S RET ;ZERO CORE PAGE GIVEN IN 1 SWPZPG: MOVEI 2,0(1) TLO 2,RWXB ;CONSTRUCT PRIVATE POINTER TO PAGE MOVEM 2,MMAP+CSWPG ;PUT IN MON MAP MOVSI 3,400000 ;GET LEGAL AGE EXCH 3,CST0(1) ;SAVE OLD AGE MOVE 2,[XWD CSWPGA,CSWPGA+1] SETZM -1(2) BLT 2,CSWPGA+777 ;ZERO THE PAGE TLO 3,(CORMB) ;NOTE PAGE WRITTEN INTO MOVEM 3,CST0(1) ;RESTORE AGE JRST RELSPG ;CLEAR PAGE FROM MMAP AND RETURN ;SCHEDULER TEST FOR PSB AND PT READ COMPLETED SWPINT: MOVE 3,4 ;SAVE RETURN HRRZ 1,FKPGS(7) ;PSB MOVE 1,SPT(1) ;ASSIGNED PAGE JSP 4,PTRT ;DONE? JRST 0(3) ;NO, RETURN NOT RUNNABLE CALL SETMAP ;SET AGE AND MAP PSB IF NECESSARY SKIPN INDFLG ;LOCKING PSB'S? JRST SWPIT1 ;NO HRRZ 1,FKJOB(7) ;YES, GET SPT MOVE 1,SPT(1) ;CORE ADDRESS JSP 4,PTRT ;CHECK IT JRST 0(3) ;NOT READY CALL AGESN SWPIT1: HLRZ 1,FKPGS(7) ;PT MOVE 1,SPT(1) JSP 4,PTRT ;PT READY? JRST 0(3) ;NO CALL AGESN JRST 1(3) ;SCHEDULER TEST FOR READ COMPLETED DSKRT: JFCL ;SAME AS SWPRT SWPRT: MOVE 2,CST0(1) ;PAGE STATE CODE SWPRT2: TLC 2,(06B5) ;COMPARE WITH READ-IN-PROG CODE TLNN 2,(77B5) JRST 0(4) ;READ STILL IN PROG JRST 1(4) ;TEST FOR PAGE TABLE ARRIVAL PTRT: MOVE 2,CST0(1) TLNE 2,700000 ;AGE GE 100? JRST 2(4) ;YES JRST SWPRT2 ;NO, SEE IF READ COMPLETED ;SET AGE AND SET PSB MAP ENTRY IF NEW FORK SETMAP: CALL AGESN ;SET AGE MOVSI 4,NEWFKF## ;NEW FORK? TDNN 4,FKINT##(7) RET ;NO HRRZ 4,FKPGS(7) LSH 4,^D9 TLO 4,RWXB+SHRBIT ;MAKE SHARE POINTER TO PSB MOVEM 4,MMAP+FITPG ;PUT IN PPR MAP MONCLR FITPG MOVEM 4,FITPGA+PSBPG ;IN PSB RET ;SWAP COMPLETION ROUTINE, CALLED FROM DRUM AND DISK INTERRUPT CODE SWPDON: MOVSI 2,DWRBIT ;WRITE BIT TDNE 2,CST3(1) ;WAS WRITE? JRST SWPD1 ;YES ;IF RESCHEDULING DESIRED ON PAGE ARRIVAL, INCLUDE THE FOLLOWING: ; AOS PSKED ; ISB SCDCHN MOVSI 2,4B23 SWPD2: ANDCAM 2,CST0(1) ;CLEAR I/O IN PROGRESS JRST 0(4) SWPD1: ANDCAM 2,CST3(1) ;CLEAR WRITE BIT LDB 2,[POINT 6,CST0(1),5] ;GET TRAP CODE CAIE 2,4 ;STILL SAYS WRITE? JRST [ SKIPE CST2(1) ;NO, PAGE USED AGAIN. STILL EXISTS? JRST 0(4) ;YES JRST ONRQ] ;IT WAS DELETED, PUT ON RPLQ SOS IOIP ;WRITE NO LONGER IN PROGRESS MOVE 2,CST1(1) ;IF WRITE WAS TO DISK, AND PAGE HLR 2,CST2(1) ;IS STILL IN SPT TLNE 2,10 TRNE 2,-1 JRST ONRQ MOVEI 2,7777 ;FAKE A REFERENCE IN ORDER TO HRLZM 2,CST3(1) ;KEEP THE PAGE ON THE DRUM DPB 2,[POINT 9,CST0(1),8] JRST 0(4) ONRQ: MOVEI 2,CST3(1) ;YES, PUT ON REPLACABLE QUEUE PIOFF HLRZ 3,RPLQ ;NOTE: THERE IS A "COPY" OF THIS HRL 3,0(3) ;CODE IN-LINE IN MAKPGA. IF ANY HRRM 2,0(3) ;CHANGE IS MADE HERE, BE SURE TO MOVSM 3,0(2) ;CHECK TO SEE IF THE SAME CHANGE IS HRLM 2,RPLQ ;APPROPRIATE IN MAKPGA ALSO. PION AOS NRPLQ SOS SUMNRX SOS PNDING MOVSI 2,77B23 JRST SWPD2 ;SWAP OUT PAGE REQUESTED BY PROCESS SWPOT0: TLNE 1,17 ;IN CORE? RET ;NO PUSH P,2 PUSH P,7 MOVE 7,FORKX MOVE 2,CST0(1) TLNN 2,(7B2) ;IN USE? JRST SWPOT1 ;NO HLRZ 2,CST3(1) ;ASSIGNMENT ANDI 2,7777 CAIE 2,0(7) ;ASSIGNED HERE? JRST SWPOT1 ;NO SOS FKWSP(2) SOS FKNR(2) AOS PNDING MOVSI 2,7777 IORM 2,CST3(1) ;DEASSIGN IT MOVE 2,CST1(1) TLNE 2,-PLKV ;LOCKED? JRST SWPOT1 ;YES, DONT TRY TO SWAP MOVSI 2,DWRBIT TDNE 2,CST3(1) ;BEING WRITTEN? JRST SWPOT1 ;YES PUSH P,3 PUSH P,4 PUSH P,5 CALL SWPOUT POP P,5 POP P,4 POP P,3 SWPOT1: POP P,7 POP P,2 RET ;INITIATE SWAP OF PAGE ;CALLED IN SCHEDULER FROM GCCOR SWPOUT: SKIPN 2,CST2(1) ;GET BACKUP JRST BKUPN ;PAGE HAS NO BACKUP, FLUSH IT TLNE 2,-1 ;SPT? JRST SWPU1 ;NO MOVE 3,SPT(2) TLNN 3,-1B31 ;SHARE COUNT 0? JRST BKUPD ;YES, SWAP TO DISK CAIL 2,NOFN ;OFN? JRST BKUPS ;NO, SHARED PAGE. GO CHECK REQUEST BIT MOVE 2,CST1(1) ;YES, CHECK BACKUP ADDRESS TLNN 2,10 ;DISK? JRST BKUP0 ;NO, DRUM ADR ALREADY ASSIGNED SKIPL DRUMP ;YES, MUST ENSURE SWAP TO DRUM SKIPG DRMFRE JRST SWPO3 ;OR LEAVE IN CORE IF CAN'T JRST SWOFN ;GO ASN DRM ADR, EVEN IF DRM SPC LOW BKUP0: MOVE 2,CST1(1) ;CORE PAGE NUMBER IN 1, GET BACKUP ADR TLNE 2,16 TLNE 2,10 ;DISK OR NOTHING? JRST SWPO4 ;YES TLZE 2,1 ;NEWLY ASSIGNED DRUM ADDRESS? (POSTPG) JRST [ MOVEM 2,CST1(1) ;YES, REMOVE NEW BIT JRST SWPP1] ;AND WRITE OUT PAGE MOVE 3,CST0(1) ;NO, DRUM. TLNE 3,(CORMB) ;PAGE WRITTEN INTO? JRST SWPO1 ;YES SWPOQ: TLNE 3,77B23 ;PAGE NOW ON REPLACABLE QUEUE? JSP 4,ONRQ ;NO, PUT IT THERE SWPO3: RET SWPU1: HLRZ 2,2 ;GET PTN CAIGE 2,NOFN ;FILE? JRST BKUPD ;YES, SWAP TO DISK BKUPS: MOVE 2,CST3(1) TLNE 2,DSKSWB ;SWAP TO DISK REQUESTED? JRST BKUPDR ;YES JRST BKUP0 ;PROCESS, SWAP TO DRUM SWPO1: CALL GDSTX SWPO5: MOVSI 3,BWRBIT ;SET BACKUP WRITTEN BIT IORM 3,DST(2) SWPO2: MOVSI 3,(CORMB) ANDCAM 3,CST0(1) ;CLEAR WRITTEN BIT MOVEI 3,4 DPB 3,[POINT 6,CST0(1),5] ;SET TRAP CODE TO WRITE IN PROG. AOS IOIP ;NOTE WRITE IN PROGRESS HRLI 1,DWRBIT ;WRITE REQUEST BIT CALL DRMIO ;INITIATE DRUM WRITE AOS DRMWR ;COUNT DRUM WRITES FOR STATISTICS JRST SWPO3 SWPO4: MOVSI 3,SWPERR TDNE 3,CST3(1) ;ERROR READING FROM DISK? JRST BKUPN ;YES, DON'T WRITE IT MOVE 3,DRMFRE SKIPLE DISKP ;IF NO DISK, DON'T MAKE ADD'L SWAP ADRS CAMGE 3,DRMIN2 ;DRUM NEARLY FULL? TLNN 2,10 ;YES, SEND TO DISK IF HAVE DISK ADDRESS SKIPGE DRUMP ;SWAPPING POSSIBLE? JRST [ TLNE 2,10 ;NO, DID WE HAVE A DISK ADDRESS? JRST BKUPD ;YES, SEND TO DISK (WHATEVER IT IS) JRST SWPO3] ;NO PLACE TO PUT PAGE, LEAVE IT IN CORE SWOFN: PUSH P,1 SETO 1, ;FREE CHOICE ASSMT CALL DRMASN ;ASSIGN DRUM ADDRESS BUG(HLT,) MOVE 2,1 POP P,1 MOVE 4,CST1(1) ;GET PREVIOUS BACKUP ADDRESS MOVEM 2,CST1(1) ;SET DRUM AS NEW BACKUP ADDRESS CALL GDSTX MOVEM 4,DST(2) ;PREVIOUS BACKUP ADDRESS TO DST SWPP1: MOVE 3,CST0(1) TLNE 3,(CORMB) ;PAGE WRITTEN WHILE IN CORE? JRST SWPO5 ;YES, SET BACKUP WRITTEN BIT ALSO JRST SWPO2 ;NO ;SWAP PAGE TO DISK BKUPD: MOVSI 2,DSKSWB ANDCAM 2,CST3(1) ;FLUSH REQUEST BIT IF ANY BKUPDR: MOVE 2,CST1(1) ;GET BACKUP ADDRESS TLNN 2,16 ;NONE? JRST BKUP7 ;YES TLNE 2,10 ;DISK? JRST BKUP3 ;YES CALL GDSTX ;DRUM MOVE 3,DST(2) ;GET NEXT LEVEL BACKUP ADDRESS MOVSI 4,(CORMB) TLZE 3,BWRBIT ;WRITTEN SINCE BACKUP? IORM 4,CST0(1) ;YES, SET CORE WRITTEN BIT SETOM DST(2) ;RELEASE DST SLOT EXCH 3,CST1(1) PUSH P,1 MOVE 1,3 CALL DASDRM ;DEASSIGN DRUM ADDRESS POP P,1 JRST BKUPDR BKUP7: BUG(HLT,) BKUP3: MOVSI 3,(CORMB) ;CLEAR CHANGED IN CORE BIT MOVSI 2,SWPERR TDNN 2,CST3(1) ;DON'T WRITE IF ERROR FROM READ TDNN 3,CST0(1) ;CHANGED? JRST BKUPN ;NO, DON'T HAVE TO WRITE ANDCAM 3,CST0(1) HRLI 1,DWRBIT ;REQUEST WRITE AOS DSKWR ;COUNT IT FOR STATISTICS AOS IOIP ;NOTE WRITE IN PROGRESS MOVSI 3,NEWFB ANDCAM 3,CST1(1) ;MAKE SURE NO NEWFB STILL AROUND MOVEI 3,4 ;INDICATE WRITE IN PROGRESS DPB 3,[POINT 6,CST0(1),5] CALL DSKIO JRST SWPO3 BKUPN: MOVE 3,CST0(1) JRST SWPOQ ;GO PUT PAGE IN QUEUE ; PUT PAGES IN AVAILABLE POOL OF SWAPPING PAGES ; CALL: 1/ FIRST PAGE TO PUT IN ; 2/ LAST PAGE TO PUT IN ; CALL MAKPGA ; RETURNS +1 ALWAYS ; ARGUMENTS ARE FORCED INTO PROPER RANGE MAKPGA: CALL CHKPGA ; CHECK PAGE ARGUMENTS PUSH P,2 ; SAVE AC'S PUSH P,3 PUSH P,4 CONI PI,2 ; GET CURRENT STATE OF PI PUSH P,2 ; AND SAVE IT PIOFF ; PREVENT CHAOS MKPGAL: LDB 2,[POINT 6,CST0(1),5] ; GET STATE OF THE PAGE CAIE 2,01 ; IS IT UN AVAILABLE? JRST MAKPGX ; NO, NOTHING TO DO SETOM CST0(1) ; SET AGE > 77 SETZM CST1(1) ; CLEAR CST WORDS SETZM CST2(1) SETZM CST3(1) MOVE 2,1 HRLI 2,RWXB MOVEM 2,MMAP+CSWPG ; SET POINTER TO THE PAGE PGRCLD ; RELOAD PAGER SKIP CSWPGA ; REFERENCE THE PAGE MOVSI 2,010000 MOVEM 2,CST0(1) ; SET AGE BACK TO UNAVAIL IN CASE NXM CONSZ APR,APNXM ; EXISTS? JRST MAKPGX ; NO CAMGE 1,SWPCOR MOVEM 1,SWPCOR ; KEEP MIN AVAILABLE AS SWPCOR CAML 1,NHIPG ;NEWLY AVAILABLE? MOVEM 1,NHIPG ;YES. UPDATE LENGTH OF SCANS SETZM CST0(1) MOVEI 2,CST3(1) ;WE WILL NOW PUT ON REPLACEABLE QUEUE HLRZ 3,RPLQ ;NOTE: THIS CODE IS A "COPY" OF THE HRL 3,0(3) ;CODE IN THE ROUTINE "ONRQ". IF ANY HRRM 2,0(3) ;CHANGE IS MADE HERE, BE SURE TO MOVSM 3,0(2) ;CHECK TO SEE IF THE CHANGE IS HRLM 2,RPLQ ;APPROPRIATE IN THE "ONRQ" ROUTINE ALSO. AOS NRPLQ AOS TOTRC ;UPDATE COUNT OF AVAILABLE CORE PAGES AOS MAXNRX MAKPGX: CONO APR,APNXM+APRCHN ; CLEAR NXM FLAG CAMGE 1,-3(P) ; REACHED END YET? AOJA 1,MKPGAL ; NO DO NEXT ONE SETZM MMAP+CSWPG ; CLEAR MAP ENTRY PGRCLD CALL FIXRC ; RECOMPUTE VARIABLES DEPENDENT ON TOTRC POP P,2 ; GET FORMER STATE OF PI TRNE 2,200 ; WAS IT ON? PION ; YES, TURN IT BACK ON POP P,4 ;RESTORE REGISTERS POP P,3 POP P,2 RET CHKPGA: CAMGE 2,1 ; CHECK THAT SECOND ARG IS .GE. FIRST EXCH 1,2 ; IF NOT, REVERSE CAIL 2,MAXCOR ; LIMIT TO TABLE SIZES MOVEI 2,MAXCOR-1 CAMGE 1,MONCOR ; AND NEVER INTO RES MON MOVE 1,MONCOR CAMGE 2,1 ; BE SURE ARGS STILL OK JRST CHKPGA RET ;REMOVE A SET OF PAGES FROM THE SWAPPABLE STORE ;ACCEPTS IN 1: PAGE NUMBER OF FIRST PAGE TO BE REMOVED ; 2: PAGE NUMBER OF LAST PAGE TO BE REMOVED ; CALL MAKPGU ; RETURNS ; +1 ; SOME PAGES LOCKED, RH(1) #LOCKED, LH(1) ONE OF THEM ; +2 ; SUCCESS MAKPGU: CALL CHKPGA ; CHECK ARGUMENTS SUBI 2,-1(1) ; NUMBER OF PAGES MOVNS 2 HRL 1,2 SETZM PGELCT ; NO LOCKED PAGES FOUND YET MOVEM 1,FSHBAL ; CAUSE SCHEDULER TO FLUSH BALSET ETC. MOVEI 1,FSHBAL CALL DISGE ; WAIT FOR PAGES TO BE FLUSHED SKIPN 1,PGELCT ; ANY LOCKED PAGES FOUND AOS 0(P) ; NO, SUCCESS RETURN RET ; FLUSH ALL PAGES FROM CORE (USED FOR TAKING PAGES OUT OF CIRCULATION) GCALC: PUSH P,NRPLQ ; SAVE CURRENT VALUE OF NRPLQ CALL GCCOR0 ; DEPG AS MUCH AS POSSIBLE THEN GC POP P,1 SKIPN IOIP CAME 1,NRPLQ JRST GCALC ; LOOP UNTIL NO CHANGE IN NRPLQ AND NO IOIP CALL GCCOR0 ; ONCE MORE FOR LUCK MOVE 3,FSHBAL ; GET AOBJN POINTER TO PAGES TO FLUSH JUMPG 3,GCALX ;DON'T RELEASE CORE GCFSH: LDB 1,[POINT 6,CST0(3),5] JUMPN 1,[ ; NOT ON REPLACEABLE QUEUE CAIN 1,01 ; ALREADY UNAVAILABLE? JRST GCEFSH ; YES, OK SKIPN PGELCT ; NO, MUST BE LOCKED. FIRST LOCKED PAGE? HRLM 3,PGELCT ; YES, SAVE PAGE NUMBER AOS PGELCT JRST GCEFSH] MOVE 4,CST3(3) ; TAKE OFF RPLQ HLLM 4,0(4) MOVSS 4 HLRM 4,0(4) SOS NRPLQ ; ACCOUNT FOR THIS STOLEN PAGE SOS TOTRC ; ADJUST REAL CORE COUNT SOS MAXNRX ; AND MAXNRX SETZM CST1(3) ; CLEAR CST SETZM CST2(3) SETZM CST3(3) MOVSI 4,(1B5) MOVEM 4,CST0(3) HRRZ 1,3 CAMN 1,NHIPG ;FLUSHING TOP PAGE? JRST [ SOS 1,NHIPG ;YES, STEP TOP DOWN ONE LDB 1,[POINT 6,CST0(1),5] CAIE 1,01 ;AVAILABLE? JRST GCEFSH ;NO, QUIT JRST .] ;YES. TRY AGAIN CAMN 1,SWPCOR ; EQUAL TO SWPCOR? JRST [ AOS 1,SWPCOR ; YES, BUMP SWPCOR LDB 1,[POINT 6,CST0(1),5] CAIN 1,01 ; NEXT ONE UNAVAILABLE? JRST . ; YES, BUMP AGAIN JRST .+1] ; ELSE CONTINUE GCEFSH: AOBJN 3,GCFSH CALL FIXRC ; FIX VARIABLES DEPENDENT ON TOTRC ;RESET ALL FKNR TO AVOID LOCKUP DUE TO POSSIBILITY OF FKNR .GT. MAXNRX MOVSI 3,-NFKS GCEFLP: HRRZ 4,FKWSP(3) ; GET CURRENT NO. OF PAGES (SHOULD BE 0) SKIPN 4 ; UNLESS HE'S GOT SOME LOCKED MOVEI 4,6 ; TWAS ZERO, MAKE IT 6 HRRM 4,FKNR(3) AOBJN 3,GCEFLP ; GO 'ROUND AGAIN SETOM OLDSUM## ; MAKE SURE WE SCAN FOR LOADABLE PROCS GCALX: SETZM FSHBAL ;SAY FLUSH IS COMPLETED RET ; FIX RC VARIABLES FIXRC: PUSH P,1 ;SETUP VARIOUS CONSTANTS FOR CORE MGT MOVE 1,TOTRC SUB 1,NRPMX MOVEM 1,MAXNRX ;MAX VALUE OF SUMNRX SUBI 1,10 MOVEM 1,NPMAX CAIL 1,140 ;REASONABLY LARGE SYSTEM? SUBI 1,40 ;YES, SET SNPMAX 16K SMALLER MOVEM 1,SNPMAX ;SMALL NPMAX SUB 1,NPMAX ;DIFFERENCE OF NPMAX AND SNPMAX MOVMM 1,SJSIZ ;FOR 'SMALL' JOB SIZE MOVE 1,TOTRC SUBI 1,20 ;20 IS ARB. LEAVE A LITTLE ROOM FOR SYS. MOVEM 1,MAXLOK ;IS MAX NUMBER PAGES TO LOCK POP P,1 RET ;LOCK, UNLOCK PAGE ON REQUEST (FOR DTA IO, ETC.) MLKMA: TLNN 1,(1B0) ;LOCK PAGE GIVEN ADDRESS. USER? SKIPA 0(1) ;NO, MON. REF PAGE TO ENSURE EXISTS XCTUU [SKIP 0(1)] CALL FPTA ;TRANSLATE ADDRESS TO OFN.PN MLKPG: PUSH P,2 PUSH P,1 MLKPG0: CALL GETONT ;GET PTN.PN OR OWNING PT TLNN 2,17 ;PAGE NOW IN CORE? JRST MLKPG1 ;YES. TLNN 2,16 ;NO, EXISTS? JRST MLKPG2 ;NO CALL SWPINP ;INITIATE SWAP AND WAIT FOR COMPL. OKSKED MOVE 1,0(P) JRST MLKPG0 ;TRY AGAIN MLKPG2: OKSKED ;MUST REF PAGE TO CREATE IT TLNE 2,-1 ;IN SPT? BUG(HLT,) CALL SETCPT SKIP CPTPGA CALL RELCPT MOVE 1,0(P) JRST MLKPG0 MLKPG1: POP P,1 ; FLUSH SAVED AC1 MOVE 1,CST1(2) TLNN 1,-PLKV ;PAGE LOCKED NOW? AOS LOKPGS ;NO, COUNT IT IFN KIFLG,< AOS KIMLKF> MOVSI 1,PLKV ADDM 1,CST1(2) ;INCREMENT LOCK COUNT AOS LOKSUM MOVEI 1,0(2) CALL AGESET ;SET AGE MONCLR 0 POP P,2 JRST SKORET ;OKSKED AND RETURN MULKPG: PUSH P,1 PUSH P,2 CALL GETONT ;GET OWNING PT TLNE 2,17 ;PAGE NOW IN CORE? BUG(HLT,) CALL MULK1 POP P,2 POP P,1 JRST SKORET MULK1: MOVSI 1,-PLKV TDNN 1,CST1(2) ;LOCK COUNT NON-ZERO? BUG(HLT,) ADDB 1,CST1(2) ;DECREMENT LOCK COUNT TLNE 1,-PLKV ;NOW UNLOCKED? JRST MULK2 ;NO SOS LOKPGS IFN KIFLG,< AOS KIMLKF> ;FLAG THAT LOCKING HAS CHANGED SKIPE CST2(2) ;STILL EXISTS? JRST MULK2 ;YES PUSH P,4 ;NO, HAS BEEN DELETED MOVEI 1,0(2) JSP 4,ONRQ ;PUT ON REPLACABLE QUEUE POP P,4 MULK2: SOS LOKSUM RET ;UNLOCK PAGE GIVEN MONITOR ADDRESS ;ASSUMED NOSKED OR INSKED MULKMP: MOVEI 1,0(1) LSH 1,-^D9 CAIL 1,PPRMPG+NRSPG CAIL 1,PPMPG BUG(HLT,) MOVE 1,MMAP(1) ;GET CORE ADDRESS TLZ 1,-1B31 ;FLUSH POINTER BITS JRST MULKCR ;UNLOCK PAGE GIVEN CORE PAGE NUMBER IN 1 MULKCR: CAML 1,SWPCOR ;LEGAL? CAIL 1,MAXCOR BUG(HLT,) PUSH P,2 MOVEI 2,0(1) CALL MULK1 POP P,2 RET END ;END OF PAGEM.MAC