Skip to content

Commit

Permalink
Merge branch 'ekeeke:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
ds22x authored Mar 9, 2024
2 parents c2c8a49 + 6972a5b commit 541229d
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 134 deletions.
1 change: 1 addition & 0 deletions HISTORY.txt
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ Genesis Plus GX 1.7.5 (xx/xx/xxxx) (Eke-Eke)
* improved Mode 5 sprites parsing accuracy (verified on real hardware)
* improved Mode 5 sprites rendering timings (fixes "Overdrive" demo)
* improved FIFO timings accuracy (fixes "Overdrive" Demo)
* improved FIFO emulation (fixes potential lockup when switching between H32 & H40 mode during active display)
* improved H-Counter accuracy in H32 mode
* improved VDP status timing accuracy
* improved HBLANK flag timing accuracy (verified on real hardware by Nemesis)
Expand Down
Binary file modified builds/genesis_plus_gx_libretro.dll
Binary file not shown.
Binary file modified builds/genplus_cube.dol
Binary file not shown.
Binary file modified builds/genplus_wii.dol
Binary file not shown.
26 changes: 16 additions & 10 deletions core/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,8 +352,10 @@ void system_frame_gen(int do_skip)
mcycles_vdp = 0;

/* reset VDP FIFO */
fifo_write_cnt = 0;
fifo_slots = 0;
fifo_cycles[0] = 0;
fifo_cycles[1] = 0;
fifo_cycles[2] = 0;
fifo_cycles[3] = 0;

/* check if display setings have changed during previous frame */
if (bitmap.viewport.changed & 2)
Expand Down Expand Up @@ -438,8 +440,8 @@ void system_frame_gen(int do_skip)
/* clear DMA Busy, FIFO FULL & field flags */
status &= 0xFEED;

/* set VBLANK & FIFO EMPTY flags */
status |= 0x0208;
/* set VBLANK flag */
status |= 0x08;

/* check interlaced modes */
if (interlaced)
Expand Down Expand Up @@ -693,8 +695,10 @@ void system_frame_scd(int do_skip)
scd.cycles = 0;

/* reset VDP FIFO */
fifo_write_cnt = 0;
fifo_slots = 0;
fifo_cycles[0] = 0;
fifo_cycles[1] = 0;
fifo_cycles[2] = 0;
fifo_cycles[3] = 0;

/* check if display setings have changed during previous frame */
if (bitmap.viewport.changed & 2)
Expand Down Expand Up @@ -779,8 +783,8 @@ void system_frame_scd(int do_skip)
/* clear DMA Busy, FIFO FULL & field flags */
status &= 0xFEED;

/* set VBLANK & FIFO EMPTY flags */
status |= 0x0208;
/* set VBLANK flag */
status |= 0x08;

/* check interlaced modes */
if (interlaced)
Expand Down Expand Up @@ -1018,8 +1022,10 @@ void system_frame_sms(int do_skip)
mcycles_vdp = 0;

/* reset VDP FIFO */
fifo_write_cnt = 0;
fifo_slots = 0;
fifo_cycles[0] = 0;
fifo_cycles[1] = 0;
fifo_cycles[2] = 0;
fifo_cycles[3] = 0;

/* check if display settings has changed during previous frame */
if (bitmap.viewport.changed & 2)
Expand Down
186 changes: 64 additions & 122 deletions core/vdp_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ static void vdp_set_all_vram(const uint8 *src);
} \
bg_name_dirty[name] |= (1 << ((addr >> 2) & 7)); \
}

