0

The problem
Discovering question ASM Replacing scancodes with ASCII characters and using it's answer(a bit modified to treat special characters not as ASCII but to move specific value to a buffer) i was able to get individual characters from keyboard input, how is it possible to combine then into one complete string?

Attempts
Procedure #1 in the following section works and correctly outputs input until it catches the Enter keypress

But when stosb gets added , it stops doing so(procedure #2) even before outputting the first character

#1

gets:
.repeat:
call keyboard
cmp byte[switch], 0x020 ; buffer named above being checked for Enter value
je .end
jmp .repeat
.end:
ret

#2

gets_modified:
mov di, buffer
.repeat:
call keyboard
cmp byte[switch], 0x020 ; buffer named above being checked for Enter value
stosb 
je .end
jmp .repeat
.end:
ret

Expected result: A string in buffer
Actual result: None

EDIT: Procedure keyboard requested in the comments

keydown: db 0x1E, 'a',0x30, 'b',0x2E, 'c',0x20, 'd',0x12, 'e',0x21, 'f',0x22, 'g',0x23, 'h',0x17, 'i',0x24, 'j',0x25, 'k',0x26, 'l',0x32, 'm',0x31, 'n',0x18, 'o',0x19, 'p',0x10, 'q',0x13, 'r',0x1F, 's',0x14, 't',0x16, 'u',0x2F, 'v',0x11, 'w',0x2D, 'x',0x15, 'y',0x2C, 'z',0x0B, '0',0x02, '1',0x03, '2',0x04, '3',0x05, '4',0x06, '5',0x07, '6',0x08, '7',0x09, '8',0x0A, '9',0x29, '~',0x0C, '-',0x0D, '=',0x2B, '\',0x1A, '[',0x1B, ']',0x27, '\59',0x28, '\39',0x33, ',',0x34, '.',0x35, '/'
keyup: db 0x9E, 'a', 0xB0, 'b', 0xAE, 'c', 0xA0, 'd', 0x92, 'e', 0xA1, 'f', 0xA2, 'g', 0xA3, 'h', 0x97, 'i', 0xA4, 'j', 0xA5, 'k', 0xA6, 'l', 0xB2, 'm', 0xB1, 'n', 0x98, 'o', 0x99, 'p', 0x90, 'q', 0x93, 'r', 0x9F, 's', 0x94, 't', 0x96, 'u', 0xAF, 'v', 0x91, 'w', 0xAD, 'x', 0x95, 'y', 0xAC, 'z', 0x8B, '0', 0x82, '1', 0x83, '2', 0x84, '3', 0x85, '4', 0x86, '5', 0x87, '6', 0x88, '7', 0x89, '8', 0x8A, '9', 0x89, '~', 0x8C, '-', 0x82, '=', 0xAB, '\', 0x9A, '[', 0x9B, ']', 0xA7, '\59', 0xA8, '\39', 0xB3, ',', 0xB4, '.', 0xB5, '/'
switch: db 0
keyboard:
    cli
    in al, 0x64
    test al, 1
    jz return
    test al, 0x20
    jnz return

    in al, 0x60

    cmp cl, 0
    je keypress
    jmp keyrelease

keyrelease:
    mov cl, 0
    sti
    ret

keypress:
    mov cl, 1
    cmp al, 1Ch
    je .ent
    call convert
    mov ah, 0x0E
    int 0x10
    jmp .end
    .ent:
    mov byte[switch], 0x020
    .end:
    sti
    ret

convert:
    mov bx, 0
    .LOOP:
        cmp al, [keydown+bx]
        je .conv
        add bx, 2
        jmp .LOOP
    .conv:
        mov al, [keydown+bx+1]
        ret

return:
   ret

It was mostly copied over but it seems to have the right value, and unlikely to be the cause of the problem

  • Can you show us the function `keyboard`? STOSB will store the byte in AL to ES:DI but it is unclear if AL actually has the right value in it. Did you set the ES register too? – Michael Petch May 05 '19 at 08:15
  • No, the es register was not set, will include function in edit, very grateful for your response – Валентин Попов May 05 '19 at 08:41
  • The code you found doesn't actually wait for a keypress (the code is terrible). Because of that it returns a value even when there is no keypress and the buffer (which you don't show us how it is defined) ill get filled up very fast probably overwriting the code and screwing things up badly making it appear to get stuck. At a minimum `keyboard` should probably start with `keyboard:` `cli` `.repeat:` `in al, 0x64` `test al, 1` `jz .repeat` At least that code would attempt to poll the keyboard state until a keypress is actually available and then retrieve a character. – Michael Petch May 05 '19 at 09:14
  • Thanks a lot, i will make needed changes soon and report the result as soon as possible! – Валентин Попов May 05 '19 at 09:17
  • What I suggested above is only a start. To be quite frank, I wouldn't even attempt to use that code you found at all. Not all code on the internet is good. – Michael Petch May 05 '19 at 09:45
  • Can you describe the keyboard interaction then? OSDev article did not give much understanding, i can rewrite it from the ground up and share with the internet. – Валентин Попов May 05 '19 at 11:25
  • @ВалентинПопов: For keyboard (and mouse, touchscreen, etc); start by assuming that keyboard driver uses IRQs (and never polls) and sends "events" via. some kind of IPC/inter-process communication (e.g. pipes or messages), where the IPC interacts with the scheduler (such that a task can block waiting for any event and the scheduler will wake it up and give it CPU time when an event arrives from anywhere). – Brendan May 05 '19 at 12:36
  • I agree with Brendan. I did write some specific code in this SO answer for an unrelated question (in 16-bit real mode) for a single tasking OS (without a scheduler) that uses interrupts to get incoming scancodes, places them in a keyboard buffer (not unlike DOS) and some main code that queries the keyboard buffer to see if a scancode is present; translates (the example is partial translation) it to ASCII; writes that to the display. https://stackoverflow.com/a/51565739/3857942 . It could be adapted for your purposes. – Michael Petch May 05 '19 at 14:39
  • Very thankful for all of your responses! Will check this answer! – Валентин Попов May 05 '19 at 14:44

0 Answers0