$title(ST8000A - STA5.M80) chip(Z80) sm si paginate pagewidth=132

	%include "sta.ver"

; 	File Name:	STA5.M80
;
;------->>> Revision History
;
;$Revision:   1.2  $
;    $Date:   14 Feb 1991  9:49:32  $
;     $Log:   D:\ST8A\STA_VCS\STA5.M8V  $
;  
;     Rev 1.2   14 Feb 1991  9:49:32
;  add new assembly control file
;  
;     Rev 1.1   08 Feb 1991  8:19:34
;  include the literal definitions in this file
;  
;     Rev 1.0   03 Feb 1991 21:54:40
;  Initial revision.
;  
;  

;*****************************************************************************
;	source file name:	STA5.M80
;	written by:		DMY
;*****************************************************************************

; 	include sta.def
;
$nosi
	%include "sta.def"


;	literal definitions
;
$nolist
;*****************************************************************************
;  		BIT TEST DEFINITIONS
;*****************************************************************************
;
ram		equ	8000h		; beginning of static ram
ramlen		equ	0800h		; 2k of ram
;ramlen		equ	01000h		; 4k of ram in the future
stacksize	equ	64		; new stack for bit test
eerom		equ	9000h		; beginning of EEprom
eeplen		equ	0800h		; 2k of EEprom


;  EEPROM addresses for test parameter storage
eep_insane  	equ	eerom+eeplen-1	; set to 5A or A5 during sanity test
eep_ins_cnt 	equ	eerom+eeplen-2	; #ms before reset in sanity test
eep_unit_sel	equ	eerom+eeplen-3 	; set if unit selected from remote
eep_t_recv  	equ	eerom+eeplen-4	; set if remote has sent a 'T'
eep_test_nbr	equ	eerom+eeplen-5	; holds # of current test in process


; detector bit settings

ms_atc		equ	0011B		; detector bits for Mark Space w/ATC
mark_space	equ	0000B		; detector bits for Mark Space w/o ATC
mark_only	equ	0001B		; detector bits for Mark Only
space_only	equ	0010B		; detector bits for Space Only


; These are loop back values 

lvl_db_0	equ	01b		; loop back selector bits for 0db
lvl_db_m20	equ	10b		; loop back selector bits for -20db
lvl_db_m45	equ	11b		; loop back selector bits for -45db


; Values for the Timer and associated tests

set_t0rd_stat	equ	11100010B	; read clock 0 status
set_t1rd_stat	equ	11100100B	; read clock 1 status
set_t2rd_stat	equ	11101000B	; read clock 2 status
stat_output_b	equ	80h		; bit from read for output level
dvsr_10000hz	equ	614		; divisor for NMI at 10000hz
dvsr_1000hz	equ	6144		; divisor for NMI at 1000hz
dvsr_100hz	equ	61440		; divisor for clk0&1 at 100hz


; The following divisors are for the NMI gate of the 8254, used for loop tests
; Input frequency is 6.144Mhz.  dvsr=freq/(baud*10).  The loop test will send
; a bit on each tenth NMI.  Receive time will vary with the receive delay.

baud_dvsr_0	equ	1800h		; 8254 divisor for 100*10 hz
baud_dvsr_1	equ	2000h		; 8254 divisor for 75*10 hz
baud_dvsr_2	equ	0800h		; 8254 divisor for 300*10 hz
baud_dvsr_3	equ	03B1h		; 8254 divisor for 650*10 hz
baud_dvsr_4	equ	0500h		; 8254 divisor for 1200*4 hz


; The following are the divisors for the Low-Pass filter clock used for loop
; tests.  Input freq = 6.144MHz. divisor=freq/(baud*96)

lpf_dvsr_0	equ	0640		; 8254 divisor for 96*100 baud
lpf_dvsr_1	equ	0853		; 8254 divisor for 96*75 baud
lpf_dvsr_2	equ	0213		; 8254 divisor for 96*300 baud
lpf_dvsr_3	equ	0000h		; uses High Speed PLL
lpf_dvsr_4 	equ	0000h		; uses High Speed PLL


; The following are the divisors for the High Speed PLL clock used for loop
; tests.  Center Freq to PLL is 11775.  dvsr=(11775+Fc)/12.5

hsf_dvsr_0	equ	044Eh		; uses LPF
hsf_dvsr_1	equ	044Eh		; uses LPF
hsf_dvsr_2	equ	044Eh		; uses LPF
hsf_dvsr_3	equ	044Eh		; dvsr for (11775+2000)/12.5
hsf_dvsr_4	equ	044Eh		; dvsr for (11775+2000)/12.5

; The following are the mark and space Q settings for the loop tests.
; High byte is mark Q, low byte is space Q.  q= (mark or space)/(1.5 * Baud)
; The Q selected is always rounded to the next highest.

q_set_0	equ	0000011100001001B	; markq = 2.1  spaceq = 23.2
q_set_1	equ	0000100100001001B	; markq = 23.2  spaceq = 23.2
q_set_2	equ	0000011000000001B	; markq = 2.3  spaceq = 4.5
q_set_3	equ	0000011100000101B	; markq = 2.1 spaceq = 2.63
q_set_4	equ	0000011100000111B	; markq = 2.1  spaceq = 2.1


; key codes for some front panel keys, all others are ignore in BIT

bit_key		equ	011h		; restart bit tests
clear_key	equ	01Ah		; restart OS
one_key		equ	001h		; entered menued mode

; values to output to 'out1' latch to control mark/space in loop-back

txdrev_mark	equ	88h
txdrev_space	equ	80h
$list

	%if	debug
	extern	rst_set
	extern	rst_show
	extern	rst_read
	extern	rst_send
	extern	rst_store
	extern	rst_setup
	extern	rst_misc
	%endif

	extern	delay_timer_cnt
	extern	delay_timer_flag
	extern	power_on_flag
	extern	remote_port_on
	extern	remote_channel


;*****************************************************************************
;			BIT TEST RAM
;*****************************************************************************
;
	defseg	ram0c,class=data,start=(ram+(ramlen/2))
	seg	ram0c

		ds	64
stack2: 	ds	1	; secondary stack because I won't know were
				; the OS's stack will reside
lp_bit_count:	ds	1	; bits left to send in this byte
lp_char_count:	ds	1	; chars left to send of 64
lp_tx_char:	ds	1	; actual character being sent
tenth_count:	ds	1	; NMI is 10*baud, transmit every 10th
tenth_read:	ds	1	; read when 10th bit count equals this value
tenth_write:	ds	1	; write time.  = 10 - tenth_read
lp_tx_bit0:	ds	1	; last bit sent
lp_tx_bit1:	ds	1	; 2nd to last bit sent, bit to read
lp_char_ptr:	ds	2	; points to next char in random 511 bit tbl
lp_read_write:	ds	1	; nmi read/write indicator (alternates)
lp_fail_flag:	ds	1	; set on first failed read
lp_done_flag:	ds	1	; set when last char is done sending
storage:	ds	50	; save 50 bytes of eeprom in ram during tests



$allpublic

;*****************************************************************************
	defseg	sta5, align=100h, class=code
	seg	sta5

$subtitle( ST-8000 Built In Test Routines )
$eject

;*****************************************************************************
;			MAIN CONTROL LOOP
;*****************************************************************************
;
;	The following is the main control loop for the current version 
;	of the BIT tests.  An input is accepted to deliver control to one
;	of three possible branches of the BIT.  There is the inline method 
;	of BIT and the menued version.  The third is the 'deadman timer'
;	subroutine of either the inline or menued versions.
;
; 	Each test is called via another routine (runtestX) that will process
;	the return status.  Numerous calls (restarts) are made to the supplied
;	Operating System.  Note that some of the calls will restore registers
;	and several will destroy them.  
;
;	Refer to the specific tests for additional comments.
;
start_bit:
	lxi	sp,stack2
	push	psw		; save selected test in A

	mvi	a,init_timer	; kick start the timers
	misc_rst	
	call	initialize2	; setup the latches and front panel outputs

	lxi	h,10		; wait 10ms before writing to EEprom again
	call	delay_hl

	pop	psw		; selected test was passed from O/S
	ana	a		; returned from sanity test
	jz	insane_2

	push	psw		; save selected test again 
				; see if this unit is selected over the 
	mvi	a,read_remote_select
	read_rst		; Remote Port
	mov	a,l
	sta	eep_unit_sel	; store 'Selected' flag
	lxi	h,10		; wait 10ms before writing to EEprom again
	call	delay_hl

	mvi	a,0
	sta	eep_t_recv 	; clear the 'T' byte. ie remote commands
				; are 'T0', 'T1' and 'T5'
	lxi	h,10		; wait 10ms before writing to EEprom again
	call	delay_hl

	pop	psw		; selected test was passed from O/S

	cpi	1		; just do regular bit tests
	jz	bit_main

	cpi	9		; do menued bit tests
	jz	bit_menu1

	RST	0		; Error...return to O/S

bit_main:
	mvi	h,00
	mvi	l,'0'		; indicates no tests passed yet
	mvi	a,show_channel_char
	show_rst

	lxi	h,bit_header
	call	outstring	; display BIT header message

	call	check_delay
	mvi	a,'1'		; test number
	mvi	c,0
	lxi	x,timertest	; 8254 timer test
	call	runtest1

	call	check_delay
	mvi	a,'2'		; test number
	mvi	c,0
	lxi	x,romtest	; rom checksum test
	call	runtest1

	call	check_delay
	mvi	a,'3'		; test number
	mvi	c,0
	lxi	x,ramtest	; ram test
	call	runtest1
main1:
	call	check_delay
	mvi	a,'4'		; test number
	mvi	c,0
	lxi	x,eromtest	; eeprom test
	call	runtest1

	call	check_delay
	mvi	a,'5'		; test number
	mvi	c,0
	lxi	x,display1	; display test
	call	runtest1

	call	check_delay
	mvi	a,'6'		; test number
	mvi	c,0		; loop test 1
	lxi	x,looptests
	call	runtest1

	call	check_delay
	mvi	a,'7'		; test number
	mvi	c,1		; loop test 2
	lxi	x,looptests
	call	runtest1

	call	check_delay
	mvi	a,'8'		; test number
	mvi	c,2		; loop test 3
	lxi	x,looptests
	call	runtest1

	call	check_delay
	mvi	a,'9'		; test number
	mvi	c,3		; loop test 4
	lxi	x,looptests
	call	runtest1

	call	check_delay
	mvi	a,'A'		; test number
	mvi	c,4		; loop test 5
	lxi	x,looptests
	call	runtest1

	call	check_delay
	mvi	a,'B'		; test number
	mvi	c,0		; allow a passed message
	lxi	x,remote	; remote port test
	call	runtest1

