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
15 #include <util/atomic.h>
17 #include "cli_readline.h" /* console_buffer[] */
18 #include "cli.h" /* run_command() */
21 #include "con-utils.h"
22 #include "getopt-min.h"
24 #include "z180-serv.h" /* restart_z180_serv() */
27 /* ugly hack to get Z180 loadfile into flash memory */
28 #define const const FLASH
29 #include "../z180/hdrom.h"
30 #include "../z180/cfboot.h"
34 command_ret_t
do_loadf(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc UNUSED
, char * const argv
[] UNUSED
)
36 if (z80_bus_state() & ZST_RUNNING
)
37 cmd_error(CMD_RET_FAILURE
, ERUNNING
, NULL
);
38 z80_bus_request_or_exit();
39 z80_load_mem(2, hdrom
,
42 hdrom_length_of_sections
);
46 return CMD_RET_SUCCESS
;
50 void print_vars(char *title
)
53 zstate_t state
= z80_bus_state();
55 if((state
& ZST_ACQUIRED
) == 0)
58 z80_read_block(buf
, 9, sizeof buf
);
60 if((state
& ZST_ACQUIRED
) == 0)
63 printf_P(PSTR("%s: stage: %d, flag: 0x%.02x, result: %d, IDE stat/error: 0x%.02x/0x%.02x\n"),
64 title
, buf
[0], buf
[1], buf
[2], buf
[3], buf
[4]);
74 * -i Partition id (52)
80 command_ret_t
do_bootcf(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc
, char * const argv
[])
100 int_fast8_t verbosity
= 0;
101 uint8_t default_stages
;
103 ERRNUM res
= ESUCCESS
;
105 /* get default values */
106 memcpy_P(&boot_param
, cfboot
, sizeof boot_param
);
107 default_stages
= boot_param
.stages
;
110 while ((opt
= getopt(argc
, argv
, PSTR("vna:s:c:t:i:"))) != -1) {
116 if (boot_param
.stages
> 0)
120 val
= eval_arg(optarg
, NULL
);
121 if (val
< 0x100 || val
> 0xFE00) {
122 printf_P(PSTR("Address out of range: 0x%.4lX\n"), val
);
123 return CMD_RET_FAILURE
;
125 boot_param
.loadaddr
= val
;
128 val
= eval_arg(optarg
, NULL
);
130 printf_P(PSTR("Start sector out of range: 0x%lX\n"), val
);
131 return CMD_RET_FAILURE
;
133 boot_param
.sec_start
= val
;
136 val
= eval_arg(optarg
, NULL
);
138 printf_P(PSTR("Sector count out of range: 0x%lX\n"), val
);
139 return CMD_RET_FAILURE
;
141 boot_param
.sec_cnt
= val
;
144 val
= eval_arg(optarg
, NULL
);
145 if (val
< 0x1 || val
> 0xFFFF) {
146 printf_P(PSTR("Timeout value out of range: 0x%lX\n"), val
);
147 return CMD_RET_FAILURE
;
149 boot_param
.timeout
= val
;
152 val
= eval_arg(optarg
, NULL
);
153 if (val
< 0x01 || val
> 0xFF) {
154 printf_P(PSTR("Partition id out of range: 0x%lX\n"), val
);
155 return CMD_RET_FAILURE
;
157 boot_param
.part_id
= val
;
160 return CMD_RET_USAGE
;
164 /* remaining arguments */
167 my_puts_P(PSTR("Argument error!\n"));
168 return CMD_RET_USAGE
;
171 if ((val
= (uint32_t) boot_param
.loadaddr
+ boot_param
.sec_cnt
* 512) >= 0xFF00) {
172 printf_P(PSTR("Top address out of range: 0x%.4lX\n"), val
);
173 return CMD_RET_FAILURE
;
176 if (z80_bus_state() & ZST_RUNNING
)
177 cmd_error(CMD_RET_FAILURE
, ERUNNING
, NULL
);
178 z80_bus_request_or_exit();
179 z80_load_mem(verbosity
, cfboot
,
182 cfboot_length_of_sections
);
184 z80_write_block((const uint8_t *) &boot_param
,
185 cfboot_address
[0], sizeof boot_param
);
186 z80_bus_cmd(Release
);
188 if (boot_param
.stages
== 0) {
189 printf_P(PSTR("Bootloader loaded at: 0x%.4X\n"), (uint16_t) cfboot_address
[0]);
191 printf_P(PSTR("Executing %d of %d Bootloader stages...\n"),
192 boot_param
.stages
, default_stages
);
195 z80_bus_cmd(Release
);
197 clear_ctrlc(); /* forget any previous Control C */
198 for (boot_res
.done
= 0; boot_res
.done
!= 0xFF;) {
200 /* check for ctrl-c to abort... */
201 if (had_ctrlc() || ctrlc()) {
204 z80_bus_cmd(Request
);
205 z80_read_block((uint8_t *) &boot_res
,
206 cfboot_address
[0]+sizeof boot_param
- 1, sizeof boot_res
);
207 z80_bus_cmd(Release
);
210 if (boot_res
.done
!= 0xFF) {
212 my_puts_P(PSTR("Abort\n"));
214 if (boot_param
.stages
== default_stages
&&
215 boot_res
.stages
== 0 &&
216 boot_res
.result
== 0) {
217 my_puts_P(PSTR("Booting...\n"));
221 printf_P(PSTR("Bootloader stopped at stage %d, result: %d, IDE stat/error: 0x%.02x/0x%.02x\n"),
222 boot_param
.stages
- boot_res
.stages
,
223 boot_res
.result
, boot_res
.ide_stat
, boot_res
.ide_error
);
228 return CMD_RET_SUCCESS
;
231 command_ret_t
do_busreq_pulse(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc
, char * const argv
[])
235 if (!(z80_bus_state() & ZST_RUNNING
)) {
236 printf_P(PSTR("## CPU is not running!\n"));
237 return CMD_RET_FAILURE
;
241 count
= (uint16_t) eval_arg(argv
[1], NULL
);
243 z80_bus_cmd(Request
);
245 z80_bus_cmd(M_Cycle
);
247 return CMD_RET_SUCCESS
;
251 command_ret_t
do_go(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc
, char * const argv
[])
257 while ((opt
= getopt(argc
, argv
, PSTR("h"))) != -1) {
263 return CMD_RET_USAGE
;
266 argc
-= optind
; /* remaining arguments */
269 return CMD_RET_USAGE
;
270 addr
= eval_arg(argv
[optind
], NULL
);
271 if (addr
>= (1UL<<16)) {
272 printf_P(PSTR("Invalid startaddress: 0x%05lx\n"
273 " (Out of logical address space (0x00000-0x0ffff))\n"),
275 return CMD_RET_FAILURE
;
278 if (z80_bus_state() & ZST_RUNNING
) {
279 printf_P(PSTR("CPU already running!\n"));
280 return CMD_RET_FAILURE
;
283 printf_P(PSTR("Starting application at 0x%04lx ...\n"), addr
);
288 z80_bus_cmd(Request
);
289 z80_read_block (tmp
, 0, 3);
292 z80_write(2, (addr
>> 8));
296 z80_bus_cmd(M_Cycle
);
298 z80_bus_cmd(M_Cycle
);
300 z80_write_block(tmp
, 0, 3);
303 z80_bus_cmd(Request
);
307 z80_bus_cmd(Release
);
309 return CMD_RET_SUCCESS
;
313 void reset_cpu(bus_cmd_t mode
)
320 command_ret_t
do_reset(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc UNUSED
, char * const argv
[] UNUSED
)
322 printf_P(PSTR("CPU now in reset state.\n"));
325 return CMD_RET_SUCCESS
;
328 command_ret_t
do_restart(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc UNUSED
, char * const argv
[] UNUSED
)
332 return CMD_RET_SUCCESS
;
336 void print_con_usage(char esc
)
338 "------------------------------------------------\n"
340 " Q,X - Return to command line\n"
341 " R - Reset (Restart) CPU\n"
342 " : - Execute monitor command\n"
343 " \\ - code input:\n"
344 " \\nnn 3 decimal digits character code\n"
345 " \\Xhh 2 hexadecimal digits character code\n"
346 " ^%c - (Escape char) Type again to send itself\n"
351 command_ret_t
do_console(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc UNUSED
, char * const argv
[] UNUSED
)
357 char esc_char
= (char) getenv_ulong(PSTR(ENV_ESC_CHAR
), 16, CONFIG_ESC_CHAR
);
359 printf_P(PSTR("Connecting to CPU. Escape character is '^%c'.\n"),
364 ATOMIC_BLOCK(ATOMIC_FORCEON
) {
365 pending
= (Stat
& S_CON_PENDING
) != 0;
366 Stat
&= ~S_CON_PENDING
;
370 while ((ch
= z80_memfifo_getc(fifo_conout
)) >= 0 && --count
)
374 if ((ch
= my_getchar(0)) >= 0) {
377 if (ch
== esc_char
) {
379 /* TODO: Timer starten */
381 z80_memfifo_putc(fifo_conin
, ch
);
386 "------------------------------------------------\n"));
389 switch (toupper(ch
)) {
393 print_con_usage(esc_char
);
409 int cmdlen
= cli_readline(PSTR(": "), 1);
411 run_command(console_buffer
, 0);
421 z80_memfifo_putc(fifo_conin
, ch
);
426 if (toupper(ch
) == 'X') {
434 code
= code
* 10 + ch
- '0';
438 z80_memfifo_putc(fifo_conin
, code
);
439 z80_memfifo_putc(fifo_conin
, ch
);
443 z80_memfifo_putc(fifo_conin
, code
);
453 code
= code
* 16 + ch
- '0';
457 z80_memfifo_putc(fifo_conin
, code
);
458 z80_memfifo_putc(fifo_conin
, ch
);
462 z80_memfifo_putc(fifo_conin
, code
);
470 return CMD_RET_SUCCESS
;