Adds prototype keyboard driver.

This commit is contained in:
Felix Queissner 2015-10-13 18:02:18 +02:00
parent 5b5b381a2c
commit f1a85fac20
2 changed files with 315 additions and 44 deletions

View file

@ -16,6 +16,12 @@ NATIVE toUInt32(…) → UINT32;
# NATIVE toBool(…) → BOOL; # NATIVE toBool(…) → BOOL;
# NATIVE toText(…) → TEXT; # NATIVE toText(…) → TEXT;
TYPE CpuState IS
eax : UINT32;
ebx : UINT32;
ecx : UINT32;
END
PRI sendCommand(cmd : UINT8) PRI sendCommand(cmd : UINT8)
BEGIN BEGIN
# Warten bis die Tastatur bereit ist, und der Befehlspuffer leer ist # Warten bis die Tastatur bereit ist, und der Befehlspuffer leer ist
@ -36,12 +42,17 @@ BEGIN
# sendCommand(244u8); # sendCommand(244u8);
END END
PRI handleKeyPress(keycode : INT, released : BOOL)
BEGIN
IF released = FALSE THEN
print("[keycode=", keycode, "]\n");
END
END
PUB main() | i : INT PUB main() | i : INT
BEGIN BEGIN
print("Initialize keyboard...\n"); print("Initialize keyboard...\n");
initKeyboard(); initKeyboard();
print(toInt8(16), "\n");
print("Hello World!\n"); print("Hello World!\n");
1 → i; 1 → i;
@ -51,21 +62,83 @@ BEGIN
END END
END END
TYPE CpuState IS # Status-Variablen fuer das Behandeln von e0- und e1-Scancodes
eax : UINT32; VAR e0Code : BOOL;
ebx : UINT32; # Wird auf 1 gesetzt, sobald e1 gelesen wurde, und auf 2, sobald das erste
ecx : UINT32; # Datenbyte gelesen wurde
VAR e1Code : INT;
VAR e1Prev : UINT16;
PRI translateKeyCode(extend : INT, scancode : INT) → keycode : INT
BEGIN
print("[extend=", extend, ",scancode=", scancode, "]\n");
0 → keycode;
IF extend = 0 THEN
# LOTS OF CODE HERE. Maybe optimize this? :P
IF scancode = 10 THEN 1 → keycode; RETURN; END
END
END END
PUB irq(id : INT, data : CpuState) | scancode : UINT8 PRI handleKeyboardIRQ() | scancode : UINT8, keycode : INT, breakcode : BOOL
BEGIN
0 → keycode;
FALSE → breakcode;
inb(96u16) → scancode;
# Um einen Breakcode handelt es sich, wenn das oberste Bit gesetzt ist und
# es kein e0 oder e1 fuer einen Extended-scancode ist
IF ((scancode & 0x80u8) =/= 0u8) & ((e1Code =/= 0) | (scancode =/= 0xE1u8)) & (e0Code | (scancode =/= 0xE0u8)) THEN
TRUE → breakcode;
(scancode & 127u8) → scancode;
END
# print("[scancode=", scancode, ",breakcode=", breakcode, "]");
IF e0Code THEN
# Fake shift abfangen und ignorieren
IF (scancode = 0x2Au8) | (scancode = 0x36u8) THEN
FALSE → e0Code;
RETURN;
END
translateKeyCode(1, toInt32(scancode)) → keycode;
FALSE → e0Code;
ELSE
IF e1Code = 2 THEN
# Fertiger e1-Scancode
# Zweiten Scancode in hoeherwertiges Byte packen
(e1Prev | toUInt16(scancode * 256u8)) → e1Prev;
translateKeyCode(2, toInt32(e1Prev)) → keycode;
0 → e1Code;
ELSE
IF e1Code = 1 THEN
# Erstes Byte fuer e1-Scancode
toUInt16(scancode) → e1Prev;
2 → e1Code;
ELSE
IF scancode = 0xE0u8 THEN
TRUE → e0Code;
ELSE
IF scancode = 0xE1u8 THEN
1 → e1Code;
ELSE
translateKeyCode(0, toInt32(scancode)) → keycode;
END
END
END
END
END
IF keycode =/= 0 THEN
handleKeyPress(keycode, breakcode);
END
END
PUB irq(id : INT, data : CpuState)
BEGIN BEGIN
# print("irq:", id, ", ", data.eax, " ", data.ebx, "\n"); # print("irq:", id, ", ", data.eax, " ", data.ebx, "\n");
IF id = 33 THEN IF id = 33 THEN
inb(96u16) → scancode; handleKeyboardIRQ();
print("keypress: ", scancode, "\n");
IF scancode = 1u8 THEN
shutdown();
END
END END
~data; ~data;
END END
@ -80,9 +153,13 @@ Was noch gemacht werden muss, bis der Tastatur-Treiber funktionieren könnte:
☑ Custom types in Copper ☑ Custom types in Copper
☑ Native function calls in Copper ☑ Native function calls in Copper
☑ Bitwise Operations ☑ Bitwise Operations
☑ outb und inb ☑ outb und inb
☐ eventuell hex literals für Copper ☑ NEW/DELETE
☐ NEW/DELETE ☑ [TYPE] →
☐ [TYPE] → ☑ ~()
☐ ~() ☑ hex literals für Copper
☑ 'RETURN' für Copper
Was noch gemacht werden muss, bis der Tastatur-Treiber schön aussieht:
☐ ELSE-IF
☐ ARRAYS
!# !#

