2 * (C) Copyright 2014-2016 Leo C. <erbl259-lmu@yahoo.de>
4 * (C) Copyright 2000-2003
5 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
7 * SPDX-License-Identifier: GPL-2.0
14 #include <util/atomic.h>
16 #include "cli_readline.h" /* console_buffer[] */
17 #include "cli.h" /* run_command() */
20 #include "con-utils.h"
21 #include "getopt-min.h"
23 #include "z180-serv.h" /* restart_z180_serv() */
26 /* ugly hack to get Z180 loadfile into flash memory */
27 #define const const FLASH
28 #include "../z180/hdrom.h"
29 #include "../z180/cfboot.h"
33 command_ret_t
do_loadf(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc UNUSED
, char * const argv
[] UNUSED
)
35 if (z80_bus_state() & ZST_RUNNING
)
36 cmd_error(CMD_RET_FAILURE
, ERUNNING
, NULL
);
37 z80_bus_request_or_exit();
38 z80_load_mem(2, hdrom
,
41 hdrom_length_of_sections
);
45 return CMD_RET_SUCCESS
;
49 void print_vars(char *title
)
52 zstate_t state
= z80_bus_state();
54 if((state
& ZST_ACQUIRED
) == 0)
57 z80_read_block(buf
, 9, sizeof buf
);
59 if((state
& ZST_ACQUIRED
) == 0)
62 printf_P(PSTR("%s: stage: %d, flag: 0x%.02x, result: %d, IDE stat/error: 0x%.02x/0x%.02x\n"),
63 title
, buf
[0], buf
[1], buf
[2], buf
[3], buf
[4]);
73 * -i Partition id (52)
79 command_ret_t
do_bootcf(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc
, char * const argv
[])
99 int_fast8_t verbosity
= 0;
100 uint8_t default_stages
;
103 /* get default values */
104 memcpy_P(&boot_param
, cfboot
, sizeof boot_param
);
105 default_stages
= boot_param
.stages
;
108 while ((opt
= getopt(argc
, argv
, PSTR("vna:s:c:t:i:"))) != -1) {
114 if (boot_param
.stages
> 0)
118 val
= eval_arg(optarg
, NULL
);
119 if (val
< 0x100 || val
> 0xFE00) {
120 printf_P(PSTR("Address out of range: 0x%.4lX\n"), val
);
121 return CMD_RET_FAILURE
;
123 boot_param
.loadaddr
= val
;
126 val
= eval_arg(optarg
, NULL
);
128 printf_P(PSTR("Start sector out of range: 0x%lX\n"), val
);
129 return CMD_RET_FAILURE
;
131 boot_param
.sec_start
= val
;
134 val
= eval_arg(optarg
, NULL
);
136 printf_P(PSTR("Sector count out of range: 0x%lX\n"), val
);
137 return CMD_RET_FAILURE
;
139 boot_param
.sec_cnt
= val
;
142 val
= eval_arg(optarg
, NULL
);
143 if (val
< 0x1 || val
> 0xFFFF) {
144 printf_P(PSTR("Timeout value out of range: 0x%lX\n"), val
);
145 return CMD_RET_FAILURE
;
147 boot_param
.timeout
= val
;
150 val
= eval_arg(optarg
, NULL
);
151 if (val
< 0x01 || val
> 0xFF) {
152 printf_P(PSTR("Partition id out of range: 0x%lX\n"), val
);
153 return CMD_RET_FAILURE
;
155 boot_param
.part_id
= val
;
158 return CMD_RET_USAGE
;
162 /* remaining arguments */
165 my_puts_P(PSTR("Argument error!\n"));
166 return CMD_RET_USAGE
;
169 if ((val
= (uint32_t) boot_param
.loadaddr
+ boot_param
.sec_cnt
* 512) >= 0xFF00) {
170 printf_P(PSTR("Top address out of range: 0x%.4lX\n"), val
);
171 return CMD_RET_FAILURE
;
174 if (z80_bus_state() & ZST_RUNNING
)
175 cmd_error(CMD_RET_FAILURE
, ERUNNING
, NULL
);
176 z80_bus_request_or_exit();
177 z80_load_mem(verbosity
, cfboot
,
180 cfboot_length_of_sections
);
182 z80_write_block((const uint8_t *) &boot_param
,
183 cfboot_address
[0], sizeof boot_param
);
184 z80_bus_cmd(Release
);
186 if (boot_param
.stages
== 0) {
187 printf_P(PSTR("Bootloader loaded at: 0x%.4X\n"), (uint16_t) cfboot_address
[0]);
189 printf_P(PSTR("Executing %d of %d Bootloader stages...\n"),
190 boot_param
.stages
, default_stages
);
193 z80_bus_cmd(Release
);
195 clear_ctrlc(); /* forget any previous Control C */
196 for (boot_res
.done
= 0; boot_res
.done
!= 0xFF;) {
198 /* check for ctrl-c to abort... */
199 if (had_ctrlc() || ctrlc()) {
202 z80_bus_cmd(Request
);
203 z80_read_block((uint8_t *) &boot_res
,
204 cfboot_address
[0]+sizeof boot_param
- 1, sizeof boot_res
);
205 z80_bus_cmd(Release
);
208 if (boot_res
.done
!= 0xFF) {
210 my_puts_P(PSTR("Abort\n"));
212 if (boot_param
.stages
== default_stages
&&
213 boot_res
.stages
== 0 &&
214 boot_res
.result
== 0) {
215 my_puts_P(PSTR("Booting...\n"));
219 printf_P(PSTR("Bootloader stopped at stage %d, result: %d, IDE stat/error: 0x%.02x/0x%.02x\n"),
220 boot_param
.stages
- boot_res
.stages
,
221 boot_res
.result
, boot_res
.ide_stat
, boot_res
.ide_error
);
226 return CMD_RET_SUCCESS
;
229 command_ret_t
do_busreq_pulse(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc
, char * const argv
[])
233 if (!(z80_bus_state() & ZST_RUNNING
)) {
234 printf_P(PSTR("## CPU is not running!\n"));
235 return CMD_RET_FAILURE
;
239 count
= (uint16_t) eval_arg(argv
[1], NULL
);
241 z80_bus_cmd(Request
);
243 z80_bus_cmd(M_Cycle
);
245 return CMD_RET_SUCCESS
;
249 command_ret_t
do_go(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc
, char * const argv
[])
255 while ((opt
= getopt(argc
, argv
, PSTR("h"))) != -1) {
261 return CMD_RET_USAGE
;
264 argc
-= optind
; /* remaining arguments */
267 return CMD_RET_USAGE
;
268 addr
= eval_arg(argv
[optind
], NULL
);
269 if (addr
>= (1UL<<16)) {
270 printf_P(PSTR("Invalid startaddress: 0x%05lx\n"
271 " (Out of logical address space (0x00000-0x0ffff))\n"),
273 return CMD_RET_FAILURE
;
276 if (z80_bus_state() & ZST_RUNNING
) {
277 cmd_error(CMD_RET_FAILURE
, ERUNNING
, NULL
);
280 printf_P(PSTR("Starting application at 0x%04lx ...\n"), addr
);
285 z80_bus_request_or_exit();
286 // z80_read_block (tmp, 0, 3);
289 z80_write(2, (addr
>> 8));
291 z80_bus_cmd(Release
);
294 // z80_write_block(tmp, 0, 3);
297 z80_bus_cmd(Request
);
301 z80_bus_cmd(Release
);
303 return CMD_RET_SUCCESS
;
307 void reset_cpu(bus_cmd_t mode
)
314 command_ret_t
do_reset(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc UNUSED
, char * const argv
[] UNUSED
)
316 printf_P(PSTR("CPU now in reset state.\n"));
319 return CMD_RET_SUCCESS
;
322 command_ret_t
do_restart(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc UNUSED
, char * const argv
[] UNUSED
)
326 return CMD_RET_SUCCESS
;
330 void print_con_usage(char esc
)
332 "------------------------------------------------\n"
334 " Q,X - Return to command line\n"
335 " R - Reset (Restart) CPU\n"
336 " : - Execute monitor command\n"
337 " \\ - code input:\n"
338 " \\nnn 3 decimal digits character code\n"
339 " \\Xhh 2 hexadecimal digits character code\n"
340 " ^%c - (Escape char) Type again to send itself\n"
345 command_ret_t
do_console(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc UNUSED
, char * const argv
[] UNUSED
)
351 char esc_char
= (char) getenv_ulong(PSTR(ENV_ESC_CHAR
), 16, CONFIG_ESC_CHAR
);
353 printf_P(PSTR("Connecting to CPU. Escape character is '^%c'.\n"),
358 ATOMIC_BLOCK(ATOMIC_FORCEON
) {
359 pending
= (Stat
& S_CON_PENDING
) != 0;
360 Stat
&= ~S_CON_PENDING
;
364 while ((ch
= z80_memfifo_getc(fifo_conout
)) >= 0 && --count
)
368 if ((ch
= my_getchar(0)) >= 0) {
371 if (ch
== esc_char
) {
373 /* TODO: Timer starten */
375 z80_memfifo_putc(fifo_conin
, ch
);
380 "------------------------------------------------\n"));
384 switch (toupper(ch
)) {
388 print_con_usage(esc_char
);
404 int cmdlen
= cli_readline(PSTR(": "), 1);
406 run_command(console_buffer
, 0);
416 z80_memfifo_putc(fifo_conin
, ch
);
421 if (toupper(ch
) == 'X') {
429 code
= code
* 10 + ch
- '0';
433 z80_memfifo_putc(fifo_conin
, code
);
434 z80_memfifo_putc(fifo_conin
, ch
);
438 z80_memfifo_putc(fifo_conin
, code
);
448 code
= code
* 16 + ch
- '0';
452 z80_memfifo_putc(fifo_conin
, code
);
453 z80_memfifo_putc(fifo_conin
, ch
);
457 z80_memfifo_putc(fifo_conin
, code
);
465 return CMD_RET_SUCCESS
;