Experimental Joyport support added (but disabled).

. Extended to allow //e support across a reset (to avoid self-test).
Added a debug-only DebugFlip() to output frame times (disabled).
This commit is contained in:
tomch 2014-02-16 14:39:26 +00:00
parent 2d1257c966
commit 073839c1d4
5 changed files with 155 additions and 3 deletions

View File

@ -415,7 +415,8 @@ void CpuDestroy ()
//===========================================================================
// Description:
// Call this when an IO-reg is access & accurate cycle info is needed
// Call this when an IO-reg is accessed & accurate cycle info is needed
// NB. Safe to call multiple times from the same IO function handler (as 'nExecutedCycles - g_nCyclesExecuted' will be zero the 2nd time)
// Pre:
// nExecutedCycles = # of cycles executed by Cpu6502() or Cpu65C02() for this iteration of ContinueExecution()
// Post:

View File

@ -139,6 +139,7 @@ enum AppMode_e
#define WM_USER_BOOT WM_USER+8
#define WM_USER_FULLSCREEN WM_USER+9
// TODO-TC: Refactor codebase by renaming /nCyclesLeft/ to /uExecutedCycles/
typedef BYTE (__stdcall *iofunction)(WORD nPC, WORD nAddr, BYTE nWriteFlag, BYTE nWriteValue, ULONG nCyclesLeft);
typedef struct _IMAGE__ { int unused; } *HIMAGE; // DiskImage's /ImageInfo/ is hidden behind HIMAGE

View File

