Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #5
0
        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));
        }
Beispiel #6
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));
        }
Beispiel #7
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);
        }
Beispiel #8
0
        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);
        }
Beispiel #12
0
        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);
        }
Beispiel #14
0
        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);
        }
Beispiel #16
0
        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);
        }
Beispiel #18
0
        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;
                }
            });
        }
Beispiel #19
0
        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);
        }
Beispiel #20
0
        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));
        }
Beispiel #21
0
        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));
        }
Beispiel #25
0
        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);
        }
Beispiel #27
0
        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));
        }