;	[]===========================================================[]
;
;	NOTICE: THIS PROGRAM BELONGS TO AWARD SOFTWARE INTERNATIONAL(R)
;	        INC. IT IS CONSIDERED A TRADE SECRET AND IS NOT TO BE 	
;	        DIVULGED OR USED BY PARTIES WHO HAVE NOT RECEIVED	
;	        WRITTEN AUTHORIZATION FROM THE OWNER.
;
; 	[]===========================================================[]
;

;----------------------------------------------------------------------------
;Rev	Date	 Name	Description
;----------------------------------------------------------------------------
;R20	03/24/99 RAY	Add switch: NO_Y2K_CHECK for some customer that they
;			have RTC that supports century
;R19D	12/01/98 TNY	Set "Ct_Save_RTC_Index" hook called between 1 sec.
;R19C	02/02/98 TNY	Save PCI index port and eax.
;R19B	01/13/98 TNY	Add hook "Ct_Save_RTC_Index" to save RTC index port
;			for security.
;R19A	12/05/97 RCH	Check CMOS "update in progress" bit to prevent error
;			CMOS year reading.
;R19	11/14/97 RCH	Fixed Year2000 test program(WILLIT.EXE) with run-time
;			patching CMOS century value. It is optional, because
;			BIOS need to access CMOS periodically that will
;			cause some imcompatibility problems.
;R18	10/07/97 RCH	Fixed UIE only be serviced once if user enable UIE
;			of RTC and IRQ 8 is unmasked.
;R17	11/18/96 RCH	Program YEAR2000.EXE designed by NSTL call INT 1AH
;			function 04H to get date information to check year
;			2000 supporting. BIOS must have some patches in this
;			routine to pass the testing.
;R16	04/12/96 RCH	Bit 3 of CMOS 0BH is used to control square wave
;			output of RTC chip, Don't touch this bit while do
;			INT 1AH function call.Industry PC use this to do
; 		        watch dog monitoring.	
;R15	10/13/95 DNL	Fixed up INT15-83h hang after multi-running
;R14	09/07/94 KVN	Fixed up Windows+ACAD9 hang in 128k bios
;			1. Move SETSPEED.ASM to F000 from E000 and rename old
;			   file to SETSPEED.128
;			2. Move CPINSTAL.ASM to E000 from F000
;			3. Move FPINSTAL.ASM to E000 from F000
;			4. Modify ATORGS.ASM and rename old file to ATORGS.128
;			5. Modify POST.ASM, AKBRD.ASM
;R13	07/18/94 KVN	Fixed up floppy motor can't to be turn off while run
;			'WINBACKUP' file.So [MOTOR_OFF_WAIT] count down when
;			is not zero and turn off motor when count to zero.
;R12	03/10/94 RAY	Mask off CALL_TABLE option
;	07/18/94 RCH	If always output port 3f2H , system can not enter
;			power down mode , because the PM chipset detect
;			this port as PM activity.
;R11	01/11/94 RCH	Don't send I/O to port 3f2h if motor is off already
;	07/18/94 RCH	If always output port 3f2H , system can not enter
;			power down mode , because the PM chipset detect
;			this port as PM activity.
;R10	12/04/93 RCH	Don't enable interrupt (STI) before calling PCI 
;			interface because NCR gererate IRQ during SCSI/HDD
;			initialization
;R09	11/08/93 RCH	Fixed PCI NCR/SCSI OS2 driver failure bug ( Don't use
;			far jump in PCI extension functions from absolute
;			address F000:FE6E , because the driver call this
;			absolute address in protected mode )
;R08	10/13/93 RCH	Complete special cycle generation function
;R07	10/05/93 RCH	Note: The BX definition of real & 32-bit mode is
;			different.
;R06	09/06/93 RCH	Don't return bit 7 high in BX
;R05	09/03/93 RAY	1. Clean the PCI service routine codes
;			   note: all old codes(R01, R02) is deleted
;			2. Move the 32 bits functions to file PCI32.ASM
;			3. Align the whole file to PARA so as to meet
;			   the PCI 2.0 spec.
;R04	08/18/93 RAY	Ugrade PCI function to 20.G
;R03	08/17/93 RCH	Don't send EOI to 8259 before leaving service routine
;R02	07/30/93 RAY	Ugrade PCI function to 20.c
;R01	04/28/93 RCH	Added PCI function support in INT 1AH
;R00	02/22/93 RCH    Initial release for 4.50

