Google
 

Trailing-Edge - PDP-10 Archives - AP-4178E-RM - swskit-sources/physio.mac
There are 56 other files named physio.mac in the archive. Click here to see a list.
;<3A-MONITOR>PHYSIO.MAC.172, 25-Aug-78 13:43:49, EDIT BY FORTMILLER
;<3A.MONITOR>PHYSIO.MAC.171, 13-Aug-78 23:33:28, EDIT BY BOSACK
;IF A POSITIONING OPERATION TO A TAPE GETS AN ERROR AT STRTPS,
;FLUSH IORB AND POST COMPLETE
;<3A.MONITOR>PHYSIO.MAC.170,  2-Jul-78 01:33:55, Edit by BOSACK
;<3A.MONITOR>PHYSIO.MAC.169,  2-Jul-78 01:27:28, Edit by BOSACK
;<3A.MONITOR>PHYSIO.MAC.168, 28-Jun-78 13:50:49, EDIT BY BOSACK
;<3A.MONITOR>PHYSIO.MAC.167, 31-May-78 20:58:07, EDIT BY BOSACK
;<3A.MONITOR>PHYSIO.MAC.166, 31-May-78 14:43:13, EDIT BY BOSACK
;ADD TEMP XBIO STATS
;<3A-NEW>PHYSIO.MAC.165, 25-May-78 11:45:48, Edit by FORTMILLER
;ADD DX20 SUPPORT
;<3A.MONITOR>PHYSIO.MAC.164,  5-May-78 14:12:54, Edit by MCLEAN
;ADD CONVERT BCD TO OCTAL ROUTINE
;<3A.MONITOR>PHYSIO.MAC.163, 22-May-78 10:34:22, EDIT BY MILLER
;MOVE CALL TO GENBLK TO PROPER PLACE
;<3A.MONITOR>PHYSIO.MAC.162, 19-May-78 08:39:19, EDIT BY MILLER
;TCO 1189. GENREATE STATUS BLOCK AT ERRFIN
;<3A.MONITOR>PHYSIO.MAC.161, 21-Apr-78 14:03:22, EDIT BY MILLER
;FIX TYPEO IN 1878 ADDITION
;<3A.MONITOR>PHYSIO.MAC.160, 20-Apr-78 13:45:41, EDIT BY BOSACK
;3A TCO 1878 - TEST IF USER WANTS ERROR ON OFFLINE IN UDSKIO
;<3A.MONITOR>PHYSIO.MAC.159, 30-Mar-78 16:06:46, EDIT BY MILLER
;ADD MASSBUS UNIT # TO OVRDTA OUTPUT
;<3A.MONITOR>PHYSIO.MAC.158, 23-Mar-78 15:13:38, EDIT BY MILLER
;ADD UNIT AND CHANNEL #'S TO OVRDTA BUGINF
;<2BOSACK>PHYSIO.MAC.155, 24-Feb-78 01:18:37, EDIT BY BOSACK
;DONT START A NEW TRANSFER ON POWERFAIL, DONT DO BAT BLOCKS UNLESS DATA ERROR
;<2BOSACK>PHYSIO.MAC.155, 24-Feb-78 01:18:37, EDIT BY BOSACK
;DONT START A NEW TRANSFER ON POWERFAIL, DONT DO BAT BLOCKS UNLESS DATA ERROR
;<4.MONITOR>PHYSIO.MAC.155, 17-Feb-78 06:53:39, Edit by GILBERT
;DON'T MASK OUT HIGH ORDER BITS OF DISK ADDRESS IN UDSKIO.
;<4.MONITOR>PHYSIO.MAC.154,  1-Feb-78 14:48:55, Edit by MCLEAN
;MAKE PHYALC,PHYUDB ONLY BUGINF ON FAILURE
;<2BOSACK>PHYSIO.MAC.153, 27-Jan-78 02:16:48, EDIT BY BOSACK
;MOVE DSKSIZ TO PHYSIO
;<2BOSACK>PHYSIO.MAC.152, 26-Jan-78 23:21:11, EDIT BY BOSACK
;DONT PASS UDB FLAGS TO SEBCPY
;<2BOSACK>PHYSIO.MAC.151, 25-Jan-78 03:10:28, EDIT BY BOSACK
;USE SKIPS FOR TESTS OF SHORT IORB
;<3-MONITOR>PHYSIO.MAC.147, 16-Nov-77 21:14:01, EDIT BY BOSACK
;FIX TO ALLOW DISKS AND TAPES TO SHARE A SINGLE CHANNEL
;<3-MONITOR>PHYSIO.MAC.146,  9-Nov-77 09:57:01, EDIT BY KIRSCHEN
;MORE COPYRIGHT UPDATING...
;<3-MONITOR>PHYSIO.MAC.145, 26-Oct-77 10:48:27, EDIT BY KIRSCHEN
;MAKE GETSTR SUCCEED EVEN IF UNIT WRITE-LOCKED, SO .MSRUS WILL WORK
;<3.SM10-RELEASE-3>PHYSIO.MAC.5,  8-Dec-77 17:41:52, Edit by MCLEAN
;<3.SM10-RELEASE-3>PHYSIO.MAC.4,  8-Dec-77 17:41:14, Edit by MCLEAN
;<3.SM10-RELEASE-3>PHYSIO.MAC.3,  8-Dec-77 11:13:52, EDIT BY ENGEL
;TCO #1887 ELIMINATED UNUSED UNVECTORED INTERRUPT ENTRIES
;<3.SM10-RELEASE-3>PHYSIO.MAC.2,  1-Nov-77 00:49:44, Edit by MCLEAN
;INSERT SEARCH OF PROKL
;<3-MONITOR>PHYSIO.MAC.145, 26-Oct-77 10:48:27, EDIT BY KIRSCHEN
;MAKE GETSTR SUCCEED EVEN IF UNIT WRITE-LOCKED, SO .MSRUS WILL WORK
;<2BOSACK>PHYSIO.MAC.144, 13-Oct-77 02:39:26, EDIT BY BOSACK
;INCREASE INIFCX AND FCP
;<2BOSACK>PHYSIO.MAC.143, 13-Oct-77 00:25:29, EDIT BY BOSACK
;COMMAND STACK IMPROVEMENTS
;<3-MONITOR>PHYSIO.MAC.142, 12-Oct-77 14:10:06, EDIT BY KIRSCHEN
;UPDATE COPYRIGHT FOR RELEASE 3
;<2BOSACK>PHYSIO.MAC.141, 18-Sep-77 05:32:17, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.140, 17-Sep-77 05:50:09, EDIT BY BOSACK
;ALLOW UDSKIO TO BE CALLED FROM NONZERO SECTION
;<2BOSACK>PHYSIO.MAC.139, 15-Sep-77 05:13:05, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.138, 13-Sep-77 15:43:47, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.137, 13-Sep-77 03:11:17, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.136, 10-Sep-77 20:29:01, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.135,  9-Sep-77 21:42:10, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.134,  9-Sep-77 12:20:50, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.133,  9-Sep-77 12:06:44, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.132,  8-Sep-77 21:45:48, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.131,  6-Sep-77 04:54:06, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.130,  6-Sep-77 04:47:11, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.129,  6-Sep-77 04:27:53, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.128,  6-Sep-77 03:34:07, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.127,  6-Sep-77 01:32:13, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.126,  5-Sep-77 06:58:21, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.125,  5-Sep-77 06:24:36, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.124,  5-Sep-77 06:18:08, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.123,  4-Sep-77 04:11:04, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.122,  4-Sep-77 02:36:36, EDIT BY BOSACK
;THE LONG AWAITED, HOPEFULLY FINAL, SET OF BACKUP REG EDITS START HERE
;<3-MONITOR>PHYSIO.MAC.120, 17-Aug-77 18:26:57, Edit by MCLEAN
;ADD RM03
;<2BOSACK>PHYSIO.MAC.119,  5-Jul-77 03:18:33, EDIT BY BOSACK
;FINAL READ PREFERENCE SCHEME
;<2BOSACK>PHYSIO.MAC.118, 15-Jun-77 16:46:34, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.117,  7-Jun-77 00:46:42, EDIT BY BOSACK
;FIX BUGS IN HUNG TERMINATION WITH DISK AND TAPE ON SAME CHANNEL
;<3-MONITOR>PHYSIO.MAC.116, 31-May-77 17:21:36, EDIT BY HELLIWELL
;FIX BUG IN DRMINI FOR PHYSICAL DRUM
;<3-MONITOR>PHYSIO.MAC.115,  5-May-77 17:05:01, Edit by HESS
;ADD PHYPOS - RETURN MAGTAPE POSTION INFO
;<3-MONITOR>PHYSIO.MAC.114,  2-May-77 18:47:35, EDIT BY HURLEY
;<3-MONITOR>PHYSIO.MAC.113,  2-May-77 15:44:33, EDIT BY KIRSCHEN
;TCO 1790 - DO NOT MOUNT STR'S WITH WRITE-LOCKED UNIT
;<2BOSACK>PHYSIO.MAC.112,  2-Apr-77 19:54:36, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.111,  1-Apr-77 22:00:18, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.110,  1-Apr-77 21:45:57, EDIT BY BOSACK
;MORE BLOCKTYPE CODE
;<2BOSACK>PHYSIO.MAC.109,  1-Apr-77 21:01:09, EDIT BY BOSACK
;REMOVE ALL CHECKS FOR A PARTICULAR UNIT TYPE
;<3-MONITOR>PHYSIO.MAC.108, 24-Mar-77 02:03:26, Edit by MCLEAN
;<3-MONITOR>PHYSIO.MAC.107, 24-Mar-77 01:52:31, Edit by MCLEAN
;<3-MONITOR>PHYSIO.MAC.106, 24-Mar-77 01:29:17, Edit by MCLEAN
;ADD GLOBAL SYMBOLS FOR DIAG JSYS
;<3-MONITOR>PHYSIO.MAC.105, 24-Mar-77 00:39:21, Edit by MCLEAN
;REMOVE DIAG JSYS TO ITS OWN MODULE
;<3-MONITOR>PHYSIO.MAC.104, 14-Mar-77 17:29:06, EDIT BY BOSACK
;TCO 1757 - FIX DOP%EO TO WORK IN ALL CASES 
;<3-MONITOR>PHYSIO.MAC.103, 13-Mar-77 03:14:44, Edit by MCLEAN
;ADD DGFKIL AS RET FOR SM10
;<3-MONITOR>PHYSIO.MAC.103, 23-Feb-77 19:55:36, EDIT BY HALL
;TCO 1740 - CHANGE CHECK OF TTICT TO CALL INTO TTYSRV
;<3-MONITOR>PHYSIO.MAC.101, 15-Feb-77 17:27:12, EDIT BY BOSACK
;TURN ILUST1 INTO A BUGHLT
;<3-MONITOR>PHYSIO.MAC.100, 15-Feb-77 15:12:25, EDIT BY BOSACK
;TCO 1735 - FIX POSSIBLE FAILURE OF CLOSE/ABORT
;<3-MONITOR>PHYSIO.MAC.98,  9-Feb-77 15:06:41, EDIT BY BOSACK
;CAUSE INITIALIZATION ALLOCATOR TO USE COMMON FREEPOOL
;<3-MONITOR>PHYSIO.MAC.97,  8-Feb-77 14:49:00, Edit by MCLEAN
;CHANGE XBLTMU TO CALL BLTMU
;<3-MONITOR>PHYSIO.MAC.96,  4-Feb-77 15:29:56, Edit by MCLEAN
;<3-MONITOR>PHYSIO.MAC.95,  4-Feb-77 13:24:15, Edit by MCLEAN
;<3-MONITOR>PHYSIO.MAC.94, 19-Jan-77 19:37:42, Edit by MCLEAN
;<3-MONITOR>PHYSIO.MAC.93, 17-Jan-77 14:34:53, Edit by MCLEAN
;<3-MONITOR>PHYSIO.MAC.92, 27-Dec-76 17:36:16, EDIT BY HURLEY
;<3-MONITOR>PHYSIO.MAC.91, 27-Dec-76 17:28:32, EDIT BY HURLEY
;<3-MONITOR>PHYSIO.MAC.90, 27-Dec-76 14:20:09, EDIT BY MILLER
;FIX TYPEO AT UDSKIO+A BUNCH. A MOVE SHOULD BE A MOVEI
;<2BOSACK>PHYSIO.MAC.89, 23-Dec-76 15:04:02, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.88, 23-Dec-76 11:46:40, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.87, 22-Dec-76 17:40:25, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.86, 22-Dec-76 17:33:20, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.85, 22-Dec-76 17:24:03, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.84, 19-Dec-76 21:37:34, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.83, 19-Dec-76 20:59:11, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.82, 19-Dec-76 20:56:23, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.81, 19-Dec-76 20:33:12, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.80, 19-Dec-76 20:27:00, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.79, 19-Dec-76 20:16:14, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.78, 14-Dec-76 12:09:22, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.77, 14-Dec-76 12:07:29, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.76, 13-Dec-76 16:29:14, EDIT BY BOSACK
;TCO 1684 - ADD CODE TO CHECK HOME BLOCKS ON OFFLINE/ONLINE TRANSITION
;<2BOSACK>PHYSIO.MAC.75, 13-Dec-76 16:13:58, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.74,  7-Dec-76 14:22:28, EDIT BY BOSACK
;<3-MONITOR>PHYSIO.MAC.80, 19-Dec-76 00:18:56, Edit by MCLEAN
;<3-MONITOR>PHYSIO.MAC.79, 10-Dec-76 01:21:09, Edit by MCLEAN
;<3-MONITOR>PHYSIO.MAC.78,  9-Dec-76 15:09:48, Edit by MCLEAN
;<3-MONITOR>PHYSIO.MAC.77,  1-Dec-76 21:22:07, Edit by MCLEAN
;<3-MONITOR>PHYSIO.MAC.76,  1-Dec-76 17:20:14, Edit by MCLEAN
;<3-MONITOR>PHYSIO.MAC.75,  1-Dec-76 03:13:21, Edit by MCLEAN
;<3-MONITOR>PHYSIO.MAC.74, 25-Nov-76 02:30:27, Edit by MCLEAN
;TCO 1669 EXTENDED ADDRESSING
;<2-MONITOR>PHYSIO.MAC.73, 23-Nov-76 19:10:20, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.72, 16-Nov-76 19:47:55, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.71,  7-Nov-76 22:12:04, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.70,  6-Nov-76 23:40:27, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.69,  5-Nov-76 17:54:05, EDIT BY BOSACK
;<2-MONITOR>PHYSIO.MAC.61, 31-Oct-76 17:21:25, EDIT BY HELLIWELL
;<2-MONITOR>PHYSIO.MAC.60, 31-Oct-76 17:19:26, EDIT BY HELLIWELL
;CHANGES FOR PHYS4
;<2BOSACK>PHYSIO.MAC.67,  5-Nov-76 14:44:32, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.66, 29-Oct-76 17:36:04, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.65, 29-Oct-76 13:55:31, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.64, 29-Oct-76 13:49:24, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.63, 26-Oct-76 15:45:11, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.62, 24-Oct-76 16:35:50, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.61, 21-Oct-76 14:16:07, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.60, 18-Oct-76 18:12:31, EDIT BY BOSACK
;<2-MONITOR>PHYSIO.MAC.56,  7-Oct-76 15:25:52, EDIT BY KIRSCHEN
;<2-MONITOR>PHYSIO.MAC.55, 16-Sep-76 14:14:10, EDIT BY KIRSCHEN
;MAKE GETSTR RETURN UNIT TYPE IN T2
;<2-MONITOR>PHYSIO.MAC.54, 29-Jul-76 14:07:06, EDIT BY MILLER
;MAKE UDWDON INTERNAL
;<2-MONITOR>PHYSIO.MAC.53, 23-Jul-76 09:34:52, EDIT BY KIRSCHEN
;LIGHT MS%DIA IF UNIT IN MAINT MODE, NOT MS%MNT ! (GETSTR ROUTINE)
;<2-MONITOR>PHYSIO.MAC.52, 16-Jul-76 10:01:50, EDIT BY KIRSCHEN
;<2-MONITOR>PHYSIO.MAC.51, 15-Jul-76 11:04:03, EDIT BY KIRSCHEN
;MAKE STRCHK CHECK THAT UNIT IS A DISK
;<2-MONITOR>PHYSIO.MAC.50, 13-Jul-76 15:35:29, EDIT BY KIRSCHEN
;FIX BUGS IN STPCHN, CHANGE CALLING SEQUENCE FOR GETSTR
;<2-MONITOR>PHYSIO.MAC.49,  9-Jul-76 12:26:19, EDIT BY KIRSCHEN
;RETURN SPECIFIC ERROR CODE FROM STRCHK IF UNIT ALREADY IN A STRUCTURE
;<2-MONITOR>PHYSIO.MAC.48,  9-Jul-76 10:59:56, EDIT BY KIRSCHEN
;MAKE STPUNI NOT STEP TO NON-DISK UNITS
;<2-MONITOR>PHYSIO.MAC.47,  8-Jul-76 10:43:16, EDIT BY KIRSCHEN
;ADD SUPPORT ROUTINES FOR MSTR JSYS
;<2-MONITOR>PHYSIO.MAC.46,  7-Jul-76 10:17:14, EDIT BY KIRSCHEN
;RETURN UNIT TYPE FROM STRCHK
;<2-MONITOR>PHYSIO.MAC.45, 30-Jun-76 10:33:54, EDIT BY KIRSCHEN
;FIX BUG IN SETSTR (USE PHYSICAL UNIT TO GET UDB, NOT UNIT WITHIN STRUCTURE)
;<2BOSACK>PHYSIO.MAC.56,  5-Aug-76 01:33:18, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.55,  2-Aug-76 12:21:19, EDIT BY MURPHY
;<2BOSACK>PHYSIO.MAC.54, 31-Jul-76 22:30:32, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.53, 29-Jul-76 16:06:28, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.52, 29-Jul-76 15:34:51, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.51, 28-Jul-76 03:54:52, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.50, 28-Jul-76 01:41:14, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.49, 28-Jul-76 00:00:20, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.48, 27-Jul-76 23:41:18, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.47, 27-Jul-76 23:34:38, EDIT BY BOSACK
;<2BOSACK>PHYSIO.MAC.46, 27-Jul-76 23:21:48, EDIT BY BOSACK
;HERE START THE INITIAL LATENCY OPTIMIZATION EDITS
;<1B-MONITOR>PHYSIO.MAC.45, 29-APR-76 16:10:59, EDIT BY BOSACK
;<2MONITOR>PHYSIO.MAC.44, 30-MAR-76 05:41:49, EDIT BY BOSACK
;<2MONITOR>PHYSIO.MAC.43, 30-MAR-76 04:47:48, EDIT BY BOSACK
;<2MONITOR>PHYSIO.MAC.42, 30-MAR-76 04:06:26, EDIT BY BOSACK
;TCO 1269 - ADD RP05/6 SUPPORT
;<2-MONITOR>PHYSIO.MAC.13, 15-JUN-76 13:30:41, EDIT BY KIRSCHEN
;FIX BUG IN STRCHK
;<2-MONITOR>PHYSIO.MAC.12,  9-JUN-76 09:27:39, EDIT BY MILLER
;<1MILLER>PHYSIO.MAC.1,  8-JUN-76 12:17:42, EDIT BY MILLER
;REMOVE CST4. ADD REFERENCES TO CSTLDA
;<2-MONITOR>PHYSIO.MAC.11,  7-JUN-76 11:14:48, EDIT BY KIRSCHEN
;<2-MONITOR>PHYSIO.MAC.10,  2-JUN-76 12:41:50, EDIT BY KIRSCHEN
;ADD CLRSTR ROUTINE
;<2-MONITOR>PHYSIO.MAC.9, 28-MAY-76 09:36:27, EDIT BY KIRSCHEN
;<2-MONITOR>PHYSIO.MAC.8, 28-MAY-76 09:27:47, EDIT BY KIRSCHEN
;ADD STRCHK ROUTINE TO VALIDATE ARGUMENTS DURING STRUCTURE MOUNTING
;<2-MONITOR>PHYSIO.MAC.7, 26-MAY-76 12:43:20, EDIT BY HALL
;ADDED COMMENT ABOUT DSKSIZ
;<2-MONITOR>PHYSIO.MAC.6, 25-MAY-76 14:23:16, EDIT BY KIRSCHEN
;ADD SETSTR ROUTINE
;<HALL>PHYSIO.MAC.1, 18-MAY-76 16:55:31, EDIT BY MILLER
;REPLACE NSECTK WITH PROPER SDB VALUES IN GETCUB ROUTINE
;<2-MONITOR>PHYSIO.MAC.4,  5-MAY-76 15:32:04, EDIT BY MILLER
;<2-MONITOR>PHYSIO.MAC.3,  3-MAY-76 11:44:00, EDIT BY BOSACK
;<2-MONITOR>PHYSIO.MAC.2, 19-APR-76 10:30:36, EDIT BY MILLER
;<2-MONITOR>PHYSIO-1B.ORIGINAL.2, 14-APR-76 10:36:19, EDIT BY MILLER
;<2MONITOR>PHYSIO.MAC.44, 30-MAR-76 05:41:49, EDIT BY BOSACK
;<2MONITOR>PHYSIO.MAC.43, 30-MAR-76 04:47:48, EDIT BY BOSACK
;<2MONITOR>PHYSIO.MAC.42, 30-MAR-76 04:06:26, EDIT BY BOSACK
;TCO 1270 - ADD RP05/6 SUPPORT
;<2MONITOR>PHYSIO.MAC.41, 25-FEB-76 13:39:15, EDIT BY BOSACK
;TCO 1100 - FIX BUGHLT ILTWQP AT IRBERR UNDER HEAVY SWAP LOAD
;<2MONITOR>PHYSIO.MAC.40, 16-FEB-76 02:31:19, EDIT BY BOSACK
;<2MONITOR>PHYSIO.MAC.39, 13-FEB-76 18:12:37, EDIT BY BOSACK
;<2MONITOR>PHYSIO.MAC.38, 13-FEB-76 18:07:43, EDIT BY BOSACK
;<2MONITOR>PHYSIO.MAC.37, 13-FEB-76 17:04:25, EDIT BY BOSACK
;<2MONITOR>PHYSIO.MAC.36, 13-FEB-76 16:33:03, EDIT BY BOSACK
;TCO 1091 - FIX SINGLE UNIT ASSIGN IN DIAG
;<2MONITOR>PHYSIO.MAC.35, 29-JAN-76 16:25:41, EDIT BY BOSACK
;TCO 40 - FIX DEADLOCK BY ADDING MORE UDSKIO IORBS
;<2MONITOR>PHYSIO.MAC.34, 29-JAN-76 16:10:44, EDIT BY BOSACK
;<2MONITOR>PHYSIO.MAC.33, 19-JAN-76 12:24:28, EDIT BY MURPHY
;<2MONITOR>PHYSIO.MAC.32,  7-JAN-76 16:35:26, EDIT BY BOSACK
;<PHYSIO>PHYSIO.MAC.146, 20-NOV-75 01:48:38, EDIT BY BOSACK


