;	[]===========================================================[]
;
;	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
;----------------------------------------------------------------------------
;R04	01/30/99  RCH	Added AMD/K7 CPU support.
;R03	02/24/98  RCH	Mask duplicated code in boot extension to get more
;			space for memory sizing
;R02	10/09/96  RCH	L1 cache is always available for P6 CPU
;R01A	05/28/96  RCH	Don't disable fast string if it is not B0 stepping
;			P6 CPU due to performance degraded
;R01	10/21/95  RCH	P6 B0 stepping default enable "fast string" and it
;			fail to work , do BIOS have to disable it. Note that
;			this function return to enable if CPU is reset or INIT


		include	cpu.equ

Get_CMOS_MACRO	MACRO
		ALIGN	4
		OUT	CMOS,AL			; address to interface
		jcxz	short $+2
		ALIGN	4
		IN	AL,CMOS+1
		jcxz	short $+2
		ENDM

Set_CMOS_MACRO	MACRO
		ALIGN	4
		OUT	CMOS,AL			; address to interface
		jcxz	short $+2
		xchg	al,ah			;ah=index,al=value	   
		ALIGN	4
		OUT	CMOS+1,AL		; and output it
		jcxz	short $+2
		ENDM

;=============================================================================
;FUNC:	CPU_CACHE
;
;DESC:	Turns the internal cache on and off depending on the cpu type.
;
;IN:	AL	00 = Turn cache off, 01 = Turn cache on.
;OUT:	NONE
;
;SAVES:	NONE + NO STACK
;
;BY:	T. Lewis
;DATE:	3 September 1991
;=============================================================================
		PUBLIC	CPU_CACHE
CPU_CACHE	PROC	NEAR

		mov	ah,al		; ah = saved input value

ifndef	KLAMATH_CPU_ONLY    				;R02
		mov	al,CMOS_AWARD_2 NMI_OFF
		out	CMOS,al
		NEWIODELAY

		in	al,CMOS+1
		cmp	al,0ffh		;Invalid type 		
		je	short Cc_9	;yes, exit		
		test	al,CPUCACHE	; CPU cache exist?
		jz	short Cc_9

		and	al,CPU_TYPE_MASK	
endif;	KLAMATH_CPU_ONLY    				;R02
		or	ah,ah		; cache on or off?
		jne	short cc_3	; on...

ifdef	IBM_CPU_SUPPORT							
;Check if IBM CPU plugged
	  	cmp	al,TYPE_IBM386SLC	
		je	short @F
		cmp	al,TYPE_IBM486SLC2	
		je	short @F		
		cmp	al,TYPE_IBM486DLC3	
		jne	short NoIBM		
@@:
		;turn off IBM CPU internal cache
		WBINVD
		mov	ecx,1000h	;register 1000h to read
		RDMSR			;read cache control register
		and	al,NOT IBMCACHEON	;disable internal cache of IBM's CPU
		WRMSR
		jmp	short cc_9

NoIBM:
endif;	IBM_CPU_SUPPORT							
		;turn off 486 CPU internal cache
		mov eax,cr0
		or  eax,CR0_CD+CR0_NW
		mov cr0,eax
		WBINVD

		jmp short cc_9

cc_3:

ifdef	IBM_CPU_SUPPORT							
;Check if IBM CPU plugged
	  	cmp	al,TYPE_IBM386SLC	
		je	short @F
		cmp	al,TYPE_IBM486SLC2	
		je	short @F		
		cmp	al,TYPE_IBM486DLC3	
		jne	short NoIBM1		
@@:
		;turn on IBM CPU internal cache
		mov	ecx,1000h	;register 1000h to read
		RDMSR			;read cache control register
		or	al,IBMCACHEON 	;enable internal cache of IBM's CPU
		WRMSR
		WBINVD
		jmp	short cc_9
NoIBM1:
endif;	IBM_CPU_SUPPORT							

		;turn on 486 CPU internal cache
		mov eax,cr0
		and eax,NOT (CR0_CD+CR0_NW)
		mov cr0,eax
		WBINVD
cc_9:

		ret
CPU_CACHE	ENDP

ifndef	CompileForExtROM			;R03
;[]==============================================================[]
;
; ROM_AND_CMOS:
;
;	AND a value to a CMOS location while executing from ROM.
;
;Entry:	AL	Location to modifiy
;	AH	Value to AND
; Exit: NONE
;
;Destroys: BL, DI + NO STACK
;
;[]==============================================================[]

		PUBLIC	ROM_AND_CMOS