.386
;[]-----------------------------------[]
;
;   Award Software 386/486 BIOS
;         Timer handling
;   Initial Revision 30-Apr-1990
;
;[]-----------------------------------[]

.XLIST
		INCLUDE BIOS.CFG
		INCLUDE COMMON.EQU

		INCLUDE 8259.EQU
		INCLUDE CMOS.EQU

		INCLUDE ATORGS.EXT

		INCLUDE COMMON.MAC
		extrn	Turbo_Pin_Hdlr:near
.LIST

;[]---------------------------[]
;
;   Low memory init (1st 64k)
;
;[]---------------------------[]


G_RAM		SEGMENT	USE16 AT 40H		; ALL HERE BUT 40:3FH, 40:40H 3.04
		INCLUDE	G_RAM.INC
G_RAM		ENDS

;
;REQUESTER_FLG_OFFSET	=	098H		;

;;;;;;;;; WAIT EQUATES
;Wait for update NOT in progress.
;Wait needs to be at least 244Us + 1984Us. See Motorola 8-bit
;microprocessor & peripheral data, pg. 3-713.
;Multiply by 4 to reduce chance of interrupts occuring during
;update in progress and lasting until next update in progress.
;assume each read takes 2 microseconds.

WAITCPU_CK_UD_STAT	EQU	((1984+244)*4)/2


		extrn	Int8_Hook:near		;128K
ifdef	PCI_BUS					;128K
		extrn	Pci_Procedure:near	;128K
endif;	PCI_BUS					;128K
		extrn	POST_func_end:Near	;128k
		extrn	POST_VECT:Near		;128k

;R05 FCODE		SEGMENT	USE16 DWORD PUBLIC 'CODE'
FCODE		SEGMENT	USE16 PARA PUBLIC 'CODE'	;R05
		ASSUME	CS:FCODE


;******************************************************
;Name:   	Time_day_start
;Entry:  	called by int 1ah
;Input:  	ah=function
;               other regs as described below
;Output: 	regs as described below
;******************************************************

		ALIGN	4
		PUBLIC	TIME_DAY_START
;R09	TIME_DAY_START	PROC	FAR
TIME_DAY_START	PROC	NEAR					;R09

		PUBLIC	TDS_S
TDS_S:
;R10		STI
;R01 - start
ifdef	PCI_BUS
PCI_FUNCTION_ID	EQU	0B1H
		cmp	ah,PCI_FUNCTION_ID
		jne	short @F
;128K		extrn	Pci_Procedure:near
		jmp	Pci_Procedure
@@:
endif;	PCI_BUS
;R01 - end
		STI				;R10
		CMP	AH,7			; SEE IF VALID AND
		JBE	SHORT VALID_REQUEST	; SET CARRY FOR POSSIBLE ERR
		STC
;R09		RET	2
		RETF	2					;R09

VALID_REQUEST:
		PUSH	BX
		MOV	BL,AH			; WORD INDEX
		XOR	BH,BH
		SHL	BX,1
		JMP	cs:TIMEHDLR_TBL[BX]	; INT 1A FUNCTIONS BRANCH TABLE

ERR_1B:						; Return here for failure due to update in progress
		;when trying to read date or time
		XOR	AL,AL

ERR_1A:						; Return here for failure of 1A invocation
		STC
		JMP	SHORT RET_1A

		; RETURN HERE FOR SUCCESSFUL 1A INVOCATION
SUCCESS_1A:	CLC

RET_1A:		MOV	AH,0
		POP	BX
		STI
;R09		RET	2
		RETF	2					;R09

;******************************************************
;Name:   	get_soft_time
;Entry:  	called from Time_day_start
;Input:  	ah=0
;Output: 	cx=high count
;   	    	dx=low count
;   	    	al=0 if get_soft_time not overflowed since last call
;   	    	al<>0 otherwise
;Description:
;
;get_soft_time will:
;1. 	save environment
;2. 	obtain time values from software clock
;3. 	restore environment
;4. 	return to Time_day_start
;******************************************************

