Tastaturabfrage
Tastaturabfrage
Hallo,
hab da mal ne Frage zu "Debug".
Um ein kleines Programm unter Debug während des Laufs zu stoppen, hatte ich, bild ich mir ein, einen 4 Zeiler wie folgt.
Mov dx,378
mov al,01
out dx,al
mov al,00
out dx,al
in al,60
cmp al,01
jnz (nach mov al,01)
int 21
Funtioniert jedoch nicht, da" in al,60" die ASII Werte in den Akku holt und ich somit keinen Vergleich mit 1 machen kann.
Weiß jemand, wie ich das Tastatur Statusflag abfragen kann?!
MfG
Berndt
hab da mal ne Frage zu "Debug".
Um ein kleines Programm unter Debug während des Laufs zu stoppen, hatte ich, bild ich mir ein, einen 4 Zeiler wie folgt.
Mov dx,378
mov al,01
out dx,al
mov al,00
out dx,al
in al,60
cmp al,01
jnz (nach mov al,01)
int 21
Funtioniert jedoch nicht, da" in al,60" die ASII Werte in den Akku holt und ich somit keinen Vergleich mit 1 machen kann.
Weiß jemand, wie ich das Tastatur Statusflag abfragen kann?!
MfG
Berndt
Willst Du wissen, ob eine Taste gedrückt wurde? Wenn ja, dann geht das wie folgt:
Das hat allerdings recht wenig mit DOS zu tun, sondern ist simple Maschinensprache 
Gruss,
Odin
Code: Alles auswählen
MOV AH, 01h // Funktion für Tastaturstatus
INT 16h // Interrupt 16h aufrufen
JNZ ... // Wenn Zero-Flag = 0, dann wurde eine Taste gedrückt

