Adds prototype keyboard driver.
This commit is contained in:
parent
5b5b381a2c
commit
f1a85fac20
2 changed files with 315 additions and 44 deletions
109
scripts/main.cu
109
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,13 +42,18 @@ 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");
|
||||
|
||||
print("Hello World!\n");
|
||||
1 → i;
|
||||
WHILE i <= 5 DO
|
||||
|
@ -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
|
||||
handleKeyboardIRQ();
|
||||
END
|
||||
~data;
|
||||
END
|
||||
|
@ -81,8 +154,12 @@ Was noch gemacht werden muss, bis der Tastatur-Treiber funktionieren könnte:
|
|||
☑ Native function calls in Copper
|
||||
☑ Bitwise Operations
|
||||
☑ outb und inb
|
||||
☐ eventuell hex literals für Copper
|
||||
☐ NEW/DELETE
|
||||
☐ [TYPE] →
|
||||
☐ ~()
|
||||
☑ 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
|
||||
!#
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue