Fixes for:

BUG#017055 - DDial timer running very fast
. TAPEIN.bit7 was being read from floating-bus. Now fixed high.
BUG#007237 - VBl IO reg not updated in 'Stepping' mode
This commit is contained in:
tomch 2010-08-17 07:52:23 +00:00
parent 1490e77037
commit 316dc7c0a6
11 changed files with 131 additions and 128 deletions

View File

@ -194,7 +194,6 @@ void ContinueExecution()
nCyclesToExecute = 0;
DWORD dwExecutedCycles = CpuExecute(nCyclesToExecute);
g_dwCyclesThisFrame += dwExecutedCycles;
//
@ -203,7 +202,6 @@ void ContinueExecution()
DiskUpdatePosition(dwExecutedCycles);
JoyUpdatePosition();
VideoUpdateVbl(g_dwCyclesThisFrame);
SpkrUpdate(cyclenum);
sg_SSC.CommUpdate(cyclenum);

View File

@ -119,8 +119,7 @@ static BYTE benchopcode[BENCHOPCODES] = {0x06,0x16,0x24,0x45,0x48,0x65,0x68,0x76
regsrec regs;
unsigned __int64 g_nCumulativeCycles = 0;
static ULONG g_nCyclesSubmitted; // Number of cycles submitted to CpuExecute()
static ULONG g_nCyclesExecuted;
static ULONG g_nCyclesExecuted; // # of cycles executed up to last IO access
//static signed long g_uInternalExecutedCycles;
// TODO: Use IRQ_CHECK_TIMEOUT=128 when running at full-speed else with IRQ_CHECK_TIMEOUT=1
@ -405,20 +404,23 @@ void CpuDestroy ()
}
//===========================================================================
// Pre:
// Description:
// Call this when an IO-reg is access & accurate cycle info is needed
// Pre:
// nExecutedCycles = # of cycles executed by Cpu6502() or Cpu65C02() for this iteration of ContinueExecution()
// Post:
// g_nCyclesExecuted
// g_nCumulativeCycles
//
void CpuCalcCycles(ULONG nExecutedCycles)
void CpuCalcCycles(const ULONG nExecutedCycles)
{
// Calc # of cycles executed since this func was last called
ULONG nCycles = nExecutedCycles - g_nCyclesExecuted;
const ULONG nCycles = nExecutedCycles - g_nCyclesExecuted;
_ASSERT( (LONG)nCycles >= 0 );
g_nCyclesExecuted += nCycles;
g_nCumulativeCycles += nCycles;
g_nCyclesExecuted = nExecutedCycles;
}
//===========================================================================
@ -431,13 +433,13 @@ void CpuCalcCycles(ULONG nExecutedCycles)
// - 137.9,135.6MHz (with check for VBL IRQ & MB_Update every 128 cycles)
#if 0 // TODO: Measure perf increase by using this new method
ULONG CpuGetCyclesThisFrame(ULONG) // Old func using g_uInternalExecutedCycles
ULONG CpuGetCyclesThisVideoFrame(ULONG) // Old func using g_uInternalExecutedCycles
{
CpuCalcCycles(g_uInternalExecutedCycles);
return g_dwCyclesThisFrame + g_nCyclesExecuted;
}
#else
ULONG CpuGetCyclesThisFrame(ULONG nExecutedCycles)
ULONG CpuGetCyclesThisVideoFrame(const ULONG nExecutedCycles)
{
CpuCalcCycles(nExecutedCycles);
return g_dwCyclesThisFrame + g_nCyclesExecuted;
@ -446,27 +448,22 @@ ULONG CpuGetCyclesThisFrame(ULONG nExecutedCycles)
//===========================================================================
DWORD CpuExecute (DWORD uCycles)
DWORD CpuExecute(const DWORD uCycles)
{
DWORD uExecutedCycles = 0;
g_nCyclesSubmitted = uCycles;
g_nCyclesExecuted = 0;
//
MB_StartOfCpuExecute();
if (uCycles == 0) // Do single step
uExecutedCycles = InternalCpuExecute(0);
else // Do multi-opcode emulation
uExecutedCycles = InternalCpuExecute(uCycles);
// uCycles:
// =0 : Do single step
// >0 : Do multi-opcode emulation
const DWORD uExecutedCycles = InternalCpuExecute(uCycles);
MB_UpdateCycles(uExecutedCycles); // Update 6522s (NB. Do this before updating g_nCumulativeCycles below)
//
UINT nRemainingCycles = uExecutedCycles - g_nCyclesExecuted;
const UINT nRemainingCycles = uExecutedCycles - g_nCyclesExecuted;
g_nCumulativeCycles += nRemainingCycles;
return uExecutedCycles;

View File

@ -16,7 +16,7 @@ extern unsigned __int64 g_nCumulativeCycles;
void CpuDestroy ();
void CpuCalcCycles(ULONG nExecutedCycles);
DWORD CpuExecute (DWORD);
ULONG CpuGetCyclesThisFrame(ULONG nExecutedCycles);
ULONG CpuGetCyclesThisVideoFrame(ULONG nExecutedCycles);
void CpuInitialize ();
void CpuSetupBenchmark ();
void CpuIrqReset();

View File

@ -7256,10 +7256,9 @@ Update_t ExecuteCommand (int nArgs)
//===========================================================================
bool InternalSingleStep ()
{
static DWORD dwCyclesThisFrame = 0;
bool bResult = false;
_try
{
@ -7269,14 +7268,16 @@ bool InternalSingleStep ()
g_aProfileOpcodes[ nOpcode ].m_nCount++;
g_aProfileOpmodes[ nOpmode ].m_nCount++;
DWORD dwExecutedCycles = CpuExecute(g_nDebugStepCycles);
dwCyclesThisFrame += dwExecutedCycles;
if (dwCyclesThisFrame >= dwClksPerFrame)
// Like ContinueExecution()
{
dwCyclesThisFrame -= dwClksPerFrame;
DWORD dwExecutedCycles = CpuExecute(g_nDebugStepCycles);
g_dwCyclesThisFrame += dwExecutedCycles;
if (g_dwCyclesThisFrame >= dwClksPerFrame)
{
g_dwCyclesThisFrame -= dwClksPerFrame;
}
}
VideoUpdateVbl( dwCyclesThisFrame );
bResult = true;
}

View File

@ -245,7 +245,7 @@ void KeybQueueKeypress (int key, BOOL bASCII)
if (key == ']') keycode = '}';
if (key == '`') keycode = '~';
if (key == 92) keycode = 96;
if (GetCapsLockAllowed ()== true)
if (GetCapsLockAllowed() == true)
{
if ((key == 92) || (key == 124)) keycode = 96; //Ý to Þ
//This shall be rewriten, so that enabling CAPS_LOCK (i.e. F10) will not invert these keys values)

View File

@ -211,7 +211,7 @@ static BYTE __stdcall IORead_C02x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG
static BYTE __stdcall IOWrite_C02x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
{
return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
return IO_Null(pc, addr, bWrite, d, nCyclesLeft); // $C020 TAPEOUT
}
//-------------------------------------
@ -302,7 +302,7 @@ static BYTE __stdcall IORead_C06x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG
//If (CAPS lOCK of Pravets8A/C is on or Shift is pressed) and (MODE is enabled), bit7 in $C000 is 1; Else it is 0
//Writing into $C060 sets MODE on and off. If bit 0 is 0 the the MODE is set 0, if bit 0 is 1 then MODE is set to 1 (8-bit)
case 0x0: return TapeRead(pc, addr, bWrite, d, nCyclesLeft);
case 0x0: return TapeRead(pc, addr, bWrite, d, nCyclesLeft); // $C060 TAPEIN
case 0x1: return JoyReadButton(pc, addr, bWrite, d, nCyclesLeft); //$C061 Digital input 0 (If bit 7=1 then JoyButton 0 or OpenApple is pressed)
case 0x2: return JoyReadButton(pc, addr, bWrite, d, nCyclesLeft); //$C062 Digital input 1 (If bit 7=1 then JoyButton 1 or ClosedApple is pressed)
case 0x3: return JoyReadButton(pc, addr, bWrite, d, nCyclesLeft); //$C063 Digital input 2

View File

@ -280,6 +280,9 @@ void Config_Load_Video()
REGLOAD(TEXT(REGVALUE_VIDEO_MODE ),&g_eVideoType);
REGLOAD(TEXT(REGVALUE_VIDEO_HALF_SCAN_LINES),&g_uHalfScanLines);
REGLOAD(TEXT(REGVALUE_VIDEO_MONO_COLOR ),&monochrome);
if (g_eVideoType >= NUM_VIDEO_MODES)
g_eVideoType = VT_COLOR_TVEMU;
}

View File

@ -30,46 +30,49 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "StdAfx.h"
static BYTE C060 = 255;
static bool CapsLockAllowed = false;
static bool g_CapsLockAllowed = false;
//---------------------------------------------------------------------------
BYTE __stdcall TapeRead (WORD, WORD address, BYTE, BYTE, ULONG nCyclesLeft)
BYTE __stdcall TapeRead(WORD, WORD address, BYTE, BYTE, ULONG nCyclesLeft)
{
/*
If retrieving KeybGetKeycode(); causes problems CurrentKestroke shall be added
If retrieving KeybGetKeycode(); causes problems uCurrentKeystroke shall be added
in the submission variables and it shall be added by the TapeRead caller
i.e. BYTE __stdcall TapeRead (WORD, WORD address, BYTE, BYTE, ULONG nCyclesLeft) shall become
BYTE __stdcall TapeRead (WORD, WORD address, BYTE, BYTE, ULONG nCyclesLeft, byte CurrentKeystroke)
BYTE __stdcall TapeRead (WORD, WORD address, BYTE, BYTE, ULONG nCyclesLeft, BYTE uCurrentKeystroke)
*/
static byte CurrentKestroke = 0;
CurrentKestroke = KeybGetKeycode();
if (g_Apple2Type == A2TYPE_PRAVETS8A )
if (g_Apple2Type == A2TYPE_PRAVETS8A)
{
C060= MemReadFloatingBus(nCyclesLeft); //IO_Null(pc, addr, bWrite, d, nCyclesLeft);
if (CapsLockAllowed) //8bit keyboard mode
const BYTE uCurrentKeystroke = KeybGetKeycode();
BYTE C060 = MemReadFloatingBus(nCyclesLeft);
if (g_CapsLockAllowed) //8bit keyboard mode
{
if (((P8CAPS_ON == false) && (P8Shift == false)) || ((P8CAPS_ON ) && (P8Shift ))) //LowerCase
if ((CurrentKestroke<65) //|| ((CurrentKestroke>90) && (CurrentKestroke<96))
|| ((CurrentKestroke>126) && (CurrentKestroke<193)))
{
if ((uCurrentKeystroke<65) //|| ((uCurrentKeystroke>90) && (uCurrentKeystroke<96))
|| ((uCurrentKeystroke>126) && (uCurrentKeystroke<193)))
C060 |= 1 << 7; //Sets bit 7 to 1 for special keys (arrows, return, etc) and for control+ key combinations.
else
C060 &= 127; //sets bit 7 to 0
}
else //UpperCase
{
C060 |= 1 << 7;
}
}
else //7bit keyboard mode
{
C060 &= 191; //Sets bit 6 to 0; I am not sure if this shall be done, because its value is disregarded in this case.
C060 |= 1 << 7; //Sets bit 7 to 1
}
}
return C060;
}
else return MemReadFloatingBus(nCyclesLeft); //IO_Null(pc, addr, bWrite, d, nCyclesLeft);
return (1<<7) | (MemReadFloatingBus(nCyclesLeft) & 0x7F); // Keep high-bit fixed (since TAPEIN isn't supported)
}
/*
@ -80,20 +83,20 @@ BYTE __stdcall TapeWrite(WORD programcounter, WORD address, BYTE write, BYTE val
{
if (g_Apple2Type == A2TYPE_PRAVETS8A)
{
if (value & 1)
CapsLockAllowed = true;
else
CapsLockAllowed = false;
//If bit0 of the input byte is 0, it will forbid 8-bit characters (Default)
//If bit0 of the input byte is 1, it will allow 8-bit characters
return 0;
if (value & 1)
g_CapsLockAllowed = true;
else
g_CapsLockAllowed = false;
//If bit0 of the input byte is 0, it will forbid 8-bit characters (Default)
//If bit0 of the input byte is 1, it will allow 8-bit characters
return 0;
}
else
{
return MemReadFloatingBus(nCyclesLeft);
}
}
bool __stdcall GetCapsLockAllowed ()
bool GetCapsLockAllowed(void)
{
return CapsLockAllowed;
return g_CapsLockAllowed;
}

View File

@ -1,5 +1,5 @@
#pragma once
extern BYTE __stdcall TapeRead (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
extern BYTE __stdcall TapeWrite (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
extern bool __stdcall GetCapsLockAllowed ();
extern BYTE __stdcall TapeRead(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
extern BYTE __stdcall TapeWrite(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
extern bool GetCapsLockAllowed(void);

View File

@ -234,7 +234,6 @@ static BOOL hasrefreshed = 0;
static DWORD lastpageflip = 0;
COLORREF monochrome = RGB(0xC0,0xC0,0xC0);
static BOOL rebuiltsource = 0;
static DWORD dwVBlCounter = 0;
static LPBYTE vidlastmem = NULL;
static DWORD vidmode = VF_TEXT;
@ -1725,7 +1724,6 @@ void VideoBenchmark () {
cycles -= executedcycles;
DiskUpdatePosition(executedcycles);
JoyUpdatePosition();
VideoUpdateVbl(0);
}
}
if (cycle & 1)
@ -1759,11 +1757,11 @@ void VideoBenchmark () {
}
//===========================================================================
BYTE __stdcall VideoCheckMode (WORD, WORD address, BYTE, BYTE, ULONG nCyclesLeft)
BYTE __stdcall VideoCheckMode (WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles)
{
address &= 0xFF;
if (address == 0x7F)
return MemReadFloatingBus(SW_DHIRES != 0, nCyclesLeft);
return MemReadFloatingBus(SW_DHIRES != 0, uExecutedCycles);
else {
BOOL result = 0;
switch (address) {
@ -1790,52 +1788,61 @@ void VideoCheckPage (BOOL force) {
}
//===========================================================================
BYTE __stdcall VideoCheckVbl (WORD, WORD, BYTE, BYTE, ULONG nCyclesLeft)
/*
// Drol expects = 80
68DE A5 02 LDX #02
68E0 AD 50 C0 LDA TXTCLR
68E3 C9 80 CMP #80
68E5 D0 F7 BNE $68DE
6957 A5 02 LDX #02
6959 AD 50 C0 LDA TXTCLR
695C C9 80 CMP #80
695E D0 F7 BNE $68DE
69D3 A5 02 LDX #02
69D5 AD 50 C0 LDA TXTCLR
69D8 C9 80 CMP #80
69DA D0 F7 BNE $68DE
// Karateka expects < 80
07DE AD 19 C0 LDA RDVBLBAR
07E1 30 FB BMI $7DE
77A1 AD 19 C0 LDA RDVBLBAR
77A4 30 FB BMI $7DE
// Gumball expects non-zero low-nibble on VBL
BBB5 A5 60 LDA $60
BBB7 4D 50 C0 EOR TXTCLR
BBBA 85 60 STA $60
BBBC 29 0F AND #$0F
BBBE F0 F5 BEQ $BBB5
BBC0 C9 0F CMP #$0F
BBC2 F0 F1 BEQ $BBB5
// Diversi-Dial (DD4.DSK or DIAL.DSK)
F822 LDA RDVBLBAR
F825 EOR #$3C
BMI $F82A
RTS
F82A LDA $F825+1
EOR #$80
STA $F825+1
BMI $F86A
...
F86A RTS
*/
BYTE __stdcall VideoCheckVbl (WORD, WORD, BYTE, BYTE, ULONG uExecutedCycles)
{
/*
// Drol expects = 80
68DE A5 02 LDX #02
68E0 AD 50 C0 LDA TXTCLR
68E3 C9 80 CMP #80
68E5 D0 F7 BNE $68DE
bool bVblBar = false;
VideoGetScannerAddress(&bVblBar, uExecutedCycles);
6957 A5 02 LDX #02
6959 AD 50 C0 LDA TXTCLR
695C C9 80 CMP #80
695E D0 F7 BNE $68DE
69D3 A5 02 LDX #02
69D5 AD 50 C0 LDA TXTCLR
69D8 C9 80 CMP #80
69DA D0 F7 BNE $68DE
// Karateka expects < 80
07DE AD 19 C0 LDA RDVBLBAR
07E1 30 FB BMI $7DE
77A1 AD 19 C0 LDA RDVBLBAR
77A4 30 FB BMI $7DE
// Gumball expects non-zero low-nibble on VBL
BBB5 A5 60 LDA $60
BBB7 4D 50 C0 EOR TXTCLR
BBBA 85 60 STA $60
BBBC 29 0F AND #$0F
BBBE F0 F5 BEQ $BBB5
BBC0 C9 0F CMP #$0F
BBC2 F0 F1 BEQ $BBB5
// return MemReturnRandomData(dwVBlCounter <= nVBlStop_NTSC);
if (dwVBlCounter <= nVBlStop_NTSC)
return (BYTE)(dwVBlCounter & 0x7F); // 0x00;
else
return 0x80 | ((BYTE)(dwVBlCounter & 1));
*/
bool bVblBar;
VideoGetScannerAddress(&bVblBar, nCyclesLeft);
BYTE r = KeybGetKeycode();
return (r & ~0x80) | ((bVblBar) ? 0x80 : 0);
BYTE r = KeybGetKeycode();
return (r & ~0x80) | ((bVblBar) ? 0x80 : 0);
}
//===========================================================================
@ -2319,7 +2326,7 @@ void VideoResetState () {
}
//===========================================================================
BYTE __stdcall VideoSetMode (WORD, WORD address, BYTE write, BYTE, ULONG nCyclesLeft)
BYTE __stdcall VideoSetMode (WORD, WORD address, BYTE write, BYTE, ULONG uExecutedCycles)
{
address &= 0xFF;
DWORD oldpage2 = SW_PAGE2;
@ -2374,14 +2381,7 @@ BYTE __stdcall VideoSetMode (WORD, WORD address, BYTE write, BYTE, ULONG nCycles
}
lastpageflip = emulmsec;
}
return MemReadFloatingBus(nCyclesLeft);
}
//===========================================================================
void VideoUpdateVbl (DWORD dwCyclesThisFrame)
{
dwVBlCounter = (DWORD) ((double)dwCyclesThisFrame / (double)uCyclesPerLine);
return MemReadFloatingBus(uExecutedCycles);
}
//===========================================================================
@ -2447,7 +2447,7 @@ WORD VideoGetScannerAddress(bool* pbVblBar_OUT, const DWORD uExecutedCycles)
{
// get video scanner position
//
int nCycles = CpuGetCyclesThisFrame(uExecutedCycles);
int nCycles = CpuGetCyclesThisVideoFrame(uExecutedCycles);
// machine state switches
//
@ -2560,7 +2560,7 @@ bool VideoGetVbl(const DWORD uExecutedCycles)
{
// get video scanner position
//
int nCycles = CpuGetCyclesThisFrame(uExecutedCycles);
int nCycles = CpuGetCyclesThisVideoFrame(uExecutedCycles);
// calculate video parameters according to display standard
//
@ -2589,6 +2589,8 @@ bool VideoGetVbl(const DWORD uExecutedCycles)
}
}
//===========================================================================
#define SCREENSHOT_BMP 1
#define SCREENSHOT_TGA 0

View File

@ -68,7 +68,6 @@ void VideoReinitialize ();
void VideoResetState ();
WORD VideoGetScannerAddress(bool* pbVblBar_OUT, const DWORD uExecutedCycles);
bool VideoGetVbl(DWORD uExecutedCycles);
void VideoUpdateVbl (DWORD dwCyclesThisFrame);
void VideoUpdateFlash();
bool VideoGetSW80COL();
DWORD VideoGetSnapshot(SS_IO_Video* pSS);
@ -98,6 +97,6 @@ enum VideoScreenShot_e
};
void Video_TakeScreenShot( int iScreenShotType );
BYTE __stdcall VideoCheckMode (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
BYTE __stdcall VideoCheckVbl (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
BYTE __stdcall VideoSetMode (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
BYTE __stdcall VideoCheckMode (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG uExecutedCycles);
BYTE __stdcall VideoCheckVbl (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG uExecutedCycles);
BYTE __stdcall VideoSetMode (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG uExecutedCycles);