From 35edb766593d019b89a3f40b6d6cdd2b50f18032 Mon Sep 17 00:00:00 2001 From: Leo C Date: Tue, 16 Dec 2014 16:03:06 +0100 Subject: Add copyright notice --- avr/env.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'avr/env.c') diff --git a/avr/env.c b/avr/env.c index 017053c..7be7d03 100644 --- a/avr/env.c +++ b/avr/env.c @@ -1,3 +1,9 @@ +/* + * (C) Copyright 2014 Leo C. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + #include "common.h" #include #include @@ -8,7 +14,6 @@ #include "xmalloc.h" #include "crc.h" #include "command.h" - #include "env.h" -- cgit v1.2.3 From c0abd68b350ffd9852923a66f3ee6c315c94813a Mon Sep 17 00:00:00 2001 From: Leo C Date: Wed, 6 May 2015 12:18:39 +0200 Subject: New command 'loadcpm3' - load 'CPM3.SYS' file. setenv() bugfix Arg 1 of function setenv() is a __MEMX pointer on AVR. --- TODO.md | 1 + avr/Tupfile | 2 +- avr/cmd_loadcpm3.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++ avr/command_tbl.c | 9 ++++ avr/env.c | 39 +++++++++++--- include/config.h | 4 ++ 6 files changed, 201 insertions(+), 9 deletions(-) create mode 100644 avr/cmd_loadcpm3.c (limited to 'avr/env.c') diff --git a/TODO.md b/TODO.md index b952c9d..625dd16 100644 --- a/TODO.md +++ b/TODO.md @@ -4,3 +4,4 @@ TODO List - TODO: eliminate xmalloc - TODO: build time directory as lib - TODO: command 'help ' should return success +- TODO: file search path. 'cd' command? diff --git a/avr/Tupfile b/avr/Tupfile index 6be8d79..0c35de4 100644 --- a/avr/Tupfile +++ b/avr/Tupfile @@ -7,7 +7,7 @@ FATFS = $(TOP)/fatfs/src/ff.c SRC = main.c SRC += cli.c cli_readline.c command.c command_tbl.c SRC += cmd_help.c cmd_date.c cmd_mem.c cmd_boot.c cmd_gpio.c cmd_misc.c -SRC += cmd_loadihex.c cmd_sd.c cmd_fat.c +SRC += cmd_loadihex.c cmd_loadcpm3.c cmd_sd.c cmd_fat.c SRC += env.c xmalloc.c con-utils.c print-utils.c getopt-min.c SRC += timer.c serial.c i2c.c pcf8583.c mmc.c SRC += background.c z180-serv.c z80-if.c gpio.c diff --git a/avr/cmd_loadcpm3.c b/avr/cmd_loadcpm3.c new file mode 100644 index 0000000..267cad8 --- /dev/null +++ b/avr/cmd_loadcpm3.c @@ -0,0 +1,155 @@ +/* + * (C) Copyright 2015 Leo C. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include "common.h" +#include +#include +#include +#include + +#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; + FATFS FatFs; + FIL File; + 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_mount(&FatFs, fname, 0); + if (!res) + res = f_open(&File, fname, FA_READ ); + if (res) { + printf_P(PSTR("Error: failed to open '%s'\n"), fname); + f_mount(NULL, fname, 0); + 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); + f_mount(NULL, fname, 0); + + 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; + } +} diff --git a/avr/command_tbl.c b/avr/command_tbl.c index 23d0803..238f132 100644 --- a/avr/command_tbl.c +++ b/avr/command_tbl.c @@ -16,6 +16,7 @@ extern command_ret_t do_env_default(cmd_tbl_t *, int, int, char * const []); extern command_ret_t do_env_set(cmd_tbl_t *, int, int, char * const []); extern command_ret_t do_env_save(cmd_tbl_t *, int, int, char * const []); extern command_ret_t do_loadf(cmd_tbl_t *, int, int, char * const []); +extern command_ret_t do_loadcpm3(cmd_tbl_t *, int, int, char * const []); extern command_ret_t do_loadihex(cmd_tbl_t *, int, int, char * const []); extern command_ret_t do_go(cmd_tbl_t *, int, int, char * const []); extern command_ret_t do_restart(cmd_tbl_t *, int, int, char * const []); @@ -126,6 +127,14 @@ CMD_TBL_ITEM( "load srec_cat prepared image from controller flash", "" ), +CMD_TBL_ITEM( + loadcpm3, 3, 0, do_loadcpm3, + "load CPM3.SYS file", + "[offset] [filename]\n" + " - Load CP/M 3 system file from FAT filesystem. This command makes\n" + " CPMLDR superfluous. Default filename is '"CONFIG_PATH_CPM3SYS"', but\n" + " uses environment variable '"ENV_PATH_CPM3SYS"', if set." +), CMD_TBL_ITEM( loadi, 2, 0, do_loadihex, "load intel hex file over serial line", diff --git a/avr/env.c b/avr/env.c index 7be7d03..a947583 100644 --- a/avr/env.c +++ b/avr/env.c @@ -31,13 +31,17 @@ #define DELIM "\0" const FLASH char default_env[] = { - "bootdelay=" "3" DELIM - "bootcmd=" "reset; loadf; go ${startaddr}" DELIM - "baudrate=" "115200" DELIM - "startaddr=" "0" DELIM + ENV_BAUDRATE "=" "115200" DELIM + ENV_BOOTDELAY "=" "3" DELIM + ENV_BOOTCMD "=" "reset; loadf; go ${startaddr}" DELIM + ENV_PATH_CPM3SYS "=" CONFIG_PATH_CPM3SYS DELIM + ENV_PINALIAS "=" "0:PG5,1:PG4,2:PB4,3:PB5,4:PB6,5:PB7," + "6:PG3,7:PG2,8:PG1,9:PG0,10:PE7" DELIM + ENV_STARTADDRESS "=" "0" DELIM DELIM }; + /* EEPROM storage */ typedef struct environment_s { uint16_t crc; /* CRC16 over data bytes */ @@ -452,7 +456,6 @@ command_ret_t _do_env_set(int flag, int argc, char * const argv[]) env_item_t e, *ep; (void) flag; - debug("Initial value for argc=%d\n", argc); name = argv[1]; value = argv[2]; @@ -519,15 +522,35 @@ command_ret_t _do_env_set(int flag, int argc, char * const argv[]) * @return 0 if ok, 1 on error */ static -int setenv(const char *varname, const char *varvalue) +int setenv(const MEMX char *varname, const char *varvalue) { - const char * const argv[3] = { NULL, varname, varvalue }; + int rc; + +#ifdef __MEMX + char *tmpname = NULL; + if (__builtin_avr_flash_segment(varname) != -1) { + tmpname = malloc(strlen_P(varname)+1); + if (tmpname == NULL) { + printf_P(PSTR("setenv: Out of Memory!\n")); + return 1; + } + strcpy_P(tmpname, varname); + } else + tmpname = (char *) varname; +#endif + + const char * const argv[3] = { NULL, tmpname, varvalue }; int argc = 3; if (varvalue == NULL || varvalue[0] == '\0') --argc; - return (int) _do_env_set(0, argc, (char * const *)argv); + rc = (int) _do_env_set(0, argc, (char * const *)argv); + +#ifdef __MEMX + free(tmpname); +#endif + return rc; } /** diff --git a/include/config.h b/include/config.h index 646835d..7c46b31 100644 --- a/include/config.h +++ b/include/config.h @@ -12,7 +12,11 @@ #define ENV_BAUDRATE "baudrate" #define ENV_BOOTDELAY "bootdelay" #define ENV_BOOTCMD "bootcmd" +#define ENV_PATH_CPM3SYS "cpm3_file" #define ENV_PINALIAS "pin_alias" +#define ENV_STARTADDRESS "startaddress" + +#define CONFIG_PATH_CPM3SYS "1:/cpm3.sys" #define CONFIG_ENV_SIZE 1600 #define CONFIG_ENV_OFFSET 0 -- cgit v1.2.3 From 057817cb1dc71416bc798b5cd592acfcea87efaa Mon Sep 17 00:00:00 2001 From: Leo C Date: Tue, 9 Jun 2015 17:20:01 +0200 Subject: loadcpm3 for new memory map --- avr/cmd_loadcpm3.c | 52 ++++++++++++++++++++++++++++++++++++---------------- avr/command_tbl.c | 10 ++++++---- avr/env.c | 2 +- include/config.h | 22 +++++++++++++++------- z180/z180reg.inc | 5 ++--- 5 files changed, 60 insertions(+), 31 deletions(-) (limited to 'avr/env.c') diff --git a/avr/cmd_loadcpm3.c b/avr/cmd_loadcpm3.c index 3f1bbe1..da1be37 100644 --- a/avr/cmd_loadcpm3.c +++ b/avr/cmd_loadcpm3.c @@ -27,7 +27,7 @@ * len = Length in pages of module to read * */ -int load(FIL *File, uint16_t addr, uint8_t len) +int load(FIL *File, uint32_t addr, uint8_t len) { uint8_t buffer[RS]; unsigned int br; /* bytes read */ @@ -63,12 +63,12 @@ command_ret_t do_loadcpm3(cmd_tbl_t *cmdtp, int flag, int argc, char * const arg uint8_t res_len; uint16_t bank_top; uint8_t bank_len; - uint16_t osentry_adr = 0; - long offset = 0; + uint16_t osentry_addr = 0; + uint32_t common_base, banked_base; char *fname; FIL File; - /* TODO: put CONFIG_PATH_CPM3SYS in flash */ - char default_fname[] = CONFIG_PATH_CPM3SYS; + /* TODO: put CONFIG_CPM3_SYSFILE in flash */ + char default_fname[] = CONFIG_CPM3_SYSFILE; unsigned int br; /* bytes read */ uint8_t buffer[RS]; int res; @@ -76,15 +76,20 @@ command_ret_t do_loadcpm3(cmd_tbl_t *cmdtp, int flag, int argc, char * const arg (void) cmdtp; (void) flag; - if (argc > 1) - offset = strtoul(argv[1], NULL, 16); + 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); - fname = getenv(PSTR(ENV_PATH_CPM3SYS)); + if (argc > 3) + banked_base = strtoul(argv[3], NULL, 16); + if (argc > 2) + banked_base = strtoul(argv[2], NULL, 16); + fname = getenv(PSTR(ENV_CPM3_SYSFILE)); if (argc > 2) { fname = argv[2]; } - if (fname == NULL || *fname == '\0') fname = default_fname; @@ -105,7 +110,7 @@ command_ret_t do_loadcpm3(cmd_tbl_t *cmdtp, int flag, int argc, char * const arg res_len = buffer[1]; bank_top = buffer[2] << 8; bank_len = buffer[3]; - osentry_adr = buffer[4] + (buffer[5] << 8); + osentry_addr = buffer[4] + (buffer[5] << 8); /* read display info */ res = f_read(&File, buffer, RS, &br); @@ -121,11 +126,11 @@ command_ret_t do_loadcpm3(cmd_tbl_t *cmdtp, int flag, int argc, char * const arg /* Main System Load */ /* Load Common Portion of System */ - if ((res = load(&File, mem_top, res_len)) != 0) + if ((res = load(&File, common_base + mem_top, res_len)) != 0) goto out; /* Load Banked Portion of System */ - res = load(&File, bank_top, bank_len); + res = load(&File, banked_base + bank_top, bank_len); out: f_close(&File); @@ -134,16 +139,31 @@ out: 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); + if (res_len != 0) { + if (osentry_addr + common_base > 0xffff) { + z80_bus_cmd(Request); + if (z80_read(osentry_addr + common_base) == 0xc3) { + osentry_addr = z80_read(osentry_addr+common_base+1) + + (z80_read(osentry_addr + common_base+2) << 8); + } + z80_bus_cmd(Release); + if (banked_base + osentry_addr > 0xffff) + osentry_addr = 0; + } + setenv_hex(PSTR(ENV_STARTADDRESS), osentry_addr); + } printf_P(PSTR("Loaded: Resident: ")); if (res_len != 0) - printf_P(PSTR("0x%.4X-0x%.4X, "), mem_top-res_len*256, mem_top-1); + printf_P(PSTR("0x%.5lX-0x%.5lX, "), + (common_base + mem_top) - res_len*256, + (common_base + 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); + printf_P(PSTR("0x%.5lX-0x%.5lX\n"), + (banked_base + bank_top) - bank_len*256, + (banked_base + bank_top) - 1); else printf_P(PSTR(" - \n")); diff --git a/avr/command_tbl.c b/avr/command_tbl.c index a9cc2bd..72a87b9 100644 --- a/avr/command_tbl.c +++ b/avr/command_tbl.c @@ -151,10 +151,12 @@ CMD_TBL_ITEM( CMD_TBL_ITEM( loadcpm3, 3, 0, do_loadcpm3, "load CPM3.SYS file", - "[offset] [filename]\n" - " - Load CP/M 3 system file from FAT filesystem. This command makes\n" - " CPMLDR superfluous. Default filename is '"CONFIG_PATH_CPM3SYS"', but\n" - " uses environment variable '"ENV_PATH_CPM3SYS"', if set." + "[filename] [common base] [banked base]] \n" + " Load CP/M 3 system file from FAT filesystem. This command makes\n" + " CPMLDR superfluous. Uses the following environment variable if set:\n" + " '"ENV_CPM3_SYSFILE"' File to load. Default is '"CONFIG_CPM3_SYSFILE"'.\n" + " '"ENV_CPM3_COMMON_BASE"' Default is '"CONFIG_CPM3_COMMON_BASE_STR"'.\n" + " '"ENV_CPM3_BANKED_BASE"' Default is '"CONFIG_CPM3_BANKED_BASE_STR"'.\n" ), CMD_TBL_ITEM( loadi, 2, 0, do_loadihex, diff --git a/avr/env.c b/avr/env.c index a947583..9ea355f 100644 --- a/avr/env.c +++ b/avr/env.c @@ -34,7 +34,7 @@ const FLASH char default_env[] = { ENV_BAUDRATE "=" "115200" DELIM ENV_BOOTDELAY "=" "3" DELIM ENV_BOOTCMD "=" "reset; loadf; go ${startaddr}" DELIM - ENV_PATH_CPM3SYS "=" CONFIG_PATH_CPM3SYS DELIM + ENV_CPM3_SYSFILE "=" CONFIG_CPM3_SYSFILE DELIM ENV_PINALIAS "=" "0:PG5,1:PG4,2:PB4,3:PB5,4:PB6,5:PB7," "6:PG3,7:PG2,8:PG1,9:PG0,10:PE7" DELIM ENV_STARTADDRESS "=" "0" DELIM diff --git a/include/config.h b/include/config.h index a403520..c7c4511 100644 --- a/include/config.h +++ b/include/config.h @@ -9,15 +9,17 @@ /* Environment variables */ -#define ENV_BAUDRATE "baudrate" -#define ENV_BOOTDELAY "bootdelay" +#define ENV_BAUDRATE "baudrate" +#define ENV_BOOTDELAY "bootdelay" #define ENV_BOOTCMD "bootcmd" -#define ENV_PATH_CPM3SYS "cpm3_file" -#define ENV_PINALIAS "pin_alias" -#define ENV_STARTADDRESS "startaddress" -#define ENV_ESC_CHAR "esc_char" -#define CONFIG_PATH_CPM3SYS "1:/cpm3.sys" +#define ENV_CPM3_SYSFILE "cpm3_file" +#define ENV_CPM3_COMMON_BASE "cpm3_commonbase" +#define ENV_CPM3_BANKED_BASE "cpm3_bankedbase" + +#define ENV_PINALIAS "pin_alias" +#define ENV_STARTADDRESS "startaddress" +#define ENV_ESC_CHAR "esc_char" #define CONFIG_ENV_SIZE 1600 #define CONFIG_ENV_OFFSET 0 @@ -28,6 +30,12 @@ #define CONFIG_BOOTDELAY 4 //#define CONFIG_ZERO_BOOTDELAY_CHECK 1 +#define CONFIG_CPM3_SYSFILE "1:/cpm3.sys" +#define CONFIG_CPM3_COMMON_BASE 0xC000 +#define CONFIG_CPM3_BANKED_BASE 0x0 +#define CONFIG_CPM3_COMMON_BASE_STR "C000" +#define CONFIG_CPM3_BANKED_BASE_STR "0" + #define CONFIG_CMD_MEMTEST #define CONFIG_MX_CYCLIC #define CONFIG_SYS_RAMSIZE_MAX (1l<<19) /* max. addressable memory */ diff --git a/z180/z180reg.inc b/z180/z180reg.inc index a248f5f..2666867 100644 --- a/z180/z180reg.inc +++ b/z180/z180reg.inc @@ -130,8 +130,8 @@ bcr1h equ IOBASE+2Fh ; dstat equ IOBASE+30h ;DMA Status Register b2m DE1,7 ;DMA enable ch 1,0 b2m DE0,6 ; - b2m DWE1,5 ;DMA Enable Bit Write Enable 1,0 - b2m DWE0,4 ; + b2m NDWE1,5 ;DMA Enable Bit Write Enable 1,0 + b2m NDWE0,4 ; b2m DIE1,3 ;DMA Interrupt Enable 1,0 b2m DIE0,2 ; b2m DME,0 ;DMA Master enable @@ -195,4 +195,3 @@ IV$ASCI0 equ 14 ;ASCI channel 0 IV$ASCI1 equ 16 ;ASCI channel 1 (lowest priority) .list - -- cgit v1.2.3