TITLE	TEST1 ---- 06/10/85  POWER ON SELF TEST (POST)

CODE	SEGMENT	WORD PUBLIC

	PUBLIC	C8042
	PUBLIC	OBF_42
	PUBLIC	POST1
	PUBLIC	START_1

	EXTRN	CMOS_READ:NEAR
	EXTRN	CMOS_WRITE:NEAR
	EXTRN	CONFIG_BAD:NEAR
	EXTRN	D11:NEAR
	EXTRN	DDS:NEAR
	EXTRN	DUMMY_RETURN:NEAR
	EXTRN	ERR_BEEP:NEAR
	EXTRN	GATE_A20:NEAR
	EXTRN	KBD_RESET:NEAR
	EXTAN	NMI_INT:NEAR
	EXTRN	POST2:NEAR
	EXTRN	PRINT_SCREEN:NEAR
	EXTRN	PROC_SHUTDOWN:NEAR
	EXTRN	ROM_CHECK:NEAR
	EXTRN	SHUT2:NEAR
	EXTRN	SHUT3:NEAR
	EXTRN	SHUT4:NEAR
	EXTRN	SHUT6:NEAR
	EXTRN	SHUT7:NEAR
	EXTRN	SHUT9:NEAR
	EXTRN	SLAVE_VECTOR_TABLE:NEAR
	EXTRN	STGTST_CNT:NEAR
	EXTRN	SYSINIT1:NEAR
	EXTRN	VECTOR_TABLE:NEAR
	EXTRN	VIDEO_PARMS:BYTE

	ASSUME	CS:CODE,DS:NOTHING,ES:NOTHING,SS:NOTHING

POST1	PROC	NEAR

BEGIN	EQU	$
	DB	'6480090COPR. IBM CORP. 1981,1985  '		;COPYRIGHT NOTICE
	EVEN						;EVEN BOUNDARY
	;	 6 4 8 0 0 9 0   C O P R .   I B M   1 9 8 5	;EVEN MODULE
	;	  6 4 8 0 0 9 1   C O P R .   I B M   1 9 8 5	;ODD  MODULE
	DB	'66448800009901  CCOOPPRR..  IIBBMM  11998855'	;COPYRIGHT NOTICE
	DB	'  '					;PAD

;-------------------------------------------------
;	INITIAL RELIABILITY TESTS -- (POST1)    :
;-------------------------------------------------

;------------------------------------------
;  TEST.01		:
;       80286 PROCESSOR TEST (REAL MODE)	:
;  DESCRIPTION		:
;	VERIFY FLAGS, REGISTERS	:
;	AND CONDITIONAL JUMPS.	:
;------------------------------------------

	ASSUME	DS:DATA

START_1:	CLI		; DISABLE INTERRUPTS
	MOV	AX,0D500H+CMOS_REG_D+NMI	; FLAG MASK IN (AH) AND NMI MASK IN (AL)
	OUT	CMOS_PORT,AL	; DISABLE NMI INTERRUPTS
	SAHF		; SET "SF" "ZF" "AF" "PF" "CF" FLAGS ON
	JNC	ERR02	; GO TO ERROR ROUTINE IF "CF" NOT SET
	JNZ	ERR02	; GO TO ERROR ROUTINE IF "ZF" NOT SET
	JNP	ERR02	; GO TO ERROR ROUTINE IF "PF" NOT SET
	JNS	ERR02	; GO TO ERROR ROUTINE IF "SF" NOT SET
	LAHF		; LOAD FLAG IMAGE TO (AH)
	MOV	CL,5	; LOAD COUNT REGISTER WITH SHIFT COUNT
	SHR	AH,CL	; SHIFT *AF" INTO CARRY BIT POSITION
	JNC	ERR02	; GO TO ERROR ROUTINE IF *AF" NOT SET
	MOV	AL,40H	; SET THE *OF" FLAG ON
	SHL	AL,1	; SETUP FOR TESTING
	JNO	ERR02	; GO TO ERROR ROUTINE IF *OF" NOT SET
	XOR	AH,AH	; SET (AH) = 0
	SAHF		; CLEAR "SF*, "CF", "ZF", AND "PF"
	JBE	EM02	; GO TO ERROR ROUTINE IF *CF* ON
			; GO TO ERROR ROUTINE IF "ZF" ON
	JS	ERR02	; GO TO ERROR ROUTINE IF *SF* ON
	JP	ERR02	; GO TO ERROR ROUTINE IF "PF" ON
	LAHF		; LOAD FLAG IMAGE TO (AH)
	SHR	AH,CL	; SHIFT *AF" INTO CARRY BIT POSITION
	JC	ERR02	; GO TO ERROR ROUTINE IF ON
	SHL	AH,1	; CHECK THAT "OF" IS CLEAR
	JO	ERR02	; GO TO ERROR ROUTINE IF ON
	JZ	VA	; CONTINUE CONFIDENCE TESTS IF *ZF" SET
ERR02:
	HLT		; ERROR HALT
	JMP	ERR02	; ERROR LOOP TRAP
C7A:
	MOV	AX,DATA	; SET DATA SEGMENT
	MOV	DS,AX	; INTO THE (DS) SEGMENT REGISTER

;-----	CHECK FOR PROCESSOR SHUTDOWN
	IN	AL,STATUS_PORT	; READ CURRENT KEYBOARD PROCESSOR STATUS
	TEST	AL,SYS_FLAG	; CHECK FOR SHUTDOWN IN PROCESS FLAG
	JNZ	C7B	; GO IF YES
	JMP	SHUT0	; USE CONTINUE NORMAL POWER ON CODE

;----- CHECK FOR SHUTDOWN 09
C7B:
	MOV	AL,CMOS_SHUT_DOWN+NNI	; CMOS ADDRESS FOR SHUTDOWN BYTE
	OUT	CMOS_PORT,AL
	JMP	$+2	; I/O DELAY
	IN	AL,CMCS_DATA	; GET REQUEST NUMBER
	CMP	AL,09H	; WAS IT SHUTDOWN REQUEST 9?
	XCHG	AL,AH	; SAVE THE SHUTDOWN REQUEST
	JE	C7C	; BYPASS INITIALIZING INTERRUPT CHIPS

;----- CHECK FOR SHUTDOWN 0A
	CMP	AH,0AH	; WAS IT SHUTDOWN REQUEST A?
	JE	C7C	; BYPASS INITIALIZING INTERRUPT CHIPS
	SUB	AL,AL	; INSURE MATH PROCESSOR RESET
	OUT	X287+1,AL

;---------------------------------------------------------
;    RE-INITIALIZE THE 8259 INTERRUPT #1 CONTROLLER CHIP :
;---------------------------------------------------------
	MOV	AL,11H	; ICW1 - EDGE, MASTER, ICW4
	OUT	INTA00,AL
	JMP	$+2	; WAIT STATE FOR I/O
	MOV	AL,08H	; SETUP ICW2 - INTERRUPT TYPE 8H (8-F)
	OUT	INTA01,AL
	JMP	$+2	; WAIT STATE FOR I/O
	MOV	AL,04H	; SETUP ICW3 - MASTER LEVEL 2
	OUT	INTA01,AL
	JMP	$+2	; I/O WAIT STATE
	MOV	AL,01H	; SETUP ICW4 - MASTER,8086 MODE
	OUT	INTA01,AL
	JMP	$+2	; WAIT STATE FOR I/O
	MOV	AL,0FFH	; MASK ALL INTERRUPTS OFF
	OUT	INTA01,AL	; (VIDEO ROUTINE ENABLES INTERRUPTS)
;---------------------------------------------------------
;    RE-INITIALIZE THE 8259 INTERRUPT #2 CONTROLLER CHIP  :
;---------------------------------------------------------
	MOV	AL,11H	; ICW1 - EDGE, SLAVE ICW4
	OUT	INTB00,AL
	JMP	$+2	; WAIT STATE FOR I/O
	MOV	AL,INT_TYPE	; SETUP ICW2 - INTERRUPT TYPE 70 (70-7F)
	OUT	INTB01,AL
	MOV	AL,02H	; SETUP ICW3 - SLAVE LEVEL 2
	JMP	$+2
	OUT	INTB01,AL
	JMP	$+2	; I/O DELAY
	MOV	AL,01H	; SETUP ICW4 - 8086 MODE, SLAVE
	OUT	INTB01,AL
	JMP	$+2	; WAIT STATE FOR I/O
	MOV	AL,0FFH	; MASK ALL INTERRUPTS OFF
	OUT	INTB01,AL
;--------------------------------------------------------------------------------
;  SHUTDOWN - RESTART							  :
;	RETURN CONTROL AFTER A SHUTDOWN COMMAND IS ISSUED				  :
;  DESCRIPTION								  :
;	A TEST IS MADE FOR THE SYSTEM FLAG BEING SET.  IF THE SYSTEM FLAG IS   :
;	SET, THE SHUTDOWN BYTE IN CMOS IS USED TO DETERMINE WHERE CONTROL IS	  :
;	RETURNED.							  :
;									  :
;	CMOS = 0   SOFT RESET OR UNEXPECTED SHUTDOWN					  :
;	CMOS = 1   SHUT DOWN AFTER MEMORY SIZE						  :
;	CMOS = 2   SHUT DOWN AFTER MEMORY TEST						  :
;	CMOS = 3   SHUT DOWN WITH MEMORY ERROR						  :
;	CMOS = 4   SHUT DOWN WITH BOOT LOADER REQUEST				  :
;	CMOS = 5   JMP DWORD REQUEST - (INTERRUPT CHIPS & 287 ARE INITIALIZED) :
;	CMOS = 6   PROTECTED MODE TEST3 PASSED						  :
;	CMOS = 7   PROTECTED MODE TEST3 FAILED						  :
;	CMOS = 8   PROTECTED MODE TEST1 FAILED						  :
;	CMOS = 9   BLOCK MOVE SHUTDOWN REQUEST						  :
;	CMOS = A   JMP DWORD REQUEST - (W/O INTERRUPT CHIPS INITIALIZED)	  :
;									  :
;	   NOTES:  RETURNS ARE MADE WITH INTERRUPTS AND NMI DISABLED.		  :
;		USER MUST RESTORE SS:SP (POST DEFAULT SET = 0000:0400),	  :
;		ENABLE NON-MASKABLE INTERRUPTS (NMI) WITH AN OUT TO		  :
;		PORT 70H WITH HIGH ORDER BIT OFF, AND THEN ISSUE A		  :
;		STI TO ENABLE INTERRUPTS. FOR SHUTDOWN (5) THE USER		  :
;		MUST ALSO RESTORE THE INTERRUPT MASK REGISTERS.		  :
;--------------------------------------------------------------------------------

;-----	CHECK FROM WHERE
C7C:
	MOV	AL,CMOS_SHUT_DOWN+NMI	; CLEAR CMOS BYTE
	OUT	CMOS_PORT,AL
	NOP		; I/0 DELAY
	SUB	AL,AL	; SET BYTE TO 0
	OUT	CMOS_DATA,AL
	XCHG	AH,AL
	CMP	AL,0AH	; COMPARE WITH MAXIMUM TABLE ENTRIES
	JA	SHUT0	; SKIP TO POST IF GREATER THAN MAXIMUM
	MOV	SI,OFFSET BRANCH	; POINT TO THE START OF THE BRANCH T 
	ADD	SI,AX
	ADD	SI,AX	; POINT TO BRANCH ADDRESS
	MOV	BX,CS:[SI]	; MOVE BRANCH TO ADDRESS TO BX REGISTER

;----- SET TEMPORARY STACK FOR POST
	MOV	AX,ABS0	; SET STACK SEGMENT TO ABS0 SEGMENT
	MOV	SS,AX
	MOV	SP,OFFSET @TOS	; SET STACK POINTER TO END OF VECTORS
	JMP	BX	; JUMP BACK TO RETURN ROUTINE

BRANCH:	DW	SHUT0	; NORMAL POWER UP/UNEXPECTED SHUTDOWN
	DW	SHUT1	; SHUT DOWN AFTER MEMORY SIZE
	DW	SHUT2	; SHUT DOWN AFTER MEMORY TEST
	DW	SHUT3	; SHUT DOWN WITH MEMORY ERROR
	DW	SHUT4	; SHUT DOWN WITH BOOT LOADER REQUEST
	DW	SHUT5	; JMP DWORD REQUEST WTTH INTERRUPT INIT
	DW	SHUT6	; PROTECTED MODE TEST7 PASSED
	DW	SHUT7	; PROTECTED MODE TEST7 FAILED
	DW	SHUT8	; PROTECTED MODE TEST1 FAILED
	DW	SHUT9	; BLOCK MOVE SHUTDOWN REQUEST
	DW	SHUTA	; JMP DWORD REQUEST (W/O INTERRUPT INIT)

;----- @IO_ROM_INIT MUST BE INITIALIZED BY THE USER FOR VECTORED REQUESTS
SHUT5:
	IN	AL,PORT_A	; FLUSH THE KEYBOARD BUFFER
	MOV	AL,EOI	; FLUSH LAST TIMER REQUEST IF PENDING
	OUT	INTA00,AL	; TO ALLOW TIMER INTERRUPTS
SHUTA:
	JMP	DWORD PTR @IO_ROM_INIT	; FAR JUMP TO USER DEFINED LOCATION
			;  AFTER SHUTDOWN TO REAL MODE CODE
			;  WITH INTERRUPTS AND NMI DISABLED
;----- CHECKPOINT 01

SHUT0:
	MOV	AL,01H	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	;	  <><> CHECKPOINT	 01 <><>

;----- READ/WRITE/TEST THE 80286 REGISTERS WITH ONE'S AND ZERO'S
	MOV	AX,0FFFFH	; SETUP ONE*S PATTERN IN (AX)
	STC		; SET CARRY FLAG
	JNC	ERR01	; GO IF NO CARRY
C8:
	MOV	DS,AX	; WRITE PATTERN TO ALL REGISTERS
	MOV	BX,DS
	MOV	ES,BX
	MOV	CX,ES
	MOV	SS,CX
	MOV	DX,SS
	MOV	SP,DX
	MOV	BP,SP
	MOV	SI,BP
	MOV	DI,SI
	JNC	C9
	XOR	AX,DI	; PATTERN MAKE IT THROUGH ALL REGISTERS
	JNZ	ERR01	; NO - GO TO ERROR ROUTINE
	CLC		; CLEAR CARRY FLAG

C9:			; TST1A
	OR	AX,01	; ZERO PATTERN MAKE IT THROUGH ?
	JZ	C10A	; YES - GO TO NEXT TEST
