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