PAGE 118,121
TITLE TEST6 ---- 06/10/85  POST TESTS AND SYSTEM BOOT STRAP
.286C
.LIST
CODE	SEGMENT	BYTE PUBLIC

	PUBLIC	BOOT_STRAP_1
	PUBLIC	POST6
	PUBLIC	STGTST_CNT
	PUBLIC	ROM_ERR
	PUBLIC 	XMIT_8042

	EXTRN	CMOS_READ:NEAR
	EXTRN	DDS:NEAR
	EXTRN	DISK_BASE:NEAR
	EXTRN	E602:NEAR
	EXTRN	ERR_BEEP:NEAR
	EXTRN	E_MSG:NEAR
	EXTRN	F3A:NEAR
	EXTRN	PRT_SEG:NEAR

	ASSUME	CS:CODE,DS:DATA

POST6	PROC	NEAR
;-----------------------------------------------------------------
; THIS SUBROUTINE PERFORMS A READ/WRITE STORAGE TEST ON A BLOCK	:
;	OF STORAGE.		:
; ENTRY REQUIREMENTS:		:
;	ES = ADDRESS OF STORAGE SEGMENT BEING TESTED	:
;	DS = ADDRESS OF STORAGE SEGMENT BEING TESTED	:
;	CX = WORD COUNT OF STORAGE BLOCK TO BE TESTED	:
; EXIT PARAMETERS:		:
;	ZERO FLAG = 0 IF STORAGE ERROR (DATA COMPARE OR PARITY	:
;	CHECK). AL=0 DENOTES A PARITY CHECK. ELSE AL=XOR'ED	:
;	BIT PATTERN OF THE EXPECTED DATA PATTERN VS THE ACTUAL	:
;	DATA READ.		:
; AX,BX,CX,DX,DI, AND SI ARE ALL DESTROYED.	:
;-----------------------------------------------------------------

STGTST_CNT	PROC	NEAR
	MOV	BX,CX		; SAVE WORD COUNT OF BLOCK TO TEST
	IN	AL,PORT_B
	OR	AL:RAM_PAR_OFF	; TOGGLE PARITY CHECK LATCHES
	OUT	PORT_B,AL	; TO RESET ANY PENDING ERROR
	AND	AL,RAM_PAR_ON
	OUT	PORT_B,AL

;-----	ROLL A BIT THROUGH THE FIRST WORD

	XOR	DX,DX		; CLEAR THE INITIAL DATA PATTERN
	MOV	CX,16		; ROLL 16 BIT POSITIONS
	SUB	DI,DI		; START AT BEGINNING OF BLOCK
	SUB	SI,SI		; INITIALIZE DESTINATION POINTER
	STC			; SET CARRY FLAG ON FOR FIRST BIT
C1:
	RCL	DX,1		; MOVE BIT OVER LEFT TO NEXT POSITION
	MOV	[DI],DX		; STORE DATA PATTERN
	MOV	AX,[DI]		; GET THE DATA WRITTEN
	XOR	AX,DX		; INSURE DATA AS EXPECTED [CLEAR CARRY)
	LOOPZ	C1		; LOOP TILL DONE OR ERROR

	JNZ	C13		; EXIT IF ERROR

;-----	CHECK CAS LINES FOR HIGH BYTE LOW BYTE

	MOV	DX,0FF00H	; TEST DATA - AX= 0000H
	MOV	[DI],AX		; STORE DATA PATTERN = 0000H
	MOV	[DI+1],AX	; WRITE A BYTE OF FFH AT ODD LOCATION
	MOV	AX,[DI]		; GET THE DATA - SHOULD BE 0FF00H
	XOR	AX,DX		; CHECK THE FIRST WRITTEN
	JNZ	C13		; ERROR EXIT IF NOT ZERO

	MOV	[DI],AX		; STORE DATA PATTERN OF 0000H
	MOV	[DI],DH		; WRITE A BYTE OF FFH AT EVEN LOCATION
	XCHG	DH,DL		; SET DX= 000FFH AND BUS SETTLE
	MOV	AX,[DI]		; GET THE DATA
	XOR	AX,DX		; CHECK THE FIRST WRITTEN
	JNZ	C13		; EXIT IF NOT

