	TITLE	MEMORY TEST (C) 1980 Software Dynamics
	PAGE	;
	TABS	20,28,44,45
	WITH	WI=107,DE=51
*
*	M E M O R Y	T E S T
*
*	1/8/83 V1.0c I.B.
*		MODIFIED TO HANDLE "ERR:ACTIVATIONNOTINBUFFER"
*		ADDED SDOS/MT INTERFACE (AUTOMATIC IF ACIA=0)
*		MOVED SCRATCH STORAGE TO PAGE ZERO
*	12/19/80 I.B.
*		CONVERTED TO M680C/M6809
*	9/16/80 MOD'S TO MATCH DOCUMENTATION, ALLOW UPPER LIMIT CONFIGURATION
*	MODIFIED BY I.B., DEC 7, 1979
*		ADDED START ADDRESS
*		STOMPED ON JUMP TABLE
*		CHANGED FOR WAVEMATE TO ALLOW I/O THROUGH PROM
*	MEMORY TEST 12/17/78 R.A.G.
*
*
CR	EQU	$D
EOS	EQU	$0
LF	EQU	$A
SYSCALL	EQU	$FB
SYSCALL:READA	EQU	$A
SYSCALL:WRITEA	EQU	$C
SYSCALL:EXIT	EQU	$11
SYSCALL:ERROREXIT	EQU	$12
ERR:ACTIVATIONNOTINBUFFER	EQU	1907

PRIME	EQU	1021

	IFUND	m6800
	IFUND	m6801
	IFUND	m6809
m6800	equ	1
m6801	equ	0
m6809	equ	0
	FIN	m6809
	FIN	m6801
	FIN	m6800

	IFUND	EXORCISOR
EXORCISOR	EQU	0
	FIN	EXORCISOR

	IFUND	MSI
MSI	EQU	0
	FIN	MSI

	IFUND	WAVEMATE
WAVEMATE	EQU	0
	FIN	WAVEMATE

	IFUND	STANDARD
	IF	&EXORCISOR
	IF	&WAVEMATE
	IF	&MSI
STANDARD	EQU	1
	FIN
	FIN
	FIN
	FIN

	IFUND	STANDARD
STANDARD	EQU	0
	FIN

	IFUND	ACIACTL$
ACIACTL$	EQU	0
ACIADATA$	EQU	0
	FIN
	PAGE	PAGE ZERO STUFF
	ORG	$20	TO SKIP AROUND 6801 REGISTERS, ETC.
COMPUTEDCHECKSUM	RMB	1	MEMTEST STORES ITS SELF-COMPUTED CHECKSUM HERE
BOTTOM	RMB	2	BOTTOM OF REGION TO TEST
TOP	RMB	2	TOP OF REGION TO TEST
MEMLOC	RMB	2	MEMORY LOCATION UNDER TEST
VARIANT	RMB	2	DIFFERS FROM MEMLOC BY ONE BIT
PATTERNNUMBER	RMB	1	USED BY PATTERN TEST
LOOPCOUNT	RMB	1	GP LOOP COUNTER
POINTER	RMB	2	GP POINTER
BUFFER	RMB	2	GP SCRATCH
	RMB	1
NUMBER	RMB	2	THIS MUST FOLLOW BUFFER
DIGITS	RMB	1	# DIGITS TO PRINT
EXPECTED	RMB	1	THIS IS VALUE EXPECTED (THAT WAS STORED)
GOT	RMB	1	THIS IS THE VALUE THAT WAS READ BACK (ACTUALLY SAVED)
VARIANTADDRESS	RMB	2	VARIANT ADDRESS MANUFACTURED BY TESTMUX, LEAKTEST
TEMPX	RMB	2
MASK	RMB	2
INTERVAL	RMB	2
COUNTER	RMB	2
LEADZEROES	RMB	1	# LEADING ZEROS OF NUMBER

	page
*	I/O routines to allow MEMTEST to run under SDOS or SDOS/MT

SIZEMEMORY ; Set HIGHLIMIT to top of user space
	LDX	SYSCALL+1	= Last user byte, +1
	STX	HIGHLIMIT	Use as Highlimit
	RTS

RASCIIGETC ; Read Ascii to Get a character
	LDX	#READASCII1	Get syscall address
	JSR	SYSCALL	Go get a character, SDOS!
	BCS	RASCIIGETC1	Ooooh...a problem arose
RASCIIGETCOK ; all is fine, get character and get out!
	LDAA	CHARACTER	Put character where desired
	RTS		All Done!

RASCIIGETC1 ; oops, error occurred while reading
	CPX	#ERR:ACTIVATIONNOTINBUFFER
	BEQ	RASCIIGETCOK	b/ this is ok
FATALERROR ; Handle heart failure
	STX	ERRORCODE
	LDX	#ERROREXIT
	JSR	SYSCALL
	BCS	*	?????

ERROREXIT FCB SYSCALL:ERROREXIT,4
ERRORCODE FDB 0

READASCII1	FCB SYSCALL:READA,14,0,1	Read Ascii on channel 0 in line mode
	FDB	0,0	Write buffer (ignored)
	FDB	0	RPLEN (Expected value=1)
	FDB	CHARACTER,1	Where to put results, and how many bytes

CHARACTER FCB	0	1 character I/O buffer

WASCIIPUTC ; Write (A) to CONSOLE:
	STAA	CHARACTER	Store the character to be written
	LDX	#WASCII1	Do the write.
	JSR	SYSCALL
	BCS	FATALERROR	Ooops...
	RTS

WASCII1	FCB	SYSCALL:WRITEA,8,0,0	Write Ascii
	FDB	CHARACTER,1	From the buffer for 1 byte
	PAGE	ENTRY VECTORS/PARAMETERS
	ORG	$100
GO	JMP	START
	JMP	MEMTEST1	ENTER HERE IF TESTING WITHOUT SDOS
	IF	STANDARD
*	Standard I/O scheme: ACIACTL$ and ACIADATA$ control port addresses
ACIACTL	FDB	ACIACTL$	0 --> Use SDOS/MT interface primitives
ACIADATA	FDB	ACIADATA$
RESET$	JMP	ACIARESET	do reset to ACIA
GETCHAR$	JMP	ACIAIN	get character from ACIA
PUTCHAR$	JMP	ACIAOUT	give character to ACIA
ECHOCHAR$	JMP	ACIAECHO	echo character to ACIA
INTDISABLE	JMP	ACIAINTDISABLE	disable interrupts if real acia
	FIN	STANDARD
	IF	WAVEMATE
ACIACTL	FDB	$FFC0	THIS IS IGNORED BY WAVEMATE VERSION OF MEMTEST
ACIADATA	FDB	$FFC1	DITTO
RESET$	JMP	$FC03	THIS IS PATCHABLE
GETCHAR$	JMP	$FC09	THIS IS PATCHABLE
PUTCHAR$	JMP	$FC06	THIS IS PATCHABLE
ECHOCHAR$	JMP	$FC06	THIS IS PATCHABLE
INTDISABLE	JMP	$FC33	THIS IS PATCHABLE
	FIN	WAVEMATE

	IF	EXORCISOR
