.improved FIFO timings accuracy (fixes Sol Deace intro)
.code cleanup
This commit is contained in:
ekeeke31 2010-04-06 23:22:27 +00:00
parent 68ceeb3b8c
commit 0794c4a5d6

View File

@ -127,12 +127,12 @@ static const uint32 dma_rates[16] = {
/*--------------------------------------------------------------------------*/
/* Functions prototype */
/*--------------------------------------------------------------------------*/
static inline void fifo_update();
static inline void data_w(unsigned int data);
static inline void reg_w(unsigned int r, unsigned int d);
static inline void dma_copy(void);
static inline void dma_vbus (void);
static inline void dma_fill(unsigned int data);
static void fifo_update();
static void data_w(unsigned int data);
static void reg_w(unsigned int r, unsigned int d);
static void dma_copy(void);
static void dma_vbus (void);
static void dma_fill(unsigned int data);
/*--------------------------------------------------------------------------*/
/* Init, reset, shutdown functions */
@ -172,7 +172,7 @@ void vdp_reset(void)
interlaced = 0;
fifo_write_cnt = 0;
fifo_lastwrite = 0;
fifo_latency = 192; /* default FIFO timings */
fifo_latency = 190; /* default FIFO timings */
status = vdp_pal | 0x0200; /* FIFO empty */
@ -248,7 +248,7 @@ void vdp_restore(uint8 *vdp_regs)
bitmap.viewport.changed = 1;
/* restore FIFO timings */
fifo_latency = (reg[12] & 1) ? 192 : 210;
fifo_latency = (reg[12] & 1) ? 190 : 214;
if ((code & 0x0F) == 0x01)
fifo_latency = fifo_latency * 2;
@ -387,22 +387,21 @@ void vdp_ctrl_w(unsigned int data)
}
/*
FIFO emulation (Chaos Engine/Soldier of Fortune, Double Clutch)
---------------------------------------------------------------
HDISP is 2560 mcycles (same in both modes)
FIFO emulation (Chaos Engine/Soldier of Fortune, Double Clutch, Sol Deace)
--------------------------------------------------------------------------
CPU access per line is limited during active display:
H32: 16 access --> 2560/16 = 160 cycles between access
H40: 18 access --> 2560/18 = 142 cycles between access
H32: 16 access --> 3420/16 = ~214 Mcycles between access
H40: 18 access --> 3420/18 = ~190 Mcycles between access
FIFO access seems to require some additional cyles (VDP latency).
This is an approximation, on real hardware, the delay between access is
more likely 16 pixels (128 or 160 Mcycles) with no access allowed during
HBLANK (~860 Mcycles), H40 mode being probably a little more restricted.
Also note that VRAM access are byte wide, so one VRAM write (word)
takes twice CPU cycles.
Each VRAM access is byte wide, so one VRAM write (word) need twice cycles.
*/
fifo_latency = (reg[12] & 1) ? 192 : 210;
fifo_latency = (reg[12] & 1) ? 190 : 214;
if ((code & 0x0F) == 0x01)
fifo_latency = fifo_latency * 2;
}
@ -432,7 +431,7 @@ unsigned int vdp_ctrl_r(void)
if ((status & 2) && !dma_length && (mcycles_68k >= dma_endCycles))
status &= 0xFFFD;
uint32 temp = status;
unsigned int temp = status;
/* display OFF: VBLANK flag is set */
if (!(reg[1] & 0x40))
@ -554,6 +553,12 @@ unsigned int vdp_data_r(void)
error("[%d(%d)][%d(%d)] VSRAM 0x%x read -> 0x%x (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE, addr, temp, m68k_get_reg (NULL, M68K_REG_PC));
#endif
break;
#ifdef LOGVDP
default:
error("[%d(%d)][%d(%d)] Unknown (%d) 0x%x read (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE, code, addr, m68k_get_reg (NULL, M68K_REG_PC));
break;
#endif
}
/* Increment address register */
@ -616,12 +621,12 @@ int vdp_int_ack_callback(int int_level)
/*--------------------------------------------------------------------------*/
/* FIFO emulation */
/*--------------------------------------------------------------------------*/
static inline void fifo_update()
static void fifo_update()
{
if (fifo_write_cnt > 0)
{
/* update FIFO reads */
uint32 fifo_read = ((mcycles_68k - fifo_lastwrite) / fifo_latency);
int fifo_read = ((mcycles_68k - fifo_lastwrite) / fifo_latency);
if (fifo_read > 0)
{
fifo_write_cnt -= fifo_read;
@ -649,16 +654,14 @@ static inline void fifo_update()
/*--------------------------------------------------------------------------*/
/* Memory access functions */
/*--------------------------------------------------------------------------*/
static inline void data_w(unsigned int data)
static void data_w(unsigned int data)
{
switch (code & 0x0F)
{
case 0x01: /* VRAM */
#ifdef LOGVDP
error("[%d(%d)][%d(%d)] VRAM 0x%x write -> 0x%x (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE, addr, data, m68k_get_reg (NULL, M68K_REG_PC));
#endif
/* Byte-swap data if A0 is set */
if (addr & 1)
data = ((data >> 8) | (data << 8)) & 0xFFFF;
@ -724,19 +727,25 @@ static inline void data_w(unsigned int data)
#endif
*(uint16 *) &vsram[(addr & 0x7E)] = data;
break;
#ifdef LOGVDP
default:
error("[%d(%d)][%d(%d)] Unknown (%d) 0x%x write -> 0x%x (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE, code, addr, data, m68k_get_reg (NULL, M68K_REG_PC));
break;
#endif
}
/* Increment address register */
addr += reg[15];
}
static inline void reg_w(unsigned int r, unsigned int d)
static void reg_w(unsigned int r, unsigned int d)
{
#ifdef LOGVDP
error("[%d(%d)][%d(%d)] VDP register %d write -> 0x%x (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE, r, d, m68k_get_reg (NULL, M68K_REG_PC));
#endif
/* See if Mode 4 (SMS mode) is enabled
/* Mode 4 (SMS mode) is enabled
According to official doc, VDP registers #11 to #23 can not be written unless bit2 in register #1 is set
Fix Captain Planet & Avengers (Alt version), Bass Master Classic Pro Edition (they incidentally activate Mode 4)
*/
@ -921,7 +930,7 @@ static inline void reg_w(unsigned int r, unsigned int d)
bitmap.viewport.x = 16;
/* Update fifo timings */
fifo_latency = ((code & 0x0F) == 0x01) ? 384 : 192;
fifo_latency = 190;
}
else
{
@ -940,9 +949,12 @@ static inline void reg_w(unsigned int r, unsigned int d)
bitmap.viewport.x = 12;
/* Update fifo timings */
fifo_latency = ((code & 0x0F) == 0x01) ? 420 : 210;
fifo_latency = 214;
}
if ((code & 0x0F) == 0x01)
fifo_latency *= 2;
/* Update viewport */
bitmap.viewport.changed = 1;
@ -995,11 +1007,11 @@ static inline void reg_w(unsigned int r, unsigned int d)
- see how source addr is affected
(can it make high source byte inc?)
*/
static inline void dma_copy(void)
static void dma_copy(void)
{
int name;
uint32 length = (reg[20] << 8 | reg[19]) & 0xFFFF;
uint32 source = (reg[22] << 8 | reg[21]) & 0xFFFF;
unsigned int length = (reg[20] << 8 | reg[19]) & 0xFFFF;
unsigned int source = (reg[22] << 8 | reg[21]) & 0xFFFF;
if (!length)
length = 0x10000;
@ -1025,12 +1037,12 @@ static inline void dma_copy(void)
}
/* 68K Copy to VRAM, VSRAM or CRAM */
static inline void dma_vbus (void)
static void dma_vbus (void)
{
uint32 source = ((reg[23] & 0x7F) << 17 | reg[22] << 9 | reg[21] << 1) & 0xFFFFFE;
uint32 base = source;
uint32 length = (reg[20] << 8 | reg[19]) & 0xFFFF;
uint32 temp;
unsigned int source = ((reg[23] & 0x7F) << 17 | reg[22] << 9 | reg[21] << 1) & 0xFFFFFE;
unsigned int base = source;
unsigned int length = (reg[20] << 8 | reg[19]) & 0xFFFF;
uint16 temp;
if (!length)
length = 0x10000;
@ -1098,10 +1110,10 @@ static inline void dma_vbus (void)
}
/* VRAM FILL */
static inline void dma_fill(unsigned int data)
static void dma_fill(unsigned int data)
{
int name;
uint32 length = (reg[20] << 8 | reg[19]) & 0xFFFF;
unsigned int length = (reg[20] << 8 | reg[19]) & 0xFFFF;
if (!length)
length = 0x10000;