Google
 

Trailing-Edge - PDP-10 Archives - BB-M080O-SM - monitor-sources/dskalc.mac
There are 55 other files named dskalc.mac in the archive. Click here to see a list.
; *** Edit 7357 to DSKALC.MAC by RASPUZZI on 22-Aug-86
; Remove routine GAPRID since the processor serial number is already in APRSER
; and make all CALLs to GAPRID refer to that resident location. 
; *** Edit 7352 to DSKALC.MAC by JROSSELL on 11-Aug-86, for SPR #21161
; Have .DSKOP return an error if an error occurs during a transfer 
; *** Edit 7337 to DSKALC.MAC by LOMARTIRE on 23-Jul-86, for SPR #21239
; Prevent MDDJFN BUGHLTs 
; *** Edit 7289 to DSKALC.MAC by MCCOLLUM on 24-Apr-86, for SPR #19581
; Fix code around CHKHOM/CKHOMU to find PS: correctly when bad structures exist
; 
; *** Edit 7288 to DSKALC.MAC by MCCOLLUM on 23-Apr-86
; Remove edit 7228. We have decided not to implement it. 
; *** Edit 7272 to DSKALC.MAC by WAGNER on 19-Mar-86, for SPR #21002
; *** PERFORMANCE *** Modify DSKASN so that adding pages to existing files will
; tend to stay contigous and so that new files will not compete with existing
; files for contiguous cylinders when structures and cylinders get full. 
;------------------------- Autopatch Tape # 13 -------------------------
;------------------------- Autopatch Tape # 12 -------------------------
; Edit 7172 to DSKALC.MAC by MCCOLLUM on 25-Oct-85, for SPR #20513
; Set FB%NDL for non-directory files on <ROOT-DIRECTORY> 
; Edit 7145 to DSKALC.MAC by WAGNER on 10-Sep-85, for SPR #19975 (TCO 6-1-1517)
; Modify documentation for ASAASG BUGCHKs to mention that redundant BAT block
; entries can also cause these BUGCHKs. 
;TCO 6.1.1517 - Mention that ASAASGs can occur with redundant BAT block entries
; Edit 7120 to DSKALC.MAC by WAGNER on 9-Aug-85 (TCO 6-1-1508)
; Dont assign bittable entries for addresses in the maintenance cylinders 
;TCO 6.1.1508 - Dont call DSKASA if address is in Maintainance area
; UPD ID= 2067, SNARK:<6.1.MONITOR>DSKALC.MAC.63,   3-Jun-85 14:31:50 by MCCOLLUM
;TCO 6.1.1406  - Update copyright notice.
; UPD ID= 2015, SNARK:<6.1.MONITOR>DSKALC.MAC.62,  28-May-85 12:03:23 by MCCOLLUM
;TCO 6.1.1238 - Fix BUG. documentation
; UPD ID= 1961, SNARK:<6.1.MONITOR>DSKALC.MAC.61,  13-May-85 09:16:09 by LOMARTIRE
;TCO 6.1.1373 - Record new MID in the UDB and SDB when homeblocks are changed
; UPD ID= 1911, SNARK:<6.1.MONITOR>DSKALC.MAC.60,   6-May-85 16:54:54 by TBOYLE
;TCO 6.1.1360 - BATS - Fix DOPAIR at DOPA1,CMNPAR,ADDPR to count by SECPAG.
; UPD ID= 1895, SNARK:<6.1.MONITOR>DSKALC.MAC.59,   4-May-85 15:45:09 by MCCOLLUM
;TCO 6.1.1238 - Fix more BUG. documentation
; UPD ID= 1875, SNARK:<6.1.MONITOR>DSKALC.MAC.58,   4-May-85 11:45:19 by MCCOLLUM
;TCO 6.1.1238 - Fix more BUG. documentation
; UPD ID= 1849, SNARK:<6.1.MONITOR>DSKALC.MAC.57,  30-Apr-85 13:29:57 by MCCOLLUM
;TCO 6.1.1238 - Fix more BUG. documentation
; UPD ID= 1753, SNARK:<6.1.MONITOR>DSKALC.MAC.56,  14-Apr-85 15:45:28 by LEACHE
;TCO 6.1.1321 define BOOT parameter word (HOMBTF) for home blocks
; UPD ID= 1727, SNARK:<6.1.MONITOR>DSKALC.MAC.55,   8-Apr-85 13:42:02 by MCCOLLUM
;TCO 6.1.1238 - Fix BUG. documentation
; UPD ID= 1589, SNARK:<6.1.MONITOR>DSKALC.MAC.54,   5-Mar-85 14:26:31 by HAUDEL
;TCO 6.1.1208 - Create a DSKBTTBL if one does not exist
; UPD ID= 1467, SNARK:<6.1.MONITOR>DSKALC.MAC.53,   3-Feb-85 16:33:32 by PAETZOLD
;6.1.1172 - Change OFNPTT to OFPTT to avoid conflict with new symbol in PROLOG.
; UPD ID= 1233, SNARK:<6.1.MONITOR>DSKALC.MAC.52,  20-Dec-84 13:46:34 by TBOYLE
;Change PDV... to PDB...
; UPD ID= 4931, SNARK:<6.MONITOR>DSKALC.MAC.51,  15-Oct-84 13:01:20 by GRANT
;The assembly switch CFSCOD has been eliminated
; UPD ID= 4806, SNARK:<6.MONITOR>DSKALC.MAC.50,  17-Sep-84 09:54:53 by PURRETTA
;Update copyright notice
; UPD ID= 4755, SNARK:<6.MONITOR>DSKALC.MAC.49,  27-Aug-84 08:27:38 by GRANT
;TCO 6.2200 - In FSIDI2, ask for channel, controller, unit in decimal and
;in FSICFG, display channel, controller, unit in decimal.
; UPD ID= 4723, SNARK:<6.MONITOR>DSKALC.MAC.48,  21-Aug-84 13:16:26 by TBOYLE
;TCO 6.2186 (QAR 706210) HRRZS A BEFORE CALLS TO CFFBBS, CFGBBS.
; UPD ID= 4400, SNARK:<6.MONITOR>DSKALC.MAC.47,  27-Jun-84 22:31:11 by MCLEAN
;CHANGES TO ADD PDB
; UPD ID= 4371, SNARK:<6.MONITOR>DSKALC.MAC.46,  22-Jun-84 10:01:41 by MCLEAN
;FIX BATQ WHEN LKBAT FAILS THE JRST TO BATQE IS WRONG
; UPD ID= 4262, SNARK:<6.MONITOR>DSKALC.MAC.45,  30-May-84 17:13:11 by MCLEAN
;FIX DECRSV ERROR FOR DOP%PS
; UPD ID= 4249, SNARK:<6.MONITOR>DSKALC.MAC.44,  29-May-84 22:12:23 by MCLEAN
;ADD SUPPORT FOR DOP%PS
; UPD ID= 4154, SNARK:<6.MONITOR>DSKALC.MAC.43,  30-Apr-84 16:39:21 by LOMARTIRE
;TCO 6.2028 - Prevent CHKRNR or DDMPNR by being NOSKED when getting BAT lock
; UPD ID= 3239, SNARK:<6.MONITOR>DSKALC.MAC.42,  30-Nov-83 21:25:37 by MCLEAN
;TCO 6.1888 MASK UNIT NUMBER FOR BAT BLOCKS TO 3 BITS
;THIS IS A FIX FOR RP20'S AND HSC'S.
; UPD ID= 2784, SNARK:<6.MONITOR>DSKALC.MAC.41,   2-Aug-83 15:40:05 by WEETON
;TCO 6.1612 - Add DA%AIN function to DSKAS JSYS
; UPD ID= 2049, SNARK:<6.MONITOR>DSKALC.MAC.40,  21-Mar-83 14:46:09 by MILLER
;TCO 6.1094. In DSKASN, do MAPBTF before looking at SDBFRC
; In GSTRPG, Call OFNTKN beofre looking at SDBFRC
; UPD ID= 2030, SNARK:<6.MONITOR>DSKALC.MAC.39,  20-Mar-83 10:17:04 by MILLER
;TCO 6.1094. Add GETFRC and STOFRC
; UPD ID= 2026, SNARK:<6.MONITOR>DSKALC.MAC.38,  19-Mar-83 08:11:12 by MILLER
;TCO 6.1094. CALL CFSSBB when a bit table is set up
; UPD ID= 1952, SNARK:<6.MONITOR>DSKALC.MAC.37,   9-Mar-83 15:52:24 by MILLER
;TCO 6.1520. Fix entry code for DEDSK and DEDSKM
; UPD ID= 1894, SNARK:<6.MONITOR>DSKALC.MAC.36,   1-Mar-83 15:09:16 by HALL
;TCO 6.1502 - Allow free space outside of section 0
;	At least temporarily, make all callers request section 0
; UPD ID= 1872, SNARK:<6.MONITOR>DSKALC.MAC.35,  23-Feb-83 16:48:26 by MILLER
;TCO 6.1094. MNTPS changes
; UPD ID= 1862, SNARK:<6.MONITOR>DSKALC.MAC.34,  23-Feb-83 13:18:35 by MILLER
;tco 6.1520. preallocate disk pages
; UPD ID= 1754, SNARK:<6.MONITOR>DSKALC.MAC.33,   3-Feb-83 13:50:38 by GRANT
;TCO 6.1493 - use UNITS pool rather than GENERAL pool for resident free space
; UPD ID= 1593, SNARK:<6.MONITOR>DSKALC.MAC.32,  29-Dec-82 10:32:34 by DONAHUE
;TCO 6.1172 - Set exempt from migration bit for BITTABLE and FRONT-END-FILE-SYSTEM
; UPD ID= 1551, SNARK:<6.MONITOR>DSKALC.MAC.31,  21-Dec-82 10:57:32 by MAYO
; UPD ID= 1455, SNARK:<6.MONITOR>DSKALC.MAC.30,  17-Nov-82 15:03:59 by MCINTEE
;More TCO - 6.1010 change a CALL @T4 to a CALL (T4) in CKHOMU to stay local
; UPD ID= 1394, SNARK:<6.MONITOR>DSKALC.MAC.29,   1-Nov-82 10:39:47 by MILLER
;TCO 6.1094. Don't do CFS stuff if bit table is not a file
; UPD ID= 1385, SNARK:<6.MONITOR>DSKALC.MAC.28,  27-Oct-82 11:59:11 by DONAHUE
;TCO 6.1314 - Change the disk allocation algorithm to be more fair on multi-pack structures
; UPD ID= 1364, SNARK:<6.MONITOR>DSKALC.MAC.27,  21-Oct-82 16:59:42 by MILLER
;merge latest CFS changes (TCO 6.1094)
; UPD ID= 1344, SNARK:<6.MONITOR>DSKALC.MAC.26,  16-Oct-82 18:56:38 by MILLER
;TCO 6.1094 again
; UPD ID= 1334, SNARK:<6.MONITOR>DSKALC.MAC.25,  13-Oct-82 17:18:20 by MILLER
;More changes to UPDBTB for CFS
; UPD ID= 1309, SNARK:<6.MONITOR>DSKALC.MAC.24,   8-Oct-82 16:41:39 by MILLER
; UPD ID= 1286, SNARK:<6.MONITOR>DSKALC.MAC.23,   6-Oct-82 13:36:15 by MILLER
; UPD ID= 1257, SNARK:<6.MONITOR>DSKALC.MAC.22,  28-Sep-82 20:50:24 by MILLER
;Put delay in FSIINI to allow CFS connections to be established.
; UPD ID= 1235, SNARK:<6.MONITOR>DSKALC.MAC.21,  24-Sep-82 12:23:20 by LEACHE
;More of previous - search MONSYM
; UPD ID= 1233, SNARK:<6.MONITOR>DSKALC.MAC.20,  24-Sep-82 12:16:23 by LEACHE
;TCO 6.1273 Add MS%ASG and MS%MXB
; UPD ID= 1227, SNARK:<6.MONITOR>DSKALC.MAC.19,  23-Sep-82 23:47:56 by MILLER
;CFS stuff. Don't do UPDBTB if bit table resource not held locally
; UPD ID= 1191, SNARK:<6.MONITOR>DSKALC.MAC.18,  16-Sep-82 18:53:54 by CDUNN
;More TCO 6.1094 - Fix the CFS related BUG. for FSICFS
; UPD ID= 1172, SNARK:<6.MONITOR>DSKALC.MAC.17,  13-Sep-82 20:07:07 by MILLER
;TCO 6.1094. Add call to CFSSMT in FSIINI
; UPD ID= 1148, SNARK:<6.MONITOR>DSKALC.MAC.16,   7-Sep-82 10:38:27 by MILLER
;TCO 6.1255. Handle DBUGSW .GT. 2
; UPD ID= 1126, SNARK:<6.MONITOR>DSKALC.MAC.15,  31-Aug-82 22:31:53 by MILLER
;More TCO 6.1094. Fix UMPBTB
; UPD ID= 1101, SNARK:<6.MONITOR>DSKALC.MAC.14,  19-Aug-82 19:09:42 by LEACHE
;TCO 6.1233 Allow monitor to set DOP%EO only on multi-page transfers
; UPD ID= 1012, SNARK:<6.MONITOR>DSKALC.MAC.13,  28-Jul-82 21:34:15 by CDUNN
;TCO 6.1196 Allow use of DOP%EO flag in DSKOP. Add it to mask of allowed flags.
; UPD ID= 945, SNARK:<6.MONITOR>DSKALC.MAC.12,  17-Jun-82 11:48:52 by MILLER
;TCO 6.1094. Add CFS support
; UPD ID= 839, SNARK:<6.MONITOR>DSKALC.MAC.11,   4-Jun-82 22:02:34 by MURPHY
;TCO 6.1147 - Move bugdefs from BUGS.MAC to here and put them in-line.
; UPD ID= 135, SNARK:<6.MONITOR>DSKALC.MAC.10,  19-Oct-81 15:46:23 by COBB
;TCO 6.1029 - CHANGE SE1CAL TO EA.ENT
; UPD ID= 121, SNARK:<6.MONITOR>DSKALC.MAC.9,  17-Oct-81 17:13:05 by PAETZOLD
;TCO 6.1031 - Insert NOP after MSETPT call in WRTBTB
; UPD ID= 51, SNARK:<6.MONITOR>DSKALC.MAC.8,  12-Aug-81 13:39:00 by PAETZOLD
;TCO 5.1446 - FIX HOME BLOCK COPYING
; UPD ID= 36, SNARK:<6.MONITOR>DSKALC.MAC.7,  20-Jul-81 13:56:54 by MURPHY
;Fix args for SWPASF
; UPD ID= 12, SNARK:<6.MONITOR>DSKALC.MAC.6,  10-Jul-81 12:15:08 by MURPHY
;TCO 5.1398 - RETURN ERROR CODES ON DSKASN FAILURES
; UPD ID= 1842, SNARK:<6.MONITOR>DSKALC.MAC.5,  21-Apr-81 06:19:35 by WACHS
;TCO 5.1288 insert UDBVID in every unit of a structure
; UPD ID= 1630, SNARK:<6.MONITOR>DSKALC.MAC.4,   2-Mar-81 16:21:34 by HALL
;TCO 5.1264 - Don't let FSIASK go to section 0
; UPD ID= 1595, SNARK:<6.MONITOR>DSKALC.MAC.3,  27-Feb-81 07:21:01 by WACHS
;TCO 6.1002 - Add code for dual-ported disks
; UPD ID= 1594, SNARK:<6.MONITOR>DSKALC.MAC.2,  27-Feb-81 04:09:08 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 bloc;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  BE  USED
;OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT  (C)  DIGITAL  EQUIPMENT  CORPORATION  1976, 1985.
;ALL RIGHTS RESERVED.


	SEARCH MONSYM,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

