mirror of
https://github.com/AppleWin/AppleWin.git
synced 2024-12-26 20:30:16 +00:00
Support Robocom's Interface Module protection dongles (#1247, PR#1248)
This commit is contained in:
parent
a62beeac1e
commit
927b0da09a
@ -85,8 +85,9 @@ From the drop-down menu, select a device to use in the internal Game I/O Connect
|
|||||||
Supported devices are:
|
Supported devices are:
|
||||||
<ul>
|
<ul>
|
||||||
<li> Empty
|
<li> Empty
|
||||||
<li> Southwestern Data Systems Datakey - SpeedStar (copy protection dongle)
|
<li> Southwestern Data Systems' datakey - SpeedStar (copy protection dongle)
|
||||||
<li> Dynatech Microsoftware / Cortechs Corp protection key - CodeWriter (copy protection dongle)
|
<li> Dynatech Microsoftware / Cortechs Corp's protection key - CodeWriter (copy protection dongle)
|
||||||
|
<li> Robocom Ltd's interface module - Robo 500/1000/1500 & RoboCAD 1/2 (copy protection dongle)
|
||||||
</ul>
|
</ul>
|
||||||
NB. Copy protection dongles can interfere with joysticks (eg. buttons may be hardwired to a fixed state), so only use dongles with the intended software.<br>
|
NB. Copy protection dongles can interfere with joysticks (eg. buttons may be hardwired to a fixed state), so only use dongles with the intended software.<br>
|
||||||
NB. Copy protection dongles can interfere with RGB cards (eg. unexpected video modes may get selected).<br>
|
NB. Copy protection dongles can interfere with RGB cards (eg. unexpected video modes may get selected).<br>
|
||||||
|
@ -47,7 +47,10 @@ const TCHAR CPageAdvanced::m_CloneChoices[] =
|
|||||||
const TCHAR CPageAdvanced::m_gameIOConnectorChoices[] =
|
const TCHAR CPageAdvanced::m_gameIOConnectorChoices[] =
|
||||||
"Empty\0"
|
"Empty\0"
|
||||||
"SDS DataKey - SpeedStar\0" /* Protection dongle for Southwestern Data Systems "SpeedStar" Applesoft Compiler */
|
"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 Ltd - Robo 500\0" /* Interface Module for Robocom Ltd's Robo 500 */
|
||||||
|
"Robocom Ltd - Robo 1000\0" /* Interface Module for Robocom Ltd's Robo 1000 */
|
||||||
|
"Robocom Ltd - Robo 1500\0"; /* Interface Module for Robocom Ltd's Robo 1500 */
|
||||||
|
|
||||||
|
|
||||||
INT_PTR CALLBACK CPageAdvanced::DlgProc(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
INT_PTR CALLBACK CPageAdvanced::DlgProc(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
||||||
|
@ -26,8 +26,9 @@
|
|||||||
Emulate hardware copy protection dongles for Apple II
|
Emulate hardware copy protection dongles for Apple II
|
||||||
|
|
||||||
Currently supported:
|
Currently supported:
|
||||||
- Southwestern Data Systems DataKey for SpeedStar Applesoft Compiler (Matthew D'Asaro Dec 2022)
|
- Southwestern Data Systems' datakey for SpeedStar Applesoft Compiler (Matthew D'Asaro Dec 2022)
|
||||||
- Dynatech Microsoftware / Cortechs Corp protection key for "CodeWriter"
|
- Dynatech Microsoftware / Cortechs Corp's protection key for "CodeWriter"
|
||||||
|
- Robocom Ltd's Interface Module for Robo Graphics 500/1000/1500 & RoboCAD 1/2 (BitStik joystick plugs in on top)
|
||||||
*/
|
*/
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -41,12 +42,12 @@ static DONGLETYPE copyProtectionDongleType = DT_EMPTY;
|
|||||||
static const BYTE codewriterInitialLFSR = 0x6B; // %1101011 (7-bit LFSR)
|
static const BYTE codewriterInitialLFSR = 0x6B; // %1101011 (7-bit LFSR)
|
||||||
static BYTE codewriterLFSR = codewriterInitialLFSR;
|
static BYTE codewriterLFSR = codewriterInitialLFSR;
|
||||||
|
|
||||||
static void codeWriterResetLFSR()
|
static void CodeWriterResetLFSR()
|
||||||
{
|
{
|
||||||
codewriterLFSR = codewriterInitialLFSR;
|
codewriterLFSR = codewriterInitialLFSR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void codeWriterClockLFSR()
|
static void CodeWriterClockLFSR()
|
||||||
{
|
{
|
||||||
BYTE bit = ((codewriterLFSR >> 1) ^ (codewriterLFSR >> 0)) & 1;
|
BYTE bit = ((codewriterLFSR >> 1) ^ (codewriterLFSR >> 0)) & 1;
|
||||||
codewriterLFSR = (codewriterLFSR >> 1) | (bit << 6);
|
codewriterLFSR = (codewriterLFSR >> 1) | (bit << 6);
|
||||||
@ -73,9 +74,9 @@ void DongleControl(WORD address)
|
|||||||
if (copyProtectionDongleType == DT_CODEWRITER)
|
if (copyProtectionDongleType == DT_CODEWRITER)
|
||||||
{
|
{
|
||||||
if ((AN == 3 && state == true) || MemGetAnnunciator(3)) // reset or was already reset? (ie. takes precedent over AN2)
|
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?
|
else if (AN == 2 && state == false && MemGetAnnunciator(2) == true) // AN2 true->false edge?
|
||||||
codeWriterClockLFSR();
|
CodeWriterClockLFSR();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,15 +104,51 @@ int CopyProtectionDonglePB2(void)
|
|||||||
{
|
{
|
||||||
switch (copyProtectionDongleType)
|
switch (copyProtectionDongleType)
|
||||||
{
|
{
|
||||||
case DT_SDSSPEEDSTAR: // Southwestern Data Systems DataKey for SpeedStar Applesoft Compiler
|
case DT_SDSSPEEDSTAR:
|
||||||
return SdsSpeedStar();
|
return SdsSpeedStar();
|
||||||
|
|
||||||
case DT_CODEWRITER: // Dynatech Microsoftware / Cortechs Corp protection key for "CodeWriter"
|
case DT_CODEWRITER:
|
||||||
return codewriterLFSR & 1;
|
return codewriterLFSR & 1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -1;
|
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)
|
||||||
|
{
|
||||||
|
if (copyProtectionDongleType != DT_ROBOCOM500 && copyProtectionDongleType != DT_ROBOCOM1000 && copyProtectionDongleType != DT_ROBOCOM1500)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
bool roboComInterfaceModulePower = !MemGetAnnunciator(3);
|
||||||
|
if (!roboComInterfaceModulePower || pdl != 3)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
UINT roboComInterfaceModuleMode = ((UINT)MemGetAnnunciator(2) << 2) | ((UINT)MemGetAnnunciator(1) << 1) | (UINT)MemGetAnnunciator(0);
|
||||||
|
|
||||||
|
switch (copyProtectionDongleType)
|
||||||
|
{
|
||||||
|
case DT_ROBOCOM500:
|
||||||
|
{
|
||||||
|
static BYTE robo500[8] = { 0x3F,0x2E,0x54,0x54,0x2E,0x22,0x72,0x17 }; // PDL3 lower bound
|
||||||
|
return robo500[roboComInterfaceModuleMode] + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DT_ROBOCOM1000:
|
||||||
|
{
|
||||||
|
static BYTE robo1000[8] = { 0x17,0x72,0x22,0x2E,0x54,0x54,0x2E,0x3F }; // PDL3 lower bound
|
||||||
|
return robo1000[roboComInterfaceModuleMode] + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DT_ROBOCOM1500:
|
||||||
|
{
|
||||||
|
static BYTE robo1500[8] = { 0x72,0x17,0x2E,0x17,0x22,0x3F,0x54,0x22 }; // PDL3 lower bound
|
||||||
|
return robo1500[roboComInterfaceModuleMode] + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,6 +159,7 @@ int CopyProtectionDonglePB2(void)
|
|||||||
// Unit version history:
|
// Unit version history:
|
||||||
// 1: Add SDS SpeedStar dongle
|
// 1: Add SDS SpeedStar dongle
|
||||||
// 2: Add Cortechs Corp CodeWriter protection key
|
// 2: Add Cortechs Corp CodeWriter protection key
|
||||||
|
// Add Robocom Ltd - Robo 500/1000/1500 Interface Modules
|
||||||
static const UINT kUNIT_VERSION = 2;
|
static const UINT kUNIT_VERSION = 2;
|
||||||
|
|
||||||
static const std::string& GetSnapshotStructName_SDSSpeedStar(void)
|
static const std::string& GetSnapshotStructName_SDSSpeedStar(void)
|
||||||
@ -132,7 +170,25 @@ static const std::string& GetSnapshotStructName_SDSSpeedStar(void)
|
|||||||
|
|
||||||
static const std::string& GetSnapshotStructName_CodeWriter(void)
|
static const std::string& GetSnapshotStructName_CodeWriter(void)
|
||||||
{
|
{
|
||||||
static const std::string name("Cortechs Corp CodeWriter protection key");
|
static const std::string name("Cortechs Corp - CodeWriter protection key");
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const std::string& GetSnapshotStructName_Robocom500(void)
|
||||||
|
{
|
||||||
|
static const std::string name("Robocom Ltd - Robo 500 Interface Module");
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const std::string& GetSnapshotStructName_Robocom1000(void)
|
||||||
|
{
|
||||||
|
static const std::string name("Robocom Ltd - Robo 1000 Interface Module");
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const std::string& GetSnapshotStructName_Robocom1500(void)
|
||||||
|
{
|
||||||
|
static const std::string name("Robocom Ltd - Robo 1500 Interface Module");
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,6 +204,21 @@ void CopyProtectionDongleSaveSnapshot(YamlSaveHelper& yamlSaveHelper)
|
|||||||
yamlSaveHelper.SaveString(SS_YAML_KEY_DEVICE, GetSnapshotStructName_CodeWriter());
|
yamlSaveHelper.SaveString(SS_YAML_KEY_DEVICE, GetSnapshotStructName_CodeWriter());
|
||||||
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_CODEWRITER_INDEX, codewriterLFSR);
|
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
|
else
|
||||||
{
|
{
|
||||||
_ASSERT(0);
|
_ASSERT(0);
|
||||||
@ -176,6 +247,18 @@ void CopyProtectionDongleLoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT versi
|
|||||||
copyProtectionDongleType = DT_CODEWRITER;
|
copyProtectionDongleType = DT_CODEWRITER;
|
||||||
codewriterLFSR = yamlLoadHelper.LoadUint(SS_YAML_KEY_CODEWRITER_INDEX);
|
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
|
else
|
||||||
{
|
{
|
||||||
_ASSERT(0);
|
_ASSERT(0);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
// Must be in the same order as in PageAdvanced.cpp
|
// 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);
|
void SetCopyProtectionDongleType(DONGLETYPE type);
|
||||||
DONGLETYPE GetCopyProtectionDongleType(void);
|
DONGLETYPE GetCopyProtectionDongleType(void);
|
||||||
@ -11,6 +11,7 @@ void DongleControl(WORD address);
|
|||||||
int CopyProtectionDonglePB0(void);
|
int CopyProtectionDonglePB0(void);
|
||||||
int CopyProtectionDonglePB1(void);
|
int CopyProtectionDonglePB1(void);
|
||||||
int CopyProtectionDonglePB2(void);
|
int CopyProtectionDonglePB2(void);
|
||||||
|
int CopyProtectionDonglePDL(UINT pdl);
|
||||||
|
|
||||||
void CopyProtectionDongleSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
|
void CopyProtectionDongleSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
|
||||||
void CopyProtectionDongleLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT version);
|
void CopyProtectionDongleLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT version);
|
||||||
|
@ -622,7 +622,7 @@ BYTE __stdcall JoyReadButton(WORD pc, WORD address, BYTE, BYTE, ULONG nExecutedC
|
|||||||
pressed = !swapButtons0and1 ? CheckButton0Pressed() : CheckButton1Pressed();
|
pressed = !swapButtons0and1 ? CheckButton0Pressed() : CheckButton1Pressed();
|
||||||
const UINT button0 = !swapButtons0and1 ? 0 : 1;
|
const UINT button0 = !swapButtons0and1 ? 0 : 1;
|
||||||
DoAutofire(button0, pressed);
|
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();
|
pressed = CopyProtectionDonglePB0();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -682,9 +682,9 @@ BYTE __stdcall JoyReadPosition(WORD programcounter, WORD address, BYTE, BYTE, UL
|
|||||||
|
|
||||||
BOOL nPdlCntrActive = g_nCumulativeCycles <= g_paddleInactiveCycle[address & 3];
|
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
|
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;
|
nPdlCntrActive = TRUE;
|
||||||
|
|
||||||
return MemReadFloatingBus(nPdlCntrActive, nExecutedCycles);
|
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)
|
void JoyResetPosition(ULONG nExecutedCycles)
|
||||||
{
|
{
|
||||||
CpuCalcCycles(nExecutedCycles);
|
CpuCalcCycles(nExecutedCycles);
|
||||||
@ -754,7 +760,17 @@ void JoyResetPosition(ULONG nExecutedCycles)
|
|||||||
if (pdlPos >= 255)
|
if (pdlPos >= 255)
|
||||||
pdlPos = 287;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user