ERR01:
	HLT		; HALT SYSTEM

;----- INSURE THAT CMOS CLOCK INTERRUPTS ARE DISABLED
C10A:
	MOV	AX,X*(CMOS_REG_B+NMI)	; ADDRESS TO BOTH (AH) AND (AL)
	OUT	CMOS_PORT,AL	; ADDRESS CMOS ALARM BYTE WITH NMI=OFF
	NOP		; I/O DELAY
	IN	AL,CMOS_DATA	; GET THE CURRENT CONTROL REGISTER
	AND	AL,00000111B	; CLEAR SET,PIE,AIE, AND SQWE BITS
	XCHG	AL,AH	; SAVE IT
	OUT	CMOS_PORT,AL
	XCHG	AL,AH
	OUT	CMOS_DATA,AL

	MOV	AL,CMOS_REG_C+NMI	; ADDRESS CMOS FLAGS BYTE WITH NMI=OFF
	NOP		; I/O DELAY
	OUT	CMOS_PORT,AL
	NOP		; I/O DELAY
	IN	AL,CMOS_DATA	; READ STATUS TO CLEAR PENDING INTERRUPT

;----- RESET VIDEO
	MOV	AL,0	; CLEAR DATA BYTE TO DISABLE VIDEO
	MOV	DX,03D8H	; GET COLOR MODE CONTROL PORT ADDRESS
	OUT	DX,AL	; DISABLE COLOR VIDEO
	INC	AL	; MONOCHROME MODE RESET MASK
	MOV	DL,0B8H	; GET ADDRESS OF MONOCHROME MODE CONTROL
	OUT	DX,AL	; DISABLE B/W VIDEO, ENABLE HIGH RES
	MOV	DL,0BAH	; ADDRESS OF MONOCHROME STATUS REGISTER
	IN	AL,DX	; READ STATUS TO DISABLE EGA VIDEO
	MOV	DL,0DAH	; ADDRESS OF COLOR MODE STATUS REGISTER
	IN	AL,DX	; READ STATUS TO DISABLE EGA VIDEO
	MOV	AL,0	; SELECT ATTRIBUTE PALETTE REGISTER 0
	MOV	DL,0C0H	; WRITE 0 TO ATTRIBUTE ADDRESS REGISTER
	OUT	DX,AL	; TO DISABLE EGA VIDEO
	MOV	AL,11111100B	; DISABLE PARITY CHECKERS
	OUT	PORT_B,AL

;------------------------------------------
; TEST.02		:
;	ROM CHECKSUM TEST 1	:
; DESCRIPTION		:
;	A CHECKSUM IS DONE FOR THE 32K	:
;	READ ONLY MEMORY MODULES (TWO)	:
;	CONTAINING POST, BASIC AND BIOS.	:
;------------------------------------------

;-----	CHECKPOINT 02
	MOV	AL,02H	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	;	  <><>  CHECKPOINT 02 <><>
	
	ASSUME	SS:CODE
	MOV	AX,CS	; SETUP SS SEGMENT REGISTER
	MOV	SS,AX
	MOV	DS,AX	; SET UP DATA SEGMENT TO POINT TO
	XOR	SI,SI	; ROM ADDRESS START
	XOR	BX,BX	; CLEAR CHECK REGISTER
	MOV	CH,080H	; COUNT FOR 32K WORDS
C11:
	LODSW		; MOVE TWO BYTES INTO AX - SI=SI+2
	ADD	BL,AH	; ADD ODD BYTE AT DS:SI+1 TO CHECKSUM
	ADD	BL,AL	; ADD EVEN BYTE AT DS:SI TO CHECKSUM
	LOOP	C11	; LOOP COUNT FOR 65K BYTES (32K WORDS)
	JC	C11E	;  EXIT IF "LOOP* RESET THE CARRY FLAG
			;  (NOTE: MODEL BYTE MUST NOT = ZERO)
	JZ	C11A	; CONTINUE IF CHECKSUM VALID (ZERO)
C11E:
	HLT		; ELSE HALT IF CHECKSUM PROBLEM

;------------------------------------------
; TEST.03		:
;	VERIFY CMOS SHUTDOWN BYTE	:
; DESCRIPTION		:
;	ROLLING BIT WRITTEN AND	:
;	VERIFIED AT SHUTDOWN ADDRESS.	:
;------------------------------------------

;-----	VERIFY AND CLEAR SHUTDOWN FLAG
C11A:
	MOV	AL,03H	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	;	  <><> CHECKPOINT  03 <><>

	MOV	CX,09H	; LOOP COUNT
	MOV	AH,1	; START WITH BIT 0
C11B:
	MOV	AL,CMOS_SHUT_DOWN+NMI
	OUT	CMOS_PORT,AL
	MOV	AL,AH	; OUTPUT ROLLING BIT
	OUT	CMOS_DATA,AL
	MOV	AL,CMOS_SHUT_DOWN+NMI	; READ CMOS
	NOP		; I/O DELAY
	OUT	CMOS_PORT,AL
	NOP		; I/O DELAY
	IN	AL,CMOS_DATA
	CMP	AL,AH	; MUST BE THE SAME
	JNZ	ERR01	; ERROR IF NOT
	RCL	AH,1	; ROLL A BIT THROUGH SHUTDOWN BYTE
	LOOP	C11B	; LOOP TILL DONE

;------------------------------------------
; TEST.04		:
;	8254 CHECK TIMER 1 ALL BITS ON	:
; DESCRIPTION		:
;	SET TIMER COUNT	:
;	CHECK THAT TIMER 1 ALL BITS ON	:
;------------------------------------------
	ASSUME	DS:DATA
	MOV	AX,DATA	; SET DATA SEGMENT
	MOV	DS,AX
	MOV	AL,04H	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	;	  <><> CHECKPOINT  04 <><>

;-----	DISABLE DMA CONTROLLER
			; (AL) ALREADY = 04H
	OUT	DMA08,AL	; DISABLE DMA CONTROLLER 1
	OUT	DMA18,AL	; DISABLE DMA CONTROLLER 2

;-----	VERIFY THAT TIMER 1 FUNCTIONS OK

	MOV	DX,@RESET_FLAG	; SAVE RESET FLAG WHILE REFRESH IS OFF
	MOV	AL,54H	; SELECT TIMER 1,LSB,MODE 2
	OUT	TIMER+3,AL
	JMP	$+2	; I/O DELAY
	MOV	AL,CL	; SET INITIAL TIMER COUNT TO 0
	OUT	TIMER+1,AL
	MOV	BH,05H	; LOOP COUNT
C12:			; TIMER1_BITS_ON
	MOV	AL,40H	; LATCH TIMER 1 COUNT
	JMP	$+2	; I/O DELAY
	OUT	TIMER+3,AL
	CMP	BL,0FFH	; YES - SEE IF ALL BITS GO OFF
	JE	C13	; TIMER1_BITS_OFF
	IN	AL,TIMER+1	; READ TTMER 1 COUNT
	OR	BL,AL	; ALL BITS ON IN TIMER
	LOOP	C12	; TIMER1_BITS_ON
	DEC	BH
	JNZ	C12	; TRY AGAIN
	HLT		; TIMER 1 FAILURE, HALT SYSTEM
			; TIMER1_BITS_OFF

;------------------------------------------
; TEST.05		:
;	8254 CHECK TIMER 1 ALL BIT OFF	:
; DESCRIPTION		:
;	SET TIMER COUNT	:
;	CHECK THAT TIMER 1 ALL BITS OFF	:
;------------------------------------------

;-----	CHECKPOINT 05

C13:	MOV	AL,05H	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	;	  <><>  CHECKPOINT 05 <><>

	MOV	AL,BL	; SET TIMER 1 COUNT
	SUB	CX,CX
	OUT	TIMER+1,AL
	MOV	BH,05H	; SET TRY AGAIN COUNT
C14:			; TIMER_LOOP
	MOV	AL,40H	; LATCH TIMER 1 COUNT
	OUT	TIMER+3,AL
	JMP	$+2	; DELAY FOR TIMER
	JMP	$+2	; ADDED DELAY FOR TIMER
	IN	AL,TIMER+1	; READ TIMER 1 COUNT
	AND	BL,AL
	JZ	C15	; GO TO WRAP DMA REGISTER TESTS
	LOOP	C14	; TIMER_LOOP
	DEC	BH
	JNZ	C14
	HLT		; HALT SYSTEM

;------------------------------------------
; TEST.06		:
;	8237 DMA 0 INITIALIZATION	:
;	CHANNEL REGISTER TEST	:
; DESCRIPTION		:
;	DISABLE THE 8237 DMA CONTROLLER.	:
;	WRITE/READ THE CURRENT ADDRESS	:
;	AND WORD COUNT REGISTERS FOR	:
;	ALL CHANNELS.	:
;------------------------------------------

;-----	CHECKPOINT 06

C15:
	MOV	AX,DATA	; SET DATA SEGMENT
	MOV 	DS,AX
	MOV	AL,06H	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	; 	  <><> CHECKPOINT  06 <><>
	MOV	@RESET_FLAG,DX	; RESTORE SOFT RESET FLAG
	OUT	DMA+0DH,AL	; SEND MASTER CLEAR TO DMA

;-----	WRAP DMA 0 CHANNEL ADDRESS AND COUNT REGISTERS

	MOV	AL,0FFH	; WRITE PATTERN *FF* TO ALL REGISTERS
C16:	MOV	BL,AL	; SAVE PATTERN FOR COMPARE
	MOV	BH,AL
	MOV	CX,8	; SETUP LOOP COUNT
	MOV	DX,DMA	; SETUP I/O PORT ADDRESS OF REGISTER
C17:	OUT	DX,AL	; WRITE PATTERN TO REGISTER, LSB
	JMP	$+2	; I/O DELAY
	OUT	DX,AL	; MSB OF 16 BIT REGISTER
	MOV	AL,01H	; AL TO ANOTHER PATTERN BEFORE READ
	JMP	$+2	; I/O DELAY
	IN	AL,DX	; READ 16-BIT DMA CH REG, LSB 2ST DMA
	JMP	$+2	; I/O DELAY
	MOV	AH,AL	; SAVE LSB OF 16-BIT REGISTER
	IN	AL,DX	; READ MSB OF DMA CHANNEL REGISTER
	CMP	AX,AX	; PATTERN READ AS WRITTEN?
	JE	C18	; YES	- CHECK NEXT REGISTER
	HLT		; NO - HALT THE SYSTEM
C18:			; NXT_DMA_CH
	INC	DX	; SET I/O PORT TO NEXT CHANNEL REGISTER
	LOOP	C17	; WRITE PATTERN TO NEXT REGISTER
	INC	AL	; SET PATTERN TO 0
	JZ	C16	; YES CONTINUE

;-----	WRITE DMA WITH 55 PATTERN

	CMP	BL,055H	; CHECK IF "55" PATTERN DONE
	JZ	C19	; GO IF YES
	CMP	BL,0AAH	; CHECK IF "AA" PATTERN DONE
	JZ	C20	; GO IF YES
	MOV	AL,055H
	JMP	C16

;-----	WRITE DWA WITH AA PATTERN
C19:	MOV	AL,0AAH
	JMP	C16

;------------------------------------------
; TEST.07		:
;	8237 DMA 1 INITIALIZATION	:
;	CHANNEL REGISTER TEST	:
; DESCRIPTION		:
;	DISABLE 8237 DMA CONTROLLER 1.	:
;	WRITE/READ THE CURRENT DMA 1	:
;	ADDRESS AND WORD COUNT	:
;	REGISTERS FOR ALL CHANNELS.	:
;------------------------------------------

;-----	CHECKPOINT 07 - DMA 1
C20:	MOV	AL,07H	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	;	  <><> CHECKPOINT  07 <><>
	OUT	DMA1+0D*2,AL	; SEND MASTER CLEAR TO 2ND DMA

;----- 	WRAP DMA 1 CHANNEL ADDRESS AND COUNT REGISTERS

	MOV	AL,OFFH	; WRITE PATTERN FF TO ALL REGISTERS
C16A:	MOV	BL,AL	; SAVE PATTERN FOR COMPARE
	MOV	SH,AL
	MOV	CX,8	; SETUP LOOP COUNT
	MOV	DX,OMAL	; SETUP I/O PORT ADDRESS OF REGISTER
C17A:	OUT	DX,AL	; WRITE PATTERN TO REGISTER, LSB
	JMP	$+2	; I/O DELAY
	OUT	DX,AL	; MSB OF 16 BIT REGISTER
	MOV	AL,OIH	; AL TO ANOTHER PAT BEFORE RD
	JMP	$+2	; I/O DELAY
	IN	AL,DX	; READ 16-BIT DMA CH REG, LSB 2ST DMA
	JMP	$+2	; I/O DELAY
	MOV	AH,AL	; SAVE LSB OF 16-BIT REGISTER
	IN	AL,DX	; READ MSB OF DMA CH REGISTER
	CMP	SX,AX	; PATTERN READ AS WRITTEN?
	JE	C18A	; YES - CHECK NEXT REGISTER
	HLT		; NO - HALT THE SYSTEM
C18A:			; NXT DMA CH
	ADD	DX,2	; SET I/O PORT TO NEXT CHANNEL REGISTER
	LOOP	C17A	; WRITE PATTERN TO NEXT REGISTER
	INC	AL	; SET PATTERN TO 0
	JZ	C16A	; YES CONTINUE

;-----	WRITE DMA WITH 55 PATTERN

	CMP	BL,55H	; CHECK IF 55 PATTERN DONE
	JZ	C20A	; GO IF YES
	CMP	BL,0AAH	; CHECK IF AA PATTERN DONE
	JZ	C21	; GO IF YES
	MOV	AL,55H
	JMP	C16A

;-----	WRITE DMA WITH AA PATTERN
C20A:	MOV	AL,0AAH
	JMP 	C16A

;-----	INITIALIZE AND START MEMORY REFRESH
C21:
	MOV	BX,@RESET_FLAG	; GET THE RESET FLAG
	MOV	@EQUIP FLAG,AX	; DO A DUMMY MEMORY WRITE BEFORE REFRESH
	MOV	AL,18	; START REFRESH TIMER
	OUT	TIMER+1,AL

;-----	SET DMA COMMAND
	SUB	AL,AL	; DACK SENSE LOW,DREQ SENSE HIGH
	OUT	DMA+8,AL	; LATE WRITE, FIXED PRIORITY, NORMAL
			; TIMING, CONTROLLER ENABLE, CH0 ADDRESS
			; HOLD DISABLE, MEMORY TO MEMORY DISABLE
	OUT	DMA18,AL	; SAME TO SECOND CONTROLLER