GET_SOFT_TIME:	CLI
		PUSH	DS
		MOV	BX,G_RAM		; address of segment
		MOV	DS,BX
		ASSUME	DS:G_RAM
		MOV	BX,OFFSET LOW_8254_CNT

		MOV	DX,[BX]			; return current free
		MOV	CX,[BX+2]
		XOR	AL,AL			; running clock values
		XCHG	AL,[BX+4]		; and clear overflow
		POP	DS
		JMP	SHORT SUCCESS_1A

;******************************************************
;Name:   	put_soft_time
;Entry:  	called from Time_day_start
;Input:  	ah=1
;   	    	cx=high count
;   	    	dx=low count
;Output: 	none
;Description:
;
;put_soft_time will:
;1. 	save environment
;2. 	set the software clock with requested values
;3. 	restore environment
;4. 	return to Time_day_start
;******************************************************

SET_SOFT_TIME:	CLI
		PUSH	DS
		MOV	BX,G_RAM
		MOV	DS,BX
		ASSUME	DS:G_RAM
		MOV	BX,OFFSET LOW_8254_CNT

		MOV	[BX],DX			; set values
		MOV	[BX+2],CX
		MOV	BYTE PTR [BX+4],0
		POP	DS
		JMP	SHORT SUCCESS_1A

;******************************************************
;Name:   	Get_Rtime
;Entry:  	called from Time_day_start
;Input:  	ah=2
;Output: 	if clock operating
;                 ch=hours in BCD
;                 cl=minutes in BCD
;   	    	 dh=seconds in BCD
;                 cy=0
;                else cy=1
;Description:
;
;Return the real time clock time of day in BCD format.
;
;Get_Rtime will:
;1. 	save environment
;2. 	obtain time values from system clock
;3. 	restore environment
;4. 	return to Time_day_start
;******************************************************

GET_RTIME:	CALL	CK_UD_STAT		; SEE IF CURRENTLY UPDATING
		OR	AL,AL
		JNZ	SHORT ERR_1B		; IF SO GET OUT

		CLI
		MOV	AL,04 NMI_ON		; GET THE HOURS
		CALL	GET_CMOS
		MOV	CH,AL
		MOV	AL,02 NMI_ON		; GET THE MINUTES
		CALL	GET_CMOS
		MOV	CL,AL
		MOV	AL,00 NMI_ON
		CALL	GET_CMOS		; GET THE SECONDS
		MOV	DH,AL
		MOV	AL,0BH NMI_ON		; get daylight mode.
		CALL	GET_CMOS
		AND	AL,01H
		MOV	DL,AL
		MOV	AL,CH			; al=hours
		JMP	SUCCESS_1A		; AND DONE

;******************************************************
;Name:   	set_rtime
;Entry:  	called from Time_day_start
;Input:  	ah=3
;        	ch=hours in BCD
;                cl=minutes in BCD
;   	    	dh=seconds in BCD
;                dl=1 if daylight savings time option, else 0 for standard.
;Output:         none
;
;Description:
;
;Set the real time clock time of day in BCD format.
;
;set_rtime will:
;1. 	save environment
;2. 	set the system clock with requested values
;3. 	restore environment
;4. 	return to Time_day_start
;******************************************************

SET_RTIME:	CALL	CK_UD_STAT		; see if clock running
		OR	AL,AL
		JZ	SHORT SET_CLK

		CALL	INIT_RTC

SET_CLK:	CLI
		AND	DL,01H			; range check DST/ST
		MOV	AL,04 NMI_ON		; SET THE HOURS
		MOV	AH,CH
		CALL	SET_CMOS
		MOV	AL,02 NMI_ON		; SET THE MINUTES
		MOV	AH,CL
		CALL	SET_CMOS
		MOV	AL,00 NMI_ON
		MOV	AH,DH			; SET THE SECONDS
		CALL	SET_CMOS

		MOV	AL,0BH NMI_ON		; GET CONTROL BYTE
		CALL	GET_CMOS
		MOV	AH,AL
;R16		AND	AH,62H			; AND FOR DEFAULTS
		and	ah,6AH			; keep bit 3 unchange.	;R16
		OR	AH,2			; SET 24 HOUR MODE
		OR	AH,DL			; OR IN USER'S DST OR ST
		MOV	AL,0BH NMI_ON		; AND SET IT
		CALL	SET_CMOS
		JMP	SUCCESS_1A

