/*
 * romdiag.s -- AIS/3200 Diagnostic Monitor functions
 * copyright(c) American Information Systems Corporation
 *  Daniel Steinberg
 *  December, 1984
 */
#include "3200config.h"

	.globl	ram_DIAG


	/* ram_DIAG */
	/* RAM Diagnostics */
	/* r0 - start address */
	/* r1 - size rounded down to 32.-byte boundary */
	/* r2 - test code */

	/* Tests:
	 *	1 - Data Pattern
	 *	2 - Marching Data Pattern
	 *	4 - Byte Alignment
	 *	8 - Uniqueness
	 *     10 - Marching Uniqueness
	 *     20 - Refresh
	 *     40 - Extended Refresh
	 *     80 - Host-Bus diagnostic
	 *    100 - Execute in Ram and Copy
	 *
	 * <ESC> to quit diagnostic
	 */
ram_DIAG:
	cmpb	r2,$0xff	/* validate test code */
	ble	chkcod0
tstall:
	movb	$0x7f,r2	/* perform all diagnostics */
	br	chkaddr
chkcod0:
	cmpqb	$0,r2
	beq	tstall
chkaddr:
	cmpqd	$0,r1
	bge	done_DIAG
	lprd	fp,r2		/* save test code */

	/* enable RAM */
	movb	$ROM_MAP,@(UART_MAPENABLE + U_SETOUT)
	bispsrw	$PSR_S		/* set user stack pointer */

	addr    0x001f(r1),r1	/* round up to 32-byte boundary */
	bicd	$0x001f,r1
	lprd	sp,r1		/* save count */
	movd	r0,r3		/* save start address */
/*  */
ram_1:
	sprd	fp,r0		/* get test code */
	movd	r0,r1
	ashd	$-1,r1		/* shift out low bit */
	lprd	fp,r1		/* save test code */
	tbitb	$0,r0		/* was bit set? */
	bfc	ram_2		/* nope */

	addr	_ramtst1msg,r6	/* print DATA PATTERN TEST start */
	addr	ram1_start,r7
	jump	printmsg
ram1_start:
				/* Copy all ones */
	addr	ONES,r1		/* set pattern address */
	addr	ram1_a0,r5	/* set return address */
	br	quadfill
ram1_a0:
				/* Copy all zeros */
	addr	ZEROES,r1	/* set pattern address */
	addr	ram1_a1,r5	/* set return address */
	br	quadfill
ram1_a1:
	addr	ZEROES,r1	/* read back */
	addr	ram1_a2,r5
	br	quadcompare
ram1_a2:

				/* Copy all ones */
	addr	ONES,r1		/* set pattern address */
	addr	ram1_b1,r5	/* set return address */
	br	quadfill
ram1_b1:
	addr	ONES,r1		/* read back */
	addr	ram1_b2,r5
	br	quadcompare
ram1_b2:

				/* Copy all fives */
	addr	FIVES,r1	/* set pattern address */
	addr	ram1_c1,r5	/* set return address */
	br	quadfill
ram1_c1:
	addr	FIVES,r1	/* read back */
	addr	ram1_c2,r5
	br	quadcompare
ram1_c2:

				/* Copy all 03's */
	addr	OTHREES,r1	/* set pattern address */
	addr	ram1_d1,r5	/* set return address */
	br	quadfill
ram1_d1:
	addr	OTHREES,r1	/* read back */
	addr	ram1_d2,r5
	br	quadcompare
ram1_d2:

				/* Copy all C0's */
	addr	CZEROES,r1	/* set pattern address */
	addr	ram1_e1,r5	/* set return address */
	br	quadfill
ram1_e1:
	addr	CZEROES,r1	/* read back */
	addr	ram1_e2,r5
	br	quadcompare
ram1_e2:

				/* Copy all 01's */
	addr	OONES,r1	/* set pattern address */
	addr	ram1_f1,r5	/* set return address */
	br	quadfill
ram1_f1:
	addr	OONES,r1	/* read back */
	addr	ram1_f2,r5
	br	quadcompare
ram1_f2:

				/* Copy all E0's */
	addr	EZEROES,r1	/* set pattern address */
	addr	ram1_g1,r5	/* set return address */
	br	quadfill
ram1_g1:
	addr	EZEROES,r1	/* read back */
	addr	ram1_g2,r5
	br	quadcompare
ram1_g2:

				/* Copy all AA's */
	addr	AAS,r1		/* set pattern address */
	addr	ram1_h1,r5	/* set return address */
	br	quadfill
ram1_h1:
	addr	AAS,r1		/* read back */
	addr	ram1_h2,r5
	br	quadcompare
ram1_h2:
				/* Marching ones */
	movqd	$1,r1
ram1_i0:
	addr	ram1_i1,r5
	br	squadfill
ram1_i1:
	addr	ram1_i2,r5
	br	squadcompare
ram1_i2:
	rotd	$1,r1
	cmpqd	$1,r1		/* back to starting point? */
	bne	ram1_i0		/* nope...continue */

				/* Marching zeros */
	movqd	$-2,r1
ram1_j0:
	addr	ram1_j1,r5
	br	squadfill
ram1_j1:
	addr	ram1_j2,r5
	br	squadcompare
ram1_j2:
	rotd	$1,r1
	cmpqd	$-2,r1		/* back to starting point? */
	bne	ram1_j0		/* nope...continue */
