2016-01-27 09:05:12 +00:00
/* Copyright (c) 2013-2016 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/. */
2016-12-31 01:00:22 +00:00
# include <mgba/gb/core.h>
2016-01-27 09:05:12 +00:00
2016-12-31 01:00:22 +00:00
# include <mgba/core/core.h>
2017-05-23 04:47:43 +00:00
# include <mgba/internal/debugger/symbols.h>
2016-12-31 01:00:22 +00:00
# include <mgba/internal/gb/cheats.h>
2017-05-23 04:47:43 +00:00
# include <mgba/internal/gb/debugger/symbols.h>
2016-12-31 01:00:22 +00:00
# include <mgba/internal/gb/extra/cli.h>
2017-04-24 19:43:12 +00:00
# include <mgba/internal/gb/io.h>
2016-12-31 01:00:22 +00:00
# include <mgba/internal/gb/gb.h>
# include <mgba/internal/gb/mbc.h>
# include <mgba/internal/gb/overrides.h>
# include <mgba/internal/gb/renderers/software.h>
2017-04-18 08:55:32 +00:00
# include <mgba/internal/gb/renderers/proxy.h>
2016-12-31 01:00:22 +00:00
# include <mgba/internal/gb/serialize.h>
# include <mgba/internal/lr35902/lr35902.h>
# include <mgba/internal/lr35902/debugger/debugger.h>
# include <mgba-util/crc32.h>
# include <mgba-util/memory.h>
# include <mgba-util/patch.h>
# include <mgba-util/vfs.h>
2016-01-27 09:05:12 +00:00
2017-06-28 08:06:15 +00:00
static const struct mCoreChannelInfo _GBVideoLayers [ ] = {
2017-04-12 20:28:21 +00:00
{ 0 , " bg " , " Background " , NULL } ,
{ 1 , " obj " , " Objects " , NULL } ,
{ 2 , " win " , " Window " , NULL } ,
} ;
2017-06-28 08:06:15 +00:00
static const struct mCoreChannelInfo _GBAudioChannels [ ] = {
{ 0 , " ch1 " , " Channel 1 " , " Square/Sweep " } ,
{ 1 , " ch2 " , " Channel 2 " , " Square " } ,
{ 2 , " ch3 " , " Channel 3 " , " PCM " } ,
{ 3 , " ch4 " , " Channel 4 " , " Noise " } ,
2017-04-12 20:28:21 +00:00
} ;
2017-06-28 08:06:15 +00:00
static const struct LR35902Segment _GBSegments [ ] = {
2017-06-03 02:37:36 +00:00
{ . name = " ROM " , . start = GB_BASE_CART_BANK1 , . end = GB_BASE_VRAM } ,
{ . name = " RAM " , . start = GB_BASE_EXTERNAL_RAM , . end = GB_BASE_WORKING_RAM_BANK0 } ,
{ 0 }
} ;
2017-06-28 08:06:15 +00:00
static const struct LR35902Segment _GBCSegments [ ] = {
2017-06-03 02:37:36 +00:00
{ . name = " ROM " , . start = GB_BASE_CART_BANK1 , . end = GB_BASE_VRAM } ,
{ . name = " RAM " , . start = GB_BASE_EXTERNAL_RAM , . end = GB_BASE_WORKING_RAM_BANK0 } ,
{ . name = " WRAM " , . start = GB_BASE_WORKING_RAM_BANK1 , . end = 0xE000 } ,
{ . name = " VRAM " , . start = GB_BASE_VRAM , . end = GB_BASE_EXTERNAL_RAM } ,
{ 0 }
} ;
2017-06-28 08:06:15 +00:00
static const struct mCoreMemoryBlock _GBMemoryBlocks [ ] = {
2017-06-05 22:20:58 +00:00
{ - 1 , " mem " , " All " , " All " , 0 , 0x10000 , 0x10000 , mCORE_MEMORY_VIRTUAL } ,
{ GB_REGION_CART_BANK0 , " cart0 " , " ROM Bank " , " Game Pak (32kiB) " , GB_BASE_CART_BANK0 , GB_SIZE_CART_BANK0 * 2 , 0x800000 , mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED , 511 } ,
{ GB_REGION_VRAM , " vram " , " VRAM " , " Video RAM (8kiB) " , GB_BASE_VRAM , GB_BASE_VRAM + GB_SIZE_VRAM , GB_SIZE_VRAM , mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED } ,
{ GB_REGION_EXTERNAL_RAM , " sram " , " SRAM " , " External RAM (8kiB) " , GB_BASE_EXTERNAL_RAM , GB_BASE_EXTERNAL_RAM + GB_SIZE_EXTERNAL_RAM , GB_SIZE_EXTERNAL_RAM * 4 , mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED , 3 } ,
{ GB_REGION_WORKING_RAM_BANK0 , " wram " , " WRAM " , " Working RAM (8kiB) " , GB_BASE_WORKING_RAM_BANK0 , GB_BASE_WORKING_RAM_BANK0 + GB_SIZE_WORKING_RAM_BANK0 * 2 , GB_SIZE_WORKING_RAM_BANK0 * 2 , mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED } ,
{ GB_BASE_OAM , " oam " , " OAM " , " OBJ Attribute Memory " , GB_BASE_OAM , GB_BASE_OAM + GB_SIZE_OAM , GB_SIZE_OAM , mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED } ,
{ GB_BASE_IO , " io " , " MMIO " , " Memory-Mapped I/O " , GB_BASE_IO , GB_BASE_IO + GB_SIZE_IO , GB_SIZE_IO , mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED } ,
{ GB_BASE_HRAM , " hram " , " HRAM " , " High RAM " , GB_BASE_HRAM , GB_BASE_HRAM + GB_SIZE_HRAM , GB_SIZE_HRAM , mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED } ,
} ;
2017-06-28 08:06:15 +00:00
static const struct mCoreMemoryBlock _GBCMemoryBlocks [ ] = {
2017-06-05 22:20:58 +00:00
{ - 1 , " mem " , " All " , " All " , 0 , 0x10000 , 0x10000 , mCORE_MEMORY_VIRTUAL } ,
{ GB_REGION_CART_BANK0 , " cart0 " , " ROM Bank " , " Game Pak (32kiB) " , GB_BASE_CART_BANK0 , GB_SIZE_CART_BANK0 * 2 , 0x800000 , mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED , 511 } ,
{ GB_REGION_VRAM , " vram " , " VRAM " , " Video RAM (8kiB) " , GB_BASE_VRAM , GB_BASE_VRAM + GB_SIZE_VRAM , GB_SIZE_VRAM * 2 , mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED , 1 } ,
{ GB_REGION_EXTERNAL_RAM , " sram " , " SRAM " , " External RAM (8kiB) " , GB_BASE_EXTERNAL_RAM , GB_BASE_EXTERNAL_RAM + GB_SIZE_EXTERNAL_RAM , GB_SIZE_EXTERNAL_RAM * 4 , mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED , 3 } ,
{ GB_REGION_WORKING_RAM_BANK0 , " wram " , " WRAM " , " Working RAM (8kiB) " , GB_BASE_WORKING_RAM_BANK0 , GB_BASE_WORKING_RAM_BANK0 + GB_SIZE_WORKING_RAM_BANK0 * 2 , GB_SIZE_WORKING_RAM_BANK0 * 8 , mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED , 7 } ,
{ GB_BASE_OAM , " oam " , " OAM " , " OBJ Attribute Memory " , GB_BASE_OAM , GB_BASE_OAM + GB_SIZE_OAM , GB_SIZE_OAM , mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED } ,
{ GB_BASE_IO , " io " , " MMIO " , " Memory-Mapped I/O " , GB_BASE_IO , GB_BASE_IO + GB_SIZE_IO , GB_SIZE_IO , mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED } ,
{ GB_BASE_HRAM , " hram " , " HRAM " , " High RAM " , GB_BASE_HRAM , GB_BASE_HRAM + GB_SIZE_HRAM , GB_SIZE_HRAM , mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED } ,
} ;
2017-04-23 04:41:48 +00:00
struct mVideoLogContext ;
2016-01-27 09:05:12 +00:00
struct GBCore {
struct mCore d ;
struct GBVideoSoftwareRenderer renderer ;
2017-04-18 08:55:32 +00:00
struct GBVideoProxyRenderer proxyRenderer ;
struct mVideoLogContext * logContext ;
struct mCoreCallbacks logCallbacks ;
2016-01-27 09:05:12 +00:00
uint8_t keys ;
2016-04-26 05:34:14 +00:00
struct mCPUComponent * components [ CPU_COMPONENT_MAX ] ;
2016-09-09 23:29:52 +00:00
const struct Configuration * overrides ;
2016-04-26 05:34:14 +00:00
struct mDebuggerPlatform * debuggerPlatform ;
2016-05-08 08:34:51 +00:00
struct mCheatDevice * cheatDevice ;
2016-01-27 09:05:12 +00:00
} ;
static bool _GBCoreInit ( struct mCore * core ) {
struct GBCore * gbcore = ( struct GBCore * ) core ;
struct LR35902Core * cpu = anonymousMemoryMap ( sizeof ( struct LR35902Core ) ) ;
struct GB * gb = anonymousMemoryMap ( sizeof ( struct GB ) ) ;
if ( ! cpu | | ! gb ) {
free ( cpu ) ;
free ( gb ) ;
return false ;
}
core - > cpu = cpu ;
core - > board = gb ;
2016-09-09 23:29:52 +00:00
gbcore - > overrides = NULL ;
2016-04-26 05:34:14 +00:00
gbcore - > debuggerPlatform = NULL ;
2016-05-08 08:34:51 +00:00
gbcore - > cheatDevice = NULL ;
2016-01-27 09:05:12 +00:00
GBCreate ( gb ) ;
2016-04-26 05:34:14 +00:00
memset ( gbcore - > components , 0 , sizeof ( gbcore - > components ) ) ;
LR35902SetComponents ( cpu , & gb - > d , CPU_COMPONENT_MAX , gbcore - > components ) ;
2016-01-27 09:05:12 +00:00
LR35902Init ( cpu ) ;
2017-02-15 18:53:37 +00:00
mRTCGenericSourceInit ( & core - > rtc , core ) ;
gb - > memory . rtc = & core - > rtc . d ;
2016-01-27 09:05:12 +00:00
GBVideoSoftwareRendererCreate ( & gbcore - > renderer ) ;
2016-05-29 19:33:40 +00:00
gbcore - > renderer . outputBuffer = NULL ;
2016-01-27 09:05:12 +00:00
2016-02-14 19:30:49 +00:00
gbcore - > keys = 0 ;
2016-01-27 09:05:12 +00:00
gb - > keySource = & gbcore - > keys ;
2016-02-04 04:56:08 +00:00
# if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
mDirectorySetInit ( & core - > dirs ) ;
# endif
2016-01-27 09:05:12 +00:00
return true ;
}
static void _GBCoreDeinit ( struct mCore * core ) {
LR35902Deinit ( core - > cpu ) ;
GBDestroy ( core - > board ) ;
mappedMemoryFree ( core - > cpu , sizeof ( struct LR35902Core ) ) ;
mappedMemoryFree ( core - > board , sizeof ( struct GB ) ) ;
2017-05-23 04:47:43 +00:00
# if defined USE_DEBUGGERS && (!defined(MINIMAL_CORE) || MINIMAL_CORE < 2)
2016-02-04 04:56:08 +00:00
mDirectorySetDeinit ( & core - > dirs ) ;
2017-05-23 04:47:43 +00:00
if ( core - > symbolTable ) {
mDebuggerSymbolTableDestroy ( core - > symbolTable ) ;
}
2016-02-04 04:56:08 +00:00
# endif
2016-05-08 08:34:51 +00:00
struct GBCore * gbcore = ( struct GBCore * ) core ;
free ( gbcore - > debuggerPlatform ) ;
if ( gbcore - > cheatDevice ) {
mCheatDeviceDestroy ( gbcore - > cheatDevice ) ;
}
free ( gbcore - > cheatDevice ) ;
2016-09-07 18:04:31 +00:00
mCoreConfigFreeOpts ( & core - > opts ) ;
2016-03-03 08:04:36 +00:00
free ( core ) ;
2016-01-27 09:05:12 +00:00
}
2016-09-20 23:21:52 +00:00
static enum mPlatform _GBCorePlatform ( const struct mCore * core ) {
2016-02-10 06:03:31 +00:00
UNUSED ( core ) ;
return PLATFORM_GB ;
}
2016-02-04 04:03:04 +00:00
static void _GBCoreSetSync ( struct mCore * core , struct mCoreSync * sync ) {
struct GB * gb = core - > board ;
gb - > sync = sync ;
}
2016-02-08 04:07:08 +00:00
static void _GBCoreLoadConfig ( struct mCore * core , const struct mCoreConfig * config ) {
UNUSED ( config ) ;
2016-02-10 07:29:25 +00:00
struct GB * gb = core - > board ;
2016-02-21 16:50:21 +00:00
if ( core - > opts . mute ) {
gb - > audio . masterVolume = 0 ;
} else {
gb - > audio . masterVolume = core - > opts . volume ;
}
2016-02-15 01:37:53 +00:00
gb - > video . frameskip = core - > opts . frameskip ;
2017-04-03 21:32:21 +00:00
int color ;
2017-07-28 21:29:56 +00:00
if ( mCoreConfigGetIntValue ( config , " gb.pal[0] " , & color ) ) {
GBVideoSetPalette ( & gb - > video , 0 , color ) ;
2017-04-03 21:32:21 +00:00
}
2017-07-28 21:29:56 +00:00
if ( mCoreConfigGetIntValue ( config , " gb.pal[1] " , & color ) ) {
GBVideoSetPalette ( & gb - > video , 1 , color ) ;
2017-04-03 21:32:21 +00:00
}
2017-07-28 21:29:56 +00:00
if ( mCoreConfigGetIntValue ( config , " gb.pal[2] " , & color ) ) {
GBVideoSetPalette ( & gb - > video , 2 , color ) ;
2017-04-03 21:32:21 +00:00
}
2017-07-28 21:29:56 +00:00
if ( mCoreConfigGetIntValue ( config , " gb.pal[3] " , & color ) ) {
GBVideoSetPalette ( & gb - > video , 3 , color ) ;
2017-04-03 21:32:21 +00:00
}
2017-01-23 17:57:41 +00:00
mCoreConfigCopyValue ( & core - > config , config , " gb.bios " ) ;
2017-08-03 00:00:29 +00:00
mCoreConfigCopyValue ( & core - > config , config , " sgb.bios " ) ;
2017-01-23 17:57:41 +00:00
mCoreConfigCopyValue ( & core - > config , config , " gbc.bios " ) ;
2017-08-05 14:56:36 +00:00
mCoreConfigCopyValue ( & core - > config , config , " gb.model " ) ;
mCoreConfigCopyValue ( & core - > config , config , " sgb.model " ) ;
mCoreConfigCopyValue ( & core - > config , config , " cgb.model " ) ;
2016-05-20 05:31:13 +00:00
2017-08-05 15:52:09 +00:00
int fakeBool ;
if ( mCoreConfigGetIntValue ( config , " sgb.borders " , & fakeBool ) ) {
gb - > video . sgbBorders = fakeBool ;
}
2016-05-20 05:31:13 +00:00
# if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
2016-09-09 23:29:52 +00:00
struct GBCore * gbcore = ( struct GBCore * ) core ;
gbcore - > overrides = mCoreConfigGetOverridesConst ( config ) ;
2016-05-20 05:31:13 +00:00
# endif
2016-02-05 05:58:45 +00:00
}
2016-01-27 09:05:12 +00:00
static void _GBCoreDesiredVideoDimensions ( struct mCore * core , unsigned * width , unsigned * height ) {
2017-08-02 02:01:44 +00:00
struct GB * gb = core - > board ;
2017-08-21 06:08:35 +00:00
if ( gb & & ( gb - > model ! = GB_MODEL_SGB | | ! gb - > video . sgbBorders ) ) {
2017-08-02 02:01:44 +00:00
* width = GB_VIDEO_HORIZONTAL_PIXELS ;
* height = GB_VIDEO_VERTICAL_PIXELS ;
} else {
* width = 256 ;
* height = 224 ;
}
2016-01-27 09:05:12 +00:00
}
2016-02-01 04:22:18 +00:00
static void _GBCoreSetVideoBuffer ( struct mCore * core , color_t * buffer , size_t stride ) {
2016-01-27 09:05:12 +00:00
struct GBCore * gbcore = ( struct GBCore * ) core ;
gbcore - > renderer . outputBuffer = buffer ;
gbcore - > renderer . outputBufferStride = stride ;
}
2016-09-17 10:37:04 +00:00
static void _GBCoreGetPixels ( struct mCore * core , const void * * buffer , size_t * stride ) {
2016-02-07 23:29:02 +00:00
struct GBCore * gbcore = ( struct GBCore * ) core ;
2016-09-17 10:37:04 +00:00
gbcore - > renderer . d . getPixels ( & gbcore - > renderer . d , stride , buffer ) ;
}
static void _GBCorePutPixels ( struct mCore * core , const void * buffer , size_t stride ) {
struct GBCore * gbcore = ( struct GBCore * ) core ;
gbcore - > renderer . d . putPixels ( & gbcore - > renderer . d , stride , buffer ) ;
2016-02-07 23:29:02 +00:00
}
2016-02-04 08:49:45 +00:00
static struct blip_t * _GBCoreGetAudioChannel ( struct mCore * core , int ch ) {
struct GB * gb = core - > board ;
switch ( ch ) {
case 0 :
return gb - > audio . left ;
case 1 :
return gb - > audio . right ;
default :
return NULL ;
}
}
2016-02-09 05:21:17 +00:00
static void _GBCoreSetAudioBufferSize ( struct mCore * core , size_t samples ) {
struct GB * gb = core - > board ;
GBAudioResizeBuffer ( & gb - > audio , samples ) ;
}
2016-02-10 04:20:14 +00:00
static size_t _GBCoreGetAudioBufferSize ( struct mCore * core ) {
struct GB * gb = core - > board ;
return gb - > audio . samples ;
}
2017-02-08 19:34:05 +00:00
static void _GBCoreAddCoreCallbacks ( struct mCore * core , struct mCoreCallbacks * coreCallbacks ) {
2016-10-21 00:35:32 +00:00
struct GB * gb = core - > board ;
2017-02-08 19:34:05 +00:00
* mCoreCallbacksListAppend ( & gb - > coreCallbacks ) = * coreCallbacks ;
}
static void _GBCoreClearCoreCallbacks ( struct mCore * core ) {
struct GB * gb = core - > board ;
mCoreCallbacksListClear ( & gb - > coreCallbacks ) ;
2016-10-21 00:35:32 +00:00
}
2016-02-08 06:41:10 +00:00
static void _GBCoreSetAVStream ( struct mCore * core , struct mAVStream * stream ) {
2016-02-15 06:50:08 +00:00
struct GB * gb = core - > board ;
gb - > stream = stream ;
2016-02-16 06:19:15 +00:00
if ( stream & & stream - > videoDimensionsChanged ) {
stream - > videoDimensionsChanged ( stream , GB_VIDEO_HORIZONTAL_PIXELS , GB_VIDEO_VERTICAL_PIXELS ) ;
}
2016-02-08 06:41:10 +00:00
}
2016-02-04 04:56:08 +00:00
static bool _GBCoreLoadROM ( struct mCore * core , struct VFile * vf ) {
return GBLoadROM ( core - > board , vf ) ;
2016-01-27 09:05:12 +00:00
}
2016-02-09 04:46:23 +00:00
static bool _GBCoreLoadBIOS ( struct mCore * core , struct VFile * vf , int type ) {
UNUSED ( type ) ;
2016-05-20 05:31:13 +00:00
GBLoadBIOS ( core - > board , vf ) ;
return true ;
2016-02-09 04:46:23 +00:00
}
2016-02-04 04:56:08 +00:00
static bool _GBCoreLoadSave ( struct mCore * core , struct VFile * vf ) {
return GBLoadSave ( core - > board , vf ) ;
2016-01-27 09:05:12 +00:00
}
2016-08-28 08:45:04 +00:00
static bool _GBCoreLoadTemporarySave ( struct mCore * core , struct VFile * vf ) {
struct GB * gb = core - > board ;
2016-09-18 07:09:15 +00:00
GBSavedataMask ( gb , vf , false ) ;
2016-08-28 08:45:04 +00:00
return true ; // TODO: Return a real value
}
2016-02-04 05:33:50 +00:00
static bool _GBCoreLoadPatch ( struct mCore * core , struct VFile * vf ) {
2016-02-06 10:30:58 +00:00
if ( ! vf ) {
return false ;
}
struct Patch patch ;
if ( ! loadPatch ( vf , & patch ) ) {
return false ;
}
GBApplyPatch ( core - > board , & patch ) ;
return true ;
2016-02-04 05:33:50 +00:00
}
2016-01-27 09:05:12 +00:00
static void _GBCoreUnloadROM ( struct mCore * core ) {
2016-09-19 14:26:06 +00:00
struct GBCore * gbcore = ( struct GBCore * ) core ;
struct LR35902Core * cpu = core - > cpu ;
if ( gbcore - > cheatDevice ) {
LR35902HotplugDetach ( cpu , CPU_COMPONENT_CHEAT_DEVICE ) ;
cpu - > components [ CPU_COMPONENT_CHEAT_DEVICE ] = NULL ;
mCheatDeviceDestroy ( gbcore - > cheatDevice ) ;
gbcore - > cheatDevice = NULL ;
}
2016-01-27 09:05:12 +00:00
return GBUnloadROM ( core - > board ) ;
}
2017-01-18 02:29:58 +00:00
static void _GBCoreChecksum ( const struct mCore * core , void * data , enum mCoreChecksumType type ) {
struct GB * gb = ( struct GB * ) core - > board ;
switch ( type ) {
case CHECKSUM_CRC32 :
memcpy ( data , & gb - > romCrc32 , sizeof ( gb - > romCrc32 ) ) ;
break ;
}
return ;
}
2016-01-27 09:05:12 +00:00
static void _GBCoreReset ( struct mCore * core ) {
2016-02-05 08:11:24 +00:00
struct GBCore * gbcore = ( struct GBCore * ) core ;
struct GB * gb = ( struct GB * ) core - > board ;
2016-02-15 03:02:45 +00:00
if ( gbcore - > renderer . outputBuffer ) {
GBVideoAssociateRenderer ( & gb - > video , & gbcore - > renderer . d ) ;
}
2016-09-09 23:29:52 +00:00
2016-10-22 02:14:09 +00:00
if ( gb - > memory . rom ) {
struct GBCartridgeOverride override ;
const struct GBCartridge * cart = ( const struct GBCartridge * ) & gb - > memory . rom [ 0x100 ] ;
2016-09-09 23:29:52 +00:00
override . headerCrc32 = doCrc32 ( cart , sizeof ( * cart ) ) ;
if ( GBOverrideFind ( gbcore - > overrides , & override ) ) {
GBOverrideApply ( gb , & override ) ;
}
}
2017-08-05 14:56:36 +00:00
const char * modelGB = mCoreConfigGetValue ( & core - > config , " gb.model " ) ;
const char * modelCGB = mCoreConfigGetValue ( & core - > config , " cgb.model " ) ;
const char * modelSGB = mCoreConfigGetValue ( & core - > config , " sgb.model " ) ;
if ( modelGB | | modelCGB | | modelSGB ) {
GBDetectModel ( gb ) ;
if ( gb - > model = = GB_MODEL_DMG & & modelGB ) {
gb - > model = GBNameToModel ( modelGB ) ;
} else if ( gb - > model = = GB_MODEL_CGB & & modelCGB ) {
gb - > model = GBNameToModel ( modelCGB ) ;
} else if ( gb - > model = = GB_MODEL_SGB & & modelSGB ) {
gb - > model = GBNameToModel ( modelSGB ) ;
}
}
2016-09-09 23:30:48 +00:00
# if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
2017-01-23 17:57:41 +00:00
if ( ! gb - > biosVf & & core - > opts . useBios ) {
struct VFile * bios = NULL ;
2016-09-17 17:37:05 +00:00
bool found = false ;
if ( core - > opts . bios ) {
bios = VFileOpen ( core - > opts . bios , O_RDONLY ) ;
if ( bios & & GBIsBIOS ( bios ) ) {
found = true ;
} else if ( bios ) {
bios - > close ( bios ) ;
bios = NULL ;
}
}
if ( ! found ) {
2016-09-09 23:30:48 +00:00
GBDetectModel ( gb ) ;
2017-03-22 22:47:33 +00:00
const char * configPath = NULL ;
2017-01-23 17:57:41 +00:00
switch ( gb - > model ) {
case GB_MODEL_DMG :
2017-08-03 00:00:29 +00:00
case GB_MODEL_MGB : // TODO
2017-01-23 17:57:41 +00:00
configPath = mCoreConfigGetValue ( & core - > config , " gb.bios " ) ;
break ;
2017-08-03 00:00:29 +00:00
case GB_MODEL_SGB :
case GB_MODEL_SGB2 : // TODO
configPath = mCoreConfigGetValue ( & core - > config , " sgb.bios " ) ;
break ;
2017-01-23 17:57:41 +00:00
case GB_MODEL_CGB :
case GB_MODEL_AGB :
configPath = mCoreConfigGetValue ( & core - > config , " gbc.bios " ) ;
break ;
default :
break ;
} ;
2017-03-21 00:37:20 +00:00
if ( configPath ) {
bios = VFileOpen ( configPath , O_RDONLY ) ;
}
2017-01-23 17:57:41 +00:00
if ( bios & & GBIsBIOS ( bios ) ) {
found = true ;
} else if ( bios ) {
bios - > close ( bios ) ;
bios = NULL ;
}
}
if ( ! found ) {
char path [ PATH_MAX ] ;
2016-09-09 23:30:48 +00:00
mCoreConfigDirectory ( path , PATH_MAX ) ;
switch ( gb - > model ) {
case GB_MODEL_DMG :
2017-08-03 00:00:29 +00:00
case GB_MODEL_MGB : // TODO
2016-09-09 23:30:48 +00:00
strncat ( path , PATH_SEP " gb_bios.bin " , PATH_MAX - strlen ( path ) ) ;
break ;
2017-08-03 00:00:29 +00:00
case GB_MODEL_SGB :
case GB_MODEL_SGB2 : // TODO
strncat ( path , PATH_SEP " sgb_bios.bin " , PATH_MAX - strlen ( path ) ) ;
break ;
2016-09-09 23:30:48 +00:00
case GB_MODEL_CGB :
case GB_MODEL_AGB :
strncat ( path , PATH_SEP " gbc_bios.bin " , PATH_MAX - strlen ( path ) ) ;
break ;
default :
break ;
} ;
bios = VFileOpen ( path , O_RDONLY ) ;
2017-01-23 17:57:41 +00:00
if ( bios & & GBIsBIOS ( bios ) ) {
found = true ;
} else if ( bios ) {
bios - > close ( bios ) ;
bios = NULL ;
}
}
if ( bios ) {
GBLoadBIOS ( gb , bios ) ;
2016-09-09 23:30:48 +00:00
}
}
# endif
2016-01-27 09:05:12 +00:00
LR35902Reset ( core - > cpu ) ;
}
static void _GBCoreRunFrame ( struct mCore * core ) {
struct GB * gb = core - > board ;
int32_t frameCounter = gb - > video . frameCounter ;
while ( gb - > video . frameCounter = = frameCounter ) {
LR35902Run ( core - > cpu ) ;
}
}
static void _GBCoreRunLoop ( struct mCore * core ) {
LR35902Run ( core - > cpu ) ;
}
static void _GBCoreStep ( struct mCore * core ) {
2016-05-24 02:09:20 +00:00
struct LR35902Core * cpu = core - > cpu ;
do {
LR35902Tick ( cpu ) ;
} while ( cpu - > executionState ! = LR35902_CORE_FETCH ) ;
2016-01-27 09:05:12 +00:00
}
2016-05-30 22:03:20 +00:00
static size_t _GBCoreStateSize ( struct mCore * core ) {
2016-02-04 10:31:50 +00:00
UNUSED ( core ) ;
2016-05-30 22:03:20 +00:00
return sizeof ( struct GBSerializedState ) ;
2016-02-04 10:31:50 +00:00
}
2016-05-30 22:03:20 +00:00
static bool _GBCoreLoadState ( struct mCore * core , const void * state ) {
return GBDeserialize ( core - > board , state ) ;
}
static bool _GBCoreSaveState ( struct mCore * core , void * state ) {
2016-08-30 06:24:03 +00:00
struct LR35902Core * cpu = core - > cpu ;
while ( cpu - > executionState ! = LR35902_CORE_FETCH ) {
LR35902Tick ( cpu ) ;
}
2016-05-31 06:06:32 +00:00
GBSerialize ( core - > board , state ) ;
return true ;
2016-02-04 10:31:50 +00:00
}
2016-01-27 09:05:12 +00:00
static void _GBCoreSetKeys ( struct mCore * core , uint32_t keys ) {
struct GBCore * gbcore = ( struct GBCore * ) core ;
gbcore - > keys = keys ;
2017-06-11 21:51:48 +00:00
GBTestKeypadIRQ ( core - > board ) ;
2016-01-27 09:05:12 +00:00
}
2016-02-03 04:59:56 +00:00
static void _GBCoreAddKeys ( struct mCore * core , uint32_t keys ) {
struct GBCore * gbcore = ( struct GBCore * ) core ;
gbcore - > keys | = keys ;
2017-06-11 21:51:48 +00:00
GBTestKeypadIRQ ( core - > board ) ;
2016-02-03 04:59:56 +00:00
}
static void _GBCoreClearKeys ( struct mCore * core , uint32_t keys ) {
struct GBCore * gbcore = ( struct GBCore * ) core ;
gbcore - > keys & = ~ keys ;
}
2016-09-20 23:21:52 +00:00
static int32_t _GBCoreFrameCounter ( const struct mCore * core ) {
const struct GB * gb = core - > board ;
2016-01-30 07:00:49 +00:00
return gb - > video . frameCounter ;
}
2016-09-20 23:21:52 +00:00
static int32_t _GBCoreFrameCycles ( const struct mCore * core ) {
2016-01-30 07:00:49 +00:00
UNUSED ( core ) ;
return GB_VIDEO_TOTAL_LENGTH ;
}
2016-09-20 23:21:52 +00:00
static int32_t _GBCoreFrequency ( const struct mCore * core ) {
2016-01-30 07:00:49 +00:00
UNUSED ( core ) ;
// TODO: GB differences
return DMG_LR35902_FREQUENCY ;
}
2016-09-20 23:21:52 +00:00
static void _GBCoreGetGameTitle ( const struct mCore * core , char * title ) {
2016-02-08 05:50:29 +00:00
GBGetGameTitle ( core - > board , title ) ;
}
2016-09-20 23:21:52 +00:00
static void _GBCoreGetGameCode ( const struct mCore * core , char * title ) {
2016-02-17 06:18:09 +00:00
GBGetGameCode ( core - > board , title ) ;
}
2017-04-10 02:37:43 +00:00
static void _GBCoreSetPeripheral ( struct mCore * core , int type , void * periph ) {
2016-02-19 05:54:06 +00:00
struct GB * gb = core - > board ;
2017-04-10 02:37:43 +00:00
switch ( type ) {
case mPERIPH_ROTATION :
gb - > memory . rotation = periph ;
break ;
case mPERIPH_RUMBLE :
gb - > memory . rumble = periph ;
break ;
2017-07-26 17:57:57 +00:00
case mPERIPH_IMAGE_SOURCE :
gb - > memory . cam = periph ;
break ;
2017-04-10 02:37:43 +00:00
default :
return ;
}
2016-02-21 02:46:39 +00:00
}
2016-04-26 04:47:40 +00:00
static uint32_t _GBCoreBusRead8 ( struct mCore * core , uint32_t address ) {
struct LR35902Core * cpu = core - > cpu ;
return cpu - > memory . load8 ( cpu , address ) ;
}
static uint32_t _GBCoreBusRead16 ( struct mCore * core , uint32_t address ) {
struct LR35902Core * cpu = core - > cpu ;
return cpu - > memory . load8 ( cpu , address ) | ( cpu - > memory . load8 ( cpu , address + 1 ) < < 8 ) ;
}
static uint32_t _GBCoreBusRead32 ( struct mCore * core , uint32_t address ) {
struct LR35902Core * cpu = core - > cpu ;
return cpu - > memory . load8 ( cpu , address ) | ( cpu - > memory . load8 ( cpu , address + 1 ) < < 8 ) |
( cpu - > memory . load8 ( cpu , address + 2 ) < < 16 ) | ( cpu - > memory . load8 ( cpu , address + 3 ) < < 24 ) ;
}
static void _GBCoreBusWrite8 ( struct mCore * core , uint32_t address , uint8_t value ) {
struct LR35902Core * cpu = core - > cpu ;
cpu - > memory . store8 ( cpu , address , value ) ;
}
static void _GBCoreBusWrite16 ( struct mCore * core , uint32_t address , uint16_t value ) {
struct LR35902Core * cpu = core - > cpu ;
cpu - > memory . store8 ( cpu , address , value ) ;
cpu - > memory . store8 ( cpu , address + 1 , value > > 8 ) ;
}
static void _GBCoreBusWrite32 ( struct mCore * core , uint32_t address , uint32_t value ) {
struct LR35902Core * cpu = core - > cpu ;
cpu - > memory . store8 ( cpu , address , value ) ;
cpu - > memory . store8 ( cpu , address + 1 , value > > 8 ) ;
cpu - > memory . store8 ( cpu , address + 2 , value > > 16 ) ;
cpu - > memory . store8 ( cpu , address + 3 , value > > 24 ) ;
}
2016-08-23 20:14:14 +00:00
static uint32_t _GBCoreRawRead8 ( struct mCore * core , uint32_t address , int segment ) {
2016-05-06 06:52:28 +00:00
struct LR35902Core * cpu = core - > cpu ;
2016-08-23 20:14:14 +00:00
return GBView8 ( cpu , address , segment ) ;
2016-05-06 06:52:28 +00:00
}
2016-08-23 20:14:14 +00:00
static uint32_t _GBCoreRawRead16 ( struct mCore * core , uint32_t address , int segment ) {
2016-05-06 06:52:28 +00:00
struct LR35902Core * cpu = core - > cpu ;
2016-08-23 20:14:14 +00:00
return GBView8 ( cpu , address , segment ) | ( GBView8 ( cpu , address + 1 , segment ) < < 8 ) ;
2016-05-06 06:52:28 +00:00
}
2016-08-23 20:14:14 +00:00
static uint32_t _GBCoreRawRead32 ( struct mCore * core , uint32_t address , int segment ) {
2016-05-06 06:52:28 +00:00
struct LR35902Core * cpu = core - > cpu ;
2016-08-23 20:14:14 +00:00
return GBView8 ( cpu , address , segment ) | ( GBView8 ( cpu , address + 1 , segment ) < < 8 ) |
( GBView8 ( cpu , address + 2 , segment ) < < 16 ) | ( GBView8 ( cpu , address + 3 , segment ) < < 24 ) ;
2016-05-06 06:52:28 +00:00
}
2016-08-23 20:14:14 +00:00
static void _GBCoreRawWrite8 ( struct mCore * core , uint32_t address , int segment , uint8_t value ) {
2016-05-09 05:44:56 +00:00
struct LR35902Core * cpu = core - > cpu ;
2016-09-17 01:17:29 +00:00
GBPatch8 ( cpu , address , value , NULL , segment ) ;
2016-05-09 05:44:56 +00:00
}
2016-08-23 20:14:14 +00:00
static void _GBCoreRawWrite16 ( struct mCore * core , uint32_t address , int segment , uint16_t value ) {
2016-05-09 05:44:56 +00:00
struct LR35902Core * cpu = core - > cpu ;
2016-09-17 01:17:29 +00:00
GBPatch8 ( cpu , address , value , NULL , segment ) ;
GBPatch8 ( cpu , address + 1 , value > > 8 , NULL , segment ) ;
2016-05-09 05:44:56 +00:00
}
2016-08-23 20:14:14 +00:00
static void _GBCoreRawWrite32 ( struct mCore * core , uint32_t address , int segment , uint32_t value ) {
2016-05-09 05:44:56 +00:00
struct LR35902Core * cpu = core - > cpu ;
2016-09-17 01:17:29 +00:00
GBPatch8 ( cpu , address , value , NULL , segment ) ;
GBPatch8 ( cpu , address + 1 , value > > 8 , NULL , segment ) ;
GBPatch8 ( cpu , address + 2 , value > > 16 , NULL , segment ) ;
GBPatch8 ( cpu , address + 3 , value > > 24 , NULL , segment ) ;
2016-05-09 05:44:56 +00:00
}
2017-06-05 22:20:58 +00:00
size_t _GBListMemoryBlocks ( const struct mCore * core , const struct mCoreMemoryBlock * * blocks ) {
const struct GB * gb = core - > board ;
switch ( gb - > model ) {
case GB_MODEL_DMG :
2017-08-03 00:00:29 +00:00
case GB_MODEL_MGB :
2017-06-05 22:20:58 +00:00
case GB_MODEL_SGB :
2017-08-03 00:00:29 +00:00
case GB_MODEL_SGB2 :
2017-06-05 22:20:58 +00:00
default :
* blocks = _GBMemoryBlocks ;
return sizeof ( _GBMemoryBlocks ) / sizeof ( * _GBMemoryBlocks ) ;
case GB_MODEL_CGB :
case GB_MODEL_AGB :
* blocks = _GBCMemoryBlocks ;
return sizeof ( _GBCMemoryBlocks ) / sizeof ( * _GBCMemoryBlocks ) ;
}
}
void * _GBGetMemoryBlock ( struct mCore * core , size_t id , size_t * sizeOut ) {
struct GB * gb = core - > board ;
bool isCgb = gb - > model > = GB_MODEL_CGB ;
switch ( id ) {
default :
return NULL ;
case GB_REGION_CART_BANK0 :
* sizeOut = gb - > memory . romSize ;
return gb - > memory . rom ;
case GB_REGION_VRAM :
* sizeOut = GB_SIZE_WORKING_RAM_BANK0 * ( isCgb ? 1 : 2 ) ;
return gb - > video . vram ;
case GB_REGION_EXTERNAL_RAM :
* sizeOut = gb - > sramSize ;
return gb - > memory . sram ;
case GB_REGION_WORKING_RAM_BANK0 :
* sizeOut = GB_SIZE_VRAM * ( isCgb ? 8 : 2 ) ;
return gb - > memory . wram ;
case GB_BASE_OAM :
* sizeOut = GB_SIZE_OAM ;
return gb - > video . oam . raw ;
case GB_BASE_HRAM :
* sizeOut = GB_SIZE_HRAM ;
return gb - > memory . hram ;
}
}
2016-10-27 06:28:25 +00:00
# ifdef USE_DEBUGGERS
2016-04-26 04:47:40 +00:00
static bool _GBCoreSupportsDebuggerType ( struct mCore * core , enum mDebuggerType type ) {
2016-04-26 05:34:14 +00:00
UNUSED ( core ) ;
switch ( type ) {
case DEBUGGER_CLI :
return true ;
default :
return false ;
}
2016-04-26 04:47:40 +00:00
}
static struct mDebuggerPlatform * _GBCoreDebuggerPlatform ( struct mCore * core ) {
2016-04-26 05:34:14 +00:00
struct GBCore * gbcore = ( struct GBCore * ) core ;
2017-06-03 02:37:36 +00:00
struct GB * gb = core - > board ;
2016-04-26 05:34:14 +00:00
if ( ! gbcore - > debuggerPlatform ) {
2017-06-03 02:37:36 +00:00
struct LR35902Debugger * platform = ( struct LR35902Debugger * ) LR35902DebuggerPlatformCreate ( ) ;
if ( gb - > model > = GB_MODEL_CGB ) {
platform - > segments = _GBCSegments ;
} else {
platform - > segments = _GBSegments ;
}
gbcore - > debuggerPlatform = & platform - > d ;
2016-04-26 05:34:14 +00:00
}
return gbcore - > debuggerPlatform ;
}
static struct CLIDebuggerSystem * _GBCoreCliDebuggerSystem ( struct mCore * core ) {
return GBCLIDebuggerCreate ( core ) ;
}
static void _GBCoreAttachDebugger ( struct mCore * core , struct mDebugger * debugger ) {
struct LR35902Core * cpu = core - > cpu ;
if ( core - > debugger ) {
LR35902HotplugDetach ( cpu , CPU_COMPONENT_DEBUGGER ) ;
}
cpu - > components [ CPU_COMPONENT_DEBUGGER ] = & debugger - > d ;
LR35902HotplugAttach ( cpu , CPU_COMPONENT_DEBUGGER ) ;
core - > debugger = debugger ;
}
static void _GBCoreDetachDebugger ( struct mCore * core ) {
struct LR35902Core * cpu = core - > cpu ;
2016-09-19 14:26:06 +00:00
if ( core - > debugger ) {
LR35902HotplugDetach ( cpu , CPU_COMPONENT_DEBUGGER ) ;
}
2016-04-26 05:34:14 +00:00
cpu - > components [ CPU_COMPONENT_DEBUGGER ] = NULL ;
core - > debugger = NULL ;
2016-04-26 04:47:40 +00:00
}
2017-05-23 04:47:43 +00:00
static void _GBCoreLoadSymbols ( struct mCore * core , struct VFile * vf ) {
core - > symbolTable = mDebuggerSymbolTableCreate ( ) ;
# if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
if ( ! vf ) {
vf = mDirectorySetOpenSuffix ( & core - > dirs , core - > dirs . base , " .sym " , O_RDONLY ) ;
}
# endif
if ( ! vf ) {
return ;
}
GBLoadSymbols ( core - > symbolTable , vf ) ;
}
2016-10-27 06:28:25 +00:00
# endif
2016-04-26 04:47:40 +00:00
2016-05-08 08:34:51 +00:00
static struct mCheatDevice * _GBCoreCheatDevice ( struct mCore * core ) {
struct GBCore * gbcore = ( struct GBCore * ) core ;
if ( ! gbcore - > cheatDevice ) {
gbcore - > cheatDevice = GBCheatDeviceCreate ( ) ;
( ( struct LR35902Core * ) core - > cpu ) - > components [ CPU_COMPONENT_CHEAT_DEVICE ] = & gbcore - > cheatDevice - > d ;
LR35902HotplugAttach ( core - > cpu , CPU_COMPONENT_CHEAT_DEVICE ) ;
gbcore - > cheatDevice - > p = core ;
}
return gbcore - > cheatDevice ;
}
2016-05-31 06:16:00 +00:00
static size_t _GBCoreSavedataClone ( struct mCore * core , void * * sram ) {
struct GB * gb = core - > board ;
struct VFile * vf = gb - > sramVf ;
if ( vf ) {
* sram = malloc ( vf - > size ( vf ) ) ;
vf - > seek ( vf , 0 , SEEK_SET ) ;
return vf - > read ( vf , * sram , vf - > size ( vf ) ) ;
}
2016-09-06 18:15:27 +00:00
* sram = malloc ( gb - > sramSize ) ;
memcpy ( * sram , gb - > memory . sram , gb - > sramSize ) ;
return gb - > sramSize ;
2016-05-31 06:16:00 +00:00
}
2016-09-18 07:09:15 +00:00
static bool _GBCoreSavedataRestore ( struct mCore * core , const void * sram , size_t size , bool writeback ) {
2016-05-31 06:16:00 +00:00
struct GB * gb = core - > board ;
2016-09-18 07:09:15 +00:00
if ( ! writeback ) {
2016-09-25 20:39:52 +00:00
struct VFile * vf = VFileMemChunk ( sram , size ) ;
2016-09-18 07:09:15 +00:00
GBSavedataMask ( gb , vf , true ) ;
return true ;
}
2016-05-31 06:16:00 +00:00
struct VFile * vf = gb - > sramVf ;
if ( vf ) {
vf - > seek ( vf , 0 , SEEK_SET ) ;
return vf - > write ( vf , sram , size ) > 0 ;
}
if ( size > 0x20000 ) {
size = 0x20000 ;
}
2016-09-06 18:15:27 +00:00
GBResizeSram ( gb , size ) ;
memcpy ( gb - > memory . sram , sram , size ) ;
2016-05-31 06:16:00 +00:00
return true ;
}
2017-04-12 20:28:21 +00:00
static size_t _GBCoreListVideoLayers ( const struct mCore * core , const struct mCoreChannelInfo * * info ) {
UNUSED ( core ) ;
* info = _GBVideoLayers ;
return sizeof ( _GBVideoLayers ) / sizeof ( * _GBVideoLayers ) ;
}
static size_t _GBCoreListAudioChannels ( const struct mCore * core , const struct mCoreChannelInfo * * info ) {
UNUSED ( core ) ;
* info = _GBAudioChannels ;
return sizeof ( _GBAudioChannels ) / sizeof ( * _GBAudioChannels ) ;
}
static void _GBCoreEnableVideoLayer ( struct mCore * core , size_t id , bool enable ) {
struct GB * gb = core - > board ;
2017-04-22 00:30:30 +00:00
switch ( id ) {
case 0 :
gb - > video . renderer - > disableBG = ! enable ;
break ;
case 1 :
gb - > video . renderer - > disableOBJ = ! enable ;
break ;
case 2 :
gb - > video . renderer - > disableWIN = ! enable ;
break ;
default :
break ;
}
2017-04-12 20:28:21 +00:00
}
static void _GBCoreEnableAudioChannel ( struct mCore * core , size_t id , bool enable ) {
struct GB * gb = core - > board ;
switch ( id ) {
case 0 :
case 1 :
case 2 :
case 3 :
gb - > audio . forceDisableCh [ id ] = ! enable ;
break ;
default :
break ;
}
}
2017-04-18 08:55:32 +00:00
static void _GBCoreStartVideoLog ( struct mCore * core , struct mVideoLogContext * context ) {
struct GBCore * gbcore = ( struct GBCore * ) core ;
struct GB * gb = core - > board ;
gbcore - > logContext = context ;
2017-04-23 04:41:48 +00:00
int channelId = mVideoLoggerAddChannel ( context ) ;
2017-04-18 08:55:32 +00:00
gbcore - > proxyRenderer . logger = malloc ( sizeof ( struct mVideoLogger ) ) ;
mVideoLoggerRendererCreate ( gbcore - > proxyRenderer . logger , false ) ;
2017-04-23 04:41:48 +00:00
mVideoLoggerAttachChannel ( gbcore - > proxyRenderer . logger , context , channelId ) ;
2017-04-18 08:55:32 +00:00
gbcore - > proxyRenderer . logger - > block = false ;
GBVideoProxyRendererCreate ( & gbcore - > proxyRenderer , & gbcore - > renderer . d ) ;
GBVideoProxyRendererShim ( & gb - > video , & gbcore - > proxyRenderer ) ;
}
static void _GBCoreEndVideoLog ( struct mCore * core ) {
struct GBCore * gbcore = ( struct GBCore * ) core ;
struct GB * gb = core - > board ;
GBVideoProxyRendererUnshim ( & gb - > video , & gbcore - > proxyRenderer ) ;
free ( gbcore - > proxyRenderer . logger ) ;
gbcore - > proxyRenderer . logger = NULL ;
}
2016-01-27 09:05:12 +00:00
struct mCore * GBCoreCreate ( void ) {
struct GBCore * gbcore = malloc ( sizeof ( * gbcore ) ) ;
struct mCore * core = & gbcore - > d ;
2016-02-05 08:11:24 +00:00
memset ( & core - > opts , 0 , sizeof ( core - > opts ) ) ;
2016-04-26 04:47:40 +00:00
core - > cpu = NULL ;
core - > board = NULL ;
core - > debugger = NULL ;
2017-05-23 04:47:43 +00:00
core - > symbolTable = NULL ;
2016-01-27 09:05:12 +00:00
core - > init = _GBCoreInit ;
core - > deinit = _GBCoreDeinit ;
2016-02-10 06:03:31 +00:00
core - > platform = _GBCorePlatform ;
2016-02-04 04:03:04 +00:00
core - > setSync = _GBCoreSetSync ;
2016-02-05 05:58:45 +00:00
core - > loadConfig = _GBCoreLoadConfig ;
2016-01-27 09:05:12 +00:00
core - > desiredVideoDimensions = _GBCoreDesiredVideoDimensions ;
core - > setVideoBuffer = _GBCoreSetVideoBuffer ;
2016-09-17 10:37:04 +00:00
core - > getPixels = _GBCoreGetPixels ;
core - > putPixels = _GBCorePutPixels ;
2016-02-04 08:49:45 +00:00
core - > getAudioChannel = _GBCoreGetAudioChannel ;
2016-02-09 05:21:17 +00:00
core - > setAudioBufferSize = _GBCoreSetAudioBufferSize ;
2016-02-10 04:20:14 +00:00
core - > getAudioBufferSize = _GBCoreGetAudioBufferSize ;
2016-02-08 06:41:10 +00:00
core - > setAVStream = _GBCoreSetAVStream ;
2017-02-08 19:34:05 +00:00
core - > addCoreCallbacks = _GBCoreAddCoreCallbacks ;
core - > clearCoreCallbacks = _GBCoreClearCoreCallbacks ;
2016-02-04 04:56:08 +00:00
core - > isROM = GBIsROM ;
2016-01-27 09:05:12 +00:00
core - > loadROM = _GBCoreLoadROM ;
2016-02-09 04:46:23 +00:00
core - > loadBIOS = _GBCoreLoadBIOS ;
2016-02-04 04:56:08 +00:00
core - > loadSave = _GBCoreLoadSave ;
2016-08-28 08:45:04 +00:00
core - > loadTemporarySave = _GBCoreLoadTemporarySave ;
2016-02-04 05:33:50 +00:00
core - > loadPatch = _GBCoreLoadPatch ;
2016-01-27 09:05:12 +00:00
core - > unloadROM = _GBCoreUnloadROM ;
2017-01-18 02:29:58 +00:00
core - > checksum = _GBCoreChecksum ;
2016-01-27 09:05:12 +00:00
core - > reset = _GBCoreReset ;
core - > runFrame = _GBCoreRunFrame ;
core - > runLoop = _GBCoreRunLoop ;
core - > step = _GBCoreStep ;
2016-05-30 22:03:20 +00:00
core - > stateSize = _GBCoreStateSize ;
2016-02-04 10:31:50 +00:00
core - > loadState = _GBCoreLoadState ;
core - > saveState = _GBCoreSaveState ;
2016-01-27 09:05:12 +00:00
core - > setKeys = _GBCoreSetKeys ;
2016-02-03 04:59:56 +00:00
core - > addKeys = _GBCoreAddKeys ;
core - > clearKeys = _GBCoreClearKeys ;
2016-01-30 07:00:49 +00:00
core - > frameCounter = _GBCoreFrameCounter ;
core - > frameCycles = _GBCoreFrameCycles ;
core - > frequency = _GBCoreFrequency ;
2016-02-08 05:50:29 +00:00
core - > getGameTitle = _GBCoreGetGameTitle ;
2016-02-17 06:18:09 +00:00
core - > getGameCode = _GBCoreGetGameCode ;
2017-04-10 02:37:43 +00:00
core - > setPeripheral = _GBCoreSetPeripheral ;
2016-04-26 04:47:40 +00:00
core - > busRead8 = _GBCoreBusRead8 ;
core - > busRead16 = _GBCoreBusRead16 ;
core - > busRead32 = _GBCoreBusRead32 ;
core - > busWrite8 = _GBCoreBusWrite8 ;
core - > busWrite16 = _GBCoreBusWrite16 ;
core - > busWrite32 = _GBCoreBusWrite32 ;
2016-05-06 06:52:28 +00:00
core - > rawRead8 = _GBCoreRawRead8 ;
core - > rawRead16 = _GBCoreRawRead16 ;
core - > rawRead32 = _GBCoreRawRead32 ;
2016-05-09 05:44:56 +00:00
core - > rawWrite8 = _GBCoreRawWrite8 ;
core - > rawWrite16 = _GBCoreRawWrite16 ;
core - > rawWrite32 = _GBCoreRawWrite32 ;
2017-06-05 22:20:58 +00:00
core - > listMemoryBlocks = _GBListMemoryBlocks ;
core - > getMemoryBlock = _GBGetMemoryBlock ;
2016-10-27 06:28:25 +00:00
# ifdef USE_DEBUGGERS
2016-04-26 04:47:40 +00:00
core - > supportsDebuggerType = _GBCoreSupportsDebuggerType ;
core - > debuggerPlatform = _GBCoreDebuggerPlatform ;
2016-04-26 05:34:14 +00:00
core - > cliDebuggerSystem = _GBCoreCliDebuggerSystem ;
core - > attachDebugger = _GBCoreAttachDebugger ;
core - > detachDebugger = _GBCoreDetachDebugger ;
2017-05-23 04:47:43 +00:00
core - > loadSymbols = _GBCoreLoadSymbols ;
2016-10-27 06:28:25 +00:00
# endif
2016-05-08 08:34:51 +00:00
core - > cheatDevice = _GBCoreCheatDevice ;
2016-05-31 06:16:00 +00:00
core - > savedataClone = _GBCoreSavedataClone ;
2016-09-18 07:09:15 +00:00
core - > savedataRestore = _GBCoreSavedataRestore ;
2017-04-12 20:28:21 +00:00
core - > listVideoLayers = _GBCoreListVideoLayers ;
core - > listAudioChannels = _GBCoreListAudioChannels ;
core - > enableVideoLayer = _GBCoreEnableVideoLayer ;
core - > enableAudioChannel = _GBCoreEnableAudioChannel ;
2017-04-19 00:13:11 +00:00
# ifndef MINIMAL_CORE
2017-04-18 08:55:32 +00:00
core - > startVideoLog = _GBCoreStartVideoLog ;
core - > endVideoLog = _GBCoreEndVideoLog ;
2017-04-19 00:13:11 +00:00
# endif
2017-04-18 08:55:32 +00:00
return core ;
}
# ifndef MINIMAL_CORE
static void _GBVLPStartFrameCallback ( void * context ) {
struct mCore * core = context ;
struct GBCore * gbcore = ( struct GBCore * ) core ;
struct GB * gb = core - > board ;
if ( ! mVideoLoggerRendererRun ( gbcore - > proxyRenderer . logger , true ) ) {
GBVideoProxyRendererUnshim ( & gb - > video , & gbcore - > proxyRenderer ) ;
2017-04-23 04:41:48 +00:00
mVideoLogContextRewind ( gbcore - > logContext , core ) ;
2017-04-18 08:55:32 +00:00
GBVideoProxyRendererShim ( & gb - > video , & gbcore - > proxyRenderer ) ;
}
}
static bool _GBVLPInit ( struct mCore * core ) {
struct GBCore * gbcore = ( struct GBCore * ) core ;
if ( ! _GBCoreInit ( core ) ) {
return false ;
}
gbcore - > proxyRenderer . logger = malloc ( sizeof ( struct mVideoLogger ) ) ;
mVideoLoggerRendererCreate ( gbcore - > proxyRenderer . logger , true ) ;
GBVideoProxyRendererCreate ( & gbcore - > proxyRenderer , NULL ) ;
memset ( & gbcore - > logCallbacks , 0 , sizeof ( gbcore - > logCallbacks ) ) ;
gbcore - > logCallbacks . videoFrameStarted = _GBVLPStartFrameCallback ;
gbcore - > logCallbacks . context = core ;
core - > addCoreCallbacks ( core , & gbcore - > logCallbacks ) ;
return true ;
}
static void _GBVLPDeinit ( struct mCore * core ) {
struct GBCore * gbcore = ( struct GBCore * ) core ;
if ( gbcore - > logContext ) {
2017-04-23 04:41:48 +00:00
mVideoLogContextDestroy ( core , gbcore - > logContext ) ;
2017-04-18 08:55:32 +00:00
}
_GBCoreDeinit ( core ) ;
}
static void _GBVLPReset ( struct mCore * core ) {
struct GBCore * gbcore = ( struct GBCore * ) core ;
struct GB * gb = ( struct GB * ) core - > board ;
if ( gb - > video . renderer = = & gbcore - > proxyRenderer . d ) {
GBVideoProxyRendererUnshim ( & gb - > video , & gbcore - > proxyRenderer ) ;
} else if ( gbcore - > renderer . outputBuffer ) {
struct GBVideoRenderer * renderer = & gbcore - > renderer . d ;
GBVideoAssociateRenderer ( & gb - > video , renderer ) ;
}
LR35902Reset ( core - > cpu ) ;
2017-04-23 04:41:48 +00:00
mVideoLogContextRewind ( gbcore - > logContext , core ) ;
2017-04-18 08:55:32 +00:00
GBVideoProxyRendererShim ( & gb - > video , & gbcore - > proxyRenderer ) ;
2017-04-24 20:14:31 +00:00
// Make sure CPU loop never spins
GBHalt ( gb - > cpu ) ;
gb - > memory . ie = 0 ;
gb - > memory . ime = false ;
2017-04-18 08:55:32 +00:00
}
static bool _GBVLPLoadROM ( struct mCore * core , struct VFile * vf ) {
struct GBCore * gbcore = ( struct GBCore * ) core ;
2017-04-23 04:41:48 +00:00
gbcore - > logContext = mVideoLogContextCreate ( NULL ) ;
if ( ! mVideoLogContextLoad ( gbcore - > logContext , vf ) ) {
mVideoLogContextDestroy ( core , gbcore - > logContext ) ;
2017-04-18 08:55:32 +00:00
gbcore - > logContext = NULL ;
return false ;
}
2017-04-23 04:41:48 +00:00
mVideoLoggerAttachChannel ( gbcore - > proxyRenderer . logger , gbcore - > logContext , 0 ) ;
2017-04-18 08:55:32 +00:00
return true ;
}
2017-04-24 19:43:12 +00:00
static bool _GBVLPLoadState ( struct mCore * core , const void * buffer ) {
struct GB * gb = ( struct GB * ) core - > board ;
const struct GBSerializedState * state = buffer ;
gb - > timing . root = NULL ;
gb - > model = state - > model ;
gb - > cpu - > pc = GB_BASE_HRAM ;
gb - > cpu - > memory . setActiveRegion ( gb - > cpu , gb - > cpu - > pc ) ;
GBVideoDeserialize ( & gb - > video , state ) ;
GBIODeserialize ( gb , state ) ;
2017-04-24 19:44:51 +00:00
GBAudioReset ( & gb - > audio ) ;
2017-04-24 19:43:12 +00:00
// Make sure CPU loop never spins
GBHalt ( gb - > cpu ) ;
gb - > memory . ie = 0 ;
gb - > memory . ime = false ;
return true ;
}
2017-04-18 08:55:32 +00:00
static bool _returnTrue ( struct VFile * vf ) {
UNUSED ( vf ) ;
return true ;
}
struct mCore * GBVideoLogPlayerCreate ( void ) {
struct mCore * core = GBCoreCreate ( ) ;
core - > init = _GBVLPInit ;
core - > deinit = _GBVLPDeinit ;
core - > reset = _GBVLPReset ;
core - > loadROM = _GBVLPLoadROM ;
2017-04-24 19:43:12 +00:00
core - > loadState = _GBVLPLoadState ;
2017-04-18 08:55:32 +00:00
core - > isROM = _returnTrue ;
2016-01-27 09:05:12 +00:00
return core ;
}
2017-04-18 08:55:32 +00:00
# else
struct mCore * GBVideoLogPlayerCreate ( void ) {
return false ;
}
# endif