diff --git a/source/NTSC.cpp b/source/NTSC.cpp index 07d24e5e..e538bf86 100644 --- a/source/NTSC.cpp +++ b/source/NTSC.cpp @@ -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++; diff --git a/source/Video.cpp b/source/Video.cpp index 295ef026..8af39c01 100644 --- a/source/Video.cpp +++ b/source/Video.cpp @@ -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(); diff --git a/source/Video.h b/source/Video.h index a2878826..f723c17f 100644 --- a/source/Video.h +++ b/source/Video.h @@ -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