.improved Z80 bus reset accuracy
.improved Z80 locks & VDP access accuracy
.improved soft-reset accuracy
.adjusted Horizontal Counter timing in H32 mode (fixes Sonic 3D Blast 'bonus' levels)
.updated win32 port to compile with recent changes
.input code cleanup

[GCN]
.fixed soft-reset (reset switch should also works now)



IMPORTANT: Because of some internal changes, saved states from previous revisions are not compatible !
This commit is contained in:
ekeeke31 2010-05-30 18:42:03 +00:00
parent 7db1b3ef85
commit f21a08ebfa
20 changed files with 360 additions and 319 deletions

View File

@ -95,7 +95,7 @@ void eeprom_init()
sram.custom = 0;
/* look into game database */
while ((i<GAME_CNT) && (!sram.custom))
while (i<GAME_CNT)
{
if (strstr(rominfo.product,database[i].game_id) != NULL)
{
@ -105,13 +105,14 @@ void eeprom_init()
sram.custom = 1;
sram.on = 1;
memcpy(&eeprom.type, &database[i].type, sizeof(T_EEPROM_TYPE));
return;
}
}
i++;
}
/* Game not found in database but header seems to indicate it uses EEPROM */
if (sram.detected && !sram.custom)
if (sram.detected)
{
if ((sram.end - sram.start) < 2)
{

View File

@ -74,6 +74,9 @@ static const uint8 hc_256[171] =
* LIGHTGUN support
*
*****************************************************************************/
static int x_offset;
static int y_offset;
static inline void lightgun_reset(int num)
{
input.analog[num][0] = bitmap.viewport.w >> 1;
@ -82,7 +85,7 @@ static inline void lightgun_reset(int num)
static inline void lightgun_update(int num)
{
if ((input.analog[num][1] == v_counter + input.y_offset))
if ((input.analog[num][1] == v_counter + y_offset))
{
/* HL enabled ? */
if (io_reg[5] & 0x80)
@ -99,9 +102,9 @@ static inline void lightgun_update(int num)
*/
hvc_latch = 0x10000 | (vctab[v_counter] << 8);
if (reg[12] & 1)
hvc_latch |= hc_320[((input.analog[num][0] * 290) / (2 * 320) + input.x_offset) % 210];
hvc_latch |= hc_320[((input.analog[num][0] * 290) / (2 * 320) + x_offset) % 210];
else
hvc_latch |= hc_256[(input.analog[num][0] / 2 + input.x_offset)%171];
hvc_latch |= hc_256[(input.analog[num][0] / 2 + x_offset)%171];
}
}
}
@ -539,17 +542,22 @@ static inline void teamplayer_write(uint32 port, uint32 data)
* 4-WAYPLAY adapter support
*
*****************************************************************************/
static struct wayplay
{
uint8 current;
} wayplay;
static inline void wayplay_write(uint32 port, uint32 data)
{
if (port == 0) gamepad_write(input.current, data);
else input.current = (data >> 4) & 0x07;
if (port == 0) gamepad_write(wayplay.current, data);
else wayplay.current = (data >> 4) & 0x07;
}
static inline uint32 wayplay_read(uint32 port)
{
if (port == 1) return 0x7F;
if (input.current >= 4) return 0x70; /* multitap detection (TH2 = 1) */
return gamepad_read(input.current); /* 0x0C = Pad1, 0x1C = Pad2, ... */
if (wayplay.current >= 4) return 0x70; /* multitap detection (TH2 = 1) */
return gamepad_read(wayplay.current); /* 0x0C = Pad1, 0x1C = Pad2, ... */
}
@ -637,8 +645,7 @@ void jcart_write(uint32 address, uint32 data)
void input_init(void)
{
int i,j;
input.max = 0;
int player = 0;
for (i=0; i<MAX_DEVICES; i++)
{
@ -649,32 +656,32 @@ void input_init(void)
switch (input.system[0])
{
case SYSTEM_GAMEPAD:
if (input.max == MAX_INPUTS) return;
input.dev[0] = config.input[input.max].padtype;
input.max ++;
if (player == MAX_INPUTS) return;
input.dev[0] = config.input[player].padtype;
player ++;
break;
case SYSTEM_MOUSE:
if (input.max == MAX_INPUTS) return;
if (player == MAX_INPUTS) return;
input.dev[0] = DEVICE_MOUSE;
input.max ++;
player ++;
break;
case SYSTEM_WAYPLAY:
for (j=0; j< 4; j++)
{
if (input.max == MAX_INPUTS) return;
input.dev[j] = config.input[input.max].padtype;
input.max ++;
if (player == MAX_INPUTS) return;
input.dev[j] = config.input[player].padtype;
player ++;
}
break;
case SYSTEM_TEAMPLAYER:
for (j=0; j<4; j++)
{
if (input.max == MAX_INPUTS) return;
input.dev[j] = config.input[input.max].padtype;
input.max ++;
if (player == MAX_INPUTS) return;
input.dev[j] = config.input[player].padtype;
player ++;
}
teamplayer_init(0);
break;
@ -683,37 +690,38 @@ void input_init(void)
switch (input.system[1])
{
case SYSTEM_GAMEPAD:
if (input.max == MAX_INPUTS) return;
input.dev[4] = config.input[input.max].padtype;
input.max ++;
if (player == MAX_INPUTS) return;
input.dev[4] = config.input[player].padtype;
player ++;
break;
case SYSTEM_MOUSE:
if (input.max == MAX_INPUTS) return;
if (player == MAX_INPUTS) return;
input.dev[4] = DEVICE_MOUSE;
input.max ++;
player ++;
break;
case SYSTEM_MENACER:
if (input.max == MAX_INPUTS) return;
if (player == MAX_INPUTS) return;
input.dev[4] = DEVICE_LIGHTGUN;
player ++;
break;
case SYSTEM_JUSTIFIER:
for (j=4; j<6; j++)
{
if (input.max == MAX_INPUTS) return;
if (player == MAX_INPUTS) return;
input.dev[j] = DEVICE_LIGHTGUN;
input.max ++;
player ++;
}
break;
case SYSTEM_TEAMPLAYER:
for (j=4; j<8; j++)
{
if (input.max == MAX_INPUTS) return;
input.dev[j] = config.input[input.max].padtype;
input.max ++;
if (player == MAX_INPUTS) return;
input.dev[j] = config.input[player].padtype;
player ++;
}
teamplayer_init(1);
break;
@ -759,7 +767,7 @@ void input_reset(void)
teamplayer_reset(1);
/* 4-Way Play */
input.current = 0;
wayplay.current = 0;
}
void input_update(void)
@ -838,8 +846,8 @@ void input_autodetect(void)
input.system[1] = old_system[1];
/* initialize default GUN settings */
input.x_offset = 0x00;
input.y_offset = 0x00;
x_offset = 0x00;
y_offset = 0x00;
/**********************************************
SEGA MENACER
@ -854,8 +862,8 @@ void input_autodetect(void)
input.system[0] = NO_SYSTEM;
input.system[1] = SYSTEM_MENACER;
input.x_offset = 0x52;
input.y_offset = 0x00;
x_offset = 0x52;
y_offset = 0x00;
}
else if (strstr(rominfo.international,"T2 ; THE ARCADE GAME") != NULL)
{
@ -867,8 +875,8 @@ void input_autodetect(void)
input.system[0] = SYSTEM_GAMEPAD;
input.system[1] = SYSTEM_MENACER;
input.x_offset = 0x84;
input.y_offset = 0x08;
x_offset = 0x84;
y_offset = 0x08;
}
else if (strstr(rominfo.international,"BODY COUNT") != NULL)
{
@ -880,8 +888,8 @@ void input_autodetect(void)
input.system[0] = SYSTEM_MOUSE;
input.system[1] = SYSTEM_MENACER;
input.x_offset = 0x44;
input.y_offset = 0x18;
x_offset = 0x44;
y_offset = 0x18;
}
/**********************************************
@ -897,8 +905,8 @@ void input_autodetect(void)
input.system[0] = SYSTEM_GAMEPAD;
input.system[1] = SYSTEM_JUSTIFIER;
input.x_offset = 0x18;
input.y_offset = 0x00;
x_offset = 0x18;
y_offset = 0x00;
}
else if (strstr(rominfo.international,"LETHAL ENFORCERS") != NULL)
{
@ -910,8 +918,8 @@ void input_autodetect(void)
input.system[0] = SYSTEM_GAMEPAD;
input.system[1] = SYSTEM_JUSTIFIER;
input.x_offset = 0x00;
input.y_offset = 0x00;
x_offset = 0x00;
y_offset = 0x00;
}
/**********************************************

View File

@ -36,18 +36,18 @@
#define NO_DEVICE (0x0F) /* unconnected */
/* Input bitmasks */
#define INPUT_MODE (0x00000800)
#define INPUT_Z (0x00000400)
#define INPUT_Y (0x00000200)
#define INPUT_X (0x00000100)
#define INPUT_START (0x00000080)
#define INPUT_C (0x00000040)
#define INPUT_B (0x00000020)
#define INPUT_A (0x00000010)
#define INPUT_LEFT (0x00000008)
#define INPUT_RIGHT (0x00000004)
#define INPUT_DOWN (0x00000002)
#define INPUT_UP (0x00000001)
#define INPUT_MODE (0x0800)
#define INPUT_Z (0x0400)
#define INPUT_Y (0x0200)
#define INPUT_X (0x0100)
#define INPUT_START (0x0080)
#define INPUT_C (0x0040)
#define INPUT_B (0x0020)
#define INPUT_A (0x0010)
#define INPUT_LEFT (0x0008)
#define INPUT_RIGHT (0x0004)
#define INPUT_DOWN (0x0002)
#define INPUT_UP (0x0001)
/* System IO ports */
#define NO_SYSTEM (0) /* Unconnected Port*/
@ -60,14 +60,10 @@
typedef struct
{
uint8 dev[MAX_DEVICES]; /* Can be any of the DEVICE_* values */
uint32 pad[MAX_DEVICES]; /* Can be any of the INPUT_* bitmasks */
uint8 system[2]; /* Can be any of the SYSTEM_* bitmasks */
uint8 max; /* maximum number of connected devices */
uint8 current; /* current PAD number (4-Way Play) */
int analog[3][2]; /* analog devices */
int x_offset; /* gun horizontal offset */
int y_offset; /* gun vertical offset */
uint8 dev[MAX_DEVICES]; /* Can be one of the DEVICE_* values */
uint16 pad[MAX_DEVICES]; /* Can be any of the INPUT_* bitmasks */
uint8 system[2]; /* Can be one of the SYSTEM_* values */
int analog[3][2]; /* Analog devices */
} t_input;
/* Global variables */

View File

@ -26,10 +26,8 @@
uint8 bios_rom[0x10000]; /* OS ROM */
uint8 work_ram[0x10000]; /* 68K RAM */
uint8 zram[0x2000]; /* Z80 RAM */
uint32 zirq; /* /IRQ to Z80 */
uint32 zstate; /* Z80 bus state (d0 = BUSACK, d1 = /RESET) */
uint8 zstate; /* Z80 bus state (d0 = BUSACK, d1 = /RESET) */
uint32 zbank; /* Z80 bank window address */
uint32 gen_running; /* 0: cpu are in locked state */
/*--------------------------------------------------------------------------*/
/* Init, reset, shutdown functions */
@ -117,10 +115,8 @@ void gen_init(void)
}
}
void gen_reset(uint32 hard_reset)
void gen_hardreset(void)
{
if (hard_reset)
{
/* Clear RAM */
memset (work_ram, 0x00, sizeof (work_ram));
memset (zram, 0x00, sizeof (zram));
@ -132,22 +128,39 @@ void gen_reset(uint32 hard_reset)
/* Reset CPU cycle counts */
mcycles_68k = 0;
mcycles_z80 = 0;
zstate = 0; /* Z80 is resetted & has control of the bus */
zbank = 0; /* Assume default bank is $000000-$007FFF */
/* Reset 68k, Z80 & YM2612 */
m68k_pulse_reset();
z80_reset();
YM2612ResetChip();
}
void gen_softreset(int state)
{
if (state)
{
/* Halt 68k, Z80 & YM2612 */
m68k_pulse_halt();
zstate = 0;
YM2612ResetChip();
}
else
{
/* VDP is not reseted so CPU could be anywhere in a frame */
/* Reset Action Replay */
if (config.lock_on == TYPE_AR)
datel_reset(0);
/* VDP is not reseted so 68k & Z80 could restart anywhere in the emulated frame */
mcycles_68k = mcycles_z80 = (uint32)((MCYCLES_PER_LINE * lines_per_frame) * ((double)rand() / (double)RAND_MAX));
}
zstate = 0; /* Z80 is reset & has control of the bus */
zirq = 0; /* No interrupts occuring */
zbank = 0; /* Assume default bank is $000000-$007FFF */
/* Reset CPUs */
gen_running = 1;
fm_reset(0);
/* Reset 68k, Z80 & YM2612 */
m68k_pulse_reset();
z80_reset();
YM2612ResetChip();
}
}
void gen_shutdown(void)
@ -158,68 +171,58 @@ void gen_shutdown(void)
/*-----------------------------------------------------------------------
Bus controller chip functions
-----------------------------------------------------------------------*/
void gen_busreq_w(uint32 state)
void gen_busreq_w(uint32 state, uint32 cycles)
{
if (state)
if (state) /* Z80 Bus Requested */
{
/* Bus requested */
/* if z80 was running, resynchronize with 68k */
if (zstate == 1)
{
/* Z80 is stopped */
/* Z80 was ON during the last 68k cycles */
z80_run(mcycles_68k);
}
z80_run(cycles);
/* update Z80 bus status */
/* request Z80 bus */
zstate |= 2;
}
else
else /* Z80 Bus Released */
{
/* Bus released */
/* if z80 is restarted, resynchronize with 68k */
if (zstate == 3)
{
/* Z80 is restarted */
/* Z80 was OFF during the last 68k cycles */
mcycles_z80 = mcycles_68k;
}
mcycles_z80 = cycles;
/* update Z80 bus status */
/* release Z80 bus */
zstate &= 1;
}
}
void gen_reset_w(uint32 state)
void gen_reset_w(uint32 state, uint32 cycles)
{
if (state)
{
/* stop RESET process */
if (!zstate)
{
/* Z80 is restarted */
/* Z80 was OFF during the last cycles */
mcycles_z80 = mcycles_68k;
}
/* detect !ZRESET transitions */
if (state == (zstate & 1))
return;
/* update Z80 bus status */
zstate |= 1;
}
else
if (state) /* !ZRESET released */
{
/* start RESET process */
if (zstate == 1)
{
/* Z80 stopped */
/* z80 was ON during the last 68k cycles */
z80_run(mcycles_68k);
}
/* if z80 is restarted, resynchronize with 68k */
if (zstate == 0)
mcycles_z80 = cycles;
/* Reset Z80 & YM2612 */
fm_reset(mcycles_68k);
/* reset Z80 */
z80_reset();
/* update Z80 bus status */
/* release Z80 reset */
zstate |= 1;
}
else /* !ZRESET enabled */
{
/* if z80 was running, resynchronize with 68k */
if (zstate == 1)
z80_run(cycles);
/* hold Z80 reset */
zstate &= 2;
}
/* reset YM2612 */
fm_reset(cycles);
}
void gen_bank_w (uint32 state)

View File

@ -28,21 +28,18 @@
extern uint8 bios_rom[0x10000];
extern uint8 work_ram[0x10000];
extern uint8 zram[0x2000];
extern uint32 zirq;
extern uint8 zstate;
extern uint32 zbank;
extern uint32 zstate;
extern uint32 gen_running;
extern int32 resetline;
/* Function prototypes */
extern void gen_init(void);
extern void gen_reset(uint32 hard_reset);
extern void gen_hardreset(void);
extern void gen_softreset(int state);
extern void gen_shutdown(void);
extern void gen_busreq_w(uint32 state);
extern void gen_reset_w(uint32 state);
extern void gen_busreq_w(uint32 state, uint32 cycles);
extern void gen_reset_w(uint32 state, uint32 cycles);
extern void gen_bank_w(uint32 state);
extern int z80_irq_callback(int param);
extern void set_softreset(void);
#endif /* _GEN_H_ */

View File

@ -334,9 +334,9 @@ static gui_butn buttons_list[4] =
/* Main menu */
static gui_butn buttons_main[9] =
{
{&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3,0,1}, 80,140,148,132},
{&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3,1,1},246,140,148,132},
{&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3,1,1},412,140,148,132},
{&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,0,0,1}, 80,140,148,132},
{&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,0,1,1},246,140,148,132},
{&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,0,1,0},412,140,148,132},
{&button_icon_data, BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,3,1,1}, 80,194,148,132},
{&button_icon_data, BUTTON_OVER_SFX ,{3,3,1,1},246,194,148,132},
{&button_icon_data, BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,2,1,1},412,194,148,132},
@ -713,7 +713,7 @@ static int update_snd_items(void)
float rolloff = config.rolloff * 100.0;
float lg = (float)config.lg/100.0;
float mg = (float)config.mg/100.0;
float hg = config.hg * 100.0;
float hg = (float)config.hg/100.0;
if (config.hq_fm)
{
@ -786,7 +786,7 @@ static void soundmenu ()
float rolloff = config.rolloff * 100.0;
float lg = (float)config.lg/100.0;
float mg = (float)config.mg/100.0;
float hg = config.hg * 100.0;
float hg = (float)config.hg/100.0;
int offset = update_snd_items();
GUI_InitMenu(m);
GUI_SlideMenuTitle(m,strlen("Audio "));
@ -2858,6 +2858,10 @@ void MainMenu (void)
m->buttons[0].y -= 90;
m->buttons[1].y -= 90;
m->buttons[2].y -= 90;
m->buttons[0].shift[1] = 3;
m->buttons[1].shift[1] = 3;
m->buttons[2].shift[1] = 3;
m->buttons[2].shift[3] = 1;
m->buttons[3].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE);
m->buttons[4].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE);
m->buttons[5].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE);

