Trailing-Edge
-
PDP-10 Archives
-
BB-4170G-SM
-
sources/pagem.mac
There are 55 other files named pagem.mac in the archive. Click here to see a list.
;<3A.MONITOR>PAGEM.MAC.696, 28-Aug-78 15:09:16, EDIT BY MURPHY
;FIX POTENTIAL UNLOCK OF BAD PTR AT SETIOP+4
;<3A.MONITOR>PAGEM.MAC.695, 16-Aug-78 13:15:54, EDIT BY MURPHY
;<3A.MONITOR>PAGEM.MAC.694, 15-Aug-78 11:36:10, EDIT BY MILLER
; LOAD AGE AT TRPSPM
;<3A.MONITOR>PAGEM.MAC.693, 13-Aug-78 11:54:07, EDIT BY MILLER
;FIXES FOR SPMQ LOGIC.
;<3A.MONITOR>PAGEM.MAC.692, 9-Aug-78 13:48:41, EDIT BY MILLER
;ADD ADDITIONAL DATA TO UBANXM BUGHLT
;<3A.MONITOR>PAGEM.MAC.691, 9-Aug-78 07:51:23, EDIT BY MILLER
;FIX CODE AT FRCSP3 TO BE NOSKED
;<3A.MONITOR>PAGEM.MAC.690, 3-Aug-78 08:19:23, Edit by ENGEL
;ADD "ADD A,BALSHC" TO NICCKS+1 AND NIC3B+3
;<3A.MONITOR>PAGEM.MAC.689, 12-Jul-78 17:37:51, EDIT BY MILLER
;CHECK FOR IMMEDIATE POINTER IN ULDPAG
;<3A.MONITOR>PAGEM.MAC.688, 27-Jun-78 12:23:40, EDIT BY MURPHY
;<1BOSACK>PAGEM.MAC.1001, 5-Jun-78 21:37:56, EDIT BY BOSACK
;<1BOSACK>PAGEM.MAC.1000, 5-Jun-78 19:23:50, EDIT BY BOSACK
;<3A.MONITOR>PAGEM.MAC.686, 13-Jun-78 08:22:51, EDIT BY MILLER
;CHANGE CODE AT NGP1 TO CHECK FOR NOINT MONITOR CORRECTLY
;<3A.MONITOR>PAGEM.MAC.685, 1-Jun-78 13:54:52, EDIT BY MILLER
;DEFINE CLRMPE AS EXTERNAL
;<3A.MONITOR>PAGEM.MAC.684, 1-Jun-78 12:46:12, EDIT BY MILLER
;ADD CALL MEMSTR AFTER ALL MEMORY IS FOUND
;<3A.MONITOR>PAGEM.MAC.683, 1-Jun-78 11:44:20, EDIT BY MILLER
;MAKE SURE PGRINI CLEARS PARITY ERROR
;<3A.MONITOR>PAGEM.MAC.682, 31-May-78 14:33:22, EDIT BY BOSACK
;ALLOW OFN2XB TO BE SET IN SPTH (TEMP)
;<3A.MONITOR>PAGEM.MAC.681, 30-May-78 08:12:28, EDIT BY MILLER
;FIX FRCRMP SO NRPLQ IS MAINTAINED PROPERLY
;<3A.MONITOR>PAGEM.MAC.680, 26-May-78 16:12:02, EDIT BY MILLER
;FIX CODE AT NPG THAT CHECKS NOINT. BE SURE PC IS IN MONITOR
;<3A.MONITOR>PAGEM.MAC.679, 14-May-78 14:27:43, EDIT BY MILLER
;FIX AT RELP4. CLEAR MAPPING AT APPROPRIATE TIME
;<3A.MONITOR>PAGEM.MAC.678, 4-May-78 12:04:09, EDIT BY MILLER
;DON'T BE NOSKED WHILE GETTING IN XB IN ASGOFN
;<3A.MONITOR>PAGEM.MAC.677, 19-Apr-78 16:57:36, EDIT BY MILLER
;CLEAR PAGER IN MSPACS
;<3A.MONITOR>PAGEM.MAC.676, 7-Apr-78 21:39:50, Edit by BORCHEK
;DO NOT DO SETUP IF ANBSEC=0
;<3A.MONITOR>PAGEM.MAC.675, 5-Apr-78 12:24:09, EDIT BY MILLER
;FIX TYPEO IN SETPST
;<3A.MONITOR>PAGEM.MAC.674, 4-Apr-78 13:25:46, EDIT BY MILLER
;MAKE SETPST RETURN PREVIOUS STATE. ADD LODPPS TO DECLARE SPECIAL
;PREVIOUS STATE
;<3A.MONITOR>PAGEM.MAC.673, 23-Mar-78 08:19:27, EDIT BY MILLER
;CHANGE NAME OF ASLOFN TO ASGOFL
;<3A.MONITOR>PAGEM.MAC.672, 23-Mar-78 08:12:46, EDIT BY MILLER
;MERGE ASLOFN INTO ASGOFN. MAKE CODE AS "SMART" AS POSSIBLE
;<3A.MONITOR>PAGEM.MAC.671, 16-Mar-78 09:28:34, EDIT BY MILLER
;WHEN ALL OFN'S EXHAUSTED, TRY FREEING "UNSHARED" ONES
;<3A.MONITOR>PAGEM.MAC.670, 3-Mar-78 15:29:11, EDIT BY MILLER
;SCAN OFN AT RELMI1 IF SHARE COUNT IS ZERO
;<3A.MONITOR>PAGEM.MAC.669, 3-Mar-78 12:20:52, Edit by MCLEAN
;<3.SM10-RELEASE-3>PAGEM.MAC.3, 27-Feb-78 17:44:42, Edit by MCLEAN
;<3.SM10-RELEASE-3>PAGEM.MAC.2, 23-Feb-78 15:36:47, Edit by MCLEAN
;FIX PAGEFAIL CODE 20 ERRORS
;<3A.MONITOR>PAGEM.MAC.667, 3-Mar-78 12:12:35, EDIT BY MILLER
;REMOVE "STRUCTURE" CHECKING IN QCHK. MOVED TO DSKASN
;<3A.MONITOR>PAGEM.MAC.666, 3-Mar-78 11:26:54, EDIT BY MILLER
;ONLY CHECK SYSSPC IN QCHK IF STRUCTURE IS PS
;<3A.MONITOR>PAGEM.MAC.665, 28-Feb-78 15:24:56, EDIT BY MILLER
;RELEASE ALOC ENTRY IN INVOFN
;<3A.MONITOR>PAGEM.MAC.664, 17-Feb-78 09:29:04, EDIT BY MILLER
;PASS PC FLAGS TO ITRSIM AT ILRFU
;<3A.MONITOR>PAGEM.MAC.663, 11-Feb-78 10:03:28, EDIT BY MILLER
;NOW SPELL IT RIGHT
;<3A.MONITOR>PAGEM.MAC.662, 11-Feb-78 09:49:02, EDIT BY MILLER
;MAKE SURE FLAGS AND PC ARE CORRECT ON RETRY FROM "HARD" PAGE FAIL
;<3A.MONITOR>PAGEM.MAC.661, 24-Jan-78 15:17:33, EDIT BY MILLER
;FIX NPG TO ALLOW USER CREATES IN ANY SECTION
;<3A.MONITOR>PAGEM.MAC.660, 24-Jan-78 12:46:51, EDIT BY MILLER
;FIX FPTA AND GETTPD TO GET USER SECTION POINTER FROM UPT
;<3A.MONITOR>PAGEM.MAC.659, 23-Jan-78 20:26:50, EDIT BY MILLER
;FIX TYPEO IN ULDPAG. CHANGE SWPOUT TO SWPOT0 IN FRCSPM
;<3A.MONITOR>PAGEM.MAC.658, 23-Jan-78 13:55:43, EDIT BY MILLER
;MORE ULDPAG FIXES
;<3A.MONITOR>PAGEM.MAC.657, 23-Jan-78 13:50:02, EDIT BY MILLER
;MAKE ULDPAG WAIT FOR SWAP TO COMPLETE
;<3A.MONITOR>PAGEM.MAC.656, 23-Jan-78 11:31:43, EDIT BY MILLER
;BUG FIXES FOR PAGE LOCKING
;<3A.MONITOR>PAGEM.MAC.655, 20-Jan-78 09:53:23, EDIT BY MILLER
;FIX FRCRMP TO DO ADDRESSING CORRECTLY
;<3.SM10-RELEASE-3>PAGEM.MAC.654, 19-Jan-78 16:33:55, EDIT BY MILLER
;<3.SM10-RELEASE-3>PAGEM.MAC.653, 19-Jan-78 16:14:28, EDIT BY MILLER
;WAIT FOR SWAP TO FINISH IN ULDPAG
;<3.SM10-RELEASE-3>PAGEM.MAC.652, 18-Jan-78 16:37:44, EDIT BY MILLER
;FIX OFFSPQ TO SET BACKUP ADDRESS TO UAAB
;<3.SM10-RELEASE-3>PAGEM.MAC.651, 18-Jan-78 16:07:46, EDIT BY MILLER
;FIX FRCSPM TO CORRECTLY PRESERVE PRESENT STATE
;<3.SM10-RELEASE-3>PAGEM.MAC.650, 18-Jan-78 13:08:23, EDIT BY MILLER
;CHANGE NAME OF ROUTINE TO RMPCHK
;<3.SM10-RELEASE-3>PAGEM.MAC.649, 18-Jan-78 13:03:17, EDIT BY MILLER
;CHANGE FRCRMP TO CALL ROUTINE IN APRSRV FOR PAGE CHECK
;<3.SM10-RELEASE-3>PAGEM.MAC.648, 17-Jan-78 15:28:40, EDIT BY MILLER
;MORE CHANGES TO LET LODPPG GRAP RES MONITOR PAGE
;<3.SM10-RELEASE-3>PAGEM.MAC.647, 17-Jan-78 14:30:32, EDIT BY MILLER
;FIX MAPPHP TO CHECK FOR RESMON CORRECTLY
;<3.SM10-RELEASE-3>PAGEM.MAC.646, 17-Jan-78 14:11:41, EDIT BY MILLER
;ALLOW LODPPG TO GET RES MONITOR PAGES. FIX UP ROUTINES TO RETURN PAGE
;<3.SM10-RELEASE-3>PAGEM.MAC.645, 17-Jan-78 12:46:34, EDIT BY MILLER
;ALLOW LODPPG TO LOAD INTO "ON-LINE" RESIDENT MONITOR PAGE
;<3.SM10-RELEASE-3>PAGEM.MAC.644, 16-Jan-78 11:32:24, EDIT BY MILLER
;ADD CHANGES FOR LOCKING PAGES NEEDED FOR MEMORY SUPPORT
;<3.SM10-RELEASE-3>PAGEM.MAC.642, 30-Dec-77 13:48:08, EDIT BY MILLER
;FIX UP FRCRMP. DON'T CHECK FOR SPECIAL PAGES
;<3.SM10-RELEASE-3>PAGEM.MAC.641, 30-Dec-77 13:43:40, EDIT BY MILLER
;UNDO ALL OF SWAP OUT CHECKS. ADD CODE TO LOCK RESIDENT MONITOR
;<3.SM10-RELEASE-3>PAGEM.MAC.640, 28-Dec-77 13:13:50, EDIT BY MILLER
;MORE CHANGES FOR TRANSITION PAGES. MAKE A SUBROUTINE OUT OF CHECKER
;<3.SM10-RELEASE-3>PAGEM.MAC.639, 28-Dec-77 12:06:56, EDIT BY MILLER
;FIX SWPOUT TO CHECK FOR TRANSITION TO SPQ
;<3.SM10-RELEASE-3>PAGEM.MAC.638, 28-Dec-77 11:56:08, EDIT BY MILLER
;FIX CODE AT SWPDON TO CHECK FOR PAGE IN TRANSITION TO SPQ
;<3.SM10-RELEASE-3>PAGEM.MAC.637, 12-Dec-77 12:30:52, EDIT BY MILLER
;FIX FPTA TO RETURN A ZERO FOR NON-EX SECTION POINTER
;<3.SM10-RELEASE-3>PAGEM.MAC.636, 11-Dec-77 19:31:59, Edit by MCLEAN
;<3.SM10-RELEASE-3>PAGEM.MAC.635, 11-Dec-77 19:31:17, Edit by MCLEAN
;FIX SEEADR FOR RM03 SUPPORT
;<3.SM10-RELEASE-3>PAGEM.MAC.634, 10-Dec-77 19:03:05, EDIT BY HELLIWELL
;LOCK PAGE FROM SPMQ DOWN AT SWPIQ1, UNLOCK AT LODPP1
;<3.SM10-RELEASE-3>PAGEM.MAC.633, 10-Dec-77 02:07:55, EDIT BY HELLIWELL
;FIX BUG IN PAGE ACCOUNTING AT SWPIQ1
;<3.SM10-RELEASE-3>PAGEM.MAC.632, 10-Dec-77 00:58:57, EDIT BY HELLIWELL
;FIX NON-EX PAGE CREATION IN SWPPAG
;<3.SM10-RELEASE-3>PAGEM.MAC.631, 9-Dec-77 23:09:42, EDIT BY HELLIWELL
;FIX PAGE ACCOUNTING FOR PAGES GOING ON/OFF SPMQ
;<3.SM10-RELEASE-3>PAGEM.MAC.6, 17-Nov-77 14:56:58, EDIT BY MURPHY
;<3.SM10-RELEASE-3>PAGEM.MAC.5, 14-Nov-77 13:10:12, EDIT BY MURPHY
;LOGIC TO INCLUDE/EXCLUDE PAGE TRAP TIME FROM RUNTIME
;<3-MONITOR>PAGEM.MAC.630, 11-Nov-77 17:19:08, EDIT BY MURPHY
;<3.SM10-RELEASE-3>PAGEM.MAC.3, 2-Nov-77 01:51:10, Edit by LCAMPBELL
;<3-MONITOR>PAGEM.MAC.625, 1-Nov-77 10:25:28, EDIT BY MURPHY
;<3-MONITOR>PAGEM.MAC.624, 31-Oct-77 23:54:59, Edit by LCAMPBELL
;<3-MONITOR>PAGEM.MAC.623, 31-Oct-77 22:36:39, Edit by LCAMPBELL
;MAKE ADBRK WITH ONLY AB%RD ON TRAP ONLY ON READS
;<3-MONITOR>PAGEM.MAC.622, 31-Oct-77 16:44:57, EDIT BY MURPHY
;<3.SM10-RELEASE-3>PAGEM.MAC.1, 27-Oct-77 22:55:07, EDIT BY MILLER
;FIX INVOFN TO RESCAN ENTIRE XB IF HAD TO BLOCK IN SKPNWR
;<3-MONITOR>PAGEM.MAC.621, 12-Oct-77 14:03:10, EDIT BY KIRSCHEN
;UPDATE COPYRIGHT FOR RELEASE 3
;<3-MONITOR>PAGEM.MAC.620, 11-Oct-77 23:46:11, EDIT BY MURPHY
;<3-MONITOR>PAGEM.MAC.619, 10-Oct-77 13:39:56, EDIT BY MURPHY
;INCREMENTAL GCCOR
;<3-MONITOR>PAGEM.MAC.618, 6-Oct-77 00:03:44, EDIT BY MURPHY
;<3-MONITOR>PAGEM.MAC.617, 5-Oct-77 08:44:43, EDIT BY MILLER
;CHANGE TEST FOR PC SECTION AT PGRT3 TO BE SLIGHTLY MORE EFFICIENT
;<3-MONITOR>PAGEM.MAC.616, 4-Oct-77 20:54:44, EDIT BY MURPHY
;<3-MONITOR>PAGEM.MAC.615, 4-Oct-77 12:30:23, EDIT BY MILLER
;ALLOW PAGE FAULT PC TO BE IN SECTION 0 OR IN SECTION MSEC1 AT PGRT3
;<3-MONITOR>PAGEM.MAC.614, 4-Oct-77 11:26:31, EDIT BY MILLER
;INIT OFN SHARE COUNT TO 1 AT ASOF6 IN CASE GARBAGE LEFT BEHIND
;<3-MONITOR>PAGEM.MAC.613, 4-Oct-77 10:11:02, EDIT BY MILLER
;SET UP FPTABL IN PGRINI SO SECTIONS CAN BE SHUFFLED
;<3-MONITOR>PAGEM.MAC.612, 3-Oct-77 17:32:39, EDIT BY MURPHY
;<3-MONITOR>PAGEM.MAC.608, 2-Oct-77 13:57:05, EDIT BY MILLER
;FIXES TO ALLOW MONITOR TO RUN ALL INSECTION 0
;<3-MONITOR>PAGEM.MAC.607, 30-Sep-77 22:40:09, EDIT BY MURPHY
;<3-MONITOR>PAGEM.MAC.606, 30-Sep-77 16:35:52, EDIT BY MURPHY
;<3-MONITOR>PAGEM.MAC.604, 23-Sep-77 16:32:54, EDIT BY MURPHY
;<3-MONITOR>PAGEM.MAC.603, 21-Sep-77 13:13:32, Edit by MCLEAN
;CHANGE MONCLR TO MONCLA IN UNLBTB
;<3-MONITOR>PAGEM.MAC.602, 19-Sep-77 06:01:01, EDIT BY BOSACK
;<3-MONITOR>PAGEM.MAC.601, 18-Sep-77 16:52:48, EDIT BY MURPHY
;<3-MONITOR>PAGEM.MAC.600, 17-Sep-77 22:49:37, EDIT BY HELLIWELL
;ADD HOOKS FOR LOCK JSYS (USED BY VB10 SERVICE)
;<3-MONITOR>PAGEM.MAC.599, 15-Sep-77 17:18:17, EDIT BY MURPHY
;<3-MONITOR>PAGEM.MAC.598, 12-Sep-77 23:08:40, EDIT BY MURPHY
;<3-MONITOR>PAGEM.MAC.597, 12-Sep-77 22:19:44, EDIT BY MURPHY
;TCO #1856 - ONRQ/OFRQ LOGIC
;<3-MONITOR>PAGEM.MAC.596, 12-Sep-77 15:15:41, EDIT BY CROSSLAND
;FIX TO MLKPGM TO SET AGE TO PSASN INSTEAD OF CONTENTS OF PSASN
;<3-MONITOR>PAGEM.MAC.595, 8-Sep-77 15:45:47, EDIT BY HELLIWELL
;CHANGES FOR REL 3 VB10 SUPPORT ALL UNDER RVCF COND.
;<3-MONITOR>PAGEM.MAC.591, 2-Sep-77 14:30:34, EDIT BY MILLER
;FIX PIPTRP CODE
;<3-MONITOR>PAGEM.MAC.590, 1-Sep-77 17:54:59, EDIT BY BOSACK
;<3-MONITOR>PAGEM.MAC.589, 1-Sep-77 17:48:08, EDIT BY BOSACK
;MAKE PI PAGE FAIL ANALYZE AR/ARX PARITY ERRORS CORRECTLY
;<3BOSACK>PAGEM.MAC.590, 23-Aug-77 01:22:04, EDIT BY BOSACK
;INITIALIZE FREECORE TO NUMBER OF INITCODE PAGES
;<3-MONITOR>PAGEM.MAC.587, 17-Aug-77 09:42:47, EDIT BY MILLER
;FIX DASALC TO CHECK FOR ALLOC INFO BEFORE TOUCHING OFNLEN
;<3-MONITOR>PAGEM.MAC.586, 12-Aug-77 17:34:09, Edit by LCAMPBELL
;MORE ADDRESS BREAK
;<3-MONITOR>PAGEM.MAC.585, 12-Aug-77 10:09:06, EDIT BY HALL
;ADD ADJALC - ADJUST DIRECTORY'S ALLOCATION ENTRY FOR CRDIR
;<3-MONITOR>PAGEM.MAC.584, 9-Aug-77 14:43:02, EDIT BY MILLER
;<3-MONITOR>PAGEM.MAC.583, 9-Aug-77 14:06:08, EDIT BY MILLER
;REMOVE BUGCHK FOR USER MODE EXTENDED ADDRESSING REFERENCE
;<3-MONITOR>PAGEM.MAC.582, 9-Aug-77 08:46:08, EDIT BY MILLER
;MAKE PSB STACK PAGE HAVE AN SPTN AND LOCK IT DOWN IN SCHEDULER
;<MILLER.1MILLER>PAGEM.MAC.1, 8-Aug-77 16:59:20, EDIT BY MILLER
;<3-MONITOR>PAGEM.MAC.581, 8-Aug-77 10:48:33, EDIT BY MILLER
;ALLOW FPTA TO RETURN A ZERO FOR NON-EX SECTION. CHECK BY ALL CALLERS
;<3-MONITOR>PAGEM.MAC.580, 4-Aug-77 18:00:59, EDIT BY MILLER
;PUT IN HACK IN MRMAP TO CHECK FOR FPTA RETURNING A ZERO
;<3-MONITOR>PAGEM.MAC.579, 29-Jul-77 14:57:27, Edit by LCAMPBELL.ADBRK
;TCO 1838 - ADDRESS BREAK
;<3-MONITOR>PAGEM.MAC.578, 28-Jul-77 10:09:07, EDIT BY MILLER
;FIX PGRTH TO USE FLAGS FROM PFAID
;<3-MONITOR>PAGEM.MAC.577, 27-Jul-77 01:09:07, EDIT BY CROSSLAND
;ADD OMITED INSTRUCTION IN MULKSP
;<3-MONITOR>PAGEM.MAC.576, 26-Jul-77 15:58:01, EDIT BY MILLER
;<3-MONITOR>PAGEM.MAC.575, 26-Jul-77 15:49:51, EDIT BY MILLER
;ADD DESSTK ROUTINE FOR USE BY SCHEDULER
;<3-MONITOR>PAGEM.MAC.574, 26-Jul-77 15:07:04, EDIT BY MILLER
;FIX FAILURES OF SETP7A TO WORK WITH EXTENDED ADDRESSING
;<3-MONITOR>PAGEM.MAC.573, 24-Jul-77 16:34:48, EDIT BY CROSSLAND
;<3-MONITOR>PAGEM.MAC.572, 24-Jul-77 00:06:58, EDIT BY CROSSLAND
;ADD MULKSP TO UNLOCK PAGES IN SECTIONS OTHER THAN 0 AT INTERRUPT LEVEL
;MOVE ARPANET BUFFERS TO ANOTHER SECTION
;<3-MONITOR>PAGEM.MAC.571, 19-Jul-77 13:54:18, EDIT BY MILLER
;TCO 1843. INHIBIT XGC IF IN A NESTED FAULT
;<3-MONITOR>PAGEM.MAC.570, 13-Jul-77 17:53:00, EDIT BY MILLER
;FIX CODE AT RELP4 (AGAIN) TO MAKE SHARER CHECK FASTER
;<3-MONITOR>PAGEM.MAC.569, 11-Jul-77 14:12:05, EDIT BY MILLER
;FIX RELP4 CODE TO UPDATE OFN RACE FREE
;<3-MONITOR>PAGEM.MAC.568, 29-Jun-77 21:01:35, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.567, 29-Jun-77 08:16:57, EDIT BY MILLER
;DON'T SCAN OFN AT RELP4 UNLESS "DUD" IS SET
;<3-MONITOR>PAGEM.MAC.566, 28-Jun-77 17:03:40, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.565, 27-Jun-77 14:52:16, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.564, 27-Jun-77 14:33:30, Edit by MCLEAN
;MOVE BITTABLE TO NON/ZERO SECTION
;<3-MONITOR>PAGEM.MAC.562, 26-Jun-77 12:38:07, EDIT BY MILLER
;FIX ILRFU TO STORE ERJMP PC IN CORRECT PC WORD
;<3-MONITOR>PAGEM.MAC.561, 23-Jun-77 15:16:19, Edit by HESS
;FIX FAIL RETURN FROM SETP7A AT SETP7E TO UNLOCK CST
;<3-MONITOR>PAGEM.MAC.560, 21-Jun-77 20:05:07, EDIT BY CROSSLAND
;FIX INDEX AT MVPT SO LEFT HALF IS ZERO
;<3-MONITOR>PAGEM.MAC.559, 17-Jun-77 18:21:23, EDIT BY CROSSLAND
;FIX UP BAD INDEXES
;<3-MONITOR>PAGEM.MAC.558, 16-Jun-77 12:56:26, EDIT BY MILLER
;<3-MONITOR>PAGEM.MAC.557, 16-Jun-77 12:07:45, EDIT BY MILLER
;CLEAR PAGER IN UNLBTB
;<3-MONITOR>PAGEM.MAC.556, 9-Jun-77 23:03:46, EDIT BY MURPHY
;PERFORMANCE ENHANCEMENTS
;REMOVE AN "RVCF" CONDITIONAL
;<2-PERF>PAGEM.MAC.7, 31-May-77 16:09:58, EDIT BY MURPHY
;<2-PERF>PAGEM.MAC.4, 27-May-77 15:49:58, EDIT BY MURPHY
;<3-MONITOR>PAGEM.MAC.555, 3-Jun-77 17:13:42, EDIT BY MILLER
;MAKE RELP4 CALL UPDOFN IF OFN SHARE COUNT IS ZERO
;<3-MONITOR>PAGEM.MAC.554, 3-Jun-77 13:56:47, EDIT BY MILLER
;LET INDIRECT POINTERS TO OFN'S ALWAYS WORK
;<3-MONITOR>PAGEM.MAC.553, 2-Jun-77 11:44:28, Edit by MCLEAN
;FIX NICMG1 FOR USER REF TO PAGE IN NON 0 SECTION
;<3-MONITOR>PAGEM.MAC.552, 1-Jun-77 23:50:09, Edit by MCLEAN
;ADD LABEL PGRI2A FOR PARITY ERROR CHECK
;<3-MONITOR>PAGEM.MAC.551, 27-May-77 16:54:42, EDIT BY HURLEY
;FIX TO MAKE PAGEM RUN ON MODEL B MACHINE
;<3-MONITOR>PAGEM.MAC.550, 5-May-77 22:10:24, Edit by MCLEAN
;ADD MSEC1 TO MSECTB INSTEAD OF +1
;<3-MONITOR>PAGEM.MAC.549, 2-May-77 10:11:41, EDIT BY MILLER
;TCO 1787. FIX MRPT
;<3-MONITOR>PAGEM.MAC.548, 29-Apr-77 15:51:37, EDIT BY BOSACK
;TCO 1786 - DONT LEAVE PRIVATE WCPY PAGE LOCKED
;<3-MONITOR>PAGEM.MAC.547, 28-Apr-77 16:59:56, EDIT BY BOSACK
;TCO 1785 - FIX BUGHLT NOTOFN BY CALLING UPDOF0 WITH JUST OFN
;<3-MONITOR>PAGEM.MAC.546, 28-Apr-77 14:40:29, EDIT BY MILLER
;MAKE MLKCP DO NOSKD1 AND OKSKD1
;<3-MONITOR>PAGEM.MAC.545, 13-Apr-77 16:08:55, EDIT BY MILLER
;TCO 1780. KEEP LONG FILE PT'S AROUND AS LONG AS POSSIBLE
;<3-MONITOR>PAGEM.MAC.544, 11-Apr-77 13:44:49, EDIT BY MURPHY
;TCO #1776 - FLUSH CALL TO RPCST AT MOVDS1
;<3-MONITOR>PAGEM.MAC.543, 7-Apr-77 14:39:18, Edit by MCLEAN
;FIX ILRD TO GET FLAGS AND PC CORRECT
;<3-MONITOR>PAGEM.MAC.542, 6-Apr-77 08:36:55, EDIT BY MILLER
;MORE FIXES TO PGRTRP
;<3-MONITOR>PAGEM.MAC.541, 6-Apr-77 02:37:57, Edit by MCLEAN
;ADD EXADF1 SO SM10 CAN USE EXTENDED ADDRESSING FORMAT PAGEFAIL
;<3-MONITOR>PAGEM.MAC.540, 5-Apr-77 16:31:32, EDIT BY MILLER
;MAKE PGRTRP RUN NOINT FROM THE TOP
;<3-MONITOR>PAGEM.MAC.539, 27-Mar-77 00:46:22, Edit by MCLEAN
;ADD MVAGER
;<3-MONITOR>PAGEM.MAC.538, 26-Mar-77 19:08:14, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.537, 20-Mar-77 15:36:13, Edit by MCLEAN
;FIX SECG37 BUGCHECK AT SETIO1-2
;<3-MONITOR>PAGEM.MAC.536, 11-Mar-77 11:25:43, EDIT BY MILLER
;TCO 1755. PRESERVE PT MAPPING ON LONG FILE UNMAP
;<3-MONITOR>PAGEM.MAC.535, 9-Feb-77 16:15:35, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.534, 3-Feb-77 16:23:33, EDIT BY MURPHY
;<3-MONITOR>PAGEM.MAC.533, 3-Feb-77 12:26:26, Edit by HESS
;TCO 1726 - FIX TO EOF ON SIMULTANEOUS UPDATE PROBLEM
;<3-MONITOR>PAGEM.MAC.532, 3-Feb-77 11:24:30, EDIT BY MURPHY
;TCO #1729 - ALLOW MLKPG USE BY RES STG ALLOCATOR WHILE INSKED
;<3-MONITOR>PAGEM.MAC.531, 1-Feb-77 13:44:58, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.530, 29-Jan-77 17:38:11, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.529, 23-Jan-77 23:29:48, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.528, 23-Jan-77 23:25:53, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.527, 23-Jan-77 22:56:52, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.526, 19-Jan-77 19:31:47, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.525, 16-Jan-77 00:06:53, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.524, 15-Jan-77 22:19:24, EDIT BY HELLIWELL
;REMOVE ADJUSTMENT TO TOTRC FOR VB10C, PAGES ARE INCLUDED IN BALSHC
;<3-MONITOR>PAGEM.MAC.523, 15-Jan-77 17:52:02, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.522, 8-Jan-77 00:33:25, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.521, 6-Jan-77 15:01:30, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.520, 4-Jan-77 13:05:41, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.519, 4-Jan-77 12:58:27, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.518, 30-Dec-76 12:43:35, EDIT BY MILLER
;FIX TYPEO AT PREPG1
;<3-MONITOR>PAGEM.MAC.517, 29-Dec-76 22:19:01, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.516, 28-Dec-76 21:47:59, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.515, 27-Dec-76 17:35:21, EDIT BY HURLEY
;<3-MONITOR>PAGEM.MAC.514, 27-Dec-76 10:49:24, EDIT BY MILLER
;MAKE SURE XB NOT BEING WRITTEN AT RELOFN
;<2-MONITOR>PAGEM.MAC.489, 22-Dec-76 17:07:56, EDIT BY BOSACK
;TCO 1688 - RECREATE LOGIC TO MARK HARD ERRORS IN XB/FDBS
;<3-MONITOR>PAGEM.MAC.512, 22-Dec-76 14:08:47, Edit by HESS
;FIX SETP7A CALLS TO UNLOCK PAGE ON FAILURE ONLY IF PAGE LOCKED
;<3-MONITOR>PAGEM.MAC.511, 20-Dec-76 13:12:15, EDIT BY MILLER
;LOCK XB DURING RELOFN SO IT WON'T GET WRITTEN
;<3-MONITOR>PAGEM.MAC.510, 20-Dec-76 09:47:26, EDIT BY MILLER
;ADD UNLBTB ROUTINE
;<3-MONITOR>PAGEM.MAC.509, 19-Dec-76 00:05:35, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.508, 18-Dec-76 23:45:33, Edit by MCLEAN
;<2-MONITOR>PAGEM.MAC.485, 18-Dec-76 18:56:54, EDIT BY HELLIWELL
;MAYBE I GOT IT RIGHT THIS TIME
;<3-MONITOR>PAGEM.MAC.506, 18-Dec-76 17:08:11, EDIT BY HELLIWELL
;MOVE SETRVC CALL
;<3-MONITOR>PAGEM.MAC.505, 18-Dec-76 04:04:41, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.503, 17-Dec-76 00:48:40, Edit by MCLEAN
;<1MCLEAN>PAGEM.MAC.2, 16-Dec-76 16:22:53, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.503, 17-Dec-76 00:48:40, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.502, 16-Dec-76 00:31:58, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.501, 13-Dec-76 17:03:40, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.500, 9-Dec-76 13:13:39, EDIT BY MILLER
;LOCK STRLOK IN DDMP
;<3-MONITOR>PAGEM.MAC.499, 9-Dec-76 11:51:08, EDIT BY MILLER
;<3-MONITOR>PAGEM.MAC.498, 9-Dec-76 10:24:42, EDIT BY MILLER
;MOVE NOSKED IN RELOFN
;<3-MONITOR>PAGEM.MAC.497, 9-Dec-76 10:19:10, EDIT BY MILLER
;<3-MONITOR>PAGEM.MAC.496, 9-Dec-76 03:41:28, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.495, 8-Dec-76 16:57:24, EDIT BY MILLER
;<3-MONITOR>PAGEM.MAC.494, 8-Dec-76 16:53:48, EDIT BY MILLER
;FIX BUG IN MRKOFN
;<3-MONITOR>PAGEM.MAC.493, 7-Dec-76 10:43:41, Edit by HESS
;DO DISK SPACE CHECKING/ACCOUNTING AT SETP7
;<3-MONITOR>PAGEM.MAC.492, 3-Dec-76 00:48:37, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.491, 2-Dec-76 03:31:40, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.490, 1-Dec-76 21:23:57, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.489, 1-Dec-76 17:09:11, Edit by MCLEAN
;<2-MONITOR>PAGEM.MAC.475, 1-Dec-76 10:50:00, EDIT BY HELLIWELL
;UPDATE FREE CORE PAGES AT SETRVC
;<3-MONITOR>PAGEM.MAC.487, 30-Nov-76 16:10:16, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.486, 30-Nov-76 15:35:43, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.485, 30-Nov-76 01:32:22, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.484, 28-Nov-76 23:09:04, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.483, 28-Nov-76 13:01:16, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.482, 27-Nov-76 17:37:55, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.481, 27-Nov-76 03:11:29, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.480, 26-Nov-76 22:26:47, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.479, 26-Nov-76 22:24:01, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.478, 26-Nov-76 22:19:20, Edit by MCLEAN
;<3-MONITOR>PAGEM.MAC.477, 26-Nov-76 21:46:38, Edit by MCLEAN
;TCO 1669 EXTENDED ADDRESSING
;<2-MONITOR>PAGEM.MAC.474, 23-Nov-76 17:00:23, EDIT BY MILLER
;RECHECK OFN SLOT IF INVOFN HAD TO WAIT FOR WRITE TO COMPLETE
;<2-MONITOR>PAGEM.MAC.473, 23-Nov-76 09:30:44, EDIT BY MILLER
;AT RELP4, CALL RELOFN INSTEAD OF CLROFN
;<2-MONITOR>PAGEM.MAC.472, 15-Nov-76 02:35:20, EDIT BY BOSACK
;<2-MONITOR>PAGEM.MAC.471, 15-Nov-76 02:31:26, EDIT BY BOSACK
;<2-MONITOR>PAGEM.MAC.470, 15-Nov-76 02:07:51, EDIT BY BOSACK
;<2-MONITOR>PAGEM.MAC.469, 15-Nov-76 00:20:30, EDIT BY BOSACK
;<2-MONITOR>PAGEM.MAC.468, 14-Nov-76 23:20:06, EDIT BY BOSACK
;<2-MONITOR>PAGEM.MAC.467, 14-Nov-76 22:45:41, EDIT BY BOSACK
;<2-MONITOR>PAGEM.MAC.466, 14-Nov-76 18:26:46, EDIT BY BOSACK
;<2-MONITOR>PAGEM.MAC.465, 14-Nov-76 18:10:24, EDIT BY BOSACK
;<2-MONITOR>PAGEM.MAC.464, 14-Nov-76 16:55:20, EDIT BY BOSACK
;<2-MONITOR>PAGEM.MAC.463, 14-Nov-76 16:21:28, EDIT BY BOSACK
;<2-MONITOR>PAGEM.MAC.462, 14-Nov-76 14:00:06, EDIT BY BOSACK
;<2-MONITOR>PAGEM.MAC.461, 13-Nov-76 18:33:38, EDIT BY BOSACK
;<2BOSACK>PAGEM.MAC.4, 13-Nov-76 16:37:23, EDIT BY BOSACK
;<2BOSACK>PAGEM.MAC.3, 13-Nov-76 14:00:17, EDIT BY BOSACK
;<2BOSACK>PAGEM.MAC.2, 13-Nov-76 11:35:00, EDIT BY BOSACK
;<2BOSACK>PAGEM.MAC.1, 12-Nov-76 21:36:11, EDIT BY BOSACK
;ADD SPMQ LOGIC, REWORK RPLQ LOGIC
;<2-MONITOR>PAGEM.MAC.459, 12-Nov-76 10:52:45, Edit by HESS
;ADD ERROR CODES TO PAGER TRAPS AND STORE IN LSTERR
;<2-MONITOR>PAGEM.MAC.458, 12-Nov-76 10:21:43, EDIT BY MILLER
;MAKE INVOFN CALL SKPNWR BEFORE REMFP1 TO INSURE STORAGE WILL BE RELEASED
;<2-MONITOR>PAGEM.MAC.457, 11-Nov-76 15:31:32, EDIT BY MILLER
;CHANGE MRKOFN TO PRESERVE LOOP CONTROL OVER CALL TO LCKOFN
;<2-MONITOR>PAGEM.MAC.456, 8-Nov-76 14:03:25, EDIT BY MILLER
;MAKE TRP0 RESTART TRAP IF AGE IS NOT SPECIAL
;<2-MONITOR>PAGEM.MAC.455, 8-Nov-76 10:40:29, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.454, 8-Nov-76 10:29:08, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.453, 8-Nov-76 10:14:02, EDIT BY MILLER
;CLEAR OFN IN RELMPG IF SHARE COUNT GOES TO ZERO
;<2-MONITOR>PAGEM.MAC.452, 5-Nov-76 17:15:49, EDIT BY MILLER
;FIX UP STACK
;<2-MONITOR>PAGEM.MAC.451, 5-Nov-76 09:17:39, EDIT BY MILLER
;PUT IN BUGCHK IF SWPOUT FINDS AN OFN WITH A ZERO SHARE COUNT
;<2-MONITOR>PAGEM.MAC.450, 3-Nov-76 19:38:36, EDIT BY MILLER
;MAKE MRKOFN SKIP DISMOUNTED OFN'S
;<2-MONITOR>PAGEM.MAC.449, 3-Nov-76 18:29:08, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.448, 3-Nov-76 18:25:59, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.447, 3-Nov-76 18:21:34, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.446, 3-Nov-76 17:43:28, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.445, 3-Nov-76 12:44:17, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.444, 3-Nov-76 12:39:30, EDIT BY MILLER
;FIX INVOFN TO PROPERLY SCAN DISMOUNTED XB
;<2-MONITOR>PAGEM.MAC.443, 1-Nov-76 15:15:52, EDIT BY HELLIWELL
;DON'T CACHE PAGES USED BY RVCF
;<2-MONITOR>PAGEM.MAC.442, 26-Oct-76 15:07:15, EDIT BY MURPHY
;TCO #1629 - NOSKED AT MLKCP
;<2-MONITOR>PAGEM.MAC.441, 22-Oct-76 15:54:05, EDIT BY MILLER
;FIX MRPACS TO CHECK OFN ON EACH INDIRECT POINTER
;<2-MONITOR>PAGEM.MAC.440, 21-Oct-76 18:51:09, EDIT BY HURLEY
;FIX SWPOG3 BUG
;<2-MONITOR>PAGEM.MAC.439, 20-Oct-76 09:50:21, EDIT BY MILLER
;FIX SWAP OUT OF XB TO ALWAYS DO SWAP
;<2-MONITOR>PAGEM.MAC.438, 20-Oct-76 09:36:20, EDIT BY MILLER
;FIX SWPOUT TO PUT PAGE ON DISK WHEN SWAPPING SPACE LOW IF POSSIBLE
;<2-MONITOR>PAGEM.MAC.437, 19-Oct-76 18:49:06, EDIT BY MILLER
;FIX SWPOUT TO SWAP EVEN IF DRUM SPACE IS LOW
;<2-MONITOR>PAGEM.MAC.436, 16-Oct-76 09:56:42, EDIT BY MILLER
;REMOVE DDMP EDITS
;<2-MONITOR>PAGEM.MAC.435, 14-Oct-76 18:16:18, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.434, 14-Oct-76 16:24:38, EDIT BY MILLER
;MAKE DDMP CALL CHKBT FOR PS
;<2-MONITOR>PAGEM.MAC.433, 13-Oct-76 16:07:45, EDIT BY MILLER
;CHECK FOR OFN SHARE COUNT UNDERFLOW IN DWNSHR
;<2-MONITOR>PAGEM.MAC.432, 12-Oct-76 20:37:27, EDIT BY MILLER
;FIX RANGE CHECK CHECK FOR BIT TABLE IN FPTA
;<2-MONITOR>PAGEM.MAC.431, 12-Oct-76 18:26:46, EDIT BY MURPHY
;MORE FIXING OF NOINT, NOSKED IN PGRTRP
;<2-MONITOR>PAGEM.MAC.430, 11-Oct-76 15:05:44, Edit by MACK
;TCO 1586 - REPLACED DIAGNOSTIC AT PRT3: WITH NORMAL NOSKED
;PGU3: DOES OKSKED AND NOT OKINT AS WELL
;<2-MONITOR>PAGEM.MAC.429, 4-Oct-76 14:10:00, EDIT BY HURLEY
;<2-MONITOR>PAGEM.MAC.428, 1-Oct-76 12:04:33, EDIT BY MURPHY
;TCO #1556 - DON'T COUNT NEW PAGES IN DSKRD
;<2-MONITOR>PAGEM.MAC.427, 28-Sep-76 17:01:32, EDIT BY MILLER
;ONLY NEED TO CHECK FOR INDIRECT LOOPS IN MRPACS
;<2-MONITOR>PAGEM.MAC.426, 28-Sep-76 13:45:17, EDIT BY MILLER
;CLEAN UP CST0 CLEAN UP
;<2-MONITOR>PAGEM.MAC.425, 28-Sep-76 13:39:57, EDIT BY MILLER
;TCO 1550. HANDLE INDIRECT LOOPS CORRECTLY.
;<2-MONITOR>PAGEM.MAC.424, 22-Sep-76 16:16:08, EDIT BY BOSACK
;TCO 1536 - CST0 DATABASE CLEANUP
;<2-MONITOR>PAGEM.MAC.423, 13-Aug-76 18:18:20, Edit by HESS
;REMOVE ASFOFN AND ASLOFN , MOVE THEM TO DISC
;<2-MONITOR>PAGEM.MAC.422, 12-Aug-76 14:11:03, EDIT BY MURPHY
;TCO #1482
;<2-MONITOR>PAGEM.MAC.421, 12-Aug-76 13:58:30, EDIT BY MURPHY
;TCO #1491 - INIT PCU FLAG IN PGRTRP CODE
;<2-MONITOR>PAGEM.MAC.420, 11-Aug-76 14:36:23, Edit by HESS
;CHECK FOR ERJMP/ERCAL BEFORE POSTING INTERUPT AT ILRF
;<2-MONITOR>PAGEM.MAC.419, 9-Aug-76 16:17:15, EDIT BY MURPHY
;<2-MONITOR>PAGEM.MAC.418, 5-Aug-76 21:52:44, Edit by HESS
;<2-MONITOR>PAGEM.MAC.417, 5-Aug-76 12:30:45, EDIT BY MURPHY
;TCO #1482 - ADJUST FKWSS AT NICMG
;<2-MONITOR>PAGEM.MAC.416, 5-Aug-76 12:13:44, EDIT BY MURPHY
;TCO #1479 - BALANCE SET PARTITIONING
;<2-MONITOR>PAGEM.MAC.414, 4-Aug-76 13:08:07, Edit by HESS
;<HESS>PAGEM.MAC.11, 3-Aug-76 14:59:21, Edit by HESS
;TCO 1478 - QUOTA CHECKING
;<2-MONITOR>PAGEM.MAC.412, 28-Jul-76 13:49:24, EDIT BY MILLER
;MAKE PMAP TO DISK SWAP OUT TO DISK
;<1MILLER>PAGEM.MAC.1, 26-Jul-76 15:20:06, EDIT BY MILLER
;MAKE RELMI1 MOVE PAGE TO THE DISK IF POSSIBLE
;<2-MONITOR>PAGEM.MAC.410, 21-Jul-76 17:28:00, EDIT BY MILLER
;FIX UPDPGS WHEN XB HAS IMMEDIATE POINTER TO DRUM
;<2-MONITOR>PAGEM.MAC.409, 21-Jul-76 14:13:09, EDIT BY MILLER
;ADD MRKOFN ROUTINE
;<2-MONITOR>PAGEM.MAC.408, 21-Jul-76 13:13:06, EDIT BY MILLER
;FIX MOVDSK TO USE RPCST
;<2-MONITOR>PAGEM.MAC.407, 21-Jul-76 11:11:51, EDIT BY MILLER
;FIX INVOFN . FIX RELMPG TO RELEASE OFN IF DISMOUNTED
;<2-MONITOR>PAGEM.MAC.406, 20-Jul-76 21:52:44, EDIT BY MILLER
;ADD CAUTION COMMENT TO MOVDSK
;<2-MONITOR>PAGEM.MAC.405, 20-Jul-76 21:25:07, EDIT BY MILLER
;FIX RELOFN TO CALL MOVDSK WITH OFN IN LH OF 4
;<1MILLER>PAGEM.MAC.6, 20-Jul-76 20:08:23, EDIT BY MILLER
;FIX MOVDSK TO PROPERLY DELETE IN CORE PAGES
;<1MILLER>PAGEM.MAC.5, 20-Jul-76 15:43:20, EDIT BY MILLER
;<1MILLER>PAGEM.MAC.4, 20-Jul-76 13:27:24, EDIT BY MILLER
;ADD TEST FOR FILDUD IN ASOFN AND SET IN SPTH IF REQUESTED
;<1MILLER>PAGEM.MAC.3, 19-Jul-76 16:25:41, EDIT BY HALL
;FIX ASOFN TO WORK IF OFN IS LOCKED
;<1MILLER>PAGEM.MAC.2, 19-Jul-76 12:38:00, EDIT BY MILLER
;<1MILLER>PAGEM.MAC.1, 19-Jul-76 12:23:14, EDIT BY MILLER
;FIX SWAPPING
;<1MILLER>PAGEM.MAC.5, 13-Jul-76 20:45:08, EDIT BY MILLER
;REMOVE ARCHAIC COMMENT LINE
;<1MILLER>PAGEM.MAC.4, 7-Jul-76 17:44:49, EDIT BY MILLER
;<1MILLER>PAGEM.MAC.3, 7-Jul-76 12:03:23, EDIT BY MILLER
;MORE CHANGES TO REDUCE STACK USAGE IN PAGE FAULT CODE
;<1MILLER>PAGEM.MAC.2, 7-Jul-76 11:26:55, EDIT BY MILLER
;CHANGE XGC TO SAVE AND RESTORE Q1 AND Q2
;<1MILLER>PAGEM.MAC.1, 7-Jul-76 10:18:02, EDIT BY MILLER
;CHANGE PGRTRP CODE SO IT USES 2 FEWER WORDS OF STACK PER FAULT.
;<2-MONITOR>PAGEM.MAC.400, 6-Jul-76 19:16:55, EDIT BY HURLEY
;UNDO TCO 1460 AFTER MUCH THOUGHT
;<2-MONITOR>PAGEM.MAC.399, 6-Jul-76 15:46:47, EDIT BY MILLER
;MAKE CHKDMO INTERNAL
;<2-MONITOR>PAGEM.MAC.398, 6-Jul-76 14:36:49, EDIT BY MILLER
;ADD CALL TO CHKDMO AT MSCANP
;<2-MONITOR>PAGEM.MAC.397, 6-Jul-76 11:36:50, EDIT BY MILLER
;<1MILLER>PAGEM.MAC.17, 5-Jul-76 10:36:56, EDIT BY MILLER
;ADD CHKDMO CHECKING TO VARIOUS ROUTINES
;<1MILLER>PAGEM.MAC.16, 1-Jul-76 16:51:07, EDIT BY MILLER
;FIX VERPT AND PTVER FOR 0,,OFN .
;<1MILLER>PAGEM.MAC.15, 1-Jul-76 11:50:52, EDIT BY MILLER
;<1MILLER>PAGEM.MAC.14, 1-Jul-76 11:47:11, EDIT BY MILLER
;<1MILLER>PAGEM.MAC.13, 1-Jul-76 10:49:01, EDIT BY MILLER
;<1MILLER>PAGEM.MAC.12, 1-Jul-76 10:20:42, EDIT BY MILLER
;<1MILLER>PAGEM.MAC.11, 1-Jul-76 09:19:33, EDIT BY MILLER
;FIX SETMPG,MSETMP,SETPT,MSETPT AND FRIENDS TO HANDLE DISMOUNTED OFNS
;<1MILLER>PAGEM.MAC.10, 30-Jun-76 18:49:30, EDIT BY MILLER
;<1MILLER>PAGEM.MAC.9, 30-Jun-76 18:21:12, EDIT BY MILLER
;<1MILLER>PAGEM.MAC.8, 30-Jun-76 12:16:38, EDIT BY MILLER
;MORE FIXES TO INVOFN
;<1MILLER>PAGEM.MAC.7, 30-Jun-76 12:02:12, EDIT BY MILLER
;<1MILLER>PAGEM.MAC.6, 30-Jun-76 11:57:26, EDIT BY MILLER
;FIX DELETE OF LOCAL STORAGE IN INVOFN
;<1MILLER>PAGEM.MAC.5, 30-Jun-76 11:48:37, EDIT BY MILLER
;MAKE INVOFN SWAPPABLE
;<1MILLER>PAGEM.MAC.4, 30-Jun-76 11:14:34, EDIT BY MILLER
;CHECK FOR DISMOUNTED OFN IN GETTPD PAGE FAULT RESOLUTION
;<1MILLER>PAGEM.MAC.3, 30-Jun-76 10:49:09, EDIT BY MILLER
;<1MILLER>PAGEM.MAC.2, 30-Jun-76 10:32:42, EDIT BY MILLER
;<1MILLER>PAGEM.MAC.1, 30-Jun-76 09:51:39, EDIT BY MILLER
;ADD INVOFN ROUTINE TO MARK OFN AS DISMOUNTED
;<2-MONITOR>PAGEM.MAC.394, 29-Jun-76 12:53:37, EDIT BY MILLER
;FIX PRELOADING TO IGNORE INDIRECT POINTERS
;<2-MONITOR>PAGEM.MAC.35, 21-Jun-76 15:02:22, EDIT BY MILLER
;FIX UPSHR AND FRIENDS
;<1B-MONITOR>PAGEM.MAC.390, 19-MAY-76 17:34:13, EDIT BY MILLER
;TCO 1302. FIX PREPG.
;<1B-MONITOR>PAGEM.MAC.391, 28-APR-76 17:44:58, EDIT BY MILLER
;TCO 1268. UNLOCK PAGE AT SETP7X
;<1B-MONITOR>PAGEM.MAC.390, 27-APR-76 11:59:39, EDIT BY MILLER
;TCO 1262. ALLOW PAGE CREATES IF NOINT
;<1B-MONITOR>PAGEM.MAC.389, 13-APR-76 19:00:16, EDIT BY BOSACK
;<2-MONITOR>PAGEM.MAC.33, 18-Jun-76 15:04:33, EDIT BY MILLER
;USE BTBORA IN PGRINI
;<1MILLER>PAGEM.MAC.8, 4-JUN-76 16:21:21, EDIT BY MILLER
;<1MILLER>PAGEM.MAC.7, 3-JUN-76 19:42:09, EDIT BY MILLER
;<1MILLER>PAGEM.MAC.6, 2-JUN-76 15:29:47, EDIT BY MILLER
;EXPAND STRUCTURE NUMBER TO 6 BITS
;<1MILLER>PAGEM.MAC.5, 2-JUN-76 11:18:11, EDIT BY MILLER
;<1MILLER>PAGEM.MAC.4, 2-JUN-76 11:09:33, EDIT BY MILLER
;<1MILLER>PAGEM.MAC.3, 2-JUN-76 11:04:20, EDIT BY MILLER
;<1MILLER>PAGEM.MAC.2, 1-JUN-76 14:00:19, EDIT BY MILLER
;<1MILLER>PAGEM.MAC.1, 1-JUN-76 13:33:56, EDIT BY MILLER
;ADD SPTO TABLE
;<2-MONITOR>PAGEM.MAC.31, 30-MAY-76 16:27:35, EDIT BY HALL
;MOVED FROM HALL
;<HALL>PAGEM.MAC.3, 30-MAY-76 09:40:30, EDIT BY MILLER
;FIX MRPACS NOT TO CREATE PT FOR UNMAPPED BITTABLE
;<HALL>PAGEM.MAC.2, 28-MAY-76 16:48:04, EDIT BY MILLER
;<HALL>PAGEM.MAC.1, 28-MAY-76 11:51:16, EDIT BY HALL
;<1MILLER>PAGEM.MAC.1, 28-MAY-76 09:54:45, EDIT BY MILLER
;IMPROVE BIT TABLE HANDLING
;<2-MONITOR>PAGEM.MAC.30, 19-MAY-76 17:34:39, EDIT BY MILLER
;TCO 1302. FIX PREPG
;<2-MONITOR>PAGEM.MAC.29, 11-MAY-76 18:30:20, EDIT BY MILLER
;ADD CHECK FOR VALID STRUCTURE NUMBER IN ASOFN
;<2-MONITOR>PAGEM.MAC.28, 28-APR-76 17:46:13, EDIT BY MILLER
;TCO 1268. UNLOCK PAGE AT SETP7X
;<2-MONITOR>PAGEM.MAC.27, 27-APR-76 12:00:45, EDIT BY MILLER
;TCO 1262. ALLOW PAGE CREATE IF NOINT
;<2-MONITOR>PAGEM.MAC.26, 20-APR-76 18:58:49, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.25, 20-APR-76 15:28:28, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.24, 20-APR-76 14:36:48, EDIT BY MILLER
;ADD SWPIN1 FOR DSKAL1 TO CALL
;<2-MONITOR>PAGEM.MAC.23, 20-APR-76 13:22:31, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.22, 20-APR-76 13:00:41, EDIT BY MILLER
;REPLACE SKIPG NTRACK WITH SKIPG NSSUN
;<2-MONITOR>PAGEM.MAC.21, 20-APR-76 11:46:01, EDIT BY MILLER
;ADD CALL TO GSTRPG AT NIC64 TO GET ALLOCATION OF STRUCTURE
;<2-MONITOR>PAGEM.MAC.20, 20-APR-76 10:37:16, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.19, 19-APR-76 17:43:35, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.18, 19-APR-76 17:38:00, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.17, 19-APR-76 16:08:07, EDIT BY HALL
;<2-MONITOR>PAGEM.MAC.16, 19-APR-76 15:56:04, EDIT BY HALL
;<2-MONITOR>PAGEM.MAC.15, 18-APR-76 18:20:03, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.14, 18-APR-76 13:35:04, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.13, 16-APR-76 09:53:40, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.12, 15-APR-76 19:42:25, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.11, 15-APR-76 16:35:41, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.10, 15-APR-76 13:44:09, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.9, 15-APR-76 12:53:00, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.8, 15-APR-76 09:30:59, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.7, 14-APR-76 20:20:19, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.6, 14-APR-76 16:31:06, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.5, 14-APR-76 11:53:13, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.4, 14-APR-76 10:29:16, EDIT BY MILLER
;<2-MONITOR>PAGEM.MAC.3, 12-APR-76 13:07:00, EDIT BY HALL
;<2-MONITOR>PAGEM.MAC.2, 5-APR-76 20:10:40, EDIT BY HALL
;<2-MONITOR>PAGEM.MAC.1, 5-APR-76 19:27:45, EDIT BY MILLER
;ADDED MMAPWP AND MMAPWE
;<1MONITOR>PAGEM.MAC.388, 29-MAR-76 15:18:25, EDIT BY MURPHY
;TCO #1222 - DETECT TOO MUCH CORE
;<1MONITOR>PAGEM.MAC.387, 5-MAR-76 12:43:00, EDIT BY MURPHY
;<1MONITOR>PAGEM.MAC.386, 1-MAR-76 11:45:38, EDIT BY MURPHY
;MORE #1097
;<1MONITOR>PAGEM.MAC.385, 1-MAR-76 10:18:04, EDIT BY KIRSCHEN
;TCO # 1130 - PRESERVE Q AC'S AT FPTAQ
;<1MONITOR>PAGEM.MAC.384, 26-FEB-76 17:27:12, EDIT BY MURPHY
;<2MONITOR>PAGEM.MAC.383, 26-FEB-76 10:53:19, EDIT BY MURPHY
;<2MONITOR>PAGEM.MAC.382, 16-FEB-76 16:28:18, EDIT BY MURPHY
;TCO #1097 - INCREASE FREE MONITOR VAS
;<2MONITOR>PAGEM.MAC.380, 10-FEB-76 11:14:15, EDIT BY MURPHY
;<2MONITOR>PAGEM.MAC.379, 6-FEB-76 18:06:27, EDIT BY MURPHY
;TCO #1064 - FIX MRPACS
;<2MONITOR>PAGEM.MAC.378, 19-JAN-76 12:22:24, EDIT BY MURPHY
;<2MONITOR>PAGEM.MAC.377, 9-JAN-76 15:36:30, EDIT BY MURPHY
;<2MONITOR>PAGEM.MAC.373, 19-DEC-75 16:39:58, EDIT BY MURPHY
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1977 BY DIGITAL EQUIPMENT CORPORATION
SEARCH PROLOG
TTITLE PAGEM
EXTN <SPCRES,MEMSTR,CLRMPE>
DEFAC (FX,Q3) ;FORK INDEX
;STORAGE
RS BTSTRT,1 ;START OF BITTABLE
RS BTEND,1 ;END OF BITTABLE
RS PAGDIF,1 ;COUNT OF NEW PAGES IN THE SYSTEM
RS SWPCOR,1 ;FIRST PAGE USED FOR SWAPPING
RS NHIPG,1 ;HIGEST PAGE USED BY SWAPPER
RS SPTC,1 ;COUNT OF SPT (EXCLUDING OFN) ENTRIES IN SPT
RS NOF,1 ;COUNT OF ENTRIES IN OFN PART OF SPT
RS FRESPT,1 ;FREE SPT LIST
RS MAXSPL,1 ;MAX NUMBER OF PROBES TO SPTH
RS MMSPTN,1 ;OFN OF MONITOR MAP
RS LOKPGS,1 ;COUNT OF LOCKED PAGES, VIA MLKPG
RS LOKSUM,1 ;NET NUMBER OF LOCKS, MLKPG-MULKPG
RS GNPBAS,1 ;AMOUNT BY WHICH NPMAX REDUCED
RS DDTIME,1 ;TIME NEXT DDMP DUE
RS IOIP,1 ;SWAP WRITES IN PROGRESS
RS DRMIN0,1 ;DRUM SPACE LEVEL FOR DDMP ACTION
RS DRMLV0,1 ;DRUM SPACE LEVEL FOR NO NEW PRIV PAGES
RS PRELRQ,1 ;PRELOADING SWAPIN IF NON-0
RS DELPGQ,1 ;QUEUE OF DELETED PAGES
RS DWRCFL,1 ;FLAG - FORK WAITING FOR WRITE COMPLETION
RS JOBBAS,1 ;JOB BASE (SPT INDEX)
RS PSBBAS,1 ;FORK BASE (SPT INDEX)
RS BTBBAS,1 ;BIT TABLE BASE
RS NBADCP,1 ;NUMBER CORE PAGES DECLARED BAD
RS BSHC1,1 ;GCCOR - NEW BALSHC
RS GCCLPG,1 ;GCCOR - LAST PAGE COLLECTED
;VARIABLES FOR SWPOM (SWPOMI, SWPOML, SWPOMG)
RS SWPLST,1 ;LIST OF PAGES FOR SWAP
RS SWPLSI,1 ;IN PTR TO SWAP LIST
RS SWPRC0,1 ;COUNT OF PAGES ON LIST
RS SWPDAD,1 ;NEXT SEQUENTIAL SWAP ADDRESS TO USE
SPC0:: EXP <SSPT-NOFN-400>*5/6 ;SPT LEVEL FOR USING INDIRECT PTRS
SPC1:: EXP SSPT-NOFN-100 ;SPT LEVEL FOR NO NEW JOBS
SPC2:: EXP SSPT-NOFN-10 ;SPT LEVEL FOR NO NEW FORKS
;INDEX BLOCK DEFINTIONS
XBBAT==1B0 ;BAT BIT
XBBWRD==4 ;WORD FOR XBBAT
;CANONICAL POINTERS
IMMPTR::FLD(IMMCOD,PTRCOD)+PTWR+PTCACH
SHRPTR::FLD(SHRCOD,PTRCOD)+PTWR+PTCACH
INDPTR::FLD(INDCOD,PTRCOD)+PTWR+PTCACH
MAXIND==1000 ;MAXIMUM INDIRECT POINTERS ALLOWED
; BEFORE MONITOR GIVES UP
;BOUNDARY TO ARTIFICIALLY LIMIT CORE
NLOWPG:: 0 ;PAGES BELOW HERE CONSIDERED NXM
;ADMINISTRATIVE LIMIT OF PROGRAM (FORK) SIZE. ACTUAL LIMIT MAY BE LOWER
;IF INSUFFICIENT CORE. SYSTEM ADMINISTRATOR MAY ADJUST THIS PARAMETER
;TO LIMIT SIZE OF LARGE JOBS THEREBY ALLOWING MORE IN CORE.
PGMMAX:: MAXFKS ;FORK SIZE LIMIT SPECIFIED IN PARAMS
IPTIM:: IPTIMF ;FLAG FOR PAGE TRAP TIME FROM PARAMS
GCMIN0==^D64 ;MIN PAGES FOR GCCOR TO COLLECT
NRPMX: MINNR+2 ;RPLQ MIN, SHOULD BE .G. MINNR
;BOUNDARIES SET BY POSTLD
MONCOR::0 ;NUMBER PAGES OF RES MON
SWPCP0::0 ;FIRST PAGE OF REAL CORE FOR SWAPPING
;INITIALIZATION, SPT, CST, ETC.
;ASSUMES PAGING ALREADY TURNED ON
PGRINI::ACVAR <Q1>
SETZM SPTC
SETZM NOF
SETZM MAXSPL
MOVE 1,[DST,,DST+1] ;INIT DST TO -1
SETOM -1(1)
BLT 1,DST+NDST-1
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 JOB BASE REG
MOVEM T1,JOBBAS
CALL UPSHR ;INIT SHARE COUNT
CALL ASSPT ;ASSIGN SPT SLOT FOR FORK BASE REG
MOVEM T1,PSBBAS
CALL UPSHR ;INIT SHARE COUNT
CALL ASSPT ;GET ANOTHER ONE
MOVEM T1,BTBBAS ;MAKE THIS THE BIT TABLE BASE
MOVX T2,UAAB ;SET UP ACCESS TO NULL
MOVEM T2,SPT(T1) ;TO THE SPT
CALL UPSHR ;INIT SHARE COUNT
SETZM SPTH(T1) ;SET NO CORRESPONDENCE
MOVE T1,[MMAP,,MMAP+1] ;CLEAR MONITOR MAP
SETZM MMAP
BLT T1,MMAP+PGSIZ-1
MOVSI T1,-MAXSEC ;SET UP TO INIT FPTA TARNSFER TABLE
MOVE T2,[IFIW!ILLFPT] ;ASSUME ALL ARE ILLEGAL
PGR00: MOVEM T2,FPTABL(T1) ;INIT THIS ENTRY
AOBJN T1,PGR00 ;DO ALL OF THE TABLE
CALL ASSPT ;ASSIGN SPT SLOT FOR MMAP
MOVE T2,SHRPTR ;CONSTRUCT SHARE PTR TO MMAP
STOR T1,SPTX,T2
MOVEM T2,MSECTB ;SETUP POINTER FOR MON SECTION 0
MOVE T3,[IFIW!FPTA0] ;ROUTINE FOR MONITOR SECTION
MOVEM T3,FPTABL ;SET UP SECTION 0
SKIPN [MSEC1] ;DOING EXTENDED ADDRESSING?
JRST PGRI10 ;NO. SKIP EPT SET UP THEN
MOVEM T2,MSECTB+MSEC1 ;SET UP POINTER FOR MON SEC1 ALSO
MOVEM T3,FPTABL+MSEC1 ;INIT FOR OTHER CODE SECTION
MOVE T3,INDPTR ;GET INDIRECT POINTER
MOVE T2,PSBBAS ;GET BASE POINTER
STOR T2,SPTX,T3 ;STORE SPT POINTER
MOVEI T2,DRMAP ;FIND INDEX
STOR T2,IPPGN,T3
MOVEM T3,MSECTB+DRSECN
MOVE T4,[IFIW!FPTA6] ;DISPATCH FOR DIRECTORY
MOVEM T4,FPTABL+DRSECN ;SET IT UP
MOVEI T2,IDXMAP ;SET UP POINTER TO IDXTAB
STOR T2,IPPGN,T3
MOVEM T3,MSECTB+IDXSEC ;SET IDX SECTION
MOVE T4,[IFIW!FPTA7] ;IDX ADDRESS
MOVEM T4,FPTABL+IDXSEC ;TO THE TABLE
MOVE T4,[IFIW!FPTA8] ;BIT TABLE HANDLER
MOVEM T4,FPTABL+BTSEC ;TO THE TABLE
MOVE T4,[IFIW!FPTAAN] ;APRPANET BUFFER HANDLER
SKIPE [ANBSEC] ;NO SPECIAL SECTION FOR NET
MOVEM T4,FPTABL+ANBSEC ;TO THE TABLE
PGRI10: MOVEI 2,MMAP/PGSIZ ;GET ADDRESS FIELD
MOVEM 2,SPT(1)
CALL UPSHR ;SET SHARE COUNT
MOVEM 1,MMSPTN
MOVSI 2,0(1)
SETZ 1, ;START WITH CORE PAGE 0
PGRI1: MOVX T4,PSASM ;INIT CST'S
MOVEM T4,CST0(T1)
MOVX T4,UAAB ;SET BACKUP ADR TO UNASSIGNED
MOVEM T4,CST1(T1)
MOVEM T2,CST2(T1)
MOVX T4,<FLD OFNUL,CSTOFK>
MOVEM T4,CST3(T1) ;MAKE PAGE UNASSIGNED
MOVE T4,IMMPTR
STOR 1,STGADR,4 ;MAKE MAPPED MON EQUIV TO PHYS CORE
MOVEM 4,MMAP(2)
ADDI 1,1
CAMGE 1,SWPCOR ;FILL TO END OF RES MON
AOJA 2,PGRI1
MOVEI T2,MMAP/PGSIZ ;CORE PAGE OF MMAP
OPSTRM <ADDM T1,>,PLKCNT,(T2) ;NOTE CORE PTRS IN MMAP
; ..
;SET UP LOCATIONS FOR BIT TABLE
CALL INITBT ;SETUP INITIAL BTB SIZES
SKIPE EXADDR ;IF EXTENDED ADDRESSING MAP NOT IN MMAP
JRST PGRIBT
MOVE T1,INDPTR ;GET INDIRECT POINTER FOR MAP
MOVE T2,BTBBAS ;THE SPTN FOR THE BITTABLE
STOR T2,SPTX,T1 ;FORM REST OF POINTER WORD
PGRI77: MOVEM T1,MMAP(T4) ;STORE NEXT POINTER
ADD T1,[<FLD 1,IPPGN>] ;NEXT PAGE
AOBJN T4,PGRI77 ;DO ALL OF ADDRESS SPACE
;SETUP JOB COMMON STORAGE (JSBPG TO JSBLST INCLUSIVE) TO INDIRECT JOBBAS
PGRIBT: MOVE T4,[XWD JSBPG-JSLST,JSBPG]
MOVE T1,INDPTR ;CONSTRUCT INDIRECT PTR
MOVE T2,JOBBAS
STOR T2,SPTX,T1
MOVEI T2,JOBMAP-JSBPGA
STOR T2,IPPGN,T1
PGRI3: MOVEM T1,MMAP(T4) ;STORE IN MON MAP
AOS T2 ;BUMP POINTER
STOR T2,IPPGN,T1
AOBJN T4,PGRI3 ;DO ALL JOB AREA
;SETUP PSB (PSSPS TO PSB1) INDIRECT PSBBAS
MOVE T4,[XWD PSSPS-PSB1-1,PSSPS]
MOVE T2,PSBBAS ;CONSTRUCT INDIRECT PTR
STOR T2,SPTX,T1
MOVEI T2,PSBMAP-PSBPGA
STOR T2,IPPGN,T1
PGRI5: MOVEM T1,MMAP(T4) ;STORE IN MON MAP
AOS T2 ;BUMP POINTER
STOR T2,IPPGN,T1
AOBJN T4,PGRI5 ;DO ALL PROCESS AREA
MOVE T1,SHRPTR ;SETUP SHARE POINTER TO PSB AND JSB
MOVE T2,PSBBAS ; VIA SPECIAL BASE ADDRESS WORDS
STOR T2,SPTX,T1
MOVEM T1,MMAP+PSBPG
MOVE T2,JOBBAS
STOR T2,SPTX,T1
MOVEM T1,MMAP+JSBPG
;SET UP ARPANET BUFFER SECTION PAGE MAP
SKIPE [ANBSEC] ;NO SPECIAL SECTION FOR NET
SKIPG [NHOSTS] ;IS IT AN ARPA SYSTEM
JRST PGRI8 ;NO SKIP SET UP
CALL ASSPT ;GET AN SPT SLOT
MOVE T2,SHRPTR ;SET UP SHARE PONITER FOR PAGE MAP
STOR T1,SPTX,T2
MOVEM T2,MSECTB+ANBSEC ;SET UP POINTER FOR ARPANET BUFFER SEC.
MOVEI T2,NTBFIX/PGSIZ ;GET PAGE NUMBER OF MAP PAGE
MOVEM T2,SPT(T1) ;SET UP SPT POINTER
CALL UPSHR ;SET SHARE COUNT
PGRI8: CALL SETPSK ;SET TO SCHED CONTEXT
CALL PGRON ;TURN ON PAGING
; ..
;FIND ALL EXISTENT PHYSICAL CORE AND CONSTRUCT RPLQ
MOVE T1,SWPCOR
SUB T1,MONCOR ;INIT TOTRC TO COUNT OF
MOVEM T1,TOTRC ;CONDITIONALLY SWAPPABLE PAGES
SETZM GNPBAS ;INIT OVERHEAD PAGES
SETZM NSPMQ ;INITIALIZE SPMQ
MOVSI T1,SPMQ ;SET TAIL POINTER
MOVEM T1,SPMQ ; ...
SETOM SPMLCK ;SPMQ USER INTERLOCK
SETOM SPMONR ;FORK OWNING SPMLCK
SETZM NRPLQ
CONO APR,APFCLR+APNXM+APRCHN ;CLEAR NXM
MOVE Q1,SWPCOR
MOVE 2,[XWD RPLQ,RPLQ]
MOVEM 2,RPLQ ;REPLACEMENT QUEUE EMPTY
PGRI2: MOVX T2,PSASM ;SET LEGAL AGE FOR TEST REFERENCE
MOVEM T2,CST0(Q1)
SETZM CST1(Q1) ;CLEAR CST ENTRIES
SETZM CST2(Q1)
SETZM CST3(Q1)
MOVE T1,Q1 ;GET PHYS PAGE NUMBER
CALL MAPRCA ;MAP IT
PGRI2A::MOVE T2,0(T1) ;TRY TO REFERENCE IT
CONSZ APR,APNXM ;NXM?
JRST PGRI6 ;YES
MOVE T2,1(T1) ;TRY 3 OTHER WORDS IN CASE INTERLEAVED
MOVE T2,2(T1)
MOVE T2,3(T1)
PGRI6:: CAML Q1,NLOWPG ;EXCLUDE PAGES BELOW BOUNDARY
CONSZ APR,APNXM ;NXM?
JRST [ CONO APR,APFCLR+APNXM+APRCHN ;YES, CLEAR FLAG
MOVX T2,<FLD(PSDEL,CSTAGE)+FLD(PSTOFL,CSTPST)>
MOVEM T2,CST0(Q1) ;CALL IT DELETED
MOVE T1,Q1 ;AND PLACE ON SPMQ
CALL ONSPMQ ;LIKE ONRQ, RETURNS
PIOFF ;PION
JRST PGRI4]
SETZM CST0(Q1) ;NO, PAGE EXISTS
MOVEM Q1,NHIPG ;REMEMBER HIGHEST PAGE FOUND
MOVE T1,Q1
CLRMPE ;CLEAR ANY PARITY ERROR FROM SCAN
CALL ONRQ ;PUT PAGE ON REPLACABLE QUEUE
PIOFF
AOS TOTRC ;COUNT PAGES OF CORE FOUND
PGRI4: CAIGE Q1,MAXCOR-1 ;CHECK ALL POSSIBLE CORE
AOJA Q1,PGRI2
CALL MEMSTR ;SET UP MEM CONTROLLERS IF APPROPRIATE
; ..
;SETUP VARIOUS CONSTANTS FOR CORE MGT
CALL MEMMGT ;SET UP PAGING PARAMETERS
CALL AJBPAR ;COMPUTE BALSET PARTITIONING
MOVEI 1,100
CALL LDAGER ;LOAD AGE REGISTER
MOVE Q1,MONCOR ;LOCK POSSIBLY SWAPPABLE PAGES
PGRI7: MOVE T1,Q1
CALL MLKCP
AOS Q1
CAMGE Q1,SWPCOR ;PAGES FROM MONCOR TO SWPCOR
JRST PGRI7
PGRRST::CALL PGRON
CALL PGRCLD
RET
;ROUTINES TO COMPUTE PAGE MANAGEMENT PARAMETERS
MEMMGT: MOVE T1,TOTRC ;TOTAL REAL MEM FOUND
SUB T1,NRPMX
MOVEM T1,MAXNR ;MAX VALUE OF SUMNR
SUBI T1,10
SKIPE T2,PGMMAX ;CUSTOMER-SPECIFIED LIMIT?
JRST [ CAMLE T2,T1 ;YES, BELOW CORE LIMIT?
MOVE T2,T1 ;NO, MUST USE CORE LIMIT
MOVEM T2,NPMAX ;USE FOR BOTH REGULAR AND SMALL LIMIT
MOVEM T2,SNPMAX
JRST PGRI9]
MOVEM T1,NPMAX
CAIL T1,140 ;REASONABLY LARGE SYSTEM?
SUBI T1,40 ;YES, SET SNPMAX 16K SMALLER
MOVEM T1,SNPMAX ;SMALL NPMAX
PGRI9: MOVE T1,NRPMX ;INIT NRPMIN
MOVEM T1,NRPMIN
MOVE T1,TOTRC
LSH T1,-3
CAIL T1,NBP
MOVEI T1,NBP-1
MOVEM T1,MAXBP
RET ;DONE
;SET SWAP SPACE PARAMETERS - CALLED FROM DRMINI AFTER DRUM SPACE KNOWN
;ALSO CALLED WHEN NEW PAGES APPAEAR IN SYSTEM
; A/ NUMBER PAGES AVAILABLE FOR SWAPPING
SETSSP::MOVE B,TOTRC ;PREVENT NEW PRIVATE PAGES
MOVEM B,DRMLV0 ;WHEN FREE DRUM EQUALS TOTAL CORE
IMULI B,2 ;DOUBLE THAT LEVEL
MOVEM B,DRMIN0 ;TO CAUSE DDMP ACTIVITY
RET
;INIT NEW FORK
FKSETP::MOVE T2,SHRPTR ;CONSTRUCT SHARE PTR
LOAD T1,FKUPT ;GET UPT IDENT
STOR T1,SPTX,T2 ;CONSTRUCT SHARE PTR
MOVEM T2,PSBM0+UPTPG ;MAP UPT
MOVEM T2,USECTB ;SET AS USER SECTION 0 ALSO
LOAD T1,FKPSB
STOR T1,SPTX,T2 ;BUILD SHARE PTR TO PSB
MOVEM T2,PSBM0+PSBPG ;SET IT IN MON MAP
LOAD T1,FSSPTN ;GET STACK PAGE I.D.
STOR T1,SPTX,T2 ;MAKE A SHARE POINTER TO IT
MOVEM T2,PSBM0+PSB1 ;POINT TO THE STACK PAGE FROM THE UPT
RET
;ROUTINE TO CHECK IF A PAGE CAN BE USED (DOESNT NXM)
;T1/ PHYSICAL PAGE
; CALL CHKPAG
;RETURNS+1(FAILURE):
; PAGE NOT USEABLE
;RETURNS+2(SUCCESS):
; PAGE APPEARS OK
CHKPAG: PIOFF ;PREVENT ANY INTERRUPTS
PUSH P,CST0(T1) ;SAVE PRESENT STATE
PUSH P,T1 ;SAVE PAGE NUMBER AS WELL
MOVX T2,PSASM ;ALLOW REFERENCE
IORM T2,CST0(T1) ; ...
CALL MAPRCA ;MAP PAGE
POP P,T2 ;RESTORE PAGE NUMBER
SKIP 0(T1) ;REFERENCE FIRST WORD
CONSZ APR,APNXM ;NXM?
JRST CHKPG1 ;YES - LOSE QUICKLY
SKIP 1(T1) ;NO - TRY NEXT 3 WORDS
SKIP 2(T1) ;IN CASE INTERLEAVE
SKIP 3(T1) ;DEFECTIVE
CONSZ APR,APNXM ;STILL NO NXM?
JRST CHKPG1 ;NXM - NOT SUITABLE
POP P,CST0(T2) ;RESTORE ORIGINAL STATE
CALL UNMRCA ;CLEAR TEMP MAPPING
PION
RETSKP ;SUCCESS RETURN
CHKPG1: CONO APR,APFCLR+APNXM+APRCHN ;RESET NXM FLAG
POP P,CST0(T2) ;RESTORE ORIGINAL STATE
CALL UNMRCA ;RELEASE TEMP MAPPING
PION
RET ;FAILURE
;ROUTINES FOR SAVING AND RESTORING SWAPPABLE MONITOR MAP
;AROUND RESTARTS
;SAVE SWAP MON MAP
SAVSMM::MOVEI Q1,SWPMPG-1
SUB Q1,SWCEND ;COMPUTE NUMBER PAGES IN SWAP MON
HRLZ Q1,Q1 ;SETUP AOBJN PTR
SAVSM1: MOVE T1,MMAP+SWPMPG(Q1) ;GET CURRENT MAP PTR
TXNN T1,NCORTM ;IN CORE?
JRST [ HRRZS T1 ;MASK OFF HIGH BITS
MOVE T1,CST1(T1) ;YES, GET DRUM ADDRESS
JRST .+1]
MOVEM T1,TMPSMM(Q1) ;SAVE DRUM ADDRESS
AOBJN Q1,SAVSM1
RET
;RESTORE SWAP MON MAP FROM TEMP AREA IN LOW CORE
RESSMM::MOVEI Q1,SWPMPG-1 ;COMPUTE NUMBER PAGES IN SWAP MON
SUB Q1,SWCEND
HRLZ Q1,Q1
RESSM1: LOAD T1,STGADR,TMPSMM(Q1) ;GET DRUM ADR FOR THIS PAGE
CALL DRMASA ;ASSIGN IT
BUG(HLT,RSMFAI,<RESSMM-FAILED TO ASSIGN SWAP MON PAGE>)
LOAD T1,STGADR,TMPSMM(Q1)
IOR T1,IMMPTR ;MAKE NEW PTR
MOVEM T1,MMAP+SWPMPG(Q1) ;SETUP MON MAP
AOBJN Q1,RESSM1
RET
;RESTART SWAPPER - REINITIATE IO OPERATIONS IN PROGRESS AT TIME OF CRASH
SWPRST::SETZM IOIP
MOVE 6,MONCOR ;SCAN CST AND CHECK STATE OF PAGES
SWPRS1: LOAD 1,CSTAGE,(6) ;GET STATE CODE
CAIN 1,PSRIP ;READ IN PROGRESS?
JRST SWPRSR ;YES, GO RESTART IT
CAIN 1,PSWIP ;WRITE?
JRST SWPRSW ;YES
CAIL 1,PSASN ;PAGE ASSIGNED TO PROCESS?
JRST [ MOVE 2,CST3(6) ;YES, SEE IF BEING WRITTEN
TLNE 2,(DWRBIT)
JRST SWPRSW ;WAS BEING WRITTEN, RESTART WRITE
JRST .+1] ;NOT BEING WRITTEN
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,(DSKAB) ;DISK?
JRST SWPRS3 ;YES
TLNN 2,(DRMAB) ;DRUM?
BUG(HLT,ILCST1,<ILLEGAL ADDRESS IN CST1 ENTRY, CAN'T RESTART>)
CALL DRMIO
JRST SWPRS2
SWPRS3: CALL DSKIO
JRST SWPRS2
;PERIODIC ROUTINE TO TRICKLE PAGES TO DISK
DDMPLF==1B0 ;LOCAL FLAG IN F, DRUM SP LOW IF 1
DDMP:: AOSE STRLOK ;STRUCTURE BEING DISMOUNTED?
RET ;YES. FAIL
SETZ F, ;CLEAR FLAGS
MOVE 1,DRMFRE
SKIPE DDTIME ;SYSTEM SHUTDOWN?
CAMGE 1,DRMIN0 ;OR INSUFFICIENT DRUM SPACE?
TLO F,(DDMPLF) ;YES, TAKE SPECIAL ACTION
MOVSI P1,-NOFN ;SETUP TO SCAN ALL OFN'S
AOBJN P1,.+1 ;0 NOT USED
DDMP9: NOSKED
SKIPN SPTH(P1) ;OFN IN USE?
JRST DDMP2 ;NO
SETCM 1,SPTH(P1) ;GET THAW AND WRITE BITS
TXNN 1,FILWB+THAWB ;BOTH 1? (I.E. THAW MODE)
JRST DDMP3 ;YES, UPDATE
TXNN F,DDMPLF ;DRUM FULL?
JRST DDMP2 ;NO, BYPASS OFN
DDMP3: MOVX 2,OFNDMO!OFNDUD ;CHECK IF THIS OFN IS DISMOUNTED
; OR DDMP BEING SUPPRESSED
TDNE 2,SPTH(P1) ;IS IT?
JRST DDMP2 ;YES. SKIP IT
MOVX 2,SPTLKB ;TRY TO LOCK OFN
TDNE 2,SPTH(P1)
JRST DDMP2 ;ALREADY LOCKED, SKIP IT THIS TIME
IORM 2,SPTH(P1) ;SET LOCK
OKSKED ;WILL UPDATE OFN, NOW SAFELY LOCKED
LOAD A,STRX,(P1) ;GET STRUCTURE NUMBER
CALL UPDBTB ;UPDATE BIT TABLE
HRLZ 1,P1 ;CONSTRUCT IDENT OF FIRST PAGE
MOVEI 2,PGSIZ ;DO ALL PAGES
TXNN F,DDMPLF ;DOING DRUM LOW ACTIONS?
CALL UPDPGS ;NO, REGULAR UPDATE PAGES
TXNE F,DDMPLF
CALL UPDPG0 ;YES, FLUSH ALL PAGES TO DISK
HRRZ 1,P1 ;GET OFN
CALL UPDOF0 ;UPDATE THE INDEX BLOCK
MOVX 1,SPTLKB
ANDCAM 1,SPTH(P1) ;CLEAR LOCK
JRST DDMP1 ;DONE WITH THIS OFN
DDMP2: OKSKED
DDMP1: AOBJN P1,DDMP9 ;SCAN ALL OFN'S
SETOM STRLOK ;RELEASE LOCK
RETSKP ;AND RETURN SUCCESSFULLY
;UPDATE OFN--GET INDEX BLOCK WRITTEN TO DISK
; 1/ OFN
; CALL UPDOFN
; RETURN +1 ALWAYS, BIT TABLE AND INDEX BLOCK UPDATED
UPDOFN::STKVAR <OFN>
MOVEM A,OFN
HRRZ B,A ;GET OFN
CALL CHKDMO ;SEE IF DISMOUNTED
RET ;IT IS. IGNORE REQUEST.
HRRZ A,OFN ;GET OFN
CALL LCKOFN ;LOCK OFN AGAINST CHANGES
MOVX B,OFNWRB ;SEE IF OFN MODIFIED
TDNN B,SPTH(A)
JRST UPDOFX ;NOT MODIFIED, DO NOTHING
LOAD A,STRX,(A) ;GET STRUCTURE NUMBER
CALL UPDBTB ;UPDATE BIT TABLE
HRRZ A,OFN ;GET OFN AGAIN
CALL UPDOF0 ;WRITE INDEX BLOCK
UPDOFX: MOVE A,OFN
CALL ULKOFN ;UNLOCK OFN
RET
;SCAN INDEX BLOCK AND WRITE IMAGE TO DISK
;ASSUMES OFN LOCKED AGAINST CHANGES
; A/ OFN
; CALL UPDOF0
; RETURN +1 ALWAYS
;AC USAGE:
; P1 - OFN
; P2 - AOBJN PTR FOR SCANNING PAGE TABLE
; P3, P4 - TEMPS
; P5 - CHECKSUM
UPDOF0: SAVEP ;SAVE P1-P6
CAILE A,0 ;ENSURE LEGAL OFN
CAIL A,NOFN
BUG(HLT,NOTOFN,<UPDOF0-ARG NOT OFN>)
MOVEM A,P1 ;KEEP OFN AROUND
LOAD A,STGADR,SPT(P1) ;GET CURRENT ADR OF XB
TXNE A,DSKAB ;ON DISK?
RET ;YES, NOTHING TO DO
MOVX A,OFNWRB
TDNN A,SPTH(P1) ;CHANGED SINCE LAST UPDATE?
RET ;NO, NOTHING TO DO
ANDCAM A,SPTH(P1) ;NOTE OFN NOW UPDATED
MOVE A,P1
MOVE B,[PTRW+FPG2A]
CALL SETMPG ;MAP XB
MOVEI A,0
MOVEI B,FPG3A
CALL SETMPG ;CLEAR A PAGE TO RECEIVE XB IMAGE
SETZM FPG3A ;MAKE IT EXIST
MOVEI P5,0 ;INIT CHECKSUM
JCRY0 .+1
MOVSI P2,-PGSIZ ;SETUP TO SCAN XB
UOFN1: SKIPE FPG2A(P2) ;ENTRY EXISTS?
JRST UOFN2 ;YES, GO TRACK DOWN DISK ADR
ADDI P5,0(P2) ;USE XB INDEX FOR 0 WORD IN CHECKSUM
JCRY0 [AOJA P5,.+1] ;WRAPAROUND CARRY
UOFN6: AOBJN P2,UOFN1 ;SCAN ALL XB
MOVX A,OFNBAT ;SEE IF OFN HAS BAT BIT
MOVX B,XBBAT ;IN CASE IT DOES
TDNE A,SPTH(P1) ;IS IT SET?
IORM B,XBBWRD+FPG3A ;YES. MARK XB
; ..
;UPDOFN...
;HAVE FINISHED SCAN OF XB
MOVEI A,P5 ;POINT TO CHECKSUM
MOVE B,[XBCKSM+FPG3A] ;PUT IT IN FIRST FOUR WORDS OF XB
CALL STXBD ;STORE CHECKSUM IN XB
MOVEI A,FPG3A ;GET IDENT FOR IMAGE PAGE
CALL FPTA
MOVEM A,P3 ;SAVE IT
CALL MLKPG ;LOCK IMAGE PAGE IN CORE FOR DSKIO
MOVEM A,P4 ;SAVE CORE PAGE NUMBER
LOAD A,STGADR,SPTH(P1) ;GET DSK ADR OF XB
MOVX B,DOP%WR+PGSIZ ;SAY WRITE ONE PAGE
HRRZ C,P4 ;SETUP PHYSICAL CORE ADR
LSH C,PGSFT
LOAD D,STRX,(P1) ;GET STRUCTURE NUMBER
CALL UDSKIO ;WRITE TO DISK
AOS DSKWR ;COUNT WRITES FOR STATISTICS
EXCH A,P3 ;SAVE ERROR BITS, GET CORE PAGE
CALL MULKPG ;UNLOCK PAGE
SKIPE P3 ;ERROR ON WRITE?
BUG(CHK,XBWERR,<UPDOFN-DSK WRITE ERROR ON XB>)
UOFNX: MOVEI A,0
MOVEI B,FPG2A
MOVEI C,2
CALL MSETMP ;UNMAP BOTH PAGES
RET
;UPDOFN...
;FIND DISK ADDRESS FOR PAGE IN XB
UOFN2: NOSKED
MOVE A,FPG2A(P2) ;GET POINTER
LOAD B,PTRCOD,A ;GET PTR TYPE
CAIE B,SHRCOD ;SHARE?
JRST [ LOAD A,STGADR,A ;NO, PRIVATE. GET ADR.
JRST UOFN3]
LOAD A,SPTX,A ;GET SPT INDEX
LOAD A,STGADR,SPT(A) ;GET ADDRESS OF PAGE
UOFN3: TXNE A,DSKAB ;HAVE DISK ADDRESS?
JRST UOFN4 ;YES, DONE
TXNE A,DRMAB ;HAVE DRUM ADDRESS?
JRST UOFN5 ;YES
TXNE A,NCORTM ;CORE ADDRESS?
JRST [ SETZ A, ;NO, UNASSIGNED. USE 0
JRST UOFN4]
CAML A,MONCOR ;LEGAL PAGE NUMBER?
CAMLE A,NHIPG
JRST UOFBPP ;NO
HRRZS A
LOAD A,STGADR,CST1(A) ;GET NEXT LEVEL ADDRESS
JRST UOFN3 ;GO SEE WHAT IT IS
;HAVE DRUM ADDRESS
UOFN5: MOVE B,A
CALL GDSTX ;GET DST INDEX
HRRZS B
LOAD A,STGADR,DST(B) ;GET NEXT LEVEL ADDRESS FROM DST
TXNN A,DSKAB ;IT MUST BE DISK
JRST UOFBPP ;LOSSAGE
UOFN4: OKSKED
STOR A,STGADR,FPG3A(P2) ;PUT DSK ADR IN IMAGE PAGE
SKIPN A ;PAGE EXISTS?
HRRZ A,P2 ;NO, USE XB INDEX FOR CHECKSUM
JCRY0 .+1 ;CLEAR CARRY FLAG
ADD P5,A ;DO CHECKSUM
JCRY0 [AOJA P5,.+1] ;WRAPAROUND CARRY
JRST UOFN6 ;CONTINUE SCAN
;CASES OF BAD POINTER
UOFBPP: BUG(HLT,ILPPT1,<UPDOFN-BAD POINTER IN PAGE TABLE>)
OKSKED
JRST UOFNX ;RETURN WITHOUT WRITING XB
;LOAD/STORE DATA IN INDEX BLOCK.
;SINCE THE STORAGE ADDRESS IS ONLY 23 BITS, THE REMAINING PORTION
;OF EACH WORD CAN BE USED TO STORE USEFUL INFORMATION, E.G. A
;CHECKSUM OF THE INDEX BLOCK. THESE ROUTINES PACK AND UNPACK
;THE DATA FROM THE XB USING B0-8 OF SUCCESSIVE WORDS.
; A/ ADDRESS OF WORD(S)
; B/ NUMBER OF XB WORDS,,XB ADDRESS + OFFSET
; CALL STXBD/LDXBD
; RETURN +1 ALWAYS, DATA MOVED BETWEEN XB AND C(C(A))
;STORE DATA INTO INDEX BLOCK
STXBD: HRLI A,(<POINT 9,0>) ;INIT PTR TO CALLERS DATA
STXBD1: ILDB C,A ;GET BYTE FROM CALLER
DPB C,[POINT 9,0(B),8] ;PUT IT IN XB
AOBJN B,STXBD1 ;INCREMENT THROUGH XB
RET
;LOAD FROM XB
LDXBD: HRLI A,(<POINT 9,0>) ;INIT PTR TO CALLERS STORAGE
LDXBD1: LDB C,[POINT 9,0(B),8] ;GET BYTE FROM XB
IDPB C,A ;PUT IT IN CALLERS STORAGE
AOBJN B,LDXBD1 ;SCAN THROUGH XB
RET
;ITEMS IN INDEX BLOCK VECTOR
XBCKSM==<-4,,0> ;CHECKSUM--4 WORDS BEGINNING AT 0
;UPDATE FILE PAGES--CAUSE CHANGED PAGES TO BE WRITTEN TO DISK
; 1/ IDENT OF FIRST FILE PAGE, OFN,,PN
; 2/ NUMBER OF SEQUENTIAL PAGES TO UPDATE
; CALL UPDPGS
; RETURN +1 ALWAYS, ALL WRITES COMPLETED
;AC USAGE:
; P1 - OFN
; P2 - AOBJN PTR FOR SCANNING PT
; P3 - FLAGS
; P4 - COPY OF INITIAL AOBJN PTR
;LOCAL FLAGS
UPGSF0==1B1 ;0=WRITE PAGES, 1=WAIT FOR COMPLETION
UPGSLF==1B2 ;1=DRUM SPACE LOW, FORCE PAGES TO DSK
UPGKPF==1B3 ;0 = USE OFRQ, 1 = USE ONRQ ON SWPOUT
;ROUTINE SCANS PAGE TABLE TWICE. FIRST TIME TO REQUEST WRITES ON
;ALL CHANGED PAGES, SECOND TIME TO WAIT FOR COMPLETION OF WRITES.
;THIS IS FASTER THAN WAITING FOR EACH WRITE TO COMPLETE AS IT
;IS REQUESTED.
UPDPGS::SAVEP ;SAVE P1-P6
MOVX P3,UPGKPF ;KEEP PAGES
JRST UPGS0
UPDPGR::SAVEP ;ENTRY TO REMOVE PAGES QUICKLY
MOVX P3,0 ;CLEAR FLAGS
JRST UPGS0
;SPECIAL ENTRY FOR DDMP, SET FLAG TO FORCE PAGES TO DSK WHEN DRUM FULL
UPDPG0: SAVEP
MOVX P3,UPGSLF+UPGKPF ;SET FULL FLAG AND KEEP PAGES
UPGS0: HLRZM A,P1 ;SAVE OFN
HRRM A,P2 ;SETUP INITIAL PAGE NUMBER
HRRZ A,A
ADD A,B ;COMPUTE FINAL PAGE NUMBER
CAILE A,PGSIZ ;BEYOND END OF PT?
BUG(HLT,PTOVRN,<UPDPGS-COUNT TOO LARGE>)
MOVN B,B
HRLM B,P2 ;CONSTRUCT AOBJN PTR TO SCAN PT
MOVE B,P1 ;GET PT
CALL CHKDMO ;SEE IF IT IS A DISMOUNTED OFN
CALLRET DMOINT ;IT IS. GIVE AN ERROR
MOVEM P2,P4 ;SAVE COPY FOR SECOND PASS
LOAD A,STGADR,SPT(P1) ;GET CURRENT ADR OF INDEX BLOCK
TXNE A,DSKAB ;ON DISK?
RET ;YES, NOTHING TO DO
MOVE A,P1 ;MAP PAGE TABLE
MOVE B,[PTRW+FPG2A]
CALL SETMPG
UPGS1: SKIPE FPG2A(P2) ;PAGE EXISTS?
JRST UPGS2 ;YES, GO CHECK IT OUT
UPGS3: AOBJN P2,UPGS1 ;DO ALL PAGES
MOVE P2,P4 ;REINIT AOBJN PTR
TXON P3,UPGSF0 ;DONE PASS 2 YET?
JRST UPGS1 ;NO, GO DO IT
UPGSX: MOVEI A,0
MOVEI B,FPG2A
CALL SETMPG ;RELEASE PT MAPPING
RET
;UPDPGS...
;INVESTIGATE SPECIFIC PAGE
UPGS2: NOSKED
UPGS7: MOVE A,FPG2A(P2) ;GET POINTER
LOAD B,PTRCOD,A ;GET PTR TYPE
CAIN B,SHRCOD ;SHARE?
JRST [ LOAD D,SPTX,A ;YES, GET SPT INDEX
LOAD A,STGADR,SPT(D) ;GET PAGE ADR FROM SPT
JRST UPGS9] ;GO PROCESS IT
MOVE D,P2 ;IS PRIVATE. FORM ID
HRL D,P1 ; AS OFN.PN
UPGS9: TXNE A,DSKAB ;ON DISK?
JRST UPGS4 ;YES, NO UPDATE NEEDED
TXNN A,DRMAB ;ON DRUM?
JRST UPGS5 ;NO
TXNE P3,UPGSF0 ;YES, PASS 2?
JRST UPGS4 ;YES, WRITE, IF ANY, MUST HAVE COMPLETED
MOVE B,A ;GET DRUM ADDRESS TO B FOR GDSTX
CALL GDSTX ;GET DST INDEX
HRRZS B
MOVE C,DST(B) ;GET DRUM INFO
TXNN C,BWRBIT ;PAGE MODIFIED?
JRST [ TXNN P3,UPGSLF ;NO, DRUM FULL?
JRST UPGS4 ;NO, BYPASS PAGE
SETOM DST(B) ;DRUM FULL, SO PUT PAGE BACK ON DSK
TLNE D,-1 ;IN SPT OR XB?
CALL [ HRRZ B,D
STOR C,STGADR,FPG2A(B) ;IN XB
RETSKP] ;DONE
STOR C,STGADR,SPT(D) ;SPT
CALL DASDRM ;ADJUST POINTER AND DEASSN DRM ADR
JRST UPGS4]
MOVE A,D ;MUST SWAPIN PAGE, GET SPT INDEX
UPGS6: CALL SWPINW ;SWAPIN THE PAGE
JRST UPGS7 ;NOW SHOULD BE IN CORE
;PAGE NOT ON DISK OR DRUM
UPGS5: TXNE A,NCORTM ;IN CORE?
JRST UPGS4 ;NO, UNASSIGNED. IGNORE.
TXNE P3,UPGSF0 ;PASS 2?
JRST [ CALL SKPNWR ;YES, WRITE STILL IN PROGRESS?
JRST UPGS7 ;YES, WAITED FOR COMPLETION
JRST UPGS4] ;NO, COMPLETED
MOVX B,CORMB
HRRZ C,A
TDNN B,CST0(C) ;PAGE IN CORE MODIFIED?
TXNE P3,UPGSLF ;OR SWAPPING BECAUSE DRUM FULL?
JRST UPGS8 ;YES, SWAPOUT PAGE
LOAD B,STGADR,CST1(C) ;NO, SEE IF MODIFIED ON DRUM
TXNN B,DSKAB ;PAGE BACKUP ON DRUM?
TXNN B,DRMAB
JRST UPGS4 ;NO, DON'T SWAPOUT
CALL GDSTX ;YES, GET DRUM INFO
HRRZS B
MOVX C,BWRBIT
TDNN C,DST(B) ;MODIFIED ON DRUM?
JRST UPGS4 ;NOT MODIFIED, NO UPDATE NEEDED
UPGS8: CALL SKPNWR ;WRITE IN PROGRESS?
JRST UPGS7 ;YES, RECHECK PAGE
CALL AGESET ;ASSIGN PAGE
MOVX B,-PLKV
TDNE B,CST1(A) ;PAGE LOCKED?
JRST UPGS4 ;YES, LEAVE IT
MOVX B,DSKSWB
IORM B,CST3(A) ;REQUEST SWAP TO DISK
JXN P3,UPGKPF,[CALL SWPOTK ;SWPOUT AND USE ONRQ
JRST UPGS4]
CALL SWPOT0 ;WRITE PAGE
UPGS4: OKSKED
JRST UPGS3 ;CONTINUE SCAN OF PT
;CASES OF BAD POINTER
UPGBPP: BUG(HLT,ILPPT2,<UPDPGS-BAD POINTER IN PAGE TABLE>)
OKSKED
JRST UPGSX ;QUIT WITHOUT FURTHER ADO
;ASSIGN OFN
; AC1/ (STGADR) INDEX BLOCK FILE ADDRESS (DISK, DRUM OR CORE)
; 1 WRITE BIT (FILWB)
; 2 THAWED BIT (THAWB)
; 3 NEW FILE BIT (FILNB)
; AC2/ STRUCTURE NUMBER
; AC3/ DIRECTORY NUMBER
; AC4/ REMAINING PAGES (DRLIQ - DRDCA)
;RETURN SKIP WITH OFN IN AC1 IF PROPER OPENING
;RETURN NO-SKIP IF ILLEGAL SHARED OPENING (ILLEGAL CONFIGURATION
; OF THAWED AND WRITE BITS)
;FILWB AND THAWB PROVIDE FOR 4 MODES OF OPENING:
; 00 - OPEN FOR READ, OTHER READERS AND 1 OTHER WRITER ALLOWED
; 10 - OPEN FOR WRITE, OTHER READERS ALLOWED BUT NO OTHER WRITERS
; 11 - OPEN 'THAWED' - ARBITRARY OTHER READERS AND WRITERS ALLOWED
; 01 - OPEN 'RESTRICTED' - NO OTHER OPENS ALLOWED
;AC USAGE:
; Q1 - XB ADDRESS/CHECKSUM OF XB
; Q2 - OFN
; FX - STRUCTURE NUMBER
;ENTRY AT ASLOFN ASSIGNS OFN ONLY IF IT ALREADY EXISTS OR
;CURRENT OFN USAGE IS BELOW LONG FILE CUTOFF
ASGOFL::TLOA T2,-1 ;REMEMBER ASLOFN ENTRY
ASGOFN::TLZ T2,-1 ;REMEMBER ASGOFN ENTRY
SAVEQ
MOVEI FX,0(2) ;SAVE STRUCTURE NUMBER
HRRZ Q2,T3 ;COPY DIRECTORY NUMBER
ASGOF1: CAIGE FX,STRN ;A VALID STRUCTURE NUMBER?
SKIPN STRTAB(FX) ;YES. DOES THE STRUCTURE EXIST?
BUG (HLT,STRBAD,<ASOFN-ILLEGAL STRUCTURE NUMBER>)
TRVAR <PGASG,DNASG,SVX,ENTTYP>
HLRZM T2,ENTTYP ;REMEMBER IF ASLOFN OR ASGOFN
MOVEM T4,PGASG ;PAGE ALLOCTION
MOVEM Q2,DNASG ;DIR NUMBER
ASOFC: LOAD Q1,STGADR,1 ;GET ADDRESS ONLY
AND 1,[FILWB+THAWB+FILNB+OFNDUD+OFN2XB] ;GET BITS CALLER ALLOWED TO SPECIFY
IOR 1,Q1 ;CONSTRUCT COMPOSIT WORD FOR SPTH
NOSKED
TLNN 1,(DSKAB) ;DISK?
JRST [ MOVEI 1,OPNX16 ;NO, RETURN BAD
JRST ASOFXB]
MOVEM 1,SVX ;SAVE ADDRESS
ASGOF2: CALL OFNSRC ;SEARCH SPTH FOR GIVEN DSK ADR
JRST ASOF4 ;NOT FOUND, GO ADD TO TABLE
HRRZ Q2,1 ;FOUND, GET OFN
MOVX 2,SPTLKB
TDNE 2,SPTH(Q2) ;OFN LOCKED?
JRST [ HRLZ 1,1 ;YES, MUST WAIT
CALL WTOFNL
MOVE 1,SVX ;RECOVER ADDRESS
JRST ASOFC] ;START OVER
IORM 2,SPTH(Q2) ;LOCK IT
NOINT ;NOINT FOR EACH SPT LOCK
; ..
;SHARED OPEN, CHECK WRITE AND THAWED BITS FOR LEGAL COMBINATION
MOVE 2,SVX ;RECOVER CLASS AND BITS
MOVE 1,SPTH(Q2) ;GET EXISTING THAWB AND FILWB
TLNE 1,(THAWB) ;FILE NOW OPEN THAWED OR RESTRICTED?
JRST [ XOR 1,2 ;YES, COMPARE EXISTING AND NEW MODES
TLNN 1,(FILWB+THAWB) ;BOTH THE SAME?
TLNN 2,(FILWB) ;AND NOT RESTRICTED?
JRST ASOFB ;NO, REPORT BUSY
JRST ASOF5] ;THIS OPEN OK
TLNE 2,(THAWB) ;NEW OPEN CONSISTENT?
JRST ASOFB ;NO, REPORT BUSY
TLNN 2,(FILWB) ;NEW OPEN WANTS WRITE?
JRST ASOF5 ;NO, MUST BE OK
TLOE 1,(FILWB) ;YES, FILE ALREADY HAS WRITER?
JRST ASOFB ;YES, REPORT BUSY
MOVEM 1,SPTH(Q2) ;NEW WRITE OPEN OK, UPDATE STATE
ASOF5: MOVX 1,OFNDUD ;GET DDMP SUPPRESS BIT
TDNE 1,2 ;DID USER REQUEST DDMP SUPPRESS?
IORM 1,SPTH(Q2) ;YES. SET IT THEN
MOVEM Q2,SVX ;SAVE OFN FOR ALLOC CODE
OPSTR <SKIPN>,ALOCX,(Q2) ;HAVE AN ALLOC ENTRY YET?
CALL ASGALC ;NO. GO GET ONE FOR THIS OFN
HRRZ 1,SVX ;RETURN OFN (SPT INDEX)
CALL UPSHR ;INCREMENT SHARE COUNT
CALL ULKOFN ;UNLOCK
JRST ASOFXG ;RETURN GOOD
ASOFB: HRRZ 1,Q2
CALL ULKOFN ;UNLOCK OFN
MOVEI 1,OPNX9 ;ERROR NUMBER FOR FILE BUSY
JRST ASOFXB
;EXITS FROM ASOFN
ASOFXB: TDZA 2,2 ;EXIT "BAD"
ASOFXG: SETO 2, ;EXIT "GOOD"
OKSKED
JUMPE 2,R ;BAD = NOSKIP RETURN
RETSKP ;GOOD = SKIP RETURN
;COULD NOT FIND MATCHING OFN. CREATE ONE.
ASOF4: SKIPE ENTTYP ;ASLOFN ENTRY?
JRST [ MOVE Q2,NOF ;YES. GET "OPEN FILE COUNT"
CAIGE T3,NOFN-NROFN-1 ;CAN WE OPEN ANOTHER LONGY?
JRST .+1 ;YES. PROCEED
SKIPG ENTTYP ;FIRST TIME?
JRST [ MOVEI T1,MONX01 ;NO. BOMB
JRST ASOFXB] ;GIVE UP
CALL FREOFN ;YES. CLEAN UP OFNS AND TRY AGAIN
JFCL
SETOM ENTTYP ;SAY DONE IT ONCE
MOVE T1,SVX ;GET BACK ARG
JRST ASGOF2] ;AND TRY AGAIN
JUMPN 1,ASOF6 ;JUMP IF HAVE DELETED ENTRY TO REUSE
MOVE 1,MAXSPL ;MUST MAKE NEW ENTRY
CAIL 1,NOFN-1 ;ROOM?
JRST [ CALL FREOFN ;TRY RELEASING ALL "UNSHARED" OFN
SKIPA ;NONE FOUND
JRST [ MOVE T1,SVX ;GET BACK OFN
JRST ASGOF2] ;AND TRY AGAIN
MOVEI 1,OPNX10 ;SAY 'NO ROOM'
JRST ASOFXB] ;RETURN BAD
AOS 1,MAXSPL ;GET NEXT FREE ENTRY
ASOF6: HRRZ Q2,1
MOVE 1,SVX ;RECOVER CLASS AND BITS
TLZE 1,(FILNB) ;NEWLY ASSIGNED XB?
TLO Q1,(DSKNB) ;YES, INDICATE IN DISK ADDRESS
MOVEM 1,SPTH(Q2)
MOVEM Q1,SPT(Q2) ;PUT ADDRESS IN SPT
STOR FX,STRX,(Q2) ;PUT IN STRUCTURE NUMBER
MOVEM Q2,SVX ;SAVE OFN INDEX
CALL ASGALC ;GO GET AN ALLOC ENTRY FOR THIS OFN
MOVE Q2,SVX ;GET BACK OFN
AOS NOF ;COUNT OPEN FILES
MOVEI 1,1 ;SHARE COUNT WILL BE ONE
STOR 1,OFNSHC,(Q2) ;STORE IT
; ...
HRRZ 3,Q2 ;COPY OFN
CALL SETXB1 ;MAP XB
HRRZ T1,Q2 ;GET OFN AGAIN
CALL LCKOFN ;LOCK THE OFN (SOULDN'T BE LOCKED YET
OKSKED ;NOW ALLOW OTHERS TO RUN
SKIP CXBPGA ;GET XB IN MEMORY
NOSKED ;TAKE OVER MACHINE AGAIN
CALL ULKOFN ;AND UNLOCK THE OFN
SKIP CXBPGA ;MUST BE SURE IT IS STILL IN MEMORY
HRRZ 1,SPT(Q2) ;CORE ADDRESS
MOVSI 2,(SWPERR)
TDNE 2,CST3(1) ;DISK ERROR IN XB?
JRST ASCHK3 ;YES, DON'T OPEN
TXNE Q1,DSKNB ;NEW XB?
JRST [ MOVX 1,OFNWRB ;YES, NOTE CHANGE FOR NEXT UPDATE
IORM 1,SPTH(Q2)
JRST ASCHK4] ;NO CHECKSUM TO COMPUTE
MOVE A,CXBPGA+XBBWRD ;SEE IF XB HAS A BAD ENTRY
MOVX B,OFNBAT ;IN CASE IT DOES
TXZE A,XBBAT ;IS IT SET?
IORM B,SPTH(Q2) ;YES. REMEMBER THIS IN SPT
MOVEM A,CXBPGA+XBBWRD ;STORE NEW XB WORD
MOVEI A,Q1 ;POINT TO Q1 TO STORE CHECKSUM
MOVE B,[XBCKSM+CXBPGA] ;CHECKSUM IS IN FIRST 4 WDS OF XB
CALL LDXBD ;GET CHECKSUM FROM XB
SETCA Q1, ;COMPLEMENT IT, SHOULD THEN ADD TO 0
JCRY0 .+1
MOVSI 1,-PGSIZ ;SETUP TO SCAN XB
ASCHK1: LOAD 2,STGADR,CXBPGA(1) ;GET ADDR FROM XB
JUMPE 2,[ADDI Q1,0(1) ;USE XB INDEX IF WORD EMPTY FOR CHECKSUM
JCRY0 [AOJA Q1,ASCHK2] ;WRAPAROUND CARRY
JRST ASCHK2]
ADD Q1,2 ;DO CHECKSUM
JCRY0 [AOJA Q1,.+1] ;WRAPAROUND CARRY
IOR 2,IMMPTR ;CONSTRUCT IMMED PTR
ASCHK2: MOVEM 2,CXBPGA(1)
AOBJN 1,ASCHK1
CAME Q1,[-1] ;CHECKSUM OK? (0 OR -0)
JUMPN Q1,ASCHK3 ;JUMP IF CHECKSUM BAD
ASCHK4: CALL RELCXB ;OK, RELEASE XB
HRRZ 1,Q2 ;RETURN OFN IN 1
JRST ASOFXG
;ASOFN...
;HANDLE BAD XB
ASCHK3: CALL RELCXB ;FILE NO GOOD, RELEASE XB
PUSH P,SPT(Q2) ;SAVE CORE ADR
MOVE 1,Q2
CALL DASOFN ;DEASSIGN OFN SLOT
POP P,1 ;RECOVER CORE ADR
CALL DECOR
HRRZS 1
SETZM CST2(1)
CALL OFRQ ;PUT ON TOP OF RPLQ SINCE PAGE IS USELESS
MOVEI 1,OPNX16 ;ERROR NUMBER FOR BAD XB
JRST ASOFXB
;ERROR IN ALLOCATION TABLE
ASG6X: BUG (HLT,OVFLOW,<ASOFN - ALLOCATION TABLE OVERFLOW>)
;ROUTINE TO FREE ALL "UNSHARED" OFNS. CALLED WHEN OFN'S
;RUN OUT
;MUST BE CALLED NOSKED
;RETURNS: +1 NONE FOUND. OFN'S STILL EXHAUSTED
; +2 AT LEAST ONE FOUND AND FREED
FREOFN: ACVAR <Q1> ;GET A WORK REG
HRLZ T1,MAXSPL ;GET HIGHEST OFN
MOVN T1,T1 ;MAKE AOBJN POINTER
HRRI T1,1 ;START AT FIRST OFN
SETZM Q1 ;NONE FOUND YET
FREOF1: SKIPN SPTH(T1) ;THIS ONE IN USE?
JRST FREOF3 ;NO. GO ON
PUSH P,T1 ;SAVE AOBJN WORD
CALL GETSHR ;SEE IF SHARED
JUMPN T1,FREOF2 ;IF SO, JUMP OFF
HRRZ T1,0(P) ;NOT SHARED.
CALL CLROFN ;COLLECT IT
AOS Q1 ;FOUND ONE
FREOF2: POP P,T1 ;RESTORE AOBJN POINTER
FREOF3: AOBJN T1,FREOF1 ;DO THEM ALL
JUMPE Q1,R ;IF NONE FOUND. +1
RETSKP ;IF SOME FOUND. +2
;CHECK OFN -- SEE IF FILE IN USE BUT DO NOT OPEN
; A/ DISK ADR OF XB (SAME AS ASOFN)
; B/ STRUCTURE NUMBER
; CALL CHKOFN
; RETURN +1, FILE ALREADY OPEN
; RETURN +2, FILE NOT OPEN
CHKOFN::SAVEQ
MOVE FX,B ;SAVE STRUCTURE NUMBER
LOAD Q1,STGADR,1 ;SETUP XB ADR
CALL OFNSRC ;SEARCH FOR IT
RETSKP ;NOT FOUND
RET ;FOUND
;LOCAL ROUTINE TO SEARCH SPTH FOR GIVEN XB ADR
; Q1/ DISK ADR
; FX/ STRUCTURE NUMBER
; CALL OFNSRC
; RETURN +1, NOT FOUND; 1/ FIRST FREE ENTRY OR 0
; RETURN +2, FOUND; 1/ INDEX
OFNSRC: HRLZ 1,MAXSPL ;GET COUNT OF ENTRIES IN USE
MOVN 1,1 ;SETUP AOBJN PTR
HRRI 1,1 ;START WITH ENTRY 1 OF SPT
SETZ 3, ;INIT PLACE TO HOLD DELETED ENTRY IF FOUND
JUMPGE 1,OFNSR3 ;QUIT NOW IF TABLE EMPTY
OFNSR1: MOVX 2,OFNDMO ;GET DISMOUNTED BIT
TDNE 2,SPTH(1) ;IS THIS A DISMOUNTED OFN?
JRST OFNSR2 ;YES. DON'T CONSIDER IT
LOAD 2,STGADR,SPTH(1) ;GET ADR
JUMPE 2,[SKIPN 3 ;ENTRY NOT IN USE, KEEP IT?
HRRZ 3,1 ;YES
JRST OFNSR2]
LOAD D,STRX,(1) ;GET THIS ENTRY'S STRUCTURE NUMBER
CAIN D,0(FX) ;SAME AS REQUESTED?
CAME B,Q1 ;YES. IS DISK ADDRESS THE SAME?
SKIPA ;NO. LOOK AT MORE
RETSKP ;YES, DONE
OFNSR2: AOBJN 1,OFNSR1 ;SEARCH ALL EXTANT ENTRIES
OFNSR3: MOVE 1,3 ;NOT FOUND, RETURN FIRST FREE SEEN
RET
;LOCAL ROUTINE TO DELETE OFN SLOT
; T1/ OFN
; CALL DASOFN
; RETURN +1 ALWAYS, REDUCE END OF TABLE IF POSSIBLE
DASOFN: SETZM SPTH(T1) ;FLUSH GIVEN ENTRY
CALL DASALC ;CLEAR ALLOC DATA
SETZRO OFNSHC,(T1) ;CLEAR SHARE COUNT IN THE OFN
SOS NOF ;NOTE ONE LESS OPEN FILE
CAME T1,MAXSPL ;THIS ENTRY LAST ONE IN TABLE?
RET ;NO, DONE
DASOF2: SOSE T2,MAXSPL ;YES, REDUCE LENGTH OF TABLE
SKIPE SPTH(T2) ;NEW LAST ENTRY ALSO FREE?
RET
JRST DASOF2 ;YES, REDUCE AGAIN
;ROUTINE TO CLEAR ALLOC DATA FROM OFN
; T1/ OFN
DASALC: LOAD T2,ALOCX,(T1) ;GET INDEX TO ALLOCATION INFO
JUMPE T2,R ;IF NO TABLE, RETURN
SETZM OFNLEN(T1) ;ZERO LENGTH INFO
SETZRO ALOCX,(T1) ;ZERO IT
DECR ODIRC,(T2) ;DECREMENT OFN COUNT
JN ODIRC,(T2),R ;OK IF STILL OPEN OFN'S
SETZRO ALCWD,(T2) ;CLEAR SLOT IF COUNT =0
SETZRO PGLFT,(T2) ; ...
RET ;AND DONE
;ROUTINE TO LOOK FOR AN APPROPRIATE ALLOC ENTRY
ASGALC: MOVE Q2,DNASG ;GET DIRECTORY NUMBER
CALL PGTCAL ;SEE IF CURRENT ENTRY
JRST ASOF6A ; NO - MAKE NEW ENTRY
MOVE Q2,SVX ;RESTORE OFN INDEX
JRST ASOF6B ;JUST INCREMENT COUNT
;HERE TO CREATE NEW DIRECTORY ALLOCATION ENTRY
ASOF6A: MOVE Q2,SVX ;GET OFN
MOVE T2,[-NOFN-1,,1] ;PREPARE AOBJN PNTR
OPSTR <SKIPE>,ALCWD,(T2) ;LOOK FOR EMPTY SLOT
AOBJN T2,.-1 ;...
JUMPGE T2,ASG6X ;ERROR IF NO ROOM
MOVE T1,DNASG ;GET DIRECTORY NUMBER
STOR T1,ADIRN,(T2) ;SAVE IN TABLE
MOVE T1,PGASG ;PAGES LEFT IN QUOTA
STOR T1,PGLFT,(T2) ;STORE
ASOF6B: STOR T2,ALOCX,(Q2) ;TABLE INDEX TO SPT
SETZM OFNLEN(Q2) ;CLEAR EOF INFO
INCR ODIRC,(T2) ;INCREMENT OFN DIRECTORY COUNT
RET ;ALL DONE.
;LOCK/UNLOCK OFN
;LOCKING OFN PREVENTS ANY CHANGE TO IT, E.G. ADDING OR DELETING PAGES
;LOCK OFN
; A/ OFN
; CALL LCKOFN
; RETURN +1 ALWAYS, BLOCK AND WAIT IF ALREADY LOCKED
LCKOFN:
LCKOF1: MOVX 2,SPTLKB
NOSKED
TDNE 2,SPTH(1) ;LOCK NOW CLEAR?
JRST [ HRLZ 1,1 ;SETUP SCHED TEST
CALL WTOFNL ;OKSKED AND DISMISS
HLRZ 1,1 ;RECOVER OFN
JRST LCKOF1] ;TRY AGAIN
IORM 2,SPTH(1) ;SET LOCK
NOINT ;NOINT FOR EACH SPT LOCK
OKSKED
RET
;ROUTINE TO DO OKSKED AND DISMISS FOR OFN LOCK
; A/ OFN,,0
; CALL WTOFNL
; RETURN +1 ALWAYS
WTOFNL: OKSKED
HRRI A,OFNLKT
MDISMS
RET
;SCHED TEST FOR OFN UNLOCKED
OFNLKT: MOVX 2,SPTLKB
TDNE 2,SPTH(1)
JRST 0(4)
JRST 1(4)
;UNLOCK OFN
; A/ OFN
; CALL ULKOFN
; RETURN +1 ALWAYS
ULKOFN: MOVX 2,SPTLKB
ANDCAM 2,SPTH(1) ;CLEAR LOCK
OKINT
RET
;LOCK/UNLOCK FOR CONVENIENCE WHERE PAGE ID IN A
;LOCK OFN
LCKOFI: SAVET
HLRZ A,A ;GET OFN
CAIGE A,NOFN ;REALLY AN OFN?
CALL LCKOFN ;YES, LOCK IT
RET
;UNLOCK
ULKOFI: SAVET
HLRZ A,A ;GET OFN
CAIGE A,NOFN ;REALLY AN OFN?
CALL ULKOFN ;YES, UNLOCK IT
RET
;RELEASE/DELETE OFN
; A/ OFN
; CALL RELOFN/DELPT
; RETURN +1 ALWAYS, A/ PAGE COUNT IN XB IF FILE COMPLETELY CLOSED,
; -1 IF FILE NOT COMPLETELY CLOSED.
DELOF==1B0 ;LOCAL FLAG IN Q1 FOR DELETE/RELEASE
DELPT:: SAVEQ
MOVX Q1,DELOF ;SAY DELETE
JRST RELOF0
RELOFN::MOVX B,OFNWRB ;OFN NEEDS UPDATING?
TDNE B,SPTH(A)
CALL UPDOFN ;YES, DO IT
SAVEQ
MOVEI Q1,0 ;SAY RELEASE
RELOF0: TRVAR <OFNX,XBX>
CALL LCKOFN ;LOCK THE OFN
MOVE 2,1 ;MOVE OFN
CALL GETSHR ;GET OFN SHARE COUNT
EXCH 1,2 ;COUNT TO 2 AND OFN TO 1
CAIE 2,1 ;IS THIS FINAL CLOSE?
JRST RELOF6 ;NO
NOSKED
MOVX 2,OFNDMO ;CHECK IF DISMOUNTED
TDNE 2,SPTH(1) ;IS IT?
JRST [ CALL DASOFN ;YES. DEASSIGN THE OFN
OKSKED ;ALLOW SCHEDULING AGAIN
OKINT ;ALLOW INTS AGAIN
RET] ;AND DONE
MOVEI 3,0(1)
CALL SETXB1 ;MAP INDEX BLOCK
MOVEM T1,OFNX ;SAVE THE OFN
RLOF00: SKIP CXBPGA ;SWAP IN XB, IF NECESSARY
LOAD T1,STGADR,SPT(T1) ;GET CORE PAGE
CALL SKPNWR ;MAKE SURE NOT BEING WRITTEN
JRST [ MOVE T1,OFNX ;IT WAS. GET OFN AGAIN
JRST RLOF00] ;AND TRY IT AGAIN
MOVX T3,PLKV ;GET A UNIT OF LOCK COUNT
ADDM T3,CST1(T1) ;LOCK XB FOR REST OF RELOFN
MOVE T1,OFNX ;GET THE OFN
CALL SCNOFN ;MOVE ALL OF THE PAGES TO DISK
JRST RELOF4 ;BAD XB .DON'T RELEASE IT
SKIPE Q2,T1 ;FOUND SOME PAGES
TXNN Q1,DELOF ;YES. WANT DELETE?
JRST RELOF7 ;NO. GO ON
MOVEM Q2,XBX ;YES. SAVE COUNT OF PAGES
MOVE 2,OFNX ;GET OFN
LOAD 3,ALOCX,(2) ;GET INDEX
OPSTRM <ADDM Q2,>,PGLFT,(3) ;UPDATE COUNT OF PAGES
MOVE 2,SPTH(2)
TXNN 2,OFNBAT ; A BAD OFN?
JRST OFNDLN ;NO. DO A FAST DELETE THEN
JRST DELBAD ;YES, GO DELETE BAD OFN
RELOF7: MOVE 1,OFNX ;RECOVER OFN
CALL DWNSHR ;DECREMENT SHARE COUNT
MOVE 3,SPTH(1) ;SAVE FLAGS
MOVEM 3,XBX ;SAVE FLAGS
LOAD C,STRX,(1) ;GET STRUCTURE NUMBER
MOVEM C,OFNX ;SAVE IT FOR LATER
CALL DASOFN ;RELEASE SPT SLOT
LOAD 1,STGADR,SPT(1) ;GET (CORE) ADDRESS OF XB
MOVSI T2,(-PLKV) ;GET A NEGATIVE UNIT OF LOCK COUNT
ADDM T2,CST1(T1) ;UNLOCK XB
OKINT ;MATCH NOINT DONE BY LCKOFN
CALL REMFP1 ;FLUSH CORE AND DRUM ADDRESSES
SKIPN 1
BUG(HLT,NOADXB,<RELOFN-NO DSK ADR FOR XB>)
MOVE 2,XBX ;RESTORE FLAGS
MOVE C,OFNX ;GET STRUCTURE NUMBER
TXNE Q1,DELOF ;DELETING FILE?
CALL DEDSKC ;YES, DELETE DISK ADR OF XB
MOVE 1,Q2 ;RETURN PAGE COUNT
RELOF4: CALL RELCXB ;RELEASE TEMP MAPPING
OKSKED
RET
;THIS ROUTINE IS GOTTEN TO WHEN THE CALLER WANTS TO DELETE THE
;OFN AND IT DOES NOT CONTAIN A BAT BLOCK.
OFNDLN: MOVSI Q2,-PGSIZ ;SCAN WHOLE XB
OFNDL1: SKIPN CXBPGA(Q2) ;AN ENTRY HERE?
JRST OFNDL2 ;NO
LOAD 1,STGADR,CXBPGA(Q2) ;GET DISK ADDRESS
MOVE B,OFNX ;GET OFN
LOAD B,STRX,(B) ;GET STRUCTURE NUMBER
CALL DEDSK ;RELEASE THE PAGE
SETZM CXBPGA(Q2) ;CLEAN UP
OFNDL2: AOBJN Q2,OFNDL1 ;DO WHOLE XB
JRST RELOF7 ;NOW GO DO XB ITSELF
;RETURN WHEN FILE NOT CLOSED BECAUSE SHARE COUNT NOT 0
RELOF6: CALL DWNSHR ;DECREMENT SHARE COUNT
MOVE 2,SPTH(1) ;GET CURRENT BITS
TXNN 2,OFNDMO ;DISMOUNTED?
TLNE 2,(THAWB) ;OPEN IN RESTRICTED OR THAWED MODE?
JRST RELOF1 ;YES, NO UPDATE OF BITS NEEDED
TLNE 1,(FILWB) ;NO, IS THIS THE WRITER?
TLZ 2,(FILWB) ;YES, AFTER THIS CLOSE, FILE HAS NO WRITER
MOVEM 2,SPTH(1) ;UPDATE BITS
RELOF1: CALL ULKOFN ;UNLOCK OFN
SETO 1, ;RETURN -1 FOR COUNT
RET
RELBAD: BUG(CHK,ILIBPT,<BAD POINTER TYPE IN INDEX BLOCK>)
SETO 1, ;SAY FILE NOT CLOSED
RET ;RETURN BAD
;CLEAR OFN FOUND WHEN SWAPPING OUT PAGE
; A/ OFN
CLROFN: CALL DASOFN ;RELEASE OFN SLOT
LOAD 1,STGADR,SPT(1) ;GET CORE ADR
CALLRET REMFP1 ;RELEASE STORAGE
;ROUTINE TO SCAN AN XB AND MOVE ALL OF ITS PAGES TO DISK.
;CALLED WITH T1/ THE OFN
;AND THE XB MAPPED INTO CXBPGA
; RETURNS +1 WITH T1/ COUNT OF PAGES
SCNOFN: ACVAR <W1,W2,W3> ;GET SOME WORK REGS
MOVE W3,T1 ;SAVE THE OFN
MOVSI W1,-PGSIZ ;SCAN XB
SETZ W2, ;INIT COUNT OF IN-USE PAGES
SCNOF3: MOVE 2,CXBPGA(W1) ;GET PTR
JUMPE 2,SCNOF2 ;JUMP IF EMPTY
LOAD T1,PTRCOD,T2 ;GET PTR TYPE
CAIE T1,IMMCOD ;PRIVATE?
JRST RELBAD ;NO, LOSSAGE
TXNE 2,DSKAB ;ON DSK?
JRST SCNOF5 ;YES
TXNE 2,NCORTM ;IN CORE?
JRST [ TXNE 2,DRMAB ;NO, PRIVATE UNASSIGNED?
JRST .+1 ;NO. MUST MOVE IT TO DISK THEN
SETZM CXBPGA(W1) ;FLUSH UNASSIGNED PTR
JRST SCNOF2]
MOVE 4,W1 ;SET UP ARGUMENT FOR CALL
HRL 4,W3 ;PROVIDE THE OFN AS WELL
CALL MOVDSK ;MOVE THE PAGE TO DISK
SCNOF4: MOVE T1,CXBPGA(W1) ;GET PRESENT ADDRESS
TXNE T1,NCORTM ;STILL IN CORE?
JRST SCNOF3 ;NO
LOAD T1,STGADR,T1 ;GET JUST PAGE NUMBER IN T1
CALL SKPNWR ;WAIT FOR WRITE TO COMPLETE
JRST SCNOF4 ;RECHECK
LOAD T2,CSTAGE,(T1) ;CHECK STATUS
CAIE T2,PSRPQ ;ON RPLQ?
CALL OFRQ ;NO, PUT IT ON
CALL RPCST ;FORCE DISK ADR BACK TO XB
JRST SCNOF3 ;LOOK AT PTR AGAIN, SHOULD BE DSK ADR
SCNOF5: AOS W2 ;COUNT THE PAGE
SCNOF2: AOBJN W1,SCNOF3 ;SCAN XB
MOVE T1,W2 ;RETURN COUNT OF PAGES FOUND
RETSKP ;AND DONE
;HERE TO DELETE A FILE (OFN) WHICH HAS ONE OR MORE BAT PAGES IN IT
DELBAD: OKSKED ;ALLOW SCHEDULING FOR A WHILE
NOINT ;BUT PREVENT LOCAL INTERRUPTS
MOVEI 1,FPG3A ;YES. LOCK DOWN A PAGE
CALL MLKMA ;GET IT
LSH 1,PGSFT ;MAKE IT A CORE ADDRESS
MOVE P3,1 ;AND SAVE IT
OFNFIN: SETZ P5, ;NO ERROR HERE
MOVSI P1,-PGSIZ ;SIZE OF XB
SETO P2, ;NO DRIVE FOUND YET
NOSKED ;PROTECT XB SCANNING
TOPOFN: LOAD 1,STGADR,CXBPGA(P1) ;GET ENTRY
JUMPE 1,NOPGH ; ANYTHING HERE?
TXZ 1,DSKAB ;CLEAR DEVICE TYPE
MOVE B,OFNX ;GET OFN
LOAD D,STRX,(B) ;GET STRUCTURE NUMBER
MOVE B,STRTAB(D) ;GET SDB INDEX
IDIV A,SDBSIZ(B) ;COMPUTE UNIT NUMBER AND LOCAL ADDRESS
MOVE P4,2 ;SAVE DISK ADDRESS
SKIPL P2 ;HAVE A DRIVE YET?
JRST HAVBAT ;YES. GO LOOK AT IT
OKSKED ;ALLOW INTS FOR BAT BLOCK LOGIC
MOVE P2,1 ;ESTABLISH THIS DRIVE
MOVE B,P3 ;CORE ADDRESS
MOVEI C,FPG3A ;VIRTUAL ADDRESS
CALL RDBAT ;GO READ THE BAT BLOCKS
JRST BUMBAT ;NO THERE
MOVE B,P4 ;RESTORE LOCAL DISK ADDRESS
NOSKED ;PROTECT THE SCANNING
JRST YESBAT
;HAVE BAT BLOCKS IN FOR THIS UNIT. NOW GO DO COMPARE
HAVBAT: CAIE A,0(P2) ;IS THIS THE PROPER UNIT?
JRST NOPGH ;NO
YESBAT: JUMPN P5,NOTBD1 ;IS OK.
MOVE A,B ;GET LOCAL ADDRESS
MOVEI B,FPG3A ;WHERE THE BAT BLOCK IS
MOVE C,OFNX ;GET OFN
LOAD C,STRX,(C) ;GET STRUCTURE NUMBER
MOVE C,STRTAB(C) ;GET SDB ENTRY
MOVE C,STRUDB(C) ;GET A UDB ADDRESS FOR ONE OF THIS TYPE
CALL SEEADR ;SEE IF THIS IS THERE
JRST NOTBD1 ;NO
JRST BADD ;YES.
NOTBD1: LOAD 1,STGADR,CXBPGA(P1) ;GET DISK ADDRESS
MOVE B,OFNX ;GET OFN
LOAD B,STRX,(B) ;GET STRUCTURE NUMBER
CALL DEDSK ;RELEASE PAGE
BADD: SETZM CXBPGA(P1) ;CLEAR SLOT
SOSG XBX ;ALL DONE?
JRST ALLDNE ;YES.
NOPGH: AOBJN P1,TOPOFN ;GO DO REST
OKSKED ;ALLOW SCHEDULING
JRST OFNFIN ;AND DONE
BUMBAT: MOVEI P5,1 ;SAY NO BAT BLOCKS HERE
NOSKED ;PREVENT SCHEDULING
JRST NOTBD1 ;GO FREE THE PAGE
;FINISHED THE SCAN OF THE BAD INDEX BLOCK. NOW RELEASE WORK
;PAGE AND PROCEED TO FREE THE INDEX BLOCK ITSELF.
ALLDNE: OKSKED ;ALLOW SCHEDULING
MOVE A,P3 ;GET PHYSICAL ADDRESS
LSH A,-PGSFT ;MAKE IT A PAGE NUMBER
CALL MULKCR ;AND RELEASE IT
OKINT ;PAGE IS RELEASED, ALLOW INTERRUPTS AGAIN
NOSKED ;PROTECT THE XB RELEASE
JRST RELOF7
;ROUTINE TO MARK THAT AN OFN IS ON A DISMOUNTED STRUCTURE.
;ACCEPTS: A/ THE OFN
;MUST BE CALLED WITH THE OFN LOCKED AND THE PROCESS NOINT.
;THIS ROUTINE WILL RELEASE ALL LOCAL STORAGE ASSOCIATED WITH THE
;OFN AND WITH ANY SHARE POINTERS ASSOCIATED WITH THE OFN. IN
;ADDITION IT WILL MARK THE OFN AS INVALID SO THAT SUBSEQUENT PAGE
;FAULTS ON IT OR ANY OF ITS PAGES CAN BE CONVERTED INTO MEMORY
;TRAPS.
SWAPCD ;CALLED FROM PROCESS CONTEXT
INVOFN: SAVEP ;GET SOME WORK REGISTERS
HRRZ P2,A ;SAVE OFN HERE
;NOW MAP OFN AND SCAN IT RELEASING ALL PRIVATE STORAGE
MOVEI T3,0(P2) ;GET OFN IN T3
CALL SETXB1 ;MAP INDEX BLOCK
INVRTY: MOVSI P1,-PGSIZ ;SCAN ENTIRE INDEX BLOCK
SKIP CXBPGA ;FAULT IN PAGE BEFORE NOSKED
NOSKED ;PROTECT THE XB
INOF2: SKIPN T1,CXBPGA(P1) ;ANYTHING HERE?
JRST INOF3 ;NO. GO ON
LOAD T2,PTRCOD,T1 ;GET POINTER
CAIN T2,IMMCOD ;IMMEDIATE?
JRST [ LOAD T1,STGADR,T1 ;GET STORAGE ADDRESS
CALL REMPGI ;GO ZAP THE PAGE
JRST INVRTY ;HAD TO BLOCK. GO CHECK IT AGAIN
STOR T1,STGADR,CXBPGA(P1) ;PUT SOMETHING BACK
JRST INOF3] ;AND PROCEED
LOAD P3,SPTX,T1 ;GET SPT INDEX
LOAD T1,STGADR,SPT(P3) ;GET SPT ADDRESS
CALL REMPGI ;GO ZAP THE PAGE
JRST INVRTY ;HAD TO BLOCK. GO TRY IT AGAIN
STOR T1,STGADR,SPT(P3) ;PUT IN A NEW ADDRESS
INOF3: AOBJN P1,INOF2 ;DO ENTIRE INDEX BLOCK
;NOW RELEASE STORAGE ASSOCIATED WITH THE OFN
LOAD A,STGADR,SPT(P2) ;GET CURRENT LOCATION
CALL REMPGI ;RELEASE THE STORAGE
JRST INVRTY ;HAD TO BLOCK. TRY AGAIN
STOR A,STGADR,SPT(P2) ;PUT IN HOME ADDRESS
MOVX T2,OFNDMO ;GET DISMOUNTED BIT
IORM T2,SPTH(P2) ;MARK THE OFN
MOVE A,P2 ;GET OFN IN 1
CALL DASALC ;RELEASE ALOC ENTRY FOR THIS OFN
OKSKED ;ALLOW SCHEDULING AGAIN
CALLRET RELCXB ;RELEASE XB MAPPING
;ROUTINE TO RELEASE STORAGE FOR INVOFN. WAITS FOR ANY WRITES TO COMPLETE
;BEFORE CALLING REMFP1
REMPGI: TXNE T1,DSKAB!DRMAB ;IS THIS A CORE PAGE?
JRST REMPG2 ;NO. GO RELEASE IT NOW
PUSH P,T1 ;YES. SAVE I.D.
REMPG1: CALL SKPNWR ;WAIT FOR WRITE TO COMPLETE
JRST [ POP P,0(P) ;CLEAN UP STACK
OKSKED ;ALLOW SCHEDULING FOR THE RETRY CODE
RET] ;SAY WE BLOCKED.
POP P,T1 ;RESTORE I.D.
REMPG2: CALL REMFP1 ;GO RELEASE STORAGE
RETSKP ;AND RETURN SUCCESSFULLY
;ROUTINE CALLED FROM JSYS CODE TO SCAN OFN'S AND MARK EACH ONE
;ON THE STRUCTURE IN QUESTION DISMOUNTED.
;ACCEPTS: A/ STRUCTURE NUMBER
;RETURNS: +1 ALWAYS. WITH ALL OFN'S MARKED AND ALL
; LOCAL STORAGE RELEASED
MRKOFN::ASUBR<STRMRK> ;SAVE STRUCTURE NUMBER
STKVAR <LOOPER> ;SAVE LOOP COUNTER
MOVSI A,-NOFN ;SEARCH ALL OFN'S
MRKOF3: MOVEM A,LOOPER ;REMEMBER CURRENT LOOPER
MRKOF4: NOSKED ;GAIN CONTROL OF THE SYSTEM
SKIPN SPTH(A) ;THIS OFN IN USE?
JRST [ OKSKED ;NO. SKIP IT
JRST MRKOF1] ;""
MOVX B,SPTLKB ;SEE IF LOCKED
TDNE B,SPTH(A) ;IS IT?
JRST [ HRLZS A ;GET OFN TO LH
CALL WTOFNL ;WAIT FOR OFN TO UNLOCK
MOVE A,LOOPER ;GET BACK INDEX
JRST MRKOF4] ;GO RECHECK IT
IORM B,SPTH(A) ;NO. LOCK IT
NOINT ;PREVENT INTERRUPTION
OKSKED ;AND ALLOW SCHEDULING AGAIN
LOAD B,STRX,(A) ;GET ITS STRUCTURE NUMBER
CAME B,STRMRK ;THE SAME AS THE ONE DSIMOUNTING?
JRST MRKOF2 ;NO. SKIP IT
MOVX B,OFNDMO ;SEE IF DISMOUNTED
TDNE B,SPTH(A) ;IS IT?
JRST MRKOF2 ;YES. SKIP IT
CALL INVOFN ;MARK IT AND ITS SHARE POINTERS
MOVE A,LOOPER ;RESTORE OFN
MRKOF2: CALL ULKOFN ;FREE THIS OFN
MOVE A,LOOPER ;GET BACK LOOP CONTROL
MRKOF1: AOBJN A,MRKOF3 ;DO ALL OF THEM
RET ;DONE
RESCD ;RETURN TO RESIDENT CODE
;ROUTINE TO SEARCH FOR THE QUOTA ALLOCATION ENTRY FOR
;A GIVEN DIRECTORY.
;CALL:
; Q2/ DIRECTORY NUMBER
; FX/ STRUCTURE NUMBER
; CALL PGTCAL
; RETURN +1, DIRECTORY NOT OPENED
; RETURN +2, FOUND, T1/ CURRENT QUOTA, T2/ INDEX INTO ALCWD
PGTCAL: HRLZ T3,MAXSPL ;GET CURRENT SPT LENGTH
JUMPE T3,R ;RETURN IF EMPTY
MOVNS T3 ;MAKE AOBJN PNTR
HRRI T3,1
GETC1: LOAD T2,ALOCX,(T3) ;GET INDEX
JUMPE T2,GETCN ;SKIP NULL ENTRIES
LOAD T1,ADIRN,(T2) ;GET DIR #
CAME T1,Q2 ;WANT THIS ONE?
JRST GETCN ;NO - TRY NEXT
LOAD T1,STRX,(T3) ;GET STR #
CAME T1,FX ;CORRECT STR?
JRST GETCN ;NO - TRY SOME MORE
LOAD T1,PGLFT,(T2) ;YES - GET QUOTA LEFT
RETSKP ;GIVE GOOD RETURN
GETCN: AOBJN T3,GETC1 ;LOOP TILL DONE
RET ;FAILED (NOT FOUND)
;GLOBAL ROUTINE FOR PGTCAL
; T1/ DIRECTORY NUMBER
; T2/ STRUCTURE NUMBER
GETCAL::SAVEQ ;SAVE Q1-Q3
HRRZ Q2,T1 ;COPY ARGS TO
HRRZ FX,T2 ;SET UP FOR PGTCAL
CALLRET PGTCAL
;ADJALC - ADJUST ALLOCATION TABLE ENTRY FOR THIS DIRECTORY
;ACCEPTS:
; T1/ DIRECTORY NUMBER
; T2/ STRUCTURE NUMBER
; T3/ AMOUNT TO ADD TO THE ALLOCATION FOR THIS DIRECTORY
; CALL ADJALC
;RETURNS +1: ALWAYS
ADJALC::STKVAR <ADJADL>
MOVEM T3,ADJADL ;SAVE CHANGE
NOSKED ;NOSKED WHILE FINDING AND CHANGING SLOT
CALL GETCAL ;GET CURRENT AVAILABLE PAGE COUNT
JRST ADJAL1 ;NO OPEN FILES IN THIS DIRECTORY
ADD T1,ADJADL ;ADD THE INCREMENT
STOR T1,PGLFT,(T2) ;STORE UPDATED VALUE IN ALLOCATION ENTRY
ADJAL1: OKSKED ;ALLOW SCHEDULING AGAIN
RET
;ASSIGN PAGE TABLE USING LOCAL VALUES. CALLED FROM DSKALC TO
;ASSIGN AN SPT FOR THE NASCENT BITTABLE.
ASSPTL::SAVEQ ;SAVE REGISTERS
MOVE FX,FORKX ;USE LOCAL FORK INDEX
;ASSIGN PSB FOR NEW PROCESS
; FX/ FORK INDEX
ASSPT:: SKIPG 1,FRESPT ;ANY FREE CELLS?
BUG(HLT,SPTFL1,<SPT COMPLETELY FULL>)
HRRZ 1,0(1)
EXCH 1,FRESPT
SUBI 1,SPT
AOS SPTC ;ASSIGN SPT SLOT
MOVX 2,UAAB ;NO ACCESS
MOVEM 2,SPT(1) ;SHARE COUNT OF 1, NO ADDRESS
CALL UPSHR ;SET SHARE COUNT TO ONE
HRRZM FX,SPTH(1) ;SPTH HOLD OWNER FORK INDEX
RET
;DEASSIGN SPT AND RELEASE STORAGE
DESPT:: CALL DWNSHR ;DECREMENT SHARE COUNT
PUSH P,1 ;SAVE SPT INDEX
CALL GETSHR ;GET CURRENT SHARE COUNT
SKIPE 1 ;IS IT NOW UNSHARED?
BUG(HLT,SHRNO0,<DESPT-SHARE COUNT NON-ZERO>)
POP P,1 ;YES. RESTORE SPT
LOAD 2,STGADR,SPT(1) ;GET STORAGE ADDRESS
TXNN 2,NCORTM ;PAGE IN CORE?
JRST [ MOVSI 3,(-PLKV) ;YES
TDNE 3,CST1(2) ;LOCKED?
JRST DESPX1
JRST .+1] ;NO, OK
PUSH P,1
MOVE 1,2 ;MOVE STORAGE ADDRESS
CALL REMFP1 ;RELEASE CORE AND/OR DRUM
SKIPE 1 ;BE SURE NOTHING LEFT TO DELETE
BUG(HLT,PTDEL,<DESPT-PT NOT DELETED>)
POP P,1
MOVEI 1,SPT(1) ;CONSTRUCT PTR
EXCH 1,FRESPT ;PUT ON FREE LIST
EXCH 1,@FRESPT
SOS SPTC
RET
DESPX1: BUG(HLT,PAGLCK,<DESPT-PAGE LOCKED>)
;ASSIGN FORK STORAGE BLOCK (JSB, PSB, UPT)
ASFSB::CALLRET ASSPT ;ASSIGN SPT SLOT ONLY
REPEAT 0,< ;FOLLOWING NOT PRESENTLY USED
ACVAR <Q1>
CALL ASSPT ;ASSIGN SPT SLOT
MOVEM T1,Q1 ;SAVE IT
CALL DRMASN ;ASSIGN SWAP STORAGE
BUG(HLT,DRMFL1,<ASFSB-UNEXPECTED DRUM FULL>)
STOR T1,STGADR,SPT(Q1) ;PUT ADR IN SPT
MOVEM T1,T2
CALL GDSTX ;GET DST INDEX
MOVX T1,UAAB ;SET DST
MOVEM T1,DST(T2)
MOVE T1,Q1 ;RETURN SPT INDEX
RET
> ;END REPEAT 0
;SPECIAL ROUTINE USED BY SCHEDULER TO DELETE SECOND PSB PAGE.
;CALLED FROM HLTFK1.
REPEAT 0,<
DESSTK::SKIPN T1,PSBMAP+PSBMSZ-1 ;SEE IF PAGE EXISTS
RET ;NO. NOTHING TO DO THEN
LOAD T1,STGADR,T1 ;GET STORAGE ADDRESS ONLY
SETZM PSBMAP+PSBMSZ-1 ;ASSUME IT IS NOW CLEARED
CALLRET REMFP1 ;AND GET RID OF IT
> ;END OF REPEAT 0
;READ MAP GIVEN VIRTUAL ADDRESS
MRMAP:: CALL FPTA ;GET PAGE TABLE ADDRESS
;**********
;TEMP FIX TO FPTA RETURNING A ZERO....
;************
JUMPE T1,RDMQ5
;GENERAL MAP READ
;ENTER HAVING PTN.PN IN 1
; RETURN +1 IF PTN.PN
; RETURN +2 IF OFN.PN
MRPT:: SAVEQ
HLRZ 2,1 ;GET PTN
CALL CHKDMO ;SEE IF A DISMOUNTED OFN
CALLRET DMOINT ;IT IS. GIVE ERROR AND RETURN
CALL SETCPT
HRRZ Q2,1
MOVE 2,CPTPGA(Q2) ;GET MAP WORD
JUMPE 2,RDMQ5 ;EMPTY
LOAD Q1,PTRCOD,2 ;GET PTR TYPE
CAIN Q1,IMMCOD ;PRIVATE?
JRST MRM1 ;YES
CAIE Q1,SHRCOD ;SHARED OR INDIRECT?
JRST [ LOAD 1,IPPGN,2 ;INDIRECT, CONSTRUCT IDENT
LOAD 2,SPTX,2
HRL 1,2
JRST MRM1]
LOAD 2,SPTX,2 ;GET SPT INDEX
MOVE 1,SPTH(2) ;NO, GET OFN.PN
MRM1: HLRZ 2,1
CAIGE 2,NOFN ;OWNED BY OFN?
AOS 0(P) ;YES, SKIP RETURN
PUSH P,T1 ;SAVE IDENT
MOVE T1,CPTPGA(Q2) ;GET POINTER
CALL GPAC ;TRANSLATE ACCESS BITS
MOVE T2,T1 ;RETURN ACCESS IN T2
POP P,T1
CALLRET RELCPT
RDMQ5: SETZB 1,2 ;RETURN 0
CALLRET RELCPT
;FIND NON-0 PAGE IF ANY, AND RETURN ITS ACCESS DATA
; 1/ IDENT
; 2/ COUNT OF NUMBER OF PAGES TO SCAN
; RETURNS +1 WITH ACCESS DATA IN 1, UPDATED COUNT IN 2. IF NO
; NON-0 PAGE FOUND, 2 WILL CONTAIN 0.
MSCANP::PUSH P,B ;SAVE ARG
HLRZ B,A ;GET SPTN
CALL CHKDMO ;SEE IF DISMOUNTED
JRST [ POP P,B ;YES. IT IS
CALLRET DMOINT] ;AND GIVE ERROR
POP P,B ;GET BACK ARG
HLRZ 3,1 ;GET OFN
CAIG 3,0 ;LEGAL?
BUG(HLT,ILOFN1,<MSCANP-ILLEG IDENT>)
CALL SETXB1 ;MAP INDEX BLOCK
HRRZ T4,T1
MSCAN1: SKIPE 3,CXBPGA(4) ;EMPTY?
JRST MSCAN2 ;NO
ADDI T4,1 ;YES, BUMP IDENT TO NEXT PAGE
SOJG 2,MSCAN1 ;COUNTDOWN MAX PAGES
HRR T1,T4 ;FIX IDENT
CALLRET RELCXB ;COUNT DONE, ALL PAGES EMPTY
MSCAN2: HRR T1,T4 ;FIX IDENT
PUSH P,2 ;SAVE UPDATED COUNT
CALL MRPACS ;GET ACCESS DATA
POP P,2
RET
;READ PAGE ACCESSIBILITY
; 1/ IDENT
; RETURNS +1 WITH ACCESS INFORMATION IN RPACS FORMAT IN 1
MRPACS::SAVEPQ
SETZB Q2,P1 ;NO PTR AND NO INDIRECT COUNT
MOVX T4,PTWR+PTCPY ;ACCESS BITS TO COMPUTE
MRP4: HLRZ 2,1 ;GET PT IDENTIFIER
CALL CHKDMO ;SEE IF A DISMOUNTED OFN
JRST [ CALL DMOINT ;DELIVER ERROR
JRST MRPCX] ;AND LEAVE
HLRZ T3,T1 ;GET PTN
CAMN T3,BTBBAS ;IS THIS THE BIT TABLE IDENT?
JRST [ MOVX T2,UAAB ;YES. SEE IF IT IS MAPPED
TDNN T2,SPT(T3) ;IS IT?
JRST .+1 ;YES. PROCEED
SETZ T1, ;NO. RETURN NONEX PAGE
JRST MRPCX] ;AND DONE
CAIG T3,0
BUG(HLT,ILPTN1,<MRPACS-ILLEG PTN>)
CALL SETXB1 ;MAP PT
HRRZS T1
MOVE T3,CXBPGA(T1) ;GET PTR
SKIPN Q2 ;FIRST PTR?
MOVEM T3,Q2 ;YES, SAVE IT
JUMPE T3,MRP2 ;JUMP IF EMPTY
TXC T3,PTCPY ;'AND' 0S FOR THIS BIT
ANDM T3,T4 ;COMPUTE COMPOSIT ACCESS
LOAD Q1,PTRCOD,T3 ;GET PTR TYPE
CAIE Q1,INDCOD ;INDIRECT?
JRST MRP2 ;NO, DONE
CAIL P1,MAXIND ;ALREADY SAW TOO MANY OF THESE?
JRST [ SETZ T1, ;YES. SAY PAGE DOES NOT EXIST
JRST MRPCX] ;AND RETURN NON-EX PAGE
ADDI P1,1 ;SAW ANOTHER INDIRECT POINTER
LOAD T1,IPPGN,T3 ;YES, CONSTRUCT IDENT
LOAD T3,SPTX,T3
HRL T1,T3
JRST MRP4 ;CONTINUE TRACE
;TRACED ALL PTRS,
; Q2/ FIRST PTR
; T4/ COMPOSIT ACCESS
; T3/ LAST PTR
MRP2: JUMPE Q2,[SETZ T1, ;FIRST PTR NULL, RETURN 0
JRST MRPCX]
MOVE T1,T4
TXC T1,PTCPY+PTRCOD ;NOT (AND (NOT ..))
CALL GPAC ;TRANSLATE ACCESS TO USER BITS
MOVEM T1,T4
LOAD Q1,PTRCOD,Q2 ;GET FIRST PTR TYPE
CAIN Q1,INDCOD ;INDIRECT?
TXO T4,PA%IND ;YES
CAIN Q1,IMMCOD ;PRIVATE?
TXO T4,PA%PRV ;YES
MOVE T1,Q2
CALL GPAC ;TRANSLATE ACCESS OF FIRST PTR
HLRZ T1,T1 ;RETURN IT IN RH
HLL T1,T4 ;RETURN COMPOSIT IN LH
JUMPE T3,MRPCY ;CLEAR 'EXISTS' IF LAST PTR EMPTY
LOAD Q1,PTRCOD,T3 ;GET TYPE OF LAST PTR
CAIE Q1,SHRCOD ;SHARED?
JRST MRPCX ;NO
LOAD T3,SPTX,T3 ;YES, CHECK ADDRESS
LOAD T3,STGADR,SPT(T3)
TXNN T3,DSKAB+DRMAB ;UNASSIGNED?
TXNN T3,UAAB
JRST MRPCX ;NO, ELSE CLEAR EXISTS
MRPCY: TXZ T1,PA%PEX ;CLEAR 'EXISTS'
MRPCX: CALLRET RELCXB ;RELEASE TEMP MAPPING AND RETURN
;TRANSLATE POINTER ACCESS BITS TO USER ACCESS BITS
; T1/ POINTER
; CALL GPAC
; RETURN +1 ALWAYS, T1/ USER ACCESS BITS
GPAC: JUMPE T1,R ;NULL PTR YEILDS 0
MOVE T2,T1
MOVX T1,PA%RD+PA%EX+PA%PEX ;SAY POINTER EXISTS
TXNE T2,PTWR ;WRITE?
TXO T1,PA%WT ;YES
TXNE T2,PTCPY ;COPY?
TXO T1,PA%CPY ;YES
RET
;TRANSLATE USER ACCESS BITS TO POINTER ACCESS BITS
; T2/ USER BITS
; T3/ POINTER TO BE SET
; CALL SPAC
; RETURN +1, T3/ MODIFIED POINTER
SPAC: TXZ T3,PTWR+PTCPY ;SET THESE BITS...
TXNE T2,PA%WT ;WRITE?
TXO T3,PTWR ;YES
TXNE T2,PA%CPY ;COPY?
TXO T3,PTCPY ;YES
RET
;SET PAGE ACCESSIBILITY
; T1/ IDENT
; T2/ ACCESS
MSPACS::PUSH P,2
CALL SETCPT ;MAP PT
HRRZ T4,T1
POP P,2
SKIPN CPTPGA(T4) ;PAGE EXISTS?
JRST MRSPX ;NO, IGNORE CALL
HLRZ 3,1
CAIGE 3,NOFN ;FILE?
JRST MRSPX ;YES, DO NOTHING
NOSKED
MOVE 3,CPTPGA(T4) ;GET PTR
CALL SPAC ;SET POINTER BITS PER USER REQUEST
MOVEM 3,CPTPGA(T4) ;STORE MODIFIED PTR
CALL MONCLA ;MAKE SURE PAGER NOTICES DIFFERENCES
OKSKED
MRSPX: CALLRET RELCPT
;MRPAC - JSYS FOR MONITOR DDT
.MRPAC::MCENT
MOVE 2,0(P) ;RETURN PC
TLNE 2,(UMODF) ;FROM MONITOR?
ITERR(ILINS1) ;NO, ILLEGAL FROM USER
TLNE 1,(1B0) ;USER?
JRST [ CALL FPTA ;YES, GET PTN.PN
JUMPE T1,MRPC1 ;IF NO SECTION, DO NO-ACCESS
JRST MRPC3]
HRRZ 2,1
CAIGE 2,PPRMA ;NON-RES MON?
JRST [ LSH 2,-PGSFT ;NO, IS RESIDENT MAPPED MON
MOVE 1,MMAP(2) ;GET PTR
CALL GPAC ;TRANSLATE PTR TO ACCESS BITS
TLO 1,(PA%PRV) ;NOTE PRIV PTR
JRST MRPC2] ;RETURN CONTENTS OF MMAP
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
JUMPE T1,MRPC1 ;IF NO SECTION, RETURN NO-ACCESS
MRPC3: CALL MRPACS
MRPC2: UMOVEM 1,2 ;RETURN RESULT IN 2 LIKE RPACS
JRST MRETN
MRPC1: MOVSI 1,(PA%PRV) ;NO-ACCESS
JRST MRPC2
;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
; 1-17 - ACCESS
SETMPG::TRVAR <SID,ADR,ARG3,ARG4,DEST>
DMOVEM T1,SID ;SAVE ARGS
DMOVEM T3,ARG3
CALL VERPT ;GO VERIFY NO DISMOUNTED OFN
RET ;USER REQUESTED BAD OFN. IGNORE IT
HLLZ 3,2 ;GET ACCESS
MOVE 1,2
CALL FPTA ;CONVERT ADDRESS TO PTN.PN
JUMPE T1,SETMPX ;IF NO SECTION, ERROR
MOVEM T1,DEST ;SAVE DEST I.D.
CALL SETCPT ;SETUP PAGE TABLE
CALL LCKOFI ;LOCK DEST IF OFN
MOVE 2,SID ;GET SOURCE IDENT
CALL RELMP5 ;RELEASE OLD CONTENTS
MOVE T1,DEST
MOVE T2,SID ;RESTORE ARGS
SKIPGE ADR ;CHANGING EXEC OR USER MAP?
JRST [ CALL PGRCLD ;USER, CLEAR ALL
JRST .+2]
HLLZ T3,ADR ;GET ACCESS BITS
CALL MONCLA ;EXEC, CLEAR EXEC SCRATCHPAD
CALL SETPT0 ;SET NEW CONTENTS
MSETM2: CALL RELCXB ;RELEASE SOURCE PT
CALL RELCPT ;RELEASE DESTINATION PT
CALL ULKOFI ;UNLOCK DEST IF OFN
DMOVE T1,SID ;RESTORE TEMPS
DMOVE T3,ARG3
RET
;MULTIPLE SET PAGE IN MAP - SAME AS ABOVE EXCEPT
; 3/ NUMBER OF SUCCESSIVE PAGES TO BE SET
MSETMP::TRVAR <SID,ADR,PCT,ARG4,DEST>
DMOVEM T1,SID ;SAVE ARGS
DMOVEM T3,PCT
CALL VERPT ;GO VERIFY NOT USING DISMOUNTED OFN
RET ;CAN'T MAP DISMOUNTED OFN
HLLZ 3,2 ;ACCESS BITS
MOVE 1,2
CALL FPTA ;CONVERT DESTINATION TO PTN.PN
JUMPE T1,SETMPX ;IF NO SECTION, ERROR
MOVEM T1,DEST ;SAVE DEST I.D.
CALL SETCPT ;MAP DESTINATION PT
CALL LCKOFI ;LOCK DEST IF OFN
MOVE 2,SID ;GET SOURCE PTN.PN
MSETM1: CALL RELMP5 ;RELEASE EXISTING CONTENTS OF DEST
MOVE T2,SID
MOVE T1,DEST ;RESTORE ARGS
HLLZ T3,ADR ;GET ACCESS BITS
CALL SETPT0 ;SET NEW CONTENTS
AOS T1,DEST ;NEXT DEST ADDRESS
SKIPE 2 ;SOURCE 0?
AOS T2,SID ;NEXT SOURCE IF APPROPRIATE
SOSLE PCT ;COUNT PAGES DONE
JRST MSETM1
SKIPGE ADR ;CHANGING EXEC OR USER MAP?
JRST [ CALL PGRCLD ;USE, CLEAR ALL
JRST .+2]
CALL MONCLA ;EXEC, CLEAR EXEC ONLY
JRST MSETM2
;LOCAL ROUTINE USED BY SETMPG AND MSETMP TO VERIFY THAT REQUESTOR
;IS NOT SELECTING A DISMOUNTED OFN.
VERPT: JUMPE 1,RSKP ;IF DELETING, ALLOW IT
SAVEAC <T2> ;DON'T CLOBBER ANY ARGS
HLRZ 2,1 ;GET OFN
SKIPN 2 ;WAS THIS AN OFN.PN?
MOVEI 2,0(1) ;NO. IS 0,,OFN. SO GET THE OFN
CALL CHKDMO ;SEE IF DISMOUNTED
CALLRET DMOINT ;YES. PROVIDE AN INTERRUPT
RETSKP ;NO. ALLOW MAP
;LOCAL ROUTINE USED BY SETPT AND MSETPT TO VERIFY THAT REQUESTOR
;IS NOT SELECTING A DISMOUNTED OFN.
PTVER: JUMPE 1,RSKP ;IF DELETING, ALLOW IT
SAVEAC <T2> ;DON'T CLOBBER ANY ARGS
STKVAR <AR2> ;SAVE DESTINATION HERE
MOVEM 2,AR2 ;SAVE DESTINATION
HLRZ 2,1 ;GET OFN OF SOURCE
SKIPN 2 ;WAS THIS OFN.PN?
MOVEI 2,0(1) ;NO. IS 0,,OFN. SO GET THE OFN
CALL CHKDMO ;SEE IF DISMOUNTED
CALLRET DMOINT ;YES. PROVIDE INTERRUPT
HLRZ 2,AR2 ;GET OFN OF DESTINATION
CALL CHKDMO ;SEE IF IT IS DISMOUNTED
CALLRET DMOINT ;YES. GIVE INTERRUPT
RETSKP ;NO. ALLOW MAP
;ROUTINE TO DELIVER A PSEUDO INTERRUPT TO PROCESS. THIS ROUTINE
;IS CALLED WHENEVER A PROCESS ATTEMPTS TO ILLEGALLY MAP A PAGE
;FROM A DISMOUNTED OFN.
DMOINT: SAVET
MOVEI A,PMAPX7 ;PROVIDE CHARACTERISTIC CODE
MOVEM A,LSTERR ; FOR PROCESS TO SEE
MOVEI A,.ICIRD ;GENERATE ILLEGAL MEM READ
CALL PSIRQ0 ; TO THIS PROCESS
CHKINT ;MAKE SURE PROCESS SEES IT ASAP
RET ;AND DONE
;ATTEMPT TO MAP A NON-EXISTANT SECTION
SETMPX: BUG (HLT,SECEX1,<SETMPG-ATTEMPT TO MAP NON-EX SECTION>)
;MAP PHYSICAL CORE PAGE
; T1/ DESTINATION IDENT
; T2/ PHYSICAL PAGE NUMBER
; CALL MAPPHP
; RETURN +1: FAILURE, PAGE LOCKED OR OTHERWISE INACCESSIBLE
; RETURN +2: SUCCESS, PRIVATE POINTER SETUP
MAPPHP::ASUBR <ID,PGNO>
CAMLE T2,NHIPG ;WITHIN KNOWN RANGE?
BUG(HLT,XSCORE,<CST TO SMALL FOR PHYSICAL CORE PRESENT>)
CALL SETCPT ;MAP DESTINATION PT
CALL RELMP5 ;CLEAR PREVIOUS CONTENTS
CALL MONCLA ;CLEAR PAGE MEMORY
NOSKED
MOVE T1,PGNO
CAMGE T1,MONCOR ;RES MONITOR PAGE?
JRST [ CALL RESPCK ;CHECK RESMON PAGE
JRST .+1 ;NOT PART OF RESMON
MOVE T2,ID ;YES, DON'T CHANGE CST
JRST MAPPH1]
MOVX T2,-PLKV
TDNE T2,CST1(T1) ;PAGE LOCKED?
JRST MAPPHX ;YES, CAN'T GRAB IT
CALL RPCST ;RELEASE PAGE FROM PRESENT USE
CALL AGESET ;ASSIGN PAGE HERE
MOVX T2,UAAB ;SET UNASSIGNED BACKUP ADDRESS
MOVEM T2,CST1(T1)
MOVE T2,ID
MOVEM T2,CST2(T1) ;SET OWNER ID
MAPPH1: IOR T1,IMMPTR ;CONSTRUCT PRIVATE PTR
HRRZS T2 ;PREVENT PAGE FAULT
MOVEM T1,CPTPGA(T2) ;PUT IN DEST MAP
HLRZ T1,ID ;GET PT I.D.
LOAD T1,STGADR,SPT(T1) ;GET MEMORY PAGE NUMBER
MOVX T2,PLKV ;ONE UNIT OF LOCK COUNT
ADDM T2,CST1(T1) ;ONE MORE PAGE IN MEMORY
OKSKED
CALL RELCPT ;RELEASE DEST MAP
MOVE T2,PGNO ;RESTORE ARG
RETSKP
MAPPHX: OKSKED
CALLRET RELCPT
;MAP PHYSICAL PAGE INTO MONITOR ADDRESS
; T1/ PHYSICAL CORE PAGE NUMBER
; T2/ MONITOR VIRTUAL ADDRESS
; CALL MAPPHA
; SAME AS MAPPHP EXCEPT TAKES MONITOR VIRTUAL ADDRESS
MAPPHA::EXCH T1,T2
CALL FPTA ;TRANSLATE ADDRESS TO IDENT
JUMPE T1,SETMPX ;SECTION MUST EXIST
CALLRET MAPPHP ;DO THE WORK
;ROUTINE TO SEE IF A PAGE LESS THAN MONCOR IS STILL PART
;OF MONITOR MAP.
;ACCEPTS: T1/ PAGE NUMBER
;RETURNS: +1 NOT PART OF MONITOR MAP
; +2 PART OF MONITOR MAP
RESPCK: HLRZ T2,CST2(T1) ;GET PRESENT OWNER
CAME T2,MMSPTN ;OWNED BY MONITOR MAP?
RET ;NO
RETSKP ;YES
;MMAPWE AND MMAPWP- ROUTINES TO WRITE ENABLE OR WRITE PROTECT THE MONITOR'S MAP
;ACCEPTS:
; T1/VIRTUAL ADDRESS OF FIRST PAGE AFFECTED
; T2/COUNT OF NUMBER OF PAGES TO AFFECT
;CALL MMAPWE OR CALL MMAPWP
;RETURNS +1 ALWAYS
;THIS ROUTINE MODIFIES THE ACCESS FOR CONSECUTIVE PAGES IN THE MONITOR'S MAP.
;IT MODIFIES MMAP FOR PAGES BELOW THE JSB, JOBMAP FOR PAGES IN THE JSB, AND
;PSBMAP FOR PAGES IN THE PER PROCESS REGION. IT ASSUMES THAT THE RANGE
;SPECIFIED DOES NOT EXTEND BEYOND THE STARTING REGION. THAT IS, ALL PAGES
;ARE BETWEEN 0 AND 577, OR 600 AND 677, OR 700 AND 777.
MMAPWE::SKIPA T3,[IORM T4,0(T1)] ;T3/INSTRUCTION TO WRITE-ENABLE
MMAPWP::MOVE T3,[ANDCAM T4,0(T1)] ;T3/INSTRUCTION TO WRITE-PROTECT
LOAD T1,VPGNO,T1 ;GET PAGE NUMBER
CAIL T1,PSSPS ;BELOW THE PSB?
JRST [ ADDI T1,PSBMAP-PSSPS ;IN THE PSB. POINT TO ENTRY IN PSBMAP FOR FIRST PAGE
JRST MM1] ;GO LOOP THROUGH PAGES
CAIL T1,JSBPG ;BELOW THE JSB?
JRST [ ADDI T1,JOBMAP-JSBPG ;IN THE JSB. POINT TO ENTRY IN JOBMAP FOR FIRST PAGE
JRST MM1] ;GO LOOP THROUGH PAGES
ADDI T1,MMAP ;IN MMAP. POINT TO ENTRY FOR THE FIRST PAGE
;T1 HAS THE ADDRESS OF THE FIRST WORD OF THE MAP. LOOP THROUGH ENTRIES
;ACCORDING TO COUNT IN T2
MM1: MOVX T4,PTWR ;T4/WRITE ACCESS
MM2: SKIPE 0(T1) ;IGNORE NON-EXISTANT PAGE
XCT T3 ;WRITE ENABLE OR PROTECT ACCORDING TO EARLIER SETUP OF T3
AOS T1 ;POINT TO NEXT WORD
SOJG T2,MM2 ;AT THE END?
CALLRET MONCLA ;YES. MAKE THE PAGER SEE THE CHANGES
;SET PAGE TABLE (FOR PROCESS OR FILE)
; AC1/ SOURCE IDENTIFIER
; AC2/ DESTINATION IDENTIFIER
; T3/ 0-17 ACCESS INFO
;IDENT IS OFN.PN (PAGE IN FILE), 0.OFN (INDEX BLOCK),
; PTN.PN (PAGE IN PROCESS), OR 0.PTN (PROCESS PT)
SETPT:: CALL PTVER ;VERIFY ARGS
RET ;CAN'T USED A DISMOUNTED OFN
EXCH 1,2
CALL RELMPG ;RELEASE EXISTING PAGE
CALL SETPT0
CALL RELCXB ;RELEASE SOURCE PT
CALL RELCPT ;RELEASE DESTINATION PT
CALL ULKOFI ;UNLOCK DEST IF OFN
EXCH 1,2
RET
;MULTIPLE SET PAGE TABLE - SAME AS SETPT, EXCEPT
; 4/ COUNT OF NUMBER OF SUCCESSIVE PAGES TO SET
MSETPT::ASUBR <SID,DID,ARG3,ARG4>
CALL PTVER ;VERIFY ARGS
RET ;CAN'T USE A DISMOUNTED OFN
MOVE 1,2
CALL SETCPT ;SETUP DESTINATION MAP
CALL LCKOFI ;LOCK DEST IF OFN
MOVE 2,SID ;GET SOURCE PTR
MSETP1: CALL RELMP5 ;RELEASE OLD CONTENTS
MOVE T2,SID
MOVE T1,DID ;RESTORE ARGS
MOVE T3,ARG3 ;ACCESS BITS
CALL SETPT0 ;SET NEW CONTENTS
AOS T1,DID ;NEXT DEST PAGE
SKIPE 2
AOS T2,SID ;NEXT SOURCE IF APPROPRIATE
SOSLE ARG4 ;MORE TO DO?
JRST MSETP1 ;DO IT
CALL PGRCLD ;CLEAR PAGER SCRATCHPAD
JRST MSETM2
;SET NEW CONTENTS OF PT
SETPT0: JUMPE 2,R ;CHECK FOR NO NEW PAGE TO SET
ASUBR <ARG1,ARG2,ARG3,ARG4>
NOSKED
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
TXNE 2,<<^-SPTM>B17+777000> ;LEGAL PTN AND PN?
BUG(HLT,ILSRC,<ILLEGAL SOURCE IDENTIFIER GIVEN TO SETPT>)
MOVE 3,ARG3 ;GET FLAGS
TXNE 3,PM%MVP ;MOVE OF PAGE REQUESTED?
JRST [ CALL MVPT ;YES, DO IT
JRST SETPTE ;FAILED
JRST SETPT2]
HLRZ 4,1 ;GET DESTINATION PTN
CAIGE 4,NOFN ;FILE?
JRST [ CALL MVPT ;YES, **SHOULD BE CHANGED TO SETPF1**
JRST SETPTE
JRST SETPT2]
HLRZ 4,2 ;GET SOURCE PTN
TXNN T3,PM%IND ;OR INDIRECT PTR REQUESTED?
CAIL 4,NOFN ;PROCESS?
JRST SETP5 ;YES, GO SETUP INDIRECT POINTER
HLRZ T3,T2 ;GET SOURCE PTN
CALL SETXB1 ;MAP SOURCE XB
OKSKED
HRRZ T3,T2
SKIP CXBPGA(T3) ;REFERENCE PAGE WHILE OKSKED
NOSKED
MOVE T3,CXBPGA(T3) ;GET WORD FROM XB
JUMPE 3,SETP5 ;JUMP IF PAGE NONEXISTENT
LOAD 4,PTRCOD,3 ;GET PTR TYPE
CAIN 4,INDCOD ;INDIRECT?
BUG(HLT,ILXBP,<SETPT-BAD POINTER IN XB>)
CAIN 4,SHRCOD ;ALREADY SHARED?
JRST SETMP3 ;YES, GO USE SAME POINTER
MOVE 4,SPTC ;YES
CAMGE 4,SPC0 ;ROOM IN SPT? (SPT .L. C FULL)
JRST SETMP6 ;YES, SETUP SHARE PTR
JRST SETP5 ;USE IND PTR
;ERROR RETURNS
SETPF1: MOVEI 1,PMAPX2 ;PMAP-ILLEGAL CASE
SETPTE: MOVEM 1,LSTERR
MOVEI 2,.ICILI ;ERROR CHANNEL
CAIN 1,IOX11 ;DISK FULL?
MOVEI 2,.ICQTA ;YES - USE THIS CHL
MOVE 1,2 ;COPY CHL TO T1
SETPF2: CALL PSIRQ0 ;REQUEST PSI
CHKINT ;GET IT SEEN
JRST SETPT2
;HERE TO CONSTRUCT INDIRECT PTR TO SOURCE
SETP5:
REPEAT 0,<
;SOMETHING POSSIBLY NEEDED HERE TO DETECT LOOPS OF INDIRECT PTRS.
;THIS CODE FORMERLY NEEDED TO ELIMINATE CHAINS OF INDIRECT PTRS
;BECAUSE OF BBN PAGER LIMITATION, ALSO WOULD DETECT SIMPLE LOOPS
;BUT NOT FIGURE 6'S, ETC.
LOAD 4,PTRCOD,3 ;GET TYPE CODE
CAIN 4,INDCOD ;INDIRECT?
JRST [ LOAD 4,SPTX,3 ;YES, GET SPTN
CAIGE 4,NOFN ;VIA INDEX BLOCK?
JRST .+1 ;YES, OK
CALL RELCXB ;NO, TRACE DOWN
LOAD 2,IPPGN,3 ;CONSTRUCT ID OF PAGE POINTED
HRLI 2,0(4) ; TO BY INDIRECT PTR
JRST SETP5A] ;AND USE THAT AS SOURCE
> ;END REPEAT 0
HLRZ T3,T2 ;GET SPTN
MOVE T4,T1 ;SAVE STORAGE ADDRESS
MOVEI T1,0(T3) ;GET SPTN
CALL GETSHR ;GET SHARE COUNT
EXCH T1,T4 ;RESTORE VALUES
CAIL T4,MAXSC0 ;TOO MUCH?
JRST [ CAIGE T3,NOFN ;IS THIS AN OFN?
JRST .+1 ;YES. WE CAN LET IT GO THEN
MOVEI T1,PMAPX6 ;NO. SHARE COUNT TOO LARGE
JRST SETPTE]
MOVE 4,INDPTR ;CONSTRUCT IND PTR
STOR 3,SPTX,4 ;PUT SPTN IN PTR
STOR 2,IPPGN,4 ;PUT PN IN PTR
MOVE 2,4
SETMP4: LOAD 3,SPTX,2 ;GET OFN OF INDEX BLOCK
SETMP5: JUMPE T3,SETMP2 ;JUMP IF NO SPT
CALL SETSHR ;LOCAL CALL TO INCREMENT SHARE COUNT
SETMP2: MOVE T3,T2 ;INITIAL POINTER...
MOVE T2,ARG3 ;GET USER ACCESS BITS
CALL SPAC ;SET POINTER ACCESS BITS FROM USER
HRRZS T1
SKIPE CPTPGA(T1) ;BE SURE PREVIOUS CONTENTS NULL
BUG(HLT,PTNON0,<SETPT0 - PREVIOUS CONTENTS NON-0>)
MOVEM T3,CPTPGA(1) ;PUT MAP WORD IN MAP
SETPT2: OKSKED
DMOVE T1,ARG1 ;RESTORE ARGS
DMOVE T3,ARG3
RET
SETMXB: CAIL 2,SSPT ;LEGAL NUMBER?
BUG(HLT,ILSPTI,<ILLEGAL SPT INDEX GIVEN TO SETMXB>)
HLRZ 3,1 ;GET DESTINATION PTN
CAIGE 3,NOFN ;FILE?
BUG(HLT,ILDEST,<ILLEGAL DESTINATION IDENTIFIER TO SETMPG OR SETPT>)
HRRZ 3,2
MOVE 2,SHRPTR ;CONSTRUCT SHARE PTR TO INDEX BLOCK
STOR 3,SPTX,2
JRST SETMP5
;SETUP NEW SHARED PAGE
SETMP6: SKIPG 4,FRESPT ;ASSIGN NEW SPT SLOT
BUG(HLT,SPTFL2,<SPT COMPLETELY FULL>)
HRRZ 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,(NCORTM) ;IN CORE?
JRST SETP2
PUSH P,5
PUSH P,6
HRRZ 6,3
CAME 2,CST2(6) ;CHECK OLD OWNERSHIP
BUG(HLT,CST2I1,<PAGE TABLE CORE POINTER AND CST2 FAIL TO CORRESPOND>)
MOVEM 4,CST2(6) ;RECORD NEW LOCATION OF CORE ADDRESS
HLRZ 6,2 ;YES, UPDATE LOCK COUNT FOR
HRRZ 6,SPT(6) ;OWNING PT
MOVSI 5,(-PLKV) ;REDUCE IT, BECAUSE IT WILL HAVE
ADDM 5,CST1(6) ;ONE LESS CORE ADDRESS IN IT
POP P,6
POP P,5
SETP2: ANDX 3,STGADM
MOVEM 3,SPT(4) ;PUT IT IN SPT
MOVEM 2,SPTH(4) ;PUT OFN.PN IN SPTH
MOVE 3,SHRPTR ;MAKE SHARE PTR
STOR 4,SPTX,3
HRRZ T4,T2
MOVEM 3,CXBPGA(T4) ;STORE IT IN XB
HLRZ 3,2 ;GET OFN
CALL SETSHR ;LOCAL INCREMENT SHARE COUNT
SETMP3: HRRZ T3,T2
LOAD 3,SPTX,CXBPGA(T3) ;GET SPT INDEX
CAME 2,SPTH(3) ;ALL OK?
BUG(HLT,ILSPTH,<SETPT-SPTH INCONSISTENT WITH XB>)
CALL SETSHR ;LOCAL INCREMENT SHARE COUNT
HLRZ 3,2 ;GET OFN
HRRZS 2
MOVE 2,CXBPGA(2) ;GET THE POINTER
JRST SETMP5 ;GO PUT IT IN PT
;LOCAL ROUNTINE TO INCREMENT SHARE COUNT OF SPT INDEX IN 3
SETSHR: EXCH T1,T3 ;SAVE CONTENTS OF 1. GET ARG
CALL UPSHR ;INCREMENT SHARE COUNT
EXCH T1,T3 ;RESTORE REGS
RET ;AND DONE
;MOVE PAGE. PAGE IS REMOVED FROM SOURCE RATHER THAN BECOMING SHARED
; 1/ DESTINATION ID, PT MAPPED INTO CPTPG
; 2/ SOURCE ID, PT MAPPED INTO CXBPG
; CALL MVPT
; RETURN +1, FAILURE, ERROR CODE IN A
; RETURN +2, SUCCESS.
MVPT: HLRZ T3,T2 ;GET SOURCE PTN
CALL SETXB1 ;MAP INDEX BLOCK
OKSKED
HRRZ T4,T2 ;GET ADDRESS ONLY
SKIP CXBPGA(T4) ;REFERENCE PAGE WHILE OKSKED
NOSKED
HLRZ 4,2 ;GET SOURCE AND DEST PTN'S
HLRZ 3,1
CAIGE 3,NOFN ;DEST IS FILE?
JRST [ CAIL 4,NOFN ;YES, SOURCE ALSO?
JRST SETP7 ;NO, DO FORK-TO-FILE CASE
HRRZ T3,T2
LOAD 3,PTRCOD,CXBPGA(3) ;FILE-TO-FILE CASE,
CAIE 3,IMMCOD ;PAGE NOW PRIVATE?
RETBAD(PMAPX3) ;NO, ERROR
JRST MVPT1]
CAIGE 4,NOFN ;DEST IS FORK, SOURCE ALSO?
RETBAD(PMAPX4) ;NO, FILE-TO-FORK ILLEGAL
MVPT1: HRRZ T3,T2
MOVE 3,CXBPGA(3) ;GET PTR
JUMPE 3,MVPT3 ;NOP IF NULL
LOAD 4,PTRCOD,3 ;GET PTR TYPE
CAIN 4,IMMCOD ;PRIVATE AND IN CORE?
TLNE 3,(NCORTM)
JRST MVPT2
HRRZ 4,3 ;GET ADDRESS ONLY
CAME 2,CST2(4) ;YES, CHECK CST CONSISTENCY
BUG(HLT,CST2I2,<MVPT-CST2 INCONSISTENT>)
MOVEM 1,CST2(4) ;NOTE NEW LOCATION OF POINTER
CALL MVLK ;MOVE THE PT LOCK COUNT
PUSH P,1
HRRZ 1,2
MOVE 1,CXBPGA(1) ;GET CORE PAGE NUMBER
CALL DECOR ;DEASSIGN PAGE FROM WS
POP P,1
MVPT2: SETZ 3,
HRRZ 4,2
EXCH 3,CXBPGA(4) ;REMOVE PTR FROM OLD LOCATION
HLRZ T4,T1
HRRZS T1
CAIGE T4,NOFN ;DEST IS FILE?
JRST [ ANDX T3,STGADM ;YES, EXTRACT STG ADR FROM PRIV PTR
IOR T3,IMMPTR ;MAKE STANDARD POINTER
MOVEM T3,CPTPGA(T1) ;PUT IN XB
JRST MVPT3]
MOVE T2,ARG3 ;GET USER ACCESS BITS
CALL SPAC ;SET THEM INTO POINTER
MOVEM 3,CPTPGA(1) ;PUT IT IN NEW LOCATION
MVPT3: RETSKP
;LOCAL ROUTINE TO MOVE PT LOCK COUNT WHEN MOVING CORE PTR
MVLK: HLRZ 4,2 ;SOURCE PTN
HRRZ 4,SPT(4)
MOVSI 3,(-PLKV)
ADDM 3,CST1(4) ;REDUCE LOCK COUNT OF PT
HLRZ 4,1
HRRZ 4,SPT(4)
MOVSI 3,(PLKV)
ADDM 3,CST1(4) ;INCREASE LOCK COUNT OF XB
RET
;DESTINATION IS FILE, SOURCE FORK
SETP7: HRRZ T3,T2
MOVE 3,CXBPGA(3) ;GET PTR
JUMPE 3,SETP7K ;JUMP IF PAGE NON-EXISTENT
LOAD 4,PTRCOD,3 ;GET PTR TYPE
CAIE 4,IMMCOD ;NOT PRIVATE?
RETBAD(PMAPX3) ;YES, ERROR
PUSH P,5
HRRZ 5,3 ;ELIMINATE LEFT HALF OF 3
TLNE 3,(DSKAB) ;NOW ON DISK?
JRST SETP71 ;YES
TLNE 3,(DRMAB) ;NOW ON DRUM?
JRST SETP7D ;YES, GO ADJUST DRUM BACKUP ADR
LOAD 4,STGADR,3 ;IN CORE, GET PAGE NUMBER
CAML 4,MONCOR ;NORMAL SWAPPING PAGE?
CAMLE 4,NHIPG
JRST [ POP P,5 ;NO, CAN'T MAP INTO FILE
RETBAD(PMAPX5)]
PUSH P,1
MOVEI 1,0(5)
CALL AGESET ;FIX PAGE
POP P,1
MOVSI 4,(PLKV) ;IN CORE,
ADDB 4,CST1(5) ;GET BACKUP ADR AND LOCK PAGE
TLNE 4,(DSKAB) ;DISK?
JRST SETP7C ;YES
TLNE 4,(DRMAB) ;DRUM?
JRST SETP7E ;YES
MOVEI 4,CST1(5) ;NOT ASSIGNED, PUT BACKUP ADR IN CST1
CALL SETP7A ;ASSIGN BACKUP ADR AND STORE IT
JRST [ HRRZ 5,T3 ;FAILED. GET CORE ADDRESS
MOVSI T1,(-PLKV)
ADDM T1,CST1(5) ;UNLOCK PAGE
POP P,5 ;CLEAN UP THE STACK
RETBAD (IOX11)] ;FAIL RETURN, NO ROOM
SETP7C: PUSH P,3
HRRZ 5,3
MOVEM 1,CST2(5) ;IN CORE, ADJUST CST
MOVSI 4,(-PLKV)
ADDM 4,CST1(5) ;UNLOCK PAGE
CALL MVLK ;MOVE PT LOCK COUNT
POP P,3
SETP71: HRRZ 5,2
SETZM CXBPGA(5) ;PUT SOURCE PTR IN DEST MAP
ANDX 3,STGADM ;EXTRACT STORAGE ADDRESS
IOR 3,IMMPTR ;MAKE PRIVATE PTR
PUSH P,1
HRRZS 1
MOVEM 3,CPTPGA(1)
SETP72: MOVE 1,0(P) ;BE SURE WE HAVE IDENT
HRRZ 3,1
MOVE 3,CPTPGA(3) ;GET CURRENT ADR OF PAGE
TLNE 3,(DSKAB) ;PAGE NOW ON DSK?
JRST SETP73 ;YES, DONE
TLNE 3,(DRMAB) ;ON DRUM?
JRST [ CALL SWPINW ;YES, GET IT IN CORE
JRST SETP72] ;RECHECK ADDRESS
HRRZS 1
MOVE 1,CPTPGA(1) ;GET CURRENT ADDRESS OF PAGE
CALL SKPNWR ;WRITE IN PROGRESS?
JRST SETP72 ;YES, RECHECK ADDRESS
MOVX 2,DSKSWB ;GET DISK BIT
IORM 2,CST3(1) ;AND SET DISK BIT IN CST
CALL SWPOT0 ;SWAP PAGE TO DISK
SETP73: POP P,1
POP P,5
SETP7K: HLRZ 3,1 ;GET DEST OFN
MOVX 4,OFNWRB ;NOTE CHANGE TO IT
IORM 4,SPTH(3)
RETSKP
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
TLNE 5,(DSKAB) ;DISK?
JRST SETPE1
CALL SETP7A ;NO, ASSIGN DISK ADDRESS AND STORE IT
JRST [ HRRZ 5,T3 ;FAILED. GET CORE ADDRESS (IF ONE)
MOVSI T1,(-PLKV)
TLNN T3,(NCORTM) ;CORE PAGE?
ADDM T1,CST1(5) ;UNLOCK PAGE
POP P,5 ;CLEAN UP THE STACK
RETBAD (IOX11)] ;FAIL RETURN
SETPE1: TLNN 3,(NCORTM)
JRST SETP7C
JRST SETP71
SETP7A: HLRZ 5,1 ;GET OFN OF DESTINATION FILE
ADJSP P,4 ;SAVE T1-T4
DMOVEM T1,-3(P)
DMOVEM T3,-1(P)
MOVE T1,5 ;OFN TO CHECK
CALL QCHK ;SEE IF OK TO ASSIGN DISK PAGE
JRST SETP7B ;ERROR - BOMB OUT NOW
MOVE T1,-3(P) ;GET DEST IDENT
CALL FNDLDA ;GET LAST DISK ADR ASSIGNED FOR DSKASN
LOAD T2,STRX,(5) ;GET STRUCTURE NUMBER
CALL DSKASN ;ASSIGN DISK ADDRESS FOR PAGE
SETP7B: SETO T1, ;DISK FULL
MOVE 5,T1 ;SAVE ADDRS (OR FLAG)
DMOVE T1,-3(P) ;RESTORE T1-T2
JUMPL 5,SETP7Y ;SKIP IF ERROR
HLRZ T3,T1 ;GET OFN AGAIN
LOAD T3,ALOCX,(T3) ;INDEX INTO QUOTA TABLE
DECR PGLFT,(T3) ;ONE LESS PAGE LEFT
SETP7Y: DMOVE T3,-1(P) ;RESTORE T3-T4
ADJSP P,-4 ;CLEAN OFF STACK
JUMPL 5,R ;FAIL RETURN
STOR 5,STGADR,0(T4) ;STORE ADDRESS PER ARG
RETSKP
;PUT INDEX BLOCK IN FIXED PAGE (CXBPG) OF PP MAP FOR TEMP USE
; 3/ SPTN
SETXB1: PUSH P,SHRPTR ;CONSTRUCT SHARE PTR
STOR 3,SPTX,0(P)
POP P,3
CAMN 3,PSBM0+CXBPG ;ALREADY THERE?
RET ;YES
CALL RELCXB ;RELEASE CURRENT ONE
NOINT ;NO INTERRUPTS WHILE XB MAPPED
MOVEM 3,PSBM0+CXBPG ;PUT INTO CURRENT X BLOCK PAGE
RET
;RELEASE INDEX BLOCK NOW IN FIXED PAGE
RELCXB: SKIPN PSBM0+CXBPG
RET ;NONE THERE NOW
SETZM PSBM0+CXBPG ;CLEAR MAP
PUSH P,1
MOVEI 1,CXBPGA
CALL MONCLR ;CLEAR MAP ENTRY
POP P,1
OKINT
RET
;MAP CURRENT PAGE TABLE FOR TEMP USE
; 1/ SPTN,,PN ;PN IGNORED
SETCPT: HLRZ 2,1 ;GET PTN
PUSH P,SHRPTR ;CONSTRUCT SHARE PTR
STOR 2,SPTX,0(P)
POP P,2
CAMN 2,PSBM0+CPTPG ;ALREADY THERE?
RET ;YES
CALL RELCPT ;RELEASE CURRENT ONE
NOINT
MOVEM 2,PSBM0+CPTPG
RET
;RELEASE CURRENT PT MAPPING
RELCPT: SKIPN PSBM0+CPTPG ;ANYTHING THERE?
RET ;NO
SETZM PSBM0+CPTPG ;CLEAR MAP
PUSH P,1
MOVEI 1,CPTPGA
CALL MONCLR ;CLEAR MAP ENTRY
POP P,1
OKINT
RET
;RELEASE PAGE FROM MAP
; AC1/ OFN.PN OF PAGE
RELMPG: SAVET ;SAVE TEMPS
HLRZ T2,T1
CALL CHKDMO ;STR DISMOUNTED?
RET ;YES, DO NOTHING
CALL SETCPT
CALL LCKOFI ;LOCK IF OFN
CALL RELMP5
CALL PGRCLD
RET
;RELEASE ASSUMING PT ALREADY MAPPED AND THAT PAGER CLEAR WILL
;BE DONE FOLLOWING.
RELMP5:
RELMP6: HRRZ T4,T1
SKIPN CPTPGA(4) ;REF PAGE BEFORE GOING NOSKED
RET ;ALREADY EMPTY
NOSKED
MOVE 2,CPTPGA(4) ;GET MAP WORD
JUMPE 2,RELMPS ;EMPTY
LOAD 3,PTRCOD,2 ;GET PTR TYPE
CAIN 3,IMMCOD ;PRIVATE?
JRST RELP3 ;YES
CAIN T3,INDCOD ;INDIRECT?
JRST RELMI1 ;YES
HLRZ T3,T1 ;GET PTN
CAIGE T3,NOFN ;OWNED BY FILE?
JRST RELMP4 ;CAN'T DELETE FILE PAGE STILL SHARED
SETZM CPTPGA(T4) ;CLEAR MAP WORD
MOVE T3,T2 ;SAVE POINTER
LOAD T2,SPTX,T2
CAIGE 2,NOFN ;OFN?
JRST RELP1 ;YES
HLRZ 3,SPTH(2) ;IS SHARE POINTER, GET OFN
JUMPE 3,RELP1 ;IF UNOWNED SPTN
MOVEI 1,0(3) ;GET OFN
CALL DWNSHR ;DECREMENT OFN SHARE COUNT
MOVEI 1,0(2) ;GET PAGE ID
CALL DWNSHR ;DECREMENT PAGE SHARE COUNT
CALL GETSHR ;GET PAGE SHARE COUNT
JUMPN 1,[LOAD 1,STGADR,SPT(2) ;NO. GET STORAGE ADDRESS
TLNN 1,(NCORTM) ;PAGE NOW IN CORE?
CALL DECOR ;YES, DEASSIGN IT
JRST RELMPS] ;DONE
LOAD 1,STGADR,SPT(2) ;GET STORAGE ADDRESS
TLNE 1,(NCORTM) ;CORE?
JRST RELMP2 ;NO
CALL AGESET ;IN CORE, SET AGE
MOVSI 4,(PLKV)
ADDM 4,CST1(1) ;AND LOCK WHILE ADJUSTING
; ..
RELMP2: PUSH P,1 ;SAVE CORE NUMBER
MOVEI 1,0(3) ;GET XB INDEX
CALL DWNSHR ;DECREMENT SHARE COUNT
POP P,1 ;RESTORE CORE PAGE NUMBER
CALL SETXB1 ;MAP OWNING XB
MOVE 4,SPTH(2) ;GET OWNING PTN.PN
PUSH P,3 ;SAVE OWNING OFN
MOVE 3,2
MOVEI 2,SPT(2) ;CONSTRUCT PTR
EXCH 2,FRESPT ;RETURN SPT SLOT TO FREE LIST
MOVEM 2,@FRESPT
SOS SPTC
POP P,2 ;GET BACK OWNING OFN
CALL CHKDMO ;SEE IF THIS OFN IS DISMOUNTED
JRST CHKRLO ;IT IS. SEE IF OFN NEEDS TO BE RELEASED
ANDX 1,STGADM ;FLUSH ACCESS AND PTR BITS
IOR 1,IMMPTR ;CONSTRUCT STANDARD XB PTR
HRRZ 2,4
MOVEM 1,CXBPGA(2) ;PUT PRIV PTR BACK INTO XB
TLNE 1,(NCORTM) ;PAGE IN CORE?
JRST RELP4 ;NO
HRRZS 1
CAME 3,CST2(1) ;CONFIRM OLD OWNERSHIP
BUG(HLT,CST2I3,<PAGE TABLE CORE POINTER AND CST2 FAIL TO CORRESPOND>)
MOVEM 4,CST2(1) ;YES, CHANGE RECORD OF OWNING PT
HLRZ 3,4 ;PTN OF OWNING PT
HRRZ 3,SPT(3) ;CORE ADDRESS OF IT
MOVSI 2,(PLKV)
ADDM 2,CST1(3) ;INCREMENT LOCK COUNT
MOVSI 3,(-PLKV)
ADDM 3,CST1(1) ;UNLOCK PAGE
JRST RELP4
RELP1: MOVEI 1,0(2)
CALL DWNSHR ;DECREMENT SHARE COUNT
JRST RELMPS
RELMP4: MOVEI 1,PMAPX2 ;ILLEG UNMAPPING
MOVEM 1,LSTERR
MOVEI 1,.ICDAE
CALL PSIRQ0 ;GENERATE ITRAP
JRST RELMPS
;HERE TO RELEASE INDIRECT PTR
RELMI1: SETZM CPTPGA(T4) ;CLEAR MAP
MOVE T3,T2 ;SAVE PTR
LOAD T2,SPTX,T3 ;GET PTN FROM PTR
MOVE T1,T2
CALL DWNSHR ;REDUCE SHARE COUNT OF PT
CAIL 2,NOFN ;IS IT A PT
JRST RELMPS ;YES. ALL DONE THEN
CALL CHKDMO ;SEE IF A DISMOUNTED OFN
JRST CHKRLO ;IT IS. GO CHECK IT OUT
MOVX 1,OFNDUD ;SEE IF NO UPDATE REQUESTED
TDNE 1,SPTH(2) ;IS IT?
JRST [ MOVE 1,2 ;COPY OFN
CALL GETSHR ;GET ITS SHARE COUNT
JUMPE 1,.+1 ;IF ZERO, SCAN IT ANYWAY
JRST RELMPS] ;NON-ZERO. SKIP THE SCAN
LOAD 4,IPPGN,3 ;NO. GET PAGE NUMBER IN FILE
HRLI 4,0(2) ;FORM ID FOR PAGE
MOVE 3,2 ;MOVE OFN
CALL SETXB1 ;MAP THE OFN
JRST RELP4 ;AND MOVE THE PAGE TO DISK
CHKRLO: MOVEI 1,0(2) ;SEE IF NEED TO RELEASE OFN
CALL GETSHR ;SEE WHAT ITS SHARE COUNT IS
JUMPN 1,RELMPR ;CAN'T RELEASE IT YET. GO ON
MOVEI 1,0(2) ;GET OFN IN 1
CALL DASOFN ;FREE IT
JRST RELMPR ;AND GO WRAP UP
;PAGE BECOMING UNSHARED, MUST MAKE IT BE ON DISK
RELP4: HLRZ T1,T4 ;GET THE OFN
CALL UPSHR ;ARTIFICIALLY INCREMENT OFN
PUSH P,T1 ;SAVE OFN
CALL MOVDSK ;MOVE IT TO DISK NOW
MOVE T1,0(P) ;GET BACK OFN
CALL GETSHR ;GET THE OFN SHARE COUNT
SOJG T1,RLMPR2 ;ARE WE THE ONLY SHARER?
MOVE T1,0(P) ;YES. GET OFN AGAIN
CALL DASALC ;CLEAR ALLOC ENTRY IN THE OFN
PUSH P,PSBM0+CPTPG ;RESTORE PT MAPPING
SETZM PSBM0+CPTPG ; AND CLEAR IT SO RELCPT DOESN'T
; GET CONFUSED
MOVX T3,OFNDUD ;CHECK IF DUD IS SET
TDNN T3,SPTH(T1) ;IS IT?
JRST RLMPR1 ;NO. DON'T NEED TO SCAN THE OFN THEN
CALL LCKOFN ;LOCK THE OFN AGAINST MODIFICATION
CALL SCNOFN ;GET XB'S PAGES TO DISK
JFCL ;SHOULDN'T HAPPEN
MOVE T1,-1(P) ;GET BACK OFN
CALL ULKOFN ;UNLOCK THE OFN
RLMPR1: MOVX T4,OFNWRB ;SEE IF MODIFIED
TDNE T4,SPTH(T1) ;WAS IT?
CALL UPDOFN ;YES. PUT OFN ON THE DISK ALSO
POP P,PSBM0+CPTPG ;RESTORE PT MAPPING
RLMPR2: POP P,T1 ;GET OFN
CALL DWNSHR ;RESTORE ORIGINAL SHARE COUNT
RELMPR: CALL RELCXB ;RELEASE XB MAPPING
RELMPS: OKSKED
RET
;HERE IF PRIVATE PAGE -- PAGE WILL BE DELETED
RELP3: TLNE 2,(NCORTM) ;IN CORE?
JRST RELP32 ;NO, CAN RELEASE ALL.
MOVSI 3,(DWRBIT) ;YES, WRITE IN PROGRESS?
HRRZ 4,2
TDNN 3,CST3(4)
JRST RELP32 ;NO, NO PROBLEM
AOS DWRCFL ;FLAG FORK WAITING FOR WRITE COMPLETION
PUSH P,1
MOVEI 1,DWRTST ;YES, MUST WAIT FOR COMPLETION
HRLI 1,0(2)
RDISMS
POP P,1
JRST RELMP6 ;GO TRY AGAIN
RELP32: PUSH P,1 ;SAVE IDENT
HRRZS 1
MOVE 2,CPTPGA(1) ;GET POINTER
SETZM CPTPGA(1) ;CLEAR MAP SLOT
LOAD 1,STGADR,2 ;GET ADDR ONLY
TXNN 1,NCORTM ;IN CORE?
CALL AGESET ;YES, ENSURE ACCESS
TXNE 2,PTLOK ;LOCKED POINTER?
CALL [ LOAD 1,STGADR,2
CAMGE 1,MONCOR ;RESMON PAGE?
JRST [ SAVEAC <T2>
CALL RESPCK ;YES. SEE IF PART OF RESMON
RET ;NO. SKIP UNLOCK THEN
CALLRET MULKCR] ;YES.
CALLRET MULKCR] ;NO. UNLOCK IT
LOAD 1,STGADR,2 ;GET ADDR ONLY AGAIN
CALL REMFP1 ;DELETE CORE AND DRUM STORAGE
JUMPE 1,[POP P,1 ;DONE IF NOTHING LEFT
JRST RELMPS]
PUSH P,1 ;HAVE DSK ADR LEFT TO DELETE, SAVE IT
HLRZ 1,-1(P) ;GET OFN OF DEST
MOVX 2,OFNWRB ;NOTE CHANGE TO XB
IORM 2,SPTH(1)
OKSKED
NOINT ;STAY NOINT WHILE CPT RELEASED
CALL RELCPT ;RELEASE CPT CAUSE UPDOF0 USES IT
CALL UPDOF0 ;UPDATE IT TO DSK
POP P,1 ;RECOVER DSK ADDRESS
HLRZ 2,0(P) ;RECOVER OFN
LOAD C,ALOCX,(2) ;GET ALLOCATION PNTR
INCR PGLFT,(C) ;ADJUST PAGES LEFT UP
LOAD C,STRX,(2) ;GET STRUCTURE NUMBER
MOVE 2,SPTH(2) ;SEND DEDSK THE OFN BITS
NOSKED ;MUST CALL IT NOSKED
CALL DEDSKC ;DELETE IT
POP P,1 ;RECOVER IDENT
CALL SETCPT ;MAP PT AGAIN
OKINT ;UNDO NOINT ABOVE
JRST RELMPS ;DONE
;ROUTINE TO MOVE A PAGE TO ITS HOME ON THE DISK AND DELETE ANY
;LOCAL STORAGE. CALLED FROM RELOFN AND RELMPG.
;ACCEPTS: 4/ OFN.PN WITH THE OFN MAPPED INTO CXBPGA
;RETURNS: +1 ALWAYS, WITH PAGE EITHER ON THE DISK OR
; A WRITE IN PROGRESS
;CLOBBERS ALL TEMP REGISTERS
MOVDSK: HRRZ 2,4
MOVE 1,CXBPGA(2) ;GET CURRENT ADR OF PAGE
JUMPE 1,R ;MAY BE EMPTY
LOAD 2,PTRCOD,1
CAIN 2,SHRCOD ;BECAME SHARED AGAIN?
RET ;YES, NOTHING TO DO OR CAN BE DONE
TXNN 1,NCORTM ;IN CORE?
JRST MOVDS1 ;YES. GO CHECK IT
TXNE 1,DSKAB ;ON DISK?
RET ;YES. ALL DONE
TXNN 1,DRMAB ;ON DRUM?
JRST [ HRRZ 2,4
SETZM CXBPGA(2) ;NO, UNNASSIGNED. FLUSH IT
RET] ;AND DONE
MOVE 2,1 ;PAGE ON DRUM, GET DRUM ADR
CALL GDSTX ;GET DST INDEX
MOVE 3,DST(2) ;CHECK DRUM STATUS WORD
TLNE 3,(BWRBIT) ;HAS PAGE BEEN MODIFIED SINCE DISK?
JRST [ MOVE 1,4 ;YES, MUST WRITE IT BACK ON DISK
PUSH P,4
CALL SWPINW ;SO FIRST GET IT INTO CORE
POP P,4
JRST MOVDSK] ;NEXT SWPOUT WILL GO TO DISK
SETOM DST(2) ;PAGE NOT MODIFIED, NO WRITING NEEDED
HRRZ 2,4
STOR 3,STGADR,CXBPGA(2) ;RELEASE DST SLOT, PUT DSK ADR BACK IN XB
CALL DASDRM ;DEASSIGN DRUM ADDRESS
RET ;PAGE NOW ON DISK
;HERE IF PAGE IN CORE
MOVDS1: CALL SKPNWR ;WRITE IN PROGRESS?
JRST MOVDSK ;YES. RECHECK PAGE ID
CALL AGESET ;MAKE PAGE IN USE
MOVX 3,DSKSWB ;MAKE SURE IT GOES TO DISK
IORM 3,CST3(1) ;BY REQUESTING THIS EXPLICITLY
CALL SWPOT0 ;SWAP IT OUT
RET ;DONE
;ROUTINES TO ADJUST AND FETCH SPT SHARE COUNTS.
;ACCEPTS: 1/ SPT INDEX (EITHER PT OR OFN)
;RETURNS: +1 ALWAYS
;INCREASE SHARE COUNT
UPSHR:: ACVAR <Q1,Q2> ;GET A WORK REGISTER
HRRZ Q2,T1 ;GET THE SPT INDEX
CAIL Q2,NOFN ;AN OFN?
JRST SHRSPT ;NO
MOVX Q1,OFSHR ;YES. GET BIT FOR OFN
ADDB Q1,SPTO(Q2) ;INCREMENT SHARE COUNT
TLNN Q1,(-OFSHR) ;DID IT OVERFLOW?
BUG (HLT,SHROFN,<UPSHR-OFN SHARE COUNT OVERFLOW>) ;YES
RET ;NO. RETURN GOOD
SHRSPT: MOVX Q1,USHR ;GET SHARE BIT FOR SPT
ADDB Q1,SPT(Q2) ;INCREMENT IT
TLNN Q1,(-USHR) ;DID IT OVERFLOW?
BUG (HLT,SPTSHR,<UPSHR-SPT SHARE COUNT OVERFLOW>)
RET ;DONE
;DECREMENT SHARE COUNT
DWNSHR::ACVAR <Q1,Q2> ;GET A WORK REGISTER
HRRZ Q1,T1 ;GET SPT INDEX
CAIL Q1,NOFN ;AN OFN
JRST [ DECR SPTSHC,(Q1) ;NO. DECREMENT SPT SHARE COUNT
RET] ;AND DONE
MOVSI Q2,(-OFSHR) ;GET DECREMENTER
TDNN Q2,SPTO(Q1) ;FIRST CHECK FOR OVER DECREMENTING
BUG (HLT,SHROFD,<DWNSHR-OFN SHARE COUNT UNDERFLOW>)
ADDM Q2,SPTO(Q1) ;DO THE DECREMENT
RET ;AND DONE
;GET CURRENT VALUE OF SHARE COUNT
GETSHR::ACVAR <Q1> ;GET A WORK REGISTER
HRRZ Q1,T1 ;GET SPT INDEX
CAIL Q1,NOFN ;AN OFN?
JRST [ LOAD T1,SPTSHC,(Q1) ;NO. GET SPT SHARE COUNT
RET] ;AND DONE
LOAD T1,OFNSHC,(Q1) ;YES. GET OFN SHARE COUNT
RET ;AND DONE
;SKIP IF NO WRITE IN PROGRESS ON CORE PAGE. OTHERWISE RESCHEDULE
;UNTIL WRITE IS COMPLETED.
; 1/ CORE PAGE NUMBER
; CALL SKPNWR
; RETURN +1, PAGE WAS BEING WRITTEN, WRITE HAS COMPLETED.
; RETURN +2, PAGE WAS NOT BEING WRITTEN.
;UNLESS THE PAGE IS LOCKED, IT MAY CHANGE STATE ON A RESCHED. HENCE
;THE +1 RETURNS MEANS THAT THE POINTER TO THE PAGE MUST BE RECHECKED.
;CLOBBERS NO AC'S
SKPNWR::HRRZS A
SKIPL CST3(A) ;WRITE IN PROGRESS?
RETSKP ;NO, SKIP
AOS DWRCFL ;FLAG FORK WAITING FOR WRITE COMPLETION
HRLZ A,A ;YES, SETUP SCHED TEST
HRRI A,DWRTST
RDISMS ;OKSKED AND DISMISS
HLRZ A,A ;RESTORE PAGE NUMBER TO A
NOSKED ;RESTORE NOSKED STATE
RET ;RETURN NOSKIP
DWRTST::MOVSI 2,(DWRBIT) ;SCHED TEST FOR WRITE COMPLETED
TDNE 2,CST3(1)
JRST 0(4)
JRST 1(4)
;ROUTINE CALLED PERIODICALLY TO FINISH DELETING PAGES LEFT BY
;REMFP1 BECAUSE OF A WRITE IN PROGRESS.
; CALL REMFPB
; RETURN +1 ALWAYS, ALL PAGES DELETED FROM QUEUE
REMFPB::SKIPN DELPGQ ;ANY PAGES ON DELETED QUEUE?
RET ;NO, DONE
PIOFF ;YES, PREVENT INTERRUPTS WHILE REMOVING
HRRZ 1,DELPGQ
HRRZ 1,0(1)
EXCH 1,DELPGQ ;REMOVE PAGE FROM QUEUE
PION
SUBI 1,CST3 ;TRANSLATE TO CORE PAGE NUMBER
CALL REMFB1 ;FINISH UP DELETE
SKIPE 1 ;COMPLETELY DELETED?
BUG(HLT,PGNDEL,<REMFPB-PAGE NOT COMPLETELY DELETED>)
JRST REMFPB ;DO ALL PAGES
;REMOVE PAGE FROM SYSTEM (DELETE PERMANENT AND TEMPORARY ADDRESSES)
; 1/ STORAGE ADDRESS
REMFP1: SAVEQ
REMFPA: HRRZ Q1,1
TLNE 1,(DSKAB) ;DISK?
RET ;YES, LEAVE IT IN 1
TLNE 1,(DRMAB) ;DRUM?
JRST REMFD ;YES
TLNE 1,(NCORTM) ;CORE?
JRST REMFPR ;UNASSIGNED, DONE
CAMG 1,NHIPG ;LEGAL PAGE?
CAMGE 1,MONCOR
JRST [ CALL RESPCK ;SEE IF PART OF RESMON
JRST .+1 ;NO. ASSUME WE WANT TO GET RID OF IT
JRST REMFPX] ;YES. LEAVE IT ALONE
LOAD 2,CSTAGE,(Q1) ;GET PAGE STATE CODE
CAIL 2,PSASN ;ASSIGNED TO PROCESS?
CALL DECOR ;YES, DEASSIGN
HLRZ 2,CST2(Q1) ;GET PTN OF OWNING PT
JUMPE 2,REMFP2 ;NONE, SPT
HRRZ 3,SPT(2) ;GET ADR OF OWNING PT
MOVSI 4,(-PLKV)
ADDM 4,CST1(3) ;DECREMENT LOCK COUNT
REMFP2: PIOFF
SETZM CST2(Q1) ;FLUSH OWNER IDENT
MOVE 3,CST3(Q1) ;GET WRITE BIT
PION
TXNE 3,DWRBIT ;PAGE BEING WRITTEN?
JRST REMFPR ;YES, DELETE WILL BE COMPL'D AFTER WRITE
SKIPA ;SKIP OVER SAVQ FOR ALTERNATE ENTRY
REMFB1: SAVEQ ;SAVE REGISTERS
HRRZ Q1,1
MOVSI 4,(-PLKV)
LOAD 3,CSTAGE,(Q1) ;GET STATE CODE
CAIE 3,PSRPQ ;ON RPLQ?
TDNE 4,CST1(Q1) ;OR LOCKED IN CORE?
JRST REMF22 ;YES, LEAVE AS IS
CALL OFRQ ;PUT ON TOP OF RPLQ SINCE NOT TO BE REUSED
REMF22: MOVSI 3,(-PLKV)
AND 3,CST1(Q1) ;FLUSH BACKUP ADDRESS, LEAVE LK CNT
EXCH 3,CST1(Q1) ;GET BACKUP ADDRESS
MOVE 1,3
JRST REMFPA
REMFD: PUSH P,1
CALL DASDRM ;DEASSIGN DRUM ADDRESS
POP P,2
CALL GDSTX
MOVE 1,DST(2) ;GET BACKUP ADDRESS
SETOM DST(2) ;MAKE DST SLOT EMPTY
JRST REMFPA
REMFPX: ;NON-SWAPPING PAGE, E.G. FROM MAPPHP
REMFPR: SETZ 1, ;RETURN 0 TO SAY ALL DELETED
RET
;HANDLE BAD CORE PAGE--CALLED AS RESULT OF PARITY ERROR OR OTHER
;PROBLEM WITH PHYSICAL PAGE.
; T1/ CORE PAGE NUMBER
; CALL BADCPG
; RETURN +1, CONTENTS NOT RECOVERABLE
; RETURN +2, CONTENTS RECOVERABLE.
;THE CONTENTS ARE RECOVERABLE IF THE PAGE IS UNMODIFIED, I.E. THE
;DATA CAN BE READ FROM DISK OR DRUM AGAIN. IN THIS CASE, THE
;POINTERS ARE RESET AND THE NEXT PROCESS REFERENCE SHOULD CAUSE
;THE PAGE TO BE READ INTO A DIFFERENT PHYSICAL CORE PAGE.
;IF THE PAGE HAS BEEN MODIFIED OR IF IT IS LOCKED, IT IS LEFT
;MAPPED AND ANY PROCESSES WHICH REFERENCE THE BAD DATA SHOULD GET
;INTERRUPTS. IN EITHER CASE, THE PAGE IS LOCKED SO THAT IT WILL
;NOT BE USED AGAIN.
BADCPG::CAMGE T1,MONCOR ;RESIDENT PAGE?
BUG(HLT,RPGERR,<BADCPG-FATAL ERROR IN RESIDENT PAGE>)
NOSKED
MOVX T2,-PLKV
MOVX T3,CORMB
TDNN T2,CST1(T1) ;PAGE LOCKED?
TDNE T3,CST0(T1) ;OR MODIFIED?
JRST BADCP3 ;YES
MOVEI T2,PSTERR ;NO, SET PAGE TO ERROR STATUS
STOR T2,CSTPST,(T1) ; ...
CALL RPCST ;RESET POINTERS
PIOFF ;INTERLOCK CALL
CALL ONSPMQ ;PLACE ON SPMQ, RETURNS PION
AOS NBADCP ;COUNT LOSSAGE
OKSKED
RETSKP
;HERE IF CANNOT RELEASE PAGE BECAUSE MODIFIED OR LOCKED
BADCP3: MOVE T2,CST2(T1) ;GET OWNER IDENT, FIND OFN IF ANY...
HLRZ T3,T2
JUMPN T3,[CAIL T3,NOFN ;HAVE PTN, IS OFN?
JRST BADCP2 ;NO, FORK PAGE
MOVE T2,T3 ;YES
JRST BADCP1] ;GO MARK OFN
CAIL T2,NOFN ;IS PAGE AN XB?
JRST [ HLRZ T2,SPTH(T2) ;NO, GET OWNING PT
JUMPN T2,BADCP1 ;GO MARK IT
BUG(HLT,FRKPTE,<BADCPG-FATAL ERROR IN FORK PT PAGE>)]
BADCP1: MOVX T3,OFNERR ;MARK ERROR IN OFN, REPORTED ON CLOSF
IORM T3,SPTH(T2)
BADCP2: MOVEI T2,PSTERR ;INDICATE ERROR IN PAGE
STOR T2,CSTPST,(T1) ; ...
AOS NBADCP
OKSKED
RET ;RETURN NOT RECOVERABLE
;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
;MAY RETURN WITH AC1 =0 IF SECTION DOES NOT EXIST
FPTA:: SAVEQ
MOVE FX,FORKX
MOVEM T1,Q1 ;CONSTRUCT RESULT IN Q1
LOAD T1,VPGNO,T1 ;GET PAGE NUMBER
LDB Q2,[POINT 5,T1,26] ;GET THE SECTION NUMBER FROM THE PAGE NUMBER
ANDI T1,777 ;GET THE PAGE NUMBER IN THE SECTION
HRRM T1,Q1 ;SAVE IT
JUMPL Q1,[SKIPN T1,USECTB(Q2) ;YES. GET SECTION POINTER
JRST RFALSE ;NON-EX SECTION
ANDX T1,STGADM ;GET SPT INDEX ONLY
JRST FPTAR]
SKIPN MSECTB(Q2) ;IS THE SECTION POINTER PRESENT?
JRST RFALSE ;NO. QUITE IRREGULAR! RETURN A ZERO
CAIG Q2,MAXSEC ;IF GREATER THAN MAX SECTION SOMBODY HAS BAD SECTION
JRST @FPTABL(Q2) ;GO TO PROPER PAGE ROUTINE
ILLFPT: BUG(HLT,ILFPTE,<ILLFPT: ILLEGAL SECTION NUMBER REFERENCED>)
FPTA0: CAIL T1,PSSPS ;WHICH PART OF MONITOR?
JRST FPTA1 ;PRIVATE PER PROCESS
CAIL T1,JSBPG
JRST FPTA2 ;PRIVATE PER JOB
CAML T1,BTSTRT ;WITHIN BIT TABLE
CAMLE T1,BTEND ;STILL?
FPTA4: SKIPA T1,MMSPTN ;NO. IN MONITOR MAP
JRST FPTA3
FPTAR: HRLM T1,Q1 ;CONSTRUCT PAGE IDENT
MOVE T1,Q1 ;RETURN RESULT
RET
FPTA1: ADDI Q1,-PSSPS+PSBMAP-PSBPGA ;OFFSET INTO PSBMAP
LOAD T1,FKPSB ;GET PSB IDENT
JRST FPTAR
FPTA2: ADDI Q1,-JSBPG+JOBMAP-JSBPGA ;FIRST JOB PAGE MAPPED BY JOBMAP+0
LOAD T1,FKJSB ;GET JSB IDENT
JRST FPTAR
FPTA3: MOVE T1,BTBBAS ;GET SPTN FOR BIT TABLE
MOVX Q2,UAAB ;GET NO ACCESS BIT
TDNE Q2,SPT(T1) ;ACCESSIBLE?
JRST FPTA4 ;NO. RETURN MMAP DATA
SUB Q1,BTSTRT ;GET PAGE NUMBER
MOVE T1,SPTH(T1) ;YES. GET TRUE ID
JRST FPTAR ;AND DONE
FPTA6: HRRZ T1,DRMAP ;MAP DIRECTORY
FPTAS: JUMPE T1,R ;IF NO SECTION POINTER, RETURN 0
JRST FPTAR ;GO FORM CORRECT POINTER
FPTA7: HRRZ T1,IDXMAP ;FIND IDXMAP
JRST FPTAS ;GO FINISH UP
FPTA8: HRRZ T1,MSECTB+BTSEC ;FIND BITMAP
JRST FPTAS ;GO FINISH UP
FPTAAN: HRRZ T1,MSECTB+ANBSEC ;FIND ARPANET BUFFER MAP
JRST FPTAS ;GO FINISH UP
;SETUP IO PAGE -- LOCKED AND MAPPED VIA MON MAP
; 1/ IDENT OF SOURCE
; 2/ ACCESS,,MON ADR
; CALL SETIOP
; RETURN +2, PAGE LOCKED AND MAPPED
SETIOP::ASUBR <SOURCE,BFRP>
LOAD 2,VPGNO,2 ;GET PAGE NUMBER
HRRM 2,BFRP
SKIPE 1,MMAP(2) ;PREVIOUS CONTENTS?
JRST [ SETZM MMAP(2) ;YES, REMOVE
TXNE T1,NCORTM ;CORE?
JRST .+1 ;NO, FORGET IT
HRRZ 1,1 ;GET CORE PAGE NUMBER
MOVX T3,-PLKV
TDNN T3,CST1(T1) ;LOCKED?
JRST .+1 ;NO, FORGET IT
CALL MULKCR ;UNLOCK IT
JRST .+1]
SKIPN 1,SOURCE ;GET SOURCE ID
JRST SETIO1 ;NONE, JUST RESETTING PREVIOUS PAGE
CALL MLKPG ;LOCK PAGE AND GET CORE PAGE NUMBER
IOR 1,IMMPTR ;CONSTRUCT POINTER
MOVE 2,BFRP ;GET ACCESS REQUEST
TXNN 2,PA%WT ;WRITE WANTED?
TXZ 1,PTWR ;NO, CLEAR IT
MOVEM 1,MMAP(2) ;PUT PAGE IN MON MAP
HRRZS T1 ;MAKE ADDRESS FOR CST0(T1)
MOVX T3,CORMB
TXNE T2,PA%WT ;PAGE WRITABLE?
IORM T3,CST0(T1) ;YES, ASSUME IT WILL BE WRITTEN
CALL KICLKP ;PUT PAGE IN KI MAP
SETIO1: RETSKP
;MARK MODIFIED PAGE - USED WHEN PAGE IS BEING MODIFIED BY OTHER
;THAN PROCESSOR REFERENCE, E.G. BY IO VIA CHANNEL.
; T1/ CORE PAGE NUMBER
; CALL MRKMPG
; RETURN +1 ALWAYS, MODIFIED BIT SET FOR SPECIFIED PAGE
MRKMPG::CAML T1,MONCOR ;VALIDATE PAGE
CAMLE T1,NHIPG
BUG(HLT,ILPAGN,<MRKMPG-INVALID PAGE NUMBER>)
SETONE CORMB,CST0(T1) ;MARK IT
RET
;LOCK, UNLOCK PAGE ON REQUEST (FOR DTA IO, ETC.)
; 1/ ADDRESS (+1B0 IF USER)
;RETURN +1: 1/ CORE PAGE NUMBER
MLKMA:: TLNN 1,(1B0) ;LOCK PAGE GIVEN ADDRESS. USER?
SKIPA 0(1) ;NO, MON. REF PAGE TO ENSURE EXISTS
XCTU [SKIP 0(1)]
CALL FPTA ;TRANSLATE ADDRESS TO OFN.PN
; JUMPE T1,SETMPX ;CAN'T HAPPEN SINCE REFERENCE TO PAGE
;SUCCEEDED
;LOCK PAGE GIVEN OFN.PN
; 1/ OFN,,PN
MLKPG:: SKIPE INSKED ;IN SCHED CONTEXT?
JRST MLKPGM ;YES, SPECIAL HANDLING
PUSH P,1
CALL GETONT ;GET PTN.PN OR OWNING PT
JUMPE T2,MLKPG2 ;JUMPE IF PAGE DOES NOT EXIST
TLNN 2,(NCORTM) ;PAGE NOW IN CORE?
JRST MLKPG1 ;YES.
MLKPG4: CALL SWPINW ;INITIATE SWAP AND WAIT FOR COMPL.
POP P,1
OKSKED
JRST MLKPG ;TRY AGAIN
MLKPG2: TLNN T1,-1 ;IN SPT?
JRST [ MOVX T2,UAAB ;YES, SETUP ADDRESS
STOR T2,STGADR,SPT(T1)
JRST MLKPG4]
CALL SETCPT ;IN A PAGE TABLE - MAP IT
HRRZ T2,T1
MOVE T3,IMMPTR ;CONSTRUCT PTR WITH UNASSIGNED ADR
TXO T3,UAAB
MOVEM T3,CPTPGA(T2) ;PUT IT IN PT
CALL RELCPT
JRST MLKPG4
;MLKPG IN SCHED CONTEXT - NONX PAGE IN MONMAP ONLY
MLKPGM: HLRZ T2,T1 ;GET PT IDENT
HRRZ T3,T1 ;GET PAGE NUMBER
CAMN T2,MMSPTN ;IN MONMAP?
SKIPE MMAP(T3) ;PAGE IS NON-EXISTENT?
BUG(HLT,ILPLK1,<MLKPG-ILLEGAL ARGS>)
MOVE T2,IMMPTR ;CONSTRUCT PTR WITH UNASSIGNED ADR
TXO T2,UAAB
MOVEM T2,MMAP(T3) ;PUT IN MON MAP
CALL SWPIN ;ASSIGN CORE AND CLEAR IT
HLRZ T1,T1 ;GET CORE PAGE NUMBER ASSIGNED
MOVEI T3,PSASN
STOR T3,CSTAGE,(T1) ;SET STATE TO IN-USE
MOVEI T3,OFNUL
STOR T3,CSTOFK,(T1) ;SET OWNERSHIP TO UNASSIGNED
SETZRO PUFLD,CST0(T1) ;CLEAR USE BITS
JRST MLKCP ;LOCK AND ADJUST VARIABLES
;LOCK PAGE GIVEN CORE PAGE NUMBER
; T1/ PAGE NUMBER
; CALL MLKCP
; RETURN +1 ALWAYS, T1 PRESERVED
;LOCK PAGE COMMON CODE
MLKCP:: NOSKD1
SKIPA T2,T1
MLKPG1: POP P,1
HRRZ T2,T2
CAMGE T2,MONCOR ;WITHIN RANGE?
JRST MLKPG5
MOVE 1,CST1(2)
TLNE 1,(-PLKV) ;PAGE LOCKED NOW?
JRST MLKPG3
AOS LOKPGS ;NO, COUNT IT
AOS BALSHC
AOS GNPBAS
AOS SUMNR
TLO 2,(1B0) ;SET LOCAL FLAG FOR TEST BELOW
MLKPG3: MOVSI 1,(PLKV)
ADDM 1,CST1(2) ;INCREMENT LOCK COUNT
AOS LOKSUM
SKIPE INSKED ;IN SCHED CONTEXT?
RET ;YES, DONE
HRRZ T1,T2
CALL AGESET ;SET AGE
PUSH P,2
LOAD 2,CSTOFK,(1) ;GET OWNING FORK
CAIGE 2,NFKS ;ASSIGNED?
CALL SOSWSP ;YES, DEASSIGN IT
POP P,2
MOVX 1,OFNUL ;STORE NULL VALUE FOR OWNER FORK
STOR 1,CSTOFK,(2)
CALL MONCLA
MLKPG5: OKSKD1
HRRZ 1,2 ;RETURN PHYS PAGE NUMBER
RET
;UNLOCK PAGE
; 1/ PAGE IDENT (OFN,,PN)
; CALL MULKPG
; RETURN +1 ALWAYS, BUGHLT IF PAGE NOT PREVIOUSLY LOCKED
MULKPG::PUSH P,2
CALL GETONT ;GET OWNING PT
TLNE 2,(NCORTM) ;PAGE NOW IN CORE?
BUG(HLT,ILULK1,<MULKPG - TRIED TO UNLOCK PAGE NOT LOCKED>)
CALL MULK1
POP P,2
OKSKED
RET
MULK1: MOVSI 1,(-PLKV)
HRRZS 2
CAMGE T2,MONCOR ;WITHIN RANGE?
RET ;NO, IGNORE
TDNN 1,CST1(2) ;LOCK COUNT NON-ZERO?
BUG(HLT,ILULK2,<TRIED TO UNLOCK PAGE NOT LOCKED>)
ADDB 1,CST1(2) ;DECREMENT LOCK COUNT
TLNE 1,(-PLKV) ;NOW UNLOCKED?
JRST MULK2 ;NO
SOS LOKPGS
CALL UPSWP ;ONE MORE SWAPPING PAGE
SKIPE CST2(2) ;STILL EXISTS?
JRST MULK2 ;YES
MOVEI 1,0(2) ;HAS BEEN DELETED, PUT ON RPLQ
CALL OFRQ ;PUT ON TOP OF RPLQ FOR IMMEDIATE REUSE
MULK2: SOS LOKSUM
RET
;UNLOCK PAGE GIVEN MONITOR ADDRESS
;ASSUMED NOSKED OR INSKED
MULKMP::LOAD 1,VPGNO,1 ;GET PAGE NUMBER
CAIL T1,JSBPG ;MONITOR MAP ONLY
BUG(HLT,ILULK3,<MULKMP - ILLEGAL MONITOR ADDRESS>)
LOAD 1,STGADR,MMAP(1) ;GET CORE ADDRESS
JRST MULKCR
;UNLOCK PAGE GIVEN CORE PAGE NUMBER IN 1
;MAY BE CALLED AT INTERRUPT LEVEL
MULKCR::CAML 1,MONCOR ;LEGAL?
CAMLE 1,NHIPG
BUG(HLT,ILULK4,<MULKCR - ILLEGAL CORE PAGE NUMBER>)
PUSH P,2
MOVEI 2,0(1)
CALL MULK1
POP P,2
RET
;MULKSP - UNLOCK A PAGE IN NON-ZERO SECTION. THIS ROUTINE MAY BE
;CALLED AT ANY INTERRUPT LEVEL.
;ACCEPTS: T1/ VIRTUAL ADDRESS
;RETURNS: +1 ALWAYS
MULKSP::PUSH P,T2 ;SAVE T2
CALL GETCPA ;GET REAL PAGE ADDRESS
POP P,T2 ;RESTORE T2
HRRZS T1 ;RETAIN JUST PAGE NUMBER
CALLRET MULKCR ;GO UNLOCK THE PAGE
;ROUTINE TO ADJUST SWAPPING WHEN PAGES ARE LOCKED OR
;UNLOCKED
;FIRST. ROUTINE TO ADJUST PARAMETERS ON UNLOCK
UPSWP: SOS BALSHC ;ONE LESS OVERHEAD PAGE
SOS GNPBAS ;ONE LESS HERE TOO
SOS SUMNR ;AND REMOVE LIEN FROM BALSET
RET ;DONE
;ROUTINE TO ADJUST SWAPPING/SCHEDULING PARAMETERS
;CALLED BY SCHEDULER WHENEVER NEW PAGES APPEAR IN SYSTEM
;RECOMPUTES ALL VALUES BASED ON TOTRC (E.G. MAXNR, DRMLV0, ...)
;CALLED FROM SCHEULER PERIODICALLY
ADJSWP::PIOFF ;PROTECT ALL STRUCTURES
CALL MEMMGT ;RECOMPUTE BASIC SWAPPING PARAMETERS
CALL AJBPAR ;RECOMPUTE BALSET PARTITIONS
SETZM PAGDIF ;NO NEW PAGES
PION ;OKAY NOW
CALLRET SETSSP ;AND RECOMPUTE "DRUM" USAGE
;GET CORE PAGE GIVEN ADDRESS OR IDENTIFIER
;CLOBBERS T2
GETCPA::CALL FPTA ;CONVERT ADDRESS TO IDENTIFIER
JUMPE T1,GETCPX ;IF NOT EXISTANT, NOT IN CORE
GETCPP::SAVEQ
HLRZ 2,1 ;PT IDENT
MOVE 2,SPT(2) ;ADR OF IT
TLNE 2,(NCORTM) ;IN CORE?
GETCPX: BUG(HLT,PAGNIC,<GETCPP-PAGE NOT IN CORE>)
HRRZS 1
HRRZS T2 ;SAVE ONLY PAGE NUMBER
CALL MOVRCA ;MOVE 1,PT(1)
LOAD Q1,PTRCOD,1 ;GET PTR TYPE
CAIN Q1,IMMCOD ;PRIVATE?
RET ;YES
CAIE Q1,INDCOD ;INDIRECT?
JRST [ LOAD 2,SPTX,1 ;SHARED, GET SPT IDX
MOVE 1,SPT(2)
RET]
LOAD Q1,SPTX,2 ;GET PT NUMBER
LOAD 1,IPPGN,2 ;GET PAGE NUMBER
HRL 1,Q1 ;CONSTRUCT IDENT
JRST GETCPP
;GET OWNING PAGE TABLE
;GIVEN PTN.PN, LOCATE PT CURRENTLY HAVING ADDRESS OF PAGE
GETONT: SAVEQ
CALL SETCPT ;MAP GIVEN PAGE TABLE
NOSKED
HRRZ 2,1
MOVE 2,CPTPGA(2) ;GET PTR
JUMPE T2,GETONX ;RETURN IF NONX PAGE
LOAD Q1,PTRCOD,2 ;GET PTR TYPE
CAIN Q1,IMMCOD ;PRIVATE?
JRST GETONX
CAIE Q1,INDCOD ;INDIRECT?
JRST GETON1 ;NO, SHARE POINTER.
OKSKED
LOAD 1,IPPGN,2 ;GET PAGE NUMBER
LOAD 2,SPTX,2 ;GET PT NUMBER
HRL 1,2 ;CONSTRUCT IDENT
CALL RELCPT ;RELEASE CPT
JRST GETONT ;TRY AGAIN
GETON1: LOAD 1,SPTX,2 ;FOR SHARE POINTER, RETURN SPTN
MOVE 2,SPT(1) ;AND CURRENT ADDRESS
GETONX: CALLRET RELCPT ;RELEASE CPT AND RETURN
;LODPPG - LOAD VIRTUAL PAGE INTO PHYSICAL LOCATION
;CALL WITH:
;T1/ PTN.PN
;T2/ BITS,,PHY. PAGE
;T3/ PREVIOUS STATE IF ENTERED AT LODPPS
;BITS ARE:
;LK%NCH DON'T CACHE PAGE
;LK%PHY IF OFF, FREE CHOICE OF PAGE
;LK%AOL ALLOW LOCKING IN OFF-LINE MEMORY
; CALL LODPPG
; ERROR RETURN, CAN'T LOAD PAGE, CODE IN 1
; SUCCESS PAGE IS LOADED AND LOCKED
;SHOULD ALWAYS BE CALLED NOINT
;VIRTUAL PAGE MUST BE PRIVATE OR NON-EXISTANT
;POINTER WILL HAVE PTLOK SET WHICH WILL CAUSE IT TO BE UNLOCKED
;BY RELMPG.
LODPPG::TXO T3,1B0 ;NO SPECIAL "PREVIOUS STATE"
LODPPS::ASUBR <LODSRC,LODDST,LODPST>
TXNN T2,LK%PHY ;FREE CHOICE?
JRST LODFRE ;YES. GO CHOOSE
LODPP3: HRRZ T1,LODDST ;GET PHY PAGE
LOAD T2,CSTPST,(T1) ;GET CURRENT PAGE STATE
SKIPGE LODPST ;ALREADY HAVE A "PREVIOUS STATE"?
MOVEM T2,LODPST ;NO. SAVE HERE
LOAD T2,CSTAGE,(T1) ;GET AGE
CAIN T2,PSSPQ ;ALREADY ON SPMQ?
JRST [ MOVX T3,LK%AOL ;YES. SEE IF OFF-LINE LOCKING ALLOWED
TDNE T3,LODDST ;IS IT?
JRST LODPP1 ;YES. PAGE WILL RETURN TO SPMQ
RETBAD (LOCKX1)] ;NO. CAN'T DO IT THEN
MOVEI T2,PSTOFL ;PLACE PAGE OFF LINE
CALL SETPST ;PUT INTO SPMQ
RETBAD(LOCKX2) ;ERROR, CODE IN 1
LODPP1: NOSKED ;OWN MACHINE FOR A WHILE
HLRZ T3,LODSRC ;GET SOURCE PAGE
CALL SETXB1 ;MAP IT
HRRZ T1,LODSRC ;GET PAGE NUMBER
SKIPN T1,CXBPGA(T1) ;GET POINTER
JRST LODPP0 ;NON-EX. OKAY
LOAD T2,PTRCOD,T1 ;GET TYPE
CAIE T2,IMMCOD ;PRIVATE?
LODBAD: RETBAD (LOCKX1,<CALL RELCXB
OKSKED>)
ANDX T1,STGADM ;GET ADDRESS ONLY
MOVX T2,-PLKV ;LOCK FIELD
TXNN T1,NCORTM ;IN MEMORY?
TDNN T2,CST1(T1) ;YES. LOCKED?
SKIPA ;NO. OKAY TO REPLACE IT
JRST LODBAD ;LOCKED. CAN'T DO IT. SORRY!
; ..
LODPP0: CALL RELCXB ;FREE INDEX BLOCK
HRRZ T1,LODDST ;GET PHY PAGE NUMBER
CALL OFFSPQ ;REMOVE FROM SPMQ
MOVEI T2,PSASN ;GET A GOOD AGE
STOR T2,CSTAGE,(T1) ;MAKE BLT WORK
MOVE T1,LODSRC ;GET SOURCE ADDRESS
MOVE T2,[PTRW+FPG2A] ;MAP PAGE
CALL SETMPG ;DO IT
SKIP FPG2A ;GET DATA
PIOFF ;OWN MACHINE
HRRZ T1,LODDST ;GET DEST PAGE
CALL MAPRCA ;MAKE IT ADDRESSABLE
MOVE T2,T1 ;SAVE ADDRESS
HRLI T1,FPG2A ;SOURCE DATA
BLT T1,PGSIZ-1(T2) ;MOVE DATA
CALL UNMRCA ;CLEAR MAPPING
PION ;BREATH A LITTLE NOW
MOVEI T2,FPG2A ;WHERE WE PUT DATA
SETZM T1 ;UNMAP
CALL SETMPG ;FREE IT
MOVE T1,LODSRC ;WHERE NEW DATA IS TO GO
HRRZ T2,LODDST ;PHYSICAL PAGE NUMBER
CALL MAPPHP ;MAKE THEM ONE AND THE SAME
JFCL ;CAN'T FAIL
HRRZ T1,LODDST ;GET PHY PAGE
MOVE T2,LODPST ;GET OLD STATE BACK
STOR T2,CSTPST,(T1) ;WILL RETURN TO STATE WHEN RELEASED
CALL MLKCP ;LOCK PAGE, SET AGE (REMOVE FROM FORK WS)
OKSKED ;WE CAN REST NOW
HLRZ T3,LODSRC ;GET PTN
CALL SETXB1 ;MAP IT
HRRZ T1,LODSRC ;GET PN
MOVX T2,PTLOK ;FLAG AS LOCKED POINTER
IORM T2,CXBPGA(T1) ;IN PAGE TABLE
JE LK%NCH,LODDST,LODPP2 ;JUMP IF NO-CACHE NOT REQUESTED
MOVX T2,PTCACH ;GET CACHE BIT
ANDCAM T2,CXBPGA(T1) ;CLEAR IT
HRRZ T1,LODDST ;GET PAGE #
CALL CASHFP ;FLUSH FROM CACHE
LODPP2: CALL RELCXB ;RELEASE PAGE TABLE
RETSKP ;RETURN SUCCESS
;ULDPAG - UNLOAD PAGE IF LOCKED
;CALL WITH:
;T1/ PTN.PN
; CALL ULDPAG
; ERROR, PAGE NOT LOCKED OR CAN'T BE SWAPPED, CODE IN 1
; SUCCESS, PAGE SWAPPED OUT OF MEM.
;PAGE ALWAYS UNLOCKED IF WAS LOCKED AND CACHE BIT TURNED ON AGAIN
ULDPAG::STKVAR <ULDSRC,ULDDST>
MOVEM T1,ULDSRC ;SAVE PTN.PN
HLRZ T3,ULDSRC ;GET PTN
CALL SETXB1 ;MAP IT (RETURNS NOINT)
HRRZ T2,ULDSRC ;USER PAGE
MOVX T1,PTLOK ;LOCKED POINTER BIT
NOSKED ;PROTECT THE PAGE POINTER
LOAD T3,PTRCOD,CXBPGA(T2) ;GET POINTER TYPE
CAIN T3,IMMCOD ;IMMEDIATE?
TDNN T1,CXBPGA(T2) ;IS IT STILL LOCKED?
JRST ULDPG1 ;NO, JUST RETURN
ANDCAM T1,CXBPGA(T2) ;CLEAR LOCKED POINTER BIT
MOVX T1,PTCACH ;TURN CACHE BIT BACK ON (IF OFF)
IORB T1,CXBPGA(T2) ;AND PICKUP POINTER
ANDX T1,STGADM ;GET PHY ADDR ONLY
MOVEM T1,ULDDST ;SAVE PAGE NUMBER
CAML T1,MONCOR ;RES MON PAGE?
CALL MULKCR ;NO, UNLOCK PAGE
MOVE T1,ULDDST ;GET PAGE NUMBER AGAIN
ULDPG3: MOVX T2,-PLKV ;SEE IF STILL LOCKED
TDNN T2,CST1(T1) ;IS IT?
CALL SWPOT0 ;NO. SWAP IT OUT THEN
ULDPG2: MOVE T1,ULDDST ;GET PAGE NUMBER AGAIN
CALL SKPNWR ;WAIT FOR IT TO FINISH
JRST ULDPG2 ;TRY AGAIN
HRRZ T2,ULDSRC ;PAGE NUMBER AGAIN
LOAD T1,STGADR,CXBPGA(T2) ;GET STORAGE ADDRESS NOW
TXNE T1,NCORTM ;IM MEMORY?
JRST ULDPG1 ;NO. ALL DONE
LOAD T2,CSTAGE,(T1) ;YES. GET ITS AGE THEN
CAIN T2,PSRPQ ;ON RPLQ YET?
JRST ULDPG1 ;YES. DONE THEN
MOVEM T1,ULDDST ;NO. SAVE MEM PAGE NUMBER
JRST ULDPG3 ;AND DO IT AGAIN
REPEAT 0,< ;FOR NOW, WAIT FOR SWAP OUT
MOVE T1,ULDSRC ;GET PTN.PN
CALL SWPPAG ;SWAP PAGE OUT (CXBPG ALREADY HAS PTN)
RETBAD() ;RETURN ERROR (ALREADY RELEASED PTN)
OKSKED ;RETURNED NOSKED
> ;END OF REPEAT 0
ULDPG1: OKSKED ;ALLOW SCHEDULING AGAIN
CALL RELCXB ;RELEASE UPT (DOES OKINT)
RETSKP
;HERE FROM LODPPG ON FREE CHOICE OF PAGE
LODFRE: NOSKED ;PROTECT RPLQ
CALL CHKRPQ ;WAIT FOR PAGES TO SHOW UP
JRST .-1 ;WAIT SOME MORE
HRRZ T1,RPLQ ;GET TOP PAGE
SUBI T1,CST3 ;COMPUTE PAGE NUMBER
HRRM T1,LODDST ;MAKE IT THE TARGET PAGE
OKSKED ;NO NEED FOR THIS NOW
JRST LODPP3 ;AND PROCEED
;SWPPAG - SWAP USER PAGE OUT AND WAIT UNTIL COMPLETE
;CALL WITH:
;T1/ PTN.PN
; CALL SWPPAG
; ERROR, PAGE CAN'T BE SWAPPED, CODE IN 1
; SUCCESS, PAGE IS NOW SWAPPED (RETURNS NOSKED)
;MUST BE CALLED NOINT
;PAGE MUST BE PRIVATE OR NOT EXIST.
;PAGE MUST NOT BE LOCKED
REPEAT 0,< ;NOT PRESENTLY NEEDED
SWPPAG::STKVAR <SWPSRC,SWPTRY>
MOVEM T1,SWPSRC
MOVEI T2,10 ;TRY THIS MANY TIMES
MOVEM T2,SWPTRY
SWPPG1: HLRZ T3,SWPSRC ;GET PTN
CALL SETXB1 ;MAP PAGE TABLE (GOES NOINT)
SKIP CXBPGA ;SWAP IN IF NECESSARY
NOSKED ;DON'T LET PAGE STATE CHANGE
HRRZ T1,SWPSRC ;GET PAGE NUMBER
SKIPN T1,CXBPGA(T1) ;GET POINTER
JRST SWPPG4 ;NON-EX
CALL RELCXB ;RELEASE MAP (OKINT)
LOAD T2,PTRCOD,T1 ;GET POINTER CODE
CAIE T2,IMMCOD ;PRIVATE?
RETBAD(LOCKX1,OKSKED) ;NO, ILLEGAL
TLNE T1,(NCORTM) ;IN CORE?
RETSKP ;NO, SKIP RETURN NOSKED
ANDX T1,STGADM ;GET ADDR ONLY
MOVSI T2,(-PLKV) ;GET LOCK MASK
TDNE T2,CST1(T1) ;IS PAGE LOCKED?
RETBAD(LOCKX2,OKSKED) ;YES, ERROR
CALL SKPNWR ;WAIT FOR ANY WRITES TO FINISH
JRST SWPPG2 ;HAD TO WAIT, CHECK EVERYTHING AGAIN
LOAD T2,CSTAGE,(T1) ;GET AGE
CAIGE T2,PSASN ;ASSIGNED TO PROCESS?
JRST SWPPG3 ;NO, DEASSIGN
CALL SWPOT0 ;SWAP PAGE OUT
SWPPG2: OKSKED
JRST SWPPG1 ;AND CHECK AGAIN
SWPPG3: CALL RPCST ;DEASSIGN CST USAGE (SO WE CAN SWAP IN)
RETSKP ;RETURN SUCCESS (NOW SWAPPED OUT) (NOSKED)
SWPPG4: HRRZ B,SWPSRC ;GET VIRT PAGE #
MOVE A,IMMPTR ;GET IMMEDIATE POINTER
TXO A,UAAB ;SET UNASSIGNED ADDR BIT
MOVEM A,CXBPGA(B) ;STORE IN PAGE TABLE
CALL RELCXB ;RELEASE TEMP MAPPING
RETSKP ;AND INDICATE SUCCESS
> ;END OF REPEAT 0
;SETUP PAGER VARIABLES FOR NEW PROCESS
; FORKX/ FORK INDEX
; CALL SETPPG
; RETURN +1 ALWAYS
SETPPG::MOVE FX,FORKX
LOAD T1,FKPSB ;GET CORE ADR OF PSB
MOVE T1,SPT(T1)
TXNE T1,NCORTM
BUG(HLT,PSBNIC,<SETPPG-PSB NOT IN CORE>)
STOR T1,PAGUBA ;PUT IT IN DATAO WORD
MOVE T2,PSBBAS
STOR T1,STGADR,SPT(T2) ;PUT IT IN MMAP BASE
LOAD T1,FKJSB ;GET CORE ADR OF JSB
MOVE T1,SPT(T1)
TXNE T1,NCORTM
BUG(HLT,JSBNIC,<SETPPG-JSB NOT IN CORE>)
MOVE T2,JOBBAS
STOR T1,STGADR,SPT(T2) ;PUT IT IN MMAP BASE
HRRZ T1,FKCNO(FX) ;GET PROCESS USE BIT NUMBER
MOVE T2,BITS(T1) ;GET BIT
LOAD T1,FKAGE ;GET CURRENT AGE
STOR T1,AGEMSK,T2 ;CONSTRUCT CST UPDATE WORD
CALL MVAGER ;SET NEW AGE WORD
RET
;PRELOAD PAGES ON REQUEST
; 1/ IDENT OF FIRST PAGE
; 2/ NUMBER OF SUCCESSIVE PAGES
; CALL PREPG
; RETURN +1: NOT ALL PAGES DONE
; RETURN +2: ALL PAGES DONE, SWAPIN REQUESTED FOR ALL PAGES NOT IN CORE
PREPG:: PUSH P,2 ;SAVE COUNT
CALL SETCPT ;MAP PAGE TABLE
PREPG4: MOVE 2,NRPLQ ;CHECK FOR SUFFICIENT FREE PAGES
CAMG 2,NRPMX ;BELOW MIN?
JRST [ CALL RELCPT ;YES, RELEASE PAGE TABLE
POP P,2
RET] ;RETURN FAIL
NOSKED
PUSH P,1 ;SAVE IDENT
HRRZ 2,1
SKIPE 2,CPTPGA(2) ;GET PTR FROM MAP
CALL PREPG1 ;INITIATE SWAP
POP P,1 ;RECOVER IDENT
OKSKED
SOSLE 0(P) ;DONE ALL PAGES?
AOJA 1,PREPG4 ;NO, BUMP IDENT AND GO DO NEXT ONE
POP P,2
CALL RELCPT ;RELEASE PT
RETSKP
;PRELOAD PAGES FOR FORK, FORKX IN 7
PRELD:: SAVEPQ
SKIPN PRELDF ;PRELOADING IN OPERATION?
JRST PREL2 ;NO
SETOM PRELRQ ;SET FLAG NOTING PRELOADING SWAPS
HRRZ 11,FKNR(7) ;CURRENT WS SIZE
SUBI 11,4 ;LESS PSB, UPT, AND 2 RESERVE
HRRZ 1,FKPGS(7) ;PSB
CALL SFITPG ;MAP IT INTO FITPG
HLRZ 1,FKPGS(7) ;PAGE TABLE
CALL SPRLPG ;MAP INTO PRLPG
MOVSI 10,-NWSPGS ;SETUP TO SCAN WS BIT WORDS
PREL1: SKIPE 5,XWSPGS(10) ;ANY PAGES THIS WORD?
PREL6: JFFO 5,PREL3 ;YES
AOBJN 10,PREL1
PREL2: SETZM PRELRQ
RET
PREL3: ANDCM 5,BITS(6) ;REMOVE BIT FOR PAGE JUST FOUND
PUSH P,5 ;SAVE PARTIAL BIT WORD
MOVEI 5,0(10) ;COMPUTE PAGE NUMBER IN UPT
IMULI 5,^D36
ADDI 6,0(5)
SKIPN 2,PRLPGA(6) ;CHECK IF PAGE EXISTS
JRST PREL4 ;NONE
HLLZ 1,FKPGS(7) ;CONSTRUCT IDENTIFIER FOR PRIVATE CASE
HRRI 1,0(6) ;PTN.PN
CALL PREPG1 ;SWAP IN IF NOT ALREADY IN CORE
PREL4: POP P,5 ;RECOVER PARTIAL BIT WORD
SOJG 11,PREL6 ;KEEP GOING UNLESS WS EXHAUSTED
JRST PREL2 ;QUIT
;PRELOAD A PAGE - INITIATE SWAPIN IF PAGE NOT ALREADY IN CORE
;WILL BE A NOOP IF POINTER IS INDIRECT
; 1/ IDENT OF PAGE
; 2/ PTR
; CALL PREPG1
; RETURN +1: ALWAYS
PREPG1: LOAD 3,PTRCOD,2 ;GET PTR TYPE
CAIN 3,INDCOD ;AN INDIRECT POINTER?
RET ;YES. RETURN IMMEDIATELY
CAIN 3,SHRCOD ;SHARED?
JRST [ LOAD 1,SPTX,2 ;YES, GET SPT INDEX
MOVE 2,1 ;SPTN TO 2
CALL CHKDMO ;SEE IF A DISMOUNTED OFN
RET ;IT IS . DON'T LOAD IT THEN
LOAD 2,STGADR,SPT(1) ;AND ADDRESS FROM SPT
JRST .+1]
TLNE 2,(NCORTM) ;PAGE NOW IN CORE?
JRST [ SKIPLE NRPLQ ;MAKE SURE THERE'S ROOM
TLNN 2,(DSKAB+DRMAB) ;AND PAGE IS ASSIGNED
JRST PREPG2
CALL SWPIN ;NO, SWAP IT IN
JRST PREPG2]
HRRZ T2,T2 ;FLUSH LH
LOAD 1,CSTAGE,(2) ;PAGE IS IN CORE, SEE WHAT STATE
CAIN 1,PSRPQ ;ON REPLACABLE?
JRST PREL5 ;YES
CAIE 1,PSWIP ;BEING WRITTEN?
JRST PREPG2 ;NO, ANYTHING ELSE IS OK
PIOFF ;INTERLOCK CHECK
LOAD 3,CSTAGE,(2) ;GET CURRENT AGE
MOVX 1,PSRDN ;SET NEW AGE
STOR 1,CSTAGE,(2) ;TO READ COMPLETE
CAIN 3,PSRPQ ;WAS ON RPLQ?
JRST PREL5 ;YES
SOS IOIP ;NO, HAVE NOW DISABLED COMPLETION ACTION
PION
PREPG2: RET
PREL5: CALL PRLDEQ ;DEQUEUE THE PAGE FROM RPLQ
MOVX 1,PSRDN
STOR 1,CSTAGE,(2) ;SET PAGE TO READ-COMPLETED
STOR FX,CFXRD,(2) ;NOTE FORK
JRST PREPG2
;ROUTINE USED BY PREPG1 AND FRCSPM TO DEQUEUE A PAGE FROM RPLQ
; T2/ PAGE NUMBER
PRLDEQ: SOS NRPLQ ;TAKE PAGE OFF REPLACABLE
PIOFF
MOVE 1,CST3(2)
HRRZ 3,1
HLLM 1,0(3)
HLRZ 3,1
HRRM 1,0(3)
PION
SETZRO <PUFLD,CORMB>,CST0(2)
SETZM CST3(2)
RET ;DONE. PAGE DEQUEUED
;CHECK WS BITS AS PROCESS LEAVES BALSET
POSTPG::SKIPG POSPGF ;POST PURGING ON?
JUMPE 1,R ;NO, RETURN IF NO WS UPDATE NEEDED
TRVAR <REMBFL> ;FLAG FOR WS UPDATE
MOVEM 1,REMBFL
SAVEQ
CALL SWPOMI ;INIT SWAPOUT LIST
HRRZ 1,FKPGS(7)
CALL SFITPG ;MAP VIA FITPG
HLRZ 1,FKPGS(7) ;PAGE TABLE
CALL SPRLPG ;MAP VIA PRLPG
MOVSI 6,-NWSPGS ;SCAN WS BIT WORDS
SETZ 3, ;COUNTING BITS
REMB2: SKIPE 4,XWSPGS(6) ;ANY BITS HERE?
REMB7: JFFO 4,REMB5 ;YES, FIND ONE
AOBJN 6,REMB2
ADDI 3,3 ;PAGES IN WS PLUS 3 FOR MON OVHD
CAIGE 3,6 ;SET NR TO: MAX(6,SIZ,WSBITS+3)
MOVEI 3,6
HRRZ 2,FKWSP(7) ;SIZE
CAIGE 3,0(2)
MOVEI 3,0(2)
LOAD 2,FKWSS ;CURRENT NR
CAILE 3,0(2) ;ABOVE .G. CURRENT?
MOVEI 3,0(2) ;YES, KEEP CURRENT
HRRM 3,FKNR(7) ;SET NEW NR
CALL SWPOMG ;DO IO FOR ALL PAGES FOUND
RET
;SWAP OUT PURGED PAGE
GCSWP: MOVE 2,CST1(1)
TLNE 2,(-PLKV) ;DON'T SWAP PAGE IF LOCKED
RET
MOVSI 2,(DWRBIT)
TDNE 2,CST3(1) ;DON'T SWAP PAGE IF NOW BEING WRITTEN
RET
LOAD 2,CSTAGE,(1) ;GET PAGE STATE CODE
CAIGE 2,PSASN ;PAGE NOW ASSIGNED?
JRST GCSW1 ;NO, SWAP IT
LOAD 2,CSTOFK,(1) ;GET OWNING FORK NUMBER
PUSH P,1
CAIGE 2,NFKS ;ASSIGNED?
CALL SOSWSP ;YES, DEASSIGN IT
POP P,1
GCSW1: SKIPG SWRSAF ;REASSIGNING STORAGE?
JRST [ CALLRET SWPOUT] ;NO, DO SINGLE-PAGE SWPOUT
CALLRET SWPOML ;YES, BUILD SWAP LIST
;LOOK AT PAGE IN WS
REMB5: ANDCM 4,BITS(5) ;REMOVE BIT FROM TEMP WORD
MOVEI 1,0(6) ;COMPUTE PAGE NUMBER IN PT
IMULI 1,^D36
ADDI 1,0(5)
SKIPN 1,PRLPGA(1) ;PAGE NOW EMPTY?
JRST REMB6 ;YES, FORGET IT
LOAD 2,PTRCOD,1 ;GET PTR TYPE
CAIN 2,INDCOD ;INDIRECT?
JRST REMB6 ;YES, IGNORE
CAIN 2,SHRCOD ;SHARED?
JRST [ LOAD 1,SPTX,1 ;YES, GET ADDRESS FROM SPT
MOVE 1,SPT(1)
JRST .+1]
TLNE 1,(NCORTM) ;PAGE NOW IN CORE?
JRST REMB6 ;NO, FORGET IT
HRRZ 2,1
LOAD 2,CSTAGE,(2) ;GET PAGE STATE CODE
CAIGE 2,PSASN ;PAGE IN USE?
JRST [ CAIE 2,PSRDN ;NO, IS IT READ COMPLETED?
JRST REMB6 ;NO, FLUSH IT
JRST .+1] ;YES, KEEP IT
PUSH P,3
PUSH P,4
SKIPLE POSPGF ;POST PURGING REQUESTED?
CALL GCSWP ;YES, SWAP OUT THE PAGE
POP P,4
POP P,3
AOJA 3,REMB7 ;COUNT PAGE AND CONTINUE
REMB6: SKIPN REMBFL ;FORK WAS DISMISSED OR FORCED OUT?
AOJA 3,REMB7 ;FORCED OUT, DON'T FLUSH UNREF PGS
MOVE 2,BITS(5)
ANDCAM 2,XWSPGS(6) ;DISMISSED, FLUSH UNREF PAGES
JRST REMB7
;DEASSIGN CORE
DECOR: TLNE 1,(NCORTM) ;GIVEN MAP WORD, NOW IN CORE?
RET ;NO, NOTHING TO DO
PUSH P,2
PUSH P,3
CALL DASWSP ;DEASSIGN PAGE FROM FORK
MOVSI 2,(-PLKV)
HRRZ 3,1
TDNE 2,CST1(3) ;PAGE WAS LOCKED?
JRST [ AOS BALSHC ;YES, CHARGE TO OVERHEAD
AOS SUMNR
JRST .+1]
POP P,3
POP P,2
RET
;REMOVE PAGE FROM CURRENT FORK ASSIGNMENT
; A/ CORE PAGE NUMBER
; CALL DASWSP
; RETURN +1, PAGE DEASSIGNED IF PREVIOUSLY ASSIGNED.
DASWSP: HRRZ 2,1
LOAD 2,CSTAGE,(2) ;GET STATE CODE
CAIGE 2,PSASN ;NOW ASSIGNED?
RET ;NO
HRRZ 2,1
LOAD 2,CSTOFK,(2) ;GET PROCESS ASSIGNMENT
CAIL 2,NFKS ;ASSIGNED?
RET ;NO
PUSH P,1
CALL SOSWSP ;REDUCE N FOR THIS PROCESS
HRRZ 1,0(P)
MOVX 2,OFNUL ;MARK PAGE UNASSIGNED
STOR 2,CSTOFK,(1)
POP P,1
RET
;DECREMENT WSP AND RELEASE CORE NUMBER IF WSP 0
SOSWSP: SOS 1,FKWSP(2)
TRNE 1,400000 ;NEGATIVE?
JRST [ BUG(CHK,WSPNEG,<SOSWSP-WSP NEGATIVE>)
SETZB 1,FKWSP(2) ;FIXUP SOMEWHAT
JRST .+1]
TRNE 1,777777 ;WSP NOW 0?
RET ;NO
PUSH P,FX
MOVEI FX,0(2)
LOAD 1,FKLOC
POP P,FX
CAIGE 1,NBP ;IN BALSET?
RET
HRRZ 1,FKCNO(2)
JUMPE 1,R ;NO NUMBER (?)
HLLZS FKCNO(2)
MOVE 1,BITS(1)
IORM 1,FRECB
RET
;GARBAGE COLLECT CORE, REMOVE PAGES OF PROCESSES NOT IN BAL SET
;LOCAL AC USE:
; P1/ NUMBER OF PAGES NOW AVAILABLE (NRPLQ+IOIP+COLLECTED)
; P2/ MASK FOR CORE NUMBERS OF PROCESSES NOW IN BALSET
; P3/ TEMP
; P4/ CURRENT CORE PAGE NUMBER
GCCOR:: MOVE T1,NRPLQ
ADD T1,IOIP ;NUMBER OF PAGES NOW OR SOON TO BE AVAILABLE
;SUBI T1,GCMIN0/4 ;LESS PAD
CAMG T1,NRPMIN ;SUFFICIENT?
SKIPG NSSUN ;FILESYS INITIALIZED?
RET ;NO, DO NOTHING
MOVE 1,NRPMX
CAMLE 1,NRPLQ
MOVE 1,NRPLQ ;INSPECT N PAGES
GCCORX: SAVEP
SKIPL SSKED ;NOSKED FORK?
JRST [ SKIPN NRPLQ ;YES, DESPERATE?
SKIPE IOIP
RET ;NO, DO NOTHING
JRST .+1] ;YES, GO AHEAD
AOS NGCCOR ;COUNT OCCURRANCES
JUMPE 1,GCPC2 ;N MAY BE 0 ...
HRRZ P3,RPLQ ;ON REPLACABLE QUEUE
GCPC1: MOVEI 3,0(P3)
SUBI 3,CST3 ;GET PAGE NUMBER
CALL DEPG ;UNDO POINTER AND FLUSH BACK PTR,
SETZM CST2(3) ;THUS UNLOCKING OWNING PT
HRRZ P3,0(P3)
SOJG 1,GCPC1
GCPC2: MOVEI T1,GCMIN0 ;GET INITIAL TARGET RPLQ LEVEL
ADD 1,NRPMIN ;INCLUDING RESERVES FOR FORKS ENTERING BS
SKIPE SKEDFC ;FORCED CLEAR?
MOVX T1,1B1 ;YES, VERY LARGE NUMBER
MOVEM 1,GCMINP
GCPC4: SKIPA SKEDFC ;FORCED CLEAR? **** UNDER INVESTIGATION ***
JRST [ CALL FGC ;NO, TRY FAST GC
JUMPE P2,GCPC3 ;JUMP IF NOTHING FOUND
MOVE T1,NRPLQ ;SEE HOW MANY PAGES NOW AVAILABLE
ADD T1,IOIP
CAMG T1,GCMINP ;SUFFICIENT?
JRST GCPC4 ;NO, DO ANOTHER FORK
RET] ;OK, DONE
GCPC3: MOVE P1,NRPLQ
ADD P1,IOIP ;WRITES NOW IN PROGRESS
SETZB P2,P3 ;FOR BITS OF BALSET PROCESSES
GCCOR3: CAML P3,FBALS ;LOOKED AT ALL BALSET PROCESSES?
JRST GCCOR2 ;YES
MOVE 1,BALSET(P3)
TLNE 1,(BSNUL) ;VALID PROCESS NUMBER?
AOJA P3,GCCOR3 ;NO
HRRZ 1,FKCNO(1)
IOR P2,BITS(1) ;PROCESS IN BALSET
AOJA P3,GCCOR3
;ENTRY TO GCCOR TO DEPG ALL RPLQ FIRST
GCCOR0::MOVE 1,NRPLQ
JRST GCCORX
;FORK GC - COLLECT PAGES FOR SPECIFIED PROCESS
; FX/ FORK INDEX
; CALL FKGC
FKGC:: SAVEAC <P1,P2>
MOVEI P2,1 ;SCAN ONLY THIS FORK
MOVE T1,MONCOR ;SETUP AOBJN PTR
SUB T1,NHIPG
MOVSI P1,-1(T1)
HRR P1,MONCOR
CALL SWPOMI ;INIT SWAPOUT LIST
JRST FGC1 ;GO SCAN CORE
;'FAST' GC - COLLECT PAGES FOR ONE PROCESS
FGC: SETZ P2, ;INIT COUNT OF PAGES COLLECTED
MOVE T1,MONCOR ;SETUP AOBJN PTR
SUB T1,NHIPG
MOVSI P1,-1(T1) ;NEG COUNT
HRR P1,MONCOR
CALL SWPOMI ;INIT SWPOUT LIST
FGC5: LOAD T1,CSTAGE,(P1) ;SCAN FOR FIRST COLLECTABLE PAGE
CAIL T1,PSASN ;ASSIGNED?
JRST FGC4 ;YES, CHECK IT
FGC6: AOBJN P1,FGC5 ;DO NEXT PAGE
RET ;FOUND NO COLLECTABLE PAGE
FGC4: LOAD FX,CSTOFK,(P1) ;GET OWNING FORK
CAIGE FX,NFKS ;ASSIGNED TO EXISTANT FORK?
SKIPGE FKPT(FX)
JRST FGC6 ;NO
LOAD T1,FKLOC
CAIGE T1,NBP ;FORK ON WTLST?
JRST FGC6 ;NO, IN BALSET
HLRZ T1,FKPT(FX)
CAIE T1,WTLST
JRST FGC6 ;NO
;NOW SCAN REST OF CST FOR PAGES OWNED BY SAME FORK
FGC1: LOAD T1,CSTOFK,(P1)
CAMN T1,FX ;SAME FORK
JRST FGC2 ;YES, COLLECT IT
FGC3: AOBJN P1,FGC1 ;DO ALL PAGES
CALL SWPOMG ;SWAPOUT LIST
RET ;DONE OK
FGC2: LOAD T1,CSTAGE,(P1)
CAIGE T1,PSASN ;PAGE ASSIGNED?
JRST FGC7 ;NO
MOVX T1,-PLKV
MOVX T2,DWRBIT
TDNN T1,CST1(P1) ;PAGE LOCKED?
TDNE T2,CST3(P1) ;PAGE BEING WRITTEN?
JRST [ HRRZ T1,P1 ;YES, JUST DEASSIGN IT
CALL DASWSP
JRST FGC7]
ADDI P2,1 ;COUNT PAGES COLLECTED
HRRZ T1,P1 ;DEASSIGN PAGE
CALL DASWSP
HRRZ T1,P1
MOVX T2,CORMB
TDNE T2,CST0(P1) ;PAGE MODIFIED?
SKIPG SWRSAF ;REASSIGN SWAP ADDRESSES?
JRST [ CALL SWPOUT ;NO, SINGLE PAGE SWPOUT
JRST FGC7]
CALL SWPOML ;YES, YES - BUILD SWAP LIST
FGC7: JUMPG P2,FGC3 ;CONTINUE SAME FORK IF PAGES COLLECTED
JRST FGC6 ;LOOK FOR ANOTHER FORK IF PAGE NOT COLLECTABLE
GCCOR2: ANDCAM P2,PUBCL ;FOR PROCESSES WHICH CAME BACK IN BALSET
CALL SWPOMI ;INIT SWAPOUT LIST
MOVE P4,MONCOR
SUB P4,NHIPG ;COMPUTE MAX NUMBER PAGES TO CHECK
MOVSI P4,-1(P4)
SKIPN T1,GCCLPG ;START WHERE ENDED LAST TIME
MOVE T1,MONCOR ;OR AT LOWEST PAGE
HRR P4,T1 ;SETUP AOBJN PTR
GCC2: HRRZ T1,P4
CAMLE T1,NHIPG ;REACHED END OF CORE?
CALL GCECOR ;YES, VARIOUS FIXUPS AND WRAPAROUND
LOAD 1,CSTAGE,(P4) ;CODE FIELD
SKIPE SKEDFC ;FORCED CLEAR?
JRST [ CAIE T1,PSRDN ;READ DONE?
CAIL T1,PSASN ;NO. ASSIGNED THEN?
JRST GCCS ;YES. COLLECT IT THEN
JRST GCC1] ;NO. MUST LEAVE IT
CAIGE 1,PSASN ;PAGE IN USE?
JRST [ CAIN T1,PSSPQ ;NO, PAGE ON SPECIAL MEMORY QUEUE?
AOS BSHC1 ;YES, CHARGE TO SYSTEM
CAIE T1,PSRDN ;READ COMPLETE?
JRST GCC1 ;NO, SKIP PAGE
CAMGE P1,NRPMIN ;TIGHT FOR CORE?
JRST GCCS ;YES, GRAB A PRELOADED PAGE
LOAD FX,CFXRD,(P4) ;GET FX OF FORK WHICH INITIATED READ
CAIGE FX,NFKS ;IF NOT A FORK,
SKIPGE FKPT(FX) ;OR FORK DELETED?
JRST GCCS ;FLUSH PAGE
LOAD 2,FKLOC
CAIL 2,NBP ;IF FORK NOT IN BALSET,
JRST GCCS ;COLLECT PAGE
JRST GCC1] ;LEAVE PAGE
LOAD FX,CSTOFK,(P4) ;GET PROCESS ASSIGNMENT
CAIGE FX,NFKS ;PAGE NOW ASSIGNED?
SKIPGE FKPT(FX) ;AND FORK NOT DELETED?
JRST GCCS ;NO, COLLECT IT
MOVE 1,PUBCL ;PROCESS BITS TO BE CLEARED
ANDCAB 1,CST0(P4)
LOAD 3,FKLOC
CAIGE 3,NBP ;OWNER IN BALSET?
JRST GCC1 ;YES, KEEP PAGE
HLRZ 3,FKPT(FX) ;CURRENT LOCATON
CAIE 3,WTLST ;ON WAIT LIST, OR
TDNN 1,P2 ;USERS IN BALSET?
JRST GCCS ;NO, COLLECT
CAMGE P1,NRPMIN ;TIGHT ON CORE?
JRST GCCS ;YES, COLLECT SHARED PAGE
AOS BSHC1 ;NO, CHARGE PAGE TO SYSTEM
JRST GCC1
GCCS: HRRZ 1,P4
CALL DASWSP ;DEASSIGN PAGE FROM FORK
MOVE 2,CST1(P4) ;BACKUP ADDRESS
TLNE 2,(-PLKV) ;PAGE LOCKED?
JRST [ AOS BSHC1 ;YES, LEAVE IT AND CHARGE TO SCHED
JRST GCC1]
MOVSI 2,(DWRBIT)
TDNE 2,CST3(P4) ;PAGE BEING WRITTEN?
JRST GCC1 ;YES, LEAVE IT
HRRZ T1,P4 ;SWAPOUT
MOVX 2,CORMB
TDNE 2,CST0(1) ;PAGE WAS WRITTEN?
SKIPG SWRSAF ;REASSIGNING SWAP STORAGE?
JRST [ CALL SWPOUT ;NO, DO SINGLE-PAGE SWAPOUT
JRST .+2]
CALL SWPOML ;YES, PUT PAGE ON LIST
ADDI P1,1 ;COUNT PAGES COLLECTED
CAMGE P1,GCMINP ;STOP IF COLLECTED ENOUGH
GCC1: AOBJN P4,GCC2
MOVEM P4,GCCLPG ;REMEMBER LAST PAGE DONE
CALL SWPOMG ;DO ALL SWAPS QUEUED ABOVE
SETZM CGFLG
RET
GCECOR: HRR P4,MONCOR ;RESET TO LOWEST PAGE
MOVE T1,BSHC1 ;GET NEW BALSHC VALUE
PIOFF ;PROTECT AGAINST CHANGES AT PI LEVEL
SUBM T1,BALSHC ;COMPUTE NEW-OLD
EXCH T1,BALSHC ;SET NEW VALUE
ADDM T1,SUMNR ;ADJUST SUMNR BY DIFFERENCE
PION
SETZM BSHC1 ;RESET NEW SHARE COUNT
RET
;MULTIPLE-PAGE SWAPOUT ROUTINES. PROCEDURE:
; 1. CALL SWPOMI TO INIT LIST
; 2. CALL SWPOML FOR EACH PAGE TO BE SWAPPED
; 3. CALL SWPOMG TO BEGIN IO FOR ALL PAGES
;INIT SWAPOUT LIST
; CALL SWPOMI
; RETURN +1: ALWAYS
SWPOMI: SETZM SWPRC0 ;INIT COUNT
MOVEI 1,SWPLST ;INIT END PTR
MOVEM 1,SWPLSI
SETZM SWPLST ;INIT LIST PTR
RET
;ADD PAGE TO SWAPOUT LIST IF POSSIBLE. IF PAGE WOULD NOT BE SWAPPED
;TO DRUM THEN CALL REGULAR SWAPOUT. OTHERWISE, DEASSIGN
;EXISTING DRUM ADDRESS AND PUT PAGE ON LIST.
SWPOML: SKIPN 2,CST2(1) ;PTR BACKUP EXISTS?
JRST SWPOM1 ;NO, EXCEPTION CASE.
HLRZ 3,2 ;CHECK IF IN SPT
JUMPN 3,[CAIGE 3,NOFN ;PAGE LIVES IN FILE XB?
JRST SWPOM1 ;YES, EXCEPTION CASE.
JRST SWPOM2] ;NO, PAGE LIVES IN FORK PAGE TABLE
MOVE T3,T1 ;SAVE STORAGE ADDRESS
MOVEI T1,0(T2) ;SPT INDEX
CALL GETSHR ;GET SHARE COUNT
EXCH T1,T3 ;RESTORE REGS
JUMPE 3,SWPOM1 ;IF SHARE COUNT 0, THEN EXCEPTION CASE
SWPOM2: MOVE 2,CST1(1) ;CHECK EXISTING BACKUP ADDRESS
TLNN 2,(DSKAB) ;HAS DRUM ADDRESS NOW?
TLNN 2,(DRMAB)
JRST SWPOM1 ;NO, EXCEPTION CASE
CALL GDSTX ;GET DST INDEX FOR DRUM ADDRESS
MOVE 3,DST(2) ;GET NEXT LEVEL BACKUP ADDRESS
MOVX 4,CORMB
TLZE 3,(BWRBIT) ;MODIFIED ON DRUM?
IORM 4,CST0(1) ;YES, NOTE
SETOM DST(2) ;FLUSH DST SLOT
EXCH 3,CST1(1) ;REPLACE BACKUP ADDRESS FOR PAGE
PUSH P,1
MOVE 1,3 ;GET DRUM ADDRESS
CALL DASDRM ;DEASSIGN IT
POP P,1
MOVEI 2,CST3(1) ;PUT PAGE ON SWAPOUT LIST
HLLZS 0(2) ;MARK END OF LIST WITH 0
HRRM 2,@SWPLSI ;APPEND TO END OF LIST
MOVEM 2,SWPLSI ;UPDATE END PTR
AOS SWPRC0 ;COUNT PAGES ON LIST
RET
;EXCEPTION CASE - PAGE CANNOT BE WRITTEN ON DRUM OR HAS NO DRUM ADDRESS
SWPOM1: CALLRET SWPOUT ;USE SINGLE-PAGE SWPOUT
;ASSIGN NEW DRUM STORAGE AND INITIATE I/O FOR ALL PAGES ON SWAPOUT LIST.
SWPOMG: SKIPG SWPRC0 ;ANY PAGES ON LIST?
RET ;NO
PUSH P,P1
PUSH P,P2
SWPOG2: HRRZ P1,SWPLST ;GET LIST OF PAGES TO DO
MOVE 1,SWPRC0 ;GET COUNT OF PAGES LEFT ON LIST
CALL DRMAM ;TRY TO GET THAT MANY SEQUENTIAL PAGES
MOVEM 2,SWPDAD ;REMEMBER FIRST ADDRESS OF GROUP
CAMLE 1,SWPRC0 ;GOT MORE THAN NEEDED?
MOVE 1,SWPRC0 ;YES
MOVEM 1,P2 ;REMEMBER COUNT OF CURRENT GROUP
MOVN 1,1
ADDM 1,SWPRC0 ;REDUCE NUMBER LEFT BY THIS GROUP SIZE
SWPOG1: JUMPE P1,SWPOG3 ;JUMP IF END OF LIST
MOVE 1,SWPDAD ;HAVE ANOTHER PAGE TO DO, GET NEXT DRUM
CALL DRMASA ; ADDRESS IN SEQUENCE AND ASSIGN IT
BUG(HLT,ASGSW2,<SWPOMG-CAN'T ASSIGN RESERVED DRUM ADDRESS>)
MOVEI 1,0(P1) ;GET PAGE NUMBER
SUBI 1,CST3
MOVE 2,SWPDAD ;GET NEW DRUM ADDRESS
MOVE 4,CST1(1) ;GET PRESENT BACKUP ADR FOR PAGE
MOVEM 2,CST1(1) ;SET DRUM ADR AS NEW BACKUP
CALL GDSTX ;GET DST INDEX FOR DRUM ADDRESS
MOVX 3,CORMB
TDNE 3,CST0(1) ;PAGE WAS MODIFIED IN CORE?
TLO 4,(BWRBIT) ;YES, MEANS MODIFIED RELATIVE TO DISK TOO
MOVEM 4,DST(2) ;SAVE DISK ADR OF PAGE
ANDCAM 3,CST0(1) ;CLEAR MODIFIED BIT IN CORE
MOVEI 3,PSWIP ;GET WRITE-IN-PROGRESS CODE
STOR 3,CSTAGE,(1) ;SET STATUS OF PAGE
AOS IOIP ;NOTE 1 MORE WRITE IN PROGRESS
AOS DRMWR ;NOTE 1 MORE DRUM WRITE
MOVE 1,SWPDAD ;BUMP DRUM ADDRESS TO NEXT PAGE
CALL DRMIAD
MOVEM 1,SWPDAD
SOJG P2,[HRRZ P1,0(P1) ;DO CDR IF HAVE MORE PAGES IN THIS GROUP
JRST SWPOG1] ;GO DO NEXT ONE
SWPOG3: HRRZ 1,0(P1) ;END OF GROUP, GET PTR TO NEXT GROUP
HLLZS 0(P1) ;TIE OFF LIST
EXCH 1,SWPLST ;SET NEXT LIST, GET CURRENT LIST
SUBI 1,CST3 ;MAKE PTR RELATIVE
TXO 1,DWRBIT ;SAY WRITE
CALL DRMIOM ;DO MULTI-PAGE WRITE
SKIPLE SWPRC0 ;DONE ALL OF GROUP, STILL PAGES ON LIST?
JRST SWPOG2 ;YES, DO ANOTHER GROUP
POP P,P2
POP P,P1
RET
;SWAP OUT PAGE REQUESTED BY PROCESS
; A/ CORE PAGE NUMBER
; CALL SWPOT0
; RETURN +1, SWAPOUT OF PAGE INITIATED.
SWPKPF==1B0 ;LOCAL FLAG: 0 = USE OFRQ, 1 = USE ONRQ
SWPOTK: SAVEAC <Q1>
MOVX Q1,SWPKPF ;KEEP PAGE
JRST SWPOT1
SWPOT0: SAVEAC <Q1>
MOVX Q1,0
SWPOT1: TLNE 1,(NCORTM) ;IN CORE?
JRST SWPTBD ;NO
HRRZ 2,1
CAML 2,MONCOR ;NO, LEGAL PAGE NUMBER?
CAMLE 2,NHIPG
JRST [ CALL RESPCK ;PART OF RESMON?
JRST .+1 ;NO. SWAP IT OUT THEN
JRST SWPTBD] ;YES. ERROR OF SOME SORT
CALL AGESET ;BE SURE PAGE IS READY
CALL DASWSP ;NOW DEASSIGN IT
MOVE 2,CST1(1)
TLNE 2,(-PLKV) ;CAN SWAP IT OUT?
JRST SWPTBD ;NO, LOCKED
MOVSI 2,(DWRBIT)
TDNE 2,CST3(1) ;BEING WRITTEN?
JRST SWPTBD ;YES
CALLRET SWPOU0 ;ALL OK, SWAPOUT THE PAGE
;HERE IF ANYTHING WRONG WITH PAGE
SWPTBD: BUG(HLT,ILPAG1,<SWPOT0-INVALID PAGE>)
;INITIATE SWAPOUT OF SINGLE PAGE
; 1/ CORE PAGE NUMBER
; CALL SWPOUT
; RETURN +1: ALWAYS, IO REQUESTED OR PAGE PUT ON REPLACABLE QUEUE
SWPOUT: SAVEAC <Q1>
MOVX Q1,0 ;CLEAR FLAGS
SWPOU0: SKIPN 2,CST2(1) ;GET BACKUP
JRST BKUPN ;PAGE HAS NO BACKUP, FLUSH IT
HLRZ 3,2 ;CHECK PT OF SOURCE
JUMPN 3,[CAIGE 3,NOFN ;PAGE LIVES IN FILE XB?
JRST BKUPC ;YES. GO CHECK FOR DISK OR DRUM
JRST BKUPS] ;NO, PAGE LIVES IN FORK PT, SEND TO DRUM
MOVE T3,T1 ;SAVE STORAGE ADDRESS
MOVEI T1,0(T2) ;GET SPTN
CALL GETSHR ;GET SHARE COUNT
EXCH T1,T3 ;RESTORE REG VALUES
CAIGE 2,NOFN ;OFN?
JRST SWPOF1 ;YES
JUMPE 3,BKUPD ;IF SHARE COUNT 0, SWAP TO DISK
BKUPC: MOVE 2,CST3(1)
TLNE 2,(DSKSWB) ;SWAP TO DISK REQUESTED BY DDMP?
JRST BKUPD ;YES
BKUPS: MOVE 2,CST1(1) ;CORE PAGE NUMBER IN 1, GET BACKUP ADR
TLNN 2,(DSKAB) ;DISK OR UNASSIGNED?
TLNN 2,(DRMAB)
JRST SWPO4 ;YES
BKUP0: MOVE 3,CST0(1) ;HAVE DRUM ADDRESS
TXNN 3,CORMB ;PAGE WRITTEN INTO?
JRST BKUPN ;NO, PUT IT ON RPLQ
CALL GDSTX
SWPO5: MOVSI 3,(BWRBIT) ;SET BACKUP WRITTEN BIT
IORM 3,DST(2)
SWPO2: MOVX 3,CORMB
ANDCAM 3,CST0(1) ;CLEAR WRITTEN BIT
MOVEI 3,PSWIP
STOR 3,CSTAGE,(1) ;SET CODE TO WRITE IN PROGRESS
AOS IOIP ;NOTE WRITE IN PROGRESS
HRLI 1,(DWRBIT) ;WRITE REQUEST BIT
CALL DRMIO ;INITIATE DRUM WRITE
AOS DRMWR ;COUNT DRUM WRITES FOR STATISTICS
RET
;OFN - MUST ALWAYS SWAP TO DRUM
SWPOF1: SKIPG 3 ;SHARE COUNT OK?
JRST [ MOVE 1,2 ;NO. OFN IS UNUSED
CALLRET CLROFN] ;SO GET RID OF IT
MOVE 2,CST1(1) ;YES, CHECK BACKUP ADDRESS
TLNN 2,(DSKAB) ;DISK?
JRST BKUP0 ;NO, DRUM ADR ALREADY ASSIGNED
SKIPGE DRUMP ;YES, MUST ENSURE SWAP OF XB TO DRUM
RET ;CAN'T SWAP TO DRUM, LEAVE IN CORE
JRST SWOFN ;GO ASN DRM ADR, EVEN IF DRM SPC LOW
;HERE IF NEED TO ASSIGN DRUM ADDRESS FOR PAGE GOING TO DRUM
SWPO4: MOVSI 3,(SWPERR)
TDNE 3,CST3(1) ;ERROR READING FROM DISK?
JRST BKUPN ;YES, DON'T WRITE IT
MOVE 3,DRMFRE
CAMGE 3,DRMIN0 ;YES. HAVE ROOM ON THE SWAPPING?
JRST [ TXNN T2,DSKAB ;NO. HAVE A BACK UP DISK ADDRESS?
JRST SWOFN ;NO. PUT IT ON THE SWAP SPACE ANYWAY
HLRZ T3,CST2(T1) ;YES. GET HOME FOR THIS PAGE
SKIPN T3 ;DOES IT LIVE IN AN OFN?
HRRZ T3,CST2(T1) ;NO. GET SPT INDEX THEN
CAIL T3,NOFN ;IS THIS THE OFN?
HLRZ T3,SPTH(T3) ;NO. GET IT FROM THE SHARE POINTER THEN
JUMPE T3,SWOFN ;IF A FORK PT PAGE, PUT IT ON THE SWAP SPACE
MOVE T3,SPTH(T3) ;GET OFN FLAGS
TXNE T3,OFNDUD ;SUPPRESSING DISK UPDATE?
JRST SWOFN ;YES. PUT IT ON SWAP SPACE
JRST BKUPD] ;NO. PUT IT ON THE DISK THEN
SWOFN: PUSH P,1
CALL DRMASN ;ASSIGN DRUM ADDRESS
BUG(HLT,DRMFUL,<DRUM COMPLETELY FULL>)
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)
TXNE 3,CORMB ;PAGE WRITTEN WHILE IN CORE?
JRST SWPO5 ;YES, SET BACKUP WRITTEN BIT ALSO
JRST SWPO2 ;NO
;SWAP PAGE TO DISK
BKUPD:
BKUPD1: MOVE 2,CST1(1) ;GET BACKUP ADDRESS
TLNN 2,(DSKAB+DRMAB) ;NONE?
JRST BKUP7 ;YES
TLNE 2,(DSKAB) ;DISK?
JRST BKUP3 ;YES
CALL GDSTX ;DRUM
MOVE 3,DST(2) ;GET NEXT LEVEL BACKUP ADDRESS
MOVX 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 BKUPD1
BKUP7: BUG(HLT,BKUPDF,<BKUPD - BAD CST1 ENTRY OR INCONSISTENT CST>)
BKUP3: MOVX T3,SWPERR
TDNE T3,CST3(T1) ;ERROR IN PAGE?
JRST BKUPN ;YES, DON'T WRITE IT
MOVX T3,CORMB
TDNN T3,CST0(T1) ;PAGE MODIFIED?
JRST [ TXNN Q1,SWPKPF ;NO, WHICH END OF RPLQ?
JRST BKUPF ;TOP
JRST BKUPN] ;END
ANDCAM 3,CST0(1)
HRLI 1,(DWRBIT) ;REQUEST WRITE
AOS DSKWR ;COUNT IT FOR STATISTICS
AOS IOIP ;NOTE WRITE IN PROGRESS
MOVSI 3,(DSKNB)
ANDCAM 3,CST1(1) ;MAKE SURE NO (DSKNB) STILL AROUND
MOVEI 3,PSWIP ;INDICATE WRITE IN PROGRESS
STOR 3,CSTAGE,(1)
LOAD T3,SWPKPF,Q1 ;SAVE KEEP FLAG FOR SWPDON
STOR T3,DSKSWB,CST3(T1)
CALL DSKIO
RET
;HERE IF PAGE CAN BE PUT DIRECTLY ON RPLQ.
BKUPF: CALLRET OFRQ ;TOP
BKUPN: CALLRET ONRQ ;END
;PAGER TRAP
PGRTRP::DATAO PAG,SETMON ;SET MON AC BLOCK
AOSGE INTDF ;MUST BE NOINT
JRST [ BUG (CHK,NSKDT2,<PGRTRP-BAD INTDF>)
SETZM INTDF ;FIX THE BAD VALUE
JRST .+1] ;AND PROCEED
SKIPE EXADF1 ;EXTENDED ADDRESS?
JRST PGRTE1 ;YES
EXCH T1,TRAPFL ;SAVE T1
MOVEM T1,TRAPS0 ;SAVE TRAP REASON
HLLZ T1,TRAPPC ;GET FLAGS
HRRZS TRAPPC ;ZERO HIGH PC
EXCH T1,TRAPFL ;STORE FLAGS
PGRTE1: CONSZ PI,177B27 ;FROM PI ROUTINE?
JRST PIPTRP ;YES. GO HANDLE IT THEN
AOSE TRAPC ;FIRST TRAP?
JRST PGRT2 ;NO, RECURSIVE
MOVEM P,TRAPAP ;SAVE AC-P
MOVE P,TRAPSP ;SETUP TRAP STACK
AOS UTRPCT ;COUNT TRAPS (BUT NOT RECURSIVE ONES)
PGRT2: EXCH A,TRAPFL ;CHECK FLAGS
TXNE A,UMODF ;USER?
JRST [ EXCH A,TRAPFL ;YES, DON'T NEED TO SAVE ACS
XJRSTF [PCU ;NOTE PERVIOUS CONTEXT USER
0,,PGRT3]]
EXCH A,TRAPFL
ADD P,BHC+4 ;SAVE ACS 1-4
DMOVEM 1,-3(P)
DMOVEM 3,-1(P)
PUSH P,7
PUSH P,CX
PUSH P,TRAPSW
PGRT3: LDB T2,[POINT 5,TRAPPC,17]
LDB T1,[POINT 5,TRAPS0,17]
SKIPG TRAPS0 ;CHECK FOR USER OR MONITOR
JRST SIMT2 ;USER -- DON'T BUGHALT
CAIE T2,MSEC1 ;IS PC IN "CODE" SECTION?
SKIPN T2 ;NO. HOW ABOUT SECTION 0?
CAILE T1,MAXSEC ;YES. IS REFERENCE TO A VALID SECTION?
BUG(HLT,SECGT1,<PGRT3 - SECTION NUMBER GREATER THAN MAXSEC>)
SIMT2: NOSKED ;NOSKED AND NOINT FOR DURATION OF TRAP
SIMT3: MOVE 1,TRAPS0 ;MOVE TRAP STATUS FROM TEMP
MOVEM 1,TRAPSW ;TO SAFE PLACE
SKIPE TRAPC
JRST PGRT5 ;NESTED TRAP, DON'T COUNT TIME TWICE
SKIPE IPTIM ;INCLUDE PAGE TRAP TIME?
JRST [ CALL GETHRT ;NO, GET CURRENT RUNTIME
PUSH P,T1 ;SAVE IT
JRST PGRT5]
CALL FRTOFF ;TURN OFF CLOCK
PUSH P,T1 ;HOLD STACK SLOT
PGRT5: DMOVE 1,TRAPFL ;RETURN
PUSH P,2 ;SAVE TRAP
PUSH P,1
EXCH 1,2
TLNE 2,(UMODF) ;FROM USER?
DMOVEM 1,UPDL ;YES, LEAVE IT WHERE IT CAN BE FOUND
MOVE FX,FORKX
MOVE T1,TRAPSW
TXNE T1,TWHPFF ;'HARD' FAILURE?
JRST [ LOAD T1,TWCOD,T1 ;YES, GET CODE
CAIL T1,PECOD0 ;MPE GROUP?
JRST PGMPE ;YES
CAIGE T1,KLCOD0 ;PROBLEM GROUP?
JRST PFDSPT-TWCOD0(T1) ;YES, DISPATCH TO HANDLER
JRST .+1]
CALL PGTACC ;ACCOUNT FOR ONE PAGE TRAP
TRPRST: CALL GETTPD ;DETERMINE CAUSE OF TRAP
JRST 0(T1) ;DISPATCH TO HANDLE IT
;PAGE FAIL AT PI LEVEL. SEE IF AR/ARX AND IF SO, DO ANALYSIS.
;IN ALL CASES, BUGHLT
;NOTA BENE... THE SAVING OF T1 IN MEMPA DOES NOT INSURE THAT
;THE REGISTER'S INITITAL CONTENTS WILL ALWAYYS BE AVAILABLE IN
;A SUBSEQUENT DUMP. IF MULTIPLE PI LEVELS TRIP THROUGH THIS CODE,
;OR IF A MEMORY PARITY OCCURS FOLLOWS CLOE UPON A PI PAGE FAIL
;FROM A BUG, THEN THE CONTENTS OF MEMAP IS NOT WHAT IS NEEDED.
;IN THE UNLIKELY EVENT THAT THIS HAPPENS, WAIT FOR THE NEXT
;OCCURRENCE OF THE BUG.
;ADD DISCALIMER TO PIPTRP
PIPTRP: MOVEM T1,MEMPA ;SAVE AN AC FOR DUMP ANALYSIS
MOVE T1,TRAPSW ;GET PAGE FAIL WORD
TXNN T1,TWHPFF ;ONE OF THE "HARD" FAILURES?
JRST PIPTR1 ;NO. BAD CODING THEN
LOAD T2,TWCOD,T1 ;YES. GET REASON
CAIL T2,PECOD0 ;AR OR ARX?
JSP T2,PFAID ;YES. GO ANALYIZE IT
PIPTR1: BUG(HLT,PITRAP,<PAGER TRAP WHILE PI IN PROGRESS>)
;DISPATCH FOR PAGE FAIL CODES
TWCOD0==20 ;FIRST 'HARD' PAGE FAIL CODE
KLCOD0==30 ;START OF KL PAGING CODES
PECOD0==36 ;MPE GROUP
PFDSPT::JRST UBPGF ;UNIBUS PAGE FAIL
JRST ILRD ;PROPRIETARY
JRST PGRTH ;REFILL ERROR
JRST ADRCMP ;ADDRESS COMPARE
JRST ILIND ;ILLEGAL INDIRECT
JRST PGRTH ;PAGE TABLE PARITY
JRST ILWR ;UNUSED
JRST ILSCN ;ILLEGAL SECTION
PGRTH: MOVE T1,TRAPSW
JSP T2,PFAID ;HANDLE HARD PAGE FAIL
PGRTH1: DMOVE T1,TRAPFL ;GET FLAGS AND PC (IN CASE MODIFIED)
EXCH T1,T2
DMOVEM T1,-1(P) ;AND MAKE IT THE ONES WE WILL USE
JRST PGUNTP ;RETRY
UBPGF:: SKIPN SMFLAG ;CHECK FOR KS10
JRST PGUNTP ;NOT A KS10 IGNORE IT
MOVE T1,TRAPFL ;FIND TRAP WORD
TLNE T1,(UMODF) ;CHECK TO SEE IF USER MODE
JRST ILWR ;YES -- ILLEGAL WRITE ERROR
BUG(HLT,UBANXM,<I/O NMX FROM UNIBUS DEVICE>,<UPTPFW,UPTPFO>)
;MEMORY DATA PARITY - DETECTED IN AR/ARX
PGMPE: CALL PGMPE0 ;HANDLE IN APRSRV
SKIPA ;NOT RECOVERABLE
JRST PGRTH1 ;RETRY. GET NEW PC AND FLAGS FIRST
MOVEI T1,ILLX03 ;PARITY ERROR
MOVEM T1,LSTERR
MOVX T1,.ICDAE ;INITIATE PSI ON DATA ERROR CHANNEL
JRST ILRF ;HANDLE AS ILLEG REFERENCE
ADRCMP: SKIPE INSKED ;WEED OUT BUGS
BUG(HLT,ABKSKD,<ADDRESS BREAK FROM SCHEDULER CONTEXT>)
MOVX T1,PC%AFI ;SET ADDRESS BREAK INHIBIT
IORM T1,0(P) ; SO FORK CAN CONTINUE AFTER SUSPENSION
MOVE T2,TRAPPC ;GET ADDR OF FAULTING INSTR
MOVEM T2,ADRBK1 ;SAVE FOR THE EXEC
MOVSI T1,400000+ADRBKF ;FLAG REQUEST FOR SCHEDULER
IORM T1,FKINT(FX) ; ..
MOVE T2,FORKX ;THIS FORK
CALL PSIR4 ;GET IT SEEN
CHKINT ;MAKE IT HAPPEN
JRST PGUNTP
REPEAT 0,<
;BAD NSKED OR INTDF - FIX BEFORE PROCEEDING
PGRT4: BUG(CHK,NSKDT2,<PGRTRP-BAD NSKED OR INTDF>)
JRST -2(T1) ;REDO AOS UNTIL IT WORKS
> ;END OF REPEAT 0
ILIND: MOVE T1,TRAPSW ;FIND TRAP REASON
JXN T1,TWUSR,ILRD ;DECLARE ILLEGAL READ
BUG(HLT,ILLIND,<ILLEGAL INDIRECT>)
ILSCN: MOVE T1,TRAPSW
JXN T1,TWUSR,ILRD ;ILLEGAL READ IF USER MODE
BUG(HLT,SECG37,<ILSCN-SECTION NUMBER GREATER THAN 37>)
JRST PGUNTP ;AND RETRY
;RESUME PROCESS AFTER PAGER TRAP
PGUNTP: SKIPE TRAPC ;OUTER LEVEL TRAP?
JRST PGU4 ;NO
SKIPE IPTIM ;INCLUDE PAGE TRAP TIME?
JRST [ CALL GETHRT ;YES, READ CURRENT TIME
SUB T1,-2(P) ;COMPUTE DIFFERENCE
JRST PGU5]
CALL FRTON ;TURN CLOCK ON, GET TIME OFF
PGU5: ADDM T1,PTTIM ;ACCUMULATE FORK TIME
ADDB T1,HSPTTM ;ACCUMULATE SYSTEM TIME
IDIVI T1,NTMS ;CONVERT UNITS
MOVEM T1,SPTTIM ;MAINTAIN 1 MS UNITS
PGU4: POP P,T3 ;flags and pc
POP P,T4
SKIPN TRAPC ;top level trap?
POP P,T1 ;yes, flush runtime
TLNN 3,(UMODF) ;TO USER?
JRST PGU3 ;NO, MONITOR
DMOVEM 3,FFL ;USER, CAN PUT RETURN IN FFL
SETOM TRAPC
SOSG NSKED ;DO OKSKED
XCT RSKED
SETOM INTDF ;FOR USER, MUST BE -1
JRST GOUSR ;RETURN TO USER
PGU3: DMOVEM 3,TRAPFL
POP P,TRAPSW
POP P,CX ;RESTORE AC'S
POP P,7
DMOVE 3,-1(P)
DMOVE 1,-3(P)
SUB P,BHC+4 ;CLEAN UP THE STACK
SOSGE TRAPC ;UNDOING TOP LEVEL TRAP?
MOVE P,TRAPAP ;YES, RESTORE P ALSO
SOSG NSKED ;DO OKSKED
XCT RSKED
SOS INTDF
OKINT
XJRSTF TRAPFL
;DETERMINE CAUSE OF TRAP AND GET TRAP INFORMATION. START FROM
;VIRTUAL ADDRESS IN TRAPSW.
; CALL GETTPD
; RETURNS +1 ALWAYS,
; TRPID/ IDENT OF PAGE CAUSING TRAP
; TRPPTR/ POINTER BITS AND/OR STORAGE ADDRESS
GETTPD: MOVE T2,TRAPSW ;START WITH TRAP ADDRESS
LOAD T1,TWVADR,T2
TXNE T2,TWUSR ;USER?
JRST [ TXO T1,1B0 ;YES
CALL FPTA ;GET I.D. OF PAGE
JUMPE T1,GETT1G ;NON-EX SECTION. ILLEGAL
JRST GETTP1] ;GOT IT.
CALL FPTA ;GET IDENT OF FIRST POINTER
JUMPE T1,GETTPX ;HAVE AN IDENTIFIER?
GETTP1: HLRZ T2,T1 ;GET PT IDENT
CALL CHKDMO ;SEE IF THIS IS A DISMOUNTED OFN
JRST GETT1F ;IT IS
MOVEM T2,TRPID ;SAVE IT UNTIL VERIFIED
LOAD T2,STGADR,SPT(T2) ;GET ADR OF PT
MOVEM T2,TRPPTR ;SAVE IT
TXNE T2,NCORTM ;IN CORE?
JRST GETT1A ;NO
HLL T2,CST0(T2) ;CHECK AGE
TXNN T2,PSASM ;ASSIGNED?
JRST GETT1B ;NO
MOVEM T1,TRPID ;PT OK, SAVE PAGE IDENT
HRRZS T1
CALL MOVRCA ;FETCH POINTER
MOVEM T1,TRPPTR ;SAVE IT
JUMPE T1,GETT1C ;JUMP IF NULL POINTER
MOVE T2,TRAPSW ;CHECK ACCESS AGAINST REFERENCE
TXNE T2,TWWRT ;WRITE REFERENCE?
JRST [ TXNE T1,PTCPY ;YES, COPY?
JRST GETT1D ;YES
TXNN T1,PTWR ;WRITE LEGAL?
JRST GETT1E ;NO
JRST .+1]
LOAD T2,PTRCOD,T1 ;CHECK POINTER TYPE
CAIN T2,INDCOD ;INDIRECT?
JRST [ LOAD T2,SPTX,T1 ;YES, CONSTRUCT IDENT OF PAGE POINTED TO
LOAD T1,IPPGN,T1
HRL T1,T2
JRST GETTP1] ;CONTINUE TRACE
CAIN T2,SHRCOD ;SHARED PTR?
JRST [ LOAD T2,SPTX,T1 ;YES, GET IDENT
MOVEM T2,TRPID ;SAVE IT
LOAD T1,STGADR,SPT(T2) ;GET ADDRESS
MOVEM T1,TRPPTR ;SAVE IT
CALL CHKDMO ;SEE IF DISMOUNTED OFN
JRST GETT1F ;IT IS
JRST .+1]
TXNE T1,NCORTM ;IN CORE?
JRST GETT1A ;NO
HRRZS T1 ;GET ADDRESS ONLY
LOAD T2,CSTAGE,(T1) ;CHECK AGE
CAIGE T2,PSASN
JRST GETT1B ;NOT ASSIGNED
MOVEI T1,PGUNTP ;PAGE OK, MAY BE REFERENCED
RET
;PAGE OR PAGE TABLE NOT IN CORE
GETT1A: MOVEI T1,NIC
RET
;PAGE OR PAGE TABLE AGE .L. 100
GETT1B: MOVEI T1,TRP0
RET
;NULL POINTER
GETT1C: MOVEI T1,NPG
RET
;WRITE-COPY
GETT1D: MOVEI T1,WCPY
RET
;ILLEGAL WRITE
GETT1E: MOVEI T1,ILWR
RET
;ATTMEPT TO CREATE PAGE TABLE IN NON-ZERO SECTION
GETTPX: BUG (HLT,SECNX,<CREATING PAGE TABLE FOR NON-0 SECTION>)
;ILLEGAL REFERENCE BECAUSE OF DISMOUNTED OFN
GETT1F: MOVEI T1,PMAPX7 ;GET CHARACTERISITIC ERROR
MOVEM T1,LSTERR ;LET PROCESS KNOW WHY MEM FAILED
SKIPA T1,[ILRD1] ;SKIP SETTING ERROR CODE
GETT1G: MOVEI T1,ILRD ;GO TO TRAP PLACE
RET ;AND DONE
;ROUTINE TO CHECK IF PAGE FAULT HAS OCCURRED ON A DISMOUNTED OFN
;ACCEPTS: T2/ SPTN OF PAGE TABLE
;RETURNS: +1 IF PAGE BELONGS TO A FILE ON A DISMOUNTED STRUCTURE
; +2 IF PAGE IS OK TO FAULT ON
CHKDMO::ACVAR <Q1,Q2> ;GET SOME REGS
HRRZ Q2,T2 ;GET SPTN FOR CHECKING
CAIL Q2,NOFN ;AN OFN?
JRST [ HLRZ Q2,SPTH(Q2) ;NO. SEE IF PAGE BELONGS TO A FILE
SKIPN Q2 ;DOES IT?
RETSKP ;NO. OK TO USE IT
JRST .+1] ;YES. MUST LOOK AT IT
MOVX Q1,OFNDMO ;GET DISMOUNTED BIT
TDNE Q1,SPTH(Q2) ;IS THIS A DISMOUNTED OFN?
RET ;YES. SAY SO
RETSKP ;NO
;AGE LESS THAN 100 TRAP
TRP0:: MOVE T2,TRPPTR ;GET CORE ADR
LOAD T1,CSTAGE,(T2) ;GET STATE CODE
CAILE T1,TRP0BM ;WITHIN RANGE?
JRST TRPRST ;NO. START TRAP OVER, PAGE PROBABLY
; HAS COMPLETED WRITING
XCT TRP0B(T1) ;DISPATCH PER PAGE STATE CODE
TRP0B: JRST TRP0C ;ON RPLQ
JRST BADAGE
JRST TRP2R ;READ COMPLETED
JRST BADAGE
JRST TRP0C ;WRITE IN PROGRESS
JRST BADAGE
JRST TRP0R ;READ IN PROGRESS
JRST BADAGE
TRP0BM==.-TRP0B-1 ;MAXIMUM LEGAL VALUE
TRP0C: MOVE T1,TRPPTR ;GET PHYSICAL PAGE
LOAD T2,CSTPST,(T1) ;GET SPECIAL PAGE STATE
CAIE T2,PSTAVL ;STILL AVAILABLE?
JRST TRPSPM ;NO - ATTEMPT TO PLACE ON SPMQ
CALL CHKRPQ ;MAKE SURE ENOUGH PAGES
JRST TRPRST ;RESCHEDULED, RESTART TRAP
TRP2R: MOVE T1,TRPPTR ;GET CORE PAGE NUMBER
LOAD T2,CSTPST,(T1) ;GET SPECIAL PAGE STATE
CAIE T2,PSTAVL ;STILL AVAILABLE?
JRST TRPSPM ;NO - ATTEMPT TO PLACE ON SPMQ
CALL AGESN ;ASSIGN PAGE
JRST PGUNTP ;UNTRAP AND CONTINUE
TRP0R: MOVSI T1,0(T2)
HRRI T1,SWPRT
RDISMS ;WAIT FOR PAGE
NOSKED
JRST TRPRST ;RECHECK TRAP
TRAPSP: IOWD NTSK,TRAPSK ;POINTER TO LOCAL STACK
BADAGE: BUG(HLT,ILAGE,<BAD AGE FIELD IN CST0>)
;HERE WHEN PAGE FAULTED ON WANTS TO BE REMOVED FROM AVAILABLE POOL
TRPSPM: LOAD T2,CSTAGE,(T1) ;GET AGE
CAIN T2,PSWIP ;WRITE IN PROGRESS?
JRST TRPSP2 ;YES - WAIT FOR COMPLETION
TRPSP1: CALL RPCST ;NO - RPLQ OR READ DONE, REMOVE FROM CST
PIOFF
CALL ONSPMQ ;PLACE ON SPMQ
JRST PGUNTP ;TRY REFERENCE AGAIN
TRPSP2: CALL SKPNWR ;STILL BEING WRITTEN?
JRST TRPRST ;RESCHEDULED - RESTART TRAP
JRST TRPSP1 ;NO - FREE PAGE NOW
;ASSIGN PAGE AND SET AGE
AGESET: PUSH P,FX
MOVE FX,FORKX
CALL AGESN
POP P,FX
RET
AGESN:: PUSH P,2
MOVEI 2,0(1)
AGES1: LOAD 1,CSTAGE,(2) ;GET AGE CODE
CAIL 1,PSASN ;NOW ASSIGNED?
JRST [ LOAD 1,CSTOFK,(2) ;YES, FIND OUT WHERE
CAML 2,MONCOR ;NOT SWAPPABLE PAGE? OR
CAIN 1,0(7) ;THIS PROCESS?
JRST AGES2 ;YES, OK
CAIL 1,NFKS ;ANY PROCESS?
JRST ATP1 ;NO
PUSH P,2
MOVEI 2,0(1)
CALL SOSWSP ;REDUCE WSP
POP P,2
JRST ATP1] ;GO ASSIGN TO THIS PROCESS
AGESX: CAILE 1,TRP0TM ;WITHIN TABLE RANGE?
JRST BADAGE ;NO - BOMB
XCT TRP0T(1)
AGES2: MOVEI 1,0(2)
POP P,2
RET
TRP0T: JRST ATP0 ;AVAILABLE AND ON REPLACABLE QUEUE
JRST BADAGE
JRST ATP1R ;READ COMPLETED
JRST BADAGE
JRST ATP4 ;WRITE IN PROGRESS
JRST BADAGE
JRST ATP2 ;READ IN PROGRESS
JRST BADAGE
TRP0TM==.-TRP0T-1 ;MAXIMUM LEGAL ENTRY
ATP1R: MOVSI 1,(SWPERR) ;CHECK FOR ERROR ON READ
TDNN 1,CST3(2)
JRST ATP1 ;NO ERROR
PUSH P,2
MOVEI T1,IOX5 ;STORE ERROR CODE
MOVEM T1,LSTERR
MOVX 1,.ICDAE ;FILE DATA ERROR PSI CHANNEL
MOVEI 2,0(7) ;GET FORK NUMBER
CALL PSIRQ ;INTERRUPT THE FORK
CHKINT ;GET IT SEEN
POP P,2
JRST ATP1
ATP2: MOVSI 1,0(2)
HRRI 1,SWPRT ;READ NOW IN PROGRESS OR COMPLETED
PDISMS ;RESCHEDULE UNTIL AVAILABLE
JRST AGES1 ;CHECK AGE AGAIN
ATP4: PIOFF
LOAD 1,CSTAGE,(2) ;GET CURRENT STATE OF PAGE
CAIE 1,PSWIP ;WRITE IN PROGRESS?
JRST [ PION ;NO, GO LOOK AT STATE AGAIN
JRST AGES1]
SETZRO <CSTAGE,CFXRD>,(2) ;INHIBIT COMPLETION ACTION
PION
SOS IOIP
JRST ATP1
ATP0: SOS NRPLQ ;ONE LESS PAGE ON REPLACABLE
PUSH P,3
PIOFF
MOVE 1,CST3(2) ;UNQUEUE PAGE FROM REPLACABLE
HRRZ 3,1
HLLM 1,0(3)
HLRZ 3,1
HRRM 1,0(3)
PION
POP P,3
SETZM CST3(2)
ATP1: AOS 1,FKWSP(7) ;INCREASE OWNERSHIP COUNT
MOVEI 1,0(1)
PUSH P,1
LOAD 1,FKWSS ;GET CURRENT RESERVE
CAML 1,0(P) ;LESS THAN CURRENT SIZE?
JRST ATP1A ;NO, OK
SUB 1,0(P) ;YES, CALCULATE DIFFERENCE
MOVN 1,1
ADDM 1,FKNR(7) ;INCREASE RESERVE
ADDM 1,SUMNR
LOAD 1,FKLOC
CAIL 1,NBP ;FORK IN BALSET?
BUG(CHK,FRKBAL,<AGESET-FORK NOT IN BALSET>)
ATP1A: SUB P,BHC+1 ;FLUSH GARBAGE
HLRZ 1,FKNR(7) ;GET UPDATED AGE
STOR 1,CSTAGE,(2) ;SET NEW AGE
STOR 7,CSTOFK,(2) ;SET OWNERSHIP
SETZRO PUFLD,CST0(2) ;CLEAR PUB FIELD
MOVX T1,DSKSWB ;CLEAR MISC FLAGS
ANDCAM T1,CST3(T2)
JRST AGES2
;ILLEGAL REFERENCE TRAPS
ILRD:: MOVEI T1,ILLX01 ;SET ERROR CODE
MOVEM T1,LSTERR
ILRD1: MOVX 1,.ICIRD ;MR TRAP CHANNEL
ILRF: MOVE 2,TRAPSW ;SET UP FOR USER IN CASE
MOVEM 2,UTRSW ; HE WANTS TRAP STATUS
DMOVE 2,-1(P) ;GET FLAGS
AOS 2 ;INCREMENT TO NEXT INSTR
TLNE 3,(UMODF) ;USER OR KERNEL
JRST ILRFU ;USER MODE TRAP
HLLZ 4,0(2) ;GET INSTRUCTION AFTER TRAP
CAMN 4,[ERJMP] ;WANT JUMP SIMULATION?
JRST ILRF1 ;YES - EASY CASE
CAME 4,[ERCAL] ;PUSHJ?
JRST ILRFX ;NO - POST INTERUPT IN 1
MOVE 4,BHC+1 ;SIMULATE PUSHJ
ADDB 4,TRAPAP ;UPDATE PDL PNTR
TLNN 4,-1 ;CHECK OVERFLOW
BUG (HLT,ILRFPD,<PDL-OV IN ILLEGAL PAGE REFERENCE>)
MOVEM 2,0(4) ;SAVE RETURN PC ON STACK
AOS 0(4) ;ADJUST AFTER ERCAL
ILRF1: MOVE 4,0(2) ;GET ADDRS TO XFER TO
HRRM 4,-1(P) ;ALTER RETURN ADDRESS (CAN'T CROSS SEC BOUND HERE!)
JRST PGUNTP ;EXIT TRAP
ILRFU: PUSH P,1 ;SAVE INTERUPT CHL CODE
MOVE T1,-1(P) ;GET PC FLAGS.
CALL ITRSIM ;CHECK FOR ERJMP/ERCAL (PC IN 2)
JRST [ POP P,1 ;NONE - POST INTERUPT
JRST ILRFX]
SUB P,BHC+1 ;PRUNE PDL
HRRM 3,-1(P) ;ALTER RETURN ADDRESS (CAN'T CROSS SECTION BOUND HERE!)
JRST PGUNTP ;EXIT TRAP
ILRFX: CALL PSIRQ0 ;REQUEST INTERRUPT, THIS FORK
CHKINT ;GET IT SEEN
MOVE 2,0(P) ;FLAGS
TLNN 2,(UMODF) ;USER?
SKIPGE INTDF ;OR INTERRUPTABLE?
JRST PGUNTP ;YES
AOS -1(P) ;NO, SKIP OVER INSTRUCTION CAUSING TRAP
JRST PGUNTP
ILWR:: MOVE 1,TRAPSW
JXN T1,TWUSR,ILWR1 ;JUMP IF NOT MONITOR REFERENCE
XMOVEI 1,0(1)
TLNE 1,-1 ;EXTENDED ADDRESS?
JRST ILWR1 ;YES -- DIRECTORY
CAIGE 1,<PPRMPG>B26 ;TO RESIDENT MON?
JRST ILWR2 ;YES
CAIL 1,SWPMA ;TO SWAPPABLE MON?
CAIL 1,NRPLBG
JRST ILWR1 ;NO
ILWR2: BUG(HLT,ILWRT2,<ATTEMPTED WRITE REF TO PROTECTED MONITOR>)
ILWR1: MOVEI T1,ILLX02 ;SET ERROR CODE
MOVEM T1,LSTERR
MOVX 1,.ICIWR ;MW INTERRUPT CHANNEL
JRST ILRF
;PAGE NOT IN EXISTANCE TRAPS
NPG:: MOVE 1,TRAPSW
HLLZ 2,1 ;CHECK FOR SECTION
TXZ 2,EXFLBT ;ZERO FLAGS JUNK
JXN T1,TWUSR,NPG1 ;ALWAYS HONOR USER REQUEST
JUMPE T2,[HRRZ 1,1 ;IF MONITOR SECTION 0
CAIL 1,PSSPSA
CAIL 1,PSSPEA
JRST NPG1 ;YES
JRST MILRF1] ;MONITOR MALFUNCTION
CAMLE 2,[MAXSEC,,0] ;CHECK FOR ILLEGAL SECTION
JRST MILRF1 ;YES -- ERROR
NPG1: MOVE T1,TRPID ;GET PAGE IDENT
HLRZ 2,1 ;GET PT NUMBER
CAIL 2,NOFN ;OFN OR PT?
JRST [ MOVE T3,DRMFRE ;PT, SEE IF ENOUGH DRUM SPACE
CAML T3,DRMLV0 ;ABOVE MINIMUM?
JRST .+1 ;YES. ALLOW CREATE THEN
MOVE T3,TRAPFL ;NO. GET FLAGS OF TRAP
TXNE T3,UMODF ;MONITOR PC?
JRST NIC6E ;NO, BOMB OUT
MOVE T3,INTDF ;YES. SEE IF NOW NOINT
SOJLE T3,NIC6E ;NOT. ERROR THEN
JRST .+1] ;IT IS. ALLOW CREATE
CALL SETSPG ;MAP IT
SKIPE CSWPGA(1) ;BE SURE PT SLOT NOW EMPTY
JRST NPGBAD ;IT'S NOT, PROBABLY SPURIOUS TRAP
MOVE 2,IMMPTR
TXO 2,UAAB
MOVEM 2,CSWPGA(1) ;SETUP NULL POINTER
CALL RELSPG ;RELEASE MAP
MOVE 1,PSICHM
MOVE 2,TRAPSW
JXE T2,TWUSR,NIC ;JUMP IF NOT USER REFERENCE
TXNN 1,1B<.ICNXP> ;USER MAP AND NON-X PAGE CHANNEL ON?
JRST NIC ;NO
MOVEI T1,ILLX04 ;SET ERROR CODE
MOVEM T1,LSTERR
MOVX 1,.ICNXP ;YES, REQUEST INTERRUPT
CALL PSIRQ0
CHKINT
MOVE 1,TRAPSW
MOVEM 1,UTRSW
JRST NIC
MILRF1: BUG(HLT,ILMADR,<ILLEGAL ADDRESS REFERENCE IN MONITOR>)
NPGBAD: BUG(HLT,ILPPT3,<BAD POINTER IN PAGE TABLE>)
;COPY-ON-WRITE TRAP
WCPY:: PUSH P,TRPID ;SAVE ORIGIANL IDENT
MOVX T4,TWWRT
ANDCAM T4,TRAPSW ;CLEAR WRITE REF
CALL GETTPD ;SEE IF PAGE READABLE
CAIE T1,PGUNTP ;PAGE READY FOR COPYING?
JRST [ POP P,0(P) ;CLEAN UP STACK
JRST 0(T1)] ;AND GO HANDLE OTHER CAUSE
MOVE T1,TRPPTR ;GET ADDRESS OF SOURCE PAGE
MOVSI 3,(PLKV) ;NOW LOCK IT IN CORE
ADDM 3,CST1(1)
EXCH T1,0(P) ;SAVE CORE PAGE NUMBER, RESTORE IDENT
HLRZ 2,1 ;PTN
CAIG 2,NOFN
BUG(HLT,IBCPYW,<COPY-WRITE POINTER IN INDEX BLOCK>)
CALL SETSPG ;MAP THE PT
MOVX 2,PTPUB ;SELECT ACCESS BITS
AND 2,CSWPGA(1) ;GET ACCESS OF SOURCE PAGE
IOR 2,IMMPTR ;MAKE PRIVATE PTR
TXO 2,UAACB ;WITH 'COPY' ADDRESS
EXCH 2,CSWPGA(1) ;EXCH IT WITH THE WC POINTER
LOAD 3,PTRCOD,2 ;CHECK PTR TYPE
CAIN 3,IMMCOD ;PRIVATE?
JRST WCPY4 ;NO, USER PROBABLY CONFUSED
MOVEM 2,PSBM0+CPYPG ;PUT THE ORIG POINTER IN MON MAP
CALL RELSPG
SKIP CPYPGA ;REF SOURCE PAGE TO ENSURE ACCESS
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,PSBM0-PSBPGA+CPYPG
HRL 1,FKPGS(7)
CALL MRPT ;GET IDENT OF SHARE PAGE BEING RELEASED
SETZ 1, ;INDIRECT TO FORK
PUSH P,1
MOVEI 1,PSBM0-PSBPGA+CPYPG
HRL 1,FKPGS(7)
CALL RELMPG ;RELEASE THE ORIG PAGE FROM MON MAP
CALL RELCPT ;CLEANUP FROM RELMPG
OKSKED
POP P,1
JUMPE 1,WCPY3 ;IGNORE INDIRECT TO FORK PTR
CALL JFNDCR ;DECREMENT MAP COUNT FOR JFN
WCPY3: NOSKED
JRST NIC ;UPDATE STATS AND CONTINUE
WCPY4: TLZ 2,(PTCPY) ;MAKE IT LOOK LIKE WE COPIED IT
TLO 2,(PTWR)
MOVEM 2,CSWPGA(1)
CALL RELSPG
POP P,1
MOVSI 3,(-PLKV)
ADDM 3,CST1(1) ;UNLOCK THE SOURCE PAGE
JRST NIC
;NOT IN CORE TRAP
NIC::
NIC2: CALL GETTPD ;UPDATE TRAP INFO
CAIE T1,NIC ;NOT IN CORE?
JRST 0(T1) ;NO, HANDLE OTHER CAUSE
MOVE T1,TRPID ;GET IDENT
MOVE T2,TRPPTR ;GET ADDRESS
NIC6: TLNN 2,(DSKAB+DRMAB) ;UNASSIGNED ADR?
JRST NIC6A ;YES
NIC6B: CALL CHKRPQ ;CHECK FOR ENOUGH PAGES FREE
JRST NIC2 ;WASN'T, HAD TO RESKED
NIC8: CALL SWPINW ;SWAP IN THE PAGE
JRST NIC2
;HERE IF PAGE HAS UNASSIGNED ADDRESS
NIC6A: HLRZ 2,1 ;GET PT
SKIPN 2 ;FROM SPT?
JRST [ CAMN 1,BTBBAS ;IS THIS THE BIT TABLE?
BUG (HLT,BADBTB,<NIC- ILLEGAL REFERENCE TO BIT TABLE>)
HLRZ 2,SPTH(1) ;NO. GET PT
JRST .+1] ;AND PROCEED
CAIE 2,0 ;OFN OR PT?
CAIL 2,NOFN
JRST NIC6B ;PT, DON'T ASSIGN ADDRESS
PUSH P,1 ;SAVE ORIGINAL IDENT
MOVX 1,TWWRT ;GET WRITE BIT
TDNE 1,TRAPSW ;ORIGINAL REQUEST WAS WRITE?
JRST NIC62 ;YES, ACCESS ALREADY CHECKED
IORM 1,TRAPSW ;MUST SEE IF WRITE ACCESS POSSIBLE
CALL GETTPD ;RECOMPUTE AS IF WRITE ACCESS
MOVX 2,TWWRT ;GET WRITE BIT AGAIN
ANDCAM 2,TRAPSW ;RESTORE
CAIE T1,ILWR ;WRITE PROBLEM?
CAIN T1,WCPY
JRST [ POP P,1 ;CLEAN UP STACK
JRST ILRD] ;AND GIVE ERROR
NIC62: HLRZ 2,0(P) ;GET PTN
JUMPE 2,NIC64 ;JUMP IF NONE
LOAD 1,STGADR,SPT(2) ;GET CORE ADR
MOVX 2,PLKV ;LOCK IT IN CORE IN CASE RESKEDS BELOW
ADDM 2,CST1(1)
NIC64: HLRZ 1,0(P) ;GET OFN OF IDENT
MOVE 2,0(P) ;GET IDENT
SKIPN 1 ;HAVE ONE?
HLRZ 1,SPTH(2) ;NO, GET IT FROM SPTH
PUSH P,1 ;SAVE OFN
CALL QCHK ;CHECK DISK, ETC...
JRST NIC6F ;CAN'T CREATE PAGE
MOVE 1,0(P) ;GET OFN BACK
MOVX 2,SPTLKB ;LOCK OFN
TDNE 2,SPTH(1)
JRST [ HRLZ 1,1 ;ALREADY LOCKED. BLOCK UNTIL UNLOCKED
CALL WTOFNL ;OKSKED AND DISMISS
NOSKED
POP P,1 ;CLEAN OFF OFN
POP P,1 ;RECOVER IDENT
CALL NIC6UC ;UNLOCK PT PAGE IF ANY
JRST NIC2] ;START OVER
TXO 2,OFNWRB ;NOTE OFN CHANGED
IORM 2,SPTH(1) ;SET LOCK AND OFN MODIFIED
MOVE T1,-1(P) ;GET IDENT
TLNN T1,-1 ;IN SPT?
MOVE T1,SPTH(T1) ;YES, GET REAL IDENT
CALL FNDLDA ;FIND LAST DISK ADDRESS ASSIGNED IN THIS XB
MOVE T2,0(P) ;GET OFN
LOAD T2,STRX,(T2) ;PASS STRUCTURE NUMBER TO DSKASN
CALL DSKASN ;ASSIGN DISK ADDRESS FOR FILE PAGE
JRST NIC6D ;RAN OUT
; ..
;ASSIGNING ADDRESS FOR NEW FILE PAGE...
POP P,T2 ;GET OFN
LOAD T2,ALOCX,(T2) ;INDEX TO QUOTA TABLE
DECR PGLFT,(T2) ;ONE LESS PAGE LEFT
TLO 1,(DSKNB) ;INDICATE PAGE NEVER PREVIOUSLY WRITTEN
MOVE 2,1
POP P,1
TLNN 1,-1 ;IN SPT?
JRST [ STOR 2,STGADR,SPT(1) ;YES, STORE NEW ADDRESS
JRST NIC63] ;NOW GO SWAP IN PAGE
PUSH P,6 ;SAVE PERMANENT REGISTER
HLRZ 6,1
CALL SETSP6 ;MAP XB
STOR 2,STGADR,CSWPGA(1) ;STORE NEW ADDRESS IN XB
MOVSI 2,(-PLKV)
ADDM 2,CST1(6) ;UNDO LOCK ABOVE
CALL RELSPG
POP P,6 ;RESTORE PERMANENT REGISTER
NIC63: CALL NIC6UL ;UNLOCK OFN
JRST NIC2 ;START OVER, PAGE NOW ASSIGNED
;UNLOCK OFN AFTER ASSIGNMENT
NIC6UL: HLRZ 2,1 ;GET OFN
SKIPN 2 ;HAVE ONE?
HLRZ 2,SPTH(1) ;NO, GET IT FROM SPTH
MOVX 3,SPTLKB
ANDCAM 3,SPTH(2) ;UNLOCK
RET
;HERE WHEN NO ROOM CONDITION -- GENERATE INTERRUPT
NIC6D: POP P,1 ;RESTORE OFN
MOVX 2,SPTLKB ;UNDO SPT LOCK
ANDCAM 2,SPTH(1) ;...
JRST NIC6G ;JOIN COMMON ERROR STUFF
NIC6F: SUB P,BHC+1 ;REMOVE OFN
NIC6G: POP P,1 ;GET ORIGINAL IDENT
TLNN 1,-1 ;OFN?
JRST NIC6Y ;NO - JUST EXIT
PUSH P,6 ;SAVE PERM REG
HLRZ 6,1 ;OFN TO REG 6
CALL SETSP6 ;MAP THE PT
SETZM CSWPGA(1) ;CLEAR POINTER (NO DSK ADDRS YET)
MOVX 2,-PLKV ;UNDO PT LOCK
ADDM 2,CST1(6) ;...
CALL RELSPG ;RELEASE SPECIAL PAGE
POP P,6 ;RESTORE 6
NIC6Y: MOVX 1,.ICQTA ;QUOTA EXCEDED CHL
NIC6X: MOVEI 2,IOX11 ;'NO ROOM'
MOVEM 2,LSTERR
JRST ILRF ;GENERATE ILLEG REF INT
NIC6E: MOVX 1,.ICMSE ;MACH SIZE EXCEEDED INT CHANNEL
MOVEI 2,IOX12 ;DISC COMPLETELY FULL
MOVEM 2,LSTERR
JRST ILRF ;GENERATE INT
;UNLOCK PT PAGE IF ANY
NIC6UC: HLRZ 2,1 ;GET PTN
JUMPE 2,R ;RETURN IMMED IF NONE
LOAD 2,STGADR,SPT(2) ;GET ADR OF PT
MOVX 3,-PLKV
ADDM 3,CST1(2) ;UNLOCK IT
RET
;FIND LAST DISK ADDRESS ASSIGNED IN THIS XB SO THAT DSKASN CAN ASSIGN
;THE NEXT PAGE AT AN OPTIMAL LOCATION
; T1/ IDENT
FNDLDA: SAVEAC <Q2>
HLRZ Q2,T1 ;SETUP OFN
JN NCORTM,SPT(Q2),FNDLDX ;IF NOT IN CORE, USE XBADDR
CALL SETSP6 ;MAP IT
FNDLD1: HRRZ T2,T1 ;GET PAGE NUMBER
SKIPN T2,CSWPGA(T2) ;ANYTHING IN THIS SLOT?
JRST FNDLD2 ;NO
LOAD T3,PTRCOD,T2 ;YES, CHECK PTR TYPE
CAIN T3,IMMCOD ;IMMEDIATE AND DISK ADDRESS?
TXNN T2,DSKAB
JRST FNDLD2 ;NO, FORGET IT
LOAD T1,STGADR,T2 ;YES, USE THIS ADDRESS
JRST FNDLD3
FNDLD2: HRRI T1,-1(T1) ;SCAN BACKWARDS THROUGH XB
TRNN T1,-PGSIZ ;RAN OFF TOP?
JRST FNDLD1 ;NO, CHECK THIS SLOT
FNDLDX: HLRZ T1,T1 ;YES, REVERT TO XB ADR ITSELF
LOAD T1,STGADR,SPTH(T1) ;GET XB DISK ADR
FNDLD3: CALL RELSPG ;RELEASE XB MAPPING
RET
;ROUTINE TO CHECK ON DISK QUOTA AND DISK AVAILABILITY
;C(T1) := OFN
;
;RETURN +1 DISK FULL / QUOTA EXCEEDED
;RETURN +2 OK
QCHK: SKIPN USRSPC ;USER SPACE CHECKING?
JRST QCHK1 ;NO - CHECK SYSTEM SPACE
LOAD T2,ALOCX,(T1) ;GET INDEX INTO QUOTA TABLES
SKIPN T2 ;GOOD THING TO CHECK
BUG (HLT,NULQTA,QCHK - NO QUOTA INFO SETUP)
OPSTR <SKIPG>,PGLFT,(T2)
JRST QCHK2 ;OVER QUOTA - CHECK PRIVS
QCHK1:
REPEAT 0,<
LOAD T1,STRX,(T1) ;GET STRUCTURE NUMBER
CAIE T1,PSNUM ;IS THIS ON PS?
RETSKP ;NO. DON'T CHECK SPACE THEN
CALL GSTRPG ;GET ALLOCATION OF THIS STRUCTURE IN T2
CAMLE T2,SYSSPC ;ABOVE MINIMUM?
> ;END OF REPEAT 0
RETSKP ;OK - GOOD RETURN
QCHK2: MOVE T2,CAPENB ;SEE IF USER IS WHEEL/OPR
TXNN T2,SC%WHL!SC%OPR
RET ;NO - ERROR
RETSKP ;YES - OK TO CREATE PAGE
;ACCOUNT FOR ONE PAGE TRAP
PGTACC:
REPEAT 0,<
MOVE 1,IFAV ;UPDATE INTERFAULT AV
FMPR 1,IFAVC0 ;AV' = (C*AV + TIME)/(C+1)
MOVE T2,FKRT ;GET CURRENT FORK RUNTIME
SUBM T2,IFTIM ;COMPUTE INTERVAL SINCE LAST FAULT
EXCH T2,IFTIM
FLTR 2,2 ;FLOAT IT
FADR 1,2
FDVR 1,IFAVC1
MOVEM 1,IFAV
> ;END REPEAT 0
MOVE 2,JOBNO
HRRZ 2,JOBNAM(2) ;GET SUBSYSTEM INDEX
AOS SPFLTS(2) ;ACCOUNT PAGE FAULTS FOR SUBSYSTEM
LOAD 1,FKXAGE ;GET AGE CLOCK AT LAST XGC
LOAD 2,FKAGE ;GET CURRENT AGE
SUBI 2,0(1) ;NOW-THEN
CAIGE 2,0 ;WRAPAROUND?
ADDI 2,1000-100 ;YES
SKIPG TRAPC ;OUTER LEVEL?
CAMGE 2,GCRATE ;TIME FOR ANOTHER XGC?
JRST NICMG1 ;NO
NICMG:
REPEAT 0,<
MOVE 1,IFAV ;CURRENT INTERFAULT AVERAGE
FDVR 1,IFAMEA ;COMPUTE RATIO OF ACTUAL/DESIRED
MOVE 2,CAPT ;CURRENT WINDOW SIZE
MOVE 3,2
ASH 3,-4 ;ADJUST UP OR DOWN BY 1/16
CAMGE 1,[0.5] ;IFAV NOW TOO LOW?
ADD 2,3 ;YES, MAKE CAPT LARGER
CAML 1,[1.5] ;IFAV NOW TOO HIGH?
SUB 2,3 ;YES, MAKE CAPT SMALLER
CAMLE 2,CAPTMX ;SEE IF CAPT WITHIN LIMITS
MOVE 2,CAPTMX
CAMGE 2,CAPTMN
MOVE 2,CAPTMN
MOVEM 2,CAPT
MOVE 1,CAPT ;USE CURRENT CAPT
>
REPEAT 1,<
MOVE T1,ICAPT ;USE FIXED WINDOW SIZE
MOVEM T1,CAPT
>
CALL XGC
LOAD T1,FKCSIZ ;SEE IF WS ESTIMATE SHOULD BE REDUCED
ADDI T1,4 ;CURRENT SIZE PLUS SMALL INCREMENT
LOAD T2,FKWSS ;CURRENT ESTIMATE
CAML T1,T2 ;SIZE LESS THAN ESTIMATE?
JRST NICMG1 ;NO, NO CHANGE
SUB T1,T2 ;YES, COMPUTE (NEG) DIFFERENCE
ADDM T1,SUMNR ;REDUCE NR AND SUMNR ACCORDINGLY
ADDM T1,FKNR(FX)
NICMG1: CALL NICCKS ;CHECK FOR ALLOWABLE SIZE
MOVE 3,TRAPSW
JXN 3,TWUSR,[LOAD 3,VPGNO,3 ;USER REF, GET PAGE NUMBER, UPDATE WS BITS
CAIL 3,1000 ;IF NOT SECTION 0 MUST RETURN
RET
IDIVI 3,^D36
MOVE 4,BITS(4)
IORM 4,WSPGS(3)
JRST .+1]
RET
;AVERAGE SWAP LATENCY * 2 - CONTROLS DESIRED INTERFAULT AVERAGE
IFAMEA: 40.0 ;IDEAL IFAV
AGTICK==:^D40 ;MILLISECONDS PER TICK OF AGE REGISTER
ICAPT:: ^D3000/AGTICK ;WINDOW SIZE IN TICKS
;CAPTMX: ^D4000/AGTICK ;MAX CAPT
;CAPTMN: ^D2000/AGTICK ;MIN CAPT
GCRATE: ^D2000/AGTICK ;RECIPROCAL OF GC FREQUENCY
;DECAY CONSTANT FOR INTERFAULT AVERAGE
IFAVC0: EXP 100.0 ;LARGER C IMPLIES SLOWER IFAV CHANGE
IFAVC1: EXP 101.0 ;IFAVC0+1
;CHECK FOR SUFFICIENT PAGES ON RPLQ
CHKRPQ: MOVE 2,NSKED
CAILE 2,1 ;NOSKED PROCESS?
JRST RSKP ;YES, ALLOW PAGE
MOVE 2,NRPMX ;OTHERWISE, ALLOW PAGE IF NRPLQ ABOVE
CAMG 2,NRPLQ
JRST RSKP ;ALLOW PAGE
MOVEI 1,TRP0CT
HRLI 1,0(2) ;MINIMUM NRPLQ
RDISMS ;OKSKED AND DISMISS
NOSKED
RET ;RETURN NOSKIP BECAUSE RESKED DONE
TRP0CT: MOVE 2,NRPLQ
CAIGE 2,0(1) ;ABOVE STATED MIN?
CAML 2,NRPMIN ;OR ABOVE NORMAL MIN?
JRST 1(4) ;YES, UNBLOCK
AOS CGFLG ;NO, SAY PAGES NEEDED
JRST 0(4)
;CHECK OVERALL SIZE FOR PHYSICAL CORE LIMITS
NICCKS: LOAD 1,FKWSS
ADD T1,BALSHC
CAMGE 1,MAXNR ;RESERVE NOW TOO BIG?
CAML 1,FNPMAX
JRST NIC3C ;YES
LOAD T3,FKCSIZ ;GET CURRENT SIZE
CAMLE 1,3 ;RESERVE .G. CURRENT SIZE?
RET ;YES, OK.
NIC3C: MOVE 1,CAPT ;INIT WINDOW SIZE FOR POSSIBLE XGC
ASH 1,-3 ;IS 1/8 REG CAPT
PUSH P,1
NIC3B: LOAD T1,FKCSIZ ;ASSUME NR IS SIZE+1
ADDI T1,1
ADD T1,BALSHC
CAMGE 1,MAXNR ;EXCEEDS SYSTEM LIMIT?
CAML 1,FNPMAX ;EXCEEDS LEGAL LIMIT?
JRST NIC3 ;YES
CAMGE 1,SNPMAX ;DEFINITELY NOT TOO BIG?
JRST NIC3E ;YES
MOVE 2,IRJAV
CAIGE 2,2 ;LDAV .GE. 2?
JRST NIC3E ;NO, LET FORK BE LARGER
NIC3:
SKIPLE TRAPC ;DOING AN OUTER LEVEL FAULT?
JRST NIC3E ;NO. INHIBIT XGC THEN
; CALL GCPG ;TRY COLLECTING JUST 1 PAGE
; JRST .+2 ;FAILED, MAYBE NO USER MAP PAGES
; JRST NIC3B
MOVE 1,0(P) ;GET WINDOW SIZE
CALL XGC ;DO GC
SKIPN 1,0(P) ;WINDOW SIZE NOW 0?
JRST NIC3E ;YES, GIVE UP ON GC
ASH 1,-1 ;REDUCE WINDOW SIZE FOR NEXT GC
MOVEM 1,0(P)
JRST NIC3B
NIC3E: LOAD T1,FKCSIZ ;GET CURRENT SIZE
ADDI T1,1 ;RESET NR TO SIZE + 1
HRRZ 3,FKNR(FX)
SUBM 1,3
ADDM 3,FKNR(FX)
ADDB 3,SUMNR ;UPDATE BALSET TOTAL
CAMG 3,MAXNR ;BALSET NOW TOO FULL?
JRST PA1 ;NO, ALL OK.
MOVEI 1,NICTST ;YES, SETUP TEST FOR BALSET SIZE
RDISMS ;OKSKED AND DISMISS
NOSKED
JRST PA1 ;SHOULD BE OK NOW
NICTST: MOVE 1,SUMNR ;SCHED TEST FOR SUMNR .LE. MAXNR
MOVE 2,NBPROC
CAMLE 1,MAXNR
CAIG 2,1 ;SUCCESS IF ONLY 1 FORK IN BALSET
JRST 1(4)
JRST 0(4)
REPEAT 0,< ;**NOT PRESENTLY USED**
;REMOVE 1 PAGE FROM PROCESS. SELECT FIRST PAGE OLDER THAN CAPT,
;OR OLDEST PAGE
GCPG: MOVSI 6,-NWSPGS ;SET TO SCAN WS BIT TABLE
PUSH P,[0] ;WILL REMEMBER OLDEST PAGE FOUND
LOAD 3,FKAGE ;CURRENT AGE
PUSH P,3
SUB 3,CAPT ;CUTOFF AGE
PUSH P,3
MOVE 3,-1(P) ;USE CURRENT AGE AS INIT MIN AGE
GCPG2: SKIPE 4,WSPGS(6)
GCPG3: JFFO 4,GCPG1 ;FIND PAGE IN USE
AOBJN 6,GCPG2
SUB P,BHC+2 ;DIDN'T FIND PAGE OLDER THAN CAPT
POP P,1 ;USE OLDEST PAGE SEEN
JUMPE 1,R ;DIDN'T FIND COLLECTABLE PAGE
JRST GCPG4 ;COLLECT IT
GCPG1: ANDCM 4,BITS(5)
MOVEI 1,0(6)
IMULI 1,^D36 ;COMPUTE MAP PAGE NUMBER
ADDI 1,0(5)
SKIPN 1,UPTPGA(1) ;GET MAP WORD
JRST GCPG3 ;IGNORE EMPTY OR INDIRECT
LOAD 2,PTRCOD,1 ;GET PTR TYPE
CAIN 2,INDCOD ;INDIRECT?
JRST GCPG3 ;YES, IGNORE
CAIN 2,SHRCOD ;SHARED?
JRST [ LOAD 1,SPTX,1 ;YES, TRACE
MOVE 1,SPT(1)
JRST .+1]
TLNE 1,(NCORTM) ;IN CORE?
JRST GCPG3 ;NO
LOAD 2,CSTAGE,(1)
CAIGE 2,100 ;IN USE?
JRST GCPG3 ;NO
LOAD 5,CSTOFK,(1) ;YES, TO THIS PROCESS?
CAIE 5,0(7)
JRST GCPG3 ;NO
CAMLE 2,-1(P) ;CHECK WRAPAROUND
SUBI 2,1000-100
CAMLE 2,0(P) ;OUTSIDE CAPT WINDOW?
JRST [ MOVE 5,2 ;NO, SAVE AGE
CAMG 2,3 ;OLDEST PAGE SEEN?
CALL SWPCHK ;SWAPPABLE?
JRST GCPG3 ;NO
MOVE 3,5 ;YES, REMEMBER OLDEST AGE
MOVEM 1,-2(P) ;AND PAGE
JRST GCPG3]
CALL SWPCHK ;CAN SWAPOUT PAGE?
JRST GCPG3 ;NO
SUB P,BHC+3 ;YES, FLUSH TEMPS
GCPG4: SOS FKWSP(7) ;DEASSIGN PAGE
CALL SWPOUT ;SWAP IT
AOS 0(P) ;RETURN GOOD
RET
> ;END REPEAT 0
;RELEASE WORKING SET JSYS
.RWSET::MCENT
NOSKED
MOVE 7,FORKX
SETZ 1, ;USE 0 WINDOW SIZE
CALL XGC ;COLLECT ALL PAGES
HRRZ 1,FKWSP(7) ;SET NEW NR TO MAX(6,SIZE)
CAIGE 1,6 ;SIZE .GE. 6?
MOVEI 1,6 ;NO, USE 6 AS NEW NR
LOAD 2,FKWSS
SUBI 1,0(2)
ADDM 1,FKNR(7)
ADDM 1,SUMNR
OKSKED
JRST MRETN
;CHECK IF PAGE IS SWAPPABLE NOW
SWPCHK: MOVE 2,CST1(1)
TLNE 2,(-PLKV)
RET ;PAGE IS LOCKED OR HAS NO SWAP ADR
MOVSI 2,(DWRBIT)
TDNN 2,CST3(1) ;BEING WRITTEN?
AOS 0(P) ;NO, OK
RET
;COLLECT OLD PAGES FOR THIS PROCESS, CALLED WITH CUTOFF DIFFERENCE IN 1
;THE PAGES ASSIGNED TO THIS PROCESS ARE ASSUMED TO HAVE AGES RANGING
;FROM M1 TO M2. M2 IS THE CURRENT AGE, LH OF FKNR. WE WISH TO
;FLUSH ALL PAGES OLDER THAN M, WHERE M1<M<M2. IF EACH PAGE >>
;HAS BEN REFERENCED ONLY ONCE, THE AGES WOULD BE EVENLY DISTRIBUTED
;BETWEEN M1 AND M2. HOWEVER, PAGES ACTIVELY BEING USED SHOULD
;HAVE AGES CLOSER TO M2. THEREFORE, WE PICK A CUTOFF AGE BY
;SUBTRACTING A SMALL NUMBER FROM M2. TO PREVENT EXCESSIVE COLLECTION
;WHERE ALL PAGES HAVE BEEN REFERENCED RECENTLY, WE SET A LIMIT
;ON THE TOTAL NUMBER OF PAGES WHICH CAN BE FLUSHED, AND STOP
;IF WE HIT THIS LIMIT. ALSO, SINCE AGES CAN WRAP AROUND THE 9-BIT
;FIELD, AGES GREATER THAN M2 ARE ASSUMED TO BE LEFT FROM THE PREVIOUS
;WRAP AROUND AND ARE ADJUSTED ACCORDINGLY.
XGC: SKIPG NSSUN ;FILESYS INITIALIZED?
RET ;NO, DO NOTHING
STKVAR <PBIT,MAXP,XAGE,CAGE,SAVQ2>
MOVEM Q2,SAVQ2 ;SAVE PERMANENT REGISTER
HRRZ 4,FKCNO(FX)
MOVE T4,BITS(T4) ;GET PROCESS USE BIT FOR THIS PROCESS
MOVEM T4,PBIT
MOVE Q2,MONCOR ;FIRST SWAPPING PAGE
HRRZ 4,FKWSP(FX) ;NUMBER PAGES NOW IN CORE
; ASH 4,-1 ;COMPUTE 1/2 CURRENT SIZE
MOVEM T4,MAXP ;MAX NUMBER OF PAGES TO COLLECT
LOAD 3,FKAGE ;NOTE TIME OF LAST XGC
STOR 3,FKXAGE
MOVEM T3,XAGE ;SAVE IT
SUBI 3,0(1) ;CUTOFF AGE, 'OLD'=NOW-DIFFERENCE
MOVEM T3,CAGE ;SAVE CUTOFF AGE
XGC2: LOAD 2,CSTOFK,(Q2) ;GET PROCESS ASSIGNMENT
CAIE 2,0(FX) ;ASSIGNED TO THIS PROCESS?
JRST XGC1 ;NO
LOAD 1,CSTAGE,(Q2) ;GET AGE FIELD
CAIGE 1,PSASN ;PAGE IN USE?
JRST XGC1 ;NO
MOVE 2,PBIT ;PROCESS USE BIT
ANDCA 2,CST0(Q2) ;LOOK AT OTHER PROCESS USE BITS
TXNE 2,PUFLD ;IF ANY ON, MEANS REFERENCES BY OTHER
MOVE 1,XAGE ;PROCESSE, AGE INVALID SO USE CURRENT
CAMLE 1,XAGE ;IF .G. NOW, MUST NOT HAVE WRAPPED
SUBI 1,1000-100 ;SO WRAP IT
CAMLE 1,CAGE ;.G. OLD?
JRST XGC1 ;YES, SAVE IT
MOVE 2,CST1(Q2)
TLNE 2,(-PLKV) ;DON'T SWAP PAGE IF LOCKED
JRST XGC1
MOVSI 2,(DWRBIT)
TDNE 2,CST3(Q2) ;DON'T SWAP PAGE IF NOW BEING WRITTEN
JRST XGC1
HRRZ T1,Q2
CALL DASWSP ;DEASSIGN PAGE FROM THIS PROCESS
CALL SWPOUT ;SWAP IT OUT
SOSG MAXP ;COLLECTED ENOUGH PAGES?
JRST XGC3 ;YES
OKSKED ;DON'T HOG MACHINE FOR TOO LONG
NOSKED
; ..
XGC1: CAMGE Q2,NHIPG ;STOP AFTER HIGHEST KNOWN PAGE
AOJA Q2,XGC2 ;NO, LOOK AT NEXT PAGE
XGC3: CALL PGRCLD
MOVEM Q1,PBIT ;SAVE A WORK REGISTER
SETZ 3,
MOVSI Q2,-NWSPGS ;SETUP TO UPDATE WS BITS
XGC5: SKIPE 4,WSPGS(Q2)
XGC6: JFFO 4,XGC4 ;FOUND BIT FOR PAGE
AOBJN Q2,XGC5
MOVE Q1,PBIT ;RESTORE PERMANENT REGISTER
MOVE Q2,SAVQ2 ;AND THIS ONE AS WELL
RET
XGC4: ANDCM 4,BITS(Q1) ;DON'T FIND THAT BIT NEXT TIME
MOVEI 1,0(Q2) ;COMPUTE PAGE NUMBER
IMULI 1,^D36
ADDI 1,0(Q1)
SKIPN 1,UPTPGA(1) ;PAGE DELETED?
JRST XGC7 ;YES, FORGET IT
LOAD 2,PTRCOD,1 ;GET PTR TYPE
CAIN 2,INDCOD ;INDIRECT?
JRST XGC7 ;YES, IGNORE
CAIN 2,SHRCOD ;SHARED?
JRST [ LOAD 1,SPTX,1
MOVE 1,SPT(1)
JRST .+1]
TLNE 1,(NCORTM) ;PAGE NOW IN CORE?
JRST XGC7 ;NO, FLUSH IT
HRRZ 2,1
LOAD 2,CSTAGE,(2) ;GET PAGE STATE CODE
CAIL 2,PSASN ;STILL ASSIGNED?
AOJA 3,XGC6 ;YES, COUNT IT AND LEAVE IT
CAIE 2,PSRDN ;READ COMPLETED?
JRST XGC7 ;NO
CALL AGESN
AOJA 3,XGC6 ;COUNT PAGE AND KEEP IT
XGC7: MOVE 1,BITS(Q1)
ANDCAM 1,WSPGS(Q2) ;CLEAR BIT FOR PAGE NO LONGER IN WS
JRST XGC6
;ROUTINE CALLED BY BIT TABLE LOGIC TO UNLOCK XB FOR BIT TABLE
; 1/ CORE PAGE NUMBER OF XB
UNLBTB::MOVSI T2,(-PLKV) ;GET ONE UNIT OF LOCK COUNT
ADDM T2,CST1(T1) ;UNLOCK IT
CALLRET MONCLA ;AND CLEAR PAGER
;LOCAL ROUTINE TO DO A SWAP IN AND LOCK. CALLED WITH SPTN
;IN 1. MUST BE CALLED FROM PROCESS CONTEXT.
SWPIN1::NOSKED ;GO NOSKED
PUSH P,FX ;SAVE FX FOR CALLER
MOVE FX,FORKX ;SAY THIS FORK IS THE TARGET
CALL SWPIN0 ;GO DO THE SWAP IN AND LOCK
POP P,FX ;RESTORE FX FOR CALLER
OKSKED ;AND ALLOW SCHEDULING AGAIN
RET ;AND DONE
;SWAP IN PAGE TABLE OR PSB
;CALLED FROM SCHED OR FROM NOSKED PROCESS
SWPIN0::TLNE 1,-1 ;SPTN?
JRST SWP01 ;NO
MOVE 3,SPT(1) ;YES, GET CURRENT ADDRESS
TLNE 3,(NCORTM) ;OUT OF CORE?
JRST SWP01 ;YES
HRRZ 2,3
LOAD 2,CSTAGE,(2) ;GET PAGE STATE CODE
CAIE T2,PSRIP ;READ IN PROGRESS?
AOS PSKED ;NO, SIGNAL THAT PAGE AVAILABLE
CAIE 2,PSRDN ;BEING READ OR COMPLETED?
CAIN 2,PSRIP
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)
HRRZS 3
ADDM 2,CST1(3) ;LOCK PAGE
RET
;SWAPIN AND WAIT AND STAY NOSKED
SWPINP: NOSKED
CALL SWPINW
OKSKED
RET
;WAIT FOR PAGE AND ACCOUNT
; 1/ SCHED TEST
; CALL PGIWT
; RETURN +1 ALWAYS AFTER SCHED TEST SATISFIED.
PGIWT:: HLRZ 2,1 ;GET PAGE NUMBER
LOAD 2,CSTAGE,(2) ;GET PAGE STATE CODE
CAIE 2,PSRIP ;READ IN PROGRESS?
RET ;NO, NO NEED TO WAIT
RDISMS
NOSKED
RET
;SWAP IN AND WAIT FOR COMPLETION
;SWPINW - SWAP INTO PAGE FROM RPLQ
;SWPINQ - SWAP INTO PAGE FROM SPMQ, PAGE # IN 3
SWPINW: SETO 3,
SWPINQ: PUSH P,FX
MOVE FX,FORKX
AOS USWPCT ;COUNT SWAPS
TLNE 1,-1 ;PT?
JRST SWPIW2 ;YES
CALL SWPIQ1 ;SWAPIN AND WAIT FOR COMPLETION
SWPIW1: CALL PGIWT
HLRZ 1,1 ;RESTORE PAGE NO TO R.H.
POP P,FX
RET
SWPIW2: PUSH P,3 ;SAVE PAGE #
PUSH P,1 ;SAVE ORIG REQUEST
HLRZ 1,1 ;GET PT
MOVE 3,SPT(1)
TLNE 3,(NCORTM) ;CORE?
JRST SWPIW3 ;NO
MOVEI 1,0(3)
CALL AGESN ;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
MOVE 3,-1(P) ;GET PAGE #
CALL SWPIQ1 ;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
POP P,3 ;RESTORE PHY PAGE #
JRST SWPIW1
SWPIW3: NOSKED
CALL SWPIN ;SWAP IN THE PT
OKSKED
HLRZ 2,1
MOVSI 3,(PLKV)
ADDM 3,CST1(2) ;LOCK IT
PDISMS ;WAIT TO FINISH
HLRZ 1,1
CALL AGESN
JRST SWPIW4 ;NOW GO GET THE PAGE
;SWAP IN PAGE
;AC1/ OFN.PN OR 0.SPTN
;RETURNS AC1/ CORE PAGE NO IN LH
;SWPIN - SWAP INTO PAGE FROM RPLQ
;SWPIQ1 - SWAP INTO PAGE FROM SPMQ, PAGE # IN 3
SWPIQ1: JUMPL 3,SWPIN ;IF .LT. 0, THEN CHOSE FROM RPLQ
PUSH P,1
PUSH P,2
PUSH P,3
MOVE 1,3
CALL OFFSPQ ;REMOVE FROM SPMQ
POP P,3
POP P,2
POP P,1
CALLRET SWPIQ2 ;START THE SWAP
SWPIQ2: PUSH P,5
PUSH P,6
JRST SWPIQ3 ;REMOVE PAGE AND SWAP
SWPIN: MOVE 3,NRPLQ ;NUMBER OF REPLACABLE PAGES
JUMPE 3,SWPQT ;GO WAIT IF NONE
HRRZ 3,RPLQ ;YES, REMOVE FROM QUEUE
SUBI 3,CST3
SOS NRPLQ
PUSH P,5
PUSH P,6
PIOFF
MOVE 4,CST3(3)
HRRZ 6,4
HLLM 4,0(6)
HLRZ 6,4
HRRM 4,0(6)
PION
SWPIQ3: SETZRO CSTAGE,(3) ;CLEAR AGE CODE
SETZRO <PUFLD,CORMB>,CST0(3) ;CLEAR PUR, MODIFIED BIT
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,(NCORTM)
BUG(HLT,SPTPIC,<SWPIN - SPT PAGE ALREADY IN CORE>)
STOR 3,STGADR,SPT(1) ;STORE NEW (CORE) ADDRESS
SWPI4: ANDX 4,STGADM ;EXTRACT ADDRESS
MOVEM 4,CST1(3) ;STORE BACKUP ADDRESS
MOVEM 1,CST2(3) ;STORE LOCATION OF OWNING PT
TLNE 4,(DSKAB+DRMAB) ;BACKUP ADDRESS ASSIGNED?
JRST SWPI5 ;YES, GO READ IN PAGE
MOVEI 1,0(3)
CALL SETSP0 ;MAP PAGE INTO CSWPG
MOVX T1,PSASM ;SET LEGAL AGE FOR LOCAL REF
IORM T1,CST0(T3)
SETZM CSWPGA
MOVE 1,[CSWPGA,,CSWPGA+1]
TXNE 4,UAACB-UAAB ;'COPY-REQUEST' PTR?
MOVE 1,[XWD CPYPGA,CSWPGA] ;YES, COPY FROM CPYPG
BLT 1,CSWPGA+777
CALL RELSPG
MOVX 1,PSRDN ;SET TO READ COMPLETED
STOR 1,CSTAGE,(3) ; ...
MOVX 1,CORMB ;AND SET MODIFIED BIT
IORM 1,CST0(3) ; ...
STOR FX,CFXRD,(3) ;NOTE FORK INDEX
MOVSI 1,0(3) ;RETURN PAGE NUMBER
HRRI 1,SWPRT ;RETURN APPROPRIATE SCHED TEST
SWPIX: POP P,6
POP P,5
RET
SWPI3: HLRZ 6,1 ;GET OWNING PT OFN
CALL SETSP6 ;MAP PT
MOVSI 4,(PLKV)
ADDM 4,CST1(6) ;INCREMENT LOCK COUNT
HRRZ 6,1
MOVE 4,CSWPGA(6)
TLNN 4,(NCORTM)
BUG(HLT,PTAIC,<SWPIN - PT PAGE ALREADY IN CORE>)
STOR 3,STGADR,CSWPGA(6) ;STORE NEW (CORE) ADDRESS
CALL RELSPG
JRST SWPI4
SWPQT: PUSH P,1 ;SAVE REQUESTED PAGE IDENT
MOVEI 1,SWPWTT ;RESCHEDULE UNTIL NRPLQ NON-0
PDISMS
POP P,1
JRST SWPIN
SWPWTT: SKIPLE NRPLQ
JRST 1(4)
AOS CGFLG ;REQUEST CORE
JRST 0(4)
SWPI5: MOVEI 1,0(3)
MOVX 2,PSRIP
STOR 2,CSTAGE,(1) ;SET STATE TO READ IN PROGRESS
STOR FX,CFXRD,(1) ;REMEMBER INITIATING FORK
TLNE 4,(DSKAB) ;DISK?
JRST SWPIK ;YES
TLNN 4,(DRMAB) ;DRUM?
BUG(HLT,ILSWPA,<SWPIN - ILLEGAL SWAP ADDRESS>)
CALL DRMIO ;YES, INITIATE READ
AOS DRMRD ;COUNT DRUM READS FOR STATISTICS
MOVSI 1,0(1)
HRRI 1,SWPRT ;RETURN APPROPRIATE SCHED TEST
JRST SWPIX
SWPIK: TLNE 4,(DSKNB) ;NEWLY ASSIGNED PAGE?
JRST [ CALL SWPZPG ;YES, ZERO IT
MOVSI 2,(DSKNB)
ANDCAM 2,CST1(1)
MOVX 2,PSRDN ;SET CODE TO READ COMPLETED
STOR 2,CSTAGE,(1)
JRST SWPIK1]
CALL DSKIO ;INITIATE DISK READ
AOS DSKRD ;COUNT DISK READS FOR STATISTICS
SWPIK1: MOVSI 1,0(1) ;RETURN APPROPRIATE SCHED TEST
HRRI 1,DSKRT
JRST SWPIX
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
STOR 5,STGADR,SPT(4) ;SPT, RESTORE BACKUP ADDRESS
RET
SWPI1: HLRZ 6,4
CALL SETSP6 ;MAP PT
MOVSI 2,(-PLKV)
ADDB 2,CST1(6) ;DECREMENT LOCK COUNT
HRRZ 6,4
STOR 5,STGADR,CSWPGA(6) ;STORE BACKUP ADDRESS
CALL RELSPG ;RELEASE TEMPORARY MAP WORD
RET
;REMOVE PAGE FROM CST
; 1/ PAGE NUMBER
; CALL RPCST
; RETURN +1 ALWAYS, POINTER TO PAGE UNDONE
RPCST: SAVEQ
MOVE 3,1
CALL DEPG ;DO THE WORK
SETZM CST2(1) ;FLUSH BACK PTR
RET
;DEASSIGN PAGE FROM CURRENT CST USAGE, SIMILAR TO RPCST BUT CAN BE
;CALLED AT INTERRUPT LEVEL.
;MUST BE CALLED PIOFF
;T1/ PHYSICAL PAGE
; CALL DASPAG
;RETURNS+1(ALWAYS):
;POINTERS BACKED UP TO NEXT LEVEL IN THE STORAGE HIERARCHY
;PRESERVES T1
DASPAG: MOVE T2,CST2(T1) ;GET OWNING PT
JUMPE T2,DASPGX ;NONE - NOTHING TO DO
SETZM CST2(T1) ;DELETE BACK POINTER
MOVE T3,CST1(T1) ;GET NEXT LEVEL ADDRESS
TLNE T2,-1 ;OWNED BY SPT?
JRST DASPG1 ;NO - MUST CLEAR PT SLOT
STOR T3,STGADR,SPT(T2) ;YES - JUST BACKUP SPT ADDRESS
DASPGX: RET
DASPG1: PUSH P,T1 ;BE TRANSPARENT FOR T1
HLRZ T1,T2 ;GET PT PHYSICAL PAGE
LOAD T1,STGADR,SPT(T1) ; ...
PUSH P,CST0(T1) ;SAVE CURRENT CST
SETOM CST0(T1) ;PREVENT AGE FAULT
PUSH P,T1 ;SAVE PHYSICAL ADDRESS
CALL MAPRCA ;MAP PAGE, RETURNS ADDRESS IN T1
ADDI T1,(T2) ;GET MAP SLOT
STOR T3,STGADR,(T1) ;STORE NEXT HIGHER LEVEL ADDRESS
POP P,T1 ;RESTORE PHYSICAL ADDRESS
POP P,CST0(T1) ;RESTORE CST
CALL UNMRCA ;RELEASE MAPPING
MOVSI T2,(-PLKV) ;DECREMENT LOCK COUNT
ADDM T2,CST1(T1) ; ...
POP P,T1 ;RESTORE ACS
JRST DASPGX ;DONE
;ROUTINE CALLED FROM PHYSIO TO GET STRUCTURE NUMBER FOR GIVEN
;CORE PAGE NUMBER. IT WILL HANDLE EITHER FILE PAGE OR SWAPPING REQUESTS
;ACCEPTS: A/ CORE PAGE NUMBER
;RETURNS: +1 B/ STRUCTURE NUMBER
FNDSTR::HLRZ B,CST2(A) ;GET PTN FROM CST
JUMPN B,HAVPT ;IF HAVE ONE GO ANALYZE IT
HRRZ B,CST2(A) ;GET SPTN
CAIGE B,NOFN ;IS THIS AN OFN?
JRST GOTOFN ;YES. GO CONSIDER IT
HLRZ B,SPTH(B) ;NO. GET OFN FOR THIS SPT
JUMPN B,GOTOFN ;IF A FILE PAGE JUMP TO LOOK AT IT
RTZRO: SETZ B, ;IS NOT A FILE PAGE. ASSUME SWAPPING SPACE
RET ;DONE
HAVPT: CAIL B,NOFN ;IS THIS AN OFN?
JRST RTZRO ;NO
GOTOFN: LOAD B,STRX,(B) ;YES. GET STRUCTURE NUMBER
RET ;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,SWPRT ;DONE?
JRST 0(3) ;NO, RETURN NOT RUNNABLE
CALL AGESN ;SET AGE
LOAD T1,FKJSB
MOVE 1,SPT(1) ;CHECK JSB
JSP 4,SWPRT
JRST 0(3)
CALL AGESN
HLRZ 1,FKPGS(7) ;PT
MOVE 1,SPT(1)
JSP 4,SWPRT ;PT READY?
JRST 0(3) ;NO
CALL AGESN
LOAD T1,FSSPTN ;GET STACK PAGE
MOVE T1,SPT(T1) ;GET CORE PAGE
JSP 4,SWPRT ;SEE IF IN YET
JRST 0(3) ;NOT
CALL AGESN ;MAKE THE AGE GOOD
JRST 1(3)
;SCHEDULER TEST FOR READ COMPLETED
DSKRT:: JFCL ;SAME AS SWPRT
SWPRT:: HRRZ 2,1
LOAD 2,CSTAGE,(2) ;GET PAGE STATE CODE
CAIN 2,PSRIP ;STILL READ-IN-PROGRESS?
JRST 0(4) ;YES
JRST 1(4)
;SWAP COMPLETION ROUTINE, CALLED FROM DRUM AND DISK INTERRUPT CODE
; 1/ PAGE NUMBER
SWPDON::MOVX 2,SWPERR
TDNE 2,CST3(1) ;SWAP ERROR IN PAGE?
JRST SWPER1 ;YES, GO DIAGNOSE IT
SWPERX: MOVSI 2,(DWRBIT) ;WRITE BIT
TDNE 2,CST3(1) ;WAS WRITE?
JRST SWPD1 ;YES
AOS PSKED ;INDICATE READ COMPLETED
MOVX 2,PSRDN
STOR 2,CSTAGE,(1)
RET
SWPD1: ANDCAM 2,CST3(1) ;CLEAR WRITE BIT
LOAD 2,CSTAGE,(1) ;GET TRAP CODE
CAIN 2,PSWIP ;STILL WRITE IN PROGRESS?
SOS IOIP ;YES, NOTE COMPLETION
SKIPE DWRCFL ;FORK WAITING FOR WRITE COMPLETION?
JRST [ AOS PSKED ;YES, POKE SCHED
SKIPN IOIP ;WRITES ALL COMPLETED?
SETZM DWRCFL ;YES, CLEAR FLAG
JRST .+1]
SKIPN CST2(1) ;PAGE DELETED?
JRST [ MOVEI 2,CST3(1) ;IT WAS DELETED, PUT ON DELETED QUEUE
EXCH 2,DELPGQ
HRRM 2,@DELPGQ
MOVEI 2,PSDEL ;SET PAGE STATE TO DELETED
STOR 2,CSTAGE,(1)
RET]
MOVX T3,SWPERR
TDNE T3,CST3(T1) ;ERROR ON WRITE?
JRST [ ANDCAM T3,CST3(T1) ;YES, CLEAR IT
MOVX T3,CORMB
IORM T3,CST0(T1) ;NOTE PAGE STILL NEEDS WRITING
CAIE T2,PSWIP ;PAGE WAS REASSIGNED?
JRST .+1 ;YES, OK
MOVX T2,OFNUL ;SET IT TO UNASSIGNED
STOR T2,CSTOFK,(T1)
STOR T2,CSTAGE,(T1)
JRST .+1]
CAIE 2,PSWIP ;PAGE REASSIGNED WHILE WRITING?
RET ;YES, DO NOTHING ELSE
MOVE 2,CST1(1) ;GET ADDRESS WHERE PAGE WAS WRITTEN
TXNN 2,DSKAB ;WAS WRITE TO DISK?
CALLRET ONRQ ;NO, PUT PAGE ON RPLQ
MOVX T2,DSKSWB
TDNN T2,CST3(T1) ;KEEP PAGE REQUESTED?
CALLRET OFRQ ;NO, PUT ON RPLQ
CALLRET ONRQ ;YES, TO END OF RPLQ
;DIAGNOSE SWAP ERROR
; A/ PAGE NUMBER
SWPER1: HLRZ B,CST2(A) ;GET OWNING SPTN
JUMPN B,SWPER3 ;JUMP IF IN PT
HRRZ B,CST2(A) ;GET SPTN OF PAGE
CAIGE B,NOFN ;INDEX BLOCK?
JRST [ CALL SWBOFN ;YES - FLAG IN SPT
JRST SWPEX2] ;AND NOTE MILD COMPLAINT
HLRZ B,SPTH(B) ;GET OFN OF IDENT
JUMPN B,SWPER3 ;JUMP IF OFN PRESENT
PUSH P,A ;SAVE PAGE NUMBER
MOVE A,CST2(A) ;SETUP SPTN
CALL FNDFPG ;GET TYPE OF FORK PAGE
MOVE B,A ;B = TYPE
POP P,A ;RECOVER PAGE NUMBER
XCT [ JRST SWPEX7 ; 0 - UNKNOWN OR HWPT
JRST SWPEX8 ;1 - PSB
JRST SWPEX8 ;2 - UPT
JRST SWPEX8](B) ;3 - JSB
;HERE WHEN HAVE PAGE TABLE IDENT IN B
SWPER3: CAIGE B,NOFN ;IN ORDINARY FILE?
JRST [ CALL SWBOFN ;YES - MARK IN SPT
JRST SWPERX] ;AND DEPART
CAMN B,MMSPTN ;IN SWAPMON?
JRST SWPEX3 ;YES
PUSH P,A ;SAVE PAGE NUMBER
MOVE A,B ;SETUP SPTN
CALL FNDFPG ;GET TYPE OF FORK PAGE
MOVE B,A ;B = TYPE
POP P,A ;RECOVER PAGE NUMBER
XCT [ JRST SWPEX6 ;0 - HWPT OR UNKNOWN
JRST SWPEX4 ;1 - PSB PAGE
JRST SWPERX ;2 - UPT PAGE
JRST SWPEX5](B) ;3 - JSB PAGE
;HERE TO INDICATE AN ERROR IN AN OFN
SWBOFN: MOVX T3,OFNBAT ;GET BAT BIT
TDNN T3,SPTH(T2) ;ALREADY SET?
TXO T3,OFNWRB ;YES - INDICATE CHANGED
IORM T3,SPTH(T2) ; IN SPTH
RET
;DISPOSITION OF SWAP ERROR CASES
SWPEX1: BUG(CHK,SWPFPE,<SWAP ERROR IN SENSITIVE FILE PAGE>)
JRST SWPERX ;TRY TO CONTINUE
SWPEX2: BUG(CHK,SWPIBE,<SWAP ERROR IN INDEX BLOCK>)
JRST SWPERX ;SHOULD CONTINUE OK
SWPEX3: BUG(HLT,SWPMNE,<SWAP ERROR IN SWAPPABLE MONITOR>)
SWPEX4: BUG(HLT,SWPPSB,<SWAP ERROR IN PSB PAGE>)
SWPEX5: BUG(CHK,SWPJSB,<SWAP ERROR IN JSB PAGE>)
JRST SWPERX ;TRY TO CONTINUE
SWPEX6: BUG(HLT,SWPPTP,<SWAP ERROR IN UNKNOWN PT PAGE>)
SWPEX7: BUG(HLT,SWPPT,<SWAP ERROR IN UNKNOWN PT>)
SWPEX8: BUG(HLT,SWPUPT,<SWAP ERROR IN UPT, OR PSB>)
;FIND TYPE OF FORK PAGE
; A/ SPTH OF PAGE
; CALL FNDFPG
; RETURNS +1 ALWAYS,
; A/ 0 - UNKNOWN PAGE OR HWPT
; 1 - PSB
; 2 - UPT
; 3 - JSB
FNDFPG: SAVEQ
SKIPE FX,SPTH(A) ;HAVE GOOD FORX INDEX?
TLNE FX,-1
JRST RETZ ;NO, RETURN UNKNOWN
HRRZ Q1,A ;SAVE SPTH
MOVSI A,-NFNFT ;SETUP TO SCAN TABLE
FNFP1: XCT FNFTAB(A) ;GET SPTN FOR A FORK PAGE
CAMN B,Q1 ;SAME AS GIVEN ONE?
RET ;YES, RETURN INDEX IN A
AOBJN A,FNFP1 ;SCAN TABLE
JRST RETZ ;NOT FOUND
FNFTAB: LOAD B,HWPTN
LOAD B,FKPSB
LOAD B,FKUPT
LOAD B,FKJSB
NFNFT==.-FNFTAB
;PUT PAGE ON TOP OF REPLACABLE QUEUE. THIS IS DONE WHEN CURRENT
;CONTENTS OF PAGE ARE NOT EXPECTED TO BE REUSED. THE CORE PAGE THUS
;S PLACED WHERE SWPIN WILL GET TO IT IMMEDIATELY.
OFRQ: MOVEI 2,CST3(1) ;MAKE PTR
PIOFF ;NO DSK OR DRM INTERRUPTS WHILE DIDDLING PTRS
LOAD 3,CSTPST,(1) ;CHECK PAGE STATE
JUMPN 3,ONSPMQ ;OTHER THAN AVAILABLE?
CAMGE 1,MONCOR ;A RESIDENT MONITOR PAGE?
JRST [ CALL DASPAG ;DEASSIGN PAGE
PION ;TURN ON PI'S AGAIN
CALLRET FRCRRM] ;AND PUT PAGE IN SERVICE AGAIN
HRRZ 3,RPLQ ;NO, MAKE PTR FOR NEW PAGE
HLL 4,0(3) ; ..
HRLM 2,0(3) ;FIX BACK PTR OF OLD TOP PAGE
HLL 3,4
MOVEM 3,0(2) ;SET PTRS FOR NEW TOP PAGE
HRRM 2,RPLQ ;SET NEW PTR TO TOP PAGE IN RPLQ
PION
JRST ONRQ1 ;GO FINISH UP
;PUT PAGE ON REPLACABLE QUEUE
; 1/ PAGE NUMBER
; CALL ONRQ
; RETURN +1 ALWAYS
ONRQ: MOVEI 2,CST3(1) ;CONSTRUCT ABSOLUTE PTR FOR PAGE
PIOFF ;NO INTS WHILE DIDDLING LIST
LOAD 3,CSTPST,(1) ;GET PAGE STATE
JUMPN 3,ONSPMQ ;OTHER THAN AVAILABLE?
CAMGE 1,MONCOR ;A RESIDENT MONITOR PAGE?
JRST [ CALL DASPAG ;DEASSIGN PAGE
PION ;TURN ON PI'S AGAIN
CALLRET FRCRRM] ;AND PUT IT BACK IN SERVICE
HLRZ 3,RPLQ ;NO, PUT PAGE ON 'IN' END OF QUEUE
HRL 4,0(3) ; BECAUSE PAGES ARE TAKEN FROM 'OUT'
HRRM 2,0(3) ; END OF QUEUE.
HLL 3,4
MOVSM 3,0(2)
HRLM 2,RPLQ
PION
ONRQ1: AOS NRPLQ
MOVEI 2,PSRPQ ;SET PAGE STATE
STOR 2,CSTAGE,(1)
RET
;HERE TO PLACE A PAGE ON THE SPECIAL MEMORY QUEUE
;MUST BE CALLED PIOFF
;T1/ CORE PAGE NUMBER
; CALL ONSPMQ
;RETURNS+1(ALWAYS):
;PAGE REMOVED FROM CST, ON SPMQ
;**NOTE**: RETURNS PION
ONSPMQ: CALL DASPAG ;REMOVE PAGE FROM CST
LOAD T2,CSTAGE,(T1) ;GET STATE CODE
CAIN T2,PSSPQ ;ALREADY ON SPMQ?
JRST ONSPQX ;YES - DONE
MOVEI T2,CST3(T1) ;BUILD POINTER
HLRZ T3,SPMQ ;GET TAIL POINTER
HRRM T2,(T3) ;APPEND TO LIST
HRLZM T3,CST3(T1) ;BACK POINTER
HRLM T2,SPMQ ;NEW TAIL OF LIST
MOVEI T2,PSSPQ ;SET PAGE STATE TO ON SPMQ
STOR T2,CSTAGE,(T1) ; ...
AOS NSPMQ ;NOTE ANOTHER PAGE
CAMG T1,NHIPG ;A KNOWN PAGE?
CAMGE T1,MONCOR ;SWAPPABLE?
JRST ONSPQX ;NO, ALL DONE
AOS GNPBAS ;UPDATE PAGE ACCOUNTING
AOS BALSHC
AOS SUMNR
ONSPQX: PION ;ENABLE INTERRUPTS
RET ;ALL DONE
;ROUTINE TO REMOVE A PAGE FROM SPMQ
;T1/ PHYSICAL PAGE
; CALL OFFSPQ
;RETURNS+1(ALWAYS):
; PAGE REMOVED
;CAUTION - THE CALLER MUST BE SURE THE PAGE IS "STABLE" ON SPMQ
OFFSPQ: PIOFF ;INTERLOCK
LOAD T2,CSTAGE,(T1) ;CHECK STATE
CAIE T2,PSSPQ ;NOW ON SPMQ?
BUG (HLT,OFFSPE,<OFFSPQ- PAGE NOT ON SPMQ>)
HRRZ T2,CST3(T1) ;GET POINTERS
HLRZ T3,CST3(T1)
JUMPE T2,[HRLM T3,SPMQ ;IF END-OF-LIST, MAKE NEW TAIL
JRST OFFSP0] ;PROCEED
HRLM T3,(T2) ;ADVANCE BACK POINTER
OFFSP0: HRRM T2,(T3) ;BACKUP FORWARD LINK
MOVX T2,UAAB ;UNASSIGNED ADDRESS
STOR T2,STGADR,CST1(T1) ;SET IT
MOVX T2,<FLD(OFNUL,CSTOFK)>
MOVEM T2,CST3(T1) ;SET OWNER TO NULL
SOS NSPMQ ;ONE FEWER PAGE
CAMGE T1,MONCOR ;A SWAPPABLE PAGE?
JRST ONSPQX ;NO. DON'T ACCOUNT IT
CAMLE T1,NHIPG ;A NEW PAGE COMING IN?
JRST [ MOVEM T1,NHIPG ;YES. MAKE XGC AND GCCRO SCAN IT
AOS TOTRC ;ANOTHER REAL PAGE
AOS PAGDIF ;NEW PAGE IN THE SYSTEM
JRST ONSPQX] ;AND DONE
CALL UPSWP ;ONE MORE SWAPPING PAGE
CALLRET ONSPQX ;DONE
;ROUTINE TO RETURN CSTPST FOR A PHYSICAL PAGE
;T1/ PAGE
; CALL GETPST
;RETURNS+1(ERROR):
; INVALID PAGE NUMBER
;RETURNS+2(SUCCESS):
;T2/ SPECIAL PAGE STATE
GETPST::CAIL T1,MAXCOR ;CHECK RANGE
RET ;INVALID PAGE
LOAD T2,CSTPST,(T1) ;PAGE OK, RETURN CURRENT STATE
RETSKP
;ROUTINE TO SET THE CSTPST STATE FOR A PHYSICAL PAGE
;ASSUMES PROCESS CONTEXT, AS IT MAY NEED TO BLOCK DEPENDING ON THE
;ACTION TO BE TAKEN
;T1/ PHYSICAL PAGE
;T2/ NEW SPECIAL PAGE STATE
; CALL SETPST
;RETURNS+1(ERROR):
; ERROR CODE IN T1
;RETURNS+2(SUCCESS):
; PAGE ON SPMQ WITH REQUESTED STATE
; T1/ PREVIOUS STATE OF PAGE
;LOCAL AC USAGE
;Q1/ PHYSICAL PAGE
;Q2/ NEW STATE
SETPST::SAVEQ
STKVAR <SETOST> ;SAVE ORIGINAL STATE HERE
MOVE Q1,T1 ;COPY ARGUMENTS
MOVE Q2,T2 ; ...
CAIN T2,PSTSPM ;ATTEMPTING TO USE TRANSITION STATE?
RETBAD (PMCLX1) ;YES - CANNOT BE SET BY USER
CAIL T1,MAXCOR ;LEGAL PAGE?
RETBAD (ARGX06) ;NO - INVALID PAGE
CALL LCKSPM ;INTERLOCK USER SIDE OF SPMQ LOGIC
;PRESERVES T,Q,P ACS
LOAD T3,CSTPST,(T1) ;YES - GET CURRENT PAGE STATE
MOVEM T3,SETOST ;SAVE ORIGINAL STATE HERE
LOAD T4,CSTAGE,(T1) ;NOW NOINT, IS PAGE ALREADY ON SPMQ
CAIE T4,PSSPQ ; ?
JRST STPST1 ;NO
CAMN T3,T2 ;SAME AS REQUESTED STATE?
JRST STPSTX ;YES - RETURN SUCCESS
STPST1: LSH T3,2 ;NO - FORM TRANSITION TABLE INDEX
IOR T3,T2 ; ...
ADJBP T3,[POINT 2,STPSTA,1] ;INDEX INTO TRANSITION TABLE
LDB T3,T3 ;GET ACTION CODE
XCT STPSTB(T3) ;PERFORM ACTION
;COMMON EXIT POINT
STPSTX: CALL ULKSPM ;RELEASE USER SIDE OF SPMQ
MOVE T1,SETOST ;RETURN ORIGINAL STATE TO CALLER
RETSKP ;RETURN SUCCESS
;TRANSITION TABLE
STPSTA: BYTE (2)0,0,1,1,0,0,0,0,2,0,0,3,2,0,3,0
;ACTION TABLE
;ENTERED WITH T1,Q1 = PAGE; T2,Q2 = REQUESTED STATE
STPSTB: RETBAD (PMCLX1,<CALL ULKSPM>) ;ILLEGAL TRANSITION
JRST STPSTF ;TRANSITION TO OFFLINE
JRST STPSTN ;TRANSITION TO ONLINE
JRST STPSTC ;CHANGE OFFLINE STATE
;HERE TO PLACE A PAGE OFFLINE
STPSTF: CALL FRCSPM ;FORCE ONTO SPMQ
RETBAD (PMCLX2,<CALL ULKSPM>) ;COULDNT FREE PAGE
MOVE T1,Q1 ;GET PAGE AGAIN
CALL CASHFP ;FLUSH PAGE FROM CACHE
MOVX T1,PSTOFL ;SET PAGE OFFLINE
STOR T1,CSTPST,(Q1) ; ...
JRST STPSTX ;EXIT
;HERE TO PLACE A PAGE ONLINE
STPSTN: CALL FRCSPM ;FORCE ONTO SPMQ
RETBAD (PMCLX2,<CALL ULKSPM>)
MOVE T1,Q1 ;COPY PAGE
CALL CHKPAG ;CHECK PAGE FOR NXM
RETBAD (PMCLX3,<CALL ULKSPM>) ;ERRORS, DONT PLACE ONLINE
MOVE T1,Q1 ;COPY PAGE
CALL OFFSPQ ;REMOVE FROM SPMQ
MOVE T1,Q1 ;COPY PAGE
MOVX T3,PSTAVL ;SET SPECIAL PAGE STATE TO AVAILABLE
STOR T3,CSTPST,(T1) ; ...
CAMGE T1,MONCOR ;A RESIDENT MONITOR PAGE?
JRST [ CALL FRCRRM ;YES. PUT IT BACK IN SERVICE
JRST STPSTX] ;AND DONE
NOSKED ;PROTECT THIS PAGE
CALL OFRQ ;PLACE AT HEAD OF RPLQ
OKSKED ;ALL QUEUED UP
JRST STPSTX
;HERE TO CHANGE THE STATE OF A PAGE (FROM OFL TO ERR OR ERR TO OFL)
STPSTC: CALL FRCSPM ;SHOULD BE A NOP
RETBAD (PMCLX2,<CALL ULKSPM>)
STOR Q2,CSTPST,(Q1) ;SET TO NEW STATE
JRST STPSTX
;COMMON ROUTINES FOR USER SPMQ MANIPULATION
;ROUTINE TO INTERLOCK USER MANIPULATION OF SPMQ
;PRESERVES T,Q,P ACS
LCKSPM: PUSH P,T1 ;SAVE T1
LCKSP1: NOINT
AOSE SPMLCK ;TEST/SET LOCK
JRST LCKSP2 ;MUST BLOCK
MOVE T1,FORKX ;HAVE LOCK, INDICATE OWNER
MOVEM T1,SPMONR ; ...
POP P,T1 ;RESTORE T1
RET
LCKSP2: OKINT ;BLOCK OKINT
MOVEI T1,SPMLCK ;LOCK WORD
CALL DISL ;WAIT FOR NEGATIVE
JRST LCKSP1 ;TRY AGAIN
;ROUTINE TO RELEASE SPMQ INTERLOCK
;PRESERVES ALL ACS
ULKSPM: SETOM SPMONR ;NO OWNER
SETOM SPMLCK ;FREE LOCK
OKINT ;ALLOW INTERRUPTS
RET
;ROUTINE TO FORCE A PAGE ONTO SPMQ
;T1/ PHYSICAL PAGE
; CALL FRCSPM
;RETURNS+1(FAILURE):
; UNABLE TO FREE PAGE
;RETURNS+2(SUCCESS):
; PAGE IS ON SPMQ
FRCSPM: ACVAR <Q1,Q2,Q3>
MOVE Q1,T1 ;COPY ARGUMENT
MOVEI Q2,^D5 ;NUMBER OF TIMES TO TRY
LOAD Q3,CSTPST,(T1) ;GET PRESENT STATE
FRCSP1: LOAD T2,CSTAGE,(Q1) ;GET CURRENT STATE
CAIN T2,PSSPQ ;ON SPMQ NOW?
RETSKP ;YES - NOTHING TO DO
MOVX T2,PSTSPM ;SETUP TO CHANGE SPECIAL PAGE STATE
PIOFF ;INTERLOCK
LOAD T3,CSTPST,(Q1) ;CHECK CURRENT STATE
CAIN T3,PSTAVL ;CURRENTLY AVAILABLE?
STOR T2,CSTPST,(Q1) ;YES - MAKE UNAVAILABLE
LOAD T2,CSTAGE,(Q1) ;GET SWAPPER STATE CODE
CAIN T2,PSRPQ ;ON RPLQ?
JRST FRCSP3 ;YES - DIRECTLY TO SPMQ
CAIGE T2,PSASN ;PAGE IN USE?
JRST FRCSP4 ;NO
HLRZ T2,CST2(Q1) ;SEE IF PART OF MONITOR MAP
CAMN T2,MMSPTN ;IS IT?
JRST [ HRRZ T2,CST2(Q1) ;YES. GET INDEX
CAML T2,SWPCOR ;IN OR ABOVE SWPMON?
JRST .+1 ;YES. CAN'T MOVE IT THEN
CAML T2,MONCOR ;IS IT A RESIDENT PAGE?
CALL [ MOVX T3,-PLKV ;NO. SEE IF LOCKED THEN
TDNN T3,CST1(Q1) ;IS IT?
RETSKP ;NO. LET STANDARD CODE DO IT
CAIL Q1,<SPCRES+PGSIZ-1>/PGSIZ ;MOVABLE?
RET ;MAYBE.
RETSKP] ;NO.
SKIPA T1,Q1 ;YES. CAN TRY TO MOVE IT THEN
JRST .+1 ;NO. CAN'T MOVE IT
PION ;TURN ON PI'S FOR A WHILE
CALL FRCRMP ;SEE IF WE CAN DO IT
JRST FRCSP0 ;CAN'T. RETURN BAD NEWS
RETSKP] ;DONE. PAGE IS ON SPMQ
CALL SWPCHK ;CAN PAGE BE SWAPPED OUT?
SKIPA ;NO - USE LARGE HAMMER
JRST FRCSP5 ;YES - SWAPOUT JUST THIS PAGE
PION ;MUST UNLOAD MEMORY
AOS SKEDFC ;INDICATE FORCED CLEAR
ISB SCDCHN ;REQUEST SCHEDULER CYCLE
FRCSP2: MOVEM Q1,SPMTPG ;SAVE REQUESTED PAGE
MOVEI T1,^D2000 ;AND WATCHDOG TIME
ADD T1,TODCLK ; ...
MOVEM T1,SPMTIM ;TWO SECONDS FROM NOW
MOVEI T1,SPMTST ;TEST ROUTINE
MDISMS ;REGRETABLY NOINT
MOVE T1,Q1 ;PUT PAGE NUMBER BACK IN T1
SOJG Q2,FRCSP1 ;TRY AGAIN
FRCSP0: STOR Q3,CSTPST,(Q1) ;RESTORE ORIGINAL STATE
RET ;FAILED
;FRCSPM CONTINUED
;ON RPLQ - REMOVE FROM RPLQ AND PLACE ON SPMQ
FRCSP3: MOVE T2,Q1 ;PAGE NUMBER
NOSKED ;PROTECT ALL STRUCTURES
CALL PRLDEQ ;GET OFF OF RPLQ
MOVE T1,Q1 ;PAGE NUMBER AGAIN
PIOFF ;PRLDEQ DID A PION
CALL ONSPMQ ;PLACE ON SPMQ (RETURNS PION)
OKSKED ;ALLOW SCHEDULING AGAIN
RETSKP ;SUCCESS
;HERE WHEN PAGE IS UNASSIGNED AND NOT ON RPLQ
FRCSP4: PION
JRST FRCSP2 ;SHOULD BE TRANSIENT STATE
;HERE WHEN PAGE IS ASSIGNED AND CAN BE SWAPPED OUT
FRCSP5: NOSKED ;FOR CALL TO SWPOUT
PION
CALL SWPOT0 ;START SWAP
OKSKED
JRST FRCSP2 ;JUST A MATTER OF TIME NOW...
;SCHEDULER TEST ROUTINE FOR FRCSPM
SPMTST: MOVE T1,SPMTPG ;SOUGHT AFTER PAGE
LOAD T2,CSTAGE,(T1) ;GET STATE CODE
CAIN T2,PSSPQ ;ON SPMQ?
JRST 1(T4) ;YES - UNBLOCK
MOVE T1,SPMTIM ;NO - TIME UP?
CAML T1,TODCLK ; ???
JRST 0(T4) ;NO - REMAIN BLOCKED
JRST 1(T4) ;TIME IS UP - UNBLOCK AND RETRY
;ROUTINE USED BY FRCSPM TO PLACE A RESIDENT MONITOR PAGE OFF-LINE.
;CALLED WITH: T1/ PAGE NUMBER
;RETURNS:
; +1 FAILED. CANNOT MOVE THIS PAGE
; +2 SUCCESS. PAGE MOVED AND MMAP UPDATED
;PAGE MUST BE LESS THAN C(SWPCOR) AND MUST BE LOCKED.
FRCRMP: STKVAR <SRCPAG,SRCADR> ;WHERE TO SAVE SOURCE PAGE
HRRZ T2,CST2(T1) ;GET MONITOR VIRTUAL PAGE NUMBER
MOVEM T2,SRCADR ;SAVE IT
CALL RMPCHK ;SEE IF CAN MOVE THIS PAGE
RETBAD () ;CAN'T.
MOVEM T1,SRCPAG ;SAVE ADDRESS OF SOURCE PAGE
FRCRM1: NOSKD1 ;PROTECT RPLQ
CALL CHKRPQ ;WAIT FOR RPLQ TO BE OKAY
JRST .-1 ;REVERIFY IF BLOCKED
HRRZ T2,RPLQ ;GET TOP PAGE
SUBI T2,CST3 ;COMPUTE PAGE NUMBER
CALL PRLDEQ ;USE COMMON ROUTINE TO DEQUEUE THE PAGE
PUSH P,T2 ;SAVE CORE PAGE NUMBER
MOVE T3,T2 ;COPY PAGE NUMBER
CALL DEPG ;DEASSIGN OWNERSHIP
SETZM CST1(T3) ;NO BACKUP NOW
MOVE T1,T3 ;GET CORE PAGE NUMBER IN T1
MOVX T3,PSRDN ;FAKE AGE
STOR T3,CSTAGE,(T1) ; SO MLKCP WILL DO RIGHT THING
CALL MLKCP ;LOCK IT IN CORE
POP P,T2 ;GET DEST CORE PAGE AGAIN
MOVE T1,SRCPAG ;GET BACK SOURCE PAGE
MOVE T3,CST2(T1) ;GET OWNERSHIP
MOVEM T3,CST2(T2) ;NEW PAGE OWNERSHIP
; ..
;PAGE NOW HAS PROPER I.D. MOVE DATA
MOVE T3,SRCADR ;GET MONITOR VIRTUAL PAGE NUMBER OF SOURCE
LSH T3,PGSFT ;AN ADDRESS
MOVE T1,T2 ;GET DEST CORE PAGE
PIOFF ;OWN THE ENTIRE MACHINE
CALL MAPRCA ;SET UP MAPPING
MOVEI T4,PGSIZ-1(T1) ;COMPUTE END OF PAGE
HRL T1,T3 ;SET UP BLT ARG
BLT T1,0(T4) ;MOVE DATA
CALL UNMRCA ;UNDO MAPPING NOW THAT DATA IS MOVED
MOVE T1,SRCADR ;GET BACK SOURCE PAGE
STOR T2,STGADR,MMAP(T1) ;SET UP NEW MAPPING FOR THIS PAGE
MOVE T1,T3 ;GET SET TO MAKE PAGE USABLE
CALL MONCLR ;DO IT
MOVE T1,SRCPAG ;GET SOURCE PAGE # AGAIN
MOVX T3,-PLKV ;TEST FOR LOCKED
TDNE T3,CST1(T1) ;NOW LOCKED?
CALL MULKCR ;YES. UNLOCK IT THEN
MOVE T1,SRCPAG ;THE PAGE AGAIN
SETZM CST2(T1) ;NOW NOT OWNED
REPEAT 0,< ;DON'T NEED EPT CODE YET
CALL TSTEPT ;SEE IF SOURCE PAGE IS NOW THE EPT
JRST [ EXCH T1,T2 ;IT IS. MUST CHANGE EPT THEN
CALL SETEPT ;MAKE NEW PAGE THE EPT
EXCH T1,T2
JRST .+1] ;PROCEED
> ;END OF REPEAT 0
CALL ONSPMQ ;PUT PAGE ON SPECIAL QUEUE
OKSKD1 ;TURN ON SCHEDULER AGAIN
RETSKP ;AND DONE
;ROUTINE TO PUT A RESIDENT MONITOR PAGE BACK ON-LINE.
; T1/ PAGE NUMBER
;PAGE ALREADY OFF OF SPMQ
FRCRRM: STKVAR <SRCPAG,OLDPAG> ;SAVE PAGE NUMBERS
NOSKD1 ;OWN THE MACHINE
MOVEM T1,SRCPAG ;SAVE PAGE TO USE AGAIN
LOAD T2,STGADR,MMAP(T1) ;GET CURRENT LOC OF DATA
MOVEM T2,OLDPAG ;SAVE IT TOO
MOVE T3,CST2(T2) ;I.D OF PAGE
MOVEM T3,CST2(T1) ;SET UP I.D.
SETONE CSTAGE,(T1) ;MAKE NEW PAGE ACCESSIBLE
MOVE T2,T1 ;GET ADDRESSABLE VALUE FOR CURRENT DATA
LSH T2,PGSFT ;GET ADDRESS OF CURRENT DATA
PIOFF ;PREVENT MISHAPS
CALL MAPRCA ;GET ACCESS TO NEW PAGE
MOVEI T4,PGSIZ-1(T1) ;GET END OF PAGE
HRL T1,T2 ;SET UP FOR DATA MOVE
BLT T1,0(T4) ;MOVE THE DATA
MOVE T1,SRCPAG ;GET NEW PAGE NUMBER AGAIN
STOR T1,STGADR,MMAP(T1) ;MAKE MMAP POINT TO NEW PAGE
MOVE T1,T2 ;GET ADDRESS
CALL MONCLR ;MAKE PAGE BE USED
MOVE T1,OLDPAG ;GET OLD PAGE I.D.
REPEAT 0,< ;DON'T NEED EPT CODE NOW
CALL TSTEPT ;IS IT NOW THE EPT?
JRST [ MOVE T1,SRCPAG ;YES. GET SOURCE PAGE
CALL SETEPT ;MAKE IT THE NEW EPT
MOVE T1,OLDPAG ;RESTORE OLD PAGE
JRST .+1] ;AND PROCEED
> ;END OF REPEAT 0
CALL UNMRCA ;CLEAR TEMP MAPPING
PION ;ALL IS O.K NOW. LET SYSTEM BREATH AGAIN
;DATA NOW RESTORED AND PAGE IN USE. RELEASE OLD PAGE
SETZM CST2(T1) ;NO LONGER OWNED
CALL MULKCR ;UNLOCK PAGE
;UNLOCKER PUTS PAGE ON RPLQ
OKSKD1 ;ALLOW SCHEDULING AGAIN
RET ;DONE
;SPECIAL ROUTINES USED BY DIAG MEMORY CONTROL.
;SET MAP TO POINT TO PHYSICAL MEMORY WITHOUT CHANGING STATE
;OF MEMORY PAGES. PROCESS SHOULD BE NOINT AND MUST INSURE
;THAT THE PAGES ARE REFERENCED ONLY WHILE NOSKED.
;ACCEPTS:
; T1/ SOURCE I.D. (PTN,,PN)
; T2/ FIRST CORE PAGE (-1 => CLEAR MAP)
; T3/ COUNT
;RETURNS: +1 ALWAYS
MAPPV:: ASUBR <SID,CPG,CNT>
HLRZ T3,T1 ;GET PTN OF MAP
CALL SETXB1 ;MAP PT
MOVE T3,IMMPTR ;FORM AN IMMEDIATE POINTER TO MEMORY
IOR T3,CPG ;INSERT MEMORY PAGE
SKIPGE CPG ;WANT TO CLEAR?
SETZM T3 ;YES.
MOVN T1,CNT ;GET NEG OF COUNT
MOVSS T1
HRR T1,SID ;STARTING PAGE IN MAP
MAPPV1: MOVEM T3,CXBPGA(T1) ;UPDATE MAP
SKIPE T3 ;WANT CLEAR?
ADDI T3,1 ;NO. NEXT PAGE THEN
AOBJN T1,MAPPV1 ;DO ALL OF MAP
CALL MONCLA ;CLEAR PAGER
CALLRET RELCXB ;RELEASE PT AND RETURN
;ROUTINE TO SET UP CST0 FOR A PROCESS THAT HAS USED MAPPV.
;THE APPROPRIATE CST0'S ARE SET UP WITH PUFLD=-1 AND
;THE AGE SET TO THE CURRENT AGE OF THE PROCESS.
;MUST BE NOSKED
;ACCEPTS:
; T1/ FIRST MEMORY PAGE
; T2/ COUNT
;RETURNS: +1 ALWAYS
SETCST::MOVX T4,<PUFLD!CORMB> ;PART OF NEW CST0 WORDS
MOVE T3,FORKX ;CURRENT FORK
HLRZ T3,FKNR(T3) ;PRESENT AGE
STOR T3,AGEMSK,T4 ;SET AGE
SETCS1: MOVEM T4,CST0(T1) ;SET NEW CST0
ADDI T1,1 ;NEXT PAGE
SOJG T2,SETCS1 ;DO ALL OF THEM
CALLRET MONCLA ;CLEAR PAGER
;ROUTINES USED BY LOADBS TO SEE IF THIS FORK'S PT,PSB,ETC
;ARE IN A TRANSITION PAGE.
;ACCEPST: FX/ FORK HANDLE
;RETURNS: +1 ONE OR MORE PAGES IN TRANSITION
; +2 NONE IN TRANSITION
TSTFRP::CAMN FX,SPMONR ;THIS FORK OWN THE LOCK?
RETSKP ;YES. ALLOW IT THEN
LOAD T1,FKJSB ;GET JSB
CALL TSTSPT ;GUILTY?
RET ;YES.
HRRZ T1,FKPGS(FX) ;TRY PSB
CALL TSTSPT
RET ;YES
HLRZ T1,FKPGS(FX) ;NO. TRY PT
CALL TSTSPT ;?
RET ;YES. GUILTY
LOAD T1,FSSPTN ;STACK PAGE
CALLRET TSTSPT ;?
;LOCAL ROUTINE TO TEST A GIVEN FORK PAGE.
;ACCEPTS: T1/ SPT OFFSET
;RETURNS: +1 IN TRANSITION
; +2 NOT
TSTSPT: LOAD T2,STGADR,SPT(T1) ;GET ADDRESS
TXNE T2,NCORTM ;IN MEMORY?
RETSKP ;NO. NOT IN TRANSITION THEN
JE CSTPST,(T2),RSKP ;IN TRANSITION?
RET ;YES.
TNXEND
END