Add CGB-B support

This commit is contained in:
Lior Halphon 2021-10-30 20:58:57 +03:00
parent b54365fc40
commit 6cd13be624
6 changed files with 17 additions and 14 deletions

View File

@ -399,7 +399,7 @@
<items> <items>
<menuItem title="CPU-CGB 0" tag="512" enabled="NO" id="2Uk-u3-6Gw"/> <menuItem title="CPU-CGB 0" tag="512" enabled="NO" id="2Uk-u3-6Gw"/>
<menuItem title="CPU-CGB A" tag="513" enabled="NO" id="axv-yk-RWM"/> <menuItem title="CPU-CGB A" tag="513" enabled="NO" id="axv-yk-RWM"/>
<menuItem title="CPU-CGB B" tag="514" enabled="NO" id="NtJ-oo-IM2"/> <menuItem title="CPU-CGB B (Experimental)" tag="514" id="NtJ-oo-IM2"/>
<menuItem title="CPU-CGB C (Experimental)" tag="515" id="9YL-u8-12z"/> <menuItem title="CPU-CGB C (Experimental)" tag="515" id="9YL-u8-12z"/>
<menuItem title="CPU-CGB D" tag="516" id="c76-oF-fkU"/> <menuItem title="CPU-CGB D" tag="516" id="c76-oF-fkU"/>
<menuItem title="CPU-CGB E" state="on" tag="517" id="3lF-1Q-2SS"/> <menuItem title="CPU-CGB E" state="on" tag="517" id="3lF-1Q-2SS"/>
@ -608,7 +608,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<clipView key="contentView" focusRingType="none" ambiguous="YES" drawsBackground="NO" id="AMs-PO-nid"> <clipView key="contentView" focusRingType="none" ambiguous="YES" drawsBackground="NO" id="AMs-PO-nid">
<rect key="frame" x="1" y="1" width="255" height="209"/> <rect key="frame" x="1" y="1" width="255" height="209"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnResizing="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" id="UDd-IJ-fxX"> <tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnResizing="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" id="UDd-IJ-fxX">
<rect key="frame" x="0.0" y="0.0" width="255" height="209"/> <rect key="frame" x="0.0" y="0.0" width="255" height="209"/>

View File

