;------------------------------------------------------------------------------
;
;	KENNEDY TAPE CONTROL UCODE - OLD PROGRAMMED I/O VERSION
;
;------------------------------------------------------------------------------

;TAPE READING AND WRITING CODE
; A-MEM USEAGE:
;		0	DISPATCH ADDR.
TPMODE =	0	;DATA PACKING MODE 
;			 BIT 0: 0=PDP-10 CORE-DUMP, 1=INDUSTRY (32-bit mode)
;			 BIT 1: NRZI Kluge Mode (to read old CCRMA & SCI tapes)
;		1	Used by FMNBWT and TRCHECK for NRZI Kluge Mode info.
;		2,3	DON'T USE... Storing into them clobbers IR left !
;		4	CURRENT CONTENTS OF MODE CTRL REG
;		5	SAVED COPY OF WORD COUNT (WRITE)
;		6	MASK FOR TESTING ERROR STATUS (WRITE)
;		7	RETRY COUNT (WRITE)

KNYRST:  ;RESET the formatter and drive.
	START-OUT ALU[0]  DEST[IOD] $
	 ;TURN OFF "FORMATTER ENABLE"
	MAPF[2] LONG POPJ $

   ;727 - OBSOLETE VERSION OF READ
TAPERD:	NORM PUSHJ[KNYRGO] $
	D[MASK 17.] DEST[IR-ADR] PUSHJ[TRP2] NORM $
		;MOVE STATUS INTO AC.
	ALU[Q] DEST[AC] ACSEL[AC] MAPF[2] JUMP[MAIN] C-OUT $

; KNYRGO -- CALLED START TAPE MOTION.   WAITS FOR FIRST BYTE.
KNYRGO:	D[CONST 22] ROT[27.] DEST[Q] NORM $
		;Construct mode information for KENNEDY formatter
	D[12] ALU[DORQ] DEST[Q] NORM $
	   	;INCLUDE STANDARD BITS (FOR TIMERS AND STUFF).
	START-OUT D[CONST 2] ROT[6] ALU[DORQ] DEST[IOD] NORM $
		;Set mode for tape controller to talk to KENNEDY
		;22000,,200 means:
		; SEL RD DAT, CTRL KNY, IN
	MAPF[4] D[CONST 0] DEST[Q]   C-OUT PUSHJ[KNYGOA] $
	 ;SEND COMMAND TO FORMATTER.
;	\ /
KNYWAIT:	START-IN SHORT $
	; command register by caller
	MAPF[1] D[CONST 77] ROT[12.] DEST[AR] NORM $
		;Clear read data ready flag
KNYW1:	START-IN D[AR] ALU[D-1] DEST[AR] 
		C550 COND[OBUS=0] JUMP[KNYW2] $
	MAPF[2] D[IOD] DEST[HOLD] C800 $
	D[MEM] ROT[27.] MASK[1] COND[-OBUS=0] POPJ C550 $
	NORM JUMP[KNYW1] $
KNYW2:	NORM POPJ $