main2:
	call	check_delay
	mvi	a,05Ah		; inline driven sanity test
	sta	eep_insane	; set BIT flag
	lxi	h,10		; wait 10ms before writing to EEprom again
	call	delay_hl
	mvi	a,'C'		; test number
	mvi	c,0
	lxi	x,insane	; sanity timer test
	call	runtest1

main3:				; second pass of sanity test (after reset)
	jc	runtest1_3	; will come back here.  FAIL on carry!!!

	lxi	h,raok		; else output 'OK' to remote port
	call	outstring
	lxi	h,pass_msg	; display 'PASS' on baud indicators
	mvi	a,show_baud_ascii
	show_rst
	lxi	h,finalpass	; output unit passed message to remote port
	call	outstring
	call	delay_1sec
	call	delay_1sec	; allow 4 seconds for viewing
	call	delay_1sec
	call	delay_1sec
	RST	0		; return to operating system
	jmp	bit_main


;*****************************************************************************
;	MENUED VERSION of BIT
;
;	An individual test is selected via a remote port input.  The test is 
;	executed and the menu may be accessed again.  All of the inline tests
;	are included in the menu and several more.  The additional tests are
;	the keypad echo routine, help display and return to the O/S.
;

bit_menu1:
	lxi	sp,stack2	; just in case returning from a routine

	lxi	h,10		; wait 10ms before writing to EEprom again
	call	delay_hl
	mvi	a,1		; set selected flag
	sta	eep_unit_sel
	lxi	h,10		; wait 10ms before writing to EEprom again
	call	delay_hl

	lxi	h,menu_msg	; show the start
	call	outstring
bit_menu2:
	out	sanity_iow

	lxi	sp,stack2	; just in case returning from a routine
	lxi	h,prompt	; show the prompt message
	call	outstring

	call	inchar		; wait for input characters

	cpi	cr
	jz	bit_menu2

	lxi	x,timertest	; timer test
	mvi	c,0
	cpi	'1'
	jz	runtest2

	lxi	x,romtest
	mvi	c,0		; rom checksum test
	cpi	'2'
	jz	runtest2

	lxi	x,ramtest
	mvi	c,0
	cpi	'3'		; ram test
	jz	runtest2

	lxi	x,eromtest
	mvi	c,0
	cpi	'4'		; eeprom test
	jz	runtest2

	lxi	x,display1
	mvi	c,0
	cpi	'5'		; display test
	jz	runtest2

	lxi	x,looptests
	mvi	c,0
	cpi	'6'		; loop test 1
	jz	runtest2
	
	lxi	x,looptests
	mvi	c,1
	cpi	'7'		; loop test 2
	jz	runtest2

	lxi	x,looptests
	mvi	c,2
	cpi	'8'		; loop test 3
	jz	runtest2
	
	lxi	x,looptests
	mvi	c,3
	cpi	'9'		; loop test 4
	jz	runtest2
	
	lxi	x,looptests
	mvi	c,4
	cpi	'A'		; loop test 5
	jz	runtest2

	lxi	x,remote
	mvi	c,-1
	cpi	'B'		; remote port test
	jz	runtest2

	lxi	x,insane
	mvi	c,0
	cpi	'C'		; sanity timer test
	jnz	bit_menu3

	lxi	h,10		; wait 10ms before writing to EEprom again
	call	delay_hl
	mvi	a,0A5h		; menu driven sanity test
	sta	eep_insane	; set BIT flag
	lxi	h,10		; wait 10ms before writing to EEprom again
	call	delay_hl
	jmp	runtest2
bit_menu3:
	cpi	'K'		; keypad display operation
	jz	keydisplay
	
	cpi	'H'
	jz	bit_menu1

	cpi	'X'
	jnz	bit_menu2

	RST	0		; restart at 0


$subtitle( Support Routines )
$eject
;*****************************************************************************
;	Setup the hardware in the ST8000A and reconfigure the O/S.
;
initialize:
	out	sanity_iow	; clear DMT

	mvi	a,restore_config
	misc_rst

	mvi	a,init_timer	; kick start the timers
	misc_rst

	out	sanity_iow	; clear DMT
	mvi	a,init_fp
	misc_rst		; reset Front Panel and it's buffers

	out	sanity_iow	; clear DMT
	mvi	a,init_remote
	misc_rst		; reset Remote Port and it's buffers

	mvi	a,read_remote_baud
	read_rst
				; set the baud to the switch settings
	mvi	a,setup_remote_baud
	setup_rst

	out	sanity_iow
	mvi	a,init_regen
	misc_rst

	out	sanity_iow	; clear DMT
	mvi	a,init_keypad_buffer
	misc_rst
	
	mvi	a,init_remote_buffer
	misc_rst

	mvi	a,enable_remote_intr
	misc_rst

	lxi	h,power_on	; set initialized flag
	shld	power_on_flag

	lda	eep_unit_sel
	sta	remote_port_on
	sta	remote_channel	

initialize2:	; reconfigure but don't reset some hardware

	mvi	h,out0_iow
	mvi	l,-1		; clear all latches
	mvi	a,set_control_clear
	set_rst

	mvi	h,out1_iow
	mvi	l,-1
	mvi	a,set_control_clear
	set_rst

	mvi	h,out2_iow
	mvi	l,-1
	mvi	a,set_control_clear
	set_rst

	lxi	h,ctrl_chsel_b	; select demod to be displayed
	mvi	a,set_control_set
	set_rst

	mvi	l,lvl_db_m45	; set loopback mode
	mvi	a,set_loopback
	set_rst

	lxi	h,0000		; now clear level indicators
	mvi	a,set_tx_mark
	set_rst			; set mark frequency for tx 
	lxi	h,0000
	mvi	a,set_tx_space
	set_rst			; set space freq for tx

	mvi	h,led0_iow	; now turn off all of the led's
	mvi	l,0FFh
	mvi	a,show_led_off
	show_rst
	mvi	h,led1_iow
	mvi	l,0FFh
	mvi	a,show_led_off
	show_rst
				; Output 'Bit' message
	lxi	h,st8_msg
	mvi	a,show_mark_ascii
	show_rst
	lxi	h,bit_msg
	mvi	a,show_space_ascii
	show_rst
	lxi	h,clear4_msg
	mvi	a,show_baud_ascii
	show_rst
	mvi	h,00
	mvi	l,' '
	mvi	a,show_channel_char
	show_rst

	lxi	h,ctrl_nmiena_b	; leave the NMI enabled
	mvi	a,set_control_set
	set_rst	
	ei
	ret



;****************************************************************************
;	Execute Tests and Display Results for NON-Menu Version
;
runtest1:
	sta	eep_test_nbr
	lxi	h,10
	call	delay_hl
	lxi	y,runtest1_2	; normally return here after test
	mov	a,c
	ana	a		; if notified
	jp	runtest1a
				; must be running remote port display	
	lxi	y,main2		; so just return w/o indicating results
runtest1a:
	pcix			; jump to routine

runtest1_2:
	jc	runtest1_3	; if No error in test
				;	then attempt displaying 'OK'
	mov	a,c
	lxi	h,raok		; else output PASSED to remote port
	call	outstring
	ret			; and return

runtest1_3:			;  FAILURE .. flash it on remote & leds
	mvi	a,' '
	call	outchar
	mvi	a,' '
	call	outchar
	mvi	a,' '
	call	outchar

runtest1_4:			; begin ENDLESS LOOP!!!!!!!!!!!!!!!!!!!!
	lxi	h,fmsg_menu	; display 'FAIL' for a half a second
	call	outstring	; if allowed
	lxi	h,fail_msg
	mvi	a,show_baud_ascii
	show_rst		; show 'FAIL' on display
	lxi	h,700
	call	delay_hl
	lxi	h,failmsg1	; back space to begin of FAIL
	call	outstring
	lxi	h,failmsg2	; overwrite FAIL with spaces, FAIL will flash
	call	outstring
	lxi	h,failmsg1	; backspace again for next write of FAIL
	call	outstring
	lxi	h,clear4_msg
	mvi	a,show_baud_ascii
	show_rst		; show '    ' on display
		
	lda	eep_unit_sel	; read 'Selected' flag
	ana	a
	jz	runtest1_5	; only remote mode can exit a failure

	call	check_input_remote	; allow retry, exit or switch to menu
runtest1_5:
	lxi	h,100
	call	delay_hl	; wait 1/3 second
	jmp	runtest1_4	; end of ENDLESS LOOP!!!!!!!!!!!!!!!!!!


;****************************************************************************
;	Execute Tests and Display Results for MENU Version
;
runtest2:
	sta	eep_test_nbr
	lxi	h,10
	call	delay_hl
	lxi	y,runtest2_2	; return here after test
	mov	a,c
	ana	a		; if notified
	jp	runtest2_1
				; must be running remote port display	
	lxi	y,bit_menu2	; so just return w/o indicating results
runtest2_1:
	pcix			; jump to routine

runtest2_2:
	jc	runtest2_3	; if No error in test
				;	then attempt displaying 'PASS'
	lxi	h,pass_msg
	mvi	a,show_baud_ascii
	show_rst
	lxi	h,passmsg	; output 'PASS' to remote port
	call	outstring
	lxi	h,300
	call	delay_hl
	jmp	bit_menu2		; and return

runtest2_3:			;  FAILURE
	lxi	h,fail_msg
	mvi	a,show_baud_ascii
	show_rst		; show 'FAIL' on display
	lxi	h,fmsg_menu
	call	outstring	; and to remote
	lxi	h,300
	call	delay_hl
	jmp	bit_menu2


;****************************************************************************
;  Delay for One Second while Checking for Input
;
check_delay:
	mvi	b,60
check_delay1:
	push	b
	call	check_input
	lxi	h,10
	call	delay_hl
	pop	b
	djnz	check_delay1
	ret


;*****************************************************************************
;   CHECK for VALID INPUT from KEYPAD or REMOTE 
;
;   Tests for any incoming character or key. If bit is reselected we go to
;   the menued version of BIT.  Uses the OS remote port functions.

check_input:
	out	sanity_iow	; don't know how long we'll wait
	
	lda	eep_unit_sel	; read 'Selected' flag
	ana	a
	jz	check_input1

	call	check_input_remote
	ret
check_input1:
	call	check_input_keyboard
	ret