View File

@ -58,9 +58,6 @@ static const char *keys_name[MAX_KEYS] =
"MODE Button"
};
static int held_cnt = 0;
#ifdef HW_RVL
#define PAD_UP 0
@ -75,8 +72,11 @@ static u32 wpad_dirmap[3][4] =
{WPAD_BUTTON_UP, WPAD_BUTTON_DOWN, WPAD_BUTTON_LEFT, WPAD_BUTTON_RIGHT}, /* WIIMOTE + NUNCHUK */
{WPAD_CLASSIC_BUTTON_UP, WPAD_CLASSIC_BUTTON_DOWN, WPAD_CLASSIC_BUTTON_LEFT, WPAD_CLASSIC_BUTTON_RIGHT} /* CLASSIC */
};
#endif
static int held_cnt = 0;
static int softreset = 0;
/***************************************************************************************/
/* Gamecube PAD support */
@ -159,23 +159,29 @@ static void pad_update(s8 chan, u8 i)
s8 x = PAD_StickX (chan);
s8 y = PAD_StickY (chan);
/* Soft Reset */
if ((p & PAD_TRIGGER_Z) && (p & PAD_TRIGGER_L))
{
gen_softreset(1);
softreset = 1;
return;
}
else if (softreset & 1)
{
gen_softreset(0);
softreset = 0;
return;
}
/* Menu Request */
if (p & PAD_TRIGGER_Z)
{
/* Menu Request */
ConfigRequested = 1;
return;
}
else if ((p & PAD_TRIGGER_L) && (p & PAD_TRIGGER_Z))
{
/* Soft RESET */
if (config.lock_on == TYPE_AR)
datel_reset(0);
gen_reset(0);
}
/* Retrieve current key mapping */
u16 pad_keymap[MAX_KEYS];
memcpy(pad_keymap, config.pad_keymap[chan], MAX_KEYS * sizeof(u16));
u16 *pad_keymap = config.pad_keymap[chan];
/* Generic buttons */
if (p & pad_keymap[KEY_BUTTONA])
@ -214,7 +220,7 @@ static void pad_update(s8 chan, u8 i)
case DEVICE_MOUSE:
{
/* MOUSE relative movement (-255,255) */
/* Mouse relative movement (-255,255) */
input.analog[2][0] = (x / ANALOG_SENSITIVITY) * 2;
input.analog[2][1] = (y / ANALOG_SENSITIVITY) * 2;
if (config.invert_mouse)
@ -226,7 +232,7 @@ static void pad_update(s8 chan, u8 i)
{
if (system_hw != SYSTEM_PICO)
{
/* gamepad */
/* Gamepad */
if ((p & PAD_BUTTON_UP) || (y > ANALOG_SENSITIVITY))
input.pad[i] |= INPUT_UP;
else if ((p & PAD_BUTTON_DOWN) || (y < -ANALOG_SENSITIVITY))
@ -463,21 +469,27 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
s8 x = 0;
s8 y = 0;
u32 p = data->btns_h;
u32 u = data->btns_u;
if ((u & WPAD_BUTTON_HOME) || (u & WPAD_CLASSIC_BUTTON_HOME))
{
/* Menu Request */
ConfigRequested = 1;
return;
}
else if (((p & WPAD_BUTTON_PLUS) && (p & WPAD_BUTTON_MINUS)) ||
/* Soft Reset */
if (((p & WPAD_BUTTON_PLUS) && (p & WPAD_BUTTON_MINUS)) ||
((p & WPAD_CLASSIC_BUTTON_PLUS) && (p & WPAD_CLASSIC_BUTTON_MINUS)))
{
/* Soft RESET */
if (config.lock_on == TYPE_AR)
datel_reset(0);
gen_reset(0);
gen_softreset(1);
softreset = 1;
return;
}
else if (softreset & 1)
{
gen_softreset(0);
softreset = 0;
return;
}
/* Menu Request */
if ((p & WPAD_BUTTON_HOME) || (p & WPAD_CLASSIC_BUTTON_HOME))
{
ConfigRequested = 1;
return;
}
/* Retrieve current key mapping */
@ -816,38 +828,43 @@ void gx_input_UpdateEmu(void)
int i;
int player = 0;
/* update controllers */
/* Update controllers */
PAD_ScanPads();
#ifdef HW_RVL
WPAD_ScanPads();
#endif
#ifdef HW_RVL
/* Check RESET button status */
if (SYS_ResetButtonDown())
{
/* Soft RESET */
if (config.lock_on == TYPE_AR)
datel_reset(0);
gen_reset(0);
gen_softreset(1);
softreset = 2;
return;
}
else if (softreset & 2)
{
gen_softreset(0);
softreset = 0;
return;
}
#endif
for (i=0; i<MAX_DEVICES; i++)
{
/* update inputs */
if (input.dev[i] != NO_DEVICE)
{
/* clear key status */
input.pad[i] = 0;
/* update inputs */
if (input.dev[i] != NO_DEVICE)
{
/* retrieve controller status */
if (config.input[player].device == 0)
pad_update(config.input[player].port, i);
#ifdef HW_RVL
else if (config.input[player].device > 0)
wpad_update(config.input[player].port,i, config.input[player].device - 1);
#endif
/* increment player index */
player ++;
}
}

View File

@ -60,8 +60,6 @@ u32 gc_pal = 0;
/*** NTSC Filters ***/
sms_ntsc_t *sms_ntsc;
md_ntsc_t *md_ntsc;
static const sms_ntsc_setup_t *sms_setup;
static const md_ntsc_setup_t *md_setup;
/*** GX FIFO ***/
static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN (32);
@ -1267,10 +1265,10 @@ void gxTextureClose(gx_texture **p_texture)
void gx_video_Stop(void)
{
/* unallocate NTSC filters */
if (sms_ntsc)
free(sms_ntsc);
if (md_ntsc)
free(md_ntsc);
if (sms_ntsc) free(sms_ntsc);
if (md_ntsc) free(md_ntsc);
sms_ntsc = NULL;
md_ntsc = NULL;
/* lightgun textures */
gxTextureClose(&crosshair[0]);
@ -1351,36 +1349,33 @@ void gx_video_Start(void)
/* 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 */
sms_ntsc = NULL;
md_ntsc = NULL;
if (config.ntsc)
{
/* allocate filters */
if (!sms_ntsc)
sms_ntsc = (sms_ntsc_t *)memalign(32,sizeof(sms_ntsc_t));
if (!md_ntsc)
md_ntsc = (md_ntsc_t *)memalign(32,sizeof(md_ntsc_t));
/* setup filters default configuration */
switch (config.ntsc)
{
case 1:
sms_setup = &sms_ntsc_composite;
md_setup = &md_ntsc_composite;
sms_ntsc_init(sms_ntsc, &sms_ntsc_composite);
md_ntsc_init(md_ntsc, &md_ntsc_composite);
break;
case 2:
sms_setup = &sms_ntsc_svideo;
md_setup = &md_ntsc_svideo;
sms_ntsc_init(sms_ntsc, &sms_ntsc_svideo);
md_ntsc_init(md_ntsc, &md_ntsc_svideo);
break;
case 3:
sms_setup = &sms_ntsc_rgb;
md_setup = &md_ntsc_rgb;
sms_ntsc_init(sms_ntsc, &sms_ntsc_rgb);
md_ntsc_init(md_ntsc, &md_ntsc_rgb);
break;
}
/* initialize filters */
sms_ntsc_init(sms_ntsc, sms_setup);
md_ntsc_init(md_ntsc, md_setup);
}
/* lightgun textures */
@ -1389,9 +1384,6 @@ void gx_video_Start(void)
if (config.gun_cursor[1] && (input.dev[5] == DEVICE_LIGHTGUN))
crosshair[1] = gxTextureOpenPNG(Crosshair_p2_png,0);
/* force changes on next video update */
bitmap.viewport.changed = 1;
/* GX emulation rendering */
gxResetRendering(0);

View File

@ -516,7 +516,7 @@ const uint8 cycle2hc40[3420] =
const uint8 cycle2hc32[3420] =
{
/* end of active display (16 pixels -> 160 Mcycles) , HINT triggered ? , Vcounter jump */
0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x88, 0x88, 0x88, 0x88,
@ -748,7 +748,8 @@ const uint8 cycle2hc32[3420] =
0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
0x82, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85,
0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
};
const uint8 *vctab;

View File

@ -67,8 +67,7 @@ void m68k_lockup_w_8 (uint32 address, uint32 data)
#ifdef LOGERROR
error ("Lockup %08X = %02X (%08X)\n", address, data, m68k_get_reg (NULL, M68K_REG_PC));
#endif
gen_running = config.force_dtack;
if (!gen_running)
if (!config.force_dtack)
m68k_pulse_halt ();
}
@ -77,8 +76,7 @@ void m68k_lockup_w_16 (uint32 address, uint32 data)
#ifdef LOGERROR
error ("Lockup %08X = %04X (%08X)\n", address, data, m68k_get_reg (NULL, M68K_REG_PC));
#endif
gen_running = config.force_dtack;
if (!gen_running)
if (!config.force_dtack)
m68k_pulse_halt ();
}
@ -87,8 +85,7 @@ uint32 m68k_lockup_r_8 (uint32 address)
#ifdef LOGERROR
error ("Lockup %08X.b (%08X)\n", address, m68k_get_reg (NULL, M68K_REG_PC));
#endif
gen_running = config.force_dtack;
if (!gen_running)
if (!config.force_dtack)
m68k_pulse_halt ();
return -1;
}
@ -98,8 +95,7 @@ uint32 m68k_lockup_r_16 (uint32 address)
#ifdef LOGERROR
error ("Lockup %08X.w (%08X)\n", address, m68k_get_reg (NULL, M68K_REG_PC));
#endif
gen_running = config.force_dtack;
if (!gen_running)
if (!config.force_dtack)
m68k_pulse_halt ();
return -1;
}
@ -371,14 +367,14 @@ void ctrl_io_write_byte(uint32 address, uint32 data)
if (address & 1)
m68k_unused_8_w(address, data);
else
gen_busreq_w(data & 1);
gen_busreq_w(data & 1, mcycles_68k);
return;
case 0x12: /* RESET */
if (address & 1)
m68k_unused_8_w(address, data);
else
gen_reset_w(data & 1);
gen_reset_w(data & 1, mcycles_68k);
return;
case 0x30: /* TIME */
@ -430,11 +426,11 @@ void ctrl_io_write_word(uint32 address, uint32 data)
return;
case 0x11: /* BUSREQ */
gen_busreq_w ((data >> 8) & 1);
gen_busreq_w ((data >> 8) & 1, mcycles_68k);
return;
case 0x12: /* RESET */
gen_reset_w ((data >> 8) & 1);
gen_reset_w ((data >> 8) & 1, mcycles_68k);
return;
case 0x50: /* SVP REGISTERS */
@ -503,18 +499,18 @@ uint32 vdp_read_byte(uint32 address)
return (vdp_data_r() & 0xff);
case 0x04: /* CTRL */
return ((m68k_read_pcrelative_8(REG_PC) & 0xfc) | ((vdp_ctrl_r() >> 8) & 3));
return ((m68k_read_pcrelative_8(REG_PC) & 0xfc) | ((vdp_ctrl_r(mcycles_68k) >> 8) & 3));
case 0x05: /* CTRL */
return (vdp_ctrl_r() & 0xff);
return (vdp_ctrl_r(mcycles_68k) & 0xff);
case 0x08: /* HVC */
case 0x0c:
return (vdp_hvc_r() >> 8);
return (vdp_hvc_r(mcycles_68k) >> 8);
case 0x09: /* HVC */
case 0x0d:
return (vdp_hvc_r() & 0xff);
return (vdp_hvc_r(mcycles_68k) & 0xff);
case 0x18: /* Unused */
case 0x19:
@ -535,11 +531,11 @@ uint32 vdp_read_word(uint32 address)
return vdp_data_r();
case 0x04: /* CTRL */
return ((vdp_ctrl_r() & 0x3FF) | (m68k_read_pcrelative_16(REG_PC) & 0xFC00));
return ((vdp_ctrl_r(mcycles_68k) & 0x3FF) | (m68k_read_pcrelative_16(REG_PC) & 0xFC00));
case 0x08: /* HVC */
case 0x0c:
return vdp_hvc_r();
return vdp_hvc_r(mcycles_68k);
case 0x18: /* Unused */
case 0x1c:

View File

@ -47,7 +47,11 @@ uint32 zbank_lockup_r(uint32 address)
#ifdef LOGERROR
error("Z80 bank lockup read %06X\n", address);
#endif
gen_running = config.force_dtack;
if (!config.force_dtack)
{
mcycles_z80 = 0xffffffff;
zstate = 0;
}
return 0xFF;
}
@ -56,7 +60,11 @@ void zbank_lockup_w(uint32 address, uint32 data)
#ifdef LOGERROR
error("Z80 bank lockup write %06X = %02X\n", address, data);
#endif
gen_running = config.force_dtack;
if (!config.force_dtack)
{
mcycles_z80 = 0xffffffff;
zstate = 0;
}
}
/* I/O & Control registers */
@ -108,14 +116,14 @@ void zbank_write_ctrl_io(uint32 address, uint32 data)
if (address & 1)
zbank_unused_w(address, data);
else
gen_busreq_w(data & 1);
gen_busreq_w(data & 1, mcycles_z80);
return;
case 0x12: /* RESET */
if (address & 1)
zbank_unused_w(address, data);
else
gen_reset_w(data & 1);
gen_reset_w(data & 1, mcycles_z80);
return;
case 0x30: /* TIME */
@ -168,18 +176,18 @@ uint32 zbank_read_vdp(uint32 address)
return (vdp_data_r() & 0xff);
case 0x04: /* CTRL */
return (0xfc | ((vdp_ctrl_r() >> 8) & 3));
return (0xfc | ((vdp_ctrl_r(mcycles_z80) >> 8) & 3));
case 0x05: /* CTRL */
return (vdp_ctrl_r() & 0xff);
return (vdp_ctrl_r(mcycles_z80) & 0xff);
case 0x08: /* HVC */
case 0x0c:
return (vdp_hvc_r() >> 8);
return (vdp_hvc_r(mcycles_z80) >> 8);
case 0x09: /* HVC */
case 0x0d:
return (vdp_hvc_r() & 0xff);
return (vdp_hvc_r(mcycles_z80) & 0xff);
case 0x18: /* Unused */
case 0x19:

