Compare commits
No commits in common. "5c02ff65858dc5d348c666e9731b34d77f40dc99" and "326b2f624794582b39625b7241ae02f0e8c9da6b" have entirely different histories.
5c02ff6585
...
326b2f6247
@ -1,33 +0,0 @@
|
|||||||
.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
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
|||||||
;;********************************************************************************
|
|
||||||
;; @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
|
|
@ -1,77 +0,0 @@
|
|||||||
.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
|
|
@ -1,189 +0,0 @@
|
|||||||
;;********************************************************************************
|
|
||||||
;; @module ps2_keyboard_text_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
|
|
||||||
;; - keeps track of modifier keys: shift, left/right alt, left right meta (super),
|
|
||||||
;; control, capslock, numlock, scrollock
|
|
||||||
;; - convert valid keycodes to chars, dependening on the state of shift and right alt
|
|
||||||
;; - update the keyboard LEDs (numlock, capslock,, scrolllock)
|
|
||||||
|
|
||||||
;; This handler is designed for efficient text input.
|
|
||||||
;; It does not track the status of the keys (except modifiers) and is therefore not suitable for games.
|
|
||||||
;;
|
|
||||||
;; @section How it works
|
|
||||||
;; In the init function, the module disables the typematic behaviour for the modifier keys by
|
|
||||||
;; sending commands to the keyboard. The 3 lock keys will be set to make only mode and
|
|
||||||
;; the others to make release.
|
|
||||||
;; This makes tracking the modifier keys much easier and is the reason why scancode set 3
|
|
||||||
;; is required, as these commands are only available with that.
|
|
||||||
;;
|
|
||||||
;; Using scancode set 3 also adds the benefit that all scancodes are only 1 byte large,
|
|
||||||
;; making the recognition of scancodes trivial.
|
|
||||||
;;
|
|
||||||
;; Scancodes from the keyboard are processed immediately, as the handling functions is called
|
|
||||||
;; from the keyboard's interrupt handler.
|
|
||||||
;;
|
|
||||||
;; @subsection Mapping keycodes to chars
|
|
||||||
;; The mapping of keycodes to chars is done using an array of chars for each state:
|
|
||||||
;; default, shift and right alt. The tables contains the ascii characters, 0 where the keycode does not
|
|
||||||
;; generate a character and 1 where the keycode is modifier key.
|
|
||||||
;; This approach consumes a relatively large amount of ROM (3 * 144 bytes), but is super fast,
|
|
||||||
;; as loading a character is merely one indexed load instruction.
|
|
||||||
;; Checking for mod keys is now also fast, beceause we only have to do 1 comparison to see IF it is a modifier key.
|
|
||||||
;;
|
|
||||||
;; @section How to use it
|
|
||||||
;; Call `kb::init` and check if it was successful (Z = 1).
|
|
||||||
;; In your program loop, check if kb::keycode is 0. If it is not, a key has been pressed.
|
|
||||||
;;
|
|
||||||
;; If the keypress generated a character `kb::char` will be non-zero and contain the character.
|
|
||||||
;;
|
|
||||||
;; Note that if you will probably want to write a 0 to `kb::keycode` and `kb::char`
|
|
||||||
;; after processing the keycode. This will not be done by the handler.
|
|
||||||
;;
|
|
||||||
;; Conditional branches based on the status of a modifier (SHIFT, RALT, LALT, CTRL, META, NUMLOCK, SCROLLLOCK) can be done
|
|
||||||
;; using the `bbs` and `bbr` instructions, as each modifier is represented by a bit of the `kb::modifier` variable
|
|
||||||
;; in the zeropage.
|
|
||||||
;;
|
|
||||||
;; @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 except the modifier keys.
|
|
||||||
;;
|
|
||||||
;; You may also send the echo (0xEE) and identify (0xF2) commands to the keyboard.
|
|
||||||
;;********************************************************************************
|
|
||||||
.ifndef INCLUDE_KEYBOARD_TEXT
|
|
||||||
INCLUDE_KEYBOARD_TEXT = 1
|
|
||||||
|
|
||||||
.include "ps2_keyboard.h65"
|
|
||||||
|
|
||||||
.scope kb
|
|
||||||
Import kb, init, char, keycode
|
|
||||||
Import kb, CHARS_NOMOD, CHARS_MODRALT, CHARS_MODSHIFT, CHARS_NUMLOCK_OFF, CHARS_NUMLOCK_ON
|
|
||||||
ImportZp kb, modifier
|
|
||||||
|
|
||||||
.enum MOD
|
|
||||||
SHIFT = %10000000 ; set if either capslock is on or shift is pressed
|
|
||||||
RALT = %01000000 ; set while rightalt is pressed
|
|
||||||
LALT = %00100000 ; set while leftalt is pressed
|
|
||||||
META = %00010000 ; set while left or right meta is pressed
|
|
||||||
CTRL = %00001000 ; set while left or right ctrl is pressed
|
|
||||||
CAPSLOCK = %00000100 ; ps/2 LED
|
|
||||||
NUMLOCK = %00000010 ; ps/2 LED
|
|
||||||
SCROLLLOCK = %00000001 ; ps/2 LED
|
|
||||||
.endenum
|
|
||||||
|
|
||||||
K_BREAK = $F0
|
|
||||||
|
|
||||||
.enum K
|
|
||||||
F1 = $07
|
|
||||||
ESCAPE = $08
|
|
||||||
TAB = $0D
|
|
||||||
GRAVE = $0E
|
|
||||||
F2 = $0F
|
|
||||||
LEFTCTRL = $11
|
|
||||||
LEFTSHIFT = $12
|
|
||||||
CAPSLOCK = $14
|
|
||||||
K_Q = $15
|
|
||||||
K_1 = $16
|
|
||||||
F3 = $17
|
|
||||||
LEFTALT = $19
|
|
||||||
K_Y = $1A
|
|
||||||
K_S = $1B
|
|
||||||
K_A = $1C
|
|
||||||
K_W = $1D
|
|
||||||
K_2 = $1E
|
|
||||||
F4 = $1F
|
|
||||||
K_C = $21
|
|
||||||
K_X = $22
|
|
||||||
K_D = $23
|
|
||||||
K_E = $24
|
|
||||||
K_4 = $25
|
|
||||||
K_3 = $26
|
|
||||||
F5 = $27
|
|
||||||
SPACE = $29
|
|
||||||
K_V = $2A
|
|
||||||
K_F = $2B
|
|
||||||
K_T = $2C
|
|
||||||
K_R = $2D
|
|
||||||
K_5 = $2E
|
|
||||||
F6 = $2F
|
|
||||||
K_N = $31
|
|
||||||
K_B = $32
|
|
||||||
K_H = $33
|
|
||||||
K_G = $34
|
|
||||||
K_Z = $35
|
|
||||||
K_6 = $36
|
|
||||||
F7 = $37
|
|
||||||
RIGHTALT = $39
|
|
||||||
K_M = $3A
|
|
||||||
K_J = $3B
|
|
||||||
K_U = $3C
|
|
||||||
K_7 = $3D
|
|
||||||
K_8 = $3E
|
|
||||||
F8 = $3F
|
|
||||||
COMMA = $41
|
|
||||||
K_K = $42
|
|
||||||
K_I = $43
|
|
||||||
K_O = $44
|
|
||||||
K_0 = $45
|
|
||||||
K_9 = $46
|
|
||||||
F9 = $47
|
|
||||||
DOT = $49
|
|
||||||
DASH = $4A
|
|
||||||
KPDIVIDE = $4A
|
|
||||||
K_L = $4B
|
|
||||||
OUML = $4C
|
|
||||||
K_P = $4D
|
|
||||||
SSHARP = $4E
|
|
||||||
KPMINUS = $4E
|
|
||||||
F10 = $4F
|
|
||||||
AUML = $52
|
|
||||||
UUML = $54
|
|
||||||
BACKTICK = $55
|
|
||||||
F11 = $56
|
|
||||||
PRINT = $57
|
|
||||||
RIGHTCTRL = $58
|
|
||||||
RIGHTSHIFT = $59
|
|
||||||
ENTER = $5A
|
|
||||||
PLUS = $5B
|
|
||||||
LESSTHAN = $5C
|
|
||||||
HASH = $5D
|
|
||||||
F12 = $5E
|
|
||||||
SCROLLLOCK = $5F
|
|
||||||
RIGHT = $60
|
|
||||||
LEFT = $61
|
|
||||||
PAUSE = $62
|
|
||||||
UP = $63
|
|
||||||
DELETE = $64
|
|
||||||
END = $65
|
|
||||||
BACKSPACE = $66
|
|
||||||
INSERT = $67
|
|
||||||
KP1 = $69
|
|
||||||
DOWN = $6A
|
|
||||||
KP4 = $6B
|
|
||||||
KP7 = $6C
|
|
||||||
PAGEDOWN = $6D
|
|
||||||
POS1 = $6E
|
|
||||||
PAGEUP = $6F
|
|
||||||
KP0 = $70
|
|
||||||
KPDOT = $71
|
|
||||||
KP2 = $72
|
|
||||||
KP5 = $73
|
|
||||||
KP6 = $74
|
|
||||||
KP8 = $75
|
|
||||||
NUMLOCK = $76
|
|
||||||
KPENTER = $79
|
|
||||||
KP3 = $7A
|
|
||||||
KPPLUS = $7C
|
|
||||||
KP9 = $7D
|
|
||||||
KPASTERISK = $7E
|
|
||||||
LEFTMETA = $8B
|
|
||||||
RIGHTMETA = $8C
|
|
||||||
MENU = $8D
|
|
||||||
.endenum
|
|
||||||
|
|
||||||
.endscope
|
|
||||||
.endif ; guard
|
|
@ -1,306 +0,0 @@
|
|||||||
.include "ps2_keyboard_text_handler.h65"
|
|
||||||
Export kb, init, char, keycode
|
|
||||||
Export kb, CHARS_NOMOD, CHARS_MODRALT, CHARS_MODSHIFT, CHARS_NUMLOCK_OFF, CHARS_NUMLOCK_ON
|
|
||||||
ExportZp kb, modifier
|
|
||||||
|
|
||||||
.zeropage
|
|
||||||
modifier: .res 1
|
|
||||||
.bss
|
|
||||||
previous_scancode: .res 1 ; all 1 if previous_scancode is break
|
|
||||||
char: .res 1
|
|
||||||
keycode: .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.
|
|
||||||
;; @modifies A, X, Y
|
|
||||||
;;********************************************************************************
|
|
||||||
.proc init
|
|
||||||
stz modifier
|
|
||||||
stz char
|
|
||||||
stz keycode
|
|
||||||
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
|
|
||||||
|
|
||||||
; toggle-behaving keys
|
|
||||||
ldx #kb::K::CAPSLOCK
|
|
||||||
jsr set_make
|
|
||||||
ldx #kb::K::NUMLOCK
|
|
||||||
jsr set_make
|
|
||||||
ldx #kb::K::SCROLLLOCK
|
|
||||||
jsr set_make
|
|
||||||
|
|
||||||
; modifiers
|
|
||||||
ldx #kb::K::LEFTSHIFT
|
|
||||||
jsr set_make_release
|
|
||||||
ldx #kb::K::RIGHTSHIFT
|
|
||||||
jsr set_make_release
|
|
||||||
ldx #kb::K::LEFTCTRL
|
|
||||||
jsr set_make_release
|
|
||||||
ldx #kb::K::RIGHTCTRL
|
|
||||||
jsr set_make_release
|
|
||||||
ldx #kb::K::LEFTALT
|
|
||||||
jsr set_make_release
|
|
||||||
ldx #kb::K::RIGHTALT
|
|
||||||
jsr set_make_release
|
|
||||||
ldx #kb::K::LEFTMETA
|
|
||||||
jsr set_make_release
|
|
||||||
ldx #kb::K::RIGHTMETA
|
|
||||||
jsr set_make_release
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
set_make:
|
|
||||||
; x must be set to scancode
|
|
||||||
lda #$fd
|
|
||||||
bra set
|
|
||||||
set_make_release:
|
|
||||||
; x must be set to scancode
|
|
||||||
lda #$fc
|
|
||||||
set:
|
|
||||||
ldy #0
|
|
||||||
jsr ps2kb::send_command
|
|
||||||
ps2kb_WaitFinishCmd
|
|
||||||
lda ps2kb::cmd_response+1
|
|
||||||
cmp #ps2kb::ACK
|
|
||||||
bne fail
|
|
||||||
rts
|
|
||||||
.endproc
|
|
||||||
|
|
||||||
|
|
||||||
;;********************************************************************************
|
|
||||||
;; @function Process a scancode
|
|
||||||
;; @details
|
|
||||||
;; Update modifier bits if a mod key is pressed.
|
|
||||||
;; 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
|
|
||||||
;; @modifies A, X
|
|
||||||
;;********************************************************************************
|
|
||||||
.proc process_scancode
|
|
||||||
; check how this scancode needs to be interpreted
|
|
||||||
ldx ps2kb::scancode
|
|
||||||
bit previous_scancode
|
|
||||||
jmi break_key ; bit 7 set = BREAK
|
|
||||||
|
|
||||||
cmp #$90 ; only BREAK is higher than 8F, (also code table only has 8F bytes)
|
|
||||||
bcs check_release
|
|
||||||
cmp #$60 ; codes >= 60 in separate table to reduce memory consumption
|
|
||||||
bcs upper_range
|
|
||||||
bbs kb::MOD::SHIFT, modifier, modshift ; if shift active
|
|
||||||
bbs kb::MOD::RALT, modifier, modralt ; if ralt active
|
|
||||||
|
|
||||||
; load from the correct table, if 0 => non-char, if 1 => non-char but mod, else char
|
|
||||||
nomod:
|
|
||||||
lda CHARS_NOMOD,x
|
|
||||||
bra check_char
|
|
||||||
upper_range:
|
|
||||||
bbs kb::MOD::NUMLOCK, modifier, modnumlock ; if numlock active
|
|
||||||
; numlock off
|
|
||||||
lda CHARS_NUMLOCK_OFF,x
|
|
||||||
bra check_char
|
|
||||||
modnumlock:
|
|
||||||
lda CHARS_NUMLOCK_ON,x
|
|
||||||
bra check_char
|
|
||||||
modshift:
|
|
||||||
lda CHARS_MODSHIFT,x
|
|
||||||
bra check_char
|
|
||||||
modralt:
|
|
||||||
lda CHARS_MODRALT,x
|
|
||||||
check_char:
|
|
||||||
beq not_mod ; 0 => not mod and not char
|
|
||||||
cmp #1 ; 1 => mod
|
|
||||||
beq is_mod
|
|
||||||
@char: ; store char
|
|
||||||
sta char
|
|
||||||
not_mod: ; store keycode if not mod
|
|
||||||
stx keycode
|
|
||||||
_rts:
|
|
||||||
rts
|
|
||||||
|
|
||||||
check_release:
|
|
||||||
cmp #kb::K_BREAK
|
|
||||||
bne _rts
|
|
||||||
lda #$ff
|
|
||||||
sta previous_scancode
|
|
||||||
rts
|
|
||||||
|
|
||||||
is_mod:
|
|
||||||
; check which mod
|
|
||||||
cpx #kb::K::LEFTSHIFT
|
|
||||||
beq set_shift
|
|
||||||
cpx #kb::K::RIGHTSHIFT
|
|
||||||
beq set_shift
|
|
||||||
cpx #kb::K::RIGHTALT
|
|
||||||
beq set_rightalt
|
|
||||||
cpx #kb::K::LEFTALT
|
|
||||||
beq set_leftalt
|
|
||||||
cpx #kb::K::RIGHTMETA
|
|
||||||
beq set_meta
|
|
||||||
cpx #kb::K::LEFTMETA
|
|
||||||
beq set_meta
|
|
||||||
cpx #kb::K::RIGHTCTRL
|
|
||||||
beq set_ctrl
|
|
||||||
cpx #kb::K::LEFTCTRL
|
|
||||||
beq set_ctrl
|
|
||||||
cpx #kb::K::CAPSLOCK
|
|
||||||
beq toggle_capslock
|
|
||||||
cpx #kb::K::NUMLOCK
|
|
||||||
beq toggle_numlock
|
|
||||||
cpx #kb::K::SCROLLLOCK
|
|
||||||
beq toggle_scrolllock
|
|
||||||
|
|
||||||
; a real keycode and not a released keycode, twobyte or release scancode
|
|
||||||
|
|
||||||
set_ctrl:
|
|
||||||
smb kb::MOD::CTRL, modifier
|
|
||||||
rts
|
|
||||||
set_meta:
|
|
||||||
smb kb::MOD::META, modifier
|
|
||||||
rts
|
|
||||||
set_leftalt:
|
|
||||||
smb kb::MOD::LALT, modifier
|
|
||||||
rts
|
|
||||||
set_rightalt:
|
|
||||||
smb kb::MOD::RALT, modifier
|
|
||||||
rts
|
|
||||||
set_shift: ; process shift
|
|
||||||
bbs kb::MOD::CAPSLOCK, modifier, @unset_shift ; CAPSLOCK unset shift when capslock is on
|
|
||||||
@set_shift:
|
|
||||||
smb kb::MOD::SHIFT, modifier
|
|
||||||
rts
|
|
||||||
@unset_shift:
|
|
||||||
rmb kb::MOD::SHIFT, modifier
|
|
||||||
rts
|
|
||||||
|
|
||||||
toggle_numlock: ; toggle numlock
|
|
||||||
lda modifier
|
|
||||||
eor #kb::MOD::NUMLOCK
|
|
||||||
sta modifier
|
|
||||||
bra update_leds
|
|
||||||
toggle_scrolllock: ; toggle numlock
|
|
||||||
lda modifier
|
|
||||||
eor #kb::MOD::SCROLLLOCK
|
|
||||||
sta modifier
|
|
||||||
bra update_leds
|
|
||||||
toggle_capslock: ; toggle capslock & shift
|
|
||||||
lda modifier
|
|
||||||
eor #(kb::MOD::CAPSLOCK | kb::MOD::SHIFT)
|
|
||||||
sta modifier
|
|
||||||
; fallthrough
|
|
||||||
load_update_leds:
|
|
||||||
lda modifier
|
|
||||||
update_leds:
|
|
||||||
and #%00000111 ; only bottom 3 bits allowed - otherwise command fails
|
|
||||||
tax
|
|
||||||
ps2kb_CmdSetLeds
|
|
||||||
rts
|
|
||||||
.endproc
|
|
||||||
|
|
||||||
;;********************************************************************************
|
|
||||||
;; @details
|
|
||||||
;; Unset modifier bits if a mod key is released.
|
|
||||||
;; @param X: The scancode
|
|
||||||
;; @modifies:
|
|
||||||
;;********************************************************************************
|
|
||||||
.proc break_key
|
|
||||||
; rmb kb::PREVIOUS::BREAK, kb::previous_scancode
|
|
||||||
stz previous_scancode
|
|
||||||
|
|
||||||
; check mod keys
|
|
||||||
cpx #kb::K::LEFTSHIFT
|
|
||||||
beq unset_shift
|
|
||||||
cpx #kb::K::RIGHTSHIFT
|
|
||||||
beq unset_shift
|
|
||||||
cpx #kb::K::RIGHTALT
|
|
||||||
beq unset_rightalt
|
|
||||||
cpx #kb::K::LEFTALT
|
|
||||||
beq unset_leftalt
|
|
||||||
cpx #kb::K::RIGHTMETA
|
|
||||||
beq unset_meta
|
|
||||||
cpx #kb::K::LEFTMETA
|
|
||||||
beq unset_meta
|
|
||||||
cpx #kb::K::RIGHTCTRL
|
|
||||||
beq unset_ctrl
|
|
||||||
cpx #kb::K::LEFTCTRL
|
|
||||||
rts
|
|
||||||
unset_shift: ; process shift
|
|
||||||
bbs kb::MOD::CAPSLOCK, modifier, @set_shift ; set shift when capslock is on
|
|
||||||
rmb kb::MOD::SHIFT, modifier ; unset if capslock is off
|
|
||||||
rts
|
|
||||||
@set_shift:
|
|
||||||
smb kb::MOD::SHIFT, modifier
|
|
||||||
rts
|
|
||||||
unset_ctrl:
|
|
||||||
rmb kb::MOD::CTRL, modifier
|
|
||||||
rts
|
|
||||||
unset_meta:
|
|
||||||
rmb kb::MOD::META, modifier
|
|
||||||
rts
|
|
||||||
unset_leftalt:
|
|
||||||
rmb kb::MOD::LALT, modifier
|
|
||||||
rts
|
|
||||||
unset_rightalt:
|
|
||||||
rmb kb::MOD::RALT, modifier
|
|
||||||
rts
|
|
||||||
.endproc
|
|
||||||
|
|
||||||
.rodata
|
|
||||||
.align 256
|
|
||||||
CHARS_NOMOD:
|
|
||||||
.byte "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00^\x00"
|
|
||||||
.byte "\x00\x01\x01<\x01q1\x00\x00\x01ysaw2\x00"
|
|
||||||
.byte "\x00cxde43\x00\x00 vftr5\x00"
|
|
||||||
.byte "\x00nbhgz6\x00\x00\x01mju78\x00"
|
|
||||||
.byte "\x00,kio09\x00\x00.-l\xEFp\xE2\x00"
|
|
||||||
.byte "\x00\x00\xE1#\xF5`\x00\x00\x01\x01\x00\x00\x00\x00\x00\x01"
|
|
||||||
CHARS_MODSHIFT:
|
|
||||||
.byte "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xDF\x00"
|
|
||||||
.byte "\x00\x01\x01>\x01Q!\x00\x00\x01YSAW\"\x00"
|
|
||||||
.byte "\x00CXDE$\xED\x00\x00 VFTR%\x00"
|
|
||||||
.byte "\x00NBHGZ&\x00\x00\x01MJU/(\x00"
|
|
||||||
.byte "\x00;KIO=)\x00\x00:_L\xEFP\xE2\x00"
|
|
||||||
.byte "\x00\x00\xE1'\xF5`\x00\x00\x01\x01\x00\x00\x00\x00\x00\x01"
|
|
||||||
CHARS_MODRALT:
|
|
||||||
.byte "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00"
|
|
||||||
.byte "\x00\x01\x01|\x01\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
|
|
||||||
.byte "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
||||||
.byte "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00{[\x00"
|
|
||||||
.byte "\x00\x00\x00\x00\x00}]\x00\x00\xA5\xB0\x00\x00\x00\x00\x00"
|
|
||||||
.byte "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x01"
|
|
||||||
CHARS_NUMLOCK_OFF:
|
|
||||||
.byte "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
||||||
.byte "\x00\x00\x00\x00\x00\x00\x01/\x00\x00\x00\x00+\x00*\x00"
|
|
||||||
.byte "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00-\x00"
|
|
||||||
CHARS_NUMLOCK_ON:
|
|
||||||
.byte "\x00\x00\x00\x00\x00\x00\x00\x00\x001\x0047\x00\x00\x00"
|
|
||||||
.byte "0.2568\x01\x00\x00\x003\x00\x009\x00\x00"
|
|
||||||
.byte "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00"
|
|
@ -1,135 +0,0 @@
|
|||||||
.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 "
|
|
@ -1,5 +1,5 @@
|
|||||||
# 8-bit Breadboard Computer with W65C02S Processor
|
# 8-bit Breadboard Computer with W65C02S Processor
|
||||||
This repo contains the assembly code for my [6502-project](https://quintern.xyz/de/posts/2021_6502).
|
This repo contains the assembly code for my [6502-project](https://quintern.xyz/de/6502.html).
|
||||||
|
|
||||||
The assembler used for this project is the excellent [ca65](https://github.com/cc65/cc65).
|
The assembler used for this project is the excellent [ca65](https://github.com/cc65/cc65).
|
||||||
After assembling it, the binary is loaded onto the EEPROM using [my *eeprom.py* script](https://git.quintern.xyz/MatthiasQuintern/AT28C256-rpi-util) on a Raspberry Pi 4B.
|
After assembling it, the binary is loaded onto the EEPROM using [my *eeprom.py* script](https://git.quintern.xyz/MatthiasQuintern/AT28C256-rpi-util) on a Raspberry Pi 4B.
|
||||||
|
490
spicode.s65
490
spicode.s65
@ -3,14 +3,12 @@
|
|||||||
.include "lcd.h65"
|
.include "lcd.h65"
|
||||||
.include "math.h65"
|
.include "math.h65"
|
||||||
.include "keypad.h65"
|
.include "keypad.h65"
|
||||||
.include "ps2_keyboard_text_handler.h65"
|
.include "keyboard_handler.h65"
|
||||||
.include "chars.h65"
|
.include "chars.h65"
|
||||||
.include "parity.h65"
|
.include "parity.h65"
|
||||||
.include "sleep.h65"
|
.include "sleep.h65"
|
||||||
.import homeloop:absolute
|
.import homeloop:absolute
|
||||||
.import home:absolute
|
.import home:absolute
|
||||||
.import ps2_keyboard_util:absolute
|
|
||||||
.import ps2_keyboard_printer:absolute
|
|
||||||
|
|
||||||
.segment "SPI"
|
.segment "SPI"
|
||||||
.export CODE_START
|
.export CODE_START
|
||||||
@ -22,43 +20,88 @@
|
|||||||
CODE_START:
|
CODE_START:
|
||||||
.assert * = $5000, error, "SPI Code not at $5000"
|
.assert * = $5000, error, "SPI Code not at $5000"
|
||||||
jsr lcd::clear
|
jsr lcd::clear
|
||||||
|
lda #'$'
|
||||||
|
jsr lcd::print_char
|
||||||
|
; jmp homeloop
|
||||||
DEBUG_LED_OFF 0
|
DEBUG_LED_OFF 0
|
||||||
DEBUG_LED_OFF 1
|
DEBUG_LED_OFF 1
|
||||||
DEBUG_LED_OFF 2
|
DEBUG_LED_OFF 2
|
||||||
|
|
||||||
stz kp::_DEBUG_VAL
|
StoreDByte _process_cmd_answer, $3200
|
||||||
lda #'$'
|
|
||||||
|
|
||||||
|
jsr ps2kb::init
|
||||||
|
stz kb::status
|
||||||
|
StoreDByte process_scancode,ps2kb::scancode_handler
|
||||||
|
; jsr ps2kb::begin_receive
|
||||||
|
JsrIndirect @a1, @a2
|
||||||
|
stp
|
||||||
|
stp
|
||||||
|
stp
|
||||||
|
stp
|
||||||
|
stp
|
||||||
|
@a1:
|
||||||
|
lda #'1'
|
||||||
jsr lcd::print_char
|
jsr lcd::print_char
|
||||||
|
rts
|
||||||
|
stp
|
||||||
|
stp
|
||||||
|
stp
|
||||||
|
stp
|
||||||
|
@a2:
|
||||||
|
lda #'2'
|
||||||
|
jsr lcd::print_char
|
||||||
|
|
||||||
|
lda #'%'
|
||||||
|
jsr lcd::print_char
|
||||||
|
|
||||||
|
stz kp::_DEBUG_VAL
|
||||||
|
ldy #0
|
||||||
@loop:
|
@loop:
|
||||||
wai
|
wai
|
||||||
|
lda ps2kb::scancode
|
||||||
|
beq @noscancode
|
||||||
|
jsr process_scancode
|
||||||
|
stz ps2kb::scancode
|
||||||
|
lda char
|
||||||
|
beq @onlykeycode
|
||||||
|
Strf fmt_codechar,out_str,keycode,kb::status,char
|
||||||
|
PrintNC out_str
|
||||||
|
stz char
|
||||||
|
stz keycode
|
||||||
|
bra @noscancode
|
||||||
|
@onlykeycode:
|
||||||
|
lda keycode
|
||||||
|
beq @noscancode
|
||||||
|
Strf fmt_code,out_str,keycode,keycode_flags
|
||||||
|
PrintNC out_str
|
||||||
|
stz keycode
|
||||||
|
@noscancode:
|
||||||
|
bbr5 kb::status, @shift_off
|
||||||
|
@shift_on:
|
||||||
|
; DEBUG_LED_ON 0
|
||||||
|
bra @check_caps
|
||||||
|
@shift_off:
|
||||||
|
; DEBUG_LED_OFF 0
|
||||||
|
@check_caps:
|
||||||
|
bbr4 kb::status, @caps_off
|
||||||
|
@caps_on:
|
||||||
|
; DEBUG_LED_ON 2
|
||||||
|
bra @read_keypad
|
||||||
|
@caps_off:
|
||||||
|
; DEBUG_LED_OFF 2
|
||||||
@read_keypad:
|
@read_keypad:
|
||||||
lda kp::_DEBUG_VAL
|
lda kp::_DEBUG_VAL
|
||||||
jeq @loop
|
jeq @loop
|
||||||
|
stz kp::_DEBUG_VAL
|
||||||
cmp #'*'
|
cmp #'*'
|
||||||
jeq homeloop
|
jeq homeloop
|
||||||
cmp #'0'
|
|
||||||
beq @l0
|
|
||||||
cmp #'1'
|
cmp #'1'
|
||||||
beq @l1
|
beq @l1
|
||||||
cmp #'2'
|
cmp #'2'
|
||||||
beq @l2
|
beq @l2
|
||||||
cmp #'3'
|
cmp #'3'
|
||||||
beq @l3
|
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'
|
cmp #'A'
|
||||||
beq @lA
|
beq @lA
|
||||||
cmp #'B'
|
cmp #'B'
|
||||||
@ -69,61 +112,378 @@ CODE_START:
|
|||||||
beq @lD
|
beq @lD
|
||||||
jsr lcd::print_char
|
jsr lcd::print_char
|
||||||
jmp @loop
|
jmp @loop
|
||||||
@l0:
|
|
||||||
jmp ps2_keyboard_util
|
|
||||||
@l1:
|
@l1:
|
||||||
jmp _ps2_keyboard_printer
|
; jsr irq_on_shift_reg
|
||||||
|
jsr $3000
|
||||||
|
lda #'*'
|
||||||
|
jsr lcd::print_char
|
||||||
|
jmp @loop
|
||||||
@l2:
|
@l2:
|
||||||
|
; jsr irq_on_timer
|
||||||
|
jsr $3100
|
||||||
|
lda #'#'
|
||||||
|
jsr lcd::print_char
|
||||||
|
jmp @loop
|
||||||
@l3:
|
@l3:
|
||||||
@l4:
|
lda $3000,y
|
||||||
@l5:
|
jsr lcd::print_char
|
||||||
@l6:
|
iny
|
||||||
@l7:
|
jmp @loop
|
||||||
@l8:
|
|
||||||
@l9:
|
|
||||||
@lhash:
|
|
||||||
@lA:
|
@lA:
|
||||||
|
jsr ps2kb::begin_receive
|
||||||
|
; StoreDByte _receive_irq_timer_handler, $3100
|
||||||
|
jmp @loop
|
||||||
@lB:
|
@lB:
|
||||||
|
; Printf "kc%x;", out_str, kb::scancode
|
||||||
|
jsr lcd::clear
|
||||||
|
ldx out_idx
|
||||||
|
lda #0
|
||||||
|
sta out_str,x
|
||||||
|
Print out_str
|
||||||
|
stz out_idx
|
||||||
|
|
||||||
|
jmp @loop
|
||||||
@lC:
|
@lC:
|
||||||
|
jsr lcd::clear
|
||||||
|
jmp @loop
|
||||||
@lD:
|
@lD:
|
||||||
|
lda ps2kb::STATUS::SEND_CMD
|
||||||
|
sta ps2kb::status
|
||||||
|
; lda #$ed
|
||||||
|
; ldx #%00000111
|
||||||
|
; lda #$f6
|
||||||
|
; lda #$ff
|
||||||
|
lda #$ee
|
||||||
|
; ldx #$ee
|
||||||
|
; ldx #0
|
||||||
|
ldx #ps2kb::NO_DATA
|
||||||
|
sta ps2kb::send_cmd
|
||||||
|
stx ps2kb::send_data
|
||||||
|
jsr _send_byte
|
||||||
|
; jsr ps2kb::send_command;
|
||||||
jmp @loop
|
jmp @loop
|
||||||
|
|
||||||
.proc _ps2_keyboard_printer
|
.byte '@'
|
||||||
jsr lcd::clear
|
|
||||||
jsr kb::init
|
|
||||||
jeq loop
|
|
||||||
ps2kb_PrintCmdFailed
|
|
||||||
; jmp homeloop
|
|
||||||
ps2kb_CmdEnable
|
|
||||||
jsr ps2kb::begin_receive
|
|
||||||
|
|
||||||
|
|
||||||
loop:
|
.proc process_scancode
|
||||||
lda kb::char
|
; DEBUG_LED_OFF 1
|
||||||
beq @no_char
|
; check how this scancode needs to be interpreted
|
||||||
stz kb::char
|
ldx ps2kb::scancode
|
||||||
|
bit kb::status
|
||||||
|
jmi release_key ; bit 7 set
|
||||||
|
bvs @twobytecode ; bit 6 set
|
||||||
|
; DEBUG_LED_ON 1
|
||||||
|
|
||||||
|
; check mods
|
||||||
|
cpx #kb::K_RELEASE
|
||||||
|
beq @code_release
|
||||||
|
cpx #kb::K::LEFTSHIFT
|
||||||
|
beq @code_shift
|
||||||
|
cpx #kb::K::RIGHTSHIFT
|
||||||
|
beq @code_shift
|
||||||
|
cpx #kb::K_TWOBYTE
|
||||||
|
beq @code_twobytecode
|
||||||
|
cpx #kb::K::CAPSLOCK
|
||||||
|
beq @code_capslock
|
||||||
|
|
||||||
|
; a real keycode and not a released keycode, twobyte or release scancode
|
||||||
|
stz keycode_flags
|
||||||
|
stx keycode
|
||||||
|
cmp #$62 ; $61 is the largest ascii scancode
|
||||||
|
bcs @special
|
||||||
|
bbs5 kb::status,@modshift ; if shift active
|
||||||
|
@nomod:
|
||||||
|
lda kb::CHARS_NOMOD,x
|
||||||
|
beq @special
|
||||||
|
@char: ; order which is fastet most of the time (lowercase characters)
|
||||||
|
sta char
|
||||||
|
rts
|
||||||
|
@modshift:
|
||||||
|
lda kb::CHARS_MODSHIFT,x
|
||||||
|
bne @char
|
||||||
|
@special:
|
||||||
|
rts
|
||||||
|
|
||||||
|
@code_release: ; set release
|
||||||
|
smb7 kb::status
|
||||||
|
rts
|
||||||
|
@code_twobytecode: ; set twobytecode
|
||||||
|
smb6 kb::status
|
||||||
|
rts
|
||||||
|
@code_shift: ; process shift
|
||||||
|
bbs4 kb::status, @unset_shift ; unset shift when capslock is on
|
||||||
|
@set_shift:
|
||||||
|
smb5 kb::status
|
||||||
|
rts
|
||||||
|
@unset_shift:
|
||||||
|
rmb5 kb::status
|
||||||
|
rts
|
||||||
|
@code_capslock: ; toggle capslock & shift
|
||||||
|
bbs1 kb::status, @rts ; ignore if held
|
||||||
|
lda kb::status
|
||||||
|
ora #(kb::STATUS::CAPSLOCK_HELD)
|
||||||
|
; toggle and capslock shift
|
||||||
|
eor #(kb::STATUS::CAPSLOCK | kb::STATUS::SHIFT)
|
||||||
|
sta kb::status
|
||||||
|
rts
|
||||||
|
@code_rightalt: ; set rightalt
|
||||||
|
smb3 kb::status
|
||||||
|
rts
|
||||||
|
@code_numlock: ; set numlock
|
||||||
|
smb2 kb::status
|
||||||
|
rts
|
||||||
|
|
||||||
|
@twobytecode:
|
||||||
|
rmb6 kb::status ; unset twobytecode
|
||||||
|
; check mods
|
||||||
|
cpx #kb::K2::RIGHTALT
|
||||||
|
beq @code_rightalt
|
||||||
|
|
||||||
|
lda #kb::STATUS::TWOBYTE
|
||||||
|
sta keycode_flags
|
||||||
|
stx keycode
|
||||||
|
@rts:
|
||||||
|
rts
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
;; @param S: The status register must be set through `bit kb::status`
|
||||||
|
;; @param X: The scancode
|
||||||
|
.proc release_key
|
||||||
|
bvs @twobytecode
|
||||||
|
rmb7 kb::status
|
||||||
|
|
||||||
|
; check mods
|
||||||
|
cpx #kb::K_TWOBYTE
|
||||||
|
beq @code_twobytecode
|
||||||
|
cpx #kb::K::LEFTSHIFT
|
||||||
|
beq @code_shift
|
||||||
|
cpx #kb::K::RIGHTSHIFT
|
||||||
|
beq @code_shift
|
||||||
|
cpx #kb::K::CAPSLOCK
|
||||||
|
beq @code_capslock
|
||||||
|
; no need to process capslock - it gets toggled when pressed
|
||||||
|
rts
|
||||||
|
@code_twobytecode: ; unset special
|
||||||
|
rmb6 kb::status
|
||||||
|
rts
|
||||||
|
@code_shift: ; process shift
|
||||||
|
bbs4 kb::status, @code_shift_caps ; set shift when capslock is on
|
||||||
|
rmb5 kb::status ; unset if capslock is off
|
||||||
|
rts
|
||||||
|
@code_shift_caps:
|
||||||
|
smb5 kb::status
|
||||||
|
rts
|
||||||
|
@code_capslock: ; unset CAPSLOCK_HELD
|
||||||
|
rmb1 kb::status
|
||||||
|
rts
|
||||||
|
@code_rightalt: ; unset rightalt
|
||||||
|
rmb3 kb::status
|
||||||
|
rts
|
||||||
|
@code_numlock: ; unset numlock
|
||||||
|
rmb2 kb::status
|
||||||
|
rts
|
||||||
|
|
||||||
|
@twobytecode:
|
||||||
|
rmb6 kb::status ; unset twobytecode
|
||||||
|
; check mods
|
||||||
|
cpx #kb::K2::RIGHTALT
|
||||||
|
beq @code_rightalt
|
||||||
|
rts
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; @macro Enable the clock signal from the keyboard
|
||||||
|
;; @modifies: A
|
||||||
|
;; @details
|
||||||
|
;; Stop pulling the keyboards clock low
|
||||||
|
;;********************************************************************************
|
||||||
|
.macro _EnableClock
|
||||||
|
; set pin to input
|
||||||
|
lda ps2kb::VIA + ps2kb::PULL_DDR
|
||||||
|
and #<~ps2kb::PULL_MASK_CLK
|
||||||
|
sta ps2kb::VIA + ps2kb::PULL_DDR
|
||||||
|
.endmacro
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; @macro Disable the clock signal from the keyboard
|
||||||
|
;; @modifies: A
|
||||||
|
;; @details
|
||||||
|
;; Pulls the keyboards clock low
|
||||||
|
;;********************************************************************************
|
||||||
|
.macro _DisableClock
|
||||||
|
; set pin to output
|
||||||
|
lda ps2kb::VIA + ps2kb::PULL_DDR
|
||||||
|
ora #ps2kb::PULL_MASK_CLK
|
||||||
|
sta ps2kb::VIA + ps2kb::PULL_DDR
|
||||||
|
; set pin low
|
||||||
|
lda ps2kb::VIA + ps2kb::PULL_REG
|
||||||
|
and #<~ps2kb::PULL_MASK_CLK
|
||||||
|
sta ps2kb::VIA + ps2kb::PULL_REG
|
||||||
|
.endmacro
|
||||||
|
|
||||||
|
|
||||||
|
.proc _send_byte
|
||||||
|
pha
|
||||||
|
IO_DisableIRQ ps2kb::VIA, (IO::IRQ::T2 | IO::IRQ::SR)
|
||||||
|
|
||||||
|
_DisableClock
|
||||||
|
|
||||||
|
lda #'X'
|
||||||
|
jsr lcd::print_char
|
||||||
|
|
||||||
|
; set shift register to output
|
||||||
|
lda ps2kb::VIA + IO::ACR
|
||||||
|
and #<~IO::ACR_MASK::SR
|
||||||
|
ora #IO::ACR::SR_SOUT_PHIE
|
||||||
|
sta ps2kb::VIA + IO::ACR
|
||||||
|
stz ps2kb::VIA + IO::SR
|
||||||
|
; shift out the startbit = data low
|
||||||
|
_EnableClock
|
||||||
|
_DisableClock
|
||||||
|
; reset shift register to start the count at 0 again
|
||||||
|
lda #IO::ACR::SR_SOUT_PHIE
|
||||||
|
trb ps2kb::VIA + IO::ACR
|
||||||
|
tsb ps2kb::VIA + IO::ACR
|
||||||
|
|
||||||
|
; setup the low timer byte
|
||||||
|
lda #<ps2kb::TIMER_SEND
|
||||||
|
sta ps2kb::VIA + IO::T2CL
|
||||||
|
|
||||||
|
; setup interrupt handlers
|
||||||
|
StoreDByte ps2kb::_send_irq_shift_reg_handler, $3000
|
||||||
|
; StoreDByte _send_irq_cb2_handler, $3020
|
||||||
|
; StoreDByte _send_irq_cb1_handler, $3040
|
||||||
|
StoreDByte _send_irq_timer_handler, $3060
|
||||||
|
pla
|
||||||
|
Reverse A
|
||||||
|
pha
|
||||||
|
CalculateOddParity
|
||||||
|
ror ; Parity -> C
|
||||||
|
lda #$ff
|
||||||
|
ror ; Parity -> bit 7, rest = 1
|
||||||
|
sta ps2kb::send_last_bits ; loaded into SR by irq handler
|
||||||
|
pla
|
||||||
|
sta ps2kb::VIA + IO::SR
|
||||||
|
IO_EnableIRQ ps2kb::VIA, IO::IRQ::SR
|
||||||
|
_EnableClock
|
||||||
|
rts
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
; .proc _send_irq_shift_reg_handler
|
||||||
|
; lda ps2kb::send_last_bits
|
||||||
|
; sta ps2kb::VIA + IO::SR
|
||||||
|
|
||||||
|
; IO_DisableIRQ ps2kb::VIA, IO::IRQ::SR
|
||||||
|
; IO_EnableIRQ ps2kb::VIA, IO::IRQ::T2
|
||||||
|
; ; start timer, low order count already in latch after init
|
||||||
|
; lda #>ps2kb::TIMER_SEND
|
||||||
|
; sta ps2kb::VIA + IO::T2CH
|
||||||
|
; rts
|
||||||
|
; .endproc
|
||||||
|
|
||||||
|
.proc _send_irq_timer_handler
|
||||||
|
lda ps2kb::VIA + IO::T2CL ; clear interrupt flag
|
||||||
|
IO_DisableIRQ ps2kb::VIA, IO::IRQ::T2
|
||||||
|
|
||||||
|
; disable shift register
|
||||||
|
lda ps2kb::VIA + IO::ACR
|
||||||
|
and #<~IO::ACR_MASK::SR
|
||||||
|
sta ps2kb::VIA + IO::ACR
|
||||||
|
bra _send_done
|
||||||
|
|
||||||
|
; lda ps2kb::VIA + IO::IFR
|
||||||
|
; jsr str::uint8_to_hex_str
|
||||||
|
; jsr lcd::print_char
|
||||||
|
; txa
|
||||||
|
; jsr lcd::print_char
|
||||||
|
rts
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
; @details
|
||||||
|
; Set the SEND_CMD_WAIT status bit the first time
|
||||||
|
; and jump to _send_done the second time it is called
|
||||||
|
; .proc _send_irq_cb1_handler
|
||||||
|
; ; clear the flag and disable interrupts
|
||||||
|
; ; DEBUG_LED_ON 1
|
||||||
|
; lda #'i'
|
||||||
|
; jsr lcd::print_char
|
||||||
|
; stp
|
||||||
|
|
||||||
|
; lda #IO::IRQ::CB1
|
||||||
|
; sta ps2kb::VIA + IO::IFR
|
||||||
|
; sta ps2kb::VIA + IO::IER
|
||||||
|
; ; DEBUG_LED_OFF 1
|
||||||
|
; bra _check_done
|
||||||
|
; .endproc
|
||||||
|
; .proc _send_irq_cb2_handler
|
||||||
|
; ; DEBUG_LED_ON 0
|
||||||
|
; ; lda #'I'
|
||||||
|
; ; jsr lcd::print_char
|
||||||
|
|
||||||
|
; lda #IO::IRQ::CB2
|
||||||
|
; sta ps2kb::VIA + IO::IFR
|
||||||
|
; sta ps2kb::VIA + IO::IER
|
||||||
|
; ; DEBUG_LED_OFF 0
|
||||||
|
; bra _send_done
|
||||||
|
; bra _check_done
|
||||||
|
; .endproc
|
||||||
|
|
||||||
|
; .proc _check_done
|
||||||
|
; ; check if done, by checking if SEND_CMD_WAIT bit is set
|
||||||
|
; lda #ps2kb::STATUS::SEND_CMD_WAIT
|
||||||
|
; tsb ps2kb::status
|
||||||
|
; bne _send_done ; SEND_CMD_WAIT was already set
|
||||||
|
; rts
|
||||||
|
; .endproc
|
||||||
|
|
||||||
|
.proc _send_done
|
||||||
|
_DisableClock ; disable keyboard while setting up receive
|
||||||
|
lda #'D'
|
||||||
jsr lcd::print_char
|
jsr lcd::print_char
|
||||||
bra loop
|
; Sleep 1
|
||||||
@no_char:
|
lda ps2kb::status
|
||||||
lda kb::keycode
|
and #ps2kb::STATUS::SEND_CMD
|
||||||
beq loop
|
beq @status_send_data ; data byte already sent
|
||||||
stz kb::keycode
|
@status_send_cmd:
|
||||||
cmp #kb::K::ESCAPE
|
lda #ps2kb::STATUS::SEND_DATA
|
||||||
beq @esacpe
|
lda ps2kb::status
|
||||||
cmp #kb::K::PRINT
|
; check if a data byte needs to be sent
|
||||||
beq @clear_display
|
lda ps2kb::send_data
|
||||||
cmp #kb::K::F12
|
beq @send_data ; if 0
|
||||||
jeq _ps2_keyboard_printer
|
cmp #ps2kb::NO_DATA
|
||||||
bra loop
|
beq @receive_answer ; if not NO_DATA
|
||||||
@esacpe:
|
@send_data:
|
||||||
jmp home
|
jmp _send_byte ; send the data
|
||||||
@clear_display:
|
@status_send_data:
|
||||||
jsr lcd::clear
|
@receive_answer:
|
||||||
bra loop
|
_DisableClock ; disable keyboard while setting up receive
|
||||||
|
DEBUG_LED_ON 0
|
||||||
|
lda #ps2kb::STATUS::RECEIVE_ANSWER
|
||||||
|
sta ps2kb::status
|
||||||
|
jmp ps2kb::begin_receive
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
|
.proc _process_cmd_answer
|
||||||
|
Strf fmt_answer, out_str, ps2kb::send_cmd, ps2kb::send_data, ps2kb::scancode
|
||||||
|
PrintNC out_str
|
||||||
|
DEBUG_LED_ON 1
|
||||||
|
stz ps2kb::scancode
|
||||||
|
lda ps2kb::prev_status
|
||||||
|
sta ps2kb::status
|
||||||
|
; set pin to input
|
||||||
|
; lda ps2kb::VIA + ps2kb::CLK_PULL_DDR
|
||||||
|
; and #<~ps2kb::CLK_PULL_MASK
|
||||||
|
; sta ps2kb::VIA + ps2kb::CLK_PULL_DDR
|
||||||
|
rts
|
||||||
|
.endproc
|
||||||
|
|
||||||
.byte '@'
|
|
||||||
out_str: .res 40
|
out_idx: .res 1
|
||||||
FMT_INIT_FAIL: .asciiz "KB init failed: %x%x > %x%x%x"
|
out_str: .res 40
|
||||||
|
char: .res 1
|
||||||
|
keycode: .res 1
|
||||||
|
keycode_flags: .res 1
|
||||||
|
fmt_codechar: .asciiz "%x %x %c "
|
||||||
|
fmt_code: .asciiz "%x %x "
|
||||||
|
fmt_answer: .asciiz "%x-%x>%x"
|
||||||
|
141
system/keyboard_handler.h65
Normal file
141
system/keyboard_handler.h65
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
;;********************************************************************************
|
||||||
|
;; @module keyboard_handler
|
||||||
|
;; @type system
|
||||||
|
;; @details:
|
||||||
|
;; This module processes keyboard scancodes from the ps2_keyboard module.
|
||||||
|
;;********************************************************************************
|
||||||
|
.ifndef INCLUDE_KEYBOARD
|
||||||
|
INCLUDE_KEYBOARD = 1
|
||||||
|
|
||||||
|
.include "ps2_keyboard.h65"
|
||||||
|
|
||||||
|
.scope kb
|
||||||
|
Import kb, CHARS_NOMOD, CHARS_MODSHIFT
|
||||||
|
ImportZp kb,status
|
||||||
|
|
||||||
|
.enum STATUS
|
||||||
|
RELEASE = %10000000
|
||||||
|
TWOBYTE = %01000000
|
||||||
|
SHIFT = %00100000
|
||||||
|
CAPSLOCK = %00010000
|
||||||
|
CAPSLOCK_HELD = %00000010
|
||||||
|
RIGHTALT = %00001000
|
||||||
|
NUMLOCK = %00000100
|
||||||
|
.endenum
|
||||||
|
|
||||||
|
K_TWOBYTE = $E0
|
||||||
|
K_RELEASE = $F0
|
||||||
|
|
||||||
|
.enum K
|
||||||
|
F9 = $01
|
||||||
|
F5 = $03
|
||||||
|
F3 = $04
|
||||||
|
F1 = $05
|
||||||
|
F2 = $06
|
||||||
|
F12 = $07
|
||||||
|
F10 = $09
|
||||||
|
F8 = $0A
|
||||||
|
F6 = $0B
|
||||||
|
F4 = $0C
|
||||||
|
TAB = $0D
|
||||||
|
GRAVE = $0E
|
||||||
|
LEFTALT = $11
|
||||||
|
LEFTSHIFT = $12
|
||||||
|
LEFTCTRL = $14
|
||||||
|
K_Q = $15
|
||||||
|
K_1 = $16
|
||||||
|
K_Y = $1A
|
||||||
|
K_S = $1B
|
||||||
|
K_A = $1C
|
||||||
|
K_W = $1D
|
||||||
|
K_2 = $1E
|
||||||
|
K_C = $21
|
||||||
|
K_X = $22
|
||||||
|
K_D = $23
|
||||||
|
K_E = $24
|
||||||
|
K_4 = $25
|
||||||
|
K_3 = $26
|
||||||
|
SPACE = $29
|
||||||
|
K_V = $2A
|
||||||
|
K_F = $2B
|
||||||
|
K_T = $2C
|
||||||
|
K_R = $2D
|
||||||
|
K_5 = $2E
|
||||||
|
K_N = $31
|
||||||
|
K_B = $32
|
||||||
|
K_H = $33
|
||||||
|
K_G = $34
|
||||||
|
K_Z = $35
|
||||||
|
K_6 = $36
|
||||||
|
K_M = $3A
|
||||||
|
K_J = $3B
|
||||||
|
K_U = $3C
|
||||||
|
K_7 = $3D
|
||||||
|
K_8 = $3E
|
||||||
|
COMMA = $41
|
||||||
|
K_K = $42
|
||||||
|
K_I = $43
|
||||||
|
K_O = $44
|
||||||
|
K_0 = $45
|
||||||
|
K_9 = $46
|
||||||
|
DOT = $49
|
||||||
|
DASH = $4A
|
||||||
|
K_L = $4B
|
||||||
|
OUML = $4C
|
||||||
|
K_P = $4D
|
||||||
|
SSHARP = $4E
|
||||||
|
AUML = $52
|
||||||
|
UUML = $54
|
||||||
|
BACKTICK = $55
|
||||||
|
CAPSLOCK = $58
|
||||||
|
RIGHTSHIFT = $59
|
||||||
|
ENTER = $5A
|
||||||
|
PLUS = $5B
|
||||||
|
HASH = $5D
|
||||||
|
LESSTHAN = $61
|
||||||
|
BACKSPACE = $66
|
||||||
|
KP1 = $69
|
||||||
|
KP4 = $6B
|
||||||
|
KP7 = $6C
|
||||||
|
KP0 = $70
|
||||||
|
KPDOT = $71
|
||||||
|
KP2 = $72
|
||||||
|
KP5 = $73
|
||||||
|
KP6 = $74
|
||||||
|
KP8 = $75
|
||||||
|
ESCAPE = $76
|
||||||
|
NUMLOCK = $77
|
||||||
|
F11 = $78
|
||||||
|
KPPLUS = $79
|
||||||
|
KP3 = $7A
|
||||||
|
KPMINUS = $7B
|
||||||
|
KPASTERISK = $7C
|
||||||
|
KP9 = $7D
|
||||||
|
SCROLLLOCK = $7E
|
||||||
|
F7 = $83
|
||||||
|
.endenum
|
||||||
|
|
||||||
|
.enum K2
|
||||||
|
RIGHTALT = $11
|
||||||
|
RIGHTCTRL = $14
|
||||||
|
LEFTMETA = $1F
|
||||||
|
RIGHTMETA = $27
|
||||||
|
MENU = $2F
|
||||||
|
BREAK = $37
|
||||||
|
SYSRQ = $3F
|
||||||
|
KPDIVIDE = $4A
|
||||||
|
KPENTER = $5A
|
||||||
|
END = $69
|
||||||
|
LEFT = $6B
|
||||||
|
POS1 = $6C
|
||||||
|
INSERT = $70
|
||||||
|
DELETE = $71
|
||||||
|
DOWN = $72
|
||||||
|
RIGHT = $74
|
||||||
|
UP = $75
|
||||||
|
PAGEDOWN = $7A
|
||||||
|
PAGEUP = $7D
|
||||||
|
.endenum
|
||||||
|
|
||||||
|
.endscope
|
||||||
|
.endif ; guard
|
28
system/keyboard_handler.s65
Normal file
28
system/keyboard_handler.s65
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
.include "keyboard_handler.h65"
|
||||||
|
Export kb, CHARS_NOMOD, CHARS_MODSHIFT
|
||||||
|
ExportZp kb,status
|
||||||
|
.zeropage
|
||||||
|
status: .res 1
|
||||||
|
|
||||||
|
.rodata
|
||||||
|
.align 256
|
||||||
|
CHARS_NOMOD:
|
||||||
|
.byte "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00^\x00"
|
||||||
|
.byte "\x00\x00\x00\x00\x00q1\x00\x00\x00ysaw2\x00"
|
||||||
|
.byte "\x00cxde43\x00\x00 vftr5\x00"
|
||||||
|
.byte "\x00nbhgz6\x00\x00\x00mju78\x00"
|
||||||
|
.byte "\x00,kio09\x00\x00.-l\xEFp\xE2\x00"
|
||||||
|
.byte "\x00\x00\xE1\x00\xF5`\x00\x00\x00\x00\x00\x00\x00#\x00\x00"
|
||||||
|
.byte "\x00<\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||||
|
.byte "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||||
|
|
||||||
|
.align 256
|
||||||
|
CHARS_MODSHIFT:
|
||||||
|
.byte "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xDF\x00"
|
||||||
|
.byte "\x00\x00\x00\x00\x00Q!\x00\x00\x00YSAW\"\x00"
|
||||||
|
.byte "\x00CXDE$\xED\x00\x00 VFTR%\x00"
|
||||||
|
.byte "\x00NBHGZ&\x00\x00\x00MJU/(\x00"
|
||||||
|
.byte "\x00;KIO=)\x00\x00:_L\xEFP\xE2\x00"
|
||||||
|
.byte "\x00\x00\xE1\x00\xF5`\x00\x00\x00\x00\x00\x00\x00'\x00\x00"
|
||||||
|
.byte "\x00>\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||||
|
.byte "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
@ -293,20 +293,18 @@ scancode_handler: .res 2 ; pointer to a function that handles new scancod
|
|||||||
_DisableClock
|
_DisableClock
|
||||||
|
|
||||||
; set shift register to output
|
; set shift register to output
|
||||||
; shift out the startbit = data low
|
|
||||||
; set SR to shift out with PHI2 and shift out zeros
|
|
||||||
lda ps2kb::VIA + IO::ACR
|
lda ps2kb::VIA + IO::ACR
|
||||||
and #<~IO::ACR_MASK::SR
|
and #<~IO::ACR_MASK::SR
|
||||||
ora #IO::ACR::SR_SOUT_PHI2
|
|
||||||
sta ps2kb::VIA + IO::ACR
|
|
||||||
stz ps2kb::VIA + IO::SR
|
|
||||||
|
|
||||||
; reset shift register to start the count at 0 again
|
|
||||||
and #<~IO::ACR_MASK::SR
|
|
||||||
sta ps2kb::VIA + IO::ACR
|
|
||||||
; set SR to shift out with external clock
|
|
||||||
ora #IO::ACR::SR_SOUT_PHIE
|
ora #IO::ACR::SR_SOUT_PHIE
|
||||||
sta ps2kb::VIA + IO::ACR
|
sta ps2kb::VIA + IO::ACR
|
||||||
|
stz ps2kb::VIA + IO::SR
|
||||||
|
; shift out the startbit = data low
|
||||||
|
_EnableClock
|
||||||
|
_DisableClock
|
||||||
|
; reset shift register to start the count at 0 again
|
||||||
|
lda #IO::ACR::SR_SOUT_PHIE
|
||||||
|
trb ps2kb::VIA + IO::ACR
|
||||||
|
tsb ps2kb::VIA + IO::ACR
|
||||||
|
|
||||||
; setup the low timer byte
|
; setup the low timer byte
|
||||||
lda #<ps2kb::TIMER_SEND
|
lda #<ps2kb::TIMER_SEND
|
||||||
|
Loading…
Reference in New Issue
Block a user