

.segment "BIOS"

.define reg_spi $4000
.define reg_spi_cfg $4002
.define reg_usb $4003
.define reg_ste $4004
.define reg_key $4005
.define reg_cfg $4006
.define reg_map $4007
.define reg_ver $4008
.define reg_i2c $4009

_bi_spi_data:
.addr $2000 | spi_data
_bi_usb_data:
.addr $2000 | usb_data
_bi_ptr1:
.addr $2000 | ptr1
_bi_ptr2:
.addr $2000 | ptr2
_bi_arg8:
.addr $2000 | arg8
_bi_ret8:
.addr $2000 | ret8
_bi_boot_ver:
.addr $5000
_bi_fpga_ver:
.addr reg_ver
_bi_usb_to_ram:
jmp bi_usb_to_ram
_bi_ram_to_usb:
jmp bi_ram_to_usb
_bi_usb_rd_byte:
jmp bi_usb_rd_byte
_bi_usb_wr_byte:
jmp bi_usb_wr_byte
_bi_set_bank_8k:
jmp bi_set_bank_8k
_bi_set_bank_512k:
jmp bi_set_bank_512k
_bi_stop_os:
jmp bi_stop_os
_bi_usb_rd_rdy:
jmp bi_usb_rd_rdy
_bi_usb_wr_rdy:
jmp bi_usb_wr_rdy
_bi_init:
jmp bi_init
_bi_init_os:
jmp bi_init_os
_bi_start_game:
jmp bi_start_game

_bi_spi:
jmp bi_spi
_bi_spi_q:
jmp bi_spi_q
_bi_spi_qq:
jmp bi_spi_qq
_bi_spi_spd_lo:
jmp bi_spi_spd_lo
_bi_spi_spd_hi:
jmp bi_spi_spd_hi
_bi_ss_on:
jmp bi_ss_on
_bi_ss_off:
jmp bi_ss_off
_bi_spi_ard_on:
jmp bi_spi_ard_on
_bi_spi_ard_off:
jmp bi_spi_ard_off
_bi_spi_to_ram:
jmp bi_spi_to_ram
_bi_ram_to_spi:
jmp bi_ram_to_spi
_bi_i2c_rx:
jmp bi_i2c_rx
_bi_i2c_tx:
jmp bi_i2c_tx
_bi_i2c_start:
jmp bi_i2c_start
_bi_i2c_stop:
jmp bi_i2c_stop




.define st_spi    1
.define st_usb_wr 4 
.define st_usb_rd 8

.define cfg_regs_oe_off 1
.define cfg_regs_we_off 2
.define cfg_usb_boot    4
.define cfg_skip_eep    8
.define cfg_ram_we_off  16

.define spi_ss  1
.define spi_spd 2
.define spi_ard 4

.define idat 128
.define iclk 2

bi_init:  
    lda #$00    ; map ed registers
    tam #4

    lda #$A5
    sta reg_key ; unlock ed regs

    lda #0
    sta reg_cfg

    lda #0
    sta reg_spi_cfg

    lda #iclk
    sta reg_i2c
    lda #iclk | idat
    sta reg_i2c

    rts

bi_init_os:
    jsr bi_init
    lda #cfg_skip_eep
    sta reg_cfg
    rts

bi_stop_os:
    lda arg8
    sta reg_cfg
    jmp $5004

bi_usb_to_ram:
    ldy #0
@0:
    ldx #2
@1:
    lda reg_ste
    and #st_usb_rd
    beq @1
    lda reg_usb
    sta (ptr1), y
    iny
    bne @1

    inc ptr1+1
    dex 
    bne @1
    dec arg8
    bne @0

    rts

bi_ram_to_usb:
    ldy #0
@0:
    ldx #2
@1:
    lda reg_ste
    and #st_usb_wr
    beq @1
    lda (ptr1), y
    sta reg_usb
    iny
    bne @1

    inc ptr1+1
    dex 
    bne @1
    dec arg8
    bne @0

    rts    

bi_usb_rd_byte:
    lda reg_ste
    and #st_usb_rd
    beq bi_usb_rd_byte
    lda reg_usb
    sta usb_data
    rts

bi_usb_wr_byte:
    lda reg_ste
    and #st_usb_wr
    beq bi_usb_wr_byte
    lda usb_data
    sta reg_usb
    rts

bi_set_bank_8k:
    lda arg8
    tam #8
    rts

bi_set_bank_512k:
    lda arg8
    sta reg_map
    rts

bi_usb_rd_rdy:
    lda reg_ste
    and #st_usb_rd
    sta ret8
    rts

bi_usb_wr_rdy:
    lda reg_ste
    and #st_usb_wr
    sta ret8
    rts




bi_spi:
    lda spi_data
    sta reg_spi
@1:
    lda reg_ste
    and #st_spi
    beq @1
    lda reg_spi
    sta spi_data
    rts

bi_spi_q:
    lda spi_data
    sta reg_spi
    lda reg_spi
    sta spi_data
    rts

