Support Uthernet save-state (#984)

Uthernet card: support save/load state
This commit is contained in:
TomCh 2021-09-21 21:32:14 +01:00 committed by GitHub
parent 10a83eed61
commit 4aa6e05528
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 143 additions and 49 deletions

View File

@ -334,10 +334,7 @@ void CPropertySheetHelper::ApplyNewConfig(const CConfigNeedingRestart& ConfigNew
SetSlot(slot, ConfigNew.m_Slot[slot]);
if (ConfigNew.m_Slot[slot] == CT_Uthernet) // TODO: move this to UthernetCard object
{
std::string& regSection = RegGetConfigSlotSection(slot);
RegSaveString(regSection.c_str(), REGVALUE_UTHERNET_INTERFACE, 1, ConfigNew.m_tfeInterface);
}
tfe_SetRegistryInterface(slot, ConfigNew.m_tfeInterface);
}
slot = SLOT4;

View File

@ -54,6 +54,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "SerialComms.h"
#include "Speaker.h"
#include "Tape.h"
#include "tfe/tfe.h"
#include "RGBMonitor.h"
#include "z80emu.h"
@ -1727,7 +1728,7 @@ void MemInitializeIO(void)
{
// Slot 3 contains the Uthernet card (which can coexist with an 80-col+Ram card in AUX slot)
// . Uthernet card has no ROM and only IO mapped at $C0Bx
// NB. I/O handlers setup via tfe_init() & update_tfe_interface()
tfe_InitializeIO(pCxRomPeripheral, SLOT3);
}
else if (GetCardMgr().QuerySlot(SLOT3) == CT_FourPlay)
{

View File

@ -380,6 +380,12 @@ static void ParseSlots(YamlLoadHelper& yamlLoadHelper, UINT unitVersion)
GetCardMgr().Insert(slot, type);
bRes = HD_LoadSnapshot(yamlLoadHelper, slot, cardVersion, g_strSaveStatePath);
}
else if (card == tfe_GetSnapshotCardName())
{
type = CT_Uthernet;
GetCardMgr().Insert(slot, type);
tfe_LoadSnapshot(yamlLoadHelper, slot, cardVersion);
}
else if (card == LanguageCardSlot0::GetSnapshotCardName())
{
type = CT_LanguageCard;
@ -612,8 +618,8 @@ void Snapshot_SaveState(void)
if (GetCardMgr().QuerySlot(SLOT2) == CT_SSC)
dynamic_cast<CSuperSerialCard&>(GetCardMgr().GetRef(SLOT2)).SaveSnapshot(yamlSaveHelper);
// if (GetCardMgr().QuerySlot(SLOT3) == CT_Uthernet)
// sg_Uthernet.SaveSnapshot(yamlSaveHelper);
if (GetCardMgr().QuerySlot(SLOT3) == CT_Uthernet)
tfe_SaveSnapshot(yamlSaveHelper);
if (GetCardMgr().QuerySlot(SLOT4) == CT_MouseInterface)
dynamic_cast<CMouseInterface&>(GetCardMgr().GetRef(SLOT4)).SaveSnapshot(yamlSaveHelper);

View File

@ -45,6 +45,10 @@ typedef unsigned int UINT;
#include "../Common.h" // For: IS_APPLE2
#include "../Memory.h"
#include "../Registry.h"
#include "../YamlHelper.h"
static UINT g_slot = SLOT3;
/**/
/** #define TFE_DEBUG_DUMP 1 **/
@ -60,8 +64,6 @@ typedef unsigned int UINT;
/* ------------------------------------------------------------------------- */
/* variables needed */
static int init_tfe_flag = 0;
/* status which received packages to accept
This is used in tfe_should_accept().
*/
@ -446,9 +448,6 @@ void tfe_reset(void)
TFE_DEBUG_OUTPUT_REG();
}
const UINT uSlot = 3;
RegisterIoHandler(uSlot, TfeIo, TfeIo, TfeIoCxxx, TfeIoCxxx, NULL, NULL);
}
#ifdef DOS_TFE
@ -557,6 +556,8 @@ int tfe_deactivate(void) {
void tfe_init(void)
{
tfe_enabled = 1;
if (!tfe_arch_init()) {
tfe_enabled = 0;
tfe_cannot_use = 1;
@ -1329,14 +1330,17 @@ void REGPARM2 tfe_store(WORD ioaddress, BYTE byte)
#if 0
static
int set_tfe_disabled(void *v, void *param)
{
/* dummy function since we don't want "disabled" to be stored on disk */
return 0;
}
#endif
#if 0
static
int set_tfe_enabled(void *v, void *param)
{
@ -1375,6 +1379,7 @@ int set_tfe_enabled(void *v, void *param)
}
return 0;
}
#endif
static
@ -1413,29 +1418,6 @@ int set_tfe_interface(const std::string & name)
//}
/* ------------------------------------------------------------------------- */
/* snapshot support functions */
#if 0
static char snap_module_name[] = "TFE1764";
#define SNAP_MAJOR 0
#define SNAP_MINOR 0
int tfe_read_snapshot_module(struct snapshot_s *s)
{
/* @SRT TODO: not yet implemented */
return -1;
}
int tfe_write_snapshot_module(struct snapshot_s *s)
{
/* @SRT TODO: not yet implemented */
return -1;
}
#endif /* #if 0 */
/* ------------------------------------------------------------------------- */
/* functions for selecting and querying available NICs */
@ -1498,6 +1480,12 @@ return ret;
}
void tfe_InitializeIO(LPBYTE pCxRomPeripheral, UINT slot)
{
g_slot = slot;
RegisterIoHandler(slot, TfeIo, TfeIo, TfeIoCxxx, TfeIoCxxx, NULL, NULL);
}
void get_disabled_state(int * param)
{
*param = tfe_cannot_use;
@ -1518,4 +1506,105 @@ int get_tfe_enabled(void)
return tfe_enabled;
}
// Called by: tfe_LoadSnapshot() & ApplyNewConfig()
void tfe_SetRegistryInterface(UINT slot, const std::string& name)
{
std::string& regSection = RegGetConfigSlotSection(slot);
RegSaveString(regSection.c_str(), REGVALUE_UTHERNET_INTERFACE, 1, name);
}
/* ------------------------------------------------------------------------- */
/* snapshot support functions */
#define SS_YAML_KEY_ENABLED "Enabled"
#define SS_YAML_KEY_NETWORK_INTERFACE "Network Interface"
#define SS_YAML_KEY_STARTED_TX "Started Tx"
#define SS_YAML_KEY_CANNOT_USE "Cannot Use"
#define SS_YAML_KEY_TXCOLLECT_BUFFER "Tx Collect Buffer"
#define SS_YAML_KEY_RX_BUFFER "Rx Buffer"
#define SS_YAML_KEY_CS8900A_REGS "CS8900A Registers"
#define SS_YAML_KEY_PACKETPAGE_REGS "PacketPage Registers"
static const UINT kUNIT_VERSION = 1;
std::string tfe_GetSnapshotCardName(void)
{
static const std::string name("Uthernet");
return name;
}
void tfe_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper)
{
YamlSaveHelper::Slot slot(yamlSaveHelper, tfe_GetSnapshotCardName(), g_slot, kUNIT_VERSION);
YamlSaveHelper::Label unit(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
yamlSaveHelper.SaveBool(SS_YAML_KEY_ENABLED, tfe_enabled ? true : false);
yamlSaveHelper.SaveString(SS_YAML_KEY_NETWORK_INTERFACE, get_tfe_interface());
yamlSaveHelper.SaveBool(SS_YAML_KEY_STARTED_TX, tfe_started_tx ? true : false);
yamlSaveHelper.SaveBool(SS_YAML_KEY_CANNOT_USE, tfe_cannot_use ? true : false);
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_TXCOLLECT_BUFFER, txcollect_buffer);
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_RX_BUFFER, rx_buffer);
{
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_CS8900A_REGS);
yamlSaveHelper.SaveMemory(tfe, TFE_COUNT_IO_REGISTER);
}
{
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_PACKETPAGE_REGS);
yamlSaveHelper.SaveMemory(tfe_packetpage, MAX_PACKETPAGE_ARRAY);
}
}
bool tfe_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version)
{
if (slot != SLOT3) // fixme
throw std::string("Card: wrong slot");
if (version < 1 || version > kUNIT_VERSION)
throw std::string("Card: wrong version");
tfe_enabled = yamlLoadHelper.LoadBool(SS_YAML_KEY_ENABLED) ? true : false;
set_tfe_interface(yamlLoadHelper.LoadStringA(SS_YAML_KEY_NETWORK_INTERFACE));
tfe_started_tx = yamlLoadHelper.LoadBool(SS_YAML_KEY_STARTED_TX) ? true : false;
tfe_cannot_use = yamlLoadHelper.LoadBool(SS_YAML_KEY_CANNOT_USE) ? true : false;
txcollect_buffer = yamlLoadHelper.LoadUint(SS_YAML_KEY_TXCOLLECT_BUFFER);
rx_buffer = yamlLoadHelper.LoadUint(SS_YAML_KEY_RX_BUFFER);
if (!yamlLoadHelper.GetSubMap(SS_YAML_KEY_CS8900A_REGS))
throw std::string("Card: Expected key: ") + SS_YAML_KEY_CS8900A_REGS;
memset(tfe, 0, TFE_COUNT_IO_REGISTER);
yamlLoadHelper.LoadMemory(tfe, TFE_COUNT_IO_REGISTER);
yamlLoadHelper.PopMap();
if (!yamlLoadHelper.GetSubMap(SS_YAML_KEY_PACKETPAGE_REGS))
throw std::string("Card: Expected key: ") + SS_YAML_KEY_PACKETPAGE_REGS;
memset(tfe_packetpage, 0, MAX_PACKETPAGE_ARRAY);
yamlLoadHelper.LoadMemory(tfe_packetpage, MAX_PACKETPAGE_ARRAY);
yamlLoadHelper.PopMap();
// Side effects after PackagePage has been loaded
tfe_sideeffects_write_pp(TFE_PP_ADDR_CC_RXCTL, 0); // set the 6 tfe_recv_* vars
for (UINT i = 0; i < 8; i++)
tfe_sideeffects_write_pp((TFE_PP_ADDR_LOG_ADDR_FILTER + i) & ~1, i & 1); // set tfe_hash_mask
for (UINT i = 0; i < 6; i++)
tfe_sideeffects_write_pp((TFE_PP_ADDR_MAC_ADDR + i) & ~1, i & 1); // set tfe_ia_mac
//
tfe_SetRegistryInterface(slot, get_tfe_interface());
return true;
}
//#endif /* #ifdef HAVE_TFE */

