diff --git a/programs/ps2_keyboard_printer.s65 b/programs/ps2_keyboard_printer.s65 new file mode 100644 index 0000000..650f1e3 --- /dev/null +++ b/programs/ps2_keyboard_printer.s65 @@ -0,0 +1,33 @@ +.include "lcd.h65" +.include "ps2_keyboard_text_handler.h65" + +.export ps2_keyboard_printer + +.import home:absolute + +.code +.proc ps2_keyboard_printer + jsr lcd::clear + jsr kb::init +loop: + lda kb::char + beq @no_char + stz kb::char + jsr lcd::print_char + bra loop +@no_char: + lda kb::keycode + beq loop + + cmp #kb::K::ESCAPE + beq @esacpe + cmp #kb::K::PRINT + beq @clear_display + bra loop +@esacpe: + jmp home +@clear_display: + jsr lcd::clear + bra loop +.endproc + diff --git a/programs/ps2_keyboard_simple_handler.h65 b/programs/ps2_keyboard_simple_handler.h65 new file mode 100644 index 0000000..c50d3d2 --- /dev/null +++ b/programs/ps2_keyboard_simple_handler.h65 @@ -0,0 +1,33 @@ +;;******************************************************************************** +;; @module ps2_keyboard_simple_handler +;; @type system +;; @details: +;; This module processes keyboard scancodes from the ps2_keyboard driver. +;; It requires a PS/2 keyboard that supports scancode set 3. +;; +;; @section What it does +;; - swallow break (release) scancodes +;; +;; This handler is designed for debug purposes. +;; +;; @section How to use it +;; Call `kb::init` and check if it was successful (Z = 1). +;; In your program loop, check if kb::scancode is 0. If it is not, a key has been pressed. +;; +;; @subsection Changing the keyboard behaviour +;; You can change the typematic rate and delay (see PS/2 keyboard command 0xF3) +;; and the typematic behavior (make, make/release, typematic) for all keys. +;; +;; You may also send the echo (0xEE) and identify (0xF2) commands to the keyboard. +;;******************************************************************************** +.ifndef INCLUDE_KEYBOARD_SIMPLE +INCLUDE_KEYBOARD_SIMPLE = 1 + +.include "ps2_keyboard.h65" + +.scope skb +Import skb, init, scancode + +K_BREAK = $F0 +.endscope +.endif ; guard diff --git a/programs/ps2_keyboard_simple_handler.s65 b/programs/ps2_keyboard_simple_handler.s65 new file mode 100644 index 0000000..a99e3f5 --- /dev/null +++ b/programs/ps2_keyboard_simple_handler.s65 @@ -0,0 +1,77 @@ +.include "ps2_keyboard_simple_handler.h65" +Export skb, init, scancode + +.bss +previous_scancode: .res 1 ; all 1 if previous_scancode is break +scancode: .res 1 + +.code +;;******************************************************************************** +;; @function Initialize the keyboard handler +;; @returns Z: Z = 1 => success, Z = 0 => failure +;; @details: +;; Initializes the PS/2 keyboard driver and the handler. +;; If any PS/2 command fails, init returns with Z = 0. The failed command (and parameter) can be loaded from `ps2kb::send_cmd` and `ps2kb::send_data` +;; After init, the keyboard will be able to send scancodes. +;;******************************************************************************** +.proc init + stz scancode + stz previous_scancode + + jsr ps2kb::init + + ; init & reset + ps2kb_CmdSelfTest + ps2kb_WaitFinishCmd + lda ps2kb::cmd_response+1 + cmp #$aa + bne fail + ; set set 3 + ps2kb_CmdSetScancodeSet 3 + ps2kb_WaitFinishCmd + lda ps2kb::cmd_response+1 + cmp #ps2kb::ACK + bne fail + + ps2kb_CmdEnable + ps2kb_WaitFinishCmd + lda ps2kb::cmd_response + cmp #ps2kb::ACK + bne fail + + StoreDByte process_scancode, ps2kb::scancode_handler + jsr ps2kb::begin_receive + lda #0 ; set Z = success +fail: + rts +.endproc + + +;;******************************************************************************** +;; @function Process a scancode +;; @details +;; If it is a 'make' scancode, store it in skb::scancode +;; If the key is not a mod key, the keycode is stored in kb::keycode +;; If the key is an ascii character, the corresponding ascii character is stored in kb::char +;; @param X: The scancode +;; @modifies A, X, Y +;;******************************************************************************** +.proc process_scancode + ; check how this scancode needs to be interpreted + bit previous_scancode + jmi break_key ; bit 7 set = BREAK + + lda ps2kb::scancode + cmp #skb::K_BREAK + beq @break_scancode + + sta scancode + rts +@break_scancode: + lda #$ff + sta previous_scancode + rts +break_key: + stz previous_scancode + rts +.endproc diff --git a/programs/ps2_keyboard_util.s65 b/programs/ps2_keyboard_util.s65 new file mode 100644 index 0000000..09217e6 --- /dev/null +++ b/programs/ps2_keyboard_util.s65 @@ -0,0 +1,135 @@ +.include "system.h65" +.include "string.h65" +.include "keypad.h65" +.include "lcd.h65" +.include "ps2_keyboard_simple_handler.h65" +.include "ps2_keyboard_text_handler.h65" + +.export ps2_keyboard_util + +.import home:absolute + +.code +.proc ps2_keyboard_util + stz kp::_DEBUG_VAL + jsr skb::init + beq print_menu + ps2kb_PrintCmdFailed + bra loop +print_menu: + Print MENU +loop: + wai + lda skb::scancode + beq @read_keypad + Printf FMT_CODE,skb::scancode + stz skb::scancode +@read_keypad: + lda kp::_DEBUG_VAL + jeq loop + stz kp::_DEBUG_VAL + cmp #'*' + jeq home + pha + jsr lcd::clear + pla + ldy #0 ; arg for commands + ldx #ps2kb::NO_DATA + cmp #'0' + beq @l0 + cmp #'1' + beq @l1 + cmp #'2' + beq @l2 + cmp #'3' + beq @l3 + cmp #'4' + beq @l4 + cmp #'5' + beq @l5 + cmp #'6' + beq @l6 + cmp #'7' + beq @l7 + cmp #'8' + beq @l8 + cmp #'9' + beq @l9 + cmp #'#' + beq @lhash + cmp #'A' + beq @lA + cmp #'B' + beq @lB + cmp #'C' + beq @lC + cmp #'D' + beq @lD + jsr lcd::print_char + jmp loop +@l0: ; get scancode set + lda #$f0 + ldx #0 + ldy #1 + bra @send_cmd +@l1: ; echo + lda #$ee + bra @send_cmd +@l2: ; identify + lda #$f2 + ldy #2 + bra @send_cmd +@l3: ; set typematic min speed and delay + lda #$f3 + ldx #%01111111 + bra @send_cmd +@l4: ; enable + lda #$f4 + bra @send_cmd +@l5: ; disable + lda #$f5 + bra @send_cmd +@l6: ; set typematic max speed and min delay + lda #$f3 + ldx #0 + bra @send_cmd +@l7: ; set typematic all + lda #$f7 + bra @send_cmd +@l8: ; set make/release all + lda #$f8 + bra @send_cmd +@l9: ; set CAPSLOCK + lda #$ed + ldx #kb::MOD::CAPSLOCK + bra @send_cmd +@lhash: ; set SCROLLLOCK led + lda #$ed + ldx #kb::MOD::SCROLLLOCK + bra @send_cmd +@lC: ; set NUMLOCK led + lda #$ed + ldx #kb::MOD::NUMLOCK + bra @send_cmd +@lD: ; turn all leds off + lda #$ed + ldx #0 + bra @send_cmd +@lA: + ; TODO +@lB: ; reprint menu + jmp print_menu +@send_cmd: + jsr ps2kb::send_command + ps2kb_WaitFinishCmd + Printf FMT_CMD_DATA, ps2kb::send_cmd, ps2kb::send_data, ps2kb::cmd_response, ps2kb::cmd_response+1, ps2kb::cmd_response+2 + jmp loop +.endproc + +.rodata +FMT_CODE: .asciiz "K %x " +FMT_CMD_DATA: .asciiz "C %x-%x > %x%x%x" +MENU: .byte " EE F2 F3 " + .byte " F4 F5 F3' MEN" + .byte " T1 T0 LC LN " + .asciiz " RET F0 LS L0 "