	PAGE	60
	TITLE	'SOLT - SOL-20 DIAGNOSTIC TEST ROUTINE'
;
SOLOS	EQU	0C000H
AINP	EQU	SOLOS+22H
AOUT	EQU	SOLOS+1CH
RETRN	EQU	SOLOS+04H
;
	ORG	0E000H
;
START:	LXI	SP,STACK
	CALL	CLEAR		;CLEAR SCREEN
	LXI	D,SMSG
	CALL	PRINT		;PRINT LIST OF COMMANDS
SCN:	CALL	INN		;INPUT COMMAND CHARACTER
	CALL	DELAY		;DELAY TO LET PERSON SEE WHAT TYPED
	CALL	SCT1		;GET JUMP TABLE INDEX
	JZ	SCN1		;ILLEGAL COMMAND CHARACTER
	CALL	GO		;LOOK UP ADDRESS IN JUMP TABLE AND GO
DONE:	JMP	START
;
; IF ILLEGAL COMMAND WAS TYPED
;
SCN1:	LXI	D,MSS		;PRINT OUT LIST OF VALID COMMANDS
	LXI	H,0CF80H
	CALL	PRINT
	DCX	H
	JMP	SCN		;GO BACK FOR NEW COMMAND
;
; SEARCH TNAMES FOR INPUTTED CHARACTER
; RETURN INDEX OF MATCH IN B
; ZERO FLAG IS SET IF NO MATCH
;
SCT1:	LXI	D,TNAMES
	MVI	B,0
	MOV	C,A
SCT2:	LDAX	D		;TABLE VALUE
	ORA	A
	RZ			;END OF TABLE
	CMP	C
	JZ	SCT3
	INX	D
	INR	B
	JMP	SCT2
SCT3:	ORA	A		;SET NZ=MATCH
	RET
;
; USE INDEX (PASSED IN B) TO INDEX INTO TATAB
;
GO:	LXI	H,TATAB
	XCHG
	MVI	H,0
	MOV	L,B		;H,L = INDEX
	DAD	H		;HL=HL*2
	DAD	D		;HL=TABLE ADDRESS
	MOV	A,M
	INX	H
	MOV	H,M
	MOV	L,A		;H,L=SUBROUTINE ADDRESS
	PCHL			;GO TO IT
;
; TEST NAME TABLE
;
TNAMES	DB	'CMFVSPWRA'
	DB	0

;
; TEST ADDRESS TABLE
;
TATAB	DW	CRCTST		;C - CRC TEST
	DW	MEMTST		;M - MEMORY TEST
	DW	SSWTST		;F - SENSE SWITCH TEST
	DW	VIDTST		;V - VIDEO TEST
	DW	SERTST		;S - SERIAL TEST
	DW	PARTST		;P - PARALLEL TEST
	DW	TPWTST		;W - TAPE WRITE TEST
	DW	TPRTST		;R - TAPE READ TEST
	DW	AUTO		;A - AUTOMATIC MODE
;
; INPUT CHARACTER FROM KEYBOARD
;
INN:	MVI	A,0		;INPUT FROM KEYBOARD
	CALL	AINP
	JZ	INN
	ANI	7FH
	CPI	1BH		;ESCAPE?
	JZ	EXIT		;YES, RETURN TO SOLOS
	CPI	7FH		;DELETE?
	JZ	START		;YES, RETURN TO COMMAND INTERPRETER
	MOV	M,A		;ECHO ON SCREEN
	INX	H
	CALL	MAP		;UPSHIFT IT
	RET
;
; UPSHIFT CHARACTER (TO UPPER CASE)
;
MAP:	CPI	'a'
	RC
	CPI	'z'+1
	RNC
	SUI	'a'-'A'
	RET
;
; DELAY ROUTINE
;
DELAY:	PUSH	H
	PUSH	B
	LXI	B,2
	LXI	H,0
DELA1:	DCR	L
	JNZ	DELA1
	DCR	H
	JNZ	DELA1
	DCR	C
	JNZ	DELA1
	POP	B
	POP	H
	RET
;
; TEST FOR ESC OR DEL KEYS BEING PRESSED
;
ESCTEST:MVI	A,0		;INPUT FROM KEYBOARD
	CALL	AINP
	JZ	ESCT1
	ANI	7FH
	CPI	1BH		;ESCAPE?
	JZ	EXIT		;YES, RETURN TO SOLOS
	CPI	7FH		;DELETE KEY
	RZ			;YES - RETURN WITH ZERO FLAG SET
	CALL	MAP		;UPSHIFT
	CPI	'S'		;S?
	JNZ	ESCT1		;NO
	ORI	0FFH		;CLEAR ZERO FLAG
	STC
	RET
