flat assembler
Message board for the users of flat assembler.

Index > OS Construction > keymap correlation to scan codes..

Author
Thread Post new topic Reply to topic
newport



Joined: 08 Jun 2012
Posts: 86
Location: Kentucky, USA
newport 25 Oct 2014, 18:20
I've been away for a while and getting back into the swing of things so to speak.. anyways, the trouble i've having now, is the keymap i'm using below (which by the way... is the only one i've found that works moderately decent), doesn't display every character correctly when typed. I've searched high and low trying to find an answer as to why the keymap doesn't work as intended..
any help in understanding how this works would be greatly appreciated.

I'm using a standard u.s. keyboard layout - such as can be seen in the image... Thanks!
Code:
basic_keymap db  0 , 27,'1','2','3','4','5','6','7','8','9','0','-','=', 8 , 9
db 'q','w','e','r','t','y','u','i','o','p','[',']', 13, 0 ,'a','s'
db 'd','f','g','h','j','k','l',';',"'",'`','\\','z','x','c','v','b'
db 'n','m',',','.','/', 0 ,'*', 0 ,' ', 0 , 0 , 0 , 0 , 0 , 0 , 0
db  0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
db  0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
db  0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
db  0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0  
    
Image

_________________
It's the desire to learn that leads to success...

http://www.webicomp.com
Post 25 Oct 2014, 18:20
View user's profile Send private message Visit poster's website Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 25 Oct 2014, 19:42
The decoding of keys depends on which mode the keyboard is using. Without checking/setting this there's no way to certain what you're receiving. Assuming this is correct, the '\\' should be '\' to fix 'z' onwards but as you haven't said which key don't work I don't know if that is enough to fix the problem.
Post 25 Oct 2014, 19:42
View user's profile Send private message Reply with quote
newport



Joined: 08 Jun 2012
Posts: 86
Location: Kentucky, USA
newport 25 Oct 2014, 20:30
Thanks for the reply.. changing the '\\' to '\' made it worse.. lol..

i'll include the file i'm using to display the characters if that will help you to see what i'm doing.. it's probably not the correct way but for now i just want to be able to type on the screen...

basic_commands.asm
Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;       32-bit kernel routines
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;    VGA - bits 15-12 background color
;          bits 11-8 foreground color
;          bits 7-0 character
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;          0 Black
;          1 Blue
;          2 Green
;          3 Cyan
;          4 Red
;          5 Magenta
;          6 Brown
;          7 Light Grey
;          8 Dark Grey
;          9 Light Blue
;          10 Light Green
;          11 LIght Cyan
;          12 Light Red
;          13 Light Magenta
;          14 Light Brown
;          15 White
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;       index = (y_value * width_of_screen) + x_value; {how to access particular index in memory}
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



use32

;variables
OrigVidmem equ 0xB8000
CharAttr equ 6h;0Fh
Cols equ 80  ;0-79
Rows equ 25  ;0-24
ScreenX db 0
ScreenY db 0
UpdatedVM dd 0
Placeholder equ 0
;Routines
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Initialize video buffer
;
InitVid:
        push eax
        xor eax, eax
        mov edi, eax
        mov edi, OrigVidmem
        mov dword[UpdatedVM], OrigVidmem
        pop eax
        retd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Update current location in Video Buffer
;
updVidBuf:
         mov dword[UpdatedVM], edi
         retd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Move Cursor