ACIACTL	FDB	$FCF4
ACIADATA	FDB	$FCF5
RESET$	JMP	ACIARESET	THIS IS PATCHABLE
GETCHAR$	JMP	ACIAIN	THIS IS PATCHABLE
PUTCHAR$	JMP	ACIAOUT	THIS IS PATCHABLE
ECHOCHAR$	JMP	ACIAOUT	THIS IS PATCHABLE
INTDISABLE
	JMP	ACIAINTDISABLE	THIS IS PATCHABLE
	FIN	EXORCISOR

	IF	MSI
ACIACTL	FDB	$F500	THIS IS PATCHABLE
ACIADATA	FDB	$F501
RESET$	JMP	ACIARESET	THIS IS PATCHABLE
GETCHAR$	JMP	ACIAIN	THIS IS PATCHABLE
PUTCHAR$	JMP	ACIAOUT	THIS IS PATCHABLE
ECHOCHAR$	JMP	ACIAOUT	THIS IS PATCHABLE
INTDISABLE
	JSR	ACIAINTDISABLE	THIS IS PATCHABLE
	FIN	MSI

LOWLIMIT	FDB	STACK+1
HIGHLIMIT	FDB	0
MEMPARTSIZE	FDB	0
CHECKSUMVALUE	FCB	CHECKSUM	THIS NEEDS TO BE RE-COMPUTED AFTER ASSEMBLY
*	IT'S UP TO THE INGENIOUS CODER TO FIGURE OUT HOW!
*
	page	ACIA I/O ROUTINES
CHECKSTART	EQU	*	checksum starts here

ACIARESET	LDX	#$4000
ACIARESET1	DEX
	BNE	ACIARESET1
	LDX	ACIACTL
	LBEQ	SIZEMEMORY	B/ SDOS/MT, set HIGHLIMIT to top of user space
	LDAA	#3
	STAA	0,X
	LDAA	#$15
	STAA	0,X
	RTS


ACIAECHO ; echo character back to ACIA
	LDX	ACIACTL
	BEQ	ACIAINTDISABLE.RTS	B/ SDOS/MT, character already echoed
ACIAOUT	LDX	ACIACTL
	LBEQ	WASCIIPUTC	B/ SDOS/MT, output character via SYSCALL
ACIAOUT1	LDAB	0,X
	BITB	#2
	BEQ	ACIAOUT1	B/ OUTPUT REGISTER NOT READY
	STA	[ACIADATA]
	RTS

ACIAIN	LDX	ACIACTL
	LBEQ	RASCIIGETC	B/ SDOS/MT, get character via SYSCALL
ACIAIN1	LDAA	0,X
	RORA
	BCC	ACIAIN1
	LDA	[ACIADATA]
	RTS

ACIAINTDISABLE ; disable interrupts
	LDX	ACIACTL
	BEQ	ACIAINTDISABLE.RTS	b/ SDOS/MT, leave interrupts on
	IF	M6800
	NOP
	FIN
	SEI
ACIAINTDISABLE.RTS
	RTS
	PAGE	START THE TESTING
STARTTESTING	JSR	CHECKCHECKSUM
	LDX	LOWLIMIT
	STX	BOTTOM
	LDX	HIGHLIMIT
	STX	TOP
	JSR	PRINTSTRING
	FCC	"Galloping Ones and Zeros test..."
	CR,EOS
	JSR	TESTGALLOPINGBITS
	JSR	CHECKCHECKSUM
	JSR	PRINTSTRING
	FCC	"Multiplexor test..."
	CR,EOS
	JSR	TESTMUX
	JSR	CHECKCHECKSUM
	JSR	PRINTSTRING
	FCC	"Pattern test..."
	CR,EOS
	JSR	TESTPATTERN
	JSR	CHECKCHECKSUM
*
*	TOP = LOWLIMIT
*100	BOTTOM = TOP
*	TOP = (BOTTOM + MEMPARTSIZE) & MASK
*	IF TOP > HIGHLIMIT THEN TOP = HIGHLIMIT
*	IF BOTTOM >= HIGHLIMIT THEN 200 \ ! DONE
*	CALL TEST
*	GOTO 100
*200	! NEXT TEST
*
	LDX	LOWLIMIT
	STX	TOP
MEMTEST15	LDD	TOP
	STD	BOTTOM
	ADDD	MEMPARTSIZE
	BCS	MEMTEST17	B/ TOP > HIGHLIMIT (OVERFLOW)
	LDX	MASK
	BEQ	MEMTEST17	B/ DON'T USE MASK (PART >= 64K)
	ANDB	MASK+1
	ANDA	MASK
	STD	TOP
	SUBD	HIGHLIMIT
	BCS	MEMTEST18	B/ TOP > HIGHLIMIT
MEMTEST17	LDX	HIGHLIMIT
	STX	TOP
MEMTEST18	LDD	BOTTOM
	SUBD	HIGHLIMIT
	BCC	MEMTEST19	B/ DO NEXT TEST
	JSR	PRINTSTRING
	FCC	"Leakage testing from "
	EOS
	LDX	BOTTOM
	JSR	PUTHEX
	JSR	PRINTSTRING
	FCC	" to "
	EOS
	LDX	TOP
	JSR	PUTHEX
	JSR	CRLF
	JSR	LEAKTEST
	BRA	MEMTEST15
	PAGE
MEMTEST19	JSR	CHECKCHECKSUM
	JSR	INTENSITYTEST
	JSR	CHECKCHECKSUM
	JSR	PRINTSTRING
	FCC	"Retention test..."
	CR,EOS
	JSR	RETENTIONTEST
MEMTEST21	JSR	CHECKCHECKSUM
	JSR	PRINTSTRING
	FCC	"Memory test Completed."
	CR,EOS
	JMP	*
	PAGE	UTILITIES
REPORTERROR	STX	NUMBER
	STAA	EXPECTED
	STAB	GOT
	JSR	PRINTSTRING
	FCC	"Error at "
	EOS
	LDX	NUMBER
REPORTERROR1	JSR	PUTHEX
	JSR	PRINTSTRING
	FCC	"; expected "
	EOS
	LDAA	EXPECTED
	JSR	PUTHEXBYTE
	JSR	PRINTSTRING
	FCC	"; retreived "
	EOS
	LDAA	GOT
	JSR	PUTHEXBYTE
	BSR	CRLF
	JSR	COMPUTECHECKSUM
	BEQ	CONTINUE
	JMP	CHECKSUMISWRONG
*
PRINTSTRING	LDX	0,S	GET ADDRESS OF STRING
	LDAA	0,X	GET THE CHARACTER
	CMPA	#EOS	IS THIS THE END OF STRING MARK?
	BNE	PRINTSTRING1	B/ NO
	LDX	0,S
	LEAS	2,S
	JMP	1,X

PRINTSTRING1	JSR	PUTCHAR
	LDD	0,S
	ADDD	#1
	STD	0,S
	BRA	PRINTSTRING
	page
CRLF	LDAA	#CR
PUTCHAR	PSHA
	JSR	PUTCHAR$
	PULA
	CMPA	#CR
	BNE	PUTCHAR1
	LDAA	#LF
	BSR	PUTCHAR
	CLRA
	BSR	PUTCHAR
	BSR	PUTCHAR
	BSR	PUTCHAR
	BRA	PUTCHAR
