wip keyboard
This commit is contained in:
parent
2bfae04f50
commit
b60ff7be12
81
main.s65
81
main.s65
@ -1,34 +1,11 @@
|
||||
.include "system/system.h65"
|
||||
.include "string.h65"
|
||||
.export home,homeloop
|
||||
.import printer:absolute
|
||||
.import spi_menu:absolute
|
||||
|
||||
.code
|
||||
|
||||
.macro DEBUG_LED_OFF nr
|
||||
pha
|
||||
lda IO1 + IO::RA
|
||||
.if nr = 0
|
||||
and #%11111110
|
||||
.else
|
||||
and #%11111101
|
||||
.endif
|
||||
sta IO1 + IO::RA
|
||||
pla
|
||||
.endmacro
|
||||
|
||||
.macro DEBUG_LED_ON nr
|
||||
pha
|
||||
lda IO1 + IO::RA
|
||||
.if nr = 0
|
||||
ora #%00000001
|
||||
.else
|
||||
ora #%00000010
|
||||
.endif
|
||||
sta IO1 + IO::RA
|
||||
pla
|
||||
.endmacro
|
||||
|
||||
;********************************************************************************
|
||||
; Modules
|
||||
;********************************************************************************
|
||||
@ -62,12 +39,14 @@ nmi:
|
||||
rti
|
||||
irq:
|
||||
; read IRFs, while bit 7 ist set handle interrupts
|
||||
; DEBUG_LED_ON 2
|
||||
@irq_io1:
|
||||
lda IO1 + IO::IFR
|
||||
sta irq_via_ifr
|
||||
bbr7 irq_via_ifr,@irq_io1 ; skip
|
||||
bbr7 irq_via_ifr,@irq_io2 ; skip
|
||||
bbs2 irq_via_ifr,@irq_kb1 ; shit reg -> first 8 bits
|
||||
bbs5 irq_via_ifr,@irq_kb2 ; timer -> last 3 bits
|
||||
bra @irq_unknown
|
||||
@irq_io2:
|
||||
lda IO2 + IO::IFR
|
||||
sta irq_via_ifr
|
||||
@ -75,6 +54,7 @@ irq:
|
||||
bbs2 irq_via_ifr,@irq_spi_p ; check SR
|
||||
bbs1 irq_via_ifr,@irq_keypad ; check CA1
|
||||
|
||||
@irq_unknown:
|
||||
; this SHOULD never be reached
|
||||
jsr lcd::clear
|
||||
Print "Unknown IRQ"
|
||||
@ -87,13 +67,16 @@ irq:
|
||||
jsr kp::read_irq
|
||||
bra @irq_return
|
||||
@irq_spi_p:
|
||||
JsrIndirect (spi_p::irq_handler), @irq_return
|
||||
jsr spi_p::irq_read_byte
|
||||
bra @irq_return
|
||||
; jmp (spi_p::irq_handler)
|
||||
; JsrIndirect (spi_p::irq_handler), @irq_return
|
||||
@irq_kb1:
|
||||
Print "$3000"
|
||||
; Print "$3000"
|
||||
jsr $3000
|
||||
bra @irq_return
|
||||
@irq_kb2:
|
||||
Print "$3100"
|
||||
; Print "$3100"
|
||||
jsr $3100
|
||||
bra @irq_return
|
||||
; @irq_dht:
|
||||
@ -114,25 +97,20 @@ reset:
|
||||
sta IO1 + IO::DDRA
|
||||
DEBUG_LED_OFF 0
|
||||
DEBUG_LED_OFF 1
|
||||
|
||||
DEBUG_LED_OFF 1
|
||||
|
||||
jsr kp::init
|
||||
|
||||
SetCustomChar chars::CAT,0
|
||||
SetCustomChar chars::SMILEY,1
|
||||
SetCustomChar chars::SMILEY_XD,2
|
||||
DEBUG_LED_ON 0
|
||||
|
||||
jsr spi_p::init
|
||||
DEBUG_LED_ON 1
|
||||
|
||||
; ; INIT DHT
|
||||
; lda #%11000010 ; enable interrupt for Timer 1 and CA1 on IO2
|
||||
; sta IER2
|
||||
; lda #%00111111 ; set Timer 1 to interrupt when loaded
|
||||
; and ACR2
|
||||
; sta ACR2
|
||||
; lda #%00000001 ; set PCR2 bit 0 CA1 pos edge interrupt
|
||||
; ora PCR2
|
||||
; sta PCR2
|
||||
; stz DHT_STATUS
|
||||
; SetCustomChar chars::CAT,0
|
||||
; SetCustomChar chars::SMILEY,1
|
||||
; SetCustomChar chars::SMILEY_XD,2
|
||||
|
||||
; DEBUG_LED_ON 2
|
||||
|
||||
; enable interrupts
|
||||
cli
|
||||
@ -170,9 +148,14 @@ reset:
|
||||
cmp #'5'
|
||||
beq @debug1_off
|
||||
cmp #'7'
|
||||
beq @debug2_on
|
||||
cmp #'8'
|
||||
beq @debug2_off
|
||||
cmp #'9'
|
||||
beq @print_rb
|
||||
cmp #'*' ; print home menu again if not visible (message 1 and 2 jmp to home)
|
||||
beq home
|
||||
wai
|
||||
jmp @loop
|
||||
|
||||
@debug0_off:
|
||||
@ -187,6 +170,12 @@ reset:
|
||||
@debug1_on:
|
||||
DEBUG_LED_ON 1
|
||||
jmp @loop
|
||||
@debug2_off:
|
||||
DEBUG_LED_OFF 2
|
||||
jmp @loop
|
||||
@debug2_on:
|
||||
DEBUG_LED_ON 2
|
||||
jmp @loop
|
||||
@print_rb:
|
||||
jsr lcd::clear
|
||||
Print str_io2
|
||||
@ -215,10 +204,10 @@ message_1:
|
||||
.byte " **** "
|
||||
.asciiz "www.quintern.xyz"
|
||||
message_2:
|
||||
.byte " Hello "
|
||||
.byte " there "
|
||||
.byte " <3 "
|
||||
.asciiz "================"
|
||||
.byte "0123456789=!?#+*"
|
||||
.byte "ABCDEFGHIJKLMNOP"
|
||||
.byte "QRSTUVWXYZÖÄÜß-_"
|
||||
.asciiz "{[(<>)]}$%&/,;.:"
|
||||
message_menu:
|
||||
.byte "<A> Printer "
|
||||
; .byte "<B> Temperatur "
|
||||
|
304
spicode.s65
304
spicode.s65
@ -20,16 +20,10 @@ CODE_START:
|
||||
jsr lcd::clear
|
||||
lda #'$'
|
||||
jsr lcd::print_char
|
||||
|
||||
; stz kp::_DEBUG_VAL
|
||||
; @loop:
|
||||
; lda kp::_DEBUG_VAL
|
||||
; beq @loop
|
||||
; stz kp::_DEBUG_VAL
|
||||
; cmp #'*'
|
||||
; jeq homeloop
|
||||
; jsr lcd::print_char
|
||||
; bra @loop
|
||||
; jmp homeloop
|
||||
DEBUG_LED_OFF 0
|
||||
DEBUG_LED_OFF 1
|
||||
DEBUG_LED_OFF 2
|
||||
|
||||
lda #<kb_irq1
|
||||
sta ARG0
|
||||
@ -39,7 +33,7 @@ CODE_START:
|
||||
sta ARG2
|
||||
lda #>$3000
|
||||
sta ARG3
|
||||
ldy #20
|
||||
ldy #10
|
||||
jsr memcopy
|
||||
|
||||
lda #<kb_irq2
|
||||
@ -50,16 +44,16 @@ CODE_START:
|
||||
sta ARG2
|
||||
lda #>$3100
|
||||
sta ARG3
|
||||
ldy #20
|
||||
ldy #10
|
||||
jsr memcopy
|
||||
|
||||
lda #'?'
|
||||
jsr lcd::print_char
|
||||
|
||||
; PrintNC $3000
|
||||
|
||||
jsr kb::init
|
||||
|
||||
stz kb::status
|
||||
|
||||
lda #'%'
|
||||
jsr lcd::print_char
|
||||
|
||||
@ -67,8 +61,41 @@ CODE_START:
|
||||
ldy #0
|
||||
|
||||
@loop:
|
||||
wai
|
||||
lda kb::scancode
|
||||
beq @noscancode
|
||||
jsr process_scancode
|
||||
stz kb::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:
|
||||
lda kp::_DEBUG_VAL
|
||||
beq @loop
|
||||
jeq @loop
|
||||
stz kp::_DEBUG_VAL
|
||||
cmp #'*'
|
||||
jeq homeloop
|
||||
@ -85,125 +112,45 @@ CODE_START:
|
||||
cmp #'C'
|
||||
beq @lC
|
||||
jsr lcd::print_char
|
||||
bra @loop
|
||||
jmp @loop
|
||||
@l1:
|
||||
; jsr irq_on_shift_reg
|
||||
jsr $3000
|
||||
lda #'*'
|
||||
jsr lcd::print_char
|
||||
bra @loop
|
||||
jmp @loop
|
||||
@l2:
|
||||
; jsr irq_on_timer
|
||||
jsr $3100
|
||||
lda #'#'
|
||||
jsr lcd::print_char
|
||||
bra @loop
|
||||
jmp @loop
|
||||
@l3:
|
||||
lda $3000,y
|
||||
jsr lcd::print_char
|
||||
iny
|
||||
bra @loop
|
||||
jmp @loop
|
||||
@lA:
|
||||
lda kb::KB_IO + IO::SR
|
||||
jsr lcd::print_char
|
||||
bra @loop
|
||||
jmp @loop
|
||||
@lB:
|
||||
Strf fmt_str, out_str, kb::keycode
|
||||
; Printf "kc%x;", out_str, kb::scancode
|
||||
jsr lcd::clear
|
||||
ldx out_idx
|
||||
lda #0
|
||||
sta out_str,x
|
||||
Print out_str
|
||||
bra @loop
|
||||
stz out_idx
|
||||
|
||||
jmp @loop
|
||||
@lC:
|
||||
jsr lcd::clear
|
||||
bra @loop
|
||||
jmp @loop
|
||||
|
||||
|
||||
; .proc kbinit
|
||||
; lda #'['
|
||||
; jsr lcd::print_char
|
||||
; ; - use the shift register interrupts to read the first 8 bits
|
||||
; ; set shift register to shift in under external clock on CB1
|
||||
; ; - configure timer for timing the read of the last 3 bits
|
||||
; ; timer 2 one shot mode is sufficient, leaves T1 available
|
||||
; lda #(IO::ACR::SR_SIN_PHIE | IO::ACR::T2_IRQ_LOAD)
|
||||
; tsb kb::KB_IO + IO::ACR
|
||||
; ; the 3 last bits take about 230us, at @1MHz => wait 230 cycles and then the shift register
|
||||
; lda #230
|
||||
; sta kb::KB_IO + IO::T2CL
|
||||
; stz key_read
|
||||
; stz key_read+1
|
||||
; ; enable SR interrupts
|
||||
; lda #(IO::IRQ::IRQ | IO::IRQ::SR)
|
||||
; sta kb::KB_IO + IO::IER
|
||||
; ; load SR to reset
|
||||
; lda kb::KB_IO + IO::SR
|
||||
; lda #']'
|
||||
; jsr lcd::print_char
|
||||
; rts
|
||||
; .endproc
|
||||
|
||||
|
||||
; ;; @details
|
||||
; ;; IO::SR has to be read before the next bit is shifted in, which happens ~75us after the irq
|
||||
; ;; at 1MHz, handlings this interrupt takes about 50us (without any additional debug code), so it should work
|
||||
; .proc irq_on_shift_reg
|
||||
; ; lda #'{'
|
||||
; ; jsr lcd::print_char
|
||||
; lda kb::KB_IO + IO::SR
|
||||
; sta key_read
|
||||
; stz kb::KB_IO + IO::SR
|
||||
|
||||
; ; disable SR interrupts
|
||||
; lda #IO::IRQ::SR
|
||||
; sta kb::KB_IO + IO::IER
|
||||
; ; enable timer interrupts
|
||||
; lda #(IO::IRQ::IRQ | IO::IRQ::T2)
|
||||
; sta kb::KB_IO + IO::IER
|
||||
; ; start timer
|
||||
; lda #1
|
||||
; sta kb::KB_IO + IO::T2CH
|
||||
; ; lda #'}'
|
||||
; ; jsr lcd::print_char
|
||||
; rts
|
||||
; .endproc
|
||||
|
||||
|
||||
.proc irq_timer_handler
|
||||
; lda #'<'
|
||||
; jsr lcd::print_char
|
||||
lda kb::KB_IO + IO::SR
|
||||
sta kb::key_read + 1
|
||||
|
||||
lda kb::KB_IO + IO::T2CL ; clear interrupt flag
|
||||
|
||||
; disable timer interrupts
|
||||
lda #(IO::IRQ::T2)
|
||||
sta kb::KB_IO + IO::IER
|
||||
; enable shift register interrupts
|
||||
lda #(IO::IRQ::IRQ | IO::IRQ::SR)
|
||||
sta kb::KB_IO + IO::IER
|
||||
; reset SR
|
||||
stz kb::KB_IO + IO::SR
|
||||
|
||||
; lda #'|'
|
||||
; rotate bit 2 (last bit of keycode) into the carry
|
||||
ror
|
||||
ror
|
||||
ror
|
||||
lda kb::key_read ; not affecting carry
|
||||
rol ; rotate carry into byte, rotate startbit into carry
|
||||
; TODO byte is inverted, maybe consider wasting 256 bytes for a bit reverse lookup table?
|
||||
sta kb::keycode
|
||||
|
||||
Strf fmt_str2, out_str, kb::keycode, kb::key_read, kb::key_read+1
|
||||
PrintNC out_str
|
||||
|
||||
stz kb::key_read
|
||||
stz kb::key_read+1
|
||||
|
||||
rts
|
||||
.endproc
|
||||
|
||||
; key_read: .res 2
|
||||
; keycode: .res 1
|
||||
; scancode: .res 1
|
||||
kb_irq1:
|
||||
; lda #'!'
|
||||
; jsr lcd::print_char
|
||||
@ -216,13 +163,142 @@ kb_irq2:
|
||||
; lda #'?'
|
||||
; jsr lcd::print_char
|
||||
; jsr kb::on_timer_irq
|
||||
jsr irq_timer_handler
|
||||
jsr kb::irq_timer_handler
|
||||
; lda #';'
|
||||
; jsr lcd::print_char
|
||||
rts
|
||||
.byte '@'
|
||||
|
||||
out_str: .res 40
|
||||
fmt_str: .asciiz "kc%x;"
|
||||
fmt_str2: .asciiz "kc%x-%x-%x; "
|
||||
.proc process_scancode
|
||||
; DEBUG_LED_OFF 1
|
||||
; check how this scancode needs to be interpreted
|
||||
ldx kb::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
|
||||
|
||||
out_idx: .res 1
|
||||
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 "
|
||||
|
@ -3,7 +3,7 @@
|
||||
;; @type drive
|
||||
;; @details:
|
||||
;; Support for a PS2 Keyboard using the shift register of a 6522 VIA
|
||||
;; Pressing a key causes 11 bits to be sent: 1 start - 8 keycode - 1 parity - 1 stop
|
||||
;; Pressing a key causes 11 bits to be sent: 1 start - 8 scancode - 1 parity - 1 stop
|
||||
;; The VIA is set up to interrupt after 8 bits have been shifted into the shift register
|
||||
;; from the external clock pulses of the keyboard (additional hardware required to
|
||||
;; address the hardware bug of the VIA, where bit get lost when the external clock
|
||||
@ -16,8 +16,136 @@ INCLUDE_KEYBOARD = 1
|
||||
.include "system.h65"
|
||||
|
||||
.scope kb
|
||||
Import kb,init,irq_shift_reg_handler,irq_timer_handler,keycode,key_read
|
||||
Import kb,init,irq_shift_reg_handler,irq_timer_handler,scancode,key_read
|
||||
Import kb, CHARS_NOMOD, CHARS_MODSHIFT
|
||||
ImportZp kb,status
|
||||
KB_IO = IO1
|
||||
|
||||
.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
|
||||
|
||||
.endif ; guard
|
||||
|
@ -1,11 +1,15 @@
|
||||
.include "keyboard.h65"
|
||||
.include "string.h65"
|
||||
.include "lcd.h65"
|
||||
Export kb,init,irq_shift_reg_handler,irq_timer_handler,keycode,key_read
|
||||
Export kb,init,irq_shift_reg_handler,irq_timer_handler,scancode,key_read
|
||||
Export kb, CHARS_NOMOD, CHARS_MODSHIFT
|
||||
ExportZp kb,status
|
||||
|
||||
.zeropage
|
||||
status:
|
||||
.bss
|
||||
key_read: .res 2
|
||||
keycode: .res 1
|
||||
scancode: .res 1
|
||||
|
||||
.code
|
||||
;;********************************************************************************
|
||||
@ -25,6 +29,8 @@ keycode: .res 1
|
||||
sta kb::KB_IO + IO::T2CL
|
||||
stz key_read
|
||||
stz key_read+1
|
||||
stz scancode
|
||||
stz status
|
||||
|
||||
; enable SR interrupts
|
||||
lda #(IO::IRQ::IRQ | IO::IRQ::SR)
|
||||
@ -60,7 +66,7 @@ keycode: .res 1
|
||||
lda #(IO::IRQ::IRQ | IO::IRQ::T2)
|
||||
sta kb::KB_IO + IO::IER
|
||||
; start timer, low order count already in latch after init
|
||||
lda #1
|
||||
lda #0
|
||||
sta kb::KB_IO + IO::T2CH
|
||||
rts
|
||||
.endproc
|
||||
@ -84,23 +90,49 @@ keycode: .res 1
|
||||
; disable timer interrupts
|
||||
lda #(IO::IRQ::T2)
|
||||
sta kb::KB_IO + IO::IER
|
||||
|
||||
; reset SR
|
||||
; disabling shifting in acr seems necessary to reset - otherwise
|
||||
; it continues counting and interrupts after the first 5 bits of the next keypress
|
||||
lda #(IO::ACR::SR_SIN_PHIE | IO::ACR::T2_IRQ_LOAD)
|
||||
trb kb::KB_IO + IO::ACR
|
||||
tsb kb::KB_IO + IO::ACR
|
||||
stz kb::KB_IO + IO::SR
|
||||
; enable shift register interrupts
|
||||
lda #(IO::IRQ::IRQ | IO::IRQ::SR)
|
||||
sta kb::KB_IO + IO::IER
|
||||
; reset SR
|
||||
stz kb::KB_IO + IO::SR
|
||||
|
||||
; rotate bit 2 (last bit of keycode) into the carry
|
||||
lda key_read+1
|
||||
ror
|
||||
ror
|
||||
ror
|
||||
lda key_read ; not affecting carry
|
||||
rol ; rotate carry into byte, rotate startbit into carry
|
||||
; TODO byte is inverted, maybe consider wasting 256 bytes for a bit reverse lookup table?
|
||||
sta keycode
|
||||
rol ; rotate carry into byte, rotate startbit into carry
|
||||
Reverse A
|
||||
sta scancode
|
||||
|
||||
stz key_read
|
||||
stz key_read+1
|
||||
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\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"
|
||||
|
@ -67,4 +67,13 @@ IO1 = $6000
|
||||
; IO2: .res 16
|
||||
IO2 = $7000
|
||||
|
||||
; charmappings for the lcd
|
||||
; .charmap 'ü', $F5
|
||||
; .charmap 'Ü', $F5
|
||||
; .charmap 'ö', $EF
|
||||
; .charmap 'Ö', $EF
|
||||
; .charmap 'ä', $E1
|
||||
; .charmap 'Ä', $E1
|
||||
; .charmap 'ß', $E2
|
||||
|
||||
.endif ; include guard
|
||||
|
23
test.s65
23
test.s65
@ -1,8 +1,23 @@
|
||||
.include "system/system.h65"
|
||||
.include "system/lcd.h65"
|
||||
|
||||
.segment "TEST"
|
||||
.macro MaskedWrite2 addr,value,mask
|
||||
lda #value
|
||||
eor addr
|
||||
and #mask
|
||||
eor addr
|
||||
sta addr
|
||||
.endmacro
|
||||
.import __SPI_SIZE__
|
||||
label:
|
||||
JsrIndirect $2022
|
||||
.byte 0,1,2,3,4
|
||||
JsrIndirect {($2022,x)}, label
|
||||
.byte 5,6,7,8,9
|
||||
; JsrIndirect $2022
|
||||
; .byte 0,1,2,3,4
|
||||
; JsrIndirect {($2022,x)}, label
|
||||
; .byte 5,6,7,8,9
|
||||
; MaskedWrite2 lcd::LCD_IO+IO::DDRA, (lcd::RS | lcd::RW | lcd::E), lcd::RA_MASK
|
||||
; lda #(lcd::RS | lcd::RW | lcd::E) ; RA 5-7 output
|
||||
; sta lcd::LCD_IO+IO::DDRA
|
||||
.word __SPI_SIZE__
|
||||
.byte >__SPI_SIZE__
|
||||
.byte <__SPI_SIZE__
|
||||
|
Loading…
Reference in New Issue
Block a user