Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Andrea Odetti 2020-01-18 19:32:56 +00:00
commit 3f39bc8f7b
23 changed files with 106 additions and 35 deletions

View file

@ -11,8 +11,7 @@ Tom Charlesworth
1.29.8.0 - ?
----------------------
. Debugger: Changed 'cycles' to be configurable (either absolute or relative).
- extended debugger commmand: videoinfo <dec|hex|apple|real|abs|rel>
. Debugger: Added new 'cycles <abs|rel>' command to show cycles as absolute or relative.
1.29.7.0 - 20 Dec 2019

View file

@ -87,6 +87,14 @@
Use this switch to allow Solid Apple (AltGr) to be used in combination with regular keys.<br>
When AltGr is pressed, Windows only sends a WM_CHAR message for (eg) international key codes; and so by default the emulator doesn't explicitly send a WM_CHAR message for regular keys when AltGr is being pressed.<br>
NB. Using this switch may prevent international keyboards from being able to type certain keys.<br><br>
-left-alt-control-buttons<br>
Use LEFT CONTROL & LEFT ALT for Open Apple & Solid Apple keys respectively.<br><br>
-right-alt-control-buttons<br>
Use RIGHT CONTROL & RIGHT ALT for Open Apple & Solid Apple keys respectively.<br><br>
-swap-buttons<br>
Swap the Windows keys used for Open Apple & Solid Apple keys.<br><br>
-use-real-printer<br>
Enables Advanced configuration control to allow dumping to a real printer<br><br>
-noreg<br>

View file

@ -33,6 +33,7 @@ then you should leave these values at 0.</li>
<li>When cursor keys are used for joystick emulation <strong>and</strong> are allowed to be read from the keyboard, then some games won't work correctly (eg. Lode Runner).</li>
<li>When cursor keys are blocked from being read from the keyboard, then simple command-line cursor editing in AppleSoft won't work.</li>
</ul>
<li>Swap 0/1: Swap buttons 0 and 1.</li>
<li>Auto-fire (all 3 buttons): For each button pressed, the button's state will be toggled when read.</li>
<li>Keyboard auto-centering: When keys used for joystick emulation are released then the joystick will return to the central position.</li>
</ul>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View file

@ -130,8 +130,9 @@ BEGIN
LTEXT "&Y-trim:",IDC_STATIC,115,56,28,8
CTEXT "0",IDC_STATIC,137,49,24,20,SS_CENTERIMAGE
CONTROL "Spin1",IDC_SPIN_YTRIM,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY,161,53,10,14
CONTROL "Allow cursor keys to be read from keyboard ",IDC_CURSORCONTROL,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,75,155,10
CONTROL "Allow cursor keys to be read from keyboard",IDC_CURSORCONTROL,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,75,150,10
CONTROL "Swap 0/1",IDC_SWAPBUTTONS0AND1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,162,75,41,10
CONTROL "Auto-fire (all 3 buttons)",IDC_AUTOFIRE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,90,89,10
CONTROL "Keyboard auto-centering",IDC_CENTERINGCONTROL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,90,96,10
CONTROL "&Scroll Lock acts as toggle for full-speed CPU",IDC_SCROLLLOCK_TOGGLE,

View file

@ -110,6 +110,7 @@
#define IDC_CURSORCONTROL 1066
#define IDC_AUTOFIRE 1067
#define IDC_CENTERINGCONTROL 1068
#define IDC_SWAPBUTTONS0AND1 1069
#define IDC_COMBO_HDD1 1078
#define IDC_COMBO_HDD2 1079
#define IDC_COMBO_DISK1 1080

View file

