static void LoadCommon(MDFNFILE *fp) { try { /* Assign default settings (US NTSC machine) */ sms.display = DISPLAY_NTSC; sms.territory = MDFN_GetSettingI("sms.territory"); sms.use_fm = FALSE; Cart_Init(fp); Cart_LoadNV(); if(IS_SMS && sms.territory == TERRITORY_DOMESTIC) sms.use_fm = MDFN_GetSettingB("sms.fm"); MDFNMP_Init(1024, 65536 / 1024); system_assign_device(PORT_A, DEVICE_PAD2B); system_assign_device(PORT_B, DEVICE_PAD2B); MDFNMP_AddRAM(8192, 0xC000, sms.wram); sms_init(); pio_init(); vdp_init(IS_SMS && sms.territory == TERRITORY_DOMESTIC); render_init(); MDFNGameInfo->GameSetMD5Valid = FALSE; uint32 sndclk; if(sms.display == DISPLAY_PAL) { sndclk = 3546893; MDFNGameInfo->fps = (uint32)((uint64)65536 * 256 * sndclk / 313 / 228); //6144000 * 65536 * 256 / 515 / 198); // 3072000 * 2 * 10000 / 515 / 198 } else { sndclk = 3579545; MDFNGameInfo->fps = (uint32)((uint64)65536 * 256 * sndclk / 262 / 228); //6144000 * 65536 * 256 / 515 / 198); // 3072000 * 2 * 10000 / 515 / 198 } MDFNGameInfo->MasterClock = MDFN_MASTERCLOCK_FIXED(sndclk); SMS_SoundInit(sndclk, sms.use_fm); sms.save = 0; system_reset(); } catch(...) { Cleanup(); throw; } }
static void InitCommon(const char *name) { NESIsVSUni = FALSE; PPU_hook = 0; GameHBIRQHook = 0; MapIRQHook = 0; MMC5Hack = 0; PAL &= 1; MDFNGameInfo->GameType = GMT_CART; MDFNGameInfo->VideoSystem = VIDSYS_NONE; MDFNGameInfo->cspecial = NULL; MDFNGameInfo->GameSetMD5Valid = FALSE; if(MDFN_GetSettingB("nes.fnscan")) { const char *fn = GetFNComponent(name); // TODO: This seems awfully spaghetti-like/inefficient. Fixme? if(strstr(fn, "(U)") || strstr(fn, "(USA)")) MDFNGameInfo->VideoSystem = VIDSYS_NTSC; else if(strstr(fn, "(J)") || strstr(fn, "(Japan)")) MDFNGameInfo->VideoSystem = VIDSYS_NTSC; else if(strstr(fn, "(E)") || strstr(fn, "(G)") || strstr(fn, "(Europe)") || strstr(fn, "(Germany)") ) MDFNGameInfo->VideoSystem = VIDSYS_PAL; } GameInterface = (NESGameType *)calloc(1, sizeof(NESGameType)); SetReadHandler(0x0000, 0xFFFF, ANull); SetWriteHandler(0x0000, 0xFFFF, BNull); SetReadHandler(0x10000,0x10000 + 0xFF, AOverflow); SetWriteHandler(0x10000,0x10000 + 0xFF, BOverflow); SetReadHandler(0,0x7FF,ARAML); SetWriteHandler(0,0x7FF,BRAML); SetReadHandler(0x800,0x1FFF,ARAMH); /* Part of a little */ SetWriteHandler(0x800,0x1FFF,BRAMH); /* hack for a small speed boost. */ MDFNMP_Init(1024, 65536 / 1024); #ifdef WANT_DEBUGGER NESDBG_Init(); ASpace_Add(NESDBG_GetAddressSpaceBytes, NESDBG_PutAddressSpaceBytes, "cpu", "CPU", 16); ASpace_Add(NESPPU_GetAddressSpaceBytes, NESPPU_PutAddressSpaceBytes, "ppu", "PPU", 14); #endif }
static MDFN_COLD void InitCommon(const std::string& fbase) { NESIsVSUni = false; PPU_hook = 0; GameHBIRQHook = 0; MapIRQHook = 0; MMC5Hack = 0; PAL &= 1; MDFNGameInfo->VideoSystem = VIDSYS_NONE; MDFNGameInfo->cspecial = NULL; if(MDFN_GetSettingB("nes.fnscan")) { if(fbase.find("(U)") != std::string::npos || fbase.find("(USA)") != std::string::npos) MDFNGameInfo->VideoSystem = VIDSYS_NTSC; else if(fbase.find("(J)") != std::string::npos || fbase.find("(Japan)") != std::string::npos) MDFNGameInfo->VideoSystem = VIDSYS_NTSC; else if(fbase.find("(E)") != std::string::npos || fbase.find("(G)") != std::string::npos || fbase.find("(F)") != std::string::npos || fbase.find("(Europe)") != std::string::npos || fbase.find("(Germany)") != std::string::npos || fbase.find("(France)") != std::string::npos) MDFNGameInfo->VideoSystem = VIDSYS_PAL; } memset(&GameInterface, 0, sizeof(GameInterface)); SetReadHandler(0x0000, 0xFFFF, ANull); SetWriteHandler(0x0000, 0xFFFF, BNull); SetReadHandler(0x10000,0x10000 + 0xFF, AOverflow); SetWriteHandler(0x10000,0x10000 + 0xFF, BOverflow); SetReadHandler(0,0x7FF,ARAML); SetWriteHandler(0,0x7FF,BRAML); SetReadHandler(0x800,0x1FFF,ARAMH); /* Part of a little */ SetWriteHandler(0x800,0x1FFF,BRAMH); /* hack for a small speed boost. */ MDFNMP_Init(1024, 65536 / 1024); #ifdef WANT_DEBUGGER NESDBG_Init(); ASpace_Add(NESDBG_GetAddressSpaceBytes, NESDBG_PutAddressSpaceBytes, "cpu", "CPU", 16); ASpace_Add(NESPPU_GetAddressSpaceBytes, NESPPU_PutAddressSpaceBytes, "ppu", "PPU", 14); ASpace_Add(NESPPU_GetAddressSpaceBytes, NESPPU_PutAddressSpaceBytes, "spram", "Sprite RAM", 8); #endif }
static void Load(MDFNFILE *fp) { try { const uint64 fp_size = fp->size(); if(fp_size > 1024 * 1024 * 8) // 4MiB maximum ROM size, 2* to be a little tolerant of garbage. throw MDFN_Error(0, _("NGP/NGPC ROM image is too large.")); ngpc_rom.length = fp_size; ngpc_rom.data = new uint8[ngpc_rom.length]; fp->read(ngpc_rom.data, ngpc_rom.length); md5_context md5; md5.starts(); md5.update(ngpc_rom.data, ngpc_rom.length); md5.finish(MDFNGameInfo->MD5); rom_loaded(); MDFN_printf(_("ROM: %uKiB\n"), (ngpc_rom.length + 1023) / 1024); MDFN_printf(_("ROM MD5: 0x%s\n"), md5_context::asciistr(MDFNGameInfo->MD5, 0).c_str()); FLASH_LoadNV(); MDFNMP_Init(1024, 1024 * 1024 * 16 / 1024); NGPGfx = new NGPGFX_CLASS(); MDFNGameInfo->fps = (uint32)((uint64)6144000 * 65536 * 256 / 515 / 198); // 3072000 * 2 * 10000 / 515 / 198 MDFNGameInfo->GameSetMD5Valid = FALSE; MDFNNGPCSOUND_Init(); MDFNMP_AddRAM(16384, 0x4000, CPUExRAM); SetFRM(); // Set up fast read memory mapping bios_install(); //main_timeaccum = 0; z80_runtime = 0; reset(); } catch(...) { Cleanup(); throw; } }
static void LoadCommonPre(void) { // FIXME: Make these globals less global! pce_overclocked = MDFN_GetSettingUI("pce_fast.ocmultiplier"); PCE_ACEnabled = MDFN_GetSettingB("pce_fast.arcadecard"); if(pce_overclocked > 1) MDFN_printf(_("CPU overclock: %dx\n"), pce_overclocked); if(MDFN_GetSettingUI("pce_fast.cdspeed") > 1) MDFN_printf(_("CD-ROM speed: %ux\n"), (unsigned int)MDFN_GetSettingUI("pce_fast.cdspeed")); memset(HuCPUFastMap, 0, sizeof(HuCPUFastMap)); for(int x = 0; x < 0x100; x++) { PCERead[x] = PCEBusRead; PCEWrite[x] = PCENullWrite; } MDFNMP_Init(1024, (1 << 21) / 1024); }
static int Load(const char *name, MDFNFILE *fp) { if(!(ngpc_rom.data = (uint8 *)MDFN_malloc(GET_FSIZE_PTR(fp), _("Cart ROM")))) return(0); ngpc_rom.length = GET_FSIZE_PTR(fp); memcpy(ngpc_rom.data, GET_FDATA_PTR(fp), GET_FSIZE_PTR(fp)); md5_context md5; md5.starts(); md5.update(ngpc_rom.data, ngpc_rom.length); md5.finish(MDFNGameInfo->MD5); rom_loaded(); MDFN_printf(_("ROM: %dKiB\n"), (ngpc_rom.length + 1023) / 1024); MDFN_printf(_("ROM MD5: 0x%s\n"), md5_context::asciistr(MDFNGameInfo->MD5, 0).c_str()); MDFNMP_Init(1024, 1024 * 1024 * 16 / 1024); NGPGfx = new NGPGFX_CLASS(); MDFNGameInfo->fps = (uint32)((uint64)6144000 * 65536 * 256 / 515 / 198); // 3072000 * 2 * 10000 / 515 / 198 MDFNGameInfo->GameSetMD5Valid = FALSE; MDFNNGPCSOUND_Init(); MDFNMP_AddRAM(16384, 0x4000, CPUExRAM); SetFRM(); // Set up fast read memory mapping bios_install(); //main_timeaccum = 0; z80_runtime = 0; reset(); return(1); }
static void LoadCommonPre(void) { HuC6280_Init(); // FIXME: Make these globals less global! pce_overclocked = MDFN_GetSettingUI("pce_fast.ocmultiplier"); PCE_ACEnabled = MDFN_GetSettingB("pce_fast.arcadecard"); if(pce_overclocked > 1) MDFN_printf(_("CPU overclock: %dx\n"), pce_overclocked); if(MDFN_GetSettingUI("pce_fast.cdspeed") > 1) MDFN_printf(_("CD-ROM speed: %ux\n"), (unsigned int)MDFN_GetSettingUI("pce_fast.cdspeed")); for(int x = 0; x < 0x100; x++) { HuCPU.PCERead[x] = PCEBusRead; HuCPU.PCEWrite[x] = PCENullWrite; } MDFNMP_Init(1024, (1 << 21) / 1024); sbuf = new Blip_Buffer[2]; }
static int ModuleLoad () { //Load the BIOS MDFNFILE biosFile; if(biosFile.Open(MDFN_MakeFName(MDFNMKF_FIRMWARE, 0, MDFN_GetSettingS("pcsxr.bios").c_str()).c_str(), 0)) { if(biosFile.size == 512 * 1024) { memcpy(BiosBuffer, biosFile.data, 512 * 1024); } else { MDFN_printf("pcsxr: BIOS file size incorrect\n"); } } else { MDFN_printf("pcsxr: Failed to load bios\n"); return 0; } //Setup the config structure memset(&Config, 0, sizeof(Config)); Config.PsxAuto = 1; Config.Cpu = MDFN_GetSettingB("pcsxr.recompiler") ? CPU_DYNAREC : CPU_INTERPRETER; Config.SlowBoot = MDFN_GetSettingB("pcsxr.slowboot"); strcpy(Config.PluginsDir, "builtin"); strcpy(Config.Gpu, "builtin"); strcpy(Config.Spu, "builtin"); strcpy(Config.Pad1, "builtin"); strcpy(Config.Pad2, "builtin"); strcpy(Config.Cdr, "builtin"); strcpy(Config.Net, "Disabled"); strncpy(Config.Mcd1, MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), MAXPATHLEN); strncpy(Config.Mcd2, MDFN_MakeFName(MDFNMKF_SAV, 0, "sav2").c_str(), MAXPATHLEN); //Init psx cpu emulator and memory mapping EmuInit(); //Open and initialize all of the plugins OpenPlugins(); //Load memory cards LoadMcds(Config.Mcd1, Config.Mcd2); //Get cdrom ID and init PPF support... CheckCdrom(); //Reset the emulated CPU and Memory EmuReset(); //Prepares the game to run, either runs the CPU thru the bios or finds and loads the game EXE if using the emulated bios LoadCdrom(); //TODO: Set the clock if the machine is PAL //Just say two 1M pages, for fun not profit MDFNMP_Init(1024 * 1024, 2); MDFNMP_AddRAM(1024 * 1024 * 2, 0, (uint8_t*)psxM); return 1; }
static void LoadCommonPost(const md_game_info &ginfo) { MDFN_printf(_("ROM: %dKiB\n"), (ginfo.rom_size + 1023) / 1024); MDFN_printf(_("ROM CRC32: 0x%08x\n"), ginfo.crc32); MDFN_printf(_("ROM MD5: 0x%s\n"), md5_context::asciistr(ginfo.md5, 0).c_str()); MDFN_printf(_("Header MD5: 0x%s\n"), md5_context::asciistr(ginfo.info_header_md5, 0).c_str()); MDFN_printf(_("Product Code: %s\n"), ginfo.product_code); MDFN_printf(_("Domestic name: %s\n"), ginfo.domestic_name); // TODO: Character set conversion(shift_jis -> utf-8) MDFN_printf(_("Overseas name: %s\n"), ginfo.overseas_name); MDFN_printf(_("Copyright: %s\n"), ginfo.copyright); if(ginfo.checksum == ginfo.checksum_real) MDFN_printf(_("Checksum: 0x%04x\n"), ginfo.checksum); else MDFN_printf(_("Checksum: 0x%04x\n Warning: calculated checksum(0x%04x) does not match\n"), ginfo.checksum, ginfo.checksum_real); MDFN_printf(_("Supported I/O devices:\n")); MDFN_indent(1); for(unsigned int iot = 0; iot < sizeof(IO_types) / sizeof(IO_type_t); iot++) { if(ginfo.io_support & (1 << IO_types[iot].id)) MDFN_printf(_("%s\n"), _(IO_types[iot].name)); } MDFN_indent(-1); MDFNMP_Init(8192, (1 << 24) / 8192); MDFNMP_AddRAM(65536, 0x7 << 21, work_ram); MDFNGameInfo->GameSetMD5Valid = FALSE; MDSound_Init(); MDFN_printf(_("Supported regions:\n")); MDFN_indent(1); if(ginfo.region_support & REGIONMASK_JAPAN_NTSC) MDFN_printf(_("Japan/Domestic NTSC\n")); if(ginfo.region_support & REGIONMASK_JAPAN_PAL) MDFN_printf(_("Japan/Domestic PAL\n")); if(ginfo.region_support & REGIONMASK_OVERSEAS_NTSC) MDFN_printf(_("Overseas NTSC\n")); if(ginfo.region_support & REGIONMASK_OVERSEAS_PAL) MDFN_printf(_("Overseas PAL\n")); MDFN_indent(-1); { const int region_setting = MDFN_GetSettingI("md.region"); const int reported_region_setting = MDFN_GetSettingI("md.reported_region"); // Default, in case the game doesn't support any regions! bool game_overseas = TRUE; bool game_pal = FALSE; bool overseas; bool pal; bool overseas_reported; bool pal_reported; // Preference order, TODO: Make it configurable if(ginfo.region_support & REGIONMASK_OVERSEAS_NTSC) { game_overseas = TRUE; game_pal = FALSE; } else if(ginfo.region_support & REGIONMASK_JAPAN_NTSC) { game_overseas = FALSE; game_pal = FALSE; } else if(ginfo.region_support & REGIONMASK_OVERSEAS_PAL) { game_overseas = TRUE; game_pal = TRUE; } else if(ginfo.region_support & REGIONMASK_JAPAN_PAL) // WTF? { game_overseas = FALSE; game_pal = TRUE; } if(region_setting == REGION_GAME) { overseas = game_overseas; pal = game_pal; } else { decode_region_setting(region_setting, overseas, pal); } if(reported_region_setting == REGION_GAME) { overseas_reported = game_overseas; pal_reported = game_pal; } else if(reported_region_setting == REGION_SAME) { overseas_reported = overseas; pal_reported = pal; } else { decode_region_setting(reported_region_setting, overseas_reported, pal_reported); } MDFN_printf("\n"); MDFN_printf(_("Active Region: %s %s\n"), overseas ? _("Overseas") : _("Domestic"), pal ? _("PAL") : _("NTSC")); MDFN_printf(_("Active Region Reported: %s %s\n"), overseas_reported ? _("Overseas") : _("Domestic"), pal_reported ? _("PAL") : _("NTSC")); system_init(overseas, pal, overseas_reported, pal_reported); if(pal) MDFNGameInfo->nominal_height = 240; else MDFNGameInfo->nominal_height = 224; MDFNGameInfo->MasterClock = MDFN_MASTERCLOCK_FIXED(pal ? CLOCK_PAL : CLOCK_NTSC); if(pal) MDFNGameInfo->fps = (int64)CLOCK_PAL * 65536 * 256 / (313 * 3420); else MDFNGameInfo->fps = (int64)CLOCK_NTSC * 65536 * 256 / (262 * 3420); //printf("%f\n", (double)MDFNGameInfo->fps / 65536 / 256); } if(MDFN_GetSettingB("md.correct_aspect")) { MDFNGameInfo->nominal_width = 292; MDFNGameInfo->lcm_width = 1280; } else { MDFNGameInfo->nominal_width = 320; MDFNGameInfo->lcm_width = 320; } MDFNGameInfo->lcm_height = MDFNGameInfo->nominal_height * 2; MDFNGameInfo->LayerNames = "BG0\0BG1\0OBJ\0"; // // { unsigned mtt = MDFN_GetSettingUI("md.input.multitap"); if(MDFN_GetSettingB("md.input.auto")) { for(auto const& e : InputDB) { if(e.crc32 == ginfo.crc32 && (!e.prod_code || !strcmp(e.prod_code, ginfo.product_code))) { MDFNGameInfo->DesiredInput.resize(8); for(unsigned n = e.max_players; n < 8; n++) // Particularly for Gauntlet 4. MDFNGameInfo->DesiredInput[n] = "none"; mtt = e.tap; break; } } } for(const auto* mte = MultiTap_List; mte->string; mte++) { if((unsigned)mte->number == mtt) { MDFN_printf(_("Active Multitap(s): %s\n"), mte->description); break; } } MDINPUT_SetMultitap(mtt); } // // system_reset(true); }
CSystem::CSystem(const uint8 *filememory, int32 filesize) :mCart(NULL), mRom(NULL), mMemMap(NULL), mRam(NULL), mCpu(NULL), mMikie(NULL), mSusie(NULL) { mFileType=HANDY_FILETYPE_LNX; if(filesize < 11) MDFN_Error(0, _("Lynx ROM image is too short: %u bytes"), filesize); char clip[11]; memcpy(clip,filememory,11); clip[4]=0; clip[10]=0; if(!strcmp(&clip[6],"BS93")) mFileType=HANDY_FILETYPE_HOMEBREW; else if(!strcmp(&clip[0],"LYNX")) mFileType=HANDY_FILETYPE_LNX; else { throw MDFN_Error(0, _("File format is unknown to module \"%s\"."), MDFNGameInfo->shortname); } MDFNMP_Init(65536, 1); // Create the system objects that we'll use // Attempt to load the cartridge errors caught above here... mRom = new CRom(MDFN_MakeFName(MDFNMKF_FIRMWARE, 0, "lynxboot.img").c_str()); // An exception from this will be caught by the level above switch(mFileType) { case HANDY_FILETYPE_LNX: mCart = new CCart(filememory,filesize); mRam = new CRam(0,0); break; case HANDY_FILETYPE_HOMEBREW: { #if 0 static uint8 dummy_cart[CCart::HEADER_RAW_SIZE + 65536] = { 'L', 'Y', 'N', 'X', 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, }; mCart = new CCart(dummy_cart, sizeof(dummy_cart)); #else mCart = new CCart(NULL, 0); #endif mRam = new CRam(filememory,filesize); } break; case HANDY_FILETYPE_SNAPSHOT: case HANDY_FILETYPE_ILLEGAL: default: mCart = new CCart(0,0); mRam = new CRam(0,0); break; } // These can generate exceptions mMikie = new CMikie(*this); mSusie = new CSusie(*this); // Instantiate the memory map handler mMemMap = new CMemMap(*this); // Now the handlers are set we can instantiate the CPU as is will use handlers on reset mCpu = new C65C02(*this); // Now init is complete do a reset, this will cause many things to be reset twice // but what the hell, who cares, I don't..... Reset(); }
static int LoadCommon(MDFNFILE *fp) { int32 size = fp->size; const uint8 *data_ptr = fp->data; if(size & 512) { size -= 512; data_ptr += 512; } /* Assign default settings (US NTSC machine) */ sms.display = DISPLAY_NTSC; sms.territory = MDFN_GetSettingI("sms.territory"); sms.use_fm = FALSE; if(!SMS_CartInit(data_ptr, size)) return(0); if(IS_SMS && sms.territory == TERRITORY_DOMESTIC) sms.use_fm = MDFN_GetSettingB("sms.fm"); MDFNMP_Init(1024, 65536 / 1024); system_assign_device(PORT_A, DEVICE_PAD2B); system_assign_device(PORT_B, DEVICE_PAD2B); MDFNMP_AddRAM(8192, 0xC000, sms.wram); sms_init(); pio_init(); vdp_init(IS_SMS && sms.territory == TERRITORY_DOMESTIC); render_init(); MDFNGameInfo->GameSetMD5Valid = FALSE; uint32 sndclk; if(sms.display == DISPLAY_PAL) { sndclk = 3546893; MDFNGameInfo->fps = (uint32)((uint64)65536 * 256 * sndclk / 313 / 228); //6144000 * 65536 * 256 / 515 / 198); // 3072000 * 2 * 10000 / 515 / 198 } else { sndclk = 3579545; MDFNGameInfo->fps = (uint32)((uint64)65536 * 256 * sndclk / 262 / 228); //6144000 * 65536 * 256 / 515 / 198); // 3072000 * 2 * 10000 / 515 / 198 } MDFNGameInfo->MasterClock = MDFN_MASTERCLOCK_FIXED(sndclk); SMS_SoundInit(sndclk, sms.use_fm); sms.save = 0; system_reset(); return(1); }
CSystem::CSystem(const uint8 *filememory, int32 filesize) :mCart(NULL), mRom(NULL), mMemMap(NULL), mRam(NULL), mCpu(NULL), mMikie(NULL), mSusie(NULL) { mFileType=HANDY_FILETYPE_LNX; if(filesize < 11) throw(-1); char clip[11]; memcpy(clip,filememory,11); clip[4]=0; clip[10]=0; if(!strcmp(&clip[6],"BS93")) mFileType=HANDY_FILETYPE_HOMEBREW; else if(!strcmp(&clip[0],"LYNX")) mFileType=HANDY_FILETYPE_LNX; else { throw(-1); //CLynxException lynxerr; //delete filememory; //mFileType=HANDY_FILETYPE_ILLEGAL; //lynxerr.Message() << "Handy Error: File format invalid!"; //lynxerr.Description() // << "The image you selected was not a recognised game cartridge format." << endl // << "(see the Handy User Guide for more information)."; //throw(lynxerr); } MDFNMP_Init(65536, 1); // Create the system objects that we'll use // Attempt to load the cartridge errors caught above here... mRom = new CRom(MDFN_MakeFName(MDFNMKF_FIRMWARE, 0, "lynxboot.img").c_str()); // An exception from this will be caught by the level above switch(mFileType) { case HANDY_FILETYPE_LNX: mCart = new CCart(filememory,filesize); mRam = new CRam(0,0); break; case HANDY_FILETYPE_HOMEBREW: { #if 0 static uint8 dummy_cart[CCart::HEADER_RAW_SIZE + 65536] = { 'L', 'Y', 'N', 'X', 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, }; mCart = new CCart(dummy_cart, sizeof(dummy_cart)); #else mCart = new CCart(NULL, 0); #endif mRam = new CRam(filememory,filesize); } break; case HANDY_FILETYPE_SNAPSHOT: case HANDY_FILETYPE_ILLEGAL: default: mCart = new CCart(0,0); mRam = new CRam(0,0); break; } // These can generate exceptions mMikie = new CMikie(*this); mSusie = new CSusie(*this); // Instantiate the memory map handler mMemMap = new CMemMap(*this); // Now the handlers are set we can instantiate the CPU as is will use handlers on reset mCpu = new C65C02(*this); // Now init is complete do a reset, this will cause many things to be reset twice // but what the hell, who cares, I don't..... Reset(); }
static int Load(const char *name, MDFNFILE *fp) { uint32 real_rom_size; if(fp->size < 65536) { MDFN_PrintError(_("%s ROM image is too small."), MDFNGameInfo->fullname); return(0); } if(!memcmp(fp->data + fp->size - 0x20, "WSRF", 4)) { const uint8 *wsr_footer = fp->data + fp->size - 0x20; IsWSR = TRUE; WSRCurrentSong = wsr_footer[0x5]; Player_Init(256, "", "", ""); } else IsWSR = false; real_rom_size = (fp->size + 0xFFFF) & ~0xFFFF; rom_size = round_up_pow2(real_rom_size); //fp->size); wsCartROM = (uint8 *)calloc(1, rom_size); // This real_rom_size vs rom_size funny business is intended primarily for handling // WSR files. if(real_rom_size < rom_size) memset(wsCartROM, 0xFF, rom_size - real_rom_size); memcpy(wsCartROM + (rom_size - real_rom_size), fp->data, fp->size); MDFN_printf(_("ROM: %dKiB\n"), real_rom_size / 1024); md5_context md5; md5.starts(); md5.update(wsCartROM, rom_size); md5.finish(MDFNGameInfo->MD5); MDFN_printf(_("ROM MD5: 0x%s\n"), md5_context::asciistr(MDFNGameInfo->MD5, 0).c_str()); uint8 header[10]; memcpy(header, wsCartROM + rom_size - 10, 10); { const char *developer_name = "???"; for(unsigned int x = 0; x < sizeof(Developers) / sizeof(DLEntry); x++) { if(Developers[x].id == header[0]) { developer_name = Developers[x].name; break; } } MDFN_printf(_("Developer: %s (0x%02x)\n"), developer_name, header[0]); } uint32 SRAMSize = 0; eeprom_size = 0; switch(header[5]) { case 0x01: SRAMSize = 8*1024; break; case 0x02: SRAMSize = 32*1024; break; case 0x03: SRAMSize = 16 * 65536; break; case 0x04: SRAMSize = 32 * 65536; break; // Dicing Knight! case 0x10: eeprom_size = 128; break; case 0x20: eeprom_size = 2*1024; break; case 0x50: eeprom_size = 1024; break; } //printf("%02x\n", header[5]); if(eeprom_size) MDFN_printf(_("EEPROM: %d bytes\n"), eeprom_size); if(SRAMSize) MDFN_printf(_("Battery-backed RAM: %d bytes\n"), SRAMSize); MDFN_printf(_("Recorded Checksum: 0x%04x\n"), header[8] | (header[9] << 8)); { uint16 real_crc = 0; for(unsigned int i = 0; i < rom_size - 2; i++) real_crc += wsCartROM[i]; MDFN_printf(_("Real Checksum: 0x%04x\n"), real_crc); } if((header[8] | (header[9] << 8)) == 0x8de1 && (header[0]==0x01)&&(header[2]==0x27)) /* Detective Conan */ { //puts("HAX"); /* WS cpu is using cache/pipeline or there's protected ROM bank where pointing CS */ wsCartROM[0xfffe8]=0xea; wsCartROM[0xfffe9]=0x00; wsCartROM[0xfffea]=0x00; wsCartROM[0xfffeb]=0x00; wsCartROM[0xfffec]=0x20; } if(!IsWSR) { if(header[6] & 0x1) MDFNGameInfo->rotated = MDFN_ROTATE90; } MDFNMP_Init(16384, (1 << 20) / 1024); #ifdef WANT_DEBUGGER WSwanDBG_Init(); #endif v30mz_init(WSwan_readmem20, WSwan_writemem20, WSwan_readport, WSwan_writeport); WSwan_MemoryInit(MDFN_GetSettingB("wswan.language"), wsc, SRAMSize, IsWSR); // EEPROM and SRAM are loaded in this func. WSwan_GfxInit(); MDFNGameInfo->fps = (uint32)((uint64)3072000 * 65536 * 256 / (159*256)); MDFNGameInfo->GameSetMD5Valid = FALSE; WSwan_SoundInit(); wsMakeTiles(); Reset(); return(1); }
CSystem::CSystem(MDFNFILE* fp) { mFileType = HANDY_FILETYPE_LNX; char clip[11]; fp->read(clip, 11); fp->seek(0, SEEK_SET); clip[4]=0; clip[10]=0; if(!strcmp(&clip[6],"BS93")) mFileType = HANDY_FILETYPE_HOMEBREW; else if(!strcmp(&clip[0],"LYNX")) mFileType = HANDY_FILETYPE_LNX; else { throw MDFN_Error(0, _("File format is unknown to module \"%s\"."), MDFNGameInfo->shortname); } MDFNMP_Init(65536, 1); // Create the system objects that we'll use // Attempt to load the cartridge errors caught above here... mRom.reset(new CRom(MDFN_MakeFName(MDFNMKF_FIRMWARE, 0, "lynxboot.img").c_str())); // An exception from this will be caught by the level above switch(mFileType) { default: abort(); break; case HANDY_FILETYPE_LNX: mCart.reset(new CCart(fp->stream())); mRam.reset(new CRam(NULL)); break; case HANDY_FILETYPE_HOMEBREW: { mCart.reset(new CCart(NULL)); mRam.reset(new CRam(fp->stream())); } break; } // These can generate exceptions mMikie.reset(new CMikie(*this)); mSusie.reset(new CSusie(*this)); // Instantiate the memory map handler mMemMap.reset(new CMemMap(*this)); // Now the handlers are set we can instantiate the CPU as is will use handlers on reset mCpu.reset(new C65C02(*this)); // Now init is complete do a reset, this will cause many things to be reset twice // but what the hell, who cares, I don't..... Reset(); }