;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976, 1977, 1978 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.

	SEARCH PROLOG,PHYPAR,SERCOD
; A SEARCH OF PROKL IS DONE HERE BECAUSE THE DEFINITONS
;OF CHNOFF AND CHNON ARE NEEDED AND PROKL IS A SUPERSET
;OF PROKS.  IN THE FUTURE IT SHOULD BE POSSIBLE TO REMOVE
;THIS SEARCH AFTER THE PI SYSTEM OF THE KL IS FIXED.
	SEARCH PROKL
	TTITLE(PHYSIO,,< - DEVICE INDEPENDENT PHYSICAL IO>)
	SUBTTL L.BOSACK 17-MAY-75
	RESCD

EXTERN MAXCHN,PHYCHL,PHYCHT,PHYPZS,ZSEND,CST5
EXTERN PHYACS,PHYIPD,PHYPDL,PHYSVP,UDIORB,UIOLST
EXTERN CHNTAB,PHYEBL

;LATENCY OPTIMIZATION PARAMETERS

MINLAT==^D2700		;2.7MS SAFETY FACTOR
INIFCX==^D40		;INITIAL FAIRNESS COUNT FOR XFRS
			;DO A ROUND ROBIN CHANNEL SCHEDULE CYCLE
			;EVERY INFCX TRANSFERS. WHEN A CHANNEL GOES
			;IDLE, RESET THE COUNT.
INIFCP==^D40		;INITIAL FAIRNESS COUNT FOR POSITIONING
			;AT MOST INIFCP TRANSFERS WILL BE APPENDED
			;TO THE END OF A UNITS TRANSFER QUEUE IF
			;THERE ARE REQUESTS TO OTHER CYLINDERS
INIFCR==^D15		;INITIAL FAIRNESS COUNT FOR READ SEEK PREFERENCE
			;FOR INIFCR SEEK SCHEDULE CYCLES READS WILL
			;BE ABSOLUTLY PREFERABLE TO WRITES

;GLOBAL BYTE POINTERS

IRYFCN::POINT ISSFCN,IRBSTS(P4),ISPFCN ;IORB FUNCTION CODE
IRYMOD::POINT IMSMOD,IRBMOD(P4),IMPMOD ;IORB MODE

USYTYP::POINT USSTYP,UDBSTS(P3),USPTYP ;UNIT TYPE
CSYTYP::POINT CSSTYP,CDBSTS(P1),CSPTYP ;CHANNEL TYPE
CSYPIA::POINT CSSPIA,CDBSTS(P1),CSPPIA ;PI ASSIGNMENT
USYBKT::POINT XSSTYP,UDBSTS(P3),XSPTYP	;BLOCK TYPE FROM P3

;TABLE OF BYTES PER WORD AS A FUNCTION OF MODE

MODTAB::EXP -1			;ILLEGAL
	EXP 1			;WORD MODE
	EXP 6			;6 BIT MODE
	EXP 5			;7 BIT MODE
	EXP 4			;8 BIT MODE

;TABLE OF UNIT TYPES USABLE BY THE FILESYSTEM
;NOTE: WHEN ADDING AN ENTRY TO THIS TABLE, BE SURE TO ADD A CORRESPONDING
;ENTRY IN DSKSIZ (DEFINED IN STG) TO INDICATE THE SIZE OF THE DISK

DSKUTP::EXP .UTRP4		;RP04
	EXP .UTRP5		;RP05
	EXP .UTRP6		;RP06
	EXP .UTRM3		;RM03
NDSKUT==:.-DSKUTP
;TABLE OF POINTER TO UNIT PHYSICAL SIZE PARAMETERS - THE TABLE ARE
;DEFINED IN STG


DSKSIZ::DSKSZ0			;RP04
	DSKSZ0			;RP05
	DSKSZ1			;RP06
	DSKSZ3			;RM03

;TABLE OF UNIT TYPE NAMES

NAMUTP::POINT 7,[ASCIZ /(ILLEGAL TYPE:0)/]
	POINT 7,[ASCIZ /RP04/]
	POINT 7,[ASCIZ /RS04/]
	POINT 7,[ASCIZ /TU45/]
	POINT 7,[ASCIZ /TM02/]
	POINT 7,[ASCIZ /RP05/]
	POINT 7,[ASCIZ /RP06/]
	POINT 7,[ASCIZ /RP07/]
	POINT 7,[ASCIZ /RP08/]
	POINT 7,[ASCIZ /RM03/]
	POINT 7,[ASCIZ /TM03/]
	POINT 7,[ASCIZ /TU77/]
	POINT 7,[ASCIZ /TM78/]
	POINT 7,[ASCIZ /TU78/]
	POINT 7,[ASCIZ /DX20/]
	POINT 7,[ASCIZ /TU70/]
	POINT 7,[ASCIZ /TU71/]
	POINT 7,[ASCIZ /TU72/]
	POINT 7,[ASCIZ /TU73/]
;INITIALIZATION - CALLED BEFORE PGRRST SO RESIDENT STORAGE CAN BE ASSIGNED
;WIPES THE ACCUMULATORS

PHYINI::MOVSI Q1,PHYCHL		;GET LENGTH OF CHANNEL SERVICE TABLE
	MOVEI P4,0		;FIRST FREE SLOT IN CHANTAB
PHYIN2:	HRRZ T1,PHYCHT(Q1)	;GET DISPATCH ADDRESS
	PUSH P,Q1		;SAVE OVER CALL
	CALL CDSINI(T1)		;CALL TO INITIALIZE ALL CHANNELS OF THIS TYPE
	POP P,Q1		;RESTORE AOBJN POINTER
	MOVEM P4,MAXCHN		;FREE SLOT UPDATED
	AOBJN Q1,PHYIN2		;LOOP FOR ALL TYPES LOADED

	MOVEI T1,UIOLEN*<NUIORB-1>+UDIORB ;INITIALIZE IORB FREE LIST
	SETZM (T1)		;CLEAR END OF LIST
PHYIN3:	CAIN T1,UDIORB		;DONE?
	JRST PHYIN4		;YES
	MOVE T2,T1		;NO - SAVE SUCCESSOR
	SUBI T1,UIOLEN		;MOVE BACKWARD IN LIST
	MOVEM T2,(T1)		;STORE FOREWARD POINTER
	JRST PHYIN3

PHYIN4:	MOVEM T1,UIOLST		;STORE HEAD OF LIST
	SETOM DIAGLK		;INITIALIZE LOCK TO FREE
	RET

;UTILITY TO SET UP AND INITIALIZE A UDB
;T3/ DISPATCH ADDRESS,,LENGTH OF UDB
;Q2/ UNIT NUMBER
;P1/ CDB
;RETURNS +1(ON FAILURE):
;RETURNS +2 (SUCCESS)
;P3/ UDB ADDRESS

PHYUDB::HRRZ T1,T3		;LENGTH OF UDB
	PUSHJ P,PHYALC		;ALLOCATE STORAGE
	RET			;NONE FOUND
	MOVE P3,T1		;UDB POINTER TO P3
	HLRZ T1,T3		;DISPATCH ADDRESS
	MOVEM T1,UDBDSP(P3)	;SET UP IN UDB
	MOVEI T1,.BTUDB		;MARK AS UDB
	DPB T1,USYBKT		; ...
	HRRZM P1,UDBCDB(P3)	;SET UP CDB ADDRESS
	HRRZM Q2,UDBADR(P3)	;THIS UNITS ADDRESS ON CHANNEL
	HRL Q2,P1		;CDB,,UNIT #
	MOVEM Q2,UDBAKA(P3)	;AKA TEMPORARY SETUP
	HRRZ Q2,Q2		;RESTORE Q2
	MOVSI T1,UDBPWQ(P3)	;MAKE EMPTY QUEUES
	MOVEM T1,UDBPWQ(P3)	;POSITION WAIT QUEUE
	MOVSI T1,UDBTWQ(P3)
	MOVEM T1,UDBTWQ(P3)	;TRANSFER WAIT QUEUE
	MOVEI T1,-1		;SET POSITIONS TO UNKNOWN
	MOVEM T1,UDBPS1(P3)	; ...
	MOVEM T1,UDBPS2(P3)	; ...
	SETOM UDBSTR(P3)	;NOT ASSIGNED TO A STRUCTURE
	RETSKP
;ALLOCATORS FOR USE DURING INITIALIZATION ONLY

;ALLOCATE RESIDENT STORAGE
;T1/ LENGTH OF BLOCK IN WORDS, ASSUMED LESS THAN PGSIZ
;	CALL PHYALC
;RETURNS+1:	ON FAILURE,
;RETRUNS+2:	SUCCESS,
;T1/ ADDRESS OF START OF BLOCK
;PRESERVES T3,T4

PHYALC::JUMPLE T1,INIERR	;CHECK ARG
	PUSH P,T3		;PRESERVE REGS
	PUSH P,T4		; ...
	HRLI T1,.RESP1		;PRIORITY
	MOVEI T2,.RESGP		;GENERAL CLASS
	CALL ASGRES		;GET STG
	JRST [ BUG(INF,PHYICE,<PHYINI - FAILED TO ASSIGN RESIDENT STG>)
		   SOS 0(P)
		   JRST .+1]
	POP P,T4		;RESTORE REGS
	POP P,T3		; ...
	RETSKP

;ALLOCATE RESIDENT PAGE 0 STORAGE (DISPATCH VECTORS, ETC.)
;T1/ ALIGNMENT,,LENGTH
;	CALL PHYALZ
;RETURNS+1:	ALWAYS,
;T1/ ADDRESS OF START OF BLOCK, A MULTIPLE OF LH(T1) ON CALL.
;	SPECIFYING A ZERO ALIGNMENT IS EQUIVALENT TO AN ALIGNMENT OF 1

PHYALZ::JUMPLE T1,INIERR	;ILLEGAL ARGUMENT
	HLRZ T4,T1		;SAVE ALIGNMENT
	SKIPN T4		;ZERO SPECIFIED?
	MOVEI T4,1		;YES - USE 1
	HRRZ T3,T1		;SAVE LENGTH
	MOVE T1,ZSEND		;GET CURRENT FREE BOUNDRY
	IDIV T1,T4		;GET BOUNDRY MOD C(T4)
	MOVE T1,T4		;COMPUTE ALIGN-(ZSEND MOD ALIGN)
	SUB T1,T2		; ...
	SKIPE T2		;IF ALREADY ALIGNED, SKIP IT.
	ADDM T1,ZSEND		;ALIGN ZSEND
	MOVE T1,ZSEND		;RETURN START OF BLOCK
	ADDB T3,ZSEND		;UPDATE BOUNDRY
	SUBI T3,PHYPZS		;SEE IF OVERFLOW
	CAILE T3,PZSSIZ		; ...
	BUG(HLT,PHYP0E,<PHYALZ - PAGE 0 STORAGE EXHAUSTED>)
	RET

;HERE WHEN GIVEN AN ILLEGAL ARGUMENT TO ALC OR ALZ

INIERR:	BUG(HLT,PHYICA,<PHYINI - ILLEGAL ARGUMENT TO CORE ALLOC>)
;RESTART ENTRY
;ENTERED WITH PI OFF, STACK IN P, ALL ACCUMULATORS FREE.

PHYRST::MOVSI Q3,-CHNN		;BUILD AOBJN POINTER
RST1:	SKIPN P1,CHNTAB(Q3)	;CHANNEL PRESENT?
	JRST RST2		;NO
	PUSH P,Q3		;SAVE CHANNEL COUNTER
	CALL DGUMAP		;FOR ALL UNITS ON THIS CHANNEL
	 CALL ABTREQ		;ABORT REQUESTS
	POP P,Q3		;RESTORE CHANNEL COUNTER
	MOVSI T1,(CS.ACT!CS.MAI!CS.ERC) ;CLEAR STATE BITS
	ANDCAM T1,CDBSTS(P1)	; ...
	MOVEI T1,1		;INDICATE FULL RESET
	HRRZ T2,CDBDSP(P1)	;GET CHANNEL DISPATCH
	CALL CDSRST(T2)		;RESET HARDWARE
RST2:	AOBJN Q3,RST1		;LOOP FOR ALL CHANNELS
	RET

;HERE TO ABORT THE REQUESTS ON A PARTICULAR UNIT

ABTREQ:	HRRZ P4,UDBTWQ(P3)	;ANY TRANSFER REQUESTS?
	JUMPE P4,ABT1		;NO MORE
	CALL OFFTWQ		;PULL FROM TWQ
	CALL ABT3		;POST DONE IF NEEDED
	JRST ABTREQ		;LOOP FOR MORE

ABT1:	HRRZ P4,UDBPWQ(P3)	;ANY POSITION REQUEST?
	JUMPE P4,ABT2		;NO MORE
	CALL OFFPWQ		;REMOVE FROM PWQ
	CALL ABT3		;AND POST COMPLETE IF NEEDED
	JRST ABT1		;LOOP FOR MORE

ABT2:	MOVSI T1,(US.BLK!US.REW!US.OIR!US.OMS) ;THINGS TO RESET ABOVE
	ANDCAM T1,UDBSTS(P3)	;WHAT CLRACT RESETS
	CALL CLRACT		;RESET UDB
	RET

ABT3:	MOVSI T1,(IS.SHT)	;PAGEM REQUEST?
	TDNE T1,IRBSTS(P4)	;?
	RET			;YES, IGNORE
	MOVSI T1,(IS.ERR!IS.NRT) ;INDICATE ERROR
	IORM T1,IRBSTS(P4)	; ..
	CALL DONIRB		;POST COMPLETE
	RET			;DONE WITH THIS REQUEST
;ONLINE ENTRY - ENTERED ON THE ONLINE INTERRUPT OF A UNIT

PHYONL::MOVSI T1,(US.OFS)	;CLEAR OFFLINE AND UNSAFE BITS
	ANDCAM T1,UDBSTS(P3)	; ...
	RET

;HERE ON REWIND DONE.

PHYRWD::SAVEQ			;SAVE ALL Q'S
	MOVSI T1,(US.REW)	;NO LONGER REWINDING
	ANDCAM T1,UDBSTS(P3)	; ...
	IOPIOF			; INTERLOCKED
	CALL SCHSEK		;START ANY POSITION OPS
	MOVSI T1,(CS.ACT!CS.ERC) ;CHAN AVAIL
	TDNE T1,CDBSTS(P1)	;CHANNEL ACTIVE?
	JRST ONRET		;YES - NO ACTION NEEDED.
	CALL SCHXFR		;START CHANNEL
	JRST ONRET		;AND RETURN
;HERE WHEN THE INTERRUPTING DEVICE HAS BEEN DETERMINED
;ENTERED WITH CDB IN P1, P1 SAVED IN CDBSVQ

PHYINT::MOVEM 17,PHYACS+17	;SAVE HIGH ACCUMULATOR
	MOVEI 17,PHYACS		;SETUP BLT POINTER
	BLT 17,PHYACS+16	;SAVE REMAINING ACCUMULATORS
	MOVE T1,CDBSVQ(P1)	;COPY P1 FROM WHERE SAVED
	MOVEM T1,PHYACS+P1	;STORE WITH REST
	MOVE P,[IOWD LPHIPD,PHYIPD] ;GET INTERRUPT PDL
	HRRZ T1,CDBDSP(P1)	;GET CHANNEL DISPATCH
;NOTE THAT INTERRUPT ROUTINES DO NOT PRESERVE P OR Q ACCUMULATORS TO SAVE TIME
	CALL CDSINT(T1)		;PASS INTERRUPT DOWNWARD
	 JRST [	MOVSI T1,(CS.AC2) ;AN ERROR WAS DETECTED, CHANNEL SHUT
		ANDCAM T1,CDBSTS(P1) ;DOWN STACKED COMMAND
		JRST .+1]
	JUMPE P4,XINT		;REQUEST TO DISMISS
	JUMPL P4,[ MOVSI T1,(CS.ERC) ;REQUEST FOR SCHEDULE CYCLE,
		TDNN T1,CDBSTS(P1) ;IS CHANNEL IN ERR RECOV?
		JRST INT1	;NO - HONOR REQUEST
		JRST XINT]	;YES - SCHED AT END OF ERR RECOV
	HLL P3,UDBSTS(P3)	;SET UP LEFT HALF FOR SOME TESTS
	HRRZ T1,UDBTWQ(P3)	;CHECK IF THIS IS THE
	TLNE P3,(US.POS)	;IORB WE EXPECTED
	HRRZ T1,UDBPWQ(P3)	;FROM EITHER QUEUE
	CAIE T1,(P4)		;??
	BUG(HLT,ILTWQ,<PHYINT - TWQ OR PWQ INCORRECT>) ;NO.
	SKIPE UDBERR(P3)	;ERROR RECOVERY IN PROGRESS?
	JRST INTERR		;YES - MUST CALL LOWER LEVEL IN ALL CASES
	MOVE T1,IRBSTS(P4)	;YES - ANY ERROR INDICATION?
	TLNN T1,(IS.ERR!IS.WGU!IS.DTE!IS.DVE!IS.RTL) ;??
	JRST INTDON
INTERR:	SKIPN T1,UDBERP(P3)	;ERRORS - ERROR BLOCK SETUP?
	JRST [	MOVSI T1,(CS.ERC) ;NO - SET ERR RECOV ON CHANNEL
		TLNN P3,(US.POS) ;TRANSFER?
		IORM T1,CDBSTS(P1) ;YES
		CALL ERRSET	;CREATE ERROR BLOCK
		JRST .+1]	;CONTINUE
	MOVEM T1,UDBERP(P3)	;STORE IN UDB
	MOVE T1,UDBDSP(P3)	;GET UNIT DISPATCH
	CALL UDSERR(T1)		;INVOKE ERROR RETRY
	 JRST XINT		;NON SKIP - RETRY IN PROGRESS
				;SKIP - DONE WITH RECOVERY, FOR GOOD OR ILL
	MOVSI T1,(CS.ERC)	;SETUP TO CLEAR ERROR RECOVERY FLAG
	TLNN P3,(US.POS)	;TRANSFER?
	ANDCAM T1,CDBSTS(P1)	;YES - CLEAR FLAG
INTDON:	TLNE P3,(US.POS)	;TAKE REQUEST OUT OF QUEUE
	JRST INT2		;HANDLE TERMINATION IN POSITIONING
	MOVSI T1,(CS.AC2)	;IS THIS A STACKED COMMAND
	TDNE T1,CDBSTS(P1)	; ??
	JRST INT3		;YES
	CALL OFFTWQ		;PULL FROM TWQ
	CALL CLRACT		;NO LONGER ACTIVE
	CALL DONIRB		;POST IORB AS DONE
	SKIPE PWRDWN		;POWER FAILING?
	JRST XINT		;YES - DISMISS
INT1:	CALL SCHSEK		;SCHEDULE SEEKS (IF NEEDED)
	CALL SCHXFR		;SCHEDULE TRANSFERS
XINT:	MOVSI P,PHYACS		;RESTORE BLT POINTER
	JRST CDBJEN(P1)		;RESTORE ACCUMULATORS AND DISMISS

;HERE WHEN AN IORB TERMINATES ON THE PWQ

INT2:	CALL OFFPWQ		;PULL FROM QUEUE
	CALL CLRPOS		;NO LONGER POSITIONING
	CALL DONIRB		;POST DONE
	CALL SCHSEK		;SEE IF MORE TO DO
	MOVSI T1,(CS.ACT!CS.ERC) ;CHANNEL NOW BUSY?
	TDNN T1,CDBSTS(P1)	; ???
	SKIPN PWRDWN		;OR POWER FAIL?
	CALL SCHXFR		;NO - SEE IF ANY WORK
	JRST XINT		;THEN EXIT

;HERE AT THE TERMINATION OF A STACKED TRANSFER