/* VINT timings */
#define VINT_H32_MCYCLE (770)
#define VINT_H40_MCYCLE (788)
Expand Down Expand Up @@ -103,8 +104,7 @@ uint16 v_counter; /* Vertical counter */
uint16 vc_max; /* Vertical counter overflow value */
uint16 lines_per_frame; /* PAL: 313 lines, NTSC: 262 lines */
uint16 max_sprite_pixels; /* Max. sprites pixels per line (parsing & rendering) */
int32 fifo_write_cnt; /* VDP FIFO write count */
uint32 fifo_slots; /* VDP FIFO access slot count */
uint32 fifo_cycles[4]; /* VDP FIFO read-out cycles */
uint32 hvc_latch; /* latched HV counter */
uint32 vint_cycle; /* VINT occurence cycle */
const uint8 *hctab; /* pointer to H Counter table */
Expand All @@ -128,7 +128,6 @@ static void vdp_z80_data_w_ms(unsigned int data);
static void vdp_z80_data_w_gg(unsigned int data);
static void vdp_z80_data_w_sg(unsigned int data);
static void vdp_bus_w(unsigned int data);
static void vdp_fifo_update(unsigned int cycles);
static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles);
static void vdp_dma_68k_ext(unsigned int length);
static void vdp_dma_68k_ram(unsigned int length);
Expand All @@ -155,7 +154,6 @@ static int cached_write; /* 2nd part of 32-bit CTRL port write (Genesis m
static uint16 fifo[4]; /* FIFO ring-buffer */
static int fifo_idx; /* FIFO write index */
static int fifo_byte_access; /* FIFO byte access flag */
static uint32 fifo_cycles; /* FIFO next access cycle */
static int *fifo_timing; /* FIFO slots timing table */
static int hblank_start_cycle; /* HBLANK flag set cycle */
static int hblank_end_cycle; /* HBLANK flag clear cycle */
Expand All @@ -175,16 +173,20 @@ static const uint16 vc_table[4][2] =
};

/* FIFO access slots timings */
static const int fifo_timing_h32[16+4] =
static const int fifo_timing_h32[] =
{
230, 510, 810, 970, 1130, 1450, 1610, 1770, 2090, 2250, 2410, 2730, 2890, 3050, 3350, 3370,
MCYCLES_PER_LINE + 230, MCYCLES_PER_LINE + 510, MCYCLES_PER_LINE + 810, MCYCLES_PER_LINE + 970,
MCYCLES_PER_LINE + 1130, MCYCLES_PER_LINE + 1450, MCYCLES_PER_LINE + 1610, MCYCLES_PER_LINE + 1770,
MCYCLES_PER_LINE + 2090, MCYCLES_PER_LINE + 2250, MCYCLES_PER_LINE + 2410, MCYCLES_PER_LINE + 2730
};

static const int fifo_timing_h40[18+4] =
static const int fifo_timing_h40[] =
{
352, 820, 948, 1076, 1332, 1460, 1588, 1844, 1972, 2100, 2356, 2484, 2612, 2868, 2996, 3124, 3364, 3380,
MCYCLES_PER_LINE + 352, MCYCLES_PER_LINE + 820, MCYCLES_PER_LINE + 948, MCYCLES_PER_LINE + 1076,
MCYCLES_PER_LINE + 1332, MCYCLES_PER_LINE + 1460, MCYCLES_PER_LINE + 1588, MCYCLES_PER_LINE + 1844,
MCYCLES_PER_LINE + 1972, MCYCLES_PER_LINE + 2100, MCYCLES_PER_LINE + 2356, MCYCLES_PER_LINE + 2484
};

/* DMA Timings (number of access slots per line) */
Expand Down Expand Up @@ -283,9 +285,6 @@ void vdp_reset(void)
odd_frame = 0;
im2_flag = 0;
interlaced = 0;
fifo_write_cnt = 0;
fifo_cycles = 0;
fifo_slots = 0;
fifo_idx = 0;
cached_write = -1;
fifo_byte_access = 1;
Expand Down Expand Up @@ -316,10 +315,10 @@ void vdp_reset(void)
/* default Window clipping */
window_clip(0,0);

