]> cloudbase.mooo.com Git - z180-stamp.git/blame - avr/cmd_loadcpm3.c
Add build configuration for ATmega2561
[z180-stamp.git] / avr / cmd_loadcpm3.c
CommitLineData
c0abd68b
L
1/*
2 * (C) Copyright 2015 Leo C. <erbl259-lmu@yahoo.de>
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7#include "common.h"
8#include <stdlib.h>
9#include <ctype.h>
10#include <string.h>
11#include <stdbool.h>
12
13#include "command.h"
14#include "env.h"
15#include "ff.h"
16#include "con-utils.h"
17#include "z80-if.h"
18#include "debug.h"
19
20
21#define RS 128 /* CP/M record size */
22
23/*
24 * Load Routine
25 *
26 * Input: addr = Page Address of load top
27 * len = Length in pages of module to read
28 *
29 */
057817cb 30int load(FIL *File, uint32_t addr, uint8_t len)
c0abd68b
L
31{
32 uint8_t buffer[RS];
33 unsigned int br; /* bytes read */
34 int res;
35
36 len *= 2; /* length in records of module */
37 //debug("## load: addr: 0x%.4X, records: 0x%.4X, (%u)\n", addr, len, len);
38
39 for (; len; len--) {
40 addr -= RS;
41 res = f_read(File, buffer, RS, &br);
42 if (res || br != RS) {
43 return 1;
44 }
45
46 if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
47 my_puts_P(PSTR("Bus timeout\n"));
48 return 2;
49 }
50 z80_write_block(buffer, addr, RS);
51 z80_bus_cmd(Release);
52 //debug("## written: 0x%.4X\n", addr);
53 }
54
55 return 0;
56}
57
ad9bc17c 58#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
c0abd68b
L
59
60command_ret_t do_loadcpm3(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
61{
62 uint16_t mem_top;
63 uint8_t res_len;
64 uint16_t bank_top;
65 uint8_t bank_len;
057817cb
L
66 uint16_t osentry_addr = 0;
67 uint32_t common_base, banked_base;
c0abd68b 68 char *fname;
c0abd68b 69 FIL File;
057817cb
L
70 /* TODO: put CONFIG_CPM3_SYSFILE in flash */
71 char default_fname[] = CONFIG_CPM3_SYSFILE;
c0abd68b
L
72 unsigned int br; /* bytes read */
73 uint8_t buffer[RS];
74 int res;
75
76 (void) cmdtp; (void) flag;
77
78
057817cb
L
79 common_base = getenv_ulong(PSTR(ENV_CPM3_COMMON_BASE), 16,
80 CONFIG_CPM3_COMMON_BASE);
81 banked_base = getenv_ulong(PSTR(ENV_CPM3_BANKED_BASE), 16,
82 CONFIG_CPM3_BANKED_BASE);
c0abd68b 83
057817cb
L
84 if (argc > 3)
85 banked_base = strtoul(argv[3], NULL, 16);
86 if (argc > 2)
98aac4d0 87 common_base = strtoul(argv[2], NULL, 16);
c0abd68b 88
057817cb 89 fname = getenv(PSTR(ENV_CPM3_SYSFILE));
98aac4d0
L
90 if (argc > 1) {
91 fname = argv[1];
c0abd68b 92 }
c0abd68b
L
93 if (fname == NULL || *fname == '\0')
94 fname = default_fname;
95
bbd45c46 96 res = f_open(&File, fname, FA_READ );
c0abd68b
L
97 if (res) {
98 printf_P(PSTR("Error: failed to open '%s'\n"), fname);
c0abd68b
L
99 return CMD_RET_FAILURE;
100 }
101
102 printf_P(PSTR("Loading: '%s'...\n"), fname);
103
104 /* read the load record */
105 res = f_read(&File, buffer, RS, &br);
106 if (res || br != RS)
107 goto out;
108
109 mem_top = buffer[0] << 8;
110 res_len = buffer[1];
111 bank_top = buffer[2] << 8;
112 bank_len = buffer[3];
057817cb 113 osentry_addr = buffer[4] + (buffer[5] << 8);
c0abd68b
L
114
115 /* read display info */
116 res = f_read(&File, buffer, RS, &br);
117 if (res || br != RS)
118 goto out;
119
120 /* print the info */
121 buffer[RS-1] = '$';
122 uint8_t *p = memchr(buffer, '$', RS);
123 *p = '\0';
124 my_puts((char *)buffer);
125
126 /* Main System Load */
127
128 /* Load Common Portion of System */
057817cb 129 if ((res = load(&File, common_base + mem_top, res_len)) != 0)
c0abd68b
L
130 goto out;
131
132 /* Load Banked Portion of System */
057817cb 133 res = load(&File, banked_base + bank_top, bank_len);
c0abd68b
L
134
135out:
136 f_close(&File);
c0abd68b
L
137
138 if (res) {
139 printf_P(PSTR("Error: failed to read '%s'\n"), fname);
140 return CMD_RET_FAILURE;
141 } else {
057817cb
L
142 if (res_len != 0) {
143 if (osentry_addr + common_base > 0xffff) {
144 z80_bus_cmd(Request);
145 if (z80_read(osentry_addr + common_base) == 0xc3) {
146 osentry_addr = z80_read(osentry_addr+common_base+1) +
147 (z80_read(osentry_addr + common_base+2) << 8);
148 }
149 z80_bus_cmd(Release);
150 if (banked_base + osentry_addr > 0xffff)
151 osentry_addr = 0;
152 }
153 setenv_hex(PSTR(ENV_STARTADDRESS), osentry_addr);
154 }
c0abd68b
L
155 printf_P(PSTR("Loaded: Resident: "));
156 if (res_len != 0)
057817cb
L
157 printf_P(PSTR("0x%.5lX-0x%.5lX, "),
158 (common_base + mem_top) - res_len*256,
159 (common_base + mem_top) - 1);
c0abd68b
L
160 else
161 printf_P(PSTR(" - "));
162 printf_P(PSTR("Banked: "));
163 if (bank_len != 0)
057817cb
L
164 printf_P(PSTR("0x%.5lX-0x%.5lX\n"),
165 (banked_base + bank_top) - bank_len*256,
166 (banked_base + bank_top) - 1);
c0abd68b
L
167 else
168 printf_P(PSTR(" - \n"));
169
170 return CMD_RET_SUCCESS;
171 }
172}