mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-27 03:31:49 +01:00
.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:
parent
f21a08ebfa
commit
12606da28e
@ -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).
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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 ***/
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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));
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
118
source/vdp.c
118
source/vdp.c
@ -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 */
|
||||||
|
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user