From cb4fb1ed02b59f798368a76f2596d7c24125e68a Mon Sep 17 00:00:00 2001 From: Leo C Date: Mon, 30 May 2016 17:33:27 +0200 Subject: New command(s): attach (and detach) - not fully working. --- avr/z180-serv.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 115 insertions(+), 17 deletions(-) (limited to 'avr/z180-serv.c') diff --git a/avr/z180-serv.c b/avr/z180-serv.c index e2a39d3..1bf76b4 100644 --- a/avr/z180-serv.c +++ b/avr/z180-serv.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: GPL-2.0 */ +#include "z180-serv.h" #include "common.h" #include #include @@ -18,13 +19,12 @@ #include "z80-if.h" #include "debug.h" #include "print-utils.h" -#include "z180-serv.h" #include "timer.h" #include "time.h" #include "bcd.h" #include "rtc.h" -#define DEBUG_CPM_SDIO 0 /* set to 1 to debug */ +#define DEBUG_CPM_SDIO 1 /* set to 1 to debug */ #define debug_cpmsd(fmt, args...) \ debug_cond(DEBUG_CPM_SDIO, fmt, ##args) @@ -207,22 +207,120 @@ void do_msg_get_set_time(uint8_t subf, int len, uint8_t * msg) /* ---------------------------------------------------------------------------*/ -/* TODO: Variable Disk Format */ -#define CONFIG_CPM_DISKSIZE (8*1024*1024L) - -struct cpm_drive_s { - uint8_t drv; - uint8_t device; - char *img_name; - bool dirty; - FIL fd; -}; - static uint8_t disk_buffer[CONFIG_CPM_BLOCK_SIZE]; static struct cpm_drive_s drv_table[CONFIG_CPM_MAX_DRIVE]; static int handle_cpm_drv_to; +int drv_list(void) +{ + for (uint8_t i = 0; i < CONFIG_CPM_MAX_DRIVE; i++) { + struct cpm_drive_s * p = &drv_table[i]; + if (p->img_name) { + printf_P(PSTR(" dsk%d: %2s %3s attached to %s\n"), i, + p->opt&DRV_OPT_RO ? "RO":"RW", p->opt&DRV_OPT_DEBUG ? "DBG":"", + p->img_name); + } + } + return 0; +} + +int drv_detach(uint8_t drv) +{ + if (drv < CONFIG_CPM_MAX_DRIVE) { + struct cpm_drive_s *p = &drv_table[drv]; + + debug_cpmsd("## detach dsk%d: %s\n", drv, + p->img_name ? p->img_name : "-"); + + if (p->img_name) { + f_close(&p->fd); + p->opt = 0; + p->dirty = false; + free(p->img_name); + p->img_name = NULL; + } + } + return 0; +} + +static int drv_find_file_attached(const char *fn) +{ + for (uint8_t i = 0; i < CONFIG_CPM_MAX_DRIVE; i++) { + struct cpm_drive_s *p = &drv_table[i]; + if (p->img_name && !strcmp(fn, p->img_name)) { + return i; + } + } + return -1; +} + +int drv_attach(uint8_t drv, const char *filename, drv_opt_t options) +{ + int res; + + if (drv >= CONFIG_CPM_MAX_DRIVE) + return AT_RANGE; + + struct cpm_drive_s *p = &drv_table[drv]; + + if (options & DRV_OPT_REATTATCH) { + if (filename) { + return AT_ERROR; + } + + if (!p->img_name) { + return AT_NOT; + } + + p->opt = options & ~DRV_OPT_REATTATCH; + + /* TODO: change options */ + + } else { + + if (p->img_name) + return AT_ALREADY; + if (drv_find_file_attached(filename) >= 0) + return AT_OTHER; + + p->opt = options & ~DRV_OPT_REATTATCH; + + /* new attachment */ + + if ((p->img_name = strdup(filename)) == NULL) + return AT_NOMEM; + + res = f_open(&p->fd, p->img_name, + FA_WRITE | FA_READ); + + if (!res && f_size(&p->fd) < CONFIG_CPM_DISKSIZE) { + unsigned int bw; + + debug_cpmsd(" expanding image file from %ld to %ld\n", + f_size(&p->fd), CONFIG_CPM_DISKSIZE); + + res = f_lseek(&p->fd, CONFIG_CPM_DISKSIZE-CONFIG_CPM_BLOCK_SIZE); + if (!res) { + memset(disk_buffer, 0xe5, CONFIG_CPM_BLOCK_SIZE); + res = f_write(&p->fd, disk_buffer, CONFIG_CPM_BLOCK_SIZE, &bw); + if (res || bw < CONFIG_CPM_BLOCK_SIZE) { + debug_cpmsd(" failed! res: %d, bytes written: %u\n", res, bw); + } + p->dirty = true; + bg_setstat(handle_cpm_drv_to, 1); + } + } + if (res) { + drv_detach(drv); + return AT_OPEN; + } + } + + return AT_OK; +} + + int cpm_drv_to(int state) { static uint32_t ts; @@ -294,13 +392,13 @@ void do_msg_cpm_login(uint8_t subf, int len, uint8_t * msg) /* Get relative drive number */ drv = msg[1]; - if ( drv>= CONFIG_CPM_MAX_DRIVE) { + if ( drv >= CONFIG_CPM_MAX_DRIVE) { return msg_cpm_result(subf, 0x02, res); } -/* - uint32_t dph = ((uint32_t)msg[4] << 16) + ((uint16_t)msg[3] << 8) + msg[2]; -*/ + + drv_table[drv].dph = ((uint32_t)msg[4] << 16) + ((uint16_t)msg[3] << 8) + msg[2]; + if (drv_table[drv].img_name != NULL) { debug_cpmsd("## %7lu close: '%s'\n", get_timer(0), drv_table[drv].img_name); -- cgit v1.2.3