;	[]===========================================================[]
;
;	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
;----------------------------------------------------------------------------
;R27	01/04/99 MCH	Added "KEY_SETUP_CTRL_ALT_KEY" define for supporting
;			"Ctrl+Alt"+special key for entering CMOS Setup with
;			"KEY_SETUP_SCAN_CODE" define.
;R26	11/11/98 RCH	Support pressing Hotkey to force boot to network 
;			before booting from local storages. For example,
;			"HOTKEY_TO_BOOT_LAN EQU 058H" use function key F12 to
;			force boot to LAN.
;M01  	09/02/98 RAY	Adapt Preboot-Agent from code modified by US
;	(01/29/98 TJM)  Added MPC 2.0 (Formerly RPB) modifications
;
;R25	06/26/98 DRS	Add No_Automatic_Load_Awdflash_InPOST definition
;			Some customers want to automatically load awdflash.exe,
;			but they don't want this function during POST.
;			They just want to automaticlly load awdflash.exe in BootBlock.
;R24	05/12/98 RAX	Added code for Cyrix VSA save to disk support.
;R23	04/22/98 KGN	Add code For HPM resume from disk post information
;R22	03/10/98 DNL	Reduce ACPI S4/BIOS code size to save more space
;R21B	02/03/98 DRS	Fixed bug
;R21A	01/22/98 DRS	Function key ALT+F2 , system will run awdflash.exe 
;			during POST
;R21	01/19/98 DRS	Support run awdflash.exe during POST 
;R20	12/18/97 LAW	change "EPA_LOGO_Use_Graphics" with "FULL_SCREEN_LOGO"
;			switch to "Graphics_post"
;R19	06/06/97 PTY	Add code for RPB
;R16A	11/20/96 RAY	Add special option key for entering setup
;R14A	07/29/96 DNL	Fixed coding mistake
;R18A	07/23/96 KEN	Remove key code process to SMI.
;R18	05/28/96 KEN	Add USB_SUPPORT.
;R17	05/24/96 RCH	Move non run-time code to new file MISC.ASM to get
;			more space in F8000-FFFFF area
;R16	04/17/96 RAY	Somebody don't want 'DEL' key to enter setup
;R14	01/12/96 KVN	Added full screen logo display function
;R13	06/13/95 KVN	Reduce Post_func_call and F000_call code size
;R12	03/16/95 BEN	Added codes for Notebook Power Management.
;R11	01/11/95 RCH	Fixed warm boot keyboard lock bug when use JETKey-v5.0
;			+ Key-Pro keyboard.
;R10	08/02/94 RCH	Kill software speed control codes , because INT 15H
;			function 4FH have it already
;R09A	04/16/94 RAY	R09 become an option because some system may hang
;			when "out 64h,0FEh" command is issued
;R09	04/12/94 RAY	Reset system instead of jumping to label REDO
;R08	03/14/94 KVN	Fixed up OS/2 hang when Num-Lock is enable.
;R07	03/10/94 RAY	Mask off CALL_TABLE option
;R06	03/03/94 RAY	Don't include .EXT files any more
;R05A	01/04/94 BEN	use MOVSW instead of MOVSD in subroutine Save_Screen
;			& Restore_Screen
;R05	12/30/93 BEN	Save & Restore mouse statue for allow setup from DOS.
;R04	12/30/93 BEN	Fixed for allow setup from DOS can serve in any video
;			mode except ET chines mode.
;R03	12/30/93 BEN	Fixed for allow setup from DOS in DOSSHELL keyboard
;			status (SHFT & ALT & CTRL) is not clear.
;R02	07/16/93 RCH	Save and Restore cursor type & mode for mono display
;R01	07/16/93 RCH	Don't re-set dispaly mode for mono dispaly , because
;			 video BIOS destroy screen while set display mode
;R00    02/16/93 RCH    Initial release 

		PAGE	62,132
		TITLE	AKBRD  
.386
;		+---------------+
;		|		|
;		|     INT 9	|
;		|		|
;		+---------------+

;
.XLIST
		INCLUDE BIOS.CFG

		INCLUDE 8042.EQU
		INCLUDE 8259.EQU
		INCLUDE	PORT61.EQU					;R01A
		INCLUDE AKBRD.EQU
		INCLUDE POST.EQU

		INCLUDE COMMON.MAC
		INCLUDE	POST.MAC					;R01B

		INCLUDE	BTROMSEG.EQU		;R21

;R06		INCLUDE ATORGS.EXT		;KEYS
;R06		INCLUDE ATBASE.EXT		;REDO
;R06		INCLUDE SETUP.EXT		;SETUP
;R06		INCLUDE SETSPEED.EXT		;SETSPEED

;R19 start
ifdef RPB_ENABLED                   ; RXX
    include rpb.cfg
ifndef RPB_ALWAYS_ENABLED
    Extrn  rpb_hot_keys:near
endif ; RPB_ALWAYS_ENABLED
endif ; RPB_ENABLED
;R19 end

ifdef	Bootblock_16K_Support				;R21
ifdef	Automatic_Load_Awdflash				;R21
ifNdef	No_Automatic_Load_Awdflash_InPOST		;R25
		extrn	INT_Awdflash_Check:near		;R21
endif	;No_Automatic_Load_Awdflash_InPOST		;R25
endif	;Automatic_Load_Awdflash			;R21	
endif	;Bootblock_16K_Support				;R21

;R18AIFDEF	USB_SUPPORT				;R18
;R18A		EXTRN	int9_usb:near			;R18
;R18AENDIF	;USB_SUPPORT				;R18

		EXTRN 	KEYS:BYTE	   	;R06
		EXTRN	REDO:NEAR		;R06
		EXTRN	SETSPEED:NEAR		;R06
		EXTRN	SETUP:NEAR		;R06
		EXTRN	EXTERN_SETUP:FAR	;R06

		extrn	Cp_Install:near
		extrn	Ct_Before_Setup:near	;128K
IFDEF	ALLOW_SETUP_FROM_DOS			;128K
		extrn	DOS_Setup_Info:near	;128K
		extrn	PM_CONFIG_BYTE:BYTE	;128K
		extrn	TIMER_VECT:near		;128K
		EXTRN	KEYBOARD:NEAR		;128K
		EXTRN	UPDATETIMER:NEAR	;128K
ENDIF	;ALLOW_SETUP_FROM_DOS			;128K
;R13		extrn	POST_func_end:Near	;128k
;R13		extrn	POST_VECT:Near		;128k
		extrn	Post_call_proc:near	;R13

;M01 - starts
ifdef RPB_ENABLED
ifdef RPB_REBOOT_DISABLE
		extrn	rpbf_prepare_for_reset:near
endif ; RPB_REBOOT_DISABLE
endif ; RPB_ENABLED
;M01 - ends

.LIST

		PAGE

G_RAM		SEGMENT	USE16 AT 40H
		INCLUDE	G_RAM.INC
G_RAM		ENDS

;R21 -start
XGROUP		GROUP	XCODE
XCODE		SEGMENT USE16 PARA PUBLIC 'XCODE'
		ASSUME	CS:XGROUP,ES:XGROUP
XCODE		ENDS
;R21 -end

DGROUP		GROUP	FCODE

FCODE		SEGMENT	USE16 DWORD PUBLIC 'CODE'
		ASSUME	CS:DGROUP

		PUBLIC	BEEP_KEY

		PUBLIC	KBD_INT
		PUBLIC	BUFFER_8042_FULL
		PUBLIC	UPDATE_LED
		PUBLIC	INSERT_CHAR
		PUBLIC	KB_OUT

		ALIGN	4
KBD_INT		PROC	NEAR

; This routine handles the interrupts generated by the keyboard
;
; ENTRY: NONE
; EXIT:  NONE

		sti				; enable int
		cld

;R07 IFDEF 	CALL_TABLE							   
;R07 ;requires a table of dword ptrs to reside at F000:0 which may just point   
;R07 ;to a far return or may point to a user maintained routine.                
;R07 
;R07    %OUT CALL_TABLE keyboard hook enabled				   
;R07 		call	dword ptr CS:[4*14]	; Entry 14 dec		   
;R07 ENDIF	;CALL_TABLE									   

		push	ds
		pusha

		mov	bx,G_RAM		; set data seg
		mov	ds,bx
		ASSUME	DS:G_RAM


;R03
IFDEF	POWER_MANAGEMENT
		call	PM_Set_Critical		; set critical setction
ENDIF	;POWER_MANAGEMENT	
;R03

; MAKE 2 BYTE VARIABLES (scan_char,temp)

		mov	bp,sp
		sub	sp,2

		mov	ax,DISABLE_KBRD		; disable keyboard
		call	kb_cntrlr_out

; READ SCAN FROM KEYBOARD (8042)

		cli
		call	buffer_8042_full	; wait for controller to
						; process disable keyboard
		in	al,DATA8042		; READ DATA FROM 8042

		public	PostInt9_to_AKBRD_Entry		;R14
PostInt9_to_AKBRD_Entry:				;R14
; perform an INT 15H, function 4FH to allow hooks into keyboard 

IFDEF	ALLOW_SETUP_FROM_DOS					;R03
		test	Init_Err_Flg,IEF_SETUP_OK		;R03
		jnz	@F					;R03
ENDIF	;ALLOW_SETUP_FROM_DOS					;R03

		stc				; set carry flag - in case of iret
		mov	ah,04fh			; set function call
		int	15h			; do it
		jnc	qwik_exit		; somebody else handled scan code

IFDEF	ALLOW_SETUP_FROM_DOS					;R03
	@@:							;R03
ENDIF	;ALLOW_SETUP_FROM_DOS					;R03

		mov	scan_char,al		; save scan after int 15
		sti

;R15 - start
;R20ifndef FULL_SCREEN_LOGO					;R14
ifndef	Graphics_Post					;R20

;R26 - start
ifdef	HOTKEY_TO_BOOT_LAN
		cmp	al, HOTKEY_TO_BOOT_LAN 		;LAN boot hot key ?
		jne	short NotF12Key			;no
		or	byte ptr ds:SYSTEM_FLAG,BOOT_LAN;yes,boot from LAN
NotF12Key:
endif;	HOTKEY_TO_BOOT_LAN
;R26 - end

		test	INIT_ERR_FLG,IEF_IN_POST	; in POST?
		jz	short Not_In_Post   

;R21 -start
ifdef	Bootblock_16K_Support			
ifdef	Automatic_Load_Awdflash				
ifNdef	No_Automatic_Load_Awdflash_InPOST		;R25
		test	byte ptr POST_Flag,AWDFLASH_ON	;will run AWDLFASH.EXE
		jnz	short Not_In_Post		;YES
endif	;No_Automatic_Load_Awdflash_InPOST		;R25
endif	;Automatic_Load_Awdflash				
endif	;Bootblock_16K_Support			
;R21 -end

		cmp	al,KEY_OVERRIDE		; insert key pressed?
		jne	short @F
		or	byte ptr POST_FLAG,OVERRIDE_ON	;override key
