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);