Autor Thema: Port 0x60 leeren - Tastaturtreiber  (Gelesen 12266 mal)

üäpöol

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #20 am: 08. May 2012, 20:00 »
Hm... Das verwirrt mich ein bisschen. Ich habe aktuell folgenden Code:
char keyboard_handler(int show) {
volatile char scancode=port_in(0x60);
if (!(scancode & 0x80)) {
if (show == 1) print_char(kbdus[(short)scancode], 4*160+12, 0x02);
return kbdus[(short)scancode];
}
return 0;
}

void reset_keyboard() {
while (!(port_in(0x64) & 0x1));
}
Der Code in der main.c hat sich nicht verändert, nur dass ich das reset_keyboard ganz am Anfang der großen hile Schleife entfernt habe. Es funktioniert auch alles so weit perfekt; das einzige seltsame Problem ist noch, wenn man vor der großen while Schleife eine Taste drückt und danach Enter, führt das dazu, dass aus der Schleife gegangen wird und gleich abgefragt, wird, ob der Computer neugestartet werden soll. Ich habe den Eindruck, dass irgendetwas total schiefgeht.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #21 am: 08. May 2012, 20:08 »
Warum verwendest du eigentlich keine Interrupts und abstrahierst die Tastatur als Queue (von Events)? Das ständige Rumgebastel an den I/O-Port-Funktionen führt nicht zum Ziel. Wenn du den Tastatur"treiber" von deiner Programmlogik mal etwas entkoppelst, kannst du den Code, den du schreibst sogar für andere Dinge wiederverwenden.
« Letzte Änderung: 08. May 2012, 20:09 von Jidder »
Dieser Text wird unter jedem Beitrag angezeigt.

üäpöol

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #22 am: 09. May 2012, 08:47 »
Ja, das wäre wahrscheinlich einfacher. Soweit ich weiß, wird aber kein Interrupt ausgelöst, wenn eine Taste gedrückt wurde. Wie kann ich das denn programmieren? Gibt es dafür einen Artikel? Ich hab keinen gefunden.

OS_3000

  • Beiträge: 53
    • Profil anzeigen
Gespeichert
« Antwort #23 am: 09. May 2012, 11:41 »
Natürlich kann auch ein Interrupt ausgelöst werden.
Ist im Wiki auch genauestens beschrieben:
http://www.lowlevel.eu/wiki/KBC#IRQ-Handler
http://www.lowlevel.eu/wiki/IRQ#IRQ_Tabelle

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #24 am: 09. May 2012, 20:02 »
Außerdem http://www.lowlevel.eu/wiki/Teil_5_-_Interrupts für allgemeine Interrupts im PM.
Dieser Text wird unter jedem Beitrag angezeigt.

üäpöol

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #25 am: 10. May 2012, 16:16 »
OK. Vielen Dank, ich habe es jetzt über IRQ 1 gelöst. Funktioniert perfekt.

üäpöol

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #26 am: 14. May 2012, 14:47 »
Ich habe nochmal eine ähnliche Frage. Ich wollte die Shifttaste programmieren:
void keyboard_handler(struct regs *null) {
volatile char scancode=inb(0x60);
if (!(scancode & 0x80) && scancode != 42 && scancode != 170) {
if (shift != 1) l_pressed_key=kbdus[(short)scancode];
else {
l_pressed_key=kbdus_caps[(short)scancode];
}
}
else {
if (scancode == 42) shift=1;
else if (scancode == 170) shift=0;
else {
print_char(scancode, 16, 0x07);
l_pressed_key=(char) 0;
}
}
}
Leider wird nur das Drücken der Shifttaste realisiert, ansonsten wird ein '¬' ausgegeben, was nach dieser Tabelle http://www.tcp-ip-info.de/tcp_ip_und_internet/ascii.htm auch 170 sein sollte. Was habe ich schon wieder falsch verstanden? :D

üäpöol

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #27 am: 14. May 2012, 21:05 »
Hat sich erledigt. Für alle, die dasselbe Problem haben:
void keyboard_handler(struct regs *null) {
volatile char scancode=inb(0x60);
if ((scancode & 0x80) == 0) {
if (shift != 1) l_pressed_key=kbdus[(short)scancode];
else {
l_pressed_key=kbdus_caps[(short)scancode];
}
if (scancode == 42) shift=1;
}
else {
scancode-=0x80;
if (scancode == 42) shift=0;
else {
l_pressed_key=(char) 0;
}
}
}
Das funktioniert bei mir. :)

 

Einloggen