Partial emulation of reading VRAM right after mode 3
This commit is contained in:
parent
29b64d7545
commit
ffa569deeb
@ -603,14 +603,15 @@ static void advance_fetcher_state_machine(GB_gameboy_t *gb)
|
||||
/* This value is cached on the CGB-D and newer, so it cannot be used to mix tiles together */
|
||||
gb->fetcher_y = y;
|
||||
}
|
||||
gb->current_tile = gb->vram[map + x + y / 8 * 32];
|
||||
gb->last_tile_index_address = map + x + y / 8 * 32;
|
||||
gb->current_tile = gb->vram[gb->last_tile_index_address];
|
||||
if (gb->vram_ppu_blocked) {
|
||||
gb->current_tile = 0xFF;
|
||||
}
|
||||
if (GB_is_cgb(gb)) {
|
||||
/* The CGB actually accesses both the tile index AND the attributes in the same T-cycle.
|
||||
This probably means the CGB has a 16-bit data bus for the VRAM. */
|
||||
gb->current_tile_attributes = gb->vram[map + x + y / 8 * 32 + 0x2000];
|
||||
gb->current_tile_attributes = gb->vram[gb->last_tile_index_address + 0x2000];
|
||||
if (gb->vram_ppu_blocked) {
|
||||
gb->current_tile_attributes = 0xFF;
|
||||
}
|
||||
@ -667,8 +668,9 @@ static void advance_fetcher_state_machine(GB_gameboy_t *gb)
|
||||
if (gb->current_tile_attributes & 0x40) {
|
||||
y_flip = 0x7;
|
||||
}
|
||||
gb->last_tile_data_address = tile_address + ((y & 7) ^ y_flip) * 2 + 1;
|
||||
gb->current_tile_data[1] =
|
||||
gb->vram[tile_address + ((y & 7) ^ y_flip) * 2 + 1];
|
||||
gb->vram[gb->last_tile_data_address];
|
||||
if (gb->vram_ppu_blocked) {
|
||||
gb->current_tile_data[1] = 0xFF;
|
||||
}
|
||||
|
@ -538,6 +538,8 @@ struct GB_gameboy_internal_s {
|
||||
uint8_t window_tile_x;
|
||||
uint8_t lcd_x; // The LCD can go out of sync since the push signal is skipped in some cases.
|
||||
bool is_odd_frame;
|
||||
uint16_t last_tile_data_address;
|
||||
uint16_t last_tile_index_address;
|
||||
);
|
||||
|
||||
/* Unsaved data. This includes all pointers, as well as everything that shouldn't be on a save state */
|
||||
|
@ -146,6 +146,18 @@ static uint8_t read_vram(GB_gameboy_t *gb, uint16_t addr)
|
||||
if (gb->vram_read_blocked) {
|
||||
return 0xFF;
|
||||
}
|
||||
if (gb->display_state == 22 && GB_is_cgb(gb) && !gb->cgb_double_speed) {
|
||||
if (addr & 0x1000) {
|
||||
addr = gb->last_tile_index_address;
|
||||
}
|
||||
else if (gb->last_tile_data_address & 0x1000) {
|
||||
/* TODO: This is case is more complicated then the rest and differ between revisions
|
||||
It's probably affected by how VRAM is layed out, might be easier after a decap is done*/
|
||||
}
|
||||
else {
|
||||
addr = gb->last_tile_data_address;
|
||||
}
|
||||
}
|
||||
return gb->vram[(addr & 0x1FFF) + (uint16_t) gb->cgb_vram_bank * 0x2000];
|
||||
}
|
||||
|
||||
@ -551,6 +563,19 @@ static void write_vram(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
|
||||
//GB_log(gb, "Wrote %02x to %04x (VRAM) during mode 3\n", value, addr);
|
||||
return;
|
||||
}
|
||||
/* TODO: not verified */
|
||||
if (gb->display_state == 22 && GB_is_cgb(gb) && !gb->cgb_double_speed) {
|
||||
if (addr & 0x1000) {
|
||||
addr = gb->last_tile_index_address;
|
||||
}
|
||||
else if (gb->last_tile_data_address & 0x1000) {
|
||||
/* TODO: This is case is more complicated then the rest and differ between revisions
|
||||
It's probably affected by how VRAM is layed out, might be easier after a decap is done */
|
||||
}
|
||||
else {
|
||||
addr = gb->last_tile_data_address;
|
||||
}
|
||||
}
|
||||
gb->vram[(addr & 0x1FFF) + (uint16_t) gb->cgb_vram_bank * 0x2000] = value;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user