.DPREA==3			;Default number of pages to preallocate
;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

DSKAWM::MOVSI T4,.DPREA		;preallocate pages
	JN SF%DPR,FACTSW,DSKASX	;If doing so proceed, else, do other case
DSKASW::TDZA T4,T4		;REMEMBER ENTRY, no preallocation
DSKASN::MOVEI T4,1
DSKASX:	SAVEQ
	EA.ENT			;FORCE SECTION 1
;**;[7272] CHANGE 1 LINE AT DSKASX:+2.L	DSW	3/19/86
	STKVAR <STRN00,MINFRE,DSKAZZ,DSKACT,DSKEXT,DSKMUF>	;[7272]
	HLRZM T4,DSKMUF		;Store count of pages to preallocate
	HRRZM T4,DSKAZZ		;Store CFS flag
	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,MS%ASG		;IF ASSIGNMENTS ARE PROHIBITED BECAUSE BIT
	TDNE T4,SDBSTS(Q2)	; TABLE IS BAD OR DOESN'T EXIST,
	RETBAD IOX35		;TAKE THE FAILURE RETURN
	MOVE Q1,SDBTYP(Q2)	;GET ADDRESS OF DSKSIZ TABLE
	MOVE 1,2		;1/STRUCTURE NUMBER
;   IFN CFSCOD,<
	SKIPE DSKAZZ
	IFSKP.
	   CALL MAPBTF		;FAIL IF NEED TO RESCHED
	   IFNSK.
		SETZM T1	;SAY WE DID A RESCHED
		RETSKP
	   ENDIF.
	ELSE.
	   CALL MAPBTB		;MAP INDEX BLOCK INTO BTBBAS, LOCK INTO CORE,
				; LOCK BTBLCK, GO NOSKED
	ENDIF.