View File

@ -46,7 +46,11 @@ static inline void z80_lockup_w(unsigned int address, unsigned int data)
#ifdef LOGERROR
error("Z80 lockup write %04X = %02X\n", address, data);
#endif
gen_running = config.force_dtack;
if (!config.force_dtack)
{
mcycles_z80 = 0xffffffff;
zstate = 0;
}
}
static inline unsigned int z80_lockup_r(unsigned int address)
@ -54,7 +58,11 @@ static inline unsigned int z80_lockup_r(unsigned int address)
#ifdef LOGERROR
error("Z80 lockup read %04X\n", address);
#endif
gen_running = config.force_dtack;
if (!config.force_dtack)
{
mcycles_z80 = 0xffffffff;
zstate = 0;
}
return 0xff;
}
/*
@ -71,18 +79,18 @@ static inline unsigned int z80_vdp_r(unsigned int address)
return (vdp_data_r() & 0xff);
case 0x04: /* CTRL */
return (0xfc | (vdp_ctrl_r() >> 8));
return (0xfc | (vdp_ctrl_r(mcycles_z80) >> 8));
case 0x05: /* CTRL */
return (vdp_ctrl_r() & 0xff);
return (vdp_ctrl_r(mcycles_z80) & 0xff);
case 0x08: /* HVC */
case 0x0c:
return (vdp_hvc_r() >> 8);
return (vdp_hvc_r(mcycles_z80) >> 8);
case 0x09: /* HVC */
case 0x0d:
return (vdp_hvc_r() & 0xff);
return (vdp_hvc_r(mcycles_z80) & 0xff);
case 0x18: /* Unused */
case 0x19:

