baby steps #5 - key handler
baby steps #5 - key handler
This code is meant to show how the hardware interrupt generated when you press a key can be handled by replacing the seg:offset specified in the IVT (interrupt vector table). This normally points to a BIOS routine. To find the entry in the IVT, multiply the interrupt number by 4 (which is the size of each entry).
This key handler just displays the scan code without conversion to ASCII, buffering, or handling extended keys. The reason for doing this is to not muddle up the basic idea, which is to provide input, as well as output, in its most simple form.
I will not go into the hows and whys of reading the ports involved in a key press. Suffice it to say that you are communicating with actual chips (or parts of chips), not some software intermediary. I personally feel it is good to remember that, no matter what level of abstraction you work at, you are ultimately telling hardware what to do.
I will point out the turning the keyboard on/off through port 0x61 is given in its complete form, some of which might not be needed, depending on the system.
;==========================================
; nasmw boot.asm -f bin -o boot.bin
; partcopy boot.bin 0 200 -f0
[ORG 0x7c00]??????; add to offsets
???jmp start
???
???%include "print.inc"
start:???xor ax, ax???; make it zero
???mov ds, ax???; DS=0
???mov ss, ax???; stack starts at 0
???mov sp, 0x9c00???; 200h past code start
???
???mov ax, 0xb800???; text video memory
???mov es, ax
???
???cli??????;no interruptions
???mov bx, 0x09???;hardware interrupt #
???shl bx, 2???;multiply by 4
???xor ax, ax
???mov gs, ax???;start of memory
???mov [gs:bx], word keyhandler
???mov [gs:bx+2], ds ; segment
???sti
?????????
???jmp $??????; loop forever???
???
keyhandler:
???in al, 0x60???; get key data
???mov bl, al???; save it
???mov byte [port60], al
???
???in al, 0x61???; keybrd control
???mov ah, al
???or al, 0x80???; disable bit 7
???out 0x61, al???; send it back
???xchg ah, al???; get original
???out 0x61, al???; send that back
???
???mov al, 0x20???; End of Interrupt
???out 0x20, al???;
??????
???and bl, 0x80???; key released
???jnz done???; don't repeat
???
???mov ax, [port60]
???mov word [reg16], ax
???call printreg16
???
done:
???iret
port60???dw 0
???
???times 510-($-$$) db 0 ; fill sector w/ 0's
???dw 0xAA55 ; req'd by some BIOSes
;==========================================
*** hardware fun
http://chip.ms.mff.cuni.cz/~pcguts/
*** Intel's Summer Reading List
http://developer.intel.com/vtune/cbts/refman.htm
*** John Fine links to hardware programming
http://www.geocities.com/SiliconValley/ ... evice.html
This key handler just displays the scan code without conversion to ASCII, buffering, or handling extended keys. The reason for doing this is to not muddle up the basic idea, which is to provide input, as well as output, in its most simple form.
I will not go into the hows and whys of reading the ports involved in a key press. Suffice it to say that you are communicating with actual chips (or parts of chips), not some software intermediary. I personally feel it is good to remember that, no matter what level of abstraction you work at, you are ultimately telling hardware what to do.
I will point out the turning the keyboard on/off through port 0x61 is given in its complete form, some of which might not be needed, depending on the system.
;==========================================
; nasmw boot.asm -f bin -o boot.bin
; partcopy boot.bin 0 200 -f0
[ORG 0x7c00]??????; add to offsets
???jmp start
???
???%include "print.inc"
start:???xor ax, ax???; make it zero
???mov ds, ax???; DS=0
???mov ss, ax???; stack starts at 0
???mov sp, 0x9c00???; 200h past code start
???
???mov ax, 0xb800???; text video memory
???mov es, ax
???
???cli??????;no interruptions
???mov bx, 0x09???;hardware interrupt #
???shl bx, 2???;multiply by 4
???xor ax, ax
???mov gs, ax???;start of memory
???mov [gs:bx], word keyhandler
???mov [gs:bx+2], ds ; segment
???sti
?????????
???jmp $??????; loop forever???
???
keyhandler:
???in al, 0x60???; get key data
???mov bl, al???; save it
???mov byte [port60], al
???
???in al, 0x61???; keybrd control
???mov ah, al
???or al, 0x80???; disable bit 7
???out 0x61, al???; send it back
???xchg ah, al???; get original
???out 0x61, al???; send that back
???
???mov al, 0x20???; End of Interrupt
???out 0x20, al???;
??????
???and bl, 0x80???; key released
???jnz done???; don't repeat
???
???mov ax, [port60]
???mov word [reg16], ax
???call printreg16
???
done:
???iret
port60???dw 0
???
???times 510-($-$$) db 0 ; fill sector w/ 0's
???dw 0xAA55 ; req'd by some BIOSes
;==========================================
*** hardware fun
http://chip.ms.mff.cuni.cz/~pcguts/
*** Intel's Summer Reading List
http://developer.intel.com/vtune/cbts/refman.htm
*** John Fine links to hardware programming
http://www.geocities.com/SiliconValley/ ... evice.html
Re:baby steps #5 - key handler
since most people work in pmode on x86, why bother with revectoring the keyboard IRQ in real mode? int 16h works fine for keyboard routines in real mode. ??
-- Stu --
Re:baby steps #5 - key handler
He did say baby steps... next keyboard step will be the IDT w/ the interrupt "handler" code
BTW: As I have been wondering about your (and most people here) "NASM -f bin filename" usage, I never have used the "-f bin" option for flat assembly. NASM uses the flat binary (-f bin) format by defaut, so you are using a redundant command.
BTW: As I have been wondering about your (and most people here) "NASM -f bin filename" usage, I never have used the "-f bin" option for flat assembly. NASM uses the flat binary (-f bin) format by defaut, so you are using a redundant command.
Re:baby steps #5 - key handler
crazybuddha: it's good of you to post this series of tutorials, but I don't understand why you're writing all of this in 16-bit real-mode assembly and putting it on the boot sector of a disk.
I could understand why you'd write 16-bit real-mode assembly as a DOS program, because it would demonstrate things like accessing the hardware which are the same under both real and protected modes. And I could understand why you'd do tutorials on writing boot sector code (although IMO writing your own boot sector is one of the least useful parts of OS development, maybe to the extent that it isn't OS development at all). But I'm not sure what you're getting at in the end.
I could understand why you'd write 16-bit real-mode assembly as a DOS program, because it would demonstrate things like accessing the hardware which are the same under both real and protected modes. And I could understand why you'd do tutorials on writing boot sector code (although IMO writing your own boot sector is one of the least useful parts of OS development, maybe to the extent that it isn't OS development at all). But I'm not sure what you're getting at in the end.
Re:baby steps #5 - key handler
I suppose I'm assuming that people who haven't gotten very far down their own development path will understand. The underlying premise is (sort of) to avoid other people's code. This includes not having to blindly copy other people's (as yet) incomrehensible code as well as use the BIOS routines or working out of an existing OS. The sequence is meant to highlight fundamental aspects of controlling hardware and, soon, to expose common assumptions about how computers operate and are used.
What am I getting at in the end? The target audience for these "meditations" (tutuorial sounds a little too organized and polished) is budding hobby system developers who don't know what they don't know. If anyone gets anything out of it, great. If they correct or augment, even better. If they question it, awesome.
What am I getting at in the end? The target audience for these "meditations" (tutuorial sounds a little too organized and polished) is budding hobby system developers who don't know what they don't know. If anyone gets anything out of it, great. If they correct or augment, even better. If they question it, awesome.
Re:baby steps #5 - key handler
I agree, it is like learning how to program an OS in C... they tell you that "this does this" and "that does that" but they don't explain how or why. That is my greatest anger with those who promote strictly C code because it is fast or efficient, you are robbing a persons' ability to understand electronics and the true architecture by doing so, which in the end makes worse programmers. CrazyBuddha is correct in giving these initial examples in assembly so people can understand how things work and why they do, not just to know that they do because someone else says so.
Re:baby steps #5 - key handler
After I posted the 'baby steps #7 - big real mode', I thought about this some more. Although I certainly see your point, it occured to me that you can do quite a lot in real mode and the BIOS key handler is inadequate for any real user input handling. Multiple keys, buffer overflows, some extended keys, detecting releases are issues that have to dealt with in a custom handler.df wrote: since most people work in pmode on x86, why bother with revectoring the keyboard IRQ in real mode? int 16h works fine for keyboard routines in real mode. ??
Re:baby steps #5 - key handler
but real mode only exists to switch into pmode. so you dont need to do anything fancy at all in real mode as far as keyboard handlers go
-- Stu --
Re:baby steps #5 - key handler
You're right in some ways. Real mode does exist to switch to Protected Mode but Real mode is maintained for compatibility reasons with older programs. Also, some people might not need PMODE for their OS. Real mode is a great starting point for OSDEVER's too.
Re:baby steps #5 - key handler
Since the 80386, Intel have stated in their manual that real mode exists only for POST and bootstrap, and that the natural mode of their processors is protected mode. All optimisations from the 386 onwards have been to make protected mode faster.