;<135-TENEX>MAGTAP.MAC;75    12-DEC-75 11:06:32    EDIT BY PLUMMER
; ADD IFDEF SSATF AROUND REFERENCES TO MTMODE (4 PLACES)
;<135-TENEX>MAGTAP.MAC;74    14-NOV-75 14:40:36    EDIT BY ROSENBERG
; PUT IN SOME ISI STUFF INCLUDING 1024K CORE FOR MAG TAPE ON A SA10
; NOTE - 1024K CORE NOT SUPPORTED FOR ANY OTHER MAG TAPE CONTROLLER
;<134-TENEX>MAGTAP.MAC;73     9-SEP-75 16:13:45    EDIT BY CLEMENTS
; FREE CONTROL AND JOB AFTER BUGCHKS FOR UNKNOWN UNIT OR UNKNOWN BUSY
;<134-TENEX>MAGTAP.MAC;72    28-APR-75 12:41:30    EDIT BY CLEMENTS
;<134-TENEX>MAGTAP.MAC;71    28-APR-75 11:39:45    EDIT BY CLEMENTS
;<133-TENEX>MAGTAP.MAC;70    18-DEC-74 15:53:32    EDIT BY CLEMENTS
; FIX FOR CASE OF NO WRITE RING AND FIRST OP IS DUMPO, NOT MTOPR (SA10)
;<133-TENEX>MAGTAP.MAC;69     4-OCT-74 14:53:58    EDIT BY CLEMENTS
;<133-TENEX>MAGTAP.MAC;68    17-SEP-74 15:33:03    EDIT BY CLEMENTS
;<133-TENEX>MAGTAP.MAC;67    11-SEP-74 11:38:48    EDIT BY ALLEN
;<133-TENEX>MAGTAP.MAC;66     3-SEP-74 15:31:49    EDIT BY CLEMENTS
; CORRECTLY NEST TESTS IN MTNXTP
;<133-TENEX>MAGTAP.MAC;65     3-SEP-74 15:26:06    EDIT BY CLEMENTS
; MAKE SSA VERSION SET CORMB ON READS
;<133-TENEX>MAGTAP.MAC;64    11-JUL-74 11:21:27    EDIT BY CLEMENTS
;<133-TENEX>MAGTAP.MAC;63    10-JUL-74 17:53:40    EDIT BY CLEMENTS
;<133-TENEX>MAGTAP.MAC;62    10-JUL-74 14:02:15    EDIT BY CLEMENTS
;<TENEX-132>MAGTAP.MAC;61     8-JUN-74 00:06:36    EDIT BY CLEMENTS
;<TENEX-132>MAGTAP.MAC;60     7-JUN-74 17:19:48    EDIT BY ALLEN
;<TENEX-132>MAGTAP.MAC;59     5-JUN-74 17:50:34    EDIT BY CLEMENTS
;<TENEX-132>MAGTAP.MAC;58     5-JUN-74 17:15:52    EDIT BY CLEMENTS
; YET ANOTHER REWORK OF SSA/IBM MAGTAPE CODE
;<TENEX-132>MAGTAP.MAC;57    22-MAY-74 16:25:23    EDIT BY CLEMENTS
;<TENEX-132>MAGTAP.MAC;56    19-MAY-74 17:50:40    EDIT BY CLEMENTS
;<TENEX-132>MAGTAP.MAC;55    19-MAY-74 17:05:31    EDIT BY CLEMENTS
; THOROUGH RE-HASH OF SSA MAGTAPE STUFF.
;<TENEX-132>MAGTAP.MAC;54    15-MAY-74 17:39:27    EDIT BY CLEMENTS
;<TENEX-132>MAGTAP.MAC;53    14-MAY-74 17:11:12    EDIT BY CLEMENTS
;<TENEX-132>MAGTAP.MAC;52     9-MAY-74 15:46:35    EDIT BY CLEMENTS
;<TENEX-132>MAGTAP.MAC;51     9-MAY-74 08:23:43    EDIT BY CLEMENTS
;<TENEX-132>MTASSA.MAC;7    12-APR-74 18:01:18	EDIT BY CLEMENTS
;<TENEX-132>MTASSA.MAC;6    30-MAR-74 20:31:10	EDIT BY CLEMENTS
;<TENEX-132>MTASSA.MAC;5    30-MAR-74 14:14:05	EDIT BY CLEMENTS
;<TENEX-132>MTASSA.MAC;4    29-MAR-74 19:19:12	EDIT BY CLEMENTS
;<TENEX-132>MTASSA.MAC;3    29-MAR-74 19:07:58	EDIT BY CLEMENTS
;<TENEX-132>MTASSA.MAC;2    29-MAR-74 18:54:53	EDIT BY CLEMENTS
;<TENEX-132>MTASSA.MAC;1    29-MAR-74 17:48:51	EDIT BY CLEMENTS
; FIRST VERSION WITH CODE IN IT FOR SSA/STC TAPES
;<TENEX-132>MAGTAP.MAC;49    29-MAR-74 14:13:47	EDIT BY CLEMENTS
; Commenting and cleanup
;<TENEX-132>MAGTAP.MAC;48    25-MAR-74 11:24:35	EDIT BY TOMLINSON
; CHANGE REWUNL TO NON-REVERSE TYPE MTOPR
; CHECK WRITE TYPPE MTOPR IF NOT OPEN FOR WRITE.
;<TENEX-132>MAGTAP.MAC;47    18-MAR-74 21:57:54	EDIT BY TOMLINSON
; ELIMINATED INC REC LENGTH AS AN ERROR
;<TENEX-132>MAGTAP.MAC;46    18-MAR-74 17:42:39	EDIT BY CLEMENTS
; COMMENTS, PAGINATION, SOME MORE PREP FOR SA10/IBM TAPES
;<TENEX-132>MAGTAP.MAC;45    19-FEB-74 15:55:20	EDIT BY CLEMENTS
;<TENEX-132>MAGTAP.MAC;44     1-FEB-74 13:44:34	EDIT BY CLEMENTS
; FIX RACE IN MTNXT FROM PROCESS LEVEL
;<TENEX-132>MAGTAP.MAC;43    10-JAN-74 08:56:09	EDIT BY CLEMENTS
; ADDED DEFENSIVE BUGCHK FOR POSITIVE IOWD BEING USED
;<TENEX-132>MAGTAP.MAC;42    21-DEC-73 11:59:13	EDIT BY ALLEN
; ELIMINATE CALL TO ARCSQ
;<TENEX-132>MAGTAP.MAC;41    10-NOV-73 17:17:28	EDIT BY CLEMENTS
; ADD KI-10 ABILITY, TM10B/DF10 ABILITY
;<TENEX-132>MAGTAP.MAC;39    28-SEP-73 21:50:21	EDIT BY ALLEN
;<TENEX-132>MAGTAP.MAC;38    17-MAY-73 00:14:43	EDIT BY CLEMENTS
;<TENEX-132>MAGTAP.MAC;37    16-MAY-73 19:09:30	EDIT BY CLEMENTS
; BAD TAPE FLAG CAUSES INTERRUPT
;<TENEX-130>MAGTAP.MAC;36    18-NOV-72 16:18:23	EDIT BY WALLACE
;<DLM/TEMP>MAGTAP.MAC;35    19-OCT-72 21:55:06	EDIT BY TOMLINSON
;<FILESYSTEM>MAGTAP.MAC;34    25-AUG-72 17:52:53	EDIT BY TOMLINSON
;<FILESYSTEM>MAGTAP.MAC;33    29-JUN-72 10:15:28	EDIT BY TOMLINSON

	SEARCH	STENEX,PROLOG
IFDEF MTAN,<
	TITLE	MAGTAPE
	SUBTTL	R.S.TOMLINSON

; Externally defined symbols used herein

EXTERN	LCKTST,BUGCHK,BUGHLT
EXTERN	CPOPJ,SKPRET
EXTERN	MTACHR		; Return from magtape interrupt
EXTERN	MTATIM		; Countdown for testing rewinding tapes
EXTERN	NSKED		; No schedule flag
EXTERN	RSKED		; Reschedule instruction
EXTERN	EDISMS		; Exec dismiss
; Entries to this part

INTERN	MTASV		; Interrupt service routine
INTERN	MTARST
INTERN	MTACHK		; Clock level routine to check rewinding tapes

IFN KAFLG,<
DEFINE	MTALOC<MTDCHN*2+40>>
IFN KIFLG,<
DEFINE MTALOC<KIEPT+40+2*MTDCHN>>
DEFINE	MTBOTH<MTACHN*10+MTDCHN>

PI==4
MTC=340
MTS=344
MTTRY==5
MTAICW=66		;INITIAL CONTROL WORD FOR DF10 IF TM10B

IFNDEF SSATF,<TM10F==1>	; COMPLEMENT OF SSA FLAG FOR CLEARER LISTING
IFDEF SSATF,<
IFNDEF SSAWCP,<SSAWCP==^D11>	; POSITION OF RIGHTMOST BIT OF WD COUNT
				;  IN SSA DATA COUNT WORDS. 15 FOR SA10A
				;  11 FOR SA10C AND NEW SA10B'S.
IFNDEF SA10BF,<
IFE SSAWCP-^D11,<SA10BF==1>	; FLAG FOR SMART PACKING MODES
IFN SSAWCP-^D11,<SA10BF==0> >

