From d6d3b60b3e4373b978bca8ea2322b61154440e07 Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Thu, 28 Apr 2016 22:37:09 -0500 Subject: [PATCH] Fix a couple assembler bugs involving obscure instructions. --- scripts/update_asm_instructions.py | 21 ++++++++++++++------- src/assembler/instructions.inc.c | 30 ++++++++++++++---------------- src/assembler/instructions.yml | 30 +++++++++++++++--------------- 3 files changed, 43 insertions(+), 38 deletions(-) diff --git a/scripts/update_asm_instructions.py b/scripts/update_asm_instructions.py index 2f66fce..ad276c4 100755 --- a/scripts/update_asm_instructions.py +++ b/scripts/update_asm_instructions.py @@ -201,7 +201,7 @@ class Instruction(object): return "INST_INDIRECT({0}).type == AT_IMMEDIATE".format(num) err = "Unknown condition for indirect argument: {0}" - return ASMInstError(err.format(cond)) + raise ASMInstError(err.format(cond)) def _build_indexed_check(self, num, cond): """ @@ -225,7 +225,7 @@ class Instruction(object): return "INST_PORT({0}).type == AT_IMMEDIATE".format(num) err = "Unknown condition for port argument: {0}" - return ASMInstError(err.format(cond)) + raise ASMInstError(err.format(cond)) _SUBCASE_LOOKUP_TABLE = { "register": _build_register_check, @@ -257,12 +257,14 @@ class Instruction(object): raise ASMInstError(msg.format(typ, cond)) return merged if typ == "register": - if cond == "i": + if cond == "ixy": return ["ix", "iy"] if cond == "ih": return ["ixh", "iyh"] if cond == "il": return ["ixl", "iyl"] + if typ == "indirect" and cond == "reg.ixy": + return ["reg.ix", "reg.iy"] return [cond] splits = [split(typ, cond) for typ, cond in zip(types, conds)] @@ -284,6 +286,11 @@ class Instruction(object): index = _rindex(types, "register") return base + self.REGISTER_OFFSETS[conds[index]] * stride + def handle_index(which): + prefix = "INST_I{0}_PREFIX".format(which.upper()) + if ret[0] != prefix: + ret.insert(0, prefix) + ret = ret[:] for i, byte in enumerate(ret): if not isinstance(byte, int): @@ -344,10 +351,10 @@ class Instruction(object): raise ASMInstError(msg.format(byte)) for i, cond in enumerate(conds): - if types[i] == "register" and cond[0] == "i": - prefix = "INST_I{0}_PREFIX".format(cond[1].upper()) - if ret[0] != prefix: - ret.insert(0, prefix) + if types[i] == "register" and cond.startswith(("ix", "iy")): + handle_index(cond[1]) + elif types[i] == "indirect" and cond in ("reg.ix", "reg.iy"): + handle_index(cond[5]) elif types[i] == "indexed": ret.insert(0, "INST_INDEX_PREFIX({0})".format(i)) ret.insert(2, "INST_INDEX({0}).offset".format(i)) diff --git a/src/assembler/instructions.inc.c b/src/assembler/instructions.inc.c index 602c99f..2b43d5d 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 Fri May 22 01:01:58 2015 UTC + @AUTOGEN_DATE Fri Apr 29 03:32:10 2016 UTC */ /* @AUTOGEN_INST_BLOCK_START */ @@ -607,7 +607,7 @@ INST_FUNC(inir) INST_FUNC(jp) { INST_TAKES_ARGS( - AT_CONDITION|AT_IMMEDIATE|AT_INDEXED|AT_INDIRECT, + AT_CONDITION|AT_IMMEDIATE|AT_INDIRECT, AT_IMMEDIATE|AT_OPTIONAL, AT_NONE ) @@ -635,12 +635,14 @@ INST_FUNC(jp) INST_RETURN(3, 0xFA, INST_IMM_U16_B1(INST_IMM(1)), INST_IMM_U16_B2(INST_IMM(1))) INST_ERROR(ARG_VALUE) } - if (INST_NARGS == 1 && INST_TYPE(0) == AT_INDIRECT && - (INST_INDIRECT(0).type == AT_REGISTER && INST_INDIRECT(0).addr.reg == REG_HL)) { - INST_RETURN(1, 0xE9) - } - if (INST_NARGS == 1 && INST_TYPE(0) == AT_INDEXED) { - INST_RETURN(3, INST_INDEX_PREFIX(0), 0xE9, INST_INDEX(0).offset) + if (INST_NARGS == 1 && INST_TYPE(0) == AT_INDIRECT) { + if ((INST_INDIRECT(0).type == AT_REGISTER && INST_INDIRECT(0).addr.reg == REG_HL)) + INST_RETURN(1, 0xE9) + if ((INST_INDIRECT(0).type == AT_REGISTER && INST_INDIRECT(0).addr.reg == REG_IX)) + INST_RETURN(2, INST_IX_PREFIX, 0xE9) + if ((INST_INDIRECT(0).type == AT_REGISTER && INST_INDIRECT(0).addr.reg == REG_IY)) + INST_RETURN(2, INST_IY_PREFIX, 0xE9) + INST_ERROR(ARG_VALUE) } INST_ERROR(ARG_TYPE) } @@ -873,14 +875,10 @@ INST_FUNC(ld) INST_RETURN(2, INST_IX_PREFIX, 0x6D) if (INST_REG(0) == REG_IYL && INST_REG(1) == REG_IYL) INST_RETURN(2, 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_I) + INST_RETURN(2, 0xED, 0x57) + if (INST_REG(0) == REG_I && INST_REG(1) == REG_A) + INST_RETURN(2, 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) diff --git a/src/assembler/instructions.yml b/src/assembler/instructions.yml index 82f5567..d0036af 100644 --- a/src/assembler/instructions.yml +++ b/src/assembler/instructions.yml @@ -35,13 +35,13 @@ add: cases: - if: [a, a|b|c|d|e|h|ih|l|il] return: [reg(0x80)] - - if: [hl|i, bc] + - if: [hl|ixy, bc] return: [0x09] - - if: [hl|i, de] + - if: [hl|ixy, de] return: [0x19] - - if: [hl|i, hl|i] + - if: [hl|ixy, hl|ixy] return: [0x29] - - if: [hl|i, sp] + - if: [hl|ixy, sp] return: [0x39] - type: [register, immediate] cases: @@ -143,7 +143,7 @@ dec: cases: - if: [a|b|c|d|e|h|ih|l|il] return: [reg(0x05 0x08)] - - if: [bc|de|hl|i|sp] + - if: [bc|de|hl|ixy|sp] return: [reg(0x0B 0x10)] - type: [indirect_hl_or_indexed] cases: @@ -177,7 +177,7 @@ ex: return: [0xEB] - type: [indirect, register] cases: - - if: [reg.sp, hl|i] + - if: [reg.sp, hl|ixy] return: [0xE3] exx: @@ -221,7 +221,7 @@ inc: cases: - if: [a|b|c|d|e|h|ih|l|il] return: [reg(0x04 0x08)] - - if: [bc|de|hl|i|sp] + - if: [bc|de|hl|ixy|sp] return: [reg(0x03 0x10)] - type: [indirect_hl_or_indexed] cases: @@ -255,9 +255,9 @@ jp: cases: - if: [nz|z|nc|c|po|pe|p|m, u16] return: [cond(0xC2 0x08), u16] - - type: [indirect_hl_or_indexed] + - type: [indirect] cases: - - if: [_] + - if: [reg.hl|reg.ixy] return: [0xE9] jr: @@ -323,13 +323,13 @@ ld: return: [0xED, 0x5F] - if: [r, a] return: [0xED, 0x4F] - - if: [sp, hl|i] + - if: [sp, hl|ixy] return: [0xF9] - type: [register, immediate] cases: - if: [a|b|c|d|e|h|ih|l|il, u8] return: [reg(0x06 0x08), u8] - - if: [bc|de|hl|i|sp, u16] + - if: [bc|de|hl|ixy|sp, u16] return: [reg(0x01 0x10), u16] - type: [register, indirect_hl_or_indexed] cases: @@ -341,7 +341,7 @@ ld: return: [0x0A] - if: [a, reg.de] return: [0x1A] - - if: [hl|i, imm] + - if: [hl|ixy, imm] return: [0x2A, u16] - if: [a, imm] return: [0x3A, u16] @@ -361,7 +361,7 @@ ld: return: [0x02] - if: [reg.de, a] return: [0x12] - - if: [imm, hl|i] + - if: [imm, hl|ixy] return: [0x22, u16] - if: [imm, a] return: [0x32, u16] @@ -443,7 +443,7 @@ pop: cases: - type: [register] cases: - - if: [bc|de|hl|i|af] + - if: [bc|de|hl|ixy|af] return: [reg(0xC1 0x10)] push: @@ -451,7 +451,7 @@ push: cases: - type: [register] cases: - - if: [bc|de|hl|i|af] + - if: [bc|de|hl|ixy|af] return: [reg(0xC5 0x10)] res: