mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-27 03:31:49 +01:00
[Core]
.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:
parent
7db1b3ef85
commit
f21a08ebfa
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**********************************************
|
||||
|
@ -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 */
|
||||
|
141
source/genesis.c
141
source/genesis.c
@ -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,37 +115,52 @@ 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));
|
||||
|
||||
/* TMSS BIOS support */
|
||||
if (config.bios_enabled == 3)
|
||||
m68k_memory_map[0].base = bios_rom;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
/* Clear RAM */
|
||||
memset (work_ram, 0x00, sizeof (work_ram));
|
||||
memset (zram, 0x00, sizeof (zram));
|
||||
|
||||
/* TMSS BIOS support */
|
||||
if (config.bios_enabled == 3)
|
||||
m68k_memory_map[0].base = bios_rom;
|
||||
|
||||
/* Reset CPU cycle counts */
|
||||
mcycles_68k = 0;
|
||||
mcycles_z80 = 0;
|
||||
/* 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));
|
||||
|
||||
/* Reset 68k, Z80 & YM2612 */
|
||||
m68k_pulse_reset();
|
||||
z80_reset();
|
||||
YM2612ResetChip();
|
||||
}
|
||||
|
||||
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);
|
||||
m68k_pulse_reset();
|
||||
z80_reset();
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -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_ */
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
/* Soft Reset */
|
||||
if (((p & WPAD_BUTTON_PLUS) && (p & WPAD_BUTTON_MINUS)) ||
|
||||
((p & WPAD_CLASSIC_BUTTON_PLUS) && (p & WPAD_CLASSIC_BUTTON_MINUS)))
|
||||
{
|
||||
/* Menu Request */
|
||||
ConfigRequested = 1;
|
||||
gen_softreset(1);
|
||||
softreset = 1;
|
||||
return;
|
||||
}
|
||||
else if (((p & WPAD_BUTTON_PLUS) && (p & WPAD_BUTTON_MINUS)) ||
|
||||
((p & WPAD_CLASSIC_BUTTON_PLUS) && (p & WPAD_CLASSIC_BUTTON_MINUS)))
|
||||
else if (softreset & 1)
|
||||
{
|
||||
/* Soft RESET */
|
||||
if (config.lock_on == TYPE_AR)
|
||||
datel_reset(0);
|
||||
gen_reset(0);
|
||||
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++)
|
||||
{
|
||||
/* clear key status */
|
||||
input.pad[i] = 0;
|
||||
|
||||
/* update inputs */
|
||||
if (input.dev[i] != NO_DEVICE)
|
||||
{
|
||||
/* clear key status */
|
||||
input.pad[i] = 0;
|
||||
|
||||
/* 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 ++;
|
||||
}
|
||||
}
|
||||
|
@ -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 */
|
||||
sms_ntsc = (sms_ntsc_t *)memalign(32,sizeof(sms_ntsc_t));
|
||||
md_ntsc = (md_ntsc_t *)memalign(32,sizeof(md_ntsc_t));
|
||||
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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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,8 +340,7 @@ 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;
|
||||
}
|
||||
|
@ -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_ */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 */
|
||||
@ -209,18 +223,13 @@ struct {
|
||||
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");
|
||||
|
||||
char caption[100];
|
||||
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);
|
||||
}
|
||||
|
||||
|
34
source/vdp.c
34
source/vdp.c
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user