Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: bscreator am 08. February 2010, 17:16

Titel: Keyboard Controller
Beitrag von: bscreator am 08. February 2010, 17:16
Hallo,

ich hab ein Problem mit meinem Keyboard Controller.
Ich versuche, einen Keyboard Self Test mit
mov al,0xAA
out 0x64,al
in al,0x60
Im Register AL steht jedoch anstatt 0x55 (für successful) noch die 0xAA.

Mach ich irgendwas falsch ?

Viele Grüße,
bsc
Titel: Re: Keyboard Controller
Beitrag von: Cool-Andy am 08. February 2010, 17:49
Ich bin mir nicht sicher, aber musst du 0x60 nicht erst leeren, bevor du in 0x64 schreiben kannst?

Also:
in al, 0x60
mov al, 0xAA
out 0x64, al
in al, 0x60

Ich hoffe es war richtig, was ich gesagt habe!  8-)
Titel: Re: Keyboard Controller
Beitrag von: Jidder am 08. February 2010, 18:29
Außerdem solltest du mit dem Lesen warten, bis der KBC was in den Ausgabepuffer geschrieben hat.
Titel: Re: Keyboard Controller
Beitrag von: bscreator am 08. February 2010, 19:17
Also leeren kann man den KBC mit dem Auslesen des Ports 0x60 nicht!
Warten bringt auch nichts.
Hab das Auslesen und vergleichen mit 0x55 schon in eine Endlosschleife gepackt, aber da würd der Assembler wahrscheinlich die ganze Nacht durchlaufen.
Titel: Re: Keyboard Controller
Beitrag von: rizor am 08. February 2010, 19:43
War es nicht so, dass du bei dem Selftest eine gewisse Zeit warten musst?
Errinnere mich da eine eine Warte-Funktion
Titel: Re: Keyboard Controller
Beitrag von: bscreator am 09. February 2010, 16:12
Naja,
im Grunde gehts mir nur darum, ohne Verwendung der Interrupts von der Tastatur lesen zu können.
Kennt ihr da noch nen anderen Weg außer über die Ports ?
Titel: Re: Keyboard Controller
Beitrag von: Jidder am 09. February 2010, 17:22
Nein, es gibt keinen anderen Weg. I/O-Ports sind dazu da, um mit Geräten zu kommunizieren.
Titel: Re: Keyboard Controller
Beitrag von: bscreator am 10. February 2010, 13:26
OK,
kennt ihr dann einen kleinen Codeabschnitt, mit dem man eine Taste unter Verwendung von Ports von der Tastatur liest ?

Vielen Dank,
bsc
Titel: Re: Keyboard Controller
Beitrag von: Jidder am 10. February 2010, 13:56
#define KBD_DATA 0x60
#define KBD_CTRL 0x64

#define KBD_OBF 0x01 // output buffer full

/* scancode in zeichen umwandeln, gibt 0 zurück, wenn der scancode kein zeichen ist */
char keyb_decode(unsigned char code);

char keyb_read_char()
{
char c;

do {
while (!(inb(KBD_CTRL) & KBD_OBF));
c = keyb_decode(inb(KBD_DATA));
} while (c == 0);

return c;
}
Titel: Re: Keyboard Controller
Beitrag von: bscreator am 10. February 2010, 17:37
Dann müsst das ganze in Assembler ungefähr so aussehen, oder ?
start:
in al,0x64      ;lese von Command-Port
mov ah,0x01
cmp al,ah     
jne start       ;wenn Input-Buffer leer

read:           
in al,0x60     ;lese von Data-Port
mov ah,0x00
cmp ah,al
je read
Titel: Re: Keyboard Controller
Beitrag von: Jidder am 10. February 2010, 21:06
Hi,

nicht ganz. Änderungen sind mit Pfeilen markiert.

start:
in al,0x64      ;lese von Command-Port
mov ah,0x01
test al,ah      ; <------------ test statt cmp, weil du nur ein bit testen willst
jz start       ;wenn Output-Buffer leer <----- edit: muss hier natürlich auch jz heißen

