Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*.log
*.smc
*.sfc
*.st
*~
*.old
*.elf
Expand Down
2 changes: 2 additions & 0 deletions snes/const.a65
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ mdesc_filesel_context_add_to_favorites .byt "Add the selected file to favorites"

text_filesel_context_set_as_autoboot .byt "Set as autoboot", 0
mdesc_filesel_context_set_as_autoboot .byt "Boot this ROM automatically on next power-on (hold START to cancel)", 0
text_filesel_context_set_as_slotb .byt "Set as Slot B", 0
mdesc_filesel_context_set_as_slotb .byt "Load this .ST ROM as the Sufami Turbo Slot B companion cart", 0

text_filesel_favorites_context_remove_from_favorites .byt "Remove from favorites", 0
mdesc_filesel_favorites_context_remove_from_favorites .byt "Remove the selected file from favorites", 0
Expand Down
59 changes: 58 additions & 1 deletion snes/filesel.a65
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,8 @@ select_item:
lda [dirptr_addr], y
cmp #TYPE_ROM
beq sel_is_file
cmp #TYPE_ROM_ST
beq sel_is_file
cmp #TYPE_SPC
beq sel_is_spc
cmp #TYPE_SUBDIR
Expand Down Expand Up @@ -800,6 +802,8 @@ open_context_menu:
lda [dirptr_addr], y
cmp #TYPE_ROM
beq ctx_is_file
cmp #TYPE_ROM_ST
beq ctx_is_file_st
cmp #TYPE_SPC
beq ctx_is_spc
cmp #TYPE_SUBDIR
Expand Down Expand Up @@ -828,6 +832,26 @@ ctx_is_file
sta @MCU_PARAM+3
jsr filesel_contextmenu_file
bra open_context_menu_cont
ctx_is_file_st
; save selected ST file path to MCU_PARAM (same as ctx_is_file)
dey
rep #$20 : .al
lda [dirptr_addr], y
and #$00ff
sta @MCU_PARAM+6
dey
dey
lda [dirptr_addr], y
sta @MCU_PARAM+4
lda #!FILESEL_CWD
sta @MCU_PARAM
sep #$20 : .as
lda #^FILESEL_CWD
sta @MCU_PARAM+2
lda #$00
sta @MCU_PARAM+3
jsr filesel_contextmenu_st_file
bra open_context_menu_cont
ctx_is_parent
bra open_context_menu_cont
ctx_is_dir
Expand Down Expand Up @@ -1157,6 +1181,37 @@ set_selected_as_autoboot_rom:
plp
rtl

set_selected_as_slotb_rom:
; have MCU store the selected .ST file as the Slot B companion cart
; the file path should already have been saved to MCU_PARAM before calling
; this routine (done by open_context_menu / ctx_is_file_st)
php
phb
sep #$20 : .as
lda #$01
jsr hide_cursor
jsr draw_loading_window
jsr waitblank
lda #$00
sta @SNES_CMD
lda #CMD_SET_SLOTB_ROM
sta @MCU_CMD
; wait for ACK/NACK
- lda @SNES_CMD
cmp #$55
; success
beq +
cmp #$aa
; failure
beq +
bra -
+ lda #$55
sta @MCU_CMD
jsr pop_window
plb
plp
rtl

