Skip to content

Commit

Permalink
- Fixed window overlay to be per-pixel rather than per-tile. Addresse…
Browse files Browse the repository at this point in the history
…s window graphics problems with CAW bosses and likely many other games.

- Fixed several dynamic range and popping/clicking APU bugs.
- Changed in-game hooks to be fpga-only.  Hook is no longer run on SNES NMI or IRQ.
- Added save states (Save=X+R, Load=X+L) for development.  To enable, modify sd2snes/config.yml sgb_* settings after booting new firmware.  In-game hooks and buttons must be enabled for them to work.  One state is recorded in the SRM file.  Does not work with MSU audio on SD2SNES classic.
- Changed SD2SNES classic to only load MSU bit file for enabled ROMs to make development easier.  The MSU bit file may lag in development.
  • Loading branch information
github-user-name committed Jun 27, 2020
1 parent 71e7ec5 commit 7c79521
Show file tree
Hide file tree
Showing 91 changed files with 16,608 additions and 10 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ MK3MENU := m3nu.bin
FPGAPATH := verilog
MK2EXT := bit
MK3EXT := bi3
MK2CORES := base cx4 gsu obc1 sdd1 sa1
MK3CORES := base cx4 gsu obc1 sdd1 sa1
MK2CORES := base cx4 gsu obc1 sdd1 sa1 sgb
MK3CORES := base cx4 gsu obc1 sdd1 sa1 sgb

MK2FPGA := $(foreach C,$(MK2CORES),$(FPGAPATH)/sd2snes_$C/fpga_$C.$(MK2EXT))
MK3FPGA := $(foreach C,$(MK3CORES),$(FPGAPATH)/sd2snes_$C/fpga_$C.$(MK3EXT))
Expand Down
2 changes: 1 addition & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ SRC = main.c ff.c ccsbcs.c clock.c uart.c power.c led.c timer.c
SRC += printf.c spi.c fileops.c rtc.c fpga.c fpga_spi.c snes.c smc.c
SRC += memory.c filetypes.c faulthandler.c sort.c crc32.c cic.c
SRC += cli.c xmodem.c irq.c rle.c sdnative.c msu1.c crc16.c sysinfo.c
SRC += cfg.c cheat.c yaml.c
SRC += cfg.c cheat.c yaml.c sgb.c

#SRC += usbdesc.c usbcore.c usbuser.c usbhw.c cdcuser.c

Expand Down
12 changes: 11 additions & 1 deletion src/cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ cfg_t CFG_DEFAULT = {
.reset_to_menu = 0,
.led_brightness = 15,
.enable_cheats = 1,
.reset_patch = 0
.reset_patch = 0,
.sgb_enable_state = 0,
.sgb_bios_override = 0
};