ESCT1:	ORI	0FFH		;CLEAR ZERO FLAG IF NO INPUT
	RET
;
; CLEAR SCREEN
;
CLEAR:	LXI	H,0CC00H
	MVI	A,0D0H
CLEA1:	MVI	M,' '
	INX	H
	CMP	H
	JNZ	CLEA1
	XRA	A
	OUT	0FEH
	LXI	H,0CC00H
	RET
;
; PRINT MESSAGE AT D,E AT POSITION H,L ON SCREEN
; \ WILL ACT AS CRLF
; STRING TO BE PRINTED ENDS WITH ZERO BYTE (HEX 00)
;
PRINT:	LDAX	D
	ORA	A
	RZ
	CPI	'\'
	JZ	PRT1
	MOV	M,A
	INX	H
	INX	D
	JMP	PRINT
;
PRT1:	MOV	A,L		;HANDLE "\"=CRLF
	ANI	0C0H		;MOVE TO BEGINNING OF LINE
	ADI	64		;NEXT LINE, THAT IS
	MOV	L,A
	MOV	A,H
	ACI	0
	MOV	H,A
	INX	D
	JMP	PRINT
;
; OUTPUT BIT MAP FOR MEMORY AND I/O TEST
; ERROR BYTE SHOULD BE PASSED IN A
; SET BITS INDICATE ERROR IN THOSE BITS
;
BOUT:	MVI	C,8
BOUT1:	RRC
	MVI	B,'X'
	JC	BOUT2
	MVI	B,'G'
BOUT2:	MOV	M,B
	INX	H
	INX	H
	DCR	C
	JNZ	BOUT1
	RET
;
EXIT:	CALL	CLEAR		;CLEAR SCREEN
	XRA	A		;STOP TAPE MOTORS
	OUT	0FAH
	JMP	RETRN		;RETURN TO SOLOS
;
; MENUS
;
MSS	DB	'Valid choices are:  C, M, F, V, S, P, W, R, or A.'
	DB	'  Try again:  '
	DB	0
;
SMSG:	DB	'               SOLT:   A Sol test diagnostic\\'
	DB	'Tests available:\'
	DB	'  C) CRC: Runs CRC test on Solos.\'
	DB	'  M) MEMORY: Tests system and video RAM.\'
	DB	'  F) SENSE SWITCHES: Tests sense switches (Port FF).\'
	DB	'  V) VIDEO: Tests character generation and windowshade.\'
	DB	'  S) SERIAL: Tests EIA and current loop I/O port F9.\'
	DB	'  P) PARALLEL: Tests parallel port FD.\'
	DB	'  W) ACI: Tests CUTS write function port FB.\'
	DB	'  R) ACI: Tests CUTS read function port FB.\'
	DB	'  A) AUTOMATIC: Runs all tests in sequence.\'
	DB	'\Type letter corresponding to test wanted: '
	DB	0
;
AUTO:	MVI	A,-1		;SET AUTO SWITCH
	STA	AUTOSW
	CALL	CRCTST
	CALL	MEMTST
	CALL	SSWTST
	CALL	VIDTST
	CALL	SERTST
	CALL	PARTST
	CALL	TPWTST
	CALL	TPRTST
	XRA	A		;RESET AUTO SWITCH
	STA	AUTOSW
	JMP	START
;
AUTOSW	DB	0
;
; CRC TEST
;
CRCTST:	CALL	CLEAR		;CLEAR SCREEN
	LXI	D,CRCMSG	;PRINT OUT START MESSAGE
	CALL	PRINT
;
CRCT0:	LXI	H,0C000H	;START OF SOLOS
	MVI	C,0		;START CLEAR
;
CRCT1:	MOV	A,C
	SUB	M
	DCR	A
	MOV	C,A
	INX	H
	MOV	A,H
	CPI	0C8H
	JNZ	CRCT1
;
; WE NOW HAVE CRC, LET'S PRINT IT OUT
;
	MOV	A,C
	RRC
	RRC
	RRC
	RRC
	CALL	ASCII
	LXI	H,0CE4CH
	MOV	M,A
	INX	H
	MOV	A,C
	CALL	ASCII
	MOV	M,A