;-----	CHECK FOR I/O OR BASE MEMORY ERROR

	IN	AL,PORT_B	; CHECK FOR I/O - PARITY CHECK
	XCHG	AL,AH		; SAVE ERROR
	IN	AL,DMA_PAGE+6	; CHECK FOR RILL OR I/O ERROR
	AND	AH,AL		; MASK FOR ERROR EXPECTED

;-----	PARITY ERROR EXIT

	MOV	AX,0		; RESTORE AX TO 0000
	JNZ	C13		; EXIT IF PARITY ERROR

	MOV	DX,0AA55H	; WRITE THE INITIAL DATA PATTERN
C3:
	SUB	DI,DI		; START AT BEGINNING OF BLOCK
	SUB	SI,SI		; INITIALIZE DESTINATION POINTER
	MOV	CX,BX		; SETUP BYTE COUNT FOR LOOP
	MOV	AX,DX		; GET THE PATTERN
	REP	STOSW		; STORE 64K BYTES (32K WORDS)
	MOV	CX,BX		; SET COUNT
	SUB	SI,SI		; ART AT BEGINNING
C6:
	LODSW			; GET THE FIRST WRITTEN
	XOR	AX,DX		; INSURE DATA AS EXPECTED
	LOOPZ	C6		; LOOP TILL DONE OR ERROR

	JNZ	C13		; EXIT IF NOT EXPECTED (ERROR BITS ON)

;-----	CHECK FOR I/O OR BASE MEMORY ERROR

	IN	AL,PORT_B	; CHECK FOR I/O -PARITY CHECK
	XCHG	AL,AH		; SAVE ERROR
	IN	AL,DMA_PAGE+6	; CHECK FOR R/W OR I/O ERROR
	AND	AH,AL

;-----	PARITY ERROR EXIT

	MOV	AX,0		; RESTORE AX TO 0000
	JNZ	C13		; GO IF YES

;-----	CHECK FOR END OF 64K BLOCK

	AND	DX,DX		; ENDING ZERO PATTERN WRITTEN TO MEMORY?
	JZ	C13		; YES - RETURN TO CALLER WITH AL,0
	
;-----	SETUP NEXT PATTERN

	CMP	DX,055AAH	; CHECK IF LAST PATTERN =55AA
	JZ	C9		; GO IF NOT
	CMP	DX,0101H	; LAST PATTERN 0101?
	JZ	C10		; GO IF YES
	MOV	DX,055AAH	; WRITE 55AA TO STORAGE
	JMP	C3

;----- 	INSURE PARITY BITS ARE NOT STUCK ON

C9:	MOV	DX,0101H	; WRITE 0101 TO STORAGE
	JMP 	C3

;-----	EXIT STORAGE TEST
C13:
	RET			; ERROR IF ZF NOT SET

;-----	CHECKER BOARD TEST

C10:	SUB	DI,DI			; POINT TO START OF BLOCK
	MOV	CX,BX			; GET THE BLOCK COUNT
	SHR	CX,1			; DIVIDE BY 2
	MOV	AX,1010101010101010B	; SECOND CHECKER PATTERN
	MOV	SI,0101010101010101B	; FIRST CHECKER PATTERN
C11:
	XCHG	AX,SI			; FIRST CHECKER PATTERN TO AX
	STOSW				; WRITE IT TO MEMORY
	XCHG	AX,SI			; SECOND CHECKER PATTERN TO AX
	STOSW				; WRITE IT TO MEMORY
	LOOP	C11			; DO IT FOR CX COUNT

	SUB	SI,SI			; POINT TO START OF BLOCK
	MOV	CX,BX			; GET THE BLOCK COUNT
	SHR	CX,1			; DIVIDE BY 2
	MOV	DI,0101010101010101B	; CHECK CORRECT
	MOV	DX,1010101010101010B
C12:
	LODSW			; GET THE DATA
	XOR	AX,DI		; CHECK CORRECT
	JNZ	C13		; EXIT IF NOT

	LODSW			; GET NEXT DATA
	XOR	AX,DX		; CHECK SECOND PATTERN
	LOOPZ	C12		; CONTINUE TILL DONE

	JNZ	C13		; ERROR EXIT IF NOT CORRECT

;-----	CHECK FOR I/O OR BASE MEMORY PARITY CHECK

	IN	AL,PORT_B	; CHECK FOR	I/O-PARITY CHECK
	XCHG	AL,AH		; SAVE ERROR
	IN	AL,DMA_PAGE+6	; CHECK FOR R/W OR I/O ERROR
	AND	AH,AL