/*  */
ram_2:
	sprd	fp,r0		/* get test code */
	movd	r0,r1
	ashd	$-1,r1		/* shift out low bit */
	lprd	fp,r1		/* save test code */
	tbitb	$0,r0		/* was bit set? */
	bfc	ram_3		/* nope */

	addr	_ramtst2msg,r6	/* print MARCHING PATTERN TEST start */
	addr	ram2_start,r7
	jump	printmsg
ram2_start:
				/* Copy all zeros */
	addr	ZEROES,r1	/* set pattern address */
	addr	ram2_a0a,r5	/* set return address */
	br	quadfill
ram2_a0a:
	addr	_march1msg,r6	/* Marching ones */
	addr	ram2_a0b,r7
	jump	printmsg
ram2_a0b:
	movd	r3,r4		/* [start address] */
	addr	ram2_a0c,r7
	br	prquad
ram2_a0c:
	addr	_ramcmp2msg,r6	/* - */
	addr	ram2_a0d,r7
	jump	printmsg
ram2_a0d:
	sprd	sp,r4
	addd	r3,r4
	addr	ram2_a1,r7
	br	prquad
ram2_a1:
	movd	r3,r2		/* copy test start address */
	sprd	sp,r0		/* get count */
	movqd	$1,r1
ram2_a2:
	movd	r1,0(r2)
	cmpd	r1,0(r2)
	bne	ram2_aerr
	movqd	$0,0(r2)	/* rezero location */
	cmpqd	$0,0(r2)
	bne	ram2_aerr
	rotd	$1,r1
	cmpqd	$1,r1		/* done yet? */
	bne	ram2_a2		/* nope */
ram2_a3:
	addqd	$4,r2		/* yes...increment address */
	addqd	$-4,r0		/* decrement count */
	cmpqd	$0,r0
	blt	ram2_a2
	addr	ram2_b0,r7
	jump	chkesc

ram2_aerr:
	movqd	$1,r1		/* reset marcher */
	addr	_cmpfailmsg,r6	/* ** */
	addr	ram2_aerr1,r7
	jump	printmsg
ram2_aerr1:
	movd	r2,r4		/* [error address] */
	addr	ram2_aerr2,r7
	br	prquad
ram2_aerr2:
	addr	ram2_a3,r7	/* continue address */
	jump	chkesc


ram2_b0:			/* Copy all ones */
	addr	ONES,r1		/* set pattern address */
	addr	ram2_b0a,r5	/* set return address */
	br	quadfill
ram2_b0a:
	addr	_march0msg,r6	/* Marching zeros */
	addr	ram2_b0b,r7
	jump	printmsg
ram2_b0b:
	movd	r3,r4		/* [start address] */
	addr	ram2_b0c,r7
	br	prquad
ram2_b0c:
	addr	_ramcmp2msg,r6	/* - */
	addr	ram2_b0d,r7
	jump	printmsg
ram2_b0d:
	sprd	sp,r4
	addd	r3,r4
	addr	ram2_b1,r7
	br	prquad
ram2_b1:
	movd	r3,r2		/* copy test start address */
	sprd	sp,r0		/* get count */
	movqd	$-2,r1
ram2_b2:
	movd	r1,0(r2)
	cmpd	r1,0(r2)
	bne	ram2_berr
	movqd	$-1,0(r2)	/* reset location */
	cmpqd	$-1,0(r2)
	bne	ram2_berr
	rotd	$1,r1
	cmpqd	$-2,r1		/* done yet? */
	bne	ram2_b2		/* nope */
ram2_b3:
	addqd	$4,r2		/* yes...increment address */
	addqd	$-4,r0		/* decrement count */
	cmpqd	$0,r0
	blt	ram2_b2
	addr	ram2_end,r7
	jump	chkesc

ram2_berr:
	movqd	$-2,r1		/* reset marcher */
	addr	_cmpfailmsg,r6	/* ** */
	addr	ram2_berr1,r7
	jump	printmsg
ram2_berr1:
	movd	r2,r4		/* [error address] */
	addr	ram2_berr2,r7
	br	prquad
ram2_berr2:
	addr	ram2_b3,r7	/* continue address */
	jump	chkesc

ram2_end:
/*  */
ram_3:
	sprd	fp,r0		/* get test code */
	movd	r0,r1
	ashd	$-1,r1		/* shift out low bit */
	lprd	fp,r1		/* save test code */
	tbitb	$0,r0		/* was bit set? */
	bfc	ram_4		/* nope */

	addr	_ramtst3msg,r6	/* print BYTE ALIGNMENT TEST start */
	addr	ram3_start,r7
	jump	printmsg
ram3_start:
	addr	ALIGNMENT,r1	/* 88442211 */
	addr	ram3_a0,r5
	br	quadfill
ram3_a0:
	addr	ALIGNMENT,r1
	addr	ram3_b1,r5
	br	bytecompare
ram3_b1:
	addr	ALIGNMENT,r1
	addr	ram3_b2,r5
	br	wordcompare
ram3_b2:
	addr	ALIGNMENT+1,r1
	movd	r3,r2		/* copy address */
	addqd	$1,r2		/* try words at odd boundaries */
	sprd	sp,r0		/* get count */
	addqd	$-1,r0
	addr	ram3_c1,r5
	br	wcompare
ram3_c1:
	addr	ALIGNMENT,r1
	addr	ram3_c2,r5
	br	quadcompare
ram3_c2:
	addr	ALIGNMENT+1,r1
	movd	r3,r2		/* copy address */
	addqd	$1,r2		/* try quads at odd boundaries */
	sprd	sp,r0		/* get count */
	addqd	$-1,r0
	addr	ram3_c3,r5
	br	qcompare