;-----	MODE SET ALL DMA CHANNELS

	MOV	AL,40H	; SET MODE FOR CHANNEL 0
	OUT	DMA+0BH,AL
	MOV	AL,0C0H	; SET CASCADE MODE ON CHANNEL 4
	OUT	DMA18+06H,AL
	JMP	$+2	; I/O DELAY
	MOV	AL,41H	; SET MODE FOR CHANNEL 1
	OUT	DMA+0BH,AL
	OUT	DMA18+06H,AL	; SET MODE FOR CHANNEL 5
	JMP	$+2	; I/O DELAY
	MOV	AL,42H	; SET MODE FOR CHANNEL 2
	OUT	DMA+0BH,AL
	OUT	DMA18+06H,AL	; SET MODE FOR CHANNEL 6
	JMP	$+2	; I/O DELAY
	MOV	AL,43H	; SET MODE FOR CHANNEL 3
	OUT	DMA+0BH,AL
	OUT	DMA18+06H,AL	; SET MODE FOR CHANNEL 7

;----- 	RESTORE RESET FLAG
	MOV 	@RESET_FLAG,BX

;------------------------------------------
; TEST.08 		:
;	DMA PAGE REGISTER TEST	:
; DESCRIPTION		:
;	WRITE/READ ALL PAGE REGISTERS	:
;------------------------------------------

;-----	CHECKPOINT 08
	MOV	AL,08H	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	; 	  <><> CHECKPOINT  08 <><>
	SUB	AL,AL
	MOV	DX,DMA_ PAGE
	MOV	CX,0FFA	; DO ALL DATA PATTERNS
C22A:	OUT	DX,AL
	INC	DX
	INC	AL
	CMP	DX,8FH	; TEST DMA PAGES 81 THROUGH 8EH
	JNZ	C22A
	XCHG	AH,AL	; SAVE CURRENT DATA PATTERN
	DEC	AH	; CHECK LAST WRITTEN
	DEC	DX
C22B:	SUB	AL,AL	; CHANGE DATA BEFORE READ
	IN	AL,DX
	CMP	AL,AH	; DATA AS WRITTEN?
	JNZ	C26	; GO ERROR HALT IF NOT
	DEC	AH
	DEC	DX
	CMP	DX,MFG_PORT	; CONTINUE TILL PORT 80
	JNZ	C22B
	INC	AH	; NEXT PATTERN TO RIPPLE
	MOV	AL,AH
	LOOP	C22A

;-----	TEST LAST DMA PAGE REGISTER (USED FOR ADDRESS LINES DURING REFRESH)
	MOV	AL,0CCH	; WRITE AN CC TO PAGE REGISTERS
C22:	MOV	DX,LAST_DMA_PAGE
	MOV	AH,AL	; SAVE THE DATA PATTERN
	OUT	DX,AL	; OUTPUT PAGE REGISTER

;-----	VERIFY PAGE REGISTER 8F

	SUB	AL,AL	; CHANGE DATA PATTERN BEFORE READ
	IN	AL,DX	; GET THE DATA FROM PAGE REGISTER
	CMP	AL,AH
	JNZ	C26	; GO IF ERROR
	CMP	AH,0CCM
	JNZ	C25	; GO IF ERROR
	MOV	AL,033H	; SET UP DATA PATTERN OF 33
	JMP	C22	; DO DATA 33
C25:
	CMP	AH,0	; CHECK DONE
	JZ	C27	; GO IF YES
	SUB	AL,AL	; SET UP FOR DATA PATTERN 00
	JMP	C22	; DO DATA 0

;-----	ERROR HALT
C26:
	HLT		; HALT SYSTEM

;------------------------------------------
; TEST.09		:
;	STORAGE REFRESH TEST	:
; DESCRIPTION		:
;	VERIFY REFRESH IS OCCURRING	:
;------------------------------------------

;-----	CHECKPOINT 09 - TEST MEMORY REFRESH
C27:
	MOV	AL,09H	; 	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	; 	  <><> CHECKPOINT  09 <><>
	SUB	CX,CX
C28:
	IN	AL,PORT_B	; INSURE REFRESH BIT IS TOGGLING
	TEST	AL,REFRESH_BIT
	LOOPZ	C28	; INSURE REFRESH IS OFF
	JCXZ	C26	; ERROR HALT IF TIMEOUT
C29:
	IN	AL,PORT_B
	TEST	AL,REFRFSH_BIT	; INSURE REFRESH IS ON
	LOOPNZ	C29
	JCXZ	C26	; ERROR HALT IF NO REFRESH BIT

;------------------------------------------
; TEST.10		:
;	8042 INTERFACE TEST	:
;	READ CONFIGURATION JUMPERS	:
; DESCRIPTION		:
;	ISSUE A SELF TEST TO THE 8042.	:
;	INSURE A 55H IS RECEIVED.	:
;	READ MANUFACTURING AND DISPLAY	:
;	JUMPERS AND SAVE IN MFG_TEST.	:
;------------------------------------------

;-----	CHECKPOINT 0A

	MOV 	AL,0AH	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	;	  <><> CHECKPOINT  0A <><>

;-----	SOFT RESET (HANDLE ALL POSSIBLE CONDITIONS)

	SUB	CX,CX	; 100 MILLISECONDS FOR THIS LOOP
TST1:	IN	AL,STATUS_PORT	; CHECK FOR INPUT BUFFER FULL
	MOV	AH,AL
	TEST	AH OUT_BUF_FULL
	JZ	TST2	; GO IF NOT
	IN	AL,PORT_A	; FLUSH
TST2:	TEST	AH,INPT_BUF_FULL	; IS THE OUTPUT BUFFER ALSO FULL?
	LOOPNZ	TST1	; TRY AGAIN
	JZ	TST4	; CONTINUE IF OK

ERR0:	HLT		; HALT SYSTEM IF BUFFER FULL

;-----	ISSUE A RESET TO THE 8042

TST4:	MOV	AL,0BH	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	; 	  <><> CHECKPOINT  0B <><>
	MOV	AL,SELF_TEST	; SELF TEST COMMAND
	MOV	SP,OFFSET C8042A	; SET RETURN ADDRESS
	JMP	SHORT C8042
TST4_B:	TEST	AL,OUT_BUF_FULL	; IS THE OUTPUT BUFFER FULL?
	JZ	TST4_A	; GO IF NOT
	IN	AL,PORT_A	; FLUSH
TST4_A:	MOV	SP,OFFSET OBF_42A	; SET RETURN ADDRESS
	JMP	SHORT OBF_42	; GO WAIT FOR BUFFER
TST4_C:	IN	AL,PORT_A	; GET THE ENDING RESPONSE
	CMP	AL,55H

	MOV	AL,0CH	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	; 	  <><> CHECKPOINT  OC <><>

	JNZ	ERR0	; GO IF NOT OK

;-----	GET THE SWITCH SETTINGS
	MOV	AL,READ_8042_INPUT	; READ INPUT COMMAND
	MOV	SP:OFFSET C8042C	; SET RETURN ADDRESS
	JMP	SHORT C8042	; ISSUE COMMAND
E30B:	MOV	SP,OFFSET OBF_42B	; SET RETURN ADDRESS
	JMP	SHORT OBF_42	; GO WAIT FOR RESPONSE
E30C:	IN	AL,PORT_A	; GET THE SWITCH
	OUT	DMA_PAGE+1,AL	; SAVE TEMPORARY

;-----	WRITE BYTE 0 OF 8042 MEMORY

	MOV	AL,WRITE_8042_LOC	; WRITE BYTE COMMAND
	MOV	OFFSET C8042B	; SET RETURN ADDRESS
	JMP	SHORT C8042	; ISSUE THE COMMAND
TST4_D:	JZ	TST4_D1	; CONTINUE IF COMMAND ACCEPTED

	MOV	AL,ODH	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	; 	  <><> CHECKPOINT  0D <><>
	HLT
TST4_D1:
	MOV	AL,5DH	; ENABLE OUTPUT BUFFER FULL INTERRUPT,
	OUT	PORT_A,AL	; DISABLE KEYBOARD, SET SYSTEM FLAG,
	JMP	SHORT E30A	; PC 1 COMPATIBILITY, INHIBIT OVERRIDE

;-----	ISSUE THE COMMAND TO THE 8042

C8042:	CLI		; NO INTERRUPTS ALLOWED
	OUT	STATUS_PORT,AL	; SEND COMMAND IN AL REGISTER

	SUB	CX,CX	; LOOP COUNT
C42_1:	IN	AL,STATUS_PORT	; WAIT FOR THE COMMAND ACCEPTED
	TEST	AL,INPT_BUF_FULL
	LOOPNZ	C42_1
	RET

;-----	WAIT FOR 8042 RESPONSE

OBF_42: 	SUB	CX,CX
	MOV	BL,6	; 200MS/PER LOOP * 6 =1200 MS +
C42_2:	IN	AL,STATUS_PORT	; CHECK FOR RESPONSE
	TEST	AL,OUT_BUP_FULL
	JNZ	C42_3	; GO IF RESPONSE
	LOOP	C42_2	; TRY AGAIN
	DEC	BL	; DECREMENT LOOP COUNT
	JNZ	C42_2
C42_3:	RET		; RETURN TO CALLER

;------------------------------------------
; TEST.11 		:
;	BASE 64K READ/WRITE MEMORY TEST	:
; DESCRIPTION 		:
;	WRITE/READ/VERIFY DATA PATTERNS	:
;	AA,55,FF,01, AND 00 TO 1 ST 64K	:
;	OF STORAGE, VERIFY STORAGE 	:
;	ADDRESSABILITY.	;
;------------------------------------------

;----- FILL MEMORY WITH DATA

E30A:	MOV	AL,0EH	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	; 	  <><> CHECKPOINT	 0E <><>

	MOV	AX,DATA	; GET THE SYSTEM SEGMENT
	MOV	DS,AX	;  OF DATA
	MOV	DX,@RESET_FLAG	; SAVE @RESET FLAG IN BX
	CLD		; SET DIRECTION FLAG TO INCREMENT
	MOV	CX,2000H*4	; SET FOR 32K WORDS
	SUB	DI,DI	; FIRST 16K
	SUB	SI,SI
	SUB	AX,AX
	MOV	DS,AX
	MOV	ES,AX
	CMP	BX,1234H	; WARM START?
	JNZ	E30A_0	; GO IF NOT
	JMP	CLR_STG

;-----	GET THE INPUT BUFFER (SWITCH SETTINGS)

E30A_0:	MOV	AL,0FH	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	;	  <><> CHECKPOINT  0F <><>
	MOV	AL,PARITY_CHECK	; SET BASE MEMORY PARITY
	OUT	DMA_PAGE+6,AL	; USE AS TEMPORARY SAVE
	MOV	SP,OFFSET C2	; SET RETURN ADDRESS
	JMP	STGTST_CNT
C30:	MOV	BX,AX	; SAVE FAILING BIT PATTERN
	JNZ	C31
	JMP	C33	; STORAGE OK, CONTINUE

;-----	TEMPORARY STACK FOR POST ROUTINES

C2	DW	C30
C8042A	DW	TST4_B
OBF_42A	DW	TST4_C
C8042B	DW	TST4_D
C8042C	DW	E30B
OBF_42B	DW	E30C

;------------------------------------------
; BASE 64K STORAGE FAILURE	
;   DISPLAY THE CHECKPOINT IMFG CHECKPOINT)
;     AND XOR EXPECTED WITH READ IN MFG_PORT
;   DISPLAY CHECKPOINT IN MFG_PORT+3
;   DISPLAY XOR'D DATA HIGH BYTE MFG_PORT+1
;     LOW BYTE IN MFG_PORT+2
;   A READ/WRITE SCOPE LOOP OF THE FIRST
;   WORD FOR POSSIBLE ADDRESS LINE FAILURES
;-------------------------------------------

C31:
	MOV	AL,AH	; SAVE HIGH BYTE
	OUT	MFG_PORT-1,AL
	MOV	AL,81-	; SavE LOW BYTE
	OUT	MFC_PCRT-2,AL

;-----	CHECK FOR VIDEO ROM
	MOV	CX,0C000H	; START OF I/O ROM
M1:	MOV	DS'CX	; POINT TO SEGMENT
	SUB	BX,BX	; GET THE FIRST 2 LOCATIONS
	MOV	AX'[BX]
	JMP	$+2	; BUS SETTLE
	CMP	AX,0AA55H	; IS THE VIDEO ROM PRESENT?
	POP
	JZ	Z5	; GO IF YES
	ADD	CX,080H	; POINT TO NEXT 2K BLOCK
	CMP	CX,0C800H	; TOP OF VIDEO ROM AREA YET?
	JL	M1	; TRY AGAIN
	AND	CX,CX	; SET NON ZERO FLAG
Z5:
	JNZ	C32	; GO IF NOT
	JMP	C31_0	; BYPASS ERROR DISPLAY IF VIDEO ROM

;-------------------------------------------------------
; SET VIDEO MODE TO DISPLAY MEMORY ERROR
;	THIS ROUTINE INITIALIZES THE ATTACHMENT TO
;	TO DISPLAY FIRST 64K STORAGE ERRORS.
; BOTH COLOR AND MONOCHROME ATTACHMENTS ARE INITIALIZED.
;-------------------------------------------------------

;-----	INITIALIZE COLOR/MONOCHROME

C32:	MOV	DX,3D8H	; CONTROL REGISTER ADDRESS OF COLOR CARD
	SUB	AL,AL	; MODE SET
	OUT	DX,AL

	MOV	DX,03B8H	; CONTROL REGISTER ADDRESS OF B/W CARD
	MOV	AL,1	; MODE SET FOR CARD
	OUT	DX,AL	; RESET VIDEO
	SUB	DX,4	; BACK TO BASE REGISTER

M4	EQU	10H

	MOV	BX,OFFSET VIDEO_PARMS+M4*3  ; POINT TO VIDEO PARAMETERS
	ASSUME	DS:COOE
Z_2:	MOV	CX,M4	; COUNT OF MONOCHROME VIDEO PARAMETERS

;-----	BX POINTS TO CORRECT ROW OF INITIALIZATION TABLE

	XOR	AH,AH 	; AH IS REGISTER NUMBER DURING LOOP