;-----	CHECKPOINT 32 FOR ADDRESS LINE 0->15 FAILURE
	MOY	AL,32H			;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; 	  <><> CHECKPOINT  32 <><>
	MOV	AX,0			; RESTORE AX (SET AX TO ZERO)
	JNZ	C13			; EXIT IF PARITY ERROR

;-----	64K ADDRESS TEST AND FILL WITH ZERO

	DEC	AX		; WRITE FIRST AND LAST LOCATION=FFFF
	SUB	DI,DI		; POINT TO START OF BLOCK
	MOV	CX,BX		; GET THE BLOCK COUNT
	SUB	CX,2		; DO ALL LOCATIONS BUT LAST
	STOSW			; WRITE FIRST LOCATION AS FFFFH
	INC	AX		; WRITE ZERO
	REP	STOSW		; WRITE IT
	DEC	AX		; LAST WORD IS FFFF
	STOSW
	SUB	SI,SI		; POINT TO START OF BLOCK
	MOV	CX		; GET THE BLOCK COUNT
	SUB	CX,2	
	LODSW			; GET THE DATA
	XOR	AX,0FFFFH	; CHECK CORRECT
	JNZ	C13		; EXIT IF NOT
C12A:
	LODSW			; GET NEXT DATA
	OR	AX,AX		; ANY BIT ON ?
	LOOPZ	C12A		; CONTINUE TILL LAST WORD
	JNZ	C13		; GO IF NOT CORRECT
	LODSW			; GET LAST WORD
	XOR	AX,0FFFFH	; S/B FFFF
	JNZ	C13		; EXIT IF NOT

;-----	CLEAR WORD 0 AND FFFE

	SUB	DI,DI		; CLEAR FIRST WORD
	STOSW
	MOV	DI,0FFFEH	; CLEAR TOP WORD
	STOSW

;----- 	CHECK FOR I/O OR BASE MEMORY

	IN	AL,PORT_B	; CHECK FOR I/O - PARITY CHECK
	XCHC	AL,AH		; SAVE ERROR
	IN	AL,DMA_PAGE+6	; CHECK FOR R/W OR I/O ERROR
	AND	AH,AL
	MOV	AX,0		; SET AX EQUAL ZERO
	JMP	C13		; ERROR EXIT IF ZF NOT SET
STGTST_CNT	ENDP

;------------------------------------------------------------------------
;  PRINT ADDRESS AND ERROR MESSAGE FOR ROM CHECKSUM ERRORS			:
;------------------------------------------------------------------------
ROM_ERR	PROC	NEAR
	PUSH	DX			; SAVE POINTER
	PUSH	ES
	PUSH	AX
	MOV	AX,DATA			; SET ES TO DATA SEGMENT
	MOV	ES,AX
	POP	AX			; RESTORE AX
	PUSH	AX
	MOV	DX,DS			; GET ADDRESS POINTER
	MOV	ES:@MFG_ERR_FLAG,DH	; 	  <><><><><><><><><><><><><><>
					;	  <><> CHECKPOINTS C0->F4 <><>
	CMP	DX,0C800H		; DISPLAY CARD IN ERROR?
	JL	ROM_ERR_BEEP		; GIVE DISPLAY CARD FAIL BEEP
	CALL	PRT_SEG			; PRINT SEGMENT IN ERROR
	MOV	SI,OFFSET F3A		; DISPLAY ERROR MESSAGE
	CALL	E_MSG
ROM_ERR_END:
	POP	AX
	POP	ES
	POP	DX
	RET
ROM_ERR_BEEP:
	MOV	DX,0102H		; BEEP 1 LONG, 2 SHORT
	CALL	ERR_BEEP
	JMP	SHORT ROM_ERR_END
ROM_ERR 	ENDP

;------------------------------------------------------------------
; THIS SUBROUTINE SENDS AN OUTPUT COMMAND TO THE KEYBOARD AND	:
;	RECEIVES THE KEYBOARD RESPONSE.		:
; ENTRY REQUIREMENTS:		:
;	AL = COMMAND/DATA TO BE SENT		:
; EXIT PARAMETERS:		:
;	ZERO FLAG = 1 IF ACK RECEIVED FROM THE KEY BOARD	:
;	AL = RESPONSE		:
;------------------------------------------------------------------

XMIT_8042 PROC	NEAR

