public void ADD_A_B_HandlesZeroFlag() { // --- Arrange var m = new Z80TestMachine(RunMode.UntilEnd); m.InitCode(new byte[] { 0x3E, 0x82, // LD A,82H 0x06, 0x7E, // LD B,7EH 0x80 // ADD A,B }); // --- Act m.Run(); // --- Assert var regs = m.Cpu.Registers; regs.A.ShouldBe((byte)0x0); regs.SFlag.ShouldBeFalse(); regs.ZFlag.ShouldBeTrue(); regs.HFlag.ShouldBeTrue(); regs.PFlag.ShouldBeFalse(); regs.CFlag.ShouldBeTrue(); regs.NFlag.ShouldBeFalse(); m.ShouldKeepRegisters(except: "AF, B"); m.ShouldKeepMemory(); regs.PC.ShouldBe((ushort)0x0005); m.Cpu.Tacts.ShouldBe(18L); }
public void LD_HLi_D_WorksAsExpected() { // --- Arrange var m = new Z80TestMachine(RunMode.UntilEnd); m.InitCode(new byte[] { 0x21, 0x00, 0x10, // LD HL,1000H 0x16, 0xB9, // LD D,B9H 0x72 // LD (HL),D }); // --- Act m.Run(); // --- Assert var regs = m.Cpu.Registers; m.Memory[0x1000].ShouldBe((byte)0xB9); m.ShouldKeepRegisters(except: "HL, D"); m.ShouldKeepMemory(except: "1000"); regs.PC.ShouldBe((ushort)0x0006); m.Cpu.Tacts.ShouldBe(24L); }
public void IndexModeIsResetAfterAnIndexedOperation() { // --- Arrange var m = new Z80TestMachine(RunMode.UntilEnd); m.InitCode(new byte[] { 0xDD, 0x21, 0x01, 0x11, // LD IX,1101H 0x21, 0x34, 0x12, // LD HL,1234H // === The issue makes the CPU behave as if these operations were // === executed: // === LD IX,1101H // === LD IX,1234H (and not LD HL,1234H) }); // --- Act m.Run(); // --- Assert var regs = m.Cpu.Registers; regs.IX.ShouldBe((ushort)0x1101); regs.HL.ShouldBe((ushort)0x1234); regs.CFlag.ShouldBeFalse(); regs.HFlag.ShouldBeFalse(); regs.NFlag.ShouldBeFalse(); m.ShouldKeepRegisters(except: "IX, HL"); m.ShouldKeepMemory(); }
public void NEXTREG_A_WorksAsExpected() { // --- Arrange var tbblue = new FakeTbBlueDevice(); var m = new Z80TestMachine(RunMode.UntilEnd, true, tbblue); m.InitCode(new byte[] { 0xED, 0x92, 0x07 // NEXTREG 0x07,A }); // --- Act var regs = m.Cpu.Registers; regs.A = 0x3D; m.Run(); // --- Assert tbblue.Register.ShouldBe((byte)0x07); tbblue.Value.ShouldBe((byte)0x3D); m.ShouldKeepRegisters(); m.ShouldKeepMemory(); regs.PC.ShouldBe((ushort)0x0003); m.Cpu.Tacts.ShouldBe(11L); }
public void LD_A_L_WorksAsExpected() { // --- Arrange var m = new Z80TestMachine(RunMode.UntilEnd); m.InitCode(new byte[] { 0x2E, 0xB9, // LD L,B9H 0x7D // LD A,L }); // --- Act m.Run(); // --- Assert var regs = m.Cpu.Registers; regs.A.ShouldBe((byte)0xB9); m.ShouldKeepRegisters(except: "A, L"); m.ShouldKeepMemory(); regs.PC.ShouldBe((ushort)0x0003); m.Cpu.Tacts.ShouldBe(11L); }
public void ADD_DE_A_WorksAsExpected(int de, int a, int result) { // --- Arrange var m = new Z80TestMachine(RunMode.OneInstruction, true); m.InitCode(new byte[] { 0xED, 0x32 // ADD DE,A }); var regs = m.Cpu.Registers; regs.DE = (ushort)de; regs.A = (byte)a; // --- Act m.Run(); // --- Assert regs.DE.ShouldBe((ushort)result); m.ShouldKeepRegisters(except: "DE"); m.ShouldKeepMemory(); regs.PC.ShouldBe((ushort)0x0002); m.Cpu.Tacts.ShouldBe(8L); }
public void OUTINB_WorksAsExpected() { // --- Arrange var m = new Z80TestMachine(RunMode.OneInstruction, true); m.InitCode(new byte[] { 0xED, 0x90 // OUTINB }); var regs = m.Cpu.Registers; regs.BC = 0x10CC; regs.HL = 0x1000; m.Memory[regs.HL] = 0x29; // --- Act m.Run(); // --- Assert regs.B.ShouldBe((byte)0x10); regs.C.ShouldBe((byte)0xCC); regs.HL.ShouldBe((ushort)0x1001); m.ShouldKeepRegisters(except: "HL"); m.ShouldKeepMemory(); m.IoAccessLog.Count.ShouldBe(1); m.IoAccessLog[0].Address.ShouldBe((ushort)0x10CC); m.IoAccessLog[0].Value.ShouldBe((byte)0x29); m.IoAccessLog[0].IsOutput.ShouldBeTrue(); regs.PC.ShouldBe((ushort)0x0002); m.Cpu.Tacts.ShouldBe(16L); }
public void SRL_A_WorksAsExpected() { // --- Arrange var m = new Z80TestMachine(RunMode.OneInstruction); m.InitCode(new byte[] { 0xCB, 0x3F // SRL A }); var regs = m.Cpu.Registers; regs.F |= FlagsSetMask.C; regs.A = 0x10; // --- Act m.Run(); // --- Assert regs.A.ShouldBe((byte)0x08); regs.SFlag.ShouldBeFalse(); regs.ZFlag.ShouldBeFalse(); regs.CFlag.ShouldBeFalse(); regs.PFlag.ShouldBeFalse(); regs.HFlag.ShouldBeFalse(); regs.NFlag.ShouldBeFalse(); m.ShouldKeepRegisters(except: "F, A"); m.ShouldKeepMemory(); regs.PC.ShouldBe((ushort)0x0002); m.Cpu.Tacts.ShouldBe(8L); }
public void SLL_B_SetsSign() { // --- Arrange var m = new Z80TestMachine(RunMode.OneInstruction); m.InitCode(new byte[] { 0xCB, 0x30 // SLL B }); var regs = m.Cpu.Registers; regs.B = 0x48; // --- Act m.Run(); // --- Assert regs.B.ShouldBe((byte)0x91); regs.SFlag.ShouldBeTrue(); regs.ZFlag.ShouldBeFalse(); regs.CFlag.ShouldBeFalse(); regs.PFlag.ShouldBeFalse(); regs.HFlag.ShouldBeFalse(); regs.NFlag.ShouldBeFalse(); m.ShouldKeepRegisters(except: "F, B"); m.ShouldKeepMemory(); regs.PC.ShouldBe((ushort)0x0002); m.Cpu.Tacts.ShouldBe(8L); }
public void SLL_E_WorksAsExpected() { // --- Arrange var m = new Z80TestMachine(RunMode.OneInstruction); m.InitCode(new byte[] { 0xCB, 0x33 // SLL E }); var regs = m.Cpu.Registers; regs.E = 0x08; // --- Act m.Run(); // --- Assert regs.E.ShouldBe((byte)0x11); regs.SFlag.ShouldBeFalse(); regs.ZFlag.ShouldBeFalse(); regs.CFlag.ShouldBeFalse(); regs.PFlag.ShouldBeTrue(); regs.HFlag.ShouldBeFalse(); regs.NFlag.ShouldBeFalse(); m.ShouldKeepRegisters(except: "F, E"); m.ShouldKeepMemory(); regs.PC.ShouldBe((ushort)0x0002); m.Cpu.Tacts.ShouldBe(8L); }
public void SLL_HLi_WorksAsExpected() { // --- Arrange var m = new Z80TestMachine(RunMode.OneInstruction); m.InitCode(new byte[] { 0xCB, 0x36 // SLL (HL) }); var regs = m.Cpu.Registers; regs.HL = 0x1000; m.Memory[regs.HL] = 0x08; // --- Act m.Run(); // --- Assert m.Memory[regs.HL].ShouldBe((byte)0x11); regs.SFlag.ShouldBeFalse(); regs.ZFlag.ShouldBeFalse(); regs.CFlag.ShouldBeFalse(); regs.PFlag.ShouldBeTrue(); regs.HFlag.ShouldBeFalse(); regs.NFlag.ShouldBeFalse(); m.ShouldKeepRegisters(except: "F"); m.ShouldKeepMemory(except: "1000"); regs.PC.ShouldBe((ushort)0x0002); m.Cpu.Tacts.ShouldBe(15L); }
public void BIT_N_C_WorksWithBitReset() { for (var n = 0; n < 8; n++) { // --- Arrange var m = new Z80TestMachine(RunMode.OneInstruction); var opcn = (byte)(0x41 | (n << 3)); m.InitCode(new byte[] { 0xCB, opcn // BIT N,C }); var regs = m.Cpu.Registers; regs.C = (byte)~(0x01 << n); // --- Act m.Run(); // --- Assert regs.SFlag.ShouldBeFalse(); regs.ZFlag.ShouldBeTrue(); regs.CFlag.ShouldBeFalse(); regs.PFlag.ShouldBeTrue(); regs.HFlag.ShouldBeTrue(); regs.NFlag.ShouldBeFalse(); m.ShouldKeepRegisters(except: "F"); m.ShouldKeepMemory(); regs.PC.ShouldBe((ushort)0x0002); m.Cpu.Tacts.ShouldBe(8L); } }
public void ADC_A_A_WithCarryWorksAsExpected() { // --- Arrange var m = new Z80TestMachine(RunMode.UntilEnd); m.InitCode(new byte[] { 0x3E, 0x12, // LD A,12H 0x37, // SCF 0x8F // ADC A,A }); // --- Act m.Run(); // --- Assert var regs = m.Cpu.Registers; regs.A.ShouldBe((byte)0x25); regs.SFlag.ShouldBeFalse(); regs.ZFlag.ShouldBeFalse(); regs.HFlag.ShouldBeFalse(); regs.PFlag.ShouldBeFalse(); regs.CFlag.ShouldBeFalse(); regs.NFlag.ShouldBeFalse(); m.ShouldKeepRegisters(except: "AF"); m.ShouldKeepMemory(); regs.PC.ShouldBe((ushort)0x0004); m.Cpu.Tacts.ShouldBe(15L); }
public void ADC_A_HLi_WorksAsExpected() { // --- Arrange var m = new Z80TestMachine(RunMode.UntilEnd); m.InitCode(new byte[] { 0x3E, 0x12, // LD A,12H 0x21, 0x00, 0x10, // LD HL,1000H 0x37, // SCF 0x8E // ADD A,(HL) }); m.Memory[0x1000] = 0x24; // --- Act m.Run(); // --- Assert var regs = m.Cpu.Registers; regs.A.ShouldBe((byte)0x37); regs.SFlag.ShouldBeFalse(); regs.ZFlag.ShouldBeFalse(); regs.HFlag.ShouldBeFalse(); regs.PFlag.ShouldBeFalse(); regs.CFlag.ShouldBeFalse(); regs.NFlag.ShouldBeFalse(); m.ShouldKeepRegisters(except: "AF, HL"); m.ShouldKeepMemory(except: "1000"); regs.PC.ShouldBe((ushort)0x0007); m.Cpu.Tacts.ShouldBe(28L); }
public void TEST_N_WorksAsExpected(int a, int n, int f) { // --- Arrange var m = new Z80TestMachine(RunMode.OneInstruction, true); m.InitCode(new byte[] { 0xED, 0x27, (byte)n // TEST N }); var regs = m.Cpu.Registers; regs.A = (byte)a; // --- Act m.Run(); // --- Assert regs.F.ShouldBe((byte)f); m.ShouldKeepRegisters(except: "F"); m.ShouldKeepMemory(); regs.PC.ShouldBe((ushort)0x0003); m.Cpu.Tacts.ShouldBe(11L); }
public void LD_NNi_HL_WorksAsExpected() { // --- Arrange var m = new Z80TestMachine(RunMode.UntilEnd); m.InitCode(new byte[] { 0x21, 0x26, 0xA9, // LD HL,A926H 0x22, 0x00, 0x10 // LD (1000H),HL }); // --- Act var lBefore = m.Memory[0x1000]; var hBefore = m.Memory[0x1001]; m.Run(); var lAfter = m.Memory[0x1000]; var hAfter = m.Memory[0x1001]; // --- Assert var regs = m.Cpu.Registers; m.ShouldKeepRegisters(except: "HL"); m.ShouldKeepMemory(except: "1000-1001"); regs.HL.ShouldBe((ushort)0xA926); lBefore.ShouldBe((byte)0x00); hBefore.ShouldBe((byte)0x00); lAfter.ShouldBe((byte)0x26); hAfter.ShouldBe((byte)0xA9); regs.PC.ShouldBe((ushort)0x0006); m.Cpu.Tacts.ShouldBe(26L); }
public void MUL_WorksAsExpected(int hl, int de, int resHl, int resDe) { // --- Arrange var m = new Z80TestMachine(RunMode.OneInstruction, true); m.InitCode(new byte[] { 0xED, 0x30 // MUL }); var regs = m.Cpu.Registers; regs.HL = (ushort)hl; regs.DE = (ushort)de; // --- Act m.Run(); // --- Assert regs.HL.ShouldBe((ushort)resHl); regs.DE.ShouldBe((ushort)resDe); m.ShouldKeepRegisters(except: "DE, HL"); m.ShouldKeepMemory(); regs.PC.ShouldBe((ushort)0x0002); m.Cpu.Tacts.ShouldBe(8L); }
public void INC_H_WorksAsExpected() { // --- Arrange var m = new Z80TestMachine(RunMode.UntilEnd); m.InitCode(new byte[] { 0x26, 0x43, // LD H,43H 0x24 // INC H }); // --- Act m.Run(); // --- Assert var regs = m.Cpu.Registers; m.ShouldKeepRegisters(except: "H, F"); m.ShouldKeepMemory(); m.ShouldKeepCFlag(); regs.NFlag.ShouldBeFalse(); regs.H.ShouldBe((byte)0x44); regs.PC.ShouldBe((ushort)0x0003); m.Cpu.Tacts.ShouldBe(11L); }
public void ADD_BC_NN_WorksAsExpected(int bc, int nn, int result) { // --- Arrange var m = new Z80TestMachine(RunMode.OneInstruction, true); m.InitCode(new byte[] { 0xED, 0x36, (byte)nn, (byte)(nn >> 8) // ADD BC,NN }); var regs = m.Cpu.Registers; regs.BC = (ushort)bc; // --- Act m.Run(); // --- Assert regs.BC.ShouldBe((ushort)result); m.ShouldKeepRegisters(except: "BC"); m.ShouldKeepMemory(); regs.PC.ShouldBe((ushort)0x0004); m.Cpu.Tacts.ShouldBe(16L); }
public void ADD_HL_HL_WorksAsExpected() { // --- Arrange var m = new Z80TestMachine(RunMode.UntilEnd); m.InitCode(new byte[] { 0x21, 0x34, 0x12, // LD HL,1234H 0x29 // ADD HL,HL }); // --- Act m.Run(); // --- Assert var regs = m.Cpu.Registers; m.ShouldKeepRegisters(except: "F, HL"); m.ShouldKeepMemory(); m.ShouldKeepSFlag(); m.ShouldKeepZFlag(); m.ShouldKeepPVFlag(); regs.NFlag.ShouldBeFalse(); regs.CFlag.ShouldBeFalse(); regs.HFlag.ShouldBeFalse(); regs.HL.ShouldBe((ushort)0x2468); regs.PC.ShouldBe((ushort)0x0004); m.Cpu.Tacts.ShouldBe(21L); }
public void MIRROR_A_WorksAsExpected(int initial, int result) { // --- Arrange var m = new Z80TestMachine(RunMode.OneInstruction, true); m.InitCode(new byte[] { 0xED, 0x24 // MIRROR A }); var regs = m.Cpu.Registers; regs.A = (byte)initial; // --- Act m.Run(); // --- Assert regs.A.ShouldBe((byte)result); m.ShouldKeepRegisters(except: "A"); m.ShouldKeepMemory(); regs.PC.ShouldBe((ushort)0x0002); m.Cpu.Tacts.ShouldBe(8L); }
public void LD_HL_NNi_WorksAsExpected() { // --- Arrange var m = new Z80TestMachine(RunMode.UntilEnd); m.InitCode(new byte[] { 0x2A, 0x00, 0x10 // LD HL,(1000H) }); m.Memory[0x1000] = 0x34; m.Memory[0x1001] = 0x12; // --- Act m.Run(); // --- Assert var regs = m.Cpu.Registers; m.ShouldKeepRegisters(except: "HL"); m.ShouldKeepMemory(); regs.HL.ShouldBe((ushort)0x1234); regs.PC.ShouldBe((ushort)0x0003); m.Cpu.Tacts.ShouldBe(16L); }
public void PIXELAD_WorksAsExpected(int row, int col, int addr) { // --- Arrange var m = new Z80TestMachine(RunMode.OneInstruction, true); m.InitCode(new byte[] { 0xED, 0x94 // PIXELAD }); var regs = m.Cpu.Registers; regs.D = (byte)row; regs.E = (byte)col; // --- Act m.Run(); // --- Assert regs.HL.ShouldBe((ushort)addr); m.ShouldKeepRegisters(except: "HL"); m.ShouldKeepMemory(); regs.PC.ShouldBe((ushort)0x0002); m.Cpu.Tacts.ShouldBe(8L); }
public void DEC_L_WorksAsExpected() { // --- Arrange var m = new Z80TestMachine(RunMode.UntilEnd); m.InitCode(new byte[] { 0x2E, 0x43, // LD L,43H 0x2D // DEC L }); // --- Act m.Run(); // --- Assert var regs = m.Cpu.Registers; m.ShouldKeepRegisters(except: "L, F"); m.ShouldKeepMemory(); m.ShouldKeepCFlag(); regs.NFlag.ShouldBeTrue(); regs.L.ShouldBe((byte)0x42); regs.PC.ShouldBe((ushort)0x0003); m.Cpu.Tacts.ShouldBe(11L); }
public void LD_A_HLi_WorksAsExpected() { // --- Arrange var m = new Z80TestMachine(RunMode.UntilEnd); m.InitCode(new byte[] { 0x21, 0x00, 0x10, // LD HL,1000H 0x7E // LD A,(HL) }); m.Memory[0x1000] = 0xB9; // --- Act m.Run(); // --- Assert var regs = m.Cpu.Registers; regs.A.ShouldBe((byte)0xB9); m.ShouldKeepRegisters(except: "A, HL"); m.ShouldKeepMemory(); regs.PC.ShouldBe((ushort)0x0004); m.Cpu.Tacts.ShouldBe(17L); }
public void CPL_WorksAsExpected() { // --- Arrange var m = new Z80TestMachine(RunMode.UntilEnd); m.InitCode(new byte[] { 0x3E, 0x81, // LD A,81H 0x2F // CPL }); // --- Act m.Run(); // --- Assert var regs = m.Cpu.Registers; m.ShouldKeepRegisters(except: "A, F"); m.ShouldKeepMemory(); m.ShouldKeepSFlag(); m.ShouldKeepZFlag(); m.ShouldKeepPVFlag(); m.ShouldKeepCFlag(); regs.HFlag.ShouldBeTrue(); regs.NFlag.ShouldBeTrue(); regs.A.ShouldBe((byte)0x7E); regs.PC.ShouldBe((ushort)0x0003); m.Cpu.Tacts.ShouldBe(11L); }
public void XRR_WorksAsExpected() { // --- Arrange const byte OFFS = 0x32; var m = new Z80TestMachine(RunMode.OneInstruction); m.InitCode(new byte[] { 0xFD, 0xCB, OFFS, 0x1E // RR (IY+32H) }); var regs = m.Cpu.Registers; regs.IY = 0x1000; regs.F |= FlagsSetMask.C; m.Memory[regs.IY + OFFS] = 0x08; // --- Act m.Run(); // --- Assert m.Memory[regs.IY + OFFS].ShouldBe((byte)0x84); regs.SFlag.ShouldBeTrue(); regs.ZFlag.ShouldBeFalse(); regs.CFlag.ShouldBeFalse(); regs.PFlag.ShouldBeTrue(); regs.HFlag.ShouldBeFalse(); regs.NFlag.ShouldBeFalse(); m.ShouldKeepRegisters(except: "F, A"); m.ShouldKeepMemory(except: "1032"); regs.PC.ShouldBe((ushort)0x0004); m.Cpu.Tacts.ShouldBe(23L); }
public void SETAE_WorksAsExpected(int a, int e, int resA) { // --- Arrange var m = new Z80TestMachine(RunMode.OneInstruction, true); m.InitCode(new byte[] { 0xED, 0x95 // SETAE }); var regs = m.Cpu.Registers; regs.A = (byte)a; regs.E = (byte)e; // --- Act m.Run(); // --- Assert regs.A.ShouldBe((byte)resA); m.ShouldKeepRegisters(except: "A"); m.ShouldKeepMemory(); regs.PC.ShouldBe((ushort)0x0002); m.Cpu.Tacts.ShouldBe(8L); }
public void RrcaDoesNotWorkProperlyWith18() { // --- Arrange var m = new Z80TestMachine(RunMode.UntilEnd); m.InitCode(new byte[] { 0x3E, 0x12, // LD A,12H 0x0F // RRCA }); // --- Act m.Run(); // --- Assert var regs = m.Cpu.Registers; regs.A.ShouldBe((byte)0x09); regs.CFlag.ShouldBeFalse(); regs.NFlag.ShouldBeFalse(); m.ShouldKeepRegisters(except: "AF"); m.ShouldKeepMemory(); }
public void ADC_A_B_WithCarryHandlesSignFlag() { // --- Arrange var m = new Z80TestMachine(RunMode.UntilEnd); m.InitCode(new byte[] { 0x3E, 0x44, // LD A,44H 0x06, 0x42, // LD B,42H 0x37, // SCF 0x88 // ADC A,B }); // --- Act m.Run(); // --- Assert var regs = m.Cpu.Registers; regs.A.ShouldBe((byte)0x87); regs.SFlag.ShouldBeTrue(); regs.ZFlag.ShouldBeFalse(); regs.HFlag.ShouldBeFalse(); regs.PFlag.ShouldBeTrue(); regs.CFlag.ShouldBeFalse(); regs.NFlag.ShouldBeFalse(); m.ShouldKeepRegisters(except: "AF, B"); m.ShouldKeepMemory(); regs.PC.ShouldBe((ushort)0x0006); m.Cpu.Tacts.ShouldBe(22L); }