read:           
in al,0x60     ;lese von Data-Port
;<--------------- und hier jetzt den Scancode (al) verarbeiten. das mit keyb_decode ist vielleicht zu verwirrend gewesen. das hätte ich da nicht einfügen sollen.
Titel: Re: Keyboard Controller
Beitrag von: bscreator am 11. February 2010, 11:40
Hi  PorkChicken,

habs jetzt mal so ausprobiert, also die getkey-Methode vom StupidOS-Kernel
getkey:
mov ah, 0 ; Funktion 0
int 016h ; Ausführen
ret

durch diese getkey-Methode
getkey:
in al,0x64
mov ah,0x01
test al,ah
jne getkey
in al,0x60
ret
ersetzt.

Aber das einzige, was Bochs dann macht, ist eine Endlosschleife, bzw. es wartet nicht auf einen Tastendruck, sondern es startet den Bootloader und den Kernel immer wieder.

Wenn du aber die Zeile jne getkey durch je getkey ersetzt, dann funktioniert es komischerweise

Habt ihr ne Ahnung, warum ?


Titel: Re: Keyboard Controller
Beitrag von: Jidder am 11. February 2010, 12:24
Weil "je" ja das gleiche ist wie "jz". Und "jz" ist hier natürlich der richtige Sprung.

Das heißt er springt solange immer wieder zu "getkey", wie das Bit 1 (also OBF) null ist. Er wartet also, bis es gesetzt ist, was ja auch dem Sinn des OBF-Flags entspricht.
Titel: Re: Keyboard Controller
Beitrag von: bscreator am 11. February 2010, 12:29
OK,
das heißt also, dass es bei Bochs "je" heißen muss.
Wenn ich das ganze aber dann unter REALEN Bedingungen, sprich den Rechner neu starten und von Floppy booten lass, testen möchte, muss es "jne" heißen, oder ?
Titel: Re: Keyboard Controller
Beitrag von: Jidder am 11. February 2010, 13:48
Unter Bochs und realem PC muss der selbe Code funktionieren. Ich verstehe nicht, wie du darauf kommst, dass es jne sein sollte.

Ich muss bei meinen Posts allerdings auch ein Detail richtig stellen: Das was ich in meinen vorherigen Posts fälschlicherweise als Input Buffer bezeichnet habe, ist der Output Buffer. Wir lesen ja den Keyboard Controller aus. Im Wiki stehts natürlich richtig.
Titel: Re: Keyboard Controller
Beitrag von: bscreator am 11. February 2010, 14:33
Du meinst
;Warten bis der Eingabepuffer leer ist
wait1:
in   al, 0x64
test al, 00000010b
jne  wait1
 
;Befehl 0xD1 zum schreiben des Inputports an den KBC senden
mov  al, 0xD1
out  0x64, al
 
;Wieder warten bis der Eingabepuffer leer ist
wait2:
in   al, 0x64
test al, 00000010b
jne  wait2
 
;Den neuen Wert für den Inputport über Port 0x60 senden
mov  al, 0xFE
out  0x60, al

Zitat
Unter Bochs und realem PC muss der selbe Code funktionieren.
Sorry, aber da muss ich Dir widersprechen. Hab schon etliche Ereignisse gehabt, wo der Code zwar unter Bochs, aber nicht beim REALEN PC-Reset funktioniert hat.

Titel: Re: Keyboard Controller
Beitrag von: XanClic am 11. February 2010, 16:45
Wenn Code zwar unter bochs, aber nicht auf einer echten Maschine funktioniert, dann heißt das trotzdem, dass der Code, der auf echter Hardware läuft, auch auf bochs geht (zumindest gehen sollte).

Bei jz vs. jnz ist es aber so, dass sich beide Codes gegenseitig ausschließen würden. Und das ist ja was anderes. PorkChicken hat sich da wohl einfach vertan, als er dein cmp mit jne übernommen hat. Bei test müsste es eben je/jz sein -- das hat er ja jetzt auch in seinem entsprechenden Code korrigiert.

Und, nein, PorkChicken meinte nicht den Inportport, sondern den Inputbuffer vs. Outputbuffer (Inputbuffer zum Senden von Befehlen, Outputbuffer zum Lesen von Scancodes).
Titel: Re: Keyboard Controller
Beitrag von: bscreator am 11. February 2010, 19:59
Zitat
(zumindest gehen sollte)
Das mein ich

