Trailing-Edge
-
PDP-10 Archives
-
saio_sources
-
4sources/physio.mac
There are 56 other files named physio.mac in the archive. Click here to see a list.
;<4.ISI-MONITOR>PHYSIO.MAC.1720 31-Mar-81 13:09:45 Edit by SMITH
;#172 Add Missing Hi-Density entry to MODTAB
;#26 Support IBM-3420 compatable Tape drives on SA10 channel
;#25 Support IBM-3330 compatable disks on SA10 channel.
;#13 Allow swapping on non-PS - SDB for swapping STR found in SDBSTR
;<4.MONITOR>PHYSIO.MAC.26, 3-Jan-80 08:10:15, EDIT BY R.ACE
;UPDATE COPYRIGHT DATE
;<4.MONITOR>PHYSIO.MAC.25, 16-Oct-79 12:09:04, EDIT BY DBELL
;TCO 4.2527 - ADD FNDCKU TO FIND CHANNEL, CONTROLLER, AND UNIT NUMBERS
; AND USE IT FOR OVRDTA BUGINF
;<4.MONITOR>PHYSIO.MAC.24, 2-Oct-79 16:42:19, EDIT BY DBELL
;TCO 4.2507 - FIX RSTSEK TO SET UP P2 AND P3 CORRECTLY
;<4.MONITOR>PHYSIO.MAC.23, 20-Sep-79 15:28:19, EDIT BY DBELL
;TCO 4.2476 - ADD EXTKDB AND EXTUDB TO CHECK FOR EXISTANCE OF UNITS
;<OSMAN.MON>PHYSIO.MAC.1, 10-Sep-79 16:01:21, EDIT BY OSMAN
;TCO 4.2412 - Move definition of BUGHLTs, BUGCHKs, and BUGINFs to BUGS.MAC
;<4.MONITOR>PHYSIO.MAC.20, 25-Jul-79 18:10:27, EDIT BY DBELL
;MAKE SCHSEK GLOBAL
;<4.MONITOR>PHYSIO.MAC.19, 6-Mar-79 09:34:56, EDIT BY KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<2BOSACK>PHYSIO.MAC.3, 14-Feb-79 10:59:18, EDIT BY BOSACK
;CAUSE UNIMES TO GET CORRECT TAPE UNIT NUMBER
;<4.MONITOR>PHYSIO.MAC.17, 7-Feb-79 14:31:21, Edit by MCLEAN
;FIX FAILURE PATH ON PHYALC SO NON-SKIP RETURN WORKS
;<4.MONITOR>PHYSIO.MAC.16, 28-Jan-79 16:55:21, Edit by MCLEAN
;<4.MONITOR>PHYSIO.MAC.16, 28-Jan-79 16:55:21, Edit by MCLEAN
;MAKE DGUMAP USE P6 INSTEAD OF P5 FOR TEMP
;<4.MONITOR>PHYSIO.MAC.14, 20-Nov-78 16:40:35, EDIT BY BOSACK
;<4.MONITOR>PHYSIO.MAC.13, 23-Oct-78 12:12:48, Edit by MILLER
;MAKE CORRECT CLEAR VALID VOLUME ROUTINE FOR PHYOFL
;<4.MONITOR>PHYSIO.MAC.12, 27-Sep-78 11:04:47, EDIT BY KIRSCHEN
;IMPROVE COMMENT AT HEAD OF GETSTR
;<4.MONITOR>PHYSIO.MAC.11, 30-Aug-78 09:57:40, EDIT BY FORTMILLER
;TCO 4.1999 Clear US.REW in HNGIRB
;<4.MONITOR>PHYSIO.MAC.10, 18-Aug-78 12:11:08, EDIT BY MURPHY
;<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
;<4.MONITOR>PHYSIO.MAC.8, 5-Aug-78 16:47:38, Edit by MCLEAN
;<4.MONITOR>PHYSIO.MAC.7, 31-Jul-78 23:54:51, Edit by MCLEAN
;CLEAR MT VALID VOLUME ON OFFLINE
;<4.MONITOR>PHYSIO.MAC.6, 28-Jul-78 01:01:58, Edit by MCLEAN
;<4.MONITOR>PHYSIO.MAC.5, 28-Jul-78 00:24:44, Edit by MCLEAN
;<4.MONITOR>PHYSIO.MAC.4, 28-Jul-78 00:08:14, Edit by MCLEAN
;<2MCLEAN>PHYSIO.MAC.3, 23-Jul-78 16:43:29, Edit by MCLEAN
;INSERT PSI REQUESTS FOR REWINDS
;<4.MONITOR>PHYSIO.MAC.2, 20-Jul-78 00:52:07, Edit by MCLEAN
;FIX PHYRWD FOR PSI ON REWIND DONE
;<1MCLEAN>PHYSIO.MAC.163, 6-May-78 21:46:32, Edit by MCLEAN
;<1MCLEAN>PHYSIO.MAC.162, 6-May-78 21:34:36, Edit by MCLEAN
;ADD RP07
;<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
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976,1977,1978,1979,1980 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
; SAIO Changes Copyright 1982, All Rights Reserved
; University of Southern California
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
;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
EXP 1 ;#172 High Density 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 .UTRP7 ;RP07
EXP .UTRP7 ;RP07
EXP .UTRM3 ;RM03
EXP .UTCC1 ;#25 Calcomp 230 (=IBM 3330 mod I)
EXP .UTCC2 ;#25 Calcomp 235 (=IBM 3330 mod II)
NDSKUT==:.-DSKUTP
;TABLE OF POINTER TO UNIT PHYSICAL SIZE PARAMETERS - THE TABLE ARE
;DEFINED IN STG
DSKSIZ::DSKSZ0 ;RP04
DSKSZ0 ;RP05
DSKSZ1 ;RP06
DSKSZ2 ;RP07
DSKSZ2 ;RP07
DSKSZ3 ;RM03
DSKSZ0 ;#25 Calcomp 230 (=IBM 3330 mod I)
DSKSZ1 ;#25 Calcomp 235 (=IBM 3330 mod II)
;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/]
POINT 7,[ASCIZ /CC01/] ;#25 Calcomp 230 (=IBM 3330 mod I)
POINT 7,[ASCIZ /CC02/] ;#25 Calcomp 235 (=IBM 3330 mod II)
POINT 7,[ASCIZ /CT01/] ;#26 IBM compatable Tape drive
;INITIALIZATION
;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
;ROUTINE TO CHECK FOR THE LEGALITY AND EXISTANCE OF A PARTICULAR
;UNIT ON A CHANNEL. THIS ROUTINE HANDLES ALMOST ALL CASES, WHERE
;CONTROLLERS AND UNITS RANGE FROM 0-7, AND ARE REFERENCED AS OFFSETS
;INTO UDB TABLES. ANY EXCEPTIONS (SUCH AS THE DX20) WILL HAVE THEIR
;OWN ROUTINES. USED BY THE .DGPDL FUNCTION OF DIAG. ARGUMENTS:
; P1/ CDB
; P2/ KDB (ONLY FOR EXTUDB CALL)
; P5/ CONTROLLER NUMBER OR -1 IF NONE (ONLY FOR EXTKDB CALL)
; Q2/ UNIT NUMBER
;RETURNS:
; +1: T1/ 0 UNIT OR CONTROLLER IS ILLEGAL
; T1/ -1 UNIT OR CONTROLLER IS NONEXISTANT
; +2: CONTROLLER AND UNIT EXIST
;TRASHES T1. P2 AND P3 ARE SET TO THE KDB AND UDB AS THEY ARE FOUND.
EXTKDB::JUMPL P5,EXTUD2 ;DIFFERENT IF NO CONTROLLER
CAILE P5,7 ;CAN HAVE ONLY 8 UNITS
JRST RFALSE ;ILLEGAL
MOVE T1,CDBIUN(P1) ;GET ADDRESS OF KDB POINTERS
ADD T1,P5 ;ADD KDB UNIT
SKIPN P2,(T1) ;KDB EXIST?
JRST RTRUE ;NO
MOVE T1,KDBDSP(P2) ;GET DISPATCH ADDRESS
JRST UDSEXT(T1) ;ASK CONTROLLER ABOUT THE UNIT
EXTUD2: SKIPA P3,[ADD T1,CDBIUN(P1)] ;INSTRUCTION FOR NO CONTROLLER
EXTUDB::SKIPA P3,[ADD T1,KDBIUN(P2)] ;OR INSTRUCTION FOR CONTROLLER
SETZ P2, ;FLAG NONEXISTANCE OF CONTROLLER
SKIPL T1,Q2 ;CHECK UNIT VALIDITY
CAILE T1,7 ;ONLY CAN HAVE 8 UNITS
JRST RFALSE ;ILLEGAL
XCT P3 ;ADD IN ADDRESS OF UNIT TABLE
SKIPN P3,(T1) ;SEE IF UDB EXISTS
JRST RTRUE ;NO
RETSKP ;YES, SKIP RETURN
;SUBROUTINE TO FIND THE CORRECT CHANNEL, CONTROLLER, AND UNIT NUMBERS
;GIVEN THE CDB, KDB, AND UDB ADDRESSES. USED BY VARIOUS BUGCHKS, ETC.
;CALL:
; P1/ CDB
; P2/ KDB, OR 0 IF NONE
; P3/ UDB
;RETURNS +1 ALWAYS:
; T1/ CHANNEL NUMBER
; T2/ CONTROLLER NUMBER OR -1 IF NONE
; T3/ UNIT NUMBER
FNDCKU::HRRZ T1,CDBADR(P1) ;GET CHANNEL NUMBER
SETO T2, ;ASSUME NO CONTROLLER
HRRZ T3,UDBAKA(P3) ;GET UNIT IF NO CONTROLLER
TRNN P2,-1 ;GUESSED RIGHT?
RET ;YES, DONE
MOVE T2,T3 ;NOPE, GET CONTROLLER NUMBER
HRRZ T3,UDBSLV(P3) ;AND UNIT OF IT
RET ;NOW DONE
;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(PHYICE)
SOS -2(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(PHYP0E)
RET
;HERE WHEN GIVEN AN ILLEGAL ARGUMENT TO ALC OR ALZ
INIERR: BUG(PHYICA)
;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
CALL MTCLVA ;CLEAR ALL VALID VOLUME BITS FOR MT'S
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
MOVSI T1,(US.PSI) ;SET PSI REQUEST
IORM T1,UDBSTS(P3)
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) ; ...
MOVSI T1,(US.PSI) ;SET PSI REQUEST
IORM T1,UDBSTS(P3)
RET
;OFFLINE ENTRY - ENTERED ON THE OFFLINE INTERRUPT OF A UNIT
PHYOFL::MOVSI T1,(US.PSI!US.OFS)
IORM T1,UDBSTS(P3)
MOVSI T1,(US.TAP) ;IS THIS A TAPE?
TDNN T1,UDBSTS(P3)
RET ;RETURN
CALLRET MTCLVL ;CLEAR VALID VOLUME FOR THIS TAPE
;HERE ON REWIND DONE.
PHYRWD::SAVEQ ;SAVE ALL Q'S
MOVSI T1,(US.REW) ;NO LONGER REWINDING
ANDCAM T1,UDBSTS(P3) ; ...
MOVSI T1,(US.PSI) ;SET POSSIBLE PSI FOR REWIND DONE
IORM 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(ILTWQ) ;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(PHYNIR)
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(ILPDAR)
;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
SIO2DL::CAME T2,UDBPS1(P3) ;SAME AS CURRENT UDBPS1? (TAG FOR DLLOOK)
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!US.ACT) ;#25 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(NRFTCL)
RET ;YES - ALL IS WELL
PDN3: MOVE Q1,P4 ;MOVE DOWN THE LIST
JRST PDN2 ;AND CONTINUE
PDN4: BUG(NPWQPD)
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(PYILUN)
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(NOIORB)
;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
;#13 SETZ Q1, ;ASSUME STRUCTURE 0
MOVE Q1,SWPSTR ;#13 get SDB of swapping structure
LOAD Q1,STRUS,(Q1) ;#13 get the structure number
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(ILRBLT)
;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(ILTWQP)
;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(ILIRBL)
;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(ILCNST)
;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(ILCNSP)
;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(TWQNUL)
;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) ; ??
JRST [ MOVSI T1,(CS.MUX) ;#25 is this a mux channel?
TDNN T1,CDBSTS(P1) ;#25 ??
BUG(ILUST1) ;#25 no
RET] ;#25 yes, just wait a while for unit
MOVSI T1,(CS.AC2) ;CHECK NOT OUT OF PHASE
TDNE T1,CDBSTS(P1) ; ...
BUG(ILCHS1)
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(ILUST5)
MOVSI T1,(CS.AC2) ;SECOND COMMAND
TDNE T1,CDBSTS(P1) ;SHOULDN'T BE ACTIVE NOW
BUG(ILCHS2)
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(ILUST2)
TRNN P2,-1 ;IS THERE A CONTROLLER?
JRST STRTP1 ;NO
MOVSI T1,(KS.ACT) ;YES
TDNE T1,KDBSTS(P2) ;ALREADY ACTIVE?
BUG(ILUST4)
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, P2, AND P3
;SHOULD BE CALLED WITH PI OFF
RSTSEK::SAVEQ
CALL DGUMAP ;LOOP OVER ALL UNITS
CALL SCHSEK ;DO THIS FOR EACH ONE
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(ILUST3)
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!US.ACT) ;#25 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!US.ACT) ;#25 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!US.ACT) ;#25 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(PHYCH1)
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!US.ACT) ;#25 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
MOVX T1,US.TAP ;#26 check for tape UDB
TDNE T1,UDBSTS(P3) ;#26 is it tape?
JRST XFR0 ;#26 yes, do round-robin
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!US.ACT) ;#25 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(PHYLTF)
;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(UIONIR)
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(PHYCH2)
CALL HNGIRB ;TERMINATE IORB IN T1
JRST CHK4 ;RESTORE PI AND CONTINUE
CHK6: BUG(PHYCH3)
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
MOVSI T1,(US.PSI) ;GET CHECK FOR PSI REQUESTED
TDNE T1,UDBSTS(P3)
CALL UNIPSI ;INIT PSI SEQUENCE IF NECESSARY
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
UNIPSI: MOVSI T1,(US.PSI) ;GET PSI BIT
ANDCAM T1,UDBSTS(P3) ;CLEAR BIT
MOVSI T1,(US.TAP) ;IS THIS A TAPE?
TDNN T1,UDBSTS(P3)
JRST UNIDPS ;NO -- HANDLE DISK ONLINE/OFFLINE
MOVEI T3,MTCUTB ;LOOK THRU TABLE AND FIND CORRECT UNIT
SETZ T4,0 ;COUNT OF MTA'S
UNIPS2: HRRZ T1,0(T3) ;GET UDB ADDRESS
CAIN P3,0(T1) ;THIS UNIT?
JRST UNIPSF ;YES SEE IF PSI NECESSARY
AOS T4 ;NEXT UNIT
CAIGE T4,MTAN ;CHECK FOR ALL DONE
AOJA T3,UNIPS2
RET ;NO MORE QUIT
UNIPSF: HRRZ T1,MTPSFK(T4) ;GET PSI CHANNEL
HLRZ T2,MTPSFK(T4) ;GET FORK
JUMPE T2,R ;QUIT IF NOT INITALIZED
CALLRET PSIRQ ;REQUEST PSI
UNIDPS: HRRZ T1,DSPSFK ;GET DISK PSI REQUEST
HLRZ T2,DSPSFK ;GET FORK
JUMPE T2,R ;IF NONE THIS IS NOT LEGAL
CALLRET PSIRQ ;REQUEST PSI
;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 T3,(US.ACT) ;PREPARE FOR PIOFF TESTS
MOVSI T4,(US.POS) ; ...
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.
CALL FNDCKU ;FIND CHANNEL, CONTROLLER, AND UNIT NUMBERS
BUG(OVRDTA,<<T1,CHAN>,<T2,CONTRL>,<T3,UNIT>>) ;COMPLAIN
TDNE T4,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 US.REW
ANDCAB T1,UDBSTS(P3) ; IN THE UDB (ALSO LOAD UDBSTS INTO T1)
TLNE T1,(US.POS) ;WAS THIS A POSITION REQUEST?
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,UDBSLV(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 #
ADDI T4,(T1) ;ADD IN SDB ADDRESS
; LOOP OVER ALL UNITS IN THE STRUCTURE
CLRST2: MOVE T2,SDBUDB(T4) ;GET ADDRESS OF UNIT DATA BLOCK
SETZM SDBUDB(T4) ;CLEAR POINTER TO UNIT DATA BLOCK
SETOM UDBSTR(T2) ;CLEAR STRUCTURE INFORMATION IN UDB
AOBJN T4,CLRST2 ;LOOP OVER ALL UNITS IN THE STRUCTURE
RET ;RETURN
; ROUTINE TO STEP TO THE NEXT CHANNEL ON THE SYSTEM
;
; ACCEPTS: T1/ CHANNEL NUMBER (-1 WILL GET FIRST CHANNEL IN SYSTEM)
; CALL STPCHN
; RETURNS: +1 FAILED, NO NEXT CHANNEL
; +2 SUCCESS, T1/ NEXT CHANNEL NUMBER
STPCHN::STKVAR <STCCHN,STCICH> ;ALLOCATE SPACE
MOVEM T1,STCICH ;SAVE INITIAL CHANNEL NUMBER
MOVSI T1,-CHNN ;SET UP AOBJN POINTER
; LOOP OVER ALL CHANNELS LOOKING FOR THE NEXT ONE
STPCH1: SKIPN CHNTAB(T1) ;DOES THIS CHANNEL EXIST ?
JRST STPCH2 ;NO, TRY NEXT CHANNEL NUMBER
MOVE T2,STCICH ;GET INITIAL CHANNEL NUMBER
CAIGE T2,(T1) ;FOUND NEXT CHANNEL ?
JRST [ MOVEM T1,STCCHN ;SAVE AOBJN POINTER
HRRZ T1,T1 ;KEEP JUST CHANNEL NUMBER
SETOM T2 ;START WITH FIRST UNIT
CALL STPUNI ;IS THERE A DISK ON THIS CHANNEL ?
JRST [ MOVE T1,STCCHN ;NO, RESTORE LOOP COUNTER
JRST STPCH2 ] ;GO CHECK NEXT CHANNEL
HRRZ T1,STCCHN ;YES, GET CHANNEL NUMBER BACK
RETSKP ] ;RETURN SUCCESS
STPCH2: AOBJN T1,STPCH1 ;LOOP OVER ALL CHANNEL NUMBERS
RET ;RETURN, NO NEXT CHANNEL
; ROUTINE TO STEP TO THE NEXT UNIT ON A CHANNEL
;
; ACCEPTS: T1/ CHANNEL NUMBER
; T2/ UNIT NUMBER (-1 WILL GET FIRST UNIT ON CHANNEL)
; CALL STPUNI
; RETURNS: +1 FAILED, NO MORE UNITS ON THIS CHANNEL
; +2 SUCCESS, T2/ NEXT UNIT NUMBER
STPUNI::MOVE T4,CHNTAB(T1) ;GET ADDRESS OF CDB FOR THIS CHANNEL
MOVE T4,CDBIUN(T4) ;GET AOBJN POINTER TO UNIT TABLE
MOVE T3,T2 ;COPY INITIAL UNIT NUMBER
MOVEI T2,0 ;INITIALIZE UNIT NUMBER
; LOOP OVER ALL UNIT NUMBERS LOOKING FOR THE NEXT ONE ON THIS CHANNEL
STPUN2: SKIPN (T4) ;IS THERE A UDB FOR THIS UNIT ?
JRST STPUN3 ;NO, GO LOOK AT NEXT UNIT NUMBER
CAIGE T3,(T2) ;YES, FOUND NEXT UNIT ?
JRST [ MOVE T1,(T4) ;YES, GET ADDRESS OF UDB
CALL TSTUNI ;GO SEE IF THIS UNIT IS A DISK
JRST STPUN3 ;NOT A DISK, KEEP LOOKING
RETSKP ] ;GOT ONE, RETURN SUCCESS !
STPUN3: AOS T2 ;NO, INCREMENT UNIT NUMBER
AOBJN T4,STPUN2 ;CHECK NEXT UNIT ON THIS CHANNEL
RET ;NO NEXT UNIT ON THIS CHANNEL
; ROUTINE TO TEST TO SEE IF A UNIT IS A DISK
;
; ACCEPTS: T1/ ADDRESS OF UDB
; CALL TSTUNI
; RETURNS: +1 FAILED, UNIT IS NOT A DISK
; +2 SUCCESS, UNIT IS A DISK
;
; PRESERVES T1-T4
TSTUNI: SAVET ;PRESERVE T1-T4
EXCH P3,T1 ;SAVE P3, COPY UDB ADDRESS
LDB T4,USYTYP ;GET UNIT TYPE
MOVE P3,T1 ;RESTORE P3
MOVSI T3,-NDSKUT ;SET UP AOBJN POINTER TO LOOP THRU DISK TYPES
; LOOP THROUGH TABLE OF DISK TYPES LOOKING FOR THE TYPE OF THIS UNIT
TSTUN2: CAMN T4,DSKUTP(T3) ;FOUND THIS TYPE OF UNIT ?
RETSKP ;YES, THEN THIS UNIT IS A DISK
AOBJN T3,TSTUN2 ;NO, LOOK AT NEXT DISK TYPE CODE
RET ;UNIT TYPE NOT IN DISK TYPE TABLE, FAIL RETURN
; ROUTINE TO RETURN STRUCTURE NUMBER OF WHICH A GIVEN UNIT IS A PART
;
; ACCEPTS: T1/ CHANNEL NUMBER
; T2/ CONTROLLER NUMBER (NOT PRESENTLY USED)
; T3/ UNIT NUMBER
; CALL GETSTR
; RETURNS: +1 FAILED, UNIT OFFLINE OR IN MAINT MODE, WITH T1/ FLAGS
; +2 SUCCESS, WITH T1/ UNIT WITHIN STRUCTURE,,STRUCTURE NUMBER
; OR -1 IF UNIT NOT IN STRUCTURE
; T2/ UNIT TYPE
; T3/ FLAGS:
; MS%WLK IF UNIT IS WRITE LOCKED
;
; ASSUMES CHANNEL, CONTROLLER, AND UNIT NUMBERS HAVE ALREADY BEEN VERIFIED
GETSTR::STKVAR <GTSFLG>
MOVE T1,CHNTAB(T1) ;GET ADDRESS OF CDB FOR THIS CHANNEL
ADDI T1,CDBUDB(T3) ;GET POINTER TO ADDRESS OF UDB FOR THIS UNIT
MOVE T3,(T1) ;GET ADDRESS OF UDB FOR THIS UNIT
LDB T2,[POINT USSTYP,UDBSTS(T3),USPTYP] ;GET UNIT TYPE
JN USOFL,(T3),[ MOVX T1,MS%OFL ;IF OFF-LINE, GET FLAG
RET ] ;RETURN
MOVE T4,UDBSTS(T3) ;GET UNIT STATUS
JN US.MAI,T4,[ MOVX T1,MS%DIA ;IF IN MAINTENANCE MODE, GET FLAG
RET ] ;RETURN
SETZM T1 ;INITIALIZE FLAGS
JN US.WLK,T4,[ MOVX T1,MS%WLK ;IF WRITE-LOCKED, GET FLAG
JRST .+1] ;CONTINUE
MOVEM T1,GTSFLG ;SAVE FLAGS
MOVE T1,UDBSTR(T3) ;GET STRUCTURE NUMBER FOR THIS UNIT
MOVE T3,GTSFLG ;GET FLAGS TO RETURN TO CALLER
RETSKP ;RETURN
RESCD
;HERE TO EXECUTE AN INSTRUCTION ONCE FOR EACH UDB ON A CHANNEL
;CALL DGUMAP
; INSTRUCTION TO EXECUTE
;THE INSTRUCTION WILL BE EXECUTED ONCE WITH P3 SETUP TO EACH UDB
;THIS ROUTINE CLOBBERS Q3
DGUMAP::MOVE Q3,CDBIUN(P1) ;GET AOBJN WORD
DGUMP1: SKIPN P3,(Q3) ;UDB PRESENT?
JRST DGUMP2 ;NO - TRY NEXT
LDB T1,USYBKT ;GET BLOCK TYPE
CAIE T1,.BTUDB ;UDB ?
JRST DGUMP3 ;IS KDB, LOOP FOR IT
MOVEI P2,0 ;IF NO KDB, PROVIDE A ZERO
XCT @(P) ;EXECUTE INSTRUCTION
DGUMP2: AOBJN Q3,DGUMP1 ;LOOP
RETSKP ;DONE
DGUMP3: MOVE P2,P3 ;COPY KDB
MOVE P6,KDBIUN(P2) ;GET AOBJN POINTER
DGUMP4: SKIPN P3,(P6) ;UDB PRESENT?
JRST DGUMP6 ;NO - CONTINUE SCAN
PUSH P,P6 ;YES - SAVE POINTER
XCT @-1(P) ;DO INSTRUCTION
POP P,P6 ;RESTORE POINTER
DGUMP6: AOBJN P6,DGUMP4 ;LOOP FOR MORE
MOVEI P2,0 ;ENSURE NIL KDB
JRST DGUMP2 ;CONTINUE OUTER LOOP
TNXEND
END