From 811d50122fca8eb2fbd7b278600a386333029551 Mon Sep 17 00:00:00 2001 From: "matthias@arch" Date: Wed, 20 Dec 2023 12:27:54 +0100 Subject: [PATCH] wip: keyboard --- Makefile | 13 +- linker.conf | 2 +- main.s65 | 18 ++- programs/memcopy.s65 | 13 +- programs/spi-menu.s65 | 2 +- spicode.s65 | 275 +++++++++++++++++++++++++----------------- system/io_W65C22.h65 | 7 +- system/lcd.h65 | 15 +++ system/spi.s65 | 6 +- utility.h65 | 4 +- 10 files changed, 229 insertions(+), 126 deletions(-) diff --git a/Makefile b/Makefile index 84e3b7a..87e51ed 100644 --- a/Makefile +++ b/Makefile @@ -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) diff --git a/linker.conf b/linker.conf index 3ccb861..64101fe 100644 --- a/linker.conf +++ b/linker.conf @@ -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; diff --git a/main.s65 b/main.s65 index 20e5eaa..fbcd708 100644 --- a/main.s65 +++ b/main.s65 @@ -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 diff --git a/programs/memcopy.s65 b/programs/memcopy.s65 index b8c20ca..53c3fc6 100644 --- a/programs/memcopy.s65 +++ b/programs/memcopy.s65 @@ -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 diff --git a/programs/spi-menu.s65 b/programs/spi-menu.s65 index cd467db..ca58aed 100644 --- a/programs/spi-menu.s65 +++ b/programs/spi-menu.s65 @@ -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" diff --git a/spicode.s65 b/spicode.s65 index d226f5a..6fe433c 100644 --- a/spicode.s65 +++ b/spicode.s65 @@ -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 ARG1 + lda #<$3000 + sta ARG2 + lda #>$3000 + sta ARG3 + ldy #20 + jsr memcopy + + 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 + +; .out .sprintf("SPI: CODE_START at %x", *) -@print: -@printloop: - lda #'r' - jsr lcd::print_char - jsr @print_state - 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 - lda #';' + ; 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 - 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 #')' + +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 -TEST_MEMSIZE = $A + ; 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 -RBUF_MEM_START: - .res TEST_MEMSIZE -RBUF_MEM_END: - + ; 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 -.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 + lda #'>' + jsr lcd::print_char 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: +keycode: .res 3 +kb_irq1: + lda #'!' + jsr lcd::print_char + jsr irq_on_shift_reg + lda #':' + jsr lcd::print_char rts -@read_wrap: ; ptr == RB_LENGTH -> ptr = 0 - stz RB_READ - ; make sure Pz is not set - ldx #$01 +.byte '=' +kb_irq2: + lda #'?' + jsr lcd::print_char + jsr irq_on_timer + lda #';' + jsr lcd::print_char 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 '@' diff --git a/system/io_W65C22.h65 b/system/io_W65C22.h65 index 812e4a8..4662454 100644 --- a/system/io_W65C22.h65 +++ b/system/io_W65C22.h65 @@ -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 diff --git a/system/lcd.h65 b/system/lcd.h65 index 392baba..eba5bcb 100644 --- a/system/lcd.h65 +++ b/system/lcd.h65 @@ -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 ARG1 + .endif jsr lcd::print .endmacro diff --git a/system/spi.s65 b/system/spi.s65 index 18cc7ef..8938b51 100644 --- a/system/spi.s65 +++ b/system/spi.s65 @@ -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 diff --git a/utility.h65 b/utility.h65 index ad66569..6463add 100644 --- a/utility.h65 +++ b/utility.h65 @@ -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