*
PUTCHAR1	RTS
*
PUTHEX	STX	NUMBER
	LDAA	NUMBER
	BSR	PUTHEXBYTE
	LDAA	NUMBER+1
PUTHEXBYTE	PSHA
	LSRA
	LSRA
	LSRA
	LSRA
	BSR	PUTHEX2
	PULA
	ANDA	#$F
PUTHEX2	ADDA	#'0
	CMPA	#'9
	BLS	PUTHEX3
	ADDA	#'A-'0-10
PUTHEX3	JMP	PUTCHAR
*
CONTINUE	BSR	PRINTSTRING
	FCC	"Press any key to continue from error: "
	EOS
	JSR	GETCHAR$
	BRA	CRLF
*
PUTDECIMAL	STX	NUMBER
	LDX	#0
	STX	BUFFER
	STX	BUFFER+1
	LDAB	#16
*
*	THIS BUILDS A BCD STRING IN BUFFER
*
DECOUT1	LDX	#BUFFER
	ASL	4,X
	ROL	3,X
DECOUT2	LDAA	2,X
	ADCA	2,X
	DAA
	STAA	2,X
	LDAA	1,X
	ADCA	1,X
	DAA
	STAA	1,X
	LDAA	0,X
	ADCA	0,X
	DAA
	STAA	0,X
	DECB
	BNE	DECOUT1
*
*	THIS CONVERTS BCD TO ASCII
*
	CLR	LEADZEROES
DECOUT3	LDAA	0,X
	LSRA
	LSRA
	LSRA
	LSRA
	BSR	DECOUT5
	LDAA	0,X
	ANDA	#$F
	CPX	#BUFFER+2	IS THIS THE LAST CHAR?
	BNE	DECOUT3.1
	BSR	DECOUT6	YES, BYPASS ZERO SUPRESSION CODE
	BRA	DECOUT3.2
DECOUT3.1	BSR	DECOUT5
DECOUT3.2	INX
	CPX	#BUFFER+3
	BNE	DECOUT3
DECOUT4	RTS
DECOUT5	TAB
	ORAB	LEADZEROES
	STAB	LEADZEROES
	BEQ	DECOUT4
DECOUT6	ADDA	#'0
	STX	TEMPX
	JSR	PUTCHAR
	LDX	TEMPX
	RTS
*
CHECKCHECKSUM	BSR	COMPUTECHECKSUM
	BEQ	CHECKCHECKSUM2	B/ CHECKSUM IS OK
CHECKSUMISWRONG ; complain about checksum over self
	JSR	PRINTSTRING
	FCC	'MEMORY TEST PROGRAM HAS BEEN DAMAGED, RESULTS MAY BE INVALID'
	CR,EOS
	JMP	CONTINUE	(FROM ERROR)
CHECKCHECKSUM2	RTS
*
COMPUTECHECKSUM	LDX	#CHECKSTART
	CLRA
CHECKCHECKSUM1
	IF	m6809
	ADDA	,X+
	ELSE	(m6800!m6801)
	ADDA	0,X
	INX
	FIN
	CPX	#CHECKEND
	BNE	CHECKCHECKSUM1
	STAA	COMPUTEDCHECKSUM	THIS MAKES IT EASY TO FIGURE OUT WHAT CHECKSUM SHOULD BE
	CMPA	CHECKSUMVALUE
	RTS
	PAGE	GALLOPING BITS TEST
*
*	GALLOPING ONES
*
TESTGALLOPINGBITS	LDX	BOTTOM
GALLOP1	LDAA	#1
T1LOOP	STAA	0,X
	LDAB	0,X
	CBA
	BNE	GALLOPERROR
	ASLA
	BCC	T1LOOP
*
*	GALLOPING ZEROS
*
	LDAA	#$FE
T0LOOP	STAA	0,X
	LDAB	0,X
	CBA
	BNE	GALLOPERROR
	SEC
	ROLA
	BCS	T0LOOP
*
	INX
	CPX	TOP
	BNE	GALLOP1
	CLC
	RTS

GALLOPERROR	JMP	REPORTERROR
	PAGE	MULTIPLEXER TEST
*
*	VARIANT ADDRESS (MUX ERROR) TEST
*
TESTMUX	LDX	BOTTOM
TESTMUX1	STX	MEMLOC
	CLR	0,X		ZERO THE ADDRESS UNDER TEST
	CLR	VARIANT
	LDAA	#1
	STAA	VARIANT+1
VARIANTLOOP	LDD	MEMLOC
	EORA	VARIANT
	EORB	VARIANT+1
	CMPD	BOTTOM
	BCS	VARNEXT
	CMPD	TOP
	BHI	VARNEXT
TESTVARIANT	STD	VARIANTADDRESS
	LDX	VARIANTADDRESS
	LDAA	#$FF
	STAA	0,X
	LDX	MEMLOC
	LDAB	0,X
	BNE	MUXERROR
VARNEXT	ASL	VARIANT
	ROL	VARIANT+1
	BCC	VARIANTLOOP
	INX
	CPX	TOP
	BNE	TESTMUX1
	RTS

MUXERROR	CLRA		= EXPECTED VALUE
MUXERROR1	STAA	EXPECTED	SAVE EXPECTED VALUE
	STAB	GOT	SAVE RETRIEVED VALUE
	JSR	PRINTSTRING
	FCC	"Error at "
	EOS
	LDX	MEMLOC
	JSR	PUTHEX
	JSR	PRINTSTRING
	FCC	"; Variant address = "
	EOS
	LDX	VARIANTADDRESS
	JMP	REPORTERROR1
	PAGE	PATTERN TEST
*
*	PATTERN SENSITIVITY TEST
*
TESTPATTERN	LDAA	#16
	STAA	LOOPCOUNT
*
*	TEST PATTERN 0 AS SPECIAL CASE
*
	LDX	BOTTOM
PATTERNTEST0	STX	MEMLOC
	LDAA	#$A5
PATTERNTEST1	STA	,X+
	CPX	TOP
	BNE	PATTERNTEST1
	LDX	MEMLOC
PATTERNTEST2	LDAB	0,X
	CBA
	BNE	PATTERNFAILEDJ	B/ NOT QUITE WHAT I EXPECTED
	NEG	0,X	NOW SHOULD CONTAIN -$A5
	INX
	CPX	TOP
	BNE	PATTERNTEST2
	NEGA
PATTERNTEST3	LDB	,-X
	CBA
	BNE	PATTERNFAILEDJ
	INC	0,X
	CPX	MEMLOC
	BNE	PATTERNTEST3
	PAGE
*
*	TEST REMAINING PATTERNS (1-15)
*
	LDAB	#1
PATTERNTEST4	STAB	PATTERNNUMBER
	LDX	MEMLOC
	LDAA	#$A5
PATTERNTEST5	STA	,X+
	CPX	TOP
	BEQ	PATTERNTEST7
PATTERNTEST6	DECB
	BNE	PATTERNTEST5
	COMA
	LDAB	PATTERNNUMBER
	STA	,X+
	CPX	TOP
	BNE	PATTERNTEST6
	PAGE
*
*	WE'RE AT THE TOP, START AT MEMLOC AGAIN
*
PATTERNTEST7	LDX	MEMLOC
	LDAA	#$A5
	LDAB	PATTERNNUMBER
	STAB	COUNTER