cfg_t CFG;
Expand Down Expand Up @@ -75,6 +77,8 @@ int cfg_save() {
f_printf(&file_handle, "%s: %s\n", CFG_ENABLE_INGAME_BUTTONS, CFG.enable_ingame_buttons ? "true" : "false");
f_printf(&file_handle, "%s: %s\n", CFG_ENABLE_HOOK_HOLDOFF, CFG.enable_hook_holdoff ? "true" : "false");
f_printf(&file_handle, "%s: %s\n", CFG_RESET_PATCH, CFG.reset_patch ? "true" : "false");
f_printf(&file_handle, "%s: %s\n", CFG_SGB_ENABLE_STATE, CFG.sgb_enable_state ? "true" : "false");
f_printf(&file_handle, "%s: %s\n", CFG_SGB_BIOS_OVERRIDE, CFG.sgb_bios_override ? "true" : "false");
f_puts("\n# Screensaver settings\n", &file_handle);
f_printf(&file_handle, "# %s: Enable screensaver\n", CFG_ENABLE_SCREENSAVER);
// f_printf(&file_handle, "# %s: Dim screen after n seconds\n", CFG_SCREENSAVER_TIMEOUT);
Expand Down Expand Up @@ -176,6 +180,12 @@ int cfg_load() {
if(yaml_get_itemvalue(CFG_RESET_PATCH, &tok)) {
CFG.reset_patch = tok.boolvalue ? 1 : 0;
}
if(yaml_get_itemvalue(CFG_SGB_ENABLE_STATE, &tok)) {
CFG.sgb_enable_state = tok.boolvalue ? 1 : 0;
}
if(yaml_get_itemvalue(CFG_SGB_BIOS_OVERRIDE, &tok)) {
CFG.sgb_bios_override = tok.boolvalue ? 1 : 0;
}
}
yaml_file_close();
return err;
Expand Down
4 changes: 4 additions & 0 deletions src/cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#define CFG_LED_BRIGHTNESS ("LEDBrightness")
#define CFG_ENABLE_CHEATS ("EnableCheats")
#define CFG_RESET_PATCH ("ResetPatch")
#define CFG_SGB_ENABLE_STATE ("SGBEnableState")
#define CFG_SGB_BIOS_OVERRIDE ("SGBBiosOverride")

typedef enum {
VIDMODE_60 = 0,
Expand Down Expand Up @@ -63,6 +65,8 @@ typedef struct __attribute__ ((__packed__)) _cfg_block {
uint8_t led_brightness; /* LED brightness (0..15) */
uint8_t enable_cheats; /* initial cheat enable state */
uint8_t reset_patch; /* enable reset patch */
uint8_t sgb_enable_state; /* enable SGB save states if present */
uint8_t sgb_bios_override; /* override the bios checks when enabling features */
} cfg_t;

int cfg_save(void);
Expand Down
4 changes: 4 additions & 0 deletions src/cheat.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
#include "cheat.h"
#include "yaml.h"
#include "cfg.h"
#include "sgb.h"

#include <string.h>
#include <stdlib.h>

extern cfg_t CFG;
extern sgb_romprops_t sgb_romprops;
extern snes_romprops_t romprops;

uint8_t rom_index;
Expand Down Expand Up @@ -63,6 +65,8 @@ void cheat_program() {
cheat_holdoff_enable(CFG.enable_hook_holdoff);
cheat_buttons_enable(CFG.enable_ingame_buttons);
cheat_wram_present(wram_index);

sgb_cheat_program();
}

void cheat_program_single(cheat_patch_record_t *cheat) {
Expand Down
5 changes: 3 additions & 2 deletions src/config-mk2
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
CONFIG_VERSION = "1.10.3"
CONFIG_FWVER = 0x010A0300
CONFIG_VERSION = "1.10.3_sgb01"
CONFIG_FWVER = 0x53474201
#CONFIG_FWVER = 0x010A0300
CONFIG_MCU_FOSC = 12000000

CONFIG_MK2 = y
Expand Down
5 changes: 3 additions & 2 deletions src/config-mk3
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
CONFIG_VERSION = "1.10.3"
CONFIG_FWVER = 0x010A0300
CONFIG_VERSION = "1.10.3_sgb01"
CONFIG_FWVER = 0x53474201
#CONFIG_FWVER = 0x010A0300
CONFIG_MCU_FOSC = 8000000

CONFIG_MK2 = n
Expand Down
2 changes: 2 additions & 0 deletions src/filetypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ SNES_FTYPE determine_filetype(FILINFO fno) {
||(!strcasecmp(ext+1, "FIG"))
||(!strcasecmp(ext+1, "SWC"))
||(!strcasecmp(ext+1, "BS"))
||(!strcasecmp(ext+1, "GB"))
||(!strcasecmp(ext+1, "GBC"))
) {
return TYPE_ROM;
}
Expand Down
1 change: 1 addition & 0 deletions src/fpga.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const uint8_t *fpga_config;
#define FPGA_GSU ((const uint8_t*)"/sd2snes/fpga_gsu." FPGA_CONF_EXT)
#define FPGA_SA1 ((const uint8_t*)"/sd2snes/fpga_sa1." FPGA_CONF_EXT)
#define FPGA_SDD1 ((const uint8_t*)"/sd2snes/fpga_sdd1." FPGA_CONF_EXT)
#define FPGA_SGB ((const uint8_t*)"/sd2snes/fpga_sgb." FPGA_CONF_EXT)
#define FPGA_BASE ((const uint8_t*)"/sd2snes/fpga_base." FPGA_CONF_EXT)
#define FPGA_ROM ((const uint8_t*)"rom")

Expand Down
14 changes: 14 additions & 0 deletions src/fpga_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,20 @@ void set_bsx_regs(uint8_t set, uint8_t reset) {
FPGA_DESELECT();
}

uint64_t get_fpga_time() {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_RTCGET);
uint64_t result = ((uint64_t)FPGA_RX_BYTE()) << 48;
result |= ((uint64_t)FPGA_RX_BYTE()) << 40;
result |= ((uint64_t)FPGA_RX_BYTE()) << 32;
result |= ((uint64_t)FPGA_RX_BYTE()) << 24;
result |= ((uint64_t)FPGA_RX_BYTE()) << 16;
result |= ((uint64_t)FPGA_RX_BYTE()) << 8;
result |= ((uint64_t)FPGA_RX_BYTE());
FPGA_DESELECT();
return result;
}

void set_fpga_time(uint64_t time) {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_RTCSET);
Expand Down
4 changes: 3 additions & 1 deletion src/fpga_spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
#define FPGA_CMD_DACSETPTR (0xe3)
#define FPGA_CMD_MSUSETPTR (0xe4)
#define FPGA_CMD_RTCSET (0xe5)
#define FPGA_CMD_RTCGET (0xe6)
#define FPGA_CMD_BSXSETBITS (0xe6)
#define FPGA_CMD_SRTCRESET (0xe7)
#define FPGA_CMD_DSPRESETPTR (0xe8)
Expand Down Expand Up @@ -122,8 +123,9 @@ void fpga_set_sddma_range(uint16_t start, uint16_t end);
uint16_t get_msu_track(void);
uint32_t get_msu_offset(void);
uint32_t get_snes_sysclk(void);
void set_bsx_regs(uint8_t set, uint8_t reset);
void set_fpga_time(uint64_t time);
uint64_t get_fpga_time(void);
void set_bsx_regs(uint8_t set, uint8_t reset);
void fpga_reset_srtc_state(void);
void fpga_reset_dspx_addr(void);
void fpga_write_dspx_pgm(uint32_t data);
Expand Down
38 changes: 37 additions & 1 deletion src/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,13 @@ memory.c: RAM operations
#include "cli.h"
#include "cheat.h"
#include "rtc.h"
#include "sgb.h"

#include <string.h>
char* hex = "0123456789ABCDEF";

extern snes_romprops_t romprops;
extern sgb_romprops_t sgb_romprops;
extern uint32_t saveram_crc_old;
extern uint8_t sram_crc_valid;
extern uint32_t sram_crc_romsize;
Expand Down Expand Up @@ -239,10 +241,19 @@ uint32_t load_rom(uint8_t* filename, uint32_t base_addr, uint8_t flags) {
uart_putc(0x30+file_res);
return 0;
}
/* SGB detect and file management */
uint8_t *sgb_filename = filename;
DWORD sgb_filesize = file_handle.fsize;
sgb_id(&sgb_romprops, sgb_filename);
if (!sgb_update_file(&filename)) return 0;

filesize = file_handle.fsize;
smc_id(&romprops);
file_close();

/* SGB assign the SGB FPGA file and relocate the snes image to the 512KB RAM */
if (!sgb_update_romprops(&romprops, sgb_filename)) return 0;

uint16_t fpga_features_preload = romprops.fpga_features | FEAT_CMD_UNLOCK | FEAT_2100_LIMIT_NONE;
if(filename == (uint8_t*)MENU_FILENAME) {
fpga_set_features(fpga_features_preload);
Expand Down Expand Up @@ -336,6 +347,31 @@ uint32_t load_rom(uint8_t* filename, uint32_t base_addr, uint8_t flags) {
rammask = romprops.ramsize_bytes - 1;
}
rommask = romprops.romsize_bytes - 1;

/* SGB send the GB file and boot ROM. Also update the SaveRAM properties */
if (sgb_romprops.has_sgb) {
/* reset the filename to match the GB file */
filename = sgb_filename;
filesize = sgb_filesize;

/* update SaveRAM */
romprops.ramsize_bytes = (CFG.sgb_enable_state && sgb_romprops.ramsize_bytes <= 64 * 1024) ? (128 * 1024) : sgb_romprops.ramsize_bytes;
romprops.srambase = sgb_romprops.srambase;
romprops.sramsize_bytes = (CFG.sgb_enable_state && sgb_romprops.ramsize_bytes <= 64 * 1024) ? (128 * 1024) : sgb_romprops.sramsize_bytes;

rammask = sgb_romprops.ramsize_bytes ? (sgb_romprops.ramsize_bytes - 1) : 0;
rommask = sgb_romprops.romsize_bytes ? (sgb_romprops.romsize_bytes - 1) : 0;

/* load images */
printf("attempting to load SGB boot ROM %s...\n", SGBFW);
load_sram_offload((uint8_t *)SGBFW, 0x800000, 0);
printf("attempting to load GB ROM %s...\n", sgb_filename);
load_sram_offload(sgb_filename, 0x0, 0);

/* load GB RTC */
sgb_gtc_load(sgb_filename);
}

printf("ramsize=%x rammask=%lx\nromsize=%x rommask=%lx\n", romprops.header.ramsize, rammask, romprops.header.romsize, rommask);
set_saveram_mask(rammask);
set_rom_mask(rommask);
Expand Down Expand Up @@ -399,7 +435,7 @@ uint32_t load_rom(uint8_t* filename, uint32_t base_addr, uint8_t flags) {
while(snes_get_mcu_cmd() != SNES_CMD_RESET) cli_entrycheck();
}

set_mapper(romprops.mapper_id);
set_mapper(sgb_romprops.has_sgb ? sgb_romprops.mapper_id : romprops.mapper_id);

//printf("%04lx\n", romprops.header_address + ((void*)&romprops.header.vect_irq16 - (void*)&romprops.header));
if(flags & (LOADROM_WITH_RESET|LOADROM_WAIT_SNES)) {
Expand Down
32 changes: 32 additions & 0 deletions src/rtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,35 @@ void testbattery() {
delay_ms(20);
LPC_RTC->CCR = BV(CLKEN);
}

void time2gtime(struct gtm *gtime, struct tm *time) {
gtime->gtm_sec = time->tm_sec;
gtime->gtm_min = time->tm_min;
gtime->gtm_hour = time->tm_hour;

/* compute a day count from some fixed date */
/* see http://howardhinnant.github.io/date_algorithms.html */
int32_t year = time->tm_year;
uint32_t mon = time->tm_mon;
uint32_t day = time->tm_mday; // already starts at 1
if (mon <= 2) year--;
int32_t era = (year >= 0 ? year : year - 399) / 400;
uint32_t yoe = (uint32_t)(year - era * 400);
uint32_t doy = (153 * (mon + (mon > 2 ? -3 : 9)) + 2) / 5 + day - 1;
uint32_t doe = yoe * 365 + yoe / 4 - yoe / 100 + doy;

// force a positive value by making start of era -1 (-0400/03/01 y/m/d) a value of 0
gtime->gtm_days = (uint32_t)((era + 1) * 146097 + (int32_t)doe);
}

uint8_t get_deltagtime(struct gtm *time1, struct gtm *time2) {
uint8_t borrow = 0;

time1->gtm_sec -= borrow; borrow = (time1->gtm_sec < time2->gtm_sec ) ? 1 : 0; time1->gtm_sec = time1->gtm_sec + (borrow ? 60 : 0) - time2->gtm_sec;
time1->gtm_min -= borrow; borrow = (time1->gtm_min < time2->gtm_min ) ? 1 : 0; time1->gtm_min = time1->gtm_min + (borrow ? 60 : 0) - time2->gtm_min;
time1->gtm_hour -= borrow; borrow = (time1->gtm_hour < time2->gtm_hour) ? 1 : 0; time1->gtm_hour = time1->gtm_hour + (borrow ? 24 : 0) - time2->gtm_hour;
time1->gtm_days -= borrow; borrow = (time1->gtm_days < time2->gtm_days) ? 1 : 0; time1->gtm_days = time1->gtm_days + 0 - time2->gtm_days;

// borrowing a day signifies underflow and the delta is not valid
return borrow;
}
15 changes: 15 additions & 0 deletions src/rtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ struct tm {
// A Unix struct tm has a few more fields we don't need in this application
};

/* for use with GB RTC */
struct __attribute__ ((__packed__)) gtm {
uint8_t gtm_sec; // 0..59
uint8_t gtm_min; // 0..59
uint8_t gtm_hour; // 0..23
uint8_t gtm_pad;
uint32_t gtm_days; // 0..N
};

#define RTC_MAGIC (0x43545253L)

extern rtcstate_t rtc_state;
Expand Down Expand Up @@ -80,4 +89,10 @@ void testbattery(void);
void bcdtime2srtctime(uint64_t bcdtime, uint8_t *srtctime);
uint64_t srtctime2bcdtime(uint8_t *srtctime);

/* convert time to gtime */
void time2gtime(struct gtm *gtime, struct tm *time);

/* get delta time: time1-time2. returns 1 if invalid (underflow) */
uint8_t get_deltagtime(struct gtm *delta, struct gtm *time);

#endif

0 comments on commit 7c79521

Please sign in to comment.