set_favorite_as_autoboot_rom:
; have MCU save the selected favorite game as the autoboot ROM
; the list index of the favorite should already have been saved to MCU_PARAM
Expand Down Expand Up @@ -1287,8 +1342,10 @@ filesel_request_filelist:
sta @MCU_PARAM+10
lda #TYPE_SPC
sta @MCU_PARAM+11
lda #$00
lda #TYPE_ROM_ST
sta @MCU_PARAM+12
lda #$00
sta @MCU_PARAM+13
sta @SNES_CMD
lda #CMD_READDIR
sta @MCU_CMD
Expand Down
4 changes: 3 additions & 1 deletion snes/memmap.i65
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
#define CMD_SET_AUTOBOOT_FAV $16 /* set autoboot from favorites (index in MCU_PARAM) */
#define CMD_CLR_AUTOBOOT_ROM $17 /* clear autoboot ROM setting */
#define CMD_LOAD_AUTOBOOT $18 /* trigger autoboot at cold boot */
#define CMD_SET_SLOTB_ROM $19 /* set Slot B companion cart for Sufami Turbo (non-persistent) */
#define CMD_SAVESTATE $40
#define CMD_LOADSTATE $41
#define CMD_MCU_RDY $55
Expand Down Expand Up @@ -174,10 +175,11 @@
#define TYPE_ROM $01
#define TYPE_SRM $02
#define TYPE_SPC $03
#define TYPE_ROM_ST $07
#define TYPE_IPS $04
#define TYPE_CHT $05
#define TYPE_SKIN $06
#define TYPE_SUBDIR $40
#define TYPE_PARENT $80

#define DIM_BRIGHTNESS $03
#define DIM_BRIGHTNESS $03
27 changes: 27 additions & 0 deletions snes/menu.a65
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,33 @@ filesel_contextmenu_file:
jsr pop_window
rts

filesel_contextmenu_st_file:
sep #$20 : .as
rep #$10 : .xl
lda #$02
sta window_x
lda #$09
sta window_y
lda #60
sta window_w
lda #18
sta window_h
jsr push_window
jsr window_greyout
lda #$06
sta window_x
lda #$0b
sta window_y
phb
lda #^menu_enttab_filesel_context_st_file
pha
plb
ldx #!menu_enttab_filesel_context_st_file
jsr show_menu
plb
jsr pop_window
rts

filesel_favorites_contextmenu:
sep #$20 : .as
rep #$10 : .xl
Expand Down
47 changes: 47 additions & 0 deletions snes/menudata.a65
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,53 @@ menu_enttab_filesel_context_file:

.byt 0

menu_enttab_filesel_context_st_file:
; HEADER
.byt 1 ; listsel_step=1
.word !text_filesel_selected_file ; window title
.byt ^text_filesel_selected_file ; for this menu
; ENTRIES
.byt MTYPE_FUNC_CLOSE
.word !text_filesel_context_add_to_favorites
.byt ^text_filesel_context_add_to_favorites
.word !add_selected_file_to_favorites-1
.byt ^add_selected_file_to_favorites-1
.byt 0
.byt 0,0,0
.word !mdesc_filesel_context_add_to_favorites
.byt ^mdesc_filesel_context_add_to_favorites
.byt 0,0,0
.byt 0,0,0
.byt 0,0,0

.byt MTYPE_FUNC_CLOSE
.word !text_filesel_context_set_as_autoboot
.byt ^text_filesel_context_set_as_autoboot
.word !set_selected_as_autoboot_rom-1
.byt ^set_selected_as_autoboot_rom-1
.byt 0
.byt 0,0,0
.word !mdesc_filesel_context_set_as_autoboot
.byt ^mdesc_filesel_context_set_as_autoboot
.byt 0,0,0
.byt 0,0,0
.byt 0,0,0

.byt MTYPE_FUNC_CLOSE
.word !text_filesel_context_set_as_slotb
.byt ^text_filesel_context_set_as_slotb
.word !set_selected_as_slotb_rom-1
.byt ^set_selected_as_slotb_rom-1
.byt 0
.byt 0,0,0
.word !mdesc_filesel_context_set_as_slotb
.byt ^mdesc_filesel_context_set_as_slotb
.byt 0,0,0
.byt 0,0,0
.byt 0,0,0

.byt 0