Zitat
jz vs. jnz ist es aber so, dass sich beide Codes gegenseitig ausschließen würden
Da hast du allerdings auch wieder recht.

OK. Das Verarbeiten von Scan-Codes funktioniert.
Aber wie kann ich Zeichen auslesen, sprich ASCII-Codes ?
Titel: Re: Keyboard Controller
Beitrag von: XanClic am 11. February 2010, 20:12
Zitat von: bscreator
Zitat
(zumindest gehen sollte)
Das mein ich
Ich dachte, du meinst das erste (also dass Code, der auf bochs geht, auf echter Hardware nicht geht). Denn normalerweise läuft jeder Code, der auf echter Hardware geht, auch auf bochs (wobei ich da mal Probleme mit so einem Bit in cr4 hatte)...

Zitat von: bscreator
Aber wie kann ich Zeichen auslesen, sprich ASCII-Codes ?
Das ist die Funktion, die PorkChicken anfangs als keyb_decode() bezeichnet hat. Zur Liste der Scancodes siehe z. B. http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html (aus dem Wiki).
Titel: Re: Keyboard Controller
Beitrag von: bscreator am 11. February 2010, 21:00
1. Dann muss ich jetzt für jeden Buchstaben den Hex-Code manuell auswerten, oder ?
Also:
falls Scancode==0x1e, dann Ausgabe 'A'
falls Scancode==0x30, dann Ausgabe 'B'
...

2. Konnte man Tasten auch schon beim 8086 mit Hilfe von Ports auslesen, oder erst ab dem 80286 ?
Titel: Re: Keyboard Controller
Beitrag von: XanClic am 11. February 2010, 21:47
Normalerweise macht man so eine Auswertung eher mit einem Array (wo man dann den Scancode als Index verwendet und dass dann den ASCII-Code zurückliefert) als mit vielen If-Abfragen.

Und das mit den Ports: Wie willst du die denn sonst auslesen? :?
Titel: Re: Keyboard Controller
Beitrag von: bscreator am 11. February 2010, 23:26
Zitat
Normalerweise macht man so eine Auswertung eher mit einem Array (wo man dann den Scancode als Index verwendet und dass dann den ASCII-Code zurückliefert) als mit vielen If-Abfragen.
Ist schon klar. Was ich damit sagen wollte ist, dass es aber keine einfache mathematische Formel gibt, um vom Scancode auf den ASCII-Wert zu schließen,oder ?

Und das mit den Ports frag ich, weil auf
http://lowlevel.brainsware.org/wiki/index.php/Keyboard_Controller 
folgendes drinsteht :
"Der KBC wurde mit dem AT System (286) eingeführt. "

Also: Wie einen KBC auslesen, wenns den erst ab dem 286 gibt ?
Titel: Re: Keyboard Controller
Beitrag von: XanClic am 12. February 2010, 00:02
Zitat von: bscreator
Zitat
Normalerweise macht man so eine Auswertung eher mit einem Array (wo man dann den Scancode als Index verwendet und dass dann den ASCII-Code zurückliefert) als mit vielen If-Abfragen.
Ist schon klar. Was ich damit sagen wollte ist, dass es aber keine einfache mathematische Formel gibt, um vom Scancode auf den ASCII-Wert zu schließen,oder ?
Soweit ich weiß, nicht, aber ich wäre dankbar, wenn du mir eine solche liefern könntest. :wink:

Zitat von: bscreator
Und das mit den Ports frag ich, weil auf
http://lowlevel.brainsware.org/wiki/index.php/Keyboard_Controller 
folgendes drinsteht :
"Der KBC wurde mit dem AT System (286) eingeführt. "