;******************************************************
;Name:   	get_rdate
;Entry:  	called from Time_day_start
;Input:  	ah=4
;Output: 	if clock operating
;                 ch=century in BCD (19 or 20)
;                 cl=year in BCD
;                 dh=month in BCD
;                 dl=day in BCD
;                 cy=0
;                else cy=1
;Description:
;
;Read date from real time clock.
;
;get_rdate will:
;1. 	save environment
;2. 	set the system clock with requested values
;3. 	restore environment
;4. 	return to Time_day_start
;******************************************************

GET_RDATE:	CALL	CK_UD_STAT		; see if clock operating
		OR	AL,AL
		JZ	SHORT READ_DATEOK

		JMP	ERR_1B

READ_DATEOK:	CLI
		MOV	AL,32H NMI_ON		; GET THE CENTURY
		CALL	GET_CMOS
		MOV	CH,AL
		MOV	AL,09 NMI_ON		; GET THE YEAR
		CALL	GET_CMOS
		MOV	CL,AL
ifndef	NO_Y2K_CHECK				;R20
;R17 - start
;Return and set CMOS to 20XX if the century value in CMOS is 19.
		cmp	al,80H			;beyond 198X ?
		jae	short Good_YearBCD	;yes,

		cmp	ch,19H			;year 19XX ?
		ja	short Good_YearBCD	;yes

		mov	ch,20H			;no, return century to 20XX
		mov	al,32H NMI_ON		;set century into CMOS
		mov	ah,ch
		call	Set_Cmos
Good_YearBCD:
;R17 - end
endif	;NO_Y2K_CHECK				;R20
		MOV	AL,08 NMI_ON		; GET THE MONTH
		CALL	GET_CMOS
		MOV	DH,AL
		MOV	AL,07 NMI_ON		; GET THE DAY
		CALL	GET_CMOS
		MOV	DL,AL
		MOV	AL,CH			; AL=century.
		JMP	SUCCESS_1A

;******************************************************
;Name:   	Set_RDate
;Entry:  	called from Time_day_start
;Input:  	ah=5
;           	ch=century in BCD (19 or 20)
;                cl=year in BCD
;                dh=month in BCD
;                dl=day in BCD
;Output: 	none
;Description:
;
;Set the date into the real time clock.
;
;Set_RDate will:
;1. 	save environment
;2. 	set the system clock with requested values
;3. 	restore environment
;4. 	return to Time_day_start
;******************************************************

SET_RDATE:	CALL	CK_UD_STAT		; see if clock running
		OR	AL,AL
		JZ	SHORT SET_DATE

		CALL	INIT_RTC

SET_DATE:	CLI
		MOV	AL,32H NMI_ON		; SET THE CENTURY
		MOV	AH,CH
		CALL	SET_CMOS
		MOV	AL,09 NMI_ON
		MOV	AH,CL			; SET THE YEAR
		CALL	SET_CMOS
		MOV	AL,08 NMI_ON
		MOV	AH,DH			; SET THE MONTH
		CALL	SET_CMOS
		MOV	AL,07 NMI_ON
		MOV	AH,DL			; SET THE DAY
		CALL	SET_CMOS
		MOV	AL,06 NMI_ON
		XOR	AH,AH
		CALL	SET_CMOS

		MOV	AL,0BH NMI_ON
		CALL	GET_CMOS		; GET CONTROL BYTE
		AND	AL,7FH			; and set clock running
		MOV	AH,AL
		MOV	AL,0BH NMI_ON
		CALL	SET_CMOS
		JMP	SUCCESS_1A

;******************************************************
;Name:   	Set_Alarm
;Entry:  	called from Time_day_start
;Input:  	ah=6
;   	    	ch=hours in BCD
;                cl=minutes in BCD
;                dh=seconds in BCD
;Output: 	cy=1 if clock not operating
;                cy=0 if clock operating
;Description:
;
;Set_Alarm will:
;1. 	save environment
;2. 	set the system clock alarm with requested values. When
;        alarm is activated the routine at interrupt 70H.
;3. 	restore environment
;4. 	return to Time_day_start
;******************************************************

SET_ALARM:	MOV	AL,0BH NMI_ON
		CALL	GET_CMOS
		TEST	AL,20H
		JZ	SHORT DO_SET_ALR

		JMP	ERR_1A			; IF SO REPORT IT