;SA10B PACKING MODES ARE:
;B1 B4 MODE
;0  0  WORD
;0  1  BYTE
;1  0  NATURAL WORD, USED FOR 7 TRACK
;1  1  TM10 CORE DUMP, USED FOR 9 TRACK
>

; Private storage for magtapes

NCHCM==20	; LENGTH OF CHANNEL COMMAND LIST IF TM10B OR SSA
IFDEF SSATF,<
NCHCM==40>	; MORE CAUSE A PAGE TAKES 2 WDS IN BYTE MODE ON SA10B

LS(MTALCK,MTAN)	; Lock word
LS(MTASTS,MTAN)	; Status of unit. USER MAY SET 18-31 VIA STSTS
MTSTKL==20
LS(MTSTK,MTSTKL); Stack for mta int
LS(REWCNT)	; Number of rewinding units
LS(MTIOWD,MTAN)	; Iowd for next transfer
LS(MTCLCK)	; CONTROL LOCK FOR PROCESS LEVEL CALL TO MTNXT
LS(MTERAS)	; Rewrite erase counter
LS(MTPNTR)	; Iowd during transfer
LS(MTAUNT)	; Unit currently attached to controller
LS(MTERRC)	; Retry counter
LS(MTERFL)	; State of retry
LS(MTACOM)	; Cono word of current operation
LS(MTAINR)	; Return address from flag interrupt
LS(MTDINR)	; Return address from data interrupt
LS(MTACLS)	; Clock routine switch, 0 for no clock wanted
LS(MTARCE,MTAN)	; Total error count
LS(CHCML,NCHCM)	; DF10 COMMAND LIST IF TM10B
LS(M10BF,1)	; FLAG. NON-ZERO IFF TM10B
IFDEF SSATF,<	; IF TAPES ON SA10,
LS MTASEN,6	; SENSE DATA. MOST RECENT DRIVE.
LS MTSNSP,3	; CHANNEL PROGRAM TO DO SENSE OP
LS MTRECP,3	; CHANNEL PROGRAM FOR RECOVERY PROCEDURE FROM ERROR.
LS MTBSYF,1	; SET WHEN COMMAND REJECTED WITH BUSY
LS MTCHS1,1	; STATUS WORD 1 SAVED FROM OP DONE THRU FINAL SENSE
LS MTCHS2,1	; STATUS WORD 2 SAVED ...
LS MTMODE,MTAN	; 0 MEANS NORMAL. ELSE, RH HAS BITS FROM
		; AC 3 OF MTOPR 20 FOR PACKING, XLATE, DATA CVT

EXTERN SSABAS	; SA10 CONTROL BLOCK BASE ADDRESS
>

; Pointers to fields of interest

	USE	RESPC

PMTOP:	POINT 9,MTASTS(UNIT),17	; Mtape operation code
PMTOP2:	POINT 9,IOS,17		; SAME, IN AC IOS
PDENS:	POINT 3,MTASTS(UNIT),28	; Density and parity

	IFDEF TM10F,<
IFN KAFLG,<
DEFINE PIJSYS(XX)<JSYS XX>>	;JSYS IN PI LOC
IFN KIFLG,<
DEFINE PIJSYS(XX)<
	IFIDN <XX>,<MTATHR>,<JSR MTATH0>>

DEFINE XJSYS(AA,BB)<
BB:	0
	MOVEM 1,MTDINR
	MOVE 1,BB
	EXCH 1,MTDINR
	JRST AA+1>		;SIMULATE JSYS CALL

	XJSYS(MTATHR,MTATH0)>	;END OF CONDITIONAL ON KIFLG
>	;END OF CONDITIONAL ON TM10F

	USE	SWAPPC

; Flags in lh of mtasts (or ios)

FLG(IO,L,IOS,400000)	; Direction of transfer
FLG(IOACT,L,IOS,200000)	; Action in progress or about to be
FLG(OPN,L,IOS,100000)	; This unit is open
FLG(REW,L,IOS,040000)	; Rewind in progress
FLG(MTP,L,IOS,020000)	; Mtape op wanted
FLG(MTSNS,L,IOS,010000)	; SENSE OP OUTSTANDING ON SSA FOR TAPE UNIT
FLG(OP2,L,IOS,004000)	; SECOND PART OF SEQUENCE ON SSA. SEQUENCE IS
			;  SENSE, DO OP, FINAL SENSE. OP2 ON FOR LATTER
			;  TWO FUNCTIONS.
FLG(MTBYT,L,IOS,002000)	; BYTE MODE XFER THRU SSA
; BITS 9-17 ARE MTOPR CODE

; Dispatch table

MTADTB::MTASET
	MTANAM
	MTAEXT
	MTAVER
	CPOPJ
	CPOPJ
	CPOPJ
	MTAOPN
	MTASQI
	MTASQO
	MTACLZ
	MTAREN
	MTADEL
	MTDMPI
	MTDMPO
	MTAMNT
	MTADSM
	MTINID
	MTMTAP
	MTSTS
	MTRTS

; Initialize magtape

	USE	RESPC

MTAINI::SETZM REWCNT
	SETZM MTAUNT
	SETZM MTERRC
	SETOM MTERFL
IFDEF TM10F,<			; TM10 CODE
	MOVEI A,CHCML
	MOVEM A,MTAICW		;SET UP FOR TM10B/DF10
	SETZM M10BF		;ESTABLISH WHICH TYPE OF TM10 IT IS
	CONO MTC,0
	CONI TMC,1		;TM10B RETURNS 7 FOR DATA CHANNEL
	ANDI 1,7		;BECAUSE NO MODULE IN THAT SLOT
	CAIN 1,7		;SAY SEVEN?
	AOS M10BF		;YES. SET FLAG, THIS IS A TM10B
	SKIPE M10BF		;AND IF SO,
	DATAO TMS,[MTAICW]	;SET ICW FOR DF10
>				; END OF TM10B HARDWARE SPECIFICS
	SETOM MTCLCK		;CLEAR CONTROL LOCK
IFDEF SSATF,<
	CONO SSA,SA.PIE!SA.SET!<SSATC>B32!SSACHN ; ALLOW PI'S
>
	MOVSI UNIT,-MTAN
MTAINL:	SETOM MTALCK(UNIT)
	SETZM MTASTS(UNIT)
	AOBJN UNIT,MTAINL
	POPJ P,

MTARST:
IFDEF TM10F,<			; TM10 SPECIFIC
	SKIPE M10BF		;TM10B?
	DATAO TMS,[MTAICW]	;YES. SET UP ICW FOR DF10 CHANNEL
>
IFDEF SSATF,<
	CONO SSA,SA.PIE!SA.SET!<SSATC>B32!SSACHN ; ALLOW PI'S
>
	SKIPN MTAUNT
	POPJ P,
	PUSH P,P
	PUSH P,UNIT
	PUSH P,IOS
	MOVE UNIT,MTAUNT
	MOVE IOS,MTASTS(UNIT)
IFDEF TM10F,<
	JSP A,MTARS1		;CHANGED FROM JSYS, FOR KI10
	POPJ P,
MTARS1:	MOVEM A,MTAINR		;PC AS IF JSYS ON INT LEVEL
>
	SKIPL A,MTERFL
	JRST TRYAGN
	JRST DATEN1

	USE	SWAPPC

; Mount magtape

MTAMNT:	JRST SKPRET		; Any kind of mount is ok for now
	JUMPL B,SKPRET		; Directoryless mount only
	POPJ P,

; Dismount magtape

MTADSM:	JRST SKPRET

; Initialize directory

MTINID:	POPJ P,

; Get mag tape status (GDTSTS)

MTSTS:	HLRZ UNIT,DEV
	MOVSI A,IOACT
	TDNE A,MTASTS(UNIT)
	 PUSHJ P,DISBIT		; Wait for ioact to go off
	MOVE B,MTIOWD(UNIT)
	UMOVEM B,3
	MOVE A,MTASTS(UNIT)
	POPJ P,

; Set mag tape status (SDSTS)

MTRTS:	HLRZ UNIT,DEV
	PUSH P,A
	MOVSI A,IOACT
	TDNE A,MTASTS(UNIT)
	 PUSHJ P,DISBIT
	POP P,A
	ANDCMI A,17
	HRRM A,MTASTS(UNIT)
	POPJ P,

; Set magtape directory

MTASET:	POPJ P,

; Name lookup

MTANAM:	POPJ P,

; Extension lookup

MTAEXT:	POPJ P,

; Version lookup

MTAVER:	MOVEI A,0
	TEST(NE,UNLKF)
	JRST SKPRET
	UNLOCK MTALCK(UNIT)
	OKINT
	JRST SKPRET

; Open magtape

MTAOPN:	HLRZ UNIT,DEV
	MOVE IOS,MTASTS(UNIT)
	TLNE STS,74000
	JRST MTAACC		; Execute access etc not allowed
	LDB A,[POINT 4,STS,35]	; Get mode
	CAIE A,17
	JRST MTAILM		; Must be dump mode for now
	LOCK MTALCK(UNIT),<PUSHJ P,LCKTST>
	TEST(NE,OPN)
	JRST BUSY		; Unit is busy, wait
	MOVSI A,OPN		; SET UNIT BUSY
	IORM A,MTASTS(UNIT)
	HLLZS MTASTS(UNIT)	; CLEAR RIGHT HALF STATUS FLAGS
IFDEF SA10BF,<
 IFDEF SSATF,<	SETZM MTMODE(UNIT)>>
	UNLOCK MTALCK(UNIT)
	JRST SKPRET