Gruss,
Odin
"640k ought to be enough for anybody." - Bill Gates (1981)
"Windows 95 needs at least 8MB RAM." - Bill Gates (1996)
... also braucht niemand Windows 95 !!!
"Windows 95 needs at least 8MB RAM." - Bill Gates (1996)
... also braucht niemand Windows 95 !!!
Hallo Odin,
Dank für Deine Antwort !
Das ist natürlich auch eine Möglichkeit. Werd's gleich mal probieren.
Das Problem beim Interrupt ist jedoch, daß dadurch der Prozessablauf gestoppt wird und relativ viel Zeit kostet, wenn ich richtig informiert bin.
Deswegen kam ein schlauer Ingenieur von Siemens, dessen Namen und Adresse ich jedoch nicht mehr weiß, auf die Lösung mit der direkten Einlesung über -- IN AL, 60 (Tastaturport) --
Leider habe ich da aber irgenwo einen Denkfehler gemacht .
Werd aber gleich mal sehen, wieviel Zeit Deine Sequenz braucht. Vielleicht ja sogar weniger.
Also, nochmals vielen Dank und einen schönen Tag
Berndt
Dank für Deine Antwort !
Das ist natürlich auch eine Möglichkeit. Werd's gleich mal probieren.
Das Problem beim Interrupt ist jedoch, daß dadurch der Prozessablauf gestoppt wird und relativ viel Zeit kostet, wenn ich richtig informiert bin.
Deswegen kam ein schlauer Ingenieur von Siemens, dessen Namen und Adresse ich jedoch nicht mehr weiß, auf die Lösung mit der direkten Einlesung über -- IN AL, 60 (Tastaturport) --
Leider habe ich da aber irgenwo einen Denkfehler gemacht .
Werd aber gleich mal sehen, wieviel Zeit Deine Sequenz braucht. Vielleicht ja sogar weniger.
Also, nochmals vielen Dank und einen schönen Tag
Berndt
High bttr,
die 1 in " 1" setzen geht nicht , da Debug das nicht annimmt.
Angenommen ich hab in Debug ein kleines Assemblerprogramm geschrieben, und möchte, das ich das Programm, wenn ich es gestartet habe, mit einer x-beliebigenTaste anhalten kann.
Dazu sollte der Controller ständig die Tastatur abfragen, ob irgendeine Taste gedrückt ist und den Zustand (0 oder 1) in den Akku einlesen. Nur welches Bit ist das, und wie fragt man das ab.
Der Tastaturport ist "60", also
" IN AL,60 " stimmt schon. Der Wert des Bits (0 oder 1) müßte dann im Low Byte des Akkus stehen, damit er dann vergleichen kann, ob"AL" 00 oder 01 ist.
Ich habe aber immer nur den Hex Code der gedrückten Taste im Akku.
Vielleicht geht diese Art der Tastaturabfrage aber auch nur mit älteren Dos Versionen. DOS 5.0 vielleicht.
Die Lösung von Odin funktioniert für sich allein wunderbar. Nur in Verbindung mit einem Programm hängt sich DOS auf.
die 1 in " 1" setzen geht nicht , da Debug das nicht annimmt.
Angenommen ich hab in Debug ein kleines Assemblerprogramm geschrieben, und möchte, das ich das Programm, wenn ich es gestartet habe, mit einer x-beliebigenTaste anhalten kann.
Dazu sollte der Controller ständig die Tastatur abfragen, ob irgendeine Taste gedrückt ist und den Zustand (0 oder 1) in den Akku einlesen. Nur welches Bit ist das, und wie fragt man das ab.
Der Tastaturport ist "60", also
" IN AL,60 " stimmt schon. Der Wert des Bits (0 oder 1) müßte dann im Low Byte des Akkus stehen, damit er dann vergleichen kann, ob"AL" 00 oder 01 ist.
Ich habe aber immer nur den Hex Code der gedrückten Taste im Akku.
Vielleicht geht diese Art der Tastaturabfrage aber auch nur mit älteren Dos Versionen. DOS 5.0 vielleicht.
Die Lösung von Odin funktioniert für sich allein wunderbar. Nur in Verbindung mit einem Programm hängt sich DOS auf.
Der Tastaturport 60h gibt auch nur den Scancode der gedrückten Taste aus. Das bedeutet, dass Du bei einem Vergleich mit 01h abfragst, ob die ESC-Taste gedrückt wurde.
Wenn ich mich recht erinnere, dann musst Du den Inhalt mit 00h vergleichen, das beudeutet nämlich, dass kein Scancode vorliegt - also auch keine Taste gedrückt wurde.
Das der Interrupt nicht funktioniert, könnte möglicherweise an DOS liegen, ich weiss es aber nicht, ich hab das noch nie ausprobiert.
Wenn ich mich recht erinnere, dann musst Du den Inhalt mit 00h vergleichen, das beudeutet nämlich, dass kein Scancode vorliegt - also auch keine Taste gedrückt wurde.
Das der Interrupt nicht funktioniert, könnte möglicherweise an DOS liegen, ich weiss es aber nicht, ich hab das noch nie ausprobiert.
"640k ought to be enough for anybody." - Bill Gates (1981)
"Windows 95 needs at least 8MB RAM." - Bill Gates (1996)
... also braucht niemand Windows 95 !!!
"Windows 95 needs at least 8MB RAM." - Bill Gates (1996)
... also braucht niemand Windows 95 !!!
@Gast
Es gibt freie Assembler in allen möglichen "Farben". Warum willst du da ausgerechnet mit Debug ein Programm schreiben? siehe z.B. http://www.bttr-software.de/links/#asm
Ansonsten habe ich dich wohl doch falsch verstanden. Wenn du die Frage also gleich gut formuliert hättest, dann wären solche Mißverständnisse gar nicht erst aufgekommen.
Für NASM würde der Quellcode für ein Programm, das abbricht, sobald eine Taste (auch Shift, Ctrl, Alt) gedrückt wurde, so aussehen:
EDIT: Die entsprechenden Infos dazu findest du z.B. in Help-PC oder Ralf Browns Interrupt-Liste (Datei "ports.*") ebenfalls auf meiner Homepage erhältlich.
Es gibt freie Assembler in allen möglichen "Farben". Warum willst du da ausgerechnet mit Debug ein Programm schreiben? siehe z.B. http://www.bttr-software.de/links/#asm
Ansonsten habe ich dich wohl doch falsch verstanden. Wenn du die Frage also gleich gut formuliert hättest, dann wären solche Mißverständnisse gar nicht erst aufgekommen.

