示例#1
0
        private void bit(IRegisterIndexed r, int shift)
        {
            bit(r.Value, shift);

            WZ.Value = r.OffsetAddress;
            F3       = WZ.Value.IsBitSet(11);
            F5       = WZ.Value.IsBitSet(13);
        }
示例#2
0
 private void srl(IRegisterIndexed r)
 {
     srl((IRegister <byte>)r);
     WZ.Value = r.OffsetAddress;
 }
示例#3
0
 private void cp(IRegisterIndexed r)
 {
     cp(r.Value);
     WZ.Value = r.OffsetAddress;
 }
示例#4
0
 private void xor(IRegisterIndexed r)
 {
     xor(r.Value);
     WZ.Value = r.OffsetAddress;
 }
示例#5
0
 private void and(IRegisterIndexed r)
 {
     and(r.Value);
     WZ.Value = r.OffsetAddress;
 }
示例#6
0
 private void sbc(IRegisterIndexed r)
 {
     sbc(r.Value);
     WZ.Value = r.OffsetAddress;
 }
示例#7
0
 private void res(IRegisterIndexed r, byte b)
 {
     r.Value &= NOT[b]; WZ.Value = r.OffsetAddress;
 }
示例#8
0
 private void set(IRegisterIndexed r, byte b)
 {
     r.Value |= BIT[b]; WZ.Value = r.OffsetAddress;
 }
示例#9
0
 private void load_ixy_nn(IRegisterIndexed r)
 {
     r.Value  = ByteAtPCPlusCoreOpCodeSizePlusOne;
     WZ.Value = r.OffsetAddress;
 }
示例#10
0
 private void load(IRegisterIndexed r1, IRegister <byte> r2)
 {
     r1.Value = r2.Value;
     WZ.Value = r1.OffsetAddress;
 }
示例#11
0
 private void load(IRegister <byte> r1, IRegisterIndexed r2)
 {
     load(r1, (IRegister <byte>)r2);
     WZ.Value = r2.OffsetAddress;
 }