View File

@ -300,7 +300,7 @@ void system_reset (void)
cart_hw_reset();
/* Genesis hardware */
gen_reset(1);
gen_hardreset();
io_reset();
vdp_reset();
render_reset();
@ -325,14 +325,8 @@ void system_shutdown (void)
/****************************************************************
* Virtual Genesis Frame emulation
****************************************************************/
int system_frame (int do_skip)
void system_frame (int do_skip)
{
if (!gen_running)
{
osd_input_Update();
return 0;
}
/* update display settings */
int line;
int vdp_height = bitmap.viewport.h;
@ -346,7 +340,6 @@ int system_frame (int do_skip)
im2_flag = ((reg[12] & 6) == 6);
odd_frame = 1;
}
odd_frame ^= 1;
/* clear VBLANK, DMA, FIFO FULL & field flags */
status &= 0xFEE5;
@ -355,6 +348,7 @@ int system_frame (int do_skip)
status |= 0x0200;
/* even/odd field flag (interlaced modes only) */
odd_frame ^= 1;
if (odd_frame && interlaced)
status |= 0x0010;
@ -473,6 +467,4 @@ int system_frame (int do_skip)
/* adjust cpu cycle count for next frame */
mcycles_68k -= mcycles_vdp;
mcycles_z80 -= mcycles_vdp;
return gen_running;
}

