From 89905ba6fefdd53e0804777aaa414f243cd596d8 Mon Sep 17 00:00:00 2001 From: Scott Hutter Date: Thu, 9 Jul 2020 00:44:48 -0500 Subject: [PATCH] add directory command to d64 menu --- software/drive/c1541.cc | 185 +++++++++++++++++++++++++++++ software/drive/c1541.h | 2 + software/filetypes/filetype_d64.cc | 1 + 3 files changed, 188 insertions(+) diff --git a/software/drive/c1541.cc b/software/drive/c1541.cc index 9189eb99e..f3277b7a3 100644 --- a/software/drive/c1541.cc +++ b/software/drive/c1541.cc @@ -671,6 +671,7 @@ int C1541 :: executeCommand(SubsysCommand *cmd) FileInfo info(32); switch(cmd->functionID) { + case D64_DIR: case D64FILE_MOUNT_UL: case G64FILE_MOUNT_UL: case D64FILE_MOUNT_RO: @@ -717,6 +718,13 @@ int C1541 :: executeCommand(SubsysCommand *cmd) SubsysCommand *c64_command; switch(cmd->functionID) { + case D64_DIR: + { + if(cmd->user_interface) { + getDir(cmd); + } + break; + } case D64FILE_RUN: case D64FILE_MOUNT: case D64FILE_MOUNT_UL: @@ -896,3 +904,180 @@ bool C1541 :: save_disk_to_file(SubsysCommand *cmd) } return false; } + +#define TRK18_OFFSET 0x16500 +#define SECTOR_SIZE 256 +#define QUOTE 0x22 + +void C1541::getDir(SubsysCommand *cmd) +{ + uint8_t filetypes[6][3] = { + { 'D', 'E', 'L' }, + { 'S', 'E', 'Q' }, + { 'P', 'R', 'G' }, + { 'U', 'S', 'R' }, + { 'R', 'E', 'L' }, + { 'C', 'B', 'M' } + }; + + FileManager *fm = FileManager::getFileManager(); + File *f = 0; + FRESULT fres = fm->fopen(cmd->path.c_str(), cmd->filename.c_str(), FA_READ, &f); + uint32_t transferred; + if (f != NULL) { + uint32_t size = f->get_size(); + char *text_buf = new char[size + 1]; + char *output = new char[3000]; + FRESULT fres = f->read(text_buf, size, &transferred); + + printf("Res = %d. Read text buffer: %d bytes\n", fres, transferred); + text_buf[transferred] = 0; + + uint32_t ctr = 0; + + // drive number + output[ctr++] = '0'; + output[ctr++] = ' '; + + // get disk name + output[ctr++] = QUOTE; + + uint8_t tmp=0; + while(tmp<16) { + output[ctr] = text_buf[TRK18_OFFSET+0x90+tmp]; + if(output[ctr] == 0xA0) + output[ctr] = 0x20; + ctr++; + tmp++; + } + + output[ctr++] = QUOTE; + output[ctr++] = ' '; + output[ctr++] = text_buf[TRK18_OFFSET+0xA2]; + output[ctr++] = text_buf[TRK18_OFFSET+0xA3]; + output[ctr++] = ' '; + output[ctr++] = text_buf[TRK18_OFFSET+0xA5]; + output[ctr++] = text_buf[TRK18_OFFSET+0xA6]; + + output[ctr++] = 0x0D; + + uint8_t cur_track = 18; + uint8_t cur_sector = 0; + uint8_t nxt_track = 18; + uint8_t nxt_sector = 1; + + while(nxt_track != 0x00) + { + cur_track = nxt_track; + cur_sector = nxt_sector; + + nxt_track = text_buf[TRK18_OFFSET+ (SECTOR_SIZE * cur_sector) + 0]; + nxt_sector = text_buf[TRK18_OFFSET+ (SECTOR_SIZE * cur_sector) + 1]; + + // file type + uint8_t ftype = 0; + uint8_t size_lo = 0; + uint8_t size_hi = 0; + + for(uint8_t entry=0; entry<7;entry++) + { + ftype = text_buf[TRK18_OFFSET+ (SECTOR_SIZE * cur_sector) + (entry * 32) + 0x02]; + size_lo = text_buf[TRK18_OFFSET+ (SECTOR_SIZE * cur_sector) + (entry * 32) + 0x1e]; + size_hi = text_buf[TRK18_OFFSET+ (SECTOR_SIZE * cur_sector) + (entry * 32) + 0x1f]; + + // only display file if not deleted + if (ftype != 0) + { + int blocks = size_hi * 256 + size_lo; + + // format file size in blocks + char str[4]; + sprintf(str, "%d", blocks); + + for(int x=0; x= 0) + { + blocks /= 10; + ++digits; + + if (blocks == 0) + break; + } + int spaces = 6 - digits; + for (; spaces > 0; spaces--) + output[ctr++] = ' '; + + // filenames + output[ctr++] = QUOTE; + + uint8_t tmp=0; + uint8_t namelen = 0; + + while(tmp<16) { + + uint8_t c = text_buf[TRK18_OFFSET+ (SECTOR_SIZE * cur_sector) + (entry * 32) + 0x05 + tmp]; + + if(c != 0x00 && c != 0xA0) { + output[ctr] = c; + namelen++; + } + else + break; + + ctr++; + tmp++; + } + + output[ctr++] = QUOTE; + + // formatting + spaces = 16-namelen; + for (; spaces > 0; spaces--) + output[ctr++] = ' '; + + + // file type + uint8_t tmptype = ftype; + tmptype = tmptype & ~128; + tmptype = tmptype & ~64; + tmptype = tmptype & ~32; + tmptype = tmptype & ~16; + + if ((ftype & 0x80) != 0x80) + output[ctr++] = '*'; + else + output[ctr++] = ' '; + + output[ctr++] = filetypes[tmptype][0]; + output[ctr++] = filetypes[tmptype][1]; + output[ctr++] = filetypes[tmptype][2]; + + // file lock + if ((ftype & 64) == 64) + output[ctr++] = '<'; + else + output[ctr++] = ' '; + + output[ctr++] = 0x0D; + } + } + } + + output[ctr] = 0x00; + + // do a late case conversion + for(int x=0; x 64 and output[x] < 91) + output[x] = output[x] + 32; + } + + cmd->user_interface->run_editor(output); + delete text_buf; + delete output; + } + return; +} diff --git a/software/drive/c1541.h b/software/drive/c1541.h index 5c4b05cba..010cf3dbc 100644 --- a/software/drive/c1541.h +++ b/software/drive/c1541.h @@ -34,6 +34,7 @@ #define D64FILE_MOUNT 0x2102 #define D64FILE_MOUNT_RO 0x2103 #define D64FILE_MOUNT_UL 0x2104 +#define D64_DIR 0x2105 #define G64FILE_RUN 0x2121 #define G64FILE_MOUNT 0x2122 @@ -127,6 +128,7 @@ class C1541 : public SubSystem, ConfigurableObject, ObjectWithMenu void mount_blank(void); bool check_if_save_needed(SubsysCommand *cmd); bool save_if_needed(SubsysCommand *cmd); + void getDir(SubsysCommand *cmd); public: C1541(volatile uint8_t *regs, char letter); ~C1541(); diff --git a/software/filetypes/filetype_d64.cc b/software/filetypes/filetype_d64.cc index 0a179177f..13d2b9a4b 100644 --- a/software/filetypes/filetype_d64.cc +++ b/software/filetypes/filetype_d64.cc @@ -63,6 +63,7 @@ int FileTypeD64 :: fetch_context_items(IndexedList &list) C64 *machine = C64 :: getMachine(); if (ftype == 1541) { if(capabilities & CAPAB_DRIVE_1541_1) { + list.append(new Action("Directory", SUBSYSID_DRIVE_A, D64_DIR)); list.append(new Action("Mount Disk", SUBSYSID_DRIVE_A, D64FILE_MOUNT)); if (machine->exists()) list.append(new Action("Run Disk", SUBSYSID_DRIVE_A, D64FILE_RUN));