mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-09-10 16:53:15 +02:00
[Wii/Gamecube]
* added an option to set VDP mode (PAL/NTSC) independently from console region. * added an option to select console master clock frequency (PAL/NTSC/AUTO): emulation now run at selected frequency when VSYNC is disabled. * added an option to force VSYNC disabled. * improved screen scaling. [Core] * moved INLINE definition to macros.h * removed unused typedef from osd_cpu.h * cleanup include files
This commit is contained in:
parent
96452ac75b
commit
cab4ecba99
@ -228,7 +228,7 @@ void md_eeprom_write_word(unsigned int address, unsigned int data)
|
||||
}
|
||||
|
||||
|
||||
static __inline__ void Detect_START()
|
||||
INLINE void Detect_START()
|
||||
{
|
||||
if (md_eeprom.old_scl && md_eeprom.scl)
|
||||
{
|
||||
@ -246,7 +246,7 @@ static __inline__ void Detect_START()
|
||||
}
|
||||
}
|
||||
|
||||
static __inline__ void Detect_STOP()
|
||||
INLINE void Detect_STOP()
|
||||
{
|
||||
if (md_eeprom.old_scl && md_eeprom.scl)
|
||||
{
|
||||
|
@ -107,6 +107,8 @@ void config_default(void)
|
||||
/* system options */
|
||||
config.system = 0; /* AUTO */
|
||||
config.region_detect = 0; /* AUTO */
|
||||
config.vdp_mode = 0; /* AUTO */
|
||||
config.master_clock = 0; /* AUTO */
|
||||
config.force_dtack = 0;
|
||||
config.addr_error = 1;
|
||||
config.bios = 0;
|
||||
@ -121,6 +123,8 @@ void config_default(void)
|
||||
config.aspect = 1;
|
||||
config.overscan = 3; /* FULL */
|
||||
config.ntsc = 0;
|
||||
config.vsync = 1; /* AUTO */
|
||||
|
||||
if (VIDEO_HaveComponentCable())
|
||||
{
|
||||
config.render = 2;
|
||||
@ -132,6 +136,21 @@ void config_default(void)
|
||||
config.bilinear = 0;
|
||||
}
|
||||
|
||||
switch (vmode->viTVMode >> 2)
|
||||
{
|
||||
case VI_PAL:
|
||||
config.tv_mode = 1; /* 50hz only */
|
||||
break;
|
||||
|
||||
case VI_EURGB60:
|
||||
config.tv_mode = 2; /* 50/60hz */
|
||||
break;
|
||||
|
||||
default:
|
||||
config.tv_mode = 0; /* 60hz only */
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef HW_RVL
|
||||
config.trap = 0;
|
||||
config.gamma = VI_GM_1_0 / 10.0;
|
||||
|
@ -65,6 +65,8 @@ typedef struct
|
||||
float rolloff;
|
||||
uint8 system;
|
||||
uint8 region_detect;
|
||||
uint8 master_clock;
|
||||
uint8 vdp_mode;
|
||||
uint8 force_dtack;
|
||||
uint8 addr_error;
|
||||
uint8 tmss;
|
||||
@ -75,6 +77,7 @@ typedef struct
|
||||
uint8 gun_cursor[2];
|
||||
uint8 overscan;
|
||||
uint8 ntsc;
|
||||
uint8 vsync;
|
||||
uint8 render;
|
||||
uint8 tv_mode;
|
||||
uint8 bilinear;
|
||||
|
@ -349,27 +349,30 @@ static gui_item items_audio[13] =
|
||||
};
|
||||
|
||||
/* System options */
|
||||
static gui_item items_system[8] =
|
||||
static gui_item items_system[10] =
|
||||
{
|
||||
{NULL,NULL,"Console Hardware: AUTO", "Select system hardware model", 56,132,276,48},
|
||||
{NULL,NULL,"Console Region: AUTO", "Select system region", 56,132,276,48},
|
||||
{NULL,NULL,"System Boot: BIOS&CART", "Select system booting method", 56,132,276,48},
|
||||
{NULL,NULL,"System Lockups: ON", "Enable/disable original system lock-ups", 56,132,276,48},
|
||||
{NULL,NULL,"68k Address Error: ON", "Enable/disable 68k address error exceptions", 56,132,276,48},
|
||||
{NULL,NULL,"Lock-on: OFF", "Select Lock-On cartridge type", 56,132,276,48},
|
||||
{NULL,NULL,"Cartridge Swap: OFF", "Enable/disable cartridge hot swap", 56,132,276,48},
|
||||
{NULL,NULL,"SVP Cycles: 1500", "Adjust SVP chip emulation speed", 56,132,276,48}
|
||||
{NULL,NULL,"Console Hardware: AUTO", "Select system hardware model", 56,132,276,48},
|
||||
{NULL,NULL,"Console Region: AUTO", "Select system region", 56,132,276,48},
|
||||
{NULL,NULL,"VDP Mode: AUTO", "Select VDP mode", 56,132,276,48},
|
||||
{NULL,NULL,"System Clock: AUTO", "Select system clock frequency", 56,132,276,48},
|
||||
{NULL,NULL,"System Boot: BIOS&CART", "Select system booting method", 56,132,276,48},
|
||||
{NULL,NULL,"System Lockups: ON", "Enable/disable original system lock-ups", 56,132,276,48},
|
||||
{NULL,NULL,"68k Address Error: ON", "Enable/disable 68k address error exceptions", 56,132,276,48},
|
||||
{NULL,NULL,"Lock-on: OFF", "Select Lock-On cartridge type", 56,132,276,48},
|
||||
{NULL,NULL,"Cartridge Swap: OFF", "Enable/disable cartridge hot swap", 56,132,276,48},
|
||||
{NULL,NULL,"SVP Cycles: 1500", "Adjust SVP chip emulation speed", 56,132,276,48}
|
||||
};
|
||||
|
||||
/* Video options */
|
||||
#ifdef HW_RVL
|
||||
static gui_item items_video[10] =
|
||||
static gui_item items_video[11] =
|
||||
#else
|
||||
static gui_item items_video[8] =
|
||||
static gui_item items_video[9] =
|
||||
#endif
|
||||
{
|
||||
{NULL,NULL,"Display: PROGRESSIVE", "Select video mode", 56,132,276,48},
|
||||
{NULL,NULL,"TV mode: 50/60Hz", "Select video refresh rate", 56,132,276,48},
|
||||
{NULL,NULL,"VSYNC: AUTO", "Enable/disable synchronization with Video Hardware", 56,132,276,48},
|
||||
{NULL,NULL,"GX Bilinear Filter: OFF", "Enable/disable texture hardware filtering", 56,132,276,48},
|
||||
#ifdef HW_RVL
|
||||
{NULL,NULL,"VI Trap Filter: ON", "Enable/disable video hardware filtering", 56,132,276,48},
|
||||
@ -559,7 +562,7 @@ static gui_menu menu_system =
|
||||
{
|
||||
"System Settings",
|
||||
0,0,
|
||||
8,4,6,0,
|
||||
10,4,6,0,
|
||||
items_system,
|
||||
buttons_list,
|
||||
bg_list,
|
||||
@ -573,7 +576,7 @@ static gui_menu menu_video =
|
||||
{
|
||||
"Video Settings",
|
||||
0,0,
|
||||
8,4,6,0,
|
||||
9,4,6,0,
|
||||
items_video,
|
||||
buttons_list,
|
||||
bg_list,
|
||||
@ -1063,6 +1066,7 @@ static const uint16 vc_table[4][2] =
|
||||
static void systemmenu ()
|
||||
{
|
||||
int ret, quit = 0;
|
||||
int reinit = 0;
|
||||
gui_menu *m = &menu_system;
|
||||
gui_item *items = m->items;
|
||||
|
||||
@ -1090,29 +1094,43 @@ static void systemmenu ()
|
||||
else if (config.region_detect == 3)
|
||||
sprintf (items[1].text, "Console Region: JAPAN");
|
||||
|
||||
sprintf (items[2].text, "System Boot: %s", (config.bios & 1) ? ((config.bios & 2) ? "BIOS&CART" : "BIOS ONLY") : "CART");
|
||||
sprintf (items[3].text, "System Lockups: %s", config.force_dtack ? "OFF" : "ON");
|
||||
sprintf (items[4].text, "68k Address Error: %s", config.addr_error ? "ON" : "OFF");
|
||||
if (config.vdp_mode == 0)
|
||||
sprintf (items[2].text, "VDP Mode: AUTO");
|
||||
else if (config.vdp_mode == 1)
|
||||
sprintf (items[2].text, "VDP Mode: NTSC");
|
||||
else if (config.vdp_mode == 2)
|
||||
sprintf (items[2].text, "VDP Mode: PAL");
|
||||
|
||||
if (config.master_clock == 0)
|
||||
sprintf (items[3].text, "System Clock: AUTO");
|
||||
else if (config.master_clock == 1)
|
||||
sprintf (items[3].text, "System Clock: NTSC");
|
||||
else if (config.master_clock == 2)
|
||||
sprintf (items[3].text, "System Clock: PAL");
|
||||
|
||||
sprintf (items[4].text, "System Boot: %s", (config.bios & 1) ? ((config.bios & 2) ? "BIOS&CART" : "BIOS ONLY") : "CART");
|
||||
sprintf (items[5].text, "System Lockups: %s", config.force_dtack ? "OFF" : "ON");
|
||||
sprintf (items[6].text, "68k Address Error: %s", config.addr_error ? "ON" : "OFF");
|
||||
|
||||
if (config.lock_on == TYPE_GG)
|
||||
sprintf (items[5].text, "Lock-On: GAME GENIE");
|
||||
sprintf (items[7].text, "Lock-On: GAME GENIE");
|
||||
else if (config.lock_on == TYPE_AR)
|
||||
sprintf (items[5].text, "Lock-On: ACTION REPLAY");
|
||||
sprintf (items[7].text, "Lock-On: ACTION REPLAY");
|
||||
else if (config.lock_on == TYPE_SK)
|
||||
sprintf (items[5].text, "Lock-On: SONIC&KNUCKLES");
|
||||
sprintf (items[7].text, "Lock-On: SONIC&KNUCKLES");
|
||||
else
|
||||
sprintf (items[5].text, "Lock-On: OFF");
|
||||
sprintf (items[7].text, "Lock-On: OFF");
|
||||
|
||||
sprintf (items[6].text, "Cartridge Swap: %s", config.hot_swap ? "ON":"OFF");
|
||||
sprintf (items[8].text, "Cartridge Swap: %s", config.hot_swap ? "ON":"OFF");
|
||||
|
||||
if (svp)
|
||||
{
|
||||
sprintf (items[7].text, "SVP Cycles: %d", SVP_cycles);
|
||||
m->max_items = 8;
|
||||
sprintf (items[9].text, "SVP Cycles: %d", SVP_cycles);
|
||||
m->max_items = 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
m->max_items = 7;
|
||||
m->max_items = 9;
|
||||
}
|
||||
|
||||
GUI_InitMenu(m);
|
||||
@ -1138,32 +1156,24 @@ static void systemmenu ()
|
||||
{
|
||||
config.system = SYSTEM_SG;
|
||||
sprintf (items[0].text, "Console Hardware: SG-1000");
|
||||
|
||||
/* Force system hardware */
|
||||
system_hw = SYSTEM_SG;
|
||||
}
|
||||
else if (config.system == SYSTEM_SG)
|
||||
{
|
||||
config.system = SYSTEM_MARKIII;
|
||||
sprintf (items[0].text, "Console Hardware: MARK-III");
|
||||
|
||||
/* Force system hardware */
|
||||
system_hw = SYSTEM_MARKIII;
|
||||
}
|
||||
else if (config.system == SYSTEM_MARKIII)
|
||||
{
|
||||
config.system = SYSTEM_SMS;
|
||||
sprintf (items[0].text, "Console Hardware: SMS");
|
||||
|
||||
/* Force system hardware */
|
||||
system_hw = SYSTEM_SMS;
|
||||
}
|
||||
else if (config.system == SYSTEM_SMS)
|
||||
{
|
||||
config.system = SYSTEM_SMS2;
|
||||
sprintf (items[0].text, "Console Hardware: SMS-II");
|
||||
|
||||
/* Force system hardware */
|
||||
system_hw = SYSTEM_SMS2;
|
||||
}
|
||||
else if (config.system == SYSTEM_SMS2)
|
||||
@ -1199,7 +1209,7 @@ static void systemmenu ()
|
||||
}
|
||||
}
|
||||
|
||||
/* restart emulation */
|
||||
/* force hard reset */
|
||||
system_init();
|
||||
system_reset();
|
||||
|
||||
@ -1226,66 +1236,61 @@ static void systemmenu ()
|
||||
|
||||
if (cart.romsize)
|
||||
{
|
||||
/* reset console region */
|
||||
region_autodetect();
|
||||
if (system_hw == SYSTEM_MD)
|
||||
{
|
||||
io_reg[0x00] = 0x20 | region_code | (config.bios & 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
io_reg[0x00] = 0x80 | (region_code >> 1);
|
||||
}
|
||||
|
||||
/* reinitialize audio timings */
|
||||
if (vdp_pal)
|
||||
{
|
||||
audio_init(snd.sample_rate, (config.tv_mode == 0) ? 50.0 : ((config.render || interlaced) ? 50.00 : (1000000.0/19968.0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
audio_init(snd.sample_rate, (config.tv_mode == 1) ? 60.0 : ((config.render || interlaced) ? 59.94 : (1000000.0/16715.0)));
|
||||
}
|
||||
|
||||
/* reintialize VDP */
|
||||
vdp_init();
|
||||
|
||||
/* reintialize VDP Status flag */
|
||||
if (system_hw & SYSTEM_MD)
|
||||
{
|
||||
status = (status & ~1) | vdp_pal;
|
||||
}
|
||||
|
||||
/* reinitialize VC max value */
|
||||
switch (bitmap.viewport.h)
|
||||
{
|
||||
case 192:
|
||||
vc_max = vc_table[0][vdp_pal];
|
||||
break;
|
||||
case 224:
|
||||
vc_max = vc_table[1][vdp_pal];
|
||||
break;
|
||||
case 240:
|
||||
vc_max = vc_table[3][vdp_pal];
|
||||
break;
|
||||
}
|
||||
|
||||
/* reinitialize sound emulation */
|
||||
sound_restore();
|
||||
/* force system reinitialization */
|
||||
reinit = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: /*** BIOS support ***/
|
||||
case 2: /*** Force VDP mode ***/
|
||||
{
|
||||
config.vdp_mode = (config.vdp_mode + 1) % 3;
|
||||
if (config.vdp_mode == 0)
|
||||
sprintf (items[2].text, "VDP Mode: AUTO");
|
||||
else if (config.vdp_mode == 1)
|
||||
sprintf (items[2].text, "VDP Mode: NTSC");
|
||||
else if (config.vdp_mode == 2)
|
||||
sprintf (items[2].text, "VDP Mode: PAL");
|
||||
|
||||
if (cart.romsize)
|
||||
{
|
||||
/* force system reinitialization */
|
||||
reinit = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: /*** Force Master Clock ***/
|
||||
{
|
||||
config.master_clock = (config.master_clock + 1) % 3;
|
||||
if (config.master_clock == 0)
|
||||
sprintf (items[3].text, "System Clock: AUTO");
|
||||
else if (config.master_clock == 1)
|
||||
sprintf (items[3].text, "System Clock: NTSC");
|
||||
else if (config.master_clock == 2)
|
||||
sprintf (items[3].text, "System Clock: PAL");
|
||||
|
||||
if (cart.romsize)
|
||||
{
|
||||
/* force system reinitialization */
|
||||
reinit = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: /*** BIOS support ***/
|
||||
{
|
||||
uint8 temp = config.bios & 3;
|
||||
config.bios &= ~3;
|
||||
if (temp == 0) config.bios |= 3;
|
||||
else if (temp == 3) config.bios |= 1;
|
||||
sprintf (items[2].text, "System Boot: %s", (config.bios & 1) ? ((config.bios & 2) ? "BIOS&CART " : "BIOS ONLY") : "CART");
|
||||
sprintf (items[4].text, "System Boot: %s", (config.bios & 1) ? ((config.bios & 2) ? "BIOS&CART " : "BIOS ONLY") : "CART");
|
||||
if (cart.romsize && ((system_hw == SYSTEM_MD) || (system_hw & SYSTEM_GG) || (system_hw & SYSTEM_SMS)))
|
||||
{
|
||||
/* reset emulation */
|
||||
/* force hard reset */
|
||||
system_init();
|
||||
system_reset();
|
||||
|
||||
@ -1298,18 +1303,19 @@ static void systemmenu ()
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: /*** force DTACK ***/
|
||||
case 5: /*** force DTACK ***/
|
||||
{
|
||||
config.force_dtack ^= 1;
|
||||
sprintf (items[3].text, "System Lockups: %s", config.force_dtack ? "OFF" : "ON");
|
||||
sprintf (items[5].text, "System Lockups: %s", config.force_dtack ? "OFF" : "ON");
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: /*** 68k Address Error ***/
|
||||
case 6: /*** 68k Address Error ***/
|
||||
{
|
||||
config.addr_error ^= 1;
|
||||
if (cart.romsize && ((system_hw & SYSTEM_PBC) == SYSTEM_MD))
|
||||
{
|
||||
/* reinitialize cartridge hardware (UMK3 hack support) */
|
||||
md_cart_init();
|
||||
|
||||
/* restore SRAM */
|
||||
@ -1318,27 +1324,25 @@ static void systemmenu ()
|
||||
slot_autoload(0,config.s_device);
|
||||
}
|
||||
}
|
||||
sprintf (items[4].text, "68k Address Error: %s", config.addr_error ? "ON" : "OFF");
|
||||
sprintf (items[6].text, "68k Address Error: %s", config.addr_error ? "ON" : "OFF");
|
||||
break;
|
||||
}
|
||||
|
||||
case 5: /*** Cart Lock-On ***/
|
||||
case 7: /*** Cart Lock-On ***/
|
||||
{
|
||||
config.lock_on++;
|
||||
if (config.lock_on > TYPE_SK)
|
||||
config.lock_on = 0;
|
||||
config.lock_on = (config.lock_on + 1) % (TYPE_SK + 1);
|
||||
if (config.lock_on == TYPE_GG)
|
||||
sprintf (items[5].text, "Lock-On: GAME GENIE");
|
||||
sprintf (items[7].text, "Lock-On: GAME GENIE");
|
||||
else if (config.lock_on == TYPE_AR)
|
||||
sprintf (items[5].text, "Lock-On: ACTION REPLAY");
|
||||
sprintf (items[7].text, "Lock-On: ACTION REPLAY");
|
||||
else if (config.lock_on == TYPE_SK)
|
||||
sprintf (items[5].text, "Lock-On: SONIC&KNUCKLES");
|
||||
sprintf (items[7].text, "Lock-On: SONIC&KNUCKLES");
|
||||
else
|
||||
sprintf (items[5].text, "Lock-On: OFF");
|
||||
sprintf (items[7].text, "Lock-On: OFF");
|
||||
|
||||
if (cart.romsize && ((system_hw & SYSTEM_PBC) == SYSTEM_MD))
|
||||
{
|
||||
/* restart emulation */
|
||||
/* force hard reset */
|
||||
system_init();
|
||||
system_reset();
|
||||
|
||||
@ -1371,17 +1375,17 @@ static void systemmenu ()
|
||||
break;
|
||||
}
|
||||
|
||||
case 6: /*** Cartridge Hot Swap ***/
|
||||
case 8: /*** Cartridge Hot Swap ***/
|
||||
{
|
||||
config.hot_swap ^= 1;
|
||||
sprintf (items[6].text, "Cartridge Swap: %s", config.hot_swap ? "ON":"OFF");
|
||||
sprintf (items[8].text, "Cartridge Swap: %s", config.hot_swap ? "ON":"OFF");
|
||||
break;
|
||||
}
|
||||
|
||||
case 7: /*** SVP cycles per line ***/
|
||||
case 9: /*** SVP cycles per line ***/
|
||||
{
|
||||
GUI_OptionBox(m,0,"SVP Cycles",(void *)&SVP_cycles,1,1,1500,1);
|
||||
sprintf (items[7].text, "SVP Cycles: %d", SVP_cycles);
|
||||
sprintf (items[9].text, "SVP Cycles: %d", SVP_cycles);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1393,6 +1397,54 @@ static void systemmenu ()
|
||||
}
|
||||
}
|
||||
|
||||
if (reinit)
|
||||
{
|
||||
/* reinitialize console region */
|
||||
region_autodetect();
|
||||
|
||||
/* reinitialize I/O region register */
|
||||
if (system_hw == SYSTEM_MD)
|
||||
{
|
||||
io_reg[0x00] = 0x20 | region_code | (config.bios & 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
io_reg[0x00] = 0x80 | (region_code >> 1);
|
||||
}
|
||||
|
||||
/* reinitialize VDP */
|
||||
if (vdp_pal)
|
||||
{
|
||||
status |= 1;
|
||||
lines_per_frame = 313;
|
||||
}
|
||||
else
|
||||
{
|
||||
status &= ~1;
|
||||
lines_per_frame = 262;
|
||||
}
|
||||
|
||||
/* reinitialize VC max value */
|
||||
switch (bitmap.viewport.h)
|
||||
{
|
||||
case 192:
|
||||
vc_max = vc_table[0][vdp_pal];
|
||||
break;
|
||||
case 224:
|
||||
vc_max = vc_table[1][vdp_pal];
|
||||
break;
|
||||
case 240:
|
||||
vc_max = vc_table[3][vdp_pal];
|
||||
break;
|
||||
}
|
||||
|
||||
/* framerate has changed, reinitialize audio timings */
|
||||
audio_init(snd.sample_rate, get_framerate());
|
||||
|
||||
/* reinitialize sound emulation */
|
||||
sound_restore();
|
||||
}
|
||||
|
||||
GUI_DeleteMenu(m);
|
||||
}
|
||||
|
||||
@ -1401,14 +1453,14 @@ static void systemmenu ()
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifdef HW_RVL
|
||||
#define VI_OFFSET 5
|
||||
#define VI_OFFSET 6
|
||||
static void update_gamma(void)
|
||||
{
|
||||
VIDEO_SetGamma((int)(config.gamma * 10.0));
|
||||
VIDEO_Flush();
|
||||
}
|
||||
#else
|
||||
#define VI_OFFSET 3
|
||||
#define VI_OFFSET 4
|
||||
#endif
|
||||
|
||||
static void videomenu ()
|
||||
@ -1433,11 +1485,16 @@ static void videomenu ()
|
||||
else
|
||||
sprintf (items[1].text, "TV Mode: 50/60HZ");
|
||||
|
||||
sprintf (items[2].text, "GX Bilinear Filter: %s", config.bilinear ? " ON" : "OFF");
|
||||
if (config.vsync)
|
||||
sprintf (items[2].text, "VSYNC: AUTO");
|
||||
else
|
||||
sprintf (items[2].text, "VSYNC: OFF");
|
||||
|
||||
sprintf (items[3].text, "GX Bilinear Filter: %s", config.bilinear ? " ON" : "OFF");
|
||||
|
||||
#ifdef HW_RVL
|
||||
sprintf (items[3].text, "VI Trap Filter: %s", config.trap ? " ON" : "OFF");
|
||||
sprintf (items[4].text, "VI Gamma Correction: %1.1f", config.gamma);
|
||||
sprintf (items[4].text, "VI Trap Filter: %s", config.trap ? " ON" : "OFF");
|
||||
sprintf (items[5].text, "VI Gamma Correction: %1.1f", config.gamma);
|
||||
#endif
|
||||
|
||||
if (config.ntsc == 1)
|
||||
@ -1531,18 +1588,27 @@ static void videomenu ()
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: /*** GX Texture filtering ***/
|
||||
case 2: /*** VSYNC ***/
|
||||
config.vsync ^= 1;
|
||||
if (config.vsync)
|
||||
sprintf (items[2].text, "VSYNC: AUTO");
|
||||
else
|
||||
sprintf (items[2].text, "VSYNC: OFF");
|
||||
reinit = 1;
|
||||
break;
|
||||
|
||||
case 3: /*** GX Texture filtering ***/
|
||||
config.bilinear ^= 1;
|
||||
sprintf (items[2].text, "GX Bilinear Filter: %s", config.bilinear ? " ON" : "OFF");
|
||||
sprintf (items[3].text, "GX Bilinear Filter: %s", config.bilinear ? " ON" : "OFF");
|
||||
break;
|
||||
|
||||
#ifdef HW_RVL
|
||||
case 3: /*** VIDEO Trap filtering ***/
|
||||
case 4: /*** VIDEO Trap filtering ***/
|
||||
config.trap ^= 1;
|
||||
sprintf (items[3].text, "VI Trap Filter: %s", config.trap ? " ON" : "OFF");
|
||||
sprintf (items[4].text, "VI Trap Filter: %s", config.trap ? " ON" : "OFF");
|
||||
break;
|
||||
|
||||
case 4: /*** VIDEO Gamma correction ***/
|
||||
case 5: /*** VIDEO Gamma correction ***/
|
||||
if (cart.romsize)
|
||||
{
|
||||
update_gamma();
|
||||
@ -1561,7 +1627,7 @@ static void videomenu ()
|
||||
m->arrows[1]->state = state[1];
|
||||
m->screenshot = 0;
|
||||
strcpy(m->title,"Video Settings");
|
||||
sprintf (items[4].text, "VI Gamma Correction: %1.1f", config.gamma);
|
||||
sprintf (items[5].text, "VI Gamma Correction: %1.1f", config.gamma);
|
||||
VIDEO_SetGamma(VI_GM_1_0);
|
||||
VIDEO_Flush();
|
||||
}
|
||||
@ -1689,15 +1755,8 @@ static void videomenu ()
|
||||
|
||||
if (cart.romsize && reinit)
|
||||
{
|
||||
/* reinitialize audio timings */
|
||||
if (vdp_pal)
|
||||
{
|
||||
audio_init(snd.sample_rate, (config.tv_mode == 0) ? 50.0 : ((config.render || interlaced) ? 50.00 : (1000000.0/19968.0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
audio_init(snd.sample_rate, (config.tv_mode == 1) ? 60.0 : ((config.render || interlaced) ? 59.94 : (1000000.0/16715.0)));
|
||||
}
|
||||
/* framerate has changed, reinitialize audio timings */
|
||||
audio_init(snd.sample_rate, get_framerate());
|
||||
|
||||
/* reinitialize sound chips */
|
||||
sound_restore();
|
||||
|
@ -39,14 +39,14 @@
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
|
||||
/* DMA soundbuffers (required to be 32-bytes aligned)
|
||||
Length is dimensionned for one frame of emulation (800/808 samples @60hz, 960 samples@50Hz)
|
||||
To prevent audio clashes, we use double buffering technique:
|
||||
one buffer is the active DMA buffer
|
||||
the other one is the current work buffer (updated during frame emulation)
|
||||
We do not need more since frame emulation and DMA operation are synchronized
|
||||
*/
|
||||
u8 soundbuffer[2][3840] ATTRIBUTE_ALIGN(32);
|
||||
u8 soundbuffer[2][SOUND_BUFFER_MAX_SIZE] ATTRIBUTE_ALIGN(32);
|
||||
|
||||
/* Current work soundbuffer */
|
||||
u32 mixbuffer;
|
||||
@ -65,6 +65,15 @@ static u32 Bg_music_ogg_size = 0;
|
||||
/* Audio DMA callback */
|
||||
static void ai_callback(void)
|
||||
{
|
||||
#ifdef LOG_TIMING
|
||||
u64 current = gettime();
|
||||
if (prevtime)
|
||||
{
|
||||
delta_time[frame_cnt] = diff_nsec(prevtime, current);
|
||||
frame_cnt = (frame_cnt + 1) % LOGSIZE;
|
||||
}
|
||||
prevtime = current;
|
||||
#endif
|
||||
frameticker ++;
|
||||
}
|
||||
|
||||
@ -115,8 +124,18 @@ void gx_audio_Shutdown(void)
|
||||
***/
|
||||
void gx_audio_Update(void)
|
||||
{
|
||||
/* retrieve audio samples */
|
||||
/* retrieve audio samples (size must be multiple of 32 bytes) */
|
||||
int size = audio_update() * 4;
|
||||
#ifdef LOG_TIMING
|
||||
if (prevtime && (frame_cnt < LOGSIZE - 1))
|
||||
{
|
||||
delta_samp[frame_cnt + 1] = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta_samp[0] = size;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set next DMA soundbuffer */
|
||||
s16 *sb = (s16 *)(soundbuffer[mixbuffer]);
|
||||
@ -131,10 +150,6 @@ void gx_audio_Update(void)
|
||||
/* Therefore we need to make sure frame emulation is completed before current DMA is */
|
||||
/* completed, either by synchronizing frame emulation with DMA start or by syncing it */
|
||||
/* with Vertical Interrupt and outputing a suitable number of samples per frame. */
|
||||
/* */
|
||||
/* In both cases, audio DMA need to be synchronized with VSYNC and therefore need to */
|
||||
/* be resynchronized (restarted) every time video settings are changed (hopefully, */
|
||||
/* this generally happens while no music is played. */
|
||||
if (!audioStarted)
|
||||
{
|
||||
/* restart audio DMA */
|
||||
@ -165,14 +180,15 @@ void gx_audio_Start(void)
|
||||
AUDIO_RegisterDMACallback(NULL);
|
||||
DSP_Halt();
|
||||
|
||||
/* when TV mode does not match emulated video mode, frame emulation is synchronized with Audio Interface DMA */
|
||||
if (gc_pal != vdp_pal)
|
||||
/* when VSYNC is forced OFF or AUTO with TV mode not matching emulated video mode, emulation is synchronized with Audio Hardware */
|
||||
if (!config.vsync || (config.tv_mode == !vdp_pal))
|
||||
{
|
||||
/* DMA Interrupt callback */
|
||||
AUDIO_RegisterDMACallback(ai_callback);
|
||||
}
|
||||
|
||||
/* reset emulation audio processing */
|
||||
memset(soundbuffer, 0, 2 * 3840);
|
||||
memset(soundbuffer, 0, 2 * SOUND_BUFFER_MAX_SIZE);
|
||||
audioStarted = 0;
|
||||
mixbuffer = 0;
|
||||
}
|
||||
|
@ -40,7 +40,10 @@
|
||||
#ifndef _GC_AUDIO_H_
|
||||
#define _GC_AUDIO_H_
|
||||
|
||||
extern u8 soundbuffer[2][3840];
|
||||
/* Length is dimensionned for at least one frame of emulation */
|
||||
#define SOUND_BUFFER_MAX_SIZE 4096
|
||||
|
||||
extern u8 soundbuffer[2][SOUND_BUFFER_MAX_SIZE];
|
||||
extern u32 mixbuffer;
|
||||
extern u32 audioStarted;
|
||||
|
||||
|
@ -351,6 +351,15 @@ static camera cam = {
|
||||
/* VSYNC callback */
|
||||
static void vi_callback(u32 cnt)
|
||||
{
|
||||
#ifdef LOG_TIMING
|
||||
u64 current = gettime();
|
||||
if (prevtime)
|
||||
{
|
||||
delta_time[frame_cnt] = diff_nsec(prevtime, current);
|
||||
frame_cnt = (frame_cnt + 1) % LOGSIZE;
|
||||
}
|
||||
prevtime = current;
|
||||
#endif
|
||||
frameticker ++;
|
||||
}
|
||||
|
||||
@ -467,80 +476,99 @@ static void gxResetMode(GXRModeObj *tvmode)
|
||||
/* Manage Aspect Ratio */
|
||||
static void gxSetAspectRatio(int *xscale, int *yscale)
|
||||
{
|
||||
/* original aspect ratio */
|
||||
/* the following values have been deducted from comparison with a real 50/60hz Mega Drive */
|
||||
/* Vertical Scaling is disabled by default */
|
||||
*yscale = (bitmap.viewport.h + (2 * bitmap.viewport.y)) / 2;
|
||||
|
||||
/* Original aspect ratio */
|
||||
if (config.aspect)
|
||||
{
|
||||
/* vertical borders */
|
||||
if (config.overscan & 1)
|
||||
/* Adjust vertical scaling when input & output video heights are different */
|
||||
if (vdp_pal && (!gc_pal || config.render))
|
||||
{
|
||||
/* Genesis outputs 288(PAL) or 243(NTSC) lines */
|
||||
/* Wii & Game Cube output 286/574(PAL50) or 240/480 (PAL60 & NTSC) lines */
|
||||
*yscale = vdp_pal + ((gc_pal && !config.render) ? 143 : 120);
|
||||
*yscale = *yscale * VI_MAX_HEIGHT_NTSC / VI_MAX_HEIGHT_PAL;
|
||||
}
|
||||
else
|
||||
else if (!vdp_pal && gc_pal && !config.render)
|
||||
{
|
||||
/* overscan is simulated (black) */
|
||||
*yscale = vheight / 2;
|
||||
|
||||
/* adjust when Genesis & Wii/GC video height does not match */
|
||||
if (vdp_pal && (!gc_pal || config.render))
|
||||
{
|
||||
*yscale = *yscale * 240 / 288;
|
||||
}
|
||||
else if (!vdp_pal && gc_pal && !config.render)
|
||||
{
|
||||
*yscale = *yscale * 288 / 240;
|
||||
}
|
||||
*yscale = *yscale * VI_MAX_HEIGHT_PAL / VI_MAX_HEIGHT_NTSC;
|
||||
}
|
||||
|
||||
/* horizontal borders */
|
||||
/* Horizontal Scaling */
|
||||
/* Wii/NGC pixel clock = 13.5 Mhz */
|
||||
/* "H32" pixel clock = Master Clock / 10 = 5.3693175 Mhz (NTSC) or 5.3203424 (PAL) */
|
||||
/* "H40" pixel clock = Master Clock / 8 = 6,711646875 Mhz (NTSC) or 6,650428 Mhz (PAL) */
|
||||
if (config.overscan & 2)
|
||||
{
|
||||
/* max visible range is ~712 pixels (= 348 'H40' pixels) */
|
||||
*xscale = (reg[12] & 1) ? 356 : 363;
|
||||
/* Horizontal borders are emulated */
|
||||
if (reg[12] & 1)
|
||||
{
|
||||
/* 348 "H40" pixels = 348 * Wii pixel clock / "H40" pixel clock = approx. 700 (NTSC) or 707 (PAL) Wii/NGC pixels */
|
||||
*xscale = (system_clock == MCLOCK_NTSC) ? 350 : 354;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 284 "H32" pixels = 284 * Wii pixel clock / "H40" pixel clock = approx. 714 (NTSC) or 721 (PAL) Wii/NGC pixels */
|
||||
*xscale = (system_clock == MCLOCK_NTSC) ? 357 : 361;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* overscan is simulated (black) */
|
||||
*xscale = (system_hw == SYSTEM_GG) ? 204 : 327;
|
||||
/* Horizontal borders are simulated */
|
||||
if (system_hw == SYSTEM_GG)
|
||||
{
|
||||
/* 160 "H32" pixels = 160 * Wii pixel clock / "H32" pixel clock = approx. 403 Wii/NGC pixels (NTSC only) */
|
||||
*xscale = 202;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 320 "H40" pixels = 256 "H32" pixels = 256 * Wii pixel clock / "H32" pixel clock = approx. 644 (NTSC) or 650 (PAL) Wii/NGC pixels */
|
||||
*xscale = (system_clock == MCLOCK_NTSC) ? 322 : 325;
|
||||
}
|
||||
}
|
||||
|
||||
/* aspect correction for 16:9 screens */
|
||||
/* Aspect correction for widescreen TV */
|
||||
if (config.aspect & 2)
|
||||
{
|
||||
/* Keep 4:3 aspect ratio on 16:9 output */
|
||||
*xscale = (*xscale * 3) / 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* manual aspect ratio (default is full screen & not scaled if possible) */
|
||||
/* Manual aspect ratio */
|
||||
else
|
||||
{
|
||||
/* vertical borders */
|
||||
if (config.overscan & 1)
|
||||
/* By default, disable horizontal scaling */
|
||||
*xscale = bitmap.viewport.w + (2 * bitmap.viewport.x);
|
||||
|
||||
/* Keep original aspect ratio in H32 modes */
|
||||
if (!(reg[12] & 1))
|
||||
{
|
||||
*yscale = (gc_pal && !config.render) ? (vdp_pal ? (268*144 / bitmap.viewport.h):143) : (vdp_pal ? (224*144 / bitmap.viewport.h):120);
|
||||
*xscale = (*xscale * 320) / 256;
|
||||
}
|
||||
else
|
||||
|
||||
/* Game Gear specific: if borders are disabled, upscale to fullscreen */
|
||||
if (system_hw == SYSTEM_GG)
|
||||
{
|
||||
*yscale = (vheight == 192) ? 96 : 112;
|
||||
if (gc_pal && !config.render)
|
||||
if (!(config.overscan & 1))
|
||||
{
|
||||
*yscale = (*yscale * 134) / 112;
|
||||
/* Active area height = approx. 224 non-interlaced lines (60hz) */
|
||||
*yscale = 112;
|
||||
}
|
||||
|
||||
if (!(config.overscan & 2))
|
||||
{
|
||||
/* Active area width = approx. 640 pixels */
|
||||
*xscale = 320;
|
||||
}
|
||||
}
|
||||
|
||||
/* horizontal borders */
|
||||
if (config.overscan & 2)
|
||||
/* By default, keep NTSC aspect ratio */
|
||||
if (gc_pal && !config.render)
|
||||
{
|
||||
*xscale = (reg[12] & 1) ? 348 : 355;
|
||||
}
|
||||
else
|
||||
{
|
||||
*xscale = 320;
|
||||
/* Upscale PAL output */
|
||||
*yscale = *yscale * VI_MAX_HEIGHT_PAL / VI_MAX_HEIGHT_NTSC;
|
||||
}
|
||||
|
||||
/* add user scaling */
|
||||
/* Add user scaling */
|
||||
*xscale += config.xscale;
|
||||
*yscale += config.yscale;
|
||||
}
|
||||
@ -1387,10 +1415,10 @@ void gx_video_Start(void)
|
||||
gc_pal = 0;
|
||||
}
|
||||
|
||||
/* VSYNC callbacks */
|
||||
/* If TV mode matches emulated video mode, frame emulation is synchronized with Video Interrupt */
|
||||
if (gc_pal == vdp_pal)
|
||||
/* When VSYNC is forced ON or AUTO with TV mode matching emulated video mode, emulation is synchronized with video hardware */
|
||||
if ((config.vsync == 1) && (gc_pal == vdp_pal))
|
||||
{
|
||||
/* VSYNC callback */
|
||||
VIDEO_SetPreRetraceCallback(vi_callback);
|
||||
VIDEO_Flush();
|
||||
}
|
||||
@ -1517,11 +1545,10 @@ void gx_video_Update(void)
|
||||
if (config.ntsc)
|
||||
{
|
||||
vwidth = (reg[12] & 1) ? MD_NTSC_OUT_WIDTH(vwidth) : SMS_NTSC_OUT_WIDTH(vwidth);
|
||||
}
|
||||
|
||||
/* texels size must be multiple of 4 */
|
||||
vwidth = (vwidth >> 2) << 2;
|
||||
vheight = (vheight >> 2) << 2;
|
||||
/* texel width must remain multiple of 4 */
|
||||
vwidth = (vwidth >> 2) << 2;
|
||||
}
|
||||
|
||||
/* initialize texture object */
|
||||
GXTexObj texobj;
|
||||
@ -1619,7 +1646,7 @@ void gx_video_Update(void)
|
||||
VIDEO_WaitVSync();
|
||||
}
|
||||
|
||||
/* audio & video resynchronization */
|
||||
/* Audio DMA need to be resynchronized with VSYNC */
|
||||
audioStarted = 0;
|
||||
}
|
||||
}
|
||||
@ -1647,29 +1674,21 @@ void gx_video_Init(void)
|
||||
TV60hz_240p.viTVMode = VI_TVMODE_EURGB60_DS;
|
||||
TV60hz_240i.viTVMode = VI_TVMODE_EURGB60_INT;
|
||||
TV60hz_480i.viTVMode = VI_TVMODE_EURGB60_INT;
|
||||
config.tv_mode = 1;
|
||||
|
||||
/* use harwdare vertical scaling to fill screen */
|
||||
/* force harwdare vertical scaling to fill screen */
|
||||
vmode = &TVPal574IntDfScale;
|
||||
break;
|
||||
|
||||
case VI_NTSC: /* 480 lines (NTSC 60hz) */
|
||||
TV60hz_240p.viTVMode = VI_TVMODE_NTSC_DS;
|
||||
TV60hz_240i.viTVMode = VI_TVMODE_NTSC_INT;
|
||||
TV60hz_480i.viTVMode = VI_TVMODE_NTSC_INT;
|
||||
config.tv_mode = 0;
|
||||
default: /* 480 lines (NTSC, MPAL or PAL 60Hz) */
|
||||
|
||||
#ifndef HW_RVL
|
||||
/* force 480p on NTSC GameCube if the Component Cable is present */
|
||||
if (VIDEO_HaveComponentCable()) vmode = &TVNtsc480Prog;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default: /* 480 lines (PAL 60Hz) */
|
||||
TV60hz_240p.viTVMode = VI_TVMODE(vmode->viTVMode >> 2, VI_NON_INTERLACE);
|
||||
TV60hz_240i.viTVMode = VI_TVMODE(vmode->viTVMode >> 2, VI_INTERLACE);
|
||||
TV60hz_480i.viTVMode = VI_TVMODE(vmode->viTVMode >> 2, VI_INTERLACE);
|
||||
config.tv_mode = 2;
|
||||
|
||||
#ifndef HW_RVL
|
||||
/* force 480p on GameCube if Component Cable is detected */
|
||||
if (VIDEO_HaveComponentCable()) vmode = &TVNtsc480Prog;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
155
source/gx/main.c
155
source/gx/main.c
@ -64,6 +64,13 @@ u32 Shutdown = 0;
|
||||
u32 ConfigRequested = 1;
|
||||
u32 frameticker;
|
||||
|
||||
#ifdef LOG_TIMING
|
||||
u64 prevtime;
|
||||
u32 frame_cnt;
|
||||
u32 delta_time[LOGSIZE];
|
||||
u32 delta_samp[LOGSIZE];
|
||||
#endif
|
||||
|
||||
#ifdef HW_RVL
|
||||
|
||||
/****************************************************************************
|
||||
@ -211,14 +218,7 @@ static void run_emulation(void)
|
||||
if (!config.render && (gc_pal == vdp_pal))
|
||||
{
|
||||
/* framerate has changed, reinitialize audio timings */
|
||||
if (vdp_pal)
|
||||
{
|
||||
audio_init(SAMPLERATE_48KHZ, interlaced ? 50.00 : (1000000.0/19968.0));
|
||||
}
|
||||
else
|
||||
{
|
||||
audio_init(SAMPLERATE_48KHZ, interlaced ? 59.94 : (1000000.0/16715.0));
|
||||
}
|
||||
audio_init(SAMPLERATE_48KHZ, get_framerate());
|
||||
|
||||
/* reinitialize sound chips */
|
||||
sound_restore();
|
||||
@ -250,18 +250,11 @@ static void run_emulation(void)
|
||||
/* check interlaced mode change */
|
||||
if (bitmap.viewport.changed & 4)
|
||||
{
|
||||
/* VSYNC "original" mode */
|
||||
if (!config.render && (gc_pal == vdp_pal))
|
||||
/* "original" mode */
|
||||
if (!config.render)
|
||||
{
|
||||
/* framerate has changed, reinitialize audio timings */
|
||||
if (vdp_pal)
|
||||
{
|
||||
audio_init(SAMPLERATE_48KHZ, interlaced ? 50.00 : (1000000.0/19968.0));
|
||||
}
|
||||
else
|
||||
{
|
||||
audio_init(SAMPLERATE_48KHZ, interlaced ? 59.94 : (1000000.0/16715.0));
|
||||
}
|
||||
audio_init(SAMPLERATE_48KHZ, get_framerate());
|
||||
|
||||
/* reinitialize sound chips */
|
||||
sound_restore();
|
||||
@ -280,6 +273,87 @@ static void run_emulation(void)
|
||||
gx_audio_Stop();
|
||||
gx_video_Stop();
|
||||
|
||||
#ifdef LOG_TIMING
|
||||
if (cart.romsize)
|
||||
{
|
||||
FILE *f;
|
||||
char filename[64];
|
||||
|
||||
memset(filename, 0, 64);
|
||||
strcpy(filename,"timings-");
|
||||
if (!config.vsync || (config.tv_mode == !vdp_pal))
|
||||
{
|
||||
strcat(filename,"no_");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gc_pal)
|
||||
{
|
||||
strcat(filename,"50hz_");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat(filename,"60hz_");
|
||||
}
|
||||
}
|
||||
strcat(filename,"vsync-");
|
||||
if (vdp_pal)
|
||||
{
|
||||
strcat(filename,"pal-");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat(filename,"ntsc-");
|
||||
}
|
||||
if (config.render == 2)
|
||||
{
|
||||
strcat(filename,"prog.txt");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!config.render && !interlaced)
|
||||
{
|
||||
strcat(filename,"no_");
|
||||
}
|
||||
strcat(filename,"int.txt");
|
||||
}
|
||||
|
||||
f = fopen(filename,"a");
|
||||
if (f != NULL)
|
||||
{
|
||||
int i;
|
||||
u32 min,max;
|
||||
double total = 0;
|
||||
double nsamples = 0;
|
||||
|
||||
if (delta_time[LOGSIZE - 1] != 0)
|
||||
{
|
||||
frame_cnt = LOGSIZE;
|
||||
}
|
||||
|
||||
min = max = delta_time[0];
|
||||
|
||||
for (i=0; i<frame_cnt; i++)
|
||||
{
|
||||
fprintf(f,"%d ns - %d samples (%5.8f samples/sec)\n", delta_time[i], delta_samp[i], 1000000000.0*(double)delta_samp[i]/(double)delta_time[i]/4.0);
|
||||
total += delta_time[i];
|
||||
nsamples += delta_samp[i] / 4.0;
|
||||
if (min > delta_time[i]) min = delta_time[i];
|
||||
if (max < delta_time[i]) max = delta_time[i];
|
||||
}
|
||||
fprintf(f,"\n");
|
||||
fprintf(f,"min = %d ns\n", min);
|
||||
fprintf(f,"max = %d ns\n", max);
|
||||
fprintf(f,"avg = %8.5f ns (%5.8f samples/sec, %5.8f samples/frame)\n\n\n", total/(double)i, nsamples/total*1000000000.0, nsamples/(double)i);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
memset(delta_time,0,LOGSIZE);
|
||||
memset(delta_samp,0,LOGSIZE);
|
||||
frame_cnt = prevtime = 0;
|
||||
#endif
|
||||
|
||||
/* show menu */
|
||||
ConfigRequested = 0;
|
||||
mainmenu();
|
||||
@ -291,6 +365,35 @@ static void run_emulation(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************************************************************************
|
||||
Output exact framerate (used for sound chips emulation -- see sound.c)
|
||||
*********************************************************************************************************************************************************/
|
||||
double get_framerate(void)
|
||||
{
|
||||
/* VSYNC is forced OFF or AUTO with TV mode not matching emulated video mode: emulation is synchronized with audio hardware (DMA interrupt) */
|
||||
if (!config.vsync || (config.tv_mode == !vdp_pal))
|
||||
{
|
||||
/* emulator will use original VDP framerate, which (theorically) provides more accurate frequencies but occasional video desynchronization */
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/* VSYNC is forced ON or AUTO with TV mode matching emulated video mode: emulation is synchronized with video hardware (VSYNC) */
|
||||
/* emulator use exact output framerate for perfect video synchronization and (theorically) no sound skipping */
|
||||
if (vdp_pal)
|
||||
{
|
||||
/* 288p -> 13500000 pixels/sec, 864 pixels/line, 312 lines/field -> fps = 13500000/864/312 = 50.08 hz */
|
||||
/* 288i,576i -> 13500000 pixels/sec, 864 pixels/line, 312.5 lines/field (two fields = one frame = 625 lines) -> fps = 13500000/864/312.5 = 50.00 hz */
|
||||
return (config.render || interlaced) ? (27000000.0/864.0/625.0) : (13500000.0/864.0/312.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 240p -> 13500000 pixels/sec, 858 pixels/line, 263 lines/field -> fps = 13500000/858/263 = 59.83 hz */
|
||||
/* 240i,480i -> 13500000 pixels/sec, 858 pixels/line, 262.5 lines/field (two fields = one frame = 525 lines) -> fps = 13500000/858/262.5 = 59.94 hz */
|
||||
/* 480p -> 27000000 pixels/sec, 858 pixels/line, 525 lines/field -> fps = 27000000/858/525 = 59.94 hz */
|
||||
return (config.render || interlaced) ? (27000000.0/858.0/525.0) : (13500000.0/858.0/263.0);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************
|
||||
Restart emulation when loading a new game
|
||||
********************************************/
|
||||
@ -315,18 +418,8 @@ void reloadrom(void)
|
||||
{
|
||||
/* Initialize audio emulation */
|
||||
/* To prevent any sound skipping, sound chips must run at the exact same speed as the rest of emulation (see sound.c) */
|
||||
/* When TV output mode matches emulated video mode, we use video hardware interrupt (VSYNC) and exact framerates for perfect synchronization */
|
||||
/* In 60Hz TV modes, Wii & GC framerates have been measured to be 59.94 (interlaced or progressive) and ~59.825 fps (non-interlaced) */
|
||||
/* In 50Hz TV modes, Wii & GC framerates have been measured to be 50.00 (interlaced) and ~50.845 fps (non-interlaced) */
|
||||
/* When modes does not match, emulation is synchronized with audio hardware interrupt (DMA) and we use default framerates (50Hz for PAL, 60Hz for NTSC). */
|
||||
if (vdp_pal)
|
||||
{
|
||||
audio_init(SAMPLERATE_48KHZ, (config.tv_mode == 0) ? 50.0 : (config.render ? 50.00 : (1000000.0/19968.0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
audio_init(SAMPLERATE_48KHZ, (config.tv_mode == 1) ? 60.0 : (config.render ? 59.94 : (1000000.0/16715.0)));
|
||||
}
|
||||
interlaced = 0;
|
||||
audio_init(SAMPLERATE_48KHZ, get_framerate());
|
||||
|
||||
/* Switch virtual system on */
|
||||
system_init();
|
||||
@ -407,7 +500,7 @@ int main (int argc, char *argv[])
|
||||
/* initialize video engine */
|
||||
gx_video_Init();
|
||||
|
||||
#ifdef HW_DOL
|
||||
#ifndef HW_RVL
|
||||
/* initialize DVD interface */
|
||||
DVD_Init();
|
||||
#endif
|
||||
|
@ -44,10 +44,20 @@
|
||||
|
||||
/* globals */
|
||||
extern void legal(void);
|
||||
extern double get_framerate(void);
|
||||
extern void reloadrom(void);
|
||||
extern void shutdown(void);
|
||||
extern u32 frameticker;
|
||||
extern u32 Shutdown;
|
||||
extern u32 ConfigRequested;
|
||||
|
||||
#ifdef LOG_TIMING
|
||||
#include <ogc/lwp_watchdog.h>
|
||||
#define LOGSIZE 2000
|
||||
extern u64 prevtime;
|
||||
extern u32 frame_cnt;
|
||||
extern u32 delta_time[LOGSIZE];
|
||||
extern u32 delta_samp[LOGSIZE];
|
||||
#endif
|
||||
|
||||
#endif /* _OSD_H_ */
|
||||
|
@ -51,7 +51,7 @@ void activator_reset(int index)
|
||||
activator[index].Counter = 0;
|
||||
}
|
||||
|
||||
static __inline__ unsigned char activator_read(int port)
|
||||
INLINE unsigned char activator_read(int port)
|
||||
{
|
||||
/* IR sensors 1-16 data (active low) */
|
||||
uint16 data = ~input.pad[port << 2];
|
||||
@ -85,7 +85,7 @@ static __inline__ unsigned char activator_read(int port)
|
||||
return temp;
|
||||
}
|
||||
|
||||
static __inline__ void activator_write(int index, unsigned char data, unsigned char mask)
|
||||
INLINE void activator_write(int index, unsigned char data, unsigned char mask)
|
||||
{
|
||||
/* update bits set as output only */
|
||||
data = (activator[index].State & ~mask) | (data & mask);
|
||||
|
@ -71,7 +71,7 @@ void gamepad_refresh(int port)
|
||||
}
|
||||
}
|
||||
|
||||
static __inline__ unsigned char gamepad_read(int port)
|
||||
INLINE unsigned char gamepad_read(int port)
|
||||
{
|
||||
/* bit 7 is latched, returns current TH state */
|
||||
unsigned int data = (gamepad[port].State & 0x40) | 0x3F;
|
||||
@ -142,7 +142,7 @@ static __inline__ unsigned char gamepad_read(int port)
|
||||
return data;
|
||||
}
|
||||
|
||||
static __inline__ void gamepad_write(int port, unsigned char data, unsigned char mask)
|
||||
INLINE void gamepad_write(int port, unsigned char data, unsigned char mask)
|
||||
{
|
||||
/* update bits set as output only */
|
||||
data = (gamepad[port].State & ~mask) | (data & mask);
|
||||
|
@ -140,7 +140,7 @@ void lightgun_refresh(int port)
|
||||
/* Sega Phaser */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
static __inline__ unsigned char phaser_read(int port)
|
||||
INLINE unsigned char phaser_read(int port)
|
||||
{
|
||||
/* TL returns TRIGGER (INPUT_A) button status (active low) */
|
||||
unsigned char temp = ~((input.pad[port] >> 2) & 0x10);
|
||||
|
@ -49,7 +49,7 @@ void paddle_reset(int index)
|
||||
paddle[index].State = 0x40;
|
||||
}
|
||||
|
||||
static __inline__ unsigned char paddle_read(int port)
|
||||
INLINE unsigned char paddle_read(int port)
|
||||
{
|
||||
/* FIRE button status (active low) */
|
||||
unsigned char temp = ~(input.pad[port] & 0x10);
|
||||
@ -83,7 +83,7 @@ static __inline__ unsigned char paddle_read(int port)
|
||||
return temp;
|
||||
}
|
||||
|
||||
static __inline__ void paddle_write(int index, unsigned char data, unsigned char mask)
|
||||
INLINE void paddle_write(int index, unsigned char data, unsigned char mask)
|
||||
{
|
||||
/* update bits set as output only */
|
||||
paddle[index].State = (paddle[index].State & ~mask) | (data & mask);
|
||||
|
@ -52,7 +52,7 @@ void sportspad_reset(int index)
|
||||
sportspad[index].Counter = 0;
|
||||
}
|
||||
|
||||
static __inline__ unsigned char sportspad_read(int port)
|
||||
INLINE unsigned char sportspad_read(int port)
|
||||
{
|
||||
/* Buttons 1(B) & 2(C) status (active low) */
|
||||
unsigned char temp = ~(input.pad[port] & 0x30);
|
||||
@ -98,7 +98,7 @@ static __inline__ unsigned char sportspad_read(int port)
|
||||
return temp;
|
||||
}
|
||||
|
||||
static __inline__ void sportspad_write(int index, unsigned char data, unsigned char mask)
|
||||
INLINE void sportspad_write(int index, unsigned char data, unsigned char mask)
|
||||
{
|
||||
/* update bits set as output only */
|
||||
data = (sportspad[index].State & ~mask) | (data & mask);
|
||||
|
@ -80,7 +80,7 @@ void teamplayer_reset(int port)
|
||||
teamplayer[port].Counter = 0;
|
||||
}
|
||||
|
||||
static __inline__ unsigned int teamplayer_read(int port)
|
||||
INLINE unsigned int teamplayer_read(int port)
|
||||
{
|
||||
unsigned int counter = teamplayer[port].Counter;
|
||||
|
||||
@ -131,7 +131,7 @@ static __inline__ unsigned int teamplayer_read(int port)
|
||||
}
|
||||
}
|
||||
|
||||
static __inline__ void teamplayer_write(int port, unsigned char data, unsigned char mask)
|
||||
INLINE void teamplayer_write(int port, unsigned char data, unsigned char mask)
|
||||
{
|
||||
/* update bits set as output only */
|
||||
unsigned int state = (teamplayer[port].State & ~mask) | (data & mask);
|
||||
|
@ -593,14 +593,25 @@ void region_autodetect(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* forced console region */
|
||||
/* force console region if requested */
|
||||
if (config.region_detect == 1) region_code = REGION_USA;
|
||||
else if (config.region_detect == 2) region_code = REGION_EUROPE;
|
||||
else if (config.region_detect == 3) region_code = REGION_JAPAN_NTSC;
|
||||
else if (config.region_detect == 4) region_code = REGION_JAPAN_PAL;
|
||||
|
||||
/* PAL/NTSC timings */
|
||||
/* autodetect PAL/NTSC timings */
|
||||
vdp_pal = (region_code >> 6) & 0x01;
|
||||
|
||||
/* autodetect PAL/NTSC master clock */
|
||||
system_clock = vdp_pal ? MCLOCK_PAL : MCLOCK_NTSC;
|
||||
|
||||
/* force PAL/NTSC timings if requested */
|
||||
if (config.vdp_mode == 1) vdp_pal = 0;
|
||||
else if (config.vdp_mode == 2) vdp_pal = 1;
|
||||
|
||||
/* force PAL/NTSC master clock if requested */
|
||||
if (config.master_clock == 1) system_clock = MCLOCK_NTSC;
|
||||
else if (config.master_clock == 2) system_clock = MCLOCK_PAL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
||||
|
||||
/* Import the configuration for this build */
|
||||
#include "m68kconf.h"
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================ GENERAL DEFINES =========================== */
|
||||
@ -122,8 +122,6 @@ typedef enum
|
||||
/* ====================== FUNCTIONS CALLED BY THE CPU ===================== */
|
||||
/* ======================================================================== */
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
/* 68k memory map structure */
|
||||
typedef struct
|
||||
{
|
||||
|
@ -121,16 +121,6 @@
|
||||
#define M68K_USE_64_BIT OPT_OFF
|
||||
|
||||
|
||||
/* Set to your compiler's static inline keyword to enable it, or
|
||||
* set it to blank to disable it.
|
||||
* If you define INLINE in the makefile, it will override this value.
|
||||
* NOTE: not enabling inline functions will SEVERELY slow down emulation.
|
||||
*/
|
||||
#ifndef INLINE
|
||||
#define INLINE static __inline__
|
||||
#endif /* INLINE */
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================== END OF FILE ============================= */
|
||||
/* ======================================================================== */
|
||||
|
@ -32,5 +32,18 @@
|
||||
#define WRITE_WORD_LONG(BASE, ADDR, VAL) *(uint32 *)((BASE) + (ADDR)) = VAL & 0xffffffff
|
||||
#endif
|
||||
|
||||
/* C89 compatibility */
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846264338327f
|
||||
#endif /* M_PI */
|
||||
|
||||
/* Set to your compiler's static inline keyword to enable it, or
|
||||
* set it to blank to disable it.
|
||||
* If you define INLINE in the makefile, it will override this value.
|
||||
* NOTE: not enabling inline functions will SEVERELY slow down emulation.
|
||||
*/
|
||||
#ifndef INLINE
|
||||
#define INLINE static __inline__
|
||||
#endif /* INLINE */
|
||||
|
||||
#endif /* _MACROS_H_ */
|
||||
|
@ -47,14 +47,14 @@
|
||||
/* machine lock up. */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
static __inline__ void z80_unused_w(unsigned int address, unsigned char data)
|
||||
INLINE void z80_unused_w(unsigned int address, unsigned char data)
|
||||
{
|
||||
#ifdef LOGERROR
|
||||
error("Z80 unused write %04X = %02X (%x)\n", address, data, Z80.pc.w.l);
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline__ unsigned char z80_unused_r(unsigned int address)
|
||||
INLINE unsigned char z80_unused_r(unsigned int address)
|
||||
{
|
||||
#ifdef LOGERROR
|
||||
error("Z80 unused read %04X (%x)\n", address, Z80.pc.w.l);
|
||||
@ -62,7 +62,7 @@ static __inline__ unsigned char z80_unused_r(unsigned int address)
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
static __inline__ void z80_lockup_w(unsigned int address, unsigned char data)
|
||||
INLINE void z80_lockup_w(unsigned int address, unsigned char data)
|
||||
{
|
||||
#ifdef LOGERROR
|
||||
error("Z80 lockup write %04X = %02X (%x)\n", address, data, Z80.pc.w.l);
|
||||
@ -74,7 +74,7 @@ static __inline__ void z80_lockup_w(unsigned int address, unsigned char data)
|
||||
}
|
||||
}
|
||||
|
||||
static __inline__ unsigned char z80_lockup_r(unsigned int address)
|
||||
INLINE unsigned char z80_lockup_r(unsigned int address)
|
||||
{
|
||||
#ifdef LOGERROR
|
||||
error("Z80 lockup read %04X (%x)\n", address, Z80.pc.w.l);
|
||||
|
@ -2,6 +2,8 @@
|
||||
#define _SHARED_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "types.h"
|
||||
|
@ -15,14 +15,14 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
/* C Conversion by Eke-Eke for use in Genesis Plus GX (2009). */
|
||||
|
||||
#include "Fir_Resampler.h"
|
||||
#include "shared.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "Fir_Resampler.h"
|
||||
#include "macros.h"
|
||||
|
||||
/* sound buffer */
|
||||
static sample_t *buffer = NULL;
|
||||
static int buffer_size = 0;
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "eq.h"
|
||||
#include "types.h"
|
||||
#include "macros.h"
|
||||
|
||||
|
||||
/* -----------
|
||||
|
@ -52,7 +52,7 @@ static void (*YM_Update)(int *buffer, int length);
|
||||
static void (*YM_Write)(unsigned int a, unsigned int v);
|
||||
|
||||
/* Run FM chip for required M-cycles */
|
||||
static __inline__ void fm_update(unsigned int cycles)
|
||||
INLINE void fm_update(unsigned int cycles)
|
||||
{
|
||||
if (cycles > fm_cycles_count)
|
||||
{
|
||||
@ -82,7 +82,7 @@ static __inline__ void fm_update(unsigned int cycles)
|
||||
}
|
||||
|
||||
/* Run PSG chip for required M-cycles */
|
||||
static __inline__ void psg_update(unsigned int cycles)
|
||||
INLINE void psg_update(unsigned int cycles)
|
||||
{
|
||||
if (cycles > psg_cycles_count)
|
||||
{
|
||||
@ -103,25 +103,29 @@ void sound_init(void)
|
||||
{
|
||||
/* Number of M-cycles executed per second. */
|
||||
/* */
|
||||
/* The original Genesis would run exactly 53693175 M-cycles (53203424 for PAL), with */
|
||||
/* All emulated chips are kept in sync by using a common oscillator (MCLOCK) */
|
||||
/* */
|
||||
/* The original console would run exactly 53693175 M-cycles (53203424 for PAL), with */
|
||||
/* 3420 M-cycles per line and 262 (313 for PAL) lines per frame, which gives an exact */
|
||||
/* framerate of 59.92 (49.70 for PAL) fps. */
|
||||
/* */
|
||||
/* On some systems, the output framerate is not exactly 60 or 50 fps because we need */
|
||||
/* 100% smooth video and therefore frame emulation is synchronized with VSYNC, which */
|
||||
/* period is never exactly 1/60 or 1/50 seconds. */
|
||||
/* Since audio samples are generated at the end of the frame, to prevent audio skipping */
|
||||
/* or lag between emulated frames, number of samples rendered per frame must be set to */
|
||||
/* output samplerate (number of samples played per second) divided by output framerate */
|
||||
/* (number of frames emulated per seconds). */
|
||||
/* */
|
||||
/* For optimal sound rendering, input samplerate (number of samples rendered per frame) */
|
||||
/* is the exact output samplerate (number of samples played per second) divided by the */
|
||||
/* exact output framerate (number of frames emulated per seconds). */
|
||||
/* On some systems, we may want to achieve 100% smooth video rendering by synchronizing */
|
||||
/* frame emulation with VSYNC, which frequency is generally not exactly those values. */
|
||||
/* In that case, number of frames emulated per seconds is the same as the number of */
|
||||
/* frames rendered per seconds by the host system video hardware. */
|
||||
/* */
|
||||
/* This ensure there is no audio skipping or lag between emulated frames, while keeping */
|
||||
/* accurate timings for sound chips execution & synchronization. */
|
||||
/* When no framerate is specified, base clock is original master clock value. */
|
||||
/* Otherwise, it is based on the output framerate. */
|
||||
/* */
|
||||
double mclk = MCYCLES_PER_LINE * lines_per_frame * snd.frame_rate;
|
||||
double mclk = snd.frame_rate ? (MCYCLES_PER_LINE * lines_per_frame * snd.frame_rate) : system_clock;
|
||||
|
||||
/* For better accuracy, sound chips run in synchronization with 68k and Z80 cpus */
|
||||
/* These values give the exact number of M-cycles between 2 rendered samples. */
|
||||
/* These values give the exact number of M-cycles executed per rendered samples. */
|
||||
/* we use 21.11 fixed point precision (max. mcycle value is 3420*313 i.e 21 bits max) */
|
||||
psg_cycles_ratio = (unsigned int)(mclk / (double) snd.sample_rate * 2048.0);
|
||||
fm_cycles_ratio = psg_cycles_ratio;
|
||||
@ -129,7 +133,7 @@ void sound_init(void)
|
||||
psg_cycles_count = 0;
|
||||
|
||||
/* Initialize core emulation (input clock based on input frequency for 100% accuracy) */
|
||||
/* By default, both chips are running at the output frequency. */
|
||||
/* By default, both PSG & FM chips are running at the output frequency. */
|
||||
SN76489_Init(mclk/15.0,snd.sample_rate);
|
||||
|
||||
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||
@ -166,8 +170,9 @@ void sound_init(void)
|
||||
}
|
||||
|
||||
#ifdef LOGSOUND
|
||||
error("%d mcycles per PSG samples\n", psg_cycles_ratio);
|
||||
error("%d mcycles per FM samples\n", fm_cycles_ratio);
|
||||
error("%f mcycles per second\n", mclk);
|
||||
error("%d mcycles per PSG sample\n", psg_cycles_ratio);
|
||||
error("%d mcycles per FM sample\n", fm_cycles_ratio);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -27,13 +27,8 @@ to do:
|
||||
|
||||
/** EkeEke (2011): removed multiple chips support, cleaned code & added FM board interface for Genesis Plus GX **/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
/* compiler dependence */
|
||||
#define INLINE static __inline__
|
||||
|
||||
#define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */
|
||||
#define EG_SH 16 /* 16.16 fixed point (EG timing) */
|
||||
#define LFO_SH 24 /* 8.24 fixed point (LFO calculations) */
|
||||
|
@ -125,19 +125,8 @@
|
||||
/* YM2610B : PSG:3ch FM:6ch ADPCM(18.5KHz):6ch DeltaT ADPCM:1ch */
|
||||
/************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
/* compiler dependence */
|
||||
#ifndef INLINE
|
||||
#define INLINE static __inline__
|
||||
#endif
|
||||
|
||||
/* globals */
|
||||
#define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */
|
||||
#define EG_SH 16 /* 16.16 fixed point (envelope generator timing) */
|
||||
|
@ -49,8 +49,9 @@ t_snd snd;
|
||||
uint32 mcycles_vdp;
|
||||
uint32 mcycles_z80;
|
||||
uint32 mcycles_68k;
|
||||
int16 SVP_cycles = 800;
|
||||
uint8 system_hw;
|
||||
uint32 system_clock;
|
||||
int16 SVP_cycles = 800;
|
||||
|
||||
static uint8 pause_b;
|
||||
static EQSTATE eq;
|
||||
@ -60,7 +61,7 @@ static int32 llp,rrp;
|
||||
* Audio subsystem
|
||||
****************************************************************/
|
||||
|
||||
int audio_init(int samplerate, float framerate)
|
||||
int audio_init(int samplerate, double framerate)
|
||||
{
|
||||
/* Shutdown first */
|
||||
audio_shutdown();
|
||||
@ -72,8 +73,25 @@ int audio_init(int samplerate, float framerate)
|
||||
snd.sample_rate = samplerate;
|
||||
snd.frame_rate = framerate;
|
||||
|
||||
/* Calculate the sound buffer size (for one frame) */
|
||||
snd.buffer_size = (int)(samplerate / framerate) + 32;
|
||||
/* If no framerate is specified, assume emulator is running at the original frequency */
|
||||
if (!framerate)
|
||||
{
|
||||
if (vdp_pal)
|
||||
{
|
||||
/* PAL mode -> MCLK cycles/sec, 3420 cycles/line, 313 lines/field */
|
||||
/* fps = MCLK/3420/313 = 49.70 hz (PAL console) or 50.16 hz (NTSC console w/ 50 hz switch) */
|
||||
framerate = (double)system_clock / (double)MCYCLES_PER_LINE / 313.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* NTSC mode -> MCLK cycles/sec, 3420 cycles/line, 262 lines/field */
|
||||
/* fps = MCLK/3420/262 = 59.92 hz (NTSC console) or 59.38 hz (PAL console w/ 60 hz switch) */
|
||||
framerate = (double)system_clock / (double)MCYCLES_PER_LINE / 262.0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sound buffer maximal size (for at least one frame) */
|
||||
snd.buffer_size = (int)((double)samplerate / framerate) + 32;
|
||||
|
||||
/* SN76489 stream buffer */
|
||||
snd.psg.buffer = (int16 *) malloc(snd.buffer_size * sizeof(int16));
|
||||
|
@ -53,6 +53,10 @@
|
||||
#define SYSTEM_PBC 0x81
|
||||
#define SYSTEM_PICO 0x82
|
||||
|
||||
/* NTSC & PAL Master Clock frequencies */
|
||||
#define MCLOCK_NTSC 53693175
|
||||
#define MCLOCK_PAL 53203424
|
||||
|
||||
/* Number of M-Cycles executed per line */
|
||||
#define MCYCLES_PER_LINE 3420
|
||||
|
||||
@ -81,7 +85,7 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
int sample_rate; /* Output Sample rate (8000-48000) */
|
||||
float frame_rate; /* Output Frame rate (usually 50 or 60 frames per second) */
|
||||
double frame_rate; /* Output Frame rate (usually 50 or 60 frames per second) */
|
||||
int enabled; /* 1= sound emulation is enabled */
|
||||
int buffer_size; /* Size of sound buffer (in bytes) */
|
||||
int16 *buffer[2]; /* Signed 16-bit stereo sound data */
|
||||
@ -106,9 +110,10 @@ extern uint32 mcycles_68k;
|
||||
extern uint32 mcycles_vdp;
|
||||
extern int16 SVP_cycles;
|
||||
extern uint8 system_hw;
|
||||
extern uint32 system_clock;
|
||||
|
||||
/* Function prototypes */
|
||||
extern int audio_init(int samplerate,float framerate);
|
||||
extern int audio_init(int samplerate, double framerate);
|
||||
extern void audio_reset(void);
|
||||
extern void audio_shutdown(void);
|
||||
extern int audio_update(void);
|
||||
|
@ -11,8 +11,3 @@
|
||||
#define int8 signed char
|
||||
#define int16 signed short
|
||||
#define int32 signed int
|
||||
|
||||
/* C89 compatibility */
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846264338327
|
||||
#endif
|
||||
|
@ -57,7 +57,7 @@ extern sms_ntsc_t *sms_ntsc;
|
||||
#undef READ_LONG
|
||||
#undef WRITE_LONG
|
||||
|
||||
static __inline__ uint32 READ_LONG(void *address)
|
||||
INLINE uint32 READ_LONG(void *address)
|
||||
{
|
||||
if ((uint32)address & 3)
|
||||
{
|
||||
@ -76,7 +76,7 @@ static __inline__ uint32 READ_LONG(void *address)
|
||||
else return *(uint32 *)address;
|
||||
}
|
||||
|
||||
static __inline__ void WRITE_LONG(void *address, uint32 data)
|
||||
INLINE void WRITE_LONG(void *address, uint32 data)
|
||||
{
|
||||
if ((uint32)address & 3)
|
||||
{
|
||||
@ -948,7 +948,7 @@ static uint32 make_lut_bgobj_m4(uint32 bx, uint32 sx)
|
||||
/* Pixel layer merging function */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
static __inline__ void merge(uint8 *srca, uint8 *srcb, uint8 *dst, uint8 *table, int width)
|
||||
INLINE void merge(uint8 *srca, uint8 *srcb, uint8 *dst, uint8 *table, int width)
|
||||
{
|
||||
do
|
||||
{
|
||||
|
@ -27,6 +27,8 @@ void set_config_defaults(void)
|
||||
/* system options */
|
||||
config.system = 0; /* = AUTO (or SYSTEM_SG, SYSTEM_MARKIII, SYSTEM_SMS, SYSTEM_SMS2, SYSTEM_GG, SYSTEM_MD) */
|
||||
config.region_detect = 0; /* = AUTO (1 = USA, 2 = EUROPE, 3 = JAPAN/NTSC, 4 = JAPAN/PAL) */
|
||||
config.vdp_mode = 0; /* = AUTO (1 = NTSC, 2 = PAL) */
|
||||
config.master_clock = 0; /* = AUTO (1 = NTSC, 2 = PAL) */
|
||||
config.force_dtack = 0;
|
||||
config.addr_error = 1;
|
||||
config.bios = 0;
|
||||
|
@ -29,6 +29,8 @@ typedef struct
|
||||
float rolloff;
|
||||
uint8 system;
|
||||
uint8 region_detect;
|
||||
uint8 vdp_mode;
|
||||
uint8 master_clock;
|
||||
uint8 force_dtack;
|
||||
uint8 addr_error;
|
||||
uint8 tmss;
|
||||
|
@ -729,7 +729,7 @@ int main (int argc, char **argv)
|
||||
bitmap.viewport.changed = 3;
|
||||
|
||||
/* initialize emulation */
|
||||
audio_init(SOUND_FREQUENCY, vdp_pal ? 50.0 : 60.0);
|
||||
audio_init(SOUND_FREQUENCY, 0);
|
||||
system_init();
|
||||
|
||||
/* load SRAM */
|
||||
|
@ -7,42 +7,23 @@
|
||||
* UINT8 - Unsigned 8-bit Integer INT8 - Signed 8-bit integer *
|
||||
* UINT16 - Unsigned 16-bit Integer INT16 - Signed 16-bit integer *
|
||||
* UINT32 - Unsigned 32-bit Integer INT32 - Signed 32-bit integer *
|
||||
* UINT64 - Unsigned 64-bit Integer INT64 - Signed 64-bit integer *
|
||||
* *
|
||||
* *
|
||||
* The macro names for the artithmatic operations are composed as follows: *
|
||||
* *
|
||||
* XXX_R_A_B, where XXX - 3 letter operation code (ADD, SUB, etc.) *
|
||||
* R - The type of the result *
|
||||
* A - The type of operand 1 *
|
||||
* B - The type of operand 2 (if binary operation) *
|
||||
* *
|
||||
* Each type is one of: U8,8,U16,16,U32,32,U64,64 *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef OSD_CPU_H
|
||||
#define OSD_CPU_H
|
||||
|
||||
#ifndef NGC
|
||||
#ifndef DOS
|
||||
#include "basetsd.h"
|
||||
#endif
|
||||
#undef TRUE
|
||||
#undef FALSE
|
||||
#define TRUE 1
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
typedef unsigned char UINT8;
|
||||
typedef unsigned short UINT16;
|
||||
typedef unsigned int UINT32;
|
||||
__extension__ typedef unsigned long long UINT64;
|
||||
typedef signed char INT8;
|
||||
typedef signed short INT16;
|
||||
typedef signed int INT32;
|
||||
__extension__ typedef signed long long INT64;
|
||||
|
||||
typedef unsigned char UINT8;
|
||||
typedef unsigned short UINT16;
|
||||
typedef unsigned int UINT32;
|
||||
typedef signed char INT8;
|
||||
typedef signed short INT16;
|
||||
typedef signed int INT32;
|
||||
|
||||
/******************************************************************************
|
||||
* Union of UINT8, UINT16 and UINT32 in native endianess of the target
|
||||
|
Loading…
Reference in New Issue
Block a user