--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>\r
+<opcodes>\r
+<!--\r
+ Z80 Core Emulation\r
+ Copyright 2010, Michael McMaster <email@michaelmcmaster.name>\r
+-->\r
+\r
+<!--\r
+code gen expectations:\r
+masks result in each instruction being unrolled and the mask name being replaced\r
+with an actual register\r
+operand = op8();\r
+operand="UPPERCASE" is 16bit operand, in NATIVE(x86) byte order, but read in little-endian order from instruction pointer. N = op16(). ACTUALLY, NO. Return a struct DWORD, and enforce constraints!\r
+-->\r
+\r
+<registerMask name="r" bits="3">\r
+ <reg name="A" mask="111" />\r
+ <reg name="B" mask="000" />\r
+ <reg name="C" mask="001" />\r
+ <reg name="D" mask="010" />\r
+ <reg name="E" mask="011" />\r
+ <reg name="H" mask="100" />\r
+ <reg name="L" mask="101" />\r
+</registerMask>\r
+\r
+<registerMask name="d" alias="s" bits="2">\r
+ <reg name="BC" mask="00" />\r
+ <reg name="DE" mask="01" />\r
+ <reg name="HL" mask="10" />\r
+ <reg name="SP" mask="11" />\r
+</registerMask>\r
+\r
+<registerMask name="q" bits="2">\r
+ <reg name="BC" mask="00" />\r
+ <reg name="DE" mask="01" />\r
+ <reg name="HL" mask="10" />\r
+ <reg name="AF" mask="11" />\r
+</registerMask>\r
+\r
+<registerMask name="p" bits="2">\r
+ <reg name="BC" mask="00" />\r
+ <reg name="DE" mask="01" />\r
+ <reg name="IX" mask="10" />\r
+ <reg name="SP" mask="11" />\r
+</registerMask>\r
+\r
+<registerMask name="R" bits="2">\r
+ <reg name="BC" mask="00" />\r
+ <reg name="DE" mask="01" />\r
+ <reg name="IY" mask="10" />\r
+ <reg name="SP" mask="11" />\r
+</registerMask>\r
+\r
+<!--\r
+ 8-BIT LD Instructions\r
+-->\r
+\r
+<instruction name="LD r,r'" clock="4">\r
+<opcode mask="01rr" />\r
+r = r2;\r
+</instruction>\r
+\r
+<instruction name="LD r,n" clock="7">\r
+<opcode mask="00r110" operand="n"/>\r
+r = n;\r
+</instruction>\r
+\r
+<instruction name="LD r,(HL)" clock="7">\r
+<opcode mask="01r110" />\r
+r = m_mem.read8(m_reg.HL);\r
+</instruction>\r
+\r
+<instruction name="LD r,(IX+d)" clock="19">\r
+<opcode prefix="0xDD" mask="01r110" signed_operand="d"/>\r
+r = m_mem.read8(m_reg.IX, d);\r
+</instruction>\r
+\r
+<instruction name="LD r,(IY+d)" clock="19">\r
+<opcode prefix="0xFD" mask="01r110" signed_operand="d"/>\r
+r = m_mem.read8(m_reg.IY, d);\r
+</instruction>\r
+\r
+<instruction name="LD (HL),r" clock="7">\r
+<opcode mask="01110r"/>\r
+m_mem.write8(m_reg.HL, r);\r
+</instruction>\r
+\r
+<instruction name="LD (IX+d),r" clock="19">\r
+<opcode prefix="0xDD" mask="01110r" signed_operand="d"/>\r
+m_mem.write8(m_reg.IX, d, r);\r
+</instruction>\r
+\r
+<instruction name="LD (IY+d),r" clock="19">\r
+<opcode prefix="0xFD" mask="01110r" signed_operand="d"/>\r
+m_mem.write8(m_reg.IY, d, r);\r
+</instruction>\r
+\r
+<instruction name="LD (HL),n" clock="10">\r
+<opcode mask="00110110" operand="n"/>\r
+m_mem.write8(m_reg.HL, n);\r
+</instruction>\r
+\r
+<instruction name="LD (IX+d),r" clock="19">\r
+<opcode prefix="0xDD" mask="00110110" signed_operand="d" operand="n"/>\r
+m_mem.write8(m_reg.IX, d, n);\r
+</instruction>\r
+\r
+<instruction name="LD (IY+d),n" clock="19">\r
+<opcode prefix="0xFD" mask="00110110" signed_operand="d" operand="n"/>\r
+m_mem.write8(m_reg.IY, d, n);\r
+</instruction>\r
+\r
+<instruction name="LD A,(BC)" clock="7">\r
+<opcode mask="00001010"/>\r
+m_reg.A = m_mem.read8(m_reg.BC);\r
+</instruction>\r
+\r
+<instruction name="LD A,(DE)" clock="7">\r
+<opcode mask="00011010"/>\r
+m_reg.A = m_mem.read8(m_reg.DE);\r
+</instruction>\r
+\r
+<instruction name="LD A,(nn)" clock="13">\r
+<opcode mask="00111010" operand="N"/>\r
+m_reg.A = m_mem.read8(N);\r
+</instruction>\r
+\r
+<instruction name="LD (BC),A" clock="7">\r
+<opcode mask="00000010"/>\r
+m_mem.write8(m_reg.BC, m_reg.A);\r
+</instruction>\r
+\r
+<instruction name="LD (DE),A" clock="7">\r
+<opcode mask="00010010"/>\r
+m_mem.write8(m_reg.DE, m_reg.A);\r
+</instruction>\r
+\r
+<instruction name="LD (nn),A" clock="13">\r
+<opcode mask="00110010" operand="N"/>\r
+m_mem.write8(N, m_reg.A);\r
+</instruction>\r
+\r
+<instruction name="LD A,I" clock="9">\r
+<opcode prefix="0xED" mask="01010111"/>\r
+m_reg.F.set(m_reg.I, *this);\r
+m_reg.A = m_reg.I;\r
+</instruction>\r
+\r
+<instruction name="LD A,R" clock="9">\r
+<opcode prefix="0xED" mask="01011111"/>\r
+m_reg.F.set(m_reg.R, *this);\r
+m_reg.A = m_reg.R;\r
+</instruction>\r
+\r
+<instruction name="LD I,A" clock="9">\r
+<opcode prefix="0xED" mask="01000111"/>\r
+m_reg.I = m_reg.A;\r
+</instruction>\r
+\r
+<instruction name="LD R,A" clock="9">\r
+<opcode prefix="0xED" mask="01001111"/>\r
+m_reg.R = m_reg.A;\r
+</instruction>\r
+\r
+<!--\r
+ 16-BIT LD Instructions\r
+-->\r
+\r
+<instruction name="LD dd,nn" clock="10">\r
+<opcode mask="00d0001" operand="N" />\r
+d = N;\r
+</instruction>\r
+\r
+<instruction name="LD IX,nn" clock="14">\r
+<opcode prefix="0xDD" mask="00100001" operand="N" />\r
+m_reg.IX = N;\r
+</instruction>\r
+\r
+<instruction name="LD IY,nn" clock="14">\r
+<opcode prefix="0xFD" mask="00100001" operand="N" />\r
+m_reg.IY = N;\r
+</instruction>\r
+\r
+<instruction name="LD HL,(nn)" clock="16">\r
+<opcode mask="00101010" operand="N" />\r
+m_reg.HL = m_mem.read16(N);\r
+</instruction>\r
+\r
+<instruction name="LD dd,(nn)" clock="20">\r
+<opcode prefix="0xED" mask="01d1011" operand="N" />\r
+d = m_mem.read16(N);\r
+</instruction>\r
+\r
+<instruction name="LD IX,(nn)" clock="20">\r
+<opcode prefix="0xDD" mask="00101010" operand="N" />\r
+m_reg.IX = m_mem.read16(N);\r
+</instruction>\r
+\r
+<instruction name="LD IY,(nn)" clock="20">\r
+<opcode prefix="0xFD" mask="00101010" operand="N" />\r
+m_reg.IY = m_mem.read16(N);\r
+</instruction>\r
+\r
+<instruction name="LD (nn),HL" clock="16">\r
+<opcode mask="00100010" operand="N" />\r
+m_mem.write16(N, m_reg.HL);\r
+</instruction>\r
+\r
+<instruction name="LD (nn),dd" clock="20">\r
+<opcode prefix="0xED" mask="01d0011" operand="N" />\r
+m_mem.write16(N, d);\r
+</instruction>\r
+\r
+<instruction name="LD (nn),IX" clock="20">\r
+<opcode prefix="0xDD" mask="00100010" operand="N" />\r
+m_mem.write16(N, m_reg.IX);\r
+</instruction>\r
+\r
+<instruction name="LD (nn),IY" clock="20">\r
+<opcode prefix="0xFD" mask="00100010" operand="N" />\r
+m_mem.write16(N, m_reg.IY);\r
+</instruction>\r
+\r
+<instruction name="LD SP,HL" clock="6">\r
+<opcode mask="11111001" />\r
+m_reg.SP = m_reg.HL;\r
+</instruction>\r
+\r
+<instruction name="LD SP,IX" clock="10">\r
+<opcode prefix="0xDD" mask="11111001" />\r
+m_reg.SP = m_reg.IX;\r
+</instruction>\r
+\r
+<instruction name="LD SP,IY" clock="10">\r
+<opcode prefix="0xFD" mask="11111001" />\r
+m_reg.SP = m_reg.IY;\r
+</instruction>\r
+\r
+<instruction name="push qq" clock="11">\r
+<opcode mask="11q0101" />\r
+m_reg.SP.dec(2);\r
+m_mem.write16(m_reg.SP, q);\r
+</instruction>\r
+\r
+<instruction name="push IX" clock="15">\r
+<opcode prefix="0xDD" mask="11100101" />\r
+m_reg.SP.dec(2);\r
+m_mem.write16(m_reg.SP, m_reg.IX);\r
+</instruction>\r
+\r
+<instruction name="push IY" clock="15">\r
+<opcode prefix="0xFD" mask="11100101" />\r
+m_reg.SP.dec(2);\r
+m_mem.write16(m_reg.SP, m_reg.IY);\r
+</instruction>\r
+\r
+<instruction name="pop qq" clock="10">\r
+<opcode mask="11q0001" />\r
+q = m_mem.read16(m_reg.SP);\r
+m_reg.SP.inc(2);\r
+</instruction>\r
+\r
+<instruction name="pop IX" clock="14">\r
+<opcode prefix="0xDD" mask="11100001" />\r
+m_reg.IX = m_mem.read16(m_reg.SP);\r
+m_reg.SP.inc(2);\r
+</instruction>\r
+\r
+<instruction name="pop IY" clock="14">\r
+<opcode prefix="0xDD" mask="11111101" />\r
+m_reg.IY = m_mem.read16(m_reg.SP);\r
+m_reg.SP.inc(2);;\r
+</instruction>\r
+\r
+\r
+<!--\r
+ Exchange, block transfer, and search\r
+-->\r
+\r
+<instruction name="EX DE,HL" clock="4">\r
+<opcode mask="111010111" />\r
+ DWORD tmp(m_reg.DE);\r
+ m_reg.DE = m_reg.HL;\r
+ m_reg.HL = tmp;\r
+</instruction>\r
+\r
+<instruction name="EX AF,AF'" clock="4">\r
+<opcode mask="111010111" />\r
+ DWORD tmp(m_reg.AF);\r
+ m_reg.AF = m_regDash.AF;\r
+ m_regDash.AF = tmp;\r
+</instruction>\r
+\r
+<instruction name="EXX'" clock="4">\r
+<opcode mask="11011000" />\r
+ DWORD tmpBC(m_reg.BC);\r
+ DWORD tmpDE(m_reg.BC);\r
+ DWORD tmpHL(m_reg.BC);\r
+ m_reg.BC = m_regDash.BC;\r
+ m_reg.DE = m_regDash.DE;\r
+ m_reg.HL = m_regDash.HL;\r
+ m_regDash.BC = tmpBC;\r
+ m_regDash.DE = tmpDE;\r
+ m_regDash.HL = tmpHL;\r
+</instruction>\r
+\r
+<instruction name="EX (SP),HL'" clock="19">\r
+<opcode mask="11100011" />\r
+ DWORD tmp(m_reg.HL);\r
+ m_reg.HL = m_mem.read16(m_reg.SP);\r
+ m_mem.write16(m_reg.SP, tmp);\r
+</instruction>\r
+\r
+<instruction name="EX (SP),IX'" clock="23">\r
+<opcode prefix="0xDD" mask="11100011" />\r
+ DWORD tmp(m_reg.IX);\r
+ m_reg.IX = m_mem.read16(m_reg.SP);\r
+ m_mem.write16(m_reg.SP, tmp);\r
+</instruction>\r
+\r
+<instruction name="EX (SP),IY'" clock="23">\r
+<opcode prefix="0xFD" mask="11100011" />\r
+ DWORD tmp(m_reg.IY);\r
+ m_reg.IY = m_mem.read16(m_reg.SP);\r
+ m_mem.write16(m_reg.SP, tmp);\r
+</instruction>\r
+\r
+<instruction name="LDI'" clock="16">\r
+<opcode prefix="0xED" mask="10100000" />\r
+ m_mem.write8(m_reg.DE, m_mem.read8(m_reg.HL));\r
+ m_reg.DE.inc();\r
+ m_reg.HL.inc();\r
+ m_reg.BC.dec();\r
+ m_reg.F.setCounter(m_reg.BC);\r
+</instruction>\r
+\r
+<instruction name="LDIR'" clock="0">\r
+<opcode prefix="0xED" mask="10110000" />\r
+ do\r
+ {\r
+ m_mem.write8(m_reg.DE, m_mem.read8(m_reg.HL));\r
+ m_reg.DE.inc();\r
+ m_reg.HL.inc();\r
+ m_reg.BC.dec();\r
+\r
+ clock += 21; // Increment for each loop iteration\r
+ interrupt(); // Check for interrupts at each iteration\r
+ } while (m_reg.BC.host() != 0);\r
+ m_reg.F.setCounter(m_reg.BC);\r
+ clock += 16; // Increment again when leaving loop.\r
+</instruction>\r
+\r
+<instruction name="LDD'" clock="16">\r
+<opcode prefix="0xED" mask="10101000" />\r
+ m_mem.write8(m_reg.DE, m_mem.read8(m_reg.HL));\r
+ m_reg.DE.dec();\r
+ m_reg.HL.dec();\r
+ m_reg.BC.dec();\r
+ m_reg.F.setCounter(m_reg.BC);\r
+</instruction>\r
+\r
+<instruction name="LDDR'" clock="0">\r
+<opcode prefix="0xED" mask="10111000" />\r
+ do\r
+ {\r
+ m_mem.write8(m_reg.DE, m_mem.read8(m_reg.HL));\r
+ m_reg.DE.dec();\r
+ m_reg.HL.dec();\r
+ m_reg.BC.dec();\r
+\r
+ clock += 21; // Increment for each loop iteration\r
+ interrupt(); // Check for interrupts at each iteration\r
+ } while (m_reg.BC.host() != 0);\r
+ m_reg.F.setCounter(m_reg.BC);\r
+ clock += 16; // Increment again when leaving loop.\r
+</instruction>\r
+\r
+<instruction name="CPI'" clock="16">\r
+<opcode prefix="0xED" mask="10100000" />\r
+ m_reg.BC.dec();\r
+ m_reg.F.setSub(m_reg.A, m_reg.read8(r_reg.HL), m_reg.BC);\r
+ m_reg.HL.inc();\r
+</instruction>\r
+\r
+<instruction name="CPIR'" clock="0">\r
+<opcode prefix="0xED" mask="10110001" />\r
+ bool equal;\r
+ do\r
+ {\r
+ m_reg.BC.dec();\r
+ m_reg.F.setSub(m_reg.A, m_reg.read8(r_reg.HL), m_reg.BC);\r
+ equal = (m_reg.A == m_reg.read8(r_reg.HL));\r
+ m_reg.HL.inc();\r
+\r
+ clock += 21; // Increment for each loop iteration\r
+ interrupt(); // Check for interrupts at each iteration\r
+ } while (m_reg.BC.host() != 0 && !equal);\r
+ clock += 16; // Increment again when leaving loop.\r
+\r
+</instruction>\r
+\r
+<instruction name="CPD'" clock="16">\r
+<opcode prefix="0xED" mask="10101001" />\r
+ m_reg.BC.dec();\r
+ m_reg.F.setSub(m_reg.A, m_reg.read8(r_reg.HL), m_reg.BC);\r
+ m_reg.HL.dec();\r
+</instruction>\r
+\r
+<instruction name="CPDR'" clock="0">\r
+<opcode prefix="0xED" mask="10111001" />\r
+ bool equal;\r
+ do\r
+ {\r
+ m_reg.BC.dec();\r
+ m_reg.F.setSub(m_reg.A, m_reg.read8(r_reg.HL), m_reg.BC);\r
+ equal = (m_reg.A == m_reg.read8(r_reg.HL));\r
+ m_reg.HL.dec();\r
+\r
+ clock += 21; // Increment for each loop iteration\r
+ interrupt(); // Check for interrupts at each iteration\r
+ } while (m_reg.BC.host() != 0 && !equal);\r
+ clock += 16; // Increment again when leaving loop.\r
+\r
+</instruction>\r
+\r
+op8_t doAdd8(op8_t a, op8_t b, Flags& flags, bool carry)\r
+{\r
+ op8_t result(a + b);\r
+\r
+ if (carry && flags.C)\r
+ {\r
+ ++result;\r
+ }\r
+\r
+ flags.byte =\r
+ (result & 0x80) | // S MSB\r
+ ((result == 0) ? 0x40 : 0) | // Z\r
+ // U5 TODO\r
+ ((a ^ b ^ result) & 0x10) | // H\r
+ // U3 TODO\r
+\r
+ // If a and b have the same sign, and the result\r
+ // has a different sign, then we overflowed the\r
+ // register.\r
+ // Can never overflow if a and b have different signs. (even with\r
+ // carry, since 127 + -1 + carry == 127).\r
+ // Step 1) Determine whether a and b have the same sign. (a NXOR b)\r
+ // Step 2) Determine whether the result has // a different sign.\r
+ ((((~(a ^ b)) & (result ^ a)) & 0x80) >> 5) |// P\r
+\r
+ // N\r
+ (((op16_t(a) + op16_t(b)) & 0x100) >> 8) // C\r
+}\r
+<!--\r
+ 8-bit arithmetic\r
+-->\r
+<instruction name="ADD A,r'" clock="4">\r
+<opcode mask="100000r" />\r
+ m_reg.A = doAdd8(m_reg.A, r, m_reg.F, false);\r
+</instruction>\r
+\r
+<instruction name="ADD A,n'" clock="7">\r
+<opcode mask="11000110" operand="n" />\r
+ m_reg.A = doAdd8(m_reg.A, n, m_reg.F, false);\r
+</instruction>\r
+\r
+<instruction name="ADD A,(HL)'" clock="7">\r
+<opcode mask="11000110" />\r
+ m_reg.A = doAdd8(m_reg.A, m_mem.read8(m_reg.HL), m_reg.F, false);\r
+</instruction>\r
+\r
+<instruction name="ADD A,(IX+d)'" clock="19">\r
+<opcode prefix="0xDD" mask="11011101" signed_operand="d" />\r
+ m_reg.A = doAdd8(m_reg.A, m_mem.read8(m_reg.IX, d), m_reg.F, false);\r
+</instruction>\r
+\r
+<instruction name="ADD A,(IY+d)'" clock="19">\r
+<opcode prefix="0xFD" mask="10000110" signed_operand="d" />\r
+ m_reg.A = doAdd8(m_reg.A, m_mem.read8(m_reg.IY, d), m_reg.F, false);\r
+</instruction>\r
+\r
+<instruction name="ADC A,r'" clock="4">\r
+<opcode mask="10001r" />\r
+ m_reg.A = doAdc8(m_reg.A, r, m_reg.F, true);\r
+</instruction>\r
+\r
+</opcodes>\r
--- /dev/null
+/** \r
+ * Emulated representation of the Z80 CPU registers.\r
+ *\r
+ * The Z80 cpu supports switching between multiple register sets. Each Register\r
+ * object only stores the details of a single register set.\r
+*\r
+* 16bit Register Pairs are represented in a Struct to enable simple byte-order\r
+* conversions where required.\r
+ *\r
+ * Authors: Michael McMaster <email@michaelmcmaster.name>\r
+ * Copyright: Michael McMaster <email@michaelmcmaster.name>\r
+ */ \r
+#pragma once\r
+\r
+#include "mm80.hh"\r
+\r
+namespace mm80\r
+{\r
+\r
+class Core;\r
+\r
+/** 8-bit packed representation of the Z80 flags register.\r
+ *\r
+ * C Carry. LSB of Flag register\r
+ * N Add/Subtract\r
+ * P (V) Parity/Overflow\r
+ * U3 3rd bit of last 8bit op that altered flags\r
+ * H Half-Carry (BCD)\r
+ * U5 5th bit of last 8bit op that altered flags\r
+ * Z Zero Flag\r
+ * S Sign Flag. MSB of Flag register\r
+ */\r
+struct Flags\r
+{\r
+ union\r
+ {\r
+ struct\r
+ {\r
+ unsigned C:1; /// Carry. LSB of Flag register\r
+ unsigned N:1; /// Add/Subtract\r
+ unsigned P:1; /// (V) Parity/Overflow\r
+ unsigned U3:1; /// 3rd bit of last 8bit op that altered flags\r
+ unsigned H:1; /// Half-Carry (BCD)\r
+ unsigned U5:1; /// 5th bit of last 8bit op that altered flags\r
+ unsigned Z:1; /// Zero Flag\r
+ unsigned S:1; /// Sign Flag. MSB of Flag register\r
+ };\r
+ reg8_t byte;\r
+ };\r
+\r
+ Flags();\r
+\r
+ // Update the flags based on an operands value (eg. for simple assignment)\r
+ void set(op8_t operand, const Core& context);\r
+\r
+ // Update the flags when changing BC\r
+ void setCounter(op16_t BC);\r
+\r
+ // Set from A - B\r
+ void setSub(op8_t A, op8_t B, reg16_t BC);\r
+};\r
+\r
+struct DWORD\r
+{\r
+ // Always constructed, and stored, in Z80 byte order.\r
+ union\r
+ {\r
+ reg16_t dword;\r
+ struct\r
+ {\r
+ reg8_t l;\r
+ reg8_t h;\r
+ };\r
+ };\r
+\r
+ reg16_t z80() const { return dword; }\r
+ reg16_t host() const\r
+ {\r
+#ifdef HOST_LITTLE_ENDIAN\r
+ return dword;\r
+#else\r
+ return (reg16_t(h) << 8) | l;\r
+#endif\r
+ }\r
+\r
+ void inc(u8_t val = 1) const\r
+ {\r
+#ifdef HOST_LITTLE_ENDIAN\r
+ ++dword;\r
+#else\r
+ reg16_t tmp(host() + val);\r
+ l = tmp & 0xf;\r
+ h = tmp >> 8;\r
+#endif\r
+ }\r
+\r
+ void dec(u8_t val = 1) const\r
+ {\r
+#ifdef HOST_LITTLE_ENDIAN\r
+ --dword;\r
+#else\r
+ reg16_t tmp(host() - val);\r
+ l = tmp & 0xf;\r
+ h = tmp >> 8;\r
+#endif\r
+ }\r
+};\r
+\r
+// Create a dword from z80-ordered mem.\r
+static DWORD CreateDWORD(u8_t* in)\r
+{\r
+ DWORD result;\r
+ result.l = in[0];\r
+ result.h = in[1];\r
+ return result;\r
+}\r
+\r
+/** Z80 register access.\r
+ *\r
+ * Registers may be accessed in either 8-bit (eg. A) \r
+ * or by their 16-bit pair (eg. AF)\r
+ *\r
+ */\r
+struct Registers\r
+{\r
+ Registers();\r
+\r
+#define Z80_REG_STRUCT(h,l) \\r
+ struct \\r
+ { \\r
+ l; \\r
+ h; \\r
+ };\r
+#endif\r
+\r
+ // Note: The order of these unions/structs is important, as\r
+ // offsets are taken into the Register struct\r
+ reg8_t[0] begin8;\r
+ reg16_t[0] begin16;\r
+\r
+ union\r
+ {\r
+ Z80_REG_STRUCT(reg8_t B, reg8_t C);\r
+ DWORD BC;\r
+ };\r
+\r
+ union\r
+ {\r
+ Z80_REG_STRUCT(reg8_t D, reg8_t E);\r
+ DWORD DE;\r
+ };\r
+\r
+ union\r
+ {\r
+ Z80_REG_STRUCT(reg8_t H, reg8_t L);\r
+ DWORD HL;\r
+ };\r
+\r
+ union\r
+ {\r
+ Z80_REG_STRUCT(reg8_t A, Flags F,);\r
+ DWORD AF;\r
+ };\r
+\r
+\r
+#undef Z80_REG_STRUCT\r
+\r
+ // Special Purpose\r
+ reg8_t I; // Interrupt Vector\r
+ reg8_t R; // Memory Refresh\r
+ DWORD IX; // Index Register\r
+ DWORD IY; // Index Register\r
+ DWORD SP; // Stack Pointer\r
+ DWORD PC; // Program Counter\r
+};\r
+\r
+}\r
+\r