diff --git a/AppleWin/Applewin.vcproj b/AppleWin/Applewin.vcproj
index cfd2dab8..1d9106a3 100644
--- a/AppleWin/Applewin.vcproj
+++ b/AppleWin/Applewin.vcproj
@@ -48,7 +48,7 @@
AdditionalOptions="/Zm200 "
Optimization="2"
InlineFunctionExpansion="2"
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;HAS_M6803"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
@@ -141,7 +141,7 @@
Name="VCCLCompilerTool"
AdditionalOptions="/Zm200 "
Optimization="0"
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;HAS_M6803"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/Applewin.pch"
@@ -526,16 +526,20 @@
Name="Resources"
Filter=".txt,.ico,.bmp,.rc"
>
+
+
+
+
-
-
+
+
@@ -640,6 +648,14 @@
RelativePath="RESOURCE\HELP.BMP"
>
+
+
+
+
@@ -648,6 +664,10 @@
RelativePath="RESOURCE\SETUP.BMP"
>
+
+
= A2TYPE_MAX)
+ dwComputerType = A2TYPE_APPLE2EEHANCED;
+ g_Apple2Type = (eApple2Type) dwComputerType;
+ }
+ else
+ {
+ LOAD(TEXT("Computer Emulation"),&dwComputerType);
+ switch (dwComputerType)
+ {
+ // NB. No A2TYPE_APPLE2E
+ case 0: g_Apple2Type = A2TYPE_APPLE2;
+ case 1: g_Apple2Type = A2TYPE_APPLE2PLUS;
+ case 2: g_Apple2Type = A2TYPE_APPLE2EEHANCED;
+ default: g_Apple2Type = A2TYPE_APPLE2EEHANCED;
+ }
+ }
+
LOAD(TEXT("Joystick 0 Emulation"),&joytype[0]);
LOAD(TEXT("Joystick 1 Emulation"),&joytype[1]);
LOAD(TEXT("Sound Emulation") ,&soundtype);
- LOAD(TEXT("Serial Port") ,&serialport);
+
+ DWORD dwSerialPort;
+ LOAD(TEXT("Serial Port") ,&dwSerialPort);
+ sg_SSC.SetSerialPort(dwSerialPort);
+
LOAD(TEXT("Emulation Speed") ,&g_dwSpeed);
LOAD(TEXT("Enhance Disk Speed"),(DWORD *)&enhancedisk);
LOAD(TEXT("Video Emulation") ,&videotype);
@@ -622,6 +645,7 @@ int APIENTRY WinMain (HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
// DO ONE-TIME INITIALIZATION
g_hInstance = passinstance;
+ MemPreInitialize(); // Call before any of the slot devices are initialized
GdiSetBatchLimit(512);
GetProgramDirectory();
RegisterExtensions();
@@ -649,7 +673,7 @@ int APIENTRY WinMain (HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
{
// DO INITIALIZATION THAT MUST BE REPEATED FOR A RESTART
restart = 0;
- g_nAppMode = MODE_LOGO;
+ g_nAppMode = MODE_LOGO;
LoadConfiguration();
DebugInitialize();
JoyInitialize();
diff --git a/AppleWin/source/Applewin.h b/AppleWin/source/Applewin.h
index 3164ab9d..7454709d 100644
--- a/AppleWin/source/Applewin.h
+++ b/AppleWin/source/Applewin.h
@@ -4,8 +4,7 @@ extern char VERSIONSTRING[]; // Contructed in WinMain()
extern TCHAR *g_pAppTitle;
-extern bool g_bApple2e;
-extern bool g_bApple2plus;
+extern eApple2Type g_Apple2Type;
extern BOOL behind;
extern DWORD cumulativecycles;
diff --git a/AppleWin/source/CPU.cpp b/AppleWin/source/CPU.cpp
index 884dd3a9..8735bde4 100644
--- a/AppleWin/source/CPU.cpp
+++ b/AppleWin/source/CPU.cpp
@@ -149,13 +149,9 @@ static volatile BOOL g_bNmiFlank = FALSE; // Positive going flank on NMI line
if (regs.sp < 0x100) \
regs.sp = 0x1FF;
#define READ ( \
- ((addr & 0xFF00) == 0xC000) \
- ? ioread[addr & 0xFF](regs.pc,(BYTE)addr,0,0,uExecutedCycles) \
- : ( \
- (((addr & 0xFF00) == 0xC400) || ((addr & 0xFF00) == 0xC500)) \
- ? CxReadFunc(regs.pc, addr, 0, 0, uExecutedCycles) \
+ ((addr & 0xF000) == 0xC000) \
+ ? IORead[(addr>>4) & 0xFF](regs.pc,addr,0,0,uExecutedCycles) \
: *(mem+addr) \
- ) \
)
#define SETNZ(a) { \
flagn = ((a) & 0x80); \
@@ -164,13 +160,11 @@ static volatile BOOL g_bNmiFlank = FALSE; // Positive going flank on NMI line
#define SETZ(a) flagz = !((a) & 0xFF);
#define WRITE(a) { \
memdirty[addr >> 8] = 0xFF; \
- LPBYTE page = memwrite[0][addr >> 8]; \
+ LPBYTE page = memwrite[addr >> 8]; \
if (page) \
*(page+(addr & 0xFF)) = (BYTE)(a); \
- else if ((addr & 0xFF00) == 0xC000) \
- iowrite[addr & 0xFF](regs.pc,(BYTE)addr,1,(BYTE)(a),uExecutedCycles); \
- else if(((addr & 0xFF00) == 0xC400) || ((addr & 0xFF00) == 0xC500)) \
- CxWriteFunc(regs.pc, addr, 1, (BYTE)(a), uExecutedCycles); \
+ else if ((addr & 0xF000) == 0xC000) \
+ IOWrite[(addr>>4) & 0xFF](regs.pc,addr,1,(BYTE)(a),uExecutedCycles); \
}
//
@@ -841,7 +835,11 @@ static DWORD Cpu65C02 (DWORD uTotalCycles)
g_uInternalExecutedCycles = uExecutedCycles;
USHORT uExtraCycles = 0;
- BYTE iOpcode = *(mem+regs.pc);
+// BYTE iOpcode = *(mem+regs.pc);
+ BYTE iOpcode = ((regs.pc & 0xF000) == 0xC000)
+ ? IORead[(regs.pc>>4) & 0xFF](regs.pc,regs.pc,0,0,uExecutedCycles) // Fetch opcode from I/O memory, but params are still from mem[]
+ : *(mem+regs.pc);
+
if (CheckDebugBreak( iOpcode ))
break;
@@ -1166,7 +1164,11 @@ static DWORD Cpu6502 (DWORD uTotalCycles)
g_uInternalExecutedCycles = uExecutedCycles;
USHORT uExtraCycles = 0;
- BYTE iOpcode = *(mem+regs.pc);
+// BYTE iOpcode = *(mem+regs.pc);
+ BYTE iOpcode = ((regs.pc & 0xF000) == 0xC000)
+ ? IORead[(regs.pc>>4) & 0xFF](regs.pc,regs.pc,0,0,uExecutedCycles)
+ : *(mem+regs.pc);
+
if (CheckDebugBreak( iOpcode ))
break;
@@ -1472,10 +1474,10 @@ static DWORD Cpu6502 (DWORD uTotalCycles)
static DWORD InternalCpuExecute (DWORD uTotalCycles)
{
- if (g_bApple2e)
- return Cpu65C02(uTotalCycles);
- else // Apple ][
- return Cpu6502(uTotalCycles);
+ if (IS_APPLE2 || (g_Apple2Type == A2TYPE_APPLE2E))
+ return Cpu6502(uTotalCycles); // Apple ][, ][+, //e
+ else
+ return Cpu65C02(uTotalCycles); // Enhanced Apple //e
}
//
diff --git a/AppleWin/source/Common.h b/AppleWin/source/Common.h
index 0c598da6..ec5774a8 100644
--- a/AppleWin/source/Common.h
+++ b/AppleWin/source/Common.h
@@ -9,6 +9,8 @@ const UINT uVisibleLinesPerFrame = 64*3; // 192
const UINT uLinesPerFrame = 262; // 64 in each third of the screen & 70 in VBL
const DWORD dwClksPerFrame = uCyclesPerLine * uLinesPerFrame; // 17030
+#define NUM_SLOTS 8
+
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
@@ -51,12 +53,13 @@ enum AppMode_e
#define BTN_DEBUG 6
#define BTN_SETUP 7
-#define MAXIMAGES 16
+//#define MAXIMAGES 16
+
// TODO: Move to StringTable.h
-#define TITLE_APPLE_2_ORG TEXT("Apple ][ Emulator")
-#define TITLE_APPLE_2_PLUS TEXT("Apple ][+ Emulator")
-#define TITLE_APPLE_2_E TEXT("Apple //e Emulator")
-// #define TITLE TITLE_APPLE_2_E
+#define TITLE_APPLE_2 TEXT("Apple ][ Emulator")
+#define TITLE_APPLE_2_PLUS TEXT("Apple ][+ Emulator")
+#define TITLE_APPLE_2E TEXT("Apple //e Emulator")
+#define TITLE_APPLE_2E_ENHANCED TEXT("Enhanced Apple //e Emulator")
#define TITLE_PAUSED TEXT(" Paused ")
#define TITLE_STEPPING TEXT("Stepping")
@@ -65,6 +68,7 @@ enum AppMode_e
#define SAVE(a,b) RegSaveValue(TEXT("Configuration"),a,1,b)
// Configuration
+#define REGVALUE_APPLE2_TYPE "Apple2 Type"
#define REGVALUE_SPKR_VOLUME "Speaker Volume"
#define REGVALUE_MB_VOLUME "Mockingboard Volume"
#define REGVALUE_SOUNDCARD_TYPE "Soundcard Type"
@@ -87,9 +91,27 @@ enum AppMode_e
enum eSOUNDCARDTYPE {SC_UNINIT=0, SC_NONE, SC_MOCKINGBOARD, SC_PHASOR}; // Apple soundcard type
-typedef BYTE (__stdcall *iofunction)(WORD nPC, BYTE nAddr, BYTE nWriteFlag, BYTE nWriteValue, ULONG nCyclesLeft);
-typedef BYTE (__stdcall *cxfunction)(WORD nPC, WORD nAddr, BYTE nWriteFlag, BYTE nWriteValue, ULONG nCyclesLeft);
+typedef BYTE (__stdcall *iofunction)(WORD nPC, WORD nAddr, BYTE nWriteFlag, BYTE nWriteValue, ULONG nCyclesLeft);
typedef struct _IMAGE__ { int unused; } *HIMAGE;
enum eIRQSRC {IS_6522=0, IS_SPEECH, IS_SSC};
+
+//
+
+#define APPLE2E_MASK 0x10
+#define APPLE2C_MASK 0x20
+
+#define IS_APPLE2 ((g_Apple2Type & (APPLE2E_MASK|APPLE2C_MASK)) == 0)
+#define IS_APPLE2E (g_Apple2Type & APPLE2E_MASK)
+#define IS_APPLE2C (g_Apple2Type & APPLE2C_MASK)
+
+// NB. These get persisted to the Registry, so don't change the values for these enums!
+enum eApple2Type {
+ A2TYPE_APPLE2=0,
+ A2TYPE_APPLE2PLUS,
+ A2TYPE_APPLE2E=APPLE2E_MASK,
+ A2TYPE_APPLE2EEHANCED,
+// A2TYPE_APPLE2C=APPLE2C_MASK, // Placeholder
+ A2TYPE_MAX
+ };
\ No newline at end of file
diff --git a/AppleWin/source/Debug.cpp b/AppleWin/source/Debug.cpp
index fa72e3a2..f617faf7 100644
--- a/AppleWin/source/Debug.cpp
+++ b/AppleWin/source/Debug.cpp
@@ -2649,9 +2649,9 @@ Update_t CmdIn (int nArgs)
return Help_Arg_1( CMD_IN );
WORD nAddress = g_aArgs[1].nValue;
-
-// ioread[ g_aArgs[1].nValue & 0xFF ](regs.pc,g_aArgs[1].nValue & 0xFF,0,0,0);
- ioread[ nAddress & 0xFF ](regs.pc, nAddress & 0xFF,0,0,0); // g_aArgs[1].nValue
+
+ BYTE nPageOffset = nAddress & 0xFF;
+ IORead[ (nAddress>>4) & 0xF ](regs.pc, nAddress & 0xFF, 0, 0, 0); // g_aArgs[1].nValue
return UPDATE_CONSOLE_DISPLAY; // TODO: Verify // 1
}
@@ -2712,8 +2712,8 @@ Update_t CmdOut (int nArgs)
WORD nAddress = g_aArgs[1].nValue;
-// iowrite[ g_aArgs[1].nValue & 0xFF](regs.pc,g_aArgs[1].nValue & 0xFF,1,g_aArgs[2].nValue & 0xFF,0);
- iowrite[ nAddress & 0xFF ] (regs.pc, nAddress & 0xFF, 1, g_aArgs[2].nValue & 0xFF,0);
+ BYTE nPageOffset = nAddress & 0xFF;
+ IOWrite[ (nAddress>>4) & 0xF ] (regs.pc, nAddress & 0xFF, 1, g_aArgs[2].nValue & 0xFF, 0);
return UPDATE_CONSOLE_DISPLAY; // TODO: Verify // 1
}
@@ -8150,13 +8150,18 @@ void DebugBegin ()
g_nAppMode = MODE_DEBUG;
FrameRefreshStatus(DRAW_TITLE);
- if (g_bApple2e)
- g_aOpcodes = & g_aOpcodes65C02[ 0 ]; // Enhanced Apple //e
+ if (IS_APPLE2 || (g_Apple2Type == A2TYPE_APPLE2E))
+ {
+ g_aOpcodes = & g_aOpcodes6502[ 0 ]; // Apple ][, ][+, //e
+ g_aOpmodes[ AM_2 ].m_nBytes = 1;
+ g_aOpmodes[ AM_3 ].m_nBytes = 1;
+ }
else
- g_aOpcodes = & g_aOpcodes6502[ 0 ]; // Original Apple ][ ][+
-
- g_aOpmodes[ AM_2 ].m_nBytes = g_bApple2e ? 2 : 1;
- g_aOpmodes[ AM_3 ].m_nBytes = g_bApple2e ? 3 : 1;
+ {
+ g_aOpcodes = & g_aOpcodes65C02[ 0 ]; // Enhanced Apple //e
+ g_aOpmodes[ AM_2 ].m_nBytes = 2;
+ g_aOpmodes[ AM_3 ].m_nBytes = 3;
+ }
g_nDisasmCurAddress = regs.pc;
DisasmCalcTopBotAddress();
diff --git a/AppleWin/source/Disk.cpp b/AppleWin/source/Disk.cpp
index e2264dd9..be286a85 100644
--- a/AppleWin/source/Disk.cpp
+++ b/AppleWin/source/Disk.cpp
@@ -28,6 +28,15 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "StdAfx.h"
#pragma hdrstop
+#include "..\resource\resource.h"
+
+static BYTE __stdcall DiskControlMotor (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+static BYTE __stdcall DiskControlStepper (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+static BYTE __stdcall DiskEnable (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+static BYTE __stdcall DiskReadWrite (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+static BYTE __stdcall DiskSetLatchValue (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+static BYTE __stdcall DiskSetReadMode (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+static BYTE __stdcall DiskSetWriteMode (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
#define LOG_DISK_ENABLED 1
@@ -275,14 +284,14 @@ void DiskBoot () {
}
//===========================================================================
-BYTE __stdcall DiskControlMotor (WORD, BYTE address, BYTE, BYTE, ULONG) {
+static BYTE __stdcall DiskControlMotor (WORD, WORD address, BYTE, BYTE, ULONG) {
floppymotoron = address & 1;
CheckSpinning();
return MemReturnRandomData(1);
}
//===========================================================================
-BYTE __stdcall DiskControlStepper (WORD, BYTE address, BYTE, BYTE, ULONG)
+static BYTE __stdcall DiskControlStepper (WORD, WORD address, BYTE, BYTE, ULONG)
{
Disk_t * fptr = &g_aFloppyDisk[currdrive];
int phase = (address >> 1) & 3;
@@ -349,7 +358,7 @@ void DiskDestroy ()
}
//===========================================================================
-BYTE __stdcall DiskEnable (WORD, BYTE address, BYTE, BYTE, ULONG) {
+static BYTE __stdcall DiskEnable (WORD, WORD address, BYTE, BYTE, ULONG) {
currdrive = address & 1;
g_aFloppyDisk[!currdrive].spinning = 0;
g_aFloppyDisk[!currdrive].writelight = 0;
@@ -392,14 +401,20 @@ LPCTSTR DiskGetName (int drive) {
}
//===========================================================================
-void DiskInitialize () {
- int loop = DRIVES;
- while (loop--)
- ZeroMemory(&g_aFloppyDisk[loop],sizeof(Disk_t ));
- TCHAR imagefilename[MAX_PATH];
- _tcscpy(imagefilename,g_sProgramDir);
- _tcscat(imagefilename,TEXT("MASTER.DSK")); // TODO: Should remember last disk by user
- DiskInsert(0,imagefilename,0,0);
+
+BYTE __stdcall Disk_IORead(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+BYTE __stdcall Disk_IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+
+void DiskInitialize ()
+{
+ int loop = DRIVES;
+ while (loop--)
+ ZeroMemory(&g_aFloppyDisk[loop],sizeof(Disk_t ));
+
+ TCHAR imagefilename[MAX_PATH];
+ _tcscpy(imagefilename,g_sProgramDir);
+ _tcscat(imagefilename,TEXT("MASTER.DSK")); // TODO: Should remember last disk by user
+ DiskInsert(0,imagefilename,0,0);
}
//===========================================================================
@@ -485,7 +500,7 @@ void DiskSetProtect( const int iDrive, const bool bWriteProtect )
//===========================================================================
-BYTE __stdcall DiskReadWrite (WORD programcounter, BYTE, BYTE, BYTE, ULONG) {
+static BYTE __stdcall DiskReadWrite (WORD programcounter, WORD, BYTE, BYTE, ULONG) {
Disk_t * fptr = &g_aFloppyDisk[currdrive];
diskaccessed = 1;
if ((!fptr->trackimagedata) && fptr->imagehandle)
@@ -517,9 +532,11 @@ BYTE __stdcall DiskReadWrite (WORD programcounter, BYTE, BYTE, BYTE, ULONG) {
}
//===========================================================================
-void DiskReset () {
- floppymotoron = 0;
- phases = 0;
+
+void DiskReset()
+{
+ floppymotoron = 0;
+ phases = 0;
}
//===========================================================================
@@ -575,20 +592,21 @@ void DiskSelect (int drive)
}
//===========================================================================
-BYTE __stdcall DiskSetLatchValue (WORD, BYTE, BYTE write, BYTE value, ULONG) {
+
+static BYTE __stdcall DiskSetLatchValue (WORD, WORD, BYTE write, BYTE value, ULONG) {
if (write)
floppylatch = value;
return floppylatch;
}
//===========================================================================
-BYTE __stdcall DiskSetReadMode (WORD, BYTE, BYTE, BYTE, ULONG) {
+static BYTE __stdcall DiskSetReadMode (WORD, WORD, BYTE, BYTE, ULONG) {
floppywritemode = 0;
return MemReturnRandomData(g_aFloppyDisk[currdrive].writeprotected);
}
//===========================================================================
-BYTE __stdcall DiskSetWriteMode (WORD, BYTE, BYTE, BYTE, ULONG) {
+static BYTE __stdcall DiskSetWriteMode (WORD, WORD, BYTE, BYTE, ULONG) {
floppywritemode = 1;
BOOL modechange = !g_aFloppyDisk[currdrive].writelight;
g_aFloppyDisk[currdrive].writelight = 20000;
@@ -646,6 +664,99 @@ bool DiskDriveSwap()
//===========================================================================
+static BYTE __stdcall Disk_IORead(WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+static BYTE __stdcall Disk_IOWrite(WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+
+void DiskLoadRom(LPBYTE pCxRomPeripheral, UINT uSlot)
+{
+ const UINT DISK2_FW_SIZE = 256;
+
+ HRSRC hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_DISK2_FW), "FIRMWARE");
+ if(hResInfo == NULL)
+ return;
+
+ DWORD dwResSize = SizeofResource(NULL, hResInfo);
+ if(dwResSize != DISK2_FW_SIZE)
+ return;
+
+ HGLOBAL hResData = LoadResource(NULL, hResInfo);
+ if(hResData == NULL)
+ return;
+
+ BYTE* pData = (BYTE*) LockResource(hResData); // NB. Don't need to unlock resource
+ if(pData == NULL)
+ return;
+
+ memcpy(pCxRomPeripheral + uSlot*256, pData, DISK2_FW_SIZE);
+
+ // TODO/FIXME: HACK! REMOVE A WAIT ROUTINE FROM THE DISK CONTROLLER'S FIRMWARE
+ *(pCxRomPeripheral+0x064C) = 0xA9;
+ *(pCxRomPeripheral+0x064D) = 0x00;
+ *(pCxRomPeripheral+0x064E) = 0xEA;
+
+ //
+
+ RegisterIoHandler(uSlot, Disk_IORead, Disk_IOWrite, NULL, NULL, NULL, NULL);
+}
+
+//===========================================================================
+
+static BYTE __stdcall Disk_IORead(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
+{
+ addr &= 0xFF;
+
+ switch (addr & 0xf)
+ {
+ case 0x0: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x1: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x2: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x3: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x4: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x5: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x6: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x7: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x8: return DiskControlMotor(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x9: return DiskControlMotor(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xA: return DiskEnable(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xB: return DiskEnable(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xC: return DiskReadWrite(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xD: return DiskSetLatchValue(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xE: return DiskSetReadMode(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xF: return DiskSetWriteMode(pc, addr, bWrite, d, nCyclesLeft);
+ }
+
+ return 0;
+}
+
+static BYTE __stdcall Disk_IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
+{
+ addr &= 0xFF;
+
+ switch (addr & 0xf)
+ {
+ case 0x0: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x1: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x2: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x3: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x4: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x5: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x6: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x7: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x8: return DiskControlMotor(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x9: return DiskControlMotor(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xA: return DiskEnable(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xB: return DiskEnable(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xC: return DiskReadWrite(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xD: return DiskSetLatchValue(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xE: return DiskSetReadMode(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xF: return DiskSetWriteMode(pc, addr, bWrite, d, nCyclesLeft);
+ }
+
+ return 0;
+}
+
+//===========================================================================
+
DWORD DiskGetSnapshot(SS_CARD_DISK2* pSS, DWORD dwSlot)
{
pSS->Hdr.UnitHdr.dwLength = sizeof(SS_CARD_DISK2);
diff --git a/AppleWin/source/Disk.h b/AppleWin/source/Disk.h
index 724a0c50..cc42462d 100644
--- a/AppleWin/source/Disk.h
+++ b/AppleWin/source/Disk.h
@@ -36,13 +36,6 @@ void DiskSetProtect( const int iDrive, const bool bWriteProtect );
void DiskSelect (int);
void DiskUpdatePosition (DWORD);
bool DiskDriveSwap();
+void DiskLoadRom(LPBYTE pCxRomPeripheral, UINT uSlot);
DWORD DiskGetSnapshot(SS_CARD_DISK2* pSS, DWORD dwSlot);
DWORD DiskSetSnapshot(SS_CARD_DISK2* pSS, DWORD dwSlot);
-
-BYTE __stdcall DiskControlMotor (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
-BYTE __stdcall DiskControlStepper (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
-BYTE __stdcall DiskEnable (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
-BYTE __stdcall DiskReadWrite (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
-BYTE __stdcall DiskSetLatchValue (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
-BYTE __stdcall DiskSetReadMode (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
-BYTE __stdcall DiskSetWriteMode (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
diff --git a/AppleWin/source/Frame.cpp b/AppleWin/source/Frame.cpp
index f0e38d0b..61f8700c 100644
--- a/AppleWin/source/Frame.cpp
+++ b/AppleWin/source/Frame.cpp
@@ -350,7 +350,7 @@ void DrawStatusArea (HDC passdc, int drawflags)
TextOut(dc,x+ 3,y+2,TEXT("1"),1);
SetTextColor(dc,RGB((iDrive2Status==2 ? 255 : 0),(iDrive2Status==1 ? 255 : 0),0));
TextOut(dc,x+13,y+2,TEXT("2"),1);
- if (g_bApple2e)
+ if (!IS_APPLE2)
{
SetTextAlign(dc,TA_RIGHT | TA_TOP);
SetTextColor(dc,(bCaps
@@ -387,7 +387,7 @@ void DrawStatusArea (HDC passdc, int drawflags)
DrawBitmapRect(dc,x+12,y+8,&rect,diskbitmap[iDrive1Status]);
DrawBitmapRect(dc,x+30,y+8,&rect,diskbitmap[iDrive2Status]);
- if (g_bApple2e)
+ if (!IS_APPLE2)
{
RECT rect = {0,0,30,8};
DrawBitmapRect(dc,x+7,y+19,&rect,capsbitmap[bCaps != 0]);
@@ -397,11 +397,13 @@ void DrawStatusArea (HDC passdc, int drawflags)
if (drawflags & DRAW_TITLE)
{
TCHAR title[40];
- _tcscpy(title,g_bApple2e
- ? TITLE_APPLE_2_E
- : (g_bApple2plus
- ? TITLE_APPLE_2_PLUS
- : TITLE_APPLE_2_ORG ));
+ switch (g_Apple2Type)
+ {
+ case A2TYPE_APPLE2: _tcscpy(title, TITLE_APPLE_2); break;
+ case A2TYPE_APPLE2PLUS: _tcscpy(title, TITLE_APPLE_2_PLUS); break;
+ case A2TYPE_APPLE2E: _tcscpy(title, TITLE_APPLE_2E); break;
+ case A2TYPE_APPLE2EEHANCED: _tcscpy(title, TITLE_APPLE_2E_ENHANCED); break;
+ }
switch (g_nAppMode)
{
@@ -522,7 +524,7 @@ LRESULT CALLBACK FrameWndProc (
HD_Cleanup();
}
PrintDestroy();
- CommDestroy();
+ sg_SSC.CommDestroy();
CpuDestroy();
MemDestroy();
SpkrDestroy();
@@ -1071,7 +1073,7 @@ void ResetMachineState () {
MemReset();
DiskBoot();
VideoResetState();
- CommReset();
+ sg_SSC.CommReset();
PrintReset();
JoyReset();
MB_Reset();
@@ -1182,25 +1184,16 @@ void FrameCreateWindow ()
if (!RegLoadValue(TEXT("Preferences"),TEXT("Window Y-Position"),1,(DWORD *)&ypos))
ypos = (GetSystemMetrics(SM_CYSCREEN)-height) >> 1;
- if (g_bApple2e)
+ switch (g_Apple2Type)
{
- g_pAppTitle = TITLE_APPLE_2_E;
- }
- else
- {
- if (g_bApple2plus)
- g_pAppTitle = TITLE_APPLE_2_PLUS;
- else
- g_pAppTitle = TITLE_APPLE_2_ORG;
+ case A2TYPE_APPLE2: g_pAppTitle = TITLE_APPLE_2; break;
+ case A2TYPE_APPLE2PLUS: g_pAppTitle = TITLE_APPLE_2_PLUS; break;
+ case A2TYPE_APPLE2E: g_pAppTitle = TITLE_APPLE_2E; break;
+ case A2TYPE_APPLE2EEHANCED: g_pAppTitle = TITLE_APPLE_2E_ENHANCED; break;
}
g_hFrameWindow = CreateWindow(
TEXT("APPLE2FRAME"),
-// g_bApple2e
-// ? TITLE_APPLE_2_E
-// : (g_bApple2plus
-// ? TITLE_APPLE_2_PLUS
-// : TITLE_APPLE_2),
g_pAppTitle,
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU |
WS_MINIMIZEBOX | WS_VISIBLE,
diff --git a/AppleWin/source/Harddisk.cpp b/AppleWin/source/Harddisk.cpp
index 7330b72b..616c2d51 100644
--- a/AppleWin/source/Harddisk.cpp
+++ b/AppleWin/source/Harddisk.cpp
@@ -127,6 +127,8 @@ static BYTE g_nHD_Command;
static HDD g_HardDrive[2] = {0};
+static UINT g_uSlot = 7;
+
//===========================================================================
static void GetImageTitle (LPCTSTR imagefilename, PHDD pHardDrive)
@@ -212,6 +214,8 @@ static LPCTSTR HD_DiskGetName (int nDrive)
// everything below is global
+static BYTE __stdcall HD_IO_EMUL (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+
static const DWORD HDDRVR_SIZE = 0x100;
static LPBYTE lpMemC000 = NULL;
@@ -231,9 +235,11 @@ void HD_SetEnabled(bool bEnabled)
return;
if(g_bHD_Enabled)
- HD_Load_Rom(lpMemC000);
+ HD_Load_Rom(lpMemC000, g_uSlot);
else
- memset(lpMemC000+0x700, 0, HDDRVR_SIZE);
+ memset(lpMemC000 + g_uSlot*256, 0, HDDRVR_SIZE);
+
+ RegisterIoHandler(g_uSlot, HD_IO_EMUL, HD_IO_EMUL, NULL, NULL, NULL, NULL);
}
LPCTSTR HD_GetFullName (int nDrive)
@@ -241,14 +247,14 @@ LPCTSTR HD_GetFullName (int nDrive)
return g_HardDrive[nDrive].hd_fullname;
}
-VOID HD_Load_Rom(LPBYTE lpMemRom)
+VOID HD_Load_Rom(LPBYTE pCxRomPeripheral, UINT uSlot)
{
- lpMemC000 = lpMemRom; // Keep a copy for HD_SetEnabled()
+ lpMemC000 = pCxRomPeripheral; // Keep a copy for HD_SetEnabled()
if(!g_bHD_Enabled)
return;
- HRSRC hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_HDDRVR), "FIRMWARE");
+ HRSRC hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_HDDRVR_FW), "FIRMWARE");
if(hResInfo == NULL)
return;
@@ -264,7 +270,8 @@ VOID HD_Load_Rom(LPBYTE lpMemRom)
if(pData == NULL)
return;
- memcpy(lpMemRom+0x700, pData, HDDRVR_SIZE);
+ g_uSlot = uSlot;
+ memcpy(pCxRomPeripheral + uSlot*256, pData, HDDRVR_SIZE);
g_bHD_RomLoaded = true;
}
@@ -354,9 +361,10 @@ void HD_Select(int nDrive)
#define DEVICE_UNKNOWN_ERROR 0x03
#define DEVICE_IO_ERROR 0x08
-BYTE __stdcall HD_IO_EMUL (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
+static BYTE __stdcall HD_IO_EMUL (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
{
BYTE r = DEVICE_OK;
+ addr &= 0xFF;
if (!HD_CardIsEnabled())
return r;
@@ -505,8 +513,7 @@ BYTE __stdcall HD_IO_EMUL (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCycle
}
break;
default:
- {
- }
+ return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
}
}
else // write
@@ -547,21 +554,9 @@ BYTE __stdcall HD_IO_EMUL (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCycle
}
break;
default:
- break;
+ return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
}
}
return r;
}
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/AppleWin/source/Harddisk.h b/AppleWin/source/Harddisk.h
index 98ac0885..54b9ae1b 100644
--- a/AppleWin/source/Harddisk.h
+++ b/AppleWin/source/Harddisk.h
@@ -3,10 +3,8 @@
bool HD_CardIsEnabled();
void HD_SetEnabled(bool bEnabled);
LPCTSTR HD_GetFullName (int drive);
-VOID HD_Load_Rom(LPBYTE lpMemRom);
+VOID HD_Load_Rom(LPBYTE pCxRomPeripheral, UINT uSlot);
VOID HD_Cleanup();
BOOL HD_InsertDisk2(int nDrive, LPCTSTR pszFilename);
BOOL HD_InsertDisk(int nDrive, LPCTSTR imagefilename);
void HD_Select(int nDrive);
-
-BYTE __stdcall HD_IO_EMUL (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
diff --git a/AppleWin/source/Joystick.cpp b/AppleWin/source/Joystick.cpp
index 838588e1..90c2eeea 100644
--- a/AppleWin/source/Joystick.cpp
+++ b/AppleWin/source/Joystick.cpp
@@ -365,8 +365,10 @@ BOOL JoyProcessKey (int virtkey, BOOL extended, BOOL down, BOOL autorep)
//===========================================================================
-BYTE __stdcall JoyReadButton (WORD, BYTE address, BYTE, BYTE, ULONG)
+BYTE __stdcall JoyReadButton (WORD, WORD address, BYTE, BYTE, ULONG)
{
+ address &= 0xFF;
+
if(joyinfo[joytype[0]].device == DEVICE_JOYSTICK)
CheckJoystick0();
if(joyinfo[joytype[1]].device == DEVICE_JOYSTICK)
@@ -417,7 +419,7 @@ BYTE __stdcall JoyReadButton (WORD, BYTE address, BYTE, BYTE, ULONG)
static const double PDL_CNTR_INTERVAL = 2816.0 / 255.0; // 11.04 (From KEGS)
-BYTE __stdcall JoyReadPosition (WORD programcounter, BYTE address, BYTE, BYTE, ULONG nCyclesLeft)
+BYTE __stdcall JoyReadPosition (WORD programcounter, WORD address, BYTE, BYTE, ULONG nCyclesLeft)
{
int nJoyNum = (address & 2) ? 1 : 0; // $C064..$C067
@@ -443,7 +445,7 @@ void JoyReset ()
}
//===========================================================================
-BYTE __stdcall JoyResetPosition (WORD, BYTE, BYTE, BYTE, ULONG nCyclesLeft)
+BYTE __stdcall JoyResetPosition (WORD, WORD, BYTE, BYTE, ULONG nCyclesLeft)
{
CpuCalcCycles(nCyclesLeft);
g_nJoyCntrResetCycle = g_nCumulativeCycles;
diff --git a/AppleWin/source/Joystick.h b/AppleWin/source/Joystick.h
index f9fcce2b..79b92832 100644
--- a/AppleWin/source/Joystick.h
+++ b/AppleWin/source/Joystick.h
@@ -17,6 +17,6 @@ short JoyGetTrim(bool bAxisX);
DWORD JoyGetSnapshot(SS_IO_Joystick* pSS);
DWORD JoySetSnapshot(SS_IO_Joystick* pSS);
-BYTE __stdcall JoyReadButton (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
-BYTE __stdcall JoyReadPosition (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
-BYTE __stdcall JoyResetPosition (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+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);
+BYTE __stdcall JoyResetPosition (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
diff --git a/AppleWin/source/Keyboard.cpp b/AppleWin/source/Keyboard.cpp
index e3e73d61..67325663 100644
--- a/AppleWin/source/Keyboard.cpp
+++ b/AppleWin/source/Keyboard.cpp
@@ -167,7 +167,7 @@ void KeybQueueKeypress (int key, BOOL bASCII)
if (key > 0x7F)
return;
- if (g_bApple2e)
+ if (!IS_APPLE2)
{
if (g_bCapsLock && (key >= 'a') && (key <='z'))
keycode = key - 32;
@@ -188,12 +188,12 @@ void KeybQueueKeypress (int key, BOOL bASCII)
if ((key == VK_CANCEL) && (GetKeyState(VK_CONTROL) < 0))
{
// Ctrl+Reset
- if (g_bApple2e)
+ if (!IS_APPLE2)
MemResetPaging();
DiskReset();
KeybReset();
- if (g_bApple2e)
+ if (!IS_APPLE2)
VideoResetState(); // Switch Alternate char set off
MB_Reset();
@@ -213,10 +213,10 @@ void KeybQueueKeypress (int key, BOOL bASCII)
return;
}
- if (!((key >= VK_LEFT) && (key <= VK_DELETE) && asciicode[g_bApple2e][key - VK_LEFT]))
+ if (!((key >= VK_LEFT) && (key <= VK_DELETE) && asciicode[IS_APPLE2 ? 0 : 1][key - VK_LEFT]))
return;
- keycode = asciicode[g_bApple2e][key - VK_LEFT]; // Convert to Apple arrow keycode
+ keycode = asciicode[IS_APPLE2 ? 0 : 1][key - VK_LEFT]; // Convert to Apple arrow keycode
lastvirtkey = key;
}
#ifdef KEY_OLD
@@ -314,7 +314,7 @@ static char ClipboardCurrChar(bool bIncPtr)
//===========================================================================
-BYTE __stdcall KeybReadData (WORD, BYTE, BYTE, BYTE, ULONG)
+BYTE __stdcall KeybReadData (WORD, WORD, BYTE, BYTE, ULONG)
{
keyboardqueries++;
@@ -352,7 +352,7 @@ BYTE __stdcall KeybReadData (WORD, BYTE, BYTE, BYTE, ULONG)
//===========================================================================
-BYTE __stdcall KeybReadFlag (WORD, BYTE, BYTE, BYTE, ULONG)
+BYTE __stdcall KeybReadFlag (WORD, WORD, BYTE, BYTE, ULONG)
{
keyboardqueries++;
@@ -389,7 +389,7 @@ BYTE __stdcall KeybReadFlag (WORD, BYTE, BYTE, BYTE, ULONG)
//===========================================================================
void KeybToggleCapsLock ()
{
- if (g_bApple2e)
+ if (!IS_APPLE2)
{
g_bCapsLock = (GetKeyState(VK_CAPITAL) & 1);
FrameRefreshStatus(DRAW_LEDS);
diff --git a/AppleWin/source/Keyboard.h b/AppleWin/source/Keyboard.h
index b45b96cb..b77d01f0 100644
--- a/AppleWin/source/Keyboard.h
+++ b/AppleWin/source/Keyboard.h
@@ -15,5 +15,5 @@ void KeybToggleCapsLock ();
DWORD KeybGetSnapshot(SS_IO_Keyboard* pSS);
DWORD KeybSetSnapshot(SS_IO_Keyboard* pSS);
-BYTE __stdcall KeybReadData (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
-BYTE __stdcall KeybReadFlag (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+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);
diff --git a/AppleWin/source/Memory.cpp b/AppleWin/source/Memory.cpp
index 944e2531..1fef3817 100644
--- a/AppleWin/source/Memory.cpp
+++ b/AppleWin/source/Memory.cpp
@@ -55,543 +55,39 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define SW_SLOTCXROM (memmode & MF_SLOTCXROM)
#define SW_WRITERAM (memmode & MF_WRITERAM)
-BYTE __stdcall NullIo (WORD programcounter, BYTE address, BYTE write, BYTE value, ULONG nCycles);
+//-----------------------------------------------------------------------------
-iofunction ioread[0x100] = {KeybReadData, // $C000
- KeybReadData, // $C001
- KeybReadData, // $C002
- KeybReadData, // $C003
- KeybReadData, // $C004
- KeybReadData, // $C005
- KeybReadData, // $C006
- KeybReadData, // $C007
- KeybReadData, // $C008
- KeybReadData, // $C009
- KeybReadData, // $C00A
- KeybReadData, // $C00B
- KeybReadData, // $C00C
- KeybReadData, // $C00D
- KeybReadData, // $C00E
- KeybReadData, // $C00F
- KeybReadFlag, // $C010
- MemCheckPaging, // $C011
- MemCheckPaging, // $C012
- MemCheckPaging, // $C013
- MemCheckPaging, // $C014
- MemCheckPaging, // $C015
- MemCheckPaging, // $C016
- MemCheckPaging, // $C017
- MemCheckPaging, // $C018
- VideoCheckVbl, // $C019
- VideoCheckMode, // $C01A
- VideoCheckMode, // $C01B
- MemCheckPaging, // $C01C
- MemCheckPaging, // $C01D
- VideoCheckMode, // $C01E
- VideoCheckMode, // $C01F
- NullIo, // $C020
- NullIo, // $C021
- NullIo, // $C022
- NullIo, // $C023
- NullIo, // $C024
- NullIo, // $C025
- NullIo, // $C026
- NullIo, // $C027
- NullIo, // $C028
- NullIo, // $C029
- NullIo, // $C02A
- NullIo, // $C02B
- NullIo, // $C02C
- NullIo, // $C02D
- NullIo, // $C02E
- NullIo, // $C02F
- SpkrToggle, // $C030
- SpkrToggle, // $C031
- SpkrToggle, // $C032
- SpkrToggle, // $C033
- SpkrToggle, // $C034
- SpkrToggle, // $C035
- SpkrToggle, // $C036
- SpkrToggle, // $C037
- SpkrToggle, // $C038
- SpkrToggle, // $C039
- SpkrToggle, // $C03A
- SpkrToggle, // $C03B
- SpkrToggle, // $C03C
- SpkrToggle, // $C03D
- SpkrToggle, // $C03E
- SpkrToggle, // $C03F
- NullIo, // $C040
- NullIo, // $C041
- NullIo, // $C042
- NullIo, // $C043
- NullIo, // $C044
- NullIo, // $C045
- NullIo, // $C046
- NullIo, // $C047
- NullIo, // $C048
- NullIo, // $C049
- NullIo, // $C04A
- NullIo, // $C04B
- NullIo, // $C04C
- NullIo, // $C04D
- NullIo, // $C04E
- NullIo, // $C04F
- VideoSetMode, // $C050
- VideoSetMode, // $C051
- VideoSetMode, // $C052
- VideoSetMode, // $C053
- MemSetPaging, // $C054
- MemSetPaging, // $C055
- MemSetPaging, // $C056
- MemSetPaging, // $C057
- NullIo, // $C058
- NullIo, // $C059
- NullIo, // $C05A
- NullIo, // $C05B
- NullIo, // $C05C
- NullIo, // $C05D
- VideoSetMode, // $C05E
- VideoSetMode, // $C05F
- NullIo, // $C060
- JoyReadButton, // $C061
- JoyReadButton, // $C062
- JoyReadButton, // $C063
- JoyReadPosition, // $C064
- JoyReadPosition, // $C065
- JoyReadPosition, // $C066
- JoyReadPosition, // $C067
- NullIo, // $C068
- NullIo, // $C069
- NullIo, // $C06A
- NullIo, // $C06B
- NullIo, // $C06C
- NullIo, // $C06D
- NullIo, // $C06E
- NullIo, // $C06F
- JoyResetPosition, // $C070
- NullIo, // $C071
- NullIo, // $C072
- NullIo, // $C073
- NullIo, // $C074
- NullIo, // $C075
- NullIo, // $C076
- NullIo, // $C077
- NullIo, // $C078
- NullIo, // $C079
- NullIo, // $C07A
- NullIo, // $C07B
- NullIo, // $C07C
- NullIo, // $C07D
- NullIo, // $C07E
- VideoCheckMode, // $C07F
- MemSetPaging, // $C080
- MemSetPaging, // $C081
- MemSetPaging, // $C082
- MemSetPaging, // $C083
- MemSetPaging, // $C084
- MemSetPaging, // $C085
- MemSetPaging, // $C086
- MemSetPaging, // $C087
- MemSetPaging, // $C088
- MemSetPaging, // $C089
- MemSetPaging, // $C08A
- MemSetPaging, // $C08B
- MemSetPaging, // $C08C
- MemSetPaging, // $C08D
- MemSetPaging, // $C08E
- MemSetPaging, // $C08F
- PrintStatus, // $C090
- PrintStatus, // $C091
- PrintStatus, // $C092
- PrintStatus, // $C093
- PrintStatus, // $C094
- PrintStatus, // $C095
- PrintStatus, // $C096
- PrintStatus, // $C097
- PrintStatus, // $C098
- PrintStatus, // $C099
- PrintStatus, // $C09A
- PrintStatus, // $C09B
- PrintStatus, // $C09C
- PrintStatus, // $C09D
- PrintStatus, // $C09E
- PrintStatus, // $C09F
- NullIo, // $C0A0
- CommDipSw, // $C0A1
- CommDipSw, // $C0A2
- NullIo, // $C0A3
- NullIo, // $C0A4
- NullIo, // $C0A5
- NullIo, // $C0A6
- NullIo, // $C0A7
- CommReceive, // $C0A8
- CommStatus, // $C0A9
- CommCommand, // $C0AA
- CommControl, // $C0AB
- NullIo, // $C0AC
- NullIo, // $C0AD
- NullIo, // $C0AE
- NullIo, // $C0AF
- TfeIo, // $C0B0
- TfeIo, // $C0B1
- TfeIo, // $C0B2
- TfeIo, // $C0B3
- TfeIo, // $C0B4
- TfeIo, // $C0B5
- TfeIo, // $C0B6
- TfeIo, // $C0B7
- TfeIo, // $C0B8
- TfeIo, // $C0B9
- TfeIo, // $C0BA
- TfeIo, // $C0BB
- TfeIo, // $C0BC
- TfeIo, // $C0BD
- TfeIo, // $C0BE
- TfeIo, // $C0BF
- PhasorIO, // $C0C0
- PhasorIO, // $C0C1
- PhasorIO, // $C0C2
- PhasorIO, // $C0C3
- PhasorIO, // $C0C4
- PhasorIO, // $C0C5
- PhasorIO, // $C0C6
- PhasorIO, // $C0C7
- PhasorIO, // $C0C8
- PhasorIO, // $C0C9
- PhasorIO, // $C0CA
- PhasorIO, // $C0CB
- PhasorIO, // $C0CC
- PhasorIO, // $C0CD
- PhasorIO, // $C0CE
- PhasorIO, // $C0CF
- PhasorIO, // $C0D0
- PhasorIO, // $C0D1
- PhasorIO, // $C0D2
- PhasorIO, // $C0D3
- PhasorIO, // $C0D4
- PhasorIO, // $C0D5
- PhasorIO, // $C0D6
- PhasorIO, // $C0D7
- PhasorIO, // $C0D8
- PhasorIO, // $C0D9
- PhasorIO, // $C0DA
- PhasorIO, // $C0DB
- PhasorIO, // $C0DC
- PhasorIO, // $C0DD
- PhasorIO, // $C0DE
- PhasorIO, // $C0DF
- DiskControlStepper, // $C0E0
- DiskControlStepper, // $C0E1
- DiskControlStepper, // $C0E2
- DiskControlStepper, // $C0E3
- DiskControlStepper, // $C0E4
- DiskControlStepper, // $C0E5
- DiskControlStepper, // $C0E6
- DiskControlStepper, // $C0E7
- DiskControlMotor, // $C0E8
- DiskControlMotor, // $C0E9
- DiskEnable, // $C0EA
- DiskEnable, // $C0EB
- DiskReadWrite, // $C0EC
- DiskSetLatchValue, // $C0ED
- DiskSetReadMode, // $C0EE
- DiskSetWriteMode, // $C0EF
- HD_IO_EMUL, // $C0F0
- HD_IO_EMUL, // $C0F1
- HD_IO_EMUL, // $C0F2
- HD_IO_EMUL, // $C0F3
- HD_IO_EMUL, // $C0F4
- HD_IO_EMUL, // $C0F5
- HD_IO_EMUL, // $C0F6
- HD_IO_EMUL, // $C0F7
- HD_IO_EMUL, // $C0F8
- NullIo, // $C0F9
- NullIo, // $C0FA
- NullIo, // $C0FB
- NullIo, // $C0FC
- NullIo, // $C0FD
- NullIo, // $C0FE
- NullIo}; // $C0FF
+//static DWORD imagemode;
+static LPBYTE memshadow[0x100];
+LPBYTE memwrite[0x100];
-iofunction iowrite[0x100] = {MemSetPaging, // $C000
- MemSetPaging, // $C001
- MemSetPaging, // $C002
- MemSetPaging, // $C003
- MemSetPaging, // $C004
- MemSetPaging, // $C005
- MemSetPaging, // $C006
- MemSetPaging, // $C007
- MemSetPaging, // $C008
- MemSetPaging, // $C009
- MemSetPaging, // $C00A
- MemSetPaging, // $C00B
- VideoSetMode, // $C00C
- VideoSetMode, // $C00D
- VideoSetMode, // $C00E
- VideoSetMode, // $C00F
- KeybReadFlag, // $C010
- KeybReadFlag, // $C011
- KeybReadFlag, // $C012
- KeybReadFlag, // $C013
- KeybReadFlag, // $C014
- KeybReadFlag, // $C015
- KeybReadFlag, // $C016
- KeybReadFlag, // $C017
- KeybReadFlag, // $C018
- KeybReadFlag, // $C019
- KeybReadFlag, // $C01A
- KeybReadFlag, // $C01B
- KeybReadFlag, // $C01C
- KeybReadFlag, // $C01D
- KeybReadFlag, // $C01E
- KeybReadFlag, // $C01F
- NullIo, // $C020
- NullIo, // $C021
- NullIo, // $C022
- NullIo, // $C023
- NullIo, // $C024
- NullIo, // $C025
- NullIo, // $C026
- NullIo, // $C027
- NullIo, // $C028
- NullIo, // $C029
- NullIo, // $C02A
- NullIo, // $C02B
- NullIo, // $C02C
- NullIo, // $C02D
- NullIo, // $C02E
- NullIo, // $C02F
- SpkrToggle, // $C030
- SpkrToggle, // $C031
- SpkrToggle, // $C032
- SpkrToggle, // $C033
- SpkrToggle, // $C034
- SpkrToggle, // $C035
- SpkrToggle, // $C036
- SpkrToggle, // $C037
- SpkrToggle, // $C038
- SpkrToggle, // $C039
- SpkrToggle, // $C03A
- SpkrToggle, // $C03B
- SpkrToggle, // $C03C
- SpkrToggle, // $C03D
- SpkrToggle, // $C03E
- SpkrToggle, // $C03F
- NullIo, // $C040
- NullIo, // $C041
- NullIo, // $C042
- NullIo, // $C043
- NullIo, // $C044
- NullIo, // $C045
- NullIo, // $C046
- NullIo, // $C047
- NullIo, // $C048
- NullIo, // $C049
- NullIo, // $C04A
- NullIo, // $C04B
- NullIo, // $C04C
- NullIo, // $C04D
- NullIo, // $C04E
- NullIo, // $C04F
- VideoSetMode, // $C050
- VideoSetMode, // $C051
- VideoSetMode, // $C052
- VideoSetMode, // $C053
- MemSetPaging, // $C054
- MemSetPaging, // $C055
- MemSetPaging, // $C056
- MemSetPaging, // $C057
- NullIo, // $C058
- NullIo, // $C059
- NullIo, // $C05A
- NullIo, // $C05B
- NullIo, // $C05C
- NullIo, // $C05D
- VideoSetMode, // $C05E
- VideoSetMode, // $C05F
- NullIo, // $C060
- NullIo, // $C061
- NullIo, // $C062
- NullIo, // $C063
- NullIo, // $C064
- NullIo, // $C065
- NullIo, // $C066
- NullIo, // $C067
- NullIo, // $C068
- NullIo, // $C069
- NullIo, // $C06A
- NullIo, // $C06B
- NullIo, // $C06C
- NullIo, // $C06D
- NullIo, // $C06E
- NullIo, // $C06F
- JoyResetPosition, // $C070
-#ifdef RAMWORKS
- MemSetPaging, // $C071 - extended memory card set page
- NullIo, // $C072
- MemSetPaging, // $C073 - Ramworks III set page
-#else
- NullIo, // $C071
- NullIo, // $C072
- NullIo, // $C073
-#endif
- NullIo, // $C074
- NullIo, // $C075
- NullIo, // $C076
- NullIo, // $C077
- NullIo, // $C078
- NullIo, // $C079
- NullIo, // $C07A
- NullIo, // $C07B
- NullIo, // $C07C
- NullIo, // $C07D
- NullIo, // $C07E
- NullIo, // $C07F
- MemSetPaging, // $C080
- MemSetPaging, // $C081
- MemSetPaging, // $C082
- MemSetPaging, // $C083
- MemSetPaging, // $C084
- MemSetPaging, // $C085
- MemSetPaging, // $C086
- MemSetPaging, // $C087
- MemSetPaging, // $C088
- MemSetPaging, // $C089
- MemSetPaging, // $C08A
- MemSetPaging, // $C08B
- MemSetPaging, // $C08C
- MemSetPaging, // $C08D
- MemSetPaging, // $C08E
- MemSetPaging, // $C08F
- PrintTransmit, // $C090
- PrintTransmit, // $C091
- PrintTransmit, // $C092
- PrintTransmit, // $C093
- PrintTransmit, // $C094
- PrintTransmit, // $C095
- PrintTransmit, // $C096
- PrintTransmit, // $C097
- PrintTransmit, // $C098
- PrintTransmit, // $C099
- PrintTransmit, // $C09A
- PrintTransmit, // $C09B
- PrintTransmit, // $C09C
- PrintTransmit, // $C09D
- PrintTransmit, // $C09E
- PrintTransmit, // $C09F
- NullIo, // $C0A0
- NullIo, // $C0A1
- NullIo, // $C0A2
- NullIo, // $C0A3
- NullIo, // $C0A4
- NullIo, // $C0A5
- NullIo, // $C0A6
- NullIo, // $C0A7
- CommTransmit, // $C0A8
- CommStatus, // $C0A9
- CommCommand, // $C0AA
- CommControl, // $C0AB
- NullIo, // $C0AC
- NullIo, // $C0AD
- NullIo, // $C0AE
- NullIo, // $C0AF
- TfeIo, // $C0B0
- TfeIo, // $C0B1
- TfeIo, // $C0B2
- TfeIo, // $C0B3
- TfeIo, // $C0B4
- TfeIo, // $C0B5
- TfeIo, // $C0B6
- TfeIo, // $C0B7
- TfeIo, // $C0B8
- TfeIo, // $C0B9
- TfeIo, // $C0BA
- TfeIo, // $C0BB
- TfeIo, // $C0BC
- TfeIo, // $C0BD
- TfeIo, // $C0BE
- TfeIo, // $C0BF
- PhasorIO, // $C0C0
- PhasorIO, // $C0C1
- PhasorIO, // $C0C2
- PhasorIO, // $C0C3
- PhasorIO, // $C0C4
- PhasorIO, // $C0C5
- PhasorIO, // $C0C6
- PhasorIO, // $C0C7
- PhasorIO, // $C0C8
- PhasorIO, // $C0C9
- PhasorIO, // $C0CA
- PhasorIO, // $C0CB
- PhasorIO, // $C0CC
- PhasorIO, // $C0CD
- PhasorIO, // $C0CE
- PhasorIO, // $C0CF
- PhasorIO, // $C0D0
- PhasorIO, // $C0D1
- PhasorIO, // $C0D2
- PhasorIO, // $C0D3
- PhasorIO, // $C0D4
- PhasorIO, // $C0D5
- PhasorIO, // $C0D6
- PhasorIO, // $C0D7
- PhasorIO, // $C0D8
- PhasorIO, // $C0D9
- PhasorIO, // $C0DA
- PhasorIO, // $C0DB
- PhasorIO, // $C0DC
- PhasorIO, // $C0DD
- PhasorIO, // $C0DE
- PhasorIO, // $C0DF
- DiskControlStepper, // $C0E0
- DiskControlStepper, // $C0E1
- DiskControlStepper, // $C0E2
- DiskControlStepper, // $C0E3
- DiskControlStepper, // $C0E4
- DiskControlStepper, // $C0E5
- DiskControlStepper, // $C0E6
- DiskControlStepper, // $C0E7
- DiskControlMotor, // $C0E8
- DiskControlMotor, // $C0E9
- DiskEnable, // $C0EA
- DiskEnable, // $C0EB
- DiskReadWrite, // $C0EC
- DiskSetLatchValue, // $C0ED
- DiskSetReadMode, // $C0EE
- DiskSetWriteMode, // $C0EF
- HD_IO_EMUL, // $C0F0
- HD_IO_EMUL, // $C0F1
- HD_IO_EMUL, // $C0F2
- HD_IO_EMUL, // $C0F3
- HD_IO_EMUL, // $C0F4
- HD_IO_EMUL, // $C0F5
- HD_IO_EMUL, // $C0F6
- HD_IO_EMUL, // $C0F7
- HD_IO_EMUL, // $C0F8
- NullIo, // $C0F9
- NullIo, // $C0FA
- NullIo, // $C0FB
- NullIo, // $C0FC
- NullIo, // $C0FD
- NullIo, // $C0FE
- NullIo}; // $C0FF
+iofunction IORead[256];
+iofunction IOWrite[256];
+static LPVOID SlotParameters[NUM_SLOTS];
-static DWORD imagemode[MAXIMAGES];
-LPBYTE memshadow[MAXIMAGES][0x100];
-LPBYTE memwrite[MAXIMAGES][0x100];
-
-static BOOL fastpaging = 0; // Redundant: only ever set to 0, by MemSetFastPaging(0)
-DWORD image = 0;
-DWORD lastimage = 0;
+//static BOOL fastpaging = 0; // Redundant: only ever set to 0, by MemSetFastPaging(0)
+//static DWORD image = 0;
+//static DWORD lastimage = 0;
static BOOL lastwriteram = 0;
+
LPBYTE mem = NULL;
+
+//
+
static LPBYTE memaux = NULL;
-LPBYTE memdirty = NULL;
-static LPBYTE memimage = NULL;
static LPBYTE memmain = NULL;
-static DWORD memmode = MF_BANK2 | MF_SLOTCXROM | MF_WRITERAM;
+
+LPBYTE memdirty = NULL;
static LPBYTE memrom = NULL;
+
+static LPBYTE memimage = NULL;
+
+static LPBYTE pCxRomInternal = NULL;
+static LPBYTE pCxRomPeripheral = NULL;
+
+//
+
+static DWORD memmode = MF_BANK2 | MF_SLOTCXROM | MF_WRITERAM;
static BOOL modechanging = 0;
MemoryInitPattern_e g_eMemoryInitPattern = MIP_FF_FF_00_00;
@@ -601,162 +97,654 @@ UINT g_uMaxExPages = 1; // user requested ram pages
static LPBYTE RWpages[128]; // pointers to RW memory banks
#endif
-void UpdatePaging (BOOL initialize, BOOL updatewriteonly);
+BYTE __stdcall IO_Annunciator(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles);
+void UpdatePaging(BOOL initialize, BOOL updatewriteonly);
-//===========================================================================
-void BackMainImage () {
- int loop = 0;
- for (loop = 0; loop < 256; loop++) {
- if (memshadow[0][loop] &&
- ((*(memdirty+loop) & 1) || (loop <= 1)))
- CopyMemory(memshadow[0][loop],memimage+(loop << 8),256);
- *(memdirty+loop) &= ~1;
- }
+//=============================================================================
+
+static BYTE __stdcall IORead_C00x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
+{
+ return KeybReadData(pc, addr, bWrite, d, nCyclesLeft);
}
-//===========================================================================
-BYTE __stdcall NullIo (WORD programcounter, BYTE address, BYTE write, BYTE value, ULONG nCycles) {
- if (!write)
- {
- return MemReadFloatingBus();
- }
+static BYTE __stdcall IOWrite_C00x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
+{
+ if ((addr & 0xf) <= 0xB)
+ return MemSetPaging(pc, addr, bWrite, d, nCyclesLeft);
else
+ return VideoSetMode(pc, addr, bWrite, d, nCyclesLeft);
+}
+
+//-------------------------------------
+
+static BYTE __stdcall IORead_C01x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
+{
+ switch (addr & 0xf)
{
- return 0;
+ case 0x0: return KeybReadFlag(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x1: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x2: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x3: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x4: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x5: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x6: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x7: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x8: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x9: return VideoCheckVbl(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xA: return VideoCheckMode(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xB: return VideoCheckMode(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xC: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xD: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xE: return VideoCheckMode(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xF: return VideoCheckMode(pc, addr, bWrite, d, nCyclesLeft);
}
+
+ return 0;
+}
+
+static BYTE __stdcall IOWrite_C01x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
+{
+ return KeybReadFlag(pc, addr, bWrite, d, nCyclesLeft);
+}
+
+//-------------------------------------
+
+static BYTE __stdcall IORead_C02x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
+{
+ return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+}
+
+static BYTE __stdcall IOWrite_C02x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
+{
+ return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+}
+
+//-------------------------------------
+
+static BYTE __stdcall IORead_C03x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
+{
+ return SpkrToggle(pc, addr, bWrite, d, nCyclesLeft);
+}
+
+static BYTE __stdcall IOWrite_C03x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
+{
+ return SpkrToggle(pc, addr, bWrite, d, nCyclesLeft);
+}
+
+//-------------------------------------
+
+static BYTE __stdcall IORead_C04x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
+{
+ return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+}
+
+static BYTE __stdcall IOWrite_C04x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
+{
+ return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+}
+
+//-------------------------------------
+
+static BYTE __stdcall IORead_C05x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
+{
+ switch (addr & 0xf)
+ {
+ case 0x0: return VideoSetMode(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x1: return VideoSetMode(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x2: return VideoSetMode(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x3: return VideoSetMode(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x4: return MemSetPaging(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x5: return MemSetPaging(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x6: return MemSetPaging(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x7: return MemSetPaging(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x8: return IO_Annunciator(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x9: return IO_Annunciator(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xA: return IO_Annunciator(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xB: return IO_Annunciator(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xC: return IO_Annunciator(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xD: return IO_Annunciator(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xE: return VideoSetMode(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xF: return VideoSetMode(pc, addr, bWrite, d, nCyclesLeft);
+ }
+
+ return 0;
+}
+
+static BYTE __stdcall IOWrite_C05x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
+{
+ switch (addr & 0xf)
+ {
+ case 0x0: return VideoSetMode(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x1: return VideoSetMode(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x2: return VideoSetMode(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x3: return VideoSetMode(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x4: return MemSetPaging(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x5: return MemSetPaging(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x6: return MemSetPaging(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x7: return MemSetPaging(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x8: return IO_Annunciator(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x9: return IO_Annunciator(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xA: return IO_Annunciator(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xB: return IO_Annunciator(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xC: return IO_Annunciator(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xD: return IO_Annunciator(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xE: return VideoSetMode(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xF: return VideoSetMode(pc, addr, bWrite, d, nCyclesLeft);
+ }
+
+ return 0;
+}
+
+//-------------------------------------
+
+static BYTE __stdcall IORead_C06x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
+{
+ switch (addr & 0xf)
+ {
+ case 0x0: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x1: return JoyReadButton(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x2: return JoyReadButton(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x3: return JoyReadButton(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x4: return JoyReadPosition(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x5: return JoyReadPosition(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x6: return JoyReadPosition(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x7: return JoyReadPosition(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x8: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x9: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xA: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xB: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xC: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xD: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xE: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xF: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ }
+
+ return 0;
+}
+
+static BYTE __stdcall IOWrite_C06x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
+{
+ return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+}
+
+//-------------------------------------
+
+static BYTE __stdcall IORead_C07x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
+{
+ switch (addr & 0xf)
+ {
+ case 0x0: return JoyResetPosition(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x1: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x2: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x3: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x4: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x5: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x6: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x7: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x8: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x9: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xA: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xB: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xC: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xD: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xE: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xF: return VideoCheckMode(pc, addr, bWrite, d, nCyclesLeft);
+ }
+
+ return 0;
+}
+
+static BYTE __stdcall IOWrite_C07x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
+{
+ switch (addr & 0xf)
+ {
+ case 0x0: return JoyResetPosition(pc, addr, bWrite, d, nCyclesLeft);
+#ifdef RAMWORKS
+ case 0x1: return MemSetPaging(pc, addr, bWrite, d, nCyclesLeft); // extended memory card set page
+ case 0x2: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x3: return MemSetPaging(pc, addr, bWrite, d, nCyclesLeft); // Ramworks III set page
+#else
+ case 0x1: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x2: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x3: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+#endif
+ case 0x4: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x5: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x6: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x7: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x8: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0x9: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xA: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xB: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xC: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xD: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xE: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ case 0xF: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
+ }
+
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+
+static iofunction IORead_C0xx[8] =
+{
+ IORead_C00x, // Keyboard
+ IORead_C01x, // Memory/Video
+ IORead_C02x, // Cassette
+ IORead_C03x, // Speaker
+ IORead_C04x,
+ IORead_C05x, // Video
+ IORead_C06x, // Joystick
+ IORead_C07x, // Joystick/Video
+};
+
+static iofunction IOWrite_C0xx[8] =
+{
+ IOWrite_C00x, // Memory/Video
+ IOWrite_C01x, // Keyboard
+ IOWrite_C02x, // Cassette
+ IOWrite_C03x, // Speaker
+ IOWrite_C04x,
+ IOWrite_C05x, // Video/Memory
+ IOWrite_C06x,
+ IOWrite_C07x, // Joystick/Ramworks
+};
+
+static BYTE IO_SELECT;
+static BYTE IO_SELECT_InternalROM;
+
+static BYTE* ExpansionRom[NUM_SLOTS];
+
+enum eExpansionRomType {eExpRomNull=0, eExpRomInternal, eExpRomPeripheral};
+static eExpansionRomType g_eExpansionRomType = eExpRomNull;
+static UINT g_uPeripheralRomSlot = 0;
+
+//=============================================================================
+
+BYTE __stdcall IO_Null(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles)
+{
+ if (!write)
+ return MemReadFloatingBus();
+ else
+ return 0;
+}
+
+BYTE __stdcall IO_Annunciator(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles)
+{
+ // Apple//e ROM:
+ // . PC=FA6F: LDA $C058 (SETAN0)
+ // . PC=FA72: LDA $C05A (SETAN1)
+ // . PC=C2B5: LDA $C05D (CLRAN2)
+
+ // NB. AN3: For //e & //c these locations are now used to enabled/disabled DHIRES
+ return 0;
+}
+
+// Enabling expansion ROM ($C800..$CFFF]:
+// . Enable if: Enable1 && Enable2
+// . Enable1 = I/O SELECT' (6502 accesses $Csxx)
+// - Reset when 6502 accesses $CFFF
+// . Enable2 = I/O STROBE' (6502 accesses [$C800..$CFFF])
+
+BYTE __stdcall IORead_Cxxx(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles)
+{
+ if (address == 0xCFFF)
+ {
+ // Disable expansion ROM at [$C800..$CFFF]
+ // . SSC will disable on an access to $CFxx - but ROM only writes to $CFFF, so it doesn't matter
+ IO_SELECT = 0;
+ IO_SELECT_InternalROM = 0;
+ g_uPeripheralRomSlot = 0;
+
+ if (SW_SLOTCXROM)
+ {
+ // NB. SW_SLOTCXROM==0 ensures that internal rom stays switched in
+ memset(pCxRomPeripheral+0x800, 0, 0x800);
+ memset(mem+0xC800, 0, 0x800);
+ g_eExpansionRomType = eExpRomNull;
+ }
+
+ // NB. IO_SELECT won't get set, so ROM won't be switched back in...
+ }
+
+ //
+
+ BYTE IO_STROBE = 0;
+
+ if (IS_APPLE2 || SW_SLOTCXROM)
+ {
+ if ((address >= 0xC100) && (address <= 0xC7FF))
+ {
+ const UINT uSlot = (address >> 8) & 0xF;
+ if ((uSlot != 3) && ExpansionRom[uSlot])
+ IO_SELECT |= 1<= 0xC800) && (address <= 0xCFFF))
+ {
+ IO_STROBE = 1;
+ }
+
+ //
+
+ if (IO_SELECT && IO_STROBE)
+ {
+ // Enable Peripheral Expansion ROM
+ UINT uSlot=1;
+ for (; uSlot= 0xC100) && (address <= 0xC7FF)) // Don't care about state of SW_SLOTC3ROM
+ IO_SELECT_InternalROM = 1;
+ else if ((address >= 0xC800) && (address <= 0xCFFF))
+ IO_STROBE = 1;
+
+ if (!SW_SLOTCXROM && IO_SELECT_InternalROM && IO_STROBE && (g_eExpansionRomType != eExpRomInternal))
+ {
+ // Enable Internal ROM
+ memcpy(mem+0xC800, pCxRomInternal+0x800, 0x800);
+ g_eExpansionRomType = eExpRomInternal;
+ g_uPeripheralRomSlot = 0;
+ }
+ }
+
+ if ((g_eExpansionRomType == eExpRomNull) && (address >= 0xC800))
+ return IO_Null(programcounter, address, write, value, nCycles);
+ else
+ return mem[address];
+}
+
+BYTE __stdcall IOWrite_Cxxx(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles)
+{
+ return 0;
}
//===========================================================================
-void ResetPaging (BOOL initialize) {
- if (!initialize)
- MemSetFastPaging(0);
- lastwriteram = 0;
- memmode = MF_BANK2 | MF_SLOTCXROM | MF_WRITERAM;
- UpdatePaging(initialize,0);
+
+static BYTE g_bmSlotInit = 0;
+
+static void InitIoHandlers()
+{
+ g_bmSlotInit = 0;
+ UINT i=0;
+
+ for (; i<8; i++) // C00x..C07x
+ {
+ IORead[i] = IORead_C0xx[i];
+ IOWrite[i] = IOWrite_C0xx[i];
+ }
+
+ for (; i<16; i++) // C08x..C0Fx
+ {
+ IORead[i] = IO_Null;
+ IOWrite[i] = IO_Null;
+ }
+
+ //
+
+ for (; i<256; i++) // C10x..CFFx
+ {
+ IORead[i] = IORead_Cxxx;
+ IOWrite[i] = IOWrite_Cxxx;
+ }
+
+ //
+
+ IO_SELECT = 0;
+ IO_SELECT_InternalROM = 0;
+ g_eExpansionRomType = eExpRomNull;
+ g_uPeripheralRomSlot = 0;
+
+ for (i=0; i= 3) &&
- ((imagemode[imagenum] & MF_IMAGEMASK) == (memmode & MF_IMAGEMASK))))
- found = 1;
- else
- ++imagenum;
- while ((imagenum <= lastimage) && !found);
- if (found) {
- image = imagenum;
- mem = memimage+(image << 16);
- if (imagemode[image] != memmode) {
- imagemode[image] = memmode;
- UpdatePaging(0,1);
- }
- }
- else {
- if (lastimage < MAXIMAGES-1) {
- imagenum = ++lastimage;
- if (lastimage >= 3)
- VirtualAlloc(memimage+lastimage*0x10000,0x10000,MEM_COMMIT,PAGE_READWRITE);
- }
- else {
- static DWORD nextimage = 0;
- if (nextimage > lastimage)
- nextimage = 0;
- imagenum = nextimage++;
- }
- imagemode[image = imagenum] = memmode;
- mem = memimage+(image << 16);
- UpdatePaging(1,0);
- }
+
+//// Only called by MemSetFastPaging()
+//void BackMainImage ()
+//{
+// for (UINT loop = 0; loop < 256; loop++)
+// {
+// if (memshadow[loop] && ((*(memdirty+loop) & 1) || (loop <= 1)))
+// CopyMemory(memshadow[loop],memimage+(loop << 8),256);
+//
+// *(memdirty+loop) &= ~1;
+// }
+//}
+
+//===========================================================================
+
+void ResetPaging (BOOL initialize)
+{
+ //if (!initialize)
+ // MemSetFastPaging(0);
+
+ lastwriteram = 0;
+ memmode = MF_BANK2 | MF_SLOTCXROM | MF_WRITERAM;
+ UpdatePaging(initialize, 0);
}
//===========================================================================
-void UpdatePaging (BOOL initialize, BOOL updatewriteonly) {
+//void UpdateFastPaging () {
+// BOOL found = 0;
+// DWORD imagenum = 0;
+// do
+// if ((imagemode[imagenum] == memmode) ||
+// ((lastimage >= 3) &&
+// ((imagemode[imagenum] & MF_IMAGEMASK) == (memmode & MF_IMAGEMASK))))
+// found = 1;
+// else
+// ++imagenum;
+// while ((imagenum <= lastimage) && !found);
+// if (found) {
+// image = imagenum;
+// mem = memimage+(image << 16);
+// if (imagemode[image] != memmode) {
+// imagemode[image] = memmode;
+// UpdatePaging(0,1);
+// }
+// }
+// else {
+// if (lastimage < MAXIMAGES-1) {
+// imagenum = ++lastimage;
+// if (lastimage >= 3)
+// VirtualAlloc(memimage+lastimage*0x10000,0x10000,MEM_COMMIT,PAGE_READWRITE);
+// }
+// else {
+// static DWORD nextimage = 0;
+// if (nextimage > lastimage)
+// nextimage = 0;
+// imagenum = nextimage++;
+// }
+// imagemode[image = imagenum] = memmode;
+// mem = memimage+(image << 16);
+// UpdatePaging(1,0);
+// }
+//}
- // SAVE THE CURRENT PAGING SHADOW TABLE
- LPBYTE oldshadow[256];
- if (!(initialize || fastpaging || updatewriteonly))
- CopyMemory(oldshadow,memshadow[image],256*sizeof(LPBYTE));
+//===========================================================================
- // UPDATE THE PAGING TABLES BASED ON THE NEW PAGING SWITCH VALUES
- int loop;
- if (initialize) {
- for (loop = 0; loop < 192; loop++)
- memwrite[image][loop] = mem+(loop << 8);
- for (loop = 192; loop < 208; loop++) // TC: [0xC000..0xCF00]
- memwrite[image][loop] = NULL;
- }
- if (!updatewriteonly)
- for (loop = 0; loop < 2; loop++)
- memshadow[image][loop] = SW_ALTZP ? memaux+(loop << 8) : memmain+(loop << 8);
- for (loop = 2; loop < 192; loop++) {
- memshadow[image][loop] = SW_AUXREAD ? memaux+(loop << 8)
- : memmain+(loop << 8);
- memwrite[image][loop] = ((SW_AUXREAD != 0) == (SW_AUXWRITE != 0))
- ? mem+(loop << 8)
- : SW_AUXWRITE ? memaux+(loop << 8)
- : memmain+(loop << 8);
- }
- if (!updatewriteonly) {
- for (loop = 192; loop < 200; loop++)
- if (loop == 195)
- memshadow[image][loop] = (SW_SLOTC3ROM && SW_SLOTCXROM) ? memrom+0x0300
- : memrom+0x1300;
- else
- memshadow[image][loop] = SW_SLOTCXROM ? memrom+(loop << 8)-0xC000
- : memrom+(loop << 8)-0xB000;
- for (loop = 200; loop < 208; loop++)
- memshadow[image][loop] = memrom+(loop << 8)-0xB000;
- }
- for (loop = 208; loop < 224; loop++) {
- int bankoffset = (SW_BANK2 ? 0 : 0x1000);
- memshadow[image][loop] = SW_HIGHRAM ? SW_ALTZP ? memaux+(loop << 8)-bankoffset
- : memmain+(loop << 8)-bankoffset
- : memrom+(loop << 8)-0xB000;
- memwrite[image][loop] = SW_WRITERAM ? SW_HIGHRAM ? mem+(loop << 8)
- : SW_ALTZP ? memaux+(loop << 8)-bankoffset
- : memmain+(loop << 8)-bankoffset
- : NULL;
- }
- for (loop = 224; loop < 256; loop++) {
- memshadow[image][loop] = SW_HIGHRAM ? SW_ALTZP ? memaux+(loop << 8)
- : memmain+(loop << 8)
- : memrom+(loop << 8)-0xB000;
- memwrite[image][loop] = SW_WRITERAM ? SW_HIGHRAM ? mem+(loop << 8)
- : SW_ALTZP ? memaux+(loop << 8)
- : memmain+(loop << 8)
- : NULL;
- }
- if (SW_80STORE) {
- for (loop = 4; loop < 8; loop++) {
- memshadow[image][loop] = SW_PAGE2 ? memaux+(loop << 8)
- : memmain+(loop << 8);
- memwrite[image][loop] = mem+(loop << 8);
- }
- if (SW_HIRES)
- for (loop = 32; loop < 64; loop++) {
- memshadow[image][loop] = SW_PAGE2 ? memaux+(loop << 8)
- : memmain+(loop << 8);
- memwrite[image][loop] = mem+(loop << 8);
- }
- }
+static void UpdatePaging (BOOL initialize, BOOL updatewriteonly)
+{
+ // SAVE THE CURRENT PAGING SHADOW TABLE
+ LPBYTE oldshadow[256];
+ if (!(initialize || updatewriteonly /*|| fastpaging*/ ))
+ CopyMemory(oldshadow,memshadow,256*sizeof(LPBYTE));
- // MOVE MEMORY BACK AND FORTH AS NECESSARY BETWEEN THE SHADOW AREAS AND
- // THE MAIN RAM IMAGE TO KEEP BOTH SETS OF MEMORY CONSISTENT WITH THE NEW
- // PAGING SHADOW TABLE
- if (!updatewriteonly)
- for (loop = 0; loop < 256; loop++)
- if (initialize || (oldshadow[loop] != memshadow[image][loop])) {
- if ((!(initialize || fastpaging)) &&
- ((*(memdirty+loop) & 1) || (loop <= 1))) {
- *(memdirty+loop) &= ~1;
- CopyMemory(oldshadow[loop],mem+(loop << 8),256);
- }
- CopyMemory(mem+(loop << 8),memshadow[image][loop],256);
- }
+ // UPDATE THE PAGING TABLES BASED ON THE NEW PAGING SWITCH VALUES
+ UINT loop;
+ if (initialize)
+ {
+ for (loop = 0x00; loop < 0xC0; loop++)
+ memwrite[loop] = mem+(loop << 8);
+
+ for (loop = 0xC0; loop < 0xD0; loop++)
+ memwrite[loop] = NULL;
+ }
+
+ if (!updatewriteonly)
+ {
+ for (loop = 0x00; loop < 0x02; loop++)
+ memshadow[loop] = SW_ALTZP ? memaux+(loop << 8) : memmain+(loop << 8);
+ }
+
+ for (loop = 0x02; loop < 0xC0; loop++)
+ {
+ memshadow[loop] = SW_AUXREAD ? memaux+(loop << 8)
+ : memmain+(loop << 8);
+
+ memwrite[loop] = ((SW_AUXREAD != 0) == (SW_AUXWRITE != 0))
+ ? mem+(loop << 8)
+ : SW_AUXWRITE ? memaux+(loop << 8)
+ : memmain+(loop << 8);
+ }
+
+ if (!updatewriteonly)
+ {
+ for (loop = 0xC0; loop < 0xC8; loop++)
+ {
+ const UINT uSlotOffset = (loop & 0x0f) * 0x100;
+ if (loop == 0xC3)
+ memshadow[loop] = (SW_SLOTC3ROM && SW_SLOTCXROM) ? pCxRomPeripheral+uSlotOffset // C300..C3FF - Slot 3 ROM (all 0x00's)
+ : pCxRomInternal+uSlotOffset; // C300..C3FF - Internal ROM
+ else
+ memshadow[loop] = SW_SLOTCXROM ? pCxRomPeripheral+uSlotOffset // C000..C7FF - SSC/Disk][/etc
+ : pCxRomInternal+uSlotOffset; // C000..C7FF - Internal ROM
+ }
+
+ for (loop = 0xC8; loop < 0xD0; loop++)
+ {
+ const UINT uRomOffset = (loop & 0x0f) * 0x100;
+ memshadow[loop] = pCxRomInternal+uRomOffset; // C800..CFFF - Internal ROM
+ }
+ }
+
+ for (loop = 0xD0; loop < 0xE0; loop++)
+ {
+ int bankoffset = (SW_BANK2 ? 0 : 0x1000);
+ memshadow[loop] = SW_HIGHRAM ? SW_ALTZP ? memaux+(loop << 8)-bankoffset
+ : memmain+(loop << 8)-bankoffset
+ : memrom+((loop-0xD0) * 0x100);
+
+ memwrite[loop] = SW_WRITERAM ? SW_HIGHRAM ? mem+(loop << 8)
+ : SW_ALTZP ? memaux+(loop << 8)-bankoffset
+ : memmain+(loop << 8)-bankoffset
+ : NULL;
+ }
+
+ for (loop = 0xE0; loop < 0x100; loop++)
+ {
+ memshadow[loop] = SW_HIGHRAM ? SW_ALTZP ? memaux+(loop << 8)
+ : memmain+(loop << 8)
+ : memrom+((loop-0xD0) * 0x100);
+
+ memwrite[loop] = SW_WRITERAM ? SW_HIGHRAM ? mem+(loop << 8)
+ : SW_ALTZP ? memaux+(loop << 8)
+ : memmain+(loop << 8)
+ : NULL;
+ }
+
+ if (SW_80STORE)
+ {
+ for (loop = 0x04; loop < 0x08; loop++)
+ {
+ memshadow[loop] = SW_PAGE2 ? memaux+(loop << 8)
+ : memmain+(loop << 8);
+ memwrite[loop] = mem+(loop << 8);
+ }
+
+ if (SW_HIRES)
+ {
+ for (loop = 0x20; loop < 0x40; loop++)
+ {
+ memshadow[loop] = SW_PAGE2 ? memaux+(loop << 8)
+ : memmain+(loop << 8);
+ memwrite[loop] = mem+(loop << 8);
+ }
+ }
+ }
+
+ // MOVE MEMORY BACK AND FORTH AS NECESSARY BETWEEN THE SHADOW AREAS AND
+ // THE MAIN RAM IMAGE TO KEEP BOTH SETS OF MEMORY CONSISTENT WITH THE NEW
+ // PAGING SHADOW TABLE
+ if (!updatewriteonly)
+ {
+ for (loop = 0x00; loop < 0x100; loop++)
+ {
+ if (initialize || (oldshadow[loop] != memshadow[loop]))
+ {
+ if ((!(initialize/* || fastpaging*/)) &&
+ ((*(memdirty+loop) & 1) || (loop <= 1)))
+ {
+ *(memdirty+loop) &= ~1;
+ CopyMemory(oldshadow[loop],mem+(loop << 8),256);
+ }
+
+ CopyMemory(mem+(loop << 8),memshadow[loop],256);
+ }
+ }
+ }
}
@@ -765,33 +753,45 @@ void UpdatePaging (BOOL initialize, BOOL updatewriteonly) {
//
//===========================================================================
-BYTE __stdcall MemCheckPaging (WORD, BYTE address, BYTE, BYTE, ULONG) {
- BOOL result = 0;
- switch (address) {
- case 0x11: result = SW_BANK2; break;
- case 0x12: result = SW_HIGHRAM; break;
- case 0x13: result = SW_AUXREAD; break;
- case 0x14: result = SW_AUXWRITE; break;
- case 0x15: result = !SW_SLOTCXROM; break;
- case 0x16: result = SW_ALTZP; break;
- case 0x17: result = SW_SLOTC3ROM; break;
- case 0x18: result = SW_80STORE; break;
- case 0x1C: result = SW_PAGE2; break;
- case 0x1D: result = SW_HIRES; break;
- }
- return KeybGetKeycode() | (result ? 0x80 : 0);
+
+// TODO: >= Apple2e only?
+BYTE __stdcall MemCheckPaging (WORD, WORD address, BYTE, BYTE, ULONG)
+{
+ address &= 0xFF;
+ BOOL result = 0;
+ switch (address)
+ {
+ case 0x11: result = SW_BANK2; break;
+ case 0x12: result = SW_HIGHRAM; break;
+ case 0x13: result = SW_AUXREAD; break;
+ case 0x14: result = SW_AUXWRITE; break;
+ case 0x15: result = !SW_SLOTCXROM; break;
+ case 0x16: result = SW_ALTZP; break;
+ case 0x17: result = SW_SLOTC3ROM; break;
+ case 0x18: result = SW_80STORE; break;
+ case 0x1C: result = SW_PAGE2; break;
+ case 0x1D: result = SW_HIRES; break;
+ }
+ return KeybGetKeycode() | (result ? 0x80 : 0);
}
//===========================================================================
-void MemDestroy () {
- if (fastpaging)
- MemSetFastPaging(0);
- VirtualFree(memimage,MAX(0x30000,0x10000*(lastimage+1)),MEM_DECOMMIT);
- VirtualFree(memaux ,0,MEM_RELEASE);
- VirtualFree(memdirty,0,MEM_RELEASE);
- VirtualFree(memimage,0,MEM_RELEASE);
- VirtualFree(memmain ,0,MEM_RELEASE);
- VirtualFree(memrom ,0,MEM_RELEASE);
+
+void MemDestroy ()
+{
+ //if (fastpaging)
+ // MemSetFastPaging(0);
+// VirtualFree(memimage,MAX(0x30000,0x10000*1),MEM_DECOMMIT);
+
+ VirtualFree(memaux ,0,MEM_RELEASE);
+ VirtualFree(memmain ,0,MEM_RELEASE);
+ VirtualFree(memdirty,0,MEM_RELEASE);
+ VirtualFree(memrom ,0,MEM_RELEASE);
+ VirtualFree(memimage,0,MEM_RELEASE);
+
+ VirtualFree(pCxRomInternal,0,MEM_RELEASE);
+ VirtualFree(pCxRomPeripheral,0,MEM_RELEASE);
+
#ifdef RAMWORKS
for (UINT i=1; i> 8)] == (memaux+(offset & 0xFF00)))
+ LPBYTE lpMem = (memshadow[(offset >> 8)] == (memaux+(offset & 0xFF00)))
? mem+offset
: memaux+offset;
@@ -833,7 +846,7 @@ LPBYTE MemGetAuxPtr (WORD offset)
((offset & 0xFF00)<=0700) ) ||
( SW_HIRES && ((offset & 0xFF00)>=0x2000) &&
((offset & 0xFF00)<=0x3F00) ) ) ) {
- lpMem = (memshadow[image][(offset >> 8)] == (RWpages[0]+(offset & 0xFF00)))
+ lpMem = (memshadow[(offset >> 8)] == (RWpages[0]+(offset & 0xFF00)))
? mem+offset
: RWpages[0]+offset;
}
@@ -843,28 +856,44 @@ LPBYTE MemGetAuxPtr (WORD offset)
}
//===========================================================================
-LPBYTE MemGetMainPtr (WORD offset) {
- return (memshadow[image][(offset >> 8)] == (memmain+(offset & 0xFF00)))
+LPBYTE MemGetMainPtr (WORD offset)
+{
+ return (memshadow[(offset >> 8)] == (memmain+(offset & 0xFF00)))
? mem+offset
: memmain+offset;
}
//===========================================================================
-void MemInitialize () {
- // ALLOCATE MEMORY FOR THE APPLE MEMORY IMAGE AND ASSOCIATED DATA STRUCTURES
- //
- // THE MEMIMAGE BUFFER CAN CONTAIN EITHER MULTIPLE MEMORY IMAGES OR
- // ONE MEMORY IMAGE WITH COMPILER DATA
- memaux = (LPBYTE)VirtualAlloc(NULL,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE); // _6502_MEM_END // 0x10000
- memdirty = (LPBYTE)VirtualAlloc(NULL,0x100 ,MEM_COMMIT,PAGE_READWRITE);
- memmain = (LPBYTE)VirtualAlloc(NULL,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE);
- memrom = (LPBYTE)VirtualAlloc(NULL,0x5000 ,MEM_COMMIT,PAGE_READWRITE);
- memimage = (LPBYTE)VirtualAlloc(NULL,
- MAX(0x30000,MAXIMAGES*0x10000),
- MEM_RESERVE,PAGE_NOACCESS);
+void MemPreInitialize ()
+{
+ // Init the I/O handlers
+ InitIoHandlers();
+}
- if ((!memaux) || (!memdirty) || (!memimage) || (!memmain) || (!memrom))
+//===========================================================================
+
+void MemInitialize()
+{
+ const UINT CxRomSize = 4*1024;
+ const UINT Apple2RomSize = 12*1024;
+ const UINT Apple2eRomSize = Apple2RomSize+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);
+ memdirty = (LPBYTE)VirtualAlloc(NULL,0x100 ,MEM_COMMIT,PAGE_READWRITE);
+ memrom = (LPBYTE)VirtualAlloc(NULL,0x5000 ,MEM_COMMIT,PAGE_READWRITE);
+// // THE MEMIMAGE BUFFER CAN CONTAIN EITHER MULTIPLE MEMORY IMAGES OR ONE MEMORY IMAGE WITH COMPILER DATA
+// memimage = (LPBYTE)VirtualAlloc(NULL,
+// MAX(0x30000,MAXIMAGES*0x10000),
+// MEM_RESERVE,PAGE_NOACCESS);
+ memimage = (LPBYTE)VirtualAlloc(NULL,_6502_MEM_END+1,MEM_RESERVE,PAGE_NOACCESS);
+
+ pCxRomInternal = (LPBYTE) VirtualAlloc(NULL, CxRomSize, MEM_COMMIT, PAGE_READWRITE);
+ pCxRomPeripheral = (LPBYTE) VirtualAlloc(NULL, CxRomSize, MEM_COMMIT, PAGE_READWRITE);
+
+ if (!memaux || !memdirty || !memimage || !memmain || !memrom || !pCxRomInternal || !pCxRomPeripheral)
{
MessageBox(
GetDesktopWindow(),
@@ -875,7 +904,8 @@ void MemInitialize () {
ExitProcess(1);
}
- LPVOID newloc = VirtualAlloc(memimage,0x30000,MEM_COMMIT,PAGE_READWRITE);
+// LPVOID newloc = VirtualAlloc(memimage,0x30000,MEM_COMMIT,PAGE_READWRITE);
+ LPVOID newloc = VirtualAlloc(memimage,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE);
if (newloc != memimage)
MessageBox(
GetDesktopWindow(),
@@ -890,32 +920,34 @@ void MemInitialize () {
// allocate memory for RAMWorks III - up to 8MB
RWpages[0] = memaux;
UINT i = 1;
- while ((i < g_uMaxExPages) && (RWpages[i] = (LPBYTE) VirtualAlloc(NULL,0x10000,MEM_COMMIT,PAGE_READWRITE)))
+ while ((i < g_uMaxExPages) && (RWpages[i] = (LPBYTE) VirtualAlloc(NULL,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE)))
i++;
#endif
// READ THE APPLE FIRMWARE ROMS INTO THE ROM IMAGE
- const UINT ROM_SIZE = 0x5000; // HACK: Magic # -- $C000..$FFFF = 4K .. why 5K?
-
- HRSRC hResInfo =
- g_bApple2e
- ? FindResource(NULL, MAKEINTRESOURCE(IDR_APPLE2E_ROM), "ROM")
- : (g_bApple2plus
- ? FindResource(NULL, MAKEINTRESOURCE(IDR_APPLE2PLUS_ROM), "ROM")
- : FindResource(NULL, MAKEINTRESOURCE(IDR_APPLE2ORIG_ROM), "ROM") );
+ UINT ROM_SIZE = 0;
+ HRSRC hResInfo = NULL;
+ switch (g_Apple2Type)
+ {
+ case A2TYPE_APPLE2: hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_APPLE2_ROM), "ROM"); ROM_SIZE = Apple2RomSize; break;
+ case A2TYPE_APPLE2PLUS: hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_APPLE2_PLUS_ROM), "ROM"); ROM_SIZE = Apple2RomSize; break;
+ case A2TYPE_APPLE2E: hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_APPLE2E_ROM), "ROM"); ROM_SIZE = Apple2eRomSize; break;
+ case A2TYPE_APPLE2EEHANCED: hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_APPLE2E_ENHANCED_ROM), "ROM"); ROM_SIZE = Apple2eRomSize; break;
+ }
if(hResInfo == NULL)
{
TCHAR sRomFileName[ MAX_PATH ];
- _tcscpy( sRomFileName,
- g_bApple2e
- ? TEXT("APPLE2E.ROM")
- : (g_bApple2plus
- ? TEXT("APPLE2PLUS.ROM")
- : TEXT("APPLE2ORIG.ROM")));
+ switch (g_Apple2Type)
+ {
+ case A2TYPE_APPLE2: _tcscpy(sRomFileName, TEXT("APPLE2.ROM")); break;
+ case A2TYPE_APPLE2PLUS: _tcscpy(sRomFileName, TEXT("APPLE2_PLUS.ROM")); break;
+ case A2TYPE_APPLE2E: _tcscpy(sRomFileName, TEXT("APPLE2E.ROM")); break;
+ case A2TYPE_APPLE2EEHANCED: _tcscpy(sRomFileName, TEXT("APPLE2E_ENHANCED.ROM")); break;
+ }
TCHAR sText[ MAX_PATH ];
- wsprintf( sText, TEXT("Unable to open the required firmware ROM data file.\n\nFile: %s."), sRomFileName );
+ wsprintf( sText, TEXT("Unable to open the required firmware ROM data file.\n\nFile: %s"), sRomFileName );
MessageBox(
GetDesktopWindow(),
@@ -937,15 +969,30 @@ void MemInitialize () {
if (pData == NULL)
return;
- memcpy(memrom, pData, ROM_SIZE);
+ //
- // TODO/FIXME: HACK! REMOVE A WAIT ROUTINE FROM THE DISK CONTROLLER'S FIRMWARE
- *(memrom+0x064C) = 0xA9;
- *(memrom+0x064D) = 0x00;
- *(memrom+0x064E) = 0xEA;
+ memset(pCxRomInternal,0,CxRomSize);
+ memset(pCxRomPeripheral,0,CxRomSize);
- HD_Load_Rom(memrom); // HDD f/w gets loaded to $C700
- PrintLoadRom(memrom); // parallel printer firmware gets loaded to $C100
+ if (ROM_SIZE == Apple2eRomSize)
+ {
+ memcpy(pCxRomInternal, pData, CxRomSize);
+ pData += CxRomSize;
+ ROM_SIZE -= CxRomSize;
+ }
+
+ _ASSERT(ROM_SIZE == Apple2RomSize);
+ memcpy(memrom, pData, Apple2RomSize); // ROM at $D000...$FFFF
+
+ //
+
+ const UINT uSlot = 0;
+ RegisterIoHandler(uSlot, MemSetPaging, MemSetPaging, NULL, NULL, NULL, NULL);
+
+ PrintLoadRom(pCxRomPeripheral, 1); // $C100 : Parallel printer f/w
+ sg_SSC.CommInitialize(pCxRomPeripheral, 2); // $C200 : SSC
+ DiskLoadRom(pCxRomPeripheral, 6); // $C600 : Disk][ f/w
+ HD_Load_Rom(pCxRomPeripheral, 7); // $C700 : HDD f/w
MemReset();
}
@@ -953,16 +1000,17 @@ void MemInitialize () {
//===========================================================================
// Called by:
+// . MemInitialize()
// . ResetMachineState() eg. Power-cycle ('Apple-Go' button)
// . Snapshot_LoadState()
void MemReset ()
{
- // TURN OFF FAST PAGING IF IT IS CURRENTLY ACTIVE
- MemSetFastPaging(0);
+ //// TURN OFF FAST PAGING IF IT IS CURRENTLY ACTIVE
+ //MemSetFastPaging(0);
// INITIALIZE THE PAGING TABLES
- ZeroMemory(memshadow,MAXIMAGES*256*sizeof(LPBYTE));
- ZeroMemory(memwrite ,MAXIMAGES*256*sizeof(LPBYTE));
+ ZeroMemory(memshadow,256*sizeof(LPBYTE));
+ ZeroMemory(memwrite ,256*sizeof(LPBYTE));
// INITIALIZE THE RAM IMAGES
ZeroMemory(memaux ,0x10000);
@@ -985,13 +1033,14 @@ void MemReset ()
// SET UP THE MEMORY IMAGE
mem = memimage;
- image = 0;
-
- // INITIALIZE & RESET THE CPU
- CpuInitialize();
+ //image = 0;
// INITIALIZE PAGING, FILLING IN THE 64K MEMORY IMAGE
ResetPaging(1);
+
+ // INITIALIZE & RESET THE CPU
+ // . Do this after ROM has been copied back to mem[], so that PC is correctly init'ed from 6502's reset vector
+ CpuInitialize();
}
//===========================================================================
@@ -1005,7 +1054,10 @@ void MemResetPaging ()
}
//===========================================================================
-BYTE MemReturnRandomData (BYTE highbit) {
+
+// Called by Disk][ I/O only
+BYTE MemReturnRandomData (BYTE highbit)
+{
static const BYTE retval[16] = {0x00,0x2D,0x2D,0x30,0x30,0x32,0x32,0x34,
0x35,0x39,0x43,0x43,0x43,0x60,0x7F,0x7F};
BYTE r = (BYTE)(rand() & 0xFF);
@@ -1031,27 +1083,29 @@ BYTE MemReadFloatingBus(BYTE const highbit)
}
//===========================================================================
-void MemSetFastPaging (BOOL on) {
- if (fastpaging && modechanging) {
- modechanging = 0;
- UpdateFastPaging();
- }
- else if (!fastpaging) {
- BackMainImage();
- if (lastimage >= 3)
- VirtualFree(memimage+0x30000,(lastimage-2) << 16,MEM_DECOMMIT);
- }
- fastpaging = on;
- image = 0;
- mem = memimage;
- lastimage = 0;
- imagemode[0] = memmode;
- if (!fastpaging)
- UpdatePaging(1,0);
-}
+//void MemSetFastPaging (BOOL on) {
+// if (fastpaging && modechanging) {
+// modechanging = 0;
+// UpdateFastPaging();
+// }
+// else if (!fastpaging) {
+// BackMainImage();
+// if (lastimage >= 3)
+// VirtualFree(memimage+0x30000,(lastimage-2) << 16,MEM_DECOMMIT);
+// }
+// fastpaging = on;
+// image = 0;
+// mem = memimage;
+// lastimage = 0;
+// imagemode[0] = memmode;
+// if (!fastpaging)
+// UpdatePaging(1,0);
+//}
//===========================================================================
-BYTE __stdcall MemSetPaging (WORD programcounter, BYTE address, BYTE write, BYTE value, ULONG) {
+BYTE __stdcall MemSetPaging (WORD programcounter, WORD address, BYTE write, BYTE value, ULONG)
+{
+ address &= 0xFF;
DWORD lastmemmode = memmode;
// DETERMINE THE NEW MEMORY PAGING MODE.
@@ -1068,7 +1122,7 @@ BYTE __stdcall MemSetPaging (WORD programcounter, BYTE address, BYTE write, BYTE
memmode |= MF_HIGHRAM;
lastwriteram = writeram;
}
- else if (g_bApple2e)
+ else if (!IS_APPLE2)
{
switch (address)
{
@@ -1096,14 +1150,10 @@ BYTE __stdcall MemSetPaging (WORD programcounter, BYTE address, BYTE write, BYTE
memaux = RWpages[value];
//memmode &= ~MF_RWPMASK;
//memmode |= value;
- if (fastpaging)
- {
- UpdateFastPaging();
- }
- else
- {
+ //if (fastpaging)
+ // UpdateFastPaging();
+ //else
UpdatePaging(0,0);
- }
}
break;
#endif
@@ -1127,20 +1177,41 @@ BYTE __stdcall MemSetPaging (WORD programcounter, BYTE address, BYTE write, BYTE
// IF THE MEMORY PAGING MODE HAS CHANGED, UPDATE OUR MEMORY IMAGES AND
// WRITE TABLES.
- if ((lastmemmode != memmode) || modechanging) {
+ if ((lastmemmode != memmode) || modechanging)
+ {
modechanging = 0;
- // IF FAST PAGING IS ACTIVE, WE KEEP MULTIPLE COMPLETE MEMORY IMAGES
- // AND WRITE TABLES, AND SWITCH BETWEEN THEM. THE FAST PAGING VERSION
- // OF THE CPU EMULATOR KEEPS ALL OF THE IMAGES COHERENT.
- if (fastpaging)
- UpdateFastPaging();
+ if ((lastmemmode & MF_SLOTCXROM) != (memmode & MF_SLOTCXROM))
+ {
+ if (SW_SLOTCXROM)
+ {
+ // Disable Internal ROM
+ // . Similar to $CFFF access
+ // . None of the peripheral cards can be driving the bus - so use the null ROM
+ memset(pCxRomPeripheral+0x800, 0, 0x800);
+ memset(mem+0xC800, 0, 0x800);
+ g_eExpansionRomType = eExpRomNull;
+ g_uPeripheralRomSlot = 0;
+ }
+ else
+ {
+ // Enable Internal ROM
+ memcpy(mem+0xC800, pCxRomInternal+0x800, 0x800);
+ g_eExpansionRomType = eExpRomInternal;
+ g_uPeripheralRomSlot = 0;
+ }
+ }
+
+ //// IF FAST PAGING IS ACTIVE, WE KEEP MULTIPLE COMPLETE MEMORY IMAGES
+ //// AND WRITE TABLES, AND SWITCH BETWEEN THEM. THE FAST PAGING VERSION
+ //// OF THE CPU EMULATOR KEEPS ALL OF THE IMAGES COHERENT.
+ //if (fastpaging)
+ // UpdateFastPaging();
// IF FAST PAGING IS NOT ACTIVE THEN WE KEEP ONLY ONE MEMORY IMAGE AND
// WRITE TABLE, AND UPDATE THEM EVERY TIME PAGING IS CHANGED.
- else {
+ //else
UpdatePaging(0,0);
- }
}
@@ -1151,86 +1222,39 @@ BYTE __stdcall MemSetPaging (WORD programcounter, BYTE address, BYTE write, BYTE
}
//===========================================================================
-void MemTrimImages () {
- if (fastpaging && (lastimage > 2)) {
- if (modechanging) {
- modechanging = 0;
- UpdateFastPaging();
- }
- static DWORD trimnumber = 0;
- if ((image != trimnumber) &&
- (image != lastimage) &&
- (trimnumber < lastimage)) {
- imagemode[trimnumber] = imagemode[lastimage];
- VirtualFree(memimage+(lastimage-- << 16),0x10000,MEM_DECOMMIT);
- DWORD realimage = image;
- image = trimnumber;
- mem = memimage+(image << 16);
- memmode = imagemode[image];
- UpdatePaging(1,0);
- image = realimage;
- mem = memimage+(image << 16);
- memmode = imagemode[image];
- }
- if (++trimnumber >= lastimage)
- trimnumber = 0;
- }
-}
+//void MemTrimImages () {
+// if (fastpaging && (lastimage > 2))
+// {
+// if (modechanging) {
+// modechanging = 0;
+// UpdateFastPaging();
+// }
+// static DWORD trimnumber = 0;
+// if ((image != trimnumber) &&
+// (image != lastimage) &&
+// (trimnumber < lastimage)) {
+// imagemode[trimnumber] = imagemode[lastimage];
+// VirtualFree(memimage+(lastimage-- << 16),0x10000,MEM_DECOMMIT);
+// DWORD realimage = image;
+// image = trimnumber;
+// mem = memimage+(image << 16);
+// memmode = imagemode[image];
+// UpdatePaging(1,0);
+// image = realimage;
+// mem = memimage+(image << 16);
+// memmode = imagemode[image];
+// }
+// if (++trimnumber >= lastimage)
+// trimnumber = 0;
+// }
+//}
//===========================================================================
-BYTE __stdcall CxReadFunc(WORD, WORD nAddr, BYTE, BYTE, ULONG nCyclesLeft)
+LPVOID MemGetSlotParameters (UINT uSlot)
{
- USHORT nPage = nAddr>>8; // Don't use BYTE - Bug in VC++ 6.0 (SP5)!
-
- CpuCalcCycles(nCyclesLeft);
-
- if(!g_bApple2e || SW_SLOTCXROM)
- {
- if((nPage == 0xC4) || (nPage == 0xC5))
- {
- // Slot 4 or 5: Mockingboard
- return MB_Read(nAddr);
- }
- else
- {
- return mem[nAddr];
- }
- }
- else
- {
-#if _DEBUG
- // Gets triggered by opcode $29 (IMM AND) by internal emulation code
-// if((nPage == 0xC4) || (nPage == 0xC5))
-// _ASSERT(0);
-#endif
- return mem[nAddr];
- }
-}
-
-BYTE __stdcall CxWriteFunc(WORD, WORD nAddr, BYTE, BYTE nValue, ULONG nCyclesLeft)
-{
- BYTE nPage = nAddr>>8;
-
- CpuCalcCycles(nCyclesLeft);
-
- if(!g_bApple2e || SW_SLOTCXROM)
- {
- if((nPage == 0xC4) || (nPage == 0xC5))
- {
- // Slot 4 or 5: Mockingboard
- MB_Write(nAddr, nValue);
- }
- }
-#if _DEBUG
- else
- {
- if((nPage == 0xC4) || (nPage == 0xC5))
- _ASSERT(0);
- }
-#endif
-
- return 0;
+ _ASSERT(uSlot < NUM_SLOTS);
+ return SlotParameters[uSlot];
}
//===========================================================================
diff --git a/AppleWin/source/Memory.h b/AppleWin/source/Memory.h
index 97ab21f5..892eb1f3 100644
--- a/AppleWin/source/Memory.h
+++ b/AppleWin/source/Memory.h
@@ -9,12 +9,9 @@ enum MemoryInitPattern_e
};
extern MemoryInitPattern_e g_eMemoryInitPattern;
-extern iofunction ioread[0x100];
-extern iofunction iowrite[0x100];
-extern LPBYTE memshadow[MAXIMAGES][0x100];
-extern LPBYTE memwrite[MAXIMAGES][0x100];
-extern DWORD image;
-extern DWORD lastimage;
+extern iofunction IORead[256];
+extern iofunction IOWrite[256];
+extern LPBYTE memwrite[0x100];
extern LPBYTE mem;
extern LPBYTE memdirty;
@@ -22,10 +19,14 @@ extern LPBYTE memdirty;
extern UINT g_uMaxExPages; // user requested ram pages (from cmd line)
#endif
+void RegisterIoHandler(UINT uSlot, iofunction IOReadC0, iofunction IOWriteC0, iofunction IOReadCx, iofunction IOWriteCx, LPVOID lpSlotParameter, BYTE* pExpansionRom);
+
void MemDestroy ();
bool MemGet80Store();
+bool MemCheckSLOTCXROM();
LPBYTE MemGetAuxPtr (WORD);
LPBYTE MemGetMainPtr (WORD);
+void MemPreInitialize ();
void MemInitialize ();
BYTE MemReadFloatingBus();
BYTE MemReadFloatingBus(BYTE highbit);
@@ -34,11 +35,11 @@ void MemResetPaging ();
BYTE MemReturnRandomData (BYTE highbit);
void MemSetFastPaging (BOOL);
void MemTrimImages ();
+LPVOID MemGetSlotParameters (UINT uSlot);
DWORD MemGetSnapshot(SS_BaseMemory* pSS);
DWORD MemSetSnapshot(SS_BaseMemory* pSS);
-BYTE __stdcall CxReadFunc(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
-BYTE __stdcall CxWriteFunc(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+BYTE __stdcall IO_Null(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles);
-BYTE __stdcall MemCheckPaging (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
-BYTE __stdcall MemSetPaging (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+BYTE __stdcall MemCheckPaging (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+BYTE __stdcall MemSetPaging(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
diff --git a/AppleWin/source/Mockingboard.cpp b/AppleWin/source/Mockingboard.cpp
index 3a1c3378..58f918e1 100644
--- a/AppleWin/source/Mockingboard.cpp
+++ b/AppleWin/source/Mockingboard.cpp
@@ -1269,6 +1269,10 @@ static void MB_DSUninit()
//=============================================================================
+static BYTE __stdcall PhasorIO (WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, ULONG nCyclesLeft);
+static BYTE __stdcall MB_Read(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, ULONG nCyclesLeft);
+static BYTE __stdcall MB_Write(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, ULONG nCyclesLeft);
+
void MB_Initialize()
{
if(g_bDisableDirectSound)
@@ -1300,6 +1304,14 @@ void MB_Initialize()
//
g_bMB_Active = (g_SoundcardType != SC_NONE);
+
+ //
+
+ const UINT uSlot4 = 4;
+ RegisterIoHandler(uSlot4, PhasorIO, PhasorIO, MB_Read, MB_Write, NULL, NULL);
+
+ const UINT uSlot5 = 5;
+ RegisterIoHandler(uSlot5, PhasorIO, PhasorIO, MB_Read, MB_Write, NULL, NULL);
}
//-----------------------------------------------------------------------------
@@ -1340,8 +1352,13 @@ void MB_Reset()
//-----------------------------------------------------------------------------
-BYTE MB_Read(WORD nAddr)
+static BYTE __stdcall MB_Read(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, ULONG nCyclesLeft)
{
+ CpuCalcCycles(nCyclesLeft);
+
+ if(!IS_APPLE2 && !MemCheckSLOTCXROM())
+ return mem[nAddr];
+
if(g_SoundcardType == SC_NONE)
return 0;
@@ -1385,10 +1402,15 @@ BYTE MB_Read(WORD nAddr)
//-----------------------------------------------------------------------------
-void MB_Write(WORD nAddr, BYTE nValue)
+static BYTE __stdcall MB_Write(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, ULONG nCyclesLeft)
{
+ CpuCalcCycles(nCyclesLeft);
+
+ if(!IS_APPLE2 && !MemCheckSLOTCXROM())
+ return 0;
+
if(g_SoundcardType == SC_NONE)
- return;
+ return 0;
BYTE nMB = (nAddr>>8)&0xf - SLOT4;
BYTE nOffset = nAddr&0xff;
@@ -1396,7 +1418,7 @@ void MB_Write(WORD nAddr, BYTE nValue)
if(g_bPhasorEnable)
{
if(nMB != 0) // Slot4 only
- return;
+ return 0;
int CS;
@@ -1414,7 +1436,7 @@ void MB_Write(WORD nAddr, BYTE nValue)
if((nOffset >= SSI263_Offset) && (nOffset <= (SSI263_Offset+0x05)))
SSI263_Write(nMB*2+1, nAddr&0xf, nValue); // Second 6522 is used for speech chip
- return;
+ return 0;
}
if(nOffset <= (SY6522A_Offset+0x0F))
@@ -1423,19 +1445,21 @@ void MB_Write(WORD nAddr, BYTE nValue)
SY6522_Write(nMB*NUM_DEVS_PER_MB + SY6522_DEVICE_B, nAddr&0xf, nValue);
else if((nOffset >= SSI263_Offset) && (nOffset <= (SSI263_Offset+0x05)))
SSI263_Write(nMB*2+1, nAddr&0xf, nValue); // Second 6522 is used for speech chip
+
+ return 0;
}
//-----------------------------------------------------------------------------
-BYTE __stdcall PhasorIO (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
+static BYTE __stdcall PhasorIO (WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, ULONG nCyclesLeft)
{
if(!g_bPhasorEnable)
return 0;
if(g_nPhasorMode < 2)
- g_nPhasorMode = addr & 1;
+ g_nPhasorMode = nAddr & 1;
- double fCLK = (addr & 4) ? CLK_6502*2 : CLK_6502;
+ double fCLK = (nAddr & 4) ? CLK_6502*2 : CLK_6502;
AY8910_InitClock((int)fCLK);
diff --git a/AppleWin/source/Mockingboard.h b/AppleWin/source/Mockingboard.h
index d35c5612..4953473f 100644
--- a/AppleWin/source/Mockingboard.h
+++ b/AppleWin/source/Mockingboard.h
@@ -7,8 +7,6 @@ void MB_Initialize();
void MB_Reinitialize();
void MB_Destroy();
void MB_Reset();
-BYTE MB_Read(WORD nAddr);
-void MB_Write(WORD nAddr, BYTE nValue);
void MB_Mute();
void MB_Demute();
void MB_EndOfFrame();
@@ -22,5 +20,3 @@ 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);
-
-BYTE __stdcall PhasorIO (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
diff --git a/AppleWin/source/ParallelPrinter.cpp b/AppleWin/source/ParallelPrinter.cpp
index 67ec7772..bf7be84a 100644
--- a/AppleWin/source/ParallelPrinter.cpp
+++ b/AppleWin/source/ParallelPrinter.cpp
@@ -35,9 +35,13 @@ static FILE* file = NULL;
DWORD const PRINTDRVR_SIZE = 0x100;
//===========================================================================
-VOID PrintLoadRom(LPBYTE lpMemRom)
+
+static BYTE __stdcall PrintStatus(WORD, WORD, BYTE, BYTE, ULONG);
+static BYTE __stdcall PrintTransmit(WORD, WORD, BYTE, BYTE value, ULONG);
+
+VOID PrintLoadRom(LPBYTE pCxRomPeripheral, const UINT uSlot)
{
- HRSRC hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_PRINTDRVR), "FIRMWARE");
+ HRSRC hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_PRINTDRVR_FW), "FIRMWARE");
if(hResInfo == NULL)
return;
@@ -53,7 +57,11 @@ VOID PrintLoadRom(LPBYTE lpMemRom)
if(pData == NULL)
return;
- memcpy(lpMemRom + 0x100, pData, PRINTDRVR_SIZE);
+ memcpy(pCxRomPeripheral + uSlot*256, pData, PRINTDRVR_SIZE);
+
+ //
+
+ RegisterIoHandler(uSlot, PrintStatus, PrintTransmit, NULL, NULL, NULL, NULL);
}
//===========================================================================
@@ -108,14 +116,14 @@ void PrintReset()
}
//===========================================================================
-BYTE __stdcall PrintStatus(WORD, BYTE, BYTE, BYTE, ULONG)
+static BYTE __stdcall PrintStatus(WORD, WORD, BYTE, BYTE, ULONG)
{
CheckPrint();
return 0xFF; // status - TODO?
}
//===========================================================================
-BYTE __stdcall PrintTransmit(WORD, BYTE, BYTE, BYTE value, ULONG)
+static BYTE __stdcall PrintTransmit(WORD, WORD, BYTE, BYTE value, ULONG)
{
if (!CheckPrint())
{
diff --git a/AppleWin/source/ParallelPrinter.h b/AppleWin/source/ParallelPrinter.h
index 1c9b88df..b4c57fd8 100644
--- a/AppleWin/source/ParallelPrinter.h
+++ b/AppleWin/source/ParallelPrinter.h
@@ -1,9 +1,6 @@
#pragma once
void PrintDestroy();
-void PrintLoadRom(LPBYTE);
+void PrintLoadRom(LPBYTE pCxRomPeripheral, UINT uSlot);
void PrintReset();
void PrintUpdate(DWORD);
-
-BYTE __stdcall PrintStatus (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
-BYTE __stdcall PrintTransmit (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
diff --git a/AppleWin/source/PropertySheetPage.cpp b/AppleWin/source/PropertySheetPage.cpp
index 3793c4da..bcb90452 100644
--- a/AppleWin/source/PropertySheetPage.cpp
+++ b/AppleWin/source/PropertySheetPage.cpp
@@ -34,10 +34,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "Tfe\Tfesupp.h"
#include "Tfe\Uilib.h"
-
-TCHAR computerchoices[] = TEXT("Apple ][ (Original Model)\0")
- TEXT("Apple ][+\0")
- TEXT("Apple //e\0");
+TCHAR computerchoices[] =
+ TEXT("Apple ][ (Original Model)\0")
+ TEXT("Apple ][+\0")
+ TEXT("Apple //e\0")
+ TEXT("Enhanced Apple //e\0");
TCHAR* szJoyChoice0 = TEXT("Disabled\0");
TCHAR* szJoyChoice1 = TEXT("PC Joystick #1\0");
@@ -203,11 +204,24 @@ static void InitJoystickChoices(HWND window, int nJoyNum, int nIdcValue)
static void ConfigDlg_OK(HWND window, BOOL afterclose)
{
- BOOL newcomptype = (BOOL) SendDlgItemMessage(window,IDC_COMPUTER,CB_GETCURSEL,0,0);
+ eApple2Type NewApple2Type;
+
+ {
+ DWORD newcomptype = (DWORD) SendDlgItemMessage(window,IDC_COMPUTER,CB_GETCURSEL,0,0);
+
+ switch (newcomptype)
+ {
+ case 0: NewApple2Type = A2TYPE_APPLE2; break;
+ case 1: NewApple2Type = A2TYPE_APPLE2PLUS; break;
+ case 2: NewApple2Type = A2TYPE_APPLE2E; break;
+ case 3: NewApple2Type = A2TYPE_APPLE2EEHANCED; break;
+ }
+ }
+
DWORD newvidtype = (DWORD)SendDlgItemMessage(window,IDC_VIDEOTYPE,CB_GETCURSEL,0,0);
DWORD newserialport = (DWORD)SendDlgItemMessage(window,IDC_SERIALPORT,CB_GETCURSEL,0,0);
- if (newcomptype != (g_bApple2e ? 2 : (g_bApple2plus ? 1 : 0)))
+ if (NewApple2Type != g_Apple2Type)
{
if (MessageBox(window,
TEXT(
@@ -228,7 +242,8 @@ static void ConfigDlg_OK(HWND window, BOOL afterclose)
if ((g_nAppMode != MODE_LOGO) && (g_nAppMode != MODE_DEBUG))
VideoRedrawScreen();
}
- CommSetSerialPort(window,newserialport);
+
+ sg_SSC.CommSetSerialPort(window,newserialport);
if (IsDlgButtonChecked(window,IDC_AUTHENTIC_SPEED))
g_dwSpeed = SPEED_NORMAL;
@@ -237,8 +252,8 @@ static void ConfigDlg_OK(HWND window, BOOL afterclose)
SetCurrentCLK6502();
- SAVE(TEXT("Computer Emulation"),newcomptype);
- SAVE(TEXT("Serial Port") ,serialport);
+ SAVE(TEXT(REGVALUE_APPLE2_TYPE),NewApple2Type);
+ SAVE(TEXT("Serial Port") ,sg_SSC.GetSerialPort());
SAVE(TEXT("Custom Speed") ,IsDlgButtonChecked(window,IDC_CUSTOM_SPEED));
SAVE(TEXT("Emulation Speed") ,g_dwSpeed);
SAVE(TEXT("Video Emulation") ,videotype);
@@ -342,9 +357,18 @@ static BOOL CALLBACK ConfigDlgProc (HWND window,
{
g_nLastPage = PG_CONFIG;
- FillComboBox(window,IDC_COMPUTER,computerchoices,g_bApple2e ? 2 : (g_bApple2plus ? 1 : 0));
+ UINT iApple2String;
+ switch (g_Apple2Type)
+ {
+ case A2TYPE_APPLE2: iApple2String = 0; break;
+ case A2TYPE_APPLE2PLUS: iApple2String = 1; break;
+ case A2TYPE_APPLE2E: iApple2String = 2; break;
+ case A2TYPE_APPLE2EEHANCED: iApple2String = 3; break;
+ }
+
+ FillComboBox(window,IDC_COMPUTER,computerchoices,iApple2String);
FillComboBox(window,IDC_VIDEOTYPE,videochoices,videotype);
- FillComboBox(window,IDC_SERIALPORT,serialchoices,serialport);
+ FillComboBox(window,IDC_SERIALPORT,serialchoices,sg_SSC.GetSerialPort());
SendDlgItemMessage(window,IDC_SLIDER_CPU_SPEED,TBM_SETRANGE,1,MAKELONG(0,40));
SendDlgItemMessage(window,IDC_SLIDER_CPU_SPEED,TBM_SETPAGESIZE,0,5);
SendDlgItemMessage(window,IDC_SLIDER_CPU_SPEED,TBM_SETTICFREQ,10,0);
diff --git a/AppleWin/source/SaveState.cpp b/AppleWin/source/SaveState.cpp
index 3507dfec..25a064c7 100644
--- a/AppleWin/source/SaveState.cpp
+++ b/AppleWin/source/SaveState.cpp
@@ -116,7 +116,7 @@ void Snapshot_LoadState()
// Reset all sub-systems
MemReset();
- if (g_bApple2e)
+ if (!IS_APPLE2)
MemResetPaging();
DiskReset();
@@ -129,7 +129,7 @@ void Snapshot_LoadState()
//
CpuSetSnapshot(&pSS->Apple2Unit.CPU6502);
- CommSetSnapshot(&pSS->Apple2Unit.Comms);
+ sg_SSC.CommSetSnapshot(&pSS->Apple2Unit.Comms);
JoySetSnapshot(&pSS->Apple2Unit.Joystick);
KeybSetSnapshot(&pSS->Apple2Unit.Keyboard);
SpkrSetSnapshot(&pSS->Apple2Unit.Speaker);
@@ -186,7 +186,7 @@ void Snapshot_SaveState()
pSS->Apple2Unit.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,0);
CpuGetSnapshot(&pSS->Apple2Unit.CPU6502);
- CommGetSnapshot(&pSS->Apple2Unit.Comms);
+ sg_SSC.CommGetSnapshot(&pSS->Apple2Unit.Comms);
JoyGetSnapshot(&pSS->Apple2Unit.Joystick);
KeybGetSnapshot(&pSS->Apple2Unit.Keyboard);
SpkrGetSnapshot(&pSS->Apple2Unit.Speaker);
diff --git a/AppleWin/source/SerialComms.cpp b/AppleWin/source/SerialComms.cpp
index 21cafa66..74517cae 100644
--- a/AppleWin/source/SerialComms.cpp
+++ b/AppleWin/source/SerialComms.cpp
@@ -40,72 +40,165 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "StdAfx.h"
#pragma hdrstop
+#include "..\resource\resource.h"
//#define SUPPORT_MODEM
-static DWORD baudrate = CBR_19200;
-static BYTE bytesize = 8;
-static BYTE commandbyte = 0x00;
-static HANDLE commhandle = INVALID_HANDLE_VALUE;
-static DWORD comminactivity = 0;
-static BYTE controlbyte = 0x1F;
-static BYTE parity = NOPARITY;
-DWORD serialport = 0;
-static BYTE stopbits = ONESTOPBIT;
+// Default: 19200-8-N-1
+// Maybe a better default is: 9600-7-N-1 (for HyperTrm)
+SSC_DIPSW CSuperSerialCard::m_DIPSWDefault =
+{
+ // DIPSW1:
+ CBR_19200,
+ FWMODE_CIC,
-//
-
-static CRITICAL_SECTION g_CriticalSection; // To guard /g_vRecvBytes/
-static BYTE g_RecvBuffer[uRecvBufferSize]; // NB: More work required if >1 is used
-static volatile DWORD g_vRecvBytes = 0;
-
-//
-
-static bool g_bTxIrqEnabled = false;
-static bool g_bRxIrqEnabled = false;
-
-static bool g_bWrittenTx = false;
-
-//
-
-static volatile bool g_vbCommIRQ = false;
-static HANDLE g_hCommThread = NULL;
-
-enum {COMMEVT_WAIT=0, COMMEVT_ACK, COMMEVT_TERM, COMMEVT_MAX};
-static HANDLE g_hCommEvent[COMMEVT_MAX] = {NULL};
-static OVERLAPPED o;
+ // DIPSW2:
+ ONESTOPBIT,
+ 8, // ByteSize
+ NOPARITY,
+ true, // LF
+ false, // INT
+};
//===========================================================================
-static void UpdateCommState ()
+CSuperSerialCard::CSuperSerialCard()
{
- if (commhandle == INVALID_HANDLE_VALUE)
+ m_dwSerialPort = 0;
+
+ GetDIPSW();
+
+ m_vRecvBytes = 0;
+
+ m_hCommHandle = INVALID_HANDLE_VALUE;
+ m_dwCommInactivity = 0;
+
+ m_bTxIrqEnabled = false;
+ m_bRxIrqEnabled = false;
+
+ m_bWrittenTx = false;
+
+ m_vbCommIRQ = false;
+ m_hCommThread = NULL;
+
+ for (UINT i=0; i [0,1,2,3]
+ _ASSERT(bmByteSize <= 3);
+
+ UINT StopBit;
+ if ( ((m_uByteSize == 8) && (m_uParity != NOPARITY)) ||
+ ( m_uStopBits != ONESTOPBIT ) )
+ StopBit = 1;
+ else
+ StopBit = 0;
+
+ return (StopBit<<7) | (bmByteSize<<5) | (CLK<<4) | BaudRateToIndex(m_uBaudRate);
+}
+
+UINT CSuperSerialCard::BaudRateToIndex(UINT uBaudRate)
+{
+ switch (uBaudRate)
+ {
+ case CBR_110: return 0x05;
+ case CBR_300: return 0x06;
+ case CBR_600: return 0x07;
+ case CBR_1200: return 0x08;
+ case CBR_2400: return 0x0A;
+ case CBR_4800: return 0x0C;
+ case CBR_9600: return 0x0E;
+ case CBR_19200: return 0x0F;
+ }
+
+ _ASSERT(0);
+ return BaudRateToIndex(CBR_9600);
+}
+
+//===========================================================================
+
+void CSuperSerialCard::UpdateCommState()
+{
+ if (m_hCommHandle == INVALID_HANDLE_VALUE)
return;
DCB dcb;
ZeroMemory(&dcb,sizeof(DCB));
dcb.DCBlength = sizeof(DCB);
- GetCommState(commhandle,&dcb);
- dcb.BaudRate = baudrate;
- dcb.ByteSize = bytesize;
- dcb.Parity = parity;
- dcb.StopBits = stopbits;
+ GetCommState(m_hCommHandle,&dcb);
+ dcb.BaudRate = m_uBaudRate;
+ dcb.ByteSize = m_uByteSize;
+ dcb.Parity = m_uParity;
+ dcb.StopBits = m_uStopBits;
- SetCommState(commhandle,&dcb);
+ SetCommState(m_hCommHandle,&dcb);
}
//===========================================================================
-static BOOL CheckComm ()
+BOOL CSuperSerialCard::CheckComm()
{
- comminactivity = 0;
+ m_dwCommInactivity = 0;
- if ((commhandle == INVALID_HANDLE_VALUE) && serialport)
+ if ((m_hCommHandle == INVALID_HANDLE_VALUE) && m_dwSerialPort)
{
TCHAR portname[8];
- wsprintf(portname, TEXT("COM%u"), serialport);
+ wsprintf(portname, TEXT("COM%u"), m_dwSerialPort);
- commhandle = CreateFile(portname,
+ m_hCommHandle = CreateFile(portname,
GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
(LPSECURITY_ATTRIBUTES)NULL, // default security attributes
@@ -113,13 +206,13 @@ static BOOL CheckComm ()
FILE_FLAG_OVERLAPPED, // required for WaitCommEvent()
NULL);
- if (commhandle != INVALID_HANDLE_VALUE)
+ if (m_hCommHandle != INVALID_HANDLE_VALUE)
{
UpdateCommState();
COMMTIMEOUTS ct;
ZeroMemory(&ct,sizeof(COMMTIMEOUTS));
ct.ReadIntervalTimeout = MAXDWORD;
- SetCommTimeouts(commhandle,&ct);
+ SetCommTimeouts(m_hCommHandle,&ct);
CommThInit();
}
else
@@ -128,77 +221,135 @@ static BOOL CheckComm ()
}
}
- return (commhandle != INVALID_HANDLE_VALUE);
+ return (m_hCommHandle != INVALID_HANDLE_VALUE);
}
//===========================================================================
-static void CloseComm ()
+void CSuperSerialCard::CloseComm()
{
CommThUninit(); // Kill CommThread before closing COM handle
- if (commhandle != INVALID_HANDLE_VALUE)
- CloseHandle(commhandle);
+ if (m_hCommHandle != INVALID_HANDLE_VALUE)
+ CloseHandle(m_hCommHandle);
- commhandle = INVALID_HANDLE_VALUE;
- comminactivity = 0;
+ m_hCommHandle = INVALID_HANDLE_VALUE;
+ m_dwCommInactivity = 0;
+}
+
+//===========================================================================
+
+BYTE __stdcall CSuperSerialCard::SSC_IORead(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft)
+{
+ UINT uSlot = ((uAddr & 0xff) >> 4) - 8;
+ CSuperSerialCard* pSSC = (CSuperSerialCard*) MemGetSlotParameters(uSlot);
+
+ switch (uAddr & 0xf)
+ {
+ case 0x0: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0x1: return pSSC->CommDipSw(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0x2: return pSSC->CommDipSw(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0x3: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0x4: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0x5: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0x6: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0x7: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0x8: return pSSC->CommReceive(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0x9: return pSSC->CommStatus(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0xA: return pSSC->CommCommand(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0xB: return pSSC->CommControl(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0xC: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0xD: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0xE: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0xF: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ }
+
+ return 0;
+}
+
+BYTE __stdcall CSuperSerialCard::SSC_IOWrite(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft)
+{
+ UINT uSlot = ((uAddr & 0xff) >> 4) - 8;
+ CSuperSerialCard* pSSC = (CSuperSerialCard*) MemGetSlotParameters(uSlot);
+
+ switch (uAddr & 0xf)
+ {
+ case 0x0: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0x1: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0x2: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0x3: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0x4: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0x5: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0x6: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0x7: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0x8: return pSSC->CommTransmit(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0x9: return pSSC->CommStatus(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0xA: return pSSC->CommCommand(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0xB: return pSSC->CommControl(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0xC: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0xD: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0xE: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ case 0xF: return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
+ }
+
+ return 0;
}
//===========================================================================
// EG. 0x09 = Enable IRQ, No parity [Ref.2]
-BYTE __stdcall CommCommand (WORD, BYTE, BYTE write, BYTE value, ULONG)
+BYTE __stdcall CSuperSerialCard::CommCommand(WORD, WORD, BYTE write, BYTE value, ULONG)
{
if (!CheckComm())
return 0;
- if (write && (value != commandbyte))
+ if (write && (value != m_uCommandByte))
{
- commandbyte = value;
+ m_uCommandByte = value;
// UPDATE THE PARITY
- if (commandbyte & 0x20)
+ if (m_uCommandByte & 0x20)
{
- switch (commandbyte & 0xC0)
+ switch (m_uCommandByte & 0xC0)
{
- case 0x00 : parity = ODDPARITY; break;
- case 0x40 : parity = EVENPARITY; break;
- case 0x80 : parity = MARKPARITY; break;
- case 0xC0 : parity = SPACEPARITY; break;
+ case 0x00 : m_uParity = ODDPARITY; break;
+ case 0x40 : m_uParity = EVENPARITY; break;
+ case 0x80 : m_uParity = MARKPARITY; break;
+ case 0xC0 : m_uParity = SPACEPARITY; break;
}
}
else
{
- parity = NOPARITY;
+ m_uParity = NOPARITY;
}
- if (commandbyte & 0x10) // Receiver mode echo [0=no echo, 1=echo]
+ if (m_uCommandByte & 0x10) // Receiver mode echo [0=no echo, 1=echo]
{
}
- switch (commandbyte & 0x0C) // transmitter interrupt control
+ switch (m_uCommandByte & 0x0C) // transmitter interrupt control
{
// Note: the RTS signal must be set 'low' in order to receive any
// incoming data from the serial device
case 0<<2: // set RTS high and transmit no interrupts
- g_bTxIrqEnabled = false;
+ m_bTxIrqEnabled = false;
break;
case 1<<2: // set RTS low and transmit interrupts
- g_bTxIrqEnabled = true;
+ m_bTxIrqEnabled = true;
break;
case 2<<2: // set RTS low and transmit no interrupts
- g_bTxIrqEnabled = false;
+ m_bTxIrqEnabled = false;
break;
case 3<<2: // set RTS low and transmit break signals instead of interrupts
- g_bTxIrqEnabled = false;
+ m_bTxIrqEnabled = false;
break;
}
// interrupt request disable [0=enable receiver interrupts]
- g_bRxIrqEnabled = ((commandbyte & 0x02) == 0);
+ m_bRxIrqEnabled = ((m_uCommandByte & 0x02) == 0);
- if (commandbyte & 0x01) // Data Terminal Ready (DTR) setting [0=set DTR high (indicates 'not ready')]
+ if (m_uCommandByte & 0x01) // Data Terminal Ready (DTR) setting [0=set DTR high (indicates 'not ready')]
{
// Note that, although the DTR is generally not used in the SSC (it may actually not
// be connected!), it must be set to 'low' in order for the 6551 to function correctly.
@@ -207,22 +358,22 @@ BYTE __stdcall CommCommand (WORD, BYTE, BYTE write, BYTE value, ULONG)
UpdateCommState();
}
- return commandbyte;
+ return m_uCommandByte;
}
//===========================================================================
-BYTE __stdcall CommControl (WORD, BYTE, BYTE write, BYTE value, ULONG)
+BYTE __stdcall CSuperSerialCard::CommControl(WORD, WORD, BYTE write, BYTE value, ULONG)
{
if (!CheckComm())
return 0;
- if (write && (value != controlbyte))
+ if (write && (value != m_uControlByte))
{
- controlbyte = value;
+ m_uControlByte = value;
// UPDATE THE BAUD RATE
- switch (controlbyte & 0x0F)
+ switch (m_uControlByte & 0x0F)
{
// Note that 1 MHz Apples (everything other than the Apple IIgs and //c
// Plus running in "fast" mode) cannot handle 19.2 kbps, and even 9600
@@ -235,74 +386,74 @@ BYTE __stdcall CommControl (WORD, BYTE, BYTE write, BYTE value, ULONG)
case 0x02: // fall through [75 bps]
case 0x03: // fall through [109.92 bps]
case 0x04: // fall through [134.58 bps]
- case 0x05: baudrate = CBR_110; break; // [150 bps]
- case 0x06: baudrate = CBR_300; break;
- case 0x07: baudrate = CBR_600; break;
- case 0x08: baudrate = CBR_1200; break;
+ case 0x05: m_uBaudRate = CBR_110; break; // [150 bps]
+ case 0x06: m_uBaudRate = CBR_300; break;
+ case 0x07: m_uBaudRate = CBR_600; break;
+ case 0x08: m_uBaudRate = CBR_1200; break;
case 0x09: // fall through [1800 bps]
- case 0x0A: baudrate = CBR_2400; break;
+ case 0x0A: m_uBaudRate = CBR_2400; break;
case 0x0B: // fall through [3600 bps]
- case 0x0C: baudrate = CBR_4800; break;
+ case 0x0C: m_uBaudRate = CBR_4800; break;
case 0x0D: // fall through [7200 bps]
- case 0x0E: baudrate = CBR_9600; break;
- case 0x0F: baudrate = CBR_19200; break;
+ case 0x0E: m_uBaudRate = CBR_9600; break;
+ case 0x0F: m_uBaudRate = CBR_19200; break;
}
- if (controlbyte & 0x10)
+ if (m_uControlByte & 0x10)
{
// receiver clock source [0= external, 1= internal]
}
// UPDATE THE BYTE SIZE
- switch (controlbyte & 0x60)
+ switch (m_uControlByte & 0x60)
{
- case 0x00: bytesize = 8; break;
- case 0x20: bytesize = 7; break;
- case 0x40: bytesize = 6; break;
- case 0x60: bytesize = 5; break;
+ case 0x00: m_uByteSize = 8; break;
+ case 0x20: m_uByteSize = 7; break;
+ case 0x40: m_uByteSize = 6; break;
+ case 0x60: m_uByteSize = 5; break;
}
// UPDATE THE NUMBER OF STOP BITS
- if (controlbyte & 0x80)
+ if (m_uControlByte & 0x80)
{
- if ((bytesize == 8) && (parity == NOPARITY))
- stopbits = ONESTOPBIT;
- else if ((bytesize == 5) && (parity == NOPARITY))
- stopbits = ONE5STOPBITS;
+ if ((m_uByteSize == 8) && (m_uParity != NOPARITY))
+ m_uStopBits = ONESTOPBIT;
+ else if ((m_uByteSize == 5) && (m_uParity == NOPARITY))
+ m_uStopBits = ONE5STOPBITS;
else
- stopbits = TWOSTOPBITS;
+ m_uStopBits = TWOSTOPBITS;
}
else
{
- stopbits = ONESTOPBIT;
+ m_uStopBits = ONESTOPBIT;
}
UpdateCommState();
}
- return controlbyte;
+ return m_uControlByte;
}
//===========================================================================
-BYTE __stdcall CommReceive (WORD, BYTE, BYTE, BYTE, ULONG)
+BYTE __stdcall CSuperSerialCard::CommReceive(WORD, WORD, BYTE, BYTE, ULONG)
{
if (!CheckComm())
return 0;
BYTE result = 0;
- if (g_vRecvBytes)
+ if (m_vRecvBytes)
{
// Don't need critical section in here as CommThread is waiting for ACK
- result = g_RecvBuffer[0];
- --g_vRecvBytes;
+ result = m_RecvBuffer[0];
+ --m_vRecvBytes;
- if (g_vbCommIRQ && !g_vRecvBytes)
+ if (m_vbCommIRQ && !m_vRecvBytes)
{
// Read last byte, so get CommThread to call WaitCommEvent() again
OutputDebugString("CommRecv: SetEvent - ACK\n");
- SetEvent(g_hCommEvent[COMMEVT_ACK]);
+ SetEvent(m_hCommEvent[COMMEVT_ACK]);
}
}
@@ -311,20 +462,20 @@ BYTE __stdcall CommReceive (WORD, BYTE, BYTE, BYTE, ULONG)
//===========================================================================
-BYTE __stdcall CommTransmit (WORD, BYTE, BYTE, BYTE value, ULONG)
+BYTE __stdcall CSuperSerialCard::CommTransmit(WORD, WORD, BYTE, BYTE value, ULONG)
{
if (!CheckComm())
return 0;
DWORD uBytesWritten;
- WriteFile(commhandle, &value, 1, &uBytesWritten, &o);
+ WriteFile(m_hCommHandle, &value, 1, &uBytesWritten, &m_o);
- g_bWrittenTx = true; // Transmit done
+ m_bWrittenTx = true; // Transmit done
// TO DO:
// 1) Use CommThread determine when transmit is complete
// 2) OR do this:
- //if (g_bTxIrqEnabled)
+ //if (m_bTxIrqEnabled)
// CpuIrqAssert(IS_SSC);
return 0;
@@ -354,14 +505,14 @@ enum { ST_PARITY_ERR = 1<<0,
ST_IRQ = 1<<7
};
-BYTE __stdcall CommStatus (WORD, BYTE, BYTE, BYTE, ULONG)
+BYTE __stdcall CSuperSerialCard::CommStatus(WORD, WORD, BYTE, BYTE, ULONG)
{
if (!CheckComm())
return ST_DSR | ST_DCD | ST_TX_EMPTY;
#ifdef SUPPORT_MODEM
DWORD modemstatus = 0;
- GetCommModemStatus(commhandle,&modemstatus); // Returns 0x30 = MS_DSR_ON|MS_CTS_ON
+ GetCommModemStatus(m_hCommHandle,&modemstatus); // Returns 0x30 = MS_DSR_ON|MS_CTS_ON
#endif
//
@@ -371,33 +522,33 @@ BYTE __stdcall CommStatus (WORD, BYTE, BYTE, BYTE, ULONG)
// . IRQs disabled : always set it [Currently done]
//
- // So that /g_vRecvBytes/ doesn't change midway (from 0 to 1):
+ // So that /m_vRecvBytes/ doesn't change midway (from 0 to 1):
// . bIRQ=false, but uStatus.ST_RX_FULL=1
- EnterCriticalSection(&g_CriticalSection);
+ EnterCriticalSection(&m_CriticalSection);
bool bIRQ = false;
- if (g_bTxIrqEnabled && g_bWrittenTx)
+ if (m_bTxIrqEnabled && m_bWrittenTx)
{
bIRQ = true;
}
- if (g_bRxIrqEnabled && g_vRecvBytes)
+ if (m_bRxIrqEnabled && m_vRecvBytes)
{
bIRQ = true;
}
- g_bWrittenTx = false; // Read status reg always clears IRQ
+ m_bWrittenTx = false; // Read status reg always clears IRQ
//
BYTE uStatus = ST_TX_EMPTY
- | (g_vRecvBytes ? ST_RX_FULL : 0x00)
+ | (m_vRecvBytes ? ST_RX_FULL : 0x00)
#ifdef SUPPORT_MODEM
| ((modemstatus & MS_RLSD_ON) ? 0x00 : ST_DCD) // Need 0x00 to allow ZLink to start up
| ((modemstatus & MS_DSR_ON) ? 0x00 : ST_DSR)
#endif
| (bIRQ ? ST_IRQ : 0x00);
- LeaveCriticalSection(&g_CriticalSection);
+ LeaveCriticalSection(&m_CriticalSection);
CpuIrqDeassert(IS_SSC);
@@ -406,50 +557,126 @@ BYTE __stdcall CommStatus (WORD, BYTE, BYTE, BYTE, ULONG)
//===========================================================================
-BYTE __stdcall CommDipSw (WORD, BYTE addr, BYTE, BYTE, ULONG)
+BYTE __stdcall CSuperSerialCard::CommDipSw(WORD, WORD addr, BYTE, BYTE, ULONG)
{
- // TO DO: determine what values a real SSC returns
BYTE sw = 0;
+ switch (addr & 0xf)
+ {
+ case 1: // DIPSW1
+ sw = (BaudRateToIndex(m_DIPSWCurrent.uBaudRate)<<4) | m_DIPSWCurrent.eFirmwareMode;
+ break;
+
+ case 2: // DIPSW2
+ // Comms mode - SSC manual, pg23/24
+ BYTE INT = m_DIPSWCurrent.uStopBits == TWOSTOPBITS ? 1 : 0; // SW2-1 (Stop bits: 1-ON(0); 2-OFF(1))
+ BYTE DSR = 0; // Always zero
+ BYTE DCD = m_DIPSWCurrent.uByteSize == 7 ? 1 : 0; // SW2-2 (Data bits: 8-ON(0); 7-OFF(1))
+ BYTE TDR = 0; // Always zero
+
+ // SW2-3 (Parity: odd-ON(0); even-OFF(1))
+ // SW2-4 (Parity: none-ON(0); SW2-3-OFF(1))
+ BYTE RDR,OVR;
+ switch (m_DIPSWCurrent.uParity)
+ {
+ case ODDPARITY:
+ RDR = 0; OVR = 1;
+ break;
+ case EVENPARITY:
+ RDR = 1; OVR = 1;
+ break;
+ default:
+ _ASSERT(0);
+ case NOPARITY:
+ RDR = 0; OVR = 0;
+ break;
+ }
+
+ BYTE FE = m_DIPSWCurrent.bLinefeed ? 1 : 0; // SW2-5 (LF: yes-ON(0); no-OFF(1))
+ BYTE PE = m_DIPSWCurrent.bInterrupts ? 1 : 0; // SW2-6 (Interrupts: yes-ON(0); no-OFF(1))
+
+ sw = (INT<<7) | (DSR<<6) | (DCD<<5) | (TDR<<4) | (RDR<<3) | (OVR<<2) | (FE<<1) | (PE<<0);
+ break;
+ }
return sw;
}
//===========================================================================
-void CommReset ()
+void CSuperSerialCard::CommInitialize(LPBYTE pCxRomPeripheral, UINT uSlot)
{
- CloseComm();
+ const UINT SSC_FW_SIZE = 2*1024;
+ const UINT SSC_SLOT_FW_SIZE = 256;
+ const UINT SSC_SLOT_FW_OFFSET = 7*256;
- baudrate = CBR_19200;
- bytesize = 8;
- commandbyte = 0x00;
- controlbyte = 0x1F;
- parity = NOPARITY;
- g_vRecvBytes = 0;
- stopbits = ONESTOPBIT;
-}
+ HRSRC hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_SSC_FW), "FIRMWARE");
+ if(hResInfo == NULL)
+ return;
-//===========================================================================
+ DWORD dwResSize = SizeofResource(NULL, hResInfo);
+ if(dwResSize != SSC_FW_SIZE)
+ return;
-void CommDestroy ()
-{
- if ((baudrate != CBR_19200) ||
- (bytesize != 8) ||
- (parity != NOPARITY) ||
- (stopbits != ONESTOPBIT))
+ HGLOBAL hResData = LoadResource(NULL, hResInfo);
+ if(hResData == NULL)
+ return;
+
+ BYTE* pData = (BYTE*) LockResource(hResData); // NB. Don't need to unlock resource
+ if(pData == NULL)
+ return;
+
+ memcpy(pCxRomPeripheral + uSlot*256, pData+SSC_SLOT_FW_OFFSET, SSC_SLOT_FW_SIZE);
+
+ // Expansion ROM
+ if (m_pExpansionRom == NULL)
{
- CommReset();
+ m_pExpansionRom = new BYTE [SSC_FW_SIZE];
+
+ if (m_pExpansionRom)
+ memcpy(m_pExpansionRom, pData, SSC_FW_SIZE);
}
- CloseComm();
+ //
+
+ RegisterIoHandler(uSlot, &CSuperSerialCard::SSC_IORead, &CSuperSerialCard::SSC_IOWrite, NULL, NULL, this, m_pExpansionRom);
}
//===========================================================================
-void CommSetSerialPort (HWND window, DWORD newserialport)
+void CSuperSerialCard::CommReset()
{
- if (commhandle == INVALID_HANDLE_VALUE)
+ CloseComm();
+
+ GetDIPSW();
+
+ m_vRecvBytes = 0;
+
+ //
+
+ m_bTxIrqEnabled = false;
+ m_bRxIrqEnabled = false;
+
+ m_bWrittenTx = false;
+
+ m_vbCommIRQ = false;
+}
+
+//===========================================================================
+
+void CSuperSerialCard::CommDestroy()
+{
+ CommReset();
+
+ delete [] m_pExpansionRom;
+ m_pExpansionRom = NULL;
+}
+
+//===========================================================================
+
+void CSuperSerialCard::CommSetSerialPort(HWND window, DWORD newserialport)
+{
+ if (m_hCommHandle == INVALID_HANDLE_VALUE)
{
- serialport = newserialport;
+ m_dwSerialPort = newserialport;
}
else
{
@@ -463,64 +690,66 @@ void CommSetSerialPort (HWND window, DWORD newserialport)
//===========================================================================
-void CommUpdate (DWORD totalcycles)
+void CSuperSerialCard::CommUpdate(DWORD totalcycles)
{
- if (commhandle == INVALID_HANDLE_VALUE)
+ if (m_hCommHandle == INVALID_HANDLE_VALUE)
return;
- if ((comminactivity += totalcycles) > 1000000)
+ if ((m_dwCommInactivity += totalcycles) > 1000000)
{
static DWORD lastcheck = 0;
- if ((comminactivity > 2000000) || (comminactivity-lastcheck > 99950))
+ if ((m_dwCommInactivity > 2000000) || (m_dwCommInactivity-lastcheck > 99950))
{
#ifdef SUPPORT_MODEM
DWORD modemstatus = 0;
- GetCommModemStatus(commhandle,&modemstatus);
+ GetCommModemStatus(m_hCommHandle,&modemstatus);
if ((modemstatus & MS_RLSD_ON) || DiskIsSpinning())
- comminactivity = 0;
+ m_dwCommInactivity = 0;
#else
if (DiskIsSpinning())
- comminactivity = 0;
+ m_dwCommInactivity = 0;
#endif
}
- //if (comminactivity > 2000000)
+ //if (m_dwCommInactivity > 2000000)
// CloseComm();
}
}
//===========================================================================
-static void CheckCommEvent(DWORD dwEvtMask)
+void CSuperSerialCard::CheckCommEvent(DWORD dwEvtMask)
{
if (dwEvtMask & EV_RXCHAR)
{
- EnterCriticalSection(&g_CriticalSection);
- ReadFile(commhandle, g_RecvBuffer, 1, (DWORD*)&g_vRecvBytes, &o);
- LeaveCriticalSection(&g_CriticalSection);
+ EnterCriticalSection(&m_CriticalSection);
+ ReadFile(m_hCommHandle, m_RecvBuffer, 1, (DWORD*)&m_vRecvBytes, &m_o);
+ LeaveCriticalSection(&m_CriticalSection);
- if (g_bRxIrqEnabled && g_vRecvBytes)
+ if (m_bRxIrqEnabled && m_vRecvBytes)
{
- g_vbCommIRQ = true;
+ m_vbCommIRQ = true;
CpuIrqAssert(IS_SSC);
}
}
//else if (dwEvtMask & EV_TXEMPTY)
//{
- // if (g_bTxIrqEnabled)
+ // if (m_bTxIrqEnabled)
// {
- // g_vbCommIRQ = true;
+ // m_vbCommIRQ = true;
// CpuIrqAssert(IS_SSC);
// }
//}
}
-static DWORD WINAPI CommThread(LPVOID lpParameter)
+DWORD WINAPI CSuperSerialCard::CommThread(LPVOID lpParameter)
{
+ CSuperSerialCard* pSSC = (CSuperSerialCard*) lpParameter;
+
char szDbg[100];
-// BOOL bRes = SetCommMask(commhandle, EV_TXEMPTY | EV_RXCHAR);
- BOOL bRes = SetCommMask(commhandle, EV_RXCHAR); // Just RX
+// BOOL bRes = SetCommMask(pSSC->m_hCommHandle, EV_TXEMPTY | EV_RXCHAR);
+ BOOL bRes = SetCommMask(pSSC->m_hCommHandle, EV_RXCHAR); // Just RX
if (!bRes)
return -1;
@@ -528,17 +757,17 @@ static DWORD WINAPI CommThread(LPVOID lpParameter)
const UINT nNumEvents = 2;
#if 1
- HANDLE hCommEvent_Wait[nNumEvents] = {g_hCommEvent[COMMEVT_WAIT], g_hCommEvent[COMMEVT_TERM]};
- HANDLE hCommEvent_Ack[nNumEvents] = {g_hCommEvent[COMMEVT_ACK], g_hCommEvent[COMMEVT_TERM]};
+ HANDLE hCommEvent_Wait[nNumEvents] = {pSSC->m_hCommEvent[COMMEVT_WAIT], pSSC->m_hCommEvent[COMMEVT_TERM]};
+ HANDLE hCommEvent_Ack[nNumEvents] = {pSSC->m_hCommEvent[COMMEVT_ACK], pSSC->m_hCommEvent[COMMEVT_TERM]};
#else
HANDLE hCommEvent_Wait[nNumEvents];
HANDLE hCommEvent_Ack[nNumEvents];
- hCommEvent_Wait[0] = g_hCommEvent[COMMEVT_WAIT];
- hCommEvent_Wait[1] = g_hCommEvent[COMMEVT_TERM];
+ hCommEvent_Wait[0] = m_hCommEvent[COMMEVT_WAIT];
+ hCommEvent_Wait[1] = m_hCommEvent[COMMEVT_TERM];
- hCommEvent_Ack[0] = g_hCommEvent[COMMEVT_ACK];
- hCommEvent_Ack[1] = g_hCommEvent[COMMEVT_TERM];
+ hCommEvent_Ack[0] = m_hCommEvent[COMMEVT_ACK];
+ hCommEvent_Ack[1] = m_hCommEvent[COMMEVT_TERM];
#endif
while(1)
@@ -546,11 +775,12 @@ static DWORD WINAPI CommThread(LPVOID lpParameter)
DWORD dwEvtMask = 0;
DWORD dwWaitResult;
- bRes = WaitCommEvent(commhandle, &dwEvtMask, &o); // Will return immediately (probably with ERROR_IO_PENDING)
+ bRes = WaitCommEvent(pSSC->m_hCommHandle, &dwEvtMask, &pSSC->m_o); // Will return immediately (probably with ERROR_IO_PENDING)
_ASSERT(!bRes);
if (!bRes)
{
DWORD dwRet = GetLastError();
+ // Got this error once: ERROR_OPERATION_ABORTED
_ASSERT(dwRet == ERROR_IO_PENDING);
if (dwRet != ERROR_IO_PENDING)
return -1;
@@ -584,9 +814,9 @@ static DWORD WINAPI CommThread(LPVOID lpParameter)
}
// Comm event
- CheckCommEvent(dwEvtMask);
+ pSSC->CheckCommEvent(dwEvtMask);
- if (g_vbCommIRQ)
+ if (pSSC->m_vbCommIRQ)
{
//
// Wait for ack
@@ -611,23 +841,23 @@ static DWORD WINAPI CommThread(LPVOID lpParameter)
if (dwWaitResult == (nNumEvents-1))
break; // Termination event
- g_vbCommIRQ = false;
+ pSSC->m_vbCommIRQ = false;
}
}
return 0;
}
-bool CommThInit()
+bool CSuperSerialCard::CommThInit()
{
- _ASSERT(g_hCommThread == NULL);
- _ASSERT(commhandle);
+ _ASSERT(m_hCommThread == NULL);
+ _ASSERT(m_hCommHandle);
- if ((g_hCommEvent[0] == NULL) && (g_hCommEvent[1] == NULL) && (g_hCommEvent[2] == NULL))
+ if ((m_hCommEvent[0] == NULL) && (m_hCommEvent[1] == NULL) && (m_hCommEvent[2] == NULL))
{
// Create an event object for use by WaitCommEvent
- o.hEvent = CreateEvent(
+ m_o.hEvent = CreateEvent(
NULL, // default security attributes
FALSE, // auto reset event (bManualReset)
FALSE, // not signaled (bInitialState)
@@ -635,24 +865,24 @@ bool CommThInit()
);
// Initialize the rest of the OVERLAPPED structure to zero
- o.Internal = 0;
- o.InternalHigh = 0;
- o.Offset = 0;
- o.OffsetHigh = 0;
+ m_o.Internal = 0;
+ m_o.InternalHigh = 0;
+ m_o.Offset = 0;
+ m_o.OffsetHigh = 0;
//
- g_hCommEvent[COMMEVT_WAIT] = o.hEvent;
- g_hCommEvent[COMMEVT_ACK] = CreateEvent(NULL, // lpEventAttributes
+ m_hCommEvent[COMMEVT_WAIT] = m_o.hEvent;
+ m_hCommEvent[COMMEVT_ACK] = CreateEvent(NULL, // lpEventAttributes
FALSE, // bManualReset (FALSE = auto-reset)
FALSE, // bInitialState (FALSE = non-signaled)
NULL); // lpName
- g_hCommEvent[COMMEVT_TERM] = CreateEvent(NULL, // lpEventAttributes
+ m_hCommEvent[COMMEVT_TERM] = CreateEvent(NULL, // lpEventAttributes
FALSE, // bManualReset (FALSE = auto-reset)
FALSE, // bInitialState (FALSE = non-signaled)
NULL); // lpName
- if ((g_hCommEvent[0] == NULL) || (g_hCommEvent[1] == NULL) || (g_hCommEvent[2] == NULL))
+ if ((m_hCommEvent[0] == NULL) || (m_hCommEvent[1] == NULL) || (m_hCommEvent[2] == NULL))
{
if(g_fh) fprintf(g_fh, "Comm: CreateEvent failed\n");
return false;
@@ -661,33 +891,33 @@ bool CommThInit()
//
- if (g_hCommThread == NULL)
+ if (m_hCommThread == NULL)
{
DWORD dwThreadId;
- g_hCommThread = CreateThread(NULL, // lpThreadAttributes
+ m_hCommThread = CreateThread(NULL, // lpThreadAttributes
0, // dwStackSize
- CommThread,
- NULL, // lpParameter
+ (LPTHREAD_START_ROUTINE) &CSuperSerialCard::CommThread,
+ this, // lpParameter
0, // dwCreationFlags : 0 = Run immediately
&dwThreadId); // lpThreadId
- InitializeCriticalSection(&g_CriticalSection);
+ InitializeCriticalSection(&m_CriticalSection);
}
return true;
}
-void CommThUninit()
+void CSuperSerialCard::CommThUninit()
{
- if (g_hCommThread)
+ if (m_hCommThread)
{
- SetEvent(g_hCommEvent[COMMEVT_TERM]); // Signal to thread that it should exit
+ SetEvent(m_hCommEvent[COMMEVT_TERM]); // Signal to thread that it should exit
do
{
DWORD dwExitCode;
- if(GetExitCodeThread(g_hCommThread, &dwExitCode))
+ if(GetExitCodeThread(m_hCommThread, &dwExitCode))
{
if(dwExitCode == STILL_ACTIVE)
Sleep(10);
@@ -697,50 +927,50 @@ void CommThUninit()
}
while(1);
- CloseHandle(g_hCommThread);
- g_hCommThread = NULL;
+ CloseHandle(m_hCommThread);
+ m_hCommThread = NULL;
- DeleteCriticalSection(&g_CriticalSection);
+ DeleteCriticalSection(&m_CriticalSection);
}
//
for (UINT i=0; ibaudrate = baudrate;
- pSS->bytesize = bytesize;
- pSS->commandbyte = commandbyte;
- pSS->comminactivity = comminactivity;
- pSS->controlbyte = controlbyte;
- pSS->parity = parity;
- memcpy(pSS->recvbuffer, g_RecvBuffer, uRecvBufferSize);
- pSS->recvbytes = g_vRecvBytes;
- pSS->stopbits = 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 = m_vRecvBytes;
+ pSS->stopbits = m_uStopBits;
return 0;
}
-DWORD CommSetSnapshot(SS_IO_Comms* pSS)
+DWORD CSuperSerialCard::CommSetSnapshot(SS_IO_Comms* pSS)
{
- baudrate = pSS->baudrate;
- bytesize = pSS->bytesize;
- commandbyte = pSS->commandbyte;
- comminactivity = pSS->comminactivity;
- controlbyte = pSS->controlbyte;
- parity = pSS->parity;
- memcpy(g_RecvBuffer, pSS->recvbuffer, uRecvBufferSize);
- g_vRecvBytes = pSS->recvbytes;
- stopbits = pSS->stopbits;
+ 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;
return 0;
}
diff --git a/AppleWin/source/SerialComms.h b/AppleWin/source/SerialComms.h
index 7b70711f..44aefda9 100644
--- a/AppleWin/source/SerialComms.h
+++ b/AppleWin/source/SerialComms.h
@@ -1,19 +1,109 @@
#pragma once
-extern DWORD serialport;
+extern class CSuperSerialCard sg_SSC;
-void CommDestroy ();
-void CommReset ();
-void CommSetSerialPort (HWND,DWORD);
-void CommUpdate (DWORD);
-bool CommThInit();
-void CommThUninit();
-DWORD CommGetSnapshot(SS_IO_Comms* pSS);
-DWORD CommSetSnapshot(SS_IO_Comms* pSS);
+enum {COMMEVT_WAIT=0, COMMEVT_ACK, COMMEVT_TERM, COMMEVT_MAX};
+enum eFWMODE {FWMODE_CIC=0, FWMODE_SIC_P8, FWMODE_PPC, FWMODE_SIC_P8A}; // NB. CIC = SSC
-BYTE __stdcall CommCommand (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
-BYTE __stdcall CommControl (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
-BYTE __stdcall CommDipSw (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
-BYTE __stdcall CommReceive (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
-BYTE __stdcall CommStatus (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
-BYTE __stdcall CommTransmit (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+typedef struct
+{
+ //DIPSW1
+ UINT uBaudRate;
+ eFWMODE eFirmwareMode;
+
+ //DIPSW2
+ UINT uStopBits;
+ UINT uByteSize;
+ UINT uParity;
+ bool bLinefeed;
+ bool bInterrupts;
+} SSC_DIPSW;
+
+class CSuperSerialCard
+{
+public:
+ CSuperSerialCard();
+ ~CSuperSerialCard();
+
+ void CommInitialize(LPBYTE pCxRomPeripheral, UINT uSlot);
+ void CommReset();
+ void CommDestroy();
+ void CommSetSerialPort(HWND,DWORD);
+ void CommUpdate(DWORD);
+ DWORD CommGetSnapshot(SS_IO_Comms* pSS);
+ DWORD CommSetSnapshot(SS_IO_Comms* pSS);
+
+ DWORD GetSerialPort() { return m_dwSerialPort; }
+ void SetSerialPort(DWORD dwSerialPort) { m_dwSerialPort = dwSerialPort; }
+
+ static BYTE __stdcall SSC_IORead(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft);
+ static BYTE __stdcall SSC_IOWrite(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft);
+
+private:
+ BYTE __stdcall CommCommand(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+ BYTE __stdcall CommControl(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+ BYTE __stdcall CommDipSw(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+ BYTE __stdcall CommReceive(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+ BYTE __stdcall CommStatus(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+ BYTE __stdcall CommTransmit(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+
+ void GetDIPSW();
+ void SetDIPSWDefaults();
+ BYTE GenerateControl();
+ UINT BaudRateToIndex(UINT uBaudRate);
+ void UpdateCommState();
+ BOOL CheckComm();
+ void CloseComm();
+ void CheckCommEvent(DWORD dwEvtMask);
+ static DWORD WINAPI CommThread(LPVOID lpParameter);
+ bool CommThInit();
+ void CommThUninit();
+
+ //
+
+private:
+ DWORD m_dwSerialPort;
+
+ static SSC_DIPSW m_DIPSWDefault;
+ SSC_DIPSW m_DIPSWCurrent;
+
+ // Derived from DIPSW1
+ UINT m_uBaudRate;
+
+ // Derived from DIPSW2
+ UINT m_uStopBits;
+ UINT m_uByteSize;
+ UINT m_uParity;
+
+ // SSC Registers
+ BYTE m_uControlByte;
+ BYTE m_uCommandByte;
+
+ //
+
+ HANDLE m_hCommHandle;
+ DWORD m_dwCommInactivity;
+
+ //
+
+ CRITICAL_SECTION m_CriticalSection; // To guard /g_vRecvBytes/
+ BYTE m_RecvBuffer[uRecvBufferSize]; // NB: More work required if >1 is used
+ volatile DWORD m_vRecvBytes;
+
+ //
+
+ bool m_bTxIrqEnabled;
+ bool m_bRxIrqEnabled;
+
+ bool m_bWrittenTx;
+
+ //
+
+ volatile bool m_vbCommIRQ;
+ HANDLE m_hCommThread;
+
+ HANDLE m_hCommEvent[COMMEVT_MAX];
+ OVERLAPPED m_o;
+
+ BYTE* m_pExpansionRom;
+};
diff --git a/AppleWin/source/Speaker.cpp b/AppleWin/source/Speaker.cpp
index 9d4886d5..adbf9654 100644
--- a/AppleWin/source/Speaker.cpp
+++ b/AppleWin/source/Speaker.cpp
@@ -419,7 +419,7 @@ static void UpdateSpkr()
// Called by emulation code when Speaker I/O reg is accessed
//
-BYTE __stdcall SpkrToggle (WORD, BYTE address, BYTE write, BYTE, ULONG nCyclesLeft)
+BYTE __stdcall SpkrToggle (WORD, WORD, BYTE, BYTE, ULONG nCyclesLeft)
{
g_bSpkrToggleFlag = true;
diff --git a/AppleWin/source/Speaker.h b/AppleWin/source/Speaker.h
index 445620fe..a0ef0af7 100644
--- a/AppleWin/source/Speaker.h
+++ b/AppleWin/source/Speaker.h
@@ -20,4 +20,4 @@ void Spkr_DSUninit();
DWORD SpkrGetSnapshot(SS_IO_Speaker* pSS);
DWORD SpkrSetSnapshot(SS_IO_Speaker* pSS);
-BYTE __stdcall SpkrToggle (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+BYTE __stdcall SpkrToggle (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
diff --git a/AppleWin/source/Tfe/Tfe.cpp b/AppleWin/source/Tfe/Tfe.cpp
index a537bf25..152d8a08 100644
--- a/AppleWin/source/Tfe/Tfe.cpp
+++ b/AppleWin/source/Tfe/Tfe.cpp
@@ -37,6 +37,13 @@
#include "tfearch.h"
#include "tfesupp.h"
+#ifndef NULL
+#define NULL 0
+#endif
+typedef unsigned int UINT;
+#include "..\common.h"
+// Define here, so we don't drag in the whole of stdafx.h:
+void RegisterIoHandler(UINT uSlot, iofunction IORead16, iofunction IOWrite16, iofunction IOReadCx, iofunction IOWriteCx, LPVOID lpSlotParameter, BYTE* pExpansionRom);
/**/
/** #define TFE_DEBUG_DUMP 1 **/
@@ -384,6 +391,8 @@ void tfe_debug_output_pp( void )
/* ------------------------------------------------------------------------- */
/* initialization and deinitialization functions */
+BYTE __stdcall TfeIo (WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles);
+
void tfe_reset(void)
{
if (tfe_enabled && !should_activate)
@@ -442,6 +451,9 @@ void tfe_reset(void)
TFE_DEBUG_OUTPUT_REG();
}
+
+ const UINT uSlot = 3;
+ RegisterIoHandler(uSlot, TfeIo, TfeIo, NULL, NULL, NULL, NULL);
}
#ifdef DOS_TFE
@@ -1489,7 +1501,7 @@ int tfe_enumadapter_close(void)
}
-BYTE __stdcall TfeIo (WORD programcounter, BYTE address, BYTE write, BYTE value, ULONG nCycles)
+static BYTE __stdcall TfeIo (WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles)
{
BYTE ret = 0;
diff --git a/AppleWin/source/Tfe/Tfe.h b/AppleWin/source/Tfe/Tfe.h
index 26ff5602..e3f408e6 100644
--- a/AppleWin/source/Tfe/Tfe.h
+++ b/AppleWin/source/Tfe/Tfe.h
@@ -52,7 +52,6 @@ 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);
-extern BYTE __stdcall TfeIo (WORD programcounter, BYTE address, BYTE write, BYTE value, ULONG nCycles);
/*
These functions let the UI enumerate the available interfaces.
diff --git a/AppleWin/source/Tfe/Types.h b/AppleWin/source/Tfe/Types.h
index ceb9b4ea..64027b46 100644
--- a/AppleWin/source/Tfe/Types.h
+++ b/AppleWin/source/Tfe/Types.h
@@ -50,6 +50,10 @@
#ifndef ULONG
typedef unsigned long ULONG;
#endif
+/* TC added for AppleWin */
+#ifndef LPVOID
+typedef void *LPVOID;
+#endif
typedef signed char SIGNED_CHAR;
typedef signed short SWORD;
diff --git a/AppleWin/source/Video.cpp b/AppleWin/source/Video.cpp
index 86b0b399..a7431af8 100644
--- a/AppleWin/source/Video.cpp
+++ b/AppleWin/source/Video.cpp
@@ -1011,10 +1011,8 @@ bool Update40ColCell (int x, int y, int xpixel, int ypixel, int offset)
CopySource(xpixel,ypixel,
APPLE_FONT_WIDTH, APPLE_FONT_HEIGHT,
- (g_bApple2e
- ? SRCOFFS_40COL
- : SRCOFFS_IIPLUS) + ((ch & 0x0F) << 4),
- (ch & 0xF0)+g_nAltCharSetOffset + (bInvert?0x40:0x00));
+ (IS_APPLE2 ? SRCOFFS_IIPLUS : SRCOFFS_40COL) + ((ch & 0x0F) << 4),
+ (ch & 0xF0) + g_nAltCharSetOffset + (bInvert ? 0x40 : 0x00));
return true;
}
@@ -1563,7 +1561,7 @@ void VideoBenchmark () {
(unsigned)totaltextfps,
(unsigned)(totalmhz10/10),
(unsigned)(totalmhz10 % 10),
- (LPCTSTR)(g_bApple2e ? TEXT("") : TEXT(" (6502)")),
+ (LPCTSTR)(IS_APPLE2 ? TEXT(" (6502)") : TEXT("")),
(unsigned)realisticfps);
MessageBox(g_hFrameWindow,
outstr,
@@ -1572,7 +1570,9 @@ void VideoBenchmark () {
}
//===========================================================================
-BYTE __stdcall VideoCheckMode (WORD, BYTE address, BYTE, BYTE, ULONG) {
+BYTE __stdcall VideoCheckMode (WORD, WORD address, BYTE, BYTE, ULONG)
+{
+ address &= 0xFF;
if (address == 0x7F)
return MemReadFloatingBus(SW_DHIRES != 0);
else {
@@ -1601,7 +1601,7 @@ void VideoCheckPage (BOOL force) {
}
//===========================================================================
-BYTE __stdcall VideoCheckVbl (WORD, BYTE, BYTE, BYTE, ULONG)
+BYTE __stdcall VideoCheckVbl (WORD, WORD, BYTE, BYTE, ULONG)
{
/*
// Drol expects = 80
@@ -2042,16 +2042,18 @@ void VideoResetState () {
}
//===========================================================================
-BYTE __stdcall VideoSetMode (WORD, BYTE address, BYTE write, BYTE, ULONG) {
+BYTE __stdcall VideoSetMode (WORD, WORD address, BYTE write, BYTE, ULONG)
+{
+ address &= 0xFF;
DWORD oldpage2 = SW_PAGE2;
int oldvalue = g_nAltCharSetOffset+(int)(vidmode & ~(VF_MASK2 | VF_PAGE2));
switch (address) {
case 0x00: vidmode &= ~VF_MASK2; break;
case 0x01: vidmode |= VF_MASK2; break;
- case 0x0C: if (g_bApple2e) vidmode &= ~VF_80COL; break;
- case 0x0D: if (g_bApple2e) vidmode |= VF_80COL; break;
- case 0x0E: if (g_bApple2e) g_nAltCharSetOffset = 0; break; // Alternate char set off
- case 0x0F: if (g_bApple2e) g_nAltCharSetOffset = 256; break; // Alternate char set on
+ case 0x0C: if (!IS_APPLE2) vidmode &= ~VF_80COL; break;
+ case 0x0D: if (!IS_APPLE2) vidmode |= VF_80COL; break;
+ case 0x0E: if (!IS_APPLE2) g_nAltCharSetOffset = 0; break; // Alternate char set off
+ case 0x0F: if (!IS_APPLE2) g_nAltCharSetOffset = 256; break; // Alternate char set on
case 0x50: vidmode &= ~VF_TEXT; break;
case 0x51: vidmode |= VF_TEXT; break;
case 0x52: vidmode &= ~VF_MIXED; break;
@@ -2060,8 +2062,8 @@ BYTE __stdcall VideoSetMode (WORD, BYTE address, BYTE write, BYTE, ULONG) {
case 0x55: vidmode |= VF_PAGE2; break;
case 0x56: vidmode &= ~VF_HIRES; break;
case 0x57: vidmode |= VF_HIRES; break;
- case 0x5E: if (g_bApple2e) vidmode |= VF_DHIRES; break;
- case 0x5F: if (g_bApple2e) vidmode &= ~VF_DHIRES; break;
+ case 0x5E: if (!IS_APPLE2) vidmode |= VF_DHIRES; break;
+ case 0x5F: if (!IS_APPLE2) vidmode &= ~VF_DHIRES; break;
}
if (SW_MASK2)
vidmode &= ~VF_PAGE2;
@@ -2243,7 +2245,7 @@ WORD VideoGetScannerAddress(bool* pbVblBar_OUT)
{
// N: text, so no higher address bits unless Apple ][, not Apple //e
//
- if ((!g_bApple2e) && // Apple ][?
+ if ((IS_APPLE2) && // Apple ][?
(kHPEClock <= nHClock) && // Y: HBL?
(nHClock <= (kHClocks - 1)))
{
diff --git a/AppleWin/source/Video.h b/AppleWin/source/Video.h
index 717802cd..5c563a24 100644
--- a/AppleWin/source/Video.h
+++ b/AppleWin/source/Video.h
@@ -70,6 +70,6 @@ bool VideoGetSW80COL();
DWORD VideoGetSnapshot(SS_IO_Video* pSS);
DWORD VideoSetSnapshot(SS_IO_Video* pSS);
-BYTE __stdcall VideoCheckMode (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
-BYTE __stdcall VideoCheckVbl (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
-BYTE __stdcall VideoSetMode (WORD pc, BYTE addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+BYTE __stdcall VideoCheckMode (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+BYTE __stdcall VideoCheckVbl (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
+BYTE __stdcall VideoSetMode (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);