; Mtape uuo
; Call:	B	; The operation wanted
;	PUSHJ P,MTMTAP
;  OPERATION 20 SETS BITS FOR IBM MAGTAPES, SA10, FROM AC3:
;  B35 ON MEANS DATA CONVERTER OFF.
;  B34 ON MEANS EBCDIC TRANSLATOR ON
;  B32-33 ARE MODES FOR SA10B PACKING, TO B1 AND B4 OF COMMAND.

MTMTAP:
IFDEF SSATF,<
 IFNDEF SA10BF,<
	CAIL B,20>
 IFDEF SA10BF,<
	CAIL B,21>
	POPJ P,
	>
	HLRZ UNIT,DEV
	LOCK MTALCK(UNIT),<PUSHJ P,LCKTST>
	MOVSI A,IOACT
	TDNE A,MTASTS(UNIT)
	PUSHJ P,DISBIT
IFDEF SSATF,<
 IFDEF SA10BF,<
	CAIN B,20
	JRST MTMTP1>
	>
	ROT B,-1
	SKIPL B
	SKIPA A,MTPTBL(B)
	HLRZ A,MTPTBL(B)
	TRNE A,400		; WRITE TYPE MTOPR?
	TEST(NE,WRTF)		; AND NOT OPEN FOR WRITING?
	 SKIPA
	  SETZ B,		; CONVERT TO NOP IF SO
	ROT B,1
	MOVE IOS,MTASTS(UNIT)
	TRZ IOS,1B18!1B19!1B20!1B22!1B23!1B24!1B25!7B31!17B35
	TEST(O,IOACT,MTP)
	TEST(Z,MTSNS,OP2)
	DPB B,PMTOP2		;INTO AC IOS
	MOVEM IOS,MTASTS(UNIT)
	UNLOCK MTALCK(UNIT)
	PUSHJ P,MTNXTP		;PROCESS LEVEL MTNXT CALL
	POPJ P,

IFDEF SA10BF,<
IFDEF SSATF,<
MTMTP1:	UMOVE A,3
	HRROM A,MTMODE(UNIT)	; SAVE USER'S MODE REQUESTS
	UNLOCK MTALCK(UNIT)
	POPJ P,0
>>

; Sequential input

MTASQI:	BUG(HLT,<MTASQI: NO WAY TO GET HERE.>)

; Sequential output

MTASQO:	BUG(HLT,<MTASQO: NO WAY TO GET HERE.>)

; Delete file

MTADEL:	POPJ P,

; Rename file

MTAREN:	POPJ P,

MTACLZ:	HLRZ UNIT,DEV
	MOVSI A,IOACT
	LOCK MTALCK(UNIT)
	TDNE A,MTASTS(UNIT)
	PUSHJ P,DISBIT		; WAIT FOR UNIT TO BE NON-BUSY
	MOVSI A,OPN
	ANDCAM A,MTASTS(UNIT)	; AND MAKE IT NON-OPEN
	UNLOCK MTALCK(UNIT)
	JRST SKPRET

MTAACC:	MOVEI A,OPNX15
	POPJ P,

	USE	RESPC

MTPTBL:				; TRANSLATION TO HARDWARE COMMANDS
IFDEF TM10F,<			; IF ON TM10 TAPE CONTROL
	XWD 101,0		; Rew nop
	XWD 405,0		; Eof nil
	XWD 0,0			; Nil nil
	XWD 107,6		; Bkspc rec, skip rec
	XWD 11,0		; Rew&unload, nil
	XWD 415,0		; Blank tape, nil
	XWD 0,0			; Nil nil
	XWD 117,16		; Back file, skip file
>
IFDEF SSATF,<			; IF ON SSA TAPE CONTROLLER,
				; USE IBM DEVICE COMMANDS.
	7,,0			; 1,,0 - REWIND,,NOP
	437,,0			; 3,,2 - WRITE EOF,,NIL
	0,,0			; 5,,4 - NIL,,NIL
	47,,67			; 7,,6 - BACKSP REC,,SKIP REC
	17,,0			; 11,,10 - REW UNLOAD,,NIL
	427,,0			; 13,,12 - ERASE GAP,,NIL
	0,,0			; 15,,14 - NIL,,NIL
	57,,77			; 17,,16 - BACK FILE,,SKIP FILE
>

	USE	SWAPPC

MTDMPI:	TDZA IOS,IOS		; 0 FOR INPUT
MTDMPO:	MOVSI IOS,IO		; FLAG FOR OUTPUT
	HLRZ UNIT,DEV
	MOVE B,A		; IOWD SET UP IN IO.MAC
	LOCK MTALCK(UNIT),<PUSHJ P,LCKTST>
	MOVSI A,IOACT
	TDNE A,MTASTS(UNIT)
	PUSHJ P,DISBIT		; WAIT FOR THIS UNIT TO BE FREE
	MOVEM B,MTIOWD(UNIT)
IFDEF SSATF,< IFE SA10BF,<	; KLUDGE FOR SA10A
	PUSH P,B		; MUST SHUFFLE DATA TO GET RIGHT FORMAT
	TEST(NN,IO)		; IF WRITING
	JRST MTDMP1		; NO.
	AOBJP B,MTDMP1		; COUNT EVERY OTHER WORD
	MOVE A,1(B)		; GET A DATA WORD
	ROT A,4			; SHIFT IT AROUND
	MOVEM A,1(B)		; AND PUT IT BACK FOR WRITING
	AOBJN B,.-4		; LOOP THROUGH WHOLE RECORD
MTDMP1:>>
	EXCH IOS,MTASTS(UNIT)
	TLZ IOS,IO!MTP!777!MTSNS!OP2 ; CLEAR OLD DIRECTION, MTAPE BITS
	TRZ IOS,1B18!1B19!1B20!1B23!1B25!1B22!1B24
	TEST(O,IOACT)
	IORB IOS,MTASTS(UNIT)	; NOW ACTIVE, SET CURRENT DIRECTION
	UNLOCK MTALCK(UNIT)
	PUSH P,UNIT
	PUSHJ P,MTNXTP		; Start up magtape io
	POP P,UNIT
	MOVSI A,IOACT
	PUSHJ P,DISBIT		; Hang til complete
IFDEF SSATF,< IFE SA10BF,<
	POP P,B			; GET BACK ORIGINAL POINTER
	AOBJP B,MTDMP2		; ROTATE EVERY OTHER WORD
	MOVE A,1(B)		; GET A WORD
	ROT A,-4		; REFORMAT TO MATCH DEC CONTROLLERS
	MOVEM A,1(B)		; PUT BACK IN USER SPACE
	AOBJN B,.-4		; FOR WHOLE RECORD
MTDMP2:>>	; ACTUALLY SHOULD ONLY DO ON DATA REALLY READ...
	HRRZ A,MTASTS(UNIT)	; Get status of transfer
	TRNE A,1B18!1B19!1B20!1B23!1B25
	TEST(O,ERRF)		; Set error flag
	TRNE A,1B22
	TEST(O,EOFF)
	POPJ P,

; Routine called periodically to check completion of rewinds

	USE	RESPC

MTACHK:	MOVEI A,^D60000
	MOVEM A,MTATIM		; ONE MINUTE CHECKS UNLESS MTNXT
				;  WANTS MORE FREQUENT ONES.
	HRROI UNIT,MTAN-1
	SKIPGE MTACLS		; CALL MTNXT IF BOTH CONTROL AVAIL AND
	PUSHJ P,MTNXT		;  SOME REASON TO CALL (REWINDS EG)
	POPJ P,

; PROCESS LEVEL CALL TO MTNXT. MUST BE INTERLOCKED AMONG PROCESSES.
; INTERLOCK AGAINST CLK AND PI IS BY MTAUNT NON-ZERO

MTNXTP:	HRROI UNIT,MTAN-1
	SETZM MTACLS
	LOCK MTCLCK,<PUSHJ P,LCKTST>
	SKIPN MTAUNT
	PUSHJ P,MTNXT
	UNLOCK MTCLCK
	POPJ P,

; Start up mag tape control
; Scans for mag tape units needing action starting with the
; One following that in unit
; THIS ROUTINE IS CALLED FROM ALL LEVELS, BUT MUST BE CALLED ONLY
; WHEN THE CONTROLLER IS FREE TO START A NEW TASK.

MTNXT:	SKIPN MTAUNT		; DEFENSIVE CHECK. SHOULD BE FREE.
	JRST MTNXTA		; OK.
	BUG(CHK,<MTNXT - MTAUNT NOT ZERO>)
	POPJ P,0
MTNXTA:	SETZM MTACLS		;CLEAR CLOCK REQUEST SWITCH
	PUSH P,UNIT		; Save starting point
MTNXT1:	AOBJN UNIT,MTNXT2
	MOVSI UNIT,-MTAN
MTNXT2:	MOVE IOS,MTASTS(UNIT)
	TEST(NN,IOACT)
	JRST MTNXT0		; NOT active, try next
IFDEF SSATF,<
	JRST MTNXSA>		; GO DO INITIAL SENSE OP