ram3_c3:
	addr	ALIGNMENT+2,r1
	movd	r3,r2		/* copy address */
	addqd	$2,r2		/* try quads at word boundaries */
	sprd	sp,r0		/* get count */
	addqd	$-2,r0
	addr	ram3_c4,r5
	br	qcompare
ram3_c4:
	addr	ALIGNMENT+3,r1
	movd	r3,r2		/* copy address */
	addqd	$3,r2		/* try quads at odd boundaries */
	sprd	sp,r0		/* get count */
	addqd	$-3,r0
	addr	ram3_done,r5
	br	qcompare
ram3_done:

/*  */
ram_4:
	sprd	fp,r0		/* get test code */
	movd	r0,r1
	ashd	$-1,r1		/* shift out low bit */
	lprd	fp,r1		/* save test code */
	tbitb	$0,r0		/* was bit set? */
	bfc	ram_5		/* nope */

	addr	_ramtst4msg,r6	/* print UNIQUENESS TEST start */
	addr	ram4_start,r7
	jump	printmsg
ram4_start:
	addr	ONES,r1		/* set all ones */
	addr	ram4_a1,r5
	br	quadfill
ram4_a1:
	addr	ZEROES,r1	/* write zeroes to Bank A */
	movd	r3,r2		/* get start address */
	sprd	sp,r0		/* get count */
	ashd	$-1,r0		/* divide by two */
	addr	ram4_a2,r5
	br	qfill
ram4_a2:
	addr	ONES,r1		/* check Bank B */
	movd	r3,r2		/* get start address */
	sprd	sp,r0		/* count */
	ashd	$-1,r0		/* divide by two */
	addd	r0,r2		/* offset to Bank B */
	addr	ram4_a3,r5
	br	qcompare
ram4_a3:
	addr	ONES,r1		/* rewrite Bank B */
	movd	r3,r2		/* get start address */
	sprd	sp,r0		/* count */
	ashd	$-1,r0		/* divide by two */
	addd	r0,r2		/* offset to Bank B */
	addr	ram4_a4,r5
	br	qfill
ram4_a4:
	addr	ZEROES,r1	/* check Bank A */
	movd	r3,r2		/* get start address */
	sprd	sp,r0		/* count */
	ashd	$-1,r0		/* divide by two */
	addr	ram4_b0,r5
	br	qcompare
ram4_b0:
	movd	r3,r2		/* get start address */
	movqd	$0,r1		/* set Bank A start pattern */
	sprd	sp,r0		/* count */
	ashd	$-1,r0		/* divide by two */
ram4_b1:
	movd	r1,0(r2)	/* init Bank A */
	addqd	$4,r1
	addqd	$4,r2		/* increment address */
	addqd	$-4,r0
	cmpqd	$0,r0
	blt	ram4_b1

	movd	$0xC0000000,r1	/* set Bank B start pattern */
	sprd	sp,r0
	ashd	$-1,r0
ram4_b2:
	movd	r1,0(r2)	/* init Bank A */
	addqd	$4,r1
	addqd	$4,r2		/* increment address */
	addqd	$-4,r0
	cmpqd	$0,r0
	blt	ram4_b2

	movd	r3,r4		/* get start address */
	movqd	$0,r1		/* set Bank A start pattern */
	movd	$0xC0000000,r2	/* set Bank B start pattern */
	sprd	sp,r0		/* count */
	ashd	$-1,r0		/* divide by two */
	movd	r0,r5		/* copy half-size */
ram4_b3:
	cmpd	r1,0(r4)	/* check Bank A */
	bne	ram4_berra
ram4_b3a:
	addd	r5,r4
	cmpd	r2,0(r4)	/* check Bank B */
	bne	ram4_berrb
ram4_b3b:
	subd	r5,r4
	addqd	$4,r1
	addqd	$4,r2
	addqd	$4,r4		/* increment address */
	addqd	$-4,r0
	cmpqd	$0,r0
	blt	ram4_b3
	br	ram4_done

ram4_berra:
	addr	_cmpfailmsg,r6
	addr	ram4_berra1,r7
	jump	printmsg
ram4_berra1:
	addr	ram4_berra2,r7
	br	prquad
ram4_berra2:
	addr	ram4_b3a,r7
	jump	chkesc

ram4_berrb:
	addr	_cmpfailmsg,r6
	addr	ram4_berrb1,r7
	jump	printmsg
ram4_berrb1:
	addr	ram4_berrb2,r7
	br	prquad
ram4_berrb2:
	addr	ram4_b3b,r7
	jump	chkesc

ram4_done:
/*  */
ram_5:
	sprd	fp,r0		/* get test code */
	movd	r0,r1
	ashd	$-1,r1		/* shift out low bit */
	lprd	fp,r1		/* save test code */
	tbitb	$0,r0		/* was bit set? */
	bfc	ram_6		/* nope */

	addr	_ramtst5msg,r6	/* print MARCHING UNIQUENESS TEST start */
	addr	ram5_start,r7
	jump	printmsg
ram5_start:
	addr	ZEROES,r1
	addr	ram5_a1,r5
	br	quadfill
ram5_a1:				/* write to Bank A */
	movd	$0xff,0(r3)
	movd	r3,r2
	sprd	sp,r0
	addqd	$1,r2
	addqd	$-1,r0
	addr	ram5_a2,r5
	addr	ZEROES,r1
	br	bcompare
ram5_a2:
	movd	$0xff00,0(r3)
	movd	r3,r2
	sprd	sp,r0
	addqd	$2,r2
	addqd	$-2,r0
	addr	ram5_a3,r5
	addr	ZEROES,r1
	br	bcompare