INT3:	ANDCAM T1,CDBSTS(P1)	;CLEAR SECOND COMMAND ACTIVE
	CALL OFFTWQ		;PULL FROM TWQ
	CALL DONIRB		;POST DONE
	SKIPN PWRDWN		;POWER FAILING?
	CALL SCHXFR		;NO - SEE IF MORE WORK TO DO
	JRST XINT		;AND DISMISS
;HERE TO POST AN IORB COMPLETE
;P4/ IORB
;	CALL DONIRB
;RETURNS+1(ALWAYS)

DONIRB:	MOVSI T1,(IS.DON)	;FLAG DONE
	MOVSI T2,(IS.WGU!IS.TPM!IS.EOT!IS.DTE!IS.DVE!IS.BOT!IS.RTL)
	TDNE T2,IRBSTS(P4)	;CHECK ERRORS
	TLO T1,(IS.ERR)		;AND INDICATE EXCEPTION
	IORM T1,IRBSTS(P4)	; ...
	CALL ERRFIN		;TERMINATE ERROR RECOVERY IF NEEDED
	SKIPL IRBSTS(P4)	;SHORT IORB?
	JRST DONIR1		;NO - CALL SPECIFIED ADDRESS
	MOVEI T1,-CST5(P4)	;GET CPN
	MOVSI T2,(IS.WGU!IS.DTE!IS.DVE!IS.RTL) ;IF ANY OF THESE ERRORS
	MOVSI T3,(SWPERR)	;NOTIFY PAGEM
	TDNE T2,IRBSTS(P4)	; CHECK.
	IORM T3,CST3(T1)	;ERRORS - INDICATE TO PAGEM.
	PUSH P,P1		;SAVE REGISTERS
	PUSH P,P3		; ...
	CALL SWPDON		;NOTIFY PAGEM
	POP P,P3		;RESTORE REGISTERS
	POP P,P1		; ..
	RET

;HERE ON COMPLETION OF A LONG IORB

DONIR1:	HRRZ T2,IRBIVA(P4)	;GET CALLERS INTERRUPT ADDRESS
	JUMPE T2,DONIR2		;IS THERE AN INTERRUPT ROUTINE?
	MOVE T1,P4		;COPY IORB FOR CALL
	CALL (T2)		;CALL
	RET

DONIR2:	BUG(CHK,PHYNIR,<PHYSIO - NULL INTERRUPT ROUTINE AT OPERATION DONE>)
	RET
	SUBTTL START IO
;HERE TO ENQUEUE AN IO REQUEST.
;T1/ IORB
;T2/ CDB,,UDB
;	CALL PHYSIO
;RETURNS+1:(ALWAYS)
;	IO REQUEST MADE. IF UNIT IS OFFLINE, A MESSAGE TO THE
;	OPERATOR WILL BE PRINTED. IF THE CALL IS IN ANY WAY
;	INVALID (NONEXISTANT UNIT, BAD ADDRESS, ETC.) A BUGHLT WILL OCCUR
;	THE CALLING ROUTINE IS ASSUMED TO HAVE MADE THOSE CHECKS
;	AND PASSED.
;	**NOTE** NOSKED IS ASSUMED, AS A PRIVATE STACK IS USED

PHYSIO::MOVEM P,PHYSVP		;SAVE CALLERS STACK
	MOVE P,[IOWD LPHYPD,PHYPDL] ;LOCAL STACK
	SE0ENT
	CALL SIO1		;DO THE REAL WORK
	MOVE P,PHYSVP		;RESTORE CALLERS STACK
	SE1CAL			;ENTER SECTION 1 BEFORE RETURN
	RET

;DETERMINE CHANNEL/UNIT FOR THIS IORB

SIO1:	SAVEPQ			;SAVE CALLERS REGISTERS ON LOCAL STACK
	MOVE P4,T1		;COPY IORB
	HLRZ P1,T2		;GET CDB
	HRRZ P3,T2		;GET UDB
	SKIPL IRBSTS(P4)	;SHORT IORB?
	JRST SIO2		;NO - CDB AND UDB IN P1 AND P3 ALREADY
	CALL GETCUB		;GET CDB AND UDB FROM PAGEM ADDRESS
	 BUG(HLT,ILPDAR,<PHYSIO - ILLEGAL DISK ADDRESS IN PAGEM REQUEST>)
				;T1 HAS UNIT ADDRESS (LINEAR)
	MOVEI T2,-CST5(P4)	;GET CORE PAGE NUMBER
	STOR T1,CSTLDA,(T2)	;STORE UNIT RELATIVE ADDRESS
SIO2:	HRRZ P2,UDBKDB(P3)	;GET KDB (IF PRESENT)
	HRRZ T2,UDBDSP(P3)	;GET UNIT DISPATCH BASE
	IOPIOF			;TURN PHYSIO CHANNELS OFF
	HLL P3,UDBSTS(P3)	;GET LEFT HALF STATUS OF UNIT
	TLNE P3,(US.POS)	;IS POSITION IN PROGRESS?
	JRST SIO3		;YES - APPEND TO PWQ
	TLNE P3,(US.TAP)	;IS THIS A TAPELIKE DEVICE?
	JRST SIO6		;YES - SEE IF POSITIONING TO DO
	TLNN P3,(US.PRQ)	;DOES THIS UNIT POSITION?
	JRST SIO4		;NO - APPEND TO TWQ
	CALL UDSCNV(T2)		;YES - GET CYLINDER (PS1) IN T2
	CAME T2,UDBPS1(P3)	;SAME AS CURRENT UDBPS1?
	JRST SIO3		;NO - POSITIONING NEEDED
	SOSLE UDBFCT(P3)	;YES - SHOULD WE DO SOME OTHER CYL?
	JRST SIO4		;NO - ADD REQUEST TO TWQ
	HRRZ T1,UDBPWQ(P3)	;COUNT EXHAUSTED, REQUESTS TO OTHER CYLS?
	JUMPE T1,SIO4		;IF NO, APPEND TO TWQ ANYWAY
SIO3:	MOVE T1,P4		;PLACE ON PWQ
	CALL ONPWQ		; ...
	MOVSI T1,(US.OIR!US.OMS!US.POS!US.ACT!US.MAI!US.MRQ!US.REW!US.CHB) ;UNIT IDLE
	MOVSI T2,(CS.MAI!CS.MRQ!CS.OFL) ;ACTIVITY DISABLED ON THIS CHAN?
	TDNN T2,CDBSTS(P1)	; ?
	TDNE T1,UDBSTS(P3)	;OR UNIT ACTIVE
	JRST ONRET		;YES TO EITHER - DO NOTHING
	MOVSI T1,(KS.ACT)	;IS CONTROLLER BUSY?
	TRNE P2,-1		;IS THERE A CONTROLLER?
	TDNN T1,KDBSTS(P2)	; ...
	SKIPA			;(NO,NO)
	JRST ONRET		;(YES,YES)
	HRRZ T1,UDBTWQ(P3)	;ARE THERE ANY TRANSFER PENDING ON CYLINDER?
	JUMPN T1,ONRET		;IF SO, DONT MOVE UNIT
	CALL STRTPS		;UNIT FREE - START POSITIONING
	 JFCL			;COULDNT DO IT, BUT NOTHING ELSE TO DO
	JRST ONRET		;ENABLE PI AND RETURN
;HERE WHEN REQUEST NEEDS NO POSITIONING

SIO4:	MOVE T1,P4		;PLACE ON TWQ
	CALL ONTWQ		; ...
	MOVSI T1,(CS.OFL!CS.AC2!CS.MAI!CS.MRQ) ;AVAILABLE?
	MOVSI T2,(US.OIR!US.OMS!US.POS!US.MAI!US.MRQ!US.REW!US.CHB) ;UNIT ...
	TDNN T2,UDBSTS(P3)	;TEST UNIT.
	TDNE T1,CDBSTS(P1)	; ??
	JRST ONRET		;NO.
	MOVSI T1,(KS.ACT)	;IS CONTROLLER BUSY?
	TRNE P2,-1		;IS THERE A CONTROLLER?
	TDNN T1,KDBSTS(P2)	; ...
	SKIPA			;(NO,NO)
	JRST ONRET		;(YES,YES)
	SKIPE PWRDWN		;POWER FAILING?
	JRST ONRET		;YES - DONT STARTUP A NEW REQUEST
	MOVSI T1,(CS.AC1)	;PRIMARY COMMAND ACTIVE?
	TDNN T1,CDBSTS(P1)	; ???
	JRST SIO5		;NO - SEE IF UNIT REALLY FREE
	MOVE T1,CDBXFR(P1)	;IS THIS THE ACTIVE UNIT?
	CAME T1,UDBADR(P3)	; ???
	JRST ONRET		;NO - DONT TRY CROSS UNIT STACK
	CALL SCHXFR		;SEE IF WE SHOULD START THIS ONE
	JRST ONRET
SIO5:	MOVSI T1,(US.ACT)	;IS THE UNIT REALLY FREE?
	TDNE T1,UDBSTS(P3)	; ???
	JRST ONRET		;NO
	CALL STRTIO		;STARTUP THIS IORB
	 JFCL			;CANT START IT, BUT NOTHING ELSE TO DO.
	JRST ONRET		;RESTORE PI

;HERE TO SEE IF REQUEST SHOULD GO THROUGH POSITION CYCLE

SIO6:	CALL UDSPRQ(T2)		;ASK DEVICE
	 JRST SIO4		;TRANSFER ONLY
	JRST SIO3		;POSITION FIRST
	SUBTTL POSITION DONE
;POSITION DONE - TRANSFER ALL REQUESTS FOR THIS CYLINDER FROM PWQ TO TWQ
;CALLED ONLY AT INTERRUPT LEVEL
;P1/ CDB, P3/ UDB, USES P4

PHYPDN::CALL CLRPOS		;UNIT NO LONGER POSITIONING
	HRRZ P4,UDBPWQ(P3)	;GET HEAD OF PWQ
	CALL ERRFIN		;RETURN ERROR BLOCK IF ONE ACTIVE
	SAVEQ
	MOVEI T1,INIFCP		;RESET FAIRNESS COUNT FOR POSITIONING
	MOVEM T1,UDBFCT(P3)	; ...
	MOVEI Q1,UDBPWQ(P3)	;PREVIOUS IORB IS INITIALLY HEAD CELL
	HRRZ Q2,UDBDSP(P3)	;GET UNIT DISPATCH
	SKIPN P4		;WAS PWQ NULL?
	JRST PDN4		;YES - COMPLAIN THEN EXIT
PDN1:	CALL UDSCNV(Q2)		;GET CYLINDER FOR IORB IN P4
	CAME T2,UDBPS1(P3)	;SAME AS CURRENT CYLINDER?
	JRST PDN3		;NO - KEEP LOOKING
	MOVE T1,Q1		;PREDECESSOR
	MOVE T2,P4		;CURRENT IORB
	CALL CONSPW		;REMOVE CURRENT, SPLICE PWQ
	MOVE T1,P4		;APPEND CURRENT TO TWQ
	CALL ONTWQ		; ...
PDN2:	HRRZ P4,IRBLNK(Q1)	;GET NEW CURRENT IORB
	JUMPN P4,PDN1		;IF NOT AT END, KEEP LOOKING
	HRRZ T1,UDBTWQ(P3)	;CHECK SOME REQUEST WAS FOUND
	SKIPN T1		; ??
	BUG(CHK,NRFTCL,<PHYSIO - NO REQUESTS FOUND FOR CYLINDER SEEKED>)
	RET			;YES - ALL IS WELL

PDN3:	MOVE Q1,P4		;MOVE DOWN THE LIST
	JRST PDN2		;AND CONTINUE

PDN4:	BUG(CHK,NPWQPD,<PHYSIO - NULL PWQ AT POSITION DONE>)
	RET			;JUST EXIT
	SUBTTL UTILITIES

;ENTER WITH 
;T1/ UNIT NUMBER
;P1/ CDB
;	CALL SETUDB
;RETURNS+1(ALWAYS):
;P2/ KDB (IF APPROPRIATE)
;P3/ UDB CORRESPONDING TO SPECIFIED UNIT # ON CHANNEL
;  NOTE: IN THE CASE OF THE TM02, THE KDB WILL BE IN BOTH P2&P3
;T1/ UNCHANGED
;T2/ DISPATCH FOR CORRESPONDING UNIT TYPE

SETUDB::MOVE T2,CDBIUN(P1)	;GET UDB TABLE POINTER
	HLRE T3,T2		;SEE IF LEGAL NUMBER
	MOVNS T3		;AS POSITIVE NUMBER
	CAIL T1,(T3)		;LEGAL?
	BUG(HLT,PYILUN,<PHYSIO - ILLEGAL UNIT NUMBER>)
	ADD T2,T1		;GET UDB
	SKIPN P3,(T2)		; ...
	JRST SETUD2		;NONE PRESENT
	LDB T2,USYBKT		;GET BLOCK TYPE
	CAIE T2,.BTUDB		;UDB?
	JRST SETUD1		;NO
	MOVE P2,UDBKDB(P3)	;GET KDB IF ANY
	HRRZ T2,UDBDSP(P3)	;RETURN DISPATCH
	RET

SETUD1:	MOVE P2,P3		;COPY KDB
	HRRZ T2,KDBDSP(P2)	;AND RETURN DISPATCH
	RET

SETUD2:	SETZB P2,P3		;RETURN 0
	RET

;UTILITY TO RETURN THE ACTIVE IORB ON A UNIT
;P3/ UDB
;	CALL SETIRB
;RETURNS+1(ALWAYS):
;P4/ ACTIVE IORB
;PRESERVES T1


SETIRB::HRRZ P4,UDBPWQ(P3)	;ASSUME POSITIONING
	MOVSI T2,(US.POS)	;IS UNIT REALLY POSITIONING?
	TDNN T2,UDBSTS(P3)	; ???
	HRRZ P4,UDBTWQ(P3)	;NO - GET HEAD OF TWQ
	JUMPN P4,R		;RETURN IF THERE REALLY WAS ONE
	BUG(HLT,NOIORB,<SETIRB - MISSING IORB>)
;DETERMINE THE UNIT RELATIVE ADDRESS FOR A DISK REQUEST

;P4/ IORB
;	CALL PHYBLK
;RETURNS+1(ALWAYS):
;T2/ UNIT RELATIVE ADDRESS
;CLOBBERS T1,T2

PHYBLK::SKIPL IRBSTS(P4)	;SHORT IORB?
	JRST BLK1		;NO
	MOVEI T2,-CST5(P4)	;YES - GET CPN
	LOAD T2,CSTLDA,(T2)	;GET UNIT RELATIVE ADDRESS
	RET

BLK1:	MOVE T2,IRBADR(P4)	;GET UNIT RELATIVE ADDRESS
	RET
;DETERMINE CORRECT CHANNEL AND UNIT FROM A DISK REQUEST

;P4/ IORB
;T4/ STRUCTURE NUMBER IF NOT FROM PAGEM
;	CALL GETCUB
;PRESERVES T2,3,4
;RETURNS+1:
;ERROR - INVALID ADDRESS
;RETURNS+2:
;T1/ UNIT RELATIVE ADDRESS
;P1/ CDB
;P3/ UDB

GETCUB:	SAVEQ			;PRESERVE ACCUMULATORS
	SKIPGE IRBSTS(P4)	;SHORT FORM IORB?
	JRST GTCUB5		;YES - GET CST1
	MOVE Q2,IRBADR(P4)	;NO - GET IORB ADDRESS
	MOVEI Q1,0(T4)		;SAVE STRUCTURE NUMBER
GTCUB1:	SKIPN Q1,STRTAB(Q1)	;ANY SUCH STRUCTURE?
	RET			;ILLEGAL STRUCTURE
	TLNN Q2,(DSKAB)		;DISK ADDRESS?
	JRST GTCUB3		;NO - SWAP ADDRESS
	TLZ Q2,DSKMSK		;CLEAR UNUSED BITS
	IDIV Q2,SDBSIZ(Q1)	;GET UNIT, RELATIVE ADDRESS
	CAML Q2,SDBNUM(Q1)	;LEGAL UNIT?
	RET			;UNIT TOO LARGE
GTCUB2:	ADDI Q2,SDBUDB(Q1)	;GET UDB ADDRESS
	MOVE P3,(Q2)		; ...
	HRRZ P1,UDBCDB(P3)	;FOLLOW BACK POINTER TO CDB
GTCUBX:	MOVE T1,Q3		;UNIT RELATIVE ADDRESS
	RETSKP			;SUCCESS RETURN

;HERE IF SWAPPING ADDRESS

GTCUB3:	TLNN Q2,(DRMOB)		;REAL DRUM ADDRESS?
	JRST GTCUB4		;YES
	TLZ Q2,-1		;NO - CLEAR UNUSED BITS ***SYMBOL***
	MOVE T1,SDBTYP(Q1)	;GET TYPE OF THIS DEVICE
	IDIV Q2,SECCYL(T1)	;GET TRACK(CYLINDER), SECTOR IN TRACK
	MOVE P3,Q3		;SAVE SECTOR WITHIN TRACK
	IDIV Q2,SDBNUM(Q1)	;GET UNIT RELATIVE TRACK, UNIT
	EXCH Q2,Q3		;PUT UNIT IN Q2
	IMUL Q3,SECCYL(T1)	;GET SECTOR STARTING TRACK ON UNIT
	ADD Q3,P3		;ADD SECTOR WITHIN TRACK
	CAML Q3,SDBNSS(Q1)	;CHECK WITHIN LIMIT
	RET			;SWAPPING ADDRESS TOO LARGE
	ADD Q3,SDBFSS(Q1)	;SWAP AREA OFFSET
	JRST GTCUB2		;JOIN OTHER CODE
;HERE IF REAL DRUM ADDRESS

GTCUB4:	LOAD Q1,DRTRK,Q2	;GET TRACK
	LOAD Q2,DRSEC,Q2	;GET SECTOR
	IMULI Q1,DRMSEC		;GET SECTORS
	ADD Q2,Q1		;INTO Q2
	IDIVI Q2,NTRK*DRMSEC	;GET UNIT AND RELATIVE ADDRESS
	HLRZ P1,DRMTAB(Q2)	;GET CDB
	HRRZ P3,DRMTAB(Q2)	;GET UDB
	JRST GTCUBX

;HERE ON A PAGEM REQUEST

GTCUB5:	MOVEI Q2,-CST5(P4)	;GET CPN
;**TEMP**
	MOVE Q1,CST2(Q2)	;GET OWNER IDENT
	CAIL Q1,NOFN		;FILE?
	JRST GTCB5A		;NO
	MOVX T1,OFN2XB		;SECOND XB
	TDNN T1,SPTH(Q1)	; ??
	JRST GTCB5A		;NO
	LDB T1,IRYFCN		;GET OPERATION
	CAIN T1,IRFRED		;READ?
	AOSA XB2RED		;YES
	AOS XB2WRT		;NO - WRITE
GTCB5A:
;**TEMP END**
	MOVE Q2,CST1(Q2)	;GET DISK ADDRESS
	SETZ Q1,		;ASSUME STRUCTURE 0
	TLNN Q2,(DSKAB)		;IS THIS A DISK REQUEST?
	JRST GTCUB1		;NO. GO DO SWAPPING REQUEST
	MOVEI T1,-CST5(P4)	;GET CORE PAGE NUMBER
	CALL FNDSTR		;GO GET STRUCTURE NUMBER FROM PAGEM
	MOVEI Q1,0(B)		;PUT IT IN THE RIGHT PLACE
	JRST GTCUB1		;JOIN OTHER PROCESSING
;HERE TO GET THE IOLIST ASSOCIATED WITH AN IORB

;P4/ IORB
;P1/ CDB
;P3/ UDB
;CALL PHYXFL
;RETURNS+1(ALWAYS):
;T1/ POINTER TO TRANSFER LIST
;T2/ POINTER TO END OF TRANSFER LIST

PHYXFL::SKIPL IRBSTS(P4)	;SHORT IORB?
	JRST XFL1		;NO - HAS OWN POINTER
	MOVE T1,[IRMWRD,,PGSIZ]	;WORD MODE, ONE PAGE
	MOVEI T2,-CST5(P4)	;GET CPN
	LSH T2,PGSFT		;AS ADDRESS
	HRRZ T4,CDBDSP(P1)	;GET CHANNEL DISPATCH
	CALL CDSCCW(T4)		;FORM CCW FOR THIS CHANNEL
	MOVEI T2,CDBCCL(P1)	;COMPUTE LIST TO USE, ASSUME PRIMARY
	HLL P1,CDBSTS(P1)	;GET CHAN STATUS
	TLNE P1,(CS.ACL)	;USE ALTERNATE?
	MOVEI T2,CDBCL2(P1)	;YES
	MOVEM T1,(T2)		;STORE IN CDB
	SETZM 1(T2)		;MARK END WITH ZERO
	MOVE T1,T2		;RETURN ADDRESS
	ADDI T2,1		;ADDRESS OF END
	RET

;HERE ON LONG FORM IORB

XFL1:	HRRZ T1,IRBXFL(P4)	;GET USERS TRANSFER LIST
	HLRZ T2,IRBXFL(P4)	;GET TAIL OF USERS LIST
	RET

;HERE TO GET THE BYTE COUNT ASSOCIATED WITH AN IORB

;P4/ IORB
;	CALL PHYCNT
;RETURNS+1(ALWAYS):
;T1/ BYTE COUNT
;PRESERVES T3,T4

PHYCNT::SKIPL IRBSTS(P4)	;SHORT IORB?
	SKIPA T1,IRBCNT(P4)	;NO, GET COUNT FROM IORB
	MOVEI T1,PGSIZ		;YES - ALL ONE SIZE
	RET
