asm-test/keyboard3.asm.in

278 lines
8.4 KiB
NASM

include(`common.m4')
define(KBD_STATE, 40) ;;; 0x40 - 0x7f
define(KBD_STATE2, 80) ;;; 0x80 - 0xbf
define(KBD_COM_MASK, 3f)
define(KBD_GLCD_Y, 3e)
define(KBD_GLCD_X, 3d)
define(KBD_GLCD_C, 3c)
define(KBD_LAYER, 3b)
BRA r :reset ; RESB
NOP i ; IRQ
reset: LDX # ff
TXS i
JSR a :gfont_init
;; gfont_init already set Y and X to 55 and 7
LDA # ^55
STA zp KBD_GLCD_Y
JSR a :_kbd_char_c2_cursor
LDA # ^7
STA zp KBD_GLCD_X
STZ zp KBD_GLCD_C
STZ zp KBD_LAYER
LDA # %11111111
STA a VIA1_PORTA
LDA # %00000000
STA a VIA1_DDRB
LDA # %11111111
STA a VIA1_DDRA
;; layer indication
LDA # %00000011
STA a VIA2_DDRA
STZ a VIA2_PORTA
LDX # 80
LDA # 0
_state: STA zp,x KBD_STATE
DEX i
BNE r :_state
loop: LDX # 7 ; state
LDA # %01111111
STA zp KBD_COM_MASK
loop0: LDA zp KBD_COM_MASK
STA a VIA1_PORTA
LDY # 4 ; bit
LDA a VIA1_PORTB
loop1: ROR A
PHA s ; [A]
PHP s ; [P,A]
;; { A = (X * 8 + Y)
TXA i
ASL A
ASL A
ASL A
STY zp 1
ORA zp 1
;; }
PLP s ; [A]
PHX s ; [X,A]
TAX i
BCS r :_kbd_up
;;; begin down
_kbd_down: LDA zp,x KBD_STATE
CMP # 4
BNE r :_kbd_state_inc
;; if (KBD_STATE[X] == 4) {
LDA a,x KBD_STATE2
BNE r :_loop1_resume
;; if (KBD_STATE2[X] == 0) {
INC a,x KBD_STATE2
LDA zp KBD_LAYER
ASL A
ASL A
ASL A
ASL A
ASL A
ASL A ; << 6
STX zp 1
ORA zp 1
TAX i
LDA a,x :_bin_res/keymap_start
PHY s ; [Y,X,A]
JSR a :kbd_char_draw
PLY s ; [X,A]
BRA r :_loop1_resume
;; }
;; }
_kbd_state_inc: INC zp,x KBD_STATE
BRA r :_loop1_resume
;;; end down
;;; begin up
_kbd_up: LDA zp,x KBD_STATE
BEQ r :_kbd_up_state2
_kbd_state_dec: DEC zp,x KBD_STATE
BRA r :_loop1_resume
_kbd_up_state2: STZ a,x KBD_STATE2
;;; end up
_loop1_resume: PLX s ; [A]
PLA s ; []
DEY i
BPL r :loop1
SEC i
ROR zp KBD_COM_MASK
DEX i
BPL r :loop0
BRA r :loop
;;; end main loop
_kbd_char_nonprint: SEC i
SBC # 80
CMP # 4 ; L0 through L3
BCC r :_kbd_set_layer
BEQ r :_kbd_backspace ; BACKSPACE
BCS r :_kbd_enter ; ENTER or ???
_kbd_jump_return: RTS s
_kbd_set_layer: AND # %11
STA zp KBD_LAYER
STA a VIA2_PORTA
RTS s
_kbd_enter: LDA # ^32
LDY zp KBD_GLCD_C
BNE r :_kbd_enter_c1
;; fallthrough to _kbd_backspace_c2
_kbd_enter_c2: JSR a :gfont_draw_c2
JMP a :_kbd_end_of_line ; too long for BRA
_kbd_enter_c1: JSR a :gfont_draw_c1
JMP a :_kbd_end_of_line ; too long for BRA
_kbd_backspace: LDA # ^32
LDY zp KBD_GLCD_C
BNE r :_kbd_backspace_c1
;; fallthrough to _kbd_backspace_c2
_kbd_backspace_c2: JSR a :gfont_draw_c2
LDA zp KBD_GLCD_Y
CLC i
ADC # 5
CMP # ^56
BMI r :_kbd_char_c2_cursor
;; transitioning to c1
LDY # 1
STY zp KBD_GLCD_C
;; beginning of line, increment X page
LDA zp KBD_GLCD_X
INC A
AND # %111
STA zp KBD_GLCD_X
ORA # %10111000 ; X page
JSR a :glcd_w_rs0_c2
LDA zp KBD_GLCD_X
ORA # %10111000 ; X page
JSR a :glcd_w_rs0_c1
LDA # ^4
BRA r :_kbd_char_c1_cursor
_kbd_backspace_c1: JSR a :gfont_draw_c1
LDA zp KBD_GLCD_Y
CLC i
ADC # 5
CMP # ^60
BMI r :_kbd_char_c1_cursor
;; transitioning to c2
LDY # 0
STY zp KBD_GLCD_C
LDA # ^0
BRA r :_kbd_char_c2_cursor
;;; begin char_draw (A)
kbd_char_draw: CMP # 80
BCS r :_kbd_char_nonprint
LDY zp KBD_GLCD_C
BNE r :_kbd_char_c1
;; fallthrough to _kbd_char_c2
;;; c2: [55,0]
;; if (KBD_GLCD_C == 0) {
_kbd_char_c2: JSR a :gfont_draw_c2
LDA zp KBD_GLCD_Y
SEC i
SBC # 5
BPL r :_kbd_char_c2_cursor
;; transitioning to c1
LDY # 1
STY zp KBD_GLCD_C
LDA # ^59
BRA r :_kbd_char_c1_cursor
_kbd_char_c2_cursor: STA zp KBD_GLCD_Y
ORA # %01000000 ; Y address
JSR a :glcd_w_rs0_c2
LDA # ^95
JSR a :gfont_draw_c2
LDA zp KBD_GLCD_Y
ORA # %01000000 ; Y address
JSR a :glcd_w_rs0_c2
RTS s
;; }
;;; c2: [59,4]
;; if (KBD_GLCD_C == 1) {
_kbd_char_c1: JSR a :gfont_draw_c1
LDA zp KBD_GLCD_Y
SEC i
SBC # 5
CMP # 4
BPL r :_kbd_char_c1_cursor
;; transitioning to c2
_kbd_end_of_line: LDY # 0
STY zp KBD_GLCD_C
;; end of line, decrement X page
LDA zp KBD_GLCD_X
DEC A
AND # %111
STA zp KBD_GLCD_X
ORA # %10111000 ; X page
JSR a :glcd_w_rs0_c2
LDA zp KBD_GLCD_X
ORA # %10111000 ; X page
JSR a :glcd_w_rs0_c1
LDA # ^55
BRA r :_kbd_char_c2_cursor
_kbd_char_c1_cursor: STA zp KBD_GLCD_Y
ORA # %01000000 ; Y address
JSR a :glcd_w_rs0_c1
LDA # ^95
JSR a :gfont_draw_c1
LDA zp KBD_GLCD_Y
ORA # %01000000 ; Y address
JSR a :glcd_w_rs0_c1
RTS s
;; }
;;; end char_draw