@@:
		cmp	al,KEY_SETUP		; del key pressed?
		jne	short @F
ifdef	KEY_SETUP_CTRL_ALT_KEY				;R27
		mov	al,byte ptr SHFT_STAT		;R27
		and	al,ALT+CTRL			;R27
		cmp	al,ALT+CTRL			;R27
		jne	short @F			;R27
else;	KEY_SETUP_CTRL_ALT_KEY				;R27
		test	byte ptr SHFT_STAT,ALT+CTRL
		jnz	short @F
endif;	KEY_SETUP_CTRL_ALT_KEY				;R27

ifndef	NO_DEL_KEY_ENTER_SETUP		;R16
		jmp	Setup_Check
else	;NO_DEL_KEY_ENTER_SETUP		;R16A
	ifdef	KEY_SETUP_SCAN_CODE	;R16A
		jmp	Setup_Check	;R16A
	endif	;KEY_SETUP_SCAN_CODE	;R16A
endif	;NO_DEL_KEY_ENTER_SETUP		;R16
@@:

Not_In_Post:
endif;	Graphics_Post					;R20
;R20endif ;FULL_SCREEN_LOGO					;R14
;R15 - end

;[]------------------------------------------------------[]
;R21 -start
ifdef	Bootblock_16K_Support			
ifdef	Automatic_Load_Awdflash				
ifNdef	No_Automatic_Load_Awdflash_InPOST		;R25

		test	byte ptr POST_FLAG,SETUP_ON	; will run SETUP ?
		jnz	short @F			; YES

		cmp	al,KEY_AWDFLASH			
		jne	short @F
		test	byte ptr SHFT_STAT,ALT		; ALT ? ;R21A
		jz	short @F				;R21A

		test	POST_FLAG,AWD_Str_Show		;R21B
		jz	short @f			;R21B

		mov	sp,bp				; restore sp
		popa					; restore all registers
		pop	ds				; restore DS
		far_jmp	<offset XGROUP:INT_Awdflash_Check>,Xgroup_Segment
	@@:

endif	;No_Automatic_Load_Awdflash_InPOST		;R25
endif	;Automatic_Load_Awdflash				
endif	;Bootblock_16K_Support			
;R21 -end
;[]------------------------------------------------------[]

; check scan response
ifndef	Non_English_KB
  ifdef	German_KB

		JMP	Try_Special_Key

  Special_ASCII		db	'aeiouEa'
  special_ASCII_L	equ	$-Offset Special_ASCII
  Special_ASCII_1	db	''	; '
  Special_ASCII_2	db	'Z'	; `
  Special_ASCII_3	db	'Z'	; ^

  Special_Scan_tbl	dw	000Dh
			db	"'"
			dw	Offset Special_ASCII_1
			db	"`"
			dw	Offset Special_ASCII_2
  Scan_Data_L		equ	$-Offset Special_Scan_tbl
			dw	0029h
			db	"^"
			dw	Offset Special_ASCII_3
			db	0FFh
			dw	0FFh
  How_Much_Data		equ	($-Offset Special_Scan_tbl)/Scan_Data_L

  Try_Special_Key:
  ;fix ht22 bug
		push	ax
		mov	ah,al
		mov	al,shft_stat
		and	al,ALT+CTRL
		cmp	al,ALT+CTRL
		jne	no_bug
		and	ah,7fh
		cmp	ah,1bh
		jne	no_bug
		pop	ax
		jmp	qwik_exit
  no_bug:
		pop	ax
  ;fix ht22 bug

  ;[]------------------- special NUM Lock for German KB ----------------[]
		push	ax
		test	al,80h				;break code?
		jnz	Clear_NumLk_End
		and	al,7Fh
		cmp	al,2Ah				;left_shift
		je	Clear_NumLk
		cmp	al,36h				;left_shift
		je	Clear_NumLk
		jmp	Clear_NumLk_End
  Clear_NumLk:
		and	ds:shft_stat,not CAPS_LK
  Clear_NumLk_End:
		pop	ax
  ;[]------------------- check key "Alt Gr" ----------------------[]
  Try_Alt_Gr:
		test	KB_Flag_3,RIGHT_ALT		;ALT pressed?
		jz	End_GR_Alpha			;no, do nothing

		or	shft_stat,ALT

		test	KBD_FLG1,02h			;left alt pressed?
		jnz	End_GR_Alpha			;yes, do nothing

		test	shft_stat,LT_SHFT + RT_SHFT	;shift pressed?
		jnz	End_GR_Alpha			;yes, do nothing

		cmp	al,03h
		jne	Try_GR_3 
		mov	al,'' 
		mov	temp,'' 
		jmp	switch_done
  Try_GR_3: 
		cmp	al,04h
		jne	Try_GR_7
		mov	al,'' 
		mov	temp,'' 
		jmp	switch_done
  Try_GR_7:
		cmp	al,08h 
		jne	Try_GR_8
		mov	al,'{' 
		mov	temp,'{' 
		jmp	switch_done
  Try_GR_8:
		cmp	al,09h 
		jne	Try_GR_9
		mov	al,'[' 
		mov	temp,'[' 
		jmp	switch_done
  Try_GR_9:
		cmp	al,0Ah
		jne	Try_GR_0
		mov	al,']' 
		mov	temp,']' 
		jmp	switch_done
  Try_GR_0:
		cmp	al,0Bh 
		jne	try_GR_Q
		mov	al,'}' 
		mov	temp,'}' 
		jmp	switch_done
  try_GR_q:
		cmp	al,10h			;key 'q' or 'Q'
		jne	try_GR_m
		mov	al,'@'
		mov	temp,'@'
		jmp	switch_done
  try_GR_m:
		cmp	al,32h			;key 'm' or 'M'
		jne	try_GR_pipe
		mov	al,''
		mov	temp,''
		jmp	switch_done
  try_GR_pipe:
		cmp	al,56h			;key '<' or '>'
		jne	try_GR_plus
		mov	temp,'|' 
		jmp	switch_done
  try_GR_plus:
		cmp	al,1Bh			;key '+' or '*'
		jne	Try_GR_Beta
		mov	temp,'~' 
		jmp	switch_done
  try_GR_Beta:
		cmp	al,0Ch			;key '' or '?'
		jne	End_GR_Alpha
		mov	temp,'\' 
		jmp	switch_done
  End_GR_Alpha:

;[]--------------------- check keys:,,.... ---------------------[]

		push	ax
		push	es
		push	di
		push	cx

		test	al,80h			;is it a break code?
		jnz	End_Special_Key		;yes, no checking

		test	shft_stat,CTRL+ALT
		jnz	End_Special_Key		;yes, no checking

		mov	cx,How_Much_Data
		mov	di,offset cs:Special_Scan_tbl
		and	ax,7fh

  Find_Special_Scan:
		cmp	ax,cs:[di]
		je	Special_Scan_Found
		add	di,Scan_Data_L
		loop	Find_Special_Scan
		jmp	End_Special_Key

  Special_Scan_Found:
		add	di,2			;di point to unshifted ASCII
		TEST	SHFT_STAT,LT_SHFT + RT_SHFT + CAPS_LK	;shift pressed"
		jz	no_shift_Pressed	;no
		add	di,3			;di point to shifted ASCII
  no_shift_Pressed:
		cmp	byte ptr cs:[di],0ffh
		je	End_Special_Key

		mov	cl,cs:[di]
		mov	ds:[Non_Eng_ASC],cl

		mov	cx,cs:[di+1]
		mov	ds:[Non_Eng_Addr],cx
  End_Special_Key1:
		pop	cx
		pop	di
		pop	es
		pop	ax
		jmp	keyt_ret_brk

  End_Special_Key:
		pop	cx
		pop	di
		pop	es
		pop	ax

  endif	;German_KB

  ifdef	Portuguese_KB
		JMP	Try_Special_Key

  Special_ASCII		db	'aeinouyAEINOUYa'
  special_ASCII_L	equ	$-Offset Special_ASCII
  Special_ASCII_1	db	'Z쵐Z'		;KEY 1B		''
  Special_ASCII_2	db	'ZZZZ'		;shift 1Bh	'`'
  Special_ASCII_3	db	'ZZZZZZZZ'		;2Bh		'~'
  Special_ASCII_4	db	'ZZZZ'		;shift 2Bh	'^'
  Special_ASCII_5	db	'ZZZ'		;GR 1Ah		''

  Special_Scan_tbl	dw	001Bh
			db	''
			dw	Offset Special_ASCII_1
			db	'`'
			dw	Offset Special_ASCII_2
  Scan_Data_L		equ	$-Offset Special_Scan_tbl

			dw	002Bh
			db	'~'
			dw	Offset Special_ASCII_3
			db	'^'
			dw	Offset Special_ASCII_4

			dw	001Ah
			db	''
			dw	Offset Special_ASCII_5
			db	0FFh
			dw	0FFFFh

  How_Much_Data		equ	($-Offset Special_Scan_tbl)/Scan_Data_L

Try_Special_Key:
;[]--------------------------------------------------------------------------
  Try_Alt_Gr:
		test	KB_Flag_3,RIGHT_ALT		;ALT pressed?
		jz	End_GR_Alpha			;no, do nothing

		or	shft_stat,ALT

		test	KBD_FLG1,02h			;left alt pressed?
		jnz	End_GR_Alpha			;yes, do nothing

		test	shft_stat,LT_SHFT + RT_SHFT	;shift pressed?
		jnz	End_GR_Alpha			;yes, do nothing

		cmp	al,03h		;key '2' 
		jne	Try_GR_3 
		mov	al,'@' 
		mov	temp,'@' 
		jmp	switch_done 
  Try_GR_3: 
		cmp	al,04h		;key '3' 
		jne	Try_GR_4 
		mov	al,'' 
		mov	temp,'' 
		jmp	switch_done 
  Try_GR_4: 
		cmp	al,05h		;key '4' 
		jne	Try_GR_7
		mov	al,''
		mov	temp,''
		jmp	switch_done 
  Try_GR_7:
		cmp	al,08h		;key '7' 
		jne	Try_GR_8
		mov	al,'{' 
		mov	temp,'{' 
		jmp	switch_done 
  Try_GR_8:
		cmp	al,09h		;key '8' 
		jne	Try_GR_9
		mov	al,'[' 
		mov	temp,'[' 
		jmp	switch_done 
  Try_GR_9:
		cmp	al,0Ah		;key '9' 
		jne	Try_GR_0
		mov	al,']' 
		mov	temp,']' 
		jmp	switch_done 
  Try_GR_0:
		cmp	al,0Bh		;key '0' 
		jne	End_GR_Alpha
		mov	al,'}' 
		mov	temp,'}' 
		jmp	switch_done 
  End_GR_Alpha:

;[]--------------------- check keys:,,.... ---------------------[]
		push	ax
		push	es
		push	di
		push	cx

		test	al,80h			;is it a break code?
		jnz	End_Special_Key		;yes, no checking

		test	shft_stat,CTRL		;CTRL pressed?
		jnz	End_Special_Key		;yes, no checking

		test	shft_stat,ALT		;ALT pressed?
		jz	Find_Special_Scan	;no, start scanning

		push	ax
		and	al,7fh
		cmp	al,1Ah
		pop	ax
		jne	End_Special_Key

  Find_Special_Scan:
		mov	cx,How_Much_Data
		mov	di,offset cs:Special_Scan_tbl
		and	ax,7fh

  Special_Scan_Loop:
		cmp	ax,cs:[di]
		je	Special_Scan_Found
		add	di,Scan_Data_L
		loop	Special_Scan_Loop
		jmp	End_Special_Key

  Special_Scan_Found:
		add	di,2				;di point to unshifted ASCII
		TEST	SHFT_STAT,LT_SHFT + RT_SHFT	;shift pressed"
		jz	no_shift_Pressed		;no
		add	di,3				;di point to shifted ASCII
  no_shift_Pressed:
		cmp	byte ptr cs:[di],0ffh
		je	End_Special_Key

		mov	cl,cs:[di]
		mov	ds:[Non_Eng_ASC],cl

		mov	cx,cs:[di+1]
		mov	ds:[Non_Eng_Addr],cx
  End_Special_Key1:
		pop	cx
		pop	di
		pop	es
		pop	ax
		jmp	keyt_ret_brk

  End_Special_Key:
		pop	cx
		pop	di
		pop	es
		pop	ax
  ;[]-------------------------------------------------------------------------
  endif	;Portuguese_KB
endif	;Non_English_KB

		cmp	al,KB_RESEND
		JNE	SHORT .D167		; SKIP : NOT RESEND

		OR	KB_FLAG_2,RESEND_RECV	; SET FLAG
		JMP	SHORT QWIK_EXIT		; DONE

.D167:		CMP	AL,KB_ACK
		JNE	SHORT .D182		; SKIP : NOT ACK

		OR	KB_FLAG_2,ACK_RECV	; SET FLAG
		JMP	SHORT QWIK_EXIT		; DONE

.D182:		CALL	UPDATE_LED

		CMP	AL,KBS_OVER		; is this an overrun char?
		JNE	SHORT .D18F
		JMP	.D806			; OVERFLOW - ring bell


; check to see if there is a read id in progress

.D18F:		MOV	AH,KB_FLAG_3		; get flag
		TEST	AH,READ_ID+LAST_AB	; check
		JE	SHORT NO_READID		; no read id in progress
		JS	SHORT FIRST_ID		; looking for 1st byte

		AND	AH,NOT LAST_AB		; reset flags
		CMP	AL,ID_101_2		; is this the 2nd id byte
		JNE	SHORT EX_READID		; if not, just clear flag

		OR	AH,E101_KEY		; set 101 keyboard flag
		TEST	AH,FORCE_NUM		; should we set num lock
		JZ	SHORT EX_READID		; if not, just return
		OR	SHFT_STAT,NUM_LK	; set num lock flag
		MOV	KB_FLAG_3,AH		; restore flag
		CALL	UPDATE_LED		; and send to keyboard
		JMP	SHORT QWIK_EXIT		; leave

FIRST_ID:	AND	AH,NOT(READ_ID+LAST_AB)	; reset flags
		CMP	AL,ID_101_1		; is this the first id byte

		JNE	SHORT EX_READID		; if not, just clear flag
		OR	AH,LAST_AB		; if yes, set LAST_AB flag


EX_READID:
		MOV	KB_FLAG_3,AH		; restore flag
QWIK_EXIT:	JMP	.D86A

NO_READID:	CMP	AL,0E0H			; is this an E0 char
		JNE	SHORT TRY_E1

		OR	KB_FLAG_3,LAST_E0+E101_KEY	; set E0 flag
		JMP	.D86A_EXIT		; return without reseting flag

TRY_E1:		CMP	AL,0E1H			; is this an E1 char
		JNE	SHORT NO_E

		OR	KB_FLAG_3,LAST_E1+E101_KEY	; set E1 flag
.DE1_E0:	JMP	.D86A_EXIT		; return without reseting flag

NO_E:		MOV	TEMP,0

; get values from 'keys' table

		lea	si,Keys			; setup pointer in table
		mov	dl,al			; save scan code in dl
		and	ax,07fh
		shl	ax,1
		shl	ax,1
		add	si,ax			; si = pointer to 'keys' table

; check groups and start process

		mov	dh,KB_FLAG_3		; get kb flag for later use

; check for shift (treat make/break shift the same)

		xor	ax,ax
		mov	al,cs:[si]		; get key type from table

		cmp	al,SHIFT
		jne	short keyt_1		; skip : shift

		test	dh,LAST_E1		; are we in a E1 sequence
		jne	short .de1_e0		; return without resetting e1

		test	dh,LAST_E0		; is this an E0
		je	short keyt_ret		; if not, exit

		test	byte ptr cs:[si]+1,ALT+CTRL	; if this is alt or ctrl
		jne	short keyt_ret			; continue processing normal
		jmp	short qwik_exit			; else if shift, throw away

; process break codes

keyt_1:		test	dl,80h			; dl contains scan code
		jz	short keyt_3		; skip : it is a make key

		and	dl,07fh			; dl = make scan code

		cmp	al,TOGGLE
		je	short keyt_2		; cont : this is a toggle key

		cmp	dl,INS_KEY
		jne	short keyt_ret_brk	; cont : this is the insert key

; indicate toggle key released

keyt_2:		mov	al,cs:+1[si]
		not	al
		and	kbd_flg1,al

; process system key on at

		cmp	dl,SYS_KEY
		jne	short keyt_ret_brk	; return break : not sys key

		call	int_kb_enable

		mov	ax,8501h		; int 15 - sys req key pressed
		int	15h
		jmp	short keyt_ret_brk	; return break

; check for if we should end hold state

keyt_3:		test	KBD_FLG1,HOLD
		jz	short keyt_ret		; hold active

		cmp	dl,NUM_KEY
		jz	short keyt_ret		; process key but don't end hold

		cmp	dl,SYS_KEY
		jz	short keyt_ret		; process key but don't end hold

		test	SHFT_STAT,CTRL
		jnz	short keyt_5		; release hold if <ctrl> on

		cmp	dl,CAPS_KEY
		jz	short keyt_ret		; process key but don't end hold

		cmp	dl,SCRL_KEY
		jz	short keyt_ret		; process key but don't end hold

keyt_5:		and	KBD_FLG1,NOT HOLD	; END HOLD STATE AND EAT CHARACTER

keyt_ret_brk:	mov	ax,BREAK		; return break code

; jump to routine for key type

keyt_ret:	mov	bx,ax			; get type
		cmp	bx,BREAK		; check for value in bound
		jb	short go_jmp		; good value
		mov	bx,BREAK		; error
go_jmp:		shl	bx,1			; word offset
		jmp	word ptr cs:jmptable[bx]	; jmp to routine

		even
jmptable:	dw	offset	SHIFT_S		; SHIFT
		dw	offset	ALPHA_S		; ALPHA
		dw	offset	ASCII_S		; ASCII
		dw	offset	FUNC_S		; FUNCTION
		dw	offset	KEYP_S		; KEYPAD
		dw	offset	TOG_S		; TOGGLE
		dw	offset	NUM_S		; NUMERIC
		dw	offset	F11_HND		; F11_F12
		dw	offset	.D86A		; BREAK

		PAGE

; process shift:

; update flag on shift state

shift_s:	mov	al,cs:+1[si]		; get bit mask
		mov	ah,al			; save template
		test	scan_char,80h		; check  make/break
		je	short .d24c		; goto make

		not	al			; set break
		and	SHFT_STAT,al		; clear flag

		test	ah,ALT+CTRL		; is this an ALT or CTRL key
		JE	SHORT .D260		; no, we are done

		TEST	DH,LAST_E0		; is this a right shift key
		JE	SHORT LEFT_BREAK

		AND	KB_FLAG_3,AL		; clear right shift key
		JMP	SHORT .D260

LEFT_BREAK:	ROR	AL,1			; change template
		ROR	AL,1
		AND	KBD_FLG1,AL		; clear left shift key
		JMP	SHORT .D260

.D24C:		OR	SHFT_STAT,AL		; set make
		TEST	AL,ALT+CTRL		; is this an ALT or CTRL key?
		JE	SHORT .D260		; no, we are done

		TEST	DH,LAST_E0		; is this an E0 shift (right)
		JE	SHORT LEFT_MAKE

		OR	KB_FLAG_3,AL		; set right shift key flag
		JMP	SHORT .D260

LEFT_MAKE:	SHR	AL,1			; change template
		SHR	AL,1
		OR	KBD_FLG1,AL		; set left shift key flag

; CHECK FOR END OF ALT INPUT

.D260:		CMP	SCAN_CHAR,0B8H
		JE	SHORT NOT_D86A_L1
.D86A_L1:	JMP	.D86A			; DONE : END OF ALT INPUT
NOT_D86A_L1:

; if(kchar = getd(ALT_INPUT,0)) /*does it exist ? */

		MOV	AL,ALT_INPUT
		OR	TEMP,AL			; SET CHARACTER VALUE
		JZ	SHORT .D86A_L1		; DONE

; scan = 0; putd(ALT_INPUT,0,0);

		XOR	AX,AX
		MOV	SCAN_CHAR,AL
		MOV	ALT_INPUT,AL		; 0
		JMP	.D7BA			; SAVE VALUE

		PAGE

; PROCESS ALPHA:

; CHECK FOR "SPACE"

ALPHA_S:
		CMP	SCAN_CHAR,57
		JNE	SHORT .D2A3		; NOT SPACE

		MOV	TEMP,20H		; SET "SPACE" VALUE
		JMP	SHORT .D310

; CHECK FLAG FOR FLAVOR (ALT, CNTR, ECT)

.D2A3:
		TEST	SHFT_STAT,ALT
		JNE	SHORT .D310

.D2CB:		TEST	SHFT_STAT,CTRL
		JE	SHORT .D2EC

		MOV	AL,CS:+3[SI]		; ctrl code
		MOV	TEMP,AL			; set TEMP to code from table
		JMP	SHORT .D310

.D2EC:		MOV	AL,CS:+1[SI]		; GET ALPHA VALUE
		MOV	TEMP,AL

		TEST	SHFT_STAT,CAPS_LK
		JE	SHORT .D30F

		AND	TEMP,0DFH		; MAKE UPPER CASE

.D30F:		TEST	SHFT_STAT,LT_SHFT + RT_SHFT
		JE	SHORT .D310

		XOR	TEMP,20H		; SWITCH CASE
.D310:		JMP	SWITCH_DONE

; PROCESS NON ALPHA ASCII CHARACTERS
; starting with the speed switching combination