IFDEF TM10F,<			; TM10 SPECIFIC
	MOVEI A,(UNIT)		; Prepare to seize tm10
	LSH A,^D15
	CONSO MTS,2		; CAN WE SELECT A NEW UNIT?
	JRST [	MOVEM UNIT,MTAUNT	; NO.
		TRO A,10400+MTACHN*10
		JRST MTNXT4]	; Do nop with next unit enable
	PUSHJ P,SETDEN		; CAN SELECT NEW UNIT, NOT BUSY
	CONO MTC,(A)		; Connect to the moving tape
	CONSZ MTS,200000	; Rewinding?
	JRST MTNXT9		; Yes, continue
	TEST(NN,REW)		; NO. Been Rewinding?
	JRST MTNXT3		; No. Need to start this drive up.
	TEST(Z,REW,IOACT)	; YES, DONE NOW. Clear rew and ioact
	HLLM IOS,MTASTS(UNIT)
	SOS REWCNT		; Decrease count of rewinding units
>
; FALL THRU

; FALLS THRU FROM ABOVE
MTNXT0:	CAME UNIT,(P)		; CHECKED THEM ALL?
	JRST MTNXT1		; NO. DO SOME MORE
	MOVEI A,^D1000		; Delay for one second
	MOVEM A,MTATIM
MTNXTX:	SKIPLE REWCNT
	AOS MTACLS		; One more reason for running clock rout
	SKIPN MTAUNT
	MOVNS MTACLS		; Make neg unless controller busy
	POP P,UNIT
	POPJ P,
IFDEF TM10F,<
MTNXT9:	TEST(NE,REW)		; Do we think it's rewinding?
	JRST MTNXT0		; Yes, go to next unit
	AOS MTACLS		; NO, JUST WAIT TILL IT STOPS REWINDING
				;  BEFORE TAKING ANY ACTION.
	MOVEI A,^D1000		; BE SURE TO LOOK SOON
	MOVEM A,MTATIM		; ..
	JRST MTNXT0		; SEE IF ANY MORE TO LOOK AT THIS PASS
>
IFDEF SSATF,<
;HERE FROM MTNXT WHEN CONTROLLER IS FREE, WHEN A DRIVE HAS IOACT ON FOR
; IT. START OPERATING THE DRIVE. FIRST, GET AN INITIAL SENSE FOR IT SO
; WE CAN SEE IF IT IS ON LINE, 7 OR 9 TK, ETC.

MTNXSA:	TEST(NE,MTSNS,OP2)	; ALREADY STARTED?
	JRST MTNXT0		; YES. BUG? SKIP THIS ONE
	TEST (NE,REW)		; REWINDING?
	JRST MTNXT0		; YES. THAT DRIVE ISN'T REALLY READY.
	MOVEM UNIT,MTAUNT	; FLAG THAT CONTROLLER BUSY, THIS DRIVE
	TEST (O,MTSNS)		; MARK THAT SENSE IS BEING DONE
	MOVEM IOS,MTASTS(UNIT)	; UPDATE STATUS
	PUSHJ P,MTSENS		; SET UP A CHANNEL PRGM TO DO SENSE
	SETZM MTBSYF		; NO BUSY REJECTION RCVD YET
	CONO SSA,SA.GOF!SA.SET!<SSATC>B32!SSACHN	; DO SENSE
	JRST MTNXTX		; CONTROL BUSY. WAIT FOR SENSE.
>

IFDEF TM10F,<
;HERE TO START UP AN ACTION ON A DRIVE.

MTNXT3:	MOVEM UNIT,MTAUNT	; CONTROLLER NOW BUSY, WITH THIS UNIT
	TEST(NE,MTP)		; Mtape op wanted?
	JRST MTDOOP		; Yes
	MOVSI A,(<BLKI MTC,>)
	TEST(NE,IO)
	MOVSI A,(<BLKO MTC,>)
	HRRI A,MTPNTR
	MOVEM A,MTALOC
	MOVE A,[PIJSYS (MTATHR)]
	MOVEM A,MTALOC+1
	SKIPL A,MTIOWD(UNIT)
	JRST MTNBUG		; SHOULDNT BE POSITIVE HERE.
	MOVEM A,MTPNTR
	MOVEI A,MTTRY
	MOVEM A,MTERRC
	SETZM MTERAS		; Erase 0 tape initially
	SETOM MTERFL		; Not now in error recovery
	MOVE A,MTPNTR
	HLRE B,A		; COUNT OF WORDS TO TRANSFER
	MOVEI A,1(A)		; ADDR OF FIRST WORD, IN MONITOR ADR SPC
	MOVSI C,-NCHCM		; SIZE OF DF10 COMMAND LIST
	SKIPN M10BF		; IS THIS A TM10B?
	JRST MTADF4		; NO. SKIP SETTING UP CHN COMMAND LIST
MTADF1:	JUMPGE B,MTADF4		; DONE IF A POSITIVE COMMAND WORD
	PUSH P,A
	PUSH P,B
	PUSHJ P,GETCPA##	; GET REAL CORE ADDRESS OF THIS PAGE
	MOVSI B,(CORMB)		; DIRTY THE PAGE
	TEST (NN,IO)		; IF READING FROM TAPE, SINCE CHANNEL
	IORM B,CST0(A)		; DOESN'T HIT CST LIKE PI DOES.
	POP P,B
	LSH A,^D9		; ADDRESS OF PAGE
	XOR A,0(P)
	TRZ A,777
	XOR A,0(P)		;STARTING WORD IN PAGE
	SUBI A,1		; ONE BEFORE IT, FOR IOWD FORMAT
	MOVEM A,CHCML(C)	; STORE IN COMMAND LIST FOR DF10
	MOVE A,0(P)		; CAN TRANSFER MAX OF (WORDS LEFT ON 
	ANDI A,777		; THE PAGE, OR, WORDS LEFT IN COUNT)
	SUBI A,1000		; SEE WHETHER TRANSFER ENDS ON THIS PAGE
	CAMGE A,B
	MOVE A,B		;IT DOES.
	SUB B,A			;UPDATE COUNT FOR WORDS LEFT ON PAGE
	HRLM A,CHCML(C)		; UPDATE COUNT IN COMMAND LIST
	MOVN A,A		; POSITIVE OF COUNT
	ADDM A,0(P)		; UPDATE CURRENT ADDRESS
	POP P,A
	AOBJN C,MTADF1		; KEEP BUILDING LIST
	BUG(CHK,<MTA - COMMAND LIST BFR OVERFLOW>)
	JRST MTFLSH		; LET SYSTEM GO ON

MTADF4:	SETZM CHCML(C)		; ZERO TERMINATES THE DF10 COMMAND LIST
				; AND ALSO THE SSA CHANNEL PROGRAM
	HRRZ A,UNIT
	LSH A,^D15
	TEST(NE,IO)
	TROA A,4000+MTBOTH	; Write function
	TRO A,2000+MTBOTH	; Read function
MTNXT4:	PUSHJ P,SETDEN		; Insert density and parity
	HRRM A,MTACOM
	CONO MTC,(A)
	JRST MTNXTX

MTDOOP:
	SETZM CHCML		;EMPTY COMMAND LIST IF DF10
	MOVEI A,(UNIT)
	LSH A,^D15
	PUSHJ P,SETDEN
	CONO MTC,(A)		; Connect to unit
	LDB B,PMTOP		; Get mtap word
	ROT B,-1
	SKIPL B
	SKIPA B,MTPTBL(B)
	HLRZ B,MTPTBL(B)
	TRZE B,100		; Backward?
	CONSO MTS,100000	; Yes, and at bot?
	JRST .+3		; NO.
	TRO IOS,1B24		; Set bot bit and
	MOVEI B,0		; Change to nop
	ANDI B,17
	JUMPE B,MTFLSH		; DON'T DO NO-OPS
	LSH B,9
	IORI A,MTACHN*10(B)
	PUSHJ P,SETDEN
	HRRM A,MTACOM
	TLZ IOS,777!MTP
	MOVEM IOS,MTASTS(UNIT)
	CONO MTC,(A)
	JRST MTNXTX


MTNBUG:	BUG(CHK,<BAD MAGTAPE IOWD>)
MTFLSH:	TLZ IOS,MTP!IOACT!777!OP2!MTSNS	; NOT MTAPE, NOT ACTIVE, NOR
				; ANY MTOPR CODE
	MOVEM IOS,MTASTS(UNIT)	; UPDATE STATUS OF UNIT
	SETZM MTAUNT		; NOW CONTROLLER IS FREE
	JRST MTNXT0
> ; END OF TM10 SPECIFIC STARTUP CODE

IFDEF TM10F,<			; TM10 SPECIFIC
SETDEN:	LDB B,PDENS
	TRZN B,4
	TRO A,1B21
	CAIN B,0
	MOVEI B,3
	SOS B
	LSH B,6
	IOR A,B
	TRO A,1B22		;SET CORE-DUMP MODE IN CASE 9-TRACK.
	POPJ P,
>
IFDEF SSATF,<			; SSA SPECIFIC
; THIS ROUTINE SETS UP THE FIRST WORD OF CHCML TO BE A MODE-SET
; COMMAND FOR AN IBM TAPE DRIVE, AND RETURNS THAT WORD IN A
; SO THE DEVICE ADDRESS CAN BE RE-USED.
; B11 IN LH OF B IS 1 IF UNIT IS 7-TK AND ONLINE

