WIP PS/2 keyboard driver
This commit is contained in:
parent
51780e5606
commit
2366408679
@ -20,32 +20,53 @@
|
|||||||
; behave strangely (will drop next pressed key). This is not a problem, as the computer, once completed, will
|
; behave strangely (will drop next pressed key). This is not a problem, as the computer, once completed, will
|
||||||
; have a 60% keyboard, without any of the unusable keys.
|
; have a 60% keyboard, without any of the unusable keys.
|
||||||
|
|
||||||
include "ps2_keyboard_scancodeset2.asm" ; PS/2 Scan Codeset 2 mappings
|
include 'ps2_keyboard_scancodeset2.asm' ; PS/2 Scan Codeset 2 mappings
|
||||||
|
|
||||||
; config (IO port 1)
|
; config (IO port 1)
|
||||||
PS2KEYB_CLEAR_REG: EQU IO_1
|
PS2KEYB_CLEAR_REG: EQU IO_2
|
||||||
PS2KEYB_DATA_REG: EQU IO_1 + 1
|
PS2KEYB_DATA_REG: EQU IO_2 + 1
|
||||||
|
|
||||||
|
PS2KEYB_TRANSMISSION_DURATION: EQU 86 ;@ 100khz ; The time needed for the keyboard to transmit all the 11 bits of data, in CPU clock cycles
|
||||||
|
|
||||||
PS2KEYB_BREAK: EQU 0xF0 - %10000000 ; The MSB is dropped: see NOTE on intro above
|
PS2KEYB_BREAK: EQU 0xF0 - %10000000 ; The MSB is dropped: see NOTE on intro above
|
||||||
|
|
||||||
; Reads a single character. 0s are ignored (can be used with keyboard).
|
; Reads a single character and returns an ascii code when a valid key is pressed. Blocking.
|
||||||
; Doesn't check DATA_AVAILABLE register of parallel port, because a 0 byte
|
|
||||||
; is ignored anyway (it represents the ASCII NUL control char).
|
|
||||||
; @return A The read character
|
; @return A The read character
|
||||||
PS2Keyb_readc:
|
PS2Keyb_readc:
|
||||||
in a, (PS2KEYB_DATA_REG) ; reads a character
|
in a, (PS2KEYB_DATA_REG) ; reads a character
|
||||||
add a, 0
|
add a, 0
|
||||||
jp z, Term_readc ; if char is 0 (NULL), user didn't press any key: wait for character
|
jp z, Term_readc ; if char is 0 (NULL), user didn't press any key: wait for character
|
||||||
; check if code is a Break Code (0xF0). If it is, discard next key as it is a released key
|
; we found something, allow the keyboard to complete data transmission
|
||||||
ld b, a ; save a
|
ld a, PS2KEYB_TRANSMISSION_DURATION/5 ; every cycle is 5 CPU cycles
|
||||||
cp 0xF0 ; compare a with Break Code
|
ps2keyb_readc_waitloop:
|
||||||
jp z, ps2keyb_readc_discard
|
sub 1
|
||||||
|
jr nz, ps2keyb_readc_waitloop
|
||||||
|
; data transmission should now be complete.
|
||||||
|
; check if code is a Break Code. If it is, discard next key as it is a released key
|
||||||
|
ld c, a ; save a
|
||||||
|
cp PS2KEYB_BREAK ; compare a with Break Code
|
||||||
|
jp z, ps2keyb_readc_discard ; if it is a Break Code, jump to discarder routine
|
||||||
; we read a valid character: clean key registers
|
; we read a valid character: clean key registers
|
||||||
in a, PS2KEYB_CLEAR_REG
|
in a, PS2KEYB_CLEAR_REG
|
||||||
; TODO: Interpretare keycode con lo scan code set
|
; now we will convert keycode in c to ASCII code
|
||||||
;ld a, b ; restore a
|
ld hl, PS2KEYB_SCANCODESET_ASCII_MAP ; load start of codeset to ascii map
|
||||||
|
ld b, 0 ; reset b, as we are going to do a sum with bc (where c contains the read scancode)
|
||||||
|
add hl, bc ; add scancode value to map start addr (we are using it as offset)
|
||||||
|
ld a, (hl) ; load the corresponding ascii code in a for return
|
||||||
ret ; returns in the a register
|
ret ; returns in the a register
|
||||||
ps2keyb_readc_discard:
|
ps2keyb_readc_discard:
|
||||||
; waits for next non-0 keycode and discards it
|
; clean key registers
|
||||||
; TODO
|
in a, PS2KEYB_CLEAR_REG
|
||||||
jp PS2Keyb_readc ; go back and wait for another keycode
|
ps2keyb_readc_discard_waitfordata:
|
||||||
|
; wait for next non-0 keycode and discards it (it is the code of the released key)
|
||||||
|
in a, (PS2KEYB_DATA_REG) ; reads a character
|
||||||
|
add a, 0
|
||||||
|
jp z, ps2keyb_readc_discard_waitfordata ; if char is 0 (NULL), wait
|
||||||
|
; we found something, allow the keyboard to complete data transmission
|
||||||
|
ld a, PS2KEYB_TRANSMISSION_DURATION/5 ; every cycle is 5 CPU cycles
|
||||||
|
ps2keyb_readc_discard_waitloop:
|
||||||
|
sub 1
|
||||||
|
jr nz, ps2keyb_readc_discard_waitloop
|
||||||
|
; data transmission should now be complete, throw away key code
|
||||||
|
in a, PS2KEYB_CLEAR_REG
|
||||||
|
jp PS2Keyb_readc ; go back and wait for another keycode
|
||||||
|
@ -0,0 +1,137 @@
|
|||||||
|
; PS/2 Keycode Mode 2 to ASCII mapping table
|
||||||
|
;
|
||||||
|
; Keycodes 0 to 83
|
||||||
|
|
||||||
|
.db PS2KEYB_SCANCODESET_ASCII_MAP: .db 0 ; (Unused)
|
||||||
|
.db 0 ; F9
|
||||||
|
.db 0 ; (Control key)
|
||||||
|
.db 0 ; F5
|
||||||
|
.db 0 ; F3
|
||||||
|
.db 0 ; F1
|
||||||
|
.db 0 ; F2
|
||||||
|
.db 0 ; F12
|
||||||
|
.db 0 ; (Control key)
|
||||||
|
.db 0 ; F10
|
||||||
|
.db 0 ; F8
|
||||||
|
.db 0 ; F6
|
||||||
|
.db 0 ; F4
|
||||||
|
.db 9 ; TAB
|
||||||
|
.db 96 ; `
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; L ALT
|
||||||
|
.db 0 ; L SHFT
|
||||||
|
.db 0 ; (Control key)
|
||||||
|
.db 0 ; L CTRL
|
||||||
|
.db 1 ; Q
|
||||||
|
.db 2 ; 1
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 3 ; Z
|
||||||
|
.db 4 ; S
|
||||||
|
.db 65 ; A
|
||||||
|
.db 66 ; W
|
||||||
|
.db 67 ; 2
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 68 ; C
|
||||||
|
.db 69 ; X
|
||||||
|
.db 70 ; D
|
||||||
|
.db 71 ; E
|
||||||
|
.db 72 ; 4
|
||||||
|
.db 73 ; 3
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 32 ; SPACE
|
||||||
|
.db 33 ; V
|
||||||
|
.db 34 ; F
|
||||||
|
.db 35 ; T
|
||||||
|
.db 36 ; R
|
||||||
|
.db 37 ; 5
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 38 ; N
|
||||||
|
.db 39 ; B
|
||||||
|
.db 40 ; H
|
||||||
|
.db 41 ; G
|
||||||
|
.db 42 ; Y
|
||||||
|
.db 43 ; 6
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 44 ; M
|
||||||
|
.db 45 ; J
|
||||||
|
.db 46 ; U
|
||||||
|
.db 47 ; 7
|
||||||
|
.db 48 ; 8
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 44 ; ,
|
||||||
|
.db 45 ; K
|
||||||
|
.db 46 ; I
|
||||||
|
.db 47 ; O
|
||||||
|
.db 48 ; 0
|
||||||
|
.db 49 ; 9
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 46 ; .
|
||||||
|
.db 47 ; /
|
||||||
|
.db 48 ; L
|
||||||
|
.db 59 ; ;
|
||||||
|
.db 60 ; P
|
||||||
|
.db 45 ; -
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 39 ; '
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 91 ; [
|
||||||
|
.db 61 ; =
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; CAPS
|
||||||
|
.db 0 ; R SHFT
|
||||||
|
.db 10 ; ENTER
|
||||||
|
.db 93 ; ]
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 92 ; \
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 8 ; BKSP
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 9 ; KP 1
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 10 ; KP 4 -- NOTE: shadowed by break code (see the NOTE in ps2_keyboard.asm)
|
||||||
|
.db 11 ; KP 7
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 0 ; (Unused)
|
||||||
|
.db 48 ; KP 0
|
||||||
|
.db 46 ; KP .
|
||||||
|
.db 47 ; KP 2
|
||||||
|
.db 48 ; KP 5
|
||||||
|
.db 49 ; KP 6
|
||||||
|
.db 50 ; KP 8
|
||||||
|
.db 27 ; ESC
|
||||||
|
.db 0 ; NUM
|
||||||
|
.db 0 ; F11
|
||||||
|
.db 43 ; KP +
|
||||||
|
.db 44 ; KP 3
|
||||||
|
; The following codes are unrecognized by PAT80, as it uses only 7 bits (see the NOTE in ps2_keyboard.asm)
|
||||||
|
; .db 45 ; KP -
|
||||||
|
; .db 42 ; KP *
|
||||||
|
; .db 43 ; KP 9
|
||||||
|
; .db 0 ; SCROLL
|
||||||
|
; .db 0 ; (Control key)
|
||||||
|
; .db 0 ; (Control key)
|
||||||
|
; .db 0 ; (Control key)
|
||||||
|
; .db 0 ; (Control key)
|
||||||
|
; .db 0 ; F7
|
@ -10,9 +10,9 @@ jp Sysinit ; Startup vector: DO NOT MOVE! Must be the first instruction
|
|||||||
; DRIVERS VAR SPACE: 0x9000 - 0x9FFF (4kb)
|
; DRIVERS VAR SPACE: 0x9000 - 0x9FFF (4kb)
|
||||||
; APPLICATION VAR SPACE: 0xA000 - 0xFFFF (24kb)
|
; APPLICATION VAR SPACE: 0xA000 - 0xFFFF (24kb)
|
||||||
; I/O MAP
|
; I/O MAP
|
||||||
; I/O 0 (0x00 - 0x1F) Parallel terminal (uses addr 0x00 only)
|
; I/O 0 (0x00 - 0x1F) Parallel terminal (uses addr 0x00 and 0x01)
|
||||||
; I/O 1 (0x20 - 0x3F) Sound card (uses addr 0x20 only)
|
; I/O 1 (0x20 - 0x3F) Sound card (uses addr 0x20 only)
|
||||||
; I/O 2 (0x40 - 0x5F)
|
; I/O 2 (0x40 - 0x5F) PS2 Keyboard (uses 0x40 and 0x41)
|
||||||
; I/O 3 (0x60 - 0x7F)
|
; I/O 3 (0x60 - 0x7F)
|
||||||
; I/O 4 (0x80 - 0x9F)
|
; I/O 4 (0x80 - 0x9F)
|
||||||
; I/O 5 (0xA0 - 0xBF)
|
; I/O 5 (0xA0 - 0xBF)
|
||||||
@ -56,7 +56,8 @@ Sys_Printc:
|
|||||||
; Reads a single character
|
; Reads a single character
|
||||||
; @return A The read character
|
; @return A The read character
|
||||||
Sys_Readc:
|
Sys_Readc:
|
||||||
jp Term_readc
|
;jp Term_readc
|
||||||
|
jp PS2Keyb_readc
|
||||||
|
|
||||||
; Reads a line
|
; Reads a line
|
||||||
; @return BC The pointer to a null-terminated read string
|
; @return BC The pointer to a null-terminated read string
|
||||||
@ -91,6 +92,7 @@ IO_7: EQU 0xE0
|
|||||||
|
|
||||||
;include 'drivers/hd44780.asm'
|
;include 'drivers/hd44780.asm'
|
||||||
;include 'drivers/keyboard.asm'
|
;include 'drivers/keyboard.asm'
|
||||||
|
include 'drivers/ps2_keyboard.asm'
|
||||||
include 'drivers/arduino_terminal.asm'
|
include 'drivers/arduino_terminal.asm'
|
||||||
include 'drivers/sn76489.asm'
|
include 'drivers/sn76489.asm'
|
||||||
include 'monitor.asm'
|
include 'monitor.asm'
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
#include <TVout.h>
|
|
||||||
#include <TVoutfonts/fontALL.h>
|
|
||||||
TVout TV;
|
|
||||||
|
|
||||||
// Pins
|
|
||||||
#define RS 5
|
|
||||||
#define EN 4
|
|
||||||
const byte DATA [] = {A5, A4, A3, A2, 13, 12, 11, 10};
|
|
||||||
|
|
||||||
|
|
||||||
bool clkState = false;
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(57600);
|
|
||||||
Serial.println("PAL debugger");
|
|
||||||
|
|
||||||
// Init comm pins
|
|
||||||
pinMode(EN, INPUT);
|
|
||||||
pinMode(RS, INPUT);
|
|
||||||
for(int pin = 0; pin < 8; pin++) {
|
|
||||||
pinMode(DATA[pin], INPUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init VGA
|
|
||||||
TV.begin(PAL,120,96);
|
|
||||||
TV.select_font(font4x6);
|
|
||||||
|
|
||||||
TV.println("TV init");
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
bool newClkState = digitalRead(EN);
|
|
||||||
if (newClkState == false && clkState == true) {
|
|
||||||
// Falling edge: read data from bus
|
|
||||||
onClk();
|
|
||||||
}
|
|
||||||
clkState = newClkState;
|
|
||||||
}
|
|
||||||
|
|
||||||
void onClk() {
|
|
||||||
bool isCommand = digitalRead(RS);
|
|
||||||
if (isCommand) {
|
|
||||||
//onCommandReceived();
|
|
||||||
onDataReceived();
|
|
||||||
} else {
|
|
||||||
onDataReceived();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void onCommandReceived() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void onDataReceived() {
|
|
||||||
char ch = readByte();
|
|
||||||
TV.print(ch);
|
|
||||||
Serial.println(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte readByte() {
|
|
||||||
unsigned int data = 0;
|
|
||||||
for(int pin=0; pin < 8; pin++) {
|
|
||||||
byte b = digitalRead(DATA[pin]) ? 1 : 0;
|
|
||||||
data = (data << 1) + b; // Shifta di 1 e aggiunge il bit corrente. Serve per ricostruire il numero da binario
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user