View file

@ -1,6 +1,6 @@
; ============================================= ; =============================================
; compiled with Copper 1.0 ; compiled with Copper 1.0
; 2015-10-13 14:57:24 ; 2015-10-13 17:50:36
; ============================================= ; =============================================
; native method: print(…) ; native method: print(…)
@ -18,6 +18,10 @@
ebx : UINT32; ebx : UINT32;
ecx : UINT32; ecx : UINT32;
} }
.global e0Code BOOL
.global e1Code INT32
.global e1Prev UINT16
@ -70,6 +74,23 @@ _private_3:
ret ret
; end of initKeyboard ; end of initKeyboard
; 0, handleKeyPress
handleKeyPress:
pushnil ; return value
load -2
pushi 6 0
op2 5
jmp_if_not _private_4
pusht "]\n"
load -1
pusht "[keycode="
calln print 3
_private_4:
ret
; end of handleKeyPress
; 1, main ; 1, main
.export main .export main
main: main:
@ -80,22 +101,17 @@ main:
call initKeyboard 0 call initKeyboard 0
pusht "\n"
pushi 2 16
callnr toInt8 1
calln print 2
pusht "Hello World!\n" pusht "Hello World!\n"
calln print 1 calln print 1
pushi 2 1 pushi 2 1
store 1 store 1
_private_4: _private_5:
load 1 load 1
pushi 2 5 pushi 2 5
op2 8 op2 8
jmp_if_not _private_5 jmp_if_not _private_6
pusht "\n" pusht "\n"
load 1 load 1
calln print 2 calln print 2
@ -105,40 +121,218 @@ _private_4:
op2 0 op2 0
store 1 store 1
jmp _private_4 jmp _private_5
_private_5: _private_6:
ret ret
; end of main ; end of main
; 1, irq
.export irq
irq: ; 0, translateKeyCode
translateKeyCode:
pushnil ; return value
pusht "]\n"
load -2
pusht ",scancode="
load -1
pusht "[extend="
calln print 5
pushi 2 0
store 0
load -1
pushi 2 0
op2 5
jmp_if_not _private_7
load -2
pushi 2 10
op2 5
jmp_if_not _private_8
pushi 2 1
store 0
load 0
retr
_private_8:
_private_7:
load 0
retr
; end of translateKeyCode
; 0, handleKeyboardIRQ
handleKeyboardIRQ:
pushnil ; return value pushnil ; return value
pushnil ; scancode:UINT8 pushnil ; scancode:UINT8
load -1 pushnil ; keycode:INT32
pushi 2 33 pushnil ; breakcode:BOOL
op2 5 pushi 2 0
jmp_if_not _private_6 store 2
pushi 6 0
store 3
pushi 4 96 pushi 4 96
callnr inb 1 callnr inb 1
store 1 store 1
pusht "\n"
load 1 load 1
pusht "keypress: " pushi 3 128
calln print 3 op2 12
pushi 3 0
op2 6
loadg e1Code
pushi 2 0
op2 6
load 1
pushi 3 225
op2 6
op2 11
loadg e0Code
load 1
pushi 3 224
op2 6
op2 11
op2 12
op2 12
jmp_if_not _private_9
pushi 6 1
store 3
load 1 load 1
pushi 3 1 pushi 3 127
op2 12
store 1
_private_9:
loadg e0Code
jmp_if_not _private_10
load 1
pushi 3 42
op2 5 op2 5
jmp_if_not _private_7 load 1
calln shutdown 0 pushi 3 54
op2 5
op2 11
jmp_if_not _private_12
pushi 6 0
storeg e0Code
_private_7: ret
_private_6: _private_12:
load 1
callnr toInt32 1
pushi 2 1
callr translateKeyCode 2
store 2
pushi 6 0
storeg e0Code
jmp _private_11
_private_10:
loadg e1Code
pushi 2 2
op2 5
jmp_if_not _private_13
loadg e1Prev
load 1
pushi 3 256
op2 2
callnr toUInt16 1
op2 11
storeg e1Prev
loadg e1Prev
callnr toInt32 1
pushi 2 2
callr translateKeyCode 2
store 2
pushi 2 0
storeg e1Code
jmp _private_14
_private_13:
loadg e1Code
pushi 2 1
op2 5
jmp_if_not _private_15
load 1
callnr toUInt16 1
storeg e1Prev
pushi 2 2
storeg e1Code
jmp _private_16
_private_15:
load 1
pushi 3 224
op2 5
jmp_if_not _private_17
pushi 6 1
storeg e0Code
jmp _private_18
_private_17:
load 1
pushi 3 225
op2 5
jmp_if_not _private_19
pushi 2 1
storeg e1Code
jmp _private_20
_private_19:
load 1
callnr toInt32 1
pushi 2 0
callr translateKeyCode 2
store 2
_private_20:
_private_18:
_private_16:
_private_14:
_private_11:
load 2
pushi 2 0
op2 6
jmp_if_not _private_21
load 3
load 2
call handleKeyPress 2
_private_21:
ret
; end of handleKeyboardIRQ
; 1, irq
.export irq
irq:
pushnil ; return value
load -1
pushi 2 33
op2 5
jmp_if_not _private_22
call handleKeyboardIRQ 0
_private_22:
load -2 load -2
destruct destruct