Mercurial > repos > blastem
diff vdp.c @ 623:66cc60215e5c
Fix most of the breakage caused by the vcounter/hcounter changes
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 18 Jun 2014 16:30:19 -0700 |
parents | b76d2a628ab9 |
children | 788545f4064f |
line wrap: on
line diff
--- a/vdp.c Tue Jun 17 19:01:01 2014 -0700 +++ b/vdp.c Wed Jun 18 16:30:19 2014 -0700 @@ -46,7 +46,7 @@ uint8_t color_map_init_done; -void init_vdp_context(vdp_context * context) +void init_vdp_context(vdp_context * context, uint8_t region_pal) { memset(context, 0, sizeof(*context)); context->vdpmem = malloc(VRAM_SIZE); @@ -133,6 +133,9 @@ context->debugcolors[color] = render_map_color(r, g, b); } } + if (region_pal) { + context->flags2 |= FLAG2_REGION_PAL; + } } int is_refresh(vdp_context * context, uint32_t slot) @@ -1428,7 +1431,7 @@ latch_mode(context); } uint8_t is_h40 = context->regs[REG_MODE_4] & BIT_H40; - if (is_h40 && slot == 167 || !is_h40 && slot == 134) { + if (is_h40 && slot == HBLANK_START_H40 || !is_h40 && slot == 134) { if (line >= inactive_start) { context->hint_counter = context->regs[REG_HINT]; } else if (context->hint_counter) { @@ -1467,7 +1470,7 @@ if (context->regs[REG_MODE_2] & DISPLAY_ENABLE && active_slot) { //run VDP rendering for a slot or a line if (is_h40) { - if (slot == 167 && line < inactive_start && (target_cycles - context->cycles) >= MCLKS_LINE) { + if (slot == HBLANK_START_H40 && line < inactive_start && (target_cycles - context->cycles) >= MCLKS_LINE) { vdp_h40_line(line, context); inccycles = MCLKS_LINE; context->vcounter++; @@ -1493,7 +1496,7 @@ context->hslot++; context->hslot &= 0xFF; if (is_h40) { - if (context->hslot == 167) { + if (context->hslot == HBLANK_START_H40) { context->vcounter++; } else if (context->hslot == 183) { context->hslot = 229; @@ -1507,10 +1510,17 @@ } } - if (context->vcounter == 0xEA) { - context->vcounter += 0xFA; - } else { - context->vcounter &= 0x1FF; + context->vcounter &= 0x1FF; + if (context->flags2 & FLAG2_REGION_PAL) { + if (context->latched_mode & BIT_PAL) { + if (context->vcounter == 0x10B) { + context->vcounter = 0x1D2; + } + } else if (context->vcounter == 0x103){ + context->vcounter = 0x1CA; + } + } else if (!(context->latched_mode & BIT_PAL) && context->vcounter == 0xEB) { + context->vcounter = 0x1E5; } context->cycles += inccycles; } @@ -1757,6 +1767,7 @@ line |= 1; } } + printf("hv_counter_read line: %d, horiz: %d, cycles: %d\n", line, linecyc, context->cycles); return (line << 8) | linecyc; } @@ -1782,6 +1793,88 @@ } } +uint32_t vdp_cycles_next_line(vdp_context * context) +{ + if (context->regs[REG_MODE_4] & BIT_H40) { + if (context->hslot < HBLANK_START_H40) { + return (HBLANK_START_H40 - context->hslot) * MCLKS_SLOT_H40; + } else if (context->hslot < 183) { + return MCLKS_LINE - (context->hslot - HBLANK_START_H40) * MCLKS_SLOT_H40; + } else { + return (256-context->hslot + HBLANK_START_H40) * MCLKS_SLOT_H40; + } + } else { + if (context->hslot < HBLANK_START_H32) { + return (HBLANK_START_H32 - context->hslot) * MCLKS_SLOT_H32; + } else if (context->hslot < 148) { + return MCLKS_LINE - (context->hslot - HBLANK_START_H32) * MCLKS_SLOT_H32; + } else { + return (256-context->hslot + HBLANK_START_H32) * MCLKS_SLOT_H32; + } + } +} + +uint32_t vdp_cycles_to_line(vdp_context * context, uint32_t target) +{ + uint32_t jump_start, jump_dst; + if (context->flags2 & FLAG2_REGION_PAL) { + if (context->latched_mode & BIT_PAL) { + jump_start = 0x10B; + jump_dst = 0x1D2; + } else { + jump_start = 0x103; + jump_dst = 0x1CA; + } + } else { + if (context->latched_mode & BIT_PAL) { + jump_start = 0; + jump_dst = 0; + } else { + jump_start = 0xEB; + jump_dst = 0x1E5; + } + } + uint32_t lines; + if (context->vcounter < target) { + if (target < jump_start) { + lines = target - context->vcounter; + } else { + lines = jump_start - context->vcounter + target - jump_dst; + } + } else { + if (context->vcounter < jump_start) { + lines = jump_start - context->vcounter + 512 - jump_dst; + } else { + lines = 512 - context->vcounter; + } + if (target < jump_start) { + lines += target; + } else { + lines += jump_start + target - jump_dst; + } + } + return MCLKS_LINE * (lines - 1) + vdp_cycles_next_line(context); +} + +uint32_t vdp_cycles_to_frame_end(vdp_context * context) +{ + uint32_t frame_end; + if (context->flags2 & FLAG2_REGION_PAL) { + if (context->latched_mode & BIT_PAL) { + frame_end = PAL_INACTIVE_START + 8; + } else { + frame_end = NTSC_INACTIVE_START + 8; + } + } else { + if (context->latched_mode & BIT_PAL) { + frame_end = 512; + } else { + frame_end = NTSC_INACTIVE_START + 8; + } + } + return context->cycles + vdp_cycles_to_line(context, frame_end); +} + uint32_t vdp_next_hint(vdp_context * context) { if (!(context->regs[REG_MODE_1] & BIT_HINT_EN)) { @@ -1791,13 +1884,14 @@ return context->cycles; } uint32_t inactive_start = context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START; - uint32_t line = context->cycles / MCLKS_LINE; - if (line >= inactive_start) { - return 0xFFFFFFFF; + uint32_t hint_line; + if (context->vcounter >= inactive_start) { + hint_line = context->regs[REG_HINT]; + } else { + hint_line = context->vcounter + context->hint_counter + 1; } - uint32_t linecyc = context->cycles % MCLKS_LINE; - uint32_t hcycle = context->cycles + context->hint_counter * MCLKS_LINE + MCLKS_LINE - linecyc; - return hcycle; + + return context->cycles + vdp_cycles_to_line(context, hint_line); } uint32_t vdp_next_vint(vdp_context * context) @@ -1808,29 +1902,44 @@ if (context->flags2 & FLAG2_VINT_PENDING) { return context->cycles; } - uint32_t inactive_start = context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START; - uint32_t vcycle = MCLKS_LINE * inactive_start; - if (context->regs[REG_MODE_4] & BIT_H40) { - vcycle += VINT_SLOT_H40 * MCLKS_SLOT_H40; - } else { - vcycle += VINT_SLOT_H32 * MCLKS_SLOT_H32; - } - if (vcycle < context->cycles) { - return 0xFFFFFFFF; - } - return vcycle; + + + return vdp_next_vint_z80(context); } uint32_t vdp_next_vint_z80(vdp_context * context) { uint32_t inactive_start = context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START; - uint32_t vcycle = MCLKS_LINE * inactive_start; + if (context->vcounter == inactive_start) { + if (context->regs[REG_MODE_4] & BIT_H40) { + if (context->hslot >= HBLANK_START_H40) { + if (context->hslot < 183) { + return context->cycles + (VINT_SLOT_H40 + 183 - context->hslot + 256 - 229) * MCLKS_SLOT_H40; + } else { + return context->cycles + (VINT_SLOT_H40 + 256 - context->hslot) * MCLKS_SLOT_H40; + } + } else if (context->hslot < VINT_SLOT_H40) { + return context->cycles + (VINT_SLOT_H40 - context->hslot) * MCLKS_SLOT_H40; + } + } else { + if (context->hslot >= HBLANK_START_H32) { + if (context->hslot < 148) { + return context->cycles + (VINT_SLOT_H32 + 148 - context->hslot + 256 - 233) * MCLKS_SLOT_H32; + } else { + return context->cycles + (VINT_SLOT_H32 + 256 - context->hslot) * MCLKS_SLOT_H32; + } + } else if (context->hslot < VINT_SLOT_H32) { + return context->cycles + (VINT_SLOT_H32 - context->hslot) * MCLKS_SLOT_H32; + } + } + } + int32_t cycles_to_vint = vdp_cycles_to_line(context, inactive_start); if (context->regs[REG_MODE_4] & BIT_H40) { - vcycle += VINT_SLOT_H40 * MCLKS_SLOT_H40; + cycles_to_vint += (VINT_SLOT_H40 + 183 - HBLANK_START_H40 + 256 - 229) * MCLKS_SLOT_H40; } else { - vcycle += VINT_SLOT_H32 * MCLKS_SLOT_H32; + cycles_to_vint += (VINT_SLOT_H32 + 148 - HBLANK_START_H32 + 256 - 233) * MCLKS_SLOT_H32; } - return vcycle; + return context->cycles + cycles_to_vint; } void vdp_int_ack(vdp_context * context, uint16_t int_num)