示例#1
0
        public void SetRegisterByName(string registerName, object value)
        {
            object boxed = (object)Registers;

            Registers.GetType().GetField(registerName).SetValue(boxed, value);
            Registers = (RegisterStruct)boxed;
        }
示例#2
0
        public int ExecuteInstruction()
        {
            if (SingleStep || Breakpoints.Contains(Registers.PC) || (HLBreak && Registers.HL != oldReg.HL && !IgnoreChangeAddrs.Contains(Registers.PC)))
            {
                if (Breakpoints.Contains(Registers.PC))
                {
                    Console.WriteLine($"Hit breakpoint at 0x{Registers.PC:x}");
                }

                if (Registers.HL != oldReg.HL)
                {
                    Console.WriteLine($"Written ${Registers.HL:X} to HL (was {oldReg.HL:X})");
                }

                SingleStep = true;
                bool waiting = true;
                while (waiting)
                {
                    ConsoleKeyInfo keyInfo           = Console.ReadKey();
                    int            currentLineCursor = Console.CursorTop;
                    Console.SetCursorPosition(0, Console.CursorTop);
                    Console.Write(new string(' ', 3));
                    Console.SetCursorPosition(0, currentLineCursor);
                    switch (keyInfo.KeyChar)
                    {
                    case 'a':
                    {
                        Console.Write("Addr> 0x");
                        string strAddr = Console.ReadLine();
                        try
                        {
                            ushort readAddr = Convert.ToUInt16(strAddr, 16);
                            {
                                byte bValue = Memory[readAddr];
                                Memory.Read(out ushort val, readAddr);
                                Console.WriteLine($"byte: 0x{bValue:X}\nushort: 0x{val:x}");
                            }
                        } catch { }
                        break;
                    }

                    case 'b':
                    {
                        Console.Write("Toggle breakpoint at> 0x");
                        string strAddr = Console.ReadLine();
                        try
                        {
                            ushort readAddr = Convert.ToUInt16(strAddr, 16);
                            {
                                if (Breakpoints.Contains(readAddr))
                                {
                                    Breakpoints.Remove(readAddr);
                                    Console.WriteLine($"Removed breakpoint at 0x{readAddr:x}");
                                }
                                else
                                {
                                    Breakpoints.Add(readAddr);
                                    Console.WriteLine($"Added breakpoint at 0x{readAddr:x}");
                                }
                            }
                        } catch { }
                        break;
                    }

                    case 'c':
                    {
                        SingleStep = false;
                        waiting    = false;
                        if (!IgnoreChangeAddrs.Contains(Registers.PC))
                        {
                            IgnoreChangeAddrs.Add(Registers.PC);
                        }
                        break;
                    }

                    case 'd':
                    {
                        Console.Write("Path for dump> ");
                        string path = Console.ReadLine();
                        using (System.IO.FileStream fs = System.IO.File.Create(path))
                        {
                            Memory.DumpMemory(fs);
                        }
                        break;
                    }

                    case 'n':
                    {
                        waiting = false;
                        break;
                    }

                    case 'i':
                    {
                        Console.WriteLine($"Regs: A:{Registers.A:X} B:{Registers.B:X} C:{Registers.C:X} D:{Registers.D:X} E:{Registers.E:X} F:{Registers.F:X} H:{Registers.H:X} L:{Registers.L:X}\nRegs: AF:{Registers.AF:X} BC:{Registers.BC:X} DE:{Registers.DE:X} HL:{Registers.HL:X}\nRegs: PC:{Registers.PC:X} SP:{Registers.SP:X}");
                        break;
                    }

                    case 'q':
                    {
                        System.Environment.Exit(1);
                        break;
                    }
                    }
                    SDL2.SDL.SDL_Delay(100);
                }
            }
            if (((IFVBlank && IEVBlank) || (IFLCDStat && IELCDStat) || (IFTimer && IETimer) || (IFSerial && IESerial) || (IFJoypad && IEJoypad)) && IME)
            {
                IME = false;
                this.StackPush(Registers.PC);

                ushort target = 0;

                if (IFJoypad && IEJoypad)
                {
                    target = 0x60;
                }

                if (IFSerial && IESerial)
                {
                    target = 0x58;
                }

                if (IFTimer && IETimer)
                {
                    target = 0x50;
                }

                if (IFLCDStat && IELCDStat)
                {
                    target = 0x48;
                }

                if (IFVBlank && IEVBlank)
                {
                    target = 0x40;
                }

                Console.WriteLine($"Executing Interrupt! Target: 0x{target:x}");
                Memory.Read(out Registers.PC, target);
                return(5 * 4);
            }
            else
            {
                oldReg = Registers;
                byte   opcodeRaw   = Memory[Registers.PC];
                ushort operandAddr = (ushort)(Registers.PC + 1);
                Memory.Read(out ushort maybeUshortArgLog, operandAddr);

                if (Opcodes.List.TryGetValue(opcodeRaw, out CurrentInst))
                {
                    Console.WriteLine($"0x{Registers.PC:x}: {CurrentInst.Mneumonic}".Replace("a8", $"a8<0x{Memory[operandAddr]:x}>").Replace("a16", $"a16<0x{maybeUshortArgLog:x}>").Replace("d8", $"d8<0x{Memory[operandAddr]:x}>").Replace("d16", $"d16<0x{maybeUshortArgLog:x}>"));
                    CurrentInst.Execute(this);
                    Registers.PC += CurrentInst.EffectiveLength;
                    return(CurrentInst.Cycles);
                }
                else
                {
                    Program.DumpStuffException();
                    throw new NotImplementedException($"OPCode 0x{opcodeRaw:X}");
                }
            }
        }