@ -702,6 +702,8 @@ void LoadConfiguration(void)
sg_PropertySheet.SetJoystickCursorControl(dwTmp);
if(REGLOAD(TEXT(REGVALUE_AUTOFIRE), &dwTmp))
sg_PropertySheet.SetAutofire(dwTmp);
if(REGLOAD(TEXT(REGVALUE_SWAP_BUTTONS_0_AND_1), &dwTmp))
sg_PropertySheet.SetButtonsSwapState(dwTmp ? true : false);
if(REGLOAD(TEXT(REGVALUE_CENTERING_CONTROL), &dwTmp))
sg_PropertySheet.SetJoystickCenteringControl(dwTmp);
@ -1232,7 +1234,7 @@ static void ExceptionHandler(const char* pError)
//---------------------------------------------------------------------------
static void ProcessCmdLine(LPSTR lpCmdLine);
static bool ProcessCmdLine(LPSTR lpCmdLine);
static void GetAppleWinVersion(void);
static void OneTimeInitialization(HINSTANCE passinstance);
static void RepeatInitialization(void);
@ -1300,7 +1302,9 @@ static CmdLine g_cmdLine;
int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
{
ProcessCmdLine(lpCmdLine);
if (!ProcessCmdLine(lpCmdLine))
return 0;
GetAppleWinVersion();
OneTimeInitialization(passinstance);
@ -1357,9 +1361,10 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
return 0;
}
static void ProcessCmdLine(LPSTR lpCmdLine)
static bool ProcessCmdLine(LPSTR lpCmdLine)
{
const std::string strCmdLine(lpCmdLine); // Keep a copy for log ouput
std::string strUnsupported;
while (*lpCmdLine)
{
@ -1576,19 +1581,19 @@ static void ProcessCmdLine(LPSTR lpCmdLine)
{
JoySetHookAltKeys(false);
}
else if (strcmp(lpCmdLine, "-left-control-alt-buttons") == 0)
else if (strcmp(lpCmdLine, "-left-alt-control-buttons") == 0) // GH#743
{
JoySetButtonVirtualKey(0, VK_CONTROL);
JoySetButtonVirtualKey(1, VK_MENU);
}
else if (strcmp(lpCmdLine, "-right-alt-control-buttons") == 0)
else if (strcmp(lpCmdLine, "-right-alt-control-buttons") == 0) // GH#743
{
JoySetButtonVirtualKey(0, VK_MENU | KF_EXTENDED);
JoySetButtonVirtualKey(1, VK_CONTROL | KF_EXTENDED);
}
else if (strcmp(lpCmdLine, "-swap-buttons") == 0)
{
JoySwapButton0and1(true);
sg_PropertySheet.SetButtonsSwapState(true);
}
else if (strcmp(lpCmdLine, "-spkr-inc") == 0)
{
@ -1683,12 +1688,31 @@ static void ProcessCmdLine(LPSTR lpCmdLine)
else // unsupported
{
LogFileOutput("Unsupported arg: %s\n", lpCmdLine);
strUnsupported += lpCmdLine;
strUnsupported += "\n";
}
lpCmdLine = lpNextArg;
}
LogFileOutput("CmdLine: %s\n", strCmdLine.c_str());
bool ok = true;
if (!strUnsupported.empty())
{
std::string msg("Unsupported commands:\n\n");
msg += strUnsupported;
msg += "\n";
msg += "Continue running AppleWin?";
int res = MessageBox(GetDesktopWindow(), // NB. g_hFrameWindow is not yet valid
msg.c_str(),
"AppleWin Command Line",
MB_ICONSTOP | MB_SETFOREGROUND | MB_YESNO);
ok = (res != IDNO);
}
return ok;
}
static void GetAppleWinVersion(void)

View file

@ -85,6 +85,7 @@ enum AppMode_e
#define REGVALUE_CURSOR_CONTROL "Joystick Cursor Control"
#define REGVALUE_CENTERING_CONTROL "Joystick Centering Control"
#define REGVALUE_AUTOFIRE "Autofire"
#define REGVALUE_SWAP_BUTTONS_0_AND_1 "Swap buttons 0 and 1"
#define REGVALUE_MOUSE_CROSSHAIR "Mouse crosshair"
#define REGVALUE_MOUSE_RESTRICT_TO_WINDOW "Mouse restrict to window"
#define REGVALUE_THE_FREEZES_F8_ROM "The Freeze's F8 Rom"

View file

@ -18,6 +18,8 @@ __interface IPropertySheet
void SetJoystickCenteringControl(UINT uValue);
UINT GetAutofire(UINT uButton);
void SetAutofire(UINT uValue);
bool GetButtonsSwapState(void);
void SetButtonsSwapState(bool value);
UINT GetMouseShowCrosshair(void);
void SetMouseShowCrosshair(UINT uValue);
UINT GetMouseRestrictToWindow(void);

View file

@ -197,6 +197,7 @@ BOOL CPageInput::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM
CheckDlgButton(hWnd, IDC_CURSORCONTROL, m_uCursorControl ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hWnd, IDC_AUTOFIRE, m_bmAutofire ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hWnd, IDC_SWAPBUTTONS0AND1, m_bSwapButtons0and1 ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hWnd, IDC_CENTERINGCONTROL, m_uCenteringControl == JOYSTICK_MODE_CENTERING ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hWnd, IDC_SCROLLLOCK_TOGGLE, m_uScrollLockToggle ? BST_CHECKED : BST_UNCHECKED);
@ -234,6 +235,7 @@ void CPageInput::DlgOK(HWND hWnd)
m_uCursorControl = IsDlgButtonChecked(hWnd, IDC_CURSORCONTROL) ? 1 : 0;
m_bmAutofire = IsDlgButtonChecked(hWnd, IDC_AUTOFIRE) ? 7 : 0; // bitmap of 3 bits
m_bSwapButtons0and1 = IsDlgButtonChecked(hWnd, IDC_SWAPBUTTONS0AND1) ? true : false;
m_uCenteringControl = IsDlgButtonChecked(hWnd, IDC_CENTERINGCONTROL) ? 1 : 0;
m_uMouseShowCrosshair = IsDlgButtonChecked(hWnd, IDC_MOUSE_CROSSHAIR) ? 1 : 0;
m_uMouseRestrictToWindow = IsDlgButtonChecked(hWnd, IDC_MOUSE_RESTRICT_TO_WINDOW) ? 1 : 0;
@ -243,6 +245,7 @@ void CPageInput::DlgOK(HWND hWnd)
REGSAVE(TEXT(REGVALUE_SCROLLLOCK_TOGGLE), m_uScrollLockToggle);
REGSAVE(TEXT(REGVALUE_CURSOR_CONTROL), m_uCursorControl);
REGSAVE(TEXT(REGVALUE_AUTOFIRE), m_bmAutofire);
REGSAVE(TEXT(REGVALUE_SWAP_BUTTONS_0_AND_1), m_bSwapButtons0and1);
REGSAVE(TEXT(REGVALUE_CENTERING_CONTROL), m_uCenteringControl);
REGSAVE(TEXT(REGVALUE_MOUSE_CROSSHAIR), m_uMouseShowCrosshair);
REGSAVE(TEXT(REGVALUE_MOUSE_RESTRICT_TO_WINDOW), m_uMouseRestrictToWindow);

View file

@ -16,6 +16,7 @@ public:
m_uCursorControl(1),
m_uCenteringControl(JOYSTICK_MODE_CENTERING),
m_bmAutofire(0),
m_bSwapButtons0and1(false),
m_uMouseShowCrosshair(0),
m_uMouseRestrictToWindow(0),
m_CPMChoice(CPM_UNPLUGGED)
@ -34,6 +35,8 @@ public:
void SetJoystickCenteringControl(UINT uValue){ m_uCenteringControl = uValue; }
UINT GetAutofire(UINT uButton) { return (m_bmAutofire >> uButton) & 1; } // Get a specific button
void SetAutofire(UINT uValue) { m_bmAutofire = uValue; } // Set all buttons
bool GetButtonsSwapState(void){ return m_bSwapButtons0and1; }
void SetButtonsSwapState(bool value){ m_bSwapButtons0and1 = value; }
UINT GetMouseShowCrosshair(void){ return m_uMouseShowCrosshair; }
void SetMouseShowCrosshair(UINT uValue){ m_uMouseShowCrosshair = uValue; }
UINT GetMouseRestrictToWindow(void){ return m_uMouseRestrictToWindow; }
@ -81,6 +84,7 @@ private:
UINT m_uCursorControl; // 1 = Allow AppleII to read cursor keys from $C000 (when using keyboard for joystick emu)
UINT m_uCenteringControl; // 1 = Centering, 0=Floating (when using keyboard for joystick emu)
UINT m_bmAutofire; // bitmask b2:0
bool m_bSwapButtons0and1;
UINT m_uMouseShowCrosshair;
UINT m_uMouseRestrictToWindow;

View file

@ -41,6 +41,8 @@ public:
virtual void SetJoystickCenteringControl(UINT uValue){ m_PageInput.SetJoystickCenteringControl(uValue); }
virtual UINT GetAutofire(UINT uButton) { return m_PageInput.GetAutofire(uButton); }
virtual void SetAutofire(UINT uValue) { m_PageInput.SetAutofire(uValue); }
virtual bool GetButtonsSwapState(void) { return m_PageInput.GetButtonsSwapState(); }
virtual void SetButtonsSwapState(bool value) { m_PageInput.SetButtonsSwapState(value); }
virtual UINT GetMouseShowCrosshair(void){ return m_PageInput.GetMouseShowCrosshair(); }
virtual void SetMouseShowCrosshair(UINT uValue){ m_PageInput.SetMouseShowCrosshair(uValue); }
virtual UINT GetMouseRestrictToWindow(void){ return m_PageInput.GetMouseRestrictToWindow(); }

View file

@ -6873,10 +6873,6 @@ Update_t CmdVideoScannerInfo(int nArgs)
g_videoScannerDisplayInfo.isHorzReal = true;
else if (strcmp(g_aArgs[1].sArg, "apple") == 0)
g_videoScannerDisplayInfo.isHorzReal = false;
else if (strcmp(g_aArgs[1].sArg, "abs") == 0)
g_videoScannerDisplayInfo.isAbsCycle = true;
else if (strcmp(g_aArgs[1].sArg, "rel") == 0)
g_videoScannerDisplayInfo.isAbsCycle = false;
else
return Help_Arg_1(CMD_VIDEO_SCANNER_INFO);
}
@ -6888,6 +6884,31 @@ Update_t CmdVideoScannerInfo(int nArgs)
return UPDATE_ALL;
}
// Cycles __________________________________________________________________________________________
Update_t CmdCyclesInfo(int nArgs)
{
if (nArgs != 1)
{
return Help_Arg_1(CMD_CYCLES_INFO);
}
else
{
if (strcmp(g_aArgs[1].sArg, "abs") == 0)
g_videoScannerDisplayInfo.isAbsCycle = true;
else if (strcmp(g_aArgs[1].sArg, "rel") == 0)
g_videoScannerDisplayInfo.isAbsCycle = false;
else
return Help_Arg_1(CMD_CYCLES_INFO);
}
TCHAR sText[CONSOLE_WIDTH];
ConsoleBufferPushFormat(sText, "Cycles display updated: %s", g_aArgs[1].sArg);
ConsoleBufferToDisplay();
return UPDATE_ALL;
}
// View ___________________________________________________________________________________________
// See: CmdWindowViewOutput (int nArgs)

