diff --git a/src/logging.h b/src/logging.h index 5b75449..91590b2 100644 --- a/src/logging.h +++ b/src/logging.h @@ -14,17 +14,19 @@ do { \ if (logging_level_ >= level) { \ fprintf(dest, type " " __VA_ARGS__); \ - extra; \ + extra \ fprintf(dest, "\n"); \ - after; \ + after \ } \ } while (0); #define LOG_ERR_(...) LOG_MSG_(stderr, __VA_ARGS__) #define LOG_OUT_(...) LOG_MSG_(stdout, __VA_ARGS__) -#define PRINT_ERR_ fprintf(stderr, ": %s", strerror(errno)) -#define EXIT_FAIL_ exit(EXIT_FAILURE) +#define PRINT_ERR_ fprintf(stderr, ": %s", strerror(errno)); +#define EXIT_FAIL_ exit(EXIT_FAILURE); +#define NO_EOL_ if (0) +#define FLUSH_OUT_ fflush(stdout); #define FATAL_TEXT_ "\x1b[1m\x1b[31m" "fatal:" "\x1b[0m" #define ERROR_TEXT_ "\x1b[1m\x1b[31m" "error:" "\x1b[0m" @@ -44,6 +46,7 @@ unsigned logging_level_; #define WARN_ERRNO(...) LOG_ERR_(0, WARN_TEXT_, PRINT_ERR_, {}, __VA_ARGS__) #define DEBUG(...) LOG_OUT_(1, DEBUG_TEXT_, {}, {}, __VA_ARGS__) #define TRACE(...) LOG_OUT_(2, TRACE_TEXT_, {}, {}, __VA_ARGS__) +#define TRACE_NOEOL(...) LOG_OUT_(2, TRACE_TEXT_, NO_EOL_, FLUSH_OUT_, __VA_ARGS__) #define SET_LOG_LEVEL(level) logging_level_ = (level); #define DEBUG_LEVEL (logging_level_ >= 1) diff --git a/src/z80.c b/src/z80.c index 5be12ee..8a4ca38 100644 --- a/src/z80.c +++ b/src/z80.c @@ -82,6 +82,10 @@ void z80_power(Z80 *z80) z80->except = false; z80->pending_cycles = 0; + + z80->trace.fresh = true; + z80->trace.last_addr = 0; + z80->trace.counter = 0; } /* @@ -182,8 +186,19 @@ static inline void increment_refresh_counter(Z80 *z80) @TRACE_LEVEL Trace the instruction about to be executed by the CPU. */ -static inline void trace_instruction(const Z80 *z80) +static inline void trace_instruction(Z80 *z80) { + if (z80->regfile.pc == z80->trace.last_addr && !z80->trace.fresh) { + z80->trace.counter++; + if (!(z80->trace.counter % (1 << 14))) + TRACE_NOEOL("repeat last: %llu times\r", z80->trace.counter); + return; + } + if (z80->trace.fresh) + z80->trace.fresh = false; + z80->trace.last_addr = z80->regfile.pc; + z80->trace.counter = 0; + uint32_t quad = mmu_read_quad(z80->mmu, z80->regfile.pc); uint8_t bytes[4] = {quad, quad >> 8, quad >> 16, quad >> 24}; DisasInstr *instr = disassemble_instruction(bytes); diff --git a/src/z80.h b/src/z80.h index 9ccbe8b..43f895c 100644 --- a/src/z80.h +++ b/src/z80.h @@ -23,11 +23,18 @@ typedef struct { } Z80RegFile; typedef struct { + bool fresh; + uint16_t last_addr; + uint64_t counter; +} Z80TraceInfo; + +typedef struct { Z80RegFile regfile; MMU *mmu; bool except; uint8_t exc_code, exc_data; double pending_cycles; + Z80TraceInfo trace; } Z80; /* Functions */