;UTILITY TO APPEND TO TWQ
;T1/ IORB
;	CALL ONTWQ
;RETURNS+1(ALWAYS):
;T1/ UNCHANGED

ONTWQ:	HLRZ T2,UDBTWQ(P3)	;GET TAIL OF TWQ
	HRRZ T3,IRBLNK(T2)	;INSURE TAIL REALLY WAS TAIL
	JUMPN T3,IRBERR		;NOT TAIL - BOMB
	HRRM T1,IRBLNK(T2)	;STORE NEW TAIL
	HRLM T1,UDBTWQ(P3)	; ...
	RET

;HERE TO PLACE AN IORB AT THE FRONT OF THE TWQ
;T1/ IORB
;P3/ UDB
;	CALL ONFTWQ
;RETURNS+1(ALWAYS):
;	IORB AT HEAD OF TWQ

ONFTWQ:	HRRZ T2,IRBLNK(T1)	;CHECK LINK OF NEW IORB IS NULL
	JUMPN T2,IRBNNT		;IF NOT NULL, DIE PROMPTLY
	HRRZ T2,UDBTWQ(P3)	;GET CURRENT HEAD OF TWQ
	HRRM T2,IRBLNK(T1)	;POINT LINK OF NEW IORB AT IT
	HRRM T1,UDBTWQ(P3)	;NEW IORB IS NEW HEAD OF LIST
	JUMPN T2,R		;WAS TWQ NON NULL?
	HLRZ T3,UDBTWQ(P3)	;WAS NULL
	CAIE T3,UDBTWQ(P3)	;CHECK TAIL WAS FOR NULL LIST
	JRST IRBERR		;POINTER WAS BAD
	HRLM T1,UDBTWQ(P3)	;STORE NEW IORB AS NEW TAIL
	RET

IRBNNT:	BUG(HLT,ILRBLT,<PHYSIO - IORB LINK NOT NULL AT ONF/STWQ>)

;HERE TO PLACE AN IORB AS THE SECOND ELEMENT ON A UNITS TWQ
;ASSUMES THE FIRST ELEMENT EXISTS
;T1/ IORB
;	CALL ONSTWQ
;RETURNS+1(ALWAYS):
;	IORB SECOND ON TWQ
;T1/ UNCHANGED

ONSTWQ:	HRRZ T2,IRBLNK(T1)	;CHECK LINK OF IORB IS NULL
	JUMPN T2,IRBNNT		;IF NOT NULL, WE HAVE TROUBLE
	HRRZ T2,UDBTWQ(P3)	;GET CURRENT HEAD OF TWQ
	HRRZ T3,IRBLNK(T2)	;GET CURRENT SECOND ELEMENT
	HRRM T1,IRBLNK(T2)	;THIS IORB IS NOW SECOND
	HRRM T3,IRBLNK(T1)	;OLD SECOND IS NOW SUCCESSOR
	JUMPN T3,R		;IF SUCCESSOR NONNULL, DONE
	HRLM T1,UDBTWQ(P3)	;SUCCESSOR NULL, NEW IORB IS TAIL
	RET			;DONE
;APPEND TO PWQ
;T1/ IORB
;P3/ UDB
;	CALL ONPWQ
;RETURNS+1(ALWAYS):

ONPWQ:	HLRZ T2,UDBPWQ(P3)	;GET TAIL POINTER
	HRRZ T3,IRBLNK(T2)	;CHECK IT REALLY WAS THE TAIL
	JUMPN T3,IRBERR		;NO - BOMB
	HRRM T1,IRBLNK(T2)	;POINT TO NEW TAIL
	HRLM T1,UDBPWQ(P3)	; ...
	RET

;HERE IF THE CURRENT TAIL OF TWQ/PWQ HAS A NON ZERO FORWARD POINTER

IRBERR:	BUG(HLT,ILTWQP,<PHYSIO - PWQ OR TWQ TAIL POINTER INCORRECT>)

;HERE TO PLACE AN IORB AT THE FRONT OF THE PWQ
;T1/ IORB
;P3/ UDB
;	CALL ONFPWQ
;RETURNS+1(ALWAYS):
;	IORB AT HEAD OF PWQ

ONFPWQ:	HRRZ T2,IRBLNK(T1)	;CHECK LINK OF NEW IORB IS NULL
	JUMPN T2,IRBNNL		;IT IS NOT NULL, LOSE BIG
	HRRZ T2,UDBPWQ(P3)	;GET CURRENT HEAD OF PWQ
	HRRM T2,IRBLNK(T1)	;POINT LINK OF NEW IORB AT IT
	HRRM T1,UDBPWQ(P3)	;NEW IORB IS NEW HEAD OF LIST
	JUMPN T2,R		;WAS PWQ NON NULL?
	HLRZ T3,UDBPWQ(P3)	;WAS NULL, CHECK TAIL POINTER
	CAIE T3,UDBPWQ(P3)	;CORRECT NULL LIST?
	JRST IRBERR		;NO
	HRLM T1,UDBPWQ(P3)	;YES - NEW HEAD IS ALSO NEW TAIL
	RET

IRBNNL:	BUG(HLT,ILIRBL,<PHYSIO - IORB LINK NOT NULL AT ONFPWQ>)
;HERE TO REMOVE AN ARBITRARY ELEMENT FROM THE TWQ
;T1/ PREDECESSOR OF ELEMENT TO BE REMOVED
;T2/ ELEMENT TO BE REMOVED
;	CALL CONSTW
;RETURNS+1(ALWAYS):
;	ELEMENT REMOVED
;**SEE NOTE AT START OF CONSPW**

CONSTW:	JUMPE T1,CNSTWE		;CHECK ARGUMENTS
	JUMPE T2,CNSTWE		; ...
	HRRZ T3,IRBLNK(T1)	;CHECK FOR REMOVAL OF EXACTLY ONE ELEMENT
	CAME T2,T3		; ...
	JRST CNSTWE		;MULTIPLE ELEMENTS, CURRENTLY ILLEGAL
	HRRZ T3,IRBLNK(T2)	;GET HEAD OF RIGHT RESIDUE LIST
	HLRZ T4,UDBTWQ(P3)	;GET TAIL OF TWQ
	CAME T4,T2		;IS TAIL OF LIST BEING REMOVED?
	JRST CNSTW1		;NO
	JUMPN T3,IRBERR		;YES - INSURE RIGHT RESIDUE REALLY NULL
	HRLM T1,UDBTWQ(P3)	;BACKUP TAIL OF TWQ
CNSTW1:	HRRM T3,IRBLNK(T1)	;POINT PREDECESSOR TO SUCCESSOR
	HLLZS IRBLNK(T2)	;CLEAR LINK IN REMOVED ELEMENT
	RET

CNSTWE:	BUG(HLT,ILCNST,<PHYSIO - ILLEGAL CALL TO CONSTW>)

;HERE TO REMOVE AN ARBITRARY ELEMENT FROM THE PWQ
;T1/ PREDECESSOR OF ELEMENT TO BE REMOVED
;T2/ ELEMENT TO BE REMOVED
;	CALL CONSPW
;RETURNS+1(ALWAYS):
;ELEMENT REMOVED
;NOTE: THE REASON TWO ARGUMENTS ARE REQUIRED IS TO ALLOW FOR POSSIBLE
;	EXTENSION TO THE REMOVAL OF SUBLISTS. IN THIS CASE, T1 WOULD BE
;	THE PREDECESSOR OF THE FIRST ELEMENT TO BE REMOVED, T2 WOULD BE
;	THE LAST ELEMENT IN THE SUBLIST TO BE REMOVED. THIS CASE IS
;	CURRENTLY DETECTED AS ILLEGAL.

CONSPW:	JUMPE T1,CNSPWE		;VALIDATE ARGUMENTS
	JUMPE T2,CNSPWE		; ...
	HRRZ T3,IRBLNK(T1)	;CHECK ONE AND ONLY ONE ELEMENT IS
	CAME T2,T3		;BEING REMOVED.
	JRST CNSPWE		;MULTIPLE ELEMENTS, ILLEGAL
	HRRZ T3,IRBLNK(T2)	;GET HEAD OF LIST AFTER ELEMENT REMOVED
	HLRZ T4,UDBPWQ(P3)	;GET TAIL OF LIST
	CAME T4,T2		;IS TAIL BEING REMOVED?
	JRST CNSPW1		;NO, NOTHING SPECIAL
	JUMPN T3,IRBERR		;YES - INSURE RESIDUE REALLY NULL
	HRLM T1,UDBPWQ(P3)	;BACKUP TAIL OF LIST
CNSPW1:	HRRM T3,IRBLNK(T1)	;POINT PREDECESSOR TO SUCCESSOR
	HLLZS IRBLNK(T2)	;CLEAR LINK IN ELEMENT REMOVED
	RET

CNSPWE:	BUG(HLT,ILCNSP,<PHYSIO - ILLEGAL CALL TO CONSPW>)
;UTILITY TO DEQUEUE THE HEAD OF A UNITS TWQ
;P3/ UDB
;	CALL OFFTWQ
;RETURNS+1(ALWAYS):
;T1/ IORB

OFFTWQ:	HRRZ T1,UDBTWQ(P3)	;GET IORB AT HEAD OF TWQ
	JUMPE T1,IRBMIS		;NO - BOMB
	HRRZ T2,IRBLNK(T1)	;GET FORWARD LINK
	HLLZS IRBLNK(T1)	;CLEAR TAIL POINTER
	HRRM T2,UDBTWQ(P3)	;NOW AT HEAD
	JUMPN T2,R		;UNLESS NOW NULL
	MOVSI T2,UDBTWQ(P3)	;NOW NULL - RESET LIST
	MOVEM T2,UDBTWQ(P3)	; ...
	RET

;UTILITY TO REMOVE THE HEAD OF A UNITS PWQ
;JUST LIKE OFFTWQ

OFFPWQ:	HRRZ T1,UDBPWQ(P3)	;GET IORB AT HEAD OF PWQ
	JUMPE T1,IRBMIS		;NO - BOMB
	HRRZ T2,IRBLNK(T1)	;GET FORWARD LINK
	HLLZS IRBLNK(T1)	;CLEAR TAIL POINTER
	HRRM T2,UDBPWQ(P3)	;NOW AT HEAD
	JUMPN T2,R		;UNLESS NOW NULL
	MOVSI T2,UDBPWQ(P3)	;NOW NULL - RESET LIST
	MOVEM T2,UDBPWQ(P3)	; ...
	RET

;HERE IF PWQ OR TWQ WAS NULL AT OFFPWQ/TWQ

IRBMIS:	BUG(HLT,TWQNUL,<PHYSIO - PWQ OR TWQ WAS NULL AT A SEEK OR TRANSFER COMPLETION>)
;HERE TO REMOVE ALL NON ACTIVE IORBS FROM A UNIT TRANSFER QUEUE
;	NOTE: THIS ROUTINE IS NOT CURRENTLY CALLED FOR DISK UDBS

;P1 & P3 SETUP
;	CALL PHYKIL
;RETURNS+1(ALWAYS):
;T1/ HEAD OF LIST OF IORBS
;NOTE: THIS ROUTINE CAN BE CALLED FROM NONZERO SECTIONS

PHYKIL::SAVEP			;SAVE REGISTERS
	HRRZ P3,T1		;SETUP UDB
	HLRZ P1,T1		;SETUP CDB
	MOVSI T1,(US.ACT)	;IS UNIT ACTIVE
	MOVSI T2,(US.POS)	;SETUP FOR POSITION TEST
	PIOFF			;PREVENT RACE - MUST NEST IN IOPIOF
	TDNN T1,UDBSTS(P3)	; .?.
	JRST KILALL		;NO - CAN PRUNE ALL
	TDNE T2,UDBSTS(P3)	;UNIT ACTIVE. POSITIONING?
	JRST KIL2		;YES
	HRRZ T2,UDBTWQ(P3)	;PICK UP ACTIVE IORB
	HRRZ T1,IRBLNK(T2)	;LINK FORWARD
	JUMPE T1,KIL1		;CHECK PWQ
	HLLZS IRBLNK(T2)	;CLEAR FORWARD LINK
	HLRZ T3,UDBTWQ(P3)	;GET TAIL POINTER
	HRLM T2,UDBTWQ(P3)	;UPDATE TAIL POINTER
KIL1:	HRRZ T2,UDBPWQ(P3)	;GET HEAD OF PWQ
	JUMPE T2,PIONRT		;IF NIL, RETURN
	HRRM T2,IRBLNK(T3)	;APPEND TO TWQ LIST
	MOVSI T2,UDBPWQ(P3)	;RESET PWQ TO NULL
	MOVEM T2,UDBPWQ(P3)	; ...
	JRST PIONRT		;RETURN

KIL2:	HRRZ T2,UDBPWQ(P3)	;HERE WHEN POSITIONING ACTIVE
	HRRZ T1,IRBLNK(T2)	;GET ENTRY AFTER HEAD
	JUMPE T1,PIONRT		;RETURN NULL
	HLLZS IRBLNK(T2)	;CLEAR FORWARD LINK
	HRLM T2,UDBPWQ(P3)	;UPDATE END OF LIST
	JRST PIONRT		;RETURN

;HERE TO KILL ALL IORBS

KILALL:	HRRZ P4,UDBTWQ(P3)	;GET IORB
	JUMPN P4,KILA1		;IF PRESENT, USE FOR ERRFIN
	HRRZ P4,UDBPWQ(P3)	;NO TRANSFER, IS THERE POSITIONING
	JUMPE P4,KILA2		;NO, SKIP ERRFIN
KILA1:	CALL ERRFIN		;TERMINATE ERROR RECOVERY IF NEEDED
KILA2:	MOVSI T1,(US.OIR!US.OMS);CLEAR OUT OPERATOR MESSAGE BITS
	ANDCAM T1,UDBSTS(P3)	; ...
	HRRZ T1,UDBTWQ(P3)	;GET HEAD OF LIST
	HLRZ T3,UDBTWQ(P3)	;GET TAIL OF LIST
	MOVSI T2,UDBTWQ(P3)	;SETUP NULL QUEUE
	MOVEM T2,UDBTWQ(P3)	; ...
	HRRZ T2,UDBPWQ(P3)	;GET PWQ HEAD
	JUMPE T1,KILA3		;WAS TWQ NIL?
	HRRM T2,IRBLNK(T3)	;NO - APPEND TO TWQ LIST
	MOVSI T2,UDBPWQ(P3)	;RESET PWQ TO NULL
	MOVEM T2,UDBPWQ(P3)	; ...
	JRST PIONRT		;RETURN

KILA3:	MOVE T1,T2		;TWQ NIL, RETURN PWQ
	MOVSI T2,UDBPWQ(P3)	;RESET PWQ TO NULL
	MOVEM T2,UDBPWQ(P3)	; ...
PIONRT:	PION
	RET
;HERE TO FETCH A WORD FROM A SPECIFIED PHYSICAL ADDRESS

;T1/ PHYSICAL ADDRESS
;CALL PHYMOV
;RETURNS+1(ALWAYS):
;T1/ UNCHANGED
;T2/ CONTENTS OF ((T1))

PHYMOV::PUSH P,T1		;SAVE ADDRESS OVER CALL
	IDIVI T1,PGSIZ		;ISOLATE CPN AND RELATIVE WORD
	EXCH T1,T2		;PLACE IN CORRECT ACCUMULATORS
	CALL MOVRCA		;CALL KERNEL ROUTINE
	MOVE T2,T1		;COPY RESULT
	JRST PA1		;POP T1 AND RETURN


;HERE TO STORE A WORD IN A SPECIFIED PHYSICAL ADDRESS

;T1/ PHYSICAL ADDRESS
;T2/ DATA TO STORE
;	CALL PHYSTO
;T1/ UNCHANGED

PHYSTO::PUSH P,T1		;SAVE ARGUMENT OVER CALL
	MOVE T3,T2		;MOVE DATA TO WHERE LOWER LEVEL WANTS IT
	IDIVI T1,PGSIZ		;ISOLATE CPN AND RELATIVE WORD
	EXCH T1,T2		;MOVE TO CORRECT PLACE
	CALL STORCA		;CALL KERNEL ROUTINE
	JRST PA1		;POP T1 AND RETURN

;HERE TO GENERATE A CCW FOR A PARTICULAR CHANNEL

;T1/ DATA MODE,,BYTE COUNT (1B0 IF BACKWARDS)
;T2/ PHYSICAL ADDRESS OF FIRST WORD TO TRANSFER
;T3/ CDB
;	CALL PHYCCW
;RETURNS+1(ALWAYS):
;T1/ CCW TO TRANSFER DATA AS SPECIFIED BY ARGUMENTS

PHYCCW::SAVEP			;PRESERVE REGISTERS
	MOVE P1,T3		;COPY CDB
	HRRZ T3,CDBDSP(P1)	;GET DISPATCH ADDRESS
	CALL CDSCCW(T3)		;GENERATE CCW
	RET
;ROUTINE TO WAIT FOR ALL PHYSIO ACTIVITY TO CEASE.
;CALLED AT SYSTEM STARTUP TIME JUST BEFORE THE SWAPPABLE MONITOR
;IS LOADED.

PHYIOW::SAVEPQ			;SAVE PRESERVED REGISTERS
IOW1:	MOVEI Q1,0		;CLEAR ACTIVITY FLAG
	MOVSI P4,-CHNN		;POINTER TO CHANNELS
IOW2:	SKIPN P1,CHNTAB(P4)	;CHANNEL PRESENT?
	JRST IOW3		;NO - CONTINUE
	MOVSI T1,(CS.ACT)	;TRANSFER ON THIS CHANNEL?
	TDNE T1,CDBSTS(P1)	; ???
	AOJA Q1,IOW3		;YES - SET FLAG
	CALL DGUMAP		;MAP OVER ALL UNITS
	 CALL [	MOVSI T1,(US.ACT!US.POS!US.OIR!US.OMS) ;CHECK ACTIVITY
		TDNE T1,UDBSTS(P3) ; ...
		AOS Q1		;FLAG ACTIVITY
		RET]
IOW3:	AOBJN P4,IOW2		;LOOP OVER ALL CHANNELS
	JUMPN Q1,IOW1		;IF ANY WERE ACTIVE, CHECK AGAIN
	RET			;NONE ACTIVE, RETURN

;ROUTINE TO RETRIEVE UDB INFO ON TAPE POSITION
;C(T1) := TAPE UNIT NUMBER
;RETURNS:
; T1/	UDBPS2	(RECORD COUNT)
; T2/	UDBPS1	(FILE COUNT)

PHYPOS::HRRZ T3,MTCUTB(T1)	;GET POINTER TO UDB
	MOVE T1,UDBPS2(T3)	;RECORD COUNT TO T1
	MOVE T2,UDBPS1(T3)	;FILE COUNT TO T2
	RET			;RETURN
	SUBTTL ERROR LOGGING INTERFACE

;HERE TO ASSIGN AN ERROR BLOCK
;P1/ CDB
;P3/ UDB
;	CALL ERRSET
;RETURNS+1(ALWAYS):
;T1/ EB ADDRESS OR ZERO IF NONE AVAILABLE

ERRSET:	MOVEI T1,MB%LEN		;TOTAL BLOCK LENGTH
	MOVEI T2,MB%SIZ		;NON STRING DATA SIZE
	MOVSI T3,(IS.IEL)	;SHOULD ANY LOGGING BE DONE?
	TDNN T3,IRBSTS(P4)	; ??
	CALL ALCSEB		;YES, TRY TO GET ERROR BLOCK
	 MOVEI T1,0		;NO LOGGING OR NONE AVAIL
	RET

;HERE TO LOG AND RELEASE AN ERROR BLOCK
;P1/ CDB
;P3/ UDB
;	CALL ERRFIN
;RETURNS+1(ALWAYS):
;ERROR LOGGING UNDERWAY

ERRFIN:	HRRZS UDBERP(P3)	;CLEAR LEFT HALF
	SKIPN UDBERP(P3)	;AN ERROR BLOCK?
	JRST ERRFN3		;NO, DONT SAVE ACCUMULATORS
	SAVEQ
	MOVEI Q1,0		;CLEAR/GET ERROR BLOCK
	EXCH Q1,UDBERP(P3)	; ...
	JUMPE Q1,ERRFN3		;NOTHING TO LOG
	MOVE Q3,UDBSTS(P3)	;GET UNIT TYPE
	HRL Q3,CDBSTS(P1)	;GET CHANNEL TYPE
	HRRZ P3,P3		;CLEAR OUT ANY FLAGS
	MOVE T1,Q1		;GET ERROR BLOCK
	MOVE T2,[-NCTAB,,CTAB]	;GET THINGS TO COPY
	CALL SEBCPY		;AND DO IT
	 JFCL			;NEVER...
	HLL P3,UDBSTS(P3)	;GET FLAGS BACK AGAIN
	MOVSI T1,(IS.ERR!IS.NRT) ;IS THIS A HARD ERROR?
	TDNN T1,IRBSTS(P4)	; ?
	JRST ERRFN2		;NO, NO NEED FOR BAT BLOCK LOGIC
	MOVSI T1,(IS.DTE)	;YES - IS IT A DATA ERROR
	TDNN T1,IRBSTS(P4)	; ???
	JRST ERRFN2		;NO - DONT DO BAT BLOCK LOGIC
	LDB T1,USYTYP		;IS THIS A DISK?
	MOVSI T2,-NDSKUT	;SEARCH TABLE OF UNIT TYPES FOR BAT LOGIC
