bini 发表于 2008-10-8 14:58:49

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

Tangailiu 发表于 2008-10-21 17:14:36

void openA20()
{        while(inp(0x64) & 2);        outp(0x64,0xd1);
        while(inp(0x64) & 2);        outp(0x60,0xdf);
        while(inp(0x64) & 2);        outp(0x64,0xff);
}
页: [1]
查看完整版本: Enable or disable A20 gate through KBC demo code.