ram5_a3:
	movd	$0xff0000,0(r3)
	movd	r3,r2
	sprd	sp,r0
	addqd	$3,r2
	addqd	$-3,r0
	addr	ram5_a4,r5
	addr	ZEROES,r1
	br	bcompare
ram5_a4:
	movd	$0xff000000,0(r3)
	movd	r3,r2
	sprd	sp,r0
	addqd	$4,r2
	addqd	$-4,r0
	addr	ram5_b0,r5
	addr	ZEROES,r1
	br	bcompare
ram5_b0:
	addr	ONES,r1
	addr	ram5_b1,r5
	br	quadfill
ram5_b1:
	movd	$0xffffff00,0(r3)
	movd	r3,r2
	sprd	sp,r0
	addqd	$1,r2
	addqd	$-1,r0
	addr	ram5_b2,r5
	addr	ONES,r1
	br	bcompare
ram5_b2:
	movd	$0xffff00ff,0(r3)
	movd	r3,r2
	sprd	sp,r0
	addqd	$2,r2
	addqd	$-2,r0
	addr	ram5_b3,r5
	addr	ONES,r1
	br	bcompare
ram5_b3:
	movd	$0xff00ffff,0(r3)
	movd	r3,r2
	sprd	sp,r0
	addqd	$3,r2
	addqd	$-3,r0
	addr	ram5_b4,r5
	addr	ONES,r1
	br	bcompare
ram5_b4:
	movd	$0x00ffffff,0(r3)
	movd	r3,r2
	sprd	sp,r0
	addqd	$4,r2
	addqd	$-4,r0
	addr	ram5_c0,r5
	addr	ONES,r1
	br	bcompare
ram5_c0:
	addr	ZEROES,r1
	addr	ram5_c1,r5
	br	quadfill
ram5_c1:			/* write to Bank B */
	sprd	sp,r2
	addqd	$-4,r2
	addd	r3,r2
	movd	$0xff000000,0(r2)
	movd	r3,r2
	sprd	sp,r0
	addqd	$-1,r0
	addr	ram5_c2,r5
	addr	ZEROES,r1
	br	bcompare
ram5_c2:
	sprd	sp,r2
	addqd	$-4,r2
	addd	r3,r2
	movd	$0xff0000,0(r2)
	movd	r3,r2
	sprd	sp,r0
	addqd	$-2,r0
	addr	ram5_c3,r5
	addr	ZEROES,r1
	br	bcompare
ram5_c3:
	sprd	sp,r2
	addqd	$-4,r2
	addd	r3,r2
	movd	$0xff00,0(r2)
	movd	r3,r2
	sprd	sp,r0
	addqd	$-3,r0
	addr	ram5_c4,r5
	addr	ZEROES,r1
	br	bcompare
ram5_c4:
	sprd	sp,r2
	addqd	$-4,r2
	addd	r3,r2
	movd	$0xff,0(r2)
	movd	r3,r2
	sprd	sp,r0
	addqd	$-4,r0
	addr	ram5_d0,r5
	addr	ZEROES,r1
	br	bcompare
ram5_d0:
	addr	ONES,r1
	addr	ram5_d1,r5
	br	quadfill
ram5_d1:
	sprd	sp,r2
	addqd	$-4,r2
	addd	r3,r2
	movd	$0x00ffffff,0(r2)
	movd	r3,r2
	sprd	sp,r0
	addqd	$-1,r0
	addr	ram5_d2,r5
	addr	ONES,r1
	br	bcompare
ram5_d2:
	sprd	sp,r2
	addqd	$-4,r2
	addd	r3,r2
	movd	$0xff00ffff,0(r2)
	movd	r3,r2
	sprd	sp,r0
	addqd	$-2,r0
	addr	ram5_d3,r5
	addr	ONES,r1
	br	bcompare
ram5_d3:
	sprd	sp,r2
	addqd	$-4,r2
	addd	r3,r2
	movd	$0xffff00ff,0(r2)
	movd	r3,r2
	sprd	sp,r0
	addqd	$-3,r0
	addr	ram5_d4,r5
	addr	ONES,r1
	br	bcompare
ram5_d4:
	sprd	sp,r2
	addqd	$-4,r2
	addd	r3,r2
	movd	$0xffffff00,0(r2)
	movd	r3,r2
	sprd	sp,r0
	addqd	$-4,r0
	addr	ram5_e0,r5
	addr	ONES,r1
	br	bcompare
ram5_e0:
/*  */
ram_6:
	sprd	fp,r0		/* get test code */
	movd	r0,r1
	ashd	$-1,r1		/* shift out low bit */
	lprd	fp,r1		/* save test code */
	tbitb	$0,r0		/* was bit set? */
	bfc	ram_7		/* nope */

	addr	_ramtst6msg,r6	/* print REFRESH TEST start */
	addr	ram6_start,r7
	jump	printmsg
ram6_start:
	addr	ZEROES,r1	/* try all zeros */
	addr	ram6_a1,r5
	br	quadfill
ram6_a1:
	addr	ram6_a2,r5
	br	refreshdelay
ram6_a2:
	addr	ZEROES,r1
	addr	ram6_b0,r5
	br	quadcompare

ram6_b0:
	addr	ONES,r1		/* try all ones */
	addr	ram6_b1,r5
	br	quadfill
ram6_b1:
	addr	ram6_b2,r5
	br	refreshdelay
ram6_b2:
	addr	ONES,r1
	addr	ram6_b3,r5
	br	quadcompare
ram6_b3:
				/* Marching ones */
	movqd	$1,r1
