Bug #241 - AppleWin 1.26 NTSC -- Fix "ANSI STORY" so horz scroll works, fix vert scroll so it mostly works, verified "Rainbow" works

This commit is contained in:
michaelangel007 2015-01-03 03:31:19 -08:00
parent b96b3fe1d4
commit ce94b59663
4 changed files with 105 additions and 77 deletions

View File

@ -38,6 +38,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "Memory.h"
#include "Mockingboard.h"
#include "MouseInterface.h"
#include "NTSC.h"
#include "NoSlotClock.h"
#include "ParallelPrinter.h"
#include "Registry.h"
@ -230,7 +231,7 @@ static BYTE __stdcall IORead_C01x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG
case 0x6: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
case 0x7: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
case 0x8: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
case 0x9: return VideoCheckVbl(pc, addr, bWrite, d, nCyclesLeft);
case 0x9: return VideoCheckVbl( nCyclesLeft ); // NTSC cleanup
case 0xA: return VideoCheckMode(pc, addr, bWrite, d, nCyclesLeft);
case 0xB: return VideoCheckMode(pc, addr, bWrite, d, nCyclesLeft);
case 0xC: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
@ -1477,13 +1478,25 @@ void MemResetPaging()
BYTE MemReadFloatingBus(const ULONG uExecutedCycles)
{
return*(LPBYTE)(mem + VideoGetScannerAddress(NULL, uExecutedCycles));
// NTSC: It is tempting to replace with
// return NTSC_VideoGetByte( uExecutedCycles );
// But that breaks "Rainbow" Bug #254
// Why is this out of sync??
//uint8_t val1 = NTSC_VideoGetByte( uExecutedCycles );
//uint8_t val2 = *(LPBYTE)(mem + VideoGetScannerAddress(NULL, uExecutedCycles));
//if( val1 != val2 ) mem[ 0x2000 ] ^= 0xFF;
return *(LPBYTE)(mem + VideoGetScannerAddress(NULL, uExecutedCycles));
}
//===========================================================================
BYTE MemReadFloatingBus(const BYTE highbit, const ULONG uExecutedCycles)
{
// NTSC: It is tempting to replace with
// return NTSC_VideoGetByte( uExecutedCycles );
// But that breaks "Rainbow" Bug #254
// BYTE r= NTSC_VideoGetByte( uExecutedCycles );
BYTE r = *(LPBYTE)(mem + VideoGetScannerAddress(NULL, uExecutedCycles));
return (r & ~0x80) | ((highbit) ? 0x80 : 0);
}

View File