ROM_AND_CMOS	PROC	NEAR

		mov	bl,al
		Get_CMOS_MACRO
		and	ah,al
		mov	al,bl
		Set_CMOS_MACRO
		ret
ROM_AND_CMOS	ENDP

;[]==============================================================[]
;
; ROM_OR_CMOS:
;
;	Or a value to a CMOS location while executing from ROM.
;
;Entry:	AL	Location to modifiy
;	AH	Value to OR
; Exit: NONE
;
;Destroys: BL, DI + NO STACK
;
;[]==============================================================[]

		PUBLIC	ROM_OR_CMOS
ROM_OR_CMOS	PROC	NEAR

		mov	bl,al
		Get_CMOS_MACRO

		or	ah,al
		mov	al,bl
		Set_CMOS_MACRO

		ret
ROM_OR_CMOS	ENDP
endif;	CompileForExtROM			;R03

;*****************************************
;Name:   	get_cmos
;Entry:  	called
;Input:  	al = memory cell to get in cmos
;Output: 	al = value
;Description:
;
;get_cmos will:
;1. 	address cell at 70H and read cell and return in al
;CMOS READ ONLY LOCATION :  0CH
;************************************************

;R16		ALIGN	4
		PUBLIC	GET_CMOS		; 303A
GET_CMOS	PROC	NEAR
		ALIGN	4
		OUT	CMOS,AL			; address to interface
		jcxz	short $+2
		jcxz	short $+2
		ALIGN	4
		IN	AL,CMOS+1
		jcxz	short $+2
		jcxz	short $+2
		RET
GET_CMOS	ENDP

;************************************************
;Name:   	set_cmos
;Entry:  	called
;Input:  	al = memory cell to store in cmos
;               ah = value to store
;Output: 	al = value
;Description:
;
;set_cmos will:
;1. 	address cell at 70H and write to cell and return in al
;************************************************

		PUBLIC	SET_CMOS
SET_CMOS	PROC	NEAR
		ALIGN	4
		OUT	CMOS,AL			; address to interface
		jcxz	short $+2
		jcxz	short $+2
		xchg	al,ah			;ah=index,al=value	   
		ALIGN	4
		OUT	CMOS+1,AL		; and output it
		jcxz	short $+2
		jcxz	short $+2
		RET
SET_CMOS	ENDP

ifndef	CompileForExtROM			;R03
;=============================================================================
;FUNC:	CPU_INIT
;
;DESC:	Handles the initialization of the CPU.
;
;IN:	NONE
;OUT:	NONE
;
;SAVES:	NONE + NO STACK
;
;BY:	T. Lewis
;DATE:	3 September 1991
;=============================================================================
		PUBLIC	CPU_INIT
CPU_INIT	PROC	NEAR

;R01 - start
ifdef	P6_BIOS_ONLY
 ifndef	K7_CPU_SUPPORT						;R04

;R01A - start
;Don't disable fast string if not B0 stepping P6 CPU
		mov	eax,1			;eax = 1 to read CPU ID
		db	0fh,0A2h		;CPU ID instruction
		cmp	ax,0611H		;B0 stepping P6 CPU ?
		jne	short Keep_FastString	;no , do nothing
;R01A - end

;Disable fast strings function
		mov	ecx,1E0H
		RDMSR
		and	eax,6
		or	al,4			;disable fast string
		WRMSR

Keep_FastString:				;R01A

 endif;	K7_CPU_SUPPORT						;R04
endif;	P6_BIOS_ONLY
;R01 - end

ifdef	IBM_CPU_SUPPORT							;R34
;Init CPU registers if IBM CPU plugged
		mov	al,CMOS_AWARD_2 NMI_OFF
		out	CMOS,al
		NEWIODELAY

		in	al,CMOS+1
		and	al,CPU_TYPE_MASK
;R11		and	al,0feh			;mask 387 bit

		cmp	al,TYPE_IBM386SLC	;R11
		je	short @F
		cmp	al,TYPE_IBM486SLC2	;R11
;R11		jne	short Not_Ibm_Cpu
		je	short @F		;R11
		cmp	al,TYPE_IBM486DLC3	;R11
		jne	short Not_Ibm_Cpu	;R11
@@:
		mov	si,offset DGROUP:IbmCpu_Common
