diff --git a/system/spi.s65 b/system/spi.s65 index bc275fc..00b57c5 100644 --- a/system/spi.s65 +++ b/system/spi.s65 @@ -10,30 +10,148 @@ .ifndef INCLUDE_SPI INCLUDE_SPI = 1 +.scope spi_p +.zeropage +code_page: .res 2 ; SPI_CODE_START + pages_written * 256 .bss -SPI_PAGES_WRITTEN: .res 1 -SPI_BYTES_WRITTEN: .res 1 +bytes_written: .res 1 +pages_written: .res 1 + +.include "util/math.s65" +; spi-transferred code will be placed here .segment "SPI" -SPI_CODE_START: ; .res $1000 - lda $1000 - sta $1000 - lda $1000 - sta $1000 - lda $1000 - sta $1000 +SPI_CODE_START: + lda '$' + jsr lcd_char + lda #TEST_FMT + sta ARG1 + lda #TEST_OUT + sta ARG3 + lda #$a9 + sta ARG4 + lda #$3c + sta ARG5 + lda #$10 + sta ARG6 + jsr strf + Print TEST_OUT +@spiloop: lda IO1 + IO::RA - lda IO1 + IO::RA - bra SPI_CODE_START - ; jsr lcd_clear - ; PrintSlow msg,20 - ; jmp home -; msg: - ; .asciiz "YO DAS WAR SPI" + lda IO2 + IO::RA + nop + bra @spiloop + jmp home + +; TODO allocate zp memory +fmt_idx = $30 +out_idx = $31 +;******************************************************************************** +; @function Format a string +; @details +; If there is no value to be read, the Pz will be set +; Formats: +; - u: unsigned decimal integer (1 byte) +; - U: unsigned decimal integer (2 bytes) +; @param ARG0-1: Format string address +; @param ARG2-3: Output string address +; @param ARG4+: Additional parameters +; @returns +; @modifies: A, Y +;******************************************************************************** +.proc strf + stz out_idx + stz fmt_idx + ldy #0 ; position in string + ldx #0 ; index of format args +@loop: + ldy fmt_idx + lda (ARG0),y + beq @null + cmp #'%' + beq @percent +@normal_char: ; store A in output string + ldy out_idx + sta (ARG2),y + inc fmt_idx + inc out_idx + beq @out_overflow + bra @loop +@percent: ; check for format in next position + iny + sty fmt_idx + lda (ARG0),y + beq @null + ; formats + cmp #'x' + beq @format_hex1 + bra @normal_char +@format_hex1: ; 1 byte hex -> 2 chars + lda ARG4,x + phx + jsr int8_to_hex_str + ldy out_idx + sta (ARG2),y ; most sig digit + iny + beq @out_overflow + txa + sta (ARG2),y ; least sig digit + iny + beq @out_overflow + sty out_idx + plx + inx ; 1 byte of args handeled + ; bra @format_return +@format_return: ; increment fmt_idx to swallow the formating char + inc fmt_idx + bra @loop +@out_overflow: ; store 0 in last position + ldy #$ff + sty out_idx +@store_null: + lda #0 +@null: ; store and return + ldy out_idx + sta (ARG2),y +@rts: + rts +.endproc +;******************************************************************************** +; @function Convert a 1 byte number into two hex characters +; @param A: Number to convert +; @returns A: Most significant digit +; @returns X: Least significant digit +; @modifies X,Y,A +;******************************************************************************** +.proc int8_to_hex_str + pha + and #%00001111 + tay + ldx HEX_CHARS,y + pla + div A,16 + and #%00001111 + tay + lda HEX_CHARS,y + rts +.endproc + + + +HEX_CHARS: .byte "0123456789ABCDEF" + +TEST_FMT: .asciiz "%x -> %x -> %x:)" +TEST_OUT: .asciiz "TESTOUT" + +; SPI_P = as peripheral .code .struct SPI_P_Pins ; VIA addresses @@ -50,12 +168,20 @@ SPI_CODE_START: ; .res $1000 .endstruct ;******************************************************************************** -; @function Initialize the IO Adapter for SPI -; @param ARG0-1 Address of the SPI_Pins struct +; @function Begin listening for SPI transfers +; @details +; - initialize variables +; - configure shift register to shift in under external clock +; - enable shift register interrupts ;******************************************************************************** -.proc spi_p_init - stz SPI_PAGES_WRITTEN - stz SPI_BYTES_WRITTEN +.proc begin + stz pages_written + stz bytes_written + ; store address in zp + lda #SPI_CODE_START + sta code_page + 1 ; todo USE MASKS ; set Shift register to shift in under external clock on CB1 lda #IO::ACR::SR_SIN_PHIE @@ -64,21 +190,49 @@ SPI_CODE_START: ; .res $1000 ; enable SR interrupts lda #(IO::IRQ::IRQ | IO::IRQ::SR) sta SPI_IO + IO::IER - DEBUG_LED_ON 1 + + ; load SR to reset + lda SPI_IO + IO::SR rts .endproc -.proc spi_p_read - DEBUG_LED_ON 0 - ; print received byte +;******************************************************************************** +; @function Stop listening for SPI transfers +; @details +; Disables shift register interrupts +;******************************************************************************** +.proc end + ; disable SR interrupts + lda #IO::IRQ::SR + sta SPI_IO + IO::IER + rts +.endproc + + + +;******************************************************************************** +; @function Read a byte from SPI +; @details +; Reads a byte from the shift register and stores it in the SPI code buffer +;******************************************************************************** +.proc read + ldx bytes_written lda SPI_IO + IO::SR sta SPI_CODE_START,x - inc SPI_BYTES_WRITTEN - jsr lcd_char + inc bytes_written + beq @new_page + rts +@new_page: + inc pages_written + inc code_page + 1 rts .endproc +;******************************************************************************** +; @function Initialize the IO Adapter for SPI +; @param ARG0-1 Address of the SPI_Pins struct +;******************************************************************************** ;******************************************************************************** ; @function Read bytes ; @param X Number of bytes to send @@ -96,8 +250,8 @@ SPI_CODE_START: ; .res $1000 .proc send_data .endproc +.endscope + -_send_byte: - .endif