;
	CALL	ESCTEST		;USER WANTS OUT?
	RZ			;YES
	JMP	CRCT0		;START CRC TEST OVER
;
ASCII:	ANI	0FH
	ADI	'0'
	CPI	'9'+1
	RC
	ADI	'A'-'9'-1
	RET
;
CRCMSG	DB	'                  Solos CRC test\'
	DB	'\\\CRC should be:\\'
	DB	'          2F  for Solos ROM'
	DB	27H
	DB	's.\'
	DB	'          8A  for BOOT ROM'
	DB	27H
	DB	's.\'
	DB	'\   CRC is: '
	DB	0
;
; MEMORY TEST
;
MEMTST:	CALL	CLEAR
	LXI	D,MEM1MSG	;PRINT MESSAGE
	CALL	PRINT
;
; FIRST TEST SYSTEM RAM
;
	LXI	H,SOLOS+800H	;IT MUST BE SAVED FIRST
	CALL	SAVE
	XRA	A
	STA	EBUF		;START CLEAR
MEMT1:	LXI	H,SOLOS+800H	;NOW DO THE TEST
	SHLD	BDADR
	CALL	MTEST
	LXI	H,SOLOS+0D50H	;OUTPUT RESULTS TO SCREEN
	LDA	EBUF
	CALL	BOUT
	CALL	STEST		;CHECK FOR 'S', DEL, ESC
	JZ	DONM1		;BACK TO COMMAND IF DEL
	JNC	MEMT1		;REPEAT TEST TILL 'S' KEY TYPED
;
	LXI	H,SOLOS+800H	;TEST OVER, RESTORE CONTENTS OF MEMORY
	CALL	RESTORE
;
; NOW TEST VDM RAM
;
	LXI	D,MEM2MSG	;PRINT OUT 2ND MESSAGE
	LXI	H,SOLOS+0E00H	;PUT IT HERE ON SCREEN
	CALL	PRINT
	CALL	DELAY		;GIVE USER TIME TO SEE WHAT'S HAPPENING
	CALL	DELAY
	LXI	H,SOLOS+0C00H	;SAVE CONTENTS OF SCREEN
	CALL	SAVE
	XRA	A
	STA	EBUF		;START CLEAN
;
MEMT2:	LXI	H,SOLOS+0C00H	;NOW DO THE TEST
	SHLD	BDADR
	CALL	MTEST
	CALL	ESCTEST
	RZ			;BACK TO COMMAND IF DEL
	JNC	MEMT2		;OVER AND OVER TILL 'S' TYPED
	LXI	H,SOLOS+0C00H
	CALL	RESTORE
;
	LXI	H,SOLOS+0E90H	;OUTPUT RESULTS TO SCREEN
	LDA	EBUF
	CALL	BOUT
MEMT3:	CALL	ESCTEST		;WAIT TILL USER TYPES ESC KEY
	JNZ	MEMT3
	RET
;
; THE MEMORY TEST
;
MTEST:	XRA	A
	STC
	PUSH	PSW
	PUSH	PSW
MTST1:	LHLD	BDADR		;1ST ADDRESS
;
MTST2:	POP	PSW
	MOV	M,A
	RAL
	PUSH	PSW
	INX	H
	MOV	A,H
	ANI	3
	ORA	L		;1K WORTH?
	JNZ	MTST2		;NOT YET
;
	POP	PSW
	POP	PSW
	PUSH	PSW
	PUSH	PSW
	LHLD	BDADR
MTST3:	Pop	PSW
	PUSH	PSW
	CMP	M		;CHECK IT
	CNZ	KERR		;OOPS
	POP	PSW
	RAL
	PUSH	PSW
	INX	H
	MOV	A,H
	ANI	3
	ORA	L		;1K WORTH?
	JNZ	MTST3		;NOPE
;
	POP	PSW
	POP	PSW
	RAL
	RC
	PUSH	PSW
	PUSH	PSW
	JMP	MTST1
;
KERR:	XRA	M
	MOV	B,A		;TO B REG
	LDA	EBUF		;ERROR ACCUMULATOR
	ORA	B		;NEW ERRORS
	STA	EBUF		;LOGGED NOW
	RET
;
; SAVE 1K BLOCK OF MEMORY
;
SAVE:	LXI	D,SAFE
	LXI	B,1024