View file

@ -121,6 +121,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
{TEXT("PAGEDN" ) , CmdCursorPageDown , CMD_CURSOR_PAGE_DOWN , "Scroll down one scren" },
{TEXT("PAGEDOWN256") , CmdCursorPageDown256 , CMD_CURSOR_PAGE_DOWN_256 , "Scroll down 256 bytes" }, // Shift
{TEXT("PAGEDOWN4K" ) , CmdCursorPageDown4K , CMD_CURSOR_PAGE_DOWN_4K , "Scroll down 4096 bytes" }, // Ctrl
// Cycles info
{TEXT("CYCLES") , CmdCyclesInfo , CMD_CYCLES_INFO, "Cycles display configuration" },
// Disassembler Data
{TEXT("Z") , CmdDisasmDataDefByte1 , CMD_DISASM_DATA , "Treat byte [range] as data" },
{TEXT("X") , CmdDisasmDataDefCode , CMD_DISASM_CODE , "Treat byte [range] as code" },

View file

@ -1406,13 +1406,18 @@ Update_t CmdHelpSpecific (int nArgs)
ConsoleColorizePrint( sText, " Usage: symbol" );
ConsoleBufferPush( " Looks up symbol in all 3 symbol tables: main, user, source" );
break;
// Cycles
case CMD_CYCLES_INFO:
ConsoleColorizePrint(sText, " Usage: <abs|rel>");
ConsoleBufferPush(" Where:");
ConsoleBufferPush(" <abs|rel> changes cycle output to absolute/relative");
break;
// Video-Scanner
case CMD_VIDEO_SCANNER_INFO:
ConsoleColorizePrint(sText, " Usage: <dec|hex|real|apple|abs|rel>");
ConsoleColorizePrint(sText, " Usage: <dec|hex|real|apple>");
ConsoleBufferPush(" Where:");
ConsoleBufferPush(" <dec|hex> changes output to dec/hex");
ConsoleBufferPush(" <real|apple> alters horz value to hbl-l,visible,hbl-r or hbl-r+l,visible");
ConsoleBufferPush(" <abs|rel> changes cycle output to absolute/relative");
{
char sText2[CONSOLE_WIDTH];
ConsolePrintFormat(sText2, " %sYellow%s=invisible (hbl or vbl active) / %sGreen%s=visible"

View file

@ -375,6 +375,8 @@
, CMD_CURSOR_PAGE_DOWN
, CMD_CURSOR_PAGE_DOWN_256 // Down to nearest page boundary
, CMD_CURSOR_PAGE_DOWN_4K // Down to nearest 4K boundary
// Cycles info
, CMD_CYCLES_INFO
// Disassembler Data
, CMD_DISASM_DATA
, CMD_DISASM_CODE
@ -662,6 +664,10 @@
Update_t CmdCursorPageUp (int nArgs);
Update_t CmdCursorPageUp256 (int nArgs);
Update_t CmdCursorPageUp4K (int nArgs);
// Cycles info
Update_t CmdCyclesInfo (int nArgs);
// Disk
Update_t CmdDisk (int nArgs);
// Help

View file

@ -872,7 +872,7 @@ void __stdcall Disk2InterfaceCard::ReadWrite(WORD pc, WORD addr, BYTE bWrite, BY
if (!pFloppy->m_trackimagedata)
{
m_floppyLatch = 0xFF;
m_floppyLatch = rand() & 0xFF; // GH#748
return;
}
@ -1056,7 +1056,7 @@ void __stdcall Disk2InterfaceCard::DataLatchReadWriteWOZ(WORD pc, WORD addr, BYT
if (!floppy.m_trackimagedata)
{
_ASSERT(0); // Can't happen for WOZ - ReadTrack() should return an empty track
m_floppyLatch = 0xFF;
m_floppyLatch = rand() & 0xFF; // GH#748
return;
}

View file

@ -1324,8 +1324,6 @@ eDetectResult CWOZHelper::ProcessChunks(const LPBYTE pImage, const DWORD dwImage
{
case INFO_CHUNK_ID:
m_pInfo = (InfoChunkv2*)(pImage32-2);
if (m_pInfo->v1.version > InfoChunk::maxSupportedVersion)
return eMismatch;
if (m_pInfo->v1.diskType != InfoChunk::diskType5_25)
return eMismatch;
break;

View file

@ -202,8 +202,8 @@ public:
virtual UINT GetMaxHdrSize(void) { return sizeof(WOZHeader); }
eDetectResult ProcessChunks(const LPBYTE pImage, const DWORD dwImageSize, DWORD& dwOffset, BYTE*& pTrackMap);
bool IsWriteProtected(void) { return m_pInfo->v1.writeProtected == 1; }
BYTE GetOptimalBitTiming(void) { return (m_pInfo->v1.version == 1) ? CWOZHelper::InfoChunkv2::optimalBitTiming5_25 : m_pInfo->optimalBitTiming; }
UINT GetMaxNibblesPerTrack(void) { return (m_pInfo->v1.version == 1) ? CWOZHelper::WOZ1_TRACK_SIZE : m_pInfo->largestTrack*CWOZHelper::BLOCK_SIZE; }
BYTE GetOptimalBitTiming(void) { return (m_pInfo->v1.version >= 2) ? m_pInfo->optimalBitTiming : CWOZHelper::InfoChunkv2::optimalBitTiming5_25; }
UINT GetMaxNibblesPerTrack(void) { return (m_pInfo->v1.version >= 2) ? m_pInfo->largestTrack*CWOZHelper::BLOCK_SIZE : CWOZHelper::WOZ1_TRACK_SIZE; }
static const UINT32 ID1_WOZ1 = '1ZOW'; // 'WOZ1'
static const UINT32 ID1_WOZ2 = '2ZOW'; // 'WOZ2'
@ -259,7 +259,6 @@ private:
// String in UTF-8. No BOM. Padded to 32 bytes
// using space character (0x20).
static const BYTE maxSupportedVersion = 2;
static const BYTE diskType5_25 = 1;
static const BYTE diskType3_5 = 2;
};

View file

@ -1420,6 +1420,7 @@ LRESULT CALLBACK FrameWndProc (
LogOutput("WM_KEYDOWN: %08X (scanCode=%04X)\n", wparam, (lparam>>16)&0xfff);
#endif
if (!IsJoyKey &&
!KeybGetAltStatus() && // GH#749 - AltGr also fakes CTRL being pressed!
(g_nAppMode != MODE_LOGO)) // !MODE_LOGO - not emulating so don't pass to the VM's keyboard
{
// GH#678 Alternate key(s) to toggle max speed

View file

@ -303,13 +303,6 @@ void JoyInitialize()
//===========================================================================
static bool g_swapButton0and1 = false;
void JoySwapButton0and1(bool swap)
{
g_swapButton0and1 = swap;
}
static UINT g_buttonVirtKey[2] = { VK_MENU, VK_MENU | KF_EXTENDED }; // VK_MENU == ALT Key
void JoySetButtonVirtualKey(UINT button, UINT virtKey)
@ -350,13 +343,14 @@ BOOL JoyProcessKey(int virtkey, bool extended, bool down, bool autorep)
BOOL keychange = 0;
bool bIsCursorKey = false;
const bool swapButtons0and1 = sg_PropertySheet.GetButtonsSwapState();
if (virtKeyWithExtended == g_buttonVirtKey[!g_swapButton0and1 ? 0 : 1])
if (virtKeyWithExtended == g_buttonVirtKey[!swapButtons0and1 ? 0 : 1])
{
keychange = 1;
keydown[JK_OPENAPPLE] = down;
}
else if (virtKeyWithExtended == g_buttonVirtKey[!g_swapButton0and1 ? 1 : 0])
else if (virtKeyWithExtended == g_buttonVirtKey[!swapButtons0and1 ? 1 : 0])
{
keychange = 1;
keydown[JK_CLOSEDAPPLE] = down;

View file

@ -25,7 +25,6 @@ void JoySetTrim(short nValue, bool bAxisX);
short JoyGetTrim(bool bAxisX);
void JoyportControl(const UINT uControl);
void JoySetHookAltKeys(bool hook);
void JoySwapButton0and1(bool swap);
void JoySetButtonVirtualKey(UINT button, UINT virtKey);
void JoySaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
void JoyLoadSnapshot(class YamlLoadHelper& yamlLoadHelper);

View file

@ -108,8 +108,8 @@ VIDEO SOFT SWITCHES
$C055 R/W PAGE2ON Select page2 display (or aux video memory)
$C056 R/W HIRESOFF Select low resolution graphics
$C057 R/W HIRESON Select high resolution graphics
$C05E R/W DHIRESOFF Select single (7M) resolution graphics
$C05F R/W DHIRESON Select double (14M) resolution graphics
$C05E R/W DHIRESON Select double (14M) resolution graphics
$C05F R/W DHIRESOFF Select single (7M) resolution graphics
SOFT SWITCH STATUS FLAGS
$C010 R7 AKD 1=key pressed 0=keys free (clears strobe)