KNYGOA:	START-IN D[CONST 1] ROT[35. - 26.] ALU[DORQ] DEST[Q]
	 PUSHJ[FMNBWT] $
	  ;Add the FMTR ENBL bit to the command word.
	  ;WAIT FOR FORMATTER NOT BUSY.
	START-OUT D[CONST 41] ROT[35. - 8.] DEST[IOD] NORM $
		;RESET THE CONTROLLER ERROR CONDITIONS.
	MAPF[1] START-OUT D[11] DEST[IOD] C800 $
	  ;Clear the pulse-catching tape status flags (FMK, etc.)
	   ; A-MEM[1] IS SET UP BY TAPE RESET CODE (TAPRST)
	MAPF[1] START-OUT 
	 D[CONST 1] ROT[35. - 33.] ALU[D#Q] DEST[IOD] C-OUT $
	  ;Set the GO bit to fmtr (on RWD, CLEAR the bit !)
	MAPF[2] START-OUT D[CONST 1] ROT[35. - 33.] ALU[-D&Q] DEST[IOD] $
	  ;Send command word again, without GO bit.
	MAPF[2] LONG POPJ $

FMNBWT:	  ;Wait for formatter to be not busy.
	START-IN D[CONST 12] ROT[16.] DEST[AR] NORM $
FMNBW1:	MAPF[4] D[IOD] DEST[HOLD] C800 $ ;GET STATUS BITS.
	D[AR] ALU[D-1] DEST[AR] C550 OBUS<0 JUMP[FMTHNG] $
	C550 $
	START-IN D[MEM] ROT[7] C550 -OBUS<0 JUMP[FMNBW1] $
	  ;CHECK FOR 'DATA BUSY'
	NORM POPJ $
FMTHNG:	NORM PUSHJ[KNYRST] $
		;Blast the formatter.
	D[CONST 42] ROT[30.] DEST[AC] JPOP[MAIN] $
		;Return error code for 'hung fmtr' and abort.

;READ A RECORD.  STORE UP TO C(IR-ADR) WORDS.

TRP2:	START-IN NORM PUSHJ[TRBY3] $ ;READ FIRST BYTE.
	NORM JUMP[TRP2B] $
TRP2A:	D[MA] ALU[D+1] DEST[MA] PUSHJ[TRBYTE] NORM $
TRP2B:	 D[MEM] ROT[34] DEST[Q] PUSHJ[TRBYTE] NORM $
	 D[MEM] ROT[24] ALU[DORQ] DEST[Q] PUSHJ[TRBYTE] NORM $
	 D[MEM] ROT[14] ALU[DORQ] DEST[Q] PUSHJ[TRBYTE] NORM $
	 D[MEM] ROT[4] ALU[DORQ] DEST[Q] PUSHJ[TRBYTE] NORM $
	 D[IR] MASK[18.] ALU[D-1] DEST[IR-ADR] C550 
		COND[OBUS18] JUMP[TRP2A] $
	D[MEM] MASK[4]  ALU[DORQ] DEST[MEMSTO] NORM JUMP[TRP2A] $

;READ 1 BYTE.  IF ERROR, EOR, EOF, SET Q_2,HIGHEST LOC WRITTEN+1,1 & POP
; ONE OFF THE STACK AND RETURN.  IF BYTE SUCCESSFULLY
; READ, JUST RETURN WITH BYTE IN HOLD.

TRBYTE:	START-IN D[CONST 35]  LLOAD NORM $
		;Ask tape for a byte and status thereof
		;Set loop counter to do timeout
		;(TIMEOUT IN ABOUT 78. USEC)
TRBY1:	MAPF[2] D[IOD] ALU[NOTD] DEST[HOLD] LONG LOOP[TRBY2] $
		;Read byte and status.  Byte comes complemented.
		;Result is put in HOLD to avoid synchronizer problems
		;Do timeout check and branch if still waiting
	START-IN NORM JUMP[TRCHECK] $
		;Byte wasn't ready in time.  Go find out why
;	---
TRBY2:
	SHORT $
	START-IN D[MEM] ROT[26.] OBUS<0 C550 JUMP[TRBY1] $
		;Check for byte ready (this is a 3 instruction loop)
		;Start getting byte and status again in case we have
		;  to loop
TRBY3:	START-IN MAPF[2] D[IOD] ALU[NOTD] DEST[HOLD] C800 $
	        ;READ THE DATA AGAIN (NOW THAT IT'S STABLE !)
	MAPF[1] D[MEM] MASK[10] DEST[HOLD] C550 POPJ $
		;MAPF[1] clears byte ready
		;Extract data byte from other status information
;	---

TRCHK1:	PUSHJ[TRCHECK] $

TRCHECK:	
	PUSHJ[FMNBWT] $
	  ;wait for FORMATTER NOT BUSY.
	D[MEM] ROT[32.] C550 -OBUS<0 JUMP[TRERR] $
	  ;check for HARD ERROR status.
;;;;;	D[MEM] ROT[16.] C550 -OBUS<0 JUMP[TRERR] $
	  ;check for OVERRUN ERROR.
	D[MEM] ROT[33.] C550 -OBUS<0 JUMP[TREOF] $
	  ;Jump if EOF was seen.
TREOR:	D[MA] MASK[24] DEST[Q] NORM JUMP[TRDONE] $ ;ENDX OF REC.
TRDONE:	NORM JPOP[. + 1] $  ;REMOVE ONE RETURN ADDR FROM STACK.
	NORM POPJ $	;RETURN UPLEVEL (CODE IN Q)
TREOF:	D[CONST 60] ROT[36] DEST[Q]  NORM JUMP[TRDONE] $
TRERR:	D[CONST 50] ROT[36] DEST[Q] NORM JUMP[TRDONE] $


	.PAIR
	UIOTRP[MUUO] $

TAPEMT:	;OPCODE 726 -- MTAPE FUNCTIONS.
	D[MA] DEST[Q] COND[OBUS=0] JUMP[TAPERW] C550 $
	D[CONST 1] ALU[D-Q] COND[OBUS=0] JUMP[TWREOF] C550 $
	D[CONST 50] ALU[D-Q] COND[OBUS=0] JUMP[TPSETIND] C550 $
		;Code ?, set industry compatable mode.
	D[CONST 51] ALU[D-Q] COND[OBUS=0] JUMP[TPSETDMP] C550 $
		;Code ?, set PDP-10 dump mode.
	D[CONST 5] ALU[D-Q] COND[OBUS=0] PUSHJ[TAPEFR] C550 $
	D[CONST 6] ALU[D-Q] COND[OBUS=0] PUSHJ[TAPEBR] C550 $
	NORM PUSHJ [TRCHK1] $
	    ;WAIT FOR ENDX OF OP. AND GET ENDING STATUS IN Q.
	ALU[Q] DEST[AC] NORM JUMP[MAIN] $
	    ;RETURN STATUS TO CALLER IN HIS AC (SAME AS READ)


TWREOF:	 ;WRITE AN ENDX OF FILE (TAPE MARK)
	D[CONST 1] ROT[35. - 28.] DEST[Q] NORM $ ; WRT EOF cmd bit
TERASE:	D[CONST 1] ROT[35. - 22.] ALU[DORQ] DEST[HOLD] 
	   NORM JUMP[KNYMTP] $  ;Add WRT CMD bit and start command.

KNYMTP:	START-OUT D[12] DEST[IOD] NORM $
	MAPF[4] D[MEM] DEST[Q] C-OUT PUSHJ[KNYGOA] $
	START-OUT D[CONST 1] ROT[35. - 26.] DEST[IOD] NORM $
	   ;CLEAR ALL COMMAND BITS EXCEPT FORMATTER ENABLE.
	MAPF[2] ALU[-1] DEST[Q] LONG POPJ $
	  ;PUT -1 IN Q IN CASE WE ARE RETURNING TO TAPEMT.

TAPERW:	;REWIND
	D[CONST 24] DEST[HOLD] NORM JUMP[KNYMTP] $
	  ;RWD AND GO BITS -- KNYGOA WILL DELETE THE GO BIT !

TAPEFR:	;SKIP FORWARD ONE RECORD.
	D[CONST 0] DEST[HOLD] NORM JUMP[KNYMTP] $
	  ;START A READ, BUT IGNORE THE DATA.

TAPEBR:	;SKIP BACKWARD ONE RECORD.
	D[CONST 1] ROT[35. - 27.] DEST[HOLD] NORM JUMP[KNYMTP] $
	  ;JUST A READ BACKWARD, WITH THE DATA IGNORED.

TPSETIND:	;Set industry compatable mode
	D[10 + TPMODE] DEST[Q] NORM $	;Stupid A-MEM
	D[CONST 1] ROT[35.] ALU[DORQ] DEST[TPMODE] DEST-A-MEM JUMP[MAIN] NORM $
		;Set appropriate bit and done

TPSETDMP:	;Set PDP-10 Dump Mode
	D[10 + TPMODE] DEST[Q] NORM $	;Stupid A-MEM
	D[CONST 1] ROT[35.] ALU[-D&Q] DEST[TPMODE] DEST-A-MEM JUMP[MAIN] NORM $
		;Clear industry compatable mode and done.


TAPERS:	;OPCODE 727 -- READ STATUS BITS FROM TAPE DRIVE.

.DEFINE TSS[A B]   
[  ;MOVE BIT A OF AR TO BIT B OF Q.
  	D[AR] ROT[1 + A] MASK[1] DEST[HOLD] NORM $
	D[MEM] ROT[35. - B] ALU[DORQ] DEST[Q] NORM $ ]

	START-OUT D[12] DEST[IOD] NORM $
	  ;CLEAR THE MODE CTRL REGISTER.
	MAPF[4] START-OUT 
	 D[CONST 1] ROT[35. - 26.] DEST[IOD] C-OUT $
	  ;ENABLE THE FORMATTER.
	MAPF[2] START-IN ALU[0] DEST[Q] C800 $
	  ;READ STATUS BITS.
	MAPF[4] D[IOD] ALU[NOTD] DEST[AR] C800 $
	  ;NOW RE-ARRANGE THE BITS
	TSS[ 3 30. ]	;ON LINE
	TSS[ 11. 31. ]	;REWINDING
	TSS[ 4 32. ]	;FILE PROTECT
	TSS[ 12. 33. ]	;LOAD POINT
	TSS[ 10. 34. ]	;READY
	TSS[ 5 35. ]	;ENDX OF TAPE
	ALU[Q] DEST[MEMSTO] NORM
		COND[-MA-AC] LBJUMP[SMAIN] $


	.PAIR
	UIOTRP[MUUO] $
TAPENR:	;730, AC/COUNT.  READ WHOLE RECORD,
	;STORING UP TO COUNT WORDS STARTING AT EFF ADR.
	;IF AC<>0 RETURN STATUS AS FOR 727.
	 ;SWAP AC AND MA, THEN DO TAPERX.
	D[MA] DEST[O_AC MA] ACSEL[AC]  NORM JUMP[TAPERX] $ 

	.PAIR
	UIOTRP[MUUO] $
TAPERX:	;732 - (AC) IS START ADDR., E IS # OF WORDS TO READ.
	NORM PUSHJ[KNYRGO] $ ;GET TAPE STARTED.
	ALU[AC] ACSEL[AC] DEST[MA] PUSHJ[TRP2] NORM $ ;READ REC.
		;MOVE STATUS INTO AC.
	D[IR] COND[-OBUS18] JUMP[TNRP3] C550 $ ; WAS RECORD TOO LONG ?
	D[CONST 44] ROT[30.] ALU[DORQ] DEST[Q] NORM $ ;YES, SET BIT 3.
TNRP3:	ALU[Q] DEST[AC] ACSEL[AC] JPOP[MAIN] NORM $  ;NO, NOT TOO LONG.


UTAPWR:	UIOTRP[MUUO] $
	D[CONST 2] ROT[6] DEST[IOD] SPEC[IOB-OUT] NORM JUMP[TAPEWR] $
		;Copy of thing in dispatch
TAPEWR:	;731, AC/ADR, E/+COUNT.  WRITE RECORD OF +COUNT
	; WORDS, DATA FROM ADR.
	;SET AC:=0 IF OPERATION COMPLETED SUCCESSFULLY.
	; SET AC:=<SETZ> + HIGHEST ADR READ IF REACHED
	; EOT DURING OPERATION (CURRENTLY THIS IS THE ONLY
	; ERROR CONDITION.)  OPERATION IS COMPLETED EVEN
	; IF EOT IS PASSED.

	D[CONST 10.] DEST[7] DEST-A-MEM NORM $
	  ;SET UP ERROR RETRY COUNT.
TWRTRY:	START-OUT D[12] DEST[Q IOD] NORM $ ;CLEAR MODE CTRL REG.
	MAPF[4] START-OUT D[CONST 1] ROT[35. - 3] DEST[IOD]  $
	   ;GIVE "MR" TO CLEAR TP RD DAT RDY
	MAPF[1] D[CONST 31] ROT[35. - 8] ALU[DORQ] DEST[Q] C-OUT $
	   ;Construct mode information for KENNEDY formatter
	START-OUT D[CONST 1] ROT[35. - 16.] ALU[DORQ] DEST[Q IOD] $
		;Set mode for tape controller to talk to KENNEDY
		;31002,,0 means:
		;SEL BT DAT, CTRL TLX, FIFO ENB
	MAPF[4] ALU[Q] DEST[4] DEST-A-MEM $
	   ;SAVE CONTENTS OF MODE REGISTER.
	D[CONST 1] ROT[35. - 22.] DEST[Q] C-OUT PUSHJ[KNYGOA] $
	   ;GO GIVE WRITE COMMAND TO FORMATTER.
	
	D[CONST 12] ROT[12.] DEST[IR-ADR] NORM $
		;Get timeout count for first call of TWBYTE.
	ALU[0] DEST[6] DEST-A-MEM NORM $
		;Clear a-mem[6], so TWBYTE can collect status
	D[MA] MASK[18.] DEST[AR 5] DEST-A-MEM NORM $
	 ;Move wc to AR, and preserve in AMEM(5) for retry.
	ALU[AC] ACSEL[AC] DEST[MA] NORM $
	 ;Fetch first word to be written.
TWNW:	FIXM1 $
	START-IN D[MEM] ROT[8] MASK[8] DEST[IOD] PUSHJ[TWBYTE] NORM $
	START-IN D[MEM] ROT[20] MASK[8] DEST[IOD] PUSHJ[TWBYTE] NORM $
	START-IN D[MEM] ROT[30] MASK[8] DEST[IOD] PUSHJ[TWBYTE] NORM $
	D[10 + TPMODE] C550 OBUS<0 JUMP[TWNWI] $
		;Check for industry compatable mode while we have time.
	START-IN D[MEM] ROT[40] MASK[8] DEST[IOD] PUSHJ[TWBYTE] NORM $
	D[AR] ALU[D-1] DEST[AR] C600 COND[OBUS=0] JUMP[TWNW1] $
	START-IN D[MEM] MASK[4] DEST[IOD] PUSHJ[TWBYTE] NORM $
	D[MA] ALU[D+1] DEST[MA] NORM JUMP[TWNW] $ ;Fetch next word.
TWNWI:	D[AR] ALU[D-1] DEST[AR] C600 COND[OBUS=0] JUMP[TWNWI1] $
	START-IN D[MEM] ROT[40] MASK[8.] DEST[IOD] PUSHJ[TWBYTE] NORM $
	D[MA] ALU[D+1] DEST[MA] NORM JUMP[TWNW] $ ;Fetch next word.

TWNW1:	D[MEM] MASK[4] DEST[Q] NORM JUMP[TWDONE] $  
		;LAST BYTE OF RECORD...
TWNWI1:	D[MEM] ROT[40] MASK[8.] DEST[Q] NORM JUMP[TWDONE] $  
			;LAST BYTE OF RECORD...
TWDONE:	START-IN D[CONST 1] ROT[35. - 1] ALU[DORQ]  
	DEST[IOD] NORM PUSHJ[TWBYTE] $ ;SET  'BT DAT LAST' BIT.

	D[14] DEST[Q] NORM $ ;RECOVER MODE REGISTER CONTENTS.
	START-OUT D[CONST 1] ROT[35. - 1] 
	   ALU[DORQ] DEST[IOD] NORM $ ;SET "LAST BYTE ENBL"
	START-IN MAPF[4] PUSHJ[FMNBWT] $
	  ;WAIT FOR FORMATTER NOT BUSY.

	D[MEM] ALU[NOTD] DEST[Q] NORM $ ;Complement of status
	D[CONST 1] ROT[35. - 32.]  ALU[D&Q] C550 
	  COND[-OBUS=0] JUMP[TWERR] $ ;Test HARD ERR.
	ALU[0] DEST[AC] NORM $ ;We return 0 in AC if no EOT.
	D[16] ROT[35. - 5] C550 -OBUS<0 JUMP[MAIN] $
	 ;If no EOT seen, all done.
	D[MA] MASK[18.] DEST[AC] NORM $ ;EOT seen. Get ending MA.
	D[CONST 41] ROT[35. - 5] ALU[DORAC] DEST[AC] NORM JUMP[MAIN] $
	 ;Turn on bits 0 and 5 to indicate EOT seen during operation.

TWBYTE:	MAPF[4] D[IOD] ALU[NOTD] DEST[Q] LONG $
	 ;Read TP STAT (complemented).
	D[16] ALU[DORQ] DEST[Q] NORM $ 
		;OR new bits into A-MEM[6] for later testing.
	D[IR] MASK[18.] ALU[D-1] DEST[IR-ADR] C550 OBUS<0 JUMP[FMTHNG] $
		;Test for timeout.
	START-IN D[CONST 2] ALU[D&Q] C550 COND[-OBUS=0] JUMP[TWBYTE] $
		;Loop until FIFO IN RDY is true.
	START-OUT D[CONST 12] ROT[12.] DEST[IR-ADR] NORM $
		;Put next byte in TP DAT BF, get timeout for next call of TWBYTE.
	MAPF[14] ALU[Q] DEST[6] DEST-A-MEM C800 POPJ $
		;Save new accumulated status (note: FIFO IN RDY bit is 0 here !)

TWERR:	START-IN NORM PUSHJ[FMNBWT] $  ;WAIT FOR NOT BUSY.
	NORM PUSHJ[KNYRST] $ 
	  ;Blast the tape formatter and drive 
	D[17] ALU[D-1] DEST[Q] C550 -OBUS<0 JUMP[TWER1] $
	  ;SEE IF WE HAVE HAD TO MANY RETRY'S ALREADY...
	D[CONST 50] ROT[30.] DEST[AC] JUMP[MAIN] $
	   ;HOPELESS. GIVE ERROR RETURN TO PRGM.
TWER1:	ALU[Q] DEST[7] DEST-A-MEM NORM PUSHJ[TAPEBR] $
	 ;Start a BACKSPACE RECORD command.
	START-IN NORM PUSHJ[FMNBWT] $ ;Wait for completion.
	D[CONST 3] ROT[35. - 29.] DEST[Q] NORM PUSHJ[TERASE] $
	  ;ERASE A 3.5" GAP ON THE TAPE.
	START-IN NORM PUSHJ[FMNBWT] $ ;Wait for completion.
	D[15] DEST[MA] NORM JUMP[TWRTRY] $
	  ;RECOVER WC AND START WRITE OP AGAIN.

;BOOTSTRAP LOADER FOR MACROCODE.

MBSAVP:	;SAVE LOC. CTR.

	.ORG[5000]
MBOOT:	JUMP[MBOOT + 1] CYLEN[LONG] $
	ALU[0] DEST[HI-ABS-MA] PUSHJ[CCLR] NORM $
	D[CONST 1] ROT[18.] DEST[HI-ABS-MA] PUSHJ[CCLR] NORM $
	D[CONST 7] DEST[DEV-ADR] PUSHJ[TAPRST] $
	D[CONST 7] DEST[DEV-ADR] CYLEN[LONG] PUSHJ[KNYRGO] $
		;SELECT DEVICE 7, START READ.
	START-IN ALU[0] DEST[MA HI-ABS-MA] NORM PUSHJ[MBTBY3] $
	NORM JUMP[P2A] $
P2:	D[MA] ALU[D+1] DEST[MA] PUSHJ[MBTBYTE] NORM $
P2A:	D[MEM] ROT[34] DEST[Q] PUSHJ[MBTBYTE] NORM $
	D[MEM] ROT[24] ALU[DORQ] DEST[Q] PUSHJ[MBTBYTE] NORM $
	D[MEM] ROT[14] ALU[DORQ] DEST[Q] PUSHJ[MBTBYTE] NORM $
	D[MEM] ROT[4] ALU[DORQ] DEST[Q] PUSHJ[MBTBYTE] NORM $
	D[MEM] MASK[4]  ALU[DORQ] DEST[MEMSTO] NORM JUMP[P2] $

CCLR:	ALU[0] DEST[MA] NORM $
	ALU[0] DEST[MEMSTO] NORM $
	D[MA] ALU[D+1] DEST[MA] NORM $
	D[MA] MASK[18.] COND[-OBUS=0] JUMP[. - 2] C600 $
	POPJ NORM $

MBTBYTE:
	START-IN D[CONST 35] ROT[1] LLOAD NORM $
		;Ask tape for a byte and status thereof
		;Set loop counter to do timeout
		;(TIMEOUT ABOUT 78 USEC)
MBTBY1:	MAPF[2] D[IOD] ALU[NOTD] DEST[HOLD] C800 LOOP[MBTBY2] $
		;Read byte and status.  Byte comes complemented.
		;Result is put in HOLD to avoid synchronizer problems
		;Do timeout check and branch if still waiting
	START-IN NORM PUSHJ[MBTCHECK] $
		;Byte wasn't ready in time.  Go find out why
	PUSHJ [KNYRGO] $ ;START NEXT RECORD.
	START-IN NORM PUSHJ[MBTBY3] $  ;GET 1ST BYTE.
	NORM JPOP[P2A] $
		;Go for another record
;	---
MBTBY2:
	START-IN D[MEM] ROT[26.] OBUS<0 C550 JUMP[MBTBY1] $
		;Check for byte ready (this is a two instruction loop)
		;Start getting byte and status again in case we have
		;  to loop
MBTBY3:	START-IN MAPF[2] D[IOD] ALU[NOTD] DEST[HOLD] C800 $
	        ;READ THE DATA AGAIN (NOW THAT IT'S STABLE !)
	MAPF[1] D[MEM] MASK[10] DEST[HOLD] C550 POPJ $
		;MAPF[1] clears byte ready
		;Extract data byte from other status information

;	---


MBTCHECK:	START-IN NORM PUSHJ[FMNBWT] $
	  ;WAIT FOR FORMATTER IDLE.
	D[MEM] ROT[32.] C550 -OBUS<0 JUMP[MBTERR] $
	  ;CHECK FOR ERROR STATUS.
	D[MEM] ROT[33.] C550 OBUS<0 POPJ $
	  ;IF ENDX OF FILE NOT SEEN, RETURN FOR MORE, ELSE DONE.
	ALU[0] DEST[Q] NORM $ ;CLEAR LIGHTS TO INDICATE NO ERRORS.
MBTDNX: START-OUT ALU[0] DEST[DEV-ADR] $
		;Setup to display code in lights
	START-OUT MAPF[2] ALU[Q] $	;LOAD LIGHTS FROM Q, CLR SW FF'S
D1:	MAPF[4] START-IN $
	   ;CHECK START AND CONT SWITCHES.  RD NEXT FILE ON CONT
	MAPF[4] D[IOD] DEST[AR] $
	D[AR]  ROT[5] MASK[2] DEST[AR]
		COND[OBUS=0] JUMP[D1] CYLEN[LONG] $
		;WAIT FOR A SWITCH.
	D[AR] MASK[1] COND[-OBUS=0] JUMP[MSTART] C550 $
	   ;  ... START MAIN MICROCODE ON START SWITCH.
	START-OUT NORM $  ;CLEAR SWITCH FF'S
	MAPF[4] JUMP[MBOOT] CYLEN[LONG] $

MBTERR:	D[CONST 0] ALU[NOTD] DEST[Q] JUMP[MBTDNX] $
;	---

	.RELOC		;RETURN TO OLD LOC. CTR.
