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>
18 #include "cli_readline.h" /* console_buffer[] */
19 #include "cli.h" /* run_command() */
22 #include "con-utils.h"
23 #include "getopt-min.h"
25 #include "z180-serv.h" /* restart_z180_serv() */
28 /* ugly hack to get Z180 loadfile into flash memory */
29 #define const const FLASH
30 #include "../z180/hdrom.h"
31 #include "../z180/cfboot.h"
36 static void z80_load_mem(int_fast8_t verbosity
,
37 const FLASH
unsigned char data
[],
38 const FLASH
unsigned long *sections
,
39 const FLASH
unsigned long address
[],
40 const FLASH
unsigned long length_of_sections
[])
42 uint32_t sec_base
= 0;
45 printf_P(PSTR("Loading Z180 memory... \n"));
47 for (unsigned sec
= 0; sec
< *sections
; sec
++) {
49 printf_P(PSTR(" From: 0x%.5lX to: 0x%.5lX (%5li bytes)\n"),
51 address
[sec
]+length_of_sections
[sec
] - 1,
52 length_of_sections
[sec
]);
55 z80_write_block_P((const FLASH
unsigned char *) &data
[sec_base
], /* src */
56 address
[sec
], /* dest */
57 length_of_sections
[sec
]); /* len */
58 sec_base
+= length_of_sections
[sec
];
62 command_ret_t
do_loadf(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
64 (void) cmdtp
; (void) flag
; (void) argc
; (void) argv
;
66 if (z80_bus_state() & ZST_RUNNING
) {
67 my_puts_P(PSTR("Can't load while CPU is running!\n"));
68 return CMD_RET_FAILURE
;
70 if (!(z80_bus_cmd(Request
) & ZST_ACQUIRED
)) {
71 my_puts_P(PSTR("Bus timeout\n"));
72 return CMD_RET_FAILURE
;
74 z80_load_mem(2, hdrom
,
77 hdrom_length_of_sections
);
81 return CMD_RET_SUCCESS
;
85 void print_vars(char *title
)
88 zstate_t state
= z80_bus_state();
90 if((state
& ZST_ACQUIRED
) == 0)
93 z80_read_block(buf
, 9, sizeof buf
);
95 if((state
& ZST_ACQUIRED
) == 0)
98 printf_P(PSTR("%s: stage: %d, flag: 0x%.02x, result: %d, IDE stat/error: 0x%.02x/0x%.02x\n"),
99 title
, buf
[0], buf
[1], buf
[2], buf
[3], buf
[4]);
107 * -s start sector (0)
108 * -c sector count (7)
109 * -i Partition id (52)
115 command_ret_t
do_bootcf(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
135 int_fast8_t verbosity
= 0;
136 uint8_t default_stages
;
139 (void) cmdtp
; (void) flag
;
141 /* get default values */
142 memcpy_P(&boot_param
, cfboot
, sizeof boot_param
);
143 default_stages
= boot_param
.stages
;
149 while ((opt
= getopt(argc
, argv
, PSTR("vna:s:c:t:i:"))) != -1) {
155 if (boot_param
.stages
> 0)
159 val
= eval_arg(optarg
, NULL
);
160 if (val
< 0x100 || val
> 0xFE00) {
161 printf_P(PSTR("Address out of range: 0x%.4lX\n"), val
);
162 return CMD_RET_FAILURE
;
164 boot_param
.loadaddr
= val
;
167 val
= eval_arg(optarg
, NULL
);
169 printf_P(PSTR("Start sector out of range: 0x%lX\n"), val
);
170 return CMD_RET_FAILURE
;
172 boot_param
.sec_start
= val
;
175 val
= eval_arg(optarg
, NULL
);
177 printf_P(PSTR("Sector count out of range: 0x%lX\n"), val
);
178 return CMD_RET_FAILURE
;
180 boot_param
.sec_cnt
= val
;
183 val
= eval_arg(optarg
, NULL
);
184 if (val
< 0x1 || val
> 0xFFFF) {
185 printf_P(PSTR("Timeout value out of range: 0x%lX\n"), val
);
186 return CMD_RET_FAILURE
;
188 boot_param
.timeout
= val
;
191 val
= eval_arg(optarg
, NULL
);
192 if (val
< 0x01 || val
> 0xFF) {
193 printf_P(PSTR("Partition id out of range: 0x%lX\n"), val
);
194 return CMD_RET_FAILURE
;
196 boot_param
.part_id
= val
;
199 return CMD_RET_USAGE
;
203 /* remaining arguments */
206 my_puts_P(PSTR("Argument error!\n"));
207 return CMD_RET_USAGE
;
210 if ((val
= (uint32_t) boot_param
.loadaddr
+ boot_param
.sec_cnt
* 512) >= 0xFF00) {
211 printf_P(PSTR("Top address out of range: 0x%.4lX\n"), val
);
212 return CMD_RET_FAILURE
;
217 if (z80_bus_state() & ZST_RUNNING
) {
218 my_puts_P(PSTR("CPU is allready running!\n"));
219 return CMD_RET_FAILURE
;
221 if (!(z80_bus_cmd(Request
) & ZST_ACQUIRED
)) {
222 my_puts_P(PSTR("Bus timeout\n"));
223 return CMD_RET_FAILURE
;
225 z80_load_mem(verbosity
, cfboot
,
228 cfboot_length_of_sections
);
230 z80_write_block((const uint8_t *) &boot_param
,
231 cfboot_address
[0], sizeof boot_param
);
232 z80_bus_cmd(Release
);
234 if (boot_param
.stages
== 0) {
235 printf_P(PSTR("Bootloader loaded at: 0x%.4X\n"), (uint16_t) cfboot_address
[0]);
237 printf_P(PSTR("Executing %d of %d Bootloader stages...\n"),
238 boot_param
.stages
, default_stages
);
241 z80_bus_cmd(Release
);
243 clear_ctrlc(); /* forget any previous Control C */
244 for (boot_res
.done
= 0; boot_res
.done
!= 0xFF;) {
246 /* check for ctrl-c to abort... */
247 if (had_ctrlc() || ctrlc()) {
250 z80_bus_cmd(Request
);
251 z80_read_block((uint8_t *) &boot_res
,
252 cfboot_address
[0]+sizeof boot_param
- 1, sizeof boot_res
);
253 z80_bus_cmd(Release
);
256 if (boot_res
.done
!= 0xFF) {
258 my_puts_P(PSTR("Abort\n"));
260 if (boot_param
.stages
== default_stages
&&
261 boot_res
.stages
== 0 &&
262 boot_res
.result
== 0) {
263 my_puts_P(PSTR("Booting...\n"));
267 printf_P(PSTR("Bootloader stopped at stage %d, result: %d, IDE stat/error: 0x%.02x/0x%.02x\n"),
268 boot_param
.stages
- boot_res
.stages
,
269 boot_res
.result
, boot_res
.ide_stat
, boot_res
.ide_error
);
274 return CMD_RET_SUCCESS
;
277 command_ret_t
do_busreq_pulse(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
281 (void) cmdtp
; (void) flag
;
283 if (!(z80_bus_state() & ZST_RUNNING
)) {
284 printf_P(PSTR("## CPU is not running!\n"));
285 return CMD_RET_FAILURE
;
289 count
= (uint16_t) eval_arg(argv
[1], NULL
);
291 z80_bus_cmd(Request
);
293 z80_bus_cmd(M_Cycle
);
295 return CMD_RET_SUCCESS
;
299 command_ret_t
do_go(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
303 (void) cmdtp
; (void) flag
;
306 return CMD_RET_USAGE
;
307 addr
= eval_arg(argv
[1], NULL
);
308 if (addr
>= (1UL<<16)) {
309 printf_P(PSTR("## Startaddress 0x%05lx too high.\n"
310 " (Out of logical address space (0x00000-0x0ffff))\n"),
312 return CMD_RET_FAILURE
;
315 if (z80_bus_state() & ZST_RUNNING
) {
316 printf_P(PSTR("## CPU allready running!\n"));
317 return CMD_RET_FAILURE
;
320 printf_P(PSTR("## Starting application at 0x%04lx ...\n"), addr
);
325 z80_bus_cmd(Request
);
326 z80_read_block (tmp
, 0, 3);
329 z80_write(2, (addr
>> 8));
332 z80_bus_cmd(M_Cycle
);
333 z80_bus_cmd(M_Cycle
);
334 z80_write_block(tmp
, 0, 3);
338 z80_bus_cmd(Release
);
340 return CMD_RET_SUCCESS
;
344 void reset_cpu(bus_cmd_t mode
)
351 command_ret_t
do_reset(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
353 (void) cmdtp
; (void) flag
; (void) argc
; (void) argv
;
355 printf_P(PSTR("CPU now in reset state.\n"));
358 return CMD_RET_SUCCESS
;
361 command_ret_t
do_restart(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
363 (void) cmdtp
; (void) flag
; (void) argc
; (void) argv
;
367 return CMD_RET_SUCCESS
;
371 void print_con_usage(char esc
)
373 "------------------------------------------------\n"
375 " Q,X - Return to command line\n"
376 " R - Reset (Restart) CPU\n"
377 " : - Execute monitor command\n"
378 " \\ - code input:\n"
379 " \\nnn 3 decimal digits character code\n"
380 " \\Xhh 2 hexadecimal digits character code\n"
381 " ^%c - (Escape char) Type again to send itself\n"
386 command_ret_t
do_console(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
390 // uint8_t help_prompt = 0;
393 char esc_char
= (char) getenv_ulong(PSTR(ENV_ESC_CHAR
), 16, CONFIG_ESC_CHAR
);
395 (void) cmdtp
; (void) flag
; (void) argc
; (void) argv
;
397 printf_P(PSTR("Connecting to CPU. Escape character is '^%c'.\n"),
402 ATOMIC_BLOCK(ATOMIC_FORCEON
) {
403 pending
= (Stat
& S_CON_PENDING
) != 0;
404 Stat
&= ~S_CON_PENDING
;
408 while ((ch
= z80_memfifo_getc(fifo_conout
)) >= 0 && --count
)
412 if ((ch
= my_getchar(0)) >= 0) {
415 if (ch
== esc_char
) {
417 /* TODO: Timer starten */
419 z80_memfifo_putc(fifo_conin
, ch
);
424 "------------------------------------------------\n"));
427 switch (toupper(ch
)) {
431 print_con_usage(esc_char
);
441 printf_P(PSTR("\n"));
447 int cmdlen
= cli_readline(PSTR(": "), 1);
449 run_command(console_buffer
, 0);
459 z80_memfifo_putc(fifo_conin
, ch
);
464 if (toupper(ch
) == 'X') {
472 code
= code
* 10 + ch
- '0';
476 z80_memfifo_putc(fifo_conin
, code
);
477 z80_memfifo_putc(fifo_conin
, ch
);
481 z80_memfifo_putc(fifo_conin
, code
);
491 code
= code
* 16 + ch
- '0';
495 z80_memfifo_putc(fifo_conin
, code
);
496 z80_memfifo_putc(fifo_conin
, ch
);
500 z80_memfifo_putc(fifo_conin
, code
);
508 return CMD_RET_SUCCESS
;