;-----	CHECK INPUT BUFFER FULL

	XCHG	AH,AL			; SAVE COMMAND
	SUB	CX,CX			; SET LOOP TIME-OUT
XMITLOOP:
	IN	AL,STATUS_PORT
	TEST	AL,INPT_BUF_FULL	; CHECK INPUT BUFFER FULL
	LOOPNZ	XMITLOOP
	JCXZ	SHORT XMIT_EXIT
	XCHG	AH,AL			; RESTORE COMMAND

;-----	ISSUE THE COMMAND

	OUT	PORT_A,AL		; SEND THE COMMAND
	SUB	CX,CX			; SET LOOP COUNT

;-----	CHECK OUTPUT BUFFER FULL

XMIT_1:	IN	AL,STATUS_PORT
	MOV	AH,AL			; SAVE STATUS
	TEST	AL,OUT_BUF_FULL		; CHECK IF 8042 HAS DATA
	JZ	XMIT_2			; GO IF NOT
	IN	AL,PORT_A		; FLUSH DATA
XMIT_2:	TEST	AH,INPT_BUF_FULL	; CHECK COMMAND ACCEPTED
	LOOPNZ	XMIT_1
	JNZ	SHORT XMIT_EXIT		; NO FLUSH OR COMMAND NOT ACCEPTED

;-----	CHECK OUTPUT BUFFER FULL

	MOV	BL,6			; SET COUNT
	SUB	CX,CX			; SET LOOP COUNT
XMIT_3:	IN	AL,STATUS_PORT
	TEST	AL,OUT_BUF_PULL		; CHECK IF HAS DATA
	LOOPZ	XMIT_3			; WAIT TILL DONE
	JNZ	XMIT_4
	DEC	BL			; DECREMENT OUTER LOOP
	JNZ	SHORT XMIT_3		; TRY AGAIN
	INC	BL			; SET ERROR FLAG
	JMP	SHORT XMIT_EXIT		; 8042 STUCK BUSY

;-----	GET THE DATA

XMIT_4:	SUB	CX,CX			; ALLOW TIME FOR POSSIBLE
					; ERROR -> SYSTEM UNIT OR KEYBOARD
XMIT_5:	LOOP	XMIT_5
	IN	AL,PORT_A
	SUB	CX,01H			; SET CX OTHER THAN ZERO
XMIT_EXIT:
	RET
XMIT_8042 ENDP

;--- BOOT_STRAP - INT  19H ----------------------------
; BOOT STRAP LOADER		:
;	TRACK 0, SECTOR 1 IS READ INTO THE	:
;	BOOT LOCATION (SEGMENT 0 OFFSET 7C00)	:
;	AND CONTROL IS TRANSFERRED THERE.	:
;				:
;	IF THERE IS A HARDWARE ERROR CONTROL IS	:
;	TRANSFERRED TO THE ROM BASIC ENTRY POINT	:
;------------------------------------------------------
	ASSUME CS:CODE,DS:ABS0,ES:ABS0

BOOT_STRAP_1	PROC 	NEAR

	MOV	AX,ABS0			; ESTABLISH ADDRESSING
	MOV	DS,AX
	MOV 	ES,AX

;-----	RESET THE DISK PARAMETER TABLE VECTOR

	MOV	WORD PTR @DISK_POINTER, OFFSET DISK_BASE
	MOV	WORD PTR @DISK_POINTER+2,CS

;-----	CLEAR @BOOT_LOCN

	XOR	AX,AX
	MOV	CX,256			; CLEAR 256 WORDS
	MAY	DI,OFFSET @BOOT_LOCN
	REP	STOSW

;-----	LOAD SYSTEM FROM DISKETTE -- CX HAS RETRY COUNT

	STI
	MOV	CX,4			; SET RETRY COUNT
H1:	PUSH	CX			; IPL SYSTEM
	KTOV	AH,0			; RESET THE DISKETTE SYSTEM
	INT	13H			; DISKETTE_IO
	JC	H2			; IF ERROR, TRY AGAIN

	MOV	AX,201H			; READ IN THE SINGLE SECTOR
	SUB	DX,DX			; TO THE BOOT LOCATION
	MOV	ES,DX
	MOV	SX,OFFSET @BOOT_LOCN	; DRIVE 0, HEAD 0
	MOV	CX,1			; SECTOR 1, TRACK 0
	INT	13H			; DISKETTE_IO