SAVE1:	MOV	A,M
	STAX	D
	INX	D
	INX	H
	DCR	C
	JNZ	SAVE1
	DCR	B
	JNZ	SAVE1
	RET
;
; RESTORE 1K BLOCK OF MEMORY
;
RESTORE:LXI	D,SAFE
	LXI	B,1024
REST1:	LDAX	D
	MOV	M,A
	INX	D
	INX	H
	DCR	C
	JNZ	REST1
	DCR	B
	JNZ	REST1
	RET
;
; CHECK KEYBOARD FOR "S", DEL OR ESC
; USED ONLY FOR MEM TEST 1 SINCE RESTORES MEMORY
;
STEST:	MVI	A,0
	CALL	AINP
	JZ	STES1
	ANI	7FH
	CPI	1BH		;ESC?
	JZ	STES2		;YES
	CPI	7FH		;DEL?
	RZ			;YES
	CALL	MAP		;UPSHIFT
	CPI	'S'		;'S' KEY?
	JNZ	STES1		;NO
	ORI	0FFH		;CLEAR ZERO FLAG
	STC
	RET
;
STES1:	ORI	0FFH
	RET
;
STES2:	LXI	H,SOLOS+800H
	CALL	RESTORE
	CALL	CLEAR
	JMP	RETRN
;
; RETURN BACK TO COMMAND FROM MEM TEST 1
;
DONM1:	LXI	H,SOLOS+800H
	CALL	RESTORE
	RET
;
EBUF	DB	0
BDADR	DW	0
;
MEM1MSG:DB	'                Memory test.\'
	DB	'\\Sol system RAM (addresses C800 to CBFF) test.\'
	DB	0
;
MEM2MSG	DB	'Sol VDM RAM (addresses CC00 to CFFF) test.'
	DB	0
;
SAFE	DS	1024
;
; VIDEO TEST
;
VIDTST:	CALL	CLEAR		;CLEAR SCREEN
	LXI	D,VIDMSG	;PRINT MESSAGE
	CALL	PRINT
	CALL	DELAY
	CALL	DELAY
;
VIDT0:	LXI	H,SOLOS+0C00H
	MVI	B,0
;
VIDT1:	CALL	ESCTEST		;TEST KEYBOARD FOR INPUT
	RZ			;DEL INPUT, RETURN TO COMMAND
	JC	VIDT2		;'S' INPUT, STOP VIDEO FILL TEST
	MOV	M,B
	INX	H
	INR	B
	MOV	A,H
	CPI	0D0H
	JNZ	VIDT1		;NOT AT END OF SCREEN
	JMP	VIDT0		;END OF SCREEN, START OVER
;
VIDT2:	CALL	CLEAR
	XRA	A
	STA	SCRPORT		;RESET MY COPY OF SCROLL PORT
	LXI	D,VID2MSG	;PRINT 2ND MESSAGE
	CALL	PRINT
VIDT3:	CALL	INN		;INPUT INSTRUCTION
	DCX	H		;ERASE CHARAACTER FORCED ON SCREEN
	MVI	M,' '
	CPI	17H		;UP ARROW?
	JZ	SCRUP		;SCROLL UP
	CPI	1AH		;DOWN ARROW?
	JZ	SCRDN		;SCROLL DOWN
	CPI	01H		;LEFT ARROW
	JZ	WINUP		;WINDOWSHADE UP
	CPI	13H		;RIGHT ARROW
	JZ	WINDN		;WINDOWSHADE DOWN
	JMP	VIDT3		;MEANINGLESS INPUT, TRY AGAIN
;
SCRUP:	LDA	SCRPORT
	RRC
	RRC
	RRC
	RRC
	ADI	10H
	RLC
	RLC
	RLC
	RLC
	STA	SCRPORT
OUT	0FEH
	JMP	VIDT3
;
SCRDN:	LDA	SCRPORT
	RRC
	RRC
	RRC
	RRC
	SUI	10H
	RLC
	RLC
	RLC
	RLC
	STA	SCRPORT
	OUT	0FEH
	JMP	VIDT3
;
WINUP:	LDA	SCRPORT
	SUI	10H
	STA	SCRPORT
	OUT	0FEH
	JMP	VIDT3
;
WINDN:	LDA	SCRPORT
	ADI	10H
	STA	SCRPORT
	OUT	0FEH
	JMP	VIDT3
;
SCRPORT	DB	0
;
VIDMSG	DB	'                   Video test.\'
	DB	0
