public void BranchExchange_BranchToRegEight_PcCorrectAndInThumbMode() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentRegisterSet.GetRegister(8) = InternalWramRegion.REGION_START + 1; CpuUtil.RunCpu(cpu, new ushort[] { 0xc747 // BX r8 }); Assert.Equal(InternalWramRegion.REGION_START, cpu.CurrentRegisterSet.GetRegister(CpuUtil.PC)); Assert.Equal(InternalWramRegion.REGION_START + 1, cpu.CurrentRegisterSet.GetRegister(8)); Assert.True(cpu.CurrentStatus.Thumb); }
public void RaiseInterrupt_CpsrIrqFlagDisabled_InterruptNotHandled() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentStatus.IrqDisable = true; cpu.MemoryMap.WriteU32(0x4000208, 1); // IME = 1 cpu.MemoryMap.WriteU16(0x4000200, 1); // IE = VBlank IRQ enabled cpu.MemoryMap.FlushMmio(); cpu.RaiseInterrupt(InterruptType.VBlank); Assert.Equal(CpuMode.User, cpu.CurrentStatus.Mode); }
public void Move_MoveRegNineToRegEight_RegEightCorrect() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentRegisterSet.GetRegister(8) = 0xCAFEBABE; cpu.CurrentRegisterSet.GetRegister(9) = 0xDEADBEEF; CpuUtil.RunCpu(cpu, new ushort[] { 0xC846 // MOV r8, r9 }); Assert.Equal((uint)0xDEADBEEF, cpu.CurrentRegisterSet.GetRegister(8)); Assert.Equal((uint)0xDEADBEEF, cpu.CurrentRegisterSet.GetRegister(9)); }
public void ShiftedRegister_AsrRegOneWithResultInRegZero_RegZeroCorrect() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentRegisterSet.GetRegister(0) = 0xDEADBEEF; cpu.CurrentRegisterSet.GetRegister(1) = 0x801FF000; CpuUtil.RunCpu(cpu, new ushort[] { 0x4813 // ASR r0, r1, #8 }); Assert.Equal((uint)0xFFFC00FF, cpu.CurrentRegisterSet.GetRegister(0)); Assert.Equal((uint)0x801FF000, cpu.CurrentRegisterSet.GetRegister(1)); Assert.True(cpu.CurrentStatus.Carry); }
public void Mrs_MoveCpsrToRegZero_RegZeroCorrect() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentStatus.RegisterValue = (uint)0b11111000000000000000000011011111; cpu.CurrentRegisterSet.GetRegister(0) = 0xDEADBEEF; CpuUtil.RunCpu(cpu, new uint[] { 0xE10F0000 // MRS r0, CPSR }); Assert.Equal((uint)0b11111000000000000000000011011111, cpu.CurrentStatus.RegisterValue); Assert.Equal((uint)0b11111000000000000000000011011111, cpu.CurrentRegisterSet.GetRegister(0)); }
public void Msr_MoveRegZeroToSpsr_SpsrCorrect() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentStatus.Mode = CpuMode.System; cpu.CurrentRegisterSet.GetRegister(0) = 0b11111000000000000000000011000000; CpuUtil.RunCpu(cpu, new uint[] { 0xE169F000 // MSR SPSR, r0 }); Assert.Equal((uint)0b11111000000000000000000011000000, cpu.CurrentSavedStatus.RegisterValue); Assert.Equal((uint)0b11111000000000000000000011000000, cpu.CurrentRegisterSet.GetRegister(0)); }
public void BranchAndExchange_BranchToRegOneInThumb_PcCorrect() { const uint targetAddress = InternalWramRegion.REGION_START + 0x1000; AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentRegisterSet.GetRegister(1) = targetAddress + 1; CpuUtil.RunCpu(cpu, new uint[] { 0xE12FFF11 // BX r1 }); Assert.Equal(targetAddress, cpu.CurrentRegisterSet.GetRegister(CpuUtil.PC)); Assert.True(cpu.CurrentStatus.Thumb); }
public void Branch_BranchWithPsotiveOffsetAndCondition_PcCorrect(uint flags, uint opcode) { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentStatus.RegisterValue = (cpu.CurrentStatus.RegisterValue & 0x0FFFFFFF) | (flags << 28); const uint baseInstruction = 0xD07F; uint instruction = (opcode << 8) | baseInstruction; CpuUtil.RunCpu(cpu, new ushort[] { (ushort)instruction // B{cond} #0xFE }, true); Assert.Equal(InternalWramRegion.REGION_START + 0x4 + 0xFE, cpu.CurrentRegisterSet.GetRegister(CpuUtil.PC)); }
public void ShiftedRegister_LslRegOneWithResultInRegZero_RegZeroCorrect() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentRegisterSet.GetRegister(0) = 0xDEADBEEF; cpu.CurrentRegisterSet.GetRegister(1) = 0x000001FF; CpuUtil.RunCpu(cpu, new ushort[] { 0x0806 // LSL r0, r1, #24 }); Assert.Equal((uint)0xFF000000, cpu.CurrentRegisterSet.GetRegister(0)); Assert.Equal((uint)0x000001FF, cpu.CurrentRegisterSet.GetRegister(1)); Assert.True(cpu.CurrentStatus.Carry); }
public void GetRelativeAddress_LoadRegSevenWithSpRelativeAddress_RegSevenCorrect() { const uint targetAddress = InternalWramRegion.REGION_START + 0x3FC; AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentRegisterSet.GetRegister(7) = 0xDEADBEEF; cpu.CurrentRegisterSet.GetRegister(CpuUtil.SP) = InternalWramRegion.REGION_START; CpuUtil.RunCpu(cpu, new ushort[] { 0xAFFF // ADD r7, SP, #0x3FC }, true); Assert.Equal(targetAddress, cpu.CurrentRegisterSet.GetRegister(7)); }
public void UpdateKeyState_ChangeAStateToPressedWithLogicalOrInterrupts_CpuInterrupted() { AgbMemoryMap memoryMap = new AgbMemoryMap(); AgbCpu cpu = new AgbCpu(memoryMap); AgbController controller = new AgbController(memoryMap, cpu); memoryMap.WriteU32(0x4000208, 1); // IME = 1 memoryMap.WriteU16(0x4000200, 0x1000); // IE = Key memoryMap.WriteU16(0x4000132, 0x4003); // Key interrupts enabled, logical OR, A or B memoryMap.FlushMmio(); controller.UpdateKeyState(ControllerKey.A, true); Assert.Equal(CpuMode.Irq, cpu.CurrentStatus.Mode); }
public void Lsr_ShiftRegZeroRightByRegOne_RegZeroCorrect() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentRegisterSet.GetRegister(0) = 0xFF800000; cpu.CurrentRegisterSet.GetRegister(1) = 0xFEFEFE18; CpuUtil.RunCpu(cpu, new ushort[] { 0xc840 // LSR r0, r1 }); Assert.Equal((uint)0x000000FF, cpu.CurrentRegisterSet.GetRegister(0)); Assert.Equal((uint)0xFEFEFE18, cpu.CurrentRegisterSet.GetRegister(1)); Assert.True(cpu.CurrentStatus.Carry); }
public void UpdateKeyState_OnlyAPressedWithLogicalAndInterrupts_CpuNotInterrupted() { AgbMemoryMap memoryMap = new AgbMemoryMap(); AgbCpu cpu = new AgbCpu(memoryMap); AgbController controller = new AgbController(memoryMap, cpu); memoryMap.WriteU32(0x4000208, 1); // IME = 1 memoryMap.WriteU16(0x4000200, 0x1000); // IE = Key memoryMap.WriteU16(0x4000132, 0xC003); // Key interrupts enabled, logical AND, A and B memoryMap.FlushMmio(); controller.UpdateKeyState(ControllerKey.A, true); Assert.Equal(CpuMode.User, cpu.CurrentStatus.Mode); }
public void Move_MoveRegOneToRegZeroWithRor_RegZeroCorrectAndCarrySet() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentRegisterSet.GetRegister(0) = 0x0000FFFF; cpu.CurrentRegisterSet.GetRegister(1) = 0xFEFEFE08; CpuUtil.RunCpu(cpu, new ushort[] { 0xc841 // ROR r0, r1 }); Assert.Equal((uint)0xFF0000FF, cpu.CurrentRegisterSet.GetRegister(0)); Assert.Equal((uint)0xFEFEFE08, cpu.CurrentRegisterSet.GetRegister(1)); Assert.True(cpu.CurrentStatus.Carry); }
public void Move_MoveRegOneToRegZeroWithRorZeroImmediate_RegZeroCorrectAndCarrySet() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentRegisterSet.GetRegister(0) = 0xDEADBEEF; cpu.CurrentRegisterSet.GetRegister(1) = 0x0000FFFF; CpuUtil.RunCpu(cpu, new uint[] { 0xE1B00061 // MOVS r0, r1, ROR#0 }); Assert.Equal((uint)0x00007FFF, cpu.CurrentRegisterSet.GetRegister(0)); Assert.Equal((uint)0x0000FFFF, cpu.CurrentRegisterSet.GetRegister(1)); Assert.True(cpu.CurrentStatus.Carry); }
public void Asr_ArithmaticShiftRegZeroRightByRegOne_RegZeroCorrect() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentRegisterSet.GetRegister(0) = 0x801FF000; cpu.CurrentRegisterSet.GetRegister(1) = 0xFEFEFE0D; CpuUtil.RunCpu(cpu, new ushort[] { 0x0841 // ASR r0, r1 }); Assert.Equal((uint)0xFFFC00FF, cpu.CurrentRegisterSet.GetRegister(0)); Assert.Equal((uint)0xFEFEFE0D, cpu.CurrentRegisterSet.GetRegister(1)); Assert.True(cpu.CurrentStatus.Carry); }
public void Move_MoveRegOneToRegZeroWithAsr_RegZeroCorrectAndCarrySet() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentRegisterSet.GetRegister(0) = 0xDEADBEEF; cpu.CurrentRegisterSet.GetRegister(1) = 0x801FF000; CpuUtil.RunCpu(cpu, new uint[] { 0xE1B006C1 // MOVS r0, r1, ASR#13 }); Assert.Equal((uint)0xFFFC00FF, cpu.CurrentRegisterSet.GetRegister(0)); Assert.Equal((uint)0x801FF000, cpu.CurrentRegisterSet.GetRegister(1)); Assert.True(cpu.CurrentStatus.Carry); }
public AgbController(AgbMemoryMap memoryMap, AgbCpu cpu) { Cpu = cpu; PressedKeys = 0x3FF; // all released InterruptBitfield = 0; // all ignore InterruptCondition = 0; // disabled InterruptCondition = ControllerInterruptCondition.LogicalOr; memoryMap.RegisterMmio16(0x4000130, () => { return((ushort)PressedKeys); }, (x) => { // Reads ignored }); memoryMap.RegisterMmio16(0x4000132, () => { ushort x = (ushort)InterruptBitfield; if (InterruptsEnabled) { BitUtil.SetBit(ref x, 14); } if (InterruptCondition == ControllerInterruptCondition.LogicalAnd) { BitUtil.SetBit(ref x, 15); } return(x); }, (x) => { InterruptBitfield = (uint)(x & 0x3ff); InterruptsEnabled = BitUtil.IsBitSet(x, 14); if (BitUtil.IsBitSet(x, 15)) { InterruptCondition = ControllerInterruptCondition.LogicalAnd; } else { InterruptCondition = ControllerInterruptCondition.LogicalOr; } }); }
public void Tst_AndRegOneAndRegTwo_FlagsCorrect() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentRegisterSet.GetRegister(0) = 0xCAFEBABE; cpu.CurrentRegisterSet.GetRegister(1) = 0xFFFF0000; CpuUtil.RunCpu(cpu, new ushort[] { 0x0842 // TST r0, r1 }); Assert.Equal(0xCAFEBABE, cpu.CurrentRegisterSet.GetRegister(0)); Assert.Equal(0xFFFF0000, cpu.CurrentRegisterSet.GetRegister(1)); Assert.False(cpu.CurrentStatus.Zero); Assert.True(cpu.CurrentStatus.Negative); }
public void SubtractCarry_RegOneFromRegZeroWithCarry_RegZeroCorrect() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentStatus.Carry = false; cpu.CurrentRegisterSet.GetRegister(0) = 0x0000F000; cpu.CurrentRegisterSet.GetRegister(1) = 0x00001000; CpuUtil.RunCpu(cpu, new ushort[] { 0x8841 // SBC r0, r1 }); Assert.Equal((uint)0x0000DFFF, cpu.CurrentRegisterSet.GetRegister(0)); Assert.Equal((uint)0x00001000, cpu.CurrentRegisterSet.GetRegister(1)); }
public void AddCarry_RegOneAndRegZeroWithCarry_RegZeroCorrect() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentStatus.Carry = true; cpu.CurrentRegisterSet.GetRegister(0) = 0x0000F000; cpu.CurrentRegisterSet.GetRegister(1) = 0x00001000; CpuUtil.RunCpu(cpu, new ushort[] { 0x4841 // ADC r0, r1 }); Assert.Equal((uint)0x00010001, cpu.CurrentRegisterSet.GetRegister(0)); Assert.Equal((uint)0x00001000, cpu.CurrentRegisterSet.GetRegister(1)); }
public void SubtractReverse_RegTwoFromRegOne_RegZeroCorrect() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentRegisterSet.GetRegister(0) = 0xDEADBEEF; cpu.CurrentRegisterSet.GetRegister(1) = 0x00001000; cpu.CurrentRegisterSet.GetRegister(2) = 0x0000F000; CpuUtil.RunCpu(cpu, new uint[] { 0xE0610002 // RSB r0, r1, r2 }); Assert.Equal((uint)0x0000E000, cpu.CurrentRegisterSet.GetRegister(0)); Assert.Equal((uint)0x00001000, cpu.CurrentRegisterSet.GetRegister(1)); Assert.Equal((uint)0x0000F000, cpu.CurrentRegisterSet.GetRegister(2)); }
public void StoreHalf_UsingAddressInRegOne_StoreSuccess() { const uint targetAddress = InternalWramRegion.REGION_START + 0x1000; AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentRegisterSet.GetRegister(0) = 0xFFFFCAFE; cpu.CurrentRegisterSet.GetRegister(1) = targetAddress; CpuUtil.RunCpu(cpu, new uint[] { 0xB000C1E1 // STRH r0, [r1] }, true); Assert.Equal((uint)0x0000CAFE, cpu.MemoryMap.ReadU16(targetAddress)); Assert.Equal(targetAddress, cpu.CurrentRegisterSet.GetRegister(1)); }
public void Add_RegTwoAndRegOne_RegZeroCorrect() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentRegisterSet.GetRegister(0) = 0xDEADBEEF; cpu.CurrentRegisterSet.GetRegister(1) = 0x0000F000; cpu.CurrentRegisterSet.GetRegister(2) = 0x00001000; CpuUtil.RunCpu(cpu, new ushort[] { 0x8818 // ADD r0, r1, r2 }); Assert.Equal((uint)0x00010000, cpu.CurrentRegisterSet.GetRegister(0)); Assert.Equal((uint)0x0000F000, cpu.CurrentRegisterSet.GetRegister(1)); Assert.Equal((uint)0x00001000, cpu.CurrentRegisterSet.GetRegister(2)); }
public void StoreByte_UsingAddressInRegOneAndImmediateOffset_StoreSuccess() { const uint targetAddress = InternalWramRegion.REGION_START + 0x1F; AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentRegisterSet.GetRegister(0) = 0xFEFEFEAA; cpu.CurrentRegisterSet.GetRegister(1) = InternalWramRegion.REGION_START; CpuUtil.RunCpu(cpu, new ushort[] { 0x77c8 // STRB r0, [r1, #0x1F] }, true); Assert.Equal(0xAA, cpu.MemoryMap.Read(targetAddress)); Assert.Equal(InternalWramRegion.REGION_START, cpu.CurrentRegisterSet.GetRegister(1)); }
public void Tst_AndRegOneAndZeroImmediate_FlagsCorrect() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentRegisterSet.GetRegister(0) = 0xDEADBEEF; cpu.CurrentRegisterSet.GetRegister(1) = 0xCAFEBABE; CpuUtil.RunCpu(cpu, new uint[] { 0xE3110000 // TST r1, #0x0 }); Assert.Equal(0xDEADBEEF, cpu.CurrentRegisterSet.GetRegister(0)); Assert.Equal(0xCAFEBABE, cpu.CurrentRegisterSet.GetRegister(1)); Assert.True(cpu.CurrentStatus.Zero); Assert.False(cpu.CurrentStatus.Negative); }
public void Compare_SubtractImmediateFromRegZero_RegZeroUntouchedAndFlagsCorrect() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentRegisterSet.GetRegister(0) = 0xDEADBEEF; CpuUtil.RunCpu(cpu, new ushort[] { 0xff28 // CMP r0, #0xff }); Assert.Equal((uint)0xDEADBEEF, cpu.CurrentRegisterSet.GetRegister(0)); Assert.True(cpu.CurrentStatus.Negative); Assert.False(cpu.CurrentStatus.Zero); Assert.True(cpu.CurrentStatus.Carry); Assert.False(cpu.CurrentStatus.Overflow); }
public void Orr_OrRegOneAndRegTwo_RegZeroCorrect() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentRegisterSet.GetRegister(0) = 0xDEADBEEF; cpu.CurrentRegisterSet.GetRegister(1) = 0xCAFE0000; cpu.CurrentRegisterSet.GetRegister(2) = 0x0000BABE; CpuUtil.RunCpu(cpu, new uint[] { 0xE0810002 // AND r0, r1, r2 }); Assert.Equal((uint)0xCAFEBABE, cpu.CurrentRegisterSet.GetRegister(0)); Assert.Equal((uint)0xCAFE0000, cpu.CurrentRegisterSet.GetRegister(1)); Assert.Equal((uint)0x0000BABE, cpu.CurrentRegisterSet.GetRegister(2)); }
public void BitClear_BicWithRegOneAndRegTwo_RegZeroCorrect() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentRegisterSet.GetRegister(0) = 0xDEADBEEF; cpu.CurrentRegisterSet.GetRegister(1) = 0x000000FF; cpu.CurrentRegisterSet.GetRegister(2) = 0xFFFFFF00; CpuUtil.RunCpu(cpu, new uint[] { 0xE1C10002 // BIC r0, r1, r2 }); Assert.Equal((uint)0x000000FF, cpu.CurrentRegisterSet.GetRegister(0)); Assert.Equal((uint)0x000000FF, cpu.CurrentRegisterSet.GetRegister(1)); Assert.Equal((uint)0xFFFFFF00, cpu.CurrentRegisterSet.GetRegister(2)); }
public void Eor_RegOneWithRegTwo_RegZeroCorrect() { AgbCpu cpu = CpuUtil.CreateCpu(); cpu.CurrentRegisterSet.GetRegister(0) = 0xFEEDFACE; cpu.CurrentRegisterSet.GetRegister(1) = 0xCAFEBABE; cpu.CurrentRegisterSet.GetRegister(2) = 0xDEADBEEF; CpuUtil.RunCpu(cpu, new uint[] { 0xE0210002 // EOR r0, r1, r2 }); Assert.Equal((uint)0x14530451, cpu.CurrentRegisterSet.GetRegister(0)); Assert.Equal((uint)0xCAFEBABE, cpu.CurrentRegisterSet.GetRegister(1)); Assert.Equal((uint)0xDEADBEEF, cpu.CurrentRegisterSet.GetRegister(2)); }