NTSC: Improve method 2

This commit is contained in:
tomcw 2017-06-19 22:03:00 +01:00
parent 6641d3ad66
commit 9ea931ee0e
3 changed files with 74 additions and 51 deletions

View File

@ -139,7 +139,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
typedef void (*UpdateScreenFunc_t)(long);
static UpdateScreenFunc_t g_pFuncUpdateTextScreen = 0; // updateScreenText40;
static UpdateScreenFunc_t g_pFuncUpdateGraphicsScreen = 0; // updateScreenText40;
typedef void (*UpdateScreenFunc2_t)(UINT, BYTE*);
typedef void (*UpdateScreenFunc1_t)(UINT, BYTE*);
static UpdateScreenFunc1_t g_pFuncUpdateTextScreen1 = 0; // updateScreenText40;
static UpdateScreenFunc1_t g_pFuncUpdateGraphicsScreen1 = 0; // updateScreenText40;
struct VideoLineItem2;
typedef void (*UpdateScreenFunc2_t)(VideoLineItem2*&);
static UpdateScreenFunc2_t g_pFuncUpdateTextScreen2 = 0; // updateScreenText40;
static UpdateScreenFunc2_t g_pFuncUpdateGraphicsScreen2 = 0; // updateScreenText40;
@ -441,6 +447,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
static void updateScreenText80 ( long cycles6502 );
static void InitVideoLineItem1(void);
static void PreInitVideoLineItem2(void);
static void InitVideoLineItem2(void);
//===========================================================================
@ -1403,7 +1410,7 @@ void updateScreenText40 (long cycles6502)
}
}
void updateScreenText40_2(UINT cycles6502, BYTE* pVideoData)
void updateScreenText40_1(UINT cycles6502, BYTE* pVideoData)
{
for (; cycles6502 > 0; --cycles6502)
{
@ -1419,6 +1426,33 @@ void updateScreenText40_2(UINT cycles6502, BYTE* pVideoData)
}
}
struct VideoLineItem2
{
UINT videoMode;
UpdateScreenFunc2_t func;
BYTE data[2];
};
void updateScreenText40_2(VideoLineItem2*& pVideoData)
{
const UINT videoMode = pVideoData->videoMode;
do
{
uint8_t m = pVideoData->data[0];
uint8_t c = getCharSetBits(m);
uint16_t bits = g_aPixelDoubleMaskHGR[c & 0x7F]; // Optimization: hgrbits second 128 entries are mirror of first 128
if (0 == g_nVideoCharSet && 0x40 == (m & 0xC0)) // Flash only if mousetext not active
bits ^= g_nTextFlashMask;
updatePixels( bits );
pVideoData++;
}
while (videoMode == pVideoData->videoMode);
}
//===========================================================================
void updateScreenText80 (long cycles6502)
{
@ -1567,6 +1601,7 @@ void NTSC_SetVideoMode( uint32_t uVideoModeFlags )
g_pFuncUpdateGraphicsScreen = updateScreenSingleLores40;
}
g_pFuncUpdateGraphicsScreen1 = updateScreenText40_1;
g_pFuncUpdateGraphicsScreen2 = updateScreenText40_2;
}
@ -1761,6 +1796,7 @@ void NTSC_VideoReinitialize( DWORD cyclesThisFrame )
updateVideoScannerAddress(); // Pre-condition: g_nVideoClockVert
InitVideoLineItem1();
PreInitVideoLineItem2();
InitVideoLineItem2();
}
@ -1859,7 +1895,7 @@ void NTSC_SetFullSpeedEvent(bool bStartFullSpeed)
//-------------------------------------
//const UINT kVideoMode_Invalid = (UINT)-1;
const UINT kVideoMode_Invalid = (UINT)-1;
struct VideoLineData
{
@ -1870,9 +1906,8 @@ struct VideoLineData
struct VideoLineItem1
{
UINT videoMode;
int videoCharSet;
UINT numCycles;
UpdateScreenFunc2_t func;
UpdateScreenFunc1_t func;
VideoLineData data[1]; // variable length
};
@ -1883,9 +1918,8 @@ static VideoLineData* g_pVideoLineNextData1 = NULL;
static void SetVideoLineItem1(void)
{
g_pVideoLineItem1->videoMode = g_uVideoMode;
g_pVideoLineItem1->videoCharSet = g_nVideoCharSet;
g_pVideoLineItem1->numCycles = 0;
g_pVideoLineItem1->func = g_pFuncUpdateGraphicsScreen2;
g_pVideoLineItem1->func = g_pFuncUpdateGraphicsScreen1;
}
static void InitVideoLineItem1(void)
@ -1916,7 +1950,7 @@ static void VideoRenderLine1( void )
// if (pItem->videoMode == kVideoMode_Invalid) // Eg. FullSpeed off
// break;
g_nVideoCharSet = pItem->videoCharSet;
g_nVideoCharSet = (pItem->videoMode & VF_ALTCHARSET) ? 1 : 0;
pItem->func( pItem->numCycles, (BYTE*)&pItem->data[0] );
@ -1957,7 +1991,7 @@ static void VideoBuildLine1( int cycles )
if (g_nVideoClockHorz > VIDEO_SCANNER_HORZ_START)
{
if (g_pVideoLineItem1->videoMode != g_uVideoMode || g_pVideoLineItem1->videoCharSet != g_nVideoCharSet)
if (g_pVideoLineItem1->videoMode != g_uVideoMode)
NextVideoLineItem1();
}
@ -2003,24 +2037,18 @@ static void VideoBuildLine1( int cycles )
//===========================================================================
struct VideoLineItem2
{
UINT videoMode;
int videoCharSet;
UpdateScreenFunc2_t func;
BYTE data[2];
};
static VideoLineItem2 g_videoLine2[40] = {0xff}; // 40 display bytes (NB. Init to 0xff so that videoMode is invalid)
static VideoLineItem2 g_videoLine2[41];
static VideoLineItem2* g_pVideoLineItem2 = NULL;
static void PreInitVideoLineItem2(void)
{
g_videoLine2[40].videoMode = kVideoMode_Invalid; // 41st item has videoMode == kVideoMode_Invalid
}
static void InitVideoLineItem2(void)
{
g_pVideoLineItem2 = &g_videoLine2[0];
g_bDontRenderVideoLine = false;
// g_pVideoLineItem2->videoMode = g_uVideoMode;
// g_pVideoLineItem2->videoCharSet = g_nVideoCharSet;
// g_pVideoLineItem2->func = g_pFuncUpdateGraphicsScreen2;
}
static void VideoRenderLine2( void )
@ -2029,17 +2057,13 @@ static void VideoRenderLine2( void )
VideoLineItem2* pItem = &g_videoLine2[0];
for (UINT i=0; i<40; i++)
do
{
// if (pItem->videoMode == kVideoMode_Invalid) // Eg. FullSpeed off
// break;
g_nVideoCharSet = (pItem->videoMode & VF_ALTCHARSET) ? 1 : 0;
// TODO: Accumulate for same videomode/charset
g_nVideoCharSet = pItem->videoCharSet;
pItem->func( 1, &pItem->data[0] );
pItem++;
pItem->func(pItem);
}
while (pItem->videoMode != kVideoMode_Invalid);
g_nVideoCharSet = currCharSet;
}
@ -2088,7 +2112,6 @@ static void VideoBuildLine2( int cycles )
}
g_pVideoLineItem2->videoMode = g_uVideoMode;
g_pVideoLineItem2->videoCharSet = g_nVideoCharSet;
g_pVideoLineItem2->func = g_pFuncUpdateGraphicsScreen2;
g_pVideoLineItem2->data[0] = *pMain++;

