public override void Initialize() { //Initialize Registers Registers = new Registers(this); //Initialize ALU ALU = new ArithmeticLogicUnit(this); //Initialize Interrupt Service InterruptService = new InterruptService(this); //Initialize Control Unit ControlUnit = new ControlUnit(this); /* * Interrupts should be served before fetching opcodes. So we check an interrupt here * before fetching the first opcode, as serving an interrupt in the loop before the fetch * would not allow us to break the debugger on interrupt vectors at 40h 48h 50h etc. */ InterruptService.InterruptServiceRoutine(); }
/// <summary> /// Fetches and Executes the opcode, PC is pointing at, serving interrupts or halting when needed. /// CPU also advances IPeripheral components when needed to reflect the timing of the physical chip. /// </summary> public override void FetchAndExecute() { //Advance the components in time (fetch takes 1 machine cycle) GetBoard().AdvanceSystemTime(); //4 //Halt will execute NOP. Essentially this is equivalent to just running the components at 4 clocks and returning if (!Halt) { //Fetch: Get the current opcode from memory byte Opcode = GetBoard().GetMemoryManagementUnit().Read(Registers.PC); //Execute: Call the Control Unit ControlUnit.Execute(Opcode); } /* * On Game Boy, Interrupts are served first, but since it's last on the loop, * this behaves as being first. For the first interrupt, we do an IR check in the Init() function */ InterruptService.InterruptServiceRoutine(); }
public override string ToString() { return(String.Format("PC:\t\t{0:X4}\nSP:\t\t{5:X4}\nAF:\t\t{1:X4}\nBC:\t\t{2:X4}\nDE:\t\t{3:X4}\nHL:\t\t{4:X4}\n{6}", Registers.PC, Registers.GetAF(), Registers.GetBC(), Registers.GetDE(), Registers.GetHL(), Registers.SP, InterruptService.ToString())); }