]> cloudbase.mooo.com Git - z180-stamp.git/blob - avr/cmd_boot.c
ce280acf817961dd2cf4e20269cddb610e76ca02
[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[1], 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
122 z80_bus_cmd(Request);
123 z80_read_block (tmp, 0, 3);
124 z80_write(0, 0xc3);
125 z80_write(1, addr);
126 z80_write(2, (addr >> 8));
127
128 z80_bus_cmd(Run);
129 z80_bus_cmd(M_Cycle);
130 z80_bus_cmd(M_Cycle);
131 z80_write_block(tmp, 0, 3);
132 } else
133 z80_bus_cmd(Run);
134
135 z80_bus_cmd(Release);
136
137 return CMD_RET_SUCCESS;
138 }
139
140 static
141 void reset_cpu(bus_cmd_t mode)
142 {
143 restart_z180_serv();
144 z80_bus_cmd(mode);
145 }
146
147
148 command_ret_t do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
149 {
150 (void) cmdtp; (void) flag; (void) argc; (void) argv;
151
152 printf_P(PSTR("CPU now in reset state.\n"));
153
154 reset_cpu(Reset);
155 return CMD_RET_SUCCESS;
156 }
157
158 command_ret_t do_restart(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
159 {
160 (void) cmdtp; (void) flag; (void) argc; (void) argv;
161
162 reset_cpu(Restart);
163
164 return CMD_RET_SUCCESS;
165 }
166
167 static
168 void print_con_usage(char esc)
169 { printf_P(PSTR("\n"
170 "------------------------------------------------\n"
171 " ?,H - This Help\n"
172 " Q,X - Return to command line\n"
173 " R - Reset (Restart) CPU\n"
174 " : - Execute monitor command\n"
175 " \\ - code input:\n"
176 " \\nnn 3 decimal digits character code\n"
177 " \\Xhh 2 hexadecimal digits character code\n"
178 " ^%c - (Escape char) Type again to send itself\n"
179 "key>"
180 ), esc + 0x40);
181 }
182
183 command_ret_t do_console(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
184 {
185 int ch;
186 uint8_t pending;
187 // uint8_t help_prompt = 0;
188 uint8_t code = 0;
189 uint8_t state = 0;
190 char esc_char = (char) getenv_ulong(PSTR(ENV_ESC_CHAR), 16, CONFIG_ESC_CHAR);
191
192 (void) cmdtp; (void) flag; (void) argc; (void) argv;
193
194 printf_P(PSTR("Connecting to CPU. Escape character is '^%c'.\n"),
195 esc_char + 0x40);
196
197 while (1) {
198
199 ATOMIC_BLOCK(ATOMIC_FORCEON) {
200 pending = (Stat & S_CON_PENDING) != 0;
201 Stat &= ~S_CON_PENDING;
202 }
203 if (pending) {
204 uint8_t count = 100;
205 while ((ch = z80_memfifo_getc(fifo_conout)) >= 0 && --count)
206 putchar(ch);
207 }
208
209 if ((ch = my_getchar(0)) >= 0) {
210 switch (state) {
211 case 0:
212 if (ch == esc_char) {
213 state = 1;
214 /* TODO: Timer starten */
215 } else {
216 z80_memfifo_putc(fifo_conin, ch);
217 }
218 break;
219 case 2:
220 printf_P(PSTR("\n"
221 "------------------------------------------------\n"));
222 case 1:
223 state = 0;
224 switch (toupper(ch)) {
225
226 case '?':
227 case 'H':
228 print_con_usage(esc_char);
229 state = 2;
230 break;
231
232 case 'R':
233 reset_cpu(Restart);
234 break;
235
236 case 'X':
237 case 'Q':
238 printf_P(PSTR("\n"));
239 goto quit;
240 break;
241
242 case ':':
243 putchar('\n');
244 int cmdlen = cli_readline(PSTR(": "));
245 if (cmdlen > 0)
246 run_command(console_buffer, 0);
247 break;
248
249 case '\\':
250 code = 0;
251 state = 3;
252 break;
253
254 default:
255 if (ch == esc_char)
256 z80_memfifo_putc(fifo_conin, ch);
257 break;
258 }
259 break;
260 case 3:
261 if (toupper(ch) == 'X') {
262 state = 6;
263 break;
264 }
265 /* fall thru */
266 case 4:
267 case 5:
268 if (isdigit(ch)) {
269 code = code * 10 + ch - '0';
270 state++;
271 } else {
272 if (state > 3)
273 z80_memfifo_putc(fifo_conin, code);
274 z80_memfifo_putc(fifo_conin, ch);
275 state = 0;
276 }
277 if (state > 5) {
278 z80_memfifo_putc(fifo_conin, code);
279 state = 0;
280 }
281 break;
282 case 6:
283 case 7:
284 if (isxdigit(ch)) {
285 ch = toupper(ch);
286 if (ch >= 'A')
287 ch -= 'A' - 10;
288 code = code * 16 + ch - '0';
289 state++;
290 }else {
291 if (state > 6)
292 z80_memfifo_putc(fifo_conin, code);
293 z80_memfifo_putc(fifo_conin, ch);
294 state = 0;
295 }
296 if (state > 7) {
297 z80_memfifo_putc(fifo_conin, code);
298 state = 0;
299 }
300 break;
301 }
302 }
303 }
304 quit:
305 return CMD_RET_SUCCESS;
306 }