diff --git a/scripts/update_asm_instructions.py b/scripts/update_asm_instructions.py index ce716e0..9c1f9df 100755 --- a/scripts/update_asm_instructions.py +++ b/scripts/update_asm_instructions.py @@ -77,7 +77,7 @@ class Instruction(object): return "AT_NONE" if optional: types.add("AT_OPTIONAL") - return "|".join(types) + return "|".join(sorted(types)) def _handle_return(self, ret, indent=1): """ @@ -105,7 +105,19 @@ class Instruction(object): """ Return an expression to check for a particular immediate value. """ - # TODO: also allow direct value comparisons here + if "." in cond: + itype, value = cond.split(".", 1) + try: + value = int(value) + except ValueError: + value = int(value, 16) + vtype = "sval" if itype.upper() in ["S8", "REL"] else "uval" + + test1 = "INST_IMM({0}).mask & IMM_{1}".format(num, itype.upper()) + test2 = "!INST_IMM({0}).is_label".format(num) + test3 = "INST_IMM({0}).{1} == {2}".format(num, vtype, value) + return "({0} && {1} && {2})".format(test1, test2, test3) + return "INST_IMM({0}).mask & IMM_{1}".format(num, cond.upper()) def _build_indirect_check(self, num, cond): @@ -140,7 +152,14 @@ class Instruction(object): """ Return an expression to check for a particular port value. """ - # TODO + if cond.startswith("reg."): + test1 = "INST_PORT({0}).type == AT_REGISTER".format(num) + test2 = "INST_PORT({0}).port.reg == REG_{1}".format( + num, cond[len("reg."):].upper()) + return "({0} && {1})".format(test1, test2) + + if cond == "imm" or cond == "immediate": + return "INST_PORT({0}).type == AT_IMMEDIATE".format(num) err = "Unknown condition for port argument: {0}" return RuntimeError(err.format(cond)) @@ -168,19 +187,30 @@ class Instruction(object): """ def split(typ, cond): if "|" in cond: - sets = [split(typ, c) for c in cond.split("|")] - return {choice for s in sets for choice in s} + splits = [split(typ, c) for c in cond.split("|")] + merged = [choice for s in splits for choice in s] + if len(merged) != len(set(merged)): + msg = "Repeated conditions for {0}: {1}" + raise RuntimeError(msg.format(typ, cond)) + return merged if typ == "register": if cond == "i": - return {"ix", "iy"} + return ["ix", "iy"] if cond == "ih": - return {"ixh", "iyh"} + return ["ixh", "iyh"] if cond == "il": - return {"ixl", "iyl"} - return {cond} + return ["ixl", "iyl"] + return [cond] + + splits = [split(typ, cond) for typ, cond in zip(types, conds)] + num = max(len(cond) for cond in splits) - return product(*(split(types[i], cond) - for i, cond in enumerate(conds))) + if any(1 < len(cond) < num for cond in splits): + msg = "Invalid condition permutations: {0}" + raise RuntimeError(msg.format(conds)) + + choices = [cond * num if len(cond) == 1 else cond for cond in splits] + return zip(*choices) def _adapt_return(self, types, conds, ret): """ @@ -190,8 +220,25 @@ class Instruction(object): for i, byte in enumerate(ret): if not isinstance(byte, int): if byte == "u8": - imm = types.index("immediate") - ret[i] = "INST_IMM({0}).uval".format(imm) + index = types.index("immediate") + ret[i] = "INST_IMM({0}).uval".format(index) + + elif byte == "u16": + if i < len(ret) - 1: + raise RuntimeError("U16 return byte must be last") + try: + index = types.index("immediate") + imm = "INST_IMM({0})".format(index) + except ValueError: + indir = types.index("indirect") + if not conds[indir].startswith("imm"): + msg = "Passing non-immediate indirect as immediate" + raise RuntimeError(msg) + imm = "INST_INDIRECT({0}).addr.imm".format(indir) + ret[i] = "INST_IMM_U16_B1({0})".format(imm) + ret.append("INST_IMM_U16_B2({0})".format(imm)) + break + else: msg = "Unsupported return byte: {0}" raise RuntimeError(msg.format(byte)) diff --git a/src/assembler/errors.c b/src/assembler/errors.c index bc2094c..5a6bcb5 100644 --- a/src/assembler/errors.c +++ b/src/assembler/errors.c @@ -53,8 +53,8 @@ static const char *error_descs[] = { [ED_PS_TOO_FEW_ARGS] = "too few arguments for opcode", [ED_PS_TOO_MANY_ARGS] = "too many arguments for opcode", [ED_PS_ARG_SYNTAX] = "invalid syntax in argument(s)", - [ED_PS_ARG_TYPE] = "ED_PS_ARG_TYPE", // TODO - [ED_PS_ARG_VALUE] = "ED_PS_ARG_VALUE" // TODO + [ED_PS_ARG_TYPE] = "invalid argument type", + [ED_PS_ARG_VALUE] = "invalid value for argument" }; /* Internal structs */ diff --git a/src/assembler/instructions.c b/src/assembler/instructions.c index 708ca68..ac2558f 100644 --- a/src/assembler/instructions.c +++ b/src/assembler/instructions.c @@ -83,6 +83,9 @@ static ASMErrorDesc parse_inst_##mnemonic( \ #define INST_COND(n) args[n].data.cond #define INST_PORT(n) args[n].data.port +#define INST_IX_PREFIX 0xDD +#define INST_IY_PREFIX 0xFD + #define INST_RETURN(len, ...) { \ (void) symbol; \ INST_ALLOC_(len) \ @@ -90,18 +93,13 @@ static ASMErrorDesc parse_inst_##mnemonic( \ return ED_NONE; \ } -#define INST_IX_PREFIX 0xDD -#define INST_IY_PREFIX 0xFD +#define INST_IMM_U16_B1(imm) \ + ((imm).is_label ? (*symbol = cr_strdup((imm).label), 0) : (imm).uval >> 8) +#define INST_IMM_U16_B2(imm) \ + ((imm).is_label ? 0 : (imm).uval & 0xFF) #define INST_INDEX_PREFIX(n) INST_PREFIX_(INST_INDEX(n).reg) -// TODO: must check for imm actually using symbol... -// - hint: *symbol = cr_strdup(label.text); -// - hint: INST_FILL_BYTES_(len - 2, __VA_ARGS__) -#define INST_INDIRECT_IMM(n) \ - INST_INDIRECT(n).addr.imm.uval >> 8, \ - INST_INDIRECT(n).addr.imm.uval & 0xFF - /* ----------------------------- END WORK BLOCK ---------------------------- */ /* diff --git a/src/assembler/instructions.inc.c b/src/assembler/instructions.inc.c index e308af7..41bda1a 100644 --- a/src/assembler/instructions.inc.c +++ b/src/assembler/instructions.inc.c @@ -7,7 +7,7 @@ `make` should trigger a rebuild when it is modified; if not, use: `python scripts/update_asm_instructions.py`. - @AUTOGEN_DATE Sun May 17 03:37:44 2015 UTC + @AUTOGEN_DATE Mon May 18 04:41:13 2015 UTC */ /* @AUTOGEN_INST_BLOCK_START */ @@ -16,7 +16,7 @@ INST_FUNC(adc) { INST_TAKES_ARGS( AT_REGISTER, - AT_IMMEDIATE|AT_INDIRECT|AT_INDEXED|AT_REGISTER, + AT_IMMEDIATE|AT_INDEXED|AT_INDIRECT|AT_REGISTER, AT_NONE ) if (INST_NARGS == 2 && INST_TYPE(0) == AT_REGISTER && INST_TYPE(1) == AT_REGISTER) { @@ -36,12 +36,12 @@ INST_FUNC(adc) INST_RETURN(2, INST_IX_PREFIX, 0x8C) if (INST_REG(0) == REG_A && INST_REG(1) == REG_IYH) INST_RETURN(2, INST_IY_PREFIX, 0x8C) - if (INST_REG(0) == REG_A && INST_REG(1) == REG_IYL) - INST_RETURN(2, INST_IY_PREFIX, 0x8D) if (INST_REG(0) == REG_A && INST_REG(1) == REG_L) INST_RETURN(1, 0x8D) if (INST_REG(0) == REG_A && INST_REG(1) == REG_IXL) INST_RETURN(2, INST_IX_PREFIX, 0x8D) + if (INST_REG(0) == REG_A && INST_REG(1) == REG_IYL) + INST_RETURN(2, INST_IY_PREFIX, 0x8D) if (INST_REG(0) == REG_HL && INST_REG(1) == REG_BC) INST_RETURN(2, 0xED, 0x4A) if (INST_REG(0) == REG_HL && INST_REG(1) == REG_DE) @@ -74,7 +74,7 @@ INST_FUNC(add) { INST_TAKES_ARGS( AT_REGISTER, - AT_IMMEDIATE|AT_INDIRECT|AT_INDEXED|AT_REGISTER, + AT_IMMEDIATE|AT_INDEXED|AT_INDIRECT|AT_REGISTER, AT_NONE ) if (INST_NARGS == 2 && INST_TYPE(0) == AT_REGISTER && INST_TYPE(1) == AT_REGISTER) { @@ -94,36 +94,36 @@ INST_FUNC(add) INST_RETURN(2, INST_IX_PREFIX, 0x84) if (INST_REG(0) == REG_A && INST_REG(1) == REG_IYH) INST_RETURN(2, INST_IY_PREFIX, 0x84) - if (INST_REG(0) == REG_A && INST_REG(1) == REG_IYL) - INST_RETURN(2, INST_IY_PREFIX, 0x85) if (INST_REG(0) == REG_A && INST_REG(1) == REG_L) INST_RETURN(1, 0x85) if (INST_REG(0) == REG_A && INST_REG(1) == REG_IXL) INST_RETURN(2, INST_IX_PREFIX, 0x85) - if (INST_REG(0) == REG_IY && INST_REG(1) == REG_BC) - INST_RETURN(2, INST_IY_PREFIX, 0x09) - if (INST_REG(0) == REG_IX && INST_REG(1) == REG_BC) - INST_RETURN(2, INST_IX_PREFIX, 0x09) + if (INST_REG(0) == REG_A && INST_REG(1) == REG_IYL) + INST_RETURN(2, INST_IY_PREFIX, 0x85) if (INST_REG(0) == REG_HL && INST_REG(1) == REG_BC) INST_RETURN(1, 0x09) - if (INST_REG(0) == REG_IY && INST_REG(1) == REG_DE) - INST_RETURN(2, INST_IY_PREFIX, 0x19) - if (INST_REG(0) == REG_IX && INST_REG(1) == REG_DE) - INST_RETURN(2, INST_IX_PREFIX, 0x19) + if (INST_REG(0) == REG_IX && INST_REG(1) == REG_BC) + INST_RETURN(2, INST_IX_PREFIX, 0x09) + if (INST_REG(0) == REG_IY && INST_REG(1) == REG_BC) + INST_RETURN(2, INST_IY_PREFIX, 0x09) if (INST_REG(0) == REG_HL && INST_REG(1) == REG_DE) INST_RETURN(1, 0x19) - if (INST_REG(0) == REG_IY && INST_REG(1) == REG_HL) - INST_RETURN(2, INST_IY_PREFIX, 0x29) - if (INST_REG(0) == REG_IX && INST_REG(1) == REG_HL) - INST_RETURN(2, INST_IX_PREFIX, 0x29) + if (INST_REG(0) == REG_IX && INST_REG(1) == REG_DE) + INST_RETURN(2, INST_IX_PREFIX, 0x19) + if (INST_REG(0) == REG_IY && INST_REG(1) == REG_DE) + INST_RETURN(2, INST_IY_PREFIX, 0x19) if (INST_REG(0) == REG_HL && INST_REG(1) == REG_HL) INST_RETURN(1, 0x29) - if (INST_REG(0) == REG_IY && INST_REG(1) == REG_SP) - INST_RETURN(2, INST_IY_PREFIX, 0x39) - if (INST_REG(0) == REG_IX && INST_REG(1) == REG_SP) - INST_RETURN(2, INST_IX_PREFIX, 0x39) + if (INST_REG(0) == REG_IX && INST_REG(1) == REG_IX) + INST_RETURN(3, INST_IX_PREFIX, INST_IX_PREFIX, 0x29) + if (INST_REG(0) == REG_IY && INST_REG(1) == REG_IY) + INST_RETURN(3, INST_IY_PREFIX, INST_IY_PREFIX, 0x29) if (INST_REG(0) == REG_HL && INST_REG(1) == REG_SP) INST_RETURN(1, 0x39) + if (INST_REG(0) == REG_IX && INST_REG(1) == REG_SP) + INST_RETURN(2, INST_IX_PREFIX, 0x39) + if (INST_REG(0) == REG_IY && INST_REG(1) == REG_SP) + INST_RETURN(2, INST_IY_PREFIX, 0x39) INST_ERROR(ARG_VALUE) } if (INST_NARGS == 2 && INST_TYPE(0) == AT_REGISTER && INST_TYPE(1) == AT_IMMEDIATE) { @@ -234,22 +234,22 @@ INST_FUNC(inc) INST_RETURN(2, INST_IX_PREFIX, 0x24) if (INST_REG(0) == REG_IYH) INST_RETURN(2, INST_IY_PREFIX, 0x24) - if (INST_REG(0) == REG_IYL) - INST_RETURN(2, INST_IY_PREFIX, 0x2C) if (INST_REG(0) == REG_L) INST_RETURN(1, 0x2C) if (INST_REG(0) == REG_IXL) INST_RETURN(2, INST_IX_PREFIX, 0x2C) + if (INST_REG(0) == REG_IYL) + INST_RETURN(2, INST_IY_PREFIX, 0x2C) if (INST_REG(0) == REG_BC) INST_RETURN(1, 0x03) if (INST_REG(0) == REG_DE) INST_RETURN(1, 0x13) - if (INST_REG(0) == REG_IY) - INST_RETURN(2, INST_IY_PREFIX, 0x23) - if (INST_REG(0) == REG_IX) - INST_RETURN(2, INST_IX_PREFIX, 0x23) if (INST_REG(0) == REG_HL) INST_RETURN(1, 0x23) + if (INST_REG(0) == REG_IX) + INST_RETURN(2, INST_IX_PREFIX, 0x23) + if (INST_REG(0) == REG_IY) + INST_RETURN(2, INST_IY_PREFIX, 0x23) if (INST_REG(0) == REG_SP) INST_RETURN(1, 0x33) INST_ERROR(ARG_VALUE) @@ -291,6 +291,388 @@ INST_FUNC(inir) INST_RETURN(2, 0xED, 0xB2) } +INST_FUNC(ld) +{ + INST_TAKES_ARGS( + AT_INDEXED|AT_INDIRECT|AT_REGISTER, + AT_IMMEDIATE|AT_INDEXED|AT_INDIRECT|AT_REGISTER, + AT_NONE + ) + if (INST_NARGS == 2 && INST_TYPE(0) == AT_REGISTER && INST_TYPE(1) == AT_REGISTER) { + if (INST_REG(0) == REG_A && INST_REG(1) == REG_A) + INST_RETURN(1, 0x7F) + if (INST_REG(0) == REG_A && INST_REG(1) == REG_B) + INST_RETURN(1, 0x78) + if (INST_REG(0) == REG_A && INST_REG(1) == REG_C) + INST_RETURN(1, 0x79) + if (INST_REG(0) == REG_A && INST_REG(1) == REG_D) + INST_RETURN(1, 0x7A) + if (INST_REG(0) == REG_A && INST_REG(1) == REG_E) + INST_RETURN(1, 0x7B) + if (INST_REG(0) == REG_A && INST_REG(1) == REG_H) + INST_RETURN(1, 0x7C) + if (INST_REG(0) == REG_A && INST_REG(1) == REG_IXH) + INST_RETURN(2, INST_IX_PREFIX, 0x7C) + if (INST_REG(0) == REG_A && INST_REG(1) == REG_IYH) + INST_RETURN(2, INST_IY_PREFIX, 0x7C) + if (INST_REG(0) == REG_A && INST_REG(1) == REG_L) + INST_RETURN(1, 0x7D) + if (INST_REG(0) == REG_A && INST_REG(1) == REG_IXL) + INST_RETURN(2, INST_IX_PREFIX, 0x7D) + if (INST_REG(0) == REG_A && INST_REG(1) == REG_IYL) + INST_RETURN(2, INST_IY_PREFIX, 0x7D) + if (INST_REG(0) == REG_B && INST_REG(1) == REG_A) + INST_RETURN(1, 0x47) + if (INST_REG(0) == REG_B && INST_REG(1) == REG_B) + INST_RETURN(1, 0x40) + if (INST_REG(0) == REG_B && INST_REG(1) == REG_C) + INST_RETURN(1, 0x41) + if (INST_REG(0) == REG_B && INST_REG(1) == REG_D) + INST_RETURN(1, 0x42) + if (INST_REG(0) == REG_B && INST_REG(1) == REG_E) + INST_RETURN(1, 0x43) + if (INST_REG(0) == REG_B && INST_REG(1) == REG_H) + INST_RETURN(1, 0x44) + if (INST_REG(0) == REG_B && INST_REG(1) == REG_IXH) + INST_RETURN(2, INST_IX_PREFIX, 0x44) + if (INST_REG(0) == REG_B && INST_REG(1) == REG_IYH) + INST_RETURN(2, INST_IY_PREFIX, 0x44) + if (INST_REG(0) == REG_B && INST_REG(1) == REG_L) + INST_RETURN(1, 0x45) + if (INST_REG(0) == REG_B && INST_REG(1) == REG_IXL) + INST_RETURN(2, INST_IX_PREFIX, 0x45) + if (INST_REG(0) == REG_B && INST_REG(1) == REG_IYL) + INST_RETURN(2, INST_IY_PREFIX, 0x45) + if (INST_REG(0) == REG_C && INST_REG(1) == REG_A) + INST_RETURN(1, 0x4F) + if (INST_REG(0) == REG_C && INST_REG(1) == REG_B) + INST_RETURN(1, 0x48) + if (INST_REG(0) == REG_C && INST_REG(1) == REG_C) + INST_RETURN(1, 0x49) + if (INST_REG(0) == REG_C && INST_REG(1) == REG_D) + INST_RETURN(1, 0x4A) + if (INST_REG(0) == REG_C && INST_REG(1) == REG_E) + INST_RETURN(1, 0x4B) + if (INST_REG(0) == REG_C && INST_REG(1) == REG_H) + INST_RETURN(1, 0x4C) + if (INST_REG(0) == REG_C && INST_REG(1) == REG_IXH) + INST_RETURN(2, INST_IX_PREFIX, 0x4C) + if (INST_REG(0) == REG_C && INST_REG(1) == REG_IYH) + INST_RETURN(2, INST_IY_PREFIX, 0x4C) + if (INST_REG(0) == REG_C && INST_REG(1) == REG_L) + INST_RETURN(1, 0x4D) + if (INST_REG(0) == REG_C && INST_REG(1) == REG_IXL) + INST_RETURN(2, INST_IX_PREFIX, 0x4D) + if (INST_REG(0) == REG_C && INST_REG(1) == REG_IYL) + INST_RETURN(2, INST_IY_PREFIX, 0x4D) + if (INST_REG(0) == REG_D && INST_REG(1) == REG_A) + INST_RETURN(1, 0x57) + if (INST_REG(0) == REG_D && INST_REG(1) == REG_B) + INST_RETURN(1, 0x50) + if (INST_REG(0) == REG_D && INST_REG(1) == REG_C) + INST_RETURN(1, 0x51) + if (INST_REG(0) == REG_D && INST_REG(1) == REG_D) + INST_RETURN(1, 0x52) + if (INST_REG(0) == REG_D && INST_REG(1) == REG_E) + INST_RETURN(1, 0x53) + if (INST_REG(0) == REG_D && INST_REG(1) == REG_H) + INST_RETURN(1, 0x54) + if (INST_REG(0) == REG_D && INST_REG(1) == REG_IXH) + INST_RETURN(2, INST_IX_PREFIX, 0x54) + if (INST_REG(0) == REG_D && INST_REG(1) == REG_IYH) + INST_RETURN(2, INST_IY_PREFIX, 0x54) + if (INST_REG(0) == REG_D && INST_REG(1) == REG_L) + INST_RETURN(1, 0x55) + if (INST_REG(0) == REG_D && INST_REG(1) == REG_IXL) + INST_RETURN(2, INST_IX_PREFIX, 0x55) + if (INST_REG(0) == REG_D && INST_REG(1) == REG_IYL) + INST_RETURN(2, INST_IY_PREFIX, 0x55) + if (INST_REG(0) == REG_E && INST_REG(1) == REG_A) + INST_RETURN(1, 0x5F) + if (INST_REG(0) == REG_E && INST_REG(1) == REG_B) + INST_RETURN(1, 0x58) + if (INST_REG(0) == REG_E && INST_REG(1) == REG_C) + INST_RETURN(1, 0x59) + if (INST_REG(0) == REG_E && INST_REG(1) == REG_D) + INST_RETURN(1, 0x5A) + if (INST_REG(0) == REG_E && INST_REG(1) == REG_E) + INST_RETURN(1, 0x5B) + if (INST_REG(0) == REG_E && INST_REG(1) == REG_H) + INST_RETURN(1, 0x5C) + if (INST_REG(0) == REG_E && INST_REG(1) == REG_IXH) + INST_RETURN(2, INST_IX_PREFIX, 0x5C) + if (INST_REG(0) == REG_E && INST_REG(1) == REG_IYH) + INST_RETURN(2, INST_IY_PREFIX, 0x5C) + if (INST_REG(0) == REG_E && INST_REG(1) == REG_L) + INST_RETURN(1, 0x5D) + if (INST_REG(0) == REG_E && INST_REG(1) == REG_IXL) + INST_RETURN(2, INST_IX_PREFIX, 0x5D) + if (INST_REG(0) == REG_E && INST_REG(1) == REG_IYL) + INST_RETURN(2, INST_IY_PREFIX, 0x5D) + if (INST_REG(0) == REG_H && INST_REG(1) == REG_A) + INST_RETURN(1, 0x67) + if (INST_REG(0) == REG_IXH && INST_REG(1) == REG_A) + INST_RETURN(2, INST_IX_PREFIX, 0x67) + if (INST_REG(0) == REG_IYH && INST_REG(1) == REG_A) + INST_RETURN(2, INST_IY_PREFIX, 0x67) + if (INST_REG(0) == REG_H && INST_REG(1) == REG_B) + INST_RETURN(1, 0x60) + if (INST_REG(0) == REG_IXH && INST_REG(1) == REG_B) + INST_RETURN(2, INST_IX_PREFIX, 0x60) + if (INST_REG(0) == REG_IYH && INST_REG(1) == REG_B) + INST_RETURN(2, INST_IY_PREFIX, 0x60) + if (INST_REG(0) == REG_H && INST_REG(1) == REG_C) + INST_RETURN(1, 0x61) + if (INST_REG(0) == REG_IXH && INST_REG(1) == REG_C) + INST_RETURN(2, INST_IX_PREFIX, 0x61) + if (INST_REG(0) == REG_IYH && INST_REG(1) == REG_C) + INST_RETURN(2, INST_IY_PREFIX, 0x61) + if (INST_REG(0) == REG_H && INST_REG(1) == REG_D) + INST_RETURN(1, 0x62) + if (INST_REG(0) == REG_IXH && INST_REG(1) == REG_D) + INST_RETURN(2, INST_IX_PREFIX, 0x62) + if (INST_REG(0) == REG_IYH && INST_REG(1) == REG_D) + INST_RETURN(2, INST_IY_PREFIX, 0x62) + if (INST_REG(0) == REG_H && INST_REG(1) == REG_E) + INST_RETURN(1, 0x63) + if (INST_REG(0) == REG_IXH && INST_REG(1) == REG_E) + INST_RETURN(2, INST_IX_PREFIX, 0x63) + if (INST_REG(0) == REG_IYH && INST_REG(1) == REG_E) + INST_RETURN(2, INST_IY_PREFIX, 0x63) + if (INST_REG(0) == REG_H && INST_REG(1) == REG_H) + INST_RETURN(1, 0x64) + if (INST_REG(0) == REG_IXH && INST_REG(1) == REG_IXH) + INST_RETURN(3, INST_IX_PREFIX, INST_IX_PREFIX, 0x64) + if (INST_REG(0) == REG_IYH && INST_REG(1) == REG_IYH) + INST_RETURN(3, INST_IY_PREFIX, INST_IY_PREFIX, 0x64) + if (INST_REG(0) == REG_H && INST_REG(1) == REG_L) + INST_RETURN(1, 0x65) + if (INST_REG(0) == REG_IXH && INST_REG(1) == REG_IXL) + INST_RETURN(3, INST_IX_PREFIX, INST_IX_PREFIX, 0x65) + if (INST_REG(0) == REG_IYH && INST_REG(1) == REG_IYL) + INST_RETURN(3, INST_IY_PREFIX, INST_IY_PREFIX, 0x65) + if (INST_REG(0) == REG_L && INST_REG(1) == REG_A) + INST_RETURN(1, 0x6F) + if (INST_REG(0) == REG_IXL && INST_REG(1) == REG_A) + INST_RETURN(2, INST_IX_PREFIX, 0x6F) + if (INST_REG(0) == REG_IYL && INST_REG(1) == REG_A) + INST_RETURN(2, INST_IY_PREFIX, 0x6F) + if (INST_REG(0) == REG_L && INST_REG(1) == REG_B) + INST_RETURN(1, 0x68) + if (INST_REG(0) == REG_IXL && INST_REG(1) == REG_B) + INST_RETURN(2, INST_IX_PREFIX, 0x68) + if (INST_REG(0) == REG_IYL && INST_REG(1) == REG_B) + INST_RETURN(2, INST_IY_PREFIX, 0x68) + if (INST_REG(0) == REG_L && INST_REG(1) == REG_C) + INST_RETURN(1, 0x69) + if (INST_REG(0) == REG_IXL && INST_REG(1) == REG_C) + INST_RETURN(2, INST_IX_PREFIX, 0x69) + if (INST_REG(0) == REG_IYL && INST_REG(1) == REG_C) + INST_RETURN(2, INST_IY_PREFIX, 0x69) + if (INST_REG(0) == REG_L && INST_REG(1) == REG_D) + INST_RETURN(1, 0x6A) + if (INST_REG(0) == REG_IXL && INST_REG(1) == REG_D) + INST_RETURN(2, INST_IX_PREFIX, 0x6A) + if (INST_REG(0) == REG_IYL && INST_REG(1) == REG_D) + INST_RETURN(2, INST_IY_PREFIX, 0x6A) + if (INST_REG(0) == REG_L && INST_REG(1) == REG_E) + INST_RETURN(1, 0x6B) + if (INST_REG(0) == REG_IXL && INST_REG(1) == REG_E) + INST_RETURN(2, INST_IX_PREFIX, 0x6B) + if (INST_REG(0) == REG_IYL && INST_REG(1) == REG_E) + INST_RETURN(2, INST_IY_PREFIX, 0x6B) + if (INST_REG(0) == REG_L && INST_REG(1) == REG_H) + INST_RETURN(1, 0x6C) + if (INST_REG(0) == REG_IXL && INST_REG(1) == REG_IXH) + INST_RETURN(3, INST_IX_PREFIX, INST_IX_PREFIX, 0x6C) + if (INST_REG(0) == REG_IYL && INST_REG(1) == REG_IYH) + INST_RETURN(3, INST_IY_PREFIX, INST_IY_PREFIX, 0x6C) + if (INST_REG(0) == REG_L && INST_REG(1) == REG_L) + INST_RETURN(1, 0x6D) + if (INST_REG(0) == REG_IXL && INST_REG(1) == REG_IXL) + INST_RETURN(3, INST_IX_PREFIX, INST_IX_PREFIX, 0x6D) + if (INST_REG(0) == REG_IYL && INST_REG(1) == REG_IYL) + INST_RETURN(3, INST_IY_PREFIX, INST_IY_PREFIX, 0x6D) + if (INST_REG(0) == REG_A && INST_REG(1) == REG_IX) + INST_RETURN(3, INST_IX_PREFIX, 0xED, 0x57) + if (INST_REG(0) == REG_A && INST_REG(1) == REG_IY) + INST_RETURN(3, INST_IY_PREFIX, 0xED, 0x57) + if (INST_REG(0) == REG_IX && INST_REG(1) == REG_A) + INST_RETURN(3, INST_IX_PREFIX, 0xED, 0x47) + if (INST_REG(0) == REG_IY && INST_REG(1) == REG_A) + INST_RETURN(3, INST_IY_PREFIX, 0xED, 0x47) + if (INST_REG(0) == REG_A && INST_REG(1) == REG_R) + INST_RETURN(2, 0xED, 0x5F) + if (INST_REG(0) == REG_R && INST_REG(1) == REG_A) + INST_RETURN(2, 0xED, 0x4F) + if (INST_REG(0) == REG_SP && INST_REG(1) == REG_HL) + INST_RETURN(1, 0xF9) + if (INST_REG(0) == REG_SP && INST_REG(1) == REG_IX) + INST_RETURN(2, INST_IX_PREFIX, 0xF9) + if (INST_REG(0) == REG_SP && INST_REG(1) == REG_IY) + INST_RETURN(2, INST_IY_PREFIX, 0xF9) + INST_ERROR(ARG_VALUE) + } + if (INST_NARGS == 2 && INST_TYPE(0) == AT_REGISTER && INST_TYPE(1) == AT_IMMEDIATE) { + if (INST_REG(0) == REG_A && INST_IMM(1).mask & IMM_U8) + INST_RETURN(2, 0x3E, INST_IMM(1).uval) + if (INST_REG(0) == REG_B && INST_IMM(1).mask & IMM_U8) + INST_RETURN(2, 0x06, INST_IMM(1).uval) + if (INST_REG(0) == REG_C && INST_IMM(1).mask & IMM_U8) + INST_RETURN(2, 0x0E, INST_IMM(1).uval) + if (INST_REG(0) == REG_D && INST_IMM(1).mask & IMM_U8) + INST_RETURN(2, 0x16, INST_IMM(1).uval) + if (INST_REG(0) == REG_E && INST_IMM(1).mask & IMM_U8) + INST_RETURN(2, 0x1E, INST_IMM(1).uval) + if (INST_REG(0) == REG_H && INST_IMM(1).mask & IMM_U8) + INST_RETURN(2, 0x26, INST_IMM(1).uval) + if (INST_REG(0) == REG_IXH && INST_IMM(1).mask & IMM_U8) + INST_RETURN(3, INST_IX_PREFIX, 0x26, INST_IMM(1).uval) + if (INST_REG(0) == REG_IYH && INST_IMM(1).mask & IMM_U8) + INST_RETURN(3, INST_IY_PREFIX, 0x26, INST_IMM(1).uval) + if (INST_REG(0) == REG_L && INST_IMM(1).mask & IMM_U8) + INST_RETURN(2, 0x2E, INST_IMM(1).uval) + if (INST_REG(0) == REG_IXL && INST_IMM(1).mask & IMM_U8) + INST_RETURN(3, INST_IX_PREFIX, 0x2E, INST_IMM(1).uval) + if (INST_REG(0) == REG_IYL && INST_IMM(1).mask & IMM_U8) + INST_RETURN(3, INST_IY_PREFIX, 0x2E, INST_IMM(1).uval) + if (INST_REG(0) == REG_BC && INST_IMM(1).mask & IMM_U16) + INST_RETURN(3, 0x01, INST_IMM_U16_B1(INST_IMM(1)), INST_IMM_U16_B2(INST_IMM(1))) + if (INST_REG(0) == REG_DE && INST_IMM(1).mask & IMM_U16) + INST_RETURN(3, 0x11, INST_IMM_U16_B1(INST_IMM(1)), INST_IMM_U16_B2(INST_IMM(1))) + if (INST_REG(0) == REG_HL && INST_IMM(1).mask & IMM_U16) + INST_RETURN(3, 0x21, INST_IMM_U16_B1(INST_IMM(1)), INST_IMM_U16_B2(INST_IMM(1))) + if (INST_REG(0) == REG_IX && INST_IMM(1).mask & IMM_U16) + INST_RETURN(4, INST_IX_PREFIX, 0x21, INST_IMM_U16_B1(INST_IMM(1)), INST_IMM_U16_B2(INST_IMM(1))) + if (INST_REG(0) == REG_IY && INST_IMM(1).mask & IMM_U16) + INST_RETURN(4, INST_IY_PREFIX, 0x21, INST_IMM_U16_B1(INST_IMM(1)), INST_IMM_U16_B2(INST_IMM(1))) + if (INST_REG(0) == REG_SP && INST_IMM(1).mask & IMM_U16) + INST_RETURN(3, 0x31, INST_IMM_U16_B1(INST_IMM(1)), INST_IMM_U16_B2(INST_IMM(1))) + INST_ERROR(ARG_VALUE) + } + if (INST_NARGS == 2 && INST_TYPE(0) == AT_REGISTER && INST_TYPE(1) == AT_INDIRECT) { + if (INST_REG(0) == REG_A && (INST_INDIRECT(1).type == AT_REGISTER && INST_INDIRECT(1).addr.reg == REG_HL)) + INST_RETURN(1, 0x7E) + if (INST_REG(0) == REG_B && (INST_INDIRECT(1).type == AT_REGISTER && INST_INDIRECT(1).addr.reg == REG_HL)) + INST_RETURN(1, 0x46) + if (INST_REG(0) == REG_C && (INST_INDIRECT(1).type == AT_REGISTER && INST_INDIRECT(1).addr.reg == REG_HL)) + INST_RETURN(1, 0x4E) + if (INST_REG(0) == REG_D && (INST_INDIRECT(1).type == AT_REGISTER && INST_INDIRECT(1).addr.reg == REG_HL)) + INST_RETURN(1, 0x56) + if (INST_REG(0) == REG_E && (INST_INDIRECT(1).type == AT_REGISTER && INST_INDIRECT(1).addr.reg == REG_HL)) + INST_RETURN(1, 0x5E) + if (INST_REG(0) == REG_H && (INST_INDIRECT(1).type == AT_REGISTER && INST_INDIRECT(1).addr.reg == REG_HL)) + INST_RETURN(1, 0x66) + if (INST_REG(0) == REG_L && (INST_INDIRECT(1).type == AT_REGISTER && INST_INDIRECT(1).addr.reg == REG_HL)) + INST_RETURN(1, 0x6E) + INST_ERROR(ARG_VALUE) + } + if (INST_NARGS == 2 && INST_TYPE(0) == AT_REGISTER && INST_TYPE(1) == AT_INDEXED) { + if (INST_REG(0) == REG_A) + INST_RETURN(3, INST_INDEX_PREFIX(1), 0x7E, INST_INDEX(1).offset) + if (INST_REG(0) == REG_B) + INST_RETURN(3, INST_INDEX_PREFIX(1), 0x46, INST_INDEX(1).offset) + if (INST_REG(0) == REG_C) + INST_RETURN(3, INST_INDEX_PREFIX(1), 0x4E, INST_INDEX(1).offset) + if (INST_REG(0) == REG_D) + INST_RETURN(3, INST_INDEX_PREFIX(1), 0x56, INST_INDEX(1).offset) + if (INST_REG(0) == REG_E) + INST_RETURN(3, INST_INDEX_PREFIX(1), 0x5E, INST_INDEX(1).offset) + if (INST_REG(0) == REG_H) + INST_RETURN(3, INST_INDEX_PREFIX(1), 0x66, INST_INDEX(1).offset) + if (INST_REG(0) == REG_L) + INST_RETURN(3, INST_INDEX_PREFIX(1), 0x6E, INST_INDEX(1).offset) + INST_ERROR(ARG_VALUE) + } + if (INST_NARGS == 2 && INST_TYPE(0) == AT_REGISTER && INST_TYPE(1) == AT_INDIRECT) { + if (INST_REG(0) == REG_A && (INST_INDIRECT(1).type == AT_REGISTER && INST_INDIRECT(1).addr.reg == REG_BC)) + INST_RETURN(1, 0x0A) + if (INST_REG(0) == REG_A && (INST_INDIRECT(1).type == AT_REGISTER && INST_INDIRECT(1).addr.reg == REG_DE)) + INST_RETURN(1, 0x1A) + if (INST_REG(0) == REG_HL && INST_INDIRECT(1).type == AT_IMMEDIATE) + INST_RETURN(3, 0x2A, INST_IMM_U16_B1(INST_INDIRECT(1).addr.imm), INST_IMM_U16_B2(INST_INDIRECT(1).addr.imm)) + if (INST_REG(0) == REG_IX && INST_INDIRECT(1).type == AT_IMMEDIATE) + INST_RETURN(4, INST_IX_PREFIX, 0x2A, INST_IMM_U16_B1(INST_INDIRECT(1).addr.imm), INST_IMM_U16_B2(INST_INDIRECT(1).addr.imm)) + if (INST_REG(0) == REG_IY && INST_INDIRECT(1).type == AT_IMMEDIATE) + INST_RETURN(4, INST_IY_PREFIX, 0x2A, INST_IMM_U16_B1(INST_INDIRECT(1).addr.imm), INST_IMM_U16_B2(INST_INDIRECT(1).addr.imm)) + if (INST_REG(0) == REG_A && INST_INDIRECT(1).type == AT_IMMEDIATE) + INST_RETURN(3, 0x3A, INST_IMM_U16_B1(INST_INDIRECT(1).addr.imm), INST_IMM_U16_B2(INST_INDIRECT(1).addr.imm)) + if (INST_REG(0) == REG_BC && INST_INDIRECT(1).type == AT_IMMEDIATE) + INST_RETURN(4, 0xED, 0x4B, INST_IMM_U16_B1(INST_INDIRECT(1).addr.imm), INST_IMM_U16_B2(INST_INDIRECT(1).addr.imm)) + if (INST_REG(0) == REG_DE && INST_INDIRECT(1).type == AT_IMMEDIATE) + INST_RETURN(4, 0xED, 0x5B, INST_IMM_U16_B1(INST_INDIRECT(1).addr.imm), INST_IMM_U16_B2(INST_INDIRECT(1).addr.imm)) + if (INST_REG(0) == REG_SP && INST_INDIRECT(1).type == AT_IMMEDIATE) + INST_RETURN(4, 0xED, 0x7B, INST_IMM_U16_B1(INST_INDIRECT(1).addr.imm), INST_IMM_U16_B2(INST_INDIRECT(1).addr.imm)) + INST_ERROR(ARG_VALUE) + } + if (INST_NARGS == 2 && INST_TYPE(0) == AT_INDIRECT && INST_TYPE(1) == AT_REGISTER) { + if ((INST_INDIRECT(0).type == AT_REGISTER && INST_INDIRECT(0).addr.reg == REG_HL) && INST_REG(1) == REG_A) + INST_RETURN(1, 0x77) + if ((INST_INDIRECT(0).type == AT_REGISTER && INST_INDIRECT(0).addr.reg == REG_HL) && INST_REG(1) == REG_B) + INST_RETURN(1, 0x70) + if ((INST_INDIRECT(0).type == AT_REGISTER && INST_INDIRECT(0).addr.reg == REG_HL) && INST_REG(1) == REG_C) + INST_RETURN(1, 0x71) + if ((INST_INDIRECT(0).type == AT_REGISTER && INST_INDIRECT(0).addr.reg == REG_HL) && INST_REG(1) == REG_D) + INST_RETURN(1, 0x72) + if ((INST_INDIRECT(0).type == AT_REGISTER && INST_INDIRECT(0).addr.reg == REG_HL) && INST_REG(1) == REG_E) + INST_RETURN(1, 0x73) + if ((INST_INDIRECT(0).type == AT_REGISTER && INST_INDIRECT(0).addr.reg == REG_HL) && INST_REG(1) == REG_H) + INST_RETURN(1, 0x74) + if ((INST_INDIRECT(0).type == AT_REGISTER && INST_INDIRECT(0).addr.reg == REG_HL) && INST_REG(1) == REG_L) + INST_RETURN(1, 0x75) + INST_ERROR(ARG_VALUE) + } + if (INST_NARGS == 2 && INST_TYPE(0) == AT_INDEXED && INST_TYPE(1) == AT_REGISTER) { + if (INST_REG(1) == REG_A) + INST_RETURN(3, INST_INDEX_PREFIX(0), 0x77, INST_INDEX(0).offset) + if (INST_REG(1) == REG_B) + INST_RETURN(3, INST_INDEX_PREFIX(0), 0x70, INST_INDEX(0).offset) + if (INST_REG(1) == REG_C) + INST_RETURN(3, INST_INDEX_PREFIX(0), 0x71, INST_INDEX(0).offset) + if (INST_REG(1) == REG_D) + INST_RETURN(3, INST_INDEX_PREFIX(0), 0x72, INST_INDEX(0).offset) + if (INST_REG(1) == REG_E) + INST_RETURN(3, INST_INDEX_PREFIX(0), 0x73, INST_INDEX(0).offset) + if (INST_REG(1) == REG_H) + INST_RETURN(3, INST_INDEX_PREFIX(0), 0x74, INST_INDEX(0).offset) + if (INST_REG(1) == REG_L) + INST_RETURN(3, INST_INDEX_PREFIX(0), 0x75, INST_INDEX(0).offset) + INST_ERROR(ARG_VALUE) + } + if (INST_NARGS == 2 && INST_TYPE(0) == AT_INDIRECT && INST_TYPE(1) == AT_IMMEDIATE) { + if ((INST_INDIRECT(0).type == AT_REGISTER && INST_INDIRECT(0).addr.reg == REG_HL) && INST_IMM(1).mask & IMM_U8) + INST_RETURN(2, 0x36, INST_IMM(1).uval) + INST_ERROR(ARG_VALUE) + } + if (INST_NARGS == 2 && INST_TYPE(0) == AT_INDEXED && INST_TYPE(1) == AT_IMMEDIATE) { + if (INST_IMM(1).mask & IMM_U8) + INST_RETURN(4, INST_INDEX_PREFIX(0), 0x36, INST_IMM(1).uval, INST_INDEX(0).offset) + INST_ERROR(ARG_VALUE) + } + if (INST_NARGS == 2 && INST_TYPE(0) == AT_INDIRECT && INST_TYPE(1) == AT_REGISTER) { + if ((INST_INDIRECT(0).type == AT_REGISTER && INST_INDIRECT(0).addr.reg == REG_BC) && INST_REG(1) == REG_A) + INST_RETURN(1, 0x02) + if ((INST_INDIRECT(0).type == AT_REGISTER && INST_INDIRECT(0).addr.reg == REG_DE) && INST_REG(1) == REG_A) + INST_RETURN(1, 0x12) + if (INST_INDIRECT(0).type == AT_IMMEDIATE && INST_REG(1) == REG_HL) + INST_RETURN(3, 0x22, INST_IMM_U16_B1(INST_INDIRECT(0).addr.imm), INST_IMM_U16_B2(INST_INDIRECT(0).addr.imm)) + if (INST_INDIRECT(0).type == AT_IMMEDIATE && INST_REG(1) == REG_IX) + INST_RETURN(4, INST_IX_PREFIX, 0x22, INST_IMM_U16_B1(INST_INDIRECT(0).addr.imm), INST_IMM_U16_B2(INST_INDIRECT(0).addr.imm)) + if (INST_INDIRECT(0).type == AT_IMMEDIATE && INST_REG(1) == REG_IY) + INST_RETURN(4, INST_IY_PREFIX, 0x22, INST_IMM_U16_B1(INST_INDIRECT(0).addr.imm), INST_IMM_U16_B2(INST_INDIRECT(0).addr.imm)) + if (INST_INDIRECT(0).type == AT_IMMEDIATE && INST_REG(1) == REG_A) + INST_RETURN(3, 0x32, INST_IMM_U16_B1(INST_INDIRECT(0).addr.imm), INST_IMM_U16_B2(INST_INDIRECT(0).addr.imm)) + if (INST_INDIRECT(0).type == AT_IMMEDIATE && INST_REG(1) == REG_BC) + INST_RETURN(4, 0xED, 0x43, INST_IMM_U16_B1(INST_INDIRECT(0).addr.imm), INST_IMM_U16_B2(INST_INDIRECT(0).addr.imm)) + if (INST_INDIRECT(0).type == AT_IMMEDIATE && INST_REG(1) == REG_DE) + INST_RETURN(4, 0xED, 0x53, INST_IMM_U16_B1(INST_INDIRECT(0).addr.imm), INST_IMM_U16_B2(INST_INDIRECT(0).addr.imm)) + if (INST_INDIRECT(0).type == AT_IMMEDIATE && INST_REG(1) == REG_SP) + INST_RETURN(4, 0xED, 0x73, INST_IMM_U16_B1(INST_INDIRECT(0).addr.imm), INST_IMM_U16_B2(INST_INDIRECT(0).addr.imm)) + INST_ERROR(ARG_VALUE) + } + INST_ERROR(ARG_TYPE) +} + INST_FUNC(ldd) { INST_TAKES_NO_ARGS @@ -425,6 +807,7 @@ static ASMInstParser lookup_parser(uint32_t key) HANDLE(indr) HANDLE(ini) HANDLE(inir) + HANDLE(ld) HANDLE(ldd) HANDLE(lddr) HANDLE(ldi) diff --git a/src/assembler/instructions.yml b/src/assembler/instructions.yml index 00359ac..dc4e5e0 100644 --- a/src/assembler/instructions.yml +++ b/src/assembler/instructions.yml @@ -69,7 +69,7 @@ add: return: [0x09] - cond: [hl|i, de] return: [0x19] - - cond: [hl|i, hl] + - cond: [hl|i, hl|i] return: [0x29] - cond: [hl|i, sp] return: [0x39] @@ -83,15 +83,15 @@ add: return: [0x86] # and: -# args: no +# args: yes # return: error # bit: -# args: no +# args: yes # return: error # call: -# args: no +# args: yes # return: error ccf: @@ -99,7 +99,7 @@ ccf: return: [0x3F] # cp: -# args: no +# args: yes # return: error cpd: @@ -127,7 +127,7 @@ daa: return: [0x27] # dec: -# args: no +# args: yes # return: error di: @@ -135,7 +135,7 @@ di: return: [0xF3] # djnz: -# args: no +# args: yes # return: error ei: @@ -143,7 +143,7 @@ ei: return: [0xFB] # ex: -# args: no +# args: yes # return: error exx: @@ -155,11 +155,11 @@ halt: return: [0x76] # im: -# args: no +# args: yes # return: error # in: -# args: no +# args: yes # return: error inc: @@ -211,16 +211,218 @@ inir: return: [0xED, 0xB2] # jp: -# args: no +# args: yes # return: error # jr: -# args: no +# args: yes # return: error -# ld: -# args: no -# return: error +ld: + args: yes + cases: + - type: [register, register] + cases: + - cond: [a, a] + return: [0x7F] + - cond: [a, b] + return: [0x78] + - cond: [a, c] + return: [0x79] + - cond: [a, d] + return: [0x7A] + - cond: [a, e] + return: [0x7B] + - cond: [a, h|ih] + return: [0x7C] + - cond: [a, l|il] + return: [0x7D] + - cond: [b, a] + return: [0x47] + - cond: [b, b] + return: [0x40] + - cond: [b, c] + return: [0x41] + - cond: [b, d] + return: [0x42] + - cond: [b, e] + return: [0x43] + - cond: [b, h|ih] + return: [0x44] + - cond: [b, l|il] + return: [0x45] + - cond: [c, a] + return: [0x4F] + - cond: [c, b] + return: [0x48] + - cond: [c, c] + return: [0x49] + - cond: [c, d] + return: [0x4A] + - cond: [c, e] + return: [0x4B] + - cond: [c, h|ih] + return: [0x4C] + - cond: [c, l|il] + return: [0x4D] + - cond: [d, a] + return: [0x57] + - cond: [d, b] + return: [0x50] + - cond: [d, c] + return: [0x51] + - cond: [d, d] + return: [0x52] + - cond: [d, e] + return: [0x53] + - cond: [d, h|ih] + return: [0x54] + - cond: [d, l|il] + return: [0x55] + - cond: [e, a] + return: [0x5F] + - cond: [e, b] + return: [0x58] + - cond: [e, c] + return: [0x59] + - cond: [e, d] + return: [0x5A] + - cond: [e, e] + return: [0x5B] + - cond: [e, h|ih] + return: [0x5C] + - cond: [e, l|il] + return: [0x5D] + - cond: [h|ih, a] + return: [0x67] + - cond: [h|ih, b] + return: [0x60] + - cond: [h|ih, c] + return: [0x61] + - cond: [h|ih, d] + return: [0x62] + - cond: [h|ih, e] + return: [0x63] + - cond: [h|ih, h|ih] + return: [0x64] + - cond: [h|ih, l|il] + return: [0x65] + - cond: [l|il, a] + return: [0x6F] + - cond: [l|il, b] + return: [0x68] + - cond: [l|il, c] + return: [0x69] + - cond: [l|il, d] + return: [0x6A] + - cond: [l|il, e] + return: [0x6B] + - cond: [l|il, h|ih] + return: [0x6C] + - cond: [l|il, l|il] + return: [0x6D] + - cond: [a, i] + return: [0xED, 0x57] + - cond: [i, a] + return: [0xED, 0x47] + - cond: [a, r] + return: [0xED, 0x5F] + - cond: [r, a] + return: [0xED, 0x4F] + - cond: [sp, hl|i] + return: [0xF9] + - type: [register, immediate] + cases: + - cond: [a, u8] + return: [0x3E, u8] + - cond: [b, u8] + return: [0x06, u8] + - cond: [c, u8] + return: [0x0E, u8] + - cond: [d, u8] + return: [0x16, u8] + - cond: [e, u8] + return: [0x1E, u8] + - cond: [h|ih, u8] + return: [0x26, u8] + - cond: [l|il, u8] + return: [0x2E, u8] + - cond: [bc, u16] + return: [0x01, u16] + - cond: [de, u16] + return: [0x11, u16] + - cond: [hl|i, u16] + return: [0x21, u16] + - cond: [sp, u16] + return: [0x31, u16] + - type: [register, indirect_hl_or_indexed] + cases: + - cond: [a, _] + return: [0x7E] + - cond: [b, _] + return: [0x46] + - cond: [c, _] + return: [0x4E] + - cond: [d, _] + return: [0x56] + - cond: [e, _] + return: [0x5E] + - cond: [h, _] + return: [0x66] + - cond: [l, _] + return: [0x6E] + - type: [register, indirect] + cases: + - cond: [a, reg.bc] + return: [0x0A] + - cond: [a, reg.de] + return: [0x1A] + - cond: [hl|i, imm] + return: [0x2A, u16] + - cond: [a, imm] + return: [0x3A, u16] + - cond: [bc, imm] + return: [0xED, 0x4B, u16] + - cond: [de, imm] + return: [0xED, 0x5B, u16] + - cond: [sp, imm] + return: [0xED, 0x7B, u16] + - type: [indirect_hl_or_indexed, register] # TODO, support both this and regular indirect + cases: + - cond: [_, a] + return: [0x77] + - cond: [_, b] + return: [0x70] + - cond: [_, c] + return: [0x71] + - cond: [_, d] + return: [0x72] + - cond: [_, e] + return: [0x73] + - cond: [_, h] + return: [0x74] + - cond: [_, l] + return: [0x75] + - type: [indirect_hl_or_indexed, immediate] + cases: + - cond: [_, u8] + return: [0x36, u8] + - type: [indirect, register] + cases: + - cond: [reg.bc, a] + return: [0x02] + - cond: [reg.de, a] + return: [0x12] + - cond: [imm, hl|i] + return: [0x22, u16] + - cond: [imm, a] + return: [0x32, u16] + - cond: [imm, bc] + return: [0xED, 0x43, u16] + - cond: [imm, de] + return: [0xED, 0x53, u16] + - cond: [imm, sp] + return: [0xED, 0x73, u16] ldd: args: no @@ -247,7 +449,7 @@ nop: return: [0x00] # or: -# args: no +# args: yes # return: error otdr: @@ -259,7 +461,7 @@ otir: return: [0xED, 0xB3] # out: -# args: no +# args: yes # return: error outd: @@ -271,19 +473,19 @@ outi: return: [0xED, 0xA3] # pop: -# args: no +# args: yes # return: error # push: -# args: no +# args: yes # return: error # res: -# args: no +# args: yes # return: error # ret: -# args: no +# args: yes # return: error reti: @@ -295,7 +497,7 @@ retn: return: [0xED, 0x45] # rl: -# args: no +# args: yes # return: error rla: @@ -303,7 +505,7 @@ rla: return: [0x17] # rlc: -# args: no +# args: yes # return: error rlca: @@ -315,7 +517,7 @@ rld: return: [0xED, 0x6F] # rr: -# args: no +# args: yes # return: error rra: @@ -323,7 +525,7 @@ rra: return: [0x1F] # rrc: -# args: no +# args: yes # return: error rrca: @@ -331,15 +533,15 @@ rrca: return: [0x0F] # rrd: -# args: no +# args: yes # return: error # rst: -# args: no +# args: yes # return: error # sbc: -# args: no +# args: yes # return: error scf: @@ -347,37 +549,37 @@ scf: return: [0x37] # set: -# args: no +# args: yes # return: error # sl1: -# args: no +# args: yes # return: error # sla: -# args: no +# args: yes # return: error # sll: -# args: no +# args: yes # return: error # sls: -# args: no +# args: yes # return: error # sra: -# args: no +# args: yes # return: error # srl: -# args: no +# args: yes # return: error # sub: -# args: no +# args: yes # return: error # xor: -# args: no +# args: yes # return: error