ASCII_S:	MOV	AL,SHFT_STAT		; check for ctrl alt +,- V2.08
		AND	AL,ALT+CTRL
		CMP	AL,ALT+CTRL
		JNE	.D31EB						;R02
;R19 start
ifdef RPB_ENABLED                   ; RXX
ifndef RPB_ALWAYS_ENABLED
    mov   al,BYTE PTR CS:[SI+1]     ; pass in key
    Post_Func_Call  rpb_hot_keys    ; RPB hotkeys
endif
endif ; RPB_ENABLED
;R19 end

		CMP	BYTE PTR CS:[SI+1],1BH	; escape key?
		JNE	NOT_SETUP					;R02

;R20ifndef FULL_SCREEN_LOGO					;R14
ifndef	Graphics_Post					;R20
Setup_Check:
		TEST	INIT_ERR_FLG,IEF_IN_POST	; in POST?	;R01A
		JZ	SHORT SAVE_FOR_POST		; no...		;R01A
		or	byte ptr POST_FLAG,SETUP_ON

		TEST	INIT_ERR_FLG,IEF_SETUP_OK	; is POST occurring
		jz	short save_for_post

		AND	INIT_ERR_FLG,NOT IEF_SETUP_OK	; prevent further  
							; setup invocations
endif;	Graphics_Post					;R20
;R20endif ;FULL_SCREEN_LOGO					;R14
;R12 - Begin
;R22 IFDEF	NoteBook_Power_Management
if	STD_Function		EQ	1		;R22
		extrn	Check_0V_Resume:near
		call	Check_0V_Resume
		jnz	short save_for_post
endif	;STD_Function		EQ	1		;R22
;R22 ENDIF	;NoteBook_Power_Management
;R12 - End

;R24 start
ifdef	VSA_VGA
ifdef	S2D_SUPPORT
		extrn	Check_VSA_resume:near
 		call	Check_VSA_resume
		jnz	short save_for_post
endif	;S2D_SUPPORT
endif	;VSA_VGA
;R24 end

ifdef	HPM_Support					;R23
		extrn	Check_HPM_Resume:Near		;R23
		Call	Check_HPM_Resume		;R23
		jnz	short save_for_post		;R23
endif	;HPM_Support					;R23

;R20ifndef FULL_SCREEN_LOGO					;R14
ifndef	Graphics_Post					;R20
		extrn	Go_Cmos_Setup:near		;R17
		jmp	Go_Cmos_Setup			;R17
;
;R17;	Here we allow the user to enter SETUP while in POST. We must
;R17;	allow keyboard interrupts again, restore BP (which the POST
;R17;	user interface routines and Setup use), call Setup then
;R17;	reboot.
;R17;
;R17
;R17
;R17		call	Int_Kb_Enable
;R17
;R17		mov	sp,bp				; restore stack
;R17		popa					; restore all registers
;R17		mov	bp,[Temp_BP]			; get POST BP		
;R17		pop	ds				; restore DS
;R17
;R17		jmp	Enter_Setup
endif;	Graphics_Post					;R20
;R20endif ;FULL_SCREEN_LOGO					;R14A
save_for_post:
;R14 endif ;FULL_SCREEN_LOGO					;R14

IFDEF ALLOW_SETUP_FROM_DOS
;[]=========================================================================[]
;
; ALLOW_SETUP_FROM_DOS		Space for DOS Setup stack/video save
;
; Allows Setup to be called from DOS. Normally this happens by pressing
; CTRL-ALT-ESC when out of POST. Currently only allows you to access
; Setup when you are in standard mode (mode 0,1,2,3,4,5,6,7,d,e,f,10,11,12,13).
; Requires a chipset-specific routine DOS_SETUP_INFO to reserve space
; for the stack and video save buffer.
; 
; When setup is called from DOS, this chipset-specific routine is called
; to open up enough space to save the video buffer (about 32k) and set
; up the stack. The routine is also called after the user exits from
; Setup to close down the area where the buffer and stack are saved.
; 
; 
; The routine DOS_SETUP_INFO has the following parameters:
; 
; ENTRY: AL	Function: 0 = open video/stack save area, 1 = close area
; 	 CX	Amount of space needed for stack save area.
; 	 DS	G_RAM
; 
; EXIT:	 C	Set if error, clear if none
; 	 DX:AX	(AL = 0) Segment/offset of stack area.
; 	 ES	(AL = 0) Segment for video save area.
; 
; If there is an error or the routine is not present, the keyboard will
; beep.
;
; Name	| Date		| Description
; -----------------------------------------------------------------
; BEN	 02/08/93	 Initial version.
;[]=========================================================================[]
;128K		extrn	DOS_Setup_Info:near

		cli
;128K		extrn	PM_CONFIG_BYTE:BYTE
		test	byte ptr cs:[PM_CONFIG_BYTE],02h	;setup from DOS allowed?
		jz	sfp_9				; no...

		test	Init_Err_Flg,IEF_IN_POST	; are we in POST?
		jnz	sfp_9				; yes...

		test	Init_Err_Flg,IEF_SETUP_OK	; already in setup?
		jnz	sfp_9				; yes...

; Check extend graphic mode or ET chinses mode.
		cmp	[Con_Mode],3			;R04
		jne	short sfp_2			;R04

		push	ax
		push	dx
		mov	dx,3ceh				; GCD register
		mov	al,6
		call	get_vga_reg
		test	al,1				;Is text mode ?
		pop	dx
		pop	ax
		jnz	sfp_9

sfp_2:
		or	Init_Err_Flg,IEF_SETUP_OK	; prevent further setup

		pushad					; save registers, 1st stack
		push	gs
		push	fs
		push	es
		push	ds				; save G_RAM

;direct int8 vector to BIOS int8

		mov	bx,ds				;save DS
		xor	ax,ax
		mov	ds,ax
		mov	eax,ds:[8*4]
		push	eax				;save INT 8 Vector
;128K		extrn	TIMER_VECT:near
		mov	word ptr ds:[8*4],offset CS:TIMER_VECT
		mov	word ptr ds:[8*4+2],0F000h
		mov	ds,bx				;restore DS

; kill speaker
		in	al,SYS1
		NEWIODELAY
		push	ax
		and	al,NOT 1
		out	SYS1,al
		NEWIODELAY

		add	cx,EXT_STOR_START+2		; cx += checksum size
		add	cx,40				; liberal for stack calls
		xor	al,al				; al = open video save/stack segs
		call	DOS_Setup_Info			; out: es = destination, dx:ax = stack location
		jc	sfp_81				; error...

		mov	bx,ss
		mov	cx,sp				; bx:cx = ss:sp
		mov	ss,dx
		mov	sp,ax				; ss:sp = dx:ax
		push	bx
		push	cx				; save old ss:sp on 2nd stack

		push	word ptr ds:[CUR_POS]	  	; save cursor pos ;R02
		push	word ptr ds:[CURSOR_MODE] 	; save cursor mode;R02

		mov	dx,24*1024			; Get buffer from stack;R05
		call	Save_Mouse_Status				       ;R05

		mov	al,[Con_Mode]			; save current mode
		push	ax
		call	SAVE_SCREEN

		push	ds				; ds = video buffer
		push	es				; es = save video save on 2nd stack

		mov	ax,0
		mov	ds,ax
		
		push	word ptr ds:[16h*4]		; Save INT 16h vector
		push	word ptr ds:[16h*4+2]
		push	word ptr ds:[09h*4]		; Save INT 09h vector
		push	word ptr ds:[09h*4+2]

;128K		EXTRN	KEYBOARD:NEAR		; Initial BIOS INT 16h vector
		mov	word ptr ds:[16h*4],offset KEYBOARD
		mov	word ptr ds:[16h*4+2],cs
						; Initial BIOS INT 09h vector
		mov	word ptr ds:[09h*4],offset KBD_INT
		mov	word ptr ds:[09h*4+2],cs
		push	ds

		call	Int_Kb_Enable

		mov	al,02h			;tell Setup who is calling
		call	Extern_Setup
		cli

		pop	ds

		pop	word ptr ds:[09h*4+2]	; Restore INT 09h vector
		pop	word ptr ds:[09h*4]
		pop	word ptr ds:[16h*4+2]	; Restore INT 16h vector
		pop	word ptr ds:[16h*4]

; restore video
		pop	ds				; ds = video save, from 2nd stack
		pop	es				; es = video buffer

		pop	ax				; set original mode
		call	RESTORE_SCREEN

		mov	dx,24*1024			; Get buffer from stack	;R05
		call	Restore_Mouse_Status					;R05

		pop	cx			 	; restore cursor mode;R02
		mov	ah,1				; set cursor type    ;R02
		int	10h						     ;R02
		cli
		pop	dx			  	; restore cursor pos ;R02
		mov	ah,2				; set cursor pos     ;R02
		xor	bh,bh						     ;R02
		int	10h						     ;R02
		cli

; Restore stack
		pop	cx				; restore ss:sp from 2nd stack
		pop	bx
		mov	ss,bx
		mov	sp,cx

		mov	al,1				; al = close video save/stack segs
		call	DOS_Setup_Info
		jnc	short sfp_81
sfp_8:							; wrong video mode/other error
		mov	cx,5000h			; set length for beep
		call	Beep_Key

sfp_81:
; Restore speaker
		pop	ax
		out	SYS1,al
		NEWIODELAY

; Restore DOS time
;128K		EXTRN	UPDATETIMER:NEAR
		call	UPDATETIMER

; Restore timer tick vector
		xor	ax,ax
		mov	ds,ax
		pop	eax
		mov	ds:[8*4],eax			;restore INT 8 Vector

; restore registers
		pop	ds				; restore registers from 1st stack
		pop	es
		pop	fs
		pop	gs
		popad

; Clear keyb buffer & status
		mov	dword ptr PTR_KBD_BUF_HD,01e001eh 
		and	SHFT_STAT,NOT (ALT+CTRL+LT_SHFT+RT_SHFT)	;R03
		and	KBD_FLG1,NOT (LEFT_CTRL+LEFT_ALT)		;R03
		and	KB_FLAG_3,NOT (RIGHT_CTRL+RIGHT_ALT)		;R03

		and	INIT_ERR_FLG,NOT IEF_SETUP_OK	; enable further setup

		jmp	.D86A
sfp_9:
ENDIF ;ALLOW_SETUP_FROM_DOS

		or	byte ptr Init_Err_Flg,IEF_TO_ENTER_SETUP
NOT_SETUP:

;R10		CMP	BYTE PTR CS:[SI+1],'-'	; see if ctrl/alt -
;R10		MOV	AL,0			; SLOWEST SPEED
;R10		JE	SHORT .D31EA
;R10
;R10		CMP	BYTE PTR CS:[SI+1],'+'	; see if ctrl/alt +
;R10		JNE	SHORT NOT_SPEED_SWITCH				   
;R10
;R10		MOV	AL,07FH			; HIGHEST SPEED
;R10
;R10.D31EA:
;R10
;R10		OR	AL,080H			; beep speaker.
;R10		CALL	SETSPEED		; set speed high
;R10
;R10		JMP	.D86A			; finish processing key
;R10
;R10NOT_SPEED_SWITCH:

