mirror of https://github.com/mgba-emu/mgba.git
GB: Improved SGB2 support
This commit is contained in:
parent
a44621e0d4
commit
23e60e081e
1
CHANGES
1
CHANGES
|
@ -124,6 +124,7 @@ Misc:
|
||||||
- Wii: Expose stretch configuration in settings
|
- Wii: Expose stretch configuration in settings
|
||||||
- Wii: Stretch now sets pixel-accurate mode size cap
|
- Wii: Stretch now sets pixel-accurate mode size cap
|
||||||
- Qt: Ensure camera image is valid
|
- Qt: Ensure camera image is valid
|
||||||
|
- GB: Improved SGB2 support
|
||||||
|
|
||||||
0.7 beta 1: (2018-09-24)
|
0.7 beta 1: (2018-09-24)
|
||||||
- Initial beta for 0.7
|
- Initial beta for 0.7
|
||||||
|
|
|
@ -150,7 +150,7 @@ void GBAudioReset(struct GBAudio* audio) {
|
||||||
audio->playingCh2 = false;
|
audio->playingCh2 = false;
|
||||||
audio->playingCh3 = false;
|
audio->playingCh3 = false;
|
||||||
audio->playingCh4 = false;
|
audio->playingCh4 = false;
|
||||||
if (audio->p && audio->p->model != GB_MODEL_SGB) {
|
if (audio->p && !(audio->p->model & GB_MODEL_SGB)) {
|
||||||
audio->playingCh1 = true;
|
audio->playingCh1 = true;
|
||||||
audio->enable = true;
|
audio->enable = true;
|
||||||
*audio->nr52 |= 0x01;
|
*audio->nr52 |= 0x01;
|
||||||
|
|
|
@ -229,7 +229,7 @@ static void _GBCoreLoadConfig(struct mCore* core, const struct mCoreConfig* conf
|
||||||
|
|
||||||
static void _GBCoreDesiredVideoDimensions(struct mCore* core, unsigned* width, unsigned* height) {
|
static void _GBCoreDesiredVideoDimensions(struct mCore* core, unsigned* width, unsigned* height) {
|
||||||
struct GB* gb = core->board;
|
struct GB* gb = core->board;
|
||||||
if (gb && (gb->model != GB_MODEL_SGB || !gb->video.sgbBorders)) {
|
if (gb && (!(gb->model & GB_MODEL_SGB) || !gb->video.sgbBorders)) {
|
||||||
*width = GB_VIDEO_HORIZONTAL_PIXELS;
|
*width = GB_VIDEO_HORIZONTAL_PIXELS;
|
||||||
*height = GB_VIDEO_VERTICAL_PIXELS;
|
*height = GB_VIDEO_VERTICAL_PIXELS;
|
||||||
} else {
|
} else {
|
||||||
|
@ -373,9 +373,9 @@ static void _GBCoreReset(struct mCore* core) {
|
||||||
GBDetectModel(gb);
|
GBDetectModel(gb);
|
||||||
if (gb->model == GB_MODEL_DMG && modelGB) {
|
if (gb->model == GB_MODEL_DMG && modelGB) {
|
||||||
gb->model = GBNameToModel(modelGB);
|
gb->model = GBNameToModel(modelGB);
|
||||||
} else if (gb->model == GB_MODEL_CGB && modelCGB) {
|
} else if ((gb->model & GB_MODEL_CGB) && modelCGB) {
|
||||||
gb->model = GBNameToModel(modelCGB);
|
gb->model = GBNameToModel(modelCGB);
|
||||||
} else if (gb->model == GB_MODEL_SGB && modelSGB) {
|
} else if ((gb->model & GB_MODEL_SGB) && modelSGB) {
|
||||||
gb->model = GBNameToModel(modelSGB);
|
gb->model = GBNameToModel(modelSGB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ static const uint8_t _knownHeader[4] = { 0xCE, 0xED, 0x66, 0x66};
|
||||||
#define DMG_2_BIOS_CHECKSUM 0x59C8598E
|
#define DMG_2_BIOS_CHECKSUM 0x59C8598E
|
||||||
#define MGB_BIOS_CHECKSUM 0xE6920754
|
#define MGB_BIOS_CHECKSUM 0xE6920754
|
||||||
#define SGB_BIOS_CHECKSUM 0xEC8A83B9
|
#define SGB_BIOS_CHECKSUM 0xEC8A83B9
|
||||||
|
#define SGB2_BIOS_CHECKSUM 0X53D0DD63
|
||||||
#define CGB_BIOS_CHECKSUM 0x41884E46
|
#define CGB_BIOS_CHECKSUM 0x41884E46
|
||||||
|
|
||||||
mLOG_DEFINE_CATEGORY(GB, "GB", "gb");
|
mLOG_DEFINE_CATEGORY(GB, "GB", "gb");
|
||||||
|
@ -400,6 +401,7 @@ bool GBIsBIOS(struct VFile* vf) {
|
||||||
case DMG_2_BIOS_CHECKSUM:
|
case DMG_2_BIOS_CHECKSUM:
|
||||||
case MGB_BIOS_CHECKSUM:
|
case MGB_BIOS_CHECKSUM:
|
||||||
case SGB_BIOS_CHECKSUM:
|
case SGB_BIOS_CHECKSUM:
|
||||||
|
case SGB2_BIOS_CHECKSUM:
|
||||||
case CGB_BIOS_CHECKSUM:
|
case CGB_BIOS_CHECKSUM:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
|
@ -588,6 +590,9 @@ void GBDetectModel(struct GB* gb) {
|
||||||
case SGB_BIOS_CHECKSUM:
|
case SGB_BIOS_CHECKSUM:
|
||||||
gb->model = GB_MODEL_SGB;
|
gb->model = GB_MODEL_SGB;
|
||||||
break;
|
break;
|
||||||
|
case SGB2_BIOS_CHECKSUM:
|
||||||
|
gb->model = GB_MODEL_SGB2;
|
||||||
|
break;
|
||||||
case CGB_BIOS_CHECKSUM:
|
case CGB_BIOS_CHECKSUM:
|
||||||
gb->model = GB_MODEL_CGB;
|
gb->model = GB_MODEL_CGB;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -199,7 +199,7 @@ void GBIOReset(struct GB* gb) {
|
||||||
}
|
}
|
||||||
GBIOWrite(gb, REG_WY, 0x00);
|
GBIOWrite(gb, REG_WY, 0x00);
|
||||||
GBIOWrite(gb, REG_WX, 0x00);
|
GBIOWrite(gb, REG_WX, 0x00);
|
||||||
if (gb->model >= GB_MODEL_CGB) {
|
if (gb->model & GB_MODEL_CGB) {
|
||||||
GBIOWrite(gb, REG_UNK4C, 0);
|
GBIOWrite(gb, REG_UNK4C, 0);
|
||||||
GBIOWrite(gb, REG_JOYP, 0xFF);
|
GBIOWrite(gb, REG_JOYP, 0xFF);
|
||||||
GBIOWrite(gb, REG_VBK, 0);
|
GBIOWrite(gb, REG_VBK, 0);
|
||||||
|
@ -211,7 +211,7 @@ void GBIOReset(struct GB* gb) {
|
||||||
GBIOWrite(gb, REG_HDMA3, 0xFF);
|
GBIOWrite(gb, REG_HDMA3, 0xFF);
|
||||||
GBIOWrite(gb, REG_HDMA4, 0xFF);
|
GBIOWrite(gb, REG_HDMA4, 0xFF);
|
||||||
gb->memory.io[REG_HDMA5] = 0xFF;
|
gb->memory.io[REG_HDMA5] = 0xFF;
|
||||||
} else if (gb->model == GB_MODEL_SGB) {
|
} else if (gb->model & GB_MODEL_SGB) {
|
||||||
GBIOWrite(gb, REG_JOYP, 0xFF);
|
GBIOWrite(gb, REG_JOYP, 0xFF);
|
||||||
}
|
}
|
||||||
GBIOWrite(gb, REG_IE, 0x00);
|
GBIOWrite(gb, REG_IE, 0x00);
|
||||||
|
@ -404,7 +404,7 @@ void GBIOWrite(struct GB* gb, unsigned address, uint8_t value) {
|
||||||
case REG_JOYP:
|
case REG_JOYP:
|
||||||
gb->memory.io[REG_JOYP] = value | 0x0F;
|
gb->memory.io[REG_JOYP] = value | 0x0F;
|
||||||
_readKeys(gb);
|
_readKeys(gb);
|
||||||
if (gb->model == GB_MODEL_SGB) {
|
if (gb->model & GB_MODEL_SGB) {
|
||||||
_writeSGBBits(gb, (value >> 4) & 3);
|
_writeSGBBits(gb, (value >> 4) & 3);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -719,7 +719,7 @@ void GBIODeserialize(struct GB* gb, const struct GBSerializedState* state) {
|
||||||
gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_SCX, state->io[REG_SCX]);
|
gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_SCX, state->io[REG_SCX]);
|
||||||
gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_WY, state->io[REG_WY]);
|
gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_WY, state->io[REG_WY]);
|
||||||
gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_WX, state->io[REG_WX]);
|
gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_WX, state->io[REG_WX]);
|
||||||
if (gb->model == GB_MODEL_SGB) {
|
if (gb->model & GB_MODEL_SGB) {
|
||||||
gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_BGP, state->io[REG_BGP]);
|
gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_BGP, state->io[REG_BGP]);
|
||||||
gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_OBP0, state->io[REG_OBP0]);
|
gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_OBP0, state->io[REG_OBP0]);
|
||||||
gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_OBP1, state->io[REG_OBP1]);
|
gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_OBP1, state->io[REG_OBP1]);
|
||||||
|
|
|
@ -196,7 +196,7 @@ static void GBVideoSoftwareRendererInit(struct GBVideoRenderer* renderer, enum G
|
||||||
softwareRenderer->lastY = GB_VIDEO_VERTICAL_PIXELS;
|
softwareRenderer->lastY = GB_VIDEO_VERTICAL_PIXELS;
|
||||||
softwareRenderer->hasWindow = false;
|
softwareRenderer->hasWindow = false;
|
||||||
softwareRenderer->wx = 0;
|
softwareRenderer->wx = 0;
|
||||||
softwareRenderer->model = model;
|
softwareRenderer->model = model & ~GB_MODEL_MGB;
|
||||||
softwareRenderer->sgbTransfer = 0;
|
softwareRenderer->sgbTransfer = 0;
|
||||||
softwareRenderer->sgbCommandHeader = 0;
|
softwareRenderer->sgbCommandHeader = 0;
|
||||||
softwareRenderer->sgbBorders = sgbBorders;
|
softwareRenderer->sgbBorders = sgbBorders;
|
||||||
|
|
|
@ -64,7 +64,7 @@ void GBSerialize(struct GB* gb, struct GBSerializedState* state) {
|
||||||
GBTimerSerialize(&gb->timer, state);
|
GBTimerSerialize(&gb->timer, state);
|
||||||
GBAudioSerialize(&gb->audio, state);
|
GBAudioSerialize(&gb->audio, state);
|
||||||
|
|
||||||
if (gb->model == GB_MODEL_SGB) {
|
if (gb->model & GB_MODEL_SGB) {
|
||||||
GBSGBSerialize(gb, state);
|
GBSGBSerialize(gb, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,7 @@ bool GBDeserialize(struct GB* gb, const struct GBSerializedState* state) {
|
||||||
GBTimerDeserialize(&gb->timer, state);
|
GBTimerDeserialize(&gb->timer, state);
|
||||||
GBAudioDeserialize(&gb->audio, state);
|
GBAudioDeserialize(&gb->audio, state);
|
||||||
|
|
||||||
if (gb->model == GB_MODEL_SGB && canSgb) {
|
if (gb->model & GB_MODEL_SGB && canSgb) {
|
||||||
GBSGBDeserialize(gb, state);
|
GBSGBDeserialize(gb, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ void GBVideoReset(struct GBVideo* video) {
|
||||||
video->renderer->oam = &video->oam;
|
video->renderer->oam = &video->oam;
|
||||||
memset(&video->palette, 0, sizeof(video->palette));
|
memset(&video->palette, 0, sizeof(video->palette));
|
||||||
|
|
||||||
if (video->p->model == GB_MODEL_SGB) {
|
if (video->p->model & GB_MODEL_SGB) {
|
||||||
video->renderer->sgbCharRam = anonymousMemoryMap(SGB_SIZE_CHAR_RAM);
|
video->renderer->sgbCharRam = anonymousMemoryMap(SGB_SIZE_CHAR_RAM);
|
||||||
video->renderer->sgbMapRam = anonymousMemoryMap(SGB_SIZE_MAP_RAM);
|
video->renderer->sgbMapRam = anonymousMemoryMap(SGB_SIZE_MAP_RAM);
|
||||||
video->renderer->sgbPalRam = anonymousMemoryMap(SGB_SIZE_PAL_RAM);
|
video->renderer->sgbPalRam = anonymousMemoryMap(SGB_SIZE_PAL_RAM);
|
||||||
|
@ -491,7 +491,7 @@ void GBVideoWritePalette(struct GBVideo* video, uint16_t address, uint8_t value)
|
||||||
video->renderer->writePalette(video->renderer, 9 * 4 + 3, video->palette[9 * 4 + 3]);
|
video->renderer->writePalette(video->renderer, 9 * 4 + 3, video->palette[9 * 4 + 3]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (video->p->model == GB_MODEL_SGB) {
|
} else if (video->p->model & GB_MODEL_SGB) {
|
||||||
video->renderer->writeVideoRegister(video->renderer, address, value);
|
video->renderer->writeVideoRegister(video->renderer, address, value);
|
||||||
} else {
|
} else {
|
||||||
switch (address) {
|
switch (address) {
|
||||||
|
|
Loading…
Reference in New Issue