;
VID2MSG	DB	' 1            Scroll and windowshade test.\'
	DB	' 2\ 3\ 4\ 5    Type up arrow to scroll up,\'
	DB	' 6\ 7         down arrow to scroll down,\'
	DB	' 8\ 9         left arrow to move windowshade up,\'
	DB	'10\11    and  right arrow to move windowshade down.\'
	DB	'12\13\14\15\16'
	DB	0
;
; SERTST - SERIAL PORT TEST
;
SERTST:	CALL	CLEAR		;CLEAR SCREEN
	LXI	D,SERMSG	;PRINT MESSAGE
	CALL	PRINT
	XRA	A
	STA	SERRLOG		;CLEAR ERROR LOG
	LXI	H,SOLOS+0F00H
	SHLD	SCRPTR		;SCREEN POINTER
	LXI	H,SOLOS+0E13H
	CALL	BOUT		;OUTPUT ERROR LOG
	IN	0F9H		;CLEAR STATUS BITS
	MVI	B,0
;
SERT1:	CALL	SSTATS		;DISPLAY STATUS BITS
	MVI	A,10H		;SERIAL REQUEST TO SEND (RTS)
	OUT	0F8H
;
	LXI	H,0400H		;RESET WAIT COUNT
	SHLD	SWAIT
SERT4:	CALL	ESCTEST	
	RZ
	CALL	SSTATS		;DISPLAY STATUS BITS
	IN	0F8H
	ANI	80H
	JNZ	SERT5
	LHLD	SWAIT
	DCX	H
SHLD	SWAIT
	MOV	A,H
	ORA	L
	JNZ	SERT4		;WAITED FOR TBE A LONG TIME?
	LXI	D,TBEMSG	;YES - TELL THEM WE'RE WAITING FOR TBE
	CALL	WAITMSG
	JMP	SERT4
;
SERT5:	LXI	D,NOMSG		;CLEAR WAIT MESSAGE
	CALL	WAITMSG
	MOV	A,B
	OUT	0F9H		;SEND OUT CHARACTER
	LXI	H,0400H		;RESET WAIT COUNT
	SHLD	SWAIT
;
SERT3:	CALL	ESCTEST
	RZ
	CALL	SSTATS		;DISPLAY STATUS BITS
	IN	0F8H
	ANI	40H
	JNZ	SERT6
	LHLD	SWAIT
	DCX	H
	SHLD	SWAIT
	MOV	A,H
	ORA	L
	JNZ	SERT3		;WAITED FOR SDR A LONG TIME?
	LXI	D,SDRMSG	;YES - TELL THEM WE'RE WAITING FOR SDR
	CALL	WAITMSG
	JMP	SERT3
;
SERT6:	LXI	D,NOMSG		;CLEAR WAIT MESSAGE
	CALL	WAITMSG
	IN	0F9H		;BRING IT BACK IN
	CMP	B		;COMPARE IT WITH WHAT WAS SENT OUT
	CNZ	SERR
	LHLD	SCRPTR
	MOV	M,A		;MOVE TO SCREEN
	INR	L
	SHLD	SCRPTR
	LXI	H,SOLOS+0E0AH
	MOV	M,A		;MOVE TO SECOND POSITION ON SCREEN
	INR	B
	CALL	ESCTEST
	RZ
	JMP	SERT1
;
SERR:	PUSH	PSW
	XRA	B		;GET BAD BITS
	MOV	C,A
	LDA	SERRLOG
	ORA	C
	STA	SERRLOG		;UPDATE LOG OF ERRORS
	PUSH	H
	PUSH	B
	LXI	H,SOLOS+0E13H
	CALL	BOUT		;OUTPUT ERRORS TO SCREEN
	POP	B
	POP	H
	POP	PSW
	RET
;
WAITMSG:PUSH	H
	LXI	H,SOLOS+0E93H
	CALL	PRINT
	POP	H
	RET
;
;OUTPUT STATUS BITS ON SCREEN
;
SSTATS:	IN	0F8H		;INPUT FROM STATUS PORT
	ANI	20H		;GET SCTS (SERIAL CLEAR TO SEND)
	MOV	C,A
	LDA	SOLDSTAT	;GET PREV. STATUS
	CMP	C		;ANY CHANGE?
	RZ			;NO
	MOV	A,C
	STA	SOLDSTAT
	RLC
	RLC
	RLC
	ADI	'0'
	STA	SOLOS+0E32H	;PUT ON SCREEN
	RET