check_input_remote:
	lda	eep_t_recv
	mov	b,a		; Unit is addressed via Remote Port
	mvi	a,read_remote_buffer
	read_rst		; any character at Remote Port?
	rc			; returns CY if no character

	mov	a,l		; else character is in reg l
	cpi	'a'
	jc	check1
				; convert it to Upper Case
	sbi	20h
check1:
	mov	l,a		; save it
	call	outchar		; echo it
	mov	a,l

	mov	a,b		; if we already got a 'T'
	ana	a		;    then look for number
	jnz	check2
				; else
	mov	a,l
	cpi	'T'		; if is NOT a T command
	rnz			;   then just return until we get one
	
	sta	eep_t_recv 	; else we got a T so save it and look for more
	lxi	h,10		; wait 10ms before writing to EEprom again
	call	delay_hl
	jmp	check_input

check2:				; post 'T' check, need '0', '1' or '9'
	xra	a
	sta	eep_t_recv
	push	h
	lxi	h,10		; wait 10ms before writing to EEprom again
	call	delay_hl
	pop	h
				; must get another 'T' if char invalid
	mov	a,l
	cpi	'1'		; if 'T1'
	jnz	check3

	mvi	a,-1
	jmp	start_bit	; restart BIT tests

check3:
	cpi	'9'		; if 'T9'
	jz	bit_menu1		; enter menued version of tests
	
	cpi	'0'		; if not 'T0'
	rnz			; just return

	RST	0		; else abort to OS
	ret


	; Do Keyboard input
check_input_keyboard:		; Unit Not addressed via Remote Port
	mvi	a,read_keypad_buffer	;     Using Front Panel Input
	read_rst
	rc			; if no key is waiting
				;    then just return
	mov	a,l
	cpi	bit_key		; else if 'BIT' key is pressed
	jnz	check_input_keyboard1

	mvi	a,1
	jmp	start_bit	;    then restart bit tests

check_input_keyboard1:
	cpi	clear_key	; else if 'CLEAR' key is not pressed
	rnz			;    then ignore rest and return

	rst	0		; else go back to Operating System
	jmp	start_bit



;*****************************************************************************
;   Output a String if Unit is Addressed
;
;   <HL> = string to display
outstring:
	lda	eep_unit_sel
	ana	a		; display only if selected or in menu mode
	rz

	mvi	a,send_remote_ascii
	send_rst
	ret


;*****************************************************************************
;   Output a Char if Unit is Addressed
;
;   A = char to display
outchar:
	push	h
	mov	l,a
	lda	eep_unit_sel
	ana	a		; display only if selected or in menu mode
	jz	outchar1

	mvi	a,send_remote_char
	send_rst	
	mov	a,l
outchar1:
	pop	h
	ret


;*****************************************************************************
;  Input a Char
;
;   Waits for a character. Uses the OS remote port functions.

inchar:
	out	sanity_iow	; don't know how long we'll wait
	mvi	a,read_remote_buffer
	read_rst
	jc	inchar

	mov	a,l

	cpi	'a'
	jc	inchar1
				; convert the char to upper case
	sbi	20h
inchar1:
	push	psw
	call	outchar
	pop	psw		; return char in reg A
	ret


;  Display Hex to Remote as 2 ASCII characters
display_hex:
	push	b
	mov	b,a
	ani	0F0h		; grab upper nibble
	rrc
	rrc			; move to lower nibble
	rrc
	rrc
	call	outhex		; display as ascii
	mov	a,b
	ani	0Fh		; grab lower nibble
	call	outhex		; display as ascii
	pop	b
	ret		


outhex:				; display nibble in A as ascii
	ori	'0'		; 0-9
	cpi	'9'+1
	jc	outhex1

	adi	'A'-'9'-1	; or A-F
outhex1:
	call	outchar		; display it
	ret


;*****************************************************************************
;  1 Second Delay
;
;  Sets up the NMI via the OS and waits for it to delay.  At 1000hz = 1 second.
delay_1sec:
	push	h
	push	d
	push	b
	mvi	a,init_timer	; make sure nmi at 1000hz
	misc_rst
	lxi	h,1000		; set delay count
	mvi	a,setup_timeout
	setup_rst

delay_loop:
	out	sanity_iow
	mvi	a,read_timeout
	read_rst

	mov	a,l		; wait for NMI to delay set period
	ora	h
	jnz	delay_loop

	pop	b
	pop	d
	pop	h
	ret

;*****************************************************************************
;  Delay HL Milliseconds
; 
;  Sets up the NMI via the OS to 1000hz.  Then sets the delay count supplied 
;  in hl and waits for it's expiration.
delay_hl:
	push	h
	push	d
	push	b
	push	h
	mvi	a,init_timer	; make sure nmi at 1000hz
	misc_rst
	pop	h		; set delay count
	mvi	a,setup_timeout
	setup_rst
	jmp	delay_loop


;*****************************************************************************
;  Delay HL Periods --  Don't Initialize the Timer
; 
;  Sets the delay count supplied in hl and waits for it's expiration.  The NMI
;  time base is NOT changed for use in multi-baud loop tests.
delay_baud:
	shld	delay_timer_cnt
	mvi	a,-1
	sta	delay_timer_flag
delay_baud1:
	out	sanity_iow
	lda	delay_timer_flag
	ana	a
	jnz	delay_baud1

	ret



$subtitle( 8254 Timer Tests )
$eject
;*****************************************************************************
;				8254 TIMER TESTS
;*****************************************************************************
;
; Controls the individual tests of the 8254.  First tests the NMI, clock 2,
; with a software timing loop.  The other clocks, LPCLK and CKREF, are tested
; against the NMI clock. All gates use the same oscillator, 6.144MHz, the
; loopback tests will verify the other oscillator.
;
timertest:
	lxi	h,clear4_msg	; clear the baud segments
	mvi	a,show_baud_ascii
	show_rst
	mvi	h,00
	mvi	l,'1'		; display test #
	mvi	a,show_channel_char
	show_rst
	lxi	h,timsg
	call	outstring

	call	tim2_test	; check the NMI gate
	jc	timertest_fail	; it's used to test the other 2 timers

	call	tim1_test	; test the LPCLK timer
	jc	timertest_fail

	call	tim0_test	; test the TXCLKS timer
	jc	timertest_fail

timertest_pass:
	mvi	a,init_timer	; set up NMI for a reference
	misc_rst		; for timer 0 and timer 1
	ora	a		; clear carry
	pciy

timertest_fail:			; main loop will replace the stack	
	mvi	a,init_timer	; set up NMI for a reference
	misc_rst		; for timer 0 and timer 1
	stc
	pciy


;***************************************************************************
;      Test the NMI Clock
;  Uses a software loop to time 1/2 a period of a 1000hz NMI clock.
tim2_test:
	lxi	h,ctrl_nmiena_b		; disable NMI
	mvi	a,set_control_clear
	set_rst

	mvi	a,timer_nmi_mode
	out	timer_ctrl_io		; set mode for clock 2 to square wave
	mvi	a,low dvsr_1000hz
	out	timer_nmi_io		; load divisor for 1000hz
	mvi	a,high dvsr_1000hz
	out	timer_nmi_io

	lxi	h,ctrl_nmiena_b		; enable NMI, starts high
	mvi	a,set_control_set	; waits 1/2 a period (5ms) 
	set_rst				; and then goes low

	mvi	b,6			; failsafe counter
tim2_test1:
	mvi	a,set_t2rd_stat		; setup to read clock 2's status
	out	timer_ctrl_io
	out	sanity_iow		; got status
	dcr	b			; if output never goes high then
	jz	tim2_fail		; NMI isn't working

	in	timer_nmi_io
	ani	stat_output_b		; wait until output starts (= 1)
	jz	tim2_test1

	mvi	b,25			; perfect timing is 22 loops
tim2_test2:				; max timing is 25 (~115%)
	mvi	a,set_t2rd_stat		; setup to read clock 2's status
	out	timer_ctrl_io
	out	sanity_iow		; got status
	dcr	b			; limit time in this loop to 110%
	jz	tim2_fail

	in	timer_nmi_io
	ani	stat_output_b		; wait until output goes low (= 0)
	jnz	tim2_test2

	mov	a,b		; if loop time was < 90% of center (22)
	cpi	6		; then fail.  ie  25 - 6 = 19 
	jc	tim2_pass	; valid range is 20-25

tim2_fail:
	stc			; Yes, then fail
	ret

tim2_pass:
	ora	a		; No, return no Cy for pass
	ret



;****************************************************************************
;	Test the LPCLK Clock
; Uses the NMI to test the rate of the 2nd timer.  NMI is set to 10000hz and
; the LPCLK to 100hz.  100 NMI interrupts should occur for one cycle of LPCLK.
tim1_test:
	lxi	h,ctrl_nmiena_b		; disable NMI
	mvi	a,set_control_clear
	set_rst
					; mode is already set
	mvi	a,low dvsr_10000hz
	out	timer_nmi_io		; load divisor for 10000hz
	mvi	a,high dvsr_10000hz
	out	timer_nmi_io

	lxi	h,ctrl_nmiena_b		; enable NMI, starts high
	mvi	a,set_control_set	; waits 1/2 a period (5ms) 
	set_rst				; and then goes low
	
	mvi	a,timer_lowpass_mode
	out	timer_ctrl_io		; set mode for clock 1
	mvi	a,low dvsr_100hz
	out	timer_lowpass_io	; load divisor for 100hz
	mvi	a,high dvsr_100hz
	out	timer_lowpass_io	; output starts at 1 right away

	lxi	h,75			; allow 75% of cycle to
	mvi	a,setup_timeout		; go to 0
	setup_rst
tim1_test1:
	mvi	a,set_t1rd_stat		; setup to read clock 1's status
	out	timer_ctrl_io
	out	sanity_iow		; got status
	mvi	a,read_timeout
	read_rst			; read current time
	mov	a,h
	ora	l			; if 3/4 cycle has elapsed
	jz	tim1_fail		; then fail

	in	timer_lowpass_io
	ani	stat_output_b		; wait until output goes low (= 0)
	jnz	tim1_test1		; i mean half a cycle

	lxi	h,110			; timing is from one low going edge
	mvi	a,setup_timeout		; to the next low going edge
	setup_rst
tim1_test2:
	mvi	a,set_t1rd_stat		; setup to read clock 1's status
	out	timer_ctrl_io
	out	sanity_iow		; got status
	mvi	a,read_timeout
	read_rst			; read current time
	mov	a,h
	ora	l			; if 110% of cycle has elapsed
	jz	tim1_fail		; then fail

	in	timer_lowpass_io
	ani	stat_output_b		; wait until output goes high (= 1)
	jz	tim1_test2

