Skeledog
Skeledog

Reputation: 21

int 16 keyboard not being read on 286 machine

I have made a very simple x86 assembly real mode OS that uses in 0x16 for the keyboard input. I have tested the OS in both VirtualBox and Qemu, both times the keyboard input works just fine. However when I try to run the OS on a real 286 based PC-AT clone, it is able to boot, load sectors to memory (via int 0x13), then print the first string but it does not respond to input from the keyboard. I checked the x86 instructions listing and every instruction I have in my code does seem to be supported by the 186 and 286. And since it runs in real mode, the 286 being 16 bit shouldn't be a problem? Is there something I am missing when compiling that is causing this issue? Or is there some quirk in the PC-AT that is causing the issue? I am very new to programming (this is one of the first larger things I have written that wasn't just following a tutorial) so I am not too familiar with stuff so I maybe it is some error/oversight in my code?

Also to note, the code on the 286 PC doesn't seem to be crashing or aything, just not reading the keyboard, since locklights can still be triggered and PC restarts on ctrl-alt-del

Here is the part of the code that boots and reads the keyboard:

            [org 0x7c00]
    xor ah, ah
    mov al, 0x03
    int 0x10
     
    mov ah, 0x0e
    mov al, 0x0a
    int 0x10
     
    xor ax, ax
    mov es, ax
    mov ds, ax
     
    mov ah, 2
    mov al, 18
    mov ch, 0
    mov cl, 2
    mov dh, 0
    mov bx, 0x7e00
     
    int 0x13
     
    mainLoop:
    mov bx, intro
    call printString
    call newLine
     
    mov bx, cmdBuffer
    xor cx, cx
    waitForKey:
        xor ah, ah
        int 0x16
        
        push bx
        push cx
        mov bx, badChar
        mov cl, 0
        cmpLoop:
            inc bx
            cmp ah, [bx]
            je popBack
            cmp cl, [bx]
            jne cmpLoop
        pop cx
        pop bx 
        jmp continue
        popBack:
            pop cx
            pop bx
            jmp waitForKey
        
        continue:
        cmp al, 0x0d
        je enterKey
        cmp al, 0x08
        je backspaceKey
        
        cmp cx, 126
        je waitForKey
        
        mov ah, 0x0e
        push bx
        mov bl, [colourByte]
        int 0x10
        pop bx
        
        mov [bx], al
        inc bx
        inc cx
     
        jmp waitForKey
;rest of code

Interestingly, this slightly older version of the code does work on the 286: https://pastebin.com/391FWSNT

(both written for NASM)

Upvotes: 0

Views: 174

Answers (1)

Skeledog
Skeledog

Reputation: 21

I found the issues:

  1. For NASM to generate machine code compatible with the 80286 I had to define CPU 286 along with BITS 16
  2. The BIOS on these ancient machines does not seem to support multitrack reads and writes and since I am trying to read more than 18 sectors from the floppy, I needed to segment the one int 0x13 into 2 and change the head in between like this:
mov ah, 2
mov al, 17
mov cx, 2   ;cl=2 ch=0
xor dh, dh
mov bx, 0x7e00

int 0x13

mov ah, 2

mov cx, 1    ;cl=1 ch=0
mov dh, 1
mov al, 8
mov bx, 0xa000

int 0x13

Upvotes: 2

Related Questions