; CHECK FLAG FOR FLAVOR (ALT, CNTR, ECT)

.D31EB:		TEST	SHFT_STAT,ALT
		JE	SHORT .D336		; jmp if not ALT

		CMP	SCAN_CHAR,0FH		; is this a tab
		JNE	SHORT .D335_2

		MOV	SCAN_CHAR,165		; set code
		JMP	SHORT .D335

; put in checks for  keypad / and keypad RETURN

.D335_2:	TEST	DH,LAST_E0		; is this extended code
		JE	SHORT .D335		; if not, finished

		CMP	SCAN_CHAR,01CH		; keypad RETURN
		JNE	SHORT .D335_1		; next

		MOV	SCAN_CHAR,166		; set scan code
		JMP	SHORT .D335

.D335_1:	CMP	SCAN_CHAR,035H		; keypad /
		JNE	SHORT .D335		; done

		MOV	SCAN_CHAR,164		; set scan code

.D335:		CMP	SCAN_CHAR,084H		; is this in old range
		JBE	SHORT .D335_A
		JMP	.D310			; if not leave code as 0
.D335_A:	MOV	TEMP,0F0H		; set extended function
		JMP	.D310			; yes, 101, ALTs defined

.D336:		TEST	SHFT_STAT,CTRL		; ctrl characters?
		JE	SHORT .D356

		MOV	AL,CS:+3[SI]		; ctrl code

		CMP	SCAN_CHAR,0FH		; is this a tab
		JNE	SHORT .D336_C		; check next case

		MOV	SCAN_CHAR,094H		; tab is extended function
.D336_F:	MOV	AL,0			; set extended code
		JMP	SHORT .D336_B

.D336_C:	CMP	SCAN_CHAR,04AH		; is this keypad -
		JNE	SHORT .D336_G		; no, check next case

		MOV	SCAN_CHAR,142		; ctrl - is extended function
		JMP	SHORT .D336_F

.D336_G:	CMP	SCAN_CHAR,04EH		; is this keypad +
		JNE	SHORT .D336_D		; no, check extended keys

		MOV	SCAN_CHAR,144		; ctrl + is extended function
		JMP	SHORT .D336_F

.D336_D:	TEST	DH,LAST_E0		; alternate function
		JE	SHORT .D336_B		; if not, go home

		CMP	SCAN_CHAR,035H		; is this keypad '/'
		JNE	SHORT .D336_A		; if not, check next case

		MOV	SCAN_CHAR,149		; set scan code
		JMP	SHORT .D336_F

.D336_A:	CMP	SCAN_CHAR,01CH		; is this keypad RETURN
		JNE	SHORT .D336_B

.D336_E:	MOV	SCAN_CHAR,0E0H		; set prefix code

.D336_B:	MOV	TEMP,AL			; set TEMP to code from table
		JMP	SWITCH_DONE

.D356:
ifndef	Non_English_KB
		TEST	SHFT_STAT,LT_SHFT + RT_SHFT
		JE	SHORT .D368		; jmp if no shift
else	;Non_English_KB
  ifdef	German_KB
		TEST	SHFT_STAT,LT_SHFT + RT_SHFT + CAPS_LK
		JE	SHORT .D368		; jmp if no shift
  endif	;German_KB
endif	;Non_English_KB

		MOV	AL,CS:+2[SI]		; shift code

		TEST	DH,LAST_E0		; is this alternate key
		JE	SHORT .D336_B		; if not, finish

ifndef	Non_English_KB
		CMP	AL,03FH 		; is this '?' (shift /)
		JNE	SHORT .D368_A		; no, test for keypad RETURN
						; yes, get unshifted code
else	;Non_English_KB
  ifdef	Portuguese_KB
		cmp	al,'_'
		jne	short .d368_a
  endif	;Portuguese_KB
  ifdef	German_KB
		cmp	al,'_'
		jne	short .d368_a
  endif	;German_KB
endif	;Non_English_KB


.D368:		MOV	AL,CS:+1[SI]		; unshifted code
		TEST	DH,LAST_E0		; is this alternate key

ifndef	Non_English_KB
		JE	SHORT .D336_B		; if not, finish
else	;Non_English_KB

  ifdef	Portuguese_KB
		jz	check_slash		;no
		jmp	no_check_slash		;yes
  check_slash:
		cmp	al,'/'
		jne	.D336_B
		mov	al,'-'
		jmp	.D336_B
  no_check_slash:
  endif	;Portuguese_KB

  ifdef	German_KB
		jz	check_slash		;no
		jmp	no_check_slash		;yes
  check_slash:
		cmp	al,'/'
		jne	.D336_B
		mov	al,'-'
		jmp	.D336_B
  no_check_slash:
  endif	;German_KB

endif	;Non_English_KB

		CMP	AL,02FH			; is this a '/'
		JE	SHORT .D336_E		; yes, set prefix code

.D368_A:	CMP	AL,0DH			; is this keypad RETURN
		JNE	SHORT .D336_B		; return normal scan code

		JMP	SHORT .D336_E		; set prefix code

; PROCESS NUMERIC

NUM_S:


.D375:		TEST	SHFT_STAT,ALT
		JNE	SHORT .D375_A
		JMP	.D336			; CHECK STATES

.D375_A:	ADD	SCAN_CHAR,118		; make alt #
		JMP	SWITCH_DONE

		PAGE

; PROCESS TOGGLE

TOG_S:		MOV	AL,CS:+1[SI]		; CHECK IF ALREADY SET
		TEST	KBD_FLG1,AL
		JE	SHORT .D3AE		; NOPE

		CMP	SCAN_CHAR,046H		; <CTRL><SCROLL LOCK>?
		JNE	SHORT .D86A_L4		; SKIP

		TEST	SHFT_STAT,CTRL
		JE	SHORT .D86A_L4		; SKIP

.D3AE:		OR	KBD_FLG1,AL		; SET BIT

; CHECK FOR SYS KEY

		CMP	SCAN_CHAR,84
		JNE	SHORT .D3E8		; NOPE

		call	int_kb_enable

		MOV	AX,8500H
		INT	15H
		JMP	.D87A

; CHECK FOR CAPS LOCK

.D3E8:		CMP	SCAN_CHAR,58
		JNE	SHORT .D45F		; NOPE

		TEST	SHFT_STAT,CTRL
		JNE	SHORT .D86A_L4
ifndef	Non_English_KB
		XOR	SHFT_STAT,CAPS_LK	; CHANGE FLAG
else	;Non_English_KB
  ifdef	German_KB
		OR	SHFT_STAT,CAPS_LK	; CHANGE FLAG
  endif	;German_KB
endif	;Non_English_KB
		CALL	UPDATE_LED		; CHANGE LED

.D86A_L4:	JMP	.D86A			; DONE

; CHECK FOR NUM LOCK

.D45F:		CMP	SCAN_CHAR,69
		JNE	SHORT .D4E3		; SKIP : NOT NUM LOCK

		TEST	DH,LAST_E1		; is this in a E1 sequence
		JNE	SHORT HOLD_IT		; this is Pause

		TEST	DH,E101_KEY		; is this a 101
		JNE	SHORT .D4CC		; yes, this is just num lock

		TEST	SHFT_STAT,CTRL
		JE	SHORT .D4CC		; SKIP : NOT CONTROL

HOLD_IT:	TEST	KBD_FLG1,HOLD		; save hold state
		PUSHF

		OR	KBD_FLG1,HOLD
		call	kyb_enable

		MOV	AL,END_OF_INT		; enable interrupts
		OUT	A8259,AL

		CMP	CON_MODE,7		; is this color graphics
		JGE	SHORT .D4B1		; no, ignore

		MOV	AL,CON_MODE_SET		; enable crt
		MOV	DX,3D8H
		OUT	DX,AL

; HOLD LOOP : AND EXIT

.D4B1:		POPF				; recover previous hold state
		JNZ	SHORT .D4B1_EXIT	; exit if previous one set

.D4B2:		TEST	KBD_FLG1,HOLD
		JNE	SHORT .D4B2		; LOOP
.D4B1_EXIT:
		JMP	.D87A			; RETURN : END OF INT 9

.D4CC:		XOR	SHFT_STAT,NUM_LK
		CALL	UPDATE_LED
		JMP	SHORT .D86A_L3		; DONE

; CHECK FOR SCROLL LOCK

.D4E3:		CMP	SCAN_CHAR,70
		JNE	SHORT TOG_DEL		; SKIP

		TEST	DH,LAST_E0		; is this ctrl Pause
		JNE	SHORT .D4E3_A		; yes, this is break

		TEST	DH,E101_KEY		; is this a 101
		JNE	SHORT .D555		; then this is only scroll lock

		TEST	SHFT_STAT,CTRL
		JE	SHORT .D555		; SKIP : NOT CONTROL

.D4E3_A:	MOV	BX,KBD_BUF_LOCN		; clear keyboard buffer
		MOV	PTR_KBD_BUF_HD,BX
		MOV	PTR_KBD_BUF_TL,BX
		MOV	BIOS_BRK,80H
		call	kyb_enable

		INT	1BH			; user called break routine

		MOV	SCAN_CHAR,0
		JMP	SWITCH_DONE

.D555:		XOR	SHFT_STAT,SCRL_LK
		CALL	UPDATE_LED

.D86A_L3:	JMP	.D86A			; DONE

; PROCESS <DEL>

TOG_DEL:	CMP	SCAN_CHAR,83
		JNE	SHORT TOG_PRTS		; NOT <DEL>

		TEST	SHFT_STAT,ALT
		JE	SHORT TOG_DEL_1		; PROCESS OTHER <DEL>'S

		TEST	SHFT_STAT,CTRL
		JE	SHORT ALT_DEL		; not ctrl/alt del

; PROCESS SYSTEM RESET (CONTROL ALT DELETE)


		MOV	USER_REBOOT,CTRL_ALT_DEL	; RESET THE SYSTEM

;M01 - starts
ifdef RPB_ENABLED
ifdef RPB_REBOOT_DISABLE
		call	rpbf_prepare_for_reset		;disable MPC before reboot
endif ; RPB_REBOOT_DISABLE
endif ; RPB_ENABLED
;M01 - ends

ifdef	Out_64h_FEh_For_Warm_Boot	;R09A
;R09 - starts
		mov	cx,20
	@@:
		mov	al,0FEh
		out	64h,al
		loop	@B
;R09 - ends
endif	;Out_64h_FEh_For_Warm_Boot	;R09A

		JMP	REDO			; restart the POST

ALT_DEL:	TEST	DH,LAST_E0		; is this alternate del
		JZ	SHORT .D86A_L3		; if not, alt del not defined

		MOV	SCAN_CHAR,163		; return valid scan code
		JMP	SHORT .D7A6_L1

