diff --git a/source/Applewin.cpp b/source/Applewin.cpp index 6f630871..a69336f8 100644 --- a/source/Applewin.cpp +++ b/source/Applewin.cpp @@ -192,6 +192,7 @@ void ContinueExecution(void) ? g_bScrollLock_FullSpeed : (GetKeyState(VK_SCROLL) < 0); + const bool bWasFullSpeed = g_bFullSpeed; g_bFullSpeed = ( (g_dwSpeed == SPEED_MAX) || bScrollLock_FullSpeed || (DiskIsSpinning() && enhancedisk && !Spkr_IsActive() && !MB_IsActive()) ); @@ -213,6 +214,9 @@ void ContinueExecution(void) } else { + if (bWasFullSpeed) + VideoRedrawScreenAfterFullSpeed(g_dwCyclesThisFrame); + // Don't call Spkr_Demute() MB_Demute(); SysClk_StartTimerUsec(nExecutionPeriodUsec); diff --git a/source/CPU/cpu6502.h b/source/CPU/cpu6502.h index b2a25e67..14fe7a24 100644 --- a/source/CPU/cpu6502.h +++ b/source/CPU/cpu6502.h @@ -44,7 +44,6 @@ static DWORD Cpu6502 (DWORD uTotalCycles) BYTE iOpcode; // NTSC_BEGIN - ULONG uElapsedCycles; ULONG uPreviousCycles = uExecutedCycles; // NTSC_END @@ -321,8 +320,11 @@ static DWORD Cpu6502 (DWORD uTotalCycles) } // NTSC_BEGIN - uElapsedCycles = uExecutedCycles - uPreviousCycles; - NTSC_VideoUpdateCycles( uElapsedCycles ); + if (!g_bFullSpeed) + { + ULONG uElapsedCycles = uExecutedCycles - uPreviousCycles; + NTSC_VideoUpdateCycles( uElapsedCycles ); + } // NTSC_END CheckInterruptSources(uExecutedCycles); diff --git a/source/CPU/cpu65C02.h b/source/CPU/cpu65C02.h index d9ad28c5..0a1cec26 100644 --- a/source/CPU/cpu65C02.h +++ b/source/CPU/cpu65C02.h @@ -47,7 +47,6 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) BYTE iOpcode; // NTSC_BEGIN - ULONG uElapsedCycles; ULONG uPreviousCycles = uExecutedCycles; // NTSC_END @@ -324,8 +323,11 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) } // NTSC_BEGIN - uElapsedCycles = uExecutedCycles - uPreviousCycles; - NTSC_VideoUpdateCycles( uElapsedCycles ); + if (!g_bFullSpeed) + { + ULONG uElapsedCycles = uExecutedCycles - uPreviousCycles; + NTSC_VideoUpdateCycles( uElapsedCycles ); + } // NTSC_END CheckInterruptSources(uExecutedCycles); diff --git a/source/CPU/cpu65d02.h b/source/CPU/cpu65d02.h index 7c3d34ed..8d72bbcd 100644 --- a/source/CPU/cpu65d02.h +++ b/source/CPU/cpu65d02.h @@ -121,7 +121,6 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) BYTE iOpcode; // NTSC_BEGIN - ULONG uElapsedCycles; ULONG uPreviousCycles = uExecutedCycles; // NTSC_END @@ -409,8 +408,11 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) #undef $ // NTSC_BEGIN - uElapsedCycles = uExecutedCycles - uPreviousCycles; - NTSC_VideoUpdateCycles( uElapsedCycles ); + if (!g_bFullSpeed) + { + ULONG uElapsedCycles = uExecutedCycles - uPreviousCycles; + NTSC_VideoUpdateCycles( uElapsedCycles ); + } // NTSC_END CheckInterruptSources(uExecutedCycles); diff --git a/source/Debugger/Debug.cpp b/source/Debugger/Debug.cpp index a985c577..d5892183 100644 --- a/source/Debugger/Debug.cpp +++ b/source/Debugger/Debug.cpp @@ -5095,7 +5095,7 @@ Update_t CmdNTSC (int nArgs) } }; - bool bColorTV = (g_eVideoType == VT_COLOR_TVEMU); + bool bColorTV = (g_eVideoType == VT_COLOR_TV); uint32_t* pChromaTable = NTSC_VideoGetChromaTable( false, bColorTV ); char aStatusText[64] = "Loaded"; @@ -7730,6 +7730,9 @@ bool InternalSingleStep () //=========================================================================== + +#define TRACELINE_WITH_VIDEO_SCANNER_POS 0 + void OutputTraceLine () { DisasmLine_t line; @@ -7747,8 +7750,13 @@ void OutputTraceLine () g_bTraceHeader = false; fprintf( g_hTraceFile, +#if TRACELINE_WITH_VIDEO_SCANNER_POS +// "0000 0000 00 00 00 0000 -------- 0000:90 90 90 NOP" + "Vert Horz A: X: Y: SP: Flags Addr:Opcode Mnemonic\n" +#else // "00 00 00 0000 -------- 0000:90 90 90 NOP" "A: X: Y: SP: Flags Addr:Opcode Mnemonic\n" +#endif ); } @@ -7761,6 +7769,21 @@ void OutputTraceLine () ); } +#if TRACELINE_WITH_VIDEO_SCANNER_POS + fprintf( g_hTraceFile, +// "a=%02x x=%02x y=%02x sp=%03x ps=%s %s\n", + "%04X %04X %02X %02X %02X %04X %s %s\n", + g_nVideoClockVert, + g_nVideoClockHorz, + (unsigned)regs.a, + (unsigned)regs.x, + (unsigned)regs.y, + (unsigned)regs.sp, + (char*) sFlags + , sDisassembly + //, sTarget // TODO: Show target? + ); +#else fprintf( g_hTraceFile, // "a=%02x x=%02x y=%02x sp=%03x ps=%s %s\n", "%02X %02X %02X %04X %s %s\n", @@ -7772,6 +7795,7 @@ void OutputTraceLine () , sDisassembly //, sTarget // TODO: Show target? ); +#endif } } diff --git a/source/Debugger/Debugger_Assembler.cpp b/source/Debugger/Debugger_Assembler.cpp index 4c2730cd..3acc73bd 100644 --- a/source/Debugger/Debugger_Assembler.cpp +++ b/source/Debugger/Debugger_Assembler.cpp @@ -470,6 +470,10 @@ int _6502_GetOpmodeOpbyte ( const int nBaseAddress, int & iOpmode_, int & nOpby if (! g_aOpcodes) { MessageBox( g_hFrameWindow, "Debugger not properly initialized", "ERROR", MB_OK ); + + g_aOpcodes = & g_aOpcodes65C02[ 0 ]; // Enhanced Apple //e + g_aOpmodes[ AM_2 ].m_nBytes = 2; + g_aOpmodes[ AM_3 ].m_nBytes = 3; } #endif diff --git a/source/NTSC.cpp b/source/NTSC.cpp index 38f78394..1bc852b4 100644 --- a/source/NTSC.cpp +++ b/source/NTSC.cpp @@ -1525,7 +1525,7 @@ void NTSC_SetVideoStyle() // (int v, int s) switch ( g_eVideoType ) { - case VT_COLOR_TVEMU: // VT_COLOR_TV: // 0: + case VT_COLOR_TV: r = 0xFF; g = 0xFF; b = 0xFF; @@ -1541,7 +1541,7 @@ void NTSC_SetVideoStyle() // (int v, int s) } break; - case VT_COLOR_STANDARD: // VT_COLOR_MONITOR: //1: + case VT_COLOR_MONITOR: default: r = 0xFF; g = 0xFF; @@ -1558,7 +1558,7 @@ void NTSC_SetVideoStyle() // (int v, int s) } break; - case VT_COLOR_TEXT_OPTIMIZED: // VT_MONO_TV: //2: + case VT_MONO_TV: r = 0xFF; g = 0xFF; b = 0xFF; @@ -1591,7 +1591,7 @@ void NTSC_SetVideoStyle() // (int v, int s) b = 0xFF; goto _mono; - case VT_MONO_HALFPIXEL_REAL: + case VT_MONO_CUSTOM: // From WinGDI.h // #define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) //#define GetRValue(rgb) (LOBYTE(rgb)) diff --git a/source/Video.cpp b/source/Video.cpp index c8159944..30a1b8cb 100644 --- a/source/Video.cpp +++ b/source/Video.cpp @@ -258,7 +258,7 @@ static LPBYTE vidlastmem = NULL; uint32_t g_uVideoMode = VF_TEXT; // Current Video Mode (this is the last set one as it may change mid-scan line!) - DWORD g_eVideoType = VT_COLOR_TVEMU; + DWORD g_eVideoType = VT_COLOR_TV; DWORD g_uHalfScanLines = 1; // drop 50% scan lines for a more authentic look static bool bVideoScannerNTSC = true; // NTSC video scanning (or PAL) @@ -267,27 +267,26 @@ static bool bVideoScannerNTSC = true; // NTSC video scanning (or PAL) // NOTE: KEEP IN SYNC: VideoType_e g_aVideoChoices g_apVideoModeDesc TCHAR g_aVideoChoices[] = - TEXT("Monochrome (Custom Luminance)\0") - TEXT("Color (Standard)\0") - TEXT("Color (Text Optimized)\0") - TEXT("Color (TV emulation)\0") + TEXT("Monochrome (Custom)\0") + TEXT("Color Monitor\0") + TEXT("B&W TV\0") + TEXT("Color TV\0") TEXT("Monochrome (Amber)\0") TEXT("Monochrome (Green)\0") TEXT("Monochrome (White)\0") ; - // AppleWin 1.19.4 VT_COLOR_AUTHENTIC -> VT_COLOR_HALFPIXEL -> VT_COLOR_STANDARD "Color Half-Pixel Authentic // NOTE: KEEP IN SYNC: VideoType_e g_aVideoChoices g_apVideoModeDesc // The window title will be set to this. char *g_apVideoModeDesc[ NUM_VIDEO_MODES ] = { - "Monochrome (Custom)" - , "Standard" - , "Text Optimized" - , "TV" - , "Amber" - , "Green" - , "White" + "Monochrome Monitor (Custom)" + , "Color Monitor" + , "B&W TV" + , "Color TV" + , "Amber Monitor" + , "Green Monitor" + , "White Monitor" }; // Prototypes (Private) _____________________________________________ @@ -1094,6 +1093,18 @@ void VideoDisplayLogo () //=========================================================================== +void VideoRedrawScreenAfterFullSpeed(DWORD dwCyclesThisFrame) +{ + const int nScanLines = bVideoScannerNTSC ? kNTSCScanLines : kPALScanLines; + + g_nVideoClockVert = (uint16_t) (dwCyclesThisFrame / kHClocks) % nScanLines; + g_nVideoClockHorz = (uint16_t) (dwCyclesThisFrame % kHClocks); + + VideoRedrawScreen(); // Better (no flicker) than using: NTSC_VideoReinitialize() or VideoReinitialize() +} + +//=========================================================================== + void VideoRedrawScreen (UINT uDelayRefresh /* =0 */) { g_VideoForceFullRedraw = 1; @@ -1185,12 +1196,22 @@ void VideoRefreshScreen ( int bVideoModeFlags, UINT uDelayRefresh /* =0 */ ) yDst = (g_nDDFullScreenH-H)/2; } + int xSrc = BORDER_W; + int ySrc = BORDER_H; + + if (g_eVideoType == VT_MONO_TV || g_eVideoType == VT_COLOR_TV) + { + // Adjust the src locations for the NTSC video modes + xSrc += 2; + ySrc -= 1; + } + StretchBlt( hFrameDC, xDst, yDst, // xDst, yDst W, H, // wDst, hDst g_hDeviceDC, - BORDER_W, BORDER_H, // xSrc, ySrc + xSrc, ySrc, // xSrc, ySrc FRAMEBUFFER_BORDERLESS_W, FRAMEBUFFER_BORDERLESS_H, // wSrc, hSrc SRCCOPY ); } @@ -1397,6 +1418,7 @@ WORD VideoGetScannerAddress(bool* pbVblBar_OUT, const DWORD uExecutedCycles) int nScanLines = bVideoScannerNTSC ? kNTSCScanLines : kPALScanLines; int nVSyncLine = bVideoScannerNTSC ? kNTSCVSyncLine : kPALVSyncLine; int nScanCycles = nScanLines * kHClocks; + nCycles %= nScanCycles; // calculate horizontal scanning state // @@ -1502,6 +1524,8 @@ bool VideoGetVbl(const DWORD uExecutedCycles) // calculate video parameters according to display standard // int nScanLines = bVideoScannerNTSC ? kNTSCScanLines : kPALScanLines; + int nScanCycles = nScanLines * kHClocks; + nCycles %= nScanCycles; // calculate vertical scanning state // @@ -1783,7 +1807,7 @@ void Config_Load_Video() REGLOAD(TEXT(REGVALUE_VIDEO_MONO_COLOR ),&g_nMonochromeRGB); if (g_eVideoType >= NUM_VIDEO_MODES) - g_eVideoType = VT_COLOR_STANDARD; // Old default: VT_COLOR_TVEMU + g_eVideoType = VT_COLOR_MONITOR; } void Config_Save_Video() diff --git a/source/Video.h b/source/Video.h index a67acf58..d27708c4 100644 --- a/source/Video.h +++ b/source/Video.h @@ -6,13 +6,13 @@ // NOTE: Used/Serialized by: g_eVideoType enum VideoType_e { - VT_MONO_HALFPIXEL_REAL // uses custom monochrome - , VT_COLOR_STANDARD - , VT_COLOR_TEXT_OPTIMIZED - , VT_COLOR_TVEMU - , VT_MONO_AMBER // now half pixel - , VT_MONO_GREEN // now half pixel - , VT_MONO_WHITE // now half pixel + VT_MONO_CUSTOM + , VT_COLOR_MONITOR + , VT_MONO_TV + , VT_COLOR_TV + , VT_MONO_AMBER + , VT_MONO_GREEN + , VT_MONO_WHITE , NUM_VIDEO_MODES }; @@ -170,6 +170,7 @@ void VideoDrawLogoBitmap(HDC hDstDC, int xoff, int yoff, int srcw, int srch, void VideoDisplayLogo (); void VideoInitialize (); void VideoRealizePalette (HDC); +void VideoRedrawScreenAfterFullSpeed(DWORD dwCyclesThisFrame); void VideoRedrawScreen (UINT uDelayRefresh = 0); void VideoRefreshScreen (int bVideoFlags, UINT uDelayRefresh =0 ); void VideoReinitialize (); diff --git a/test/TestCPU6502/TestCPU6502.cpp b/test/TestCPU6502/TestCPU6502.cpp index df50fe55..a0644924 100644 --- a/test/TestCPU6502/TestCPU6502.cpp +++ b/test/TestCPU6502/TestCPU6502.cpp @@ -4,6 +4,7 @@ #include "../../source/CPU.h" // From Applewin.cpp +bool g_bFullSpeed = false; enum AppMode_e g_nAppMode = MODE_RUNNING; // From Memory.cpp