summaryrefslogtreecommitdiff
path: root/avr
diff options
context:
space:
mode:
authorLeo C2015-05-06 12:18:39 +0200
committerLeo C2015-05-06 12:18:39 +0200
commitc0abd68b350ffd9852923a66f3ee6c315c94813a (patch)
treeab4a7019bc6e0d30311c73df94c03e6fe559b24a /avr
parent2fa1a7069a9709f8d61a198cec1b1d9b2e275fe1 (diff)
downloadz180-stamp-c0abd68b350ffd9852923a66f3ee6c315c94813a.zip
New command 'loadcpm3' - load 'CPM3.SYS' file. setenv() bugfix
Arg 1 of function setenv() is a __MEMX pointer on AVR.
Diffstat (limited to 'avr')
-rw-r--r--avr/Tupfile2
-rw-r--r--avr/cmd_loadcpm3.c155
-rw-r--r--avr/command_tbl.c9
-rw-r--r--avr/env.c39
4 files changed, 196 insertions, 9 deletions
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. <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;
+ }
+}
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 []);
@@ -127,6 +128,14 @@ 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."
+),
+CMD_TBL_ITEM(
loadi, 2, 0, do_loadihex,
"load intel hex file over serial line",
"[[-]offset]\n"
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;
}
/**