void GBReset(struct LR35902Core* cpu) { struct GB* gb = (struct GB*) cpu->master; GBDetectModel(gb); if (gb->biosVf) { if (!GBIsBIOS(gb->biosVf)) { gb->biosVf->close(gb->biosVf); gb->biosVf = NULL; } else { gb->biosVf->seek(gb->biosVf, 0, SEEK_SET); gb->memory.romBase = malloc(GB_SIZE_CART_BANK0); ssize_t size = gb->biosVf->read(gb->biosVf, gb->memory.romBase, GB_SIZE_CART_BANK0); memcpy(&gb->memory.romBase[size], &gb->memory.rom[size], GB_SIZE_CART_BANK0 - size); if (size > 0x100) { memcpy(&gb->memory.romBase[0x100], &gb->memory.rom[0x100], sizeof(struct GBCartridge)); } cpu->a = 0; cpu->f.packed = 0; cpu->c = 0; cpu->e = 0; cpu->h = 0; cpu->l = 0; cpu->sp = 0; cpu->pc = 0; } } cpu->b = 0; cpu->d = 0; if (!gb->biosVf) { switch (gb->model) { case GB_MODEL_DMG: // TODO: SGB case GB_MODEL_SGB: case GB_MODEL_AUTODETECT: // Silence warnings gb->model = GB_MODEL_DMG; cpu->a = 1; cpu->f.packed = 0xB0; cpu->c = 0x13; cpu->e = 0xD8; cpu->h = 1; cpu->l = 0x4D; break; case GB_MODEL_AGB: cpu->b = 1; // Fall through case GB_MODEL_CGB: cpu->a = 0x11; cpu->f.packed = 0x80; cpu->c = 0; cpu->e = 0x08; cpu->h = 0; cpu->l = 0x7C; break; } cpu->sp = 0xFFFE; cpu->pc = 0x100; } gb->eiPending = INT_MAX; gb->doubleSpeed = 0; cpu->memory.setActiveRegion(cpu, cpu->pc); if (gb->yankedRomSize) { gb->memory.romSize = gb->yankedRomSize; gb->yankedRomSize = 0; } GBMemoryReset(gb); GBVideoReset(&gb->video); GBTimerReset(&gb->timer); GBAudioReset(&gb->audio); GBIOReset(gb); GBSIOReset(&gb->sio); GBSavedataUnmask(gb); }
bool retro_load_game(const struct retro_game_info* game) { struct VFile* rom; if (game->data) { data = anonymousMemoryMap(game->size); dataSize = game->size; memcpy(data, game->data, game->size); rom = VFileFromMemory(data, game->size); } else { data = 0; rom = VFileOpen(game->path, O_RDONLY); } if (!rom) { return false; } core = mCoreFindVF(rom); if (!core) { rom->close(rom); mappedMemoryFree(data, game->size); return false; } mCoreInitConfig(core, NULL); core->init(core); core->setAVStream(core, &stream); size_t size = 256 * 224 * BYTES_PER_PIXEL; outputBuffer = malloc(size); memset(outputBuffer, 0xFF, size); core->setVideoBuffer(core, outputBuffer, 256); core->setAudioBufferSize(core, SAMPLES); blip_set_rates(core->getAudioChannel(core, 0), core->frequency(core), 32768); blip_set_rates(core->getAudioChannel(core, 1), core->frequency(core), 32768); core->setPeripheral(core, mPERIPH_RUMBLE, &rumble); savedata = anonymousMemoryMap(SIZE_CART_FLASH1M); struct VFile* save = VFileFromMemory(savedata, SIZE_CART_FLASH1M); _reloadSettings(); core->loadROM(core, rom); core->loadSave(core, save); const char* sysDir = 0; const char* biosName = 0; char biosPath[PATH_MAX]; environCallback(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &sysDir); #ifdef M_CORE_GBA if (core->platform(core) == PLATFORM_GBA) { core->setPeripheral(core, mPERIPH_GBA_LUMINANCE, &lux); biosName = "gba_bios.bin"; } #endif #ifdef M_CORE_GB if (core->platform(core) == PLATFORM_GB) { memset(&cam, 0, sizeof(cam)); cam.height = GBCAM_HEIGHT; cam.width = GBCAM_WIDTH; cam.caps = 1 << RETRO_CAMERA_BUFFER_RAW_FRAMEBUFFER; cam.frame_raw_framebuffer = _updateCamera; core->setPeripheral(core, mPERIPH_IMAGE_SOURCE, &imageSource); environCallback(RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE, &cam); const char* modelName = mCoreConfigGetValue(&core->config, "gb.model"); struct GB* gb = core->board; if (modelName) { gb->model = GBNameToModel(modelName); } else { GBDetectModel(gb); } switch (gb->model) { case GB_MODEL_AGB: case GB_MODEL_CGB: biosName = "gbc_bios.bin"; break; case GB_MODEL_SGB: biosName = "sgb_bios.bin"; break; case GB_MODEL_DMG: default: biosName = "gb_bios.bin"; break; } } #endif if (core->opts.useBios && sysDir && biosName) { snprintf(biosPath, sizeof(biosPath), "%s%s%s", sysDir, PATH_SEP, biosName); struct VFile* bios = VFileOpen(biosPath, O_RDONLY); if (bios) { core->loadBIOS(core, bios, 0); } } core->reset(core); _setupMaps(core); return true; }