diff --git a/src/gbasm/errors.c b/src/gbasm/errors.c index c7f9533..fc30e7c 100644 --- a/src/gbasm/errors.c +++ b/src/gbasm/errors.c @@ -54,3 +54,13 @@ void gbasm_too_few_args_error(const struct gbasm_parsed_inst *inst, exit(1); } + +void gbasm_invalid_imm_error(const struct gbasm_parsed_inst *inst, + const struct gbasm_op_info *opcode) +{ + gbasm_print_error( + "ERROR: %s:%d out of bounds constant for opcode \"%s\"\n", + inst->file_name, inst->line_num, inst->opcode); + + exit(1); +} diff --git a/src/gbasm/errors.h b/src/gbasm/errors.h index b1edc8d..6f2fa4b 100644 --- a/src/gbasm/errors.h +++ b/src/gbasm/errors.h @@ -14,4 +14,6 @@ void gbasm_arg_wrong_type_error(const struct gbasm_parsed_inst *inst, void gbasm_too_few_args_error(const struct gbasm_parsed_inst *inst, const struct gbasm_op_info *opcode); +void gbasm_invalid_imm_error(const struct gbasm_parsed_inst *inst, + const struct gbasm_op_info *opcode); #endif diff --git a/src/gbasm/gb_types.h b/src/gbasm/gb_types.h index 5949042..86ee38e 100644 --- a/src/gbasm/gb_types.h +++ b/src/gbasm/gb_types.h @@ -43,7 +43,7 @@ struct gbasm_operand_r16 { }; struct gbasm_operand_imm { - uint16_t value; + int value; }; enum gbasm_operand_cond_type { diff --git a/src/gbasm/opcodes.c b/src/gbasm/opcodes.c index 68dba8b..eb8ccf9 100644 --- a/src/gbasm/opcodes.c +++ b/src/gbasm/opcodes.c @@ -15,9 +15,10 @@ static bool gbasm_argtype_in_set(uint32_t argtype_set, uint32_t argtype) return !!(argtype & argtype_set); } -static bool imm_is_8_bit(uint16_t val) +static bool imm_is_8_bit(int val) { - return (val <= 127) && (val >= -128); + /* Allow signed or unsigned representation */ + return (val <= 255) && (val >= -128); } static int check_no_args(const struct gbasm_parsed_inst *inst, @@ -94,9 +95,13 @@ static int ld_check(const struct gbasm_parsed_inst *inst, gbasm_arg_wrong_type_error(inst, op_info); } - if (inst->operands[0].type == GBASM_OPERAND_REG_8 && - imm_is_8_bit(inst->operands[1].imm.value)) { + if (inst->operands[0].type == GBASM_OPERAND_REG_8) { + if (!imm_is_8_bit(inst->operands[1].imm.value)) { + DEBUG_LOG("inst->operands[1].imm.value = %d", + inst->operands[1].imm.value); + gbasm_invalid_imm_error(inst, op_info); + } } return 0; diff --git a/src/gbasm/tests/ld.c b/src/gbasm/tests/ld.c index c53d76d..2a0545e 100644 --- a/src/gbasm/tests/ld.c +++ b/src/gbasm/tests/ld.c @@ -3,22 +3,40 @@ #include -void init_r8(void); +void init_r8_r8(void); +void init_r8_d8(void); -static char ld_r8_src[1024] = { 0 }; +/* + * Data for LD R8, R8 tests + */ +static char ld_r8_r8_src[1024] = { 0 }; +static uint8_t ld_r8_r8_output[0x40]; -static uint8_t ld_r8_output[0x40]; +struct gbasm_test r8_r8 = { + .init = init_r8_r8, + .name = "r8/r8", + .asm_source = ld_r8_r8_src, + .expected_output = ld_r8_r8_output, + .expected_output_len = 0, +}; -struct gbasm_test r8 = { - .init = init_r8, - .name = "r8", - .asm_source = ld_r8_src, - .expected_output = ld_r8_output, +/* + * Data for LD R8, D8 tests + */ +static char ld_r8_d8_src[1024] = { 0 }; +static uint8_t ld_r8_d8_output[0x40]; + +struct gbasm_test r8_d8 = { + .init = init_r8_d8, + .name = "r8/d8", + .asm_source = ld_r8_d8_src, + .expected_output = ld_r8_d8_output, .expected_output_len = 0, }; static const struct gbasm_test *tests[] = { - &r8, + &r8_r8, + &r8_d8, }; struct gbasm_tests gbasm_ld_tests = { @@ -38,7 +56,7 @@ const char *operands[] = { "A", }; -void gen_r8_src(void) +void gen_r8_r8_src(void) { const char *src, *dst; size_t len = 0; @@ -55,16 +73,16 @@ void gen_r8_src(void) continue; } - len += sprintf(ld_r8_src + len, "ld %s %s\n", src, dst); + len += sprintf(ld_r8_r8_src + len, "ld %s %s\n", src, dst); } } - sprintf(ld_r8_src + len, "halt"); + sprintf(ld_r8_r8_src + len, "halt"); - DEBUG_LOG("%s", ld_r8_src); + DEBUG_LOG("%s", ld_r8_r8_src); } -void gen_r8_output(void) +void gen_r8_r8_output(void) { int num_insts = ARRAY_SIZE(operands) * ARRAY_SIZE(operands); int halt_code = 0x76; @@ -75,15 +93,38 @@ void gen_r8_output(void) continue; } - ld_r8_output[i++] = opcode; + ld_r8_r8_output[i++] = opcode; } - ld_r8_output[i] = halt_code; - r8.expected_output_len = num_insts; + ld_r8_r8_output[i] = halt_code; + r8_r8.expected_output_len = num_insts; } -void init_r8(void) +void init_r8_r8(void) { - gen_r8_src(); - gen_r8_output(); + gen_r8_r8_src(); + gen_r8_r8_output(); +} + +void gen_r8_d8_src(void) +{ + snprintf(ld_r8_d8_src, + sizeof(ld_r8_d8_src), + "ld a, $12\n" + "ld b, $0\n" + "ld c, $0xff\n" + "ld d, $127\n" + "ld e, $0xfe\n" + "ld h, $-1\n" + "ld l, $-128"); +} + +void gen_r8_d8_output(void) +{ +} + +void init_r8_d8(void) +{ + gen_r8_d8_src(); + gen_r8_d8_output(); }