after i finish running the program using mob's 'in' command on my borland asm, i got all those 'leftovers' from keys that i pressed.
I get something like 'skjhhhasssjjaldnf' on the command line in my compiler. why is it so ?
and why is that supposed to be dangerous ?
how is IN different from lets say int16,ah=00 or int21,ah=01
i dont get it.... for me, they all do the same thing - get a character input from the keyboard, but to you guys it seems like a hell of a difference

please explain
Posted on 2002-04-27 08:01:19 by flipmode
The leftovers are there because BIOS's IRQ1 trapped them and stored them in the keyboard buffer. In your input loop, you may need to do a 'clear buffer' routine. The fastest is to access the buffer pointers and make them equal. Otherwise use BIOS's own clear keyboard buffer routine.

Because only Int09h or IRQ1 are 'supposed' to do keyboard hardware access. Nothing, just a mind-set. Probably not deadly. It's just not the 'right' thing to do since IRQ1 is supposed to talk to the keyboard when the keyboard is ready, and store it somewhere else. Possibly, if you do straight polling instead of waiting for an interrupt, you might be talking to a device which isn't ready yet. For the keyboard it's not dangerous, since it's always prepared to give you SOMETHING.

Or rather, it's just something I've never done, never had experience with, so I'm thinking it's dangerous. Maybe it isn't. Probably isn't. Just paranoia.
Posted on 2002-04-28 19:46:33 by AmkG
ok, amgk i think it's no problem to access the keyb-port
directly... sure you can do it with the int9 but it's nearly
the same if you program 60h and 61h correctly...

flipmode, just check this reference
Posted on 2002-04-29 03:22:59 by mob
what command shall i use for fastest response ?
im scanning for a key inside a loop, so what is recommended ?
how do i clean those leftovers ? if you have already noticed i really have absolutely no idea what the buffer is and whats irq1 and how to handle anything here...
if you could spare me a few hours of research and tell me how exactly to make those leftovers go away i would be nothing but thankful.
Posted on 2002-04-29 09:31:44 by flipmode
i think these "leftovers" are trapped because
you forget to clear interrupt access... try to set
a "CLI" instruction *before* the "in" command
so that there's no int trapping anymore... you
can enable interupts with "STI" again when
you need them... thats just a guess because
it's years ago since i wrote my last dos prog...
Posted on 2002-04-29 09:55:15 by mob
the cli and sti actually do disable and enable interrupt, i think, but the leftovers are still there when i get back to the asm window.
any other suggestions ?

Posted on 2002-04-29 11:39:54 by flipmode
thats very strange... maybe you can try to delete the
keyboard buffer after you're finished... it was like:
huh? pascalref says [0000H:04c1H] = [0000H:041AH]
and some asm ref says 40:1a = 40:1c mhh?? so just
try out both, start with the suggestion for asm lang ;)

push 040H
pop es
mov di, 01AH
mov ax, es:[ di ]
mov es:[ di + 2 ], ax