PATTERNTEST8	LDAB	0,X
	CBA
PATTERNFAILEDJ	BNE	PATTERNTESTFAILED
	NEG	0,X
	INX
	CPX	TOP
	BEQ	PATTERNTEST10
PATTERNTEST9	DEC	COUNTER
	BNE	PATTERNTEST8
	COMA
	LDAB	PATTERNNUMBER
	STAB	COUNTER
	LDAB	0,X
	CBA
	BNE	PATTERNTESTFAILED
	NEG	0,X
	INX
	CPX	TOP
	BNE	PATTERNTEST9
	PAGE
*
*	WE'RE AT THE TOP, GO BACKWARDS
*
PATTERNTEST10	NEGA
	LDAB	COUNTER
	DECB
	NEGB
	ADDB	PATTERNNUMBER
	STAB	COUNTER
PATTERNTEST11	LDB	,-X
	CBA
	BNE	PATTERNTESTFAILED
	INC	0,X
	CPX	MEMLOC
	BEQ	PATTERNTEST13
PATTERNTEST12	DEC	COUNTER
	BNE	PATTERNTEST11
	NEGA
	INCA
	LDAB	PATTERNNUMBER
	STAB	COUNTER
	LDB	,-X
	CBA
	BNE	PATTERNTESTFAILED
	INC	0,X
	CPX	MEMLOC
	BNE	PATTERNTEST12
*
PATTERNTEST13	LDAB	PATTERNNUMBER
	INCB
	CMPB	#16
	BNE	PATTERNTEST4
	INX
	CPX	TOP
	BEQ	PATTERNTEST14	B/ ALL DONE
	DEC	LOOPCOUNT
	BEQ	PATTERNTEST14
	JMP	PATTERNTEST0

PATTERNTEST14	CLC
	RTS

PATTERNTESTFAILED
	JMP	REPORTERROR
	PAGE	LEAKAGE TEST
*
*	! INITIALIZE RAM TO ZERO
*	FOR I = BOTTOM TO TOP
*	POKE I,0
*	NEXT I
*
LEAKTEST	LDX	BOTTOM
	CLRA
X1	STA	,X+
	CPX	TOP
	BNE	X1
*
*	FOR MEMLOC = BOTTOM TO TOP
*	POKE MEMLOC, :FF
*!	DELAY 100 US TO LET LEAKS HAPPEN
*
	LDX	BOTTOM
X2	STX	MEMLOC
	LDAA	#$FF
	STAA	0,X
	JSR	DELAY
	PAGE
*
*	FOR I = TABLESTART TO TABLEEND
*	X = MEMLOC + TABLE(I)
*	IF X >= TOP THEN X4
*	IF PEEK(X) <> 0 THEN ERROR
*	NEXT I
*
	LDX	#TABLE
X3	STX	POINTER
	LDD	MEMLOC
	ADDD	0,X
	BCS	X4
	STD	VARIANTADDRESS
	SUBD	TOP
	BCC	X4
	LDX	VARIANTADDRESS
	CLRA		= EXPECTED VALUE
	LDAB	0,X
	BNE	LEAKTESTERREDJ1
	LDX	POINTER
	LEAX	2,X
	CPX	#TABLEEND
	BNE	X3
	PAGE
*
*	FOR I = TABLESTART TO TABLE END
*	X = MEMLOC - TABLE(I)
*	IF X < BOTTOM THEN X6
*	IF PEEK(X) <> 0 THEN ERROR
*	NEXT I
*
X4	LDX	#TABLE
X5	STX	POINTER
	LDD	MEMLOC
	SUBD	0,X
	BCS	X6
	STD	VARIANTADDRESS
	SUBD	BOTTOM
	BCS	X6
	LDX	VARIANTADDRESS
	CLRA		= EXPECTED VALUE
	LDAB	0,X
LEAKTESTERREDJ1	BNE	LEAKTESTERREDJ
	LDX	POINTER
	LEAX	2,X
	CPX	#TABLEEND
	BNE	X5
*
*	POKE MEMLOC, 0
*	NEXT MEMLOC
*
X6	LDX	MEMLOC
	CLR	0,X
	INX
	CPX	TOP
	BNE	X2
	PAGE
*
*	! INITIALIZE RAM TO :FF
*	FOR I = BOTTOM TO TOP
*	POKE I, :FF
*	NEXT I
*
	LDX	BOTTOM
	LDAA	#$FF
X7	STA	,X+
	CPX	TOP
	BNE	X7
*
*	FOR MEMLOC = BOTTOM TO TOP
*	POKE MEMLOC, 0
*!	DELAY 100 US TO LET MEMORY LEAK
*
	LDX	BOTTOM
X8	STX	MEMLOC
	CLR	0,X
	BSR	DELAY
*
	PAGE
*
*	FOR I = TABLESTART TO TABLEEND
*	X = MEMLOC + TABLE(I)
*	IF X >= TOP THEN X10
*	IF PEEK(X) <> :FF THEN ERROR
*	NEXT I
*
	LDX	#TABLE
X9	STX	POINTER
	LDD	MEMLOC
	ADDD	0,X
	BCS	X10
	STD	VARIANTADDRESS
	SUBD	TOP
	BCC	X10
	LDX	VARIANTADDRESS
	LDAA	#$FF	= EXPECTED VALUE
	LDAB	0,X
	CBA
LEAKTESTERREDJ	BNE	LEAKTESTERRED
	LDX	POINTER
	LEAX	2,X
	CPX	#TABLEEND
	BNE	X9
	PAGE
*
*	FOR I = TABLESTART TO TABLE END
*	X = MEMLOC - TABLE(I)
*	IF X < BOTTOM THEN X12
*	IF PEEK(X) <> :FF THEN ERROR
*	NEXT I
*
X10	LDX	#TABLE
X11	STX	POINTER
	LDD	MEMLOC
	SUBD	0,X
	BCS	X12
	STD	VARIANTADDRESS
	SUBD	BOTTOM
	BCS	X12
	LDX	VARIANTADDRESS
	LDAA	#$FF	= EXPECTED VALUE
	LDAB	0,X
	CBA
	BNE	LEAKTESTERRED
	LDX	POINTER
	LEAX	2,X
	CPX	#TABLEEND
	BNE	X11
*
*	POKE MEMLOC, :FF
*	NEXT MEMLOC
*
X12	LDX	MEMLOC
	COM	0,X
	INX
	CPX	TOP
	BNE	X8
	CLC
	RTS

LEAKTESTERRED	JMP	MUXERROR1
	PAGE
DELAY	LDAA	#12
DELAY1	DECA
	BNE	DELAY1
	RTS
	PAGE	LEAK CONSTANT GENERATION PROGRAM