ram6_c0:
	addr	ram6_c1,r5
	br	squadfill
ram6_c1:
	addr	ram6_c1a,r5
	br	refreshdelay
ram6_c1a:
	addr	ram6_c2,r5
	br	squadcompare
ram6_c2:
	rotd	$1,r1
	cmpqd	$1,r1		/* back to starting point? */
	bne	ram6_c0		/* nope...continue */

				/* Marching zeros */
	movqd	$-2,r1
ram6_d0:
	addr	ram6_d1,r5
	br	squadfill
ram6_d1:
	addr	ram6_d1a,r5
	br	refreshdelay
ram6_d1a:
	addr	ram6_d2,r5
	br	squadcompare
ram6_d2:
	rotd	$1,r1
	cmpqd	$-2,r1		/* back to starting point? */
	bne	ram6_d0		/* nope...continue */
/*  */
ram_7:
	sprd	fp,r0		/* get test code */
	movd	r0,r1
	ashd	$-1,r1		/* shift out low bit */
	lprd	fp,r1		/* save test code */
	tbitb	$0,r0		/* was bit set? */
	bfc	ram_8		/* nope */

	addr	_ramtst7msg,r6	/* print LONG REFRESH TEST start */
	addr	ram7_start,r7
	jump	printmsg
ram7_start:
	addr	ZEROES,r1	/* try all zeros */
	addr	ram7_a1,r5
	br	quadfill
ram7_a1:
	addr	ram7_a2,r5
	br	extrefreshdelay
ram7_a2:
	addr	ZEROES,r1
	addr	ram7_b0,r5
	br	quadcompare

ram7_b0:
	addr	ONES,r1		/* try all ones */
	addr	ram7_b1,r5
	br	quadfill
ram7_b1:
	addr	ram7_b2,r5
	br	extrefreshdelay
ram7_b2:
	addr	ONES,r1
	addr	ram7_c0,r5
	br	quadcompare

ram7_c0:
	addr	FIVES,r1	/* try all fives */
	addr	ram7_c1,r5
	br	quadfill
ram7_c1:
	addr	ram7_c2,r5
	br	extrefreshdelay
ram7_c2:
	addr	FIVES,r1
	addr	ram7_d0,r5
	br	quadcompare

ram7_d0:
	addr	AAS,r1		/* try all a's */
	addr	ram7_d1,r5
	br	quadfill
ram7_d1:
	addr	ram7_d2,r5
	br	extrefreshdelay
ram7_d2:
	addr	AAS,r1
	addr	ram7_e0,r5
	br	quadcompare

ram7_e0:
/*  */

ram_8:
	sprd	fp,r0		/* get test code */
	movd	r0,r1
	ashd	$-1,r1		/* shift out low bit */
	lprd	fp,r1		/* save test code */
	tbitb	$0,r0		/* was bit set? */
	bfc	ram_9		/* nope */

	addr	_ramtst8msg,r6	/* print HOST BUS ACTIVITY TEST start */
	addr	ram8_start,r5	/* return after character struck */
	addr	erd1,r7		/* print msg and wait for character */
	jump	printmsg
ram8_start:
	movb	$HOST_MEMENABLE,@(UART_MAPENABLE+U_SETOUT)	/* enable bus */
ram8_a0:
	movw	@HOST_CSR,@HOST_CSR	/* read CSR & intrpt at that vector */
	movw	@HOST_CSR,@HOST_CSR
	addr	FIVES,r1	/* write all fives */
	addr	ram8_a1,r5
	br	wordfill
ram8_a1:
/*	movw	@HOST_CSR,@HOST_CSR
	movw	@HOST_CSR,@HOST_CSR
	addr	FIVES,r1
	addr	ram8_a2,r5
	br	wordcompare	*/
ram8_a2:
	movw	@HOST_CSR,@HOST_CSR	/* read CSR & intrpt at that vector */
	movw	@HOST_CSR,@HOST_CSR
	addr	ram8_a0,r5		/* loop when this test finishes */
	br	wordrw			/* read and write host memory */
/*  */

ram_9:
	sprd	fp,r0		/* get test code */
	movd	r0,r1
	ashd	$-1,r1		/* shift out low bit */
	lprd	fp,r1		/* save test code */
	tbitb	$0,r0		/* was bit set? */
	bfc	ram_10		/* nope */

	addr	_ramtst9msg,r6	/* print Copy and Execute in Ram Test */
	addr	ram9_start,r7
	jump	printmsg
ram9_start:
	addr	_copyoutmsg,r6	/* print copying... */
	addr	ram9_cp,r7
	jump	printmsg
ram9_cp:
	addr	((endcode-copycode)+32)/32,r0	/* count mod 32 */
	addr	copycode,r1			/* source */
	movd	r2,r3				/* destination */
	movsd					/* copy code to ram */

	/* go execute the program just copied into ram */
	movd	r3,r2		/* code is here */
	jump	0(r2)	

copycode:
	sprd	sp,r0				/* size */
	subd	((endcode-copycode)+32)/32,r0	/* start after code */
	movd	r3,r1		/* start address */
	movqd	$-1,0(r1)	/* write all f's */
	movqd	$0,4(r1)	/* write all zero's */
	addr	8(r1),r2	/* copy here */

	movsd			/* write words of f's and zeros's */

	sprd	sp,r0				/* size */
	subd	((endcode-copycode)+32)/32,r0	/* start after code */
	movd	r3,r1		/* reload start address */
	cmpqd	$-1,0(r1)	/* is it all f's */
	bne	cpfailure
	cmpqd	$0,4(r1)	/* is it all zero's */
	bne	cpfailure

	cmpsd

	bfs	cpfailure	/* go jump to rom to print error mesg */
	bne	cpfailure

	jump	endcode		/* return normally */
