Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Andrea Odetti 2020-06-14 09:03:55 +01:00
commit 66bb1b9905
27 changed files with 394 additions and 84 deletions

View file

@ -9,6 +9,19 @@ https://github.com/AppleWin/AppleWin/issues/new
Tom Charlesworth
1.29.13.0 - 31 May 2020
-----------------------
. [Bug #790] Fixed regression for -d1,-d2 & -s7-empty-on-exit (introduced at 1.29.7.0).
. [Change #787] Debugger: Extended 'cycles part' command to do timings relative to a user-specified base.
. [Change #783] Debugger: Extended 'tf' command to include cycle count.
. [Change #720] Debugger: Added more symbols to APPLE2E.SYM.
- NB. LC ($C08n) symbols are now correct for the LC, so 'LDA $C08C,X' will disassemble as 'LDA LCRAMIN1_,X'
instead of 'LDA DATASTROBE,X'. So now perhaps less helpful when stepping Disk II code.
. [PR #785] Debugger: Improvements to Bookmarks.
- AppleWin.chm: Added debugger help about Bookmarks.
. Fixed occasional speaker clicks in full-speed mode.
1.29.12.0 - 26 Apr 2020
-----------------------
. [PR #757] Allow use of an INI-file for configuration instead of the Registry (fixes #709).
@ -23,10 +36,10 @@ Tom Charlesworth
1.29.11.0 - 27 Mar 2020
-----------------------
. [Bug #771] Added new command line switch to load custom ROM: -rom <file>.
. [Change #771] Added new command line switch to load custom ROM: -rom <file>.
- Supports 12KiB (at $D000) and 16KiB (at $C000) rom files.
. [Bug #765] Lancaster (Total Replay) hangs when starting second game.
. [Bug #734] DiskII controller card: support 13-sector firmware.
. [Change #734] DiskII controller card: support 13-sector firmware.
- The card auto-selects the firmware based on the .woz (v2 or higher) image properties.
- Only change the firmware at reset/reboot to avoid changing whilst running in $C6xx space!
- Fixes 'The Best of MUSE' & 'MicroChess 2.0' (#732)
@ -54,7 +67,7 @@ Tom Charlesworth
. [Bug #748] DiskII: data latch returns a rand() value when no disk is in drive.
. [Bug #746] Debugger: correctly repaint Apple II screen when showing it from debugger.
. [Bug #745] WOZ: Support for large tracks.
. [Bug #743] Added new command line switches:
. [Change #743] Added new command line switches:
-left-alt-control-buttons : left-ctrl=button0, left-alt=button1
-right-alt-control-buttons : right-alt=button0, right-ctrl=button1
-swap-buttons : for swapping buttons 0 & 1

View file

@ -52,10 +52,12 @@
Useful to allow a floppy disk to boot from slot 6, drive 1. Use in combination with -d1.<br><br>
-s7-empty-on-exit<br>
Remove the hard disk controller card from slot 7 on AppleWin exit.<br><br>
-no-nsc<br>
Remove the No-Slot clock (NSC).<br><br>
-r &lt;number of pages&gt;<br>
Emulate a RamWorks III card with 1 to 127 pages (each page is 64K, giving a max of 8MB) in the auxiliary slot in an Apple //e machine.<br><br>
-load-state &lt;savestate&gt;<br>
Load a save-state file<br>
Load a save-state file (and auto power-on the Apple II).<br>
NB. This takes precedent over the -d1, -d2, -d#s#, -h1, -h2, s0-7, -model and -r switches.<br><br>
-f<br>
Start in full-screen mode<br><br>
@ -138,7 +140,10 @@
-50hz<br>
Support 50Hz(PAL) video refresh rate and PAL 1.016MHz base CPU clock.<br><br>
-60hz<br>
Support 60Hz(NTSC) video refresh rate and NTSC 1.020MHz base CPU clock (default).<br>
Support 60Hz(NTSC) video refresh rate and NTSC 1.020MHz base CPU clock (default).<br><br>
-power-on<br>
Force a power-on.<br>
Use to auto power-on when not using -d1, -h1 or -load-state.<br>
<br>
<P style="FONT-WEIGHT: bold">Debug arguments:

View file

@ -195,6 +195,10 @@
<param name="Name" value="Breakpoints">
<param name="Local" value="dbg-breakpoints.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Bookmarks">
<param name="Local" value="dbg-bookmarks.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Configuration">
<param name="Local" value="dbg-configuration.html">

View file

@ -12,7 +12,7 @@
<h3>Clock:</h3>
<p>AppleWin emulates a No-Slot clock (aka NSC).</p>
<p>This is a chip (a Dallas SmartWatch DS1216) that sits under one of the 28-pin ROM chips in the Apple II.<br>
No hardware configuration is required: this chip is always present, but won't interfere with emulation when not in use.
No hardware configuration is required: this chip is always present (unless -no-nsc is used), but won't interfere with emulation when not in use.
</p>
<p>It requires a software driver to be installed (for DOS and ProDOS). This driver then emulates the Thunderclock card.</p>
<p>Here's a summary of NSC/ROM chip locations and which drivers work:</p>

127
help/dbg-bookmarks.html Normal file
View file

@ -0,0 +1,127 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>AppleWin Debugger Tutorial</title>
<meta http-equiv="CONTENT-TYPE" content="text/html; charset=windows-1252">
</head>
<body style="DIRECTION: ltr" lang="en-US">
<h1>Bookmarks</h1>
<p>Bookmarks allow you to "tag" an address and consequently jump back to them.<br>
They appear as a number with a circle around them between where address and opcodes are listed (where the : separator is).
</p>
<img src="img/debugger-bookmarks-annotated.png" hspace="5" vspace="5">
<br>
<p><font size="4"><b>Notes</b>:</font></p>
<ul>
<li>Set a bookmark at the current disassembly cursor, use Ctrl-Shift-#, ie:
<ul>
<li>NB. Ctrl-Shift-0 can't be used, as it's not recognised by Windows
<li>Ctrl-Shift-1 set bookmark 1
<li>Ctrl-Shift-2 set bookmark 2
<li>...
<li>Ctrl-Shift-9 set bookmark 9
</ul>
</li>
<br>
<li>To jump to an existing bookmark, if it exists, press Ctrl-#, ie:
<ul>
<li>Ctrl-0 to jump to bookmark 0
<li>Ctrl-1 to jump to bookmark 1
<li>Ctrl-2 to jump to bookmark 2
<li>...
<li>Ctrl-9 to jump to bookmark 9
</ul>
</li>
<br>
<li>NB.
<ul>
<li>Bookmarks can appear in any order that you set - not just contiguous.
<li>An address can only have ONE bookmark assigned to it. If you try setting a new bookmark over an existing one, the old one will become free for use.
</ul>
</li>
</ul>
<p>
</p>
<p><font size="4"><b>Commands to manipulate bookmarks:</b></font></p>
<table border="1" cellpadding="2" cellspacing="0" width="75%">
<COLGROUP>
<col width="64">
<col width="192">
<tbody>
<tr bgcolor="#000000">
<td width="25%">
<p><font color="#ffffff"><b>Command</b></font></p>
</td>
<td>
<p><font color="#ffffff"><b>Description</b></font></p>
</td>
</tr>
<tr>
<td width="25%">
<p>help bookmarks</p>
</td>
<td>
<p>Lists all bookmark related commands</p>
</td>
</tr>
<tr>
<td width="25%">
<p>help bma</p>
</td>
<td>
<p>Lists specific help about the bma command</p>
</td>
</tr>
<tr>
<td width="25%">
<p>bma &lt;address|label&gt;</p>
</td>
<td>
<p>Add a bookmark at an address or label</p>
</td>
</tr>
<tr>
<td width="25%">
<p>bmc #</p>
</td>
<td>
<p>Clear a specific bookmarks, for example 'bmc 1' clears bookmark 1</p>
</td>
</tr>
<tr>
<td width="25%">
<p>bmc *</p>
</td>
<td>
<p>Clears all bookmarks</p>
</td>
</tr>
<tr>
<td width="25%">
<p>bml</p>
</td>
<td>
<p>Lists all boommarks</p>
</td>
</tr>
<tr>
<td width="25%">
<p>bmsave</p>
</td>
<td>
<p>Not implemented yet</p>
</td>
</tr>
</tbody>
</table>
</body>
</html>

View file

@ -27,6 +27,7 @@
<LI><A href="dbg-calculator.html">Calculator</A>
<LI><A href="dbg-windows.html">Windows</A>
<LI><A href="dbg-breakpoints.html">Breakpoints</A>
<LI><A href="dbg-bookmarks.html">Bookmarks</A>
<LI><A href="dbg-configuration.html">Configuration</A>
<UL>
<LI><A href="dbg-configuration.html#Colors">Colors</A>

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View file

@ -31,12 +31,12 @@
<li>CP/M SoftCard</li>
<li>Parallel Printer card</li>
<li>Super Serial card</li>
<li>No-Slot clock</li>
</ul>
The following are not yet persisted to the file:
<ul>
<li>Uthernet card</li>
<li>SAM card</li>
<li>No-Slot clock (there's nothing to persist)</li>
<li>Using The Freeze's F8 ROM</li>
<li>Alternate F8 ROM</li>
<li>Alternate ROM</li>

View file

@ -1,4 +1,4 @@
#define APPLEWIN_VERSION 1,29,12,0
#define APPLEWIN_VERSION 1,29,13,0
#define xstr(a) str(a)
#define str(a) #a

View file

@ -82,6 +82,7 @@ AppMode_e g_nAppMode = MODE_LOGO;
static bool g_bLoadedSaveState = false;
static bool g_bSysClkOK = false;
std::string g_sStartDir; // NB. AppleWin.exe maybe relative to this! (GH#663)
std::string g_sProgramDir; // Directory of where AppleWin executable resides
std::string g_sDebugDir; // TODO: Not currently used
std::string g_sScreenShotDir; // TODO: Not currently used
@ -541,7 +542,8 @@ void EnterMessageLoop(void)
}
//===========================================================================
void GetProgramDirectory(void)
static void GetProgramDirectory(void)
{
TCHAR programDir[MAX_PATH];
GetModuleFileName((HINSTANCE)0, programDir, MAX_PATH);
@ -1141,19 +1143,27 @@ static std::string GetFullPath(LPCSTR szFileName)
}
else
{
// Rel pathname
char szCWD[_MAX_PATH] = {0};
if (!GetCurrentDirectory(sizeof(szCWD), szCWD))
return "";
strPathName = szCWD;
strPathName.append("\\");
// Rel pathname (GH#663)
strPathName = g_sStartDir;
strPathName.append(szFileName);
}
return strPathName;
}
static void SetCurrentDir(std::string pathname)
{
// Due to the order HDDs/disks are inserted, then s7 insertions take priority over s6 & s5; and d2 takes priority over d1:
// . if -s6[dN] and -hN are specified, then g_sCurrentDir will be set to the HDD image's path
// . if -s5[dN] and -s6[dN] are specified, then g_sCurrentDir will be set to the s6 image's path
// . if -[sN]d1 and -[sN]d2 are specified, then g_sCurrentDir will be set to the d2 image's path
// This is purely dependent on the current order of InsertFloppyDisks() & InsertHardDisks() - ie. very brittle!
// . better to use -current-dir to be explicit
std::size_t found = pathname.find_last_of("\\");
std::string path = pathname.substr(0, found);
SetCurrentImageDir(path);
}
static bool DoDiskInsert(const UINT slot, const int nDrive, LPCSTR szFileName)
{
Disk2InterfaceCard& disk2Card = dynamic_cast<Disk2InterfaceCard&>(g_CardMgr.GetRef(slot));
@ -1162,7 +1172,10 @@ static bool DoDiskInsert(const UINT slot, const int nDrive, LPCSTR szFileName)
if (strPathName.empty()) return false;
ImageError_e Error = disk2Card.InsertDisk(nDrive, strPathName.c_str(), IMAGE_USE_FILES_WRITE_PROTECT_STATUS, IMAGE_DONT_CREATE);
return Error == eIMAGE_ERROR_NONE;
bool res = (Error == eIMAGE_ERROR_NONE);
if (res)
SetCurrentDir(strPathName);
return res;
}
static bool DoHardDiskInsert(const int nDrive, LPCSTR szFileName)
@ -1171,7 +1184,10 @@ static bool DoHardDiskInsert(const int nDrive, LPCSTR szFileName)
if (strPathName.empty()) return false;
BOOL bRes = HD_Insert(nDrive, strPathName.c_str());
return bRes ? true : false;
bool res = (bRes == TRUE);
if (res)
SetCurrentDir(strPathName);
return res;
}
static void InsertFloppyDisks(const UINT slot, LPSTR szImageName_drive[NUM_DRIVES], bool& bBoot)
@ -1211,11 +1227,9 @@ static void InsertHardDisks(LPSTR szImageName_harddisk[NUM_HARDDISKS], bool& bBo
HD_SetEnabled(true);
DWORD dwTmp;
if (REGLOAD(TEXT(REGVALUE_HDD_ENABLED), &dwTmp))
{
if (!dwTmp)
REGSAVE(TEXT(REGVALUE_HDD_ENABLED), 1); // Config: HDD Enabled
}
BOOL res = REGLOAD(TEXT(REGVALUE_HDD_ENABLED), &dwTmp);
if (!res || !dwTmp)
REGSAVE(TEXT(REGVALUE_HDD_ENABLED), 1); // Config: HDD Enabled
//
@ -1244,11 +1258,9 @@ static void UnplugHardDiskControllerCard(void)
HD_SetEnabled(false);
DWORD dwTmp;
if (REGLOAD(TEXT(REGVALUE_HDD_ENABLED), &dwTmp))
{
if (dwTmp)
REGSAVE(TEXT(REGVALUE_HDD_ENABLED), 0); // Config: HDD Disabled
}
BOOL res = REGLOAD(TEXT(REGVALUE_HDD_ENABLED), &dwTmp);
if (!res || dwTmp)
REGSAVE(TEXT(REGVALUE_HDD_ENABLED), 0); // Config: HDD Disabled
}
static bool CheckOldAppleWinVersion(void)
@ -1306,6 +1318,7 @@ struct CmdLine
bSlot0LanguageCard = false;
bSlot7EmptyOnExit = false;
bSwapButtons0and1 = false;
bRemoveNoSlotClock = false;
bestWidth = 0;
bestHeight = 0;
szImageName_harddisk[HARDDISK_1] = NULL;
@ -1338,6 +1351,7 @@ struct CmdLine
bool bSlotEmpty[NUM_SLOTS];
bool bSlot7EmptyOnExit;
bool bSwapButtons0and1;
bool bRemoveNoSlotClock;
SS_CARDTYPE slotInsert[NUM_SLOTS];
UINT bestWidth;
UINT bestHeight;
@ -1353,15 +1367,22 @@ struct CmdLine
VideoRefreshRate_e newVideoRefreshRate;
double clockMultiplier;
eApple2Type model;
std::string strCurrentDir;
};
static CmdLine g_cmdLine;
int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
{
char startDir[_MAX_PATH];
GetCurrentDirectory(sizeof(startDir), startDir);
g_sStartDir = startDir;
if (*(g_sStartDir.end()-1) != '\\') g_sStartDir += '\\';
if (!ProcessCmdLine(lpCmdLine))
return 0;
LogFileOutput("g_sStartDir = %s\n", g_sStartDir.c_str());
GetAppleWinVersion();
OneTimeInitialization(passinstance);
@ -1504,15 +1525,15 @@ static bool ProcessCmdLine(LPSTR lpCmdLine)
g_cmdLine.szImageName_drive[slot][drive] = lpCmdLine;
}
}
else if (strcmp(lpCmdLine, "-s7-empty-on-exit") == 0)
{
g_cmdLine.bSlot7EmptyOnExit = true;
}
else
{
LogFileOutput("Unsupported arg: %s\n", lpCmdLine);
}
}
else if (strcmp(lpCmdLine, "-s7-empty-on-exit") == 0)
{
g_cmdLine.bSlot7EmptyOnExit = true;
}
else if (strcmp(lpCmdLine, "-load-state") == 0)
{
lpCmdLine = GetCurrArg(lpNextArg);
@ -1773,6 +1794,20 @@ static bool ProcessCmdLine(LPSTR lpCmdLine)
{
g_cmdLine.newVideoRefreshRate = VR_60HZ;
}
else if (strcmp(lpCmdLine, "-power-on") == 0)
{
g_cmdLine.bBoot = true;
}
else if (strcmp(lpCmdLine, "-current-dir") == 0)
{
lpCmdLine = GetCurrArg(lpNextArg);
lpNextArg = GetNextArg(lpNextArg);
g_cmdLine.strCurrentDir = lpCmdLine;
}
else if (strcmp(lpCmdLine, "-no-nsc") == 0)
{
g_cmdLine.bRemoveNoSlotClock = true;
}
else // unsupported
{
LogFileOutput("Unsupported arg: %s\n", lpCmdLine);
@ -1964,6 +1999,8 @@ static void RepeatInitialization(void)
LogFileOutput("Main: FrameCreateWindow() - post\n");
// Allow the 4 hardcoded slots to be configurated as empty
// NB. this state is not persisted to the Registry/conf.ini (just as '-s7 empty' isn't)
// TODO: support bSlotEmpty[] for slots: 0,4,5
if (g_cmdLine.bSlotEmpty[SLOT1])
g_CardMgr.Remove(SLOT1);
if (g_cmdLine.bSlotEmpty[SLOT2])
@ -1998,9 +2035,16 @@ static void RepeatInitialization(void)
g_cmdLine.szImageName_harddisk[HARDDISK_1] = g_cmdLine.szImageName_harddisk[HARDDISK_2] = NULL; // Don't insert on a restart
if (g_cmdLine.bSlotEmpty[7])
HD_SetEnabled(false);
HD_SetEnabled(false); // Disable HDD controller, but don't persist this to Registry/conf.ini (consistent with other '-sn empty' cmds)
}
// Set *after* InsertFloppyDisks() & InsertHardDisks(), which both update g_sCurrentDir
if (!g_cmdLine.strCurrentDir.empty())
SetCurrentImageDir(g_cmdLine.strCurrentDir);
if (g_cmdLine.bRemoveNoSlotClock)
MemRemoveNoSlotClock();
MemInitialize();
LogFileOutput("Main: MemInitialize()\n");

View file

@ -46,12 +46,12 @@ void CardManager::Insert(UINT slot, SS_CARDTYPE type)
switch (type)
{
case CT_Disk2:
m_slot[slot] = new Disk2InterfaceCard;
m_slot[slot] = new Disk2InterfaceCard(slot);
break;
case CT_SSC:
_ASSERT(m_pSSC == NULL);
if (m_pSSC) break; // Only support one SSC
m_slot[slot] = m_pSSC = new CSuperSerialCard;
m_slot[slot] = m_pSSC = new CSuperSerialCard(slot);
break;
case CT_MockingboardC:
m_slot[slot] = new DummyCard(type);

View file

@ -161,7 +161,7 @@ enum eIRQSRC {IS_6522=0, IS_SPEECH, IS_SSC, IS_MOUSE};
#define APPLECLONE_MASK 0x100
#define IS_APPLE2 ((g_Apple2Type & (APPLE2E_MASK|APPLE2C_MASK)) == 0)
#define IS_APPLE2E() (g_Apple2Type & APPLE2E_MASK)
//#define IS_APPLE2E() (g_Apple2Type & APPLE2E_MASK) // unused
#define IS_APPLE2C() (g_Apple2Type & APPLE2C_MASK)
#define IS_CLONE() (g_Apple2Type & APPLECLONE_MASK)
@ -218,6 +218,11 @@ inline bool IsApple2PlusOrClone(eApple2Type type) // Apple ][,][+,][J-Plus or cl
return (type & (APPLE2E_MASK|APPLE2C_MASK)) == 0;
}
inline bool IsAppleIIeOrAbove(eApple2Type type) // Apple //e,Enhanced//e,//c or clone //e,Enhanced//e
{
return !IsApple2PlusOrClone(type);
}
extern eApple2Type g_Apple2Type;
inline bool IsEnhancedIIE(void)
{

View file

@ -8160,7 +8160,17 @@ void OutputTraceLine ()
char sDisassembly[ CONSOLE_WIDTH ]; // DrawDisassemblyLine( 0,regs.pc, sDisassembly); // Get Disasm String
FormatDisassemblyLine( line, sDisassembly, CONSOLE_WIDTH );
char sFlags[ _6502_NUM_FLAGS + 1 ]; DrawFlags( 0, regs.ps, sFlags ); // Get Flags String
char sFlags[] = "........";
WORD nRegFlags = regs.ps;
int nFlag = _6502_NUM_FLAGS;
while (nFlag--)
{
int iFlag = (_6502_NUM_FLAGS - nFlag - 1);
bool bSet = (nRegFlags & 1);
if (bSet)
sFlags[nFlag] = g_aBreakpointSource[BP_SRC_FLAG_C + iFlag][0];
nRegFlags >>= 1;
}
if (!g_hTraceFile)
return;
@ -8178,8 +8188,8 @@ void OutputTraceLine ()
else
{
fprintf( g_hTraceFile,
// "00 00 00 0000 -------- 0000:90 90 90 NOP"
"A: X: Y: SP: Flags Addr:Opcode Mnemonic\n");
// "00000000 00 00 00 0000 -------- 0000:90 90 90 NOP"
"Cycles A: X: Y: SP: Flags Addr:Opcode Mnemonic\n");
}
}
@ -8214,8 +8224,10 @@ void OutputTraceLine ()
}
else
{
const UINT cycles = (UINT)g_nCumulativeCycles;
fprintf( g_hTraceFile,
"%02X %02X %02X %04X %s %s\n",
"%08X %02X %02X %02X %04X %s %s\n",
cycles,
(unsigned)regs.a,
(unsigned)regs.x,
(unsigned)regs.y,

View file

@ -2340,9 +2340,8 @@ WORD DrawDisassemblyLine ( int iLine, const WORD nBaseAddress )
}
// Optionally copy the flags to pText_
//===========================================================================
void DrawFlags ( int line, WORD nRegFlags, LPTSTR pFlagNames_)
static void DrawFlags ( int line, WORD nRegFlags )
{
if (! ((g_iWindowThis == WINDOW_CODE) || ((g_iWindowThis == WINDOW_DATA))))
return;
@ -2431,19 +2430,8 @@ void DrawFlags ( int line, WORD nRegFlags, LPTSTR pFlagNames_)
rect.top -= g_nFontHeight;
rect.bottom -= g_nFontHeight;
if (pFlagNames_)
{
if (!bSet)
sFlagNames[nFlag] = '.';
else
sFlagNames[nFlag] = g_aBreakpointSource[ BP_SRC_FLAG_C + iFlag ][0];
}
nRegFlags >>= 1;
}
if (pFlagNames_)
strcpy(pFlagNames_,sFlagNames);
}
//===========================================================================
@ -2732,7 +2720,7 @@ void DrawRegisters ( int line )
DrawRegister( line++, sReg[ BP_SRC_REG_X ] , 1, regs.x , PARAM_REG_X );
DrawRegister( line++, sReg[ BP_SRC_REG_Y ] , 1, regs.y , PARAM_REG_Y );
DrawRegister( line++, sReg[ BP_SRC_REG_PC] , 2, regs.pc, PARAM_REG_PC );
DrawFlags ( line , regs.ps, NULL);
DrawFlags ( line , regs.ps);
line += 2;
DrawRegister( line++, sReg[ BP_SRC_REG_S ] , 2, regs.sp, PARAM_REG_SP );
}

View file

@ -81,8 +81,6 @@
void FormatOpcodeBytes ( WORD nBaseAddress, DisasmLine_t & line_ );
void FormatNopcodeBytes ( WORD nBaseAddress, DisasmLine_t & line_ );
void DrawFlags ( int line, WORD nRegFlags, LPTSTR pFlagNames_);
//
extern HDC GetDebuggerMemDC(void);

View file

@ -53,14 +53,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// . if false && I/O ReadWrite($C0EC) && drive is spinning, then advance the track buffer's nibble index (to simulate spinning).
// Also m_enhanceDisk is persisted to the save-state, so it's an attribute of the DiskII interface card.
Disk2InterfaceCard::Disk2InterfaceCard(void) :
Card(CT_Disk2)
Disk2InterfaceCard::Disk2InterfaceCard(UINT slot) :
Card(CT_Disk2),
m_slot(slot)
{
ResetSwitches();
m_floppyLatch = 0;
m_saveDiskImage = true; // Save the DiskImage name to Registry
m_slot = 0;
m_diskLastCycle = 0;
m_diskLastReadLatchCycle = 0;
m_enhanceDisk = true;
@ -1770,6 +1770,7 @@ void Disk2InterfaceCard::Initialize(LPBYTE pCxRomPeripheral, UINT uSlot)
// . Patching the firmware breaks the ADC checksum used by "The CIA Files" (Tricky Dick)
// . In this case we can patch to compensate for an ADC or EOR checksum but not both (nickw)
_ASSERT(m_slot == uSlot);
RegisterIoHandler(uSlot, &Disk2InterfaceCard::IORead, &Disk2InterfaceCard::IOWrite, NULL, NULL, this, NULL);
m_slot = uSlot;

View file

@ -120,7 +120,7 @@ public:
class Disk2InterfaceCard : public Card
{
public:
Disk2InterfaceCard(void);
Disk2InterfaceCard(UINT slot);
virtual ~Disk2InterfaceCard(void);
virtual void Init(void) {};

View file

@ -2297,7 +2297,7 @@ void ResetMachineState ()
HD_Reset();
g_bFullSpeed = 0; // Might've hit reset in middle of InternalCpuExecute() - so beep may get (partially) muted
MemReset(); // calls CpuInitialize()
MemReset(); // calls CpuInitialize(), CNoSlotClock.Reset()
PravetsReset();
if (g_CardMgr.QuerySlot(SLOT6) == CT_Disk2)
dynamic_cast<Disk2InterfaceCard&>(g_CardMgr.GetRef(SLOT6)).Boot();

View file

@ -210,7 +210,7 @@ static LPBYTE g_pMemMainLanguageCard = NULL;
static DWORD memmode = LanguageCardUnit::kMemModeInitialState;
static BOOL modechanging = 0; // An Optimisation: means delay calling UpdatePaging() for 1 instruction
static CNoSlotClock g_NoSlotClock;
static CNoSlotClock* g_NoSlotClock = new CNoSlotClock;
static LanguageCardUnit* g_pLanguageCard = NULL; // For all Apple II, //e and above
#ifdef RAMWORKS
@ -832,17 +832,17 @@ static BYTE __stdcall IO_Cxxx(WORD programcounter, WORD address, BYTE write, BYT
}
}
if (IsPotentialNoSlotClockAccess(address))
if (g_NoSlotClock && IsPotentialNoSlotClockAccess(address))
{
if (!write)
{
int data = 0;
if (g_NoSlotClock.Read(address, data))
if (g_NoSlotClock->Read(address, data))
return (BYTE) data;
}
else
{
g_NoSlotClock.Write(address);
g_NoSlotClock->Write(address);
return 0;
}
}
@ -1763,19 +1763,17 @@ void MemInitializeIO(void)
if (g_CardMgr.QuerySlot(SLOT7) == CT_GenericHDD)
HD_Load_Rom(pCxRomPeripheral, SLOT7); // $C700 : HDD f/w
//
// Finally remove the cards' ROMs at $Csnn if internal ROM is enabled
// . required when restoring saved-state
if (SW_INTCXROM)
IoHandlerCardsOut();
}
// Called by:
// . Snapshot_LoadState_v2()
void MemInitializeCardExpansionRomFromSnapshot(void)
void MemInitializeCardSlotAndExpansionRomFromSnapshot(void)
{
// Remove all the cards' ROMs at $Csnn if internal ROM is enabled
if (IsAppleIIeOrAbove(GetApple2Type()) && SW_INTCXROM)
IoHandlerCardsOut();
// Potentially init a card's expansion ROM
const UINT uSlot = g_uPeripheralRomSlot;
if (ExpansionRom[uSlot] == NULL)
@ -1795,7 +1793,7 @@ inline DWORD getRandomTime()
//===========================================================================
// Called by:
// . MemInitialize()
// . MemInitialize() eg. on AppleWin start & restart (eg. h/w config changes)
// . ResetMachineState() eg. Power-cycle ('Apple-Go' button)
// . Snapshot_LoadState_v2()
void MemReset()
@ -1942,7 +1940,7 @@ void MemReset()
mem = memimage;
// INITIALIZE PAGING, FILLING IN THE 64K MEMORY IMAGE
ResetPaging(1); // Initialize=1
ResetPaging(TRUE); // Initialize=1, init memmode
// INITIALIZE & RESET THE CPU
// . Do this after ROM has been copied back to mem[], so that PC is correctly init'ed from 6502's reset vector
@ -1950,6 +1948,9 @@ void MemReset()
//Sets Caps Lock = false (Pravets 8A/C only)
z80_reset(); // NB. Also called above in CpuInitialize()
if (g_NoSlotClock)
g_NoSlotClock->Reset(); // NB. Power-cycle, but not RESET signal
}
//===========================================================================
@ -2092,7 +2093,7 @@ BYTE __stdcall MemSetPaging(WORD programcounter, WORD address, BYTE write, BYTE
bool MemOptimizeForModeChanging(WORD programcounter, WORD address)
{
if (IS_APPLE2E())
if (IsAppleIIeOrAbove(GetApple2Type()))
{
// IF THE EMULATED PROGRAM HAS JUST UPDATED THE MEMORY WRITE MODE AND IS
// ABOUT TO UPDATE THE MEMORY READ MODE, HOLD OFF ON ANY PROCESSING UNTIL
@ -2136,6 +2137,26 @@ bool MemGetAnnunciator(UINT annunciator)
//===========================================================================
bool MemHasNoSlotClock(void)
{
return g_NoSlotClock != NULL;
}
void MemInsertNoSlotClock(void)
{
if (!MemHasNoSlotClock())
g_NoSlotClock = new CNoSlotClock;
g_NoSlotClock->Reset();
}
void MemRemoveNoSlotClock(void)
{
delete g_NoSlotClock;
g_NoSlotClock = NULL;
}
//===========================================================================
// NB. Don't need to save 'modechanging', as this is just an optimisation to save calling UpdatePaging() twice.
// . If we were to save the state when 'modechanging' is set, then on restoring the state, the 6502 code will immediately update the read memory mode.
// . This will work correctly.
@ -2452,3 +2473,17 @@ bool MemLoadSnapshotAux(YamlLoadHelper& yamlLoadHelper, UINT unitVersion)
return true;
}
void NoSlotClockSaveSnapshot(YamlSaveHelper& yamlSaveHelper)
{
if (g_NoSlotClock)
g_NoSlotClock->SaveSnapshot(yamlSaveHelper);
}
void NoSlotClockLoadSnapshot(YamlLoadHelper& yamlLoadHelper)
{
if (!g_NoSlotClock)
g_NoSlotClock = new CNoSlotClock;
g_NoSlotClock->LoadSnapshot(yamlLoadHelper);
}

View file

@ -75,7 +75,7 @@ void MemInitializeROM(void);
void MemInitializeCustomROM(void);
void MemInitializeCustomF8ROM(void);
void MemInitializeIO(void);
void MemInitializeCardExpansionRomFromSnapshot(void);
void MemInitializeCardSlotAndExpansionRomFromSnapshot(void);
BYTE MemReadFloatingBus(const ULONG uExecutedCycles);
BYTE MemReadFloatingBus(const BYTE highbit, const ULONG uExecutedCycles);
void MemReset ();
@ -83,11 +83,16 @@ void MemResetPaging ();
void MemUpdatePaging(BOOL initialize);
LPVOID MemGetSlotParameters (UINT uSlot);
bool MemGetAnnunciator(UINT annunciator);
bool MemHasNoSlotClock(void);
void MemInsertNoSlotClock(void);
void MemRemoveNoSlotClock(void);
std::string MemGetSnapshotUnitAuxSlotName(void);
void MemSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
bool MemLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT unitVersion);
void MemSaveSnapshotAux(class YamlSaveHelper& yamlSaveHelper);
bool MemLoadSnapshotAux(class YamlLoadHelper& yamlLoadHelper, UINT unitVersion);
void NoSlotClockSaveSnapshot(YamlSaveHelper& yamlSaveHelper);
void NoSlotClockLoadSnapshot(YamlLoadHelper& yamlLoadHelper);
BYTE __stdcall IO_Null(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles);

View file

@ -181,6 +181,7 @@ void CMouseInterface::Initialize(LPBYTE pCxRomPeripheral, UINT uSlot)
{
// m_bActive = true;
m_bEnabled = true;
_ASSERT(m_uSlot == uSlot);
SetSlotRom(); // Pre: m_bActive == true
RegisterIoHandler(uSlot, &CMouseInterface::IORead, &CMouseInterface::IOWrite, NULL, NULL, this, NULL);
}

View file

@ -41,6 +41,7 @@ All the other drivers and utilities available to me don't define the DOW mapping
#include "StdAfx.h"
#include "NoSlotClock.h"
#include "YamlHelper.h"
CNoSlotClock::CNoSlotClock()
:
@ -166,6 +167,45 @@ void CNoSlotClock::PopulateClockRegister()
m_ClockRegister.WriteNibble(year / 10);
}
#define SS_YAML_KEY_CLOCK_REGISTER_ENABLED "Clock Register Enabled"
#define SS_YAML_KEY_WRITE_ENABLED "Write Enabled"
#define SS_YAML_KEY_CLOCK_REGISTER_MASK "Clock Register Mask"
#define SS_YAML_KEY_CLOCK_REGISTER "Clock Register"
#define SS_YAML_KEY_COMPARISON_REGISTER_MASK "Comparison Register Mask"
#define SS_YAML_KEY_COMPARISON_REGISTER "Comparison Register"
std::string CNoSlotClock::GetSnapshotStructName(void)
{
static const std::string name("No Slot Clock");
return name;
}
void CNoSlotClock::SaveSnapshot(YamlSaveHelper& yamlSaveHelper)
{
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", GetSnapshotStructName().c_str());
yamlSaveHelper.SaveBool(SS_YAML_KEY_CLOCK_REGISTER_ENABLED, m_bClockRegisterEnabled);
yamlSaveHelper.SaveBool(SS_YAML_KEY_WRITE_ENABLED, m_bWriteEnabled);
yamlSaveHelper.SaveHexUint64(SS_YAML_KEY_CLOCK_REGISTER_MASK, m_ClockRegister.m_Mask);
yamlSaveHelper.SaveHexUint64(SS_YAML_KEY_CLOCK_REGISTER, m_ClockRegister.m_Register);
yamlSaveHelper.SaveHexUint64(SS_YAML_KEY_COMPARISON_REGISTER_MASK, m_ComparisonRegister.m_Mask);
yamlSaveHelper.SaveHexUint64(SS_YAML_KEY_COMPARISON_REGISTER, m_ComparisonRegister.m_Register);
}
void CNoSlotClock::LoadSnapshot(YamlLoadHelper& yamlLoadHelper)
{
if (!yamlLoadHelper.GetSubMap(GetSnapshotStructName()))
return;
m_bClockRegisterEnabled = yamlLoadHelper.LoadBool(SS_YAML_KEY_CLOCK_REGISTER_ENABLED);
m_bWriteEnabled = yamlLoadHelper.LoadBool(SS_YAML_KEY_WRITE_ENABLED);
m_ClockRegister.m_Mask = yamlLoadHelper.LoadUint64(SS_YAML_KEY_CLOCK_REGISTER_MASK);
m_ClockRegister.m_Register = yamlLoadHelper.LoadUint64(SS_YAML_KEY_CLOCK_REGISTER);
m_ComparisonRegister.m_Mask = yamlLoadHelper.LoadUint64(SS_YAML_KEY_COMPARISON_REGISTER_MASK);
m_ComparisonRegister.m_Register = yamlLoadHelper.LoadUint64(SS_YAML_KEY_COMPARISON_REGISTER);
yamlLoadHelper.PopMap();
}
CNoSlotClock::RingRegister64::RingRegister64()
{
Reset();

View file

@ -57,6 +57,9 @@ public:
bool ClockRead(int& data);
void ClockWrite(int address);
void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
void LoadSnapshot(class YamlLoadHelper& yamlLoadHelper);
bool m_bClockRegisterEnabled;
bool m_bWriteEnabled;
RingRegister64 m_ClockRegister;
@ -64,6 +67,7 @@ public:
private:
void PopulateClockRegister();
std::string GetSnapshotStructName(void);
static const UINT64 kClockInitSequence = 0x5CA33AC55CA33AC5;
};

View file

@ -71,10 +71,13 @@ static YamlHelper yamlHelper;
// v3: Extended: memory (added 'AnnunciatorN')
// v4: Extended: video (added 'Video Refresh Rate')
// v5: Extended: cpu (added 'Defer IRQ By 1 Opcode')
#define UNIT_APPLE2_VER 5
// v6: Added 'Unit Miscellaneous' for NoSlotClock(NSC)
#define UNIT_APPLE2_VER 6
#define UNIT_SLOTS_VER 1
#define UNIT_MISC_VER 1
//-----------------------------------------------------------------------------
void Snapshot_SetFilename(const std::string & strPathname)
@ -134,6 +137,12 @@ static std::string GetSnapshotUnitSlotsName(void)
return name;
}
static std::string GetSnapshotUnitMiscName(void)
{
static const std::string name("Miscellaneous");
return name;
}
#define SS_YAML_KEY_MODEL "Model"
#define SS_YAML_VALUE_APPLE2 "Apple]["
@ -353,6 +362,9 @@ static void ParseUnit(void)
if (unit == GetSnapshotUnitApple2Name())
{
ParseUnitApple2(yamlLoadHelper, unitVersion);
if (unitVersion < 6) MemInsertNoSlotClock(); // NSC always inserted
else MemRemoveNoSlotClock(); // NSC only add if there's a misc unit
}
else if (unit == MemGetSnapshotUnitAuxSlotName())
{
@ -362,6 +374,11 @@ static void ParseUnit(void)
{
ParseSlots(yamlLoadHelper, unitVersion);
}
else if (unit == GetSnapshotUnitMiscName())
{
// NB. could extend for other misc devices - see how ParseSlots() calls GetMapNextSlotNumber()
NoSlotClockLoadSnapshot(yamlLoadHelper);
}
else
{
throw std::string(SS_YAML_KEY_UNIT ": Unknown type: " ) + unit;
@ -371,6 +388,7 @@ static void ParseUnit(void)
static void Snapshot_LoadState_v2(void)
{
bool restart = false; // Only need to restart if any VM state has change
HCURSOR oldcursor = SetCursor(LoadCursor(0,IDC_WAIT));
try
{
@ -454,7 +472,7 @@ static void Snapshot_LoadState_v2(void)
MemInitializeCustomROM();
MemInitializeCustomF8ROM();
MemInitializeIO();
MemInitializeCardExpansionRomFromSnapshot();
MemInitializeCardSlotAndExpansionRomFromSnapshot();
MemUpdatePaging(TRUE);
@ -474,6 +492,7 @@ static void Snapshot_LoadState_v2(void)
PostMessage(g_hFrameWindow, WM_USER_RESTART, 0, 0); // Power-cycle VM (undoing all the new state just loaded)
}
SetCursor(oldcursor);
yamlHelper.FinaliseParser();
}
@ -568,6 +587,15 @@ void Snapshot_SaveState(void)
if (g_CardMgr.QuerySlot(SLOT7) == CT_GenericHDD)
HD_SaveSnapshot(yamlSaveHelper);
}
// Miscellaneous
if (MemHasNoSlotClock())
{
yamlSaveHelper.UnitHdr(GetSnapshotUnitMiscName(), UNIT_MISC_VER);
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
NoSlotClockSaveSnapshot(yamlSaveHelper);
}
}
catch(std::string szMessage)
{

View file

@ -64,9 +64,9 @@ SSC_DIPSW CSuperSerialCard::m_DIPSWDefault =
//===========================================================================
CSuperSerialCard::CSuperSerialCard() :
CSuperSerialCard::CSuperSerialCard(UINT slot) :
Card(CT_SSC),
m_uSlot(0),
m_uSlot(slot),
m_aySerialPortChoices(NULL),
m_uTCPChoiceItemIdx(0),
m_bCfgSupportDCD(false),
@ -957,10 +957,9 @@ void CSuperSerialCard::CommInitialize(LPBYTE pCxRomPeripheral, UINT uSlot)
if(pData == NULL)
return;
_ASSERT(m_uSlot == uSlot);
memcpy(pCxRomPeripheral + uSlot*256, pData+SSC_SLOT_FW_OFFSET, SSC_SLOT_FW_SIZE);
m_uSlot = uSlot;
// Expansion ROM
if (m_pExpansionRom == NULL)
{

View file

@ -25,7 +25,7 @@ typedef struct
class CSuperSerialCard : public Card
{
public:
CSuperSerialCard();
CSuperSerialCard(UINT slot);
virtual ~CSuperSerialCard();
virtual void Init(void) {};