*	DIM A(2000),I,J,K,L,MEMLOC,LIMIT,LINES,TWOTOTHE(16),FILE$(20)
*
*	INPUT 'GENERATE MEMORY TEST CONSTANTS. HOW MANY ADDRESS LINES? ' LINES
*	FOR I = 0 TO LINES-1
*	TWOTOTHE(I) = 2^I
*	NEXT I
*	LIMIT = 2^LINES
*	INPUT 'OUTPUT FILE: ' FILE$
*	A(1) = 1
*	K = 1
*
*	FOR I = 0 TO LINES-1
*	FOR J = 0 TO LINES-1
*	MEMLOC = TWOTOTHE(I) \ ! COMPUTE 2^I
*	GOSUB 10
*	MEMLOC = MEMLOC + TWOTOTHE(J) \ ! COMPUTE 2^I + 2^J
*	GOSUB 10
*	MEMLOC = ABS(TWOTOTHE(I) - TWOTOTHE(J)) \ ! COMPUTE 2^I - 2^J
*	GOSUB 10
*!
*!	THE FOLLOWING THREE CASES ARE IDENTICAL WITH THE
*!	ABOVE THREE CASES
*!
*!	MEMLOC = ABS(- TWOTOTHE(I)) \ ! COMPUTE -2^I
*!	GOSUB 10
*!	MEMLOC = ABS(TWOTOTHE(J) - TWOTOTHE(I)) \ ! COMPUTE -2^I + 2^J
*!	GOSUB 10
*!	MEMLOC = ABS(- TWOTOTHE(I) - TWOTOTHE(J)) \ ! COMPUTE -2^I - 2^J
*!	GOSUB 10
*	NEXT J
*	NEXT I
*	CREATE #1, FILE$
*	FOR I = 1 TO K-1
*	FOR J = I+1 TO K
*	IF A(J) < A(I) THEN L=A(J) \ A(J) = A(I) \ A(I) = L
*	NEXT J
*	PRINT #1, A(I)
*	NEXT I
*	PRINT 'K=' ; K
*	STOP
*10	IF MEMLOC > LIMIT THEN RETURN
*	IF MEMLOC = 0 THEN RETURN
*	FOR L = 1 TO K
*	IF A(L) = MEMLOC THEN RETURN
*	NEXT L
*	K = K + 1
*	A(K) = MEMLOC
*	RETURN
*	END
	PAGE	LEAK CONSTANTS
*
*	THERE ARE ENOUGH CONSTANTS HERE FOR A 64K MEMORY PART
*
TABLE	FDB	1
	FDB	2
	FDB	3
	FDB	4
	FDB	5
	FDB	6
	FDB	7
	FDB	8
	FDB	9
	FDB	10
	FDB	12
	FDB	14
	FDB	15
	FDB	16
	FDB	17
	FDB	18
	FDB	20
	FDB	24
	FDB	28
	FDB	30
	FDB	31
	FDB	32
	FDB	33
	FDB	34
	FDB	36
	FDB	40
	FDB	48
	FDB	56
	FDB	60
	FDB	62
	FDB	63
	FDB	64
	FDB	65
	FDB	66
	FDB	68
	FDB	72
	FDB	80
	FDB	96
	FDB	112
	FDB	120
	FDB	124
	FDB	126
	FDB	127
	FDB	128
	FDB	129
	FDB	130
	FDB	132
	FDB	136
	FDB	144
	FDB	160
	FDB	192
	FDB	224
	FDB	240
	FDB	248
	FDB	252
	FDB	254
	FDB	255
	FDB	256
	FDB	257
	FDB	258
	FDB	260
	FDB	264
	FDB	272
	FDB	288
	FDB	320
	FDB	384
	FDB	448
	FDB	480
	FDB	496
	FDB	504
	FDB	508
	FDB	510
	FDB	511
	FDB	512
	FDB	513
	FDB	514
	FDB	516
	FDB	520
	FDB	528
	FDB	544
	FDB	576
	FDB	640
	FDB	768
	FDB	896
	FDB	960
	FDB	992
	FDB	1008
	FDB	1016
	FDB	1020
	FDB	1022
	FDB	1023
	FDB	1024
	FDB	1025
	FDB	1026
	FDB	1028
	FDB	1032
	FDB	1040
	FDB	1056
	FDB	1088
	FDB	1152
	FDB	1280
	FDB	1536
	FDB	1792
	FDB	1920
	FDB	1984
	FDB	2016
	FDB	2032
	FDB	2040
	FDB	2044
	FDB	2046
	FDB	2047
	FDB	2048
	FDB	2049
	FDB	2050
	FDB	2052
	FDB	2056
	FDB	2064
	FDB	2080
	FDB	2112
	FDB	2176
	FDB	2304
	FDB	2560
	FDB	3072
	FDB	3584
	FDB	3840
	FDB	3968
	FDB	4032
	FDB	4064
	FDB	4080
	FDB	4088
	FDB	4092
	FDB	4094
	FDB	4095
	FDB	4096
	FDB	4097
	FDB	4098
	FDB	4100
	FDB	4104
	FDB	4112
	FDB	4128
	FDB	4160
	FDB	4224
	FDB	4352
	FDB	4608
	FDB	5120
	FDB	6144
	FDB	7168
	FDB	7680
	FDB	7936
	FDB	8064
	FDB	8128
	FDB	8160
	FDB	8176
	FDB	8184
	FDB	8188
	FDB	8190
	FDB	8191
	FDB	8192
	FDB	8193
	FDB	8194
	FDB	8196
	FDB	8200
	FDB	8208
	FDB	8224
	FDB	8256
	FDB	8320
	FDB	8448
	FDB	8704
	FDB	9216
	FDB	10240
	FDB	12288
	FDB	14336
	FDB	15360
	FDB	15872
	FDB	16128
	FDB	16256
	FDB	16320
	FDB	16352
	FDB	16368
	FDB	16376
	FDB	16380
	FDB	16382
	FDB	16383
	FDB	16384
	FDB	16385
	FDB	16386
	FDB	16388
	FDB	16392
	FDB	16400
	FDB	16416
	FDB	16448
	FDB	16512
	FDB	16640
	FDB	16896
	FDB	17408
	FDB	18432
	FDB	20480
	FDB	24576
	FDB	28672
	FDB	30720
	FDB	31744
	FDB	32256
	FDB	32512
	FDB	32640
	FDB	32704
	FDB	32736
	FDB	32752
	FDB	32760
	FDB	32764
	FDB	32766
	FDB	32767
	FDB	32768
	FDB	32769
	FDB	32770
	FDB	32772
	FDB	32776
	FDB	32784
	FDB	32800
	FDB	32832
	FDB	32896
	FDB	33024
	FDB	33280
	FDB	33792
	FDB	34816
	FDB	36864
	FDB	40960
	FDB	49152
TABLEEND	EQU	*
	PAGE	INTENSITY TEST
*
*	THIS TEST OPERATES ON THE ASSUMPTION THAT OVERWORKED
*	MEMORY CAN BECOME FLAKEY. THE IDEA HERE IS TO
*	PLANT A PROGRAM IN THE TEST AREA THAT WORKS
*	A SMALL AREA OF MEMORY VERY INTENSELY, THEN MOVES
*	AND DOES IT SOME MORE.
*
INTENSITYTEST	LDX	LOWLIMIT	FILL MEMORY WITH COPIES...
	STX	TEMPX	OF INTENSITY TEST LOOP
	STX	POINTER
	LDX	#INTENSITYSTART
	STX	MEMLOC
INTENSITY1	LDX	MEMLOC
	LDA	,X+
	CPX	#INTENSITYEND
	BNE	INTENSITY1.0
	LDX	#INTENSITYSTART
