;*************************** AMUS Program Label ******************************
; Filename: SSDCHK.M68                                      Date: 10/05/91
; Category: UTIL         Hash Code: 770-361-661-337      Version: 1.0(100)
; Initials: ULTR/US      Name: DAVID PALLMANN
; Company: ULTRASOFT CORPORATION                   Telephone #: 5163484848
; Related Files: 
; Min. Op. Sys.: AMOSL 1.0/AMOS32 1.0          Expertise Level: INT
; Special: Run this if you suspect faulty SSD chip or CPU timing problems.
; Description: Checks SSD continually, displays failures on screen.
;*****************************************************************************

;****************************************************************************
;*									    *
;*				   SSDCHK				    *
;*		   Utility to check integrity of your SSD		    *
;*									    *
;****************************************************************************
;[100] 04 October 1991 16:51	Edited by David Pallmann
;	Created.

;version number

	VMAJOR	=1
	VMINOR	=0
	VSUB	=0
	VEDIT	=100.
	VWHO	=0

;universals

	SEARCH	SYS
	SEARCH	SYSSYM
	SEARCH	TRM

;variables

	.OFINI
	.OFDEF	CODES1,	64.		; 1st set of codes read
	.OFDEF	CODES2,	64.		; last set of codes read
	.OFDEF	CODES,	4		; number of codes to read
	.OFDEF	PASSES,	4		; passes made
	.OFDEF	DELAY,	4		; delay between passes
	.OFDEF	GOOD,	4		; good pass count
	.OFDEF	BAD,	4		; bad pass count
	.OFSIZ	MEMSIZ

;***********
;*  START  *
;***********
;initialization

START:	PHDR	-1,0,PH$REE!PH$REU	; program header
	GETIMP	MEMSIZ,A5		; allocate local memory for variables

	TYPESP	SSDCHK Version		; 
	VCVT	START+2,OT$TRM		; 
	CRLF				; 
	CRLF				; 
	TYPECR	<This utility will continually sample the SSD chip, and will display>
	TYPECR	<warnings if the codes returned differ from one pass to the next.>
	CRLF				; 

	TYPESP	How many passes do you want to make (default: run continually):
	KBD	EXIT			; 
	GTDEC				; 
	MOV	D1,PASSES(A5)		; 

	TYPESP	How many seconds do you want to pause between each pass (default: none):
	KBD	EXIT			; 
	GTDEC				; 
	MOV	D1,DELAY(A5)		; 

10$:	TYPESP	How many bytes do you want to read during each pass (default: 16):
	KBD	EXIT			; 
	MOV	#16.,D1			; 
	NUM				; 
	BNE	20$			; 
	GTDEC				; 
20$:	CMP	D1,#1			; 
	BLO	10$			; 
	CMP	D1,#64.			; 
	BHI	10$			; 
	MOV	D1,CODES(A5)		; 

BEGIN:	CRLF				; 
	MOV	PASSES(A5),D5		; 
	CLR	PASSES(A5)		; 

SAMPLE:	LEA	A2,CODES1(A5)		; 
	CLR	D0			; 
	CLR	D2			; 
	MOV	CODES(A5),D3		; 
	CALL	REDSSD			; 

NEW.PASS:
	CTRLC	REPORT			; 

	INC	PASSES(A5)		; 

	MOVB	#13.,D1			; 
	TTY				; 

	MOV	PASSES(A5),D1		; 
	TYPESP	Pass			; 
	DCVT	0,OT$TRM		; 
	TYPE	<, error count = >	; 
	MOV	BAD(A5),D1		; 
	DCVT	0,OT$TRM		; 

	LEA	A2,CODES2(A5)		; 
	CLR	D0			; 
	CLR	D2			; 
	MOV	CODES(A5),D3		; 
	CALL	REDSSD			; 

	LEA	A0,CODES1(A5)		; 
	LEA	A1,CODES2(A5)		; 
	MOV	CODES(A5),D0		; 
10$:	CMPB	(A0)+,(A1)+		; 
	BNE	ERROR			; 
	SOB	D0,10$			; 
	INC	GOOD(A5)		; 
	BR	SLEEP			; 

ERROR:	MOVB	#13.,D1			; 
	TTY				; 
	TYPE	<********** ERROR IN SSD BYTES READ DURING PASS > 
	MOV	PASSES(A5),D1		; 
	DCVT	0,OT$TRM		; 
	TYPECR	< **********>		; 
	INC	BAD(A5)			; 

SLEEP:	MOV	DELAY(A5),D0		; 
	JEQ	NEW.PASS		; 
	MUL	D0,#10000.		; 
	SLEEP	D0			; 

NEXT:	CTRLC	REPORT			; 
	DEC	D5			; 
	JNE	NEW.PASS		; 

REPORT:	CRLF				; 
	CRLF				; 
	TYPESP	Passes made:		; 
	MOV	PASSES(A5),D1		; 
	DCVT	0,OT$TRM		; 
	CRLF				; 
	TYPESP	Good passes:		; 
	MOV	GOOD(A5),D1		; 
	DCVT	0,OT$TRM		; 
	CRLF				; 
	TYPESP	Bad passes:		; 
	MOV	BAD(A5),D1		; 
	DCVT	0,OT$TRM		; 
	CRLF				; 
	CRLF				; 

;**********
;*  EXIT  *
;**********
;exit to AMOS command level

EXIT:	EXIT				; exit

;************
;*  REDSSD  *
;************
;Function:	Read codes from SSD
;
;Inputs:	D0 - SSD type code:
;			0 - Alpha Micro SSD
;			2 - Alpha Micro SSD on AM965 board
;		D2 - bytes to ignore count
;		D3 - bytes to return count
;		A2 - buffer address
;
;Outputs:	A2 - updated

	AMSSD1	=^H0FFFFFE00		; AM SSD at standard address
	AMSSD2	=^H0FFFFFFAA		; AM SSD on AM965 board

REDSSD:	SAVE	A0,D1-D4		; save registers
	CALL	SLOCK			; lock system			[106]
	MOV	#AMSSD1,A0		; 
	TSTW	D0			; at standard address?
	BEQ	RS.INI			;   yes
	MOV	#AMSSD2,A0		; 
RS.INI:	MOVB	#0,2(A0)		; initialize
	MOVB	#1,2(A0)		;   SSD
RS.IGN:	TST	D2			; ignore count zero?
	BEQ	RS.GET			;   yes
10$:	MOVB	@A0,D1			; get first byte from SSD
	SOB	D2,10$			; 
RS.GET:	TST	D3			; read count zero?
	BEQ	RS.CLR			;   yes
10$:	MOVB	@A0,(A2)+		; 
	SOB	D3,10$			; 
RS.CLR:	MOVB	#0,2(A0)		; reset SSD
RS.RTN:	CALL	SUNLOK			; unlock system			[106]
	REST	A0,D1-D4		; 
	RTN				; return

;***********
;*  SLOCK  *
;***********
;Function:	Lock system

SLOCK:
10$:	TST	DDBCHN			; 
	BEQ	20$			; 
	SLEEP	#10			; 
	BR	10$			; 
20$:	JLOCK				; 
	RTN				; 

;************
;*  SUNLOK  *
;************
;Function:	Unlock system

SUNLOK:	JUNLOK				; 
	RTN				; 

	END