;   >	;IFN CFSCOD
   REPEAT 0,<			;CFSCOD NO LONGER USED
   IFE CFSCOD,<CALL MAPBTB>
   >				;END REPEAT 0
	MOVE T1,STRN00		;Recover structure number
	CAIE T1,PSNUM		;IS THIS PS?
	IFSKP.
	 MOVX T2,SC%WHL!SC%OPR	;Check if privileged
	 TDNE T2,CAPENB		;Is it?
	ANSKP.
	  MOVE T2,SDBFRC(Q2)	;Get current free count
	  CAMLE T2,SYSSPC	;ABOVE MIN FREE?
	ANSKP.			;If not
	  CALL UMPBTB		;Release Bit table
	  RETBAD IOX34		;NO, ERROR DISK FULL
	ENDIF.
	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, INTERLEAVE TRACKS ON ALL UNITS

	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?
;**;[7272] DELETE 1 LINE AND CHANGE COMMENT AT DSKA9:-2.L	DSW	3/19/86
	JRST DSKSQ		;[7272] NO, FIND ONE NEARBY
	; ..
;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
	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.(CHK,DSKBT1,DSKALC,HARD,<DSK bit table fouled, cannot find free page on track with non-0 count>,<<T2,STRCOD>,<T3,CYLNDR>>,<

Cause:	The bit table for this disk cylinder indicated there
	were free pages for assignment.  However, none could be
	found.

Data:	STRCOD - Structure Unique Code
	CYLNDR - Cylinder Number
>)
	MOVX T3,MS%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
;	T4/ADDRESS OF TRACK COUNT WORD IN BT
;	Q2/ADDRESS OF SDB
;	Q1/ADDRESS OF SIZE DATA FOR THIS DISK TYPE

DSKA3:	SOS 0(T4)		;One less if here
	SOS SDBFRC(Q2)		;And one less on the structure
	MOVEM T4,DSKEXT		;Save track count word
	MOVEI T4,1		;One page
	MOVEM T4,DSKACT		;init count
	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
	SKIPN DSKMUF		;Want to do preallocation?
	IFSKP.			;If so
	 EXCH Q3,DSKMUF		;Save a reg. Get count to preallocate
	 MOVE T4,DSKEXT		;Recover track count word
	 DO.			;Look for others
	  LSH T3,-1		;next bit please
	  JUMPE T3,ENDLP.	;If at the end, done
	  SKIPE 0(T4)		;Any more here?
	  TDNN T3,0(1)		;This one free too?
	  EXIT.			;No
	  ANDCAM T3,0(T1)	;yes. get it
	  SOS SDBFRC(Q2)	;One less, again
	  SOS 0(T4)		;And one less here too
	  AOS DSKACT		;Another one
	  SOJG Q3,TOP.		;Do more if we can
	 ENDDO.
	 MOVE Q3,DSKMUF		;Recover register
	ENDIF.
	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
	MOVE T2,DSKACT		;return count as well
	RETSKP
;THE SEARCH FOR THE BEST TRACK (DSKASN)

;	Q2/ADDRESS OF SDB
;	Q1/ADDRESS OF SIZE DATA FOR THIS DISK TYPE

;**;[7272] REWRITE CODE AT DSKA1:+0.L	DSW	3/19/86
DSKA1:	MOVE T1,SDBMFP(Q2)	;[7272] FREE CHOICE, USE CURRENT STRUCTURE
	MOVEM T1,MINFRE		;[7272] MINIMUM
	SKIPA T1,SDBLCA(Q2)	;[7272] AND START WITH LAST CYLINDER ASSIGNED
DSKSQ:	SETZM MINFRE		;[7272] SPECIFIED...PICK NEARBY, NO MIN CYLINDER
	SETZ T4,		;[7272] TO RECORD MAX FREE FOUND
	MOVE T3,SDBCYL(Q2)	;[7272] NUMBER CYLINDERS TO LOOK AT
DSKA6:	ADD T1,CYLUNT(Q1)	;[7272] LOOK AT NEXT UNIT (TO BALANCE I/O)
	CAML T1,SDBCYL(Q2)	;[7272] LOOKING WITHIN KNOWN CYLINDERS?
	AOJA T1,[IDIV T1,CYLUNT(Q1) ;[7272] NO, LOOK ON NEXT TRACK, PACK ZERO
		MOVEI T1,(2)	;[7272] ...  
		JRST .+1]	;[7272] ...
	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
