GameBoy\Core::ROMLoad PHP Method

ROMLoad() public method

public ROMLoad ( )
    public function ROMLoad()
    {
        //Load the first two ROM banks (0x0000 - 0x7FFF) into regular gameboy memory:
        $this->ROM = $this->getTypedArray(strlen($this->ROMImage), 0, 'uint8');
        for ($romIndex = 0; $romIndex < strlen($this->ROMImage); ++$romIndex) {
            $this->ROM[$romIndex] = ord($this->ROMImage[$romIndex]) & 0xff;
            if ($romIndex < 0x8000) {
                $this->memory[$romIndex] = $this->ROM[$romIndex];
                //Load in the game ROM.
            }
        }
        // ROM name
        for ($address = 0x134; $address < 0x13f; ++$address) {
            if (ord($this->ROMImage[$address]) > 0) {
                $this->name .= $this->ROMImage[$address];
            }
        }
        // ROM game code (for newer games)
        for ($address = 0x13f; $address < 0x143; ++$address) {
            if (ord($this->ROMImage[$address]) > 0) {
                $this->gameCode .= $this->ROMImage[$address];
            }
        }
        echo 'Game Title: ' . $this->name . '[' . $this->gameCode . '][' . $this->ROMImage[0x143] . ']' . PHP_EOL;
        echo 'Game Code: ' . $this->gameCode . PHP_EOL;
        // Cartridge type
        $this->cartridgeType = $this->ROM[0x147];
        echo 'Cartridge type #' . $this->cartridgeType . PHP_EOL;
        //Map out ROM cartridge sub-types.
        $MBCType = '';
        switch ($this->cartridgeType) {
            case 0x0:
                //ROM w/o bank switching
                if (!Settings::$overrideMBC1) {
                    $MBCType = 'ROM';
                    break;
                }
                // no break
            // no break
            case 0x1:
                $this->cMBC1 = true;
                $MBCType = 'MBC1';
                break;
            case 0x2:
                $this->cMBC1 = true;
                $this->cSRAM = true;
                $MBCType = 'MBC1 + SRAM';
                break;
            case 0x3:
                $this->cMBC1 = true;
                $this->cSRAM = true;
                $this->cBATT = true;
                $MBCType = 'MBC1 + SRAM + BATT';
                break;
            case 0x5:
                $this->cMBC2 = true;
                $MBCType = 'MBC2';
                break;
            case 0x6:
                $this->cMBC2 = true;
                $this->cBATT = true;
                $MBCType = 'MBC2 + BATT';
                break;
            case 0x8:
                $this->cSRAM = true;
                $MBCType = 'ROM + SRAM';
                break;
            case 0x9:
                $this->cSRAM = true;
                $this->cBATT = true;
                $MBCType = 'ROM + SRAM + BATT';
                break;
            case 0xb:
                $this->cMMMO1 = true;
                $MBCType = 'MMMO1';
                break;
            case 0xc:
                $this->cMMMO1 = true;
                $this->cSRAM = true;
                $MBCType = 'MMMO1 + SRAM';
                break;
            case 0xd:
                $this->cMMMO1 = true;
                $this->cSRAM = true;
                $this->cBATT = true;
                $MBCType = 'MMMO1 + SRAM + BATT';
                break;
            case 0xf:
                $this->cMBC3 = true;
                $this->cTIMER = true;
                $this->cBATT = true;
                $MBCType = 'MBC3 + TIMER + BATT';
                break;
            case 0x10:
                $this->cMBC3 = true;
                $this->cTIMER = true;
                $this->cBATT = true;
                $this->cSRAM = true;
                $MBCType = 'MBC3 + TIMER + BATT + SRAM';
                break;
            case 0x11:
                $this->cMBC3 = true;
                $MBCType = 'MBC3';
                break;
            case 0x12:
                $this->cMBC3 = true;
                $this->cSRAM = true;
                $MBCType = 'MBC3 + SRAM';
                break;
            case 0x13:
                $this->cMBC3 = true;
                $this->cSRAM = true;
                $this->cBATT = true;
                $MBCType = 'MBC3 + SRAM + BATT';
                break;
            case 0x19:
                $this->cMBC5 = true;
                $MBCType = 'MBC5';
                break;
            case 0x1a:
                $this->cMBC5 = true;
                $this->cSRAM = true;
                $MBCType = 'MBC5 + SRAM';
                break;
            case 0x1b:
                $this->cMBC5 = true;
                $this->cSRAM = true;
                $this->cBATT = true;
                $MBCType = 'MBC5 + SRAM + BATT';
                break;
            case 0x1c:
                $this->cRUMBLE = true;
                $MBCType = 'RUMBLE';
                break;
            case 0x1d:
                $this->cRUMBLE = true;
                $this->cSRAM = true;
                $MBCType = 'RUMBLE + SRAM';
                break;
            case 0x1e:
                $this->cRUMBLE = true;
                $this->cSRAM = true;
                $this->cBATT = true;
                $MBCType = 'RUMBLE + SRAM + BATT';
                break;
            case 0x1f:
                $this->cCamera = true;
                $MBCType = 'GameBoy Camera';
                break;
            case 0xfd:
                $this->cTAMA5 = true;
                $MBCType = 'TAMA5';
                break;
            case 0xfe:
                $this->cHuC3 = true;
                $MBCType = 'HuC3';
                break;
            case 0xff:
                $this->cHuC1 = true;
                $MBCType = 'HuC1';
                break;
            default:
                $MBCType = 'Unknown';
                throw new RuntimeException('Cartridge type is unknown.');
        }
        echo 'Cartridge Type: ' . $MBCType . PHP_EOL;
        // ROM and RAM banks
        $this->numROMBanks = $this->ROMBanks[$this->ROM[0x148]];
        echo $this->numROMBanks . ' ROM banks.' . PHP_EOL;
        switch ($this->RAMBanks[$this->ROM[0x149]]) {
            case 0:
                echo 'No RAM banking requested for allocation or MBC is of type 2.' . PHP_EOL;
                break;
            case 2:
                echo '1 RAM bank requested for allocation.' . PHP_EOL;
                break;
            case 3:
                echo '4 RAM banks requested for allocation.' . PHP_EOL;
                break;
            case 4:
                echo '16 RAM banks requested for allocation.' . PHP_EOL;
                break;
            default:
                echo 'RAM bank amount requested is unknown, will use maximum allowed by specified MBC type.' . PHP_EOL;
        }
        //Check the GB/GBC mode byte:
        switch ($this->ROM[0x143]) {
            case 0x0:
                //Only GB mode
                $this->cGBC = false;
                echo 'Only GB mode detected.' . PHP_EOL;
                break;
            case 0x80:
                //Both GB + GBC modes
                $this->cGBC = !Settings::$priorizeGameBoyMode;
                echo 'GB and GBC mode detected.' . PHP_EOL;
                break;
            case 0xc0:
                //Only GBC mode
                $this->cGBC = true;
                echo 'Only GBC mode detected.' . PHP_EOL;
                break;
            default:
                $this->cGBC = false;
                echo 'Unknown GameBoy game type code #' . $this->ROM[0x143] . ", defaulting to GB mode (Old games don't have a type code)." . PHP_EOL;
        }
        $this->inBootstrap = false;
        $this->setupRAM();
        //CPU/(V)RAM initialization.
        $this->initSkipBootstrap();
        $this->checkPaletteType();
        //License Code Lookup:
        $cOldLicense = $this->ROM[0x14b];
        $cNewLicense = $this->ROM[0x144] & 0xff00 | $this->ROM[0x145] & 0xff;
        if ($cOldLicense != 0x33) {
            //Old Style License Header
            echo 'Old style license code: ' . $cOldLicense . PHP_EOL;
        } else {
            //New Style License Header
            echo 'New style license code: ' . $cNewLicense . PHP_EOL;
        }
    }