All 3 RoboCom interface modules working

This commit is contained in:
tomcw 2023-07-15 22:21:26 +01:00
parent a62beeac1e
commit 3612d47bf3
4 changed files with 107 additions and 11 deletions

View File

@ -47,7 +47,10 @@ const TCHAR CPageAdvanced::m_CloneChoices[] =
const TCHAR CPageAdvanced::m_gameIOConnectorChoices[] =
"Empty\0"
"SDS DataKey - SpeedStar\0" /* Protection dongle for Southwestern Data Systems "SpeedStar" Applesoft Compiler */
"Cortechs Corp - CodeWriter\0"; /* Protection key for Dynatech Microsoftware / Cortechs Corp "CodeWriter" */
"Cortechs Corp - CodeWriter\0" /* Protection key for Dynatech Microsoftware / Cortechs Corp "CodeWriter" */
"Robocom - Robo 500\0" /* Interface Module for Robocom 500 */
"Robocom - Robo 1000\0" /* Interface Module for Robocom 1000 */
"Robocom - Robo 1500\0"; /* Interface Module for Robocom 1500 */
INT_PTR CALLBACK CPageAdvanced::DlgProc(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)

View File

@ -28,6 +28,7 @@
Currently supported:
- Southwestern Data Systems DataKey for SpeedStar Applesoft Compiler (Matthew D'Asaro Dec 2022)
- Dynatech Microsoftware / Cortechs Corp protection key for "CodeWriter"
- Robocom Ltd's Interface Module for Robo Graphics' BitStik
*/
#include "StdAfx.h"
#include <sstream>
@ -41,12 +42,12 @@ static DONGLETYPE copyProtectionDongleType = DT_EMPTY;
static const BYTE codewriterInitialLFSR = 0x6B; // %1101011 (7-bit LFSR)
static BYTE codewriterLFSR = codewriterInitialLFSR;
static void codeWriterResetLFSR()
static void CodeWriterResetLFSR()
{
codewriterLFSR = codewriterInitialLFSR;
}
static void codeWriterClockLFSR()
static void CodeWriterClockLFSR()
{
BYTE bit = ((codewriterLFSR >> 1) ^ (codewriterLFSR >> 0)) & 1;
codewriterLFSR = (codewriterLFSR >> 1) | (bit << 6);
@ -73,9 +74,9 @@ void DongleControl(WORD address)
if (copyProtectionDongleType == DT_CODEWRITER)
{
if ((AN == 3 && state == true) || MemGetAnnunciator(3)) // reset or was already reset? (ie. takes precedent over AN2)
codeWriterResetLFSR();
CodeWriterResetLFSR();
else if (AN == 2 && state == false && MemGetAnnunciator(2) == true) // AN2 true->false edge?
codeWriterClockLFSR();
CodeWriterClockLFSR();
}
}
@ -111,10 +112,39 @@ int CopyProtectionDonglePB2(void)
default:
return -1;
break;
}
}
// Returns the copy protection dongle state of PDL(n). A return value of -1 means not used by copy protection dongle
int CopyProtectionDonglePDL(UINT pdl)
{
bool roboComInterfaceModulePower = !MemGetAnnunciator(3);
if (!roboComInterfaceModulePower || pdl != 3)
return -1;
UINT roboComInterfaceModuleMode = ((UINT)MemGetAnnunciator(2) << 2) | ((UINT)MemGetAnnunciator(1) << 1) | (UINT)MemGetAnnunciator(0);
if (copyProtectionDongleType == DT_ROBOCOM500)
{
static BYTE robo500[8] = { 0x3F,0x2E,0x54,0x54,0x2E,0x22,0x72,0x17 }; // lower bound
return robo500[roboComInterfaceModuleMode] + 1;
}
if (copyProtectionDongleType == DT_ROBOCOM1000)
{
static BYTE robo1000[8] = { 0x17,0x72,0x22,0x2E,0x54,0x54,0x2E,0x3F }; // lower bound
return robo1000[roboComInterfaceModuleMode] + 1;
}
if (copyProtectionDongleType == DT_ROBOCOM1500)
{
static BYTE robo1500[8] = { 0x72,0x17,0x2E,0x17,0x22,0x3F,0x54,0x22 }; // lower bound
return robo1500[roboComInterfaceModuleMode] + 1;
}
return -1;
}
//===========================================================================
#define SS_YAML_KEY_CODEWRITER_INDEX "LFSR"
@ -122,6 +152,7 @@ int CopyProtectionDonglePB2(void)
// Unit version history:
// 1: Add SDS SpeedStar dongle
// 2: Add Cortechs Corp CodeWriter protection key
// Add Robocom Ltd - Robo 500/1000/1500 Interface Modules
static const UINT kUNIT_VERSION = 2;
static const std::string& GetSnapshotStructName_SDSSpeedStar(void)
@ -136,6 +167,24 @@ static const std::string& GetSnapshotStructName_CodeWriter(void)
return name;
}
static const std::string& GetSnapshotStructName_Robocom500(void)
{
static const std::string name("Robocom Robo 500 Interface Module");
return name;
}
static const std::string& GetSnapshotStructName_Robocom1000(void)
{
static const std::string name("Robocom Robo 1000 Interface Module");
return name;
}
static const std::string& GetSnapshotStructName_Robocom1500(void)
{
static const std::string name("Robocom Robo 1500 Interface Module");
return name;
}
void CopyProtectionDongleSaveSnapshot(YamlSaveHelper& yamlSaveHelper)
{
if (copyProtectionDongleType == DT_SDSSPEEDSTAR)
@ -148,6 +197,21 @@ void CopyProtectionDongleSaveSnapshot(YamlSaveHelper& yamlSaveHelper)
yamlSaveHelper.SaveString(SS_YAML_KEY_DEVICE, GetSnapshotStructName_CodeWriter());
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_CODEWRITER_INDEX, codewriterLFSR);
}
else if (copyProtectionDongleType == DT_ROBOCOM500)
{
yamlSaveHelper.SaveString(SS_YAML_KEY_DEVICE, GetSnapshotStructName_Robocom500());
// NB. No state for this dongle
}
else if (copyProtectionDongleType == DT_ROBOCOM1000)
{
yamlSaveHelper.SaveString(SS_YAML_KEY_DEVICE, GetSnapshotStructName_Robocom1000());
// NB. No state for this dongle
}
else if (copyProtectionDongleType == DT_ROBOCOM1500)
{
yamlSaveHelper.SaveString(SS_YAML_KEY_DEVICE, GetSnapshotStructName_Robocom1500());
// NB. No state for this dongle
}
else
{
_ASSERT(0);
@ -176,6 +240,18 @@ void CopyProtectionDongleLoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT versi
copyProtectionDongleType = DT_CODEWRITER;
codewriterLFSR = yamlLoadHelper.LoadUint(SS_YAML_KEY_CODEWRITER_INDEX);
}
else if (device == GetSnapshotStructName_Robocom500())
{
copyProtectionDongleType = DT_ROBOCOM500;
}
else if (device == GetSnapshotStructName_Robocom1000())
{
copyProtectionDongleType = DT_ROBOCOM1000;
}
else if (device == GetSnapshotStructName_Robocom1500())
{
copyProtectionDongleType = DT_ROBOCOM1500;
}
else
{
_ASSERT(0);

View File

@ -3,7 +3,7 @@
#include "Common.h"
// Must be in the same order as in PageAdvanced.cpp
enum DONGLETYPE { DT_EMPTY, DT_SDSSPEEDSTAR, DT_CODEWRITER };
enum DONGLETYPE { DT_EMPTY, DT_SDSSPEEDSTAR, DT_CODEWRITER, DT_ROBOCOM500, DT_ROBOCOM1000, DT_ROBOCOM1500 };
void SetCopyProtectionDongleType(DONGLETYPE type);
DONGLETYPE GetCopyProtectionDongleType(void);
@ -11,6 +11,7 @@ void DongleControl(WORD address);
int CopyProtectionDonglePB0(void);
int CopyProtectionDonglePB1(void);
int CopyProtectionDonglePB2(void);
int CopyProtectionDonglePDL(UINT pdl);
void CopyProtectionDongleSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
void CopyProtectionDongleLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT version);