@ -99,6 +99,12 @@ static unsigned __int64 g_nJoyCntrResetCycle = 0; // Abs cycle that joystick cou
static short g_nPdlTrimX = 0;
static short g_nPdlTrimY = 0;
enum {JOYPORT_LEFTRIGHT=0, JOYPORT_UPDOWN=1};
static UINT g_bJoyportEnabled = 0; // Set to use Joyport to drive the 3 button inputs
static UINT g_uJoyportActiveStick = 0;
static UINT g_uJoyportReadMode = JOYPORT_LEFTRIGHT;
//===========================================================================
void CheckJoystick0()
{
@ -425,7 +431,58 @@ static void DoAutofire(UINT uButton, BOOL& pressed)
lastPressed[uButton] = nowPressed;
}
BYTE __stdcall JoyReadButton(WORD, WORD address, BYTE, BYTE, ULONG nCyclesLeft)
BYTE __stdcall JoyportReadButton(WORD address, ULONG nCyclesLeft)
{
BOOL pressed = 0;
if (g_uJoyportActiveStick == 0)
{
switch (address)
{
case 0x61:
pressed = (buttonlatch[0] || joybutton[0] || setbutton[0] /*|| keydown[JK_OPENAPPLE]*/);
if(joyinfo[joytype[1]] != DEVICE_KEYBOARD) // BUG? joytype[1] should be [0] ?
pressed = (pressed || keydown[JK_BUTTON0]);
buttonlatch[0] = 0;
break;
case 0x62: // Left or Up
if (g_uJoyportReadMode == JOYPORT_LEFTRIGHT) // LEFT
{
if (xpos[0] == 0) // TODO: More range for mouse control?
pressed = 1;
}
else // UP
{
if (ypos[0] == 0) // TODO: More range for mouse control?
pressed = 1;
}
break;
case 0x63: // Right or Down
if (g_uJoyportReadMode == JOYPORT_LEFTRIGHT) // RIGHT
{
if (xpos[0] >= 255) // TODO: More range for mouse control?
pressed = 1;
}
else // DOWN
{
if (ypos[0] >= 255) // TODO: More range for mouse control?
pressed = 1;
}
break;
}
}
else // TODO: stick #1
{
}
pressed = pressed ? 0 : 1; // Invert as Joyport signals are active low
return MemReadFloatingBus(pressed, nCyclesLeft);
}
BYTE __stdcall JoyReadButton(WORD pc, WORD address, BYTE, BYTE, ULONG nCyclesLeft)
{
address &= 0xFF;
@ -434,12 +491,19 @@ BYTE __stdcall JoyReadButton(WORD, WORD address, BYTE, BYTE, ULONG nCyclesLeft)
if(joyinfo[joytype[1]] == DEVICE_JOYSTICK)
CheckJoystick1();
if (g_bJoyportEnabled)
{
// Some extra logic to stop the Joyport forcing a self-test at CTRL+RESET
if ((address != 0x62) || (address == 0x62 && pc != 0xC242 && pc != 0xC2BE)) // Original //e ($C242), Enhanced //e ($C2BE)
return JoyportReadButton(address, nCyclesLeft);
}
BOOL pressed = 0;
switch (address)
{
case 0x61:
pressed = (buttonlatch[0] || joybutton[0] || setbutton[0] || keydown[JK_OPENAPPLE]);
if(joyinfo[joytype[1]] != DEVICE_KEYBOARD)
if(joyinfo[joytype[1]] != DEVICE_KEYBOARD) // BUG? joytype[1] should be [0] ?
pressed = (pressed || keydown[JK_BUTTON0]);
buttonlatch[0] = 0;
DoAutofire(0, pressed);
@ -705,6 +769,49 @@ short JoyGetTrim(bool bAxisX)
//===========================================================================
// Joyport truth-table:
//
// AN0 AN1 /PB0 /PB1 /PB2
// ------------------------------------
// 0 0 Trigger-1 Left-1 Right-1
// 0 1 Trigger-1 Up-1 Down-1
// 1 0 Trigger-2 Left-2 Right-2
// 1 1 Trigger-2 Up-2 Down-2
#if 0
void JoyportEnable(const bool bEnable)
{
if (IS_APPLE2C)
g_bJoyportEnabled = false;
else
g_bJoyportEnabled = bEnable ? 1 : 0;
}
#endif
void JoyportControl(const UINT uControl)
{
if (!g_bJoyportEnabled)
return;
switch (uControl)
{
case 0: // AN0 clr
g_uJoyportActiveStick = 0;
break;
case 1: // AN0 set
g_uJoyportActiveStick = 1;
break;
case 2: // AN1 clr
g_uJoyportReadMode = JOYPORT_LEFTRIGHT;
break;
case 3: // AN1 set
g_uJoyportReadMode = JOYPORT_UPDOWN;
break;
}
}
//===========================================================================
DWORD JoyGetSnapshot(SS_IO_Joystick* pSS)
{
pSS->g_nJoyCntrResetCycle = g_nJoyCntrResetCycle;

View File

@ -23,6 +23,7 @@ BOOL JoyUsingKeyboardNumpad();
void JoyDisableUsingMouse();
void JoySetTrim(short nValue, bool bAxisX);
short JoyGetTrim(bool bAxisX);
void JoyportControl(const UINT uControl);
DWORD JoyGetSnapshot(SS_IO_Joystick* pSS);
DWORD JoySetSnapshot(SS_IO_Joystick* pSS);

View File

@ -488,6 +488,12 @@ BYTE __stdcall IO_Annunciator(WORD programcounter, WORD address, BYTE write, BYT
// . PC=C2B5: LDA $C05D (CLRAN2)
// NB. AN3: For //e & //c these locations are now used to enabled/disabled DHIRES
if (address >= 0xC058 && address <= 0xC05B)
{
JoyportControl(address & 0x3); // AN0 and AN1 control
}
if (!write)
return MemReadFloatingBus(nCyclesLeft);
else
@ -1467,10 +1473,46 @@ BYTE MemReadFloatingBus(const BYTE highbit, const ULONG uExecutedCycles)
//}
//===========================================================================
//#define DEBUG_FLIP_TIMINGS
#if defined(_DEBUG) && defined(DEBUG_FLIP_TIMINGS)
static void DebugFlip(WORD address, ULONG nCyclesLeft)
{
static unsigned __int64 uLastFlipCycle = 0;
static unsigned int uLastPage = -1;
if (address != 0x54 && address != 0x55)
return;
const unsigned int uNewPage = address & 1;
if (uLastPage == uNewPage)
return;
uLastPage = uNewPage;
CpuCalcCycles(nCyclesLeft); // Update g_nCumulativeCycles
const unsigned int uCyclesBetweenFlips = (unsigned int) (uLastFlipCycle ? g_nCumulativeCycles - uLastFlipCycle : 0);
uLastFlipCycle = g_nCumulativeCycles;
if (!uCyclesBetweenFlips)
return; // 1st time in func
const double fFreq = CLK_6502 / (double)uCyclesBetweenFlips;
char szStr[100];
sprintf(szStr, "Cycles between flips = %d (%f Hz)\n", uCyclesBetweenFlips, fFreq);
OutputDebugString(szStr);
}
#endif
BYTE __stdcall MemSetPaging (WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCyclesLeft)
{
address &= 0xFF;
DWORD lastmemmode = memmode;
#if defined(_DEBUG) && defined(DEBUG_FLIP_TIMINGS)
DebugFlip(address, nCyclesLeft);
#endif
// DETERMINE THE NEW MEMORY PAGING MODE.
if ((address >= 0x80) && (address <= 0x8F))