menu_enttab_filesel_favorites_context:
; HEADER
.byt 1 ; listsel_step=1
Expand Down
6 changes: 5 additions & 1 deletion src/filetypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ printf("start\n");
if(is_requested_filetype(type, filetypes)) {
switch(type) {
case TYPE_ROM:
case TYPE_ROM_ST:
case TYPE_SPC:
case TYPE_SUBDIR:
case TYPE_PARENT:
Expand Down Expand Up @@ -154,6 +155,9 @@ SNES_FTYPE determine_filetype(FILINFO fno) {
) {
return TYPE_ROM;
}
if(!strcasecmp(ext+1, "ST")) {
return TYPE_ROM_ST;
}
/* if( (!strcasecmp(ext+1, "IPS"))
||(!strcasecmp(ext+1, "UPS"))
) {
Expand Down Expand Up @@ -209,4 +213,4 @@ void make_filesize_string(char *buf, uint32_t size) {

int is_requested_filetype(SNES_FTYPE type, const SNES_FTYPE *filetypes) {
return strchr((const char*)filetypes, (int)type) != NULL;
}
}
1 change: 1 addition & 0 deletions src/filetypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ typedef enum {
TYPE_IPS = 4,
TYPE_CHT = 5,
TYPE_SKIN = 6,
TYPE_ROM_ST = 7,
TYPE_SUBDIR = 64,
TYPE_PARENT = 128
} SNES_FTYPE;
Expand Down
9 changes: 9 additions & 0 deletions src/fpga_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,15 @@ void set_rom_mask(uint32_t mask) {
FPGA_DESELECT();
}

void set_rom_mask_b(uint32_t mask) {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SETROMMASK_B);
FPGA_TX_BYTE((mask >> 16) & 0xff);
FPGA_TX_BYTE((mask >> 8) & 0xff);
FPGA_TX_BYTE((mask) & 0xff);
FPGA_DESELECT();
}

void set_mapper(uint8_t val) {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SETMAPPER(val));
Expand Down
2 changes: 2 additions & 0 deletions src/fpga_spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
/* commands */
#define FPGA_CMD_SETADDR (0x00)
#define FPGA_CMD_SETROMMASK (0x10)
#define FPGA_CMD_SETROMMASK_B (0x50)
#define FPGA_CMD_SETRAMMASK (0x20)
#define FPGA_CMD_SETRAMBASE (0x20 | 1)
#define FPGA_CMD_SETMAPPER(x) (0x30 | (x & 15))
Expand Down Expand Up @@ -124,6 +125,7 @@ void set_msu_status(uint16_t status);
void set_saveram_base(uint8_t);
void set_saveram_mask(uint32_t);
void set_rom_mask(uint32_t);
void set_rom_mask_b(uint32_t);
void set_mapper(uint8_t val);
void fpga_sddma(uint8_t tgt, uint8_t partial);
void fpga_set_sddma_range(uint16_t start, uint16_t end);
Expand Down
8 changes: 8 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,14 @@ int main(void) {
status_load_to_menu();
cmd=0; /* stay in menu loop */
break;
case SNES_CMD_SET_SLOTB_ROM:
get_selected_name(file_lfn);
printf("Set Slot B ROM: %s\n", file_lfn);
strncpy(slotb_filename, (char*)file_lfn, 257);
slotb_filename[257] = 0;
status_load_to_menu();
cmd=0; /* stay in menu loop, non-persistent */
break;
case SNES_CMD_SET_AUTOBOOT_FAV:
cfg_get_favorite_game(file_lfn, snes_get_mcu_param() & 0xff);
printf("Set autoboot from favorite: %s\n", file_lfn);
Expand Down
53 changes: 53 additions & 0 deletions src/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ uint16_t sram_writeblock(void* buf, uint32_t addr, uint16_t size) {
}

char current_filename[258];
char slotb_filename[258];
uint32_t slotb_ramsize_bytes = 0; /* Slot B SRAM size in bytes; 0 when no Slot B or no SRAM */
uint32_t load_rom(uint8_t* filename, uint32_t base_addr, uint8_t flags) {
UINT bytes_read;
DWORD filesize;
Expand Down Expand Up @@ -364,6 +366,46 @@ uint32_t load_rom(uint8_t* filename, uint32_t base_addr, uint8_t flags) {
set_fpga_time(get_bcdtime());
}
}
uint32_t slotb_rammask = 0;
if(romprops.mapper_id==5) {
printf("Sufami Turbo ROM\n");
printf("Loading ST BIOS %s...\n", STBIOS_FW);
load_sram_offload((uint8_t*)STBIOS_FW, 0x000000, LOADRAM_AUTOSKIP_HEADER);
if(file_res) snes_menu_errmsg(MENU_ERR_SUPPLFILE, (void*)STBIOS_FW);
if(slotb_filename[0]) {
uint8_t slotb_buf[258];
strncpy((char*)slotb_buf, slotb_filename, sizeof(slotb_buf)-1);
slotb_buf[sizeof(slotb_buf)-1] = 0;
printf("Loading Slot B ROM %s...\n", slotb_buf);
uint32_t slotb_filesize = load_sram_offload(slotb_buf, 0x600000, LOADRAM_AUTOSKIP_HEADER);
if(file_res) {
printf("Slot B ROM load failed, disabling\n");
sram_memset(0x600000, 0x100, 0x00);
set_rom_mask_b(0);
} else {
/* Compute Slot B ROM mask: next power of 2 >= filesize */
uint32_t slotb_sz = 1;
while(slotb_sz < slotb_filesize) slotb_sz <<= 1;
set_rom_mask_b(slotb_sz - 1);
/* Read Slot B SRAM size from ST header byte 0x37 (2KB units) */
uint32_t slotb_ramsize = (uint32_t)sram_readbyte(0x600037) * 2048;
slotb_rammask = slotb_ramsize ? (slotb_ramsize - 1) : 0;
slotb_ramsize_bytes = slotb_ramsize;
/* Initialize Slot B SRAM region (0xE80000) and load from .srm file */
if(slotb_ramsize) {
sram_memset(0xE80000, slotb_ramsize, 0xFF);
strncpy((char*)slotb_buf, slotb_filename, sizeof(slotb_buf)-1);
slotb_buf[sizeof(slotb_buf)-1] = 0;
migrate_and_load_srm(slotb_buf, 0xE80000);
if(file_res == FR_NO_FILE) file_res = 0;
}
}
} else {
/* No Slot B: zero header area so STBIOS cannot match "BANDAI SFC-ADX" signature */
sram_memset(0x600000, 0x40, 0x00);
set_rom_mask_b(0);
}
}
if(romprops.has_dspx) {
printf("DSPx game. Loading firmware image %s...\n", romprops.dsp_fw);
load_dspx(romprops.dsp_fw, romprops.fpga_features);
Expand All @@ -390,6 +432,17 @@ uint32_t load_rom(uint8_t* filename, uint32_t base_addr, uint8_t flags) {
romprops.srambase = 0;
romprops.sramsize_bytes = romprops.ramsize_bytes;
rammask = 1;
} else if(romprops.mapper_id == 5) {
/* Sufami Turbo Slot A: SRAM size from ST header byte 0x37, not standard header.
When Slot B is present, bit 19 of SAVERAM_MASK separates Slot A (0xE00000)
from Slot B SRAM (0xE80000). Use larger of the two masks for the window size. */
/* ST hardware always has a physical 8KB SRAM used by STBIOS as runtime RAM.
Games with no declared save SRAM (byte 0x37 == 0) still need the SRAM
accessible so the STBIOS can dispatch into it (e.g. $E0:$78F9). */
uint32_t slota_ramsize = (romprops.ramsize_bytes > 0x2000) ? romprops.ramsize_bytes : 0x2000;
uint32_t slota_rammask = slota_ramsize - 1;
rammask = (slota_rammask > slotb_rammask) ? slota_rammask : slotb_rammask;
if(slotb_rammask) rammask |= 0x80000;
} else if(romprops.header.ramsize == 0) {
rammask = 0;
} else {
Expand Down
2 changes: 2 additions & 0 deletions src/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#include "smc.h"

extern char current_filename[];
extern char slotb_filename[];
extern uint32_t slotb_ramsize_bytes;

#define MENU_ADDR_BRAM_SRC (0xFF00)

Expand Down
Loading