tim1_test3:
	mvi	a,set_t1rd_stat		; setup to read clock 1's status
	out	timer_ctrl_io
	out	sanity_iow		; got status
	mvi	a,read_timeout
	read_rst			; read current time
	mov	a,h
	ora	l			; if 110% of cycle has elapsed
	jz	tim1_fail		; then fail

	in	timer_lowpass_io
	ani	stat_output_b		; wait until output goes low (= 0)
	jnz	tim1_test3		; i mean half a cycle

	mov	a,l		; test cycle length
	cpi	21		; allowable range is 90% to 110%
	jc	tim1_pass

tim1_fail:
	stc			; Yes, then fail
	ret

tim1_pass:
	ora	a		; No, return no Cy for pass
	ret



;****************************************************************************
;	Test the TXCLKS Clock
; Uses the NMI to test the rate of the 1ST timer.  NMI is set to 10000hz and
; the TXCLKS to 100hz.  100 NMI ints should occur for one cycle of TXCLKS.

tim0_test:
	lxi	h,ctrl_nmiena_b		; disable NMI
	mvi	a,set_control_clear
	set_rst
					; mode is already set
	mvi	a,low dvsr_10000hz
	out	timer_nmi_io		; load divisor for 10000hz
	mvi	a,high dvsr_10000hz
	out	timer_nmi_io

	lxi	h,ctrl_nmiena_b		; enable NMI, starts high
	mvi	a,set_control_set	; waits 1/2 a period (5ms) 
	set_rst				; and then goes low
	
	mvi	a,timer_ref_mode
	out	timer_ctrl_io		; set mode for clock 0
	mvi	a,low dvsr_100hz
	out	timer_ref_io		; load divisor for 100hz
	mvi	a,high dvsr_100hz
	out	timer_ref_io		; output starts at 1 right away

	lxi	h,75			; allow 75% of cycle to
	mvi	a,setup_timeout		; go to 0
	setup_rst
tim0_test1:
	mvi	a,set_t0rd_stat		; setup to read clock 0's status
	out	timer_ctrl_io
	out	sanity_iow		; got status
	mvi	a,read_timeout
	read_rst			; read current time
	mov	a,h
	ora	l			; if 3/4 cycle has elapsed
	jz	tim0_fail		; then fail

	in	timer_ref_io
	ani	stat_output_b		; wait until output goes low (= 0)
	jnz	tim0_test1		; i mean half a cycle

	lxi	h,110			; timing is from one low going edge
	mvi	a,setup_timeout		; to the next low going edge
	setup_rst
tim0_test2:
	mvi	a,set_t0rd_stat		; setup to read clock 0's status
	out	timer_ctrl_io
	out	sanity_iow		; got status
	mvi	a,read_timeout
	read_rst			; read current time
	mov	a,h
	ora	l			; if 110% of cycle has elapsed
	jz	tim0_fail		; then fail

	in	timer_ref_io
	ani	stat_output_b		; wait until output goes high (= 1)
	jz	tim0_test2

tim0_test3:
	mvi	a,set_t0rd_stat		; setup to read clock 0's status
	out	timer_ctrl_io
	out	sanity_iow		; got status
	mvi	a,read_timeout
	read_rst			; read current time
	mov	a,h
	ora	l			; if 110% of cycle has elapsed
	jz	tim0_fail		; then fail

	in	timer_ref_io
	ani	stat_output_b		; wait until output goes low (= 0)
	jnz	tim0_test3		; i mean half a cycle

	mov	a,l		; test cycle length
	cpi	21		; allowable range is 90% to 110%
	jc	tim0_pass

tim0_fail:
	stc			; Yes, then fail
	ret

tim0_pass:
	ora	a		; No, return no Cy for pass
	ret



$subtitle( ROM Test )
$eject
;*****************************************************************************
;				ROM CHECKSUM TESTS
;*****************************************************************************
;
;  Does a sum of each byte of the ROM from 0000h to 8000h.  The sum must = 0.

romtest:
	lxi	h,clear4_msg	; clear the baud segments
	mvi	a,show_baud_ascii
	show_rst
	mvi	h,00
	mvi	l,'2'		; display test #
	mvi	a,show_channel_char
	show_rst
	lxi	h,romsg
	call	outstring

	call	romtest1	; get the checksum
	jc	romtest_fail

romtest_pass:
	ora	a		; clear carry
	pciy

romtest_fail:			; main loop will replace the stack	
	stc
	pciy


;****************************************************************************
;
romtest1:
	lxi	h,0000h		; start at beginning of the rom
	lxi	d,8000h		; read all 32k bytes
	mvi	c,0		; start with checksum of zero
romtest1_1:
	out	sanity_iow
	mov	a,m		; read this location
	ora	a		; clear CY
	add	c		; add it to previous, no CY 
	mov	c,a		; save it
	inx	h		; next address
	dcx	d
	mov	a,d		; up to 8000h bytes
	ora	e
	jnz	romtest1_1

	mov	a,c		; get the checksum

	%if	debug
	call	display_hex	; checksums
	ora	a
	ret

	%else			; debug versions will have incorrect
	ana	a		; must be 00 to be good
	stc
	rnz			; on errors return CY

	cmc
	ret
	%endif


$subtitle( Ram Tests )
$eject
;*****************************************************************************
;				STATIC RAM TESTS
;*****************************************************************************
;
;  The ram tests will test the lower half of the ram, move the stack to the
;  lower half and then test the upper half of ram.  The tests are done by
;  writing a byte to each memory location.  After half the ram is written
;  it is then read and verified to be the same as written.  The ram is tested
;  in this manner with 0F0's, 0F's, AA's, 55's and 00's.  After the above
;  tests, an incrementing pattern is written to all locations besides the new
;  stack, at the end of the ram.  This pattern is verified also.

; NOTE: Bit stack must not be overwritten!!!

ramtest:
	lxi	h,ctrl_nmiena_b
	mvi	a,set_control_clear
	set_rst

	lxi	h,clear4_msg	; clear the baud segments
	mvi	a,show_baud_ascii
	show_rst
	mvi	h,00
	mvi	l,'3'		; display test # in channel
	mvi	a,show_channel_char
	show_rst

	lxi	h,ramsg
	call	outstring

	lxi	sp,ram+ramlen-1	; move stack to the end of ram
	mvi	b,0		; test first half
	call	ramtest1	; with straight values
	jc	ramtest_fail
	
	lxi	sp,ram+(ramlen/2)-1	; stack is at end of 1st half of ram
	xra	a		; turn off the display

	mvi	b,-1		; then test second half
	call	ramtest1	; with non-changing values
	jc	ramtest_fail

	lxi	sp,ram+ramlen-1	; move stack to the end of ram
	call	ramtest2	; now test with an incrementing pattern
	lxi	sp,stack2
	lxi	h,main1		; restore return address for in-line tests
	push	h
	jc	ramtest_fail

ramtest_pass:
	call	initialize
	mvi	h,00
	mvi	l,'3'		; display test # 
	mvi	a,show_channel_char
	show_rst
	ora	a		; clear carry
	pciy

ramtest_fail:			; main loop will replace the stack	
	call	initialize
	mvi	h,00
	mvi	l,'3'		; display test # in channel
	mvi	a,show_channel_char
	show_rst
	stc
	pciy


;*****************************************************************************
;	Test the currently selected memory half (in 'B' and passed to 
;	'tstram1') with several differant patterns.
;
ramtest1:
	mvi	a,0F0h
	call	tstram1		; test pattern with f0h
	rc
	mvi	a,00Fh
	call	tstram1		; test pattern with 0fh
	rc
	mvi	a,0AAh
	call	tstram1		; test pattern with 0AAh
	rc
	mvi	a,055h
	call	tstram1		; test pattern with 055h
	rc
	mvi	a,00h
	call	tstram1		; test pattern with 00h
	ret


;*****************************************************************************
;	Test the ram with an incrementing pattern, not just one byte.
;
ramtest2:
	call	tstram2		; test w/incrementing pattern
	ret


;*****************************************************************************
;	Do tests on one-half of the memory according to how 'B' is set.
;	Write the byte in 'A' to half of the memory then verify.
;

tstram1:
	push	b
	push	psw
	mov	a,b
	ana	a
	jz	tr3
				; test the upper half of memory

	pop	psw
	lxi	h,ram+(ramlen/2)	; <hl> is the source
	lxi	d,ram+(ramlen/2)+1	; <de> is the destination
	mov	m,a			; seed the first byte
	lxi	b,(ramlen/2)-1		; load the count to write
tr1:
	out	sanity_iow
	ldi			; write all but the first
	jpe	tr1		; setup for read and compare

	lxi	h,ram+(ramlen/2)
	lxi	b,ramlen/2
tr2:
	out	sanity_iow
	cci			; test each location against reg a (pattern)
	jnz	trfail		; zero if <hl> == A
	jpe	tr2		; parity is odd if checked all bytes
	jmp	trpass

tr3:				; test the lower half of memory		
	pop	psw
	lxi	h,ram		; <hl> is the source
	lxi	d,ram+1		; <de> is the destination
	mov	m,a		; seed the first byte
	lxi	b,(ramlen/2)-1	; load the count to write
tr4:
	out	sanity_iow
	ldi			; write all but the first
	jpe	tr4		; setup for read and compare

	lxi	h,ram
	lxi	b,ramlen/2
tr5:
	out	sanity_iow
	cci			; test each location against reg a (pattern)
	jnz	trfail		; zero if <hl> == A
	jpe	tr5		; parity is odd if checked all bytes
	
trpass:				; pattern checked out ok
	stc
	cmc			; clear the carry
	pop	b
	ret

trfail:				; ERROR found during read
	stc			; set carry and return
	pop	b
	ret
	
	
;*****************************************************************************
;	Test all of memory but the upper 66 bytes (for the new stack).
;	Write an incrementing odd pattern (01-ffh) to the memory and
;	verify with a read at each location.
;
tstram2:
	lxi	h,ram		; <hl> is the beginning
	mvi	b,01h		; the first byte, never 00h
	lxi	d,ramlen-stacksize	; load the count to write
tr21:
	out	sanity_iow
	mov	m,b		; write next byte to ram
	inr	b		; increment byte upward
	jnz	tr22
				; bypass 00h
	inr	b
tr22:	
	inx	h		; next memory location
	dcx	d
	mov	a,d		; until all written
	ora	e
	jnz	tr21	
				; write all but the first
				; setup for read and compare
	lxi	h,ram
	lxi	b,ramlen-stacksize-1
	mvi	a,00h
