H/GDMA was 4 times faster than it should have been. Made it also more accurate. Fixes #56
This commit is contained in:
parent
51e3cb7b9f
commit
f1ec42d4ba
@ -280,7 +280,7 @@ struct GB_gameboy_internal_s {
|
|||||||
bool hdma_on;
|
bool hdma_on;
|
||||||
bool hdma_on_hblank;
|
bool hdma_on_hblank;
|
||||||
uint8_t hdma_steps_left;
|
uint8_t hdma_steps_left;
|
||||||
uint16_t hdma_cycles; // in 8MHz units
|
int16_t hdma_cycles; // in 8MHz units
|
||||||
uint16_t hdma_current_src, hdma_current_dest;
|
uint16_t hdma_current_src, hdma_current_dest;
|
||||||
|
|
||||||
uint8_t dma_steps_left;
|
uint8_t dma_steps_left;
|
||||||
|
@ -767,7 +767,7 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
|
|||||||
gb->hdma_on_hblank = (value & 0x80) != 0;
|
gb->hdma_on_hblank = (value & 0x80) != 0;
|
||||||
if (gb->hdma_on_hblank && (gb->io_registers[GB_IO_STAT] & 3) == 0) {
|
if (gb->hdma_on_hblank && (gb->io_registers[GB_IO_STAT] & 3) == 0) {
|
||||||
gb->hdma_on = true;
|
gb->hdma_on = true;
|
||||||
gb->hdma_cycles = 0;
|
gb->hdma_cycles = -8;
|
||||||
}
|
}
|
||||||
gb->io_registers[GB_IO_HDMA5] = value;
|
gb->io_registers[GB_IO_HDMA5] = value;
|
||||||
gb->hdma_steps_left = (gb->io_registers[GB_IO_HDMA5] & 0x7F) + 1;
|
gb->hdma_steps_left = (gb->io_registers[GB_IO_HDMA5] & 0x7F) + 1;
|
||||||
@ -775,7 +775,7 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
|
|||||||
if (gb->hdma_current_dest + (gb->hdma_steps_left << 4) > 0xFFFF) {
|
if (gb->hdma_current_dest + (gb->hdma_steps_left << 4) > 0xFFFF) {
|
||||||
gb->hdma_steps_left = (0x10000 - gb->hdma_current_dest) >> 4;
|
gb->hdma_steps_left = (0x10000 - gb->hdma_current_dest) >> 4;
|
||||||
}
|
}
|
||||||
gb->hdma_cycles = 0;
|
gb->hdma_cycles = -8;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Todo: what happens when starting a transfer during a transfer?
|
/* Todo: what happens when starting a transfer during a transfer?
|
||||||
@ -863,6 +863,7 @@ void GB_dma_run(GB_gameboy_t *gb)
|
|||||||
/* Todo: measure this value */
|
/* Todo: measure this value */
|
||||||
gb->dma_cycles -= 4;
|
gb->dma_cycles -= 4;
|
||||||
gb->dma_steps_left--;
|
gb->dma_steps_left--;
|
||||||
|
|
||||||
if (gb->dma_current_src < 0xe000) {
|
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);
|
||||||
}
|
}
|
||||||
@ -882,22 +883,22 @@ void GB_dma_run(GB_gameboy_t *gb)
|
|||||||
void GB_hdma_run(GB_gameboy_t *gb)
|
void GB_hdma_run(GB_gameboy_t *gb)
|
||||||
{
|
{
|
||||||
if (!gb->hdma_on) return;
|
if (!gb->hdma_on) return;
|
||||||
while (gb->hdma_cycles >= 0x10) {
|
while (gb->hdma_cycles >= 0x4) {
|
||||||
gb->hdma_cycles -= 0x10;
|
gb->hdma_cycles -= 0x4;
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 0x10; i++) {
|
GB_write_memory(gb, 0x8000 | (gb->hdma_current_dest++ & 0x1FFF), GB_read_memory(gb, (gb->hdma_current_src++)));
|
||||||
GB_write_memory(gb, 0x8000 | (gb->hdma_current_dest++ & 0x1FFF), GB_read_memory(gb, (gb->hdma_current_src++)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(--gb->hdma_steps_left == 0){
|
if ((gb->hdma_current_dest & 0xf) == 0) {
|
||||||
gb->hdma_on = false;
|
if(--gb->hdma_steps_left == 0){
|
||||||
gb->hdma_on_hblank = false;
|
gb->hdma_on = false;
|
||||||
gb->io_registers[GB_IO_HDMA5] &= 0x7F;
|
gb->hdma_on_hblank = false;
|
||||||
break;
|
gb->io_registers[GB_IO_HDMA5] &= 0x7F;
|
||||||
}
|
break;
|
||||||
if (gb->hdma_on_hblank) {
|
}
|
||||||
gb->hdma_on = false;
|
if (gb->hdma_on_hblank) {
|
||||||
break;
|
gb->hdma_on = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1438,6 +1438,6 @@ void GB_cpu_run(GB_gameboy_t *gb)
|
|||||||
if (gb->hdma_starting) {
|
if (gb->hdma_starting) {
|
||||||
gb->hdma_starting = false;
|
gb->hdma_starting = false;
|
||||||
gb->hdma_on = true;
|
gb->hdma_on = true;
|
||||||
gb->hdma_cycles = 0;
|
gb->hdma_cycles = -8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user