X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp.git/blobdiff_plain/e0b20381498f524cb1902dc486249a967edf2592..228b1c5f79749940e11247bd97626e21df7033bd:/avr/cmd_loadcpm3.c diff --git a/avr/cmd_loadcpm3.c b/avr/cmd_loadcpm3.c index 324a40d..39e3278 100644 --- a/avr/cmd_loadcpm3.c +++ b/avr/cmd_loadcpm3.c @@ -1,18 +1,19 @@ /* - * (C) Copyright 2015 Leo C. + * (C) Copyright 2015,2016 Leo C. * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: GPL-2.0 */ -#include "common.h" -#include +/* + * See CP/M 3 System Manual, Appendix D: CPM3.SYS File Format + */ + +#include "cmd_loadcpm3.h" #include -#include -#include -#include "command.h" #include "env.h" #include "ff.h" +#include "eval_arg.h" #include "con-utils.h" #include "z80-if.h" #include "debug.h" @@ -20,6 +21,8 @@ #define RS 128 /* CP/M record size */ +#define FSIZE_t DWORD + /* * Load Routine * @@ -57,17 +60,17 @@ int load(FIL *File, uint32_t addr, uint8_t len) #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -command_ret_t do_loadcpm3(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +command_ret_t do_loadcpm3(cmd_tbl_t *cmdtp, uint_fast8_t 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_addr = 0; - uint32_t common_base, banked_base; + uint32_t common_base = 0; + uint32_t banked_base; char *fname; FIL File; - /* TODO: put CONFIG_CPM3_SYSFILE in flash */ char default_fname[] = CONFIG_CPM3_SYSFILE; unsigned int br; /* bytes read */ uint8_t buffer[RS]; @@ -76,17 +79,17 @@ command_ret_t do_loadcpm3(cmd_tbl_t *cmdtp, int flag, int argc, char * const arg (void) cmdtp; (void) flag; - common_base = getenv_ulong(PSTR(ENV_CPM3_COMMON_BASE), 16, - CONFIG_CPM3_COMMON_BASE); + //common_base = getenv_ulong(PSTR(ENV_CPM3_COMMON_BASE), 16, + // CONFIG_CPM3_COMMON_BASE); banked_base = getenv_ulong(PSTR(ENV_CPM3_BANKED_BASE), 16, CONFIG_CPM3_BANKED_BASE); if (argc > 3) - banked_base = strtoul(argv[3], NULL, 16); + banked_base = eval_arg(argv[3], NULL); if (argc > 2) - common_base = strtoul(argv[2], NULL, 16); + common_base = eval_arg(argv[2], NULL); - fname = getenv(PSTR(ENV_CPM3_SYSFILE)); + fname = getenv_str(PSTR(ENV_CPM3_SYSFILE)); if (argc > 1) { fname = argv[1]; } @@ -123,6 +126,23 @@ command_ret_t do_loadcpm3(cmd_tbl_t *cmdtp, int flag, int argc, char * const arg *p = '\0'; my_puts((char *)buffer); + if (common_base == 0) { + /* read common base + * http://www.seasip.info/Cpm/scb.html + */ + FSIZE_t common_base_ofs = ((res_len - 6) << 8) + 2*RS + RS-7; + FSIZE_t cur_pos = f_tell(&File); + if ((res = f_lseek(&File, common_base_ofs)) || + (res = f_read(&File, buffer, 2, &br)) || + (br != 2) || + (res = f_lseek(&File, cur_pos))) + goto out; + common_base = (uint16_t) buffer[0] + (buffer[1] << 8); + setenv_hex(PSTR(ENV_CPM3_COMMON_BASE), common_base); + } + + setenv_hex(PSTR(ENV_CPM3_SCB), mem_top - ((res_len - (6 - 1)) << 8) + common_base); + /* Main System Load */ /* Load Common Portion of System */