;
SERRLOG	DB	0		;LOG OF ERRORS
SCRPTR	DW	SOLOS+0F00H	;POINTER TO WHERE TO PUT NEXT BYTE ON SCREEN
SWAIT	DW	0		;COUNTER OF WAITS (MSG WHEN =0)
SOLDSTAT	DW	0	;OLD STATUS STORAGE
;
SERMSG	DB	'                   Serial port test.\'
	DB	'\\Insert proper connector in serial port.\'
	DB	'\\\'
	DB	'\                                           SCTS:  0'
	DB	0
;
TBEMSG	DB	'Waiting for TBE.'
	DB	0
;
SDRMSG	DB	'Waiting for SDR.'
	DB	0
;
NOMSG	DB	'                '
	DB	0

;
; PARALLEL PORT TEST
;
PARTST:	CALL	CLEAR		;CLEAR SCREEN
	LXI	D,PARMSG	;PRINT MESSAGE
	CALL	PRINT
	XRA	A
	STA	PERRLOG		;CLEAR PARALLEL ERROR LOG
	LXI	H,SOLOS+0F00H
	SHLD	SCRPTR		;SET SCREEN POINTER
	LXI	H,SOLOS+0E13H
	CALL	BOUT		;OUTPUT ERROR LOG
	IN	0FDH		;CLEAR STATUS BITS
	MVI	B,0
;
PERT1:	CALL	PSTATS		;DISPLAY STATUS BITS
	MVI	A,40H		;PARALLEL INPUT ENABLE (PIE)
	OUT	0FAH
;
	MOV	A,B
	OUT	0FDH		;SEND OUT CHAR
;
;	CALL	DELAY
	IN	0FDH		;BRING IT BACK IN
	CMP	B		;COMPARE TO WHAT WAS SENT
;
;	CNZ	PERR
;
	LHLD	SCRPTR
	MOV	M,A		;MOVE TO SCREEN
	INR	L
	SHLD	SCRPTR
	LXI	H,SOLOS+0E0AH
	MOV	M,A		;MOVE TO 2ND POSITION ON SCREEN
	INR	B
	CALL	ESCTEST
	RZ
	JMP	PERT1
;
PERR	PUSH	PSW
	XRA	B		;GET BAD BITS
	MOV	C,A
;	LDA	PERRLOG
;	ORA	C
;	STA	PERRLOG
	PUSH	H
	PUSH	B
	LXI	H,SOLOS+0E13H
	CALL	BOUT		;OUTPUT NEW ERRORS TO SCREEN
	POP	B
	POP	H
	POP	PSW
	RET
;
; OUTPUT STATUS BITS TO SCREEN
;
PSTATS:	IN	0FAH		;INPUT FROM STATUS PORT
	ANI	06H		;MASK PXER AND PDR
	MOV	C,A
	LDA	POLDSTAT
	CMP	C		;ANY CHANGE?
	RZ			;NO
	MOV	A,C
	STA	POLDSTAT
	ANI	04H		;GET PADR
	RRC
	RRC
	ADI	'0'
	STA	SOLOS+0E32H	;PUT ON SCREEN
	MOV	A,C
	ANI	02H		;GET PDR
	RRC
	ADI	'0'		;CONVERT TO ASCII
	STA	0CE72H		;PUT ON SCREEN
	RET
;
PERRLOG	DB	0
POLDSTAT	DW	0		;OLD STATUS STORAGE
;
PARMSG	DB	'                  Parallel port test.\'
	DB	'\\Insert proper connector in parallel port.\\'
	DB	'     (Note: This test only valid for Rev. E\'
	DB	'            or updated Rev. D Sol'
	DB	27H,'s.)\\'
	DB	'                                           PXDR:  0\'
	DB	'                                           PDR:   0'
	DB	0
;
; ACI TAPE WRITE TEST
;
TPWTST:	CALL	CLEAR		;CLEAR SCREEN
	LXI	D,TPWMSG
	CALL	PRINT
	CALL	GETUNIT		;GET TAPE UNIT
	JZ	WEXIT
	CALL	GETCHR		;GET CHAR TO BE WRITTEN
	JZ	WEXIT
	LDA	SPEED
	OUT	0FAH		;START MOTOR
;
	MVI	C,128		;WRITE OUT NULLS
	XRA	A
TPWT0:	OUT	0FBH
	DCR	C
	JNZ	TPWT0
	MVI	A,1		;FOLLOWED BY A ONE
	OUT	0FBH