MoveCursor:
;               0xE     Cursor Location High (bh)
;               OxF     Cursor Location Low  (bl)
;               ;;;;;;;;;;;;;;;;;;;;MOVING LOW BYTE OF CURSOR ADDRESS REQUIRES THE FOLLOWING;;;;;;;;;
;               1. Put Cursor Low(0x0F) into the index register(0x03D4)
;               2. Put Low byte address(bl) into the data register(0x03D5)
;               3. NOTE: index and data registers must be assigned to DX
;               4. NOTE: cursor low(0xF) and address(bl) must be moved to DX after being added to AL
;               ;;;;;;;;;;;;;;;;;;;;MOVING HIGH BYTE OF CURSOR ADDRESS REQUIRES THE FOLLOWING;;;;;;;;;
;               1. Put Cursor High(0x0E) into the index register(0x03D4)
;               2. Put High byte address(bh) into the data register(0x03D5)
;               3. NOTE: index and data registers must be assigned to DX
;               4. NOTE: cursor High(0xE) and address(bh) must be moved to DX after being added to AL
;               ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;               NOTES: Calculations must be done prior to the above to determine BL and BH
;
;               CALCULATION of COORDINATES - ie: Current Video Memory Position
                pusha
                xor eax, eax

                mov bh, byte[ScreenY]
                mov bl, byte[ScreenX]

                mov eax, [UpdatedVM]
                mov ebx, OrigVidmem
                sub eax, ebx
                mov ecx, 2
                div ecx
                add eax, edx
                mov ebx, eax
;               HANDLE CURSOR LOW POSITIONING
                ;xor eax, eax
                mov al, 0x0F
                mov dx, 0x03D4
                out dx, al
                mov al, bl
                mov dx, 0x03D5
                out dx, al
;               HANDLE CURSOR HIGH POSITIONING
                xor eax, eax
                mov al, 0x0E
                mov dx, 0x03D4
                out dx, al
                mov al, bh
                mov dx, 0x03D5
                out dx, al
                popa
                retd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;PlaceChar0
;       -this routine actually puts the character on the screen
PlaceChar:
                mov byte[es:edi], al
                inc edi
                mov byte[es:edi], CharAttr
                inc edi

                retd

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Print Character
;      -prints character to screen and calculates cursorX and Y positions
PrintChar:
        cmp al, 0xD
        je .genNewLine

        mov bl, byte[ScreenX]
        cmp bl, 65
        jge .wordWrap

        ; actual print char to screen routine goes here
        call PlaceChar

        jmp .contPC

        .genNewLine:
              mov dword eax, [UpdatedVM]
              mov ebx, OrigVidmem
              sub eax, ebx
              mov ecx, 160
              div ecx
              inc eax
              mov ecx, 160
              mul ecx
              mov ebx, OrigVidmem
              add eax, ebx
              mov dword [UpdatedVM], eax
              mov dword edi, [UpdatedVM]
              inc byte[ScreenY]
              mov byte[ScreenX], 0

              jmp .contPC

        .wordWrap:
              test al, 0x20
              jne .endWW

              mov cl, 80
              sub cl, byte[ScreenX]
              inc cl
              shl cl, 1
              mov ebx, dword[UpdatedVM]
              add ebx, ecx
              mov edi, ebx
              mov byte[ScreenX], 0
              call updVidBuf

                .endWW:
                      call PlaceChar

                      jmp .contPC

        .contPC:
                inc byte[ScreenX]
                call updVidBuf
                retd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Print String
;      -prints a string to the screen utilizing PrintChar & updates Vidmem
PrintString:
        mov edi, dword[UpdatedVM]
        pusha
        xor eax, eax
        mov ebx, eax
        mov ecx, eax
        jmp @f
        @@:
                lodsb
                or al, al
                jz .stringFinished
                call PrintChar
                jmp @b
                jmp .stringFinished

        .stringFinished:
                call MoveCursor
                popa
                retd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Create a Newline Break
;       -used to skip a row when printing text to the screen
nlBreak:
        ;routine not coded yet...
        retd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Tab Space
;    -used to add a TAB(5 spaces) to the beginning of a string on a new row
tab:
        pusha
        xor eax, eax
        mov al, 10
        mov ecx, dword[UpdatedVM]
        add eax, ecx
        mov edi, eax
        call updVidBuf
        popa
        retd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;
stop_floppy:
        push  edx
        push  eax
        mov   dx,0x3f2
        mov   al,0
        out   dx,al
        pop   eax
        pop   edx
        retd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
