S
Hallo,
ich nutze nur Kleinbuchstaben.
Meine ISR für den IRQ 1 sieht so aus:
IRQ_33: ;Tastatur Interrupt IRQ 1
pushad
.einlesen:
xor eax, eax
;hier ist ein Zeichen im Tastaturpuffer
mov byte [getchar.tmp], al
in al, 0x60 ;Zeichen einlesen
test al, 128d
jnz .ende ;Prüfen ob Bit 7 gesetzt ist
mov ebx, getchar.ascii_tabelle
xlat
mov byte [getchar.tmp], al
.ende:
mov al, 0x20
out 0x20, al
popad
iret
Bei einem Tastendruck wird obige ISR aufgerufen.
Erstmal die Variable getchar.tmp löschen!
In Zeile 8 wird der Scancode eingelesen. Zeile 9 testet nur ob die Taste losgelassen
wurde, was mich aber erstmal nicht interessiert.
Mit dem Befehl xlat hole ich mir das Asciizeichen aus der Tabelle und
lege es in der Variablen ab.
Wie man sieht ist mein Ringpuffer nur 1 Byte groß (reicht aber)
Der Buchstabe wird einfach in getchar.tmp gespeichert. Diese Variable liegt
in der Prozedur getchar
Meine Tabelle in der aus Scancode der Asciicode wird sieht so aus und liegt ebenfalls hinter der Prozedur getchar.tmp.
getchar:
xor eax, eax
mov al, byte [.tmp]
or al, al
jz getchar
mov byte [.tmp], ah
ret
.tmp db 0,0
.ascii_tabelle:
db 0, 1, "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "?", "`", 14 ;0 - 14
db 15, "q", "w", "e", "r", "t", "z", "u", "i", "o", "p", "ü", "+", 13 ;15 - 28
db 29, "a", "s", "d", "f", "g", "h", "j", "k", "l", "ö", "ä",0, 42,"#"
db "y", "x", "c", "v", "b", "n", "m", ",", ".", "-", 54, 55, 0," ", 58
db 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 200, 73, 74, 201, 76
db 202, 78, 79, 203, 81, 82, 83, 84, 85, "<", 87, 88, 89, 90, 91, 92, 93,
db 94, 95, 96, 97, 98, 99, 100, 101, 102
Wenn ich getchar aufrufe, wird geschaut ob in der Variablen .tmp
ein Asciizeichen liegt, das ganze geschieht in einer Schleife sodaß es erst
weiter geht wenn man die Tastaur betätigt.
Sobald ein Zeichen vorhanden ist wird es nach AL geladen und die Variable wieder
gelöscht.
Nun kann man den Tastendruck auswerten.
call getchar
cmp al, "j" ;j gedrückt
je .ja
cmp al, "n" ;n gedrückt
je .nein
jmp .?
Das ganze funktioniert auch sehr einfach mit Großbuchstaben.
Dazu legst dur dir eine zweite Tabelle an z.B.
shift_tabelle:
db 0, 1, "!", 34, "§", "$", "%", "&", "/", "(", ")", "=", "?", "`", 14 ;0 - 14
db 15, "Q", "W", "E", "R", "T", "Z", "U", "I", "O", "P", "Ü", "*", 13 ;15 - 28
db 29, "A", "S", "D", "F", "G", "H", "J", "K", "L", "Ö", "Ä",0, 42,"'"
db "Y", "X", "C", "V", "B", "N", "M", ";", ":", "_", 54, 55, 0," ", 58
db 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 200, 73, 74, 201, 76
db 202, 78, 79, 203, 81, 82, 83, 84, 85, ">", 87, 88, 89, 90, 91, 92, 93,
db 94, 95, 96, 97, 98, 99, 100, 101, 102
und baust noch ein Flag oder Statusbyte ein, was z.B. in Bit 0 vermerkt ob
die Shift-Taste gedrückt oder losgelassen wurde.
Das gleiche noch für die ALT-Taste:
alt_tabelle:
db 0, 0, "²", "³", 0, 0, 0, 0, "{", "[", "]", "}", "\",0, 0 ;0 - 14
db 0, "@", 0, "€", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ;15 - 28
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0,0
db "Y", "X", "C", "V", "B", "N", "µ", ";", ":", "_", 54, 55, 56, " ", 58
db 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 200, 73, 74, 201, 76
db 202, 78, 79, 203, 81, 82, 83, 84, 85, "|", 87, 88, 89, 90, 91, 92, 93,
db 94, 95, 96, 97, 98, 99, 100, 101, 102
Mit den ASCII Zeichen musst du mal ein bisschen probieren. Ü liegt vielleicht nicht
auf der Ü-Taste aber dafür kannst du die Tabellen ja anpassen.
Schreiben auf dem Schirm klappt tadellos.
Um einen String einzulesen habe ich folgende Prozedur erstellt die mit
zwei Parametern über den Stack aufgerufen wird:
;liest einen String ein bis zum Enter Zeichen (13)
;Param1 = Adresse wo der String abgelegt werden soll +8
;Param2 = Adresse mit der Anzahl max. Zeichen +12
getstring:
push ebp
mov ebp, esp
sub esp, 0x20
pushad
mov edi, [ebp + 8] ;Stringablage nach EDI
xor ecx, ecx
mov [ebp - 4], ecx ;Zählervariable
mov [ebp - 8], ecx ;tmp Feld zum schreiben
mov esi, [ebp + 12]
mov ecx, [esi] ;Anzahl der max. Zeichen nach ECX
mov [ebp - 12], ecx ;Anzahl temporär zwischenspeichern
push dword [coursor]
pop dword [ebp - 16] ;Startpos des Coursor speichern!
.einlesen:
call getchar ;Zeichen einlesen
cmp al, 13d
je .ende ;Wenn Enter dann Ende
cmp al, 14d
je .back ;Wenn Back dann Sprung zu .back
mov byte [ebp - 8], al ;
stosb ;Schreibe zeichen
pushad
mov eax, ebp
sub eax, 8d
push dword eax
call print
popad
inc dword [ebp - 4] ;Zähler + 1
dec dword [ebp - 12] ;Zählervariable verringern - 1
jz .ende
jmp .einlesen
.ende:
xor al, al
stosb ;Leerzeichen am Ende des Strings setzen
; mov ebx, [ebp + 12]
; mov eax, [ebp - 4]
; mov [ebx], eax ;geschriebene Zeichen nach Param2
popad
add esp, 0x20
mov eax, [ebp - 4]
pop ebp
ret 8
.back:
push eax
push ebx
push ecx
;schauen ob wir nicht am Beginn sind!
mov ecx, dword [coursor]
cmp ecx, dword [ebp - 16]
je .no_back
mov ebx, [coursor]
sub ebx, 2d
xor al, al
mov byte [ebx + 0xA0000], al
dec edi
mov byte [edi], al
mov [coursor], ebx
call setcoursor
dec dword [ebp - 4] ;Zähler - 1
inc dword [ebp - 12] ;
.no_back:
pop ecx
pop ebx
pop eax
jmp .einlesen
Wenn du noch mehr brauchst, schick mir eine Mail.
ichmachmit@unitybox.de
Gruß, Nicky