wip: keyboard

This commit is contained in:
matthias@arch 2023-12-20 12:27:54 +01:00
parent 404c435162
commit 811d50122f
10 changed files with 229 additions and 126 deletions

View File

@ -1,4 +1,5 @@
ROM = ../rom.bin
ROM = ../rom.bin
SPI = ../spi.bin
OBJ_DIR = build
@ -20,7 +21,7 @@ DEP = $(wildcard $(OBJ_DIR)/*/*.d)
-include $(DEP)
.PHONY: default test clean print
.PHONY: default test clean print spi
.DEFAULT_GOAL = default
FMT_MESSAGE="\e[1;34m%s\e[0m %s\n"
@ -33,12 +34,15 @@ print:
@printf $(FMT_VAR) "LDFLAGS" "$(LDFLAGS)"
@printf $(FMT_VAR) "SRC" "$(SRC)"
@printf $(FMT_VAR) "OBJ" "$(OBJ)"
default: $(ROM)
default: $(ROM) $(SPI)
spi: default
./../ad-spi/spi-transfer -f $(SPI)
$(OBJ_DIRS):
mkdir -p $@
$(ROM): $(OBJ)
$(SPI) $(ROM): $(OBJ) linker.conf
@printf $(FMT_MESSAGE) "Linking" "$@"
$(LD) $(LDFLAGS) $(OBJ) -o $@
@ -52,3 +56,4 @@ $(OBJ_DIR)/%.o: %.s65 | $(OBJ_DIRS)
clean:
rm -r $(OBJ_DIR)
rm $(ROM)
rm $(SPI)

View File

@ -3,7 +3,7 @@ MEMORY {
# RAM: start = $0100, size = $5eff, type = rw, file = "", fill = yes;
STACK: start = $0100, size = $0100, type = rw, file = "", fill = yes;
RAM: start = $0200, size = $4e00, type = rw, file = "", fill = yes;
SPI: start = $5000, size = $1000, type = rw, file = "spi.bin", fill = no;
SPI: start = $5000, size = $1000, type = rw, file = "../spi.bin", fill = no;
VIA1: start = $6000, size = $000f, type = rw, file = "", fill = yes;
VIA2: start = $7000, size = $000f, type = rw, file = "", fill = yes;
ROM: start = $8000, size = $8000, type = ro, file = %O, fill = yes;

View File

@ -72,7 +72,14 @@ irq:
bbr7 IRQ_VAR,@irq_return
bbs2 IRQ_VAR,@irq_spi_p ; check SR
bbs1 IRQ_VAR,@irq_keypad ; check CA1
; this should never be reached
;
lda IO1+IO::IFR
sta IRQ_VAR
bbr7 IRQ_VAR,@irq_return
bbs2 IRQ_VAR,@irq_kb1 ; shit reg -> first 8 bits
bbs5 IRQ_VAR,@irq_kb2 ; timer -> last 3 bits
; this SHOULD never be reached
jsr lcd::clear
Print str_irq_unknown
; force reset interrupt flags
@ -86,6 +93,14 @@ irq:
@irq_spi_p:
jsr spi_p::read
bra @irq_return
@irq_kb1:
Print "$3000"
jsr $3000
bra @irq_return
@irq_kb2:
Print "$3100"
jsr $3100
bra @irq_return
; @irq_dht:
; lda IO1 + IO::T1CL ;T1L2 ; clear interrupt flag
; bra @irq_return
@ -131,6 +146,7 @@ reset:
.proc home
Print message_menu
; jsr rb_keypad_read
stz kp::_DEBUG_VAL
bra homeloop
.endproc
.proc homeloop

View File

@ -3,6 +3,8 @@ INCLUDE_MEMCOPY = 1
.include "system.h65"
.export memcopy
.code
;********************************************************************************
; @function Copy a block of memory to a different address
@ -12,13 +14,14 @@ INCLUDE_MEMCOPY = 1
;********************************************************************************
.proc memcopy
cpy #0
@loop:
beq @loop_end
beq @rts
@copy_byte:
dey
lda (ARG0),y
sta (ARG2),y
dey
bra @loop
@loop_end:
cpy #0
bne @copy_byte
@rts:
rts
.endproc
.endif ; guard

View File

@ -83,7 +83,7 @@ status_str: .res 17 ; 16 + null
.rodata
MENU:
.byte chars::DOT, "A Beg. Transfer"
.byte "A> Beg. Transfer"
.byte "B> Stop Transfer"
.asciiz "C> Jump Home <*"
; .asciiz "0b0p Status: X"

View File

@ -6,149 +6,206 @@
.include "chars.h65"
.import homeloop:absolute
.import home:absolute
.segment "SPI"
.export CODE_START
.import memcopy
.scope kb
KB_IO = IO1
.endscope
CODE_START:
.assert * = $5000, error, "SPI Code not at $5000"
jsr lcd::clear
lda #'>'
lda #'$'
jsr lcd::print_char
jsr rb_test_init
; stz kp::_DEBUG_VAL
; @loop:
; lda kp::_DEBUG_VAL
; beq @loop
; stz kp::_DEBUG_VAL
; cmp #'*'
; jeq homeloop
; jsr lcd::print_char
; bra @loop
lda #<kb_irq1
sta ARG0
lda #>kb_irq1
sta ARG1
lda #<$3000
sta ARG2
lda #>$3000
sta ARG3
ldy #20
jsr memcopy
lda #<kb_irq2
sta ARG0
lda #>kb_irq2
sta ARG1
lda #<$3100
sta ARG2
lda #>$3100
sta ARG3
ldy #20
jsr memcopy
lda #'?'
jsr lcd::print_char
; PrintNC $3000
jsr kbinit
lda #'%'
jsr lcd::print_char
stz kp::_DEBUG_VAL
ldy #0
@loop:
lda kp::_DEBUG_VAL
pha
stz kp::_DEBUG_VAL
pla
beq @loop
stz kp::_DEBUG_VAL
cmp #'*'
jeq homeloop
cmp #'#'
beq @print
tya
pha
cmp #'1'
beq @l1
cmp #'2'
beq @l2
cmp #'3'
beq @l3
cmp #'A'
beq @lA
jsr lcd::print_char
bra @loop
@l1:
; jsr irq_on_shift_reg
jsr $3000
lda #'*'
jsr lcd::print_char
bra @loop
@l2:
; jsr irq_on_timer
jsr $3100
lda #'#'
jsr lcd::print_char
bra @loop
@l3:
lda $3000,y
jsr lcd::print_char
iny
jsr rb_test_write
pla
ora #$30
bra @loop
@lA:
lda kb::KB_IO + IO::SR
jsr lcd::print_char
bra @loop
@print:
@printloop:
lda #'r'
jsr lcd::print_char
jsr @print_state
; .out .sprintf("SPI: CODE_START at %x", *)
jsr rb_test_read
beq @empty
ora #$30
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
; 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
irq_on_shift_reg:
lda #'{'
jsr lcd::print_char
lda kb::KB_IO + IO::SR
sta keycode
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
lda #$10 ; todo remove
sta kb::KB_IO + IO::T2CH
; lda #'}'
; jsr lcd::print_char
rts
irq_on_timer:
lda #'<'
jsr lcd::print_char
lda kb::KB_IO + IO::SR
sta keycode + 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
; load SR to reset
stz kb::KB_IO + IO::SR
; lda #'|'
lda keycode
jsr lcd::print_char
lda keycode + 1
jsr lcd::print_char
; rotate bit 2 (last bit of keycode) into the carry
ror
ror
ror
lda keycode ; 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 + 1
jsr lcd::print_char
lda #'>'
jsr lcd::print_char
rts
keycode: .res 3
kb_irq1:
lda #'!'
jsr lcd::print_char
jsr irq_on_shift_reg
lda #':'
jsr lcd::print_char
rts
.byte '='
kb_irq2:
lda #'?'
jsr lcd::print_char
jsr irq_on_timer
lda #';'
jsr lcd::print_char
bra @printloop
@empty:
lda #'E'
jsr lcd::print_char
lda #';'
jsr lcd::print_char
bra @loop
@print_state:
lda #'('
jsr lcd::print_char
lda RB_READ
ora #$30
jsr lcd::print_char
lda RB_WRITE
ora #$30
jsr lcd::print_char
lda #')'
jsr lcd::print_char
rts
TEST_MEMSIZE = $A
RBUF_MEM_START:
.res TEST_MEMSIZE
RBUF_MEM_END:
.define RBUF_NAME "test"
.define _RBUF_NAME .concat("rb_", RBUF_NAME)
RB_WRITE = RBUF_MEM_START ; write pointer, relative to RB_WRITE
RB_READ = RBUF_MEM_START + 1 ; read ponter, relative to RB_START
RB_START = RBUF_MEM_START + 2
RB_LENGTH = RBUF_MEM_END - RBUF_MEM_START - 2
.if RB_LENGTH < 1
.fatal "buffer size too small, must be at least 1"
.endif
.if RB_LENGTH > $ff
.fatal "buffer size too large, must be <= $ff"
.endif
; .out .sprintf("Buffer: %x -> %x (len=%x)", RBUF_MEM_START, RBUF_MEM_END, RB_LENGTH)
.proc rb_test_init
stz RB_WRITE
stz RB_READ
rts
.endproc
.proc rb_test_read
ldx RB_READ
cpx RB_WRITE
beq @rb_read_rts ; if buffer empty
lda RB_START,x
inx ; increment RB_READ pointer, not using macro bec. of unknown Pz
cpx #RB_LENGTH
beq @read_wrap
stx RB_READ
@rb_read_rts:
rts
@read_wrap: ; ptr == RB_LENGTH -> ptr = 0
stz RB_READ
; make sure Pz is not set
ldx #$01
rts
.endproc
.proc rb_test_write
; lda kp_VALUES, x ; load the char in a
ldx RB_WRITE
sta RB_START,x
inx ; increment write pointer
cpx #RB_LENGTH
beq @write_wrap
stx RB_WRITE
@check_buf_full: ; increment read if buffer is full
cpx RB_READ
beq @read_inc
rts
@write_wrap: ; ptr == RB_LENGTH -> ptr = 0
stz RB_WRITE
ldx #0
bra @check_buf_full
@read_inc:
ldx RB_READ
inx
cpx #RB_LENGTH
beq @read_wrap
stx RB_READ
rts
@read_wrap: ; ptr == RB_LENGTH -> ptr = 0
stz RB_READ
rts
.endproc
.byte '@'

View File

@ -53,7 +53,12 @@ INCLUDE_IOW65C22 = 1
T1_IRQ_CONT = %01000000 ; Continuous interrupts
T1_IRQ_LOAD_PB7 = %10000000 ; Timed interrupt each time T1 is loaded - PB7 One Shot output
T1_IRQ_CONT_PB7 = %11000000 ; Continuous interrupts - PB7 Square wave output
; todo: others
; T2 Modes
T2_IRQ_LOAD = %00000000 ; Timed interrupt each time T2 is loaded
T2_COUNT_PB6 = %00100000 ; Count down with pulsen on PB6
; Latch
LATCH_DISABLE = %00000000
LATCH_ENBLE = %00000000
.endenum
.enum PCR_MASK ; PCR Masks

View File

@ -27,11 +27,26 @@ Import lcd,_cmd,_wait_nbusy,_write_ram,_read_ram
; @param message: Address of the message
;********************************************************************************
.macro Print message
; .out .sprintf("message is a string literal: '%s' len=%x", message, .strlen(message))
.if .match(message, "")
.pushseg
.rodata
: .asciiz message
.popseg
.out .sprintf("message is a string literal: '%s' len=%x", message, .strlen(message))
jsr lcd::clear
lda #<:-
sta ARG0
lda #>:-
sta ARG1
.else
.out "message is a n0t string"
jsr lcd::clear
lda #<message
sta ARG0
lda #>message
sta ARG1
.endif
jsr lcd::print
.endmacro

View File

@ -62,6 +62,7 @@ CODE_START := spi_p::CODE_START
; @function Stop listening for SPI transfers
; @details
; Disables shift register interrupts
; @modifies A
;********************************************************************************
.proc end
; disable SR interrupts
@ -75,11 +76,12 @@ CODE_START := spi_p::CODE_START
; @function Read a byte from SPI
; @details
; Reads a byte from the shift register and stores it in the SPI code buffer
; @modifies A,Y
;********************************************************************************
.proc read
ldx bytes_written
ldy bytes_written
lda SPI_IO + IO::SR
sta CODE_START,x
sta (code_page),y
inc bytes_written
beq @new_page
rts

View File

@ -27,11 +27,11 @@ INCLUDE_UTILITY = 1
.endmacro
;_n_genlabel .set 0
_n_genlabel .set 0
;;********************************************************************************
;; @macro Generate a unique label
;;********************************************************************************
.macro GenLabel
.macro GenLabel name
.ident(.sprintf("generated_label%04X", _n_genlabel))
_n_genlabel .set _n_genlabel + 1
.endmacro