INTENSITY1.0	STX	MEMLOC
	LDX	TEMPX
	STA	,X+
	STX	TEMPX
	CPX	HIGHLIMIT
	BNE	INTENSITY1
	BRA	INTENSITY1.2
	PAGE
*
*	THIS IS THE CODE THAT MOVES AROUND IN THE TEST AREA
*
	IF	m6800!m6801
INTENSITYDISPLACEMENT	EQU	$D	HAND COMPUTED TO AVOID A FORWARD REF PROBLEM
	ELSE	(m6809)
INTENSITYDISPLACEMENT	EQU	$E	HAND COMPUTED TO AVOID A FORWARD REF PROBLEM
	FIN	m6800!m6801

INTENSITYSTART	CLRA
INTENSITY2	PSHA
	CLRB
INTENSITY2.1	LDAA	INTENSITYDISPLACEMENT,X
	STAA	INTENSITYDISPLACEMENT,X
	LDAA	INTENSITYDISPLACEMENT,X
	STAA	INTENSITYDISPLACEMENT,X
	DECB
	BNE	INTENSITY2.1
INTENSITY3	EQU	*-1	IF A BIT CHANGES HERE, THE PROGRAM
*	WILL MOST LIKELY RUN AWAY. THE CONSOLE DISPLAY WILL INDICATE
*	THE ADDRESS OF THE TEST THAT BLEW.
*
	IF	INTENSITYDISPLACEMENT#INTENSITY3-INTENSITYSTART
	??INTENSITYDISPLACEMENT INCORRECTLY COMPUTED??
	FIN
	PULA
	DECA
	BNE	INTENSITY2
	JMP	INTENSITY1.2	TIME TO MOVE
INTENSITYEND	EQU	*
*
*	THIS IS THE END OF THE MOBILE CODE
*
	PAGE
INTENSITY1.2	JSR	CHECKCHECKSUM	SEE IF THE PROGRAM IS STILL OK
*
*	THIS CHECKS THE RETENTION OF THE MEMORY WE'VE THRASHED INTENSELY
*
	LDX	LOWLIMIT
	STX	MEMLOC
	LDX	#INTENSITYSTART
	STX	TEMPX
INTENSITY8	LDX	TEMPX
	LDA	,X+
	CPX	#INTENSITYEND
	BNE	INTENSITY9
	LDX	#INTENSITYSTART
INTENSITY9	STX	TEMPX
	LDX	MEMLOC
	LDAB	0,X	FETCH RETAINED VALUE
	CBA		ARE THEY THE SAME ?
	BNE	INTENSITYERROR	B/ NO, MEMORY FAILURE
	INX
	STX	MEMLOC
	CPX	HIGHLIMIT
	BNE	INTENSITY8
INTENSITY11	JSR	PRINTSTRING
	FCC	"Intensity testing at "
	EOS
	LDX	POINTER
	JSR	PUTHEX
	JSR	CRLF
	LDX	POINTER
	LDD	POINTER
	ADDD	#INTENSITYEND-INTENSITYSTART
	BCS	INTENSITY11.1	B/ MUST BE RAM AT TOP OF MEMORY
	STD	POINTER	FOR NEXT TIME
	SUBD	HIGHLIMIT
	BCC	INTENSITY11.1	B/ WE'RE DONE
	JMP	0,X	GO DO ANOTHER ROUND

INTENSITY11.1	RTS
INTENSITYERROR	JMP	REPORTERROR
	PAGE	RETENTION TEST
*
*	THIS TEST CHECKS THE ABILITY OF THE MEMORY TO RETAIN
*	IT'S CONTENTS. THE MEMORY TEST PROGRAM IS USED
*	AS A BIT PATTERN TO FILL UP THE AREA UNDER TEST
*	THEN WE WAIT FOR AN INTERVAL, THEN CHECK TO SEE
*	THAT THE BIT PATTERN IS UNCHANGED. THEN WE MAKE NOISE,
*	WAIT, THEN CHECK THE PATTERN. THEN WE COMPLEMENT THE
*	PATTERN, WAIT, AND CHECK, THEN WE MAKE NOISE, WAIT,
*	AND CHECK. THEN WE DOUBLE THE INTERVAL AND KEEP GOING.
*
RETENTIONTEST	LDX	LOWLIMIT
	LDD	#$5AA5
RETENTION1	STA	,X+
	CPX	HIGHLIMIT
	BEQ	RETENTION2
	STB	,X+
	CPX	HIGHLIMIT
	BNE	RETENTION1
RETENTION2	LDX	#0
	STX	INTERVAL
	JSR	PRINTSTRING
	FCC	"On a 1 Mhz computer, an 'Interval' is approximate 1 second."
	CR,EOS
RETENTION3	SEC		*2 +1
	ROL	INTERVAL+1
	ROL	INTERVAL
	BCC	RETENTION3.0
	CLC
	RTS		WE'RE DONE
RETENTION3.0	BSR	RETENTION4	DELAY A WHILE
	JSR	RETENTION8	CHECK THE PATTERN
	BCS	RETENTIONERROR	B/ ERROR
	BSR	RETENTION6	MAKE NOISE A WHILE
	BSR	RETENTION8	CHECK THE PATTERN
	BCS	RETENTIONERROR	B/ ERROR
	JSR	RETENTION15	COMPLIMENT THE BIT PATTERN
	BSR	RETENTION4	DELAY A WHILE
	JSR	RETENTION12	CHECK THE PATTERN
	BCS	RETENTIONERROR	B/ ERROR
	BSR	RETENTION6	MAKE NOISE A WHILE
	JSR	RETENTION12	CHECK THE PATTERN
	BCS	RETENTIONERROR	B/ ERROR
	JSR	RETENTION15	COMPLEMENT THE BIT PATTERN
	JSR	PRINTSTRING
	FCC	"Memory retained for "
	EOS
	LDX	INTERVAL
	JSR	PUTDECIMAL
	JSR	PRINTSTRING
	FCC	" intervals."
	CR,EOS
	JSR	CHECKCHECKSUM
	BRA	RETENTION3
RETENTIONERROR	JMP	REPORTERROR
*
RETENTION4	LDX	INTERVAL	DELAY AWHILE
	STX	COUNTER
	LDAA	#111	DELAY LONG ENOUGH TO MATCH THE NOISE SUBROUTINE
RETENTION5.1	DECB
	BNE	RETENTION5.1
RETENTION5.2	DECA
	BNE	RETENTION5.1
	DEX
	BNE	RETENTION5.1
	RTS
*
RETENTION6	LDX	INTERVAL	MAKE NOISE AWHILE
RETENTION7	STX	COUNTER
	BSR	NOISE
	LDX	COUNTER
	DEX
	BNE	RETENTION7
	RTS
	page
RETENTION8	LDD	#$5AA5
RETENTION8.1	LDX	LOWLIMIT
RETENTION9	PSHB
	LDAB	,X
	CBA
	BNE	RETENTION11A
	PULB
	INX
	CPX	HIGHLIMIT
	BEQ	RETENTION10
	PSHA
	LDAA	,X
	CBA
	BNE	RETENTION11B
	PULA
	INX
	CPX	HIGHLIMIT
	BNE	RETENTION9
RETENTION10	CLC
	RTS

RETENTION11A	INS		POP TO ACCOUNT FOR PSHB
	SEC
	RTS

