4

I want to implement cursor movement using keys in my OS. I tried this code to do that:

mouse:
mov ah,0h
int 16h

    cmp al, 107
    je Down


    cmp al, 105
    je Up


    cmp al, 106
    je Left


    cmp al, 108
    je Right

    jmp mouse

    Right:
        add dl, 1
        call SetCursor
        jmp mouse
        ret

    Left:
      sub dl, 1
      call SetCursor
      jmp mouse
      ret

   Up:
     sub dh, 1
     call SetCursor
     jmp mouse
     ret

   Down:
      add dh, 1
      call SetCursor
      jmp mouse
      ret

   SetCursor:
       mov ah, 02h
       mov bh, 00
       int 10h
       ret

Bootloader (a little part of it):

%include "stage2info.inc"

STAGE2_LOAD_SEG  equ STAGE2_ABS_ADDR>>4

.stage2_loaded:
    mov ax, STAGE2_RUN_SEG      
    mov ds, ax
    mov es, ax
    jmp STAGE2_RUN_SEG:STAGE2_RUN_OFS

TIMES 510-($-$$) db  0
dw 0xaa55

Why cursor doesn't moves vertically on real hardware but does on a virtual machine? I tried to change the keys but nothing, same. Why the code doesn't work on real hardware? Is my code wrong?

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
fsdfff
  • 121
  • 8

1 Answers1

4

Issues and comments:

  • To check for the arrow keys you need to look at the scancodes in AH, not the ASCII characters in AL. Scan codes are 0x50 for down, 0x48 for up, 0x4b for left, and 0x4d for right
  • You don't initialize DH and DL before entering your mouse loop. Retrieve the current coordinates with Int 10h/AH=3h before entering the loop
  • You don't test the bounds going off the top, left, right, and bottom edges of the screen so if the cursor goes out of bounds unexpected things can happen
  • You have unnecessary ret instructions after jmp mouse that can never be reached.
  • You can use INC and DEC instructions to add or subtract one from a register rather than using ADD and SUB with a value of one.
  • For people viewing the question, the bootloader being used is a template I put together in this Stackoverflow Answer.

This code should work:

%include "stage2info.inc"
ORG STAGE2_RUN_OFS

BITS 16

MAX_ROW equ 25                  ; 80x25 screen extents
MAX_COL equ 80

mouse:
    mov ah, 3                   ; Get cursor BIOS call
    mov bh, 0                   ; Page number is zero
    int 10h                     ; DH and DL will be set to current coordinates.

    mov ah,0h
    int 16h

    cmp ah, 0x50
    je Down

    cmp ah, 0x48
    je Up

    cmp ah, 0x4b
    je Left

    cmp ah, 0x4d
    je Right

    jmp mouse

    Right:
      inc dl
      cmp dl, MAX_COL           ; Test for right edge.
      jl right_bound_ok
      mov dl, MAX_COL-1
    right_bound_ok:
      call SetCursor
      jmp mouse

    Left:
      dec dl
      jge left_bound_ok         ; Test for left edge (<0?)

      mov dl, 0
    left_bound_ok:
      call SetCursor
      jmp mouse

    Up:
      dec dh
      jge up_bound_ok           ; Test for upper edge (<0?)

      mov dh, 0
    up_bound_ok:
      call SetCursor
      jmp mouse

    Down:
      inc dh
      cmp dh, MAX_ROW           ; Test for bottom edge
      jl down_bound_ok
      mov dh, MAX_ROW-1
    down_bound_ok:
      call SetCursor
      jmp mouse

    SetCursor:
      mov ah, 02h
      mov bh, 00
      int 10h
      ret
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/186072/discussion-on-answer-by-michael-petch-why-cursor-doesnt-moves-verticaly-on-real). – Samuel Liew Jan 02 '19 at 22:59