KeyboardInput:
    in al, 64h
    test al, 01b
    jz KeyboardInput
    in al, 60h

    xor bx, bx
    mov bl, al

    mov al, [cs:bx + basic_keymap]
    call PrintChar

    call KeyboardInput

    retd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;Clear Screen Routine                                                                         ;
;;;;;      * Clears Entire Text Mode Screen (all 4000 bytes) from 0xB8000 - 0xB8FA0               ;
;;;;;      * Resets edi to 0xB8000                                                                ;
;;;;;      * Sets the cursor position to (0, 0) :: x=0, y=0 :: memory location is 0xB8000         ;
;;;;;      *                                                                                      ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;
;;;;;;;;;

        clearScreen:
         ; not programmed yet...
        retd

;;;;; ----------------------------------END OF CLEAR SCREEN ROUTINE -------------------------;;;;;      
    


..then in my kernel section...

kernel.asm
Code:
        ;org 9200h
        theKERNEL:
                ;xor ax, ax
                ;mov es, ax
                ;mov     ax, 0x8000              ; stack begins at 0x9000-0xffff
                ;mov     ss, ax
                ;mov     sp, 0xffff

                mov esi, m6     ;m6: db "Kernel has been initialized!", 13, 0 
                call PrintString    ;works perfectly everytime...

                call KeyboardInput    ;allows me to type on screen (contains errors)
                jmp $    
    

..and the only characters that display correctly are.. "2, 3, 7, 8, =, r, t, y, u, i, o, p, [, ], a, s, h, j, k, l, SemiColon, EnterKey, Spacebar"

_________________
It's the desire to learn that leads to success...

http://www.webicomp.com
Post 25 Oct 2014, 20:30
View user's profile Send private message Visit poster's website Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 25 Oct 2014, 21:41
For safety, inside KeyboardInput changing "call KeyboardInput" to "jmp KeyboardInput" will prevent the stack trashing memory.
My own code uses "test al,0x02" to check the input buffer as opposed to the output buffer indicated by your "test al,0x01" but to be honest I don't which is right since I wrote that line about a decade ago.

Looking at the behaviour of KeyboardInput, it's not correctly decoding the scancodes. This is more complicated than just using the LUT directly. The scancodes are multi-byte and have to handle 1~8 bytes per key action (here "action" is key down when pressed, which is repeated if held, then key up when released). Using the map image you posted and assuming you're in mode 2, if I pressed key A the bytes received would be 1C for down and 9C up. Here bit 7 denotes the key up state (masking it off gets you 1C). Currently you'd see 'A' (down) then a trash byte (up).

To complicate things more, the special keys have additional prefix bytes (0xE0, 0xE1, 0xF0) which simply tell you this is not a character in your normal map. If I pressed right CTRL, the bytes could be E0,14;E0,84. Again, you'd currently see a trash byte, 'R' and two trash bytes when nothing needs to be displayed.

Hopefully what I've just said makes some kind of sense...unfortunately my code is for keyboards on the other side of the Atlantic with a lovely "todo" for other layouts.
Post 25 Oct 2014, 21:41
View user's profile Send private message Reply with quote
newport



Joined: 08 Jun 2012
Posts: 86
Location: Kentucky, USA
newport 25 Oct 2014, 22:39
it's making a little more sense.. thanks!
Post 25 Oct 2014, 22:39
View user's profile Send private message Visit poster's website Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 26 Oct 2014, 02:31
Hi, I wrote mine a while back, and I certainly leveraged it from somewhere else, but I obviously didn't put the reference in here. Although, here's my code for reference, which does work:

Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; KEYBOARD.ASM - Contains the driver code for the keyboard, which is internal
;;                to the kernel at this time. Takes control of the keyboard
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Header - This is the header used by smiddyOS device drivers.
;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Data elements
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

