diff options
author | Leo C | 2014-12-01 11:12:23 +0100 |
---|---|---|
committer | Leo C | 2014-12-01 11:12:23 +0100 |
commit | 4565be9a755c4de8ffdbc8b9a7b2d87c87f7a9e1 (patch) | |
tree | 65cc3402ed89d30ea058ed3244a36e7863110739 /avr/cmd_fat.c | |
parent | 4f881b028b8e5f6d41efc430185db4d41cb48caa (diff) | |
download | z180-stamp-4565be9a755c4de8ffdbc8b9a7b2d87c87f7a9e1.zip |
merge do_fat_read() and do_fat_write() to do_fat_rw()
Diffstat (limited to 'avr/cmd_fat.c')
-rw-r--r-- | avr/cmd_fat.c | 216 |
1 files changed, 171 insertions, 45 deletions
diff --git a/avr/cmd_fat.c b/avr/cmd_fat.c index 1c46dd1..0232f5d 100644 --- a/avr/cmd_fat.c +++ b/avr/cmd_fat.c @@ -6,13 +6,17 @@ #include "command.h" #include "ff.h" #include "z80-if.h" +#include "con-utils.h" #include "print-utils.h" #include "timer.h" #include "debug.h" +#define MAX_MEMORY (1ul << 20) + DWORD get_fattime (void) { + /* TODO: */ return 0; } @@ -109,65 +113,70 @@ FRESULT scan_files ( */ command_ret_t do_fat_stat(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - FATFS FatFs, *fs; - DWORD clusters; + FATFS *FatFs, *fs; + DWORD nfreeclst; FRESULT res; - char buffer[512]; + char *buffer; (void) cmdtp; (void) flag; (void) argc; - res = f_mount(&FatFs, argv[1], 0); - if (!res) - res = f_getfree(argv[1], &clusters, &fs); - if (res) { - put_rc(res); + FatFs = (FATFS *) malloc(sizeof (FATFS)); + buffer = (char *) malloc(512); + if (FatFs == NULL || buffer == NULL) { + printf_P(PSTR("fatstat: Out of Memory!\n")); + free(FatFs); + free(buffer); return CMD_RET_FAILURE; } - printf_P(PSTR( - "FAT type: %u\n" - "Bytes/Cluster: %lu\n" - "Number of FATs: %u\n" - "Root DIR entries: %u\n" - "Sectors/FAT: %lu\n" - "Number of clusters: %lu\n" - "FAT start (lba): %lu\n" - "DIR start (lba,cluster): %lu\n" - "Data start (lba): %lu\n"), - fs->fs_type, (DWORD)fs->csize * 512, fs->n_fats, - fs->n_rootdir, fs->fsize, fs->n_fatent - 2, - fs->fatbase, fs->dirbase, fs->database); + res = f_mount(FatFs, argv[1], 0); + if (!res) { + res = f_getfree(argv[1], &nfreeclst, &fs); + if (!res) { + printf_P(PSTR( + "FAT type: %u\n" + "Bytes/Cluster: %lu\n" + "Number of FATs: %u\n" + "Root DIR entries: %u\n" + "Sectors/FAT: %lu\n" + "Number of clusters: %lu\n" + "FAT start (lba): %lu\n" + "DIR start (lba,cluster): %lu\n" + "Data start (lba): %lu\n"), + fs->fs_type, (DWORD)fs->csize * 512, fs->n_fats, + fs->n_rootdir, fs->fsize, fs->n_fatent - 2, + fs->fatbase, fs->dirbase, fs->database); #if _USE_LABEL - TCHAR label[12]; - DWORD serial; - res = f_getlabel(argv[1], label, &serial); - if (res) { - put_rc(res); - return CMD_RET_FAILURE; - } - printf_P(PSTR( - "Volume name: %s\n" - "Volume S/N: %04X-%04X\n"), - label, (WORD)(serial >> 16), (WORD)(serial & 0xFFFF)); + TCHAR label[12]; + DWORD serial; + res = f_getlabel(argv[1], label, &serial); + if (!res) { + printf_P(PSTR( + "Volume name: %s\n" + "Volume S/N: %04X-%04X\n"), + label, (WORD)(serial >> 16), (WORD)(serial & 0xFFFF)); + } #endif - my_puts_P(PSTR("\n...")); - AccSize = AccFiles = AccDirs = 0; + if (!res) { + my_puts_P(PSTR("\n...")); + AccSize = AccFiles = AccDirs = 0; - strcpy(buffer, argv[1]); + strcpy(buffer, argv[1]); - res = scan_files(buffer); - if (res) { - put_rc(res); - return CMD_RET_FAILURE; + res = scan_files(buffer); + } + if (!res) { + printf_P(PSTR("\r%u files, %lu bytes.\n%u folders.\n" + "%lu KB total disk space.\n%lu KB available.\n"), + AccFiles, AccSize, AccDirs, + (fs->n_fatent - 2) * (fs->csize / 2), nfreeclst * (fs->csize / 2) + ); + } + } } - printf_P(PSTR("\r%u files, %lu bytes.\n%u folders.\n" - "%lu KB total disk space.\n%lu KB available.\n"), - AccFiles, AccSize, AccDirs, - (fs->n_fatent - 2) * (fs->csize / 2), clusters * (fs->csize / 2) - ); - res = f_mount(NULL, argv[1], 0); + f_mount(NULL, argv[1], 0); if (res) { put_rc(res); return CMD_RET_FAILURE; @@ -396,3 +405,120 @@ command_ret_t do_fat_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const ar return CMD_RET_SUCCESS; } + +/* + * fatread/write - load binary file to/from a dos filesystem + * read <d:/path/filename> <addr> [bytes [pos]] + * write <d:/path/filename> <addr> <bytes> + */ +command_ret_t do_fat_rw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + FATFS FatFs; + FIL File; + uint32_t addr; + unsigned long bytes; + unsigned long pos; + unsigned long bytes_rw; + + bool dowrite = (argv[0][3] == 'w'); + FRESULT res; + bool buserr = 0; + uint32_t timer; + uint8_t buffer[512]; + + (void) cmdtp; (void) flag; + + if (argc < (dowrite ? 4 : 3)) + return CMD_RET_USAGE; + + addr = strtoul(argv[2], 0, 16); + if (addr >= MAX_MEMORY) { + printf_P(PSTR("address too high: 0x%0lx\n"), addr); + return CMD_RET_FAILURE; + } + if (argc > 3) + bytes = strtoul(argv[3], 0, 16); + else + bytes = MAX_MEMORY; + if (argc > 4) + pos = strtoul(argv[4], 0, 16); + else + pos = 0; + + if (addr + bytes > MAX_MEMORY) + bytes = MAX_MEMORY - addr; + + res = f_mount(&FatFs, argv[1], 0); + if (!res) { + res = f_open(&File, argv[1], dowrite ? FA_WRITE | FA_CREATE_ALWAYS + : FA_READ ); + + if (!res) { + res = f_lseek(&File, pos); + if (!res) { + bytes_rw = 0; + timer = get_timer(0); + while (bytes) { + unsigned int cnt, br; + + if (bytes >= sizeof buffer) { + cnt = sizeof buffer; + bytes -= sizeof buffer; + } else { + cnt = bytes; bytes = 0; + } + if (dowrite) { + if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) { + buserr = 1; + break; + } + z80_read_block(buffer, addr, cnt); + z80_bus_cmd(Release); + res = f_write(&File, buffer, cnt, &br); + if (res != FR_OK) + break; + } else { + res = f_read(&File, buffer, cnt, &br); + if (res != FR_OK) + break; + if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) { + buserr = 1; + break; + } + z80_write_block(buffer, addr, br); + z80_bus_cmd(Release); + } + addr += br; + + bytes_rw += br; + if (cnt != br) { + if (dowrite) + printf_P(PSTR("Disk full?\n")); + break; + } + if (ctrlc()) { + printf_P(PSTR("Abort\n")); + break; + } + } + + FRESULT fr = f_close(&File); + if (!res) + res = fr; + timer = get_timer(timer); + printf_P(PSTR("%lu (0x%lx) bytes read/written with %lu bytes/sec.\n"), + bytes_rw, bytes_rw, timer ? (bytes_rw * 1000 / timer) : 0); + } + } + f_mount(NULL, argv[1], 0); + } + + if (buserr) + my_puts_P(PSTR("Bus timeout\n")); + if (res) + put_rc(res); + if (buserr || res) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} |