H2:	POP	CX			; RECOVER RETRY COUNT
	JNC	H4			; CARRY FLAG SET BY UNSUCCESSFUL READ
	CMP	AH,80H			; IF TIME OUT, NO RETRY
	JZ	H5			; TRY FIXED DISK
	LOOP	H1			; DO IT FOR RETRY TIMES
	JMP	SHORT H5		; TRY FIXED DISK

;-----	BOOT RECORD READ SUCCESSFUL
;-----	INSURE FIRST BYTE OF LOADED BOOT RECORD IS VALID (NOT ZERO)

H4:	CMP	BYTE PTR @BOOT_LOCN,06H	; CHECK FOR FIRST INSTRUCTION INVALID
	JB	H10			; IF BOOT NOT VALID PRINT MESSAGE HALT

;-----	INSURE DATA PATTERN FIRST 8 WORDS NOT ALL EQUAL

	MOV	DI,OFFSET @BOOT_LOCN	; CHECK DATA PATTERN
	MOV	CX,8			; CHECK THE NEXT 8 WORDS
	MOV	AX,WORD PTR @BOOT_LOCN

H4A:	ADD	DI,2			; POINT TO NEXT LOCATION
	CMP	AX,[DI]			; CHECK DATA PATTERN FOR A FILL PATTERN
	LOOPZ	H4A
	JZ	H10			; BOOT NOT VALID PRINT MESSAGE HALT

H4_A:	JMP	@BOOT_LOCN

;----- 	ATTEMPT BOOTSTRAP FROM FIXED DISK

H5:	MOV	AL,044H			;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	  <><> CHECKPOINT  44 <><>
	ASSUME	DS:DATA
	CALL	DDS
	TEST	@LASTRATE,DUAL		; FLOPPY/FIXED DISK CARD INSTALLED
	ASSUME	DS:ABS0
	MOV	AX,ABS0			; ESTABLISH ADDRESSING
	MOV	DS,AX
	JZ	H9			; GO IF NOT

;-----	CHECK FOR FIXED DISK INITIALIZATION ERROR
	
	MOV	AL,CMOS_DIAG		; GET POST POWER ON STATUS (NMI ENABLED)
	CALL	CMOS_READ		; FROM DIAGNOSTIC STATUS BYTE
	TEST	AL,HF_FAIL		; DID WE HAVE A FIXED DISK FAILURE?
	JNZ	H9			; GO IF YES

	SUB	AX,AX			; RESET DISKETTE
	SUB	DX,DX
	INT	13H
	MOV	CX,3			; RETRY COUNT
H6:
	PUSH	CX			; SAVE RETRY COUNT
	MOV	DX,0080H		; FIXED DISK ZERO
	MOV	AX,0201H		; READ IN A SINGLE SECTOR
	SUB	BX,BX
	MOV	ES,BX
	MOV	BX,OFFSET @BOOT_LOCN	; TO THE BOOT LOCATION
	MOV	CX,1			; SECTOR 1, TRACK 0
	INT	13H			; FILE I/O CALL
	POP	CX			; RECOVER RETRY COUNT
	JC	H8
	CMP	WORD PTR @BOOT_LOCN+510D,0AA55H ; TEST FOR GENERIC BOOT BLOCK
	JZ	H4_A

H8:	PUSH	CX
	MOV	DX,0080H		; FIXED DISK ZERO
	SUB	AX,AX			; RESET THE FIXED DISK
	INT	13H			; FILE I/O CALL
	POP	CX			; RESTORE LOOP COUNT
	JC	H10A			; IF ERROR, TRY AGAIN
	LOOP	H6			; DO IT FOR RETRY TIMES

;-----	UNABLE TO IPL FROM THE DISKETTE OR FIXED DISK

H9:	MOV	AL,045H			;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;	  <><> CHECKPOINT  45 <><>

	INT	18H			; GO TO RESIDENT BASIC

;----- 	HARD FILE RESET FAILURE

H10A:	LOOP	H8			; TRY RESET AGAIN
	JMP	H9			; GO TO RESIDENT BASIC

;----- 	IF DISKETTE READ OK BUT BOOT RECORD IS NOT STOP SYSTEM ALLOW SOFT RESET

H10:	MOV	SI,OFFSET E602		; PRINT DISKETTE BOOT
	CALL	E_MSG			; PRINT MESSAGE
H11:	JMP	H11
BOOT_STRAP_1	ENDP
POST6	ENDP
CODE	ENDS
	END
