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