menu: SPC player (necronomfive, blargg)
This commit is contained in:
parent
c07b8f42c2
commit
f9c8e62f10
@ -1,4 +1,4 @@
|
|||||||
OBJS = header.ips reset.o65 main.o65 font.o65 palette.o65 data.o65 const.o65 logo.o65 logospr.o65 text.o65 dma.o65 menu.o65 pad.o65 time.o65 mainmenu.o65 sysinfo.o65 # gfx.o65 # vars.o65
|
OBJS = header.ips reset.o65 main.o65 font.o65 palette.o65 data.o65 const.o65 logo.o65 logospr.o65 text.o65 dma.o65 menu.o65 pad.o65 time.o65 mainmenu.o65 sysinfo.o65 spc700.o65 spcplay.o65 # gfx.o65 # vars.o65
|
||||||
|
|
||||||
all: clean menu.bin map
|
all: clean menu.bin map
|
||||||
|
|
||||||
|
|||||||
@ -168,4 +168,24 @@ text_mm_vmode_game .byt "Game video mode", 0
|
|||||||
text_mm_sysinfo .byt "System Information", 0
|
text_mm_sysinfo .byt "System Information", 0
|
||||||
text_statusbar_keys .byt "A:Select B:Back X:Menu", 0
|
text_statusbar_keys .byt "A:Select B:Back X:Menu", 0
|
||||||
text_last .byt "Run previous ROM: Press Start again to confirm", 0
|
text_last .byt "Run previous ROM: Press Start again to confirm", 0
|
||||||
|
text_system .byt "PPU1 Rev.: x PPU2 Rev.: y CPU Rev.: z",0
|
||||||
|
|
||||||
|
|
||||||
|
text_spcplay .byt "SPC Music Player", 0
|
||||||
|
spcplay_win_x .byt 15
|
||||||
|
spcplay_win_y .byt 15
|
||||||
|
spcplay_win_w .byt 33
|
||||||
|
spcplay_win_h .byt 5
|
||||||
|
|
||||||
|
text_spcload .byt "Loading SPC data to SPC700...", 0
|
||||||
|
text_spcstarta .byt "**** Now playing SPC tune ****", 0
|
||||||
|
text_spcstartb .byt "Name: ",0
|
||||||
|
text_spcstartc .byt "Song: ",0
|
||||||
|
text_spcstartd .byt "Artist:",0
|
||||||
|
|
||||||
|
spcstart_win_x .byt 10
|
||||||
|
spcstart_win_y .byt 13
|
||||||
|
spcstart_win_w .byt 44
|
||||||
|
spcstart_win_h .byt 9
|
||||||
|
|
||||||
|
text_spcid .byt "SNES-SPC700"
|
||||||
|
|||||||
@ -184,4 +184,9 @@ direntry_xscroll
|
|||||||
direntry_xscroll_wait
|
direntry_xscroll_wait
|
||||||
.word 0
|
.word 0
|
||||||
infloop .byt 0,0 ; to be filled w/ 80 FE
|
infloop .byt 0,0 ; to be filled w/ 80 FE
|
||||||
|
;------------------------
|
||||||
|
saved_sp
|
||||||
|
.word 0
|
||||||
|
warm_signature
|
||||||
|
.word 0
|
||||||
wram_fadeloop .byt 0
|
wram_fadeloop .byt 0
|
||||||
|
|||||||
@ -11,6 +11,35 @@ GAME_MAIN:
|
|||||||
sta @AVR_PARAM+2
|
sta @AVR_PARAM+2
|
||||||
sep #$20 : .as
|
sep #$20 : .as
|
||||||
stz $4200 ; inhibit VBlank NMI
|
stz $4200 ; inhibit VBlank NMI
|
||||||
|
|
||||||
|
rep #$20 : .al
|
||||||
|
lda @warm_signature ; Was CMD_RESET issued before reset?
|
||||||
|
cmp #$fa50 ; If yes, then perform warm boot procedure
|
||||||
|
bne coldboot
|
||||||
|
lda #$0000
|
||||||
|
sta @warm_signature
|
||||||
|
lda @saved_sp ; Restore previous stack pointer
|
||||||
|
tcs
|
||||||
|
sep #$20 : .as
|
||||||
|
|
||||||
|
jsr killdma ; The following initialization processes must not touch memory
|
||||||
|
jsr waitblank ; structures used by the main menu !
|
||||||
|
jsr snes_init
|
||||||
|
lda #$01
|
||||||
|
sta $420d ; fast cpu
|
||||||
|
jsr setup_gfx
|
||||||
|
jsr colortest
|
||||||
|
jsr setup_hdma
|
||||||
|
jsr tests
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
jsr killdma
|
jsr killdma
|
||||||
jsr waitblank
|
jsr waitblank
|
||||||
jsr snes_init
|
jsr snes_init
|
||||||
@ -70,12 +99,15 @@ killdma:
|
|||||||
|
|
||||||
|
|
||||||
waitblank:
|
waitblank:
|
||||||
|
php
|
||||||
|
sep #$30 : .as : .xs
|
||||||
- lda $4212
|
- lda $4212
|
||||||
and #$80
|
and #$80
|
||||||
bne -
|
bne -
|
||||||
- lda $4212
|
- lda $4212
|
||||||
and #$80
|
and #$80
|
||||||
beq -
|
beq -
|
||||||
|
plp
|
||||||
rts
|
rts
|
||||||
|
|
||||||
colortest:
|
colortest:
|
||||||
@ -225,6 +257,7 @@ tests:
|
|||||||
sta $212e
|
sta $212e
|
||||||
sta $212f
|
sta $212f
|
||||||
stz $2121
|
stz $2121
|
||||||
|
jsr waitblank
|
||||||
lda #$0f
|
lda #$0f
|
||||||
sta $2100 ;screen on, full brightness
|
sta $2100 ;screen on, full brightness
|
||||||
lda #9
|
lda #9
|
||||||
|
|||||||
@ -6,6 +6,11 @@
|
|||||||
/* These must be defined as constants, because they're used
|
/* These must be defined as constants, because they're used
|
||||||
* in calculation that is sent to PPU as parameters */
|
* in calculation that is sent to PPU as parameters */
|
||||||
|
|
||||||
|
#define APUIO0 $2140
|
||||||
|
#define APUIO1 $2141
|
||||||
|
#define APUIO2 $2142
|
||||||
|
#define APUIO3 $2143
|
||||||
|
|
||||||
#define BG1_TILE_BASE $5800
|
#define BG1_TILE_BASE $5800
|
||||||
#define BG2_TILE_BASE $5000
|
#define BG2_TILE_BASE $5000
|
||||||
|
|
||||||
@ -27,3 +32,9 @@
|
|||||||
#define ROOT_DIR $C10000
|
#define ROOT_DIR $C10000
|
||||||
|
|
||||||
#define CMD_SYSINFO $03
|
#define CMD_SYSINFO $03
|
||||||
|
#define CMD_LOADSPC $05
|
||||||
|
#define CMD_RESET $06
|
||||||
|
|
||||||
|
#define SPC_DATA $DD0000
|
||||||
|
#define SPC_HEADER $DE0000
|
||||||
|
#define SPC_DSP_REGS $DE0100
|
||||||
|
|||||||
@ -272,6 +272,10 @@ dirent_is_file
|
|||||||
lda #$0000
|
lda #$0000
|
||||||
bra dirent_type_cont
|
bra dirent_type_cont
|
||||||
+
|
+
|
||||||
|
cmp #$0003 ;SPC -> palette 2
|
||||||
|
bne +
|
||||||
|
lda #$0002
|
||||||
|
bra dirent_type_cont
|
||||||
cmp #$0004 ;IPS -> palette 2 (green)
|
cmp #$0004 ;IPS -> palette 2 (green)
|
||||||
bne +
|
bne +
|
||||||
lda #$0002
|
lda #$0002
|
||||||
@ -502,6 +506,8 @@ select_item:
|
|||||||
lda [dirptr_addr], y
|
lda [dirptr_addr], y
|
||||||
cmp #$01
|
cmp #$01
|
||||||
beq sel_is_file
|
beq sel_is_file
|
||||||
|
cmp #$03
|
||||||
|
beq sel_is_spc
|
||||||
cmp #$04
|
cmp #$04
|
||||||
beq sel_is_file
|
beq sel_is_file
|
||||||
cmp #$80
|
cmp #$80
|
||||||
@ -519,6 +525,9 @@ sel_is_parent
|
|||||||
sel_is_dir
|
sel_is_dir
|
||||||
jsr select_dir
|
jsr select_dir
|
||||||
bra select_item_cont
|
bra select_item_cont
|
||||||
|
sel_is_spc
|
||||||
|
jsr select_spc
|
||||||
|
bra select_item_cont
|
||||||
|
|
||||||
select_file:
|
select_file:
|
||||||
; have avr load the rom
|
; have avr load the rom
|
||||||
@ -635,6 +644,27 @@ select_parent:
|
|||||||
sta @menu_dirty
|
sta @menu_dirty
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
select_spc:
|
||||||
|
dey
|
||||||
|
rep #$20 : .al
|
||||||
|
lda [dirptr_addr], y
|
||||||
|
and #$00ff
|
||||||
|
sta @AVR_PARAM+2
|
||||||
|
dey
|
||||||
|
dey
|
||||||
|
lda [dirptr_addr], y
|
||||||
|
sta @AVR_PARAM
|
||||||
|
sep #$20 : .as
|
||||||
|
lda #CMD_LOADSPC
|
||||||
|
sta @AVR_CMD
|
||||||
|
wait_spc:
|
||||||
|
lda @AVR_CMD
|
||||||
|
cmp #$00
|
||||||
|
bne wait_spc
|
||||||
|
jsr spcplayer
|
||||||
|
jsr restore_screen
|
||||||
|
rts
|
||||||
|
|
||||||
menu_key_x:
|
menu_key_x:
|
||||||
jsr mainmenu
|
jsr mainmenu
|
||||||
rts
|
rts
|
||||||
|
|||||||
61
snes/spc700.a65
Normal file
61
snes/spc700.a65
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
; All SPC700 routines in SPC700 machine code
|
||||||
|
; SPC loader & transfer routines by Shay Green <gblargg@gmail.com>
|
||||||
|
|
||||||
|
loader ; .org $0002
|
||||||
|
.byt $F8,$21 ; mov x,@loader_data
|
||||||
|
.byt $BD ; mov sp,x
|
||||||
|
.byt $CD,$22 ; mov x,#@loader_data+1
|
||||||
|
|
||||||
|
; Push PC and PSW from SPC header
|
||||||
|
.byt $BF ; mov a,(x)+
|
||||||
|
.byt $2D ; push a
|
||||||
|
.byt $BF ; mov a,(x)+
|
||||||
|
.byt $2D ; push a
|
||||||
|
.byt $BF ; mov a,(x)+
|
||||||
|
.byt $2D ; push a
|
||||||
|
|
||||||
|
; Set FLG to $60 rather than value from SPC
|
||||||
|
.byt $E8,$60 ; mov a,#$60
|
||||||
|
.byt $D4,$6C ; mov FLG+x,a
|
||||||
|
|
||||||
|
; Restore DSP registers
|
||||||
|
.byt $8D,$00 ; mov y,#0
|
||||||
|
.byt $BF ; next: mov a,(x)+
|
||||||
|
.byt $CB,$F2 ; mov $F2,y
|
||||||
|
.byt $C4,$F3 ; mov $F3,a
|
||||||
|
.byt $FC ; inc y
|
||||||
|
.byt $10,-8 ; bpl next
|
||||||
|
|
||||||
|
.byt $8F,$6C,$F2 ; mov $F2,#FLG ; set for later
|
||||||
|
|
||||||
|
; Rerun loader
|
||||||
|
.byt $5F,$C0,$FF ; jmp $FFC0
|
||||||
|
|
||||||
|
;---------------------------------------
|
||||||
|
|
||||||
|
transfer ; .org $0002
|
||||||
|
|
||||||
|
.byt $CD,$FE ; mov x,#$FE ; transfer 254 pages
|
||||||
|
|
||||||
|
; Transfer four-byte chunks
|
||||||
|
.byt $8D,$3F ; page: mov y,#$3F
|
||||||
|
.byt $E4,$F4 ; quad: mov a,$F4
|
||||||
|
.byt $D6,$00,$02 ; mov0: mov !$0200+y,a
|
||||||
|
.byt $E4,$F5 ; mov a,$F5
|
||||||
|
.byt $D6,$40,$02 ; mov1: mov !$0240+y,a
|
||||||
|
.byt $E4,$F6 ; mov a,$F6
|
||||||
|
.byt $D6,$80,$02 ; mov2: mov !$0280+y,a
|
||||||
|
.byt $E4,$F7 ; mov a,$F7 ; tell S-CPU we're ready for more
|
||||||
|
.byt $CB,$F7 ; mov $F7,Y
|
||||||
|
.byt $D6,$C0,$02 ; mov3: mov !$02C0+y,a
|
||||||
|
.byt $DC ; dec y
|
||||||
|
.byt $10,-25 ; bpl quad
|
||||||
|
; Increment MSBs of addresses
|
||||||
|
.byt $AB,$0A ; inc mov0+2
|
||||||
|
.byt $AB,$0F ; inc mov1+2
|
||||||
|
.byt $AB,$14 ; inc mov2+2
|
||||||
|
.byt $AB,$1B ; inc mov3+2
|
||||||
|
.byt $1D ; dec x
|
||||||
|
.byt $D0,-38 ; bne page
|
||||||
|
; Rerun loader
|
||||||
|
.byt $5F,$C0,$FF ; jmp $FFC0
|
||||||
648
snes/spcplay.a65
Normal file
648
snes/spcplay.a65
Normal file
@ -0,0 +1,648 @@
|
|||||||
|
#include "memmap.i65"
|
||||||
|
|
||||||
|
; SPC Player
|
||||||
|
; SPC700 transfer and IO routines by Shay Green <gblargg@gmail.com>
|
||||||
|
|
||||||
|
spcplayer:
|
||||||
|
php
|
||||||
|
sep #$30 : .as : .xs
|
||||||
|
|
||||||
|
ldx #$0a ; Check if SPC header is present
|
||||||
|
-
|
||||||
|
lda @SPC_HEADER,x
|
||||||
|
cmp @text_spcid,x
|
||||||
|
beq +
|
||||||
|
jmp spc_exit
|
||||||
|
+
|
||||||
|
dey
|
||||||
|
bne -
|
||||||
|
|
||||||
|
rep #$10 : .xl ; Now draw lots of stuff
|
||||||
|
|
||||||
|
stz bar_wl
|
||||||
|
dec bar_wl
|
||||||
|
stz bar_xl
|
||||||
|
dec bar_xl
|
||||||
|
stz bar_yl
|
||||||
|
dec bar_yl
|
||||||
|
jsr backup_screen
|
||||||
|
|
||||||
|
lda #^text_spcplay ; Loading window
|
||||||
|
sta window_tbank
|
||||||
|
ldx #!text_spcplay
|
||||||
|
stx window_taddr
|
||||||
|
lda @spcplay_win_x
|
||||||
|
sta window_x
|
||||||
|
lda @spcplay_win_y
|
||||||
|
sta window_y
|
||||||
|
lda @spcplay_win_w
|
||||||
|
sta window_w
|
||||||
|
lda @spcplay_win_h
|
||||||
|
sta window_h
|
||||||
|
jsr draw_window
|
||||||
|
|
||||||
|
lda #^text_spcload ; Loading text
|
||||||
|
ldx #!text_spcload
|
||||||
|
sta print_bank
|
||||||
|
stx print_src
|
||||||
|
stz print_pal
|
||||||
|
lda #29
|
||||||
|
sta print_count
|
||||||
|
lda #17
|
||||||
|
sta print_y
|
||||||
|
lda #17
|
||||||
|
sta print_x
|
||||||
|
jsr hiprint
|
||||||
|
|
||||||
|
stz isr_done
|
||||||
|
-
|
||||||
|
lda isr_done ; Wait until text is being printed...
|
||||||
|
beq -
|
||||||
|
|
||||||
|
jsr spc700_load ; Load SPC into SPC700
|
||||||
|
|
||||||
|
lda #^text_spcplay
|
||||||
|
sta window_tbank
|
||||||
|
ldx #!text_spcplay
|
||||||
|
stx window_taddr
|
||||||
|
lda @spcstart_win_x
|
||||||
|
sta window_x
|
||||||
|
lda @spcstart_win_y
|
||||||
|
sta window_y
|
||||||
|
lda @spcstart_win_w
|
||||||
|
sta window_w
|
||||||
|
lda @spcstart_win_h
|
||||||
|
sta window_h
|
||||||
|
jsr draw_window
|
||||||
|
|
||||||
|
lda #^text_spcstarta
|
||||||
|
ldx #!text_spcstarta
|
||||||
|
sta print_bank
|
||||||
|
stx print_src
|
||||||
|
lda #$01
|
||||||
|
sta print_pal
|
||||||
|
lda #30
|
||||||
|
sta print_count
|
||||||
|
lda #15
|
||||||
|
sta print_y
|
||||||
|
lda #17
|
||||||
|
sta print_x
|
||||||
|
jsr hiprint
|
||||||
|
|
||||||
|
lda #^text_spcstartb
|
||||||
|
ldx #!text_spcstartb
|
||||||
|
sta print_bank
|
||||||
|
stx print_src
|
||||||
|
lda #$01
|
||||||
|
sta print_pal
|
||||||
|
lda #07
|
||||||
|
sta print_count
|
||||||
|
lda #17
|
||||||
|
sta print_y
|
||||||
|
lda #12
|
||||||
|
sta print_x
|
||||||
|
jsr hiprint
|
||||||
|
|
||||||
|
lda #$de
|
||||||
|
ldx #$004e
|
||||||
|
sta print_bank
|
||||||
|
stx print_src
|
||||||
|
stz print_pal
|
||||||
|
lda #32
|
||||||
|
sta print_count
|
||||||
|
lda #17
|
||||||
|
sta print_y
|
||||||
|
lda #20
|
||||||
|
sta print_x
|
||||||
|
jsr hiprint
|
||||||
|
|
||||||
|
lda #^text_spcstartc
|
||||||
|
ldx #!text_spcstartc
|
||||||
|
sta print_bank
|
||||||
|
stx print_src
|
||||||
|
lda #$01
|
||||||
|
sta print_pal
|
||||||
|
lda #07
|
||||||
|
sta print_count
|
||||||
|
lda #18
|
||||||
|
sta print_y
|
||||||
|
lda #12
|
||||||
|
sta print_x
|
||||||
|
jsr hiprint
|
||||||
|
|
||||||
|
lda #$de
|
||||||
|
ldx #$002e
|
||||||
|
sta print_bank
|
||||||
|
stx print_src
|
||||||
|
stz print_pal
|
||||||
|
lda #32
|
||||||
|
sta print_count
|
||||||
|
lda #18
|
||||||
|
sta print_y
|
||||||
|
lda #20
|
||||||
|
sta print_x
|
||||||
|
jsr hiprint
|
||||||
|
|
||||||
|
lda #^text_spcstartd
|
||||||
|
ldx #!text_spcstartd
|
||||||
|
sta print_bank
|
||||||
|
stx print_src
|
||||||
|
lda #$01
|
||||||
|
sta print_pal
|
||||||
|
lda #07
|
||||||
|
sta print_count
|
||||||
|
lda #19
|
||||||
|
sta print_y
|
||||||
|
lda #12
|
||||||
|
sta print_x
|
||||||
|
jsr hiprint
|
||||||
|
|
||||||
|
lda #$de
|
||||||
|
ldx #$00b1
|
||||||
|
sta print_bank
|
||||||
|
stx print_src
|
||||||
|
stz print_pal
|
||||||
|
lda #32
|
||||||
|
sta print_count
|
||||||
|
lda #19
|
||||||
|
sta print_y
|
||||||
|
lda #20
|
||||||
|
sta print_x
|
||||||
|
jsr hiprint
|
||||||
|
|
||||||
|
spc_playloop:
|
||||||
|
lda isr_done ; SPC player loop
|
||||||
|
lsr
|
||||||
|
bcc spc_playloop
|
||||||
|
jsr printtime
|
||||||
|
stz isr_done
|
||||||
|
|
||||||
|
jsr read_pad
|
||||||
|
lda #$80
|
||||||
|
and pad1trig+1
|
||||||
|
bne spc_key_b
|
||||||
|
bra spc_playloop
|
||||||
|
|
||||||
|
spc_key_b:
|
||||||
|
rep #$20 : .al
|
||||||
|
tsc
|
||||||
|
sta saved_sp ; Save SP for later re-entry
|
||||||
|
lda #$fa50 ; Write reset signature
|
||||||
|
sta @warm_signature
|
||||||
|
sep #$20 : .as
|
||||||
|
|
||||||
|
sei ; Blank screen & issue CMD_RESET command to Microcontroller...
|
||||||
|
stz $2100 ; ...this is required, because there is no other way to stop S-SMP & S-DSP
|
||||||
|
lda #CMD_RESET
|
||||||
|
sta @AVR_CMD
|
||||||
|
-
|
||||||
|
bra - ; At this point, the SNES waits for an external reset from the Microcontroller
|
||||||
|
|
||||||
|
spc_exit: ; Return from player in case of wrong SPC file data
|
||||||
|
plp
|
||||||
|
rts
|
||||||
|
|
||||||
|
;---------------------------------------
|
||||||
|
spc700_load:
|
||||||
|
php
|
||||||
|
sep #$20 : .as
|
||||||
|
rep #$10 : .xl
|
||||||
|
|
||||||
|
sei ; Disable NMI & IRQ
|
||||||
|
stz $4200 ; The SPC player code is really timing sensitive ;)
|
||||||
|
jsr upload_dsp_regs ; Upload S-DSP registers
|
||||||
|
jsr upload_high_ram ; Upload 63.5K of SPC700 ram
|
||||||
|
jsr upload_low_ram ; Upload rest of ram
|
||||||
|
jsr restore_final ; Restore SPC700 state & start execution
|
||||||
|
|
||||||
|
lda #$81 ; VBlank NMI + Auto Joypad Read
|
||||||
|
sta $4200 ; enable V-BLANK NMI
|
||||||
|
cli
|
||||||
|
plp
|
||||||
|
rts
|
||||||
|
;---------------------------------------
|
||||||
|
; Uploads DSP registers and some other setup code
|
||||||
|
upload_dsp_regs:
|
||||||
|
|
||||||
|
; ---- Begin upload
|
||||||
|
|
||||||
|
ldy #$0002
|
||||||
|
jsr spc_begin_upload
|
||||||
|
|
||||||
|
; ---- Upload loader
|
||||||
|
|
||||||
|
ldx #$0000
|
||||||
|
-
|
||||||
|
lda @loader,x
|
||||||
|
jsr spc_upload_byte
|
||||||
|
inx
|
||||||
|
cpy #31 ; size of loader
|
||||||
|
bne -
|
||||||
|
|
||||||
|
; ---- Upload SP, PC & PSW
|
||||||
|
|
||||||
|
lda @SPC_HEADER+43
|
||||||
|
jsr spc_upload_byte
|
||||||
|
lda @SPC_HEADER+38
|
||||||
|
jsr spc_upload_byte
|
||||||
|
lda @SPC_HEADER+37
|
||||||
|
jsr spc_upload_byte
|
||||||
|
lda @SPC_HEADER+42
|
||||||
|
jsr spc_upload_byte
|
||||||
|
|
||||||
|
; ---- Upload DSP registers
|
||||||
|
|
||||||
|
ldx #$0000
|
||||||
|
-
|
||||||
|
lda @SPC_DSP_REGS,x
|
||||||
|
jsr spc_upload_byte
|
||||||
|
inx
|
||||||
|
cpx #128
|
||||||
|
bne -
|
||||||
|
|
||||||
|
; --- Upload fixed values for $F1-$F3
|
||||||
|
|
||||||
|
ldy #$00F1
|
||||||
|
jsr spc_next_upload
|
||||||
|
|
||||||
|
lda #$80 ; stop timers
|
||||||
|
jsr spc_upload_byte
|
||||||
|
lda #$6c ; get dspaddr set for later
|
||||||
|
jsr spc_upload_byte
|
||||||
|
lda #$60
|
||||||
|
jsr spc_upload_byte
|
||||||
|
|
||||||
|
; ---- Upload $f8-$1ff
|
||||||
|
|
||||||
|
ldy #$00F8
|
||||||
|
jsr spc_next_upload
|
||||||
|
|
||||||
|
ldx #$00F8
|
||||||
|
-
|
||||||
|
lda @SPC_DATA,x
|
||||||
|
jsr spc_upload_byte
|
||||||
|
inx
|
||||||
|
cpx #$200
|
||||||
|
bne -
|
||||||
|
|
||||||
|
; ---- Execute loader
|
||||||
|
|
||||||
|
ldy #$0002
|
||||||
|
jsr spc_execute
|
||||||
|
rts
|
||||||
|
;---------------------------------------
|
||||||
|
upload_high_ram:
|
||||||
|
|
||||||
|
ldy #$0002
|
||||||
|
jsr spc_begin_upload
|
||||||
|
|
||||||
|
; ---- Upload transfer routine
|
||||||
|
|
||||||
|
ldx #$0000
|
||||||
|
-
|
||||||
|
lda @transfer,x
|
||||||
|
jsr spc_upload_byte
|
||||||
|
inx
|
||||||
|
cpy #43 ; size of transfer routine
|
||||||
|
bne -
|
||||||
|
|
||||||
|
ldx #$023f ; prepare transfer address
|
||||||
|
|
||||||
|
; ---- Execute transfer routine
|
||||||
|
|
||||||
|
ldy #$0002
|
||||||
|
sty APUIO2
|
||||||
|
stz APUIO1
|
||||||
|
lda APUIO0
|
||||||
|
inc
|
||||||
|
inc
|
||||||
|
sta APUIO0
|
||||||
|
; Wait for acknowledgement
|
||||||
|
-
|
||||||
|
cmp APUIO0
|
||||||
|
bne -
|
||||||
|
|
||||||
|
; ---- Burst transfer of 63.5K using custom routine
|
||||||
|
|
||||||
|
outer_transfer_loop:
|
||||||
|
ldy #$003f ; 3
|
||||||
|
inner_transfer_loop:
|
||||||
|
lda @SPC_DATA,x ; 5 |
|
||||||
|
sta APUIO0 ; 4 |
|
||||||
|
lda @SPC_DATA+$40,x ; 5 |
|
||||||
|
sta APUIO1 ; 4 |
|
||||||
|
lda @SPC_DATA+$80,x ; 5 |
|
||||||
|
sta APUIO2 ; 4 |
|
||||||
|
lda @SPC_DATA+$C0,x ; 5 |
|
||||||
|
sta APUIO3 ; 4 |
|
||||||
|
tya ; 2 >> 38 cycles
|
||||||
|
-
|
||||||
|
cmp APUIO3 ; 4 |
|
||||||
|
bne - ; 3 |
|
||||||
|
dex ; 2 |
|
||||||
|
dey ; 2 |
|
||||||
|
bpl inner_transfer_loop ; 3 >> 14 cycles
|
||||||
|
|
||||||
|
rep #$21 : .al ; 3 |
|
||||||
|
txa ; 2 |
|
||||||
|
adc #$140 ; 3 |
|
||||||
|
tax ; 2 |
|
||||||
|
sep #$20 : .as ; 3 |
|
||||||
|
cpx #$003f ; 3 |
|
||||||
|
bne outer_transfer_loop ; 3 >> 19 cycles
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
;---------------------------------------
|
||||||
|
upload_low_ram:
|
||||||
|
|
||||||
|
; ---- Upload $0002-$00EF
|
||||||
|
|
||||||
|
ldy #$0002
|
||||||
|
jsr spc_begin_upload
|
||||||
|
|
||||||
|
ldx #$0002
|
||||||
|
-
|
||||||
|
lda @SPC_DATA,x
|
||||||
|
jsr spc_upload_byte
|
||||||
|
inx
|
||||||
|
cpx #$00F0
|
||||||
|
bne -
|
||||||
|
rts
|
||||||
|
;---------------------------------------
|
||||||
|
; Executes final restoration code
|
||||||
|
restore_final:
|
||||||
|
jsr start_exec_io
|
||||||
|
stz $420d ; SPC700 I/O code requires SLOW timing
|
||||||
|
|
||||||
|
; ---- Restore first two bytes of RAM
|
||||||
|
|
||||||
|
lda @SPC_DATA
|
||||||
|
xba
|
||||||
|
lda #$e8 ; MOV A,#@SPC_DATA
|
||||||
|
tax
|
||||||
|
jsr exec_instr
|
||||||
|
ldx #$00C4 ; MOV $00,A
|
||||||
|
jsr exec_instr
|
||||||
|
|
||||||
|
lda @SPC_DATA+1
|
||||||
|
xba
|
||||||
|
lda #$e8 ; MOV A,#@SPC_DATA+1
|
||||||
|
tax
|
||||||
|
jsr exec_instr
|
||||||
|
ldx #$01C4 ; MOV $01,A
|
||||||
|
jsr exec_instr
|
||||||
|
|
||||||
|
; ---- Restore SP
|
||||||
|
|
||||||
|
lda @SPC_HEADER+43
|
||||||
|
sec
|
||||||
|
sbc #3
|
||||||
|
xba
|
||||||
|
lda #$cd ; MOV X,#@SPC_HEADER+43
|
||||||
|
tax
|
||||||
|
jsr exec_instr
|
||||||
|
ldx #$bd ; MOV SP,X
|
||||||
|
jsr exec_instr
|
||||||
|
|
||||||
|
; ---- Restore X
|
||||||
|
|
||||||
|
lda @SPC_HEADER+40
|
||||||
|
xba
|
||||||
|
lda #$cd ; MOV X,#@SPC_HEADER+40
|
||||||
|
tax
|
||||||
|
jsr exec_instr
|
||||||
|
|
||||||
|
; ---- Restore Y
|
||||||
|
|
||||||
|
lda @SPC_HEADER+41
|
||||||
|
xba
|
||||||
|
lda #$8d ; MOV Y,#@SPC_HEADER+41
|
||||||
|
tax
|
||||||
|
jsr exec_instr
|
||||||
|
|
||||||
|
; ---- Restore DSP FLG register
|
||||||
|
|
||||||
|
lda @SPC_DSP_REGS+$6c
|
||||||
|
xba
|
||||||
|
lda #$e8 ; MOV A,#@SPC_DSP_REGS+$6c
|
||||||
|
tax
|
||||||
|
jsr exec_instr
|
||||||
|
ldx #$f3C4 ; MOV $f3,A -> $f2 has been set-up before by SPC700 loader
|
||||||
|
jsr exec_instr
|
||||||
|
|
||||||
|
; ---- Restore DSP KON register
|
||||||
|
|
||||||
|
lda #$4C
|
||||||
|
xba
|
||||||
|
lda #$e8 ; MOV A,#$4c
|
||||||
|
tax
|
||||||
|
jsr exec_instr
|
||||||
|
ldx #$f2C4 ; MOV $f2,A
|
||||||
|
jsr exec_instr
|
||||||
|
lda @SPC_DSP_REGS+$4C
|
||||||
|
xba
|
||||||
|
lda #$e8 ; MOV A,#@SPC_DSP_REGS+$4c
|
||||||
|
tax
|
||||||
|
jsr exec_instr
|
||||||
|
ldx #$f3C4 ; MOV $f3,A
|
||||||
|
jsr exec_instr
|
||||||
|
|
||||||
|
; ---- Restore DSP register address
|
||||||
|
|
||||||
|
lda @SPC_DATA+$F2
|
||||||
|
xba
|
||||||
|
lda #$e8 ; MOV A,#@SPC_DATA+$F2
|
||||||
|
tax
|
||||||
|
jsr exec_instr
|
||||||
|
ldx #$f2C4 ; MOV dest,A
|
||||||
|
jsr exec_instr
|
||||||
|
|
||||||
|
; ---- Restore CONTROL register
|
||||||
|
|
||||||
|
lda @SPC_DATA+$F1
|
||||||
|
and #$CF ; don't clear input ports
|
||||||
|
xba
|
||||||
|
lda #$e8 ; MOV A,#@SPC_DATA+$F1
|
||||||
|
tax
|
||||||
|
jsr exec_instr
|
||||||
|
ldx #$f1C4 ; MOV $F1,A
|
||||||
|
jsr exec_instr
|
||||||
|
|
||||||
|
;---- Restore A
|
||||||
|
|
||||||
|
lda @SPC_HEADER+39
|
||||||
|
xba
|
||||||
|
lda #$e8 ; MOV A,#@SPC_HEADER+39
|
||||||
|
tax
|
||||||
|
jsr exec_instr
|
||||||
|
|
||||||
|
;---- Restore PSW and PC
|
||||||
|
|
||||||
|
ldx #$7F00 ; NOP; RTI
|
||||||
|
stx APUIO0
|
||||||
|
lda #$FC ; Patch loop to execute instruction just written
|
||||||
|
sta APUIO3
|
||||||
|
|
||||||
|
;---- restore IO ports $f4 - $f7
|
||||||
|
|
||||||
|
rep #$20 : .al
|
||||||
|
lda @SPC_DATA+$F4
|
||||||
|
tax
|
||||||
|
lda @SPC_DATA+$F6
|
||||||
|
sta APUIO2
|
||||||
|
stx APUIO0 ; last to avoid overwriting RETI before run
|
||||||
|
sep #$20 : .as
|
||||||
|
|
||||||
|
lda #$01
|
||||||
|
sta $420d ; restore FAST CPU operation
|
||||||
|
rts
|
||||||
|
;---------------------------------------
|
||||||
|
spc_begin_upload:
|
||||||
|
|
||||||
|
sty APUIO2 ; Set address
|
||||||
|
|
||||||
|
ldy #$BBAA ; Wait for SPC
|
||||||
|
-
|
||||||
|
cpy APUIO0
|
||||||
|
bne -
|
||||||
|
|
||||||
|
lda #$CC ; Send acknowledgement
|
||||||
|
sta APUIO1
|
||||||
|
sta APUIO0
|
||||||
|
|
||||||
|
- ; Wait for acknowledgement
|
||||||
|
cmp APUIO0
|
||||||
|
bne -
|
||||||
|
|
||||||
|
ldy #0 ; Initialize index
|
||||||
|
rts
|
||||||
|
;---------------------------------------
|
||||||
|
spc_upload_byte:
|
||||||
|
sta APUIO1
|
||||||
|
|
||||||
|
tya ; Signal it's ready
|
||||||
|
sta APUIO0
|
||||||
|
- ; Wait for acknowledgement
|
||||||
|
cmp APUIO0
|
||||||
|
bne -
|
||||||
|
|
||||||
|
iny
|
||||||
|
|
||||||
|
rts
|
||||||
|
;---------------------------------------
|
||||||
|
spc_next_upload:
|
||||||
|
sty APUIO2
|
||||||
|
|
||||||
|
; Send command
|
||||||
|
; Special case operation has been fully tested.
|
||||||
|
lda APUIO0
|
||||||
|
inc
|
||||||
|
inc
|
||||||
|
bne +
|
||||||
|
inc
|
||||||
|
+
|
||||||
|
sta APUIO1
|
||||||
|
sta APUIO0
|
||||||
|
|
||||||
|
; Wait for acknowledgement
|
||||||
|
-
|
||||||
|
cmp APUIO0
|
||||||
|
bne -
|
||||||
|
|
||||||
|
ldy #0
|
||||||
|
rts
|
||||||
|
;---------------------------------------
|
||||||
|
spc_execute:
|
||||||
|
sty APUIO2
|
||||||
|
|
||||||
|
stz APUIO1
|
||||||
|
|
||||||
|
lda APUIO0
|
||||||
|
inc
|
||||||
|
inc
|
||||||
|
sta APUIO0
|
||||||
|
|
||||||
|
; Wait for acknowledgement
|
||||||
|
-
|
||||||
|
cmp APUIO0
|
||||||
|
bne -
|
||||||
|
|
||||||
|
rts
|
||||||
|
;---------------------------------------
|
||||||
|
start_exec_io:
|
||||||
|
; Set execution address
|
||||||
|
ldx #$00F5
|
||||||
|
stx APUIO2
|
||||||
|
|
||||||
|
stz APUIO1 ; NOP
|
||||||
|
ldx #$FE2F ; BRA *-2
|
||||||
|
|
||||||
|
; Signal to SPC that we're ready
|
||||||
|
lda APUIO0
|
||||||
|
inc
|
||||||
|
inc
|
||||||
|
sta APUIO0
|
||||||
|
|
||||||
|
; Wait for acknowledgement
|
||||||
|
-
|
||||||
|
cmp APUIO0
|
||||||
|
bne -
|
||||||
|
|
||||||
|
; Quickly write branch
|
||||||
|
stx APUIO2
|
||||||
|
|
||||||
|
rts
|
||||||
|
;---------------------------------------
|
||||||
|
exec_instr:
|
||||||
|
; Replace instruction
|
||||||
|
stx APUIO0
|
||||||
|
lda #$FC
|
||||||
|
sta APUIO3 ; 30
|
||||||
|
|
||||||
|
; SPC BRA loop takes 4 cycles, so it reads
|
||||||
|
; the branch offset every 4 SPC cycles (84 master).
|
||||||
|
; We must handle the case where it read just before
|
||||||
|
; the write above, and when it reads just after it.
|
||||||
|
; If it reads just after, we have at least 7 SPC
|
||||||
|
; cycles (147 master) to change restore the branch
|
||||||
|
; offset.
|
||||||
|
|
||||||
|
; 48 minimum, 90 maximum
|
||||||
|
ora #0
|
||||||
|
ora #0
|
||||||
|
ora #0
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
|
||||||
|
; 66 delay, about the middle of the above limits
|
||||||
|
phd ;4
|
||||||
|
pld ;5
|
||||||
|
|
||||||
|
; Give plenty of extra time if single execution
|
||||||
|
; isn't needed, as this avoids such tight timing
|
||||||
|
; requirements.
|
||||||
|
|
||||||
|
; phd ;4
|
||||||
|
; pld ;5
|
||||||
|
; phd ;4
|
||||||
|
; pld ;5
|
||||||
|
|
||||||
|
; Patch loop to skip first two bytes
|
||||||
|
lda #$FE ; 16
|
||||||
|
sta APUIO3 ; 30
|
||||||
|
|
||||||
|
; 38 minimum (assuming 66 delay above)
|
||||||
|
phd ; 4
|
||||||
|
pld ; 5
|
||||||
|
|
||||||
|
; Give plenty of extra time if single execution
|
||||||
|
; isn't needed, as this avoids such tight timing
|
||||||
|
; requirements.
|
||||||
|
|
||||||
|
phd
|
||||||
|
pld
|
||||||
|
phd
|
||||||
|
pld
|
||||||
|
rts
|
||||||
Loading…
x
Reference in New Issue
Block a user