.improved mid-frame screen changes (fixes Bugs Bunny in Double Trouble)

.improved VDP FIFO timing accuracy
.improved Z80 interrupt accuracy
.modified CPU Hard Reset start cycles
This commit is contained in:
ekeeke31 2010-06-10 07:57:18 +00:00
parent f21a08ebfa
commit 12606da28e
11 changed files with 204 additions and 143 deletions

View File

@ -27,7 +27,6 @@ of samples per frame and keeping PSG & FM chips in sync.
* added support for 2-Cell vertical scrolling in Interlaced 2 mode * added support for 2-Cell vertical scrolling in Interlaced 2 mode
* added proper HV Counter latch support (fixes Sunset Riders intro) * added proper HV Counter latch support (fixes Sunset Riders intro)
* fixed left-most column vertical scrolling when horizontally scrolled (Gynoug, F1) * fixed left-most column vertical scrolling when horizontally scrolled (Gynoug, F1)
* fixed VBLANK transition line checks
* improved VDP FIFO timings accuracy: fixes Sol Deace intro * improved VDP FIFO timings accuracy: fixes Sol Deace intro
* improved sprite masking accuracy (thanks to Nemesis for his sprite test program) * improved sprite masking accuracy (thanks to Nemesis for his sprite test program)
* improved HBLANK flag timing accuracy: fixes Mega Turrican (Sky level) * improved HBLANK flag timing accuracy: fixes Mega Turrican (Sky level)
@ -41,6 +40,7 @@ of samples per frame and keeping PSG & FM chips in sync.
--------------- ---------------
* updated Z80 core to last version (fixes interrupt Mode 0 timing and some BIT instructions). * updated Z80 core to last version (fixes interrupt Mode 0 timing and some BIT instructions).
* fixed some Z80 instructions timing. * fixed some Z80 instructions timing.
* improved Z80 interrupt accuracy
* improved 68k accuracy (initial Reset timing + auto-vectored interrupts handling). * improved 68k accuracy (initial Reset timing + auto-vectored interrupts handling).
* improved 68k timing accuracy for DIVU/DVIS (thanks to Jorge Cwik) & MULU/MULS instructions. * improved 68k timing accuracy for DIVU/DVIS (thanks to Jorge Cwik) & MULU/MULS instructions.
* improved Z80 & 68k cpu execution/synchronization accuracy by using Master Clock as common reference (now run exactly 3420 M-Cycles per line). * improved Z80 & 68k cpu execution/synchronization accuracy by using Master Clock as common reference (now run exactly 3420 M-Cycles per line).

View File

