flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
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.
|
|||
![]() |
|
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" |
|||
![]() |
|
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. |
|||
![]() |
|
newport 25 Oct 2014, 22:39
it's making a little more sense.. thanks!
|
|||
![]() |
|
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. |
|||
![]() |
|
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.
|
|||
![]() |
|
smiddy 26 Oct 2014, 13:15
No sweat...let me know if you need anything else. Happy to help.
|
|||
![]() |
|
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! |
|||
![]() |
|
smiddy 31 Oct 2014, 03:29
I just recalled seeing this too: https://code.google.com/p/ostin/source/browse/kernel/hid/keyboard.asm?r=e8e17c71d6342b9e26d1dde9e24f637f281fe327
Smiddy |
|||
![]() |
|
newport 01 Nov 2014, 15:08
cool.. thanks
|
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.
Website powered by rwasa.