;-----	LOOP THROUGH TABLE, OUTPUTTING REGISTER ADDRESS, THEN VALUE FROM TABLE

M10:	MOV	AL,AH	; GET 6845 REGISTER NUMBER
	OUT	DX,AL
	INC	DX	; POINT TO DATA PORT
	INC	AH	; NEXT REGISTER VALUE
	MOV	AL,CS:[BX]	; GET TABLE VALUE
	OUT	DX,AL	; OUT TO CHIP
	INC	BX	; NEXT IN TABLE
	DEC	DX	; BACK TO POINTER REGISTER
	LOOP	M10	; DO THE WHOLE TABLE
	MOV	AH,DL	; CHECK IF COLOR CARD DONE
	AND	AH,0F0H	; STRIP UNWANTED BITS
	CMP	AH,0D0H	; IS IT THE COLOR CARD7
	JZ	Z_3	; CONTINUE IF COLOR
	MOV	BX,OFFSET VIDEO_PARMS	; POINT TO VIDEO PARAMETERS
	MOV	DX,3D4H	; COLOR BASE
	JMP	Z_2	; CONTINUE

;-----	FILL REGEN AREA WITH BLANK

Z_3:	XOR	DI,DI	; SET UP POINTER FOR REGEN
	MOV	AX,0B000H	; SET UP ES TO VIDEO REGEN
	MOV	ES,AX

	MOV	CX,2048	; NUMBER OF WORDS IN MONOCHROME CARD
	MOV	AX,' '+7*H	; FILL CHARACTER FOR ALPHA - ATTRIBUTE
	REP	STOSW	; FILL THE REGEN BUFFER WITH BLANKS

	XOR	DI,DI	; CLEAR COLOR VIDEO BUFFER MEMORY
	MOV	AX,0B800H	; SET LIP ES TO COLOR VIDEO MEMORY
	MOV	ES,BX
	MOV	CX,8192
	REP	STOSW	; FILL WITH BLANKS

;-----	ENABLE VIDEO AND CORRECT PORT SETTING

	MOV	DX,3B8H
	MOV	AL,29H
	OUT	DX,AL	; SET VIDEO ENABLE PORT

;-----	SET UP OVERSCAN REGISTER

	INC	DX	; SET OVERSCAN PORT TO A DEFAULT
	MOV	AL,30H	; VALUE 30H FOR ALL MODES EXCEPT 640X200
	OUT	DX,AL	; OUTPUT THE CORRECT VALUE TO 3D9 PORT

;-----	ENABLE COLOR VIDEO AND CORRECT PORT SETTING
	MOV	DX,3D8H
	MOV	AL,28H
	OUT	DX,AL	; SET VIDEO ENABLE PORT

;-----	SET UP OVERSCAN REGISTER

	INC	DX	; SET OYERSCAN PORT TO A DEFAULT
	MOV	AL,30H	; VALUE 30H FOR ALL MODES EXCEPT 640X200
	OUT	DX,AL	; OUTPUT THE CORRECT VALUE TO 3D9 PORT

;-----	DISPLAY FAILING CHECKPOINT AND

	MOV	AX,CS	; SET STACK SEGMENT TO CODE SEGMENT
	MOV	SS,AX

	MOV 	EX,0B000H
	MOV	DS,EX	; SET DS TO 8/W DISPLAY BUFFER

Z_0:	MOV	AL,'0'	; DISPLAY BANK 000000
	MOV	CX,6
	SUB	DI,DI	; START AT 0
Z:	MOV	[DI],AL	; WRITE TO DISPLAY REGEN BUFFER
	INC	DI	; POINT TO NEXT POSITION
	INC	DI
	LOOP	Z

	CMP	BH,0B8H	; CHECK THAT COLOR BUFFER WRITTEN
	JZ	Z_1
	SUB	DI,DI	; POINT TO START OF BUFFER

	MOV	BH,0B0H
	MOV	ES,BX	; ES = MONOCHROME
	MOV	SH,0B8H	; SET SEGMENT TO COLOR
	MOV	DS,BX	; DS = COLOR
	JMP	Z_0

;-----	PRINT FAILING BIT PATTERN
Z_1:	MOV	AL,' '	; DISPLAY A BLANK
	MOV	[DI], AL	; WRITE TO COLOR BUFFER
	MOV	ES:[DI],AL	; WRITE TO MONOCHROME REGEN BUFFER
	INC	DI	; POINT TO NEXT POSITION
	INC	DI
	IN	AL,MFG_PORT+1	; GET THE HIGH BYTE OF FAILING PATTERN
	MOV	CL,4	; SHIFT COUNT
	SHR	AL,CL	; NIBBLE SWAP
	MOV	SP,OFFSET Z1_O
	JMP	SHORT PR

Z1:	IN	AL,MFG_PORT+1
	AND	AL,OFH	; ISOLATE TO LOW NIBBLE
	MOV	SP,OFFSET Z2_O
	JMP	SHORT PR
Z2:	IN	AL,MFG_PORT+2	; GET THE HIGH BYTE OF FAILING PATTERN
	MOV	CL,4	; SHIFT COUNT
	SHR	AL,CL	; NIBBLE SWAP
	MOV	SP,OFFSET Z3_0
	JMP	SHORT PR
Z31	IN	AL,MFG_PORT+2
	AND	AL,0FH	; ISOLATE TO LOW NIBBLE
	MOV	SP,OFFSET Z4_0	; RETURN TO Z4:

; -----	CONVERT AND PRINT	; CONVERT 00-OF TO ASCII CHARACTER
PR:	ADD	AL,090M	; ADD FIRST CONVERSION FACTOR
	DAA		; ADJUST FOR NUMERIC AND ALPHA RANGE
	ADC	AL,040H	; ADD CONVERSION AND ADJUST LOW NIBBLE
	DAA		; ADJUST HIGH NIBBLE TO ASCII RANGE

	MOV	[DI],AL	; WRITE TO COLOR BUFFER
	MOV	ES:[DI],AL	; WRITE TO MONOCHROME BUFFER
	INC	DI	; POINT TO NEXT POSITION
	INC	DI
	RET

;-----	DISPLAY 201 ERROR

Z4:	MOV	AL,' '	; DISPLAY A BLANK
	MOV	[DI],AL	; WRITE TO DISPLAY REGEN BUFFER
	MOV	ES:1011,AL	; WRITE TO MONOCHROME BUFFER
	INC	DI	; POINT TO NEXT POSITION
	INC	DI
	MOV	AL,'2'	; DISPLAY 201 ERROR
	MOV	[DI],AL	; WRITE TO DISPLAY REGEN BUFFER
	MOV	ES:[DI],AL	; WRITE TO MONOCHROME BUFFER
	INC	DI	; POINT TO NEXT POSITION

	INC	DI
	MOV	AL,'0'
	MOV	[DI],AL	; WRITE TO DISPLAY REGEN BUFFER
	MOV	ES:[DI],AL	; WRITE TO MONOCHROME BUFFER
	INC	DI	; POINT TO NEXT POSITION
	INC	DI
	MOV	AL,'1'
	MOV	[DI],AL	; WRITE TO DISPLAY REGEN BUFFER
	MOV	ES:[DI],AL	; WRITE TO MONOCHROME BUFFER

;-----	ROLL ERROR CODE IN MFG_PORT --> FIRST THE CHECKPOINT
C31_0:	MOV	AL,ODDH	;	 <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	;	 <><> CHECKPOINT  DD <><>
	OUT	MFG_PORT+3,AL	; ALSO DISPLAY CHECK POINT IN PORT 83
	SUB	CX,CX
C31_A:

	SUB	AX,AX	; SETUP SEGMENT
	MOV	DS,AX
	MOV	AX,0AA55H	; WRITE AN AA55
	SUB	DI,DI
	MOV	[DI],AX
	MOV	AX,[DI]	; READ THE FIRST WORD
	LOOP	C31_A	; DISPLAY CHECKPOINT LONGER
C31_B:	
	MOV	[DI],AX
	MOV	AX,[DI]
	LOOP	C31_B
C31_C:	
	MOV	[DI],AX
	MOV	AX,[DI]
	LOOP	C31_C
C31_D:	
	MOV	[DI],AX
	MOV	AX,[DI]
	LOOP	C31_D
C31_E:
	MOV	[DI],AX
	MOV	AX,[DI]
	LOOP	C31_E

;-----	ROLL ERROR CODE IN MFG_PORT --> NEXT THE HIGH BYTE

	IN	AL,MFG_PORT+1	; XOR OF FAILING BIT PATTERN
	OUT	MFG_PORT,AL	; HIGH BYTE
C31_G:
	MOV	AX,0AA55H	; WRITE AN AA55
	MOV	[DI],AX
	MOV	AX,[DI]	; READ THE FIRST WORD
	LOOP	C31_G
C31_H:
	MOV	[DI],AX
	MOV	AX,[DI]
	LOOP	C31_H
C31_I:	
	MOV	[DI],AX
	MOV	AX,[DI]
	LOOP	C31_1

;-----	ROLL ERROR CODE IN MFG_PORT --> THEN THE LOW BYTE

	IN	AL,MFG_PORT+2	; LOW BYTE
	OUT	MFG_PORT,AL
	MOV	AX,0AA55H	; WRITE AN AA55
C31_K:	SUB	DI,DI
	MOV	[DI],AX
	MOV	AX,[DI]	; READ THE FIRST WORD
	LOOP	C31_K
C31_L:
	MOV	[DI],AX
	Mov	AX,[DI]
	LOOP	C31_L
C31_M:
	MOV	[DI],AX
	Mov	AX,[DI]
	LOOP	C31_M
C31_N:
	MOV	[DI],AX
	MOV	AX,[DI]
	LOOP	C31_N
	JMP	C31_0	; DO AGAIN

Z1_0	DW	Z1	; TEMPORARY STACK
Z2_0	DW	Z2	; TEMPORARY STACK
Z3_0	DW	Z3	; TEMPORARY STACK
Z4_0	DW	Z4	; TEMPORARY STACK

;-----	CLEAR STORAGE ENTRY

CLR_STG:
	ASSUME	DS:DATA
	REP	STOSW	; STORE 32K WORDS OF 0000
	MOV	AX,DATA	; RESTORE DATA SEGMENT
	MOV	DS,AX
	MOV	@RESET_FLAG,BX	; RESTORE RESET FLAG

;-----	SETUP STACK SEGMENT AND SP

C33:
	MOV	AX,DATA	; SET DATA SEGMENT
	MOV	DS,AX
	MOV	SP,POST_SS	; GET STACK VALUE
	MOV	SS,SP	; SET THE STACK UP
	MOV	SP,POST_SP	; STACK IS READY TO GO

;-----	INITIALIZE DISPLAY ROW COUNT

	MOV	@ROWS,25-1	; SET ROWS FOR PRINT SCREEN DEFAULT

	MOV 	AL,11H	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	; 	  <><> CHECKPOINT  11 <><>

;-----	VERIFY SPEED/REFRESH CLOCK RATES   ( ERROR = 1 LONG AND 1 SHORT BEEP )
	XOR	BL,BL	; CLEAR REFRESH CYCLE REPEAT COUNT
	XOR	CX,CX	; INITIALIZE SPEED RATE REGISTER
	EVEN		; PLACE ON EVEN WORD BOUNDARY
C34:
	IN	AL,PORT_B	; READ REFRESH BIT REGISTER
	TEST	AL,REFRFSH_BIT	; MASK FOR BIT
	LOOPZ	C34	; DECREMENT LOOP COUNTER TILL ON
C35:
	IN	AL,PORT_B	; READ REFRESH BIT REGISTER
	TEST	AL,REFRFESH_BIT	; MASK FOR BIT
	LOOPNZ	C35	; DECREMENT LOOP COUNTER TILL OFF

	DEC	BL	; DECREMENT REFRESH CYCLE REPEAT COUNT
	JNZ	C34	; REPEAT TILL CYCLE COUNT DONE

	CMP	CX,RATE_UPPER	; CHECK FOR RATE BELOW UPPER LIMIT
	JAE	C36	; SKIP ERROR BEEP IF BELOW MAXIMUM
C36E:
	MOV	DX,0101H	; GET BEEP COUNTS FOR REFRESH ERROR
	CALL	ERR_BEEP	; CALL TO POST ERROR BEEP ROUTINES
	HLT		; HALT SYSTEM - BAD REFRESH RATE
C36I
	CMP	CX,RATE_LOWER	; CHECK FOR RATE ABOVE LOWER LIMIT
	JA	C36E	; GO TO ERROR BEEP IF BELOW MINIMUM

;-----	GET THE INPUT BUFFER (SWITCH SETTINGS)
	IN	AL,DMA_PAGE+1	; GET THE SWITCH SETTINGS
	AND	AL,KEY_BD_INHIB+DSP_JMP+MFG_LOOP+BASE_MEM+BASE_MEM8 ; STRIP BITS
	MOV	@MFG_TST,AL	; SAVE SETTINDS
	SUB	AL,AL	; RESET DMA_PAGE
	OUT	DMA_PAGE+1,AL

;------------------------------------------
; TEST.11A		:
;       VERIFY 286 LGDT/SGDT LIDT/SIDT	:
;       INSTRUCTIONS	:
; DESCRIPTION 		:
;       LOAD GOT AND IDT REGISTERS WITH	:
;       AA,55,00 AND VERIFY CORRECT.	:
;------------------------------------------

;-----	VERIFY STATUS INDICATE COMPATIBILITY (REAL) MODE

	SMSW	AX	; GET THE CURRENT STATUS WORD
	DD	00FH,001H,0E0H
	TEST	AX,0FH	; PE/MP/EM/TS BITS SHOULD BE ZERO
	JNZ	ERR_PROT	; GO IF STATUS NOT REAL MODE

;-----	TEST PROTECTED MODE REGISTERS
	MOV	AL,12H	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	; 	  <><> CHECKPOINT  12 <><>

	PUSH	DS	; SET ES TO SAME SEGMENT AS DS
	POP	ES
	MOV	DI,SYS_IDT_LOC	; USE THIS AREA TO BUILD TEST PATTERN
	MOV	CX,3
	MOV	AX,0AAAAH	; FIRST PATTERN
	CALL	WRT_PAT
	MOV	AX,05555H
	CALL	WRT_PAT	; WRITE NEXT PATTERN
	SUB	AX,AX	; WRITE 0
	CALL	WRT_PAT