示例#12
0
        private void SetupInstructionObjects()
        {
            IRegister <byte>[]   r8    = new IRegister <byte>[]   { B, C, D, E, H, L, HLM, A };
            IRegister <ushort>[] r16s  = new IRegister <ushort>[] { BC, DE, HL, SP };
            IRegister <ushort>[] r16a  = new IRegister <ushort>[] { BC, DE, HL, AF };
            IRegister <ushort>[] r16xs = new IRegister <ushort>[] { BC, DE, IX, SP };
            IRegister <ushort>[] r16ys = new IRegister <ushort>[] { BC, DE, IY, SP };
            IRegisterIndexed[]   rxyi  = new IRegisterIndexed[]  { IXM, IYM };
            IRegister <ushort>[] rxy   = new IRegister <ushort>[] { IX, IY };
            IRegister <byte>[]   r8x   = new IRegister <byte>[]   { B, C, D, E, IX.H, IX.L, null, A };
            IRegister <byte>[]   r8y   = new IRegister <byte>[]   { B, C, D, E, IY.H, IY.L, null, A };

            // prevent closure capture by using foreach instead of for
            byte[] iter8    = new byte[]    { 0, 1, 2, 3, 4, 5, 6, 7 };
            byte[] iter4    = new byte[]    { 0, 1, 2, 3 };
            byte[] iter2    = new byte[]    { 0, 1 };
            byte[] iter8alt = new byte[] { 0, 1, 2, 3, 4, 5, 7 }; // skips HLM entry

            byte HLMIndex = 6;
            byte opCode;
            byte tStates;

            InstructionSet.Add(new Instruction("ADC N", 7, adc_n, 0xCE));
            InstructionSet.Add(new Instruction("ADD N", 7, add_n, 0xC6));
            InstructionSet.Add(new Instruction("SUB N", 7, sub_n, 0xD6));
            InstructionSet.Add(new Instruction("SBC N", 7, sbc_n, 0xDE));
            InstructionSet.Add(new Instruction("AND N", 7, and_n, 0xE6));
            InstructionSet.Add(new Instruction("OR N", 7, or_n, 0xF6));
            InstructionSet.Add(new Instruction("XOR N", 7, xor_n, 0xEE));
            InstructionSet.Add(new Instruction("CP N", 7, cp_n, 0xFE));

            InstructionSet.Add(new Instruction("LDI", 16, ldi, 0xED, 0xA0));
            InstructionSet.Add(new Instruction("LDIR", 16, ldir, 0xED, 0xB0).WithTStatesAlt(5));
            InstructionSet.Add(new Instruction("LDD", 16, ldd, 0xED, 0xA8));
            InstructionSet.Add(new Instruction("LDDR", 16, lddr, 0xED, 0xB8).WithTStatesAlt(5));

            InstructionSet.Add(new Instruction("CPI", 16, cpi, 0xED, 0xA1));
            InstructionSet.Add(new Instruction("CPIR", 16, cpir, 0xED, 0xB1).WithTStatesAlt(5));
            InstructionSet.Add(new Instruction("CPD", 16, cpd, 0xED, 0xA9));
            InstructionSet.Add(new Instruction("CPDR", 16, cpdr, 0xED, 0xB9).WithTStatesAlt(5));

            InstructionSet.Add(new Instruction("NOP", 4, nop, 0x00));
            InstructionSet.Add(new Instruction("DAA", 4, daa, 0x27));
            InstructionSet.Add(new Instruction("CPL", 4, cpl, 0x2F));
            InstructionSet.Add(new Instruction("CCF", 4, ccf, 0x3F));
            InstructionSet.Add(new Instruction("SCF", 4, scf, 0x37));
            InstructionSet.Add(new Instruction("HALT", 6, halt, 0x76));

            InstructionSet.Add(new Instruction("DI", 4, di, 0xF3));
            InstructionSet.Add(new Instruction("EI", 4, ei, 0xFB));

            InstructionSet.Add(new Instruction("IM 0", 8, () => im(0), 0xED, 0x46));
            InstructionSet.Add(new Instruction("IM 1", 8, () => im(1), 0xED, 0x56));
            InstructionSet.Add(new Instruction("IM 2", 8, () => im(2), 0xED, 0x5E));

            InstructionSet.Add(new Instruction("RLCA", 4, rlca, 0x07));
            InstructionSet.Add(new Instruction("RLA", 4, rla, 0x17));
            InstructionSet.Add(new Instruction("RRCA", 4, rrca, 0x0F));
            InstructionSet.Add(new Instruction("RRA", 4, rra, 0x1F));

            InstructionSet.Add(new Instruction("RLD", 18, rld, 0xED, 0x6F));
            InstructionSet.Add(new Instruction("RRD", 18, rrd, 0xED, 0x67));

            InstructionSet.Add(new Instruction("IN A, (N)", 11, InPortN, 0xDB));
            InstructionSet.Add(new Instruction("IN (C)", 12, InPortZero, 0xED, 0x70));
            InstructionSet.Add(new Instruction("OUT (C), 0", 12, OutPortZero, 0xED, 0x71));

            foreach (var i in iter8)
            {
                tStates = (byte)(i == HLMIndex ? 7 : 4); // (HL) takes longer

                InstructionSet.Add(new Instruction($"ADD {r8[i].Name}", tStates, () => add(r8[i]), (byte)(0x80 + i)));
                InstructionSet.Add(new Instruction($"ADC {r8[i].Name}", tStates, () => adc(r8[i]), (byte)(0x88 + i)));
                InstructionSet.Add(new Instruction($"SUB {r8[i].Name}", tStates, () => sub(r8[i]), (byte)(0x90 + i)));
                InstructionSet.Add(new Instruction($"SBC {r8[i].Name}", tStates, () => sbc(r8[i]), (byte)(0x98 + i)));
                InstructionSet.Add(new Instruction($"AND {r8[i].Name}", tStates, () => and(r8[i]), (byte)(0xA0 + i)));
                InstructionSet.Add(new Instruction($"XOR {r8[i].Name}", tStates, () => xor(r8[i]), (byte)(0xA8 + i)));
                InstructionSet.Add(new Instruction($"OR {r8[i].Name}", tStates, () => or(r8[i]), (byte)(0xB0 + i)));
                InstructionSet.Add(new Instruction($"CP {r8[i].Name}", tStates, () => cp(r8[i]), (byte)(0xB8 + i)));

                tStates = (byte)(i == HLMIndex ? 11 : 4);

                InstructionSet.Add(new Instruction($"INC {r8[i].Name}", tStates, () => inc(r8[i]), (byte)(0x04 + i * 0x08)));
                InstructionSet.Add(new Instruction($"DEC {r8[i].Name}", tStates, () => dec(r8[i]), (byte)(0x05 + i * 0x08)));

                tStates = (byte)(i == HLMIndex ? 15 : 8);

                InstructionSet.Add(new Instruction($"RLC {r8[i].Name}", tStates, () => rlc(r8[i]), 0xCB, i));
                InstructionSet.Add(new Instruction($"RRC {r8[i].Name}", tStates, () => rrc(r8[i]), 0xCB, (byte)(i + 0x08)));
                InstructionSet.Add(new Instruction($"RL {r8[i].Name}", tStates, () => rl(r8[i]), 0xCB, (byte)(i + 0x10)));
                InstructionSet.Add(new Instruction($"RR {r8[i].Name}", tStates, () => rr(r8[i]), 0xCB, (byte)(i + 0x18)));
                InstructionSet.Add(new Instruction($"SLA {r8[i].Name}", tStates, () => sla(r8[i]), 0xCB, (byte)(i + 0x20)));
                InstructionSet.Add(new Instruction($"SRA {r8[i].Name}", tStates, () => sra(r8[i]), 0xCB, (byte)(i + 0x28)));
                InstructionSet.Add(new Instruction($"SLL {r8[i].Name}", tStates, () => sll(r8[i]), 0xCB, (byte)(i + 0x30)));
                InstructionSet.Add(new Instruction($"SRL {r8[i].Name}", tStates, () => srl(r8[i]), 0xCB, (byte)(i + 0x38)));

                tStates = (byte)(i == HLMIndex ? 10 : 7);

                InstructionSet.Add(new Instruction($"LD {r8[i].Name}, N", tStates, () => load_reg_nn(r8[i]), (byte)(i * 0x08 + 0x06)));

                if (i != HLMIndex)
                {
                    foreach (var j in iter2)
                    {
                        InstructionSet.Add(new Instruction($"LD {r8[i].Name}, ({rxyi[j].Proxy.Name}+d)", 19, () => load(r8[i], rxyi[j]), (byte)(0xDD + 0x20 * j), (byte)(0x46 + i * 0x08)));
                        InstructionSet.Add(new Instruction($"LD ({rxyi[j].Proxy.Name}+d), {r8[i].Name}", 19, () => load(rxyi[j], r8[i]), (byte)(0xDD + 0x20 * j), (byte)(0x70 + i)));

                        // COMPOUND INSTRUCTIONS (UNDOCUMENTED)
                        InstructionSet.Add(new Instruction($"RLC ({rxyi[j].Proxy.Name}+d), {r8[i].Name}", 23, () => rlc_compound(rxyi[j], r8[i]), (byte)(0xDD + 0x20 * j), 0xCB, i));
                        InstructionSet.Add(new Instruction($"RRC ({rxyi[j].Proxy.Name}+d), {r8[i].Name}", 23, () => rrc_compound(rxyi[j], r8[i]), (byte)(0xDD + 0x20 * j), 0xCB, (byte)(0x08 + i)));
                        InstructionSet.Add(new Instruction($"RL ({rxyi[j].Proxy.Name}+d), {r8[i].Name}", 23, () => rl_compound(rxyi[j], r8[i]), (byte)(0xDD + 0x20 * j), 0xCB, (byte)(0x10 + i)));
                        InstructionSet.Add(new Instruction($"RR ({rxyi[j].Proxy.Name}+d), {r8[i].Name}", 23, () => rr_compound(rxyi[j], r8[i]), (byte)(0xDD + 0x20 * j), 0xCB, (byte)(0x18 + i)));
                        InstructionSet.Add(new Instruction($"SLA ({rxyi[j].Proxy.Name}+d), {r8[i].Name}", 23, () => sla_compound(rxyi[j], r8[i]), (byte)(0xDD + 0x20 * j), 0xCB, (byte)(0x20 + i)));
                        InstructionSet.Add(new Instruction($"SRA ({rxyi[j].Proxy.Name}+d), {r8[i].Name}", 23, () => sra_compound(rxyi[j], r8[i]), (byte)(0xDD + 0x20 * j), 0xCB, (byte)(0x28 + i)));
                        InstructionSet.Add(new Instruction($"SLL ({rxyi[j].Proxy.Name}+d), {r8[i].Name}", 23, () => sll_compound(rxyi[j], r8[i]), (byte)(0xDD + 0x20 * j), 0xCB, (byte)(0x30 + i)));
                        InstructionSet.Add(new Instruction($"SRL ({rxyi[j].Proxy.Name}+d), {r8[i].Name}", 23, () => srl_compound(rxyi[j], r8[i]), (byte)(0xDD + 0x20 * j), 0xCB, (byte)(0x38 + i)));
                        foreach (var k in iter8)
                        {
                            InstructionSet.Add(new Instruction(string.Format("RES {0}, ({1}+d), {2}", k, rxyi[j].Proxy.Name, r8[i].Name), 23, () => res_compound(rxyi[j], r8[i], k), (byte)(0xDD + 0x20 * j), 0xCB, (byte)(0x80 + k * 0x08 + i)));
                            InstructionSet.Add(new Instruction(string.Format("SET {0}, ({1}+d), {2}", k, rxyi[j].Proxy.Name, r8[i].Name), 23, () => set_compound(rxyi[j], r8[i], k), (byte)(0xDD + 0x20 * j), 0xCB, (byte)(0xC0 + k * 0x08 + i)));
                        }
                    }
                    InstructionSet.Add(new Instruction($"LD {r8x[i].Name}, IXh", 8, () => load(r8x[i], IX.H), 0xDD, (byte)(0x44 + i * 0x08)));
                    InstructionSet.Add(new Instruction($"LD {r8x[i].Name}, IXl", 8, () => load(r8x[i], IX.L), 0xDD, (byte)(0x45 + i * 0x08)));

                    InstructionSet.Add(new Instruction($"LD {r8y[i].Name}, IYh", 8, () => load(r8y[i], IY.H), 0xFD, (byte)(0x44 + i * 0x08)));
                    InstructionSet.Add(new Instruction($"LD {r8y[i].Name}, IYl", 8, () => load(r8y[i], IY.L), 0xFD, (byte)(0x45 + i * 0x08)));

                    if (i <= 3 || i == 7) // r is B, C, D, E, or A
                    {
                        InstructionSet.Add(new Instruction($"LD IXh, {r8x[i].Name}", 8, () => load(IX.H, r8x[i]), 0xDD, (byte)(0x60 + i)));
                        InstructionSet.Add(new Instruction($"LD IXl, {r8x[i].Name}", 8, () => load(IX.L, r8x[i]), 0xDD, (byte)(0x68 + i)));

                        InstructionSet.Add(new Instruction($"LD IYh, {r8y[i].Name}", 8, () => load(IY.H, r8y[i]), 0xFD, (byte)(0x60 + i)));
                        InstructionSet.Add(new Instruction($"LD IYl, {r8y[i].Name}", 8, () => load(IY.L, r8y[i]), 0xFD, (byte)(0x68 + i)));
                    }

                    InstructionSet.Add(new Instruction($"IN {r8[i].Name}, (C)", 12, () => InPortR(r8[i]), 0xED, (byte)(0x40 + i * 0x08)));
                    InstructionSet.Add(new Instruction($"OUT (C), {r8[i].Name}", 12, () => OutPortR(r8[i]), 0xED, (byte)(0x41 + i * 0x08)));
                }

                foreach (var j in iter2)
                {
                    InstructionSet.Add(new Instruction($"SET {i}, ({rxyi[j].Proxy.Name}+d)", 23, () => set(rxyi[j], i), (byte)(0xDD + j * 0x20), 0xCB, (byte)(0xC6 + i * 0x08)));
                    InstructionSet.Add(new Instruction($"RES {i}, ({rxyi[j].Proxy.Name}+d)", 23, () => res(rxyi[j], i), (byte)(0xDD + j * 0x20), 0xCB, (byte)(0x86 + i * 0x08)));
                }

                foreach (var j in iter8)
                {
                    tStates = (byte)(i == HLMIndex || j == HLMIndex ? 7 : 4); // (HL) takes longer
                    opCode  = (byte)(0x40 + 0x08 * i + j);
                    if (opCode != 0x76)                                       // halt
                    {
                        InstructionSet.Add(new Instruction($"LD {r8[i].Name}, {r8[j].Name}", tStates, () => load(r8[i], r8[j]), opCode));
                    }

                    tStates = (byte)(i == HLMIndex ? 12 : 8);

                    InstructionSet.Add(new Instruction($"BIT {j}, {r8[i].Name}", tStates, i == HLMIndex ? new Action(() => bitHLM(j))
                                      : new Action(() => bit(r8[i], j)), 0xCB,
                                                       (byte)(0x40 + j * 0x08 + i)));

                    InstructionSet.Add(new Instruction($"SET {j}, {r8[i].Name}", tStates, () => set(r8[i], j), 0xCB, (byte)(0xC0 + j * 0x08 + i)));
                    InstructionSet.Add(new Instruction($"RES {j}, {r8[i].Name}", tStates, () => res(r8[i], j), 0xCB, (byte)(0x80 + j * 0x08 + i)));

                    foreach (var k in iter2)
                    {
                        // redundant opcodes
                        InstructionSet.Add(new Instruction($"BIT {i}, ({rxyi[k].Proxy.Name}+d)", 20, () => bit(rxyi[k], i), (byte)(0xDD + k * 0x20), 0xCB, (byte)(0x40 + i * 8 + j)));
                    }
                }
            }

            foreach (var i in iter4)
            {
                InstructionSet.Add(new Instruction(string.Format("LD {0}, NN", r16s[i].Name), 10, () => load_reg_nnnn(r16s[i]), (byte)(0x01 + i * 0x10)));
                InstructionSet.Add(new Instruction(string.Format("LD {0}, (NN)", r16s[i].Name), 20, () => load_xx_mmmm(r16s[i]), 0xED, (byte)(0x4B + i * 0x10)));
                InstructionSet.Add(new Instruction(string.Format("LD (NN), {0}", r16s[i].Name), 20, () => load_mmmm_xx(r16s[i]), 0xED, (byte)(0x43 + i * 0x10)));
                InstructionSet.Add(new Instruction(string.Format("INC {0}", r16s[i].Name), 6, () => inc(r16s[i]), (byte)(0x03 + i * 0x10)));
                InstructionSet.Add(new Instruction(string.Format("DEC {0}", r16s[i].Name), 6, () => dec(r16s[i]), (byte)(0x0B + i * 0x10)));
                InstructionSet.Add(new Instruction(string.Format("ADD HL, {0}", r16s[i].Name), 11, () => add(HL, r16s[i]), (byte)(0x09 + i * 0x10)));
                InstructionSet.Add(new Instruction(string.Format("SBC HL, {0}", r16s[i].Name), 15, () => sbc_hl(r16s[i]), 0xED, (byte)(0x42 + i * 0x10)));
                InstructionSet.Add(new Instruction(string.Format("ADC HL, {0}", r16s[i].Name), 15, () => adc_hl(r16s[i]), 0xED, (byte)(0x4A + i * 0x10)));

                InstructionSet.Add(new Instruction($"POP {r16a[i].Name}", 10, () => pop(r16a[i]), (byte)(0xC1 + i * 0x10)));
                InstructionSet.Add(new Instruction($"PUSH {r16a[i].Name}", 11, () => push(r16a[i]), (byte)(0xC5 + i * 0x10)));

                InstructionSet.Add(new Instruction($"ADD {IX.Name}, {r16xs[i].Name}", 15, () => add(IX, r16xs[i]), 0xDD, (byte)(0x09 + i * 0x10)));
                InstructionSet.Add(new Instruction($"ADD {IY.Name}, {r16ys[i].Name}", 15, () => add(IY, r16ys[i]), 0xFD, (byte)(0x09 + i * 0x10)));
            }
            foreach (var i in iter2)
            {
                InstructionSet.Add(new Instruction(string.Format("LD ({0}+d), N", rxyi[i].Proxy.Name), 10, () => load_ixy_nn(rxyi[i]), (byte)(0xDD + i * 0x20), 0x36));
                InstructionSet.Add(new Instruction(string.Format("LD {0}, NN", rxy[i].Name), 14, () => load_reg_nnnn(rxy[i]), (byte)(0xDD + i * 0x20), 0x21));
                InstructionSet.Add(new Instruction(string.Format("LD (NN), {0}", rxy[i].Name), 20, () => load_mmmm_ixy(rxy[i]), (byte)(0xDD + i * 0x20), 0x22));
                InstructionSet.Add(new Instruction(string.Format("LD {0}, (NN)", rxy[i].Name), 20, () => load_ixy_mmmm(rxy[i]), (byte)(0xDD + i * 0x20), 0x2A));
                InstructionSet.Add(new Instruction(string.Format("INC {0}", rxy[i].Name), 10, () => inc(rxy[i]), (byte)(0xDD + i * 0x20), 0x23));
                InstructionSet.Add(new Instruction(string.Format("DEC {0}", rxy[i].Name), 10, () => dec(rxy[i]), (byte)(0xDD + i * 0x20), 0x2B));
                InstructionSet.Add(new Instruction(string.Format("POP {0}", rxy[i].Name), 14, () => pop(rxy[i]), (byte)(0xDD + i * 0x20), 0xE1));
                InstructionSet.Add(new Instruction(string.Format("PUSH {0}", rxy[i].Name), 15, () => push(rxy[i]), (byte)(0xDD + i * 0x20), 0xE5));

                InstructionSet.Add(new Instruction(string.Format("INC ({0}+d)", rxyi[i].Proxy.Name), 23, () => inc(rxyi[i]), (byte)(0xDD + i * 0x20), 0x34));
                InstructionSet.Add(new Instruction(string.Format("DEC ({0}+d)", rxyi[i].Proxy.Name), 23, () => dec(rxyi[i]), (byte)(0xDD + i * 0x20), 0x35));

                InstructionSet.Add(new Instruction(string.Format("ADD ({0}+d)", rxyi[i].Proxy.Name), 19, () => add(rxyi[i]), (byte)(0xDD + i * 0x20), 0x86));
                InstructionSet.Add(new Instruction(string.Format("ADC ({0}+d)", rxyi[i].Proxy.Name), 19, () => adc(rxyi[i]), (byte)(0xDD + i * 0x20), 0x8E));
                InstructionSet.Add(new Instruction(string.Format("SUB ({0}+d)", rxyi[i].Proxy.Name), 19, () => sub(rxyi[i]), (byte)(0xDD + i * 0x20), 0x96));
                InstructionSet.Add(new Instruction(string.Format("SBC ({0}+d)", rxyi[i].Proxy.Name), 19, () => sbc(rxyi[i]), (byte)(0xDD + i * 0x20), 0x9E));

                InstructionSet.Add(new Instruction(string.Format("AND ({0}+d)", rxyi[i].Proxy.Name), 19, () => and(rxyi[i]), (byte)(0xDD + i * 0x20), 0xA6));
                InstructionSet.Add(new Instruction(string.Format("XOR ({0}+d)", rxyi[i].Proxy.Name), 19, () => xor(rxyi[i]), (byte)(0xDD + i * 0x20), 0xAE));
                InstructionSet.Add(new Instruction(string.Format("OR ({0}+d)", rxyi[i].Proxy.Name), 19, () => or(rxyi[i]), (byte)(0xDD + i * 0x20), 0xB6));
                InstructionSet.Add(new Instruction(string.Format("CP ({0}+d)", rxyi[i].Proxy.Name), 19, () => cp(rxyi[i]), (byte)(0xDD + i * 0x20), 0xBE));

                InstructionSet.Add(new Instruction(string.Format("RLC ({0}+d)", rxyi[i].Proxy.Name), 23, () => rlc(rxyi[i]), (byte)(0xDD + i * 0x20), 0xCB, 0x06));
                InstructionSet.Add(new Instruction(string.Format("RRC ({0}+d)", rxyi[i].Proxy.Name), 23, () => rrc(rxyi[i]), (byte)(0xDD + i * 0x20), 0xCB, 0x0E));
                InstructionSet.Add(new Instruction(string.Format("RL ({0}+d)", rxyi[i].Proxy.Name), 23, () => rl(rxyi[i]), (byte)(0xDD + i * 0x20), 0xCB, 0x16));
                InstructionSet.Add(new Instruction(string.Format("RR ({0}+d)", rxyi[i].Proxy.Name), 23, () => rr(rxyi[i]), (byte)(0xDD + i * 0x20), 0xCB, 0x1E));
                InstructionSet.Add(new Instruction(string.Format("SLA ({0}+d)", rxyi[i].Proxy.Name), 23, () => sla(rxyi[i]), (byte)(0xDD + i * 0x20), 0xCB, 0x26));
                InstructionSet.Add(new Instruction(string.Format("SRA ({0}+d)", rxyi[i].Proxy.Name), 23, () => sra(rxyi[i]), (byte)(0xDD + i * 0x20), 0xCB, 0x2E));
                InstructionSet.Add(new Instruction(string.Format("SLL ({0}+d)", rxyi[i].Proxy.Name), 23, () => sll(rxyi[i]), (byte)(0xDD + i * 0x20), 0xCB, 0x36));
                InstructionSet.Add(new Instruction(string.Format("SRL ({0}+d)", rxyi[i].Proxy.Name), 23, () => srl(rxyi[i]), (byte)(0xDD + i * 0x20), 0xCB, 0x3E));
            }

            InstructionSet.Add(new Instruction("LD A, (BC)", 7, () => load(A, BCM), 0x0A));
            InstructionSet.Add(new Instruction("LD A, (DE)", 7, () => load(A, DEM), 0x1A));
            InstructionSet.Add(new Instruction("LD A, (NN)", 13, load_a_mmmm, 0x3A));

            InstructionSet.Add(new Instruction("LD (BC), A", 7, () => load(BCM, A), 0x02));
            InstructionSet.Add(new Instruction("LD (DE), A", 7, () => load(DEM, A), 0x12));
            InstructionSet.Add(new Instruction("LD (NN), A", 13, load_mmmm_a, 0x32));

            InstructionSet.Add(new Instruction("LD A, I", 9, load_a_i, 0xED, 0x57));
            InstructionSet.Add(new Instruction("LD A, R", 9, load_a_r, 0xED, 0x5F));
            InstructionSet.Add(new Instruction("LD I, A", 9, () => load(I, A), 0xED, 0x47));
            InstructionSet.Add(new Instruction("LD R, A", 9, () => load(R, A), 0xED, 0x4F));

            InstructionSet.Add(new Instruction("LD HL, (NN)", 16, () => load_xx_mmmm(HL), 0x2A));
            InstructionSet.Add(new Instruction("LD (NN), HL", 16, () => load_mmmm_xx(HL), 0x22));

            InstructionSet.Add(new Instruction("LD SP, HL", 6, () => load(SP, HL), 0xF9));
            InstructionSet.Add(new Instruction("LD SP, IX", 10, () => load(SP, IX), 0xDD, 0xF9));
            InstructionSet.Add(new Instruction("LD SP, IY", 10, () => load(SP, IY), 0xFD, 0xF9));

            InstructionSet.Add(new Instruction("LD IXh, N", 11, () => load_reg_nn(IX.H), 0xDD, 0x26));
            InstructionSet.Add(new Instruction("LD IYh, N", 11, () => load_reg_nn(IY.H), 0xFD, 0x26));
            InstructionSet.Add(new Instruction("LD IXl, N", 11, () => load_reg_nn(IX.L), 0xDD, 0x2E));
            InstructionSet.Add(new Instruction("LD IYl, N", 11, () => load_reg_nn(IY.L), 0xFD, 0x2E));

            InstructionSet.Add(new Instruction("EXX", 4, exx, 0xD9));
            InstructionSet.Add(new Instruction("EX DE, HL", 4, () => ex(DE, HL), 0xEB));
            InstructionSet.Add(new Instruction("EX AF, AF'", 4, () => ex(AF, AFp), 0x08));
            InstructionSet.Add(new Instruction("EX (SP), HL", 19, () => ex_spm(HL), 0xE3));
            InstructionSet.Add(new Instruction("EX (SP), IX", 23, () => ex_spm(IX), 0xDD, 0xE3));
            InstructionSet.Add(new Instruction("EX (SP), IY", 23, () => ex_spm(IY), 0xFD, 0xE3));

            InstructionSet.Add(new Instruction("ADD IXh", 19, () => add(IX.H), 0xDD, 0x84));
            InstructionSet.Add(new Instruction("ADD IYh", 19, () => add(IY.H), 0xFD, 0x84));
            InstructionSet.Add(new Instruction("ADD IXl", 19, () => add(IX.L), 0xDD, 0x85));
            InstructionSet.Add(new Instruction("ADD IYl", 19, () => add(IY.L), 0xFD, 0x85));

            InstructionSet.Add(new Instruction("ADC IXh", 19, () => adc(IX.H), 0xDD, 0x8C));
            InstructionSet.Add(new Instruction("ADC IYh", 19, () => adc(IY.H), 0xFD, 0x8C));
            InstructionSet.Add(new Instruction("ADC IXl", 19, () => adc(IX.L), 0xDD, 0x8D));
            InstructionSet.Add(new Instruction("ADC IYl", 19, () => adc(IY.L), 0xFD, 0x8D));

            InstructionSet.Add(new Instruction("SUB IXh", 19, () => sub(IX.H), 0xDD, 0x94));
            InstructionSet.Add(new Instruction("SUB IYh", 19, () => sub(IY.H), 0xFD, 0x94));
            InstructionSet.Add(new Instruction("SUB IXl", 19, () => sub(IX.L), 0xDD, 0x95));
            InstructionSet.Add(new Instruction("SUB IYl", 19, () => sub(IY.L), 0xFD, 0x95));

            InstructionSet.Add(new Instruction("SBC IXh", 19, () => sbc(IX.H), 0xDD, 0x9C));
            InstructionSet.Add(new Instruction("SBC IYh", 19, () => sbc(IY.H), 0xFD, 0x9C));
            InstructionSet.Add(new Instruction("SBC IXl", 19, () => sbc(IX.L), 0xDD, 0x9D));
            InstructionSet.Add(new Instruction("SBC IYl", 19, () => sbc(IY.L), 0xFD, 0x9D));

            InstructionSet.Add(new Instruction("AND IXh", 19, () => and(IX.H), 0xDD, 0xA4));
            InstructionSet.Add(new Instruction("AND IYh", 19, () => and(IY.H), 0xFD, 0xA4));
            InstructionSet.Add(new Instruction("AND IXl", 19, () => and(IX.L), 0xDD, 0xA5));
            InstructionSet.Add(new Instruction("AND IYl", 19, () => and(IY.L), 0xFD, 0xA5));

            InstructionSet.Add(new Instruction("OR IXh", 19, () => or(IX.H), 0xDD, 0xB4));
            InstructionSet.Add(new Instruction("OR IYh", 19, () => or(IY.H), 0xFD, 0xB4));
            InstructionSet.Add(new Instruction("OR IXl", 19, () => or(IX.L), 0xDD, 0xB5));
            InstructionSet.Add(new Instruction("OR IYl", 19, () => or(IY.L), 0xFD, 0xB5));

            InstructionSet.Add(new Instruction("XOR IXh", 19, () => xor(IX.H), 0xDD, 0xAC));
            InstructionSet.Add(new Instruction("XOR IYh", 19, () => xor(IY.H), 0xFD, 0xAC));
            InstructionSet.Add(new Instruction("XOR IXl", 19, () => xor(IX.L), 0xDD, 0xAD));
            InstructionSet.Add(new Instruction("XOR IYl", 19, () => xor(IY.L), 0xFD, 0xAD));

            InstructionSet.Add(new Instruction("CP IXh", 19, () => cp(IX.H), 0xDD, 0xBC));
            InstructionSet.Add(new Instruction("CP IYh", 19, () => cp(IY.H), 0xFD, 0xBC));
            InstructionSet.Add(new Instruction("CP IXl", 19, () => cp(IX.L), 0xDD, 0xBD));
            InstructionSet.Add(new Instruction("CP IYl", 19, () => cp(IY.L), 0xFD, 0xBD));

            InstructionSet.Add(new Instruction("INC IXh", 8, () => inc(IX.H), 0xDD, 0x24));
            InstructionSet.Add(new Instruction("INC IYh", 8, () => inc(IY.H), 0xFD, 0x24));
            InstructionSet.Add(new Instruction("INC IXl", 8, () => inc(IX.L), 0xDD, 0x2C));
            InstructionSet.Add(new Instruction("INC IYl", 8, () => inc(IY.L), 0xFD, 0x2C));

            InstructionSet.Add(new Instruction("DEC IXh", 8, () => dec(IX.H), 0xDD, 0x25));
            InstructionSet.Add(new Instruction("DEC IYh", 8, () => dec(IY.H), 0xFD, 0x25));
            InstructionSet.Add(new Instruction("DEC IXl", 8, () => dec(IX.L), 0xDD, 0x2D));
            InstructionSet.Add(new Instruction("DEC IYl", 8, () => dec(IY.L), 0xFD, 0x2D));

            InstructionSet.Add(new Instruction("JP NN", 10, jp, 0xC3));

            InstructionSet.Add(new Instruction("JP NZ, NN", 10, () => jp(NZ), 0xC2 + 0x00));
            InstructionSet.Add(new Instruction("JP Z, NN", 10, () => jp(ZF), 0xC2 + 0x08));
            InstructionSet.Add(new Instruction("JP NC, NN", 10, () => jp(NC), 0xC2 + 0x10));
            InstructionSet.Add(new Instruction("JP C, NN", 10, () => jp(CF), 0xC2 + 0x18));
            InstructionSet.Add(new Instruction("JP PO, NN", 10, () => jp(PO), 0xC2 + 0x20));
            InstructionSet.Add(new Instruction("JP PE, NN", 10, () => jp(PE), 0xC2 + 0x28));
            InstructionSet.Add(new Instruction("JP P, NN", 10, () => jp(!SF), 0xC2 + 0x30));
            InstructionSet.Add(new Instruction("JP M, NN", 10, () => jp(SF), 0xC2 + 0x38));

            InstructionSet.Add(new Instruction("JP (HL)", 4, () => jp(HL), 0xE9));
            InstructionSet.Add(new Instruction("JP (IX)", 8, () => jp(IX), 0xDD, 0xE9));
            InstructionSet.Add(new Instruction("JP (IY)", 8, () => jp(IY), 0xFD, 0xE9));
            InstructionSet.Add(new Instruction("JR e", 12, jr, 0x18));
            InstructionSet.Add(new Instruction("JR NZ, e", 7, () => jr(NZ), 0x20).WithTStatesAlt(5));
            InstructionSet.Add(new Instruction("JR Z, e", 7, () => jr(ZF), 0x28).WithTStatesAlt(5));
            InstructionSet.Add(new Instruction("JR NC, e", 7, () => jr(NC), 0x30).WithTStatesAlt(5));
            InstructionSet.Add(new Instruction("JR C, e", 7, () => jr(CF), 0x38).WithTStatesAlt(5));

            InstructionSet.Add(new Instruction("DJNZ e", 8, djnz, 0x10).WithTStatesAlt(5));

            InstructionSet.Add(new Instruction("CALL NN", 17, () => call(), 0xCD));
            InstructionSet.Add(new Instruction("CALL NZ, NN", 10, () => call(NZ), 0xC4 + 0x00).WithTStatesAlt(7));
            InstructionSet.Add(new Instruction("CALL Z, NN", 10, () => call(ZF), 0xC4 + 0x08).WithTStatesAlt(7));
            InstructionSet.Add(new Instruction("CALL NC, NN", 10, () => call(NC), 0xC4 + 0x10).WithTStatesAlt(7));
            InstructionSet.Add(new Instruction("CALL C, NN", 10, () => call(CF), 0xC4 + 0x18).WithTStatesAlt(7));
            InstructionSet.Add(new Instruction("CALL PO, NN", 10, () => call(PO), 0xC4 + 0x20).WithTStatesAlt(7));
            InstructionSet.Add(new Instruction("CALL PE, NN", 10, () => call(PE), 0xC4 + 0x28).WithTStatesAlt(7));
            InstructionSet.Add(new Instruction("CALL P, NN", 10, () => call(!SF), 0xC4 + 0x30).WithTStatesAlt(7));
            InstructionSet.Add(new Instruction("CALL M, NN", 10, () => call(SF), 0xC4 + 0x38).WithTStatesAlt(7));

            InstructionSet.Add(new Instruction("RST 00", 11, () => rst(0x00), 0xC7));
            InstructionSet.Add(new Instruction("RST 08", 11, () => rst(0x08), 0xCF));
            InstructionSet.Add(new Instruction("RST 10", 11, () => rst(0x10), 0xD7));
            InstructionSet.Add(new Instruction("RST 18", 11, () => rst(0x18), 0xDF));
            InstructionSet.Add(new Instruction("RST 20", 11, () => rst(0x20), 0xE7));
            InstructionSet.Add(new Instruction("RST 28", 11, () => rst(0x28), 0xEF));
            InstructionSet.Add(new Instruction("RST 30", 11, () => rst(0x30), 0xF7));
            InstructionSet.Add(new Instruction("RST 38", 11, () => rst(0x38), 0xFF));

            InstructionSet.Add(new Instruction("RET", 10, () => ret(), 0xC9));
            InstructionSet.Add(new Instruction("RET NZ", 5, () => ret(NZ), 0xC0).WithTStatesAlt(6));
            InstructionSet.Add(new Instruction("RET Z", 5, () => ret(ZF), 0xC8).WithTStatesAlt(6));
            InstructionSet.Add(new Instruction("RET NC", 5, () => ret(NC), 0xD0).WithTStatesAlt(6));
            InstructionSet.Add(new Instruction("RET C", 5, () => ret(CF), 0xD8).WithTStatesAlt(6));
            InstructionSet.Add(new Instruction("RET PO", 5, () => ret(PO), 0xE0).WithTStatesAlt(6));
            InstructionSet.Add(new Instruction("RET PE", 5, () => ret(PE), 0xE8).WithTStatesAlt(6));
            InstructionSet.Add(new Instruction("RET P", 5, () => ret(!SF), 0xF0).WithTStatesAlt(6));
            InstructionSet.Add(new Instruction("RET M", 5, () => ret(SF), 0xF8).WithTStatesAlt(6));
            InstructionSet.Add(new Instruction("RETI", 14, retin, 0xED, 0x4D));
            InstructionSet.Add(new Instruction("RETN", 14, retin, 0xED, 0x45));

            InstructionSet.Add(new Instruction("INI", 16, ini, 0xED, 0xA2));
            InstructionSet.Add(new Instruction("INIR", 16, inir, 0xED, 0xB2).WithTStatesAlt(5));
            InstructionSet.Add(new Instruction("IND", 16, ind, 0xED, 0xAA));
            InstructionSet.Add(new Instruction("INDR", 16, indr, 0xED, 0xBA).WithTStatesAlt(5));
            InstructionSet.Add(new Instruction("OUT (N), A", 11, OutPortN, 0xD3));
            InstructionSet.Add(new Instruction("OUTI", 16, outi, 0xED, 0xA3));
            InstructionSet.Add(new Instruction("OTIR", 16, otir, 0xED, 0xB3).WithTStatesAlt(5));
            InstructionSet.Add(new Instruction("OUTD", 16, outd, 0xED, 0xAB));
            InstructionSet.Add(new Instruction("OTDR", 16, otdr, 0xED, 0xBB).WithTStatesAlt(5));

            InstructionSet.Add(new Instruction("NEG", 8, neg, 0xED, 0x44));
            InstructionSet.Add(new Instruction("NEG", 8, neg, 0xED, 0x4C));
            InstructionSet.Add(new Instruction("NEG", 8, neg, 0xED, 0x54));
            InstructionSet.Add(new Instruction("NEG", 8, neg, 0xED, 0x5C));
            InstructionSet.Add(new Instruction("NEG", 8, neg, 0xED, 0x64));
            InstructionSet.Add(new Instruction("NEG", 8, neg, 0xED, 0x6C));
            InstructionSet.Add(new Instruction("NEG", 8, neg, 0xED, 0x74));
            InstructionSet.Add(new Instruction("NEG", 8, neg, 0xED, 0x7C));

            InstructionSet.Add(new Instruction("RETN", 14, retin, 0xED, 0x55));
            InstructionSet.Add(new Instruction("RETN", 14, retin, 0xED, 0x5D));
            InstructionSet.Add(new Instruction("RETN", 14, retin, 0xED, 0x65));
            InstructionSet.Add(new Instruction("RETN", 14, retin, 0xED, 0x6D));
            InstructionSet.Add(new Instruction("RETN", 14, retin, 0xED, 0x75));
            InstructionSet.Add(new Instruction("RETN", 14, retin, 0xED, 0x7D));

            InstructionSet.Add(new Instruction("IM 0", 8, () => im(0), 0xED, 0x4E));
            InstructionSet.Add(new Instruction("IM 0", 8, () => im(0), 0xED, 0x66));
            InstructionSet.Add(new Instruction("IM 0", 8, () => im(0), 0xED, 0x6E));
            InstructionSet.Add(new Instruction("IM 1", 8, () => im(1), 0xED, 0x76));
            InstructionSet.Add(new Instruction("IM 2", 8, () => im(2), 0xED, 0x7E));
        }