diff --git a/src/assembler/inst_args.h b/src/assembler/inst_args.h index ef2d0e0..29eaa77 100644 --- a/src/assembler/inst_args.h +++ b/src/assembler/inst_args.h @@ -40,10 +40,15 @@ typedef struct { } ASMArgImmediate; typedef struct { + char text[MAX_SYMBOL_SIZE]; +} ASMArgLabel; + +typedef struct { ASMArgType type; union { ASMArgRegister reg; ASMArgImmediate imm; + ASMArgLabel label; } addr; } ASMArgIndirect; @@ -52,10 +57,6 @@ typedef struct { int8_t offset; } ASMArgIndexed; -typedef struct { - char text[MAX_SYMBOL_SIZE]; -} ASMArgLabel; - typedef enum { COND_NZ, COND_N, COND_NC, COND_C, COND_PO, COND_PE, COND_P, COND_M } ASMArgCondition; diff --git a/src/assembler/instructions.c b/src/assembler/instructions.c index 443f4e5..3e354ae 100644 --- a/src/assembler/instructions.c +++ b/src/assembler/instructions.c @@ -533,10 +533,52 @@ INST_FUNC(jr) INST_FUNC(ld) { - // TODO - INST_TAKES_NO_ARGS - INST_ERROR(ARG_SYNTAX) - INST_RETURN(1, 0xFF) + INST_TAKES_ARGS(2, 2) + switch (INST_TYPE(0)) { + case AT_REGISTER: + switch (INST_REG(0)) { + case REG_A: // TODO (20 cases) + case REG_B: // TODO (15 cases) + case REG_C: // TODO (15 cases) + case REG_D: // TODO (15 cases) + case REG_E: // TODO (15 cases) + case REG_H: // TODO (11 cases) + case REG_L: // TODO (11 cases) + case REG_I: // TODO ( 1 case ) + case REG_R: // TODO ( 1 case ) + case REG_BC: // TODO ( 2 cases) + case REG_DE: // TODO ( 2 cases) + case REG_HL: // TODO ( 3 cases) + case REG_IX: // TODO ( 2 cases) + case REG_IY: // TODO ( 2 cases) + case REG_SP: // TODO ( 5 cases) + case REG_IXH: // TODO ( 8 cases) + case REG_IXL: // TODO ( 8 cases) + case REG_IYH: // TODO ( 8 cases) + case REG_IYL: // TODO ( 8 cases) + default: INST_ERROR(ARG0_BAD_REG) + } + case AT_INDIRECT: + switch (INST_INDIRECT(0).type) { + case AT_REGISTER: + switch (INST_INDIRECT(0).addr.reg) { + case REG_BC: // TODO (1 case ) + case REG_DE: // TODO (1 case ) + case REG_HL: // TODO (8 cases) + default: INST_ERROR(ARG0_BAD_REG) + } + case AT_IMMEDIATE: + // TODO (8 cases) + case AT_LABEL: + // TODO (same 8 cases) + default: + INST_ERROR(ARG0_TYPE) + } + case AT_INDEXED: + // TODO (16 cases) + default: + INST_ERROR(ARG0_TYPE) + } } INST_FUNC(ldd) @@ -691,10 +733,8 @@ INST_FUNC(rlca) INST_FUNC(rld) { - // TODO INST_TAKES_NO_ARGS - INST_ERROR(ARG_SYNTAX) - INST_RETURN(1, 0xFF) + INST_RETURN(2, 0xED, 0x6F) } INST_FUNC(rr) diff --git a/src/assembler/parse_util.c b/src/assembler/parse_util.c index b060cac..2aa448a 100644 --- a/src/assembler/parse_util.c +++ b/src/assembler/parse_util.c @@ -374,6 +374,7 @@ bool argparse_indirect(ASMArgIndirect *result, ASMArgParseInfo ai) ASMArgRegister reg; ASMArgImmediate imm; + ASMArgLabel label; if (argparse_register(®, ai)) { if (reg == REG_BC || reg == REG_DE || reg == REG_HL) { result->type = AT_REGISTER; @@ -386,6 +387,10 @@ bool argparse_indirect(ASMArgIndirect *result, ASMArgParseInfo ai) result->addr.imm = imm; return true; } + } else if (argparse_label(&label, ai)) { + result->type = AT_LABEL; + result->addr.label = label; + return true; } return false; }