Browse Source

Refactor debug logging as distinct from dev build; add tracing.

master
Ben Kurtovic 4 years ago
parent
commit
a74c4ab405
16 changed files with 171 additions and 144 deletions
  1. +3
    -5
      README.md
  2. +9
    -9
      crater.c
  3. +10
    -7
      makefile
  4. +7
    -6
      src/assembler.c
  5. +1
    -1
      src/assembler/preprocessor.c
  6. +5
    -6
      src/assembler/state.c
  7. +1
    -3
      src/assembler/state.h
  8. +2
    -1
      src/assembler/tokenizer.c
  9. +13
    -15
      src/config.c
  10. +2
    -5
      src/config.h
  11. +5
    -7
      src/iomanager.c
  12. +28
    -20
      src/logging.h
  13. +25
    -14
      src/mmu.c
  14. +41
    -34
      src/rom.c
  15. +18
    -7
      src/z80.c
  16. +1
    -4
      src/z80.h

+ 3
- 5
README.md View File

@@ -28,8 +28,7 @@ Only OS X and Linux are tested. You'll need a modern compiler that supports C11
`brew install sdl2`; using apt, you can `apt-get install libsdl2-dev`.

Run `make` to create `./crater`. To build the development version with debug
symbols and extra diagnostic info (they can exist simultaneously), run
`make DEBUG=1`, which creates `./crater-dev`.
symbols and no optimizations, run `make DEBUG=1`, which creates `./crater-dev`.

crater has a number of test cases. Run the entire suite with `make test`;
individual components can be tested by doing `make test-{component}`, where
@@ -51,9 +50,8 @@ Add or symlink ROMs to `roms/` at your leisure. Note that they must end in
Add `--fullscreen` (`-f`) to enable fullscreen mode, or `--scale <n>`
(`-s <n>`) to scale the game screen by an integer factor.

Add `--debug` (`-g`) to display detailed information about emulation state
while running, including register values and memory contents. You can also
pause emulation to set breakpoints and change state.
Add `--debug` (`-g`) to show logging information while running. Pass it twice
(`-g -g`) to show more detailed logs, including an emulator trace.

`./crater -h` gives (fairly basic) command-line usage, and `./crater -v` gives
the current version.

+ 9
- 9
crater.c View File

@@ -1,4 +1,4 @@
/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

#include <stdlib.h>
@@ -24,15 +24,15 @@ int main(int argc, char *argv[])
if (retval != CONFIG_OK)
return retval == CONFIG_EXIT_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;

#ifdef DEBUG_MODE
config_dump_args(config);
#endif
SET_LOG_LEVEL(config->debug)
if (DEBUG_LEVEL)
config_dump_args(config);

