* [Qemu-devel] qemu kbd emulation
@ 2006-06-28 8:27 Rafał Cygnarowski
2006-06-28 8:39 ` Oliver Gerlich
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Rafał Cygnarowski @ 2006-06-28 8:27 UTC (permalink / raw)
To: qemu-devel
Hi!
I wanted to correct qemu emulation of keyboard under DOS as
guest OS, so I started with simple pascal program to check
what happen on guest DOS (and DOS) when I press up/down/left/right
keys.
The program was:
-- BEGIN test.pas --
program time; {$M 2048,0,0}
uses crt, dos;
var OldKeyInt : procedure;
procedure NewKeyInt; interrupt;
begin
write(Port[$60]); write(' ')
inline($9c); OldKeyInt;
end;
begin
getintvec($9, addr(OldKeyInt));
setintvec($9, @NewKeyInt);
keep(0);
end.
-- END test.pas --
and it look that qemu does not generate some codes before
pressing and after releasing arrow keys. For example pressing
up key on qemu looks like:
224 72 224 200
while without emulation it looks:
224 42 224 72 224 200 224 170.
It's true only for single keystrokes, but good for the
beginning.
So I tried to patch qemu for this and created following patch:
-- BEGIN sdl.patch --
--- sdl.c.old 2006-05-03 20:32:58.000000000 +0000
+++ sdl.c 2006-06-28 07:26:14.000000000 +0000
@@ -254,14 +254,34 @@
kbd_put_keycode(keycode);
kbd_put_keycode(keycode | 0x80);
return;
+ case 0xc8: /* up */
+ case 0xd0: /* down */
+ case 0xcd: /* right */
+ case 0xcb: /* left */
+ if (ev->type != SDL_KEYUP) {
+ kbd_put_keycode(e0);
+ kbd_put_keycode(2a);
+ }
+ break;
}
-
+
/* now send the key code */
if (keycode & 0x80)
kbd_put_keycode(0xe0);
- if (ev->type == SDL_KEYUP)
- kbd_put_keycode(keycode | 0x80);
- else
+
+ if (ev->type == SDL_KEYUP) {
+ kbd_put_keycode(keycode | 0x80);
+
+ switch(keycode) {
+ case 0xc8: /* up */
+ case 0xd0: /* down */
+ case 0xcd: /* right */
+ case 0xcb: /* left */
+ kbd_put_keycode(0xe0);
+ kbd_put_keycode(0xaa);
+ break;
+ }
+ } else
kbd_put_keycode(keycode & 0x7f);
}
-- END sdl.patch --
Unfortunatelly results of this patch completely suprised me. After this patch
my test program produces results witch are impossible to produce in normal
situation. Example output for UP key was:
224 224 72 88224 224 170.
What's wrong with this patch? What I'm doing wrong?
Regards,
--
Rafał Cygnarowski
rafi@pers.pl
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] qemu kbd emulation
2006-06-28 8:27 [Qemu-devel] qemu kbd emulation Rafał Cygnarowski
@ 2006-06-28 8:39 ` Oliver Gerlich
2006-06-28 12:16 ` Rafał Cygnarowski
2006-06-28 9:39 ` Stuart Brady
2006-06-28 10:07 ` Stuart Brady
2 siblings, 1 reply; 10+ messages in thread
From: Oliver Gerlich @ 2006-06-28 8:39 UTC (permalink / raw)
To: qemu-devel
Rafał Cygnarowski wrote:
> Hi!
>
> I wanted to correct qemu emulation of keyboard under DOS as
> guest OS, so I started with simple pascal program to check
> what happen on guest DOS (and DOS) when I press up/down/left/right
> keys.
>
> The program was:
>
> -- BEGIN test.pas --
> program time; {$M 2048,0,0}
> uses crt, dos;
> var OldKeyInt : procedure;
>
> procedure NewKeyInt; interrupt;
> begin
> write(Port[$60]); write(' ')
> inline($9c); OldKeyInt;
> end;
>
> begin
> getintvec($9, addr(OldKeyInt));
> setintvec($9, @NewKeyInt);
> keep(0);
> end.
> -- END test.pas --
>
> and it look that qemu does not generate some codes before
> pressing and after releasing arrow keys. For example pressing
> up key on qemu looks like:
>
> 224 72 224 200
>
> while without emulation it looks:
>
> 224 42 224 72 224 200 224 170.
>
> It's true only for single keystrokes, but good for the
> beginning.
>
> So I tried to patch qemu for this and created following patch:
>
> -- BEGIN sdl.patch --
[snipped patch]
> -- END sdl.patch --
>
> Unfortunatelly results of this patch completely suprised me. After this patch
> my test program produces results witch are impossible to produce in normal
> situation. Example output for UP key was:
>
> 224 224 72 88224 224 170.
>
> What's wrong with this patch? What I'm doing wrong?
>
> Regards,
What SDL version are you using? I noticed some strange keyboard behavior
with SDL 1.2.9 (Debian package), and this didn't happen when using SDL
1.2.10 (self-built). The problems were things like no Shift-Tab in
Windows, and "showkey" under Linux displaying strange keycodes when
using Shift-Tab.
Regards,
Oliver
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] qemu kbd emulation
2006-06-28 8:39 ` Oliver Gerlich
@ 2006-06-28 12:16 ` Rafał Cygnarowski
2006-06-28 14:28 ` Jim C. Brown
2006-06-28 15:05 ` Stuart Brady
0 siblings, 2 replies; 10+ messages in thread
From: Rafał Cygnarowski @ 2006-06-28 12:16 UTC (permalink / raw)
To: qemu-devel
> What SDL version are you using? I noticed some strange keyboard behavior
> with SDL 1.2.9 (Debian package), and this didn't happen when using SDL
> 1.2.10 (self-built). The problems were things like no Shift-Tab in
> Windows, and "showkey" under Linux displaying strange keycodes when
> using Shift-Tab.
I was using SDL 1.2.9. After upgrade to 1.2.10 (and qemu
recompilation) nothing changed.
I also made same more tests and now I know sth more.
1. ps2_queue
I changed ps2_queue to see if my patch do what I thought
it should do.
-- BEGIN --
--- ps2.c.old 2006-06-28 13:21:01.000000000 +0200
+++ ps2.c 2006-06-28 13:00:17.000000000 +0200
@@ -117,6 +117,8 @@
void ps2_queue(void *opaque, int b)
{
+printf("%i ", b);
+
PS2State *s = (PS2State *)opaque;
PS2Queue *q = &s->queue;
-- END --
Result on pressing UP key: 224 42 224 72 224 200 224 170,
so it's correct.
2. I understood output of my program wrong. Output was sth like:
224 224 72 88224 224 170 where these to 8s were strange for me.
The true is that qemu dropped somewhere part of my fake keycodes
+ kbd_put_keycode(0xe0);
+ kbd_put_keycode(0x2a);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - this one was lost
+ kbd_put_keycode(0xe0);
+ kbd_put_keycode(0xaa);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - and this one too
As the result of this drop, after pressing UP key (without my
test program loaded) DOS displays ONE '8' character. When I load
my TSR test program DOS displays TWO '8' characters! I suppose
these 8s are the answare(?) why arrow keys are interpreted twice
in such programs like Dos Navigator when I run them with qemu.
So now I have to find out:
- where those fake keycodes were dropped,
- why after loading my test program those two 8s are displayed
(there is some unneeded interrupt generated - am I right?).
Honestly, I don't know where I should start looking...
--
Rafał Cygnarowski
rafi@pers.pl
PS. My goal is to lost those fake twice pressed keys
becouse I use (want to use) qemu only for DOS guest OS.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] qemu kbd emulation
2006-06-28 12:16 ` Rafał Cygnarowski
@ 2006-06-28 14:28 ` Jim C. Brown
2006-06-28 17:27 ` Rafał Cygnarowski
2006-06-29 20:56 ` Rafał Cygnarowski
2006-06-28 15:05 ` Stuart Brady
1 sibling, 2 replies; 10+ messages in thread
From: Jim C. Brown @ 2006-06-28 14:28 UTC (permalink / raw)
To: qemu-devel
On Wed, Jun 28, 2006 at 02:16:56PM +0200, Rafa?? Cygnarowski wrote:
> So now I have to find out:
> - where those fake keycodes were dropped,
> - why after loading my test program those two 8s are displayed
> (there is some unneeded interrupt generated - am I right?).
>
> Honestly, I don't know where I should start looking...
>
Not sure if this is the cause, but I believe that ps2_read_data remembers the last key pressed and returns it if there is no new key to be read (to make it work with EMM386 it seems).
I have an ugly hack that fixes the code so there are no more key repeats, but I was never able to figure out what caused the key drops.
--
Infinite complexity begets infinite beauty.
Infinite precision begets infinite perfection.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] qemu kbd emulation
2006-06-28 14:28 ` Jim C. Brown
@ 2006-06-28 17:27 ` Rafał Cygnarowski
2006-06-29 20:56 ` Rafał Cygnarowski
1 sibling, 0 replies; 10+ messages in thread
From: Rafał Cygnarowski @ 2006-06-28 17:27 UTC (permalink / raw)
To: qemu-devel
Dnia środa, 28 czerwca 2006 16:28, Jim C. Brown napisał:
> On Wed, Jun 28, 2006 at 02:16:56PM +0200, Rafa?? Cygnarowski wrote:
> > So now I have to find out:
> > - where those fake keycodes were dropped,
> > - why after loading my test program those two 8s are displayed
> > (there is some unneeded interrupt generated - am I right?).
> >
> > Honestly, I don't know where I should start looking...
>
> Not sure if this is the cause, but I believe that ps2_read_data remembers
> the last key pressed and returns it if there is no new key to be read (to
> make it work with EMM386 it seems).
And it's ok while reading port 0x60 should return last key.
What I can say is that I found 1st REAL bug.
Value recived from port 0x60 in interrupt function should
always be the same.
While I'm not sure if this is clear, here is sample code
for testing:
-- BEGIN test.pas --
program time; {$M 2048,0,0}
uses crt, dos;
var oldkbd : procedure;
procedure kbd; interrupt;
begin
Write(' 1. '); Write(Port[$60]);
Write(' 2. '); Write(Port[$60]);
Write(' 3. '); Writeln(Port[$60]);
inline($9c); oldkbd;
end;
begin
getintvec($9, addr(oldkbd));
setintvec($9, @kbd);
keep(0);
end.
-- END test.pas --
kbd function works fine on qemu for keys which fill ps2_queue
to q->count == 1 (like letters). It works in this case becouse
after reading first value from queue q->count is equal 0 and
then last key is returned.
For keys which are suppressed by 0xe0 for example this code fails.
ps2_read_data is used to recive Port[$60] value and every use of
this function decrease q->count (and moves pointer to next value)
which is wrong in this case while this action should take place
after exiting my "kbd" function.
Any idea how to fix it? (I'm not familiar with qemu src code and
I don't know where to put the code which should move ps2_queue
pointer to next value.)
--
Rafał Cygnarowski
rafi@pers.pl
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] qemu kbd emulation
2006-06-28 14:28 ` Jim C. Brown
2006-06-28 17:27 ` Rafał Cygnarowski
@ 2006-06-29 20:56 ` Rafał Cygnarowski
1 sibling, 0 replies; 10+ messages in thread
From: Rafał Cygnarowski @ 2006-06-29 20:56 UTC (permalink / raw)
To: qemu-devel
> I have an ugly hack that fixes the code so there are no more key repeats,
> but I was never able to figure out what caused the key drops.
I suppose that I have same ugly hack as you:
uint32_t ps2_read_data(void *opaque)
{
[...]
if (q->count == 0) {
[...]
} else {
val = q->data[q->rptr];
if (++q->rptr == PS2_QUEUE_SIZE)
q->rptr = 0;
q->count--;
/* reading deasserts IRQ */
/*
If I comment out following line:
s->update_irq(s->update_arg, 0);
repeating keys disapear. I didn't notice negative
effects of this so far.
*/
/* reassert IRQs if data left */
s->update_irq(s->update_arg, q->count != 0);
}
return val;
}
BTW: what happens when update_irq is called?
AFAIK some interraption should be emulated but I don't know how.
Becouse ps2_queue can grow (q->count can be sth more than 1) and
becouse every time at the end of ps2_queue function update_irq is
called, I suppose that irqs are emulated by another thread.
So how they are synchronized?
--
Rafał Cygnarowski
rafi@pers.pl
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] qemu kbd emulation
2006-06-28 12:16 ` Rafał Cygnarowski
2006-06-28 14:28 ` Jim C. Brown
@ 2006-06-28 15:05 ` Stuart Brady
1 sibling, 0 replies; 10+ messages in thread
From: Stuart Brady @ 2006-06-28 15:05 UTC (permalink / raw)
To: qemu-devel
On Wed, Jun 28, 2006 at 02:16:56PM +0200, Rafa?? Cygnarowski wrote:
> So now I have to find out:
> - where those fake keycodes were dropped,
I'm not sure.
> - why after loading my test program those two 8s are displayed
> (there is some unneeded interrupt generated - am I right?).
8 is on the same key as "up" on the numeric keypad.
> Honestly, I don't know where I should start looking...
Have you tried toggling numlock?
The URL I posted might help -- especially the bit about fake shifts.
The output you're getting is:
e0 e0 48 e0 e0 aa
but you should get:
e0 2a e0 48 e0 c8 e0 aa
So you're losing 2a (which after e0 would fakes pressing shift) and then
c8 (which would release the up key itself).
(BTW, it'd be easier if you used hexadecimal in your output.)
It seems that having the MSB bit set in the output of
sdl_keyevent_to_keycode() means that it's one of the 'e0'-escaped keys
(mostly the 'grey' versions of the numeric keypad keys)... and the MSB
in the final keycode is set if the key is being released, otherwise
it's cleared.
I can't see anything wrong... but I'm not sure if you're adding code in
the wrong place. QEMU uses PC keycodes internally but I'm not sure this
should go as far as including fake shifts -- either way, you'll probably
need to look at hw/ps2.c.
I don't know much about PS/2, unfortunately, but hw/ps2.c seems to
translate keycodes from set 1 to set 2, and they get converted back to
set 1 elsewhere. Maybe that's where the bug is?
--
Stuart Brady
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] qemu kbd emulation
2006-06-28 8:27 [Qemu-devel] qemu kbd emulation Rafał Cygnarowski
2006-06-28 8:39 ` Oliver Gerlich
@ 2006-06-28 9:39 ` Stuart Brady
2006-06-28 10:07 ` Stuart Brady
2 siblings, 0 replies; 10+ messages in thread
From: Stuart Brady @ 2006-06-28 9:39 UTC (permalink / raw)
To: qemu-devel
On Wed, Jun 28, 2006 at 10:27:31AM +0200, Rafa?? Cygnarowski wrote:
> and it look that qemu does not generate some codes before
> pressing and after releasing arrow keys. For example pressing
> up key on qemu looks like:
>
> 224 72 224 200
>
> while without emulation it looks:
>
> 224 42 224 72 224 200 224 170.
(e0 2a e0 48 e0 c8 e0 aa)
FWIW, 2a is the left shift key.
See http://www.win.tue.nl/~aeb/linux/kbd/scancodes.html
--
Stuart Brady
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] qemu kbd emulation
2006-06-28 8:27 [Qemu-devel] qemu kbd emulation Rafał Cygnarowski
2006-06-28 8:39 ` Oliver Gerlich
2006-06-28 9:39 ` Stuart Brady
@ 2006-06-28 10:07 ` Stuart Brady
2006-06-28 11:17 ` Rafał Cygnarowski
2 siblings, 1 reply; 10+ messages in thread
From: Stuart Brady @ 2006-06-28 10:07 UTC (permalink / raw)
To: qemu-devel
On Wed, Jun 28, 2006 at 10:27:31AM +0200, Rafa?? Cygnarowski wrote:
> + case 0xc8: /* up */
> + case 0xd0: /* down */
> + case 0xcd: /* right */
> + case 0xcb: /* left */
> + if (ev->type != SDL_KEYUP) {
> + kbd_put_keycode(e0);
> + kbd_put_keycode(2a);
> + }
> + break;
> }
As I suspected, this is the "fake shift" sequence. It's should also be
needed for the insert, delete, home, end, page up and page down keys.
Note that fake shifts shouldn't be generated for the numeric keypad.
--
Stuart Brady
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] qemu kbd emulation
2006-06-28 10:07 ` Stuart Brady
@ 2006-06-28 11:17 ` Rafał Cygnarowski
0 siblings, 0 replies; 10+ messages in thread
From: Rafał Cygnarowski @ 2006-06-28 11:17 UTC (permalink / raw)
To: qemu-devel
> > + case 0xc8: /* up */
> > + case 0xd0: /* down */
> > + case 0xcd: /* right */
> > + case 0xcb: /* left */
> > + if (ev->type != SDL_KEYUP) {
> > + kbd_put_keycode(e0);
> > + kbd_put_keycode(2a);
This should be:
+ kbd_put_keycode(0xe0);
+ kbd_put_keycode(0x2a);
my fault...
> > + }
> > + break;
> > }
>
> As I suspected, this is the "fake shift" sequence. It's should also be
> needed for the insert, delete, home, end, page up and page down keys.
>
> Note that fake shifts shouldn't be generated for the numeric keypad.
Yes, but now I'm trying only these few keys...
--
Rafał Cygnarowski
rafi@pers.pl
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2006-06-29 20:57 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-28 8:27 [Qemu-devel] qemu kbd emulation Rafał Cygnarowski
2006-06-28 8:39 ` Oliver Gerlich
2006-06-28 12:16 ` Rafał Cygnarowski
2006-06-28 14:28 ` Jim C. Brown
2006-06-28 17:27 ` Rafał Cygnarowski
2006-06-29 20:56 ` Rafał Cygnarowski
2006-06-28 15:05 ` Stuart Brady
2006-06-28 9:39 ` Stuart Brady
2006-06-28 10:07 ` Stuart Brady
2006-06-28 11:17 ` Rafał Cygnarowski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).