RETENTION11B	INS		POP TO ACCOUNT FOR PSHA
	PSHA		EXCHANGE (A) WITH (B)
	TFR	B,A
	PULB
	SEC
	RTS
*
RETENTION12	LDD	#$A55A
	BRA	RETENTION8.1
*
RETENTION15	LDX	LOWLIMIT	COMPLEMENT THE BIT PATTERN
RETENTION16	COM	0,X
	INX
	CPX	HIGHLIMIT
	BNE	RETENTION16
	RTS
	PAGE
*
*	NOISE: GENERATE AS MUCH ACTIVITY ON THE BUS AS POSSIBLE
*	THE FIRST ROUTINE WILL MAKE THE ADDRESS BUS FLOP
*	BETWEEN ALL ONES AND ALL ZEROS, R/W LINE WILL FLOP,
*	AND RANDOM DATA WILL BE READ AND WRITTEN
*
NOISE	LDX	$FFFF	IF MACHINE HAS I/O AT $FFFF,
	STX	TEMPX	THIS CAUSES TROUBLE!
	LDX	#307
NOISE1	LDAB	0
	LDAB	$FFFF
	ADDA	#13	GENERATE THE NEXT RANDOM NUMBER
	STAA	0
	STAA	$FFFF
	STX	$FFFF	HITS LOCATIONS 0 AND $FFFF
	DEX
	BNE	NOISE1
	LDX	TEMPX
	STX	$FFFF	RESTORE LOCS ZERO AND $FFFF
*
*	MAKE ALL THE ADDRESS LINES TOGGLE ONE BY ONE:
*	1,2,4,8,16,...
*
	LDX	#307
NOISE2	LDAA	1
	LDAA	2
	LDAA	4
	LDAA	8
	LDAA	$10
	LDAA	$20
	LDAA	$40
	LDAA	$80
	LDAA	$100
	LDAA	$200
	LDAA	$400
	LDAA	$800
	LDAA	$1000
	LDAA	$2000
	LDAA	$4000
	LDAA	$8000
	DEX
	BNE	NOISE2
	PAGE
*
*	GENERATE RANDOM ADDRESSES AND READ/WRITE RANDOM DATA
*	OUTSIDE THE TEST AREA TO SEE IF THE TEST AREA
*	WILL RETAIN IT'S CONTENTS REGARDLESS OF OUTSIDE
*	ACTIVITY. THIS IS ACCOMPLISHED BY READING AND WRITING
*	THE MEMORY TEST PROGRAM ITSELF. THE RANDOM ADDRESS
*	IS GENERATED BY ADDING A RELATIVELY PRIME NUMBER
*	(WITH RESPECT TO THE SIZE OF THE MEMORY TEST PROGRAM)
*	TO THE ADDRESS POINTER MODULO THE SIZE OF THE MEMORY TEST
*
	LDX	#0
	STX	POINTER
	LDX	#307
NOISE4	STX	TEMPX
	LDD	POINTER
	ADDD	#PRIME
NOISE5	SUBD	#CHECKEND-CHECKSTART
	BCC	NOISE5	B/ STILL TOO BIG
	ADDD	#CHECKEND-CHECKSTART
	STD	POINTER
	ADDD	#CHECKSTART
	STD	VARIANT
	LDX	VARIANT
	LDAA	0,X
	STAA	0,X
	LDX	TEMPX
	DEX
	BNE	NOISE4
	RTS
	page
HELLOSTRING	FCC	'Memory Test V1.0c 1/15/83, (C) 1980 Software Dynamics'
	CR
HELLOSTRINGEND
CHECKEND	EQU	*	END OF CHECKSUMMED REGION
WARNINGSTRING
	FCC	'THIS TEST KILLS SDOS; YOU WILL HAVE TO RE-BOOT WHEN DONE'
	CR
	FCC	'OK? '
WARNINGSTRINGEND
*
STACK	EQU	CHECKEND+50	EMPIRICALLY DETERMINED STACK SIZE
	PAGE	GATHER INFO
START	LDX	#HELLO	SAY 'HELLO' AND GIVE HIM A CHANCE TO BACK OUT
	JSR	SYSCALL
	BCS	FATALERRORJ	B/ ERROR
	LDX	ACIACTL	Set up SDOS/MT operation ?
	BEQ	MEMTEST1J	B/ yes, running this test is not fatal
	LDX	#WARNING	No, tell user what will happen...
	JSR	SYSCALL
	BCS	FATALERRORJ	B/ something awful happened!
	JSR	RASCIIGETC	get reply character
	PSHA		save reply
ignorerestofline ; loop to ignore rest of line
	CMPA	#CR	end of line ?
	BEQ	INSPECTANSWER	b/ yes
	JSR	RASCIIGETC	no
	BRA	IGNORERESTOFLINE

INSPECTANSWER ; now inspect answer from user
	PULA
	CMPA	#'Y	WELL, IS USER READY TO DO IT??
	BEQ	MEMTEST1J	B/ HE SAY'S HE'S READY TO DO IT!
	CMPA	#'y
	BNE	ABORT	B/ USER WANTS TO QUIT...
MEMTEST1J	JSR	INTDISABLE	SHUT OFF THE WORLD
	JMP	MEMTEST1

ABORT ; user doesn't wish to do MEMTEST
	LDX	#0	make him do an EXIT
FATALERRORJ	JMP	FATALERROR	EXIT WITH ERROR CODE GIVEN IN (X)

HELLO	FCB	SYSCALL:WRITEA
	FCB	8	LENGTH
	FCB	0	CHANNEL
	FCB	0
	FDB	HELLOSTRING	POINTER TO HELLO STRING
	FDB	HELLOSTRINGEND-HELLOSTRING	LENGTH OF HELLO STRING

WARNING	FCB	SYSCALL:WRITEA
	FCB	8	LENGTH
	FCB	0	CHANNEL
	FCB	0
	FDB	WARNINGSTRING
	FDB	WARNINGSTRINGEND-WARNINGSTRING
	PAGE
MEMTEST1	LDS	#STACK	USE SOMETHING SAFE
	LDX	#0	ALLOW SETTLING TIME FOR THE I/O ROUTINES
MEMTEST1.0	DEX
	BNE	MEMTEST1.0
	JSR	INTDISABLE	WE'RE ON OUR OWN, TAKE OVER THE WORLD
	if	M6809
	CLRA
	TFR	A,DP
	fin
	JSR	RESET$
	JSR	CHECKCHECKSUM	MAKE SURE THE PROGRAM IS OK
	LDX	#PROGEND	FIND END OF MEMORY
	BRA	MEMTEST2.A
MEMTEST2	COM	0,X	PUT IT BACK THE WAY IT WAS
MEMTEST2.A	CPX	HIGHLIMIT	AT END OF RAM ?
	BEQ	MEMTEST2A	B/ YES
	INX		(ASSUME AT LEAST ONE MEMORY CELL TO TEST)
	LDAA	0,X
	COM	0,X
	COMA
	CMPA	0,X
	BEQ	MEMTEST2	B/ THIS IS NOT THE END
	STX	HIGHLIMIT	THIS IS THE END OF THE (CONTIGUOUS) WORLD
