Files
sd2snes/snes/main.a65
ikari 48fecdb5c6 Fix refresh/cursor issues in "Favorite games" menu
Fixes #156

UI stuff is always the most painful...
- There was no way to return outside of the submenu system whether a
  function was executed so a `listsel_dirty` flag was introduced to force
  refresh
- Same for the `listsel_backup` variable
- Redrawing the list after removing a favorite resulted in some flickering so
  an additional `screen_dma_disable` flag was introduced to inhibit
  screen refresh (WRAM->VRAM DMA) until the redraw was finished.
  This feature can be useful for other redraw operations.
2023-02-20 00:40:41 +01:00

737 lines
12 KiB
Plaintext

.link page $c0
#include "memmap.i65"
#include "dma.i65"
.word nmihook
GAME_MAIN:
sep #$20 : .as
stz $4200 ; inhibit VBlank NMI
lda #$01
sta $420d
rep #$20 : .al
lda #$0000
sta @MCU_CMD ; clear MCU command register
rep #$20 : .al
lda #$0000
sta @MCU_PARAM ; clear MCU command parameters
sta @MCU_PARAM+2
stz dbg_ptr
lda WARM_SIGNATURE ; Was CMD_RESET issued before reset?
cmp #$fa50 ; If yes, then perform warm boot procedure
bne coldboot
eor WARM_COMPLEMENT
inc
bne coldboot
sta WARM_SIGNATURE
sta WARM_COMPLEMENT
lda SAVED_SP ; Restore previous stack pointer
tcs
; restore menu state that might have been destroyed
sep #$20 : .as
rep #$10 : .xl
stz $2183
ldx #$0000
stx $2181
stz $4370
ldx #!WRAM_BAK
lda #^WRAM_BAK
stx $4372
sta $4374
ldx #$2000
stx $4375
lda #$80
sta $4371
sta $420b
; The following initialization processes must not touch memory
; structures used by the file selector!
jsr killdma
jsr apu_ram_init
jsr waitblank
jsr snes_init
jsr setup_gfx
jsr store_wram_routines
jsr colortest
jsr video_init
jsr setup_hdma
jsr detect_ultra16
jsr detect_satellaview
lda @CFG_BRIGHTNESS_LIMIT
sta cur_bright
sta tgt_bright
sta $2100
jmp @set_bank ; Set bios bank, just to be sure
set_bank:
plp ; Restore processor state
rts ; Jump to the routine which called the sub-routine issuing CMD_RESET
coldboot: ; Regular, cold-start init
sep #$20 : .as
lda @CFG_SHOW_TRIBUTE
beq +
jsr near_screen
lda #$00
sta @CFG_SHOW_TRIBUTE
+ jsr killdma
jsr clear_wram
jsr apu_ram_init
jsr waitblank
jsr snes_init
jsr setup_gfx
jsr store_wram_routines
jsr colortest
jsr video_init
jsr setup_hdma
jsr detect_ultra16
jsr detect_satellaview
jsr screen_on
jsr wait_mcu_ready
jsr filesel_init
sep #$20 : .as
lda @ST_RTC_VALID
beq +
jsl rtc_init
+
jsr fileselloop
sei
stz $4200
jmp @infloop ; infinite loop in WRAM
colortest:
sep #$20 : .as
rep #$10 : .xl
stz $2130
rts
setup_gfx:
sep #$20 : .as
rep #$10 : .xl
stz $4200
stz $420b
stz $420c
; clear tilemap buffers
ldx #$8000
stx $2181
lda #$00
sta $2183
DMA7(#$08, #$8000, #^zero, #!zero, #$80)
; generate fonts
jsr genfonts
; clear BG1 tilemap
ldx #BG1_TILE_BASE
stx $2116
DMA7(#$09, #$1000, #^zero, #!zero, #$18)
; clear BG2 tilemap
ldx #BG2_TILE_BASE
stx $2116
DMA7(#$09, #$1000, #^zero, #!zero, #$18)
; clear OAM tables
ldx #$0000
stx $2102
DMA7(#$08, #$220, #^zero, #!zero, #$04)
; copy logo tiles
ldx #$2000
stx $2116
DMA7(#$01, #$4000, #^logo, #!logo, #$18)
; generate logo tilemap
ldx #BG1_TILE_BASE
stx $2116
ldx #$0100
- stx $2118
inx
cpx #$01e0
bne -
; copy sprites tiles
ldx #OAM_TILE_BASE
stx $2116
DMA7(#$01, #$500, #^logospr, #!logospr, #$18)
; set OAM tables
ldx #$0000
stx $2102
DMA7(#$00, #$60, #^oam_data_l, #!oam_data_l, #$04)
ldx #$0100
stx $2102
DMA7(#$00, #$09, #^oam_data_h, #!oam_data_h, #$04)
; set palette
stz $2121
DMA7(#$00, #$200, #^palette, #!palette, #$22)
stz $2121
; copy hdma tables so we can work "without" the cartridge
; palette
lda #^hdma_pal
ldx #!hdma_pal
stx $2181
sta $2183
DMA7(#$00, #55, #^hdma_pal_src, #!hdma_pal_src, #$80)
; CG addr for palette
lda #^hdma_cg_addr
ldx #!hdma_cg_addr
stx $2181
sta $2183
DMA7(#$00, #227, #^hdma_cg_addr_src, #!hdma_cg_addr_src, #$80)
; screen mode
lda #^hdma_mode
ldx #!hdma_mode
stx $2181
sta $2183
DMA7(#$00, #5, #^hdma_mode_src, #!hdma_mode_src, #$80)
; bg scroll
lda #^hdma_bg1scroll
ldx #!hdma_bg1scroll
stx $2181
sta $2183
DMA7(#$00, #21, #^hdma_bg1scroll_src, #!hdma_bg1scroll_src, #$80);
lda #^hdma_bg2scroll
ldx #!hdma_bg2scroll
stx $2181
sta $2183
DMA7(#$00, #13, #^hdma_bg2scroll_src, #!hdma_bg2scroll_src, #$80);
; color math
lda #^hdma_math
ldx #!hdma_math
stx $2181
sta $2183
DMA7(#$00, #19, #^hdma_math_src, #!hdma_math_src, #$80);
; initialize window stack
ldx #$ffff
stx window_stack_head
rts
genfonts:
php
rep #$10 : .xl
sep #$20 : .as
; clear VRAM font areas
ldx #$0000
stx $2116
DMA7(#$09, #$4000, #^zero, #!zero, #$18)
ldx #$4000
stx $2116
DMA7(#$09, #$2000, #^zero, #!zero, #$18)
sep #$10 : .xs
rep #$20 : .al
stz $2116
stz $2117
ldx #$01
stx $4370
ldx #^font
stx $4374
lda #!font
sta $4372
lda #$0010
sta $4375
ldx #$18
stx $4371
lda #$0000
- sta $2116
ldx #$10
stx $4375
ldx #$80
stx $420b
clc
adc #$20
cmp #$2000
bne -
ldx #^font
stx $4374
lda #!font
sta $4372
lda #$4000
- sta $2116
ldx #$10
stx $4375
ldx #$80
stx $420b
clc
adc #$10
cmp #$5000
bne -
plp
rts
video_init:
sep #$20 : .as ; 8-bit accumulator
rep #$10 : .xl ; 16-bit index
lda #$03 ; mode 3, mode 5 via HDMA
sta $2105
lda #$58 ; Tilemap addr 0xB000
ora #$02 ; SC size 32x64
sta $2107 ; for BG1
lda #$50 ; Tilemap addr 0xA000
ora #$02 ; SC size 32x64
sta $2108 ; for BG2
lda #$40 ; chr base addr:
sta $210b ; BG1=0x0000, BG2=0x8000
lda #$13 ; enable BG1+BG2+OBJ
sta $212c ; BG Main
lda #$13 ; enable BG1+BG2+OBJ
sta $212d ; BG Sub
lda #$20 ; Window 1 for color
sta $2125 ; Color window
lda #$01 ; cut off leftmost subscreen pixel garbage
sta $2126
lda #$fe
sta $2127
jsr setup_224
lda #$10
sta $2130
lda #$1f
sta $212e
sta $212f
; stz $2121
lda #8
sta bar_yl
stz cur_bright
stz tgt_bright
lda #$01
sta fade_speed
stz fade_count
stz idle_count
stz idle_count+1
stz screen_dma_disable
stz screen_dma_disable+1
rts
screen_on:
stz $2100 ; screen on, 0% brightness
lda @CFG_BRIGHTNESS_LIMIT
sta tgt_bright
sta bright_limit
rts
snes_init:
sep #$20 : .as ; 8-bit accumulator
rep #$10 : .xl ; 16-bit index
stz $4200
lda #$ff
sta $4201
stz $4202
stz $4203
stz $4204
stz $4205
stz $4206
stz $4207
stz $4208
stz $4209
stz $420a
stz $420b
stz $420c
lda #$8f
sta $2100 ; INIDISP: force blank
lda #$03 ; 8x8+16x16; name=0; base=3
sta $2101
stz $2102
stz $2103
; stz $2104 ; (OAM Data?!)
; stz $2104 ; (OAM Data?!)
stz $2105
stz $2106
stz $2107
stz $2108
stz $2109
stz $210a
stz $210b
stz $210c
stz $210d
stz $210d
stz $210e
stz $210e
stz $210f
stz $210f
lda #$05
sta $2110
stz $2110
stz $2111
stz $2111
stz $2112
stz $2112
stz $2113
stz $2113
stz $2114
stz $2114
lda #$80
sta $2115
stz $2116
stz $2117
; stz $2118 ;(VRAM Data?!)
; stz $2119 ;(VRAM Data?!)
stz $211a
stz $211b
lda #$01
sta $211b
stz $211c
stz $211c
stz $211d
stz $211d
stz $211e
sta $211e
stz $211f
stz $211f
stz $2120
stz $2120
stz $2121
; stz $2122 ; (CG Data?!)
; stz $2122 ; (CG Data?!)
stz $2123
stz $2124
stz $2125
stz $2126
stz $2127
stz $2128
stz $2129
stz $212a
stz $212b
stz $212c
stz $212d
stz $212e
stz $212f
lda #$30
sta $2130
stz $2131
lda #$e0
sta $2132
stz $2133
rts
clear_vram:
php
sep #$20 : .as
rep #$10 : .xl
lda $2100
pha
lda #$80
sta $2100
sta $2115
ldx #$8000
ldy #$0000
stx $2116
- sty $2118
dex
bne -
pla
sta $2100
plp
rts
.byt "fadeloop"
; *=$002a10
; via $7ef100
; acknowledge ready for ROM load
; wait for ACK
; fade screen
; acknowledge WRAM init done (send RESET)
fadeloop:
sep #$30 : .as : .xs
phk
plb
stz $4200
sei
sta MCU_CMD
ldx cur_bright
fadeloop_start
lda $4212
asl
bcs fadeloop_start
- lda $4212
asl
bcc -
dex
dex
stx $2100
bpl fadeloop_start
stz $2126
stz $212e
stz $2131
stz $2130
lda #$80
sta $2100
stz $2a00
stz $420c
; DMA fill WRAM banks
ldx #$00
rep #$10 : .xl
stz $2183
stx $2181
stx $4375
lda #$55
sta $2aff ; WRAM fill value
ldx #$8008
stx $4370
ldx #$2aff
stx $4372
stz $4374
lda #$80
; fill bank $7e
sta $420b
; fill bank $7f
sta $420b
; reset PPU2 H/V odd/even read flag
; (fix for uninitialized $213c/$213d reads)
lda $213f
; fix for uninitialized DMA transfers
rep #$20 : .al
lda #$ffff
ldy #$007c
- dey
dey
sta $4300, y
bne -
lda #$fe80 ; - bra -
sta @$7fffe0
lda #CMD_RESET
sta MCU_CMD
jmp @$7fffe0
- bra -
.byt "fadeloop_end"
; stores routines in WRAM (including payload for block ram copy)
store_wram_routines:
; copy wram_routine_src
; copy store_blockram_routine
; copy fadeloop
php
rep #$30 : .xl : .al
lda #$007f
ldx #!wram_routine_src
ldy #!WRAM_ROUTINE
phb
mvn $7e, $c0
lda #$007f
ldx #!store_blockram_routine_src
ldy #!WRAM_STORE_BLOCKRAM_ROUTINE
mvn $7e, $c0
lda #$00ee
ldx #!fadeloop
ldy #!WRAM_FADELOOP
mvn $7e, $c0
lda #$000a
ldx #!wram_wait_mcu_src
ldy #!WRAM_WAIT_MCU
mvn $7e, $c0
lda #$007f
ldx #!wram_load_ultra16_cfg_src
ldy #!WRAM_LOAD_ULTRA16_CFG
mvn $7e, $c0
plb
plp
rts
; *=$7ef080
store_blockram_routine_src:
php
sep #$20 : .as
rep #$10 : .xl
lda #$80
sta infloop
lda #$fe
sta infloop+1
rep #$20 : .al
lda #$00ee
ldx #!WRAM_FADELOOP
ldy #!BRAM_ROUTINE
phb
mvn $00, $7e
plb
plp
rtl
; *=$7ef000
wram_routine_src:
php
sep #$20 : .as
rep #$10 : .xl
; acknowledge ready for FPGA reconf
lda #CMD_FPGA_RECONF
sta @MCU_CMD
; wait for ACK (reconf done or not necessary)
- lda @SNES_CMD
cmp #$77
bne -
; install fade loop in block RAM after FPGA reconf
; must reside in WRAM prior to copying! ROM not available
jsl @WRAM_STORE_BLOCKRAM_ROUTINE
jsl @BRAM_ROUTINE
plp
rtl
; *=$7ef200
wram_wait_mcu_src:
.as
- lda @SNES_CMD
cmp #$55
bne -
rtl
; *=$7ef210
wram_load_ultra16_cfg_src:
.as
lda @$0021c1
and #$fe
sta @$0021c1
lda @$c70000
pha
lda @$0021c1
ora #$01
sta @$0021c1
pla
sta @ST_U16_CFG
rtl
game_handshake:
php
sep #$20 : .as
pha
lda #$01
jsr hide_cursor
jsr draw_loading_window
jsr waitblank
; send initial request to MCU
lda #$00
sta @SNES_CMD
sta $4200
sei
pla
sta @MCU_CMD
; wait for ACK/NACK with error (noimpl warning etc.)
- lda @SNES_CMD
cmp #$55
beq +
cmp #$aa
beq game_handshake_error
bra -
+ lda #$55
sta @MCU_CMD
; jump to WRAM
jsl @WRAM_ROUTINE
plp
rts
game_handshake_error:
; TODO display meaningful error message
jsr pop_window
plp
rts
wait_mcu_ready:
php
sep #$20 : .as
lda #$00
sta @MCU_CMD
- lda @SNES_CMD
cmp #$55
bne -
plp
rts
clear_wram:
php
rep #$10 : .xl
ldx #$0000
stz $2183
stx $2181
lda #$55
sta $2aff ; WRAM fill value
ldx #$8008
stx $4370
ldx #$2aff
stx $4372
stz $4374
lda #$80
; fill $7e0000-$7e1fef (spare a bit of stack)
ldx #$1ff0
stx $4375
sta $420b
; fill $7e2000-$7effff
ldx #$2000
stx $2181
ldx #$e000
stx $4375
sta $420b
; fill bank $7f
ldx #$0000
stx $4375
sta $420b
plp
rts
backup_wram:
php
rep #$10 : .xl
sep #$20 : .as
ldx #$0000
stx $2181
stz $2183
DMA7(#$80, #$2000, #^WRAM_BAK, #!WRAM_BAK, #$80)
plp
rts
detect_ultra16:
php
sep #$20 : .as
lda #$aa
sta @$0021c0
lda @$0021c0
cmp #$55
beq detect_ultra16_found
lda #$00
sta @ST_IS_U16
bra detect_ultra16_out
detect_ultra16_found:
lda @$0021c2
sta @ST_IS_U16
jsl @WRAM_LOAD_ULTRA16_CFG
lda @$0021c1
and #$fb
sta @$0021c1
detect_ultra16_out:
lda #$55
sta @$0021c0
plp
rts
detect_satellaview:
php
sep #$20 : .as
lda #$aa
sta $2188
cmp $2188
bne detect_satellaview_out
lda #$55
sta $2188
cmp $2188
bne detect_satellaview_out
detect_satellaview_found:
stz $2188
stz $2189
stz $218e
stz $218f
lda #$01
sta @ST_HAS_SATELLAVIEW
plp
rts
detect_satellaview_out:
lda #$00
sta @ST_HAS_SATELLAVIEW
plp
rts