SD acceleration, display file size in menu (fw side)
This commit is contained in:
parent
f4b88ca792
commit
4bc455f12b
@ -11,4 +11,11 @@
|
|||||||
(bit)*4 + 0x02000000 + ((unsigned long)&(addr) & 0xfe000000) \
|
(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
|
#endif
|
||||||
|
|||||||
20
src/config.h
20
src/config.h
@ -1,6 +1,8 @@
|
|||||||
#ifndef _CONFIG_H
|
#ifndef _CONFIG_H
|
||||||
#define _CONFIG_H
|
#define _CONFIG_H
|
||||||
|
|
||||||
|
// #define DEBUG_SD
|
||||||
|
|
||||||
#define VER "0.0.1(NSFW)"
|
#define VER "0.0.1(NSFW)"
|
||||||
#define IN_AHBRAM __attribute__ ((section(".ahbram")))
|
#define IN_AHBRAM __attribute__ ((section(".ahbram")))
|
||||||
|
|
||||||
@ -71,4 +73,22 @@
|
|||||||
// 1: 3
|
// 1: 3
|
||||||
#define SSP_DMACH LPC_GPDMACH0
|
#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
|
#endif
|
||||||
|
|||||||
@ -62,6 +62,7 @@ void disk_init(void);
|
|||||||
/* Will be set to DISK_ERROR if any access on the card fails */
|
/* Will be set to DISK_ERROR if any access on the card fails */
|
||||||
enum diskstates { DISK_CHANGED = 0, DISK_REMOVED, DISK_OK, DISK_ERROR };
|
enum diskstates { DISK_CHANGED = 0, DISK_REMOVED, DISK_OK, DISK_ERROR };
|
||||||
|
|
||||||
|
extern int sd_offload, ff_sd_offload;
|
||||||
extern volatile enum diskstates disk_state;
|
extern volatile enum diskstates disk_state;
|
||||||
|
|
||||||
/* Disk type - part of the external API except for ATA2! */
|
/* Disk type - part of the external API except for ATA2! */
|
||||||
|
|||||||
6
src/ff.c
6
src/ff.c
@ -2175,8 +2175,12 @@ FRESULT f_read (
|
|||||||
if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */
|
if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */
|
||||||
cc = fp->fs->csize - csect;
|
cc = fp->fs->csize - csect;
|
||||||
/* XXX OFFLOAD GOES HERE */
|
/* XXX OFFLOAD GOES HERE */
|
||||||
|
if (ff_sd_offload) {
|
||||||
|
sd_offload = 1;
|
||||||
|
}
|
||||||
if (disk_read(fp->fs->drv, rbuff, sect, (BYTE)cc) != RES_OK)
|
if (disk_read(fp->fs->drv, rbuff, sect, (BYTE)cc) != RES_OK)
|
||||||
ABORT(fp->fs, FR_DISK_ERR);
|
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_READONLY && _FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */
|
||||||
#if _FS_TINY
|
#if _FS_TINY
|
||||||
if (fp->fs->wflag && fp->fs->winsect - sect < cc)
|
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 */
|
mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
ff_sd_offload = 0;
|
||||||
LEAVE_FF(fp->fs, FR_OK);
|
LEAVE_FF(fp->fs, FR_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -48,7 +48,7 @@
|
|||||||
/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
|
/* 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. */
|
/* To enable fast seek feature, set _USE_FASTSEEK to 1. */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -61,6 +61,9 @@ UINT file_read() {
|
|||||||
UINT file_write() {
|
UINT file_write() {
|
||||||
UINT bytes_written;
|
UINT bytes_written;
|
||||||
file_res = f_write(&file_handle, file_buf, sizeof(file_buf), &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;
|
return bytes_written;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -70,7 +70,10 @@ uint32_t scan_dir(char* path, char mkdb, uint32_t this_dir_tgt) {
|
|||||||
uint16_t numentries;
|
uint16_t numentries;
|
||||||
uint32_t dirsize;
|
uint32_t dirsize;
|
||||||
uint8_t pass = 0;
|
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;
|
dir_tgt = this_dir_tgt;
|
||||||
if(depth==0) {
|
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 */
|
/* write element pointer to current dir structure */
|
||||||
/* printf("d=%d Saving %lX to Address %lX [file]\n", depth, db_tgt, dir_tgt); */
|
/* 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);
|
printf("switch! old=%lx ", db_tgt);
|
||||||
db_tgt &= 0xffff0000;
|
db_tgt &= 0xffff0000;
|
||||||
db_tgt += 0x00010000;
|
db_tgt += 0x00010000;
|
||||||
@ -198,7 +201,14 @@ uint32_t scan_dir(char* path, char mkdb, uint32_t this_dir_tgt) {
|
|||||||
- file name
|
- file name
|
||||||
- file size */
|
- file size */
|
||||||
/* sram_writeblock((uint8_t*)&romprops, db_tgt, sizeof(romprops)); */
|
/* 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_writeblock(buf, db_tgt, sizeof(buf)-1);
|
||||||
sram_writebyte(len+1, 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);
|
sram_writeblock(path, db_tgt + sizeof(len) + sizeof(buf)-1, pathlen + 1);
|
||||||
|
|||||||
17
src/fpga.c
17
src/fpga.c
@ -97,11 +97,22 @@ void fpga_pgm(uint8_t* filename) {
|
|||||||
int MAXRETRIES = 10;
|
int MAXRETRIES = 10;
|
||||||
int retries = MAXRETRIES;
|
int retries = MAXRETRIES;
|
||||||
uint8_t data;
|
uint8_t data;
|
||||||
|
int i;
|
||||||
|
tick_t timeout;
|
||||||
|
// UINT bytes_read;
|
||||||
|
// uint16_t j;
|
||||||
do {
|
do {
|
||||||
|
i=0;
|
||||||
|
timeout = getticks() + 100;
|
||||||
fpga_set_prog_b(0);
|
fpga_set_prog_b(0);
|
||||||
uart_putc('P');
|
uart_putc('P');
|
||||||
fpga_set_prog_b(1);
|
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));
|
LPC_GPIO2->FIOMASK1 = ~(BV(0));
|
||||||
uart_putc('p');
|
uart_putc('p');
|
||||||
|
|
||||||
@ -114,13 +125,17 @@ void fpga_pgm(uint8_t* filename) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uart_putc('C');
|
uart_putc('C');
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
data = rle_file_getc();
|
data = rle_file_getc();
|
||||||
|
i++;
|
||||||
if (file_status || file_res) break; /* error or eof */
|
if (file_status || file_res) break; /* error or eof */
|
||||||
FPGA_SEND_BYTE_SERIAL(data);
|
FPGA_SEND_BYTE_SERIAL(data);
|
||||||
}
|
}
|
||||||
uart_putc('c');
|
uart_putc('c');
|
||||||
file_close();
|
file_close();
|
||||||
|
printf("fpga_pgm: %d bytes programmed\n", i);
|
||||||
|
delay_ms(1);
|
||||||
} while (!fpga_get_done() && retries--);
|
} while (!fpga_get_done() && retries--);
|
||||||
if(!fpga_get_done()) {
|
if(!fpga_get_done()) {
|
||||||
printf("FPGA failed to configure after %d tries.\n", MAXRETRIES);
|
printf("FPGA failed to configure after %d tries.\n", MAXRETRIES);
|
||||||
|
|||||||
@ -35,7 +35,6 @@ void fpga_set_cclk(uint8_t val);
|
|||||||
int fpga_get_initb(void);
|
int fpga_get_initb(void);
|
||||||
|
|
||||||
void fpga_init(void);
|
void fpga_init(void);
|
||||||
uint8_t fpga_test(void);
|
|
||||||
void fpga_postinit(void);
|
void fpga_postinit(void);
|
||||||
void fpga_pgm(uint8_t* filename);
|
void fpga_pgm(uint8_t* filename);
|
||||||
|
|
||||||
|
|||||||
@ -29,16 +29,19 @@
|
|||||||
|
|
||||||
cmd param function
|
cmd param function
|
||||||
=============================================
|
=============================================
|
||||||
00 bb[hh[ll]] set address to 0xbb0000, 0xbbhh00, or 0xbbhhll
|
00 bbhhll set address to 0xbbhhll
|
||||||
10 bbhhll set SNES input address mask to 0xbbhhll
|
01 bbhhll set SNES input address mask to 0xbbhhll
|
||||||
20 bbhhll set SRAM address mask to 0xbbhhll
|
02 bbhhll set SRAM address mask to 0xbbhhll
|
||||||
3m - set mapper to m
|
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
|
80 - read with increment
|
||||||
81 - read w/o increment
|
81 - read w/o increment
|
||||||
90 {xx}* write xx with increment
|
90 {xx}* write xx with increment
|
||||||
91 {xx}* write xx w/o 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)
|
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) {
|
void set_saveram_mask(uint32_t mask) {
|
||||||
FPGA_SELECT();
|
FPGA_SELECT();
|
||||||
FPGA_TX_BYTE(0x20);
|
FPGA_TX_BYTE(0x02);
|
||||||
FPGA_TX_BYTE((mask>>16)&0xff);
|
FPGA_TX_BYTE((mask>>16)&0xff);
|
||||||
FPGA_TX_BYTE((mask>>8)&0xff);
|
FPGA_TX_BYTE((mask>>8)&0xff);
|
||||||
FPGA_TX_BYTE((mask)&0xff);
|
FPGA_TX_BYTE((mask)&0xff);
|
||||||
@ -75,7 +78,7 @@ void set_saveram_mask(uint32_t mask) {
|
|||||||
|
|
||||||
void set_rom_mask(uint32_t mask) {
|
void set_rom_mask(uint32_t mask) {
|
||||||
FPGA_SELECT();
|
FPGA_SELECT();
|
||||||
FPGA_TX_BYTE(0x10);
|
FPGA_TX_BYTE(0x01);
|
||||||
FPGA_TX_BYTE((mask>>16)&0xff);
|
FPGA_TX_BYTE((mask>>16)&0xff);
|
||||||
FPGA_TX_BYTE((mask>>8)&0xff);
|
FPGA_TX_BYTE((mask>>8)&0xff);
|
||||||
FPGA_TX_BYTE((mask)&0xff);
|
FPGA_TX_BYTE((mask)&0xff);
|
||||||
@ -97,3 +100,25 @@ uint8_t fpga_test() {
|
|||||||
return result;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@ -47,7 +47,8 @@
|
|||||||
#define FPGA_SPI_SLOW() spi_set_speed(SPI_SPEED_FPGA_SLOW)
|
#define FPGA_SPI_SLOW() spi_set_speed(SPI_SPEED_FPGA_SLOW)
|
||||||
|
|
||||||
void fpga_spi_init(void);
|
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_fpga(void);
|
||||||
void spi_sd(void);
|
void spi_sd(void);
|
||||||
void spi_none(void);
|
void spi_none(void);
|
||||||
@ -55,5 +56,6 @@ void set_mcu_addr(uint32_t);
|
|||||||
void set_saveram_mask(uint32_t);
|
void set_saveram_mask(uint32_t);
|
||||||
void set_rom_mask(uint32_t);
|
void set_rom_mask(uint32_t);
|
||||||
void set_mapper(uint8_t val);
|
void set_mapper(uint8_t val);
|
||||||
|
void fpga_sd2ram(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
39
src/main.c
39
src/main.c
@ -23,15 +23,19 @@
|
|||||||
#include "cli.h"
|
#include "cli.h"
|
||||||
#include "sdnative.h"
|
#include "sdnative.h"
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
|
#include "smc.h"
|
||||||
|
|
||||||
#define EMC0TOGGLE (3<<4)
|
#define EMC0TOGGLE (3<<4)
|
||||||
#define MR0R (1<<1)
|
#define MR0R (1<<1)
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
int sd_offload = 0, ff_sd_offload = 0;
|
||||||
/* FIXME HACK */
|
/* FIXME HACK */
|
||||||
volatile enum diskstates disk_state;
|
volatile enum diskstates disk_state;
|
||||||
extern volatile tick_t ticks;
|
extern volatile tick_t ticks;
|
||||||
|
extern snes_romprops_t romprops;
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
LPC_GPIO2->FIODIR = BV(0) | BV(1) | BV(2);
|
LPC_GPIO2->FIODIR = BV(0) | BV(1) | BV(2);
|
||||||
LPC_GPIO1->FIODIR = 0;
|
LPC_GPIO1->FIODIR = 0;
|
||||||
@ -58,25 +62,12 @@ int main(void) {
|
|||||||
/* do this last because the peripheral init()s change PCLK dividers */
|
/* do this last because the peripheral init()s change PCLK dividers */
|
||||||
clock_init();
|
clock_init();
|
||||||
|
|
||||||
// sd_init();
|
|
||||||
sdn_init();
|
sdn_init();
|
||||||
// while(1);
|
|
||||||
fpga_spi_init();
|
fpga_spi_init();
|
||||||
delay_ms(10);
|
|
||||||
printf("\n\nsd2snes mk.2\n============\nfw ver.: " VER "\ncpu clock: %d Hz\n", CONFIG_CPU_FREQUENCY);
|
printf("\n\nsd2snes mk.2\n============\nfw ver.: " VER "\ncpu clock: %d Hz\n", CONFIG_CPU_FREQUENCY);
|
||||||
file_init();
|
file_init();
|
||||||
cic_init(1);
|
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) */
|
/* setup timer (fpga clk) */
|
||||||
LPC_TIM3->CTCR=0;
|
LPC_TIM3->CTCR=0;
|
||||||
LPC_TIM3->EMR=EMC0TOGGLE;
|
LPC_TIM3->EMR=EMC0TOGGLE;
|
||||||
@ -103,16 +94,6 @@ restart:
|
|||||||
uint32_t mem_dir_id = sram_readlong(SRAM_DIRID);
|
uint32_t mem_dir_id = sram_readlong(SRAM_DIRID);
|
||||||
uint32_t mem_magic = sram_readlong(SRAM_SCRATCHPAD);
|
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);
|
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 */
|
mem_magic=0x12938712; /* always rescan card for now */
|
||||||
if((mem_magic != 0x12345678) || (mem_dir_id != saved_dir_id)) {
|
if((mem_magic != 0x12345678) || (mem_dir_id != saved_dir_id)) {
|
||||||
@ -172,11 +153,12 @@ restart:
|
|||||||
printf("test sram\n");
|
printf("test sram\n");
|
||||||
while(!sram_reliable());
|
while(!sram_reliable());
|
||||||
printf("ok\n");
|
printf("ok\n");
|
||||||
sram_hexdump(SRAM_DB_ADDR, 0x200);
|
//sram_hexdump(SRAM_DB_ADDR, 0x200);
|
||||||
|
//sram_hexdump(SRAM_MENU_ADDR, 0x400);
|
||||||
|
|
||||||
while(!cmd) {
|
while(!cmd) {
|
||||||
cmd=menu_main_loop();
|
cmd=menu_main_loop();
|
||||||
printf("derp %d\n", cmd);
|
printf("cmd: %d\n", cmd);
|
||||||
sleep_ms(50);
|
sleep_ms(50);
|
||||||
uart_putc('-');
|
uart_putc('-');
|
||||||
switch(cmd) {
|
switch(cmd) {
|
||||||
@ -192,13 +174,13 @@ sram_hexdump(SRAM_DB_ADDR, 0x200);
|
|||||||
} else {
|
} else {
|
||||||
printf("No SRAM\n");
|
printf("No SRAM\n");
|
||||||
}
|
}
|
||||||
save_sram((uint8_t*)"/debug.smc", filesize, SRAM_ROM_ADDR);
|
|
||||||
set_mcu_ovr(0);
|
set_mcu_ovr(0);
|
||||||
snes_reset(1);
|
snes_reset(1);
|
||||||
delay_ms(100);
|
delay_ms(100);
|
||||||
snes_reset(0);
|
snes_reset(0);
|
||||||
break;
|
break;
|
||||||
case SNES_CMD_SETRTC:
|
case SNES_CMD_SETRTC:
|
||||||
|
cmd=0; /* stay in loop */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("unknown cmd: %d\n", cmd);
|
printf("unknown cmd: %d\n", cmd);
|
||||||
@ -230,18 +212,17 @@ save_sram((uint8_t*)"/debug.smc", filesize, SRAM_ROM_ADDR);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(snes_reset_state) {
|
if(snes_reset_state) {
|
||||||
delay_ms(10);
|
|
||||||
reset_count++;
|
reset_count++;
|
||||||
} else {
|
} else {
|
||||||
sram_reliable();
|
sram_reliable();
|
||||||
snes_main_loop();
|
snes_main_loop();
|
||||||
}
|
}
|
||||||
if(reset_count>100) {
|
if(reset_count>4) {
|
||||||
reset_count=0;
|
reset_count=0;
|
||||||
set_mcu_ovr(1);
|
set_mcu_ovr(1);
|
||||||
snes_reset(1);
|
snes_reset(1);
|
||||||
delay_ms(100);
|
delay_ms(100);
|
||||||
if(romprops.ramsize_bytes && fpga_test() == 0xa5) {
|
if(romprops.ramsize_bytes && fpga_test() == FPGA_TEST_TOKEN) {
|
||||||
writeled(1);
|
writeled(1);
|
||||||
save_sram(file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR);
|
save_sram(file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR);
|
||||||
writeled(0);
|
writeled(0);
|
||||||
|
|||||||
71
src/memory.c
71
src/memory.c
@ -39,9 +39,13 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "snes.h"
|
#include "snes.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
#include "rle.h"
|
||||||
|
#include "diskio.h"
|
||||||
|
|
||||||
char* hex = "0123456789ABCDEF";
|
char* hex = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
extern snes_romprops_t romprops;
|
||||||
|
|
||||||
void sram_hexdump(uint32_t addr, uint32_t len) {
|
void sram_hexdump(uint32_t addr, uint32_t len) {
|
||||||
static uint8_t buf[16];
|
static uint8_t buf[16];
|
||||||
uint32_t ptr;
|
uint32_t ptr;
|
||||||
@ -162,25 +166,30 @@ uint32_t load_rom(uint8_t* filename, uint32_t base_addr) {
|
|||||||
UINT bytes_read;
|
UINT bytes_read;
|
||||||
DWORD filesize;
|
DWORD filesize;
|
||||||
UINT count=0;
|
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);
|
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) {
|
if(file_res) {
|
||||||
uart_putc('?');
|
uart_putc('?');
|
||||||
uart_putc(0x30+file_res);
|
uart_putc(0x30+file_res);
|
||||||
return 0;
|
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);
|
f_lseek(&file_handle, romprops.offset);
|
||||||
FPGA_DESELECT();
|
// FPGA_DESELECT();
|
||||||
FPGA_SELECT();
|
// FPGA_SELECT();
|
||||||
FPGA_TX_BYTE(0x91); /* write w/ increment */
|
// FPGA_TX_BYTE(0x91); /* write w/ increment */
|
||||||
for(;;) {
|
for(;;) {
|
||||||
/* SPI_OFFLOAD=1; */
|
ff_sd_offload=1;
|
||||||
|
tickstmp=getticks();
|
||||||
bytes_read = file_read();
|
bytes_read = file_read();
|
||||||
|
ticks_read+=getticks()-tickstmp;
|
||||||
if (file_res || !bytes_read) break;
|
if (file_res || !bytes_read) break;
|
||||||
if(!(count++ % 32)) {
|
if(!(count++ % 512)) {
|
||||||
toggle_read_led();
|
toggle_read_led();
|
||||||
/* bounce_busy_led(); */
|
/* bounce_busy_led(); */
|
||||||
uart_putc('.');
|
uart_putc('.');
|
||||||
@ -188,14 +197,17 @@ uint32_t load_rom(uint8_t* filename, uint32_t base_addr) {
|
|||||||
// for(int j=0; j<bytes_read; j++) {
|
// for(int j=0; j<bytes_read; j++) {
|
||||||
// FPGA_TX_BYTE(file_buf[j]);
|
// FPGA_TX_BYTE(file_buf[j]);
|
||||||
// }
|
// }
|
||||||
FPGA_TX_BLOCK(file_buf, 512);
|
//tickstmp = getticks();
|
||||||
|
// FPGA_TX_BLOCK(file_buf, 512);
|
||||||
|
//ticks_tx+=getticks()-tickstmp;
|
||||||
}
|
}
|
||||||
FPGA_TX_BYTE(0x00); /* dummy tx for increment+write pulse */
|
// FPGA_TX_BYTE(0x00); /* dummy tx for increment+write pulse */
|
||||||
FPGA_DESELECT();
|
// FPGA_DESELECT();
|
||||||
file_close();
|
file_close();
|
||||||
set_mapper(romprops.mapper_id);
|
set_mapper(romprops.mapper_id);
|
||||||
printf("rom header map: %02x; mapper id: %d\n", romprops.header.map, romprops.mapper_id);
|
printf("rom header map: %02x; mapper id: %d\n", romprops.header.map, romprops.mapper_id);
|
||||||
|
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 rammask;
|
||||||
uint32_t rommask;
|
uint32_t rommask;
|
||||||
|
|
||||||
@ -212,7 +224,7 @@ uint32_t load_rom(uint8_t* filename, uint32_t base_addr) {
|
|||||||
printf("ramsize=%x rammask=%lx\nromsize=%x rommask=%lx\n", romprops.header.ramsize, rammask, romprops.header.romsize, rommask);
|
printf("ramsize=%x rammask=%lx\nromsize=%x rommask=%lx\n", romprops.header.ramsize, rammask, romprops.header.romsize, rommask);
|
||||||
set_saveram_mask(rammask);
|
set_saveram_mask(rammask);
|
||||||
set_rom_mask(rommask);
|
set_rom_mask(rommask);
|
||||||
|
readled(0);
|
||||||
return (uint32_t)filesize;
|
return (uint32_t)filesize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,6 +250,26 @@ uint32_t load_sram(uint8_t* filename, uint32_t base_addr) {
|
|||||||
return (uint32_t)filesize;
|
return (uint32_t)filesize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t load_sram_rle(uint8_t* filename, uint32_t base_addr) {
|
||||||
|
uint8_t data;
|
||||||
|
set_mcu_addr(base_addr);
|
||||||
|
DWORD filesize;
|
||||||
|
file_open(filename, FA_READ);
|
||||||
|
filesize = file_handle.fsize;
|
||||||
|
if(file_res) return 0;
|
||||||
|
FPGA_SELECT();
|
||||||
|
FPGA_TX_BYTE(0x91);
|
||||||
|
for(;;) {
|
||||||
|
data = rle_file_getc();
|
||||||
|
if (file_res || file_status) break;
|
||||||
|
FPGA_TX_BYTE(data);
|
||||||
|
}
|
||||||
|
FPGA_TX_BYTE(0x00); /* dummy tx */
|
||||||
|
FPGA_DESELECT();
|
||||||
|
file_close();
|
||||||
|
return (uint32_t)filesize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void save_sram(uint8_t* filename, uint32_t sram_size, uint32_t base_addr) {
|
void save_sram(uint8_t* filename, uint32_t sram_size, uint32_t base_addr) {
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
@ -318,3 +350,14 @@ uint8_t sram_reliable() {
|
|||||||
rdyled(result);
|
rdyled(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sram_memset(uint32_t base_addr, uint32_t len, uint8_t val) {
|
||||||
|
set_mcu_addr(base_addr);
|
||||||
|
FPGA_SELECT();
|
||||||
|
FPGA_TX_BYTE(0x91);
|
||||||
|
for(uint32_t i=0; i<len; i++) {
|
||||||
|
FPGA_TX_BYTE(val);
|
||||||
|
}
|
||||||
|
FPGA_TX_BYTE(0x00);
|
||||||
|
FPGA_DESELECT();
|
||||||
|
}
|
||||||
|
|||||||
@ -45,6 +45,7 @@
|
|||||||
|
|
||||||
uint32_t load_rom(uint8_t* filename, uint32_t base_addr);
|
uint32_t load_rom(uint8_t* filename, uint32_t base_addr);
|
||||||
uint32_t load_sram(uint8_t* filename, uint32_t base_addr);
|
uint32_t load_sram(uint8_t* filename, uint32_t base_addr);
|
||||||
|
uint32_t load_sram_rle(uint8_t* filename, uint32_t base_addr);
|
||||||
void sram_hexdump(uint32_t addr, uint32_t len);
|
void sram_hexdump(uint32_t addr, uint32_t len);
|
||||||
uint8_t sram_readbyte(uint32_t addr);
|
uint8_t sram_readbyte(uint32_t addr);
|
||||||
uint16_t sram_readshort(uint32_t addr);
|
uint16_t sram_readshort(uint32_t addr);
|
||||||
@ -58,6 +59,6 @@ void sram_writeblock(void* buf, uint32_t addr, uint16_t size);
|
|||||||
void save_sram(uint8_t* filename, uint32_t sram_size, uint32_t base_addr);
|
void save_sram(uint8_t* filename, uint32_t sram_size, uint32_t base_addr);
|
||||||
uint32_t calc_sram_crc(uint32_t base_addr, uint32_t size);
|
uint32_t calc_sram_crc(uint32_t base_addr, uint32_t size);
|
||||||
uint8_t sram_reliable(void);
|
uint8_t sram_reliable(void);
|
||||||
|
void sram_memset(uint32_t base_adde, uint32_t len, uint8_t val);
|
||||||
|
|
||||||
snes_romprops_t romprops;
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
487
src/sdnative.c
487
src/sdnative.c
@ -1,5 +1,4 @@
|
|||||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||||
#include <arm/bits.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
@ -10,13 +9,18 @@
|
|||||||
#include "led.h"
|
#include "led.h"
|
||||||
#include "sdnative.h"
|
#include "sdnative.h"
|
||||||
#include "fileops.h"
|
#include "fileops.h"
|
||||||
|
#include "bits.h"
|
||||||
|
#include "fpga_spi.h"
|
||||||
|
|
||||||
#define MAX_CARDS 1
|
#define MAX_CARDS 1
|
||||||
|
|
||||||
// SD/MMC commands
|
// SD/MMC commands
|
||||||
#define GO_IDLE_STATE 0
|
#define GO_IDLE_STATE 0
|
||||||
#define SEND_OP_COND 1
|
#define SEND_OP_COND 1
|
||||||
|
#define ALL_SEND_CID 2
|
||||||
|
#define SEND_RELATIVE_ADDR 3
|
||||||
#define SWITCH_FUNC 6
|
#define SWITCH_FUNC 6
|
||||||
|
#define SELECT_CARD 7
|
||||||
#define SEND_IF_COND 8
|
#define SEND_IF_COND 8
|
||||||
#define SEND_CSD 9
|
#define SEND_CSD 9
|
||||||
#define SEND_CID 10
|
#define SEND_CID 10
|
||||||
@ -41,6 +45,7 @@
|
|||||||
#define CRC_ON_OFF 59
|
#define CRC_ON_OFF 59
|
||||||
|
|
||||||
// SD ACMDs
|
// SD ACMDs
|
||||||
|
#define SD_SET_BUS_WIDTH 6
|
||||||
#define SD_STATUS 13
|
#define SD_STATUS 13
|
||||||
#define SD_SEND_NUM_WR_BLOCKS 22
|
#define SD_SEND_NUM_WR_BLOCKS 22
|
||||||
#define SD_SET_WR_BLK_ERASE_COUNT 23
|
#define SD_SET_WR_BLK_ERASE_COUNT 23
|
||||||
@ -62,20 +67,6 @@
|
|||||||
#define CARD_SD (1<<0)
|
#define CARD_SD (1<<0)
|
||||||
#define CARD_SDHC (1<<1)
|
#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
|
1 DAT3/SS P0.6
|
||||||
2 CMD/DI P0.9
|
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 rsp[17];
|
||||||
uint8_t csd[17];
|
uint8_t csd[17];
|
||||||
uint8_t ccs=0;
|
uint8_t ccs=0;
|
||||||
uint8_t rca1, rca2;
|
uint32_t rca;
|
||||||
|
|
||||||
enum trans_state { TRANS_NONE = 0, TRANS_READ, TRANS_WRITE };
|
enum trans_state { TRANS_NONE = 0, TRANS_READ, TRANS_WRITE };
|
||||||
enum cmd_state { CMD_RSP = 0, CMD_RSPDAT, CMD_DAT };
|
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;
|
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
|
send_command_slow
|
||||||
@ -215,9 +210,8 @@ static inline void wiggle_fast_pos1(void) {
|
|||||||
int send_command_slow(uint8_t* cmd, uint8_t* rsp){
|
int send_command_slow(uint8_t* cmd, uint8_t* rsp){
|
||||||
uint8_t shift, i=6;
|
uint8_t shift, i=6;
|
||||||
int rsplen;
|
int rsplen;
|
||||||
// printf("send_command_slow: sending CMD:\n");
|
uint8_t cmdno = *cmd & 0x3f;
|
||||||
wiggle_slow_pos(5);
|
wiggle_slow_pos(5);
|
||||||
// uart_trace(cmd, 0, 6);
|
|
||||||
switch(*cmd & 0x3f) {
|
switch(*cmd & 0x3f) {
|
||||||
case 0:
|
case 0:
|
||||||
rsplen = 0;
|
rsplen = 0;
|
||||||
@ -254,12 +248,11 @@ int send_command_slow(uint8_t* cmd, uint8_t* rsp){
|
|||||||
|
|
||||||
if(rsplen) {
|
if(rsplen) {
|
||||||
uint16_t timeout=1000;
|
uint16_t timeout=1000;
|
||||||
/* wait for responsebob */
|
|
||||||
while((BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN)) && --timeout) {
|
while((BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN)) && --timeout) {
|
||||||
wiggle_slow_neg(1);
|
wiggle_slow_neg(1);
|
||||||
}
|
}
|
||||||
// printf("timeout=%d\n", timeout);
|
|
||||||
if(!timeout) {
|
if(!timeout) {
|
||||||
|
printf("CMD%d timed out\n", cmdno);
|
||||||
return 0; /* no response within timeout */
|
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){
|
int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
|
||||||
uint8_t datshift=8, cmdshift, i=6;
|
uint8_t datshift=8, cmdshift, i=6;
|
||||||
|
uint8_t cmdno = *cmd & 0x3f;
|
||||||
int rsplen, dat=0, waitbusy=0, datcnt=512, j=0;
|
int rsplen, dat=0, waitbusy=0, datcnt=512, j=0;
|
||||||
static int state=CMD_RSP;
|
static int state=CMD_RSP;
|
||||||
// printf("send_command_fast: sending CMD:\n");
|
wiggle_fast_pos(9); /* give the card >=8 cycles after last command */
|
||||||
wiggle_fast_pos(9);
|
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]);
|
||||||
// uart_trace(cmd, 0, 6);
|
|
||||||
switch(*cmd & 0x3f) {
|
switch(*cmd & 0x3f) {
|
||||||
case 0:
|
case 0:
|
||||||
rsplen = 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;
|
BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 1;
|
||||||
|
|
||||||
while(i--) {
|
while(i--) {
|
||||||
|
uint8_t data = *cmd;
|
||||||
cmdshift = 8;
|
cmdshift = 8;
|
||||||
do {
|
do {
|
||||||
cmdshift--;
|
cmdshift--;
|
||||||
uint8_t data = *cmd;
|
|
||||||
*cmd<<=1;
|
|
||||||
if(data&0x80) {
|
if(data&0x80) {
|
||||||
BITBAND(SD_CMDREG->FIOSET, SD_CMDPIN) = 1;
|
BITBAND(SD_CMDREG->FIOSET, SD_CMDPIN) = 1;
|
||||||
} else {
|
} else {
|
||||||
BITBAND(SD_CMDREG->FIOCLR, SD_CMDPIN) = 1;
|
BITBAND(SD_CMDREG->FIOCLR, SD_CMDPIN) = 1;
|
||||||
}
|
}
|
||||||
|
data<<=1;
|
||||||
wiggle_fast_pos1();
|
wiggle_fast_pos1();
|
||||||
} while (cmdshift);
|
} while (cmdshift);
|
||||||
cmd++;
|
cmd++;
|
||||||
}
|
}
|
||||||
|
|
||||||
wiggle_fast_pos(1);
|
wiggle_fast_pos1();
|
||||||
BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 0;
|
BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 0;
|
||||||
|
|
||||||
if(rsplen) {
|
if(rsplen) {
|
||||||
uint16_t timeout=65535;
|
uint32_t timeout=2000000;
|
||||||
/* wait for responsebob */
|
/* wait for response */
|
||||||
while((BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN)) && --timeout) {
|
while((BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN)) && --timeout) {
|
||||||
wiggle_fast_neg1();
|
wiggle_fast_neg1();
|
||||||
}
|
}
|
||||||
// printf("timeout=%d\n", timeout);
|
|
||||||
if(!timeout) {
|
if(!timeout) {
|
||||||
|
printf("CMD%d timed out\n", cmdno);
|
||||||
return 0; /* no response within timeout */
|
return 0; /* no response within timeout */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,7 +348,7 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
|
|||||||
do {
|
do {
|
||||||
if(dat) {
|
if(dat) {
|
||||||
if(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) {
|
if(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) {
|
||||||
// printf("data start\n");
|
DBG_SD printf("data start during response\n");
|
||||||
j=datcnt;
|
j=datcnt;
|
||||||
state=CMD_RSPDAT;
|
state=CMD_RSPDAT;
|
||||||
break;
|
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;
|
cmddata |= (BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN)) << cmdshift;
|
||||||
wiggle_fast_neg1();
|
wiggle_fast_neg1();
|
||||||
} while (cmdshift);
|
} while (cmdshift);
|
||||||
if(state==1)break;
|
if(state==CMD_RSPDAT)break;
|
||||||
*rsp=cmddata;
|
*rsp=cmddata;
|
||||||
cmddata=0;
|
cmddata=0;
|
||||||
rsp++;
|
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 */
|
if(state==CMD_RSPDAT) { /* process response+data */
|
||||||
int startbit=1;
|
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;
|
datshift=8;
|
||||||
while(1) {
|
while(1) {
|
||||||
cmdshift--;
|
cmdshift--;
|
||||||
@ -385,16 +378,14 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
|
|||||||
rsp++;
|
rsp++;
|
||||||
i--;
|
i--;
|
||||||
if(!i) {
|
if(!i) {
|
||||||
printf("response end\n");
|
DBG_SD printf("response end\n");
|
||||||
if(j) state=CMD_DAT; /* response over, remaining data */
|
if(j) state=CMD_DAT; /* response over, remaining data */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!startbit) {
|
if(!startbit) {
|
||||||
datshift-=4;
|
datshift-=4;
|
||||||
datdata |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))
|
datdata |= SD_DAT << datshift;
|
||||||
|((SD_DAT1REG->FIOPIN >> 13) & 0x6)
|
|
||||||
|((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3)) << datshift;
|
|
||||||
if(!datshift) {
|
if(!datshift) {
|
||||||
datshift=8;
|
datshift=8;
|
||||||
*buf=datdata;
|
*buf=datdata;
|
||||||
@ -413,25 +404,26 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
|
|||||||
state=CMD_DAT;
|
state=CMD_DAT;
|
||||||
j=datcnt;
|
j=datcnt;
|
||||||
datshift=8;
|
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) {
|
while((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) && --timeout) {
|
||||||
wiggle_fast_neg1();
|
wiggle_fast_neg1();
|
||||||
}
|
}
|
||||||
wiggle_fast_neg1(); /* eat the start bit */
|
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 */
|
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) {
|
if(datshift==8) {
|
||||||
while(1) {
|
while(1) {
|
||||||
datdata |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))
|
datdata |= SD_DAT << 4;
|
||||||
|((SD_DAT1REG->FIOPIN >> 13) & 0x6)
|
|
||||||
|((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3)) << 4;
|
|
||||||
wiggle_fast_neg1();
|
wiggle_fast_neg1();
|
||||||
|
|
||||||
datdata |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))
|
datdata |= SD_DAT;
|
||||||
|((SD_DAT1REG->FIOPIN >> 13) & 0x6)
|
|
||||||
|((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3));
|
|
||||||
wiggle_fast_neg1();
|
wiggle_fast_neg1();
|
||||||
|
|
||||||
*buf=datdata;
|
*buf=datdata;
|
||||||
@ -444,9 +436,7 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
|
|||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
datshift-=4;
|
datshift-=4;
|
||||||
datdata |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))
|
datdata |= SD_DAT << datshift;
|
||||||
|((SD_DAT1REG->FIOPIN >> 13) & 0x6)
|
|
||||||
|((BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN)) << 3)) << datshift;
|
|
||||||
if(!datshift) {
|
if(!datshift) {
|
||||||
datshift=8;
|
datshift=8;
|
||||||
*buf=datdata;
|
*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(dat) wiggle_fast_neg(17);
|
||||||
|
|
||||||
if(waitbusy) {
|
if(waitbusy) {
|
||||||
while(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) {
|
DBG_SD printf("waitbusy after send_cmd\n");
|
||||||
wiggle_fast_neg1();
|
wait_busy();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
state=CMD_RSP;
|
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;
|
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(0, cmd[0]);
|
||||||
cmd[5]=crc7update(cmd[5], cmd[1]);
|
cmd[5]=crc7update(cmd[5], cmd[1]);
|
||||||
cmd[5]=crc7update(cmd[5], cmd[2]);
|
cmd[5]=crc7update(cmd[5], cmd[2]);
|
||||||
@ -482,65 +473,85 @@ void make_crc7(uint8_t* cmd) {
|
|||||||
cmd[5]=(cmd[5] << 1) | 1;
|
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) {
|
void stream_datablock(uint8_t *buf) {
|
||||||
// uint8_t datshift=8;
|
// uint8_t datshift=8;
|
||||||
int j=512;
|
int j=512;
|
||||||
uint8_t datdata=0;
|
uint8_t datdata=0;
|
||||||
uint16_t timeout=65535;
|
uint32_t timeout=1000000;
|
||||||
|
|
||||||
while((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) && --timeout) {
|
while((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) && --timeout) {
|
||||||
wiggle_fast_neg1();
|
wiggle_fast_neg1();
|
||||||
}
|
}
|
||||||
wiggle_fast_neg1(); /* eat the start bit */
|
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;
|
*buf=datdata;
|
||||||
datdata=0;
|
|
||||||
buf++;
|
buf++;
|
||||||
j--;
|
j--;
|
||||||
if(!j) break;
|
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 */
|
/* eat the crc for now */
|
||||||
wiggle_fast_neg(17);
|
wiggle_fast_neg(17);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_datablock(uint8_t *buf) {
|
void send_datablock(uint8_t *buf) {
|
||||||
uint16_t crc0=0, crc1=0, crc2=0, crc3=0, cnt=512;
|
uint16_t crc0=0, crc1=0, crc2=0, crc3=0, cnt=512;
|
||||||
uint8_t dat0=0, dat1=0, dat2=0, dat3=0, crcshift, datshift;
|
uint8_t dat0=0, dat1=0, dat2=0, dat3=0, crcshift, datshift;
|
||||||
//uart_trace(buf, 0, 512);
|
|
||||||
wiggle_fast_pos(1);
|
wiggle_fast_pos1();
|
||||||
// printf("send_datablock: wait for card\n");
|
|
||||||
/* wait - card might be busy */
|
|
||||||
while(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) {
|
|
||||||
wiggle_fast_neg(1);
|
|
||||||
printf(".");
|
|
||||||
}
|
|
||||||
BITBAND(SD_DAT0REG->FIODIR, SD_DAT0PIN) = 1;
|
BITBAND(SD_DAT0REG->FIODIR, SD_DAT0PIN) = 1;
|
||||||
BITBAND(SD_DAT1REG->FIODIR, SD_DAT1PIN) = 1;
|
BITBAND(SD_DAT1REG->FIODIR, SD_DAT1PIN) = 1;
|
||||||
BITBAND(SD_DAT2REG->FIODIR, SD_DAT2PIN) = 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_DAT2REG->FIOCLR, SD_DAT2PIN) = 1;
|
||||||
BITBAND(SD_DAT3REG->FIOCLR, SD_DAT3PIN) = 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;
|
crcshift=8;
|
||||||
while(cnt--) {
|
while(cnt--) {
|
||||||
datshift=8;
|
datshift=8;
|
||||||
@ -577,7 +588,7 @@ void send_datablock(uint8_t *buf) {
|
|||||||
} else {
|
} else {
|
||||||
BITBAND(SD_DAT0REG->FIOCLR, SD_DAT0PIN) = 1;
|
BITBAND(SD_DAT0REG->FIOCLR, SD_DAT0PIN) = 1;
|
||||||
}
|
}
|
||||||
wiggle_fast_pos(1);
|
wiggle_fast_pos1();
|
||||||
} while (datshift);
|
} while (datshift);
|
||||||
|
|
||||||
crcshift-=2;
|
crcshift-=2;
|
||||||
@ -603,27 +614,27 @@ void send_datablock(uint8_t *buf) {
|
|||||||
datshift=16;
|
datshift=16;
|
||||||
do {
|
do {
|
||||||
datshift--;
|
datshift--;
|
||||||
if((crc0 >> datshift)&1) {
|
if((crc0 >> datshift) & 1) {
|
||||||
BITBAND(SD_DAT0REG->FIOSET, SD_DAT0PIN) = 1;
|
BITBAND(SD_DAT0REG->FIOSET, SD_DAT0PIN) = 1;
|
||||||
} else {
|
} else {
|
||||||
BITBAND(SD_DAT0REG->FIOCLR, SD_DAT0PIN) = 1;
|
BITBAND(SD_DAT0REG->FIOCLR, SD_DAT0PIN) = 1;
|
||||||
}
|
}
|
||||||
if((crc1 >> datshift)&1) {
|
if((crc1 >> datshift) & 1) {
|
||||||
BITBAND(SD_DAT1REG->FIOSET, SD_DAT1PIN) = 1;
|
BITBAND(SD_DAT1REG->FIOSET, SD_DAT1PIN) = 1;
|
||||||
} else {
|
} else {
|
||||||
BITBAND(SD_DAT1REG->FIOCLR, SD_DAT1PIN) = 1;
|
BITBAND(SD_DAT1REG->FIOCLR, SD_DAT1PIN) = 1;
|
||||||
}
|
}
|
||||||
if((crc2 >> datshift)&1) {
|
if((crc2 >> datshift) & 1) {
|
||||||
BITBAND(SD_DAT2REG->FIOSET, SD_DAT2PIN) = 1;
|
BITBAND(SD_DAT2REG->FIOSET, SD_DAT2PIN) = 1;
|
||||||
} else {
|
} else {
|
||||||
BITBAND(SD_DAT2REG->FIOCLR, SD_DAT2PIN) = 1;
|
BITBAND(SD_DAT2REG->FIOCLR, SD_DAT2PIN) = 1;
|
||||||
}
|
}
|
||||||
if((crc3 >> datshift)&1) {
|
if((crc3 >> datshift) & 1) {
|
||||||
BITBAND(SD_DAT3REG->FIOSET, SD_DAT3PIN) = 1;
|
BITBAND(SD_DAT3REG->FIOSET, SD_DAT3PIN) = 1;
|
||||||
} else {
|
} else {
|
||||||
BITBAND(SD_DAT3REG->FIOCLR, SD_DAT3PIN) = 1;
|
BITBAND(SD_DAT3REG->FIOCLR, SD_DAT3PIN) = 1;
|
||||||
}
|
}
|
||||||
wiggle_fast_pos(1);
|
wiggle_fast_pos1();
|
||||||
} while(datshift);
|
} while(datshift);
|
||||||
/* send end bit */
|
/* send end bit */
|
||||||
BITBAND(SD_DAT0REG->FIOSET, SD_DAT0PIN) = 1;
|
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_DAT2REG->FIOSET, SD_DAT2PIN) = 1;
|
||||||
BITBAND(SD_DAT3REG->FIOSET, SD_DAT3PIN) = 1;
|
BITBAND(SD_DAT3REG->FIOSET, SD_DAT3PIN) = 1;
|
||||||
|
|
||||||
wiggle_fast_pos(1);
|
wiggle_fast_pos1();
|
||||||
|
|
||||||
BITBAND(SD_DAT0REG->FIODIR, SD_DAT0PIN) = 0;
|
BITBAND(SD_DAT0REG->FIODIR, SD_DAT0PIN) = 0;
|
||||||
BITBAND(SD_DAT1REG->FIODIR, SD_DAT1PIN) = 0;
|
BITBAND(SD_DAT1REG->FIODIR, SD_DAT1PIN) = 0;
|
||||||
BITBAND(SD_DAT2REG->FIODIR, SD_DAT2PIN) = 0;
|
BITBAND(SD_DAT2REG->FIODIR, SD_DAT2PIN) = 0;
|
||||||
BITBAND(SD_DAT3REG->FIODIR, SD_DAT3PIN) = 0;
|
BITBAND(SD_DAT3REG->FIODIR, SD_DAT3PIN) = 0;
|
||||||
|
|
||||||
wiggle_fast_neg(4);
|
wiggle_fast_neg(3);
|
||||||
dat0=0;
|
dat0=0;
|
||||||
|
|
||||||
datshift=3;
|
datshift=4;
|
||||||
do {
|
do {
|
||||||
datshift--;
|
datshift--;
|
||||||
dat0 |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) << datshift);
|
dat0 |= ((BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN)) << datshift);
|
||||||
wiggle_fast_neg(1);
|
wiggle_fast_neg1();
|
||||||
} while (datshift);
|
} while (datshift);
|
||||||
|
DBG_SD printf("crc %02x\n", dat0);
|
||||||
if(dat0!=2) {
|
if((dat0 & 7) != 2) {
|
||||||
printf("crc error! %02x\n", dat0);
|
printf("crc error! %02x\n", dat0);
|
||||||
while(1);
|
while(1);
|
||||||
}
|
}
|
||||||
wiggle_fast_neg(1);
|
if(dat0 & 8) {
|
||||||
while(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) {
|
printf("missing start bit in CRC status response...\n");
|
||||||
wiggle_fast_neg(1);
|
}
|
||||||
}
|
wiggle_fast_neg(2);
|
||||||
|
wait_busy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void read_block(uint32_t address, uint8_t *buf) {
|
void read_block(uint32_t address, uint8_t *buf) {
|
||||||
if(during_blocktrans == TRANS_READ && (last_block == address-1)) {
|
if(during_blocktrans == TRANS_READ && (last_block == address-1)) {
|
||||||
|
//uart_putc('r');
|
||||||
stream_datablock(buf);
|
stream_datablock(buf);
|
||||||
last_block=address;
|
last_block=address;
|
||||||
} else {
|
} else {
|
||||||
if(during_blocktrans) {
|
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 */
|
/* send STOP_TRANSMISSION to end an open READ/WRITE_MULTIPLE_BLOCK */
|
||||||
cmd[0]=0x40+STOP_TRANSMISSION;
|
cmd_fast(STOP_TRANSMISSION, 0, 0x61, NULL, rsp);
|
||||||
cmd[1]=0;
|
|
||||||
cmd[2]=0;
|
|
||||||
cmd[3]=0;
|
|
||||||
cmd[4]=0;
|
|
||||||
cmd[5]=0x61;
|
|
||||||
send_command_fast(cmd, rsp, NULL);
|
|
||||||
}
|
}
|
||||||
last_block=address;
|
last_block=address;
|
||||||
if(!ccs) address <<= 9;
|
if(!ccs) {
|
||||||
cmd[0]=0x40+READ_MULTIPLE_BLOCK;
|
address <<= 9;
|
||||||
cmd[1]=address>>24;
|
}
|
||||||
cmd[2]=address>>16;
|
cmd_fast(READ_MULTIPLE_BLOCK, address, 0, buf, rsp);
|
||||||
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);
|
|
||||||
during_blocktrans = TRANS_READ;
|
during_blocktrans = TRANS_READ;
|
||||||
}
|
}
|
||||||
// uart_trace(buf, 0, 512);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_block(uint32_t address, uint8_t* buf) {
|
void write_block(uint32_t address, uint8_t* buf) {
|
||||||
if(during_blocktrans == TRANS_WRITE && (last_block == address-1)) {
|
if(during_blocktrans == TRANS_WRITE && (last_block == address-1)) {
|
||||||
|
wait_busy();
|
||||||
send_datablock(buf);
|
send_datablock(buf);
|
||||||
last_block=address;
|
last_block=address;
|
||||||
} else {
|
} else {
|
||||||
if(during_blocktrans) {
|
if(during_blocktrans) {
|
||||||
/* send STOP_TRANSMISSION to end an open READ/WRITE_MULTIPLE_BLOCK */
|
/* send STOP_TRANSMISSION to end an open READ/WRITE_MULTIPLE_BLOCK */
|
||||||
cmd[0]=0x40+STOP_TRANSMISSION;
|
cmd_fast(STOP_TRANSMISSION, 0, 0x61, NULL, rsp);
|
||||||
cmd[1]=0;
|
|
||||||
cmd[2]=0;
|
|
||||||
cmd[3]=0;
|
|
||||||
cmd[4]=0;
|
|
||||||
cmd[5]=0x61;
|
|
||||||
send_command_fast(cmd, rsp, NULL);
|
|
||||||
}
|
}
|
||||||
|
wait_busy();
|
||||||
last_block=address;
|
last_block=address;
|
||||||
if(!ccs) address <<= 9;
|
if(!ccs) {
|
||||||
cmd[0]=0x40+WRITE_MULTIPLE_BLOCK;
|
address <<= 9;
|
||||||
cmd[1]=address>>24;
|
}
|
||||||
cmd[2]=address>>16;
|
/* only send cmd & get response */
|
||||||
cmd[3]=address>>8;
|
cmd_fast(WRITE_MULTIPLE_BLOCK, address, 0, NULL, rsp);
|
||||||
cmd[4]=address;
|
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]);
|
||||||
make_crc7(cmd);
|
wiggle_fast_pos(8);
|
||||||
send_command_fast(cmd, rsp, NULL); /* only send cmd & get response */
|
|
||||||
send_datablock(buf);
|
send_datablock(buf);
|
||||||
during_blocktrans = TRANS_WRITE;
|
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) {
|
DRESULT sdn_initialize(BYTE drv) {
|
||||||
|
|
||||||
uint8_t cmd[6]={0,0,0,0,0,0}; /* command */
|
|
||||||
uint8_t rsp[17]; /* space for response */
|
uint8_t rsp[17]; /* space for response */
|
||||||
int rsplen;
|
int rsplen;
|
||||||
uint8_t hcs=0;
|
uint8_t hcs=0;
|
||||||
if(drv>=MAX_CARDS)
|
rca = 0;
|
||||||
|
if(drv>=MAX_CARDS) {
|
||||||
return STA_NOINIT|STA_NODISK;
|
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
|
/* if the card is sending data from before a reset we try to deselect it
|
||||||
prior to initialization */
|
prior to initialization */
|
||||||
for(rsplen=0; rsplen<2042; rsplen++) {
|
for(rsplen=0; rsplen<2042; rsplen++) {
|
||||||
if(!(BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN))) {
|
if(!(BITBAND(SD_DAT3REG->FIOPIN, SD_DAT3PIN))) {
|
||||||
printf("card seems to be sending data, attempting deselect\n");
|
printf("card seems to be sending data, attempting deselect\n");
|
||||||
cmd[0]=0x40+7;
|
cmd_slow(SELECT_CARD, 0, 0, NULL, rsp);
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
wiggle_slow_neg(1);
|
wiggle_slow_neg(1);
|
||||||
}
|
}
|
||||||
cmd[0]=0x40+GO_IDLE_STATE;
|
|
||||||
cmd[5]=0x95;
|
|
||||||
printf("sd_init start\n");
|
printf("sd_init start\n");
|
||||||
if((rsplen=send_command_slow(cmd, rsp))) {
|
cmd_slow(GO_IDLE_STATE, 0, 0x95, NULL, rsp);
|
||||||
// printf("CMD0 response?!:\n");
|
|
||||||
// uart_trace(rsp, 0, rsplen);
|
|
||||||
}
|
|
||||||
|
|
||||||
wiggle_slow_pos(1000);
|
if((rsplen=cmd_slow(SEND_IF_COND, 0x000001aa, 0x87, NULL, rsp))) {
|
||||||
cmd[0]=0x40+SEND_IF_COND;
|
DBG_SD printf("CMD8 response:\n");
|
||||||
cmd[3]=0x01;
|
DBG_SD uart_trace(rsp, 0, rsplen);
|
||||||
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);
|
|
||||||
hcs=1;
|
hcs=1;
|
||||||
}
|
}
|
||||||
while(1) {
|
while(1) {
|
||||||
cmd[0]=0x40+APP_CMD;
|
if(!(acmd_slow(SD_SEND_OP_COND, (hcs << 30) | 0xfc0000, 0, NULL, rsp))) {
|
||||||
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 {
|
|
||||||
printf("ACMD41 no response!\n");
|
printf("ACMD41 no response!\n");
|
||||||
}
|
}
|
||||||
if(rsp[1]&0x80) break;
|
if(rsp[1]&0x80) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ccs = (rsp[1]>>6) & 1; /* SDHC */
|
ccs = (rsp[1]>>6) & 1; /* SDHC/XC */
|
||||||
|
|
||||||
cmd[0]=0x40+2;
|
cmd_slow(ALL_SEND_CID, 0, 0x4d, NULL, rsp);
|
||||||
cmd[1]=0;
|
if(cmd_slow(SEND_RELATIVE_ADDR, 0, 0x21, NULL, rsp)) {
|
||||||
cmd[2]=0;
|
rca=(rsp[1]<<24) | (rsp[2]<<16);
|
||||||
cmd[3]=0;
|
printf("RCA: %04lx\n", rca>>16);
|
||||||
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);
|
|
||||||
} else {
|
} else {
|
||||||
printf("CMD3 no response!\n");
|
printf("CMD3 no response!\n");
|
||||||
rca1=0;
|
rca=0;
|
||||||
rca2=0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd[0]=0x40+9;
|
|
||||||
cmd[1]=rca1;
|
|
||||||
cmd[2]=rca2;
|
|
||||||
cmd[3]=0;
|
|
||||||
cmd[4]=0;
|
|
||||||
make_crc7(cmd);
|
|
||||||
|
|
||||||
/* record CSD for getinfo */
|
/* record CSD for getinfo */
|
||||||
if((rsplen=send_command_slow(cmd, csd))) {
|
cmd_slow(SEND_CSD, rca, 0, NULL, rsp);
|
||||||
// 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);
|
|
||||||
|
|
||||||
/* select the card */
|
/* select the card */
|
||||||
if((rsplen=send_command_slow(cmd, rsp))) {
|
if(cmd_slow(SELECT_CARD, rca, 0, NULL, rsp)) {
|
||||||
// printf("CMD7 response:\n");
|
|
||||||
// uart_trace(rsp, 0, rsplen);
|
|
||||||
printf("card selected!\n");
|
printf("card selected!\n");
|
||||||
} else {
|
} else {
|
||||||
printf("CMD7 no response!\n");
|
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 */
|
/* get card status */
|
||||||
if((rsplen=send_command_fast(cmd, rsp, NULL))) {
|
cmd_slow(SEND_STATUS, rca, 0, NULL, rsp);
|
||||||
// printf("CMD13 response:\n");
|
|
||||||
// uart_trace(rsp, 0, rsplen);
|
|
||||||
} else {
|
|
||||||
printf("CMD13 no response!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set bus width */
|
/* set bus width */
|
||||||
cmd[0]=0x40+55;
|
acmd_slow(SD_SET_BUS_WIDTH, 0x2, 0, NULL, rsp);
|
||||||
cmd[1]=rca1;
|
|
||||||
cmd[2]=rca2;
|
|
||||||
cmd[3]=0;
|
|
||||||
cmd[4]=0;
|
|
||||||
make_crc7(cmd);
|
|
||||||
|
|
||||||
if((rsplen=send_command_slow(cmd, rsp))) {
|
/* set block length */
|
||||||
// printf("CMD55 response:\n");
|
cmd_slow(SET_BLOCKLEN, 0x200, 0, NULL, rsp);
|
||||||
// uart_trace(rsp, 0, rsplen);
|
|
||||||
} else {
|
|
||||||
printf("CMD55 no response!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
printf("SD init complete. SDHC/XC=%d\n", ccs);
|
||||||
|
disk_state = DISK_OK;
|
||||||
|
during_blocktrans = TRANS_NONE;
|
||||||
return sdn_status(drv);
|
return sdn_status(drv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -955,28 +825,30 @@ void disk_init(void) __attribute__ ((weak, alias("sdn_init")));
|
|||||||
|
|
||||||
|
|
||||||
DSTATUS sdn_status(BYTE drv) {
|
DSTATUS sdn_status(BYTE drv) {
|
||||||
if (SDCARD_DETECT)
|
if (SDCARD_DETECT) {
|
||||||
if (SDCARD_WP)
|
if (SDCARD_WP) {
|
||||||
return STA_PROTECT;
|
return STA_PROTECT;
|
||||||
else
|
} else {
|
||||||
return RES_OK;
|
return RES_OK;
|
||||||
else
|
}
|
||||||
|
} else {
|
||||||
return STA_NOINIT|STA_NODISK;
|
return STA_NOINIT|STA_NODISK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DSTATUS disk_status(BYTE drv) __attribute__ ((weak, alias("sdn_status")));
|
DSTATUS disk_status(BYTE drv) __attribute__ ((weak, alias("sdn_status")));
|
||||||
|
|
||||||
DRESULT sdn_getinfo(BYTE drv, BYTE page, void *buffer) {
|
DRESULT sdn_getinfo(BYTE drv, BYTE page, void *buffer) {
|
||||||
uint32_t capacity;
|
uint32_t capacity;
|
||||||
|
|
||||||
if (drv >= MAX_CARDS)
|
if (drv >= MAX_CARDS) {
|
||||||
return RES_NOTRDY;
|
return RES_NOTRDY;
|
||||||
|
}
|
||||||
if (sdn_status(drv) & STA_NODISK)
|
if (sdn_status(drv) & STA_NODISK) {
|
||||||
return RES_NOTRDY;
|
return RES_NOTRDY;
|
||||||
|
}
|
||||||
if (page != 0)
|
if (page != 0) {
|
||||||
return RES_ERROR;
|
return RES_ERROR;
|
||||||
|
}
|
||||||
if (ccs) {
|
if (ccs) {
|
||||||
/* Special CSD for SDHC cards */
|
/* Special CSD for SDHC cards */
|
||||||
capacity = (1 + getbits(csd,127-69+8,22)) * 1024;
|
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->disktype = DISK_TYPE_SD;
|
||||||
di->sectorsize = 2;
|
di->sectorsize = 2;
|
||||||
di->sectorcount = capacity;
|
di->sectorcount = capacity;
|
||||||
|
|
||||||
|
printf("card capacity: %lu sectors\n", capacity);
|
||||||
return RES_OK;
|
return RES_OK;
|
||||||
}
|
}
|
||||||
DRESULT disk_getinfo(BYTE drv, BYTE page, void *buffer) __attribute__ ((weak, alias("sdn_getinfo")));
|
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) {
|
if(drv >= MAX_CARDS) {
|
||||||
return RES_NOTRDY;
|
return RES_NOTRDY;
|
||||||
}
|
}
|
||||||
if (sdn_status(drv) & STA_NODISK)
|
if (sdn_status(drv) & STA_NODISK) {
|
||||||
return RES_NOTRDY;
|
return RES_NOTRDY;
|
||||||
|
}
|
||||||
for(sec=0; sec<count; sec++) {
|
for(sec=0; sec<count; sec++) {
|
||||||
write_block(sector+sec, buf);
|
write_block(sector+sec, buf);
|
||||||
buf+=512;
|
buf+=512;
|
||||||
@ -1017,9 +891,10 @@ DRESULT disk_write(BYTE drv, const BYTE *buffer, DWORD sector, BYTE count) __att
|
|||||||
|
|
||||||
/* Detect changes of SD card 0 */
|
/* Detect changes of SD card 0 */
|
||||||
void sdn_changed() {
|
void sdn_changed() {
|
||||||
if (SDCARD_DETECT)
|
if (SDCARD_DETECT) {
|
||||||
disk_state = DISK_CHANGED;
|
disk_state = DISK_CHANGED;
|
||||||
else
|
} else {
|
||||||
disk_state = DISK_REMOVED;
|
disk_state = DISK_REMOVED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,8 +3,16 @@
|
|||||||
#ifndef SDNATIVE_H
|
#ifndef SDNATIVE_H
|
||||||
#define SDNATIVE_H
|
#define SDNATIVE_H
|
||||||
|
|
||||||
|
#ifdef DEBUG_SD
|
||||||
|
#define DBG_SD
|
||||||
|
#else
|
||||||
|
#define DBG_SD while(0)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "diskio.h"
|
#include "diskio.h"
|
||||||
|
|
||||||
|
extern int sd_offload;
|
||||||
|
|
||||||
/* These functions are weak-aliased to disk_... */
|
/* These functions are weak-aliased to disk_... */
|
||||||
void sdn_init(void);
|
void sdn_init(void);
|
||||||
DSTATUS sdn_status(BYTE drv);
|
DSTATUS sdn_status(BYTE drv);
|
||||||
|
|||||||
@ -29,6 +29,8 @@
|
|||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
#include "smc.h"
|
#include "smc.h"
|
||||||
|
|
||||||
|
snes_romprops_t romprops;
|
||||||
|
|
||||||
uint32_t hdr_addr[6] = {0xffb0, 0x101b0, 0x7fb0, 0x81b0, 0x40ffb0, 0x4101b0};
|
uint32_t hdr_addr[6] = {0xffb0, 0x101b0, 0x7fb0, 0x81b0, 0x40ffb0, 0x4101b0};
|
||||||
uint8_t countAllASCII(uint8_t* data, int size) {
|
uint8_t countAllASCII(uint8_t* data, int size) {
|
||||||
uint8_t res = 0;
|
uint8_t res = 0;
|
||||||
|
|||||||
@ -39,6 +39,8 @@
|
|||||||
|
|
||||||
uint8_t initloop=1;
|
uint8_t initloop=1;
|
||||||
uint32_t saveram_crc, saveram_crc_old;
|
uint32_t saveram_crc, saveram_crc_old;
|
||||||
|
extern snes_romprops_t romprops;
|
||||||
|
|
||||||
void snes_init() {
|
void snes_init() {
|
||||||
/* put reset level on reset pin */
|
/* put reset level on reset pin */
|
||||||
BITBAND(SNES_RESET_REG->FIOCLR, SNES_RESET_BIT) = 1;
|
BITBAND(SNES_RESET_REG->FIOCLR, SNES_RESET_BIT) = 1;
|
||||||
@ -135,5 +137,5 @@ uint8_t menu_main_loop() {
|
|||||||
void get_selected_name(uint8_t* fn) {
|
void get_selected_name(uint8_t* fn) {
|
||||||
uint32_t addr = sram_readlong(SRAM_PARAM_ADDR);
|
uint32_t addr = sram_readlong(SRAM_PARAM_ADDR);
|
||||||
printf("fd addr=%lx\n", 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);
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/sort.c
12
src/sort.c
@ -62,13 +62,15 @@ int sort_cmp_elem(const void* elem1, const void* elem2) {
|
|||||||
|
|
||||||
/* get truncated string from database */
|
/* get truncated string from database */
|
||||||
void sort_getstring_for_dirent(char *ptr, uint32_t addr) {
|
void sort_getstring_for_dirent(char *ptr, uint32_t addr) {
|
||||||
stat_getstring++;
|
uint8_t leaf_offset;
|
||||||
if(addr & 0x80000000) {
|
if(addr & 0x80000000) {
|
||||||
/* is directory link, name offset 6 */
|
/* is directory link, name offset 4 */
|
||||||
sram_readblock(ptr, addr+0x6+SRAM_MENU_ADDR, 20);
|
leaf_offset = sram_readbyte(addr + 4 + SRAM_MENU_ADDR);
|
||||||
|
sram_readblock(ptr, addr + 5 + leaf_offset + SRAM_MENU_ADDR, 20);
|
||||||
} else {
|
} else {
|
||||||
/* is file link, name offset 10 */
|
/* is file link, name offset 6 */
|
||||||
sram_readblock(ptr, addr+10+SRAM_MENU_ADDR, 20);
|
leaf_offset = sram_readbyte(addr + 6 + SRAM_MENU_ADDR);
|
||||||
|
sram_readblock(ptr, addr + 7 + leaf_offset + SRAM_MENU_ADDR, 20);
|
||||||
}
|
}
|
||||||
ptr[20]=0;
|
ptr[20]=0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user