tr23:
	out	sanity_iow
	inr	a
	jnz	tr24
	
	inr	a
tr24:	
	cci			; test each location against reg a (pattern)
	jnz	tr2fail		; zero if <hl> == A
	jpe	tr23		; parity is odd if checked all bytes
	
tr2pass:			; pattern checked out ok
	stc
	cmc			; clear the carry
	ret

tr2fail:			; ERROR found during read
	stc			; set carry and return
	ret

$subtitle( EEprom Test )
$eject
;*****************************************************************************
;				EEPROM TESTS
;*****************************************************************************
;
; It takes 10ms for a location to be written, therefore, only the first 50
; bytes of the eeprom are tested.  Before beginning the first 50 bytes are 
; read and saved into the ram.  Each memory location is then tested before
; writing the next.  First a 55h is written and verified at each location then
; the saved data is written back and verified.
;
eromtest:			; now test the EEPROM

	lxi	h,clear4_msg	; clear the baud segments
	mvi	a,show_baud_ascii
	show_rst
	mvi	h,00
	mvi	l,'4'		; display test # 
	mvi	a,show_channel_char
	show_rst

	lxi	h,ramsg6	; indicate test to remote
	call	outstring
	
	lxi	h,eerom
	lxi	d,storage	; save the first fifty bytes
	lxi	b,50
	out	sanity_iow
	ldir
	out	sanity_iow
	
	lxi	h,eerom
	mvi	c,50
et1:				; write a 55h to the next location
	mvi	m,55h
	push	h
	lxi	h,10
	call	delay_hl	; wait 10ms

	pop	h	
	mov	a,m		; now read the byte written
	cpi	55h
	jnz	etfail		; woops
	
	inx	h		; next location
	dcr	c		; do 50
	jnz	et1
	
	lxi	h,eerom
	lxi	d,storage	; prepare to write the saved data back
	mvi	c,50		; to the eeprom
et3:
	ldax	d		; get the saved data
	mov	m,a		; program the eeprom
	push	h
	lxi	h,10
	call	delay_hl	; wait 10ms
	
	pop	h
	ldax	d
	mov	b,m		; read it back
	cmp	b		; is it correct??
	jnz	etfail		; woops
	
	inx	h
	inx	d
	dcr	c		; do all 50
	jnz	et3

etpass:
	ora	a		; clear carry
	pciy

etfail:
	stc			; set carry on fail
	pciy



$subtitle( Display Test )
$eject
;*****************************************************************************
;			FRONT PANEL DISPLAY EXCERCISES
;*****************************************************************************
;
;  This is not truly a test because it requires external observation.  The 
;  ST-8000A led's are all illuminated for 

display1:
	mvi	h,00
	mvi	l,'5'		; display the test number for a while
	mvi	a,show_channel_char
	show_rst
	lxi	h,350		; wait 3.5 seconds
	call	delay_hl

	mvi	h,led0_iow	; now turn on all of the led's
	mvi	l,0FFh
	mvi	a,show_led_on
	show_rst
	mvi	h,led1_iow
	mvi	l,0FFh
	mvi	a,show_led_on
	show_rst

	out	sanity_iow
	lxi	h,set_msg	; now set all seven segment led's on
	mvi	a,show_mark_string
	show_rst
	mvi	a,show_space_string
	show_rst
	mvi	a,show_baud_string
	show_rst
	mvi	h,03h
	mvi	l,0FFh
	mvi	a,show_channel_byte
	show_rst

	lxi	h,ctrl_hsena_b	; select low speed demod
	mvi	a,set_control_clear
	set_rst
	mvi	l,ms_atc	; bits for detector
	mvi	a,set_detmode
	set_rst			; use Mark/Space ATC detector

	mvi	l,lvl_db_0	; load the loopback mode
	mvi	a,set_loopback	; close loopback at this new level
	set_rst
	lxi	h,2000*8
	mvi	a,set_tx_mark
	set_rst		; set mark frequency for tx and rx
	lxi	h,2000*4
	mvi	a,set_rx_mark
	set_rst
	lxi	h,2000*8
	mvi	a,set_tx_space
	set_rst		; set space freq for tx and rx
	lxi	h,2000*4
	mvi	a,set_rx_space
	set_rst
	lxi	h,lpf_dvsr_0	; hl = lpf timer constant
	mvi	a,set_rx_lowpass
	set_rst
	mvi	l,0111B		; l = mark Q setting
	mvi	a,set_q_mark
	set_rst
	mvi	l,0111B		; l = space Q setting
	mvi	a,set_q_space
	set_rst

	lxi	h,dsmsg1
	call	outstring
				; now wait for 2.5 second so anyone
	call	delay_1sec	; may observe the segments on
	call	delay_1sec
	lxi	h,500
	call	delay_hl

	lxi	h,0000		; now clear level indicators
	mvi	a,set_tx_mark
	set_rst			; set mark frequency for tx 
	lxi	h,0000
	mvi	a,set_tx_space
	set_rst			; set space freq for tx

	mvi	h,led0_iow	; now turn off all of the led's
	mvi	l,0FFh
	mvi	a,show_led_off
	show_rst
	mvi	h,led1_iow
	mvi	l,0FFh
	mvi	a,show_led_off
	show_rst

	lxi	h,clear5_msg	; now clear the seven segment led's
	mvi	a,show_mark_ascii
	show_rst
	mvi	a,show_space_ascii
	show_rst
	mvi	a,show_baud_ascii
	show_rst
	mvi	h,00
	mvi	l,' '
	mvi	a,show_channel_char
	show_rst

	call	delay_1sec	; leave off for 1.5 seconds
	lxi	h,500
	call	delay_hl

	lxi	h,st8_msg
	mvi	a,show_mark_ascii
	show_rst
	lxi	h,bit_msg	; restore bit test indicator
	mvi	a,show_space_ascii
	show_rst

display2:
	mvi	h,00
	mvi	l,'5'
	mvi	a,show_channel_char
	show_rst

	ora	a		; clear carry
	pciy			; go back to main loop
				


$subtitle( LoopBack Tests )
$eject
;*****************************************************************************
;			LOOPBACK TESTS
;*****************************************************************************
;
;  Sends and receives 511 random data bits at one of five conditions.  All 
;  data must be read correctly else an error is reported.  Displays results
;  on the leds and to the remote port


looptests:			; generic loop tests
	push	b		; loopback test number is in B
lp1:
	mvi	h,00
	lda	eep_test_nbr	; BIT test number is put in channel display
	mov	l,a
	mvi	a,show_channel_char
	show_rst

	lxi	h,clear4_msg	; clear the baud segments
	mvi	a,show_baud_ascii
	show_rst


	mvi	a,cr		; do potential remote output
	call	outchar
	mvi	a,lf
	call	outchar
	mvi	a,' '
	call	outchar
	lda	eep_test_nbr
	call	outchar
	lxi	h,lpmsg1	; indicate loop test
	call	outstring

	pop	b		; retrieve loopback #
	push	b
	mov	a,c
	adi	'1'		; make it ascii and display 
	call	outchar
	lxi	h,lpmsg2	; output dots
	call	outstring
	pop	b
	push	b
				; 'c' must hold test #
	call	loopit		; go run the loop tests
	jc	lp4
		
lp3:				; Passed
	pop	b
	mvi	a,init_timer
	misc_rst		; restore the timer
	call	initialize2

	ora	a
	pciy
lp4:				; Failed
	pop	b
	mvi	a,init_timer
	misc_rst		; restore the timer
	call	initialize2

	stc
	pciy


;*****************************************************************************
;		Main Loop Test Control Routine
;
; Setup the desired mod/demod conditions and send 511 bits of data in loopback
; mode.  The first error received kills further testing.  Data is sent by
; disabling the transmitter (txenable) and toggling the transmit polarity in
; sequence with the random data.  The unit is set into loopback mode and data
; will flow from the transmitter back to the receiver at the loopback level.
; There is a delay period between transmission and reception.  This test first
; sets the correct tx and rx settings and then samples the average delay 
; period from tx to rx.  The delay is expected within 1/2 to 1 1/2 bit 
; periods. A half bit period is then added to this delay to acquire the mid-
; bit period.  The NMI is set to a sub-division of 10 or 4 times the transmit 
; This allows sampling of the receive data at various times.  Once the delay
; is determined the test will run as follows:
;    1- A transmit data bit is fetched and sent via 'txdnr'
;    2- There is a receive delay pause according to the determined period
;    3- The receive data is read and verified.  If in error the test FAILs.
;    4- There is a transmit delay pause equal to the rate period minus the
;       receive delay period.
; NOTE: The first bit received is erroneous (a space, actually) because of the
;       minimum delay period of 1 bit.
; NOTE: Measuring the tx to rx delay requires priming the circuitry.  This is
;       necessary when switching the receive levels quickly.  An alternating 
;       signal was used to speed the recovery time.
;
loopit:
	push	b
	lxi	h,ctrl_hsena_b	; select high or low speed demod
	mov	a,c
	cpi	3		; tests 0-2 are low speed
	jc	loopit1

	mvi	a,set_control_set
	jmp	loopit2		; tests 3 & 4 are high speed
loopit1:
	mvi	a,set_control_clear
loopit2:
	set_rst
	mvi	l,ms_atc	; bits for detector
	mvi	a,set_detmode
	set_rst			; use Mark/Space ATC detector
	pop	b

	push	b
	lxi	h,lp_tbl_0	; This table holds the setup conditions
	ora	a
	mov	a,c		; table index is in reg c
	rlc			; *2
	mov	d,a		; save *2
	rlc			; *4
	mov	e,a		; save *4
	rlc			; *8
	add	d		; *10
	add	e		; *14
	mov	e,a
	mvi	d,0
	dad	d		; calculated address of this tests 
	mov	d,m		; condition table  hl = lp_tbl_x + 0
	inx	h
	mov	e,m		; de holds mark_freq * 2
	inx	h
	xchg			; de <-> hl
	mvi	a,setup_tx_mark
	setup_rst		; set mark frequency for tx and rx
	mvi	a,setup_rx_mark
	setup_rst
	xchg			; hl = lp_tbl_x + 2
	mov	d,m
	inx	h
	mov	e,m
	inx	h		; de holds space_freq*2
	xchg			; de <-> hl
	mvi	a,setup_tx_space
	setup_rst		; set space freq for tx and rx
	mvi	a,setup_rx_space
	setup_rst
	xchg			; hl = lp_tbl_x + 4
	mov	d,m
	inx	h
	mov	e,m		; load the NMI rate
	inx	h
	push	h
	xchg			; hl = rate
	mvi	a,set_nmi_clock	; this is the transmit rate * 2
	set_rst
	pop	h		; hl = lp_tbl_x + 6
	mov	d,m
	inx	h
	mov	e,m		; load the lpf clock divisor
	inx	h
	push	h
	xchg			; hl = lpf timer constant
	mvi	a,set_rx_lowpass
	set_rst
	pop	h		; hl = lp_tbl_x + 8
	mov	d,m
	inx	h
	mov	e,m		; load the hs Fo divisor
	inx	h
	push	h
	xchg			; hl = hs divisor
	mvi	a,set_rx_hispeed
	set_rst
	pop	h		; hl = lp_tbl_x + 10
	mov	e,m
	inx	h
	push	h
	xchg			; hl = mark Q setting
	mvi	a,set_q_mark
	set_rst
	pop	h		; hl = lp_tbl_x + 11
	mov	e,m
	inx	h
	push	h
	xchg			; hl = space Q setting
	mvi	a,set_q_space
	set_rst
	pop	h		; hl = lp_tbl_x + 12
	mov	e,m		; load the loopback mode
	inx	h
	push	h
	xchg
	mvi	a,set_loopback	; close loopback at this new level
	set_rst
	pop	h