;-----	TEST 286 CONTROL FLAGS
	STD		; SET DIRECTION FLAG FOR DECREMENT
	PUSHF		; GET THE FLAGS
	POP	AX
	TEST	AX,0200H	; INTERRUPT FLAG SHOULD BE OFF
	JNZ	ERR PROT	; GO IF NOT
	TEST	AX,Z400H	; CHECK DIRECTION FLAG
	JZ	ERR_PROT	; GO IF NOT SET
	CLD		; CLEAR DIRECTION FLAG
	PUSHF		; INSURE DIRECTION FLAG IS RESET
	POP	AX
	TEST	AX,0400H
	JNZ	ERR_PROT	; GO IF NOT

	JMP	SHORT C37A	; TEST OK CONTINUE
ERR_PROT:
	HLT		; PROTECTED MODE REGISTER FAILURE
	JMP	SHORT ERR_PROT	; INSURE NO BREAKOUT OF HALT

;----- 	WRITE TO 286 REGISTERS
WRT_PAT:	MOV	CX,3
	REP	STOSW	; STORE 6 BYTES OF PATTERN
	MOV	BP,SYS_IDT_LOC
	SEGOV	ES	; LOAD THE IDT
	DB	026H
	LIDT	[BP]	; REGISTER FROM THIS AREA
	DB	00FH
??0001	LABEL 	BYTE
	MOV	BX,WORD PTR [BP]
??0002	LABEL	BYTE
	ORG	OFFSET CS:??0001
	DB	001H
	ORG	OFFSET CS:??0002
	MOV	BP,SYS_IDT_LOC
	SEGOV	ES	; LOAD THE GDT
	DB	026H
	LGDT	[BP]	; FROM THE SAME AREA
	DB	00FH
??0004	LABEL	BYTE
	MOV	DX,WORD PTR [BP]
??0005	LABEL 	BYTE
	ORG	OFFSET CS:??0004
	DB	001H
	ORG	OFFSET CS:??0005

;-----	READ AND VERIFY 286 REGISTERS
	MOV	BP,GDT_LOC	; STORE THE REGISTERS HERE
	SEGOV	ES
	DB	026H
	SIDT	[BP]	; GET THE IDT REGISTERS
	DB	00FH
??0007	LABEL	BYTE
	MOV	CX,[BP]
??0008	LABEL	BYTE
	ORG	OFFSET CS:??0007
	DB	001H
	ORG	OFFSET CS:??0008
	MOV	BP,GDT_LOC+5
	SEGOV	ES
	DB	026H
	SGDT	[BP]	; GET THE GDT REGISTERS
	DB	00FH
??000A	LABEL	BYTE
	ADD	AX,[BP]
??000B	LABEL	BYTE
	ORG	OFFSET CS:??000A
	DB	001H
	ORG	OFFSET CS:??000B
	MOV	DI,SYS_IDT_LOC
	MOV	AX,[DI]	; GET THE PATTERN WRITTEN
	MOV	CX,5	; CHECK ALL REGISTERS
	MOV	SI,GDT_LOC	; POINT TO THE BEGINNING
C37B:	CMP	AX,ES:[SI]
	JNZ	ERR_PROT	; HALT IF ERROR
	INC	SI	; POINT TO NEXT WORD
	INC	SI
	LOOP	C37B	; CONTINUE TILL DONE
	RET

;----------------------------------------------------------
;	INITIALIZE THE 6259 INTERRUPT #1 CONTROLLER CHIP  :
;----------------------------------------------------------
C37A:
	SUB	AL,AL	; RESET MATH PROCESSOR
	OUT	X287+1,AL
	MOV	AL,11H	; ICWI - EDGE, MASTER, ICW4
	OUT	INTA00,AL
	JMP	$+2	; I/O DELAY
	MOV	AL,8	; SETUP ICW2 INTERRUPT TYPE 8 (8-FL
	OUT	INTA01,AL
	JMP	$+2	; I/O DELAY

	MOV	AL,04H	; SETUP ICW3 MASTER LEVEL 2
	OUT	INTA01,AL
	JMP	$+2	; I/O DELAY
	MOV	AL,01H	; SETUP ICW4 MASTER,8086 MODE
	OUT	INTA01,AL
	JMP	$+2	; I/O DELAY
	MOV	AL,0FFH	; MASK ALL INTERRUPTS OFF
	OUT	INTA01,AL	; (VIDEO ROUTINE ENABLES INTERRUPTS)

;-----------------------------------------------------------
;	INITIALIZE THE 8259 INTERRUPT #2 CONTROLLER CHIP  :
;-----------------------------------------------------------

	MOV	AL,13H	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	;	  <><> CHECKPOINT  13 <><>

	MOV	AL,11H	; ICWI - EDGE, SLAVE ICW4
	OUT	INTB00,AL
	JMP	$+2	; I/O DELAY
	MOV	AL,INT_TYPE	; SETUP ICW2 - INTERRUPT TYPE 70 170-7F)
	OUT	INTB01,AL
	MOV	AL,02H	; SETUP ICW3 - SLAVE LEVEL 2
	JMP	$+2
	OUT	INTB01,AL
	JMP	$+2	; I/O DELAY
	MOV	AL,01H	; SETUP ICW4 - 8086 MODE, SLAVE
	OUT	INTB01,AL
	JMP	$+2	; I/O DELAY
	MOV	AL,0FFH	; MASK ALL INTERRUPTS OFF
	OUT	INTB01,AL

;-----	SET UP THE INTERRUPT VECTORS TO TEMPORARY INTERRUPT

	MOV	AL,14H	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	; 	  <><> CHECKPOINT  14 <><>

	MOV	CX,78H	; FILL ALL INTERRUPT LOCATIONS
	SUB	DI,DI	; FIRST INTERRUPT LOCATION
	MOV	ES,DI	; SET (ES) ALSO
D3:	MOV	AX,OFFSET DI	; GET ADDRESS OF INTERRUPT OFFSET
	STOSW		; PLACE IN INTERRUPT VECTOR LOCATION
	MOV	AX,CS	; GET THE CURRENT CODE SEGMENT
	STOSW		; PLACE CODE SEGMENT IN VECTOR LOCATION
	LOOP	D3

;-----	ESTABLISH BIOS SUBROUTINE CALL INTERRUPT VECTORS

	MOV	AL,15H	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	;	  <><> CHECKPOINT  15 <><>

	MOV	DI,OFFSET @VIDEO_INT	; SET VIDEO INTERRUPT AREA
	PUSH	CS
	POP	DS	; SET UP ADDRESS OF VECTOR TABLE
	MOV	AX,DS	; SET AX=SEGMENT
	MOV	SI,OFFSET VECTOR_TABLE+16  ; START WITH VIDEO ENTRY
	MOV	CX,16

D3A:	MOVSW		; MOVE VECTOR TABLE TO LOW MEMORY
	INC	DI
	INC	DI	; SKIP SEGMENT POINTER
	LOOP	D3A

;------------------------------------------
; TEST.12		:
;       VERIFY CMOS CHECKSUM/BATTERY OK	:
; DESCRIPTION		:
;       DETERMINE IF CONFIG RECORD	:
;       CAN BE USED FOR INITIALIZATION.	:
;------------------------------------------
	ASSUME	DS:DATA
	CALL	DDS	;SET THE DATA SEGMENT

	MOV 	AL,16H	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	;	  <><> CHECKPOINT  16 <><>

;-----	IS THE BATTERY LOW THIS POWER UP?

	MOV	AL,CMCS_REG_D+NMI	; CHECK BATTERY CONDITION
	CALL	CMOS_READ	; READ THE BATTERY STATUS
	TEST	AL,10000000B	; IS THE BATTERY LOW?
	JZ	CMOS1A	; ERROR IF YES
	
	MOV	AL,CMOS_DIAG+NMI	; GET THE OLD STATUS
	CALL	CMOS_READ	; FROM DIAGNOSTIC STATUS BYTE
	TEST	AL,BAD_BAT	; HAS CUSTOMER SETUP BEEN EXFCUTE07
	JZ	CMOS1	; GO CHECK CHECKSUM IF YES

	JMP	SHORT CMOS4	; CONTINUE WITHOUT CONFIGURATION

;-----	SET DEFECTIVE BATTERY FLAG

CMOS1A:	MOV	AL,17H	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	; 	  <><> CHECKPOINT  17 <><>

	MOV	AX,X'!CMCS OIAG-NMIL	; CMOS DIAGNOSTIC STATUS BYTE
	CALL	CMOS_READ	; GET THE CURRENT STATUS
	OR	AL,8AO_BAT	; SET THE DEAD BATTERY FLAG
	XCHG	AL,AH	; SAVE
	CALL	CMOS WRITE	; OUTPUT THE STATUS
	JMP	SHORT CMOS4	; GO TO MINIMUM CONFIGURATION

;-----	VERIFY CHECKSUM

CMOS1:	MOV	AX,X*(CMOS_DIAG+NMI)	; CLEAR OLD STATUS
	CALL	CMOS_READ	; GET THE CURRENT STATUS
	CMP	@RESET_FLAG,1234H	; IS THIS A SOFT RESET
	JNZ	CMOS1_A	; GO IF NOT

	AND	AL,W_MEM_SIZE	; CLEAR ALL BUT THE CMOS/POR MEMORY SIZE
	JMP	SHORT CMOS1_B
CMOS1_A:
	SUB	AL,AL	; CLEAR STATUS IF POWER ON RESET
CMOS1_B:
	XCHG	AL,AH	; SAVE THE CURRENT STATUS
	CALL	CMOS_WRITE

	SUB	BX,BX
	SUB	CX,CX
	MOV	CL,CMOS_DISKETTE+NMI	; SET START OF CMCS CHECKSUMED AREA
	MOV	CH,CMOS_CKSUM_HI+NMI	; SET END OF CMCS CHECKSUMED AREA +1
			; (FIRST BYTE OF CHECKSUM)
CMOS2:	MOV	AL,CL
	CALL	CMOS_READ	; ADDRESS THE BEGINNING
	SUB	AH,AH	; INSURE AH=0
	ADD	BX,AX	; ADD TO CURRENT VALUE
	INC	CL	; POINT TO NEXT BYTE ADDRESS IN CMOS
	CMP	CH,CL	; FINISHED?	 (AT CHECKSUM BYTE HIGH)
	JNZ	CMOS2	; GO IF NOT
	OR	BX,BX	; BX MUST NOT BE 0
	JZ	CMOS3	; CMOS BAD IF CMECKSUM=0
	MOV	AL,CMOS_CKSUM_HI+NMI	; GET THE CHECK SUM HIGH BYTE
	CALL	CMOS_READ	; FIRST BYTE OF CHECKSUM
	MOV	AH,AL	; SAVE IT
	MOV	AL,CMOS_CKSUM_LO+NMI	; SECOND BYTE OF CHECKSUM
	CALL	CMOS_READ
	CMP	AX,BX	; IS THE CHECKSUM OK
	JZ	CMOS4	; GO IF YES

;-----	SET CMOS CHECKSUM ERROR

CMOS3:	MOV	AX,XLFCMOS-OIAG-NMI)	; ADDRESS DIAGNOSTIC STATUS
	CALL	CMOS_REAO	; GET THE CURRENT STATUS
	OR	AL,13AO_CKSUM	; SET BAD CHECKSUM FLAG
	XCHG	AL,AH	; SAVE IT
	CALL	CMOS_WRITE	; SET FLAG

;----	INSURE CMOS DIVIDERS SET

CMOS4:
	MOV	AX,X*(CMOS_REG_A+NMI)	; ADDRESS CMOS REGISTER A
	CALL	CMOS_READ	; GET CURRENT DIVISORS
	AND	AL,00FH	; LOOK AT PERIODIC RATE BITS
	JNZ	CMOS9	; EXIT IF SET TO SOMETHING USEFUL

	MOV	AL,26H	; ELSE SET THE STANDARD DEFAULT USED BY
	XCHG	AL,AH	;  BIOS FOR THE 976.56 US RATE
	CALL	CMOS_WRITE	;  FOR THE PERIODIC CLOCK
CMOS9:
	MOV	AL,18H	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	; 	  <><> CHECKPOINT  18 <><>

;-----	ENABLE PROTECTED MODE

	IN	AL,PORT_B	; DISABLE MEMORY AND I/O PARITY CHECKS
	OR	AL,RAM_PAR_OFF
	OUT	PORT_B,AL

;-----	SET RETURN ADDRESS BYTE IN CMOS

	MOV	AL,19H	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	; 	  <><> CHECKPOINT  19 <><>

	MOV	AX,1*H+(CMOS_SHUT_DOWN+NMI)	; SET THE RETURN ADDRESS FOR
	CALL	CMOS_WRITE	; THE FIRST SHUTDOWN RETURN ADDRESS

	MOV	SP,POST_SS	; SET STACK FOR SYSINIT1
	MOV	SS,SP
	MOV	SP,POST_SP
	CALL	SYSINIT1	; CALL THE DESCRIPTOR TABLE BUILDER
			; AND REAL-TO-PROTECTEO MODE SWTTCHER

	MOV	AL,1AH	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	; 	  <><> CHECKPOINT  1A <><>

;-----	SET TEMPORARY STACK

	PUSH	BYTE PTR GDT_PTR	; SET (DS:) SELECTOR TO GDT SEGMENT
	POP	DS
	MOV	DS:SS_TEMP.BASE_LO_WORD,0
	MOV	BYTE PTR DS:(SS_TEMP.BASE_HI_BYTE),0
	MOV	SI,SS_TEMP
	MOV	SS,SI
	MOV	SP,MAX_SEG_LEN-2

;-------------------------------------------------------------------------------
; TEST.13								 :
;  PROTECTED MODE TEST AND MEMORY SIZE DETERMINE ( 0 --> 640K )			 :
;									 :
; DESCRIPTION:								 :
;     THIS ROUTINE RUNS IN PROTECTED MODE IN ORDER TO ADDRESS ALL OF STORAGE.  :
;     IT CHECKS THE MACHINE STATUS WORD (MSW) FOR PROTECTED MODE AND THE BASE  :
;     MEMORY SIZE IS DETERMINED AND SAVED.  BIT 4 OF THE CMOS DIAGNOSTIC	 :
;     STATUS BYTE IS SET IF 512K --> 640K MEMORY IS INSTALLED.			 :
;     DURING A POWER UP SEQUENCE THE MEMORY SIZE DETERMINE IS DONE WITH		 :
;     PLANAR AND I/O PARITY CHECKS DISABLED.  DURING A SOFT RESET THE MEMORY	 :
;     SIZE DETERMINE WILL CHECK FOR PARITY ERRORS.					 :
;-------------------------------------------------------------------------------