@ -65,7 +65,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#endif
#endif
// Types
struct ColorSpace_PAL_t // Phase Amplitute Luma
@ -142,6 +141,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
static UpdateScreenFunc_t g_apFuncVideoUpdateScanline[VIDEO_SCANNER_Y_DISPLAY];
static UpdateScreenFunc_t g_pFuncUpdateTextScreen = 0; // updateScreenText40;
static UpdateScreenFunc_t g_pFuncUpdateGraphicsScreen = 0; // updateScreenText40;
static UpdateScreenFunc_t g_pFuncModeSwitchDelayed = 0;
static UpdateScreenFunc_t g_aFuncUpdateHorz [VIDEO_SCANNER_MAX_HORZ]; // ANSI STORY: DGR80/TEXT80 vert/horz scrolll switches video mode mid-scan line!
static uint32_t g_aHorzClockVideoMode [VIDEO_SCANNER_MAX_HORZ]; // ANSI STORY: DGR80/TEXT80 vert/horz scrolll switches video mode mid-scan line!
typedef void (*UpdatePixelFunc_t)(uint16_t);
static UpdatePixelFunc_t g_pFuncUpdateBnWPixel = 0; //updatePixelBnWMonitorSingleScanline;
@ -404,6 +407,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
inline void updateFramebufferMonitorSingleScanline( uint16_t signal, bgra_t *pTable );
inline void updateFramebufferMonitorDoubleScanline( uint16_t signal, bgra_t *pTable );
inline void updatePixels( uint16_t bits );
inline bool updateScanLineModeSwitch( long cycles6502, UpdateScreenFunc_t self );
inline void updateVideoScannerHorzEOL();
inline void updateVideoScannerAddress();
@ -660,6 +664,25 @@ inline void updatePixels( uint16_t bits )
}
}
//===========================================================================
inline bool updateScanLineModeSwitch( long cycles6502, UpdateScreenFunc_t self )
{
bool bBail = false;
if( g_aHorzClockVideoMode[ g_nVideoClockHorz ] != g_aHorzClockVideoMode[ g_nVideoClockHorz+1 ] && !g_nVideoMixed ) // !g_nVideoMixed for "Rainbow"
{
UpdateScreenFunc_t pFunc = g_aFuncUpdateHorz[ g_nVideoClockHorz ];
if( pFunc && pFunc != self )
{
g_pFuncUpdateGraphicsScreen = pFunc;
// g_pFuncUpdateTextScreen = pFunc; // No, as we can't break mixed mode for "Rainbow"
pFunc( cycles6502 );
bBail = true;
}
}
return bBail;
}
//===========================================================================
inline void updateVideoScannerHorzEOL()
{
@ -711,6 +734,12 @@ inline void updateVideoScannerAddress()
g_nColorPhaseNTSC = INITIAL_COLOR_PHASE;
g_nLastColumnPixelNTSC = 0;
g_nSignalBitsNTSC = 0;
// ANSI STORY: clear mode and pointer to draw func
memset( g_aFuncUpdateHorz , 0, sizeof( g_aFuncUpdateHorz ) );
memset( g_aHorzClockVideoMode, 0, sizeof( g_aHorzClockVideoMode ) );
g_aFuncUpdateHorz[0] = g_pFuncUpdateGraphicsScreen;
}
// Non-Inline _________________________________________________________
@ -1014,7 +1043,7 @@ void updateScreenDoubleHires40 (long cycles6502) // wsUpdateVideoHires0
return;
}
for (; cycles6502; --cycles6502)
for (; cycles6502 > 0; --cycles6502)
{
UpdateVideoAddressHGR();
@ -1026,6 +1055,8 @@ void updateScreenDoubleHires40 (long cycles6502) // wsUpdateVideoHires0
}
else if (g_nVideoClockHorz >= VIDEO_SCANNER_HORZ_START)
{
if ( updateScanLineModeSwitch( cycles6502, updateScreenDoubleHires40 ) ) return; // ANSI STORY: vide mode switch mid scan line!
uint8_t *pMain = MemGetMainPtr(ad);
uint8_t m = pMain[0];
uint16_t bits = g_aPixelDoubleMaskHGR[m & 0x7F]; // Optimization: hgrbits second 128 entries are mirror of first 128
@ -1048,7 +1079,7 @@ void updateScreenDoubleHires80 (long cycles6502 ) // wsUpdateVideoDblHires
return;
}
for (; cycles6502; --cycles6502)
for (; cycles6502 > 0; --cycles6502)
{
UpdateVideoAddressHGR();
@ -1060,6 +1091,8 @@ void updateScreenDoubleHires80 (long cycles6502 ) // wsUpdateVideoDblHires
}
else if (g_nVideoClockHorz >= VIDEO_SCANNER_HORZ_START)
{
if ( updateScanLineModeSwitch( cycles6502, updateScreenDoubleHires80 ) ) return; // ANSI STORY: vide mode switch mid scan line!
uint8_t *pMain = MemGetMainPtr(ad);
uint8_t *pAux = MemGetAuxPtr(ad);
@ -1087,7 +1120,7 @@ void updateScreenDoubleLores40 (long cycles6502) // wsUpdateVideo7MLores
return;
}
for (; cycles6502; --cycles6502)
for (; cycles6502 > 0; --cycles6502)
{
UpdateVideoAddressTXT();
@ -1099,6 +1132,8 @@ void updateScreenDoubleLores40 (long cycles6502) // wsUpdateVideo7MLores
}
else if (g_nVideoClockHorz >= VIDEO_SCANNER_HORZ_START)
{
if ( updateScanLineModeSwitch( cycles6502, updateScreenDoubleLores40 ) ) return; // ANSI STORY: vide mode switch mid scan line!
uint8_t *pMain = MemGetMainPtr(ad);
uint8_t m = pMain[0];
uint16_t lo = getLoResBits( m );
@ -1121,7 +1156,7 @@ void updateScreenDoubleLores80 (long cycles6502) // wsUpdateVideoDblLores
return;
}
for (; cycles6502; --cycles6502)
for (; cycles6502 > 0; --cycles6502)
{
UpdateVideoAddressTXT();
@ -1133,6 +1168,8 @@ void updateScreenDoubleLores80 (long cycles6502) // wsUpdateVideoDblLores
}
else if (g_nVideoClockHorz >= VIDEO_SCANNER_HORZ_START)
{
if( updateScanLineModeSwitch( cycles6502, updateScreenDoubleLores80 ) ) return; // ANSI STORY: vide mode switch mid scan line!
uint8_t *pMain = MemGetMainPtr(ad);
uint8_t *pAux = MemGetAuxPtr(ad);
@ -1147,9 +1184,11 @@ void updateScreenDoubleLores80 (long cycles6502) // wsUpdateVideoDblLores
uint16_t bits = (main << 7) | (aux & 0x7f);
updatePixels( bits );
g_nLastColumnPixelNTSC = (bits >> 14) & 3;
}
}
updateVideoScannerHorzEOL();
}
}
@ -1164,7 +1203,7 @@ void updateScreenSingleHires40 (long cycles6502)
return;
}
for (; cycles6502; --cycles6502)
for (; cycles6502 > 0; --cycles6502)
{
UpdateVideoAddressHGR();
@ -1176,6 +1215,8 @@ void updateScreenSingleHires40 (long cycles6502)
}
else if (g_nVideoClockHorz >= VIDEO_SCANNER_HORZ_START)
{
if ( updateScanLineModeSwitch( cycles6502, updateScreenSingleHires40 ) ) return; // ANSI STORY: vide mode switch mid scan line!
uint8_t *pMain = MemGetMainPtr(ad);
uint8_t m = pMain[0];
uint16_t bits = g_aPixelDoubleMaskHGR[m & 0x7F]; // Optimization: hgrbits second 128 entries are mirror of first 128
@ -1199,7 +1240,7 @@ void updateScreenSingleLores40 (long cycles6502)
return;
}
for (; cycles6502; --cycles6502)
for (; cycles6502 > 0; --cycles6502)
{
UpdateVideoAddressTXT();
@ -1211,6 +1252,8 @@ void updateScreenSingleLores40 (long cycles6502)
}
else if (g_nVideoClockHorz >= VIDEO_SCANNER_HORZ_START)
{
if( updateScanLineModeSwitch( cycles6502, updateScreenSingleLores40 ) ) return; // ANSI STORY: vide mode switch mid scan line!
uint8_t *pMain = MemGetMainPtr(ad);
uint8_t m = pMain[0];
uint16_t lo = getLoResBits( m );
@ -1227,7 +1270,7 @@ void updateScreenText40 (long cycles6502)
{
unsigned ad;
for (; cycles6502; --cycles6502)
for (; cycles6502 > 0; --cycles6502)
{
UpdateVideoAddressTXT();
@ -1240,6 +1283,8 @@ void updateScreenText40 (long cycles6502)
{
if (g_nVideoClockHorz >= VIDEO_SCANNER_HORZ_START)
{
if ( updateScanLineModeSwitch( cycles6502, updateScreenText40 ) ) return; // ANSI STORY: vide mode switch mid scan line!
uint8_t *pMain = MemGetMainPtr(ad);
uint8_t m = pMain[0];
uint8_t c = getCharSetBits(m);
@ -1247,6 +1292,7 @@ void updateScreenText40 (long cycles6502)
if (0 == g_nVideoCharSet && 0x40 == (m & 0xC0))
bits ^= g_nTextFlashMask;
updatePixels( bits );
}
}
updateVideoScannerHorzEOL();
@ -1258,7 +1304,7 @@ void updateScreenText80 (long cycles6502)
{
unsigned int ad;
for (; cycles6502; --cycles6502)
for (; cycles6502 > 0; --cycles6502)
{
UpdateVideoAddressTXT();
@ -1271,6 +1317,8 @@ void updateScreenText80 (long cycles6502)
{
if (g_nVideoClockHorz >= VIDEO_SCANNER_HORZ_START)
{
if ( updateScanLineModeSwitch( cycles6502, updateScreenText80 ) ) return; // ANSI STORY: vide mode switch mid scan line!
uint8_t *pAux = MemGetAuxPtr(ad);
uint8_t *pMain = MemGetMainPtr(ad);
@ -1308,6 +1356,11 @@ void NTSC_SetVideoTextMode( int cols )
//===========================================================================
void NTSC_SetVideoMode( int bVideoModeFlags )
{
int h = g_nVideoClockHorz;
// int h = (g_dwCyclesThisFrame + 40) % 65;
g_aHorzClockVideoMode[ h ] = bVideoModeFlags;
g_nVideoMixed = bVideoModeFlags & VF_MIXED;
g_nVideoCharSet = g_nAltCharSetOffset != 0;
@ -1320,6 +1373,8 @@ void NTSC_SetVideoMode( int bVideoModeFlags )
}
}
UpdateScreenFunc_t pPrevUpdate = g_pFuncUpdateGraphicsScreen;
if (bVideoModeFlags & VF_TEXT) {
if (bVideoModeFlags & VF_80COL)
g_pFuncUpdateGraphicsScreen = updateScreenText80;
@ -1344,6 +1399,16 @@ void NTSC_SetVideoMode( int bVideoModeFlags )
else
g_pFuncUpdateGraphicsScreen = updateScreenSingleLores40;
}
#if 0
g_aFuncUpdateHorz[ g_nVideoClockHorz ] = g_pFuncUpdateGraphicsScreen; // ANSI STORY
if( g_nVideoClockHorz >= VIDEO_SCANNER_HORZ_START )
g_pFuncUpdateGraphicsScreen = pPrevUpdate;
else
g_aFuncUpdateHorz[0] = g_pFuncUpdateGraphicsScreen;
#else
g_aFuncUpdateHorz[ h ] = g_pFuncUpdateGraphicsScreen; // NTSC: ANSI STORY
#endif
}
//===========================================================================
@ -1514,6 +1579,10 @@ void NTSC_VideoInitAppleType ()
g_pHorzClockOffset = APPLE_IIE_HORZ_CLOCK_OFFSET;
else
g_pHorzClockOffset = APPLE_IIP_HORZ_CLOCK_OFFSET;
g_nVideoClockVert = 0;
g_nVideoClockHorz = 0;
}
//===========================================================================
@ -1528,10 +1597,11 @@ void NTSC_VideoUpdateCycles( long cycles6502 )
{
bool bRedraw = cycles6502 >= VIDEO_SCANNER_6502_CYCLES;
// if( g_bFullSpeed )
// g_pFuncUpdateGraphicsScreen( cycles6502 );
// else
// if( !g_bFullSpeed )
if(true)
g_pFuncUpdateGraphicsScreen( cycles6502 );
else
{
while( cycles6502 > VIDEO_SCANNER_6502_CYCLES )
/* */ cycles6502 -= VIDEO_SCANNER_6502_CYCLES ;
@ -1567,3 +1637,4 @@ void NTSC_VideoUpdateCycles( long cycles6502 )
g_pFuncUpdateGraphicsScreen( nCyclesVBlank );
}
}
}

View File

@ -227,8 +227,6 @@ int const kVLine0State = 0x100; // V[543210CBA] = 100000000
int const kVPresetLine = 256; // line when V state presets
int const kVSyncLines = 4; // lines per VSync duration
static BYTE celldirty[40][32]; // [TC: 27/06/2014] NB. No longer used!
// NUM_COLOR_PALETTE
static COLORREF customcolors[256]; // MONOCHROME is last custom color
static HBITMAP g_hDeviceBitmap;
@ -249,14 +247,6 @@ static LPBYTE g_aSourceStartofLine[ MAX_SOURCE_Y ];
static LPBYTE g_pTextBank1; // Aux
static LPBYTE g_pTextBank0; // Main
// For tv emulation HGR Video Mode
// 2 extra scan lines on bottom?
static BYTE hgrpixelmatrix[FRAMEBUFFER_W/2][FRAMEBUFFER_H/2 + 2 * HGR_MATRIX_YOFFSET];
static BYTE colormixbuffer[6];
static WORD colormixmap[6][6][6];
//
static /*bool*/ UINT g_VideoForceFullRedraw = 1;
static bool g_bVideoUpdatedThisFrame = false;
@ -895,10 +885,12 @@ BYTE VideoCheckMode (WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles)
*/
BYTE VideoCheckVbl (WORD, WORD, BYTE, BYTE, ULONG uExecutedCycles)
BYTE VideoCheckVbl ( ULONG uExecutedCycles )
{
//bool bVblBar = VideoGetVbl(uExecutedCycles);
bool bVblBar = NTSC_VideoIsVbl();
bool bVblBar = VideoGetVbl(uExecutedCycles);
// NTSC: It is tempting to replace with
// bool bVblBar = NTSC_VideoIsVbl();
// But this breaks "ANSI STORY"
BYTE r = KeybGetKeycode();
return (r & ~0x80) | (bVblBar ? 0x80 : 0);
@ -1080,47 +1072,6 @@ void VideoDisplayLogo ()
//===========================================================================
void VideoRealizePalette(HDC dc)
{
#if 0
if( g_bIsFullScreen )
{
if( !g_pDDPal )
{
PALETTEENTRY aPal[256];
BYTE *pSrc = ((BYTE*)g_pFramebufferinfo) + sizeof(BITMAPINFOHEADER);
BYTE *pDst = ((BYTE*)aPal);
int iPal;
for(iPal = 0; iPal < 256; iPal++ )
{
*(pDst + 0) = *(pSrc + 2); // BGR -> RGB
*(pDst + 1) = *(pSrc + 1);
*(pDst + 2) = *(pSrc + 0);
*(pDst + 3) = 0;
pDst += 4;
pSrc += 4;
}
if (g_pDD->CreatePalette(DDPCAPS_8BIT, aPal, &g_pDDPal, NULL) != DD_OK)
{
g_pDDPal = NULL;
}
}
if (g_pDDPal)
{
g_pDDPrimarySurface->SetPalette(g_pDDPal); // this sets the palette for the primary surface
}
}
else
{
if (g_hPalette)
{
SelectPalette(dc,g_hPalette,0);
RealizePalette(dc);
}
}
#endif
if (g_hPalette)
{
SelectPalette(dc,g_hPalette,0);
@ -1137,12 +1088,6 @@ void VideoRedrawScreen ()
VideoRefreshScreen( g_uVideoMode );
}
//===========================================================================
void _Video_Dirty()
{
ZeroMemory(celldirty,40*32);
}
//===========================================================================
int _Video_SetupBanks( bool bBank2 )
{

View File

@ -94,7 +94,6 @@ bool VideoGetSWAltCharSet(void);
void VideoSetForceFullRedraw(void);
void _Video_Dirty();
int _Video_SetupBanks( bool bBank2 );
bool Update40ColCell (int x, int y, int xpixel, int ypixel, int offset);
bool Update80ColCell (int x, int y, int xpixel, int ypixel, int offset);
@ -116,7 +115,7 @@ void Video_TakeScreenShot( int iScreenShotType );
// Win32/MSVC: __stdcall
BYTE VideoCheckMode (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG uExecutedCycles);
BYTE VideoCheckVbl (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG uExecutedCycles);
BYTE VideoCheckVbl ( ULONG uExecutedCycles );
BYTE VideoSetMode (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG uExecutedCycles);
void Config_Load_Video(void);