;DSK:PAGEM.PEF;19 8-Jul-80 20:47:15, Edit by FRENCH ;FIX CLEARING OF XBBAT AT ASCHK1 ;DSK:PAGEM.PEF;16 8-Jul-80 14:33:32, Edit by FRENCH ;MINOR BUG FIXES IN SWPFIX (TYPOS) ;DSK:PAGEM.PEF;9 2-Jul-80 12:23:30, Edit by FRENCH ;ASOFN RETURNS OPNX24 ON SCANNING READ OF XB IF ITS A BAD SPOT (SWAP ERROR) ;DSK:PAGEM.PEF;7 1-Jul-80 14:23:15, Edit by FRENCH ;FIX TEST OF FROM DISK OR DRUM IN SWPFIX ;DSK:PAGEM.PEF;6 25-Jun-80 16:54:08, Edit by FRENCH ;FOR SWAP READ ERROR: IF CORE BACKUP DIFF FROM DRUM BACKUP (BWRBIT), ;MAKE DRUM BACKUP THE CORE BACKUP ANYWAY BUT ISSUE INT INSTEAD OF REDOING IO. ;DSK:PAGEM.MAC;29 24-Jun-80 18:20:24, Edit by FRENCH ;MUCH SMARTNESS FOR DRUM SWAP IN ERRORS - POSSIBLE WINNING RETRIES ;ALLOW FREE CHOICE FOR DRMASN AT SWOFN (BUG: WAS USING CPN) ;DSK:PAGEM.MAC;19 24-Jun-80 12:57:53, Edit by FRENCH ;ADDED DRUM ADR SWITCHING ON SWAP ERRORS FOR BAT LOGIC ;ADD FLAG PASSING TO REMFPG FOR NON-RELEASE OF BAD FILE PAGES ;REMFPG WILL NOT DEASSIGN DISK ADRS IF HANDED OFNBAT FLAG IN AC2 ;XFER BAT BIT FROM XB TO SPTH FOR OFN BEFORE ASCHK1 ;XFER BAT BIT FROM SPTH TO COPY OF XB TO BE DUMPED AT DDMPXB ;DSK:PAGEM.MAC;3 20-Jun-80 16:51:08, Edit by FRENCH ;ADDED SWPFIX TO HANDLE SWAPPING ERRORS ;DSK:<134-TENEX>PAGEM.MAC;267 18-May-80 21:32:51, Edit by PETERS ; Removed TOPS20 AC definitions which are now in PROLOG ;<134-TENEX>PAGEM.MAC;266 27-Jan-80 17:45:09 EDIT BY PETERS ; Fix KAFLG to be KAFLG!F3FLG ;<134-TENEX>PAGEM.MAC;265 19-Nov-79 16:16:31 EDIT BY PETERS ;Add support for sysmem getab to make memory configuration available ;<134-TENEX>PAGEM.MAC;264 16-Sep-79 18:46:04 EDIT BY PETERS ;added isi, ki, and tymshare changes ;[SRI-KA]<134-TENEX>PAGEM.OLD;29, 11-Jun-79 09:30:43, EDIT BY LYNCH ; TOOK OUT OKSKED/NOSKED BUG IN ASOFN. ;<134-TENEX>PAGEM.MAC;28 31-Dec-77 22:30:06 EDIT BY LYNCH ; DID CLEANUP AND PUT IN CALL TO AGESET IN RELOFN ;<134-TENEX>PAGEM.DCL;27 19-Dec-77 04:10:00 TVEDIT BY HEATHMAN ;1 Edit #1 - Fix DDMP4+7 to keep 160041,,0 pointers out of file system ;<134-TENEX>PAGEM.DCL;26 16-Dec-77 19:57:10 EDIT BY LYNCH ; REFINE NGCC TO KICK OUT NON BALSET PAGES ON TAIL OF CURVE ;<134-TENEX>PAGEM.DCL;25 9-Dec-77 23:01:15 EDIT BY SYSTEM ; ADD ANOTHER CHECK AT NIC8 FOR RPLQ DEPLETION ;<134-TENEX>PAGEM.MAC;24 18-Nov-77 21:22:37 EDIT BY LYNCH ; FIXED UGLY BUG IN NIC CODE -- FORGOT TO GO NOSKED! ;<134-TENEX>PAGEM.DCL;23 16-Nov-77 19:19:49 EDIT BY LYNCH ; FIXED BUG IN NGCC START POINT AT SWPCOR IN GCEFSH CODE. ;<134-TENEX>PAGEM.DCL;22 14-Nov-77 08:47:11 EDIT BY LYNCH ; FIXED THE "EVERYBODY OUT OF THE POOL" LOGIC. ; A COMMENT IN THE MAKPGU ROUTINE ABOUT ONCE MORE FOR LUCK ; IS VERY, VERY DECEPTIVE!!! ;<134-TENEX>PAGEM.DCL;20 13-Nov-77 12:03:16 EDIT BY LYNCH ; FIXED BUG IN AGE CODE INTERPRETATION BETWEEN KA AND KL ; FOR THE NGCC CODE! ;<134-TENEX>PAGEM.MAC;19 10-Oct-77 16:20:42 EDIT BY LYNCH ; PUT IN NEW GARBAGE COLLECTOR CODE (NGCC) ;<134-TENEX>PAGEM.MAC;10 21-Dec-76 15:48:36 EDIT BY LYNCH ; PUT BACK IN THE 5 MS QUANTUM DECREMENT AT PGIWT. ; THE EFFECT OF THIS IS TO PULL OFF PAGE GOBBLERS FROM ; THE INTERACTIVE QUEUE QUICKLY. ;<134-TENEX>PAGEM.MAC;9 1-JUL-76 21:20:28 EDIT BY UNTULIS ;ADDED JSYS TO FIND DRUM PAGES PER FORK (.GPGC - GET PAGE COUNT) ;<134-TENEX>PAGEM.MAC;8 21-APR-76 13:38:16 EDIT BY LYNCH ; TOOK OUT FKIFAV SAVING. OBSOLETE ;<134-TENEX>PAGEM.MAC;7 5-APR-76 14:40:09 EDIT BY UNTULIS ;ADD ISI SECURITY HOLE PLUG ;<134-TENEX>PAGEM.MAC;2 17-FEB-76 15:52:48 EDIT BY UNTULIS ;ADDED RECLAIM DRUM CODE ;<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 ;<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,.RWSET INTERN SWPINT INTERN SWPDON,DWRBIT,SWPERR INTERN DSKRT,GCALC,PGRRST,PGRTRP,SWPIN0,ASSPT,DESPT INTERN SWPRT,SETPPG,SWPRST,PGRINI INTERN MKSHRP,SETDVP ;LINKAGE TO PISRV AND SCHED EXTERN BHC,BITS,BLOCK1,BUGCHK,BUGHLT,DEVMPE,PSISV2 EXTERN DISGE,DISLT,DRMRD,DRMWR,DSKRD,DSKWR,ETIME,FKJOB EXTERN BKGFLG,EDISMS,DISL EXTERN FKPGS,FKPT,FKWSP,FORKX,FSHBAL,ILIST EXTERN INSKED,ISKED,ITRAP,JOBNAM,LSTERR,MENTR EXTERN MRETN,MSTKOV,NPMAX,NRPLQ,NRPMIN,JOBRTT EXTERN PATCH2,PSIRQ,PSIRQ0,PSKED,R,RJQNT,RPLQ,RSKP,TOPTRP EXTERN SCHEDP,SCHEDR,SJSIZ,GCCR,SPFLTS,PTRAP,STIME EXTERN TODCLK,TOTRC,WTLST,WTSPT,WTSPTT EXTERN FKFLGS,BLST EXTERN SNSOFN extern bugmsg,bugtyo,jobpgf IFN KIFLG,< ;[ISI] Possible linkage to KISRV EXTERN KILUPT EXTERN KIMAC1,KIMAC2,KIMLKF,KIPGWD,KIRFLG,KXUPT > ; 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,OPNX24 ;PARAMETERS DISKP: 1 ;DISK ON SYSTEM DRUMP: IFDEF DRMCHN,<1> ;1 = DRUM AVAIL, IFNDEF DRMCHN,<0> ;0 = USE DISK, -1 = USE NOTHING ; FOLLOWING USED TO CONTROL NGCC CORE GARBAGE COLLECTOR LS FKPAGE,NFKS ; CUTOFF AGE FOR NGCC LS GCBALB ; BALSET BIAS FOR THROWING OUT PAGES LS GCPN ; ROVING POINTER TO LAST PAGE LOOKED AT LS GCMOD ; SCALE FOR CHKRPQ TEST LS AGEGLB ; GLOBAL AGE COUNTER LS GCSTRT ; FIRE UP NGCC WHEN NRPLQ FALLS BELOW THIS LS GCDIFF ; COLLECT AT LEAST THIS MANY PAGES FOR RPLQ 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 NXTDMP,1 ;FLAG TO CAUSE DDMP ACTION GS DDTIME,1 ;TIME NEXT DDMP DUE ls ddmpct,1 ;flag to aid asofai in recognizing ddmp finish 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 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 ; MOVEI 1,<3*NDST>/^D16 ;GET 3/16 OF DRUM SPACE MOVEI 1,3200 ;ASSIGN PRIVATE PAGES TO DISK BELOW THIS *** SRI-AIC *** MOVEM 1,DRMIN2 ;NO NEW DRUM ASSIGNMENTS BELOW THIS MOVEI 1,3200 ;DRUM BARRIER *** SRI-AIC *** MOVEM 1,DRMIN1 ;DEASSIGN PAGES TRICKLED TO DISK ;IF DRMFRE FALLS BELOW THIS MOVEI 1,100 MOVEM 1,AGEGLB DPB 1,[POINT 9,PGR72,8] ; INIT AGE FIELD MOVEI 1,^D25 ; PICK START POINT FOR NGCC MOVEM 1,GCSTRT MOVEI 1,^D10 ; AND NUMBER OF PAGES TO COLLECT EACH TIME MOVEM 1,GCDIFF MOVEI 1,^D600 ; MAX PAGES A FORK COULD EVER HAVE IDIV 1,GCSTRT MOVEM 1,GCMOD ; SCALE FOR CHKRPQ TEST MOVE 1,SWPCOR ; INIT ROBING POINTER FOR NGCC MOVEM 1,GCPN SETZM PGR71 CALL PGRRST MOVE 1,SWPCOR ifn kiflg,< addi 1,nupt ;reserve for ki upts > 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 movei 1,[sixbit '$pgrini: /'] ;tell oper how much core we have jsr bugmsg ;type it move 1,totrc ;"user" core add 1,swpcor ;plus monitor gives total pages ifn kiflg,< addi 1,nupt ;account for upts if ki > hrli 1,maxcor ;put configuration maximum in left halt movsm 1,sysmem## ;leave for getab as online,,maximum hrrzs 1 ;now clear left half before divide idivi 1,2 ;convert from pages to k idivi 1,^d1000 ;get thousands digit addi 1,"0" ;make an ascii character caie 1,"0" ;skip if thousands not needed jsr bugtyo ;type it idivi 2,^d100 ;get hundreds movei 1,"0"(2) ;fetch hundreds and make ascii char jsr bugtyo ;type it idivi 3,^d10 ;get tens and ones digits movei 1,"0"(3) ;get tens and make ascii char jsr bugtyo ;type it movei 1,"0"(4) ;get ones and make ascii char jsr bugtyo ;type it movei 1,[sixbit 'k physical core online$/'] jsr bugmsg ;type rest of message 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 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 setom 0(p) ;unassigned, force xb write 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: MOVSI 1,OFNBAT ;THE SPTH BAT BIT MOVSI 2,XBBAT ;THE XB BAT BIT TDNE 1,SPTH(10) ;THIS XB BAD? IORM 2,DDPG2A+XBBWRD ;YES-TURN ON BIT IN BAT WORD IN COPY XB 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 AOS DDMPCT ;[ISI] 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) ;note: opnx24 error can only be returned for non-new xb's since ;swpin does not do a disk read for brand new pages. ;therfore, caller need not handle opnx24 if b3 set for new xb in call args ASOFN: TLNN 1,10 ;DISK? RET ;NO, RETURN BAD PUSH P,7 ;[ISI] Protect AC7 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 MOVE 1,CXBPGA ;GET XB IN CORE MOVE 1,SPT(3) ;CORE ADDRESS MOVSI 2,SWPERR TDNE 2,CST3(1) ;DISK ERROR IN XB? (impssbl if brand new xb) JRST ASCHK4 ;YES, DON'T OPEN, return bad spot error MOVSI 1,XBBAT ;THE XB BAT BIT MOVSI 2,OFNBAT ;THE SPTH BAT BIT TDNE 1,CXBPGA+XBBWRD ;ON IN XB? IORM 2,SPTH(3) ;YES-REMEMBER IT FOR OFN TDNE 1,CXBPGA+XBBWRD ;ON IN XB? DON'T CHANGE IT UNNECESSARILY ANDCAM 1,CXBPGA+XBBWRD ;CLEAR IT FROM XB MOVSI 1,-1000 ;SETUP TO SCAN XB ASCHK1: MOVE 2,CXBPGA(1) ;GET WORD FROM XB (XBBAT ALREADY CLEARED OUT) JUMPE 2,ASCHK2 ;NOT IN USE ANDCM 2,[RWX,,-1] ;[ISI] Ignore RWX bits and low addr bits TLC 2,ACCESB+01 ;[ISI] Flip access & non-exist bits (to zero) TLNE 2,10 ;[ISI] If disk addr, TLZ 2,17 ;[ISI] zero all addr bits JUMPN 2,ASCHK3 ;[ISI] Any one bits are bad, don't open ASCHK2: AOBJN 1,ASCHK1 CALL RELCXB ;OK, RELEASE XB, IT IS CLEAN FOR MAP USE JRST ASOF9 ;IF THERE WAS A SWAP ERROR (SWPERR IN CST3) FOR THE XB, DON'T SET ;XBBAT IN XBBWRD SINCE DON'T WANT TO WRITE BACK OVER THE XB. ;INSTEAD RETURN OPNX24 TO CALLER SO CALLER CAN MARK FDB AS BAD FILE. ;FILES WITH ONLY BAD INDEX BLOCKS THEREFORE HAVE JUST FDBBAT ON IN FDB ;BUT NO XBBAT ON IN XBBWRD OF INDEX BLOCK. (AS OPPOSED TO FILES WITH BAD ;FILE PAGES THAT HAVE BOTH FDB AND XB BITS ON). ASCHK4: PUSH P,[OPNX24] ;BAD SPOT INDEX BLOCK ERROR CAIA ASCHK3: PUSH P,[OPNX16] ;BAD LOOKING INDEX BLOCK ERROR CALL RELCXB ;FILE NO GOOD, RELEASE XB MOVE 1,SPT(3) ;CLEAR OFN AND CORE PAGE SETOM SPTH(3) SOS NOF CALL DECOR ;TRASH ANY CHANGES (LIKE CLEARING OF XBBAT) SETZM CST2(1) JSP 4,ONRQ POP P,1 ;ERROR # INTO 1 ASOFNX: POP P,7 ;[ISI] 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 POP P,7 ;[ISI] 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 ASOFNX ;[ISI] ASOFW2: SKIPA 1,2 ASOFW1: POP P,1 POP P,7 ;[ISI] 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? MOVE 1,FORKX ;[ISI] CAMN 1,DDMPFK## ;[ISI] JRST ASOFA1 ;[ISI] OKSKED MOVEI 1,FSHBAL ;POS. NUMBER MOVEM 1,FSHBAL ;REQUEST TO GC CORE BUT KEEP ONLINE CALL DISE## ;WAIT FOR IT TO HAPPEN SETZM DDMPCT SETZM NXTDMP SETZM DDTIME ;CAUSE DDUMP TO RUN AOS JB0FLG## MOVEI 1,DDMPCT ;[ISI] CALL DISG## ;[ISI] 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 ASOFNX ;[ISI] 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 TLNE 2,SHRBIT+INDBIT ;[ISI] Pointer type ok if private JRST RELBAD ;[ISI] TLNN 2,10 ;[ISI] Address ok if on disk or in core TLNN 2,16 ;[ISI] JRST RELOF6 ;[ISI] PUSH P,1 ;[ISI] From KI TENEX 1.31 PUSH P,3 ;[ISI] Page probably on drum, try to get it PUSH P,4 ;[ISI] onto the disk.. PUSH P,7 ;[ISI] HRLZ 1,1 ;[ISI] Get AC1 set up for call to SWPINP HRRI 1,0(3) ;[ISI] CALL SWPINP ;[ISI] Bring page into core from drum CALL AGESET ;[ISI] Set age CALL SWPOT0 ;[ISI] Swap out to disk POP P,7 ;[ISI] POP P,4 ;[ISI] POP P,3 ;[ISI] POP P,1 ;[ISI] MOVE 2,CXBPGA(3) ;[ISI] Make sure page not on drum JUMPE 2,RELOF2 ;[ISI] TLNN 2,10 ;[ISI] TLNN 2,16 ;[ISI] TLNE 2,SHRBIT+INDBIT ;[ISI] JRST RELBAD ;[ISI] really bad RELOF6: TLNN 2,10 ;[ISI] (The end) 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? jrst [ tlnn 1,17 ;no, in core? jrst .+1 ;no, can't swap out call ageset ;yes, go set ownership so swpout works call swpot0 ;now swap out xb jrst .+1] 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 SETZ 2, ;NO QUESTION ABOUT BAD SPOTS 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 MOVSI 2,OFNBAT ;PASS JUST OFNBAT AND 2,SPTH(1) ;FROM SPTH FLAGS SETOM SPTH(1) ;DELETE FROM SPTH PUSH P,1 CALL REMFP1 ;REMOVE PAGE 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 ifn kiflg,< call kipsad## ;go do fixup for kiupt > 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: 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 SETP51: TLNN 3,INDBIT ;[ISI] SOURCE PT CONTAINS AN @ PTR? JRST SETP58 ;NO. PRIVATE, SHARED, OR EMPTY 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 CAIGE 3,NOFN ;[ISI] If @ to file page, get out (OK) JRST SETP58 CALL SETXB1 ;MAP IT OKSKED SKIP CXBPGA NOSKED MOVE 3,CXBPGA(2) ;GET CONTENTS OF @ PT WORD JRST SETP51 ; and check it out 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 ifn kiflg,< call kipsad## ;go do fixup for kiupt > 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 SKIP CPTPGA ;[ISI] Make sure page in core! (RS patch) 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) ifn kiflg,< call kipsad## ;go do fixup for kiupt > EXCH 1,2 ;EXCHANGE SOURCE AND DESTINATION PT'S MOVE 3,PSB+CPTPG EXCH 3,PSB+CXBPG MOVEM 3,PSB+CPTPG IFN KAFLG!F3FLG,< ;[ISI] MONCLR ;[ISI] Clear ARs for exec mapping > IFN KIFLG,< ;[ISI] PUSH P,2 ;[ISI] CALL SETCP2 ;[ISI] CALL SETXB2 ;[ISI] POP P,2 ;[ISI] > 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 IFN KIFLG,< ;[ISI] SETXB2: MOVE 3,PSB+CXBPG ;[ISI] SETKIM (CXBPG,3) ;[ISI] DATAO PAG,KIPGWD ;[ISI] MOVE 3,PSB+CXBPG ;[ISI] > 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 IFN KIFLG,< ;[ISI] SETCP2: MOVE 2,PSB+CPTPG ;[ISI] SETKIM (CPTPG,2) ;[ISI] DATAO PAG,KIPGWD ;[ISI] MOVE 2,PSB+CPTPG ;[ISI] > 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 MOVES CPTPGA ;[ISI] Dummy ref & dirty page RELMP7: PUSH P,1 RELMP5: MOVE 2,CPTPGA(1) ;GET MAP WORD JUMPE 2,RELMPR ;EMPTY IFN KIFLG,< ;[ISI] From KI TENEX 1.31 (PAGEM, p29) HLRZ 4,1 ;[ISI] See if this page is in the monitor.. HRRZ 3,FORKX ;[ISI] Is the owning page table HRRZ 3,FKPGS(3) ;[ISI] the PSB? CAIE 4,0(3) ;[ISI] JRST [ LDB 3,[POINT 13,PSB+JSBPG,26] ;[ISI] No, CAIE 4,0(3) ;[ISI] Is it the JSB? CAMN 4,MMSPTN ;[ISI] Or MMAP? JRST .+1 ;[ISI] Yes JRST RELKI2 ] ;[ISI] MOVEI 3,0(1) ;[ISI] Is the page in the job private area? CAIGE 3,NRPLBG/1000 ;[ISI] JRST RELKI2 ;[ISI] no ROT 3,-1 ;[ISI] Blitz this page's entry in the p.t. SKIPL 3 ;[ISI] HRRZS KIEPT(3) ;[ISI] SKIPGE 3 ;[ISI] HLLZS KIEPT(3) ;[ISI] DATAO PAG,KIPGWD ;[ISI] KI pager should take a fresh look JRST RELKI1 ;[ISI] (very fast PGRCLD) RELKI2: ;[ISI] AOS KIRFLG ;[ISI] Reset all KI UPTs > PGRCLD ;CLEAR AR'S RELKI1: ;[ISI] 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 ifn kiflg,< call kipsad## ;go do fixup for kiupt > 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 MOVES CXBPGA ;[ISI] Dummy ref & dirty page 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: HLRZ 2,(P) ;GET OFN (FROM OFN.PN) MOVE 2,SPTH(2) ;GET FLAGS TLZ 2,^-OFNBAT ;PASS JUST OFNBAT FOR NOW 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) ;ACCEPTS 1/ FILE PAGE # IF CALLING REMFPG ; 2/ FLAGS: DON'T DEASSIGN ADR BECAUSE PART OF BAD FILE (OFNBAT) ; 3/ PAGE ADR IF CALLING REMFP1 REMFPG: MOVE 3,CPTPGA(1) ;GET MAP WORD SETZM CPTPGA(1) ;CLEAR MAP WORD ifn kiflg,< call kipsad## ;go do fixup for kiupt > REMFP1: PUSH P,2 ;SAVE OFNBAT FLAG REMFP0: TLNE 3,10 ;DISK? JRST REMFF ;YES TLNE 3,16 ;DRUM? JRST REMFD ;YES TLNE 3,17 ;CORE? JRST REMFPR ;NO-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 REMFP0 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 (CAN'T BE BAD SPOT) POP P,2 CALL GDSTX MOVE 3,DST(2) ;GET BACKUP ADDRESS SETOM DST(2) ;MAKE DST SLOT EMPTY JRST REMFP0 REMFF: MOVE 1,3 MOVE 2,(P) ;GET CALLERS FLAGS TLNN 2,OFNBAT ;DON'T DEASSIGN IF PART OF BAD FILE CALL DEDSK ;DEASSIGN DISK ADDRESS REMFPR: POP P,2 ;COMMON EXIT 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 ifn kiflg,< call kipsad## ;go do fixup for kiupt > 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!F3FLG,< 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,XRMRCA > ;GET OWNING PAGE TABLE ;GIVEN PTN.PN, LOCATE PT CURRENTLY HAVING ADDRESS OF PAGE GETONT: CALL SETCPT ;[ISI] 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 CALL RELCPT ;RELEASE CPT HRRZ 1,2 ;[ISI] Reformat into PTN.PN ANDI 1,777 ;[ISI] LSH 2,-^D9 ;[ISI] ANDI 2,SPTM ;[ISI] HRLI 1,(2) ;[ISI] 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: ifn kiflg,< call kilupt ;set up ki upt pointer > 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 SETZ 2, ; NO PROCESS USE BITS ANYMORE MOVE 1,AGEGLB ; GET GLOBAL AGE ROTC 1,-^D9 MOVEM 2,PGR72 PGRCLD ;LOAD PAGER FROM 71,72 MOVE 1,ACBAS ;SET AC BASE REGISTER SETACB 1 RET ;DEASSIGN CORE DASWSP: 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 SOS FKWSP(2) ; REDUCE PAGE COUNT FOR THIS PROCESS MOVSI 2,7777 IORM 2,CST3(1) ;MAKE PAGE UNASSIGNED DECRR: POP P,2 POP P,3 RET ;PAGER TRAP PGRTRP: XWD TRAPPC,.+1 IFDEF FOOVID,< CONO APR,3000+APCHNS ;Re-enable 60HZ clock, which Foovision may mung. > 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 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 TRP0R: MOVSI 1,0(2) HRRI 1,SWPRT CALL PGIWT ;WAIT FOR PAGE AND ACCOUNT JRST NICN 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 CAIL 1,NFKS ;ANY PROCESS? JRST ATP1 ;NO SOS FKWSP(1) ; REDUCE CORE OCCUPANCY FOR PREVIOUS OWNER 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,) 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 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 FKWSP(7) ;INCREASE OWNERSHIP COUNT MOVE 1,AGEGLB ; GET GLOBAL AGE 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,<-2*KIFLG-1>(P) ;[ISI] WRITE DATA (ASSUMING TOP-LEVEL TRAP) MOVEM 2,UTRWD MOVE 2,<-2*KIFLG-2>(P) ;[ISI] PC TLNN 2,UMODF ;USER? SKIPGE INTDF ;OR INTERRUPTABLE? JRST .+3 ;YES TLNE 1,12 ;MUST DEFER INTERRUPT, READ REF? AOS <-2*KIFLG-2>(P) ;[ISI] Yes, do not 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,READB ;DO NOT ALLOW IF NO READ ACCESS TDNN 2,CSWPGA(1) ;... JRST [ CALL RELSPG JRST ILRD ] 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 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 ;JUST UPDATE STATISTICS AND CHECK FOR CORE LIMITS NIC: MOVE 2,JOBNO AOS JOBPGF##(2) ;PAGE FAULTS/JOB HRRZ 2,JOBNAM(2) ;GET SUBSYSTEM INDEX AOS SPFLTS(2) ;ACCOUNT PAGE FAULTS FOR SUBSYSTEM ; CHECK RPLQ HERE AND STOP HOGS NICN: NIC2: 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 CHKRPQ ; ENSURE NO DISMIS AT SWPQT JRST NIC2 ; HAD TO RESKED SO BACK TO TOP CALL SWPINW ;SWAP IN THE PAGE JRST NIC2 CHKRPQ: MOVE 2,NSKED CAILE 2,1 ; IF NOSKED (TRAP CAUSES ONE, TOO) JRST RSKP ; THEN LET PROCESS HAVE A PAGE MOVE 2,NRPMIN CAMLE 2,NRPLQ ; ABOVE BARE MIN? JRST CHKRP1 ; NO HRRZ 2,FKWSP(7) ; GET CURRENT # PAGES ASSIGNED TO THIS FORK IDIV 2,GCMOD ; SCALE TO ALLOWABLE SIZE CAMG 2,NRPLQ ; ENOUGH ROOM LEFT? JRST RSKP ; YES CHKRP1: MOVEI 1,TRPNEW ; ADDRESS OF TEST JSYS SCHEDR ; DISMS AND WAIT FOR RPLQ TO GE REPLENISHED NOSKED ; NOW GET BACK TO NORMAL STATE RET TRPNEW: MOVE 2,NRPLQ CAMGE 2,NRPMIN ; IS IT ABOVE ABSOLUTE MIN? JRST 0(4) ; NOT YET, SO STAY OUT HRRZ 2,FKWSP(7) ; GET CURREN NUMBER OF PAGES OWNED BY FORK IDIV 2,GCMOD ; SCALE CAMG 2,NRPLQ ; ROOM LEFT? JRST 1(4) ; YES JRST 0(4) ; NO 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 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 ;RELEASE WORKING SET JSYS ;EFFECTIVELY A NO OP UNDER NGCC .RWSET: JSYS MENTR 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!F3FLG,< 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 IFN KAFLG!F3FLG,< ;[ISI] 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 > IFN KIFLG,< ;[ISI] PIOFF ;[ISI] EXCH 1,PGURET ;[ISI] Set up to return thru scheduler MOVEM 1,PPC ;[ISI] HRRZ 1,MJRSTF ;[ISI] Deferred interrupt waiting? CAIN 1,FPC ;[ISI] SETOM PGUNTF## ;[ISI] No, leave via PI on SCDCHN MOVE 1,PGURET ;[ISI] AOS INSKED ;[ISI] Claim to be in scheduler SOS NSKED ;[ISI] Like OKSKED SOS INTDF ;[ISI] Like OKINT PION ;[ISI] SKIPN PGUNTF ;[ISI] JRST RSKD1## ;[ISI] Exit thru scheduler ISB SCDCHN ;[ISI] Call scheduler via PI JRST .-1 ;[ISI] > ;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,(400B8+CORMB) ;[ISI] SET LEGAL AGE SO PAGER DOESN'T TRAP MOVEM 1,CST0(3) TLO 3,RWXB ;NO, ZERO OUT PAGE MOVEM 3,MMAP+CSWPG IFN KIFLG,< ;[ISI] MOVEI 1,KIAXB+KIWB(3) ;[ISI] MONSET (CSWPG,1) > ;[ISI] 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) 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,(400B8+CORMB) ;[ISI] TRAP IN A SAFE WAY SHOULD IT HAPPEN MOVEM 2,CST0(1) ;TO INTERPRET AN INDIRECT PTR WHICH IFN KIFLG,< ;[ISI] MOVEI 2,KIAXB+KIWB(1) ;[ISI] MONSET (CSWPG,2,3) > ;[ISI] 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 IFN KIFLG,< ;[ISI] MOVEI 6,KIAXB(1) ;[ISI] HLL 1,CST0(1) ;[ISI] TLNE 1,(CORMB) ;[ISI] IORI 6,KIWB ;[ISI] MONSET (CSWPG,6) > ;[ISI] 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,(400B8+CORMB) ;[ISI] GET LEGAL AGE EXCH 3,CST0(1) ;SAVE OLD AGE IFN KIFLG,< ;[ISI] MOVEI 2,KIAXB+KIWB(1) ;[ISI] MONSET (CSWPG,2) > ;[ISI] 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 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,SWPERR TDNE 2,CST3(1) ;ERROR? JRST SWPFIX ;YES-HANDLE IT SWPDO0: MOVSI 2,DWRBIT ;WRITE BIT TDNE 2,CST3(1) ;WAS WRITE? JRST SWPD1 ;YES skipg 2,forkx ;find out who is now running jrst swpd3 ;do nothing if sched or ddmpfk hrrz 3,cst0(1) ;find out who is waiting for this page cail 3,nfks ;legal fork number? jrst swpd3 ;no, do nothing hlrz 2,fkq##(2) ;yes, get sched queue of running fork hlrz 3,fkq(3) ;and that of fork waiting for this page camg 2,3 ;is running fk on higher q than waiting fk? jrst swpd3 ;no, do nothing aos psked ;yes, ask for rescheduling isb scdchn ;and poke channel seven to make it happen swpd3: 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) ;HERE TO PROCESS SWAPPING ERROR, BAT ENTRY QUEUED FOR JOB 0 ALREADY ;VIA DISK DRIVER ;------------------------------------------------------------------------------ ;SWAPPING ERROR HANDLING: ; ; WRITE: NOT EXPECTED OR HANDLED. ; ; READ: ; ; FROM DISK: DECODE USAGE AND POSSIBLY COMPLAIN. ; POSSIBLY SET OFNBAT FOR OFN. ; SWPERR SEEN LATER IF ALLOWED TO FLY AND ; INTERRUPT WILL BE HANDED OFF TO PROCESS. ; ; FROM DRUM: ; ; NO BACKUP: ASSIGN TRASH DRUM ADR TO CST. ; LEAVE OLD BAD DRUM ADR ASSIGNED. ; DECODE USAGE AND POSSIBLY COMPLAIN. ; POSSIBLY SET OFNBAT FOR OFN. ; SWPERR SEEN LATER IF ALLOWED TO FLY AND ; INTERRUPT WILL BE HANDED OFF TO PROCESS. ; ; BACKUP: ; ; DST BWRBIT ON: LEAVE OLD BAD DRUM ADR ASSGNED. ; MAKE DRUM BACKUP CORE BACKUP. ; DECODE USAGE & POSSBLY CMPLAIN. ; POSSIBLY SET OFNBAT FOR OFN. ; SWPERR SEEN LATER IF ALLOWED TO ; FLY & INTERRUPT WILL BE HANDED ; OFF TO PROCESS. ; ; DST BWRBIT OFF: LEAVE OLD BAD DRUM ADR ASSGNED. ; MAKE DRUM BACKUP CORE BACKUP. ; RESTART READ FROM NEW BACKUP. ;------------------------------------------------------------------------------ ;ACCEPTS 1/ PAGE NUMBER SWPFIX: PUSH P,1 ;CLOBBER NO ACS PUSH P,2 PUSH P,3 PUSH P,4 MOVE 2,CST3(1) ;WE ARE EXPECTING ONLY READ ERRORS FOR NOW TLNE 2,DWRBIT ;WAS IT? BUG (HLT,) MOVE 2,CST1(1) ;GET BACKUP ADR WE READ FROM TLNN 2,(DSKABT) ;DID WE READ FROM DRUM? JRST SWPFDR ;YES-DRUM ADR HANDLING SWPFI0: MOVE 1,-3(P) ;GET CPN AGAIN INCASE JRSTED BACK FROM SWPFDR HLRZ 2,CST2(1) ;GET OWNING SPTN JUMPN 2,SWPFI1 ;JUMP IF IN PT HRRZ 2,CST2(1) ;GET SPTN OF PAGE CAIGE 2,NOFN ;INDEX BLOCK? JRST [ CALL SWBOFN ;YES - FLAG IN SPT CALL SWPSNS ;IS IT SENSITIVE INDEX BLOCK? JRST SWPX10 ;NO - NOTE MILD COMPLAINT JRST SWPX11] ;YES-COMPLAIN HLRZ 2,SPTH(2) ;GET OFN OF IDENT JUMPN 2,SWPFI1 ;JUMP IF OFN PRESENT HRRZ 2,CST2(1) ;GET SPTN AGAIN IN 2 CALL FNDFPG ;GET TYPE OF FORK PAGE, 1/ PAGE #, 2/ SPTN JRST @[ SWPX12 ;0 - UNKNOWN SWPX13 ;1 - PSB SWPX14 ;2 - UPT SWPX15](2) ;3 - JSB ;HERE WHEN HAVE PAGE TABLE IDENT IN 2 SWPFI1: CAIGE 2,NOFN ;IN ORDINARY FILE? JRST [ CALL SWBOFN ;YES - MARK IN SPT CALL SWPSNS ;IS IT SENSITIVE FILE PAGE? JRST SWPX20 ;NO-LET IT RIDE JRST SWPX21] ;YES-COMPLAIN CAMN 2,MMSPTN ;SWAPPABLE MONITOR? JRST SWPX30 ;YES CALL FNDFPG ;GET TYPE OF FORK PAGE, 1/ PAGE #, 2/ SPTN JRST @[ SWPX22 ;0 - UNKNOWN SWPX23 ;1 - PSB PAGE SWPX24 ;2 - UPT PAGE SWPX25](2) ;3 - JSB PAGE ;HERE TO RESTORE THINGS AND RETURN TO SWPDON SWPFIR: POP P,4 ;RESTORE ACS POP P,3 POP P,2 POP P,1 JRST SWPDO0 ;BACK TO SWPDON ;HERE TO RESTORE THINGS AND RETURN TO CALLER OF SWPDON ;HENCE ABORTING REST OF SWPDON (LIKE CLEARING READ IN PROGRESS FOR REDOS) SWPFIA: POP P,4 ;RESTORE ACS POP P,3 POP P,2 POP P,1 JRST (4) ;ABORT REST OF SWPDON ;HERE TO DETERMINE IF OFN IS IN SENSITIVE RANGE ;ACCEPTS OFN IN 2 ;SKIPS IF SENSITIVE, NO SKIP IF NOT SWPSNS: PUSH P,1 ;CLOBBER NO ACS HLRZ 1,SNSOFN ;GET START OF RANGE CAMGE 2,1 ;OFN BELOW LOWEST? JRST SWPSN1 ;YES-NOT IN SENSITIVE RANGE HRRZ 1,SNSOFN ;NO-GET END OF RANGE CAMG 2,1 ;OFN ABOVE HIGHEST? AOS -1(P) ;NO-ITS SENSITIVE, SKIP SWPSN1: POP P,1 RET ;HERE TO INDICATE AN ERROR IN AN OFN SWBOFN: PUSH P,1 ;CLOBBER NO ACS MOVSI 1,OFNBAT ;GET BAT BIT IORM 1,SPTH(2) ;IN SPTH FOR OFN POP P,1 RET ;DISPOSITION OF SWAP ERROR CASES ;PAGE TABLE ERRORS SWPX10: BUG(CHK,) JRST SWPFIR SWPX11: BUG(HLT,) SWPX12: BUG(HLT,) SWPX13: BUG(HLT,) SWPX14: BUG(HLT,) SWPX15: BUG(HLT,) ;NON PAGE TABLE ERRORS SWPX20: JRST SWPFIR ;QUIET ON NORMAL FILE PAGE SWAP ERRORS SWPX21: BUG(CHK,) JRST SWPFIR SWPX22: BUG(HLT,) SWPX23: BUG(HLT,) SWPX24: JRST SWPFIR ;QUIET ON UPT PAGE SWAP ERRORS SWPX25: BUG(CHK,) JRST SWPFIR ;MISC ERRORS SWPX30: BUG(HLT,) ;HERE FOR BAD SPOT READS FROM DRUM ;CORE PAGE # IN 1 ;IF THERE IS A DISK BACKUP AND BWRBIT IS OFF ;MAKE IT THE CORE BACKUP AND TRY IO AGAIN ;LEAVING THE DRUM ADR ASSIGNED BUT NOT LINKED TO A CST ;IF THE BWRBIT IS ON, MAKE DISK THE BACKUP BUT RETURN TO SWPDON ;TO ALLOW USER TO SEE INTERRUPT. IF USER DOES NOT WRITE ON THE BAD PAGE, ;THE OLD COPY WILL STILL BE THERE. BETTER THAN COMPLETE TRASH. SWPFDR: PUSH P,1 ;SAVE CPN [-4(P)] OR {-2(P)} MOVE 2,CST1(1) ;GET BACKUP DRUM ADR TLZ 2,DSKMSK ;WITHOUT THE LOCK COUNT PUSH P,2 ;SAVE BAD SPOT DRUM ADR [-3(P)] OR {-1(P)} CALL GDSTX ;GET BAD DRUM ADR DST INDEX PUSH P,2 ;AND SAVE IT [-2(P)] OR {0(P)} MOVE 1,DST(2) ;GET THE BACKUP FOR DRUM (HOPEFULLY DISK) CAME 1,[-1] ;FREE TLNN 1,(DSKABT) ;OR NOT A DISK ADR? (UNASSIGNED) CAIA ;YES JRST SWPFD1 ;NO-POINT CST AT IT AND TRY AGAIN SETO 1, ;GET A TRASHED NEW FREE CHOICE CALL DRMASN ;GET A NEW DRUM ADR BUG (HLT,) PUSH P,1 ;SAVE NEW DRUM ADR [-1(P)] MOVE 2,1 ;WHERE GDSTX LIKES IT CALL GDSTX ;GET DST FOR NEW DRUM ADR PUSH P,2 ;SAVE IT [0(P)] MOVE 2,-2(P) ;GET OLD DST INDEX MOVE 1,DST(2) ;GET THE CONTENTS TLZ 1,BWRBIT ;SAY PAGE NOT CHANGED, HOPE NOT TO WRITE BACK MOVE 2,0(P) ;GET NEW DST INDEX MOVEM 1,DST(2) ;INSTALL DST FOR NEW DRUM ADR (COPY OF OLD) MOVE 1,-4(P) ;GET CPN HLLZ 2,CST1(1) ;GET LOCK COUNT TLZ 2,^-DSKMSK ;CLEANLY IOR 2,-1(P) ;ADD NEW DRUM ADR TO OLD LOCK COUNT MOVEM 2,CST1(1) ;INSTALL NEW DRUM ADR AS BACKUP FOR CPN MOVE 2,-2(P) ;GET OLD DRUM ADR DST INDEX SETOM DST(2) ;CLEAR IT, OLD DRUM ADR STILL ASSIGNED SUB P,BHC+5 ;RESYNC STACK JRST SWPFI0 ;BACK TO REST OF SWAP ERROR HANDLING ;COMPLAIN AS APPROPRIATE ;HERE FOR DRUM SWAP ERROR AND BACKUP FOR DRUM (DISK) EXISTS. ;STACK HAS CPN,DRUM ADR,DST INDEX AS {-2(P)},{-1(P)},{0(P)} SWPFD1: MOVE 1,0(P) ;GET DST INDEX MOVE 1,DST(1) ;GET CONTENTS OF DST (PRESERVE STATUS BITS) HRLI 2,DSKMSK ;BUILD MASK OF BITS NOT TO KEEP TLZ 2,NEWFB(DSKABT) ;KEEP NEW FILE BIT AND DISK DEVICE BIT ANDCM 1,2 ;CLEAN UP 1 RETAINING NEWFB AND DSKABT MOVE 3,-2(P) ;GET CPN HLLZ 2,CST1(3) ;GET LOCK COUNT TLZ 2,^-DSKMSK ;CLEANLY IOR 1,2 ;IOR LOCK COUNT AND DISK ADR MOVEM 1,CST1(3) ;MAKE CORE BACKUP DISK NOW MOVE 1,0(P) ;GET DST INDEX OF BAD DRUM ADR MOVE 2,DST(1) ;GET OLD DST CONTENTS SETOM DST(1) ;CLEAR IT, BUT DRUM ADR STILL ASSIGNED TLNE 2,BWRBIT ;DRUM DIFFERENT FROM DISK? JRST SWPFD2 ;YES-SEMI LOSAGE MOVE 1,-2(P) ;NO-REQUEUE FOR SWAPPING IN FROM DISK MOVSI 2,DWRBIT ;THE WRITE BIT TDNE 2,CST3(1) ;WAS IT A WRITE WE ARE GONNA REDO? TLO 1,DWRBIT ;YES-TURN ON DWRBIT IN DSKIO ARG CALL DSKIO ;REDO THE IO, DISK THIS TIME SUB P,BHC+3 ;RESYNC STACK JRST SWPFIA ;AND ABORT SWPDON, PROCESS WAITING FOR ;REDO TO COMPLETE NOW ;HERE AFTER MAKING DISK THE BACKUP FOR CORE AND FOUND BWRBIT ON ;IN BAD SPOT DST. RESYNC AND CONTINUE - PASSING THE INTERRUPT ON TO USER. SWPFD2: SUB P,BHC+3 ;RESYNC STACK JRST SWPFI0 ;COMPLAIN AS APPROPRIATE ;FIND TYPE OF FORK PAGE ; 1/ PAGE # ; 2/ SPTN OF CONCERN ; CALL FNDFPG ; RETURNS +1 ALWAYS, ; 2/ 0 - UNKNOWN PAGE ; 1 - PSB ; 2 - UPT ; 3 - JSB FNDFPG: PUSH P,1 ;CLOBBER NO ACS PUSH P,2 PUSH P,3 HRRZ 3,CST0(1) ;GET FORKX OF PAGE IN 3 CAIL 3,0 ;LOOK LEGAL? CAIL 3,NFKS JRST FNDFP2 ;NO-UNKNOWN MOVSI 2,-NFNFT ;SETUP TO SCAN TABLE FNDFP1: XCT FNFTAB(2) ;GET SPTN FOR A FORK PAGE IN 1 CAMN 1,-1(P) ;SAME AS GIVEN ONE? JRST FNDFP3 ;YES, RETURN INDEX IN 2 AOBJN 2,FNDFP1 ;SCAN TABLE FNDFP2: SETZ 2, ;NOT FOUND, 0 IS UNKNOWN FNDFP3: HRRZM 2,-1(P) ;CLEAR COUNTER PART OF AOBJN POP P,3 ;RESTORE ACS POP P,2 ;HAS ANSWER TYPE POP P,1 RET FNFTAB: SETZ 1, ;IMPOSSIBLE SPTN TO FAKE UNKNOWN HRRZ 1,FKPGS(3) ;GET SPTN OF PSB FOR FORK IN 3 HLRZ 1,FKPGS(3) ;GET SPTN OF UPT FOR FORK IN 3 HRRZ 1,FKJOB(3) ;GET SPTN OF JSB FOR FORK IN 3 NFNFT==.-FNFTAB 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 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) 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: IFN KIFLG,< ;[ISI] AOS KIRFLG > ;[ISI] Force resetting of all KI UPTs 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 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 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 IFN KAFLG!F3FLG,< ;[ISI] MONCLR (CSWPG) ;[ISI] Clear the AR used for CSWPG > IFN KIFLG,< ;[ISI] Set up KI's page table directly MOVEI 3,KIAXB+KIWB(1) ;[ISI] and have the pager take a fresh MONSET (CSWPG,3,2) ;[ISI] look at CSWPG DATAO PAG,KIPGWD ;[ISI] > SKIP CSWPGA ; REFERENCE THE PAGE MOVSI 2,010000 MOVEM 2,CST0(1) ; SET AGE BACK TO UNAVAIL IN CASE NXM IFE F3FLG,< CONSZ APR,APNXM ; EXISTS? > IFN F3FLG,< SETZM CSWPGA ;TRY TO ZERO OUT LOCATION SKIPE CSWPGA ;F3 RETURNS -1 ON NXM READS... > 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 MAKPGX: CONO APR,APNXM+APCHNS ;[ISI] CLEAR NXM FLAG CAMGE 1,-3(P) ; REACHED END YET? AOJA 1,MKPGAL ; NO DO NEXT ONE SETZM MMAP+CSWPG ; CLEAR MAP ENTRY PGRCLD 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 DEPGIT ; GO BREAK ALL POINTERS TO RPLQ! MOVSI 1,-NFKS SETZM FKPAGE(1) ; MAKE CUTOFF AGE BE NOW FO AL FORKS AOBJN 1,.-1 PUSH P,GCDIFF ; SAVE OLD VALUE MOVEI 1,MAXCOR MOVEM 1,GCDIFF ; MAKE MAX SIZE CALL NGCC ; NOW COLLECT AS MUCH AS POSSIBLE POP P,GCDIFF POP P,1 ; GET OLD NRPLQ SKIPN IOIP CAME 1,NRPLQ JRST GCALC ; LOOP UNTIL NO CHANGE IN NRPLQ AND NO IOIP CALL DEPGIT ; NOW GO BREAK THE LAST BUNCH OF POINTERS 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 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 MOVEM 1,GCPN ; AND UPDATE GARBAGE COLLECTOR START POINT! 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 GCALX: SETZM FSHBAL ;SAY FLUSH IS COMPLETED RET DEPGIT: MOVE 1,NRPLQ ; GET SIZE OF LIST JUMPE 1,R ; COULD BE EMPTY HRRZ 7,RPLQ DEPGT1: MOVEI 3,(7) SUBI 3,CST3 CALL DEPG ; BREAK POINTERS TO THIS PAGE SETZM CST2(3) HRRZ 7,(7) ; CONTINUE DOWN RPLQ LIST SOJG 1,DEPGT1 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 ;15 FORK KILL LOGIC CALLS THIS TO CLEAN UP FKDGCC::MOVE FX,-1(P) SETOM FKPAGE(FX) PUSH P,P1 MOVN P1,NHIPG ADD P1,SWPCOR MOVSI P1,-1(P1) ADD P1,SWPCOR FKDGC1:LDB T1,[POINT 12,CST3(P1),17] ; GET OWNING FORK CAIE T1,0(FX) JRST FKDGC2 LDB T1,[POINT 9,CST0(P1),8] ; GET AGE FIELD CAIGE T1,100 ;10 Page in use? JRST FKDGC2 ;10 No, don't collect MOVEI T1,0(P1) CALL DASWSP MOVE T2,CST1(P1) TLNE T2,-PLKV JRST FKDGC2 MOVE T2,CST3(P1) TLNN T2,DWRBIT CALL SWPOUT FKDGC2: AOBJN P1,FKDGC1 POP P,P1 RET ;NEW GARBAGE COLLECT CORE ROUTINE ;P1 IS THE NUMBER OF PAGES TO COLLECT. ;P2 IS THE PAGE NUMBER OF THE PAGE BEING LOOKED AT. ;NGCC ENTRY POINT NGCC:: ;CALCULATE THE NUMBER OF PAGES TO COLLECT. JSP 4,STIME ; COLLECT TIMING DATA MOVN P1,GCSTRT ;CALCULATE NUMBER OF PAGES TO COLLECT SUB P1,GCDIFF ; GCSTRT + GCDIFF - NRPLQ - IOIP ADD P1,NRPLQ ; AND PUT IN P1 AS A NEGATIVE NUMBER. ADD P1,IOIP MOVSI P1,0(P1) HRRZ P2,GCPN ; GET ROVING CORE PAGE POINTER FROM LAST PASS MOVEI P3,3 ;17 INIT LOOP DETECTION COUNTER NGCC10:LDB T1,[POINT 9,CST0(P2),8] ; GET AGE FIELD FOR THIS PAGE CAIGE T1,100 ;8 IS THIS PAGE AGE LEGAL? JRST NGCC50 ;NO, TRY TO COLLECT IT NOW. LDB FX,[POINT 12,CST3(P2),17] ; GET OWNING FORK CAIL FX,NFKS ;IS THIS FORK A LEGAL FORK? JRST NGCC40 ;NO, TRY TO COLLECT IT NOW. SUB T1,AGEGLB ; GET CURRENT PAGE AGE MOVNS 1 ;18 MAKE CORRECT!!! CAIGE T1,0 ; CHECK FOR OVERFLOW ADDI T1,700 CAML T1,FKPAGE(FX) ; IS THE AGE OF THIS PAGE OLDER THAN FKPAGE? JRST NGCC30 ;YES...TRY TO COLLECT THIS PAGE... NGCC12: ; ADJUST AGE FOR PAGE NOT COLLECTED MOVE T1,FKFLGS(FX) TLNN 1,BLST ; IS THIS FORK IN BALSET? JRST [ HRRZ T2,FKWSP(FX) ; GET CURRENT SIZE CAIG T2,3 ; IF VERY SMALL, THEN KICK OUT FAST SETZM FKPAGE(FX) MOVN T1,GCBALB ;21 Bias in favor of balset jobs ADDM T1,FKPAGE(FX) ;11 pages out of memory JRST .+1 ] ;11 SOSGE FKPAGE(FX) ;17 ADJUST AGE FOR PAGE NOT COLLECTED SETZM FKPAGE(FX) ;17 PREVENT FROM GOINT NEGATIVE! NGCC14: CAMGE P2,NHIPG ;IS THIS THE LAST PAGE OF CORE? AOJA P2,NGCC10 ;NO... MOVE P2,SWPCOR ;RESET PAGE NUMBER TO LOWEST VALUE. SOSGE P3 ;17 LOOK FOR "INFINITE" LOOP JRST NGCCXT ;17 EXIT NOW AND PRAY SOME FORK GIVES PAGES BACK JRST NGCC10 ; ; TRY TO COLLECT THIS PAGE WITH CSTAGE > FKPAGE AND FOR A LEGAL FORK. NGCC30: MOVE T1,CST1(P2) ;GET BACKUP ADDRESS WORD TLNE T1,-PLKV ;IS PAGE LOCKED? JRST NGCC12 ;YES MOVE T1,CST3(P2) ;GET DRUM WRITE BIT. TLNE T1,DWRBIT ;IS PAGE BEING WRITTEN? JRST NGCC12 ;YES HRRZ T2,FKWSP(FX) ; ADJUST FKPAGE FOR PAGE TO BE COLLECTED CAIN T2,1 ; IS THIS THE VERY LAST PAGE? JRST NGCC35 ; YES, SO RESET FKPAGE TO HIGH FOR NEXT ENTRY CAIG T2,3 ; IF VERY SMALL, HELP IT OUT FASTER JRST [ SETZM FKPAGE(FX) JRST NGCC36] LSH T2,2 ;15 SCALE TO GET 20% COLLECTION RATE MOVE T3,TOTRC ;GET TOTAL SWAPPABLE CORE SIZE IDIVI T3,(T2) ADD T3,FKPAGE(FX) ;FKPAGE := FKPAGE + TOTRC/4*WSP SECONDS. CAIL T3,^D360 ;360 SECOND MAXIMUM NGCC35: MOVEI T3,^D360 MOVEM T3,FKPAGE(FX) NGCC36: MOVEI T1,(P2) ; COLLECT THE PAGE CALL DASWSP ;DEASSIGN PAGE FROM OWNING FORK. CALL SWPOUT ;SWAPOUT THIS PAGE. AOBJN P1,NGCC14 ;LOOP UNTIL ENOUGH COLLECTED NGCCXT: MOVEM P2,GCPN ;SAVE PAGE NUMBER TO START ON NEXT TIME JSP 4,ETIME ; FINISH TIMING DATA ADDM 1,GCCR AOS GCCR+1 ; COUNT OCCURRENCES RET ; ;AGE OF THIS PAGE IS VALID, BUT THE FORK IS NOT LEGAL. NGCC40: MOVE T1,CST1(P2) ;GET BACKUP ADDRESS WORD TLNE T1,-PLKV ;IS PAGE LOCKED? JRST NGCC14 ;YES MOVE T1,CST3(P2) ;GET DRUM WRITE BIT. TLNE T1,DWRBIT ;IS PAGE BEING WRITTEN? JRST NGCC14 ;YES... JRST NGCC36 ;DON'T ADJUST FKPAGE, BUT COLLECT THIS PAGE. ; ; THIS PAGE DOES NOT HAVE A VALID AGE. NGCC50: TRZ T1,7 ; SCRAPE OFF AGE BIT REMNANTS CAIE T1,20 ;IS THIS PAGE IN READ COMP MODE? JRST NGCC14 ;NO...DON'T ADJUST FKPAGE AND DON'T COLLECT. HRRZ FX,CST0(P2) ;YES, GET FORK NUMBER THAT INITIATED READ CAIL FX,NFKS ;IS THIS FORK A LEGAL FORK? JRST NGCC40 ;NO. FORK GONE, SO GET PAGE SKIPL FKPT(FX) ;YES...IS THIS FORK A DELETED FORK? JRST NGCC12 ;NO...ADJUST FKPAGE, AND DON'T COLLECT THIS PAGE. JRST NGCC40 ; DELETED FORK, SO GET PAGE GCBLBS::MOVSI T2,-NLDGCB ;21 adjust GC balset bias for load HRRZ T1,LDGCB(T2) ;21 Get break-over LA CAIGE T3,(T1) ;21 Is LA greater than break-over point? AOBJN T2,.-2 ;21 No, look at next break-over point HLRZ T1,LDGCB(T2) ;22 Yes, get GC balset bias MOVEM T1,GCBALB ;21 Set GC balset bias RET ;21 LDGCB: ^D100,,^D10 ;21 ^D10,,5 ;21 ^D2,,0 ;21 NLDGCB==.-LDGCB ;21 END ;END OF PAGEM.MAC