diff options
author | 2025-04-10 07:19:01 -0400 | |
---|---|---|
committer | 2025-04-10 13:19:01 +0200 | |
commit | 6e595d751fbf2066426b5af2e81d87b993510e64 (patch) | |
tree | cf7c7b8e32cd288a86a98e102b63895e5df70e29 | |
parent | e0ea6961f75e06e2fd84ae1ebbb0305a52dda206 (diff) |
z80/z80make.py: Revisited z80 code generator (#13573)
* z80/z80make.py: Revisited z80 code generator
* cpu/z80/t6a84.cpp: isolate device specific callbacks
-rw-r--r-- | scripts/src/cpu.lua | 13 | ||||
-rw-r--r-- | src/devices/cpu/z80/t6a84.cpp | 19 | ||||
-rw-r--r-- | src/devices/cpu/z80/t6a84.h | 11 | ||||
-rw-r--r-- | src/devices/cpu/z80/z80.cpp | 3 | ||||
-rw-r--r-- | src/devices/cpu/z80/z80.h | 12 | ||||
-rw-r--r-- | src/devices/cpu/z80/z80.lst | 67 | ||||
-rw-r--r-- | src/devices/cpu/z80/z80make.py | 222 |
7 files changed, 230 insertions, 117 deletions
diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index ef9a5987072..37bee222d71 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -3031,9 +3031,10 @@ end --@src/devices/cpu/z80/kl5c80a12.h,CPUS["KC80"] = true --@src/devices/cpu/z80/kl5c80a16.h,CPUS["KC80"] = true --@src/devices/cpu/z80/ky80.h,CPUS["KC80"] = true +--@src/devices/cpu/z80/t6a84.h,CPUS["T6A84"] = true -------------------------------------------------- -if CPUS["Z80"] or CPUS["KC80"] or CPUS["Z80N"] then +if CPUS["Z80"] or CPUS["KC80"] or CPUS["Z80N"] or CPUS["T6A84"] then files { MAME_DIR .. "src/devices/cpu/z80/z80.cpp", MAME_DIR .. "src/devices/cpu/z80/z80.h", @@ -3055,18 +3056,22 @@ if CPUS["Z80"] or CPUS["KC80"] or CPUS["Z80N"] then MAME_DIR .. "src/devices/cpu/z80/r800.h", MAME_DIR .. "src/devices/cpu/z80/z84c015.cpp", MAME_DIR .. "src/devices/cpu/z80/z84c015.h", + MAME_DIR .. "src/devices/cpu/z80/t6a84.cpp", + MAME_DIR .. "src/devices/cpu/z80/t6a84.h", } dependency { { MAME_DIR .. "src/devices/cpu/z80/z80.cpp", GEN_DIR .. "emu/cpu/z80/z80.hxx" }, { MAME_DIR .. "src/devices/cpu/z80/nsc800.cpp", GEN_DIR .. "emu/cpu/z80/ncs800.hxx" }, { MAME_DIR .. "src/devices/cpu/z80/r800.cpp", GEN_DIR .. "emu/cpu/z80/r800.hxx" }, + { MAME_DIR .. "src/devices/cpu/z80/t6a84.cpp", GEN_DIR .. "emu/cpu/z80/t6a84.hxx" }, } custombuildtask { - { MAME_DIR .. "src/devices/cpu/z80/z80.lst", GEN_DIR .. "emu/cpu/z80/z80.hxx", { MAME_DIR .. "src/devices/cpu/z80/z80make.py" }, { "@echo Generating Z80 source file...", PYTHON .. " $(1) $(<) $(@)" } }, - { MAME_DIR .. "src/devices/cpu/z80/z80.lst", GEN_DIR .. "emu/cpu/z80/ncs800.hxx", { MAME_DIR .. "src/devices/cpu/z80/z80make.py" }, { "@echo Generating NSC800 source file...", PYTHON .. " $(1) ncs800 $(<) $(@)" } }, - { MAME_DIR .. "src/devices/cpu/z80/z80.lst", GEN_DIR .. "emu/cpu/z80/r800.hxx", { MAME_DIR .. "src/devices/cpu/z80/z80make.py" }, { "@echo Generating R800 source file...", PYTHON .. " $(1) r800 $(<) $(@)" } }, + { MAME_DIR .. "src/devices/cpu/z80/z80.lst", GEN_DIR .. "emu/cpu/z80/z80.hxx", { MAME_DIR .. "src/devices/cpu/z80/z80make.py" }, { "@echo Generating Z80 source file...", PYTHON .. " $(1) $(<) $(@)" } }, + { MAME_DIR .. "src/devices/cpu/z80/z80.lst", GEN_DIR .. "emu/cpu/z80/ncs800.hxx", { MAME_DIR .. "src/devices/cpu/z80/z80make.py" }, { "@echo Generating NSC800 source file...", PYTHON .. " $(1) ncs800 $(<) $(@)" } }, + { MAME_DIR .. "src/devices/cpu/z80/z80.lst", GEN_DIR .. "emu/cpu/z80/r800.hxx", { MAME_DIR .. "src/devices/cpu/z80/z80make.py" }, { "@echo Generating R800 source file...", PYTHON .. " $(1) r800 $(<) $(@)" } }, + { MAME_DIR .. "src/devices/cpu/z80/z80.lst", GEN_DIR .. "emu/cpu/z80/t6a84.hxx", { MAME_DIR .. "src/devices/cpu/z80/z80make.py" }, { "@echo Generating T6A84 source file...", PYTHON .. " $(1) t6a84 $(<) $(@)" } }, } end diff --git a/src/devices/cpu/z80/t6a84.cpp b/src/devices/cpu/z80/t6a84.cpp index 3e0dca08688..48f137d2d89 100644 --- a/src/devices/cpu/z80/t6a84.cpp +++ b/src/devices/cpu/z80/t6a84.cpp @@ -9,9 +9,13 @@ #include "emu.h" #include "t6a84.h" -#define LOG_PAGE_R (1U << 1) -#define LOG_PAGE_W (1U << 2) -#define LOG_MEM (1U << 3) +#include "z80.inc" + +#define LOG_INT (1U << 1) // z80.lst +#define LOG_UNDOC (1U << 2) +#define LOG_PAGE_R (1U << 3) +#define LOG_PAGE_W (1U << 4) +#define LOG_MEM (1U << 5) //#define VERBOSE (LOG_PAGE_R | LOG_PAGE_W | LOG_MEM) #include "logmacro.h" @@ -38,6 +42,9 @@ t6a84_device::t6a84_device(const machine_config &mconfig, device_type type, cons , m_data_space_config("data", ENDIANNESS_LITTLE, 8, 20, 0, 16, 0) , m_stack_space_config("stack", ENDIANNESS_LITTLE, 8, 20, 0, 16, 0) , m_io_space_config("io", ENDIANNESS_LITTLE, 8, 16, 0, io_map) + , m_branch_cb(*this) + , m_irqfetch_cb(*this) + , m_reti_cb(*this) , m_code_page(0) , m_delay_code_page(0) , m_is_delay_code_page_set(false) @@ -48,6 +55,7 @@ t6a84_device::t6a84_device(const machine_config &mconfig, device_type type, cons { // Interrupt vectors need to be fetched and executed from their corresponding page. // For simplicity, we switch pages via callbacks, instead of using a dedicated address space. + // TODO: Find a better way to solve this, at least these hacks are isolated to t6a84.cpp for now. irqfetch_cb().set([this](int state) { LOGMASKED(LOG_PAGE_W, "IRQ FETCH %02x => %02x\n", m_code_page, m_vector_page); m_prev_code_page = m_code_page; @@ -76,6 +84,11 @@ t6a84_device::t6a84_device(const machine_config &mconfig, device_type type, cons }); } +void t6a84_device::execute_run() +{ + #include "cpu/z80/t6a84.hxx" +} + void t6a84_device::device_start() { z80_device::device_start(); diff --git a/src/devices/cpu/z80/t6a84.h b/src/devices/cpu/z80/t6a84.h index 6dfc4285087..1f81b934a99 100644 --- a/src/devices/cpu/z80/t6a84.h +++ b/src/devices/cpu/z80/t6a84.h @@ -40,6 +40,10 @@ public: uint32_t data_address(uint16_t address); uint32_t stack_address(uint16_t address); + auto branch_cb() { return m_branch_cb.bind(); } + auto irqfetch_cb() { return m_irqfetch_cb.bind(); } + auto reti_cb() { return m_reti_cb.bind(); } + protected: t6a84_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor io_map); @@ -47,6 +51,9 @@ protected: virtual void device_start() override; virtual void device_reset() override; + // device_execute_interface implementation + virtual void execute_run() override; + // z80 overrides virtual uint8_t stack_read(uint16_t addr) override; virtual void stack_write(uint16_t addr, uint8_t value) override; @@ -71,6 +78,10 @@ protected: memory_access<16, 0, 0, ENDIANNESS_LITTLE>::specific m_stack; + devcb_write_line m_branch_cb; + devcb_write_line m_irqfetch_cb; + devcb_write_line m_reti_cb; + private: uint8_t m_code_page; uint8_t m_delay_code_page; diff --git a/src/devices/cpu/z80/z80.cpp b/src/devices/cpu/z80/z80.cpp index ba96ac62beb..46b3da1485b 100644 --- a/src/devices/cpu/z80/z80.cpp +++ b/src/devices/cpu/z80/z80.cpp @@ -822,9 +822,6 @@ z80_device::z80_device(const machine_config &mconfig, device_type type, const ch m_nomreq_cb(*this), m_halt_cb(*this), m_busack_cb(*this), - m_branch_cb(*this), - m_irqfetch_cb(*this), - m_reti_cb(*this), m_m1_cycles(4), m_memrq_cycles(3), m_iorq_cycles(4) diff --git a/src/devices/cpu/z80/z80.h b/src/devices/cpu/z80/z80.h index 3a4c926299c..57751694c7f 100644 --- a/src/devices/cpu/z80/z80.h +++ b/src/devices/cpu/z80/z80.h @@ -43,12 +43,6 @@ public: auto halt_cb() { return m_halt_cb.bind(); } auto busack_cb() { return m_busack_cb.bind(); } - // Extra callbacks that do not map to any documented signals. - // Used by derived classes to customise instruction behaviour. - auto branch_cb() { return m_branch_cb.bind(); } - auto irqfetch_cb() { return m_irqfetch_cb.bind(); } - auto reti_cb() { return m_reti_cb.bind(); } - // output pins state int halt_r() { return m_halt; } int busack_r() { return m_busack_state; } @@ -143,12 +137,6 @@ protected: devcb_write_line m_halt_cb; devcb_write_line m_busack_cb; - // Extra callbacks that do not map to any documented signals. - // Used by derived classes to customise instruction behaviour. - devcb_write_line m_branch_cb; - devcb_write_line m_irqfetch_cb; - devcb_write_line m_reti_cb; - PAIR16 m_prvpc; PAIR16 m_pc; PAIR16 m_sp; diff --git a/src/devices/cpu/z80/z80.lst b/src/devices/cpu/z80/z80.lst index 44442cd43f3..3d38a2d35b1 100644 --- a/src/devices/cpu/z80/z80.lst +++ b/src/devices/cpu/z80/z80.lst @@ -4,7 +4,7 @@ # macros ########################################################## macro nomreq_addr - if (!m_nomreq_cb.isunset()) + if (nomemrq_en) m_nomreq_cb(TADR, 0x00, 0xff); + 1 @@ -47,7 +47,7 @@ macro wm16_sp macro rop m_m1_cycles-2 !! TDAT8 = opcode_read(); - if (!m_refresh_cb.isunset()) + if (refresh_en) m_refresh_cb((I << 8) | (R2 & 0x80) | (R & 0x7f), 0x00, 0xff); + 2 PC++; R++; Q = QT; QT = YF | XF; @@ -87,12 +87,26 @@ macro push macro jp call arg16 PC = TDAT; WZ = PC; + +macro t6a84:jp + call arg16 + PC = TDAT; WZ = PC; m_branch_cb(1); macro jp_cond if (TDAT8) { call arg16 PC = TDAT; WZ = PC; + } else { + // implicit do PC += 2 + call arg16 + WZ = TDAT; + } + +macro t6a84:jp_cond + if (TDAT8) { + call arg16 + PC = TDAT; WZ = PC; m_branch_cb(1); } else { // implicit do PC += 2 @@ -105,6 +119,12 @@ macro jr TADR = PC-1; 5 * call nomreq_addr PC += (s8)TDAT8; WZ = PC; + +macro t6a84:jr + call arg + TADR = PC-1; + 5 * call nomreq_addr + PC += (s8)TDAT8; WZ = PC; m_branch_cb(1); macro r800:jr @@ -169,6 +189,11 @@ macro z80n:retn macro reti call pop PC = TDAT; WZ = PC; m_iff1 = m_iff2; + daisy_call_reti_device(); + +macro t6a84:reti + call pop + PC = TDAT; WZ = PC; m_iff1 = m_iff2; m_reti_cb(1); daisy_call_reti_device(); @@ -508,11 +533,11 @@ macro r800:otdr macro jump %opcode m_ref = 0x%opcode00; - continue; + goto process; macro jump_prefixed %prefix m_ref = (%prefix << 16) | (TDAT8 << 8); - continue; + goto process; macro take_nmi // Check if processor was halted @@ -530,6 +555,23 @@ macro take_nmi WZ = PC; m_nmi_pending = false; +macro irqfetch + { + // fetch the IRQ vector + device_z80daisy_interface *intf = daisy_get_irq_device(); + m_tmp_irq_vector = (intf != nullptr) ? intf->z80daisy_irq_ack() : standard_irq_callback(0, m_pc.w); + LOGMASKED(LOG_INT, "single INT m_tmp_irq_vector $%02x\n", m_tmp_irq_vector); + } + +macro t6a84:irqfetch + { + // fetch the IRQ vector + m_irqfetch_cb(1); + device_z80daisy_interface *intf = daisy_get_irq_device(); + m_tmp_irq_vector = (intf != nullptr) ? intf->z80daisy_irq_ack() : standard_irq_callback(0, m_pc.w); + LOGMASKED(LOG_INT, "single INT m_tmp_irq_vector $%02x\n", m_tmp_irq_vector); + } + macro take_interrupt // check if processor was halted leave_halt(); @@ -539,13 +581,7 @@ macro take_interrupt // Not precise in all cases. z80 must finish current instruction (NOP) to reach this state - in such case frame timings are shifter from cb event if calculated based on it. m_irqack_cb(1); m_r++; - { - // fetch the IRQ vector - m_irqfetch_cb(1); - device_z80daisy_interface *intf = daisy_get_irq_device(); - m_tmp_irq_vector = (intf != nullptr) ? intf->z80daisy_irq_ack() : standard_irq_callback(0, m_pc.w); - LOGMASKED(LOG_INT, "single INT m_tmp_irq_vector $%02x\n", m_tmp_irq_vector); - } + call irqfetch // 'interrupt latency' cycles + 2 // Interrupt mode 2. Call [i:databyte] @@ -671,20 +707,19 @@ macro ncs800:check_interrupts # ROP ########################################################## ffff - rop: m_ref = 0xffff00; if (m_icount <= 0) return; if (m_busrq_state) { if (!m_busack_state) { m_busack_state = 1; - m_busack_cb(1); + if (busack_en) m_busack_cb(1); } if (m_icount > 0) m_icount = 0; return; } else if (m_busack_state) { m_busack_state = 0; - m_busack_cb(0); + if (busack_en) m_busack_cb(0); } call check_interrupts m_after_ei = false; @@ -693,13 +728,13 @@ ffff debugger_wait_hook(); call rop PC--; - goto rop; + continue; } else { PRVPC = PC; debugger_instruction_hook(PC); call rop m_ref = (0x00 << 16) | (TDAT8 << 8); - continue; + goto process; } diff --git a/src/devices/cpu/z80/z80make.py b/src/devices/cpu/z80/z80make.py index ed1d097e0a8..38efc20f5ac 100644 --- a/src/devices/cpu/z80/z80make.py +++ b/src/devices/cpu/z80/z80make.py @@ -49,59 +49,91 @@ class IndStr: class Opcode: - def __init__(self, code): + def __init__(self, prefix, code): + self.prefix = prefix self.code = code self.source = [] def add_source_lines(self, lines): self.source.extend(lines) - def save_dasm(self, f): - code = self.code - has_steps = len(self.source) > 1 + def with_steps(self): + for i in range(0, len(self.source)): + tokens = self.source[i].line().split() + if (tokens[0] == '+') or (len(tokens) > 2 and tokens[1] == "!!"): + return True + return False + + def save_dasm(self, step_switch: bool, f): + has_steps = self.with_steps() if has_steps: - print("\t\tswitch (u8(m_ref))", file=f) - print("\t\t{", file=f) - print("\t\tcase 0x00:", file=f) + if step_switch: + print("\t\tswitch (u8(m_ref))", file=f) + print("\t\t{", file=f) + print("\t\tcase 0x00:", file=f) + else: + print("\t\t//case 0x00:", file=f) step = 0 for i in range(0, len(self.source)): il = self.source[i] - if not has_steps: + if not has_steps or not step_switch: il.indent = "" line = il.line() tokens = line.split() + last_line = i + 1 == len(self.source) + if tokens[0] == '+': il.print("m_icount -= %s;" % (" ".join(tokens[1:])), f) step += 1 - to_step = "0x%s" % (hex(256 + step)[3:]) il.print("if (m_icount <= 0) {", f) - il.print(" m_ref = (m_ref & 0xffff00) | %s;" % (to_step), f) - il.print(" return;", f) - il.print("}", f) - il.print("[[fallthrough]];", f) - print("\t\tcase %s:" % (to_step), file=f) + if not last_line: + to_step = hex(256 + step)[3:] + il.print(" m_ref = 0x%s%s%s;" % (self.prefix, self.code, to_step), f) + il.print(" return;", f) + il.print("}", f) + if step_switch: + il.print("[[fallthrough]];", f) + print("\t\tcase 0x%s:" % (to_step), file=f) + else: + print("\t\t//case 0x%s:" % (to_step), file=f) + else: + il.print(" m_ref = 0xffff00;", f) + il.print(" return;", f) + il.print("}", f) elif (len(tokens) > 2 and tokens[1] == "!!"): - il.print("[[fallthrough]];", f) step += 1; - print("\t\tcase 0x%s:" % (hex(256 + step)[3:]), file=f) + if step_switch: + il.print("[[fallthrough]];", f) + print("\t\tcase 0x%s:" % (hex(256 + step)[3:]), file=f) + else: + print("\t\t//case 0x%s:" % (hex(256 + step)[3:]), file=f) il.print("%s" % " ".join(tokens[2:]), f) il.print("m_icount -= %s;" % (tokens[0]), f) il.print("if (m_icount <= 0) {", f) il.print(" if (access_to_be_redone()) {", f) il.print(" m_icount += %s;" % (tokens[0]), f) - il.print(" m_ref = (m_ref & 0xffff00) | 0x%s;" % (hex(256 + step)[3:]), f) - il.print(" } else", f) - step += 1 - to_step = "0x%s" % (hex(256 + step)[3:]) - il.print(" m_ref = (m_ref & 0xffff00) | %s;" % (to_step), f) - il.print(" return;", f) - il.print("}", f) - il.print("[[fallthrough]];", f) - print("\t\tcase %s:" % (to_step), file=f) + il.print(" m_ref = 0x%s%s%s;" % (self.prefix, self.code, hex(256 + step)[3:]), f) + il.print(" } else {", f) + if not last_line: + step += 1 + to_step = hex(256 + step)[3:] + il.print(" m_ref = 0x%s%s%s;" % (self.prefix, self.code, to_step), f) + il.print(" }", f) + il.print(" return;", f) + il.print("}", f) + if step_switch: + il.print("[[fallthrough]];", f) + print("\t\tcase 0x%s:" % (to_step), file=f) + else: + print("\t\t//case 0x%s:" % (to_step), file=f) + else: + il.print(" m_ref = 0xffff00;", f) + il.print(" }", f) + il.print(" return;", f) + il.print("}", f) else: il.print("%s" % line, f) - if has_steps: - print("\t\t\tbreak;\n", file=f) + if has_steps and step_switch: print("\t\t}", file=f) class Macro: @@ -122,7 +154,7 @@ class Macro: class OpcodeList: def __init__(self, gen, fname): self.gen = gen - self.opcode_info = [] + self.opcode_info = {} # prefix -> [Opcode] self.macros = {} try: @@ -167,33 +199,32 @@ class OpcodeList: self.macros[nnames[0]] = inf else: ntokens = tokens[0].split(":") - if len(ntokens) == 2: - inf = Opcode(ntokens[1]) - if ntokens[0] == self.gen: - # Replace in list when already present, otherwise append - found = False - found_index = 0 - for i in range(len(self.opcode_info)): - if self.opcode_info[i].code == inf.code: - found = True - found_index = i - if found: - self.opcode_info[found_index] = inf - else: - self.opcode_info.append(inf) - else: - inf = Opcode(ntokens[0]) - if None == self.gen: - self.opcode_info.append(inf) - else: - # Only place in list when not already present - found = False - for i in range(len(self.opcode_info)): - if self.opcode_info[i].code == inf.code: - found = True - if not found: - self.opcode_info.append(inf) + gen = None if len(ntokens) == 1 else ntokens[0] + prefix = ntokens[0][:2] if len(ntokens) == 1 else ntokens[1][:2] + opcode = ntokens[0][2:] if len(ntokens) == 1 else ntokens[1][2:] + if self.opcode_info.get(prefix) is None: + self.opcode_info[prefix] = [] + opcodes = self.opcode_info[prefix] + if None == gen: + inf = Opcode(prefix, opcode) + opcodes.append(inf) + elif gen == self.gen: + # Replace for ext generator + found = False + found_index = 0 + for i in range(len(opcodes)): + if opcodes[i].code == opcode: + found = True + found_index = i + if found: + inf = Opcode(prefix, opcode) + opcodes[found_index] = inf + else: + sys.stderr.write("[%s] Cannot find opcode: %s%s\n" % (gen, prefix, opcode)) + sys.exit(1) + else: + inf = Opcode(prefix, '/dev/null') def pre_process(self, iline): out = [] @@ -220,39 +251,72 @@ class OpcodeList: out.append(iline.with_str(line)) return out + def switch_prefix(self, prefixes, reenter: bool, f): + prefix_switch = len(prefixes) > 1 + + if prefix_switch: + print("switch (u8(m_ref >> 16)) // prefix", file=f) + print("{", file=f) + + for prefix in prefixes: + is_rop = prefix == 'ff' + if prefix_switch: + print("case 0x%s:" % (prefix), file=f) + print("{", file=f) + if not is_rop: + print("\tswitch (u8(m_ref >> 8)) // opcode", file=f) + print("\t{", file=f) + for opc in self.opcode_info[prefix]: + # reenter loop only process steps > 0 + if not reenter or opc.with_steps(): + if not is_rop: + print("\tcase 0x%s:" % (opc.code), file=f) + opc.save_dasm(step_switch=reenter, f=f) + print("\t\tcontinue;", file=f) + print("", file=f) + if not is_rop: + print("\t}", file=f) + + if prefix_switch: + print("} break; // prefix: %s" % (prefix), file=f) + print("", file=f) + if prefix_switch: + print("} // switch prefix", file=f) + def save_exec(self, f): - prefix = None print("if (m_wait_state)", file=f) print("{", file=f) print("\tm_icount = 0; // stalled", file=f) print("\treturn;", file=f) print("}", file=f) - print("while (true) {", file=f) - print("switch (u8(m_ref >> 16)) // prefix", file=f) - print("{", file=f) - for opc in self.opcode_info: - if (opc.code[:2]) != prefix: - if prefix is not None: - print("\n\t}", file=f) - print("\t\tbreak;", file=f) - print("", file=f) - print("}", file=f) - print("break; // prefix: 0x%s" % (prefix), file=f) - print("", file=f) - prefix = opc.code[:2] - print("case 0x%s:" % (opc.code[:2]), file=f) - print("{", file=f) - print("\tswitch (u8(m_ref >> 8)) // opcode", file=f) - print("\t{", file=f) - print("\tcase 0x%s:" % (opc.code[2:]), file=f) - opc.save_dasm(f) - print("\t\tgoto rop;", file=f) - print("", file=f) - print("\t} // switch opcode", file=f) + print("", file=f) + print("const bool nomemrq_en = !m_nomreq_cb.isunset();", file=f) + print("[[maybe_unused]] const bool refresh_en = !m_refresh_cb.isunset();", file=f) + print("const bool busack_en = !m_busack_cb.isunset();", file=f) + print("", file=f) + print("bool interrupted = true;", file=f) + print("while (u8(m_ref) != 0x00) {", file=f) + print("\t// workaround to simulate main loop behavior where continue statement relays on having it set after", file=f) + print("\tif (!interrupted) {", file=f) + print("\t\tm_ref = 0xffff00;", file=f) + print("\t\tcontinue;", file=f) + print("\t}", file=f) + print("\tinterrupted = false;", file=f) + print("", file=f) + self.switch_prefix(self.opcode_info.keys(), reenter=True, f=f) + print("", file=f) + print('assert((void("switch statement above must cover all possible cases!"), false));', file=f) print("}", file=f) - print("break; // prefix: 0x%s" % (prefix), file=f) print("", file=f) - print("} // switch prefix", file=f) + print("if (m_ref != 0xffff00) goto process;", file=f) + print("", file=f) + print("while (true) {", file=f) + print("", file=f) + print("\t\t// unwrapped ff prefix", file=f) + self.switch_prefix(['ff'], reenter=False, f=f) + print("", file=f) + print("process:", file=f) + self.switch_prefix(self.opcode_info.keys() - ['ff'], reenter=False, f=f) print("", file=f) print("} // while (true)", file=f) |