ERRFN0:	CAMN T1,DSKUTP(T2)	;UNIT TYPE IN TABLE?
	JRST ERRFN1		;YES - DO BAT LOGIC
	AOBJN T2,ERRFN0		;NO - LOOP
	JRST ERRFN2		;NO, DONT TRY BAT BLOCK LOGIC
ERRFN1:	MOVE T1,Q1		;GET ERROR BLOCK AGAIN
	MOVE T2,[-1,,[SEBPTR 0,SBTFNA,ERRBAT]]
	CALL SEBCPY		;INSERT JOB 0 FUNCTION
	 JFCL
ERRFN2:	MOVE T1,Q1		;RECOVER ERROR BLOCK
	CALL QUESEB
	MOVEI T1,MASBGX		;SAY WE ARE REOCRDING A MASSBUS ERROR
	CALL GENBLK		;SEE IF STATUS BLOCK NEEDED
ERRFN3:	SETZM UDBERR(P3)	;YES - CLEAR STATE INFORMATION
	SETZM UDBERC(P3)	; ...
	RET			;AND WE ARE DONE
;COPY BLOCK
CTAB:	SEBPTR 0,SBTEVC,SEC%MB	;BLOCK TYPE
	SEBPTR MB%VID,SBTWD,UDBVID(P3) ;VID
	SEBPTR MB%FES,SBTWD,UDBERR(P3) ;FINAL ERROR STATE
	SEBPTR MB%UDB,SBTWD,P3	;UDB - NEEDED FOR BAT BLOCK LOGIC IN JOB 0
	SEBPTR MB%IRS,SBTWD,IRBSTS(P4) ;IORB STATUS WORD
	SEBPTR MB%TYP,SBTWD,Q3	;CHANNEL TYPE,,UNIT TYPE
	SEBPTR MB%SEK,SBTWD,UDBSEK(P3) ;NUMBER OF SEEKS
	SEBPTR MB%RED,SBTWD,UDBRED(P3) ;DATA READ
	SEBPTR MB%WRT,SBTWD,UDBWRT(P3) ;DATA WRITTEN
	SEBPTR MB%SRE,SBTWD,UDBSRE(P3) ;SOFT READ ERRORS
	SEBPTR MB%SWE,SBTWD,UDBSWE(P3) ;SOFT WRITE ERRORS
	SEBPTR MB%HRE,SBTWD,UDBHRE(P3) ;HARD READ ERRORS
	SEBPTR MB%HWE,SBTWD,UDBHWE(P3) ;HARD WRITE ERRORS
	SEBPTR MB%PS1,SBTWD,UDBPS1(P3) ;POSITION 1
	SEBPTR MB%PS2,SBTWD,UDBPS2(P3) ;POSITION 2
	SEBPTR MB%FEC,SBTWD,UDBERC(P3) ;FINAL ERROR COUNTER
	SEBPTR MB%USR,SBTWD,UDBUDR(P3) ;USER DIRECTORY TO LOG
	SEBPTR MB%PGM,SBTWD,UDBPNM(P3) ;USER PROGRAM TO LOG
	SEBPTR MB%MPE,SBTWD,CDBPAR(P1) ;PAR ERR COUNT
	SEBPTR MB%NXM,SBTWD,CDBNXM(P1) ;NXM COUNT
	SEBPTR MB%OVR,SBTWD,CDBOVR(P1) ;NUMBER OF OVERRUNS
	SEBPTR MB%CAD,SBTWD,CDBADR(P1) ;CHANNEL NUMBER
	SEBPTR MB%UAD,SBTWD,UDBADR(P3) ;UNIT ADDRESS

NCTAB=.-CTAB

;HERE IN JOB 0 CONTEXT WHEN A HARD ERROR HAS OCCURED ON A DISK.
;THE BAT BLOCK LOGIC MUST BE INVOKED TO PREVENT RE-USE OF THE BAD BLOCK.

	SWAPCD			;RUNS IN JOB 0 CONTEXT, MAY BE SWAPPABLE
ERRBAT:	MOVE T2,SEBDAT+MB%LOC(T1) ;GET LINEAR ADDRESS FROM ERROR BLOCK
	MOVE T1,SEBDAT+MB%UDB(T1) ;GET UDB FROM ERROR BLOCK
	CALL BATQ		;MARK BAT BLOCKS, FDB, ETC.
	RET

	RESCD
SUBTTL INTERNAL START IO UTILITIES

;HERE TO START IO ON AN IORB

;SHOULD BE CALLED WITH PI OFF IF NOT AT INTERRUPT LEVEL
;P4/ IORB
;P1,2,3 SETUP
;	CALL STRTIO
;RETURNS+1:
;	IO NOT STARTED, IORB EITHER TERMINATED OR REMAINING IN QUEUES
;RETURNS+2:
;	IO STARTED

STRTIO:	SKIPGE IRBSTS(P4)	;SHORT IORB?
	JRST STRTI1		;YES, NEVER AN EXIT ROUTINE
	HLRZ T2,IRBIVA(P4)	;GET STARTIO EXIT
	JUMPE T2,STRTI1		;NONE
	MOVE T1,P4		;COPY IORB FOR CALL
	CALL (T2)		;CALL EXIT ROUTINE
	 SKIPA			;ABORT
	JRST STRTI1		;NORMAL STARTUP
STRTI0:	MOVSI T1,(US.OIR!US.OMS) ;NO LONGER ANY NEED FOR OPER INTERVENTION
	ANDCAM T1,UDBSTS(P3)	; ...
	CALL OFFTWQ		;REMOVE FROM TWQ
	CALL DONIRB		;FLAG AS DONE
	RET			;AND EXIT INDICATING REFUSED
STRTI1:	MOVSI T1,(US.POS!US.ACT) ;UNIT FREE?
	MOVSI T2,(KS.ACT)	;CONTROLLER FREE?
	TRNE P2,-1		;IS THERE A CONTROLLER?
	TDNN T2,KDBSTS(P2)	; ??
	TDNE T1,UDBSTS(P3)	; ??
	BUG(HLT,ILUST1,<PHYSIO - UNIT STATUS INCONSISTENT AT SIO>)
	MOVSI T1,(CS.AC2)	;CHECK NOT OUT OF PHASE
	TDNE T1,CDBSTS(P1)	; ...
	BUG(HLT,ILCHS1,<PHYSIO - ILLEGAL CHANNEL STATUS AT SIO>)
	MOVSI T1,(CS.AC1)	;CHANNEL GOING ACTIVE
	IORM T1,CDBSTS(P1)	; ...
	MOVSI T1,(KS.ACT)	;AND CONTROLLER
	TRNE P2,-1		;IF PRESENT
	IORM T1,KDBSTS(P2)	; ...
	MOVSI T1,(US.ACT)	; ALSO UNIT
	IORM T1,UDBSTS(P3)	; ...
	HRRZ T1,UDBAKA(P3)	;GET CURRENT UDB ADDRESS
	MOVEM T1,CDBXFR(P1)	;MARK A UNIT HOLDING CHANNEL
	CALL SETIO		;SETUP FOR IO
	CALL CDSSIO(T1)		;GO START IO
	 SKIPA			;OFFLINE - CANT START IO
	RETSKP			;IO STARTED SUCCESSFULLY
	CALL CLRACT		;CLEAR CHANNEL AND UNIT ACTIVE BITS
	MOVX T1,IS.ERR		;ANY ERRORS OCCURRED?
	TDNE T1,IRBSTS(P4)	;CHECK IORB
	JRST STRTI0		;YES, REMOVE IORB FROM QUEUE
	CALLRET SETOIR		;INDICATE OPERATOR NEEDED

;HERE WHEN OPERATOR INTERVENTION REQUIRED

SETOIR:	MOVSI T1,(US.OIR)	;SET OPERATOR INTERVENTION BIT
	IORM T1,UDBSTS(P3)	;FOR PERIODIC CHECKER
	SETZM UDBODT(P3)	;ALSO CLEAR OUT OVERDUE TIMER
	RET
;HERE TO STACK A SECOND DATA TRANSFER COMMAND FOR A CHANNEL

;REQUIRES THE USUAL PIOFF OR INTERRUPT LEVEL INTERLOCK
;P4/ IORB
;P1,2,3 SETUP
;	CALL STKIO
;RETURNS+1:
;	COMMAND NOT STACKED
;RETURNS+2:
;	COMMAND STACKED IN CHANNEL

STKIO:	SKIPGE IRBSTS(P4)	;SHORT IORB?
	JRST STKIO1		;YES - NO NEED TO CALL EXIT RTN
	HLRZ T2,IRBIVA(P4)	;GET SIO EXIT ROUTINE ADDRESS
	JUMPE T2,STKIO1		;IF NONE, ASSUME OK
	MOVE T1,P4		;COPY IORB
	CALL (T2)		;CALL EXIT ROUTINE
	 RET			;SIGNAL FAILURE, WILL TERMINATE AT STRTIO
STKIO1:	MOVSI T1,(US.POS)	;IS THIS UNIT
	MOVSI T2,(CS.AC1)	;AND THIS CHANNEL
	TDNE T2,CDBSTS(P1)	;IN THE CORRECT
	TDNE T1,UDBSTS(P3)	;STATE?
	BUG(HLT,ILUST5,<PHYSIO - ILLEGAL UNIT OR CHANNEL STATE AT STKIO>)
	MOVSI T1,(CS.AC2)	;SECOND COMMAND
	TDNE T1,CDBSTS(P1)	;SHOULDN'T BE ACTIVE NOW
	BUG(HLT,ILCHS2,<PHYSIO - ILLEGAL CHANNEL STATE AT STKIO>)
	IORM T1,CDBSTS(P1)	;WILL NOW HAVE BOTH ACTIVE
	CALL SETIO		;SETUP
	CALL CDSSTK(T1)		;CALL LOWER LEVELS
	 RET			;FAILED
	RETSKP			;USE CALLRET LATER, CAN BKPT HERE NOW
;HERE TO START POSITIONING FOR AN IORB

;P4/ IORB
;P1,3 SETUP
;	CALL STRTPS
;RETURN+1:
;	POSITIONING NOT STARTED, IORB TERMINATED IF APPROPRIATE
;RETURNS+2:
;	POSITIONING STARTED

STRTPS:	HRRZ T1,UDBTWQ(P3)	;CHECK IF POSITIONING LEGAL NOW
	MOVSI T2,(US.ACT)	;IF ANY PENDING REQUEST ON CYLINDER
	TDNE T2,UDBSTS(P3)	;OR IF UNIT ACTIVE
	SKIPN T1		; ...
	SKIPA			;NONE OF THE ABOVE
	BUG(CHK,ILUST2,<PHYSIO - UNIT STATUS INCONSISTENT AT SPS>)
	TRNN P2,-1		;IS THERE A CONTROLLER?
	JRST STRTP1		;NO
	MOVSI T1,(KS.ACT)	;YES
	TDNE T1,KDBSTS(P2)	;ALREADY ACTIVE?
	BUG(HLT,ILUST4,<PHYSIO - CONTROLLER ACTIVE AT SPS>)
	IORM T1,KDBSTS(P2)	;NO - MAKE IT ACTIVE
STRTP1:	MOVSI T1,(US.ACT!US.POS) ;UNIT SOON POSITIONING
	IORM T1,UDBSTS(P3)	; ...
	CALL SETIO		;SETUP
	CALL CDSPOS(T1)		;CALL LOWER LEVEL
	 SKIPA			;COULDNT
	RETSKP			;ALL OK.
	CALL CLRPOS		;CLEAR ACTIVE
	MOVX T1,US.TAP		;IS THIS A TAPE LIKE DEVICE?
	TDNN T1,UDBSTS(P3)	;???
	JRST STRTP2		;NO
	MOVX T1,IS.ERR		;YES - WAS AN ERROR INDICATED?
	TDNN T1,IRBSTS(P4)	; ???
	JRST STRTP2		;NO - KEEP IN QUEUES
	MOVX T1,US.OIR!US.OMS	;YES - TERMINATE
	ANDCAM T1,UDBSTS(P3)	;NO LONGER WAITING FOR OPR
	CALL OFFPWQ		;REMOVE FROM PWQ
	CALL DONIRB		;POST COMPLETE
	RET			;FAIL RETURN

STRTP2:	CALLRET	SETOIR		;SET OPERATOR INVERVENTION REQ
				;AND FAIL RETURN


;HERE TO RESTART SEEKS ON A CHANNEL
;P1/ CDB
;	CALL RSTSEK
;RETURNS+1(ALWAYS):
;CLOBBERS P REGISTERS, P3
;SHOULD BE CALLED WITH PI OFF

RSTSEK::SAVEQ
	MOVE T1,CDBIUN(P1)	;GET POINTER
RSEK1:	SKIPN P3,(T1)		;IS THERE A UNIT HERE?
	JRST RSEK2		;NO, MOVE ON.
	HRRZ P2,UDBKDB(P3)	;GET KDB, IF ANY
	PUSH P,T1		;YES, SAVE COUNTER
	CALL SCHSEK		;DO SEEKS IF NEEDED.
	POP P,T1		;RESTORE COUNTER
RSEK2:	AOBJN T1,RSEK1		;LOOP FOR MORE
	RET			;DONE
;UTILITY TO SET UP FOR IO
;P4/IORB ADDRESS
;P1/CDB
;RETURNS +1 (ALWAYS):
;ERROR BIT CLEARED IN IORB,
;T1/DISPATCH ADDRESS
SETIO::	MOVSI T1,(IS.ALE)	;CLEAR ALL ERROR BITS
	ANDCAM T1,IRBSTS(P4)
	MOVEI T1,^D17000	;ALLOW 17 SECONDS FOR MAXIMUM TRANSFER
	ADD T1,TODCLK		;FROM NOW
	MOVEM T1,UDBODT(P3)	;AND STORE AS OVERDUE TIME
	HRRZ T1,CDBDSP(P1)
	RET

;HERE TO CLEAR CHANNEL AND UNIT ACTIVE BITS

CLRACT:	MOVSI T1,(CS.ACT!CS.ERC) ;NO LONGER ACTIVE OR IN ERROR RECOVERY
	ANDCAM T1,CDBSTS(P1)	; ...
	SETOM CDBXFR(P1)	;MARK CHANNEL FREE
CLRPOS:	MOVSI T1,(KS.ACT)	;CONTROLLER NO LONGER ACTIVE
	TRNE P2,-1		;IF ONE EXISTS
	ANDCAM T1,KDBSTS(P2)	; ...
	MOVSI T1,(US.ACT!US.POS) ;NOT ACTIVE OR POSITIONING
	ANDCAM T1,UDBSTS(P3)	; ...
CLRXIT:	SETZM UDBODT(P3)	;ALSO CLEAR TIMEOUT
	MOVSI T1,(US.MRQ)	;WAITING FOR MAINT MODE?
	TDNN T1,UDBSTS(P3)	;?
	RET			;NO - JUST RETURN
	MOVSI T2,(US.MAI)	;YES - SET BIT
	IORM T2,UDBSTS(P3)	; ...
	ANDCAM T1,UDBSTS(P3)	;NO LONGER REQUESTING
	AOS PSKED		;POKE SCHED
	RET
	SUBTTL SEEK SCHEDULER
;SHOULD BE CALLED WITH INTERRUPTS OFF OR AT INTERRUPT LEVEL
;P1/ CDB
;P2/ KDB (IF PRESENT)
;P3/ UDB
;	CALL SCHSEK
;RETURNS+1(ALWAYS):
;	SEEK STARTED ON THIS UNIT IF APPROPRIATE
;	POSITION OP STARTED IF CONTROLLER FREE (SEE SCHPOS COMMENTS)
;USES P4,THE Q'S

;THE ALGORITHM USED IS THAT REFERED TO IN THE LITERATURE AS "SCAN"
;BRIEFLY STATED, THE ALGORITHM SELECTS THE REQUEST TO THE CLOSEST
;HIGHER NUMBERED CYLINDER THAN THE UNITS CURRENT CYLINDER. IF THERE IS
;NO SUCH REQUEST, THE REQUEST TO THE LOWEST NUMBERED CYLINDER IS
;SELECTED. THIS CAUSES THE DISK ARM TO "SCAN" FROM LOWER NUMBERED
;CYLINDERS TO HIGHER NUMBERED CYLINDERS. THE CACM AND IBM SYS. J.
;HAVE MANY DESCRIPTIONS AND WINDY RELIGIOUS DEBATES ON THE SUBJECT.

;NOTE: READS ARE GIVEN PREFERENCE OVER WRITES IN SELECTING THE
;	NEXT SEEK CYLINDER. THIS TENDS TO REDUCE SYSTEM SWAP WAIT TIME
;	IN THAT A PROCESS IS USUALLY BLOCKED WAITING FOR A READ WHILE
;	WRITES USUALLY ORIGINATE WITH GCCOR. ALL TRANSFERS FOR THE
;	SELECTED CYLINDER ARE DONE, BOTH READS AND WRITES.

;REGISTER USAGE:
;Q1/ FLAGS,,PREDECESSOR TO ELEMENT UNDER CONSIDERATION
;Q2/ MINIMUM CYLINDER SO FAR,,PREDECESSOR TO MINIMUM ELEMENT
;Q3/ BEST CYLINDER SO FAR,,PREDECESSOR TO BEST ELEMENT
;P4/ CURRENT ELEMENT UNDER CONSIDERATION

;LOCAL FLAGS IN LH(Q1)
SEKF%R==1B0		;PREFER READS OVER WRITES
SEKF%M==1B1		;HAVE A READ FOR MIN CYL
SEKF%B==1B2		;HAVE A READ FOR BEST CYL
SCHSEK:	MOVSI T1,(CS.MRQ!CS.MAI) ;CHANNEL IN MAINT MODE?
	TDNE T1,CDBSTS(P1)	; ???
	RET			;YES - NO NEW ACTIVITY
	TRNE P2,-1		;KDB FOR THIS UNIT?
	JRST SCHPOS		;YES - GO WORK ON IT
	HRRZ T1,UDBTWQ(P3)	;ANY TRANSFERS PENDING ON CYLINDER?
	JUMPN T1,R		;YES - WHY MESS THINGS UP?
	MOVEI Q1,UDBPWQ(P3)	;SETUP PREDECESSOR
	MOVSI Q2,-1		;SETUP MINIMUM CYLINDER TO LARGE NUMBER
	MOVSI Q3,-1		;SETUP BEST CYLINDER TO LARGE NUMBER
	HRRZ P4,UDBPWQ(P3)	;GET CURRENT HEAD OF PWQ
	JUMPE P4,SEKIDL		;IF QUEUE IS NULL, EXIT
	SOSG UDBFCR(P3)		;SHOULD READS GET PREFERENCE?
	SKIPA T1,[EXP INIFCR]	;NO - ALSO RESET COUNT
	TLOA Q1,(SEKF%R)	;YES
	MOVEM T1,UDBFCR(P3)	;SAVE NEW VALUE
SEK1:	HRRZ T1,UDBDSP(P3)	;GET UNIT DISPATCH
	CALL UDSCNV(T1)		;GET CYLINDER FOR THIS REQUEST
	LDB T3,IRYFCN		;GET FUNCTION CODE
	CAME T2,UDBPS1(P3)	;SAME AS CURRENT?
	JRST SEK3		;NO
	SKIPG UDBFCT(P3)	;YES - "FAIRNESS" COUNT EXHAUSTED?
	JRST SEK5		;COUNT EXHAUSTED, WILL REPOSITION
	HRRZ T1,Q1		;GET PREDECESSOR
	HRRZ T2,P4		;GET ELEMENT TO BE REMOVED
	CALL CONSPW		;SPLICE QUEUE
	HRRZ T1,P4		;GET CURRENT REQUEST
	CALL ONTWQ		;AND PLACE ON TWQ
SEK2:	HRRZ P4,IRBLNK(Q1)	;ADVANCE CURRENT REQUEST
	JUMPN P4,SEK1		;IF ONE PRESENT, CONSIDER IT.
	HRRZ T1,UDBTWQ(P3)	;END OF QUEUE, ANYTHING IN TWQ?
	JUMPN T1,R		;YES - DONT DISTURB POSITION.
	HLRZ T1,Q3		;GET BEST CYLINDER FOUND
	CAIN T1,-1		;FOUND ANY REQUESTS TO HIGHER CYLINDERS?
	MOVE Q3,Q2		;NO - RESET SCAN AT MINIMUM
	HRRZ T1,Q3		;GET REQUEST DECIDED ABOVE
	HRRZ T2,IRBLNK(T1)	; ACTUAL ELEMENT
	HRRZ P4,T2		;COPY NEW CURRENT IORB
	CALL CONSPW		;SPLICE QUEUE
	MOVE T1,P4		;SHUFFLE TO HEAD OF PWQ
	CALL ONFPWQ		; ...
	MOVSI T1,(US.OIR!US.OMS!US.MAI!US.MRQ) ;WAITING FOR OPERATOR?
	TDNE T1,UDBSTS(P3)	; ???
	RET			;YES - DO NOTHING
	MOVSI T1,(US.POS!US.ACT) ;UNIT IDLE?
	TDNE T1,UDBSTS(P3)	; ??
	BUG(HLT,ILUST3,<PHYSIO - SCHSEK - IMPOSSIBLE UNIT STATUS>)
	CALL STRTPS		;START POSITIONING
	 JFCL			;COULDNT POSITION THIS UNIT, OPERATOR NEEDED
	RET
SEK3:	JUMPGE Q1,SEK3B		;READ PREFERENCE?
	CAIE T3,IRFRED		;YES - IS THIS A READ?
	JRST SEK3A		;NO
	TLON Q1,(SEKF%M)	;YES - SET/TEST IF WE HAVE A READ NOW
	JRST SEK3C		;NO - TAKE THIS REQUEST
	JRST SEK3B		;YES - SEE IF THIS REQUEST IS BETTER
SEK3A:	TLNE Q1,(SEKF%M)	;NOT A READ - DO WE HAVE A READ NOW?
	JRST SEK4		;YES
SEK3B:	HLRZ T1,Q2		;GET MINIMUM CYLINDER FOUND SO FAR
	CAML T2,T1		;THIS REQUEST LESS THAN MINIMUM?
	JRST SEK4		;NO
SEK3C:	HRRZ Q2,Q1		;YES - SAVE PREDECESSOR
	HRL Q2,T2		;AND NEW MINIMUM CYLINDER
SEK4:	CAMG T2,UDBPS1(P3)	;THIS REQUEST GREATER THAN UNIT CURRENT?
	JRST SEK5		;NO
	JUMPGE Q1,SEK4B		;READ PREFERENCE?
	CAIE T3,IRFRED		;YES - IS THIS A READ?
	JRST SEK4A		;NO
	TLON Q1,(SEKF%B)	;YES - SET/TEST DO WE HAVE A READ NOW?
	JRST SEK4C		;NO - USE THIS REQUEST
	JRST SEK4B		;YES - CHECK IF THIS REQUEST IS BETTER
SEK4A:	TLNE Q1,(SEKF%B)	;NOT A READ - DO WE HAVE A READ NOW?
	JRST SEK5		;YES
SEK4B:	HLRZ T1,Q3		;GET CURRENT BEST CYLINDER
	CAML T2,T1		;BETTER? (LESS)
	JRST SEK5		;NO - CONTINUE SEARCH
SEK4C:	HRRZ Q3,Q1		;YES - SAVE PREDECESSOR
	HRL Q3,T2		;SAVE NEW BEST CYLINDER
SEK5:	HRR Q1,P4		;ADVANCE POINTER
	JRST SEK2		;AND CONTINUE SCAN

;HERE WHEN UNIT HAS NO MORE POSITION REQUESTS

SEKIDL:	MOVEI T1,INIFCR		;RESET READ PREFERENCE COUNT
	MOVEM T1,UDBFCR(P3)	; ...
	RET
;HERE TO SCHEDULE A POSITION OPERATION ON A UNIT WHICH IS A SUBUNIT
;OF A CONTROLLER TYPE DEVICE. THE POSITION AND TRANSFER OPERATIONS
;ARE SCHEDULED ROUND ROBIN AMONG THE DEVICES ON THE CONTROLLER.
;UNLIKE A DISK WHERE A SINGLE UNIT'S QUEUES DETERMINE WHETHER
;TO SEEK/NOT SEEK, THE UNITS OTHER THAN THE CURRENT ONE MUST BE
;SCANNED FIRST ON A CONTROLLER. 

;THE CURRENT UNIT'S POSITION WAIT QUEUE IS MOVED TO ITS TWQ IF
;(AND AS FAR AS) IT IS APPROPRIATE. THE REQUESTS FOR A PARTICULAR
;DEVICE MUST BE FINISHED IN THE ORDER SUBMITTED.

SCHPOS:	MOVSI T1,(KS.ACT)	;IS THE CONTROLLER FREE?
	TDNE T1,KDBSTS(P2)	; ???
	RET			;NO - NOTHING TO DO NOW

POS1:	HRRZ P4,UDBPWQ(P3)	;GET HEAD OF PWQ
	JUMPE P4,POS2		;IF NONE, JUST SCAN OTHER UNITS
	HRRZ T1,UDBDSP(P3)	;GET UNIT DISPATCH
	CALL UDSPRQ(T1)		;DOES THIS REQUEST REQUIRE POSITIONING?
	 SKIPA			;NO - TRANSFER IT TO UNITS TWQ
	JRST POS2		;YES - TRY OTHER UNITS
	CALL OFFPWQ		;PULL REQUEST FROM PWQ
	CALL ONTWQ		;APPEND TO TWQ
	JRST POS1		;AND CHECK AGAIN

POS2:	MOVE Q1,KDBCUN(P2)	;GET CURRENT LOOP POINTER
	JRST POS5		;AND START WITH NEXT UNIT

POS3:	SKIPN P3,(Q1)		;IS THERE A UNIT PRESENT?
	JRST POS4		;NO
	MOVSI T1,(US.OIR!US.OMS!US.MAI!US.MRQ!US.REW!US.CHB) ;OPERATOR INTERVENTION OR REWINDING?
	TDNE T1,UDBSTS(P3)	;IS THIS UNIT AVAILABLE?
	JRST POS4		;NO - KEEP LOOKING
	HRRZ P4,UDBTWQ(P3)	;DOES THIS UNIT HAVE ANY TRANSFER REQS?
	JUMPN P4,R		;YES - LET TRANSFER SCHEDULER DO IT
	HRRZ P4,UDBPWQ(P3)	;ARE THERE ANY POSITION REQUESTS?
	JUMPE P4,POS4		;NO
	MOVEM Q1,KDBCUN(P2)	;YES - SAVE CURRENT UNIT POINTER
	CALL STRTPS		;TRY TO START IT
	 JRST POS5		;FAILED - SEE IF ANYTHING ELSE
	RET			;ALL DONE

POS4:	CAMN Q1,KDBCUN(P2)	;BACK TO ORIGINAL UNIT?
	RET			;YES - IDLE
POS5:	AOBJN Q1,POS3		;LOOP
	MOVE Q1,KDBIUN(P2)	;WRAP AROUND THE UNIT NUMBERS
	JRST POS3		;AND LOOP
	SUBTTL CHANNEL SCHEDULER

SCHXFR::MOVSI T1,(CS.MRQ!CS.MAI!CS.ERC) ;CHANNEL IN MAINT MODE?
	TDNE T1,CDBSTS(P1)	; ?
	RET			;YES - NO NEW ACTIVITY
	SOSLE CDBFCT(P1)	;CHECK "FAIRNESS" COUNT
	JRST SCHLTM		;NOT TIME TO ROUND ROBIN, DO LAT OPT
	MOVSI T1,(CS.AC1)	;IS CHANNEL NOW ACTIVE
	TDNE T1,CDBSTS(P1)	; ??
	RET			;YES - WAS A POSSIBLE COMMAND STACK REQ
	MOVEI T1,INIFCX		;RESET COUNT
	MOVEM T1,CDBFCT(P1)	; ...
XFR0:	MOVE Q1,CDBCUN(P1)	;CONTINUE SCAN FROM LAST ACTIVE UNIT
	JRST XFR3

XFR1:	SKIPN P3,(Q1)		;ANY SUCH UNIT?
	JRST XFR2		;NO - CONTINUE SCAN
	LDB T1,USYBKT		;GET BLOCK TYPE
	CAIE T1,.BTUDB		;UDB?
	JRST XFR4		;SCAN KDB
	HRRZ P2,UDBKDB(P3)	;GET KDB IF ANY
	HRRZ P4,UDBTWQ(P3)	;GET REQUEST
	MOVSI T1,(US.CHB)	;NEED TO CHECK HOME BLOCKS
	TDNE T1,UDBSTS(P3)	; ??
	SKIPN UDBCHB(P3)	;IS A SPECIAL IORB PRESENT?
	SKIPA			;NO TO EITHER QUESTION
	JRST XFRCHB		;YES TO BOTH QUESTIONS
	JUMPE P4,XFR2		;NOTHING - CONTINUE SCAN
	MOVSI T1,(US.OIR!US.OMS!US.MAI!US.MRQ!US.REW!US.CHB) ;OPERATOR INTERVENTION OR REWINDING?
	TDNE T1,UDBSTS(P3)	; ??
	JRST XFR2		;YES - CONTINUE SCAN
	CALL XFRX		;ATTEMPT TO START IO
	 JRST XFR3		;COULDNT - TRY ANOTHER UNIT
	RET			;ALL OK - RETURN

;HERE TO ATTEMPT TO START IO WHEN A REQUEST IS FOUND

XFRX:	MOVEM Q1,CDBCUN(P1)	;SETUP CURRENT UNIT POINTER
	CALLRET STRTIO		;START IO ON THIS IORB

XFR2:	CAMN Q1,CDBCUN(P1)	;BACK TO ORIGINAL UNIT?
	JRST XFRIDL		;YES - NOTHING TO DO, CHANNEL IDLE
XFR3:	AOBJN Q1,XFR1		;ADVANCE UNIT POINTER
	MOVE Q1,CDBIUN(P1)	;WRAPAROUND
	JRST XFR1		;CONTINUE SCAN

;HERE WHEN A CHANNEL GOES IDLE

XFRIDL:	MOVEI T1,INIFCX		;RESET "FAIRNESS" COUNT
	MOVEM T1,CDBFCT(P1)	; ...
	RET			;AND RETURN
;HERE WHEN A UNITS HOME BLOCKS NEED CHECKING

XFRCHB:	MOVSI T1,(US.MAI!US.MRQ!US.REW) ;CAN THIS UNIT BE USED?
	TDNE T1,UDBSTS(P3)	;???
	JRST XFR2		;NO - CONTINUE SCAN
	HRRZ P4,UDBCHB(P3)	;GET SPECIAL IORB
	HRRZ T1,UDBTWQ(P3)	;GET CURRENT HEAD OF TWQ
	CAMN P4,T1		;ALREADY ON TWQ?
	BUG(HLT,PHYCH1,<PHYSIO - HOME BLOCK CHECK IORB ALREADY ON TWQ>)
	MOVE T1,P4		;COPY IORB
	CALL ONFTWQ		;PLACE AT HEAD OF TWQ
	CALL XFRX		;ATTEMPT TO START IT
	 SKIPA			;COULDNT
	RET			;STARTED - RETURN
	CALL OFFTWQ		;PULL IORB
	MOVSI T1,(IS.NRT!IS.DVE) ;INDICATE HARD HARDWARE ERROR
	IORM T1,IRBSTS(P4)	; ...
	CALL DONIRB		;POST AS IF DONE
	JRST XFR3		;AND TRY FOR ANOTHER UNIT
;HERE TO SCAN A KDB FOR UDBS WITH WORK

XFR4:	MOVE P2,P3		;COPY KDB
	MOVSI T1,(KS.ACT)	;IS IT FREE?
	TDNE T1,KDBSTS(P2)	; ???
	JRST XFR2		;NO - MOVE ALONG
	MOVE Q2,KDBCUN(P2)	;GET POINTER
	JRST XFR7		;ENTER BELOW

XFR5:	SKIPN P3,(Q2)		;UNIT PRESENT?
	JRST XFR6		;NO - TRY NEXT
	HRRZ P4,UDBTWQ(P3)	;ANY REQUESTS?
	JUMPE P4,XFR6		;NO - TRY AGAIN
	MOVSI T1,(US.OIR!US.OMS!US.MAI!US.MRQ!US.REW!US.CHB) ;OPERATOR INTERVENTION OR REWINDING?
	TDNE T1,UDBSTS(P3)	; ??
	JRST XFR6		;NO - CONTINUE SCAN
	MOVEM Q2,KDBCUN(P2)	;YES - UPDATE POINTER
	CALL XFRX		;ATTEMPT START IO
	 JRST XFR7		;COULDNT - TRY AGAIN ON ANOTHER UNIT
	RET			;OK.

XFR6:	CAMN Q2,KDBCUN(P2)	;BACK TO STARTING UNIT?
	JRST XFR2		;YES - CONTINUE CHANNEL SCAN
XFR7:	AOBJN Q2,XFR5		;NEXT UNIT AND LOOP
	MOVE Q2,KDBIUN(P2)	;RESET TO START OF TABLE
	JRST XFR5		;AND LOOP
;HERE TO DO DISK LATENCY OPTIMIZATION

;REGISTER USAGE:
;Q1/UDB OF BEST IORB,,LATENCY OF BEST IORB SO FAR(MICROSECONDS)
;Q2/PREDECESSOR OF BEST IORB,,BEST IORB
;Q3/AOBJN POINTER TO UDB TABLE FOR THIS CHANNEL

SCHLTM:	MOVSI T1,(CS.AC1)	;PRIMARY COMMAND ACTIVE?
	TDNE T1,CDBSTS(P1)	; ???
	JRST SCHSTK		;YES - SEE IF WE SHOULD STACK ANOTHER
	MOVEI Q1,777777		;NIL UDB,,LARGE INITIAL BEST LATENCY
	MOVEI Q2,0		;NIL BEST IORBS
	MOVE Q3,CDBIUN(P1)	;GET AOBJN POINTER
	MOVEI P6,0		;INIT COUNT OF NON UDBS

LTM1:	SKIPN P3,(Q3)		;UNIT EXIST?
	JRST LTM2		;NO
	LDB T1,USYBKT		;GET BLOCK TYPE
	CAIE T1,.BTUDB		;UDB?
	AOJA P6,LTM2		;NO
	HRRZ P2,UDBKDB(P3)	;GET KDB (IF ANY)
	HRRZ T1,UDBTWQ(P3)	;IS TWQ NONNULL?
	JUMPE T1,LTM2		;NO
	MOVSI T1,(US.OIR!US.OMS!US.MAI!US.MRQ!US.REW!US.CHB) ;OPERATOR INTERVENTION OR REWINDING?
	TDNE T1,UDBSTS(P3)	;UNIT AVAILABLE FOR TRANSFER?
	JRST LTM2		;NO

	MOVEI T1,MINLAT		;MINIMUM ACCEPTABLE LATENCY
	PUSH P,P6		;SAVE COUNTER
	HRRZ T2,UDBDSP(P3)	;GET UNIT DISPATCH
	CALL UDSLTM(T2)		;GET BEST TRANSFER ON THIS UNIT
	 BUG(HLT,PHYLTF,<PHYSIO - SCHLTM - UNEXPECTED LATOPT FAILURE>)
				;RETURNS T1/LATENCY IN USEC
				;	 T2/ PRED. TO BEST IORB
				;	 T3/ BEST IORB
	POP P,P6		;RESTORE COUNTER
	CAIL T1,(Q1)		;BETTER THAN CURRENT BEST?
	JRST LTM2		;NO - TRY ANOTHER UNIT
	MOVE Q1,T1		;YES - SAVE AS CURRENT BEST TIME
	HRL Q1,P3		;SAVE BEST UDB
	MOVE Q2,T3		;SAVE BEST IORB
	HRL Q2,T2		;SAVE PREDECESSOR TO BEST IORB
LTM2:	AOBJN Q3,LTM1		;LOOP FOR ALL UNITS ON THIS CHANNEL
	JUMPE Q2,LTM3		;NO DISK TRANSFERS - SEE IF ANY AT ALL
	HLRZ P3,Q1		;GET BEST UDB
	HLRZ T1,Q2		;GET PREDECESSOR TO BEST IORB
	HRRZ T2,Q2		;GET BEST IORB
	MOVE P4,T2		; ...
	CALL CONSTW		;PULL FROM TWQ
	MOVE T1,P4		;GET IORB
	CALL ONFTWQ		;PLACE AT HEAD OF TWQ
	CALL STRTIO		;ATTEMPT TO START IO
	 JRST XFR0		;FAILURE - REGRESS TO ROUND ROBIN
	MOVSI T1,(CS.STK)	;CHANNEL SUPPORT COMMAND STACKING?
	TDNN T1,CDBSTS(P1)	; ???
	RET			;NO - DONE
	JRST STK1		;YES - ENTER COMMAND STACK SCHEDULER

LTM3:	JUMPN P6,XFR0		;IF ANY NON UDBS, TRY ROUND ROBIN
	JRST XFRIDL		;NONE - NOW IDLE
;HERE TO DECIDE IF A SECOND COMMAND SHOULD BE STARTED TO THIS CHANNEL
;THOSE CHANNELS (RH20) WHICH SUPPORT A COMMAND STACK CAN BE RUN AT
;THEORETICAL BANDWIDTH ON A PER PAGE BASIS.

;FOR THE PRESENT, ONLY THE CURRENTLY ACTIVE UNIT IS SCANNED FOR
;A REQUEST TO STACK. A REQUEST WILL BE STACKED ONLY IF ITS LATENCY
;IS BETWEEN MINLTS AND MINLAT + (TIME TO TRANSFER ONE PAGE).

SCHSTK:	MOVSI T1,(CS.STK)	;DOES THIS CHANNEL SUPPORT A COMMAND
	TDNN T1,CDBSTS(P1)	;STACK ??
	RET			;NO - DONE
	SKIPGE P3,CDBXFR(P1)	;YES - GET CURRENTLY TRANSFERING UNIT
	RET			;NOT REALLY
	ADDI P3,CDBUDB(P1)	;DOUBLE INDEX
	MOVE P3,(P3)		;TO GET UDB
	LDB T1,USYBKT		;GET BLOCK TYPE
	CAIE T1,.BTUDB		;IS IT A UDB?
	RET			;NO
	HRRZ P4,UDBTWQ(P3)	;GET CURRENT HEAD OF TWQ
STK1:	HRRZ P4,IRBLNK(P4)	;CHECK TO SEE IF MORE
	JUMPE P4,R		;THAN ONE REQUEST
	MOVX T1,SF%FLO		;TEST GLOBAL "FULL LATENCY OPT" ENABLE
	TDNN T1,FACTSW		; OK?
	RET			;NO
	MOVEI T1,0		;YES - FLAG STACK LATOPT, ASSUMES DISK
				; IS JUST AFTER CURRENT PAGE
	HRRZ T2,UDBDSP(P3)	;GET UNIT TRANSFER VECTOR
	CALL UDSLTM(T2)		;COMPUTE BEST LATENCY
	 RET			;NO STACKABLE REQUEST
	CAILE T1,MINLAT		;WILL IT BE LESS THAN MINLAT?
	RET			;NO - WAIT UNTIL CURRENT TRANSFER DONE
	DMOVE T1,T2		;YES - GET PRED IN T1, BEST IN T2
	MOVE P4,T2		;SAVE BEST IORB
	CALL CONSTW		;SPLICE IT OUT OF TWQ
	MOVE T1,P4		;GET IORB AGAIN
	CALL ONSTWQ		;MOVE TO SECOND POSITION ON TWQ
	CALL STKIO		;STACK COMMAND
	 JFCL			;NOTHING TO DO ABOUT IT
	RET
	SUBTTL UDSKIO

;UDSKIO REPLACEMENT
;T1/ PHYSICAL DISK ADDRESS (INCLUDE STRUCTURE IN THE FULLNESS...)
;T2/DOP%WR IF WRITE,,COUNT ;TRANSFER CANNOT CROSS PAGE BOUNDRY
;T3/ PHYSICAL MEMORY ADDRESS
;T4/ CHANNEL #,,UNIT #	;IF 1B0 ON IN T2
;	AND STRUCTURE NUMBER IF 1B0 IS OFF IN T2
;	CALL UDSKIO
;RETURNS+1(ALWAYS)
;T1/ ZERO IF OK, ERROR BITS IF NOT OK

UDSKIO::SAVEPQ			;SALT AWAY ACCUMULATORS
	SE0ENT			;USE SEC0 FOR PHYSIO CALLS
	CALL GETIRB		;GET IORB+CCW BLOCK IN P4, WAIT IF NEEDED
	TLZ T1,DSKMSK		;CLEAR UNUSED BITS
	TLO T1,(DSKAB)		;AND SET DISK ADDRESS BIT
	MOVEM T1,IRBADR(P4)	;STORE DEVICE ADDRESS
	HRRZM T2,IRBCNT(P4)	;STORE COUNT IN IORB
	MOVEI T1,IRFRED		;SEE IF READ OR WRITE
	TLNE T2,(DOP%WR)	; ...
	MOVEI T1,IRFWRT		;IS WRITE.
	DPB T1,IRYFCN		;STORE IN IORB
	MOVEI T1,IRMWRD		;WORD MODE
	DPB T1,IRYMOD		;STORE IN IORB
	MOVEI T1,0		;COPY INHIBIT ERR LOG OR RECOVERY BITS
	TLNE T2,(DOP%IR)	;INHIBIT RECOVERY?
	TLO T1,(IS.IER)		;YES, INHIBIT IT.
	TLNE T2,(DOP%IL)	;INHIBIT LOGGING?
	TLO T1,(IS.IEL)		;YES
	IORM T1,IRBSTS(P4)	;STORE IN IORB
	MOVEI T1,0		;NO SIO EXIT NEEDED UNLESS
	TLNE T2,(DOP%EO)	;USER ASKED FOR ERROR ON OFFLINE
	MOVEI T1,UDISIE		;CALLER WANTS ERROR
	HRLM T1,IRBIVA(P4)	;STORE EXIT OR NOT
	TLNN T2,(1B0)		;USE CHANNEL,,UNIT IN T4?
	JRST UIO1		; NO
	HLRZ P1,T4		;YES - GET CDB
	SKIPN P1,CHNTAB(P1)	;EXIST?
	JRST UIONCH		;NO SUCH CHANNEL - RETURN ERROR
	ADDI T4,CDBUDB(P1)	; ...
	SKIPN P3,(T4)		;EXIST?
	JRST UIONUN		;NO SUCH UNIT - RETURN ERROR
	MOVSI T1,DSKMSK		;INVALID BITS IN DISK ADDRESS
	ANDCAM T1,IRBADR(P4)	;CLEAR DSKAB & PERHAPS OTHER GARBAGE
	JRST UIO2		;JOIN OTHER PROCESSING
