Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
0783c4ec1d
22 changed files with 255 additions and 276 deletions
|
@ -374,7 +374,7 @@
|
|||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;ddraw.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
||||
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
|
||||
</Link>
|
||||
|
@ -429,7 +429,7 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;ddraw.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
||||
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
|
||||
|
|
|
@ -8,6 +8,20 @@ https://github.com/AppleWin/AppleWin/issues/new
|
|||
|
||||
Tom Charlesworth
|
||||
|
||||
1.29.2.0 - 6 Sep 2019
|
||||
---------------------
|
||||
. [Change #678] Hotkeys to change emulation speed:
|
||||
- Ctrl-0 Toggles between custom speed and Full-Speed
|
||||
- Ctrl-1 Sets 1 MHz
|
||||
- Ctrl-3 Sets Full-Speed
|
||||
. [Change #671] Register .woz extension with AppleWin. Updated AppleWin.chm & DELREG.INF.
|
||||
. [Bug #685] Fixed support for French Touch's "CHIP" demo (Mockingboard / multi-TIMER interrupt support).
|
||||
. [Bug #677] Loading a save-state wasn't restoring the pending IRQ.
|
||||
. [Bug #672] For WOZ images: all even disk I/O read accesses will now read the data latch.
|
||||
. [Bug #650] NTSC TV (Color and B&W): image was half an Apple II scanline vertically shifted down.
|
||||
. [PR #674] Prevent uninitialized value bugs and improve string safety.
|
||||
|
||||
|
||||
1.29.1.0 - 27 Jul 2019
|
||||
----------------------
|
||||
. [Bug #662] Fixed WOZ 'Wizardry III' not booting.
|
||||
|
|
|
@ -1,6 +1,24 @@
|
|||
Requests (Wishlist):
|
||||
====================
|
||||
|
||||
* [ ] HELP BPM on read/write
|
||||
Nail down syntax:
|
||||
BPM A7 = R
|
||||
BPM A7 = W
|
||||
BPM R A7
|
||||
BPM W A7
|
||||
Add support 65D02 to break on read/write memory location
|
||||
|
||||
* [ ] HELP BPM
|
||||
Add help document and examples
|
||||
|
||||
* [ ] Fix BUG: (partial) symbols starting with E not parsed propery
|
||||
sym ErasePlayer1 = 65D3
|
||||
sym ErasePlayer
|
||||
Address not found: $000E
|
||||
|
||||
* [ ] Color code error messages in red foreground
|
||||
|
||||
- HELP CD: Document examples
|
||||
Helps needs to list:
|
||||
SEE: HELP PWD
|
||||
|
|
|
@ -16,11 +16,15 @@
|
|||
<p>This can be enabled manually or automatically in a variety of ways:</p>
|
||||
|
||||
<ul>
|
||||
<li>Permanently enable by the AppleWin <a href="cfg-config.html">Configuration</a> tab's 'Emulation Speed Control', and setting 'Custom Speed (in MHz)' to 'Fastest'.
|
||||
<li>Permanently enabled by the AppleWin <a href="cfg-config.html">Configuration</a> tab's 'Emulation Speed Control', and setting 'Custom Speed (in MHz)' to 'Fastest'.
|
||||
<li>Scroll Lock key: can be configured to toggle normal/full-speed mode, or only enable full-speed when pressed.
|
||||
<ul>
|
||||
<li>See <a href="cfg-input.html">Input</a> for configuring how Scroll Lock behaves.
|
||||
</ul>
|
||||
<li>Ctrl-0 & Ctrl-3: can be used to toggle custom/full-speed mode, or set full-speed mode respectively.
|
||||
<ul>
|
||||
<li>See <a href="keyboard.html">Using the Keyboard</a> for more information.
|
||||
</ul>
|
||||
<li>When 'Disk access speed' is set to 'Enhanced Speed' (the default), then whenever the Disk][ drive motor is on, the emulator will automatically switch to full-speed (and when the motor is switched off, then the emulator will automatically revert to what the 'Emulation Speed Control' has been set to).
|
||||
<ul>
|
||||
<li>See <a href="cfg-disk.html">Disk</a> for configuring 'Disk access speed'.
|
||||
|
|
|
@ -56,9 +56,16 @@
|
|||
<p><span style="font-weight: bold;">Scroll Lock:</span><br>
|
||||
<span style="font-style: italic;">Scroll Lock</span>
|
||||
key can be configured to toggle normal/full-speed mode, or only enable full-speed when pressed. See <a href="cfg-input.html">Input</a> for configuring how <span style="font-style: italic;">Scroll Lock</span> behaves.
|
||||
NOTE: The status of the PC's
|
||||
NOTE: The status of the PC's
|
||||
<span style="font-style: italic;">Scroll Lock</span>
|
||||
LED is meaningless.</p>
|
||||
<p><span style="font-weight: bold;">Ctrl+0, Ctrl+1, Ctrl+3:</span><br>
|
||||
Hotkeys to change emulation speed:
|
||||
<ul>
|
||||
<li>Ctrl-0 Toggles between custom speed and Full-Speed
|
||||
<li>Ctrl-1 Sets 1 MHz
|
||||
<li>Ctrl-3 Sets Full-Speed
|
||||
</ul>
|
||||
<p><span style="font-weight: bold;">Shift+Insert:</span><br>
|
||||
Paste text from Windows' clipboard. Text gets fed a character at a time to the
|
||||
Apple's keyboard hardware. The 'CR+LF' combination gets converted to CR.</p>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define APPLEWIN_VERSION 1,29,1,0
|
||||
#define APPLEWIN_VERSION 1,29,2,0
|
||||
|
||||
#define xstr(a) str(a)
|
||||
#define str(a) #a
|
||||
|
|
|
@ -60,7 +60,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "Configuration/PropertySheet.h"
|
||||
#include "Tfe/Tfe.h"
|
||||
|
||||
#define VERSIONSTRING_SIZE 16
|
||||
static const UINT VERSIONSTRING_SIZE = 16;
|
||||
|
||||
static UINT16 g_AppleWinVersion[4] = {0};
|
||||
static UINT16 g_OldAppleWinVersion[4] = {0};
|
||||
|
@ -545,8 +545,8 @@ void LoadConfiguration(void)
|
|||
|
||||
if (dwLoadedComputerType != dwComputerType)
|
||||
{
|
||||
char sText[ 100 ];
|
||||
_snprintf( sText, sizeof(sText)-1, "Unsupported Apple2Type(%d). Changing to %d", dwLoadedComputerType, dwComputerType);
|
||||
char sText[100];
|
||||
StringCbPrintf(sText, sizeof(sText), "Unsupported Apple2Type(%d). Changing to %d", dwLoadedComputerType, dwComputerType);
|
||||
|
||||
LogFileOutput("%s\n", sText);
|
||||
|
||||
|
|
|
@ -188,6 +188,11 @@ void SetActiveCpu(eCpuType cpu)
|
|||
g_ActiveCPU = cpu;
|
||||
}
|
||||
|
||||
bool Is6502InterruptEnabled(void)
|
||||
{
|
||||
return !(regs.ps & AF_INTERRUPT);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
#include "CPU/cpu_general.inl"
|
||||
|
@ -426,7 +431,8 @@ static __forceinline void CheckInterruptSources(ULONG uExecutedCycles, const boo
|
|||
}
|
||||
|
||||
MB_UpdateCycles(uExecutedCycles);
|
||||
sg_Mouse.SetVBlank( !VideoGetVblBar(uExecutedCycles) );
|
||||
if (sg_Mouse.IsActive())
|
||||
sg_Mouse.SetVBlank( !VideoGetVblBar(uExecutedCycles) );
|
||||
}
|
||||
|
||||
// GH#608: IRQ needs to occur within 17 cycles (6 opcodes) of configuring the timer interrupt
|
||||
|
|
|
@ -42,3 +42,5 @@ eCpuType ProbeMainCpuDefault(eApple2Type apple2Type);
|
|||
void SetMainCpuDefault(eApple2Type apple2Type);
|
||||
eCpuType GetActiveCpu(void);
|
||||
void SetActiveCpu(eCpuType cpu);
|
||||
|
||||
bool Is6502InterruptEnabled(void);
|
||||
|
|
|
@ -363,20 +363,17 @@ void CPageDisk::HandleHDDSwap(HWND hWnd)
|
|||
UINT CPageDisk::RemovalConfirmation(UINT uCommand)
|
||||
{
|
||||
TCHAR szText[100];
|
||||
const size_t strLen = sizeof(szText)-1;
|
||||
bool bMsgBox = true;
|
||||
|
||||
if (uCommand == IDC_COMBO_DISK1 || uCommand == IDC_COMBO_DISK2)
|
||||
_snprintf(szText, strLen, "Do you really want to eject the disk in drive-%c ?", '1' + uCommand - IDC_COMBO_DISK1);
|
||||
StringCbPrintf(szText, sizeof(szText), "Do you really want to eject the disk in drive-%c ?", '1' + uCommand - IDC_COMBO_DISK1);
|
||||
else if (uCommand == IDC_COMBO_HDD1 || uCommand == IDC_COMBO_HDD2)
|
||||
_snprintf(szText, strLen, "Do you really want to unplug harddisk-%c ?", '1' + uCommand - IDC_COMBO_HDD1);
|
||||
StringCbPrintf(szText, sizeof(szText), "Do you really want to unplug harddisk-%c ?", '1' + uCommand - IDC_COMBO_HDD1);
|
||||
else if (uCommand == IDC_HDD_SWAP)
|
||||
_snprintf(szText, strLen, "Do you really want to swap the harddisk images?");
|
||||
StringCbPrintf(szText, sizeof(szText), "Do you really want to swap the harddisk images?");
|
||||
else
|
||||
bMsgBox = false;
|
||||
|
||||
szText[strLen] = 0;
|
||||
|
||||
if (bMsgBox)
|
||||
{
|
||||
int nRes = MessageBox(g_hFrameWindow, szText, TEXT("Eject/Unplug Warning"), MB_ICONWARNING | MB_YESNO | MB_SETFOREGROUND);
|
||||
|
|
|
@ -6157,6 +6157,12 @@ Update_t CmdOutputCalc (int nArgs)
|
|||
nBit |= (1 << (iBit * 4)); // 4 bits per hex digit
|
||||
}
|
||||
|
||||
// TODO: Colorize output
|
||||
// CHC_NUM_HEX
|
||||
// CHC_NUM_BIN -- doesn't exist, use CHC_INFO
|
||||
// CHC_NUM_DEC
|
||||
// CHC_ARG_
|
||||
// CHC_STRING
|
||||
wsprintf( sText, TEXT("$%04X 0z%08X %5d '%c' "),
|
||||
nAddress, nBit, nAddress, c );
|
||||
|
||||
|
@ -6176,6 +6182,10 @@ Update_t CmdOutputCalc (int nArgs)
|
|||
_tcscat( sText, TEXT(")") );
|
||||
|
||||
ConsoleBufferPush( sText );
|
||||
|
||||
// If we colorize then w must also guard against character ouput $60
|
||||
// ConsolePrint( sText );
|
||||
|
||||
return ConsoleUpdate();
|
||||
}
|
||||
|
||||
|
|
|
@ -638,8 +638,7 @@ ImageError_e Disk2InterfaceCard::InsertDisk(const int drive, LPCTSTR pszImageFil
|
|||
if (Error == eIMAGE_ERROR_NONE && ImageIsMultiFileZip(pFloppy->m_imagehandle))
|
||||
{
|
||||
TCHAR szText[100+MAX_PATH];
|
||||
szText[sizeof(szText)-1] = 0;
|
||||
_snprintf(szText, sizeof(szText)-1, "Only the first file in a multi-file zip is supported\nUse disk image '%s' ?", pFloppy->m_strFilenameInZip.c_str());
|
||||
StringCbPrintf(szText, sizeof(szText), "Only the first file in a multi-file zip is supported\nUse disk image '%s' ?", pFloppy->m_strFilenameInZip.c_str());
|
||||
int nRes = MessageBox(g_hFrameWindow, szText, TEXT("Multi-Zip Warning"), MB_ICONWARNING | MB_YESNO | MB_SETFOREGROUND);
|
||||
if (nRes == IDNO)
|
||||
{
|
||||
|
|
|
@ -200,7 +200,7 @@ void SetAltEnterToggleFullScreen(bool mode)
|
|||
|
||||
UINT GetFrameBufferBorderlessWidth(void)
|
||||
{
|
||||
static const UINT uFrameBufferBorderlessW = NTSC_GetFrameBufferBorderlessWidth(); // 560 = Double Hi-Res, +1 for GH#555
|
||||
static const UINT uFrameBufferBorderlessW = 560; // 560 = Double Hi-Res
|
||||
return uFrameBufferBorderlessW;
|
||||
}
|
||||
|
||||
|
@ -246,6 +246,7 @@ UINT Get3DBorderHeight(void)
|
|||
}
|
||||
|
||||
// ==========================================================================
|
||||
|
||||
static void GetAppleWindowTitle()
|
||||
{
|
||||
static TCHAR g_pAppleWindowTitle[ 128 ] = "";
|
||||
|
@ -1392,7 +1393,38 @@ LRESULT CALLBACK FrameWndProc (
|
|||
if (!IsJoyKey &&
|
||||
(g_nAppMode != MODE_LOGO)) // !MODE_LOGO - not emulating so don't pass to the VM's keyboard
|
||||
{
|
||||
KeybQueueKeypress(wparam, NOT_ASCII);
|
||||
// GH#678 Alternate key(s) to toggle max speed
|
||||
// . Ctrl-0: Toggle speed: custom speed / Full-Speed
|
||||
// . Ctrl-1: Speed = 1 MHz
|
||||
// . Ctrl-3: Speed = Full-Speed
|
||||
bool keyHandled = false;
|
||||
if( KeybGetCtrlStatus() && wparam >= '0' && wparam <= '9' )
|
||||
{
|
||||
switch (wparam)
|
||||
{
|
||||
case '0': // Toggle speed: custom speed / Full-Speed
|
||||
if (g_dwSpeed == SPEED_MAX)
|
||||
REGLOAD_DEFAULT(TEXT(REGVALUE_EMULATION_SPEED), &g_dwSpeed, SPEED_NORMAL);
|
||||
else
|
||||
g_dwSpeed = SPEED_MAX;
|
||||
keyHandled = true; break;
|
||||
case '1': // Speed = 1 MHz
|
||||
g_dwSpeed = SPEED_NORMAL;
|
||||
REGSAVE(TEXT(REGVALUE_EMULATION_SPEED), g_dwSpeed);
|
||||
keyHandled = true; break;
|
||||
case '3': // Speed = Full-Speed
|
||||
g_dwSpeed = SPEED_MAX;
|
||||
keyHandled = true; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (keyHandled)
|
||||
SetCurrentCLK6502();
|
||||
}
|
||||
|
||||
if (!keyHandled)
|
||||
KeybQueueKeypress(wparam, NOT_ASCII);
|
||||
|
||||
if (!autorep)
|
||||
KeybAnyKeyDown(WM_KEYDOWN, wparam, extended);
|
||||
|
|
|
@ -413,17 +413,16 @@ BOOL HD_Insert(const int iDrive, LPCTSTR pszImageFilename)
|
|||
return g_HardDisk[iDrive].hd_imageloaded;
|
||||
}
|
||||
|
||||
static bool HD_SelectImage(const int iDrive, LPCSTR pszFilename)
|
||||
static bool HD_SelectImage(const int drive, LPCSTR pszFilename)
|
||||
{
|
||||
TCHAR directory[MAX_PATH];
|
||||
TCHAR filename[MAX_PATH];
|
||||
TCHAR title[40];
|
||||
|
||||
strcpy(filename, pszFilename);
|
||||
StringCbCopy(filename, MAX_PATH, pszFilename);
|
||||
|
||||
RegLoadString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_HDV_START_DIR), 1, directory, MAX_PATH, TEXT(""));
|
||||
_tcscpy(title, TEXT("Select HDV Image For HDD "));
|
||||
_tcscat(title, iDrive ? TEXT("2") : TEXT("1"));
|
||||
StringCbPrintf(title, 40, TEXT("Select HDV Image For HDD %d"), drive + 1);
|
||||
|
||||
_ASSERT(sizeof(OPENFILENAME) == sizeof(OPENFILENAME_NT4)); // Required for Win98/ME support (selected by _WIN32_WINNT=0x0400 in stdafx.h)
|
||||
|
||||
|
@ -445,9 +444,9 @@ static bool HD_SelectImage(const int iDrive, LPCSTR pszFilename)
|
|||
if (GetOpenFileName(&ofn))
|
||||
{
|
||||
if ((!ofn.nFileExtension) || !filename[ofn.nFileExtension])
|
||||
_tcscat(filename,TEXT(".hdv"));
|
||||
StringCbCat(filename, MAX_PATH, TEXT(".hdv"));
|
||||
|
||||
if (HD_Insert(iDrive, filename))
|
||||
if (HD_Insert(drive, filename))
|
||||
{
|
||||
bRes = true;
|
||||
}
|
||||
|
|
|
@ -1528,7 +1528,7 @@ void MemInitializeROM(void)
|
|||
}
|
||||
|
||||
TCHAR sText[MAX_PATH];
|
||||
_snprintf(sText, sizeof(sText)-1, TEXT("Unable to open the required firmware ROM data file.\n\nFile: %s"), sRomFileName);
|
||||
StringCbPrintf(sText, sizeof(sText), TEXT("Unable to open the required firmware ROM data file.\n\nFile: %s"), sRomFileName);
|
||||
|
||||
LogFileOutput("%s\n", sText);
|
||||
|
||||
|
|
|
@ -211,12 +211,18 @@ static const double g_f6522TimerPeriod_NoIRQ = CLK_6502_NTSC / 60.0; // Constant
|
|||
static bool g_bCritSectionValid = false; // Deleting CritialSection when not valid causes crash on Win98
|
||||
static CRITICAL_SECTION g_CriticalSection; // To guard 6522's IFR
|
||||
|
||||
// If we have 2 timer ints: 50Hz and 60Hz, then need to be able to determine the AY8910 reg update freq
|
||||
static bool g_waitFirstAYWriteAfterTimer1Int = false;
|
||||
static UINT64 g_lastAY8910cycleAccess = 0;
|
||||
static UINT64 g_AYWriteAccessTimer1IntPeriod = 0;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Forward refs:
|
||||
static DWORD WINAPI SSI263Thread(LPVOID);
|
||||
static void Votrax_Write(BYTE nDevice, BYTE nValue);
|
||||
static double MB_GetFramePeriod(void);
|
||||
static void MB_Update(void);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
@ -229,7 +235,7 @@ static void StartTimer1(SY6522_AY8910* pMB)
|
|||
|
||||
if (pMB->sy6522.IER & IxR_TIMER1) // Using 6522 interrupt
|
||||
g_nMBTimerDevice = pMB->nAY8910Number;
|
||||
else if (pMB->sy6522.ACR & RM_FREERUNNING) // Polling 6522 IFR
|
||||
else if (pMB->sy6522.ACR & RM_FREERUNNING) // Polling 6522 IFR (GH#496)
|
||||
g_nMBTimerDevice = pMB->nAY8910Number;
|
||||
}
|
||||
|
||||
|
@ -388,6 +394,19 @@ static void SY6522_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
|||
break;
|
||||
}
|
||||
|
||||
if (g_waitFirstAYWriteAfterTimer1Int) // GH#685: Multiple TIMER1 interrupts
|
||||
{
|
||||
g_waitFirstAYWriteAfterTimer1Int = false;
|
||||
//CpuCalcCycles(uExecutedCycles); // Done in parent MB_Write() via MB_UpdateCycles()
|
||||
|
||||
g_AYWriteAccessTimer1IntPeriod = g_nCumulativeCycles - g_lastAY8910cycleAccess;
|
||||
if (g_AYWriteAccessTimer1IntPeriod > 0xffff)
|
||||
g_AYWriteAccessTimer1IntPeriod = (UINT64)g_f6522TimerPeriod_NoIRQ;
|
||||
g_lastAY8910cycleAccess = g_nCumulativeCycles;
|
||||
|
||||
MB_Update();
|
||||
}
|
||||
|
||||
if(g_bPhasorEnable)
|
||||
{
|
||||
int nAY_CS = (g_nPhasorMode & 1) ? (~(nValue >> 3) & 3) : 1;
|
||||
|
@ -769,7 +788,8 @@ static void Votrax_Write(BYTE nDevice, BYTE nValue)
|
|||
// Called by:
|
||||
// . MB_UpdateCycles() - when g_nMBTimerDevice == {0,1,2,3}
|
||||
// . MB_EndOfVideoFrame() - when g_nMBTimerDevice == kTIMERDEVICE_INVALID
|
||||
static void MB_Update()
|
||||
// . SY6522_Write() - when multiple TIMER1s (interrupt sources) are active
|
||||
static void MB_Update(void)
|
||||
{
|
||||
//char szDbg[200];
|
||||
|
||||
|
@ -1475,6 +1495,10 @@ static void ResetState()
|
|||
g_nPhasorMode = 0;
|
||||
g_PhasorClockScaleFactor = 1;
|
||||
|
||||
g_waitFirstAYWriteAfterTimer1Int = false;
|
||||
g_lastAY8910cycleAccess = 0;
|
||||
g_AYWriteAccessTimer1IntPeriod = 0;
|
||||
|
||||
// Not these, as they don't change on a CTRL+RESET or power-cycle:
|
||||
// g_bMBAvailable = false;
|
||||
// g_SoundcardType = CT_Empty; // Don't uncomment, else _ASSERT will fire in MB_Read() after an F2->MB_Reset()
|
||||
|
@ -1773,7 +1797,7 @@ static bool CheckTimerUnderflowAndIrq(USHORT& timerCounter, int& timerIrqDelay,
|
|||
|
||||
// Called by:
|
||||
// . CpuExecute() every ~1000 @ 1MHz
|
||||
// . CheckInterruptSources() every 128 cycles
|
||||
// . CheckInterruptSources() every opcode (or every 40 opcodes at full-speed)
|
||||
// . MB_Read() / MB_Write()
|
||||
void MB_UpdateCycles(ULONG uExecutedCycles)
|
||||
{
|
||||
|
@ -1786,6 +1810,10 @@ void MB_UpdateCycles(ULONG uExecutedCycles)
|
|||
_ASSERT(uCycles < 0x10000);
|
||||
USHORT nClocks = (USHORT) uCycles;
|
||||
|
||||
UINT numActiveTimer1s = 0;
|
||||
for (int i=0; i<NUM_SY6522; i++)
|
||||
numActiveTimer1s += g_MB[i].bTimer1Active ? 1 : 0;
|
||||
|
||||
for (int i=0; i<NUM_SY6522; i++)
|
||||
{
|
||||
SY6522_AY8910* pMB = &g_MB[i];
|
||||
|
@ -1811,9 +1839,18 @@ void MB_UpdateCycles(ULONG uExecutedCycles)
|
|||
{
|
||||
UpdateIFR(pMB, 0, IxR_TIMER1);
|
||||
|
||||
// Do MB_Update() before StopTimer1()
|
||||
if (g_nMBTimerDevice == i)
|
||||
MB_Update();
|
||||
if (numActiveTimer1s == 1)
|
||||
{
|
||||
// Do MB_Update() before StopTimer1()
|
||||
if (g_nMBTimerDevice == i)
|
||||
MB_Update();
|
||||
}
|
||||
else // GH#685: Multiple TIMER1 interrupts
|
||||
{
|
||||
// Only allow when not in interrupt handler (ie. only allow when interrupts are enabled)
|
||||
if (Is6502InterruptEnabled())
|
||||
g_waitFirstAYWriteAfterTimer1Int = true; // Defer MB_Update() until MB_Write()
|
||||
}
|
||||
|
||||
if ((pMB->sy6522.ACR & RUNMODE) == RM_ONESHOT)
|
||||
{
|
||||
|
@ -1877,6 +1914,9 @@ static double MB_GetFramePeriod(void)
|
|||
// -> MB_GetFramePeriod()
|
||||
// NB. Removing this Phasor-IFR check means the occasional 'g_f6522TimerPeriod_NoIRQ' gets returned.
|
||||
|
||||
if (g_AYWriteAccessTimer1IntPeriod)
|
||||
return (double)g_AYWriteAccessTimer1IntPeriod;
|
||||
|
||||
if ((g_nMBTimerDevice != kTIMERDEVICE_INVALID) ||
|
||||
(g_bPhasorEnable && (g_MB[0].sy6522.IFR & IxR_TIMER1))) // [*1]
|
||||
{
|
||||
|
@ -2139,6 +2179,7 @@ bool MB_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version)
|
|||
throw std::string("Card: Expected key: ") + std::string(unit);
|
||||
|
||||
LoadSnapshotSY6522(yamlLoadHelper, pMB->sy6522, version);
|
||||
UpdateIFR(pMB, 0, pMB->sy6522.IFR); // Assert any pending IRQs (GH#677)
|
||||
AY8910_LoadSnapshot(yamlLoadHelper, nDeviceNum, std::string(""));
|
||||
LoadSnapshotSSI263(yamlLoadHelper, pMB->SpeechChip);
|
||||
|
||||
|
@ -2261,6 +2302,7 @@ bool Phasor_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version
|
|||
throw std::string("Card: Expected key: ") + std::string(unit);
|
||||
|
||||
LoadSnapshotSY6522(yamlLoadHelper, pMB->sy6522, version);
|
||||
UpdateIFR(pMB, 0, pMB->sy6522.IFR); // Assert any pending IRQs (GH#677)
|
||||
AY8910_LoadSnapshot(yamlLoadHelper, nDeviceNum+0, std::string("-A"));
|
||||
AY8910_LoadSnapshot(yamlLoadHelper, nDeviceNum+1, std::string("-B"));
|
||||
LoadSnapshotSSI263(yamlLoadHelper, pMB->SpeechChip);
|
||||
|
|
|
@ -473,8 +473,7 @@ void CMouseInterface::OnMouseEvent(bool bEventVBL)
|
|||
|
||||
void CMouseInterface::SetVBlank(bool bVBL)
|
||||
{
|
||||
if (!m_bActive)
|
||||
return;
|
||||
_ASSERT(m_bActive); // Only called from CheckInterruptSources(), which is guarded by an: if (sg_Mouse.IsActive())
|
||||
|
||||
if ( m_bVBL != bVBL )
|
||||
{
|
||||
|
@ -751,6 +750,9 @@ bool CMouseInterface::LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT sl
|
|||
m_bButtons[1] = yamlLoadHelper.LoadBool(SS_YAML_KEY_BUTTON1);
|
||||
m_bEnabled = yamlLoadHelper.LoadBool(SS_YAML_KEY_ENABLED); // MemInitializeIO() calls Initialize() which sets true
|
||||
|
||||
if (m_byState & STAT_INT_ALL) // GH#677
|
||||
CpuIrqAssert(IS_MOUSE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
304
source/NTSC.cpp
304
source/NTSC.cpp
|
@ -32,15 +32,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "NTSC_CharSet.h"
|
||||
|
||||
|
||||
// GH#555: Extend the 14M video modes by 1 pixel
|
||||
// . 14M (DHGR,DGR,80COL) are shifted right by 1 pixel, so zero out the left-most visible pixel.
|
||||
// . 7M (all other modes) are not shift right by 1 pixel, so zero out the right-most visible pixel.
|
||||
// NB. This 1 pixel shift is a workaround for the 14M video modes that actually start 7x 14M pixels to the left on *real h/w*.
|
||||
// . 7x 14M pixels early + 1x 14M pixel shifted right = 2 complete color phase rotations.
|
||||
// . ie. the 14M colors are correct, but being 1 pixel out is the closest we can get the 7M and 14M video modes to overlap.
|
||||
// . The alternative is to render the 14M correctly 7 pixels early, but have 7-pixel borders left (for 7M modes) or right (for 14M modes).
|
||||
#define EXTEND_14M_VIDEO_BY_1_PIXEL 0
|
||||
|
||||
#define NTSC_REMOVE_WHITE_RINGING 1 // 0 = theoritical dimmed white has chroma, 1 = pure white without chroma tinting
|
||||
#define NTSC_REMOVE_BLACK_GHOSTING 1 // 1 = remove black smear/smudges carrying over
|
||||
#define NTSC_REMOVE_GRAY_CHROMA 1 // 1 = remove all chroma in gray1 and gray2
|
||||
|
@ -415,18 +406,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
static csbits_t csbits; // charset, optionally followed by alt charset
|
||||
|
||||
// Prototypes
|
||||
INLINE float clampZeroOne( const float & x );
|
||||
INLINE uint8_t getCharSetBits( const int iChar );
|
||||
INLINE uint16_t getLoResBits( uint8_t iByte );
|
||||
INLINE uint32_t getScanlineColor( const uint16_t signal, const bgra_t *pTable );
|
||||
INLINE uint32_t* getScanlineNext1Address();
|
||||
INLINE uint32_t* getScanlinePrev1Address();
|
||||
INLINE uint32_t* getScanlinePrev2Address();
|
||||
INLINE uint32_t* getScanlineThis0Address();
|
||||
INLINE void updateColorPhase();
|
||||
INLINE void updateFlashRate();
|
||||
INLINE void updateFramebufferColorTVSingleScanline( uint16_t signal, bgra_t *pTable );
|
||||
INLINE void updateFramebufferColorTVDoubleScanline( uint16_t signal, bgra_t *pTable );
|
||||
INLINE void updateFramebufferTVSingleScanline( uint16_t signal, bgra_t *pTable );
|
||||
INLINE void updateFramebufferTVDoubleScanline( uint16_t signal, bgra_t *pTable );
|
||||
INLINE void updateFramebufferMonitorSingleScanline( uint16_t signal, bgra_t *pTable );
|
||||
INLINE void updateFramebufferMonitorDoubleScanline( uint16_t signal, bgra_t *pTable );
|
||||
INLINE void updatePixels( uint16_t bits );
|
||||
|
@ -461,17 +442,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
static void updateScreenText40 ( long cycles6502 );
|
||||
static void updateScreenText80 ( long cycles6502 );
|
||||
|
||||
//===========================================================================
|
||||
// NB. This func only exists so that EXTEND_14M_VIDEO_BY_1_PIXEL only needs to exist in this cpp file!
|
||||
UINT NTSC_GetFrameBufferBorderlessWidth(void)
|
||||
{
|
||||
#if !EXTEND_14M_VIDEO_BY_1_PIXEL
|
||||
return 560; // 560 = Double Hi-Res
|
||||
#else
|
||||
return 561; // 560 = Double Hi-Res, +1 for GH#555
|
||||
#endif
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
static void set_csbits()
|
||||
{
|
||||
|
@ -518,25 +488,29 @@ inline uint32_t getScanlineColor( const uint16_t signal, const bgra_t *pTable )
|
|||
}
|
||||
|
||||
//===========================================================================
|
||||
inline uint32_t* getScanlineNext1Address()
|
||||
inline uint32_t* getScanlineNextInbetween()
|
||||
{
|
||||
return (uint32_t*) (g_pVideoAddress - 1*g_kFrameBufferWidth);
|
||||
}
|
||||
|
||||
#if 0 // don't use this pixel, as it's from the previous video-frame!
|
||||
inline uint32_t* getScanlineNext()
|
||||
{
|
||||
return (uint32_t*) (g_pVideoAddress - 2*g_kFrameBufferWidth);
|
||||
}
|
||||
#endif
|
||||
//===========================================================================
|
||||
inline uint32_t* getScanlinePrev1Address()
|
||||
inline uint32_t* getScanlinePreviousInbetween()
|
||||
{
|
||||
return (uint32_t*) (g_pVideoAddress + 1*g_kFrameBufferWidth);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline uint32_t* getScanlinePrev2Address()
|
||||
inline uint32_t* getScanlinePrevious()
|
||||
{
|
||||
return (uint32_t*) (g_pVideoAddress + 2*g_kFrameBufferWidth);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline uint32_t* getScanlineThis0Address()
|
||||
inline uint32_t* getScanlineCurrent()
|
||||
{
|
||||
return (uint32_t*) g_pVideoAddress;
|
||||
}
|
||||
|
@ -579,15 +553,15 @@ inline void updateFlashRate() // TODO: Flash rate should be constant (regardless
|
|||
} while(0)
|
||||
|
||||
// prevp is never used nor blended with!
|
||||
#define updateFramebufferColorTVSingleScanline(signal,table) \
|
||||
#define updateFramebufferTVSingleScanline(signal,table) \
|
||||
do { \
|
||||
uint32_t ntscp, prevp, betwp; \
|
||||
uint32_t ntscp, /*prevp,*/ betwp; \
|
||||
uint32_t *prevlin, *between; \
|
||||
g_nSignalBitsNTSC = ((g_nSignalBitsNTSC << 1) | signal) & 0xFFF; \
|
||||
prevlin = (uint32_t*)(g_pVideoAddress + 2*FRAMEBUFFER_W); \
|
||||
/*prevlin = (uint32_t*)(g_pVideoAddress + 2*FRAMEBUFFER_W);*/ \
|
||||
between = (uint32_t*)(g_pVideoAddress + 1*FRAMEBUFFER_W); \
|
||||
ntscp = *(uint32_t*) &table[g_nSignalBitsNTSC]; /* raw current NTSC color */ \
|
||||
prevp = *prevlin; \
|
||||
/*prevp = *prevlin;*/ \
|
||||
betwp = ntscp - ((ntscp & 0x00fcfcfc) >> 2); \
|
||||
*between = betwp | ALPHA32_MASK; \
|
||||
*(uint32_t*)g_pVideoAddress = ntscp; \
|
||||
|
@ -604,7 +578,7 @@ inline void updateFlashRate() // TODO: Flash rate should be constant (regardless
|
|||
g_pVideoAddress++; \
|
||||
} while(0)
|
||||
|
||||
#define updateFramebufferColorTVDoubleScanline(signal,table) \
|
||||
#define updateFramebufferTVDoubleScanline(signal,table) \
|
||||
do { \
|
||||
uint32_t ntscp, prevp, betwp; \
|
||||
uint32_t *prevlin, *between; \
|
||||
|
@ -619,73 +593,76 @@ inline void updateFlashRate() // TODO: Flash rate should be constant (regardless
|
|||
g_pVideoAddress++; \
|
||||
} while(0)
|
||||
#else
|
||||
|
||||
//===========================================================================
|
||||
inline void updateFramebufferColorTVSingleScanline( uint16_t signal, bgra_t *pTable )
|
||||
|
||||
// Original: Prev1(inbetween) = current - 25% of previous AppleII scanline
|
||||
// GH#650: Prev1(inbetween) = 50% of (50% current + 50% of previous AppleII scanline)
|
||||
inline void updateFramebufferTVSingleScanline( uint16_t signal, bgra_t *pTable )
|
||||
{
|
||||
/* */ uint32_t *pLine0Address = getScanlineThis0Address();
|
||||
/* */ uint32_t *pLine1Address = getScanlinePrev1Address(); // NB. TV mode uses previous 2 lines
|
||||
/* */ uint32_t *pLine2Address = getScanlinePrev2Address();
|
||||
|
||||
uint32_t *pLine0Curr = getScanlineCurrent();
|
||||
uint32_t *pLine1Prev = getScanlinePreviousInbetween();
|
||||
uint32_t *pLine2Prev = getScanlinePrevious();
|
||||
const uint32_t color0 = getScanlineColor( signal, pTable );
|
||||
const uint32_t color2 = *pLine2Address;
|
||||
// const uint32_t color1 = color0 - ((color2 & 0x00fcfcfc) >> 2); // BUG? color0 - color0? not color0-color2?
|
||||
// TC: The above operation "color0 - ((color2 & 0x00fcfcfc) >> 2)" causes underflow, so I've recoded to clamp on underflow:
|
||||
uint32_t color1;
|
||||
{
|
||||
int r=(color0>>16)&0xff, g=(color0>>8)&0xff, b=color0&0xff;
|
||||
uint32_t color2_prime = (color2 & 0x00fcfcfc) >> 2;
|
||||
r -= (color2_prime>>16)&0xff; if (r<0) r=0; // clamp to 0 on underflow
|
||||
g -= (color2_prime>>8)&0xff; if (g<0) g=0; // clamp to 0 on underflow
|
||||
b -= (color2_prime)&0xff; if (b<0) b=0; // clamp to 0 on underflow
|
||||
color1 = (r<<16)|(g<<8)|(b);
|
||||
}
|
||||
const uint32_t color2 = *pLine2Prev;
|
||||
uint32_t color1 = ((color0 & 0x00fefefe) >> 1) + ((color2 & 0x00fefefe) >> 1); // 50% Blend
|
||||
color1 = (color1 & 0x00fefefe) >> 1; // ... then 50% brightness for inbetween line
|
||||
|
||||
/* */ *pLine1Address = color1 | ALPHA32_MASK;
|
||||
/* */ *pLine0Address = color0;
|
||||
/* */ g_pVideoAddress++;
|
||||
*pLine1Prev = color1 | ALPHA32_MASK;
|
||||
*pLine0Curr = color0;
|
||||
|
||||
// GH#650: Draw to final inbetween scanline to avoid residue from other video modes (eg. Amber->TV B&W)
|
||||
if (g_nVideoClockVert == (VIDEO_SCANNER_Y_DISPLAY-1))
|
||||
*getScanlineNextInbetween() = ((color0 & 0x00fcfcfc) >> 2) | ALPHA32_MASK; // 50% of (50% current + black)) = 25% of current
|
||||
|
||||
g_pVideoAddress++;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline void updateFramebufferColorTVDoubleScanline( uint16_t signal, bgra_t *pTable )
|
||||
{
|
||||
/* */ uint32_t *pLine0Address = getScanlineThis0Address();
|
||||
/* */ uint32_t *pLine1Address = getScanlinePrev1Address(); // NB. TV mode uses previous 2 lines
|
||||
const uint32_t *pLine2Address = getScanlinePrev2Address();
|
||||
|
||||
// Original: Prev1(inbetween) = 50% current + 50% of previous AppleII scanline
|
||||
inline void updateFramebufferTVDoubleScanline( uint16_t signal, bgra_t *pTable )
|
||||
{
|
||||
uint32_t *pLine0Curr = getScanlineCurrent();
|
||||
uint32_t *pLine1Prev = getScanlinePreviousInbetween();
|
||||
uint32_t *pLine2Prev = getScanlinePrevious();
|
||||
const uint32_t color0 = getScanlineColor( signal, pTable );
|
||||
const uint32_t color2 = *pLine2Address;
|
||||
const uint32_t color2 = *pLine2Prev;
|
||||
const uint32_t color1 = ((color0 & 0x00fefefe) >> 1) + ((color2 & 0x00fefefe) >> 1); // 50% Blend
|
||||
|
||||
/* */ *pLine1Address = color1 | ALPHA32_MASK;
|
||||
/* */ *pLine0Address = color0;
|
||||
/* */ g_pVideoAddress++;
|
||||
*pLine1Prev = color1 | ALPHA32_MASK;
|
||||
*pLine0Curr = color0;
|
||||
|
||||
// GH#650: Draw to final inbetween scanline to avoid residue from other video modes (eg. Amber->TV B&W)
|
||||
if (g_nVideoClockVert == (VIDEO_SCANNER_Y_DISPLAY-1))
|
||||
*getScanlineNextInbetween() = ((color0 & 0x00fefefe) >> 1) | ALPHA32_MASK; // (50% current + black)) = 50% of current
|
||||
|
||||
g_pVideoAddress++;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline void updateFramebufferMonitorSingleScanline( uint16_t signal, bgra_t *pTable )
|
||||
{
|
||||
/* */ uint32_t *pLine0Address = getScanlineThis0Address();
|
||||
/* */ uint32_t *pLine1Address = getScanlineNext1Address(); // NB. Monitor mode just uses next line
|
||||
uint32_t *pLine0Curr = getScanlineCurrent();
|
||||
uint32_t *pLine1Next = getScanlineNextInbetween();
|
||||
const uint32_t color0 = getScanlineColor( signal, pTable );
|
||||
const uint32_t color1 = 0; // Remove blending for consistent DHGR MIX mode (GH#631)
|
||||
// const uint32_t color1 = ((color0 & 0x00fcfcfc) >> 2); // 25% Blend (original)
|
||||
|
||||
/* */ *pLine1Address = color1 | ALPHA32_MASK;
|
||||
/* */ *pLine0Address = color0;
|
||||
/* */ g_pVideoAddress++;
|
||||
*pLine1Next = color1 | ALPHA32_MASK;
|
||||
*pLine0Curr = color0;
|
||||
g_pVideoAddress++;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline void updateFramebufferMonitorDoubleScanline( uint16_t signal, bgra_t *pTable )
|
||||
{
|
||||
/* */ uint32_t *pLine0Address = getScanlineThis0Address();
|
||||
/* */ uint32_t *pLine1Address = getScanlineNext1Address(); // NB. Monitor mode just uses next line
|
||||
uint32_t *pLine0Curr = getScanlineCurrent();
|
||||
uint32_t *pLine1Next = getScanlineNextInbetween();
|
||||
const uint32_t color0 = getScanlineColor( signal, pTable );
|
||||
|
||||
/* */ *pLine1Address = color0;
|
||||
/* */ *pLine0Address = color0;
|
||||
/* */ g_pVideoAddress++;
|
||||
*pLine1Next = color0;
|
||||
*pLine0Curr = color0;
|
||||
g_pVideoAddress++;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -788,7 +765,6 @@ inline void updateVideoScannerHorzEOLSimple()
|
|||
}
|
||||
}
|
||||
|
||||
#if !EXTEND_14M_VIDEO_BY_1_PIXEL
|
||||
// NOTE: This writes out-of-bounds for a 560x384 framebuffer
|
||||
inline void updateVideoScannerHorzEOL()
|
||||
{
|
||||
|
@ -826,97 +802,6 @@ inline void updateVideoScannerHorzEOL()
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
#if EXTEND_14M_VIDEO_BY_1_PIXEL
|
||||
// NB. Only needed for video modes that are 14M and shift the color phase, ie:
|
||||
// . updateScreenDoubleHires80(), updateScreenDoubleLores80(), updateScreenText80()
|
||||
// NOTE: This writes out-of-bounds for a 560x384 framebuffer
|
||||
inline void updateVideoScannerHorzEOL_14M()
|
||||
{
|
||||
if (VIDEO_SCANNER_MAX_HORZ == ++g_nVideoClockHorz)
|
||||
{
|
||||
if (g_nVideoClockVert < VIDEO_SCANNER_Y_DISPLAY)
|
||||
{
|
||||
if (!GetColorBurst())
|
||||
{
|
||||
// Only for: VF_TEXT && !VF_MIXED (ie. full 24-row TEXT40 or TEXT80)
|
||||
g_pFuncUpdateBnWPixel(g_nLastColumnPixelNTSC); // 14M: Output a 561st dot
|
||||
g_pFuncUpdateBnWPixel(0);
|
||||
g_pFuncUpdateBnWPixel(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pFuncUpdateHuePixel(g_nLastColumnPixelNTSC); // 14M: Output a 561st dot
|
||||
g_pFuncUpdateHuePixel(0);
|
||||
g_pFuncUpdateHuePixel(0);
|
||||
}
|
||||
}
|
||||
|
||||
g_nVideoClockHorz = 0;
|
||||
|
||||
if (++g_nVideoClockVert == g_videoScannerMaxVert)
|
||||
{
|
||||
g_nVideoClockVert = 0;
|
||||
|
||||
updateFlashRate();
|
||||
}
|
||||
|
||||
if (g_nVideoClockVert < VIDEO_SCANNER_Y_DISPLAY)
|
||||
{
|
||||
updateVideoScannerAddress();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------
|
||||
|
||||
// NOTE: This writes out-of-bounds for a 560x384 framebuffer
|
||||
inline void updateVideoScannerHorzEOL()
|
||||
{
|
||||
if (VIDEO_SCANNER_MAX_HORZ == ++g_nVideoClockHorz)
|
||||
{
|
||||
if (g_nVideoClockVert < VIDEO_SCANNER_Y_DISPLAY)
|
||||
{
|
||||
if ( !GetColorBurst() || // Only for: VF_TEXT && !VF_MIXED (ie. full 24-row TEXT40 or TEXT80)
|
||||
(g_eVideoType == VT_MONO_CUSTOM) || (g_eVideoType == VT_MONO_AMBER) || (g_eVideoType == VT_MONO_GREEN) || (g_eVideoType == VT_MONO_WHITE) )
|
||||
{
|
||||
g_pFuncUpdateBnWPixel(0);
|
||||
g_pFuncUpdateBnWPixel(0);
|
||||
|
||||
// 7M: Stop outputting video after 560 dots
|
||||
*(UINT32*)&g_pVideoAddress[0] = 0;
|
||||
*(UINT32*)&g_pVideoAddress[g_kFrameBufferWidth] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pFuncUpdateHuePixel(g_nLastColumnPixelNTSC);
|
||||
g_pFuncUpdateHuePixel(0);
|
||||
|
||||
// 7M: Stop outputting video after 560 dots
|
||||
*(UINT32*)&g_pVideoAddress[0] = 0;
|
||||
*(UINT32*)&g_pVideoAddress[g_kFrameBufferWidth] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
g_nVideoClockHorz = 0;
|
||||
|
||||
if (++g_nVideoClockVert == g_videoScannerMaxVert)
|
||||
{
|
||||
g_nVideoClockVert = 0;
|
||||
|
||||
updateFlashRate();
|
||||
}
|
||||
|
||||
if (g_nVideoClockVert < VIDEO_SCANNER_Y_DISPLAY)
|
||||
{
|
||||
updateVideoScannerAddress();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//===========================================================================
|
||||
inline void updateVideoScannerAddress()
|
||||
|
@ -1267,26 +1152,26 @@ static void updatePixelBnWMonitorDoubleScanline (uint16_t compositeSignal)
|
|||
//===========================================================================
|
||||
static void updatePixelBnWColorTVSingleScanline (uint16_t compositeSignal)
|
||||
{
|
||||
updateFramebufferColorTVSingleScanline(compositeSignal, g_aBnWColorTVCustom);
|
||||
updateFramebufferTVSingleScanline(compositeSignal, g_aBnWColorTVCustom);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
static void updatePixelBnWColorTVDoubleScanline (uint16_t compositeSignal)
|
||||
{
|
||||
updateFramebufferColorTVDoubleScanline(compositeSignal, g_aBnWColorTVCustom);
|
||||
updateFramebufferTVDoubleScanline(compositeSignal, g_aBnWColorTVCustom);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
static void updatePixelHueColorTVSingleScanline (uint16_t compositeSignal)
|
||||
{
|
||||
updateFramebufferColorTVSingleScanline(compositeSignal, g_aHueColorTV[g_nColorPhaseNTSC]);
|
||||
updateFramebufferTVSingleScanline(compositeSignal, g_aHueColorTV[g_nColorPhaseNTSC]);
|
||||
updateColorPhase();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
static void updatePixelHueColorTVDoubleScanline (uint16_t compositeSignal)
|
||||
{
|
||||
updateFramebufferColorTVDoubleScanline(compositeSignal, g_aHueColorTV[g_nColorPhaseNTSC]);
|
||||
updateFramebufferTVDoubleScanline(compositeSignal, g_aHueColorTV[g_nColorPhaseNTSC]);
|
||||
updateColorPhase();
|
||||
}
|
||||
|
||||
|
@ -1304,31 +1189,6 @@ static void updatePixelHueMonitorDoubleScanline (uint16_t compositeSignal)
|
|||
updateColorPhase();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
#if EXTEND_14M_VIDEO_BY_1_PIXEL
|
||||
// NB. Only needed for video modes that are 14M and shift the color phase, ie:
|
||||
// . updateScreenDoubleHires80(), updateScreenDoubleLores80(), updateScreenText80()
|
||||
inline void zeroPixel0_14M(void) // GH#555
|
||||
{
|
||||
if (g_nVideoClockHorz == VIDEO_SCANNER_HORZ_START)
|
||||
{
|
||||
UINT32* p = ((UINT32*)g_pVideoAddress) - 14; // Point back to pixel-0
|
||||
// NB. For VT_COLOR_MONITOR_NTSC, also check color-burst so that TEXT and MIXED(HGR+TEXT) render the TEXT at the same offset (GH#341)
|
||||
if (g_eVideoType == VT_MONO_TV || g_eVideoType == VT_COLOR_TV || (g_eVideoType == VT_COLOR_MONITOR_NTSC && GetColorBurst()))
|
||||
{
|
||||
p[2] = 0;
|
||||
p[g_kFrameBufferWidth+2] = 0; // Next line (there are 2 lines per Apple II scanline)
|
||||
}
|
||||
else
|
||||
{
|
||||
p[0] = 0;
|
||||
p[g_kFrameBufferWidth+0] = 0; // Next line (there are 2 lines per Apple II scanline)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//===========================================================================
|
||||
void updateScreenDoubleHires40 (long cycles6502) // wsUpdateVideoHires0
|
||||
{
|
||||
|
@ -1459,17 +1319,9 @@ void updateScreenDoubleHires80 (long cycles6502 ) // wsUpdateVideoDblHires
|
|||
bits = (bits << 1) | g_nLastColumnPixelNTSC;
|
||||
updatePixels( bits );
|
||||
g_nLastColumnPixelNTSC = (bits >> 14) & 1;
|
||||
|
||||
#if EXTEND_14M_VIDEO_BY_1_PIXEL
|
||||
zeroPixel0_14M();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#if EXTEND_14M_VIDEO_BY_1_PIXEL
|
||||
updateVideoScannerHorzEOL_14M();
|
||||
#else
|
||||
updateVideoScannerHorzEOL();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1571,18 +1423,9 @@ void updateScreenDoubleLores80 (long cycles6502) // wsUpdateVideoDblLores
|
|||
uint16_t bits = (main << 7) | (aux & 0x7f);
|
||||
updatePixels( bits );
|
||||
g_nLastColumnPixelNTSC = (bits >> 14) & 1;
|
||||
|
||||
#if EXTEND_14M_VIDEO_BY_1_PIXEL
|
||||
zeroPixel0_14M();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#if EXTEND_14M_VIDEO_BY_1_PIXEL
|
||||
updateVideoScannerHorzEOL_14M();
|
||||
#else
|
||||
updateVideoScannerHorzEOL();
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1799,18 +1642,9 @@ void updateScreenText80 (long cycles6502)
|
|||
bits = (bits << 1) | g_nLastColumnPixelNTSC; // GH#555: Align TEXT80 chars with DHGR
|
||||
updatePixels( bits );
|
||||
g_nLastColumnPixelNTSC = (bits >> 14) & 1;
|
||||
|
||||
#if EXTEND_14M_VIDEO_BY_1_PIXEL
|
||||
zeroPixel0_14M();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#if EXTEND_14M_VIDEO_BY_1_PIXEL
|
||||
updateVideoScannerHorzEOL_14M();
|
||||
#else
|
||||
updateVideoScannerHorzEOL();
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1979,14 +1813,6 @@ void NTSC_SetVideoMode( uint32_t uVideoModeFlags, bool bDelay/*=false*/ )
|
|||
|
||||
//===========================================================================
|
||||
|
||||
// TV modes don't write to the last line, so when switching from another (Monitor) mode there may be stale data left behind
|
||||
void ClearLastLine(void)
|
||||
{
|
||||
uint32_t* p = (uint32_t*)g_pScanLines[VIDEO_SCANNER_Y_DISPLAY * 2 - 1];
|
||||
for (UINT x = 0; x < NTSC_GetFrameBufferBorderlessWidth(); x++)
|
||||
p[x] = 0;
|
||||
}
|
||||
|
||||
void NTSC_SetVideoStyle() // (int v, int s)
|
||||
{
|
||||
int half = IsVideoStyle(VS_HALF_SCANLINES);
|
||||
|
@ -2008,7 +1834,6 @@ void NTSC_SetVideoStyle() // (int v, int s)
|
|||
g_pFuncUpdateBnWPixel = updatePixelBnWColorTVDoubleScanline;
|
||||
g_pFuncUpdateHuePixel = updatePixelHueColorTVDoubleScanline;
|
||||
}
|
||||
ClearLastLine();
|
||||
break;
|
||||
|
||||
case VT_COLOR_MONITOR_NTSC:
|
||||
|
@ -2040,7 +1865,6 @@ void NTSC_SetVideoStyle() // (int v, int s)
|
|||
else {
|
||||
g_pFuncUpdateBnWPixel = g_pFuncUpdateHuePixel = updatePixelBnWColorTVDoubleScanline;
|
||||
}
|
||||
ClearLastLine();
|
||||
break;
|
||||
|
||||
case VT_MONO_AMBER:
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
extern void NTSC_VideoInitChroma();
|
||||
extern void NTSC_VideoUpdateCycles( UINT cycles6502 );
|
||||
extern void NTSC_VideoRedrawWholeScreen( void );
|
||||
extern UINT NTSC_GetFrameBufferBorderlessWidth( void );
|
||||
|
||||
enum VideoRefreshRate_e;
|
||||
void NTSC_SetRefreshRate(VideoRefreshRate_e rate);
|
||||
|
|
|
@ -1469,6 +1469,9 @@ bool CSuperSerialCard::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, U
|
|||
m_vbRxIrqPending = yamlLoadHelper.LoadBool(SS_YAML_KEY_RXIRQPENDING);
|
||||
m_vbTxEmpty = yamlLoadHelper.LoadBool(SS_YAML_KEY_WRITTENTX);
|
||||
|
||||
if (m_vbTxIrqPending || m_vbRxIrqPending) // GH#677
|
||||
CpuIrqAssert(IS_SSC);
|
||||
|
||||
std::string serialPortName = yamlLoadHelper.LoadString(SS_YAML_KEY_SERIALPORTNAME);
|
||||
SetSerialPortName(serialPortName.c_str());
|
||||
|
||||
|
|
|
@ -226,10 +226,15 @@ void DSReleaseSoundBuffer(VOICE* pVoice)
|
|||
|
||||
bool DSZeroVoiceBuffer(PVOICE Voice, char* pszDevName, DWORD dwBufferSize)
|
||||
{
|
||||
#ifdef NO_DIRECT_X
|
||||
|
||||
return false;
|
||||
|
||||
#else
|
||||
|
||||
DWORD dwDSLockedBufferSize = 0; // Size of the locked DirectSound buffer
|
||||
SHORT* pDSLockedBuffer;
|
||||
|
||||
|
||||
HRESULT hr = Voice->lpDSBvoice->Stop();
|
||||
if(FAILED(hr))
|
||||
{
|
||||
|
@ -262,6 +267,7 @@ bool DSZeroVoiceBuffer(PVOICE Voice, char* pszDevName, DWORD dwBufferSize)
|
|||
}
|
||||
|
||||
return true;
|
||||
#endif // NO_DIRECT_X
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -569,6 +569,11 @@ void VideoRefreshScreen ( uint32_t uRedrawWholeScreenVideoMode /* =0*/, bool bRe
|
|||
if (bRedrawWholeScreen)
|
||||
NTSC_SetVideoMode( uRedrawWholeScreenVideoMode );
|
||||
NTSC_VideoRedrawWholeScreen();
|
||||
|
||||
// MODE_DEBUG|PAUSED: Need to refresh a 2nd time if changing video-type, otherwise could have residue from prev image!
|
||||
// . eg. Amber -> B&W TV
|
||||
if (g_nAppMode == MODE_DEBUG || g_nAppMode == MODE_PAUSED)
|
||||
NTSC_VideoRedrawWholeScreen();
|
||||
}
|
||||
|
||||
HDC hFrameDC = FrameGetDC();
|
||||
|
@ -594,7 +599,11 @@ void VideoRefreshScreen ( uint32_t uRedrawWholeScreenVideoMode /* =0*/, bool bRe
|
|||
SRCCOPY);
|
||||
}
|
||||
|
||||
#ifdef NO_DIRECT_X
|
||||
#else
|
||||
//if (g_lpDD) g_lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL);
|
||||
#endif // NO_DIRECT_X
|
||||
|
||||
GdiFlush();
|
||||
}
|
||||
|
||||
|
@ -904,6 +913,11 @@ static BOOL CALLBACK DDEnumProc(LPGUID lpGUID, LPCTSTR lpszDesc, LPCTSTR lpszDrv
|
|||
|
||||
bool DDInit(void)
|
||||
{
|
||||
#ifdef NO_DIRECT_X
|
||||
|
||||
return false;
|
||||
|
||||
#else
|
||||
HRESULT hr = DirectDrawEnumerate((LPDDENUMCALLBACK)DDEnumProc, NULL);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
|
@ -934,6 +948,7 @@ bool DDInit(void)
|
|||
}
|
||||
|
||||
return true;
|
||||
#endif // NO_DIRECT_X
|
||||
}
|
||||
|
||||
// From SoundCore.h
|
||||
|
|
Loading…
Add table
Reference in a new issue