Für NASM würde der Quellcode für ein Programm, das abbricht, sobald eine Taste (auch Shift, Ctrl, Alt) gedrückt wurde, so aussehen:
Code: Alles auswählen
Org 100h
start:
in al, 64h ; Status-Register des Tastatur-Controllers lesen
and al, 1 ; alles außer Bit 0 verwerfen
or al, al ; auf 0 prüfen (keine neuen Daten vorhanden)
jz start ; wieder von vorn beginnen
ret
Bei ihm gehts um einen Softwareinterrupt...bei mir um einen Hardwareinterrupt (sprich: ich will nicht die Tastatur abfragen, die soll schon selbst sagen wenn was ist...)
diese realisierung hat den Vorteil, das das Programm irgendwas anderes machen kann, bei Tastendruck gehts dann automatisch an der richtigen stelle weiter (sonst braucht man eine Abfrageschleife - was durchaus eine verzoegerte Reaktion bedeuten kann), hat aber den Nachteil das dies fuer harte Echtzeitbedingungen ungeeignet ist (durch den Interrupt treten unvorhersehbare verzoegerungen im Programmablauf auf) und ist fuer reine Warteschleifen ziemlich sinnlos...
Edit: oder mal schnell in Pascal ausgedrueckt:
diese realisierung hat den Vorteil, das das Programm irgendwas anderes machen kann, bei Tastendruck gehts dann automatisch an der richtigen stelle weiter (sonst braucht man eine Abfrageschleife - was durchaus eine verzoegerte Reaktion bedeuten kann), hat aber den Nachteil das dies fuer harte Echtzeitbedingungen ungeeignet ist (durch den Interrupt treten unvorhersehbare verzoegerungen im Programmablauf auf) und ist fuer reine Warteschleifen ziemlich sinnlos...
Edit: oder mal schnell in Pascal ausgedrueckt:
Code: Alles auswählen
uses dos;
var count:longint;
var OldInterrupt: procedure;
procedure NewInterrupt; interrupt;
begin
inc(count);
OldInterrupt;
writeln(count);
end;
{int09=Tasta}
begin
count:=0;
GetIntVec ($09, @OldInterrupt);{ Uebergebe den Interruptvector $09 an OldInterrupt}
SetIntVec ($09, @NewInterrupt);{ Setze den Interruptvector $09 auf NewInterrupt}
repeat;
{Hier ist wirklich nix}
until count>9;
SetIntVec ($09, @OldInterrupt);
end.
-
- DOS-Übermensch
- Beiträge: 1035
- Registriert: Mi 31. Jan 2007, 19:04
- Wohnort: Halle
- Kontaktdaten:
Harte Echtzeitbedingungen? :P
Bei einem PC ist das doch absolute Augenwischerei. Wenn du hier etwas halbwegs Echtzeit machen willst, musst du das durch extra Hardware erledigen. Ansonsten musst du durch nicht ganz triviale Routinen die Zyklen vorher ausmessen, beim Pentium durch den integrieten MSR Counterm beim 486er wirds noch viel schwerer.
Aber das geht auch nicht immer.
Selbst Latenzen wie beim C64 fuer Interrupts (6 us) gehoeren beim PC in den Bereich der Maerchen und MYthen.
[/quote]
Bei einem PC ist das doch absolute Augenwischerei. Wenn du hier etwas halbwegs Echtzeit machen willst, musst du das durch extra Hardware erledigen. Ansonsten musst du durch nicht ganz triviale Routinen die Zyklen vorher ausmessen, beim Pentium durch den integrieten MSR Counterm beim 486er wirds noch viel schwerer.
Aber das geht auch nicht immer.
Selbst Latenzen wie beim C64 fuer Interrupts (6 us) gehoeren beim PC in den Bereich der Maerchen und MYthen.
[/quote]
Ob nun Hardware- oder Softwareinterrupt, das macht letztenendes ja kaum einen Unterschied... der Softwareinterrupt ist zwar langsamer, aber bremsen können beide...
Ich glaube, es wäre sinnvoll wenn sich der Autor dieses Threads zu dem Ziel dieser Sache äußern würde - dann könnte man vielleicht eher eine passende Lösung finden...
Ich glaube, es wäre sinnvoll wenn sich der Autor dieses Threads zu dem Ziel dieser Sache äußern würde - dann könnte man vielleicht eher eine passende Lösung finden...
"640k ought to be enough for anybody." - Bill Gates (1981)
"Windows 95 needs at least 8MB RAM." - Bill Gates (1996)
... also braucht niemand Windows 95 !!!
"Windows 95 needs at least 8MB RAM." - Bill Gates (1996)
... also braucht niemand Windows 95 !!!
-
- DOS-Übermensch
- Beiträge: 1035
- Registriert: Mi 31. Jan 2007, 19:04
- Wohnort: Halle
- Kontaktdaten:
Der Befehl in al, 64h dauert vermutlich wesentlich laenger als der Rest des Codes. So dass eine direkte Abfrage oder eine Abfrage ueber Soft Int nahezu dieselbe Zeit dauern duerfte. (Unter der Annahme, dass der Soft Int auch nur einmal in al,64h ausfuehrt)
Um das herauszufinden, kann man mit Debug auch mal schnell in den Bios Code schauen oder zB in den Source von 'keypressed' unter TP.
Um das herauszufinden, kann man mit Debug auch mal schnell in den Bios Code schauen oder zB in den Source von 'keypressed' unter TP.
@Odin
ich sags mal so: wenn es nur darum geht einen Tastendruck mitzukriegen, reicht es im Interrupt einen wert im Speicher zu setzen.
(mov x,y - mehr muss da nicht gemacht werden)
diesen Wert im Speicher zu ueberpruefen geht dann verdammt schnell - zumal dieser dann sehr wahrscheinlich sowieso im Cache ist...
und bremsen wird er wahrscheinlich nicht, denn solange du nicht im Interruptregister die Interrupts sperrst, werden sie sowieso ausgefuehrt...(es sei denn der IRQ wird erst per SetIntVec freigeschalten; mit IRQs habe ich mich bisher noch nicht auf Assemblerebene herumgeschlagen - zumindest nicht auf PCs)
ich sags mal so: wenn es nur darum geht einen Tastendruck mitzukriegen, reicht es im Interrupt einen wert im Speicher zu setzen.
(mov x,y - mehr muss da nicht gemacht werden)
diesen Wert im Speicher zu ueberpruefen geht dann verdammt schnell - zumal dieser dann sehr wahrscheinlich sowieso im Cache ist...
und bremsen wird er wahrscheinlich nicht, denn solange du nicht im Interruptregister die Interrupts sperrst, werden sie sowieso ausgefuehrt...(es sei denn der IRQ wird erst per SetIntVec freigeschalten; mit IRQs habe ich mich bisher noch nicht auf Assemblerebene herumgeschlagen - zumindest nicht auf PCs)
Hallo liebe Leute,
da hab ich ja eine ganze Lawine losgetreten. Schön, das es so viele Menschen gibt, die sich noch Gedanken machen !
Danke für Eure Antworten.
Es ist einfach so, daß ich für Demonstrationszwecke (privat) eine kleine Routine bräuchte, mit der ich auf x-beliebigen Tastendruck oder auch eine bestimmte Taste hin eine laufende Schleife (z. B. Rechteckgenerator, Ausgabe an Bit 1) unterbrechen kann. Die Abfrage ist ein Bestandteil der Schleife.
z.B. diese Schleife
MOV DX,378 (Parallelschnittstelle initialisieren)
MMOV,AL,01 (Bit 1=1)
OUT DX,AL (Ausgabe an Parallelschnittstelle = 1)
MOV,AL,00 (Bit 1=0)
OUT DX,AL (Ausgabe an Parallelschnittstelle = 0)
Hier sollte jetzt die Tastaturabfrage geschehen, und die Schleife sollte zu
MOV AL,01
zurückspringen, oder das Programm bei Tastendruck abbrechen(z.B. INT 21)
Ich hatte früher mit dem verflixten "IN AL, 60"
und einem Vergleich das ganze schon am Laufen, habe jedoch die Unterlagen nicht mehr.
Was mich interessieren würde, was genau kommt rein beim IN-Befehl
und steht dann in AL oder auch AX ?!
Was, und wie kann ich dann vergleichen ?!
Nochmals vielen Dank für Eure Bemühungen und einen wunderschönen Tag
Berndt
I
da hab ich ja eine ganze Lawine losgetreten. Schön, das es so viele Menschen gibt, die sich noch Gedanken machen !
Danke für Eure Antworten.
Es ist einfach so, daß ich für Demonstrationszwecke (privat) eine kleine Routine bräuchte, mit der ich auf x-beliebigen Tastendruck oder auch eine bestimmte Taste hin eine laufende Schleife (z. B. Rechteckgenerator, Ausgabe an Bit 1) unterbrechen kann. Die Abfrage ist ein Bestandteil der Schleife.
z.B. diese Schleife
MOV DX,378 (Parallelschnittstelle initialisieren)
MMOV,AL,01 (Bit 1=1)
OUT DX,AL (Ausgabe an Parallelschnittstelle = 1)
MOV,AL,00 (Bit 1=0)
OUT DX,AL (Ausgabe an Parallelschnittstelle = 0)
Hier sollte jetzt die Tastaturabfrage geschehen, und die Schleife sollte zu
MOV AL,01
zurückspringen, oder das Programm bei Tastendruck abbrechen(z.B. INT 21)
Ich hatte früher mit dem verflixten "IN AL, 60"
und einem Vergleich das ganze schon am Laufen, habe jedoch die Unterlagen nicht mehr.
Was mich interessieren würde, was genau kommt rein beim IN-Befehl
und steht dann in AL oder auch AX ?!
Was, und wie kann ich dann vergleichen ?!
Nochmals vielen Dank für Eure Bemühungen und einen wunderschönen Tag
Berndt
I