DO_SET_ALR:	CALL	CK_UD_STAT		; IF UPDATING THEN STOP UPDATE MODE
		OR	AL,AL
		JZ	SHORT NO_INIT

		CALL	INIT_RTC

NO_INIT:	CLI
		IN	AL,B8259+1		; ENABLE 8259 ALARM INTERRUPT
		AND	AL,0FEH
		SIODELAY
		OUT	B8259+1,AL
		MOV	AL,05 NMI_ON		; SET HOUR ALARM
		MOV	AH,CH
		CALL	SET_CMOS
		MOV	AL,03 NMI_ON
		MOV	AH,CL			; SET MINUTES ALARM
		CALL	SET_CMOS
		MOV	AL,01 NMI_ON
		MOV	AH,DH			; SET SECONDS ALARM
		CALL	SET_CMOS
		MOV	AL,0BH NMI_ON		; SET AIE
		CALL	GET_CMOS
		AND	AL,7FH
		OR	AL,20H
		MOV	AH,AL
		MOV	AL,0BH NMI_ON
		CALL	SET_CMOS
		JMP	SUCCESS_1A

;******************************************************
;Name:   	Reset_Alarm
;Entry:  	called from Time_day_start
;Input:  	ah=7
;Output: 	none
;Description:
;
;put_soft_time will:
;1. 	save environment
;2. 	reset the alarm mode on system clock
;3. 	restore environment
;4. 	return to Time_day_start
;******************************************************

RESET_ALARM:	CLI
		MOV	AL,0BH NMI_ON		; DISABLE AIE
		CALL	GET_CMOS
;R16		AND	AL,57H
		and	al,5fH			; keep bit 3 unchange	;R16
		MOV	AH,AL
		MOV	AL,0BH NMI_ON
		CALL	SET_CMOS
		JMP	SUCCESS_1A

		; 1A FUNCTION JUMP TABLE

		ALIGN	4
TIMEHDLR_TBL	DW	OFFSET GET_SOFT_TIME
		DW	OFFSET SET_SOFT_TIME
		DW	OFFSET GET_RTIME
		DW	OFFSET SET_RTIME
		DW	OFFSET GET_RDATE
		DW	OFFSET SET_RDATE
		DW	OFFSET SET_ALARM
		DW	OFFSET RESET_ALARM

TIME_DAY_START	ENDP

;******************************************************
;Name:   	Init_RTC
;Entry:  	called
;Input:  	none
;Output: 	ax destroyed
;		CLI in effect
;Description:
;Init_RTC will:
;1. 	set clock operating frequency, stop updating and reset it
;******************************************************

INIT_RTC	PROC	NEAR

		CLI				; interrupts off while
						; changing CMOS
		MOV	AL,0AH NMI_ON
		MOV	AH,26H			; 32.8KHZ BASE,1.024KHZ SQ. WAVE,976.6 uSEC PI
		CALL	SET_CMOS
		MOV	AL,0BH NMI_ON
		MOV	AH,82H			; STOP UPDATING, 24 HOUR MODE
		call	Get_Cmos		; Read current value	;R16
		and	al,08H			; get bit 3 status	;R16
		or	ah,al						;R16		
		mov	al,0BH NMI_ON					;R16
		CALL	SET_CMOS
		MOV	AL,0CH NMI_ON
		CALL	GET_CMOS		; READ AND RESET
		RET

INIT_RTC	ENDP

;******************************************************
;Name:   	CK_UD_STAT
;Entry:  	called
;Input:  	none
;Output: 	if ok to update
;			al=0
;			CLI in effect
;		else
;			al <>0
;			STI in effect
;Description:
;ck_ud_stat will:
;1. 	wait for no update in progress and return al == 0save environment
;2. 	reset the alarm mode on system clock
;3. 	restore environment
;4. 	return to Time_day_start
;******************************************************

CK_UD_STAT	PROC	NEAR

		PUSH	CX
		MOV	CX,WAITCPU_CK_UD_STAT	; timeout value

		ALIGN	4
CK_UD_LOOP:	CLI				; stop interrupts
						; while accessing CMOS
		MOV	AL,0Ah NMI_ON
		OUT	CMOS,AL
		NEWIODELAY
		IN	AL,CMOS+1

		AND	AL,80H			; TEST FOR UPDATE IN PROGRESS
		JZ	SHORT CK_UD_EXIT

		STI				; allow interrupts.
		LOOP	SHORT CK_UD_LOOP

		MOV	AL,80H			; indicate timeout.