View File

@ -89,7 +89,7 @@ extern void audio_set_equalizer(void);
extern void system_init (void);
extern void system_reset (void);
extern void system_shutdown (void);
extern int system_frame(int skip);
extern void system_frame(int do_skip);
#endif /* _SYSTEM_H_ */

View File

@ -5,19 +5,18 @@
# modified by Eke-Eke <eke_eke31@yahoo.fr>
#
# Defines :
# LSB_FIRST : for little endian systems.
# X86_ASM : enable x86 assembly optimizations
# LOGERROR
# LOGVDP
# LOGSOUND
# -DLSB_FIRST : for little endian systems.
# -DLOGERROR : enable message log
# -DLOGVDP : enable VDP debug messages
# -DLOGSOUND : enable AUDIO debug messages
NAME = gen_sdl.exe
CC = gcc
CFLAGS = `sdl-config --cflags` -O6 -march=i686 -fomit-frame-pointer
CFLAGS = `sdl-config --cflags` -march=i686 -O6 -fomit-frame-pointer -Wall -Wno-strict-aliasing
#-g -ggdb -pg
#-fomit-frame-pointer
#LDFLAGS = -g -ggdb -pg
#LDFLAGS = -pg
DEFINES = -DLSB_FIRST -DX86_ASM
INCLUDES = -I. -I.. -I../z80 -I../m68k -I../sound -I../cart_hw -I../cart_hw/svp -I../ntsc