@ -834,7 +834,6 @@ static inline uint16_t effective_channel4_counter(GB_gameboy_t *gb)
switch (gb->model) { switch (gb->model) {
/* Pre CGB revisions are assumed to be like CGB-C, A and 0 for the lack of a better guess. /* Pre CGB revisions are assumed to be like CGB-C, A and 0 for the lack of a better guess.
TODO: It could be verified with audio based test ROMs. */ TODO: It could be verified with audio based test ROMs. */
#if 0
case GB_MODEL_CGB_B: case GB_MODEL_CGB_B:
if (effective_counter & 8) { if (effective_counter & 8) {
effective_counter |= 0xE; // Seems to me F under some circumstances? effective_counter |= 0xE; // Seems to me F under some circumstances?
@ -861,7 +860,6 @@ static inline uint16_t effective_channel4_counter(GB_gameboy_t *gb)
effective_counter |= 0x20; effective_counter |= 0x20;
} }
break; break;
#endif
case GB_MODEL_DMG_B: case GB_MODEL_DMG_B:
case GB_MODEL_MGB: case GB_MODEL_MGB:
case GB_MODEL_SGB_NTSC: case GB_MODEL_SGB_NTSC:
@ -1056,7 +1054,6 @@ void GB_apu_write(GB_gameboy_t *gb, uint8_t reg, uint8_t value)
case GB_IO_NR14: case GB_IO_NR14:
case GB_IO_NR24: { case GB_IO_NR24: {
/* TODO: GB_MODEL_CGB_D fails channel_1_sweep_restart_2, don't forget when adding support for this revision! */
unsigned index = reg == GB_IO_NR24? GB_SQUARE_2: GB_SQUARE_1; unsigned index = reg == GB_IO_NR24? GB_SQUARE_2: GB_SQUARE_1;
bool was_active = gb->apu.is_active[index]; bool was_active = gb->apu.is_active[index];
/* TODO: When the sample length changes right before being updated, the countdown should change to the /* TODO: When the sample length changes right before being updated, the countdown should change to the
@ -1162,7 +1159,7 @@ void GB_apu_write(GB_gameboy_t *gb, uint8_t reg, uint8_t value)
} }
/* APU glitch - if length is enabled while the DIV-divider's LSB is 1, tick the length once. */ /* APU glitch - if length is enabled while the DIV-divider's LSB is 1, tick the length once. */
if ((value & 0x40) && if (((value & 0x40) || (GB_is_cgb(gb) && gb->model <= GB_MODEL_CGB_B)) && // Current value is irrelevant on CGB-B and older
!gb->apu.square_channels[index].length_enabled && !gb->apu.square_channels[index].length_enabled &&
(gb->apu.div_divider & 1) && (gb->apu.div_divider & 1) &&
gb->apu.square_channels[index].pulse_length) { gb->apu.square_channels[index].pulse_length) {
@ -1262,7 +1259,7 @@ void GB_apu_write(GB_gameboy_t *gb, uint8_t reg, uint8_t value)
} }
/* APU glitch - if length is enabled while the DIV-divider's LSB is 1, tick the length once. */ /* APU glitch - if length is enabled while the DIV-divider's LSB is 1, tick the length once. */
if ((value & 0x40) && if (((value & 0x40) || (GB_is_cgb(gb) && gb->model <= GB_MODEL_CGB_B)) && // Current value is irrelevant on CGB-B and older
!gb->apu.wave_channel.length_enabled && !gb->apu.wave_channel.length_enabled &&
(gb->apu.div_divider & 1) && (gb->apu.div_divider & 1) &&
gb->apu.wave_channel.pulse_length) { gb->apu.wave_channel.pulse_length) {

View File

@ -1463,13 +1463,14 @@ static void reset_ram(GB_gameboy_t *gb)
} }
break; break;
case GB_MODEL_CGB_B:
case GB_MODEL_CGB_C: case GB_MODEL_CGB_C:
for (unsigned i = 0; i < gb->ram_size; i++) { for (unsigned i = 0; i < gb->ram_size; i++) {
if ((i & 0x808) == 0x800 || (i & 0x808) == 0x008) { if ((i & 0x808) == 0x800 || (i & 0x808) == 0x008) {
gb->ram[i] = 0; gb->ram[i] = 0;
} }
else { else {
gb->ram[i] = GB_random() | GB_random() | GB_random() | GB_random(); gb->ram[i] = GB_random() | GB_random() | GB_random() | GB_random() | GB_random();
} }
} }
break; break;
@ -1488,6 +1489,7 @@ static void reset_ram(GB_gameboy_t *gb)
/* HRAM */ /* HRAM */
switch (gb->model) { switch (gb->model) {
case GB_MODEL_CGB_B:
case GB_MODEL_CGB_C: case GB_MODEL_CGB_C:
case GB_MODEL_CGB_D: case GB_MODEL_CGB_D:
case GB_MODEL_CGB_E: case GB_MODEL_CGB_E:
@ -1518,11 +1520,12 @@ static void reset_ram(GB_gameboy_t *gb)
/* OAM */ /* OAM */
switch (gb->model) { switch (gb->model) {
case GB_MODEL_CGB_B:
case GB_MODEL_CGB_C: case GB_MODEL_CGB_C:
case GB_MODEL_CGB_D: case GB_MODEL_CGB_D:
case GB_MODEL_CGB_E: case GB_MODEL_CGB_E:
case GB_MODEL_AGB: case GB_MODEL_AGB:
/* Zero'd out by boot ROM anyway*/ /* Zero'd out by boot ROM anyway, extra OAM no accessible */
break; break;
case GB_MODEL_DMG_B: case GB_MODEL_DMG_B:
@ -1549,6 +1552,7 @@ static void reset_ram(GB_gameboy_t *gb)
/* Wave RAM */ /* Wave RAM */
switch (gb->model) { switch (gb->model) {
case GB_MODEL_CGB_B:
case GB_MODEL_CGB_C: case GB_MODEL_CGB_C:
case GB_MODEL_CGB_D: case GB_MODEL_CGB_D:
case GB_MODEL_CGB_E: case GB_MODEL_CGB_E:
@ -1622,6 +1626,7 @@ static void request_boot_rom(GB_gameboy_t *gb)
case GB_MODEL_SGB2_NO_SFC: case GB_MODEL_SGB2_NO_SFC:
type = GB_BOOT_ROM_SGB2; type = GB_BOOT_ROM_SGB2;
break; break;
case GB_MODEL_CGB_B:
case GB_MODEL_CGB_C: case GB_MODEL_CGB_C:
case GB_MODEL_CGB_D: case GB_MODEL_CGB_D:
case GB_MODEL_CGB_E: case GB_MODEL_CGB_E:

View File

@ -133,7 +133,7 @@ typedef enum {
GB_MODEL_SGB2_NO_SFC = GB_MODEL_SGB2 | GB_MODEL_NO_SFC_BIT, GB_MODEL_SGB2_NO_SFC = GB_MODEL_SGB2 | GB_MODEL_NO_SFC_BIT,
// GB_MODEL_CGB_0 = 0x200, // GB_MODEL_CGB_0 = 0x200,
// GB_MODEL_CGB_A = 0x201, // GB_MODEL_CGB_A = 0x201,
// GB_MODEL_CGB_B = 0x202, GB_MODEL_CGB_B = 0x202,
GB_MODEL_CGB_C = 0x203, GB_MODEL_CGB_C = 0x203,
GB_MODEL_CGB_D = 0x204, GB_MODEL_CGB_D = 0x204,
GB_MODEL_CGB_E = 0x205, GB_MODEL_CGB_E = 0x205,

View File

@ -503,8 +503,8 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr)
return gb->extra_oam[addr - 0xfea0]; return gb->extra_oam[addr - 0xfea0];
case GB_MODEL_CGB_C: case GB_MODEL_CGB_C:
/*
case GB_MODEL_CGB_B: case GB_MODEL_CGB_B:
/*
case GB_MODEL_CGB_A: case GB_MODEL_CGB_A:
case GB_MODEL_CGB_0: case GB_MODEL_CGB_0:
*/ */
@ -1009,8 +1009,8 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
gb->extra_oam[addr - 0xfea0] = value; gb->extra_oam[addr - 0xfea0] = value;
break; break;
case GB_MODEL_CGB_C: case GB_MODEL_CGB_C:
/*
case GB_MODEL_CGB_B: case GB_MODEL_CGB_B:
/*
case GB_MODEL_CGB_A: case GB_MODEL_CGB_A:
case GB_MODEL_CGB_0: case GB_MODEL_CGB_0:
*/ */

View File

@ -347,6 +347,7 @@ static bool verify_and_update_state_compatibility(GB_gameboy_t *gb, GB_gameboy_t
case GB_MODEL_MGB: return true; case GB_MODEL_MGB: return true;
case GB_MODEL_SGB2: return true; case GB_MODEL_SGB2: return true;
case GB_MODEL_SGB2_NO_SFC: return true; case GB_MODEL_SGB2_NO_SFC: return true;
case GB_MODEL_CGB_B: return true;
case GB_MODEL_CGB_C: return true; case GB_MODEL_CGB_C: return true;
case GB_MODEL_CGB_D: return true; case GB_MODEL_CGB_D: return true;
case GB_MODEL_CGB_E: return true; case GB_MODEL_CGB_E: return true;
@ -647,7 +648,7 @@ static int save_state_internal(GB_gameboy_t *gb, virtual_file_t *file, bool appe
case GB_MODEL_SGB2: case GB_MODEL_SGB2:
bess_core.full_model = BE32('S2 '); break; bess_core.full_model = BE32('S2 '); break;
case GB_MODEL_CGB_B: bess_core.full_model = BE32('CCB '); break;
case GB_MODEL_CGB_C: bess_core.full_model = BE32('CCC '); break; case GB_MODEL_CGB_C: bess_core.full_model = BE32('CCC '); break;
case GB_MODEL_CGB_D: bess_core.full_model = BE32('CCD '); break; case GB_MODEL_CGB_D: bess_core.full_model = BE32('CCD '); break;
case GB_MODEL_CGB_E: bess_core.full_model = BE32('CCE '); break; case GB_MODEL_CGB_E: bess_core.full_model = BE32('CCE '); break;