CK_UD_EXIT:
		POP	CX
		RET

CK_UD_STAT	ENDP

		PAGE

		;****************************************
		;*                                      *
		;*    INT 8 - TIME TICK OFF 8254        *
		;*                                      *
		;****************************************

		ALIGN	4
		PUBLIC	T_S
T_S:		STI

IFDEF CALL_TABLE							   
;requires a table of dword ptrs to reside at F000:0 which may just point   
;to a far return or may point to a user maintained routine.                
IF1
   %OUT CALL_TABLE Timer hook enabled
ENDIF

		call	dword ptr CS:[4*13]	; Entry 13 dec		   
ENDIF									   

		PUSH	DS			; some app. programs that use
						; 1CH as timer ticks
		PUSH	SI			; require that DS,AX,DX are
						; saved at time of 1CH
		MOV	SI,G_RAM		; so have to (see below)
		MOV	DS,SI
		ASSUME	DS:G_RAM


		MOV	SI,OFFSET LOW_8254_CNT	; address them

ifndef	NO_Y2K_CHECK				;R20
;R19 - start
ifdef	PATCH_WILLIT_YEAR2000
;Force year to 20XXH if the year in CMOS is smaller than 1980H. It's used 
;to fix Year 2000 test program - WILLIT.EXE, This program set RTC to 23:59:59
;12/31/1999 and wait BIOS to set the century to 20.
		cli
;R19C		push	ax

		pushad				;R19C
		mov	dx,0cf8h		;R19C
		in	eax,dx			;R19C
		push	eax			;R19C

;R19D		extrn	Ct_Save_RTC_Index:near	;R19B
;R19D		call	Ct_Save_RTC_Index	;R19B
;R19D		push	ax			;R19B
;R19D
;R19D		test	byte ptr [si],1111b	;every 16x56ms
;R19D		jnz	short NoChkCentury

;R19D - start
		test	byte ptr [si],1111b	;every 16x56ms
		jnz	short NoChkCentury1

		extrn	Ct_Save_RTC_Index:near	
		call	Ct_Save_RTC_Index	
		push	ax			
;R19D - end

		mov	al,32h NMI_ON		;read century value
		call	Get_Cmos
		cmp	al,19H			;19th ?
		jne	short NoChkCentury
 
;R19A - start
	;the CMOS RTC is invalid if the "update in progress" is set.
		mov	al,0AH NMI_ON		;update in progress ?
		call	Get_Cmos
		test	al,80H			;yes, 
		jnz	short NoChkCentury	;skip year 2000 checking
;R19A - end
	
		mov	al,09H NMI_ON		;read year value
		call	Get_Cmos

		cmp	al,80H			;before 2080H ?
		jae	short NoChkCentury
	
		mov	ah,20H
		mov	al,32h NMI_ON		;write new century value
		call	Set_Cmos

NoChkCentury:

		pop	ax			;R19B
		out	70h,al			;R19B

NoChkCentury1:					;R19D

		pop	eax			;R19C
		mov	dx,0cf8h		;R19C
		out	dx,eax			;R19C
		popad				;R19C

;R19C		pop	ax
		sti
endif;	PATCH_WILLIT_YEAR2000
;R19 - end
endif	;NO_Y2K_CHECK				;R20

		ADD	WORD PTR [SI],1
		ADC	WORD PTR [SI+2],0
		CMP	WORD PTR [SI+2],18H	; see if next day
		JNE	SHORT T3

		CMP	WORD PTR [SI],0B0H
		JNE	SHORT T3

		MOV	WORD PTR [SI],0		; clear time and set overflow
		MOV	WORD PTR [SI+2],0
		MOV	BYTE PTR [SI+4],1

T3:		POP	SI			; recover si
		PUSH	AX
		PUSH	DX			; diskette time out check
		cmp	BYTE PTR DS:[MOTOR_OFF_WAIT],0		;R13
		je	SHORT T4				;R13
;R13		DEC	BYTE PTR DS:[MOTOR_OFF_WAIT]
;R13		JNZ	SHORT T4