;**;[7272] CHANGE 1 LINE AT DSKA4:-2.L	DSW	3/19/86
	CAML T4,MINFRE		;[7272]GOOD ENOUGH TO QUIT?
	JRST DSKA8		;YES
;**;[7272] REMOVE 1 LINE AT DSKA4:+0.L	DSW	3/19/86
DSKA4:	SOJG 3,DSKA6		;[7272] 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>
	EA.ENT			;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.(CHK,ASAASG,DSKALC,SOFT,<DSKASA - Assigning already assigned disk address>,<<T1,STRCOD>,<T2,SECTOR>>,<

Cause:	The sector being assigned on the disk is already assigned.
	This may happen during creation of structure when assigning
	swapping space, and the sector is already assigned in the
	BAT blocks. Also can be caused by redundant BAT block entries.

Data:	STRCOD - Structure Unique Code
	SECTOR - Sector Number on Disk Relative	to Start of Structure

>)
		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,MS%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.(CHK,ASGBAD,DSKALC,SOFT,<DSKASA - Assigning bad disk address>,<<T3,STRCOD>,<T2,SECTOR>>,<

Cause:	The sector being assigned was not within the legal range
	of sector numbers.

Data:	STRCOD - Structure Unique Code
	SECTOR - Sector Number on Disk Relative	to Start of Structure
>)
	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>
	EA.ENT
	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

;DEDSKM for deassigning mulitple pages.
;	T3/ count of pages to deassign. All must be on same track
;CALLED BY MONITOR ROUTINES (NOT DSKAS JSYS)
;BUGCHKS IF PAGE WAS NOT ASSIGNED

DEDSK::	MOVEI T3,1		;Release one page
DEDSKM::ASUBR<DEDADR,DEDSTN,DEPCNT>
	EA.ENT
	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.(CHK,DEAUNA,DSKALC,SOFT,<DEDSK - Deassigning unassigned disk address>,<<T1,STRCOD>,<T2,SECTOR>>,<

Cause:	The disk address being deassigned was never assigned.

Data:	STRCOD - Structure Unique Code
	SECTOR - Sector Number on Disk Relative	to Start of Structure
>)
		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)
;	T3/ COUNT OF PAGES ON TRACK TO DEASSIGN

;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,DSKCNT>
	MOVEM T1,DSKADR		;SAVE SECTOR NUMBER
	MOVEM T2,STRN02		;SAVE STRUCTURE NUMBER
	MOVEM T3,DSKCNT
	MOVE T3,STRTAB(T2)	;POINT TO START OF SDB FOR THIS STRUCTURE
	MOVX T4,MS%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
				;T4/ count of bits remaining in track
	 JRST DSKDE2		;BAD ADDRESS
	SUB T4,DSKCNT		;Make sure the args are correct
	AOSGE T4		;Are they?
	BUG.(HLT,DSKBRP,DSKALC,SOFT,<DSKDEA - Pages on multiple cylinders>,<>,<

Cause:	DSKDEA has been called to delete a number of pages, and the pages
	are on multiple cylinders. This is not allowed.
>)
	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
	MOVE T4,DSKCNT		;Get the count
	DO.			;Do them all
	 TDNE 3,0(T1)		;PAGE ASSIGNED?
	 JRST DSKDE1		;NO, RETURN BAD
	 IORM 3,0(T1)		;YES. UNASSIGN IT
	 SOJLE T4,ENDLP.	;If no more, done
	 ROT T3,-1		;Slide the bit over
	 JUMPG T3,TOP.		;Keep going it in same word
	 AOJA T1,TOP.		;next word
	ENDDO.
	ADD T2,BTBORA		;POINT TO WORD IN BIT TABLE FOR THIS TRACK
	MOVE T1,DSKCNT		;Get the count again
	ADDM T1,0(T2)		;Increase the track count
	MOVE T4,STRN01		;GET STRUCTURE NUMBER
	MOVE T4,STRTAB(T4)	;POINT TO START OF SDB FOR THIS STRUCTURE
	ADDB 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.(CHK,DEABAD,DSKALC,SOFT,<DSKDEA - Deassigning bad disk address>,<<T3,STRCOD>,<T2,SECTOR>>,<

Cause:	The sector being deassigned was not within the legal
	range of sector numbers.

Data:	STRCOD - Structure Unique Code
	SECTOR - Sector Number on Disk Relative	to Start of Structure
>)
	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>
	EA.ENT
	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::SAVEP
	EA.ENT
	MOVE P2,B		;SAVE CORE ADDRESS
	TLZ C,-1		;CLEAR JUNK IN LEFT HALF
	MOVE C,UDBSIZ(C)	;GET POINTER TO DSKSIZ ENTRY
	MOVE P4,SECPAG(C)	;REMEMBER SECTORS PER PAGE
	PUSH P,A		;SAVE DISK ADDRESS
	IDIV A,SECCYL(C)	;FIND NUMBER OF CYL'S
	IMUL A,LPPCYL(C)	;FIND NUMBER OF LOST SECTORS
	ADDB A,0(P)		;UPDATE LOCAL 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
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
	ADD D,C			;GET LAST ONE
	TRZ C,-1(P4)		;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
	EA.ENT
	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?
	IFNSK.
	 MOVSS A		;YES. SET UP FOR TEST
	 HRRI A,BATTST
	 RDISMS			;WAIT FOR IT
	 HLRZS A
	ELSE.
	 IORM B,UDBSTS(A)	;NO. LOCK IT THEN AND STAY NOSKED
	ENDIF.
;   IFN CFSCOD,<
	SKIPGE A,UDBSTR(A)	;GET STR IT IS MOUNTED WITH
	IFSKP. 
	 HRRZS A		;ONLY GET STRTAB INDEX
	 CALL CFGBBS
	ENDIF.
;   >	;IFN CFSCOD
	RETSKP			;RETURN WITH IT LOCKED

;SCHEDULER TEST FOR BAT BLOCK AVAILABLE

	RESCD

BATTST:	MOVX B,US.BLK		;THE BIT
	TDNE B,UDBSTS(A)	;FREE NOW?
	JRST 0(4)		;NO. BLOCK AGAIN
	NOSKED			;BE NOSKED WHILE WE HAVE LOCK
	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
	EA.ENT
	ANDCAM B,UDBSTS(A)	;CLEAR LOCK
	OKSKED			;BECOME OKSKED AGAIN AFTER LOCK RELEASE
;   IFN CFSCOD,<
	SKIPGE A,UDBSTR(A)	;IS IT A MOUNTED PACK?
	IFSKP. 
	 HRRZS A		;ONLY USE STRTAB INDEX
	 CALL CFFBBS		;YES
	ENDIF.
;   >	;IFN CFSCOD
	RET			;DONE
;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
;		T4/ bits remaining in this cylinder

;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
	MOVE T4,PAGCYL(T4)	;Get pages per cylinder
	SUB T4,T2		;Compute number remaining
	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>
	EA.ENT
	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
	EA.ENT
	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