bi_spi_qq:
    lda spi_data
    sta reg_spi
    rts



bi_spi_spd_lo:
    lda reg_spi_cfg
    ora #spi_spd
    sta reg_spi_cfg
    rts

bi_spi_spd_hi:
    lda reg_spi_cfg
    and #~spi_spd
    sta reg_spi_cfg
    rts

bi_ss_on:
    lda reg_spi_cfg
    and #~spi_ss
    sta reg_spi_cfg
    rts

bi_ss_off:
    lda reg_spi_cfg
    ora #spi_ss
    sta reg_spi_cfg
    rts

bi_spi_ard_on:
    lda reg_spi_cfg
    ora #spi_ard
    sta reg_spi_cfg
    rts
bi_spi_ard_off:
    lda reg_spi_cfg
    and #~spi_ard
    sta reg_spi_cfg
    rts

bi_spi_to_ram:
    jsr bi_spi_ard_on
@0:
    lda reg_spi
    ldx #0
    ldy #0
@1:
    lda reg_spi
    cmp #$fe
    beq @11
    inx
    bne @1
    iny
    bne @1
    lda #$D3
    bra @3
@11:
    lda ptr1
    sta @2+3
    lda ptr1+1
    sta @2+4

@2:    
    tai reg_spi, 0, 512

    lda reg_spi
    inc ptr1+1
    inc ptr1+1

    dec arg8
    bne @0

    lda #0
@3:
    sta ret8
    jsr bi_spi_ard_off
    rts

bi_ram_to_spi:

@0:;send begin cmd
    lda #$ff
    sta reg_spi
    sta reg_spi
    lda #$fc
    sta reg_spi

    ldy #0
    ldx #2
@1:;write block
    lda (ptr1), y
    sta reg_spi
    iny
    bne @1
    
    inc ptr1+1
    dex
    bne @1

    lda #$ff
    sta reg_spi
    sta reg_spi
    sta reg_spi

;check if wr begins
    lda reg_spi
    and  #$1f
    cmp #5
    bne @10

    ldx #0
    ldy #0
@2:;check if wr with success
    nop
    nop
    lda #$ff
    sta reg_spi
    lda reg_spi
    cmp #$ff
    beq @3
    dex 
    bne @2
    dey
    bne @2
    bra @11
@3:

    dec arg8
    bne @0
;finalize wr operation

    lda #$fd
    sta reg_spi
    lda #$ff
    sta reg_spi
    ldx #0
    ldy #0
@4:
    nop
    nop
    lda #$ff
    sta reg_spi
    lda reg_spi  
    and #1
    cmp #0
    bne @5
    dex
    bne @4
    dey
    bne @4
    bra @12

@5:
    lda #0 
    bra @100
@10:
    lda #$d5
    bra @100
@11:
    lda #$d6
    bra @100
@12:
    lda #$d7 
    bra @100
@100:
    sta ret8
    rts

bi_start_game:
    lda arg8
    tax
    tii start_game_code, $3f00,  start_game_code_end - start_game_code
    jmp $3f00
start_game_code:
    lda #$04
    sta reg_map
    ;lda #cfg_regs_oe_off | cfg_regs_we_off | cfg_skip_eep 
    txa
    sta reg_cfg
   
    lda #$00
    tam #128
    csl
    jmp ($fffe)
start_game_code_end:

bi_i2c_rx:
    ldy #8
    ldx #idat
    stx reg_i2c
    lda #0
@1:
    asl 
    ldx #idat | iclk
    stx reg_i2c
    nop
    nop
    ora reg_i2c
    ldx #idat
    stx reg_i2c
    dey
    bne @1

    sta ret8
    lda arg8
    and #idat
    sta reg_i2c
    nop
    ora #iclk
    sta reg_i2c
    nop
    and #idat
    sta reg_i2c
    nop
    rts

bi_i2c_tx:
    ldx arg8
    ldy #8
@1:
    txa
    and #idat
    sta reg_i2c
    nop
    nop
    nop
    ora #iclk
    sta reg_i2c
    nop
    nop
    nop
    and #idat
    sta reg_i2c
    txa
    asl
    tax
    dey
    bne @1

    lda #idat
    sta reg_i2c
    lda #idat | iclk
    sta reg_i2c
    lda reg_i2c
    sta ret8
    lda #idat
    sta reg_i2c
    rts

bi_i2c_start:
    lda #iclk | idat
    sta reg_i2c
    nop
    lda #iclk
    sta reg_i2c
    nop
    lda #0
    sta reg_i2c
    nop
    rts
bi_i2c_stop:
    lda #0
    sta reg_i2c
    nop
    lda #iclk
    sta reg_i2c
    nop
    lda #iclk | idat
    sta reg_i2c
    nop
    rts


irq:
    rti

.segment "VECTORS"

.word $0100
.word irq 
.word irq 
.word irq   ;irq1
.word irq   ;irq2

.word irq   ;$fffa tmr
.word irq   ;$fffc nmi
.word rst   ;$fffe irq / brk