Firmware: ST0010 support + peripheral enable switches

This commit is contained in:
ikari 2011-06-20 14:22:52 +02:00
parent 7fc6952fab
commit 1183718234
13 changed files with 125 additions and 40 deletions

View File

@ -58,8 +58,8 @@ static char *curchar;
/* Word lists */
static char command_words[] =
"cd\0reset\0sreset\0dir\0ls\0test\0resume\0loadrom\0loadraw\0saveraw\0put\0d4\0vmode\0mapper\0settime\0time\0";
enum { CMD_CD = 0, CMD_RESET, CMD_SRESET, CMD_DIR, CMD_LS, CMD_TEST, CMD_RESUME, CMD_LOADROM, CMD_LOADRAW, CMD_SAVERAW, CMD_PUT, CMD_D4, CMD_VMODE, CMD_MAPPER, CMD_SETTIME, CMD_TIME };
"cd\0reset\0sreset\0dir\0ls\0test\0resume\0loadrom\0loadraw\0saveraw\0put\0d4\0vmode\0mapper\0settime\0time\0setfeature\0";
enum { CMD_CD = 0, CMD_RESET, CMD_SRESET, CMD_DIR, CMD_LS, CMD_TEST, CMD_RESUME, CMD_LOADROM, CMD_LOADRAW, CMD_SAVERAW, CMD_PUT, CMD_D4, CMD_VMODE, CMD_MAPPER, CMD_SETTIME, CMD_TIME, CMD_SETFEATURE };
/* ------------------------------------------------------------------------- */
/* Parse functions */
@ -386,6 +386,11 @@ void cmd_time(void) {
time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec);
}
void cmd_setfeature(void) {
uint8_t feat = parse_unsigned(0, 255);
fpga_set_features(feat);
}
/* ------------------------------------------------------------------------- */
/* CLI interface functions */
/* ------------------------------------------------------------------------- */
@ -507,7 +512,10 @@ void cli_loop(void) {
case CMD_TEST:
testbattery();
break;
case CMD_SETFEATURE:
cmd_setfeature();
break;
}
}
}

View File

@ -1,3 +1,3 @@
CONFIG_VERSION=0.0.1
CONFIG_FWVER=16777215
CONFIG_FWVER=16777214
CONFIG_MCU_FOSC=12000000

View File