KeyboardInitializationMessage   db 'smiddyOS Keyboard Initializing...',0
KeyboardInstalledMessage                db 'Done!',13,10,0

     ;--------------------------------------------------------------------------------;
     ;   _______________________      Keyboard buffer system                          ;
     ;   | | | | | | | | | | | |                                                      ;
     ;   +---------------------+                                                      ;
     ;      |         +----------> KeyboardHead, here is where we put new scan-codes. ;
     ;      +--------------------> KeyboardTail, where we last read a key. this means ;
     ;                     that we have 4 new scan-codes to read before we catch up.  ;
     ;--------------------------------------------------------------------------------;
          KeyboardBuffer        db   '                                '
                                                db   '                                ',0       ; Ended with a 0 terminator just in case we DEBUG
          KeyboardHead          db   1                ; head must be +1 from tail to start
          KeyboardTail          db   0

     ;-------------------------------------------------------------------------;
     ; _________________        Flag byte:                                     ;
     ; |1|1|0|0|0|1|1|1|                                                       ;
     ; +---------------+                     1 = True   0 = False              ;
     ;  | | | | | | | +--->  shift key                                         ;
     ;  | | | | | | +----->  ctrl key                                          ;
     ;  | | | | | +------->  alt key                                           ;
     ;  | | | | +--------->  reserved bit                                      ;
     ;  | | | +----------->  reserved bit                                      ;
     ;  | | +------------->  reserved bit                                      ;
     ;  | +--------------->  ctrl + alt + del                                  ;
     ;  +----------------->  key released                                      ;
     ;-------------------------------------------------------------------------;
          KeyboardFlags         db   0                ; flag byte

     ;-------------------------------------------------------------------------;
     ; _________________        LED status byte:                               ;
     ; |0|0|0|0|0|1|1|1|                                                       ;
     ; +---------------+                     1 = True   0 = False              ;
     ;            | | +--->  scroll lock                                       ;
     ;            | +----->  num lock                                          ;
     ;            +------->  caps lock                                         ;
     ;-------------------------------------------------------------------------;
          KeyboardStatus        db   0                ; LED statusbyte


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; InitializeKeyboard - Initializes the keyboard based on BIOS information.
;;
;;      417h    byte    Keyboard flag byte 0 (see KB FLAGS)
;;              |7|6|5|4|3|2|1|0| keyboard flag byte 0
;;               | | | | | | | `--- right shift key depressed
;;               | | | | | | `---- left shift key depressed
;;               | | | | | `----- CTRL key depressed
;;               | | | | `------ ALT key depressed
;;               | | | `------- scroll-lock is active
;;               | | `-------- num-lock is active
;;               | `--------- caps-lock is active
;;               `---------- insert is active
;;      418h    byte    Keyboard flag byte 1 (see KB FLAGS)
;;              |7|6|5|4|3|2|1|0| keyboard flag byte
;;               | | | | | | | `--- left CTRL key depressed
;;               | | | | | | `---- left ALT key depressed
;;               | | | | | `----- system key depressed and held
;;               | | | | `------ suspend key has been toggled
;;               | | | `------- scroll lock key is depressed
;;               | | `-------- num-lock key is depressed
;;               | `--------- caps-lock key is depressed
;;               `---------- insert key is depressed
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

InitializeKeyboard:

        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        ;; ToDo:
        ;;      - Need to check for type of keyboard with command F2h (not sure how)
        ;;      - Update variables from BIOS to our variables
        ;;      - Make an Unitialize for times when we retreat to DOS (update BIOS)
        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

        mov esi,KeyboardInitializationMessage   ; Load initialize message
        call PrintString32                                              ; Print initialize message

        cli                                                                             ; Disable interrupts
        call DisableAllIRQs                                             ; Disable all IRQs

        mov esi,KeyboardISR                                             ; Load keyboard ISR
        mov eax,1                                                               ; Place IRQ number into EAX
        call AddISRToIDT                                                ; Add the ISR for the IRQ
        sti                                                                             ; Turn interrupts back on

        mov eax,1                                                               ; Place IRQ number into EAX
        call EnableAnIRQ                                                ; Reprogram PIC for IRQ 1

        mov esi,KeyboardInstalledMessage                ; Load installed message
        call PrintString32                                              ; Print installed message

        ret                                                                             ; Return to calling procedure

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; KeyboardISR - This is the interrupt service routine for the keyboard. It
;;               updates the main screen during CLI operation mode.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

