asm-test/bootloader.asm.in

175 lines
4.2 KiB
NASM

; -*-asm-*-
include(`common.m4')
BRA r :reset ; RESB
JMP a 0202 ; IRQB
;; reset stack
reset: SEI i
LDX # ff
TXS i
;; CS high, SCLK low
LDA # hh(M_CS)
STA a VIA2_PORTB
LDA # hh(M_DDR_MASK)
STA a VIA2_DDRB
LDX # hh(M_CFGH)
LDY # hh(M_CFGL_BAUD_115200)
JSR a :spi16
define(SPI_IN_H, 2)dnl
define(SPI_IN_L, 1)dnl
define(SPI_OUT_H, 4)dnl
define(SPI_OUT_L, 3)dnl
define(LDR_OFFSET, fc)dnl
define(LDR_LEN, fd)dnl
define(LDR_ADDR_L, fe)dnl
define(LDR_ADDR_H, ff)dnl
;; read header
;;; begin hdr_len
LDX # hh(M_W_DATAH|M_W_DATAH_TE|M_W_DATAH_RTS)
LDY # 0
BRA r :_read_hdr_spi
read_header: LDX # hh(M_W_DATAH|M_W_DATAH_RTS)
LDY zp SPI_OUT_L
_read_hdr_spi: JSR a :spi16
LDA zp SPI_OUT_H
BMI r :_hdr_len ; BMI = if the leftmost bit is 0
_wait_hdr_len: LDX # hh(M_W_DATAH|M_W_DATAH_TE|M_W_DATAH_RTS)
LDY # 0
JSR a :spi16
LDA zp SPI_OUT_H
BPL r :_wait_hdr_len ; BPL = if the leftmost bit is 0
_hdr_len: LDA zp SPI_OUT_L
STA zp LDR_LEN
;;; end hdr_len
;;; begin hdr_al
LDX # hh(M_W_DATAH|M_W_DATAH_RTS)
LDY # 4c ; L
JSR a :spi16
LDA zp SPI_OUT_H
BMI r :_hdr_al ; BMI = if the leftmost bit is 0
_wait_hdr_al: LDX # hh(M_W_DATAH|M_W_DATAH_TE|M_W_DATAH_RTS)
LDY # 0
JSR a :spi16
LDA zp SPI_OUT_H
BPL r :_wait_hdr_al ; BPL = if the leftmost bit is 0
_hdr_al: LDA zp SPI_OUT_L
STA zp LDR_ADDR_L
;;; end hdr_al
;;; begin hdr_ah
LDX # hh(M_W_DATAH|M_W_DATAH_RTS)
LDY # 44 ; D
JSR a :spi16
LDA zp SPI_OUT_H
BMI r :_hdr_ah ; BMI = if the leftmost bit is 0
_wait_hdr_ah: LDX # hh(M_W_DATAH|M_W_DATAH_TE|M_W_DATAH_RTS)
LDY # 0
JSR a :spi16
LDA zp SPI_OUT_H
BPL r :_wait_hdr_ah ; BPL = if the leftmost bit is 0
_hdr_ah: LDA zp SPI_OUT_L
STA zp LDR_ADDR_H
;;; end hdr_ah
LDA zp LDR_LEN
BEQ r :_ldr_jump ; if (len == zero) goto _ldr_jump;
STZ zp LDR_OFFSET
LDX # hh(M_W_DATAH|M_W_DATAH_RTS)
LDY # 52 ; R
JSR a :spi16
BRA r :_data_cmp
;; transfer data
wait_data: LDX # hh(M_W_DATAH|M_W_DATAH_TE|M_W_DATAH_RTS)
LDY # 0
JSR a :spi16
_data_cmp: LDA zp SPI_OUT_H
BPL r :wait_data ; BPL = if the leftmost bit is 0
copy_fifo: LDY zp LDR_OFFSET
LDA zp SPI_OUT_L
STA (zp),y LDR_ADDR_L
INC zp LDR_OFFSET
DEC zp LDR_LEN
BEQ r :read_header
LDX # hh(M_W_DATAH)
LDY zp SPI_OUT_L
JSR a :spi16
LDA zp SPI_OUT_H
BMI r :copy_fifo ; BMI = if the leftmost bit is 1
BRA r :wait_data
_ldr_jump: JMP (a) LDR_ADDR_L
;; CS low, SCLK low
spi16: LDA # %00000000
STA a VIA2_PORTB
STX zp 2
STY zp 1
;; SPI output
STZ zp 4
STZ zp 3
LDX # 2
_spi_next: LDY # 8
STY zp 0
_spi_8: ASL zp,x 0
LDA # 0 ; preclear MOSI
BCC r :_spi_zout
ORA # hh(M_DIN) ; set MOSI
_spi_zout: STA a VIA2_PORTB
ORA # hh(M_SCLK) ; set SCLK
STA a VIA2_PORTB
LDY a VIA2_PORTB ; DOUT on bit 7
CLC i ; preclear MISO
BPL r :_spi_zin ;
SEC i ; set MISO
_spi_zin: ROL zp,x 2
AND # hh(~M_SCLK & 0xff) ; clear SCLK
STA a VIA2_PORTB
DEC zp 0
BNE r :_spi_8
DEX i
BNE r :_spi_next
;; CS high, SCLK low
LDA # hh(M_CS)
STA a VIA2_PORTB
RTS s