mirror of
https://github.com/AppleWin/AppleWin.git
synced 2024-06-16 06:29:33 +00:00
Submitted changed files from AppleWin-Tom branch to trunk
. Change: Added support for SSC receive IRQ (eg. Z-Link) . Fix: [Bug #7231] AppleWin installed in path with spaces Internal: . Modified operation of interrupt assert/deassert
This commit is contained in:
parent
8a453a479e
commit
0b8d9e723c
|
@ -358,9 +358,6 @@
|
||||||
<Filter
|
<Filter
|
||||||
Name="Docs"
|
Name="Docs"
|
||||||
Filter="">
|
Filter="">
|
||||||
<File
|
|
||||||
RelativePath=".\docs\Bugs.txt">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\docs\CodingConventions.txt">
|
RelativePath=".\docs\CodingConventions.txt">
|
||||||
</File>
|
</File>
|
||||||
|
|
|
@ -46,23 +46,6 @@ END
|
||||||
|
|
||||||
#endif // APSTUDIO_INVOKED
|
#endif // APSTUDIO_INVOKED
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// String Table
|
|
||||||
//
|
|
||||||
|
|
||||||
STRINGTABLE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
IDS_TFE_CAPTION "Ethernet Settings"
|
|
||||||
IDS_TFE_ETHERNET "Ethernet"
|
|
||||||
IDS_TFE_INTERFACE "Interface"
|
|
||||||
END
|
|
||||||
|
|
||||||
STRINGTABLE
|
|
||||||
BEGIN
|
|
||||||
IDS_OK "OK"
|
|
||||||
IDS_CANCEL "Cancel"
|
|
||||||
END
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -216,8 +199,8 @@ BEGIN
|
||||||
GROUPBOX "Harddisk Controller",IDC_STATIC,2,113,205,71
|
GROUPBOX "Harddisk Controller",IDC_STATIC,2,113,205,71
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_TFE_SETTINGS_DIALOG DIALOG DISCARDABLE 0, 0, 270, 100
|
IDD_TFE_SETTINGS_DIALOG DIALOG 0, 0, 270, 100
|
||||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
CAPTION "Ethernet Settings"
|
CAPTION "Ethernet Settings"
|
||||||
FONT 8, "MS Sans Serif"
|
FONT 8, "MS Sans Serif"
|
||||||
BEGIN
|
BEGIN
|
||||||
|
@ -233,6 +216,7 @@ BEGIN
|
||||||
PUSHBUTTON "Cancel",IDCANCEL,80,75,50,14
|
PUSHBUTTON "Cancel",IDCANCEL,80,75,50,14
|
||||||
END
|
END
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Icon
|
// Icon
|
||||||
|
@ -249,8 +233,8 @@ DISK_ICON ICON "DISK.ICO"
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,12,9,1
|
FILEVERSION 1,13,0,0
|
||||||
PRODUCTVERSION 1,12,9,1
|
PRODUCTVERSION 1,13,0,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -268,12 +252,12 @@ BEGIN
|
||||||
VALUE "Comments", "http://applewin.berlios.de"
|
VALUE "Comments", "http://applewin.berlios.de"
|
||||||
VALUE "CompanyName", "Michael O'Brien, Oliver Schmidt, Tom Charlesworth"
|
VALUE "CompanyName", "Michael O'Brien, Oliver Schmidt, Tom Charlesworth"
|
||||||
VALUE "FileDescription", "Apple //e Emulator for Windows"
|
VALUE "FileDescription", "Apple //e Emulator for Windows"
|
||||||
VALUE "FileVersion", "1, 12, 9, 1"
|
VALUE "FileVersion", "1, 13, 0, 0"
|
||||||
VALUE "InternalName", "APPLEWIN"
|
VALUE "InternalName", "APPLEWIN"
|
||||||
VALUE "LegalCopyright", "© 1994-2006 Michael O'Brien, Oliver Schmidt, Tom Charlesworth, Michael Pohoreski"
|
VALUE "LegalCopyright", "© 1994-2006 Michael O'Brien, Oliver Schmidt, Tom Charlesworth, Michael Pohoreski"
|
||||||
VALUE "OriginalFilename", "APPLEWIN.EXE"
|
VALUE "OriginalFilename", "APPLEWIN.EXE"
|
||||||
VALUE "ProductName", "Apple //e Emulator"
|
VALUE "ProductName", "Apple //e Emulator"
|
||||||
VALUE "ProductVersion", "1, 12, 9, 1"
|
VALUE "ProductVersion", "1, 13, 0, 0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
@ -302,7 +286,6 @@ END
|
||||||
|
|
||||||
IDR_HDDRVR FIRMWARE "Hddrvr.bin"
|
IDR_HDDRVR FIRMWARE "Hddrvr.bin"
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// ROM
|
// ROM
|
||||||
|
@ -341,6 +324,25 @@ BEGIN
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// String Table
|
||||||
|
//
|
||||||
|
|
||||||
|
STRINGTABLE
|
||||||
|
BEGIN
|
||||||
|
IDS_TFE_CAPTION "Ethernet Settings"
|
||||||
|
IDS_TFE_ETHERNET "Ethernet"
|
||||||
|
IDS_TFE_INTERFACE "Interface"
|
||||||
|
END
|
||||||
|
|
||||||
|
STRINGTABLE
|
||||||
|
BEGIN
|
||||||
|
IDS_OK "OK"
|
||||||
|
IDS_CANCEL "Cancel"
|
||||||
|
END
|
||||||
|
|
||||||
#endif // English (U.S.) resources
|
#endif // English (U.S.) resources
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,11 @@
|
||||||
#include <crtdbg.h>
|
#include <crtdbg.h>
|
||||||
#include "ay8910.h"
|
#include "ay8910.h"
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Structs.h"
|
||||||
|
#include "Applewin.h" // For g_fh
|
||||||
|
#include "Mockingboard.h" // For g_uTimer1IrqCount
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
// typedefs & dummy funcs to allow MAME code to compile:
|
// typedefs & dummy funcs to allow MAME code to compile:
|
||||||
|
|
||||||
|
@ -105,7 +110,56 @@ struct AY8910
|
||||||
|
|
||||||
static struct AY8910 AYPSG[MAX_8910]; /* array of PSG's */
|
static struct AY8910 AYPSG[MAX_8910]; /* array of PSG's */
|
||||||
|
|
||||||
|
static bool g_bAYReset = false; // Doing AY8910_reset()
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//#define LOG_AY8910
|
||||||
|
#ifdef LOG_AY8910
|
||||||
|
static void LogAY8910(int n, int r, UINT uFreq)
|
||||||
|
{
|
||||||
|
// TO DO: Determine freq from 6522 timer
|
||||||
|
|
||||||
|
if ((g_fh == NULL) || g_bAYReset)
|
||||||
|
return;
|
||||||
|
|
||||||
|
static UINT nCnt = 0;
|
||||||
|
const UINT nNumAYs = 4; // 1..4
|
||||||
|
if((r == 0))
|
||||||
|
{
|
||||||
|
if(nCnt == 0)
|
||||||
|
{
|
||||||
|
fprintf(g_fh, "Time : ");
|
||||||
|
for(UINT i=0; i<nNumAYs; i++)
|
||||||
|
fprintf(g_fh, "APer BPer CPer NP EN AV BV CV ");
|
||||||
|
fprintf(g_fh, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(g_fh, "%02d.%02d: ", g_uTimer1IrqCount/uFreq, g_uTimer1IrqCount%uFreq);
|
||||||
|
|
||||||
|
for(int j=0; j<n*(3*5+5*3+1); j++)
|
||||||
|
fprintf(g_fh, " ");
|
||||||
|
|
||||||
|
UINT i=n;
|
||||||
|
{
|
||||||
|
UCHAR* pAYRegs = &AYPSG[i].Regs[0];
|
||||||
|
fprintf(g_fh, "%04X ", *(USHORT*)&pAYRegs[AY_AFINE]);
|
||||||
|
fprintf(g_fh, "%04X ", *(USHORT*)&pAYRegs[AY_BFINE]);
|
||||||
|
fprintf(g_fh, "%04X ", *(USHORT*)&pAYRegs[AY_CFINE]);
|
||||||
|
fprintf(g_fh, "%02X ", pAYRegs[AY_NOISEPER]);
|
||||||
|
fprintf(g_fh, "%02X ", pAYRegs[AY_ENABLE]);
|
||||||
|
fprintf(g_fh, "%02X ", pAYRegs[AY_AVOL]);
|
||||||
|
fprintf(g_fh, "%02X ", pAYRegs[AY_BVOL]);
|
||||||
|
fprintf(g_fh, "%02X ", pAYRegs[AY_CVOL]);
|
||||||
|
}
|
||||||
|
fprintf(g_fh, "\n");
|
||||||
|
|
||||||
|
nCnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void _AYWriteReg(int n, int r, int v)
|
void _AYWriteReg(int n, int r, int v)
|
||||||
{
|
{
|
||||||
|
@ -115,27 +169,8 @@ void _AYWriteReg(int n, int r, int v)
|
||||||
|
|
||||||
PSG->Regs[r] = v;
|
PSG->Regs[r] = v;
|
||||||
|
|
||||||
//#define LOG_AY8910
|
|
||||||
#ifdef LOG_AY8910
|
#ifdef LOG_AY8910
|
||||||
extern FILE* g_fh; // Filehandle for log file
|
LogAY8910(n, r, 60);
|
||||||
static UINT nCnt = 0;
|
|
||||||
if((n == 0) && (r == 0) && g_fh)
|
|
||||||
{
|
|
||||||
if(nCnt == 0)
|
|
||||||
fprintf(g_fh, "Time : APer BPer CPer NP EN AV BV CV\n");
|
|
||||||
|
|
||||||
fprintf(g_fh, "%02d.%02d: ", nCnt/60, nCnt%60);
|
|
||||||
nCnt++;
|
|
||||||
|
|
||||||
fprintf(g_fh, "%04X ", *(USHORT*)&PSG->Regs[AY_AFINE]);
|
|
||||||
fprintf(g_fh, "%04X ", *(USHORT*)&PSG->Regs[AY_BFINE]);
|
|
||||||
fprintf(g_fh, "%04X ", *(USHORT*)&PSG->Regs[AY_CFINE]);
|
|
||||||
fprintf(g_fh, "%02X ", PSG->Regs[AY_NOISEPER]);
|
|
||||||
fprintf(g_fh, "%02X ", PSG->Regs[AY_ENABLE]);
|
|
||||||
fprintf(g_fh, "%02X ", PSG->Regs[AY_AVOL]);
|
|
||||||
fprintf(g_fh, "%02X ", PSG->Regs[AY_BVOL]);
|
|
||||||
fprintf(g_fh, "%02X\n", PSG->Regs[AY_CVOL]);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* A note about the period of tones, noise and envelope: for speed reasons,*/
|
/* A note about the period of tones, noise and envelope: for speed reasons,*/
|
||||||
|
@ -692,6 +727,8 @@ void ay8910_write_ym(int chip, int addr, int data)
|
||||||
|
|
||||||
void AY8910_reset(int chip)
|
void AY8910_reset(int chip)
|
||||||
{
|
{
|
||||||
|
g_bAYReset = true;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
struct AY8910 *PSG = &AYPSG[chip];
|
struct AY8910 *PSG = &AYPSG[chip];
|
||||||
|
|
||||||
|
@ -706,6 +743,8 @@ void AY8910_reset(int chip)
|
||||||
_AYWriteReg(chip,i,0); /* AYWriteReg() uses the timer system; we cannot */
|
_AYWriteReg(chip,i,0); /* AYWriteReg() uses the timer system; we cannot */
|
||||||
/* call it at this time because the timer system */
|
/* call it at this time because the timer system */
|
||||||
/* has not been initialized. */
|
/* has not been initialized. */
|
||||||
|
|
||||||
|
g_bAYReset = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
|
|
@ -412,38 +412,50 @@ void LoadConfiguration () {
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
void RegisterExtensions () {
|
void RegisterExtensions ()
|
||||||
TCHAR command[MAX_PATH];
|
{
|
||||||
GetModuleFileName((HMODULE)0,command,MAX_PATH);
|
TCHAR szCommandTmp[MAX_PATH];
|
||||||
command[MAX_PATH-1] = 0;
|
GetModuleFileName((HMODULE)0,szCommandTmp,MAX_PATH);
|
||||||
TCHAR icon[MAX_PATH];
|
|
||||||
wsprintf(icon,TEXT("%s,1"),(LPCTSTR)command);
|
TCHAR command[MAX_PATH];
|
||||||
_tcscat(command,TEXT(" %1"));
|
wsprintf(command, "\"%s\"", szCommandTmp); // Wrap path & filename in quotes & null terminate
|
||||||
RegSetValue(HKEY_CLASSES_ROOT,".bin",REG_SZ,"DiskImage",10);
|
|
||||||
RegSetValue(HKEY_CLASSES_ROOT,".do" ,REG_SZ,"DiskImage",10);
|
TCHAR icon[MAX_PATH];
|
||||||
RegSetValue(HKEY_CLASSES_ROOT,".dsk",REG_SZ,"DiskImage",10);
|
wsprintf(icon,TEXT("%s,1"),(LPCTSTR)command);
|
||||||
RegSetValue(HKEY_CLASSES_ROOT,".nib",REG_SZ,"DiskImage",10);
|
|
||||||
RegSetValue(HKEY_CLASSES_ROOT,".po" ,REG_SZ,"DiskImage",10);
|
_tcscat(command,TEXT(" \"%1\"")); // Append "%1"
|
||||||
// RegSetValue(HKEY_CLASSES_ROOT,".aws",REG_SZ,"DiskImage",10); // TO DO
|
|
||||||
// RegSetValue(HKEY_CLASSES_ROOT,".hdv",REG_SZ,"DiskImage",10); // TO DO
|
RegSetValue(HKEY_CLASSES_ROOT,".bin",REG_SZ,"DiskImage",10);
|
||||||
RegSetValue(HKEY_CLASSES_ROOT,
|
RegSetValue(HKEY_CLASSES_ROOT,".do" ,REG_SZ,"DiskImage",10);
|
||||||
"DiskImage",
|
RegSetValue(HKEY_CLASSES_ROOT,".dsk",REG_SZ,"DiskImage",10);
|
||||||
REG_SZ,"Disk Image",21);
|
RegSetValue(HKEY_CLASSES_ROOT,".nib",REG_SZ,"DiskImage",10);
|
||||||
RegSetValue(HKEY_CLASSES_ROOT,
|
RegSetValue(HKEY_CLASSES_ROOT,".po" ,REG_SZ,"DiskImage",10);
|
||||||
"DiskImage\\DefaultIcon",
|
// RegSetValue(HKEY_CLASSES_ROOT,".aws",REG_SZ,"DiskImage",10); // TO DO
|
||||||
REG_SZ,icon,_tcslen(icon)+1);
|
// RegSetValue(HKEY_CLASSES_ROOT,".hdv",REG_SZ,"DiskImage",10); // TO DO
|
||||||
RegSetValue(HKEY_CLASSES_ROOT,
|
|
||||||
"DiskImage\\shell\\open\\command",
|
RegSetValue(HKEY_CLASSES_ROOT,
|
||||||
REG_SZ,command,_tcslen(command)+1);
|
"DiskImage",
|
||||||
RegSetValue(HKEY_CLASSES_ROOT,
|
REG_SZ,"Disk Image",21);
|
||||||
"DiskImage\\shell\\open\\ddeexec",
|
|
||||||
REG_SZ,"%1",3);
|
RegSetValue(HKEY_CLASSES_ROOT,
|
||||||
RegSetValue(HKEY_CLASSES_ROOT,
|
"DiskImage\\DefaultIcon",
|
||||||
"DiskImage\\shell\\open\\ddeexec\\application",
|
REG_SZ,icon,_tcslen(icon)+1);
|
||||||
REG_SZ,"applewin",9);
|
|
||||||
RegSetValue(HKEY_CLASSES_ROOT,
|
RegSetValue(HKEY_CLASSES_ROOT,
|
||||||
"DiskImage\\shell\\open\\ddeexec\\topic",
|
"DiskImage\\shell\\open\\command",
|
||||||
REG_SZ,"system",7);
|
REG_SZ,command,_tcslen(command)+1);
|
||||||
|
|
||||||
|
RegSetValue(HKEY_CLASSES_ROOT,
|
||||||
|
"DiskImage\\shell\\open\\ddeexec",
|
||||||
|
REG_SZ,"%1",3);
|
||||||
|
|
||||||
|
RegSetValue(HKEY_CLASSES_ROOT,
|
||||||
|
"DiskImage\\shell\\open\\ddeexec\\application",
|
||||||
|
REG_SZ,"applewin",9);
|
||||||
|
|
||||||
|
RegSetValue(HKEY_CLASSES_ROOT,
|
||||||
|
"DiskImage\\shell\\open\\ddeexec\\topic",
|
||||||
|
REG_SZ,"system",7);
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
|
@ -106,6 +106,14 @@ static ULONG g_nCyclesExecuted;
|
||||||
|
|
||||||
static signed long nInternalCyclesLeft;
|
static signed long nInternalCyclesLeft;
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
// Assume all interrupt sources assert until the device is told to stop:
|
||||||
|
// - eg by r/w to device's register or a machine reset
|
||||||
|
|
||||||
|
static CRITICAL_SECTION g_CriticalSection; // To guard /g_bmIRQ/
|
||||||
|
static volatile UINT32 g_bmIRQ = 0;
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
*
|
*
|
||||||
* GENERAL PURPOSE MACROS
|
* GENERAL PURPOSE MACROS
|
||||||
|
@ -488,21 +496,6 @@ static DWORD InternalCpuExecute (DWORD totalcycles)
|
||||||
nInternalCyclesLeft = (totalcycles<<8) - (cycles<<8);
|
nInternalCyclesLeft = (totalcycles<<8) - (cycles<<8);
|
||||||
USHORT uExtraCycles = 0;
|
USHORT uExtraCycles = 0;
|
||||||
|
|
||||||
if(regs.bIRQ && !(regs.ps & AF_INTERRUPT))
|
|
||||||
{
|
|
||||||
g_nCycleIrqStart = g_nCumulativeCycles + cycles;
|
|
||||||
regs.bIRQ = 0;
|
|
||||||
PUSH(regs.pc >> 8)
|
|
||||||
PUSH(regs.pc & 0xFF)
|
|
||||||
EF_TO_AF
|
|
||||||
regs.ps |= AF_RESERVED;
|
|
||||||
PUSH(regs.ps)
|
|
||||||
regs.ps |= AF_INTERRUPT;
|
|
||||||
regs.pc = * (WORD*) (mem+0xFFFE);
|
|
||||||
CYC(7)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (*(mem+regs.pc++))
|
switch (*(mem+regs.pc++))
|
||||||
{
|
{
|
||||||
case 0x00: BRK CYC(7) break;
|
case 0x00: BRK CYC(7) break;
|
||||||
|
@ -764,6 +757,20 @@ static DWORD InternalCpuExecute (DWORD totalcycles)
|
||||||
case 0xFE: ABSX INC CYC(6) break;
|
case 0xFE: ABSX INC CYC(6) break;
|
||||||
case 0xFF: INVALID1 CYC(1) break;
|
case 0xFF: INVALID1 CYC(1) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(g_bmIRQ && !(regs.ps & AF_INTERRUPT))
|
||||||
|
{
|
||||||
|
// IRQ signals are deasserted when a specific r/w operation is done on device
|
||||||
|
g_nCycleIrqStart = g_nCumulativeCycles + cycles;
|
||||||
|
PUSH(regs.pc >> 8)
|
||||||
|
PUSH(regs.pc & 0xFF)
|
||||||
|
EF_TO_AF
|
||||||
|
regs.ps |= AF_RESERVED;
|
||||||
|
PUSH(regs.ps)
|
||||||
|
regs.ps |= AF_INTERRUPT;
|
||||||
|
regs.pc = * (WORD*) (mem+0xFFFE);
|
||||||
|
CYC(7)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (cycles < totalcycles);
|
while (cycles < totalcycles);
|
||||||
EF_TO_AF
|
EF_TO_AF
|
||||||
|
@ -784,6 +791,8 @@ void CpuDestroy () {
|
||||||
cpugetcodefunc[loop] = NULL;
|
cpugetcodefunc[loop] = NULL;
|
||||||
cpulibrary[loop] = (HINSTANCE)0;
|
cpulibrary[loop] = (HINSTANCE)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeleteCriticalSection(&g_CriticalSection);
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -902,9 +911,15 @@ void CpuInitialize () {
|
||||||
regs.ps = 0x20;
|
regs.ps = 0x20;
|
||||||
regs.pc = *(LPWORD)(mem+0xFFFC);
|
regs.pc = *(LPWORD)(mem+0xFFFC);
|
||||||
regs.sp = 0x01FF;
|
regs.sp = 0x01FF;
|
||||||
regs.bIRQ = 0;
|
|
||||||
|
InitializeCriticalSection(&g_CriticalSection);
|
||||||
|
CpuIrqReset();
|
||||||
|
|
||||||
#ifdef _X86_
|
#ifdef _X86_
|
||||||
|
// TO DO:
|
||||||
|
// . FreeLibrary isn't being called if DLLs' version is too low
|
||||||
|
// . This code is going to get ditched, so ignore this!
|
||||||
|
|
||||||
if (mem) {
|
if (mem) {
|
||||||
TCHAR filename[MAX_PATH];
|
TCHAR filename[MAX_PATH];
|
||||||
_tcscpy(filename,progdir);
|
_tcscpy(filename,progdir);
|
||||||
|
@ -998,11 +1013,27 @@ BOOL CpuSupportsFastPaging () {
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
void CpuIRQ()
|
|
||||||
|
void CpuIrqReset()
|
||||||
{
|
{
|
||||||
regs.bIRQ = 1;
|
EnterCriticalSection(&g_CriticalSection);
|
||||||
|
g_bmIRQ = 0;
|
||||||
|
LeaveCriticalSection(&g_CriticalSection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CpuIrqAssert(eIRQSRC Device)
|
||||||
|
{
|
||||||
|
EnterCriticalSection(&g_CriticalSection);
|
||||||
|
g_bmIRQ |= 1<<Device;
|
||||||
|
LeaveCriticalSection(&g_CriticalSection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CpuIrqDeassert(eIRQSRC Device)
|
||||||
|
{
|
||||||
|
EnterCriticalSection(&g_CriticalSection);
|
||||||
|
g_bmIRQ &= ~(1<<Device);
|
||||||
|
LeaveCriticalSection(&g_CriticalSection);
|
||||||
|
}
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
DWORD CpuGetSnapshot(SS_CPU6502* pSS)
|
DWORD CpuGetSnapshot(SS_CPU6502* pSS)
|
||||||
|
@ -1026,7 +1057,7 @@ DWORD CpuSetSnapshot(SS_CPU6502* pSS)
|
||||||
regs.ps = pSS->P;
|
regs.ps = pSS->P;
|
||||||
regs.sp = (USHORT)pSS->S + 0x100;
|
regs.sp = (USHORT)pSS->S + 0x100;
|
||||||
regs.pc = pSS->PC;
|
regs.pc = pSS->PC;
|
||||||
regs.bIRQ = 0;
|
CpuIrqReset();
|
||||||
g_nCumulativeCycles = pSS->g_nCumulativeCycles;
|
g_nCumulativeCycles = pSS->g_nCumulativeCycles;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -28,6 +28,8 @@ void CpuReinitialize ();
|
||||||
void CpuResetCompilerData ();
|
void CpuResetCompilerData ();
|
||||||
void CpuSetupBenchmark ();
|
void CpuSetupBenchmark ();
|
||||||
BOOL CpuSupportsFastPaging ();
|
BOOL CpuSupportsFastPaging ();
|
||||||
void CpuIRQ ();
|
void CpuIrqReset();
|
||||||
|
void CpuIrqAssert(eIRQSRC Device);
|
||||||
|
void CpuIrqDeassert(eIRQSRC Device);
|
||||||
DWORD CpuGetSnapshot(SS_CPU6502* pSS);
|
DWORD CpuGetSnapshot(SS_CPU6502* pSS);
|
||||||
DWORD CpuSetSnapshot(SS_CPU6502* pSS);
|
DWORD CpuSetSnapshot(SS_CPU6502* pSS);
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
const double _M14 = 14.31818e6;
|
const double _M14 = 14.31818e6;
|
||||||
const double CLK_6502 = (_M14 / 14.0);
|
const double CLK_6502 = (_M14 / 14.0); // 1022727 + 1/7
|
||||||
|
//const double CLK_6502 = 23 * 44100; // 1014300
|
||||||
|
|
||||||
const UINT uCyclesPerLine = 65; // 25 cycles of HBL & 40 cycles of HBL'
|
const UINT uCyclesPerLine = 65; // 25 cycles of HBL & 40 cycles of HBL'
|
||||||
const UINT uVisibleLinesPerFrame = 64*3; // 192
|
const UINT uVisibleLinesPerFrame = 64*3; // 192
|
||||||
|
@ -71,3 +72,4 @@ typedef BYTE (__stdcall *cxfunction)(WORD nPC, WORD nAddr, BYTE nWriteFlag, BYTE
|
||||||
|
|
||||||
typedef struct _IMAGE__ { int unused; } *HIMAGE;
|
typedef struct _IMAGE__ { int unused; } *HIMAGE;
|
||||||
|
|
||||||
|
enum eIRQSRC {IS_6522=0, IS_SPEECH, IS_SSC};
|
||||||
|
|
|
@ -983,7 +983,7 @@ void MemReset ()
|
||||||
// INITIALIZE PAGING, FILLING IN THE 64K MEMORY IMAGE
|
// INITIALIZE PAGING, FILLING IN THE 64K MEMORY IMAGE
|
||||||
ResetPaging(1);
|
ResetPaging(1);
|
||||||
regs.pc = *(LPWORD)(mem+0xFFFC);
|
regs.pc = *(LPWORD)(mem+0xFFFC);
|
||||||
regs.bIRQ = 0;
|
CpuIrqReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
|
@ -120,9 +120,10 @@ typedef struct
|
||||||
|
|
||||||
|
|
||||||
// IFR & IER:
|
// IFR & IER:
|
||||||
#define PERIPHERAL (1<<1)
|
#define IxR_PERIPHERAL (1<<1)
|
||||||
#define TIMER2 (1<<5)
|
#define IxR_VOTRAX (1<<4) // TO DO: Get proper name from 6522 datasheet!
|
||||||
#define TIMER1 (1<<6)
|
#define IxR_TIMER2 (1<<5)
|
||||||
|
#define IxR_TIMER1 (1<<6)
|
||||||
|
|
||||||
// ACR:
|
// ACR:
|
||||||
#define RUNMODE (1<<6) // 0 = 1-Shot Mode, 1 = Free Running Mode
|
#define RUNMODE (1<<6) // 0 = 1-Shot Mode, 1 = Free Running Mode
|
||||||
|
@ -194,6 +195,7 @@ static const double g_f6522TimerPeriod_NoIRQ = CLK_6502 / 60.0; // Constant wha
|
||||||
|
|
||||||
// External global vars:
|
// External global vars:
|
||||||
bool g_bMBTimerIrqActive = false;
|
bool g_bMBTimerIrqActive = false;
|
||||||
|
UINT32 g_uTimer1IrqCount = 0; // DEBUG
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -208,7 +210,7 @@ static void StartTimer(SY6522_AY8910* pMB)
|
||||||
if((pMB->nAY8910Number & 1) != SY6522_DEVICE_A)
|
if((pMB->nAY8910Number & 1) != SY6522_DEVICE_A)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if((pMB->sy6522.IER & TIMER1) == 0x00)
|
if((pMB->sy6522.IER & IxR_TIMER1) == 0x00)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
USHORT nPeriod = pMB->sy6522.TIMER1_LATCH.w;
|
USHORT nPeriod = pMB->sy6522.TIMER1_LATCH.w;
|
||||||
|
@ -216,14 +218,6 @@ static void StartTimer(SY6522_AY8910* pMB)
|
||||||
if(nPeriod <= 0xff) // Timer1L value has been written (but TIMER1H hasn't)
|
if(nPeriod <= 0xff) // Timer1L value has been written (but TIMER1H hasn't)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#if 0
|
|
||||||
if(nPeriod < 0x3000) // Bit of IRQ protection (probably not needed) - Phasor has ~0x800 cycle period
|
|
||||||
{
|
|
||||||
_ASSERT(0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pMB->nTimerStatus = 1;
|
pMB->nTimerStatus = 1;
|
||||||
|
|
||||||
// 6522 CLK runs at same speed as 6502 CLK
|
// 6522 CLK runs at same speed as 6502 CLK
|
||||||
|
@ -285,7 +279,6 @@ static void AY8910_Write(BYTE nDevice, BYTE nReg, BYTE nValue, BYTE nAYDevice)
|
||||||
|
|
||||||
case AY_WRITE: // 6: WRITE TO PSG
|
case AY_WRITE: // 6: WRITE TO PSG
|
||||||
_AYWriteReg(nDevice+2*nAYDevice, pMB->nAYCurrentRegister, pMB->sy6522.ORA);
|
_AYWriteReg(nDevice+2*nAYDevice, pMB->nAYCurrentRegister, pMB->sy6522.ORA);
|
||||||
// AY8910_write_ym(nDevice+2*nAYDevice, pMB->nAYCurrentRegister, pMB->sy6522.ORA);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AY_LATCH: // 7: LATCH ADDRESS
|
case AY_LATCH: // 7: LATCH ADDRESS
|
||||||
|
@ -303,6 +296,17 @@ static void UpdateIFR(SY6522_AY8910* pMB)
|
||||||
|
|
||||||
if(pMB->sy6522.IFR & pMB->sy6522.IER & 0x7F)
|
if(pMB->sy6522.IFR & pMB->sy6522.IER & 0x7F)
|
||||||
pMB->sy6522.IFR |= 0x80;
|
pMB->sy6522.IFR |= 0x80;
|
||||||
|
|
||||||
|
// Now update the IRQ signal from all 6522s
|
||||||
|
// . OR-sum of all active TIMER1, TIMER2 & SPEECH sources (from all 6522s)
|
||||||
|
UINT bIRQ = 0;
|
||||||
|
for(UINT i=0; i<NUM_SY6522; i++)
|
||||||
|
bIRQ |= g_MB[i].sy6522.IFR & 0x80;
|
||||||
|
|
||||||
|
if (bIRQ)
|
||||||
|
CpuIrqAssert(IS_6522);
|
||||||
|
else
|
||||||
|
CpuIrqDeassert(IS_6522);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SY6522_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
static void SY6522_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
||||||
|
@ -360,7 +364,7 @@ static void SY6522_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
||||||
/* Initiates timer1 & clears time-out of timer1 */
|
/* Initiates timer1 & clears time-out of timer1 */
|
||||||
|
|
||||||
// Clear Timer Interrupt Flag.
|
// Clear Timer Interrupt Flag.
|
||||||
pMB->sy6522.IFR &= ~TIMER1;
|
pMB->sy6522.IFR &= ~IxR_TIMER1;
|
||||||
UpdateIFR(pMB);
|
UpdateIFR(pMB);
|
||||||
|
|
||||||
pMB->sy6522.TIMER1_LATCH.h = nValue;
|
pMB->sy6522.TIMER1_LATCH.h = nValue;
|
||||||
|
@ -371,7 +375,7 @@ static void SY6522_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
||||||
case 0x07: // TIMER1H_LATCH
|
case 0x07: // TIMER1H_LATCH
|
||||||
// Clear Timer1 Interrupt Flag.
|
// Clear Timer1 Interrupt Flag.
|
||||||
pMB->sy6522.TIMER1_LATCH.h = nValue;
|
pMB->sy6522.TIMER1_LATCH.h = nValue;
|
||||||
pMB->sy6522.IFR &= ~TIMER1;
|
pMB->sy6522.IFR &= ~IxR_TIMER1;
|
||||||
UpdateIFR(pMB);
|
UpdateIFR(pMB);
|
||||||
break;
|
break;
|
||||||
case 0x08: // TIMER2L
|
case 0x08: // TIMER2L
|
||||||
|
@ -379,7 +383,7 @@ static void SY6522_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
||||||
break;
|
break;
|
||||||
case 0x09: // TIMER2H
|
case 0x09: // TIMER2H
|
||||||
// Clear Timer2 Interrupt Flag.
|
// Clear Timer2 Interrupt Flag.
|
||||||
pMB->sy6522.IFR &= ~TIMER2;
|
pMB->sy6522.IFR &= ~IxR_TIMER2;
|
||||||
UpdateIFR(pMB);
|
UpdateIFR(pMB);
|
||||||
|
|
||||||
pMB->sy6522.TIMER2_LATCH.h = nValue;
|
pMB->sy6522.TIMER2_LATCH.h = nValue;
|
||||||
|
@ -410,7 +414,7 @@ static void SY6522_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
||||||
UpdateIFR(pMB);
|
UpdateIFR(pMB);
|
||||||
|
|
||||||
// Check if timer has been disabled.
|
// Check if timer has been disabled.
|
||||||
if(pMB->sy6522.IER & TIMER1)
|
if(pMB->sy6522.IER & IxR_TIMER1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if(pMB->nTimerStatus == 0)
|
if(pMB->nTimerStatus == 0)
|
||||||
|
@ -461,7 +465,7 @@ static BYTE SY6522_Read(BYTE nDevice, BYTE nReg)
|
||||||
break;
|
break;
|
||||||
case 0x04: // TIMER1L_COUNTER
|
case 0x04: // TIMER1L_COUNTER
|
||||||
nValue = pMB->sy6522.TIMER1_COUNTER.l;
|
nValue = pMB->sy6522.TIMER1_COUNTER.l;
|
||||||
pMB->sy6522.IFR &= ~TIMER1; // Also clears Timer1 Interrupt Flag
|
pMB->sy6522.IFR &= ~IxR_TIMER1; // Also clears Timer1 Interrupt Flag
|
||||||
UpdateIFR(pMB);
|
UpdateIFR(pMB);
|
||||||
break;
|
break;
|
||||||
case 0x05: // TIMER1H_COUNTER
|
case 0x05: // TIMER1H_COUNTER
|
||||||
|
@ -475,7 +479,7 @@ static BYTE SY6522_Read(BYTE nDevice, BYTE nReg)
|
||||||
break;
|
break;
|
||||||
case 0x08: // TIMER2L
|
case 0x08: // TIMER2L
|
||||||
nValue = pMB->sy6522.TIMER2_COUNTER.l;
|
nValue = pMB->sy6522.TIMER2_COUNTER.l;
|
||||||
pMB->sy6522.IFR &= ~TIMER2; // Also clears Timer2 Interrupt Flag
|
pMB->sy6522.IFR &= ~IxR_TIMER2; // Also clears Timer2 Interrupt Flag
|
||||||
UpdateIFR(pMB);
|
UpdateIFR(pMB);
|
||||||
break;
|
break;
|
||||||
case 0x09: // TIMER2H
|
case 0x09: // TIMER2H
|
||||||
|
@ -543,32 +547,12 @@ const BYTE AMPLITUDE_MASK = 0x0F;
|
||||||
|
|
||||||
static BYTE SSI263_Read(BYTE nDevice, BYTE nReg)
|
static BYTE SSI263_Read(BYTE nDevice, BYTE nReg)
|
||||||
{
|
{
|
||||||
BYTE nValue;
|
|
||||||
|
|
||||||
SY6522_AY8910* pMB = &g_MB[nDevice];
|
SY6522_AY8910* pMB = &g_MB[nDevice];
|
||||||
|
|
||||||
switch(nReg)
|
// Regardless of register, just return inverted A/!R in bit7
|
||||||
{
|
// . A/!R is low for IRQ
|
||||||
case SSI_DURPHON:
|
|
||||||
nValue = pMB->SpeechChip.DurationPhonome;
|
|
||||||
break;
|
|
||||||
case SSI_INFLECT:
|
|
||||||
nValue = pMB->SpeechChip.Inflection;
|
|
||||||
break;
|
|
||||||
case SSI_RATEINF:
|
|
||||||
nValue = pMB->SpeechChip.RateInflection;
|
|
||||||
break;
|
|
||||||
case SSI_CTTRAMP:
|
|
||||||
nValue = pMB->SpeechChip.CtrlArtAmp;
|
|
||||||
break;
|
|
||||||
case SSI_FILFREQ:
|
|
||||||
nValue = pMB->SpeechChip.FilterFreq;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nValue;
|
return pMB->SpeechChip.CurrentMode << 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SSI263_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
static void SSI263_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
||||||
|
@ -581,6 +565,14 @@ static void SSI263_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
||||||
#if LOG_SSI263
|
#if LOG_SSI263
|
||||||
if(g_fh) fprintf(g_fh, "DUR = 0x%02X, PHON = 0x%02X\n\n", nValue>>6, nValue&PHONEME_MASK);
|
if(g_fh) fprintf(g_fh, "DUR = 0x%02X, PHON = 0x%02X\n\n", nValue>>6, nValue&PHONEME_MASK);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Datasheet is not clear, but a write to DURPHON must clear the IRQ
|
||||||
|
if(g_bPhasorEnable)
|
||||||
|
CpuIrqDeassert(IS_SPEECH);
|
||||||
|
pMB->sy6522.IFR &= ~IxR_PERIPHERAL;
|
||||||
|
UpdateIFR(pMB);
|
||||||
|
pMB->SpeechChip.CurrentMode &= ~1; // Clear SSI263's D7 pin
|
||||||
|
|
||||||
pMB->SpeechChip.DurationPhonome = nValue;
|
pMB->SpeechChip.DurationPhonome = nValue;
|
||||||
|
|
||||||
// Phoneme output not dependent on CONTROL bit
|
// Phoneme output not dependent on CONTROL bit
|
||||||
|
@ -703,6 +695,11 @@ static void Votrax_Write(BYTE nDevice, BYTE nValue)
|
||||||
{
|
{
|
||||||
g_bVotraxPhoneme = true;
|
g_bVotraxPhoneme = true;
|
||||||
|
|
||||||
|
// !A/R: Acknowledge receipt of phoneme data (signal goes from high to low)
|
||||||
|
SY6522_AY8910* pMB = &g_MB[nDevice];
|
||||||
|
pMB->sy6522.IFR &= ~IxR_VOTRAX;
|
||||||
|
UpdateIFR(pMB);
|
||||||
|
|
||||||
SSI263_Play(Votrax2SSI263[nValue & PHONEME_MASK]);
|
SSI263_Play(Votrax2SSI263[nValue & PHONEME_MASK]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -895,18 +892,19 @@ static DWORD WINAPI SSI263Thread(LPVOID lpParameter)
|
||||||
{
|
{
|
||||||
if((pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED))
|
if((pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED))
|
||||||
{
|
{
|
||||||
CpuIRQ();
|
pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin
|
||||||
|
|
||||||
|
// Is Phasor's SSI263.IRQ wired directly to IRQ? (Bypassing the 6522)
|
||||||
|
CpuIrqAssert(IS_SPEECH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if((pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED) && (pMB->sy6522.PCR == 0x0C))
|
if((pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED) && (pMB->sy6522.PCR == 0x0C))
|
||||||
{
|
{
|
||||||
pMB->sy6522.IFR |= PERIPHERAL;
|
pMB->sy6522.IFR |= IxR_PERIPHERAL;
|
||||||
UpdateIFR(pMB);
|
UpdateIFR(pMB);
|
||||||
|
pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin
|
||||||
if(pMB->sy6522.IER & PERIPHERAL)
|
|
||||||
CpuIRQ();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -914,11 +912,10 @@ static DWORD WINAPI SSI263Thread(LPVOID lpParameter)
|
||||||
|
|
||||||
if(g_bVotraxPhoneme && (pMB->sy6522.PCR == 0xB0))
|
if(g_bVotraxPhoneme && (pMB->sy6522.PCR == 0xB0))
|
||||||
{
|
{
|
||||||
pMB->sy6522.IFR |= 0x10;
|
// !A/R: Time-out of old phoneme (signal goes from low to high)
|
||||||
UpdateIFR(pMB);
|
|
||||||
|
|
||||||
if(pMB->sy6522.IER & 0x10)
|
pMB->sy6522.IFR |= IxR_VOTRAX;
|
||||||
CpuIRQ();
|
UpdateIFR(pMB);
|
||||||
|
|
||||||
g_bVotraxPhoneme = false;
|
g_bVotraxPhoneme = false;
|
||||||
}
|
}
|
||||||
|
@ -939,6 +936,10 @@ static void SSI263_Play(unsigned int nPhoneme)
|
||||||
|
|
||||||
g_nCurrentActivePhoneme = nPhoneme;
|
g_nCurrentActivePhoneme = nPhoneme;
|
||||||
|
|
||||||
|
hr = SSI263Voice[g_nCurrentActivePhoneme].lpDSBvoice->SetCurrentPosition(0);
|
||||||
|
if(FAILED(hr))
|
||||||
|
return;
|
||||||
|
|
||||||
hr = SSI263Voice[g_nCurrentActivePhoneme].lpDSBvoice->Play(0,0,0); // Not looping
|
hr = SSI263Voice[g_nCurrentActivePhoneme].lpDSBvoice->Play(0,0,0); // Not looping
|
||||||
if(FAILED(hr))
|
if(FAILED(hr))
|
||||||
return;
|
return;
|
||||||
|
@ -1449,7 +1450,7 @@ void MB_EndOfFrame()
|
||||||
if(g_SoundcardType == SC_NONE)
|
if(g_SoundcardType == SC_NONE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!g_bFullSpeed && !g_bMBTimerIrqActive && !(g_MB[0].sy6522.IFR & TIMER1))
|
if(!g_bFullSpeed && !g_bMBTimerIrqActive && !(g_MB[0].sy6522.IFR & IxR_TIMER1))
|
||||||
MB_Update();
|
MB_Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1478,9 +1479,11 @@ void MB_UpdateCycles(USHORT nClocks)
|
||||||
|
|
||||||
if( bTimer1Underflow && (g_nMBTimerDevice == i) && g_bMBTimerIrqActive )
|
if( bTimer1Underflow && (g_nMBTimerDevice == i) && g_bMBTimerIrqActive )
|
||||||
{
|
{
|
||||||
pMB->sy6522.IFR |= TIMER1;
|
g_uTimer1IrqCount++; // DEBUG
|
||||||
|
|
||||||
|
pMB->sy6522.IFR |= IxR_TIMER1;
|
||||||
UpdateIFR(pMB);
|
UpdateIFR(pMB);
|
||||||
CpuIRQ();
|
|
||||||
if((pMB->sy6522.ACR & RUNMODE) == RM_ONESHOT)
|
if((pMB->sy6522.ACR & RUNMODE) == RM_ONESHOT)
|
||||||
{
|
{
|
||||||
// One-shot mode
|
// One-shot mode
|
||||||
|
@ -1524,7 +1527,7 @@ void MB_SetSoundcardType(eSOUNDCARDTYPE NewSoundcardType)
|
||||||
|
|
||||||
double MB_GetFramePeriod()
|
double MB_GetFramePeriod()
|
||||||
{
|
{
|
||||||
return (g_bMBTimerIrqActive||(g_MB[0].sy6522.IFR & TIMER1)) ? (double)g_n6522TimerPeriod : g_f6522TimerPeriod_NoIRQ;
|
return (g_bMBTimerIrqActive||(g_MB[0].sy6522.IFR & IxR_TIMER1)) ? (double)g_n6522TimerPeriod : g_f6522TimerPeriod_NoIRQ;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MB_IsActive()
|
bool MB_IsActive()
|
||||||
|
@ -1606,15 +1609,18 @@ DWORD MB_SetSnapshot(SS_CARD_MOCKINGBOARD* pSS, DWORD /*dwSlot*/)
|
||||||
//
|
//
|
||||||
|
|
||||||
// Crude - currently only support a single speech chip
|
// Crude - currently only support a single speech chip
|
||||||
|
// FIX THIS:
|
||||||
|
// . Speech chip could be Votrax instead
|
||||||
|
// . Is this IRQ compatible with Phasor?
|
||||||
if(pMB->SpeechChip.DurationPhonome)
|
if(pMB->SpeechChip.DurationPhonome)
|
||||||
{
|
{
|
||||||
g_nSSI263Device = nDeviceNum;
|
g_nSSI263Device = nDeviceNum;
|
||||||
|
|
||||||
if((pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED) && (pMB->sy6522.PCR == 0x0C) && (pMB->sy6522.IER & PERIPHERAL))
|
if((pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED) && (pMB->sy6522.PCR == 0x0C) && (pMB->sy6522.IER & IxR_PERIPHERAL))
|
||||||
{
|
{
|
||||||
pMB->sy6522.IFR |= PERIPHERAL;
|
pMB->sy6522.IFR |= IxR_PERIPHERAL;
|
||||||
UpdateIFR(pMB);
|
UpdateIFR(pMB);
|
||||||
CpuIRQ();
|
pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
extern bool g_bMBTimerIrqActive;
|
extern bool g_bMBTimerIrqActive;
|
||||||
|
extern UINT32 g_uTimer1IrqCount; // DEBUG
|
||||||
|
|
||||||
void MB_Initialize();
|
void MB_Initialize();
|
||||||
void MB_Reinitialize();
|
void MB_Reinitialize();
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
//
|
// Structs used by save-state file
|
||||||
|
|
||||||
|
// *** DON'T CHANGE ANY STRUCT WITHOUT CONSIDERING BACKWARDS COMPATIBILITY WITH .AWS FORMAT ***
|
||||||
|
|
||||||
#define MAKE_VERSION(a,b,c,d) ((a<<24) | (b<<16) | (c<<8) | (d))
|
#define MAKE_VERSION(a,b,c,d) ((a<<24) | (b<<16) | (c<<8) | (d))
|
||||||
|
|
||||||
|
@ -34,6 +36,8 @@ typedef struct
|
||||||
// IRQ = OR-sum of all interrupt sources
|
// IRQ = OR-sum of all interrupt sources
|
||||||
} SS_CPU6502;
|
} SS_CPU6502;
|
||||||
|
|
||||||
|
const UINT uRecvBufferSize = 9;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
DWORD baudrate;
|
DWORD baudrate;
|
||||||
|
@ -42,7 +46,7 @@ typedef struct
|
||||||
DWORD comminactivity; // If non-zero then COM port open
|
DWORD comminactivity; // If non-zero then COM port open
|
||||||
BYTE controlbyte;
|
BYTE controlbyte;
|
||||||
BYTE parity;
|
BYTE parity;
|
||||||
BYTE recvbuffer[9];
|
BYTE recvbuffer[uRecvBufferSize];
|
||||||
DWORD recvbytes;
|
DWORD recvbytes;
|
||||||
BYTE stopbits;
|
BYTE stopbits;
|
||||||
} SS_IO_Comms;
|
} SS_IO_Comms;
|
||||||
|
@ -232,7 +236,7 @@ typedef struct
|
||||||
BYTE CtrlArtAmp;
|
BYTE CtrlArtAmp;
|
||||||
BYTE FilterFreq;
|
BYTE FilterFreq;
|
||||||
//
|
//
|
||||||
BYTE CurrentMode;
|
BYTE CurrentMode; // b7:6=Mode; b0=D7 pin (for IRQ)
|
||||||
} SSI263A;
|
} SSI263A;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
Loading…
Reference in New Issue
Block a user