From 874f6bf78925bfdcba52155dde3375a59313c501 Mon Sep 17 00:00:00 2001 From: Thomas Eberhardt Date: Fri, 27 Dec 2024 16:18:46 +0100 Subject: [PATCH 1/3] make log.h usable in picosim and more robust Use "PRIu32" in _log_timestamp(). Encapsulate LOG?() in "do { ... } while (0)" so that they work correctly with statements like: if (foo) LOGW(TAG, "..."); else bar(); --- z80core/log.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/z80core/log.h b/z80core/log.h index 2093f8f9..2c4f52cf 100644 --- a/z80core/log.h +++ b/z80core/log.h @@ -19,8 +19,8 @@ #ifndef LOG_INC #define LOG_INC +#include #include -#include #include #include #define CONFIG_LOG_COLORS @@ -82,17 +82,17 @@ static inline uint32_t _log_timestamp(void) { #define LOG_RESET_COLOR #endif /* CONFIG_LOG_COLORS */ -#define _LOG_FORMAT(letter, format) LOG_COLOR_ ## letter #letter " (%d) %s: " format LOG_RESET_COLOR "\r\n" +#define _LOG_FORMAT(letter, format) LOG_COLOR_ ## letter #letter " (%" PRIu32 ") %s: " format LOG_RESET_COLOR "\r\n" #ifndef LOG_LOCAL_LEVEL #define LOG_LOCAL_LEVEL ((log_level_t) LOG_DEFAULT_LEVEL) #endif -#define LOG( tag, format, ... ) _log_write(LOG_NONE, NULL, format, ##__VA_ARGS__); -#define LOGE( tag, format, ... ) if (LOG_LOCAL_LEVEL >= LOG_ERROR) { _log_write(LOG_ERROR, tag, _LOG_FORMAT(E, format), _log_timestamp(), tag, ##__VA_ARGS__); } -#define LOGW( tag, format, ... ) if (LOG_LOCAL_LEVEL >= LOG_WARN) { _log_write(LOG_WARN, tag, _LOG_FORMAT(W, format), _log_timestamp(), tag, ##__VA_ARGS__); } -#define LOGI( tag, format, ... ) if (LOG_LOCAL_LEVEL >= LOG_INFO) { _log_write(LOG_INFO, tag, _LOG_FORMAT(I, format), _log_timestamp(), tag, ##__VA_ARGS__); } -#define LOGD( tag, format, ... ) if (LOG_LOCAL_LEVEL >= LOG_DEBUG) { _log_write(LOG_DEBUG, tag, _LOG_FORMAT(D, format), _log_timestamp(), tag, ##__VA_ARGS__); } -#define LOGV( tag, format, ... ) if (LOG_LOCAL_LEVEL >= LOG_VERBOSE) { _log_write(LOG_VERBOSE, tag, _LOG_FORMAT(V, format), _log_timestamp(), tag, ##__VA_ARGS__); } +#define LOG( tag, format, ... ) _log_write(LOG_NONE, NULL, format, ##__VA_ARGS__) +#define LOGE( tag, format, ... ) do { if (LOG_LOCAL_LEVEL >= LOG_ERROR) { _log_write(LOG_ERROR, tag, _LOG_FORMAT(E, format), _log_timestamp(), tag, ##__VA_ARGS__); } } while (0) +#define LOGW( tag, format, ... ) do { if (LOG_LOCAL_LEVEL >= LOG_WARN) { _log_write(LOG_WARN, tag, _LOG_FORMAT(W, format), _log_timestamp(), tag, ##__VA_ARGS__); } } while (0) +#define LOGI( tag, format, ... ) do { if (LOG_LOCAL_LEVEL >= LOG_INFO) { _log_write(LOG_INFO, tag, _LOG_FORMAT(I, format), _log_timestamp(), tag, ##__VA_ARGS__); } } while (0) +#define LOGD( tag, format, ... ) do { if (LOG_LOCAL_LEVEL >= LOG_DEBUG) { _log_write(LOG_DEBUG, tag, _LOG_FORMAT(D, format), _log_timestamp(), tag, ##__VA_ARGS__); } } while (0) +#define LOGV( tag, format, ... ) do { if (LOG_LOCAL_LEVEL >= LOG_VERBOSE) { _log_write(LOG_VERBOSE, tag, _LOG_FORMAT(V, format), _log_timestamp(), tag, ##__VA_ARGS__); } } while (0) #endif /* !LOG_INC */ From ddb870dc4a203638d33498987f5fe32d1b551fcb Mon Sep 17 00:00:00 2001 From: Thomas Eberhardt Date: Fri, 27 Dec 2024 16:45:08 +0100 Subject: [PATCH 2/3] use LOG? everywhere and make BAREMETAL an ICE only options --- doc/README-ice.txt | 2 +- picosim/srcsim/sim.h | 2 +- z80core/simcore.c | 55 -------------------------------------------- 3 files changed, 2 insertions(+), 57 deletions(-) diff --git a/doc/README-ice.txt b/doc/README-ice.txt index 338eae8c..1af059c4 100644 --- a/doc/README-ice.txt +++ b/doc/README-ice.txt @@ -30,7 +30,7 @@ Pico. Because on bare metal there is no operating system all commands that require one are disabled. To enable bare metal support add the following to the sim.h file for the machine: -#define BAREMETAL /* set up the simulator core for bare metal use */ +#define BAREMETAL /* disable ICE commands that require a full OS */ Also watch out what code you are going to execute, because without an operating system that provides signal handling for applications, we diff --git a/picosim/srcsim/sim.h b/picosim/srcsim/sim.h index 68c9b343..863bee6a 100644 --- a/picosim/srcsim/sim.h +++ b/picosim/srcsim/sim.h @@ -18,10 +18,10 @@ #ifndef EXCLUDE_Z80 /*#define FAST_BLOCK*/ /* much faster but not accurate Z80 block instr. */ #endif -#define BAREMETAL /* set up the simulator core for bare metal use */ /*#define WANT_ICE*/ /* attach ICE to headless machine */ #ifdef WANT_ICE +#define BAREMETAL /* disable ICE commands that require a full OS */ #define WANT_TIM /* count t-states */ #define HISIZE 100 /* number of entries in history */ #define SBSIZE 4 /* number of software breakpoints */ diff --git a/z80core/simcore.c b/z80core/simcore.c index 49b9c254..518b0d29 100644 --- a/z80core/simcore.c +++ b/z80core/simcore.c @@ -34,11 +34,9 @@ #include "simctl.h" #endif -#ifndef BAREMETAL /* #define LOG_LOCAL_LEVEL LOG_DEBUG */ #include "log.h" static const char *TAG = "core"; -#endif /* * Initialize the CPU @@ -184,59 +182,11 @@ void report_cpu_error(void) return; /* always start on a new line */ -#ifdef BAREMETAL - printf("\n"); -#else LOG(TAG, "\r\n"); -#endif switch (cpu_error) { case NONE: break; -#ifdef BAREMETAL - case OPHALT: - printf("INT disabled and HALT Op-Code reached at 0x%04x\n", - PC - 1); - break; - case IOTRAPIN: - printf("I/O input Trap at 0x%04x, port 0x%02x\n", PC, io_port); - break; - case IOTRAPOUT: - printf("I/O output Trap at 0x%04x, port 0x%02x\n", - PC, io_port); - break; - case IOHALT: - printf("System halted\n"); - break; - case IOERROR: - printf("Fatal I/O Error at 0x%04x\n", PC); - break; - case OPTRAP1: - printf("Op-code trap at 0x%04x 0x%02x\n", - PC - 1, getmem(PC - 1)); - break; - case OPTRAP2: - printf("Op-code trap at 0x%04x 0x%02x 0x%02x\n", - PC - 2, getmem(PC - 2), getmem(PC - 1)); - break; - case OPTRAP4: - printf("Op-code trap at 0x%04x 0x%02x 0x%02x 0x%02x 0x%02x\n", - PC - 4, getmem(PC - 4), getmem(PC - 3), - getmem(PC - 2), getmem(PC - 1)); - break; - case USERINT: - printf("User Interrupt at 0x%04x\n", PC); - break; - case INTERROR: - printf("Unsupported bus data during INT: 0x%02x\n", int_data); - break; - case POWEROFF: - printf("System powered off\n"); - break; - default: - printf("Unknown error %d\n", cpu_error); - break; -#else /* !BAREMETAL */ case OPHALT: LOG(TAG, "INT disabled and HALT Op-Code reached at 0x%04x\r\n", PC - 1); @@ -280,7 +230,6 @@ void report_cpu_error(void) default: LOGW(TAG, "Unknown error %d", cpu_error); break; -#endif /* !BAREMETAL */ } } @@ -349,9 +298,7 @@ BYTE io_in(BYTE addrl, BYTE addrh) fp_led_data = io_data; #endif -#ifndef BAREMETAL LOGD(TAG, "input %02x from port %02x", io_data, io_port); -#endif cpu_time -= get_clock_us() - clk; @@ -375,9 +322,7 @@ void io_out(BYTE addrl, BYTE addrh, BYTE data) io_port = addrl; io_data = data; -#ifndef BAREMETAL LOGD(TAG, "output %02x to port %02x", io_data, io_port); -#endif busy_loop_cnt = 0; From cea18be05926fd459a242b6ff44c0a0d89e26f5d Mon Sep 17 00:00:00 2001 From: Thomas Eberhardt Date: Fri, 27 Dec 2024 19:00:50 +0100 Subject: [PATCH 3/3] add i_flag/u_flag toggle commands to the ICE Also report cpu errors in 'p' command. Clean-up 's' command a bit. --- z80core/simice.c | 66 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 13 deletions(-) diff --git a/z80core/simice.c b/z80core/simice.c index d4271f0e..b1c9a92a 100644 --- a/z80core/simice.c +++ b/z80core/simice.c @@ -95,6 +95,8 @@ static void do_count(char *s); #if !defined (EXCLUDE_I8080) && !defined(EXCLUDE_Z80) static void do_switch(char *s); #endif +static void do_uflag(void); +static void do_iflag(void); static void do_show(void); static void do_help(void); @@ -202,6 +204,12 @@ void ice_cmd_loop(int go_flag) do_switch(cmd + 1); break; #endif + case 'u': + do_uflag(); + break; + case 'i': + do_iflag(); + break; case 's': do_show(); break; @@ -611,7 +619,7 @@ static void do_move(char *s) */ static void do_port(char *s) { - register BYTE port; + register BYTE port, data; while (isspace((unsigned char) *s)) s++; @@ -620,13 +628,20 @@ static void do_port(char *s) return; } port = strtol(s, NULL, 16); - printf("%02x = %02x : ", port, io_in(port, 0)); + cpu_error = NONE; + data = io_in(port, 0); + report_cpu_error(); + printf("%02x = %02x : ", port, data); if (!get_cmdline(arg, LENCMD)) { s = arg; while (isspace((unsigned char) *s)) s++; - if (isxdigit((unsigned char) *s)) - io_out(port, 0, (BYTE) strtol(s, NULL, 16)); + if (isxdigit((unsigned char) *s)) { + data = (BYTE) strtol(s, NULL, 16); + cpu_error = NONE; + io_out(port, 0, data); + report_cpu_error(); + } } } @@ -1195,6 +1210,30 @@ static void do_switch(char *s) } #endif /* !EXCLUDE_I8080 && !EXCLUDE_Z80 */ +/* + * Toggle trap on undocumented op-codes + */ +static void do_uflag(void) +{ +#ifdef UNDOC_INST + u_flag = !u_flag; + printf("Undocumented op-codes are now %s\n", + u_flag ? "trapped" : "executed"); +#else + puts("Undocumented op-codes are always trapped"); +#endif +} + +/* + * Toggle trap on undefined ports I/O + */ +static void do_iflag(void) +{ + i_flag = !i_flag; + printf("Undefined ports I/O is now %s\n", + i_flag ? "trapped" : "allowed"); +} + /* * Output information about compiling options */ @@ -1212,17 +1251,15 @@ static void do_show(void) #endif printf("sim Release: %s\n", RELEASE); #ifdef HISIZE - i = HISIZE; + printf("No. of entries in history memory: %d\n", HISIZE); #else - i = 0; + puts("History not available"); #endif - printf("No. of entries in history memory: %d\n", i); #ifdef SBSIZE - i = SBSIZE; + printf("No. of software breakpoints: %d\n", SBSIZE); #else - i = 0; + puts("Software breakpoints not available"); #endif - printf("No. of software breakpoints: %d\n", i); #ifdef WANT_HB i = 1; #else @@ -1230,11 +1267,12 @@ static void do_show(void) #endif printf("Hardware breakpoint %savailable\n", i ? "" : "not "); #ifdef UNDOC_INST - i = u_flag; + printf("Undocumented op-codes are %s\n", + u_flag ? "trapped" : "executed"); #else - i = 1; + puts("Undocumented op-codes are always trapped"); #endif - printf("Undocumented op-codes are %sexecuted\n", i ? "not " : ""); + printf("Undefined ports I/O is %s\n", i_flag ? "trapped" : "allowed"); #ifdef WANT_TIM i = 1; #else @@ -1269,6 +1307,8 @@ static void do_help(void) puts("hc clear history"); puts("z start,stop set trigger addr for t-state count"); puts("z show t-state count"); + puts("u toggle trap on undocumented op-codes"); + puts("i toggle trap on undefined ports I/O"); puts("s show settings"); #if !defined (EXCLUDE_I8080) && !defined(EXCLUDE_Z80) puts("8 toggle between Z80 & 8080 mode");