cpfailure:
	jump	romcpfail
endcode:
	addr	_donemsg,r6	/* print verify done */
	addr	ram_10,r7
	jump	printmsg
romcpfail:
	







/*  */

ram_10:
done_DIAG:
	bicpsrw	$PSR_S		/* set normal stack pointer */
	jump	ramless_quiet


refreshdelay:			/* return thru r5 */
	addr	_refreshmsg,r6
	addr	rd1,r7
	jump	printmsg
rd1:
	addr	rd2,r7
	addr	@40000,r0	/* loop count */
rd1a:
	jump	chkesc
rd2:
	acbd	$-1,r0,rd1a	/* decrement loop variable */
	jump	0(r5)		/* return */


extrefreshdelay:		/* return thru r5 */
	addr	_extrefreshmsg,r6
	addr	erd1,r7
	jump	printmsg
erd1:
#ifdef REV_2A /****************** CPU REVISION-2A **********************/
	tbitb	$U_B_RXRDY,@(UART0+U_STAT)	/*  incoming char on UART-0? */
	bfc	erd1			/*  no....loop forever */
	movb	@(UART0+U_IDATA),r6	/*  yes...read it from UART-0 */
#endif /************************* CPU REVISION-2A **********************/

	andb	$0x7F,r6		/* clear extra bits */
	cmpb	r6,$0x1b		/* ESCAPE? */
	beq	erd2			/* yes...quit */
	jump	0(r5)			/* no....wake up */
erd2:
	jump	ramless_quiet
/*  */

/* quadfill / qfill - fill a region with a pattern
 *	r1 - 16-byte pattern address
 *	r3 - destination start address (r2, if qfill)
 *	usp - byte count (r0, if qfill) *** Must be mod 16 ***
 *	r5 - return address
 */
quadfill:
	sprd	sp,r0		/* copy count */
	movd	r3,r2		/* copy destination address */
qfill:
	movmd	r1,r2,$4	/* copy 16-bytes */
	addr	16(r2),r2	/* increment destination */
	addr	-16(r0),r0	/* decrement count */
	cmpqd	$0,r0		/* done? */
	blt	qfill		/* no */
	movd	r5,r7		/* copy return address */
	jump	chkesc		/* and check for <ESCAPE> */


/* wordfill / wfill - fill a region with a pattern (word access)
 *	r1 - 16-byte pattern address
 *	r3 - destination start address (r2, if wfill)
 *	usp - byte count (r0, if wfill) *** Must be mod 16 ***
 *	r5 - return address
 */
wordfill:
	sprd	sp,r0		/* copy count */
	movd	r3,r2		/* copy destination address */
wfill:
	movmw	r1,r2,$8	/* copy 16-bytes */
	addr	16(r2),r2	/* increment destination */
	addr	-16(r0),r0	/* decrement count */
	cmpqd	$0,r0		/* done? */
	blt	wfill		/* no */
	movd	r5,r7		/* copy return address */
	jump	chkesc		/* and check for <ESCAPE> */


/* wordrw / wrw - read and write a region (word access)
 *	r3 - destination start address (r2, if wrw)
 *	usp - byte count (r0, if wrw) *** Must be mod 16 ***
 *	r5 - return address
 */
wordrw:
	sprd	sp,r0		/* copy count */
	movd	r3,r2		/* copy destination address */
wrw:
	movw	0(r2),0(r2)	/* read and write */
	cmpw	0(r2),0(r2)	/* read read */
	movw	0(r2),0(r2)	/* read and write */
	addqd	$2,r2		/* increment destination */
	addqd	$-2,r0		/* decrement count */
	cmpqd	$0,r0		/* done? */
	blt	wrw		/* no */
	movd	r5,r7		/* copy return address */
	jump	chkesc		/* and check for <ESCAPE> */


/* quadcompare / qcompare - compare a region with a pattern
 *	r1 - 16-byte pattern address
 *	r3 - destination start address (r2, if qcompare)
 *	usp - byte count (r0, if qcompare)
 *	r5 - return address
 *	r4 - used
 */
quadcompare:
	sprd	sp,r0		/* copy count */
	movd	r3,r2		/* copy destination address */
qcompare:
	/* print message about what's happening */
	addr	_ramcmpqmsg,r6
	addr	qcmpm1,r7
	jump	printmsg	/* Quad compare: */
qcmpm1:
	movd	r2,r4
	addr	qcmpm2,r7
	br	prquad		/* [start address] */
qcmpm2:
	addr	_ramcmp2msg,r6
	addr	qcmpm3,r7
	jump	printmsg	/* - */
qcmpm3:
	movd	r2,r4
	addd	r0,r4
	addr	qcmpm4,r7
	br	prquad		/* [end address] */
qcmpm4:
	addr	_ramcmp3msg,r6
	addr	qcmpm5,r7
	jump	printmsg	/* / pattern: */
qcmpm5:
	movd	0(r1),r4	/* get first pattern quad */
	addr	qcmpm6,r7
	br	prquad		/* [pattern] */
qcmpm6:

qcmploop:
	cmpd	r0,$16		/* enough for next multiple? */
	blt	qcmplast	/* nope */
	movd	r2,r4		/* save error address */
	addr	16(r2),r2	/* increment destination */
	addr	-16(r0),r0	/* decrement count */
	cmpmd	r1,-16(r2),$4	/* compare 16-bytes */
	bne	qcmpfail	/* no match */
	br	qcmploop	/* no */