;
TPWT1:	LXI	H,400H		;RESET WAIT COUNT
	SHLD	WWAIT
TPWT4:	CALL	ESCTEST
	JZ	WEXIT
	IN	0FAH
	ANI	80H		;CHECK FOR TTBE
	JNZ	TPWT5		;WAS EMPTY
	LHLD	WWAIT
	DCX	H
	SHLD	WWAIT
	MOV	A,H
	ORA	L
	JNZ	TPWT4		;WAITED FOR A LONG TIME?
	LXI	D,TTBEMSG	;YES-TELL THEM WE'RE WAITING FOR TTBE
	CALL	WAITMSG
	JMP	TPWT4
;
TPWT5:	LXI	D,NOMSG		;CLEAR WAIT MESSAGE
	CALL	WAITMSG
	LDA	CHAR
	OUT	0FBH		;SEND OUT CHAR
;
	LXI	H,SOLOS+0E90H
	MOV	M,A		;ALSO DISPLAY ON SCREEN
	LXI	H,CHRADV	;WRITING OUT SINGLE CHAR OR ALL CHARS?
	ADD	M		;IF SINGLE CHAR IS 0, ALL CHARS IS 1
	STA	CHAR		;RESAVE CHAR (EITHER SAME OR INCREMENTED)
	CALL	ESCTEST		;DOES USER WANT OUT?
	JNZ	TPWT1		;NOPE
;
WEXIT:	XRA	A		;YES, BUT 1ST STOP TAPE MOTOR
	OUT	0FAH
	RET
;
; GET CHAR TO BE WRITTEN FROM USER
;
GETCHR:	LXI	D,CHRMSG
	LXI	H,SOLOS+0E00H
	CALL	PRINT		;ASK FOR CHAR
	XRA	A
	STA	CHRADV		;ASSUME NOT AUTO INCREMENT
	CALL	GETNYB		;GET NIBBLE FROM USER
	RZ
	JC	GETC1		;USER HIT CR RIGHT AWAY, WANTS AUTO INCREMENT
	RLC
	RLC
	RLC	
	RLC
	STA	CHAR
	CALL	GETNYB
	RZ			;DELETE WAS TYPED
	JC	GETCHR		;CR NOT VALID AS 2ND NIBBLE
	MOV	C,A
	LDA	CHAR
	ADD	C
	STA	CHAR
	INR	C
	RET
;
GETC1:	XRA	A		;AUTO INCREMENT MODE
	STA	CHAR
	MVI	A,1
	STA	CHRADV
	ORA	A
	RET
;
; GET NIBBLE FROM KEYBOARD & CONVERT TO BINARY
;
GETNYB:	DCX	H
	MVI	M,' '		;CLEAR PREV. ANSWER
	CALL	INN
	RZ			;USER WANTS OUT
	CALL	DELAY
	CALL	MAP		;UPPER CASE
	CPI	0DH		;C/R?
	JZ	GETN2		;YES
	SUI	'0'		;CONVERTING TO BINARY
	JC	GETNYB		;BAD ANSWER
	CPI	9+1
	JNC	GETN1
	INX	H
	ORA	A
	MVI	B,0
	INR	B		;ZAP ZERO FLAG
	RET
;
GETN1:	SUI	'A'-'0'
	JC	GETNYB		;ONLY HEX DIGITS ALLOWED
	CPI	'F'-'A'+1
	JNC	GETNYB		;GREATER THAN "F"
	ADI	10		;MAKE IN RANGE 10-15 AND ZAP ZERO & CARRY FLAG
	INX	H
	RET
;
GETN2:	XRA	A
	INR	A
	STC
	RET
;
WWAIT	DW	0		;TIMER COUNTER (WAIT MSG WHEN ZERO)
CHAR	DB	0		;CHAR TO WRITE TO TAPE
CHRADV	DB	0		;FLAG..SHOULD CHAR BE INCR AFTER EACH WRITE OR NOT?
;
TPWMSG	DB	'                 ACI  tape write test.\'
	DB	'\\Insert tape into recorder and press record button.\\'
	DB	0
;
CHRMSG	DB	'Type hex of character to write '
	DB	'(CR for auto-increment mode):  '
	DB	0
;
TTBEMSG	DB	'Waiting for TTBE.'
	DB	0
;
; GET TAPE UNIT FROM USER
;
GETUNIT:LXI	D,UNITMSG	;ASK FOR UNIT NUMBER
	CALL	PRINT