KeyboardISR:

        pusha                                   ; Save all general registers
        push gs                                 ; Save data segment registers
        push fs
        push ds
        push es

        mov al,0ADh                             ; Place disable keybaord command into AL
        call KeyboardCommand
        cli
        xor eax,eax                             ; Zero out EAX
        in al,60h                               ; Get scancode from keyboard
        sti

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; Check to see if key was released
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

        test al,80h                             ; Was this a release (break)?
        jz .KeyDown                             ; No, key pressed, move there (This also filters E0 and E1 and F?

        ;; If ALT and not released, don't do a release until it is an ALT release
        and byte [KeyboardFlags],01111111b      ; Yes a release, update flags

        cmp al,42+128                   ; Left shift key up?
        je .ShiftUp                             ; Yes, go there

        cmp al,54+128                   ; Right shift key up?
        je .ShiftUp                             ; Yes, go there

        cmp al,29+128                   ; Control key up?
        je .ControlUp                   ; Yes, go there

        cmp al,83+128                   ; Delete key up?
        je .DeleteUp                    ; Yes, go there

        cmp al,56+128                   ; Alternate key up?
        je .AlternateUp                 ; Yes, go there
        jmp .End                                ; Otherwise checking done

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        ;; It was released then
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

.ShiftUp:

        and byte [KeyboardFlags],11111110b              ; Update shift keyboard flag
        jmp .End

.DeleteUp:

        jmp .ControlAlternateDeleteOff                  ; Go to turn off flag

.ControlUp:

        and byte [KeyboardFlags],11111101b              ; Update control keyboard flag
        jmp .ControlAlternateDeleteOff                  ; Go to turn off flag

.AlternateUp:

        and byte [KeyboardFlags],11111011b              ; Update alternate keyboard flag
        jmp .ControlAlternateDeleteOff                  ; Go to turn off flag

.ControlAlternateDeleteOff:

        test byte [KeyboardFlags],01000000b             ; Is flag already on?
        jz .ControlAlternateDeleteIsOff                 ; No, then no need to update flag
        and byte [KeyboardFlags],10111111b              ; Yes, then turn flag off

.ControlAlternateDeleteIsOff:

        jmp .End                                                                ; Check done

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        ;; A key was pressed, check for special keys
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

.KeyDown:

        or byte [KeyboardFlags],10000000b               ; Update keypressed flag
;       mov [WaitKeyPressed],byte 1

.Shift:

        cmp al,42                                                               ; Is the left shift key pressed?
        jnz .CheckRightShift                                    ; No, go to check right shift
        or byte [KeyboardFlags],00000001b               ; Update shift key pressed flag
        jmp .End                                                                ; Check done

.CheckRightShift:

        cmp al,54                                                               ; Is the right shift key pressed?
        jnz .CheckControl                                               ; No, go check control key
        or byte [KeyboardFlags],00000001b               ; Yes, update corresponding flag
        jmp .End                                                                ; Check done

.CheckControl:

        cmp al,29                                                               ; Is the control key pressed?
        jnz .CheckAlternate                                             ; No, move onto check alternate
        or byte [KeyboardFlags],00000010b               ; Yes, update corresponding flag
        jmp .End                                                                ; Check is done

.CheckAlternate:

        cmp al,56                                                               ; Is the alternate key pressed?
        jnz .ControlAlternateDelete                             ; No, move to check control + alternate + delete
        or byte [KeyboardFlags],00000100b               ; Yes, update correpsonding flag
        jmp .End                                                                ; Check done

.ControlAlternateDelete:

        test byte [KeyboardFlags],00000110b             ; Has control + alternate already been pressed
        jz .CheckCapsLock                                               ; No, move to check caps lock
        cmp al,83                                                               ; Yes, is this the delete key?
        jne .CheckCapsLock                                              ; No, move to check caps lock
        or byte [KeyboardFlags],01000000b               ; Yes, update control + alternate + delete flag on.

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        ;; Toggle caps, num and scroll lock
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

.CheckCapsLock:

        cmp al,58                                                               ; Has the caps lock key been pressed?
        jnz .CheckNumLock                                               ; No, move to check num lock
        xor byte [KeyboardStatus],4                             ; Yes, update keyboard status bit
        call UpdateLEDs                                                 ; Go update the LEDs with new information
        jmp .End                                                                ; Check done

.CheckNumLock:

        cmp al,69                                                               ; Has the num lock key been pressed?
        jnz .CheckScrollLock                                    ; No, move onto check scroll lock
        xor byte [KeyboardStatus],2                             ; Yes, update keyboard status bit
        call UpdateLEDs                                                 ; Go update the LEDs with new infromation
        jmp .End                                                                ; Check done

.CheckScrollLock:

        cmp al,70                                                               ; Has scroll lock been pressed?
        jnz .End                                                                ; Nope, then we're done
        xor byte [KeyboardStatus],1                             ; Yupper, update keyboard status bit
        call UpdateLEDs                                                 ; Go update the LEDs with new information
        jmp .End                                                                ; Checking done

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        ;; Put the scancode in the buffer
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

.End:

        push eax                                                                ; Save EAX
        mov edi,KeyboardBuffer                                  ; Load keyboard buffer address into EDI
        movzx eax,[KeyboardHead]                                ; Place current keyboard buffer head in AL
        add edi,eax                                                             ; Update EDI with current location
        pop eax                                                                 ; Restore EAX
        mov [ds:edi],al                                                 ; Update EDI location with AL, increment EDI
        cmp [KeyboardHead],63                                   ; Have we reached the buffer end?
        jne .Increment                                                  ; No, go increment head
        cmp [KeyboardTail],0                                    ; Is the tail at 0?
        je .Error                                                               ; Yes, go to error indication (buffer is full)
        mov [KeyboardHead],0                                    ; Move head to 0
        jmp .Quit                                                               ; Totally finished, so leave

.Increment:

        mov ah,[KeyboardTail]                                   ; Save tail number into AH
        mov al,[KeyboardHead]                                   ; Save head number into AL
        add al,1                                                                ; Add 1 to head number
        cmp ah,al                                                               ; Is head and tail the same?
        je .Error                                                               ; Yes, then go to error indication
        inc [KeyboardHead]                                              ; Increment head
        jmp .Quit                                                               ; Totally complete, leave now

.Error:

        call Boop                                                               ; Not made yet, should go in SPEAKER.ASM
        mov [KeyboardHead],1                                    ; Fix buffer as good (not sure this is wise)
        mov [KeyboardTail],0                                    ; Now head and tail are at their starting points

.Quit:


.FinishUp:

        mov al,20h                                                              ; Load EOI into AL
        out 20h,al                                                              ; Send to first PIC port

        mov al,0AEh                                                             ; Put enable keybaord command into AL
        call KeyboardCommand                                    ; Enter command

        pop es
        pop ds
        pop fs
        pop gs                                                                  ; Restore all data segment registers from entry
        popa                                                                    ; Restore all general registers from entry

        iret                                                                    ; Return control to system

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; UpdateLEDs - Updates the keyboard LEDs with keyboard status bits
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

UpdateLEDs:

        push ax                                                                 ; Save AX

        call KeyboardWait                                               ; Check keyboard buffers
        mov al,0EDh                                                             ; Load AL with command write LEDs
        out 60h,al                                                              ; Send verb to keyboard port
        call KeyboardWait                                               ; Check keyboard buffers
        mov al,[KeyboardStatus]                                 ; Load current status into AL
        out 60h,al                                                              ; Send status to keyboard port
        call KeyboardWait                                               ; Check keyboard buffers

        pop ax                                                                  ; Restore on entry AX

        ret                                                                             ; Return to caller

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; KeyboardWait - Checks to ensure buffer is empty and returns when it is
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

KeyboardWait:

        jmp $+2                                                                 ; Adds a clock tic delay, going to next opcode
        in al,64h                                                               ; Read keyboard status port
        test al,1                                                               ; Is keyboard _blank_?
        jz .OK                                                                  ; No, then go to check if OK
        jmp $+2                                                                 ; Adds a clock tic delay, going to next opcode
        in al,60h                                                               ; Read keyboard port
        jmp KeyboardWait                                                ; Do KeyboardWait again

.OK:

        test al,2                                                               ; Is keyboard _blank_?
        jnz KeyboardWait                                                ; Yes, then do KeyboardWait again

        ret                                                                             ; Return to caller

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; KeyboardCommand - Sends a byte to the keyboard
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

KeyboardCommand:

        push ax
        cli

.SIO:

        in al,64h                                                               ; Status port read
        test al,02h                                                             ; Is input buffer full?
        loopnz .SIO

        pop ax
        out 64h,al                                                              ; Send the command

        sti

        ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; GetCharacter - smiddyOS INT to get a character
;;
;;          OUT: AH = Scan code,      AL = ASCII
;;               BH = Flag byte,      BL = LED byte
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

GetCharacter:

.NoNew:                                                 ; This loops until there is a new character in the buffer

        mov al,[KeyboardHead]           ; Get head pointer
        mov ah,[KeyboardTail]           ; Get tail pointer
        push ax
        sub al,ah                                       ; Check size of buffer
        mov bl,al
        pop ax
        cmp bl,1
        ja .EmptyBuffer
        jmp .NoNew

.EmptyBuffer:

        mov esi,KeyboardBuffer
        movzx ebx,ah
        inc ebx
        mov al,[esi + ebx]                      ; Get what is in the buffer
        inc ah                                          ; Move tail up one
        cmp ah,63
        ja .ZeroTail
        mov [KeyboardTail],ah

.CheckByte:

        test al,10000000b                       ; Is this a break?
        jnz .NoNew                                      ; Yes, then get another one.
        jmp .Done

.ZeroTail:

        mov [KeyboardTail],0
        jmp .CheckByte

.Done:

        movzx ebx,al
        mov ah,al
        test [KeyboardStatus],00000100b
        jnz .Caps
        test [KeyboardFlags],00000001b
        jnz .Shift
        mov al,[KeyboardMap + ebx]
        jmp .End

.Caps:

        test [KeyboardFlags],00000001b
        jnz .CapsAndShift

        mov al,[KeyboardMapCaps + ebx]
        jmp .End

.CapsAndShift:

        mov al,[KeyboardMapCapsShift + ebx]
        jmp .End

.Shift:

        mov al,[KeyboardMapShift + ebx]
        jmp .End

.End:

        mov bl, [KeyboardStatus]
        mov bh, [KeyboardFlags]

        ret

KeyboardMap:
;        0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19
        db       0 , 27,'1','2','3','4','5','6','7','8','9','0','-','=', 8,  9, 'q','w','e','r'
        db      't','y','u','i','o','p','[',']',13 , 0 ,'a','s','d','f','g','h','j','k','l',';'
        db  "'",'`', 0 ,'\','z','x','c','v','b','n','m',',','.','/', 0 , 0 , 0 ,' ', 0 , 0
        db   0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
        db   0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0

KeyboardMapCaps:
        db       0 , 27,'1','2','3','4','5','6','7','8','9','0','-','=', 8,  9, 'Q','W','E','R'
        db      'T','Y','U','I','O','P','[',']',13 , 0 ,'A','S','D','F','G','H','J','K','L',';'
        db  "'",'`', 0 ,'\','Z','X','C','V','B','N','M',',','.','/', 0 , 0 , 0 ,' ', 0 , 0
        db   0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
        db   0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0

KeyboardMapCapsShift:
        db       0 , 27,'!','@','#','$','%','^','&','*','(',')','_','+', 8,  9, 'q','w','e','r'
        db      't','y','u','i','o','p','{','}',13 , 0 ,'a','s','d','f','g','h','j','k','l',':'
        db  "'",'~', 0 ,'|','z','x','c','v','b','n','m','<','>','?', 0 , 0 , 0 ,' ', 0 , 0
        db   0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
        db   0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0

KeyboardMapShift:
        db       0 , 27,'!','@','#','$','%','^','&','*','(',')','_','+', 8,  9, 'Q','W','E','R'
        db      'T','Y','U','I','O','P','{','}',13 , 0 ,'A','S','D','F','G','H','J','K','L',':'
        db  "'",'~', 0 ,'|','Z','X','C','V','B','N','M','<','>','?', 0 , 0 , 0 ,' ', 0 , 0
        db   0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
        db   0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0



WaitKeyPressed db 0

Boop:                                                                   ; Doesn't appear to work, yet

        pusha

        in al,61h                                                       ; Get speaker port contents
        push ax

        mov bx,6818
        call SpeakerCommand
        mov ecx,4b4bh

.Delay3:

        loop .Delay3

        pop ax                                                          ; Restore speaker contents
        out 61h,al

        popa

        ret

SpeakerCommand:

        mov al,10110110b                                        ; Channel 2, write LSB/MSB
        out 43h,al                                                      ; operation mode 3, binary
        mov ax,bx                                                       ; Send counter LSB
        out 42h,al
        mov al,ah                                                       ; Send counter MSB
        out 42h,al
        in al,61h                                                       ; Get 8255 port contents
        or al,00000011b                                         ; Enable speaker and use
        out 61h,al                                                      ; clock channel 2 for input

        ret
    


I caveat that I am revamping my code now, and intend to add my specific keyboard. I have not critically read this site, but skimmed it and it appears to have some useful information: http://www.win.tue.nl/~aeb/linux/kbd/scancodes.html

Once I get to the keyboard portion, I intend to rewrite the above.
Post 26 Oct 2014, 02:31
View user's profile Send private message Reply with quote
newport



Joined: 08 Jun 2012
Posts: 86
Location: Kentucky, USA
newport 26 Oct 2014, 11:01
Thank you very much smiddy. This is exactly the kind of thing I've been trying to find for learning.. Most everything on the web is in C Language. If I were well versed in assembly, then using C would be no problem...lol Finally an assembly keyboard routine I can study. Thanks again.

_________________
It's the desire to learn that leads to success...

http://www.webicomp.com
Post 26 Oct 2014, 11:01
View user's profile Send private message Visit poster's website Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 26 Oct 2014, 13:15
No sweat...let me know if you need anything else. Happy to help.
Post 26 Oct 2014, 13:15
View user's profile Send private message Reply with quote
newport



Joined: 08 Jun 2012
Posts: 86
Location: Kentucky, USA
newport 26 Oct 2014, 18:53
..so I tried using your keymap with my routine...
Code:
KeyboardMap:
;        0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19
        db       0 , 27,'1','2','3','4','5','6','7','8','9','0','-','=', 8,  9, 'q','w','e','r'
        db      't','y','u','i','o','p','[',']',13 , 0 ,'a','s','d','f','g','h','j','k','l',';'
        db  "'",'`', 0 ,'\','z','x','c','v','b','n','m',',','.','/', 0 , 0 , 0 ,' ', 0 , 0
        db   0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
        db   0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 
    

and i was having the same problems.. so I started digging, and it turns out that the order of my include files in stage two of my bootloader were the cause of all the problems. After I relocated and re-organized the order of the include files, i can now type on the screen to perfection. Weird huh? Anyways, now I can start utilizing what i'm learning from your post smiddy and integrate the shift and caps lock, etc.. Thanks!

_________________
It's the desire to learn that leads to success...

http://www.webicomp.com
Post 26 Oct 2014, 18:53
View user's profile Send private message Visit poster's website Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 31 Oct 2014, 03:29
Post 31 Oct 2014, 03:29
View user's profile Send private message Reply with quote
newport



Joined: 08 Jun 2012
Posts: 86
Location: Kentucky, USA
newport 01 Nov 2014, 15:08
cool.. thanks

_________________
It's the desire to learn that leads to success...

http://www.webicomp.com
Post 01 Nov 2014, 15:08
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.