@ -125,12 +125,14 @@ void gen_hardreset(void)
if (config.bios_enabled == 3) if (config.bios_enabled == 3)
m68k_memory_map[0].base = bios_rom; m68k_memory_map[0].base = bios_rom;
/* Reset CPU cycle counts */ /* Reset CPU cycles (check EA logo corruption, no glitches for Skitchin/Budokan on PAL 60hz MD2 with TMSS) */
mcycles_68k = 0; mcycles_68k = mcycles_z80 = (rand() % lines_per_frame) * MCYCLES_PER_LINE;
mcycles_z80 = 0;
zstate = 0; /* Z80 is resetted & has control of the bus */ /* Z80 bus is released & Z80 reset is asserted */
zbank = 0; /* Assume default bank is $000000-$007FFF */ zstate = 0;
/* Assume default bank is $000000-$007FFF */
zbank = 0;
/* Reset 68k, Z80 & YM2612 */ /* Reset 68k, Z80 & YM2612 */
m68k_pulse_reset(); m68k_pulse_reset();
@ -149,11 +151,11 @@ void gen_softreset(int state)
} }
else else
{ {
/* Reset Action Replay */ /* Reset Pro Action Replay (required in Trainer mode) */
if (config.lock_on == TYPE_AR) if (config.lock_on == TYPE_AR)
datel_reset(0); datel_reset(0);
/* VDP is not reseted so 68k & Z80 could restart anywhere in the emulated frame */ /* 68k & Z80 could restart anywhere in VDP frame (fixes Eternal Champions, X-Men 2) */
mcycles_68k = mcycles_z80 = (uint32)((MCYCLES_PER_LINE * lines_per_frame) * ((double)rand() / (double)RAND_MAX)); mcycles_68k = mcycles_z80 = (uint32)((MCYCLES_PER_LINE * lines_per_frame) * ((double)rand() / (double)RAND_MAX));
/* Reset 68k, Z80 & YM2612 */ /* Reset 68k, Z80 & YM2612 */
@ -199,7 +201,7 @@ void gen_reset_w(uint32 state, uint32 cycles)
if (state == (zstate & 1)) if (state == (zstate & 1))
return; return;
if (state) /* !ZRESET released */ if (state) /* !ZRESET inactive */
{ {
/* if z80 is restarted, resynchronize with 68k */ /* if z80 is restarted, resynchronize with 68k */
if (zstate == 0) if (zstate == 0)
@ -208,16 +210,16 @@ void gen_reset_w(uint32 state, uint32 cycles)
/* reset Z80 */ /* reset Z80 */
z80_reset(); z80_reset();
/* release Z80 reset */ /* negate Z80 reset */
zstate |= 1; zstate |= 1;
} }
else /* !ZRESET enabled */ else /* !ZRESET active */
{ {
/* if z80 was running, resynchronize with 68k */ /* if z80 was running, resynchronize with 68k */
if (zstate == 1) if (zstate == 1)
z80_run(cycles); z80_run(cycles);
/* hold Z80 reset */ /* assert Z80 reset */
zstate &= 2; zstate &= 2;
} }
@ -232,7 +234,5 @@ void gen_bank_w (uint32 state)
int z80_irq_callback (int param) int z80_irq_callback (int param)
{ {
zirq = 0;
z80_set_irq_line (0, CLEAR_LINE);
return 0xFF; return 0xFF;
} }

View File

@ -96,7 +96,7 @@ void config_default(void)
config.xscale = 0; config.xscale = 0;
config.yscale = 0; config.yscale = 0;
config.aspect = 1; config.aspect = 1;
config.overscan = 1; config.overscan = 3;
if (VIDEO_HaveComponentCable()) if (VIDEO_HaveComponentCable())
config.render = 2; config.render = 2;
else else

View File

@ -437,7 +437,7 @@ int slot_save(int slot, int device)
return 0; return 0;
} }
/* Read into buffer (2k blocks) */ /* Write from buffer (2k blocks) */
while (filesize > FATCHUNK) while (filesize > FATCHUNK)
{ {
fwrite(savebuffer + done, FATCHUNK, 1, fp); fwrite(savebuffer + done, FATCHUNK, 1, fp);

View File

@ -1050,7 +1050,7 @@ static void systemmenu ()
else if (config.region_detect == 2) else if (config.region_detect == 2)
sprintf (items[0].text, "Console Region: EUR"); sprintf (items[0].text, "Console Region: EUR");
else if (config.region_detect == 3) else if (config.region_detect == 3)
sprintf (items[0].text, "Console Region: JAP"); sprintf (items[0].text, "Console Region: JPN");
if (cart.romsize) if (cart.romsize)
{ {
@ -1211,7 +1211,14 @@ static void videomenu ()
else else
sprintf (items[VI_OFFSET].text, "NTSC Filter: OFF"); sprintf (items[VI_OFFSET].text, "NTSC Filter: OFF");
sprintf (items[VI_OFFSET+1].text, "Borders: %s", config.overscan ? "ON" : "OFF"); if (config.overscan == 3)
sprintf (items[VI_OFFSET+1].text, "Borders: ALL");
else if (config.overscan == 2)
sprintf (items[VI_OFFSET+1].text, "Borders: H ONLY");
else if (config.overscan == 1)
sprintf (items[VI_OFFSET+1].text, "Borders: V ONLY");
else
sprintf (items[VI_OFFSET+1].text, "Borders: NONE");
if (config.aspect == 1) if (config.aspect == 1)
sprintf (items[VI_OFFSET+2].text,"Aspect: ORIGINAL (4:3)"); sprintf (items[VI_OFFSET+2].text,"Aspect: ORIGINAL (4:3)");
@ -1360,8 +1367,15 @@ static void videomenu ()
break; break;
case VI_OFFSET+1: /*** overscan emulation ***/ case VI_OFFSET+1: /*** overscan emulation ***/
config.overscan ^= 1; config.overscan = (config.overscan + 1) % 4;
sprintf (items[VI_OFFSET+1].text, "Borders: %s", config.overscan ? "ON" : "OFF"); if (config.overscan == 3)
sprintf (items[VI_OFFSET+1].text, "Borders: ALL");
else if (config.overscan == 2)
sprintf (items[VI_OFFSET+1].text, "Borders: H ONLY");
else if (config.overscan == 1)
sprintf (items[VI_OFFSET+1].text, "Borders: V ONLY");
else
sprintf (items[VI_OFFSET+1].text, "Borders: NONE");
break; break;
case VI_OFFSET+2: /*** aspect ratio ***/ case VI_OFFSET+2: /*** aspect ratio ***/

View File

@ -1332,24 +1332,8 @@ void gx_video_Start(void)
tvmodes[2]->xfbMode = VI_XFBMODE_DF; tvmodes[2]->xfbMode = VI_XFBMODE_DF;
} }
/* overscan emulation */ /* force video update */
if (config.overscan) bitmap.viewport.changed = 3;
{
bitmap.viewport.x = (reg[12] & 1) ? 16 : 12;
bitmap.viewport.y = (reg[1] & 8) ? 0 : 8;
if (vdp_pal)
bitmap.viewport.y += 24;
}
else
{
bitmap.viewport.x = 0;
bitmap.viewport.y = 0;
}
/* reinitialize video size */
vwidth = bitmap.viewport.w + (2 * bitmap.viewport.x);
vheight = bitmap.viewport.h + (2 * bitmap.viewport.y);
bitmap.viewport.changed = 1;
/* NTSC filter */ /* NTSC filter */
if (config.ntsc) if (config.ntsc)
@ -1394,28 +1378,22 @@ void gx_video_Start(void)
/* GX render update */ /* GX render update */
void gx_video_Update(void) void gx_video_Update(void)
{ {
int update = bitmap.viewport.changed; int update = bitmap.viewport.changed & 1;
/* check if display has changed */ /* check if display has changed */
if (update) if (update)
{ {
/* update texture size */ /* update texture size */
int old_vwidth = vwidth;
vwidth = bitmap.viewport.w + (2 * bitmap.viewport.x); vwidth = bitmap.viewport.w + (2 * bitmap.viewport.x);
vheight = bitmap.viewport.h + (2 * bitmap.viewport.y); vheight = bitmap.viewport.h + (2 * bitmap.viewport.y);
/* if width has been changed, do no render this frame */
/* this fixes texture glitches when changing width middle-frame */
if (vwidth != old_vwidth)
return;
/* interlaced mode */ /* interlaced mode */
if (config.render && interlaced) if (config.render && interlaced)
vheight = vheight << 1; vheight = vheight << 1;
/* ntsc filter */ /* ntsc filter */
if (config.ntsc) if (config.ntsc)
vwidth = (reg[12]&1) ? MD_NTSC_OUT_WIDTH(vwidth) : SMS_NTSC_OUT_WIDTH(vwidth); vwidth = (reg[12] & 1) ? MD_NTSC_OUT_WIDTH(vwidth) : SMS_NTSC_OUT_WIDTH(vwidth);
/* texels size must be multiple of 4 */ /* texels size must be multiple of 4 */
vwidth = (vwidth >> 2) << 2; vwidth = (vwidth >> 2) << 2;
@ -1488,7 +1466,7 @@ void gx_video_Update(void)
/* force audio DMA resynchronization */ /* force audio DMA resynchronization */
audioStarted = 0; audioStarted = 0;
bitmap.viewport.changed = 0; bitmap.viewport.changed &= ~1;
} }
} }

View File

@ -1490,8 +1490,9 @@ static void render_obj(int line, uint8 *buf, uint8 *table)
int height; int height;
int v_line; int v_line;
int column; int column;
int max = bitmap.viewport.w;
int left = 0x80; int left = 0x80;
int right = 0x80 + bitmap.viewport.w; int right = 0x80 + max;
uint8 *s, *lb; uint8 *s, *lb;
uint16 name, index; uint16 name, index;
@ -1506,7 +1507,9 @@ static void render_obj(int line, uint8 *buf, uint8 *table)
/* sprite masking (requires at least one sprite with xpos > 0) */ /* sprite masking (requires at least one sprite with xpos > 0) */
if (xpos) if (xpos)
{
spr_over = 1; spr_over = 1;
}
else if (spr_over) else if (spr_over)
{ {
spr_over = 0; spr_over = 0;
@ -1539,9 +1542,9 @@ static void render_obj(int line, uint8 *buf, uint8 *table)
/* number of tiles to draw */ /* number of tiles to draw */
/* adjusted for sprite limit */ /* adjusted for sprite limit */
if (pixelcount > bitmap.viewport.w) if (pixelcount > max)
{ {
width -= (pixelcount - bitmap.viewport.w); width -= (pixelcount - max);
} }
width >>= 3; width >>= 3;
@ -1555,7 +1558,7 @@ static void render_obj(int line, uint8 *buf, uint8 *table)
} }
/* sprite limit (256 or 320 pixels) */ /* sprite limit (256 or 320 pixels) */
if (pixelcount >= bitmap.viewport.w) if (pixelcount >= max)
{ {
spr_over = 1; spr_over = 1;
return; return;
@ -1580,8 +1583,9 @@ static void render_obj_im2(int line, int odd, uint8 *buf, uint8 *table)
int height; int height;
int v_line; int v_line;
int column; int column;
int max = bitmap.viewport.w;
int left = 0x80; int left = 0x80;
int right = 0x80 + bitmap.viewport.w; int right = 0x80 + max;
uint8 *s, *lb; uint8 *s, *lb;
uint16 name, index; uint16 name, index;
@ -1597,7 +1601,9 @@ static void render_obj_im2(int line, int odd, uint8 *buf, uint8 *table)
/* sprite masking (requires at least one sprite with xpos > 0) */ /* sprite masking (requires at least one sprite with xpos > 0) */
if (xpos) if (xpos)
{
spr_over = 1; spr_over = 1;
}
else if(spr_over) else if(spr_over)
{ {
spr_over = 0; spr_over = 0;
@ -1630,8 +1636,8 @@ static void render_obj_im2(int line, int odd, uint8 *buf, uint8 *table)
/* number of tiles to draw */ /* number of tiles to draw */
/* adjusted for sprite limit */ /* adjusted for sprite limit */
if (pixelcount > bitmap.viewport.w) if (pixelcount > max)
width -= (pixelcount - bitmap.viewport.w); width -= (pixelcount - max);
width >>= 3; width >>= 3;
for(column = 0; column < width; column += 1, lb+=8) for(column = 0; column < width; column += 1, lb+=8)
@ -1646,7 +1652,7 @@ static void render_obj_im2(int line, int odd, uint8 *buf, uint8 *table)
} }
/* sprite limit (256 or 320 pixels) */ /* sprite limit (256 or 320 pixels) */
if (pixelcount >= bitmap.viewport.w) if (pixelcount >= max)
{ {
spr_over = 1; spr_over = 1;
return; return;
@ -1736,25 +1742,24 @@ void render_shutdown(void)
/* Line render function */ /* Line render function */
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
void render_line(int line, int overscan) void render_line(int line)
{ {
int width = bitmap.viewport.w;
int x_offset = bitmap.viewport.x;
/* display OFF */ /* display OFF */
if (reg[0] & 0x01) if (reg[0] & 0x01)
return; return;
uint8 *lb = tmp_buf;
int width = bitmap.viewport.w;
int x_offset = bitmap.viewport.x;
/* background color (blanked display or vertical borders) */ /* background color (blanked display or vertical borders) */
if (!(reg[1] & 0x40) || overscan) if (!(reg[1] & 0x40) || (status & 8))
{ {
width += 2 * x_offset; width += 2 * x_offset;
memset(&tmp_buf[0x20 - x_offset], 0x40, width); memset(&lb[0x20 - x_offset], 0x40, width);
} }
else else
{ {
uint8 *lb = tmp_buf;
/* update pattern generator */ /* update pattern generator */
if (bg_list_index) if (bg_list_index)
{ {
@ -1810,7 +1815,11 @@ void render_line(int line, int overscan)
} }
} }
/* borders */ /* left-most column blanking */
if(reg[0] & 0x20)
memset(&lb[0x20], 0x40, 0x08);
/* horizontal borders */
if (x_offset) if (x_offset)
{ {
memset(&lb[0x20 - x_offset], 0x40, x_offset); memset(&lb[0x20 - x_offset], 0x40, x_offset);
@ -1877,7 +1886,7 @@ void window_clip(void)
int hf = (reg[17] >> 7) & 1; int hf = (reg[17] >> 7) & 1;
/* Display size */ /* Display size */
int sw = bitmap.viewport.w >> 4; int sw = (reg[12] & 1) ? 20 : 16;
/* Clear clipping data */ /* Clear clipping data */
memset(&clip, 0, sizeof(clip)); memset(&clip, 0, sizeof(clip));

View File

@ -31,7 +31,7 @@ extern uint32 object_index_count;
extern void render_init(void); extern void render_init(void);
extern void render_reset(void); extern void render_reset(void);
extern void render_shutdown(void); extern void render_shutdown(void);
extern void render_line(int line, int overscan); extern void render_line(int line);
extern void remap_buffer(int line,int width); extern void remap_buffer(int line,int width);
extern void window_clip(void); extern void window_clip(void);
extern void parse_satb(int line); extern void parse_satb(int line);

View File

@ -327,19 +327,52 @@ void system_shutdown (void)
****************************************************************/ ****************************************************************/
void system_frame (int do_skip) void system_frame (int do_skip)
{ {
/* update display settings */ int start = 0;
int line; int end = 0;
int vdp_height = bitmap.viewport.h; int line = 0;
int end_line = vdp_height + bitmap.viewport.y;
int start_line = lines_per_frame - bitmap.viewport.y; /* display changed during VBLANK */
int old_interlaced = interlaced; if (bitmap.viewport.changed & 2)
interlaced = (reg[12] & 2) >> 1;
if (old_interlaced != interlaced)
{ {
bitmap.viewport.changed = 1; bitmap.viewport.changed &= ~2;
im2_flag = ((reg[12] & 6) == 6);
odd_frame = 1; /* interlaced mode */
int old_interlaced = interlaced;
interlaced = (reg[12] & 2) >> 1;
if (old_interlaced != interlaced)
{
im2_flag = ((reg[12] & 6) == 6);
odd_frame = 1;
bitmap.viewport.changed = 1;
}
/* screen height */
if (reg[1] & 8)
{
bitmap.viewport.h = 240;
bitmap.viewport.y = (config.overscan & 1) ? (vdp_pal ? 24 : 0) : 0;
}
else
{
bitmap.viewport.h = 224;
bitmap.viewport.y = (config.overscan & 1) ? (vdp_pal ? 32 : 8) : 0;
}
/* screen width */
if (reg[12] & 1)
{
bitmap.viewport.w = 320;
bitmap.viewport.x = (config.overscan & 2) ? 16 : 0;
}
else
{
bitmap.viewport.w = 256;
bitmap.viewport.x = (config.overscan & 2) ? 12 : 0;
}
} }
/* Z80 interrupt flag */
int zirq = 0;
/* clear VBLANK, DMA, FIFO FULL & field flags */ /* clear VBLANK, DMA, FIFO FULL & field flags */
status &= 0xFEE5; status &= 0xFEE5;
@ -349,8 +382,8 @@ void system_frame (int do_skip)
/* even/odd field flag (interlaced modes only) */ /* even/odd field flag (interlaced modes only) */
odd_frame ^= 1; odd_frame ^= 1;
if (odd_frame && interlaced) if (interlaced)
status |= 0x0010; status |= (odd_frame << 4);
/* reload HCounter */ /* reload HCounter */
int h_counter = reg[10]; int h_counter = reg[10];
@ -382,10 +415,10 @@ void system_frame (int do_skip)
if (status & 8) if (status & 8)
{ {
/* render overscan */ /* render overscan */
if (!do_skip && ((line < end_line) || (line >= start_line))) if (!do_skip && ((line < end) || (line >= start)))
render_line(line, 1); render_line(line);
/* clear any pending Z80 interrupt */ /* clear pending Z80 interrupt */
if (zirq) if (zirq)
{ {
zirq = 0; zirq = 0;
@ -406,18 +439,34 @@ void system_frame (int do_skip)
} }
/* end of active display */ /* end of active display */
if (line == vdp_height) if (line == bitmap.viewport.h)
{ {
/* render overscan */ /* set border area */
if (!do_skip && (line < end_line)) start = lines_per_frame - bitmap.viewport.y;
render_line(line, 1); end = bitmap.viewport.h + bitmap.viewport.y;
/* update inputs (doing this here fix Warriors of Eternal Sun) */ /* check viewport changes */
osd_input_Update(); if (bitmap.viewport.h != bitmap.viewport.oh)
{
bitmap.viewport.oh = bitmap.viewport.h;
bitmap.viewport.changed |= 1;
}
if (bitmap.viewport.w != bitmap.viewport.ow)
{
bitmap.viewport.ow = bitmap.viewport.w;
bitmap.viewport.changed |= 1;
}
/* set VBLANK flag */ /* set VBLANK flag */
status |= 0x08; status |= 0x08;
/* render overscan */
if (!do_skip && bitmap.viewport.y)
render_line(line);
/* update inputs (doing this here fix Warriors of Eternal Sun) */
osd_input_Update();
/* Z80 interrupt is 16ms period (one frame) and 64us length (one scanline) */ /* Z80 interrupt is 16ms period (one frame) and 64us length (one scanline) */
zirq = 1; zirq = 1;
z80_set_irq_line(0, ASSERT_LINE); z80_set_irq_line(0, ASSERT_LINE);
@ -445,7 +494,7 @@ void system_frame (int do_skip)
parse_satb(0x80 + line); parse_satb(0x80 + line);
/* render scanline */ /* render scanline */
render_line(line, 0); render_line(line);
} }
} }

View File

@ -50,7 +50,6 @@ uint16 status; /* VDP status flags */
uint8 dmafill; /* next VDP Write is DMA Fill */ uint8 dmafill; /* next VDP Write is DMA Fill */
uint8 hint_pending; /* 0= Line interrupt is pending */ uint8 hint_pending; /* 0= Line interrupt is pending */
uint8 vint_pending; /* 1= Frame interrupt is pending */ uint8 vint_pending; /* 1= Frame interrupt is pending */
uint8 zirq; /* Z80 IRQ status */
uint8 irq_status; /* 68K IRQ status */ uint8 irq_status; /* 68K IRQ status */
/* Global variables */ /* Global variables */
@ -161,7 +160,6 @@ void vdp_reset(void)
pending = 0; pending = 0;
hint_pending = 0; hint_pending = 0;
vint_pending = 0; vint_pending = 0;
zirq = 0;
irq_status = 0; irq_status = 0;
hvc_latch = 0; hvc_latch = 0;
v_counter = 0; v_counter = 0;
@ -204,21 +202,21 @@ void vdp_reset(void)
hctab = cycle2hc32; hctab = cycle2hc32;
/* reset display area */ /* reset display area */
bitmap.viewport.w = 256; bitmap.viewport.w = 256;
bitmap.viewport.h = 224; bitmap.viewport.h = 224;
bitmap.viewport.changed = 1; bitmap.viewport.ow = 256;
bitmap.viewport.oh = 224;
/* reset overscan area */ /* reset overscan area */
bitmap.viewport.x = 0; bitmap.viewport.x = 0;
bitmap.viewport.y = 0; bitmap.viewport.y = 0;
if (config.overscan) if (config.overscan & 1)
{
bitmap.viewport.x = 12;
bitmap.viewport.y = vdp_pal ? 32 : 8; bitmap.viewport.y = vdp_pal ? 32 : 8;
} if (config.overscan & 2)
bitmap.viewport.x = 12;
/* initialize some registers (normally set by BIOS) */ /* reset some registers normally set by BIOS */
if (config.bios_enabled != 3) if (config.bios_enabled == 1)
{ {
reg_w(0 , 0x04); /* Palette bit set */ reg_w(0 , 0x04); /* Palette bit set */
reg_w(1 , 0x04); /* Mode 5 enabled */ reg_w(1 , 0x04); /* Mode 5 enabled */
@ -244,11 +242,6 @@ void vdp_restore(uint8 *vdp_regs)
vctab = (vdp_pal) ? ((reg[1] & 8) ? vc_pal_240 : vc_pal_224) : vc_ntsc_224; vctab = (vdp_pal) ? ((reg[1] & 8) ? vc_pal_240 : vc_pal_224) : vc_ntsc_224;
hctab = (reg[12] & 1) ? cycle2hc40 : cycle2hc32; hctab = (reg[12] & 1) ? cycle2hc40 : cycle2hc32;
/* reinitialize overscan area */
bitmap.viewport.x = config.overscan ? ((reg[12] & 1) ? 16 : 12) : 0;
bitmap.viewport.y = config.overscan ? (((reg[1] & 8) ? 0 : 8) + (vdp_pal ? 24 : 0)) : 0;
bitmap.viewport.changed = 1;
/* restore FIFO timings */ /* restore FIFO timings */
fifo_latency = (reg[12] & 1) ? 190 : 214; fifo_latency = (reg[12] & 1) ? 190 : 214;
if ((code & 0x0F) == 0x01) if ((code & 0x0F) == 0x01)
@ -501,18 +494,12 @@ void vdp_data_w(unsigned int data)
/* update VDP FIFO */ /* update VDP FIFO */
fifo_update(mcycles_68k); fifo_update(mcycles_68k);
if (fifo_write_cnt == 0)
{
/* reset cycle counter */
fifo_lastwrite = mcycles_68k;
/* FIFO is not empty anymore */
status &= 0xFDFF;
}
/* increase FIFO word count */ /* increase FIFO word count */
fifo_write_cnt ++; fifo_write_cnt ++;
/* FIFO is not empty anymore */
status &= 0xFDFF;
/* FIFO full ? */ /* FIFO full ? */
if (fifo_write_cnt >= 4) if (fifo_write_cnt >= 4)
{ {
@ -818,26 +805,29 @@ static void reg_w(unsigned int r, unsigned int d)
/* See if the viewport height has actually been changed */ /* See if the viewport height has actually been changed */
if (r & 0x08) if (r & 0x08)
{ {
/* PAL mode only ! */ /* Update V Counter table */
if (vdp_pal) if (vdp_pal)
vctab = (d & 8) ? vc_pal_240 : vc_pal_224;
/* Update viewport */
if (status & 8)
{ {
/* changes should be applied on next frame */
bitmap.viewport.changed |= 2;
}
else
{
/* Update active display */
if (d & 8) if (d & 8)
{ {
bitmap.viewport.h = 240; bitmap.viewport.h = 240;
if (config.overscan) bitmap.viewport.y = (config.overscan & 1) ? (vdp_pal ? 24 : 0) : 0;
bitmap.viewport.y = 24;
vctab = vc_pal_240;
} }
else else
{ {
bitmap.viewport.h = 224; bitmap.viewport.h = 224;
if (config.overscan) bitmap.viewport.y = (config.overscan & 1) ? (vdp_pal ? 32 : 8) : 0;
bitmap.viewport.y = 32;
vctab = vc_pal_224;
} }
/* update viewport */
bitmap.viewport.changed = 1;
} }
} }
@ -861,8 +851,8 @@ static void reg_w(unsigned int r, unsigned int d)
#ifdef LOGVDP #ifdef LOGVDP
error("Line redrawn (%d sprites) \n",object_index_count); error("Line redrawn (%d sprites) \n",object_index_count);
#endif #endif
/* re-render line */ /* redraw entire line */
render_line(v_counter, 0); render_line(v_counter);
} }
#ifdef LOGVDP #ifdef LOGVDP
else else
@ -939,12 +929,7 @@ static void reg_w(unsigned int r, unsigned int d)
/* Update HC table */ /* Update HC table */
hctab = cycle2hc40; hctab = cycle2hc40;
/* Update viewport width */
bitmap.viewport.w = 320;
if (config.overscan)
bitmap.viewport.x = 16;
/* Update fifo timings */ /* Update fifo timings */
fifo_latency = 190; fifo_latency = 190;
} }
@ -959,23 +944,50 @@ static void reg_w(unsigned int r, unsigned int d)
/* Update HC table */ /* Update HC table */
hctab = cycle2hc32; hctab = cycle2hc32;
/* Update viewport width */
bitmap.viewport.w = 256;
if (config.overscan)
bitmap.viewport.x = 12;
/* Update fifo timings */ /* Update fifo timings */
fifo_latency = 214; fifo_latency = 214;
} }
if ((code & 0x0F) == 0x01)
fifo_latency *= 2;
/* Update viewport */ if ((code & 0x0F) == 0x01)
bitmap.viewport.changed = 1; fifo_latency = fifo_latency * 2;
/* Update clipping */ /* Update clipping */
window_clip(); window_clip();
/* Update viewport */
if (status & 8)
{
/* changes should be applied on next frame */
bitmap.viewport.changed |= 2;
}
else
{
/* Update active display */
if (d & 1)
{
bitmap.viewport.w = 320;
bitmap.viewport.x = (config.overscan & 2) ? 16 : 0;
}
else
{
bitmap.viewport.w = 256;
bitmap.viewport.x = (config.overscan & 2) ? 12 : 0;
}
/* display width changed during HBLANK (Bugs Bunny Double Trouble) */
if (mcycles_68k <= (mcycles_vdp + 860))
{
/* redraw entire line */
render_line(v_counter);
}
}
}
/* Interlaced modes */
if (r & 0x06)
{
/* changes should be applied on next frame */
bitmap.viewport.changed |= 2;
} }
/* See if the S/TE mode bit has changed */ /* See if the S/TE mode bit has changed */

View File

@ -38,7 +38,6 @@ extern uint16 status;
extern uint8 dmafill; extern uint8 dmafill;
extern uint8 hint_pending; extern uint8 hint_pending;
extern uint8 vint_pending; extern uint8 vint_pending;
extern uint8 zirq;
extern uint8 irq_status; extern uint8 irq_status;
/* Global variables */ /* Global variables */