]> cloudbase.mooo.com Git - z180-stamp.git/commitdiff
New command 'loadcpm3' - load 'CPM3.SYS' file. setenv() bugfix
authorLeo C <erbl259-lmu@yahoo.de>
Wed, 6 May 2015 10:18:39 +0000 (12:18 +0200)
committerLeo C <erbl259-lmu@yahoo.de>
Wed, 6 May 2015 10:18:39 +0000 (12:18 +0200)
Arg 1 of function setenv() is a __MEMX pointer on AVR.

TODO.md
avr/Tupfile
avr/cmd_loadcpm3.c [new file with mode: 0644]
avr/command_tbl.c
avr/env.c
include/config.h

diff --git a/TODO.md b/TODO.md
index b952c9dced76ac153d02a6ce982773251e31383f..625dd16b6f49705c7a5c3eed2040661c1edb8fae 100644 (file)
--- a/TODO.md
+++ b/TODO.md
@@ -4,3 +4,4 @@ TODO List
 - TODO: eliminate xmalloc
 - TODO: build time directory as lib
 - TODO: command 'help <topic>' should return success
+- TODO: file search path. 'cd' command?
index 6be8d7976e3317fb089bc7d582359e637b51ad85..0c35de4cfb94e9d5f38424d40d4c04264315d98e 100644 (file)
@@ -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 (file)
index 0000000..267cad8
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * (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;
+       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;
+       }
+}
index 23d080372dd2db3fa950e5a63f410a27b5438de5..238f132012b811466f69e8346cbde6ec4f4dfdca 100644 (file)
@@ -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",
index 7be7d03501f102a7fbed6367262272859d3f8ead..a947583a6fe273ce4b3710c5b642e616fb216534 100644 (file)
--- a/avr/env.c
+++ b/avr/env.c
 #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;
 }
 
 /**
index 646835da8402d4ba51cd78f4669bd71d4a1000d7..7c46b31bf4ba618157b83376ba652d18344e94fd 100644 (file)
 #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