loopit3:
	mvi	a,64		; now prime the test data
	sta	lp_char_count	; 63 * 8bits + 1*7bits = 511 bits
	mvi	a,8
	sta	lp_bit_count	; 8 bits/byte
	lxi	h,ber511_txt
	mov	a,m		; transmit data source
	sta	lp_tx_char	; load the first byte
	inx	h
	shld	lp_char_ptr

	lxi	h,ctrl_rxdrev_b
	mvi	a,set_control_clear	; force normal polarity receive
	set_rst
	lxi	h,ctrl_txdena_b	; disable transmit gate so that
	mvi	a,set_control_clear	; TXD polarity will control tx bit
	set_rst
	xra	a
	sta	lp_fail_flag	; clear some flags used later
	sta	lp_done_flag
	sta	lp_tx_bit0
	sta	lp_tx_bit1

	pop	b
	mov	a,c		; retrieve the test number
	cpi	4
	jz	loopit4
				; tests 0-3 use BAUD * 10
	call	lp_fnd_dlay	; find transmit to mid-bit rx delay
	jmp	loopit5
loopit4:			; test 4 uses BAUD * 4
	call	lp5_fnd_dlay	; find transmit to mid-bit rx delay
loopit5:
	ana	a
	jnz	loopit_fail
				; start the transmit loop with the first bit
loopit6:	
	lda	lp_tx_bit0	; shift last data bit sent over 
	sta	lp_tx_bit1	; data read in 1/2 period should equal this
	lda	lp_tx_char	; get char we're sending
	rrc			; bit to send is in CY
	sta	lp_tx_char	; save char
	jc	loopit8		; send a 0 or a 1 ?
	
loopit7:			; WRITE
	xra	a		; save bit sent to compare later
	sta	lp_tx_bit0
	mvi	a,txdrev_space	; set output to a 0
	jmp	loopit9
loopit8:
	mvi	a,input_rxd_b	; save bit sent to compare later
	sta	lp_tx_bit0
	mvi	a,txdrev_mark	; set output to a 1
loopit9:
	out	out1_iow	; set the correct output
	lda	lp_bit_count
	dcr	a		; next bit
	sta	lp_bit_count
	jnz	loopit11	; do eight per byte
	
	lda	lp_char_count
	dcr	a		; next character up to 64
	jnz	loopit10
	
	mvi	a,-1
	sta	lp_done_flag
	jmp	loopit11

loopit10:			; adjust for next character
	sta	lp_char_count
	lhld	lp_char_ptr	; address next char
	mov	a,m
	sta	lp_tx_char	; read amd save it
	inx	h
	shld	lp_char_ptr	; adjust the pointer
	mvi	a,8
	sta	lp_bit_count	; send eight more bits
loopit11:

	mvi	h,0
	lda	tenth_read
	mov	l,a		; wait for center of rx bit to read
	shld	delay_timer_cnt
	mvi	a,-1
	sta	delay_timer_flag
loopit12:			; delay until read time
	out	sanity_iow
	lda	delay_timer_flag
	ana	a
	jnz	loopit12

				; READ
	in	input_ior	; rx data is 'RXDTR'
	ani	input_rxd_b	; isolate rx data bit
	mov	b,a
	lda	lp_tx_bit1
	xra	b		; rx data the same as transmitted?
	jnz	loopit_fail

	lda	lp_done_flag	; have we read all bits?
	ana	a		; transmit will set this flag
	jnz	loopit_pass	; Yes, SUCCESS

	mvi	h,0
	lda	tenth_write
	mov	l,a		; end of this transmit bit period to send
	shld	delay_timer_cnt	; another
	mvi	a,-1		; total non-transmit time is 10 NMI's
	sta	delay_timer_flag
loopit13:
	out	sanity_iow
	lda	delay_timer_flag
	ana	a
	jnz	loopit13

	jmp	loopit6		; go write (transmit)


loopit_pass:	
	stc
	cmc			; return NO CY if ok
	ret

loopit_fail:
	stc			; return CY on error
	ret



;*****************************************************************************
;	Find the Transmit to Receive Delay for LoopBack Tests # 0-4
;
lp_fnd_dlay:			; toggle output to allow AGC and ATC
	mvi	b,35		; time to adapt
dlayx1:
	push	b
	lxi	h,ctrl_txdrev_b	; change transmit data to a mark
	mvi	a,set_control_set
	set_rst

	lxi	h,10		; wait 1 transmit periods
	call	delay_baud

	lxi	h,ctrl_txdrev_b	; change transmit data to a space
	mvi	a,set_control_clear
	set_rst

	lxi	h,10		; wait 1 transmit periods
	call	delay_baud

	pop	b
	dcr	b		; keep toggling output
	jnz	dlayx1


	lxi	h,10		; wait another transmit period
	call	delay_baud

lp_fnd_dlay1:			; NOW test for the space
	in	input_ior	; rx data is 'RXDTR'
	ani	input_rxd_b	; isolate rx data bit
	jnz	lp_fnd_dlay6	; FAIL if no space
	
	xra	a
	sta	tenth_read	; count from transmit to receive
	lxi	h,20
	shld	delay_timer_cnt
	mvi	a,-1
	sta	delay_timer_flag

	mvi	a,txdrev_mark	; change transmit data to a mark
	out	out1_iow
lp_fnd_dlay2:
	lda	delay_timer_flag
	ana	a		; wait up to 2 bit periods
	jz	lp_fnd_dlay6

  	in	input_ior	; rx data is 'RXDTR'
	ani	input_rxd_b	; isolate rx data bit
	jz	lp_fnd_dlay2	; keep looking if a space

	lhld	delay_timer_cnt
	ana	a		; now adjust rx time to be usable later
	mvi	a,15		; center of bit period (range is now 10-20)
	sub	l 		; remove a whole bit because we wait one
				; whole bit period before starting to read
	jm	lp_fnd_dlay3
	jnz	lp_fnd_dlay4
lp_fnd_dlay3:			; if <= 0  just use 1
	mvi	a,1
	jmp	lp_fnd_dlay5
lp_fnd_dlay4:
	cpi	10
	jc	lp_fnd_dlay5
				; if >= 10, use 9
	mvi	a,9
lp_fnd_dlay5:
	sta	tenth_read	; range is 1-9

	ana	a
	mov	b,a
	mvi	a,10
	sub	b
	sta	tenth_write
	
	lxi	h,ctrl_txdrev_b	; change transmit data to a space
	mvi	a,set_control_clear
	set_rst

	lxi	h,20		; let the space settle 
	call	delay_baud
	xra	a
	ret

lp_fnd_dlay6:
	mvi	a,-1
	ret


;*****************************************************************************
;	Find the Transmit to Receive Delay for LoopBack Test #5
;
lp5_fnd_dlay:			; 1200 baud uses 4 * BAUD NMI clock (4800)
	mvi	b,25
dlay5x1:
	push	b

	lxi	h,ctrl_txdrev_b	; change transmit data to a mark
	mvi	a,set_control_set
	set_rst

	lxi	h,4		; wait 1 transmit periods
	call	delay_baud

	lxi	h,ctrl_txdrev_b	; change transmit data to a space
	mvi	a,set_control_clear
	set_rst

	lxi	h,4		; wait 2 transmit periods
	call	delay_baud

	pop	b
	dcr	b
	jnz	dlay5x1

	lxi	h,4		; wait 2 transmit periods
	call	delay_baud

lp5_fnd_dlay1:			; NOW wait for the space
	in	input_ior	; rx data is 'RXDTR'
	ani	input_rxd_b	; isolate rx data bit
	jnz	lp5_fnd_dlay6	; FAIL if no space 

	xra	a
	sta	tenth_read	; count from transmit to receive
	lxi	h,8
	shld	delay_timer_cnt
	mvi	a,-1
	sta	delay_timer_flag

	mvi	a,txdrev_mark	; change transmit data to a mark
	out	out1_iow
lp5_fnd_dlay2:
	lda	delay_timer_flag
	ana	a		; wait up to 2 bit periods
	jz	lp5_fnd_dlay6

  	in	input_ior	; rx data is 'RXDTR'
	ani	input_rxd_b	; isolate rx data bit
	jz	lp5_fnd_dlay2	; keep looking if a mark

	lhld	delay_timer_cnt
	ana	a		; now adjust rx time to be usable later
	mvi	a,6		; center of bit period (range is now 4-8)
	sub	l 		; remove a whole bit because we wait one
				; whole bit period before starting to read
	jm	lp5_fnd_dlay3
	jnz	lp5_fnd_dlay4
lp5_fnd_dlay3:			; if <= 0  just use 1
	mvi	a,1
	jmp	lp5_fnd_dlay5
lp5_fnd_dlay4:
	cpi	4
	jc	lp5_fnd_dlay5
				; if >= 4, use 3
	mvi	a,3
lp5_fnd_dlay5:
	sta	tenth_read	; range is 1-3
	ana	a
	mov	b,a
	mvi	a,4
	sub	b
	sta	tenth_write

	lxi	h,ctrl_txdrev_b	; change transmit data to a space
	mvi	a,set_control_clear
	set_rst

	lxi	h,6		; let the space settle 
	call	delay_baud
	xra	a
	ret

lp5_fnd_dlay6:
	mvi	a,-1
	ret