SETDEN:	MOVSI A,(SC.NMX!SC.XCT!SC.CHN!SC.ILE)
	MOVEI B,I.TDEV(UNIT)	; I/O ADDRESS OF TAPE UNIT
	LSH B,14		; TO RIGHT PLACE IN WORD
	IOR A,B			; SET INTO BITS 16-23 OF A
	LDB B,[POINT 2,IOS,28]	; USER'S DENSITY REQUEST
	CAIN B,3		; IF "800" OR 0, SET TO 0
	MOVEI B,0		; ..
	HLL B,MTASEN		; GET THE 7-TRACK BIT
	TLNN B,(1B11)		; SEVEN TRACK DRIVE?
	JRST [	MOVEI C,303	; NO (OR OFFLINE AND CAN'T TELL)
		TRNE B,3	; REQUEST HIGH DENSITY? YES = 1600
		MOVEI C,313	; NO. PUT IT AT 800.
		JRST SETDN1]
	MOVEI C,123		; SEVEN TRACK. 556, ODD, CONV ON, NO XLT
	TRNN B,3		; ASK FOR 556 OR 200?
	MOVEI C,223		; NO. SWITCH TO 800
	TRNE IOS,1B26		; WANT EVEN PARITY?
	TRZ C,20		; YES.
SETDN1:	ROT C,2			; FASTER THAN SHIFT 20. BITS, USE TLO
	TLO A,(C)		; COMMAND TO BITS 8-15 OF A
IFN SA10BF,<
	TLNE B,(1B11)		; 7 TRACK?
	SKIPN C,MTMODE(UNIT)	; YES. USER WANT TO SET MODES?
	JRST SETDN2		; NO.
	TRNE C,1B35		; YES. SUPPRESS DATA CONVERTER?
	TLO A,(40B15)		; YUP
	TRNE C,1B34		; DATA TRANSLATOR ON?
	TLO A,(10B15)		; YUP
>
SETDN2:	MOVEM A,CHCML		; FIRST WORD OF CHANNEL COMMANDS
	POPJ P,0		; END OF SSA VERSION OF SETDEN
>

IFDEF TM10F,<			; TM10 SPECIFIC
; Data done interrupt

MTATHR:	XWD MTDINR,.+1
	CONO MTS,1		; JUST SET JOB DONE FLAG, WILL CHECK
				; OR WRITE PARITY AND THEN INTERRUPT
	JEN @MTDINR
>

; Flag interrupt
; TM10 VERSION - JSYS HERE FROM PISRV

IFDEF TM10F,<			; TM10 SPECIFIC
MTASV:	XWD MTAINR,.+1
	CONSO MTC,70
	JRST @MTAINR

	CONSZ MTC,400		; Next unit enable
	CONSO MTS,2		; And control free
	CONSZ MTS,440300	; Or illop, hung xprt, BAD TAPE, job done
	JRST .+2		; Is reason for interrupt
	JRST @MTAINR		; Else this is not a mag tape int
	MOVEI A,MTACHR
	MOVEM A,MTAINR
	MOVEM P,MTSTK
	MOVE P,[XWD -MTSTKL+1,MTSTK]
	PUSH P,UNIT
	PUSH P,IOS
	MOVE UNIT,MTAUNT
	MOVE IOS,MTASTS(UNIT)
	CONSZ MTC,400		; Next unit interrupt?
	JRST MTASV3		; Yes, go look for something to do
	SKIPL A,MTERFL		; Are we trying to recover from an error
	JRST TRYAGN		; Yes
	CONSZ MTS,400000	; Unit hung?
	JRST THRTAP		; Yes. Update status and return
	CONSZ MTS,040000
	JRST ILLOP
	CONSZ MTC,7		; Data operation?
	JRST DATEND		; Yes
	LDB A,[POINT 4,MTACOM,26]	; Get cono word
	CONSZ MTS,10000		; Eof?
	TRO IOS,1B22		; Yes, set device eof
	CAIE A,1		; Rewind
	CAIN A,11		; Or unload
	JRST MTARW1
; FALL THRU, STILL TM10 CONDITIONAL

; STILL IN TM10 CONDITIONAL

THRTAP:	CONI MTS,A		;UPDATE STATUS FROM HARDWARE
	TRNE A,1B20		; Hardware load point?
	TROA IOS,1B24		; Set bot
	TRZ IOS,1B24		; Or clear it
	TRNE A,1B24		; Hardware EOT?
	TRO IOS,1B25		; Eot
	TRNE A,1B23		; If end file seen,
	 JRST MTASV1		; Ignore any errors
	TRNE A,1B22!1B25!1B27!1B28
	TRO IOS,1B20		; Data error
	TRNE A,1B18
	TRO IOS,1B19		; Data late or hung xprt
	LSH A,-^D14
	ANDI A,7B31		; Get character count
	CONSO MTS,1B26		; Incorrect record length?
	JRST MTASV1		; No
	TRZ IOS,7B31		; Yes, clear old character count
	TRO IOS,1B23		; Set incorrect record length bit
	IORI IOS,(A)		; And set count
MTASV1:	TEST(Z,IOACT)		; Io no longer active
MTASV2:	MOVEM IOS,MTASTS(UNIT)
MTASV3:	MOVE A,MTACOM
	TRZ A,17477		;CLEAR BOTH PI'S, NEXT UNIT ENB, AND
				;  FUNCTION. LEAVE DENSITY, PARITY,
				;  AND CORE-DUMP
	CONO MTC,(A)		; Clear bits
	SETZM MTAUNT		; Say controller free, unless MTNXT 
	PUSHJ P,MTNXT		;  finds something else to do
MTAXIT:	POP P,IOS
	POP P,UNIT
	MOVE P,MTSTK		;RESTORE STACK AT INTERRUPT
	JRST @MTAINR

ILLOP:	LDB A,[POINT 4,MTACOM,26] ; CONTROL SAYS ILLEG. SEE WHY
	CAIE A,4		;WHAT WAS CONO FUNCTION?
	CAIN A,14		; A WRITE?
	SKIPA			; YES
	CAIN A,5		; OR A WRITE EOF
	CONSO MTS,1B32		;YES. WRITE LOCKED?
	TROA IOS,1B19		; NO. MISC HARDWARE ERROR
	TRO IOS,1B18		; YES. WRITE LOCK ERROR
	JRST THRTAP		; ANYWAY, SHUT DOWN WITH ONE OF
				; THESE ERROR BITS.

; STILL IN TM10 CONDITIONAL

DATEND:	CONSO MTS,1B23		; Ignore errors if eof
	CONSO MTS,20600		; Data errors?
	JRST DATND1
DATEN1:	AOS MTARCE(UNIT)
	TRNE IOS,1B21		; Suppress retry?
	JRST DATND1		; Yes. Just go return status
	SOSG MTERRC
	JRST PRMERR		; Permanent error
RETRY0:	MOVE A,MTERAS
	ADDI A,2
RETRY1:	MOVEM A,MTERFL		; Initialize error sequence
	MOVE A,MTACOM		; Get original command
	ANDI A,760770		; Retain unit, density etc
	CONO MTC,7000(A)	; Space backward
	JRST MTAXIT

DATND1:	SKIPN M10BF		;TM10B?
	JRST MTADF5		;NO.
	HLRZ D,MTAICW+1		;FINAL CONTROL WORD. CHECK XFR LENGTH
	SETZB A,C
MTADF2:	CAIG D,CHCML(C)		;COMPLETED THIS COMMAND?
	JRST MTADF3		;NO
	HLRE B,CHCML(C)		;YES. GET ITS LENGTH
	SUB A,B			;ACCUMULATE TOTAL AS POSITIVE NUMBER
	AOJA C,MTADF2		;CK ALL PARTIAL COMMANDS

MTADF3:	SKIPN B,CHCML(C)	;THIS THE END OF LIST?
	JRST MTADF6		;YES.
	HRRZ C,MTAICW+1		;NO. GET ADDR OF LAST WORD XFRED
	SUBI C,0(B)		;LESS FIRST, GIVES NUMBER WORDS
	ADD A,C			; IN THIS COMMAND. ADD IT IN.
MTADF6:	HRLI A,0(A)		;GET COUNT IN BOTH HALVES
	ADDM A,MTPNTR		;COUNT UP THE BLKI/O POINTER
MTADF5:	HRRZ A,MTPNTR
	SUB A,MTIOWD(UNIT)
	HRLZM A,MTIOWD(UNIT)	; Leave length for GDSTS
	CONSZ MTS,10000		; Hardware EOF flag?
	TRO IOS,1B22		; Yes, tell user.
	JRST THRTAP

; STILL IN TM10 CONDITIONAL

PRMERR:	TEST(NN,IO)		; Write?
	JRST DATND1		; No, report error and quit
	AOS MTERAS
	MOVEI A,MTTRY
	MOVEM A,MTERRC
	JRST RETRY0

TRYAGN:	CONSZ MTS,100000	; Bot?
	MOVE A,MTERAS
	SOJL A,TRYAG1
	MOVEM A,MTERFL
	CAMLE A,MTERAS
	JRST RETRY1
	CAME A,MTERAS
	JRST TRYAG2
	MOVEM A,MTERFL
	MOVE A,MTACOM		; Now space forward over preceeding rec
	ANDI A,760770
	CONO MTC,6000(A)
	JRST MTAXIT

TRYAG2:	JUMPL A,TRYAG1
	MOVE A,MTACOM
	ANDI A,760770
	CONO MTC,15000(A)	; Erase tape
	JRST MTAXIT

TRYAG1:	SETOM MTERFL		; Through repositioning. Start over.
	MOVE A,MTIOWD(UNIT)
	MOVEM A,MTPNTR
	MOVE A,MTACOM
	CONO MTC,(A)		; Redo original op
	JRST MTAXIT

MTARW1:	TEST(O,REW)		; Remember this tape is rewinding
	AOS REWCNT
	JRST MTASV2
> ; END OF TM10 CONDITIONAL AT MTASV

IFDEF SSATF,<			; SSA SPECIFIC
;
; SSA VERSION - CALLED HERE VIA PUSHJ FROM SSASRV
; CALLED WITH FOLLOWING AC'S SET UP
;
; A/	DEVICE NUMBER
; B/	SSATC
; C/	BASE OF 4-WD BLOCK IN SSABAS
; D/	CHANNEL AND DEVICE STATUS, WORD 1
; P/	SET UP

MTASV:	PUSH P,UNIT		; SAVE A COUPLE MORE AC'S
	PUSH P,IOS		;  ..
	SUBI A,I.TDEV		; VERIFY THE TAPE UNIT NUMBER
	CAIGE A,MTAN		; FIRST IS IT ONE SYS ASSEMBLED FOR?
	CAIGE A,0		; ..
	JRST MTABUN		; BAD UNIT NUMBER.
	MOVE IOS,MTASTS(A)	; OK. GET THE CURRENT STATUS
	SKIPE UNIT,MTAUNT	; SET LH IOS .G.0 IF UNIT NOT THE
	CAIE A,(UNIT)		; SAME AS IN MTAUNT, OR MTAUNT IS 0.
	HRRZ UNIT,A		; ..
	TLNE D,(SS.SER!SS.BIP!SS.CSE)	; BAD BITS FROM SSA ITSELF?
	JRST MTCHER		; YES. CHANNEL ERROR.
	JRST MTSV00		; OK. GO PROCESS.

;EXITS FOLLOW:

MTSVX3:	CONO SSA,SA.GOF!SA.SET!<SSATC>B32!SSACHN	; START NEW OP
	SETZM MTBSYF				; NOT YET REJECTED BUSY
MTSVX1:	CONO SSA,SA.STS+<SSATC>B32+SSACHN	; CLEAR STATUS DONE FLAG
	POP P,IOS		; RESTORE AC'S
	POP P,UNIT		; ..
	POPJ P,0		; AND RETURN TO SSASRV

MTABUN:	BUG(CHK,<MTASV - UNKNOWN TAPE UNIT RESPONDED>)
	SKIPN UNIT,MTAUNT	;ASSUME SHOULD FREE CURRENT UNIT IF ANY
	JRST MTSVX1		;NONE. JUST DISMISS.
	JRST MTCHER		;GIVE CHANNEL ERROR FLAG, FREE CONTROL.
; STILL IN SSA CONDITIONAL

MTSV00:	LDB A,[POINT 8,D,15]	; THE DEVICE STATUS BYTE
	TRNE A,ID.BSY!ID.CUE	; THE HARD STATUS BITS?
	JRST MTBYCE		; BUSY OR CONTROL UNIT END.
	TEST (NE,MTSNS)		; SIMPLER CASES. DOING A SENSE?
	JRST MTSNSD		; YES. SENSE DONE
	TRNN A,ID.DVE!ID.UCK	; DEVICE END OR INITIAL UNIT CK?
	JRST MTSV01		; NO. SEE IF IT'S REWIND.
	JUMPGE UNIT,MTSRWQ	; MAY BE ASYNC REWIND
	MOVEM D,MTCHS1		; SAVE CHANNEL STATUS AFTER OP DONE.
	MOVE B,SSABAS+2+4*SSATC	; BOTH WORDS.
	MOVEM B,MTCHS2		; ..
FNLSTS:	TEST (O,OP2,MTSNS)	; FLAG DOING FINAL SENSE
RESENS:	MOVEM IOS,MTASTS(UNIT)	; UPDATE STATUS WORD
	PUSHJ P,MTSENS		; SET UP THE CHANNEL PROG FOR SENSE
	JRST MTSVX3		; START IT AND DISMISS.

MTSV01:	TRNE A,ID.CHE		; NO DEV END. SEE IF REW AND CH END.
	TEST (NN,REW)		; ..
	JRST MTSVX1		; NO. DISMISS.
	JUMPGE UNIT,MTSVX1	; MAKE SURE FOR CURRENT UNIT
	JRST THRTAP		; YES. REWINDING, DECLARE FREE.

MTSNSD:	JUMPGE UNIT,MTSVX1	; SENSE DONE. IGNORE UNLESS CURRENT UNIT
	CAIE A,ID.DVE!ID.CHE	; NORMAL STATUS BYTE COMPLETION?
	JRST RESENS		; NO. GO TRY IT AGAIN.
	TEST (Z,MTSNS)		; YES. NOT NOW DOING SENSE.
	TEST (NN,OP2)		; HAS THE OPERATION BEEN DONE?
	JRST MTSVGO		; NO. INITIAL STATUS DONE, GO DO OP.
	MOVE D,MTCHS1		; YES. ALL THRU UNLESS ERRORS. GET STAT
				;  AFTER THE OP FINISHED.
MTSI2:	TLNE D,(<ID.UCK!ID.UEX>B15)	; ANY UNUSUAL STATUS?
	JRST MTSER1		; YES. GO ANALYZE
MTSI3:	SKIPL A,MTERFL		; DEVICE END, NO ERRORS. RECOVERING?
	JRST TRYAGN		; YES.
	TEST (NN,MTP)		; NO. WAS IT AN MTAPE?
	JRST DATEND		; NO. GO FINISH DATA OP.
	JRST THRTAP		; YES. DONE WITH CONTROL. RETURN STATUS.

;NON-TRIVIAL STATUS. DECODE IT.

MTSER1:	TLNE D,(<ID.UCK>B15)	; UNIT CHECK?
	JRST MTUCK1		; YES. SOME KIND OF ERROR.
	TEST (NE,MTP)		; NO. JUST UNIT EXCEPT. DOING AN MTAPE?
	JRST MTSER4		; YES. SEE WHAT KIND.
	TEST (NE,IO)		; SET EOT OR EOF. READ OR WRITE?
	JRST MTSI3		; WRITE OP. NOT EOF, EOT SET IN THRTAP
MTSER3:	SKIPL MTERFL		; SET EOF UNLESS IN RECOVERY SEQUENCE
	JRST MTSI3		; BACK TO MAIN LINE
	TRO IOS,1B22		; SET END OF FILE
	MOVSI A,1		; AND BE COMPATIBLE WITH TM10 VERSION
	MOVEM A,MTIOWD(UNIT)	; BY GIVING ONE-WORD LENGTH OF XFER
	JRST THRTAP		; GIVE OTHER STATUS BITS.

MTSER4:	LDB A,PMTOP		; GET THE MTOPR CODE
	CAIE A,6		; SKIP RECORD?
	CAIN A,7		; OR BACKSPACE RECORD?
	JRST MTSER3		; YES, SET EOF.
	JRST MTSI3		; NO. ASSUME EOT, SET IN THRTAP

MTSRWQ:	TEST (ZE,REW)		; CLEAR REWIND
	MOVEM IOS,MTASTS(UNIT)	; UPDATE STATUS IF IT WAS REW
	JRST MTSVX1		; AND DISMISS


;BUSY OR CONTROL UNIT END ON IN STATUS BYTE

MTBYCE:	CAIN A,ID.BSY!ID.CUE!ID.SMD	; TEMPORARY BUSY?
	JRST MTSVX1		; YES. IT WILL CALL AGAIN SOON.
	TRNN A,ID.BSY		; IS IT BUSY OR JUST CONTROL UNIT END?
	JRST MTSCUE		; CU END WITHOUT BUSY
	TRNE A,377-<ID.BSY!ID.SMD>	; ANY BITS OTHER THAN THESE 2?
	JRST MTUKBS		;UNKNOWN BUSY STATUS.
	SETOM MTBSYF		; REMEMBER THIS BUSY.
	JRST MTSVX1		; AND WAIT FOR END FLAG TO ARRIVE.
MTUKBS:	BUG(CHK,<MTA - UNKNOWN BUSY STATUS>) ; FIGURE THESE OUT...
	SKIPN UNIT,MTAUNT	;MAKE SURE THIS UNIT SHOULD BE BUSY
	JRST MTSVX1		;NO, JUST DISMISS INTERRUPT
	JRST MTCHER		;YES. GIVE CHANNEL ERROR AND FREE UP JOB

MTSCUE:	SKIPN MTBSYF		; REAL BUSY?
	JRST MTCUEP		; NO, PHONY, OR REWUNLOAD.
	SETZM MTBSYF		; REAL. CLEAR SOFTWARE FLAG.
MTCUE1:	TRZ A,ID.CUE		; SEE IF ANYTHING ELSE WITH IT
	JUMPE A,MTSVX3		; IF NOT, RESTART REJECTED COMMAND
	MOVSI D,(<ID.CUE>B15)	; OTHER BITS. CLEAR CU END,
	ANDCAB D,SSABAS+<4*SSATC>+1
	JRST MTSV00		; AND GO TRY PROCESSING REST.

MTCUEP:	TRNN A,ID.DVE		; DEVICE END?
	JRST MTCUE1		; NO.
	TEST (NN,MTP)		; YES. SEE IF REWUNLOAD
	JRST MTCUE1		; NO
	LDB B,PMTOP
	CAIE B,11
	JRST MTCUE1
	JRST MTCUE1		; YES. QUICK EXIT. UNIT, CU FREE.
	;** THIS LAST WAS THRTAP BUT NEED TO DO SENSE TO FREE DRIVE..

; HERE TO START OP AFTER INITIAL SENSE DONE.

MTSVGO:	TEST (Z,MTSNS,MTBYT)	; CLEAR DOING-SENSE FLAG, BYTE MODE
	TEST (O,OP2)		; FLAG INTO OPERATION PHASE.
	MOVEM IOS,MTASTS(UNIT)	; UPDATE STATUS IN CORE
	MOVE B,MTASEN		; SEE IF IT'S ON LINE
	TLNN B,(100B15)		; TU STATUS A?
	JRST THRTPE		; NO. ABORT EARLY.
	PUSHJ P,SETDEN		; MAKE THE MODE SET COMMAND FOR CHANNEL
	TEST (NE,MTP)		; MTAPE OR DUMPI/O ?
	JRST MTDOOP		; MTAPE
	TLZ A,(377B7!377B15)	; CLR CHANNEL AND DEV CMDS, SAVE DEV ADR
	TEST (NN,IO)		; READ OR WRITE DIRECTION?
	TLOA A,(SC.XCT!<IC.RDT>B15+<SA10BF>B1)	; READ.
	TLO A,(SC.XCT!SC.ILE!<IC.WRT>B15+<SA10BF>B1)	; WRITE.
IFN SA10BF,<
	SKIPN C,MTMODE(UNIT)	; USER SPECIFYING MODES?
	JRST MTSGO1		; NO
	TEST (O,MTBYT)		; YES. ASSUME BYTE MODE
	TRNN C,1B33		; BIT 4 PACKING?
	TLZA A,(1B4)		; NO
	TLOA A,(1B4)		; YES.
	TEST (Z,MTBYT)		; NO. NOT BYTE MODE
	TRNE C,1B32		; BIT 1 PACKING?
	TEST (ZA,MTBYT)		; YES. NOT BYTE MODE.
	TLZA A,(1B1)		; NO
	TLO A,(1B1)		; YES.
	MOVEM IOS,MTASTS(UNIT)	; UPDATE BYTE MODE BIT
	JRST MTSGO2		; AND SKIP DEFAULT PACKING STUFF
MTSGO1:	TLNN B,(1B11)		; NINE TRACK DRIVE?
	TRNN B,3		; AND NOT MAX DENSITY?
	SKIPA			; NO. 7TK OR HIGH DENSITY
	TLO A,(1B4)		; YES. SET CORE-DUMP MODE.
MTSGO2:>
	MOVEM A,CHCML+1		; STORE AS CMD AFTER MODE-SET
	MOVEM A,MTACOM		; AND SAVE AS TRACKS OF LAST CMD DONE
	SKIPL A,MTIOWD(UNIT)	; GET IOLIST. MUST BE POSITIVE.
	JRST MTNBUG		; OOPS, BAD IO LIST POINTER.
	MOVEM A,MTPNTR		; SAVE TRACKS
	MOVEI B,MTTRY		; INITIALIZE ERROR COUNTERS
	MOVEM B,MTERRC		; ..
	SETZM MTERAS		; ..
	SETOM MTERFL		; ..
	HLRE B,A		; COUNT OF WORDS TO TRANSFER
	MOVEI A,1(A)		; FIRST WORD TO XFR. NO COUNT.
	MOVSI C,-<NCHCM-3>	; LENGTH OF LIST, XCEPT 0 AT END AND
	HRRI C,2		; INITIAL TWO (MODE SET AND RD OR WRT)

;FALL THRU - STILL IN SSA COND

;FALL THRU - STILL IN SSA COND

MTADF1:	JUMPGE B,MTADF4		; DONE WHEN LOOP BACK WITH + COUNT
	PUSH P,A		; CURRENT ADDR IN MON SPACE
	PUSH P,B		; CURRENT NEGATIVE COUNT
	PUSHJ P,GETCPA##	; GET CORE PAGE ADDR OF MON BFR
	MOVSI B,(CORMB)		; PAGE HAS BEEN DIRTIED, IF
	TEST (NN,IO)		; READING, BUT NEED TO MARK IT
	IORM B,CST0(A)		; BECAUSE CHANNEL DOESN'T GO THRU PGR
	POP P,B			; CURRENT -COUNT
	ANDI A,3777		; RETAIN ^D11 BITS OF PAGE NUMBER
	LSH A,11		; ADDRESS, NOT PAGE NUMBER, IN CORE.
	XOR A,(P)		; GET STARTING WORD IN REAL PAGE
	TRZ A,777		; ..
	XOR A,(P)		; ..
	MOVEM A,CHCML(C)	; STORE IN COMMAND LIST
	MOVE A,(P)		; NOW COMPUTE COUNT. FIRST WD IN BUFFER.
	ANDI A,377		; WORD IN HALF-PAGE
	SUBI A,400		; WORDS LEFT IN HALF-PAGE.
	CAMGE A,B		; OR IN IO LIST, WHICHEVER SMALLER.
	MOVE A,B		; LIST WAS SMALLER
	SUB B,A			; UPDATE COUNT TOWARD 0 (TO 0 IF DONE)
	ASH A,^D35-SSAWCP	; SHIFT TO WD CT FIELD
	TEST (NE,MTBYT)		; BYTE MODE XFER?
	ASH A,2			; YES. MAKE BYTE COUNT
	TLZ A,(1B0)		; AND MARK TO DATA CHAIN
	IORM A,CHCML(C)		; STORE IN LH OF CHANNEL DATA CMD WD
	TLO A,(1B0)		; TURN BACK INTO COUNT
	ASH A,SSAWCP-^D35	; MAKE A NEGATIVE NUMBER AGAIN
	TEST (NE,MTBYT)		; BYTE MODE XFER?
	ASH A,-2		; BACK TO WDS FROM BYTES
	MOVN A,A		; PLUS NUM WDS JUST SET UP
	ADDM A,0(P)		; ADD TO CURRENT ADDRESS
	POP P,A			; CURRENT ADDR BACK TO AC
	AOBJN C,MTADF1		; LOOP TO BUILD WHOLE DATA CHAIN
	BUG (CHK,<MTA - CMD BUFFER OVERFLOWED>)
	JRST MTFSHE		; ABORT.

MTADF4:	SETZM CHCML(C)		; END COMMAND LIST
	MOVSI A,(1B0)		; AND END DATA CHAINING IN LAST COUNT
	IORM A,CHCML-1(C)	; ..
MTADF5:	MOVE A,[TCH+CHCML]	; START WORD FOR LOW CORE
MTSVX4:	MOVEM IOS,MTASTS(UNIT)	; UPDATE STATUS
	MOVEM A,SSABAS+<4*SSATC>; ..
	JRST MTSVX3		; SET GO, CLR DONE, DISMISS

;STILL IN SSA COND

; HERE AFTER INITIAL SENSE WHEN MTOPR IS PENDING TO DO.

MTDOOP:	LDB B,PMTOP		; GET THE MTAPE CODE
	CAIN B,1		; REWIND?
	JRST [	TEST (O,REW)	; YES. FLAG IT
		AOS REWCNT	; AND COUNT REWINDING TAPES
		JRST .+1]
	ROT B,-1		; TRANSLATE TO IBM CODE
	SKIPL B
	SKIPA B,MTPTBL(B)
	HLRZ B,MTPTBL(B)
	TRNN B,-1		; NO-OP?
	JRST MTFLSH		; SKIP IT.
	DPB B,[POINT 8,A,15]	; PUT COMMAND IN WITH DEV ADDR
	TLZ A,(377B7)		; CLEAR OLD CHANNEL BITS
	TLO A,(SC.NMX!SC.XCT!SC.ILE)	; SET NEW ONES FOR MTOPR
	MOVEM A,CHCML+1		; STORE IN COMMAND LIST
	MOVEM A,MTACOM		; SAVE FOR TRACKS
	SETZM CHCML+2		; TERMINATE LIST.
	MOVEM IOS,MTASTS(UNIT)	; UPDATE STATUS
	JRST MTADF5		; AND START THE OPERATION, DISMISS.

MTNBUG:	BUG(CHK,<BAG MAGTAPE IOWD>)
MTFSHE:	TRO IOS,1B19		; DEVICE ERROR FLAG
MTFLSH:	TLZ IOS,MTP!MTSNS!OP2!MTBYT!IOACT!REW!777
	MOVEM IOS,MTASTS(UNIT)	; CLEAR ALL ACTIVITY ON UNIT
	JRST MTASV3		; AND LET GO OF CONTROL

;STILL IN SSA CONDITIONAL
; HERE IF UNIT CHECK IS ON, BUSY IS OFF. EITHER REWIND OR TROUBLE.

MTUCK1:	LDB A,[POINT 8,MTASEN,7]; FIRST BYTE OF SENSE
	CAIN A,1		; IF JUST DATA CONVERTER CHECK,
	JRST MTSI3		; IT'S OK -- HAPPENS ON 7 TK
	TRNE A,200		; COMMAND REJECT?
	JRST THRTAP		; YES. QUIT. REPORT DEVICE ERROR.
	SKIPL A,MTERFL		; IGNORE ERRORS IF IN RECOVERY SEQUENCE
	JRST TRYAGN		; ..
	TEST (NE,MTP)		; MTAPE OR DATA OP?
	JRST THRTAP		; MTAPE. JUST UPDATE STATUS WD
MTUCK2:	AOS MTARCE(UNIT)	; AN ERROR. COUNT IT.
	TRNE IOS,1B21		; USER WANT HIS OWN ERROR CHECKING?
	JRST DATEND		; YES.
	SOSG MTERRC		; NO. COUNT ERRORS DOWN.
	JRST PRMERR		; FAILED. CALL IT PERMANENT
RETRY0:	MOVE A,MTERAS		; DO A RETRY
	ADDI A,2		; SET STATE FLAG TO START RETRY
	MOVEM A,MTERFL		; ..
RETRY1:	MOVSI B,(<IC.BSB>B15)	; AND DO A BACKSPACE "BLOCK" (=RECORD)
RETRYX:	MOVE A,CHCML		; GET MODE SET COMMAND FROM SETDEN
	MOVEM A,MTRECP		; TO RECOVERY PROGRAM
	TLZ A,(SC.CHN!377B15)	; CLEAR CHAIN BIT, OP CODE.
	TDO A,B			; SET NEW OP CODE.
	MOVEM A,MTRECP+1	; DO THIS OPCODE
	SETZM MTRECP+2		; END OF PROGRAM
	MOVE A,[TCH+MTRECP]	; FOR LOW CORE
RETRYY:	JRST MTSVX4		; UPDATE IOS, STORE LO CORE, SET GO

DATEND:	HRRZ D,MTCHS2		; HOW MUCH OF CHAIN WAS DONE?
	SETZB A,C		; WORK AC'S
DATEN3:	CAIG D,CHCML+2(C)	; STILL IN EXECUTED PART OF CHAIN?
	JRST DATEN4		; NO
	SKIPE B,CHCML+2(C)	; YES. GET THE LENGTH
	TLO B,(1B0)		; SET SIGN UNLESS IT'S 0
	ASH B,-<^D18+<^D17-SSAWCP>>	; MINUS WORDS IN THIS POINTER
	SUB A,B			; MAKE IT PLUS WORDS TRANSFERRED SO FAR
	AOJA C,DATEN3		; LOOP THRU CHANNEL COMMAND LIST
DATEN4:	HLRE B,MTCHS2		 ; ANY PARTIAL COUNT LEFT
	ASH B,-<^D17-SSAWCP>	; WORDS
	JUMPE B,DATEN5		; ANY THERE?
	ORCMI B,<1_<SSAWCP+1>>-1 ; YES. MAKE IT NEGATIVE
	ADD A,B			; SUBTRACT FROM TOTAL IN REQUESTS
DATEN5:	HLRE B,MTIOWD(UNIT)	; SEE IF IT IS RIGHT
	TEST(NE,MTBYT)		; IN BYTE MODE, CONVERT
	ASH B,2			;  REQUESTED WORDS TO BYTES
	ADD B,A			; SHOULD ADD TO ZERO
	MOVE C,MTCHS1		; WAS IT MAYBE TOO LONG?
	TLNN C,(SS.LNE)		; IF SO COUNT GOOD BUT H'WARE TELLS.
	SKIPE B			; SHOULD BE 0
	TRO IOS,1B23		; LENGTH ERROR
	HRLZM A,MTIOWD(UNIT)	; SAVE FOR GDSTS
	JRST THRTAP		; UPDATE STATUS FOR USER.

DATEN1==RESENS			; FOR RESTART ENTRY POINT

; STILL IN SSA CONDITIONAL

;STILL IN SSA CONDITIONAL
; HERE ON INTERRUPT LEVEL TO RELEASE MAGTAPE CONTROL,
; UPDATE IOS, AND CALL MTNXT. THRTPE ALSO SETS ERROR BIT 19 IN IOS.
; SENSE INFO MUST ALREADY BE IN MTASEN ON CALL

THRTPE:	TRO IOS,1B19		; GIVE EQUIPMENT ERROR
THRTAP:	MOVE D,MTASEN		; UPDATE SOFTWARE FROM HARDWARE
	TLNE D,(1B12)		; AT LOAD POINT?
	TROA IOS,1B24		; YES
	TRZ IOS,1B24		; NO
	MOVE B,MTASEN+1		; GET EOT (TAPE INDICATOR)
	TLNE B,(1B2)		; ON?
	TROA IOS,1B25		; YES
	TRZ IOS,1B25		; NO
	TLNE D,(1B4)		; DATA ERROR?
	TRO IOS,1B20		; YES.
	TLNE D,(1B1!1B3)	; INTERV REQ, EQUIP CK?
	TRO IOS,1B19		; YES. "HARDWARE ERROR"
	TLNE D,(1B0)		; COMMAND REJECT?
	TRO IOS,1B18		; YES. WRITE LOCK ERROR.
MTASV1:	TLZ IOS,IOACT!MTP!777!OP2!MTBYT!MTSNS
				; TAPE NO LONGER ACTIVE. UNBLK PROCESS.
MTASV2:	MOVEM IOS,MTASTS(UNIT)		;UPDATE SOFTWARE STATUS
	HRRZ A,MTAUNT		; SEE IF FOR UNIT IN MTAUNT
	SKIPE MTAUNT		; IF NO SUCH UNIT,
	CAIE A,(UNIT)		; OR NOT SAME ONE,
	JRST MTSVX1		; QUIT NOW.
MTASV3:	SETZM MTAUNT		; NOW THE CONTROL IS FREE
	HRROI UNIT,MTAN-1	; IN CASE CAME IN ASYNCHRONOUSLY
	PUSHJ P,MTNXT		; GIVE IT TO ANOTHER GUY IF WANTED
	JRST MTSVX1		; DISMISS

MTCHER:	MOVEI IOS,1B19		; EQUIP ERROR ON SSA CHANNEL ERR FLAG
	IORB IOS,MTASTS(UNIT)
	JRST MTASV1		; CLEAR EVERYTHING AND DISMISS

; STILL IN SSA CONDITIONAL

;STILL IN SSA CONDITIONAL

PRMERR:	TEST (NN,IO)		; READING OR WRITING?
	JRST THRTAP		; READING. QUIT.
	AOS MTERAS		; WRITING. SET TO ERASE GAP MORE.
	MOVEI A,MTTRY		; AND RESTORE ERROR COUNT
	MOVEM A,MTERRC		; ..
	JRST RETRY0		; START RETRY SEQUENCE

TRYAGN:	MOVE A,MTERFL		; GET CURRENT ERROR STATE
	MOVE D,MTASEN		; SEE IF BACK TO LOAD POINT
	TLNE D,(1B12)		; ..
	MOVE A,MTERAS		; YES. DON'T BACK UP ANY MORE
	SOJL A,TRYAG1		; TIME TO ERASE, IF JUMP.
	MOVEM A,MTERFL		; UPDATE STATE COUNTER
	CAMLE A,MTERAS		; WHAT NEXT?
	JRST RETRY1		; BACKSPACE
	CAME A,MTERAS		; WANT ERASE OR SKIP?
	JRST TRYAG2		; ERASE
	MOVEM A,MTERFL		; UPDATE COUNTER
	MOVSI B,(<IC.SKB>B15)	; SKIP BLOCK ("BLOCK"=RECORD)
	JRST RETRYX

TRYAG2:	MOVSI B,(<IC.ERG>B15)	; ERASE GAP
	JRST RETRYX

TRYAG1:	SETOM MTERFL		; BACK TO RE-TRY ORIGINAL DATA OP.
	MOVE A,[TCH+CHCML]	; CHANNEL JUMP TO DO IT AGAIN
	JRST RETRYY		; GO RESTART IT.
; STILL IN SSA CONDITIONAL

;STILL IN SSA CONDITIONAL
; ROUTINE TO BUILD CHANNEL COMMAND LIST TO READ
;  SENSE BYTES FOR A DRIVE INTO THE "MTASEN" BUFFER.
; ASSUMES INTERLOCKING SO NOBODY CONTESTS FOR THAT STORAGE
; BLOCK OR FOR THE MAGTAPE CHANNEL OF THE SSA.

MTSENS:	MOVEI A,I.TDEV(UNIT)	; THIS UNIT
	MOVSI B,(SC.XCT!SC.BYT!<IC.SNS>B15)
	DPB A,[POINT 8,B,23]	; SET UP A SENSE COMMAND FOR THE DRIVE
	MOVEM B,MTSNSP		; STORE IN CHANNEL PROGRAM
	MOVSI B,<-^D24>_<^D17-SSAWCP>	; TWENTY FOUR SENSE BYTES
	HRRI B,MTASEN		; TO THIS STORAGE AREA
	MOVEM B,MTSNSP+1	; NEXT WORD OF PROGRAM
	SETZM MTSNSP+2		; END OF PROGRAM
	MOVE B,[TCH+MTSNSP]	; WHERE TO START.
	MOVEM B,SSABAS+<4*SSATC>
	POPJ P,0		; END OF MTSENS
> ; END OF CONDITIONAL ON SSA, WAY BACK AT MTASV

	USE	SWAPPC

BUSY:	MOVEI A,OPNX9
	UNLOCK MTALCK(UNIT)
	POPJ P,

MTAILM:	MOVEI A,OPNX14
	POPJ P,

DISBIT:	PUSH P,A+1
	JFFO A,.+1
	PUSH P,A
	MOVEI A,BITTST
	DPB A+1,[POINT 9,A,8]
	DPB UNIT,[POINT 9,A,17]
	JSYS EDISMS
	POP P,A
	POP P,A+1
	POPJ P,

	USE	RESPC

BITTST:	LDB 2,[POINT 9,1,26]
	LDB 3,[POINT 9,1,35]
	MOVE 3,MTASTS(3)
	ROT 3,(2)
	JUMPL 3,0(4)
	JRST 1(4)

>		; End of ifdef on page 1
	END