...and everything should be ok.
i found another way, try also mov ax,0c00H; int 21H
(but don't forget to enable your interrupts then... :) )
Posted on 2002-04-29 11:59:59 by mob
Okay, I FINALLY figured out why my spider-sense kept telling me it was dangerous, it has to do with the fact that on SLOW systems, you might be taking a lot of time in the processing of the input, such that some of the keyboard input gets lost. So on SLOW systems, it might be possible that the user types three keys very fast, so that your program is still responding to the first key, the second gets in, then the third, the next time it reaches 'in 60h' it only sees the third key, and not the second which is lost FOREVER. If you used IRQ's, however, while processing the first key, you get informed of the second and third keys (which you would then put in a buffer), then continue processing, then you look in the buffer and see the second and third keys still there. Of course that is a SLOW system, something like 16 MHz or less using an ISA video card running at 8MHz or less. Not likely those systems are still being used now, ne?

Here's how to clear the keyboard buffer:
mov word ptr es:[41ch],1eh
mov word ptr es:[41ah],1eh

This assumes es =0.

If you use es=40h
mov word ptr es:[1ch],1eh
mov word ptr es:[1ah],1eh

NOTE! You must include this in the LOOP, not AFTER the program! Otherwise the buffer *might* overflow, which causes the computer to bleep at the user... not very friendly.
Posted on 2002-04-29 19:28:26 by AmkG
For fast response, I would suggest a jump table... 'Course its going to get real big considering the large number of codes....
Posted on 2002-04-29 19:30:29 by AmkG
1AH = current char in buffer
1CH = last char in buffer...

the buffer is considered as 'clear' if the current
char = last char... stated in the keyboard manual.

2nd thing... there's actually no
'danger' if you're using direct port access, the
interupt method does this too... the only thing
that should be different is the syncronity of interupts.
you might think That there's only port 60h, thats
wrong, there's a load of funktionality like button-
hit-rate, speed, blah blah blah... in dos times almost
every gfx asm programm (demo's and such) used
port 60h so i don't see where's your problem with
this... i mean sure you can talk your mouth dry but
c'mon, if you want to *help* then give flipmode an
example how to create int9 tsr's if you still think
that your method is better for a simple piano prog.
Posted on 2002-04-30 03:28:31 by mob
*ANCIENT* Code for a IRQ1 handler, last touched around 96-97.

; get key pressed and adjust
in al, 60h ; get key into scancode
mov ah, al ; store in keycode
and ah, 7fh ; strip high bit off keycode

; set ES:DI => keytable[keycode]
mov bx, seg keytable
mov es, bx
mov di, offset keytable ; get offset of keytable

xor bh, bh
mov bl, ah ; adjust DI so we get to the
add di, bx
dec di ; right entry in the table.

; figure if we're gonna set key on/off.
and al, 80h
shr al, 7
xor al, 1
mov es:[di], al

; reset keyboard, get ready for next key
in al, 61h
mov ah, al
or al, 80h
out 61h, al
mov al, ah
out 61h, al

; send "end of interrupt" hardware signal to the CPU
mov al, 020h
out 020h, al

You should "probably" preserve a few registers ;).
Posted on 2002-04-30 04:23:37 by f0dder
with your help, i managed to finnaly fix my stupid problems about the keys input...
now there is only one more thing :) lol !
since i have to hand over this work in 2 days (i managed to post pone it, luckily, very luckily) i got this one more problem to fix -

all the keys, produce the same sound !
now, i know how this speaker activation works, and if someone here knows it - i would be happy to get some explanation about it, because no matter what experiments i do with it, each key sounds exactly the same.
the thing is, the program creates a square wave in volts (from 1 binary to 0 binary and back to 1 again) and the frequency of that wave determines the height of the sound.
now if i change the delay between the 'putting of a 1' and the 'putting of 0' it would change the frequency right ?
anyway, once a certain key is pressed, a certain delay value which represents the frequency, is put into bx, which afterwards goes to cx in the sound procedure itself (appears in code below).
here is the piece of code for the sound - anyone can help ?
if you noticed, the change is in the second least important bit, that is the one that goes 0 to 1 and back all the time.

SOUND proc ;start procedure SOUND
mov delayer,100h ;set length of sound
sound2: mov al,4eh ;store 4e in al (1001110 in binary)
out 61h,al ;move that value to adress 61h?
mov cx,bx ;sound frequency from bx to cx
wait1: loop wait1 ;wait an amount of time
mov al,04ch ;store 4c in al (1001100 in binary) out 61h,al ;move that value to adress 61h
mov cx,1000h ;move a delay value to cx
wait2: loop wait2 ;wait a fixed amount of time
dec delayer ;decrease the length of sound
jnz sound2 ;if not reached 0, jump to begin
ret ;return to main program
SOUND endp ;end procedure SOUND
Posted on 2002-05-03 06:59:45 by flipmode