MSU1 data support

This commit is contained in:
ikari 2010-12-22 03:58:40 +01:00
parent 4c8eab9228
commit 3e93af19ee
4 changed files with 117 additions and 41 deletions

View File

@ -1937,6 +1937,7 @@ FRESULT validate ( /* FR_OK(0): The object is valid, !=0: Invalid */
WORD id /* Member id of the target object to be checked */
)
{
// printf("fs=%p fs->fs_type=%d fs->id=%d id=%d\n", fs, fs->fs_type, fs->id, id);
if (!fs || !fs->fs_type || fs->id != id)
return FR_INVALID_OBJECT;
@ -2144,6 +2145,7 @@ FRESULT f_read (
UINT rcnt, cc;
BYTE csect, *rbuff = buff;
if(btr>512 && !ff_sd_offload) printf("WARNING: read >512 bytes but offloading is inactive!!\n");
*br = 0; /* Initialize byte counter */
@ -2220,7 +2222,7 @@ printf("DIRTY!?!\n");
mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */
#else
mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */
// printf("final mem_cpy, rcnt=%d, rbuff-buff=%d\n", rcnt, (void*)rbuff-buff);
printf("final mem_cpy, rcnt=%d, rbuff-buff=%d\n", rcnt, (void*)rbuff-buff);
} else {
sd_offload_partial_start = fp->fptr % SS(fp->fs);
sd_offload_partial_end = sd_offload_partial_start + rcnt;

View File

@ -64,6 +64,7 @@
E1 - pause DAC
E2 - resume/play DAC
E3 - reset DAC playback pointer (0)
E4 - reset MSU read pointer (0)
F0 - receive test token (to see if FPGA is alive)
F1 - receive status
@ -72,6 +73,7 @@
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)
*/
@ -88,7 +90,7 @@ void fpga_spi_init(void) {
spi_init(SPI_SPEED_FPGA_FAST);
}
void set_msu_addr(uint32_t address) {
void set_msu_addr(uint16_t address) {
FPGA_SELECT();
FPGA_TX_BYTE(0x02);
FPGA_TX_BYTE((address>>8)&0xff);
@ -96,7 +98,7 @@ void set_msu_addr(uint32_t address) {
FPGA_DESELECT();
}
void set_dac_addr(uint32_t address) {
void set_dac_addr(uint16_t address) {
FPGA_SELECT();
FPGA_TX_BYTE(0x01);
FPGA_TX_BYTE((address>>8)&0xff);
@ -215,6 +217,17 @@ void dac_reset() {
FPGA_SELECT();
FPGA_TX_BYTE(0xe3);
FPGA_TX_BYTE(0x00); /* latch reset */
FPGA_TX_BYTE(0x00); /* latch reset */
FPGA_DESELECT();
}
void msu_reset(uint16_t address) {
FPGA_SELECT();
FPGA_TX_BYTE(0xe4);
FPGA_TX_BYTE((address>>8) & 0xff); /* address hi */
FPGA_TX_BYTE(address & 0xff); /* address lo */
FPGA_TX_BYTE(0x00); /* latch reset */
FPGA_TX_BYTE(0x00); /* latch reset */
FPGA_DESELECT();
}
@ -224,7 +237,6 @@ void set_msu_status(uint8_t set, uint8_t reset) {
FPGA_TX_BYTE(set);
FPGA_TX_BYTE(reset);
FPGA_TX_BYTE(0x00); /* latch reset */
FPGA_TX_BYTE(0x00); /* latch reset */
FPGA_DESELECT();
}
@ -259,3 +271,15 @@ uint32_t get_msu_offset() {
return result;
}
uint32_t get_snes_sysclk() {
FPGA_SELECT();
FPGA_TX_BYTE(0xFE); /* GET_SYSCLK */
FPGA_TX_BYTE(0x00); /* dummy */
FPGA_TX_BYTE(0x00); /* dummy */
uint32_t result = (FPGA_RX_BYTE()) << 24;
result |= (FPGA_RX_BYTE()) << 16;
result |= (FPGA_RX_BYTE()) << 8;
result |= (FPGA_RX_BYTE());
FPGA_DESELECT();
return result;
}

View File

@ -55,12 +55,13 @@ void spi_fpga(void);
void spi_sd(void);
void spi_none(void);
void set_mcu_addr(uint32_t);
void set_dac_addr(uint32_t);
void set_dac_addr(uint16_t);
void set_dac_vol(uint8_t);
void dac_play(void);
void dac_pause(void);
void dac_reset(void);
void set_msu_addr(uint32_t);
void msu_reset(uint16_t);
void set_msu_addr(uint16_t);
void set_msu_status(uint8_t set, uint8_t reset);
void set_saveram_mask(uint32_t);
void set_rom_mask(uint32_t);
@ -70,4 +71,5 @@ void fpga_set_sddma_range(uint16_t start, uint16_t end);
uint8_t get_msu_volume(void);
uint16_t get_msu_track(void);
uint32_t get_msu_offset(void);
uint32_t get_snes_sysclk(void);
#endif

View File

@ -71,7 +71,7 @@ led_pwm();
fpga_spi_init();
printf("\n\nsd2snes mk.2\n============\nfw ver.: " VER "\ncpu clock: %d Hz\n", CONFIG_CPU_FREQUENCY);
file_init();
cic_init(1);
cic_init(0);
/* setup timer (fpga clk) */
LPC_TIM3->CTCR=0;
@ -124,7 +124,7 @@ restart:
snes_bootprint(" Loading ... \0");
if(get_cic_state() == CIC_PAIR) {
printf("PAIR MODE ENGAGED!\n");
cic_pair(CIC_NTSC, CIC_NTSC);
cic_pair(CIC_PAL, CIC_NTSC);
}
rdyled(1);
readled(0);
@ -180,6 +180,7 @@ restart:
}
/* 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 */
@ -204,10 +205,15 @@ restart:
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('-');
@ -215,6 +221,7 @@ restart:
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) {
@ -242,14 +249,13 @@ restart:
/* MSU1 STUFF, GET ME OUTTA HERE */
FIL durr;
f_open(&durr, "/SF96SOE.smc", FA_READ);
ff_sd_offload=1;
sd_offload_tgt=2;
f_lseek(&durr, 79L);
set_msu_addr(0);
// 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;
uint16_t volume=0;
set_dac_vol(0x00);
spi_set_speed(SSP_CLK_DIVISOR_FAST);
while(fpga_status() & 0x4000);
@ -260,9 +266,20 @@ restart:
uint8_t msu_repeat = 0;
uint16_t msu_track = 0;
uint32_t msu_offset = 0;
uint8_t msu_volume = 0;
uint8_t msu_volupdate = 0;
uint8_t msu_volupdate_cnt = 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();
@ -281,15 +298,16 @@ while(1){
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);
ff_sd_offload=1;
sd_offload_tgt=1;
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 */
@ -297,11 +315,56 @@ while(1){
}
if(fpga_status_now & 0x0010) {
/* get address */
msu_offset=get_msu_offset();
printf("Data requested! Offset=%08lx\n", msu_offset);
// get address
// open file + fill buffer
// clear busy bit
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);
}
@ -340,31 +403,20 @@ while(1){
f_read(&file_handle, file_buf, 1024, &bytes_read);
}
/* volume update */
if(msu_volupdate && !(msu_volupdate_cnt++ & 0x1)) {
if(volume < msu_volume) {
volume++;
} else if(volume > msu_volume) {
volume--;
} else {
msu_volupdate = 0;
}
printf("should not see me!\n");
set_dac_vol(volume);
}
/* 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;
f_read(&durr, file_buf, 8192, &bytes_read2);
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;
@ -385,10 +437,6 @@ while(1){
}
bytes_read=1024;
}
if(!bytes_read2) {
f_lseek(&durr, 0L);
uart_putc('*');
}
}
/* END OF MSU1 STUFF */