View File

@ -194,6 +194,7 @@ const BYTE DoubleHiresPalIndex[16] = {
#define SW_MIXED (g_uVideoMode & VF_MIXED)
#define SW_PAGE2 (g_uVideoMode & VF_PAGE2)
#define SW_TEXT (g_uVideoMode & VF_TEXT)
#define SW_ALTCHARSET (g_uVideoMode & VF_ALTCHARSET)
#define SETSOURCEPIXEL(x,y,c) g_aSourceStartofLine[(y)][(x)] = (c)
@ -207,7 +208,6 @@ const BYTE DoubleHiresPalIndex[16] = {
// Globals (Public)
uint8_t *g_pFramebufferbits = NULL; // last drawn frame
int g_nAltCharSetOffset = 0; // alternate character set
// Globals (Private)
@ -761,12 +761,12 @@ BYTE VideoCheckMode (WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles)
else {
BOOL result = 0;
switch (address) {
case 0x1A: result = SW_TEXT; break;
case 0x1B: result = SW_MIXED; break;
case 0x1D: result = SW_HIRES; break;
case 0x1E: result = g_nAltCharSetOffset; break;
case 0x1F: result = SW_80COL; break;
case 0x7F: result = SW_DHIRES; break;
case 0x1A: result = SW_TEXT; break;
case 0x1B: result = SW_MIXED; break;
case 0x1D: result = SW_HIRES; break;
case 0x1E: result = SW_ALTCHARSET; break;
case 0x1F: result = SW_80COL; break;
case 0x7F: result = SW_DHIRES; break;
}
return KeybGetKeycode() | (result ? 0x80 : 0);
}
@ -1202,7 +1202,6 @@ void VideoReinitialize ()
//===========================================================================
void VideoResetState ()
{
g_nAltCharSetOffset = 0;
g_uVideoMode = VF_TEXT;
NTSC_SetVideoTextMode( 40 );
@ -1222,8 +1221,8 @@ BYTE VideoSetMode (WORD, WORD address, BYTE write, BYTE, ULONG uExecutedCycles)
case 0x01: g_uVideoMode |= VF_80STORE; break;
case 0x0C: if (!IS_APPLE2){g_uVideoMode &= ~VF_80COL; NTSC_SetVideoTextMode(40);}; break;
case 0x0D: if (!IS_APPLE2){g_uVideoMode |= VF_80COL; NTSC_SetVideoTextMode(80);}; break;
case 0x0E: if (!IS_APPLE2) g_nAltCharSetOffset = 0; break; // Alternate char set off
case 0x0F: if (!IS_APPLE2) g_nAltCharSetOffset = 256; break; // Alternate char set on
case 0x0E: if (!IS_APPLE2) g_uVideoMode &= ~VF_ALTCHARSET; break;
case 0x0F: if (!IS_APPLE2) g_uVideoMode |= VF_ALTCHARSET; break;
case 0x50: g_uVideoMode &= ~VF_TEXT; break;
case 0x51: g_uVideoMode |= VF_TEXT; break;
case 0x52: g_uVideoMode &= ~VF_MIXED; break;
@ -1287,15 +1286,15 @@ bool VideoGetSWTEXT(void)
bool VideoGetSWAltCharSet(void)
{
return g_nAltCharSetOffset != 0;
return SW_ALTCHARSET ? true : false;
}
//===========================================================================
void VideoSetSnapshot_v1(const UINT AltCharSet, const UINT VideoMode)
{
g_nAltCharSetOffset = !AltCharSet ? 0 : 256;
g_uVideoMode = VideoMode;
g_uVideoMode |= AltCharSet ? VF_ALTCHARSET : 0;
g_dwCyclesThisFrame = 0;
}
@ -1314,7 +1313,7 @@ static std::string VideoGetSnapshotStructName(void)
void VideoSaveSnapshot(YamlSaveHelper& yamlSaveHelper)
{
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", VideoGetSnapshotStructName().c_str());
yamlSaveHelper.SaveBool(SS_YAML_KEY_ALTCHARSET, g_nAltCharSetOffset ? true : false);
yamlSaveHelper.SaveBool(SS_YAML_KEY_ALTCHARSET, VideoGetSWAltCharSet());
yamlSaveHelper.SaveHexUint32(SS_YAML_KEY_VIDEOMODE, g_uVideoMode);
yamlSaveHelper.SaveUint(SS_YAML_KEY_CYCLESTHISFRAME, g_dwCyclesThisFrame);
}
@ -1324,8 +1323,8 @@ void VideoLoadSnapshot(YamlLoadHelper& yamlLoadHelper)
if (!yamlLoadHelper.GetSubMap(VideoGetSnapshotStructName()))
return;
g_nAltCharSetOffset = yamlLoadHelper.LoadBool(SS_YAML_KEY_ALTCHARSET) ? 256 : 0;
g_uVideoMode = yamlLoadHelper.LoadUint(SS_YAML_KEY_VIDEOMODE);
g_uVideoMode |= yamlLoadHelper.LoadBool(SS_YAML_KEY_ALTCHARSET) ? VF_ALTCHARSET : 0;
g_dwCyclesThisFrame = yamlLoadHelper.LoadUint(SS_YAML_KEY_CYCLESTHISFRAME);
yamlLoadHelper.PopMap();

View File

@ -21,13 +21,14 @@
enum VideoFlag_e
{
VF_80COL = 0x00000001,
VF_DHIRES = 0x00000002,
VF_HIRES = 0x00000004,
VF_80STORE= 0x00000008, // was called VF_MASK2
VF_MIXED = 0x00000010,
VF_PAGE2 = 0x00000020,
VF_TEXT = 0x00000040
VF_80COL = 0x00000001,
VF_DHIRES = 0x00000002,
VF_HIRES = 0x00000004,
VF_80STORE = 0x00000008, // was called VF_MASK2
VF_MIXED = 0x00000010,
VF_PAGE2 = 0x00000020,
VF_TEXT = 0x00000040,
VF_ALTCHARSET = 0x00000080
};
enum AppleFont_e