diff options
Diffstat (limited to 'avr/cmd_loadcpm3.c')
-rw-r--r-- | avr/cmd_loadcpm3.c | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/avr/cmd_loadcpm3.c b/avr/cmd_loadcpm3.c new file mode 100644 index 0000000..fd685b2 --- /dev/null +++ b/avr/cmd_loadcpm3.c @@ -0,0 +1,151 @@ +/* + * (C) Copyright 2015 Leo C. <erbl259-lmu@yahoo.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include "common.h" +#include <stdlib.h> +#include <ctype.h> +#include <string.h> +#include <stdbool.h> + +#include "command.h" +#include "env.h" +#include "ff.h" +#include "con-utils.h" +#include "z80-if.h" +#include "debug.h" + + +#define RS 128 /* CP/M record size */ + +/* + * Load Routine + * + * Input: addr = Page Address of load top + * len = Length in pages of module to read + * + */ +int load(FIL *File, uint16_t addr, uint8_t len) +{ + uint8_t buffer[RS]; + unsigned int br; /* bytes read */ + int res; + + len *= 2; /* length in records of module */ + //debug("## load: addr: 0x%.4X, records: 0x%.4X, (%u)\n", addr, len, len); + + for (; len; len--) { + addr -= RS; + res = f_read(File, buffer, RS, &br); + if (res || br != RS) { + return 1; + } + + if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) { + my_puts_P(PSTR("Bus timeout\n")); + return 2; + } + z80_write_block(buffer, addr, RS); + z80_bus_cmd(Release); + //debug("## written: 0x%.4X\n", addr); + } + + return 0; +} + + +command_ret_t do_loadcpm3(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + uint16_t mem_top; + uint8_t res_len; + uint16_t bank_top; + uint8_t bank_len; + uint16_t osentry_adr = 0; + long offset = 0; + char *fname; + FIL File; + /* TODO: put CONFIG_PATH_CPM3SYS in flash */ + char default_fname[] = CONFIG_PATH_CPM3SYS; + unsigned int br; /* bytes read */ + uint8_t buffer[RS]; + int res; + + (void) cmdtp; (void) flag; + + + if (argc > 1) + offset = strtoul(argv[1], NULL, 16); + + fname = getenv(PSTR(ENV_PATH_CPM3SYS)); + + if (argc > 2) { + fname = argv[2]; + } + + if (fname == NULL || *fname == '\0') + fname = default_fname; + + res = f_open(&File, fname, FA_READ ); + if (res) { + printf_P(PSTR("Error: failed to open '%s'\n"), fname); + return CMD_RET_FAILURE; + } + + printf_P(PSTR("Loading: '%s'...\n"), fname); + + /* read the load record */ + res = f_read(&File, buffer, RS, &br); + if (res || br != RS) + goto out; + + mem_top = buffer[0] << 8; + res_len = buffer[1]; + bank_top = buffer[2] << 8; + bank_len = buffer[3]; + osentry_adr = buffer[4] + (buffer[5] << 8); + + /* read display info */ + res = f_read(&File, buffer, RS, &br); + if (res || br != RS) + goto out; + + /* print the info */ + buffer[RS-1] = '$'; + uint8_t *p = memchr(buffer, '$', RS); + *p = '\0'; + my_puts((char *)buffer); + + /* Main System Load */ + + /* Load Common Portion of System */ + if ((res = load(&File, mem_top, res_len)) != 0) + goto out; + + /* Load Banked Portion of System */ + res = load(&File, bank_top, bank_len); + +out: + f_close(&File); + + if (res) { + printf_P(PSTR("Error: failed to read '%s'\n"), fname); + return CMD_RET_FAILURE; + } else { + if (res_len != 0) + setenv_hex(PSTR(ENV_STARTADDRESS), osentry_adr); + printf_P(PSTR("Loaded: Resident: ")); + if (res_len != 0) + printf_P(PSTR("0x%.4X-0x%.4X, "), mem_top-res_len*256, mem_top-1); + else + printf_P(PSTR(" - ")); + printf_P(PSTR("Banked: ")); + if (bank_len != 0) + printf_P(PSTR("0x%.4X-0x%.4X\n"), bank_top-bank_len*256, bank_top-1); + else + printf_P(PSTR(" - \n")); + + return CMD_RET_SUCCESS; + } +} |