UIO1:	CALL GETCUB		;GET CDB/ UDB
	 JRST UIOILA		;ILLEGAL ADDRESS
				;P1,P3,T1 SETUP AS CDB,UDB,UNIT ADDRESS
	MOVEM T1,IRBADR(P4)	;STORE UNIT RELATIVE ADDRESS IN IORB
UIO2:	TLNN T2,(DOP%EO)	;WANT ERROR ON OFFLINE?
	JRST UIO3		;NO - QUEUE IT UP
	MOVSI T1,(CS.OFL)	;OFFLINE?
	TDNE T1,CDBSTS(P1)	; ?
	JRST UIOCFL		;YES - RETURN ERROR
	MOVSI T1,(US.OFS!US.CHB) ;OFFLINE OR UNSAFE?
	TDNE T1,UDBSTS(P3)	; ??
	JRST UIOUFL		;YES - RETURN ERROR
UIO3:	LDB T1,USYTYP		;GET DEVICE TYPE
	MOVSI T4,-NDSKUT	;CHECK IF IT IS A FILE DISK
	CAME T1,DSKUTP(T4)	; ??
	AOBJN T4,.-1		;LOOP
	SKIPL T4		;WAS THIS UNIT TYPE FOUND?
	JRST UIONDS		;NO - NOT DISK ERROR
	MOVSI T1,IRMWRD		;CONSTRUCT CCW LIST
	HRR T1,T2		;COPY COUNT
	MOVE T2,T3		;COPY ADDRESS IN MEMORY
	HRRZ T4,CDBDSP(P1)	;GET DISPATCH BASE
	CALL CDSCCW(T4)		;BUILD CCW INTO T1
	MOVEM T1,IRBLEN(P4)	;STORE
	SETZM IRBLEN+1(P4)	;CLEAR SECOND WORD
	MOVEI T1,IRBLEN(P4)	;BUILD TAIL,,HEAD OF CCW LIST
	HRLI T1,IRBLEN+1(P4)	; ...
	MOVEM T1,IRBXFL(P4)	;STORE
	MOVEI T1,UDIINT		;INTERRUPT ROUTINE TO CALL
	HRRM T1,IRBIVA(P4)	;STORE IN IORB
	MOVE T1,P4		;CALL TO START IO
	HRLZ T2,P1		;SETUP CDB
	HRR T2,P3		;AND UDB
	NOSKED			;FOR PHYSIO CALL
	CALL PHYSIO		; ...
	OKSKED
UIO4:	MOVEI T1,UDWDON		;WAIT FOR DONE
	HRL T1,P4		;ON THIS IORB
	PDISMS			; AS A PAGE FAULT
	MOVE T1,IRBSTS(P4)	;EXAMINE STATUS BITS
	TLNN T1,(IS.DON)	;CONDITION SATISFIED?
	JRST UIO4		;NO - BLOCK AGAIN
	TLNN T1,(IS.ERR)	;ANY ERRORS?
	MOVEI T1,0		;NO - RETURN 0
UIOXIT:	CALL GIVIRB		;RELEASE THIS IORB
	SE1CAL			;RETURN TO CALLER SECTION
	RET
;HERE FOR VARIOUS UDSKIO ERRORS. CURRENT CALLERS EXPECT
;ONLY -1 FOR VARIOUS NONEXISTANT OR OFFLINE CONDITIONS.

UIONCH:
UIONUN:
UIOCFL:
UIOUFL:
UIOILA:
UIONDS:	MOVNI T1,1		;NON DISK ERROR CODE
	JRST UIOXIT

;HERE JUST BEFORE SIO OF UDSKIO REQUEST
;CHECK IF UNIT OFFLINE

UDISIE:	MOVSI T1,(US.OFS!US.CHB)	;UNIT ACCESSABLE
	TDNN T1,UDBSTS(P3)	; ???
	RETSKP			;YES - GO AHEAD
	MOVSI T1,(IS.ERR!IS.NRT) ; NO -ERRORS
	IORM T1,IRBSTS(P4)	;STORE
	RET			;FAIL RETURN

;HERE AT INTERRUPT LEVEL WHEN REQUEST COMPLETED

UDIINT:	AOS PSKED		;FLAG SCHEDULER
	RET

;HERE TO GET AN IORB FROM THE POOL
;	CALL GETIRB
;RETURNS+1(ALWAYS):
;P4/ IORB + CCW BLOCK (LENGTH UIOLEN)
;CLOBBERS P3

GETIRB:	SKIPN NSKED		;NOSKED?
	JRST GETIR1		;NO - USUAL CASE
	SKIPN UIOLST		;YES - ANY LEFT
	BUG(HLT,UIONIR,<UDSKIO - NO IORB FOR NOSKED FORK>)
	MOVE P4,@UIOLST		;GET SUCCESSOR
	EXCH P4,UIOLST		;NOW HEAD OF LIST
	JRST GETIR2		;CLEAR IORB AND RETURN

GETIR1:	NOSKED			;INTERLOCK LIST MANIPULATION
	SKIPN UIOLST		;LIST NONNULL?
	JRST GETIR3		;NO.
	SKIPN P4,@UIOLST	;TEST/GET SUCCESSOR
	JRST GETIR3		;NO SUCCESSOR - FORCE BLOCK
	EXCH P4,UIOLST		;NEW HEAD OF LIST
	OKSKED			;RELEASE PROCESSOR
GETIR2:	SETZM 0(P4)		;CLEAR FIRST WORD OF BLOCK
	MOVS P3,P4		;BUILD BLT POINTER
	HRRI P3,1(P4)		; ...
	BLT P3,UIOLEN-1(P4)	;CLEAR BLOCK
	RET

GETIR3:	OKSKED			;WE MUST BLOCK
	CALL UDIWAT		; ...
	JRST GETIR1		;AND TRY AGAIN

;SCHEDULER TEST ROUTINE, WAITS FOR IORB DONE BIT

UDWDON::MOVSI T2,(IS.DON)	;CHECK DONE BIT
	TDNN T2,IRBSTS(T1)	;IN IORB
	JRST 0(T4)		;STILL WAITING
	JRST 1(T4)		;ALL DONE

;HERE WHEN THE IORBS ARE IN USE. WAIT FOR THEM TO BECOME FREE

UDIWAT:	SAVET			;SAVE ARGUMENTS
UDIWT1:	MOVEI T1,UDITST		;WAIT FOR FREE IORB
	MDISMS			;ORDINARY BLOCK - MAY BE LONG TERM
	RET			;FREE, LOCK ACQUIRED

;SCHEDULE TEST TO WAIT FOR IORB

UDITST:	SKIPE T1,UIOLST		;LIST NON NULL
	SKIPN (T1)		;AT LEAST 2 FREE?
	JRST 0(T4)		;NO
	JRST 1(T4)		;YES

;HERE TO RELEASE AN IORB TO THE FREE LIST

GIVIRB:	NOSKED
	EXCH P4,UIOLST		;NEW HEAD OF LIST
	MOVEM P4,@UIOLST	;STORE FOREWARD LINK
	OKSKED
	RET
	SUBTTL PAGEM INTERFACE

;HERE TO TRANSFER A PAGE
;T1/ CPN	;1B0 ON IF WRITE
;	CALL DSKIO, DRMIO
;RETURNS+1(ALWAYS)

DSKIO::
DRMIO::	PUSH P,P4		;SAVE P4, IORB MUST BE IN P4 FOR IRYFCN
	PUSH P,T1		;SAVE T1 FOR PAGEM
	MOVSI T2,(DWRBIT)	;COPY WRITE BIT TO CST3 FOR PAGEM
	AND T2,T1		; ...
	IORM T2,CST3(T1)	; ...
	MOVEI P4,CST5(T1)	;PUT IORB ADDRESS IN P4
	MOVSI T2,(IS.SHT)	;FLAG AS SHORT IORB
	MOVEM T2,IRBSTS(P4)	;INITIALIZE IORB
	MOVEI T2,IRFRED		;SET IORB FUNCTION
	TLNE T1,(DWRBIT)	;WRITE?
	MOVEI T2,IRFWRT		;YES
	DPB T2,IRYFCN		;STORE IN IORB
	MOVE T1,P4		;COPY IORB ADDRESS
	CALL PHYSIO		;NOTE - ALREADY NOSKED
	POP P,T1		;RESTORE T1
	POP P,P4		;RESTORE P4
	RET

;HERE TO QUEUE A LIST OF PAGES FOR SWAPPER
;T1/ DWRBIT,,FIRST PAGE CST INDEX
;	CALL DXXIOM
;RETURNS+1(ALWAYS):
;	WHOLE LIST STARTED

DSKIOM::
DRMIOM::PUSH P,P4		;SAVE VARIABLE FOR POINTER
IOMNXT:	HRRZ P4,CST3(T1)	;GET FORWARD LINK
	HLLZS CST3(T1)		;CLEAR FORWARD LINK IN MEMORY
	CALL DRMIO		;INSERT REQUEST
	JUMPE P4,IOMXIT		;WAS LINK NULL
	SUBI P4,CST3		;NO - GET CST INDEX
	HRR T1,P4		;COPY (NOTE: DWRBIT IS STILL IN LH(T1))
	JRST IOMNXT		;LOOP

IOMXIT:	POP P,P4		;RESTORE
	RET

DRMINI::SETOM DRMJ0R		;SO OLD ERROR LOGGER IS HAPPY
	SKIPG DRUMP
	TDZA T1,T1		;NO DRUMS UNLESS DRUMP .GT. 0
	MOVE T1,DRMNUM		;GET NUMBER OF DRUMS FROM RS4INI
	MOVEM T1,NPDRMS		;STORE FOR REST OF WORLD
	RET
	SUBTTL OPERATOR INTERVENTION, RESTART AND TIMEOUT

;ENTERED FROM SCHEDULER WHEN PHYTIM GT TODCLK.

PHYCHK::SAVEPQ			;SAVE ACCUMULATORS
	SE0ENT			;MAY CALL LOWER LEVELS, USE SEC0
	MOVEI T1,^D1000		;UPDATE NEXT CALL
	MOVEM T1,PHYTIM		; ...
	AOS T1,PHYSEC		;INCREMENT LOCAL ONCE A MINUTE TIMER
	CAILE T1,^D59		;AND IF EXPIRED,
	SETZM PHYSEC		;WRAPAROUND
	MOVSI T1,(IS.DON)	;IS HOME BLOCK CHECK IORB DONE?
	SKIPE CHBUDB		;IS A UNIT BEING CHECKED FOR HOME BLOCK
	TDNN T1,CHBIRB		;DONE?
	SKIPA			;NO TO EITHER QUESTION
	JRST CHK7		;YES TO BOTH
	MOVE T1,CHBODT		;NOW CHECK HOME BLOCK IORB OVERDUE
	CAMGE T1,TODCLK		; ...
	SKIPN CHBUDB		;IS HOME BLOCK CHECKER ACTIVE?
	SKIPA			;NO TO EITHER QUESTION
	JRST CHK3		;APPARENTLY OVERDUE - INVESTIGATE FURTHER
CHK0:	MOVSI Q1,-CHNN		;LOOP OVER ALL CHANNELS
CHK1:	SKIPN P1,CHNTAB(Q1)	;IS THIS CHANNEL PRESENT?
	JRST CHK2		;NO - TRY NEXT
	MOVSI T1,(CS.OFL!CS.MAI) ;CHANNEL OFFLINE OR IN MAINTENENCE MODE
	TDNE T1,CDBSTS(P1)	;OR HAVE NO UNITS?
	JRST CHK2		;YES - IGNORE IT.
	CALL DGUMAP		;YES - FOR EACH UNIT,
	 CALL UNICHK		;DO CHECK CODE
	HRRZ T1,CDBDSP(P1)	;GET CHANNEL DISPATCH
	CALL CDSCHK(T1)		;AND CALL PERIODIC CHECKER
CHK2:	AOBJN Q1,CHK1		;AND LOOP FOR ALL CHANNELS
	SE1CAL			;RETURN
	RET			;DONE

;HERE WHEN THE HOME BLOCK CHECK IORB SEEMS TO BE OVERDUE

CHK3:	IOPIOF			;INTERLOCK CHECKS
	SKIPE P3,CHBUDB		;GET UNIT BEING CHECKED
	JRST CHK5		;IF THERE IS STILL ONE
CHK4:	IOPION			;RESTORE INTERRUPTS
	JRST CHK0		;AND CONTINUE CHECKS

CHK5:	MOVE T1,CHBODT		;RE-CHECK OVERDUE TIMER
	CAML T1,TODCLK		;INCASE CHANGED
	JRST CHK4		;NO LONGER OVERDUE
	MOVEI T1,(US.ACT)	;IS THIS UNIT ACTIVE?
	TDNN T1,UDBSTS(P3)	; ???
	JRST CHK6		;NO
	HRRZ P1,UDBCDB(P3)	;YES - GET CHANNEL
	HRRZ T1,UDBTWQ(P3)	;GET CURRENT TWQ HEAD
	CAIE T1,CHBIRB		;IS IT SPECIAL IORB?
	JRST CHK6		;NO - JUST REMOVE REQUEST
	BUG(INF,PHYCH2,<PHYSIO - HOME BLOCK CHECK IORB TIMED OUT>)
	CALL HNGIRB		;TERMINATE IORB IN T1
	JRST CHK4		;RESTORE PI AND CONTINUE
CHK6:	BUG(INF,PHYCH3,<PHYSIO - HOME BLOCK CHECK IORB TIMED OUT BUT WAS NOT ON TWQ>)
	CALL CLRCHB		;CLEAR HOME BLOCK CHECK DATA
	JRST CHK4		;AND CONTINUE CHECKS

;HERE IF THE HOME BLOCK CHECK IORB IS DONE.

CHK7:	HRRZ P3,CHBUDB		;GET UNIT BEING CHECKED
	HRRZ P2,UDBKDB(P3)
	HRRZ P1,UDBCDB(P3)	;GET CHANNEL UNIT IS ON
	MOVSI T1,(IS.ERR)	;ANY ERRORS?
	TDNE T1,CHBIRB+IRBSTS	;???
	JRST CHKA		;YES - COMPLAIN
	SKIPGE Q1,UDBSTR(P3)	;GET STR UNIT IS IN
	JRST CHK9		;UNIT NO LONGER IN STR
	MOVE Q1,STRTAB(Q1)	;GET SDB
	MOVE T1,CHBHB1+HOMNAM	;CHECK HOME BLOCK NAME AND CODE
	MOVE T2,CHBHB2		;GET HOMCOD (SYMBOL? )
	CAMN T1,[SIXBIT /HOM/]	;BLOCK NAME GOOD?
	CAIE T2,CODHOM		;BLOCK CODE GOOD?
	JRST CHK8		;NO TO EITHER
	MOVE T1,CHBHB1+HOMSNM	;CHECK STRUCTURE NAME
	MOVE T2,CHBHB1+HOMMID	;AND "UNIQUE" ID
	CAMN T1,SDBNAM(Q1)	;SAME NAME?
	CAME T2,SDBPUC(Q1)	;SAME CODE?
	JRST CHK8		;NO TO EITHER
	HRRZ T1,CHBHB1+HOMLUN	;CHECK IF SAME UNIT
	CAILE T1,MXSTRU		;LESS THAN MAXIMUM?
	JRST CHK8		;NO
	ADDI T1,SDBUDB(Q1)	;YES - GET POINTER TO UDB
	HRRZ T1,(T1)		;GET UDB
	HLRZ T2,CHBHB1+HOMLUN	;GET NUMBER OF UNITS
	CAMN T1,P3		;SAME UNIT AS THIS?
	CAME T2,SDBNUM(Q1)	;SAME TOTAL NUMBER?
	JRST CHK8		;NO TO EITHER
	MOVSI T1,(US.OMS)	;SEEMS TO MATCH - PREVENT ANY
	IORM T1,UDBSTS(P3)	;DEADLOCK
	MOVSI T1,(US.CHB)	;NO LONGER NEED CHECKING - ALLOW IO
	ANDCAM T1,UDBSTS(P3)	; ...
CHKX:	CALL CLRCHB		;RESET HOME BLOCK CHECK DATA
	JRST CHK0		;AND DO USUAL TIMER THING

;HERE WHEN THE HOME BLOCK MISCOMPARES OR IS ILL FORMED

CHK8:	HRROI T1,[ASCIZ /
%WRONG PACK ON DEVICE:/]	;SLIGHTLY MISLEADING MESSAGE
	SKIPE PHYSEC		;ONLY REPORT ONCE A MINUTE
	JRST CHKX		;NOT TIME
	CALL UNIMES		;USE COMMON MESSAGE TAIL
	AOS PHYSEC		;CROCK COMPENSATION FOR TTEMES
	JRST CHKX		;AND JOIN NORMAL CHECKS

;HERE WHEN UNIT CHANGED STRUCTURE STATUS (FORCE REMOVAL?)

CHK9:	MOVSI T1,(US.CHB)	;CLEAR CHECK HOME BLOCK BIT
	ANDCAM T1,UDBSTS(P3)	; ...
	JRST CHKX		;AND DO NORMAL CHECKS

;HERE WHEN AN IO ERROR OCCURS READING A HOME BLOCK

CHKA:	HRROI T1,[ASCIZ /
%ERROR READING HOME BLOCK ON DEVICE:/]
	SKIPE PHYSEC		;PREVENT OUTPUT OVERLOAD
	JRST CHKX		;EXIT
	CALL UNIMES		;APPEND STOCK TRAILER
	AOS PHYSEC
	JRST CHKX

;HERE TO CLEAR HOME BLOCK CHECKING DATABASE

CLRCHB:	SETZM UDBCHB(P3)	;CLEAR SPECIAL IORB
	SETZM CHBODT		;CLEAR TIMER
	MOVEM P3,CHBLUC		;SETUP LAST UNIT CHECKED CELL
	SETZM CHBUDB		;CLEAR CURRENT CHECK UDB
	MOVSI T1,(IS.DON)	;CLEAR DONE FLAG
	ANDCAM T1,CHBIRB+IRBSTS	; ...
	RET
;HERE FOR EACH UNIT. CHECK IF OPERATOR MESSAGE NEEDED OR RESTART NEEDED.
;IF UNIT IS ACTIVE, CHECK OVERDUE TIMER AND RESET IF HUNG.
;PRESERVES Q1-Q3

UNICHK:	MOVSI T1,(US.MAI)	;UNIT IN MAINTENENCE MODE?
	TDNE T1,UDBSTS(P3)	; ??
	JRST UNICK5		;YES - DISABLE USUAL CHECKS
	MOVSI T1,(US.MRQ)	;MAINTENENCE MODE REQUESTED?
	TDNE T1,UDBSTS(P3)	; ??
	JRST UNICK6		;YES - CHECK IF NOW ALLOWED
	MOVSI T1,(US.CHB)	;DOES THIS UNIT NEED ITS HOME BLOCKS CHECKED?
	TDNE T1,UDBSTS(P3)	; ??
	JRST UNICK7		;YES - SEE WHAT CAN BE DONE
UNICK0:	MOVSI T1,(US.OIR)	;OPER INTERVENTION REQUEST?
	TDNN T1,UDBSTS(P3)	; ??
	JRST UNICK3		;NO - TRY OTHER CASES
	ANDCAM T1,UDBSTS(P3)	;YES - RESET BIT
	CALL UNITRY		;ATTEMPT TO RESTART IO
	 SKIPA			;ATTEMPT FAILED OR INDETERMINATE
	JRST UNIOK		;SUCCESS.
	MOVSI T1,(US.OMS)	;OPERATOR MESSAGE ON MINUTE?
	TDNE T1,UDBSTS(P3)	; ??
	JRST UNICK2		;YES - CHECK FOR MINUTE
	IORM T1,UDBSTS(P3)	;NO - REQUEST IT AND PRINT MESSAGE NOW
UNICK1:	HRROI T1,[ASCIZ /
%PROBLEM ON DEVICE: /]
	CALL UNIMES		;ISSUE MESSAGE
	RET			;AND EXIT THIS UNIT

UNICK2:	SKIPN PHYSEC		;MINUTE BOUNDRY?
	JRST UNICK1		;YES - PRINT MESSAGE
	RET			;NO - EXIT THIS UNIT

UNICK3:	MOVSI T1,(US.OMS)	;OPERATOR MESSAGE ON MINUTE?
	TDNN T1,UDBSTS(P3)	; ??
	JRST UNICKT		;NO - CHECK TIMEOUT
	CALL UNITRY		;DO RETRY
	 JRST UNICK2		;FAILED - DO RETRY
UNIOK:	MOVSI T1,(US.OMS)	;SUCCESS - CLEAR MESSAGE BIT
	ANDCAM T1,UDBSTS(P3)	; ...
	RET			;DONE WITH THIS UNIT
;HERE TO CHECK TIMER

