mirror of
https://github.com/AppleWin/AppleWin.git
synced 2025-01-10 13:29:56 +00:00
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:
parent
2d1257c966
commit
073839c1d4
@ -415,7 +415,8 @@ void CpuDestroy ()
|
|||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
// Description:
|
// 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:
|
// Pre:
|
||||||
// nExecutedCycles = # of cycles executed by Cpu6502() or Cpu65C02() for this iteration of ContinueExecution()
|
// nExecutedCycles = # of cycles executed by Cpu6502() or Cpu65C02() for this iteration of ContinueExecution()
|
||||||
// Post:
|
// Post:
|
||||||
|
@ -139,6 +139,7 @@ enum AppMode_e
|
|||||||
#define WM_USER_BOOT WM_USER+8
|
#define WM_USER_BOOT WM_USER+8
|
||||||
#define WM_USER_FULLSCREEN WM_USER+9
|
#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 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
|
typedef struct _IMAGE__ { int unused; } *HIMAGE; // DiskImage's /ImageInfo/ is hidden behind HIMAGE
|
||||||
|
@ -99,6 +99,12 @@ static unsigned __int64 g_nJoyCntrResetCycle = 0; // Abs cycle that joystick cou
|
|||||||
static short g_nPdlTrimX = 0;
|
static short g_nPdlTrimX = 0;
|
||||||
static short g_nPdlTrimY = 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()
|
void CheckJoystick0()
|
||||||
{
|
{
|
||||||
@ -425,7 +431,58 @@ static void DoAutofire(UINT uButton, BOOL& pressed)
|
|||||||
lastPressed[uButton] = nowPressed;
|
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;
|
address &= 0xFF;
|
||||||
|
|
||||||
@ -434,12 +491,19 @@ BYTE __stdcall JoyReadButton(WORD, WORD address, BYTE, BYTE, ULONG nCyclesLeft)
|
|||||||
if(joyinfo[joytype[1]] == DEVICE_JOYSTICK)
|
if(joyinfo[joytype[1]] == DEVICE_JOYSTICK)
|
||||||
CheckJoystick1();
|
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;
|
BOOL pressed = 0;
|
||||||
switch (address)
|
switch (address)
|
||||||
{
|
{
|
||||||
case 0x61:
|
case 0x61:
|
||||||
pressed = (buttonlatch[0] || joybutton[0] || setbutton[0] || keydown[JK_OPENAPPLE]);
|
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]);
|
pressed = (pressed || keydown[JK_BUTTON0]);
|
||||||
buttonlatch[0] = 0;
|
buttonlatch[0] = 0;
|
||||||
DoAutofire(0, pressed);
|
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)
|
DWORD JoyGetSnapshot(SS_IO_Joystick* pSS)
|
||||||
{
|
{
|
||||||
pSS->g_nJoyCntrResetCycle = g_nJoyCntrResetCycle;
|
pSS->g_nJoyCntrResetCycle = g_nJoyCntrResetCycle;
|
||||||
|
@ -23,6 +23,7 @@ BOOL JoyUsingKeyboardNumpad();
|
|||||||
void JoyDisableUsingMouse();
|
void JoyDisableUsingMouse();
|
||||||
void JoySetTrim(short nValue, bool bAxisX);
|
void JoySetTrim(short nValue, bool bAxisX);
|
||||||
short JoyGetTrim(bool bAxisX);
|
short JoyGetTrim(bool bAxisX);
|
||||||
|
void JoyportControl(const UINT uControl);
|
||||||
DWORD JoyGetSnapshot(SS_IO_Joystick* pSS);
|
DWORD JoyGetSnapshot(SS_IO_Joystick* pSS);
|
||||||
DWORD JoySetSnapshot(SS_IO_Joystick* pSS);
|
DWORD JoySetSnapshot(SS_IO_Joystick* pSS);
|
||||||
|
|
||||||
|
@ -488,6 +488,12 @@ BYTE __stdcall IO_Annunciator(WORD programcounter, WORD address, BYTE write, BYT
|
|||||||
// . PC=C2B5: LDA $C05D (CLRAN2)
|
// . PC=C2B5: LDA $C05D (CLRAN2)
|
||||||
|
|
||||||
// NB. AN3: For //e & //c these locations are now used to enabled/disabled DHIRES
|
// 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)
|
if (!write)
|
||||||
return MemReadFloatingBus(nCyclesLeft);
|
return MemReadFloatingBus(nCyclesLeft);
|
||||||
else
|
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)
|
BYTE __stdcall MemSetPaging (WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCyclesLeft)
|
||||||
{
|
{
|
||||||
address &= 0xFF;
|
address &= 0xFF;
|
||||||
DWORD lastmemmode = memmode;
|
DWORD lastmemmode = memmode;
|
||||||
|
#if defined(_DEBUG) && defined(DEBUG_FLIP_TIMINGS)
|
||||||
|
DebugFlip(address, nCyclesLeft);
|
||||||
|
#endif
|
||||||
|
|
||||||
// DETERMINE THE NEW MEMORY PAGING MODE.
|
// DETERMINE THE NEW MEMORY PAGING MODE.
|
||||||
if ((address >= 0x80) && (address <= 0x8F))
|
if ((address >= 0x80) && (address <= 0x8F))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user