public function performHdma()
{
$this->CPUTicks += 1 + 8 * $this->multiplier;
$dmaSrc = ($this->memory[0xff51] << 8) + $this->memory[0xff52];
$dmaDstRelative = ($this->memory[0xff53] << 8) + $this->memory[0xff54];
$dmaDstFinal = $dmaDstRelative + 0x10;
$tileRelative = $this->tileData->length - $this->tileCount;
if ($this->currVRAMBank == 1) {
while ($dmaDstRelative < $dmaDstFinal) {
// Bkg Tile data area
if ($dmaDstRelative < 0x1800) {
$tileIndex = ($dmaDstRelative >> 4) + 384;
if ($this->tileReadState[$tileIndex] == 1) {
$r = $tileRelative + $tileIndex;
do {
$this->tileData[$r] = null;
$r -= $this->tileCount;
} while ($r >= 0);
$this->tileReadState[$tileIndex] = 0;
}
}
$this->VRAM[$dmaDstRelative++] = $this->memoryRead($dmaSrc++);
}
} else {
while ($dmaDstRelative < $dmaDstFinal) {
// Bkg Tile data area
if ($dmaDstRelative < 0x1800) {
$tileIndex = $dmaDstRelative >> 4;
if ($this->tileReadState[$tileIndex] == 1) {
$r = $tileRelative + $tileIndex;
do {
$this->tileData[$r] = null;
$r -= $this->tileCount;
} while ($r >= 0);
$this->tileReadState[$tileIndex] = 0;
}
}
$this->memory[0x8000 + $dmaDstRelative++] = $this->memoryRead($dmaSrc++);
}
}
$this->memory[0xff51] = ($dmaSrc & 0xff00) >> 8;
$this->memory[0xff52] = $dmaSrc & 0xf0;
$this->memory[0xff53] = ($dmaDstFinal & 0x1f00) >> 8;
$this->memory[0xff54] = $dmaDstFinal & 0xf0;
if ($this->memory[0xff55] == 0) {
$this->hdmaRunning = false;
$this->memory[0xff55] = 0xff;
//Transfer completed ("Hidden last step," since some ROMs don't imply this, but most do).
} else {
--$this->memory[0xff55];
}
}