;**;[7120] ADD CODE IN LITERAL AT TOPASG:+5.L	DSW	8/8/85
	JRST [	MOVE B,STRN04	;[7120]  NOT IN SWPNG AREA, B/ STR #
		MOVE B,STRTAB(B);[7120]  B/ SDB ADDRESS
		MOVE B,SDBTYP(B);[7120]  B/ DSKSZn TABLE ADDRESS
		MOVE B,SECUNT(B);[7120]  B/ # SECTORS PER UNIT
		MOVE A,SVADR2	;[7120]  GET BAD SECTOR ADDRESS
		CAMLE A,B	;[7120]  IN MAINTENANCE AREA ?
		 JRST TPASG1	;[7120]  YES, DON'T ASSIGN (WOULD FAIL ANYWAY)
		MOVE B,STRN04	;[7120]  NO, GET STRUCTURE #
		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
;**;[7120] ADD LABEL AT TOPASG:+7.L	DSW	8/8/85
TPASG1:	MOVE B,STRTPT		;[7120] 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.(CHK,ASGBPG,DSKALC,SOFT,<INIBTB - Failed to assign bad page(s)>,<<T1,STRCOD>,<T2,AMOUNT>>,<

Cause:	The bit table is being initialized; home blocks, pages
	in the BAT blocks, and swapping space are being assigned.
	Address(es) in the BAT blocks were not assigned.

Data:	STRCOD - Structure unique code
	AMOUNT - Number of addresses not assigned
>)
		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
	EA.ENT
	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,.AREXM		;EXEMPT FROM MIGRATION
	MOVEI T3,.ARSET		;SET IT
	ARCF			;DO IT
	 ERJMP WRTBT5		;HANDLE ERROR
	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
;**;[7172] Change 2 lines at WRTBTB:+18L	JDM	23-Oct-85
	MOVX T2,FB%NOD!FB%NDL	;[7172]T2/MASK OF BITS TO BE AFFECTED
	MOVX T3,FB%NOD!FB%NDL	;[7172]T3/NEW VALUE - SET NO DUMP
				;[7172]AND NEVER DELETE
	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.(HLT,WRTLNG,DSKALC,SOFT,<WRTBTB - Bit table is a long file>,,<

Cause:	The FDB for a file structure bit table has the FB%LNG bit set, which
	says the file is a long file.

>)
	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
;   IFN CFSCOD,<
	CALL CFSSBB		;Notify CFS
;   >	;IFN CFSCOD
	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			;NORMAL RETURN IS SKIP
	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.(CHK,WRTCPB,DSKALC,HARD,<WRTBTB - Failed to backup ROOT-DIRECTORY>,<<T1,STRCOD>>,<

Cause:	The bit table is being written.  The backup root-directory or
	symbol table may not have been written, or there may not be
	enough free space on the pack.

Data:	STRCOD - Structure Unique Code
>)
		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.(CHK,WRTBT4,DSKALC,SOFT,<ASOFN on bit table file failed>,<<T2,STRCOD>>,<

Cause:	Could not assign an OFN for the structure bit table.

Data:	STRCOD - Structure Unique Code
>)

;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
	EA.ENT
	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.(HLT,MNTLNG,DSKALC,SOFT,<MNTBTB - Bit table is a long file>,,<

Cause:	While mounting the structure, the monitor discovered that the bit table
	for the structure is a long file.

Action: Use CHECKD to rebuild the file structure bit table.  If that does not
	work, recreate the structure.
>)
	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
;   IFN CFSCOD,<
	CALL CFSSBB		;Notify CFS
;   >	;IFN CFSCOD
	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
;MPABTF ENTRY:
;	Same as MAPBTB, but fails if we had to wait

MAPBTF:	TDZA T2,T2		;ENTRY TYPE
MAPBTB::MOVEI T2,1
	STKVAR<BTBMAP,BTBMP0>
	MOVEM T2,BTBMP0
	EA.ENT
	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.(HLT,MAPBT1,DSKALC,SOFT,<OFN for bit table is zero>,,<

Cause:	There is no OFN for the file structure bit table currently being
	mapped.

>)
	MOVEM T1,BTBMAP		;YES. SAVE SPT INDEX
MAPBTR:	NOSKED			;Exclusive ownership for a bit
;   IFN CFSCOD,<
	CAIL T1,NOFN		;Is this really an OFN?
	JRST MAPBTP		;No. Skip the rest of this
	LOAD T2,SPTST,(T1)	;Get state of the bit table file
	TMNN SPTFO,(T1)		;being forced?
	CAIE T2,.SPSWR		;Here and exclusive?
	SKIPA T1,BTBMAP		;Must request it
	JRST MAPBT0		;If so, go to it
	MOVEI T2,1		;NEED WRITE
	OKSKED
	CALL CFSAWT		;MOVE IT HERE AND RESCHED
	SKIPN BTBMP0		;Want to know about this?
	RET			;Yes
	MOVE T1,BTBMAP
	JRST MAPBTR		;No.

MAPBT0:	MOVE T1,BTBMAP		;GET STR
	TMNN SPTSFD,(T1)	;Does this need reverifying?
	IFSKP.			;If so...
	 OKSKED			;Undo NOSKED from above
	 CALL XBCHK		;Do the check
	 SKIPN BTBMP0		;Want to know about that?
	 RET			;yes
	 MOVE T1,BTBMAP
	 JRST MAPBTR		;No. So try again now
	ENDIF.
	MOVEI T2,1		;WRITE PLEASE
	CALL CFSAWP		;GET IT
	MOVE T1,BTBMAP
;   >	;IFN CFSCOD
MAPBTP:	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
	SKIPE BTBMP0		;WANT TO KNOW ABOUT RESCHED?
	RET
	RETSKP			;YES
;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::STKVAR <UNMBTS>
	MOVEM T1,UNMBTS		;SAVE STR NUMBER
	EA.ENT
	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,UNMBTS		;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
;   IFN CFSCOD,<

	MOVE T1,UNMBTS		;GET STR NUMBER
	MOVE T1,STRTAB(T1)	;Get SDB pointer
	MOVE T1,SDBBTB(T1)	;Get OFN of bit table
	CAIGE T1,NOFN		;Is it really an OFN?
	CALL CFSFWT		;YES, RELEASE IT
;   >	;IFN CFSCOD
	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.(CHK,DSKBT3,DSKALC,SOFT,<DISK Bit table already locked at LCKBTB>,<<T1,SPTIDX>>,<

Cause:	A structure bit table being locked is already locked.

Data:	SPTIDX - Offset in SPT for entry to copy into BTBBAS SPT and SPTH
	slots.
>)
	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/
;utility to incrment a disk address.
;	T1/ The address
;	T2/ structure number
;Returns +1
;	Preserves all ACs except T1

DSKINC::SAVEAC<Q1>		;Get a work AC
	MOVE Q1,STRTAB(T2)	;SDB address
	MOVE Q1,SDBTYP(Q1)	;Get type table
	ADD T1,SECPAG(Q1)	;increment the address
	RET			;And done
;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!DA%AIN ;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 [	MOVEI T3,1	;One page only
		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!DA%AIN	;NOW, WHAT WERE WE DOING?
	JRST DSKUA5		;WRITING(OR ABORTING) 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 MS%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
	UMOVE T2,T1		;get user's flags back
	TXNE T2,DA%AIN		;aborting initialization?
	JRST [  HRLZ T2,T1	;yes, T2/ (OFN,,PN)
		MOVE T1,STRN07	;get stucture number back.
		MOVE T1,STRTAB(T1) ;get address of SDB
		MOVE Q1,T1	;save address for later use
		MOVE T3,SDBBT0(T1) ;get size of top half of BIT table
		ADD T3,SDBBT1(T1) ;add size of bottom half
		ADDI T3,<PGSIZ-1> ;round to end of page
		IDIVI T3,PGSIZ	;convert to number of pages
		MOVE T4,T3	;T4/number of pages
		MOVX T3,PM%RD+PM%WR ;make page available
		SETZM T1	;T1/ to indicate clear the page table
		CALL MSETPT	;CLEAR THE TEMPORARY PAGE TABLE
		 NOP		;don't care
		MOVE T1,SDBBTB(Q1) ;OFN of bit table
		CALL DESPT	;RELEASE THE SPT SLOT
		SETZM SDBBTB(Q1) ;clear OFN of BTB
		MOVE T1,STRN07	;structure number
		CALL MNTBTB	;mount bittable
		 JFCL		;don't care about errors
		JRST DSKUA7]	;don't write data onto the disk

	MOVE T1,STRN07		;T1/STRUCTURE NUMBER
	MOVX T2,GJ%OLD!GJ%PHY!GJ%DEL!GJ%SHT
	CALL GETBTB		;GET A JFN FOR THE FILE
	 JRST [CAIE T1,GJFX24	;IS ERROR "FILE NOT FOUND"?
		RETSKP		;NO. IGNORE THE FAILURE.
		JRST DSKU10]	;YES. THEN GO MAKE A NEW ONE
	MOVEM T1,BTJFN1		;SAVE JFN
;**;[7172] Add 6 lines at DSKUA5:+33L	JDM	23-Oct-85
	HRLI T1,.FBCTL		;[7172]OFFSET OF WORD TO CHANGE
	MOVX T2,FB%NDL		;[7172]BIT MASK TO MODIFY
	SETZ T3,		;[7172]TURN OFF 'NEVER DELETE' BIT
	CHFDB%			;[7172]WE CAN DELETE THE FILE
	 ERJMP .+1		;[7172]NO DAMAGE DONE
	MOVE T1,BTJFN1		;[7172]GET BACK THE 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
DSKU10:	MOVE T1,STRN07		;T1/STRUCTURE NUMBER
	CALL WRTBTB		;WRITE THE BIT TABLE FILE
	 RETBAD (,<OKSKED>)	;FAILED
DSKUA7:	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
	UMOVE T4,T1		;get user's flags back
	TXNE T4,DA%AIN		;aborting initialization?
	CALL UPDOFN		;NO, THEN 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>
	EA.ENT
	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
	BLOCK.
	 SAVEAC <T3>		;Save arg
	 SKIPE T1,SDBBTB(T3)	;Get bit table OFN
	 CALL OFNTKN		;Yes. Make sure we have it
	ENDBK.
	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
;Utility routines needed by CFS to manage the STR free count.

;Get structure free count
;	T3/ STR number
;Returns:	+1 T4/ SDBFRC

	RESCD

GETFRC::MOVE T4,STRTAB(T3)	;Get SDB address
	MOVE T4,SDBFRC(T4)	;Get Free count
	RET			;And done

;Store free count
;	T3/ STR number
;	T4/ New SDBFRC
;Preserves T3

STOFRC::MOVE T3,STRTAB(T3)	;Get SDB
	MOVEM T4,SDBFRC(T3)	;New value
	LOAD T3,STRUS,(T3)	;REcover structure number
	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:
;	1B9 (DOP%NF) Use new format for channel, controller,
;		     and unit numbers (CKU number)
;	1B10 (DOP%EO) Error if unit is offline
;	1B11 (DOP%IL) Inhibit error logging
;	1B12 (DOP%IR) Inhibit error recovery
;	1B13 (DOP%PS) Physical sector addressing
;	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.
	SWAPCD
.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%PS!DOP%IR!DOP%WR!DOP%CT!DOP%EO>	;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
	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
	JUMPN P3,DSKOP5		;DOING MULTI-PAGE TRANSFER?
	TXO T2,DOP%EO		;YES, GENERATE ERRORS ON OFF-LINE
	CALL MDSKIO		;CALL MULTIPLE-PAGE ROUTINE
	SKIPA
DSKOP5:	CALL UDSKIO		;HERE FOR SINGLE PAGE TRANSFER
	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
;**;[7352]At DSKOP5:+9L replace 1 line with 5 lines  JCR  7/29/86
	UMOVE T1,1		;[7352]Pick up the potential error code
	SKIPL T1		;[7352]Was there an error?
	JRST MRETN		;[7352]No, so just return
	HRRZ T1,T1		;[7352]Yes, zero out the LH -1
	ITERR()			;[7352]Indicate the error
;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>
	EA.ENT
	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
	EA.ENT
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
;   IFN CFSCOD,<			;If CFS stuff
	LOAD T2,SPTST,(T1)	;Get state of the bit table
	TMNN SPTSFD,(T1)	;Is it already purged?
	CAIE T2,.SPSWR		;No, write access?
	RET			;No. All done then (can't be modified here)
;   >	;IFN CFSCOD
	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
;OFPTT		;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
	EA.ENT
	SAVEPQ
	JSBVAR <STRTY1,STRN13,OFPTT,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
	SKIPN UDB2ND(D)		;DUAL PORTED, BOTH PORTS ON THE -20?
	TDNN C,UDBSTS(D)	;NO, IS THIS DUAL PORTED (ON -11)?
	SKIPA			;NOT THE FRONT-END DISK
	JRST FEFSY1		;YES
	AOBJN B,FESYS2		;LOOK AT NEXT
   REPEAT 0,<
	SKIPN FILTYP		;IF BOOTSTRAP NO BUGCHECK
	BUG.(CHK,NO2PRT,DSKALC,HARD,<FEFSYS-NO DUAL-PORTED DISK. USING LOGICAL 0>,,<

Cause:	This BUG is not documented yet.

Action:

>) >   ;END REPEAT 0
	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
;**;[7337]  Change 1 line at FEFSY7:+20			DML	23-Jul-86
	MOVX A,GJ%NEW!GJ%SHT!GJ%PHY  ;[7337]  GTJFN flags - no log name expand
	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
;**;[7172] Change 1 line at FEFSY7:+23L	JDM	23-Oct-85
	TXO B,FB%LNG!FB%NOD!FB%NDL ;[7172]MAKE IT LONG, NO DUMP
				;[7172]AND 'NEVER DELETE' AS WELL
	MOVEM B,.FBCTL(P4)	;BACK INTO THE FDB
	MOVX B,AR%EXM		;EXEMPT FROM MIGRATION
	IORM B,.FBBBT(P4)	;SET IT IN 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,OFPTT		;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,OFPTT		;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,OFPTT		;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,OFPTT		;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.(CHK,FEOCPB,DSKALC,SOFT,<FEFSYS - Failed to backup ROOT-DIRECTORY>,<<T1,STRCOD>>,<

Cause:	A copy of the Root-Directory was not made due to one of the
	following errors:
	    1.  Not enough free space
	    2.  Could not get JFN
	    3.  Root-Directory or symbol table is bad

Data:	STRCOD - Structure unique code
>)
		JRST .+1]
	RETSKP			;AND DONE

FEFER3:	MOVE A,OFPTT		;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

	EA.ENT			;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+DOP%WR+DOP%PS+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
	EA.ENT
	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
	EA.ENT
	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.(CHK,BADBAT,DSKALC,HARD,<BAT blocks unreadable>,,<

Cause:	BAT block header contains bad information.

>)
		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 BATQE1		;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
	MOVE B,UDBSIZ(P4)	;GET PREVIOUS PAGE
	SUB A,SECPAG(B)		;IN SECTORS PER 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
	MOVE A,UDBSIZ(P4)	;NEW COUNT
	ADD B,SECPAG(A)		;IN SECTORS PER PAGE
	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)
	MOVE B,UDBSIZ(P4)	;SET NUMBER IN REGION
	MOVE B,SECPAG(B)	;BASED ON SECPAG FOR DISK
	SUBI B,1		;ONE LESS IS FORMAT FOR 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
	ANDI B,7		;DRIVE UNITS GREATER THAN 8 DESTROYS THE
				;TABLE.  THIS IS TRUE FOR RP20'S AND HSC'S
	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
;**;[7357] Change 1 line at UPDBLK:+8L	MDR	20-AUG-86
	MOVE A,APRSER		;[7357] 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
BATQE2:	SKIPE ERRSWP		;WAS THERE A SWAP ERROR?
	JRST [			;YES THERE WAS, TAKE CARE OF IT
		SOSN ERRSWP	;DEC THE COUNT, SKIP IF DONE
		BUG. (HLT,SWPXXX,DSKALC,HARD,<Unrecoverable swap error for critical page>,,<

Cause:	The monitor had a swap error for a PSB, PT, PTP, or UPT.
	At the time of the error, a BUGCHK reported the problem,
	and allowed the system to continue to record the error in
	SYSERR, and rewrite the BATBLOCK.

>)
		JRST .+1]	;IF WE KEEP GOING, OK BY ME
	OKINT			;AND ALLOW INTS NOW
	RET

BATQE1:	MOVE A,P1
	LSH A,-PGSFT		;GET CORE PAGE NUMBER
	CALL MULKCR		;RELEASE IT
	JRST BATQE2
   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
;Routine used at system start-up to mount PS:. This is called
;is called after SETSPD has run so that in the future the CONFIG file
;might indicate how PS: should be mounted. For now, this routine tires
;to get it mounted exclusively first and failing that, shared. It is
;up to some other job to verify that PS: is mounted correctly.

;   IFN CFSCOD,<			;Only for CFS monitors
MNTPS::	MOVEI T2,1		;Try for exclusive first
	MOVEI T1,PSNUM		;Number of PS:
	CALL CFSSMT		;Do mount
	IFSKP.			;If it made it
	 MOVEI T2,1		;Say it was exclusive
	ELSE.
	 MOVEI T1,PSNUM		;PS again
	 MOVEI T2,0		;Try for "shared"
	 CALL CFSSMT		;Do it
	  BUG.(HLT,FSICFS,DSKALC,SOFT,<Could not register PS with CFS>,,<

Cause:	Some other CFS system has this structure mounted exclusively
	or as an alias and is preventing this system from mounting the 
	structure. This is an administrative problem.
>)
	 SETZM T2		;Got it
	ENDIF.
	MOVE T1,STRTAB+PSNUM	;Get SDB for PS:
	STOR T2,STEXL,(T1)	;Set mount tyep bit
	RET			;And done
;   >	;IFN CFSCOD
;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
PDBBLK==:3			;ADDRESS OF PDB 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)
HOMDCF==:16			;DON'T CARE DISK FLAG (FILE SYSTEM PROTECTION
				;FOR FILE STRUCTURE IGNORED)