/* reset VDP status (FIFO empty flag is set) */
/* reset VDP status */
if (system_hw & SYSTEM_MD)
{
status = vdp_pal | 0x200;
status = vdp_pal;
}
else
{
Expand Down Expand Up @@ -1226,12 +1225,6 @@ unsigned int vdp_68k_ctrl_r(unsigned int cycles)
/* Cycle-accurate VDP status read (adjust CPU time with current instruction execution time) */
cycles += m68k_cycles();

/* Update FIFO status flags if not empty */
if (fifo_write_cnt)
{
vdp_fifo_update(cycles);
}

/* Check if DMA Busy flag is set */
if (status & 2)
{
Expand All @@ -1252,6 +1245,20 @@ unsigned int vdp_68k_ctrl_r(unsigned int cycles)
/* Clear SOVR & SCOL flags */
status &= 0xFF9F;

/* Check if FIFO last entry read-out cycle has been reached */
if (cycles >= fifo_cycles[(fifo_idx + 3) & 3])
{
/* FIFO is empty */
temp |= 0x200;
}

/* Check if FIFO oldest entry read-out cycle is not yet reached */
else if (cycles < fifo_cycles[fifo_idx])
{
/* FIFO is full */
temp |= 0x100;
}

/* VBLANK flag is set when display is disabled */
if (!(reg[1] & 0x40))
{
Expand Down Expand Up @@ -2026,13 +2033,6 @@ static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles)
/* Active display width */
if (r & 0x01)
{
/* FIFO access slots timings depend on active width */
if (fifo_slots)
{
/* Synchronize VDP FIFO */
vdp_fifo_update(cycles);
}

if (d & 0x01)
{
/* Update display-dependant registers */
Expand Down Expand Up @@ -2149,68 +2149,6 @@ static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles)
}
}

/*--------------------------------------------------------------------------*/
/* FIFO emulation (Mega Drive VDP specific) */
/* ---------------------------------------- */
/* */
/* CPU access to VRAM, CRAM & VSRAM is limited during active display: */
/* H32 mode -> 16 access per line */
/* H40 mode -> 18 access per line */
/* */
/* with fixed access slots timings detailled below. */
/* */
/* Each VRAM access is byte wide, so one VRAM write (word) need two slots. */
/* */
/*--------------------------------------------------------------------------*/

static void vdp_fifo_update(unsigned int cycles)
{
int fifo_read_cnt, line_slots = 0;

/* number of access slots up to current line */
int total_slots = dma_timing[0][reg[12] & 1] * ((v_counter + 1) % lines_per_frame);

/* number of access slots within current line */
cycles -= mcycles_vdp;
while (fifo_timing[line_slots] <= cycles)
{
line_slots++;
}

/* number of processed FIFO entries since last access (byte access needs two slots to process one FIFO word) */
fifo_read_cnt = (total_slots + line_slots - fifo_slots) >> fifo_byte_access;

if (fifo_read_cnt > 0)
{
/* process FIFO entries */
fifo_write_cnt -= fifo_read_cnt;

/* Clear FIFO full flag */
status &= 0xFEFF;

if (fifo_write_cnt <= 0)
{
/* No more FIFO entries */
fifo_write_cnt = 0;

/* Set FIFO empty flag */
status |= 0x200;

/* Reinitialize FIFO access slot counter */
fifo_slots = total_slots + line_slots;
}
else
{
/* Update FIFO access slot counter */
fifo_slots += (fifo_read_cnt << fifo_byte_access);
}
}

/* next FIFO update cycle */
fifo_cycles = mcycles_vdp + fifo_timing[fifo_slots - total_slots + fifo_byte_access];
}


/*--------------------------------------------------------------------------*/
/* Internal 16-bit data bus access function (Mode 5 only) */
/*--------------------------------------------------------------------------*/
Expand Down Expand Up @@ -2370,29 +2308,31 @@ static void vdp_68k_data_w_m4(unsigned int data)
/* Restricted VDP writes during active display */
if (!(status & 8) && (reg[1] & 0x40))
{
/* Update VDP FIFO */
vdp_fifo_update(m68k.cycles);
int slot = 0;

/* Clear FIFO empty flag */
status &= 0xFDFF;
/* Cycle-accurate VDP data port access */
int cycles = m68k.cycles;

/* up to 4 words can be stored */
if (fifo_write_cnt < 4)
/* Check against last FIFO entry read-out cycle */
if (cycles < fifo_cycles[(fifo_idx + 3) & 3])
{
/* Increment FIFO counter */
fifo_write_cnt++;
/* Check against oldest FIFO entry read-out cycle */
if (cycles < fifo_cycles[fifo_idx])
{
/* FIFO is full, 68k waits until oldest FIFO entry is processed (Chaos Engine / Soldiers of Fortune, Double Clutch, Titan Overdrive Demo) */
m68k.cycles = (((fifo_cycles[fifo_idx] + 6) / 7) * 7);
}

/* Set FIFO full flag if 4 words are stored */
status |= ((fifo_write_cnt & 4) << 6);
/* FIFO is not empty, next FIFO entry will be processed after last FIFO entry */
cycles = fifo_cycles[(fifo_idx + 3) & 3];
}
else
{
/* CPU is halted until next FIFO entry processing */
m68k.cycles = fifo_cycles;

/* Update FIFO access slot counter */
fifo_slots += (fifo_byte_access + 1);
}
/* Determine next FIFO entry processing slot */
cycles -= mcycles_vdp;
while (cycles >= fifo_timing[slot]) slot++;

/* Update last FIFO entry read-out cycle */
fifo_cycles[fifo_idx] = mcycles_vdp + fifo_timing[slot + fifo_byte_access];
}

/* Check destination code */
Expand Down Expand Up @@ -2462,31 +2402,33 @@ static void vdp_68k_data_w_m5(unsigned int data)
/* Restricted VDP writes during active display */
if (!(status & 8) && (reg[1] & 0x40))
{
/* Update VDP FIFO */
vdp_fifo_update(m68k.cycles);
int slot = 0;

/* Clear FIFO empty flag */
status &= 0xFDFF;
/* Cycle-accurate VDP data port access */
int cycles = m68k.cycles;

/* up to 4 words can be stored */
if (fifo_write_cnt < 4)
/* Check against last FIFO entry read-out cycle */
if (cycles < fifo_cycles[(fifo_idx + 3) & 3])
{
/* Increment FIFO counter */
fifo_write_cnt++;
/* Check against oldest FIFO entry read-out cycle */
if (cycles < fifo_cycles[fifo_idx])
{
/* FIFO is full, 68k waits until oldest FIFO entry is processed (Chaos Engine / Soldiers of Fortune, Double Clutch, Titan Overdrive Demo) */
m68k.cycles = (((fifo_cycles[fifo_idx] + 6) / 7) * 7);
}

/* Set FIFO full flag if 4 words are stored */
status |= ((fifo_write_cnt & 4) << 6);
/* FIFO is not empty, next FIFO entry will be processed after last FIFO entry */
cycles = fifo_cycles[(fifo_idx + 3) & 3];
}
else
{
/* CPU is halted until next FIFO entry processing (Chaos Engine / Soldiers of Fortune, Double Clutch, Titan Overdrive Demo) */
m68k.cycles = fifo_cycles;

/* Update FIFO access slot counter */
fifo_slots += (fifo_byte_access + 1);
}
/* Determine next FIFO entry processing slot */
cycles -= mcycles_vdp;
while (cycles >= fifo_timing[slot]) slot++;

/* Update last FIFO entry read-out cycle */
fifo_cycles[fifo_idx] = mcycles_vdp + fifo_timing[slot + fifo_byte_access];
}

/* Write data */
vdp_bus_w(data);

Expand Down Expand Up @@ -3228,7 +3170,7 @@ static void vdp_dma_fill(unsigned int length)
{
int name;

/* Get source data from last written FIFO entry */
/* Get source data from last written FIFO entry */
uint8 data = fifo[(fifo_idx+3)&3] >> 8;

do
Expand Down
3 changes: 1 addition & 2 deletions core/vdp_ctrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,7 @@ extern uint16 vc_max;
extern uint16 vscroll;
extern uint16 lines_per_frame;
extern uint16 max_sprite_pixels;
extern int32 fifo_write_cnt;
extern uint32 fifo_slots;
extern uint32 fifo_cycles[4];
extern uint32 hvc_latch;
extern uint32 vint_cycle;
extern const uint8 *hctab;
Expand Down

0 comments on commit 541229d

Please sign in to comment.