$subtitle( Remote Port Output Test )
$eject
;*****************************************************************************
;			REMOTE PORT TESTS
;*****************************************************************************
; This test will send two QBF's to the remote port.  It does not matter if
; the unit is in remote or not.

remote:				; remote test sends two QBF's 
	lxi	h,clear4_msg
	mvi	a,show_baud_ascii
	show_rst		; clear last test's message	
	mvi	h,00
	mvi	l,'B'		; and update test number
	mvi	a,show_channel_char
	show_rst
	lxi	h,remsg1	; display test name
	call	outstring

	lxi	h,qbfmsg	; send this always
	mvi	a,send_remote_ascii
	send_rst		; whether selected or not

	lxi	h,500
	call	delay_hl	; wait 1/2 sec

	lxi	h,qbfmsg	; send second QBF, always
	mvi	a,send_remote_ascii
	send_rst		; whether selected or not

	lxi	h,500
	call	delay_hl	; wait 1/2 sec
	lxi	h,remsg1
	call	outstring
	
remote1:
	ora	a		; clear carry
	pciy


$subtitle( Sanity Timer Tests )
$eject
;*****************************************************************************
; 			SANITY TIMER TESTS
;*****************************************************************************
;  Sets a flag in the OS and at the end of the EEPROM then waits for the
;  timer to elapse.   While waiting, a time count will be updated in EEPROM
;  until the DMT causes a reset.  The OS will return to the BIT because the 
;  flag is set.  On return the time period before reset is checked to
;  be within the limits of 1sec to 3sec.
;
insane:
	out	sanity_iow
	lxi	h,clear4_msg	; clear the baud segments
	mvi	a,show_baud_ascii
	show_rst
	mvi	h,00
	mvi	l,'C'		;  display this test number
	mvi	a,show_channel_char
	show_rst	
	lxi	h,inmsg1
	call	outstring

	mvi	a,set_sanity_flag
	set_rst			; set OS flag
	out	sanity_iow	; last diddle, now let it be
	mvi	c,0		; count of the # of elapsed delays
	push	b		; must wait 10ms before writes to EEPROM 
insane2:
	lxi	h,100		; 100ms
	mvi	a,setup_timeout
	setup_rst
insane3:
	mvi	a,read_timeout
	read_rst

	mov	a,l		; wait for NMI to delay 100ms
	ora	h
	jnz	insane3
				; another 100ms elapsed
	pop	b
	inr	c
	mov	a,c
	sta	eep_ins_cnt	; increment the count
	push	b
	jmp	insane2		; and start another


; This is the return trip from the Resetting of the DMT (DS1232)
insane_2:
	out	sanity_iow
	lxi	h,10		; wait 10ms before writing to EEprom again
	call	delay_hl
	lda	eep_insane	; set return address for correct
	mov	b,a
	xra	a
	sta	eep_insane	; clear DMT flag in EEprom
	lxi	y,main3		; test source
	mov	a,b
	cpi	05Ah
	jz	insane_23

	mvi	a,1		; set selected flag
	sta	eep_unit_sel	; in bit eeprom
	sta	remote_port_on	; and O/S memory
	lxi	y,runtest2_2
insane_23:
	lxi	h,10		; wait 10 ms before accessing EEProm again
	call	delay_hl
	call	initialize	; front panel was destroyed so fix it
	mvi	h,00
	mvi	l,'C'		;  display this test number
	mvi	a,show_channel_char
	show_rst	
	lxi	h,100
	call	delay_hl	; pause a little
		
	lda	eep_ins_cnt	; # of 100ms delays before reset
	
	cpi	05		; less than 1/2 second ?
	jc	insane_fail
	cpi	30
	jnc	insane_fail
	
insane_pass:
	ora	a		; clear carry
	pciy

insane_fail:
	stc			; set carry on failures
	pciy



$subtitle( Keypad Display Operation )
$eject
;*****************************************************************************
; 			KEYPAD ECHO OPERATION
;*****************************************************************************
; All keys pressed on the front panel get scan code and key top displayed.
keydisplay:
	out	sanity_iow
	lxi	h,clear4_msg	; clear the baud segments
	mvi	a,show_baud_ascii
	show_rst
	lxi	h,keymsg1
	call	outstring
keydisplay1:
	out	sanity_iow
	mvi	a,read_keypad_buffer
	read_rst
	jc	keydisplay2

	push	h
	ora	a		; clear Cy
	mvi	h,0
	mov	e,l
	mvi	d,0
	dad	d		; find offset into keytop name table
	xchg
	ora	a
	lxi	h,keytop_table
	dad	d
	mov	e,m
	inx	h
	mov	d,m		; get address of keytop name message
	xchg
	call	outstring	; display keytop name
	pop	h
	mov	a,h		; display the scan code
	call	display_hex

	mvi	a,cr
	call	outchar
	mvi	a,lf
	call	outchar
	out	sanity_iow

keydisplay2:
	mvi	a,read_remote_buffer
	read_rst
	jc	keydisplay1

	mov	a,l
	cpi	cr		;must have a carraige return
	jnz	keydisplay1

	jmp	bit_menu2
	


$subtitle( Messages, Output Strings And Data Arrays )
$eject
;*****************************************************************************
;	Text Messages for the Remote Port and LED Segments
;*****************************************************************************
;       Header for the In-line BIT tests
bit_header:
	db	'\r\n\n'
	db	' HAL ST-8000A HF MODEM \r\n'
	db	' BUILT-IN-TEST (BIT) SUMMARY \r\n'
	db	'--------------------------------------'
	db	00h

;	show a help message for the user
menu_msg:
	db	'\r\n\n'
	db	' HAL ST-8000A HF MODEM \r\n'
	db	' BUILT-IN-TEST (BIT) MENU \r\n'
	db	'-----------------------------\r\n'

mhelp:
	db	' 1 .. Timer Frequency Tests \r\n'
	db	' 2 .. EPROM Memory Test \r\n'
	db	' 3 .. RAM Memory Tests \r\n'
	db	' 4 .. EEPROM Memory Tests \r\n'
	db	' 5 .. Display Test \r\n'
	db	' 6 .. Loopback Test #1 \r\n'
	db	' 7 .. Loopback Test #2 \r\n'
	db	' 8 .. Loopback Test #3 \r\n'
	db	' 9 .. Loopback Test #4 \r\n'
	db	' A .. Loopback Test #5 \r\n'
	db	' B .. Remote Port Test \r\n'
	db	' C .. Deadman Timer Test \r\n'
	db	' K .. Keypad Echo Test \r\n'
	db	' H .. Help \r\n'
	db	' X .. Exit BIT Menu \r\n'
	db	00h

prompt:	db	'\r\n'
	db	' Select Test >> '
	db	00h

passmsg:
	db	" PASSED", 00h
failmsg:
	db	" FAILED #", 00h
fmsg_menu:
	db	" FAILED ",00H
failmsg1:
	db	"\b\b\b\b\b\b\b\b", 00h
failmsg2:
	db	"        ", 00h

finalpass:
	db	"\r\n\n ST-8000A PASSED ALL TESTS. \r\n\n"
	db	00h

;*****************************************************************************
;  Some ascii strings for the led segments, must be 00h terminated
;*****************************************************************************
;  The case makes a difference with some characters.
st8_msg:
	db	"8000A\0"
bit_msg:
	db	"-bit-\0"
clear5_msg:
	db	"     \0"
clear4_msg:
	db	"    \0"
fail_msg:
	db	"FAIL\0"
pass_msg:
	db	"PASS\0"


;*****************************************************************************
;	CLOCK Test Message
timsg:	db	'\r\n'
	db	' 1 .. Timer Frequency Test....'
	db	00h


;*****************************************************************************
;	ROM Test Message
romsg:	db	'\r\n'
	db	' 2 .. EPROM Memory Test.......'
	db	00h


;*****************************************************************************
; 	Ram Test Messages
ramsg:	db	'\r\n'
	db	' 3 .. RAM Memory Test.........'
	db	00h
raok:	db	' PASSED '
	db	00h
ramsg6:	db	'\r\n'
	db	' 4 .. EEPROM Memory Test......'
	db	00h

; This is the sequence of bytes written into ram.  ie.  All of ram is written
; with F0h and then read and verified... then with 0Fh etc.
ramary:	db	0F0h,00Fh,0AAh,055h,00h



;*****************************************************************************
;	Display Test Messages and data
dsmsg1:	db	'\r\n'
	db	' 5 .. Display Test............'
	db	00h

set_msg: db	0FFh,0FFh,0FFh,0FFh,0FFh


;*****************************************************************************
;	Remote Port Test Messages
remsg1:	db	'\r\n'
	db	' B .. Remote Port Test........'
	db	00h

qbfmsg:	db	'\r\nTHE QUICK BROWN FOX JUMPS OVER THE LAZY DOG\'S BACK'
	db	' 0123456789',00h


;*****************************************************************************
;	Deadman Timer Test Message
inmsg1:	db	'\r\n'
	db	' C .. Deadman Timer Test......'
	db	00h


;*****************************************************************************
;	Loop Test Messages and Data

lpmsg1:
	db	' .. Loopback Test #'
	db	00h

lpmsg2:	db	'........',00h

;	LoopBack Configuration Tables
;
; These are the configuration tables for each of the five loop tests.  
; I believe it's self explanatory.
lp_tbl_0:			; Loop Test 1's condition table
	db	high (300 * 2)
	db	low (300 * 2)	; Tx and Rx Mark Frequency
	db	high (3000 * 2)
	db	low (3000 * 2)	; Tx and Rx Space Frequency
	db	high baud_dvsr_0	; 2 times the transmit rate
	db	low baud_dvsr_0	; divisor for nmi gate of the 8254
	db	high lpf_dvsr_0
	db	low lpf_dvsr_0  ; divisor for low pass filter clock of 8254
	db	high hsf_dvsr_0
	db	low hsf_dvsr_0  ; divisor for HS PLL Fo 
	db	high q_set_0	; mark Q bit setting
	db	low q_set_0	; space Q bit setting
	db	lvl_db_0	; loopback and level bits 
	db	0 		; sample every third tenth after first

lp_tbl_1:			; Loop Test 2's condition table
	db	high (2000 * 2)
	db	low (2000 * 2)	; Tx and Rx Mark Frequency
	db	high (2085 * 2)
	db	low (2085 * 2)	; Tx and Rx Space Frequency
	db	high baud_dvsr_1	; 2 times the transmit rate
	db	low baud_dvsr_1	; divisor for nmi gate of the 8254
	db	high lpf_dvsr_1
	db	low lpf_dvsr_1  ; divisor for low pass filter clock of 8254
	db	high hsf_dvsr_1
	db	low hsf_dvsr_1  ; divisor for HS PLL Fo 
	db	high q_set_1	; mark Q bit setting
	db	low q_set_1	; space Q bit setting
	db	lvl_db_m20	; loopback and level bits 
	db	0		; sample every third tenth after first