HOMBTF==:17			;BOOT PARAMETER FLAGS - THIS OFFSET CANNOT BE
				; CHANGED WITHOUT RECOMPILING BOOT
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 (3 WORDS)
HOMOID==:170			;OWNER ID (3 WORDS)
HOMFSN==:173			;FILE SYSTEM TYPE (3 WORDS)
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.(HLT,TTNAC5,DSKALC,HARD,<CTY not active at FSIINI>,,<

Cause:	While mounting the public structure, the monitor found it 
	had no CTY on which to output information.

Action:	Call Digital Field Service.

>)
	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
;**; [7289] Add 1 line at CHKH20: + 2 L		JDM	24-Apr-86
	CALL REMSTR		;[7289]CLEAN UP STRTAB AND UDB'S
	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,MS%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
;**; [7289] Change 1 line at CHKH21:		JDM	24-Apr-86
CHKH21:	MOVE T1,FSICUR		;[7289]GET NAME OF THIS STRUCTURE
	CALL FSI6TY
;**; [7289] Replace 1 line with 4 at CHKH21: + 2 L	JDM	24-Apr-86
	HRROI T1,[ASCIZ/: Does not have swapping space.
/]				;[7289]
	CALL FSIPSO		;[7289]TELL OPERATOR ABOUT PROBLEM
	HRROI T1,[ASCIZ/ What is the name of the system structure? /] ;[7289]
	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
