Browse Source

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

master
Ben Kurtovic 3 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
28 28
 `brew install sdl2`; using apt, you can `apt-get install libsdl2-dev`.
29 29
 
30 30
 Run `make` to create `./crater`. To build the development version with debug
31
-symbols and extra diagnostic info (they can exist simultaneously), run
32
-`make DEBUG=1`, which creates `./crater-dev`.
31
+symbols and no optimizations, run `make DEBUG=1`, which creates `./crater-dev`.
33 32
 
34 33
 crater has a number of test cases. Run the entire suite with `make test`;
35 34
 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
51 50
 Add `--fullscreen` (`-f`) to enable fullscreen mode, or `--scale <n>`
52 51
 (`-s <n>`) to scale the game screen by an integer factor.
53 52
 
54
-Add `--debug` (`-g`) to display detailed information about emulation state
55
-while running, including register values and memory contents. You can also
56
-pause emulation to set breakpoints and change state.
53
+Add `--debug` (`-g`) to show logging information while running. Pass it twice
54
+(`-g -g`) to show more detailed logs, including an emulator trace.
57 55
 
58 56
 `./crater -h` gives (fairly basic) command-line usage, and `./crater -v` gives
59 57
 the current version.

+ 9
- 9
crater.c View File

@@ -1,4 +1,4 @@
1
-/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
1
+/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
2 2
    Released under the terms of the MIT License. See LICENSE for details. */
3 3
 
4 4
 #include <stdlib.h>
@@ -24,15 +24,15 @@ int main(int argc, char *argv[])
24 24
     if (retval != CONFIG_OK)
25 25
         return retval == CONFIG_EXIT_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;
26 26
 
27
-#ifdef DEBUG_MODE
28
-    config_dump_args(config);
29
-#endif
27
+    SET_LOG_LEVEL(config->debug)
28
+    if (DEBUG_LEVEL)
29
+        config_dump_args(config);
30 30
 