qcmplast:
	cmpqd	$3,r0		/* done? */
	blt	qcmpsingle	/* no */
	movd	r5,r7		/* copy return address */
	jump	chkesc		/* and check for <ESCAPE> */

qcmpsingle:
	movd	r2,r4		/* save error address */
	addqd	$-4,r0		/* count 4 less bytes */
	addqd	$4,r1		/* update addresses */
	addqd	$4,r2
	cmpd	-4(r1),-4(r2)	/* compare quad */
	bne	qcmpfail	/* not equal */
	br	qcmplast

qcmpfail:
	addr	_cmpfailmsg,r6	/* ** */
	addr	qcmpf1,r7
	jump	printmsg
qcmpf1:
	addr	qcmpf2,r7	/* [error address] */
	br	prquad
qcmpf2:
	addr	qcmploop,r7
	jump	chkesc
/*  */

/* squadfill / sqfill - fill a region with a pattern
 *	r1 - 4-byte pattern
 *	r3 - destination start address (r2, if sqfill)
 *	usp - byte count (r0, if sqfill) *** Must be mod 4 ***
 *	r5 - return address
 */
squadfill:
	sprd	sp,r0		/* copy count */
	movd	r3,r2		/* copy destination address */
sqfill:
	movd	r1,0(r2)	/* copy 4-bytes */
	addqd	$4,r2		/* increment destination */
	addqd	$-4,r0		/* decrement count */
	cmpqd	$0,r0		/* done? */
	blt	sqfill		/* no */
	movd	r5,r7		/* copy return address */
	jump	chkesc		/* and check for <ESCAPE> */


/* squadcompare / sqcompare - compare a region with a pattern
 *	r1 - 4-byte pattern
 *	r3 - destination start address (r2, if sqcompare)
 *	usp - byte count (r0, if sqcompare)
 *	r5 - return address
 *	r4 - used
 */
squadcompare:
	sprd	sp,r0		/* copy count */
	movd	r3,r2		/* copy destination address */
sqcompare:
	/* print message about what's happening */
	addr	_ramcmpqmsg,r6
	addr	sqcmpm1,r7
	jump	printmsg	/* Quad compare: */
sqcmpm1:
	movd	r2,r4
	addr	sqcmpm2,r7
	br	prquad		/* [start address] */
sqcmpm2:
	addr	_ramcmp2msg,r6
	addr	sqcmpm3,r7
	jump	printmsg	/* - */
sqcmpm3:
	movd	r2,r4
	addd	r0,r4
	addr	sqcmpm4,r7
	br	prquad		/* [end address] */
sqcmpm4:
	addr	_ramcmp3msg,r6
	addr	sqcmpm5,r7
	jump	printmsg	/* / pattern: */
sqcmpm5:
	movd	r1,r4		/* get pattern */
	addr	sqcmpm6,r7
	br	prquad		/* [pattern] */
sqcmpm6:

sqcmploop:
	cmpd	r0,$4		/* enough for next compare? */
	blt	sqcmpdone	/* nope */
	movd	r2,r4		/* save error address */
	addd	$4,r2		/* increment destination */
	subd	$4,r0		/* decrement count */
	cmpd	r1,-4(r2)	/* compare 4-bytes */
	bne	sqcmpfail	/* no match */
	br	sqcmploop	/* no */

sqcmpdone:
	movd	r5,r7		/* copy return address */
	jump	chkesc		/* and check for <ESCAPE> */

sqcmpfail:
	addr	_cmpfailmsg,r6	/* ** */
	addr	sqcmpf1,r7
	jump	printmsg
sqcmpf1:
	addr	sqcmpf2,r7	/* [error address] */
	br	prquad
sqcmpf2:
	addr	sqcmploop,r7
	jump	chkesc
/*  */

/* wordcompare / wcompare - compare a region with a pattern
 *	r1 - 16-byte pattern address
 *	r3 - destination start address (r2, if wcompare)
 *	usp - byte count (r0, if wcompare)
 *	r5 - return address
 *	r4 - used
 */
wordcompare:
	sprd	sp,r0		/* copy count */
	movd	r3,r2		/* copy destination address */
wcompare:
	/* print message about what's happening */
	addr	_ramcmpwmsg,r6
	addr	wcmpm1,r7
	jump	printmsg	/* Word compare: */
wcmpm1:
	movd	r2,r4
	addr	wcmpm2,r7
	br	prquad		/* [start address] */
wcmpm2:
	addr	_ramcmp2msg,r6
	addr	wcmpm3,r7
	jump	printmsg	/* - */
wcmpm3:
	movd	r2,r4
	addd	r0,r4
	addr	wcmpm4,r7
	br	prquad		/* [end address] */
wcmpm4:
	addr	_ramcmp3msg,r6
	addr	wcmpm5,r7
	jump	printmsg	/* / pattern: */
wcmpm5:
	movd	0(r1),r4	/* get first pattern quad */
	addr	wcmpm6,r7
	br	prquad		/* [pattern] */
wcmpm6:

wcmploop:
	cmpd	r0,$16		/* enough for next multiple? */
	blt	wcmplast	/* nope */
	movd	r2,r4		/* save error address */
	addr	16(r2),r2	/* increment destination */
	addr	-16(r0),r0		/* decrement count */
	cmpmw	r1,-16(r2),$8	/* compare 16-bytes */
	bne	wcmpfail	/* no match */
	br	wcmploop	/* no */