if (config->assemble || config->disassemble) {
if (config->assemble)
retval = assemble_file(config->src_path, config->dst_path);
else
retval = disassemble_file(config->src_path, config->dst_path);
if (config->assemble) {
retval = assemble_file(config->src_path, config->dst_path);
retval = retval ? EXIT_SUCCESS : EXIT_FAILURE;
} else if (config->disassemble) {
retval = disassemble_file(config->src_path, config->dst_path);
retval = retval ? EXIT_SUCCESS : EXIT_FAILURE;
} else {
ROM *rom;

+ 10
- 7
makefile View File

@@ -8,17 +8,16 @@ DEVEXT = -dev
TESTS = cpu vdp psg asm dis integrate

CC = clang
FLAGS = -O2 -Wall -Wextra -pedantic -std=c11
FLAGS = -Wall -Wextra -pedantic -std=c11
CFLAGS = $(shell sdl2-config --cflags)
LIBS = $(shell sdl2-config --libs)
DFLAGS = -g -DDEBUG_MODE
DFLAGS = -g
RFLAGS = -O2

MKDIR = mkdir -p
RM = rm -rf
ASM_UP = scripts/update_asm_instructions.py

MODE = release
BNRY = $(PROGRAM)
FLGS = $(FLAGS)
SDRS = $(shell find $(SOURCES) -type d | xargs echo)
SRCS = $(filter-out %.inc.c,$(foreach d,. $(SDRS),$(wildcard $(addprefix $(d)/*,.c))))
OBJS = $(patsubst %.c,%.o,$(addprefix $(BUILD)/$(MODE)/,$(SRCS)))
@@ -27,9 +26,13 @@ DIRS = $(sort $(dir $(OBJS)))
TCPS = $(addprefix test-,$(TESTS))

ifdef DEBUG
BNRY := $(BNRY)$(DEVEXT)
FLGS += $(DFLAGS)
BNRY := $(PROGRAM)$(DEVEXT)
FLGS += $(DFLAGS) $(FLAGS)
MODE = debug
else
BNRY := $(PROGRAM)
FLGS += $(RFLAGS) $(FLAGS)
MODE = release
endif

export CC

+ 7
- 6
src/assembler.c View File

@@ -1,4 +1,4 @@
/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

#include <stdlib.h>
@@ -38,6 +38,7 @@ static size_t bounding_rom_size(size_t size)
*/
static ErrorInfo* resolve_defaults(AssemblerState *state)
{
DEBUG("Resolving defaults")
if (!state->rom_size) {
state->rom_size = ROM_SIZE_MIN;

@@ -82,6 +83,7 @@ static ErrorInfo* resolve_symbols(AssemblerState *state)
ASMInstruction *inst = state->instructions;
const ASMSymbol *symbol;

DEBUG("Resolving symbols")
while (inst) {
if (inst->symbol) {
symbol = asm_symtable_find(state->symtable, inst->symbol);
@@ -145,6 +147,7 @@ static void write_header(const ASMHeaderInfo *info, uint8_t *binary)
*/
static void serialize_binary(const AssemblerState *state, uint8_t *binary)
{
DEBUG("Serializing binary data")
memset(binary, 0xFF, state->rom_size);

const ASMInstruction *inst = state->instructions;
@@ -188,16 +191,13 @@ size_t assemble(const LineBuffer *source, uint8_t **binary_ptr, ErrorInfo **ei_p

asm_symtable_init(&state.symtable);

#ifdef DEBUG_MODE
asm_lines_print(state.lines);
#endif
if (TRACE_LEVEL)
asm_lines_print(state.lines);

if ((error_info = tokenize(&state)))
goto error;

if ((error_info = resolve_defaults(&state)))
goto error;

if ((error_info = resolve_symbols(&state)))
goto error;

@@ -240,6 +240,7 @@ bool assemble_file(const char *src_path, const char *dst_path)
return false;
}

DEBUG("Writing output file")
bool success = write_binary_file(dst_path, binary, size);
free(binary);
return success;

+ 1
- 1
src/assembler/preprocessor.c View File

@@ -373,7 +373,7 @@ static inline bool is_header_offset_valid(uint16_t offset)
ErrorInfo* preprocess(AssemblerState *state, const LineBuffer *source)
{
ErrorInfo* ei = NULL;
DEBUG("Running preprocessor:")
DEBUG("Running preprocessor")

if ((ei = build_asm_lines(source, &state->lines, NULL, &state->includes, 0)))
return ei;

+ 5
- 6
src/assembler/state.c View File

@@ -1,4 +1,4 @@
/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

#include <stdlib.h>
@@ -196,17 +196,16 @@ bool asm_deftable_remove(
return hash_table_remove(tab, key, size);
}

#ifdef DEBUG_MODE
/*
DEBUG FUNCTION: Print out an ASMLine list to stdout.
@TRACE_LEVEL
Print out an ASMLine list to stdout.
*/
void asm_lines_print(const ASMLine *line)
{
DEBUG("Dumping ASMLines:")
TRACE("Dumping ASMLines:")
while (line) {
DEBUG("- %-40.*s [%s:%02zu]", (int) line->length, line->data,
TRACE("- %-40.*s [%s:%02zu]", (int) line->length, line->data,
line->filename, line->original->lineno)
line = line->next;
}
}
#endif

+ 1
- 3
src/assembler/state.h View File

@@ -1,4 +1,4 @@
/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

#pragma once
@@ -112,6 +112,4 @@ const ASMDefine* asm_deftable_find(const ASMDefineTable*, const char*, size_t);
void asm_deftable_insert(ASMDefineTable*, ASMDefine*);
bool asm_deftable_remove(ASMDefineTable*, const char*, size_t);

#ifdef DEBUG_MODE
void asm_lines_print(const ASMLine*);
#endif

+ 2
- 1
src/assembler/tokenizer.c View File

@@ -1,4 +1,4 @@
/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

#include <stdlib.h>
@@ -468,6 +468,7 @@ ErrorInfo* tokenize(AssemblerState *state)
const ASMLine *line = state->lines;
size_t offset = 0;

DEBUG("Running tokenizer")
init_layout_info(&li, state);
memset(si.slots, -1, MMU_NUM_ROM_BANKS);


+ 13
- 15
src/config.c View File

@@ -1,4 +1,4 @@
/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

#include <dirent.h>
@@ -24,15 +24,14 @@ static void print_help(const char *arg1)
" -h, --help show this help message and exit\n"
" -v, --version show crater's version number and exit\n"
" -f, --fullscreen enable fullscreen mode\n"
" -s, --scale <n> scale the game screen by an integer factor\n"
" (applies to windowed mode only)\n"
" <rom_path> path to the rom file to execute; if not given, will look\n"
" in the roms/ directory and prompt the user\n"
"\n"
"advanced options:\n"
" -g, --debug display information about emulation state while running,\n"
" including register and memory values; can also pause\n"
" emulation, set breakpoints, and change state\n"
" -g, --debug show logging information while running; add twice (-g -g)\n"
" to show more detailed logs, including an emulator trace\n"
" -s, --scale <n> scale the game screen by an integer factor\n"
" (applies to windowed mode only)\n"
" -a, --assemble <in> [<out>] convert z80 assembly source code into a\n"
" binary file that can be run by crater\n"
" -d, --disassemble <in> [<out>] convert a binary file into z80 assembly\n"
@@ -202,7 +201,7 @@ static int parse_args(Config *config, int argc, char *argv[])
}
config->scale = scale;
} else if (!strcmp(arg, "g") || !strcmp(arg, "debug")) {
config->debug = true;
config->debug++;
} else if (!strcmp(arg, "a") || !strcmp(arg, "assemble")) {
if (paths_read >= 1) {
config->src_path = config->rom_path;
@@ -277,7 +276,7 @@ static bool sanity_check(Config* config)
} else if (config->assemble && config->disassemble) {
ERROR("cannot assemble and disassemble at the same time")
return false;
} else if (assembler && (config->debug || config->fullscreen || config->scale > 1)) {
} else if (assembler && (config->fullscreen || config->scale > 1)) {
ERROR("cannot specify emulator options in assembler mode")
return false;
} else if (assembler && !config->src_path) {
@@ -309,7 +308,7 @@ int config_create(Config** config_ptr, int argc, char* argv[])
Config *config = cr_malloc(sizeof(Config));
int retval;

config->debug = false;
config->debug = 0;
config->assemble = false;
config->disassemble = false;
config->fullscreen = false;
@@ -342,21 +341,20 @@ void config_destroy(Config *config)
free(config);
}

#ifdef DEBUG_MODE
/*
DEBUG FUNCTION: Print out all config arguments to stdout.
@DEBUG_LEVEL
Print out all config arguments to stdout.
*/
void config_dump_args(const Config* config)
{
DEBUG("Dumping arguments:")
DEBUG("- fullscreen: %s", config->fullscreen ? "true" : "false")
DEBUG("- scale: %d", config->scale)
DEBUG("- debug: %s", config->debug ? "true" : "false")
DEBUG("- debug: %d", config->debug)
DEBUG("- assemble: %s", config->assemble ? "true" : "false")
DEBUG("- disassemble: %s", config->disassemble ? "true" : "false")
DEBUG("- fullscreen: %s", config->fullscreen ? "true" : "false")
DEBUG("- scale: %d", config->scale)
DEBUG("- rom_path: %s", config->rom_path ? config->rom_path : "(null)")
DEBUG("- src_path: %s", config->src_path ? config->src_path : "(null)")
DEBUG("- dst_path: %s", config->dst_path ? config->dst_path : "(null)")
DEBUG("- overwrite: %s", config->overwrite ? "true" : "false")
}
#endif

+ 2
- 5
src/config.h View File

@@ -1,4 +1,4 @@
/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

#pragma once
@@ -21,7 +21,7 @@
/* Structs */

typedef struct {
bool debug;
int debug;
bool assemble;
bool disassemble;
bool fullscreen;
@@ -36,7 +36,4 @@ typedef struct {

int config_create(Config**, int, char*[]);
void config_destroy(Config*);

#ifdef DEBUG_MODE
void config_dump_args(const Config*);
#endif

+ 5
- 7
src/iomanager.c View File

@@ -1,4 +1,4 @@
/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

#include <signal.h>
@@ -36,9 +36,8 @@ void iomanager_emulate(GameGear *gg)
while (!caught_signal) {
if (gamegear_simulate(gg)) {
ERROR("caught exception: %s", gamegear_get_exception(gg))
#ifdef DEBUG_MODE
z80_dump_registers(&gg->cpu);
#endif
if (DEBUG_LEVEL)
z80_dump_registers(&gg->cpu);
break;
}
usleep(1000 * 1000 / 60);
@@ -46,9 +45,8 @@ void iomanager_emulate(GameGear *gg)

if (caught_signal) {
WARN("caught signal, stopping...")
#ifdef DEBUG_MODE
z80_dump_registers(&gg->cpu);
#endif
if (DEBUG_LEVEL)
z80_dump_registers(&gg->cpu);
}

DEBUG("IOManager unpowering GameGear")

+ 28
- 20
src/logging.h View File

@@ -1,4 +1,4 @@
/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

#pragma once
@@ -10,30 +10,38 @@

/* Internal usage only */

#define LOG_MSG_(dest, level, extra, after, ...) \
do { \
fprintf(dest, level ": " __VA_ARGS__); \
extra; \
fprintf(dest, "\n"); \
after; \
#define LOG_MSG_(dest, level, type, extra, after, ...) \
do { \
if (logging_level_ >= level) { \
fprintf(dest, type " " __VA_ARGS__); \
extra; \
fprintf(dest, "\n"); \
after; \
} \
} while (0);

#define LOG_ERR_(...) LOG_MSG_(stderr, __VA_ARGS__)
#define LOG_OUT_(...) LOG_MSG_(stdout, __VA_ARGS__)

#define PRINT_ERRNO_() fprintf(stderr, ": %s", strerror(errno))
#define PRINT_ERR_ fprintf(stderr, ": %s", strerror(errno))
#define EXIT_FAIL_ exit(EXIT_FAILURE)

#define DEBUG_TEXT_ "\x1b[0m\x1b[37m[DEBUG]\x1b[0m"
#define TRACE_TEXT_ "\x1b[1m\x1b[33m[TRACE]\x1b[0m"

unsigned logging_level_;

/* Public logging macros */

#define FATAL(...) LOG_ERR_("fatal", {}, exit(EXIT_FAILURE), __VA_ARGS__)
#define FATAL_ERRNO(...) LOG_ERR_("fatal", PRINT_ERRNO_(), exit(EXIT_FAILURE), __VA_ARGS__)
#define ERROR(...) LOG_ERR_("error", {}, {}, __VA_ARGS__)
#define ERROR_ERRNO(...) LOG_ERR_("error", PRINT_ERRNO_(), {}, __VA_ARGS__)
#define WARN(...) LOG_ERR_("warning", {}, {}, __VA_ARGS__)
#define WARN_ERRNO(...) LOG_ERR_("warning", PRINT_ERRNO_(), {}, __VA_ARGS__)
#ifdef DEBUG_MODE
#define DEBUG(...) LOG_OUT_("[DEBUG]", {}, {}, __VA_ARGS__)
#else
#define DEBUG(...) {}
#endif
#define FATAL(...) LOG_ERR_(0, "fatal:", {}, EXIT_FAIL_, __VA_ARGS__)
#define FATAL_ERRNO(...) LOG_ERR_(0, "fatal:", PRINT_ERR_, EXIT_FAIL_, __VA_ARGS__)
#define ERROR(...) LOG_ERR_(0, "error:", {}, {}, __VA_ARGS__)
#define ERROR_ERRNO(...) LOG_ERR_(0, "error:", PRINT_ERR_, {}, __VA_ARGS__)
#define WARN(...) LOG_ERR_(0, "warning:", {}, {}, __VA_ARGS__)
#define WARN_ERRNO(...) LOG_ERR_(0, "warning:", PRINT_ERR_, {}, __VA_ARGS__)
#define DEBUG(...) LOG_OUT_(1, DEBUG_TEXT_, {}, {}, __VA_ARGS__)
#define TRACE(...) LOG_OUT_(2, TRACE_TEXT_, {}, {}, __VA_ARGS__)
#define SET_LOG_LEVEL(level) logging_level_ = (level);
#define DEBUG_LEVEL (logging_level_ >= 1)
#define TRACE_LEVEL (logging_level_ >= 2)

+ 25
- 14
src/mmu.c View File

@@ -1,9 +1,10 @@
/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

#include <stdlib.h>
#include <string.h>

#include "mmu.h"
#include "logging.h"
#include "util.h"
#include "z80.h"
@@ -31,6 +32,27 @@ void mmu_free(MMU *mmu)
}

/*
@DEBUG_LEVEL
Print out the bank mapping.
*/
static void dump_bank_table(const MMU *mmu, const uint8_t *data)
{
char buffer[49];
size_t group, elem, bank;

DEBUG("Dumping MMU bank table:")
for (group = 0; group < MMU_NUM_ROM_BANKS / 8; group++) {
for (elem = 0; elem < 8; elem++) {
bank = 8 * group + elem;
snprintf(buffer + 6 * elem, 7, "%02zX=%02zX ", bank,
(mmu->rom_banks[bank] - data) >> 14);
}
buffer[47] = '\0';
DEBUG("- %s", buffer)
}
}

/*
Load a block of ROM into the MMU.

size must be a multiple of MMU_ROM_BANK_SIZE (16 KB), the load will fail
@@ -55,19 +77,8 @@ void mmu_load_rom(MMU *mmu, const uint8_t *data, size_t size)
mmu->rom_banks[mirror] = data + (bank * MMU_ROM_BANK_SIZE);
}

#ifdef DEBUG_MODE
char temp_str[64];
DEBUG("Dumping MMU bank table:")
for (size_t group = 0; group < MMU_NUM_ROM_BANKS / 8; group++) {
for (size_t elem = 0; elem < 8; elem++) {
bank = 8 * group + elem;
snprintf(temp_str + 6 * elem, 7, "%02zX=%02zX ", bank,
(mmu->rom_banks[bank] - data) >> 14);
}
temp_str[47] = '\0';
DEBUG("- %s", temp_str)
}
#endif
if (DEBUG_LEVEL)
dump_bank_table(mmu, data);
}

/*

+ 41
- 34
src/rom.c View File

@@ -1,4 +1,4 @@
/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

#include <ctype.h>
@@ -18,11 +18,29 @@

static size_t header_locations[NUM_LOCATIONS] = {0x7FF0, 0x3FF0, 0x1FF0};

#ifdef DEBUG_MODE
/*
DEBUG FUNCTION: Print out the header to stdout.
@DEBUG_LEVEL
Given a ROM size, return a pretty string.
*/
static void print_header(const uint8_t *header)
static const char* size_to_string(size_t size)
{
static char buffer[SIZE_CODE_BUF];

if (!size)
strncpy(buffer, "unknown", SIZE_CODE_BUF);
else if (size >= (1 << 20))
snprintf(buffer, SIZE_CODE_BUF, "%zu MB", size >> 20);
else
snprintf(buffer, SIZE_CODE_BUF, "%zu KB", size >> 10);

return buffer;
}

/*
@DEBUG_LEVEL
Print out the raw header to stdout.
*/
static void print_header_dump(const uint8_t *header)
{
char header_hex[3 * HEADER_SIZE], header_chr[3 * HEADER_SIZE];

@@ -40,26 +58,27 @@ static void print_header(const uint8_t *header)
DEBUG("- header dump (hex): %s", header_hex)
DEBUG("- header dump (chr): %s", header_chr)
}
#endif

#ifdef DEBUG_MODE
/*
DEBUG FUNCTION: Given a ROM size, return a pretty string.
@DEBUG_LEVEL
Print out the analyzed header to stdout.
*/
static const char* size_to_string(size_t size)
static void print_header_contents(const ROM *rom, const uint8_t *header)
{
static char buffer[SIZE_CODE_BUF];

if (!size)
strncpy(buffer, "unknown", SIZE_CODE_BUF);
else if (size >= (1 << 20))
snprintf(buffer, SIZE_CODE_BUF, "%zu MB", size >> 20);
DEBUG("- header info:")
if (rom->reported_checksum == rom->expected_checksum)
DEBUG(" - checksum: 0x%04X (valid)", rom->reported_checksum)
else
snprintf(buffer, SIZE_CODE_BUF, "%zu KB", size >> 10);

return buffer;
DEBUG(" - checksum: 0x%04X (invalid, expected 0x%04X)",
rom->reported_checksum, rom->expected_checksum)
DEBUG(" - product code: %u (%s)", rom->product_code,
rom_product(rom) ? rom_product(rom) : "unknown")
DEBUG(" - version: %u", rom->version)
DEBUG(" - region code: %u (%s)", rom->region_code,
rom_region(rom) ? rom_region(rom) : "unknown")
DEBUG(" - reported size: %s",
size_to_string(size_code_to_bytes(header[0xF] & 0xF)))
}
#endif

/*
Parse a ROM image's header, and return whether or not it is valid.
@@ -88,9 +107,8 @@ static const char* size_to_string(size_t size)
*/
static bool parse_header(ROM *rom, const uint8_t *header)
{
#ifdef DEBUG_MODE
print_header(header);
#endif
if (DEBUG_LEVEL)
print_header_dump(header);

rom->reported_checksum = header[0xA] + (header[0xB] << 8);
rom->expected_checksum = compute_checksum(rom->data, rom->size, header[0xF]);
@@ -99,19 +117,8 @@ static bool parse_header(ROM *rom, const uint8_t *header)
rom->version = header[0xE] & 0x0F;
rom->region_code = header[0xF] >> 4;

DEBUG("- header info:")
if (rom->reported_checksum == rom->expected_checksum)
DEBUG(" - checksum: 0x%04X (valid)", rom->reported_checksum)
else
DEBUG(" - checksum: 0x%04X (invalid, expected 0x%04X)",
rom->reported_checksum, rom->expected_checksum)
DEBUG(" - product code: %u (%s)", rom->product_code,
rom_product(rom) ? rom_product(rom) : "unknown")
DEBUG(" - version: %u", rom->version)
DEBUG(" - region code: %u (%s)", rom->region_code,
rom_region(rom) ? rom_region(rom) : "unknown")
DEBUG(" - reported size: %s",
size_to_string(size_code_to_bytes(header[0xF] & 0xF)))
if (DEBUG_LEVEL)
print_header_contents(rom, header);
return true;
}


+ 18
- 7
src/z80.c View File

@@ -1,8 +1,9 @@
/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

#include "logging.h"
#include "z80.h"
#include "disassembler.h"
#include "logging.h"

#define REG_AF 0
#define REG_BC 1
@@ -19,7 +20,6 @@
#define FLAG_ZERO 6
#define FLAG_SIGN 7

#ifdef DEBUG_MODE
#define BINARY_FMT "0b%u%u%u%u%u%u%u%u" // Used by z80_dump_registers()
#define BINARY_VAL(data) \
(data & (1 << 7) ? 1 : 0), \
@@ -30,7 +30,6 @@
(data & (1 << 2) ? 1 : 0), \
(data & (1 << 1) ? 1 : 0), \
(data & (1 << 0) ? 1 : 0)
#endif

/*
Initialize a Z80 object.
@@ -92,6 +91,7 @@ static inline uint16_t get_pair(Z80 *z80, uint8_t pair)
case REG_HL: return (z80->regfile.h << 8) + z80->regfile.l;
default: FATAL("invalid call: get_pair(z80, %u)", pair)
}
return 0;
}

/*
@@ -164,6 +164,16 @@ static inline void increment_refresh_counter(Z80 *z80)
#include "z80_ops.inc.c"

/*
@TRACE_LEVEL
Trace the instruction about to be executed by the CPU.
*/
static inline void trace_instruction(const Z80 *z80)
{
TRACE("PC @ 0x%04X", z80->regfile.pc)
// TODO
}

/*
Emulate the given number of cycles of the Z80, or until an exception.

The return value indicates whether the exception flag is set. If it is,
@@ -175,6 +185,8 @@ bool z80_do_cycles(Z80 *z80, double cycles)
cycles -= z80->pending_cycles;
while (cycles > 0 && !z80->except) {
uint8_t opcode = mmu_read_byte(z80->mmu, z80->regfile.pc);
if (TRACE_LEVEL)
trace_instruction(z80);
increment_refresh_counter(z80);
cycles -= (*instruction_lookup_table[opcode])(z80, opcode);
}
@@ -183,9 +195,9 @@ bool z80_do_cycles(Z80 *z80, double cycles)
return z80->except;
}

#ifdef DEBUG_MODE
/*
DEBUG FUNCTION: Print out all register values to stdout.
@DEBUG_LEVEL
Print out all register values to stdout.
*/
void z80_dump_registers(const Z80 *z80)
{
@@ -233,4 +245,3 @@ void z80_dump_registers(const Z80 *z80)
DEBUG("- IFF1: %u", rf->iff1)
DEBUG("- IFF2: %u", rf->iff2)
}
#endif

+ 1
- 4
src/z80.h View File

@@ -1,4 +1,4 @@
/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

#pragma once
@@ -35,7 +35,4 @@ typedef struct {
void z80_init(Z80*, MMU*);
void z80_power(Z80*);
bool z80_do_cycles(Z80*, double);

#ifdef DEBUG_MODE
void z80_dump_registers(const Z80*);
#endif

Loading…
Cancel
Save