]>
cloudbase.mooo.com Git - z180-stamp.git/blob - avr/cmd_boot.c
26855f1e6099e7858f0c6a8136417f22d198e5e6
9 #include <util/delay.h>
10 #include <avr/pgmspace.h>
13 #include "getopt-min.h"
18 /* ugly hack to get Z180 loadfile into flash memory */
19 #define const const FLASH
20 #include "../z180/hdrom.h"
25 static void z80_load_mem(void)
28 uint32_t sec_base
= hdrom_start
;
30 printf_P(PSTR("Loading Z180 memory... \n"));
32 while (sec
< hdrom_sections
) {
33 printf_P(PSTR(" From: 0x%.5lX to: 0x%.5lX (%5li bytes)\n"),
35 hdrom_address
[sec
]+hdrom_length_of_sections
[sec
] - 1,
36 hdrom_length_of_sections
[sec
]);
39 z80_write_block((const FLASH
unsigned char *) &hdrom
[sec_base
], /* src */
40 hdrom_address
[sec
], /* dest */
41 hdrom_length_of_sections
[sec
]); /* len */
43 sec_base
+=hdrom_length_of_sections
[sec
];
48 command_ret_t
do_loadf(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
50 (void) cmdtp
; (void) flag
; (void) argc
; (void) argv
;
52 if (z80_bus_state() & ZST_RUNNING
) {
53 printf_P(PSTR("## Can't load while CPU is running!\n"));
54 return CMD_RET_FAILURE
;
59 return CMD_RET_SUCCESS
;
63 command_ret_t
do_busreq_pulse(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
67 (void) cmdtp
; (void) flag
;
69 if (!(z80_bus_state() & ZST_RUNNING
)) {
70 printf_P(PSTR("## CPU is not running!\n"));
71 return CMD_RET_FAILURE
;
75 count
= (uint16_t) strtoul(argv
[2], NULL
, 16);
81 return CMD_RET_SUCCESS
;
85 command_ret_t
do_go(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
89 (void) cmdtp
; (void) flag
;
93 addr
= strtoul(argv
[1], NULL
, 16);
94 if (addr
>= (1UL<<16)) {
95 printf_P(PSTR("## Startaddress 0x%05lx too high.\n"
96 " (Out of logical address space (0x00000-0x0ffff))\n"),
98 return CMD_RET_FAILURE
;
101 if (z80_bus_state() & ZST_RUNNING
) {
102 printf_P(PSTR("## CPU allready running!\n"));
103 return CMD_RET_FAILURE
;
106 printf_P(PSTR("## Starting application at 0x%04lx ...\n"), addr
);
112 z80_bus_cmd(Request
);
113 for (i
= 0; i
< 3; i
++)
114 tmp
[i
] = z80_read(i
);
117 z80_write(2, (addr
>> 8));
120 z80_bus_cmd(M_Cycle
);
121 z80_bus_cmd(M_Cycle
);
122 for (i
= 0; i
< 3; i
++)
123 z80_write(i
, tmp
[i
]);
127 z80_bus_cmd(Release
);
129 return CMD_RET_SUCCESS
;
132 command_ret_t
do_reset(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
134 (void) cmdtp
; (void) flag
; (void) argc
; (void) argv
;
136 printf_P(PSTR("## CPU now in reset state.\n"));
139 return CMD_RET_SUCCESS
;
142 command_ret_t
do_restart(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
144 (void) cmdtp
; (void) flag
; (void) argc
; (void) argv
;
146 z80_bus_cmd(Restart
);
148 return CMD_RET_SUCCESS
;
152 command_ret_t
do_clock(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char *const argv
[])
157 (void) cmdtp
; (void) flag
;
160 if (toupper(argv
[1][0]) == 'L')
162 else if (toupper(argv
[1][0]) == 'H')
165 freq
= strtol(argv
[1], &endp
, 10);
176 printf_P(PSTR("invalid value\n"));
177 return CMD_RET_USAGE
;
181 printf_P(PSTR("CPU clock cannot be 0\n"));
182 return CMD_RET_USAGE
;
186 /* if (freq > (long) F_CPU / 2) {
187 printf_P(PSTR("Max CPU clock freq. is: %luHz\n"), F_CPU/2);
188 return CMD_RET_USAGE;
192 if (z80_clock_set(freq
) < 0) {
193 printf_P(PSTR("Setting CPU clock freq. to %luHz failed.\n"),
198 printf_P(PSTR("CPU clock: %luHz\n"), z80_clock_get());
201 return CMD_RET_SUCCESS
;
204 command_ret_t
do_clock2(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char *const argv
[])
208 uint8_t div_flag
= 0;
210 (void) cmdtp
; (void) flag
;
213 if (argv
[1][0] == '-' && argv
[1][1] == 'd') {
221 if (toupper(argv
[1][0]) == 'L')
223 else if (toupper(argv
[1][0]) == 'H')
226 value
= strtol(argv
[1], &endp
, 10);
237 printf_P(PSTR("invalid value\n"));
238 return CMD_RET_USAGE
;
242 printf_P(PSTR("clk2 cannot be 0\n"));
243 return CMD_RET_USAGE
;
247 if (value
> 256*1024L) {
248 printf_P(PSTR("Max clk2 divider is: %lu\n"), 256*1024L);
249 return CMD_RET_USAGE
;
252 if (value
> (long) F_CPU
/ 2) {
253 printf_P(PSTR("Max clk2 freq. is: %luHz\n"), F_CPU
/2);
254 return CMD_RET_USAGE
;
258 if (div_flag
? z80_clock2_divset(value
) : z80_clock2_set(value
) < 0) {
259 printf_P(PSTR("Setting clk2 freq. to %luHz failed.\n"),
264 printf_P(PSTR("clk2: %luHz\n"), z80_clock2_get());
267 return CMD_RET_SUCCESS
;
271 // {INPUT, INPUT_PULLUP, OUTPUT, OUTPUT_TIMER} pinmode_t;
274 static void print_blanks(uint_fast8_t count
)
280 static const FLASH
char * const FLASH pinconf_str
[] = {
288 static const FLASH
char * const FLASH pinlevel_str
[] = {
294 int print_pin(int pin
, int multi
)
297 const FLASH
char *levelp
;
300 pinconf
= pin_config_get(pin
);
301 if (pinconf
== OUTPUT_TIMER
) {
302 div
= pin_clockdiv_get(pin
);
303 levelp
= pinlevel_str
[2];
305 levelp
= pinlevel_str
[pin_read(pin
)];
308 printf_P(PSTR("%3d "), pin
);
309 my_puts_P(pinconf_str
[pinconf
]);
310 print_blanks(8 - strlen_P(pinconf_str
[pinconf
]));
312 print_blanks(6 - strlen_P(levelp
));
313 if (pinconf
== OUTPUT_TIMER
)
314 printf_P(PSTR("%7ld %8ld"),
317 printf_P(PSTR("Pin %d: "), pin
);
318 my_puts_P(pinconf_str
[pinconf
]);
319 printf_P(PSTR(", "));
322 if (pinconf
== OUTPUT_TIMER
)
323 printf_P(PSTR("divide by %ld (%ldHz)"),
326 printf_P(PSTR("\n"));
331 int pinarg_insert(int pin
, int count
, int pinarg
[])
335 if (pin
< 0 || pin
>= PIN_MAX
)
338 for (pos
= 0; pos
< count
; pos
++) {
339 if (pin
== pinarg
[pos
])
341 if (pin
< pinarg
[pos
])
344 for (int i
= count
-1; i
== pos
; i
--)
345 pinarg
[i
+1] = pinarg
[i
];
351 int pinarg_get(char * arg
, int pinarg
[])
358 pin1
= (int) strtoul(arg
, &endp
, 10);
359 if (endp
!= arg
&& *endp
== '-') {
361 pin2
= (int) strtoul(arg
, &endp
, 10);
363 for (; pin1
< pin2
; pin1
++)
364 if ((rc
= pinarg_insert(pin1
, count
, pinarg
)) >= 0)
371 if (endp
!= arg
&& pin1
>= 0) {
372 if ((*endp
== ',' || *endp
== '\0') &&
373 (rc
= pinarg_insert(pin1
, count
, pinarg
)) >= 0) {
387 command_ret_t
do_pin(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char *const argv
[])
389 char printheader
= 1;
393 (void) cmdtp
; (void) flag
;
399 while ((opt
= getopt(argc
, argv
, PSTR("s"))) != -1) {
405 return CMD_RET_USAGE
;
409 /* remaining arguments */
413 /* print cofig of all pins */
414 for (pinargc
= 0; pinargc
< PIN_MAX
; pinargc
++)
415 pinarg
[pinargc
] = pinargc
;
418 pinargc
= pinarg_get(argv
[optind
++], pinarg
);
420 return CMD_RET_USAGE
;
426 /* no more args, print config */
428 print_pin(pinarg
[0], 0);
431 printf_P(PSTR("Pin Config Level Divider Frequency/Hz\n"
432 "-----------------------------------------\n"));
433 for (int i
= 0; i
< pinargc
; i
++)
434 print_pin(pinarg
[i
], 1);
436 return CMD_RET_SUCCESS
;
439 /* arguments must be in pairs: pins conf */
441 return CMD_RET_USAGE
;
445 pinmode_t mode
= NONE
;
447 unsigned long value
= 0;
450 switch (toupper(argv
[optind
][0])) {
465 value
= strtoul(argv
[optind
], &endp
, 10);
474 if (*endp
&& strcmp_P(endp
, PSTR("Hz")) == 0) {
480 printf_P(PSTR("invalid parameter: '%s'\n"), argv
[optind
]);
481 return CMD_RET_USAGE
;
485 printf_P(PSTR("invalid value: %lu \n"));
486 return CMD_RET_USAGE
;
490 if (value
> F_CPU
/ 2) {
491 printf_P(PSTR("Max frequency is: %luHz\n"), F_CPU
/2);
492 return CMD_RET_USAGE
;
501 return CMD_RET_USAGE
;
503 for (int i
= 0; i
< pinargc
; i
++) {
506 pin_write(pinarg
[i
], level
);
510 pin_config(pinarg
[i
], mode
);
513 if (pin_clockdiv_set(pinarg
[i
], value
) < 0) {
514 printf_P(PSTR("Setting pin %d to %lu failed.\n"),
524 pinargc
= pinarg_get(argv
[optind
++], pinarg
);
528 return CMD_RET_SUCCESS
;