wcmplast:
	cmpqd	$1,r0		/* done? */
	blt	wcmpsingle	/* no */
	movd	r5,r7		/* copy return address */
	jump	chkesc		/* and check for <ESCAPE> */

wcmpsingle:
	movd	r2,r4		/* save error address */
	addqd	$-2,r0		/* count 2 less bytes */
	addqd	$2,r1		/* update addresses */
	addqd	$2,r2
	cmpw	-2(r1),-2(r2)	/* compare word */
	bne	wcmpfail	/* not equal */
	br	wcmplast

wcmpfail:
	addr	_cmpfailmsg,r6	/* ** */
	addr	wcmpf1,r7
	jump	printmsg
wcmpf1:
	addr	wcmpf2,r7	/* [error address] */
	br	prquad
wcmpf2:
	addr	wcmploop,r7
	jump	chkesc
/*  */

/* bytecompare / bcompare - compare a region with a pattern
 *	r1 - 16-byte pattern address
 *	r3 - destination start address (r2, if bcompare)
 *	r4 - byte count (r0, if bcompare)
 *	r5 - return address
 *	usp - used
 */
bytecompare:
	sprd	sp,r0		/* copy count */
	movd	r3,r2		/* copy destination address */
bcompare:
	/* print message about what's happening */
	addr	_ramcmpbmsg,r6
	addr	bcmpm1,r7
	jump	printmsg	/* Byte compare: */
bcmpm1:
	movd	r2,r4
	addr	bcmpm2,r7
	br	prquad		/* [start address] */
bcmpm2:
	addr	_ramcmp2msg,r6
	addr	bcmpm3,r7
	jump	printmsg	/* - */
bcmpm3:
	movd	r2,r4
	addd	r0,r4
	addr	bcmpm4,r7
	br	prquad		/* [end address] */
bcmpm4:
	addr	_ramcmp3msg,r6
	addr	bcmpm5,r7
	jump	printmsg	/* / pattern: */
bcmpm5:
	movd	0(r1),r4	/* get first pattern quad */
	addr	bcmpm6,r7
	br	prquad		/* [pattern] */
bcmpm6:

bcmploop:
	cmpd	r0,$16		/* enough for next multiple? */
	blt	bcmplast	/* nope */
	movd	r2,r4		/* save error address */
	addr	16(r2),r2	/* increment destination */
	addr	-16(r0),r0	/* decrement count */
	cmpmb	r1,-16(r2),$16	/* compare 16-bytes */
	bne	bcmpfail	/* no match */
	br	bcmploop	/* no */

bcmplast:
	cmpqd	$0,r0		/* done? */
	blt	bcmpsingle	/* no */
	movd	r5,r7		/* copy return address */
	jump	chkesc		/* and check for <ESCAPE> */

bcmpsingle:
	movd	r2,r4		/* save error address */
	addqd	$-1,r0		/* count 1 less byte */
	addqd	$1,r1		/* update addresses */
	addqd	$1,r2
	cmpb	-1(r1),-1(r2)	/* compare byte */
	bne	bcmpfail	/* not equal */
	br	bcmplast

bcmpfail:
	addr	_cmpfailmsg,r6	/* ** */
	addr	bcmpf1,r7
	jump	printmsg
bcmpf1:
	addr	bcmpf2,r7	/* [error address] */
	br	prquad
bcmpf2:
	addr	bcmploop,r7	/* [error address] */
	jump	chkesc
/*  */

/* prquad - print a quad value in r4
 *	r4 - input value
 *	r6 - used
 *	r7 - return address
 *	mod - used
 */
prquad:
	lprw	mod,$9		/* set char count */
prqloop:
	rotd	$4,r4		/* rotate high nibble into low */
	sprw	mod,r6		/* get char count */
	addqw	$-1,r6		/* decrement character counter */
	lprw	mod,r6		/* save count */
	cmpqw	$0,r6		/* done? */
	bne	prqnxt		/* nope */
	jump	0(r7)		/* return */

prqnxt:
	movd	r4,r6		/* copy value */
	andd	$0x0f,r6	/* mask off the rest */
	cmpb	r6,$0x0a	/* is it a digit? */
	bge	prqalph		/* no, print the alpha character */
	addb	$0x30,r6	/* yes convert to digit hex */
	br	prqchr
prqalph:
	addb	$0x37,r6	/* convert to alpha hex */
prqchr:
#ifdef REV_2A /****************** CPU REVISION-2A **********************/
	tbitb	$U_B_TXRDY,@(UART0+U_STAT)	/* wait til ok to write more */
	bfc	prqchr
	movb	r6,@(UART0+U_ODATA)		/* write out character */

prqchrout:
	tbitb	$U_B_TXEMPTY,@(UART0+U_STAT)	/* wait for transmitter empty */
	bfc	prqchrout			/* before returning */
#endif /************************* CPU REVISION-2A **********************/

	br	prqloop		/* loop until done */


FIVES:		.double	0x55555555, 0x55555555, 0x55555555, 0x55555555
AAS:		.double	0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa
OTHREES:	.double	0x03030303, 0x03030303, 0x03030303, 0x03030303
OONES:		.double	0x01010101, 0x01010101, 0x01010101, 0x01010101
CZEROES:	.double	0xc0c0c0c0, 0xc0c0c0c0, 0xc0c0c0c0, 0xc0c0c0c0
EZEROES:	.double	0xe0e0e0e0, 0xe0e0e0e0, 0xe0e0e0e0, 0xe0e0e0e0

ALIGNMENT:	.double	0x88442211, 0x88442211, 0x88442211, 0x88442211
		.double	0x88442211
