OAM DMA/GDMA conflicts
This commit is contained in:
parent
76b881c2e1
commit
37ca174f37
151
Core/memory.c
151
Core/memory.c
@ -473,6 +473,42 @@ static inline void sync_ppu_if_needed(GB_gameboy_t *gb, uint8_t register_accesse
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t read_oam(GB_gameboy_t *gb, uint8_t addr)
|
||||||
|
{
|
||||||
|
if (addr < 0xa0) {
|
||||||
|
return gb->oam[addr];
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (gb->model) {
|
||||||
|
case GB_MODEL_CGB_E:
|
||||||
|
case GB_MODEL_AGB_A:
|
||||||
|
return (addr & 0xF0) | (addr >> 4);
|
||||||
|
|
||||||
|
case GB_MODEL_CGB_D:
|
||||||
|
if (addr > 0xc0) {
|
||||||
|
addr |= 0xf0;
|
||||||
|
}
|
||||||
|
return gb->extra_oam[addr - 0xa0];
|
||||||
|
|
||||||
|
case GB_MODEL_CGB_C:
|
||||||
|
case GB_MODEL_CGB_B:
|
||||||
|
case GB_MODEL_CGB_A:
|
||||||
|
case GB_MODEL_CGB_0:
|
||||||
|
addr &= ~0x18;
|
||||||
|
return gb->extra_oam[addr - 0xa0];
|
||||||
|
|
||||||
|
case GB_MODEL_DMG_B:
|
||||||
|
case GB_MODEL_MGB:
|
||||||
|
case GB_MODEL_SGB_NTSC:
|
||||||
|
case GB_MODEL_SGB_PAL:
|
||||||
|
case GB_MODEL_SGB_NTSC_NO_SFC:
|
||||||
|
case GB_MODEL_SGB_PAL_NO_SFC:
|
||||||
|
case GB_MODEL_SGB2:
|
||||||
|
case GB_MODEL_SGB2_NO_SFC:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr)
|
static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr)
|
||||||
{
|
{
|
||||||
if (addr < 0xFE00) {
|
if (addr < 0xFE00) {
|
||||||
@ -552,46 +588,7 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr)
|
|||||||
return 0xff;
|
return 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr < 0xFEA0) {
|
return read_oam(gb, addr);
|
||||||
return gb->oam[addr & 0xFF];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gb->oam_read_blocked) {
|
|
||||||
return 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (gb->model) {
|
|
||||||
case GB_MODEL_CGB_E:
|
|
||||||
case GB_MODEL_AGB_A:
|
|
||||||
return (addr & 0xF0) | ((addr >> 4) & 0xF);
|
|
||||||
|
|
||||||
case GB_MODEL_CGB_D:
|
|
||||||
if (addr > 0xfec0) {
|
|
||||||
addr |= 0xf0;
|
|
||||||
}
|
|
||||||
return gb->extra_oam[addr - 0xfea0];
|
|
||||||
|
|
||||||
case GB_MODEL_CGB_C:
|
|
||||||
case GB_MODEL_CGB_B:
|
|
||||||
case GB_MODEL_CGB_A:
|
|
||||||
case GB_MODEL_CGB_0:
|
|
||||||
addr &= ~0x18;
|
|
||||||
return gb->extra_oam[addr - 0xfea0];
|
|
||||||
|
|
||||||
case GB_MODEL_DMG_B:
|
|
||||||
case GB_MODEL_MGB:
|
|
||||||
case GB_MODEL_SGB_NTSC:
|
|
||||||
case GB_MODEL_SGB_PAL:
|
|
||||||
case GB_MODEL_SGB_NTSC_NO_SFC:
|
|
||||||
case GB_MODEL_SGB_PAL_NO_SFC:
|
|
||||||
case GB_MODEL_SGB2:
|
|
||||||
case GB_MODEL_SGB2_NO_SFC:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addr < 0xFF00) {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr < 0xFF80) {
|
if (addr < 0xFF80) {
|
||||||
@ -1200,6 +1197,40 @@ static void write_banked_ram(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
|
|||||||
gb->ram[(addr & 0x0FFF) + gb->cgb_ram_bank * 0x1000] = value;
|
gb->ram[(addr & 0x0FFF) + gb->cgb_ram_bank * 0x1000] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void write_oam(GB_gameboy_t *gb, uint8_t addr, uint8_t value)
|
||||||
|
{
|
||||||
|
if (addr < 0xa0) {
|
||||||
|
gb->oam[addr] = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (gb->model) {
|
||||||
|
case GB_MODEL_CGB_D:
|
||||||
|
if (addr > 0xc0) {
|
||||||
|
addr |= 0xf0;
|
||||||
|
}
|
||||||
|
gb->extra_oam[addr - 0xa0] = value;
|
||||||
|
break;
|
||||||
|
case GB_MODEL_CGB_C:
|
||||||
|
case GB_MODEL_CGB_B:
|
||||||
|
case GB_MODEL_CGB_A:
|
||||||
|
case GB_MODEL_CGB_0:
|
||||||
|
addr &= ~0x18;
|
||||||
|
gb->extra_oam[addr - 0xa0] = value;
|
||||||
|
break;
|
||||||
|
case GB_MODEL_CGB_E:
|
||||||
|
case GB_MODEL_AGB_A:
|
||||||
|
case GB_MODEL_DMG_B:
|
||||||
|
case GB_MODEL_MGB:
|
||||||
|
case GB_MODEL_SGB_NTSC:
|
||||||
|
case GB_MODEL_SGB_PAL:
|
||||||
|
case GB_MODEL_SGB_NTSC_NO_SFC:
|
||||||
|
case GB_MODEL_SGB_PAL_NO_SFC:
|
||||||
|
case GB_MODEL_SGB2:
|
||||||
|
case GB_MODEL_SGB2_NO_SFC:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
|
static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
|
||||||
{
|
{
|
||||||
if (addr < 0xFE00) {
|
if (addr < 0xFE00) {
|
||||||
@ -1221,37 +1252,7 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (GB_is_cgb(gb)) {
|
if (GB_is_cgb(gb)) {
|
||||||
if (addr < 0xFEA0) {
|
write_oam(gb, addr, value);
|
||||||
gb->oam[addr & 0xFF] = value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (gb->model) {
|
|
||||||
case GB_MODEL_CGB_D:
|
|
||||||
if (addr > 0xfec0) {
|
|
||||||
addr |= 0xf0;
|
|
||||||
}
|
|
||||||
gb->extra_oam[addr - 0xfea0] = value;
|
|
||||||
break;
|
|
||||||
case GB_MODEL_CGB_C:
|
|
||||||
case GB_MODEL_CGB_B:
|
|
||||||
case GB_MODEL_CGB_A:
|
|
||||||
case GB_MODEL_CGB_0:
|
|
||||||
addr &= ~0x18;
|
|
||||||
gb->extra_oam[addr - 0xfea0] = value;
|
|
||||||
break;
|
|
||||||
case GB_MODEL_CGB_E:
|
|
||||||
case GB_MODEL_AGB_A:
|
|
||||||
break;
|
|
||||||
case GB_MODEL_DMG_B:
|
|
||||||
case GB_MODEL_MGB:
|
|
||||||
case GB_MODEL_SGB_NTSC:
|
|
||||||
case GB_MODEL_SGB_PAL:
|
|
||||||
case GB_MODEL_SGB_NTSC_NO_SFC:
|
|
||||||
case GB_MODEL_SGB_PAL_NO_SFC:
|
|
||||||
case GB_MODEL_SGB2:
|
|
||||||
case GB_MODEL_SGB2_NO_SFC:
|
|
||||||
unreachable();
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1702,7 +1703,10 @@ void GB_dma_run(GB_gameboy_t *gb)
|
|||||||
gb->dma_current_dest++;
|
gb->dma_current_dest++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (gb->dma_current_src < 0xe000) {
|
if (unlikely(gb->hdma_in_progress && (gb->hdma_steps_left > 1 || (gb->hdma_current_dest & 0xF) != 0xF))) {
|
||||||
|
gb->dma_current_dest++;
|
||||||
|
}
|
||||||
|
else if (gb->dma_current_src < 0xe000) {
|
||||||
gb->oam[gb->dma_current_dest++] = GB_read_memory(gb, gb->dma_current_src);
|
gb->oam[gb->dma_current_dest++] = GB_read_memory(gb, gb->dma_current_src);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1744,6 +1748,9 @@ void GB_hdma_run(GB_gameboy_t *gb)
|
|||||||
(gb->hdma_current_src & 0xE000) == 0xA000) {
|
(gb->hdma_current_src & 0xE000) == 0xA000) {
|
||||||
byte = GB_read_memory(gb, gb->hdma_current_src);
|
byte = GB_read_memory(gb, gb->hdma_current_src);
|
||||||
}
|
}
|
||||||
|
if (unlikely(GB_is_dma_active(gb)) && (gb->dma_cycles_modulo == 0 || gb->cgb_double_speed)) {
|
||||||
|
write_oam(gb, gb->hdma_current_src, byte);
|
||||||
|
}
|
||||||
gb->hdma_current_src++;
|
gb->hdma_current_src++;
|
||||||
if (gb->addr_for_hdma_conflict == 0xFFFF /* || (gb->model == GB_MODEL_AGS && gb->cgb_double_speed) */) {
|
if (gb->addr_for_hdma_conflict == 0xFFFF /* || (gb->model == GB_MODEL_AGS && gb->cgb_double_speed) */) {
|
||||||
gb->vram[vram_base + (gb->hdma_current_dest++ & 0x1FFF)] = byte;
|
gb->vram[vram_base + (gb->hdma_current_dest++ & 0x1FFF)] = byte;
|
||||||
|
Loading…
Reference in New Issue
Block a user