Enable or disable A20 gate through KBC demo code.
反正图方便的,就拿去参照,也是之前遗留的code,整理了一下,好象其中的代码,一位Korea的同学有留下来一段code。;A200N.ASM;
; Trun on the line A20 through the KBC, programming by bini for debug. 2008-07-01
; ml A20ON.asm
;
.model tiny
.code
.486
.startup
mov dx, offset msg_author
mov ah, 09h
int 21h
mov dx, offset msg_fail
call A20_ENABLE
jz exit1
mov dx, offset msg_ok
exit1: mov ah, 09h
int 21h
mov ax, 4C00h
int 21h
msg_author db "Trun on the line A20 tools through the KBC, programmin by bini", 13, 10,
"2008-07-01",13, 10, "$"
msg_ok db "A20 Enable OK", 13, 10, "$"
msg_fail db "A20 Enable FAIL", 13, 10, "$"
;------------------------ follow code maybe make to lib, if you want...-------------------------------
A20_ENABLE:
call A20Write
jz exit_enable
cli ; Only need for reading value from KBC
mov al, 0D0h
out 64h, al
call A20Read
jz enable_int
in al, 60h ; Get current status
mov ah, al
call A20Write
enable_int: sti
jz exit_enable
mov al, 0D1h ; Tell the KBC , want to write to the
out 64h, al ; Out Put Port next
call A20Write
jz exit_enable
mov al, ah
or al, 2 ; Enable line A20
out 60h, al
call A20Write
jz exit_enable
mov al, 0FFh ; NOP
out 64h, al
call A20Write
exit_enable: ret
A20Write: xor cx, cx ; Reasonable wait
get_wirte: in al, 64h ; Get KBC read status
test al, 02 ; See if buffer empty, bit 1 clear
jz clear
dec cx
jz exit_write
jmp short get_wirte
clear: inc al ; Clear ZR
exit_write: ret
A20Read: xor cx, cx
get_read: in al, 64h
test al, 01 ; If the 'output buffer' is full, has
jnz exit4 ; ...
dec cx
jnz get_read
exit4: ret
end ;A200FF.ASM
;
; Trun off the line A20 through the KBC, programming by bini for debug. 2008-07-01
; ml A20ON.asm
;
.model tiny
.code
.486
.startup
mov dx, offset msg_author
mov ah, 09h
int 21h
mov dx, offset msg_fail
call A20_DISABLE
jz exit1
mov dx, offset msg_ok
exit1: mov ah, 09h
int 21h
mov ax, 4C00h
int 21h
msg_author db "Trun off the line A20 tools through the KBC, programmin by bini", 13, 10,
"2008-07-01",13, 10, "$"
msg_ok db "A20 Disable OK", 13, 10, "$"
msg_fail db "A20 Disable FAIL", 13, 10, "$"
;------------------------ follow code maybe make to lib, if you want...-------------------------------
A20_DISABLE:
call A20Write
jz exit_disable
cli ; Only need for reading value from KBC
mov al, 0D0h
out 64h, al
call A20Read
jz Disable_int
in al, 60h ; Get current status
mov ah, al
call A20Write
Disable_int: sti
jz exit_disable
mov al, 0D1h ; Tell the KBC , want to write to the
out 64h, al ; Out Put Port next
call A20Write
jz exit_disable
mov al, ah
and al, not 2 ; Disable line A20
out 60h, al
call A20Write
jz exit_disable
mov al, 0FFh ; NOP
out 64h, al
call A20Write
exit_disable: ret
A20Write: xor cx, cx ; Reasonable wait
get_wirte: in al, 64h ; Get KBC read status
test al, 02 ; See if buffer empty, bit 1 clear
jz clear
dec cx
jz exit_write
jmp short get_wirte
clear: inc al ; Clear ZR
exit_write: ret
A20Read: xor cx, cx
get_read: in al, 64h
test al, 01 ; If the 'output buffer' is full, has
jnz exit4 ; ...
dec cx
jnz get_read
exit4: ret
end ;A20STATE.ASM
;
; Returns the status of the line A20 through the KBC
; programming by bini for debug. 2008-07-01
;
.model tiny
.code
.486
.startup
mov dx, offset msg_fail
call _GET_A20_STATE_
jz exit1 ;was a problem
push ax ; Save state, AH
mov dx, offset msg_ok ; There wasn't a problem
mov ah, 09h
int 21h ; Print message
pop ax ; retreve state
mov dx, offset msg_dis
and ah, 00000010b ; bit 1, 2h, indicates state
jz exit1
mov dx, offset msg_en
exit1: mov ah, 09h
; DX already contains address of string
int 21h
mov ax, 4C00h
int 21h
msg_ok db "OK", 13, 10, "A20 $"
msg_fail db "FAIL", 13, 10, "$"
msg_en db "ENABLED", 13, 10, "$"
msg_dis db "DISABLED", 13, 10, "$"
_GET_A20_STATE_:
call A20Write ; Wait till the input register is empty
jz exit2+1 ; Bypas the reset int's
cli ; Disable ints so we'll get our value
mov al, 0D0h ; Send command to the 8042 command register
out 64h, al ; to tell it we want to Read the Output Port
call A20Read ; Wait till the 8042 output register
jz exit2 ; has something in it's buffer
in al, 60h ; Get it
mov ah, al
call A20Write ; Make sure the input register is empty
jz exit2
mov al, 0FFh ; KBC NOP command, does nothing
out 64h, al
call A20Write
exit2: sti
ret
A20Write: xor cx, cx ; Reasonable wait
get1: in al, 64h ; Get KBC read status
test al, 02 ; See if buffer empty, bit 1 clear
jz clear
dec cx
jz exit3
jmp SHORT get1
clear: inc al ; Clear ZR
exit3: ret
A20Read: xor cx, cx
get2: in al, 64h
test al, 01 ; If the 'output buffer' is full, has
jnz exit4 ; something for me
dec cx
jnz get2
exit4: ret
end void openA20()
{ while(inp(0x64) & 2); outp(0x64,0xd1);
while(inp(0x64) & 2); outp(0x60,0xdf);
while(inp(0x64) & 2); outp(0x64,0xff);
}
页:
[1]