UNICKT:	MOVSI T1,(US.ACT)	;UNIT NOW ACTIVE?
	TDNN T1,UDBSTS(P3)	; ??
	RET			;NO - ALL DONE
	MOVE T1,UDBODT(P3)	;CHECK OVERDUE TIME
	CAML T1,TODCLK		;AGAINST PRESENT TIME
	RET			;NOT OVERDUE
	SAVEQ			;OVERDUE - SAVE Q ACCUMULATORS
	MOVSI T2,(US.POS)	;PREPARE FOR PIOFF TESTS
	MOVSI T3,(US.ACT)	; ...
	IOPIOF			;INTERLOCK AGAINST RACE
	MOVE T1,UDBODT(P3)	;GET OVERDUE TIME AGAIN
	CAMGE T1,TODCLK		;CHECK STILL OVERDUE
	TDNN T3,UDBSTS(P3)	;AND STILL ACTIVE
	JRST ONRET		;NOT BOTH - LOST RACE, USER WON.
	PUSH P,T1
	PUSH P,T2		;SAVE SOME REGS
	PUSH P,T3		;SAVE SOME MORE
	HRRZ T1,UDBADR(P3)	;GET SLAVE UNIT #
	MOVE T3,CDBXFR(P1)	;GET MASSBUS UNIT NUMBER
	HRRZ T2,CDBADR(P1)	;GET CHANNEL #
	BUG(INF,OVRDTA,<PHYSIO - OVERDUE TRANSFER ABORTED>,<T1,T3,T2>)
	POP P,T3
	POP P,T2
	POP P,T1		;RESTORE REGS
	TDNE T2,UDBSTS(P3)	;CHECK SEEK OR TRANSFER THAT LOST
	JRST [	CALL OFFPWQ	;WAS SEEK, PULL IORB
		JRST UNICK4]	;AND ABORT
	CALL OFFTWQ		;WAS TRANSFER, PULL IORB
UNICK4:	CALL HNGIRB		;TERMINATE HUNG IORB AND RESTART CHAN
ONRET:	IOPION			;AT LONG LAST
	RET

UNICK5:	IOPIOF			;INTERLOCK CHECK
	MOVE T1,UDBODT(P3)	;CHECK OVERDUE TIME
	JUMPE T1,ONRET		;UNTIMED
	CAML T1,TODCLK		;CHECK AGAINST NOW
	JRST ONRET		;STILL OK
	MOVE T1,UDBONR(P3)	;GET OWNING FORK
	HRRZ T1,FKJOB(T1)	;GET JOB
	CALL ELOGOO		;LOGOUT OUT THAT JOB
	IOPION
	RET

UNICK6:	MOVSI T1,(US.ACT)	;CHECK IF UNIT STILL ACTIVE
	TDNE T1,UDBSTS(P3)	; ??
	JRST UNICK0		;YES - PERFORM USUAL CHECKS
	MOVSI T1,(US.MAI)	;NO - SET IT INTO MAINTENENCE MODE
	IORM T1,UDBSTS(P3)	; ...
	RET			;AND CONTINUE SCAN
;HERE WHEN A UNIT NEEDS ITS HOME BLOCKS CHECKED

UNICK7:	SKIPE CHBUDB		;IS A UNIT CURRENTLY BEING CHECKED?
	JRST UNICK0		;YES - CONTINUE OTHER CHECKS
	CAME P3,CHBLUC		;NO - WAS THIS UNIT THE LAST ONE CHECKED
	JRST UNICK8		;NO - ATTEMPT CHECKS
	SETZM CHBLUC		;YES - BYPASS THIS TIME
	JRST UNICK0		;AND CONTINUE CHECKS

UNICK8:	SKIPGE UDBSTR(P3)	;IS THIS UNIT NOW PART OF A STR?
	JRST UNICKA		;NO - CLEAR CHECK REQUEST
	MOVSI T1,(US.OFS!US.ACT!US.MAI) ;IS THIS UNIT OFFLINE OR ACTIVE?
	IOPIOF			;INTERLOCK TESTS
	TDNE T1,UDBSTS(P3)	; ???
	JRST UNICK9		;YES - CANNOT CHECK
	HRRZM P3,CHBUDB		;STORE THIS UNIT AS CURRENTLY CHECKED
	MOVEI T1,^D20000	;SET TIMEOUT FOR 20 SECONDS
	ADD T1,TODCLK		; ...
	MOVEM T1,CHBODT		;STORE OVERDUE TIME
	MOVE T1,[CHBIRB,,CHBIRB+1] ;SETUP TO CLEAR IORB
	SETZM CHBIRB		;CLEAR IORB
	BLT T1,CHBIRB+IRBLEN-1	; ...
	MOVEI P4,CHBIRB		;GET IORB IN STANDARD PLACE
	MOVEI T1,IRFRED		;GET READ FUNCTION CODE
	DPB T1,IRYFCN		;STORE IN IORB
	MOVEI T1,IRMWRD		;GET WORD MODE
	DPB T1,IRYMOD		;STORE IN IORB
	MOVSI T1,(IS.IEL)	;INHIBIT ERROR LOGGING
	IORM T1,IRBSTS(P4)	; ...
	MOVEI T1,HBLEN		;SETUP COUNT
	HRRZM T1,IRBCNT(P4)	; ...
	MOVE T1,[CHBCCL+1,,CHBCCL] ;GET TAIL+1,,HEAD OF CHANNEL COMMAND LIST
	MOVEM T1,IRBXFL(P4)	;STORE IN IORB
	MOVE Q1,UDBSTR(P3)	;GET STRUCTURE NUMBER
	MOVE Q1,STRTAB(Q1)	;GET SDB
	MOVEI T2,HM1BLK		;GET ADDRESS OF PRIMARY HOME BLOCK
	MOVX T1,HB%1OK		;WAS PRIMARY HOME BLOCK GOOD?
	TDNN T1,SDBSTS(Q1)	; ???
	MOVEI T2,HM2BLK		;NO - ATTEMPT READ OF SECONDARY
	MOVEM T2,IRBADR(P4)	;STORE ADDRESS DECIDED UPON
	MOVEI T1,CHBINT		;INTERRUPT ROUTINE
	MOVEM T1,IRBIVA(P4)	; STORE IN IORB
	MOVSI T1,IRMWRD		;SETUP TO BUILD FIRST CCW
	HRRI T1,HBLEN		;COUNT
	MOVEI T2,CHBHB1		;ADDRESS 
	HRRZ T3,CDBDSP(P1)	;GET CHANNEL DISPATCH
	CALL CDSCCW(T3)		;BUILD CCW
	MOVEM T1,CHBCCL		;STORE IN CHANNEL COMMAND LIST
	MOVEM P4,UDBCHB(P3)	;STORE SPECIAL IORB IN UDB
	MOVSI T1,(CS.ACT)	;IS CHANNEL ACTIVE?
	TDNE T1,CDBSTS(P1)	; ???
	JRST UNICK9		;YES - CANT START IT NOW
	MOVE T1,P4		;PLACE ON HEAD OF TWQ
	CALL ONFTWQ		; ...
	CALL STRTIO		;ATTEMPT STARTUP NOW
	 SKIPA			;FAILED - UNIT WAS WRONG ABOUT ONLINE
	JRST ONRET		;SUCCESS - ENABLE PI AND RETURN
	CALL OFFTWQ		;PULL FROM QUEUE
	CALL CLRCHB		;UNDO ABOVE WORK
UNICK9:	IOPION
	JRST UNICK0		;COULDNT CHECK AFTERALL


;HERE WHEN A UNIT CHANGES STRUCTURE STATUS

UNICKA:	MOVSI T1,(US.CHB)	;CLEAR CHECK HOME BLOCKS BIT
	ANDCAM T1,UDBSTS(P3)	; ...
	JRST UNICK0		;AND DO USUAL CHECKS


;INTERRUPT ROUTINE FOR HOME BLOCK CHECKER IO

CHBINT:	SETZM UDBCHB(P3)	;ONLY NEED THIS STARTED ONCE
	RET
;HERE TO ATTEMPT RESTART OF A FAILED IORB

UNITRY:	SAVEQ			;PRESERVE REGISTERS
	MOVSI T1,(US.ACT!US.CHB) ;UNIT ACTIVE NOW?
	MOVSI T2,(KS.ACT)	;OR CONTROLLER?
	IOPIOF			;INTERLOCK
	TRNE P2,-1		;KDB ?
	TDNN T1,KDBSTS(P2)	;ACTIVE?
	TDNE T1,UDBSTS(P3)	;ACTIVE?
	JRST ONRET		;YES - FATE INDETERMINATE
	HRRZ P4,UDBTWQ(P3)	;ANY TRANSFERS PENDING?
	JUMPN P4,UNITR2		;YES - ATTEMPT RESTART
	HRRZ P4,UDBPWQ(P3)	;ANY SEEKS?
	JUMPN P4,UNITR1		;YES - RESTART
ONRSKP:	IOPION			;NOTHING AT ALL, MUST HAVE WON
	RETSKP			;AND SAY SO.

UNITR1:	CALL STRTPS		;RESTART POSITION OPERATION
	 JRST ONRET		;FAILED
	JRST ONRSKP		;WON - SUCCESS RETURN

UNITR2:	MOVSI T1,(CS.ACT)	;CHANNEL ACTIVE?
	TDNE T1,CDBSTS(P1)	; ???
	JRST ONRET		;YES - RETURN INDETERMINATE
	CALL STRTIO		;NO - RESTART IO OPERATION
	 JRST ONRET		;FAILED
	JRST ONRSKP		;WON - SUCCESS RETURN

;HERE TO TERMINATE A HUNG IORB AND RESTART CHANNEL ACTIVITY

;T1/ IORB
;P1 SETUP
;WIPES THE REGISTERS
;MUST BE CALLED IOPIOF 

HNGIRB:	MOVE P4,T1		;SETUP IORB IN EXPECTED PLACE
	MOVSI T1,(IS.NRT!IS.DVE) ;MARK IORB AS FATAL ERROR
	IORM T1,IRBSTS(P4)	; ...
	MOVSI T1,(US.REW)	;CLEAR REWINDING
	ANDCAM T1,UDBSTS(P3)	; IN THE UDB
	MOVSI T1,(US.POS)	;WAS THIS A POSITION REQUEST?
	TDNE T1,UDBSTS(P3)	; ???
	JRST HNGIR1		;YES
	HRRZ T1,CDBDSP(P1)	;GET CHANNEL DISPATCH
	CALL CDSHNG(T1)		;DO HUNG RESET
	CALL CLRACT		;RESET ALL ACTIVE BITS
	CALL DONIRB		;POST AS COMPLETE
	CALL SCHSEK		;START SEEKS (IF APPROPRIATE)
	CALL SCHXFR		;RESTART CHANNEL IF ANY WORK
	RET

;HERE TO CLEAN UP AFTER A HUNG SEEK

HNGIR1:	CALL CLRPOS		;NO LONGER POSITIONING
	CALL DONIRB		;POST COMPLETE WITH ERRORS
	CALL SCHSEK		;START ANOTHER SEEK
	MOVSI T1,(CS.ACT!CS.ERC) ;CHANNEL NOW IDLE?
	TDNN T1,CDBSTS(P1)	; ???
	CALL SCHXFR		;YES - SEE IF ANYTHING ELSE TO DO
	RET
;HERE TO ISSUE A MESSAGE TO THE OPERATOR
;T1/ POINTER TO INITIAL MESSAGE

UNIMES:	SAVEQ			;PRESERVE REGISTERS
	CALL PMES		;PRINT START OF MESSAGE
	MOVSI T1,(US.TAP)	;MAGTAPE?
	TDNE T1,UDBSTS(P3)	; ???
	JRST UNIMS5		;YES, PRINT OUT "MTAN"
	LDB T1,USYTYP		;GET UNIT TYPE
	MOVE T1,NAMUTP(T1)	;GET NAME AS STRING POINTER
	CALL PMES		;PRINT TYPE
	SKIPL Q1,UDBSTR(P3)	;UNIT IN STR?
	SKIPN Q1,STRTAB(Q1)	; ???
	JRST UNIMS0		;NO
	HRROI T1,[ASCIZ /, STR=/]
	CALL PMES		;YES - PRINT NAME
	MOVE T1,SDBNAM(Q1)	;COPY STR NAME
	CALL PSIX		;PRINT IT
UNIMS0:	SKIPN UDBDSN(P3)	;SERIAL NUMBER KNOWN?
	JRST UNIMS2		;NO - SKIP THAT PART
	HRROI T1,[ASCIZ /, S.N.=/]
	CALL PMES		;PREPARE TO PRINT SERIAL
	MOVE Q1,UDBDSN(P3)	;GET SERIAL NUMBER
	CALL UNIDEC		;PRINT THE SERIAL NUMBER
UNIMS2:	HRROI T1,[ASCIZ /, ACCESS PATH: CHN=/] ;PREPARE NEXT PART
	CALL PMES		;PRINT
	HRRZ T1,CDBADR(P1)	;GET CHANNEL NUMBER
	CALL PNUM		;PRINT IT
	JUMPN P2,UNIMS4		;IF KDB, PRINT APPROPRIATE MESSAGE
UNIMS3:	HRROI T1,[ASCIZ /, UNI=/] ;PREPARE NEXT
	CALL PMES
	HRRZ T1,UDBAKA(P3)	;GET ADDRESS
	SKIPE P2		;UNLESS TAPE
	HRRZ T1,UDBDDP+0(P3)	;IN WHICH CASE, SUBUNIT IS HERE
	CALL PNUM		;AND PRINT
	HRROI T1,[ASCIZ /
/]
	CALL PMES		;FINISH IT OFF
	RET
;HERE WHEN A TM02 IS IN THE WAY

UNIMS4:	HRROI T1,[ASCIZ /, /]
	CALL PMES		;PREPARE TO PRINT KON TYPE
	EXCH P2,P3		;GET KDB IN P3
	LDB T1,USYTYP		;GET UNIT TYPE
	EXCH P2,P3		;REPLACE KDB,UDB
	MOVE T1,NAMUTP(T1)	;GET KON TYPE
	CALL PMES		;PRINT IT
	HRROI T1,[ASCIZ /=/]
	CALL PMES		;ANNOUNCE OBJECT
	HRRZ T1,UDBAKA(P3)	;GET ADDRESS
	CALL PNUM		;PRINT IT
	JRST UNIMS3		;JOIN ABOVE


UNIMS5:	HRROI T1,[ASCIZ/MTA/]
	CALL PMES		;GIVE LOGICAL UNIT NUMBER
	MOVSI Q1,-MTAN		;LOOK FOR THIS UNIT
UNIMS6:	HRRZ T1,MTCUTB(Q1)	;GET UDB ADR
	CAIN T1,(P3)		;FOUND THE UNIT YET?
	JRST UNIMS7		;YES
	AOBJN Q1,UNIMS6		;NO, LOOP BACK TIL FOUND
	JRST UNIMS0		;NOT FOUND SO DONT GIVE UNIT NUMBER

UNIMS7:	HRRZS Q1		;GET UNIT NUMBER
	CALL UNIOCT		;PRINT THE UNIT NUMBER
	JRST UNIMS0		;GO CONTINUE MESSAGE

UNIOCT:	SKIPA Q3,[^D8]		;SETUP FOR OCTAL NUMBER
UNIDEC:	MOVX Q3,^D10		;SETUP FOR DECIMAL NUMBER
UNIDE1:	IDIV Q1,Q3		;GET HIGH ORDER DIGIT
	PUSH P,Q2		;SAVE LOW ORDER DIGIT
	SKIPE Q1		;ANY MORE TO DO?
	CALL UNIde1		;YES, GO DO ANOTHER
	POP P,T1		;GET BACK HIGH ORDER DIGIT
	CALLRET PNUM		;TYPE IT OUT
				; AND RETURN FOR OTHER DIGITS
;HERE TO PRINT A STRING TO THE OPERATOR

PMES:	MOVE T2,CTYLNO		;GET CTY LINE
	CALL TTEMES		;CALL TTY SERVICE
	RET

;HERE TO PRINT T1 AS A 1 DIGIT DECIMAL NUMBER

PNUM:	ADDI T1,"0"		;CHEAPO CONVERSION
	LSH T1,^D29		;POSITION CHAR
	PUSH P,T1		;SAVE
	HRROI T1,(P)		;POINTER
	CALL PMES
	JRST PA1		;SCRAP STACK AND RETURN

;HERE TO PRINT T1 IN SIXBIT

PSIX:	MOVE T2,T1		;COPY ARG
	ADJSP P,2		;ALLOC STRING SPACE (STACK ALMOST GONE)
	HRRZI T3,-1(P)		;GET START OF STRING
	HRLI T3,(<POINT 7,.-.>)	;BUILD BYTE POINTER
PSIX1:	MOVEI T1,0		;CLEAR T1
	LSHC T1,6		;GET A CHAR FROM ARG
	SKIPE T1		;IF NOT END
	ADDI T1,40		;MAKE LIKE ASCII
	IDPB T1,T3		;STORE IN OUTPUT STRING
	JUMPN T1,PSIX1		;LOOP
	HRROI T1,-1(P)		;BUILD STRING POINTER
	CALL PMES		;PRINT STRING
	ADJSP P,-2		;SCRAP STACK
	RET			;DONE

PHCVBO::MOVE T4,T1		;SAVE THE NUMBER GIVEN
	LDB T1,[POINT 4,T4,23]	;GET HIGH ORDER DIGIT
	IMULI T1,^D10		;MULT BY 10
	LDB T2,[POINT 4,T4,27]	;GET 2ND DIGIT
	ADD T1,T2		;ADD TO NUMBER
	IMULI T1,^D10
	LDB T2,[POINT 4,T4,31]	;GET THIRD DIGIT
	ADD T1,T2
	IMULI T1,^D10
	LDB T2,[POINT 4,T4,35]	;LAST DIGIT
	ADD T1,T2		;LAST ONE
	RET			;RETURN
SUBTTL	MOUNTABLE STRUCTURE SUPPORT ROUTINES

; ROUTINE TO SET UP UDBSTR AND SDBUDB DURING MOUNTING OF A STRUCTURE
;
;ACCEPTS IN T1/ PHYSICAL UNIT NUMBER,,CHANNEL NUMBER
;	    T2/	UNIT NUMBER IN STRUCTURE,,STRUCTURE NUMBER
;	    T3/	ADDRESS OF SDB
;		CALL SETSTR
; RETURNS: +1 ALWAYS

	SWAPCD
SETSTR::HLRM T1,T4		;GET JUST THE PHYSICAL UNIT NUMBER
	HRRZS T1		;GET ADDRESS ONLY
	MOVE T1,CHNTAB(T1)	;GET ADDRESS OF CDB FOR THIS CHANNEL
	ADDI T1,CDBUDB(T4)	;GET OFFSET TO UDB ADDRESS
	MOVE T1,(T1)		;GET UDB ADDRESS FOR THIS PHYSICAL UNIT
	HLRZM T2,T4		;GET THE LOGICAL UNIT # WITHIN THE STRUCTURE
	ADD T3,T4		;GET SDB ADDRESS + UNIT # IN STRUCTURE
	MOVEM T1,SDBUDB(T3)	;STORE UDB ADDRESS IN SDB
	MOVEM T2,UDBSTR(T1)	;STORE UNIT,,STRUCTURE NUMBERS IN UDB
	RET			;RETURN


; ROUTINE TO VALIDATE THE CHANNEL, CONTROLLER, AND UNIT NUMBERS WHEN
; MOUNTING A STRUCTURE.
;
;ACCEPTS IN T1/	CHANNEL NUMBER
;	    T2/	CONTROLLER NUMBER (PRESENTLY IGNORED)
;	    T3/	UNIT NUMBER
;		CALL STRCHK
;RETURNS: +1	 ERROR, ERROR CODE IN T1
;	  +2	CHANNEL, CONTROLLER, AND UNIT ALL OK,
;		T1/ UNIT TYPE

STRCHK::SAVEP			;PRESERVE SOME ACCUMULATORS
	CAMG T1,MAXCHN		;IS CHANNEL NUMBER TOO HIGH ?
	SKIPGE T1		;OR NEGATIVE ?
	RETBAD (MSTX14)		;YES, RETURN "BAD CHANNEL" ERROR CODE
	CAME T2,[-1]		;CONTROLLER NUMBER OK ?
	RETBAD (MSTX16)		;NO, RETURN "BAD CONTROLLER" ERROR CODE
	MOVE T4,CHNTAB(T1)	;GET ADDRESS OF CDB
	HLRE T4,CDBIUN(T4)	;GET NEGATIVE NUMBER OF UNITS ON THIS CHANNEL
	MOVNS T4		;FORM POSITIVE NUMBER OF UNITS ON THIS CHANNEL
	CAIGE T3,(T4)		;WAS AN EXTANT UNIT SPECIFIED ?
	SKIPGE T3		;AND NON-NEGATIVE ?
	RETBAD (MSTX15)		;NO, RETURN "BAD UNIT" ERROR CODE
	MOVE P3,CHNTAB(T1)	;GET ADDRESS OF CDB
	ADDI P3,CDBUDB(T3)	;ADD OFFSET TO UDB ADDRESS
	MOVE T1,(P3)		;GET ADDRESS OF UDB
	CALL TSTUNI		;GO SEE IF THIS UNIT IS A DISK
	 RETBAD (MSTX15)	;UNIT NOT A DISK, RETURN "BAD UNIT" ERROR
	MOVE P3,(P3)		;GET ADDRESS OF UDB
	LDB T1,USYTYP		;NO, GET UNIT TYPE
	RETSKP			;RETURN ALL VALUES OK
; ROUTINE TO CLEAR THE UDBSTR AND SDBUDB ENTRIES FOR ALL UNITS IN
; A STRUCTURE.
;
; CALL:
; ACCEPTS IN T1/ SDB ADDRESS
;	CALL CLRSTR
; RETURNS: +1 ALWAYS

CLRSTR::MOVE T4,SDBNUM(T1)	;GET NUMBER OF UNITS IN THIS STRUCTURE
	MOVN T4,T4		;FORM AN AOBJN POINTER, I.E.,
	MOVSI T4,(T4)		;   -<NUMBER OF UNITS>,,SDB ADDRESS+UNIT #