PDA

View Full Version : Keyboard Hardware Interrupt in DOS with GO32?



cronodragon
28-01-2008, 05:07 PM
I found this code in the FPC manual (section 7.2.12):

http://deug-stpi.gavysn.univ-nantes.fr/info/docs/freepascal/units/node8.html#SECTION00827000000000000000

But it doesn't compile for me :? Is anybody able to compile it? What settings do you use? Or is it un-updated... the assembly looks weird, not like TASM syntax. Indeed I have been successful at compiling asm code for VGA with FPC, and the old TASM syntax just works fine. No idea why they use those "%" everywhere, and removing them doesn't help at all.

Anyway what I want is just reading the keyboards raw data like in the old days. :D I don't want to use the keyboard unit, since it doesn't detects when keys are released.

Thanks!
-Marco

dmantione
28-01-2008, 05:13 PM
It is ATT syntax, rather than Intel syntax. The compiler should process it without problems, if you set the assembler mode to ATT.

cronodragon
28-01-2008, 05:36 PM
That helped, but still get some errors. For example, it tries to get data from labels like INT9_DS and OLDHANDLER, but doesn't find them. I defined the label, but no luck, placed the data defines at the beginning (with a jmp before), no luck. What could be missing?

Thanks!

Ñuño Martínez
28-01-2008, 09:20 PM
If you can read C code, download the sources of Allegro (http://alleg.sf.net/). May be you can translate it to Pascal. It's a bit complex so may be you should download version 3 instead version 4 (version 3 was DOS only). It uses ASM also but I'm not sure if keyboard used it or was C only.

JSoftware
29-01-2008, 10:35 AM
I haven't used DPMI services but I presume you are in PMode. I would do it like this then:


type
TIdtE = array[0..3] of word;
PIdtE = ^TIdtE;

var olde: TIdtE;

procedure KeyIrq; interrupt;
begin

end;

procedure InitKeyInterrupt;
var idtr: packed record limit: word; offset: cardinal; end;
r: PIdtE;
p: word;
begin
asm
cli
sidt [idtr]
end;
r := Pointer(idtr.offset);
olde := r[9];
r[9,0] := cardinal(@KeyIrq) and $FFFF;
asm
xor edi,edi
push cs
pop di
mov p,di
end['edi'];
r[9,1] := p;
r[9,2] := $E400;
r[9,3] := (cardinal(@KeyIrq) shr 16) and $FFFF;
asm
sti
lidt [idtr]
end;
end;

procedure SetOldKeyboard;
var idtr: packed record limit: word; offset: cardinal; end;
r: PIdtE;
p: word;
begin
asm
cli
sidt [idtr]
end;
r := Pointer(idtr.offset);
r[9] := olde;
asm
sti
lidt [idtr]
end;
end;

cronodragon
30-01-2008, 03:11 AM
Thanks JSoftware... hmm it will take time to test that code, I'll do it later on. :D

JSoftware
30-01-2008, 09:16 AM
I think it should drop right in without anything else. I made some small changes to it as it probably wouldn't work before

cronodragon
30-01-2008, 02:47 PM
I still have to fill in the code of KeyIrq.

JSoftware
30-01-2008, 03:37 PM
You could try something like this:

...
var sc, m: byte;
i,t: integer;
begin
m := inportb($64);
t := 10;
while (t > 0) and ((m and 1) = 1) do
begin
sc := inportb($60);

m := inportb($61);
m := m or $80;
outportb($61, m);
m := m and $7F;
outportb($61, m);

HandleScancode(sc);

dec(t);
m := inportb($64);
end;