Esempio n. 1
0
            private static void HandleGeneral(VR4300 cpu, SystemControlUnit.CauseRegister.ExceptionCode excCode, byte?ce = null)
            {
                cpu.CP0.Cause.ExcCode = excCode;

                if (ce.HasValue)
                {
                    cpu.CP0.Cause.CE = ce.Value;
                }

                cpu.CP0.Registers[(int)SystemControlUnit.RegisterIndex.BadVAddr] = cpu.PC;

                if (!cpu.CP0.Status.EXL)
                {
                    if ((cpu.CP0.Cause.BD = cpu.branchDelay))
                    {
                        cpu.CP0.Registers[(int)SystemControlUnit.RegisterIndex.EPC] = cpu.PC - Instruction.Size;
                    }
                    else
                    {
                        cpu.CP0.Registers[(int)SystemControlUnit.RegisterIndex.EPC] = cpu.PC;
                    }
                }

                cpu.CP0.Status.EXL = true;
                cpu.PC             = (cpu.CP0.Status.DS.BEV ? GeneralVectorBEV : GeneralVector) + GeneralVectorOffset;
            }
            public SystemControlUnit(VR4300 cpu)
            {
                this.cpu   = cpu;
                Config     = new ConfigRegister(this);
                Status     = new StatusRegister(this);
                Cause      = new CauseRegister(this);
                operations = new Dictionary <Instruction, Action <Instruction> >
                {
                    [From(OpCode.MT)] = i =>
                    {
                        var destination = i.RD;
                        var data        = cpu.GPR[i.RT];

                        switch ((RegisterIndex)destination)
                        {
                        case RegisterIndex.Cause:
                            Registers[destination] &= ~CauseRegister.WriteMask;
                            Registers[destination] |= data & CauseRegister.WriteMask;
                            return;

                        case RegisterIndex.Compare:
                            var ip = Cause.IP;
                            ip.TimerInterrupt = false;
                            Cause.IP          = ip;
                            break;
                        }

                        Registers[destination] = data;
                    },
                    [From(OpCode.MF)]         = i => cpu.GPR[i.RT] = (ulong)(int)Registers[i.RD],
                    [From(FunctOpCode.TLBWI)] = i => { /* TODO. */ },
                    [From(FunctOpCode.ERET)]  = i =>
                    {
                        if (Status.ERL)
                        {
                            cpu.PC     = Registers[(int)RegisterIndex.ErrorEPC];
                            Status.ERL = false;
                        }
                        else
                        {
                            cpu.PC     = Registers[(int)RegisterIndex.EPC];
                            Status.EXL = false;
                        }

                        cpu.LLBit     = false;
                        cpu.DelaySlot = null;
                    }
                };
            }
Esempio n. 3
0
            public FloatingPointUnit(VR4300 cpu)
            {
                this.cpu = cpu;
                ImplementationRevision = new ImplementationRevisionRegister(this);
                ControlStatus          = new ControlStatusRegister(this);
                operations             = new Dictionary <OpCode, Action <Instruction> >
                {
                    [OpCode.CF] = i =>
                    {
                        switch (i.RD)
                        {
                        case 0:
                            cpu.GPR[i.RT] = (ulong)(int)cpu.FCR0;
                            break;

                        case 31:
                            cpu.GPR[i.RT] = (ulong)(int)cpu.FCR31;
                            break;

                        default:
                            ExceptionProcessing.ReservedInstruction(cpu, i);
                            return;
                        }
                    },
                    [OpCode.CT] = i =>
                    {
                        switch (i.RD)
                        {
                        case 0:
                            return;     // Read-only register.

                        case 31:
                            cpu.FCR31 = (uint)cpu.GPR[i.RT];

                            if ((ControlStatus.Cause & (ControlStatus.Enables | ControlStatusRegister.ExceptionFlags.E)) != 0)
                            {
                                ExceptionProcessing.FloatingPoint(cpu);
                                return;
                            }
                            break;

                        default:
                            ExceptionProcessing.ReservedInstruction(cpu, i);
                            return;
                        }
                    }
                };
            }
Esempio n. 4
0
            public static void ColdReset(VR4300 cpu)
            {
                var ds = cpu.CP0.Status.DS;

                ds.TS             = ds.SR = cpu.CP0.Status.RP = false;
                cpu.CP0.Config.EP = 0;

                cpu.CP0.Status.ERL = ds.BEV = true;
                cpu.CP0.Config.BE  = (SystemControlUnit.ConfigRegister.Endianness) 1;

                cpu.CP0.Registers[(int)SystemControlUnit.RegisterIndex.Random] = 31;

                cpu.CP0.Config.EC = cpu.DivMode;

                cpu.CP0.Status.DS = ds;

                HandleReset(cpu);
            }
Esempio n. 5
0
 public static void FloatingPoint(VR4300 cpu) => HandleGeneral(cpu, SystemControlUnit.CauseRegister.ExceptionCode.FPE);
Esempio n. 6
0
 public static void CoprocessorUnusable(VR4300 cpu, byte unit) => HandleGeneral(cpu, SystemControlUnit.CauseRegister.ExceptionCode.CpU, unit);
Esempio n. 7
0
            public static void ReservedInstruction(VR4300 cpu, Instruction instruction)
            {
                HandleGeneral(cpu, SystemControlUnit.CauseRegister.ExceptionCode.RI);

                throw new UnimplementedOperationException(instruction); // TODO: Remove this and the parameter once every instruction gets implemented.
            }
Esempio n. 8
0
 public static void Interrupt(VR4300 cpu) => HandleGeneral(cpu, SystemControlUnit.CauseRegister.ExceptionCode.Int);
Esempio n. 9
0
 private static void HandleReset(VR4300 cpu)
 {
     cpu.CP0.Registers[(int)SystemControlUnit.RegisterIndex.ErrorEPC] = cpu.PC;
     cpu.PC = ResetVector;
 }