;-----	INSURE PROTECTED MODE

	SMSW	AX	; GET THE MACHINE STATUS WORD
	DB	00FH,001H,0E0H
	TEST	AX,VIRTUAL_ENABLE	; ARE WE IN PROTECTED MODE
	JNZ	VIR_OK

SHUT_8: 	MOV	AX,8*H+(CMOS_SHUT_DOWN+NMI)	; SET THE RETURN ADDRESS
	CALL	CMOS_WRITE	; AND SET SHUTDOWN 8
	JMP	PROC_SHUTDOWN	; CAUSE A SHUTDOWN

;-----	VIRTUAL MODE ERROR HALT
SHUT8:	HLT
	JMP	SHUT8	; ERROR HALT

;-----	64K SEGMENT LIMIT

VIR_OK: 	MOV 	DS:ES_TEMP.SEG_LIMIT,MAX_SEG_LEN

;-----	CPL0, DATA ACCESS RIGHTS

	MOV	BYTE PTR DS(ES_TEMP.DATA_ACC_RIGHTS),CPL0_DATA_ACCESS

;-----	START WITH SEGMENT ADDRESS 01-0000 (SECOND 64K)

	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),01H
	MOV	DS:ES_TEMP,BASE_LO_WORD,0H

	MOV	AL,1BH	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	; 	  <><> CHECKPOINT  1B <><>

	MOV	BX,16*4	; SET THE FIRST 64K DONE

;-----	START STORAGE SIZE/CLEAR

NOT_DONE:
	PUSH	BYTE PTR ES_TEMP	; POINT ES TO DATA
	POP	ES	; POINT TO SEGMENT TO TEST
	CALL	HOW-BIG	; DO THE FIRST 64K
	JZ	NCT_FIN	; CHECK IF TOP OF MEMORY
	JMP	DONE

NOT_FIN:	ADD	BX,16*4	; BUMP MEMORY COUNT BY 64K

;-----	DO NEXT 64K (0X0000) BLOCK

	INC	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE)

;-----	CHECK FOR END OF FIRST 640K (END OF BASE MEMORY)

	CMP	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),0AH
	JNZ	NOT_DONE	; GO IF NOT
	CALL	HOW_BIG_END	; GO SET MEMORY SIZE
	JMP	DONE

;-----	FILL/CHECK LOOP

	SUB	DI,DI
	MOV	AX,0AA55H	; TEST PATTERN
	MOV	CX,AX	; SAVE PATTERN
	MOV	ES:[DI],AX	; WRITE PATTERN TO MEMORY
	MOV	AL,0FH	; PUT SOMETHING IN AL
	MOV	AX,ES:[DI]	; GET PATTERN
	MOV	ES:[DI],AX	; INSURE NO PARITY I/O CHECK
	XOR	AX,CX	; COMPARE PATTERNS
	JNZ	HOW_BIG_END	; GO END IF NO COMPARE

	PUSH	DS	
	PUSH	BYTE PTR RSDA_PTR	; POINT TO SYSTEM DATA AREA
	POP	DS	; GET (DS:)

;-----	IS THIS A SOFT RESET
	CMP	@RESET_FLAG,1234H	; SOFT RESET
	POP	DS	; RESTORE DS
	JNZ	HOW_BIG_2	; GO IF NOT SOFT RESET

;-----	INSURE NO PARITY WITH PARITY BITS OFF

	MOV	WORD PTR ES:[DI],0101H	; TURN OFF BOTH PARITY BITS
	IN	AL,PORT_B
	OR	AL,RAM_PAR_OFF	; TOGGLE PARITY CHECK ENABLES
	OUT	PORT_B,AL
	AND	AL,RAM_PAR_ON
	OUT	PORT_B,AL
	PUSH	BYTE PTR 0FFH	; PLACE 0FFFFH IN STACK (BUS BITS ON)
	POP	AX	; DELAY - CAUSING BUS BITS ON
	MOV	AX,ES:[DI]	; CHECK PARITY

	IN	AL,PORT_B	; CHECK FOR PLANAR OR I/O PARITY CHECK
	AND	AL:PARITY_ERR
	MOV	ES,[DI],AX	; CLEAR POSSIBLE PARITY ERROR
	JNZ	HOW_BIG_END	; GO IF PLANAR OR I/O PARITY CHECK

;-----	CHECK ALL BITS WRITE OK

	MOV	WORD PTR ES:[DI],0FFFFH 	; TURN ON ALL BITS
	MOV	AX,ES:[DI]	; CHECK FOR FFFFH
	PUSH	AX	; SAVE RESULTS
	IN	AL,PORT_B	; CHECK FOR PLANAR OR I/O PARITY CHECK
	AND	AL,PARITY_ERR
	MOV	ES:[DI],AX	; CLEAR POSSIBLE PARITY ERROR
	POP	AX	; GET RESULTS
	JNZ	HOW_BIG_END	; GO IF PARITY CHECK
	CMP	AX,0FFFFH
	JNZ	HOW_BIG_END

;-----	CHECK 64K BLOCK FOR PARITY CHECK

HOW_BIG_2:
	SUB	AX,AX	; WRITE ZEROS
	MOV	CX,2000H*4	; SET COUNT FOR 32K WORDS
	REP	STOSW	; FILL 32K WORDS

	PUSH	DS
	PUSH	ES
	PUSH	ES	; GET ES TO DS
	POP	DS
	MOV	CX,2000H*4	; SET COUNT FOR 32K WORDS
	SUB	SI,DI
	REP	LODSW
	SUB	DI,DI	; SET TO BEGINNING OF BLOCK
	IN	AL,PORT_B	; CHECK FOR PLANAR OR I/O PARITY CHECK
	AND	AL,PARITY_ERR
	MOV	WORD PTR ES:[DI],0	; CLEAR POSSIBLE PARITY ERROR
	POP	ES	; RESTORE SEGMENTS
	POP	DS
	JNZ	HOW_BIG_END	; GO IF PLANAR OR I/O PARITY CHECK

	RET

HOW_BIG_END:
	PUSHF		; SAVE THE CURRENT FLAGS
	MOV	AL,1CH	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	; 	  <><> CHECKPOINT  1C <><>

;-----	SET OR RESET 512 TO 640 INSTALLED FLAG

	MOV	AX,X*(CMOS_INFO128+NMI)	; SET/RESET 640K STATUS FLAG
	CALL	CMOS_READ	; GET THE DIAGNOSTIC STATUS
	OR	AL,M64OK
	CMP	BX,512	; CHECK MEMORY SIZE
	JA	K640	; SET FLAG FOR 512 - 640 INSTALLED
	AND	AL,NOT M640K
K640:	
	XCHG	AL,AH	; SAVE THE SUTUS
	CALL	CMOS_WRITE	; RESTORE THE STATUS

	PUSH	BYTE PTR RSDA_PTR	; RESTORE THE DATA SEGMENT
	POP	DS
	MOV	@MEMORY_SIZE,BX	; SAVE MEMORY SIZE
	POPF		; RESTORE THE FLAG REGISTER
	RET
;------------------------------------------------------------------------------
; TEST.13A								:
;  PROTECTED MODE TEST AND MEMORY SIZE DETERMINE ( ABOVE 1024K )			:

; DESCRIPTION:								:
;     THIS ROUTINE RUNS IN PROTECTED MODE IN ORDER TO ADDRESS ABOVE 1 MEG.	:
;     THE MEMORY SIZE IS DETERMINED AND SAVED IN CMOS.				:
;     DURING A POWER UP SEQUENCE THE MEMORY SIZE DETERMINE IS DONE WITH 	:
;     PLANAR AND I/O PARITY CHECKS DISABLED.  DURING A SOFT RESET THE MEMORY 	:
;     SIZE DETERMINE WILL CHECK FOR PARITY ERRORS.					:
;------------------------------------------------------------------------------

DONE:	PUSH	BYTE PTR GDT_PTR	; POINT DS TO THE DESCRIPTOR TABLE
	POP	05

;-----	START WITH SEGMENT ADDRESS 10-0000 (ONE MEG AND ABOVE)

	MOV	BYTE PTR CS:(ES_TEMP,BASE_HI_BYTE),10H
	MOV	DS:ES_TEMP.BASE_LO_WORD,0H

	MOV	AL,1DH	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	; 	  <><> CHECKPOINT  1D <><>
	SUB	BX,BX	; START WITH COUNT 0

;-----	START STORAGE SIZE/CLEAR

NOT_DONE1:
	PUSH	BYTE PTR ES_TEMP	; POINT ES TO DATA
	POP	ES	; POINT TO SEGMENT TO TEST
	CALL	HOW_BIG1	; DO THE FIRST 64K
	JZ	DONEA	; CHECK IF TOP

	JMP	DONE1	; GO IF TOP

DONEA:	ADD	BX,16*4	; BUMP MEMORY COUNT BY 64K

;-----	DO NEXT 64K (XX0000) BLOCK

	INC	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE)

;-----	CHECK FOR TOP OF MEMORY (FE0000)

	CMP	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),0FEH	; LAST OF MEMORY?
	JNZ	NOT_DONE1				; GO IF NOT
	CALL	HOW_BIG_END1				; GO SET MEMORY SIZE
	JMP	DONE1

;-----	FILL/CHECK LOOP

HOW_BIG1:
	SUB	DI,DI
	MOV	AX,0AA55H	; TEST PATTERN
	MOV	CX,AX	; SAVE PATTERN
	MOV	ES:[DI],AX	; SEND PATTERN TO MEMORY
	MOV	AL,0FH	; PUT SOMETHING IN AL
	MOV	AX,ES:[DI]	; GET PATTERN
	MOV	ES:[DI],AX	; INSURE NO PARITY I/O CHECK
	XOR	AX,CX	; COMPARE PATTERNS
	JNZ	HOW_BIG_END1	; GO END IF NO COMPARE

;-----	IS THIS A SOFT RESET

	PUSH	DS
	PUSH	BYTE PTR RSDA_PTR	; POINT TO SYSTEM DATA AREA
	POP	DS
	CMP	@RESET_FLAG,1234H	; SOFT RESET
	POP	DS	; RESTORE DS
	JNZ	HOW_BIG_2A	; GO IF NOT SOFT RESET

;-----	CHECK PARITY WITH PARITY BITS OFF

	MOV	WORD PYR ES:[DI],0101H	; TURN OFF BOTH PARITY BITS
	PUSH	BYTE PTR 0FFH	; PLACE 0FFFFH IN STACK (BUS BITS ON)
	POP	AX	; DELAY - CAUSING BUS BITS ON
	MOV	AX,ES:[DI]	; CHECK PARITY

	IN	AL,PORT_B	; CHECK FOR PLANAR OR I/O PARITY CHECK
	AND	AL,PARITY_ERR
	MOV	ES,[DI],AX	; CLEAR POSSIBLE PARITY ERROR
	JNZ	HOW_BIG_END1	; GO IF PLANAR OR I/O PARITY CHECK

;-----	CHECK ALL BITS
	MOV	WORD PTR ES:[DI],0FFFFH	; TURN ON ALL BITS
	PUSH	BYTE PTR 0	; PLACE 00000H IN STACK (BUS BITS OFF)
	POP	AX	; DELAY - CAUSING BUS BITS OFF
	MOV	AX,ES:[DI]	; CHECK FOR FFPFH
	PUSH	AX	; SAVE RESULTS
	IN	AL,POPT_B	; CHECK FOR PLANAR OR I/O PARITY CHECK
	AND	AL,PARITY_ERR
	MOV	ES:[DI],AX	; CLEAR POSSIBLE PARITY ERROR
	POP	AX	; GET RESULTS
	JNZ	HOW_BIG_END1	; GO IF PLANAR OR I/O PARITY CHECK
	CMP	AX,0FFFFH
	JNZ	HOW_BIG_END1

;-----	CLEAR 64K BLOCK OF MEMORY

HOW_BIG_2A:
	SUB	AX,AX	; WRITE ZEROS
	MOV	CX,2000H*4	; SET COUNT FOR 32K WORDS
	REP	STOSW	; FILL 32K WORDS

;-----	CHECK 64K BLOCK FOR PARITY CHECK (VALID TEST DURING SOFT RESET ONLY)

	PUSH	DS
	PUSH	ES
	PUSH	ES	; GET ES TO DS
	POP	DS
	MOV	CX,2000H*4	; SET COUNT FOR 32K WORDS
	SUB	SI,SI
	REP	LODSW
	SUB	DI,DI	; SET TO BEGINNING OF BLOCK
	IN	AL,PORT_B	; CHECK FOR PLANAR OR I/O PARITY CHECK
	AND	AL,PARITY_ERR
	MOV	WORD PTR ES:[DI],0	; CLEAR POSSABLE PARITY ERROR
	POP	ES	; RESTORE SEGMENT
	POP	DS
	JNZ	HOW_BIG_END1	; GO IF PLANAR OR I/O PARITY CHECK

	RET

HOW_BIG_END1:
	MOV	AL,1EH	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	; 	  <><> CHECKPOINT  1E <><>

;-----	SET EXPANSION MEMORY SIZE DETERMINED IN CMOS

	MOV	AL,CMOS_U_M_S_LO+NMI	; ADDRESS LOW BYTE
	MOV	AH,BL	; GET LOW MEMORY SIZE
	CALL	CMOS_WRITE	; SET LOW BYTE
	MOV	AL,CMOS_U_M_S_HI+NMI	; ADDRESS HI BYTE
	MOV	AH,BH	; GET THE HIGH MEMORY SIZE
	CALL	CMOS_WRITE	; PLACE IN CMOS
	RET
;-----	TEST ADDRESS LINES 19 - 23

OONE1:	MOV	AL,1FH	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	; 	  <><> CHECKPOINT  1F <><>
	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),00H
	SUB	DI,DI	; SET LOCATION POINTER TO ZERO
	MOV	DX,0FFFFH	; WRITE FFFF AT ADDRESS 0
	CALL	SD0
	SUB	DX,DX	; WRITE 0
	
	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),08H
	CALL	SD0
	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),10H
	CALL	SD0
	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),20H
	CALL	SD0
	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),40H
CALL	SD0
MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),80H
CALL	SD0

JMP	SHORT SD2	; TEST PASSED CONTINUE

SD0:
PUSH	BYTE PTR ES_TEMP	; POINT ES TO DATA
POP	ES	; POINT TO SEGMENT TO TEST
MOV	ES:[DI],DX	; WRITE THE PATTERN

MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),00H

