summaryrefslogtreecommitdiff
path: root/avr/cmd_fat.c
diff options
context:
space:
mode:
Diffstat (limited to 'avr/cmd_fat.c')
-rw-r--r--avr/cmd_fat.c216
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;
+}