diff --git a/source/NTSC.cpp b/source/NTSC.cpp index 72f045a4..b97b5b6b 100644 --- a/source/NTSC.cpp +++ b/source/NTSC.cpp @@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // Includes #include "StdAfx.h" #include "Applewin.h" - #include "CPU.h" + #include "CPU.h" // CpuGetCyclesThisVideoFrame() #include "Frame.h" // FRAMEBUFFER_W FRAMEBUFFER_H #include "Memory.h" // MemGetMainPtr() MemGetBankPtr() #include "Video.h" // g_pFramebufferbits @@ -41,9 +41,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "ntsc_rgb.h" #endif - //LPBYTE MemGetMainPtr(const WORD); - //LPBYTE MemGetBankPtr(const UINT nBank); - // Defines #define HGR_TEST_PATTERN 0 @@ -199,8 +196,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define SIGNAL_1 0.7465656072f // Tables - static unsigned short g_aClockVertOffsetsHGR[ VIDEO_SCANNER_MAX_VERT ]; + // Video scanner tables are now runtime-generated using UTAIIe logic + static unsigned short g_aClockVertOffsetsHGR[VIDEO_SCANNER_MAX_VERT]; + static unsigned short g_aClockVertOffsetsTXT[33]; + static unsigned short APPLE_IIP_HORZ_CLOCK_OFFSET[5][VIDEO_SCANNER_MAX_HORZ]; + static unsigned short APPLE_IIE_HORZ_CLOCK_OFFSET[5][VIDEO_SCANNER_MAX_HORZ]; +#ifdef _DEBUG static unsigned short g_kClockVertOffsetsHGR[ VIDEO_SCANNER_MAX_VERT ] = { 0x0000,0x0400,0x0800,0x0C00,0x1000,0x1400,0x1800,0x1C00,0x0080,0x0480,0x0880,0x0C80,0x1080,0x1480,0x1880,0x1C80, @@ -226,8 +228,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 0x0B80,0x0F80,0x1380,0x1780,0x1B80,0x1F80 }; - static unsigned short g_aClockVertOffsetsTXT[33]; - static unsigned short g_kClockVertOffsetsTXT[33] = { 0x0000,0x0080,0x0100,0x0180,0x0200,0x0280,0x0300,0x0380, @@ -238,8 +238,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 0x380 }; - static unsigned short APPLE_IIP_HORZ_CLOCK_OFFSET[5][VIDEO_SCANNER_MAX_HORZ]; - static unsigned short kAPPLE_IIP_HORZ_CLOCK_OFFSET[5][VIDEO_SCANNER_MAX_HORZ] = { {0x1068,0x1068,0x1069,0x106A,0x106B,0x106C,0x106D,0x106E,0x106F, @@ -288,8 +286,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F} }; - static unsigned short APPLE_IIE_HORZ_CLOCK_OFFSET[5][VIDEO_SCANNER_MAX_HORZ]; - static unsigned short kAPPLE_IIE_HORZ_CLOCK_OFFSET[5][VIDEO_SCANNER_MAX_HORZ] = { {0x0068,0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F, @@ -337,6 +333,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017, 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F} }; +#endif /* http://www.kreativekorp.com/miscpages/a2info/munafo.shtml @@ -397,11 +394,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA static csbits_t csbits; // charset, optionally followed by alt charset // Prototypes - // prototype from CPU.h - //unsigned char CpuRead(unsigned short addr, unsigned long uExecutedCycles); - // prototypes from Memory.h - //unsigned char * MemGetAuxPtr (unsigned short); - //unsigned char * MemGetMainPtr (unsigned short); INLINE float clampZeroOne( const float & x ); INLINE uint8_t getCharSetBits( const int iChar ); INLINE uint16_t getLoResBits( uint8_t iByte ); @@ -419,8 +411,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA INLINE void updatePixels( uint16_t bits ); INLINE void updateVideoScannerHorzEOL(); INLINE void updateVideoScannerAddress(); - INLINE uint16_t updateVideoScannerAddressTXT(); - INLINE uint16_t updateVideoScannerAddressHGR(); + INLINE uint16_t getVideoScannerAddressTXT(); + INLINE uint16_t getVideoScannerAddressHGR(); static void initChromaPhaseTables(); static real initFilterChroma (real z); @@ -775,16 +767,16 @@ inline void updateVideoScannerAddress() } //=========================================================================== -INLINE uint16_t updateVideoScannerAddressTXT() +INLINE uint16_t getVideoScannerAddressTXT() { return (g_aClockVertOffsetsTXT[g_nVideoClockVert/8] + g_pHorzClockOffset [g_nVideoClockVert/64][g_nVideoClockHorz] + (g_nTextPage * 0x400)); } //=========================================================================== -INLINE uint16_t updateVideoScannerAddressHGR() +INLINE uint16_t getVideoScannerAddressHGR() { - // NB. Not a bug: For both A2 and //e then use APPLE_IIE_HORZ_CLOCK_OFFSET - see VideoGetScannerAddress() where only TEXT mode adds $1000 + // NB. For both A2 and //e use APPLE_IIE_HORZ_CLOCK_OFFSET - see VideoGetScannerAddress() where only TEXT mode adds $1000 return (g_aClockVertOffsetsHGR[g_nVideoClockVert ] + APPLE_IIE_HORZ_CLOCK_OFFSET[g_nVideoClockVert/64][g_nVideoClockHorz] + (g_nHiresPage * 0x2000)); } @@ -1142,7 +1134,7 @@ void updateScreenDoubleHires40 (long cycles6502) // wsUpdateVideoHires0 for (; cycles6502 > 0; --cycles6502) { - uint16_t addr = updateVideoScannerAddressHGR(); + uint16_t addr = getVideoScannerAddressHGR(); if (g_nVideoClockVert < VIDEO_SCANNER_Y_DISPLAY) { @@ -1173,7 +1165,7 @@ void updateScreenDoubleHires80 (long cycles6502 ) // wsUpdateVideoDblHires for (; cycles6502 > 0; --cycles6502) { - uint16_t addr = updateVideoScannerAddressHGR(); + uint16_t addr = getVideoScannerAddressHGR(); if (g_nVideoClockVert < VIDEO_SCANNER_Y_DISPLAY) { @@ -1210,7 +1202,7 @@ void updateScreenDoubleLores40 (long cycles6502) // wsUpdateVideo7MLores for (; cycles6502 > 0; --cycles6502) { - uint16_t addr = updateVideoScannerAddressTXT(); + uint16_t addr = getVideoScannerAddressTXT(); if (g_nVideoClockVert < VIDEO_SCANNER_Y_DISPLAY) { @@ -1242,7 +1234,7 @@ void updateScreenDoubleLores80 (long cycles6502) // wsUpdateVideoDblLores for (; cycles6502 > 0; --cycles6502) { - uint16_t addr = updateVideoScannerAddressTXT(); + uint16_t addr = getVideoScannerAddressTXT(); if (g_nVideoClockVert < VIDEO_SCANNER_Y_DISPLAY) { @@ -1283,7 +1275,7 @@ void updateScreenSingleHires40 (long cycles6502) for (; cycles6502 > 0; --cycles6502) { - uint16_t addr = updateVideoScannerAddressHGR(); + uint16_t addr = getVideoScannerAddressHGR(); if (g_nVideoClockVert < VIDEO_SCANNER_Y_DISPLAY) { @@ -1324,7 +1316,7 @@ void updateScreenSingleLores40 (long cycles6502) for (; cycles6502 > 0; --cycles6502) { - uint16_t addr = updateVideoScannerAddressTXT(); + uint16_t addr = getVideoScannerAddressTXT(); if (g_nVideoClockVert < VIDEO_SCANNER_Y_DISPLAY) { @@ -1350,7 +1342,7 @@ void updateScreenText40 (long cycles6502) { for (; cycles6502 > 0; --cycles6502) { - uint16_t addr = updateVideoScannerAddressTXT(); + uint16_t addr = getVideoScannerAddressTXT(); if ((g_nVideoClockHorz < VIDEO_SCANNER_HORZ_COLORBURST_END) && (g_nVideoClockHorz >= VIDEO_SCANNER_HORZ_COLORBURST_BEG)) { @@ -1382,7 +1374,7 @@ void updateScreenText80 (long cycles6502) { for (; cycles6502 > 0; --cycles6502) { - uint16_t addr = updateVideoScannerAddressTXT(); + uint16_t addr = getVideoScannerAddressTXT(); if ((g_nVideoClockHorz < VIDEO_SCANNER_HORZ_COLORBURST_END) && (g_nVideoClockHorz >= VIDEO_SCANNER_HORZ_COLORBURST_BEG)) { @@ -1477,9 +1469,9 @@ uint16_t NTSC_VideoGetScannerAddress ( const ULONG uExecutedCycles ) uint16_t addr; bool bHires = (g_uVideoMode & VF_HIRES) && !(g_uVideoMode & VF_TEXT); // SW_HIRES && !SW_TEXT if( bHires ) - addr = updateVideoScannerAddressHGR(); + addr = getVideoScannerAddressHGR(); else - addr = updateVideoScannerAddressTXT(); + addr = getVideoScannerAddressTXT(); g_nVideoClockVert = currVideoClockVert; g_nVideoClockHorz = currVideoClockHorz; @@ -1839,55 +1831,93 @@ bool NTSC_GetColorBurst( void ) } //=========================================================================== -void GenerateVideoTables( void ) + +static bool CheckVideoTables2( eApple2Type type, uint32_t mode ) +{ + SetApple2Type(type); + NTSC_VideoInitAppleType(); + + g_uVideoMode = mode; + + g_dwCyclesThisFrame = 0; + g_nVideoClockHorz = g_nVideoClockVert = 0; + + for (DWORD cycles=0; cycles= kVPresetLine)) // check for previous vertical state preset + if (nVLine >= kVPresetLine) // check for previous vertical state preset { nVState -= nScanLines; // compensate for preset } @@ -835,6 +850,8 @@ WORD VideoGetScannerAddress(bool* pbVblBar_OUT, DWORD nCycles) nAddress |= h_1 << 1; // a1 nAddress |= h_2 << 2; // a2 nAddress |= nSum << 3; // a3 - a6 + g_PartialH = nAddress; + nAddress |= v_0 << 7; // a7 nAddress |= v_1 << 8; // a8 nAddress |= v_2 << 9; // a9 @@ -849,6 +866,8 @@ WORD VideoGetScannerAddress(bool* pbVblBar_OUT, DWORD nCycles) nAddress |= v_A << 10; // a10 nAddress |= v_B << 11; // a11 nAddress |= v_C << 12; // a12 + g_PartialV = nAddress - g_PartialH; + nAddress |= p2a << 13; // a13 nAddress |= p2b << 14; // a14 } @@ -856,24 +875,23 @@ WORD VideoGetScannerAddress(bool* pbVblBar_OUT, DWORD nCycles) { // N: insert text-only address bits // - nAddress |= p2a << 10; // a10 - nAddress |= p2b << 11; // a11 + g_PartialV = nAddress - g_PartialH; // Apple ][ (not //e) and HBL? // if (IS_APPLE2 && // Apple II only (UTAIIe:I-4,#5) !h_5 && (!h_4 || !h_3)) // HBL (UTAIIe:8-10,F8.5) { - nAddress |= 1 << 12; // Y: a12 (add $1000 to address!) + nAddress |= 1 << 12; // Y: a12 (add $1000 to address!) + g_PartialH |= 1 << 12; } - } - // update VBL' state - // - if (pbVblBar_OUT != NULL) - { - *pbVblBar_OUT = !v_4 || !v_3; // VBL' = (v_4 & v_3)' (UTAIIe:5-10,#3) + nAddress |= p2a << 10; // a10 + nAddress |= p2b << 11; // a11 } + + // VBL' = v_4' | v_3' = (v_4 & v_3)' (UTAIIe:5-10,#3) + return static_cast(nAddress); } diff --git a/source/Video.h b/source/Video.h index 1e133a11..3bacb655 100644 --- a/source/Video.h +++ b/source/Video.h @@ -169,7 +169,9 @@ void VideoRedrawScreen (void); void VideoRefreshScreen (uint32_t uRedrawWholeScreenVideoMode = 0, bool bRedrawWholeScreen = false); void VideoReinitialize (); void VideoResetState (); -WORD VideoGetScannerAddress(bool* pbVblBar_OUT, const DWORD uExecutedCycles); +WORD VideoGetScannerAddressPartialV(DWORD nCycles); +WORD VideoGetScannerAddressPartialH(DWORD nCycles); +WORD VideoGetScannerAddress(DWORD nCycles); bool VideoGetVblBar(DWORD uExecutedCycles); bool VideoGetSW80COL(void);