diff --git a/AppleWin/docs/History.txt b/AppleWin/docs/History.txt
index abcdd51a..e7bac1df 100644
--- a/AppleWin/docs/History.txt
+++ b/AppleWin/docs/History.txt
@@ -12,10 +12,20 @@ https://developer.berlios.de/feature/?func=addfeature&group_id=6117
Tom Charlesworth
tomch at users.berlios.de
-1.23.1 - 8 Aug 2013
+1.23.2 - 14 Sep 2013
--------------------
Changes:
. Added About dialog showing GPL (at startup, but only when AppleWin version changes).
+. [Bug #18940] Extend BSAVE and BLOAD Command To Memory Banks 0 and 1
+ Extended debugger BLOAD with bank support:
+ . BLOAD [file],[bank:]address[,length]
+ . BLOAD [file],[bank:]address[:end]
+ . If no filename specified, will use last BLOAD or BSAVE filename.
+ Extended debugger BSAVE with bank support:
+ . BSAVE [file],[bank:]address,length
+ . BSAVE [file],[bank:]address:end
+ . If no filename specified, defaults to: '####.####.[bank##].bin'
+ (where the form is
..bin)
Fixes:
. Fixed save-state bug for when 4K BANK1 is dirty (previously it would save the stale data instead).
diff --git a/AppleWin/resource/Applewin.rc b/AppleWin/resource/Applewin.rc
index 0d2e57a4..be227717 100644
--- a/AppleWin/resource/Applewin.rc
+++ b/AppleWin/resource/Applewin.rc
@@ -246,8 +246,8 @@ DISK_ICON ICON "DISK.ICO"
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,23,1,0
- PRODUCTVERSION 1,23,1,0
+ FILEVERSION 1,23,2,0
+ PRODUCTVERSION 1,23,2,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -265,12 +265,12 @@ BEGIN
VALUE "Comments", "http://applewin.berlios.de"
VALUE "CompanyName", "AppleWin"
VALUE "FileDescription", "Apple //e Emulator for Windows"
- VALUE "FileVersion", "1, 23, 1, 0"
+ VALUE "FileVersion", "1, 23, 2, 0"
VALUE "InternalName", "APPLEWIN"
VALUE "LegalCopyright", " 1994-2013 Michael O'Brien, Oliver Schmidt, Tom Charlesworth, Michael Pohoreski, Nick Westgate, Linards Ticmanis"
VALUE "OriginalFilename", "APPLEWIN.EXE"
VALUE "ProductName", "Apple //e Emulator"
- VALUE "ProductVersion", "1, 23, 1, 0"
+ VALUE "ProductVersion", "1, 23, 2, 0"
END
END
BLOCK "VarFileInfo"
diff --git a/AppleWin/source/Debugger/Debug.cpp b/AppleWin/source/Debugger/Debug.cpp
index c052fa8f..3815ce3f 100644
--- a/AppleWin/source/Debugger/Debug.cpp
+++ b/AppleWin/source/Debugger/Debug.cpp
@@ -4007,6 +4007,7 @@ Update_t CmdConfigSetDebugDir (int nArgs)
}
//===========================================================================
+#if 0 // Original
Update_t CmdMemoryLoad (int nArgs)
{
// BLOAD ["Filename"] , addr[, len]
@@ -4128,6 +4129,164 @@ Update_t CmdMemoryLoad (int nArgs)
return ConsoleUpdate();
}
+#else // Extended cmd for loading physical memory
+Update_t CmdMemoryLoad (int nArgs)
+{
+ // Active memory:
+ // BLOAD ["Filename"] , addr[, len]
+ // BLOAD ["Filename"] , addr[: end]
+ // 1 2 3 4 5
+ // Physical 64K memory bank:
+ // BLOAD ["Filename"] , bank : addr [, len]
+ // BLOAD ["Filename"] , bank : addr [: end]
+ // 1 2 3 4 5 6 7
+ if (nArgs > 7)
+ return Help_Arg_1( CMD_MEMORY_LOAD );
+
+ if (nArgs < 1)
+ return Help_Arg_1( CMD_MEMORY_LOAD );
+
+ bool bHaveFileName = false;
+
+ if (g_aArgs[1].bType & TYPE_QUOTED_2)
+ bHaveFileName = true;
+
+// if (g_aArgs[2].bType & TOKEN_QUOTE_DOUBLE)
+// bHaveFileName = true;
+
+ int iArgComma1 = 2;
+ int iArgAddress = 3;
+ int iArgComma2 = 4;
+ int iArgLength = 5;
+ int iArgBank = 3;
+ int iArgColon = 4;
+
+ int nBank = 0;
+ bool bBankSpecified = false;
+
+ if (! bHaveFileName)
+ {
+ iArgComma1 = 1;
+ iArgAddress = 2;
+ iArgComma2 = 3;
+ iArgLength = 4;
+ iArgBank = 2;
+ iArgColon = 3;
+
+ if (nArgs > 6)
+ return Help_Arg_1( CMD_MEMORY_LOAD );
+ }
+
+ if (nArgs >= 5)
+ {
+ if (!(g_aArgs[iArgBank].bType & TYPE_ADDRESS && g_aArgs[iArgColon].eToken == TOKEN_COLON))
+ return Help_Arg_1( CMD_MEMORY_LOAD );
+
+ nBank = g_aArgs[iArgBank].nValue;
+ bBankSpecified = true;
+
+ iArgAddress += 2;
+ iArgComma2 += 2;
+ iArgLength += 2;
+ }
+ else
+ {
+ bBankSpecified = false;
+ }
+
+ if (g_aArgs[ iArgComma1 ].eToken != TOKEN_COMMA)
+ return Help_Arg_1( CMD_MEMORY_LOAD );
+
+ TCHAR sLoadSaveFilePath[ MAX_PATH ];
+ _tcscpy( sLoadSaveFilePath, g_sCurrentDir ); // TODO: g_sDebugDir
+
+ WORD nAddressStart;
+ WORD nAddress2 = 0;
+ WORD nAddressEnd = 0;
+ int nAddressLen = 0;
+
+ RangeType_t eRange;
+ eRange = Range_Get( nAddressStart, nAddress2, iArgAddress );
+ if (nArgs > iArgComma2)
+ {
+ if (eRange == RANGE_MISSING_ARG_2)
+ {
+ return Help_Arg_1( CMD_MEMORY_LOAD );
+ }
+
+// if (eRange == RANGE_MISSING_ARG_2)
+ if (! Range_CalcEndLen( eRange, nAddressStart, nAddress2, nAddressEnd, nAddressLen ))
+ {
+ return Help_Arg_1( CMD_MEMORY_LOAD );
+ }
+ }
+
+ if (bHaveFileName)
+ {
+ _tcscpy( g_sMemoryLoadSaveFileName, g_aArgs[ 1 ].sArg );
+ }
+ _tcscat( sLoadSaveFilePath, g_sMemoryLoadSaveFileName );
+
+ BYTE * const pMemBankBase = bBankSpecified ? MemGetBankPtr(nBank) : mem;
+ if (!pMemBankBase)
+ {
+ ConsoleBufferPush( TEXT( "Error: Bank out of range." ) );
+ return ConsoleUpdate();
+ }
+
+ FILE *hFile = fopen( sLoadSaveFilePath, "rb" );
+ if (hFile)
+ {
+ fseek( hFile, 0, SEEK_END );
+ int nFileBytes = ftell( hFile );
+ fseek( hFile, 0, SEEK_SET );
+
+ if (nFileBytes > _6502_MEM_END)
+ nFileBytes = _6502_MEM_END + 1; // Bank-switched RAM/ROM is only 16-bit
+
+ // Caller didn't specify how many bytes to read, default to them all
+ if (nAddressLen == 0)
+ {
+ nAddressLen = nFileBytes;
+ }
+
+ size_t nRead = fread( pMemBankBase+nAddressStart, nAddressLen, 1, hFile );
+ if (nRead == 1)
+ {
+ ConsoleBufferPush( TEXT( "Loaded." ) );
+ }
+ else
+ {
+ ConsoleBufferPush( TEXT( "Error loading data." ) );
+ }
+ fclose( hFile );
+
+ if (bBankSpecified)
+ {
+ MemUpdatePaging(1);
+ }
+ else
+ {
+ for (UINT i=(nAddressStart>>8); i!=((nAddressStart+nAddressLen)>>8); i++)
+ {
+ memdirty[i] = 0xff;
+ }
+ }
+ }
+ else
+ {
+ ConsoleBufferPush( TEXT( "ERROR: Bad filename" ) );
+
+ CmdConfigGetDebugDir( 0 );
+
+ TCHAR sFile[ MAX_PATH + 8 ] = "File: ";
+ _tcscat( sFile, g_sMemoryLoadSaveFileName );
+ ConsoleBufferPush( sFile );
+ }
+
+ return ConsoleUpdate();
+}
+#endif
// dst src : len
//===========================================================================
@@ -4304,11 +4463,11 @@ Update_t CmdMemorySave (int nArgs)
Update_t CmdMemorySave (int nArgs)
{
// Active memory:
- // BSAVE ["Filename"] , addr , len
+ // BSAVE ["Filename"] , addr , len
// BSAVE ["Filename"] , addr : end
// 1 2 3 4 5
// Physical 64K memory bank:
- // BSAVE ["Filename"] , bank : addr , len
+ // BSAVE ["Filename"] , bank : addr , len
// BSAVE ["Filename"] , bank : addr : end
// 1 2 3 4 5 6 7
static WORD nAddressStart = 0;
@@ -4404,7 +4563,10 @@ Update_t CmdMemorySave (int nArgs)
{
if (! bHaveFileName)
{
- sprintf( g_sMemoryLoadSaveFileName, "%04X.%04X.bin", nAddressStart, nAddressLen ); // nAddressEnd );
+ if (! bBankSpecified)
+ sprintf( g_sMemoryLoadSaveFileName, "%04X.%04X.bin", nAddressStart, nAddressLen );
+ else
+ sprintf( g_sMemoryLoadSaveFileName, "%04X.%04X.bank%02X.bin", nAddressStart, nAddressLen, nBank );
}
else
{
@@ -4412,49 +4574,37 @@ Update_t CmdMemorySave (int nArgs)
}
_tcscat( sLoadSaveFilePath, g_sMemoryLoadSaveFileName );
-// if (nArgs == 2)
+ const BYTE * const pMemBankBase = bBankSpecified ? MemGetBankPtr(nBank) : mem;
+ if (!pMemBankBase)
{
- const BYTE * const pMemBankBase = bBankSpecified ? MemGetBankPtr(nBank) : mem;
- if (!pMemBankBase)
- {
- ConsoleBufferPush( TEXT( "Error: Bank out of range." ) );
- return ConsoleUpdate();;
- }
+ ConsoleBufferPush( TEXT( "Error: Bank out of range." ) );
+ return ConsoleUpdate();
+ }
- BYTE * const pMemory = new BYTE [ nAddressLen ];
- BYTE *pDst = pMemory;
- const BYTE *pSrc = pMemBankBase + nAddressStart;
-
- // memcpy -- copy out of active memory bank
- int iByte;
- for( iByte = 0; iByte < nAddressLen; iByte++ )
- {
- *pDst++ = *pSrc++;
- }
+ FILE *hFile = fopen( sLoadSaveFilePath, "rb" );
+ if (hFile)
+ {
+ ConsoleBufferPush( TEXT( "Warning: File already exists. Overwriting." ) );
+ fclose( hFile );
+ }
- FILE *hFile = fopen( sLoadSaveFilePath, "rb" );
- if (hFile)
+ hFile = fopen( sLoadSaveFilePath, "wb" );
+ if (hFile)
+ {
+ size_t nWrote = fwrite( pMemBankBase+nAddressStart, nAddressLen, 1, hFile );
+ if (nWrote == 1)
{
- ConsoleBufferPush( TEXT( "Warning: File already exists. Overwriting." ) );
- fclose( hFile );
+ ConsoleBufferPush( TEXT( "Saved." ) );
}
-
- hFile = fopen( sLoadSaveFilePath, "wb" );
- if (hFile)
+ else
{
- size_t nWrote = fwrite( pMemory, nAddressLen, 1, hFile );
- if (nWrote == 1) // (size_t)nAddressLen)
- {
- ConsoleBufferPush( TEXT( "Saved." ) );
- }
- else
- {
- ConsoleBufferPush( TEXT( "Error saving." ) );
- }
- fclose( hFile );
+ ConsoleBufferPush( TEXT( "Error saving." ) );
}
-
- delete [] pMemory;
+ fclose( hFile );
+ }
+ else
+ {
+ ConsoleBufferPush( TEXT( "Error opening file." ) );
}
}
}
@@ -4463,7 +4613,6 @@ Update_t CmdMemorySave (int nArgs)
}
#endif
-
//===========================================================================
int _SearchMemoryFind(
MemorySearchValues_t vMemorySearchValues,
diff --git a/AppleWin/source/Debugger/Debugger_Help.cpp b/AppleWin/source/Debugger/Debugger_Help.cpp
index 9b63b6c6..b9984ffd 100644
--- a/AppleWin/source/Debugger/Debugger_Help.cpp
+++ b/AppleWin/source/Debugger/Debugger_Help.cpp
@@ -1169,26 +1169,25 @@ Update_t CmdHelpSpecific (int nArgs)
case CMD_MEMORY_SAVE:
if (iCommand == CMD_MEMORY_LOAD)
{
- sprintf( sTemp, " Usage: [\"Filename\",]address[,length]" );
+ sprintf( sTemp, " Usage: [\"Filename\"],[bank:]address[,length]" );
Colorize( sText, sTemp );
ConsolePrint( sText );
- sprintf( sTemp, " Usage: [\"Filename\",]range" );
+ sprintf( sTemp, " Usage: [\"Filename\"],[bank:]range" );
Colorize( sText, sTemp );
ConsolePrint( sText );
Help_Range();
ConsoleBufferPush( " Notes: If no filename specified, defaults to the last filename (if possible)" );
- ConsoleBufferPush( " Optional bank not supported for BLOAD" );
}
if (iCommand == CMD_MEMORY_SAVE)
{
- sprintf( sTemp, " Usage: [\"Filename\",][bank:]address,length" );
+ sprintf( sTemp, " Usage: [\"Filename\"],[bank:]address,length" );
Colorize( sText, sTemp );
ConsolePrint( sText );
- sprintf( sTemp, " Usage: [\"Filename\",][bank:]range" );
+ sprintf( sTemp, " Usage: [\"Filename\"],[bank:]range" );
Colorize( sText, sTemp );
ConsolePrint( sText );
Help_Range();
- ConsoleBufferPush( " Notes: If no filename specified, defaults to: '####.####.bin'" );
+ ConsoleBufferPush( " Notes: If no filename specified, defaults to: '####.####.[bank##].bin'" );
ConsoleBufferPush( " Where the form is ..bin" );
}
@@ -1198,8 +1197,10 @@ Update_t CmdHelpSpecific (int nArgs)
sprintf( sText, "%s BLOAD \"test\",2000:2010" , CHC_EXAMPLE ); ConsolePrint( sText );
sprintf( sText, "%s BSAVE \"test\",F000:FFFF" , CHC_EXAMPLE ); ConsolePrint( sText );
sprintf( sText, "%s BLOAD \"test\",4000" , CHC_EXAMPLE ); ConsolePrint( sText );
- sprintf( sText, "%s BSAVE \"test\",0:2000,2000" , CHC_EXAMPLE ); ConsolePrint( sText );
- sprintf( sText, "%s BSAVE \"test\",1:2000:3FFF" , CHC_EXAMPLE ); ConsolePrint( sText );
+ sprintf( sText, "%s BLOAD \"main.bin\",0:2000" , CHC_EXAMPLE ); ConsolePrint( sText );
+ sprintf( sText, "%s BSAVE \"aux2.bin\",1:2000" , CHC_EXAMPLE ); ConsolePrint( sText );
+ sprintf( sText, "%s BSAVE \"main.bin\",0:2000,2000" , CHC_EXAMPLE ); ConsolePrint( sText );
+ sprintf( sText, "%s BSAVE \"aux2.bin\",1:2000:3FFF" , CHC_EXAMPLE ); ConsolePrint( sText );
break;
case CMD_MEMORY_SEARCH:
Colorize( sText, " Usage: range <\"ASCII text\" | 'apple text' | hex>" );
diff --git a/AppleWin/source/Memory.cpp b/AppleWin/source/Memory.cpp
index 667c84ad..e6b08036 100644
--- a/AppleWin/source/Memory.cpp
+++ b/AppleWin/source/Memory.cpp
@@ -846,6 +846,11 @@ void ResetPaging (BOOL initialize)
//===========================================================================
+void MemUpdatePaging(BOOL initialize)
+{
+ UpdatePaging(initialize, 0);
+}
+
static void UpdatePaging (BOOL initialize, BOOL updatewriteonly /*Always zero*/)
{
// SAVE THE CURRENT PAGING SHADOW TABLE
diff --git a/AppleWin/source/Memory.h b/AppleWin/source/Memory.h
index 510aba39..732c3bae 100644
--- a/AppleWin/source/Memory.h
+++ b/AppleWin/source/Memory.h
@@ -45,9 +45,8 @@ BYTE MemReadFloatingBus(const ULONG uExecutedCycles);
BYTE MemReadFloatingBus(const BYTE highbit, const ULONG uExecutedCycles);
void MemReset ();
void MemResetPaging ();
+void MemUpdatePaging(BOOL initialize);
BYTE MemReturnRandomData (BYTE highbit);
-void MemSetFastPaging (BOOL);
-void MemTrimImages ();
LPVOID MemGetSlotParameters (UINT uSlot);
DWORD MemGetSnapshot(SS_BaseMemory* pSS);
DWORD MemSetSnapshot(SS_BaseMemory* pSS);