memory access bugfix (broke resetting after MSU1 usage)

This commit is contained in:
ikari
2010-12-31 03:06:21 +01:00
parent d803252866
commit a701dfbe2e
11 changed files with 284 additions and 746 deletions

View File

@@ -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.

View File

@@ -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;

View File

@@ -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

View File

@@ -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>

View File

@@ -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();
}

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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);