From 2c007c3264f43b1e8ddca2c2b9ac1bab90843d2f Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Mon, 25 May 2015 21:32:45 -0400 Subject: [PATCH 01/10] A lot of work on general test infrastructure. --- .gitignore | 1 + README.md | 15 ++++-- makefile | 40 ++++++++------- tests/{z80 => cpu}/01_basic_math.asm | 0 tests/{z80 => cpu}/_header.asm | 0 tests/makefile | 18 +++++++ tests/runner.c | 99 +++++++++++++++++++++++++++++++++++- 7 files changed, 151 insertions(+), 22 deletions(-) rename tests/{z80 => cpu}/01_basic_math.asm (100%) rename tests/{z80 => cpu}/_header.asm (100%) create mode 100644 tests/makefile diff --git a/.gitignore b/.gitignore index 18eb94a..f5cc384 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ roms/* !roms/README crater crater-dev +tests/runner diff --git a/README.md b/README.md index 948fb94..fcd8097 100644 --- a/README.md +++ b/README.md @@ -24,12 +24,19 @@ Installing ---------- Only OS X and Linux are tested. You'll need a modern compiler that supports C11 -(clang preferred) and SDL 2. Using Homebrew, you can `brew install sdl2`; using -apt, you can `apt-get install libsdl2-dev`. +([clang][clang] preferred) and [SDL 2][sdl2]. Using Homebrew, you can +`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 (they can exist simultaneously), run `make DEBUG=1`, which creates -`./crater-dev`. This also enables the printing of debugging info to stdout. +symbols and extra diagnostic info (they can exist simultaneously), 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 +`{component}` is one of `cpu`, `vdp`, `psg`, `asm`, `dis`, or `integrate`. + +[clang]: http://clang.llvm.org/ +[sdl2]: https://www.libsdl.org/ Usage ----- diff --git a/makefile b/makefile index fdf785b..61ba471 100644 --- a/makefile +++ b/makefile @@ -1,50 +1,59 @@ -# Copyright (C) 2014 Ben Kurtovic +# Copyright (C) 2014-2015 Ben Kurtovic # Released under the terms of the MIT License. See LICENSE for details. PROGRAM = crater SOURCES = src BUILD = build DEVEXT = -dev +TESTS = cpu vdp psg asm dis integrate CC = clang FLAGS = -O2 -Wall -Wextra -pedantic -std=c11 CFLAGS = $(shell sdl2-config --cflags) LIBS = $(shell sdl2-config --libs) +DFLAGS = -g -DDEBUG_MODE 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))) DEPS = $(OBJS:%.o=%.d) DIRS = $(sort $(dir $(OBJS))) +TCPS = $(addprefix test-,$(TESTS)) ifdef DEBUG - BNRY := $(BNRY)$(DEVEXT) - FLAGS += -g -DDEBUG_MODE - MODE = debug + BNRY := $(BNRY)$(DEVEXT) + FLGS += $(DFLAGS) + MODE = debug endif -.PHONY: all clean test test-all test-z80 test-asm test-dasm +export CC +export FLAGS +export RM + +.PHONY: all clean test-prereqs test tests $(TCPS) all: $(BNRY) clean: $(RM) $(BUILD) $(PROGRAM) $(PROGRAM)$(DEVEXT) + $(MAKE) -C tests clean $(DIRS): $(MKDIR) $@ $(BNRY): $(OBJS) - $(CC) $(FLAGS) $(LIBS) $(OBJS) -o $@ + $(CC) $(FLGS) $(LIBS) $(OBJS) -o $@ $(OBJS): | $(DIRS) $(BUILD)/$(MODE)/%.o: %.c - $(CC) $(FLAGS) $(CFLAGS) -MMD -MP -c $< -o $@ + $(CC) $(FLGS) $(CFLAGS) -MMD -MP -c $< -o $@ -include $(DEPS) @@ -52,16 +61,13 @@ ASM_INST = $(SOURCES)/assembler/instructions $(ASM_INST).inc.c: $(ASM_INST).yml $(ASM_UP) python $(ASM_UP) -test: test-all test-z80 test-asm test-dasm - -test-all: - @echo "running all tests" +test-prereqs: + $(MAKE) $(PROGRAM) DEBUG= -test-z80: - @echo "running Z80 CPU tests" +test: test-prereqs + $(MAKE) -C tests all -test-asm: - @echo "running assembler tests" +tests: test -test-dasm: - @echo "running disassembler tests" +$(TCPS): test-prereqs + $(MAKE) -C tests $(subst test-,,$@) diff --git a/tests/z80/01_basic_math.asm b/tests/cpu/01_basic_math.asm similarity index 100% rename from tests/z80/01_basic_math.asm rename to tests/cpu/01_basic_math.asm diff --git a/tests/z80/_header.asm b/tests/cpu/_header.asm similarity index 100% rename from tests/z80/_header.asm rename to tests/cpu/_header.asm diff --git a/tests/makefile b/tests/makefile new file mode 100644 index 0000000..f202e5f --- /dev/null +++ b/tests/makefile @@ -0,0 +1,18 @@ +# Copyright (C) 2014-2015 Ben Kurtovic +# Released under the terms of the MIT License. See LICENSE for details. + +RUNNER = runner +COMPONENTS = cpu vdp psg asm dis integrate + +.PHONY: all clean $(COMPONENTS) + +all: $(COMPONENTS) + +clean: + $(RM) $(RUNNER) + +$(RUNNER): $(RUNNER).c + $(CC) $(FLAGS) $< -o $@ + +$(COMPONENTS): $(RUNNER) + ./$(RUNNER) $@ diff --git a/tests/runner.c b/tests/runner.c index 1763ea4..44a9e4c 100644 --- a/tests/runner.c +++ b/tests/runner.c @@ -1,4 +1,101 @@ /* Copyright (C) 2014-2015 Ben Kurtovic Released under the terms of the MIT License. See LICENSE for details. */ -// ... +#include +#include +#include +#include + +#include "../src/logging.h" + +/* + TODO +*/ +static bool test_cpu() +{ + // TODO + return true; +} + +/* + TODO +*/ +static bool test_vdp() +{ + // TODO + return true; +} + +/* + TODO +*/ +static bool test_psg() +{ + // TODO + return true; +} + +/* + TODO +*/ +static bool test_asm() +{ + // TODO + return true; +} + +/* + TODO +*/ +static bool test_dis() +{ + // TODO + return true; +} + +/* + TODO +*/ +static bool test_integrate() +{ + // TODO + return true; +} + + +/* + Main function. +*/ +int main(int argc, char *argv[]) +{ + if (argc != 2) + FATAL("a component name is required") + + const char *component = argv[1], *name; + bool (*func)(); + + if (!strcmp(component, "cpu")) { + name = "Z80 CPU"; + func = test_cpu; + } else if (!strcmp(component, "vdp")) { + name = "VDP"; + func = test_vdp; + } else if (!strcmp(component, "psg")) { + name = "SN76489 PSG"; + func = test_psg; + } else if (!strcmp(component, "asm")) { + name = "assembler"; + func = test_asm; + } else if (!strcmp(component, "dis")) { + name = "disassembler"; + func = test_dis; + } else if (!strcmp(component, "integrate")) { + name = "integration"; + func = test_integrate; + } else { + FATAL("unknown component: %s", component) + } + + printf("crater: running %s tests\n", name); + return func() ? EXIT_SUCCESS : EXIT_FAILURE; +} From 0b2f3c00890e60f0110edb6e6acde1d233453eab Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Fri, 21 Aug 2015 22:37:46 -0400 Subject: [PATCH 02/10] Minor update to docs. --- tests/runner.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/tests/runner.c b/tests/runner.c index 44a9e4c..34db5af 100644 --- a/tests/runner.c +++ b/tests/runner.c @@ -9,7 +9,7 @@ #include "../src/logging.h" /* - TODO + Run tests for the Z80 CPU. */ static bool test_cpu() { @@ -18,7 +18,7 @@ static bool test_cpu() } /* - TODO + Run tests for the VDP. */ static bool test_vdp() { @@ -27,7 +27,7 @@ static bool test_vdp() } /* - TODO + Run tests for the SN76489 PSG. */ static bool test_psg() { @@ -36,7 +36,7 @@ static bool test_psg() } /* - TODO + Run tests for the assembler. */ static bool test_asm() { @@ -45,7 +45,7 @@ static bool test_asm() } /* - TODO + Run tests for the disassembler. */ static bool test_dis() { @@ -54,7 +54,7 @@ static bool test_dis() } /* - TODO + Run integration tests (i.e., multiple components working together). */ static bool test_integrate() { @@ -62,14 +62,13 @@ static bool test_integrate() return true; } - /* Main function. */ int main(int argc, char *argv[]) { if (argc != 2) - FATAL("a component name is required") + FATAL("a single component name is required") const char *component = argv[1], *name; bool (*func)(); From e66b158aa9fdda92517f56e32b59ab9b241c43d0 Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Fri, 8 Apr 2016 03:52:42 -0500 Subject: [PATCH 03/10] Copyright year bumps; minor tweaks. --- LICENSE | 2 +- makefile | 19 +++++++++++-------- src/assembler/instructions.c | 2 -- src/config.c | 2 +- src/logging.h | 5 +++-- src/rom.c | 2 +- src/z80_ops.inc.c | 2 +- 7 files changed, 18 insertions(+), 16 deletions(-) diff --git a/LICENSE b/LICENSE index 0764864..1811091 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (C) 2014-2015 Ben Kurtovic +Copyright (C) 2014-2016 Ben Kurtovic Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/makefile b/makefile index 61ba471..fdd9618 100644 --- a/makefile +++ b/makefile @@ -1,4 +1,4 @@ -# Copyright (C) 2014-2015 Ben Kurtovic +# Copyright (C) 2014-2016 Ben Kurtovic # Released under the terms of the MIT License. See LICENSE for details. PROGRAM = crater @@ -36,7 +36,7 @@ export CC export FLAGS export RM -.PHONY: all clean test-prereqs test tests $(TCPS) +.PHONY: all clean test tests test-prereqs test-make-prereqs $(TCPS) all: $(BNRY) @@ -61,13 +61,16 @@ ASM_INST = $(SOURCES)/assembler/instructions $(ASM_INST).inc.c: $(ASM_INST).yml $(ASM_UP) python $(ASM_UP) -test-prereqs: - $(MAKE) $(PROGRAM) DEBUG= +test-prereqs: $(PROGRAM) + @: # No-op; prevents make from cluttering output with "X is up to date" -test: test-prereqs - $(MAKE) -C tests all +test-make-prereqs: + @$(MAKE) test-prereqs DEBUG= + +test: test-make-prereqs + @$(MAKE) -C tests -s all tests: test -$(TCPS): test-prereqs - $(MAKE) -C tests $(subst test-,,$@) +$(TCPS): test-make-prereqs + @$(MAKE) -C tests -s $(subst test-,,$@) diff --git a/src/assembler/instructions.c b/src/assembler/instructions.c index 04e0cea..e268ebf 100644 --- a/src/assembler/instructions.c +++ b/src/assembler/instructions.c @@ -98,8 +98,6 @@ static ASMErrorDesc parse_inst_##mnemonic( \ #define INST_INDEX_PREFIX(n) INST_PREFIX_(INST_INDEX(n).reg) -/* ----------------------------- END WORK BLOCK ---------------------------- */ - /* Fill an instruction's byte array with the given data. diff --git a/src/config.c b/src/config.c index 1777772..d13fb14 100644 --- a/src/config.c +++ b/src/config.c @@ -90,7 +90,7 @@ static int get_rom_paths(char ***path_ptr) } closedir(dirp); } else { - WARN_ERRNO("couldn't open 'roms/'") + WARN_ERRNO("couldn't open '" ROMS_DIR "/'") } *path_ptr = paths; return npaths; diff --git a/src/logging.h b/src/logging.h index a40e3cd..16e2a90 100644 --- a/src/logging.h +++ b/src/logging.h @@ -10,12 +10,13 @@ /* Internal usage only */ -#define LOG_MSG_(dest, level, extra, after, ...) { \ +#define LOG_MSG_(dest, level, extra, after, ...) \ + do { \ fprintf(dest, level ": " __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__) diff --git a/src/rom.c b/src/rom.c index 2083dd6..1185f7b 100644 --- a/src/rom.c +++ b/src/rom.c @@ -32,7 +32,7 @@ static void print_header(const uint8_t *header) snprintf(&header_chr[3 * i], 3, "%2c", header[i]); else { header_chr[3 * i] = ' '; - header_chr[3 * i + 1] = '?'; + header_chr[3 * i + 1] = '.'; } header_hex[3 * i + 2] = header_chr[3 * i + 2] = ' '; } diff --git a/src/z80_ops.inc.c b/src/z80_ops.inc.c index 787f590..835f5ff 100644 --- a/src/z80_ops.inc.c +++ b/src/z80_ops.inc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2015 Ben Kurtovic +/* Copyright (C) 2014-2016 Ben Kurtovic Released under the terms of the MIT License. See LICENSE for details. */ /* From 04645ef72f8fe2ad7c244cf79ec36b2cb0a1e1ff Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Fri, 8 Apr 2016 03:53:10 -0500 Subject: [PATCH 04/10] Sketch out most of the ASM test runner. --- .gitignore | 1 + tests/asm/full/empty.asm | 0 tests/asm/full/manifest | 1 + tests/asm/full/roms.tar.gz | Bin 0 -> 198 bytes tests/makefile | 11 ++- tests/runner.c | 170 ++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 179 insertions(+), 4 deletions(-) create mode 100644 tests/asm/full/empty.asm create mode 100644 tests/asm/full/manifest create mode 100644 tests/asm/full/roms.tar.gz diff --git a/.gitignore b/.gitignore index f5cc384..b3b5627 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ roms/* crater crater-dev tests/runner +tests/asm/full/*.gg diff --git a/tests/asm/full/empty.asm b/tests/asm/full/empty.asm new file mode 100644 index 0000000..e69de29 diff --git a/tests/asm/full/manifest b/tests/asm/full/manifest new file mode 100644 index 0000000..d0eedad --- /dev/null +++ b/tests/asm/full/manifest @@ -0,0 +1 @@ +empty.asm empty.gg diff --git a/tests/asm/full/roms.tar.gz b/tests/asm/full/roms.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..0c2c3e8f7913d12e42c931d7d44cde841a60e6ae GIT binary patch literal 198 zcmb2|=3p?$WDjRxetX`~@34aa>jhgT_Zz|w3RB)#u`cqO{DjG|>#l`H*IT9K?CKLU zCImS$?g@W0|LVV_GIN=(vRA*8>Mi=7A7AHvUtj6fs#DW*UM8MH1?#p{lz5e$$FMr+Ew{ySm`1{znzO$SGKlstUZFT8AoBcY$ aRTj&p{9=KqJ~00S +# Copyright (C) 2014-2016 Ben Kurtovic # Released under the terms of the MIT License. See LICENSE for details. RUNNER = runner @@ -10,9 +10,18 @@ all: $(COMPONENTS) clean: $(RM) $(RUNNER) + rm asm/full/*.gg $(RUNNER): $(RUNNER).c $(CC) $(FLAGS) $< -o $@ $(COMPONENTS): $(RUNNER) ./$(RUNNER) $@ + +asm: asm-unarchive + +asm-archive: + tar -czf asm/full/roms.tar.gz asm/full/*.gg + +asm-unarchive: + tar -xf asm/full/roms.tar.gz diff --git a/tests/runner.c b/tests/runner.c index 34db5af..40b5cb5 100644 --- a/tests/runner.c +++ b/tests/runner.c @@ -1,12 +1,176 @@ -/* Copyright (C) 2014-2015 Ben Kurtovic +/* Copyright (C) 2014-2016 Ben Kurtovic Released under the terms of the MIT License. See LICENSE for details. */ #include #include #include #include +#include #include "../src/logging.h" +#include "../src/util.h" + +#define ASM_FULL "asm/full/" +#define ASM_OUTFILE ASM_FULL ".output.gg" + +/* Helper macros for reporting test passings/failures */ + +#define PASS_TEST() \ + do { \ + printf("."); \ + fflush(stdout); \ + passed_tests++; \ + pending_nl = true; \ + } while(0); + +#define FAIL_TEST(format, ...) \ + do { \ + printf("F\n"); \ + fprintf(stderr, "***** FAILURE *****\n" format "\n", __VA_ARGS__); \ + failed_tests++; \ + pending_nl = false; \ + } while(0); + +#define READY_STDOUT() \ + do { \ + if (pending_nl) { \ + printf("\n"); \ + pending_nl = false; \ + } \ + } while(0); + +static int passed_tests = 0, failed_tests = 0; +static bool pending_nl = false; + +/* + Prints out the test report. Called before exiting using atexit(). +*/ +static void finalize() { + READY_STDOUT() + if (failed_tests) + printf("fail (%d/%d)\n", passed_tests, passed_tests + failed_tests); + else + printf("pass (%d/%d)\n", passed_tests, passed_tests); +} + +/* + Compare two files. If they are identical, then return true. Otherwise, + return false and print an error message showing the difference. +*/ +static bool diff_files(const char *expected_path, const char *actual_path) +{ + bool same = false; + FILE *expected = NULL, *actual = NULL; + + if (!(expected = fopen(expected_path, "rb"))) { + FAIL_TEST("missing reference file: %s", expected_path) + goto cleanup; + } + if (!(actual = fopen(actual_path, "rb"))) { + FAIL_TEST("missing output file: %s", actual_path) + goto cleanup; + } + + size_t len = 0; + int e, a; + while ((e = fgetc(expected)) != EOF) { + a = fgetc(actual); + if (a == EOF) { + FAIL_TEST("files differ: output file too short (index %zu)", len) + goto cleanup; + } + if (e != a) { + FAIL_TEST("files differ: 0x%02X != 0x%02X (expected vs. actual at " + "index %zu)", e, a, len) + goto cleanup; + } + len++; + } + + if (fgetc(actual) != EOF) { + FAIL_TEST("files differ: junk at end of output file (index %zu)", len) + goto cleanup; + } + + same = true; + + cleanup: + if (expected) + fclose(expected); + if (actual) + fclose(actual); + return same; +} + +/* + Run a single ASM->ROM test, converting the given source file to a temporary + output file, compared against the reference file. +*/ +static bool run_full_asm_test(const char *src_file, const char *ref_file) +{ + char *cmd_prefix = "../crater --assemble " ASM_FULL; + char *cmd = cr_malloc(sizeof(char) * + (strlen(cmd_prefix) + strlen(ASM_OUTFILE) + strlen(src_file)) + 2); + + // Construct the command by concatenating: + // ../crater --assemble asm/full/ asm/full/.output.gg + stpcpy(stpcpy(stpcpy(cmd, cmd_prefix), src_file), " " ASM_OUTFILE); + unlink(ASM_OUTFILE); + system(cmd); + free(cmd); + + // Construct the full reference file path in a temporary variable and diff + // it with the output file: + char *ref_path = malloc(sizeof(char) * + (strlen(ASM_FULL) + strlen(ref_file) + 1)); + stpcpy(stpcpy(ref_path, ASM_FULL), ref_file); + bool diff = diff_files(ref_path, ASM_OUTFILE); + free(ref_path); + return diff; +} + +/* + Run all "full"/"complete" ASM->ROM tests. +*/ +static bool run_full_asm_tests() +{ + FILE *fp = fopen(ASM_FULL "manifest", "r"); + if (!fp) { + ERROR_ERRNO("couldn't open manifest file") + return false; + } + + char *line = NULL, *split; + size_t cap = 0, lineno = 0; + ssize_t len; + + while ((len = getline(&line, &cap, fp)) > 0) { + lineno++; + line[--len] = '\0'; + if (!len) + continue; + + // TODO: validate chars + + split = strchr(line, ' '); + if (!split || strchr(split + 1, ' ')) { + READY_STDOUT() + ERROR("bad format in manifest file on line %zu", lineno) + return false; + } + + *(split++) = '\0'; + if (!run_full_asm_test(line, split)) { + fprintf(stderr, "test: %s -> %s\n", line, split); + return false; + } + PASS_TEST() + } + + unlink(ASM_OUTFILE); + free(line); + return true; +} /* Run tests for the Z80 CPU. @@ -40,8 +204,7 @@ static bool test_psg() */ static bool test_asm() { - // TODO - return true; + return run_full_asm_tests(); } /* @@ -96,5 +259,6 @@ int main(int argc, char *argv[]) } printf("crater: running %s tests\n", name); + atexit(finalize); return func() ? EXIT_SUCCESS : EXIT_FAILURE; } From 3f12049ee5f3aba7f1bcd0bf47236206bb103d95 Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Fri, 8 Apr 2016 04:08:11 -0500 Subject: [PATCH 05/10] Merge full ASM tests into regular ASM tests. --- .gitignore | 2 +- makefile | 2 +- tests/asm/{full => }/empty.asm | 0 tests/asm/full/roms.tar.gz | Bin 198 -> 0 bytes tests/asm/{full => }/manifest | 0 tests/asm/roms.tar.gz | Bin 0 -> 194 bytes tests/makefile | 6 +-- tests/runner.c | 86 +++++++++++++++++++---------------------- 8 files changed, 45 insertions(+), 51 deletions(-) rename tests/asm/{full => }/empty.asm (100%) delete mode 100644 tests/asm/full/roms.tar.gz rename tests/asm/{full => }/manifest (100%) create mode 100644 tests/asm/roms.tar.gz diff --git a/.gitignore b/.gitignore index b3b5627..bdf39ee 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,4 @@ roms/* crater crater-dev tests/runner -tests/asm/full/*.gg +tests/asm/*.gg diff --git a/makefile b/makefile index fdd9618..6793148 100644 --- a/makefile +++ b/makefile @@ -42,7 +42,7 @@ all: $(BNRY) clean: $(RM) $(BUILD) $(PROGRAM) $(PROGRAM)$(DEVEXT) - $(MAKE) -C tests clean + @$(MAKE) -C tests clean $(DIRS): $(MKDIR) $@ diff --git a/tests/asm/full/empty.asm b/tests/asm/empty.asm similarity index 100% rename from tests/asm/full/empty.asm rename to tests/asm/empty.asm diff --git a/tests/asm/full/roms.tar.gz b/tests/asm/full/roms.tar.gz deleted file mode 100644 index 0c2c3e8f7913d12e42c931d7d44cde841a60e6ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 198 zcmb2|=3p?$WDjRxetX`~@34aa>jhgT_Zz|w3RB)#u`cqO{DjG|>#l`H*IT9K?CKLU zCImS$?g@W0|LVV_GIN=(vRA*8>Mi=7A7AHvUtj6fs#DW*UM8MH1?#p{lz5e$$FMr+Ew{ySm`1{znzO$SGKlstUZFT8AoBcY$ aRTj&p{9=KqJ~00Sjhh Uc~I3qg!eH#(0gUhuz-O90Qa#>jsO4v literal 0 HcmV?d00001 diff --git a/tests/makefile b/tests/makefile index b2da06d..fb7b410 100644 --- a/tests/makefile +++ b/tests/makefile @@ -10,7 +10,7 @@ all: $(COMPONENTS) clean: $(RM) $(RUNNER) - rm asm/full/*.gg + $(RM) asm/*.gg $(RUNNER): $(RUNNER).c $(CC) $(FLAGS) $< -o $@ @@ -21,7 +21,7 @@ $(COMPONENTS): $(RUNNER) asm: asm-unarchive asm-archive: - tar -czf asm/full/roms.tar.gz asm/full/*.gg + tar -czf asm/roms.tar.gz asm/*.gg asm-unarchive: - tar -xf asm/full/roms.tar.gz + tar -xf asm/roms.tar.gz diff --git a/tests/runner.c b/tests/runner.c index 40b5cb5..341ed80 100644 --- a/tests/runner.c +++ b/tests/runner.c @@ -10,8 +10,8 @@ #include "../src/logging.h" #include "../src/util.h" -#define ASM_FULL "asm/full/" -#define ASM_OUTFILE ASM_FULL ".output.gg" +#define ASM_PREFIX "asm/" +#define ASM_OUTFILE ASM_PREFIX ".output.gg" /* Helper macros for reporting test passings/failures */ @@ -106,14 +106,14 @@ static bool diff_files(const char *expected_path, const char *actual_path) Run a single ASM->ROM test, converting the given source file to a temporary output file, compared against the reference file. */ -static bool run_full_asm_test(const char *src_file, const char *ref_file) +static bool run_asm_test(const char *src_file, const char *ref_file) { - char *cmd_prefix = "../crater --assemble " ASM_FULL; + char *cmd_prefix = "../crater --assemble " ASM_PREFIX; char *cmd = cr_malloc(sizeof(char) * (strlen(cmd_prefix) + strlen(ASM_OUTFILE) + strlen(src_file)) + 2); // Construct the command by concatenating: - // ../crater --assemble asm/full/ asm/full/.output.gg + // ../crater --assemble asm/ asm/.output.gg stpcpy(stpcpy(stpcpy(cmd, cmd_prefix), src_file), " " ASM_OUTFILE); unlink(ASM_OUTFILE); system(cmd); @@ -122,19 +122,48 @@ static bool run_full_asm_test(const char *src_file, const char *ref_file) // Construct the full reference file path in a temporary variable and diff // it with the output file: char *ref_path = malloc(sizeof(char) * - (strlen(ASM_FULL) + strlen(ref_file) + 1)); - stpcpy(stpcpy(ref_path, ASM_FULL), ref_file); + (strlen(ASM_PREFIX) + strlen(ref_file) + 1)); + stpcpy(stpcpy(ref_path, ASM_PREFIX), ref_file); bool diff = diff_files(ref_path, ASM_OUTFILE); free(ref_path); return diff; } +/* --------------------------- Main test runners --------------------------- */ + +/* + Run tests for the Z80 CPU. +*/ +static bool test_cpu() +{ + // TODO + return true; +} + +/* + Run tests for the VDP. +*/ +static bool test_vdp() +{ + // TODO + return true; +} + +/* + Run tests for the SN76489 PSG. +*/ +static bool test_psg() +{ + // TODO + return true; +} + /* - Run all "full"/"complete" ASM->ROM tests. + Run tests for the assembler. */ -static bool run_full_asm_tests() +static bool test_asm() { - FILE *fp = fopen(ASM_FULL "manifest", "r"); + FILE *fp = fopen(ASM_PREFIX "manifest", "r"); if (!fp) { ERROR_ERRNO("couldn't open manifest file") return false; @@ -160,7 +189,7 @@ static bool run_full_asm_tests() } *(split++) = '\0'; - if (!run_full_asm_test(line, split)) { + if (!run_asm_test(line, split)) { fprintf(stderr, "test: %s -> %s\n", line, split); return false; } @@ -173,41 +202,6 @@ static bool run_full_asm_tests() } /* - Run tests for the Z80 CPU. -*/ -static bool test_cpu() -{ - // TODO - return true; -} - -/* - Run tests for the VDP. -*/ -static bool test_vdp() -{ - // TODO - return true; -} - -/* - Run tests for the SN76489 PSG. -*/ -static bool test_psg() -{ - // TODO - return true; -} - -/* - Run tests for the assembler. -*/ -static bool test_asm() -{ - return run_full_asm_tests(); -} - -/* Run tests for the disassembler. */ static bool test_dis() From 1ddb484cfc352bf7f6696685a2b685b984adce78 Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Fri, 8 Apr 2016 04:26:41 -0500 Subject: [PATCH 06/10] Validate characters in manifest file paths. --- tests/runner.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/tests/runner.c b/tests/runner.c index 341ed80..5a62358 100644 --- a/tests/runner.c +++ b/tests/runner.c @@ -62,14 +62,14 @@ static bool diff_files(const char *expected_path, const char *actual_path) bool same = false; FILE *expected = NULL, *actual = NULL; - if (!(expected = fopen(expected_path, "rb"))) { - FAIL_TEST("missing reference file: %s", expected_path) - goto cleanup; - } if (!(actual = fopen(actual_path, "rb"))) { FAIL_TEST("missing output file: %s", actual_path) goto cleanup; } + if (!(expected = fopen(expected_path, "rb"))) { + FAIL_TEST("missing reference file: %s", expected_path) + goto cleanup; + } size_t len = 0; int e, a; @@ -103,6 +103,14 @@ static bool diff_files(const char *expected_path, const char *actual_path) } /* + Return whether the given character is valid within a filename. +*/ +static bool is_valid_filename_char(char c) { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || c == '.' || c == '_' || c == '-'; +} + +/* Run a single ASM->ROM test, converting the given source file to a temporary output file, compared against the reference file. */ @@ -169,8 +177,8 @@ static bool test_asm() return false; } - char *line = NULL, *split; - size_t cap = 0, lineno = 0; + char *line = NULL, *split, c; + size_t cap = 0, lineno = 0, i; ssize_t len; while ((len = getline(&line, &cap, fp)) > 0) { @@ -179,7 +187,14 @@ static bool test_asm() if (!len) continue; - // TODO: validate chars + i = 0; + while ((c = line[i++])) { + if (!is_valid_filename_char(c) && c != ' ') { + READY_STDOUT() + ERROR("bad character in manifest file on line %zu", lineno) + return false; + } + } split = strchr(line, ' '); if (!split || strchr(split + 1, ' ')) { From 8095143debe8db0f864e18d19185b33fd5cf9c70 Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Fri, 8 Apr 2016 11:31:30 -0500 Subject: [PATCH 07/10] Add ASM tests --- tests/asm/{empty.asm => 01-empty.asm} | 0 tests/asm/02-headers1.asm | 8 ++++++++ tests/asm/03-headers2.asm | 8 ++++++++ tests/asm/04-basic.asm | 13 +++++++++++++ tests/asm/05-includes.asm | 8 ++++++++ tests/asm/05.inc1.asm | 13 +++++++++++++ tests/asm/05.inc2.asm | 3 +++ tests/asm/05.inc3.asm | 2 ++ tests/asm/05.inc4.asm | 3 +++ tests/asm/manifest | 6 +++++- tests/asm/roms.tar.gz | Bin 194 -> 807 bytes tests/runner.c | 13 +++++++------ 12 files changed, 70 insertions(+), 7 deletions(-) rename tests/asm/{empty.asm => 01-empty.asm} (100%) create mode 100644 tests/asm/02-headers1.asm create mode 100644 tests/asm/03-headers2.asm create mode 100644 tests/asm/04-basic.asm create mode 100644 tests/asm/05-includes.asm create mode 100644 tests/asm/05.inc1.asm create mode 100644 tests/asm/05.inc2.asm create mode 100644 tests/asm/05.inc3.asm create mode 100644 tests/asm/05.inc4.asm diff --git a/tests/asm/empty.asm b/tests/asm/01-empty.asm similarity index 100% rename from tests/asm/empty.asm rename to tests/asm/01-empty.asm diff --git a/tests/asm/02-headers1.asm b/tests/asm/02-headers1.asm new file mode 100644 index 0000000..a991487 --- /dev/null +++ b/tests/asm/02-headers1.asm @@ -0,0 +1,8 @@ +.rom_size auto +.rom_header auto +.rom_product 0 +.rom_version 0 +.rom_region "GG Export" +.rom_checksum off +.rom_declsize auto +.cross_blocks auto diff --git a/tests/asm/03-headers2.asm b/tests/asm/03-headers2.asm new file mode 100644 index 0000000..9ebea50 --- /dev/null +++ b/tests/asm/03-headers2.asm @@ -0,0 +1,8 @@ +.rom_size "64 KB" +.rom_header $7FF0 +.rom_product 101893 +.rom_version 3 +.rom_region "GG International" +.rom_checksum on +.rom_declsize "32 KB" +.cross_blocks off diff --git a/tests/asm/04-basic.asm b/tests/asm/04-basic.asm new file mode 100644 index 0000000..8a8d034 --- /dev/null +++ b/tests/asm/04-basic.asm @@ -0,0 +1,13 @@ +.org $0000 +main: + di + ld a, $23 + inc a + call foo + +foo: + push bc + xor c + ret z + rrca + ret diff --git a/tests/asm/05-includes.asm b/tests/asm/05-includes.asm new file mode 100644 index 0000000..46e80c8 --- /dev/null +++ b/tests/asm/05-includes.asm @@ -0,0 +1,8 @@ +.include "05.inc1.asm" + +.org $0000 +main: + di + ld c, $FA + inc c + call bar diff --git a/tests/asm/05.inc1.asm b/tests/asm/05.inc1.asm new file mode 100644 index 0000000..1a2fe8c --- /dev/null +++ b/tests/asm/05.inc1.asm @@ -0,0 +1,13 @@ +.org $0100 + +.include "05.inc2.asm" +.include "05.inc3.asm" + +bar: + push de + call blah + xor d + ret pe + call testfunc + exx + ret diff --git a/tests/asm/05.inc2.asm b/tests/asm/05.inc2.asm new file mode 100644 index 0000000..83b7a98 --- /dev/null +++ b/tests/asm/05.inc2.asm @@ -0,0 +1,3 @@ +testfunc: + sub b + ret diff --git a/tests/asm/05.inc3.asm b/tests/asm/05.inc3.asm new file mode 100644 index 0000000..aa42dc4 --- /dev/null +++ b/tests/asm/05.inc3.asm @@ -0,0 +1,2 @@ +.include "05.inc4.asm" +.rom_product 57005 diff --git a/tests/asm/05.inc4.asm b/tests/asm/05.inc4.asm new file mode 100644 index 0000000..4e2f059 --- /dev/null +++ b/tests/asm/05.inc4.asm @@ -0,0 +1,3 @@ +blah: + ei + ret diff --git a/tests/asm/manifest b/tests/asm/manifest index d0eedad..267f419 100644 --- a/tests/asm/manifest +++ b/tests/asm/manifest @@ -1 +1,5 @@ -empty.asm empty.gg +01-empty.asm 01-empty.gg +02-headers1.asm 02-headers1.gg +03-headers2.asm 03-headers2.gg +04-basic.asm 04-basic.gg +05-includes.asm 05-includes.gg diff --git a/tests/asm/roms.tar.gz b/tests/asm/roms.tar.gz index 7714e891e2f2fc1bb40c19b39d79d0f89bc48098..dfb1ed91f45f6b4ddf811315b9781bbb7dd3bab6 100644 GIT binary patch literal 807 zcmb2|=3qE{hdrEu`R%2RSvsK->>r9wl}F zc|!e;f8JVr_(sa6XEtHqcbrdul+S=4{E)Y@v^jPBH+!|_-aS5=u_b?V)K{&&{`g(a zo)@RTmCTZhbulTO`+ifd+v%RHt^FFOO{cHwz0~(=m8RvXyxZ@V$@IrRU5MT8q|5IG z@mtPd_VCFE4f*%-Zu5KGzf*U#}LPd+*8bHv@pcJn)Z_q!9Y_(sd*!;5S7)Nh!6>GWxNyZ;|= z`+jG{ucx8D85ApfOK*LBzJA;C%U?v47Oi|;GdOM$$kInv*+)tZvA|Fzy1Hd+)g*2UDu7@ zYK9N{=E%rBef+n1@05Mk{*YL5i+=t&T>N_abCWk`;@1% zysx@ty8CMS_61E33hFz){?moh`m4HaTFW2*ytOki$0)K`ZgusY=f)quUADL1`S-)o zW%HjNtEvBd{p{@9{BeK&9M7%#`1|a#*MwX)5AL!$$@-F?UtO6%Iv&`+l>fD<*@Z!Y GnE?O@fmP@L literal 194 zcmb2|=3r1OVGn0uetX_9?~sE4>jhh Uc~I3qg!eH#(0gUhuz-O90Qa#>jsO4v diff --git a/tests/runner.c b/tests/runner.c index 5a62358..3c54e34 100644 --- a/tests/runner.c +++ b/tests/runner.c @@ -23,12 +23,13 @@ pending_nl = true; \ } while(0); -#define FAIL_TEST(format, ...) \ - do { \ - printf("F\n"); \ - fprintf(stderr, "***** FAILURE *****\n" format "\n", __VA_ARGS__); \ - failed_tests++; \ - pending_nl = false; \ +#define FAIL_MSG "***** FAILURE *****" +#define FAIL_TEST(format, ...) \ + do { \ + printf("F\n"); \ + fprintf(stderr, FAIL_MSG "\n" format "\n", __VA_ARGS__); \ + failed_tests++; \ + pending_nl = false; \ } while(0); #define READY_STDOUT() \ From a3b943aebb0d9f2ff38e9ce2b411e721ee328ab3 Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Fri, 8 Apr 2016 14:16:50 -0500 Subject: [PATCH 08/10] Fix implementation of ASCIIz strings. --- src/assembler/tokenizer.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/assembler/tokenizer.c b/src/assembler/tokenizer.c index c55b51e..2028a45 100644 --- a/src/assembler/tokenizer.c +++ b/src/assembler/tokenizer.c @@ -276,6 +276,21 @@ static bool parse_space( } /* + Parse a string like parse_string(), but null-terminate it. +*/ +static bool parse_cstring( + char **result, size_t *length, const char *arg, ssize_t size) +{ + if (!parse_string(result, length, arg, size)) + return false; + + (*length)++; + *result = cr_realloc(*result, sizeof(char) * (*length)); + (*result)[*length - 1] = '\0'; + return true; +} + +/* Parse data encoded in a line into an ASMData object. On success, return NULL and store the instruction in *data_ptr. On failure, @@ -285,7 +300,7 @@ static ErrorInfo* parse_data( const ASMLine *line, ASMData **data_ptr, size_t offset) { const char *directive; - parser_func parser = (parser_func) parse_string; + parser_func parser; if (IS_DIRECTIVE(line, DIR_BYTE)) { directive = DIR_BYTE; @@ -295,10 +310,13 @@ static ErrorInfo* parse_data( parser = parse_space; } else if (IS_DIRECTIVE(line, DIR_ASCII)) { directive = DIR_ASCII; + parser = (parser_func) parse_string; } else if (IS_DIRECTIVE(line, DIR_ASCIZ)) { directive = DIR_ASCIZ; + parser = (parser_func) parse_cstring; } else if (IS_DIRECTIVE(line, DIR_ASCIIZ)) { directive = DIR_ASCIIZ; + parser = (parser_func) parse_cstring; } else { return error_info_create(line, ET_PREPROC, ED_PP_UNKNOWN); } From c632ddf9bd1f5d717987bd4197c2cff85e9d7968 Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Fri, 8 Apr 2016 14:17:26 -0500 Subject: [PATCH 09/10] Document and add new ASM tests. --- tests/asm/02-headers1.asm | 8 ++++++++ tests/asm/03-headers2.asm | 8 ++++++++ tests/asm/04-basic.asm | 8 ++++++++ tests/asm/05-includes.asm | 9 +++++++++ tests/asm/06-formatting.asm | 15 +++++++++++++++ tests/asm/06.inc.asm | 13 +++++++++++++ tests/asm/07-data.asm | 31 +++++++++++++++++++++++++++++++ tests/asm/08-instructions.asm | 7 +++++++ tests/asm/manifest | 2 ++ tests/asm/roms.tar.gz | Bin 807 -> 1158 bytes tests/runner.c | 2 +- 11 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 tests/asm/06-formatting.asm create mode 100644 tests/asm/06.inc.asm create mode 100644 tests/asm/07-data.asm create mode 100644 tests/asm/08-instructions.asm diff --git a/tests/asm/02-headers1.asm b/tests/asm/02-headers1.asm index a991487..db2169e 100644 --- a/tests/asm/02-headers1.asm +++ b/tests/asm/02-headers1.asm @@ -1,3 +1,11 @@ +;; Copyright (C) 2016 Ben Kurtovic +;; Released under the terms of the MIT License. See LICENSE for details. + +; ----- CRATER UNIT TESTING SUITE --------------------------------------------- + +; 02-headers1.asm +; Basic test for headers and other directives, mostly using default values + .rom_size auto .rom_header auto .rom_product 0 diff --git a/tests/asm/03-headers2.asm b/tests/asm/03-headers2.asm index 9ebea50..59502df 100644 --- a/tests/asm/03-headers2.asm +++ b/tests/asm/03-headers2.asm @@ -1,3 +1,11 @@ +;; Copyright (C) 2016 Ben Kurtovic +;; Released under the terms of the MIT License. See LICENSE for details. + +; ----- CRATER UNIT TESTING SUITE --------------------------------------------- + +; 03-headers2.asm +; Header/directive test using non-default values + .rom_size "64 KB" .rom_header $7FF0 .rom_product 101893 diff --git a/tests/asm/04-basic.asm b/tests/asm/04-basic.asm index 8a8d034..fd2ec81 100644 --- a/tests/asm/04-basic.asm +++ b/tests/asm/04-basic.asm @@ -1,3 +1,11 @@ +;; Copyright (C) 2016 Ben Kurtovic +;; Released under the terms of the MIT License. See LICENSE for details. + +; ----- CRATER UNIT TESTING SUITE --------------------------------------------- + +; 04-basic.asm +; Basic instruction test + .org $0000 main: di diff --git a/tests/asm/05-includes.asm b/tests/asm/05-includes.asm index 46e80c8..42c3b29 100644 --- a/tests/asm/05-includes.asm +++ b/tests/asm/05-includes.asm @@ -1,3 +1,12 @@ +;; Copyright (C) 2016 Ben Kurtovic +;; Released under the terms of the MIT License. See LICENSE for details. + +; ----- CRATER UNIT TESTING SUITE --------------------------------------------- + +; 05-includes.asm +; Source file inclusion test, involving cross-file label references and complex +; origins + .include "05.inc1.asm" .org $0000 diff --git a/tests/asm/06-formatting.asm b/tests/asm/06-formatting.asm new file mode 100644 index 0000000..f8533d8 --- /dev/null +++ b/tests/asm/06-formatting.asm @@ -0,0 +1,15 @@ +;; Copyright (C) 2016 Ben Kurtovic +;; Released under the terms of the MIT License. See LICENSE for details. + +; ----- CRATER UNIT TESTING SUITE --------------------------------------------- + +; 06-formatting.asm +; Complex formatting test, involving strange indentation and newline usage + +foo: .inCLUde "06.inc.asm" + +.ORG $0100 + +ayy: lmao: + di +ret diff --git a/tests/asm/06.inc.asm b/tests/asm/06.inc.asm new file mode 100644 index 0000000..199e02b --- /dev/null +++ b/tests/asm/06.inc.asm @@ -0,0 +1,13 @@ +test1:test2: test3: test4: + + + + inc a + +inc b +inc c + + ret + + + diff --git a/tests/asm/07-data.asm b/tests/asm/07-data.asm new file mode 100644 index 0000000..c6ff13b --- /dev/null +++ b/tests/asm/07-data.asm @@ -0,0 +1,31 @@ +;; Copyright (C) 2016 Ben Kurtovic +;; Released under the terms of the MIT License. See LICENSE for details. + +; ----- CRATER UNIT TESTING SUITE --------------------------------------------- + +; 07-data.asm +; Test of data directives to fill ROM with non-code bytes + +.org $1000 + +str1: .ascii "Hello, world!" +str2: .asciz "World, hello!" +str3: .asciiz "foobar" + +arr1: .byte 1 2 3 4 5 6 +arr2: .byte 14 $14 $FF 255 $F0 +arr3: .byte 8, $10, 4 5 6, 8, 10 + +void1: .space 3 +void2: .space 6 $D0 +void3: .space 128 $DE + +.org $0000 +main: + di +loop: + jp loop + +.org $0066 +nmi: + retn diff --git a/tests/asm/08-instructions.asm b/tests/asm/08-instructions.asm new file mode 100644 index 0000000..3ecdba0 --- /dev/null +++ b/tests/asm/08-instructions.asm @@ -0,0 +1,7 @@ +;; Copyright (C) 2016 Ben Kurtovic +;; Released under the terms of the MIT License. See LICENSE for details. + +; ----- CRATER UNIT TESTING SUITE --------------------------------------------- + +; 08-instructions.asm +; Exhaustive test of instruction syntax diff --git a/tests/asm/manifest b/tests/asm/manifest index 267f419..2a0f414 100644 --- a/tests/asm/manifest +++ b/tests/asm/manifest @@ -3,3 +3,5 @@ 03-headers2.asm 03-headers2.gg 04-basic.asm 04-basic.gg 05-includes.asm 05-includes.gg +06-formatting.asm 06-formatting.gg +07-data.asm 07-data.gg diff --git a/tests/asm/roms.tar.gz b/tests/asm/roms.tar.gz index dfb1ed91f45f6b4ddf811315b9781bbb7dd3bab6..e86fb67526f6bcb7129ab7e85ca8ab1a2ab6ea5b 100644 GIT binary patch literal 1158 zcmb2|=3uB};s|G8etT(SesZKJ`-9o3VqqCueH|S?Y8NcNWZw@`ZS-H=`($-JDzY{CaKQzFeDoMe?(4-+k`9@wJ)- zzs(J?J8Z1ai>og`u4!BUb@ltdztVTlW5=(D;h%U(_szsBzYphq{L~E!n>MUr)4VOj z^3=t^;N>#?MrXtC=uNx3M?TeJ*S%ZUxAz{8ewV!Yc&(jae%*(^=i}?O|GqQd|Nq?G zb@!DBSY8vWcmCYxqbFY$dhM^688oX5=oFrB@p1Krd-qD|@~KV!@<3_P%GY~NZIfJM zyy~pwqBYriq0&obO_rKidc}HqTFTW;DZh)uF?K(XA74NJ?b~0G@6PDI|5y3__;vX= zf4{9?fBD}0cV)JG1l$%s`Sj+`HHAf0b1qF^%pdgFi>BY( zbNx0mez)w|4-cmLnaiduyPH%d@%CTn_BWsq(!dfzS6_wj7EM`vi7%+{xa9NuxI$>( z9q<1Cul|*N`mvu8=z>4y_A;(V- literal 807 zcmb2|=3qE{hdrEu`R%2RSvsK->>r9wl}F zc|!e;f8JVr_(sa6XEtHqcbrdul+S=4{E)Y@v^jPBH+!|_-aS5=u_b?V)K{&&{`g(a zo)@RTmCTZhbulTO`+ifd+v%RHt^FFOO{cHwz0~(=m8RvXyxZ@V$@IrRU5MT8q|5IG z@mtPd_VCFE4f*%-Zu5KGzf*U#}LPd+*8bHv@pcJn)Z_q!9Y_(sd*!;5S7)Nh!6>GWxNyZ;|= z`+jG{ucx8D85ApfOK*LBzJA;C%U?v47Oi|;GdOM$$kInv*+)tZvA|Fzy1Hd+)g*2UDu7@ zYK9N{=E%rBef+n1@05Mk{*YL5i+=t&T>N_abCWk`;@1% zysx@ty8CMS_61E33hFz){?moh`m4HaTFW2*ytOki$0)K`ZgusY=f)quUADL1`S-)o zW%HjNtEvBd{p{@9{BeK&9M7%#`1|a#*MwX)5AL!$$@-F?UtO6%Iv&`+l>fD<*@Z!Y GnE?O@fmP@L diff --git a/tests/runner.c b/tests/runner.c index 3c54e34..10c27ab 100644 --- a/tests/runner.c +++ b/tests/runner.c @@ -206,7 +206,7 @@ static bool test_asm() *(split++) = '\0'; if (!run_asm_test(line, split)) { - fprintf(stderr, "test: %s -> %s\n", line, split); + fprintf(stderr, "in test: %s -> %s\n", line, split); return false; } PASS_TEST() From c8ecf0160062726505440ce4a4cc35ac471464d9 Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Fri, 8 Apr 2016 14:39:03 -0500 Subject: [PATCH 10/10] Add ASM instruction test. --- tests/asm/06-formatting.asm | 1 + tests/asm/08-instructions.asm | 96 ++++++++++++++++++++++++++++++++++++++++++ tests/asm/manifest | 1 + tests/asm/roms.tar.gz | Bin 1158 -> 1488 bytes 4 files changed, 98 insertions(+) diff --git a/tests/asm/06-formatting.asm b/tests/asm/06-formatting.asm index f8533d8..b15f805 100644 --- a/tests/asm/06-formatting.asm +++ b/tests/asm/06-formatting.asm @@ -12,4 +12,5 @@ foo: .inCLUde "06.inc.asm" ayy: lmao: di + InC a ret diff --git a/tests/asm/08-instructions.asm b/tests/asm/08-instructions.asm index 3ecdba0..a9859b6 100644 --- a/tests/asm/08-instructions.asm +++ b/tests/asm/08-instructions.asm @@ -5,3 +5,99 @@ ; 08-instructions.asm ; Exhaustive test of instruction syntax + +.define COUNTER $C010 +.define OFFSET 6 +.define OFFSET2 157 + +.org $1000 + +str1: .ascii "Hello, world!" + +.org $0000 +main: + di + call inst + halt + +.org $0066 +nmi: + retn + +.org $2000 +inst: + inc a + inc c + inc hl + inc sp + inc (hl) + inc ( hl ) + inc ix + inc iyl + inc (ix) + inc ( ix ) + inc (iy+0) + inc (ix+3) + inc (ix+OFFSET) + inc (ix-OFFSET) + inc ( ix + 7 ) + inc (ix-8) + inc (ix - +9) + inc (iy+127) + inc (iy-128) + + add a, e + add a, 5 + add a, $12 + add a, (hl) + add a, (ix+4) + add hl, bc + add ix, de + + adc a, e + adc a, 5 + adc a, $12 + adc a, (hl) + adc a, (ix+4) + adc hl, bc + + rlca + rrca + rla + rra + daa + cpl + scf + ccf + halt + exx + ei + di + cpd + cpdr + cpi + cpir + ind + indr + ini + inir + ldd + lddr + ldi + ldir + otdr + otir + outd + outi + rrd + rld + + ld hl, COUNTER ; H contains $C0, L contains $10 + ld d, (hl) ; D contains $FF (garbage) + ld c, $3B ; C contains $3B + ld (hl), c ; memory address $C010 contains $3B + + ld hl, str1 + ld b, (hl) ; B contains 'H' + ld hl, (str1) ; H contains 'e', L contains 'H' + ld (hl), b ; error, writing to cartridge ROM diff --git a/tests/asm/manifest b/tests/asm/manifest index 2a0f414..75a5147 100644 --- a/tests/asm/manifest +++ b/tests/asm/manifest @@ -5,3 +5,4 @@ 05-includes.asm 05-includes.gg 06-formatting.asm 06-formatting.gg 07-data.asm 07-data.gg +08-instructions.asm 08-instructions.gg diff --git a/tests/asm/roms.tar.gz b/tests/asm/roms.tar.gz index e86fb67526f6bcb7129ab7e85ca8ab1a2ab6ea5b..10d3d107b7c0b101830cf5dd1dc4aed4117e4769 100644 GIT binary patch literal 1488 zcmaizeNfVO9LH&GCwJSTuASCEF|*4DoK9y>B{+9Z#%|N|p|#Z1)4-XgBSn0`hg)lr zq+I!wIkXcWP)8b`f&xC|ktPsR6MVv_nTCqw4+IsJX}5L#BYpq;{_}plKA-moP6dN% zz~GCZ!>S=^d^O3^?6ta$r*IIR`^@M3CZZ9{#-gNdQY3ArYW`?&QLe3zv=EO!=Yo}$ zVX4-36aknzgMO%sUKYYFa>9R)CP2dYX|GOI2tEOO+Bu0*T@N4PsbIFs6Z-Y&4SuDX zjDAh-giOn#k~{&SZb~srD(O(9SlLuLh*oTu8$6%c)h<)WK`ngd>87XGaP)7d>_j#= z!WYAQ>1@>K5)Ct!sFtokIYcivT}(#7FyGqh5Xj`~KK@I5*6E4x%VF5K*~IVb<)5!O zVIHT|DaPaUW}88r^5@~cA-FR7mCNpDPYP2k?*?2gu^`S9TM!LMDnC%3UnCr(0o>l6 z<`FoJt(dAD^GIAy!LRgbVRh*~Vgu>}lkuQ#WCAPcN_k_vV_d_V?3guwUhD8GB(EmX zgWgVI4!C+h>$vLgny1XzcB#J<@#3yr!WK6ofa}{A2j*5V>5~VTFJ!^r;~r(zCi7rR zMp}!D%vX2kgPXERQySB_pl;)D``Z~1s$@}m;XdQ7cNx8GDqkR+m-?6SEzhY4z>nb& zY`*9!F~E-e!P-qLQt5WZorJJDw-|Ko;@6Uo=QczhNoeka-R<$n3LaX`1HUI8Ud&q0 zPe>+SJ5!U%v#*JWZ|1-xLdA|n<}GhkkBM~+XdI|~u?C4F=orY=UtJQ``xprveXK5j z!i#>=@a6fwxQL^D^67Tn3{aCEDQe$b+aalqs-ED|2xH%k6s5|bu`)AFmrLuHZTYpe zceLFbf~p)zU4!wT>Pi@)D=@7-w0Cwjn^ZsXV=Tg^fi3oDKYCDjC%U7c|E#-+>Xk?F zQ&1298$m4+UV;EVN6dPE%0UjKX6E3hxvb%`$ME6gKNmhC7=TuTrn69!LN?q+p-j_s zACLdP*~%6{QBafnXjnl8q0T+QiO5ri`}$re8N^<- z6bBpu_0M+Q0j-905$x$k7L-+C^xk90g=oIv$-TM70`lK#)#Qc@D=1cYZmRv3V6X(v zmU1XKAhHt>uLmGAw9;6MrvcJzWQ|sSyGuI8M_ZYYFmm4ZGkf$q`}NQpf|na}bE~^i zqi8aLo7s&1c`0?cERWKFXes=walw{x|IujxD*>tsY^uai2?D@>)v$M;1#3MA4RqTY z=S(;3s~8;LsI0%Ma$oPV_u1Xf%~IhR2wEbFPYkJDQ_o_vwwUAvCV7#`&j{HyFt_Es zKqf?_HqJ;KlTgNiLB~>bs#XaX5MQzu)s_k#a%+5K5w%$+b(Tk_D^(;KrYS!gy*2hq z&X8krPVA7i<%7ts6zk% literal 1158 zcmb2|=3uB};s|G8etT(SesZKJ`-9o3VqqCueH|S?Y8NcNWZw@`ZS-H=`($-JDzY{CaKQzFeDoMe?(4-+k`9@wJ)- zzs(J?J8Z1ai>og`u4!BUb@ltdztVTlW5=(D;h%U(_szsBzYphq{L~E!n>MUr)4VOj z^3=t^;N>#?MrXtC=uNx3M?TeJ*S%ZUxAz{8ewV!Yc&(jae%*(^=i}?O|GqQd|Nq?G zb@!DBSY8vWcmCYxqbFY$dhM^688oX5=oFrB@p1Krd-qD|@~KV!@<3_P%GY~NZIfJM zyy~pwqBYriq0&obO_rKidc}HqTFTW;DZh)uF?K(XA74NJ?b~0G@6PDI|5y3__;vX= zf4{9?fBD}0cV)JG1l$%s`Sj+`HHAf0b1qF^%pdgFi>BY( zbNx0mez)w|4-cmLnaiduyPH%d@%CTn_BWsq(!dfzS6_wj7EM`vi7%+{xa9NuxI$>( z9q<1Cul|*N`mvu8=z>4y_A;(V-