View File

@ -20,6 +20,8 @@ void set_config_defaults(void)
config.mg = 1.0;
config.hg = 1.0;
config.lp_range = 50;
config.rolloff = 0.999;
config.dac_bits = 14;
/* system options */
config.region_detect = 0;
@ -30,7 +32,7 @@ void set_config_defaults(void)
config.romtype = 0;
/* display options */
config.overscan = 1;
config.overscan = 0;
config.render = 0;
/* controllers options */

View File

@ -24,6 +24,8 @@ typedef struct
float lg;
float mg;
float hg;
float rolloff;
uint8 dac_bits;
uint8 region_detect;
uint8 force_dtack;
uint8 addr_error;

View File

@ -10,8 +10,8 @@
#define SOUND_FREQUENCY 48000
#define SOUND_SAMPLES_SIZE 2048
#define VIDEO_WIDTH 640
#define VIDEO_HEIGHT 480
#define VIDEO_WIDTH 320
#define VIDEO_HEIGHT 240
int joynum = 0;
@ -117,8 +117,8 @@ static void sdl_sound_close()
}
/* video */
md_ntsc_t md_ntsc;
sms_ntsc_t sms_ntsc;
md_ntsc_t *md_ntsc;
sms_ntsc_t *sms_ntsc;
struct {
SDL_Surface* surf_screen;
@ -158,29 +158,41 @@ static void sdl_video_update()
rect.x=(VIDEO_WIDTH-rect.w)/2;
rect.y=(VIDEO_HEIGHT-rect.h)/2;
/* init NTSC filter */
md_ntsc_setup_t md_setup;
sms_ntsc_setup_t sms_setup;
if (config.ntsc == 1)
/* NTSC filters */
if (config.ntsc)
{
sms_setup = sms_ntsc_composite;
md_setup = md_ntsc_composite;
sms_ntsc_init( &sms_ntsc, &sms_setup );
md_ntsc_init( &md_ntsc, &md_setup );
sms_ntsc = (sms_ntsc_t *)malloc(sizeof(sms_ntsc_t));
md_ntsc = (md_ntsc_t *)malloc(sizeof(md_ntsc_t));
switch (config.ntsc)
{
case 1:
sms_ntsc_init(sms_ntsc, &sms_ntsc_composite);
md_ntsc_init(md_ntsc, &md_ntsc_composite);
break;
case 2:
sms_ntsc_init(sms_ntsc, &sms_ntsc_svideo);
md_ntsc_init(md_ntsc, &md_ntsc_svideo);
break;
case 3:
sms_ntsc_init(sms_ntsc, &sms_ntsc_rgb);
md_ntsc_init(md_ntsc, &md_ntsc_rgb);
break;
}
else if (config.ntsc == 2)
{
sms_setup = sms_ntsc_svideo;
md_setup = md_ntsc_svideo;
sms_ntsc_init( &sms_ntsc, &sms_setup );
md_ntsc_init( &md_ntsc, &md_setup );
}
else if (config.ntsc == 3)
else
{
sms_setup = sms_ntsc_rgb;
md_setup = md_ntsc_rgb;
sms_ntsc_init( &sms_ntsc, &sms_setup );
md_ntsc_init( &md_ntsc, &md_setup );
if (sms_ntsc)
{
free(sms_ntsc);
sms_ntsc = NULL;
}
if (md_ntsc)
{
free(md_ntsc);
md_ntsc = NULL;
}
}
}
@ -193,8 +205,10 @@ static void sdl_video_update()
static void sdl_video_close()
{
if (sdl_video.surf_bitmap) SDL_FreeSurface(sdl_video.surf_bitmap);
if (sdl_video.surf_screen) SDL_FreeSurface(sdl_video.surf_screen);
if (sdl_video.surf_bitmap)
SDL_FreeSurface(sdl_video.surf_bitmap);
if (sdl_video.surf_screen)
SDL_FreeSurface(sdl_video.surf_screen);
}
/* Timer Sync */
@ -210,17 +224,12 @@ static Uint32 sdl_sync_timer_callback(Uint32 interval)
{
SDL_SemPost(sdl_sync.sem_sync);
char caption[100];
char region[10];
if (region_code == REGION_USA) sprintf(region,"USA");
else if (region_code == REGION_EUROPE) sprintf(region,"EUR");
else sprintf(region,"JAP");
sdl_sync.ticks++;
if (sdl_sync.ticks == (vdp_pal ? 50 : 20))
{
int fps = vdp_pal ? (sdl_video.frames_rendered / 3) : sdl_video.frames_rendered;
sdl_sync.ticks = sdl_video.frames_rendered = 0;
sprintf(caption, "Genesis Plus/SDL - %s (%s) - 0x%04X - %d fps", rominfo.international, region, rominfo.realchecksum, fps);
sprintf(caption, "Genesis Plus SDL - %d fps", fps);
SDL_WM_SetCaption(caption, NULL);
}
return interval;
@ -228,10 +237,12 @@ static Uint32 sdl_sync_timer_callback(Uint32 interval)
static int sdl_sync_init()
{
if(SDL_InitSubSystem(SDL_INIT_TIMER|SDL_INIT_EVENTTHREAD) < 0) {
if(SDL_InitSubSystem(SDL_INIT_TIMER|SDL_INIT_EVENTTHREAD) < 0)
{
MessageBox(NULL, "SDL Timer initialization failed", "Error", 0);
return 0;
}
sdl_sync.sem_sync = SDL_CreateSemaphore(0);
sdl_sync.ticks = 0;
return 1;
@ -347,7 +358,7 @@ static int sdl_control_update(SDLKey keystate)
case SDLK_F10:
{
set_softreset();
gen_softreset(0);
break;
}
@ -433,7 +444,8 @@ int sdl_input_update(void)
input.analog[2][1] = y;
/* Vertical movement is upsidedown */
if (!config.invert_mouse) input.analog[2][1] = 0 - input.analog[2][1];
if (!config.invert_mouse)
input.analog[2][1] = 0 - input.analog[2][1];
/* Map mouse buttons to player #1 inputs */
if(state & SDL_BUTTON_MMASK) input.pad[joynum] |= INPUT_C;
@ -463,8 +475,8 @@ int sdl_input_update(void)
int state = SDL_GetMouseState(&x,&y);
/* Calculate X Y axis values */
input.analog[0][0] = 0x3c + (x * (0x17c-0x03c+1)) / 640;
input.analog[0][1] = 0x1fc + (y * (0x2f7-0x1fc+1)) / 480;
input.analog[0][0] = 0x3c + (x * (0x17c-0x03c+1)) / VIDEO_WIDTH;
input.analog[0][1] = 0x1fc + (y * (0x2f7-0x1fc+1)) / VIDEO_HEIGHT;
/* Map mouse buttons to player #1 inputs */
if(state & SDL_BUTTON_MMASK) pico_current++;
@ -601,7 +613,7 @@ int main (int argc, char **argv)
f = fopen("./game.srm", "wb");
if (f!=NULL)
{
fwrite(&sram.sram,0x10000,1, f);
fwrite(sram.sram,0x10000,1, f);
fclose(f);
}

View File

@ -50,7 +50,8 @@ uint16 status; /* VDP status flags */
uint8 dmafill; /* next VDP Write is DMA Fill */
uint8 hint_pending; /* 0= Line interrupt is pending */
uint8 vint_pending; /* 1= Frame interrupt is pending */
uint8 irq_status; /* Interrupt lines updated */
uint8 zirq; /* Z80 IRQ status */
uint8 irq_status; /* 68K IRQ status */
/* Global variables */
uint16 ntab; /* Name table A base address */
@ -127,7 +128,7 @@ static const uint32 dma_rates[16] = {
/*--------------------------------------------------------------------------*/
/* Functions prototype */
/*--------------------------------------------------------------------------*/
static void fifo_update();
static void fifo_update(unsigned int cycles);
static void data_w(unsigned int data);
static void reg_w(unsigned int r, unsigned int d);
static void dma_copy(void);
@ -160,6 +161,7 @@ void vdp_reset(void)
pending = 0;
hint_pending = 0;
vint_pending = 0;
zirq = 0;
irq_status = 0;
hvc_latch = 0;
v_counter = 0;
@ -172,7 +174,7 @@ void vdp_reset(void)
interlaced = 0;
fifo_write_cnt = 0;
fifo_lastwrite = 0;
fifo_latency = 190; /* default FIFO timings */
fifo_latency = 190;
status = vdp_pal | 0x0200; /* FIFO empty */
@ -422,13 +424,13 @@ void vdp_ctrl_w(unsigned int data)
* 9 Write FIFO empty
* 10 - 15 Open Bus
*/
unsigned int vdp_ctrl_r(void)
unsigned int vdp_ctrl_r(unsigned int cycles)
{
/* update FIFO flags */
fifo_update();
fifo_update(cycles);
/* update DMA Busy flag */
if ((status & 2) && !dma_length && (mcycles_68k >= dma_endCycles))
if ((status & 2) && !dma_length && (cycles >= dma_endCycles))
status &= 0xFFFD;
unsigned int temp = status;
@ -438,7 +440,7 @@ unsigned int vdp_ctrl_r(void)
temp |= 0x08;
/* HBLANK flag (Sonic 3 and Sonic 2 "VS Modes", Lemmings 2, Mega Turrican, V.R Troopers, Gouketsuji Ichizoku, ...) */
if ((mcycles_68k % MCYCLES_PER_LINE) < 588)
if ((cycles % MCYCLES_PER_LINE) < 588)
temp |= 0x04;
/* clear pending flag */
@ -448,19 +450,19 @@ unsigned int vdp_ctrl_r(void)
status &= 0xFF9F;
#ifdef LOGVDP
error("[%d(%d)][%d(%d)] VDP status read -> 0x%x (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE, temp, m68k_get_reg (NULL, M68K_REG_PC));
error("[%d(%d)][%d(%d)] VDP status read -> 0x%x (%x)\n", v_counter, cycles/MCYCLES_PER_LINE, cycles, cycles%MCYCLES_PER_LINE, temp, m68k_get_reg (NULL, M68K_REG_PC));
#endif
return (temp);
}
unsigned int vdp_hvc_r(void)
unsigned int vdp_hvc_r(unsigned int cycles)
{
/* HVC is frozen (Lightgun games + Sunset Riders) */
/* HVC is frozen (Lightgun games, Sunset Riders) */
if (hvc_latch)
return (hvc_latch & 0xffff);
/* Horizontal Counter (Striker, Mickey Mania, Skitchin, Road Rash I,II,III, ...) */
uint8 hc = hctab[mcycles_68k%MCYCLES_PER_LINE];
/* Horizontal Counter (Striker, Mickey Mania, Skitchin, Road Rash I,II,III, Sonic 3D Blast...) */
uint8 hc = hctab[cycles%MCYCLES_PER_LINE];
/* Vertical Counter */
uint8 vc = vctab[v_counter];
@ -470,7 +472,7 @@ unsigned int vdp_hvc_r(void)
vc = (vc << 1) | ((vc >> 7) & 1);
#ifdef LOGVDP
error("[%d(%d)][%d(%d)] VDP HVC Read -> 0x%04x (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE,(vc << 8) | hc, m68k_get_reg (NULL, M68K_REG_PC));
error("[%d(%d)][%d(%d)] VDP HVC Read -> 0x%04x (%x)\n", v_counter, cycles/MCYCLES_PER_LINE, cycles, cycles%MCYCLES_PER_LINE,(vc << 8) | hc, m68k_get_reg (NULL, M68K_REG_PC));
#endif
return ((vc << 8) | hc);
}
@ -497,7 +499,7 @@ void vdp_data_w(unsigned int data)
if (!(status&8) && (reg[1]&0x40))
{
/* update VDP FIFO */
fifo_update();
fifo_update(mcycles_68k);
if (fifo_write_cnt == 0)
{
@ -625,12 +627,12 @@ int vdp_int_ack_callback(int int_level)
/*--------------------------------------------------------------------------*/
/* FIFO emulation */
/*--------------------------------------------------------------------------*/
static void fifo_update()
static void fifo_update(unsigned int cycles)
{
if (fifo_write_cnt > 0)
{
/* update FIFO reads */
int fifo_read = ((mcycles_68k - fifo_lastwrite) / fifo_latency);
int fifo_read = ((cycles - fifo_lastwrite) / fifo_latency);
if (fifo_read > 0)
{
fifo_write_cnt -= fifo_read;

View File

@ -38,6 +38,7 @@ extern uint16 status;
extern uint8 dmafill;
extern uint8 hint_pending;
extern uint8 vint_pending;
extern uint8 zirq;
extern uint8 irq_status;
/* Global variables */
@ -80,10 +81,10 @@ extern void vdp_shutdown(void);
extern void vdp_restore(uint8 *vdp_regs);
extern void vdp_update_dma();
extern void vdp_ctrl_w(unsigned int data);
extern unsigned int vdp_ctrl_r(void);
extern unsigned int vdp_ctrl_r(unsigned int cycles);
extern void vdp_data_w(unsigned int data);
extern unsigned int vdp_data_r(void);
extern unsigned int vdp_hvc_r(void);
extern unsigned int vdp_hvc_r(unsigned int cycles);
extern void vdp_test_w(unsigned int value);
extern int vdp_int_ack_callback(int int_level);