;R11		cmp	al,CPU_IBM486SLC2
;R11		jne	short Next_Ibm
		cmp	al,TYPE_IBM386SLC	;R11
		je	short Next_Ibm		;R11
		
		mov	si,offset DGROUP:IbmCpu_Reg
Next_Ibm:
		lods	word ptr cs:[si]
		xor	ecx,ecx
		mov	cx,ax
		lods	dword ptr cs:[si]
		mov	edx,eax
		lods	dword ptr cs:[si]
		cmp	cx,1002h		;R11
		jne	short Init_Reg		;R11

		mov	ebx,eax			;R11
		mov	al,OVERRIDE NMI_OFF	;R11
		out	CMOS,al			;R11
		NEWIODELAY			;R11
		in	al,CMOS+1		;R11
		NEWIODELAY			;R11
		and	ebx,NOT 07000000h	;R11 Set One To One Mode
		test	al,DOUBLE_CLOCK		;R11
		jz	short Three_Clock_Mode	;R11
		or	ebx,03000000h		;R11 Set Two To One Mode
		jmp	short @F		;R11
Three_Clock_Mode:				;R11
		test	al,THREE_CLOCK		;R11
		jz	short @F		;R11
		or	ebx,04000000h		;R11 Set Three To One Mode
@@:						;R11
		mov	eax,ebx			;R11
Init_Reg:
		WRMSR
		cmp	si,offset DGROUP:IbmCpu_End
		jne	short Next_Ibm
		WBINVD
Not_IBM_CPU:
endif;	IBM_CPU_SUPPORT							;R34

		ret
CPU_INIT	ENDP

		public	SYS_INITS
SYS_INITS:	
;R23		DW	3D8H			; DISABLE VIDEO
;R23		DB	0
		DW	3B8H
		DB	1
		DW	SYS1			; DISABLE PARITY CHECKERS
		DB	0FCH
		DW	CH0_DMA+8		; DISABLE DMA CHIPS
		DB	4
		DW	CH0_DMA+0D0H
		DB	4
		DW	MATH_PORT+1
		DB	0			; RESET 287
		DW	CTRL8254		; INIT TIMER 1
		DB	54H
		DW	DATA8254+1
		DB	0
		DW	CH0_DMA+0DH		; CLEAR DMA CHIPS
		DB	7
		DW	CH0_DMA+0DAH
		DB	7
		DW	CTRL8254		; LATCH AND START TIMER 1
		DB	40H
		DW	DATA8254+1
		DB	12H
		DW	CH0_DMA+8		; ENABLE DMA 0 AND 1
		DB	0
		DW	CH0_DMA+0D0H
		DB	0
		DW	CH0_DMA+0BH		; SET CHANNEL 0 MODE
		DB	040H
		DW	CH0_DMA+0D6H		; SET CH. 4 AS SLAVE HDLR
		DB	0C0H
		DW	CH0_DMA+0D6H
		DB	041H
		DW	CH0_DMA+0BH		; SET MODES FOR ALL CHANNELS
		DB	41H
		DW	CH0_DMA+0D6H
		DB	42H
		DW	CH0_DMA+0BH
		DB	42H
		DW	CH0_DMA+0D6H
		DB	43H
		DW	CH0_DMA+0BH
		DB	43H
		DW	0D2H			; CLEAR MASK AND REQ. REGS
		DB	0
		DW	0D4H
		DB	0

		public	INT_INITS
INT_INITS:	DW	A8259			; INIT FIRST 8259
		DB	11H
		DW	A8259+1
		DB	8    			; INT Vector INT08-INT0F
		DW	A8259+1
		DB	4
		DW	A8259+1
		DB	1

		DW	A8259+1
		DB	0FFH			; mask IRQ0 - IRQ7

		DW	B8259			; INIT SECOND 8259
		DB	11H
		DW	B8259+1
		DB	70H			;INT vector INT70-INT77
		DW	B8259+1
		DB	2
		DW	B8259+1
		DB	1

		DW	B8259+1
		DB	0FFH			; mask IRQ8 - IRQ15
		public	SIZE_INT_INITS
SIZE_INT_INITS	EQU	($-INT_INITS)/3

		DW	CTRL8254		; INIT TIMER 0
		DB	36H
		DW	DATA8254
		DB	0
		DW	DATA8254
		DB	0
		public	SIZE_SYS_INITS
SIZE_SYS_INITS	EQU	($-SYS_INITS)/3
endif;	CompileForExtROM			;R03