TOG_DEL_1:	TEST	DH,LAST_E0		; is this alternate del
		JZ	SHORT NOT_ADEL

		MOV	TEMP,0E0H		; yes, use E0 prefix

NOT_ADEL:	TEST	SHFT_STAT,CTRL
		JZ	SHORT NOT_CTRL_DEL

		MOV	SCAN_CHAR,147		; scan code
		JMP	SHORT .D7A6_L1

NOT_CTRL_DEL:	TEST	SHFT_STAT,NUM_LK
		JE	SHORT .D5DD		; SKIP : NOT NUM LOCK

		TEST	SHFT_STAT,LT_SHFT + RT_SHFT
		JNE	SHORT .D7A6_L1

.D5D4:		TEST	DH,LAST_E0		; is this alternate del
		JNZ	SHORT .D7A6_L1		; then leave prefix = E0
		MOV	TEMP,'.'		; <SHIFT><DEL> = '.'
		JMP	SWITCH_DONE

.D5DD:		TEST	SHFT_STAT,LT_SHFT + RT_SHFT
		JNE	SHORT .D5D4

.D7A6_L1:	JMP	SWITCH_DONE		; LONG JUMP

; CHECK FOR PRINT SCREEN - changed for 101 keyboard

TOG_PRTS:	CMP	SCAN_CHAR,55		; check for print screen
		JNE	SHORT .D7A6_L1		; SWITCH DONE : NOT PRINT SCREEN

		TEST	DH,LAST_E0		; is this print screen on 101 - V3.02
		JE	SHORT NON_101_PRNT	; no, skip

		TEST	SHFT_STAT,CTRL		; is this ctrl prntscrn
		JZ	SHORT PRNT_IT		; if not, jmp to print screen

		JMP	SHORT PRT_CTRL		; jmp to ctrl prntscrn

NON_101_PRNT:	TEST	SHFT_STAT,ALT		; is it ALT *
		JE	SHORT PRT_101_A		; not ALT

		MOV	TEMP,0F0H		; set extended prefix
		JMP	SWITCH_DONE

PRT_101_A:	TEST	DH,E101_KEY		; is this a 101
		JE	SHORT PRT_84

		TEST	SHFT_STAT,CTRL		; is it CTRL *
		JE	SHORT .D628		; not CTRL

		MOV	SCAN_CHAR,096H		; set extended function
		JMP	SWITCH_DONE

PRT_84:		TEST	SHFT_STAT,CTRL
		JE	SHORT .D60E		; NOT CONTROL

PRT_CTRL:	MOV	SCAN_CHAR,72H
		JMP	SWITCH_DONE

.D60E:		TEST	SHFT_STAT,LT_SHFT + RT_SHFT
		JE	SHORT .D628

; PRINT SCREEN

PRNT_IT:	call	kyb_enable

		MOV	AL,END_OF_INT		; end of interrupt
		OUT	A8259,AL

		INT	5			; print screen
		JMP	.D870

.D628:		MOV	TEMP,'*'		; <PRT SC>
		JMP	SWITCH_DONE

		PAGE

; PROCESS KEYPAD

KEYP_S:
		TEST	SHFT_STAT,ALT
		JE	SHORT .D68C		; NOT ALT

		TEST	DH,LAST_E0		; is this one of the alternate keys
		JE	SHORT .D634_1		; if not, numeric enter

		ADD	SCAN_CHAR,050H		; convert to ALT key
		JMP	SWITCH_DONE		; return keystroke

.D634_1:	MOV	AL,ALT_INPUT		; PROCESS ALT - numeric enter
		MOV	BL,10
		MUL	BL			; ax=ALT_INPUT*10
		MOV	BL,CS:+2[SI]
		AND	BX,255
		SUB	BX,48			; bx= next digit
		ADD	AX,BX			; ax=ALT_INPUT*10+bx
		MOV	ALT_INPUT,AL		; save

.D86A_L2:	JMP	.D86A			; DONE : LONG JUMP

.D68C:		TEST	DH,LAST_E0		; is this an alternate keypad
		JZ	SHORT NOT_AKEY		; jmp if not
		MOV	TEMP,0E0H		; set alternate prefix

NOT_AKEY:	TEST	SHFT_STAT,CTRL
		JE	SHORT .D6AD		; NOT CONTROL

		MOV	AL,CS:+3[SI]

.D68C_A:	MOV	SCAN_CHAR,AL
		JMP	SWITCH_DONE

.D6AD:		TEST	SHFT_STAT,NUM_LK
		JE	SHORT .D6D7		; NOT NUM LOCK

		TEST	SHFT_STAT,LT_SHFT + RT_SHFT
		JNE	SHORT .D6E0

.D6CB:		TEST	DH,LAST_E0		; is this alternate
		JNZ	SHORT .D6EA		; V3.00 . ,finished if it is

		MOV	AL,CS:+2[SI]		; otherwise return ASCII
		MOV	TEMP,AL
		JMP	SWITCH_DONE

.D6D7:		TEST	SHFT_STAT,LT_SHFT + RT_SHFT
		JNE	SHORT .D6CB

.D6E0:		CMP	SCAN_CHAR,76		; keypad 5
		JNE	SHORT .D6EA

		MOV	TEMP,0F0H		; set prefix code
		JMP	SHORT SWITCH_DONE	; send character

.D6EA:		CMP	SCAN_CHAR,82		; Insert
		JNE	SHORT SWITCH_DONE

		MOV	AL,CS:+1[SI]		; if Insert, set flags
		TEST	KBD_FLG1,AL
		JNE	SHORT .D86A_L2		; DONE

		OR	KBD_FLG1,AL
		XOR	SHFT_STAT,INS_LK
.D7A6_L5:	JMP	SHORT SWITCH_DONE

		PAGE

; PROCESS F11 and F12 - V2.09

F11_HND:	ADD	SCAN_CHAR,52		; make ALT code
		TEST	SHFT_STAT,ALT
		JNZ	SHORT .D777		; return alt code

		SUB	SCAN_CHAR,2		; make ctrl code
		TEST	SHFT_STAT,CTRL
		JNZ	SHORT .D777		; return ctrl code

		SUB	SCAN_CHAR,2		; make shift code
		TEST	SHFT_STAT,LT_SHFT + RT_SHFT
		JNZ	SHORT .D777		; return shift code

		SUB	SCAN_CHAR,2		; make unshifted code
		JMP	SHORT .D777		; return unshifted code

; PROCESS FUNCTION

FUNC_S:		TEST	SHFT_STAT,ALT		; alt function?
		JE	SHORT .D74F

		ADD	SCAN_CHAR,45		; return alt scan code
		JMP	SHORT .D777

.D74F:		TEST	SHFT_STAT,CTRL		; ctrl function
		JE	SHORT .D76B

		ADD	SCAN_CHAR,35		; return ctrl scan code
		JMP	SHORT .D777

.D76B:		TEST	SHFT_STAT,LT_SHFT + RT_SHFT	; shifted function
		JE	SHORT .D777

		ADD	SCAN_CHAR,25		; return shift scan code

.D777:

		PAGE

; SWITCH DONE

SWITCH_DONE:
		CMP	SCAN_CHAR,0FFH
		JNE	SHORT .D86A_0
		JMP	.D86A		; DONE
.D86A_0:
		CMP	TEMP,0FFH
		JNE	SHORT .D86A_1
		JMP	.D86A		; DONE
.D86A_1:

; SAVE VALUE

.D7BA:		MOV	CH,SCAN_CHAR		; SCAN CODE
		MOV	CL,TEMP			; CHARACTER

ifndef	Non_English_KB
		CALL	INSERT_CHAR		; try to insert character
else	;Non_English_KB
		cmp	word ptr ds:[Non_Eng_Addr],0
		je	Special_Key_False

		push	es
		push	di
		push	ax
		push	cx

		mov	al,temp			;ascii code to be checked

		mov	di,word ptr ds:[Non_Eng_Addr]

		push	di
		push	cs
		pop	es
		mov	di,offset cs:Special_ASCII
		mov	cx,Special_ASCII_L
		repne	scasb
		pop	di
		jcxz	No_Special_ASCII

		add	di,Special_ASCII_L
		sub	di,cx
		dec	di
		cmp	byte ptr es:[di],'Z'
		je	No_Special_ASCII
		mov	cl,byte ptr es:[di]
		xor	ch,ch
		call	insert_char

		pop	cx
		pop	ax
		pop	di
		pop	es
		mov	word ptr ds:[Non_Eng_Addr],0
		jmp	Special_Key_Exit

  No_Special_ASCII:
		pop	cx
		pop	ax
		pop	di
		pop	es

		push	cx
		mov	cl,byte ptr ds:[Non_Eng_ASC]
		mov	ch,0
		call	insert_char
		pop	cx
		mov	word ptr ds:[Non_Eng_Addr],0

  Special_Key_False:

		CALL	INSERT_CHAR		; try to insert character
  Special_Key_Exit:
endif	;Non_English_KB

		JE	SHORT .D806		; if zero, then buffer overflow

		CLI
		call	int_kb_enable

		MOV	AX,9102H		; set interrupt complete flag
		MOV	SP,BP
		INT	15H

		AND	KB_FLAG_3, NOT (LAST_E1+LAST_E0)	; clear the E1
						; and E0 flags
		JMP	SHORT KBD_INT_RET	; RETURN : END OF INT 9

; BUFFER OVERFLOW : RING BELL

.D806:
		MOV	AL,END_OF_INT		; allow interrupts during
		OUT	A8259,AL		; beep.
		MOV	CX,5000H		; set length for beep
		CALL	BEEP_KEY
		AND	KB_FLAG_3, NOT (LAST_E1+LAST_E0)
		JMP	.D870			; don't send another END_OF_INT

; DONE : RETURN

.D86A:		AND	KB_FLAG_3, NOT (LAST_E1+LAST_E0)	; clear the E1
						; and E0 flags

.D86A_EXIT:	CLI
		MOV	AL,END_OF_INT		; END_OF_INT
		OUT	A8259,AL

.D870:		call	kyb_enable

.D87A:		CLI
		MOV	SP,BP

; RETURN FROM INT 9

;R18KBD_INT_RET:	POPA
KBD_INT_RET:					;R18
;R18AIFDEF	USB_SUPPORT             		;R18
;R18A		call	int9_usb		;R18
;R18AENDIF	;USB_SUPPORT				;R18
		POPA    			;R18
		POP	DS

IFDEF	POWER_MANAGEMENT			; R03
		call	PM_Clr_Critical		; clear critical setction
ENDIF	;POWER_MANAGEMENT			; semaphore

		IRET

KBD_INT		ENDP

		PAGE
		ALIGN	4			; 303A
INSERT_CHAR	PROC	NEAR
; tries to place character into buffer - fails if buffer full

