mirror of
https://github.com/AppleWin/AppleWin.git
synced 2025-02-05 17:30:45 +00:00
New save-state (.aws) v2:
. Format now extensible for supporting new hardware types in the future . Include missing items like Apple2Type, CyclesThisVideoFrame (#255) Continue to support loading of old v1 format. Added card save/load for: . Mouse (#260) . HDD (#260) . Printer Extended card support for: . SSC Other: . Added save-state v1 struct size checks . Create SaveState_Structs_v2.h and split out common into SaveState_Structs_common.h . Refactor HardDisk.cpp to use imagehandle; and consolidate with Disk.cpp . Fix Disk/HD_GetFullPathName() which wasn't always returning full pathname . Consolidate common GetImageTitle() and move into DiskImage.cpp
This commit is contained in:
parent
0fc6d18139
commit
717c5cba84
@ -755,11 +755,19 @@
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\source\SSI263Phonemes.h"
|
||||
RelativePath=".\source\SaveState_Structs_common.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\source\Structs.h"
|
||||
RelativePath=".\source\SaveState_Structs_v1.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\source\SaveState_Structs_v2.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\source\SSI263Phonemes.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
|
@ -32,6 +32,21 @@ typedef struct
|
||||
mem_write_handler func;
|
||||
} STWriteHandler;
|
||||
|
||||
struct mc6821_s {
|
||||
/* MC6821 register. */
|
||||
BYTE pra;
|
||||
BYTE ddra;
|
||||
BYTE cra;
|
||||
BYTE prb;
|
||||
BYTE ddrb;
|
||||
BYTE crb;
|
||||
|
||||
/* Drive structure */
|
||||
// struct drive_s *drive;
|
||||
};
|
||||
typedef struct mc6821_s mc6821_t;
|
||||
|
||||
|
||||
class C6821
|
||||
{
|
||||
public:
|
||||
@ -64,6 +79,18 @@ public:
|
||||
m_stOutB.objTo = objTo;
|
||||
m_stOutB.func = func;
|
||||
}
|
||||
void Get6821(mc6821_t& r6821, BYTE& byIA, BYTE& byIB)
|
||||
{
|
||||
r6821 = mc6821[0];
|
||||
byIA = m_byIA;
|
||||
byIB = m_byIB;
|
||||
}
|
||||
void Set6821(const mc6821_t& r6821, const BYTE byIA, const BYTE byIB)
|
||||
{
|
||||
mc6821[0] = r6821;
|
||||
m_byIA = byIA;
|
||||
m_byIB = byIB;
|
||||
}
|
||||
// AppleWin:TC END
|
||||
|
||||
private:
|
||||
@ -75,20 +102,6 @@ private:
|
||||
|
||||
//struct drive_s;
|
||||
|
||||
struct mc6821_s {
|
||||
/* MC6821 register. */
|
||||
BYTE pra;
|
||||
BYTE ddra;
|
||||
BYTE cra;
|
||||
BYTE prb;
|
||||
BYTE ddrb;
|
||||
BYTE crb;
|
||||
|
||||
/* Drive structure */
|
||||
// struct drive_s *drive;
|
||||
};
|
||||
typedef struct mc6821_s mc6821_t;
|
||||
|
||||
//struct drive_context_s;
|
||||
void mc6821_init(/*struct drive_context_s *drv*/);
|
||||
void mc6821_reset(/*struct drive_context_s *drv*/);
|
||||
|
@ -469,12 +469,6 @@ void LoadConfiguration(void)
|
||||
if(REGLOAD(TEXT(REGVALUE_HDD_ENABLED), &dwTmp))
|
||||
HD_SetEnabled(dwTmp ? true : false);
|
||||
|
||||
char szHDVPathname[MAX_PATH] = {0};
|
||||
if(RegLoadString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_LAST_HARDDISK_1), 1, szHDVPathname, sizeof(szHDVPathname)))
|
||||
HD_InsertDisk(HARDDISK_1, szHDVPathname);
|
||||
if(RegLoadString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_LAST_HARDDISK_2), 1, szHDVPathname, sizeof(szHDVPathname)))
|
||||
HD_InsertDisk(HARDDISK_2, szHDVPathname);
|
||||
|
||||
if(REGLOAD(TEXT(REGVALUE_PDL_XTRIM), &dwTmp))
|
||||
JoySetTrim((short)dwTmp, true);
|
||||
if(REGLOAD(TEXT(REGVALUE_PDL_YTRIM), &dwTmp))
|
||||
@ -509,6 +503,16 @@ void LoadConfiguration(void)
|
||||
|
||||
char szFilename[MAX_PATH] = {0};
|
||||
|
||||
RegLoadString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_HDV_START_DIR), 1, szFilename, MAX_PATH);
|
||||
if (szFilename[0] == 0)
|
||||
GetCurrentDirectory(sizeof(szFilename), szFilename);
|
||||
SetCurrentImageDir(szFilename);
|
||||
|
||||
HD_LoadLastDiskImage(HARDDISK_1);
|
||||
HD_LoadLastDiskImage(HARDDISK_2);
|
||||
|
||||
//
|
||||
|
||||
// Current/Starting Dir is the "root" of where the user keeps his disk images
|
||||
RegLoadString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_START_DIR), 1, szFilename, MAX_PATH);
|
||||
if (szFilename[0] == 0)
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "Structs.h"
|
||||
#include "SaveState_Structs_common.h"
|
||||
#include "Common.h"
|
||||
|
||||
void SetCurrentCLK6502();
|
||||
|
@ -102,6 +102,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "Z80VICE\z80mem.h"
|
||||
|
||||
#include "Debugger\Debug.h"
|
||||
#include "SaveState_Structs_v2.h"
|
||||
|
||||
|
||||
#define AF_SIGN 0x80
|
||||
@ -642,30 +643,46 @@ void CpuReset()
|
||||
|
||||
//===========================================================================
|
||||
|
||||
DWORD CpuGetSnapshot(SS_CPU6502* pSS)
|
||||
void CpuSetSnapshot_v1(const BYTE A, const BYTE X, const BYTE Y, const BYTE P, const BYTE SP, const USHORT PC, const unsigned __int64 CumulativeCycles)
|
||||
{
|
||||
pSS->A = regs.a;
|
||||
pSS->X = regs.x;
|
||||
pSS->Y = regs.y;
|
||||
pSS->P = regs.ps | AF_RESERVED | AF_BREAK;
|
||||
pSS->S = (BYTE) (regs.sp & 0xff);
|
||||
pSS->PC = regs.pc;
|
||||
pSS->g_nCumulativeCycles = g_nCumulativeCycles;
|
||||
regs.a = A;
|
||||
regs.x = X;
|
||||
regs.y = Y;
|
||||
regs.ps = P | (AF_RESERVED | AF_BREAK);
|
||||
regs.sp = ((USHORT)SP) | 0x100;
|
||||
regs.pc = PC;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD CpuSetSnapshot(SS_CPU6502* pSS)
|
||||
{
|
||||
regs.a = pSS->A;
|
||||
regs.x = pSS->X;
|
||||
regs.y = pSS->Y;
|
||||
regs.ps = pSS->P | AF_RESERVED | AF_BREAK;
|
||||
regs.sp = (USHORT)pSS->S | 0x100;
|
||||
regs.pc = pSS->PC;
|
||||
CpuIrqReset();
|
||||
CpuNmiReset();
|
||||
g_nCumulativeCycles = pSS->g_nCumulativeCycles;
|
||||
|
||||
return 0;
|
||||
g_nCumulativeCycles = CumulativeCycles;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
void CpuGetSnapshot(SS_CPU6502_v2& CPU)
|
||||
{
|
||||
regs.ps |= (AF_RESERVED | AF_BREAK);
|
||||
|
||||
CPU.A = regs.a;
|
||||
CPU.X = regs.x;
|
||||
CPU.Y = regs.y;
|
||||
CPU.P = regs.ps;
|
||||
CPU.S = (BYTE) regs.sp;
|
||||
CPU.PC = regs.pc;
|
||||
|
||||
CPU.CumulativeCycles = g_nCumulativeCycles;
|
||||
}
|
||||
|
||||
void CpuSetSnapshot(const SS_CPU6502_v2& CPU)
|
||||
{
|
||||
regs.a = CPU.A;
|
||||
regs.x = CPU.X;
|
||||
regs.y = CPU.Y;
|
||||
regs.ps = CPU.P | (AF_RESERVED | AF_BREAK);
|
||||
regs.sp = ((USHORT)CPU.S) | 0x100;
|
||||
regs.pc = CPU.PC;
|
||||
|
||||
CpuIrqReset();
|
||||
CpuNmiReset();
|
||||
g_nCumulativeCycles = CPU.CumulativeCycles;
|
||||
}
|
||||
|
10
source/CPU.h
10
source/CPU.h
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct _regsrec {
|
||||
struct regsrec
|
||||
{
|
||||
BYTE a; // accumulator
|
||||
BYTE x; // index X
|
||||
BYTE y; // index Y
|
||||
@ -8,7 +9,7 @@ typedef struct _regsrec {
|
||||
WORD pc; // program counter
|
||||
WORD sp; // stack pointer
|
||||
BYTE bJammed; // CPU has crashed (NMOS 6502 only)
|
||||
} regsrec, *regsptr;
|
||||
};
|
||||
|
||||
extern regsrec regs;
|
||||
extern unsigned __int64 g_nCumulativeCycles;
|
||||
@ -26,8 +27,9 @@ void CpuNmiReset();
|
||||
void CpuNmiAssert(eIRQSRC Device);
|
||||
void CpuNmiDeassert(eIRQSRC Device);
|
||||
void CpuReset ();
|
||||
DWORD CpuGetSnapshot(SS_CPU6502* pSS);
|
||||
DWORD CpuSetSnapshot(SS_CPU6502* pSS);
|
||||
void CpuSetSnapshot_v1(const BYTE A, const BYTE X, const BYTE Y, const BYTE P, const BYTE SP, const USHORT PC, const unsigned __int64 CumulativeCycles);
|
||||
void CpuGetSnapshot(struct SS_CPU6502_v2& CPU);
|
||||
void CpuSetSnapshot(const struct SS_CPU6502_v2& CPU);
|
||||
|
||||
BYTE CpuRead(USHORT addr, ULONG uExecutedCycles);
|
||||
void CpuWrite(USHORT addr, BYTE a, ULONG uExecutedCycles);
|
||||
|
@ -164,7 +164,7 @@ enum eIRQSRC {IS_6522=0, IS_SPEECH, IS_SSC, IS_MOUSE};
|
||||
#define IS_APPLE2C (g_Apple2Type & APPLE2C_MASK)
|
||||
#define IS_CLONE() (g_Apple2Type & APPLECLONE_MASK)
|
||||
|
||||
// NB. These get persisted to the Registry, so don't change the values for these enums!
|
||||
// NB. These get persisted to the Registry & save-state file, so don't change the values for these enums!
|
||||
enum eApple2Type {
|
||||
A2TYPE_APPLE2=0,
|
||||
A2TYPE_APPLE2PLUS,
|
||||
|
@ -1,10 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
class CConfigNeedingRestart;
|
||||
|
||||
__interface IPropertySheet
|
||||
{
|
||||
void Init(void);
|
||||
DWORD GetVolumeMax(void); // TODO:TC: Move out of here
|
||||
bool SaveStateSelectImage(HWND hWindow, bool bSave); // TODO:TC: Move out of here
|
||||
void ApplyNewConfig(const CConfigNeedingRestart& ConfigNew, const CConfigNeedingRestart& ConfigOld);
|
||||
|
||||
UINT GetScrollLockToggle(void);
|
||||
void SetScrollLockToggle(UINT uValue);
|
||||
|
@ -22,7 +22,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "..\Structs.h"
|
||||
#include "..\Common.h"
|
||||
|
||||
#include "..\ParallelPrinter.h"
|
||||
|
@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "..\Structs.h"
|
||||
#include "..\SaveState_Structs_common.h"
|
||||
#include "..\Common.h"
|
||||
|
||||
#include "..\Keyboard.h"
|
||||
|
@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "..\Structs.h"
|
||||
#include "..\SaveState_Structs_common.h"
|
||||
#include "..\Common.h"
|
||||
|
||||
#include "..\Mockingboard.h"
|
||||
|
@ -24,6 +24,10 @@ public:
|
||||
virtual void Init(void);
|
||||
virtual DWORD GetVolumeMax(void); // TODO:TC: Move out of here
|
||||
virtual bool SaveStateSelectImage(HWND hWindow, bool bSave); // TODO:TC: Move out of here
|
||||
void ApplyNewConfig(const CConfigNeedingRestart& ConfigNew, const CConfigNeedingRestart& ConfigOld)
|
||||
{
|
||||
m_PropertySheetHelper.ApplyNewConfig(ConfigNew, ConfigOld);
|
||||
}
|
||||
|
||||
virtual UINT GetScrollLockToggle(void){ return m_PageInput.GetScrollLockToggle(); }
|
||||
virtual void SetScrollLockToggle(UINT uValue){ m_PageInput.SetScrollLockToggle(uValue); }
|
||||
|
@ -319,35 +319,40 @@ bool CPropertySheetHelper::CheckChangesForRestart(HWND hWnd)
|
||||
return true; // OK
|
||||
}
|
||||
|
||||
#define CONFIG_CHANGED(var) \
|
||||
(m_ConfigOld.var != m_ConfigNew.var)
|
||||
#define CONFIG_CHANGED_LOCAL(var) \
|
||||
(ConfigOld.var != ConfigNew.var)
|
||||
|
||||
// Apply changes to Registry
|
||||
void CPropertySheetHelper::ApplyNewConfig(const CConfigNeedingRestart& ConfigNew, const CConfigNeedingRestart& ConfigOld)
|
||||
{
|
||||
if (CONFIG_CHANGED_LOCAL(m_Apple2Type))
|
||||
{
|
||||
SaveComputerType(ConfigNew.m_Apple2Type);
|
||||
}
|
||||
|
||||
if (CONFIG_CHANGED_LOCAL(m_Slot[4]))
|
||||
SetSlot4(ConfigNew.m_Slot[4]);
|
||||
|
||||
if (CONFIG_CHANGED_LOCAL(m_Slot[5]))
|
||||
SetSlot5(ConfigNew.m_Slot[5]);
|
||||
|
||||
if (CONFIG_CHANGED_LOCAL(m_bEnhanceDisk))
|
||||
REGSAVE(TEXT(REGVALUE_ENHANCE_DISK_SPEED), ConfigNew.m_bEnhanceDisk);
|
||||
|
||||
if (CONFIG_CHANGED_LOCAL(m_bEnableHDD))
|
||||
{
|
||||
REGSAVE(TEXT(REGVALUE_HDD_ENABLED), ConfigNew.m_bEnableHDD ? 1 : 0);
|
||||
}
|
||||
|
||||
if (CONFIG_CHANGED_LOCAL(m_bEnableTheFreezesF8Rom))
|
||||
{
|
||||
REGSAVE(TEXT(REGVALUE_THE_FREEZES_F8_ROM), ConfigNew.m_bEnableTheFreezesF8Rom);
|
||||
}
|
||||
}
|
||||
|
||||
void CPropertySheetHelper::ApplyNewConfig(void)
|
||||
{
|
||||
if (CONFIG_CHANGED(m_Apple2Type))
|
||||
{
|
||||
SaveComputerType(m_ConfigNew.m_Apple2Type);
|
||||
}
|
||||
|
||||
if (CONFIG_CHANGED(m_Slot[4]))
|
||||
SetSlot4(m_ConfigNew.m_Slot[4]);
|
||||
|
||||
if (CONFIG_CHANGED(m_Slot[5]))
|
||||
SetSlot5(m_ConfigNew.m_Slot[5]);
|
||||
|
||||
if (CONFIG_CHANGED(m_bEnhanceDisk))
|
||||
REGSAVE(TEXT(REGVALUE_ENHANCE_DISK_SPEED), m_ConfigNew.m_bEnhanceDisk);
|
||||
|
||||
if (CONFIG_CHANGED(m_bEnableHDD))
|
||||
{
|
||||
REGSAVE(TEXT(REGVALUE_HDD_ENABLED), m_ConfigNew.m_bEnableHDD ? 1 : 0);
|
||||
}
|
||||
|
||||
if (CONFIG_CHANGED(m_bEnableTheFreezesF8Rom))
|
||||
{
|
||||
REGSAVE(TEXT(REGVALUE_THE_FREEZES_F8_ROM), m_ConfigNew.m_bEnableTheFreezesF8Rom);
|
||||
}
|
||||
ApplyNewConfig(m_ConfigNew, m_ConfigOld);
|
||||
}
|
||||
|
||||
void CPropertySheetHelper::SaveCurrentConfig(void)
|
||||
@ -411,6 +416,9 @@ bool CPropertySheetHelper::IsOkToRestart(HWND hWnd)
|
||||
return true;
|
||||
}
|
||||
|
||||
#define CONFIG_CHANGED(var) \
|
||||
(m_ConfigOld.var != m_ConfigNew.var)
|
||||
|
||||
bool CPropertySheetHelper::HardwareConfigChanged(HWND hWnd)
|
||||
{
|
||||
std::string strMsg("The emulator needs to restart as the hardware configuration has changed:\n");
|
||||
|
@ -37,6 +37,7 @@ public:
|
||||
CConfigNeedingRestart& GetConfigNew(void) { return m_ConfigNew; }
|
||||
bool IsConfigChanged(void) { return m_ConfigNew != m_ConfigOld; }
|
||||
void SetDoBenchmark(void) { m_bDoBenchmark = true; }
|
||||
void ApplyNewConfig(const CConfigNeedingRestart& ConfigNew, const CConfigNeedingRestart& ConfigOld);
|
||||
|
||||
private:
|
||||
bool IsOkToSaveLoadState(HWND hWnd, const bool bConfigChanged);
|
||||
|
@ -4285,7 +4285,7 @@ Update_t CmdMemoryLoad (int nArgs)
|
||||
|
||||
if (bBankSpecified)
|
||||
{
|
||||
MemUpdatePaging(1);
|
||||
MemUpdatePaging(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "..\Structs.h"
|
||||
#include "..\SaveState_Structs_v1.h" // For SS_CARD_MOCKINGBOARD
|
||||
#include "..\Common.h"
|
||||
|
||||
#include "Debugger_Types.h"
|
||||
|
@ -2437,7 +2437,7 @@ void DrawMemory ( int line, int iMemDump )
|
||||
SS_CARD_MOCKINGBOARD SS_MB;
|
||||
|
||||
if ((eDevice == DEV_SY6522) || (eDevice == DEV_AY8910))
|
||||
MB_GetSnapshot(&SS_MB, 4+(nAddr>>1)); // Slot4 or Slot5
|
||||
MB_GetSnapshot_v1(&SS_MB, 4+(nAddr>>1)); // Slot4 or Slot5
|
||||
|
||||
int nFontWidth = g_aFontConfig[ FONT_INFO ]._nFontWidthAvg;
|
||||
|
||||
|
381
source/Disk.cpp
381
source/Disk.cpp
@ -28,6 +28,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "SaveState_Structs_v1.h"
|
||||
|
||||
#include "AppleWin.h"
|
||||
#include "Disk.h"
|
||||
#include "DiskImage.h"
|
||||
@ -61,21 +63,18 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
// Private ________________________________________________________________________________________
|
||||
|
||||
const int MAX_DISK_IMAGE_NAME = 15;
|
||||
const int MAX_DISK_FULL_NAME = 127;
|
||||
|
||||
struct Disk_t
|
||||
{
|
||||
TCHAR imagename[ MAX_DISK_IMAGE_NAME + 1 ]; // <FILENAME> (ie. no extension)
|
||||
TCHAR fullname [ MAX_DISK_FULL_NAME + 1 ]; // <FILENAME.EXT> or <FILENAME.zip> : This is persisted to the snapshot file
|
||||
std::string strDiskPathFilename;
|
||||
std::string strFilenameInZip; // 0x00 or <FILENAME.EXT>
|
||||
std::string strFilenameInZip; // "" or <FILENAME.EXT>
|
||||
HIMAGE imagehandle; // Init'd by DiskInsert() -> ImageOpen()
|
||||
bool bWriteProtected;
|
||||
//
|
||||
int track;
|
||||
LPBYTE trackimage;
|
||||
int phase;
|
||||
int byte;
|
||||
bool bWriteProtected;
|
||||
BOOL trackimagedata;
|
||||
BOOL trackimagedirty;
|
||||
DWORD spinning;
|
||||
@ -86,14 +85,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
{
|
||||
memcpy(imagename, other.imagename, sizeof(imagename));
|
||||
memcpy(fullname , other.fullname, sizeof(fullname));
|
||||
strDiskPathFilename = other.strDiskPathFilename;
|
||||
strFilenameInZip = other.strFilenameInZip;
|
||||
imagehandle = other.imagehandle;
|
||||
bWriteProtected = other.bWriteProtected;
|
||||
track = other.track;
|
||||
trackimage = other.trackimage;
|
||||
phase = other.phase;
|
||||
byte = other.byte;
|
||||
bWriteProtected = other.bWriteProtected;
|
||||
trackimagedata = other.trackimagedata;
|
||||
trackimagedirty = other.trackimagedirty;
|
||||
spinning = other.spinning;
|
||||
@ -109,8 +107,9 @@ static Disk_t g_aFloppyDisk[NUM_DRIVES];
|
||||
static BYTE floppylatch = 0;
|
||||
static BOOL floppymotoron = 0;
|
||||
static BOOL floppywritemode = 0;
|
||||
static WORD phases; // state bits for stepper magnet phases 0 - 3
|
||||
static WORD phases = 0; // state bits for stepper magnet phases 0 - 3
|
||||
static bool g_bSaveDiskImage = true; // Save the DiskImage name to Registry
|
||||
static UINT g_uSlot = 0;
|
||||
|
||||
static void CheckSpinning();
|
||||
static Disk_Status_e GetDriveLightStatus( const int iDrive );
|
||||
@ -127,14 +126,9 @@ int DiskGetCurrentPhase(void) { return g_aFloppyDisk[currdrive].phase; }
|
||||
int DiskGetCurrentOffset(void) { return g_aFloppyDisk[currdrive].byte; }
|
||||
int DiskGetTrack( int drive ) { return g_aFloppyDisk[ drive ].track; }
|
||||
|
||||
const std::string& DiskGetDiskPathFilename(const int iDrive)
|
||||
const char* DiskGetDiskPathFilename(const int iDrive)
|
||||
{
|
||||
return g_aFloppyDisk[iDrive].strDiskPathFilename;
|
||||
}
|
||||
|
||||
static void DiskSetDiskPathFilename(const int iDrive, const std::string strPathName)
|
||||
{
|
||||
g_aFloppyDisk[iDrive].strDiskPathFilename = strPathName;
|
||||
return g_aFloppyDisk[iDrive].fullname;
|
||||
}
|
||||
|
||||
char* DiskGetCurrentState(void)
|
||||
@ -164,7 +158,7 @@ char* DiskGetCurrentState(void)
|
||||
|
||||
//===========================================================================
|
||||
|
||||
void Disk_LoadLastDiskImage(const int iDrive)
|
||||
void Disk_LoadLastDiskImage(const int iDrive)
|
||||
{
|
||||
_ASSERT(iDrive == DRIVE_1 || iDrive == DRIVE_2);
|
||||
|
||||
@ -175,22 +169,15 @@ char* DiskGetCurrentState(void)
|
||||
? REGVALUE_PREF_LAST_DISK_1
|
||||
: REGVALUE_PREF_LAST_DISK_2;
|
||||
|
||||
if (RegLoadString(TEXT(REG_PREFS),pRegKey,1,sFilePath,MAX_PATH))
|
||||
if (RegLoadString(TEXT(REG_PREFS), pRegKey, 1, sFilePath, MAX_PATH))
|
||||
{
|
||||
sFilePath[ MAX_PATH ] = 0;
|
||||
DiskSetDiskPathFilename(iDrive, sFilePath);
|
||||
|
||||
#if _DEBUG
|
||||
// MessageBox(g_hFrameWindow,pFileName,pRegKey,MB_OK);
|
||||
#endif
|
||||
|
||||
// _tcscat(imagefilename,TEXT("MASTER.DSK")); // TODO: Should remember last disk by user
|
||||
g_bSaveDiskImage = false;
|
||||
// Pass in ptr to local copy of filepath, since RemoveDisk() sets DiskPathFilename = ""
|
||||
DiskInsert(iDrive, sFilePath, IMAGE_USE_FILES_WRITE_PROTECT_STATUS, IMAGE_DONT_CREATE);
|
||||
g_bSaveDiskImage = true;
|
||||
}
|
||||
//else MessageBox(g_hFrameWindow,"Reg Key/Value not found",pRegKey,MB_OK);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@ -202,7 +189,7 @@ void Disk_SaveLastDiskImage(const int iDrive)
|
||||
if (!g_bSaveDiskImage)
|
||||
return;
|
||||
|
||||
const char *pFileName = DiskGetDiskPathFilename(iDrive).c_str();
|
||||
const char *pFileName = g_aFloppyDisk[iDrive].fullname;
|
||||
|
||||
if (iDrive == DRIVE_1)
|
||||
RegSaveString(TEXT(REG_PREFS), REGVALUE_PREF_LAST_DISK_1, TRUE, pFileName);
|
||||
@ -249,53 +236,6 @@ static Disk_Status_e GetDriveLightStatus(const int iDrive)
|
||||
return DISK_STATUS_OFF;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
static void GetImageTitle(LPCTSTR imagefilename, Disk_t* fptr)
|
||||
{
|
||||
TCHAR imagetitle[ MAX_DISK_FULL_NAME+1 ];
|
||||
LPCTSTR startpos = imagefilename;
|
||||
|
||||
// imagetitle = <FILENAME.EXT>
|
||||
if (_tcsrchr(startpos,TEXT('\\')))
|
||||
startpos = _tcsrchr(startpos,TEXT('\\'))+1;
|
||||
|
||||
_tcsncpy(imagetitle,startpos,MAX_DISK_FULL_NAME);
|
||||
imagetitle[MAX_DISK_FULL_NAME] = 0;
|
||||
|
||||
// if imagetitle contains a lowercase char, then found=1 (why?)
|
||||
BOOL found = 0;
|
||||
int loop = 0;
|
||||
while (imagetitle[loop] && !found)
|
||||
{
|
||||
if (IsCharLower(imagetitle[loop]))
|
||||
found = 1;
|
||||
else
|
||||
loop++;
|
||||
}
|
||||
|
||||
if ((!found) && (loop > 2))
|
||||
CharLowerBuff(imagetitle+1,_tcslen(imagetitle+1));
|
||||
|
||||
// fptr->fullname = <FILENAME.EXT>
|
||||
_tcsncpy( fptr->fullname, imagetitle, MAX_DISK_FULL_NAME );
|
||||
fptr->fullname[ MAX_DISK_FULL_NAME ] = 0;
|
||||
|
||||
if (imagetitle[0])
|
||||
{
|
||||
LPTSTR dot = imagetitle;
|
||||
if (_tcsrchr(dot,TEXT('.')))
|
||||
dot = _tcsrchr(dot,TEXT('.'));
|
||||
if (dot > imagetitle)
|
||||
*dot = 0;
|
||||
}
|
||||
|
||||
// fptr->imagename = <FILENAME> (ie. no extension)
|
||||
_tcsncpy( fptr->imagename, imagetitle, MAX_DISK_IMAGE_NAME );
|
||||
fptr->imagename[ MAX_DISK_IMAGE_NAME ] = 0;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
|
||||
static bool IsDriveValid(const int iDrive)
|
||||
@ -370,7 +310,6 @@ static void RemoveDisk(const int iDrive)
|
||||
memset( pFloppy->imagename, 0, MAX_DISK_IMAGE_NAME+1 );
|
||||
memset( pFloppy->fullname , 0, MAX_DISK_FULL_NAME +1 );
|
||||
pFloppy->strFilenameInZip = "";
|
||||
DiskSetDiskPathFilename(iDrive, "");
|
||||
|
||||
Disk_SaveLastDiskImage( iDrive );
|
||||
Video_ResetScreenshotCounter( NULL );
|
||||
@ -558,6 +497,11 @@ LPCTSTR DiskGetFullDiskFilename(const int iDrive)
|
||||
return DiskGetFullName(iDrive);
|
||||
}
|
||||
|
||||
static LPCTSTR DiskGetFullPathName(const int iDrive)
|
||||
{
|
||||
return ImageGetPathname(g_aFloppyDisk[iDrive].imagehandle);
|
||||
}
|
||||
|
||||
// Return the imagename
|
||||
// . Used by Drive Button's icons & Property Sheet Page (Save snapshot)
|
||||
LPCTSTR DiskGetBaseName(const int iDrive)
|
||||
@ -611,10 +555,20 @@ ImageError_e DiskInsert(const int iDrive, LPCTSTR pszImageFilename, const bool b
|
||||
else
|
||||
fptr->bWriteProtected = bForceWriteProtected ? true : (dwAttributes & FILE_ATTRIBUTE_READONLY);
|
||||
|
||||
// Check if image is being used by the other HDD, and unplug it in order to be swapped
|
||||
std::string otherDisk = DiskGetDiskPathFilename(!iDrive);
|
||||
if (!strcmp(otherDisk.c_str(), pszImageFilename)) {
|
||||
DiskEject(!iDrive);
|
||||
// Check if image is being used by the other drive, and if so remove it in order so it can be swapped
|
||||
{
|
||||
const char* pszOtherPathname = DiskGetFullPathName(!iDrive);
|
||||
|
||||
char szCurrentPathname[MAX_PATH];
|
||||
DWORD uNameLen = GetFullPathName(pszImageFilename, MAX_PATH, szCurrentPathname, NULL);
|
||||
if (uNameLen == 0 || uNameLen >= MAX_PATH)
|
||||
strcpy_s(szCurrentPathname, MAX_PATH, pszImageFilename);
|
||||
|
||||
if (!strcmp(pszOtherPathname, szCurrentPathname))
|
||||
{
|
||||
DiskEject(!iDrive);
|
||||
FrameRefreshStatus(DRAW_LEDS | DRAW_BUTTON_DRIVES);
|
||||
}
|
||||
}
|
||||
|
||||
ImageError_e Error = ImageOpen(pszImageFilename,
|
||||
@ -637,19 +591,15 @@ ImageError_e DiskInsert(const int iDrive, LPCTSTR pszImageFilename, const bool b
|
||||
|
||||
if (Error == eIMAGE_ERROR_NONE)
|
||||
{
|
||||
GetImageTitle(pszImageFilename, fptr);
|
||||
|
||||
DiskSetDiskPathFilename(iDrive, pszImageFilename);
|
||||
|
||||
//MessageBox( g_hFrameWindow, imagefilename, fptr->imagename, MB_OK );
|
||||
Video_ResetScreenshotCounter( fptr->imagename );
|
||||
GetImageTitle(pszImageFilename, fptr->imagename, fptr->fullname);
|
||||
Video_ResetScreenshotCounter(fptr->imagename);
|
||||
}
|
||||
else
|
||||
{
|
||||
Video_ResetScreenshotCounter( NULL );
|
||||
Video_ResetScreenshotCounter(NULL);
|
||||
}
|
||||
|
||||
Disk_SaveLastDiskImage( iDrive );
|
||||
Disk_SaveLastDiskImage(iDrive);
|
||||
|
||||
return Error;
|
||||
}
|
||||
@ -730,6 +680,13 @@ void DiskNotifyInvalidImage(const int iDrive, LPCTSTR pszImageFilename, const Im
|
||||
pszImageFilename);
|
||||
break;
|
||||
|
||||
case eIMAGE_ERROR_FAILED_TO_GET_PATHNAME:
|
||||
wsprintf(
|
||||
szBuffer,
|
||||
TEXT("Unable to GetFullPathName() for the file: %s."),
|
||||
pszImageFilename);
|
||||
break;
|
||||
|
||||
default:
|
||||
// IGNORE OTHER ERRORS SILENTLY
|
||||
return;
|
||||
@ -852,7 +809,7 @@ void DiskReset(void)
|
||||
|
||||
//===========================================================================
|
||||
|
||||
void DiskSelectImage(const int iDrive, LPSTR pszFilename)
|
||||
static bool DiskSelectImage(const int iDrive, LPCSTR pszFilename)
|
||||
{
|
||||
TCHAR directory[MAX_PATH] = TEXT("");
|
||||
TCHAR filename[MAX_PATH] = TEXT("");
|
||||
@ -880,6 +837,8 @@ void DiskSelectImage(const int iDrive, LPSTR pszFilename)
|
||||
ofn.Flags = OFN_PATHMUSTEXIST;
|
||||
ofn.lpstrTitle = title;
|
||||
|
||||
bool bRes = false;
|
||||
|
||||
if (GetOpenFileName(&ofn))
|
||||
{
|
||||
if ((!ofn.nFileExtension) || !filename[ofn.nFileExtension])
|
||||
@ -888,16 +847,18 @@ void DiskSelectImage(const int iDrive, LPSTR pszFilename)
|
||||
ImageError_e Error = DiskInsert(iDrive, filename, ofn.Flags & OFN_READONLY, IMAGE_CREATE);
|
||||
if (Error == eIMAGE_ERROR_NONE)
|
||||
{
|
||||
DiskSetDiskPathFilename(iDrive, filename);
|
||||
filename[ofn.nFileOffset] = 0;
|
||||
if (_tcsicmp(directory, filename))
|
||||
RegSaveString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_START_DIR), 1, filename);
|
||||
bRes = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
DiskNotifyInvalidImage(iDrive, filename, Error);
|
||||
}
|
||||
}
|
||||
|
||||
return bRes;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@ -1040,6 +1001,8 @@ void DiskLoadRom(LPBYTE pCxRomPeripheral, UINT uSlot)
|
||||
// . In this case we can patch to compensate for an ADC or EOR checksum but not both
|
||||
|
||||
RegisterIoHandler(uSlot, Disk_IORead, Disk_IOWrite, NULL, NULL, NULL, NULL);
|
||||
|
||||
g_uSlot = uSlot;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@ -1100,53 +1063,13 @@ static BYTE __stdcall Disk_IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULON
|
||||
|
||||
//===========================================================================
|
||||
|
||||
DWORD DiskGetSnapshot(SS_CARD_DISK2* pSS, DWORD dwSlot)
|
||||
int DiskSetSnapshot_v1(const SS_CARD_DISK2* const pSS)
|
||||
{
|
||||
pSS->Hdr.UnitHdr.dwLength = sizeof(SS_CARD_DISK2);
|
||||
pSS->Hdr.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,2);
|
||||
if(pSS->Hdr.UnitHdr.hdr.v1.dwVersion > MAKE_VERSION(1,0,0,2))
|
||||
return -1;
|
||||
|
||||
pSS->Hdr.dwSlot = dwSlot;
|
||||
pSS->Hdr.dwType = CT_Disk2;
|
||||
|
||||
pSS->phases = phases; // new in 1.0.0.2 disk snapshots
|
||||
pSS->currdrive = currdrive; // this was an int in 1.0.0.1 disk snapshots
|
||||
pSS->diskaccessed = diskaccessed;
|
||||
pSS->enhancedisk = enhancedisk;
|
||||
pSS->floppylatch = floppylatch;
|
||||
pSS->floppymotoron = floppymotoron;
|
||||
pSS->floppywritemode = floppywritemode;
|
||||
|
||||
for(UINT i=0; i<NUM_DRIVES; i++)
|
||||
{
|
||||
strcpy(pSS->Unit[i].szFileName, g_aFloppyDisk[i].fullname);
|
||||
pSS->Unit[i].track = g_aFloppyDisk[i].track;
|
||||
pSS->Unit[i].phase = g_aFloppyDisk[i].phase;
|
||||
pSS->Unit[i].byte = g_aFloppyDisk[i].byte;
|
||||
pSS->Unit[i].writeprotected = g_aFloppyDisk[i].bWriteProtected ? TRUE : FALSE;
|
||||
pSS->Unit[i].trackimagedata = g_aFloppyDisk[i].trackimagedata;
|
||||
pSS->Unit[i].trackimagedirty = g_aFloppyDisk[i].trackimagedirty;
|
||||
pSS->Unit[i].spinning = g_aFloppyDisk[i].spinning;
|
||||
pSS->Unit[i].writelight = g_aFloppyDisk[i].writelight;
|
||||
pSS->Unit[i].nibbles = g_aFloppyDisk[i].nibbles;
|
||||
|
||||
if(g_aFloppyDisk[i].trackimage)
|
||||
memcpy(pSS->Unit[i].nTrack, g_aFloppyDisk[i].trackimage, NIBBLES_PER_TRACK);
|
||||
else
|
||||
memset(pSS->Unit[i].nTrack, 0, NIBBLES_PER_TRACK);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD DiskSetSnapshot(SS_CARD_DISK2* pSS, DWORD /*dwSlot*/)
|
||||
{
|
||||
if(pSS->Hdr.UnitHdr.dwVersion > MAKE_VERSION(1,0,0,2))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
phases = pSS->phases; // new in 1.0.0.2 disk snapshots
|
||||
currdrive = pSS->currdrive; // this was an int in 1.0.0.1 disk snapshots
|
||||
phases = pSS->phases;
|
||||
currdrive = pSS->currdrive;
|
||||
diskaccessed = pSS->diskaccessed;
|
||||
enhancedisk = pSS->enhancedisk;
|
||||
floppylatch = pSS->floppylatch;
|
||||
@ -1183,7 +1106,6 @@ DWORD DiskSetSnapshot(SS_CARD_DISK2* pSS, DWORD /*dwSlot*/)
|
||||
// DiskInsert() sets up:
|
||||
// . imagename
|
||||
// . fullname
|
||||
// . strDiskPathFilename
|
||||
// . writeprotected
|
||||
}
|
||||
|
||||
@ -1225,3 +1147,194 @@ DWORD DiskSetSnapshot(SS_CARD_DISK2* pSS, DWORD /*dwSlot*/)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
struct DISK2_Unit_v2
|
||||
{
|
||||
char szFileName[MAX_PATH];
|
||||
UINT Track;
|
||||
UINT Phase;
|
||||
UINT Byte;
|
||||
BOOL WriteProtected;
|
||||
BOOL TrackImageData;
|
||||
BOOL TrackImageDirty;
|
||||
DWORD Spinning;
|
||||
DWORD WriteLight;
|
||||
UINT Nibbles;
|
||||
BYTE TrackImage[NIBBLES_PER_TRACK];
|
||||
};
|
||||
|
||||
struct SS_CARD_DISK2_v2
|
||||
{
|
||||
SS_CARD_HDR Hdr;
|
||||
DISK2_Unit_v2 Unit[2];
|
||||
WORD Phases;
|
||||
WORD CurrDrive;
|
||||
BOOL DiskAccessed;
|
||||
BOOL EnhanceDisk;
|
||||
BYTE FloppyLatch;
|
||||
BOOL FloppyMotorOn;
|
||||
BOOL FloppyWriteMode;
|
||||
};
|
||||
|
||||
void DiskGetSnapshot(const HANDLE hFile)
|
||||
{
|
||||
SS_CARD_DISK2_v2 CardDisk2;
|
||||
|
||||
SS_CARD_DISK2_v2* const pSS = &CardDisk2;
|
||||
|
||||
pSS->Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_DISK2);
|
||||
pSS->Hdr.UnitHdr.hdr.v2.Type = UT_Card;
|
||||
pSS->Hdr.UnitHdr.hdr.v2.Version = 1;
|
||||
|
||||
pSS->Hdr.Slot = g_uSlot;
|
||||
pSS->Hdr.Type = CT_Disk2;
|
||||
|
||||
pSS->Phases = phases;
|
||||
pSS->CurrDrive = currdrive;
|
||||
pSS->DiskAccessed = diskaccessed;
|
||||
pSS->EnhanceDisk = enhancedisk;
|
||||
pSS->FloppyLatch = floppylatch;
|
||||
pSS->FloppyMotorOn = floppymotoron;
|
||||
pSS->FloppyWriteMode = floppywritemode;
|
||||
|
||||
for(UINT i=0; i<NUM_DRIVES; i++)
|
||||
{
|
||||
strcpy(pSS->Unit[i].szFileName, g_aFloppyDisk[i].fullname);
|
||||
pSS->Unit[i].Track = g_aFloppyDisk[i].track;
|
||||
pSS->Unit[i].Phase = g_aFloppyDisk[i].phase;
|
||||
pSS->Unit[i].Byte = g_aFloppyDisk[i].byte;
|
||||
pSS->Unit[i].WriteProtected = g_aFloppyDisk[i].bWriteProtected ? TRUE : FALSE;
|
||||
pSS->Unit[i].TrackImageData = g_aFloppyDisk[i].trackimagedata;
|
||||
pSS->Unit[i].TrackImageDirty = g_aFloppyDisk[i].trackimagedirty;
|
||||
pSS->Unit[i].Spinning = g_aFloppyDisk[i].spinning;
|
||||
pSS->Unit[i].WriteLight = g_aFloppyDisk[i].writelight;
|
||||
pSS->Unit[i].Nibbles = g_aFloppyDisk[i].nibbles;
|
||||
|
||||
if(g_aFloppyDisk[i].trackimage)
|
||||
memcpy(pSS->Unit[i].TrackImage, g_aFloppyDisk[i].trackimage, NIBBLES_PER_TRACK);
|
||||
else
|
||||
memset(pSS->Unit[i].TrackImage, 0, NIBBLES_PER_TRACK);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
DWORD dwBytesWritten;
|
||||
BOOL bRes = WriteFile( hFile,
|
||||
&CardDisk2,
|
||||
CardDisk2.Hdr.UnitHdr.hdr.v2.Length,
|
||||
&dwBytesWritten,
|
||||
NULL);
|
||||
|
||||
if(!bRes || (dwBytesWritten != CardDisk2.Hdr.UnitHdr.hdr.v2.Length))
|
||||
{
|
||||
//dwError = GetLastError();
|
||||
throw std::string("Save error: Disk][");
|
||||
}
|
||||
}
|
||||
|
||||
void DiskSetSnapshot(const HANDLE hFile)
|
||||
{
|
||||
SS_CARD_DISK2_v2 CardDisk2;
|
||||
|
||||
DWORD dwBytesRead;
|
||||
BOOL bRes = ReadFile( hFile,
|
||||
&CardDisk2,
|
||||
sizeof(CardDisk2),
|
||||
&dwBytesRead,
|
||||
NULL);
|
||||
|
||||
if (dwBytesRead != sizeof(CardDisk2))
|
||||
throw std::string("Card: file corrupt");
|
||||
|
||||
if (CardDisk2.Hdr.Slot != 6) // fixme
|
||||
throw std::string("Card: wrong slot");
|
||||
|
||||
if (CardDisk2.Hdr.UnitHdr.hdr.v2.Version > 1)
|
||||
throw std::string("Card: wrong version");
|
||||
|
||||
if (CardDisk2.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_DISK2_v2))
|
||||
throw std::string("Card: unit size mismatch");
|
||||
|
||||
const SS_CARD_DISK2_v2* const pSS = &CardDisk2;
|
||||
|
||||
phases = pSS->Phases;
|
||||
currdrive = pSS->CurrDrive;
|
||||
diskaccessed = pSS->DiskAccessed;
|
||||
enhancedisk = pSS->EnhanceDisk;
|
||||
floppylatch = pSS->FloppyLatch;
|
||||
floppymotoron = pSS->FloppyMotorOn;
|
||||
floppywritemode = pSS->FloppyWriteMode;
|
||||
|
||||
// Eject all disks first in case Drive-2 contains disk to be inserted into Drive-1
|
||||
for(UINT i=0; i<NUM_DRIVES; i++)
|
||||
{
|
||||
DiskEject(i); // Remove any disk & update Registry to reflect empty drive
|
||||
ZeroMemory(&g_aFloppyDisk[i], sizeof(Disk_t ));
|
||||
}
|
||||
|
||||
bool bResSelectImage = false;
|
||||
|
||||
for(UINT i=0; i<NUM_DRIVES; i++)
|
||||
{
|
||||
if(pSS->Unit[i].szFileName[0] == 0x00)
|
||||
continue;
|
||||
|
||||
DWORD dwAttributes = GetFileAttributes(pSS->Unit[i].szFileName);
|
||||
if(dwAttributes == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
// Get user to browse for file
|
||||
bResSelectImage = DiskSelectImage(i, pSS->Unit[i].szFileName);
|
||||
|
||||
dwAttributes = GetFileAttributes(pSS->Unit[i].szFileName);
|
||||
}
|
||||
|
||||
bool bImageError = (dwAttributes == INVALID_FILE_ATTRIBUTES);
|
||||
if (!bImageError)
|
||||
{
|
||||
if(DiskInsert(i, pSS->Unit[i].szFileName, dwAttributes & FILE_ATTRIBUTE_READONLY, IMAGE_DONT_CREATE) != eIMAGE_ERROR_NONE)
|
||||
bImageError = true;
|
||||
|
||||
// DiskInsert() sets up:
|
||||
// . imagename
|
||||
// . fullname
|
||||
// . writeprotected
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
// strcpy(g_aFloppyDisk[i].fullname, pSS->Unit[i].szFileName);
|
||||
g_aFloppyDisk[i].track = pSS->Unit[i].Track;
|
||||
g_aFloppyDisk[i].phase = pSS->Unit[i].Phase;
|
||||
g_aFloppyDisk[i].byte = pSS->Unit[i].Byte;
|
||||
// g_aFloppyDisk[i].writeprotected = pSS->Unit[i].WriteProtected;
|
||||
g_aFloppyDisk[i].trackimagedata = pSS->Unit[i].TrackImageData;
|
||||
g_aFloppyDisk[i].trackimagedirty = pSS->Unit[i].TrackImageDirty;
|
||||
g_aFloppyDisk[i].spinning = pSS->Unit[i].Spinning;
|
||||
g_aFloppyDisk[i].writelight = pSS->Unit[i].WriteLight;
|
||||
g_aFloppyDisk[i].nibbles = pSS->Unit[i].Nibbles;
|
||||
|
||||
//
|
||||
|
||||
if(!bImageError)
|
||||
{
|
||||
if((g_aFloppyDisk[i].trackimage == NULL) && g_aFloppyDisk[i].nibbles)
|
||||
AllocTrack(i);
|
||||
|
||||
if(g_aFloppyDisk[i].trackimage == NULL)
|
||||
bImageError = true;
|
||||
else
|
||||
memcpy(g_aFloppyDisk[i].trackimage, pSS->Unit[i].TrackImage, NIBBLES_PER_TRACK);
|
||||
}
|
||||
|
||||
if(bImageError)
|
||||
{
|
||||
g_aFloppyDisk[i].trackimagedata = 0;
|
||||
g_aFloppyDisk[i].trackimagedirty = 0;
|
||||
g_aFloppyDisk[i].nibbles = 0;
|
||||
}
|
||||
}
|
||||
|
||||
FrameRefreshStatus(DRAW_LEDS | DRAW_BUTTON_DRIVES);
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ const bool IMAGE_DONT_CREATE = false;
|
||||
const bool IMAGE_CREATE = true;
|
||||
|
||||
extern BOOL enhancedisk;
|
||||
const std::string& DiskGetDiskPathFilename(const int iDrive);
|
||||
const char* DiskGetDiskPathFilename(const int iDrive);
|
||||
|
||||
void DiskInitialize(void); // DiskIIManagerStartup()
|
||||
void DiskDestroy(void); // no, doesn't "destroy" the disk image. DiskIIManagerShutdown()
|
||||
@ -70,8 +70,10 @@ void DiskSelect(const int iDrive);
|
||||
void DiskUpdatePosition(DWORD);
|
||||
bool DiskDriveSwap(void);
|
||||
void DiskLoadRom(LPBYTE pCxRomPeripheral, UINT uSlot);
|
||||
DWORD DiskGetSnapshot(SS_CARD_DISK2* pSS, DWORD dwSlot);
|
||||
DWORD DiskSetSnapshot(SS_CARD_DISK2* pSS, DWORD dwSlot);
|
||||
|
||||
int DiskSetSnapshot_v1(const struct SS_CARD_DISK2* const pSS);
|
||||
void DiskGetSnapshot(const HANDLE hFile);
|
||||
void DiskSetSnapshot(const HANDLE hFile);
|
||||
|
||||
void Disk_LoadLastDiskImage(const int iDrive);
|
||||
void Disk_SaveLastDiskImage(const int iDrive);
|
||||
|
@ -27,7 +27,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "Structs.h"
|
||||
#include "Common.h"
|
||||
|
||||
#include "DiskImage.h"
|
||||
@ -40,32 +39,37 @@ static CDiskImageHelper sg_DiskImageHelper;
|
||||
|
||||
// Pre: *pWriteProtected_ already set to file's r/w status - see DiskInsert()
|
||||
ImageError_e ImageOpen( LPCTSTR pszImageFilename,
|
||||
HIMAGE* hDiskImage_,
|
||||
bool* pWriteProtected_,
|
||||
HIMAGE* hDiskImage,
|
||||
bool* pWriteProtected,
|
||||
const bool bCreateIfNecessary,
|
||||
std::string& strFilenameInZip)
|
||||
std::string& strFilenameInZip,
|
||||
const bool bExpectFloppy /*=true*/)
|
||||
{
|
||||
if (! (pszImageFilename && hDiskImage_ && pWriteProtected_ && sg_DiskImageHelper.GetWorkBuffer()))
|
||||
if (! (pszImageFilename && hDiskImage && pWriteProtected && sg_DiskImageHelper.GetWorkBuffer()))
|
||||
return eIMAGE_ERROR_BAD_POINTER;
|
||||
|
||||
// CREATE A RECORD FOR THE FILE, AND RETURN AN IMAGE HANDLE
|
||||
*hDiskImage_ = (HIMAGE) VirtualAlloc(NULL, sizeof(ImageInfo), MEM_COMMIT, PAGE_READWRITE);
|
||||
if (*hDiskImage_ == NULL)
|
||||
*hDiskImage = (HIMAGE) VirtualAlloc(NULL, sizeof(ImageInfo), MEM_COMMIT, PAGE_READWRITE);
|
||||
if (*hDiskImage == NULL)
|
||||
return eIMAGE_ERROR_BAD_POINTER;
|
||||
|
||||
ZeroMemory(*hDiskImage_, sizeof(ImageInfo));
|
||||
ImageInfo* pImageInfo = (ImageInfo*) *hDiskImage_;
|
||||
pImageInfo->bWriteProtected = *pWriteProtected_;
|
||||
ZeroMemory(*hDiskImage, sizeof(ImageInfo));
|
||||
ImageInfo* pImageInfo = (ImageInfo*) *hDiskImage;
|
||||
pImageInfo->bWriteProtected = *pWriteProtected;
|
||||
|
||||
ImageError_e Err = sg_DiskImageHelper.Open(pszImageFilename, pImageInfo, bCreateIfNecessary, strFilenameInZip);
|
||||
|
||||
if (pImageInfo->pImageType != NULL && Err == eIMAGE_ERROR_NONE && pImageInfo->pImageType->GetType() == eImageHDV)
|
||||
Err = eIMAGE_ERROR_UNSUPPORTED_HDV;
|
||||
|
||||
if (Err != eIMAGE_ERROR_NONE)
|
||||
{
|
||||
ImageClose(*hDiskImage_, true);
|
||||
*hDiskImage_ = (HIMAGE)0;
|
||||
ImageClose(*hDiskImage, true);
|
||||
*hDiskImage = (HIMAGE)0;
|
||||
return Err;
|
||||
}
|
||||
|
||||
if (pImageInfo->pImageType && pImageInfo->pImageType->GetType() == eImageHDV)
|
||||
{
|
||||
if (bExpectFloppy)
|
||||
Err = eIMAGE_ERROR_UNSUPPORTED_HDV;
|
||||
return Err;
|
||||
}
|
||||
|
||||
@ -76,7 +80,7 @@ ImageError_e ImageOpen( LPCTSTR pszImageFilename,
|
||||
for (UINT uTrack = 0; uTrack < pImageInfo->uNumTracks; uTrack++)
|
||||
pImageInfo->ValidTrack[uTrack] = (pImageInfo->uImageSize > 0) ? 1 : 0;
|
||||
|
||||
*pWriteProtected_ = pImageInfo->bWriteProtected;
|
||||
*pWriteProtected = pImageInfo->bWriteProtected;
|
||||
|
||||
return eIMAGE_ERROR_NONE;
|
||||
}
|
||||
@ -185,6 +189,36 @@ void ImageWriteTrack( const HIMAGE hDiskImage,
|
||||
|
||||
//===========================================================================
|
||||
|
||||
bool ImageReadBlock( const HIMAGE hDiskImage,
|
||||
UINT nBlock,
|
||||
LPBYTE pBlockBuffer)
|
||||
{
|
||||
ImageInfo* ptr = (ImageInfo*) hDiskImage;
|
||||
|
||||
bool bRes = false;
|
||||
if (ptr->pImageType->AllowRW())
|
||||
bRes = ptr->pImageType->Read(ptr, nBlock, pBlockBuffer);
|
||||
|
||||
return bRes;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
bool ImageWriteBlock( const HIMAGE hDiskImage,
|
||||
UINT nBlock,
|
||||
LPBYTE pBlockBuffer)
|
||||
{
|
||||
ImageInfo* ptr = (ImageInfo*) hDiskImage;
|
||||
|
||||
bool bRes = false;
|
||||
if (ptr->pImageType->AllowRW() && !ptr->bWriteProtected)
|
||||
bRes = ptr->pImageType->Write(ptr, nBlock, pBlockBuffer);
|
||||
|
||||
return bRes;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
int ImageGetNumTracks(const HIMAGE hDiskImage)
|
||||
{
|
||||
ImageInfo* ptr = (ImageInfo*) hDiskImage;
|
||||
@ -202,3 +236,60 @@ bool ImageIsMultiFileZip(const HIMAGE hDiskImage)
|
||||
ImageInfo* ptr = (ImageInfo*) hDiskImage;
|
||||
return ptr ? (ptr->uNumEntriesInZip > 1) : false;
|
||||
}
|
||||
|
||||
const char* ImageGetPathname(const HIMAGE hDiskImage)
|
||||
{
|
||||
static char* szEmpty = "";
|
||||
ImageInfo* ptr = (ImageInfo*) hDiskImage;
|
||||
return ptr ? ptr->szFilename : szEmpty;
|
||||
}
|
||||
|
||||
UINT ImageGetImageSize(const HIMAGE hDiskImage)
|
||||
{
|
||||
ImageInfo* ptr = (ImageInfo*) hDiskImage;
|
||||
return ptr ? ptr->uImageSize : 0;
|
||||
}
|
||||
|
||||
void GetImageTitle(LPCTSTR pPathname, TCHAR* pImageName, TCHAR* pFullName)
|
||||
{
|
||||
TCHAR imagetitle[ MAX_DISK_FULL_NAME+1 ];
|
||||
LPCTSTR startpos = pPathname;
|
||||
|
||||
// imagetitle = <FILENAME.EXT>
|
||||
if (_tcsrchr(startpos, TEXT('\\')))
|
||||
startpos = _tcsrchr(startpos, TEXT('\\'))+1;
|
||||
|
||||
_tcsncpy(imagetitle, startpos, MAX_DISK_FULL_NAME);
|
||||
imagetitle[MAX_DISK_FULL_NAME] = 0;
|
||||
|
||||
// if imagetitle contains a lowercase char, then found=1 (why?)
|
||||
BOOL found = 0;
|
||||
int loop = 0;
|
||||
while (imagetitle[loop] && !found)
|
||||
{
|
||||
if (IsCharLower(imagetitle[loop]))
|
||||
found = 1;
|
||||
else
|
||||
loop++;
|
||||
}
|
||||
|
||||
if ((!found) && (loop > 2))
|
||||
CharLowerBuff(imagetitle+1, _tcslen(imagetitle+1));
|
||||
|
||||
// pFullName = <FILENAME.EXT>
|
||||
_tcsncpy( pFullName, imagetitle, MAX_DISK_FULL_NAME );
|
||||
pFullName[ MAX_DISK_FULL_NAME ] = 0;
|
||||
|
||||
if (imagetitle[0])
|
||||
{
|
||||
LPTSTR dot = imagetitle;
|
||||
if (_tcsrchr(dot, TEXT('.')))
|
||||
dot = _tcsrchr(dot, TEXT('.'));
|
||||
if (dot > imagetitle)
|
||||
*dot = 0;
|
||||
}
|
||||
|
||||
// pImageName = <FILENAME> (ie. no extension)
|
||||
_tcsncpy( pImageName, imagetitle, MAX_DISK_IMAGE_NAME );
|
||||
pImageName[ MAX_DISK_IMAGE_NAME ] = 0;
|
||||
}
|
||||
|
@ -55,9 +55,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
eIMAGE_ERROR_UNABLE_TO_OPEN,
|
||||
eIMAGE_ERROR_UNABLE_TO_OPEN_GZ,
|
||||
eIMAGE_ERROR_UNABLE_TO_OPEN_ZIP,
|
||||
eIMAGE_ERROR_FAILED_TO_GET_PATHNAME,
|
||||
};
|
||||
|
||||
ImageError_e ImageOpen(LPCTSTR pszImageFilename, HIMAGE* hDiskImage_, bool* pWriteProtected_, const bool bCreateIfNecessary, std::string& strFilenameInZip);
|
||||
const int MAX_DISK_IMAGE_NAME = 15;
|
||||
const int MAX_DISK_FULL_NAME = 127;
|
||||
|
||||
|
||||
ImageError_e ImageOpen(LPCTSTR pszImageFilename, HIMAGE* hDiskImage, bool* pWriteProtected, const bool bCreateIfNecessary, std::string& strFilenameInZip, const bool bExpectFloppy=true);
|
||||
void ImageClose(const HIMAGE hDiskImage, const bool bOpenError=false);
|
||||
BOOL ImageBoot(const HIMAGE hDiskImage);
|
||||
void ImageDestroy(void);
|
||||
@ -65,7 +70,13 @@ void ImageInitialize(void);
|
||||
|
||||
void ImageReadTrack(const HIMAGE hDiskImage, int nTrack, int nQuarterTrack, LPBYTE pTrackImageBuffer, int* pNibbles);
|
||||
void ImageWriteTrack(const HIMAGE hDiskImage, int nTrack, int nQuarterTrack, LPBYTE pTrackImage, int nNibbles);
|
||||
bool ImageReadBlock(const HIMAGE hDiskImage, UINT nBlock, LPBYTE pBlockBuffer);
|
||||
bool ImageWriteBlock(const HIMAGE hDiskImage, UINT nBlock, LPBYTE pBlockBuffer);
|
||||
|
||||
int ImageGetNumTracks(const HIMAGE hDiskImage);
|
||||
bool ImageIsWriteProtected(const HIMAGE hDiskImage);
|
||||
bool ImageIsMultiFileZip(const HIMAGE hDiskImage);
|
||||
const char* ImageGetPathname(const HIMAGE hDiskImage);
|
||||
UINT ImageGetImageSize(const HIMAGE hDiskImage);
|
||||
|
||||
void GetImageTitle(LPCTSTR pPathname, TCHAR* pImageName, TCHAR* pFullName);
|
||||
|
@ -28,7 +28,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Structs.h"
|
||||
#include "Common.h"
|
||||
|
||||
#include "zlib.h"
|
||||
@ -1435,7 +1434,9 @@ ImageError_e CImageHelperBase::Open( LPCTSTR pszImageFilename,
|
||||
if (Err != eIMAGE_ERROR_NONE)
|
||||
return Err;
|
||||
|
||||
_tcsncpy(pImageInfo->szFilename, pszImageFilename, MAX_PATH);
|
||||
DWORD uNameLen = GetFullPathName(pszImageFilename, MAX_PATH, pImageInfo->szFilename, NULL);
|
||||
if (uNameLen == 0 || uNameLen >= MAX_PATH)
|
||||
Err = eIMAGE_ERROR_FAILED_TO_GET_PATHNAME;
|
||||
|
||||
return eIMAGE_ERROR_NONE;
|
||||
}
|
||||
@ -1453,9 +1454,10 @@ void CImageHelperBase::Close(ImageInfo* pImageInfo, const bool bDeleteFile)
|
||||
if (bDeleteFile)
|
||||
{
|
||||
DeleteFile(pImageInfo->szFilename);
|
||||
pImageInfo->szFilename[0] = 0;
|
||||
}
|
||||
|
||||
pImageInfo->szFilename[0] = 0;
|
||||
|
||||
delete [] pImageInfo->pImageBuffer;
|
||||
pImageInfo->pImageBuffer = NULL;
|
||||
}
|
||||
|
@ -563,7 +563,8 @@ static void DrawFrameWindow ()
|
||||
else if (g_nAppMode == MODE_DEBUG)
|
||||
DebugDisplay(1);
|
||||
else
|
||||
// Win7: In fullscreen mode with 1 redraw, the the screen doesn't get redraw.
|
||||
// Win7: In fullscreen mode with 1 redraw, the screen doesn't get redraw.
|
||||
// TC: 07/01/2015: Tryed with MP's double-buffered DX full-screen code, but still the same.
|
||||
VideoRedrawScreen(g_bIsFullScreen ? 2 : 1); // TC: 22/06/2014: Why 2 redraws in full-screen mode (32-bit only)? (8-bit doesn't need this nor does Win8, just Win7 or older OS's)
|
||||
|
||||
// DD Full-Screen Palette: BUGFIX: needs to come _after_ all drawing...
|
||||
@ -617,6 +618,9 @@ void FrameDrawDiskLEDS( HDC passdc )
|
||||
//===========================================================================
|
||||
void FrameDrawDiskStatus( HDC passdc )
|
||||
{
|
||||
if (mem == NULL)
|
||||
return;
|
||||
|
||||
// We use the actual drive since probing from memory doesn't tell us anything we don't already know.
|
||||
// DOS3.3 ProDOS
|
||||
// Drive $B7EA $BE3D
|
||||
@ -1023,7 +1027,7 @@ LRESULT CALLBACK FrameWndProc (
|
||||
if (!restart) {
|
||||
DiskDestroy();
|
||||
ImageDestroy();
|
||||
HD_Cleanup();
|
||||
HD_Destroy();
|
||||
}
|
||||
PrintDestroy();
|
||||
sg_SSC.CommDestroy();
|
||||
|
@ -4,7 +4,7 @@ AppleWin : An Apple //e emulator for Windows
|
||||
Copyright (C) 1994-1996, Michael O'Brien
|
||||
Copyright (C) 1999-2001, Oliver Schmidt
|
||||
Copyright (C) 2002-2005, Tom Charlesworth
|
||||
Copyright (C) 2006-2007, Tom Charlesworth, Michael Pohoreski
|
||||
Copyright (C) 2006-2015, Tom Charlesworth, Michael Pohoreski
|
||||
|
||||
AppleWin is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -114,22 +114,23 @@ Overview
|
||||
struct HDD
|
||||
{
|
||||
// From Disk_t
|
||||
TCHAR imagename[16]; // Not used
|
||||
TCHAR fullname[128];
|
||||
TCHAR imagename[ MAX_DISK_IMAGE_NAME + 1 ]; // <FILENAME> (ie. no extension) [not used]
|
||||
TCHAR fullname[ MAX_DISK_FULL_NAME + 1 ]; // <FILENAME.EXT> or <FILENAME.zip>
|
||||
std::string strFilenameInZip; // "" or <FILENAME.EXT> [not used]
|
||||
HIMAGE imagehandle; // Init'd by HD_Insert() -> ImageOpen()
|
||||
bool bWriteProtected; // Needed for ImageOpen() [otherwise not used]
|
||||
//
|
||||
BYTE hd_error;
|
||||
WORD hd_memblock;
|
||||
UINT hd_diskblock;
|
||||
WORD hd_buf_ptr;
|
||||
BOOL hd_imageloaded;
|
||||
BYTE hd_buf[HD_BLOCK_SIZE+1]; // Why +1?
|
||||
BYTE hd_buf[HD_BLOCK_SIZE+1]; // Why +1? Probably for erroreous reads beyond the block size (ie. reads from I/O addr 0xC0F8)
|
||||
|
||||
#if HD_LED
|
||||
Disk_Status_e hd_status_next;
|
||||
Disk_Status_e hd_status_prev;
|
||||
#endif
|
||||
|
||||
ImageInfo Info;
|
||||
};
|
||||
|
||||
static bool g_bHD_RomLoaded = false;
|
||||
@ -143,114 +144,85 @@ static BYTE g_nHD_Command;
|
||||
|
||||
static HDD g_HardDisk[NUM_HARDDISKS] = {0};
|
||||
|
||||
static bool g_bSaveDiskImage = true; // Save the DiskImage name to Registry
|
||||
static UINT g_uSlot = 7;
|
||||
|
||||
static CHardDiskImageHelper sg_HardDiskImageHelper;
|
||||
|
||||
//===========================================================================
|
||||
|
||||
static void HD_SaveLastDiskImage(const int iDrive);
|
||||
|
||||
static void HD_CleanupDrive(const int iDrive)
|
||||
{
|
||||
sg_HardDiskImageHelper.Close(&g_HardDisk[iDrive].Info, false);
|
||||
|
||||
g_HardDisk[iDrive].hd_imageloaded = false;
|
||||
g_HardDisk[iDrive].imagename[0] = 0;
|
||||
g_HardDisk[iDrive].fullname[0] = 0;
|
||||
g_HardDisk[iDrive].Info.szFilename[0] = 0;
|
||||
}
|
||||
|
||||
static ImageError_e ImageOpen( LPCTSTR pszImageFilename,
|
||||
const int iDrive,
|
||||
const bool bCreateIfNecessary,
|
||||
std::string& strFilenameInZip)
|
||||
{
|
||||
if (!pszImageFilename)
|
||||
return eIMAGE_ERROR_BAD_POINTER;
|
||||
|
||||
HDD* pHDD = &g_HardDisk[iDrive];
|
||||
ImageInfo* pImageInfo = &pHDD->Info;
|
||||
pImageInfo->bWriteProtected = false;
|
||||
|
||||
ImageError_e Err = sg_HardDiskImageHelper.Open(pszImageFilename, pImageInfo, bCreateIfNecessary, strFilenameInZip);
|
||||
|
||||
if (Err != eIMAGE_ERROR_NONE)
|
||||
if (g_HardDisk[iDrive].imagehandle)
|
||||
{
|
||||
HD_CleanupDrive(iDrive);
|
||||
return Err;
|
||||
ImageClose(g_HardDisk[iDrive].imagehandle);
|
||||
g_HardDisk[iDrive].imagehandle = (HIMAGE)0;
|
||||
}
|
||||
|
||||
return eIMAGE_ERROR_NONE;
|
||||
g_HardDisk[iDrive].hd_imageloaded = false;
|
||||
|
||||
g_HardDisk[iDrive].imagename[0] = 0;
|
||||
g_HardDisk[iDrive].fullname[0] = 0;
|
||||
g_HardDisk[iDrive].strFilenameInZip = "";
|
||||
|
||||
HD_SaveLastDiskImage(iDrive);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void GetImageTitle(LPCTSTR pszImageFilename, HDD* pHardDrive)
|
||||
{
|
||||
TCHAR imagetitle[128];
|
||||
LPCTSTR startpos = pszImageFilename;
|
||||
|
||||
// imagetitle = <FILENAME.EXT>
|
||||
if (_tcsrchr(startpos,TEXT('\\')))
|
||||
startpos = _tcsrchr(startpos,TEXT('\\'))+1;
|
||||
_tcsncpy(imagetitle,startpos,127);
|
||||
imagetitle[127] = 0;
|
||||
|
||||
// if imagetitle contains a lowercase char, then found=1 (why?)
|
||||
BOOL found = 0;
|
||||
int loop = 0;
|
||||
while (imagetitle[loop] && !found)
|
||||
{
|
||||
if (IsCharLower(imagetitle[loop]))
|
||||
found = 1;
|
||||
else
|
||||
loop++;
|
||||
}
|
||||
|
||||
if ((!found) && (loop > 2))
|
||||
CharLowerBuff(imagetitle+1,_tcslen(imagetitle+1));
|
||||
|
||||
// hdptr->fullname = <FILENAME.EXT>
|
||||
_tcsncpy(pHardDrive->fullname,imagetitle,127);
|
||||
pHardDrive->fullname[127] = 0;
|
||||
|
||||
if (imagetitle[0])
|
||||
{
|
||||
LPTSTR dot = imagetitle;
|
||||
if (_tcsrchr(dot,TEXT('.')))
|
||||
dot = _tcsrchr(dot,TEXT('.'));
|
||||
if (dot > imagetitle)
|
||||
*dot = 0;
|
||||
}
|
||||
|
||||
// hdptr->imagename = <FILENAME> (ie. no extension)
|
||||
_tcsncpy(pHardDrive->imagename,imagetitle,15);
|
||||
pHardDrive->imagename[15] = 0;
|
||||
}
|
||||
|
||||
static void NotifyInvalidImage(TCHAR* pszImageFilename)
|
||||
{
|
||||
// TC: TO DO
|
||||
}
|
||||
|
||||
static BOOL HD_Load_Image(const int iDrive, LPCSTR pszImageFilename)
|
||||
//===========================================================================
|
||||
|
||||
BOOL HD_Insert(const int iDrive, LPCTSTR pszImageFilename);
|
||||
|
||||
void HD_LoadLastDiskImage(const int iDrive)
|
||||
{
|
||||
const bool bCreateIfNecessary = false; // NB. Don't allow creation of HDV files
|
||||
std::string strFilenameInZip; // TODO: Use this
|
||||
ImageError_e Error = ImageOpen(pszImageFilename, iDrive, bCreateIfNecessary, strFilenameInZip);
|
||||
_ASSERT(iDrive == HARDDISK_1 || iDrive == HARDDISK_2);
|
||||
|
||||
g_HardDisk[iDrive].hd_imageloaded = (Error == eIMAGE_ERROR_NONE);
|
||||
char sFilePath[ MAX_PATH + 1];
|
||||
sFilePath[0] = 0;
|
||||
|
||||
#if HD_LED
|
||||
g_HardDisk[iDrive].hd_status_next = DISK_STATUS_OFF;
|
||||
g_HardDisk[iDrive].hd_status_prev = DISK_STATUS_OFF;
|
||||
#endif
|
||||
char *pRegKey = (iDrive == HARDDISK_1)
|
||||
? REGVALUE_PREF_LAST_HARDDISK_1
|
||||
: REGVALUE_PREF_LAST_HARDDISK_2;
|
||||
|
||||
return g_HardDisk[iDrive].hd_imageloaded;
|
||||
if (RegLoadString(TEXT(REG_PREFS), pRegKey, 1, sFilePath, MAX_PATH))
|
||||
{
|
||||
sFilePath[ MAX_PATH ] = 0;
|
||||
|
||||
g_bSaveDiskImage = false;
|
||||
// Pass in ptr to local copy of filepath, since RemoveDisk() sets DiskPathFilename = "" // todo: update comment for HD func
|
||||
HD_Insert(iDrive, sFilePath);
|
||||
g_bSaveDiskImage = true;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
// everything below is global
|
||||
static void HD_SaveLastDiskImage(const int iDrive)
|
||||
{
|
||||
_ASSERT(iDrive == HARDDISK_1 || iDrive == HARDDISK_2);
|
||||
|
||||
if (!g_bSaveDiskImage)
|
||||
return;
|
||||
|
||||
const char *pFileName = g_HardDisk[iDrive].fullname;
|
||||
|
||||
if (iDrive == HARDDISK_1)
|
||||
RegSaveString(TEXT(REG_PREFS), REGVALUE_PREF_LAST_HARDDISK_1, TRUE, pFileName);
|
||||
else
|
||||
RegSaveString(TEXT(REG_PREFS), REGVALUE_PREF_LAST_HARDDISK_2, TRUE, pFileName);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
// (Nearly) everything below is global
|
||||
|
||||
static BYTE __stdcall HD_IO_EMUL(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
|
||||
|
||||
@ -263,7 +235,8 @@ bool HD_CardIsEnabled(void)
|
||||
|
||||
// Called by:
|
||||
// . LoadConfiguration() - Done at each restart
|
||||
// . DiskDlg_OK() - When HD is enabled/disabled on UI
|
||||
// . RestoreCurrentConfig() - Done when Config dialog is cancelled
|
||||
// . Snapshot_LoadState_v2() - Done to default to disabled state
|
||||
void HD_SetEnabled(const bool bEnabled)
|
||||
{
|
||||
if(g_bHD_Enabled == bEnabled)
|
||||
@ -298,17 +271,17 @@ LPCTSTR HD_GetFullName(const int iDrive)
|
||||
|
||||
LPCTSTR HD_GetFullPathName(const int iDrive)
|
||||
{
|
||||
return g_HardDisk[iDrive].Info.szFilename;
|
||||
return ImageGetPathname(g_HardDisk[iDrive].imagehandle);
|
||||
}
|
||||
|
||||
static LPCTSTR HD_DiskGetBaseName (const int iDrive) // Not used
|
||||
static LPCTSTR HD_DiskGetBaseName(const int iDrive) // Not used
|
||||
{
|
||||
return g_HardDisk[iDrive].imagename;
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
VOID HD_Load_Rom(const LPBYTE pCxRomPeripheral, const UINT uSlot)
|
||||
void HD_Load_Rom(const LPBYTE pCxRomPeripheral, const UINT uSlot)
|
||||
{
|
||||
if(!g_bHD_Enabled)
|
||||
return;
|
||||
@ -336,46 +309,82 @@ VOID HD_Load_Rom(const LPBYTE pCxRomPeripheral, const UINT uSlot)
|
||||
RegisterIoHandler(g_uSlot, HD_IO_EMUL, HD_IO_EMUL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
VOID HD_Cleanup(void)
|
||||
void HD_Destroy(void)
|
||||
{
|
||||
for(int i=HARDDISK_1; i<HARDDISK_2; i++)
|
||||
{
|
||||
HD_CleanupDrive(i);
|
||||
}
|
||||
g_bSaveDiskImage = false;
|
||||
HD_CleanupDrive(HARDDISK_1);
|
||||
|
||||
g_bSaveDiskImage = false;
|
||||
HD_CleanupDrive(HARDDISK_2);
|
||||
|
||||
g_bSaveDiskImage = true;
|
||||
}
|
||||
|
||||
// pszImageFilename is qualified with path
|
||||
BOOL HD_InsertDisk(const int iDrive, LPCTSTR pszImageFilename)
|
||||
static BOOL HD_Insert(const int iDrive, LPCTSTR pszImageFilename)
|
||||
{
|
||||
if (*pszImageFilename == 0x00)
|
||||
return false;
|
||||
return FALSE;
|
||||
|
||||
if (g_HardDisk[iDrive].hd_imageloaded)
|
||||
HD_CleanupDrive(iDrive);
|
||||
HD_Unplug(iDrive);
|
||||
|
||||
// Check if image is being used by the other HDD, and unplug it in order to be swapped
|
||||
if (!strcmp(HD_GetFullPathName(!iDrive), pszImageFilename)) {
|
||||
HD_Unplug(!iDrive);
|
||||
{
|
||||
const char* pszOtherPathname = HD_GetFullPathName(!iDrive);
|
||||
|
||||
char szCurrentPathname[MAX_PATH];
|
||||
DWORD uNameLen = GetFullPathName(pszImageFilename, MAX_PATH, szCurrentPathname, NULL);
|
||||
if (uNameLen == 0 || uNameLen >= MAX_PATH)
|
||||
strcpy_s(szCurrentPathname, MAX_PATH, pszImageFilename);
|
||||
|
||||
if (!strcmp(pszOtherPathname, szCurrentPathname))
|
||||
{
|
||||
HD_Unplug(!iDrive);
|
||||
FrameRefreshStatus(DRAW_LEDS);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL bResult = HD_Load_Image(iDrive, pszImageFilename);
|
||||
const bool bCreateIfNecessary = false; // NB. Don't allow creation of HDV files
|
||||
const bool bExpectFloppy = false;
|
||||
ImageError_e Error = ImageOpen(pszImageFilename,
|
||||
&g_HardDisk[iDrive].imagehandle,
|
||||
&g_HardDisk[iDrive].bWriteProtected,
|
||||
bCreateIfNecessary,
|
||||
g_HardDisk[iDrive].strFilenameInZip, // TODO: Use this
|
||||
bExpectFloppy);
|
||||
|
||||
if (bResult)
|
||||
GetImageTitle(pszImageFilename, &g_HardDisk[iDrive]);
|
||||
g_HardDisk[iDrive].hd_imageloaded = (Error == eIMAGE_ERROR_NONE);
|
||||
|
||||
return bResult;
|
||||
#if HD_LED
|
||||
g_HardDisk[iDrive].hd_status_next = DISK_STATUS_OFF;
|
||||
g_HardDisk[iDrive].hd_status_prev = DISK_STATUS_OFF;
|
||||
#endif
|
||||
|
||||
if (Error == eIMAGE_ERROR_NONE)
|
||||
{
|
||||
GetImageTitle(pszImageFilename, g_HardDisk[iDrive].imagename, g_HardDisk[iDrive].fullname);
|
||||
}
|
||||
|
||||
HD_SaveLastDiskImage(iDrive);
|
||||
|
||||
return g_HardDisk[iDrive].hd_imageloaded;
|
||||
}
|
||||
|
||||
void HD_Select(const int iDrive)
|
||||
static bool HD_SelectImage(const int iDrive, LPCSTR pszFilename)
|
||||
{
|
||||
TCHAR directory[MAX_PATH] = TEXT("");
|
||||
TCHAR filename[MAX_PATH] = TEXT("");
|
||||
TCHAR title[40];
|
||||
|
||||
strcpy(filename, pszFilename);
|
||||
|
||||
RegLoadString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_HDV_START_DIR), 1, directory, MAX_PATH);
|
||||
_tcscpy(title, TEXT("Select HDV Image For HDD "));
|
||||
_tcscat(title, iDrive ? TEXT("2") : TEXT("1"));
|
||||
|
||||
_ASSERT(sizeof(OPENFILENAME) == sizeof(OPENFILENAME_NT4)); // Required for Win98/ME support (selected by _WIN32_WINNT=0x0400 in stdafx.h)
|
||||
|
||||
OPENFILENAME ofn;
|
||||
ZeroMemory(&ofn,sizeof(OPENFILENAME));
|
||||
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||
@ -389,22 +398,32 @@ void HD_Select(const int iDrive)
|
||||
ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; // Don't allow creation & hide the read-only checkbox
|
||||
ofn.lpstrTitle = title;
|
||||
|
||||
bool bRes = false;
|
||||
|
||||
if (GetOpenFileName(&ofn))
|
||||
{
|
||||
if ((!ofn.nFileExtension) || !filename[ofn.nFileExtension])
|
||||
_tcscat(filename,TEXT(".hdv"));
|
||||
|
||||
if (HD_InsertDisk(iDrive, filename))
|
||||
if (HD_Insert(iDrive, filename))
|
||||
{
|
||||
filename[ofn.nFileOffset] = 0;
|
||||
if (_tcsicmp(directory, filename))
|
||||
RegSaveString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_HDV_START_DIR), 1, filename);
|
||||
bRes = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
NotifyInvalidImage(filename);
|
||||
}
|
||||
}
|
||||
|
||||
return bRes;
|
||||
}
|
||||
|
||||
void HD_Select(const int iDrive)
|
||||
{
|
||||
HD_SelectImage(iDrive, TEXT(""));
|
||||
}
|
||||
|
||||
void HD_Unplug(const int iDrive)
|
||||
@ -450,33 +469,33 @@ static BYTE __stdcall HD_IO_EMUL(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG
|
||||
{
|
||||
default:
|
||||
case 0x00: //status
|
||||
if (pHDD->Info.uImageSize == 0)
|
||||
if (ImageGetImageSize(pHDD->imagehandle) == 0)
|
||||
{
|
||||
pHDD->hd_error = 1;
|
||||
r = DEVICE_IO_ERROR;
|
||||
}
|
||||
break;
|
||||
case 0x01: //read
|
||||
if ((pHDD->hd_diskblock * HD_BLOCK_SIZE) < pHDD->Info.uImageSize)
|
||||
if ((pHDD->hd_diskblock * HD_BLOCK_SIZE) < ImageGetImageSize(pHDD->imagehandle))
|
||||
{
|
||||
bool bRes = ImageReadBlock(pHDD->imagehandle, pHDD->hd_diskblock, pHDD->hd_buf);
|
||||
if (bRes)
|
||||
{
|
||||
bool bRes = pHDD->Info.pImageType->Read(&pHDD->Info, pHDD->hd_diskblock, pHDD->hd_buf);
|
||||
if (bRes)
|
||||
{
|
||||
pHDD->hd_error = 0;
|
||||
r = 0;
|
||||
pHDD->hd_buf_ptr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pHDD->hd_error = 1;
|
||||
r = DEVICE_IO_ERROR;
|
||||
}
|
||||
pHDD->hd_error = 0;
|
||||
r = 0;
|
||||
pHDD->hd_buf_ptr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pHDD->hd_error = 1;
|
||||
r = DEVICE_IO_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pHDD->hd_error = 1;
|
||||
r = DEVICE_IO_ERROR;
|
||||
}
|
||||
break;
|
||||
case 0x02: //write
|
||||
{
|
||||
@ -484,17 +503,17 @@ static BYTE __stdcall HD_IO_EMUL(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG
|
||||
pHDD->hd_status_next = DISK_STATUS_WRITE;
|
||||
#endif
|
||||
bool bRes = true;
|
||||
const bool bAppendBlocks = (pHDD->hd_diskblock * HD_BLOCK_SIZE) >= pHDD->Info.uImageSize;
|
||||
const bool bAppendBlocks = (pHDD->hd_diskblock * HD_BLOCK_SIZE) >= ImageGetImageSize(pHDD->imagehandle);
|
||||
|
||||
if (bAppendBlocks)
|
||||
{
|
||||
ZeroMemory(pHDD->hd_buf, HD_BLOCK_SIZE);
|
||||
|
||||
// Inefficient (especially for gzip/zip files!)
|
||||
UINT uBlock = pHDD->Info.uImageSize / HD_BLOCK_SIZE;
|
||||
UINT uBlock = ImageGetImageSize(pHDD->imagehandle) / HD_BLOCK_SIZE;
|
||||
while (uBlock < pHDD->hd_diskblock)
|
||||
{
|
||||
bRes = pHDD->Info.pImageType->Write(&pHDD->Info, uBlock++, pHDD->hd_buf);
|
||||
bRes = ImageWriteBlock(pHDD->imagehandle, uBlock++, pHDD->hd_buf);
|
||||
_ASSERT(bRes);
|
||||
if (!bRes)
|
||||
break;
|
||||
@ -504,7 +523,7 @@ static BYTE __stdcall HD_IO_EMUL(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG
|
||||
MoveMemory(pHDD->hd_buf, mem+pHDD->hd_memblock, HD_BLOCK_SIZE);
|
||||
|
||||
if (bRes)
|
||||
bRes = pHDD->Info.pImageType->Write(&pHDD->Info, pHDD->hd_diskblock, pHDD->hd_buf);
|
||||
bRes = ImageWriteBlock(pHDD->imagehandle, pHDD->hd_diskblock, pHDD->hd_buf);
|
||||
|
||||
if (bRes)
|
||||
{
|
||||
@ -560,7 +579,8 @@ static BYTE __stdcall HD_IO_EMUL(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG
|
||||
break;
|
||||
case 0xF8:
|
||||
r = pHDD->hd_buf[pHDD->hd_buf_ptr];
|
||||
pHDD->hd_buf_ptr++;
|
||||
if (pHDD->hd_buf_ptr < sizeof(pHDD->hd_buf)-1)
|
||||
pHDD->hd_buf_ptr++;
|
||||
break;
|
||||
default:
|
||||
#if HD_LED
|
||||
@ -631,3 +651,159 @@ void HD_GetLightStatus (Disk_Status_e *pDisk1Status_)
|
||||
*pDisk1Status_ = DISK_STATUS_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
struct HDD_Unit
|
||||
{
|
||||
char szFilename[MAX_PATH];
|
||||
BYTE error;
|
||||
WORD memblock;
|
||||
UINT diskblock;
|
||||
WORD buf_ptr;
|
||||
BOOL imageloaded;
|
||||
BYTE buf[HD_BLOCK_SIZE];
|
||||
UINT status_next;
|
||||
UINT status_prev;
|
||||
};
|
||||
|
||||
struct SS_CARD_HDD
|
||||
{
|
||||
SS_CARD_HDR Hdr;
|
||||
HDD_Unit Unit[NUM_HARDDISKS];
|
||||
BYTE CurrUnit;
|
||||
BYTE Command;
|
||||
};
|
||||
|
||||
void HD_GetSnapshot(const HANDLE hFile)
|
||||
{
|
||||
if (!HD_CardIsEnabled())
|
||||
return;
|
||||
|
||||
SS_CARD_HDD CardHDD;
|
||||
|
||||
CardHDD.Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_HDD);
|
||||
CardHDD.Hdr.UnitHdr.hdr.v2.Type = UT_Card;
|
||||
CardHDD.Hdr.UnitHdr.hdr.v2.Version = 1;
|
||||
|
||||
CardHDD.Hdr.Slot = g_uSlot;
|
||||
CardHDD.Hdr.Type = CT_GenericHDD;
|
||||
|
||||
CardHDD.CurrUnit = g_nHD_UnitNum;
|
||||
CardHDD.Command = g_nHD_Command;
|
||||
|
||||
for (UINT i=0; i<NUM_HARDDISKS; i++)
|
||||
{
|
||||
strcpy(CardHDD.Unit[i].szFilename, g_HardDisk[i].fullname);
|
||||
CardHDD.Unit[i].error = g_HardDisk[i].hd_error;
|
||||
CardHDD.Unit[i].memblock = g_HardDisk[i].hd_memblock;
|
||||
CardHDD.Unit[i].diskblock = g_HardDisk[i].hd_diskblock;
|
||||
CardHDD.Unit[i].buf_ptr = g_HardDisk[i].hd_buf_ptr;
|
||||
CardHDD.Unit[i].imageloaded = g_HardDisk[i].hd_imageloaded;
|
||||
memcpy(CardHDD.Unit[i].buf, g_HardDisk[i].hd_buf, sizeof(CardHDD.Unit[i].buf));
|
||||
CardHDD.Unit[i].status_next = g_HardDisk[i].hd_status_next;
|
||||
CardHDD.Unit[i].status_prev = g_HardDisk[i].hd_status_prev;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
DWORD dwBytesWritten;
|
||||
BOOL bRes = WriteFile( hFile,
|
||||
&CardHDD,
|
||||
CardHDD.Hdr.UnitHdr.hdr.v2.Length,
|
||||
&dwBytesWritten,
|
||||
NULL);
|
||||
|
||||
if(!bRes || (dwBytesWritten != CardHDD.Hdr.UnitHdr.hdr.v2.Length))
|
||||
{
|
||||
//dwError = GetLastError();
|
||||
throw std::string("Save error: HDD");
|
||||
}
|
||||
}
|
||||
|
||||
void HD_SetSnapshot(const HANDLE hFile, const std::string strSaveStatePath)
|
||||
{
|
||||
SS_CARD_HDD CardHDD;
|
||||
|
||||
DWORD dwBytesRead;
|
||||
BOOL bRes = ReadFile( hFile,
|
||||
&CardHDD,
|
||||
sizeof(CardHDD),
|
||||
&dwBytesRead,
|
||||
NULL);
|
||||
|
||||
if (dwBytesRead != sizeof(CardHDD))
|
||||
throw std::string("Card: file corrupt");
|
||||
|
||||
if (CardHDD.Hdr.Slot != 7) // fixme
|
||||
throw std::string("Card: wrong slot");
|
||||
|
||||
if (CardHDD.Hdr.UnitHdr.hdr.v2.Version > 1)
|
||||
throw std::string("Card: wrong version");
|
||||
|
||||
if (CardHDD.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_HDD))
|
||||
throw std::string("Card: unit size mismatch");
|
||||
|
||||
g_nHD_UnitNum = CardHDD.CurrUnit;
|
||||
g_nHD_Command = CardHDD.Command;
|
||||
|
||||
// Unplug all HDDs first in case HDD-2 is to be plugged in as HDD-1
|
||||
for (UINT i=0; i<NUM_HARDDISKS; i++)
|
||||
{
|
||||
HD_Unplug(i);
|
||||
ZeroMemory(&g_HardDisk[i], sizeof(HDD));
|
||||
}
|
||||
|
||||
bool bResSelectImage = false;
|
||||
|
||||
for (UINT i=0; i<NUM_HARDDISKS; i++)
|
||||
{
|
||||
if (CardHDD.Unit[i].szFilename[0] == 0x00)
|
||||
continue;
|
||||
|
||||
DWORD dwAttributes = GetFileAttributes(CardHDD.Unit[i].szFilename);
|
||||
if (dwAttributes == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
// Get user to browse for file
|
||||
bResSelectImage = HD_SelectImage(i, CardHDD.Unit[i].szFilename);
|
||||
|
||||
dwAttributes = GetFileAttributes(CardHDD.Unit[i].szFilename);
|
||||
}
|
||||
|
||||
bool bImageError = (dwAttributes == INVALID_FILE_ATTRIBUTES);
|
||||
if (!bImageError)
|
||||
{
|
||||
if (!HD_Insert(i, CardHDD.Unit[i].szFilename))
|
||||
bImageError = true;
|
||||
|
||||
// HD_Insert() sets up:
|
||||
// . imagename
|
||||
// . fullname
|
||||
// . hd_imageloaded
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
// strcpy(g_HardDisk[i].fullname, CardHDD.Unit[i].szFilename);
|
||||
g_HardDisk[i].hd_error = CardHDD.Unit[i].error;
|
||||
g_HardDisk[i].hd_memblock = CardHDD.Unit[i].memblock;
|
||||
g_HardDisk[i].hd_diskblock = CardHDD.Unit[i].diskblock;
|
||||
g_HardDisk[i].hd_buf_ptr = CardHDD.Unit[i].buf_ptr;
|
||||
// g_HardDisk[i].hd_imageloaded = CardHDD.Unit[i].imageloaded;
|
||||
memcpy(g_HardDisk[i].hd_buf, CardHDD.Unit[i].buf, sizeof(CardHDD.Unit[i].buf));
|
||||
g_HardDisk[i].hd_status_next = (Disk_Status_e) CardHDD.Unit[i].status_next;
|
||||
g_HardDisk[i].hd_status_prev = (Disk_Status_e) CardHDD.Unit[i].status_prev;
|
||||
|
||||
if (bImageError)
|
||||
{
|
||||
g_HardDisk[i].hd_imageloaded = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bResSelectImage)
|
||||
RegSaveString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_HDV_START_DIR), 1, strSaveStatePath.c_str());
|
||||
|
||||
HD_SetEnabled(true);
|
||||
|
||||
FrameRefreshStatus(DRAW_LEDS);
|
||||
}
|
||||
|
@ -30,16 +30,19 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
NUM_HARDDISKS
|
||||
};
|
||||
|
||||
void HD_Destroy(void);
|
||||
bool HD_CardIsEnabled(void);
|
||||
void HD_SetEnabled(const bool bEnabled);
|
||||
LPCTSTR HD_GetFullName(const int iDrive);
|
||||
LPCTSTR HD_GetFullPathName(const int iDrive);
|
||||
VOID HD_Load_Rom(const LPBYTE pCxRomPeripheral, const UINT uSlot);
|
||||
VOID HD_Cleanup(void);
|
||||
BOOL HD_InsertDisk(const int iDrive, LPCTSTR pszImageFilename);
|
||||
void HD_Load_Rom(const LPBYTE pCxRomPeripheral, const UINT uSlot);
|
||||
void HD_Select(const int iDrive);
|
||||
void HD_Unplug(const int iDrive);
|
||||
bool HD_IsDriveUnplugged(const int iDrive);
|
||||
void HD_LoadLastDiskImage(const int iDrive);
|
||||
|
||||
// 1.19.0.0 Hard Disk Status/Indicator Light
|
||||
void HD_GetLightStatus (Disk_Status_e *pDisk1Status_);
|
||||
|
||||
void HD_GetSnapshot(const HANDLE hFile);
|
||||
void HD_SetSnapshot(const HANDLE hFile, const std::string strSaveStatePath);
|
||||
|
@ -824,14 +824,19 @@ void JoyportControl(const UINT uControl)
|
||||
|
||||
//===========================================================================
|
||||
|
||||
DWORD JoyGetSnapshot(SS_IO_Joystick* pSS)
|
||||
void JoySetSnapshot_v1(const unsigned __int64 JoyCntrResetCycle)
|
||||
{
|
||||
pSS->g_nJoyCntrResetCycle = g_nJoyCntrResetCycle;
|
||||
return 0;
|
||||
g_nJoyCntrResetCycle = JoyCntrResetCycle;
|
||||
}
|
||||
|
||||
DWORD JoySetSnapshot(SS_IO_Joystick* pSS)
|
||||
//
|
||||
|
||||
void JoyGetSnapshot(unsigned __int64& rJoyCntrResetCycle)
|
||||
{
|
||||
g_nJoyCntrResetCycle = pSS->g_nJoyCntrResetCycle;
|
||||
return 0;
|
||||
rJoyCntrResetCycle = g_nJoyCntrResetCycle;
|
||||
}
|
||||
|
||||
void JoySetSnapshot(const unsigned __int64 JoyCntrResetCycle)
|
||||
{
|
||||
g_nJoyCntrResetCycle = JoyCntrResetCycle;
|
||||
}
|
||||
|
@ -24,8 +24,9 @@ void JoyDisableUsingMouse();
|
||||
void JoySetTrim(short nValue, bool bAxisX);
|
||||
short JoyGetTrim(bool bAxisX);
|
||||
void JoyportControl(const UINT uControl);
|
||||
DWORD JoyGetSnapshot(SS_IO_Joystick* pSS);
|
||||
DWORD JoySetSnapshot(SS_IO_Joystick* pSS);
|
||||
void JoySetSnapshot_v1(const unsigned __int64 JoyCntrResetCycle);
|
||||
void JoyGetSnapshot(unsigned __int64& rJoyCntrResetCycle);
|
||||
void JoySetSnapshot(const unsigned __int64 JoyCntrResetCycle);
|
||||
|
||||
BYTE __stdcall JoyReadButton(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
|
||||
BYTE __stdcall JoyReadPosition(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
|
||||
|
@ -50,7 +50,6 @@ static bool g_bCapsLock = true; //Caps lock key for Apple2 and Lat/Cyr lock for
|
||||
static bool g_bP8CapsLock = true; //Caps lock key of Pravets 8A/C
|
||||
static int lastvirtkey = 0; // Current PC keycode
|
||||
static BYTE keycode = 0; // Current Apple keycode
|
||||
static DWORD keyboardqueries = 0;
|
||||
|
||||
#ifdef KEY_OLD
|
||||
// Original
|
||||
@ -160,14 +159,6 @@ BYTE KeybGetKeycode () // Used by MemCheckPaging() & VideoCheckMode()
|
||||
return keycode;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
DWORD KeybGetNumQueries () // Used in determining 'idleness' of Apple system
|
||||
{
|
||||
DWORD result = keyboardqueries;
|
||||
keyboardqueries = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void KeybQueueKeypress (int key, BOOL bASCII)
|
||||
{
|
||||
@ -425,10 +416,6 @@ static char ClipboardCurrChar(bool bIncPtr)
|
||||
|
||||
BYTE __stdcall KeybReadData (WORD, WORD, BYTE, BYTE, ULONG)
|
||||
{
|
||||
keyboardqueries++;
|
||||
|
||||
//
|
||||
|
||||
if(g_bPasteFromClipboard)
|
||||
ClipboardInit();
|
||||
|
||||
@ -463,10 +450,6 @@ BYTE __stdcall KeybReadData (WORD, WORD, BYTE, BYTE, ULONG)
|
||||
|
||||
BYTE __stdcall KeybReadFlag (WORD, WORD, BYTE, BYTE, ULONG)
|
||||
{
|
||||
keyboardqueries++;
|
||||
|
||||
//
|
||||
|
||||
if(g_bPasteFromClipboard)
|
||||
ClipboardInit();
|
||||
|
||||
@ -516,16 +499,19 @@ void KeybToggleP8ACapsLock ()
|
||||
|
||||
//===========================================================================
|
||||
|
||||
DWORD KeybGetSnapshot(SS_IO_Keyboard* pSS)
|
||||
void KeybSetSnapshot_v1(const BYTE LastKey)
|
||||
{
|
||||
pSS->keyboardqueries = keyboardqueries;
|
||||
pSS->nLastKey = g_nLastKey;
|
||||
return 0;
|
||||
g_nLastKey = LastKey;
|
||||
}
|
||||
|
||||
DWORD KeybSetSnapshot(SS_IO_Keyboard* pSS)
|
||||
//
|
||||
|
||||
void KeybGetSnapshot(BYTE& rLastKey)
|
||||
{
|
||||
keyboardqueries = pSS->keyboardqueries;
|
||||
g_nLastKey = pSS->nLastKey;
|
||||
return 0;
|
||||
rLastKey = g_nLastKey;
|
||||
}
|
||||
|
||||
void KeybSetSnapshot(const BYTE LastKey)
|
||||
{
|
||||
g_nLastKey = LastKey;
|
||||
}
|
||||
|
@ -11,12 +11,12 @@ bool KeybGetShiftStatus();
|
||||
bool KeybGetCapsAllowed(); //For Pravets8A/C only
|
||||
void KeybUpdateCtrlShiftStatus();
|
||||
BYTE KeybGetKeycode ();
|
||||
DWORD KeybGetNumQueries ();
|
||||
void KeybQueueKeypress (int,BOOL);
|
||||
void KeybToggleCapsLock ();
|
||||
void KeybToggleP8ACapsLock ();
|
||||
DWORD KeybGetSnapshot(SS_IO_Keyboard* pSS);
|
||||
DWORD KeybSetSnapshot(SS_IO_Keyboard* pSS);
|
||||
void KeybSetSnapshot_v1(const BYTE LastKey);
|
||||
void KeybGetSnapshot(BYTE& rLastKey);
|
||||
void KeybSetSnapshot(const BYTE LastKey);
|
||||
|
||||
BYTE __stdcall KeybReadData (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
|
||||
BYTE __stdcall KeybReadFlag (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
|
||||
|
@ -51,6 +51,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "..\resource\resource.h"
|
||||
#include "Configuration\PropertySheet.h"
|
||||
#include "Debugger\DebugDefs.h"
|
||||
#include "SaveState_Structs_v2.h"
|
||||
|
||||
// Memory Flag
|
||||
#define MF_80STORE 0x00000001
|
||||
@ -1103,17 +1104,14 @@ LPBYTE MemGetCxRomPeripheral()
|
||||
|
||||
//===========================================================================
|
||||
|
||||
const UINT CxRomSize = 4*1024;
|
||||
const UINT Apple2RomSize = 12*1024;
|
||||
const UINT Apple2eRomSize = Apple2RomSize+CxRomSize;
|
||||
//const UINT Pravets82RomSize = 12*1024;
|
||||
//const UINT Pravets8ARomSize = Pravets82RomSize+CxRomSize;
|
||||
|
||||
void MemInitialize()
|
||||
{
|
||||
// Init the I/O handlers
|
||||
InitIoHandlers();
|
||||
|
||||
const UINT CxRomSize = 4*1024;
|
||||
const UINT Apple2RomSize = 12*1024;
|
||||
const UINT Apple2eRomSize = Apple2RomSize+CxRomSize;
|
||||
//const UINT Pravets82RomSize = 12*1024;
|
||||
//const UINT Pravets8ARomSize = Pravets82RomSize+CxRomSize;
|
||||
|
||||
// ALLOCATE MEMORY FOR THE APPLE MEMORY IMAGE AND ASSOCIATED DATA STRUCTURES
|
||||
memaux = (LPBYTE)VirtualAlloc(NULL,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE);
|
||||
memmain = (LPBYTE)VirtualAlloc(NULL,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE);
|
||||
@ -1154,6 +1152,14 @@ void MemInitialize()
|
||||
i++;
|
||||
#endif
|
||||
|
||||
MemInitializeROM();
|
||||
MemInitializeCustomF8ROM();
|
||||
MemInitializeIO();
|
||||
MemReset();
|
||||
}
|
||||
|
||||
void MemInitializeROM(void)
|
||||
{
|
||||
// READ THE APPLE FIRMWARE ROMS INTO THE ROM IMAGE
|
||||
UINT ROM_SIZE = 0;
|
||||
HRSRC hResInfo = NULL;
|
||||
@ -1210,8 +1216,6 @@ void MemInitialize()
|
||||
if (pData == NULL)
|
||||
return;
|
||||
|
||||
//
|
||||
|
||||
memset(pCxRomInternal,0,CxRomSize);
|
||||
memset(pCxRomPeripheral,0,CxRomSize);
|
||||
|
||||
@ -1223,17 +1227,23 @@ void MemInitialize()
|
||||
}
|
||||
|
||||
_ASSERT(ROM_SIZE == Apple2RomSize);
|
||||
memcpy(memrom, pData, Apple2RomSize); // ROM at $D000...$FFFF
|
||||
memcpy(memrom, pData, Apple2RomSize); // ROM at $D000...$FFFF
|
||||
}
|
||||
|
||||
void MemInitializeCustomF8ROM(void)
|
||||
{
|
||||
const UINT F8RomSize = 0x800;
|
||||
if (g_hCustomRomF8 != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
BYTE OldRom[Apple2RomSize]; // NB. 12KB on stack
|
||||
memcpy(OldRom, memrom, Apple2RomSize);
|
||||
|
||||
SetFilePointer(g_hCustomRomF8, 0, NULL, FILE_BEGIN);
|
||||
DWORD uNumBytesRead;
|
||||
BOOL bRes = ReadFile(g_hCustomRomF8, memrom+Apple2RomSize-F8RomSize, F8RomSize, &uNumBytesRead, NULL);
|
||||
if (uNumBytesRead != F8RomSize)
|
||||
{
|
||||
memcpy(memrom, pData, Apple2RomSize); // ROM at $D000...$FFFF
|
||||
memcpy(memrom, OldRom, Apple2RomSize); // ROM at $D000...$FFFF
|
||||
bRes = FALSE;
|
||||
}
|
||||
|
||||
@ -1248,15 +1258,27 @@ void MemInitialize()
|
||||
|
||||
if (sg_PropertySheet.GetTheFreezesF8Rom() && IS_APPLE2)
|
||||
{
|
||||
hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_FREEZES_F8_ROM), "ROM");
|
||||
HGLOBAL hResData = NULL;
|
||||
BYTE* pData = NULL;
|
||||
|
||||
HRSRC hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_FREEZES_F8_ROM), "ROM");
|
||||
|
||||
if (hResInfo && (SizeofResource(NULL, hResInfo) == 0x800) && (hResData = LoadResource(NULL, hResInfo)) && (pData = (BYTE*) LockResource(hResData)))
|
||||
{
|
||||
memcpy(memrom+Apple2RomSize-F8RomSize, pData, F8RomSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Called by:
|
||||
// . MemInitialize()
|
||||
// . Snapshot_LoadState_v2()
|
||||
//
|
||||
// Since called by LoadState(), then this must not init any cards
|
||||
// - it should only init the card I/O hooks
|
||||
void MemInitializeIO(void)
|
||||
{
|
||||
InitIoHandlers();
|
||||
|
||||
const UINT uSlot = 0;
|
||||
RegisterIoHandler(uSlot, MemSetPaging, MemSetPaging, NULL, NULL, NULL, NULL);
|
||||
@ -1297,8 +1319,6 @@ void MemInitialize()
|
||||
|
||||
DiskLoadRom(pCxRomPeripheral, 6); // $C600 : Disk][ f/w
|
||||
HD_Load_Rom(pCxRomPeripheral, 7); // $C700 : HDD f/w
|
||||
|
||||
MemReset();
|
||||
}
|
||||
|
||||
inline DWORD getRandomTime()
|
||||
@ -1647,27 +1667,43 @@ LPVOID MemGetSlotParameters(UINT uSlot)
|
||||
// . 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.
|
||||
|
||||
DWORD MemGetSnapshot(SS_BaseMemory* pSS)
|
||||
void MemSetSnapshot_v1(const DWORD MemMode, const BOOL LastWriteRam, const BYTE* const pMemMain, const BYTE* const pMemAux)
|
||||
{
|
||||
pSS->dwMemMode = memmode;
|
||||
pSS->bLastWriteRam = lastwriteram;
|
||||
SetMemMode(MemMode);
|
||||
lastwriteram = LastWriteRam;
|
||||
|
||||
for(DWORD dwOffset = 0x0000; dwOffset < 0x10000; dwOffset+=0x100)
|
||||
{
|
||||
memcpy(pSS->nMemMain+dwOffset, MemGetMainPtr((WORD)dwOffset), 0x100);
|
||||
memcpy(pSS->nMemAux+dwOffset, MemGetAuxPtr((WORD)dwOffset), 0x100);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD MemSetSnapshot(SS_BaseMemory* pSS)
|
||||
{
|
||||
SetMemMode(pSS->dwMemMode);
|
||||
lastwriteram = pSS->bLastWriteRam;
|
||||
|
||||
memcpy(memmain, pSS->nMemMain, nMemMainSize);
|
||||
memcpy(memaux, pSS->nMemAux, nMemAuxSize);
|
||||
memcpy(memmain, pMemMain, nMemMainSize);
|
||||
memcpy(memaux, pMemAux, nMemAuxSize);
|
||||
memset(memdirty, 0, 0x100);
|
||||
|
||||
//
|
||||
|
||||
modechanging = 0;
|
||||
|
||||
UpdatePaging(1); // Initialize=1
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
void MemGetSnapshot(SS_BaseMemory_v2& Memory)
|
||||
{
|
||||
Memory.dwMemMode = memmode;
|
||||
Memory.bLastWriteRam = lastwriteram;
|
||||
|
||||
for(DWORD dwOffset = 0x0000; dwOffset < 0x10000; dwOffset+=0x100)
|
||||
{
|
||||
memcpy(Memory.MemMain+dwOffset, MemGetMainPtr((WORD)dwOffset), 0x100);
|
||||
memcpy(Memory.MemAux+dwOffset, MemGetAuxPtr((WORD)dwOffset), 0x100);
|
||||
}
|
||||
}
|
||||
|
||||
void MemSetSnapshot(const SS_BaseMemory_v2& Memory)
|
||||
{
|
||||
SetMemMode(Memory.dwMemMode);
|
||||
lastwriteram = Memory.bLastWriteRam;
|
||||
|
||||
memcpy(memmain, Memory.MemMain, nMemMainSize);
|
||||
memcpy(memaux, Memory.MemAux, nMemAuxSize);
|
||||
memset(memdirty, 0, 0x100);
|
||||
|
||||
//
|
||||
@ -1675,6 +1711,4 @@ DWORD MemSetSnapshot(SS_BaseMemory* pSS)
|
||||
modechanging = 0;
|
||||
|
||||
UpdatePaging(1); // Initialize=1
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -44,14 +44,18 @@ LPBYTE MemGetMainPtr(const WORD);
|
||||
LPBYTE MemGetBankPtr(const UINT nBank);
|
||||
LPBYTE MemGetCxRomPeripheral();
|
||||
void MemInitialize ();
|
||||
void MemInitializeROM(void);
|
||||
void MemInitializeCustomF8ROM(void);
|
||||
void MemInitializeIO(void);
|
||||
BYTE MemReadFloatingBus(const ULONG uExecutedCycles);
|
||||
BYTE MemReadFloatingBus(const BYTE highbit, const ULONG uExecutedCycles);
|
||||
void MemReset ();
|
||||
void MemResetPaging ();
|
||||
void MemUpdatePaging(BOOL initialize);
|
||||
LPVOID MemGetSlotParameters (UINT uSlot);
|
||||
DWORD MemGetSnapshot(SS_BaseMemory* pSS);
|
||||
DWORD MemSetSnapshot(SS_BaseMemory* pSS);
|
||||
void MemSetSnapshot_v1(const DWORD MemMode, const BOOL LastWriteRam, const BYTE* const pMemMain, const BYTE* const pMemAux);
|
||||
void MemGetSnapshot(struct SS_BaseMemory_v2& Memory);
|
||||
void MemSetSnapshot(const struct SS_BaseMemory_v2& Memory);
|
||||
|
||||
BYTE __stdcall IO_Null(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles);
|
||||
|
||||
|
@ -77,6 +77,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "SaveState_Structs_v1.h"
|
||||
|
||||
#include "AppleWin.h"
|
||||
#include "CPU.h"
|
||||
#include "Log.h"
|
||||
@ -1761,13 +1763,15 @@ void MB_SetVolume(DWORD dwVolume, DWORD dwVolumeMax)
|
||||
|
||||
//===========================================================================
|
||||
|
||||
DWORD MB_GetSnapshot(SS_CARD_MOCKINGBOARD* pSS, DWORD dwSlot)
|
||||
// Called by debugger - Debugger_Display.cpp
|
||||
void MB_GetSnapshot_v1(SS_CARD_MOCKINGBOARD* const pSS, const DWORD dwSlot)
|
||||
{
|
||||
pSS->Hdr.UnitHdr.dwLength = sizeof(SS_CARD_DISK2);
|
||||
pSS->Hdr.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,0);
|
||||
pSS->Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_MOCKINGBOARD);
|
||||
pSS->Hdr.UnitHdr.hdr.v2.Type = UT_Card;
|
||||
pSS->Hdr.UnitHdr.hdr.v2.Version = 1;
|
||||
|
||||
pSS->Hdr.dwSlot = dwSlot;
|
||||
pSS->Hdr.dwType = CT_MockingboardC;
|
||||
pSS->Hdr.Slot = dwSlot;
|
||||
pSS->Hdr.Type = CT_MockingboardC;
|
||||
|
||||
UINT nMbCardNum = dwSlot - SLOT4;
|
||||
UINT nDeviceNum = nMbCardNum*2;
|
||||
@ -1783,16 +1787,14 @@ DWORD MB_GetSnapshot(SS_CARD_MOCKINGBOARD* pSS, DWORD dwSlot)
|
||||
nDeviceNum++;
|
||||
pMB++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD MB_SetSnapshot(SS_CARD_MOCKINGBOARD* pSS, DWORD /*dwSlot*/)
|
||||
int MB_SetSnapshot_v1(const SS_CARD_MOCKINGBOARD* const pSS, const DWORD /*dwSlot*/)
|
||||
{
|
||||
if(pSS->Hdr.UnitHdr.dwVersion != MAKE_VERSION(1,0,0,0))
|
||||
if(pSS->Hdr.UnitHdr.hdr.v1.dwVersion != MAKE_VERSION(1,0,0,0))
|
||||
return -1;
|
||||
|
||||
UINT nMbCardNum = pSS->Hdr.dwSlot - SLOT4;
|
||||
UINT nMbCardNum = pSS->Hdr.Slot - SLOT4;
|
||||
UINT nDeviceNum = nMbCardNum*2;
|
||||
SY6522_AY8910* pMB = &g_MB[nDeviceNum];
|
||||
|
||||
@ -1832,3 +1834,111 @@ DWORD MB_SetSnapshot(SS_CARD_MOCKINGBOARD* pSS, DWORD /*dwSlot*/)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
void MB_GetSnapshot(const HANDLE hFile, const UINT uSlot)
|
||||
{
|
||||
SS_CARD_MOCKINGBOARD CardMockingboardC;
|
||||
|
||||
SS_CARD_MOCKINGBOARD* const pSS = &CardMockingboardC;
|
||||
|
||||
pSS->Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_MOCKINGBOARD);
|
||||
pSS->Hdr.UnitHdr.hdr.v2.Type = UT_Card;
|
||||
pSS->Hdr.UnitHdr.hdr.v2.Version = 1;
|
||||
|
||||
pSS->Hdr.Slot = uSlot; // fixme: object should be just 1 Mockingboard card & it will know its slot
|
||||
pSS->Hdr.Type = CT_MockingboardC;
|
||||
|
||||
UINT nMbCardNum = uSlot - SLOT4;
|
||||
UINT nDeviceNum = nMbCardNum*2;
|
||||
SY6522_AY8910* pMB = &g_MB[nDeviceNum];
|
||||
|
||||
for(UINT i=0; i<MB_UNITS_PER_CARD; i++)
|
||||
{
|
||||
memcpy(&pSS->Unit[i].RegsSY6522, &pMB->sy6522, sizeof(SY6522));
|
||||
memcpy(&pSS->Unit[i].RegsAY8910, AY8910_GetRegsPtr(nDeviceNum), 16);
|
||||
memcpy(&pSS->Unit[i].RegsSSI263, &pMB->SpeechChip, sizeof(SSI263A));
|
||||
pSS->Unit[i].nAYCurrentRegister = pMB->nAYCurrentRegister;
|
||||
|
||||
nDeviceNum++;
|
||||
pMB++;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
DWORD dwBytesWritten;
|
||||
BOOL bRes = WriteFile( hFile,
|
||||
&CardMockingboardC,
|
||||
CardMockingboardC.Hdr.UnitHdr.hdr.v2.Length,
|
||||
&dwBytesWritten,
|
||||
NULL);
|
||||
|
||||
if(!bRes || (dwBytesWritten != CardMockingboardC.Hdr.UnitHdr.hdr.v2.Length))
|
||||
{
|
||||
//dwError = GetLastError();
|
||||
throw std::string("Save error: Mockingboard");
|
||||
}
|
||||
}
|
||||
|
||||
void MB_SetSnapshot(const HANDLE hFile)
|
||||
{
|
||||
SS_CARD_MOCKINGBOARD CardMockingboardC;
|
||||
|
||||
DWORD dwBytesRead;
|
||||
BOOL bRes = ReadFile( hFile,
|
||||
&CardMockingboardC,
|
||||
sizeof(CardMockingboardC),
|
||||
&dwBytesRead,
|
||||
NULL);
|
||||
|
||||
if (dwBytesRead != sizeof(CardMockingboardC))
|
||||
throw std::string("Card: file corrupt");
|
||||
|
||||
if (CardMockingboardC.Hdr.Slot != 4 && CardMockingboardC.Hdr.Slot != 5) // fixme
|
||||
throw std::string("Card: wrong slot");
|
||||
|
||||
if (CardMockingboardC.Hdr.UnitHdr.hdr.v2.Version > 1)
|
||||
throw std::string("Card: wrong version");
|
||||
|
||||
if (CardMockingboardC.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_MOCKINGBOARD))
|
||||
throw std::string("Card: unit size mismatch");
|
||||
|
||||
UINT nMbCardNum = CardMockingboardC.Hdr.Slot - SLOT4;
|
||||
UINT nDeviceNum = nMbCardNum*2;
|
||||
SY6522_AY8910* pMB = &g_MB[nDeviceNum];
|
||||
|
||||
g_nSSI263Device = 0;
|
||||
g_nCurrentActivePhoneme = -1;
|
||||
|
||||
for(UINT i=0; i<MB_UNITS_PER_CARD; i++)
|
||||
{
|
||||
memcpy(&pMB->sy6522, &CardMockingboardC.Unit[i].RegsSY6522, sizeof(SY6522));
|
||||
memcpy(AY8910_GetRegsPtr(nDeviceNum), &CardMockingboardC.Unit[i].RegsAY8910, 16);
|
||||
memcpy(&pMB->SpeechChip, &CardMockingboardC.Unit[i].RegsSSI263, sizeof(SSI263A));
|
||||
pMB->nAYCurrentRegister = CardMockingboardC.Unit[i].nAYCurrentRegister;
|
||||
|
||||
StartTimer(pMB); // Attempt to start timer
|
||||
|
||||
//
|
||||
|
||||
// Crude - currently only support a single speech chip
|
||||
// FIX THIS:
|
||||
// . Speech chip could be Votrax instead
|
||||
// . Is this IRQ compatible with Phasor?
|
||||
if(pMB->SpeechChip.DurationPhonome)
|
||||
{
|
||||
g_nSSI263Device = nDeviceNum;
|
||||
|
||||
if((pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED) && (pMB->sy6522.PCR == 0x0C) && (pMB->sy6522.IER & IxR_PERIPHERAL))
|
||||
{
|
||||
pMB->sy6522.IFR |= IxR_PERIPHERAL;
|
||||
UpdateIFR(pMB);
|
||||
pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin
|
||||
}
|
||||
}
|
||||
|
||||
nDeviceNum++;
|
||||
pMB++;
|
||||
}
|
||||
}
|
||||
|
@ -22,5 +22,8 @@ double MB_GetFramePeriod();
|
||||
bool MB_IsActive();
|
||||
DWORD MB_GetVolume();
|
||||
void MB_SetVolume(DWORD dwVolume, DWORD dwVolumeMax);
|
||||
DWORD MB_GetSnapshot(SS_CARD_MOCKINGBOARD* pSS, DWORD dwSlot);
|
||||
DWORD MB_SetSnapshot(SS_CARD_MOCKINGBOARD* pSS, DWORD dwSlot);
|
||||
|
||||
void MB_GetSnapshot_v1(struct SS_CARD_MOCKINGBOARD* const pSS, const DWORD dwSlot); // For debugger
|
||||
int MB_SetSnapshot_v1(const struct SS_CARD_MOCKINGBOARD* const pSS, const DWORD dwSlot);
|
||||
void MB_GetSnapshot(const HANDLE hFile, const UINT uSlot);
|
||||
void MB_SetSnapshot(const HANDLE hFile);
|
||||
|
@ -41,7 +41,7 @@ Etc.
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Structs.h"
|
||||
#include "SaveState_Structs_common.h"
|
||||
#include "Common.h"
|
||||
|
||||
#include "CPU.h"
|
||||
@ -598,6 +598,166 @@ void CMouseInterface::SetButton(eBUTTON Button, eBUTTONSTATE State)
|
||||
OnMouseEvent();
|
||||
}
|
||||
|
||||
struct MouseCard_Unit
|
||||
{
|
||||
//6821
|
||||
mc6821_t mc6821;
|
||||
BYTE byIA;
|
||||
BYTE byIB;
|
||||
|
||||
//MouseCard
|
||||
int nDataLen;
|
||||
BYTE byMode;
|
||||
|
||||
BYTE by6821B;
|
||||
BYTE by6821A;
|
||||
BYTE byBuff[8];
|
||||
int nBuffPos;
|
||||
|
||||
BYTE byState;
|
||||
int nX;
|
||||
int nY;
|
||||
BOOL bBtn0;
|
||||
BOOL bBtn1;
|
||||
|
||||
bool bVBL;
|
||||
|
||||
//
|
||||
|
||||
int iX;
|
||||
int iMinX;
|
||||
int iMaxX;
|
||||
int iY;
|
||||
int iMinY;
|
||||
int iMaxY;
|
||||
|
||||
BOOL bButtons[2];
|
||||
|
||||
//
|
||||
|
||||
bool bActive; // Mouse h/w is active within the Apple][ VM
|
||||
bool bEnabled; // Windows' mouse events get passed to Apple]['s mouse h/w
|
||||
};
|
||||
|
||||
struct SS_CARD_MOUSECARD
|
||||
{
|
||||
SS_CARD_HDR Hdr;
|
||||
MouseCard_Unit Unit;
|
||||
};
|
||||
|
||||
// Post:
|
||||
// 0 = No mouse card
|
||||
// >0 = Mouse card saved OK from slot n
|
||||
// -1 = File error
|
||||
int CMouseInterface::GetSnapshot(const HANDLE hFile)
|
||||
{
|
||||
if (!m_bActive)
|
||||
return 0;
|
||||
|
||||
SS_CARD_MOUSECARD CardMouseCard;
|
||||
|
||||
CardMouseCard.Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_MOUSECARD);
|
||||
CardMouseCard.Hdr.UnitHdr.hdr.v2.Type = UT_Card;
|
||||
CardMouseCard.Hdr.UnitHdr.hdr.v2.Version = 1;
|
||||
|
||||
CardMouseCard.Hdr.Slot = m_uSlot;
|
||||
CardMouseCard.Hdr.Type = CT_MouseInterface;
|
||||
|
||||
MouseCard_Unit& Unit = CardMouseCard.Unit;
|
||||
|
||||
m_6821.Get6821(Unit.mc6821, Unit.byIA, Unit.byIB);
|
||||
|
||||
Unit.nDataLen = m_nDataLen;
|
||||
Unit.byMode = m_byMode;
|
||||
Unit.by6821B = m_by6821B;
|
||||
Unit.by6821A = m_by6821A;
|
||||
memcpy(Unit.byBuff, m_byBuff, sizeof(Unit.byBuff));
|
||||
Unit.nBuffPos = m_nBuffPos;
|
||||
Unit.byState = m_byState;
|
||||
Unit.nX = m_nX;
|
||||
Unit.nY = m_nY;
|
||||
Unit.bBtn0 = m_bBtn0;
|
||||
Unit.bBtn1 = m_bBtn1;
|
||||
Unit.bVBL = m_bVBL;
|
||||
Unit.iX = m_iX;
|
||||
Unit.iMinX = m_iMinX;
|
||||
Unit.iMaxX = m_iMaxX;
|
||||
Unit.iY = m_iY;
|
||||
Unit.iMinY = m_iMinY;
|
||||
Unit.iMaxY = m_iMaxY;
|
||||
Unit.bButtons[0] = m_bButtons[0];
|
||||
Unit.bButtons[1] = m_bButtons[1];
|
||||
Unit.bActive = m_bActive;
|
||||
Unit.bEnabled = m_bEnabled;
|
||||
|
||||
//
|
||||
|
||||
DWORD dwBytesWritten;
|
||||
BOOL bRes = WriteFile( hFile,
|
||||
&CardMouseCard,
|
||||
CardMouseCard.Hdr.UnitHdr.hdr.v2.Length,
|
||||
&dwBytesWritten,
|
||||
NULL);
|
||||
|
||||
if(!bRes || (dwBytesWritten != CardMouseCard.Hdr.UnitHdr.hdr.v2.Length))
|
||||
throw std::string("Save error: Mouse");
|
||||
|
||||
return m_uSlot;
|
||||
}
|
||||
|
||||
void CMouseInterface::SetSnapshot(const HANDLE hFile)
|
||||
{
|
||||
SS_CARD_MOUSECARD CardMouseCard;
|
||||
|
||||
DWORD dwBytesRead;
|
||||
BOOL bRes = ReadFile( hFile,
|
||||
&CardMouseCard,
|
||||
sizeof(CardMouseCard),
|
||||
&dwBytesRead,
|
||||
NULL);
|
||||
|
||||
if (dwBytesRead != sizeof(CardMouseCard))
|
||||
throw std::string("Card: file corrupt");
|
||||
|
||||
if (CardMouseCard.Hdr.Slot != 4) // fixme
|
||||
throw std::string("Card: wrong slot");
|
||||
|
||||
if (CardMouseCard.Hdr.UnitHdr.hdr.v2.Version > 1)
|
||||
throw std::string("Card: wrong version");
|
||||
|
||||
if (CardMouseCard.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_MOUSECARD))
|
||||
throw std::string("Card: unit size mismatch");
|
||||
|
||||
const MouseCard_Unit& Unit = CardMouseCard.Unit;
|
||||
|
||||
m_6821.Set6821(Unit.mc6821, Unit.byIA, Unit.byIB);
|
||||
|
||||
m_nDataLen = Unit.nDataLen;
|
||||
m_byMode = Unit.byMode;
|
||||
m_by6821B = Unit.by6821B;
|
||||
m_by6821A = Unit.by6821A;
|
||||
memcpy(m_byBuff, Unit.byBuff, sizeof(Unit.byBuff));
|
||||
m_nBuffPos = Unit.nBuffPos;
|
||||
m_byState = Unit.byState;
|
||||
m_nX = Unit.nX;
|
||||
m_nY = Unit.nY;
|
||||
m_bBtn0 = Unit.bBtn0;
|
||||
m_bBtn1 = Unit.bBtn1;
|
||||
m_bVBL = Unit.bVBL;
|
||||
m_iX = Unit.iX;
|
||||
m_iMinX = Unit.iMinX;
|
||||
m_iMaxX = Unit.iMaxX;
|
||||
m_iY = Unit.iY;
|
||||
m_iMinY = Unit.iMinY;
|
||||
m_iMaxY = Unit.iMaxY;
|
||||
m_bButtons[0] = Unit.bButtons[0];
|
||||
m_bButtons[1] = Unit.bButtons[1];
|
||||
|
||||
m_bActive = Unit.bActive;
|
||||
//m_bEnabled = Unit.bEnabled;
|
||||
//m_uSlot = CardMouseCard.Hdr.Slot;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// DirectInput interface
|
||||
//=============================================================================
|
||||
@ -819,4 +979,4 @@ namespace DIMouse
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}; // namespace DIMouse
|
||||
}; // namespace DIMouse
|
||||
|
@ -12,7 +12,6 @@ public:
|
||||
void Initialize(LPBYTE pCxRomPeripheral, UINT uSlot);
|
||||
void Uninitialize();
|
||||
void Reset();
|
||||
void SetSlotRom();
|
||||
static BYTE __stdcall IORead(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft);
|
||||
static BYTE __stdcall IOWrite(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft);
|
||||
|
||||
@ -38,7 +37,11 @@ public:
|
||||
m_iY = iY;
|
||||
}
|
||||
|
||||
int GetSnapshot(const HANDLE hFile);
|
||||
void SetSnapshot(const HANDLE hFile);
|
||||
|
||||
protected:
|
||||
void SetSlotRom();
|
||||
void On6821_A(BYTE byData);
|
||||
void On6821_B(BYTE byData);
|
||||
void OnCommand();
|
||||
|
@ -36,18 +36,19 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "..\resource\resource.h"
|
||||
|
||||
static DWORD inactivity = 0;
|
||||
static int g_iPrinterIdleLimit = 10;
|
||||
static FILE* file = NULL;
|
||||
DWORD const PRINTDRVR_SIZE = APPLE_SLOT_SIZE;
|
||||
TCHAR filepath[MAX_PATH * 2];
|
||||
#define DEFAULT_PRINT_FILENAME "Printer.txt"
|
||||
static char g_szPrintFilename[MAX_PATH] = {0};
|
||||
bool g_bDumpToPrinter = false;
|
||||
bool g_bConvertEncoding = true;
|
||||
bool g_bFilterUnprintable = true;
|
||||
bool g_bPrinterAppend = false;
|
||||
int g_iPrinterIdleLimit = 10;
|
||||
bool g_bEnableDumpToRealPrinter = false;
|
||||
|
||||
static UINT g_uSlot = 0;
|
||||
|
||||
//===========================================================================
|
||||
|
||||
static BYTE __stdcall PrintStatus(WORD, WORD, BYTE, BYTE, ULONG);
|
||||
@ -79,6 +80,8 @@ VOID PrintLoadRom(LPBYTE pCxRomPeripheral, const UINT uSlot)
|
||||
//
|
||||
|
||||
RegisterIoHandler(uSlot, PrintStatus, PrintTransmit, NULL, NULL, NULL, NULL);
|
||||
|
||||
g_uSlot = uSlot;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@ -245,8 +248,110 @@ unsigned int Printer_GetIdleLimit()
|
||||
return g_iPrinterIdleLimit;
|
||||
}
|
||||
|
||||
//unsigned int
|
||||
void Printer_SetIdleLimit(unsigned int Duration)
|
||||
{
|
||||
g_iPrinterIdleLimit = Duration;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
struct PrinterCard_Unit
|
||||
{
|
||||
DWORD Inactivity;
|
||||
UINT PrinterIdleLimit;
|
||||
char PrintFilename[MAX_PATH];
|
||||
BOOL IsFileOpen;
|
||||
BOOL DumpToPrinter;
|
||||
BOOL ConvertEncoding;
|
||||
BOOL FilterUnprintable;
|
||||
BOOL PrinterAppend;
|
||||
BOOL EnableDumpToRealPrinter;
|
||||
};
|
||||
|
||||
struct SS_CARD_PRINTER
|
||||
{
|
||||
SS_CARD_HDR Hdr;
|
||||
PrinterCard_Unit Unit;
|
||||
};
|
||||
|
||||
void Printer_GetSnapshot(const HANDLE hFile)
|
||||
{
|
||||
SS_CARD_PRINTER CardPrinter;
|
||||
|
||||
SS_CARD_PRINTER* const pSS = &CardPrinter;
|
||||
|
||||
pSS->Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_PRINTER);
|
||||
pSS->Hdr.UnitHdr.hdr.v2.Type = UT_Card;
|
||||
pSS->Hdr.UnitHdr.hdr.v2.Version = 1;
|
||||
|
||||
pSS->Hdr.Slot = g_uSlot;
|
||||
pSS->Hdr.Type = CT_GenericPrinter;
|
||||
|
||||
CardPrinter.Unit.Inactivity = inactivity;
|
||||
CardPrinter.Unit.PrinterIdleLimit = g_iPrinterIdleLimit;
|
||||
memcpy(CardPrinter.Unit.PrintFilename, g_szPrintFilename, sizeof(CardPrinter.Unit.PrintFilename));
|
||||
CardPrinter.Unit.IsFileOpen = (file != NULL);
|
||||
CardPrinter.Unit.DumpToPrinter = g_bDumpToPrinter;
|
||||
CardPrinter.Unit.ConvertEncoding = g_bConvertEncoding;
|
||||
CardPrinter.Unit.FilterUnprintable = g_bFilterUnprintable;
|
||||
CardPrinter.Unit.PrinterAppend = g_bPrinterAppend;
|
||||
CardPrinter.Unit.EnableDumpToRealPrinter = g_bEnableDumpToRealPrinter;
|
||||
|
||||
//
|
||||
|
||||
DWORD dwBytesWritten;
|
||||
BOOL bRes = WriteFile( hFile,
|
||||
&CardPrinter,
|
||||
CardPrinter.Hdr.UnitHdr.hdr.v2.Length,
|
||||
&dwBytesWritten,
|
||||
NULL);
|
||||
|
||||
if(!bRes || (dwBytesWritten != CardPrinter.Hdr.UnitHdr.hdr.v2.Length))
|
||||
{
|
||||
//dwError = GetLastError();
|
||||
throw std::string("Save error: Printer Card");
|
||||
}
|
||||
}
|
||||
|
||||
void Printer_SetSnapshot(const HANDLE hFile)
|
||||
{
|
||||
SS_CARD_PRINTER CardPrinter;
|
||||
|
||||
DWORD dwBytesRead;
|
||||
BOOL bRes = ReadFile( hFile,
|
||||
&CardPrinter,
|
||||
sizeof(CardPrinter),
|
||||
&dwBytesRead,
|
||||
NULL);
|
||||
|
||||
if (dwBytesRead != sizeof(CardPrinter))
|
||||
throw std::string("Card: file corrupt");
|
||||
|
||||
if (CardPrinter.Hdr.Slot != 1) // fixme
|
||||
throw std::string("Card: wrong slot");
|
||||
|
||||
if (CardPrinter.Hdr.UnitHdr.hdr.v2.Version > 1)
|
||||
throw std::string("Card: wrong version");
|
||||
|
||||
if (CardPrinter.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_PRINTER))
|
||||
throw std::string("Card: unit size mismatch");
|
||||
|
||||
ClosePrint(); // Close current print session (and close file handle)
|
||||
|
||||
inactivity = CardPrinter.Unit.Inactivity;
|
||||
g_iPrinterIdleLimit = CardPrinter.Unit.PrinterIdleLimit;
|
||||
memcpy(g_szPrintFilename, CardPrinter.Unit.PrintFilename, sizeof(g_szPrintFilename));
|
||||
if (CardPrinter.Unit.IsFileOpen)
|
||||
{
|
||||
g_bPrinterAppend = true; // Re-open print-file in append mode
|
||||
BOOL bRes = CheckPrint();
|
||||
if (!bRes)
|
||||
throw std::string("Printer Card: Unable to resume printing to file");
|
||||
}
|
||||
|
||||
g_bDumpToPrinter = CardPrinter.Unit.DumpToPrinter == TRUE;
|
||||
g_bConvertEncoding = CardPrinter.Unit.ConvertEncoding == TRUE;
|
||||
g_bFilterUnprintable = CardPrinter.Unit.FilterUnprintable == TRUE;
|
||||
g_bPrinterAppend = CardPrinter.Unit.PrinterAppend == TRUE;
|
||||
g_bEnableDumpToRealPrinter = CardPrinter.Unit.EnableDumpToRealPrinter == TRUE;
|
||||
}
|
||||
|
@ -9,11 +9,11 @@ char* Printer_GetFilename();
|
||||
void Printer_SetIdleLimit(unsigned int Duration);
|
||||
unsigned int Printer_GetIdleLimit();
|
||||
|
||||
void Printer_GetSnapshot(const HANDLE hFile);
|
||||
void Printer_SetSnapshot(const HANDLE hFile);
|
||||
|
||||
extern bool g_bDumpToPrinter;
|
||||
extern bool g_bConvertEncoding;
|
||||
extern bool g_bFilterUnprintable;
|
||||
extern bool g_bPrinterAppend;
|
||||
extern int g_iPrinterIdleLimit;
|
||||
extern bool g_bFilterUnprintable;
|
||||
extern bool g_bPrinterAppend;
|
||||
extern bool g_bEnableDumpToRealPrinter; // Set by cmd-line: -printer-real
|
||||
|
@ -23,11 +23,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/* Description: Save-state (snapshot) module
|
||||
*
|
||||
* Author: Copyright (c) 2004-2006 Tom Charlesworth
|
||||
* Author: Copyright (c) 2004-2015 Tom Charlesworth
|
||||
*/
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "SaveState_Structs_v1.h"
|
||||
#include "SaveState_Structs_v2.h"
|
||||
|
||||
#include "AppleWin.h"
|
||||
#include "CPU.h"
|
||||
#include "Disk.h"
|
||||
@ -36,10 +39,15 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "Keyboard.h"
|
||||
#include "Memory.h"
|
||||
#include "Mockingboard.h"
|
||||
#include "MouseInterface.h"
|
||||
#include "ParallelPrinter.h"
|
||||
#include "SerialComms.h"
|
||||
#include "Speaker.h"
|
||||
#include "Video.h"
|
||||
|
||||
#include "Configuration\Config.h"
|
||||
#include "Configuration\IPropertySheet.h"
|
||||
|
||||
|
||||
#define DEFAULT_SNAPSHOT_NAME "SaveState.aws"
|
||||
|
||||
@ -93,22 +101,27 @@ const char* Snapshot_GetPath()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void Snapshot_LoadState()
|
||||
static void Snapshot_LoadState_v1() // .aws v1.0.0.1, up to (and including) AppleWin v1.25.0
|
||||
{
|
||||
char szMessage[32 + MAX_PATH];
|
||||
std::string strOldImageDir;
|
||||
std::string strOldImageDir(g_sCurrentDir);
|
||||
|
||||
APPLEWIN_SNAPSHOT* pSS = (APPLEWIN_SNAPSHOT*) new char[sizeof(APPLEWIN_SNAPSHOT)];
|
||||
APPLEWIN_SNAPSHOT_v1* pSS = (APPLEWIN_SNAPSHOT_v1*) new char[sizeof(APPLEWIN_SNAPSHOT_v1)]; // throw's bad_alloc
|
||||
|
||||
try
|
||||
{
|
||||
strOldImageDir = g_sCurrentDir;
|
||||
#if _MSC_VER >= 1600 // static_assert supported from VS2010 (cl.exe v16.00)
|
||||
static_assert(kSnapshotSize_v1 == sizeof(APPLEWIN_SNAPSHOT_v1), "Save-state v1 struct size mismatch");
|
||||
#else
|
||||
// A compile error here means sizeof(APPLEWIN_SNAPSHOT_v1) is wrong, eg. one of the constituent structs has been modified
|
||||
typedef char VerifySizesAreEqual[kSnapshotSize_v1 == sizeof(APPLEWIN_SNAPSHOT_v1) ? 1 : -1];
|
||||
#endif
|
||||
|
||||
if (kSnapshotSize_v1 != sizeof(APPLEWIN_SNAPSHOT_v1))
|
||||
throw std::string("Save-state v1 struct size mismatch");
|
||||
|
||||
SetCurrentImageDir(g_strSaveStatePath.c_str()); // Allow .dsk's load without prompting
|
||||
|
||||
if(pSS == NULL)
|
||||
throw(0);
|
||||
|
||||
memset(pSS, 0, sizeof(APPLEWIN_SNAPSHOT));
|
||||
memset(pSS, 0, sizeof(APPLEWIN_SNAPSHOT_v1));
|
||||
|
||||
//
|
||||
|
||||
@ -121,39 +134,26 @@ void Snapshot_LoadState()
|
||||
NULL);
|
||||
|
||||
if(hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
strcpy(szMessage, "File not found: ");
|
||||
strcpy(szMessage + strlen(szMessage), g_strSaveStatePathname.c_str());
|
||||
throw(0);
|
||||
}
|
||||
throw std::string("File not found: ") + g_strSaveStatePathname;
|
||||
|
||||
DWORD dwBytesRead;
|
||||
BOOL bRes = ReadFile( hFile,
|
||||
pSS,
|
||||
sizeof(APPLEWIN_SNAPSHOT),
|
||||
sizeof(APPLEWIN_SNAPSHOT_v1),
|
||||
&dwBytesRead,
|
||||
NULL);
|
||||
|
||||
CloseHandle(hFile);
|
||||
|
||||
if(!bRes || (dwBytesRead != sizeof(APPLEWIN_SNAPSHOT)))
|
||||
{
|
||||
if(!bRes || (dwBytesRead != sizeof(APPLEWIN_SNAPSHOT_v1)))
|
||||
// File size wrong: probably because of version mismatch or corrupt file
|
||||
strcpy(szMessage, "File size mismatch");
|
||||
throw(0);
|
||||
}
|
||||
throw std::string("File size mismatch");
|
||||
|
||||
if(pSS->Hdr.dwTag != AW_SS_TAG)
|
||||
{
|
||||
strcpy(szMessage, "File corrupt");
|
||||
throw(0);
|
||||
}
|
||||
throw std::string("File corrupt");
|
||||
|
||||
if(pSS->Hdr.dwVersion != MAKE_VERSION(1,0,0,1))
|
||||
{
|
||||
strcpy(szMessage, "Version mismatch");
|
||||
throw(0);
|
||||
}
|
||||
throw std::string("Version mismatch");
|
||||
|
||||
// TO DO: Verify checksum
|
||||
|
||||
@ -173,34 +173,40 @@ void Snapshot_LoadState()
|
||||
// Apple2 unit
|
||||
//
|
||||
|
||||
CpuSetSnapshot(&pSS->Apple2Unit.CPU6502);
|
||||
sg_SSC.CommSetSnapshot(&pSS->Apple2Unit.Comms);
|
||||
JoySetSnapshot(&pSS->Apple2Unit.Joystick);
|
||||
KeybSetSnapshot(&pSS->Apple2Unit.Keyboard);
|
||||
SpkrSetSnapshot(&pSS->Apple2Unit.Speaker);
|
||||
VideoSetSnapshot(&pSS->Apple2Unit.Video);
|
||||
MemSetSnapshot(&pSS->Apple2Unit.Memory);
|
||||
SS_CPU6502& CPU = pSS->Apple2Unit.CPU6502;
|
||||
CpuSetSnapshot_v1(CPU.A, CPU.X, CPU.Y, CPU.P, CPU.S, CPU.PC, CPU.nCumulativeCycles);
|
||||
|
||||
SS_IO_Comms& SSC = pSS->Apple2Unit.Comms;
|
||||
sg_SSC.SetSnapshot_v1(SSC.baudrate, SSC.bytesize, SSC.commandbyte, SSC.comminactivity, SSC.controlbyte, SSC.parity, SSC.stopbits);
|
||||
|
||||
JoySetSnapshot_v1(pSS->Apple2Unit.Joystick.nJoyCntrResetCycle);
|
||||
KeybSetSnapshot_v1(pSS->Apple2Unit.Keyboard.nLastKey);
|
||||
SpkrSetSnapshot_v1(pSS->Apple2Unit.Speaker.nSpkrLastCycle);
|
||||
VideoSetSnapshot_v1(pSS->Apple2Unit.Video.bAltCharSet, pSS->Apple2Unit.Video.dwVidMode);
|
||||
MemSetSnapshot_v1(pSS->Apple2Unit.Memory.dwMemMode, pSS->Apple2Unit.Memory.bLastWriteRam, pSS->Apple2Unit.Memory.nMemMain, pSS->Apple2Unit.Memory.nMemAux);
|
||||
|
||||
//
|
||||
|
||||
//
|
||||
// Slot4: Mockingboard
|
||||
MB_SetSnapshot(&pSS->Mockingboard1, 4);
|
||||
MB_SetSnapshot_v1(&pSS->Mockingboard1, 4);
|
||||
|
||||
//
|
||||
// Slot5: Mockingboard
|
||||
MB_SetSnapshot(&pSS->Mockingboard2, 5);
|
||||
MB_SetSnapshot_v1(&pSS->Mockingboard2, 5);
|
||||
|
||||
//
|
||||
// Slot6: Disk][
|
||||
DiskSetSnapshot(&pSS->Disk2, 6);
|
||||
DiskSetSnapshot_v1(&pSS->Disk2);
|
||||
|
||||
SetLoadedSaveStateFlag(true);
|
||||
|
||||
MemUpdatePaging(TRUE);
|
||||
}
|
||||
catch(int)
|
||||
catch(std::string szMessage)
|
||||
{
|
||||
MessageBox( g_hFrameWindow,
|
||||
szMessage,
|
||||
szMessage.c_str(),
|
||||
TEXT("Load State"),
|
||||
MB_ICONEXCLAMATION | MB_SETFOREGROUND);
|
||||
|
||||
@ -212,104 +218,429 @@ void Snapshot_LoadState()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void Snapshot_SaveState()
|
||||
HANDLE m_hFile = INVALID_HANDLE_VALUE;
|
||||
CConfigNeedingRestart m_ConfigNew;
|
||||
|
||||
static void Snapshot_LoadState_FileHdr(SS_FILE_HDR& Hdr)
|
||||
{
|
||||
APPLEWIN_SNAPSHOT* pSS = (APPLEWIN_SNAPSHOT*) new char[sizeof(APPLEWIN_SNAPSHOT)];
|
||||
if(pSS == NULL)
|
||||
try
|
||||
{
|
||||
// To do
|
||||
m_hFile = CreateFile( g_strSaveStatePathname.c_str(),
|
||||
GENERIC_READ,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
|
||||
if(m_hFile == INVALID_HANDLE_VALUE)
|
||||
throw std::string("File not found: ") + g_strSaveStatePathname;
|
||||
|
||||
DWORD dwBytesRead;
|
||||
BOOL bRes = ReadFile( m_hFile,
|
||||
&Hdr,
|
||||
sizeof(Hdr),
|
||||
&dwBytesRead,
|
||||
NULL);
|
||||
|
||||
if(!bRes || (dwBytesRead != sizeof(Hdr)))
|
||||
throw std::string("File size mismatch");
|
||||
|
||||
if(Hdr.dwTag != AW_SS_TAG)
|
||||
throw std::string("File corrupt");
|
||||
}
|
||||
catch(std::string szMessage)
|
||||
{
|
||||
MessageBox( g_hFrameWindow,
|
||||
szMessage.c_str(),
|
||||
TEXT("Load State"),
|
||||
MB_ICONEXCLAMATION | MB_SETFOREGROUND);
|
||||
|
||||
if(m_hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle(m_hFile);
|
||||
m_hFile = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define UNIT_APPLE2_VER 1
|
||||
#define UNIT_CARD_VER 1
|
||||
#define UNIT_CONFIG_VER 1
|
||||
|
||||
static void LoadUnitApple2(DWORD Length, DWORD Version)
|
||||
{
|
||||
SS_APPLE2_Unit_v2 Apple2Unit;
|
||||
|
||||
if (Version != UNIT_APPLE2_VER)
|
||||
throw std::string("Apple2: Version mismatch");
|
||||
|
||||
if (Length != sizeof(Apple2Unit))
|
||||
throw std::string("Apple2: Length mismatch");
|
||||
|
||||
if (SetFilePointer(m_hFile, -(LONG)sizeof(Apple2Unit.UnitHdr), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER)
|
||||
throw std::string("Apple2: file corrupt");
|
||||
|
||||
DWORD dwBytesRead;
|
||||
BOOL bRes = ReadFile( m_hFile,
|
||||
&Apple2Unit,
|
||||
Length,
|
||||
&dwBytesRead,
|
||||
NULL);
|
||||
|
||||
if (dwBytesRead != Length)
|
||||
throw std::string("Apple2: file corrupt");
|
||||
|
||||
g_Apple2Type = (eApple2Type) Apple2Unit.Apple2Type;
|
||||
m_ConfigNew.m_Apple2Type = g_Apple2Type;
|
||||
|
||||
CpuSetSnapshot(Apple2Unit.CPU6502);
|
||||
JoySetSnapshot(Apple2Unit.Joystick.JoyCntrResetCycle);
|
||||
KeybSetSnapshot(Apple2Unit.Keyboard.LastKey);
|
||||
SpkrSetSnapshot(Apple2Unit.Speaker.SpkrLastCycle);
|
||||
VideoSetSnapshot(Apple2Unit.Video);
|
||||
MemSetSnapshot(Apple2Unit.Memory);
|
||||
}
|
||||
|
||||
//===
|
||||
|
||||
static void LoadCardDisk2(void)
|
||||
{
|
||||
DiskSetSnapshot(m_hFile);
|
||||
}
|
||||
|
||||
static void LoadCardMockingboardC(void)
|
||||
{
|
||||
MB_SetSnapshot(m_hFile);
|
||||
}
|
||||
|
||||
static void LoadCardMouseInterface(void)
|
||||
{
|
||||
sg_Mouse.SetSnapshot(m_hFile);
|
||||
}
|
||||
|
||||
static void LoadCardSSC(void)
|
||||
{
|
||||
sg_SSC.SetSnapshot(m_hFile);
|
||||
}
|
||||
|
||||
static void LoadCardPrinter(void)
|
||||
{
|
||||
Printer_SetSnapshot(m_hFile);
|
||||
}
|
||||
|
||||
static void LoadCardHDD(void)
|
||||
{
|
||||
HD_SetSnapshot(m_hFile, g_strSaveStatePath);
|
||||
m_ConfigNew.m_bEnableHDD = true;
|
||||
}
|
||||
|
||||
//===
|
||||
|
||||
static void LoadUnitCard(DWORD Length, DWORD Version)
|
||||
{
|
||||
SS_CARD_HDR Card;
|
||||
|
||||
if (Version != UNIT_APPLE2_VER)
|
||||
throw std::string("Card: Version mismatch");
|
||||
|
||||
if (Length < sizeof(Card))
|
||||
throw std::string("Card: file corrupt");
|
||||
|
||||
if (SetFilePointer(m_hFile, -(LONG)sizeof(Card.UnitHdr), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER)
|
||||
throw std::string("Card: file corrupt");
|
||||
|
||||
DWORD dwBytesRead;
|
||||
BOOL bRes = ReadFile( m_hFile,
|
||||
&Card,
|
||||
sizeof(Card),
|
||||
&dwBytesRead,
|
||||
NULL);
|
||||
|
||||
if (dwBytesRead != sizeof(Card))
|
||||
throw std::string("Card: file corrupt");
|
||||
|
||||
//currently cards are changed by restarting machine (ie. all slot empty) then adding cards (most of which are hardcoded to specific slots)
|
||||
|
||||
if (SetFilePointer(m_hFile, -(LONG)sizeof(SS_CARD_HDR), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER)
|
||||
throw std::string("Card: file corrupt");
|
||||
|
||||
bool bIsCardSupported = true;
|
||||
|
||||
switch(Card.Type)
|
||||
{
|
||||
case CT_Empty:
|
||||
throw std::string("Card: todo");
|
||||
break;
|
||||
case CT_Disk2:
|
||||
LoadCardDisk2();
|
||||
break;
|
||||
case CT_SSC:
|
||||
LoadCardSSC();
|
||||
break;
|
||||
case CT_MockingboardC:
|
||||
LoadCardMockingboardC();
|
||||
break;
|
||||
case CT_GenericPrinter:
|
||||
LoadCardPrinter();
|
||||
break;
|
||||
case CT_GenericHDD:
|
||||
LoadCardHDD();
|
||||
break;
|
||||
case CT_MouseInterface:
|
||||
LoadCardMouseInterface();
|
||||
break;
|
||||
case CT_Z80:
|
||||
throw std::string("Card: todo");
|
||||
break;
|
||||
case CT_Phasor:
|
||||
throw std::string("Card: todo");
|
||||
break;
|
||||
default:
|
||||
//throw std::string("Card: unsupported");
|
||||
bIsCardSupported = false;
|
||||
if (SetFilePointer(m_hFile, Card.UnitHdr.hdr.v2.Length, NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER)
|
||||
throw std::string("Card: failed to skip unsupported card");
|
||||
}
|
||||
|
||||
if (bIsCardSupported)
|
||||
m_ConfigNew.m_Slot[Card.Slot] = (SS_CARDTYPE) Card.Type;
|
||||
}
|
||||
|
||||
static void LoadUnitConfig(DWORD Length, DWORD Version)
|
||||
{
|
||||
SS_APPLEWIN_CONFIG Cfg;
|
||||
|
||||
if (Version != UNIT_CONFIG_VER)
|
||||
throw std::string("Config: Version mismatch");
|
||||
|
||||
if (Length != sizeof(Cfg))
|
||||
throw std::string("Config: Length mismatch");
|
||||
|
||||
if (SetFilePointer(m_hFile, -(LONG)sizeof(Cfg.UnitHdr), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER)
|
||||
throw std::string("Config: file corrupt");
|
||||
|
||||
DWORD dwBytesRead;
|
||||
BOOL bRes = ReadFile( m_hFile,
|
||||
&Cfg,
|
||||
Length,
|
||||
&dwBytesRead,
|
||||
NULL);
|
||||
|
||||
if (dwBytesRead != Length)
|
||||
throw std::string("Config: file corrupt");
|
||||
|
||||
// todo:
|
||||
//m_ConfigNew.m_bEnhanceDisk;
|
||||
//m_ConfigNew.m_bEnableHDD;
|
||||
}
|
||||
|
||||
static void Snapshot_LoadState_v2(DWORD dwVersion)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (dwVersion != MAKE_VERSION(2,0,0,0))
|
||||
throw std::string("Version mismatch");
|
||||
|
||||
CConfigNeedingRestart ConfigOld;
|
||||
ConfigOld.m_Slot[1] = CT_GenericPrinter; // fixme
|
||||
ConfigOld.m_Slot[2] = CT_SSC; // fixme
|
||||
ConfigOld.m_Slot[6] = CT_Disk2; // fixme
|
||||
ConfigOld.m_Slot[7] = ConfigOld.m_bEnableHDD ? CT_GenericHDD : CT_Empty; // fixme
|
||||
|
||||
for (UINT i=0; i<NUM_SLOTS; i++)
|
||||
m_ConfigNew.m_Slot[i] = CT_Empty;
|
||||
|
||||
MemReset();
|
||||
|
||||
if (!IS_APPLE2)
|
||||
MemResetPaging();
|
||||
|
||||
DiskReset();
|
||||
KeybReset();
|
||||
VideoResetState();
|
||||
MB_Reset();
|
||||
sg_Mouse.Uninitialize();
|
||||
sg_Mouse.Reset();
|
||||
HD_SetEnabled(false);
|
||||
|
||||
while(1)
|
||||
{
|
||||
SS_UNIT_HDR UnitHdr;
|
||||
DWORD dwBytesRead;
|
||||
BOOL bRes = ReadFile( m_hFile,
|
||||
&UnitHdr,
|
||||
sizeof(UnitHdr),
|
||||
&dwBytesRead,
|
||||
NULL);
|
||||
|
||||
if (dwBytesRead == 0)
|
||||
break; // EOF (OK)
|
||||
|
||||
if(!bRes || (dwBytesRead != sizeof(UnitHdr)))
|
||||
throw std::string("File size mismatch");
|
||||
|
||||
switch (UnitHdr.hdr.v2.Type)
|
||||
{
|
||||
case UT_Apple2:
|
||||
LoadUnitApple2(UnitHdr.hdr.v2.Length, UnitHdr.hdr.v2.Version);
|
||||
break;
|
||||
case UT_Card:
|
||||
LoadUnitCard(UnitHdr.hdr.v2.Length, UnitHdr.hdr.v2.Version);
|
||||
break;
|
||||
case UT_Config:
|
||||
LoadUnitConfig(UnitHdr.hdr.v2.Length, UnitHdr.hdr.v2.Version);
|
||||
break;
|
||||
default:
|
||||
// Log then skip unsupported unit type
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SetLoadedSaveStateFlag(true);
|
||||
|
||||
// NB. The following disparity should be resolved:
|
||||
// . A change in h/w via the Configuration property sheets results in a the VM completely restarting (via WM_USER_RESTART)
|
||||
// . A change in h/w via loading a save-state avoids this VM restart
|
||||
// The latter is the desired approach (as the former needs a "power-on" / F2 to start things again)
|
||||
|
||||
sg_PropertySheet.ApplyNewConfig(m_ConfigNew, ConfigOld);
|
||||
|
||||
MemInitializeROM();
|
||||
MemInitializeCustomF8ROM();
|
||||
MemInitializeIO();
|
||||
|
||||
MemUpdatePaging(TRUE);
|
||||
|
||||
//PostMessage(g_hFrameWindow, WM_USER_RESTART, 0, 0); // No, as this power-cycles VM (undoing all the new state just loaded)
|
||||
}
|
||||
catch(std::string szMessage)
|
||||
{
|
||||
MessageBox( g_hFrameWindow,
|
||||
szMessage.c_str(),
|
||||
TEXT("Load State"),
|
||||
MB_ICONEXCLAMATION | MB_SETFOREGROUND);
|
||||
}
|
||||
|
||||
CloseHandle(m_hFile);
|
||||
m_hFile = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
void Snapshot_LoadState()
|
||||
{
|
||||
SS_FILE_HDR Hdr;
|
||||
Snapshot_LoadState_FileHdr(Hdr);
|
||||
|
||||
if (m_hFile == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
|
||||
if(Hdr.dwVersion <= MAKE_VERSION(1,0,0,1))
|
||||
{
|
||||
CloseHandle(m_hFile);
|
||||
m_hFile = INVALID_HANDLE_VALUE;
|
||||
|
||||
Snapshot_LoadState_v1();
|
||||
return;
|
||||
}
|
||||
|
||||
memset(pSS, 0, sizeof(APPLEWIN_SNAPSHOT));
|
||||
Snapshot_LoadState_v2(Hdr.dwVersion);
|
||||
}
|
||||
|
||||
pSS->Hdr.dwTag = AW_SS_TAG;
|
||||
pSS->Hdr.dwVersion = MAKE_VERSION(1,0,0,1);
|
||||
pSS->Hdr.dwChecksum = 0; // TO DO
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Apple2 unit
|
||||
//
|
||||
|
||||
pSS->Apple2Unit.UnitHdr.dwLength = sizeof(SS_APPLE2_Unit);
|
||||
pSS->Apple2Unit.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,0);
|
||||
|
||||
CpuGetSnapshot(&pSS->Apple2Unit.CPU6502);
|
||||
sg_SSC.CommGetSnapshot(&pSS->Apple2Unit.Comms);
|
||||
JoyGetSnapshot(&pSS->Apple2Unit.Joystick);
|
||||
KeybGetSnapshot(&pSS->Apple2Unit.Keyboard);
|
||||
SpkrGetSnapshot(&pSS->Apple2Unit.Speaker);
|
||||
VideoGetSnapshot(&pSS->Apple2Unit.Video);
|
||||
MemGetSnapshot(&pSS->Apple2Unit.Memory);
|
||||
|
||||
//
|
||||
// Slot1: Empty
|
||||
pSS->Empty1.Hdr.UnitHdr.dwLength = sizeof(SS_CARD_EMPTY);
|
||||
pSS->Empty1.Hdr.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,0);
|
||||
pSS->Empty1.Hdr.dwSlot = 1;
|
||||
pSS->Empty1.Hdr.dwType = CT_Empty;
|
||||
|
||||
//
|
||||
// Slot2: Empty
|
||||
pSS->Empty2.Hdr.UnitHdr.dwLength = sizeof(SS_CARD_EMPTY);
|
||||
pSS->Empty2.Hdr.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,0);
|
||||
pSS->Empty2.Hdr.dwSlot = 2;
|
||||
pSS->Empty2.Hdr.dwType = CT_Empty;
|
||||
|
||||
//
|
||||
// Slot3: Empty
|
||||
pSS->Empty3.Hdr.UnitHdr.dwLength = sizeof(SS_CARD_EMPTY);
|
||||
pSS->Empty3.Hdr.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,0);
|
||||
pSS->Empty3.Hdr.dwSlot = 3;
|
||||
pSS->Empty3.Hdr.dwType = CT_Empty;
|
||||
|
||||
//
|
||||
// Slot4: Mockingboard
|
||||
MB_GetSnapshot(&pSS->Mockingboard1, 4);
|
||||
|
||||
//
|
||||
// Slot5: Mockingboard
|
||||
MB_GetSnapshot(&pSS->Mockingboard2, 5);
|
||||
|
||||
//
|
||||
// Slot6: Disk][
|
||||
DiskGetSnapshot(&pSS->Disk2, 6);
|
||||
|
||||
//
|
||||
|
||||
HANDLE hFile = CreateFile( g_strSaveStatePathname.c_str(),
|
||||
GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
|
||||
DWORD dwError = GetLastError();
|
||||
_ASSERT((dwError == 0) || (dwError == ERROR_ALREADY_EXISTS));
|
||||
|
||||
if(hFile != INVALID_HANDLE_VALUE)
|
||||
void Snapshot_SaveState()
|
||||
{
|
||||
try
|
||||
{
|
||||
// todo: append '.aws' if missing
|
||||
|
||||
m_hFile = CreateFile( g_strSaveStatePathname.c_str(),
|
||||
GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
|
||||
DWORD dwError = GetLastError();
|
||||
_ASSERT((dwError == 0) || (dwError == ERROR_ALREADY_EXISTS));
|
||||
|
||||
// todo: handle ERROR_ALREADY_EXISTS - ask if user wants to replace existing file
|
||||
|
||||
if(m_hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
//dwError = GetLastError();
|
||||
throw std::string("Save error");
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
APPLEWIN_SNAPSHOT_v2 AppleSnapshotv2;
|
||||
|
||||
AppleSnapshotv2.Hdr.dwTag = AW_SS_TAG;
|
||||
AppleSnapshotv2.Hdr.dwVersion = MAKE_VERSION(2,0,0,0);
|
||||
AppleSnapshotv2.Hdr.dwChecksum = 0; // TO DO
|
||||
|
||||
SS_APPLE2_Unit_v2& Apple2Unit = AppleSnapshotv2.Apple2Unit;
|
||||
|
||||
//
|
||||
// Apple2 unit
|
||||
//
|
||||
|
||||
Apple2Unit.UnitHdr.hdr.v2.Length = sizeof(SS_APPLE2_Unit_v2);
|
||||
Apple2Unit.UnitHdr.hdr.v2.Type = UT_Apple2;
|
||||
Apple2Unit.UnitHdr.hdr.v2.Version = UNIT_APPLE2_VER;
|
||||
|
||||
Apple2Unit.Apple2Type = g_Apple2Type;
|
||||
|
||||
CpuGetSnapshot(Apple2Unit.CPU6502);
|
||||
JoyGetSnapshot(Apple2Unit.Joystick.JoyCntrResetCycle);
|
||||
KeybGetSnapshot(Apple2Unit.Keyboard.LastKey);
|
||||
SpkrGetSnapshot(Apple2Unit.Speaker.SpkrLastCycle);
|
||||
VideoGetSnapshot(Apple2Unit.Video);
|
||||
MemGetSnapshot(Apple2Unit.Memory);
|
||||
|
||||
DWORD dwBytesWritten;
|
||||
BOOL bRes = WriteFile( hFile,
|
||||
pSS,
|
||||
sizeof(APPLEWIN_SNAPSHOT),
|
||||
BOOL bRes = WriteFile( m_hFile,
|
||||
&AppleSnapshotv2,
|
||||
sizeof(APPLEWIN_SNAPSHOT_v2),
|
||||
&dwBytesWritten,
|
||||
NULL);
|
||||
|
||||
if(!bRes || (dwBytesWritten != sizeof(APPLEWIN_SNAPSHOT)))
|
||||
dwError = GetLastError();
|
||||
if(!bRes || (dwBytesWritten != sizeof(APPLEWIN_SNAPSHOT_v2)))
|
||||
{
|
||||
//dwError = GetLastError();
|
||||
throw std::string("Save error");
|
||||
}
|
||||
|
||||
CloseHandle(hFile);
|
||||
//
|
||||
|
||||
Printer_GetSnapshot(m_hFile);
|
||||
|
||||
sg_SSC.GetSnapshot(m_hFile);
|
||||
|
||||
sg_Mouse.GetSnapshot(m_hFile);
|
||||
|
||||
if (g_Slot4 == CT_MockingboardC)
|
||||
MB_GetSnapshot(m_hFile, 4);
|
||||
|
||||
if (g_Slot5 == CT_MockingboardC)
|
||||
MB_GetSnapshot(m_hFile, 5);
|
||||
|
||||
DiskGetSnapshot(m_hFile);
|
||||
|
||||
HD_GetSnapshot(m_hFile);
|
||||
}
|
||||
else
|
||||
catch(std::string szMessage)
|
||||
{
|
||||
dwError = GetLastError();
|
||||
MessageBox( g_hFrameWindow,
|
||||
szMessage.c_str(),
|
||||
TEXT("Save State"),
|
||||
MB_ICONEXCLAMATION | MB_SETFOREGROUND);
|
||||
}
|
||||
|
||||
_ASSERT((dwError == 0) || (dwError == ERROR_ALREADY_EXISTS));
|
||||
|
||||
delete [] pSS;
|
||||
CloseHandle(m_hFile);
|
||||
m_hFile = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
77
source/SaveState_Structs_common.h
Normal file
77
source/SaveState_Structs_common.h
Normal file
@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
|
||||
// Structs used by save-state file
|
||||
|
||||
// *** DON'T CHANGE ANY STRUCT WITHOUT CONSIDERING BACKWARDS COMPATIBILITY WITH .AWS FORMAT ***
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define MAKE_VERSION(a,b,c,d) ((a<<24) | (b<<16) | (c<<8) | (d))
|
||||
|
||||
#define AW_SS_TAG 'SSWA' // 'AWSS' = AppleWin SnapShot
|
||||
|
||||
struct SS_FILE_HDR
|
||||
{
|
||||
DWORD dwTag; // "AWSS"
|
||||
DWORD dwVersion;
|
||||
DWORD dwChecksum;
|
||||
};
|
||||
|
||||
struct SS_UNIT_HDR
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
DWORD dwLength; // Byte length of this unit struct
|
||||
DWORD dwVersion;
|
||||
} v1;
|
||||
struct
|
||||
{
|
||||
DWORD Length; // Byte length of this unit struct
|
||||
WORD Type; // SS_UNIT_TYPE
|
||||
WORD Version; // Incrementing value from 1
|
||||
} v2;
|
||||
} hdr;
|
||||
};
|
||||
|
||||
enum SS_UNIT_TYPE
|
||||
{
|
||||
UT_Reserved = 0,
|
||||
UT_Apple2,
|
||||
UT_Card,
|
||||
UT_Config,
|
||||
};
|
||||
|
||||
const UINT nMemMainSize = 64*1024;
|
||||
const UINT nMemAuxSize = 64*1024;
|
||||
|
||||
struct SS_CARD_HDR
|
||||
{
|
||||
SS_UNIT_HDR UnitHdr;
|
||||
DWORD Type; // SS_CARDTYPE
|
||||
DWORD Slot; // [1..7], 0=Language card, 8=Aux
|
||||
};
|
||||
|
||||
enum SS_CARDTYPE
|
||||
{
|
||||
CT_Empty = 0,
|
||||
CT_Disk2, // Apple Disk][
|
||||
CT_SSC, // Apple Super Serial Card
|
||||
CT_MockingboardC, // Soundcard
|
||||
CT_GenericPrinter,
|
||||
CT_GenericHDD, // Hard disk
|
||||
CT_GenericClock,
|
||||
CT_MouseInterface,
|
||||
CT_Z80,
|
||||
CT_Phasor, // Soundcard
|
||||
CT_Echo, // Soundcard
|
||||
CT_SAM, // Soundcard: Software Automated Mouth
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct SS_CARD_EMPTY
|
||||
{
|
||||
SS_CARD_HDR Hdr;
|
||||
};
|
@ -1,34 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "DiskDefs.h"
|
||||
#include "SaveState_Structs_common.h"
|
||||
|
||||
// Structs used by save-state file
|
||||
// Structs used by save-state file v1
|
||||
|
||||
// *** DON'T CHANGE ANY STRUCT WITHOUT CONSIDERING BACKWARDS COMPATIBILITY WITH .AWS FORMAT ***
|
||||
|
||||
#define MAKE_VERSION(a,b,c,d) ((a<<24) | (b<<16) | (c<<8) | (d))
|
||||
|
||||
#define AW_SS_TAG 'SSWA' // 'AWSS' = AppleWin SnapShot
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DWORD dwTag; // "AWSS"
|
||||
DWORD dwVersion;
|
||||
DWORD dwChecksum;
|
||||
} SS_FILE_HDR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DWORD dwLength; // Byte length of this unit struct
|
||||
DWORD dwVersion;
|
||||
} SS_UNIT_HDR;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const UINT nMemMainSize = 64*1024;
|
||||
const UINT nMemAuxSize = 64*1024;
|
||||
|
||||
typedef struct
|
||||
struct SS_CPU6502
|
||||
{
|
||||
BYTE A;
|
||||
BYTE X;
|
||||
@ -36,13 +17,13 @@ typedef struct
|
||||
BYTE P;
|
||||
BYTE S;
|
||||
USHORT PC;
|
||||
unsigned __int64 g_nCumulativeCycles;
|
||||
unsigned __int64 nCumulativeCycles;
|
||||
// IRQ = OR-sum of all interrupt sources
|
||||
} SS_CPU6502;
|
||||
};
|
||||
|
||||
const UINT uRecvBufferSize = 9;
|
||||
|
||||
typedef struct
|
||||
struct SS_IO_Comms
|
||||
{
|
||||
DWORD baudrate;
|
||||
BYTE bytesize;
|
||||
@ -53,121 +34,53 @@ typedef struct
|
||||
BYTE recvbuffer[uRecvBufferSize];
|
||||
DWORD recvbytes;
|
||||
BYTE stopbits;
|
||||
} SS_IO_Comms;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
struct SS_IO_Joystick
|
||||
{
|
||||
unsigned __int64 g_nJoyCntrResetCycle;
|
||||
} SS_IO_Joystick;
|
||||
unsigned __int64 nJoyCntrResetCycle;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
struct SS_IO_Keyboard
|
||||
{
|
||||
DWORD keyboardqueries;
|
||||
BYTE nLastKey;
|
||||
} SS_IO_Keyboard;
|
||||
};
|
||||
|
||||
//typedef struct
|
||||
//{
|
||||
//} SS_IO_Memory;
|
||||
|
||||
typedef struct
|
||||
struct SS_IO_Speaker
|
||||
{
|
||||
unsigned __int64 g_nSpkrLastCycle;
|
||||
} SS_IO_Speaker;
|
||||
unsigned __int64 nSpkrLastCycle;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
struct SS_IO_Video
|
||||
{
|
||||
bool bAltCharSet; // charoffs
|
||||
DWORD dwVidMode;
|
||||
} SS_IO_Video;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
struct SS_BaseMemory
|
||||
{
|
||||
DWORD dwMemMode;
|
||||
BOOL bLastWriteRam;
|
||||
BYTE nMemMain[nMemMainSize];
|
||||
BYTE nMemAux[nMemAuxSize];
|
||||
} SS_BaseMemory;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
struct SS_APPLE2_Unit
|
||||
{
|
||||
SS_UNIT_HDR UnitHdr;
|
||||
SS_CPU6502 CPU6502;
|
||||
SS_IO_Comms Comms;
|
||||
SS_IO_Joystick Joystick;
|
||||
SS_IO_Keyboard Keyboard;
|
||||
// SS_IO_Memory Memory;
|
||||
SS_IO_Speaker Speaker;
|
||||
SS_IO_Video Video;
|
||||
SS_BaseMemory Memory;
|
||||
} SS_APPLE2_Unit;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DWORD dwComputerEmulation;
|
||||
bool bCustomSpeed;
|
||||
DWORD dwEmulationSpeed;
|
||||
bool bEnhancedDiskSpeed;
|
||||
DWORD dwJoystickType[2];
|
||||
bool bMockingboardEnabled;
|
||||
DWORD dwMonochromeColor;
|
||||
DWORD dwSerialPort;
|
||||
DWORD dwSoundType; // Sound Emulation
|
||||
DWORD dwVideoType; // Video Emulation
|
||||
} SS_AW_CFG;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char StartingDir[MAX_PATH];
|
||||
DWORD dwWindowXpos;
|
||||
DWORD dwWindowYpos;
|
||||
} SS_AW_PREFS;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SS_UNIT_HDR UnitHdr;
|
||||
DWORD dwAppleWinVersion;
|
||||
SS_AW_PREFS Prefs;
|
||||
SS_AW_CFG Cfg;
|
||||
} SS_APPLEWIN_CONFIG;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SS_UNIT_HDR UnitHdr;
|
||||
DWORD dwType; // SS_CARDTYPE
|
||||
DWORD dwSlot; // [1..7]
|
||||
} SS_CARD_HDR;
|
||||
|
||||
enum SS_CARDTYPE
|
||||
{
|
||||
CT_Empty = 0,
|
||||
CT_Disk2, // Apple Disk][
|
||||
CT_SSC, // Apple Super Serial Card
|
||||
CT_MockingboardC, // Soundcard
|
||||
CT_GenericPrinter,
|
||||
CT_GenericHDD, // Hard disk
|
||||
CT_GenericClock,
|
||||
CT_MouseInterface,
|
||||
CT_Z80,
|
||||
CT_Phasor, // Soundcard
|
||||
CT_Echo, // Soundcard
|
||||
CT_SAM, // Soundcard: Software Automated Mouth
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SS_CARD_HDR Hdr;
|
||||
} SS_CARD_EMPTY;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct
|
||||
struct DISK2_Unit
|
||||
{
|
||||
char szFileName[MAX_PATH];
|
||||
int track;
|
||||
@ -180,9 +93,9 @@ typedef struct
|
||||
DWORD writelight;
|
||||
int nibbles;
|
||||
BYTE nTrack[NIBBLES_PER_TRACK];
|
||||
} DISK2_Unit;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
struct SS_CARD_DISK2
|
||||
{
|
||||
SS_CARD_HDR Hdr;
|
||||
DISK2_Unit Unit[2];
|
||||
@ -193,11 +106,11 @@ typedef struct
|
||||
BYTE floppylatch;
|
||||
BOOL floppymotoron;
|
||||
BOOL floppywritemode;
|
||||
} SS_CARD_DISK2;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct
|
||||
struct IWORD
|
||||
{
|
||||
union
|
||||
{
|
||||
@ -208,9 +121,9 @@ typedef struct
|
||||
};
|
||||
USHORT w;
|
||||
};
|
||||
} IWORD;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
struct SY6522
|
||||
{
|
||||
BYTE ORB; // $00 - Port B
|
||||
BYTE ORA; // $01 - Port A (with handshaking)
|
||||
@ -234,9 +147,9 @@ typedef struct
|
||||
BYTE IFR; // $0D - Interrupt Flag Register
|
||||
BYTE IER; // $0E - Interrupt Enable Register
|
||||
BYTE ORA_NO_HS; // $0F - Port A (without handshaking)
|
||||
} SY6522;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
struct SSI263A
|
||||
{
|
||||
BYTE DurationPhonome;
|
||||
BYTE Inflection; // I10..I3
|
||||
@ -245,9 +158,9 @@ typedef struct
|
||||
BYTE FilterFreq;
|
||||
//
|
||||
BYTE CurrentMode; // b7:6=Mode; b0=D7 pin (for IRQ)
|
||||
} SSI263A;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
struct MB_Unit
|
||||
{
|
||||
SY6522 RegsSY6522;
|
||||
BYTE RegsAY8910[16];
|
||||
@ -256,23 +169,22 @@ typedef struct
|
||||
bool bTimer1IrqPending;
|
||||
bool bTimer2IrqPending;
|
||||
bool bSpeechIrqPending;
|
||||
} MB_Unit;
|
||||
};
|
||||
|
||||
const UINT MB_UNITS_PER_CARD = 2;
|
||||
|
||||
typedef struct
|
||||
struct SS_CARD_MOCKINGBOARD
|
||||
{
|
||||
SS_CARD_HDR Hdr;
|
||||
MB_Unit Unit[MB_UNITS_PER_CARD];
|
||||
} SS_CARD_MOCKINGBOARD;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct
|
||||
struct APPLEWIN_SNAPSHOT_v1
|
||||
{
|
||||
SS_FILE_HDR Hdr;
|
||||
SS_APPLE2_Unit Apple2Unit;
|
||||
// SS_APPLEWIN_CONFIG AppleWinCfg;
|
||||
SS_CARD_EMPTY Empty1; // Slot1
|
||||
SS_CARD_EMPTY Empty2; // Slot2
|
||||
SS_CARD_EMPTY Empty3; // Slot3
|
||||
@ -280,6 +192,6 @@ typedef struct
|
||||
SS_CARD_MOCKINGBOARD Mockingboard2; // Slot5
|
||||
SS_CARD_DISK2 Disk2; // Slot6
|
||||
SS_CARD_EMPTY Empty7; // Slot7
|
||||
} APPLEWIN_SNAPSHOT;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
const UINT kSnapshotSize_v1 = 145400; // Const size for v1
|
114
source/SaveState_Structs_v2.h
Normal file
114
source/SaveState_Structs_v2.h
Normal file
@ -0,0 +1,114 @@
|
||||
#pragma once
|
||||
|
||||
#include "SaveState_Structs_common.h"
|
||||
|
||||
// Structs used by save-state file v2
|
||||
|
||||
// *** DON'T CHANGE ANY STRUCT WITHOUT CONSIDERING BACKWARDS COMPATIBILITY WITH .AWS FORMAT ***
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct SS_CPU6502_v2
|
||||
{
|
||||
BYTE A;
|
||||
BYTE X;
|
||||
BYTE Y;
|
||||
BYTE P;
|
||||
BYTE S;
|
||||
USHORT PC;
|
||||
unsigned __int64 CumulativeCycles;
|
||||
// IRQ = OR-sum of all interrupt sources
|
||||
};
|
||||
|
||||
struct SS_IO_Joystick_v2
|
||||
{
|
||||
unsigned __int64 JoyCntrResetCycle;
|
||||
};
|
||||
|
||||
struct SS_IO_Keyboard_v2
|
||||
{
|
||||
BYTE LastKey;
|
||||
};
|
||||
|
||||
struct SS_IO_Speaker_v2
|
||||
{
|
||||
unsigned __int64 SpkrLastCycle;
|
||||
};
|
||||
|
||||
struct SS_IO_Video_v2
|
||||
{
|
||||
UINT32 AltCharSet;
|
||||
UINT32 VideoMode;
|
||||
UINT32 CyclesThisVideoFrame;
|
||||
};
|
||||
|
||||
struct SS_BaseMemory_v2
|
||||
{
|
||||
DWORD dwMemMode;
|
||||
BOOL bLastWriteRam;
|
||||
BYTE MemMain[nMemMainSize];
|
||||
BYTE MemAux[nMemAuxSize];
|
||||
};
|
||||
|
||||
struct SS_APPLE2_Unit_v2
|
||||
{
|
||||
SS_UNIT_HDR UnitHdr;
|
||||
UINT32 Apple2Type;
|
||||
SS_CPU6502_v2 CPU6502;
|
||||
SS_IO_Joystick_v2 Joystick;
|
||||
SS_IO_Keyboard_v2 Keyboard;
|
||||
SS_IO_Speaker_v2 Speaker;
|
||||
SS_IO_Video_v2 Video;
|
||||
SS_BaseMemory_v2 Memory;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma pack(push,4) // push current alignment to stack & set alignment to 4
|
||||
// - need so that 12-byte Hdr doesn't get padded to 16 bytes
|
||||
// - NB. take care not to affect the old v2 structs
|
||||
|
||||
struct APPLEWIN_SNAPSHOT_v2
|
||||
{
|
||||
SS_FILE_HDR Hdr;
|
||||
SS_APPLE2_Unit_v2 Apple2Unit;
|
||||
// SS_CARD_EMPTY[7] Slots; // Slot 0..7 (0=language card for Apple][)
|
||||
// SS_CARD_EMPTY AuxSlot; // Apple//e auxiliary slot (including optional RAMworks memory)
|
||||
// SS_APPLEWIN_CONFIG AppleWinCfg;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct SS_AW_CFG
|
||||
{
|
||||
UINT32 AppleWinVersion;
|
||||
UINT32 VideoMode;
|
||||
UINT32 MonochromeColor;
|
||||
float ClockFreqMHz;
|
||||
//
|
||||
UINT32 JoystickType[2];
|
||||
UINT32 JoystickTrim[2];
|
||||
UINT32 IsAllowCursorsToBeRead;
|
||||
UINT32 IsAutofire;
|
||||
UINT32 IsKeyboardAutocentering;
|
||||
UINT32 IsSwapButton0and1;
|
||||
//
|
||||
UINT32 SpeakerVolume;
|
||||
UINT32 MockingboardVolume;
|
||||
//
|
||||
UINT32 IsEnhancedDiskSpeed;
|
||||
//
|
||||
UINT32 IsEncodingConversionForClones;
|
||||
UINT32 IsFilterUnprintableChars;
|
||||
UINT32 IsAppendToFile;
|
||||
UINT32 TerminatePrintingAfterIdleSecs;
|
||||
UINT32 IsUsingFreezesF8Rom;
|
||||
};
|
||||
|
||||
struct SS_APPLEWIN_CONFIG
|
||||
{
|
||||
SS_UNIT_HDR UnitHdr;
|
||||
SS_AW_CFG Cfg;
|
||||
};
|
@ -72,7 +72,8 @@ SSC_DIPSW CSuperSerialCard::m_DIPSWDefault =
|
||||
|
||||
CSuperSerialCard::CSuperSerialCard() :
|
||||
m_aySerialPortChoices(NULL),
|
||||
m_uTCPChoiceItemIdx(0)
|
||||
m_uTCPChoiceItemIdx(0),
|
||||
m_uSlot(0)
|
||||
{
|
||||
memset(m_ayCurrentSerialPortName, 0, sizeof(m_ayCurrentSerialPortName));
|
||||
m_dwSerialPortItem = 0;
|
||||
@ -831,6 +832,8 @@ void CSuperSerialCard::CommInitialize(LPBYTE pCxRomPeripheral, UINT uSlot)
|
||||
|
||||
memcpy(pCxRomPeripheral + uSlot*256, pData+SSC_SLOT_FW_OFFSET, SSC_SLOT_FW_SIZE);
|
||||
|
||||
m_uSlot = uSlot;
|
||||
|
||||
// Expansion ROM
|
||||
if (m_pExpansionRom == NULL)
|
||||
{
|
||||
@ -1293,30 +1296,144 @@ void CSuperSerialCard::SetSerialPortName(const char* pSerialPortName)
|
||||
|
||||
//===========================================================================
|
||||
|
||||
DWORD CSuperSerialCard::CommGetSnapshot(SS_IO_Comms* pSS)
|
||||
void CSuperSerialCard::SetSnapshot_v1( const DWORD baudrate,
|
||||
const BYTE bytesize,
|
||||
const BYTE commandbyte,
|
||||
const DWORD comminactivity,
|
||||
const BYTE controlbyte,
|
||||
const BYTE parity,
|
||||
const BYTE stopbits)
|
||||
{
|
||||
pSS->baudrate = m_uBaudRate;
|
||||
pSS->bytesize = m_uByteSize;
|
||||
pSS->commandbyte = m_uCommandByte;
|
||||
pSS->comminactivity = m_dwCommInactivity;
|
||||
pSS->controlbyte = m_uControlByte;
|
||||
pSS->parity = m_uParity;
|
||||
// memcpy(pSS->recvbuffer, m_RecvBuffer, uRecvBufferSize);
|
||||
pSS->recvbytes = 0;
|
||||
pSS->stopbits = m_uStopBits;
|
||||
return 0;
|
||||
m_uBaudRate = baudrate;
|
||||
m_uByteSize = bytesize;
|
||||
m_uCommandByte = commandbyte;
|
||||
m_dwCommInactivity = comminactivity;
|
||||
m_uControlByte = controlbyte;
|
||||
m_uParity = parity;
|
||||
// memcpy(m_RecvBuffer, pSS->recvbuffer, uRecvBufferSize);
|
||||
// m_vRecvBytes = recvbytes;
|
||||
m_uStopBits = stopbits;
|
||||
}
|
||||
|
||||
DWORD CSuperSerialCard::CommSetSnapshot(SS_IO_Comms* pSS)
|
||||
//===========================================================================
|
||||
|
||||
struct SSC_Unit
|
||||
{
|
||||
m_uBaudRate = pSS->baudrate;
|
||||
m_uByteSize = pSS->bytesize;
|
||||
m_uCommandByte = pSS->commandbyte;
|
||||
m_dwCommInactivity = pSS->comminactivity;
|
||||
m_uControlByte = pSS->controlbyte;
|
||||
m_uParity = pSS->parity;
|
||||
// memcpy(m_RecvBuffer, pSS->recvbuffer, uRecvBufferSize);
|
||||
// m_vRecvBytes = pSS->recvbytes;
|
||||
m_uStopBits = pSS->stopbits;
|
||||
SSC_DIPSW DIPSWDefault;
|
||||
SSC_DIPSW DIPSWCurrent;
|
||||
|
||||
DWORD uBaudRate;
|
||||
|
||||
BYTE uStopBits;
|
||||
BYTE uByteSize;
|
||||
BYTE uParity;
|
||||
|
||||
BYTE uControlByte;
|
||||
BYTE uCommandByte;
|
||||
|
||||
DWORD dwCommInactivity; // If non-zero then COM port open
|
||||
|
||||
bool bTxIrqEnabled;
|
||||
bool bRxIrqEnabled;
|
||||
|
||||
bool vbTxIrqPending;
|
||||
bool vbRxIrqPending;
|
||||
|
||||
bool bWrittenTx;
|
||||
};
|
||||
|
||||
struct SS_CARD_SSC
|
||||
{
|
||||
SS_CARD_HDR Hdr;
|
||||
SSC_Unit Unit;
|
||||
};
|
||||
|
||||
// Post:
|
||||
// 0 = No card
|
||||
// >0 = Card saved OK from slot n
|
||||
// -1 = File error
|
||||
int CSuperSerialCard::GetSnapshot(const HANDLE hFile)
|
||||
{
|
||||
SS_CARD_SSC CardSuperSerial;
|
||||
|
||||
CardSuperSerial.Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_SSC);
|
||||
CardSuperSerial.Hdr.UnitHdr.hdr.v2.Type = UT_Card;
|
||||
CardSuperSerial.Hdr.UnitHdr.hdr.v2.Version = 1;
|
||||
|
||||
CardSuperSerial.Hdr.Slot = m_uSlot;
|
||||
CardSuperSerial.Hdr.Type = CT_SSC;
|
||||
|
||||
SSC_Unit& Unit = CardSuperSerial.Unit;
|
||||
|
||||
Unit.DIPSWDefault = m_DIPSWDefault;
|
||||
Unit.DIPSWCurrent = m_DIPSWCurrent;
|
||||
Unit.uBaudRate = m_uBaudRate;
|
||||
Unit.uStopBits = m_uStopBits;
|
||||
Unit.uByteSize = m_uByteSize;
|
||||
Unit.uParity = m_uParity;
|
||||
Unit.uControlByte = m_uControlByte;
|
||||
Unit.uCommandByte = m_uCommandByte;
|
||||
Unit.dwCommInactivity = m_dwCommInactivity;
|
||||
Unit.bTxIrqEnabled = m_bTxIrqEnabled;
|
||||
Unit.bRxIrqEnabled = m_bRxIrqEnabled;
|
||||
Unit.vbTxIrqPending = m_vbTxIrqPending;
|
||||
Unit.vbRxIrqPending = m_vbRxIrqPending;
|
||||
Unit.bWrittenTx = m_bWrittenTx;
|
||||
|
||||
//
|
||||
|
||||
DWORD dwBytesWritten;
|
||||
BOOL bRes = WriteFile( hFile,
|
||||
&CardSuperSerial,
|
||||
CardSuperSerial.Hdr.UnitHdr.hdr.v2.Length,
|
||||
&dwBytesWritten,
|
||||
NULL);
|
||||
|
||||
if(!bRes || (dwBytesWritten != CardSuperSerial.Hdr.UnitHdr.hdr.v2.Length))
|
||||
throw std::string("Save error: SSC");
|
||||
|
||||
return m_uSlot;
|
||||
}
|
||||
|
||||
int CSuperSerialCard::SetSnapshot(const HANDLE hFile)
|
||||
{
|
||||
SS_CARD_SSC CardSuperSerial;
|
||||
|
||||
DWORD dwBytesRead;
|
||||
BOOL bRes = ReadFile( hFile,
|
||||
&CardSuperSerial,
|
||||
sizeof(CardSuperSerial),
|
||||
&dwBytesRead,
|
||||
NULL);
|
||||
|
||||
if (dwBytesRead != sizeof(CardSuperSerial))
|
||||
throw std::string("Card: file corrupt");
|
||||
|
||||
if (CardSuperSerial.Hdr.Slot != 2) // fixme
|
||||
throw std::string("Card: wrong slot");
|
||||
|
||||
if (CardSuperSerial.Hdr.UnitHdr.hdr.v2.Version != 1)
|
||||
throw std::string("Card: wrong version");
|
||||
|
||||
if (CardSuperSerial.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_SSC))
|
||||
throw std::string("Card: unit size mismatch");
|
||||
|
||||
SSC_Unit& Unit = CardSuperSerial.Unit;
|
||||
|
||||
m_DIPSWDefault = Unit.DIPSWDefault;
|
||||
m_DIPSWCurrent = Unit.DIPSWCurrent;
|
||||
m_uBaudRate = Unit.uBaudRate;
|
||||
m_uStopBits = Unit.uStopBits;
|
||||
m_uByteSize = Unit.uByteSize;
|
||||
m_uParity = Unit.uParity;
|
||||
m_uControlByte = Unit.uControlByte;
|
||||
m_uCommandByte = Unit.uCommandByte;
|
||||
m_dwCommInactivity = Unit.dwCommInactivity;
|
||||
m_bTxIrqEnabled = Unit.bTxIrqEnabled;
|
||||
m_bRxIrqEnabled = Unit.bRxIrqEnabled;
|
||||
m_vbTxIrqPending = Unit.vbTxIrqPending;
|
||||
m_vbRxIrqPending = Unit.vbRxIrqPending;
|
||||
m_bWrittenTx = Unit.bWrittenTx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -33,8 +33,9 @@ public:
|
||||
void CommDestroy();
|
||||
void CommSetSerialPort(HWND hWindow, DWORD dwNewSerialPortItem);
|
||||
void CommUpdate(DWORD);
|
||||
DWORD CommGetSnapshot(SS_IO_Comms* pSS);
|
||||
DWORD CommSetSnapshot(SS_IO_Comms* pSS);
|
||||
void SetSnapshot_v1(const DWORD baudrate, const BYTE bytesize, const BYTE commandbyte, const DWORD comminactivity, const BYTE controlbyte, const BYTE parity, const BYTE stopbits);
|
||||
int GetSnapshot(const HANDLE hFile);
|
||||
int SetSnapshot(const HANDLE hFile);
|
||||
|
||||
char* GetSerialPortChoices();
|
||||
DWORD GetSerialPort() { return m_dwSerialPortItem; } // Drop-down list item
|
||||
@ -134,4 +135,5 @@ private:
|
||||
OVERLAPPED m_o;
|
||||
|
||||
BYTE* m_pExpansionRom;
|
||||
UINT m_uSlot;
|
||||
};
|
||||
|
@ -1080,14 +1080,19 @@ void Spkr_DSUninit()
|
||||
|
||||
//=============================================================================
|
||||
|
||||
DWORD SpkrGetSnapshot(SS_IO_Speaker* pSS)
|
||||
void SpkrSetSnapshot_v1(const unsigned __int64 SpkrLastCycle)
|
||||
{
|
||||
pSS->g_nSpkrLastCycle = g_nSpkrLastCycle;
|
||||
return 0;
|
||||
g_nSpkrLastCycle = SpkrLastCycle;
|
||||
}
|
||||
|
||||
DWORD SpkrSetSnapshot(SS_IO_Speaker* pSS)
|
||||
//
|
||||
|
||||
void SpkrGetSnapshot(unsigned __int64& rSpkrLastCycle)
|
||||
{
|
||||
g_nSpkrLastCycle = pSS->g_nSpkrLastCycle;
|
||||
return 0;
|
||||
rSpkrLastCycle = g_nSpkrLastCycle;
|
||||
}
|
||||
|
||||
void SpkrSetSnapshot(const unsigned __int64 SpkrLastCycle)
|
||||
{
|
||||
g_nSpkrLastCycle = SpkrLastCycle;
|
||||
}
|
||||
|
@ -19,7 +19,8 @@ void Spkr_Demute();
|
||||
bool Spkr_IsActive();
|
||||
bool Spkr_DSInit();
|
||||
void Spkr_DSUninit();
|
||||
DWORD SpkrGetSnapshot(SS_IO_Speaker* pSS);
|
||||
DWORD SpkrSetSnapshot(SS_IO_Speaker* pSS);
|
||||
void SpkrSetSnapshot_v1(const unsigned __int64 SpkrLastCycle);
|
||||
void SpkrGetSnapshot(unsigned __int64& rSpkrLastCycle);
|
||||
void SpkrSetSnapshot(const unsigned __int64 SpkrLastCycle);
|
||||
|
||||
BYTE __stdcall SpkrToggle (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <windows.h>
|
||||
@ -36,6 +35,7 @@
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// SM_CXPADDEDBORDER is not supported on 2000 & XP:
|
||||
|
@ -39,6 +39,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "..\resource\resource.h"
|
||||
#include "Configuration\PropertySheet.h"
|
||||
#include "Debugger\Debugger_Color.h" // For NUM_DEBUG_COLORS
|
||||
#include "SaveState_Structs_v2.h"
|
||||
|
||||
#define HALF_PIXEL_SOLID 1
|
||||
#define HALF_PIXEL_BLEED 0
|
||||
@ -2941,20 +2942,26 @@ void VideoSetForceFullRedraw(void)
|
||||
|
||||
//===========================================================================
|
||||
|
||||
DWORD VideoGetSnapshot(SS_IO_Video* pSS)
|
||||
void VideoSetSnapshot_v1(const UINT AltCharSet, const UINT VideoMode)
|
||||
{
|
||||
pSS->bAltCharSet = !(g_nAltCharSetOffset == 0);
|
||||
pSS->dwVidMode = g_uVideoMode;
|
||||
return 0;
|
||||
g_nAltCharSetOffset = !AltCharSet ? 0 : 256;
|
||||
g_uVideoMode = VideoMode;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
||||
DWORD VideoSetSnapshot(SS_IO_Video* pSS)
|
||||
void VideoGetSnapshot(SS_IO_Video_v2& Video)
|
||||
{
|
||||
g_nAltCharSetOffset = !pSS->bAltCharSet ? 0 : 256;
|
||||
g_uVideoMode = pSS->dwVidMode;
|
||||
return 0;
|
||||
Video.AltCharSet = !(g_nAltCharSetOffset == 0);
|
||||
Video.VideoMode = g_uVideoMode;
|
||||
Video.CyclesThisVideoFrame = g_dwCyclesThisFrame;
|
||||
}
|
||||
|
||||
void VideoSetSnapshot(const SS_IO_Video_v2& Video)
|
||||
{
|
||||
g_nAltCharSetOffset = !Video.AltCharSet ? 0 : 256;
|
||||
g_uVideoMode = Video.VideoMode;
|
||||
g_dwCyclesThisFrame = Video.CyclesThisVideoFrame;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -85,8 +85,9 @@ bool VideoGetSWAltCharSet(void);
|
||||
|
||||
void VideoSetForceFullRedraw(void);
|
||||
|
||||
DWORD VideoGetSnapshot(SS_IO_Video* pSS);
|
||||
DWORD VideoSetSnapshot(SS_IO_Video* pSS);
|
||||
void VideoSetSnapshot_v1(const UINT AltCharSet, const UINT VideoMode);
|
||||
void VideoGetSnapshot(struct SS_IO_Video_v2& Video);
|
||||
void VideoSetSnapshot(const struct SS_IO_Video_v2& Video);
|
||||
|
||||
void _Video_Dirty();
|
||||
void _Video_RedrawScreen( VideoUpdateFuncPtr_t update, bool bMixed = false );
|
||||
|
Loading…
x
Reference in New Issue
Block a user