Add a mostly non-functional Gameboy CPU and the skeleton of a Gameboy assembler intended for unit tests.
80 lines
1.8 KiB
C
80 lines
1.8 KiB
C
#include "gbasm/assemble.h"
|
|
#include "gbasm/emitter.h"
|
|
#include "tests/gbasm/test.h"
|
|
#include "tests/gbasm/inc.h"
|
|
#include "tests/gbasm/fixed.h"
|
|
#include "common.h"
|
|
|
|
#include <string.h> /* memset */
|
|
#include <glib.h>
|
|
|
|
const static struct gbasm_tests *tests[] = {
|
|
&gbasm_fixed_tests,
|
|
&gbasm_inc_tests,
|
|
};
|
|
|
|
static int cmp_mem(const uint8_t *test_data, const uint8_t *expected_data, size_t len)
|
|
{
|
|
for (size_t i = 0; i < len; i++) {
|
|
if (test_data[i] != expected_data[i]) {
|
|
g_test_message("memory contents differed at index %zu, data=%x, expected=%x",
|
|
i, test_data[i], expected_data[i]);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void run_test(const void *test_data)
|
|
{
|
|
static uint8_t program[4096];
|
|
const struct gbasm_test *test = test_data;
|
|
struct emitter emitter;
|
|
struct buffer_emitter buffer_emitter;
|
|
char *src;
|
|
int rc;
|
|
size_t len;
|
|
|
|
src = strdup(test->asm_source);
|
|
|
|
memset(program, 0, sizeof(program));
|
|
buffer_emitter_init(&emitter, &buffer_emitter, program, sizeof(program));
|
|
|
|
rc = gbasm_assemble(src, &emitter);
|
|
g_assert_cmpint(rc, ==, 0);
|
|
|
|
len = test->expected_output_len;
|
|
|
|
if (len != buffer_emitter.cursor) {
|
|
g_warning("output lengths were not equal expected %zu, actual %zu",
|
|
len, buffer_emitter.cursor);
|
|
g_test_fail();
|
|
len = MIN(len, buffer_emitter.cursor);
|
|
}
|
|
|
|
rc = cmp_mem(program, test->expected_output, len);
|
|
g_assert_cmpint(rc, ==, 0);
|
|
|
|
free(src);
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
char test_name_buff[256];
|
|
|
|
g_test_init(&argc, &argv, NULL);
|
|
|
|
for (int i = 0; i < ARRAY_SIZE(tests); i++) {
|
|
for (int j = 0; j < tests[i]->num_tests; j++) {
|
|
snprintf(test_name_buff, sizeof(test_name_buff),
|
|
"/gbasm/%s/%s",
|
|
tests[i]->name,
|
|
tests[i]->tests[j]->name);
|
|
g_test_add_data_func(test_name_buff, tests[i]->tests[j], run_test);
|
|
}
|
|
}
|
|
|
|
return g_test_run();
|
|
}
|