diff --git a/resource/Applewin.rc b/resource/Applewin.rc index 59201b7a..046ed933 100644 --- a/resource/Applewin.rc +++ b/resource/Applewin.rc @@ -257,7 +257,7 @@ BEGIN CONTROL "The Free&ze's non-autostart F8 rom (Apple ][ or ][+ only)",IDC_THE_FREEZES_F8_ROM_FW, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,201,194,10 LTEXT "&Game I/O Connector:",IDC_STATIC,5,220,82,8 - COMBOBOX IDC_COMBO_GAME_IO_CONNECTOR,89,218,100,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBO_GAME_IO_CONNECTOR,89,218,114,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END diff --git a/source/Configuration/PageAdvanced.cpp b/source/Configuration/PageAdvanced.cpp index b0ffcc00..6fe7f76a 100644 --- a/source/Configuration/PageAdvanced.cpp +++ b/source/Configuration/PageAdvanced.cpp @@ -44,10 +44,10 @@ const TCHAR CPageAdvanced::m_CloneChoices[] = TEXT("TK3000 //e\0") // Brazilian TEXT("Base 64A\0"); // Taiwanese -//enum GAMEIOCONNECTOR_CHOICE { MENUITEM_EMPTY, MENUITEM_SPEEDSTAR }; const TCHAR CPageAdvanced::m_gameIOConnectorChoices[] = - TEXT("Empty\0") - TEXT("SDS DataKey - SpeedStar\0"); // Protection dongle for Southwestern Data Systems "SpeedStar" Applesoft Compiler + "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" */ INT_PTR CALLBACK CPageAdvanced::DlgProc(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam) diff --git a/source/CopyProtectionDongles.cpp b/source/CopyProtectionDongles.cpp index 2f2f3524..bcbb833f 100644 --- a/source/CopyProtectionDongles.cpp +++ b/source/CopyProtectionDongles.cpp @@ -4,7 +4,7 @@ Copyright (C) 1994-1996, Michael O'Brien Copyright (C) 1999-2001, Oliver Schmidt Copyright (C) 2002-2005, Tom Charlesworth - Copyright (C) 2006-2022, Tom Charlesworth, Michael Pohoreski + Copyright (C) 2006-2023, 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 @@ -26,9 +26,8 @@ Emulate hardware copy protection dongles for Apple II 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" */ #include "StdAfx.h" #include @@ -39,6 +38,20 @@ static DONGLETYPE copyProtectionDongleType = DT_EMPTY; +static const BYTE codewriterInitialLFSR = 0x6B; // %1101011 (7-bit LFSR) +static BYTE codewriterLFSR = codewriterInitialLFSR; + +static void codeWriterResetLFSR() +{ + codewriterLFSR = codewriterInitialLFSR; +} + +static void codeWriterClockLFSR() +{ + BYTE bit = ((codewriterLFSR >> 1) ^ (codewriterLFSR >> 0)) & 1; + codewriterLFSR = (codewriterLFSR >> 1) | (bit << 6); +} + void SetCopyProtectionDongleType(DONGLETYPE type) { copyProtectionDongleType = type; @@ -49,9 +62,26 @@ DONGLETYPE GetCopyProtectionDongleType(void) return copyProtectionDongleType; } +void DongleControl(WORD address) +{ + UINT AN = ((address - 8) >> 1) & 7; + bool state = address & 1; // ie. C058 = AN0_off; C059 = AN0_on + + if (copyProtectionDongleType == DT_EMPTY || copyProtectionDongleType == DT_SDSSPEEDSTAR) + return; + + if (copyProtectionDongleType == DT_CODEWRITER) + { + if ((AN == 3 && state == true) || MemGetAnnunciator(3)) // reset or was already reset? (ie. takes precedent over AN2) + codeWriterResetLFSR(); + else if (AN == 2 && state == false && MemGetAnnunciator(2) == true) // AN2 true->false edge? + codeWriterClockLFSR(); + } +} + // This protection dongle consists of a NAND gate connected with AN1 and AN2 on the inputs // PB2 on the output, and AN0 connected to power it. -bool SdsSpeedStar(void) +static bool SdsSpeedStar(void) { return !MemGetAnnunciator(0) || !(MemGetAnnunciator(1) && MemGetAnnunciator(2)); } @@ -75,7 +105,9 @@ int CopyProtectionDonglePB2(void) { case DT_SDSSPEEDSTAR: // Southwestern Data Systems DataKey for SpeedStar Applesoft Compiler return SdsSpeedStar(); - break; + + case DT_CODEWRITER: // Dynatech Microsoftware / Cortechs Corp protection key for "CodeWriter" + return codewriterLFSR & 1; default: return -1; @@ -85,7 +117,12 @@ int CopyProtectionDonglePB2(void) //=========================================================================== -static const UINT kUNIT_VERSION = 1; +#define SS_YAML_KEY_CODEWRITER_INDEX "LFSR" + +// Unit version history: +// 1: Add SDS SpeedStar dongle +// 2: Add Cortechs Corp CodeWriter protection key +static const UINT kUNIT_VERSION = 2; static const std::string& GetSnapshotStructName_SDSSpeedStar(void) { @@ -93,6 +130,12 @@ static const std::string& GetSnapshotStructName_SDSSpeedStar(void) return name; } +static const std::string& GetSnapshotStructName_CodeWriter(void) +{ + static const std::string name("Cortechs Corp CodeWriter protection key"); + return name; +} + void CopyProtectionDongleSaveSnapshot(YamlSaveHelper& yamlSaveHelper) { if (copyProtectionDongleType == DT_SDSSPEEDSTAR) @@ -100,6 +143,11 @@ void CopyProtectionDongleSaveSnapshot(YamlSaveHelper& yamlSaveHelper) yamlSaveHelper.SaveString(SS_YAML_KEY_DEVICE, GetSnapshotStructName_SDSSpeedStar()); // NB. No state for this dongle } + else if (copyProtectionDongleType == DT_CODEWRITER) + { + yamlSaveHelper.SaveString(SS_YAML_KEY_DEVICE, GetSnapshotStructName_CodeWriter()); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_CODEWRITER_INDEX, codewriterLFSR); + } else { _ASSERT(0); @@ -123,6 +171,11 @@ void CopyProtectionDongleLoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT versi { copyProtectionDongleType = DT_SDSSPEEDSTAR; } + else if (device == GetSnapshotStructName_CodeWriter()) + { + copyProtectionDongleType = DT_CODEWRITER; + codewriterLFSR = yamlLoadHelper.LoadUint(SS_YAML_KEY_CODEWRITER_INDEX); + } else { _ASSERT(0); diff --git a/source/CopyProtectionDongles.h b/source/CopyProtectionDongles.h index 7b4ace5e..bbff9a98 100644 --- a/source/CopyProtectionDongles.h +++ b/source/CopyProtectionDongles.h @@ -3,14 +3,14 @@ #include "Common.h" // Must be in the same order as in PageAdvanced.cpp -enum DONGLETYPE { DT_EMPTY, DT_SDSSPEEDSTAR }; +enum DONGLETYPE { DT_EMPTY, DT_SDSSPEEDSTAR, DT_CODEWRITER }; void SetCopyProtectionDongleType(DONGLETYPE type); DONGLETYPE GetCopyProtectionDongleType(void); +void DongleControl(WORD address); int CopyProtectionDonglePB0(void); int CopyProtectionDonglePB1(void); int CopyProtectionDonglePB2(void); -bool SdsSpeedStar(void); void CopyProtectionDongleSaveSnapshot(class YamlSaveHelper& yamlSaveHelper); void CopyProtectionDongleLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT version); diff --git a/source/Memory.cpp b/source/Memory.cpp index 0845825b..da9cbabe 100644 --- a/source/Memory.cpp +++ b/source/Memory.cpp @@ -34,6 +34,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "Interface.h" #include "Core.h" #include "CardManager.h" +#include "CopyProtectionDongles.h" #include "CPU.h" #include "Joystick.h" #include "Keyboard.h" @@ -709,6 +710,8 @@ BYTE __stdcall IO_Annunciator(WORD programcounter, WORD address, BYTE write, BYT // . $C2B5: LDA $C05D (CLRAN2) ;SETUP // . $C2B8: LDA $C05F (CLRAN3) ; ANNUNCIATORS + DongleControl(address); // do before setting g_Annunciator[] as may need to access old MemGetAnnunciator() state + g_Annunciator[(address>>1) & 3] = (address&1) ? true : false; if (address >= 0xC058 && address <= 0xC05B)