Mode 2 OAM open bus behavior
This commit is contained in:
parent
850e7bb78c
commit
4e27558ac2
@ -485,14 +485,11 @@ static void add_object_from_index(GB_gameboy_t *gb, unsigned index)
|
|||||||
if (gb->n_visible_objs == 10) return;
|
if (gb->n_visible_objs == 10) return;
|
||||||
|
|
||||||
/* TODO: It appears that DMA blocks PPU access to OAM, but it needs verification. */
|
/* TODO: It appears that DMA blocks PPU access to OAM, but it needs verification. */
|
||||||
if (unlikely(GB_is_dma_active(gb))) {
|
if (unlikely(GB_is_dma_active(gb) && (gb->halted || gb->stopped))) {
|
||||||
if (!gb->halted && !gb->stopped) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (gb->model < GB_MODEL_CGB_E) {
|
if (gb->model < GB_MODEL_CGB_E) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* CGB-0 to CGB-D: Halted DMA still blocks Mode 2;
|
/* CGB-0 to CGB-D: Halted DMA blocks Mode 2;
|
||||||
Pre-CGB: Unit specific behavior, some units read FFs, some units read using
|
Pre-CGB: Unit specific behavior, some units read FFs, some units read using
|
||||||
several different corruption pattterns. For simplicity, we emulate
|
several different corruption pattterns. For simplicity, we emulate
|
||||||
FFs. */
|
FFs. */
|
||||||
@ -502,22 +499,24 @@ static void add_object_from_index(GB_gameboy_t *gb, unsigned index)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This reverse sorts the visible objects by location and priority */
|
if (likely(!GB_is_dma_active(gb) || gb->halted || gb->stopped)) {
|
||||||
uint8_t oam_y = oam_read(gb, index * 4);
|
gb->mode2_y_bus = oam_read(gb, index * 4);
|
||||||
uint8_t oam_x = oam_read(gb, index * 4 + 1);
|
gb->mode2_x_bus = oam_read(gb, index * 4 + 1);
|
||||||
|
}
|
||||||
bool height_16 = (gb->io_registers[GB_IO_LCDC] & 4) != 0;
|
bool height_16 = (gb->io_registers[GB_IO_LCDC] & 4) != 0;
|
||||||
signed y = oam_y - 16;
|
signed y = gb->mode2_y_bus - 16;
|
||||||
|
/* This reverse sorts the visible objects by location and priority */
|
||||||
if (y <= gb->current_line && y + (height_16? 16 : 8) > gb->current_line) {
|
if (y <= gb->current_line && y + (height_16? 16 : 8) > gb->current_line) {
|
||||||
unsigned j = 0;
|
unsigned j = 0;
|
||||||
for (; j < gb->n_visible_objs; j++) {
|
for (; j < gb->n_visible_objs; j++) {
|
||||||
if (gb->objects_x[j] <= oam_x) break;
|
if (gb->objects_x[j] <= gb->mode2_x_bus) break;
|
||||||
}
|
}
|
||||||
memmove(gb->visible_objs + j + 1, gb->visible_objs + j, gb->n_visible_objs - j);
|
memmove(gb->visible_objs + j + 1, gb->visible_objs + j, gb->n_visible_objs - j);
|
||||||
memmove(gb->objects_x + j + 1, gb->objects_x + j, gb->n_visible_objs - j);
|
memmove(gb->objects_x + j + 1, gb->objects_x + j, gb->n_visible_objs - j);
|
||||||
memmove(gb->objects_y + j + 1, gb->objects_y + j, gb->n_visible_objs - j);
|
memmove(gb->objects_y + j + 1, gb->objects_y + j, gb->n_visible_objs - j);
|
||||||
gb->visible_objs[j] = index;
|
gb->visible_objs[j] = index;
|
||||||
gb->objects_x[j] = oam_x;
|
gb->objects_x[j] = gb->mode2_x_bus;
|
||||||
gb->objects_y[j] = oam_y;
|
gb->objects_y[j] = gb->mode2_y_bus;
|
||||||
gb->n_visible_objs++;
|
gb->n_visible_objs++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,7 +229,7 @@ enum {
|
|||||||
|
|
||||||
/* Missing */
|
/* Missing */
|
||||||
|
|
||||||
/* CGB Paletts */
|
/* CGB Palettes */
|
||||||
GB_IO_BGPI = 0x68, // CGB Mode Only - Background Palette Index
|
GB_IO_BGPI = 0x68, // CGB Mode Only - Background Palette Index
|
||||||
GB_IO_BGPD = 0x69, // CGB Mode Only - Background Palette Data
|
GB_IO_BGPD = 0x69, // CGB Mode Only - Background Palette Data
|
||||||
GB_IO_OBPI = 0x6a, // CGB Mode Only - Object Palette Index
|
GB_IO_OBPI = 0x6a, // CGB Mode Only - Object Palette Index
|
||||||
@ -621,6 +621,8 @@ struct GB_gameboy_internal_s {
|
|||||||
uint16_t last_tile_index_address;
|
uint16_t last_tile_index_address;
|
||||||
bool cgb_repeated_a_frame;
|
bool cgb_repeated_a_frame;
|
||||||
uint8_t data_for_sel_glitch;
|
uint8_t data_for_sel_glitch;
|
||||||
|
uint8_t mode2_y_bus;
|
||||||
|
uint8_t mode2_x_bus;
|
||||||
)
|
)
|
||||||
|
|
||||||
/* Unsaved data. This includes all pointers, as well as everything that shouldn't be on a save state */
|
/* Unsaved data. This includes all pointers, as well as everything that shouldn't be on a save state */
|
||||||
|
Loading…
Reference in New Issue
Block a user