;R11 ifdef SKIP_MOTOR_OFF_WHEN_OFF
;R13		TEST	BYTE PTR DS:[MOTOR_ON_IND],0fh ;drive run flags
;R13		jz	T4
;R11 endif ;SKIP_MOTOR_OFF_WHEN_OFF

		DEC	BYTE PTR DS:[MOTOR_OFF_WAIT]		;R13
		JNZ	SHORT T4				;R13
		AND	BYTE PTR DS:[MOTOR_ON_IND],0F0H	; drive run flags
		MOV	DX,3F2H			; and kill controller
		MOV	AL,0CH
		OUT	DX,AL

T4:		INT	1CH			; do user timer tick

;R03		inc	byte ptr ds:[Turbo_Pin_Interval]
;R03		test	byte ptr ds:[Turbo_Pin_Interval],08h
;R03		jz	No_Turbo_Pin_Hdlr
;R03		MOV	AL,END_OF_INT		; CLEAR 8259
;R03		OUT	A8259,AL		; and clear interrupt
		call	Turbo_Pin_Hdlr	
;R03		mov	byte ptr ds:[Turbo_Pin_Interval],0
;R03No_Turbo_Pin_Hdlr:

;128K		extrn	Int8_Hook:near
		call	Int8_Hook 	; special process (chipset dependent)

		CLI


				; stop interrupts before iret - V3.00
		MOV	AL,END_OF_INT		; CLEAR 8259
		OUT	A8259,AL		; and clear interrupt
		POP	DX
		POP	AX
		POP	DS
		IRET

		PAGE

		;****************************************
		;*                                      *
		;*   PROGRAMMED INTERUPT ON CMOS CLOCK  *
		;*   INT 70H                            *
		;****************************************

		PUBLIC	PIE_AIE_HDLR
PIE_AIE_HDLR	PROC	FAR

		PUSH	AX
		MOV	AL,0BH NMI_ON
		CALL	GET_CMOS
		TEST	AL,60H			; SEE IF AIE OR PIE WAS ENABLED
;R18		JNZ	SHORT TRUE_INT
;R18
;R18		JMP	SHORT END_CLK_INT	; IF NOT CLEAR 8259 AND RETURN
		jz	short Safe_Return	; R18 read register C to clear
						; interrupt flag

TRUE_INT:	MOV	AL,0CH NMI_ON
		CALL	GET_CMOS		; NOW SEE WHICH ONE CAUSED INT
		TEST	AL,60h			;R15
		JZ	SHORT END_CLK_INT	;R15
		TEST	AL,20H			; CHECK FOR AI
		JZ	SHORT CK_PI		; IF NOT GO CK FOR PI

		PUSH	AX
		INT	4AH			; CALL USER ROUTINE
		POP	AX

CK_PI:		TEST	AL,40H			; CK FOR PI
;R15		JZ	SHORT END_CLK_INT
		JZ	SHORT SAFE_RETURN	;R15

		PUSH	DS
		PUSH	SI
		MOV	SI,G_RAM		; address segment
		MOV	DS,SI
		ASSUME	DS:G_RAM
		MOV	SI,OFFSET REQUESTER_FLG_OFFSET	; get offset - V2.07 change
		SUB	WORD PTR [SI+4],977	; DECREMENT USERS WAIT COUNT
		SBB	WORD PTR[SI+6],0
		JNC	SHORT END_CK_PI		; SEE IF EVENT WAIT IS UP

		;we also have to clear the wait in use flag!		   
		mov	byte ptr ds:[WAIT_IN_USE], 0			   

		MOV	AL,0BH NMI_ON
		CALL	GET_CMOS		; IF SO DISABLE PIE
;R16		AND	AL,37H			; MASK BIT 7,BIT 3 OFF
		and	al,3fH			; mask bit 7   	;R16
		MOV	AH,AL
		MOV	AL,0BH NMI_ON
		CALL	SET_CMOS

		LDS	SI,DWORD PTR[SI]
		ASSUME	DS:NOTHING
		MOV	BYTE PTR [SI],80H

END_CK_PI:	POP	SI
		POP	DS

;R15 - start
SAFE_RETURN:
		MOV	AL,0CH NMI_ON		
		CALL	GET_CMOS
;R15 - end		
END_CLK_INT:	MOV	AL,END_OF_INT		; CLEAR 8259
		OUT	B8259,AL
		SIODELAY
		OUT	A8259,AL
		POP	AX
		IRET

PIE_AIE_HDLR	ENDP


FCODE		ENDS
		END