PUSH	BYTE PTR ES_TEMP	; POINT ES TO DATA
POP	ES	; POINT TO SEGMENT TO TEST
CMP	WORD PTR ES:[DI],0FFFFH] 	; LOCAT10N 0 CHANGE?
JZ	SD1	; CONTINUE IF NOT
JMP	SHUT_8	; GO HALT IF YES
SD1:
RET

;-----	CAUSE A SHUTDOWN

SD2:	MOV	AL,20H	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	; 	  <><> CHECKPOINT  20 <><>
	IN	AL,PORT_B
	OR	AL,RAM_PAR_OFF	; TOGGLE PARITY CHECK ENABLES
	OUT	PORT_B,AL
	AND	AL,RAM_PAR_ON
	OUT	PORT_B,AL
	JMP	PRoC_SHUTDOWN	; CAUSE A SHUTDOWN (RETURN VIA JUMP)

;------------------------------------------
;	RETURN 1 FROM SHUTDOWN	:
;------------------------------------------

SHUT1:	MOV	AL,21H	;	  <><><><><><><><><><><><>
	OUT	MFG_PQRT,AL	; 	  <><> CHECKPOINT  21 <><>
	MOV	SP,ABS0	; SET REAL MODE STACK
	MOV	SS,SP
	MOV	SP,OFFSET @TOS

;-----	SET DIVIDE 0 VECTOR OFFSET
	SUB	DI,DI	; POINT TO FIRST INTERRUPT LOCATION
	MOV	ES,DI	; SET ES TO ABS0 SEGMENT
	MOV	AX,OFFSET D11	; GET ADDRESS OF INTERRUPT OFFSET
	STOSW		; PLACE OFFSET IF NULL HANDLER IN VECTOR

	CALL	DDS	; SET UP THE REAL DATA AREA

;-----	GET THE CONFIGURATION FROM CMOS

	MOV	AX,X*(CMOS_DIAG+NMI)	; CHECK CMOS GOOD
	CALL	CMOS_READ	; GET THE STATUS
	TEST	AL,BAD_BAT+BAD_CKSUM	; VALID CMOS ?
	JZ	M_OK	; GO IF YES
	JMP	BAD_MOS	; GO IF NOT
M_OK:
	AND	AL,0DFH	; CLEAR THE MINIMUM CONFIG BIT
	XCHG	AL,AH	; SAVE THE STATUS BYTE
	CALL	CMOS_WRITE	; BACK INTO CMOS

;-----	CHECK FOR CM0S RUN IN MODE

	CMP	@RESET_FLAG,1234H	; CHECK FOR SOFT RESET
	JE	M_OK_64	; BYPASS IF SOFT RESET

	MOV	AL,CMOS_B_M_S_HI+NMI	; GET THE BASE MEMORY SIZE HIGH BYTE
	CALL	CMOS_READ
	AND	AL,0C0H	; MASK FOR MANUFACTURING TEST BITS
	CMP	AL,0C0H	; CHECK FOR MANUFACTURING TEST MODE SET
	JNE	M_OK_64	; SKIP IF NOT MANUFACTURING LINE TEST

	MOV	BYTE PTR @RESET_FLAG,64H	; ELSE SET THE MFG TEST FLAG

;----	INSURE CONFIGURATION HAS CORRECT VIDEO TYPE

M_OK_64:
	MOV	AL,CMOS_EQUIP+NMI	; GET THE EQUIPMENT BYTE
	CALL	CMOS_READ
	MOV	AH,AL	; SAVE VIDEO TYPE
	TEST	AL,030H	; ANY VIDEO?
	JNZ	MOS_OK_1	; CONTINUE
	CALL	CHK_VIDEO	; INSURE VIDEO ROM PRESENT
	JZ	MOS_OK	; CONTINUE

	TEST	@MFG_TST,MFG_LOOP	; EXCEPT IF MFG JUMPER IS INSTALLED
	JZ	NORMAL_CONFIG	; GO IF INSTALLED
	JMP	SHORT BAD_MOS	; GO DEFAULT

;-----	ROUTINE CHECK FOR VIDEO FEATURE ROM PRESENT

CHK_VIDEO:
	MOV	CX,0C000H	; START OF FEATURE I/O ROM
CHK_VIDEO1:
	PUSH	AX	; SAVE THE CONFIGURATION
	PUSH	DS	; SAVE THE DATA SEGMENT
	PUSH	DI	; SAVE COMPARE REGISTER
	MOV	DS,CX	; GET ROM SEGMENT
	MOV	DI,0AA55H	; GET THE PRESENCE SIGNATURE
	SUB	BX,BX	; CLEAR INDEX POINTER
	MOV	AX,[BX]	; GET THE FIRST 2 LOCATIONS
	CMP	AX,DI	; IS THE VIDEO FEATURE ROM PRESENT?
	POP	DI	; RESTORE WORK REGISTER
	POP	DS	; RESTORE DATA SEGMENT
	POP	AX	; GET THE CONFIGURATION
	JZ	CHK_VIDEO2	; GO IF VIDEO ROM INSTALLED

	ADD	CX,080H	; POINT TO NEXT 2K BLOCK
	CMP	CX,0C800H	; TOP OF VIDEO ROM AREA YET?
	JL	CHK_VIDEO1	; TRY AGAIN
	AND	CX,CX	; SET NON ZERO FLAG
CHK_VIDEO2:
	RET		; RETURN TO CALLER

;-----	CMOS VIDEO BITS NON ZERO (CHECK FOR PRIMARY DISPLAY AND NO VIDEO ROM)

MOS_OK_1:
	CALL	CHK_VIDEO	; IS THE VIDEO ROM INSTALLED?
	JZ	BAD_MOS	; WRONG CONFIGURATION IN CONFIG BYTE

	MOV	AL,AH	; RESTORE CONFIGURATION
	TEST	@MFG_TST,DSP_JMP	; CHECK FOR DISPLAY JUMPER
	JZ	MOS_OK_2	; GO IF COLOR CARD IS PRIMARY DISPLAY

;-----	MONOCHROME CARD 15 PRIMARY DISPLAY IND JUMPER INSTALLED)

	AND	AL,30H	; INSURE MONOCHROME IS PRIMARY
	CMP	AL,30H	; CONFIGURATION OK?
	JNZ	BAD_MOS	; GO IF NOT
	MOV	AL,AH	; RESTORE CONFIGURATION
	JMP	SHORT MOS_OK	; USE THE CONFIGURATION BYTE FOR DISPLAY

;-----	COLOR CARD

MOS_OK_2:
	AND	AL,30H	; STRIP UNWANTED BITS
	CMP	AL,30H	; MUST NOT BE MONO WITH JUMPER INSTALLED
	MOV	AL,AH	; RESTORE CONFIGURATION
	JZ	BAD_MOS	; GO IF YES

;-----	CONFIGURATION MUST HAVE AT LEAST ONE DISKETTE

MOS_OK:	TEST	AL,01H	; MUST HAVE AT LEAST ONE DISKETTE
	JNZ	NORMAL_CONFIG	; GO SET CONFIGURATION IF OK
	TEST	@MFG_TST,MFG_LOOP	; EXCEPT IF MFG JUMPER IS INSTALLED
	JZ	NORMAL_CONFIG	; GO IF INSTALLED

;-----	MINIMUM CONFIGURATION WITH BAD CMOS OR NON VALID VIDEO

BAD_MOS:
	MOV	AX,CMOS_DIAG+NMI	; GET THE DIAGNOSTIC STATUS
	CALL	CMOS_READ
	TEST	AL,BAD_BAT+BAD_CKSUM	; WAS BATTERY DEFECTIVE OR BAD CHECKSUM
	JNZ	BAD_MOS1	; GO IF YES

	CALL	CONFIG_BAD	; SET THE MINIMUM CONFIGURATION FLAG
BAD_MOS1:
	CALL	CHK_VIDEO	; CHECK FOR VIDEO ROM
	MOV	AL,01H	; DISKETTE ONLY
	JZ	NORMAL_CONFIG	; GO IF VIDEO ROM PRESENT

	TEST	@MFC_TST,DSP_JMP	; CHECK FOR DISPLAY JUMPER
	MOV	AL,11H	; DEFAULT TO 4OX25 COLOR
	JZ	NORMAL_CONFIG	; GO IF JUMPER IS INSTALLED

	MOV	AL,31H	; DISKETTE / B/W DISPLAY 80X25

;------------------------------------------
;	CONFIGURATION AND MFG MODE	:
;------------------------------------------

NORMAL_CONFIG:
	TEST	@MFG_TST,MFG_LOOP	; IS THE MANUFACTURING JUMPER INSTALLED
	JNZ	NORM1	; GO IF NOT
	AND	AL,03EH	; STRIP DISKETTE FOR MFG TEST

NORM1:	SUB	AH,AH
	MOV	@EQUIP_FLAG,AX	; SAVE SWITCH INFORMATION
	CMP	@RESET_FLAG,1234H	; BYPASS IF SOFT RESET
	JZ	E6

;-----	GET THE FIRST SELF TEST RESULTS FROM KEYBOARD
	MOV	AL,WRITE_8042_LOC	; ENABLE KEYBOARD
	CALL	C8042	; ISSUE WRITE BYTE COMMAND
	MOV	AL,4DH	; ENABLE OUTPUT BUFFER FULL INTERRUPT,
			; SET SYSTEM FLAG, PC 1 COMPATIBILITY,
	OUT	PORT_A,AL	; INHIBIT OVERRIDE, ENABLE KEYBOARD

	SUB	CX,CX	; WAIT FOR COMMAND ACCEPTED
	CALL	C42_1
	MOV	CX,07FFFH	; SET LOOP COUNT FOR APPROXIMATELY 100MS
			; TO RESPOND
TST6:	IN	AL,STATUS_PORT	; WAIT FOR OUTPUT BUFFER FULL
	TEST	AL,OUT_BUF_FULL
	LOOPZ	TST6	; TRY AGAIN IF NOT

	PUSHF		; SAVE FLAGS
	MOV	AL,DIS_KBD	; DISABLE KEYBOARD
	CALL	C8042	; ISSUE THE COMMAND
	POPF		; RESTORE FLAGS
	JZ	E6	; CONTINUE WITHOUT RESULTS

	IN	AL,PORT_A	; GET INPUT FROM KEYBOARD
	MOV	BYTE PTR @RESET_FLAG,AL 	; TEMPORARY SAVE FOR AA RECEIVED

;-----	CHECK FOR MFG REQUEST

	CMP	AL,065H	; LOAD MANUFACTURING TEST REQUEST?
	JNE	E6	; CONTINUE IF NOT
	JMP	MFG_BOOT	; ELSE GO TO MANUFACTURING BOOTSTRAP
	
;--------------------------------------------------------
; TEST.14				  :
;       INITIALIZE AND START CRT CONTROLLER (6845)      :
;       TEST VIDEO READ/WRITE STORAGE.			  :
; DESCRIPTION				  :
;       RESET THE VIDEO ENABLE SIGNAL.			  :
;       SELECT ALPHANUMERIC MODE, 40 * 25, B & W. 	  :
;       READ/WRITE DATA PATTERNS TO MEMORY, CHECK 	  :
;       STORAGE ADDRESSABILITY.			  :
; ERROR = 1 LONG AND 2 SHORT BEEPS			  :
;--------------------------------------------------------

E6:
	MOV	AX,@EQUIP_FLAG	; GET SENSE INFORMATION
	PUSH	AX	; SAVE IT
	MOV	AL,30H	; FORCE MONOCHROME TYPE
	MOV	@EQUIP_FLAG,AX	; INTO EQUIPMENT FLAG
	SUB	AX,AX	; MODE SET COMMAND FOR DEFAULT MODE
	INT	INT_VIDEO	; SEND INITIALIZATION TO B/W CARD
	MOV	AL,20H	; FORCE COLOR AT 80 BY 25
	MOV	@EQUIP_FLAG,AX	; INTO EQUIPMENT FLAG TO CLEAR BUFFERS
	MOV	AX,0003H	; AND INITIALIZATION COLOR CARD 80X25
	INT	INT_VIDEO	; MODE SET 80 X 25
	MOV	AX,0001H	; SET COLOR 40 X 25 MODE
	INT	INT_VIDEO	; SET DEFAULT COLOR MODE
	POP	AX	; RECOVER REAL SWITCH INFORMATION
	MOV	@EQUIP_FLAG,AX	; RESTORE IT
	AND	AL,30H	; ISOLATE VIDEO SWITCHES
	JNZ	E7	; VIDEO SWITCHES SET TO 0?
	PUSH	DS	; SAVE THE DATA SEGMENT
	PUSH	AX
	SUB	AX,AX	; SET DATA SEGMENT TO 0
	MOV	DS,AX
	MOV	DI,OFFSET @VIDEO INT	; SET INTERRUPT 10H TO DUMMY
	MOV	WORD PTR [DI],OFFSET DUMMY_RETURN	; RETURN IF NO VIDEO CARD
	POP	AX	; RESTORE REGISTERS
	POP	DS
	JMP	SHORT E18_1	; BYPASS VIDEO TEST

E7:
	CMP	AL,30H	; B/W CARD ATTACHED?
	JE	E8	; YES - SET MODE FOR B/W CARD
	INC	AM	; SET COLOR MODE FOR COLOR CARD
	CMP	AL,20H	; 80X25 MODE SELECTED7
	JNE	E8	; NO - SET MODE FOR 40X25
	MOV	AH,3	; SET MODE FOR 8OX25

E8:	XCHG	AH,AL
	PUSH	AX	; SAVE VIDEO MODE ON STACK
	SUB	AH,AH	; INITIALIZE TO ALPHANUMERIC MD
	INT	INT_VIDEO	; CALL VIDEO_IO
	POP	AX	; RESTORE VIDEO SENSE SWITCHES IN AH
	PUSH	AX	; SAVE VALUE
	MOV	BX,0B000H	; STARTING VIDEO MEMORY ADDRESS B/W CARD
	MOV	DX,3B8H	; MODE REGISTER FOR B/W
	MOV	CX,2048	; MEMORY WORD COUNT FOR B/W CARD
	CMP	AH,30H	; B/W VIDEO CARD ATTACHED?
	JE	E9	; YES - GO TEST VIDEO STORAGE
	MOV	BH,0B8H	; STARTING MEMORY ADDRESS FOR COLOR CARD
	MOV	DX,3D8H	; MODE REGISTER FOR COLOR CARD
	MOV	CH,20H	; MEMORY WORD COUNT FOR COLOR CARD