View File

@ -37,8 +37,6 @@
*/
/** #define TFE_DEBUG_FRAMES **/
struct snapshot_s;
extern int tfe_enabled;
extern void tfe_init(void);
@ -51,8 +49,12 @@ extern void tfe_reset(void);
extern void tfe_shutdown(void);
extern BYTE REGPARM1 tfe_read(WORD addr);
extern void REGPARM2 tfe_store(WORD addr, BYTE byte);
extern int tfe_read_snapshot_module(struct snapshot_s *s);
extern int tfe_write_snapshot_module(struct snapshot_s *s);
void tfe_InitializeIO(LPBYTE pCxRomPeripheral, UINT slot);
void tfe_SetRegistryInterface(UINT slot, const std::string& name);
std::string tfe_GetSnapshotCardName(void);
void tfe_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
bool tfe_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version);
/*
These functions let the UI enumerate the available interfaces.

View File

@ -256,17 +256,15 @@ void LoadConfiguration(void)
if (slot == SLOT3)
{
tfe_enabled = 0;
if ((SS_CARDTYPE)dwTmp == CT_Uthernet) // TODO: move this to when UthernetCard object is instantiated
{
tfe_enabled = 1;
std::string& regSection = RegGetConfigSlotSection(slot);
if (RegLoadString(regSection.c_str(), REGVALUE_UTHERNET_INTERFACE, TRUE, szFilename, MAX_PATH, TEXT("")))
update_tfe_interface(szFilename);
}
else
{
tfe_enabled = 0;
tfe_init();
}
}
else if (slot == SLOT7)
@ -279,15 +277,19 @@ void LoadConfiguration(void)
{
if (slot == SLOT3)
{
tfe_enabled = 0;
DWORD tfeEnabled;
REGLOAD_DEFAULT(TEXT(REGVALUE_UTHERNET_ACTIVE), &tfeEnabled, 0);
tfe_enabled = tfeEnabled ? 1 : 0;
GetCardMgr().Insert(SLOT3, get_tfe_enabled() ? CT_Uthernet : CT_Empty);
// TODO: move this to when UthernetCard object is instantiated
RegLoadString(TEXT(REG_CONFIG), TEXT(REGVALUE_UTHERNET_INTERFACE), 1, szFilename, MAX_PATH, TEXT(""));
update_tfe_interface(szFilename);
if (tfeEnabled)
tfe_init();
}
else if (slot == SLOT4 && REGLOAD(TEXT(REGVALUE_SLOT4), &dwTmp))
GetCardMgr().Insert(SLOT4, (SS_CARDTYPE)dwTmp);

View File

@ -841,9 +841,6 @@ static void RepeatInitialization(void)
g_cmdLine.bShutdown = true;
}
tfe_init();
LogFileOutput("Main: tfe_init()\n");
if (g_cmdLine.szSnapshotName)
{
std::string strPathname(g_cmdLine.szSnapshotName);