; INPUT
; CH = scan code to be placed on buffer
; CL = ascii code to be placed in buffer
; DS = 40H

; OUTPUT
; Zero flag = 1 - if failed
;	    = 0 - if successful

; MODIFIES	   AX,SI

		MOV	AX,PTR_KBD_BUF_TL	; check for end of buffer
		ADD	AX,2
		CMP	AX,KBD_BUFEND_LOCN
		JNE	SHORT .D7F3		; NOPE

		MOV	AX,KBD_BUF_LOCN		; SET TO START

.D7F3:		CMP	AX,PTR_KBD_BUF_HD	; MORE ROOM IN BUFFER
		JE	SHORT .D7F3_1		; NO, exit with z=1

; ADD CHARACTER TO BUFFER

		MOV	SI,PTR_KBD_BUF_TL
		MOV	[SI],CX			; PUT CODE & CHAR IN BUFFER
		MOV	PTR_KBD_BUF_TL,AX	; UPDATE TAIL
.D7F3_1:	RET

INSERT_CHAR	ENDP

UPDATE_LED:
; Update the keyboard LED's
; Changed in V2.09 to only use ax and cx registers

; ENTRY
; DS = 40H

; EXIT
; NONE

; MODIFIES	CX
; CHECK FLAGS

		pushf				;R08
		CLI
		PUSH	AX			; save ax
		MOV	AL,SHFT_STAT
		AND	AL,70H			; get the state of the led keys
		MOV	CL,4
		SHR	AL,CL

		MOV	AH,KB_FLAG_2
		AND	AH,7			; get the actual led settings

		CMP	AL,AH			; check to see if the leds are right
		JE	SHORT .D9FD		; NO CHANGE NEEDED

		AND	KB_FLAG_2,0F8H		; update kb_flag_2 for new leds
		OR	KB_FLAG_2,AL		; with value from current led state

		PUSH	AX			; save led settings from al
		MOV	AL,END_OF_INT		; ENABLE INT
		OUT	A8259,AL

		MOV	AL,LED_CMD		; SEND LED COMMAND
		CALL	KB_OUT
		POP	AX			; get led settings
		JNE	SHORT .D9E9		; jump if there is an error

		CALL	KB_OUT
		JE	SHORT .D9FD		; jump if there is an error

.D9E9:		MOV	AL,KB_ENABLE		; SEND KEYBOARD ENABLE
		CALL	KB_OUT

.D9FD:		POP	AX			; restore
		popf				;R08
;R08		STI				; ENABLE INT AND RETURN
		RET

		PAGE
		ALIGN	4
BEEP_KEY	PROC	NEAR
; SOUND THE BELL

; ENTRY
; CX = loop counter

; EXIT
; NONE
DATA8254	=	40H
CTRL8254	=	43H

		IN	AL,CTRL8042
		IODELAY
		MOV	AH,AL			; SAVE VALUE

;Reprogram speaker's tone
DATA8254	=	40H
CTRL8254	=	43H
		push	ax
		mov	al,0B6H
		out	CTRL8254,al
		mov	ax,533H	
		out	DATA8254+2,al
		mov	al,ah
		NEWIODELAY
		out	DATA8254+2,al
		NEWIODELAY
		pop	ax

		OR	AL,00000011B		; ON
		OUT	CTRL8042,AL

		ALIGN	4			; 304 CONSTANT DURATION
		LOOP	SHORT $

		AND	AL,11111101B		; OFF
		OUT	CTRL8042,AL

		IODELAY
		MOV	AL,AH			; RESTORE VALUE
		OUT	CTRL8042,AL

		RET
BEEP_KEY	ENDP

		PAGE

		ALIGN	4
KB_OUT		PROC	NEAR
; Output DATA byte to the keyboard

; ENTRY
; AL	=	BYTE

; EXIT
; AX	=	0  - if ACK is received	- Zero flag = 1
; AX	=	FF - otherwise		- Zero flag = 0

; MODIFIES	AX,CX

                push    cx

                xor     cx,cx
		MOV	AH,AL			; SAVE AL	;R14
wait_mouse_data_clear:
;R14		MOV	AH,AL			; SAVE AL
                in      al,STAT8042             ;Read status
                test    al,OBF_AUX              ;AUX OBF (bit5)
                jz      ready_to_out_command
                sti
                loop    wait_mouse_data_clear   ; wait mouse data be cleared
                mov     ax,0ffh                 ;Set zero flag
                or      ax,ax
                jmp     .da41

ready_to_out_command:
                cli

		IN	AL,DATA8042		; CLEAR DATA PORT
		CALL	BUFFER_8042_FULL	; wait till buffer empty
		MOV	AL,AH                   ;Restore data
		OUT	DATA8042,AL		; SEND DATA
		call	Buffer_8042_Full	; Richard

		CALL	OUT_8042_FULL		; check for byte in controller
		JZ	SHORT .DA2B
		MOV	AL,END_OF_INT		; byte has arrived from controller
		OUT	A8259,AL

.DA2B:		IN	AL,DATA8042		; get byte
		CMP	AL,KB_ACK		; is it ACK?
		MOV	AX,0FFH			; if no, return ax=0FFH
		JNE	SHORT .DA41

		XOR	AX,AX			; yes, return ax=0
.DA41:		
                pop     cx
                RET
KB_OUT		ENDP
;R08 - end


		public	int_kb_enable			;R14
int_kb_enable:
		MOV	AL,END_OF_INT		; END OF INT
		OUT	A8259,AL
		public	kyb_enable			;R14
kyb_enable:
		MOV	AX,ENABLE_KBRD		; enable keyboard

		PUBLIC	KB_CNTRLR_OUT
		ALIGN	4			; N3.03
KB_CNTRLR_OUT	PROC	NEAR
; Output CONTROL byte to the keyboard
; ENTRY
; AL	=	BYTE
; EXIT
; NONE
; Modifies	CX, AX

		CLI
		CALL	OUT_8042
		STI
		RET
KB_CNTRLR_OUT	ENDP


		ALIGN	4
;[]=============================================================[]
; Procedure Name:	out_8042
;
;	Output a command to 8042 port 64h
;
; Inputs:	al = command byte
; Output:	zf = 0 : keyboard controller error
;		zf = 1 : successful
; Destroy:	ax, cx
; Author:	Ken Chen
; Date: 	06/21/90
;
; Rev	| Name	| Date		| TPR#	| Description
; ------+-------+---------------+-------+-------------------------------------
; 1.00	| Ken	| 06/21/90	| NEW	| Initial revision
;
;[]=============================================================[]
		PUBLIC	OUT_8042
OUT_8042	PROC	NEAR

		mov	ah,al			; save al
		call	Buffer_8042_Full	; wait till buffer empty, then
		jnz	out_8042_ret

		mov	al,ah
		out	STAT8042,al		; send command
		call	Buffer_8042_Full
out_8042_ret:
		ret
OUT_8042	ENDP

		ALIGN	4
;[]=============================================================[]
; Procedure Name:	out_8042_full
;	Check for 8042 output buffer full
; Saves:
; Inputs:	none
; Output:	al = status register value
;		zf = 0 : output buffer full
;		zf = 1 : no output buffer full
; Destroy:	ax, cx
; Author:	Ken Chen
; Date: 	06/21/90
;
; Rev	| Name	| Date		| TPR#	| Description
; ------+-------+---------------+-------+-------------------------------------
; 1.00	| Ken	| 06/21/90	| NEW	| Initial revision
;
;[]=============================================================[]
		PUBLIC	OUT_8042_FULL
OUT_8042_FULL	PROC	NEAR
		mov	ah,12
		public	Out_8042_Full1
Out_8042_Full1	label	near
otrck:
		xor	cx,cx
inrck:
		in	al,STAT8042
IFNDEF	NO_NEWIODELAY_IN_8042_IO				;R10
		NEWIODELAY			;R04
ENDIF	;NO_NEWIODELAY_IN_8042_IO				;R10

		test	al,OBF_8042				
		jnz	short onret

		loop	short inrck

		dec	ah
		jnz	short otrck
onret:
		ret
OUT_8042_FULL	ENDP

		ALIGN	4
;[]=============================================================[]
; Procedure Name:	buffer_8042_full
;	Check for 8042 input buffer full
; Saves:
; Inputs:	none
; Output:	al = status register value
;		zf = 0 : input buffer full
;		zf = 1 : no input buffer full
; Destroy:	al, cx
; Author:	Ken Chen
; Date: 	06/21/90
;
; Rev	| Name	| Date		| TPR#	| Description
; ------+-------+---------------+-------+-----------------------
; 1.00	| Ken	| 06/21/90	| NEW	| Initial revision
;
;[]=============================================================[]
		PUBLIC	BUFFER_8042_FULL
BUFFER_8042_FULL PROC	NEAR

		xor	cx,cx
inrck1:
		in	al,STAT8042
IFNDEF	NO_NEWIODELAY_IN_8042_IO				;R10
		NEWIODELAY			;R04
ENDIF	;NO_NEWIODELAY_IN_8042_IO				;R10

		and	al,IBF_8042			
		loopnz	short inrck1
		ret
BUFFER_8042_FULL ENDP


;R17ifndef FULL_SCREEN_LOGO					;R14
;R17		public	Enter_Setup_Check
;R17Enter_Setup_Check	proc	near
;R17		push	ds
;R17		mov	ax,G_RAM
;R17		mov	ds,ax
;R17		ASSUME	DS:G_RAM
;R17		test	byte ptr POST_FLAG,SETUP_ON
;R17		pop	ds
;R17		jz	short Not_To_Setup
;R17
;R17;R12 - Begin
;R17IFDEF	NoteBook_Power_Management
;R17		extrn	Check_0V_Resume:near
;R17		call	Check_0V_Resume
;R17		jnz	short Not_To_Setup
;R17ENDIF	;NoteBook_Power_Management
;R17;R12 - End
;R17
;R17Enter_Setup:
;R17		push	ds
;R17		mov	ax,G_RAM
;R17		mov	ds,ax
;R17		ASSUME	DS:G_RAM
;R17		mov	word ptr ds:USER_REBOOT, 0	;reset warm boot flag
;R17		and	INIT_ERR_FLG,NOT IEF_SETUP_OK	; prevent further
;R17
;R17;128K		extrn	Ct_Before_Setup:near
;R17		call	Ct_Before_Setup
;R17
;R17		pop	ds
;R17
;R17PRINTER_0_INIT	EQU	15H
;R17PRN_S_AF_IP_SI	EQU	37AH			;port to talk to strobe,
;R17						; auto feed, initialize
;R17						; printer, and select input
;R17						; pins of parrallel adapter
;R17INITIALIZE_PORT EQU	0100H
;R17		POST_func_call	Cp_Install
;R17		push	ax
;R17		push	dx
;R17		mov	al, PRINTER_0_INIT
;R17		mov	dx, PRN_S_AF_IP_SI
;R17		out	dx, al
;R17		mov	ax, INITIALIZE_PORT
;R17		xor	dx, dx
;R17		int	17H			;init printer port #0
;R17		pop	dx
;R17		pop	ax
;R17
;R17		mov	ax,g_ram			;R11
;R17		mov	ds,ax				;R11
;R17		assume	ds:g_ram			;R11
;R17		or	byte ptr KB_FLAG_2,7		;R11
;R17		call	UPDATE_LED			;R11
;R17
;R17		mov	al,0AAh
;R17		CALL	SETUP
;R17
;R17		JMP	REDO
;R17Not_To_Setup:
;R17		ret
;R17Enter_Setup_Check	endp
;R17endif ;FULL_SCREEN_LOGO					;R14

 IFDEF	ALLOW_SETUP_FROM_DOS
