www.pudn.com > hpbios.rar > ATIME.ASM


;	[]===========================================================[] 
; 
;	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 
;---------------------------------------------------------------------------- 
;R20B	06/03/99 TNY	ICH need Y2K patch to fix some y2000 program test 
;			fail. 
;R20A	05/26/99 TNY	ICH do not need Y2K check at runtime. Also patch 
;			the UIP glitch of ICH B0 stepping bug. 
; 
;R20	03/24/99 RAY	Add switch: NO_Y2K_CHECK for some customer that they 
;			have RTC that supports century 
;990222		 RAY	Use ML 6.x to compile 
;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. 
 
ifdef	MASM611				;990222 
.MODEL  SMALL, BASIC			;990222 
OPTION	PROC: PRIVATE			;990222 
endif	;MASM611			;990222 
 
		PAGE	60,132 
 
.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 
 
 
ifdef	PCI_BUS					 
		extrn	Pci_Procedure:near	 
endif;	PCI_BUS					 
		extrn	Int8_Hook:near		 
		extrn	POST_func_end:Near	 
		extrn	POST_VECT:Near		 
 
FCODE		SEGMENT	USE16 PARA PUBLIC 'CODE' 
		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 
TIME_DAY_START	PROC	NEAR			 
 
		PUBLIC	TDS_S 
;990222 TDS_S: 
TDS_S		Label	Near			;990222 
 
ifdef	PCI_BUS 
	;Check if PCI BIOS service handler 
PCI_FUNCTION_ID	EQU	0B1H 
		cmp	ah,PCI_FUNCTION_ID 
		jne	short @F 
		jmp	Pci_Procedure 
@@: 
endif;	PCI_BUS 
 
		STI			 
		CMP	AH,7			; SEE IF VALID AND 
		JBE	SHORT VALID_REQUEST	; SET CARRY FOR POSSIBLE ERR 
		STC 
		RETF	2			 
 
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 
		RETF	2		 
 
;****************************************************** 
;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 
		and	ah,6AH			; keep bit 3 unchange. 
		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 
 
;R20A - start 
Y2K_CHECK_AT_RUNTIME	=	1 
ifdef	NO_Y2K_CHECK 
Y2K_CHECK_AT_RUNTIME	=	0 
endif;	NO_Y2K_CHECK 
ifdef	ICH 
;R20B Y2K_CHECK_AT_RUNTIME	=	0 
Y2K_CHECK_AT_RUNTIME	=	1 
endif;	ICH 
;R20A - end 
 
;R20A ifndef	NO_Y2K_CHECK				;R20 
IF	Y2K_CHECK_AT_RUNTIME				;R20A 
;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: 
;R20A endif	;NO_Y2K_CHECK				;R20 
ENDIF;	Y2K_CHECK_AT_RUNTIME				;R20A 
 
		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 
		and	al,5fH			; keep bit 3 unchange	 
		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	 
		and	al,08H			; get bit 3 status	 
		or	ah,al								 
		mov	al,0BH NMI_ON					 
		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 
 
;R20A - start 
ifdef	ICH 
	;Double check the UIP status to avoid the glitch of ICH B0 stepping 
		jnz	short StillInUIP 
		mov	al,0Ah NMI_ON 
		out	CMOS,al 
		NEWIODELAY 
		in	al,CMOS+1 
 
		and	AL,80H			; TEST FOR UPDATE IN PROGRESS 
	StillInUIP: 
endif;	ICH 
;R20A - end 
		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 
 
		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 
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 
 
		pushad				 
	;Save PCI index register 
		mov	dx,0cf8h		 
		in	eax,dx			 
		push	eax			 
 
	;Save RTC/CMOS index register , it depends on chipset implemention 
	;due to standard RTC/CMOS not accessable for RTC index 
;R19D		extrn	Ct_Save_RTC_Index:near	 
;R19D		call	Ct_Save_RTC_Index	 
;R19D		push	ax			 
;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 
  
	;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 
	 
		mov	al,09H NMI_ON		;read year value 
		call	Get_Cmos 
 
		cmp	al,80H			;before 2080H ? 
		jae	short NoChkCentury 
	 
		mov	ah,20H			;force century to 20xx. 
		mov	al,32h NMI_ON		;write new century value 
		call	Set_Cmos 
 
NoChkCentury: 
 
	;restore CMOS index register 
		pop	ax			 
		out	70h,al			 
 
NoChkCentury1:					;R19D 
 
	;restore PCI index register 
		pop	eax			 
		mov	dx,0cf8h		 
		out	dx,eax			 
		popad				 
 
		sti 
endif;	PATCH_WILLIT_YEAR2000 
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		 
		je	SHORT T4				 
 
		DEC	BYTE PTR DS:[MOTOR_OFF_WAIT]		 
		JNZ	SHORT T4				 
		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 
 
		call	Turbo_Pin_Hdlr	 
 
		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 
		jz	short Safe_Return	; 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			 
		JZ	SHORT END_CLK_INT	 
		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 
		JZ	SHORT SAFE_RETURN 
 
		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 
		and	al,3fH			; mask bit 7    
		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 
 
SAFE_RETURN: 
		MOV	AL,0CH NMI_ON		 
		CALL	GET_CMOS 
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