Hi,
ManOfSteel wrote:
The code posted all looks ok to me, so I'd guess that the base of DS is causing trouble, or "int 33" is trashing EDI.
- ds = 10h.
- int 33 (which is the keyboard IRQ) doesn't use edi at all.
Perhaps it's not that EDI is changed - you're using "mov [CmdBuf+di],al". Just try "mov [CmdBuf+edi],al" instead. If CmdBuf is greater than 65535 NASM sometimes truncates it to fit into 16 bits without issuing a warning.
ManOfSteel wrote:
On another note, what happens if the user types 100 characters before pressing enter?
Nothing special. What is it supposed to do?
Currently it'd overwrite anything that follows CmdBuf, including the "db 13,0". It might be a good idea to limit the number of characters stored in the buffer. If the user falls asleep with their head on the 'h' key how much will be trashed before you get an exception?
ManOfSteel wrote:
Oh, i hope that '0x21' is *not* your IRQ1 and that you're not trying to call an IRQ handler from software. That'd lead to ugly results (such as having the handler called twice, interrseting data lost, etc).
Yes, that's what it does. So, if I don't want it to do that, what should I do?
Have a seperate IRQ handler that gets keypresses from the keyboard, processes them and puts them into a buffer. Then use a software interrupt (or the kernel API, or IPC, or something else) to get the next keypress from the buffer.
The problem with what you're doing is that the CPU will automatically execute the IRQ handler, which will change AL (even when your code isn't waiting for a keypress). If your code is waiting for a keypress the IRQ handler will be run twice.
It also makes it impossible for any other IRQ to be handled, so when you start using anything more than just the keyboard (timers, mouse, disk drives, etc) you'll be stuck. In addition it has the same problems as all polling code does - the CPU can't be doing other things while the keyboard is being used.
If you really do want to use polling, test the "output buffer full" bit in IO port 0x64 until there's something in the input buffer, and don't mess with the IRQ at all. In this case your code would become:
Code: Select all
mov edi,CmdBuf
cld
Shell:
int 66 ;keyboard API
cmp al,13
je EnterKeyPressed
;print the keyboard input
cmp edi,CmdBuf+10
jae Shell
stosb
jmp Shell
EnterKeyPressed:
;print 'CmdBuf' to the screen
mov edi,CmdBuf
mov al,90h
mov ecx,10
rep stosb
mov edi,CmdBuf
jmp Shell
section .data
CmdBuf times 10 db 90h
db 13,0
section .text
int66handler:
.wait:
rep nop
in al,0x64
test al,0x01
jne .wait
;Convert scancode into ASCII
iretd
Cheers,
Brendan