31
-    if (config->assemble || config->disassemble) {
32
-        if (config->assemble)
33
-            retval = assemble_file(config->src_path, config->dst_path);
34
-        else
35
-            retval = disassemble_file(config->src_path, config->dst_path);
31
+    if (config->assemble) {
32
+        retval = assemble_file(config->src_path, config->dst_path);
33
+        retval = retval ? EXIT_SUCCESS : EXIT_FAILURE;
34
+    } else if (config->disassemble) {
35
+        retval = disassemble_file(config->src_path, config->dst_path);
36 36
         retval = retval ? EXIT_SUCCESS : EXIT_FAILURE;
37 37
     } else {
38 38
         ROM *rom;

+ 10
- 7
makefile View File

@@ -8,17 +8,16 @@ DEVEXT  = -dev
8 8
 TESTS   = cpu vdp psg asm dis integrate
9 9
 
10 10
 CC     = clang
11
-FLAGS  = -O2 -Wall -Wextra -pedantic -std=c11
11
+FLAGS  = -Wall -Wextra -pedantic -std=c11
12 12
 CFLAGS = $(shell sdl2-config --cflags)
13 13
 LIBS   = $(shell sdl2-config --libs)
14
-DFLAGS = -g -DDEBUG_MODE
14
+DFLAGS = -g
15
+RFLAGS = -O2
16
+
15 17
 MKDIR  = mkdir -p
16 18
 RM     = rm -rf
17 19
 ASM_UP = scripts/update_asm_instructions.py
18 20
 
19
-MODE = release
20
-BNRY = $(PROGRAM)
21
-FLGS = $(FLAGS)
22 21
 SDRS = $(shell find $(SOURCES) -type d | xargs echo)
23 22
 SRCS = $(filter-out %.inc.c,$(foreach d,. $(SDRS),$(wildcard $(addprefix $(d)/*,.c))))
24 23
 OBJS = $(patsubst %.c,%.o,$(addprefix $(BUILD)/$(MODE)/,$(SRCS)))
@@ -27,9 +26,13 @@ DIRS = $(sort $(dir $(OBJS)))
27 26
 TCPS = $(addprefix test-,$(TESTS))
28 27
 
29 28
 ifdef DEBUG
30
-	BNRY := $(BNRY)$(DEVEXT)
31
-	FLGS += $(DFLAGS)
29
+	BNRY := $(PROGRAM)$(DEVEXT)
30
+	FLGS += $(DFLAGS) $(FLAGS)
32 31
 	MODE  = debug
32
+else
33
+	BNRY := $(PROGRAM)
34
+	FLGS += $(RFLAGS) $(FLAGS)
35
+	MODE  = release
33 36
 endif
34 37
 
35 38
 export CC

+ 7
- 6
src/assembler.c View File

@@ -1,4 +1,4 @@
1
-/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
1
+/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
2 2
    Released under the terms of the MIT License. See LICENSE for details. */
3 3
 
4 4
 #include <stdlib.h>
@@ -38,6 +38,7 @@ static size_t bounding_rom_size(size_t size)
38 38
 */
39 39
 static ErrorInfo* resolve_defaults(AssemblerState *state)
40 40
 {
41
+    DEBUG("Resolving defaults")
41 42
     if (!state->rom_size) {
42 43
         state->rom_size = ROM_SIZE_MIN;
43 44
 
@@ -82,6 +83,7 @@ static ErrorInfo* resolve_symbols(AssemblerState *state)
82 83
     ASMInstruction *inst = state->instructions;
83 84
     const ASMSymbol *symbol;
84 85
 
86
+    DEBUG("Resolving symbols")
85 87
     while (inst) {
86 88
         if (inst->symbol) {
87 89
             symbol = asm_symtable_find(state->symtable, inst->symbol);
@@ -145,6 +147,7 @@ static void write_header(const ASMHeaderInfo *info, uint8_t *binary)
145 147
 */
146 148
 static void serialize_binary(const AssemblerState *state, uint8_t *binary)
147 149
 {
150
+    DEBUG("Serializing binary data")
148 151
     memset(binary, 0xFF, state->rom_size);
149 152
 
150 153
     const ASMInstruction *inst = state->instructions;
@@ -188,16 +191,13 @@ size_t assemble(const LineBuffer *source, uint8_t **binary_ptr, ErrorInfo **ei_p
188 191
 
189 192
     asm_symtable_init(&state.symtable);
190 193
 
191
-#ifdef DEBUG_MODE
192
-    asm_lines_print(state.lines);
193
-#endif
194
+    if (TRACE_LEVEL)
195
+        asm_lines_print(state.lines);
194 196
 
195 197
     if ((error_info = tokenize(&state)))
196 198
         goto error;
197
-
198 199
     if ((error_info = resolve_defaults(&state)))
199 200
         goto error;
200
-
201 201
     if ((error_info = resolve_symbols(&state)))
202 202
         goto error;
203 203
 
@@ -240,6 +240,7 @@ bool assemble_file(const char *src_path, const char *dst_path)
240 240
         return false;
241 241
     }
242 242
 
243
+    DEBUG("Writing output file")
243 244
     bool success = write_binary_file(dst_path, binary, size);
244 245
     free(binary);
245 246
     return success;

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

@@ -373,7 +373,7 @@ static inline bool is_header_offset_valid(uint16_t offset)
373 373
 ErrorInfo* preprocess(AssemblerState *state, const LineBuffer *source)
374 374
 {
375 375
     ErrorInfo* ei = NULL;
376
-    DEBUG("Running preprocessor:")
376
+    DEBUG("Running preprocessor")
377 377
 
378 378
     if ((ei = build_asm_lines(source, &state->lines, NULL, &state->includes, 0)))
379 379
         return ei;

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

@@ -1,4 +1,4 @@
1
-/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
1
+/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
2 2
    Released under the terms of the MIT License. See LICENSE for details. */
3 3
 
4 4
 #include <stdlib.h>
@@ -196,17 +196,16 @@ bool asm_deftable_remove(
196 196
     return hash_table_remove(tab, key, size);
197 197
 }
198 198
 
199
-#ifdef DEBUG_MODE
200 199
 /*
201
-    DEBUG FUNCTION: Print out an ASMLine list to stdout.
200
+    @TRACE_LEVEL
201
+    Print out an ASMLine list to stdout.
202 202
 */
203 203
 void asm_lines_print(const ASMLine *line)
204 204
 {
205
-    DEBUG("Dumping ASMLines:")
205
+    TRACE("Dumping ASMLines:")
206 206
     while (line) {
207
-        DEBUG("- %-40.*s [%s:%02zu]", (int) line->length, line->data,
207
+        TRACE("- %-40.*s [%s:%02zu]", (int) line->length, line->data,
208 208
               line->filename, line->original->lineno)
209 209
         line = line->next;
210 210
     }
211 211
 }
212
-#endif

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

@@ -1,4 +1,4 @@
1
-/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
1
+/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
2 2
    Released under the terms of the MIT License. See LICENSE for details. */
3 3
 
4 4
 #pragma once
@@ -112,6 +112,4 @@ const ASMDefine* asm_deftable_find(const ASMDefineTable*, const char*, size_t);
112 112
 void asm_deftable_insert(ASMDefineTable*, ASMDefine*);
113 113
 bool asm_deftable_remove(ASMDefineTable*, const char*, size_t);
114 114
 
115
-#ifdef DEBUG_MODE
116 115
 void asm_lines_print(const ASMLine*);
117
-#endif

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

@@ -1,4 +1,4 @@
1
-/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
1
+/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
2 2
    Released under the terms of the MIT License. See LICENSE for details. */
3 3
 
4 4
 #include <stdlib.h>
@@ -468,6 +468,7 @@ ErrorInfo* tokenize(AssemblerState *state)
468 468
     const ASMLine *line = state->lines;
469 469
     size_t offset = 0;
470 470
 
471
+    DEBUG("Running tokenizer")
471 472
     init_layout_info(&li, state);
472 473
     memset(si.slots, -1, MMU_NUM_ROM_BANKS);
473 474
 

+ 13
- 15
src/config.c View File

@@ -1,4 +1,4 @@
1
-/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
1
+/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
2 2
    Released under the terms of the MIT License. See LICENSE for details. */
3 3
 
4 4
 #include <dirent.h>
@@ -24,15 +24,14 @@ static void print_help(const char *arg1)
24 24
 "    -h, --help        show this help message and exit\n"
25 25
 "    -v, --version     show crater's version number and exit\n"
26 26
 "    -f, --fullscreen  enable fullscreen mode\n"
27
-"    -s, --scale <n>   scale the game screen by an integer factor\n"
28
-"                      (applies to windowed mode only)\n"
29 27
 "    <rom_path>        path to the rom file to execute; if not given, will look\n"
30 28
 "                      in the roms/ directory and prompt the user\n"
31 29
 "\n"
32 30
 "advanced options:\n"
33
-"    -g, --debug       display information about emulation state while running,\n"
34
-"                      including register and memory values; can also pause\n"
35
-"                      emulation, set breakpoints, and change state\n"
31
+"    -g, --debug       show logging information while running; add twice (-g -g)\n"
32
+"                      to show more detailed logs, including an emulator trace\n"
33
+"    -s, --scale <n>   scale the game screen by an integer factor\n"
34
+"                      (applies to windowed mode only)\n"
36 35
 "    -a, --assemble <in> [<out>]     convert z80 assembly source code into a\n"
37 36
 "                                    binary file that can be run by crater\n"
38 37
 "    -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[])
202 201
             }
203 202
             config->scale = scale;
204 203
         } else if (!strcmp(arg, "g") || !strcmp(arg, "debug")) {
205
-            config->debug = true;
204
+            config->debug++;
206 205
         } else if (!strcmp(arg, "a") || !strcmp(arg, "assemble")) {
207 206
             if (paths_read >= 1) {
208 207
                 config->src_path = config->rom_path;
@@ -277,7 +276,7 @@ static bool sanity_check(Config* config)
277 276
     } else if (config->assemble && config->disassemble) {
278 277
         ERROR("cannot assemble and disassemble at the same time")
279 278
         return false;
280
-    } else if (assembler && (config->debug || config->fullscreen || config->scale > 1)) {
279
+    } else if (assembler && (config->fullscreen || config->scale > 1)) {
281 280
         ERROR("cannot specify emulator options in assembler mode")
282 281
         return false;
283 282
     } else if (assembler && !config->src_path) {
@@ -309,7 +308,7 @@ int config_create(Config** config_ptr, int argc, char* argv[])
309 308
     Config *config = cr_malloc(sizeof(Config));
310 309
     int retval;
311 310
 
312
-    config->debug = false;
311
+    config->debug = 0;
313 312
     config->assemble = false;
314 313
     config->disassemble = false;
315 314
     config->fullscreen = false;
@@ -342,21 +341,20 @@ void config_destroy(Config *config)
342 341
     free(config);
343 342
 }
344 343
 
345
-#ifdef DEBUG_MODE
346 344
 /*
347
-    DEBUG FUNCTION: Print out all config arguments to stdout.
345
+    @DEBUG_LEVEL
346
+    Print out all config arguments to stdout.
348 347
 */
349 348
 void config_dump_args(const Config* config)
350 349
 {
351 350
     DEBUG("Dumping arguments:")
352
-    DEBUG("- fullscreen:  %s", config->fullscreen ? "true" : "false")
353
-    DEBUG("- scale:       %d", config->scale)
354
-    DEBUG("- debug:       %s", config->debug ? "true" : "false")
351
+    DEBUG("- debug:       %d", config->debug)
355 352
     DEBUG("- assemble:    %s", config->assemble ? "true" : "false")
356 353
     DEBUG("- disassemble: %s", config->disassemble ? "true" : "false")
354
+    DEBUG("- fullscreen:  %s", config->fullscreen ? "true" : "false")
355
+    DEBUG("- scale:       %d", config->scale)
357 356
     DEBUG("- rom_path:    %s", config->rom_path ? config->rom_path : "(null)")
358 357
     DEBUG("- src_path:    %s", config->src_path ? config->src_path : "(null)")
359 358
     DEBUG("- dst_path:    %s", config->dst_path ? config->dst_path : "(null)")
360 359
     DEBUG("- overwrite:   %s", config->overwrite ? "true" : "false")
361 360
 }
362
-#endif

+ 2
- 5
src/config.h View File

@@ -1,4 +1,4 @@
1
-/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
1
+/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
2 2
    Released under the terms of the MIT License. See LICENSE for details. */
3 3
 
4 4
 #pragma once
@@ -21,7 +21,7 @@
21 21
 /* Structs */
22 22
 
23 23
 typedef struct {
24
-    bool debug;
24
+    int debug;
25 25
     bool assemble;
26 26
     bool disassemble;
27 27
     bool fullscreen;
@@ -36,7 +36,4 @@ typedef struct {
36 36
 
37 37
 int config_create(Config**, int, char*[]);
38 38
 void config_destroy(Config*);
39
-
40
-#ifdef DEBUG_MODE
41 39
 void config_dump_args(const Config*);
42
-#endif

+ 5
- 7
src/iomanager.c View File

@@ -1,4 +1,4 @@
1
-/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
1
+/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
2 2
    Released under the terms of the MIT License. See LICENSE for details. */
3 3
 
4 4
 #include <signal.h>
@@ -36,9 +36,8 @@ void iomanager_emulate(GameGear *gg)
36 36
     while (!caught_signal) {
37 37
         if (gamegear_simulate(gg)) {
38 38
             ERROR("caught exception: %s", gamegear_get_exception(gg))
39
-#ifdef DEBUG_MODE
40
-            z80_dump_registers(&gg->cpu);
41
-#endif
39
+            if (DEBUG_LEVEL)
40
+                z80_dump_registers(&gg->cpu);
42 41
             break;
43 42
         }
44 43
         usleep(1000 * 1000 / 60);
@@ -46,9 +45,8 @@ void iomanager_emulate(GameGear *gg)
46 45
 
47 46
     if (caught_signal) {
48 47
         WARN("caught signal, stopping...")
49
-#ifdef DEBUG_MODE
50
-        z80_dump_registers(&gg->cpu);
51
-#endif
48
+        if (DEBUG_LEVEL)
49
+            z80_dump_registers(&gg->cpu);
52 50
     }
53 51
 
54 52
     DEBUG("IOManager unpowering GameGear")

+ 28
- 20
src/logging.h View File

@@ -1,4 +1,4 @@
1
-/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
1
+/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
2 2
    Released under the terms of the MIT License. See LICENSE for details. */
3 3
 
4 4
 #pragma once
@@ -10,30 +10,38 @@
10 10
 
11 11
 /* Internal usage only */
12 12
 
13
-#define LOG_MSG_(dest, level, extra, after, ...)  \
14
-    do {                                          \
15
-        fprintf(dest, level ": " __VA_ARGS__);    \
16
-        extra;                                    \
17
-        fprintf(dest, "\n");                      \
18
-        after;                                    \
13
+#define LOG_MSG_(dest, level, type, extra, after, ...) \
14
+    do {                                               \
15
+        if (logging_level_ >= level) {                 \
16
+            fprintf(dest, type " " __VA_ARGS__);       \
17
+            extra;                                     \
18
+            fprintf(dest, "\n");                       \
19
+            after;                                     \
20
+        }                                              \
19 21
     } while (0);
20 22
 
21 23
 #define LOG_ERR_(...) LOG_MSG_(stderr, __VA_ARGS__)
22 24
 #define LOG_OUT_(...) LOG_MSG_(stdout, __VA_ARGS__)
23 25
 
24
-#define PRINT_ERRNO_() fprintf(stderr, ": %s", strerror(errno))
26
+#define PRINT_ERR_ fprintf(stderr, ": %s", strerror(errno))
27
+#define EXIT_FAIL_ exit(EXIT_FAILURE)
28
+
29
+#define DEBUG_TEXT_ "\x1b[0m\x1b[37m[DEBUG]\x1b[0m"
30
+#define TRACE_TEXT_ "\x1b[1m\x1b[33m[TRACE]\x1b[0m"
31
+
32
+unsigned logging_level_;
25 33
 
26 34
 /* Public logging macros */
27 35
 
28
-#define FATAL(...)       LOG_ERR_("fatal",   {},             exit(EXIT_FAILURE), __VA_ARGS__)
29
-#define FATAL_ERRNO(...) LOG_ERR_("fatal",   PRINT_ERRNO_(), exit(EXIT_FAILURE), __VA_ARGS__)
30
-#define ERROR(...)       LOG_ERR_("error",   {},             {},                 __VA_ARGS__)
31
-#define ERROR_ERRNO(...) LOG_ERR_("error",   PRINT_ERRNO_(), {},                 __VA_ARGS__)
32
-#define WARN(...)        LOG_ERR_("warning", {},             {},                 __VA_ARGS__)
33
-#define WARN_ERRNO(...)  LOG_ERR_("warning", PRINT_ERRNO_(), {},                 __VA_ARGS__)
34
-
35
-#ifdef DEBUG_MODE
36
-#define DEBUG(...)       LOG_OUT_("[DEBUG]", {},             {},                 __VA_ARGS__)
37
-#else
38
-#define DEBUG(...)       {}
39
-#endif
36
+#define FATAL(...)       LOG_ERR_(0, "fatal:",    {},         EXIT_FAIL_, __VA_ARGS__)
37
+#define FATAL_ERRNO(...) LOG_ERR_(0, "fatal:",    PRINT_ERR_, EXIT_FAIL_, __VA_ARGS__)
38
+#define ERROR(...)       LOG_ERR_(0, "error:",    {},         {},         __VA_ARGS__)
39
+#define ERROR_ERRNO(...) LOG_ERR_(0, "error:",    PRINT_ERR_, {},         __VA_ARGS__)
40
+#define WARN(...)        LOG_ERR_(0, "warning:",  {},         {},         __VA_ARGS__)
41
+#define WARN_ERRNO(...)  LOG_ERR_(0, "warning:",  PRINT_ERR_, {},         __VA_ARGS__)
42
+#define DEBUG(...)       LOG_OUT_(1, DEBUG_TEXT_, {},         {},         __VA_ARGS__)
43
+#define TRACE(...)       LOG_OUT_(2, TRACE_TEXT_, {},         {},         __VA_ARGS__)
44
+
45
+#define SET_LOG_LEVEL(level) logging_level_ = (level);
46
+#define DEBUG_LEVEL (logging_level_ >= 1)
47
+#define TRACE_LEVEL (logging_level_ >= 2)

+ 25
- 14
src/mmu.c View File

@@ -1,9 +1,10 @@
1
-/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
1
+/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
2 2
    Released under the terms of the MIT License. See LICENSE for details. */
3 3
 
4 4
 #include <stdlib.h>
5 5
 #include <string.h>
6 6
 
7
+#include "mmu.h"
7 8
 #include "logging.h"
8 9
 #include "util.h"
9 10
 #include "z80.h"
@@ -31,6 +32,27 @@ void mmu_free(MMU *mmu)
31 32
 }
32 33
 
33 34
 /*
35
+    @DEBUG_LEVEL
36
+    Print out the bank mapping.
37
+*/
38
+static void dump_bank_table(const MMU *mmu, const uint8_t *data)
39
+{
40
+    char buffer[49];
41
+    size_t group, elem, bank;
42
+
43
+    DEBUG("Dumping MMU bank table:")
44
+    for (group = 0; group < MMU_NUM_ROM_BANKS / 8; group++) {
45
+        for (elem = 0; elem < 8; elem++) {
46
+            bank = 8 * group + elem;
47
+            snprintf(buffer + 6 * elem, 7, "%02zX=%02zX ", bank,
48
+                     (mmu->rom_banks[bank] - data) >> 14);
49
+        }
50
+        buffer[47] = '\0';
51
+        DEBUG("- %s", buffer)
52
+    }
53
+}
54
+
55
+/*
34 56
     Load a block of ROM into the MMU.
35 57
 
36 58
     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)
55 77
             mmu->rom_banks[mirror] = data + (bank * MMU_ROM_BANK_SIZE);
56 78
     }
57 79
 
58
-#ifdef DEBUG_MODE
59
-    char temp_str[64];
60
-    DEBUG("Dumping MMU bank table:")
61
-    for (size_t group = 0; group < MMU_NUM_ROM_BANKS / 8; group++) {
62
-        for (size_t elem = 0; elem < 8; elem++) {
63
-            bank = 8 * group + elem;
64
-            snprintf(temp_str + 6 * elem, 7, "%02zX=%02zX ", bank,
65
-                     (mmu->rom_banks[bank] - data) >> 14);
66
-        }
67
-        temp_str[47] = '\0';
68
-        DEBUG("- %s", temp_str)
69
-    }
70
-#endif
80
+    if (DEBUG_LEVEL)
81
+        dump_bank_table(mmu, data);
71 82
 }
72 83
 
73 84
 /*

+ 41
- 34
src/rom.c View File

@@ -1,4 +1,4 @@
1
-/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
1
+/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
2 2
    Released under the terms of the MIT License. See LICENSE for details. */
3 3
 
4 4
 #include <ctype.h>
@@ -18,11 +18,29 @@
18 18
 
19 19
 static size_t header_locations[NUM_LOCATIONS] = {0x7FF0, 0x3FF0, 0x1FF0};
20 20
 
21
-#ifdef DEBUG_MODE
22 21
 /*
23
-    DEBUG FUNCTION: Print out the header to stdout.
22
+    @DEBUG_LEVEL
23
+    Given a ROM size, return a pretty string.
24 24
 */
25
-static void print_header(const uint8_t *header)
25
+static const char* size_to_string(size_t size)
26
+{
27
+    static char buffer[SIZE_CODE_BUF];
28
+
29
+    if (!size)
30
+        strncpy(buffer, "unknown", SIZE_CODE_BUF);
31
+    else if (size >= (1 << 20))
32
+        snprintf(buffer, SIZE_CODE_BUF, "%zu MB", size >> 20);
33
+    else
34
+        snprintf(buffer, SIZE_CODE_BUF, "%zu KB", size >> 10);
35
+
36
+    return buffer;
37
+}
38
+
39
+/*
40
+    @DEBUG_LEVEL
41
+    Print out the raw header to stdout.
42
+*/
43
+static void print_header_dump(const uint8_t *header)
26 44
 {
27 45
     char header_hex[3 * HEADER_SIZE], header_chr[3 * HEADER_SIZE];
28 46
 
@@ -40,26 +58,27 @@ static void print_header(const uint8_t *header)
40 58
     DEBUG("- header dump (hex): %s", header_hex)
41 59
     DEBUG("- header dump (chr): %s", header_chr)
42 60
 }
43
-#endif
44 61
 
45
-#ifdef DEBUG_MODE
46 62
 /*
47
-    DEBUG FUNCTION: Given a ROM size, return a pretty string.
63
+    @DEBUG_LEVEL
64
+    Print out the analyzed header to stdout.
48 65
 */
49
-static const char* size_to_string(size_t size)
66
+static void print_header_contents(const ROM *rom, const uint8_t *header)
50 67
 {
51
-    static char buffer[SIZE_CODE_BUF];
52
-
53
-    if (!size)
54
-        strncpy(buffer, "unknown", SIZE_CODE_BUF);
55
-    else if (size >= (1 << 20))
56
-        snprintf(buffer, SIZE_CODE_BUF, "%zu MB", size >> 20);
68
+    DEBUG("- header info:")
69
+    if (rom->reported_checksum == rom->expected_checksum)
70
+        DEBUG("  - checksum:      0x%04X (valid)", rom->reported_checksum)
57 71
     else
58
-        snprintf(buffer, SIZE_CODE_BUF, "%zu KB", size >> 10);
59
-
60
-    return buffer;
72
+        DEBUG("  - checksum:      0x%04X (invalid, expected 0x%04X)",
73
+              rom->reported_checksum, rom->expected_checksum)
74
+    DEBUG("  - product code:  %u (%s)", rom->product_code,
75
+          rom_product(rom) ? rom_product(rom) : "unknown")
76
+    DEBUG("  - version:       %u", rom->version)
77
+    DEBUG("  - region code:   %u (%s)", rom->region_code,
78
+          rom_region(rom) ? rom_region(rom) : "unknown")
79
+    DEBUG("  - reported size: %s",
80
+          size_to_string(size_code_to_bytes(header[0xF] & 0xF)))
61 81
 }
62
-#endif
63 82
 
64 83
 /*
65 84
     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)
88 107
 */
89 108
 static bool parse_header(ROM *rom, const uint8_t *header)
90 109
 {
91
-#ifdef DEBUG_MODE
92
-    print_header(header);
93
-#endif
110
+    if (DEBUG_LEVEL)
111
+        print_header_dump(header);
94 112
 
95 113
     rom->reported_checksum = header[0xA] + (header[0xB] << 8);
96 114
     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)
99 117
     rom->version = header[0xE] & 0x0F;
100 118
     rom->region_code = header[0xF] >> 4;
101 119
 
102
-    DEBUG("- header info:")
103
-    if (rom->reported_checksum == rom->expected_checksum)
104
-        DEBUG("  - checksum:      0x%04X (valid)", rom->reported_checksum)
105
-    else
106
-        DEBUG("  - checksum:      0x%04X (invalid, expected 0x%04X)",
107
-              rom->reported_checksum, rom->expected_checksum)
108
-    DEBUG("  - product code:  %u (%s)", rom->product_code,
109
-          rom_product(rom) ? rom_product(rom) : "unknown")
110
-    DEBUG("  - version:       %u", rom->version)
111
-    DEBUG("  - region code:   %u (%s)", rom->region_code,
112
-          rom_region(rom) ? rom_region(rom) : "unknown")
113
-    DEBUG("  - reported size: %s",
114
-          size_to_string(size_code_to_bytes(header[0xF] & 0xF)))
120
+    if (DEBUG_LEVEL)
121
+        print_header_contents(rom, header);
115 122
     return true;
116 123
 }
117 124
 

+ 18
- 7
src/z80.c View File

@@ -1,8 +1,9 @@
1
-/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
1
+/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
2 2
    Released under the terms of the MIT License. See LICENSE for details. */
3 3
 
4
-#include "logging.h"
5 4
 #include "z80.h"
5
+#include "disassembler.h"
6
+#include "logging.h"
6 7
 
7 8
 #define REG_AF 0
8 9
 #define REG_BC 1
@@ -19,7 +20,6 @@
19 20
 #define FLAG_ZERO      6
20 21
 #define FLAG_SIGN      7
21 22
 
22
-#ifdef DEBUG_MODE
23 23
 #define BINARY_FMT "0b%u%u%u%u%u%u%u%u"  // Used by z80_dump_registers()
24 24
 #define BINARY_VAL(data)       \
25 25
     (data & (1 << 7) ? 1 : 0), \
@@ -30,7 +30,6 @@
30 30
     (data & (1 << 2) ? 1 : 0), \
31 31
     (data & (1 << 1) ? 1 : 0), \
32 32
     (data & (1 << 0) ? 1 : 0)
33
-#endif
34 33
 
35 34
 /*
36 35
     Initialize a Z80 object.
@@ -92,6 +91,7 @@ static inline uint16_t get_pair(Z80 *z80, uint8_t pair)
92 91
         case REG_HL: return (z80->regfile.h << 8) + z80->regfile.l;
93 92
         default: FATAL("invalid call: get_pair(z80, %u)", pair)
94 93
     }
94
+    return 0;
95 95
 }
96 96
 
97 97
 /*
@@ -164,6 +164,16 @@ static inline void increment_refresh_counter(Z80 *z80)
164 164
 #include "z80_ops.inc.c"
165 165
 
166 166
 /*
167
+    @TRACE_LEVEL
168
+    Trace the instruction about to be executed by the CPU.
169
+*/
170
+static inline void trace_instruction(const Z80 *z80)
171
+{
172
+    TRACE("PC @ 0x%04X", z80->regfile.pc)
173
+    // TODO
174
+}
175
+
176
+/*
167 177
     Emulate the given number of cycles of the Z80, or until an exception.
168 178
 
169 179
     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)
175 185
     cycles -= z80->pending_cycles;
176 186
     while (cycles > 0 && !z80->except) {
177 187
         uint8_t opcode = mmu_read_byte(z80->mmu, z80->regfile.pc);
188
+        if (TRACE_LEVEL)
189
+            trace_instruction(z80);
178 190
         increment_refresh_counter(z80);
179 191
         cycles -= (*instruction_lookup_table[opcode])(z80, opcode);
180 192
     }
@@ -183,9 +195,9 @@ bool z80_do_cycles(Z80 *z80, double cycles)
183 195
     return z80->except;
184 196
 }
185 197
 
186
-#ifdef DEBUG_MODE
187 198
 /*
188
-    DEBUG FUNCTION: Print out all register values to stdout.
199
+    @DEBUG_LEVEL
200
+    Print out all register values to stdout.
189 201
 */
190 202
 void z80_dump_registers(const Z80 *z80)
191 203
 {
@@ -233,4 +245,3 @@ void z80_dump_registers(const Z80 *z80)
233 245
     DEBUG("- IFF1: %u", rf->iff1)
234 246
     DEBUG("- IFF2: %u", rf->iff2)
235 247
 }
236
-#endif

+ 1
- 4
src/z80.h View File

@@ -1,4 +1,4 @@
1
-/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
1
+/* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
2 2
    Released under the terms of the MIT License. See LICENSE for details. */
3 3
 
4 4
 #pragma once
@@ -35,7 +35,4 @@ typedef struct {
35 35
 void z80_init(Z80*, MMU*);
36 36
 void z80_power(Z80*);
37 37
 bool z80_do_cycles(Z80*, double);
38
-
39
-#ifdef DEBUG_MODE
40 38
 void z80_dump_registers(const Z80*);
41
-#endif

Loading…
Cancel
Save