fixed SVP DMA, fixed bug with interlaced mode, added backdrop color for NTSC filters

This commit is contained in:
ekeeke31 2008-12-07 19:31:50 +00:00
parent c4c78f58be
commit 35530e0ee3
15 changed files with 130 additions and 161 deletions

View File

@ -5,7 +5,6 @@ CURRENT:
--------- ---------
[Genesis] [Genesis]
- YM2612(MAME): - YM2612(MAME):
.fixed EG Decay->Substain transition when SL & DR are minimals: fix tracks #3 and #9 in "Mega Turrican" .fixed EG Decay->Substain transition when SL & DR are minimals: fix tracks #3 and #9 in "Mega Turrican"
.fixed a bug in SSG-EG emulation code: fix Level 1 music in "Alisia Dragoon" .fixed a bug in SSG-EG emulation code: fix Level 1 music in "Alisia Dragoon"
@ -13,33 +12,27 @@ CURRENT:
.improved Detune overflow accuracy: fix very high frequency sounds in many games .improved Detune overflow accuracy: fix very high frequency sounds in many games
.fixed registers 0x20-0x26 Reset state: fix intro music in "B.O.B" .fixed registers 0x20-0x26 Reset state: fix intro music in "B.O.B"
.reverted incorrect fix with KEY ON: fix "Flamethrower" sound effect in "Alien 3" and many others .reverted incorrect fix with KEY ON: fix "Flamethrower" sound effect in "Alien 3" and many others
- adjusted HCounter values: fixes line flickering in "Sonic 3D" bonus stage - adjusted HCounter values: fixes line flickering in "Sonic 3D" bonus stage
- adjusted VINT timing: fixes hang-up in "V.R Troopers" - adjusted VINT timing: fixes hang-up in "V.R Troopers"
- improved HBLANK flag accuracy: fixes line flickering in "Gouketsuji Ichizoku" - improved HBLANK flag accuracy: fixes line flickering in "Gouketsuji Ichizoku"
- fixed broken Z80 access to WRAM: fixes hang-up in "Mamono Hunter Youko" - fixed broken Z80 access to WRAM: fixes hang-up in "Mamono Hunter Youko"
- modified JCART emulation: fixes corrupted tracks logo in "Micro Machines 2" - modified JCART emulation: fixes corrupted tracks logo in "Micro Machines 2"
- added Blargg's NTSC Filters support (NTSC video artifacts emulation) - added Blargg's NTSC Filters support (NTSC video artifacts emulation)
- improved emulation speed: highly optimized VDP rendering engine, 68k memory handlers, cpu execution & interrupts - optimized VDP rendering core, rewrote 68k interface (memory handlers, cycle execution, interrupts): greatly improved emulation speed
[NGC/Wii] [NGC/Wii]
- remove slowest libsamplerate settings under "HQ YM2612" option, only keeps SRC_LINEAR (faster) and SRC_SINC_FAST (better) - remove slowest libsamplerate settings under "HQ YM2612" option, only keeps SRC_LINEAR (faster) and SRC_SINC_FAST (better)
- implemented fast scrolling in menu using Wiimote D-PAD
- added an option to enable/disable bilinear filtering - added an option to enable/disable bilinear filtering
- rewrote video engine: improved horizontal scaling (VI+GX), improved rendering speed (direct texture mapping) - rewrote video engine: improved horizontal scaling (VI+GX), improved rendering speed (direct texture mapping)
- removed embedded font, (re)enabled IPL font support: now should works for Qoob users too (thanks to emukiddid) - removed embedded font, (re)enabled IPL font support: now should works for Qoob users too (thanks to emukiddid)
- fixed "Reset" button behavior, now acts more like Genesis Reset button ;-) - fixed "Reset" button behavior, now acts more like Genesis Reset button ;-)
- minor bugfixes and menu tweaks - minor bugfixes and menu tweaks
[NGC only] [NGC only]
- added 480p support in menu - added 480p support in menu
[Wii only] [Wii only]
- implemented fast scrolling in menu using Wiimote D-PAD
- added "Power" button support - added "Power" button support
- improved SDCARD access speed (svpe's "read-ahead" patch) - improved SDCARD access speed (svpe's "read-ahead" patch)
- compiled with libogc CVS: SDHC support, Wiimote shutdown button support - compiled with libogc CVS: SDHC support, Wiimote shutdown button support

View File