;**; [7289] Add 1 line at CHKH21: + 11 L	JDM	24-Apr-86
	SETZM FSICUR		;[7289]PREPARE TO LOOK AGAIN FOR PS
	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


;**; [7289] Remove 44 lines at CHKH30: + 10 L	JDM	24-Apr-86
;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
	SKIPL UDB2ND(P3)	;DONT EXAMINE THE ALTERNATE PORT OF A DUAL PORTED DRIVE
	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
;**; [7289] Replace 7 lines with 11 at CKHOMU:+32.L	JDM	24-Apr-86
	SKIPE FSINAM		;[7289]LOOKING FOR SPECIFIC NAME?
	IFNSK.			;[7289]YES
	 MOVE T2,HOMSNM(T1)	;[7289]GET THE STRUCTURE NAME
	 CAME T2,FSINAM		;[7289]IS THIS IT?
	 RET			;[7289]NO. SO DON'T BUILD THE SDB
	ELSE.			;[7289]NO NAME, SO CHECK SERIAL NUMBER
	 MOVE T2,HOMSER(T1)	;[7289]GET THE SERIAL # FROM HOME BLOCKS
	 CAME T2,APRSER		;[7289]DOES IT MATCH THIS SYSTEM?
	 RET			;[7289]NO, SO DON'T BUILD AN SDB
	 MOVE T2,HOMSNM(T1)	;[7289]YES. GET THE STRUCTURE NAME
	ENDIF.			;[7289]
	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 0(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
	MOVX T2,RS%SE0!.RESUP	;GET SPACE FROM UNITS POOL, SECTION 0
	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,MS%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
;**; [7289] Add routine at BLDSDB: + 12 L	JDM	24-Apr-86
;REMSTR - REMOVE A STRUCTURE FROM STRTAB
;	  This routine cleans up the UDBs associated with the structure and
;	  clears the STRTAB entry. It releases the SDB free space when
;	  needed.
; ACCEPTS:
;	T1/ STRUCTURE NUMBER (OFFSET INTO STRTAB) IN RH
;
;	CALL REMSTR
;
; RETURNS: +1: ALWAYS
;
REMSTR:	SAVET			;[7289]
	SKIPN T3,STRTAB(T1)	;[7289]LOAD T3 WITH THE SDB ADDRESS
	RET			;[7289]NOTHING TO DO IF ZERO
	MOVN T2,SDBNUM(T3)	;[7289]MAKE AOBJN WORD FROM # OF UNITS
	HRLZS T2		;[7289]PUT NEGATIVE COUNT IN LEFT HALF
	HRR T2,T3		;[7289]AND SDB ADDRESS IN RIGHT HALF
REMST2:	MOVE T3,SDBUDB(T2)	;[7289]GET ADDRESS OF UNIT DATA BLOCK
	JUMPE T3,REMST3		;[7289]IF NONE SETUP GO TO NEXT
	SETOM UDBSTR(T3)	;[7289]CLEAR STRUCTURE INFORMATION IN UDB
	SETZM SDBUDB(T2)	;[7289]CLEAR POINTER TO UNIT DATA BLOCK
REMST3:	AOBJN T2,REMST2		;[7289]LOOP OVER ALL UNITS IN THE STRUCTURE
	HRRZS T1		;[7289]GET STRUCTURE NUMBER ONLY
	CALL CLRSTB		;[7289]CLEAN UP STRTAB
	RET			;[7289]
; 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
	MOVE P1,CRHUDB		;Get UDB address
	MOVEM T1,UDBMID(P1)	;Save the new ID in the UDB too
	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!DOP%PS ;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!DOP%PS ;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+DOP%PS+HBLEN] ;CHANNEL+UNIT, WR+DOP%PSITE, 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+DOP%WR+DOP%PS)	;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+DOP%WR+DOP%PS+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+DOP%WR+DOP%PS+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 <LSTBAT,CURBAT,CKBADR,CKBPAG,CKBNDX,CKBFLG,CKBDRA>
	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
	MOVEM B,LSTBAT		;SAVE IT
