GB: Support for combo "Super Game Boy Color" SGB + GBC ROM hacks

This commit is contained in:
Vicki Pfau 2021-05-07 14:37:19 -07:00
parent c633d08076
commit e00987ddeb
7 changed files with 23 additions and 11 deletions

View File

@ -3,6 +3,7 @@ Features:
- Presets for Game Boy palettes
- Tool for converting scanned pictures of e-Reader cards to raw dotcode data
- Cheat code support in homebrew ports
- Support for combo "Super Game Boy Color" SGB + GBC ROM hacks
Emulation fixes:
- GB Video: Clear VRAM on reset (fixes mgba.io/i/2152)
- GBA Video: Revert scanline latching changes (fixes mgba.io/i/2153, mgba.io/i/2149)

View File

@ -17,8 +17,9 @@ enum GBModel {
GB_MODEL_DMG = 0x00,
GB_MODEL_SGB = 0x20,
GB_MODEL_MGB = 0x40,
GB_MODEL_SGB2 = 0x60,
GB_MODEL_SGB2 = GB_MODEL_MGB | GB_MODEL_SGB,
GB_MODEL_CGB = 0x80,
GB_MODEL_SCGB = GB_MODEL_CGB | GB_MODEL_SGB,
GB_MODEL_AGB = 0xC0
};

View File