Also: Wie einen KBC auslesen, wenns den erst ab dem 286 gibt ?
1. Was heißt "erst"? Hast du noch einen 8086 oder 80186 zu Hause rumliegen?
2. Dann gabs vorher wohl andere Standards (oder vielleicht ja auch gar keinen), ich bin mir aber ziemlich sicher, dass das dann auch über Ports funktionierte. Und wenn da nichts dokumentiert ist, muss man eben das BIOS nehmen (ein 8086 oder 80186 kommt ja noch gar nicht in den PM, deshalb ist das BIOS ja immer verfügbar).
Titel: Re: Keyboard Controller
Beitrag von: bluecode am 12. February 2010, 11:45
Damals hast du glaube ich mit der Tastatur direkt geredet und erst mit PS/2 kam dann der Controller dazu, mit dem man dann auch ne Maus ansprechen konnte. Wenn mein Protected-Mode OS macht, ist das aber sowieso egal, denn den gibts ja schließlich erst mit dem 386iger (zumindest in der 32Bit Variante des PM).
Titel: Re: Keyboard Controller
Beitrag von: bscreator am 18. February 2010, 18:26
Zitat
Damals hast du glaube ich mit der Tastatur direkt geredet
Ähm, das versteh ich nicht richtig.
Jetzt kommuniziere ich doch auch mit der Tastatur direkt und nicht über den ab dem 286 eingeführten Keyboard Controller, oder ?

Zitat
Was heißt "erst"? Hast du noch einen 8086 oder 80186 zu Hause rumliegen?
Hab zuhause noch nen 8086 und der ist mein absolutes Sahnetörtchen. :-D

Noch ne Frage:
Die Interrupts vom BIOS werden wohl auch über Ports kommunizieren. Wie kann ich mit der Tastatur DIREKT kommunizieren ?

Gruss,
bsc
Titel: Re: Keyboard Controller
Beitrag von: Svenska am 18. February 2010, 19:17
Noch ne Frage:
Die Interrupts vom BIOS werden wohl auch über Ports kommunizieren. Wie kann ich mit der Tastatur DIREKT kommunizieren ?

Guck dich mal im Linux-Kernel um, die haben Tastaturtreiber für XT-Tastaturen und ähnliches drin, aber die laufen _alle_ über einen Fremdanschluss, d.h. Parallelport oder so. Die Tastatur kannst du über den normalen Anschluss nicht direkt ansprechen.

Der XT (8086/8088) nutzt übrigens einen anderen Tastaturstandard, in dem man der Tastatur nichts senden kann. Also elektrisch gibt die Tastatur den Takt und die Daten vor und der Rechner muss es nehmen oder es lassen. Ab dem AT (80286) kam dann das AT-Tastaturprotokoll dazu und dort kann man der Tastatur auch Befehle schicken (z.B. LEDs an/aus), und um das vernünftig hinzukriegen, gibt es den KBC. Die Tastatur gibt übrigens trotzdem den Takt vor. :-) Aus dem Grund funktionieren XT-Tastaturen nicht mit einem modernen PC (und in der Übergangsphase gab es Jumper oder DIP-Schalter zum Umschalten).

Mit der PS/2-Baureihe hat IBM dann den PS/2-Anschluss eingeführt, der sich aber elektrisch und protokolltechnisch nicht vom AT-Tastaturanschluss unterscheidet, nur der Controller auf PC-Seite wurde erweitert/ersetzt und der kann jetzt zusätzlich auch Mäuse ansprechen. Für die Tastatur blieb alles beim alten.

Wie man eine XT-Tastatur ohne BIOS anspricht, weiß ich nicht, es gibt aber gute elektrische Beschreibungen (für Mikrocontroller oder so) im Internet...

So, ich hoffe, nicht genervt zu haben.

Gruß,
Svenska
Titel: Re: Keyboard Controller
Beitrag von: bscreator am 21. February 2010, 12:16
Zitat
Der XT (8086/8088) nutzt übrigens einen anderen Tastaturstandard, in dem man der Tastatur nichts senden kann.

Dann ist man aber über die BIOS-Interrupts flexibler (da diese sowohl für XT, als auch für AT-Tastaturen funktionieren), oder ?
Titel: Re: Keyboard Controller
Beitrag von: bluecode am 21. February 2010, 12:27
Wenn du ein Realmode OS baust ist es sowieso nicht ungeschickt die BIOS-Interrupts zu nehmen. Bei einem Protected Mode OS findest du (wahrscheinlich) eh keine Uralttastatur und willst sowieso keine BIOS-Interrupts nehmen (abgesehen von VESA BIOS Extensions vielleicht).