Trailing-Edge
-
PDP-10 Archives
-
bb-m780a-sm
-
monitor-sources/dskalc.mac
There are 55 other files named dskalc.mac in the archive. Click here to see a list.
; UPD ID= 379, SNARK:<5.MONITOR>DSKALC.MAC.22, 6-Jan-82 10:58:08 by DONAHUE
;More 5.1495 - Save Q registers in SEEADR
; UPD ID= 161, SNARK:<5.MONITOR>DSKALC.MAC.21, 9-Sep-81 16:06:20 by DONAHUE
;TCO 5.1495 - REWRITE BAT BLOCK LOGIC TO ACCOUNT FOR LOST PAGES
; UPD ID= 99, SNARK:<5.MONITOR>DSKALC.MAC.20, 12-Aug-81 13:32:13 by PAETZOLD
;TCO 5.1446 - FIX HOME BLOCK COPYING
; UPD ID= 44, SNARK:<5.MONITOR>DSKALC.MAC.19, 17-Jul-81 16:17:48 by MURPHY
;MORE TCO 5.1398 - SKIP RETURN FROM MSETPT
; UPD ID= 11, SNARK:<5.MONITOR>DSKALC.MAC.18, 9-Jul-81 17:14:14 by MURPHY
;TCO 5.1398 - RETURN ERROR CODES ON DSKASN FAILURES
; UPD ID= 1985, SNARK:<5.MONITOR>DSKALC.MAC.17, 13-May-81 14:34:03 by SCHMITT
;More of TCO 5.1319 ...
; UPD ID= 1964, SNARK:<5.MONITOR>DSKALC.MAC.16, 8-May-81 10:33:59 by SCHMITT
;TCO 5.1319 - Rewrite BAT block allocation in drum bit table.
; UPD ID= 1879, SNARK:<5.MONITOR>DSKALC.MAC.15, 23-Apr-81 17:44:36 by LYONS
;ALLOW LOWER CASE INPUT WHEN LOOKING FOR A STRUCTURE NAME
; UPD ID= 1819, SNARK:<5.MONITOR>DSKALC.MAC.14, 17-Apr-81 09:47:47 by WACHS
;TCO 5.1288 Set UDBVID in all units of a file structure
; UPD ID= 1637, SNARK:<5.MONITOR>DSKALC.MAC.13, 3-Mar-81 05:08:45 by WACHS
;TCO 5.1264 - Don't let FSIASK get into section 0
; UPD ID= 1593, SNARK:<5.MONITOR>DSKALC.MAC.12, 27-Feb-81 04:08:02 by WACHS
;TCO 5.1264 - Stay in section 1 after asking for name of Public Structure
; UPD ID= 899, SNARK:<5.MONITOR>DSKALC.MAC.11, 14-Aug-80 10:54:05 by LYONS
;TCO 5.1062 - Check ERRSWP, and bughlt if non zero
; UPD ID= 658, SNARK:<5.MONITOR>DSKALC.MAC.8, 16-Jun-80 17:23:01 by KONEN
;TCO 5.1063 -
;Look for home block with the CPU serial number before the name PS
;Add to home blocks the serial number of CPU a structure boots
; UPD ID= 638, SNARK:<5.MONITOR>DSKALC.MAC.7, 13-Jun-80 18:27:23 by DBELL
;CHANGE DSKSIZ TO UDBSIZ AT FSIDE1
; UPD ID= 612, SNARK:<5.MONITOR>DSKALC.MAC.6, 6-Jun-80 15:47:22 by SCHMITT
;TCO 5.1060 - Fix calc of size of BTB for struc during initialization
; UPD ID= 610, SNARK:<5.MONITOR>DSKALC.MAC.5, 6-Jun-80 13:57:26 by DBELL
;CHECK WRITE PROTECTION OF PAGES IN DSKOP PROPERLY
; UPD ID= 573, SNARK:<5.MONITOR>DSKALC.MAC.4, 31-May-80 22:46:09 by DBELL
;TCO 5.1048 - CHANGE DSKOP TO ALLOW MULTIPLE-PAGE TRANSFERS
; UPD ID= 391, SNARK:<4.1.MONITOR>DSKALC.MAC.19, 28-Mar-80 14:52:28 by DBELL
;FIX BUG DESCRIPTIONS FOR NOBAT1 AND NOBAT2 BUGCHKS
; UPD ID= 357, SNARK:<4.1.MONITOR>DSKALC.MAC.18, 26-Mar-80 11:06:21 by DBELL
;TCO 4.1.1119 - ADD SUPPORT FOR RP20 DISKS
; UPD ID= 321, SNARK:<4.1.MONITOR>DSKALC.MAC.17, 12-Mar-80 11:59:48 by KONEN
; UPD ID= 202, SNARK:<4.1.MONITOR>DSKALC.MAC.15, 15-Jan-80 10:50:47 by MILLER
;TCO 4.1.1067. FIX COMPUTATION OF SWAT ADDRESS AT DOBDRM
; UPD ID= 54, SNARK:<4.1.MONITOR>DSKALC.MAC.14, 29-Nov-79 10:41:34 by SCHMITT
;MORE OF TCO 4.2409, RESTORE D AFTER DSKASA
;<OSMAN.MON>DSKALC.MAC.1, 10-Sep-79 15:27:16, EDIT BY OSMAN
;TCO 4.2412 - Move definition of BUGHLTs, BUGCHKs, and BUGINFs to BUGS.MAC
;<4.MONITOR>DSKALC.MAC.12, 7-Sep-79 10:37:47, EDIT BY SCHMITT
;JUST CLEANING UP PREVIOUS EDIT
;<4.MONITOR>DSKALC.MAC.11, 17-Aug-79 10:39:46, EDIT BY SCHMITT
;TCO 4.2409-EDIT TO CURE ASAASG & ASGBPG BUGCHECK DURING BIT TABLE INIT
;<4.MONITOR>DSKALC.MAC.10, 2-May-79 08:13:11, Edit by KONEN
;CHANGE JOB TO FORK IN SDBSTS FOR INITING A STRUCTURE
;<4.MONITOR>DSKALC.MAC.9, 17-Apr-79 15:47:50, EDIT BY DBELL
;TCO 4.2251 - ROUND BAT BLOCK ENTRIES DOWN TO PAGE BOUNDARIES.
;<4.MONITOR>DSKALC.MAC.8, 19-Mar-79 13:51:01, EDIT BY HALL
;GETBTB - BE NOINT WHEN WE HAVE JSB FREE SPACE
;<4.MONITOR>DSKALC.MAC.7, 4-Mar-79 15:27:50, EDIT BY KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<4.MONITOR>DSKALC.MAC.5, 8-Jan-79 06:42:59, EDIT BY GILBERT
;TCO 4.2155 - Implement hidden symbol tables:
; Change PSECT bounds symbols.
; Change BUTPGA to HOMPGA.
;FIX REDHOM ROUTINE SO ADDRESSES LESS THAN 400000 DON'T CAUSE SECG37
;<4.MONITOR>DSKALC.MAC.4, 15-Oct-78 00:07:18, EDIT BY ZIMA
;TCO 4.2044 FIX CPYH1/CPYH2 TO WRITE CORRECT HOMHOM WORD
;<4.MONITOR>DSKALC.MAC.3, 12-Oct-78 01:11:04, EDIT BY ZIMA
;TCO 4.2041 FIX ADDPR TO USE THE LAST BAT BLOCK ENTRY
;<3A.MONITOR>DSKALC.MAC.11, 24-Jul-78 22:56:16, Edit by MCLEAN
;FIX DSKASG NOT TO LOOSE Q1
;<4.MONITOR>DSKALC.MAC.8, 6-May-78 21:26:06, Edit by MCLEAN
;ADD RP07
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976,1977,1978,1979 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
SEARCH PROLOG,PHYPAR
TTITLE DSKALC
;NO SPECIAL AC'S USED HEREIN
SWAPCD
;DEVICE INDEPENDENT DISK RELATED STUFF - D. MURPHY
;STORAGE
;RS LSTTKA,1 ;LAST TRACK ASSIGNED
;RS DSKFRC,1 ;TOTAL FREE PAGES ON DISK
;RS DSKALK,1 ;LOCK AGAINST DISK ASSIGNMENTS
;DSKASN - ASSIGN PAGE ON DISK
;IF AC1 .NE 0, AC1 IS DISK ADDRESS - ASSIGN FROM SAME TRACK
;OTHERWISE, ASSIGN FROM A TRACK WITH .GE MINFPG FREE PAGES. START
;SEARCHING AT SDBLCA, EXAMINE TRACK N ON ALL DRIVES, THEN TRACK
;N+1 ON ALL DRIVES, ETC.
;ACCEPTS:
; T1/SECTOR NUMBER ON DISK RELATIVE TO START OF STRUCTURE OR ZERO
; T2/STRUCTURE NUMBER
;RETURNS +1: FAILURE
; +2: SUCCESS
; T1/DISK ADDRESS ASSIGNED
;USE OF Q REGISTERS:
; Q1/ADDRESS OF SIZE DATA FOR THIS DISK TYPE
; Q2/ADDRESS OF SDB FOR THIS STRUCTURE
; Q3/CURRENT CYLINDER NUMBER
DSKASN::SAVEQ
SE1CAL ;FORCE SECTION 1
STKVAR <STRN00,MINFP0>
MOVEM 2,STRN00 ;SAVE STRUCTURE NUMBER
MOVEM 1,Q3 ;SAVE DISK ADDRESS
MOVE Q2,STRTAB(2) ;GET ADDRESS OF SDB FOR THIS STRUCTURE
MOVX T4,MI%ASG ;IF ASSIGNMENTS ARE PROHIBITED BECAUSE BIT
TDNE T4,SDBSTS(Q2) ; TABLE IS BAD OR DOESN'T EXIST,
RETBAD IOX35 ;TAKE THE FAILURE RETURN
CAIE 2,PSNUM ;IS THIS PS?
IFSKP.
MOVX Q1,SC%WHL!SC%OPR ;YES. SEE IF PRIVILEGED
TDNE Q1,CAPENB ; IS IT?
ANSKP.
MOVE 1,2 ;NO, GET STRUCTURE #
CALL GSTRPG ;GET ALLOCATION
CAMG T2,SYSSPC ;ABOVE MIN FREE?
RETBAD IOX34 ;NO, ERROR DISK FULL
MOVE 2,STRN00 ;YES. ALLOW IT
ENDIF.
MOVE Q1,SDBTYP(Q2) ;GET ADDRESS OF DSKSIZ TABLE
MOVE 1,2 ;1/STRUCTURE NUMBER
CALL MAPBTB ;MAP INDEX BLOCK INTO BTBBAS, LOCK INTO CORE,
; LOCK BTBLCK, GO NOSKED
MOVE 1,Q3 ;RESTORE DISK ADDRESS
MOVE 4,BTBORA ;ADDRESS OF START OF BIT TABLE
JUMPE 1,DSKA1 ;FREE CHOICE
;USER REQUESTED A SPECIFIC ADDRESS. TRY TO GET A PAGE ON THE SAME
;CYLINDER. IF NO PAGE IS FREE, SCAN INCREASING TRACK NUMBES
TLZ 1,DSKMSK ;FLUSH GARBAGE BITS
IDIV 1,SECCYL(Q1) ;1/CYLINDER, 2/SECTOR WITHIN CYLINDER
CAMG 1,SDBCYL(Q2) ;WITHIN CYLINDER LIMIT FOR STRUCTURE?
CAIGE 1,LOTRK ;NON-NEGATIVE CYLINDER NUMBER?
JRST DSKA1 ;NO, USE FREE CHOICE ALGORITHM
ADD 4,1 ;POINT TO BIT TABLE WORD FOR THIS TRACK
SKIPN 0(T4) ;ANY PAGES FREE ON THIS TRACK?
AOJA T1,[SETZM MINFP0 ;NO, GO GET A PAGE FROM THE NEXT TRACK
JRST DSKSQ]
; ..
;A CYLINDER HAS BEEN SELECTED
; T1/CYLINDER NUMBER
; T4/ADDRESS OF WORD IN BIT TABLE CONTAINING THE NUMBER OF FREE PAGES
DSKA9: MOVEM 1,Q3 ;SAVE TRACK NUMBER
SOS 0(4) ;REDUCE FREE COUNT THIS TRACK
SOS SDBFRC(Q2) ;REDUCE FREE COUNT FOR STRUCTURE
IMUL 1,BTWCYL(Q1) ;COMPUTE OFFSET OF START OF BITS FOR THIS TRACK
ADD 1,BTBORA ;COMPUTE ADDRESS IN BIT TABLE
ADD 1,SDBBT0(Q2) ;ADD SIZE OF TOP HALF
SETZ 2, ;INITIALIZE COUNT OF BITS
;LOOP THROUGH BIT WORDS FOR THIS CYLINDER, FINDING THE FIRST WORD
;WITH AT LEAST ONE 'ON' BIT, INDICATING A FREE PAGE
DSKA2: SKIPE 3,0(1) ;ANY FREE PAGES THIS WORD?
JRST DSKA3 ;YES
ADDI 2,^D36 ;NO. NOTE 36 BITS HAVE BEEN CHECKED
CAML 2,PAGCYL(Q1) ;LOOKED AT BITS FOR ALL PAGES?
SKIPA ;YES. COULDN'T FIND A FREE PAGE
AOJA 1,DSKA2 ;NO. GO LOOK AT THE NEXT WORD OF BITS
;FOUND A CYLINDER WHOSE FREE COUNT IS NON-ZERO, AND ITS BITS INDICATE NO
;FREE PAGES. WARN THE OPERATOR AND PROHIBIT ASSIGNMENTS AND DEASSIGNMENTS
MOVE T1,STRN00 ;T1/ STRUCTURE NUMBER
MOVE T2,STRTAB(T1) ;POINT TO SDB FOR THIS STRUCTURE
LOAD T2,STRUC,(T2) ;GET UNIQUE CODE FOR THIS STRUCTURE
MOVE T3,Q3 ;GET CYLINDER NUMBER
BUG(DSKBT1,<<T2,STRCOD>,<T3,CYLNDR>>)
MOVX T3,MI%ASG ;SET BIT IN STRUCTURE STATUS WORD
IORM T3,SDBSTS(Q2) ; TO PROHIBIT ASSIGNMENTS AND DEASSIGNMENTS
CALL UMPBTB ;UNMAP INDEX BLOCK FROM BTBBAS, UNLOCK CORE PAGE
; UNLOCK BTBLCK, GO OKSKED
RETBAD IOX35 ;TAKE FAILURE RETURN
;HERE WHEN FREE PAGE HAS BEEN FOUND. MARK IF OFF IN THE BIT TABLE
;CONVERT IT TO A SECTOR NUMBER TO RETURN TO THE CALLER
; T1/ADDRESS OF WORD IN BIT HALF OF BIT TABLE
; T2/PAGE NUMBER WITHIN CYLINDER FOR BIT 0 OF CURRENT BIT WORD
; T3/CONTENTS OF WORD
; Q2/ADDRESS OF SDB
; Q1/ADDRESS OF SIZE DATA FOR THIS DISK TYPE
DSKA3: JFFO 3,.+1 ;FIND FIRST FREE BLOCK
MOVE 3,BITS(4) ;MAKE IT NO LONGER FREE
ANDCAM 3,0(1) ;CLEAR BIT
ADDI 2,0(4) ;PAGE NUMBER WITHIN THIS TRACK
IMUL 2,SECPAG(Q1) ;CONVERT TO SECTOR NUMBER
MOVE 1,Q3 ;RECOVER CYLINDER NUMBER
IMUL 1,SECCYL(Q1) ;COMPUTE LINEAR ADDRESS
ADD 1,2
TLO 1,(DSKAB) ;INDICATE DISK ADDRESS, NEWLY ASSIGNED
MOVEM 1,Q3 ;SAVE DISK ADDRESS
MOVE 1,STRN00 ;1/STRUCTURE NUMBER
CALL UMPBTB ;UNMAP INDEX BLOCK FROM BTBBAS, UNLOCK CORE PAGE
; UNLOCK BTBLCK, GO OKSKED
MOVE 1,Q3 ;RESTORE DISK ADDRESS
RETSKP
;THE SEARCH FOR THE BEST TRACK (DSKASN)
; Q2/ADDRESS OF SDB
; Q1/ADDRESS OF SIZE DATA FOR THIS DISK TYPE
DSKA1: MOVE 1,SDBMFP(Q2) ;GET MINIMUM LIMIT
MOVEM 1,MINFP0
MOVE 1,SDBLCA(Q2) ;START WITH LAST TRACK ASSIGNED
DSKSQ: SETZ 4, ;TO RECORD MAX FREE FOUND
MOVE 3,SDBCYL(Q2) ;NUMBER CYLINDERS TO LOOK AT
DSKA6: CAIGE 1,LOTRK ;LOOKING AT NON-NEGATIVE TRACK?
JRST [ ADD 1,CYLUNT(Q1);NO, LOOK AT NEXT PACK
JRST DSKA6]
CAML 1,SDBCYL(Q2) ;LOOKING WITHIN KNOWN CYLINDERS?
JRST [ IDIV 1,CYLUNT(Q1) ;NO, LOOK ON PACK 0...
MOVEI 1,1(2) ;NEXT CYLINDER
JRST DSKA6]
MOVE 2,BTBORA ;POINT TO START OF BIT TABLE
ADD 2,1 ;POINT TO WORD FOR THIS TRACK
CAML 4,0(2) ;THIS TRACK HAVE .G THAN BEST SO FAR?
JRST DSKA4 ;NO
MOVE 4,0(2) ;YES, REMEMBER COUNT
MOVEM 1,SDBLCA(Q2) ;REMEMBER WHAT TRACK HAD IT
CAML 4,MINFP0 ;GOOD ENOUGH TO QUIT?
JRST DSKA8 ;YES
DSKA4: SKIPN MINFP0 ;DOING FREE CHOICE?
AOSA T1 ;NO, LOOK ON NEXT TRACK
ADD 1,CYLUNT(Q1) ;LOOK ON NEXT DRIVE
SOJG 3,DSKA6 ;COUNT TRACKS EXAMINED
MOVEM 4,SDBMFP(Q2) ;REMEMBER NEW LOW VALUE
JUMPE 4,[MOVE 1,STRN00 ;IF ZERO, FOUND NO TRACK WITH FREE PAGE
CALL UMPBTB ;UNMAP INDEX BLOCK FROM BTBBAS, UNLOCK CORE PAGE
; UNLOCK BTBLCK, GO OKSKED
MOVE 1,Q3 ;RETURN ADDRESS REQUESTED
RETBAD IOX34] ;DISK FULL
DSKA8: MOVE 1,SDBLCA(Q2) ;GET TRACK
MOVE 4,BTBORA ;POINT TO START OF BIT TABLE
ADD 4,1 ;POINT TO WORD OF FREE PAGES FOR THIS TRACK
JRST DSKA9 ;GO SELECT PAGE ON THIS TRACK
;DSKASA - ASSIGN SPECIFIC DISK ADDRESS
;CYLASA - ASSIGN SPECIFIC CYLINDER (1 CYL OF DISK ADDRESSES)
;ACCEPTS:
; T1/SECTOR NUMBER ON DISK RELATIVE TO START OF STRUCTURE
; T2/STRUCTURE NUMBER
;RETURNS +1: FAILURE
; T1/ERROR CODE
; +2: SUCCESS
; T1/ DISK ADDRESS ASSIGNED
;THIS ROUTINE IS CALLED BY MONITOR CODE. IT BUGCHKS IF THE PAGE
;WAS ALREADY ASSIGNED
CYLASA::TDZA T3,T3 ;SAY CYLINDER
DSKASA::SETO T3,0 ;SAY SINGLE ADDRESS
ASUBR<DSKAD1,STRN20>
SE1CAL ;FORCE SECTION 1
CALL DSKASG ;GO DO THE ASSIGNMENT
JRST [ CAIE T1,DSKX08 ;FAILED. WAS IT ALREADY ASSIGNED?
RETBAD ;NO. SOME OTHER ERROR. DON'T BUGCHK
EXCH T1,STRN20 ;YES. GET STRUCTURE NUMBER AND SAVE ERROR
HRRZ T1,STRTAB(T1) ;POINT TO ITS SDB
LOAD T1,STRUC,(T1) ;GET ITS UNIQUE CODE
MOVE T2,DSKAD1 ;GET REQUESTED DISK ADDRESS
BUG(ASAASG,<<T1,STRCOD>,<T2,SECTOR>>)
MOVE T1,STRN20 ;RETRIEVE ERROR CODE
RETBAD] ;TAKE ERROR RETURN
RETSKP ;SUCCESS
;DSKASG - ASSIGN SPECIFIC DISK ADDRESS OR CYLINDER
;ACCEPTS:
; T1/SECTOR NUMBER ON DISK RELATIVE TO START OF STRUCTURE
; T2/STRUCTURE NUMBER
; T3/ -1 IF SINGLE DISK ADDRESS, 0 IF CYLINDER
;RETURNS +1: FAILURE
; T1/ERROR CODE
; +2: SUCCESS
; T1/ DISK ADDRESS ASSIGNED
;THIS ROUTINE IS CALLED DIRECTLY BY THE DSKAS JSYS. IT DOES NOT BUGCHK
;WHEN AN ADDRESS IS PASSED FOR A PAGE THAT IS ALREADY ASSIGNED. THIS
;IS BECAUSE CHECKD DELIBERATELY DOES THE DSKAS JSYS FOR PAGES THAT ARE
;ASSIGNED. IT DOES BUGCHK ON ILLEGAL DISK ADDRESS.
DSKASG: STKVAR <STRN01,DSKADR,ASGTYP>
MOVEM T1,DSKADR ;SAVE DISK ADDRESS
MOVEM T2,STRN01 ;SAVE STRUCTURE NUMBER
MOVEM T3,ASGTYP ;SAVE TYPE OF ASSIGN
MOVE T3,STRTAB(T2) ;POINT TO SDB FOR THIS STRUCTURE
MOVX T4,MI%ASG ;IF ASSIGNMENTS ARE PROHIBITED BECAUSE BIT
TDNE T4,SDBSTS(T3) ; TABLE IS BAD OR DOESN'T EXIST,
RETBAD (DSKX05) ; TAKE THE FAILURE RETURN
MOVE T1,T2 ;T1/STRUCTURE NUMBER
CALL MAPBTB ;MAP INDEX BLOCK INTO BTBBAS, LOCK INTO CORE,
; LOCK BTBLCK, GO NOSKED
MOVE T1,DSKADR ;T1/DISK ADDRESS
MOVE T2,STRN01 ;T2/STRUCTURE NUMBER
CALL DSKGX ;COMPUTE LOCATION IN BIT TABLE
; T1/OFFSET IN BIT PART OF BITTABLE, T2/TRACK
; NUMBER, T3/WORD CONTAINING BIT FOR THIS PAGE
JRST DSKAA2 ;BAD ADDRESS
EXCH Q1,ASGTYP ;GET TYPE
MOVE T4,STRN01 ;GET STRUCTURE NUMBER
MOVE T4,STRTAB(T4) ;POINT TO START OF SDB FOR THIS STRUCTURE
ADD T1,SDBBT0(T4) ;COMPUTE OFFSET IN BIT TABLE FOR BIT WORD
ADD T1,BTBORA ;COMPUTE ADDRESS OF BIT WORD
ADD T2,BTBORA ;POINT TO WORD CONTAINING FREE PAGE COUNT
JUMPN Q1,DSKAA3 ;ONLY SINGLE PAGE
MOVE Q1,SDBTYP(T4) ;FIND DISK TYPE
MOVE Q1,PAGCYL(Q1) ;GET PAGES PER CYL
DSKAA3: TDNN 3,0(T1) ;PAGE FREE?
JRST DSKAA1 ;NO. RETURN BAD
ANDCAM T3,0(T1) ;YES. ASSIGN IT
SOS 0(T2) ;REDUCE FREE COUNT FOR TRACK
SOS SDBFRC(T4) ;REDUCE FREE PAGE COUNT FOR STRUCTURE
SOJLE Q1,DSKATX ;DONE IF Q1 <0
ROT T3,-1 ;SHIFT 1 BIT
JUMPG T3,DSKAA3 ;DO NEXT BIT
AOJA T1,DSKAA3 ;NEXT WORD
DSKATX: EXCH Q1,ASGTYP ;RESTORE Q1
MOVE T1,STRN01 ;T1/STRUCTURE NUMBER
CALL UMPBTB ;UNMAP INDEX BLOCK FROM BTBBAS, UNLOCK CORE PAGE,
; UNLOCK BTBLCK, GO OKSKED
MOVE T1,DSKADR ;RESTORE SECTOR NUMBER
RETSKP ;TAKE SUCCESSFUL RETURN
;PAGE WAS ALREADY ASSIGNED
DSKAA1: EXCH Q1,ASGTYP ;RESTORE Q1
MOVE T1,STRN01 ;T1/STRUCTURE NUMBER
CALL UMPBTB ;UNMAP INDEX BLOCK FROM BTBBAS, UNLOCK CORE PAGE,
; UNLOCK BTBLCK, GO OKSKED
RETBAD (DSKX08) ;INDICATE PAGE ALREADY ASSIGNED
;ILLEGAL ADDRESS WAS SPECIFIED. GIVE BUGCHK AND TAKE FAILURE RETURN
DSKAA2: MOVE T1,STRN01 ;T1/STRUCTURE NUMBER
HRRZ T3,STRTAB(T1) ;POINT TO THE SDB FOR THIS STRUCTURE
LOAD T3,STRUC,(T3) ;GET ITS UNIQUE CODE
MOVE T2,DSKADR ;GET REQUESTED ADDRESS
BUG(ASGBAD,<<T3,STRCOD>,<T2,SECTOR>>)
CALL UMPBTB ;UNMAP INDEX BLOCK FROM BTBBAS, UNLOCK CORE PAGE,
; UNLOCK BTBLCK, GO OKSKED
RETBAD(DSKX06) ;INDICATE INVALID DISK ADDRESS
;DEDSKC - DEASSIGN DISK ADDRESS
;ACCEPTS:
; 1/LINEAR DISK ADDRESS (SECTOR NUMBER)
; 2/ SPTH VALUE FOR THE OFN
; 3/STRUCTURE NUMBER
; CALL DEDSKC
;RETURNS +1: ALWAYS
;THIS ROUTINE DEASSIGNS A DISK ADDRESS ONLY IF IT IS NOT BAD. IT CHECKS
;THE BAT BLOCKS TO SEE IF THE PAGE IS BAD.
DEDSKC::STKVAR<STRNO>
SE1CAL
MOVEM T3,STRNO ;SAVE STRUCTURE NUMBER
TXNE T2,OFNBAT ;DOES THIS OFN DESCRIBE A BAD PAGE?
JRST [ CALL CHKBAD ;YES. GO SEE IF THIS PAGE IS BAD
RET ;PAGE IS MARKED IN BAT BLOCKS. DON'T DEASSIGN
JRST .+1]
;THIS PAGE IS GOOD. RELEASE IT. T1 CONTAINS THE SECTOR NUMBER
MOVE T2,STRNO ;RESTORE STRUCTURE NUMBER
; AND FALL INTO DEDSK
;DEDSK - DEASSIGN A SPECIFIC ADDRESS, IGNORING BAT BLOCKS
;ACCEPTS:
; T1/SECTOR NUMBER RELATIVE TO START OF STRUCTURE
; T2/STRUCTURE NUMBER
; CALL DEDSK
;RETURNS +1:ALWAYS
;CALLED BY MONITOR ROUTINES (NOT DSKAS JSYS)
;BUGCHKS IF PAGE WAS NOT ASSIGNED
DEDSK:: ASUBR<DEDADR,DEDSTN>
SE1CAL
CALL DSKDEA ;DO IT
JRST [ CAIE T1,DSKX07 ;FAILED. WAS PAGE NOT ASSIGNED?
JRST .+1 ;NO. SOMETHING ELSE. DON'T BUGCHK
MOVE T1,DEDSTN ;YES. GET STRUCTURE NUMBER
HRRZ T1,STRTAB(T1) ;POINT TO ITS SDB
LOAD T1,STRUC,(T1) ;GET ITS UNIQUE CODE
MOVE T2,DEDADR ;GET REQUESTED DISK ADDRESS
BUG(DEAUNA,<<T1,STRCOD>,<T2,SECTOR>>)
JRST .+1]
RET ;RETURN +1 REGARDLESS OF RESULT
;DSKDEA - DEASSIGN A SPECIFID ADDRESS, IGNORING BAD BLOCKS
;ACCEPTS:
; T1/ SECTOR NUMBER RELATIVE TO START OF STRUCTURE
; T2/ STRUCTURE NUMBER (STRTAB INDEX)
;RETURNS +1: BAD ADDRESS OR IT WASN'T ASSIGNED OR BIT TABLE IS BAD
; T1/ERROR CODE
; +2: SUCCESS
;CALLED FROM DSKAS JSYS AS WELL AS FROM ABOVE - BUGCHKS ONLY ON ILLEGAL ADDRESS
DSKDEA: STKVAR<STRN02,DSKADR>
MOVEM T1,DSKADR ;SAVE SECTOR NUMBER
MOVEM T2,STRN02 ;SAVE STRUCTURE NUMBER
MOVE T3,STRTAB(T2) ;POINT TO START OF SDB FOR THIS STRUCTURE
MOVX T4,MI%ASG ;IF DEASSIGNMENTS ARE PROHIBITED BECAUSE BIT
TDNE T4,SDBSTS(T3) ; TABLE IS BAD OR DOESN'T EXIST,
RETBAD(DSKX05) ;TAKE THE FAILURE RETURN
MOVE T1,T2 ;T1/STRUCTURE NUMBER
CALL MAPBTB ;MAP INDEX BLOCK INTO BTBBAS, LOCK INTO CORE,
; LOCK BTBLCK, GO NOSKED
MOVE T1,DSKADR ;RESTORE SECTOR NUMBER
MOVE T2,STRN02 ;RESTORE STRUCTURE NUMBER
CALL DSKGX ;COMPUTE LOCATION IN BIT TABLE
; T1/OFFSET IN BIT PART OF BITTABLE, T2/TRACK
; NUMBER, T3/WORD CONTAINING BIT FOR THIS PAGE
JRST DSKDE2 ;BAD ADDRESS
MOVE T4,STRN01 ;GET STRUCTURE NUMBER
MOVE T4,STRTAB(T4) ;POINT TO START OF SDB FOR THIS STRUCTURE
ADD T1,SDBBT0(T4) ;OFFSET IN BIT TABLE FOR BIT WORD
ADD T1,BTBORA ;ADDRESS OF BIT WORD
TDNE 3,0(T1) ;PAGE ASSIGNED?
JRST DSKDE1 ;NO, RETURN BAD
IORM 3,0(T1) ;YES. UNASSIGN IT
ADD T2,BTBORA ;POINT TO WORD IN BIT TABLE FOR THIS TRACK
AOS 0(T2) ;INCREMENT COUNT OF FREE PAGES FOR THIS TRACK
AOS T1,SDBFRC(T4) ;INCREMENT FREE COUNT FOR THIS STRUCTURE
MOVE T2,SDBOMF(T4) ;GET ORIGINAL MINIMUM FREE PAGE VALUE
CAMLE T1,SDBMXF(T4) ;HAS THE FREE COUNT GONE ABOVE MINIMUM
MOVEM T2,SDBMFP(T4) ;YES, SET THE MINIMUM VALUE UP AGAIN
MOVE T1,STRN02 ;T1/STRUCTURE NUMBER
CALL UMPBTB ;UNMAP INDEX BLOCK FROM BTBBAS, UNLOCK CORE PAGE,
; UNLOCK BTBLCK, GO OKSKED
RETSKP ;TAKE SUCCESSFUL RETURN
;PAGE WAS NOT ASSIGNED
DSKDE1: MOVE T1,STRN02 ;T1/STRUCTURE NUMBER
CALL UMPBTB ;UNMAP INDEX BLOCK FROM BTBBAS, UNLOCK CORE PAGE,
; UNLOCK BTBLCK, GO OKSKED
RETBAD(DSKX07) ;INDICATE PAGE NOT ASSIGNED
;ILLEGAL ADDRESS WAS SPECIFIED. GIVE BUGCHK AND TAKE FAILURE RETURN
DSKDE2: MOVE T1,STRN02 ;T1/STRUCTURE NUMBER
HRRZ T3,STRTAB(T1) ;POINT TO ITS SDB
LOAD T3,STRUC,(T3) ;GET ITS UNIQUE CODE
MOVE T2,DSKADR ;GET THE REQUESTED ADDRESS
BUG(DEABAD,<<T3,STRCOD>,<T2,SECTOR>>)
CALL UMPBTB ;UNMAP THE BIT TABLE
RETBAD(DSKX06) ;INDICATE INVALID DISK ADDRESS
;CHKBAD - ROUTINE TO SEE IF DISK ADDRESS IS MARKED IN BAT BLOCKS
;ACCEPTS:
; T1/SECTOR NUMBER RELATIVE TO START OF STRUCTURE
; T3/STRUCTURE NUMBER
;CALL CHKBAD
;RETURNS +1: ADDRESS IS MARKED IN BAT BLOCKS
; +2: ADDRESS IS NOT MARKED IN BAT BLOCKS
; T1/SECTOR NUMBER
;USES FPG3A AS A WORK PAGE. LOCKS AND READS THE BAT BLOCK FOR THE
;APPROPRIATE DRIVE, AND LOOKS FOR THE GIVEN ADDRESS IN THE BAT BLOCKS
CHKBAD:SAVEP
MOVE P1,A ;SAVE ADDRESS
MOVE P5,C ;MOVE STRUCTURE NUMBER TO PERMANENT PLACE
TXZ A,DSKAB ;TURN OFF TYPE BIT
HRRZ B,STRTAB(P5) ;GET SDB FOR THIS STRUCTURE
IDIV A,SDBSIZ(B) ;COMPUTE UNIT AND ADDRESS
MOVE P2,A ;SAVE LOGICAL UNIT
MOVE P3,B ;SAVE LOCAL ADDRESS
HRRZ P4,STRTAB(P5) ;GET POINTER TO PS
MOVEI P4,SDBUDB(P4) ;GET FIRST SDBUDB INDEX
ADDI P4,0(A) ;POINTER TO THIS SDBUDB
HRRZ A,0(P4) ;GET UDB INDEX
CALL LKBAT ;LOCK THIS BAT BLOCK
JRST [ MOVE A,P1 ;NO. MUST BE GOOD THEN
RETSKP] ;SO GO DELETE IT
NOINT ;PREVENT LOCAL INTERRUPTS
MOVEI A,FPG3A ;GET A PAGE
CALL MLKMA ;LOCK IT DOWN
MOVE P2,A ;SAVE CORE PAGE NUMBER
LSH A,PGSFT ;MAKE IT A CORE ADDRESS
PUSH P,A ;SAVE VIRTUAL ADDRESS
CALL FNDCHN ;GET CKU VALUE (ARGUMENT IN P4)
POP P,B ;PHYSICAL PAGE
MOVEI C,FPG3A ;VIRTUAL ADDRESS
CALL GETBAT ;GET THE BAT BLOCKS
HRRZ C,0(P4) ;UDB POINTER
MOVEI B,FPG3A ;VIRTUAL PAGE
CALL VERBAT ;MAKE SURE THEY ARE GOOD
JRST ISGOOD ;NONE THERE. ASSUME PAGE IS GOOD
MOVE A,P3 ;ADDRESS
MOVEI B,FPG3A ;BAT BLOCK
MOVE C,P5 ;GET THE STRUCTURE NUMBER
HRRZ C,STRTAB(P5) ;GET POINTER TO STRUCTURE TABLE
MOVE C,SDBUDB(C) ;GET A UDB POINTER
CALL SEEADR ;SEE IF IN THERE
JRST ISGOOD
MOVE A,P2 ;CORE ADDRESS
CALL MULKCR ;RELEASE IT
OKINT ;ALLOW INTS AGAIN
HRRZ A,0(P4) ;UDB INDEX
CALL ULKBAT ;FREE THE BAT BLOCK
RETBAD ;LEAVE PAGE ASSIGNED
ISGOOD: MOVE A,P2 ;CORE PAGE
CALL MULKCR ;FREE IT
OKINT ;ALLOW INTS AGAIN
HRRZ A,0(P4) ;UDB INDEX
CALL ULKBAT ;FREE THE BAT BLOCK
MOVE A,P1
RETSKP ;GO RELEASE THEPAGE
;SPECIAL ROUTINE CALLED FROM PAGEM TO READ IN BAT BLOCKS FOR
;A GIVEN UNIT. ACCEPTS:
; 1/ UNIT
; 2/ CORE ADDRESS
; 3/ MEMORY ADDRESS
; 4/ STRUCTURE NUMBER
;RETURNS:
; +1/ NO BAT BLOCKS
; +2/ BAT BLOCKS READ IN BUT NOT LOCKED
RDBAT:: STKVAR <SAVUNT,SAVCOR,SAVMEM,SAVUDB>
SE1CAL
MOVEM A,SAVUNT
MOVEM B,SAVCOR
MOVEM C,SAVMEM
HRRZ A,STRTAB(D) ;PS
HRRI A,SDBUDB(A) ;THE UDB
ADD A,SAVUNT ;ADD IN UNIT
HRRZ A,0(A) ;GET UDB ADDRESS
MOVEM A,SAVUDB ;SAVE IT
CALL LKBAT ;LOCK IT
RET ;FAILED
MOVE C,SAVUDB ;GET UDB
CALL FNDCH1 ;GET CKU NUMBERS
MOVE B,SAVCOR
MOVE C,SAVMEM ;ARGS
CALL GETBAT ;GET BAT BLOCKS
MOVE C,SAVUDB ;GET UDB
MOVE B,SAVMEM ;THE MEMORY ADDRESS
CALL VERBAT ;VERIFY EM
SKIPA
AOS (P)
MOVE A,SAVUDB ;GET UDB
CALL ULKBAT ;FREE BAT LOCKS
RET ;DONE
;ROUTINE TO SEE IF LOCAL DISK ADDRESS IN A IS CONTAINED IN
;BAT BLOCK POINTED TO BY B
;ACCEPTS: 1/LOCAL DISK ADDRESS
; 2/BAT BLOCK VIRTUAL ADDRESS
; 3/UDB ADDRESS OF ONE DISK ON THIS STRUCTURE
;RETURNS:
; +1/ NOT IN BLOCK
; +2/ IN BLOCK , B= WORD ADDRESS OF PAIR A= REAL DISK ADDRESS
; (DISK ADDRESS UPDATED TO INCLUDE LOST SECTORS PER CYLINDER
SEEADR::SAVEPQ
SE1CAL
MOVE P2,B ;SAVE CORE ADDRESS
TLZ C,-1 ;CLEAR JUNK IN LEFT HALF
MOVE P4,UDBSIZ(C) ;GET POINTER TO DSKSIZ ENTRY
PUSH P,A ;SAVE DISK ADDRESS
MOVE P1,A ;SET CORRECT DISK SIZE
MOVEI A,0(P2) ;POINTER TO BAT BLOCK
CALL BATSPC ;GET SPACE REMAINING
CAIN A,-MAXBFR ;ANY THERE?
JRST [ POP P,A ;NO. NOT IN BLOCK THEN
RET]
ADDI A,MAXBFR ;DO SUBTRACT
MOVNI A,0(A) ;GET NEGATIVE OF DIFFERENCE
ASH A,-1 ;DIVIDE BY TWO
HRLI B,0(A) ;GET NEG NUMBER OF PAIRS
HRRI B,BAT1P(P2) ;FIRST BAD PAIR
MOVE P2,SECPAG(P4) ;GET SECTORS PER PAGE
DOABAD: LOAD C,BADT,(B) ;GET TYPE OF THIS BAD PAIR
SKIPE C ;OLD OR NEW
JRST [ LOAD C,ADD27,(B) ;NEW GET LONG ADDRESS
JRST DOABA1]
LOAD C,ADD18,(B) ;OLD, GET SHORT ADDRESS
DOABA1: LOAD D,BATNB,(B) ;GET NUMBER IN THIS REGION
PUSH P,D ;SAVE NUMBER
MOVEM C,D ;STORE ADDRESS
MOVE A,SECCYL(P4) ;GET NUMBER OF SECTORS
ADD A,LPPCYL(P4) ; IN ONE CYLINDER
IDIV D,A ;GET NUMBER OF CYLINDERS IN PHYSICAL ADDRESS
IMUL D,LPPCYL(P4) ;GET NUMBER OF LOST SECTORS
SUB C,D ;TRANSLATE TO LOGICAL
POP P,D ;RESTORE NUMBER OF BLOCKS
ADD D,C ;GET LAST ONE
TRZ C,-1(P2) ;TRUNCATE TO PAGE BOUNDARY
CAML P1,C ;WITHIN THE RANGE?
CAMLE P1,D ;" ?
SKIPA ;NO
JRST [ POP P,T1
RETSKP]
AOS B ;TWO WORDS PER PAIR
AOBJN B,DOABAD ;DO ALL REGIONS
CALLRET PA1 ;NOT THERE
;ROUTINE TO CALCULATE SPACE LEFT IN BAT BLOCK. ACCEPTS:
; A/ ADDRESS OF BAT BLOCK
;RETURNS: +1 WITH A/SPACE LEFT
RESCD(INIT) ;MUST BE RESIDENT
BATSPC: LOAD B,BTHCT,(A) ;GET ENTRIES USED BY MAPPER
LOAD C,BTMCT,(A) ;PAIRS ADDED BY MONITOR
ADDI B,0(C) ;TOTAL PAIRS USED
LSH B,1 ;2 WORDS PER PAIR
MOVEI A,-MAXBFR(B) ;GET NEG OF SPACE
TRNN A,1B18 ;OVERFLOW?
SETZ A, ;YES. SAY NO ROOM LEFT
RET ;AND DONE
;THESE ROUTINES LOCK AND UNLOCK BAT BLOCKS.
;ACCEPTS: 1/UDB POINTER
;RETURNS: +1/ UNIT HAS NO BAT BLOCKS
; +2/BAT BLOCKS LOCKED
SWAPCD ;IS SWAPPABLE
LKBAT:: MOVX B,US.BAT ;FIRST SEE IF IT HAS BAT BLOCKS
SE1CAL
TDNE B,UDBSTS(A) ;DOES IT?
RET ;NO
MOVX B,US.BLK ;GET THE BIT
NOSKED ;PROTECT IT
TDNE B,UDBSTS(A) ;IS IT ALREADY LOCKED?
JRST CANT ;YES. ARRANGE FOR A BLOCK
IORM B,UDBSTS(A) ;NO. LOCK IT THEN
OKSKED
RETSKP ;RETURN WITH IT LOCKED
CANT: HRLI A,0(A) ;UNIT NUMBER TO LH
HRRI A,BATTST ;TEST ADDRESS
RDISMS ;AND GO INTO SCHEDULER WAIT
RETSKP
;SCHEDULER TEST FOR BAT BLCOK AVAILABLE
RESCD
BATTST: MOVX B,US.BLK ;THE BIT
TDNE B,UDBSTS(A) ;FREE NOW?
JRST 0(4) ;NO. BLOCK AGAIN
IORM B,UDBSTS(A) ;YES. LOCK IT
JRST 1(4) ;AND WAKE UP
SWAPCD
;ROUTINE TO UNLOCK A BAT BLOCK
;ACCEPTS 1/UDB POINTER
ULKBAT::MOVX B,US.BLK ;THE BIT
SE1CAL
ANDCAM B,UDBSTS(A) ;CLEAR LOCK
RET ;AND RETURN
;COMPUTE INDEX INTO BIT TABLE
;ACCEPTS:
; T1/SECTOR NUMBER RELATIVE TO START OF STRUCTURE
; T2/STRUCTURE NUMBER
;RETURNS +1: INVALID ADDRESS
; +2: VALID ADDRESS
; T1/OFFSET IN BIT PART OF BIT TABLE FOR DESIRED TRACK
; T2/TRACK NUMBER
; T3/WORD WITH BIT CORRESPONDING TO THIS PAGE SET
;CALLED AFTER A CALL TO MAPBTB, WHICH MAPS THE BIT TABLE FOR THIS STRUCTURE
;AND GOES NOSKED
SWAPCD
DSKGX: MOVE T3,STRTAB(T2) ;POINT TO SDB FOR THIS STRUCTURE
MOVE T4,SDBTYP(T3) ;POINT TO DSKSIZ TABLE FOR THIS DISK TYPE
TLZ T1,DSKMSK ;FLUSH RANDOM BITS
IDIV T1,SECCYL(T4) ;1/CYLINDER, 2/SECTOR WITHIN CYLINDER
CAML T1,SDBCYL(T3) ;WITHIN KNOWN CYLINDERS FOR THIS STRUCTURE?
RET ;NO.
CAML T1,SDBBT0(T3) ;WITHIN TOP HALF OF BIT TABLE?
RET ;NO, RETURN NO-SKIP
CAIGE T1,LOTRK ;NON-NEGATIVE CYLINDER NUMBER?
RET ;NO
MOVE T3,PAGCYL(T4) ;GET PAGES PER CYLINDER
IMUL T3,SECPAG(T4) ;COMPUTE NUMBER SECTORS IN COMPLETE PAGES
CAML T2,T3 ;IS THIS SECTOR WITHIN A FULL PAGE (POSSIBLE
; EXTRA SECTORS AT END OF CYLINDER)?
RET ;NO
PUSH P,T1 ;SAVE TRACK NUMBER
IMUL T1,BTWCYL(T4) ;INDEX TO FIRST WORD OF BITS
IDIV T2,SECPAG(T4) ;CONVERT SECTOR TO PAGE WITHIN CYLINDER
IDIVI T2,^D36 ;GET INDEX TO BIT WORD WITHIN CYLINDER
ADDI T1,0(T2) ;T1/OFFSET OF BIT WORD FOR THIS PAGE
POP P,T2 ;T2/CYLINDER NUMBER
MOVE T3,BITS(T3) ;T3/BIT FOR THIS PAGE
RETSKP
;CREATE THE BIT TABLE
;ACCEPTS:
; T1/STRUCTURE NUMBER
;RETURNS +1: FAILURE (FATAL ERROR FROM CRTBTB)
; +2: SUCCESS
;CALLED WHEN A STRUCTURE IS BEING CREATED OR ITS BIT TABLE
;IS BEING RECREATED. INITIALIZES THE BIT TABLE
;IN CORE, LEAVING THE SDB POINTING TO THE IN-CORE PAGE TABLE
;ASSIGNS SPACE FOR HOME BLOCKS AND SWAPPING SPACE
;EXITS OKSKED WITH BIT TABLE UNLOCKED AND SPT(BTBBAS) CLEARED.
CRTBTB::STKVAR<STRN03,BTBMAP,CRTBER>
SE1CAL
MOVEM T1,STRN03 ;SAVE STRUCTURE NUMBER
NOSKED ;NOSKED WHILE INITING THE BIT TABLE
CALL ASSPTL ;ASSIGN SPT SLOT; INIT TO USHR AND UAAB; PUT
; FORK INDEX IN SPTH; RETURN OFFSET IN AC1
MOVEM T1,BTBMAP ;SAVE SPT SLOT FOR TEMPORARY PAGE TABLE
MOVE T2,STRN03 ;GET STRUCTURE NUMBER
MOVE T2,STRTAB(T2) ;POINT TO START OF SDB FOR THIS STRUCTURE
MOVEM T1,SDBBTB(T2) ;SAVE SPT INDEX FOR PAGE TABLE IN SDB
HLL T1,SHRPTR ;MAKE SHARE POINTER
MOVEM T1,MSECTB+BTSEC ;SET IN SECTION POINTER
CALL MONCLR ;CLEAR PAGER
MOVE T1,BTBMAP ;FIND SPT
CALL SWPIN1 ;GET A CORE PAGE, MAKE SPT POINTED TO BY T1 POINT
; TO THE PAGE, LOCK IT IN CORE
MOVE T1,BTBMAP ;T1/SPT INDEX FOR PAGE TABLE FOR BIT TABLE
CALL LCKBTB ;LOCK THE LOCK AND MAKE BTBBAS POINT TO PAGE TABLE
SETZM CRTBER ;INDICATE NO ERRORS INITIALLY
MOVE T1,STRN03 ;T1/STRUCTURE NUMBER
CALL INIBTB ;SET INITIAL VALUES IN BIT TABLE
SETOM CRTBER ;INDICATE ERROR
MOVE T1,STRN03 ;T1/STRUCTURE NUMBER
CALL UMPBTB ;UNMAP INDEX BLOCK FROM BTBBAS, UNLOCK CORE PAGE,
; UNLOCK BTBLCK, GO OKSKED
SKIPE CRTBER ;DID WE ENCOUNTER ANY ERRORS?
RETBAD ;YES. TAKE FAILURE RETURN
RETSKP ;NO. TAKE SUCCESS RETURN
;INITIALIZE BIT TABLE
;ACCEPTS:
; T1/STRUCTURE NUMBER
;RETURNS +1: FATAL ERROR (FAILED TO ASSIGN HOME BLOCK OR SWAPPING SPACE)
; +2: SUCCESS
;THIS ROUTINE INITIALIZES THE BIT TABLE THAT IS CURRENTLY POINTED TO
;BY THE STRUCTURE'S SDB. NORMALLY IT IS CALLED BY CRTBTB, WHICH HAS
;OBTAINED A PAGE IN CORE TO SERVE AS A PAGE TABLE TO AN ADDRESS SPACE.
;IT CAUSES ALL PAGES TO BE AVAILABLE AND THEN ASSIGNS THOSE PAGES THAT
;BELONG TO THE HOME BLOCKS AND SWAPPING SPACE. IT ALSO ASSIGNS PAGES THAT
;ARE POINTED TO BY THE BAT BLOCKS.
;CALLED NOSKED WITH SPT(BTBBAS) SET UP AND BTBLCK LOCKED
INIBTB::SAVEPQ
SE1CAL
STKVAR<STRN04,SVPAIR,SVADR1,SVADR2,STRTPT,LSTPAG,INIER1,INIER2>
SETZM INIER1 ;INDICATE NO FATAL ERRORS YET
SETZM INIER2 ;INDICATE NO BAT BLOCK FAILURES YET
MOVEM T1,STRN04 ;SAVE STRUCTURE NUMBER
MOVE T4,STRTAB(T1) ;POINT TO START OF SDB FOR THIS STRUCTURE
MOVE T1,SDBTYP(T4) ;POINT TO SIZE DATA FOR THIS DISK TYPE
MOVEM T1,STRTPT ;SAVE POINTER
;INITIALIZE TOP HALF OF BIT TABLE (CONTAINS COUNT OF FREE PAGES PER CYLINDER).
;SET EACH WORD TO INDICATE ALL PAGES AVAILABLE.
MOVE T1,PAGCYL(T1) ;GET NUMBER OF PAGES PER CYLINDER
MOVN T2,SDBBT0(T4) ;GET SIZE OF TOP HALF OF BIT TABLE
HRLZS T2 ;T2/(-COUNT,,OFFSET IN TOP HALF)
INIBT2: MOVEI T3,0(T2) ;GET OFFSET
ADD T3,BTBORA ;ADDRESS OF CURRENT WORD
MOVEM T1,0(T3) ;STORE FULL COUNT FOR EACH TRACK
AOBJN T2,INIBT2 ;GO TO NEXT WORD
;INITIALIZE BOTTOM OF BIT TABLE. CONTAINS 1 BIT PER PAGE, WITH EACH NEW
;CYLINDER STARTING A NEW WORD. CURRENTLY EACH CYLINDER HAS 3 WORDS WITH
;THE THIRD ONLY PARTIALLY USED. THIS CODE INITIALIZES THE FIRST 3 TO
;INDICATE ALL PAGES FREE (THEIR CORRESPONDING BITS SET) AND BLTS TO THE
;REST OF THE TABLE
MOVE T2,SDBBT0(T4) ;START AT BEGINNING OF BIT PART OF BIT TABLE
ADD T2,BTBORA ;COMPUTE ADDRESS OF FIRST BIT WORD
INIBT1: SETOM 0(T2) ;INIT ONE TRACK OF BITS
SUBI 1,^D36 ;REDUCE COUNT OF PAGES (1 BIT PER PAGE)
CAILE 1,^D36 ;LAST WORD?
AOJA 2,INIBT1 ;NO. GO INITIALIZE IT
MOVN 1,BITS-1(1) ;LAST WORD PARTIALLY FULL. SET ONLY VALID BITS
MOVEM T1,1(T2) ;STORE LAST WORD FOR FIRST TRACK
MOVE T2,BTBORA ;CONSTRUCT STARTING LOCATIONS FOR BLT
ADD T2,SDBBT0(T4) ;GET SIZE OF TOP HALF OF BIT TABLE
MOVE T3,T2 ;MAKE DESTINATION POINTER
MOVE T1,STRTPT ;POINT TO SIZE DATA FOR THIS DISK TYPE
ADD T3,BTWCYL(T1) ;2ND GROUP OF WORDS
MOVN T1,BTWCYL(T1) ;FIND OFFSET INTO SECOND GROUP
ADD T1,SDBBT1(T4) ;FIND LENGTH OF TRANSFER
CALL XBLTA ;COPY GROUPS OF BIT WORDS TO REST OF TABLE
SETOM BTBLCK ;CLEAR LOCK BECAUSE DSKASA WILL SET IT.
; WE ARE STILL NOSKED
;ASSIGN SPACE FOR THE HOME BLOCKS
MOVE Q1,STRN04 ;GET STRUCTURE NUMBER
MOVE Q1,STRTAB(Q1) ;POINT TO START OF SDB FOR STRUCTURE
MOVE P2,SDBTYP(Q1) ;POINT TO SIZE DATA FOR THIS DISK TYPE
MOVSI Q3,-NHOME ;Q3/(-COUNT,,OFFSET TO HOME TABLE)
SETOM LSTPAG ;INITIALIZE LAST PAGE ASSIGNED
;LOOP OVER SPECIAL SECTORS IN HOME BLOCK TABLE
HOMAS1: MOVE T1,HOME(Q3) ;GET SECTOR NUMBER WITHIN UNIT
IDIV T1,SECPAG(P2) ;CONVERT TO PAGE
CAMN T1,LSTPAG ;SAME AS LAST PAGE ASSIGNED?
JRST HOMAS3 ;YES. DON'T ASSIGN IT AGAIN
;ASSIGN THIS PAGE FOR ALL UNITS
MOVEM T1,LSTPAG ;SAVE LAST PAGE ASSIGNED
MOVN Q2,SDBNUM(Q1) ;NO. GET NUMBER OF UNITS IN STRUCTURE
HRLZS Q2 ;Q2/(-COUNT,,UNIT NUMBER)
HOMAS2: MOVEI T1,0(Q2) ;GET UNIT NUMBER
IMUL T1,SECUNT(P2) ;COMPUTE FIRST SECTOR IN THIS UNIT
ADD T1,HOME(Q3) ;T1/SECTOR TO ASSIGN
MOVE T2,STRN04 ;T2/STRUCTURE NUMBER
CALL DSKASA ;ASSIGN THE PAGE
SETOM INIER1 ;INDICATE A FATAL ERROR
AOBJN Q2,HOMAS2 ;LOOP TO NEXT UNIT IN STRUCTURE
HOMAS3: AOBJN Q3,HOMAS1 ;LOOP TO NEXT SPECIAL SECTOR
;ASSIGN PAGES FOR SWAPPING. SDB INDICATES HOW MANY PAGES
;IF NONE, SWPASN RETURNS NORMALLY
MOVE T1,STRN04 ;T1/ STRUCTURE NUMBER
CALL SWPASN ;ALLOCATE PAGES FOR SWAPPING SPACE
SETOM INIER1 ;INDICATE FATAL ERROR
; ..
; ..
; NOW READ IN ALL OF THE BAT BLOCKS AND MARK EACH RECORDED
;BAT BLOCK IN THE NEW BIT TABLE
; SETZ P2,
MOVEI A,FPG3A ; GET A PAGE TO WORK WITH
CALL MLKMA ;LOCK IT
LSH A,PGSFT ;MAKE IT A CORE ADDRESS
MOVE P1,A ;SAVE IT
MOVE A,STRN04 ;GET STRUCTURE NUMBER
HRRZ A,STRTAB(A) ;GET SDB FOR THIS STRUCTURE
MOVN P4,SDBNUM(A) ;NUMBER OF PACKS
MOVSI P4,0(P4) ;TO THE LEFT HALF
HRRI P4,SDBUDB(A) ;FIRST UDB POINTER
PACKS: HRRZ A,0(P4) ;GET UDB POINTER
CALL LKBAT ;LOCK UP THE BAT BLOCKS
JRST CYCLE ;NONE THERE
CALL FNDCHN ;GET CKU VALUE
MOVE P2,T1 ;SAVE IT
MOVE B,P1 ;PAGE ADDRESS
MOVEI C,FPG3A ;THE VIRTUAL ADDRESS
CALL GETBAT ;GET AND VERIFY BAT BLOCKS
MOVEI B,FPG3A ; CORE ADDRESS
HRRZ C,0(P4) ;UDB ADDRESS
CALL VERBAT ; GO VERIFY THE BATS
JRST [ HRRZ A,0(P4) ;UDB ADDRESS
CALL ULKBAT ;FREE THE BAT BLOCK
JRST CYCLE] ;AND DONE
MOVEI A,FPG3A ;BAT BLOCK ADDRESS
CALL BATSPC ;GET SPACE USED
MOVEI P3,MAXBFR(A) ;SPACE USED
JUMPE P3,CYCLE0 ; NONE HERE IF A ZERO
LSH P3,-1 ;CALCULATE NUMBER OF PAIRS
MOVEI C,BAT1P+FPG3A ;FIRST BAD BLOCK PAIR
DOBAD: LOAD A,BADT,(C) ; GET TYPE OF THIS BLOCK
SKIPN A
JRST [ LOAD A,ADD18,(C) ;GET 18 BIT ADDRESS
JRST GOTADR] ;AND GO IN LINE
LOAD A,ADD27,(C) ;GET 27 BIT ADDRESS
GOTADR: LOAD B,BATNB,(C) ;GET NUMBER OF BAD ONES
ADD B,A ;
MOVEM C,SVPAIR ;SAVE BAD PAIR INDEX
MOVE D,STRN04 ;GET STRUCTURE NUMBER
HRRZ D,STRTAB(D) ;POINT TO START OF SDB FOR THIS STRUCTURE
MOVEI C,0(P4) ;THIS ONE
SUBI C,SDBUDB(D)
IMUL C,SDBSIZ(D)
ADD A,C ; MAKE THIS LINEAR
ADD B,C ; AND THIS TOO
MOVEM B,SVADR1 ;SAVE LAST ADDRESS
TOPASG: MOVEM A,SVADR2 ; SAVE ADDRESS
TRZ A,3
SUB A,SDBFSS(D) ; SUB XDR OF START OF SWAPPING SECTRS
SKIPL A ; IF <0 THEN XDR IS NOT IN SWAPPING AREA
CAML A,SDBNSS(D) ; IF 0 <= A < # SWPPNG SCTRS ==> IN SWPING AREA
JRST [ MOVE A,SVADR2 ; NOT IN SWPNG AREA, GET BAD SECTOR ADDRESS
MOVE D,STRTPT ;GET SIZE DATA
MOVE B,SECCYL(D);GET NUMBER OF SECTORS
ADD B,LPPCYL(D) ; IN A CYLINDER
IDIV A,B ;NUMBER OF CYLINDERS
IMUL A,LPPCYL(D);NUMBER OF LOST SECTORS
MOVE D,SVADR2 ;GET BACK ADDRESS
SUBM D,A ;TRANSLATE TO LOGICAL
MOVE B,STRN04 ;2/STRUCTURE NUMBER
CALL DSKASA ; ASSIGN IT
AOS INIER2 ;COUNT NUMBER OF FAILURES FOR BAD PAGES
MOVE D,STRN04 ; GET BACK STRUCTURE NUMBER
HRRZ D,STRTAB(D) ; AND THEN GET START OF SDB FOR STRUCTURE
JRST .+1]
MOVE A,SVADR2 ; GET BACK BAD SECTOR ADDRESS
MOVE B,STRTPT ;POINT TO SIZE DATA FOR THIS DISK TYPE
ADD A,SECPAG(B) ; MOVE TO NEXT PAGE
CAMG A,SVADR1 ; OVER THE END?
JRST TOPASG ; NO
MOVE C,SVPAIR ; RESTORE BAD PAIR INDEX
ADDI C,2 ; TO NEXT PAIR
SOJG P3,DOBAD
CYCLE0: HRRZ A,0(P4) ;UDB ADDRESS
CALL ULKBAT ;FREE THE BAT BLOCK
CYCLE: AOBJN P4,PACKS ;DO ALL PACKS
MOVE A,P1 ; GET CORE ADDRESS
LSH A,-PGSFT ;MAKE IT A PAGE NUMBER
CALL MULKCR ;UNLOCK IT
MOVE A,STRN04
CALL DSKSP ;GET NEW FREE COUNT
MOVE 1,STRN04 ;GET STRUCTURE NUMBER
MOVE 1,STRTAB(1) ;POINT TO START OF SDB FOR THIS STRUCTURE
MOVEM 2,SDBFRC(1) ;UPDATE COUNT OF FREE PAGES FOR STRUCTURE
SKIPE INIER1 ;WERE THERE ANY FATAL ERRORS?
RETBAD(MSTX28) ;YES. RETURN 'FAILED TO INIT BIT TABLE'
SKIPE T2,INIER2 ;NO. WERE ANY BAD PAGES NOT ASSIGNED?
JRST [ MOVE T1,STRN04 ;YES. GET THE STRUCTURE NUMBER
MOVE T1,STRTAB(T1) ;POINT TO START OF SDB FOR THIS STRUCTURE
LOAD T1,STRUC,(T1) ;GET UNIQUE CODE FOR THIS STRUCTURE
BUG(ASGBPG,<<T1,STRCOD>,<T2,AMOUNT>>)
JRST .+1]
RETSKP ; AND DONE
;WRTBTB - WRITE THE BIT TABLE
;ACCEPTS:
; T1/STRUCTURE NUMBER
;RETURNS +1: FAILED
; +2: SUCCEEDED
;WHEN THIS IS CALLED, SDBBTB POINTS TO TEMPORARY PAGE TABLE, WHICH
;CONTAINS POINTERS TO THE IN-CORE COPY OF THE BIT TABLE. THIS ROUTINE
;MAPS THE BIT TABLE INTO A FILE, WHICH IT CREATES, AND DESTROYS THE
;IN-CORE COPY. IT MAKES SDBBTB CONTAIN THE OFN FOR THE NEW FILE
WRTBTB::SAVEQ
SE1CAL
STKVAR<STRN05,BTJFN3,BTBFIL,BTBPT>
MOVEM T1,STRN05 ;SAVE THE STRUCTURE NUMBER
;CONSTRUCT A FILE SPEC FOR THE NEW BIT TABLE FILE CONTAINING THE STRUCTURE
;NAME AND GET A JFN
MOVX T2,GJ%FOU!GJ%PHY!GJ%SHT ;NEXT GENERATION,PHYSICAL,SHORT
CALL GETBTB ;BUILD THE FILE SPEC AND GET A JFN
RETBAD ;FAILED
MOVEM T1,BTJFN3 ;SAVE THE JFN
;OPEN THE FILE AND SET THE NO-DUMP BIT IN THE FDB FOR DUMPER WON'T DUMP FILE
MOVX T2,OF%RD!OF%WR!OF%THW ;T2/READ, WRITE, THAWED ACCESS
OPENF ;OPEN THE BIT TABLE FILE
JRST WRTBT2 ;FAILED
MOVEI T2,.FBCTL ;OFFSET OF FLAG WORD IN FDB
MOVE T1,BTJFN3 ;T1/JFN IN RH
STOR T2,CF%DSP,T1 ;T1/OFFSET IN FDB IN LH
MOVX T2,FB%NOD ;T2/MASK OF BITS TO BE AFFECTED
MOVX T3,FB%NOD ;T3/NEW VALUE - SET NO DUMP
CHFDB ;CHANGE THE FDB TO REFLECT NO DUMP
ERJMP WRTBT5 ;FAILED - GO CLOSE THE FILE
;GET SOME INFORMATION ABOUT THE FILE
MOVE T1,BTJFN3 ;T1/JFN
MOVE T2,[3,,.FBCTL] ;T2/(COUNT,,FIRST WORD)
MOVEI T3,Q1 ;T3/DESTINATION
GTFDB ;GET SOME INFO ON THE FILE
ERJMP WRTBT5 ;FAILED. GO CLOSE THE FILE
TXNE Q1,FB%LNG ;IS IT A LONG FILE?
BUG(WRTLNG)
MOVE T1,Q3 ;T1/ADDRESS OF INDEX BLOCK
TXO T1,THAWB+FILWB ;OPEN THAWED WITH WRITE ACCESS
;..
;GET AN OFN FOR THE FILE TO UPDATE THE SHARE COUNT SO THAT CLOSING
;IT WON'T GET RID OF THE OFN
;..
MOVE T2,STRN05 ;T2/STRUCTURE NUMBER
CALL ASROFN ;ASSIGN OFN
JRST WRTBT3 ;FAILED. THIS SHOULD NOT HAPPEN IF OPENF SUCCEEDED
MOVEM T1,BTBFIL ;SAVE THE OFN FOR THE FILE
MOVE T1,BTJFN3 ;T1/JFN
CLOSF ;CLOSE THE FILE TO GET RID OF THE JFN (OFN REMAINS)
JFCL
;GET THE SPT INDEX FOR THE TEMPORARY PAGE TABLE
MOVE T1,STRN05 ;GET STRUCTURE NUMBER
MOVE T1,STRTAB(T1) ;POINT TO START OF SDB FOR THIS STRUCTURE
MOVE T2,SDBBTB(T1) ;GET SPT INDEX FOR PAGE TABLE
MOVEM T2,BTBPT ;SAVE IT
;COPY THE IN-CORE BIT TABLE TO THE NEW FILE
MOVE Q2,SDBBT0(T1) ;GET SIZE OF TOP HALF OF BIT TABLE
MOVEM Q2,Q3 ;SAVE IT FOR LATER
ADD Q2,SDBBT1(T1) ;ADD SIZE OF BOTTOM HALF
ADDI Q2,<PGSIZ-1> ;ROUND TO END OF PAGE
IDIVI Q2,PGSIZ ;CONVERT TO NUMBER OF PAGES
MOVN Q1,Q2 ;-NUMBER OF PAGES IN BIT TABLE FILE
HRLZS Q1 ;Q1/(-PAGE COUNT,,0)
;LOOP THROUGH ALL PAGES IN THE FILE,MAPPING THE CORE PAGE INTO THE FILE.
;MAP IT BACK BECAUSE THE IN-CORE COPY IS BEING USED WHEN SETPT CALLS DSKASN,
;AND THE CORE-TO-FILE MAP DESTROYS THE CORE CONTENTS.
WRTBT1: NOSKED
HRLZ T1,BTBPT ;T1/(PTN,,PN)
HRR T1,Q1
HRLZ T2,BTBFIL ;T2/(OFN,,PN)
HRR T2,Q1
MOVX T3,PTRW ;T3/READ, WRITE ACCESS
CALL SETPT ;MAP PAGE TO FILE
EXCH T1,T2
CALL SETPT ;MAP FILE TO PAGE
OKSKED
AOBJN Q1,WRTBT1 ;AT END OF TABLE YET?
;..
;ALL PAGES MAPPED. MAKE THE SDB POINT TO THE FILE AND GET RID OF THE
;IN-CORE PAGES, INCLUDING THE PAGE TABLE
;..
MOVE T1,BTBFIL ;YES. GET OFN FOR FILE
MOVE T2,STRN05 ;GET STRUCTURE NUMBER
MOVE T2,STRTAB(T2) ;POINT TO START OF SDB FOR THIS STRUCTURE
MOVEM T1,SDBBTB(T2) ;SAVE THE OFN IN THE SDB
SETZM T1 ;T1/ TO INDICATE CLEAR THE PAGE TABLE
HRLZ T2,BTBPT ;T2/ (OFN,,PN)
MOVE T4,Q2 ;T4/NUMBER OF PAGES
CALL MSETPT ;CLEAR THE TEMPORARY PAGE TABLE
NOP
MOVE T1,BTBPT ;T1/SPT ENTRY FOR PAGE TABLE
CALL DESPT ;RELEASE THE SPT SLOT
MOVE T1,STRN05 ;T1/STRUCTURE NUMBER
CALL CPYBAK ;UPDATE BACKUP OF ROOT-DIRECTORY TO SHOW
; THE NEW BIT TABLE FILE
JRST [ MOVE T1,STRN05 ;GET STRUCTURE NUMBER
MOVE T1,STRTAB(T1) ;POINT TO SDB FOR THIS STRUCTURE
LOAD T1,STRUC,(T1) ;GET UNIQUE CODE
BUG(WRTCPB,<<T1,STRCOD>>)
JRST .+1]
MOVE T1,STRN05 ;T1/STRUCTURE NUMBER
MOVEI T2,HOMBTB ;T2/OFFSET IN HOME BLOCK FOR WORD TO CHANGE
MOVE T3,STRN05 ;GET STRUCTURE NUMBER
MOVE T3,STRTAB(T3) ;POINT TO SDB FOR THIS STRUCTURE
MOVE T3,SDBBT0(T3) ;T3/SIZE OF TOP HALF OF BIT TABLE
HRROI T4,-1 ;CHANGE ENTIRE WORD
CALL MODHOM ;REWRITE THE HOME BLOCK TO INDICATE THE
; NEW SIZE OF THE BIT TABLE
RETBAD(MSTRX6) ;INDICATE HOME BLOCKS ARE BAD
HRLZ T1,BTBFIL ;OFN,,0
MOVEI T2,1000
CALL UPDPGS ;UPDATE FILE PAGES
MOVE T1,BTBFIL
CALL UPDOFN ;UPDATE OFN ALSO
RETSKP
;ERROR AFTER GTJFN BUT BEFORE OPENF. RELEASE THE JFN
WRTBT2: MOVEM T1,STRN05 ;SAVE ERROR CODE IN TEMPORARY LOCATION
MOVE T1,BTJFN3 ;T1/JFN OF BIT TABLE FILE
RLJFN ;RELEASE THE JFN
JFCL ;IGNORE FAILURE
MOVE T1,STRN05 ;RESTORE ERROR CODE
RETBAD ;TAKE NON-SKIP RETURN
;ASOFN FAILED WHEN OPENF SUCCEEDED. SOMETHING IS REALLY WRONG...
WRTBT3: MOVE T2,STRN05 ;GET STRUCTURE NUMBER
HRRZ T2,STRTAB(T2) ;POINT TO ITS SDB
LOAD T2,STRUC,(T2) ;GET ITS UNIQUE CODE
BUG(WRTBT4,<<T2,STRCOD>>)
;ERROR OCCURRED AFTER OPENF AND BEFORE CLOSF. CLOSE THE FILE
WRTBT5: MOVEM T1,STRN05 ;SAVE ERROR CODE IN TEMPORARY LOCATION
MOVE T1,BTJFN3 ;T1/JFN FOR BIT TABLE FILE
CLOSF ;CLOSE THE FILE
JFCL ;IGNORE FAILURE
MOVE T1,STRN05 ;RESTORE ERROR CODE
RETBAD ;TAKE NON-SKIP RETURN
;MNTBTB - MOUNT THE BIT TABLE
;ACCEPTS:
; T1/STRUCTURE NUMBER
;RETURNS +1: FAILED TO FIND BIT TABLE
; +2: SUCCEEDED
;CALLED WHEN STRUCTURE IS BEING MOUNTED AND BY JOB 0 FOR ALL STRUCTURES MOUNTED AT
;SYSTEM STARTUP. GETS AN OFN FOR THE BIT TABLE FILE AND STORES IT IN THE SDB
MNTBTB::SAVEQ
SE1CAL
STKVAR<STRN06,BTJFN2>
MOVEM T1,STRN06 ;SAVE STRUCTURE NUMBER
MOVX T2,GJ%OLD!GJ%PHY!GJ%DEL!GJ%SHT ;T2/BITS FOR GTJFN
CALL GETBTB ;GET JFN FOR BIT TABLE FILE
RETBAD ;FAILED
MOVEM T1,BTJFN2 ;SAVE THE JFN
MOVE T2,[3,,.FBCTL] ;T2/(COUNT,,FIRST WORD)
MOVEI T3,Q1 ;T3/DESTINATION
GTFDB ;GET SOME INFO ON THE FILE
ERJMP MNTBT1 ;FAILED. RELEASE THE JFN
TXNE Q1,FB%LNG ;IS IT A LONG FILE?
BUG(MNTLNG)
MOVE T1,Q3 ;T1/ADDRESS OF INDEX BLOCK
TXO T1,THAWB+FILWB ;THAWED SO IT IS UPDATED INSTANTLY
MOVE T2,STRN06 ;T2/STRUCTURE NUMBER
CALL ASROFN ;GET AN OFN FOR THE FILE
JRST MNTBT1 ;FAILED. GO RELEASE THE JFN
MOVE T2,STRN06 ;GET STRUCTURE NUMBER
MOVE T2,STRTAB(T2) ;POINT TO START OF SDB FOR THIS STRUCTURE
MOVEM T1,SDBBTB(T2) ;SAVE OFN FOR THIS STRUCTURE
MOVE T1,BTJFN2 ;T1/JFN FOR BIT TABLE
RLJFN ;RELEASE THE JFN
JFCL ;IGNORE FAILURE
RETSKP
;ERROR AFTER GTJFN. RELEASE THE JFN
MNTBT1: MOVEM T1,STRN06 ;SAVE ERROR CODE IN TEMPORARY LOCATION
MOVE T1,BTJFN2 ;T1/JFN FOR BIT TABLE FILE
RLJFN ;RELEASE THE JFN
JFCL ;IGNORE FAILURE
MOVE T1,STRN06 ;RESTORE ERROR CODE
RETBAD ;TAKE NON-SKIP RETURN
;MAPBTB - MAP THE BIT TABLE
;ACCEPTS:
; T1/STRUCTURE NUMBER
;RETURNS +1: ALWAYS, NOSKED
;FOR A GIVEN STRUCTURE, GETS OFN FOR ITS BIT TABLE FROM ITS SDB, SWAPS ITS
;INDEX BLOCK INTO CORE. CALLS LCKBTB TO LOCK BTBLCK AND MAKE THE SPECIAL
;SPT SLOT, BTBBAS, POINT TO THE INDEX BLOCK
MAPBTB::STKVAR<BTBMAP>
SE1CAL
MOVE T1,STRTAB(T1) ;POINT TO START OF SDB FOR THIS STRUCTURE
SKIPN T1,SDBBTB(T1) ;IS THERE AN OFN FOR THE BIT TABLE?
BUG(MAPBT1)
MOVEM T1,BTBMAP ;YES. SAVE SPT INDEX
NOSKED ;NOSKED WHILE BTBBAS POINTS TO THIS BIT TABLE
HLL T1,SHRPTR ;SET UP SHARE POINTER TO BTB SECTION
MOVEM T1,MSECTB+BTSEC ;SET UP SECTION POINTER
CALL MONCLR ;RESET PAGER MAP
MOVE T1,BTBMAP ;RECOVER MAP
CALL SWPIN1 ;SWAP IT INTO CORE AND LOCK DOWN THE PAGE
MOVE T1,BTBMAP ;GET SPT INDEX
CALL LCKBTB ;LOCK THE LOCK AND SET BTBBAS TO POINT TO THIS INDEX BLOCK
RET
;UMPBTB - UNMAP THE BIT TABLE
;ACCPETS:
; T1/STRUCTURE NUMBER
;RETURNS +1: ALWAYS
;CALLED NOSKED, WITH BIT TABLE MAPPED. RETURNS OKSKED WITH BIT TABLE UNMAPPED
;AND BTBLCK UNLOCKED
UMPBTB::MOVEM T1,T4 ;SAVE STRUCTURE NUMBER
SE1CAL
MOVE T1,BTBBAS ;GET OFFSET OF SPECIAL SPT SLOT FOR BIT TABLE
MOVX T3,UAAB ;SET UP FOR SPT SLOT UNUSED
MOVEM T3,SPT(T1) ;INDICATE THIS IN BTBBAS SLOT
CALL UPSHR ;SET SHARE COUNT
SETZM SPTH(T1) ;NO ONE OWNS THIS SLOT FOR NOW
MOVE T2,T4 ;GET STRUCTURE NUMBER
MOVE T2,STRTAB(T2) ;POINT TO START OF SDB FOR THIS STRUCTURE
SETZM MSECTB+BTSEC ;CLEAR SECTION POINTER
MOVE T1,SDBBTB(T2) ;GET OFN CURRENTLY MAPPED
LOAD T1,STGADR,SPT(T1) ;GET CORE ADDRESS THAT INDEX BLOCK IS MAPPED INTO
CALL UNLBTB ;UNLOCK THE CORE PAGE (LOCKED BY MAPBTB)
SETOM BTBLCK ;CLEAR THE BIT TABLE LOCK
OKSKED
RET
;LCKBTB - LOCK BIT TABLE - CALLED ON ENTRY TO ANY ASSIGNMENT OR DEASSIGNMENT
;ROUTINE
;ACCEPTS:
; T1/OFFSET IN SPT FOR ENTRY TO COPY INTO BTBBAS
;RETURNS +1: ALWAYS
;CALLED NOSKED
;COPIES AN SPT ENTRY INTO THE SPECIAL BIT TABLE SLOT, BTBBAS. STORES THE OFFSET
;INTO SPTH(BTBBAS). THE SPT SLOT MUST POINT TO A PAGE TABLE FOR A BIT TABLE.
;IT MAY BE IN EITHER PART OF THE SPT. THIS ROUTINE ALSO LOCKS THE BIT TABLE
;LOCK.
LCKBTB: AOSE BTBLCK ;TRY TO LOCK SPT SLOT
BUG(DSKBT3,<<T1,SPTIDX>>)
MOVE T2,BTBBAS ;GET SPECIAL SPT INDEX FOR BIT TABLE
MOVE T3,SPT(T1) ;GET CONTENTS OF SPT ENTRY FOR STRUCTURE TO BE MAPPED
MOVEM T3,SPT(T2) ;COPY INTO BTBBAS ENTRY (MMAP POINTS TO BTBBAS)
MOVEM T1,SPTH(T2) ;SHOW SPT SLOT AS OWNER IN BTBBAS
RET
;GETBTB - GET A JFN ON THE BIT TABLE FILE
;ACCEPTS:
; T1/STRUCTURE NUMBER
; T2/BITS FOR GTJFN AS PASSED IN T1
; CALL GETBTB
;RETURNS +1: FAILED
; +2: SUCCEEDED
; T1/JFN FOR BIT TABLE FILE
GETBTB:
STKVAR <STRN16,NAMBLK,FLAGS,BTJFN0>
MOVEM T1,STRN16 ;SAVE THE STRUCTURE NUMBER
MOVEM T2,FLAGS ;SAVE BITS FOR GTJFN
MOVEI T2,10 ;GET 8 WORDS OF FREE SPACE FROM THE
NOINT ;NOINT WHILE WE HAVE JSB FREE SPACE
CALL ASGJFR ; JSB TO HOLD THE FILE SPEC
RETBAD (,<OKINT>) ;FAILED TO GET THE SPACE
MOVEM T1,NAMBLK ;SAVE LOCATION OF START OF STRING AREA
HRROI T1,1(T1) ;POINT TO WORD AFTER THE HEADER
MOVE T2,STRN16 ;T2/STRUCTURE NUMBER
HRROI T3,BTBNAM ;T3/POINTER TO FILE NAME
CALL STRST ;BUILD A STRING CONTAINING STRUCTURE NAME
; AND FILE SPEC
JRST GETBT1 ;FAILED
MOVE T1,FLAGS ;T1/BITS FOR GTJFN
HRRO T2,NAMBLK ;USE FILE NAME JUST CREATED
ADDI T2,1 ;POINT TO WORD AFTER HEADER
GTJFN ;GET A JFN FOR THE BIT TABLE FILE
JRST GETBT1 ;FAILED
MOVEM T1,BTJFN0 ;SAVE THE JFN
MOVEI T1,JSBFRE ;T1/RETURNING SPACE IN JSB
MOVE T2,NAMBLK ;T2/START OF BLOCK
CALL RELFRE ;RELEASE THE STRING SPACE WE GOT BEFORE
OKINT ;OKINT NOW THAT FREE SPACE RETURNED
MOVE T1,BTJFN0 ;RETURN THE JFN IN T1
RETSKP
;GOT AN ERROR AFTER THE CALL TO ASGJFR AND BEFORE THE CALL TO RELFRE.
;RELEASE THE SPACE AND TAKE ERROR RETURN
GETBT1: MOVEM T1,STRN16 ;SAVE ERROR CODE IN TEMPORARY LOCATION
MOVEI T1,JSBFRE ;T1/RETURNING SPACE IN THE JSB
MOVE T2,NAMBLK ;T2/START OF BLOCK
CALL RELFRE ;RELEASE THE SPACE WE GOT BEFORE
OKINT ;OKINT NOW THAT FREE SPACE RETURNED
MOVE T1,STRN16 ;RESTORE THE ERROR CODE
RETBAD
BTBNAM: ASCIZ /<ROOT-DIRECTORY>DSKBTTBL/
;DSKAS - DISK ASSIGNMENT CONTROL JSYS
;ACCEPTS:
;T1/ DATA PLUS BITS (SEE BELOW)
;T2/ DEVICE DESIGNATOR
;NO BITS: DATA IS SECTOR NUMBER FROM BEGINNING OF STRUCTURE. ASSIGN THIS PAGE
;B0 (DA%DEA): DATA IS SECTOR NUMBER FROM BEGINNING OF STRUCTURE. DEASSIGN THIS PAGE
;B1 (DA%ASF): DATA IS SECTOR NUMBER FROM BEGINNING OF STRUCTURE. ASSIGN NEAR THIS SECTOR
;B2 (DA%CNV): CONVERT THE ADDRESS IN THE REST OF THE WORD
;B3 (DA%HWA): ADDRESS IS HARDWARE. CONVERT TO SOFTWARE
;IF B3 IS NOT SET, DATA IS SOFTWARE ADDRESS. CONVERT TO HARDWARE
;B4 (DA%INI): NO DATA. INITIALIZE THE BIT TABLE FOR STRUCTURE IN T2
;B5 (DA%WRT): NO DATA. WRITE THE BIT TABLE FILE FOR THE STRUCTURE IN T2
; 1B0+1B1+SIXBIT / CLEAR/ = CLEAR WHOLE BIT TABLE (NO LONGER SUPPORTED)
;RETURNS +1: FAILED
; +2: SUCCEEDED
.DSKAS::MCENT
CALL DSKASO ;CALL ROUTINE TO DO THE WORK
RETERR ;FAILED. NON-SKIP RETURN
SMRETN ;SUCCEEDED. SKIP RETURN
DSKASO: TRVAR <STRN07,BTJFN1>
TXNE A,DA%CNV ;CONVERSION WANTED?
JRST DSKUA2 ;YES
MOVE 4,CAPENB ;NO. EVERYTHING ELSE REQUIRES WHEEL OR OPERATOR
TXNN 4,SC%WHL+SC%OPR
RETBAD(WHELX1) ;CALLER DOESN'T HAVE ENOUGH PRIVILEGES
UMOVE T1,2 ;GET DEVICE DESIGNATOR
CALL CHKSTR
RETBAD (DSKX01) ;NO SUCH STR
MOVEM T1,STRN07 ;SAVE STR NUMBER
UMOVE T1,1 ;RESTORE USER FLAGS
MOVE T2,STRN07 ;SET THIS UP
TXNE T1,DA%INI!DA%WRT ;WORKING ON THE BIT TABLE?
JRST [ MOVEI T4,DSKUA4 ;YES
JRST DSKUAD]
TXZE 1,DA%DEA ;NO.DEASSIGN?
JRST [ MOVEI T4,DSKUA1 ;YES - GO DO IT
JRST DSKUAD]
;SOME SORT OF ASSIGNMENT TO BE DONE
MOVEI T4,DSKUAA ;DO SPECIFIC ASSIGNMENT
TXZE 1,DA%ASF ;UNLESS BIT 1,
MOVEI T4,DSKUAN ;IN WHICH CASE ASSIGN AS CLOSE
; AS POSSIBLE
; ..
; ..
DSKUAD: CALL 0(T4) ;DO WHICHEVER
JRST [ EXCH T1,STRN07 ;SAVE ERROR CODE - GET STR #
CALL ULKSTR ;UNLOCK STR
MOVE T1,STRN07 ;GET ERROR CODE BACK
RET] ;FAIL RETURN
MOVE T1,STRN07 ;UPDATE BIT TABLE
CALL UPDBTB ;...
MOVE T1,STRN07 ;RELEASE STRUCTURE LOCK
CALL ULKSTR ;...
RETSKP ;GIVE GOOD RETURN
;HERE IF DA%DEA IS SET. IF DA%ASF IS SET TOO, THIS IS THE BIT TABLE
;CLEAR FUNCTION. OTHERWISE, IT IS THE DEASSIGN FUNCTION
DSKUA1: TXZN 1,DA%ASF ;BIT 1 ALSO?
JRST [ CALL DSKDEA ;NO, DEASSIGN SPECIFIC ADDRESS
RETBAD ;FAILED
RETSKP]
;USER HAS REQUESTED THE BIT TABLE CLEAR FUNCTION. THIS HAS BEEN
;REPLACED BY THE INI/WRT COMBINATION
RETBAD (ARGX02) ;RETURN 'INVALID FUNCTION'
REPEAT 0,<
CAME 1,[SIXBIT / CLEAR/] ;SEE IF 'PASSWORD' OK
RETBAD ;LOSE - HE DIDN'T 'REALLY' WANT TO...
MOVE T1,STRN07 ;T1/STRUCTURE NUMBER
CALL MAPBTB ;MAP INDEX BLOCK INTO BTBBAS, LOCK INTO CORE,
; LOCK BTBLCK, GO NOSKED
MOVE T1,STRN07 ;T1/STRUCTURE NUMBER
CALL INIBTB ;INITIALIZE THE BIT TABLE
MOVE T1,STRN07 ;T1/STRUCTURE NUMBER
CALL UMPBTB ;UNMAP INDEX BLOCK FROM BTBBAS, UNLOCK CORE PAGE,
; UNLOCK BTBLCK, GO OKSKED
RETSKP
>
;USER WANTS ADDRESS CONVERSION
DSKUA2: MOVE D,CAPENB ;CHECK CAPABILITIES
TXNN D,SC%WHL+SC%OPR+SC%MNT
RETBAD(WHELX1) ;INSUFFICIENT
TXZN A,DA%HWA ;HARDWARE OR SOFTWARE ADDRESS?
JRST [ ANDX A,STGADR ;SOFTWARE, GET ONLY VALID BITS
JRST DSKUA3]
DSKUA3: UMOVEM A,A
RETSKP
;USER WANTS TO MODIFY THE BIT TABLE. DO SOME COMMON THINGS BEFORE DECIDING
;WHICH FUNCTION TO DO
DSKUA4: MOVE T3,STRTAB(T2) ;GET SDB PNTR FOR STRUCTURE
ADDI T2,DVXST0 ;POINT TO DEVXXX TABLES FOR THIS STRUCTURE
MOVX T4,D1%INI ;SET UP BIT FOR STRUCTURE BEING INITED
NOSKED ;DON'T LET ANYONE STOP US WHILE WE'RE MESSING
; WITH THE BIT TABLE
TXNE T1,DA%WRT ;NOW, WHAT WERE WE DOING?
JRST DSKUA5 ;WRITING THE FILE. GO DO IT
;USER WANTS TO INITIALIZE THE BIT TABLE. CREATE AN IN-CORE COPY AND
;GIVE THIS FORK EXCLUSIVE ACCESS UNTIL THE WRITE FUNCTION IS DONE.
TDNE T4,DEVCH1(T2) ;IS BIT ALREADY ON?
JRST DSKU40 ;YES - DON'T CHANGE JOB #
IORM T4,DEVCH1(T2) ;SAY THAT WE ARE DOING IT
HRRZS DEVUNT(T2) ;MAKE STRUCTURE APPEAR TO BE ASSIGNED TO JOB 0
;SO EXEC WON'T SAY IT IS AVAILABLE
MOVE T4,FORKX ;GET THIS FORK'S NUMBER
STOR T4,STRJB,(T3) ;SAVE IT AS THE INITING FORK
DSKU40: SETZRO MI%ASG,SDBSTS(T3) ;ALLOW ASSIGNMENTS AGAIN SINCE WE ARE
; CREATING A NEW BIT TABLE
SETZM SDBLCA(T3) ;RESET LAST CYLINDER ASSIGNED FOR THIS
;STRUCTURE (USED BY DSKASN)
SKIPE T1,SDBBTB(T3) ;GET CURRENT OFN FOR BIT TABLE
JRST [ CAIL T1,NOFN ;IS IT A REAL OFN FOR A FILE?
JRST DSKUA6 ;NO. BIT TABLE WAS JUST CREATED
CALL RELOFN ;YES. RELEASE IT
JRST .+1]
MOVE T1,STRN07 ;T1/STRUCTURE NUMBER
CALL CRTBTB ;GO INITIALIZE THE IN-CORE COPY OF THE
; BIT TABLE
RETBAD (,<OKSKED>) ;FAILED
DSKUA6: OKSKED ;ALLOW SCHEDULING
RETSKP
;NOTE ON THE CALL TO RELOFN:
;IT IS POSSIBLE TO DO THE CREATE FUNCTION TWICE IN A ROW, THUS
;ENTERING THIS CODE WHEN A PRIVATE COPY OF THE BIT TABLE EXISTS.
;ONLY THE JOB THAT SET THE D1%INI BIT IN DEVCH1 (AND THUS HAS
;EXCLUSIVE ACCESS) CAN DO THIS FUNCTION AS WELL AS THE 'WRITE'
;FUNCTION. IF A PRIVATE COPY EXISTS, SDBBTB FOR THE STRUCTURE WILL
;CONTAIN A NUMBER LARGER THAN NOFN. IN THAT CASE, RELOFN AND CRTBTB
;ARE NOT CALLED. THIS IS BECAUSE (1) RELOFN WILL FAIL AND (2)
;CRTBTB WOULD CREATE A SECOND PRIVATE PAGE TABLE, LOSING TRACK OF
;THE EXISTING PAGE TABLE.
;USER WANTS TO WRITE THE BIT TABLE FILE. IF AN IN-CORE COPY EXISTS, SDBBTB
;CONTAINS A NUMBER >= NOFN. IF NOT, THIS CODE RETURNS AN ERROR
DSKUA5: TDNN T4,DEVCH1(T2) ;IS THE BIT TABLE BEING INITED?
RETBAD(DSKX03,<OKSKED>) ;NO. IT SHOULD BE
MOVE T1,SDBBTB(T3) ;GET CURRENT OFN FOR BIT TABLE
SKIPE T1
CAIGE T1,NOFN ;REAL FILE OFN?
RETBAD(DSKX03,<OKSKED>) ;DON'T HAVE SPT INDEX FOR BITTABLE
;GET A JFN ON THE FILE AND GET RID OF IT IN THE DIRECTORY
MOVE T1,STRN07 ;T1/STRUCTURE NUMBER
MOVX T2,GJ%OLD!GJ%PHY!GJ%DEL!GJ%SHT
CALL GETBTB ;GET A JFN FOR THE FILE
RETSKP ;IGNORE FAILURE
MOVEM T1,BTJFN1 ;SAVE JFN
TXO T1,DF%FGT!DF%EXP ;GET RID OF POINTER TO INDEX BLOCK
; AND RELEASE FDB (SEE DSKDEL)
DELF ; IN THE DIRECTORY
JFCL ;IGNORE FAILURE. PRIVATE COPY HAS BEEN
; CREATED ANYWAY
MOVE T1,BTJFN1 ;T1/JFN
RLJFN ;RELEASE THE JFN
JFCL ;IGNORE FAILURE
MOVE T1,STRN07 ;T1/STRUCTURE NUMBER
CALL WRTBTB ;WRITE THE BIT TABLE FILE
RETBAD (,<OKSKED>) ;FAILED
MOVE T1,STRN07 ;T1/STRUCTURE NUMBER
MOVE T2,STRTAB(T1) ;T2/ADDRESS OF START OF SDB FOR THIS STRUCTURE
CALL FRESTR ;INDICATE STRUCTURE IS AVAILABLE
MOVE T1,STRN07 ;GET STRUCTURE AGAIN
MOVE T1,STRTAB(T1) ;GET SDB FOR THIS STRUCTURE
HRRZ T1,SDBBTB(T1) ;GET OFN OF THE NEW BIT TABLE
CALL UPDOFN ;AND MAKE IT APPEAR ON THE DISK
OKSKED ;ALLOW SCHEDULING
RETSKP
;JACKET ROUTINES FOR DSKASN AND DSKASA
DSKUAA: TDZA T4,T4 ;OFFSET 0
DSKUAN: MOVEI T4,1 ;OFFSET 1
SETO T3,0 ;SAY SINGLE ASSIGN
CALL @[ IFIW!DSKASG
IFIW!DSKASN](T4) ;CALL CORRECT ROUTINE
RETBAD () ;FAILURE
UMOVEM T1,1 ;RETURN ADDRESS ASSIGNED
RETSKP ;GOOD RETURN
;DISK USAGE STATISTICS
;ACCEPTS:
; T1/STRUCTURE NUMBER
; CALL DSKSP
;RETURNS +1: ALWAYS
; T1/NUMBER OF USED PAGES
; T2/NUMBER OF FREE PAGES
DSKSP:: STKVAR <STRN10,FRECNT>
SE1CAL
MOVEM T1,STRN10 ;SAVE THE STRUCTURE NUMBER
CALL MAPBTB ;MAP INDEX BLOCK INTO BTBBAS, LOCK INTO CORE,
; LOCK BTBLCK, GO NOSKED
MOVE T3,STRN10 ;GET STRUCTURE NUMBER
MOVE T3,STRTAB(T3) ;POINT TO START OF SDB FOR THIS STRUCTURE
MOVN T4,SDBCYL(T3) ;(-TOTAL CYLINDERS IN STRUCTURE)
MOVEI T3,LOTRK
ADD T3,BTBORA ;POINT TO WORD IN TOP OF BIT TABLE
SETZ T2, ;SETUP TO EXAMINE ALL TRACKS
DSKSP1: ADD T2,0(T3) ;ADD FREE COUNT OF THIS TRACK
AOS T3 ;NEXT WORD
AOJL T4,DSKSP1 ;DO ALL TRACKS
MOVEM T2,FRECNT ;SAVE COUNT OF FREE PAGES
MOVE T1,STRN10 ;T1/STRUCTURE NUMBER
CALL UMPBTB ;UNMAP INDEX BLOCK FROM BTBBAS, UNLOCK CORE PAGE,
; UNLOCK BTBLCK, GO OKSKED
MOVE T3,STRN10 ;GET STRUCTURE NUMBER
MOVE T3,STRTAB(T3) ;POINT TO START OF SDB FOR THIS STRUCTURE
MOVE T1,SDBCYL(T3) ;GET TOTAL CYLINDERS ON STRUCTURE
MOVE T3,SDBTYP(T3) ;POINT TO SIZE DATA FOR THIS DISK TYPE
IMUL T1,PAGCYL(T3) ;CONVERT CYLINDERS TO PAGES ON STRUCTURE
MOVE T2,FRECNT ;RESTORE FREE COUNT
SUB T1,T2 ;USED = TOTAL - FREE
RET
;GDSKC - JSYS TO GET COUNT OF FREE PAGES ON A STRUCTURE
;ACCEPTS:
; T1/DEVICE DESIGNATOR (MUST BE DISK)
;RETURNS +1: ALWAYS
; T1/NUMBER OF PAGES USED
; T2/NUMBER OF PAGES FREE
;NOTE: IF THE BIT TABLE IS IN THE PROCESS OF BEING INITIALIZED,
;D1%INI WILL BE SET IN DEVCH1. IF THE FORK DOING THIS JSYS IS DOING THE
;INIT, THE JSYS WILL SUCCEED. HOWEVER, IT IS POSSIBLE THE SDBFRC WILL
;NOT BE SET UP CORRECTLY.
.GDSKC::MCENT ;JSYS ENTRY
STKVAR <STRN17>
UMOVE T1,T1 ;GET DEVICE DESIGNATOR
CALL CHKSTR ;SEE IF VALID STRUCTURE, RETURN NO. IN AC1
ITERR(DEVX1) ;STRUCTURE DOES NOT EXIST
MOVEM T1,STRN17 ;SAVE STR #
CALL GSTRPG ;GET COUNTS. RETURNS USED IN T1, FREE IN T2
UMOVEM T1,1 ;PAGES USED
UMOVEM T2,2 ;PAGES FREE
MOVE T1,STRN17 ;UNLOCK STR
CALL ULKSTR ;...
JRST MRETN
;CHKSTR - CONVERT DEVICE DESIGNATOR TO STRUCTURE NUMBER
;ACCEPTS:
; T1/DEVICE DESIGNATOR
;RETURNS +1: STRUCTURE DOES NOT EXIST OR IS BEING INITIALIZED
; +2: STRUCTURE EXISTS
; T1/STRUCTURE NUMBER
CHKSTR: HLRZ T2,T1 ;GET DEVICE TYPE
CAIE T2,.DVDES+.DVDSK ;IS IT A DISK
RET ;NO - RETURN
HRRZS T1 ;USE UNIQUE CODE
CAIN T1,-1 ;DSK?
LOAD T1,JSUC ;YES, GET CURRENT CONNECTED STR
CALL CNVSTR ;CONVERT TO STR #
RET ;NO - SUCH STR
MOVE T4,STRTAB(T1) ;GET SDB
MOVEI T2,DVXST0(T1) ;POINT TO THIS STR IN DEVXXX TABLE
MOVX T3,D1%INI ;TEST FOR STRUCTURE BEING INITIALIZED
TDNE T3,DEVCH1(T2) ;IF SO, DSKFRC MAY NOT BE SET UP
JRST [ LOAD T3,STRJB,(T4) ;BEING INITED. SEE WHAT FORK IS DOING IT
CAME T3,FORKX ;IS IT THIS FORK?
CALLRET ULKSTR ;NO - UNLOCK STR AND RETURN
JRST .+1] ;YES. CAN REFERENCE BIT TABLE INFO
RETSKP ;GOOD STRUCTURE, NOT BEING INITIALIZED
; OR BEING INITED BY THIS FORK
;GSTRPG - GET PAGE COUNTS FOR A STRUCTURE
;ACCEPTS:
; T1/STRUCTURE NUMBER
;RETURNS +1: ALWAYS
; T1/COUNT OF USED PAGES ON THE STRUCTURE
; T2/COUNT OF FREE PAGES ON THE STRUCTURE
;THIS ROUTINE DOES NOT MAKE A CONSISTENCY CHECK. IT MERELY USES THE SDB VALUES
GSTRPG::MOVE T3,STRTAB(T1) ;POINT TO SDB FOR THIS STRUCTURE
MOVE T2,SDBFRC(T3) ;GET NUMBER FREE PAGES FOR STRUCTURE
MOVE T1,SDBCYL(T3) ;GET TOTAL CYLINDERS IN STRUCTURE
MOVE T3,SDBTYP(T3) ;POINT TO SIZE DATA FOR THIS DISK TYPE
IMUL T1,PAGCYL(T3) ;CONVERT CYLINDERS TO TOTAL PAGES
SUB T1,T2 ;USED = TOTAL - FREE
RET
;DISK OPERATE JSYS - USER UTILITY DISK HANDLE
;ACCEPTS:
; T1/ 1B1+CHANNEL NUMBER (BITS 2-6) + UNIT NUMBER (BITS 7-12)
; + SECTOR NUMBER WITHIN UNIT (BITS 13-35)
; OR
; 1B0 + 0 (BITS 2-6) + SECTOR NUMBER WITHIN STRUCTURE (BITS 7-35)
; OR
; 1B0 + -1 (BITS 2-6) +SECTOR NUMBER WITHIN STRUCTURE (BITS 7-35)
; T2/FLAGS + NUMBER OF WORDS
; T3/ STARTING ADDRESS IN USER'S ADDRESS SPACE
; T4/ DEPENDS ON T1 AS FOLLOWS:
; IF 1B0 SET AND BITS 2-6 ARE -1, DEVICE DESIGNATOR FOR STRUCTURE
; IF 1B1 SET AND DOP%NF ALSO, THE CHAN, CONTROLLER, AND
; UNIT NUMBERS TO BE USED (CKU VALUE)
; OTHERWISE, IGNORED
;
;RETURNS +1: ALWAYS,
; T1/ 0 ON SUCCESS, NON-ZERO ON FAILURE
;
;FLAGS IN T2:
; 1B10 (DOP%NF) USE NEW FORMAT FOR CHANNEL AND UNIT NUMBERS (CKU NUMBER)
; 1B11 (DOP%IL) INHIBIT ERROR LOGGING
; 1B12 (DOP%IR) INHIBIT ERROR RECOVERY
; 1B14 (DOP%WR) WRITE ACCESS
;
;CURRENTLY, IF THE TRANSFER CROSSES A PAGE BOUNDARY, THEN ERROR CORRECTION
;AND LOGGING ARE INHIBITED SINCE PHYSIO DOESN'T YET KNOW HOW TO HANDLE
;MULTIPLE CCW WORDS IN ERROR RECOVERY.
.DSKOP::MCENT
STKVAR <STRNXX,UAC2,UAC3,SAVLCK> ;ALLOCATE STORAGE
SETOM STRNXX ;NO STRUCTURE TO UNLOCK YET
MOVEM T1,Q1 ;REMEMBER AC FOR LATER
MOVEM T2,UAC2 ;PRESERVE USER'S FLAGS AND COUNT
MOVEM T3,UAC3 ;PRESERVE ADDRESS ALSO
MOVE T4,CAPENB ;GET USER'S CAPABILITIES
TXNN T4,SC%WHL!SC%OPR!SC%MNT ;HAVE PROPER PRIVILEGES?
ITERR (WHELX1) ;NO. COMPLAIN
TXNE T2,-1-<DOP%NF!DOP%IL!DOP%IR!DOP%WR!DOP%CT> ;ANY UNUSED FLAGS USED?
ITERR (DECRSV) ;YES, COMPLAIN
LOAD Q2,DOP%AT,Q1 ;GET ADDRESS TYPE
CAIN Q2,.DOPSR ;STRUCTURE RELATIVE?
JRST [ LOAD T1,DOP%SN,Q1 ;YES. GET SN
JUMPE T1,[MOVEI T1,PSNUM ;USE PS IF ZERO
SKIPN STRTAB(A) ;MAKE SURE ITS HERE
ITERR (DSKOX3)
JRST DSKOP3] ;CONTINUE (NO STR TO LOCK)
CAIE T1,<.RTJST (DOP%SN,DOP%SN)> ;IS FIELD ALL ONES?
ITERR (DSKOX3)
UMOVE T1,4 ;GET DEVICE DESIGNATOR
CALL CHKSTR ;CONVERT TO STR #
ITERR (DSKOX3) ;NONE
MOVEM T1,STRNXX ;REMEMBER STRUCTURE TO UNLOCK
JRST DSKOP3] ;PROCEED
CAIE Q2,.DOPPU ;PHYSICAL?
ITERR (DSKOX4) ;NO, THEN ILLEGAL MODE WAS REQUESTED
UMOVE P4,4 ;GET POSSIBLE CHANNEL, CONTROLLER, UNIT NUMBERS
MOVE T1,UAC2 ;ALSO GET USER'S FLAGS
TXNE T1,DOP%NF ;ALREADY SETUP IN NEW FORMAT?
JRST DSKOPN ;YES, GO ON
MOVX P4,DOP%K2 ;OLD FORMAT, GET VALUE FOR NO CONTROLLER
LOAD T1,DOP%CN,Q1 ;GET CHANNEL FROM OLD FORMAT LOCATION
STOR T1,DOP%C2,P4 ;STORE AWAY IN NEW FORMAT
LOAD T1,DOP%UN,Q1 ;GET UNIT NUMBER FROM OLD STYLE LOCATION
STOR T1,DOP%U2,P4 ;STORE AWAY IN NEW FORMAT TOO
DSKOPN: MOVE T1,P4 ;GET CKU NUMBER
CALL CKUNPK ;UNPACK THEM
CALL CHKCKU ;SEE IF THEY ARE LEGAL
ITERR () ;NO, GIVE AN ERROR
MOVE P3,T1 ;REMEMBER THE UDB
DSKOP3: MOVE T4,CAPENB ;GET CAPS AGAIN
TXNE T4,SC%WHL!SC%OPR ;WHEEL OR OPERATOR?
JRST DSKOP2 ;WHEELS AND OPERATORS CAN DO IT ALL
MOVE T2,UAC2 ;GET USER FLAGS
TXNN T2,DOP%WR ;WANT TO WRITE IT?
JRST DSKOP2 ;NO. ALLOW MAINT TO READ ANYTHING
CAIN Q2,.DOPPU ;WANT TO WRITE PHYSICAL?
SKIPL UDBSTR(P3) ;AND UNIT NOT PART OF A STRUCTURE?
ITERR (WHELX1,<SKIPL T1,STRNXX ;NO, GET STRUCTURE NUMBER
CALL ULKSTR>) ;UNLOCK IT AND RETURN ERROR
DSKOP2: NOINT ;NO INTERRUPTIONS NOW
MOVE T1,UAC3 ;GET USER ADDRESS
HRRZ T2,UAC2 ;AND WORD COUNT
MOVX T3,DOP%WR ;GET WRITE FLAG READY
ANDCM T3,UAC2 ;MAKE VALUE INDICATING IF CORE IS TO BE WRITTEN
CALL IOLOCK ;LOCK DOWN NECESSARY USER PAGES
ITERR(,<EXCH T1,STRNXX ;FAILED, SAVE ERROR CODE AND GET STR INDEX
SKIPL T1 ;WAS ONE SAVED?
CALL ULKSTR ;YES, UNLOCK THE STRUCTURE
OKINT ;INTERRUPTS OK AGAIN
MOVE T1,STRNXX>) ;RESTORE ERROR CODE
MOVEM T1,SAVLCK ;REMEMBER ADDRESS OF PAGE LIST
MOVE T2,UAC3 ;GET USER ADDRESS AGAIN
HRRZ T3,UAC2 ;AND WORD COUNT AGAIN
HRRZ P1,STRTAB+PSNUM ;** TEMPORARY CROCK TO GET CDB ADDRESS **
HRRZ P1,SDBUDB(P1) ;GET A UDB
HRRZ P1,UDBCDB(P1) ;THEN GET A CDB ADDRESS
CALL IOLCCW ;TURN LIST OF PAGES INTO LIST OF CCW WORDS
MOVE T1,SAVLCK ;GET ADDRESS OF CCW LIST
MOVE T1,(T1) ;THEN GET AOBJN POINTER TO LIST
TLC T1,-1 ;CHECK FOR ONLY ONE ELEMENT IN LIST
TLCE T1,-1 ;IS THERE ONLY ONE?
JRST DSKOP4 ;NO, SKIP ON
MOVE T1,(T1) ;YES, GET THE CCW WORD
HRRZ T2,CDBDSP(P1) ;GET DISPATCH ADDRESS
CALL CDSCCA(T2) ;EXTRACT THE PHYSICAL ADDRESS FROM THE CCW
SKIPA P3,T1 ;THEN SAVE IT
DSKOP4: SETZM P3 ;OR ZERO AC AS A FLAG
LOAD T1,DOP%RA,Q1 ;GET DISK ADDRESS
CAIE Q2,.DOPSR ;STRUCTURE RELATIVE?
LOAD T1,DOP%UA,Q1 ;NO. GET UNIT RELATIVE ADDRESS
MOVE T2,UAC2 ;GET FLAGS AND COUNT
TXO T2,DOP%EO ;GENERATE ERRORS ON OFF-LINE
SKIPN T3,P3 ;GET PHYSICAL ADDRESS IF ONLY ONE CCW
MOVE T3,SAVLCK ;OR POINTER TO CCW LIST IF MULTIPLE ONES
SKIPGE T4,STRNXX ;GET STRUCTURE NUMBER
MOVEI T4,PSNUM ;USE PS IF -1
CAIN Q2,.DOPPU ;PHYSICAL ADDRESSES?
JRST [ TXO T2,1B0 ;YES. TELL UDSKIO WE HAVE THE NUMBERS
MOVE T4,P4 ;GET CKU VALUE TO USE
JRST .+1] ;AND GO DO IT
SKIPN P3 ;DOING MULTIPLE PAGE TRANSFER?
CALL MDSKIO ;YES, CALL MULTIPLE-PAGE ROUTINE
SKIPE P3 ;DOING A SINGLE PAGE TRANSFER INSTEAD?
CALL UDSKIO ;YES, CALL OLD ROUTINE
UMOVEM T1,1 ;RETURN ERROR BITS
MOVE T1,SAVLCK ;GET POINTER TO LIST OF CCW WORDS
MOVX T2,DOP%WR ;GET WRITE FLAG READY
ANDCM T2,UAC2 ;CREATE FLAG INDICATING IF CORE WAS WRITTEN
CALL IOCNLK ;UNLOCK ALL PAGES THAT WERE LOCKED
OKINT ;ALLOW INTS AGAIN
SKIPL T1,STRNXX ;SAVED STR #
CALL ULKSTR ;YES - UNLOCK IT
JRST MRETN ;AND RETURN
;CHKBT - CHECK CONSISTENCY OF BIT TABLE
;ACCEPTS:
; T1/ STRUCTURE NUMBER
; T2/ FLAGS
; CALL CHKBT
;RETURNS +1: CHKB0 FOUND ERRORS
; T1/ COUNT OF USED PAGES
; T2/ COUNT OF FREE PAGES
; T3/ ERROR COUNT
; +2: NO ERRORS,
; T1/ COUNT OF USED PAGES
; T2/ COUNT OF FREE PAGES
; T3/ ERROR COUNT (ZERO)
;COMPARES COUNT OF FREE PAGES PER TRACK WITH BITS FOR EACH PAGE IN THE TRACK.
;IF THEY DISAGREE, FIXES THE COUNT AND PRINTS MESSAGE IF REQUESTED IN T2
;ALSO FIXES THE FREE COUNT FOR THE ENTIRE STRUCTURE
CHKBT:: STKVAR <STRN11,CHKBTE>
SE1CAL
MOVEM T1,STRN11 ;SAVE STRUCTURE NUMBER
CALL CHKB0 ;CHECK CONSISTENCY
MOVEM T1,CHKBTE ;SAVE COUNT OF ERRORS
MOVE T1,STRN11 ;NO. T1/STRUCTURE NUMBER
CALL DSKSP ;CALCULATE FREE COUNT
;T1/USED PAGES, T2/FREE PAGES
MOVE T3,STRN11 ;GET STRUCTURE NUMBER
MOVE T3,STRTAB(T3) ;POINT TO START OF SDB FOR THIS STRUCTURE
MOVEM T2,SDBFRC(T3) ;STORE NEW COUNT OF FREE PAGES IN SDB
SKIPE T3,CHKBTE ;WERE THERE ANY ERRORS?
RETBAD ;YES. TAKE ERROR RETURN
RETSKP ;NO. TAKE SUCCESS RETURN
;CHKB0 - CHECK FREE PAGE COUNT AGAINST BITS FOR INDIVIDUAL PAGES
;ACCEPTS:
; T1/ STRUCTURE NUMBER
; T2/ FLAGS
;RETURNS +1: ALWAYS
; T1/COUNT OF ERRORS
;USE OF P REGISTERS:
; P1/ADDRESS OF SDB FOR THIS STRUCTURE
; P2/ADDRESS OF SIZE DATA FOR THIS DISK TYPE
CHKB0: SAVEPQ
STKVAR<STRN12,ERRCNT,GOODCT,BADCNT,CKBTFL>
MOVEM T1,STRN12 ;SAVE THE STRUCTURE NUMBER
MOVEM T2,CKBTFL ;SAVE FLAGS
MOVE P1,STRTAB(T1) ;P1/ADDRESS OF SDB FOR THIS STRUCTURE
MOVE P2,SDBTYP(P1) ;P2/ADDRESS OF SIZE DATA FOR THIS DISK TYPE
CALL MAPBTB ;MAP INDEX BLOCK INTO BTBBAS, LOCK INTO CORE,
; LOCK BTBLCK, GO NOSKED
SETZM ERRCNT ;INITIALIZE COUNT OF ERRORS
MOVN 7,SDBCYL(P1) ;7/(-TOTAL CYLINDERS IN STRUCTURE,,LOWEST CYL)
HRLZ 7,7
HRRI 7,LOTRK
CHKB5: MOVEI 6,0(7) ;GET NEXT CYLINDER NUMBER
IMUL 6,BTWCYL(P2) ;COMPUTE OFFSET IN BIT PART OF TABLE
ADD 6,BTBORA ;POINT TO ACTUAL WORD IN BIT PART OF TABLE
ADD 6,SDBBT0(P1)
MOVE 4,PAGCYL(P2) ;COUNT BACKWARDS FROM NO. PAGES PER CYLINDER
SETZ 5, ;WILL COUNT FREE PAGES FOUND
CHKB2: MOVE 1,0(6) ;GET WORD OF BITS
MOVNI 2,^D36 ;36 OF THEM...
CHKB1: TDNE 1,BITS+^D36(2) ;THIS PAGE FREE?
AOJ 5, ;YES, COUNT IT
SOJLE 4,CHKB3 ;STOP IF CHECKED ALL PAGES THIS TRACK
AOJL 2,CHKB1 ;LOOP OVER BITS IN WORD
AOJA 6,CHKB2 ;LOOP OVER WORDS
CHKB3: MOVE 1,BTBORA ;POINT TO BEGINNING OF BIT TABLE
ADDI 1,0(7) ;POINT TO WORD FOR THIS TRACK
CAME 5,0(1) ;COUNT CORRECT AS REMEMBERED?
JRST CHKB4 ;NO
CHKB6: AOBJN 7,CHKB5 ;YES, LOOP OVER TRACKS
MOVE 1,STRN12 ;1/STRUCTURE NUMBER
CALL UMPBTB ;UNMAP INDEX BLOCK FROM BTBBAS, UNLOCK CORE PAGE,
; UNLOCK BTBLCK, GO OKSKED
MOVE 1,ERRCNT ;RESTORE COUNT OF ERRORS
RET
;INCONSISTENCY BETWEEN COUNT OF FREE PAGES FOR A TRACK AND THE BITS FOR
;EACH PAGE. REPORT THE INCONSISTENCY AND CONTINUE THE SEARCH.
;T1/ ADDRESS OF WORD IN FIRST PART OF BIT TABLE CONTAINING FREE PAGE COUNT
;5/ COUNT AS OBTAINED FROM ADDING BITS
;7/CYLINDER NUMBER
CHKB4: MOVEM 5,GOODCT ;SAVE THE COUNT OF BITS
EXCH 5,0(1) ;STORE NEW COUNT, GET OLD ONE
MOVEM 5,BADCNT ;SAVE OLD COUNT OF FREE PAGES
AOS 6,ERRCNT ;COUNT ERRORS
MOVE A,CKBTFL ;GET FLAGS
TXNN A,MI%MSG ;MESSAGES DESIRED ?
JRST CHKB6 ;NO, GO ON
CAIL 6,^D20 ;YES, REPORTED ENOUGH?
JRST [ CAIE 6,^D20 ;YES, NOTED OTHERS ALREADY?
JRST CHKB6 ;YES, CONTINUE QUIETLY
MOVE 1,STRN12 ;T1/STRUCTURE NUMBER
CALL UMPBTB ;UNMAP INDEX BLOCK FROM BTBBAS, UNLOCK CORE PAGE,
; UNLOCK BTBLCK, GO OKSKED
HRROI 1,[ASCIZ /
AND OTHERS...
/]
PSOUT ;NOTE ADDITIONAL ERRORS AFTER CUTOFF
MOVE 1,STRN12 ;T1/STRUCTURE NUMBER
CALL MAPBTB ;MAP INDEX BLOCK INTO BTBBAS, LOCK INTO CORE,
; LOCK BTBLCK, GO NOSKED
JRST CHKB6] ;CONTINUE WITH SCAN
MOVE 1,STRN12 ;T1/STRUCTURE NUMBER
CALL UMPBTB ;UNMAP INDEX BLOCK FROM BTBBAS, UNLOCK CORE PAGE,
; UNLOCK BTBLCK, GO OKSKED
HRROI 1,[ASCIZ /
BT INCONSISTENCY (COUNTS WILL BE CORRECTED)
TRK CNT BITS
/]
CAIG 6,1 ;FIRST ERROR?
PSOUT ;YES, PRINT HEADING
MOVEI 1,101
MOVX T3,<NO%LFL+FLD(4,NO%COL)+FLD(10,NO%RDX)> ;LEADING FILLER,
;4 COLUMNS, OCTAL NUMBER
MOVEI 2,0(7) ;GET CYLINDER NUMBER
NOUT ;PRINT TRACK NUMBER
MOVX T3,<NO%LFL+FLD(4,NO%COL)+FLD(10,NO%RDX)> ;FAILED. RESTORE FLAGS
MOVE 2,BADCNT ;RESTORE FREE PAGE COUNT FROM TOP OF BIT TABLE
NOUT ;PRINT FREE PAGE COUNT
MOVX T3,<NO%LFL+FLD(4,NO%COL)+FLD(10,NO%RDX)> ;FAILED. RESTORE FLAGS
MOVE 2,GOODCT ;GET COUNT FROM BITS
ANDI 2,777 ;IN CASE REALLY FOULED UP
NOUT ;PRINT COUNT FROM BITS
JFCL
HRROI 1,[ASCIZ /
/]
PSOUT
MOVE 1,STRN12 ;T1/ STRUCTURE NUMBER
CALL MAPBTB ;MAP INDEX BLOCK INTO BTBBAS, LOCK INTO CORE,
; LOCK BTBLCK, GO NOSKED
JRST CHKB6 ;CONTINUE SCAN
;UPDATE BIT TABLE--CAUSE CHANGED PAGES TO BE WRITTEN TO DISK
;ACCEPTS:
; T1/STRUCTURE NUMBER
; CALL UPDBTB
;RETURNS +1: ALWAYS
;NOTE: IF THE BIT TABLE IS IN PRIVATE PAGES RATHER THAN A FILE,
;ITS OFN IS >= NOFN. UPDPGS CANNOT BE CALLED IN THIS CASE BECAUSE
;IT CALLS UPDOFN, WHICH WANTS THE PAGES TO BE IN A FILE
UPDBTB::MOVE T4,T1 ;GET UNIT NUMBER
SE1CAL
REPEAT 0,<
ADDI T4,DVXST0 ;POINT TO THIS STRUCTURE IN DEVXXX TABLES
MOVX T3,D1%INI ;SET UP BIT FOR INITING STRUCTURE
TDNE T3,DEVCH1(T4) ;IF SO, DON'T TRY TO DO THIS BECAUSE
; UPDPGS CALLS OPDOFN, WHICH WANTS BIT TABLE
; TO BE A FILE.
RET
>
MOVE T3,STRTAB(T1) ;POINT TO START OF SDB FOR THIS STRUCTURE
SKIPE T1,SDBBTB(T3) ;GET OFN FOR BIT TABLE
CAIL T1,NOFN ;IS IT A REAL OFN?
RET ;NO OFN FOR BIT TABLE. DON'T TRY TO UPDATE
HRLZS T1 ;T1/(OFN,,PAGE 0)
MOVE T2,SDBBT0(T3) ;GET SIZE OF TOP HALF OF BIT TABLE
ADD T2,SDBBT1(T3) ;ADD SIZE OF BOTTOM
ADDI T2,<PGSIZ-1> ;ROUND UP TO END OF PAGE
IDIVI T2,PGSIZ ;T2/ PAGE COUNT
SKIPE T1 ;DO NOTHING IF NO OFN ASSIGNED
CALL UPDPGS ;UPDATE PAGES
RET
;THIS ROUTINE WILL ALLOCATE THE FE FILE SYSTEM ON THE DUAL-PORTED
;DISK DRIVE AND THE BOOTSTRAP.BIN FILE.
; IT IS EXECUTED ONLY AT SYSTEM REFRESH TIME AND
;IS DONE AS PART OF THE BIT TABLE INITIALIZATION LOGIC.
;ACCEPTS:
; T1/STRUCTURE NUMBER
; T2/NUMBER OF PAGES TO ALLOCATE
; CALL FEFSYS
;RETURNS: +1 FAILURE
; +2 SUCCESS
; LOCAL VARIABLES --
;STRN13 ;STRUCTURE NUMBER
;OFNPTT ;OFN OF PTT
;OFNPT ;OFN OF PT
;FEFNAM ;GTJFN STRING PLACED HERE
;FEFPAG ;NUMBER OF PAGES SPECIFIED FOR FE FILE SYSTEM
;FEFCYL ;NUMBER OF CYLINDERS FOR FE FILE SYSTEM
BOTSYS::TDZA C,C ;SET BOOT FLAG
FEFSYS::SETO C, ;SET FE FLAG
JUMPE T2,RSKP ;RETURN SUCCESS IF NOTHING TO ALLOCATE
SKIPG T2 ;NEGATIVE # OF PAGES SPECIFIED ?
RET ;YES, RETURN FAILURE
SE1CAL
SAVEPQ
JSBVAR <STRTY1,STRN13,OFNPTT,OFNPT,<FEFNAM,^D12>,FEFPAG,FEFCYL,FILTYP>,R
MOVEM C,FILTYP ;SAVE TYPE OF ENTRY
DMOVEM A,P1 ;SAVE STRUCTURE # AND # OF PAGES FOR FE FILE SYS
MOVEM P1,STRN13 ;SAVE STRUCTURE NUMBER
MOVEM P2,FEFPAG ;SAVE NUMBER OF PAGES INITIALLY SPECIFIED
HRRZ Q1,STRTAB(P1) ;Q1/ADDRESS OF SDB FOR THIS STRUCTURE
MOVN Q2,SDBNUM(Q1) ;NUMBER OF UNITS IN STRUCTURE
MOVSI Q2,0(Q2) ;FORM AOBJN POINTER
HRRI Q2,SDBUDB(Q1) ;FIRST UDB
MOVE Q3,Q2 ;COPY AOBJN POINTER
FEFSY0: HRRZ A,0(Q3) ;GET UDB
CALL WRBOOT ;WRITE BOOT BLOCK
AOBJN Q3,FEFSY0 ;LOOP FO ALL UNITS
MOVE A,Q1 ;COPY SDB
MOVE B,Q2 ;COPY AOBJN POINTER AGAIN
;LOOP THROUGH LOGICAL UNITS LOOKING FOR DUAL-PORTED DRIVE
FESYS2: MOVE D,0(B) ;UDB ADDRESS
MOVX C,US.PGM ;FLAG FOR THE DUAL-PORTED DRIVE
TDNE C,UDBSTS(D) ;IS THIS IT?
JRST FEFSY1 ;YES
AOBJN B,FESYS2 ;NO. LOOK AT NEXT
; SKIPN FILTYP ;IF BOOTSTRAP NO BUGCHECK
; BUG(NO2PRT)
MOVEI B,SDBUDB(Q1) ;POINTER TO LOGICAL 0
FEFSY1: MOVE P4,B ;SAVE UDB INDEX
MOVEI P1,0(B) ;ADDRESS OF UDB POINTER
SUBI P1,SDBUDB(Q1) ;CALCULATE RELATIVE PCAK NUMBER
MOVE Q2,SDBTYP(Q1) ;Q2/ADDRESS OF SIZE DATA FOR THIS DISK TYPE
MOVEM Q2,STRTY1 ;SAVE IT FOR FEWRTH
MOVE A,FEFPAG ;GET DESIRED # OF PAGES IN FE FILE SYSTEM
IDIV A,PAGCYL(Q2) ;COMPUTE # OF CYLINDERS
SKIPE B ;ROUND UP TO THE NEXT FULL CYLINDER
ADDI A,1 ; IF A PARTIAL CYLINDER REQUESTED
MOVEM A,FEFCYL ;SAVE # OF CYLINDERS TO ALLOCATE
IMUL A,PAGCYL(Q2) ;COMPUTE ACTUAL # OF PAGES TO ALLOCATE
SKIPE FILTYP ;SKIP IF BOOTSTRAP.BIN SINCE IT REALLY
;DOESN'T NEED A FULL CYL OF SPACE
MOVEM A,FEFPAG ;SAVE ACTUAL # OF PAGES TO ALLOCATE
IMUL P1,CYLUNT(Q2) ;NOW GET FIRST CYLINDER ON PACK
MOVE P2,P1 ;MOVE TRACK NUMBER
ADD P1,CYLUNT(Q2) ;LAST TRACK ON THE PACK
SOS P1 ; ...
MOVE A,STRN13 ;1/STRUCTURE NUMBER
CALL MAPBTB ;MAP INDEX BLOCK INTO BTBBAS, LOCK INTO CORE,
; LOCK BTBLCK, GO NOSKED
;A DUAL-PORTED DRIVE HAS BEEN FOUND. FIND A BLOCK OF CONTIGUOUS
;CYLINDERS LARGE ENOUGH TO HOLD THE FRONT END FILE SYSTEM.
;EACH CYLINDER IN THE BLOCK MUST HAVE ALL ITS PAGES FREE
;P2/CYLINDER NUMBER RELATIVE TO START OF STRUCTURE FOR FIRST CYLINDER
; ON THIS UNIT
;P1/CYLINDER NUMBER RELATIVE TO START OF STRUCTURE FOR LAST CYLINDER
; ON THIS UNIT
FEFSY3: MOVE C,FEFCYL ;GET # OF CYLINDERS TO ALLOCATE
ADD C,P2 ;COMPUTE LAST CYLINDER # TO ALLOCATE
CAML C,P1 ;ENOUGH SPACE LEFT ON THIS PACK ?
JRST [ MOVE A,STRN13 ;NO, GET STRUCTURE NUMBER
CALL UMPBTB ;GO UNMAP THE BIT TABLE AND RETURN FAILURE
JRST FEFER0] ;GO RELEASE LOCAL VARIABLE BLOCK AND RETURN
MOVE D,P2 ;GET NUMBER OF FIRST CYLINDER TO USE
MOVN P2,FEFCYL ;GET -<# OF CYLINDERS TO ALLOCATE>
ADD D,BTBORA ;COMPUTE ADDRESS IN BIT TABLE
MOVE C,PAGCYL(Q2) ;GET # OF PAGES ON EACH CYLINDER FOR THIS PACK
FEFSY4: CAME C,0(D) ;THIS ONE GOOD?
JRST FEFSY5 ;NO
AOS D
AOJL P2,FEFSY4 ;YES. DO ALL OF THEM
MOVE P2,D ;GET SIZE
SUB P2,BTBORA ;SUBTRACT BIT MAP START
SUB P2,FEFCYL ;BACK UP TO BEGINNING
JRST FEFSY6 ;FOUND A REGION
FEFSY5: XMOVEI P2,1(D) ;SKIP THIS BAD TRACK AND GO ON
SUB P2,BTBORA ;RESTORE TRACK NUMBER
JRST FEFSY3 ;AND TRY AGAIN
;FOUND A REGION TO ALLOCATE.
; P2/ LOWEST TRACK NUMBER IN REGION
FEFSY6: MOVE A,STRN13 ;1/STRUCTURE NUMBER
CALL UMPBTB ;UNMAP INDEX BLOCK FROM BTBBAS, UNLOCK CORE PAGE,
; UNLOCK BTBLCK, GO OKSKED
MOVEI P1,0(P2) ;GET FIRST TRACK NUMBER
IMUL P1,SECCYL(Q2) ;CONVERT TO SECTOR NUMBER
MOVE P3,FEFPAG ;GET # OF PAGES TO ALLOCATE
MOVE P2,P1 ;SAVE STARTING SECTOR
;WRITE THE HOME BLOCK SAYING THIS PACK HAS THE FE FILE SYSTEM
CALL ASGPAG ;GET A PAGE
JRST FEFER0 ;FAILED, RELEASE LOCAL VARIABLE BLOCK AND RETURN
MOVE Q3,A ;SAVE PAGE
MOVE B,P4 ;GET SDBUDB POINTER
MOVE C,P1 ;START SECTOR
MOVE D,P3 ;# OF PAGES
SKIPN FILTYP ;CHECK FILE TYPE
JRST [CALL BOWRTH ;WRITE BOOT FILE
JRST FEFER1 ;RELEASE ASSIGNED PAGE AND RETURN ERROR
JRST .+3] ;SKIP OVER FE WRITE
CALL FEWRTH ;GO WRITE THE HOME BLOCK
JRST FEFER1 ;RELEASE ASSIGNED PAGE AND RETURN ERROR
; ..
;ASSIGN ALL PAGES IN THE BLOCK.
; P1/FIRST SECTOR
; P2/FIRST SECTOR
; Q2/ADDRESS OF SIZE DATA FOR THIS DISK TYPE
FEFSY7: MOVE A,P1 ;1/SECTOR NUMBER
MOVE B,STRN13 ;2/STRUCTURE NUMBER
CALL DSKASA ;ASSIGN IT
JRST FEFER1 ;FAILED, RELEASE SPACE AND RETURN ERROR
ADD P1,SECPAG(Q2) ;NEXT PAGE
SOJG P3,FEFSY7 ;ASSIGN ALL RELEVANT PAGES
;NOW THAT THE REGION IS ALLOCATED, A FILE MUST BE CREATED WHICH
;DEFINES THE SELECTED TRACKS.
; P2/ STARTING SECTOR IN REGION
HRROI A,FEFNAM ;T1/ ADDRS OF BLOCK FOR NAME
MOVE B,STRN13 ;T2/STRUCTURE NUMBER
HRROI C,[ASCIZ/<ROOT-DIRECTORY>FRONT-END-FILE-SYSTEM.BIN;P770000/]
SKIPN FILTYP ;CHECK FOR BOOT FILE
HRROI C,[ASCIZ/<ROOT-DIRECTORY>BOOTSTRAP.BIN;P770000/]
;C/ NAME OF FILE WITHOUT STRUCTURE
CALL STRST ;CREATE FILE SPEC INCLUDING THE STRUCTURE NAME
; IN FREE SPACE POINTED TO BY FEFNAM
JRST FEFERR ;FAILED. GO RELEASE FREE SPACE
MOVX A,GJ%NEW!GJ%SHT ;GTJFN ARGS
HRROI B,FEFNAM ;B/ ADDRS OF FILE NAME
GTJFN ;GET A JFN FOR IT
JRST FEFERR ;NOT THERE. CANT FIX HOME BLOCK THEN
MOVE P3,A ;SAVE THE JFN
IMULI A,MLJFN ;MAKE IT AN INTERNAL INDEX
CALL GETFDT ;GET FDB FOR THIS JFN
JRST FEFER1 ;FAILED, RELEASE LOCAL VARIABLE BLOCK AND RETURN
MOVE P4,A ;SAVE FDB LOC
MOVE B,.FBCTL(P4) ;GET CONTROL WORD
TXZ B,FB%NXF ;MAKE IT EXISTANT
TXO B,FB%LNG!FB%NOD ;AND MAKE IT LONG AND NO DUMP AS WELL
MOVEM B,.FBCTL(P4) ;BACK INTO THE FDB
CALL ASGPAG ;NOW GET ONE FOR THE SUB PAGE TABLES
JRST FEFER1 ;FAILED, RELEASE SPACE AND RETURN ERROR
MOVE P5,A ;AND SAVE THIS AS WELL
SETZ A, ;A/0 FOR FREE CHOICE OF SECTOR NUMBER
MOVE B,STRN13 ;B/STRUCTURE NUMBER
CALL DSKASN ;GET A DISK PAGE
JRST FEFER2 ;RELEASE ASSIGNED PAGES AND RETURN ERROR
MOVEM A,.FBADR(P4) ;SAVE THIS IN THE FDB
MOVE B,STRN13 ;2/STRUCTURE NUMBER
TXO A,FILNB ;SAY IS A NEW INDEX BLOCK
CALL ASROFN ;GET THE OFN
JRST FEFER2 ;FAILED, RELEASE ASSIGNED PAGES AND RETURN ERROR
MOVEM A,OFNPTT ;SAVE THE OFN OF THE PTT
CALL UPDOFN ;UPDATE IT
MOVE C,FEFPAG ;GET # OF PAGES TO ALLOCATE
HRRM C,.FBBYV(P4) ;STORE FILE SIZE
CALL USTDIR ;DONE WITH THE FDB AND THE DIRECTORY
MOVE P4,FEFPAG ;GET # OF PAGES TO ALLOCATE
TXO P2,DSKAB ;SAY THIS IS A DISK ADDRESS
MOVE A,OFNPTT ;GET OFN OF PTT
MOVEI B,0(Q3) ;PAGE TO HOLD IT
HRLI B,(PTRW) ;GET FULL ACCESS
CALL SETMPG ;GET THE PAGE
;..
FEFSY8: SETZ A, ;1/FREE CHOICE OF PAGE
MOVE B,STRN13 ;2/STRUCTURE NUMBER
CALL DSKASN ;GET A DISK PAGE
JRST FEFER3 ;FAILED; RELEASE PAGES AND OFN, RETURN ERROR
TXO A,DSKAB ;SAY IS A DISK ADDRESS
MOVEM A,0(Q3) ;TO THE PTT
MOVX B,OFNWRB ;THE OFN WRITE BIT
MOVE C,OFNPTT ;OFN OF PTT
IORM B,SPTH(C) ;SAY IT IS WRITTEN
MOVEI B,IMMCOD ;AND THAT THE POINTER IS IMMEDIATE
STOR B,PTRCOD,(Q3) ;""
AOS Q3 ;NEXT SLOT
TXO A,FILNB ;SAY IS A NEW INDEX BLOCK
MOVE B,STRN13 ;2/STRUCTURE NUMBER
CALL ASROFN ;GET AN OFN
JRST FEFER3 ;FAILED, RELEASE PAGES AND OFN; RETURN ERROR
MOVEM A,OFNPT ;SAVE IT
CALL UPDOFN ;INITIALIZE IT
MOVE A,OFNPT ;GET THE OFN
MOVEI B,0(P5) ;GET PAGE FOR THIS PT
HRLI B,(PTRW) ;FULL ACCESS
CALL SETMPG ;GET THE PAGE
MOVEI D,1000 ;SIZE OF A PT
CAIGE P4,1000 ;ROOM FOR ALL OF IT?
MOVEI D,0(P4) ;NO
SUBI P4,1000 ;NUMBER LEFT TO DO
MOVEI B,IMMCOD ;ALL POINTERS ARE IMMEDIATE
;WRITE A PAGE TABLE
FEFSY9: MOVEM P2,0(P5) ;STORE SECTOR NUMBER
STOR B,PTRCOD,(P5) ;MAKE IT IMMEDIATE
ADD P2,SECPAG(Q2) ;GO TO NEXT PAGE
SOJLE D,FEFS11 ;MORE TO DO?
ADDI P5,1
JRST FEFSY9 ;OFF TO STORE THEM ALL
FEFS11: TRZ P5,777 ;RESOTRE PAGE ADDRESS
MOVEI B,0(P5)
MOVE A,OFNPT ;GET OFN OF PT
MOVX C,OFNWRB ;THE WRITE BIT
IORM C,SPTH(A) ;SAY THE XB IS WRITTEN
SETZ A, ;UNMAP THE PAGE
CALL SETMPG ;DO IT
MOVE A,OFNPT ;RESTORE OFN OF PT
CALL RELOFN ;FREE IT
JUMPG P4,FEFSY8 ;DO THEM ALL
;HERE THE FILE IS CREATED. NOW RELEASE ALL SPACE AND RETURN
TXZ Q3,777 ;ADDRESS OF PTT IN CORE
SETZ A, ;UNMAP THE PAGE
MOVEI B,0(Q3) ;TO DO THE UNMAP
CALL SETMPG ;DO IT
MOVE A,OFNPTT ;OFN OF THE PTT
CALL RELOFN ;DO IT
MOVE A,Q3
CALL RELPAG ;RELEASE ALL JSB SPACE
MOVE A,P5
CALL RELPAG ;THIS ONE TOO
MOVE A,P3 ;THE JFN
RLJFN ;FREE THE JFN
JFCL
MOVE A,STRN13 ;A/STRUCTURE NUMBER
CALL CPYBAK ;REMAKE BACKUP OF ROOT-DIRECTORY TO
; POINT TO FRONT END FILE SYSTEM
JRST [ MOVE A,STRN13 ;GET STRUCTURE NUMBER
HRRZ A,STRTAB(A) ;POINT TO ITS SDB
LOAD A,STRUC,(A) ;GET ITS UNIQUE CODE
BUG(FEOCPB,<<T1,STRCOD>>)
JRST .+1]
RETSKP ;AND DONE
FEFER3: MOVE A,OFNPTT ;GET OFN
CALL RELOFN ;RELEASE THE OFN
;FALL INTO FEFER2
FEFER2: MOVE A,P5 ;GET ADDRESS OF ASSIGNED PAGE
CALL RELPAG ;RELEASE THE PAGE
;FALL INTO FEFER1
FEFERR:
FEFER1: MOVE A,Q3 ;GET ADDRESS OF ASSIGNED PAGE
CALL RELPAG ;RELEASE THE PAGE
SE1CAL ;FIXUP FOR SECTION 1 RETURNS TO 0
FEFER0: RET
;ROUTINE TO WRITE FE BOOT BLOCK ON PACK WITH FE FILE SYSTEM.
;ACCEPTS: A/ UDB
;RETURNS +1 ALWAYS
WRBOOT: SAVEP ;PRESERVE REGS
MOVE P1,A ;SAVE UDB
CALL ASGPAG ;GET A WORK PAGE
RET ;DON'T DO IT THEN
MOVE P2,A ;SAVE PAGE ADDRESS
HRLI A,BOOTST ;MOVE FE BOOT BLOCK
BLT A,BOOTLN-1(P2) ;MOVE BOOT DATA
MOVE A,P2 ;THE ADDRESS AGAIN
CALL MLKMA ;LOCK IT DOWN
LSH A,PGSFT ;MAKE IT A CORE ADDRESS
MOVE P3,A ;SAVE IT
MOVE T3,P1 ;GET UDB
CALL FNDCH1 ;RETURN THE CKU NUMBERS NEEDED
MOVE D,T1 ;PUT INTO RIGHT AC
SETZ A, ;DO BLOCK 0
MOVE B,[1B0+1B14+HBLEN] ;WRITE ONE BLOCK
MOVE C,P3 ;THE PHYSICAL ADDRESS
CALL UDSKIO ;WRITE IT OUT
MOVE A,P3 ;THE PHYSICAL ADDRESS
LSH A,-PGSFT ;GET PAGE ADDRESS
CALL MULKCR ;UNLOCK IT
MOVE A,P2 ;THE WORK PAGE
CALLRET RELPAG ;GET RID OF IT
;THE BOOT DATA FOR THE FE
;THIS CODE IS POSITION INDEPENDENT AND IT CAN BE LOCATED ANYWHERE
;IN MEMORY (THAT IS THE CODE FROM BOOT11 DOWN.).
BOOTST:
BOOTBK:
BOOT11: 5,,12706 ;RESET,MOVE #1000,SP
1000,,10700 ;MOV PC,R0
62700,,36 ;ADD #BOTMSG-.,R0
112001,,1403 ;MOVB (R0)+,R1,BEQ 20$
4767,,4
773,,0 ;BR 10$,HALT
110137,,177566 ;MOVB R1,@#TPB
105737,,177564
100375,,207 ;BPL 10$,RET
BTMSG: 5015,,20012
20040,,25052
52052,,44510
20123,,47526
52514,,42515
42040,,42517
20123,,47516
20124,,47503
52116,,44501
20116,,20101
40510,,42122
40527,,42522
41040,,47517
40524,,46102
20105,,54523
52123,,46505
25040,,25052
5015,,12
BOOTLN==.-BOOTBK ;LENGTH OF THIS DATA BLOCK
;FEWRTH - SUBROUTINE TO WRITE THE HOME BLOCKS FOR THE FRONT END FILE
;BOWRTH - SUBROUTINE TO WRITE THE HOME BLOCKS FOR THE BOOTSTRAP FILE
;SYSTEM.
;ACCEPTS:
; A/ VIRTUAL ADDRESS OF WORK PAGE
; B/ ADDRESS OF SDBUDB FOR THE UNIT
; C/ SECTOR NUMBER OF START OF FRONT END FILE SYSTEM
; D/# OF PAGES IN FRONT END FILE SYSTEM
; CALL FEWRTH
; CALL BOWRTH
;RETURNS +1: FAILURE
; +2: SUCCESS
;THE CALLER HAS ESTABLISHED WHICH UNIT IS TO CONTAIN THE FRONT END OR BOOTSTRAP
;FILE SYSTEM. THIS ROUTINE WRITES INTO THAT PACK'S HOME BLOCKS THE
;STARTING SECTOR AND LENGTH OF THE FRONT END FILE SYSTEM.
BOWRTH: SAVEPQ ;SAVE WORK CELLS
SETZ Q2,0 ;SET BOOT FLAG
JRST FEWCOM ;GO TO COMMON PART
FEWRTH: SAVEPQ ;SAVE WORK CELLS
SETO Q2,0 ;SET FE FLAG
FEWCOM: SETZM P2 ;INITIALIZE ERROR REGISTER
MOVE Q3,A ;SAVE VIRTUAL ADDRESS OF WORK PAGE
MOVE P4,B ;SDBUDB ADDRESS
MOVE P1,C ;START SECTOR OF FRONT END FILE SYSTEM
MOVE P3,D ;# OF PAGES IN FRONT END FILE SYSTEM
CALL MLKMA ;LOCK IT DOWN FOR THE I/O
LSH A,PGSFT ;MAKE PHYSICAL ADDRESS
MOVE P5,A ;SAVE PHYSICAL ADDRESS OF WORK PAGE
CALL FNDCHN ;GET THE CKU VALUE (CHAN, CTRL, UNIT NUMBERS)
MOVEM A,Q1 ;SAVE IT
MOVE B,P5 ;PHYSICAL ADDRESS OF WORK PAGE
MOVEI C,HM1BLK ;HOME BLOCK SECTOR NUMBER
MOVE D,Q3 ;VIRTUAL ADDRESS OF WORK PAGE
CALL REDHOM ;READ THE HOME BLOCKS
JRST [ SETOM P2 ;NOTE FAILURE
JRST FWRT10 ] ;GO UNLOCK THE PAGE
MOVE A,P1 ;SECTOR NUMBER OF START OF FEFS
TLO A,(1B4) ;EXISTANT BIT
SKIPN Q2 ;CHECK FOR BOOT FLAG
ADDI Q3,HOMFE2-HOMFE0 ;CHEAT A LITTLE HERE TO POINT TO BOOT AREA IN HOME BLOCK
DPB A,[POINT ^D16,HOMFE0(Q3),35] ;STORE IN FIRST HOME BLOCK
DPB A,[POINT ^D16,HOMFE0+HBLEN(Q3),35] ;STORE IN 2ND HOME BLOCK
LSH A,-^D16 ;GET UPPER 16 BITS
DPB A,[POINT ^D16,HOMFE0(Q3),17]
DPB A,[POINT ^D16,HOMFE0+HBLEN(Q3),17]
MOVE A,P3 ;GET NUMBER OF PAGES
MOVE B,STRTY1 ;GET ADDRESS OF SIZE DATA FOR THIS DISK TYPE
IMUL A,SECPAG(B) ;CONVERT PAGES TO SECTORS
DPB A,[POINT ^D16,HOMFE1(Q3),35]
DPB A,[POINT ^D16,HOMFE1+HBLEN(Q3),35]
LSH A,-^D16
DPB A,[POINT ^D16,HOMFE1(Q3),17]
DPB A,[POINT ^D16,HOMFE1+HBLEN(Q3),17]
MOVE A,P5 ;A/ PHYSICAL ADDRESS FOR WORK PAGE
MOVE B,Q1 ;B/ CKU NUMBERS
MOVE C,Q3 ;C/ VIRTUAL ADDRESS OF WORK PAGE
CALL UPDHOM ;WRITE BOTH HOME BLOCKS TO THE DISK
SETOM P2 ;NOTE OCCURRENCE OF ERROR
FWRT10: MOVE A,P5 ;GET CORE ADDRESS
LSH A,-PGSFT ;MAKE IT A CORE PAGE NUMBER
CALL MULKCR ;UNLOCK IT
SKIPE P2 ;ANY ERRORS FOUND ?
RET ;AND DONE
RETSKP ;NO, GIVE SUCCESS RETURN
;ROUTINE CALLED FROM FILINI AND MSTR TO PUT THE FRONT END FILE SYSTEM
;OR THE BOOTSTRAP.BIN FILE
;POINTERS INTO THE HOME BLOCK ON THE RELEVANT PACK. THIS IS
;CALLED WHENEVER THE MONITOR HAS BEEN REQUESTED TO REWRITE
;THE HOME BLOCKS, BUT NOT DO A FILE SYSTEM REFRESH.
;ACCEPTS:
; A/STRUCTURE NUMBER
;RETURNS +1: FAILURE
; +2: SUCCESS
FIXBOT::TDZA B,B ;SET BOOT FLAG
FIXFES::SETO B, ;SET FE FLAG
SE1CAL
TRVAR <STRTY1> ;ADDRESS OF SIZE DATA FOR THIS DISK TYPE
STKVAR <STRN14,SVPAGE,SVSIZE,SVDISK,SVPHYS,NAMBLK,TYPBLK>
MOVEM B,TYPBLK ;SAVE ENTRY FLAG
MOVEM A,STRN14 ;SAVE STRUCTURE NUMBER
MOVEI B,^D12 ;GET SOME FREE SPACE TO BUILD THE FILE
CALL ASGJFR ; SPEC IN (INCLUDING STRUCTURE NAME)
RET ;FAILED TO GET IT
MOVEM A,NAMBLK ;SAVE ADDRESS OF HEADER FOR STRING SPACE
HRROI A,1(A) ;T1/ADDRESS OF FREE SPACE (AFTER HEADER)
MOVE B,STRN14 ;T2/STRUCTURE NUMBER
HRROI C,[ASCIZ/<ROOT-DIRECTORY>FRONT-END-FILE-SYSTEM.BIN.1/]
SKIPN TYPBLK ;CHECK FOR BOOTSTRAP FILE
HRROI C,[ASCIZ/<ROOT-DIRECTORY>BOOTSTRAP.BIN.1/]
;C/ NAME OF FILE WITHOUT STRUCTURE
CALL STRST ;CREATE FILE SPEC INCLUDING THE STRUCTURE NAME
; IN FREE SPACE POINTED TO BY NAMBLK
JRST FIXFE2 ;FAILED. RELEASE SPACE AND RETURN
MOVX A,GJ%OLD!GJ%SHT ;GTJFN ARGS
HRRO B,NAMBLK ;B/ADDRESS OF FILE NAME
ADDI B,1 ;POINT BEYOND HEADER
GTJFN ;GET A JFN FOR IT
JRST FIXFE2 ;FAILED. RELEASE SPACE AND RETURN
MOVEM A,SVPAGE ;STASH AWAY JFN
MOVEI A,JSBFRE ;A/RETURNING SPACE IN JSB
MOVE B,NAMBLK ;B/ADDRESS OF BLOCK
CALL RELFRE ;RETURN THE FREE SPACE
SETZM NAMBLK ;INITIALIZE ERROR FLAG
MOVE A,SVPAGE ;RESTORE JFN
IMULI A,MLJFN ;MAKE IT AN INTERNAL INDEX
CALL GETFDT ;GO FIND FILE'S FDB
JRST [ MOVE A,SVPAGE ;GET JFN BACK AGAIN
RLJFN ;RELEASE THE JFN
JFCL ;IGNORE FAILURE
RET ] ;GIVE FAIL RETURN
HRRZ B,.FBBYV(A) ;GET SIZE OF FILE
MOVEM B,SVSIZE ;SAVE IT
MOVE B,.FBADR(A) ;GET DISK ADDRESS
MOVEM B,SVDISK ;REMEMBER IT
CALL USTDIR ;DONE WITH THE DIRECTORY
MOVE A,SVPAGE ;THE JFN
RLJFN ;CLEAN IT UP
JFCL
CALL ASGPAG ;GO GET A PAGE
RET ;FAILED, GIVE FAIL RETURN
MOVEM A,SVPAGE ;REMEMBER IT
CALL MLKMA ;LOCK IT DOWN
LSH A,PGSFT ;MAKE IT A CORE ADDRESS
MOVEM A,SVPHYS ;REMEMBER IT
MOVE C,A
MOVE A,SVDISK ;THE ADDRESS
MOVEI B,1000 ;COUNT
MOVE D,STRN14 ;D/STRUCTURE NUMBER
CALL UDSKIO ;READ IN INDEX
SKIPE A ;GOT IT?
FIXFE1: JRST [ MOVE A,SVPHYS ;NO, GET PHYS ADR
LSH A,-PGSFT ;CONVERT TO PAGE
CALL MULKCR ;UNLOCK PAGE
MOVE A,SVPAGE ;GET PAGE #
CALLRET RELPAG] ;RELEASE THE PAGE AND RETURN FAILURE
HRRZ A,SVPAGE ;GET ADDRESS OF FIRST INDEX BLOCK
MOVE A,0(A)
MOVEI B,1000
MOVE C,SVPHYS ;THE PHYSICAL ADDRESS
MOVE D,STRN14 ;D/STRUCTURE NUMBER
CALL UDSKIO
JUMPN A,FIXFE1 ;IF FAILED GO COMPLAIN
MOVE A,SVPAGE ;GET ADDRESS OF FIRST PAGE
MOVE A,0(A)
TLZ A,DSKMSK ;ONLY USE GOOD BITS
EXCH A,SVPHYS ;GET PHYSICAL ADDRESS
LSH A,-PGSFT ;MAKE IT A PAGE ADDRESS
CALL MULKCR ;FREE IT
MOVE B,STRN14 ;GET STRUCTURE NUMBER
HRRZ D,STRTAB(B) ;FIND START OF SDB'S
MOVE C,SDBTYP(D) ;POINT TO SIZE DATA FOR THIS DISK TYPE
MOVEM C,STRTY1 ;SAVE FOR FEWRTH
MOVE A,SVPHYS ;GET DISK ADDRESS
IDIV A,SECUNT(C) ;GET UNIT NUMBER
MOVEI B,SDBUDB(D) ;THE FIRST ONE
ADDI B,0(A) ;ADDRESS OF SDBUDB
MOVE A,SVPAGE ;THE WORK ADDRESS
MOVE C,SVPHYS ;FIRST SECTOR
MOVE D,SVSIZE ;# OF PAGES
SKIPN TYPBLK ;CHECK WHICH TO WRITE
JRST [ CALL BOWRTH ;WRITE BOOT
SETOM NAMBLK ;FAILED, NOTE ERROR
JRST .+3]
CALL FEWRTH ;GO FIX HOME BLOCK
SETOM NAMBLK ;FAILED, NOTE ERROR
MOVE A,SVPAGE ;THE PAGE
CALL RELPAG ;AND DONE
SKIPE NAMBLK ;ANY ERRORS ?
RET ;YES, RETURN FAILURE
RETSKP ;NO, RETURN SUCCESS
;GOT AN ERROR AFTER THE CALL TO ASGJFR AND BEFORE THE CALL TO RELFRE
;RELEASE THE SPACE
FIXFE2: MOVEI T1,JSBFRE ;T1/RETURNING SPACE IN THE JSB
MOVE T2,NAMBLK ;T2/START OF BLOCK
CALL RELFRE ;RELEASE THE SPACE WE GOT BEFORE
RET
;GTFESZ - GET THE SIZE OF THE FRONT END FILE SYSTEM
;GTBTSZ - GET THE SIZE OF THE BOOTSTRAP FILE
;ACCEPTS:
; T1/STRUCTURE NUMBER
; CALL GTFESZ
; CALL GTBTSZ
;RETURNS +1: INTERNAL ERROR
; +2: NO ERROR,
; T1/NUMBER OF PAGES (0 IS POSSIBLE)
;THIS ROUTINE IS CALLED WHEN THE FILE SYSTEM IS BEING REFRESHED AND THE
;HOME BLOCKS ARE NOT BEING REWRITTEN. IT OBTAINS THE SIZE OF THE FRONT END
;FILE SYSTEM FROM THE HOME BLOCKS OF THE UNIT THAT CONTAINS THE FILE.
;THIS NUMBER WILL BE PASSED TO FEFSYS, WHICH CREATES THE FILE
;<ROOT-DIRECTORY>FRONT-END-FILE-SYSTEM.BIN.
;SINCE FEFSYS LOOKS FOR A DUAL-PORTED DRIVE, AND SINCE THE PACK THAT
;PRESENTLY CONTAINS THE FILE MAY NOT BE DUAL-PORTED, THE WORDS IN THE
;HOME BLOCK THAT POINT TO THE FRONT END FILE SYSTEM ARE ZEROED BY THIS
;ROUTINE. FEFSYS WILL REWRITE THE HOME BLOCKS FOR THE UNIT THAT IT PICKS.
GTBTSZ::TDZA T2,T2 ;FLAG ENTRY TYPE
GTFESZ::SETO T2,0
SE1CAL
SAVEQ
STKVAR <GTFEST,GTFEVA,GTFEPA,GTFECU,GTTYPE>
MOVEM T2,GTTYPE ;SAVE ENTRY TYPE
MOVEM T1,GTFEST ;SAVE STRUCTURE NUMBER
NOINT ;NO INTERRUPTS WHILE FREE PAGE IS ASSIGNTED
CALL ASGPAG ;GET A PAGE TO READ HOME BLOCKS INTO
RETBAD(,<OKINT>) ;FAILED. NO SPACE AVAILABLE
MOVEM T1,GTFEVA ;SAVE VIRTUAL ADDRESS OF START OF PAGE
CALL MLKMA ;LOCK DOWN THE PAGE INTO CORE
LSH T1,PGSFT ;CONVERT PAGE NUMBER TO PHYSICAL ADDRESS
MOVEM T1,GTFEPA ;SAVE PHYSICAL ADDRESS OF WORK PAGE
MOVE T2,GTFEST ;GET STRUCTURE NUMBER
MOVE T2,STRTAB(T2) ;POINT TO SDB FOR THIS STRUCTURE
LOAD Q1,STRNUM,(T2) ;GET NUMBER OF UNITS IN THIS STRUCTURE
MOVNS Q1 ;GET NEGATIVE NUMBER
HRLZS Q1 ;SET UP AOBJN POINTER TO UNITS
HRRI Q1,SDBUDB(T2) ;Q1/(-COUNT,,SDBUDB ADDRESS)
GTFES1: MOVE T3,0(Q1) ;GET ADDRESS OF UDB FOR THIS LOGICAL UNIT
CALL FNDCH1 ;GET THE CKU NUMBER FOR THE UNIT
MOVEM T1,GTFECU ;SAVE FOR LATER
MOVE T2,GTFEPA ;T2/PHYSICAL ADDRESS OF WORK PAGE
MOVEI T3,HM1BLK ;T3/SECTOR NUMBER OF FIRST HOME BLOCK
MOVE T4,GTFEVA ;T4/VIRTUAL ADDRESS OF WORK PAGE
CALL REDHOM ;READ THE FIRST HOME BLOCK
JRST GTFES2 ;DRIVE IS OFF-LINE. IGNORE IT
MOVE T3,GTFEVA ;POINT TO START OF WORK PAGE
SKIPN GTTYPE ;CHECK TYPE SO CORRECT WORD IS FOUND
ADDI T3,HOMFE2-HOMFE0
MOVE T2,HOMFE0(T3) ;GET NUMBER OF SECTORS IN FEFS
TXNE T2,1B2 ;DOES THIS PACK HAVE THE FRONT END FILE SYSTEM?
JRST GTFES3 ;YES. GO GET THE INFORMATION
GTFES2: AOBJN Q1,GTFES1 ;NO. GO TO NEXT UNIT
SETZ Q3, ;INDICATE NO FRONT END FILE SYSTEM IN STRUCTURE
JRST GTFES4 ;GO CLEAN UP AND EXIT
;THIS UNIT HAS THE FRONT END FILE SYSTEM. GET ITS SIZE IN SECTORS
;THEN CLEAR THIS FIELD IN THE HOME BLOCKS SO THAT FEFSYS CAN PUT THE
;FRONT END FILE SYSTEM IN WHATEVER PACK IT CHOOSES
GTFES3: LDB Q3,[POINT ^D16,HOMFE1(T3),17]
LSH Q3,^D16 ;SHIFT LEFT HALF LEFT 16 BITS
LDB T2,[POINT ^D16,HOMFE1(T3),35]
IORM T2,Q3 ;STORE RIGHT HALF IN RIGHT 16 BITS
SETZM HOMFE0(T3) ;CLEAR THE STARTING SECTOR IN THE FIRST HOME BLOCK
SETZM HOMFE0+HBLEN(T3) ;CLEAR IT IN THE SECOND HOME BLOCK
SETZM HOMFE1(T3) ;CLEAR THE COUNT IN THE FIRST HOME BLOCK
SETZM HOMFE1+HBLEN(T3) ;CLEAR IT IN THE SECOND HOME BLOCK
MOVE T1,GTFEPA ;T1/PHYSICAL ADDRESS OF PAGE CONTAINING HOME BLOCKS
MOVE T2,GTFECU ;T2/ CKU NUMBERS
CALL UPDHOM ;REWRITE THE HOME BLOCKS
JFCL ;IGNORE FAILURE
;RELEASE THE PAGE AND EXIT
GTFES4: MOVE T1,GTFEPA ;GET PHYSICAL ADDRESS OF START OF PAGE
LSH T1,-PGSFT ;T1/PAGE NUMBER OF LOCKED PAGE
CALL MULKCR ;UNLOCK THE CORE PAGE
MOVE T1,GTFEVA ;T1/VIRTUAL ADDRESS OF WORK PAGE
CALL RELPAG ;RELEASE THE PAGE IN JSB FREE SPACE
OKINT ;ALLOW INTERRUPTS
MOVE T2,GTFEST ;GET STRUCTURE NUMBER
MOVE T2,STRTAB(T2) ;POINT TO SDB FOR THIS STRUCTURE
MOVE T2,SDBTYP(T2) ;POINT TO SIZE DATA FOR THIS TYPE OF DISK
MOVE T1,Q3 ;GET SIZE IN SECTORS
IDIV T1,SECPAG(T2) ;CONVERT TO NUMBER OF PAGES (FEWRTH MADE
; IT AN INTEGRAL NUMBER)
RETSKP ;TAKE SUCCESS RETURN
;THIS ROUTINE VERIFIES THE BAT BLOCKS.
;ACEPTS A/MASK RETURNED BY GETBAT
; B/CORE ADDRESS
; C/UDB POINTER
;
;RETURNS +1 NO GOOD BLOCKS
; +2 B POINTS TO A GOOD BAT BLOCK
VERBAT::SAVEP
MOVE P2,C ; SAVE DRIVE
MOVE P1,B ; SAVE ADDRESS
MOVE P3,A ; SAVE MASK
TLNN P3,(1B0) ; 1 OK?
JRST NO1 ; NO
TLNE P3,(1B1) ; 2 OK?
RETSKP ; ALL WELL
MOVEI A,HBLEN(P1) ;CORE ADDRESS
HRLI A,(P1) ; CORE ADDRESS OF PRIMARY
BLT A,<2*HBLEN-2>(P1) ;COPY TO THE SECONDARY
MOVEI A,BATBL1+HM2BLK-HM1BLK ;ADDRESS OF SECONDARY
MOVEM A,BATBLK+HBLEN(P1) ;STORE BLOCK NUMBER
RETSKP
NO1: TLNN P3,(1B1) ; 2 GOOD?
JRST [ MOVX A,US.BAT ;SAY NO BATS ON THIS GUY
IORM A,UDBSTS(P2) ;MARK BIT
BUG(BADBAT)
RET] ;AND GIVE UP
MOVEI A,(P1)
HRLI A,HBLEN(P1) ;TO THE SECONDARY
BLT A,<HBLEN-2>(P1) ;MOVE SECONDARY TO THE PRIMARY
MOVEI A,BATBL1 ;ADDRESS OF BAT BLOCK
MOVEM A,BATBLK(P1) ;STORE BLOCK NUMBER
RETSKP ;AND RETURN
;ROUTINE CALLED BY SYSERR POSTING ROUTINE TO MARK A DISK BAT
;BLOCK ON A "HARD" DISK ERROR. ACCEPTS:
; 1/ UDB POINTER
; 2/LOCAL LINEAR DISK ADDRESS
;
;RETURNS: +1 ALWAYS WITH BAT BLOCK UPDATED
BATQ:: SAVEP ;YES. SAVE SOME REGISTERS
NOINT ; NO INTS WHILST PAGE IS LOCKED
MOVEI P5,FPG3A ;ADDRESS OF BAT BLOCK
MOVE P4,A ;SAVE UDB INDEX
MOVE P3,B ;SAVE LOCAL DISK ADDRESS
MOVEI A,FPG3A ;USE ALTERNATE XB PAGE
CALL MLKMA ;LOCK IT DOWN
LSH A,PGSFT ;MAKE IT A CORE ADDRESS
MOVE P1,A ;SAVE IT
MOVEI A,0(P4) ;UDB POINTER
CALL LKBAT ;LOCK DOWN THE BAT BLOCK
JRST BATQE ;FAILED. MUST BE DONE THEN
MOVEI C,0(P4) ;UDB INDEX
CALL FNDCH1 ;GO GET CKU NUMBERS
MOVE P2,A ;SAVE THEM
MOVE B,P1 ;PHYSICAL CORE ADDRESS
MOVEI C,FPG3A ;VIRTUAL ADDRESS
CALL GETBAT ;GET THE BAT BLOCKS
MOVEI B,FPG3A ;VIRTUAL ADDRESS
MOVEI C,0(P4) ;UDB INDEX
CALL VERBAT ;GO VERIFY BAT BLOCKS
JRST BATQE ;ALL DONE
; ..
; ..
;HERE WHEN CORRECT BAT BLOCKS ARE IN FPG3A. P3=LOCAL DISK ADDRESS
;P4= UDB INDEX P1=PHYSCIAL CORE ADDRESS P2=CKU NUMBER
GOTDRV: MOVE A,P3 ;GET LOCAL ADDRESS
MOVEI B,FPG3A ;AND WHERE THE BAT BLOCK IS
MOVE C,P4 ;GET UDB ADDRESS
CALL SEEADR ;SEE IF IN THE PAGE YET
JRST GTDRV1 ;NO. MUST ADD IT THEN
MOVE P3,A ;SAVE DISK ADDRESS
MOVEI C,HBLEN(B) ;SET UP POINTER TO PAIR
JRST UPDBLK ;GO SET VALUES
;MUST INSERT THE ADDRESS IN THE BAT BLOCK
GTDRV1: MOVE P3,A ;SAVE DISK ADDRESS
LOAD B,BTMCT,(P5) ;GET NUMBER OF PAIRS ADDED BY MONITOR
JUMPE B,ADDPR ;NONE. MUST ADD A PAIR THEN
MOVNI B,(B) ;GET NEG
LOAD C,BTHCT,(P5) ;GET PAIRS ADDED BY MAPPER
LSH C,1 ;MAKE IT A WORD COUNT
ADDI C,FPG3A+BAT1P ;GET START OF MONITOR PAIRS
HRLI C,0(B) ;FORM AOBJN WORD
DOPAIR: LOAD A,BATNB,(C) ;GET NUMBER OF BAD SPOTS IN THIS REGION
CAILE A,MAXBAD-4 ;ROOM FOR ANOTHER PAGE?
JRST NXTPR ;NO. GO ON
LOAD A,BADT,(C) ;GET TYPE OF THIS ENTRY
SKIPE A ;OLD OR NEW?
JRST [ LOAD A,ADD27,(C) ;NEW
JRST DOPA1] ;GO INLINE
LOAD A,ADD18,(C) ;OLD. GET SHORT ADDRESS
DOPA1: LOAD D,BATNB,(C) ;GET NUMBER
ADD D,A ;GET END ADDRESS
ADDI D,1 ;ONE MORE PLEASE
SUBI A,4 ;GET PREVIOUS PAGE
CAMN A,P3 ;IS THIS IMMEDIATELY PRECEEDING PAGE?
JRST [ STOR P3,ADD27,(C) ;MAKE THIS THW NEW START
MOVEI D,HBLEN(C) ;POINT TO THE SECONDARY
STOR P3,ADD27,(D) ;UPDATE THE SECONDARY
JRST CMNPAR] ;GO DO COMMON STUFF
CAME D,P3 ;AT THE END?
JRST NXTPR ;NO. GO TO NEXT PAIR
CMNPAR: LOAD B,BATNB,(C) ;GET COUNT
ADDI B,4 ;NEW COUNT
STOR B,BATNB,(C)
MOVEI D,1 ;JUTS IN CASE
STOR D,BADT,(C) ;MAKE IT A NEW TYPE
ADDI C,HBLEN ;POINT TO THE SECONDARY
STOR B,BATNB,(C) ;UPDATE THIS NODE COUNT
STOR D,BADT,(C) ;AND SET TYPE
JRST UPDBLK ;GO PUT IN COMMON STUFF
NXTPR: AOS C
AOBJN C,DOPAIR
; ..
; ..
;HERE IF MUST ADD A NEW PAIR
; TCO 4.2041 CALL BATSPC BEFORE BUMPING MONITOR-ADDED COUNT
; AND ADJUST ADDRESS CALCULATION SO LAST BAT ENTRY IS USED.
ADDPR: MOVEI A,0(P5) ;ADDRESS OF BAT BLOCK
CALL BATSPC ;CALCULATE SPACE LEFT FOR US
LOAD B,BTMCT,(P5) ;GET COUNT ADDED BY MONITOR
AOS B
STOR B,BTMCT,(P5) ;UPDATE THIS
STOR B,BTMC2,(P5) ;AND UPDATE THE SECONDARY
SKIPN A ;ANY PAIRS LEFT?
JRST RLSNOD ;NO. GO GIVE IT UP THEN
MOVEI C,MAXBFR(A) ;ROOM USED
ADDI C,BAT1P+FPG3A ;GET REAL ADDRESS OF PAIR(TCO 4.2041 ADJUSTMENT)
MOVEI B,3 ;NUMBER IN REGION
MOVEI A,1 ;FOR TYPE
STOR B,BATNB,(C)
STOR P3,ADD27,(C) ;STORE ADDRESS
STOR A,BADT,(C) ;STORE THE TYPE
ADDI C,HBLEN ;POINT TO SECONDARY
STOR B,BATNB,(C) ;INTO SECONDARY AS WELL
STOR P3,ADD27,(C)
STOR A,BADT,(C)
UPDBLK: MOVEI D,-HBLEN(C) ;POINT TO PRIMARY
MOVEI A,1 ;A BIT TO SHIFT
LOAD B,DOP%U2,P2 ;UNIT NUMBER OF THIS DRIVE
;** NOTE: THIS IS POSSIBLY WORTHLESS FOR THE
;** RP20, SINCE IT HAS A CONTROLLER, AND ITS
;** UNIT NUMBER CAN BE LARGER THAN 35 ANYWAY
LSH A,PUBCNT(B) ;POSITION THE BIT
IORM A,0(C) ;MERGE IT INTO THE BLOCK
IORM A,0(D) ;AND THE PRIMARY AS WELL
CALL GAPRID ;GET APR SERIAL NUMBER
STOR A,APRNM,(C) ;AND STASH IT IN THE ENTRY
STOR A,APRNM,(D) ;AND IN THE PRIMARY AS WELL
MOVE A,UDBCDB(P4) ;GET ADDRESS OF CDB
MOVE A,CDBADR(A) ;GET MASSBUS CONTROLLER #
STOR A,BTKNM,(C) ;TO THE BAT BLOCK
STOR A,BTKNM,(D) ;AND THE OTHER AS WELL
;NOW WRITE THE BAT BLOCK OUT
RLSNOD: MOVE A,P2 ;GET CHAN, CTRL, AND UNIT NUMBERS
MOVE B,P5 ;GET VIRTUAL ADDRESS
MOVE C,P1 ;AND PHYSICAL CORE ADDRESS
CALL BATOUT ;WRITE THEM
JFCL ;CAN'T DO MUCH ABOUT IT
BATQE: MOVE A,P1
LSH A,-PGSFT ;GET CORE PAGE NUMBER
CALL MULKCR ;RELEASE IT
MOVEI T1,0(P4) ;THE UDB INDEX
CALL ULKBAT ;FREE THE BAT BLOCKS
SKIPE ERRSWP ;WAS THERE A SWAP ERROR?
JRST [ ;YES THERE WAS, TAKE CARE OF IT
SOSN ERRSWP ;DEC THE COUNT, SKIP IF DONE
BUG (SWPXXX) ;CATCH ALL ERROR
JRST .+1] ;IF WE KEEP GOING, OK BY ME
OKINT ;AND ALLOW INTS NOW
RET
REPEAT 0,<
;ROUTINE TO WRITE OUT THE IN CORE BAT BLOCK IF IT HAS BEEN CHANGED
CLRPAG: JUMPL P2,R ;IF NO BAT BLOCKS, RETURN
TLNN P2,(1B1) ;HAS IT BEEN WRITTEN?
JRST CLRPG1 ;NO. JUTS UNLOCK IT
MOVEI A,0(P2) ;YES. GET UNIT
MOVE C,P1 ;AND CORE ADDRESS
CALL BATOUT ;AND WRITE THEM OUT
JFCL ;DONT CARE HERE
CLRPG1: HRRZ A,DRIVTB(P2) ;GET UNIT ID
CALL ULKBAT ;RELEASE THE BAT BLOCKS
SETO P2, ;SAY NO CURRENT UNIT
RET ;AND DONE
> ;END OF REPEAT 0
;ROUTINE TO ASSIGN THE SWAPPING BLOCKS
;ACCEPTS:
; T1/STRUCTURE NUMBER
; CALL SWPASN
;RETURNS +1: FAILED TO ASSIGN ONE OR MORE SWAPPING PAGES
; +2: SUCCESS
SWPASN: SAVEQ
STKVAR <STRN15,STRTP,STRPTR,SWPAER>
SETZM SWPAER ;INITIALLY NO ERRORS
MOVEM T1,STRN15 ;SAVE STRUCTURE NUMBER
MOVE T1,STRTAB(T1) ;POINT TO SDB FOR THIS STRUCTURE
MOVEM T1,STRPTR ;SAVE POINTER
SKIPN SDBNSS(T1) ;ANY SWAPPING ON THIS STRUCTURE ?
RETSKP ;NO, RETURN
MOVE T2,SDBTYP(T1) ;POINT TO SIZE DATA FOR THIS DISK TYPE
MOVEM T2,STRTP ;SAVE POINTER
MOVN Q1,SDBNUM(T1) ;Q1/(-NO. PACKS IN STRUCTURE,,PACK NO.)
HRLZS Q1 ;FOR ALL PACKS
;LOOP THROUGH UNITS, ASSIGNING SWAPPING PAGES
SWPAS1: MOVE Q2,SECUNT(T2) ;GET # OF SECTORS PER UNIT
IMULI Q2,0(Q1) ;GET LOGICAL ADR OF START OF THIS PACK
ADD Q2,SDBFSS(T1) ;GET START OF SWAPPING SPACE ON UNIT
MOVE Q3,SDBNSS(T1) ;GET # OF SWAPPING SECTORS PER UNIT
ADD Q3,SECPAG(T2) ;MAKE SURE TO EVEN UP TO FULL PAGE
SUBI Q3,1
MOVE T1,Q3 ;GET # OF SECTORS FOR SWAPPING
IDIV T1,SECCYL(T2) ;GET # OF PAGES FOR SWAPPING
MOVE Q3,T1 ;COULD NOT DO A IDIV TO Q3
;FOR A UNIT, ASSIGN EACH SWAPPING PAGE
SWPAS2: MOVE T1,Q2 ;GET NEXT PAGE TO BE ASSIGNED
MOVE T2,STRN15 ;T2/STRUCTURE NUMBER
CALL CYLASA ;ASSIGN THE PAGE
SETOM SWPAER ;INDICATE FAILURE
MOVE T1,STRPTR ;RESTORE POINTER TO SDB FOR STRUCTURE
MOVE T2,STRTP ;RESTORE POINTER TO SIZE DATA
ADD Q2,SECCYL(T2) ;STEP TO THE NEXT PAGE
SOJG Q3,SWPAS2 ;LOOP BACK FOR ALL PAGES ON UNIT
AOBJN Q1,SWPAS1 ;LOOP BACK FOR ALL UNITS
SKIPE SWPAER ;WERE THERE ANY ERRORS?
RETBAD ;YES. TAKE FAILURE RETURN
RETSKP ;NO. TAKE SUCCESS RETURN
;VARIABLES USED BY FSIINI ROUTINE
CTYFIL==6 ;FILLER CHARACTERS NEEDED FOR CTY
;HOME BLOCK DEFINITIONS
CODHOM==:707070 ;HOME BLOCK SPECIAL CODE
HBLEN==:200 ;LENGTH OF HOME BLOCK
HM1BLK==:1 ;BLOCK # OF FIRST HOME BLOCK
HM2BLK==:^D10 ;BLOCK # OF SECOND HOME BLOCK
HOMNAM==:0 ;SIXBIT /HOM/
HOMID==:1 ;SIXBIT /ID/
HOMPHY==:2 ;PHYSICAL ADR'S OF HOME BLOCKS
HOMSNM==:3 ;SIXBIT /STRUCTURE NAME/
HOMLUN==:4 ;XWD TOTAL PACKS, LOGICAL PACK #
HOMHOM==:5 ;BLOCK # OF HOME BLK,, BLK # OF OTHER HB
HOMP4S==:6 ;# OF PAGES FOR SWAPPING ON EACH UNIT
HOMFST==:7 ;FIRST SWAPPING TRACK ON EACH UNIT
HOMRXB==:10 ;ADR OF INDEX BLOCK OF ROOT DIRECTORY
HOMBXB==:11 ;INDEX BLOCK ADR OF BACKUP FILE
HOMFLG==:12 ;FLAGS
HOMSIZ==:13 ;SIZE OF A UNIT IN SECTORS (BLOCKS)
HOMBTB==:14 ;SIZE OF TOP HALF OF BIT TABLE (NUMBER OF TRACKS)
HOMMID==:15 ;MEDIA IDENTIFICATION (PACK UNIQUE CODE)
HOMFE0==:61 ;FE FILE SYSTEM WORD ONE (SECTOR #)
HOMFE1==:62 ;FE FILE SYSTEM WORD TWO (# OF SECTORS)
;HOME BLOCK LOCATIONS 61-100 ARE RESERVED FOR THE FRONT-END.
HOMFE2==:101 ;BOOTSTRAP.BIN WORD ONE (SECTOR #)
HOMFE3==:102 ;BOOTSTRAP.BIN WORD TWO (# OF SECTORS)
HOMSER==:164 ;SERIAL NUMBER OF CPU WHICH IS BOOTED BY THIS
; STRUCTURE
HOMUID==:165 ;UNIT ID
HOMOID==:170 ;OWNER ID
HOMFSN==:173 ;FILE SYSTEM TYPE
HOMCOD==:176 ;0 ,, CODHOM
HOMSLF==:177 ;THIS HOME BLOCK #
;ROUTINE TO DO THE FIRST PHASE OF THE FILE SYSTEM INITIALIZATION
;FOR THE PUBLIC STRUCTURE (CALLED ONLY ON SYSTEM STARTUP)
;IF THE FILE SYSTEM IS BEING INITIALIZED (STARTED AT SYSLOD),
;THEN A DIALOGUE IS ENTERED TO REWRITE THE HOME BLOCKS ON THE
;PUBLIC STRUCTURE
;WHEN THE STRUCTURE IS DEFINED, OR IF NORMAL STARTUP IS DONE, THE
;SDB AND STRTAB ENTRY ARE CREATED FOR THE PUBLIC STRUCTURE. IT IS
;ASSUMED TO BE PS, BUT THE USER MAY SPECIFY AN ALTERNATIVE.
RESCD(INIT)
;DISC ADDRESS OF INDEX FILE
DIDSC0==:5740 ;ROOT-DIR XB IS IN A FIXED PLACE
DIDSC1==:13700 ;BACKUP ROOT-DIR XB IS ALSO FIXED
DIDSCI::DIDSC0+DSKAB
DIDSCJ::DIDSC1+DSKAB ;BACKUP OF ROOT-DIR IS IN FIXED PLACE
;RS DIDSCA,1
;THIS ROUTINE USES "STARTF" TO TELL IF FILE SYSTEM IS BEING INITIALIZED.
; 0 MEANS NOT REFRESHING (STARTED AT SYSGO1),
; MI%RFS MEANS REFRESHING (STARTED AT SYSLOD)
; CALL FSIINI
;RETURNS +1: ALWAYS
FSIINI::SAVEP
TRVAR <FSIPPG,FSIPPA,FSIDIC,FSICHN,FSICTL,FSIUNT,FSIUDB,FSINAM,FSIFLG,FSINPK,FSIUSZ,FSISWP,FSITYP,FSISER,FSICUR>
MOVEI T1,HOMPGA ;GET A PAGE LOCKED DOWN TO DO IO INTO
CALL MLKMA ;LOCK IT INTO PHYSICAL PAGE
MOVEM T1,FSIPPG ;SAVE PHYSICAL PAGE NUMBER
LSH T1,PGSFT ;GET PHYSICAL ADDRESS ALSO
MOVEM T1,FSIPPA ;SAVE PHYSICAL ADR OF IO PAGE
HRROI T1,[ASCIZ/
/]
CALL FSIPSO ;START AT THE BEGINNING OF A NEW LINE
FSIIN0: SKIPE STARTF ;IS THE FILE SYSTEM BEING INITIALIZED
CALL FSIDIA ;YES, DO THE INITIALIZATION DIALOGUE
CALL CHKHOM ;GO READ HOME BLOCKS AND CHECK THEM
JRST [SKIPN T1,LPSNAM ;NO PUBLIC STR FOUND, CHECK NAMES
MOVE T1,PSNAM ;LOGICAL PS NAME NOT SET UP, USE PS NAME
MOVEM T1,FSINAM
SETZM FSICUR ;CLEAR NAME OF CURRENT STR NAME
CALL CHKHOM ;GO READ HOME BLOCKS AND CHECK THEM
JRST FSIIN1 ;NO PUBLIC STRUCTURE FOUND, GO COMPLAIN
JRST .+1]
;..
;..
REPEAT 0,<
HRROI T1,[ASCIZ/
[/]
CALL FSIPSO ;START STR MESSAGE
MOVSI P1,-STRN ;NOW TYPE OUT THE STR'S THAT ARE MOUNTED
SETZ P2, ;FIRST COUNT THEM
FSINR1: SKIPE STRTAB(P1) ;IS THERE A STR DEFINED HERE?
AOS P2 ;YES, COUNT IT
AOBJN P1,FSINR1 ;LOOP FOR ALL STRUCTURES
MOVSI P1,-STRN ;NOW TYPE NAMES
FSINR2: SKIPN T2,STRTAB(P1) ;GET POINTER TO SDB
JRST FSINR3 ;NO STR HERE
MOVE T1,SDBNAM(T2) ;GET NAME OF STR
CALL FSI6TY ;TYPE OUT NAME
SOJLE P2,FSINR4 ;ANY MORE LEFT?
HRROI T1,[ASCIZ/, /] ;ASSUME MORE THAN ONE LEFT
CAIN P2,1 ;UNLESS THERE IS EXACTLY 1 LEFT
HRROI T1,[ASCIZ/, and /]
CALL FSIPSO ;TYPE OUT COMMA BETWEEN STR NAMES
FSINR3: AOBJN P1,FSINR2 ;LOOP BACK FOR OTHER STR NAMES
FSINR4: HRROI T1,[ASCIZ/ mounted]
/]
CALL FSIPSO ;END MESSAGE
>
HRROI T1,[ASCIZ/
[/]
CALL FSIPSO ;START WITH A NEW LINE
MOVE P1,STRTAB+PSNUM ;POINT TO SDB FOR PUBLIC STRUCTURE
MOVE P1,SDBNAM(P1) ;GET ITS NAME
MOVEM P1,FSINAM ;STORE FOR POSSIBLE LATER USE
MOVE T1,P1 ;PRINT ITS NAME
CALL FSI6TY
HRROI T1,[ASCIZ/ mounted/] ;SAY IT IS MOUNTED
CALL FSIPSO
FSIIN2: HRROI T1,[ASCIZ/]
/]
CALL FSIPSO ;END THE LINE
MOVEI T1,HOMPGA ;UNLOCK THE IO PAGE
CALL MULKMP ;...
SKIPE STARTF ;IF SYSTEM BEING INIT'ED,
JRST [ MOVEI T1,PSNUM ;T1/STRUCTURE 0 (PUBLIC STRUCTURE)
CALL FSIBAT ; INIT BAT BLOCKS FOR PS
JRST .+1]
MOVE T2,CTYLNO ;WAIT FOR MESSAGES TO FINISH
CALL STADYN ;POINT TO DYNAMIC DATA
BUG(TTNAC5)
CALL TTSOBE ;SEE IF OUTPUT BUFFER IS EMPTY
JRST .-1 ;LOOP UNTIL THEY ARE TYPED
RET ;ALL DONE
FSIIN1: HRROI T1,[ASCIZ/
Have the problems mentioned above been corrected yet? /]
HRROI T2,[ASCIZ/
[When all of the problems are corrected, type "Y". If structures
need defining, then follow the file system initialization procedure.]
/]
MOVEI T3,FSIYNO ;YES OR NO ANSWER WANTED
CALL FSIASK ;GO ASK QUESTION
JRST FSIIN1 ;ERROR, REPEAT QUESTION
JUMPE T1,FSIIN1 ;IF NO, REPEAT QUESTON UNTIL YES
JRST FSIIN0 ;START OVER AGAIN
;ROUTINE TO READ ALL HOME BLOCKS AND CHECK THEIR CONSISTENCY
;THIS ROUTINE BUILDS STRTAB AND THE SDB'S FOR EACH STRUCTURE
; CALL CHKHOM
;RETURNS +1: SOMETHING IS AMISS - A MESSAGE WAS TYPED ALREADY
; +2: STRTAB AND SDB'S ARE SET UP
;USE OF NON-TEMPORARY REGISTERS:
; P1/ CURRENT CDB
; P2/ CURRENT KDB IF ANY
; P3/ CURRENT UDB
; P4/ AOBJN POINTER OVER ALL CHANNELS
CHKHOM: SAVEPQ ;SAVE PERMANENT ACS
STKVAR <CHKHOE>
CHKH20: SETOM CHKHOE ;INITIALIZE ERROR WORD TO "TRUE"
MOVSI T1,-STRN ;INITIALIZE THE STRTAB TO ZERO
SETZM STRTAB(T1) ;ZERO STRTAB
AOBJN T1,.-1 ;...
MOVN P4,MAXCHN ;SET UP TO READ EVERY HOME BLOCK
HRLZS P4 ;GET AOBJN COUNTER OF CHANNELS
CHKHO1: SKIPN P1,CHNTAB(P4) ;THIS CHANNEL EXIST?
JRST CHKHO2 ;NO, TRY NEXT ONE
CALL DGUMAP ;YES, LOOP OVER ALL UNITS ON THIS CHANNEL
CALL CKHOMU ;EXAMINE EACH UNIT ON THE CHANNEL
CHKHO2: AOBJN P4,CHKHO1 ;LOOP OVER ALL CHANNELS
;LOOP THROUGH STRUCTURES CHECKING FOR CONSISTENCY AND COMPLETENESS
MOVSI P1,-STRN ;SET UP TO LOOK AT STRTAB
CHKHO5: SKIPN P2,STRTAB(P1) ;IS THIS STR DEFINED?
JRST CHKHO7 ;NO, SKIP IT
MOVEI T1,540000 ;MAKE INTO 5B2+40000+STR NUMBER
STOR T1,STRUC,(P2) ;STORE UNIQUE CODE IN STRUCTURE DATA BLOCK
HRRZ T1,P1 ;GET STRUCTURE NUMBER
STOR T1,STRUS,(P2) ;PUT THE STR NUMBER INTO STRUC
MOVE T1,SDBSTS(P2) ;GET FLAGS
TXNE T1,HB%HBM ;IS THERE ANY INCONSISTENCY IN HOME B'S
JRST CHKH16 ;YES, GO COMPLAIN
TXNE T1,MI%MXB ;IS BIT TABLE TOO BIG?
JRST CHKH40 ;YES. GO COMPLAIN
MOVN P3,SDBNUM(P2) ;GET NUMBER OF PACKS IN THIS STR
HRLZS P3 ;SET UP AOBJN COUNTER
HRR P3,P2 ;GET ADR OF SDB
;LOOP THROUGH LOGICAL UNITS
CHKHO6: SKIPN T1,SDBUDB(P3) ;IS THERE A UNIT?
JRST CHKH11 ;NO, MISSING UNIT
TXNE T1,HB%MUN ;MULTIPLE UNIT?
JRST CHKH12 ;YES, GO COMPLAIN
TXNE T1,HB%WLK ;WRITE LOCKED?
JRST CHKH17 ;YES
;STORE INTO UDBSTR (UNIT WITHIN STRUCTURE,,STRUCTURE NUMBER)
MOVEM P1,UDBSTR(T1) ;STORE STRUCTURE NUMBER IN RH
MOVEI T2,0(P3) ;ADDRESS OF SDB FOR THIS STRUCTURE PLUS UNIT NO.
SUBI T2,0(P2) ;MINUS ADDRESS OF SDB FOR THIS STRUCTURE
HRLM T2,UDBSTR(T1) ;STORE UNIT NUMBER IN LH
TXNN T1,HB%1OK ;GOOD PRIMARY HOME BLOCK?
JRST CHKH13 ;NO
TXNN T1,HB%2OK ;GOOD BACKUP HOME BLOCK?
JRST CHKH14 ;NO
CHKH6A: AOBJN P3,CHKHO6 ;CHECK OTHER UNITS IN STR
CHKHO7: AOBJN P1,CHKHO5 ;LOOP FOR ALL STR'S
;..
;..
;ALL PACKS HAVE BEEN READ. IF THE SPECIFIED STRUCTURE WAS FOUND, THERE
;IS AN SDB FOR IT. IT MUST HAVE SWAPPING SPACE
SKIPE T1, STRTAB+PSNUM ;HAVE WE FOUND THE PUBLIC STRUCTURE?
JRST CHKH10 ;YES.
SKIPE FSINAM ;HAVE WE TRIED PS: YET?
JRST CHKHO9 ;YES
SKIPN T1,LPSNAM ;IS THERE A LOGICAL PS NAME?
MOVE T1,PSNAM ;NO, THE DEFAULT NAME IS PS
MOVEM T1,FSINAM ;STORE FOR NEXT LOOK
SETZM FSICUR ;ZERO ANY CURRENT STR LOOKING AT
JRST CHKH20 ;AND GO LOOK AGAIN
CHKHO9: HRROI T1,[ASCIZ/ System structure not found. What is its name? /]
HRROI T2,[ASCIZ/
[Type the name of a structure that is on-line and has swapping space]
/]
MOVEI T3,FSIDEV ;GET A SIXBIT DEVICE NAME
CALL FSIASK ;GET THE NAME OF THE PUBLIC STRUCTURE
JRST CHKHO9 ;FAILED. TRY AGAIN
JUMPE T1,CHKHO9 ;GAVE NO NAME. TRY AGAIN
MOVEM T1,FSINAM ;SAVE THE NAME AND GO TRY TO FIND
JRST CHKH20 ; THIS STRUCTURE
;A STRUCTURE IS DEFINED. SEE IF IT HAS SWAPPING SPACE
CHKH10: SKIPE T2,SDBNSS(T1) ;# OF SWAPPING SECTORS
JRST CHKH30 ;HAS SWAPPING. THIS IS THE PUBLIC STRUCTURE
CHKH21: MOVE T1,FSINAM ;NO. SWAPPING. COMPLAIN
CALL FSI6TY
HRROI T1,[ASCIZ/ Does not have swapping space. What is the name of the system structure? /]
HRROI T2,[ASCIZ/
[Type the name of a structure that is on-line and has swapping space]
/]
MOVEI T3,FSISIX ;GET A SIXBIT NAME
CALL FSIASK ;GET THE NAME OF THE PUBLIC STRUCTURE
JRST CHKH21 ;FAILED. TRY AGAIN
JUMPE T1,CHKH21 ;GAVE NO NAME. TRY AGAIN
MOVEM T1,FSINAM ;SAVE THE NAME
JRST CHKH20 ;GO TRY TO FIND THIS STRUCTURE
;THIS STRUCTURE IS OK. MAKE IT THE PUBLIC STRUCTURE
CHKH30: MOVEM T2,NSSUN ; IN THE PUBLIC STRUCTURE
MOVE T2,SDBFSS(T1) ;FIRST SWAPPING SECTOR
MOVEM T2,FSSUN ; IN THE PUBLIC STRUCTURE
MOVX T2,MS%DOM ;SAY THAT THIS IS A DOMESTIC STRUCTURE
IORM T2,SDBSTS(T1)
SKIPN CHKHOE ;WAS THERE AN ERROR DURING CHKHOM?
RET ;YES
RETSKP ;NO
REPEAT 0,<
;NOW SEARCH FOR A PUBLIC STR (NEEDED FOR SWAPPING)
SETZ P3, ;INITIALIZE TO SAY NO PUB BIT YET
MOVSI P1,-STRN
CHKHO8: SKIPN P2,STRTAB(P1) ;IS THIS STR DEFINED?
JRST CHKHO9 ;NO
MOVE T2,SDBNAM(P2) ;GET STRUCTURE NAME
MOVE T1,SDBSTS(P2) ;GET FLAGS
TXNE T1,HB%PUB ;IS THIS THE PUBLIC STR?
JRST CHKH20 ;YES!
CAME T2,PSNAM ;NO. IS IT PS?
JRST CHKHO9 ;NO. KEEP LOOKING
HRROI T1,[ASCIZ/? There is a non-public PS mounted.
/]
CALL FSIPSO ;YES. PRINT A MESSAGE
RET
;A STRUCTURE HAD THE PUB BIT SET. THIS QUALIFIES TO BE PS
CHKH20: CAMN T2,PSNAM ;IS IT PS?
JRST [ MOVEM P1,P3 ;YES. SAVE ITS LOCATION
JRST CHKHO9] ;GO TO THE NEXT STRUCTURE
SKIPN P3 ;NO. HAVE WE FOUND A CANDIDATE?
MOVEM P1,P3 ;NO. SAVE THIS ONE
CHKHO9: AOBJN P1,CHKHO8 ;LOOP FOR ALL STR'S
SKIPE P1,P3 ;DID WE FIND A PUB BIT?
JRST CHKH10 ;YES. GO MAKE IT BE STRUCTURE 0
;NO STRUCTURE HAD THE PUB BIT SET
HRROI T1,[ASCIZ/? No public structure mounted.
/]
CALL FSIPSO ;NO PUBLIC STR IS A FATAL ERROR
RET
;FOUND A STRUCTURE WITH HB%PUB SET. MAKE IT BE STRUCTURE 0
;P1 POINTS TO PS IF THERE WAS ONE, FIRST PUBLIC STRUCTURE OTHERWISE
CHKH10: MOVE T1,STRTAB ;GET STR 0
EXCH T1,STRTAB(P1) ;MAKE PUBLIC STR BE STR 0
MOVEM T1,STRTAB ;...
>
;ERROR CONDITIONS
;ERRORS IN A SINGLE UNIT
;MISSING UNIT IN STRUCTURE. MARK THIS AS A FATAL ERROR
;BUT LOOK AT THE REMAINING UNITS
CHKH11: HRROI T1,[ASCIZ/? Logical unit /]
CALL FSIPSO
HRRZ T1,P3 ;GET UNIT NUMBER
SUBI T1,0(P2) ;SUBTRACT OFF THE SDB ADR
CALL FSIDTY ;TYPE OUT UNIT NUMBER
HRROI T1,[ASCIZ/ missing from structure /]
HRROI P4,[ASCIZ/.
/]
JRST CHKH15 ;GO TYPE STR NAME
;MULTIPLE UNITS IN STRUCTURE. MARK THIS AS A FATAL ERROR
;BUT LOOK AT THE REMAINING UNITS
CHKH12: HRROI T1,[ASCIZ/? More than one logical unit /]
CALL FSIPSO
HRRZ T1,P3 ;GET UNIT NUMBER
SUBI T1,0(P2) ;SUBTRACT OFF THE SDB ADR
CALL FSIDTY
HRROI T1,[ASCIZ/ in structure /]
HRROI P4,[ASCIZ/.
/]
JRST CHKH15
;WRITE LOCKED UNIT. MARK THIS AS A FATAL ERROR
;BUT LOOK AT THE REMAINING UNITS
CHKH17: HRROI T1,[ASCIZ/? Logical unit /]
CALL FSIPSO
MOVEI T1,0(P3) ;GET UNIT NUMBER
SUBI T1,0(P2) ;SUBTRACT OFF THE SDB ADR
CALL FSIDTY ;TYPE OUT UNIT NUMBER
HRROI T1,[ASCIZ/ of structure /]
HRROI P4,[ASCIZ/ is write locked.
/]
JRST CHKH15
CHKH15: CALL FSIPSO
MOVE T1,SDBNAM(P2) ;GET STR NAME
CALL FSI6TY ;TYPE OUT STR NAME
MOVE T1,P4
CALL FSIPSO
SETZM CHKHOE ;INDICATE FATAL ERROR
JRST CHKH6A ;GO ON TO NEXT UNIT IN STRUCTURE
;PROBLEM WITH ONE HOME BLOCK. PRINT A WARNING BUT DON'T
;INDICATE A FATAL ERROR
CHKH13: SKIPA T1,[-1,,[ASCIZ/% Primary Home Block on "/]]
CHKH14: HRROI T1,[ASCIZ/% Backup Home Block on "/]
CALL FSIPSO ;TYPE OUT START OF MESSAGE
MOVE T1,SDBNAM(P2) ;GET STR NAME
CALL FSI6TY ;TYPE IT OUT
HRROI T1,[ASCIZ/" Logical Unit /]
CALL FSIPSO ;...
MOVEI T1,0(P3) ;GET LOGICAL UNIT NUMBER
SUBI T1,0(P2) ;SUBTRACT OFF THE SDB ADR
CALL FSIDTY ;ADD IT TO MESSAGE
HRROI T1,[ASCIZ/ is incorrect.
/]
CALL FSIPSO ;END MESSAGE
JRST CHKH6A ;LOOP BACK FOR ALL UNITS
;PROBLEMS RELATED TO A STRUCTURE
;BIT TABLE FILE IS TOO BIG FOR MONITOR'S ADDRESS SPACE
CHKH40: HRROI T1,[ASCIZ/? Bit table is too large in structure /]
JRST CHKH42
;HOME BLOCK INCONSISTENCY. MARK THIS AS A FATAL ERROR
;AND PROCEED TO THE NEXT STRUCTURE
CHKH16: HRROI T1,[ASCIZ/? Inconsistent set of packs composing structure /]
CHKH42: CALL FSIPSO
MOVE T1,SDBNAM(P2) ;GET STR NAME
CALL FSI6TY ;TYPE OUT STR NAME
HRROI T1,[ASCIZ/.
/]
CALL FSIPSO ;END MESSAGE
SETZM CHKHOE ;MARK THAT A FATAL ERROR HAPPENED
JRST CHKHO7 ;GO BACK AND LOOK AT OTHER STR'S
;SUBROUTINE CALLED BY CHKHOM TO EXAMINE THE STATE OF A PARTICULAR UNIT.
;CALLED WITH:
; P1/ CDB
; P2/ KDB IF ANY
; P3/ UDB
;RETURNS: +1 ALWAYS
;USES Q1-Q3
CKHOMU: MOVE T1,UDBSTS(P3) ;GET UNIT STATUS
TXNN T1,US.DSK ;IS THIS A DISK UNIT?
RET ;NO, DON'T EXAMINE IT
MOVE T3,P3 ;COPY UDB FOR CALL
CALL FNDCH1 ;CALCULATE THE CKU NUMBERS
MOVEM T1,Q2 ;REMEMBER FOR LATER USE
MOVE T2,FSIPPA ;GET PAGE FOR IO
MOVEI T3,HM1BLK ;GET HOME BLOCK NUMBER
MOVEI T4,HOMPGA ;GET VIRTUAL PAGE ADR TO READ INTO
CALL REDHOM ;READ IN THE HOME BLOCKS
RET ;ERROR OR OFF-LINE
MOVEI T1,HOMPGA ;NOW CHECK THE FIRST HOME BLOCK
MOVEI T2,HM1BLK ;...
CALL HBCCHK ;CHECK THE CONSISTENCY CHECKS
TXZA Q1,HB%1OK ;HOME BLOCKS BAD
TXO Q1,HB%1OK ;HOME BLOCK IS GOOD
MOVEI T1,HOMPGA+HBLEN ;NOW CHECK THE BACKUP HOME BLOCK
MOVEI T2,HM2BLK
CALL HBCCHK
TXZA Q1,HB%2OK ;BACKUP HOME BLOCK IS BAD
TXO Q1,HB%2OK ;BACKUP HOME BLOCK IS GOOD
TXNE Q1,HB%2OK ;ARE THERE ANY GOOD HOME BLOCKS
HRRI Q1,HOMPGA+HBLEN ;YES, GET ADR OF HOME BLOCK
TXNE Q1,HB%1OK ;SEE IF PRIMARY IS GOOD
HRRI Q1,HOMPGA ;YES, USE IT
TRNN Q1,-1 ;ANY HOME BLOCKS GOOD?
RET ;NO, RETURN
MOVX T1,US.WLK ;SEE IF THIS UNIT IS WRITE LOCKED
TDNE T1,UDBSTS(P3) ;...
TXO Q1,HB%WLK ;YES, SET WRITE LOCKED FLAG
HRRZ T1,Q1 ;GET ADDRESS OF HOME BLOCK
MOVE T2,HOMSER(T1) ;GET THE CPU SERIAL # OUT OF THE HOME BLOCK
CAME T2,APRSER ;IS IT THE ONE FOR THE PUBLIC STRUCTURE?
JRST [SKIPE T2,HOMSNM(T1) ;SERIAL # DOES NOT MATCH. CHECKING FOR PS?
CAME T2,FSINAM ;YES, CORRECT NAME?
RET ;NO, DON'T BUILD AN SDB, THEN
JRST .+1]
MOVE T2,HOMSNM(T1) ;GET STRUCTURE NAME
SKIPN FSICUR ;FIRST TIME THRU?
MOVEM T2,FSICUR ;YES, STORE CURRENT NAME
CAME T2,FSICUR ;ARE THEY THE SAME?
RET ;NO, DON'T BUILD AN SDB, THEN
SETZ T4, ;INDICATE NO COPYING REQUIRED
TXNN Q1,HB%1OK ;WAS FIRST HOME BLOCK OK?
MOVEI T4,CPYH2 ;NO. SET UP TO COPY THE SECONDARY
TXNN Q1,HB%2OK ;WAS SECOND HOME BLOCK OK?
MOVEI T4,CPYH1 ;NO. SET UP TO COPY PRIMARY
JUMPE T4,CHKHO8 ;BOTH OK. DON'T COPY EITHER
MOVX T1,MI%MSG ;T1/ASK FOR MESSAGE
HRRI T1,HOMPGA ;T1/VIRTUAL START OF WORK PAGE
MOVE T2,FSIPPA ;T2/PHYSICAL START OF WORK PAGE
MOVE T3,Q2 ;GET CKU NUMBERS
CALL @T4 ;COPY THE GOOD ONE INTO THE BAD ONE
JRST CHKHO8 ;FAILED. LEAVE ERROR BITS SET
TXO Q1,HB%1OK!HB%2OK ;OK, CLEAR ERROR BITS
CHKHO8: MOVE T1,Q1 ;T1/(FLAGS,,ADR OF HOME BLOCK)
MOVE T2,P3 ;T2/ADDRESS OF UDB FOR THIS UNIT
CALL BLDSTR ;GO BUILD STRTAB AND SDB
; RETURNS ADDRESS OF SDB IN T1
RET ;RAN OUT OF STR'S
;SDB BUILT AND STRTAB POINTS TO IT. STORE POINTER TO UDB+FLAGS IN SDBUDB
MOVE T2,P3 ;GET ADDRESS OF UDB
HLL T2,Q1 ;SAVE FLAGS FOR THIS UNIT
HRRZ T3,HOMLUN(Q1) ;GET LOGICAL UNIT # OF THIS UNIT
ADDI T3,SDBUDB(T1) ;GET INDEX INTO SDB FOR THIS UNIT
SKIPE 0(T3) ;GET CURRENT UDB ADR
TXO T2,HB%MUN ;MARK THAT THERE ARE MULTIPLE UNITS
IORM T2,0(T3) ;STORE UDB ADR AND FLAGS IN SDBUDB
RET ;DONE WITH THIS UNIT
;BLDSTR - ROUTINE TO SET UP SDB'S AND STRTAB
;ACCEPTS:
; T1/VIRTUAL ADDRESS OF WORK PAGE HOLDING HOME BLOCK
; T2/ADDRESS OF UDB FOR THIS UNIT
; CALL BLDSTR
;RETURNS +1: NO MORE ROOM IN STRTAB
; T1/ADDRESS OF SDB
; +2: SUCCESS,
; T1/ ADDRESS OF SDB
;THIS ROUTINE IS CALLED BY FSIINI, ONCE FOR EACH PHYSICAL UNIT
;IF AN SDB ENTRY EXISTS FOR A STRUCTURE WITH THE NAME IN THE HOME
;BLOCKS, IT ADDS THIS UNIT TO THAT STRUCTURE. IF NOT, IT CREATES
;A NEW SDB. IF ERRORS ARE DETECTED, FLAGS ARE SET IN SDBUDB (IF THE
;ERROR APPLIES TO A SINGLE UNIT) OR SDBSTS (IF IT APPLIES TO THE
;STRUCTURE). ERRORS ARE NOT INDICATED BY A +1 RETURN.
BLDSTR::STKVAR <UDBLOC>
MOVEM T2,UDBLOC ;SAVE ADDRESS OF UDB
MOVE T2,HOMSNM(T1) ;GET THE STR NAME
MOVSI T4,-STRN ;SET UP TO SEARCH FOR THIS STR NAME
BLDST1: SKIPN T3,STRTAB(T4) ;IS THIS STR DEFINED?
JRST [ MOVE T2,UDBLOC ;NOT YET, GET ADDRESS OF UDB
HRRZ T3,T4 ;ALSO GET STRUCTURE NUMBER
CALL CRTSTR ;CREATE THE SDB
MOVE T1,T3 ;FAILED, GET ADDRESS OF SDB
RETSKP] ;SLOT CREATED, TAKE SUCCESS RETURN
CAMN T2,SDBNAM(T3) ;IS THIS THE STRUCTURE WE WANT?
JRST [ MOVE T2,UDBLOC ;YES, GET ADDRESS OF UDB
CALL ADDSTR ;ADD THE UNIT TO THE STRUCTURE
MOVE T1,T3 ;FAILED, GET ADDRESS OF SDB
RETSKP] ;UNIT ADDED, TAKE SUCCESS RETURN
AOBJN T4,BLDST1 ;NO, LOOP THROUGH ALL STR'S
RETBAD ;NO MORE SLOTS AVAILABLE
;ADDSTR - ADD A UNIT TO AN EXISTING SDB
;ACCEPTS:
; T1/ VIRTUAL ADDRESS OF START OF HOME BLOCKS
; T2/ ADDRESS OF UDB FOR THIS UNIT
; T3/ ADDRESS OF SDB FOR THIS STRUCTURE
; CALL ADDSTR
;RETURNS +1: PACK DOESN'T AGREE WITH REST OF STRUCTURE
; T1/ERROR CODE
; T3/ ADDRESS OF SDB
; +2: PACK ADDED TO STRUCTURE
; T1/ ADDRESS OF SDB
ADDSTR: STKVAR <ADSUDB>
MOVEM T2,ADSUDB ;SAVE ADDRESS OF UDB
HLRZ T2,HOMLUN(T1) ;GET NUMBER OF PACKS IN STR
CAME T2,SDBNUM(T3) ;SAME AS PREVIOUS HOME BLOCK?
JRST ADDST5 ;NO, MISMATCH
MOVE T2,HOMRXB(T1) ;GET ADR OF ROOT IB
CAME T2,SDBRXB(T3) ;CHECK FOR MATCHING ADR'S
JRST ADDST5 ;NO MATCH
MOVE T2,HOMBXB(T1) ;GET ADR OF BACKUP IB
CAME T2,SDBBXB(T3)
JRST ADDST5 ;NO MATCH
MOVE T2,HOMMID(T1) ;GET MEDIA ID
CAME T2,SDBPUC(T3) ;SAME AS ID OF OTHER PACKS ?
JRST ADDST5 ;NO, FAIL
MOVE T4,ADSUDB ;GET ADDRESS OF UDB
CALL GETTYP ;GET DISK SIZE POINTER
RETBAD (MSTX17) ;INDICATE 'PACKS MUST BE OF SAME TYPE'
CAME T4,SDBTYP(T3) ;IS THE NEW DISK THE SAME SIZE
JRST ADDST5 ;NO. NO MATCH
SKIPN T2,HOMBTB(T1) ;GET SIZE OF TOP HALF OF BIT TABLE
MOVEI T2,BTBTOP ;ZERO. USE OLD STYLE SIZE
CAME T2,SDBBT0(T3) ;IS IT THE SAME AS THE REST OF THE STRUCTURE?
JRST ADDST5 ;NO. REPORT HOME BLOCKS MISMATCH
MOVE T2,HOMFLG(T1) ;GET FLAGS
IORM T2,SDBSTS(T3) ;SAVE FLAGS
MOVE T4,ADSUDB ;SET T4=ADDRESS OF UDB
CALL FIXVID ;FIX UDBVID
MOVE T1,T3 ;RETURN WITH ADR OF SDB IN T1
RETSKP
ADDST5: MOVX T2,HB%HBM ;MARK THAT THE HOME BLOCKS MISMATCH
IORM T2,SDBSTS(T3)
RETBAD (MSTX17) ;INDICATE 'PACKS MUST BE OF SAME TYPE'
;CRTSTR - CREATE A NEW SDB
;ACCEPTS:
; T1/ ADDRESS OF HOME BLOCK
; T2/ ADDRESS OF UDB FOR THIS UNIT
; T3/ OFFSET IN STRTAB FOR NEXT AVAILABLE SLOT
;
; CALL CRTSTR
;
;RETURNS +1: FAILURE, T1/ ERROR CODE
; T3/ ADDRESS OF SDB
; +2: SUCCESS, T1/ ADDRESS OF SDB
CRTSTR::ASUBR <CRTSHB,CRTUDB,CRTSSN,CRTSER> ;SAVE CALLING ARGUMENTS
SETZM CRTSER ;INDICATE NO ERRORS YET
TRNN T3,-1 ;IF STR 0, USE THE PREALLOCATED SDB
JRST [ MOVE T1,[SDBBL0,,SDBBL0+1]
SETZM SDBBL0 ;GET A ZERO
BLT T1,SDBBL0+SDBLN-1 ;CLEAR THE SDB
MOVEI T1,SDBBL0 ;GET ADDRESS OF PS SDB
JRST CRTST1] ;AND PROCEED
MOVEI T1,SDBLN ;GET SPACE FOR SDB
HRLI T1,.RESP3 ;FROM THE RESIDENT FREE POOL
MOVEI T2,.RESGP ;GET SPACE FROM GENERAL POOL
CALL ASGRES ;...
RETBAD () ;COULD NOT GET SPACE
CRTST1: MOVE T4,CRTSSN ;GET STR NUMBER TO BE USED
MOVEM T1,STRTAB(T4) ;STORE THE POINTER TO THE SDB
MOVE T3,T1 ;GET ADR OF SDB INTO T3
MOVE T1,CRTSHB ;SET UP ACS AGAIN
MOVE T4,CRTUDB ;GET UDB ADDRESS
MOVE T2,HOMSNM(T1) ;GET STR NAME
MOVEM T2,SDBNAM(T3) ;SAVE NAME IN SDB
MOVEM T2,UDBVID(T4) ;STORE STR NAME AS VOLUMN ID IN UDB
HLRZ T2,HOMLUN(T1) ;GET NPACKS
MOVEM T2,SDBNUM(T3) ;STORE NUMBER OF UNITS IN SDB
MOVE T2,HOMRXB(T1) ;ROOT INDEX ADR
MOVEM T2,SDBRXB(T3)
MOVE T2,HOMBXB(T1) ;BACKUP OF ROOT DIR
MOVEM T2,SDBBXB(T3)
MOVEI T2,NRESDN ;SET UP STARTING DIR # FOR GETNDN
STOR T2,STRLDN,(T3) ;GETNDN STARTS SCANNING AT DIR # 20
MOVE T2,HOMMID(T1) ;GET MEDIA ID
STOR T2,STRMI,(T3) ;STORE MEDIA ID (PACK UNIQUE CODE)
CALL GETTYP ;GET DISK SIZE POINTER
JRST [ MOVEI T2,MSTX27 ;INDICATE 'NOT A DISK'
MOVEM T2,CRTSER
JRST CRTST5]
MOVEM T4,SDBTYP(T3) ;SAVE IT IN THE SDB
MOVE T2,MINFPG(T4) ;GET INITIAL VALUE OF MINIMUM FREE COUNT
MOVEM T2,SDBOMF(T3) ;REMEMBER THIS IN THE SDB
MOVEM T2,SDBMFP(T3) ;START WITH THIS AS THE MINIMUM VALUE
MOVE T2,MAXFPU(T4) ;GET TURNING POINT OF ALLOCATION ALGORITHM
IMUL T2,SDBNUM(T3) ;GET TURNING POINT FOR STRUCTURE
MOVEM T2,SDBMXF(T3) ;SAVE IT IN SDB
MOVE T2,CYLUNT(T4) ;SET THE STARTING TRACK NUMBER
LSH T2,-1 ; FOR THE FREE CHOICE TO THE MIDDLE
MOVEM T2,SDBLCA(T3) ; OF THE FIRST PACK OF THE STRUCTURE
MOVE T2,SDBNUM(T3) ;GET NUMBER OF UNITS IN STRUCTURE
IMUL T2,CYLUNT(T4) ;COMPUTE TOTAL CYLINDERS IN STRUCTURE
MOVEM T2,SDBCYL(T3) ;SAVE IN SDB
IMUL T2,PAGCYL(T4) ;COMPUTE TOTAL PAGES IN STRUCTURE
CAMLE T2,[MXPGUN] ;LEGAL # OF PAGES?
JRST [ MOVEI T2,MSTX35 ;NO. STRUCTURE TOO BIG
MOVEM T2,CRTSER ;SAVE ERROR
JRST CRTST5] ;AND GIVE UP
MOVE T2,HOMP4S(T1) ;NUMBER PAGES FOR SWAPPING PER UNIT
IMUL T2,SECPAG(T4) ;CONVERT TO SECTORS
MOVEM T2,SDBNSS(T3) ;SAVE IN SDB
MOVE T2,HOMFST(T1) ;FIRST SWAPPING TRACK
IMUL T2,SECCYL(T4) ;CONVERT TO SECTOR NUMBER
MOVEM T2,SDBFSS(T3) ;SAVE IN SDB
MOVE T2,CRTUDB ;GET ADDRESS OF UDB
MOVE T2,CYLUNT(T4) ;GET NUMBER OF CYLINDERS PER UNIT
IMUL T2,SECCYL(T4) ;CONVERT TO SECTORS
MOVEM T2,SDBSIZ(T3) ;SAVE IN SDB
SKIPN T2,HOMBTB(T1) ;SEE IF SIZE OF TOP OF BIT TABLE IS DEFINED
JRST [ MOVEI T2,BTBTOP ;NO. MUST HAVE BEEN BUILT BY OLD MONITOR
MOVEM T2,SDBBT0(T3) ;SAVE OLD SIZE OF TOP HALF OF BIT TABLE
MOVEI T2,BTBBOT ; AND OLD SIZE OF BOTTOM HALF
MOVEM T2,SDBBT1(T3) ; IN THE SDB
JRST CRTST3]
MOVEM T2,SDBBT0(T3) ;BUILT BY RELEASE 2 OR LATER. SAVE SIZE
; OF TOP HALF OF BIT TABLE
IMUL T2,BTWCYL(T4) ;COMPUTE NUMBER OF BIT WORDS IN BOTTOM
MOVEM T2,SDBBT1(T3) ;SAVE IT IN THE SDB
CRTST3: ADD T2,SDBBT0(T3) ;COMPUTE TOTAL SPACE IN FILE
CAMLE T2,BTBSIZ ;WILL IT FIT IN ADDRESS SPACE?
JRST [ HRRZ T2,HOMLUN(T1) ;GET UNIT WITHIN STRUCTURE
ADDI T2,SDBUDB(T3) ;POINT TO ITS UDB
MOVX T4,MI%MXB ;NO. INDICATE THIS FOR LATER
IORM T4,0(T2)
MOVEI T2,MSTRX6 ;INDICATE 'BAD HOME BLOCKS'
MOVEM T2,CRTSER
JRST .+1]
CRTST5: MOVE T2,HOMFLG(T1) ;GET FLAGS
IORM T2,SDBSTS(T3) ;SAVE FLAGS
MOVE T4,CRTUDB ;SET T4=ADDRESS OF UDB
CALL FIXVID ;FIX UP UDBVID IF A MULTI-PACK STRUCTURE
MOVE T1,T3 ;RETURN WITH ADR OF SDB IN T1
SKIPN CRTSER
RETSKP
MOVE T1,CRTSSN ;GET STR NUMBER
CALL CLRSTB ;CLEAR THE STRTAB ENTRY
MOVE T1,CRTSER ;GET THE ERROR CODE
RETBAD () ;GIVE FAILURE RETURN
;ROUTINE TO FIX UP UDBVID FOR A UNIT IN A MULTI-PACK STRUCTURE
;ACCEPTS
; T1/ADDRESS OF HOME BLOCK
; T3/ADDRESS OF SDB
; T4/ADDRESS OF UDB
;
; CALL FIXVID
;RETURNS +1 WITH UDBVID FIXED TO BE XXXN, WHERE XXX=STR NAME, N=UNIT IN STR
FIXVID: HLRZ T2,HOMLUN(T1) ;GET NO OF PACKS IN STRUCTURE
SOJLE T2,R ;NOTHING TO DO IF A SINGLE-PACK STRUCTURE
HRRZ T2,HOMLUN(T1) ;MULTI-PACK - GET UNIT WITHIN STRUCTURE
MOVE T1,SDBNAM(T3) ;GET NAME OF STRUCTURE
TRNE T1,77 ;6-CHARACTER NAME?
RET ;YES, NOTHING WE CAN DO ABOUT IT
ADDI T2,'0' ;NO, GET SIXBIT UNIT NUMBER
MOVEI T1,7700 ;SET FOR TEST ON NAME
FIXVI1: TDNE T1,SDBNAM(T3) ;THIS CHARACTER IN NAME?
JRST FIXVI2 ;YES, HERE IS WHERE TO APPEND UNIT NO
LSHC T1,6 ;NO, SHIFT MASK, ENDING CHARACTER
JRST FIXVI1 ;AND TEST NEXT CHARACTER OF NAME
FIXVI2: IOR T2,SDBNAM(T3) ;MANUFACTURE XXXX+N
MOVEM T2,UDBVID(T4) ;SAVE NAME IN UDB
RET ;AND WE ARE DONE
;ROUTINE TO CLEAR AN ENTRY IN STRTAB
;ACCEPTS IN T1/ STR NUMBER
; CALL CLRSTB
;RETURNS +1: ALWAYS
CLRSTB::SKIPN T2,STRTAB(T1) ;IS THERE ANYTHING THERE?
RET ;NO
SETZM STRTAB(T1) ;YES, CLEAR IT
JUMPE T1,R ;DONT TRY TO RELEASE STR 0'S SDB
MOVE T1,T2 ;AND RELEASE THE SDB BLOCK
CALLRET RELRES ;BACK TO THE RESIDENT POOL
;GETTYP - GET TYPE OF DISK
;ACCEPTS:
; T1/ ADDRESS OF HOME BLOCK
; T3/ ADDRESS OF SDB
; T4/ ADDRESS OF UDB FOR THIS UNIT
; CALL GETTYP
;RETURNS +1: UNKNOWN DISK TYPE
; +2: VALID DISK TYPE,
; T2/ OFFSET INTO DSKUTP FOR THIS DISK TYPE
; T4/ ADDRESS OF DISK SIZE TABLE
;PRESERVES T1 AND T3
GETTYP: LOAD T4,USTYP,(T4) ;GET TYPE OF UNIT
MOVSI T2,-NDSKUT ;T2/(-COUNT OF TABLE,,CURRENT OFFSET)
CAME T4,DSKUTP(T2) ;IS THIS A DISK?
AOBJN T2,.-1 ;NO. KEEP LOOKING
SKIPL T2 ;OUT OF LOOP. DID WE FIND ONE?
JRST [ HRRZ T2,HOMLUN(T1)
ADDI T2,SDBUDB(T3)
MOVX T4,MS%TYP
IORM T4,0(T2)
RETBAD]
MOVE T4,DSKSIZ(T2) ;YES. GET ADDRESS OF SIZE DATA FOR THIS TYPE
RETSKP
;BLDNEW - ROUTINE CALLED FROM THE MSTR JSYS TO CREATE A NEW SBD
;BLDSDB - ROUTINE CALLED FROM THE MSTR JSYS TO ADD A UNIT TO A STRUCTURE
;
;ACCEPTS IN T1/ CKU NUMBER OF UNIT
; T2/ ADDRESS OF HOME BLOCK PAGE
; T3/ FOR BLDNEW: STRUCTURE NUMBER
; FOR BLDSDB: SDB ADDRESS
;
;RETURNS: +1 FAILURE, ERROR CODE IN T1
; +2 SUCCESS, T1/ ADDRESS OF SDB
BLDNEW::SKIPA T4,[IFIW CRTSTR] ;GET ONE ROUTINE TO CALL
BLDSDB::MOVE T4,[IFIW ADDSTR] ;OR OTHER ROUTINE TO CALL
ASUBR <BLSCKU,BLSADR,BLSSDB,BLSROU>
CALL CKUNPK ;UNPACK THE CKU NUMBERS
CALL CHKCKU ;VERIFY THEY ARE GOOD AND RETURN THE UDB
RETBAD () ;FAILED
MOVE T2,T1 ;PUT UDB IN RIGHT AC
MOVE T1,BLSADR ;GET ADDRESS OF PAGE CONTAINING HOME BLOCKS
MOVE T3,BLSSDB ;GET SDB ADDRESS OR STRUCTURE NUMBER
CALL @BLSROU ;CREATE AN SDB OR ADD THIS UNIT TO IT
RETBAD () ;FAILED, RETURN ERROR
RETSKP ;RETURN SUCCESS
; ROUTINE TO CHECK THE BAT BLOCKS ON A SINGLE UNIT, CALLED FROM MSTR JSYS
;
; ACCEPTS IN T1/ CHANNEL NUMBER
; T2/ CONTROLLER NUMBER
; T3/ UNIT NUMBER
; T4/ VIRTUAL ADDRESS,,PHYSICAL PAGE NUMBER OF BAT BLOCK PAGE
; CALL UNIBAT
; RETURNS: +1 FAILED, BAT BLOCKS BAD
; +2 SUCCESS, BAT BLOCKS OK
SWAPCD
UNIBAT::STKVAR <UNIBVA> ;ALLOCATE STORAGE
MOVEM T4,UNIBVA ;REMEMBER ADDRESS AND PAGE
CALL CHKCKU ;CONVERT THE CKU NUMBERS INTO UDB ADDRESS
RETBAD () ;CAN'T DO IT
MOVE T4,T1 ;MOVE UDB TO RIGHT AC
HLRZ T1,UNIBVA ;GET VIRTUAL ADDRESS OF BAT BLOCK PAGE
HRRZ T2,UNIBVA ;GET PHYSICAL PAGE NUMBER OF BAT BLOCK PAGE
LSH T2,PGSFT ;CONVERT TO PHYSICAL ADDRESS OF BAT BLOCK PAGE
MOVX T3,MS%NFB ;DO NOT REPAIR THE BAT BLOCKS IF BAD
CALLRET DOPACK ;GO CHECK THE BAT BLOCKS ON THIS UNIT
; ROUTINE TO CREATE A PAIR OF NEW HOME BLOCKS ON A UNIT
;
; ACCEPTS IN T1/ FLAGS,,ADDRESS OF ID INFO
; T2/ STRUCTURE NAME
; T3/ CKU VALUE (CHANNEL, CONTROLLER, AND UNIT NUMBERS)
; T4/ NUMBER OF UNITS IN STRUCTURE,,UNIT NUMBER WITHIN STRUCTURE
; P1/ # OF PAGES FOR SWAPPING ON THIS STRUCTURE
; P2/ MEDIA IDENTIFICATION (PACK UNIQUE CODE)
; P3/ SERIAL NUMBER OF CPU BOOTED FROM THIS STRUCTURE
; CALL CRTHOM
; RETURNS: +1 FAILED, COULD NOT WRITE HOME BLOCKS
; +2 SUCCESS, HOME BLOCKS WRITTEN
IDLEN==6 ;NUMBER OF WORDS OF UNIT AND OWNER ID INFO
CRTHOM::SAVEP
ASUBR <CRHINF,CRHSTR,CRHCKU,CRHNUM>
STKVAR <CRHVIR,CRHP4S,CRHMID,CRHUDB,CRHSER>
MOVEM P1,CRHP4S ;SAVE # OF PAGES FOR SWAPPING
MOVEM P2,CRHMID ;SAVE MEDIA ID
MOVEM P3,CRHSER ;SAVE SERIAL NUMBER
; VALIDATE AMOUNT OF SWAPPING SPACE REQUESTED
MOVE T1,CRHCKU ;GET CKU VALUE
CALL CKUNPK ;EXPAND INTO THE SEPARATE NUMBERS
CALL CHKCKU ;RETURN THE UDB IN T1
RETBAD () ;CAN'T FIND IT
MOVEM T1,CRHUDB ;REMEMBER THE UDB
HLRZ T2,CRHNUM ;GET NUMBER OF UNITS IN STRUCTURE
MOVE T3,CRHP4S ;GET # OF PAGES FOR SWAPPING ON THIS STR
CALL CHKSWP ;GO CHECK THE SWAPPING SPACE REQUESTED
RETBAD () ;FAILED, INVALID AMOUNT REQUESTED
; GET UNIT SIZE AND ADDRESS OF SIZE TABLE
MOVE P1,CRHUDB ;GET BACK UDB ADDRESS
MOVE P1,UDBSIZ(P1) ;THEN GET POINTER TO SIZE TABLE
HRLZ P3,CYLUNT(P1) ;GET NUMBER OF CYLINDERS PER UNIT
HLR P3,CRHNUM ;GET NUMBER OF UNITS IN STRUCTURE
; GET A PAGE FOR IN WHICH TO CREATE A HOME BLOCK
NOINT ;DO NOT PERMIT INTERRUPTS
CALL ASGPAG ;ASSIGN A PAGE
RETBAD (,<OKINT>) ;FAILED, RETURN
MOVEM T1,CRHVIR ;SAVE ADDRESS OF PAGE
HRR T4,CRHVIR ;GET ADDRESS OF HOME BLOCK PAGE
HRL T4,CRHP4S ;GET # OF PAGES FOR SWAPPING ON THIS STR
MOVE T3,P3 ;GET UNIT SIZE AND # OF UNITS
MOVE T2,CRHSTR ;GET STRUCTURE NAME
HLLZ T1,CRHINF ;GET FLAGS
MOVE P2,CRHSER ;GET CPU SERIAL NUMBER
CALL SETHOM ;GO SET UP PRIMARY HOME BLOCK
; ADD REMAINING INFO TO THE HOME BLOCK
HRRZ T2,CRHVIR ;GET ADDRESS OF HOME BLOCK
MOVE T1,CRHMID ;GET MEDIA IDENTIFICATION (PACK UNIQUE CODE)
MOVEM T1,HOMMID(T2) ;SAVE MEDIA ID
HRRZ T1,CRHNUM ;GET UNIT NUMBER WITHIN STRUCTURE
HRRM T1,HOMLUN(T2) ;STORE UNIT # WITHIN STRUCTURE
HRLZ T1,CRHINF ;GET ADDRESS OF ID INFO BLOCK
HRRI T1,HOMUID(T2) ;GET DESTINATION ADDRESS
BLT T1,HOMUID+IDLEN-1(T2) ;COPY ID INFO INTO HOME BLOCK
;..
;..
; LOCK THE HOME BLOCK PAGE AND WRITE THE HOME BLOCKS
SETZM P2 ;INITIALIZE FAILURE FLAG
HRRZ T1,CRHVIR ;GET ADDRESS OF HOME BLOCK PAGE
CALL MLKMA ;LOCK THE PAGE
MOVEM T1,P1 ;SAVE PHYSICAL PAGE NUMBER
HRRZ T1,CRHVIR ;GET FLAGS,,VIRTUAL ADDRESS OF HOME BLOCK PAGE
HRRZ T2,P1 ;GET PHYSICAL PAGE NUMBER
LSH T2,PGSFT ;FORM PHYSICAL ADDRESS OF HOME BLOCK PAGE
MOVE T3,CRHCKU ;GET CKU NUMBERS
CALL CPYH1 ;WRITE OUT SECONDARY HOME BLOCK
SETOM P2 ;FAILED, FLAG ERROR
HRRZ T1,CRHVIR ;GET FLAGS,,VIRTUAL ADDRESS OF HOME BLOCK PAGE
HRRZ T2,P1 ;GET PHYSICAL PAGE NUMBER
LSH T2,PGSFT ;FORM PHYSICAL ADDRESS OF HOME BLOCK PAGE
MOVE T3,CRHCKU ;GET CKU NUMBERS
CALL CPYH2 ;WRITE OUT PRIMARY HOME BLOCK
SETOM P2 ;FAILED, FLAG ERROR
; UNLOCK AND RETURN THE HOME BLOCK PAGE, AND RETURN
HRRZ T1,P1 ;GET PHYSICAL PAGE NUMBER
CALL MULKCR ;UNLOCK THE PAGE
HRRZ T1,CRHVIR ;GET VIRTUAL ADDRESS OF PAGE
CALL RELPAG ;RELEASE THE PAGE
OKINT ;PERMIT INTERRUPTS
JUMPN P2,R ;IF I/O ERROR, RETURN FAILURE
RETSKP ;ELSE RETURN SUCCESS
RESCD(INIT)
;ROUTINE TO READ IN THE PRIMARY AND BACKUP HOME BLOCKS
;OR THE PRIMARY AND BACKUP BAT BLOCKS
;ACCEPTS IN T1/ CKU NUMBERS OF DRIVE TO BE READ
; T2/ ADDRESS OF PAGE TO READ INTO
; T3/ LOCAL BLOCK ADDRESS OF PRIMARY BLOCK
; T4/ VIRTUAL CORE ADDRESS
; CALL REDHOM
;RETURNS +1: DRIVE OFF-LINE
; +2: BOTH BLOCKS READ IN (BUT NOT NECESSARILY WITHOUT ERRORS)
;
;NOTICE: SINCE AN RP20 HAS SECTORS OF 1000 WORDS, AND WE HAVE READ ONLY
;200 WORDS, A CERTAIN KIND OF OVERRUN IS EXPECTED TO OCCUR BY PHYH2, AND
;THEREFORE IS IGNORED. IF THE HOME BLOCKS READ BAD OCCASIONALLY, THEN
;THE PROBLEM MIGHT BE THAT THESE IGNORED OVERRUNS ARE "REAL".
REDHOM::STKVAR <REDCKU,REDHOB,REDBLK,REDVIR>
MOVEM T1,REDCKU ;SAVE CHANNEL, CONTROLLER, AND UNIT NUMBER
MOVEM T2,REDHOB ;SAVE ADDRESS OF PAGE TO HOLD HOME BLKS
MOVEM T4,REDVIR ; SAVE VIRTUAL ADDRESS
SETZM (T4) ; ZERO WHOLE AREA
HRLI T4,(T4) ; IN BOTH HALFS
AOS T4
HRRZ T2,T4 ;GET BASE ADDRESS AGAIN
BLT T4,<HBLEN*2-1>(T2) ; ZAP ENTIRE AREA
MOVEM T3,REDBLK ; SAVE LOCAL BLOCK NUMBER
MOVE T1,REDBLK ;GET UNIT RELATIVE ADR TO BE READ
MOVEI T2,HBLEN ;READ IN ONLY THE HOME BLOCK
MOVE T3,REDHOB ;GET ADDRESS TO READ INTO
MOVE T4,REDCKU ;GET CKU NUMBER
TXO T2,1B0!DOP%EO ;GET AN ERROR ON OFFLINE
CALL UDSKIO ;READ IN THE HOME BLOCK
MOVE T4,REDVIR ;RESTORE VIRTUAL ADDRESS
SKIPE T1 ;WAS THERE AN ERROR?
SETZM HOMNAM(T4) ;YES. CLEAR NAME
MOVE T1,REDBLK ;GET BACK DISK ADDRESS
ADDI T1,HM2BLK-HM1BLK ;POINT TO BACKUP HOME BLOCKS
MOVEI T2,HBLEN ;SET UP LENGTH
MOVE T3,REDHOB ;GET ADDRESS TO READ INTO
ADDI T3,HBLEN ;PUT IT JUST AFTER FIRST HOME BLOCK
MOVE T4,REDCKU ;GET CKU NUMBER AGAIN
TXO T2,1B0!DOP%EO ;GET AN ERROR ON OFFLINE
CALL UDSKIO ;READ IN HOME BLOCK
MOVE T4,REDVIR ;GET VIRTUAL ADDRESS
SKIPE T1 ;DISK ERROR?
SETZM <HOMNAM+HBLEN>(T4) ;YES. ZAP THIS NAME
TLC T1,-1 ;CHECK FOR DRIVE OFFLINE KIND OF ERROR
TLCN T1,-1 ;DRIVE OFF-LINE?
RET ;YES
RETSKP ;READ IN BOTH OK
;ROUTINE TO CHECK THE CONSISTENCY OF THE HOME BLOCKS
;ACCEPTS IN T1/ ADDRESS OF HOME BLOCK
; T2/ HOME BLOCK #
; CALL HBCCHK
;RETURNS +1: NOT CONSISTENT OR MULTIPLE LOGICAL UNITS
; +2: CONSISTENT, LOGICAL UNIT # IN T1
HBCCHK::MOVS T3,HOMNAM(T1) ;GET SIXBIT /HOM/
CAIE T3,'HOM' ;IS THIS CORRECT?
RET ;NO, GIVE ERROR RETURN
MOVE T3,HOMCOD(T1) ;GET HOME BLOCK CODE
CAIE T3,CODHOM ;MUST BE "707070"
RET ;INCONSISTENT
MOVE T3,HOMSLF(T1) ;GET BLOCK NUMBER OF HOME BLOCK
CAME T2,T3 ;IS IT WHAT IS EXPECTED?
RETBAD ;NO, NOT A CONSISTENT HOME BLOCK
MOVE T2,HOMFSN(T1) ;GET FILE SYSTEM TYPE
CAME T2,[BYTE (2)0(8)" "," "(2)0(8)"O","T"]
RETBAD ;NOT A TOPS-20 PACK
MOVE T2,HOMFSN+1(T1) ;GET CHARACTERS 5-8 OF TYPE
MOVE T3,HOMFSN+2(T1) ;GET CHARACTERS 9-12 OF TYPE
CAMN T2,[BYTE (2)0(8)"S","P"(2)0(8)"2","-"]
CAME T3,[BYTE (2)0(8)" ","0"(2)0(8)" "," "]
RETBAD ;NOT A TOPS-20 PACK
RETSKP ;HOME BLOCK IS OK
;ROUTINES TO CORRECT ONE INCORRECT HOME BLOCK
;AND WRITE THE CORRECTED BLOCK ON THE DISK
;CALLED FROM MSTR JSYS
;
;ACCEPTS: T1/ FLAGS,,VIRTUAL ADDRESS OF PAGE CONTAINING HOME BLOCKS
; T2/ PHYSICAL ADDRESS OF PAGE CONTAINING HOME BLOCKS
; T3/ CKU NUMBERS FOR THIS PACK
; IF A MESSAGE IS REQUESTED, ALSO:
; P4/ SDBUDB POINTER FOR THIS UNIT
; P5/ STRUCTURE NUMBER
; CALL CPYH1/CPYH2
;RETURNS: +1 ERROR WRITING THE HOME BLOCK
; +2 SUCCESS, GOOD HOME BLOCK COPIED OVER BAD ONE
CPYH1:: TDZA T4,T4 ;INDICATE COPYING PRIMARY TO SECONDARY
CPYH2:: SETOM T4 ;INDICATE COPYING SECONDARY TO PRIMARY
ASUBR <CPHVIR,CPHPHY,CPHCKU> ;STORE INPUT ARGUMENTS
STKVAR <CPHDIR,CPHLOC> ;ALLOCATE SPACE FOR DIRECTION OF TRANSFER FLAG
MOVEM T4,CPHDIR ;SAVE DIRECTION OF TRANSFER
TXNN T1,MI%MSG ;MESSAGE DESIRED ?
JRST CPYH10 ;NO, GO COPY THE GOOD HOME BLOCK
HRRZ T3,CPHVIR ;POINT TO START OF HOME BLOCK 1
HRROI T1,[ASCIZ/% Copying primary HOME block to secondary on /]
SKIPE CPHDIR ;REALLY COPYING SECONDARY TO PRIMARY ?
JRST [ HRROI T1,[ASCIZ/% Copying secondary HOME block to primary on /]
ADDI T3,HBLEN ;POINT TO START OF HOME BLOCK 2
JRST .+1]
MOVEM T3,CPHLOC ;SAVE ADDRESS OF GOOD HOME BLOCK
CALL FSIPSO ;OUTPUT INITIAL PART OF MESSAGE
MOVE T3,CPHLOC ;POINT TO CORRECT HOME BLOCK
MOVE T1,HOMSNM(T3) ;GET NAME OF STRUCTURE
CALL FSI6TY ;PRINT NAME OF STRUCTURE
HRROI T1,[ASCIZ/ UNIT /]
CALL FSIPSO ;PRINT 'UNIT'
MOVE T3,CPHLOC
HRRZ T1,HOMLUN(T3) ;GET UNIT NUMBER
CALL FSIOTY ;PRINT THE UNIT NUMBER
HRROI T1,[ASCIZ/
/] ;GET END OF LINE
CALL FSIPSO ;OUTPUT END OF MESSAGE
;...
; HERE TO DO THE ACTUAL COPY
CPYH10: HRRZ T1,CPHVIR ;GET VIRTUAL ADDRESS OF FIRST HOME BLOCK
MOVE T3,[HM2BLK,,HM1BLK] ;GET BLOCK NUMBERS OF OTHER,,THIS HOME BLOCK
MOVEI T4,(T1) ;GET VIRTUAL ADDRESS OF FIRST HOME BLOCK
HRLI T1,HBLEN(T1) ;GET SOURCE ADDRESS FOR COPY
SKIPE CPHDIR ;COPYING SECONDARY TO PRIMARY ?
JRST CPYH20 ;YES, GO SET UP TERMINATING ADDRESS
HRLI T1,(T4) ;NO, GET SOURCE ADDRESS
HRRI T1,HBLEN(T4) ;GET DESTINATION ADDRESS
MOVS T3,T3 ;SWAP THIS,,OTHER HOME BLOCK NUMBERS
ADDI T4,HBLEN ;POINT TO SECOND HOME BLOCK
CPYH20: MOVEI T2,(T1) ;GET BASE FOR TERMINATING ADDRESS
BLT T1,HBLEN-1(T2) ;COPY GOOD HOME BLOCK
MOVSM T3,HOMHOM(T4) ;SAVE THIS,,OTHER BLOCK NUMBERS
HRRZM T3,HOMSLF(T4) ;SAVE THIS BLOCK NUMBER
; NOW WRITE OUT THE CORRECTED HOME BLOCK
HRRZ T1,CPHVIR ;GET VIRTUAL ADDRESS OF HOME BLOCKS
SKIPN CPHDIR ;WRITING OUT FIRST HOME BLOCK?
CALL SWPHOM ;NO, SWAP THEM SO PAGE STARTS WITH SECOND ONE
HRRZ T1,T3 ;GET SECTOR NUMBER
MOVE T2,[1B0+DOP%WR+HBLEN] ;CHANNEL+UNIT, WRITE, ONE HOME BLOCK
MOVE T3,CPHPHY ;GET PHYSICAL ADDRESS OF FIRST HOME BLOCK
MOVE T4,CPHCKU ;GET CKU VALUE FOR UNIT
CALL UDSKIO ;WRITE THE CORRECTED HOME BLOCK
MOVE T4,T1 ;SAVE RESULT
HRRZ T1,CPHVIR ;GET BACK VIRTUAL ADDRESS OF HOME BLOCKS
SKIPN CPHDIR ;DID WE SWAP THEM?
CALL SWPHOM ;YES, SWAP THEM BACK
JUMPN T4,R ;IF ERROR, RETURN FAILURE
RETSKP ;RETURN SUCCESS
;ROUTINE TO WRITE ALL HOME BLOCKS IN PUBLIC STRUCTURE
;ASSUMES THAT HOMTAB IS SET UP FOR THE PUBLIC STR
; CALL WRTHOM
;RETURNS +1: ERROR ON WRITE
; +2: HOME BLOCKS WRITTEN OK
;HOMTAB IS INDEXED BY LOGICAL UNIT WITHIN STRUCTURE, CONTAINS
;THE CHANNEL, CONTROLLER, AND UNIT NUMBERS OF THE UNIT (CKU VALUE)
;FSINPK/NUMBER OF UNITS IN STRUCTURE
WRTHOM: SAVEP
MOVE T1,FSIFLG ;GET FLAGS
MOVE T2,FSINAM ;GET STRUCTURE NAME
HRR T3,FSINPK ;GET NUMBER OF UNITS IN STRUCTURE
HRL T3,FSIUSZ ;GET UNIT SIZE
MOVEI T4,HOMPGA ;GET ADDRESS OF HOME BLOCK PAGE
HRL T4,FSISWP ;GET # OF PAGES FOR SWAPPING
MOVE P1,FSITYP ;GET ADDRESS OF DISK SIZE DATA
MOVE P2,FSISER ;GET CPU SERIAL NUMBER
CALL SETHOM ;GO SETUP HOME BLOCK PAGE
CALL GETMID ;GET THE MEDIA ID FOR THIS STR
MOVEM T1,HOMPGA+HOMMID ;SAVE THE MEDIA ID
MOVN P1,FSINPK ;SET UP LOOP COUNTER
HRLZS P1
SETZ P3, ;INITIALIZE ERROR COUNTER TO 0
WRTHO1: HRRM P1,HOMPGA+HOMLUN ;SET UP LOGICAL UNIT NUMBER
MOVEI T1,HM1BLK ;WRITE FIRST HOME BLOCK
MOVE T2,HOMTAB(P1) ;GET CKU NUMBER
CALL WRTHB
AOS P3 ;COUNT UP ERRORS
MOVSS HOMPGA+HOMHOM ;SWITCH POINTER TO HOME BLOCKS
MOVEI T1,HM2BLK ;THEN WRITE SECOND HOME BLOCK
MOVE T2,HOMTAB(P1) ;GET CKU NUMBER
CALL WRTHB
AOS P3 ;COUNT UP ERRORS
MOVSS HOMPGA+HOMHOM ;SWITCH POINTER BACK FOR FIRST HOME BLK
AOBJN P1,WRTHO1 ;LOOP BACK FOR ALL PACKS IN PUBLIC STR
JUMPG P3,R ;IF ERRORS, GIVE NON-SKIP RETURN
RETSKP ;OTHERWISE GIVE SKIP RETURN
;ROUTINE TO WRITE A HOME BLOCK
;ASSUMES THAT HOMPG IS SET UP WITH A HOME BLOCK IMAGE
;ACCEPTS IN T1/ BLOCK # OF THIS HOME BLOCK
; T2/ CKU NUMBER
; P1/ LOGICAL PACK #
; CALL WRTHB
;RETURNS +1: ERROR ON WRITE
; +2: OK
WRTHB: MOVEM T1,HOMPGA+HOMSLF ;SAVE POINTER TO SELF
MOVE T4,T2 ;SET UP FOR CALL TO UDSKIO
MOVEI T2,HBLEN ;ONLY WRITE THE HOME BLOCK
TLO T2,(1B0+1B14) ;MARK THAT A WRITE IS TO BE DONE
MOVE T3,FSIPPA ;GET PHYSICAL ADDRESS
CALL UDSKIO ;WRITE OUT THE HOME BLOCK
JUMPE T1,RSKP ;NO ERRORS IF T1=0
HRROI T1,[ASCIZ/
? Error writing Home Block on logical unit /]
CALL FSIPSO
MOVEI T1,0(P1) ;GET UNIT NUMBER
CALL FSIOTY ;TYPE IT OUT
HRROI T1,[ASCIZ/
/]
CALL FSIPSO ;END WITH A CR-LF
RET ;AND EXIT
;ROUTINE TO SWAP THE HOME OR BAT BLOCKS IN A PAGE. NECESSARY BECAUSE
;THE DISK WRITE HAS TO BEGIN AT THE FIRST WORD OF A PAGE FOR RP20'S.
;CALL:
; T1/ VIRTUAL ADDRESS OF THE PAGE HOLDING THE HOME OR BAT BLOCKS
;RETURNS:
; +1: ALWAYS, WITH THE TWO HOME OR BAT BLOCKS SWAPPED.
;THIS ROUTINE TRASHES THE REMAINDER OF THE PAGE AFTER THE TWO BLOCKS.
SWPHOM: MOVSI T2,0(T1) ;COPY FROM FIRST BLOCK
IORI T2,HBLEN*2(T1) ;TO SECOND HALF OF PAGE
BLT T2,HBLEN*3-1(T1) ;SAVE FIRST HOME BLOCK AWAY
MOVSI T2,HBLEN(T1) ;NOW POINT AT SECOND HOME BLOCK
IORI T2,0(T1) ;AND TOP OF PAGE
BLT T2,HBLEN-1(T1) ;COPY SECOND HOME BLOCK UP ONTO FIRST ONE
MOVSI T2,HBLEN*2(T1) ;NOW WANT TO COPY BACK FIRST HOME BLOCK
IORI T2,HBLEN(T1) ;ON TOP OF OLD SECOND HOME BLOCK
BLT T2,HBLEN*2-1(T1) ;DO IT
RET ;DONE
; ROUTINE TO SETUP FIRST HOME BLOCK ON A UNIT
; (EXCEPT FOR LOGICAL UNIT # IN HOMLUN)
;
; ACCEPTS IN T1/ FLAGS
; T2/ STRUCTURE NAME
; T3/ UNIT SIZE,,NUMBER OF UNITS IN STRUCTURE
; T4/ # OF PAGES FOR SWAPPING,,ADDRESS OF HOME BLOCK PAGE
; P1/ ADDRESS OF DISK SIZE TABLE
; P2/ SERIAL NUMBER OF CPU THIS STRUCTURE BOOTS
; CALL SETHOM
; RETURNS: +1 ALWAYS, FIRST HOME BLOCK SET UP
SETHOM::ASUBR <STHFLG,STHSTR,STHUNI,STHADR>
HRLZ T1,T4 ;GET START ADDRESS OF HOME BLOCK PAGE
HRRI T1,1(T4) ;GET DESTINATION ADDRESS
HRRZS T4 ;GET ADDRESS ONLY
SETZM (T4) ;ZERO THE PAGE FIRST
BLT T1,HBLEN-1(T4) ;...
MOVSI T1,'HOM' ;SET UP THE HOME BLOCK
MOVEM T1,HOMNAM(T4) ;SIXBIT /HOM/
MOVE T1,SECUNT(P1) ;GET NUMBER OF SECTORS PER UNIT
MOVEM T1,HOMSIZ(T4) ;TO THE HOME BLOCK
MOVE T1,STHSTR ;GET STR NAME
MOVEM T1,HOMSNM(T4)
HRLZ T1,STHUNI ;GET TOTAL # OF PACKS IN STR
MOVEM T1,HOMLUN(T4) ;LOGICAL UNITS GET SET UP LATER
MOVE T1,[HM1BLK,,HM2BLK]
MOVEM T1,HOMHOM(T4) ;SET UP POINTERS TO HOME BLOCKS
MOVE T1,[BYTE (2)0(8)" "," "(2)0(8)"O","T"]
MOVEM T1,HOMFSN(T4) ;SET UP NAME OF SYSTEM PACKS
MOVE T1,[BYTE (2)0(8)"S","P"(2)0(8)"2","-"]
MOVEM T1,HOMFSN+1(T4)
MOVE T1,[BYTE (2)0(8)" ","0"(2)0(8)" "," "]
MOVEM T1,HOMFSN+2(T4)
MOVE T1,STHFLG ;SET UP FLAGS
MOVEM T1,HOMFLG(T4)
MOVE T1,DIDSCI ;SET UP POINTER TO INDEX BLOCK
MOVEM T1,HOMRXB(T4)
MOVE T1,DIDSCJ ;SET UP POINTER TO BACKUP ROOT-DIR
MOVEM T1,HOMBXB(T4)
HLRZ T1,STHADR ;GET # OF PAGES TO ALLOCATE FOR SWAPPING
MOVE T2,STHUNI ;GET # OF UNITS IN THIS STRUCTURE
MOVE T3,P1 ;GET POINTER TO DSKSIZ TABLE
CALL CMPSWP ;COMPUTE # OF PAGES FOR SWAPPING ON THIS UNIT
MOVEM T1,HOMP4S(T4) ;PUT # OF PAGES FOR SWAPPING IN HOME BLK
IDIV T1,PAGCYL(P1) ;GET NUMBER OF CYLINDERS OF SWAP SPACE
HLRZ T2,STHUNI ;GET UNIT SIZE IN CYLINDERS
SUB T2,T1 ;COMPUTE STARTING CYLINDER FOR SWAPPING
LSH T2,-1 ;SO THAT SWAP SPACE STRADDLES THE CENTER
MOVEM T2,HOMFST(T4) ;PUT ADR OF FIRST SWAPPING TRACK IN HB
MOVEI T1,CODHOM ;SET UP SPECIAL CODE
MOVEM T1,HOMCOD(T4)
MOVE T1,CYLUNT(P1) ;GET TOTAL CYLINDERS PER UNIT
HRRZ T2,STHUNI ;GET NUMBER OF UNITS IN STRUCTURE
IMUL T1,T2 ;COMPUTE TOTAL FOR STRUCTURE
MOVEM T1,HOMBTB(T4) ;SAVE AS SIZE OF TOP HALF OF BIT TABLE
MOVEM P2,HOMSER(T4) ;STORE CPU SERIAL NUMBER
RET ;RETURN
;MODHOM - MODIFY THE HOME BLOCKS
;ACCEPTS:
; T1/ STRUCTURE NUMBER
; T2/ OFFSET IN HOME BLOCKS OF WORD TO CHANGE
; T3/ DATA TO GO INTO THAT WORD
; T4/ MASK OF BITS TO CHANGE
; CALL MODHOM
;RETURNS +1: FAILED TO UPDATE THE HOME BLOCK
; +2: SUCCEEDED
;THIS ROUTINE READS BOTH HOME BLOCKS, CHANGES ONE WORD IN THEM, AND
;REWRITES THE MODIFIED HOME BLOCKS. IT DOES NOT CHECK THEM FOR
;CORRECTNESS
SWAPCD
MODHOM::
SAVEQ
STKVAR <MODHOF,MODHDA,MODHVA,MODHPA,MODHST,MODHCU,MODMSK>
MOVEM T1,MODHST ;SAVE STRUCTURE NUMBER
MOVEM T2,MODHOF ;SAVE THE OFFSET
MOVEM T3,MODHDA ;SAVE THE DATA
MOVEM T4,MODMSK ;SAVE MASK
NOINT ;NO INTERRUPTS WHILE PAGE IS ASSIGNED
CALL ASGPAG ;GET A PAGE IN JSB FREE SPACE
RETBAD (,<OKINT>) ;COULDN'T GET A PAGE
MOVEM T1,MODHVA ;SAVE STARTING ADDRESS OF PAGE (VIRTUAL)
CALL MLKMA ;LOCK DOWN A PHYSICAL PAGE TO CORRESPOND
; TO THIS ADDRESS
LSH T1,PGSFT ;CONVERT ITS PHYSICAL PAGE NO. TO AN ADDRESS
MOVEM T1,MODHPA ;SAVE STARTING ADDRESS OF PAGE (PHYSICAL)
MOVE T2,MODHST ;GET STRUCTURE NUMBER
MOVE T2,STRTAB(T2) ;POINT TO SDB FOR THIS STRUCTURE
LOAD Q1,STRNUM,(T2) ;GET NUMBER OF UNITS IN STRUCTURE
MOVNS Q1 ;MAKE IT NEGATIVE
HRLZS Q1 ;LEFT HALF OF AOBJN POINTER
HRRI Q1,SDBUDB(T2) ;Q1/(-COUNT,,SDBUDB ADDRESS)
SETZM Q2 ;INITIALIZE ERROR FLAG TO NO ERRORS
MODHO1: MOVE T3,0(Q1) ;GET ADDRESS OF UDB FOR THIS LOCICAL UNIT
CALL FNDCH1 ;CONVERT UDB ADDRESS INTO CKU NUMBER
MOVEM T1,MODHCU ;SAVE THE CKU VALUE
MOVE T2,MODHPA ;T2/PHYSICAL ADDRESS OF PAGE TO READ INTO
MOVEI T3,HM1BLK ;T2/SECTOR NUMBER OF FIRST HOME BLOCK
MOVE T4,MODHVA ;T4/VIRTUAL ADDRESS OF PAGE TO READ INTO
CALL REDHOM ;READ BOTH HOME BLOCKS INTO PAGE POINTED
; TO BY T4
JRST [ SETOM Q2 ;INDICATE ERROR
JRST MODHO5] ;GO CLEAN UP AND QUIT
MOVE T1,MODHOF ;GET THE OFFSET TO BE CHANGED
ADD T1,MODHVA ;POINT TO THE ACTUAL WORD
MOVE T2,0(T1) ;GET ORIGINAL DATA FROM HOMEBLOCK
TDZ T2,MODMSK ;CLEAR BITS BEING CHANGED
MOVE T3,MODHDA ;GET NEW DATA
AND T3,MODMSK ;KEEP ONLY BITS BEING CHANGED
IOR T2,T3 ;COLLECT NEW VERSION OF DATA WORD FOR HOMEBLOCK
MOVEM T2,0(T1) ;STORE INTO FIRST HOME BLOCK
MOVE T2,HBLEN(T1) ;GET ORIGINAL DATA FROM SECOND HOMEBLOCK
TDZ T2,MODMSK ;CLEAR BITS BEING CHANGED
IOR T2,T3 ;COLLECT NEW VERSION OF DATA WORD FOR HOMEBLOCK
MOVEM T2,HBLEN(T1) ;STORE INTO SECOND HOME BLOCK
MOVE T1,MODHPA ;T1/PHYSICAL ADDRESS OF WORK PAGE
MOVE T2,MODHCU ;T2/CKU NUMBERS FOR THIS LOGICAL UNIT
MOVE T3,MODHVA ;GET VIRTUAL ADDRESS
CALL UPDHOM ;UPDATE HOME BLOCKS ON THIS UNIT
JRST [ SETOM Q2 ;NOTE FAILURE
JRST MODHO5] ;GO CLEAN UP AND QUIT
MODHO3: AOBJN Q1,MODHO1 ;LOOP THROUGH ALL UNITS IN STRUCTURE
MODHO5: MOVE T1,MODHPA ;T1/PHYSICAL ADDRESS OF WORK PAGE
LSH T1,-PGSFT ;CONVERT TO PAGE NUMBER
CALL MULKCR ;UNLOCK IT FROM CORE
MOVE T1,MODHVA ;T1/VIRTUAL ADDRESS OF WORK PAGE
CALL RELPAG ;RELEASE THE WORK PAGE
OKINT ;INTERRUPTS ARE OK NOW
SKIPE Q2 ;WERE THERE ANY ERRORS?
RETBAD ;YES. TAKE ERROR RETURN
RETSKP ;NO. TAKE SUCCESS RETURN
;UPDHOM - UPDATE THE HOME BLOCKS
;
;ACCEPTS:
; T1/ PHYSICAL ADDRESS OF START OF PAGE WHERE HOME BLOCK DATA
; IS STORED
; T2/ CKU NUMBERS FOR THE PACK TO BE WRITTEN
; T3/ VIRTUAL ADDRESS OF THE PAGE WITH THE HOME BLOCKS
;
; CALL UPDHOM
;
;RETURNS +1: FAILED
; +2: SUCCEEDED
;
;THIS ROUTINE WRITES BOTH HOME BLOCKS FOR A SINGLE UNIT. THE CALLER
;MUST HAVE SET UP IN THE PAGE POINTED TO BY T1 THE DATA FOR BOTH HOME
;BLOCKS IN 2 CONTIGUOUS BLOCKS OF LENGTH HBLEN EACH. CALLING REDHOM
;WILL CAUSE THE PAGE TO BE SET UP THIS WAY
UPDHOM: SAVEQ
ASUBR <UPDHPA,UPDHCU,UPDVPA>
DMOVE T3,T1 ;MOVE ARGUMENTS TO T3 AND T4 FOR UDSKIO
MOVEI T1,HM1BLK ;T1/SECTOR NUMBER OF FIRST HOME BLOCK
MOVE T2,[1B0+1B14+HBLEN] ;T2/WRITE, ADDRESS IS CKU NUMBER, LENGTH
CALL UDSKIO ;WRITE THE FIRST HOME BLOCK TO THE DISK
MOVEM T1,Q1 ;SAVE ERROR INDICATOR FROM UDSKIO
MOVE T1,UPDVPA ;GET VIRTUAL ADDRESS OF HOME BLOCKS
CALL SWPHOM ;SWAP THE HOME BLOCKS
MOVEI T1,HM2BLK ;T1/SECTOR NUMBER OF SECOND HOME BLOCK
MOVE T2,[1B0+1B14+HBLEN] ;T2/WRITE, ADDRESS IS CKU NUMBER, LENGTH
MOVE T3,UPDHPA ;T3/PHYSICAL ADDRESS OF START OF PAGE
MOVE T4,UPDHCU ;T4/ CKU VALUE
CALL UDSKIO ;WRITE THE SECOND HOME BLOCK TO THE DISK
IORM T1,Q1 ;REMEMBER ERROR IF ANY
MOVE T1,UPDVPA ;GET BACK VIRTUAL ADDRESS
CALL SWPHOM ;SWAP BACK THE HOME BLOCKS
SKIPE Q1 ;ANY ERROR FROM EITHER WRITE?
RETBAD ;YES. TAKE ERROR RETURN
RETSKP ;NO ERRORS. TAKE SUCCESS RETURN
RESCD(INIT)
;ROUTINE TO READ ALL BAT BLOCKS ON A GIVEN STRUCTURE AND
;PERFORM A QUICK CONSISTENCY CHECK FOR THE GIVEN STRUCTURE.
;IF THE PUBLIC STRUCTURE IS GIVEN, IT MARKS OFF IN THE SWAPPING
;SPACE BIT TABLE DISK ADDRESSES IN THE SWAPPING SPACE THAT ARE BAD
; CALL CHKBAT
;
;ACCEPTS:
; T1/ STRUCTURE NUMBER
; T2/ VIRTUAL ADDRESS OF PAGE TO READ BAT BLOCKS INTO
; T3/ FLAGS
; CALL CHKBAT
;RETURNS: +1 ALWAYS WITH APPROPRIATE WARNINGS AND MESSAGES OUTPUT
; ON THE CTY AND LOGGED IN THE ERROR FILE
;USE OF P REGISTERS:
; P1/ PHYSICAL ADDRESS OF BAT BLOCK PAGE
; P4 /(-NUMBER PACKS,,SDBUDB FOR CURRENT PACK)
; P5 /STRUCTURE NUMBER
CHKBAT::SAVEP ;GET SOME WORK SPACE
STKVAR <CKBADR,CKBPAG,CKBFLG>
MOVEM T2,CKBADR ;SAVE VIRTUAL ADDRESS OF BAT BLOCK PAGE
MOVEM T3,CKBFLG ;SAVE FLAGS
MOVE P5,A
MOVE T1,CKBADR ;GET VIRTUAL ADDRESS OF BAT BLOCK PAGE
CALL MLKMA ;LOCK IT DOWN
MOVEM A,CKBPAG ;SAVE PHYSICAL PAGE NUMBER
MOVEI P1,(T1) ;GET PHYSICAL PAGE NUMBER
LSH P1,PGSFT ;SAVE CORE ADDRESS
BATSTR: SKIPN P4,STRTAB(P5) ;THIS STRUCTURE EXIST?
JRST NXTUN1 ;NO. GO TO NEXT
MOVN T1,SDBNUM(P4) ;GET -NUMBER OF PACKS
HRLI P4,0(T1) ;FORM AOBJN POINTER
HRRI P4,SDBUDB(P4) ;AND POINT TO FIRST UDB
;LOOP THROUGH PACKS
; P4/(NEGATIVE COUNT,,SDBUDB)
DOUNIT: MOVE T1,CKBADR ;GET VIRTUAL ADDRESS OF BAT BLOCK PAGE
MOVE T2,P1 ;GET PHYSICAL ADDRESS OF BAT BLOCK PAGE
MOVE T3,CKBFLG ;GET FLAGS
HRRZ T4,(P4) ;GET ADDRESS OF UDB
CALL DOPACK ;GO CHECK THE BAT BLOCKS ON ONE UNIT
JRST NXTUN1 ;DON'T TRY TO MARK OFF SWAPPING SPACE
;..
;..
;ROUTINE TO MARK OFF SWAPPING SPACE WHICH HAS BEEN RECORDED BAD
;AND TO MOVE TO THE NEXT LOGICAL UNIT
NXTUNT: JUMPN P5,NXTUN1 ;IS THIS THE PUBLIC STRUCTURE
MOVE A,CKBADR ;GET VIRTAUL ADDRESS OF FIRST BAT BLOCK
CALL BATSPC ;FOUND SPACE IN BLOCK
MOVEI P3,MAXBFR(A) ;FIND NUMBER USED
JUMPE P3,NXTUN1 ;NONE HERE
LSH P3,-1 ;CALCULATE NUMBER OF PAIRS
MOVE C,CKBADR ;GET VIRTUAL ADDRESS OF FIRST BAT BLOCK
ADDI C,BAT1P ;FIRST BAD ONE
DOBADS: LOAD A,BADT,(C) ;GET TYPE OF THIS PAIR
SKIPN A ;OLD?
JRST [ LOAD A,ADD18,(C) ;YES.
JRST GTADR] ;GO INLINE
LOAD A,ADD27,(C) ;NO. GET NEW TYPE
GTADR: LOAD B,BATNB,(C) ;NUMBER OF BAD ONES
ADD B,A ;CALCULATE LAST SECTOR
CALL DSPAIR ;MARK BAT SECTORS IN BIT TABLE
ADDI C,2 ;NEXT PAIR
SOJG P3,DOBADS ;DO ALL PAIRS
NXTUN1: AOBJN P4,DOUNIT ;DO ALL PACKS
MOVE A,CKBPAG ;GET PHYSICAL PAGE NUMBER OF BAT BLOCK PAGE
CALLRET MULKCR ;UNLOCK THE PAGE AND RETURN
;DSPAIR
;Routine to mark a bat block pair as used in the drum bit table.
;
;Accepts:
;
; T1/ Physical Disk Address of first bad sector
; T2/ Physical Disk Address of last bad sector
; P4/ (Negative Count,,SDBUDB)
; P5/ Structure Number
;
; CALL DSPAIR
;
;Returns: +1 Always.
; All sectors defined by arguments which correspond to
; logical sectors are marked in the drum bit table
;
; Destroys T1 and T2
;
;Use of Registers:
;
; C/ DSKSIZ Table
; D/ SDB
; P1/ PHYSICAL ADDRESS OF BAT BLOCK PAGE
; P4 /(-NUMBER PACKS,,SDBUDB FOR CURRENT PACK)
; P5 /STRUCTURE NUMBER
DSPAIR: CAML T1,T2 ; STILL WITHIN THE REGION?
RET ; NO, FINISHED WITH THIS PAIR
CALL DOSECT ; MARK THIS SECTOR AS USED
JRST DSPAIR ; YES. GO DO IT
DOSECT: SAVEAC <T2,T3,T4> ;
STKVAR <CURBAT,CKBDRA> ;
MOVEM T1,CURBAT ; SAVE PHYS SECT ADDRESS OF FIRST SECTOR
MOVE T4,STRTAB(P5) ; GET SDB
MOVE T3,SDBTYP(T4) ; POINT TO SIZE DATA FOR THIS DISK TYPE
CALL CVDADR ; FIND LOGICAL SECTOR NUMBER
RET ; THIS IS A LOST SECTOR, FORGET IT
IDIV T1,SECPAG(T3) ; GET INTEGRAL NUMBER OF PAGES
IMUL T1,SECPAG(T3) ; FIND STARTING SECTOR FOR PAGE
SUB T1,SDBFSS(T4) ; SEE IF WITHIN SWAPPING BOUNDS
SKIPL T1 ; IS IT?
CAML T1,SDBNSS(T4) ; ?
JRST DSECT1 ; NO
IDIV T1,SECCYL(T3) ; FIND TRACK AND SECTOR OFFSET IN TRACK
IMUL T1,SDBNUM(T4) ; FIND INTERLEAVED TRACK NUMBER
MOVEI T4,-SDBUDB(P4) ; GET PACK # + SDB LOCATION
SUB T4,STRTAB(P5) ; COMPUTE PACK NUMBER IN STRUCTURE
ADD T1,T4 ; ADD PACK NUMBER ...
IMUL T1,SECCYL(T3) ; FIND STARTING SWAP SECT FOR THIS TRACK
ADD T1,T2 ; ADD IN SECTOR OFFSET IN TRACK
TXO T1,DRMOB ; SAY IS AN OVERFLOW ADDRESS
MOVEM T1,CKBDRA ; SAVE ADDRESS TO BE ASSIGNED
CALL DRMASA ; ASSIGN DRUM ADDRESS
JRST [ MOVE T3,STRTAB+PSNUM ; POINT TO SDB FOR PS (ONLY CASE
LOAD T3,STRNAM,(T3) ; IN WHICH WE GET HERE)
SKIPE T1 ; OUT-OF-RANGE?
BUG(SWPASF,<<T3,STRNAM>,<CKBDRA,ADDR>>)
JRST DSECT1] ;
DSECT1: MOVE T1,CURBAT ; GET BACK PHYSICAL SECTOR ADDRESS
MOVE T3,STRTAB(P5) ; GET SDB
MOVE T3,SDBTYP(T3) ; POINT TO SIZE DATA FOR THIS DISK TYPE
ADD T1,SECPAG(T3) ; STEP THE SECTORS BY A PAGE
RET ; AND RETURN
;CVDADR - Local routine to DSPAIR to convert a physical unit address to
; a logical linear unit sector address, accounting for lost sectors.
;
;ACCEPTS
; T1/ Physical Sector Address
; T3/ DSKSIZ table for structure type
;
; CALL CVDADR
;
;RETURNS +1: Address is for a lost sector.
; T1/ Physical sector address just following lost region
; +2: T1/ Logical sector address
;
;Uses T1-T3. Preserves T4.
CVDADR: SAVEAC <T4>
MOVE T4,SECCYL(T3) ; GET LOGICAL SECTORS/CYLINDER
ADD T4,LPPCYL(T3) ; ADD LOST SECT TO GET PHYSICAL SEC/CYL
IDIV T1,T4 ; GET CYL IN T1, SEC IN T2
CAML T2,SECCYL(T3) ; IS THIS A LOST SECTOR?
JRST [ AOS T1 ; YES, GET CYL FOLLOWING THIS LOST REGION
IMUL T1,T4 ; FIND PHYS SECT NUMBER OF FIRST SECTOR
RET] ; AND RETURN
IMUL T1,SECCYL(T3) ; CONVERT CYL TO LOGICAL SECTORS
ADD T1,T2 ; COMBINE TO GET LOGICAL ADR
RETSKP ; AND TAKE SKIP RETURN
; ROUTINE TO CHECK THE BAT BLOCKS ON A SINGLE UNIT
;
; ACCEPTS IN T1/ VIRTUAL ADDRESS OF BAT BLOCK PAGE
; T2/ PHYSICAL ADDRESS OF BAT BLOCK PAGE
; T3/ FLAGS
; MI%MSG - TYPE MESSAGES ON CTY IF ON
; MS%NFB - DO NOT FIX BAD BAT BLOCKS
; T4/ ADDRESS OF UDB FOR THIS UNIT
; CALL DOPACK
; RETURNS: +1 FAILED, BAT BLOCKS BAD (ONLY TAKEN IF MS%NFB WAS ON)
; +2 SUCCESS, BAT BLOCKS GOOD OR REPAIRED IF BAD
DOPACK: SAVEP
ASUBR <PAKVIR,PAKPHY,PAKFLG,PAKUDB>
MOVEI P4,PAKUDB ;SET UP POINTER TO ADDRESS OF UDB
CALL SETBAT ;SET NO BAT BIT
CALL FNDCHN ;GO FIND THE CKU NUMBERS FOR THIS PACK
MOVE P2,T1 ;SAVE THE PHYSICAL ID
MOVE T3,PAKVIR ;VIRTUAL ADDRESS TO READ INTO
MOVE T2,PAKPHY ;CORE ADDRESS
CALL GETBAT ;GET THE BAT BLOCKS INTO CORE
MOVE T2,T1 ;MOVE THE MASK
TLNN T2,(1B0) ;IS ONE OK?
JRST ONEBAD ;NO. HOPE 2 IS OK!
TLNE T2,(1B1) ;IS 2 OK?
JRST CMPBAT ;YES. GO COMPARE BAT BLOCKS
TWOBAD: MOVE T1,PAKFLG ;GET FLAGS
TXNE T1,MS%NFB ;FIX THE BAD BAT BLOCK ?
RET ;NO, RETURN FAILURE (BAT BLOCK BAD)
MOVE T2,PAKVIR ;GET VIRTUAL ADDRESS OF FIRST BAT BLOCK
MOVE T3,PAKPHY ;PHYSICAL CORE ADDRESS
CALL CPY1 ;COPY PRIMARY
JRST NOBATS ; ASSUME NONE THERE
JRST CHKFUL
;PRIMARY BAT BLOCK IS INCORRECT
ONEBAD: TLNN T2,(1B1) ;IS THE BACKUP OK?
JRST NOBATS ;NO. WE LOSE
MOVE T1,PAKFLG ;YES, GET FLAGS
TXNE T1,MS%NFB ;FIX THE BAD BAT BLOCK ?
RET ;NO, RETURN FAILURE (BAD BAT BLOCK)
MOVE T2,PAKVIR ;GET ADDRESS OF BAT BLOCKS
MOVE T3,PAKPHY ;PHYSICAL CORE ADDRESS
CALL CPY2 ;COPY SECONDARY TO PRIMARY BAT BLOCK
JRST NOBATS ; ASSUME NONE THERE
; HERE TO COMPARE THE TWO BAT BLOCKS
CMPBAT: MOVE T1,PAKVIR ;GET ADDRESS OF FIRST BAT BLOCK
CALL BATCMP ;COMPARE THE TWO BLOCKS
SKIPA ;DIDNT MAKE IT
JRST CHKFUL ;THEY COMPARE!
NOCMPR: MOVE T1,PAKFLG ;GET FLAGS
TXNN T1,MI%MSG ;MESSAGE REQUESTED ?
JRST TWOBAD ;NO, GO ON
HRROI T1,[ASCIZ /%BAT blocks do not compare on /]
CALL FSIPSO
CALL UNTSTR ;OUTPUT STRUCTURE/UNIT MESSAGE
HRROI T1,[ASCIZ /
/]
CALL FSIPSO
JRST TWOBAD ;SO DO THE COPY
CHKFUL: CALL CLRBAT ; CLEAR BAT BIT
MOVE T1,PAKVIR ;GET ADDRESS OF BAT BLOCKS
CALL BATSPC ;FOUND SPACE LEFT
JUMPN A,RSKP ;IF ROOM LEFT, GO ON
MOVE T1,PAKFLG ;GET FLAGS
TXNN T1,MI%MSG ;MESSAGE REQUESTED ?
RETSKP ;NO, RETURN SUCCESS
HRROI T1,[ASCIZ /%BAT block full on /]
CALL FSIPSO
CALL UNTSTR ;OUTPUT STRUCTURE/UNIT MESSAGE
HRROI T1,[ASCIZ /
/]
CALL FSIPSO ;FINISH IT OFF
RETSKP ;RETURN SUCCESS
;HERE IF UNIT DOES NOT HAVE CONSISTENT BAT BLOCKS
NOBATS: MOVE T1,PAKFLG ;GET FLAGS
TXNN T1,MI%MSG ;MESSAGES REQUESTED ?
JRST CREBAT ;NO, GO SEE IF NEW BAT BLOCKS ARE WANTED
MOVEI T1,"?" ;YES, GET FIRST CHARACTER OF ERROR MESSAGE
CALL FSIPBO ;OUTPUT INITIAL PART OF MESSAGE
CALL UNTSTR ;STRUCTURE/UNIT MESSAGE
HRROI T1,[ASCIZ / has no consistent BAT blocks
/]
CALL FSIPSO ;TELL HIM
CREBAT: MOVE T1,PAKFLG ;GET FLAGS
TXNE T1,MS%NFB ;FIX THE BAT BLOCKS ?
RETSKP ;NO, RETURN
XMOVEI P4,PAKUDB ;GET POINTER TO ADDRESS OF UDB
CALL FNDCHN ;GET CHANNEL, CONTROLLER, AND UNIT NUMBERS
MOVE T2,PAKVIR ;GET VIRTUAL ADDRESS FOR NEW BAT BLOCKS
MOVE T3,PAKPHY ;GET PHYSICAL ADDRESS FOR NEW BAT BLOCKS
SETZM T4 ;NO FLAGS
CALL MAKBAT ;MAKE A SET OF NEW BAT BLOCKS
RET ;FAILED, RETURN ERROR
RETSKP ;DONE, RETURN SUCCESS
;ROUTINE TO OUTPUT STANDARD STRUCTURE/UNIT MESSAGE
; P5/ STRUCTURE NUMBER
; P4/ SDBUDB POINTER
UNTSTR: HRRZ T1,STRTAB(P5) ;GET SDB POINTER
MOVE T1,SDBNAM(T1) ;GET IT'S NAME
CALL FSI6TY ;OUTPUT SIXBIT NAME
HRROI T1,[ASCIZ / unit /]
CALL FSIPSO ;OUTPUT LITERAL STRING
MOVE T1,(P4) ;GET ADDRESS OF UDB FOR THIS UNIT
HLRZ T1,UDBSTR(T1) ;GET UNIT NUMBER
CALLRET FSIOTY ;OUTPUT OCTAL NUMBER
;THIS ROUTINE COMPARES TWO BAT BLOCKS
;ACCEPTS: T1/ VIRTUAL ADDRESS OF FIRST BAT BLOCK
;
;RETURNS: +1 NO COMPARE
; +2 COMPARE
BATCMP: MOVEI T3,HBLEN-1 ;DO 127 WORDS
MOVE T2,T1 ;GET ADDRESS OF FIRST BAT BLOCK
MOVEI T4,HBLEN(T2) ;GET ADDRESS OF SECOND BAT BLOCK
CMPR: MOVE T1,(T2) ;GET WORD FROM BLOCK 1
CAME T1,(T4) ;SAME IN BLOCK 2?
RET ;NO COMPARE
ADDI T2,1
ADDI T4,1 ;NEXT WORD
SOJG T3,CMPR ;DO ALL OF BLOCK
RETSKP ;EXACT
;ROUTINES TO SET AND CLEAR DSKBAT IN DSKSTS
;ACCEPTS P4/ SDBUDB POINTER
;
;RETURNS +1 ALWAYS
SETBAT: TDZA T1,T1 ; REMEMBER THIS ENTRY
CLRBAT: MOVEI T1,1 ; REMEMBER THIS ENTRY
MOVX T2,US.BAT ; THE BIT IN QUESTION
HRRZ T3,0(P4) ;GET UDB POINTER
XCT [ IORM T2,UDBSTS(T3) ;SET BIT
ANDCAM T2,UDBSTS(T3)](T1)
RET
;THIS ROUTINE WILL READ THE BAT BLOCKS INTO A SPECIFED BUFFER
;ACCEPTS T1/ CKU NUMBER (CHAN, CTRL, AND UNIT NUMBERS)
; T2/ CORE ADDRESS
; T3/ VIRTUAL CORE ADDRESS
;RETURNS +1 ALWAYS WITH
; 1B0 0F T1 =1 IF PRIMARY IS IN AND GOOD
; 1B1 OF T1 =1 IF SECONDARY IS IN AND GOOD
GETBAT::SAVEP ;GET SOME REGS
MOVEI P1,(T3) ;SAVE VIRTUAL ADDRESS
MOVEI T3,BATBL1 ;LOCAL ADDRESS OF FIRST BAT BLOCK
MOVE P2,T1 ;SAVE DRIVE
MOVEI T4,(P1) ;VIRTUAL CORE ADDRESS
CALL REDHOM ;GET THE BAT BLOCKS IN CORE
JFCL ;IGNORE ERROR CONDITIONS
MOVEI T1,(P1) ;CORE ADDRESS
MOVEI T2,BATBL1 ;BLOCK NUMBER
SETZ P3,
CALL BATLOK ;VERIFY BLOCK IS GOOD
JRST CHKBT1 ;NOT. GO LOOK AT NEXT ONE
MOVSI P3,(1B0) ; SAY 1 IS GOOD
CHKBT1: MOVEI T1,(P1)
ADDI T1,HBLEN ;POIINT TO SECOND ONE
MOVEI T2,BATBL1+HM2BLK-HM1BLK ;IS AFTER NEXT BLOCK
CALL BATLOK ;GO CHECK SECOND BAT BLOCK
TDZA T1,T1 ; 2 IS BAD
MOVSI T1,(1B1) ;SAY 2 IS GOOD
IOR T1,P3 ;MASK THEM TOGETHER
RET
;ROUTINE TO WRITE OUT THE BAT BLOCKS FOR A GIVEN PHYSICAL DRIVE
;ACCEPTS: T1/ CKU NUMBER OF UNIT
; T2/ VIRTUAL ADDRESS IN MEMORY OF BAT BLOCKS
; T3/ PHYSICAL CORE ADDRESS OF BAT BLOCKS
;RETURNS: +1 WRITE FAILED
; +2 OK
BATOUT::ASUBR <SVDRV,SVVADR,SVPADR,TEST1> ;SAVE CALLING ARGUMENTS
SETZM TEST1 ;ASSUME NONE WORKED
MOVE T2,[1B0+1B14+HBLEN] ;CONTROL WORD
MOVE T3,SVPADR ;GET PHYSICAL ADDRESS
MOVE T4,SVDRV ;GET CKU NUMBERS
MOVEI T1,BATBL1 ;BLOCK NUMBER
CALL UDSKIO ;OPERATE THE DISK
JUMPE T1,DO2B ;IF NO ERROR,GO ON
SETOM TEST1 ;MARK FAILURE
MOVE T1,SVDRV ;GET CKU NUMBER BACK
BUG(NOBAT1,<<T1,CKUNUM>>)
DO2B: MOVE T1,SVVADR ;GET VIRTUAL ADDRESS OF BAT BLOCKS
CALL SWPHOM ;SWAP THE BAT BLOCKS
MOVE T2,[1B0+1B14+HBLEN] ;CONTROL WORD
MOVE T3,SVPADR ;GET PHYSICAL ADDRESS AGAIN
MOVE T4,SVDRV ;GET CKU NUMBER
MOVEI T1,BATBL1+HM2BLK-HM1BLK ;ADDRESS OF SECONDARY BLOCK
CALL UDSKIO ;OPERATE DISK AGAIN
MOVE T4,T1 ;SAVE RESULT
MOVE T1,SVVADR ;RETRIEVE VIRTUAL ADDRESS OF BAT BLOCKS
CALL SWPHOM ;SWAP BAT BLOCKS BACK
SKIPN T4 ;NO ERRORS?
RETSKP ;YES. SAY IT IS GOOD THEN
MOVE T1,SVDRV ;GET CKU NUMBER
BUG(NOBAT2,<<T1,CKUNUM>>)
SKIPE TEST1 ;DID IT WRITE THE PRIMARY?
RET ;NO. NONE GOOD THEN
RETSKP ;YES. ONE IS GOOD
;ROUTINE TO CHECK THE BAT BLOCK FOR CONSISTENCY
;ACCEPTS IN T1/ CORE ADDRESS OF BAT BLOCK
; T2/ BLOCK #
;RETURNS: +1 INCOSISTENT BAT BLOCK
; +2 CONSISTENT
BATLOK: MOVS T3,BATNAM(T1) ;GET THE NAME
CAIE T3,'BAT' ;IS IT A BAT BLOCK
RETBAD ;BAD
MOVE T3,BATCOD(T1) ;GET UNLIKELY CODE
CAIE T3,CODBAT ;GOOD?
RETBAD ;NO
MOVE T3,BATBLK(T1) ;GET BLOCK NUMBER
CAME T3,T2 ;CORRECT ONE?
RETBAD ;NO
RETSKP ;IT'S GOOD
;FSIDIA - DIAGLOGUE TO DEFINE THE PUBLIC STRUCTURE
; CALL FSIDIA
;RETURNS +1: ALWAYS,
; FLAGS SET IN STARTF INDICATING ANSWERS TO QUESTIONS
;THIS IS ALWAYS CALLED WHEN THE SYSTEM IS STARTED AT SYSLOD. IT ACCEPTS
;INFORMATION FROM THE USER AND WRITES THE HOME BLOCKS (IF REQUESTED)
;ON THE SPECIFIED PACKS, THUS CREATING A STRUCTURE. IT DOES NOT
;BUILD AN SDB FOR THE STRUCTURE
FSIDIA: MOVSI T1,-HOMTBL ;CLEAR OUT PHYSICAL DRIVE CORRESPONDENCE
SETOM HOMTAB(T1) ;FOR DETECTING MULTIPLE REFERENCES
AOBJN T1,.-1
HRROI T1,[ASCIZ/
[For additional information type "?" to any of the following questions.]
/]
CALL FSIPSO
;SEE IF USER WANTS TO REFRESH THE FILE SYSTEM
FSIDI0: SETOM FSIUSZ ;INDICATE UNIT SIZE UNKNOWN
HRROI T1,[ASCIZ/
Do you want to replace the file system on the system structure? /]
HRROI T2,[ASCIZ/
[This procedure removes all existing directories and files and creates
the minimum directories needed to bring up the system.]
/]
MOVEI T3,FSIYNO ;GET YES OR NO
CALL FSIASK ;GO ASK QUESTION AND GET ANSWER IN T1
JRST FSIDI0 ;ERROR, GO ASK AGAIN
SKIPN T1 ;WAS THE ANSWER YES?
JRST [ MOVX T4,MI%RFS ;NO. INDICATE NOT REFRESHING
ANDCAM T4,STARTF
MOVX T4,MI%RCN ; BUT RATHER MIGHT BE RECONSTRUCTING
IORM T4,STARTF ; FOR FILINI TO DETECT LATER
MOVE T2,DBUGSW ;IF DEBUGGING, ALLOW THEM TO REWRITE THE
CAIE T2,2 ; THE HOME BLOCKS. OTHERWISE, ASSUME
RET ; THEY COULD DO THEMSELVES IN
JRST .+1]
SETOM FEFSIZ ;INDICATE SIZE OF FE FILE SYSTEM UNKNOWN
;SEE IF USER WANTS TO REWRITE THE HOME BLOCKS
FSIDI4: HRROI T1,[ASCIZ/
Do you want to define the system structure? /]
HRROI T2,[ASCIZ/
[This will cause the home blocks to be rewritten. It should be done
only if the answer to the previous question was yes.]
/]
MOVEI T3,FSIYNO ;GET YES OR NO
CALL FSIASK ;ASK THE QUESTION AND GET THE ANSWER
JRST FSIDI4 ;FAILED. TRY AGAIN
JUMPE T1,R ;IF NO. DON'T REWRITE HOME BLOCKS
;USER WANTS TO REWRITE HOME BLOCKS. IF NOT ALSO REFRESHING FILE SYSTEM,
;PRINT WARNING BUT CONTINUE
MOVX T4,MI%HMB ;YES. INDICATE HOME BLOCKS ARE TO BE
IORM T4,STARTF ; REWRITTEN FOR FILINI TO DETECT LATER
MOVX T4,MI%RFS ;ARE WE REFRESHING THE FILE SYSTEM?
TDNE T4,STARTF
JRST FSIDI1 ;YES. OK THEN
HRROI T1,[ASCIZ/
WARNING: This is a dangerous procedure. It may cause inconsistency
in the structure.
/]
CALL FSIPSO ;OUTPUT THE WARNING
;FIND OUT WHAT PACKS ARE IN THE STRUCTURE
FSIDI1: HRROI T1,[ASCIZ/
How many packs are in this structure: /]
HRROI T2,[ASCIZ/
[Enter the decimal number of disk packs that compose this structure]
/]
MOVEI T3,FSIDEC ;GET DECIMAL NUMBER OF PACKS
CALL FSIASK ;GO ASK QUESTION AND GET ANSWER
JRST FSIDI1 ;ERROR, GO ASK QUESTION AGAIN
JUMPLE T1,[HRROI T1,[ASCIZ/? The answer must be greater than zero!
/]
CALL FSIPSO ;TYPE OUT COMPLAINT
JRST FSIDI1] ;GO ASK QUESTION AGAIN
MOVEM T1,FSINPK ;SAVE COUNT OF PACKS IN PUBLIC STR
MOVEM T1,FSIDIC ;SAVE THIS COUNT FOR ENSUING QUESTIONS
CAILE T1,HOMTBL ;IS THIS NUMBER TOO BIG?
JRST [ HRROI T1,[ASCIZ/? The monitor is not assembled to handle that many units!
/]
CALL FSIPSO ;TYPE OUT MESSAGE
JRST FSIDI1] ;ASK QUESTION AGAIN
;..
;..
;GET THE CHANNEL, CONTROLLER, AND UNIT FOR EACH LOGICAL UNIT IN THE STRUCTURE.
;STORE IN HOMTAB, INDEXED BY LOGICAL UNIT NUMBER
FSIDI2: MOVE T1,[POINT 7,FSIBLK] ;SET UP TO BUILD QUESTION STRING
MOVE T2,[POINT 7,[ASCIZ/
On which "CHANNEL,CONTROLLER,UNIT" is logical pack # /]]
CALL FSICPY ;COPY STRING TO TEMP BLOCK
MOVE T2,FSINPK ;CALCULATE NUMBER OF THIS UNIT
SUB T2,FSIDIC ;UNITS START AT 0, THEN 1, 2, ...
MOVEI T3,12 ;SET RADIX TO 10
CALL FSINST ;PUT PACK # IN QUESTION STRING
MOVE T2,[POINT 7,[ASCIZ/ mounted? /]]
CALL FSICPY ;FINISH BUILDING QUESTION STRING
HRROI T1,FSIBLK ;GET POINTER TO QUESTION STRING
MOVEI T2,FSICFG ;HELP MESSAGE ROUTINE
MOVEI T3,FSIOCT ;GET PHYSICAL DRIVE #
CALL FSIASK ;ASK QUESTION AND GET ANSWER
JRST FSIDI2 ;ERROR, GO ASK QUESTION AGAIN
MOVEM T1,FSICHN ;SAVE CHANNEL NUMBER
CALL FSIOCT ;READ IN CONTROLLER NUMBER
JRST FSIDI2 ;ERROR, ASK AGAIN
MOVEM T1,FSICTL ;SAVE CONTROLLER NUMBER
CALL FSIOCT ;READ IN UNIT NUMBER
JRST FSIDI2 ;ERROR
MOVEM T1,FSIUNT ;SAVE UNIT NUMBER
MOVE T1,FSICHN ;GET CHANNEL NUMBER
MOVE T2,FSICTL ;CONTROLLER NUMBER
MOVE T3,FSIUNT ;AND UNIT NUMBER
CALL CHKCKU ;LOOK FOR THE SPECIFIED UNIT
SKIPA T2,T1 ;FAILED, HAVE TO SEE WHY
JRST FSIDE1 ;FOUND IT, PROCEED
HRROI T1,[ASCIZ/? Can't find specified unit/] ;START WITH CATCH ALL
CAIN T2,MSTX14 ;INVALID CHANNEL?
HRROI T1,[ASCIZ/? Illegal channel number/]
CAIN T2,MSTX41 ;NO SUCH CHANNEL?
HRROI T1,[ASCIZ/? No such channel/]
CAIN T2,MSTX16 ;INVALID CONTROLLER?
HRROI T1,[ASCIZ/? Illegal controller number/]
CAIN T2,MSTX42 ;NO SUCH CONTROLLER?
HRROI T1,[ASCIZ/? No such controller/]
CAIN T2,MSTX15 ;ILLEGAL UNIT?
HRROI T1,[ASCIZ/? Illegal unit number/]
CAIN T2,DIAGX9 ;NO SUCH UNIT?
HRROI T1,[ASCIZ/? No such unit/]
CAIN T2,MSTX27 ;NOT A DISK?
HRROI T1,[ASCIZ/? Not a disk device/]
CALL FSIPSO ;GIVE THE MESSAGE
HRROI T1,[ASCIZ/.
/] ;FINAL CRLF
CALL FSIPSO ;GIVE THAT TOO
JRST FSIDI2 ;AND TRY AGAIN
FSIDE1: MOVEM T1,FSIUDB ;REMEMBER UDB OF UNIT
MOVE T3,UDBSIZ(T1) ;GET ADDRESS OF SIZE DATA FOR THIS TYPE
MOVEM T3,FSITYP ;SAVE IT FOR WRTHOM
MOVE T2,CYLUNT(T3) ;GET NUMBER OF CYLINDERS
SKIPGE FSIUSZ ;UNIT SIZE SET YET?
MOVEM T2,FSIUSZ ;NO - SET IT
CAME T2,FSIUSZ ;CHECK IF SAME AS OTHER UNITS
JRST [ HRROI T1,[ASCIZ /? All disk units in a single structure must be the same size.
/]
CALL FSIPSO ;CHIDE USER
JRST FSIDI2] ;AND TRY AGAIN
IMUL T2,FSINPK ;CHECK IF A STRUCTURE THIS LARGE IS OK
MOVE T1,BTWCYL(T3) ; Get Bit words per cylinder
AOS T1 ; Add one word/cyl for Top of BTB
IMUL T2,T1 ; CYL/STR * BTB words/CYL = Size of BTB
CAMLE T2,BTBSIZ ; I.E,. ITS BIT TABLE ISN'T TOO BIG)
JRST [ HRROI T1,[ASCIZ /? You are attempting to define a structure which has more space than is supported.
/]
CALL FSIPSO
JRST FSIDI0] ;RESTART THE WHOLE AFFAIR
MOVE T1,FSICHN ;GET CHANNEL
MOVE T2,FSICTL ;CONTROLLER
MOVE T3,FSIUNT ;AND UNIT
CALL CKUPAK ;RETURN THE CKU NUMBER IN T1
MOVE T2,FSINPK ;GET LOGICAL PACK NUMBER AGAIN
SUB T2,FSIDIC ;...
MOVE T4,T2 ;LIMIT SEARCH TO PREVIOUS ENTRY
SOS T4
JUMPL T4,FSIDI8 ;NO PREVIOUS ENTRIES. NO DUPLICATION
MOVNS T4 ;GET NEGATIVE COUNT
HRLZS T4 ;T4/(-COUNT,,LOGICAL UNIT NUMBER)
FSIDI7: CAMN T1,HOMTAB(T4) ;HAS THIS PAIR BEEN SPECIFIED BEFORE?
JRST [ HRROI T1,[ASCIZ/? That drive was already assigned
/]
CALL FSIPSO ;TYPE OUT COMPLAINT
JRST FSIDI2] ;ASK QUESTION AGAIN
AOBJN T4,FSIDI7 ;NO. KEEP LOOKING
FSIDI8: MOVEM T1,HOMTAB(T2) ;STORE CKU NUMBER FOR THIS LOGICAL UNIT
SOSLE FSIDIC ;ANY MORE PACKS IN THE STR?
JRST FSIDI2 ;YES, ASK ABOUT THEM ALSO
FSIDI3: HRROI T1,[ASCIZ/
Do you want the default swapping space? /]
MOVEI T2,FSIPSW ;T2/ROUTINE TO TYPE HELP TEXT
MOVEI T3,FSIYNO ;T3/ROUTINE TO GET YES OR NOT
CALL FSIASK ;ASK THE QUESTION
JRST FSIDI3 ;ERROR. GO ASK AGAIN
JUMPN T1,[ MOVE T1,NSWPGS
JRST FSIDI6]
;USER DOESN'T WANT THE DEFAULT. GET THE USER'S CHOICE
FSIDI5: HRROI T1,[ASCIZ/
How many pages for swapping? /]
HRROI T2,[ASCIZ/
[Enter the decimal number of pages to be allocated for the entire structure]
/]
MOVEI T3,FSIDEC ;READ A DECIMAL NUMBER
CALL FSIASK ;ASK THE QUESTION AND GET THE ANSWER
JRST FSIDI5 ;ERROR. ASK AGAIN
FSIDI6: MOVEM T1,FSISWP ;SAVE THE ANSWER
JUMPLE T1,FSIDI9 ;NEGATIVE IS ILLEGAL
CAIGE T1,^D2000 ;IS THIS ENOUGH SWAPPING SPACE?
JRST FSIDI9 ;NO. PS MUST HAVE ENOUGH
MOVE T1,FSIUDB ;T1/ UDB OF A UNIT
MOVE T2,FSINPK ;T2/NUMBER OF UNITS IN STRUCTURE
MOVE T3,FSISWP ;T3/NUMBER OF SWAPPING PAGES SPECIFIED
CALL CHKSWP ;SEE IF THIS ANSWER IS VALID
SKIPA ;INVALID. GO COMPLAIN
JRST FSID10 ;VALID. PROCEED
FSIDI9: HRROI T1,[ASCIZ/
? Invalid number of swapping pages for this type of disk.
/]
CALL FSIPSO ;PRINT THE COMPLAINT
JRST FSIDI3 ;GO ASK AGAIN
;IF USER IS REFRESHING, FIND OUT HOW MUCH ROOM TO ALLOCATE FOR THE
;FRONT END FILE SYSTEM
FSID10: MOVX T4,MI%RFS ;ARE WE REFRESHING?
TDNN T4,STARTF
JRST FSID17 ;NO. DON'T ASK ABOUT THE SIZE
HRROI T1,[ASCIZ/
Do you want the default size front end file system? /]
HRROI T2,[ASCIZ/
[The default is 950 pages]
/]
MOVEI T3,FSIYNO ;GET YES OR NO
CALL FSIASK ;ASK QUESTION AND GET THE ANSWER
JRST FSID10 ;ERROR. ASK AGAIN
JUMPN T1,[MOVEI T1,NPGSFE
JRST FSID12]
;USER DOESN'T WANT THE DEFAULT. GET THE USER'S CHOICE
FSID11: HRROI T1,[ASCIZ/
How many pages for the front end file system? /]
HRROI T2,[ASCIZ/
[Enter the decimal number of pages for the front end file system]
/]
MOVEI T3,FSIDEC ;GET A DECIMAL NUMBER
CALL FSIASK ;ASK QUESTION AND GET THE ANSWER
JRST FSID10 ;ERROR. ASK AGAIN
FSID12: JUMPL T1,FSID10 ;ASK AGAIN IF NEGATIVE
MOVEM T1,FEFSIZ ;SAVE THE ANSWER
JRST FSID13 ;YES.
REPEAT 0,<
FSIDI3: HRROI T1,[ASCIZ/
Is this structure the system structure? /]
HRROI T2,[ASCIZ/
[The system structure is the structure that contains <SYSTEM>
and <SUBSYS> and to which each user is connected by login. The
system structure must always be mounted during system operation.]
/]
MOVEI T3,FSIYNO ;GET A YES OR NO ANSWER
CALL FSIASK ;ASK THE QUESTION
JRST FSIDI3 ;GET AN ANSWER
SKIPE T1 ;WAS THE ANSWER YES?
MOVX T1,HB%PUB ;YES, MARK THAT THIS IS PUBLIC STR
MOVEM T1,FSIFLG ;SAVE FLAGS
>
FSID13: HRROI T1,[ASCIZ/
Do you want the default size bootstrap area? /]
HRROI T2,[ASCIZ/
[The default is 64 pages]
/]
MOVEI T3,FSIYNO ;GET YES OR NO
CALL FSIASK ;ASK QUESTION AND GET THE ANSWER
JRST FSID13 ;ERROR. ASK AGAIN
JUMPN T1,[MOVEI T1,NPGSBT
JRST FSID15]
;USER DOESN'T WANT THE DEFAULT. GET THE USERS CHOICE
HRROI T1,[ASCIZ/
How many pages for the bootstrap file? /]
HRROI T2,[ASCIZ/
[Enter the decimal number of pages for the bootstrap file]
/]
MOVEI T3,FSIDEC ;GET A DECIMAL NUMBER
CALL FSIASK ;ASK QUESTION AND GET THE ANSWER
JRST FSID13 ;ERROR. ASK AGAIN
FSID15: MOVEM T1,BOTSIZ ;SAVE THE ANSWER
CAIL T1,NPGSBT ;IS THIS ENOUGH SPACE?
JRST FSID17 ;YES
HRROI T1,[ASCIZ/
? Invalid number of pages for the bootstrap file
/]
CALL FSIPSO ;NO. COMPLAIN
JRST FSID13 ;TRY AGAIN
FSID17: HRROI T1,[ASCIZ/
What is the name of this structure? /]
HRROI T2,[ASCIZ/
Enter 6 or fewer characters
/]
MOVEI T3,FSIDEV ;GET A SIXBIT DEVICE NAME
CALL FSIASK ;GET THE NAME OF THE STRUCTURE
JRST FSID17 ;FAILED, TRY AGAIN
JUMPE T1,FSID17 ;GAVE NO NAME, TRY AGAIN
MOVEM T1,FSINAM ;SAVE THE NAME
SETZM FSIFLG ;INIT FLAGS
MOVE T1,APRSER ;GET CPU SERIAL NUMBER
MOVEM T1,FSISER
CALL WRTHOM ;NOW THAT HOMTAB IS OK, GO WRITE HB'S
RET ;ERROR ON WRITING OF HOME BLOCKS
HRROI T1,[ASCIZ/
[Structure "/]
CALL FSIPSO ;TELL OPERATOR THAT STR WAS DEFINED OK
MOVE T1,FSINAM ;GET STR NAME
CALL FSI6TY
HRROI T1,[ASCIZ/" successfully defined]
/]
CALL FSIPSO ;END MESSAGE AND EXIT
; JRST FSIDI0 ;LOOP BACK UNTIL USER THRU DEFINING
RET
;ROUTINE TO TYPE OUT CONFIGURATION OF CHANNELS, CONTROLLERS, AND UNITS
FSICFG: STKVAR <FSICFC,FSICFK,FSICFU,FSICFA> ;ALLOCATE STORAGE
HRROI T1,FSIMS1 ;GET HELP MESSAGE
CALL FSIPSO ;TYPE OUT FIRST PART OF MESSAGE
SETOM FSICFC ;SET CHANNEL TO -1 TO START LOOP
FSICF1: MOVE T1,FSICFC ;GET CHANNEL NUMBER
MOVE T2,FSICFK ;AND CONTROLLER NUMBER
MOVE T3,FSICFU ;AND THE UNIT NUMBER
CALL ADVCKU ;ADVANCE TO NEXT DISK UNIT IN SYSTEM
JRST [ HRROI T1,[ASCIZ/]
/] ;NO MORE UNITS, GET FINAL TEXT
CALLRET FSIPSO] ;FINISH MESSAGE AND RETURN
MOVEM T1,FSICFC ;SAVE NEW CHANNEL NUMBER (DMOVEM DOESN'T WORK!!)
MOVEM T2,FSICFK ;AND NEW CONTROLLER NUMBER
MOVEM T3,FSICFU ;ALSO SAVE NEW UNIT NUMBER
MOVEM T4,FSICFA ;FINALLY SAVE UDB ADDRESS
HRROI T1,[ASCIZ/ /] ;START WITH SOME SPACES
CALL FSIPSO ;TYPE THEM
MOVE T1,FSICFC ;GET CHANNEL NUMBER
CALL FSIOTY ;TYPE IT
MOVEI T1,"," ;PRINT COMMA
CALL FSIPBO ; ...
MOVE T1,FSICFK ;GET CONTROLLER NUMBER
CALL FSIOTY ;PRINT IT
MOVEI T1,"," ;ANOTHER COMMA
CALL FSIPBO ;TYPE IT
MOVE T1,FSICFU ;GET UNIT NUMBER
CALL FSIOTY ;TYPE IT
HRROI T1,[ASCIZ / ;Type=/] ;PREPARE TO PRINT UNIT TYPE
CALL FSIPSO ; ...
MOVE T4,FSICFA ;GET UDB ADDRESS
LOAD T1,USTYP,(T4) ;GET TYPE
MOVE T1,NAMUTP(T1) ;GET POINTER TO NAME
CALL FSIPSO ;PRINT NAME
MOVE T4,UDBSTS(T4) ;GET UNIT STATUS
TXNE T4,US.OFS ;OFFLINE?
CALL FSICF5 ;YES - PRINT MESSAGE
TXNE T4,US.PGM ;PROGRAMMABLE DUAL PORT?
CALL FSICF6 ;YES - PRINT MESSAGE
TXNE T4,US.WLK ;WRITE LOCKED?
CALL FSICF7 ;YES - PRINT MESSAGE
HRROI T1,[ASCIZ /
/]
CALL FSIPSO
JRST FSICF1 ;LOOP FOR NEXT UNIT
;HERE IF OFFLINE
FSICF5: HRROI T1,[ASCIZ /, Offline/]
CALL FSIPSO ;PRINT MESSAGE
RET
;HERE IF DUAL PORT
FSICF6: HRROI T1,[ASCIZ /, Dual port/]
CALL FSIPSO ;PRINT MESSAGE
RET
;HERE IF WRITE LOCKED
FSICF7: HRROI T1,[ASCIZ /, Write locked/]
CALL FSIPSO ;PRINT MESSAGE
RET
FSIMS1: ASCIZ/
[Enter a triple of numbers separated by commas that specify the channel,
controller, and unit upon which the appropriate pack is mounted. The
following is a list of valid channel, controller, and unit numbers:
/
;ROUTINES TO CORRECT ONE INCORRECT BAT BLOCK
;AND WRITE THE CORRECT PAIR
;BOTH ACCEPT: T1/ FLAGS
; T2/ VIRTUAL ADDRESS OF FIRST BAT BLOCK
; T3/ PHYSICAL CORE ADDRESS
; P2/ CKU NUMBER
; P4/ SDBUDB POINTER
; P5/ STRTAB POINTER
CPY1: TDZA T4,T4 ;INDICATE COPYING PRIMARY TO SECONDARY
CPY2: SETOM T4 ;INDICATE COPYING SECONDARY TO PRIMARY
ASUBR <CPBFLG,CPBVIR,CPBPHY,CPBDIR> ;SAVE ARGUMENTS
TXNN T1,MI%MSG ;MESSAGE DESIRED ?
JRST CPYB10 ;NO, GO SET UP THE BLT INSTRUCTION
HRROI T1,[ASCIZ/% Copying secondary BAT block to primary on /]
SKIPN CPBDIR ;COPYING PRIMARY TO SECONDARY ?
HRROI T1,[ASCIZ/% Copying primary BAT block to secondary on /]
CALL FSIPSO ;ISSUE MESSAGE
CALL UNTSTR ;OUTPUT STR NAME AND UNIT NUMBER
HRROI T1,[ASCIZ/
/] ;GET END OF LINE
CALL FSIPSO ;TERMINATE LINE
; HERE TO DO THE ACTUAL COPY
CPYB10: MOVE T1,CPBVIR ;GET VIRTUAL ADDRESS OF FIRST BAT BLOCK
MOVEI T3,BATBL1 ;GET BLOCK NUMBER OF FIRST BAT BLOCK
MOVEI T4,BATBLK(T1) ;GET ADDRESS OF BLOCK # IN FIRST BAT BLOCK
SKIPN CPBDIR ;COPYING SECONDARY TO PRIMARY ?
JRST CPYB20 ;NO, GO SET UP TO COPY PRIMARY TO SECONDARY
HRLI T1,HBLEN(T1) ;YES, GET SOURCE ADDRESS
JRST CPYB30 ;GO SET UP TERMINATING ADDRESS FOR COPY
CPYB20: HRLI T1,(T1) ;GET SOURCE ADDRESS
ADDI T1,HBLEN ;GET DESTINATION ADDRESS
ADDI T3,HM2BLK-HM1BLK ;GET BLOCK NUMBER OF SECOND BAT BLOCK
ADDI T4,HBLEN ;POINNT TO BLOCK NUMBER IN SECOND BAT BLOCK
CPYB30: MOVEI T2,(T1) ;SET UP TERMINATING ADDRESS
BLT T1,HBLEN-2(T2) ;COPY THE GOOD BAT BLOCK
MOVEM T3,(T4) ;STORE PROPER BLOCK NUMBER IN DESTINATION BLOCK
MOVE T1,P2 ;GET CKU NUMBERS
MOVE T2,CPBVIR ;GET VIRTUAL ADDRESS OF BAT BLOCKS
MOVE T3,CPBPHY ;GET PHYSICAL ADDRESS OF BAT BLOCKS
CALL BATOUT ;WRITE THE NOW GOOD BAT BLOCKS
RETBAD ;FAILED, RETURN ERROR
RETSKP ;SUCCESS, RETURN
;FSIBAT - DO ONCE ONLY CODE FOR THE BAT BLOCKS
;ACCEPTS:
; T1/STRUCTURE NUMBER
; CALL FSIBAT
;RETURNS +1: ALWAYS
;DOES CONSISTENCY CHECK AND CORRECTS BAT BLOCK BY COPYING THE
;BACKUP LIKE CHKBAT
;IF NONE THERE, ASKS IF A SET SHOULD BE PUT ON AND DOES IT IF THE
;ANSWER IS YES
;CURRENTLY ONLY CALLED FOR STRUCTURE 0 AT SYSTEM STARTUP
FSIBAT: SAVEP ;SAVE THE PERMANENTS
MOVEM T1,P5 ;SAVE STRUCTURE NUMBER
MOVEI T1,HOMPGA ;THE WORK PAGE
CALL MLKMA ;LOCK IT
LSH T1,PGSFT ;MAKE IT A CORE ADDRESS
MOVE P1,T1 ;SAVE IT
FSIBA1: SKIPN P4,STRTAB(P5) ;DOES STRUCTURE EXIST?
JRST GOOD22 ;NO. DON'T DO ANYTHING TO IT
MOVN T1,SDBNUM(P4) ;YES. SET UP UNIT AOBJN WORD
HRLI P4,0(T1) ;NEGATIVE COUNT
HRRI P4,SDBUDB(P4) ;THE SDBUBD INDEX
;LOOP THROUGH ALL PACKS IN A STRUCTURE
NEW1: CALL SETBAT ; SET DSKBAT BIT IN DSKSTS
CALL FNDCHN ;FIND CKU NUMBERS FOR THIS PACK
MOVE P2,T1 ;SAVE IT
MOVE T2,P1 ;PHYSICAL CORE ADDRESS
MOVEI T3,HOMPGA ;VIRTUAL ADDRESS
CALL GETBAT ;GET THE BAT BLOCKS
MOVE T2,T1 ;BITS
TLNN T2,(1B0) ;PRIMARY OK?
JRST BAD1 ;NO
TLNE T2,(1B1) ;SECONDARY OK?
JRST GOOD2
MOVE T3,P1 ;CORE ADDRESS
MOVX T1,MI%MSG ;NOTE THAT A MESSAGE IS DESIRED
MOVEI T2,HOMPGA ;GET VIRTUAL ADDRESS OF FIRST BAT BLOCK
CALL CPY1 ;COPY PRIMARY
JRST NONB ;BAD
JRST GOOD2
BAD1: TLNN T2,(1B1) ; A GOOD SECONDARY?
JRST NONB ;NO. NO BAT BLOCKS
MOVX T1,MI%MSG ;NOTE THAT A MESSAGE IS DESIRED
MOVEI T2,HOMPGA ;GET VIRTUAL ADDRESS OF FIRST BAT BLOCK
MOVE T3,P1 ;GET CORE ADDRESS
CALL CPY2 ;PUT SECONDARY INTO PRIMARY
JRST NONB ;BAD I/O
JRST GOOD2
;HERE WHEN NO GOOD BAT BLOCKS COULD BE FOUND FOR THIS UNIT
NONB: MOVEI T1,"?"
CALL FSIPBO ;ERROR PREFIX
CALL UNTSTR
HRROI T1,[ASCIZ / has no BAT blocks.
/]
CALL FSIPSO ;TELL HIM
REASK: HRROI T1,[ASCIZ /Do you want to write a set of prototype BAT blocks? /]
HRROI T2,BATASK ; THE QUESTION
HRROI T3,FSIYNO ; GET A YES OR A NO.
CALL FSIASK ; GO ASK THE QUESTION
JRST REASK ; ASK AGAIN
JUMPL T1,NEWBAT ; IF YES, GO MAKE THEM
JRST GOOD21 ; NO. SKIP IT THEN
NEWBAT: MOVE T1,P2 ; GET CKU NUMBERS
MOVEI T2,HOMPGA ; VIRTUAL ADDRESS OF NEW BAT BLOCKS
MOVE T3,P1 ; PHYSICAL CORE ADDRESS OF NEW BAT BLOCKS
MOVX T4,MI%MSG ; ISSUE A MESSAGE ON A WRITE ERROR
CALL MAKBAT ; CREATE A PAIR OF NEW BAT BLOCKS
JRST GOOD21 ; FAILED, GO ON
; ..
; ..
;THE PACK HAS TWO GOOD BAT BLOCKS HERE
GOOD2: CALL CLRBAT ; MARK STATUS WORD
GOOD21: AOBJN P4,NEW1 ;DO ALL PACKS
GOOD22: MOVEI T1,HOMPGA ;RELEASE PAGE THAT BAT BLOCKS WERE
CALL MULKMP ; READ INTO
RET ; AND DONE
;ROUTINE TO FIND THE CKU NUMBERS FOR A PACK (THE CHANNEL, CONTROLLER,
;AND UNIT NUMBERS OF THE PACK).
;ACCEPTS: P4/ SDBUDB INDEX (FOR CALL TO FNDCHN)
;OR: T3/ UDB (FOR CALL TO FNDCH1)
;RETURNS: T1/ CKU NUMBERS
;DESTROYS T2-T4
FNDCHN: HRRZ T3,0(P4) ;GET UDB
FNDCH1::SAVEP ;PROTECT SOME ACS
HRRZ P1,UDBCDB(T3) ;SET UP POINTERS
HRRZ P2,UDBKDB(T3) ;AS THEY NORMALLY ARE
MOVE P3,T3 ;FOR CALL
CALL FNDCKU ;GET THE PROPER NUMBERS
CALLRET CKUPAK ;PACK THEM INTO ONE AC AND RETURN
BATASK: ASCIZ /
[This pack does not have a valid set of BAT blocks. Answering yes will
cause the monitor to create the BAT blocks without performing a full
map function.]
/
;MAKBAT - ROUTINE TO CREATE AND WRITE OUT TWO NEW BAT BLOCKS
;
;ACCEPTS IN T1/ PHYSICAL CKU NUMBERS
; T2/ VIRTUAL ADDRESS OF WHERE NEW BAT BLOCKS ARE TO GO
; T3/ PHYSICAL MEMORY ADDRESS OF NEW BAT BLOCKS
; T4/ FLAGS:
; * P4/ SDBUDB POINTER FOR THIS UNIT
; * P5/ STRUCTURE NUMBER
; MI%MSG - ISSUE A MESSAGE ON TERMINAL ON WRITE ERROR
; CALL MAKBAT
;RETURNS: +1 FAILURE, WRITE ERROR
; +2 SUCCESS, BAT BLOCKS CREATED
;
; * P4 AND P5 NEED NOT BE SET UP IF MESSAGES ARE NOT DESIRED ON ERRORS
MAKBAT: ASUBR <MKBCKU,MKBVIR,MKBPHY,MKBFLG>
MOVE T1,MKBVIR ;GET START OF BAT BLOCK PAGE
SETZM (T1) ;CLEAR FIRST WORD OF NEW BAT BLOCK
ADDI T1,1 ;SET UP TO CLEAR THE FIRST BAT BLOCK
HRL T1,MKBVIR ;THE START
BLT T1,HBLEN-1(T2) ;CLEAR OUT ONE BLOCK
MOVSI T1,'BAT' ; THE BLOCK NAME
MOVEM T1,BATNAM(T2) ; TO THE NEW BLOCK
MOVE T1,[-MAXBFR,,BAT1P] ;FORM FREE SPACE WORD
MOVEM T1,BATFRE(T2) ; TO THE BLOCK
MOVEI T1,CODBAT ; UNLIKELY CODE
MOVEM T1,BATCOD(T2) ; TO THE BLOCK
MOVEI T1,BATBL1 ; BLOCK NUMBER
MOVEM T1,BATBLK(T2) ; TO THE BLOCK
ADDI T1,HM2BLK-HM1BLK ; NUMBER BETWEEN THEM
MOVEM T1,BATBLK+HBLEN(T2) ;THE BACKUP ADDRESS
MOVEI T1,HBLEN(T2)
HRLI T1,(T2) ; FOR THE BLT
BLT T1,2*HBLEN-2(T2) ; ALL BUT LAST WORD
MOVE T1,MKBCKU ; GET CHAN, CTRL, AND UNIT NUMBERS
MOVE T2,MKBVIR ;GET VIRTUAL CORE ADDRESS OF BLOCKS
MOVE T3,MKBPHY ;REAL CORE ADDRESS
CALL BATOUT ; WRITE IT
JRST MKB010 ; FAILED, GO ISSUE MESSAGE IF REQUESTED
RETSKP ; SUCCESS, RETURN
; HERE ON A WRITE ERROR
MKB010: MOVE T1,MKBFLG ;GET THE FLAGS
TXNN T1,MI%MSG ;A MESSAGE DESIRED ?
RET ;NO, JUST GIVE FAIL RETURN
HRROI T1,[ASCIZ /? Failed to write BAT blocks for /]
CALL FSIPSO ;TELL HIM
CALL UNTSTR
HRROI T1,[ASCIZ /
/]
CALLRET FSIPSO ;CLEAN UP THE MESSAGE
;CHKSWP - ROUTINE TO VALIDATE THE # OF PAGES FOR SWAPPING ON A STRUCTURE
;
;ACCEPTS IN T1/ UDB OF A DISK UNIT OF THE STRUCTURE
; T2/ # OF UNITS IN STRUCTURE
; T3/ # OF PAGES FOR SWAPPING ON STR
; CALL CHKSWP
;RETURNS: +1 FAILED, # OF PAGES SPECIFIED IS INVALID
; +2 SUCCESS, VALID # OF PAGES SPECIFIED
CHKSWP::JUMPE T3,RSKP ;RETURN SUCCESS IF NOTHING TO ALLOCATE
EXCH T1,T3 ;SWITCH ARGUMENTS
MOVX T4,US.DSK ;GET FLAG READY
SKIPLE T1 ;POSITIVE NUMBER OF PAGES FOR SWAPPING?
TDNN T4,UDBSTS(T3) ;AND THIS IS A DISK?
RETBAD (MSTX25) ;NO, ERROR
MOVE T3,UDBSIZ(T3) ;GET DISK SIZE POINTER
CALL CMPSWP ;COMPUTE # OF PAGES FOR SWAPPING ON THIS UNIT
MOVE T2,CYLUNT(T3) ;GET # OF CYLINDERS ON THIS UNIT
IMUL T2,PAGCYL(T3) ;COMPUTE # OF PAGES ON THIS UNIT
CAMG T2,T1 ;MORE PAGES THAN REQUESTED FOR SWAPPING ?
RETBAD (MSTX25) ;NO, FAIL
RETSKP ;YES, RETURN SUCCESS
;CMPSWP - ROUTINE TO COMPUTE # OF PAGES FOR SWAPPING ON A UNIT
;
;ACCEPTS IN T1/ DESIRED # OF PAGES FOR SWAPPING ON STRUCTURE
; T2/ NUMBER OF UNITS IN STRUCTURE
; T3/ ADDRESS OF DISK SIZE TABLE FOR THIS STRUCTURE
; CALL CMPSWP
;RETURNS: +1 ALWAYS, T1/ # OF PAGES FOR SWAPPING ON THIS UNIT
;PRESERVES T3
CMPSWP: SOS T1 ;ONE LESS
HRRZ T2,STHUNI ;GET NUMBER OF UNITS IN STRUCTURE
ADD T1,T2 ;T1 = NDST+NPACKS-1 (TO AVOID ROUND OFF)
IDIV T1,T2 ;GET # OF PAGES PER UNIT
ADD T1,PAGCYL(T3) ;ROUND TO EVEN NUMBER OF CYLINDERS
SUBI T1,1
IDIV T1,PAGCYL(T3)
IMUL T1,PAGCYL(T3)
RET ;RETURN
;ROUTINE TO COPY ONE STRING TO ANOTHER
;ACCEPTS IN T1/ POINTER TO DESTINATION STRING
; T2/ POINTER TO SOURCE STRING
; CALL FSICPY
;RETURNS +1: ALWAYS, UPDATED STRING POINTER IN T1 AND NULL AFTER END
FSICPY: ILDB T3,T2 ;GET NEXT CHARACTER
JUMPE T3,FSICP1 ;NULL MEANS AT END
IDPB T3,T1 ;STORE CHARACTER
JRST FSICPY ;LOOP BACK
FSICP1: MOVE T4,T1 ;NOW APPEND NULL
IDPB T3,T4 ;WITHOUT CHANGING BYTE POINTER IN T1
RET ;ALL DONE
;ROUTINE TO TYPE OUT A OCTAL NUMBER
;ACCEPTS IN T1/ NUMBER
; CALL FSIOTY
;RETURNS +1: ALWAYS
FSIDTY: SKIPA T3,[12] ;SET RADIX TO ^D10
FSIOTY: MOVEI T3,10 ;SET RADIX TO 8
STKVAR <<FSINBK,3>>
MOVE T2,T1 ;SET UP FOR CALL TO FSINST
MOVSI T1,(POINT 7,0) ;SET UP BYTE POINTER
HRRI T1,FSINBK
CALL FSINST
MOVEI T2,0 ;ADD NULL TO END OF STRING
IDPB T2,T1 ;...
HRROI T1,FSINBK
CALLRET FSIPSO ;TYPE NUMBER
;ROUTINE TO CONVERT A NUMBER TO AN ASCIZ STRING
;ACCEPTS: T1/ STRING POINTER TO STORAGE
; T2/ NUMBER TO TYPE
; T3/ RADIX
; CALL FSINST
;RETURNS +1: ALWAYS, UPDATED STRING POINTER IN T1
FSINST: MOVE T4,T3 ;SAVE RADIX
JUMPGE T2,FSINS1 ;SKIP ON IF NUMBER IS POSITIVE
MOVEI T3,"-" ;IT'S NEGATIVE, GET MINUS SIGN
IDPB T3,T1 ;STORE IN THE STRING
MOVM T2,T2 ;AND MAKE NUMBER POSITIVE
FSINS1: IDIVI T2,0(T4) ;GET LOW ORDER DIGIT
PUSH P,T3 ;SAVE IT
SKIPE T2 ;ALL DONE?
CALL FSINS1 ;NO, GO GET NEXT LOW ORDER DIGIT
POP P,T2 ;GET HIGH ORDER DIGIT
ADDI T2,"0" ;MAKE IT ASCII
IDPB T2,T1 ;PUT IT IN THE STRING
RET ;GO GET OTHER DIGITS IF ANY
;ROUTINE TO ASK A QUESTION AND GET AN ANSWER
; THIS ROUTINE HANDLES "?" AND RUBOUT
;ACCEPTS IN T1/ POINTER TO QUESTION STRING
; T2/ POINTER TO HELP STRING OR THE ADR OF THE HELP ROUTINE
; T3/ ADDRESS OF ROUTINE TO READ IN ANSWER
; CALL FSIASK
;RETURNS +1: ERROR
; +2: SUCCESSFUL, ANSWER IN T1
FSIASK: STKVAR <FSIASP,FSIASH,FSIASR>
MOVEM T1,FSIASP ;SAVE POINTER TO QUESTION
MOVEM T2,FSIASH ;SAVE POINTER TO HELP MESSAGE
HRRZM T3,FSIASR ;SAVE ADDRESS OF ROUTINE TO BE CALLED
FSIAS1: MOVE T1,FSIASP ;GET POINTER TO QUESTION STRING
CALL FSIPSO ;ASK THE QUESTION
MOVE T3,FSIASR ;GET ADDRESS OF ROUTINE FOR ANSWER
CALL (T3) ;GET THE ANSWER
JRST [ JUMPE T1,FSIAS2 ;"?" TYPED
JRST FSIAS1] ;CONTROL-R TYPED
RETSKP ;RETURN WITH ANSWER IN T1
FSIAS2: MOVE T1,FSIASH ;GET POINTER TO HELP MESSAGE
TLNN T1,-1 ;IS THIS A HELP ROUTINE
JRST [ CALL 0(T1) ;YES, GO CALL IT
JRST FSIAS1] ;AND GO REASK THE QUESTION
CALL FSIPSO ;TYPE OUT HELP MESSAGE
JRST FSIAS1 ;GO ASK QUESTION AGAIN
;ROUTINE TO GET A YES OR NO ANSWER
; CALL FSIYNO
;RETURNS +1: T1=0 MEANS "?" TYPED, T1=1 MEANS CONT-R TYPED
; +2: T1=-1 MEANS YES, T1=0 MEANS NO
FSIYNO: CALL FSIPBI ;GET A CHARACTER FROM TTY
MOVE T2,T1 ;SAVE FIRST CHARACTER
FSIYN1: CAIN T1,"?" ;IS THIS A HELP REQUEST
JRST RFALSE ;YES, RETURN WITH T1=0
CAIN T1,"R"-100 ;CONTROL-R?
JRST [ MOVEI T1,1 ;YES, RETURN WITH T1=1
RET]
CAIE T1,"U"-100 ;CONTROL-U?
CAIN T1,.CHDEL ;OR RUBOUT?
JRST [ CALL FSIRUB ;YES, SIMULATE RUBOUT ACTION
JRST FSIYNO] ;START OVER AGAIN
CAIN T1,.CHLFD ;END OF LINE?
JRST FSIYN2 ;YES, CHECK ANSWER
CALL FSIPBI ;GET ANOTHER CHARACTER
JRST FSIYN1 ;GO CHECK IT OUT
FSIYN2: CAIN T2,"Y" ;FIRST CHAR A Y?
JRST FSIYN3 ;YES, GO RETURN TRUE
CAIN T2,"N" ;NO?
JRST FSIYN4 ;YES, GO RETURN FALSE
HRROI T1,[ASCIZ/? Answer "Y" or "N" /]
CALL FSIPSO ;TYPE OUT HELP
JRST FSIYNO ;GO GET ANSWER AGAIN
FSIYN4: TDZA T1,T1 ;NO, RETURN T1=0
FSIYN3: SETO T1, ;YES, RETURN T1=-1
RETSKP
;ROUTINE TO READ IN A SIXBIT NAME
; CALL FSISIX
;RETURNS +1: T1=0 MEANS "?" TYPED, T1=1 MEANS CONTROL-R TYPED
; +2: SIXBIT NAME IN T1
FSIDEV: TDZA T4,T4 ;ALLOW ":" AS A TERMINATOR
FSISIX: SETO T4, ;COLON IS NOT ALLOWED
FSISI4: MOVE T2,[POINT 6,T3] ;SET UP STRING POINTER TO ANSWER
SETZ T3, ;INITIALIZE ANSWER AC
FSISI1: CALL FSIPBI ;GET A CHARACTER
CAIN T1,"?"
JRST RFALSE ;QUESTION MARK WAS TYPED
CAIN T1,"R"-100 ;CONTROL-R?
JRST [ MOVEI T1,1 ;YES, RETURN WITH T1=1
RET]
CAIE T1,"U"-100 ;CONTROL-U?
CAIN T1,.CHDEL ;OR RUBOUT?
JRST [ CALL FSIRUB ;YES. GO TYPE 'XXX'
JRST FSISI4] ;START OVER. T4 IS STILL SET UP
CAIN T1,.CHLFD ;END OF LINE?
JRST [ MOVE T1,T3 ;YES, GET ANSWER
RETSKP] ;RETURN WITH ANSWER IN T1
JUMPN T4,FSISI2 ;ALLOWING A COLON?
CAIN T1,":" ;YES, IS IT A COLON
TLZ T2,7700 ;YES, IGNORE ANY OTHER STUFF AFTER IT
FSISI2: CAIL T1,140 ;LOWER CASE?
SUBI T1,40 ;YES, UPPERCASE IT BEFORE THE SIXBIT CONVERSION
SUBI T1,40 ;CONVERT TO SIXBIT
TRNE T1,777700 ;LEGAL SIXBIT CHARACTER?
JRST FSISI3 ;NO, GO COMPLAIN
IDPB T1,T2 ;STORE CHARACTER IN ANSWER
TLNN T2,770000 ;AT END OF 6 CHAR WORD?
TLZ T2,7700 ;YES, SET SIZE FIELD TO 0 FOR REMAINDER
JRST FSISI1 ;LOOP BACK FOR OTHER CHARACTERS
FSISI3: HRROI T1,[ASCIZ/? Illegal character, retype answer again: /]
CALL FSIPSO ;TYPE OUT COMPLAINT
JRST FSISI4 ;START OVER. T4 IS STILL SET UP
;ROUTINE TO TYPE OUT A SIXBIT NAME
;ACCEPTS IN T1/ SIXBIT NAME
; CALL FSI6TY
;RETURNS +1: ALWAYS
FSI6TY: MOVE T2,T1 ;SAVE SIXBIT NAME
MOVE T3,[POINT 6,T2] ;SET UP BYTE POINTER
FSI6T1: ILDB T1,T3 ;GET NEXT CHARACTER
JUMPE T1,R ;IF ZERO, EXIT
ADDI T1,40 ;MAKE IT ASCII
CALL FSIPBO ;TYPE OUT CHARACTER
TLNE T3,770000 ;LAST CHARACTER?
JRST FSI6T1 ;NO, GO TYPE OUT NEXT CHAR
RET ;YES, EXIT
;ROUTINES TO GET A SIGNED OCTAL OR DECIMAL NUMBER
; CALL FSIOCT OR CALL FSIDEC
;RETURNS +1: T1=0 MEANS "?" TYPED, T1=1 MEANS CONTROL-R TYPED
; +2: NUMBER IN T1
FSIOCT: SKIPA T1,[^D8] ;GET OCTAL RADIX
FSIDEC: MOVEI T1,^D10 ;OR DECIMAL RADIX
STKVAR <FSIOCN,FSIOCR,FSIOCC,FSIOCS> ;ALLOCATE VARIABLES
MOVEM T1,FSIOCR ;REMEMBER RADIX
FSIOC0: SETZM FSIOCN ;INITIALIZE THE ANSWER
SETZM FSIOCC ;INITIALIZE COUNT OF DIGITS SEEN
SETZM FSIOCS ;INITIALIZE SIGN OF NUMBER TO BE POSITIVE
FSIOC1: CALL FSIPBI ;GET A CHARACTER
CAIN T1,"?" ;QUESTION MARK?
JRST RFALSE ;YES, RETURN WITH T1=0
CAIN T1,"R"-100 ;CONTROL-R?
JRST [ MOVEI T1,1 ;YES, RETURN WITH T1=1
RET]
CAIE T1,"U"-100 ;CONTROL-U?
CAIN T1,.CHDEL ;OR RUBOUT?
JRST [ CALL FSIRUB ;YES, TYPE OUT RUBOUT STRING
JRST FSIOC0] ;AND START OVER AGAIN
CAIE T1," " ;ALLOW SPACE OR COMMA
CAIN T1,"," ; TO DELIMIT A NUMBER
SKIPA
CAIN T1,.CHLFD ;END OF LINE?
JRST [ SKIPG FSIOCC ;ANY DIGITS TYPED
JRST FSIOC2 ;NO, NULL INPUT ISN'T LEGAL
MOVE T1,FSIOCN ;GET NUMBER TYPED
SKIPE FSIOCS ;MINUS SIGN USED?
MOVNS T1 ;YES, NEGATE THE NUMBER
RETSKP] ;AND RETURN
CAIN T1,"-" ;MINUS SIGN?
JRST [ SKIPN FSIOCS ;ALREADY TYPED A MINUS SIGN?
SKIPE FSIOCC ;OR ALREADY TYPED DIGITS?
JRST FSIOCE ;YES, BAD NUMBER
SETOM FSIOCS ;REMEMBER TO NEGATE ANSWER
JRST FSIOC1] ;AND CONTINUE
SUBI T1,"0" ;SHOULD BE A DIGIT NOW, CONVERT FROM ASCIZ
SKIPL T1 ;TOO SMALL TO BE A DIGIT?
CAML T1,FSIOCR ;OR TOO LARGE TO BE A DIGIT?
JRST FSIOCE ;YES, COMPLAIN
MOVE T2,FSIOCR ;GET RADIX
IMULM T2,FSIOCN ;MULTIPLY PREVIOUS RESULT BY RADIX
ADDM T1,FSIOCN ;ADD IN NEW DIGIT
AOS FSIOCC ;COUNT UP DIGITS SEEN
JRST FSIOC1 ;AND LOOP BACK FOR MORE
FSIOC2: HRROI T1,[ASCIZ/? Null answer not allowed, retype answer: /]
CALL FSIPSO ;TYPE OUT MESSAGE
JRST FSIOC0 ;AND TRY AGAIN
FSIOCE: HRROI T1,[ASCIZ/
? Illegal number, retype answer: /]
CALL FSIPSO ;TYPE OUT COMPLAINT
JRST FSIOC0 ;TRY AGAIN
;ROUTINE TO TYPE OUT RUBOUT STRING
; CALL FSIRUB
;RETURNS +1: ALWAYS
FSIRUB: HRROI T1,[ASCIZ/ XXX
/]
CALL FSIPSO ;TYPE OUT STRING
RET ;AND RETURN
;ROUTINE TO TYPE OUT A STRING
;ACCEPTS IN T1/ STRING POINTER
; CALL FSIPSO
;RETURNS +1: ALWAYS
; CLOBERS T1 ONLY
FSIPSO: STKVAR <FSIPSP>
TLC T1,-1 ;SEE IF -1,,ADR
TLCN T1,-1 ;...
HRLI T1,(POINT 7,0) ;YES, SET UP BYTE POINTER
MOVEM T1,FSIPSP ;SAVE STRING POINTER
FSIPS1: ILDB T1,FSIPSP ;GET NEXT CHARACTER
JUMPE T1,R ;RETURN ON NULL
CALL FSIPBO ;OUTPUT THIS CHARACTER
JRST FSIPS1 ;LOOP TIL THRU
;ROUTINE TO READ IN A CHARACTER
; CALL FSIPBI
;RETURNS +1: ALWAYS, UPPERCASE CHARACTER IN T1
; SAVES ALL ACS
;NOTE: THIS ROUTINE LOCKS THE TELETYPE DATA EVEN THOUGH IT IS THE
;ONLY PROCESS RUNNING BECAUSE TCI CALLS ULKTTY IF IT GOES INTO INPUT
;WAIT.
FSIPBI: PUSH P,T2 ;SAVE ALL ACS
PUSH P,T3
PUSH P,T4
FSIPB1: MOVE T2,CTYLNO ;GET CTY LINE NUMBER
CALL LCKTTY ;POINT TO DYNAMIC DATA
BUG(TTNAC4)
CALL TCI ;INPUT A CHAR
JRST FSIPB1 ;NEEDED TO BLOCK. GO TRY AGAIN
CALL ULKTTY ;FREE THE TTY
CAIN T1,.CHCRT ;FLUSH CR
JRST FSIPB1
POP P,T4
POP P,T3
POP P,T2
RET
;ROUTINE TO OUTPUT A CHARACTER
;ACCEPTS IN T1/ CHARACTER
; CALL FSIPBO
;RETURN +1: ALWAYS, ALL ACS PRESERVED
FSIPBO: SAVET
MOVE T2,CTYLNO ;GET CTY LINE NUMBER
CALL LCKTTY ;POINT TO DYNAMIC DATA
BUG(TTNAC3)
CALL TCO
CALL ULKTTY ;FREE THE TTY
RET
;FSIPSW - ROUTINE TO PRINT HELP TEXT FOR SWAPPING SPACE DEFAULT
;USES THE DEFAULT NUMBER OF PAGES FOR THE RUNNING MONITOR AND ROUNDS
;IT UP TO AN INTEGRAL NUMBER OF CYLINDERS. ASSUMES THAT ALL KNOWN
;DISK TYPES HAVE THE SAME NUMBER OF PAGES PER CYLINDER AS AN RP04
FSIPSW: HRROI T1,[ASCIZ/
[The default is /]
CALL FSIPSO
MOVEI T3,DSKSZ0 ;ASSUME RP04 SIZE CHARACTERISTICS
MOVE T1,NSWPGS ;GET DEFAULT NUMBER OF PAGES
IDIV T1,PAGCYL(T3) ;CONVERT TO CYLINDERS
SKIPE T2 ;WAS THERE A REMAINDER?
AOS T1 ;YES. INCREMENT CYLINDER COUNT
IMUL T1,PAGCYL(T3) ;CONVERT BACK TO PAGES
CALL FSIDTY ;PRINT THE NUMBER
HRROI T1,[ASCIZ/ pages]
/]
CALL FSIPSO
RET
TNXEND
END