@ -560,6 +560,7 @@ static void _GBCoreReset(struct mCore* core) {
break;
case GB_MODEL_CGB:
case GB_MODEL_AGB:
case GB_MODEL_SCGB:
configPath = mCoreConfigGetValue(&core->config, "gbc.bios");
break;
default:
@ -589,6 +590,7 @@ static void _GBCoreReset(struct mCore* core) {
break;
case GB_MODEL_CGB:
case GB_MODEL_AGB:
case GB_MODEL_SCGB:
strncat(path, PATH_SEP "gbc_bios.bin", PATH_MAX - strlen(path));
break;
default:

View File

@ -546,6 +546,7 @@ void GBSkipBIOS(struct GB* gb) {
cpu->b = 1;
// Fall through
case GB_MODEL_CGB:
case GB_MODEL_SCGB:
cpu->a = 0x11;
if (gb->model == GB_MODEL_AGB) {
cpu->f.packed = 0x00;
@ -671,6 +672,7 @@ void GBDetectModel(struct GB* gb) {
break;
case GB_MODEL_AGB:
case GB_MODEL_CGB:
case GB_MODEL_SCGB:
gb->audio.style = GB_AUDIO_CGB;
break;
}
@ -932,11 +934,11 @@ void GBFrameEnded(struct GB* gb) {
}
enum GBModel GBNameToModel(const char* model) {
if (strcasecmp(model, "DMG") == 0) {
if (strcasecmp(model, "DMG") == 0 || strcasecmp(model, "GB") == 0) {
return GB_MODEL_DMG;
} else if (strcasecmp(model, "CGB") == 0) {
} else if (strcasecmp(model, "CGB") == 0 || strcasecmp(model, "GBC") == 0) {
return GB_MODEL_CGB;
} else if (strcasecmp(model, "AGB") == 0) {
} else if (strcasecmp(model, "AGB") == 0 || strcasecmp(model, "GBA") == 0) {
return GB_MODEL_AGB;
} else if (strcasecmp(model, "SGB") == 0) {
return GB_MODEL_SGB;
@ -944,6 +946,8 @@ enum GBModel GBNameToModel(const char* model) {
return GB_MODEL_MGB;
} else if (strcasecmp(model, "SGB2") == 0) {
return GB_MODEL_SGB2;
} else if (strcasecmp(model, "SCGB") == 0 || strcasecmp(model, "SGBC") == 0) {
return GB_MODEL_SCGB;
}
return GB_MODEL_AUTODETECT;
}
@ -962,6 +966,8 @@ const char* GBModelToName(enum GBModel model) {
return "CGB";
case GB_MODEL_AGB:
return "AGB";
case GB_MODEL_SCGB:
return "SCGB";
default:
case GB_MODEL_AUTODETECT:
return NULL;

View File

@ -629,7 +629,7 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i
int p = 0;
switch (softwareRenderer->d.sgbRenderMode) {
case 0:
if (softwareRenderer->model & GB_MODEL_SGB) {
if ((softwareRenderer->model & (GB_MODEL_SGB | GB_MODEL_CGB)) == GB_MODEL_SGB) {
p = softwareRenderer->d.sgbAttributes[(startX >> 5) + 5 * (y >> 3)];
p >>= 6 - ((x / 4) & 0x6);
p &= 3;
@ -639,7 +639,7 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i
row[x] = softwareRenderer->palette[p | softwareRenderer->lookup[softwareRenderer->row[x] & OBJ_PRIO_MASK]];
}
for (; x + 7 < (endX & ~7); x += 8) {
if (softwareRenderer->model & GB_MODEL_SGB) {
if ((softwareRenderer->model & (GB_MODEL_SGB | GB_MODEL_CGB)) == GB_MODEL_SGB) {
p = softwareRenderer->d.sgbAttributes[(x >> 5) + 5 * (y >> 3)];
p >>= 6 - ((x / 4) & 0x6);
p &= 3;
@ -654,7 +654,7 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i
row[x + 6] = softwareRenderer->palette[p | softwareRenderer->lookup[softwareRenderer->row[x + 6] & OBJ_PRIO_MASK]];
row[x + 7] = softwareRenderer->palette[p | softwareRenderer->lookup[softwareRenderer->row[x + 7] & OBJ_PRIO_MASK]];
}
if (softwareRenderer->model & GB_MODEL_SGB) {
if ((softwareRenderer->model & (GB_MODEL_SGB | GB_MODEL_CGB)) == GB_MODEL_SGB) {
p = softwareRenderer->d.sgbAttributes[(x >> 5) + 5 * (y >> 3)];
p >>= 6 - ((x / 4) & 0x6);
p &= 3;

View File

@ -238,7 +238,7 @@ void GBVideoSkipBIOS(struct GBVideo* video) {
video->modeEvent.callback = _endMode1;
int32_t next;
if (video->p->model == GB_MODEL_CGB) {
if (video->p->model & GB_MODEL_CGB) {
video->ly = GB_VIDEO_VERTICAL_PIXELS;
video->p->memory.io[GB_REG_LY] = video->ly;
video->stat = GBRegisterSTATClearLYC(video->stat);
@ -536,9 +536,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]);
break;
}
} else if (video->p->model & GB_MODEL_SGB) {
video->renderer->writeVideoRegister(video->renderer, address, value);
} else {
} else if (video->p->model >= GB_MODEL_CGB) {
switch (address) {
case GB_REG_BCPD:
if (video->mode != 3) {
@ -579,6 +577,8 @@ void GBVideoWritePalette(struct GBVideo* video, uint16_t address, uint8_t value)
video->p->memory.io[GB_REG_OCPD] = video->palette[8 * 4 + (video->ocpIndex >> 1)] >> (8 * (video->ocpIndex & 1));
break;
}
} else {
video->renderer->writeVideoRegister(video->renderer, address, value);
}
}

View File

@ -15,6 +15,7 @@ static const QList<GBModel> s_gbModelList{
GB_MODEL_SGB,
GB_MODEL_CGB,
GB_MODEL_AGB,
GB_MODEL_SCGB,
};
static const QList<GBMemoryBankControllerType> s_mbcList{
@ -58,6 +59,7 @@ QString GameBoy::modelName(GBModel model) {
s_gbModelNames[GB_MODEL_SGB2] = tr("Super Game Boy 2 (SGB)");
s_gbModelNames[GB_MODEL_CGB] = tr("Game Boy Color (CGB)");
s_gbModelNames[GB_MODEL_AGB] = tr("Game Boy Advance (AGB)");
s_gbModelNames[GB_MODEL_SCGB] = tr("Super Game Boy Color (SGB + CGB)");
}
return s_gbModelNames[model];