#include "z80-if.h"
#include "con-utils.h"
//#include "env.h"
-//#include "eval_arg.h"
-//#include "getopt-min.h"
+#include "eval_arg.h"
+#include "timer.h"
+#include "getopt-min.h"
//#include "debug.h"
/* hack to get Z180 loadfile into flash memory */
return CMD_RET_SUCCESS;
}
+
+/*
+ * delay for <count> ms...
+ */
+static void test_delay(uint32_t count)
+{
+ uint32_t ts = get_timer(0);
+
+ while (get_timer(ts) < count);
+}
+
+command_ret_t do_cpu_test(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[])
+{
+
+ uint32_t pulsewidth = 10; /* ms */
+
+ /* reset getopt() */
+ optind = 0;
+
+ int opt;
+ while ((opt = getopt(argc, argv, PSTR("t:"))) != -1) {
+ switch (opt) {
+ case 't':
+ pulsewidth = eval_arg(optarg, NULL);
+ break;
+ default: /* '?' */
+ return CMD_RET_USAGE;
+ }
+ }
+
+ if ((z80_bus_state() & ZST_ACQUIRED) != RESET)
+ cmd_error(CMD_RET_FAILURE, ERUNNING, NULL);
+
+ clear_ctrlc(); /* forget any previous Control C */
+ do {
+ z80_bus_cmd(Request);
+ test_delay(pulsewidth);
+ z80_bus_cmd(Release);
+ test_delay(pulsewidth);
+ } while (!(had_ctrlc() || ctrlc()));
+
+ return CMD_RET_SUCCESS;
+}
+
+#if 0
+command_ret_t do_cpu_freq(cmd_tbl_t *cmdtp UNUSED, int flag UNUSED, int argc, char * const argv[])
+{
+ bool silent = false;
+ bool write_env = false;
+ bool load_loop = true;
+ uint8_t lcycles = 18;
+ uint16_t timeout = 1000;
+
+ uint8_t eicrb_save;
+ uint8_t eimsk_save;
+ uint8_t mem_save[cpuinfo_length];
+
+ /* reset getopt() */
+ optind = 0;
+
+ int opt;
+ while ((opt = getopt(argc, argv, PSTR("swnc:t:"))) != -1) {
+ switch (opt) {
+ case 's':
+ silent = true;
+ break;
+ case 'w':
+ write_env = true;
+ break;
+ case 'n':
+ load_loop = false;
+ break;
+ case 'c':
+ lcycles = eval_arg(optarg, NULL);
+ break;
+ case 't':
+ lcycles = eval_arg(optarg, NULL);
+ break;
+ default: /* '?' */
+ return CMD_RET_USAGE;
+ }
+ }
+
+ if (z80_bus_state() & ZST_RUNNING) {
+ if (!silent)
+ printf_P(PSTR("Frequency measuring failed. CPU allready running!\n"));
+ return CMD_RET_FAILURE;
+ }
+
+ ATOMIC_BLOCK(ATOMIC_FORCEON) {
+ /* Save state and disable INT6 */
+ eimsk_save = EIMSK;
+ EIMSK &= ~_BV(INT6);
+ /* Save state and set INT6 for falling edge */
+ eicrb_save = EICRB;
+ EICRB = (eicrb_save & ~(0b11 << ISC60)) | (0b10 << ISC60);
+ }
+
+ z80_bus_cmd(Request);
+ if (load_loop) {
+ z80_read_block(mem_save, 0, cpuinfo_length);
+ z80_load_mem(0, cpuinfo,
+ &cpuinfo_sections,
+ cpuinfo_address,
+ cpuinfo_length_of_sections);
+ }
+ z80_bus_cmd(Run);
+ z80_bus_cmd(Release);
+
+ uint32_t cpu_freq = z80_measure_phi(lcycles, true, timeout);
+
+ z80_bus_cmd(Reset);
+ z80_bus_cmd(Request);
+ if (load_loop)
+ z80_write_block(mem_save, 0, cpuinfo_length);
+ z80_bus_cmd(Release);
+
+ ATOMIC_BLOCK(ATOMIC_FORCEON) {
+ /* Restore INT6 */
+ eicrb_save = EICRB;
+ EICRB = (EICRB & ~(0b11 << ISC60)) | (eicrb_save & (0b11 << ISC60));
+ if ((eimsk_save & _BV(INT6)) != 0)
+ EIMSK |= _BV(INT6);
+ /* Reset pending int */
+ EIFR = _BV(INTF6);
+ }
+
+ if (!silent) {
+ if (cpu_freq != 0)
+ printf_P(PSTR("%luHz\n"), cpu_freq);
+ else
+ printf_P(PSTR("No CPU clock or input frequency to low!\n"));
+ }
+
+ if (write_env) {
+ if (setenv_ulong(PSTR(ENV_CPU_FREQ), cpu_freq)) {
+ if (!silent)
+ printf_P(PSTR("'SETENV (%S, %lu)' failed!\n"), PSTR(ENV_CPU_FREQ), cpu_freq);
+ return CMD_RET_FAILURE;
+ }
+ }
+
+ return CMD_RET_SUCCESS;
+}
+#endif
+
+/*
+ * command table for fat subcommands
+ */
+
+cmd_tbl_t cmd_tbl_cpu[] = {
+CMD_TBL_ITEM(
+ chkcpu, CONFIG_SYS_MAXARGS, CTBL_RPT, do_cpuchk,
+ "Check CPU",
+ ""
+),
+CMD_TBL_ITEM(
+ test, CONFIG_SYS_MAXARGS, 1, do_cpu_test,
+ "Do bus request/release cycles",
+ "[-t pulsewidth]"
+),
+#if 0
+CMD_TBL_ITEM(
+ freq, CONFIG_SYS_MAXARGS, 1, do_cpu_freq,
+ "Measure cpu frequency",
+ "[-swn] [-c loopcycles]\n"
+ " -s Supress output (silent)\n"
+ " -w Write result to environment variable '"ENV_CPU_FREQ"'"
+),
+#endif
+CMD_TBL_ITEM(
+ help, CONFIG_SYS_MAXARGS, CTBL_RPT, do_help,
+ "Print sub command description/usage",
+ "\n"
+ " - print brief description of all sub commands\n"
+ "fat help command ...\n"
+ " - print detailed usage of sub cmd 'command'"
+),
+
+/* This does not use the CMD_TBL_ITEM macro as ? can't be used in symbol names */
+ {FSTR("?"), CONFIG_SYS_MAXARGS, 1, do_help,
+ NULL,
+#ifdef CONFIG_SYS_LONGHELP
+ FSTR(""),
+#endif /* CONFIG_SYS_LONGHELP */
+ NULL,
+#ifdef CONFIG_AUTO_COMPLETE
+ NULL,
+#endif
+},
+/* Mark end of table */
+CMD_TBL_END(cmd_tbl_cpu)
+};
+
+
+command_ret_t do_cpu(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc UNUSED, char * const argv[] UNUSED)
+{
+ //puts_P(PSTR("Huch?"));
+
+ return CMD_RET_USAGE;
+}
+
+
+#if 0
+/*
+ * Z180 Single Step Functions
+ *
+ */
+
+
+#define P_RUN PORTG
+#define RUN 1
+#define DDR_RUN DDRG
+#define P_STEP PORTG
+#define STEP 0
+#define DDR_STEP DDRG
+#define P_WAIT PORTG
+#define WAIT 2
+#define DDR_WAIT DDRG
+/* All three signals are on the same Port (PortG) */
+#define PORT_SS PORTG
+#define DDR_SS DDRG
+#define PIN_SS PING
+
+static bool ss_available;
+
+int single_step_setup(void)
+{
+ ss_available = false;
+
+#if 0
+ if (z80_bus_state() & ZST_RUNNING ||
+ !(z80_bus_cmd(Request) & ZST_ACQUIRED))
+ return -1;
+#endif
+
+ /* STEP, RUN output, WAIT input */
+
+ PORT_SS |= _BV(RUN) | _BV(STEP);
+ DDR_SS |= _BV(RUN) | _BV(STEP);
+ DDR_SS &= ~_BV(WAIT);
+
+ /* RUN high, MREQ pulse --> WAIT should be low */
+ z80_mreq_pulse();
+
+ if ((PIN_SS & _BV(WAIT)) == 0) {
+
+ /* RUN high, STEP pulse --> WAIT should be high */
+ PIN_SS = _BV(STEP);
+ PIN_SS = _BV(STEP);
+ if ((PIN_SS & _BV(WAIT)) != 0) {
+
+ /* RUN high, MREQ pulse --> WAIT should be low */
+ z80_mreq_pulse();
+ if ((PIN_SS & _BV(WAIT)) == 0) {
+
+ /* RUN low --> WAIT should be high */
+ PIN_SS = _BV(RUN);
+ if ((PIN_SS & _BV(WAIT)) != 0) {
+
+ /* RUN low, STEP pulse --> WAIT should be high */
+ PIN_SS = _BV(STEP);
+ PIN_SS = _BV(STEP);
+ if ((PIN_SS & _BV(WAIT)) != 0) {
+
+ /* all tests passed */
+ ss_available = true;
+ }
+ }
+ }
+ }
+ }
+
+ if (!ss_available) {
+ DDR_SS &= ~(_BV(STEP) | _BV(RUN));
+ PORT_SS |= _BV(RUN) | _BV(STEP);
+ }
+
+ return ss_available ? 0 : -1;
+}
+#endif