;[]===============================================================[]
;
; Save_Screen :
;	Routine to check save current screen in order to enter setup
;	from DOS.
;
; Entry: DS = G_RAM
;	 ES = Screen save area segment
;
; Exit:
;	Save current display to buffer, change the video mode to mode 3.
;
;
; Author: Ben Huang
; Date: Feb 08, 1993
;
; Name	| Date		| Description
; -----------------------------------------------------------------
; BEN	 02/08/93	 Initial version for OPTi Notebook
; BEN	 12/30/93	 Save text font area & text mode page 0 video RAM,;R04
;			 That we can save & restore in any video mode.	  ;R04
;			 ( The original source code is save video memory.);R04
;[]==================================================================[]
SAVE_SCREEN	PROC	NEAR

		call	save_vga_status
;R04 - Begin
;
; Save text mode character generator area
; 
                mov     dx,03c4h	; enable plane 2 will loaded font.
		mov     ax,0402h
		call	set_vga_reg
                mov     ax,0704h	; Chain for mode
		call	set_vga_reg

                mov     dx,03ceh
                mov     ax,0005h
		call	set_vga_reg
                mov     ax,0406h        ; memory mapping select to a000h,64k.
		call	set_vga_reg

		mov	ax,0204h	; Set plane ??
		call	set_vga_reg

		xor	di,di				; di = start of buffer
		mov	ax,0a000h
		mov	ds,ax

		xor	si,si
		mov	cx,10*512			; 4k byte / per plane
		cld
		rep	movsw

; Set to text mode 3 for setup
		mov	ax,083h				; set mode 3 & don't clear SCR
		int	10h
		cli

; Save video RAM that will be lost
		mov	ax,0B000h			; seg = (B000)
		cmp	byte ptr ds:[Con_Mode],7	; monochrome?
		je	short @F			; yes...
		add	ax,800h				; no... (seg = B800)
	@@:
		mov	ds,ax

;R05A		mov	cx,800h				; cx = length in dwords
		mov	cx,800h	* 2	;R05A		; cx = length in dwords
		xor	si,si
		cld
;R05A		rep	movsd				; copy buffer to save
		rep	movsw		;R05A		; copy buffer to save
;R04 - End

save_screen_exit:
		ret

SAVE_SCREEN	ENDP

;[]===============================================================[]
;
; Restore_Screen :
;	Routine to restore screen in order to return to DOS from
;	from setup.
;
; Entry: DS = Screen save area segment.
;	 AL = Video mode before enter setup.
;
; Exit:
;	Restore original video mode and display data which before 
;	enter setup.
;
; Author: Ben Huang
; Date: Feb 08, 1993
;
; Name	| Date		| Description
; -----------------------------------------------------------------
; BEN	 02/08/93	 Initial version for OPTi Notebook
; BEN	 12/30/93	 Save text font area & text mode page 0 video RAM.;R04
;			 That we can save & restore in any video mode.	  ;R04
;			 ( The original source code is save video memory.);R04
;[]==================================================================[]
RESTORE_SCREEN	PROC	NEAR

;R04 - Begin
		push	ax
; Restore video RAM
		mov	ax,0B000h			; seg = (B000)
		cmp	byte ptr ds:[Con_Mode],7	; monochrome?
		je	short @F			; yes...
		add	ax,800h				; no... (seg = B800)
	@@:
		mov	es,ax
;R05A		mov	cx,800h				; cx = length in dwords
		mov	cx,800h	* 2	;R05A		; cx = length in dwords
		mov	si,10*1024
		xor	di,di				; si,di = start of buffer
		cld
;R05A		rep	movsd				; copy buffer to save
		rep	movsw		;R05A		; copy buffer to save

		pop	ax

; Set to original mode
		xor	ah,ah				; Set to original mode
		or	al,80h				; Don't clear screen
		int	10h
		cli

;
; Restore text font for character generator
;
                mov     dx,03c4h
		mov     al,02h
		call	get_vga_reg
		push	ax
		mov     ax,0402h
		call	set_vga_reg

                mov     al,04h
		call	get_vga_reg
		push	ax
                mov     ax,0704h
		call	set_vga_reg

                mov     dx,03ceh
                mov     al,05h
		call	get_vga_reg
		push	ax
                mov     ax,0005h
		call	set_vga_reg

                mov     al,06h
		call	get_vga_reg
		push	ax
                mov     ax,0406h        ; memory mapping select to a000h,64k.
		call	set_vga_reg

                mov     al,04h
		call	get_vga_reg
		push	ax
		mov	ax,0204h	; Set plane ??
		call	set_vga_reg

		xor	si,si				; di = start of buffer
		mov	ax,0a000h
		mov	es,ax

		xor	di,di
		mov	cx,10*512			; 4k byte / per plane
		cld
		rep	movsw

		pop	ax
		xchg	ah,al
                mov     al,04h
		call	set_vga_reg

		pop	ax
		xchg	ah,al
                mov     al,06h
		call	set_vga_reg

		pop	ax
		xchg	ah,al
                mov     al,05h
		call	set_vga_reg

                mov     dx,03c4h
		pop	ax
		xchg	ah,al
                mov     al,04h
		call	set_vga_reg

		pop	ax
		xchg	ah,al
		mov	al,2
		call	set_vga_reg

; Restore VGA Status
		call	restore_vga_status
;R04 - End

		ret

RESTORE_SCREEN	ENDP

;
; Subroutine for restore VGA status use VGA BIOS function call.
;
restore_vga_status	proc	near
			push	es
			mov	ax,ss
			mov	es,ax
			mov	bx,20*1024		;R04
	ifdef	Chips_VGA
; save video information for C&T VGA BIOS
			mov	ax,5fa2h
			mov	cx,8007h
			int	10h
			cli
	else
			mov	ax,01c02h
			mov	cx,7		; Restore DAC & color register
ifdef	Save_VGA_Entry_Point
			int	ORG_VGA_INT
else
			int	10h
endif	;Save_VGA_Entry_Point
			cli
	endif	;Chips_VGA

			pop	es
			ret
restore_vga_status	endp

;
; Subroutine for save VGA status use VGA BIOS function call.
;
save_vga_status		proc	near
			push	es
			mov	bx,20*1024	; Get buffer from stack;R04
			mov	ax,ss
			mov	es,ax
	ifdef	Chips_VGA
; save video information for C&T VGA BIOS
			mov	ax,5fa1h
			mov	cx,8007h
			int	10h
			cli
	else
; save video information
			mov	ax,01c01h
			mov	cx,7		; Save DAC & color register
ifdef	Save_VGA_Entry_Point
			int	ORG_VGA_INT
else
			int	10h
endif	;Save_VGA_Entry_Point
			cli
	endif	;Chips_VGA
			pop	es
			ret
save_vga_status		endp

;
; Subroutine for read VGA register
;
get_vga_reg	proc	near
		out	dx,al
		inc	dl
		in	al,dx
		dec	dl
		ret
get_vga_reg	endp

;
; Subroutine for write VGA register
;
set_vga_reg	proc	near
		out	dx,al
		inc	dl
		xchg	ah,al
		out	dx,al
		dec	dl
		xchg	ah,al
		ret
set_vga_reg	endp

;R05 - Begin
;[]===============================================================[]
;
; Save_Mouse_Status :
;	Routine to save mouse status via INT 33H mouse driver.
;
; Entry:
;	DX=Offset of save area.
;
; Exit:
;	Disable mouse cursor.
;
; Author: Ben Huang
;
; Name	| Date		| Description
; -----------------------------------------------------------------
; BEN	 12/30/93	 Initial version
;[]==================================================================[]
			public	Save_Mouse_Status
Save_Mouse_Status	proc	near

			push	es
			xor	bx,bx
			mov	ax,15h		; Get mouse status size.
			int	33h
			or	bx,bx		; Is mouse driver support ?
			jz	short  @F

			mov	di,dx

			mov	ax,2		; Hide mouse cursor
			int	33h

			add	dx,8
			mov	ax,ss
			mov	es,ax
			mov	ax,16h		; Save mouse status to buffer
			int	33h

			in	al,A8259+1
			mov	byte ptr es:[di+2],al	; Save IRQ mask status
			or	al,0f8h			; Mask IRQ 3,4,5,6,7
			out	A8259+1,al

			mov	ax,G_RAM
			mov	ds,ax
			mov	ax,word ptr ds:[Hardware]
			mov	word ptr es:[di],ax

			test	word ptr ds:[Hardware],04h
			jz	short @F	; Is PS2 mouse exist ?

			mov	ax,0c200h
			mov	bx,0000h
			int	15h
			and	word ptr ds:[Hardware],not 04h

		@@:
			pop	es
			cli
			ret
Save_Mouse_Status	endp

;[]===============================================================[]
;
; Restore_Mouse_Status :
;	Routine to restore mouse status via INT 33H mouse driver.
;
; Entry:
;	DX=Offset of save area.
;
; Exit:
;	Enable mouse cursor.
;
; Author: Ben Huang
;
; Name	| Date		| Description
; -----------------------------------------------------------------
; BEN	  12/30/93	 Initial version
;[]==================================================================[]
			public	Restore_Mouse_Status
Restore_Mouse_Status	proc	near

			push	es
			xor	bx,bx
			mov	ax,15h		; Get mouse status size.
			int	33h
			or	bx,bx		; Is mouse driver support ?
			jz	short  @F

			mov	ax,ss
			mov	es,ax
			mov	di,dx
			add	dx,8

			mov	ax,G_RAM
			mov	ds,ax
			mov	ax,word ptr es:[di]
			mov	word ptr ds:[Hardware],ax

			mov	al,byte ptr es:[di+2]
			out	A8259+1,al

			test	word ptr ds:[Hardware],04h
			jz	short no_ps2

			mov	ax,0c200h
			mov	bx,0100h
			int	15h
no_ps2:
			mov	ax,17h		; Restore mouse status to buffer
			int	33h

			mov	ax,1		; Show mouse cursor
			int	33h
		@@:
			pop	es
			cli
			ret
Restore_Mouse_Status	endp
;R05 - End
ENDIF ;ALLOW_SETUP_FROM_DOS

FCODE		ENDS
		END