View File

@ -622,7 +622,7 @@ BYTE __stdcall JoyReadButton(WORD pc, WORD address, BYTE, BYTE, ULONG nExecutedC
pressed = !swapButtons0and1 ? CheckButton0Pressed() : CheckButton1Pressed();
const UINT button0 = !swapButtons0and1 ? 0 : 1;
DoAutofire(button0, pressed);
if(CopyProtectionDonglePB0() >= 0) //If a copy protection dongle needs PB0, this overrides the joystick
if (CopyProtectionDonglePB0() >= 0) //If a copy protection dongle needs PB0, this overrides the joystick
pressed = CopyProtectionDonglePB0();
}
break;
@ -682,9 +682,9 @@ BYTE __stdcall JoyReadPosition(WORD programcounter, WORD address, BYTE, BYTE, UL
BOOL nPdlCntrActive = g_nCumulativeCycles <= g_paddleInactiveCycle[address & 3];
// If no joystick connected, then this is always active (GH#778)
// If no joystick connected, then this is always active (GH#778) && no copy-protection dongle connected
const UINT joyNum = (address & 2) ? 1 : 0; // $C064..$C067
if (joyinfo[joytype[joyNum]] == DEVICE_NONE)
if (joyinfo[joytype[joyNum]] == DEVICE_NONE && CopyProtectionDonglePDL(address & 3) < 0)
nPdlCntrActive = TRUE;
return MemReadFloatingBus(nPdlCntrActive, nExecutedCycles);
@ -699,6 +699,12 @@ void JoyReset()
}
//===========================================================================
static void SetPaddleInactiveCycle(UINT pdl, UINT pdlPos)
{
g_paddleInactiveCycle[pdl] = g_nCumulativeCycles + (UINT64)((double)pdlPos * PDL_CNTR_INTERVAL);
}
void JoyResetPosition(ULONG nExecutedCycles)
{
CpuCalcCycles(nExecutedCycles);
@ -754,7 +760,17 @@ void JoyResetPosition(ULONG nExecutedCycles)
if (pdlPos >= 255)
pdlPos = 287;
g_paddleInactiveCycle[pdl] = g_nCumulativeCycles + (UINT64)((double)pdlPos * PDL_CNTR_INTERVAL);
SetPaddleInactiveCycle(pdl, pdlPos);
}
// Protection dongle overrides the PDL timer
// . eg. needed when Robocom PDL3 is still timing-out from the extended-255 count (eg. 287)
// . really if it were at 255 (ie. not connected), then on enabling the dongle it switches to (eg) 23 it should timeout immediately
for (UINT pdl = 0; pdl < 4; pdl++)
{
int pdlPosDongle = CopyProtectionDonglePDL(pdl);
if (pdlPosDongle >= 0)
SetPaddleInactiveCycle(pdl, pdlPosDongle);
}
}