@ -4,9 +4,11 @@
#include <fat.h> #include <fat.h>
#include <sys/dir.h> #include <sys/dir.h>
#define CONFIG_VERSION "GENPLUS 1.2.2 " #ifdef HW_RVL
#define CONFIG_VERSION "GENPLUS 1.2.2W"
t_config config; #else
#define CONFIG_VERSION "GENPLUS 1.2.2G"
#endif
void config_save() void config_save()
{ {
@ -17,7 +19,7 @@ void config_save()
if (dir == NULL) mkdir("/genplus",S_IRWXU); if (dir == NULL) mkdir("/genplus",S_IRWXU);
else dirclose(dir); else dirclose(dir);
/* open file for writing */ /* open configuration file */
FILE *fp = fopen("/genplus/genplus.ini", "wb"); FILE *fp = fopen("/genplus/genplus.ini", "wb");
if (fp == NULL) return; if (fp == NULL) return;
@ -29,7 +31,7 @@ void config_save()
void config_load() void config_load()
{ {
/* open file for writing */ /* open configuration file */
FILE *fp = fopen("/genplus/genplus.ini", "rb"); FILE *fp = fopen("/genplus/genplus.ini", "rb");
if (fp == NULL) return; if (fp == NULL) return;
@ -43,20 +45,6 @@ void config_load()
fp = fopen("/genplus/genplus.ini", "rb"); fp = fopen("/genplus/genplus.ini", "rb");
fread(&config, sizeof(config), 1, fp); fread(&config, sizeof(config), 1, fp);
fclose(fp); fclose(fp);
#ifndef HW_RVL
/* check some specific Wii-version options */
int i;
for (i=0; i<MAX_DEVICES; i++)
{
if (config.input[i].device > 0)
{
config.input[i].device = 0;
config.input[i].port = i%4;
}
}
#endif
} }
void set_config_defaults(void) void set_config_defaults(void)

View File

@ -37,7 +37,10 @@ typedef struct
uint8 invert_mouse; uint8 invert_mouse;
} t_config; } t_config;
extern t_config config; /* Global data */
t_config config;
extern void config_save(); extern void config_save();
extern void config_load(); extern void config_load();
extern void set_config_defaults(void); extern void set_config_defaults(void);

View File

