diff --git a/source/Memory.cpp b/source/Memory.cpp index 1451efb7..56c36b00 100644 --- a/source/Memory.cpp +++ b/source/Memory.cpp @@ -1480,18 +1480,23 @@ BYTE MemReadFloatingBus(const ULONG uExecutedCycles) { #if 0 // NTSC: It is tempting to replace with - // return NTSC_VideoGetByte( uExecutedCycles ); - // But that breaks "Rainbow" Bug #254 - // Why is this out of sync?? - uint16_t a1 = NTSC_VideoGetScannerAddressByte( uExecutedCycles ); - uint16_t a2 = VideoGetScannerAddress(NULL, uExecutedCycles); - uint8_t b1 = mem[ a1 ]; - uint8_t b2 = mem[ a2 ]; + // return NTSC_VideoGetScannerAddress( uExecutedCycles ); + // But that breaks "Rainbow" Bug #254 if NTSC_VideoGetScannerAddress() is not correct. + // This is out of sync with VideoGetScannerAddress() due to two reasons: + // a) returning a cached copy of g_aHorzClockMemAddress + // Fixed by calling: updateVideoScannerAddressTXT or updateVideoScannerAddressHGR() + // b) A bug? in APPLE_IIE_HORZ_CLOCK_OFFSET[0][8] containing the incorrect value of 0x006F + uint16_t addr1 = NTSC_VideoGetScannerAddress( uExecutedCycles ); + uint16_t addr2 = VideoGetScannerAddress(NULL, uExecutedCycles); + uint8_t byte1 = mem[ addr1 ]; + uint8_t byte2 = mem[ addr2 ]; - if( val1 != val2 ) + if( byte1 != byte2 ) mem[ 0x2000 ] ^= 0xFF; #endif - return mem[ VideoGetScannerAddress(NULL, uExecutedCycles) ]; + // return mem[ VideoGetScannerAddress(NULL, uExecutedCycles) ]; + uint16_t addr = NTSC_VideoGetScannerAddress( uExecutedCycles ); + return mem[ addr ] ; // cycles is ignored } //=========================================================================== @@ -1499,7 +1504,7 @@ BYTE MemReadFloatingBus(const ULONG uExecutedCycles) BYTE MemReadFloatingBus(const BYTE highbit, const ULONG uExecutedCycles) { // NTSC: It is tempting to replace with - // return NTSC_VideoGetByte( uExecutedCycles ); + // return NTSC_VideoGetScannerAddress( uExecutedCycles ); // But that breaks "Rainbow" Bug #254 // BYTE r= NTSC_VideoGetByte( uExecutedCycles ); BYTE r = *(LPBYTE)(mem + VideoGetScannerAddress(NULL, uExecutedCycles)); diff --git a/source/NTSC.cpp b/source/NTSC.cpp index 5ef3f202..daeb4dda 100644 --- a/source/NTSC.cpp +++ b/source/NTSC.cpp @@ -291,7 +291,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA static unsigned APPLE_IIE_HORZ_CLOCK_OFFSET[5][VIDEO_SCANNER_MAX_HORZ] = { - {0x0068,0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x106F, // bug? 0x106F + {0x0068,0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F, // bug? 0x106F 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077, 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F, 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, @@ -746,7 +746,7 @@ inline void updateVideoScannerHorzEOL() g_nVideoClockVert = 0; updateFlashRate(); - //VideoRefreshScreen(0); // ContinueExecution() calls VideoRefreshScreen(0) ever dwClksPerFrame (17030) + //VideoRefreshScreen(0); // ContinueExecution() calls VideoRefreshScreen(0) every dwClksPerFrame (17030) } if (g_nVideoClockVert < VIDEO_SCANNER_Y_DISPLAY) @@ -1392,7 +1392,7 @@ void updateScreenText80 (long cycles6502) } } -// Functions (Public) _________________________________________________ +// Functions (Public) _____________________________________________________________________________ //=========================================================================== void NTSC_SetVideoTextMode( int cols ) @@ -1407,7 +1407,6 @@ void NTSC_SetVideoTextMode( int cols ) void NTSC_SetVideoMode( int bVideoModeFlags ) { int h = g_nVideoClockHorz; -// int h = (g_dwCyclesThisFrame + 40) % 65; g_aHorzClockVideoMode[ h ] = bVideoModeFlags; @@ -1417,6 +1416,8 @@ void NTSC_SetVideoMode( int bVideoModeFlags ) g_nTextPage = 1; g_nHiresPage = 1; if (bVideoModeFlags & VF_PAGE2) { + // Apple IIe, Techical Nodtes, #3: Double High-Resolution Graphics + // 80STORE must be OFF to display page 2 if (0 == (bVideoModeFlags & VF_80STORE)) { g_nTextPage = 2; g_nHiresPage = 2; @@ -1553,9 +1554,16 @@ _mono: //=========================================================================== uint16_t NTSC_VideoGetScannerAddress ( unsigned long cycles6502 ) { - (void)cycles6502; // TODO: Do we need to offset based on the clock cycles? - // uint8_t h = (g_nVideoClockHorz + cycles6502) % VIDEO_SCANNER_MAX_HORZ - return g_aHorzClockMemAddress[ g_nVideoClockHorz ]; + (void)cycles6502; + + int nHires = (g_uVideoMode & VF_HIRES) && !(g_uVideoMode & VF_TEXT); // (SW_HIRES && !SW_TEXT) ? 1 : 0; + if( nHires ) + updateVideoScannerAddressHGR(); + else + updateVideoScannerAddressTXT(); + + // Required for ANSI STORY vert scrolling mid-scanline mixed mode: DGR80, TEXT80, DGR80 + return g_aHorzClockMemAddress[ (g_nVideoClockHorz+VIDEO_SCANNER_MAX_HORZ-2)%VIDEO_SCANNER_MAX_HORZ ]; // Optimization: (h-2) } //=========================================================================== diff --git a/source/Video.cpp b/source/Video.cpp index 94aef201..52aa8366 100644 --- a/source/Video.cpp +++ b/source/Video.cpp @@ -255,7 +255,7 @@ COLORREF g_nMonochromeRGB = RGB(0xC0,0xC0,0xC0); static BOOL rebuiltsource = 0; static LPBYTE vidlastmem = NULL; -static UINT g_uVideoMode = VF_TEXT; + 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_uHalfScanLines = 1; // drop 50% scan lines for a more authentic look @@ -1196,8 +1196,9 @@ void VideoResetState () BYTE VideoSetMode (WORD, WORD address, BYTE write, BYTE, ULONG uExecutedCycles) { address &= 0xFF; - DWORD oldpage2 = SW_PAGE2; - int oldvalue = g_nAltCharSetOffset+(int)(g_uVideoMode & ~(VF_80STORE | VF_PAGE2)); + +// DWORD oldpage2 = SW_PAGE2; +// int oldvalue = g_nAltCharSetOffset+(int)(g_uVideoMode & ~(VF_80STORE | VF_PAGE2)); switch (address) { @@ -1219,13 +1220,16 @@ BYTE VideoSetMode (WORD, WORD address, BYTE write, BYTE, ULONG uExecutedCycles) case 0x5F: if (!IS_APPLE2) g_uVideoMode &= ~VF_DHIRES; break; } + // Apple IIe, Techical Nodtes, #3: Double High-Resolution Graphics + // 80STORE must be OFF to display page 2 + if (SW_80STORE) + g_uVideoMode &= ~VF_PAGE2; + // NTSC_BEGIN NTSC_SetVideoMode( g_uVideoMode ); // NTSC_END #if 0 // NTSC_CLEANUP: Is this still needed?? - if (SW_80STORE) - g_uVideoMode &= ~VF_PAGE2; if (oldvalue != g_nAltCharSetOffset+(int)(g_uVideoMode & ~(VF_80STORE | VF_PAGE2))) g_VideoForceFullRedraw = 1; // Defer video redraw until VideoEndOfVideoFrame() diff --git a/source/Video.h b/source/Video.h index 090b9cad..142e4314 100644 --- a/source/Video.h +++ b/source/Video.h @@ -58,7 +58,8 @@ extern HBITMAP g_hLogoBitmap; extern COLORREF g_nMonochromeRGB; // saved -extern DWORD g_eVideoType; // saved +extern uint32_t g_uVideoMode ; +extern DWORD g_eVideoType ; // saved extern DWORD g_uHalfScanLines; // saved extern uint8_t *g_pFramebufferbits; extern int g_nAltCharSetOffset; // alternate character set