lp_tbl_2:			; Loop Test 3's condition table
	db	high (1000 * 2)
	db	low (1000 * 2)	; Tx and Rx Mark Frequency
	db	high (2000 * 2)
	db	low (2000 * 2)	; Tx and Rx Space Frequency
	db	high baud_dvsr_2	; 2 times the transmit rate
	db	low baud_dvsr_2	; divisor for nmi gate of the 8254
	db	high lpf_dvsr_2
	db	low lpf_dvsr_2  ; divisor for low pass filter clock of 8254
	db	high hsf_dvsr_2
	db	low hsf_dvsr_2  ; divisor for HS PLL Fo 
	db	high q_set_2	; mark Q bit setting
	db	low q_set_2	; space Q bit setting
	db	lvl_db_m45	; loopback and level bits 
	db	0		; sample every third tenth after first

lp_tbl_3:			; Loop Test 4's condition table
	db	high (1575 * 2)
	db	low (1575 * 2)	; Tx and Rx Mark Frequency
	db	high (2425 * 2)
	db	low (2425 * 2)	; Tx and Rx Space Frequency
	db	high baud_dvsr_3	; 2 times the transmit rate
	db	low baud_dvsr_3	; divisor for nmi gate of the 8254
	db	high lpf_dvsr_3
	db	low lpf_dvsr_3  ; divisor for low pass filter clock of 8254
	db	high hsf_dvsr_3
	db	low hsf_dvsr_3  ; divisor for HS PLL Fo 
	db	high q_set_3	; mark Q bit setting
	db	low q_set_3	; space Q bit setting
	db	lvl_db_m20	; loopback and level bits 
	db	0		; sample every third tenth after first

lp_tbl_4:			; Loop Test 4's condition table
	db	high (1400 * 2)
	db	low (1400 * 2)	; Tx and Rx Mark Frequency
	db	high (2600 * 2)
	db	low (2600 * 2)	; Tx and Rx Space Frequency
   	db	high baud_dvsr_4	; 2 times the transmit rate
	db	low baud_dvsr_4	; divisor for nmi gate of the 8254
	db	high lpf_dvsr_4
	db	low lpf_dvsr_4  ; divisor for low pass filter clock of 8254
	db	high hsf_dvsr_4
	db	low hsf_dvsr_4  ; divisor for HS PLL Fo 
	db	high q_set_4	; mark Q bit setting
	db	low q_set_4	; space Q bit setting
	db	lvl_db_0	; loopback and level bits 
	db	0		; sample every third tenth after first




;*****************************************************************************
;	Keypad Test Messages and Data
;
keymsg1:
	db	'\r\n'
	db	' K .. Keypad Test:  Shows KEY NAME and SCAN CODE.\r\n'
	db	' Type <CR> to Quit. \r\n\n'
	db	' KEY      CODE\r\n'
	db	' ------   ----\r\n'
	db	00h


key0:
	db	' \'0\'       ',00h
key1:
	db	' \'1\'       ',00h
key2:
	db	' \'2\'       ',00h
key3:
	db	' \'3\'       ',00h
key4:
	db	' \'4\'       ',00h
key5:
	db	' \'5\'       ',00h
key6:
	db	' \'6\'       ',00h
key7:
	db	' \'7\'       ',00h
key8:
	db	' \'8\'       ',00h
key9:
	db	' \'9\'       ',00h
key10:
	db	' ENTER     ',00h
key11:
	db	' \'0.5\'     ',00h
key12:
	db	' M/S       ',00h
key13:
	db	' FSK       ',00h
key14:
	db	' DIV       ',00h
key15:
	db	' AMH       ',00h
key16:
	db	' CHAN      ',00h
key17:
	db	' BIT       ',00h
key18:
	db	' MARK      ',00h
key19:
	db	' MUTE      ',00h
key20:
	db	' NORM      ',00h
key21:
	db	' BAUD      ',00h
key22:
	db	' 2ND       ',00h
key23:
	db	' SPACE     ',00h
key24:
	db	' REMOTE    ',00h
key25:
	db	' SYNC      ',00h
key26:
	db	' CLEAR     ',00h

keytop_table:
	dw	key0
	dw	key1
	dw	key2
	dw	key3
	dw	key4
	dw	key5
	dw	key6
	dw	key7
	dw	key8
	dw	key9
	dw	key10
	dw	key11
	dw	key12
	dw	key13
	dw	key14
	dw	key15
	dw	key16
	dw	key17
	dw	key18
	dw	key19
	dw	key20
	dw	key21
	dw	key22
	dw	key23
	dw	key24
	dw	key25
	dw	key26
	dw	00000

;*****************************************************************************
; BERT 511 pattern.
;*****************************************************************************
;
; The following data bytes are the first 511
; bytes of the BERT 511 pseudo random bit 
; sequence.  The byte pattern begins to repeat
; at byte 512.
;
ber511_txt:
	db	010H,043H,04EH,035H,0ECH,065H,027H,00AH,0B5H,0FCH,026H,069H
	db	03FH,059H,099H,001H,063H,08AH,0A5H,0BFH,068H,05CH,0D3H,03CH
	db	0BEH,00BH,0D6H,076H,083H,0D6H,057H,005H,04AH,03DH,0DDH,081H
	db	073H,0C9H,0EBH,08AH,084H,039H,0F4H,036H,00BH,0F7H,0F0H,01FH
	db	0BCH,08FH,0CEH,004H,029H,0B7H,078H,03EH,01BH,095H,038H,0B6H
	db	03AH,032H,022H,040H,088H,021H,0A7H,01AH,0F6H,0B2H,013H,085H
	db	05AH,07EH,093H,0B4H,09FH,0ACH,0CCH,080H,031H,0C5H,0D2H,05FH
	db	034H,0AEH,069H,01EH,0DFH,005H,06BH,0BBH,041H,0EBH,0ABH,002H
	db	0A5H,09EH,0EEH,0C0H,0B9H,0E4H,075H,045H,0C2H,01CH,07AH,09BH
	db	085H,07BH,0F8H,00FH,0DEH,047H,067H,082H,094H,05BH,03CH,09FH
	db	08DH,04AH,01CH,05BH,01DH,019H,011H,020H,0C4H,090H,053H,00DH
	db	07BH,0D9H,089H,042H,02DH,0BFH,049H,0DAH,04FH,056H,066H,0C0H
	db	098H,062H,0E9H,02FH,01AH,0D7H,034H,08FH,0EFH,082H,0B5H,0DDH
	db	0A0H,0F5H,055H,081H,052H,04FH,077H,0E0H,05CH,0F2H,0BAH,022H
	db	061H,00EH,0BDH,0CDH,0C2H,03DH,0FCH,007H,0EFH,0A3H,033H,041H
	db	0CAH,02DH,09EH,0CFH,046H,025H,08EH,0ADH,08EH,08CH,008H,010H
	db	062H,0C8H,0A9H,086H,0BDH,0ECH,044H,0A1H,096H,0DFH,024H,0EDH
	db	027H,02BH,033H,060H,04CH,0B1H,0F4H,017H,08DH,06BH,09AH,0C7H
	db	077H,0C1H,0DAH,06EH,0D0H,0FAH,0AAH,040H,0A9H,0A7H,03BH,070H
	db	02EH,079H,05DH,091H,030H,087H,0DEH,066H,0E1H,01EH,0FEH,083H
	db	0F7H,0D1H,099H,020H,0E5H,016H,0CFH,067H,0A3H,012H,0C7H,056H
	db	047H,046H,004H,008H,031H,0E4H,054H,0C3H,05EH,076H,0A2H,050H
	db	0CBH,06FH,092H,0F6H,093H,095H,019H,030H,0A6H,058H,0FAH,08BH
	db	0C6H,035H,0CDH,0E3H,0BBH,060H,06DH,037H,068H,07DH,055H,0A0H
	db	0D4H,0D3H,01DH,038H,097H,0BCH,0AEH,048H,098H,043H,06FH,0B3H
	db	070H,00FH,0FFH,0C1H,0FBH,0E8H,04CH,090H,072H,08BH,0E7H,0B3H
	db	051H,089H,063H,0ABH,023H,023H,002H,084H,018H,072H,0AAH,061H
	db	02FH,03BH,051H,0A8H,0E5H,037H,049H,0FBH,0C9H,0CAH,00CH,018H
	db	053H,02CH,0FDH,045H,0E3H,09AH,0E6H,0F1H,05DH,0B0H,0B6H,01BH
	db	0B4H,0BEH,02AH,050H,0EAH,0E9H,00EH,09CH,04BH,05EH,057H,024H
	db	0CCH,0A1H,0B7H,059H,0B8H,087H,0FFH,0E0H,07DH,074H,026H,048H
	db	0B9H,0C5H,0F3H,0D9H,0A8H,0C4H,0B1H,0D5H,091H,011H,001H,042H
	db	00CH,039H,0D5H,0B0H,097H,09DH,028H,0D4H,0F2H,09BH,0A4H,0FDH
	db	064H,065H,006H,08CH,029H,096H,0FEH,0A2H,071H,04DH,0F3H,0F8H
	db	02EH,058H,0DBH,00DH,05AH,05FH,015H,028H,0F5H,074H,007H,0CEH
	db	025H,0AFH,02BH,012H,0E6H,0D0H,0DBH,02CH,0DCH,0C3H,07FH,0F0H
	db	03EH,03AH,013H,0A4H,0DCH,0E2H,0F9H,06CH,054H,0E2H,0D8H,0EAH
	db	0C8H,088H,000H,021H,086H,09CH,06AH,0D8H,0CBH,04EH,014H,06AH
	db	0F9H,04DH,0D2H,07EH,0B2H,032H,003H,0C6H,014H,04BH,07FH,0D1H
	db	0B8H,0A6H,079H,07CH,017H,0ACH,0EDH,006H,0ADH,0AFH,00AH,094H
	db	07AH,0BAH,003H,0E7H,092H,0D7H,015H,009H,073H,0E8H,06DH,016H
	db	0EEH,0E1H,03FH,078H,01FH,09DH,009H,052H,06EH,0F1H,07CH,036H
	db	02AH,071H,06CH,075H,064H,044H,080H
ber511_txt_end:
	db	0

	end
