Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine whether the computer has an XT/AT keyboard in assembly?

I just finished writing my 16 bit operating system but I used int 0x16 to tell which key the user pressed. Now I want to write my own keyboard driver and I don't want to use any interrupts. (So that I can enter long mode). I realized there are two scan codes, the AT and the XT. How can I determine which keyboard does the computer use in NASM x86 assembly?

Should I ask the user to press a key and determine using the scan code in port 0x60 when the OS boots?
eg: A key - 0x1c(make) for AT and 0x1e(make) for XT
But linux does not do that.......

I used the following code and discovered virtual box uses an XT keyboard....

[org 0x2e00]

mov bx, 0x1000
mov ds, bx      ;The program is loaded at 0x12e00 or 1000:2e00 by the operating system

    xor ax, ax  ;Set AX to zero
    mov bl, 0x0e    ;Set text color 

loop:           ;Main loop

    in al, 0x60 ;Read all ports and display them
    mov cx, ax
    call hex_print  ;Print content of the port in hex
    in al, 0x61
    mov cx, ax
    call hex_print
    in al, 0x62
    mov cx, ax
    call hex_print
    in al, 0x63
    mov cx, ax
    call hex_print
    in al, 0x64
    call hex_print
    call com_cls    ;Clear the screen after printing content
    jmp loop    ;Jump to loop


;Print hex values;;;;;;;;;;;;;;;;;
hex_print:
    push ax
    push cx
    mov ah, 0x0e
    mov al, ' '
    int 0x10
    mov al, '0'
    int 0x10
    mov al, 'x'
    int 0x10
hex_print_start:
    mov al, ch
    and al, 0xf0
    call hex_map
    int 0x10
    shl cx, 0x04
    mov al, ch
    and al, 0xf0
    call hex_map
    int 0x10
    shl cx, 0x04
    mov al, ch
    and al, 0xf0
    call hex_map
    int 0x10
    shl cx, 0x04
    mov al, ch
    and al, 0xf0
    call hex_map
    int 0x10
hex_print_end:
    pop cx
    pop ax
    ret

hex_map:
    cmp al, 0x00
    jne zero_end
    mov al, '0'
    ret
zero_end:
    cmp al, 0x10
    jne one_end
    mov al, '1'
    ret
one_end:
    cmp al, 0x20
    jne two_end
    mov al, '2'
    ret
two_end:
    cmp al, 0x30
    jne three_end
    mov al, '3'
    ret
three_end:
    cmp al, 0x40
    jne four_end
    mov al, '4'
    ret
four_end:
    cmp al, 0x50
    jne five_end
    mov al, '5'
    ret
five_end:
    cmp al, 0x60
    jne six_end
    mov al, '6'
    ret
six_end:
    cmp al, 0x70
    jne seven_end
    mov al, '7'
    ret
seven_end:
    cmp al, 0x80
    jne eight_end
    mov al, '8'
    ret
eight_end:
    cmp al, 0x90
    jne nine_end
    mov al, '9'
    ret
nine_end:
    cmp al, 0xa0
    jne a_end
    mov al, 'A'
    ret
a_end:
    cmp al, 0xb0
    jne b_end
    mov al, 'B'
    ret
b_end:
    cmp al, 0xc0
    jne c_end
    mov al, 'C'
    ret
c_end:
    cmp al, 0xd0
    jne d_end
    mov al, 'D'
    ret
d_end:
    cmp al, 0xe0
    jne e_end
    mov al, 'E'
    ret
e_end:
    cmp al, 0xf0
    jne f_end
    mov al, 'F'
    ret
f_end:
    ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;The "cls" command;;;;;;;;;;;;;;;;;;;;;;;;;;;;
com_cls:
    push ax
    push bx
    push cx
    push dx
    mov ax, 0x0700      ; function 07, AL=0 means scroll whole window
    mov bh, 0x00        ; character attribute = black
    mov cx, 0x0000      ; row = 0, col = 0
    mov dx, 0x1e54      ; row = 30 (0x1e), col = 79 (0x4f)
    int 0x10            ; call BIOS video interrupt
    mov ah, 0x02        ;function 02, set curser position
    mov dx, 0x00
    int 0x10
    pop dx
    pop cx
    pop bx
    pop ax
    ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ret

scan code 0x9e: XT! Scan code 0x9E: Break for 'A' key in XT keyboard!

Thanks in advance for the help.

like image 815
RainingComputers Avatar asked Dec 24 '22 05:12

RainingComputers


1 Answers

Whenever you need some advice programming an OS, take a look at The OSDev wiki is great!
These two pages will help you:

  • The PS2 Controller.
  • The PS2 Keyboard.

It is unlikely that you have to deal with an XT keyboard because they where used in the PC-XT that didn't have an 8042 but an 8255 (PPI) chip.
And the PPI responds to ports 60h-63h only, leaving out the 64h which I think you are using.
See this listing.


Don't get confused between keyboard commands and controller commands, from your OS both translate into writes to the same data port but the firsts make their way down to the keyboard, the latter stop at the 8042.

Consider that there are three scan code sets (named set 1, 2 and 3).
The XT used the first, the second one is currently supported by every keyboard, the third is rarely used.
So you have to check which scan code set the keyboard is using, by default it is the second.
Use keyboard command 0f0h with a payload of 00h to known the current scan code (after the usual keyboard ACK 0fah).
If you use a payload of 01h, 02h or 03h you can set the scan code set in use.

Beware that the 8082 by default translate scan code set 2 into scan code set 1, to disable this translation use the controller commands 20h and 60h to clear bit 6 of the Controller Configuration Byte.


So in short:

  1. You are likely dealing with a scan code translation, rather than with an (emulated) XT keyboard.
  2. Disable the translation.
  3. Explicitly set the scan code set you support.
like image 162
Margaret Bloom Avatar answered Dec 31 '22 15:12

Margaret Bloom