@ -66,6 +66,10 @@ void file_close() {
file_res = f_close(&file_handle);
}
void file_seek(uint32_t offset) {
file_res = f_lseek(&file_handle, (DWORD)offset);
}
UINT file_read() {
UINT bytes_read;
file_res = f_read(&file_handle, file_buf, sizeof(file_buf), &bytes_read);

View File

@ -43,6 +43,7 @@ void file_init(void);
void file_open(uint8_t* filename, BYTE flags);
void file_open_by_filinfo(FILINFO* fno);
void file_close(void);
void file_seek(uint32_t offset);
UINT file_read(void);
UINT file_write(void);
UINT file_readblock(void* buf, uint32_t addr, uint16_t size);

View File

@ -79,6 +79,7 @@
EA hhllxxxx write+incr. DSP data ROM (xxxx=dummy writes)
EB - put DSP into reset
EC - release DSP from reset
ED - set feature enable bits (see below)
F0 - receive test token (to see if FPGA is alive)
F1 - receive status (16bit, MSB first), see below
@ -110,6 +111,17 @@
1 MSU1 Audio control status: 0=pause, 1=play
0 MSU1 Audio control request
FPGA feature enable bits:
bit function
==========================================================================
7 -
6 -
5 -
4 -
3 enable MSU1 registers
2 enable SRTC registers
1 enable ST0010 mapping
0 enable DSPx mapping
*/
@ -386,3 +398,12 @@ void fpga_dspx_reset(uint8_t reset) {
FPGA_TX_BYTE(0x00);
FPGA_DESELECT();
}
void fpga_set_features(uint8_t feat) {
printf("set features: %02x\n", feat);
FPGA_SELECT();
FPGA_TX_BYTE(0xed);
FPGA_TX_BYTE(feat);
FPGA_DESELECT();
}

View File

@ -48,6 +48,12 @@
#define FPGA_SPI_FAST() spi_set_speed(SPI_SPEED_FPGA_FAST)
#define FPGA_SPI_SLOW() spi_set_speed(SPI_SPEED_FPGA_SLOW)
#define FEAT_MSU1 (1 << 3)
#define FEAT_SRTC (1 << 2)
#define FEAT_ST0010 (1 << 1)
#define FEAT_DSPX (1 << 0)
void fpga_spi_init(void);
uint8_t fpga_test(void);
uint16_t fpga_status(void);
@ -79,4 +85,5 @@ void fpga_reset_dspx_addr(void);
void fpga_write_dspx_pgm(uint32_t data);
void fpga_write_dspx_dat(uint16_t data);
void fpga_dspx_reset(uint8_t reset);
void fpga_set_features(uint8_t feat);
#endif

View File

@ -78,7 +78,7 @@ led_pwm();
printf("PCONP=%lx\n", LPC_SC->PCONP);
file_init();
cic_init(0);
cic_init(1);
/* setup timer (fpga clk) */
LPC_TIM3->CTCR=0;
LPC_TIM3->EMR=EMC0TOGGLE;
@ -237,7 +237,6 @@ sram_hexdump(SRAM_DIR_ADDR, 0x300);
while(!cmd) {
cmd=menu_main_loop();
printf("cmd: %d\n", cmd);
sleep_ms(500);
uart_putc('-');
switch(cmd) {
case SNES_CMD_LOADROM:
@ -262,8 +261,7 @@ sram_hexdump(SRAM_DIR_ADDR, 0x300);
}
printf("cmd was %x, going to snes main loop\n", cmd);
/* always try MSU1 for now */
if(msu1_entrycheck_and_loop()) {
if(romprops.has_msu1 && msu1_loop()) {
prepare_reset();
continue;
}

View File

@ -42,6 +42,7 @@
#include "rle.h"
#include "diskio.h"
#include "snesboot.h"
#include "msu1.h"
#include <string.h>
char* hex = "0123456789ABCDEF";
@ -181,7 +182,6 @@ uint32_t load_rom(uint8_t* filename, uint32_t base_addr, uint8_t flags) {
filesize = file_handle.fsize;
smc_id(&romprops);
set_mcu_addr(base_addr);
printf("no nervous breakdown beyond this point! or else!\n");
f_lseek(&file_handle, romprops.offset);
for(;;) {
ff_sd_offload=1;
@ -218,9 +218,13 @@ uint32_t load_rom(uint8_t* filename, uint32_t base_addr, uint8_t flags) {
}
if(romprops.has_dspx) {
printf("DSPx game. Loading firmware image %s...\n", romprops.necdsp_fw);
load_dspx(romprops.necdsp_fw);
if(file_res && romprops.necdsp_fw == DSPFW_1) {
load_dspx(DSPFW_1B);
if(romprops.has_st0010) {
load_dspx(romprops.necdsp_fw, 1);
} else {
load_dspx(romprops.necdsp_fw, 0);
if(file_res && romprops.necdsp_fw == DSPFW_1) {
load_dspx(DSPFW_1B, 0);
}
}
if(file_res) {
snes_menu_errmsg(MENU_ERR_NODSP, (void*)romprops.necdsp_fw);
@ -253,6 +257,17 @@ uint32_t load_rom(uint8_t* filename, uint32_t base_addr, uint8_t flags) {
}
}
printf("check MSU...");
if(msu1_check(filename)) {
romprops.fpga_features |= FEAT_MSU1;
romprops.has_msu1 = 1;
}
printf("done\n");
romprops.fpga_features |= FEAT_SRTC;
fpga_set_features(romprops.fpga_features);
if(flags & LOADROM_WITH_RESET) {
set_mcu_ovr(0);
fpga_dspx_reset(1);
@ -465,7 +480,7 @@ uint64_t sram_gettime(uint32_t base_addr) {
return result & 0x00ffffffffffffffLL;
}
void load_dspx(const uint8_t *filename) {
void load_dspx(const uint8_t *filename, uint8_t st0010) {
UINT bytes_read;
DWORD filesize;
uint16_t word_cnt;
@ -473,9 +488,16 @@ void load_dspx(const uint8_t *filename) {
uint16_t sector_remaining = 0;
uint16_t sector_cnt = 0;
uint16_t pgmsize = 2048;
uint16_t datsize = 1024;
uint16_t datsize;
uint32_t pgmdata = 0;
uint16_t datdata = 0;
if(st0010) {
datsize = 1536;
} else {
datsize = 1024;
}
file_open((uint8_t*)filename, FA_READ);
filesize = file_handle.fsize;
if(file_res) {
@ -503,6 +525,10 @@ void load_dspx(const uint8_t *filename) {
}
wordsize_cnt = 0;
if(st0010) {
file_seek(0xc000);
sector_remaining = 0;
}
for(word_cnt = 0; word_cnt < datsize;) {
if(!sector_remaining) {

View File

@ -52,7 +52,7 @@ uint32_t load_sram(uint8_t* filename, uint32_t base_addr);
uint32_t load_sram_offload(uint8_t* filename, uint32_t base_addr);
uint32_t load_sram_rle(uint8_t* filename, uint32_t base_addr);
uint32_t load_bootrle(uint32_t base_addr);
void load_dspx(const uint8_t* filename);
void load_dspx(const uint8_t* filename, uint8_t st0010);
void sram_hexdump(uint32_t addr, uint32_t len);
uint8_t sram_readbyte(uint32_t addr);
uint16_t sram_readshort(uint32_t addr);

View File

@ -10,6 +10,10 @@
#include "msu1.h"
#include "snes.h"
#include "timer.h"
#include "smc.h"
FIL msufile;
extern snes_romprops_t romprops;
int msu1_check_reset(void) {
static tick_t rising_ticks;
@ -27,17 +31,21 @@ int msu1_check_reset(void) {
return 0;
}
int msu1_entrycheck_and_loop() {
/* MSU1 STUFF, GET ME OUTTA HERE */
FIL durr;
// open MSU file
strcpy((char*)file_buf, (char*)file_lfn);
int msu1_check(uint8_t* filename) {
/* open MSU file */
strcpy((char*)file_buf, (char*)filename);
strcpy(strrchr((char*)file_buf, (int)'.'), ".msu");
printf("MSU datafile: %s\n", file_buf);
if(f_open(&durr, (const TCHAR*)file_buf, FA_READ) != FR_OK) {
if(f_open(&msufile, (const TCHAR*)file_buf, FA_READ) != FR_OK) {
printf("MSU datafile not found\n");
return 0;
}
romprops.fpga_features |= FEAT_MSU1;
return 1;
}
int msu1_loop() {
/* it is assumed that the MSU file is already opened by calling msu1_check(). */
UINT bytes_read = 1024;
UINT bytes_read2 = 1;
FRESULT res;
@ -61,10 +69,10 @@ int msu1_entrycheck_and_loop() {
msu_reset(0x0);
ff_sd_offload=1;
sd_offload_tgt=2;
f_lseek(&durr, 0L);
f_lseek(&msufile, 0L);
ff_sd_offload=1;
sd_offload_tgt=2;
f_read(&durr, file_buf, 16384, &bytes_read2);
f_read(&msufile, file_buf, 16384, &bytes_read2);
set_dac_addr(dac_addr);
dac_pause();
@ -90,7 +98,7 @@ int msu1_entrycheck_and_loop() {
set_msu_addr(msu_addr);
sd_offload_tgt=2;
ff_sd_offload=1;
res = f_read(&durr, file_buf, 8192, &bytes_read2);
res = f_read(&msufile, file_buf, 8192, &bytes_read2);
DBG_MSU1 printf("data buffer refilled. res=%d page1=%08lx page2=%08lx\n", res, msu_page1_start, msu_page2_start);
}
@ -153,12 +161,12 @@ int msu1_entrycheck_and_loop() {
set_msu_addr(0x0);
sd_offload_tgt=2;
ff_sd_offload=1;
res = f_lseek(&durr, msu_offset);
res = f_lseek(&msufile, msu_offset);
DBG_MSU1 printf("seek to %08lx, res = %d\n", msu_offset, res);
sd_offload_tgt=2;
ff_sd_offload=1;
res = f_read(&durr, file_buf, 16384, &bytes_read2);
res = f_read(&msufile, file_buf, 16384, &bytes_read2);
DBG_MSU1 printf("read res = %d\n", res);
DBG_MSU1 printf("read %d bytes\n", bytes_read2);
msu_reset(0x0);
@ -172,7 +180,7 @@ int msu1_entrycheck_and_loop() {
set_msu_addr(0x2000);
sd_offload_tgt=2;
ff_sd_offload=1;
f_read(&durr, file_buf, 8192, &bytes_read2);
f_read(&msufile, file_buf, 8192, &bytes_read2);
DBG_MSU1 printf("next page dirty (was: %08lx), loaded page2 (start now: ", msu_page2_start);
msu_page2_start = msu_page1_start + msu_page_size;
DBG_MSU1 printf("%08lx)\n", msu_page2_start);
@ -184,7 +192,7 @@ int msu1_entrycheck_and_loop() {
set_msu_addr(0x0);
sd_offload_tgt=2;
ff_sd_offload=1;
f_read(&durr, file_buf, 8192, &bytes_read2);
f_read(&msufile, file_buf, 8192, &bytes_read2);
DBG_MSU1 printf("next page dirty (was: %08lx), loaded page1 (start now: ", msu_page1_start);
msu_page1_start = msu_page2_start + msu_page_size;
DBG_MSU1 printf("%08lx)\n", msu_page1_start);
@ -240,7 +248,7 @@ int msu1_entrycheck_and_loop() {
bytes_read = MSU_DAC_BUFSIZE;
}
if(msu1_check_reset()) {
f_close(&durr);
f_close(&msufile);
f_close(&file_handle);
spi_set_speed(SSP_CLK_DIVISOR_FPGA_SLOW);
return 1;

View File

@ -9,6 +9,7 @@
#define MSU_DAC_BUFSIZE (2048)
int msu1_entrycheck_and_loop(void);
int msu1_check(uint8_t*);
int msu1_loop(void);
#endif

View File

@ -29,6 +29,7 @@
#include "uart.h"
#include "smc.h"
#include "string.h"
#include "fpga_spi.h"
snes_romprops_t romprops;
@ -81,6 +82,8 @@ void smc_id(snes_romprops_t* props) {
snes_header_t* header = &(props->header);
props->has_dspx = 0;
props->has_st0010 = 0;
props->fpga_features = 0;
for(uint8_t num = 0; num < 6; num++) {
if(!file_readblock(header, hdr_addr[num], sizeof(snes_header_t))
|| file_res) {
@ -138,20 +141,20 @@ void smc_id(snes_romprops_t* props) {
switch(header->map & 0xef) {
case 0x21: /* HiROM */
props->mapper_id = 0;
if(header->map == 0x31 && (header->carttype == 0x03 || header->carttype == 0x05)) {
props->has_dspx = 1;
props->mapper_id = 4; /* DSPx HiROM */
props->necdsp_fw = DSPFW_1B;
} else {
props->mapper_id = 0; /* regular HiROM */
props->fpga_features |= FEAT_DSPX;
}
break;
case 0x20: /* LoROM */
props->mapper_id = 1;
if ((header->map == 0x20 && header->carttype == 0x03) ||
(header->map == 0x30 && header->carttype == 0x05 && header->licensee != 0xb2)) {
props->mapper_id = 5;
props->has_dspx = 1;
props->fpga_features |= FEAT_DSPX;
// Pilotwings uses DSP1 instead of DSP1B
if(!memcmp(header->name, "PILOTWINGS", 10)) {
props->necdsp_fw = DSPFW_1;
@ -160,18 +163,22 @@ void smc_id(snes_romprops_t* props) {
}
} else if (header->map == 0x20 && header->carttype == 0x05) {
props->has_dspx = 1;
props->mapper_id = 5; /* DSPx LoROM */
props->necdsp_fw = DSPFW_2;
props->fpga_features |= FEAT_DSPX;
} else if (header->map == 0x30 && header->carttype == 0x05 && header->licensee == 0xb2) {
props->has_dspx = 1;
props->mapper_id = 5; /* DSPx LoROM */
props->necdsp_fw = DSPFW_3;
props->fpga_features |= FEAT_DSPX;
} else if (header->map == 0x30 && header->carttype == 0x03) {
props->has_dspx = 1;
props->mapper_id = 5; /* DSPx LoROM */
props->necdsp_fw = DSPFW_4;
} else {
props->mapper_id = 1; /* regular LoROM */
props->fpga_features |= FEAT_DSPX;
} else if (header->map == 0x30 && header->carttype == 0xf6 && header->romsize >= 0xa) {
props->has_dspx = 1;
props->has_st0010 = 1;
props->necdsp_fw = DSPFW_ST0010;
props->fpga_features |= FEAT_ST0010;
header->ramsize = 2;
}
break;

View File

@ -31,7 +31,8 @@
#define DSPFW_2 ((const uint8_t*)"/sd2snes/dsp2.bin")
#define DSPFW_3 ((const uint8_t*)"/sd2snes/dsp3.bin")
#define DSPFW_4 ((const uint8_t*)"/sd2snes/dsp4.bin")
#define DSPFW_1B ((const uint8_t*)"/sd2snes/dsp1b.bin")
#define DSPFW_1B ((const uint8_t*)"/sd2snes/dsp1b.bin")
#define DSPFW_ST0010 ((const uint8_t*)"/sd2snes/st0010.bin")
typedef struct _snes_header {
uint8_t maker[2]; /* 0xB0 */
@ -61,6 +62,9 @@ typedef struct _snes_romprops {
uint32_t romsize_bytes; /* ROM size in bytes (rounded up) */
const uint8_t* necdsp_fw; /* NEC DSP ROM filename */
uint8_t has_dspx; /* DSP[1-4] presence flag */
uint8_t has_st0010; /* st0010 presence flag (additional to dspx)*/
uint8_t has_msu1; /* MSU1 presence flag */
uint8_t fpga_features; /* feature/peripheral enable bits*/
snes_header_t header; /* original header from ROM image */
} snes_romprops_t;