memory access bugfix (broke resetting after MSU1 usage)
This commit is contained in:
@@ -55,7 +55,7 @@ TARGET = $(OBJDIR)/sd2snes
|
||||
|
||||
|
||||
# List C source files here. (C dependencies are automatically generated.)
|
||||
SRC = main.c ff.c ccsbcs.c clock.c uart.c power.c led.c timer.c printf.c spi.c fileops.c rtc.c fpga.c fpga_spi.c snes.c smc.c memory.c filetypes.c faulthandler.c sort.c crc32.c cic.c cli.c xmodem.c irq.c rle.c sdnative.c
|
||||
SRC = main.c ff.c ccsbcs.c clock.c uart.c power.c led.c timer.c printf.c spi.c fileops.c rtc.c fpga.c fpga_spi.c snes.c smc.c memory.c filetypes.c faulthandler.c sort.c crc32.c cic.c cli.c xmodem.c irq.c rle.c sdnative.c msu1.c
|
||||
|
||||
|
||||
# List Assembler source files here.
|
||||
|
||||
17
src/cli.c
17
src/cli.c
@@ -57,8 +57,8 @@ static char *curchar;
|
||||
|
||||
/* Word lists */
|
||||
static char command_words[] =
|
||||
"cd\0reset\0dir\0ls\0test\0resume\0loadrom\0loadraw\0put\0d4\0vmode\0mapper\0";
|
||||
enum { CMD_CD = 0, CMD_RESET, CMD_DIR, CMD_LS, CMD_TEST, CMD_RESUME, CMD_LOADROM, CMD_LOADRAW, CMD_PUT, CMD_D4, CMD_VMODE, CMD_MAPPER };
|
||||
"cd\0reset\0dir\0ls\0test\0resume\0loadrom\0loadraw\0saveraw\0put\0d4\0vmode\0mapper\0";
|
||||
enum { CMD_CD = 0, CMD_RESET, CMD_DIR, CMD_LS, CMD_TEST, CMD_RESUME, CMD_LOADROM, CMD_LOADRAW, CMD_SAVERAW, CMD_PUT, CMD_D4, CMD_VMODE, CMD_MAPPER };
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Parse functions */
|
||||
@@ -151,7 +151,7 @@ static int8_t parse_wordlist(char *wordlist) {
|
||||
cur++;
|
||||
c = *ptr;
|
||||
} while (c != 0);
|
||||
|
||||
|
||||
if (matched) {
|
||||
char *tmp = curchar;
|
||||
|
||||
@@ -296,6 +296,13 @@ static void cmd_loadrom(void) {
|
||||
snes_reset(0);
|
||||
}
|
||||
|
||||
static void cmd_saveraw(void) {
|
||||
uint32_t address = parse_unsigned(0,16777216);
|
||||
uint32_t length = parse_unsigned(0,16777216);
|
||||
set_mcu_ovr(0);
|
||||
save_sram((uint8_t*)curchar, length, address);
|
||||
}
|
||||
|
||||
static void cmd_d4(void) {
|
||||
int32_t hz;
|
||||
|
||||
@@ -451,6 +458,10 @@ void cli_loop(void) {
|
||||
cmd_loadrom();
|
||||
break;
|
||||
|
||||
case CMD_SAVERAW:
|
||||
cmd_saveraw();
|
||||
break;
|
||||
|
||||
case CMD_D4:
|
||||
cmd_d4();
|
||||
break;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
// #define DEBUG_SD
|
||||
// #define DEBUG_IRQ
|
||||
#define DEBUG_MSU1
|
||||
|
||||
#define VER "0.0.1(NSFW)"
|
||||
#define IN_AHBRAM __attribute__ ((section(".ahbram")))
|
||||
@@ -28,7 +29,7 @@
|
||||
#define SD_SUPPLY_VOLTAGE (1L<<21) /* 3.3V - 3.4V */
|
||||
#define CONFIG_SD_BLOCKTRANSFER 1
|
||||
#define CONFIG_SD_AUTO_RETRIES 10
|
||||
// #define SD_CHANGE_VECT
|
||||
// #define SD_CHANGE_VECT
|
||||
// #define CONFIG_SD_DATACRC 1
|
||||
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
SPI commands
|
||||
|
||||
cmd param function
|
||||
cmd param function
|
||||
=============================================
|
||||
0t bbhhll set address to 0xbbhhll
|
||||
t = target
|
||||
@@ -50,12 +50,15 @@
|
||||
60 sssseeee set SD DMA partial transfer start+end
|
||||
ssss = start offset (msb first)
|
||||
eeee = end offset (msb first)
|
||||
|
||||
80 - read with increment (RAM only)
|
||||
81 - read w/o increment (RAM only)
|
||||
|
||||
90 {xx}* write xx with increment (RAM only)
|
||||
91 {xx}* write xx w/o increment (RAM only)
|
||||
8p - read (RAM only)
|
||||
p: 0 = no increment after read
|
||||
1 = increment after read
|
||||
|
||||
9p {xx}* write xx
|
||||
p: tt-i
|
||||
tt = target (see above)
|
||||
i = increment (see above)
|
||||
|
||||
E0 ssrr set MSU-1 status register (=FPGA status byte 2)
|
||||
ss = bits to set in status register (1=set)
|
||||
@@ -64,17 +67,17 @@
|
||||
E1 - pause DAC
|
||||
E2 - resume/play DAC
|
||||
E3 - reset DAC playback pointer (0)
|
||||
E4 - reset MSU read pointer (0)
|
||||
E4 hhll set MSU read pointer
|
||||
|
||||
F0 - receive test token (to see if FPGA is alive)
|
||||
F1 - receive status
|
||||
F1 - receive status (2 bytes)
|
||||
|
||||
F2 - get MSU data address (32bit, MSB first)
|
||||
F3 - get MSU audio track no. (16bit, MSB first)
|
||||
F4 - get MSU volume (8bit)
|
||||
|
||||
FE - get SNES master clock frequency (32bit, MSB first)
|
||||
FF {xx]* echo (returns the sent data in the next byte)
|
||||
FF {xx}* echo (returns the sent data in the next byte)
|
||||
*/
|
||||
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
|
||||
610
src/main.c
610
src/main.c
@@ -24,6 +24,7 @@
|
||||
#include "sdnative.h"
|
||||
#include "crc.h"
|
||||
#include "smc.h"
|
||||
#include "msu1.h"
|
||||
|
||||
#define EMC0TOGGLE (3<<4)
|
||||
#define MR0R (1<<1)
|
||||
@@ -68,7 +69,6 @@ int main(void) {
|
||||
LPC_PINCON->PINSEL0 |= BV(20) | BV(21); /* MAT3.0 (FPGA clock) */
|
||||
led_pwm();
|
||||
sdn_init();
|
||||
fpga_spi_init();
|
||||
printf("\n\nsd2snes mk.2\n============\nfw ver.: " VER "\ncpu clock: %d Hz\n", CONFIG_CPU_FREQUENCY);
|
||||
file_init();
|
||||
cic_init(0);
|
||||
@@ -81,415 +81,219 @@ led_pwm();
|
||||
LPC_TIM3->TCR=1;
|
||||
fpga_init();
|
||||
fpga_rompgm();
|
||||
restart:
|
||||
if(disk_state == DISK_CHANGED) {
|
||||
sdn_init();
|
||||
newcard = 1;
|
||||
}
|
||||
load_bootrle(SRAM_MENU_ADDR);
|
||||
set_saveram_mask(0x1fff);
|
||||
set_rom_mask(0x3fffff);
|
||||
set_mapper(0x7);
|
||||
set_mcu_ovr(0);
|
||||
snes_reset(0);
|
||||
delay_ms(15); /* allow CIC to settle */
|
||||
|
||||
while(get_cic_state() == CIC_FAIL) {
|
||||
rdyled(0);
|
||||
readled(0);
|
||||
writeled(0);
|
||||
delay_ms(500);
|
||||
rdyled(1);
|
||||
readled(1);
|
||||
writeled(1);
|
||||
delay_ms(500);
|
||||
}
|
||||
/* some sanity checks */
|
||||
uint8_t card_go = 0;
|
||||
while(!card_go) {
|
||||
if(disk_status(0) & (STA_NOINIT|STA_NODISK)) {
|
||||
snes_bootprint(" No Card! \0");
|
||||
while(disk_status(0) & (STA_NOINIT|STA_NODISK));
|
||||
delay_ms(200);
|
||||
while(1) {
|
||||
set_mcu_ovr(1);
|
||||
if(disk_state == DISK_CHANGED) {
|
||||
sdn_init();
|
||||
newcard = 1;
|
||||
}
|
||||
file_open((uint8_t*)"/sd2snes/menu.bin", FA_READ);
|
||||
if(file_status != FILE_OK) {
|
||||
snes_bootprint(" /sd2snes/menu.bin not found! \0");
|
||||
while(disk_status(0) == RES_OK);
|
||||
} else {
|
||||
card_go = 1;
|
||||
}
|
||||
file_close();
|
||||
}
|
||||
snes_bootprint(" Loading ... \0");
|
||||
if(get_cic_state() == CIC_PAIR) {
|
||||
printf("PAIR MODE ENGAGED!\n");
|
||||
cic_pair(CIC_PAL, CIC_NTSC);
|
||||
}
|
||||
rdyled(1);
|
||||
readled(0);
|
||||
writeled(0);
|
||||
/* exclusive mode */
|
||||
set_mcu_ovr(1);
|
||||
|
||||
*fs_path=0;
|
||||
uint32_t saved_dir_id;
|
||||
get_db_id(&saved_dir_id);
|
||||
load_bootrle(SRAM_MENU_ADDR);
|
||||
set_saveram_mask(0x1fff);
|
||||
set_rom_mask(0x3fffff);
|
||||
set_mapper(0x7);
|
||||
set_mcu_ovr(0);
|
||||
snes_reset(0);
|
||||
delay_ms(15); /* allow CIC to settle */
|
||||
|
||||
uint32_t mem_dir_id = sram_readlong(SRAM_DIRID);
|
||||
uint32_t mem_magic = sram_readlong(SRAM_SCRATCHPAD);
|
||||
printf("mem_magic=%lx mem_dir_id=%lx saved_dir_id=%lx\n", mem_magic, mem_dir_id, saved_dir_id);
|
||||
if((mem_magic != 0x12345678) || (mem_dir_id != saved_dir_id) || (newcard)) {
|
||||
newcard = 0;
|
||||
/* generate fs footprint (interesting files only) */
|
||||
uint32_t curr_dir_id = scan_dir(fs_path, 0, 0);
|
||||
printf("curr dir id = %lx\n", curr_dir_id);
|
||||
/* files changed or no database found? */
|
||||
if((get_db_id(&saved_dir_id) != FR_OK)
|
||||
|| saved_dir_id != curr_dir_id) {
|
||||
/* rebuild database */
|
||||
printf("saved dir id = %lx\n", saved_dir_id);
|
||||
printf("rebuilding database...");
|
||||
snes_bootprint(" rebuilding database ... \0");
|
||||
curr_dir_id = scan_dir(fs_path, 1, 0);
|
||||
sram_writeblock(&curr_dir_id, SRAM_DB_ADDR, 4);
|
||||
uint32_t endaddr, direndaddr;
|
||||
sram_readblock(&endaddr, SRAM_DB_ADDR+4, 4);
|
||||
sram_readblock(&direndaddr, SRAM_DB_ADDR+8, 4);
|
||||
printf("%lx %lx\n", endaddr, direndaddr);
|
||||
printf("sorting database...");
|
||||
snes_bootprint(" sorting database ... \0");
|
||||
sort_all_dir(direndaddr);
|
||||
printf("done\n");
|
||||
snes_bootprint(" saving database ... \0");
|
||||
save_sram((uint8_t*)"/sd2snes/sd2snes.db", endaddr-SRAM_DB_ADDR, SRAM_DB_ADDR);
|
||||
save_sram((uint8_t*)"/sd2snes/sd2snes.dir", direndaddr-(SRAM_DIR_ADDR), SRAM_DIR_ADDR);
|
||||
printf("done\n");
|
||||
} else {
|
||||
printf("saved dir id = %lx\n", saved_dir_id);
|
||||
printf("different card, consistent db, loading db...\n");
|
||||
load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
|
||||
load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
|
||||
}
|
||||
sram_writelong(curr_dir_id, SRAM_DIRID);
|
||||
sram_writelong(0x12345678, SRAM_SCRATCHPAD);
|
||||
} else {
|
||||
printf("same card, loading db...\n");
|
||||
load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
|
||||
load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
|
||||
}
|
||||
/* load menu */
|
||||
fpga_pgm((uint8_t*)"/main.bit.rle");
|
||||
|
||||
uart_putc('(');
|
||||
load_rom((uint8_t*)"/sd2snes/menu.bin", SRAM_MENU_ADDR);
|
||||
/* force memory size + mapper */
|
||||
set_rom_mask(0x3fffff);
|
||||
set_mapper(0x7);
|
||||
uart_putc(')');
|
||||
uart_putcrlf();
|
||||
|
||||
sram_writebyte(0, SRAM_CMD_ADDR);
|
||||
|
||||
/* shared mode */
|
||||
set_mcu_ovr(0);
|
||||
|
||||
printf("SNES GO!\n");
|
||||
snes_reset(1);
|
||||
delay_ms(1);
|
||||
snes_reset(0);
|
||||
|
||||
uint8_t cmd = 0;
|
||||
uint32_t filesize=0;
|
||||
sram_writebyte(32, SRAM_CMD_ADDR);
|
||||
printf("test sram\n");
|
||||
while(!sram_reliable());
|
||||
printf("ok\n");
|
||||
//while(1) {
|
||||
// delay_ms(1000);
|
||||
// printf("Estimated SNES master clock: %ld Hz\n", get_snes_sysclk());
|
||||
//}
|
||||
//sram_hexdump(SRAM_DB_ADDR, 0x200);
|
||||
//sram_hexdump(SRAM_MENU_ADDR, 0x400);
|
||||
while(!cmd) {
|
||||
cmd=menu_main_loop();
|
||||
// cmd = 1;
|
||||
printf("cmd: %d\n", cmd);
|
||||
sleep_ms(50);
|
||||
uart_putc('-');
|
||||
switch(cmd) {
|
||||
case SNES_CMD_LOADROM:
|
||||
get_selected_name(file_lfn);
|
||||
set_mcu_ovr(1);
|
||||
// strcpy((char*)file_lfn, "/mon.smc");
|
||||
printf("Selected name: %s\n", file_lfn);
|
||||
filesize = load_rom(file_lfn, SRAM_ROM_ADDR);
|
||||
if(romprops.ramsize_bytes) {
|
||||
strcpy(strrchr((char*)file_lfn, (int)'.'), ".srm");
|
||||
printf("SRM file: %s\n", file_lfn);
|
||||
load_sram(file_lfn, SRAM_SAVE_ADDR);
|
||||
} else {
|
||||
printf("No SRAM\n");
|
||||
}
|
||||
set_mcu_ovr(0);
|
||||
snes_reset(1);
|
||||
delay_ms(10);
|
||||
snes_reset(0);
|
||||
break;
|
||||
case SNES_CMD_SETRTC:
|
||||
cmd=0; /* stay in loop */
|
||||
break;
|
||||
default:
|
||||
printf("unknown cmd: %d\n", cmd);
|
||||
cmd=0; /* unknown cmd: stay in loop */
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("cmd was %x, going to snes main loop\n", cmd);
|
||||
|
||||
/* MSU1 STUFF, GET ME OUTTA HERE */
|
||||
FIL durr;
|
||||
// open MSU file
|
||||
strcpy((char*)file_buf, (char*)file_lfn);
|
||||
strcpy(strrchr((char*)file_buf, (int)'.'), ".msu");
|
||||
printf("MSU datafile: %s\n", file_buf);
|
||||
printf("f_open result: %d\n", f_open(&durr, (const TCHAR*)file_buf, FA_READ));
|
||||
UINT bytes_read = 1024;
|
||||
UINT bytes_read2 = 1;
|
||||
set_dac_vol(0x00);
|
||||
spi_set_speed(SSP_CLK_DIVISOR_FAST);
|
||||
while(fpga_status() & 0x4000);
|
||||
uint16_t fpga_status_prev = fpga_status();
|
||||
uint16_t fpga_status_now = fpga_status();
|
||||
uint16_t dac_addr = 0;
|
||||
uint16_t msu_addr = 0;
|
||||
uint8_t msu_repeat = 0;
|
||||
uint16_t msu_track = 0;
|
||||
uint32_t msu_offset = 0;
|
||||
|
||||
uint32_t msu_page1_start = 0x0000;
|
||||
uint32_t msu_page2_start = 0x2000;
|
||||
uint32_t msu_page_size = 0x2000;
|
||||
|
||||
set_msu_addr(0x0);
|
||||
msu_reset(0x0);
|
||||
ff_sd_offload=1;
|
||||
sd_offload_tgt=2;
|
||||
f_lseek(&durr, 0L);
|
||||
ff_sd_offload=1;
|
||||
sd_offload_tgt=2;
|
||||
f_read(&durr, file_buf, 16384, &bytes_read2);
|
||||
|
||||
set_dac_addr(dac_addr);
|
||||
dac_pause();
|
||||
dac_reset();
|
||||
/* audio_start, data_start, volume_start, audio_ctrl[1:0], ctrl_start */
|
||||
while(1){
|
||||
fpga_status_now = fpga_status();
|
||||
if(fpga_status_now & 0x0020) {
|
||||
char suffix[11];
|
||||
|
||||
/* get trackno */
|
||||
msu_track = get_msu_track();
|
||||
printf("Audio requested! Track=%d\n", msu_track);
|
||||
|
||||
/* open file */
|
||||
f_close(&file_handle);
|
||||
snprintf(suffix, sizeof(suffix), "-%d.wav", msu_track);
|
||||
strcpy((char*)file_buf, (char*)file_lfn);
|
||||
strcpy(strrchr((char*)file_buf, (int)'.'), suffix);
|
||||
printf("filename: %s\n", file_buf);
|
||||
f_open(&file_handle, (const TCHAR*)file_buf, FA_READ);
|
||||
ff_sd_offload=1;
|
||||
sd_offload_tgt=1;
|
||||
f_lseek(&file_handle, 44L);
|
||||
set_dac_addr(0);
|
||||
dac_pause();
|
||||
dac_reset();
|
||||
ff_sd_offload=1;
|
||||
sd_offload_tgt=1;
|
||||
f_read(&file_handle, file_buf, 2048, &bytes_read);
|
||||
|
||||
/* clear busy bit */
|
||||
set_msu_status(0x00, 0x20); /* set no bits, reset bit 5 */
|
||||
}
|
||||
|
||||
if(fpga_status_now & 0x0010) {
|
||||
/* get address */
|
||||
msu_offset=get_msu_offset();
|
||||
printf("Data requested! Offset=%08lx page1=%08lx page2=%08lx\n", msu_offset, msu_page1_start, msu_page2_start);
|
||||
if( ((msu_offset < msu_page1_start)
|
||||
|| (msu_offset >= msu_page1_start + msu_page_size))
|
||||
&& ((msu_offset < msu_page2_start)
|
||||
|| (msu_offset >= msu_page2_start + msu_page_size))) {
|
||||
printf("offset %08lx out of range (%08lx-%08lx, %08lx-%08lx), reload\n", msu_offset, msu_page1_start,
|
||||
msu_page1_start+msu_page_size-1, msu_page2_start, msu_page2_start+msu_page_size-1);
|
||||
/* cache miss */
|
||||
/* fill buffer */
|
||||
set_msu_addr(0x0);
|
||||
sd_offload_tgt=2;
|
||||
ff_sd_offload=1;
|
||||
printf("seek to %08lx, res = %d\n", msu_offset, f_lseek(&durr, msu_offset));
|
||||
sd_offload_tgt=2;
|
||||
ff_sd_offload=1;
|
||||
printf("read res = %d\n", f_read(&durr, file_buf, 16384, &bytes_read2));
|
||||
printf("read %d bytes\n", bytes_read2);
|
||||
msu_reset(0x0);
|
||||
msu_page1_start = msu_offset;
|
||||
msu_page2_start = msu_offset + msu_page_size;
|
||||
} else {
|
||||
if (msu_offset >= msu_page1_start && msu_offset <= msu_page1_start + msu_page_size) {
|
||||
msu_reset(0x0000 + msu_offset - msu_page1_start);
|
||||
printf("inside page1, new offset: %08lx\n", 0x0000 + msu_offset-msu_page1_start);
|
||||
if(!(msu_page2_start == msu_page1_start + msu_page_size)) {
|
||||
set_msu_addr(0x2000);
|
||||
sd_offload_tgt=2;
|
||||
ff_sd_offload=1;
|
||||
f_read(&durr, file_buf, 8192, &bytes_read2);
|
||||
printf("next page dirty (was: %08lx), loaded page2 (start now: ", msu_page2_start);
|
||||
msu_page2_start = msu_page1_start + msu_page_size;
|
||||
printf("%08lx)\n", msu_page2_start);
|
||||
}
|
||||
} else if (msu_offset >= msu_page2_start && msu_offset <= msu_page2_start + msu_page_size) {
|
||||
printf("inside page2, new offset: %08lx\n", 0x2000 + msu_offset-msu_page2_start);
|
||||
msu_reset(0x2000 + msu_offset - msu_page2_start);
|
||||
if(!(msu_page1_start == msu_page2_start + msu_page_size)) {
|
||||
set_msu_addr(0x0);
|
||||
sd_offload_tgt=2;
|
||||
ff_sd_offload=1;
|
||||
f_read(&durr, file_buf, 8192, &bytes_read2);
|
||||
printf("next page dirty (was: %08lx), loaded page1 (start now: ", msu_page1_start);
|
||||
msu_page1_start = msu_page2_start + msu_page_size;
|
||||
printf("%08lx)\n", msu_page1_start);
|
||||
}
|
||||
} else printf("!!!WATWATWAT!!!\n");
|
||||
}
|
||||
/* clear busy bit */
|
||||
set_msu_status(0x00, 0x10);
|
||||
}
|
||||
|
||||
if(fpga_status_now & 0x0001) {
|
||||
if(fpga_status_now & 0x0004) {
|
||||
msu_repeat = 1;
|
||||
set_msu_status(0x04, 0x01); /* set bit 2, reset bit 0 */
|
||||
printf("Repeat set!\n");
|
||||
} else {
|
||||
msu_repeat = 0;
|
||||
set_msu_status(0x00, 0x05); /* set no bits, reset bit 0+2 */
|
||||
printf("Repeat clear!\n");
|
||||
}
|
||||
|
||||
if(fpga_status_now & 0x0002) {
|
||||
printf("PLAY!\n");
|
||||
set_msu_status(0x02, 0x01); /* set bit 0, reset bit 1 */
|
||||
dac_play();
|
||||
} else {
|
||||
printf("PAUSE!\n");
|
||||
set_msu_status(0x00, 0x03); /* set no bits, reset bit 1+0 */
|
||||
dac_pause();
|
||||
}
|
||||
}
|
||||
|
||||
/* Audio buffer refill */
|
||||
if((fpga_status_now & 0x4000) != (fpga_status_prev & 0x4000)) {
|
||||
if(fpga_status_now & 0x4000) {
|
||||
dac_addr = 0x0;
|
||||
} else {
|
||||
dac_addr = 0x400;
|
||||
}
|
||||
set_dac_addr(dac_addr);
|
||||
sd_offload_tgt=1;
|
||||
ff_sd_offload=1;
|
||||
f_read(&file_handle, file_buf, 1024, &bytes_read);
|
||||
}
|
||||
|
||||
/* Data buffer refill */
|
||||
if((fpga_status_now & 0x2000) != (fpga_status_prev & 0x2000)) {
|
||||
printf("data\n");
|
||||
if(fpga_status_now & 0x2000) {
|
||||
msu_addr = 0x0;
|
||||
msu_page1_start = msu_page2_start + msu_page_size;
|
||||
} else {
|
||||
msu_addr = 0x2000;
|
||||
msu_page2_start = msu_page1_start + msu_page_size;
|
||||
}
|
||||
set_msu_addr(msu_addr);
|
||||
sd_offload_tgt=2;
|
||||
ff_sd_offload=1;
|
||||
printf("data buffer refilled. res=%d page1=%08lx page2=%08lx\n", f_read(&durr, file_buf, 8192, &bytes_read2), msu_page1_start, msu_page2_start);
|
||||
}
|
||||
fpga_status_prev = fpga_status_now;
|
||||
|
||||
/* handle loop / end */
|
||||
if(bytes_read<1024) {
|
||||
ff_sd_offload=0;
|
||||
sd_offload=0;
|
||||
if(msu_repeat) {
|
||||
printf("loop\n");
|
||||
ff_sd_offload=1;
|
||||
sd_offload_tgt=1;
|
||||
f_lseek(&file_handle, 44L);
|
||||
ff_sd_offload=1;
|
||||
sd_offload_tgt=1;
|
||||
f_read(&file_handle, file_buf, 1024 - bytes_read, &bytes_read);
|
||||
} else {
|
||||
set_msu_status(0x00, 0x02); /* clear play bit */
|
||||
}
|
||||
bytes_read=1024;
|
||||
}
|
||||
}
|
||||
|
||||
/* END OF MSU1 STUFF */
|
||||
|
||||
cmd=0;
|
||||
uint8_t snes_reset_prev=0, snes_reset_now=0, snes_reset_state=0;
|
||||
uint16_t reset_count=0;
|
||||
while(fpga_test() == FPGA_TEST_TOKEN) {
|
||||
cli_entrycheck();
|
||||
sleep_ms(250);
|
||||
sram_reliable();
|
||||
printf("%s ", get_cic_statename(get_cic_state()));
|
||||
snes_reset_now=get_snes_reset();
|
||||
if(snes_reset_now) {
|
||||
if(!snes_reset_prev) {
|
||||
printf("RESET BUTTON DOWN\n");
|
||||
snes_reset_state=1;
|
||||
reset_count=0;
|
||||
}
|
||||
} else {
|
||||
if(snes_reset_prev) {
|
||||
printf("RESET BUTTON UP\n");
|
||||
snes_reset_state=0;
|
||||
}
|
||||
}
|
||||
if(snes_reset_state) {
|
||||
reset_count++;
|
||||
} else {
|
||||
sram_reliable();
|
||||
snes_main_loop();
|
||||
}
|
||||
if(reset_count>4) {
|
||||
reset_count=0;
|
||||
set_mcu_ovr(1);
|
||||
snes_reset(1);
|
||||
delay_ms(1);
|
||||
if(romprops.ramsize_bytes && fpga_test() == FPGA_TEST_TOKEN) {
|
||||
writeled(1);
|
||||
save_sram(file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR);
|
||||
writeled(0);
|
||||
}
|
||||
while(get_cic_state() == CIC_FAIL) {
|
||||
rdyled(0);
|
||||
readled(0);
|
||||
writeled(0);
|
||||
delay_ms(500);
|
||||
rdyled(1);
|
||||
readled(1);
|
||||
writeled(1);
|
||||
snes_reset(0);
|
||||
while(get_snes_reset());
|
||||
snes_reset(1);
|
||||
delay_ms(200);
|
||||
goto restart;
|
||||
delay_ms(500);
|
||||
}
|
||||
snes_reset_prev = snes_reset_now;
|
||||
/* some sanity checks */
|
||||
uint8_t card_go = 0;
|
||||
while(!card_go) {
|
||||
if(disk_status(0) & (STA_NOINIT|STA_NODISK)) {
|
||||
snes_bootprint(" No Card! \0");
|
||||
while(disk_status(0) & (STA_NOINIT|STA_NODISK));
|
||||
delay_ms(200);
|
||||
}
|
||||
file_open((uint8_t*)"/sd2snes/menu.bin", FA_READ);
|
||||
if(file_status != FILE_OK) {
|
||||
snes_bootprint(" /sd2snes/menu.bin not found! \0");
|
||||
while(disk_status(0) == RES_OK);
|
||||
} else {
|
||||
card_go = 1;
|
||||
}
|
||||
file_close();
|
||||
}
|
||||
snes_bootprint(" Loading ... \0");
|
||||
if(get_cic_state() == CIC_PAIR) {
|
||||
printf("PAIR MODE ENGAGED!\n");
|
||||
cic_pair(CIC_PAL, CIC_NTSC);
|
||||
}
|
||||
rdyled(1);
|
||||
readled(0);
|
||||
writeled(0);
|
||||
/* exclusive mode */
|
||||
set_mcu_ovr(1);
|
||||
|
||||
*fs_path=0;
|
||||
uint32_t saved_dir_id;
|
||||
get_db_id(&saved_dir_id);
|
||||
|
||||
uint32_t mem_dir_id = sram_readlong(SRAM_DIRID);
|
||||
uint32_t mem_magic = sram_readlong(SRAM_SCRATCHPAD);
|
||||
printf("mem_magic=%lx mem_dir_id=%lx saved_dir_id=%lx\n", mem_magic, mem_dir_id, saved_dir_id);
|
||||
if((mem_magic != 0x12345678) || (mem_dir_id != saved_dir_id) || (newcard)) {
|
||||
newcard = 0;
|
||||
/* generate fs footprint (interesting files only) */
|
||||
uint32_t curr_dir_id = scan_dir(fs_path, 0, 0);
|
||||
printf("curr dir id = %lx\n", curr_dir_id);
|
||||
/* files changed or no database found? */
|
||||
if((get_db_id(&saved_dir_id) != FR_OK)
|
||||
|| saved_dir_id != curr_dir_id) {
|
||||
/* rebuild database */
|
||||
printf("saved dir id = %lx\n", saved_dir_id);
|
||||
printf("rebuilding database...");
|
||||
snes_bootprint(" rebuilding database ... \0");
|
||||
curr_dir_id = scan_dir(fs_path, 1, 0);
|
||||
sram_writeblock(&curr_dir_id, SRAM_DB_ADDR, 4);
|
||||
uint32_t endaddr, direndaddr;
|
||||
sram_readblock(&endaddr, SRAM_DB_ADDR+4, 4);
|
||||
sram_readblock(&direndaddr, SRAM_DB_ADDR+8, 4);
|
||||
printf("%lx %lx\n", endaddr, direndaddr);
|
||||
printf("sorting database...");
|
||||
snes_bootprint(" sorting database ... \0");
|
||||
sort_all_dir(direndaddr);
|
||||
printf("done\n");
|
||||
snes_bootprint(" saving database ... \0");
|
||||
save_sram((uint8_t*)"/sd2snes/sd2snes.db", endaddr-SRAM_DB_ADDR, SRAM_DB_ADDR);
|
||||
save_sram((uint8_t*)"/sd2snes/sd2snes.dir", direndaddr-(SRAM_DIR_ADDR), SRAM_DIR_ADDR);
|
||||
printf("done\n");
|
||||
} else {
|
||||
printf("saved dir id = %lx\n", saved_dir_id);
|
||||
printf("different card, consistent db, loading db...\n");
|
||||
load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
|
||||
load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
|
||||
}
|
||||
sram_writelong(curr_dir_id, SRAM_DIRID);
|
||||
sram_writelong(0x12345678, SRAM_SCRATCHPAD);
|
||||
} else {
|
||||
printf("same card, loading db...\n");
|
||||
load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
|
||||
load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
|
||||
}
|
||||
/* load menu */
|
||||
fpga_pgm((uint8_t*)"/main.bit.rle");
|
||||
|
||||
uart_putc('(');
|
||||
load_rom((uint8_t*)"/sd2snes/menu.bin", SRAM_MENU_ADDR);
|
||||
/* force memory size + mapper */
|
||||
set_rom_mask(0x3fffff);
|
||||
set_mapper(0x7);
|
||||
uart_putc(')');
|
||||
uart_putcrlf();
|
||||
|
||||
sram_writebyte(0, SRAM_CMD_ADDR);
|
||||
|
||||
/* shared mode */
|
||||
set_mcu_ovr(0);
|
||||
|
||||
printf("SNES GO!\n");
|
||||
snes_reset(1);
|
||||
delay_ms(1);
|
||||
snes_reset(0);
|
||||
|
||||
uint8_t cmd = 0;
|
||||
uint32_t filesize=0;
|
||||
sram_writebyte(32, SRAM_CMD_ADDR);
|
||||
printf("test sram\n");
|
||||
while(!sram_reliable());
|
||||
printf("ok\n");
|
||||
//while(1) {
|
||||
// delay_ms(1000);
|
||||
// printf("Estimated SNES master clock: %ld Hz\n", get_snes_sysclk());
|
||||
//}
|
||||
//sram_hexdump(SRAM_DB_ADDR, 0x200);
|
||||
//sram_hexdump(SRAM_MENU_ADDR, 0x400);
|
||||
while(!cmd) {
|
||||
cmd=menu_main_loop();
|
||||
// cmd = 1;
|
||||
printf("cmd: %d\n", cmd);
|
||||
sleep_ms(50);
|
||||
uart_putc('-');
|
||||
switch(cmd) {
|
||||
case SNES_CMD_LOADROM:
|
||||
get_selected_name(file_lfn);
|
||||
set_mcu_ovr(1);
|
||||
// strcpy((char*)file_lfn, "/msu1/msu1vid_ikari_01/msu1vid.sfc");
|
||||
printf("Selected name: %s\n", file_lfn);
|
||||
filesize = load_rom(file_lfn, SRAM_ROM_ADDR);
|
||||
if(romprops.ramsize_bytes) {
|
||||
strcpy(strrchr((char*)file_lfn, (int)'.'), ".srm");
|
||||
printf("SRM file: %s\n", file_lfn);
|
||||
load_sram(file_lfn, SRAM_SAVE_ADDR);
|
||||
} else {
|
||||
printf("No SRAM\n");
|
||||
}
|
||||
set_mcu_ovr(0);
|
||||
snes_reset(1);
|
||||
delay_ms(10);
|
||||
snes_reset(0);
|
||||
break;
|
||||
case SNES_CMD_SETRTC:
|
||||
cmd=0; /* stay in loop */
|
||||
break;
|
||||
default:
|
||||
printf("unknown cmd: %d\n", cmd);
|
||||
cmd=0; /* unknown cmd: stay in loop */
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("cmd was %x, going to snes main loop\n", cmd);
|
||||
|
||||
/* always try MSU1 for now */
|
||||
if(msu1_entrycheck_and_loop()) {
|
||||
prepare_reset();
|
||||
continue;
|
||||
}
|
||||
|
||||
cmd=0;
|
||||
uint8_t snes_reset_prev=0, snes_reset_now=0, snes_reset_state=0;
|
||||
uint16_t reset_count=0;
|
||||
while(fpga_test() == FPGA_TEST_TOKEN) {
|
||||
cli_entrycheck();
|
||||
sleep_ms(250);
|
||||
sram_reliable();
|
||||
printf("%s ", get_cic_statename(get_cic_state()));
|
||||
snes_reset_now=get_snes_reset();
|
||||
if(snes_reset_now) {
|
||||
if(!snes_reset_prev) {
|
||||
printf("RESET BUTTON DOWN\n");
|
||||
snes_reset_state=1;
|
||||
reset_count=0;
|
||||
}
|
||||
} else {
|
||||
if(snes_reset_prev) {
|
||||
printf("RESET BUTTON UP\n");
|
||||
snes_reset_state=0;
|
||||
}
|
||||
}
|
||||
if(snes_reset_state) {
|
||||
reset_count++;
|
||||
} else {
|
||||
sram_reliable();
|
||||
snes_main_loop();
|
||||
}
|
||||
if(reset_count>4) {
|
||||
reset_count=0;
|
||||
prepare_reset();
|
||||
break;
|
||||
}
|
||||
snes_reset_prev = snes_reset_now;
|
||||
}
|
||||
/* fpga test fail: panic */
|
||||
if(fpga_test() != FPGA_TEST_TOKEN){
|
||||
led_panic();
|
||||
}
|
||||
/* else reset */
|
||||
}
|
||||
/* fpga test fail: panic */
|
||||
led_panic();
|
||||
}
|
||||
|
||||
|
||||
34
src/memory.c
34
src/memory.c
@@ -59,7 +59,7 @@ void sram_hexdump(uint32_t addr, uint32_t len) {
|
||||
void sram_writebyte(uint8_t val, uint32_t addr) {
|
||||
set_mcu_addr(addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x91); /* WRITE */
|
||||
FPGA_TX_BYTE(0x98); /* WRITE */
|
||||
FPGA_TX_BYTE(val);
|
||||
FPGA_TX_BYTE(0x00); /* dummy */
|
||||
FPGA_DESELECT();
|
||||
@@ -68,7 +68,7 @@ void sram_writebyte(uint8_t val, uint32_t addr) {
|
||||
uint8_t sram_readbyte(uint32_t addr) {
|
||||
set_mcu_addr(addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x81); /* READ */
|
||||
FPGA_TX_BYTE(0x88); /* READ */
|
||||
FPGA_TX_BYTE(0x00); /* dummy */
|
||||
uint8_t val = FPGA_TXRX_BYTE(0x00);
|
||||
FPGA_DESELECT();
|
||||
@@ -78,7 +78,7 @@ uint8_t sram_readbyte(uint32_t addr) {
|
||||
void sram_writeshort(uint16_t val, uint32_t addr) {
|
||||
set_mcu_addr(addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x91); /* WRITE */
|
||||
FPGA_TX_BYTE(0x98); /* WRITE */
|
||||
FPGA_TX_BYTE(val&0xff);
|
||||
FPGA_TX_BYTE((val>>8)&0xff);
|
||||
FPGA_TX_BYTE(0x00); /* dummy */
|
||||
@@ -88,7 +88,7 @@ void sram_writeshort(uint16_t val, uint32_t addr) {
|
||||
void sram_writelong(uint32_t val, uint32_t addr) {
|
||||
set_mcu_addr(addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x91); /* WRITE */
|
||||
FPGA_TX_BYTE(0x98); /* WRITE */
|
||||
FPGA_TX_BYTE(val&0xff);
|
||||
FPGA_TX_BYTE((val>>8)&0xff);
|
||||
FPGA_TX_BYTE((val>>16)&0xff);
|
||||
@@ -100,7 +100,7 @@ void sram_writelong(uint32_t val, uint32_t addr) {
|
||||
uint16_t sram_readshort(uint32_t addr) {
|
||||
set_mcu_addr(addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x81);
|
||||
FPGA_TX_BYTE(0x88);
|
||||
FPGA_TX_BYTE(0x00);
|
||||
uint32_t val = FPGA_TXRX_BYTE(0x00);
|
||||
val |= ((uint32_t)FPGA_TXRX_BYTE(0x00)<<8);
|
||||
@@ -111,7 +111,7 @@ uint16_t sram_readshort(uint32_t addr) {
|
||||
uint32_t sram_readlong(uint32_t addr) {
|
||||
set_mcu_addr(addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x81);
|
||||
FPGA_TX_BYTE(0x88);
|
||||
FPGA_TX_BYTE(0x00);
|
||||
uint32_t val = FPGA_TXRX_BYTE(0x00);
|
||||
val |= ((uint32_t)FPGA_TXRX_BYTE(0x00)<<8);
|
||||
@@ -124,7 +124,7 @@ uint32_t sram_readlong(uint32_t addr) {
|
||||
void sram_readlongblock(uint32_t* buf, uint32_t addr, uint16_t count) {
|
||||
set_mcu_addr(addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x81);
|
||||
FPGA_TX_BYTE(0x88);
|
||||
FPGA_TX_BYTE(0x00);
|
||||
uint16_t i=0;
|
||||
while(i<count) {
|
||||
@@ -142,7 +142,7 @@ void sram_readblock(void* buf, uint32_t addr, uint16_t size) {
|
||||
uint8_t* tgt = buf;
|
||||
set_mcu_addr(addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x81); /* READ */
|
||||
FPGA_TX_BYTE(0x88); /* READ */
|
||||
FPGA_TX_BYTE(0x00); /* dummy */
|
||||
while(count--) {
|
||||
*(tgt++) = FPGA_TXRX_BYTE(0x00);
|
||||
@@ -155,7 +155,7 @@ void sram_writeblock(void* buf, uint32_t addr, uint16_t size) {
|
||||
uint8_t* src = buf;
|
||||
set_mcu_addr(addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x91); /* WRITE */
|
||||
FPGA_TX_BYTE(0x98); /* WRITE */
|
||||
while(count--) {
|
||||
FPGA_TX_BYTE(*src++);
|
||||
}
|
||||
@@ -212,7 +212,7 @@ ticks_total=getticks()-ticksstart;
|
||||
printf("%u ticks in read, %u ticks in tx, %u ticks total\n", ticks_read, ticks_tx, ticks_total);
|
||||
uint32_t rammask;
|
||||
uint32_t rommask;
|
||||
|
||||
|
||||
if(filesize > (romprops.romsize_bytes + romprops.offset)) {
|
||||
romprops.romsize_bytes <<= 1;
|
||||
}
|
||||
@@ -241,7 +241,7 @@ uint32_t load_sram(uint8_t* filename, uint32_t base_addr) {
|
||||
bytes_read = file_read();
|
||||
if (file_res || !bytes_read) break;
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x91);
|
||||
FPGA_TX_BYTE(0x98);
|
||||
for(int j=0; j<bytes_read; j++) {
|
||||
FPGA_TX_BYTE(file_buf[j]);
|
||||
}
|
||||
@@ -260,7 +260,7 @@ uint32_t load_sram_rle(uint8_t* filename, uint32_t base_addr) {
|
||||
filesize = file_handle.fsize;
|
||||
if(file_res) return 0;
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x91);
|
||||
FPGA_TX_BYTE(0x98);
|
||||
for(;;) {
|
||||
data = rle_file_getc();
|
||||
if (file_res || file_status) break;
|
||||
@@ -277,9 +277,9 @@ uint32_t load_bootrle(uint32_t base_addr) {
|
||||
set_mcu_addr(base_addr);
|
||||
DWORD filesize = 0;
|
||||
rle_mem_init(bootrle, sizeof(bootrle));
|
||||
|
||||
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x91);
|
||||
FPGA_TX_BYTE(0x98);
|
||||
for(;;) {
|
||||
data = rle_mem_getc();
|
||||
if(rle_state) break;
|
||||
@@ -304,7 +304,7 @@ void save_sram(uint8_t* filename, uint32_t sram_size, uint32_t base_addr) {
|
||||
while(count<sram_size) {
|
||||
set_mcu_addr(base_addr+count);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x81); /* read */
|
||||
FPGA_TX_BYTE(0x88); /* read */
|
||||
FPGA_TX_BYTE(0x00); /* dummy */
|
||||
for(int j=0; j<sizeof(file_buf); j++) {
|
||||
file_buf[j] = FPGA_TXRX_BYTE(0x00);
|
||||
@@ -328,7 +328,7 @@ uint32_t calc_sram_crc(uint32_t base_addr, uint32_t size) {
|
||||
crc_valid=1;
|
||||
set_mcu_addr(base_addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x81);
|
||||
FPGA_TX_BYTE(0x88);
|
||||
FPGA_TX_BYTE(0x00);
|
||||
for(count=0; count<size; count++) {
|
||||
data = FPGA_TXRX_BYTE(0x00);
|
||||
@@ -375,7 +375,7 @@ uint8_t sram_reliable() {
|
||||
void sram_memset(uint32_t base_addr, uint32_t len, uint8_t val) {
|
||||
set_mcu_addr(base_addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x91);
|
||||
FPGA_TX_BYTE(0x98);
|
||||
for(uint32_t i=0; i<len; i++) {
|
||||
FPGA_TX_BYTE(val);
|
||||
}
|
||||
|
||||
23
src/snes.c
23
src/snes.c
@@ -37,16 +37,35 @@
|
||||
#include "timer.h"
|
||||
#include "cli.h"
|
||||
#include "fpga.h"
|
||||
#include "fpga_spi.h"
|
||||
|
||||
uint8_t initloop=1;
|
||||
uint32_t saveram_crc, saveram_crc_old;
|
||||
extern snes_romprops_t romprops;
|
||||
|
||||
void prepare_reset() {
|
||||
set_mcu_ovr(1);
|
||||
snes_reset(1);
|
||||
delay_ms(1);
|
||||
if(romprops.ramsize_bytes && fpga_test() == FPGA_TEST_TOKEN) {
|
||||
writeled(1);
|
||||
save_sram(file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR);
|
||||
writeled(0);
|
||||
}
|
||||
rdyled(1);
|
||||
readled(1);
|
||||
writeled(1);
|
||||
snes_reset(0);
|
||||
while(get_snes_reset());
|
||||
snes_reset(1);
|
||||
delay_ms(200);
|
||||
}
|
||||
|
||||
void snes_init() {
|
||||
/* put reset level on reset pin */
|
||||
BITBAND(SNES_RESET_REG->FIOCLR, SNES_RESET_BIT) = 1;
|
||||
/* reset the SNES */
|
||||
snes_reset(1);
|
||||
snes_reset(1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -106,7 +125,7 @@ void snes_main_loop() {
|
||||
diffcount=0;
|
||||
writeled(1);
|
||||
save_sram(file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR);
|
||||
didnotsave=0;
|
||||
didnotsave=0;
|
||||
writeled(0);
|
||||
}
|
||||
saveram_crc_old = saveram_crc;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
uint8_t crc_valid;
|
||||
|
||||
void prepare_reset(void);
|
||||
void snes_init(void);
|
||||
void snes_reset(int state);
|
||||
uint8_t get_snes_reset(void);
|
||||
|
||||
Reference in New Issue
Block a user