@ -1100,7 +1100,7 @@ void MainMenu ()
VIDEO_WaitVSync(); VIDEO_WaitVSync();
VIDEO_WaitVSync(); VIDEO_WaitVSync();
/* autosave SRAM (Freeze States should be saved on exit only) */ /* autosave (SRAM only) */
int temp = config.freeze_auto; int temp = config.freeze_auto;
config.freeze_auto = -1; config.freeze_auto = -1;
memfile_autosave(); memfile_autosave();
@ -1108,6 +1108,20 @@ void MainMenu ()
while (quit == 0) while (quit == 0)
{ {
#ifdef HW_RVL
/* wii shutdown */
if (Shutdown)
{
/* autosave SRAM/State */
memfile_autosave();
/* shutdown Wii */
DI_Close();
SYS_ResetSystem(SYS_POWEROFF, 0, 0);
}
#endif
crccheck = crc32 (0, &sram.sram[0], 0x10000); crccheck = crc32 (0, &sram.sram[0], 0x10000);
if (genromsize && (crccheck != sram.crc)) strcpy (menutitle, "*** SRAM has been modified ***"); if (genromsize && (crccheck != sram.crc)) strcpy (menutitle, "*** SRAM has been modified ***");
else sprintf(menutitle, "%d FPS", FramesPerSecond); else sprintf(menutitle, "%d FPS", FramesPerSecond);
@ -1117,10 +1131,7 @@ void MainMenu ()
{ {
case -1: /*** Button B ***/ case -1: /*** Button B ***/
case 0: /*** Play Game ***/ case 0: /*** Play Game ***/
if (genromsize) if (genromsize) quit = 1;
{
quit = 1;
}
break; break;
case 1: /*** ROM Information ***/ case 1: /*** ROM Information ***/

View File

@ -28,9 +28,10 @@
#include "di/di.h" #include "di/di.h"
#endif #endif
int Shutdown = 0;
#ifdef HW_RVL #ifdef HW_RVL
/* Power Button callback */ /* Power Button callback */
static int Shutdown;
void Power_Off(void) void Power_Off(void)
{ {
Shutdown = 1; Shutdown = 1;
@ -38,6 +39,7 @@ void Power_Off(void)
} }
#endif #endif
/*************************************************************************** /***************************************************************************
* Genesis Virtual Machine * Genesis Virtual Machine
* *
@ -66,7 +68,7 @@ static void load_bios()
} }
} }
static void init_machine() static void init_machine (void)
{ {
/* Allocate cart_rom here */ /* Allocate cart_rom here */
cart_rom = memalign(32, 10 * 1024 * 1024); cart_rom = memalign(32, 10 * 1024 * 1024);
@ -117,6 +119,7 @@ int main (int argc, char *argv[])
{ {
#ifdef HW_RVL #ifdef HW_RVL
/* initialize Wii DVD interface first */ /* initialize Wii DVD interface first */
DI_Close();
DI_Init(); DI_Init();
#endif #endif
@ -145,10 +148,10 @@ int main (int argc, char *argv[])
if (fatInitDefault() == true) if (fatInitDefault() == true)
{ {
use_FAT = 1; use_FAT = 1;
// fatEnableReadAhead (PI_DEFAULT, 6, 64); fatEnableReadAhead (PI_DEFAULT, 6, 64);
} }
/* Restore User Configuration */ /* Default Config */
set_config_defaults(); set_config_defaults();
config_load(); config_load();
@ -241,20 +244,6 @@ int main (int argc, char *argv[])
/* reset AUDIO */ /* reset AUDIO */
ogc_audio__reset(); ogc_audio__reset();
#ifdef HW_RVL
/* wii shutdown */
if (Shutdown)
{
/* autosave SRAM/State */
memfile_autosave();
/* shutdown Wii */
Shutdown = 0;
DI_Close();
SYS_ResetSystem(SYS_POWEROFF, 0, 0);
}
#endif
/* go to menu */ /* go to menu */
MainMenu (); MainMenu ();
ConfigRequested = 0; ConfigRequested = 0;

View File

@ -21,7 +21,6 @@
#include "shared.h" #include "shared.h"
#include "ogc_input.h" #include "ogc_input.h"
//#include <asndlib.h>
/* global datas */ /* global datas */
unsigned char soundbuffer[16][3840] ATTRIBUTE_ALIGN(32); unsigned char soundbuffer[16][3840] ATTRIBUTE_ALIGN(32);
@ -50,7 +49,6 @@ static void AudioSwitchBuffers()
AUDIO_InitDMA((u32) soundbuffer[playbuffer], dma_len); AUDIO_InitDMA((u32) soundbuffer[playbuffer], dma_len);
DCFlushRange(soundbuffer[playbuffer], dma_len); DCFlushRange(soundbuffer[playbuffer], dma_len);
AUDIO_StartDMA(); AUDIO_StartDMA();
//ASND_SetVoice(0, VOICE_STEREO_16BIT, 48000, 0, soundbuffer[playbuffer], dma_len, 255, 255, AudioSwitchBuffers);
/* increment soundbuffers index */ /* increment soundbuffers index */
if (playbuffer == mixbuffer) if (playbuffer == mixbuffer)
@ -70,14 +68,12 @@ void ogc_audio__init(void)
AUDIO_Init (NULL); AUDIO_Init (NULL);
AUDIO_SetDSPSampleRate (AI_SAMPLERATE_48KHZ); AUDIO_SetDSPSampleRate (AI_SAMPLERATE_48KHZ);
AUDIO_RegisterDMACallback (AudioSwitchBuffers); AUDIO_RegisterDMACallback (AudioSwitchBuffers);
//ASND_Init();
memset(soundbuffer, 0, 16 * 3840); memset(soundbuffer, 0, 16 * 3840);
} }
void ogc_audio__reset(void) void ogc_audio__reset(void)
{ {
AUDIO_StopDMA (); AUDIO_StopDMA ();
//ASND_Pause(1);
IsPlaying = 0; IsPlaying = 0;
mixbuffer = 0; mixbuffer = 0;
playbuffer = 0; playbuffer = 0;
@ -86,9 +82,5 @@ void ogc_audio__reset(void)
void ogc_audio__update(void) void ogc_audio__update(void)
{ {
/* restart Audio DMA if needed */ /* restart Audio DMA if needed */
if (!IsPlaying) if (!IsPlaying) AudioSwitchBuffers();
{
//ASND_Pause(0);
AudioSwitchBuffers();
}
} }

View File

@ -113,7 +113,8 @@ static u32 wpad_keys[20] =
*******************************/ *******************************/
static void pad_config(int num, int padtype) static void pad_config(int num, int padtype)
{ {
int i,j,max; int i,j;
int max = (padtype == DEVICE_6BUTTON) ? MAX_KEYS : (MAX_KEYS - 3);
u16 p; u16 p;
u8 quit; u8 quit;
char msg[30]; char msg[30];
@ -127,7 +128,6 @@ static void pad_config(int num, int padtype)
} }
/* configure keys */ /* configure keys */
max = (padtype == DEVICE_6BUTTON) ? MAX_KEYS : (MAX_KEYS - 3);
for (i=0; i<max; i++) for (i=0; i<max; i++)
{ {
/* remove any pending keys */ /* remove any pending keys */
@ -333,7 +333,8 @@ static s8 WPAD_StickY(u8 chan, u8 right)
static void wpad_config(u8 num, u8 exp, u8 padtype) static void wpad_config(u8 num, u8 exp, u8 padtype)
{ {
int i,j,max; int i,j;
int max = (padtype == DEVICE_6BUTTON) ? MAX_KEYS : (MAX_KEYS - 3);
u8 quit; u8 quit;
char msg[30]; char msg[30];
u32 current = 255; u32 current = 255;
@ -353,7 +354,6 @@ static void wpad_config(u8 num, u8 exp, u8 padtype)
u8 index = exp + (num * 3); u8 index = exp + (num * 3);
/* loop on each mapped keys */ /* loop on each mapped keys */
max = (padtype == DEVICE_6BUTTON) ? MAX_KEYS : (MAX_KEYS - 3);
for (i=0; i<max; i++) for (i=0; i<max; i++)
{ {
/* remove any pending buttons */ /* remove any pending buttons */

View File

@ -52,7 +52,6 @@ static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN (32);
static GXTexObj texobj; static GXTexObj texobj;
static Mtx view; static Mtx view;
static u32 vwidth, vheight; static u32 vwidth, vheight;
static u32 stride;
/*** custom Video modes (used to emulate original console video modes) ***/ /*** custom Video modes (used to emulate original console video modes) ***/
/* 288 lines progressive (PAL 50Hz) */ /* 288 lines progressive (PAL 50Hz) */
@ -72,10 +71,10 @@ GXRModeObj TV50hz_288p =
// sample points arranged in increasing Y order // sample points arranged in increasing Y order
{ {
{3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
{3,2},{9,6},{3,10}, // pix 1 {6,6},{6,6},{6,6}, // pix 1
{9,2},{3,6},{9,10}, // pix 2 {6,6},{6,6},{6,6}, // pix 2
{9,2},{3,6},{9,10} // pix 3 {6,6},{6,6},{6,6} // pix 3
}, },
// vertical filter[7], 1/64 units, 6 bits each // vertical filter[7], 1/64 units, 6 bits each
@ -107,10 +106,10 @@ GXRModeObj TV50hz_288i =
// sample points arranged in increasing Y order // sample points arranged in increasing Y order
{ {
{3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
{3,2},{9,6},{3,10}, // pix 1 {6,6},{6,6},{6,6}, // pix 1
{9,2},{3,6},{9,10}, // pix 2 {6,6},{6,6},{6,6}, // pix 2
{9,2},{3,6},{9,10} // pix 3 {6,6},{6,6},{6,6} // pix 3
}, },
// vertical filter[7], 1/64 units, 6 bits each // vertical filter[7], 1/64 units, 6 bits each
@ -142,21 +141,21 @@ GXRModeObj TV50hz_576i =
// sample points arranged in increasing Y order // sample points arranged in increasing Y order
{ {
{3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
{3,2},{9,6},{3,10}, // pix 1 {6,6},{6,6},{6,6}, // pix 1
{9,2},{3,6},{9,10}, // pix 2 {6,6},{6,6},{6,6}, // pix 2
{9,2},{3,6},{9,10} // pix 3 {6,6},{6,6},{6,6} // pix 3
}, },
// vertical filter[7], 1/64 units, 6 bits each // vertical filter[7], 1/64 units, 6 bits each
{ {
4, // line n-1
8, // line n-1 8, // line n-1
8, // line n-1
10, // line n
12, // line n 12, // line n
16, // line n 10, // line n
12, // line n
8, // line n+1 8, // line n+1
4 // line n+1 8 // line n+1
} }
}; };
@ -177,10 +176,10 @@ GXRModeObj TV60hz_240p =
// sample points arranged in increasing Y order // sample points arranged in increasing Y order
{ {
{3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
{3,2},{9,6},{3,10}, // pix 1 {6,6},{6,6},{6,6}, // pix 1
{9,2},{3,6},{9,10}, // pix 2 {6,6},{6,6},{6,6}, // pix 2
{9,2},{3,6},{9,10} // pix 3 {6,6},{6,6},{6,6} // pix 3
}, },
// vertical filter[7], 1/64 units, 6 bits each // vertical filter[7], 1/64 units, 6 bits each
@ -247,21 +246,21 @@ GXRModeObj TV60hz_480i =
// sample points arranged in increasing Y order // sample points arranged in increasing Y order
{ {
{3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
{3,2},{9,6},{3,10}, // pix 1 {6,6},{6,6},{6,6}, // pix 1
{9,2},{3,6},{9,10}, // pix 2 {6,6},{6,6},{6,6}, // pix 2
{9,2},{3,6},{9,10} // pix 3 {6,6},{6,6},{6,6} // pix 3
}, },
// vertical filter[7], 1/64 units, 6 bits each // vertical filter[7], 1/64 units, 6 bits each
{ {
4, // line n-1
8, // line n-1 8, // line n-1
8, // line n-1
10, // line n
12, // line n 12, // line n
16, // line n 10, // line n
12, // line n
8, // line n+1 8, // line n+1
4 // line n+1 8 // line n+1
} }
}; };
@ -453,9 +452,9 @@ static void gxScale(GXRModeObj *rmode)
/* GX Scaler (by default, use EFB maximal width) */ /* GX Scaler (by default, use EFB maximal width) */
rmode->fbWidth = 640; rmode->fbWidth = 640;
if (!config.bilinear) if (!config.bilinear && !config.ntsc)
{ {
/* try to prevent GX bilinear filtering */ /* filtering (soft or hard) is disabled, let VI handles horizontal scaling */
/* if possible, let GX simply doubles the width, otherwise disable GX stretching completely */ /* if possible, let GX simply doubles the width, otherwise disable GX stretching completely */
int width = vwidth * 4; int width = vwidth * 4;
if ((width * 2) <= 640) rmode->fbWidth = width * 2; if ((width * 2) <= 640) rmode->fbWidth = width * 2;
@ -590,17 +589,14 @@ void ogc_video__update()
if (config.ntsc) vwidth = (reg[12]&1) ? MD_NTSC_OUT_WIDTH(vwidth) : SMS_NTSC_OUT_WIDTH(vwidth); if (config.ntsc) vwidth = (reg[12]&1) ? MD_NTSC_OUT_WIDTH(vwidth) : SMS_NTSC_OUT_WIDTH(vwidth);
/* texels size must be multiple of 4 */ /* texels size must be multiple of 4 */
vwidth = vwidth >> 2; vwidth = vwidth / 4;
vheight = vheight >> 2; vheight = vheight / 4;
/* final offset */
stride = bitmap.width - vwidth;
/* image size has changed, reset GX */ /* image size has changed, reset GX */
ogc_video__reset(); ogc_video__reset();
/* reinitialize texture */ /* reinitialize texture */
GX_InitTexObj (&texobj, texturemem, vwidth << 2, vheight << 2, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE); GX_InitTexObj (&texobj, texturemem, vwidth * 4, vheight * 4, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
/* enable/disable bilinear filtering */ /* enable/disable bilinear filtering */
if (!config.bilinear) if (!config.bilinear)
@ -695,7 +691,6 @@ void ogc_video__init(void)
TV60hz_240i.viTVMode = VI_TVMODE(vmode->viTVMode >> 2, VI_INTERLACE); TV60hz_240i.viTVMode = VI_TVMODE(vmode->viTVMode >> 2, VI_INTERLACE);
TV60hz_480i.viTVMode = VI_TVMODE(vmode->viTVMode >> 2, VI_INTERLACE); TV60hz_480i.viTVMode = VI_TVMODE(vmode->viTVMode >> 2, VI_INTERLACE);
config.tv_mode = 2; config.tv_mode = 2;
gc_pal = 0;
break; break;
} }

View File

@ -43,5 +43,6 @@ extern void memfile_autoload();
extern int peripherals; extern int peripherals;
extern int frameticker; extern int frameticker;
extern int FramesPerSecond; extern int FramesPerSecond;
extern int Shutdown;
#endif /* _OSD_H_ */ #endif /* _OSD_H_ */

View File

@ -91,8 +91,9 @@ void md_ntsc_blit( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned ch
int in_width, int vline) int in_width, int vline)
{ {
int const chunk_count = in_width / md_ntsc_in_chunk - 1; int const chunk_count = in_width / md_ntsc_in_chunk - 1;
MD_NTSC_IN_T border = table[0];
MD_NTSC_BEGIN_ROW( ntsc, md_ntsc_black, MD_NTSC_BEGIN_ROW( ntsc, border,
MD_NTSC_ADJ_IN( table[*input++] ), MD_NTSC_ADJ_IN( table[*input++] ),
MD_NTSC_ADJ_IN( table[*input++] ), MD_NTSC_ADJ_IN( table[*input++] ),
MD_NTSC_ADJ_IN( table[*input++] ) ); MD_NTSC_ADJ_IN( table[*input++] ) );
@ -143,7 +144,7 @@ void md_ntsc_blit( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned ch
MD_NTSC_RGB_OUT( 0, *line_out++, MD_NTSC_OUT_DEPTH ); MD_NTSC_RGB_OUT( 0, *line_out++, MD_NTSC_OUT_DEPTH );
MD_NTSC_RGB_OUT( 1, *line_out++, MD_NTSC_OUT_DEPTH ); MD_NTSC_RGB_OUT( 1, *line_out++, MD_NTSC_OUT_DEPTH );
MD_NTSC_COLOR_IN( 1, ntsc, md_ntsc_black ); MD_NTSC_COLOR_IN( 1, ntsc, border );
MD_NTSC_RGB_OUT( 2, *line_out++, MD_NTSC_OUT_DEPTH ); MD_NTSC_RGB_OUT( 2, *line_out++, MD_NTSC_OUT_DEPTH );
MD_NTSC_RGB_OUT( 3, *line_out++, MD_NTSC_OUT_DEPTH ); MD_NTSC_RGB_OUT( 3, *line_out++, MD_NTSC_OUT_DEPTH );
@ -151,11 +152,11 @@ void md_ntsc_blit( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned ch
line_out += 12; line_out += 12;
#endif #endif
MD_NTSC_COLOR_IN( 2, ntsc, md_ntsc_black ); MD_NTSC_COLOR_IN( 2, ntsc, border );
MD_NTSC_RGB_OUT( 4, *line_out++, MD_NTSC_OUT_DEPTH ); MD_NTSC_RGB_OUT( 4, *line_out++, MD_NTSC_OUT_DEPTH );
MD_NTSC_RGB_OUT( 5, *line_out++, MD_NTSC_OUT_DEPTH ); MD_NTSC_RGB_OUT( 5, *line_out++, MD_NTSC_OUT_DEPTH );
MD_NTSC_COLOR_IN( 3, ntsc, md_ntsc_black ); MD_NTSC_COLOR_IN( 3, ntsc, border );
MD_NTSC_RGB_OUT( 6, *line_out++, MD_NTSC_OUT_DEPTH ); MD_NTSC_RGB_OUT( 6, *line_out++, MD_NTSC_OUT_DEPTH );
MD_NTSC_RGB_OUT( 7, *line_out++, MD_NTSC_OUT_DEPTH ); MD_NTSC_RGB_OUT( 7, *line_out++, MD_NTSC_OUT_DEPTH );
} }

View File

@ -138,14 +138,7 @@ struct md_ntsc_t {
/* x is always zero except in snes_ntsc library */ /* x is always zero except in snes_ntsc library */
#define MD_NTSC_RGB_OUT_( rgb_out, bits, x ) {\ #define MD_NTSC_RGB_OUT_( rgb_out, bits, x ) {\
if ( bits == 16 )\
rgb_out = (raw_>>(13-x)& 0xF800)|(raw_>>(8-x)&0x07E0)|(raw_>>(4-x)&0x001F);\ rgb_out = (raw_>>(13-x)& 0xF800)|(raw_>>(8-x)&0x07E0)|(raw_>>(4-x)&0x001F);\
if ( bits == 24 || bits == 32 )\
rgb_out = (raw_>>(5-x)&0xFF0000)|(raw_>>(3-x)&0xFF00)|(raw_>>(1-x)&0xFF);\
if ( bits == 15 )\
rgb_out = (raw_>>(14-x)& 0x7C00)|(raw_>>(9-x)&0x03E0)|(raw_>>(4-x)&0x001F);\
if ( bits == 0 )\
rgb_out = raw_ << x;\
} }
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -95,7 +95,9 @@ void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned
unsigned const extra2 = (unsigned) -(in_extra >> 1 & 1); /* (unsigned) -1 = ~0 */ unsigned const extra2 = (unsigned) -(in_extra >> 1 & 1); /* (unsigned) -1 = ~0 */
unsigned const extra1 = (unsigned) -(in_extra & 1) | extra2; unsigned const extra1 = (unsigned) -(in_extra & 1) | extra2;
SMS_NTSC_BEGIN_ROW( ntsc, sms_ntsc_black, SMS_NTSC_IN_T border = table[0];
SMS_NTSC_BEGIN_ROW( ntsc, border,
(SMS_NTSC_ADJ_IN( table[input[0]] )) & extra2, (SMS_NTSC_ADJ_IN( table[input[0]] )) & extra2,
(SMS_NTSC_ADJ_IN( table[input[extra2 & 1]] )) & extra1 ); (SMS_NTSC_ADJ_IN( table[input[extra2 & 1]] )) & extra1 );
@ -103,8 +105,8 @@ void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned
/* directly fill the RGB565 texture */ /* directly fill the RGB565 texture */
/* one tile is 32 byte = 4x4 pixels */ /* one tile is 32 byte = 4x4 pixels */
/* tiles are stored continuously in texture memory */ /* tiles are stored continuously in texture memory */
in_width = SMS_NTSC_OUT_WIDTH(in_width) >> 2; in_width = SMS_NTSC_OUT_WIDTH(in_width) / 4;
int offset = ((in_width << 5) * (vline >> 2)) + ((vline & 3) * 8); int offset = ((in_width * 32) * (vline / 4)) + ((vline & 3) * 8);
sms_ntsc_out_t* restrict line_out = (sms_ntsc_out_t*)(texturemem + offset); sms_ntsc_out_t* restrict line_out = (sms_ntsc_out_t*)(texturemem + offset);
offset = 0; offset = 0;
#else #else
@ -118,10 +120,10 @@ void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned
/* order of input and output pixels must not be altered */ /* order of input and output pixels must not be altered */
SMS_NTSC_COLOR_IN( 0, ntsc, SMS_NTSC_ADJ_IN( table[*input++] ) ); SMS_NTSC_COLOR_IN( 0, ntsc, SMS_NTSC_ADJ_IN( table[*input++] ) );
#ifdef NGC #ifdef NGC
SMS_NTSC_RGB_OUT( 0, line_out[16*(offset/4) + (offset%4)], SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 0, line_out[offset++], SMS_NTSC_OUT_DEPTH );
offset ++; if ((offset % 4) == 0) offset += 12;
SMS_NTSC_RGB_OUT( 1, line_out[16*(offset/4) + (offset%4)], SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 1, line_out[offset++], SMS_NTSC_OUT_DEPTH );
offset ++; if ((offset % 4) == 0) offset += 12;
#else #else
SMS_NTSC_RGB_OUT( 0, *line_out++, SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 0, *line_out++, SMS_NTSC_OUT_DEPTH );
SMS_NTSC_RGB_OUT( 1, *line_out++, SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 1, *line_out++, SMS_NTSC_OUT_DEPTH );
@ -129,10 +131,10 @@ void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned
SMS_NTSC_COLOR_IN( 1, ntsc, SMS_NTSC_ADJ_IN( table[*input++] ) ); SMS_NTSC_COLOR_IN( 1, ntsc, SMS_NTSC_ADJ_IN( table[*input++] ) );
#ifdef NGC #ifdef NGC
SMS_NTSC_RGB_OUT( 2, line_out[16*(offset/4) + (offset%4)], SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 2, line_out[offset++], SMS_NTSC_OUT_DEPTH );
offset ++; if ((offset % 4) == 0) offset += 12;
SMS_NTSC_RGB_OUT( 3, line_out[16*(offset/4) + (offset%4)], SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 3, line_out[offset++], SMS_NTSC_OUT_DEPTH );
offset ++; if ((offset % 4) == 0) offset += 12;
#else #else
SMS_NTSC_RGB_OUT( 2, *line_out++, SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 2, *line_out++, SMS_NTSC_OUT_DEPTH );
SMS_NTSC_RGB_OUT( 3, *line_out++, SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 3, *line_out++, SMS_NTSC_OUT_DEPTH );
@ -140,12 +142,12 @@ void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned
SMS_NTSC_COLOR_IN( 2, ntsc, SMS_NTSC_ADJ_IN( table[*input++] ) ); SMS_NTSC_COLOR_IN( 2, ntsc, SMS_NTSC_ADJ_IN( table[*input++] ) );
#ifdef NGC #ifdef NGC
SMS_NTSC_RGB_OUT( 4, line_out[16*(offset/4) + (offset%4)], SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 4, line_out[offset++], SMS_NTSC_OUT_DEPTH );
offset ++; if ((offset % 4) == 0) offset += 12;
SMS_NTSC_RGB_OUT( 5, line_out[16*(offset/4) + (offset%4)], SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 5, line_out[offset++], SMS_NTSC_OUT_DEPTH );
offset ++; if ((offset % 4) == 0) offset += 12;
SMS_NTSC_RGB_OUT( 6, line_out[16*(offset/4) + (offset%4)], SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 6, line_out[offset++], SMS_NTSC_OUT_DEPTH );
offset ++; if ((offset % 4) == 0) offset += 12;
#else #else
SMS_NTSC_RGB_OUT( 4, *line_out++, SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 4, *line_out++, SMS_NTSC_OUT_DEPTH );
SMS_NTSC_RGB_OUT( 5, *line_out++, SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 5, *line_out++, SMS_NTSC_OUT_DEPTH );
@ -154,35 +156,36 @@ void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned
} }
/* finish final pixels */ /* finish final pixels */
SMS_NTSC_COLOR_IN( 0, ntsc, sms_ntsc_black ); SMS_NTSC_COLOR_IN( 0, ntsc, border );
#ifdef NGC #ifdef NGC
SMS_NTSC_RGB_OUT( 0, line_out[16*(offset/4) + (offset%4)], SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 0, line_out[offset++], SMS_NTSC_OUT_DEPTH );
offset ++; if ((offset % 4) == 0) offset += 12;
SMS_NTSC_RGB_OUT( 1, line_out[16*(offset/4) + (offset%4)], SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 1, line_out[offset++], SMS_NTSC_OUT_DEPTH );
offset ++; if ((offset % 4) == 0) offset += 12;
#else #else
SMS_NTSC_RGB_OUT( 0, *line_out++, SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 0, *line_out++, SMS_NTSC_OUT_DEPTH );
SMS_NTSC_RGB_OUT( 1, *line_out++, SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 1, *line_out++, SMS_NTSC_OUT_DEPTH );
#endif #endif
SMS_NTSC_COLOR_IN( 1, ntsc, sms_ntsc_black ); SMS_NTSC_COLOR_IN( 1, ntsc, border );
#ifdef NGC #ifdef NGC
SMS_NTSC_RGB_OUT( 2, line_out[16*(offset/4) + (offset%4)], SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 2, line_out[offset++], SMS_NTSC_OUT_DEPTH );
offset ++; if ((offset % 4) == 0) offset += 12;
SMS_NTSC_RGB_OUT( 3, line_out[16*(offset/4) + (offset%4)], SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 3, line_out[offset++], SMS_NTSC_OUT_DEPTH );
offset ++; if ((offset % 4) == 0) offset += 12;
#else #else
SMS_NTSC_RGB_OUT( 2, *line_out++, SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 2, *line_out++, SMS_NTSC_OUT_DEPTH );
SMS_NTSC_RGB_OUT( 3, *line_out++, SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 3, *line_out++, SMS_NTSC_OUT_DEPTH );
#endif #endif
SMS_NTSC_COLOR_IN( 2, ntsc, sms_ntsc_black ); SMS_NTSC_COLOR_IN( 2, ntsc, border );
#ifdef NGC #ifdef NGC
SMS_NTSC_RGB_OUT( 4, line_out[16*(offset/4) + (offset%4)], SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 4, line_out[offset++], SMS_NTSC_OUT_DEPTH );
offset ++; if ((offset % 4) == 0) offset += 12;
SMS_NTSC_RGB_OUT( 5, line_out[16*(offset/4) + (offset%4)], SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 5, line_out[offset++], SMS_NTSC_OUT_DEPTH );
offset ++; if ((offset % 4) == 0) offset += 12;
SMS_NTSC_RGB_OUT( 6, line_out[16*(offset/4) + (offset%4)], SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 6, line_out[offset++], SMS_NTSC_OUT_DEPTH );
if ((offset % 4) == 0) offset += 12;
#else #else
SMS_NTSC_RGB_OUT( 4, *line_out++, SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 4, *line_out++, SMS_NTSC_OUT_DEPTH );
SMS_NTSC_RGB_OUT( 5, *line_out++, SMS_NTSC_OUT_DEPTH ); SMS_NTSC_RGB_OUT( 5, *line_out++, SMS_NTSC_OUT_DEPTH );

View File

@ -147,14 +147,7 @@ struct sms_ntsc_t {
/* x is always zero except in snes_ntsc library */ /* x is always zero except in snes_ntsc library */
#define SMS_NTSC_RGB_OUT_( rgb_out, bits, x ) {\ #define SMS_NTSC_RGB_OUT_( rgb_out, bits, x ) {\
if ( bits == 16 )\
rgb_out = (raw_>>(13-x)& 0xF800)|(raw_>>(8-x)&0x07E0)|(raw_>>(4-x)&0x001F);\ rgb_out = (raw_>>(13-x)& 0xF800)|(raw_>>(8-x)&0x07E0)|(raw_>>(4-x)&0x001F);\
if ( bits == 24 || bits == 32 )\
rgb_out = (raw_>>(5-x)&0xFF0000)|(raw_>>(3-x)&0xFF00)|(raw_>>(1-x)&0xFF);\
if ( bits == 15 )\
rgb_out = (raw_>>(14-x)& 0x7C00)|(raw_>>(9-x)&0x03E0)|(raw_>>(4-x)&0x001F);\
if ( bits == 0 )\
rgb_out = raw_ << x;\
} }
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -126,13 +126,14 @@ int system_frame (int do_skip)
int end_line = vdp_height + bitmap.viewport.y; int end_line = vdp_height + bitmap.viewport.y;
int start_line = lines_per_frame - bitmap.viewport.y; int start_line = lines_per_frame - bitmap.viewport.y;
int old_interlaced = interlaced; int old_interlaced = interlaced;
interlaced = (reg[12] >> 1) & 3; interlaced = (reg[12] & 2) >> 1;
if (old_interlaced != interlaced) if (old_interlaced != interlaced)
{ {
bitmap.viewport.changed = 2; bitmap.viewport.changed = 2;
im2_flag = (interlaced == 3); im2_flag = ((reg[12] & 6) == 6);
odd_frame = 1; odd_frame = 1;
} }
odd_frame ^= 1; odd_frame ^= 1;
/* clear VBLANK and DMA flags */ /* clear VBLANK and DMA flags */

View File

@ -396,6 +396,12 @@ static inline void dma_vbus (void)
} }
else else
{ {
/* SVP latency */
if (svp && (source < 0x400000))
{
source = (source - 2);
}
/* ROM & RAM */ /* ROM & RAM */
do do
{ {