GameBoy\Core::updateCore PHP Метод

updateCore() публичный Метод

public updateCore ( )
    public function updateCore()
    {
        // DIV control
        $this->DIVTicks += $this->CPUTicks;
        if ($this->DIVTicks >= 0x40) {
            $this->DIVTicks -= 0x40;
            $this->memory[0xff04] = $this->memory[0xff04] + 1 & 0xff;
            // inc DIV
        }
        //LCD Controller Ticks
        $timedTicks = $this->CPUTicks / $this->multiplier;
        // LCD Timing
        $this->LCDTicks += $timedTicks;
        //LCD timing
        $this->lcdController->scanLine($this->lcdController->actualScanLine);
        //Scan Line and STAT Mode Control
        //Audio Timing
        $this->audioTicks += $timedTicks;
        //Not the same as the LCD timing (Cannot be altered by display on/off changes!!!).
        //Are we past the granularity setting?
        if ($this->audioTicks >= Settings::$audioGranularity) {
            //Emulator Timing (Timed against audio for optimization):
            $this->emulatorTicks += $this->audioTicks;
            if ($this->emulatorTicks >= Settings::$machineCyclesPerLoop) {
                //Make sure we don't overdo the audio.
                if (($this->stopEmulator & 1) == 0) {
                    //LCD off takes at least 2 frames.
                    if ($this->drewBlank == 0) {
                        $this->drawToCanvas();
                        //Display frame
                    }
                }
                $this->stopEmulator |= 1;
                //End current loop.
                $this->emulatorTicks = 0;
            }
            $this->audioTicks = 0;
        }
        // Internal Timer
        if ($this->TIMAEnabled) {
            $this->timerTicks += $this->CPUTicks;
            while ($this->timerTicks >= $this->TACClocker) {
                $this->timerTicks -= $this->TACClocker;
                if ($this->memory[0xff05] == 0xff) {
                    $this->memory[0xff05] = $this->memory[0xff06];
                    $this->memory[0xff0f] |= 0x4;
                    // set IF bit 2
                } else {
                    ++$this->memory[0xff05];
                }
            }
        }
    }

Usage Example

 /**
  * Opcode #0x76.
  *
  * HALT
  *
  * @param \GameBoy\Core $core
  * @throws Exception
  */
 public static function opcode118(Core $core)
 {
     if ($core->untilEnable == 1) {
         /*VBA-M says this fixes Torpedo Range (Seems to work):
           Involves an edge case where an EI is placed right before a HALT.
           EI in this case actually is immediate, so we adjust (Hacky?).*/
         $core->programCounter = $core->nswtuw($core->programCounter - 1);
     } else {
         if (!$core->halt && !$core->IME && !$core->cGBC && ($core->memory[0xff0f] & $core->memory[0xffff] & 0x1f) > 0) {
             $core->skipPCIncrement = true;
         }
         $core->halt = true;
         while ($core->halt && ($core->stopEmulator & 1) === 0) {
             /*We're hijacking the main interpreter loop to do this dirty business
               in order to not slow down the main interpreter loop code with halt state handling.*/
             $bitShift = 0;
             $testbit = 1;
             $interrupts = $core->memory[0xffff] & $core->memory[0xff0f];
             while ($bitShift < 5) {
                 //Check to see if an interrupt is enabled AND requested.
                 if (($testbit & $interrupts) === $testbit) {
                     $core->halt = false;
                     //Get out of halt state if in halt state.
                     return;
                     //Let the main interrupt handler compute the interrupt.
                 }
                 $testbit = 1 << ++$bitShift;
             }
             $core->CPUTicks = 1;
             //1 machine cycle under HALT...
             //Timing:
             $core->updateCore();
         }
         //Throw an error on purpose to exit out of the loop.
         throw new Exception('HALT_OVERRUN');
     }
 }