From f1a85fac207202c6c41a09cdeae5ee054b9c8541 Mon Sep 17 00:00:00 2001 From: Felix Queissner Date: Tue, 13 Oct 2015 18:02:18 +0200 Subject: [PATCH] Adds prototype keyboard driver. --- scripts/main.cu | 115 ++++++++++++++++---- scripts/main.cu.spark | 244 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 315 insertions(+), 44 deletions(-) diff --git a/scripts/main.cu b/scripts/main.cu index bb3bf02..3cf7947 100644 --- a/scripts/main.cu +++ b/scripts/main.cu @@ -16,6 +16,12 @@ NATIVE toUInt32(…) → UINT32; # NATIVE toBool(…) → BOOL; # NATIVE toText(…) → TEXT; +TYPE CpuState IS + eax : UINT32; + ebx : UINT32; + ecx : UINT32; +END + PRI sendCommand(cmd : UINT8) BEGIN # Warten bis die Tastatur bereit ist, und der Befehlspuffer leer ist @@ -36,12 +42,17 @@ BEGIN # sendCommand(244u8); END +PRI handleKeyPress(keycode : INT, released : BOOL) +BEGIN + IF released = FALSE THEN + print("[keycode=", keycode, "]\n"); + END +END + PUB main() | i : INT BEGIN print("Initialize keyboard...\n"); - initKeyboard(); - - print(toInt8(16), "\n"); + initKeyboard(); print("Hello World!\n"); 1 → i; @@ -51,21 +62,83 @@ BEGIN END END -TYPE CpuState IS - eax : UINT32; - ebx : UINT32; - ecx : UINT32; +# Status-Variablen fuer das Behandeln von e0- und e1-Scancodes +VAR e0Code : BOOL; +# Wird auf 1 gesetzt, sobald e1 gelesen wurde, und auf 2, sobald das erste +# 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 -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 # print("irq:", id, ", ", data.eax, " ", data.ebx, "\n"); - IF id = 33 THEN - inb(96u16) → scancode; - print("keypress: ", scancode, "\n"); - IF scancode = 1u8 THEN - shutdown(); - END + IF id = 33 THEN + handleKeyboardIRQ(); END ~data; END @@ -80,9 +153,13 @@ Was noch gemacht werden muss, bis der Tastatur-Treiber funktionieren könnte: ☑ Custom types in Copper ☑ Native function calls in Copper ☑ Bitwise Operations - ☑ outb und inb - ☐ eventuell hex literals für Copper - ☐ NEW/DELETE - ☐ [TYPE] → - ☐ ~() + ☑ outb und inb + ☑ NEW/DELETE + ☑ [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 !# diff --git a/scripts/main.cu.spark b/scripts/main.cu.spark index 2c3d73c..7a039b0 100644 --- a/scripts/main.cu.spark +++ b/scripts/main.cu.spark @@ -1,6 +1,6 @@ ; ============================================= ; compiled with Copper 1.0 -; 2015-10-13 14:57:24 +; 2015-10-13 17:50:36 ; ============================================= ; native method: print(…) @@ -18,6 +18,10 @@ ebx : UINT32; ecx : UINT32; } +.global e0Code BOOL +.global e1Code INT32 +.global e1Prev UINT16 + @@ -70,6 +74,23 @@ _private_3: ret ; 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 .export main main: @@ -80,22 +101,17 @@ main: call initKeyboard 0 - pusht "\n" - pushi 2 16 - callnr toInt8 1 - calln print 2 - pusht "Hello World!\n" calln print 1 pushi 2 1 store 1 -_private_4: +_private_5: load 1 pushi 2 5 op2 8 - jmp_if_not _private_5 + jmp_if_not _private_6 pusht "\n" load 1 calln print 2 @@ -105,40 +121,218 @@ _private_4: op2 0 store 1 - jmp _private_4 -_private_5: + jmp _private_5 +_private_6: ret ; 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 ; scancode:UINT8 - load -1 - pushi 2 33 - op2 5 - jmp_if_not _private_6 + pushnil ; keycode:INT32 + pushnil ; breakcode:BOOL + pushi 2 0 + store 2 + + pushi 6 0 + store 3 + pushi 4 96 callnr inb 1 store 1 - pusht "\n" load 1 - pusht "keypress: " - calln print 3 + pushi 3 128 + 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 - 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 - jmp_if_not _private_7 - calln shutdown 0 + load 1 + 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 destruct