MEMTEST2A	JSR	CHECKCHECKSUM	MAKE SURE THE PROGRAM IS OK
	JSR	PRINTSTRING
	FCC	"Testing memory from "
	EOS
	LDX	LOWLIMIT
	JSR	PUTHEX
	JSR	PRINTSTRING
	FCC	" to "
	EOS
	LDX	HIGHLIMIT
	JSR	PUTHEX
	JSR	CRLF
MEMTEST3	JSR	PRINTSTRING
	FCC	"New lower limit? (Hex number or <CR>) "
	EOS
	JSR	GETHEX
	BCS	MEMTEST3	B/ OVERFLOW
	CMPA	#CR
	BNE	MEMTEST3	B/ LET HIM TRY AGAIN
	TSTB		1 OR MORE DIGITS?
	BEQ	MEMTEST5	B/ NO DIGITS TYPED
	STX	TEMPX	LET'S CHECK IT OUT
	LDD	TEMPX
	SUBD	LOWLIMIT
	BCC	MEMTEST4	B/ THIS NUMBER IS >= LOWLIMIT (OK)
	JSR	PRINTSTRING
	FCC	"That's too small!"
	CR,EOS
	BRA	MEMTEST3
MEMTEST4	STX	LOWLIMIT
*
*	HERE'S HIS CHANCE TO CHANGE THE UPPER LIMIT
*
MEMTEST5	JSR	PRINTSTRING
	FCC	"New upper limit? (Hex number or <CR>) "
	EOS
	JSR	GETHEX
	BCS	MEMTEST5	B/ OVERFLOW
	CMPA	#CR
	BNE	MEMTEST5	B/ LET HIM TRY AGAIN
	TSTB		ARE THERE 1 OR MORE DIGITS?
	BEQ	MEMTEST6	B/ NOPE
	STX	HIGHLIMIT	LET'S CHECK HIM OUT
	LDD	LOWLIMIT
	SUBD	HIGHLIMIT
	BCS	MEMTEST6	B/ OK
	JSR	PRINTSTRING
	FCC	"That's too small!"
	CR,EOS
	BRA	MEMTEST5	GIVE HIM ANOTHER CHANCE
*
*	FIND OUT HOW BIG HIS MEMORY PARTS ARE
*
MEMTEST6	LDX	#64	ASSUME 64K PARTS
	STX	MEMPARTSIZE
	JSR	PRINTSTRING
	FCC	"What is the size of the largest memory part"
	CR
	FCC	"in K bits? (Decimal number, <CR> defaults to 64) "
	EOS
	JSR	GETDECIMAL
	BCS	MEMTEST6	B/ OVERFLOW
	CMPA	#CR
	BNE	MEMTEST6	B/ LET HIM TRY AGAIN
	TSTB		1 OR MORE DIGITS?
	BEQ	MEMTEST7	B/ NOPE
	STX	MEMPARTSIZE	LET'S CHECK HIM OUT
	BNE	MEMTEST7	B/ NON-ZERO, THAT'S GOOD ENOUGH
	JSR	PRINTSTRING
	FCC	"That's too small!"
	CR,EOS
	JMP	MEMTEST6	GIVE HIM ANOTHER CHANCE
*
*	MULTIPLY BY 1024 (1K)
*
MEMTEST7	LDD	MEMPARTSIZE
	LDX	#10
MEMTEST8	ASLD
	DEX
	BNE	MEMTEST8
	STAA	MEMPARTSIZE
	STAB	MEMPARTSIZE+1
*
*	BUILD A MODULO MASK
*
	LDX	MEMPARTSIZE
	BEQ	MEMTEST11
	CLR	LOOPCOUNT
MEMTEST9	INC	LOOPCOUNT
	LSRD
	BCC	MEMTEST9
	LDAA	#$FF
	TAB
	BRA	MEMTEST10A
MEMTEST10	ASLD
MEMTEST10A	DEC	LOOPCOUNT
	BNE	MEMTEST10
MEMTEST11	STD	MASK
	JMP	STARTTESTING
	PAGE	DISPENSIBLE UTILITIES
GETCHAR	JSR	GETCHAR$
	ANDA	#$7F
	CMPA	#'a-1
	BLS	GETCHAR1	B/ NOT A LOWER CASE CHAR
	CMPA	#'z
	BHI	GETCHAR1	B/ NOT A LOWER CASE CHAR
	SUBA	#'a-'A
GETCHAR1	RTS
*
GETDECIMAL	CLRA
	CLRB
	STAA	DIGITS
GETDECIMAL1	STAA	NUMBER
	STAB	NUMBER+1
	JSR	GETCHAR
	BSR	IS0THRU9
	BCC	GETDECIMAL2	B/ NOT A DIGIT, WE'RE DONE HERE
	BSR	ECHO
	INC	DIGITS
	ASL	NUMBER+1	*2
	ROL	NUMBER
	BCS	GETDECIMAL2	B/ OVERFLOW
	LDX	NUMBER
	STX	TEMPX
	ASL	NUMBER+1	*4
	ROL	NUMBER
	BCS	GETDECIMAL2	B/ OVERFLOW
	ASL	NUMBER+1	*8
	ROL	NUMBER
	BCS	GETDECIMAL2	B/ OVERFLOW
	CLRA		B STILL HAS DECIMAL DIGIT
	ADDB	TEMPX+1
	ADCA	TEMPX
	BCS	GETDECIMAL2	B/ OVERFLOW
	ADDB	NUMBER+1
	ADCA	NUMBER
	BCC	GETDECIMAL1	B/ NO OVERFLOW, KEEP GOING
GETDECIMAL2	BRA	GETHEX3
*
ECHO	PSHA
	PSHB
	JSR	ECHOCHAR$
	PULB
	PULA
	RTS
*
IS0THRU9	TAB		LEAVE THE INPUT CHAR INTACT IN THE A REG
	SUBB	#'0	MAKE IT A NUMBER
	CMPB	#10
	RTS		C ON IF DIGIT, OFF IF NOT A DIGIT
*
IS0THRUF	BSR	IS0THRU9
	BCS	IS0THRUF2	B/ ITS A DIGIT
	SUBB	#'A-'0-10
	CMPB	#10
	BCC	IS0THRUF1	B/ SO FAR, SO GOOD
	CLC		NOT A DIGIT
	RTS
IS0THRUF1	CMPB	#16
IS0THRUF2	RTS
*
GETHEX	LDX	#0
	STX	NUMBER
	CLR	DIGITS
GETHEX1	JSR	GETCHAR
	BSR	IS0THRUF
	BCC	GETHEX3	B/ NOT A DIGIT
	BSR	ECHO
	INC	DIGITS
	ASLB
	ASLB
	ASLB
	ASLB
	LDAA	#4
GETHEX2	ASLB
	ROL	NUMBER+1
	ROL	NUMBER
	BCS	GETHEX3	B/ OVERFLOW
	DECA
	BNE	GETHEX2
	BRA	GETHEX1	GO GET MORE INPUT
GETHEX3	BCS	GETHEX4	B/ OVERFLOW
	BSR	GETHEX5
	CLC
	RTS
GETHEX4	BSR	GETHEX5
	SEC
	RTS
GETHEX5	PSHA
	JSR	CRLF
	PULA
	LDAB	DIGITS
	LDX	NUMBER
	RTS
PROGEND	EQU	*
	END	GO