GETU1:	DCX	H
	MVI	M,' '		;BLANK OLD ANSWER
	CALL	INN		;GET ANSWER
	RZ
	CALL	DELAY		;DELAY A BIT
	SUI	'1'
	JC	GETU1		;TOO LOW
	CPI	2
	JNC	GETU1		;TOO HIGH
	INR	A
	CMA
	ANI	3
	RRC
	RRC
	STA	SPEED
;
	LXI	D,SPEDMSG
	CALL PRINT		;ASK FOR SPEED
GETU4:	DCX	H
	MVI	M,' '		;BLANK OUT OLD ANSWER, IF ANY
	CALL	INN		;GET ANSWER
	RZ
	CALL	DELAY
	CALL	MAP
	CPI	'H'
	JNZ	GETU2
	XRA	A		;HIGH SPEED WANTED SO BIT 5=0
	JMP	GETU3
;
GETU2:	CPI	'L'
	JNZ	GETU4		;BAD ANSWER
	MVI	A,20H		;LOW SPEED WANTED, BIT 5=1
GETU3:	MOV	B,A
	LDA	SPEED
	ORA	B
	STA	SPEED
	INR	B		;CLEAR ZERO FLAG
	RET
;
SPEED	DB	0		;TAPE UNIT & SPEED
;
UNITMSG	DB	'Enter tape unit number (1 or 2):  '
	DB	0
;
SPEDMSG	DB	'\Enter H for high speed or L for low speed:  '
	DB	0
;
; ACI TAPE READ TEST
;
TPRTST:	CALL	CLEAR		;CLEAR SCREEN
	LXI	D,TPRMSG
	CALL	PRINT
	CALL	GETUNIT
	JZ	REXIT
	LXI	H,SOLOS+0F00H
	SHLD	SCRPTR
	IN	0FBH		;CLEAR STATUS BITS
	LDA	SPEED
	OUT	0FAH		;START MOTOR
;
TPRT1:	LXI	H,0400H		;RESET WAIT COUNT
	SHLD	RWAIT
;
TPRT3:	CALL	ESCTEST
	JZ	REXIT
	IN	0FAH
	ANI	40H		;TAPE DATA READY
	JNZ	TPRT6		;DATA READY
LHLD	RWAIT
	DCX	H
	SHLD	RWAIT
	MOV	A,H
	ORA	L
	JNZ	TPRT3		;WAITED FOR A LONG TIME?
	LXI	D,TDRMSG
	CALL	WAITMSG
	JMP	TPRT3
;
TPRT6:	LXI	D,NOMSG
	CALL	WAITMSG
	IN	0FBH		;READ CHAR
	LHLD	SCRPTR
	MOV	M,A		;MOVE TO SCREEN
	INR	L
	SHLD	SCRPTR
	LXI	H,SOLOS+0E90H
	MOV	M,A		;MOVE IT TO 2ND POSITION ON SCREEN
	CALL	ESCTEST
	JNZ	TPRT1
;
REXIT:	XRA	A
	OUT	0FAH		;STOP MOTORS
	RET
;
RWAIT	DW	0
;
TPRMSG	DB	'                  ACI  tape read test.\'
	DB	'\\Insert tape in recorder, rewind it and play it.\'
	DB	0
;
TDRMSG	DB	'Waiting for TDR.'
	DB	0
;
; SENSE SWITCH TEST ROUTINE
;
SSWTST	CALL	CLEAR
	LXI	D,SSWMSG
	CALL	PRINT
	IN	0FFH
;
SENS1:	LXI	H,SOLOS+0DD0H
	MVI	C,8
SENS2:	RRC
	MVI	B,'1'
	JC	SENS3
	MVI	B,'0'
SENS3:	MOV	M,B
	INX	H
	INX	H
	INX	H
	INX	H
	DCR	C
	JNZ	SENS2
	MOV	B,A
SENS4:	CALL	ESCTEST
	RZ
	IN	0FFH
	CMP	B		;HAVE THEY CHANGED?
	JZ	SENS4		;NO
	JMP	SENS1		;YES, OUTPUT NEW VALUE
;
SSWMSG	DB	'         Sense switch test.\\'
	DB	'Set sense switches and observe display.\\\'
	DB	'                1   2   3   4   5   6   7   8'
	DB	0
;
	DS	50
STACK	DS	0
;
	END