E9:
	MOV	AL,@CRT_MODE_SET	; GET CURRENT MODE SET VALUE
	AND	AL,037H	; SET VIDEO BIT OFF
	OUT	DX,AL	; DISABLE VIDEO FOR COLOR CARD
	MOV	ES,BX	; POINT ES TO VIDEO MEMORY
	MOV	DS,BX	; POINT DS TO VIDEO MEMORY
	ROR	CX,1	; DIVIDE BY 2 FOR WORD COUNT
	CALL	STGTST_CNT	; GO TEST VIDEO READ/WRITE STORAGE
	JNE	E17	; R/W MEMORY FAILURE - BEEP SPEAKER

;------------------------------------------------
; TEST.15			:
;       SETUP VIDEO DATA ON SCREEN FOR VIDEO    :
;       LINE TEST.		:
; DESCRIPTION			:
;       ENABLE VIDEO SIGNAL AND SET MODE.		:
;       DISPLAY A HORIZONTAL BAR ON SCREEN.	:
;------------------------------------------------

	MOV	AL,22H	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	; 	  <><> CHECKPOINT  22 <><>

	POP	AX	; GET VIDEO SENSE SWITCHES (AH)
	PUSH	AX	; SAVE IT
	MOV	AH,0	; ENABLE VIDEO AND SET MODE
	INT	INT_VIDEO	; VIDEO
	MOV	AX,7020H	; WRITE BLANKS IN REVERSE VIDEO
	SUB	DI,DI	; SETUP STARTING LOCATION
	MOV	CX,40	; NUMBER OF BLANKS TO DISPLAY
	REP	STOSW	; WRITE VIDEO STORAGE

;------------------------------------------
; TEST.16		:
;	CRT INTERFACE LINES TEST	:
; DESCRIPTION		:
;	SENSE ON/OFF TRANSITION OF THE	:
;	VIDEO ENABLE AND HORIZONTAL	:
;	SYNC LINES	:
;------------------------------------------

	POP	AX	; GET VIDEO SENSE SWITCH INFORMATION
	PUSH	AX	; SAVE IT
	CMP	AH,30H	; B/W CARD ATTACHED7
	MOV	DX,03BAH	; SETUP ADDRESS OF B/W STATUS PORT
	JE	E11	; YES - GO TEST LINES
	MOV	DX,03DAH	; COLOR CARD IS ATTACHED
E11:
	MOV	AH,8
E12:
	SUB	CX,CX
E13:
	IN	AL,DX	; READ CRT STATUS PORT
	AND	AL,AH	; CHECK VIDEO/HORIZONTAL LINE
	JNZ	E14	; ITS ON - CHECK IF IT GOES OFF
	LOOP	E13	; LOOP UNTIL ON OR TIMEOUT
	JMP	SHORT E17	; GO PRINT ERROR MESSAGE
E14:
	SUB	CX,CX
E15:
	IN	AL,DX	; READ CRT STATUS PORT
	AND	AL,AH	; CHECK VIDEO/HORIZONTAL LINE
	JZ	E16	; ITS ON - CHECK NEXT LINE
	LOOP	E15	; LOOP IF ON UNTIL IT GOES OFF
	JMP	SHORT E17	; GO ERROR BEEP


;-----	CHECK HORIZONTAL LINE
E16:	MOV	CL,3	; GET NEXT BIT TO CHECK
	SHR	AH,CL
	JNZ	E12	; CONTINUE
E18:
	POP	AX	; GET VIDEO SENSE SWITCHES (AH)
	MOV	AH,0	; SET MODE AND DISPLAY CURSOR
	INT	INT_VIDEO	; CALL VIDEO I/O PROCEDURE

;-----	CHECK FOR THE ADVANCED VIDEO CARD

E18_1:	MOV	DX,0C000H	; SET THE LOW SEGMENT VALUE
E18A:
	MOV	AL,23H	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	;	  <><> CHECKPOINT  23 <><>
	MOV	DS,DX
	PUSH	DI	; SAVE WORK REGISTER
	MOV	DI,0AA55H	; PRESENCE SIGNATURE
	SUB	BX,BX	; CLEAR POINTER
	MOV	AX,[BX]	; GET FIRST 2 LOCATIONS
	CMP	AX,DI	; PRESENT?
	POP	DI	; RECOVER REGISTER
	JNZ	E18B	; N0? GO LOOK FOR OTHER MODULES

	CALL	ROM_CHECK	; GO SCAN MODULE
	JMP	SHORT E18C
E18B:
	ADD	DX,0080H	; POINT TO NEXT 2K BLOCK
E18C:
	CMP	DX,0C800H	; TOP OF VIDEO ROM AREA YET?
	JL	E18A	; GO SCAN FOR ANOTHER MODULE

	MOV	AL,24H	;	  <><><><><><><><><><><><>
	OUT	MFG_PORT,AL	;	  <><> CHECKPOINT  24 <><>
	JMP	POST2	; GO TO NEXT TEST

;-----	CRT ERROR SET MFG CHECKPOINT AND ERROR BEEP

E17:	CALL	DDS	; POINT TO DATA

;-----	CHECKPOINT OC = MONOCHROME FAILED
	
	MOV	@MFG_ERR_FLAG,0CH	; CRT ERROR CHECKPOINT OC
	CMP	BYTE PTR @RESET_FLAG,064H	 ; IS THIS A MFG REQUEST?
	JZ	E19	; BY PASS ERROR BEEP IF YES
	TEST	@MFG_TST,MFG_LOOP	; IS THE MFG LOOP JUMPER INSTALLED?
	JZ	E19	; BY PASS ERROR BEEP IF YES
	MOV	DX,102H
	CALL	ERR_BEEP	; GO BEEP SPEAKER
E19:
	PUSH	DS
	MOV	AX,@EQUIP_FLAG	; GET THE CURRENT VIDEO
	AND	AL,30H	; STRIP OTHER BITS
	CMP	AL,30H	; IS IT MONOCHROME
	JZ	TRY_COLOR	; GO IF YES

;-----	COLOR FAILED TRY MONOCHROME	; CHECKPOINT 0D = COLOR FAILED

	MOV	@MFG_ERR_FLAG,0DH	; <><> CRT ERROR CHECKPOINT 0D <><>

	MOV	DX,3B8H	; DISABLE B/W
	MOV	AL,1
	OUT	DX,AL	; OUTPUT THE DISABLE
	MOV	BX,0B000H	; CHECK FOR MONOCHROME VIDEO MEMORY
	MOV	DS,BX
	MOV	AX,0AA55H	; WRITE AN AA55
	SUB	BX,BX	; TO THE FIRST LOCATION
	MOV	[BX],AX
	JMP	$+2	; ALLOW BUS TO SETTLE
	MOV	AX,[BX]	; READ THE FIRST LOCATION
	CMP	AX,0AA55H	; IS THE MONOCHROME VIDEO CARD THERE7
	POP	DS	; RESTORE THE DATA SEGMENT
	JNZ	E17_3	; GO IF NOT
	OR	@EQUIP_FLAG,30H	; TURN ON MONOCHROME BITS IN EQUIP FLAG
	MOV	AX,@EQUIP_FLAG	; ENABLE VIDEO
	SUB	AH,AH
	INT	INT_VIDEO
	JMP	SHORT E17_1	; CONTINUE

;-----	MONOCHROME FAILED TRY COLOR
TRY_COLOR:
	MOV	AL,01H	; SET MODE COLOR 40X25
	SUB	AH,AH
	INT	INT_VIDEO
	MOV	DX,3D8H	; DISABLE COLOR
	MOV	AL,0
	OUT	DX,AL	; OUTPUT THE DISABLE
	MOV	BX,0B800H	; CHECK FOR COLOR VIDEO MEMORY
	MOV	DS,BX
	MOV	AX,0AA55H	; WRITE AN AA55
	SUB	BX,BX	; TO THE FIRST LOCATION
	MOV	[BX],AX
	JMP	$+2	; ALLOW BUS TO SETTLE
	MOV	AX,[BX]	; READ THE FIRST LOCATION
	CMP	AX,0AA55H	; IS THE COLOR VIDEO CARD THERE7
	POP	DS	; RESTORE THE DATA SEGMENT
	JNZ	E17_3	; GO IF NOT
	AND	@EQUIP_FLAG,0FFCFH	; TURN OFF VIDEO BITS
	OR	@EQUIP_FLAG,10H	; SET COLOR 40X24
	MOV	AL,01H
	SUB	AH,AH
	INT	INT_VIDEO
E17_1:
	POP	AX	; SET NEW VIDEO TYPE ON STACK
	MOV	AX,@EQUIP_FLAG
	AND	AL,30H
	CMP	AL,30H	; IS IT THE B/W?
	SUB	AL,AL
	JZ	E17_2	; GO IF YES

	INC	AL	; INITIALIZE FOR 40X25
E17_2:
	PUSH	AX
E17_4:
	JMP	E18

;-----	BOTH VIDEO CARDS FAILED SET DUMMY RETURN IF RETRACE FAILURE
E17_3:
	PUSH	DS
	SUB	AX,AX	; SET DS SEGMENT TO 0
	MOV	DS,AX
	MOV	DI,OFFSET @VIDEO_INT	; SET INTERRUPT 10H TO DUMMY
	MOV	WORD PTR [DI],OFFSET DUMMY_RETURN ; RETURN IF NO VIDEO CARD
	POP	DS
	JMP	E18_1	; BYPASS REST OF VIDEO TEST

;-------------------------------------------------------------------------------
; MANUFACTURING BOOT TEST CODE ROUTINE							 :
;       LOAD A BLOCK OF TEST CODE THROUGH THE KEYBOARD PORT FOR MANUFACTURING  :
;       TESTS.								 :
;       THIS ROUTINE WILL LOAD A TEST (MAX LENGTH,FAFFH) THROUGH THE KEYBOARD  :
;       PORT. CODE WILL BE LOADED AT LOCATION 0000:0500.   AFTER LOADING,	 :
;       CONTROL WILL BE TRANSFERRED TO LOCATION 0000:0500.  THE STACK WILL	 :
;       BE LOCATED AT 0000:0400.  THIS ROUTINE ASSUMES THAT THE FIRST 2 BYTES  :
;       TRANSFERRED CONTAIN THE COUNT OF BYTES TO BE LOADED 			 :
;       (BYTE 1=COUNT LOW, BYTE 2=COUNT HI.)						 :
--------------------------------------------------------------------------------

;-----	DEGATE ADDRESS LINE 20

MFG_BOOT:
	MOV	AH,DISABLE_BIT20	; DEGATE COMMAND FOR ADDRESS LINE 20
	CALL	GATE_A20	; ISSUE TO KEYBOARD ADAPTER AND CLI

;-----	SETUP HARDWARE INTERRUPT VECTOR TABLE LEVEL 0-7 AND SOFTWARE INTERRUPTS
	PUSH	ABS0	; SET ES SEGMENT REGISTER TO ABS0
	POP	ES
	MOV	CX,24	; GET VECTOR COUNT
	MOV	AX,CS	; GET THE CURRENT CODE SEGMENT VALUE
	MOV	DS,AX	; SETUP DS SEGMENT REGISTER TO
	MOV	SI,OFFSET VECTOR_TABLE	; POINT TO THE ROUTINE ADDRESS TABLE
	MOV	DI,OFFSET @INT_PTR	; SET DESTINATION TO FIRST USED VECTOR
MFG_B1:
	MOVSW		; MOVE ONE ROUTINE OFFSET ADDRESS
	STOSW		; INSERT CODE SEGMENT VALUE
	LOOP	MFG_B1	; MOVE THE NUMBER OF ENTRIES REQUIRED

;-----	SETUP HARDWARE INTERRUPT VECTORS LEVEL 8-15 (VECTORS START AT INT 70 H)

	MOV	CX,08	; GET VECTOR COUNT
	MOV	SI,OFFSET SLAVE_VECTOR_TABLE
	MOV	DI,OFFSET @SLAVE_INT_PTR
MFG_B2:
	MOVSW		; MOVE ONE ROUTINE OFFSET ADDRESS
	STOSW		; INSERT CODE SEGMENT VALUE
	LOOP	MFG_B2

;-----	SET UP OTHER INTERRUPTS AS NECESSARY

	ASSUME	DS:ABS0,ES:ABS0
	PUSH	ES				; ES= ABS0
	POP	DS				; SET DS TO ABS0
	MOV	WORD PTR @NMI_PTR,OFFSET NMI_INT 		; NMI INTERRUPT
	MOV	WORD PTR @INT5_PTR,OFFSET PRINT_SCREEN	; PRINT SCREEN
	MOV	WORD PTR @BASIC_PTR+2,0F600H			; CASSETTE BASIC SEGMENT

;-----	ENABLE KEYBOARD PORT
	MOV	AL,60H	; WRITE 8042 MEMORY LOCATION 0
	CALL	C8042	; ISSUE THE COMMAND
	MOV	AL,00001001B	; SET INHIBIT OVERRIDE/ENABLE OBF
	OUT	PORT_A,AL	; INTERRUPT AND NOT PC COMPATIBLE

	CALL	MFG_B4	; GET COUNT LOW
	MOV	BH,AL	; SAVE IT
	CALL	MFG_B4	; GET COUNT HI
	MOV	CH,AL
	MOV	CL,BH	; CX NOW HAS COUNT
	CLD		; SET DIRECTION FLAG TO INCREMENT
	MOV	DI,OFFSET @MFG_TEST_RTN	; SET TARGET OFFSET (DS=0000)
MFG_B3:
	IN	AL,STATUS PORT	; GET 8042 STATUS PORT
	TEST	AL,OUT_BUF_FULL	; KEYBOARD REQUEST PENDING?
	JZ	MFG_B3	; LOOP TILL DATA PRESENT
	IN	AL,PORT_A	; GET DATA
	STOSB		; STORE IT
	OUT	MFG_PORT,AL	; DISPLAY CHARACTER AT MFG PORT
	LOOP	MFG_B3	; LOOP TILL ALL BYTES READ

	JMP	@MFG_TEST_RTN	; FAR JUMP TO CODE THAT WAS JUST LOADED

MFG_B4:	IN	AL,STATUS_PORT	; CHECK FOR OUTPUT BUFFER FULL
	TEST	AL,OUT_BUF_FULL	; HANG HERE IF NO DATA AVAILABLE
	LOOPZ 	MFG_B4

	IN	AL,PORT_A	; GET THE COUNT
	RET

POST1	ENDP
CODE	ENDS
	END
