]> cloudbase.mooo.com Git - z180-stamp.git/blob - avr/cmd_boot.c
b8799aa350e462456c069089f094e57f87d4ff69
[z180-stamp.git] / avr / cmd_boot.c
1 /*
2 * (C) Copyright 2014 Leo C. <erbl259-lmu@yahoo.de>
3 *
4 * (C) Copyright 2000-2003
5 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
6 *
7 * SPDX-License-Identifier: GPL-2.0+
8 */
9
10 /*
11 * Misc boot support
12 */
13 #include "common.h"
14 #include <stdlib.h>
15 #include <ctype.h>
16 #include <util/atomic.h>
17
18 #include "command.h"
19 #include "cli_readline.h"
20 #include "cli.h"
21 #include "env.h"
22 #include "con-utils.h"
23 #include "z80-if.h"
24 #include "z180-serv.h"
25 #include "debug.h"
26
27 /* ugly hack to get Z180 loadfile into flash memory */
28 #define const const FLASH
29 #include "../z180/hdrom.h"
30 #undef const
31
32
33
34 static void z80_load_mem(void)
35 {
36 unsigned sec = 0;
37 uint32_t sec_base = hdrom_start;
38
39 printf_P(PSTR("Loading Z180 memory... \n"));
40
41 while (sec < hdrom_sections) {
42 printf_P(PSTR(" From: 0x%.5lX to: 0x%.5lX (%5li bytes)\n"),
43 hdrom_address[sec],
44 hdrom_address[sec]+hdrom_length_of_sections[sec] - 1,
45 hdrom_length_of_sections[sec]);
46
47 z80_write_block_P((const FLASH unsigned char *) &hdrom[sec_base], /* src */
48 hdrom_address[sec], /* dest */
49 hdrom_length_of_sections[sec]); /* len */
50 sec_base+=hdrom_length_of_sections[sec];
51 sec++;
52 }
53 }
54
55 command_ret_t do_loadf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
56 {
57 (void) cmdtp; (void) flag; (void) argc; (void) argv;
58
59 if (z80_bus_state() & ZST_RUNNING) {
60 my_puts_P(PSTR("Can't load while CPU is running!\n"));
61 return CMD_RET_FAILURE;
62 }
63 if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
64 my_puts_P(PSTR("Bus timeout\n"));
65 return CMD_RET_FAILURE;
66 }
67 z80_load_mem();
68 z80_bus_cmd(Release);
69
70 return CMD_RET_SUCCESS;
71 }
72
73
74 command_ret_t do_busreq_pulse(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
75 {
76 uint16_t count=1;
77
78 (void) cmdtp; (void) flag;
79
80 if (!(z80_bus_state() & ZST_RUNNING)) {
81 printf_P(PSTR("## CPU is not running!\n"));
82 return CMD_RET_FAILURE;
83 }
84
85 if (argc > 1)
86 count = (uint16_t) strtoul(argv[2], NULL, 16);
87
88 z80_bus_cmd(Request);
89 while (count--)
90 z80_bus_cmd(M_Cycle);
91
92 return CMD_RET_SUCCESS;
93 }
94
95
96 command_ret_t do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
97 {
98 uint32_t addr;
99
100 (void) cmdtp; (void) flag;
101
102 if (argc < 2)
103 return CMD_RET_USAGE;
104 addr = strtoul(argv[1], NULL, 16);
105 if (addr >= (1UL<<16)) {
106 printf_P(PSTR("## Startaddress 0x%05lx too high.\n"
107 " (Out of logical address space (0x00000-0x0ffff))\n"),
108 addr);
109 return CMD_RET_FAILURE;
110 }
111
112 if (z80_bus_state() & ZST_RUNNING) {
113 printf_P(PSTR("## CPU allready running!\n"));
114 return CMD_RET_FAILURE;
115 }
116
117 printf_P(PSTR("## Starting application at 0x%04lx ...\n"), addr);
118
119 if (addr != 0) {
120 uint8_t tmp[3];
121 uint_fast8_t i;
122
123 z80_bus_cmd(Request);
124 for (i = 0; i < 3; i++)
125 tmp[i] = z80_read(i);
126 z80_write(0, 0xc3);
127 z80_write(1, addr);
128 z80_write(2, (addr >> 8));
129
130 z80_bus_cmd(Run);
131 z80_bus_cmd(M_Cycle);
132 z80_bus_cmd(M_Cycle);
133 for (i = 0; i < 3; i++)
134 z80_write(i, tmp[i]);
135 } else
136 z80_bus_cmd(Run);
137
138 z80_bus_cmd(Release);
139
140 return CMD_RET_SUCCESS;
141 }
142
143 static
144 void reset_cpu(bus_cmd_t mode)
145 {
146 restart_z180_serv();
147 z80_bus_cmd(mode);
148 }
149
150
151 command_ret_t do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
152 {
153 (void) cmdtp; (void) flag; (void) argc; (void) argv;
154
155 printf_P(PSTR("CPU now in reset state.\n"));
156
157 reset_cpu(Reset);
158 return CMD_RET_SUCCESS;
159 }
160
161 command_ret_t do_restart(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
162 {
163 (void) cmdtp; (void) flag; (void) argc; (void) argv;
164
165 reset_cpu(Restart);
166
167 return CMD_RET_SUCCESS;
168 }
169
170 static
171 void print_con_usage(char esc)
172 { printf_P(PSTR("\n"
173 "------------------------------------------------\n"
174 " ?,H - This Help\n"
175 " Q,X - Return to command line\n"
176 " R - Reset (Restart) CPU\n"
177 " : - Execute monitor command\n"
178 " \\ - code input:\n"
179 " \\nnn 3 decimal digits character code\n"
180 " \\Xhh 2 hexadecimal digits character code\n"
181 " ^%c - (Escape char) Type again to send itself\n"
182 "key>"
183 ), esc + 0x40);
184 }
185
186 command_ret_t do_console(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
187 {
188 int ch;
189 uint8_t pending;
190 // uint8_t help_prompt = 0;
191 uint8_t code = 0;
192 uint8_t state = 0;
193 char esc_char = (char) getenv_ulong(PSTR(ENV_ESC_CHAR), 16, CONFIG_ESC_CHAR);
194
195 (void) cmdtp; (void) flag; (void) argc; (void) argv;
196
197 printf_P(PSTR("Connecting to CPU. Escape character is '^%c'.\n"),
198 esc_char + 0x40);
199
200 while (1) {
201
202 ATOMIC_BLOCK(ATOMIC_FORCEON) {
203 pending = (Stat & S_CON_PENDING) != 0;
204 Stat &= ~S_CON_PENDING;
205 }
206 if (pending) {
207 uint8_t count = 100;
208 while ((ch = z80_memfifo_getc(fifo_conout)) >= 0 && --count)
209 putchar(ch);
210 }
211
212 if ((ch = my_getchar(0)) >= 0) {
213 switch (state) {
214 case 0:
215 if (ch == esc_char) {
216 state = 1;
217 /* TODO: Timer starten */
218 } else {
219 z80_memfifo_putc(fifo_conin, ch);
220 }
221 break;
222 case 2:
223 printf_P(PSTR("\n"
224 "------------------------------------------------\n"));
225 case 1:
226 state = 0;
227 switch (toupper(ch)) {
228
229 case '?':
230 case 'H':
231 print_con_usage(esc_char);
232 state = 2;
233 break;
234
235 case 'R':
236 reset_cpu(Restart);
237 break;
238
239 case 'X':
240 case 'Q':
241 printf_P(PSTR("\n"));
242 goto quit;
243 break;
244
245 case ':':
246 putchar('\n');
247 int cmdlen = cli_readline(PSTR(": "));
248 if (cmdlen > 0)
249 run_command(console_buffer, 0);
250 break;
251
252 case '\\':
253 code = 0;
254 state = 3;
255 break;
256
257 default:
258 if (ch == esc_char)
259 z80_memfifo_putc(fifo_conin, ch);
260 break;
261 }
262 break;
263 case 3:
264 if (toupper(ch) == 'X') {
265 state = 6;
266 break;
267 }
268 /* fall thru */
269 case 4:
270 case 5:
271 if (isdigit(ch)) {
272 code = code * 10 + ch - '0';
273 state++;
274 } else {
275 if (state > 3)
276 z80_memfifo_putc(fifo_conin, code);
277 z80_memfifo_putc(fifo_conin, ch);
278 state = 0;
279 }
280 if (state > 5) {
281 z80_memfifo_putc(fifo_conin, code);
282 state = 0;
283 }
284 break;
285 case 6:
286 case 7:
287 if (isxdigit(ch)) {
288 ch = toupper(ch);
289 if (ch >= 'A')
290 ch -= 'A' - 10;
291 code = code * 16 + ch - '0';
292 state++;
293 }else {
294 if (state > 6)
295 z80_memfifo_putc(fifo_conin, code);
296 z80_memfifo_putc(fifo_conin, ch);
297 state = 0;
298 }
299 if (state > 7) {
300 z80_memfifo_putc(fifo_conin, code);
301 state = 0;
302 }
303 break;
304 }
305 }
306 }
307 quit:
308 return CMD_RET_SUCCESS;
309 }