mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-27 03:31:49 +01:00
[Core/MD] added basic emulation of 68k bus access refresh delays (fixes Super Airwolf graphical glitch during intro & some Krikzz's mcd-verificator timing tests)
This commit is contained in:
parent
405c54555e
commit
47761b9b8f
@ -73,6 +73,7 @@ Genesis Plus GX 1.7.5 (xx/xx/xxxx) (Eke-Eke)
|
|||||||
* added support for some new unlicensed games with copy protection (Thunderbolt II, Tom Clown, Chaoji Puke / Super Poker, Rock Heaven, Rock World)
|
* added support for some new unlicensed games with copy protection (Thunderbolt II, Tom Clown, Chaoji Puke / Super Poker, Rock Heaven, Rock World)
|
||||||
* added support for Everdrive extended SSF mapper
|
* added support for Everdrive extended SSF mapper
|
||||||
* added support for MegaSD CD hardware overlay (MD+ hacks) and extended SSF2 / ROM write mappers
|
* added support for MegaSD CD hardware overlay (MD+ hacks) and extended SSF2 / ROM write mappers
|
||||||
|
* added basic emulation of 68k bus access refresh delays (fixes Super Airwolf graphical glitch during intro & some Krikzz's mcd-verificator timing tests)
|
||||||
* added (very basic) emulation of Flashkit MD hardware
|
* added (very basic) emulation of Flashkit MD hardware
|
||||||
* added emulation of Micro Machines USA on-board TMSS bypass logic hardware
|
* added emulation of Micro Machines USA on-board TMSS bypass logic hardware
|
||||||
* added SRAM support for games larger than 8MB
|
* added SRAM support for games larger than 8MB
|
||||||
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 3.8 MiB After Width: | Height: | Size: 3.8 MiB |
Binary file not shown.
Before Width: | Height: | Size: 4.0 MiB After Width: | Height: | Size: 4.0 MiB |
@ -238,7 +238,8 @@ typedef struct
|
|||||||
|
|
||||||
cpu_idle_t poll; /* polling detection */
|
cpu_idle_t poll; /* polling detection */
|
||||||
|
|
||||||
uint cycles; /* current master cycle count */
|
sint cycles; /* current master cycle count */
|
||||||
|
sint refresh_cycles; /* external bus refresh cycle */
|
||||||
uint cycle_end; /* aimed master cycle count for current execution frame */
|
uint cycle_end; /* aimed master cycle count for current execution frame */
|
||||||
|
|
||||||
uint dar[16]; /* Data and Address Registers */
|
uint dar[16]; /* Data and Address Registers */
|
||||||
|
@ -299,6 +299,13 @@ void m68k_run(unsigned int cycles)
|
|||||||
/* Decode next instruction */
|
/* Decode next instruction */
|
||||||
REG_IR = m68ki_read_imm_16();
|
REG_IR = m68ki_read_imm_16();
|
||||||
|
|
||||||
|
/* 68K bus access refresh delay (Mega Drive / Genesis specific) */
|
||||||
|
if (m68k.cycles >= (m68k.refresh_cycles + (128*7)))
|
||||||
|
{
|
||||||
|
m68k.refresh_cycles = (m68k.cycles / (128*7)) * (128*7);
|
||||||
|
m68k.cycles += (2*7);
|
||||||
|
}
|
||||||
|
|
||||||
/* Execute instruction */
|
/* Execute instruction */
|
||||||
m68ki_instruction_jump_table[REG_IR]();
|
m68ki_instruction_jump_table[REG_IR]();
|
||||||
USE_CYCLES(CYC_INSTRUCTION[REG_IR]);
|
USE_CYCLES(CYC_INSTRUCTION[REG_IR]);
|
||||||
@ -382,6 +389,9 @@ void m68k_pulse_reset(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
USE_CYCLES(CYC_EXCEPTION[EXCEPTION_RESET]);
|
USE_CYCLES(CYC_EXCEPTION[EXCEPTION_RESET]);
|
||||||
|
|
||||||
|
/* Synchronize 68k bus refresh mechanism (Mega Drive / Genesis specific) */
|
||||||
|
m68k.refresh_cycles = (m68k.cycles / (128*7)) * (128*7);
|
||||||
}
|
}
|
||||||
|
|
||||||
void m68k_pulse_halt(void)
|
void m68k_pulse_halt(void)
|
||||||
|
@ -8,7 +8,7 @@ INLINE void UseDivuCycles(uint32 dst, uint32 src)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* minimum cycle time */
|
/* minimum cycle time */
|
||||||
uint mcycles = 38 * MUL;
|
uint mcycles = 76 * MUL;
|
||||||
|
|
||||||
/* 16-bit divisor */
|
/* 16-bit divisor */
|
||||||
src <<= 16;
|
src <<= 16;
|
||||||
@ -27,27 +27,33 @@ INLINE void UseDivuCycles(uint32 dst, uint32 src)
|
|||||||
{
|
{
|
||||||
/* shift dividend and add two cycles */
|
/* shift dividend and add two cycles */
|
||||||
dst <<= 1;
|
dst <<= 1;
|
||||||
mcycles += (2 * MUL);
|
mcycles += (4 * MUL);
|
||||||
|
|
||||||
if (dst >= src)
|
if (dst >= src)
|
||||||
{
|
{
|
||||||
/* apply divisor and remove one cycle */
|
/* apply divisor and remove one cycle */
|
||||||
dst -= src;
|
dst -= src;
|
||||||
mcycles -= 1 * MUL;
|
mcycles -= 2 * MUL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
USE_CYCLES(mcycles << 1);
|
USE_CYCLES(mcycles);
|
||||||
|
|
||||||
|
/* one 68K bus refresh cycle should be skipped if instruction processing time is longer than refresh period (128 CPU cycles on Mega Drive / Genesis) */
|
||||||
|
if (mcycles >= (128*MUL))
|
||||||
|
{
|
||||||
|
m68ki_cpu.refresh_cycles += (128*MUL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE void UseDivsCycles(sint32 dst, sint16 src)
|
INLINE void UseDivsCycles(sint32 dst, sint16 src)
|
||||||
{
|
{
|
||||||
/* minimum cycle time */
|
/* minimum cycle time */
|
||||||
uint mcycles = 6 * MUL;
|
uint mcycles = 12 * MUL;
|
||||||
|
|
||||||
/* negative dividend */
|
/* negative dividend */
|
||||||
if (dst < 0) mcycles += 1 * MUL;
|
if (dst < 0) mcycles += 2 * MUL;
|
||||||
|
|
||||||
if ((abs(dst) >> 16) < abs(src))
|
if ((abs(dst) >> 16) < abs(src))
|
||||||
{
|
{
|
||||||
@ -57,30 +63,36 @@ INLINE void UseDivsCycles(sint32 dst, sint16 src)
|
|||||||
uint32 quotient = abs(dst) / abs(src);
|
uint32 quotient = abs(dst) / abs(src);
|
||||||
|
|
||||||
/* add default cycle time */
|
/* add default cycle time */
|
||||||
mcycles += (55 * MUL);
|
mcycles += (110 * MUL);
|
||||||
|
|
||||||
/* positive divisor */
|
/* positive divisor */
|
||||||
if (src >= 0)
|
if (src >= 0)
|
||||||
{
|
{
|
||||||
/* check dividend sign */
|
/* check dividend sign */
|
||||||
if (dst >= 0) mcycles -= 1 * MUL;
|
if (dst >= 0) mcycles -= 2 * MUL;
|
||||||
else mcycles += 1 * MUL;
|
else mcycles += 2 * MUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check higher 15-bits of quotient */
|
/* check higher 15-bits of quotient */
|
||||||
for (i=0; i<15; i++)
|
for (i=0; i<15; i++)
|
||||||
{
|
{
|
||||||
quotient >>= 1;
|
quotient >>= 1;
|
||||||
if (!(quotient & 1)) mcycles += 1 * MUL;
|
if (!(quotient & 1)) mcycles += 2 * MUL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* absolute overflow */
|
/* absolute overflow */
|
||||||
mcycles += (2 * MUL);
|
mcycles += (4 * MUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
USE_CYCLES(mcycles << 1);
|
USE_CYCLES(mcycles);
|
||||||
|
|
||||||
|
/* one 68K bus refresh cycle should be skipped if instruction processing time is longer than refresh period (128 CPU cycles on Mega Drive / Genesis) */
|
||||||
|
if (mcycles >= (128*MUL))
|
||||||
|
{
|
||||||
|
m68ki_cpu.refresh_cycles += (128*MUL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE void UseMuluCycles(uint16 src)
|
INLINE void UseMuluCycles(uint16 src)
|
||||||
@ -18692,6 +18704,7 @@ static void m68k_op_reset(void)
|
|||||||
{
|
{
|
||||||
m68ki_output_reset() /* auto-disable (see m68kcpu.h) */
|
m68ki_output_reset() /* auto-disable (see m68kcpu.h) */
|
||||||
USE_CYCLES(CYC_RESET);
|
USE_CYCLES(CYC_RESET);
|
||||||
|
m68ki_cpu.refresh_cycles += (128*MUL); /* skip one 68K bus refresh cycle as instruction processing time is longer than refresh period (128 CPU cycles on Mega Drive / Genesis) */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m68ki_exception_privilege_violation();
|
m68ki_exception_privilege_violation();
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* Support for 16-bit & 8-bit hardware modes
|
* Support for 16-bit & 8-bit hardware modes
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
||||||
* Copyright (C) 2007-2021 Eke-Eke (Genesis Plus GX)
|
* Copyright (C) 2007-2024 Eke-Eke (Genesis Plus GX)
|
||||||
*
|
*
|
||||||
* Redistribution and use of this code or any derivative works are permitted
|
* Redistribution and use of this code or any derivative works are permitted
|
||||||
* provided that the following conditions are met:
|
* provided that the following conditions are met:
|
||||||
@ -659,6 +659,7 @@ void system_frame_gen(int do_skip)
|
|||||||
|
|
||||||
/* adjust timings for next frame */
|
/* adjust timings for next frame */
|
||||||
input_end_frame(mcycles_vdp);
|
input_end_frame(mcycles_vdp);
|
||||||
|
m68k.refresh_cycles -= mcycles_vdp;
|
||||||
m68k.cycles -= mcycles_vdp;
|
m68k.cycles -= mcycles_vdp;
|
||||||
Z80.cycles -= mcycles_vdp;
|
Z80.cycles -= mcycles_vdp;
|
||||||
}
|
}
|
||||||
@ -983,6 +984,7 @@ void system_frame_scd(int do_skip)
|
|||||||
/* adjust timings for next frame */
|
/* adjust timings for next frame */
|
||||||
scd_end_frame(scd.cycles);
|
scd_end_frame(scd.cycles);
|
||||||
input_end_frame(mcycles_vdp);
|
input_end_frame(mcycles_vdp);
|
||||||
|
m68k.refresh_cycles -= mcycles_vdp;
|
||||||
m68k.cycles -= mcycles_vdp;
|
m68k.cycles -= mcycles_vdp;
|
||||||
Z80.cycles -= mcycles_vdp;
|
Z80.cycles -= mcycles_vdp;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* Support for 16-bit & 8-bit hardware modes
|
* Support for 16-bit & 8-bit hardware modes
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
||||||
* Copyright (C) 2007-2022 Eke-Eke (Genesis Plus GX)
|
* Copyright (C) 2007-2024 Eke-Eke (Genesis Plus GX)
|
||||||
*
|
*
|
||||||
* Redistribution and use of this code or any derivative works are permitted
|
* Redistribution and use of this code or any derivative works are permitted
|
||||||
* provided that the following conditions are met:
|
* provided that the following conditions are met:
|
||||||
@ -95,7 +95,6 @@ typedef struct
|
|||||||
blip_t* blips[3]; /* Blip Buffer resampling (stereo) */
|
blip_t* blips[3]; /* Blip Buffer resampling (stereo) */
|
||||||
} t_snd;
|
} t_snd;
|
||||||
|
|
||||||
|
|
||||||
/* Global variables */
|
/* Global variables */
|
||||||
extern t_bitmap bitmap;
|
extern t_bitmap bitmap;
|
||||||
extern t_snd snd;
|
extern t_snd snd;
|
||||||
@ -119,4 +118,3 @@ extern void system_frame_scd(int do_skip);
|
|||||||
extern void system_frame_sms(int do_skip);
|
extern void system_frame_sms(int do_skip);
|
||||||
|
|
||||||
#endif /* _SYSTEM_H_ */
|
#endif /* _SYSTEM_H_ */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user