diff --git a/src/bits.h b/src/bits.h index 37e3b80..5055737 100644 --- a/src/bits.h +++ b/src/bits.h @@ -11,4 +11,11 @@ (bit)*4 + 0x02000000 + ((unsigned long)&(addr) & 0xfe000000) \ ))) +#define BITBAND_OFF(addr,offset,bit) \ + (*((volatile unsigned long *)( \ + (((unsigned long)&(addr) + offset) & 0x01ffffff)*32 + \ + (bit)*4 + 0x02000000 + (((unsigned long)&(addr) + offset) & 0xfe000000) \ + ))) + + #endif diff --git a/src/config.h b/src/config.h index a8f22e5..d8abba8 100644 --- a/src/config.h +++ b/src/config.h @@ -1,6 +1,8 @@ #ifndef _CONFIG_H #define _CONFIG_H +// #define DEBUG_SD + #define VER "0.0.1(NSFW)" #define IN_AHBRAM __attribute__ ((section(".ahbram"))) @@ -71,4 +73,22 @@ // 1: 3 #define SSP_DMACH LPC_GPDMACH0 +#define SD_CLKREG LPC_GPIO0 +#define SD_CMDREG LPC_GPIO0 +#define SD_DAT0REG LPC_GPIO0 +#define SD_DAT1REG LPC_GPIO1 +#define SD_DAT2REG LPC_GPIO1 +#define SD_DAT3REG LPC_GPIO0 + +#define SD_CLKPIN (7) +#define SD_CMDPIN (9) +#define SD_DAT0PIN (8) +#define SD_DAT1PIN (14) +#define SD_DAT2PIN (15) +#define SD_DAT3PIN (6) + +#define SD_DAT ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))\ + |((SD_DAT1REG->FIOPIN1 >> 5) & 0x6)\ + |((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3)) + #endif diff --git a/src/diskio.h b/src/diskio.h index 74e3851..3ca62ec 100644 --- a/src/diskio.h +++ b/src/diskio.h @@ -62,6 +62,7 @@ void disk_init(void); /* Will be set to DISK_ERROR if any access on the card fails */ enum diskstates { DISK_CHANGED = 0, DISK_REMOVED, DISK_OK, DISK_ERROR }; +extern int sd_offload, ff_sd_offload; extern volatile enum diskstates disk_state; /* Disk type - part of the external API except for ATA2! */ diff --git a/src/ff.c b/src/ff.c index 80f0037..6b759a0 100644 --- a/src/ff.c +++ b/src/ff.c @@ -2175,8 +2175,12 @@ FRESULT f_read ( if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */ cc = fp->fs->csize - csect; /* XXX OFFLOAD GOES HERE */ + if (ff_sd_offload) { + sd_offload = 1; + } if (disk_read(fp->fs->drv, rbuff, sect, (BYTE)cc) != RES_OK) ABORT(fp->fs, FR_DISK_ERR); + sd_offload = 0; #if !_FS_READONLY && _FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */ #if _FS_TINY if (fp->fs->wflag && fp->fs->winsect - sect < cc) @@ -2214,7 +2218,7 @@ FRESULT f_read ( mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ #endif } - + ff_sd_offload = 0; LEAVE_FF(fp->fs, FR_OK); } diff --git a/src/ffconf.h b/src/ffconf.h index 14551ed..fb2757c 100644 --- a/src/ffconf.h +++ b/src/ffconf.h @@ -48,7 +48,7 @@ /* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */ -#define _USE_FASTSEEK 1 /* 0:Disable or 1:Enable */ +#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */ /* To enable fast seek feature, set _USE_FASTSEEK to 1. */ diff --git a/src/fileops.c b/src/fileops.c index a596d7d..60746e6 100644 --- a/src/fileops.c +++ b/src/fileops.c @@ -61,6 +61,9 @@ UINT file_read() { UINT file_write() { UINT bytes_written; file_res = f_write(&file_handle, file_buf, sizeof(file_buf), &bytes_written); + if(bytes_written < sizeof(file_buf)) { + printf("wrote less than expected - card full?\n"); + } return bytes_written; } diff --git a/src/filetypes.c b/src/filetypes.c index 0eb43d1..41733ad 100644 --- a/src/filetypes.c +++ b/src/filetypes.c @@ -70,7 +70,10 @@ uint32_t scan_dir(char* path, char mkdb, uint32_t this_dir_tgt) { uint16_t numentries; uint32_t dirsize; uint8_t pass = 0; - char buf[10]; + char buf[7]; + char *size_units[3] = {" ", "k", "M"}; + uint32_t entry_fsize; + uint8_t entry_unit_idx; dir_tgt = this_dir_tgt; if(depth==0) { @@ -185,7 +188,7 @@ uint32_t scan_dir(char* path, char mkdb, uint32_t this_dir_tgt) { /* write element pointer to current dir structure */ /* printf("d=%d Saving %lX to Address %lX [file]\n", depth, db_tgt, dir_tgt); */ - if((db_tgt&0xffff) > ((0x10000-(sizeof(len) + pathlen + sizeof(fno.fsize) + 1))&0xffff)) { + if((db_tgt&0xffff) > ((0x10000-(sizeof(len) + pathlen + sizeof(buf)-1 + 1))&0xffff)) { printf("switch! old=%lx ", db_tgt); db_tgt &= 0xffff0000; db_tgt += 0x00010000; @@ -198,7 +201,14 @@ uint32_t scan_dir(char* path, char mkdb, uint32_t this_dir_tgt) { - file name - file size */ /* sram_writeblock((uint8_t*)&romprops, db_tgt, sizeof(romprops)); */ - snprintf(buf, sizeof(buf), " % 7ldk", fno.fsize/1024); + entry_fsize = fno.fsize; + entry_unit_idx = 0; + while(entry_fsize > 9999) { + entry_fsize >>= 10; + entry_unit_idx++; + } + snprintf(buf, sizeof(buf), "% 5ld", entry_fsize); + strncat(buf, size_units[entry_unit_idx], 1); sram_writeblock(buf, db_tgt, sizeof(buf)-1); sram_writebyte(len+1, db_tgt + sizeof(buf)-1); sram_writeblock(path, db_tgt + sizeof(len) + sizeof(buf)-1, pathlen + 1); diff --git a/src/fpga.c b/src/fpga.c index 1d7f029..9110745 100644 --- a/src/fpga.c +++ b/src/fpga.c @@ -97,11 +97,22 @@ void fpga_pgm(uint8_t* filename) { int MAXRETRIES = 10; int retries = MAXRETRIES; uint8_t data; + int i; + tick_t timeout; +// UINT bytes_read; +// uint16_t j; do { + i=0; + timeout = getticks() + 100; fpga_set_prog_b(0); uart_putc('P'); fpga_set_prog_b(1); - while(!fpga_get_initb()); + while(!fpga_get_initb()){ + if(getticks() > timeout) { + printf("no response from FPGA trying to initiate configuration!\n"); + led_panic(); + } + }; LPC_GPIO2->FIOMASK1 = ~(BV(0)); uart_putc('p'); @@ -114,13 +125,17 @@ void fpga_pgm(uint8_t* filename) { return; } uart_putc('C'); + for (;;) { data = rle_file_getc(); +i++; if (file_status || file_res) break; /* error or eof */ FPGA_SEND_BYTE_SERIAL(data); } uart_putc('c'); file_close(); + printf("fpga_pgm: %d bytes programmed\n", i); + delay_ms(1); } while (!fpga_get_done() && retries--); if(!fpga_get_done()) { printf("FPGA failed to configure after %d tries.\n", MAXRETRIES); diff --git a/src/fpga.h b/src/fpga.h index b3e4058..0396af5 100644 --- a/src/fpga.h +++ b/src/fpga.h @@ -35,7 +35,6 @@ void fpga_set_cclk(uint8_t val); int fpga_get_initb(void); void fpga_init(void); -uint8_t fpga_test(void); void fpga_postinit(void); void fpga_pgm(uint8_t* filename); diff --git a/src/fpga_spi.c b/src/fpga_spi.c index 586c018..093a04b 100644 --- a/src/fpga_spi.c +++ b/src/fpga_spi.c @@ -29,16 +29,19 @@ cmd param function ============================================= - 00 bb[hh[ll]] set address to 0xbb0000, 0xbbhh00, or 0xbbhhll - 10 bbhhll set SNES input address mask to 0xbbhhll - 20 bbhhll set SRAM address mask to 0xbbhhll + 00 bbhhll set address to 0xbbhhll + 01 bbhhll set SNES input address mask to 0xbbhhll + 02 bbhhll set SRAM address mask to 0xbbhhll 3m - set mapper to m - 0=HiROM, 1=LoROM, 2=ExHiROM, 7=Menu + 0=HiROM, 1=LoROM, 2=ExHiROM, 6=SF96, 7=Menu + 40 - trigger SD DMA (512b from SD to memory) 80 - read with increment 81 - read w/o increment 90 {xx}* write xx with increment 91 {xx}* write xx w/o increment + Eu - set memory unit (u=0: "ROM"; u=1: SRAM) F0 - receive test token (to see if FPGA is alive) + F1 - receive status */ @@ -66,7 +69,7 @@ void set_mcu_addr(uint32_t address) { void set_saveram_mask(uint32_t mask) { FPGA_SELECT(); - FPGA_TX_BYTE(0x20); + FPGA_TX_BYTE(0x02); FPGA_TX_BYTE((mask>>16)&0xff); FPGA_TX_BYTE((mask>>8)&0xff); FPGA_TX_BYTE((mask)&0xff); @@ -75,7 +78,7 @@ void set_saveram_mask(uint32_t mask) { void set_rom_mask(uint32_t mask) { FPGA_SELECT(); - FPGA_TX_BYTE(0x10); + FPGA_TX_BYTE(0x01); FPGA_TX_BYTE((mask>>16)&0xff); FPGA_TX_BYTE((mask>>8)&0xff); FPGA_TX_BYTE((mask)&0xff); @@ -97,3 +100,25 @@ uint8_t fpga_test() { return result; } +uint8_t fpga_status() { + FPGA_SELECT(); + FPGA_TX_BYTE(0xF1); /* STATUS */ + FPGA_TX_BYTE(0x00); /* dummy */ + uint8_t result = FPGA_RX_BYTE(); + FPGA_DESELECT(); + return result; +} + +void fpga_sd2ram() { + BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 0; + FPGA_SELECT(); + FPGA_TX_BYTE(0x40); /* DO DMA */ + FPGA_TX_BYTE(0x00); /* dummy for falling DMA_EN edge */ + FPGA_DESELECT(); + FPGA_SELECT(); + FPGA_TX_BYTE(0xF1); /* STATUS */ + FPGA_TX_BYTE(0x00); /* dummy */ + while(FPGA_RX_BYTE() & 0x80); + FPGA_DESELECT(); + BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 1; +} diff --git a/src/fpga_spi.h b/src/fpga_spi.h index 12fbd89..83bf5a7 100644 --- a/src/fpga_spi.h +++ b/src/fpga_spi.h @@ -47,7 +47,8 @@ #define FPGA_SPI_SLOW() spi_set_speed(SPI_SPEED_FPGA_SLOW) void fpga_spi_init(void); -void fpga_spi_test(void); +uint8_t fpga_test(void); +uint8_t fpga_status(void); void spi_fpga(void); void spi_sd(void); void spi_none(void); @@ -55,5 +56,6 @@ void set_mcu_addr(uint32_t); void set_saveram_mask(uint32_t); void set_rom_mask(uint32_t); void set_mapper(uint8_t val); +void fpga_sd2ram(void); #endif diff --git a/src/main.c b/src/main.c index 9071a5f..9db23f1 100644 --- a/src/main.c +++ b/src/main.c @@ -23,15 +23,19 @@ #include "cli.h" #include "sdnative.h" #include "crc.h" +#include "smc.h" #define EMC0TOGGLE (3<<4) #define MR0R (1<<1) int i; +int sd_offload = 0, ff_sd_offload = 0; /* FIXME HACK */ volatile enum diskstates disk_state; extern volatile tick_t ticks; +extern snes_romprops_t romprops; + int main(void) { LPC_GPIO2->FIODIR = BV(0) | BV(1) | BV(2); LPC_GPIO1->FIODIR = 0; @@ -58,25 +62,12 @@ int main(void) { /* do this last because the peripheral init()s change PCLK dividers */ clock_init(); -// sd_init(); sdn_init(); -// while(1); fpga_spi_init(); - delay_ms(10); printf("\n\nsd2snes mk.2\n============\nfw ver.: " VER "\ncpu clock: %d Hz\n", CONFIG_CPU_FREQUENCY); file_init(); cic_init(1); -/* uart_putc('S'); - for(p1=0; p1<8192; p1++) { - file_read(); - } - file_close(); - uart_putc('E'); - uart_putcrlf(); - printf("sizeof(struct FIL): %d\n", sizeof(file_handle)); - uart_trace(file_buf, 0, 512);*/ - /* setup timer (fpga clk) */ LPC_TIM3->CTCR=0; LPC_TIM3->EMR=EMC0TOGGLE; @@ -103,16 +94,6 @@ restart: uint32_t mem_dir_id = sram_readlong(SRAM_DIRID); uint32_t mem_magic = sram_readlong(SRAM_SCRATCHPAD); -/* printf("savetest..."); - int i; - uint16_t testcrc = 0; - for(i=0; i<128; i++) { - testcrc = crc_xmodem_update(testcrc, 0xff); - } - printf("testcrc = %04x\n", testcrc); - save_sram((uint8_t*)"/pretty long filename here you know.bin", 0x400000, SRAM_DB_ADDR); - printf("it's over!\n"); - while(1)cli_entrycheck(); */ printf("mem_magic=%lx mem_dir_id=%lx saved_dir_id=%lx\n", mem_magic, mem_dir_id, saved_dir_id); mem_magic=0x12938712; /* always rescan card for now */ if((mem_magic != 0x12345678) || (mem_dir_id != saved_dir_id)) { @@ -172,11 +153,12 @@ restart: printf("test sram\n"); while(!sram_reliable()); printf("ok\n"); -sram_hexdump(SRAM_DB_ADDR, 0x200); +//sram_hexdump(SRAM_DB_ADDR, 0x200); +//sram_hexdump(SRAM_MENU_ADDR, 0x400); while(!cmd) { cmd=menu_main_loop(); - printf("derp %d\n", cmd); + printf("cmd: %d\n", cmd); sleep_ms(50); uart_putc('-'); switch(cmd) { @@ -192,13 +174,13 @@ sram_hexdump(SRAM_DB_ADDR, 0x200); } else { printf("No SRAM\n"); } -save_sram((uint8_t*)"/debug.smc", filesize, SRAM_ROM_ADDR); set_mcu_ovr(0); snes_reset(1); delay_ms(100); snes_reset(0); break; case SNES_CMD_SETRTC: + cmd=0; /* stay in loop */ break; default: printf("unknown cmd: %d\n", cmd); @@ -230,18 +212,17 @@ save_sram((uint8_t*)"/debug.smc", filesize, SRAM_ROM_ADDR); } } if(snes_reset_state) { - delay_ms(10); reset_count++; } else { sram_reliable(); snes_main_loop(); } - if(reset_count>100) { + if(reset_count>4) { reset_count=0; set_mcu_ovr(1); snes_reset(1); delay_ms(100); - if(romprops.ramsize_bytes && fpga_test() == 0xa5) { + if(romprops.ramsize_bytes && fpga_test() == FPGA_TEST_TOKEN) { writeled(1); save_sram(file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR); writeled(0); diff --git a/src/memory.c b/src/memory.c index a30b917..bcf9d11 100644 --- a/src/memory.c +++ b/src/memory.c @@ -39,9 +39,13 @@ #include "memory.h" #include "snes.h" #include "timer.h" +#include "rle.h" +#include "diskio.h" char* hex = "0123456789ABCDEF"; +extern snes_romprops_t romprops; + void sram_hexdump(uint32_t addr, uint32_t len) { static uint8_t buf[16]; uint32_t ptr; @@ -162,25 +166,30 @@ uint32_t load_rom(uint8_t* filename, uint32_t base_addr) { UINT bytes_read; DWORD filesize; UINT count=0; + tick_t tickstmp, ticksstart, ticks_read=0, ticks_tx=0, ticks_total=0; +ticksstart=getticks(); +printf("%s\n", filename); file_open(filename, FA_READ); - filesize = file_handle.fsize; - smc_id(&romprops); - set_mcu_addr(base_addr); - printf("no nervous breakdown beyond this point! or else!\n"); if(file_res) { uart_putc('?'); uart_putc(0x30+file_res); return 0; } + 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); - FPGA_DESELECT(); - FPGA_SELECT(); - FPGA_TX_BYTE(0x91); /* write w/ increment */ +// FPGA_DESELECT(); +// FPGA_SELECT(); +// FPGA_TX_BYTE(0x91); /* write w/ increment */ for(;;) { -/* SPI_OFFLOAD=1; */ + ff_sd_offload=1; +tickstmp=getticks(); bytes_read = file_read(); +ticks_read+=getticks()-tickstmp; if (file_res || !bytes_read) break; - if(!(count++ % 32)) { + if(!(count++ % 512)) { toggle_read_led(); /* bounce_busy_led(); */ uart_putc('.'); @@ -188,14 +197,17 @@ uint32_t load_rom(uint8_t* filename, uint32_t base_addr) { // for(int j=0; j -#include #include #include "config.h" #include "crc.h" @@ -10,13 +9,18 @@ #include "led.h" #include "sdnative.h" #include "fileops.h" +#include "bits.h" +#include "fpga_spi.h" #define MAX_CARDS 1 // SD/MMC commands #define GO_IDLE_STATE 0 #define SEND_OP_COND 1 +#define ALL_SEND_CID 2 +#define SEND_RELATIVE_ADDR 3 #define SWITCH_FUNC 6 +#define SELECT_CARD 7 #define SEND_IF_COND 8 #define SEND_CSD 9 #define SEND_CID 10 @@ -41,6 +45,7 @@ #define CRC_ON_OFF 59 // SD ACMDs +#define SD_SET_BUS_WIDTH 6 #define SD_STATUS 13 #define SD_SEND_NUM_WR_BLOCKS 22 #define SD_SET_WR_BLK_ERASE_COUNT 23 @@ -62,20 +67,6 @@ #define CARD_SD (1<<0) #define CARD_SDHC (1<<1) -#define SD_CLKREG LPC_GPIO0 -#define SD_CMDREG LPC_GPIO0 -#define SD_DAT0REG LPC_GPIO0 -#define SD_DAT1REG LPC_GPIO1 -#define SD_DAT2REG LPC_GPIO1 -#define SD_DAT3REG LPC_GPIO0 - -#define SD_CLKPIN (7) -#define SD_CMDPIN (9) -#define SD_DAT0PIN (8) -#define SD_DAT1PIN (14) -#define SD_DAT2PIN (15) -#define SD_DAT3PIN (6) - /* 1 DAT3/SS P0.6 2 CMD/DI P0.9 @@ -118,7 +109,7 @@ uint8_t cmd[6]={0,0,0,0,0,0}; uint8_t rsp[17]; uint8_t csd[17]; uint8_t ccs=0; -uint8_t rca1, rca2; +uint32_t rca; enum trans_state { TRANS_NONE = 0, TRANS_READ, TRANS_WRITE }; enum cmd_state { CMD_RSP = 0, CMD_RSPDAT, CMD_DAT }; @@ -204,8 +195,12 @@ static inline void wiggle_fast_pos1(void) { BITBAND(SD_CLKREG->FIOCLR, SD_CLKPIN) = 1; } - - +static inline void wait_busy(void) { + while(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) { + wiggle_fast_neg1(); + } + wiggle_fast_neg(4); +} /* send_command_slow @@ -215,9 +210,8 @@ static inline void wiggle_fast_pos1(void) { int send_command_slow(uint8_t* cmd, uint8_t* rsp){ uint8_t shift, i=6; int rsplen; -// printf("send_command_slow: sending CMD:\n"); + uint8_t cmdno = *cmd & 0x3f; wiggle_slow_pos(5); -// uart_trace(cmd, 0, 6); switch(*cmd & 0x3f) { case 0: rsplen = 0; @@ -254,12 +248,11 @@ int send_command_slow(uint8_t* cmd, uint8_t* rsp){ if(rsplen) { uint16_t timeout=1000; - /* wait for responsebob */ while((BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN)) && --timeout) { wiggle_slow_neg(1); } - // printf("timeout=%d\n", timeout); if(!timeout) { + printf("CMD%d timed out\n", cmdno); return 0; /* no response within timeout */ } @@ -287,11 +280,11 @@ int send_command_slow(uint8_t* cmd, uint8_t* rsp){ */ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){ uint8_t datshift=8, cmdshift, i=6; + uint8_t cmdno = *cmd & 0x3f; int rsplen, dat=0, waitbusy=0, datcnt=512, j=0; static int state=CMD_RSP; -// printf("send_command_fast: sending CMD:\n"); - wiggle_fast_pos(9); -// uart_trace(cmd, 0, 6); + wiggle_fast_pos(9); /* give the card >=8 cycles after last command */ + DBG_SD printf("send_command_fast: sending CMD%d; payload=%02x%02x%02x%02x%02x%02x...\n", cmdno, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5]); switch(*cmd & 0x3f) { case 0: rsplen = 0; @@ -319,32 +312,32 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){ BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 1; while(i--) { + uint8_t data = *cmd; cmdshift = 8; do { cmdshift--; - uint8_t data = *cmd; - *cmd<<=1; if(data&0x80) { BITBAND(SD_CMDREG->FIOSET, SD_CMDPIN) = 1; } else { BITBAND(SD_CMDREG->FIOCLR, SD_CMDPIN) = 1; } + data<<=1; wiggle_fast_pos1(); } while (cmdshift); cmd++; } - wiggle_fast_pos(1); + wiggle_fast_pos1(); BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 0; if(rsplen) { - uint16_t timeout=65535; - /* wait for responsebob */ + uint32_t timeout=2000000; + /* wait for response */ while((BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN)) && --timeout) { wiggle_fast_neg1(); } - // printf("timeout=%d\n", timeout); if(!timeout) { + printf("CMD%d timed out\n", cmdno); return 0; /* no response within timeout */ } @@ -355,7 +348,7 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){ do { if(dat) { if(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) { -// printf("data start\n"); + DBG_SD printf("data start during response\n"); j=datcnt; state=CMD_RSPDAT; break; @@ -365,7 +358,7 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){ cmddata |= (BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN)) << cmdshift; wiggle_fast_neg1(); } while (cmdshift); - if(state==1)break; + if(state==CMD_RSPDAT)break; *rsp=cmddata; cmddata=0; rsp++; @@ -373,7 +366,7 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){ if(state==CMD_RSPDAT) { /* process response+data */ int startbit=1; - printf("processing rsp+data cmdshift=%d i=%d j=%d\n", cmdshift, i, j); + DBG_SD printf("processing rsp+data cmdshift=%d i=%d j=%d\n", cmdshift, i, j); datshift=8; while(1) { cmdshift--; @@ -385,16 +378,14 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){ rsp++; i--; if(!i) { - printf("response end\n"); + DBG_SD printf("response end\n"); if(j) state=CMD_DAT; /* response over, remaining data */ break; } } if(!startbit) { datshift-=4; - datdata |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) - |((SD_DAT1REG->FIOPIN >> 13) & 0x6) - |((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3)) << datshift; + datdata |= SD_DAT << datshift; if(!datshift) { datshift=8; *buf=datdata; @@ -413,25 +404,26 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){ state=CMD_DAT; j=datcnt; datshift=8; -// printf("response over, waiting for data...\n"); + DBG_SD printf("response over, waiting for data...\n"); while((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) && --timeout) { wiggle_fast_neg1(); } wiggle_fast_neg1(); /* eat the start bit */ + if(sd_offload) { + fpga_sd2ram(); + state=CMD_RSP; + return rsplen; + } } if(state==CMD_DAT) { /* transfer rest of data */ -// printf("remaining data: %d\n", j); + DBG_SD printf("remaining data: %d\n", j); if(datshift==8) { while(1) { - datdata |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) - |((SD_DAT1REG->FIOPIN >> 13) & 0x6) - |((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3)) << 4; + datdata |= SD_DAT << 4; wiggle_fast_neg1(); - datdata |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) - |((SD_DAT1REG->FIOPIN >> 13) & 0x6) - |((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3)); + datdata |= SD_DAT; wiggle_fast_neg1(); *buf=datdata; @@ -444,9 +436,7 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){ while(1) { datshift-=4; - datdata |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) - |((SD_DAT1REG->FIOPIN >> 13) & 0x6) - |((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3)) << datshift; + datdata |= SD_DAT << datshift; if(!datshift) { datshift=8; *buf=datdata; @@ -463,17 +453,18 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){ if(dat) wiggle_fast_neg(17); if(waitbusy) { - while(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) { - wiggle_fast_neg1(); - } + DBG_SD printf("waitbusy after send_cmd\n"); + wait_busy(); } state=CMD_RSP; } + rsp-=rsplen; + DBG_SD printf("send_command_fast: CMD%d response: %02x%02x%02x%02x%02x%02x\n", cmdno, rsp[0], rsp[1], rsp[2], rsp[3], rsp[4], rsp[5]); return rsplen; } -void make_crc7(uint8_t* cmd) { +static inline void make_crc7(uint8_t* cmd) { cmd[5]=crc7update(0, cmd[0]); cmd[5]=crc7update(cmd[5], cmd[1]); cmd[5]=crc7update(cmd[5], cmd[2]); @@ -482,65 +473,85 @@ void make_crc7(uint8_t* cmd) { cmd[5]=(cmd[5] << 1) | 1; } +int cmd_slow(uint8_t cmd, uint32_t param, uint8_t crc, uint8_t* dat, uint8_t* rsp) { + uint8_t cmdbuf[6]; + cmdbuf[0] = 0x40 | cmd; + cmdbuf[1] = param >> 24; + cmdbuf[2] = param >> 16; + cmdbuf[3] = param >> 8; + cmdbuf[4] = param; + if(!crc) { + make_crc7(cmdbuf); + } else { + cmdbuf[5] = crc; + } + return send_command_slow(cmdbuf, rsp); +} + +int acmd_slow(uint8_t cmd, uint32_t param, uint8_t crc, uint8_t* dat, uint8_t* rsp) { + if(!(cmd_slow(APP_CMD, rca, 0, NULL, rsp))) { + return 0; + } + return cmd_slow(cmd, param, crc, dat, rsp); +} + +int cmd_fast(uint8_t cmd, uint32_t param, uint8_t crc, uint8_t* dat, uint8_t* rsp) { + uint8_t cmdbuf[6]; + cmdbuf[0] = 0x40 | cmd; + cmdbuf[1] = param >> 24; + cmdbuf[2] = param >> 16; + cmdbuf[3] = param >> 8; + cmdbuf[4] = param; + if(!crc) { + make_crc7(cmdbuf); + } else { + cmdbuf[5] = crc; + } + return send_command_fast(cmdbuf, rsp, dat); +} + +int acmd_fast(uint8_t cmd, uint32_t param, uint8_t crc, uint8_t* dat, uint8_t* rsp) { + if(!(cmd_fast(APP_CMD, rca, 0, NULL, rsp))) { + return 0; + } + return cmd_fast(cmd, param, crc, dat, rsp); +} + void stream_datablock(uint8_t *buf) { // uint8_t datshift=8; int j=512; uint8_t datdata=0; - uint16_t timeout=65535; + uint32_t timeout=1000000; while((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) && --timeout) { wiggle_fast_neg1(); } wiggle_fast_neg1(); /* eat the start bit */ + if(sd_offload) { + fpga_sd2ram(); + } else { + while(1) { + datdata = SD_DAT << 4; + wiggle_fast_neg1(); + + datdata |= SD_DAT; + wiggle_fast_neg1(); - while(1) { -/* - datshift-=4; - datdata |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) - |((SD_DAT1REG->FIOPIN >> 13) & 0x6) - |((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3)) << datshift; - if(!datshift) { - datshift=8; *buf=datdata; - datdata=0; buf++; j--; if(!j) break; } -*/ - datdata |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) - |((SD_DAT1REG->FIOPIN >> 13) & 0x6) - |((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3)) << 4; - wiggle_fast_neg1(); - - datdata |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) - |((SD_DAT1REG->FIOPIN >> 13) & 0x6) - |((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3)); - - wiggle_fast_neg1(); - - *buf=datdata; - datdata=0; - buf++; - j--; - if(!j) break; - } - /* eat the crc for now */ wiggle_fast_neg(17); + } } void send_datablock(uint8_t *buf) { uint16_t crc0=0, crc1=0, crc2=0, crc3=0, cnt=512; uint8_t dat0=0, dat1=0, dat2=0, dat3=0, crcshift, datshift; -//uart_trace(buf, 0, 512); - wiggle_fast_pos(1); -// printf("send_datablock: wait for card\n"); - /* wait - card might be busy */ - while(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) { - wiggle_fast_neg(1); - printf("."); - } + + wiggle_fast_pos1(); BITBAND(SD_DAT0REG->FIODIR, SD_DAT0PIN) = 1; BITBAND(SD_DAT1REG->FIODIR, SD_DAT1PIN) = 1; BITBAND(SD_DAT2REG->FIODIR, SD_DAT2PIN) = 1; @@ -551,7 +562,7 @@ void send_datablock(uint8_t *buf) { BITBAND(SD_DAT2REG->FIOCLR, SD_DAT2PIN) = 1; BITBAND(SD_DAT3REG->FIOCLR, SD_DAT3PIN) = 1; - wiggle_fast_pos(1); /* send start bit to card */ + wiggle_fast_pos1(); /* send start bit to card */ crcshift=8; while(cnt--) { datshift=8; @@ -577,7 +588,7 @@ void send_datablock(uint8_t *buf) { } else { BITBAND(SD_DAT0REG->FIOCLR, SD_DAT0PIN) = 1; } - wiggle_fast_pos(1); + wiggle_fast_pos1(); } while (datshift); crcshift-=2; @@ -603,27 +614,27 @@ void send_datablock(uint8_t *buf) { datshift=16; do { datshift--; - if((crc0 >> datshift)&1) { + if((crc0 >> datshift) & 1) { BITBAND(SD_DAT0REG->FIOSET, SD_DAT0PIN) = 1; } else { BITBAND(SD_DAT0REG->FIOCLR, SD_DAT0PIN) = 1; } - if((crc1 >> datshift)&1) { + if((crc1 >> datshift) & 1) { BITBAND(SD_DAT1REG->FIOSET, SD_DAT1PIN) = 1; } else { BITBAND(SD_DAT1REG->FIOCLR, SD_DAT1PIN) = 1; } - if((crc2 >> datshift)&1) { + if((crc2 >> datshift) & 1) { BITBAND(SD_DAT2REG->FIOSET, SD_DAT2PIN) = 1; } else { BITBAND(SD_DAT2REG->FIOCLR, SD_DAT2PIN) = 1; } - if((crc3 >> datshift)&1) { + if((crc3 >> datshift) & 1) { BITBAND(SD_DAT3REG->FIOSET, SD_DAT3PIN) = 1; } else { BITBAND(SD_DAT3REG->FIOCLR, SD_DAT3PIN) = 1; } - wiggle_fast_pos(1); + wiggle_fast_pos1(); } while(datshift); /* send end bit */ BITBAND(SD_DAT0REG->FIOSET, SD_DAT0PIN) = 1; @@ -631,88 +642,73 @@ void send_datablock(uint8_t *buf) { BITBAND(SD_DAT2REG->FIOSET, SD_DAT2PIN) = 1; BITBAND(SD_DAT3REG->FIOSET, SD_DAT3PIN) = 1; - wiggle_fast_pos(1); + wiggle_fast_pos1(); BITBAND(SD_DAT0REG->FIODIR, SD_DAT0PIN) = 0; BITBAND(SD_DAT1REG->FIODIR, SD_DAT1PIN) = 0; BITBAND(SD_DAT2REG->FIODIR, SD_DAT2PIN) = 0; BITBAND(SD_DAT3REG->FIODIR, SD_DAT3PIN) = 0; - wiggle_fast_neg(4); + wiggle_fast_neg(3); dat0=0; - datshift=3; + datshift=4; do { datshift--; dat0 |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) << datshift); - wiggle_fast_neg(1); + wiggle_fast_neg1(); } while (datshift); - - if(dat0!=2) { + DBG_SD printf("crc %02x\n", dat0); + if((dat0 & 7) != 2) { printf("crc error! %02x\n", dat0); while(1); } - wiggle_fast_neg(1); - while(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) { - wiggle_fast_neg(1); - } + if(dat0 & 8) { + printf("missing start bit in CRC status response...\n"); + } + wiggle_fast_neg(2); + wait_busy(); } void read_block(uint32_t address, uint8_t *buf) { if(during_blocktrans == TRANS_READ && (last_block == address-1)) { +//uart_putc('r'); stream_datablock(buf); last_block=address; } else { if(during_blocktrans) { +//printf("nonseq read (%lx -> %lx), restarting transmission\n", last_block, address); /* send STOP_TRANSMISSION to end an open READ/WRITE_MULTIPLE_BLOCK */ - cmd[0]=0x40+STOP_TRANSMISSION; - cmd[1]=0; - cmd[2]=0; - cmd[3]=0; - cmd[4]=0; - cmd[5]=0x61; - send_command_fast(cmd, rsp, NULL); + cmd_fast(STOP_TRANSMISSION, 0, 0x61, NULL, rsp); } last_block=address; - if(!ccs) address <<= 9; - cmd[0]=0x40+READ_MULTIPLE_BLOCK; - cmd[1]=address>>24; - cmd[2]=address>>16; - cmd[3]=address>>8; - cmd[4]=address; - make_crc7(cmd); - send_command_fast(cmd, rsp, buf); -// uart_trace(cmd, 0, 6); -// uart_trace(rsp, 0, rsplen); + if(!ccs) { + address <<= 9; + } + cmd_fast(READ_MULTIPLE_BLOCK, address, 0, buf, rsp); during_blocktrans = TRANS_READ; } -// uart_trace(buf, 0, 512); } void write_block(uint32_t address, uint8_t* buf) { if(during_blocktrans == TRANS_WRITE && (last_block == address-1)) { + wait_busy(); send_datablock(buf); last_block=address; } else { if(during_blocktrans) { /* send STOP_TRANSMISSION to end an open READ/WRITE_MULTIPLE_BLOCK */ - cmd[0]=0x40+STOP_TRANSMISSION; - cmd[1]=0; - cmd[2]=0; - cmd[3]=0; - cmd[4]=0; - cmd[5]=0x61; - send_command_fast(cmd, rsp, NULL); + cmd_fast(STOP_TRANSMISSION, 0, 0x61, NULL, rsp); } + wait_busy(); last_block=address; - if(!ccs) address <<= 9; - cmd[0]=0x40+WRITE_MULTIPLE_BLOCK; - cmd[1]=address>>24; - cmd[2]=address>>16; - cmd[3]=address>>8; - cmd[4]=address; - make_crc7(cmd); - send_command_fast(cmd, rsp, NULL); /* only send cmd & get response */ + if(!ccs) { + address <<= 9; + } + /* only send cmd & get response */ + cmd_fast(WRITE_MULTIPLE_BLOCK, address, 0, NULL, rsp); + DBG_SD printf("write_block: CMD25 response = %02x%02x%02x%02x%02x%02x\n", rsp[0], rsp[1], rsp[2], rsp[3], rsp[4], rsp[5]); + wiggle_fast_pos(8); send_datablock(buf); during_blocktrans = TRANS_WRITE; } @@ -737,200 +733,74 @@ DRESULT disk_read(BYTE drv, BYTE *buffer, DWORD sector, BYTE count) __attribute_ DRESULT sdn_initialize(BYTE drv) { - uint8_t cmd[6]={0,0,0,0,0,0}; /* command */ uint8_t rsp[17]; /* space for response */ int rsplen; uint8_t hcs=0; - if(drv>=MAX_CARDS) + rca = 0; + if(drv>=MAX_CARDS) { return STA_NOINIT|STA_NODISK; + } + if(sdn_status(drv) & STA_NODISK) { + return STA_NOINIT|STA_NODISK; + } /* if the card is sending data from before a reset we try to deselect it prior to initialization */ for(rsplen=0; rsplen<2042; rsplen++) { if(!(BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN))) { printf("card seems to be sending data, attempting deselect\n"); - cmd[0]=0x40+7; - cmd[1]=0; - cmd[2]=0; - cmd[3]=0; - cmd[4]=0; - make_crc7(cmd); - if(send_command_slow(cmd, rsp)) { - printf("card was sending data, CMD7 succeeded\n"); - } else { - printf("CMD7 deselect no response! D:\n"); - } + cmd_slow(SELECT_CARD, 0, 0, NULL, rsp); } wiggle_slow_neg(1); } - cmd[0]=0x40+GO_IDLE_STATE; - cmd[5]=0x95; printf("sd_init start\n"); - if((rsplen=send_command_slow(cmd, rsp))) { -// printf("CMD0 response?!:\n"); -// uart_trace(rsp, 0, rsplen); - } + cmd_slow(GO_IDLE_STATE, 0, 0x95, NULL, rsp); - wiggle_slow_pos(1000); - cmd[0]=0x40+SEND_IF_COND; - cmd[3]=0x01; - cmd[4]=0xaa; - cmd[5]=0x87; - if((rsplen=send_command_slow(cmd, rsp))) { -// uart_trace(cmd, 0, 6); -// printf("CMD8 response:\n"); -// uart_trace(rsp, 0, rsplen); + if((rsplen=cmd_slow(SEND_IF_COND, 0x000001aa, 0x87, NULL, rsp))) { + DBG_SD printf("CMD8 response:\n"); + DBG_SD uart_trace(rsp, 0, rsplen); hcs=1; } while(1) { - cmd[0]=0x40+APP_CMD; - cmd[1]=0; - cmd[2]=0; - cmd[3]=0; - cmd[4]=0; - cmd[5]=0x65; - - if((rsplen=send_command_slow(cmd, rsp))) { -// printf("CMD55 response:\n"); -// uart_trace(rsp, 0, rsplen); - } else { - printf("CMD55 no response!\n"); - } - - cmd[0]=0x40+41; - cmd[1]=hcs<<6; - cmd[2]=0xfc; /* 2.7-3.6V */ - cmd[3]=0x00; - cmd[4]=0x00; - cmd[5]=hcs ? 0x53 : 0xc1; -// printf("send ACMD41 hcs=%d\n", hcs); - if((rsplen=send_command_slow(cmd, rsp))) { -// printf("ACMD41 response:\n"); -// uart_trace(rsp, 0, rsplen); -// printf("busy=%d\n ccs=%d\n", rsp[1]>>7, (rsp[1]>>6)&1); - } else { + if(!(acmd_slow(SD_SEND_OP_COND, (hcs << 30) | 0xfc0000, 0, NULL, rsp))) { printf("ACMD41 no response!\n"); } if(rsp[1]&0x80) break; } - ccs = (rsp[1]>>6) & 1; /* SDHC */ + ccs = (rsp[1]>>6) & 1; /* SDHC/XC */ - cmd[0]=0x40+2; - cmd[1]=0; - cmd[2]=0; - cmd[3]=0; - cmd[4]=0; - cmd[5]=0x4d; - - if((rsplen=send_command_slow(cmd, rsp))) { -// printf("CMD2 response:\n"); -// uart_trace(rsp, 0, rsplen); - } else { - printf("CMD2 no response!\n"); - } - - cmd[0]=0x40+3; - cmd[1]=0; - cmd[2]=0; - cmd[3]=0; - cmd[4]=0; - cmd[5]=0x21; - - if((rsplen=send_command_slow(cmd, rsp))) { -// printf("CMD3 response:\n"); -// uart_trace(rsp, 0, rsplen); - rca1=rsp[1]; - rca2=rsp[2]; -// printf("RCA: %02x%02x\n", rca1, rca2); + cmd_slow(ALL_SEND_CID, 0, 0x4d, NULL, rsp); + if(cmd_slow(SEND_RELATIVE_ADDR, 0, 0x21, NULL, rsp)) { + rca=(rsp[1]<<24) | (rsp[2]<<16); + printf("RCA: %04lx\n", rca>>16); } else { printf("CMD3 no response!\n"); - rca1=0; - rca2=0; + rca=0; } - cmd[0]=0x40+9; - cmd[1]=rca1; - cmd[2]=rca2; - cmd[3]=0; - cmd[4]=0; - make_crc7(cmd); - /* record CSD for getinfo */ - if((rsplen=send_command_slow(cmd, csd))) { -// printf("CMD9 response:\n"); -// uart_trace(rsp, 0, rsplen); - } else { - printf("CMD9 no response!\n"); - } - - cmd[0]=0x40+7; - cmd[1]=rca1; - cmd[2]=rca2; - cmd[3]=0; - cmd[4]=0; - make_crc7(cmd); + cmd_slow(SEND_CSD, rca, 0, NULL, rsp); /* select the card */ - if((rsplen=send_command_slow(cmd, rsp))) { -// printf("CMD7 response:\n"); -// uart_trace(rsp, 0, rsplen); + if(cmd_slow(SELECT_CARD, rca, 0, NULL, rsp)) { printf("card selected!\n"); } else { printf("CMD7 no response!\n"); } - cmd[0]=0x40+13; - cmd[1]=rca1; - cmd[2]=rca2; - cmd[3]=0; - cmd[4]=0; - make_crc7(cmd); - /* get card status */ - if((rsplen=send_command_fast(cmd, rsp, NULL))) { -// printf("CMD13 response:\n"); -// uart_trace(rsp, 0, rsplen); - } else { - printf("CMD13 no response!\n"); - } + cmd_slow(SEND_STATUS, rca, 0, NULL, rsp); /* set bus width */ - cmd[0]=0x40+55; - cmd[1]=rca1; - cmd[2]=rca2; - cmd[3]=0; - cmd[4]=0; - make_crc7(cmd); + acmd_slow(SD_SET_BUS_WIDTH, 0x2, 0, NULL, rsp); - if((rsplen=send_command_slow(cmd, rsp))) { -// printf("CMD55 response:\n"); -// uart_trace(rsp, 0, rsplen); - } else { - printf("CMD55 no response!\n"); - } + /* set block length */ + cmd_slow(SET_BLOCKLEN, 0x200, 0, NULL, rsp); - cmd[0]=0x40+6; - cmd[1]=0; - cmd[2]=0; - cmd[3]=0; - cmd[4]=2; - make_crc7(cmd); - if((rsplen=send_command_slow(cmd, rsp))) { -// printf("CMD55 response:\n"); -// uart_trace(rsp, 0, rsplen); - } else { - printf("ACMD6 no response!\n"); - } - -/* int i; - printf("start 4MB streaming test\n"); - for(i=0; i<8192; i++) { - read_block(i, file_buf); - } - printf("end 4MB streaming test\n");*/ printf("SD init complete. SDHC/XC=%d\n", ccs); - + disk_state = DISK_OK; + during_blocktrans = TRANS_NONE; return sdn_status(drv); } @@ -955,28 +825,30 @@ void disk_init(void) __attribute__ ((weak, alias("sdn_init"))); DSTATUS sdn_status(BYTE drv) { - if (SDCARD_DETECT) - if (SDCARD_WP) + if (SDCARD_DETECT) { + if (SDCARD_WP) { return STA_PROTECT; - else + } else { return RES_OK; - else + } + } else { return STA_NOINIT|STA_NODISK; + } } DSTATUS disk_status(BYTE drv) __attribute__ ((weak, alias("sdn_status"))); DRESULT sdn_getinfo(BYTE drv, BYTE page, void *buffer) { uint32_t capacity; - if (drv >= MAX_CARDS) + if (drv >= MAX_CARDS) { return RES_NOTRDY; - - if (sdn_status(drv) & STA_NODISK) + } + if (sdn_status(drv) & STA_NODISK) { return RES_NOTRDY; - - if (page != 0) + } + if (page != 0) { return RES_ERROR; - + } if (ccs) { /* Special CSD for SDHC cards */ capacity = (1 + getbits(csd,127-69+8,22)) * 1024; @@ -993,6 +865,8 @@ DRESULT sdn_getinfo(BYTE drv, BYTE page, void *buffer) { di->disktype = DISK_TYPE_SD; di->sectorsize = 2; di->sectorcount = capacity; + + printf("card capacity: %lu sectors\n", capacity); return RES_OK; } DRESULT disk_getinfo(BYTE drv, BYTE page, void *buffer) __attribute__ ((weak, alias("sdn_getinfo"))); @@ -1003,9 +877,9 @@ DRESULT sdn_write(BYTE drv, const BYTE *buffer, DWORD sector, BYTE count) { if(drv >= MAX_CARDS) { return RES_NOTRDY; } - if (sdn_status(drv) & STA_NODISK) + if (sdn_status(drv) & STA_NODISK) { return RES_NOTRDY; - + } for(sec=0; secFIOCLR, SNES_RESET_BIT) = 1; @@ -135,5 +137,5 @@ uint8_t menu_main_loop() { void get_selected_name(uint8_t* fn) { uint32_t addr = sram_readlong(SRAM_PARAM_ADDR); printf("fd addr=%lx\n", addr); - sram_readblock(fn, addr+10+SRAM_MENU_ADDR, 256); + sram_readblock(fn, addr + 7 + SRAM_MENU_ADDR, 256); } diff --git a/src/sort.c b/src/sort.c index f1de3d7..377a077 100644 --- a/src/sort.c +++ b/src/sort.c @@ -62,13 +62,15 @@ int sort_cmp_elem(const void* elem1, const void* elem2) { /* get truncated string from database */ void sort_getstring_for_dirent(char *ptr, uint32_t addr) { -stat_getstring++; + uint8_t leaf_offset; if(addr & 0x80000000) { - /* is directory link, name offset 6 */ - sram_readblock(ptr, addr+0x6+SRAM_MENU_ADDR, 20); + /* is directory link, name offset 4 */ + leaf_offset = sram_readbyte(addr + 4 + SRAM_MENU_ADDR); + sram_readblock(ptr, addr + 5 + leaf_offset + SRAM_MENU_ADDR, 20); } else { - /* is file link, name offset 10 */ - sram_readblock(ptr, addr+10+SRAM_MENU_ADDR, 20); + /* is file link, name offset 6 */ + leaf_offset = sram_readbyte(addr + 6 + SRAM_MENU_ADDR); + sram_readblock(ptr, addr + 7 + leaf_offset + SRAM_MENU_ADDR, 20); } ptr[20]=0; }