DOBDRM:	MOVEM A,CURBAT		;SAVE CURRENT AS WELL
	MOVE D,STRTAB(P5)	;GET SDB
	MOVE B,SDBTYP(D)	;POINT TO SIZE DATA FOR THIS DISK TYPE
	MOVE B,SECPAG(B)	;GET NUMBER OF SECTORS PER PAGE
	SUBI B,1		; -1
	ANDCM A,B		;ROUND DOWN TO NEAREST PAGE
	SUB A,SDBFSS(D)		;SEE IF WITHIN SWAPPING BOUNDS
	SKIPL A			;IS IT?
	CAML A,SDBNSS(D)	;?
	JRST NOTER		;NO
	MOVEM C,CKBNDX		;SAVE BAD PAIR INDEX
	MOVE CX,SDBTYP(D)	;GET ADDR OF DSKSIZ TABLE
	IDIV A,SECCYL(CX)	;GET TRACK,,SECTOR WITHIN SWAP SPACE
	IMUL A,SDBNUM(D)	;COMPUTE INTERLEAVE BASED ON SIZE OF STR
	MOVEI C,-SDBUDB(P4)	;COMPUTE PACK # IN STR
	SUB C,D			; "
	ADD A,C			;ADD IN PACK # FOR PHYSIO
	IMUL A,SECCYL(CX)	;COMPUTE CYLINDER # IN SWAP SPACE
	ADD A,B			;ADD IN SECTOR #
	TXO A,DRMOB		;INDICATE AN OVERFLOW ADDRESS
	MOVEM A,CKBDRA		;SAVE ADDRESS TO BE ASSIGNED
	CALL DRMASA		;ASSIGN DRUM ADDRESS
	 JRST [	MOVE C,STRTAB+PSNUM	;POINT TO SDB FOR PS (ONLY CASE
		LOAD C,STRNAM,(C) ; IN WHICH WE GET HERE)
		SKIPE T1	; OUT-OF-RANGE?
		BUG.(CHK,SWPASF,DSKALC,SOFT,<CHKBAT - Failed to assign bad swapping address>,<<T3,STRNAM>,<CKBDRA,ADDR>>,<

Cause:	Swapping address was not assigned due to an illegal address or
	an already assigned address.

Data:	STRNAM - Sixbit Structure Name
	ADDR - Address to be Assigned
>)
		JRST .+1]
	MOVE C,CKBNDX		;RESTORE INDEX
NOTER:	MOVE A,CURBAT		;GET BACK THIS ONE
	MOVE D,STRTAB+PSNUM	;POINT TO SDB FOR PUBLIC STRUCTURE
	MOVE B,SDBTYP(D)	;POINT TO SIZE DATA FOR THIS DISK TYPE
	ADD A,SECPAG(B)		;GET TP NEXT ONE
	CAMG A,LSTBAT		;STILL WITHIN THE REGION?
	JRST DOBDRM		;YES. GO DO IT
	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
; 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+DOP%WR+DOP%PS+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.(CHK,NOBAT1,DSKALC,HARD,<Failed to write primary BAT BLOCK>,<<T1,CKUNUM>>,<

Cause:	Primary BAT blocks were not written due to one of the following
	errors:
	    1.  Invalid unit or channel specified
	    2.  Channel and unit is not a disk device
	    3.  Hardware error

Data:	CKUNUM - Channel, controller, and unit numbers (12 bits each)
>)
DO2B:	MOVE T1,SVVADR		;GET VIRTUAL ADDRESS OF BAT BLOCKS
	CALL SWPHOM		;SWAP THE BAT BLOCKS
	MOVE T2,[1B0+DOP%WR+DOP%PS+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.(CHK,NOBAT2,DSKALC,HARD,<Failed to write secondary BAT BLOCK>,<<T1,CKUNUM>>,<

Cause:	Secondary BAT blocks were not written due to one of the following
	errors:
	    1.  Invalid unit or channel specified
	    2.  Channel and unit is not a disk device
	    3.  Hardware error

Data:	CKUNUM - Channel, controller, and unit numbers (12 bits each)
>)
	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
		CAIGE T2,2	; THE HOME BLOCKS. OTHERWISE, ASSUME
		RET		; THEY COULD DO THEMSELVES IN
		JRST .+1]
	SETOM FEFSIZ		;INDICATE SIZE OF FE FILE SYSTEM UNKNOWN
	SETOM BOTSIZ		;[2609] BOOTSTRAP SIZE 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,FSIDEC		;GET PHYSICAL CHANNEL #
	CALL FSIASK		;ASK QUESTION AND GET ANSWER
	 JRST FSIDI2		;ERROR, GO ASK QUESTION AGAIN
	MOVEM T1,FSICHN		;SAVE CHANNEL NUMBER
	CALL FSIDEC		;READ IN CONTROLLER NUMBER
	 JRST FSIDI2		;ERROR, ASK AGAIN
	MOVEM T1,FSICTL		;SAVE CONTROLLER NUMBER
	CALL FSIDEC		;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 FSIDTY		;TYPE IT
	MOVEI T1,","		;PRINT COMMA
	CALL FSIPBO		; ...
	MOVE T1,FSICFK		;GET CONTROLLER NUMBER
	CALL FSIDTY		;PRINT IT
	MOVEI T1,","		;ANOTHER COMMA
	CALL FSIPBO		;TYPE IT
	MOVE T1,FSICFU		;GET UNIT NUMBER
	CALL FSIDTY		;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 PROVIDED BY CALLER
	CALL 0(T3)		;CALL IT TO 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:	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.(HLT,TTNAC4,DSKALC,HARD,<CTY not active at FSIPBI>,,<

Cause:	The CTY was not available to read in a character.

Action:	Call Digital Field Service.

>)
	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.(HLT,TTNAC3,DSKALC,HARD,<CTY not active at FSIPBO>,,<

Cause:	The monitor tried to write to the CTY, but the CTY was not available to
	output a character.  The line is not active.

Action:	Call Digital Field Service.

>)
	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