Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
0a087e40ae
27 changed files with 563 additions and 153 deletions
|
@ -8,6 +8,34 @@ https://github.com/AppleWin/AppleWin/issues/new
|
|||
|
||||
Tom Charlesworth
|
||||
|
||||
|
||||
1.27.12.0 - 17 Nov 2018
|
||||
-----------------------
|
||||
. [Change #574] Add support for PAL/European or custom 8K video ROMs:
|
||||
- Added new command line switch: -videorom <file>
|
||||
- Replaces the video ROM for the Enhanced //e.
|
||||
- Support video ROM sizes of 4K, 8K and 16K (top 8K only).
|
||||
- NB. The rocker switch is set to the European video ROM position.
|
||||
- F10 (for //e or Enhanced //e models) emulates the PAL //e's rocker switch (under the keyboard).
|
||||
- Use to toggle between European or US video ROM.
|
||||
. [Change #583] Added new switch: '-no-hook-alt':
|
||||
- Used to prevent left/right ALT from emulating Open/Solid Apple keys.
|
||||
- For European keyboards where AltGr is needed to type keys like '[',']'.
|
||||
|
||||
|
||||
1.27.10.0 - 4 Nov 2018
|
||||
----------------------
|
||||
. [Change #590] Apple II original: default to 48K (so no LC installed in slot-0).
|
||||
- Added new command line switch: -s0 <languagecard|lc>
|
||||
('lc' is an alias for 'languagecard')
|
||||
- When LC is in slot-0, it now use the Apple II+'s F8 (auto-start) ROM
|
||||
. [Change #408] Support Saturn 64K and 128K cards in slot-0.
|
||||
- Added new command line switch: -s0 <saturn|saturn64|saturn128>
|
||||
('saturn' is an alias for 'saturn128')
|
||||
. [Bug #591] Save-state wasn't preserving the 'key-waiting' flag.
|
||||
. [Bug #587] Debugger: disassembly for branch targets < $1000 were missing the leading '0'.
|
||||
|
||||
|
||||
1.27.9.0 - 2 Oct 2018
|
||||
---------------------
|
||||
. [Bug #582] Support for partial disk II latch reads when accesses are very close.
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
-s0 <saturn|saturn64|saturn128><br>
|
||||
Insert a Saturn 64K or Saturn 128K card into slot 0 in Apple II or Apple II+ machines (or similar clone).<br>
|
||||
Where -s0 saturn is an alias for -s0 saturn128.<br><br>
|
||||
-s0 <languagecard|lc><br>
|
||||
Insert an Apple 16K Language Card into slot 0 in Apple II and use the F8 auto-start ROM.<br>
|
||||
NB. The Apple II+ already defaults to having a Language Card, so this switch is not required.<br><br>
|
||||
-s7 empty<br>
|
||||
Remove the hard disk controller card from slot 7.<br>
|
||||
Useful to allow a floppy disk to boot from slot 6, drive 1. Use in combination with -d1.<br><br>
|
||||
|
@ -41,6 +44,8 @@
|
|||
NB. This changes the display resolution (and restores on exit).<br><br>
|
||||
-f8rom <rom-file><br>
|
||||
Use custom 2K ROM at [$F800..$FFFF]. <rom-file> must be 2048 bytes long<br><br>
|
||||
-videorom <file><br>
|
||||
Use an alternate European or custom 4K, 8K or 16K video ROM.<br><br>
|
||||
-printscreen<br>
|
||||
Enable the dialog box to display the last file saved to<br><br>
|
||||
-no-printscreen-key<br>
|
||||
|
@ -48,6 +53,8 @@
|
|||
-no-hook-system-key<br>
|
||||
Prevent certain system key combinations from being hooked (to prevent the emulator from trapping ALT+ESC, ALT+SPACE, ALT+TAB and CTRL+ESC). This means that the equivalent Open Apple+<key> combinations won't work within the emulator.<br>
|
||||
NB. This switch takes precedence over -hook-alt-tab and -hook-altgr-control.<br><br>
|
||||
-no-hook-alt<br>
|
||||
Prevent the left and right ALT keys from being hooked (eg. to prevent emulation of Open/Solid Apple keys via the ALT keys).<br><br>
|
||||
-hook-alt-tab<br>
|
||||
By default the emulator doesn't hook ALT+TAB. Use this to allow Open Apple+TAB to be readable by the emulated machine.<br><br>
|
||||
-hook-altgr-control<br>
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
the predecessors of the Apple //e: the Apple ][ and Apple ][+. Besides running
|
||||
with a different Apple system ROM, some differences are discussed below.<br>
|
||||
<ul>
|
||||
<li>Apple ][ : Non-autobooting, 64K machine, no lower-case, no 80-column, 6502 CPU
|
||||
<li>Apple ][+ : Autobooting version of the Apple ][
|
||||
<li>Apple ][ : 48K non-autostarting, Integer BASIC, no lower-case, no 80-column, 6502 CPU
|
||||
<li>Apple ][+ : 64K autostarting, Applesoft BASIC version of the Apple ][
|
||||
<li>Apple //e : 128K machine, lower-case, 80-column, 6502 CPU</li>
|
||||
<li>Enhanced Apple //e : 128K machine, lower-case, 80-column, 65C02 CPU</li>
|
||||
<li>Clone (specific model selectable from Advanced page)</li>
|
||||
|
|
|
@ -86,10 +86,11 @@
|
|||
through the configuration dialog. <br>NB. Use Shift+F9 to reverse-cycle the display modes.</p>
|
||||
<p><span style="font-weight: bold;">Function Key F9 + Ctrl + Shift:</span><br>
|
||||
This PC function key combo will toggle 50% scanline mode</p>
|
||||
<p><span style="font-weight: bold;">Function Key F10 (or Ctrl+left mouse button):</span><br>
|
||||
This PC function key will stop emulating an Apple joystick with the PC's mouse.<br>
|
||||
In Pravets 8A emulation mode it servers as Caps Lock and Ctrl+F10 shall
|
||||
be used to stop emulating an Apple joystick with the PC's mouse.</p>
|
||||
<p><span style="font-weight: bold;">Function Key F10:</span><br>
|
||||
In //e or Enhanced //e emulation mode it will emulate the rocker switch for European video ROM selection. Use the <a href="CommandLine.html">Command Line</a> switch to use an alternate European video ROM file.<br>
|
||||
In Pravets 8A emulation mode it servers as Caps Lock.</p>
|
||||
<p><span style="font-weight: bold;">Function Key F10 + Ctrl (or Ctrl+left mouse button):</span><br>
|
||||
This PC function key combo will stop emulating an Apple joystick with the PC's mouse.<br>
|
||||
<p><span style="font-weight: bold;">Function Keys F11-F12:</span><br>
|
||||
These PC function keys correspond to saving/loading a <a href="savestate.html">save-state</a>
|
||||
file.</p>
|
||||
|
|
|
@ -252,8 +252,8 @@ DISK_ICON ICON "DISK.ICO"
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,27,9,0
|
||||
PRODUCTVERSION 1,27,9,0
|
||||
FILEVERSION 1,27,12,0
|
||||
PRODUCTVERSION 1,27,12,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -271,12 +271,12 @@ BEGIN
|
|||
VALUE "Comments", "https://github.com/AppleWin"
|
||||
VALUE "CompanyName", "AppleWin"
|
||||
VALUE "FileDescription", "Apple //e Emulator for Windows"
|
||||
VALUE "FileVersion", "1, 27, 9, 0"
|
||||
VALUE "FileVersion", "1, 27, 12, 0"
|
||||
VALUE "InternalName", "APPLEWIN"
|
||||
VALUE "LegalCopyright", " 1994-2018 Michael O'Brien, Oliver Schmidt, Tom Charlesworth, Michael Pohoreski, Nick Westgate, Linards Ticmanis"
|
||||
VALUE "OriginalFilename", "APPLEWIN.EXE"
|
||||
VALUE "ProductName", "Apple //e Emulator"
|
||||
VALUE "ProductVersion", "1, 27, 9, 0"
|
||||
VALUE "ProductVersion", "1, 27, 12, 0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -1142,6 +1142,7 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
|||
bool bSetFullScreen = false;
|
||||
bool bBoot = false;
|
||||
bool bChangedDisplayResolution = false;
|
||||
bool bSlot0LanguageCard = false;
|
||||
bool bSlot7Empty = false;
|
||||
UINT bestWidth = 0, bestHeight = 0;
|
||||
LPSTR szImageName_drive[NUM_DRIVES] = {NULL,NULL};
|
||||
|
@ -1269,20 +1270,41 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
|||
lpCmdLine = GetCurrArg(lpNextArg);
|
||||
lpNextArg = GetNextArg(lpNextArg);
|
||||
|
||||
// "The boards consist of 16K banks of memory (4 banks for the 64K board, 8 banks for the 128K), accessed one at a time" - Ref: "64K/128K RAM BOARD", Saturn Systems, Ch.1 Introduction(pg-5)
|
||||
if (strcmp(lpCmdLine, "saturn") == 0 || strcmp(lpCmdLine, "saturn128") == 0)
|
||||
uSaturnBanks = Saturn128K::kMaxSaturnBanks;
|
||||
else if (strcmp(lpCmdLine, "saturn64") == 0)
|
||||
uSaturnBanks = Saturn128K::kMaxSaturnBanks/2;
|
||||
else if (strcmp(lpCmdLine, "languagecard") == 0 || strcmp(lpCmdLine, "lc") == 0)
|
||||
bSlot0LanguageCard = true;
|
||||
}
|
||||
else if (strcmp(lpCmdLine, "-f8rom") == 0) // Use custom 2K ROM at [$F800..$FFFF]
|
||||
{
|
||||
lpCmdLine = GetCurrArg(lpNextArg);
|
||||
lpNextArg = GetNextArg(lpNextArg);
|
||||
|
||||
if (g_hCustomRomF8 != INVALID_HANDLE_VALUE) // Stop resource leak if -f8rom is specified twice!
|
||||
CloseHandle(g_hCustomRomF8);
|
||||
|
||||
g_hCustomRomF8 = CreateFile(lpCmdLine, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
|
||||
if ((g_hCustomRomF8 == INVALID_HANDLE_VALUE) || (GetFileSize(g_hCustomRomF8, NULL) != 0x800))
|
||||
g_bCustomRomF8Failed = true;
|
||||
}
|
||||
else if (strcmp(lpCmdLine, "-videorom") == 0) // Use 4K,8K or 16K video ROM for Enhanced //e
|
||||
{
|
||||
lpCmdLine = GetCurrArg(lpNextArg);
|
||||
lpNextArg = GetNextArg(lpNextArg);
|
||||
|
||||
if (!ReadVideoRomFile(lpCmdLine))
|
||||
{
|
||||
std::string msg = "Failed to load video rom (not found or not exactly 4/8/16KiB)";
|
||||
LogFileOutput("%s", msg.c_str());
|
||||
MessageBox(g_hFrameWindow, msg.c_str(), TEXT("AppleWin Error"), MB_OK);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetVideoRomRockerSwitch(true); // Use PAL char set
|
||||
}
|
||||
}
|
||||
else if (strcmp(lpCmdLine, "-printscreen") == 0) // Turn on display of the last filename print screen was saved to
|
||||
{
|
||||
g_bDisplayPrintScreenFileName = true;
|
||||
|
@ -1307,6 +1329,10 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
|||
{
|
||||
g_bHookAltGrControl = true;
|
||||
}
|
||||
else if (strcmp(lpCmdLine, "-no-hook-alt") == 0) // GH#583
|
||||
{
|
||||
JoySetHookAltKeys(false);
|
||||
}
|
||||
else if (strcmp(lpCmdLine, "-spkr-inc") == 0)
|
||||
{
|
||||
lpCmdLine = GetCurrArg(lpNextArg);
|
||||
|
@ -1470,6 +1496,12 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
|||
uSaturnBanks = 0; // Don't reapply after a restart
|
||||
}
|
||||
|
||||
if (bSlot0LanguageCard)
|
||||
{
|
||||
SetExpansionMemType(CT_LanguageCard);
|
||||
bSlot0LanguageCard = false; // Don't reapply after a restart
|
||||
}
|
||||
|
||||
DebugInitialize();
|
||||
LogFileOutput("Main: DebugInitialize()\n");
|
||||
|
||||
|
@ -1537,7 +1569,9 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
|||
|
||||
if (g_bCustomRomF8Failed)
|
||||
{
|
||||
MessageBox(g_hFrameWindow, "Failed to load custom F8 rom (not found or not exactly 2KB)", TEXT("AppleWin Error"), MB_OK);
|
||||
std::string msg = "Failed to load custom F8 rom (not found or not exactly 2KiB)";
|
||||
LogFileOutput("%s", msg.c_str());
|
||||
MessageBox(g_hFrameWindow, msg.c_str(), TEXT("AppleWin Error"), MB_OK);
|
||||
bShutdown = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -193,9 +193,14 @@ enum eApple2Type {
|
|||
A2TYPE_MAX
|
||||
};
|
||||
|
||||
inline bool IsApple2Original(eApple2Type type) // Apple ][
|
||||
{
|
||||
return type == A2TYPE_APPLE2;
|
||||
}
|
||||
|
||||
inline bool IsApple2Plus(eApple2Type type) // Apple ][,][+
|
||||
{
|
||||
return (type & (APPLE2E_MASK|APPLE2C_MASK)) == 0;
|
||||
return ((type & (APPLE2E_MASK|APPLE2C_MASK)) == 0) && !(type & APPLECLONE_MASK);
|
||||
}
|
||||
|
||||
inline bool IsClone(eApple2Type type)
|
||||
|
@ -205,8 +210,7 @@ inline bool IsClone(eApple2Type type)
|
|||
|
||||
inline bool IsApple2PlusOrClone(eApple2Type type) // Apple ][,][+ or clone ][,][+
|
||||
{
|
||||
return ((type & (APPLE2E_MASK|APPLE2C_MASK)) == 0)
|
||||
|| (type & APPLECLONE_MASK) && !(type & A2TYPE_CLONE_A2E);
|
||||
return (type & (APPLE2E_MASK|APPLE2C_MASK)) == 0;
|
||||
}
|
||||
|
||||
extern eApple2Type g_Apple2Type;
|
||||
|
|
|
@ -3639,7 +3639,7 @@ Update_t CmdFlagClear (int nArgs)
|
|||
{
|
||||
int iFlag = (g_iCommand - CMD_FLAG_CLR_C);
|
||||
|
||||
if (g_iCommand == CMD_FLAG_CLEAR)
|
||||
if (g_iCommand == CMD_FLAG_CLEAR) // Undocumented: "cl f f ... f", eg: "se n v c" (TODO: Conflicts with monitor command #L -> 000CL)
|
||||
{
|
||||
int iArg = nArgs;
|
||||
while (iArg)
|
||||
|
@ -3648,9 +3648,10 @@ Update_t CmdFlagClear (int nArgs)
|
|||
while (iFlag < _6502_NUM_FLAGS)
|
||||
{
|
||||
// if (g_aFlagNames[iFlag] == g_aArgs[iArg].sArg[0])
|
||||
if (g_aBreakpointSource[ BP_SRC_FLAG_N + iFlag ][0] == g_aArgs[iArg].sArg[0])
|
||||
if (g_aBreakpointSource[ BP_SRC_FLAG_N - iFlag ][0] == toupper(g_aArgs[iArg].sArg[0]))
|
||||
{
|
||||
regs.ps &= ~(1 << iFlag);
|
||||
regs.ps &= ~(1 << (7-iFlag));
|
||||
break;
|
||||
}
|
||||
iFlag++;
|
||||
}
|
||||
|
@ -3670,7 +3671,7 @@ Update_t CmdFlagSet (int nArgs)
|
|||
{
|
||||
int iFlag = (g_iCommand - CMD_FLAG_SET_C);
|
||||
|
||||
if (g_iCommand == CMD_FLAG_SET)
|
||||
if (g_iCommand == CMD_FLAG_SET) // Undocumented: "se f f ... f", eg: "se n v c"
|
||||
{
|
||||
int iArg = nArgs;
|
||||
while (iArg)
|
||||
|
@ -3679,9 +3680,10 @@ Update_t CmdFlagSet (int nArgs)
|
|||
while (iFlag < _6502_NUM_FLAGS)
|
||||
{
|
||||
// if (g_aFlagNames[iFlag] == g_aArgs[iArg].sArg[0])
|
||||
if (g_aBreakpointSource[ BP_SRC_FLAG_N + iFlag ][0] == g_aArgs[iArg].sArg[0])
|
||||
if (g_aBreakpointSource[ BP_SRC_FLAG_N - iFlag ][0] == toupper(g_aArgs[iArg].sArg[0]))
|
||||
{
|
||||
regs.ps |= (1 << iFlag);
|
||||
regs.ps |= (1 << (7-iFlag));
|
||||
break;
|
||||
}
|
||||
iFlag++;
|
||||
}
|
||||
|
@ -4151,8 +4153,12 @@ Update_t CmdConfigSetDebugDir (int nArgs)
|
|||
{
|
||||
_tcsncpy( sPath, g_sCurrentDir, 2 ); // Prefix with drive letter & colon
|
||||
sPath[2] = 0;
|
||||
_tcscat( sPath, g_aArgs[1].sArg );
|
||||
}
|
||||
else
|
||||
{
|
||||
_tcscpy( sPath, g_aArgs[1].sArg );
|
||||
}
|
||||
_tcscat( sPath, g_aArgs[1].sArg );
|
||||
}
|
||||
else // Relative
|
||||
{
|
||||
|
@ -6454,7 +6460,8 @@ Update_t CmdOutputRun (int nArgs)
|
|||
|
||||
// if (g_aArgs[1].bType & TYPE_QUOTED_2)
|
||||
|
||||
_tcscpy( sMiniFileName, pFileName );
|
||||
_tcsncpy( sMiniFileName, pFileName, sizeof(sMiniFileName) );
|
||||
sMiniFileName[sizeof(sMiniFileName)-1] = 0;
|
||||
// _tcscat( sMiniFileName, ".aws" ); // HACK: MAGIC STRING
|
||||
|
||||
if (pFileName[0] == '\\' || pFileName[1] == ':') // NB. Any prefix quote has already been stripped
|
||||
|
@ -7616,7 +7623,7 @@ Update_t CmdZeroPagePointer (int nArgs)
|
|||
// int nPtrNum = g_aArgs[0].sArg[1] - '0'; // HACK: hard-coded to command length
|
||||
int iZP = g_iCommand - CMD_ZEROPAGE_POINTER_0;
|
||||
|
||||
if( (iZP < 0) || (iZP > MAX_ZEROPAGE_POINTERS) )
|
||||
if( (iZP < 0) || (iZP >= MAX_ZEROPAGE_POINTERS) )
|
||||
return Help_Arg_1( g_iCommand );
|
||||
|
||||
if (nArgs == 0)
|
||||
|
|
|
@ -81,16 +81,21 @@ WORD _CmdDefineByteRange(int nArgs,int iArg,DisasmData_t & tData_)
|
|||
// tData_.nArraySize = 0;
|
||||
|
||||
char *pSymbolName = "";
|
||||
char aSymbolName[ 32 ];
|
||||
char aSymbolName[ MAX_SYMBOLS_LEN+1 ];
|
||||
SymbolTable_Index_e eSymbolTable = SYMBOLS_ASSEMBLY;
|
||||
bool bAutoDefineName = false; // 2.7.0.34
|
||||
|
||||
if( nArgs > 1 )
|
||||
{
|
||||
if( g_aArgs[ 2 ].eToken == TOKEN_COLON ) // 2.7.0.31 Bug fix: DB range, i.e. DB 174E:174F
|
||||
{
|
||||
bAutoDefineName = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pSymbolName = g_aArgs[ 1 ].sArg;
|
||||
pSymbolName[MAX_SYMBOLS_LEN] = 0; // truncate to max symbol length
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1792,7 +1792,8 @@ void FormatDisassemblyLine( const DisasmLine_t & line, char * sDisassembly, cons
|
|||
if (line.bTargetImmediate)
|
||||
{
|
||||
strcat( sDisassembly, "#" );
|
||||
strcpy( sTarget, line.sTarget ); // sTarget
|
||||
strncpy( sTarget, line.sTarget, sizeof(sTarget) );
|
||||
sTarget[sizeof(sTarget)-1] = 0;
|
||||
}
|
||||
else
|
||||
sprintf( sTarget, g_aOpmodes[ line.iOpmode ].m_sFormat, line.nTarget );
|
||||
|
@ -2460,7 +2461,7 @@ void DrawMemory ( int line, int iMemDump )
|
|||
char sText[ MAX_MEM_VIEW_TXT * 2 ];
|
||||
char sData[ MAX_MEM_VIEW_TXT * 2 ];
|
||||
|
||||
char sType [ 4 ] = "Mem";
|
||||
char sType [ 6 ] = "Mem";
|
||||
char sAddress[ 8 ] = "";
|
||||
|
||||
int iForeground = FG_INFO_OPCODE;
|
||||
|
@ -3088,7 +3089,7 @@ void DrawSoftSwitches( int iSoftSwitch )
|
|||
_DrawSoftSwitch( rect, 0xC00C, bSet, "Col", "40", "80", NULL, bgMemory );
|
||||
|
||||
// C00E = off, C00F = on
|
||||
bSet = VideoGetSWAltCharSet();
|
||||
bSet = !VideoGetSWAltCharSet();
|
||||
_DrawSoftSwitch( rect, 0xC00E, bSet, NULL, "ASC", "MOUS", NULL, bgMemory ); // ASCII/MouseText
|
||||
|
||||
#if SOFTSWITCH_LANGCARD
|
||||
|
|
|
@ -127,7 +127,7 @@ int _Arg_Shift( int iSrc, int iEnd, int iDst )
|
|||
{
|
||||
if (iDst < 0)
|
||||
return ARG_SYNTAX_ERROR;
|
||||
if (iDst > MAX_ARGS)
|
||||
if (iDst >= MAX_ARGS)
|
||||
return ARG_SYNTAX_ERROR;
|
||||
|
||||
int nArgs = (iEnd - iSrc);
|
||||
|
@ -151,10 +151,10 @@ int _Args_Insert( int iSrc, int iEnd, int nLen )
|
|||
iSrc += nLen;
|
||||
int iDst = iEnd + nLen;
|
||||
|
||||
if (iDst > MAX_ARGS)
|
||||
if (iDst >= MAX_ARGS)
|
||||
return ARG_SYNTAX_ERROR;
|
||||
|
||||
if (iSrc > MAX_ARGS)
|
||||
if (iSrc >= MAX_ARGS)
|
||||
return ARG_SYNTAX_ERROR;
|
||||
|
||||
while (nLen--)
|
||||
|
|
|
@ -1268,6 +1268,7 @@ ImageError_e CImageHelperBase::CheckZipFile(LPCTSTR pszImageFilename, ImageInfo*
|
|||
return eIMAGE_ERROR_ZIP;
|
||||
|
||||
strncpy(pImageInfo->szFilenameInZip, szFilename, MAX_PATH);
|
||||
pImageInfo->szFilenameInZip[MAX_PATH-1] = 0;
|
||||
memcpy(&pImageInfo->zipFileInfo.tmz_date, &file_info.tmu_date, sizeof(file_info.tmu_date));
|
||||
pImageInfo->zipFileInfo.dosDate = file_info.dosDate;
|
||||
pImageInfo->zipFileInfo.internal_fa = file_info.internal_fa;
|
||||
|
|
|
@ -1316,14 +1316,19 @@ LRESULT CALLBACK FrameWndProc (
|
|||
}
|
||||
else if (wparam == VK_F10)
|
||||
{
|
||||
if (g_Apple2Type == A2TYPE_PRAVETS8A && !KeybGetCtrlStatus())
|
||||
{
|
||||
KeybToggleP8ACapsLock (); // F10: Toggles P8 Capslock
|
||||
}
|
||||
else
|
||||
if (KeybGetCtrlStatus())
|
||||
{
|
||||
SetUsingCursor(FALSE); // Ctrl+F10
|
||||
}
|
||||
else if (g_Apple2Type == A2TYPE_APPLE2E || g_Apple2Type == A2TYPE_APPLE2EENHANCED)
|
||||
{
|
||||
SetVideoRomRockerSwitch( !GetVideoRomRockerSwitch() ); // F10: toggle rocker switch
|
||||
NTSC_VideoInitAppleType();
|
||||
}
|
||||
else if (g_Apple2Type == A2TYPE_PRAVETS8A)
|
||||
{
|
||||
KeybToggleP8ACapsLock (); // F10: Toggles Pravets8A Capslock
|
||||
}
|
||||
}
|
||||
else if (wparam == VK_F11 && !KeybGetCtrlStatus()) // Save state (F11)
|
||||
{
|
||||
|
@ -1378,10 +1383,10 @@ LRESULT CALLBACK FrameWndProc (
|
|||
else if ((g_nAppMode == MODE_RUNNING) || (g_nAppMode == MODE_LOGO) || (g_nAppMode == MODE_STEPPING))
|
||||
{
|
||||
// NB. Alt Gr (Right-Alt): this normally send 2 WM_KEYDOWN messages for: VK_LCONTROL, then VK_RMENU
|
||||
// . NB. The keyboard hook filter now suppresses VK_LCONTROL
|
||||
// . NB. The keyboard hook filter will suppress VK_LCONTROL (if -hook-altgr-control is passed on the cmd-line)
|
||||
bool extended = (HIWORD(lparam) & KF_EXTENDED) != 0;
|
||||
BOOL down = 1;
|
||||
BOOL autorep = (HIWORD(lparam) & KF_REPEAT) != 0;
|
||||
bool down = true;
|
||||
bool autorep = (HIWORD(lparam) & KF_REPEAT) != 0;
|
||||
BOOL IsJoyKey = JoyProcessKey((int)wparam, extended, down, autorep);
|
||||
|
||||
#if DEBUG_KEY_MESSAGES
|
||||
|
@ -1436,8 +1441,8 @@ LRESULT CALLBACK FrameWndProc (
|
|||
else
|
||||
{
|
||||
bool extended = (HIWORD(lparam) & KF_EXTENDED) != 0;
|
||||
BOOL down = 0;
|
||||
BOOL autorep = 0;
|
||||
bool down = false;
|
||||
bool autorep = false;
|
||||
BOOL bIsJoyKey = JoyProcessKey((int)wparam, extended, down, autorep);
|
||||
|
||||
#if DEBUG_KEY_MESSAGES
|
||||
|
@ -1758,7 +1763,6 @@ LRESULT CALLBACK FrameWndProc (
|
|||
KeybUpdateCtrlShiftStatus();
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/gg153546(v=vs.85).aspx
|
||||
// v1.25.0: Alt-Return Alt-Enter toggle fullscreen
|
||||
if (g_bAltEnter_ToggleFullScreen && KeybGetAltStatus() && (wparam == VK_RETURN)) // NB. VK_RETURN = 0x0D; Normally WM_CHAR will be 0x0A but ALT key triggers as WM_SYSKEYDOWN and VK_MENU
|
||||
return 0; // NOP -- eat key
|
||||
|
||||
|
@ -1772,7 +1776,10 @@ LRESULT CALLBACK FrameWndProc (
|
|||
case WM_SYSKEYUP:
|
||||
KeybUpdateCtrlShiftStatus();
|
||||
|
||||
// v1.25.0: Alt-Return Alt-Enter toggle fullscreen
|
||||
// F10: no WM_KEYUP handler for VK_F10. Don't allow WM_KEYUP to pass to default handler which will show the app window's "menu" (and lose focus)
|
||||
if (wparam == VK_F10)
|
||||
return 0;
|
||||
|
||||
if (g_bAltEnter_ToggleFullScreen && KeybGetAltStatus() && (wparam == VK_RETURN)) // NB. VK_RETURN = 0x0D; Normally WM_CHAR will be 0x0A but ALT key triggers as WM_SYSKEYDOWN and VK_MENU
|
||||
ScreenWindowResize(false);
|
||||
else
|
||||
|
|
|
@ -111,6 +111,15 @@ static UINT g_bJoyportEnabled = 0; // Set to use Joyport to drive the 3 button i
|
|||
static UINT g_uJoyportActiveStick = 0;
|
||||
static UINT g_uJoyportReadMode = JOYPORT_LEFTRIGHT;
|
||||
|
||||
static bool g_bHookAltKeys = true;
|
||||
|
||||
//===========================================================================
|
||||
|
||||
void JoySetHookAltKeys(bool hook)
|
||||
{
|
||||
g_bHookAltKeys = hook;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CheckJoystick0()
|
||||
{
|
||||
|
@ -296,7 +305,7 @@ void JoyInitialize()
|
|||
|
||||
#define SUPPORT_CURSOR_KEYS
|
||||
|
||||
BOOL JoyProcessKey(int virtkey, BOOL extended, BOOL down, BOOL autorep)
|
||||
BOOL JoyProcessKey(int virtkey, bool extended, bool down, bool autorep)
|
||||
{
|
||||
static struct
|
||||
{
|
||||
|
@ -314,6 +323,9 @@ BOOL JoyProcessKey(int virtkey, BOOL extended, BOOL down, BOOL autorep)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!g_bHookAltKeys && virtkey == VK_MENU) // GH#583
|
||||
return 0;
|
||||
|
||||
//
|
||||
|
||||
BOOL keychange = 0;
|
||||
|
|
|
@ -8,7 +8,7 @@ enum JOY1CHOICE {J1C_DISABLED=0, J1C_JOYSTICK2, J1C_KEYBD_CURSORS, J1C_KEYBD_NUM
|
|||
enum {JOYSTICK_MODE_FLOATING=0, JOYSTICK_MODE_CENTERING}; // Joystick centering control
|
||||
|
||||
void JoyInitialize();
|
||||
BOOL JoyProcessKey(int,BOOL,BOOL,BOOL);
|
||||
BOOL JoyProcessKey(int,bool,bool,bool);
|
||||
void JoyReset();
|
||||
void JoySetButton(eBUTTON,eBUTTONSTATE);
|
||||
BOOL JoySetEmulationType(HWND,DWORD,int, const bool bMousecardActive);
|
||||
|
@ -24,6 +24,7 @@ DWORD JoyGetJoyType(UINT num);
|
|||
void JoySetTrim(short nValue, bool bAxisX);
|
||||
short JoyGetTrim(bool bAxisX);
|
||||
void JoyportControl(const UINT uControl);
|
||||
void JoySetHookAltKeys(bool hook);
|
||||
void JoySetSnapshot_v1(const unsigned __int64 JoyCntrResetCycle);
|
||||
void JoySaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
|
||||
void JoyLoadSnapshot(class YamlLoadHelper& yamlLoadHelper);
|
||||
|
|
|
@ -44,19 +44,33 @@ LanguageCardUnit::LanguageCardUnit(void) :
|
|||
SetMemMainLanguageCard(NULL, true);
|
||||
}
|
||||
|
||||
DWORD LanguageCardUnit::SetPaging(WORD address, DWORD memmode, BOOL& modechanging, bool write)
|
||||
LanguageCardUnit::~LanguageCardUnit(void)
|
||||
{
|
||||
SetMemMainLanguageCard(NULL);
|
||||
}
|
||||
|
||||
void LanguageCardUnit::InitializeIO(void)
|
||||
{
|
||||
RegisterIoHandler(kSlot0, &LanguageCardUnit::IO, &LanguageCardUnit::IO, NULL, NULL, this, NULL);
|
||||
}
|
||||
|
||||
BYTE __stdcall LanguageCardUnit::IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nExecutedCycles)
|
||||
{
|
||||
LanguageCardUnit* pLC = (LanguageCardUnit*) MemGetSlotParameters(kSlot0);
|
||||
|
||||
DWORD memmode = GetMemMode();
|
||||
DWORD lastmemmode = memmode;
|
||||
memmode &= ~(MF_BANK2 | MF_HIGHRAM);
|
||||
|
||||
if (!(address & 8))
|
||||
if (!(uAddr & 8))
|
||||
memmode |= MF_BANK2;
|
||||
|
||||
if (((address & 2) >> 1) == (address & 1))
|
||||
if (((uAddr & 2) >> 1) == (uAddr & 1))
|
||||
memmode |= MF_HIGHRAM;
|
||||
|
||||
if (address & 1) // GH#392
|
||||
if (uAddr & 1) // GH#392
|
||||
{
|
||||
if (!write && GetLastRamWrite())
|
||||
if (!bWrite && pLC->GetLastRamWrite())
|
||||
{
|
||||
memmode |= MF_WRITERAM; // UTAIIe:5-23
|
||||
}
|
||||
|
@ -66,9 +80,22 @@ DWORD LanguageCardUnit::SetPaging(WORD address, DWORD memmode, BOOL& modechangin
|
|||
memmode &= ~MF_WRITERAM; // UTAIIe:5-23
|
||||
}
|
||||
|
||||
SetLastRamWrite( ((address & 1) && !write) ); // UTAIIe:5-23
|
||||
pLC->SetLastRamWrite( ((uAddr & 1) && !bWrite) ); // UTAIIe:5-23
|
||||
SetMemMode(memmode);
|
||||
|
||||
return memmode;
|
||||
//
|
||||
|
||||
if (MemOptimizeForModeChanging(PC, uAddr))
|
||||
return bWrite ? 0 : MemReadFloatingBus(nExecutedCycles);
|
||||
|
||||
// IF THE MEMORY PAGING MODE HAS CHANGED, UPDATE OUR MEMORY IMAGES AND
|
||||
// WRITE TABLES.
|
||||
if (lastmemmode != memmode)
|
||||
{
|
||||
MemUpdatePaging(0); // Initialize=0
|
||||
}
|
||||
|
||||
return bWrite ? 0 : MemReadFloatingBus(nExecutedCycles);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
@ -89,7 +116,7 @@ LanguageCardSlot0::~LanguageCardSlot0(void)
|
|||
//
|
||||
|
||||
static const UINT kUNIT_LANGUAGECARD_VER = 1;
|
||||
static const UINT kSLOT_LANGUAGECARD = 0;
|
||||
static const UINT kSLOT_LANGUAGECARD = LanguageCardUnit::kSlot0;
|
||||
|
||||
#define SS_YAML_VALUE_CARD_LANGUAGECARD "Language Card"
|
||||
|
||||
|
@ -183,7 +210,9 @@ Saturn128K::Saturn128K(UINT banks)
|
|||
for (UINT i=0; i<kMaxSaturnBanks; i++)
|
||||
m_aSaturnBanks[i] = NULL;
|
||||
|
||||
for (UINT i = 0; i < m_uSaturnTotalBanks; i++)
|
||||
m_aSaturnBanks[0] = m_pMemory; // Reuse memory allocated in base ctor
|
||||
|
||||
for (UINT i = 1; i < m_uSaturnTotalBanks; i++)
|
||||
m_aSaturnBanks[i] = (LPBYTE) VirtualAlloc(NULL, kMemBankSize, MEM_COMMIT, PAGE_READWRITE); // Saturn banks are 16K, max 8 banks/card
|
||||
|
||||
SetMemMainLanguageCard( m_aSaturnBanks[ m_uSaturnActiveBank ] );
|
||||
|
@ -191,7 +220,9 @@ Saturn128K::Saturn128K(UINT banks)
|
|||
|
||||
Saturn128K::~Saturn128K(void)
|
||||
{
|
||||
for (UINT i = 0; i < m_uSaturnTotalBanks; i++)
|
||||
m_aSaturnBanks[0] = NULL; // just zero this - deallocated in base ctor
|
||||
|
||||
for (UINT i = 1; i < m_uSaturnTotalBanks; i++)
|
||||
{
|
||||
if (m_aSaturnBanks[i])
|
||||
{
|
||||
|
@ -211,7 +242,12 @@ UINT Saturn128K::GetActiveBank(void)
|
|||
return m_uSaturnActiveBank;
|
||||
}
|
||||
|
||||
DWORD Saturn128K::SetPaging(WORD address, DWORD memmode, BOOL& modechanging, bool /*write*/)
|
||||
void Saturn128K::InitializeIO(void)
|
||||
{
|
||||
RegisterIoHandler(kSlot0, &Saturn128K::IO, &Saturn128K::IO, NULL, NULL, this, NULL);
|
||||
}
|
||||
|
||||
BYTE __stdcall Saturn128K::IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nExecutedCycles)
|
||||
{
|
||||
/*
|
||||
Bin Addr.
|
||||
|
@ -232,54 +268,70 @@ DWORD Saturn128K::SetPaging(WORD address, DWORD memmode, BOOL& modechanging, boo
|
|||
1110 $C0NE select 16K Bank 7
|
||||
1111 $C0NF select 16K Bank 8
|
||||
*/
|
||||
_ASSERT(m_uSaturnTotalBanks);
|
||||
if (!m_uSaturnTotalBanks)
|
||||
return memmode;
|
||||
Saturn128K* pLC = (Saturn128K*) MemGetSlotParameters(kSlot0);
|
||||
|
||||
if (address & (1<<2))
|
||||
_ASSERT(pLC->m_uSaturnTotalBanks);
|
||||
if (!pLC->m_uSaturnTotalBanks)
|
||||
return bWrite ? 0 : MemReadFloatingBus(nExecutedCycles);
|
||||
|
||||
bool bBankChanged = false;
|
||||
DWORD memmode=0, lastmemmode=0;
|
||||
|
||||
if (uAddr & (1<<2))
|
||||
{
|
||||
m_uSaturnActiveBank = 0 // Saturn 128K Language Card Bank 0 .. 7
|
||||
| (address >> 1) & 4
|
||||
| (address >> 0) & 3;
|
||||
pLC->m_uSaturnActiveBank = 0 // Saturn 128K Language Card Bank 0 .. 7
|
||||
| (uAddr >> 1) & 4
|
||||
| (uAddr >> 0) & 3;
|
||||
|
||||
if (m_uSaturnActiveBank >= m_uSaturnTotalBanks)
|
||||
if (pLC->m_uSaturnActiveBank >= pLC->m_uSaturnTotalBanks)
|
||||
{
|
||||
// EG. Run RAMTEST128K tests on a Saturn 64K card
|
||||
// TODO: Saturn::UpdatePaging() should deal with this case:
|
||||
// . Technically read floating-bus, write to nothing
|
||||
// . But the mem cache doesn't support floating-bus reads from non-I/O space
|
||||
m_uSaturnActiveBank = m_uSaturnTotalBanks-1; // FIXME: just prevent crash for now!
|
||||
pLC->m_uSaturnActiveBank = pLC->m_uSaturnTotalBanks-1; // FIXME: just prevent crash for now!
|
||||
}
|
||||
|
||||
SetMemMainLanguageCard( m_aSaturnBanks[ m_uSaturnActiveBank ] );
|
||||
|
||||
modechanging = 1;
|
||||
SetMemMainLanguageCard( pLC->m_aSaturnBanks[ pLC->m_uSaturnActiveBank ] );
|
||||
bBankChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
memmode = GetMemMode();
|
||||
lastmemmode = memmode;
|
||||
memmode &= ~(MF_BANK2 | MF_HIGHRAM);
|
||||
|
||||
if (!(address & 8))
|
||||
if (!(uAddr & 8))
|
||||
memmode |= MF_BANK2;
|
||||
|
||||
if (((address & 2) >> 1) == (address & 1))
|
||||
if (((uAddr & 2) >> 1) == (uAddr & 1))
|
||||
memmode |= MF_HIGHRAM;
|
||||
|
||||
if (address & 1 && GetLastRamWrite()) // Saturn differs from Apple's 16K LC: any access (LC is read-only)
|
||||
if (uAddr & 1 && pLC->GetLastRamWrite())// Saturn differs from Apple's 16K LC: any access (LC is read-only)
|
||||
memmode |= MF_WRITERAM;
|
||||
else
|
||||
memmode &= ~MF_WRITERAM;
|
||||
|
||||
SetLastRamWrite(address & 1); // Saturn differs from Apple's 16K LC: any access (LC is read-only)
|
||||
pLC->SetLastRamWrite(uAddr & 1); // Saturn differs from Apple's 16K LC: any access (LC is read-only)
|
||||
SetMemMode(memmode);
|
||||
}
|
||||
|
||||
return memmode;
|
||||
// NB. Unlike LC, no need to check if next opcode is STA $C002-5, as Saturn is not for //e
|
||||
|
||||
// IF THE MEMORY PAGING MODE HAS CHANGED, UPDATE OUR MEMORY IMAGES AND
|
||||
// WRITE TABLES.
|
||||
if ((lastmemmode != memmode) || bBankChanged)
|
||||
{
|
||||
MemUpdatePaging(0); // Initialize=0
|
||||
}
|
||||
|
||||
return bWrite ? 0 : MemReadFloatingBus(nExecutedCycles);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
static const UINT kUNIT_SATURN_VER = 1;
|
||||
static const UINT kSLOT_SATURN = 0;
|
||||
static const UINT kSLOT_SATURN = LanguageCardUnit::kSlot0;
|
||||
|
||||
#define SS_YAML_VALUE_CARD_SATURN128 "Saturn 128"
|
||||
|
||||
|
|
|
@ -8,9 +8,9 @@ class LanguageCardUnit
|
|||
{
|
||||
public:
|
||||
LanguageCardUnit(void);
|
||||
virtual ~LanguageCardUnit(void) {}
|
||||
virtual ~LanguageCardUnit(void);
|
||||
|
||||
virtual DWORD SetPaging(WORD address, DWORD memmode, BOOL& modechanging, bool write);
|
||||
virtual void InitializeIO(void);
|
||||
virtual void SetMemorySize(UINT banks) {} // No-op for //e and slot-0 16K LC
|
||||
virtual UINT GetActiveBank(void) { return 0; } // Always 0 as only 1x 16K bank
|
||||
virtual void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper) { _ASSERT(0); } // Not used for //e
|
||||
|
@ -20,7 +20,10 @@ public:
|
|||
void SetLastRamWrite(BOOL count) { m_uLastRamWrite = count; }
|
||||
SS_CARDTYPE GetMemoryType(void) { return m_type; }
|
||||
|
||||
static BYTE __stdcall IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nExecutedCycles);
|
||||
|
||||
static const UINT kMemModeInitialState;
|
||||
static const UINT kSlot0 = 0;
|
||||
|
||||
protected:
|
||||
SS_CARDTYPE m_type;
|
||||
|
@ -49,10 +52,10 @@ protected:
|
|||
void SaveLCState(class YamlSaveHelper& yamlSaveHelper);
|
||||
void LoadLCState(class YamlLoadHelper& yamlLoadHelper);
|
||||
|
||||
LPBYTE m_pMemory;
|
||||
|
||||
private:
|
||||
std::string GetSnapshotMemStructName(void);
|
||||
|
||||
LPBYTE m_pMemory;
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -65,12 +68,15 @@ public:
|
|||
Saturn128K(UINT banks);
|
||||
virtual ~Saturn128K(void);
|
||||
|
||||
virtual DWORD SetPaging(WORD address, DWORD memmode, BOOL& modechanging, bool write);
|
||||
virtual void InitializeIO(void);
|
||||
virtual void SetMemorySize(UINT banks);
|
||||
virtual UINT GetActiveBank(void);
|
||||
virtual void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
|
||||
virtual bool LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version);
|
||||
|
||||
static BYTE __stdcall IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nExecutedCycles);
|
||||
|
||||
// "The boards consist of 16K banks of memory (4 banks for the 64K board, 8 banks for the 128K), accessed one at a time" - Ref: "64K/128K RAM BOARD", Saturn Systems, Ch.1 Introduction(pg-5)
|
||||
static const UINT kMaxSaturnBanks = 8; // 8 * 16K = 128K
|
||||
static std::string GetSnapshotCardName(void);
|
||||
|
||||
|
|
|
@ -214,6 +214,9 @@ BYTE __stdcall IO_Annunciator(WORD programcounter, WORD address, BYTE write, BYT
|
|||
|
||||
//=============================================================================
|
||||
|
||||
// Default memory types on a VM restart
|
||||
// - can be overwritten by cmd-line or loading a save-state
|
||||
static SS_CARDTYPE g_MemTypeAppleII = CT_Empty;
|
||||
static SS_CARDTYPE g_MemTypeAppleIIPlus = CT_LanguageCard; // Keep a copy so it's not lost if machine type changes, eg: A][ -> A//e -> A][
|
||||
static SS_CARDTYPE g_MemTypeAppleIIe = CT_Extended80Col; // Keep a copy so it's not lost if machine type changes, eg: A//e -> A][ -> A//e
|
||||
static UINT g_uSaturnBanksFromCmdLine = 0;
|
||||
|
@ -221,14 +224,18 @@ static UINT g_uSaturnBanksFromCmdLine = 0;
|
|||
// Called from MemLoadSnapshot()
|
||||
static void ResetDefaultMachineMemTypes(void)
|
||||
{
|
||||
g_MemTypeAppleII = CT_Empty;
|
||||
g_MemTypeAppleIIPlus = CT_LanguageCard;
|
||||
g_MemTypeAppleIIe = CT_Extended80Col;
|
||||
}
|
||||
|
||||
// Called from MemInitialize(), MemLoadSnapshot()
|
||||
void SetExpansionMemTypeDefault(void)
|
||||
// Called from MemInitialize(), MemLoadSnapshot(), MemSetSnapshot_v1()
|
||||
static void SetExpansionMemTypeDefault(void)
|
||||
{
|
||||
SS_CARDTYPE defaultType = IsApple2PlusOrClone(GetApple2Type()) ? g_MemTypeAppleIIPlus : g_MemTypeAppleIIe;
|
||||
SS_CARDTYPE defaultType = IsApple2Original(GetApple2Type()) ? g_MemTypeAppleII
|
||||
: IsApple2PlusOrClone(GetApple2Type()) ? g_MemTypeAppleIIPlus
|
||||
: g_MemTypeAppleIIe;
|
||||
|
||||
SetExpansionMemType(defaultType);
|
||||
}
|
||||
|
||||
|
@ -239,7 +246,12 @@ void SetExpansionMemType(const SS_CARDTYPE type)
|
|||
SS_CARDTYPE newSlotAuxCard;
|
||||
|
||||
// Set defaults:
|
||||
if (IsApple2PlusOrClone(GetApple2Type()))
|
||||
if (IsApple2Original(GetApple2Type()))
|
||||
{
|
||||
newSlot0Card = CT_Empty;
|
||||
newSlotAuxCard = CT_Empty;
|
||||
}
|
||||
else if (IsApple2PlusOrClone(GetApple2Type()))
|
||||
{
|
||||
newSlot0Card = CT_LanguageCard;
|
||||
newSlotAuxCard = CT_Empty;
|
||||
|
@ -250,11 +262,12 @@ void SetExpansionMemType(const SS_CARDTYPE type)
|
|||
newSlotAuxCard = CT_Extended80Col;
|
||||
}
|
||||
|
||||
if (type == CT_Saturn128K)
|
||||
if (type == CT_LanguageCard || type == CT_Saturn128K)
|
||||
{
|
||||
g_MemTypeAppleII = type;
|
||||
g_MemTypeAppleIIPlus = type;
|
||||
if (IsApple2PlusOrClone(GetApple2Type()))
|
||||
newSlot0Card = CT_Saturn128K;
|
||||
newSlot0Card = type;
|
||||
else
|
||||
newSlot0Card = CT_Empty; // NB. No slot0 for //e
|
||||
}
|
||||
|
@ -264,31 +277,33 @@ void SetExpansionMemType(const SS_CARDTYPE type)
|
|||
if (IsApple2PlusOrClone(GetApple2Type()))
|
||||
newSlotAuxCard = CT_Empty; // NB. No aux slot for ][ or ][+
|
||||
else
|
||||
newSlotAuxCard = CT_RamWorksIII;
|
||||
newSlotAuxCard = type;
|
||||
}
|
||||
|
||||
if (IsApple2PlusOrClone(GetApple2Type()))
|
||||
{
|
||||
delete g_pLanguageCard;
|
||||
g_pLanguageCard = NULL;
|
||||
|
||||
if (newSlot0Card == CT_Saturn128K)
|
||||
g_pLanguageCard = new Saturn128K(g_uSaturnBanksFromCmdLine);
|
||||
else // newSlot0Card == CT_LanguageCard
|
||||
g_pLanguageCard = new LanguageCardSlot0;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete g_pLanguageCard;
|
||||
g_pLanguageCard = new LanguageCardUnit;
|
||||
}
|
||||
|
||||
_ASSERT(g_pMemMainLanguageCard);
|
||||
|
||||
g_Slot0 = newSlot0Card;
|
||||
g_SlotAux = newSlotAuxCard;
|
||||
}
|
||||
|
||||
void CreateLanguageCard(void)
|
||||
{
|
||||
delete g_pLanguageCard;
|
||||
g_pLanguageCard = NULL;
|
||||
|
||||
if (IsApple2PlusOrClone(GetApple2Type()))
|
||||
{
|
||||
if (g_Slot0 == CT_Saturn128K)
|
||||
g_pLanguageCard = new Saturn128K(g_uSaturnBanksFromCmdLine);
|
||||
else if (g_Slot0 == CT_LanguageCard)
|
||||
g_pLanguageCard = new LanguageCardSlot0;
|
||||
else
|
||||
g_pLanguageCard = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pLanguageCard = new LanguageCardUnit;
|
||||
}
|
||||
}
|
||||
|
||||
SS_CARDTYPE GetCurrentExpansionMemType(void)
|
||||
{
|
||||
if (IsApple2PlusOrClone(GetApple2Type()))
|
||||
|
@ -318,12 +333,15 @@ void SetSaturnMemorySize(UINT banks)
|
|||
|
||||
static BOOL GetLastRamWrite(void)
|
||||
{
|
||||
return g_pLanguageCard->GetLastRamWrite();
|
||||
if (g_pLanguageCard)
|
||||
return g_pLanguageCard->GetLastRamWrite();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void SetLastRamWrite(BOOL count)
|
||||
{
|
||||
g_pLanguageCard->SetLastRamWrite(count);
|
||||
if (g_pLanguageCard)
|
||||
g_pLanguageCard->SetLastRamWrite(count);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -338,6 +356,7 @@ void SetMemMainLanguageCard(LPBYTE ptr, bool bMemMain /*=false*/)
|
|||
|
||||
LanguageCardUnit* GetLanguageCard(void)
|
||||
{
|
||||
_ASSERT(g_pLanguageCard);
|
||||
return g_pLanguageCard;
|
||||
}
|
||||
|
||||
|
@ -1003,7 +1022,12 @@ void MemResetPaging()
|
|||
static void ResetPaging(BOOL initialize)
|
||||
{
|
||||
SetLastRamWrite(0);
|
||||
SetMemMode(LanguageCardUnit::kMemModeInitialState);
|
||||
|
||||
if (IsApple2PlusOrClone(GetApple2Type()) && g_Slot0 == CT_Empty)
|
||||
SetMemMode(0);
|
||||
else
|
||||
SetMemMode(LanguageCardUnit::kMemModeInitialState);
|
||||
|
||||
UpdatePaging(initialize);
|
||||
}
|
||||
|
||||
|
@ -1016,6 +1040,8 @@ void MemUpdatePaging(BOOL initialize)
|
|||
|
||||
static void UpdatePaging(BOOL initialize)
|
||||
{
|
||||
modechanging = 0;
|
||||
|
||||
// SAVE THE CURRENT PAGING SHADOW TABLE
|
||||
LPBYTE oldshadow[256];
|
||||
if (!initialize)
|
||||
|
@ -1178,8 +1204,6 @@ void MemDestroy()
|
|||
|
||||
mem = NULL;
|
||||
|
||||
g_pMemMainLanguageCard = NULL;
|
||||
|
||||
ZeroMemory(memwrite, sizeof(memwrite));
|
||||
ZeroMemory(memshadow,sizeof(memshadow));
|
||||
}
|
||||
|
@ -1418,7 +1442,7 @@ void MemInitialize()
|
|||
SetExpansionMemTypeDefault();
|
||||
|
||||
#ifdef RAMWORKS
|
||||
if (GetCurrentExpansionMemType() == CT_RamWorksIII)
|
||||
if (g_SlotAux == CT_RamWorksIII)
|
||||
{
|
||||
// allocate memory for RAMWorks III - up to 8MB
|
||||
g_uActiveBank = 0;
|
||||
|
@ -1433,6 +1457,8 @@ void MemInitialize()
|
|||
|
||||
//
|
||||
|
||||
CreateLanguageCard();
|
||||
|
||||
MemInitializeROM();
|
||||
MemInitializeCustomF8ROM();
|
||||
MemInitializeIO();
|
||||
|
@ -1519,6 +1545,36 @@ void MemInitializeROM(void)
|
|||
void MemInitializeCustomF8ROM(void)
|
||||
{
|
||||
const UINT F8RomSize = 0x800;
|
||||
const UINT F8RomOffset = Apple2RomSize-F8RomSize;
|
||||
|
||||
if (IsApple2Original(GetApple2Type()) && g_Slot0 == CT_LanguageCard)
|
||||
{
|
||||
try
|
||||
{
|
||||
HRSRC hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_APPLE2_PLUS_ROM), "ROM");
|
||||
if (hResInfo == NULL)
|
||||
throw false;
|
||||
|
||||
DWORD dwResSize = SizeofResource(NULL, hResInfo);
|
||||
if(dwResSize != Apple2RomSize)
|
||||
throw false;
|
||||
|
||||
HGLOBAL hResData = LoadResource(NULL, hResInfo);
|
||||
if(hResData == NULL)
|
||||
throw false;
|
||||
|
||||
BYTE* pData = (BYTE*) LockResource(hResData); // NB. Don't need to unlock resource
|
||||
if (pData == NULL)
|
||||
throw false;
|
||||
|
||||
memcpy(memrom+F8RomOffset, pData+F8RomOffset, F8RomSize);
|
||||
}
|
||||
catch (bool)
|
||||
{
|
||||
MessageBox( g_hFrameWindow, "Failed to read F8 (auto-start) ROM for language card in original Apple][", TEXT("AppleWin Error"), MB_OK );
|
||||
}
|
||||
}
|
||||
|
||||
if (g_hCustomRomF8 != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
BYTE OldRom[Apple2RomSize]; // NB. 12KB on stack
|
||||
|
@ -1526,13 +1582,15 @@ void MemInitializeCustomF8ROM(void)
|
|||
|
||||
SetFilePointer(g_hCustomRomF8, 0, NULL, FILE_BEGIN);
|
||||
DWORD uNumBytesRead;
|
||||
BOOL bRes = ReadFile(g_hCustomRomF8, memrom+Apple2RomSize-F8RomSize, F8RomSize, &uNumBytesRead, NULL);
|
||||
BOOL bRes = ReadFile(g_hCustomRomF8, memrom+F8RomOffset, F8RomSize, &uNumBytesRead, NULL);
|
||||
if (uNumBytesRead != F8RomSize)
|
||||
{
|
||||
memcpy(memrom, OldRom, Apple2RomSize); // ROM at $D000...$FFFF
|
||||
bRes = FALSE;
|
||||
}
|
||||
|
||||
// NB. If succeeded, then keep g_hCustomRomF8 handle open - so that any next restart can load it again
|
||||
|
||||
if (!bRes)
|
||||
{
|
||||
MessageBox( g_hFrameWindow, "Failed to read custom F8 rom", TEXT("AppleWin Error"), MB_OK );
|
||||
|
@ -1566,8 +1624,10 @@ void MemInitializeIO(void)
|
|||
{
|
||||
InitIoHandlers();
|
||||
|
||||
const UINT uSlot = 0;
|
||||
RegisterIoHandler(uSlot, MemSetPaging, MemSetPaging, NULL, NULL, NULL, NULL);
|
||||
if (g_pLanguageCard)
|
||||
g_pLanguageCard->InitializeIO();
|
||||
else
|
||||
RegisterIoHandler(LanguageCardUnit::kSlot0, IO_Null, IO_Null, NULL, NULL, NULL, NULL);
|
||||
|
||||
// TODO: Cleanup peripheral setup!!!
|
||||
PrintLoadRom(pCxRomPeripheral, 1); // $C100 : Parallel printer f/w
|
||||
|
@ -1854,11 +1914,7 @@ BYTE __stdcall MemSetPaging(WORD programcounter, WORD address, BYTE write, BYTE
|
|||
#endif
|
||||
|
||||
// DETERMINE THE NEW MEMORY PAGING MODE.
|
||||
if ((address >= 0x80) && (address <= 0x8F))
|
||||
{
|
||||
SetMemMode( g_pLanguageCard->SetPaging(address, memmode, modechanging, write ? true : false) );
|
||||
}
|
||||
else if (!IS_APPLE2)
|
||||
if (!IS_APPLE2)
|
||||
{
|
||||
switch (address)
|
||||
{
|
||||
|
@ -1892,33 +1948,13 @@ BYTE __stdcall MemSetPaging(WORD programcounter, WORD address, BYTE write, BYTE
|
|||
}
|
||||
}
|
||||
|
||||
if (GetCurrentExpansionMemType() != CT_Saturn128K) // TODO: Not sure this optimisation is valid for Saturn, so skip it for now
|
||||
{
|
||||
// IF THE EMULATED PROGRAM HAS JUST UPDATE THE MEMORY WRITE MODE AND IS
|
||||
// ABOUT TO UPDATE THE MEMORY READ MODE, HOLD OFF ON ANY PROCESSING UNTIL
|
||||
// IT DOES SO.
|
||||
//
|
||||
// NB. A 6502 interrupt occurring between these memory write & read updates could lead to incorrect behaviour.
|
||||
// - although any data-race is probably a bug in the 6502 code too.
|
||||
if ((address >= 4) && (address <= 5) &&
|
||||
((*(LPDWORD)(mem+programcounter) & 0x00FFFEFF) == 0x00C0028D)) {
|
||||
modechanging = 1;
|
||||
return write ? 0 : MemReadFloatingBus(1, nExecutedCycles);
|
||||
}
|
||||
if ((address >= 0x80) && (address <= 0x8F) && (programcounter < 0xC000) &&
|
||||
(((*(LPDWORD)(mem+programcounter) & 0x00FFFEFF) == 0x00C0048D) ||
|
||||
((*(LPDWORD)(mem+programcounter) & 0x00FFFEFF) == 0x00C0028D))) {
|
||||
modechanging = 1;
|
||||
return write ? 0 : MemReadFloatingBus(1, nExecutedCycles);
|
||||
}
|
||||
}
|
||||
if (MemOptimizeForModeChanging(programcounter, address))
|
||||
return write ? 0 : MemReadFloatingBus(nExecutedCycles);
|
||||
|
||||
// IF THE MEMORY PAGING MODE HAS CHANGED, UPDATE OUR MEMORY IMAGES AND
|
||||
// WRITE TABLES.
|
||||
if ((lastmemmode != memmode) || modechanging)
|
||||
{
|
||||
modechanging = 0;
|
||||
|
||||
// NB. Must check MF_SLOTC3ROM too, as IoHandlerCardsIn() depends on both MF_INTCXROM|MF_SLOTC3ROM
|
||||
if ((lastmemmode & (MF_INTCXROM|MF_SLOTC3ROM)) != (memmode & (MF_INTCXROM|MF_SLOTC3ROM)))
|
||||
{
|
||||
|
@ -1958,6 +1994,37 @@ BYTE __stdcall MemSetPaging(WORD programcounter, WORD address, BYTE write, BYTE
|
|||
|
||||
//===========================================================================
|
||||
|
||||
bool MemOptimizeForModeChanging(WORD programcounter, WORD address)
|
||||
{
|
||||
if (IS_APPLE2E)
|
||||
{
|
||||
// IF THE EMULATED PROGRAM HAS JUST UPDATED THE MEMORY WRITE MODE AND IS
|
||||
// ABOUT TO UPDATE THE MEMORY READ MODE, HOLD OFF ON ANY PROCESSING UNTIL
|
||||
// IT DOES SO.
|
||||
//
|
||||
// NB. A 6502 interrupt occurring between these memory write & read updates could lead to incorrect behaviour.
|
||||
// - although any data-race is probably a bug in the 6502 code too.
|
||||
if ((address >= 4) && (address <= 5) && // Now: RAMWRTOFF or RAMWRTON
|
||||
((*(LPDWORD)(mem+programcounter) & 0x00FFFEFF) == 0x00C0028D)) // Next: STA $C002(RAMRDOFF) or STA $C003(RAMRDON)
|
||||
{
|
||||
modechanging = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((address >= 0x80) && (address <= 0x8F) && (programcounter < 0xC000) && // Now: LC
|
||||
(((*(LPDWORD)(mem+programcounter) & 0x00FFFEFF) == 0x00C0048D) || // Next: STA $C004(RAMWRTOFF) or STA $C005(RAMWRTON)
|
||||
((*(LPDWORD)(mem+programcounter) & 0x00FFFEFF) == 0x00C0028D))) // or STA $C002(RAMRDOFF) or STA $C003(RAMRDON)
|
||||
{
|
||||
modechanging = 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
LPVOID MemGetSlotParameters(UINT uSlot)
|
||||
{
|
||||
_ASSERT(uSlot < NUM_SLOTS);
|
||||
|
@ -1972,6 +2039,12 @@ LPVOID MemGetSlotParameters(UINT uSlot)
|
|||
|
||||
void MemSetSnapshot_v1(const DWORD MemMode, const BOOL LastWriteRam, const BYTE* const pMemMain, const BYTE* const pMemAux)
|
||||
{
|
||||
// Create default LC type for AppleII machine (do prior to loading saved LC state)
|
||||
ResetDefaultMachineMemTypes();
|
||||
g_MemTypeAppleII = CT_LanguageCard; // SSv1 doesn't save machine type - so if current machine is Apple II then give it 64K + LC
|
||||
SetExpansionMemTypeDefault();
|
||||
CreateLanguageCard(); // Create LC here, as for SSv1 there is no slot-0 state
|
||||
|
||||
SetMemMode(MemMode ^ MF_INTCXROM); // Convert from SLOTCXROM to INTCXROM
|
||||
SetLastRamWrite(LastWriteRam);
|
||||
|
||||
|
@ -1981,7 +2054,6 @@ void MemSetSnapshot_v1(const DWORD MemMode, const BOOL LastWriteRam, const BYTE*
|
|||
|
||||
//
|
||||
|
||||
modechanging = 0;
|
||||
// NB. MemUpdatePaging(TRUE) called at end of Snapshot_LoadState_v1()
|
||||
UpdatePaging(1); // Initialize=1
|
||||
}
|
||||
|
@ -2076,7 +2148,13 @@ bool MemLoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version)
|
|||
|
||||
// Create default LC type for AppleII machine (do prior to loading saved LC state)
|
||||
ResetDefaultMachineMemTypes();
|
||||
if (version == 1)
|
||||
g_MemTypeAppleII = CT_LanguageCard; // version=1: original Apple II always has a LC
|
||||
else
|
||||
g_MemTypeAppleIIPlus = CT_Empty; // version=2+: Apple II/II+ initially start with slot-0 empty
|
||||
SetExpansionMemTypeDefault();
|
||||
CreateLanguageCard(); // Create default LC now for: (a) //e which has no slot-0 LC (so this is final)
|
||||
// (b) II/II+ which get re-created later if slot-0 has a card
|
||||
|
||||
//
|
||||
|
||||
|
@ -2123,7 +2201,6 @@ bool MemLoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version)
|
|||
|
||||
//
|
||||
|
||||
modechanging = 0;
|
||||
// NB. MemUpdatePaging(TRUE) called at end of Snapshot_LoadState_v2()
|
||||
UpdatePaging(1); // Initialize=1 (Still needed, even with call to MemUpdatePaging() - why?)
|
||||
// TC-TODO: At this point, the cards haven't been loaded, so the card's expansion ROM is unknown - so pointless(?) calling this now
|
||||
|
|
|
@ -68,6 +68,7 @@ LPBYTE MemGetBankPtr(const UINT nBank);
|
|||
LPBYTE MemGetCxRomPeripheral();
|
||||
DWORD GetMemMode(void);
|
||||
void SetMemMode(DWORD memmode);
|
||||
bool MemOptimizeForModeChanging(WORD programcounter, WORD address);
|
||||
bool MemIsAddrCodeMemory(const USHORT addr);
|
||||
void MemInitialize ();
|
||||
void MemInitializeROM(void);
|
||||
|
@ -94,6 +95,7 @@ BYTE __stdcall MemSetPaging(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExec
|
|||
enum SS_CARDTYPE;
|
||||
void SetExpansionMemType(const SS_CARDTYPE type);
|
||||
SS_CARDTYPE GetCurrentExpansionMemType(void);
|
||||
void CreateLanguageCard(void);
|
||||
|
||||
void SetRamWorksMemorySize(UINT pages);
|
||||
UINT GetRamWorksActiveBank(void);
|
||||
|
|
|
@ -471,7 +471,7 @@ static void set_csbits()
|
|||
case A2TYPE_APPLE2: csbits = &csbits_a2[0]; g_nVideoCharSet = 0; break;
|
||||
case A2TYPE_APPLE2PLUS: csbits = &csbits_a2[0]; g_nVideoCharSet = 0; break;
|
||||
case A2TYPE_APPLE2E: csbits = &csbits_2e[0]; break;
|
||||
case A2TYPE_APPLE2EENHANCED:csbits = &csbits_enhanced2e[0]; break;
|
||||
case A2TYPE_APPLE2EENHANCED:csbits = GetEnhanced2e_csbits(); break;
|
||||
case A2TYPE_PRAVETS82: csbits = &csbits_pravets82[0]; g_nVideoCharSet = 0; break; // Apple ][ clone
|
||||
case A2TYPE_PRAVETS8M: csbits = &csbits_pravets8M[0]; g_nVideoCharSet = 0; break; // Apple ][ clone
|
||||
case A2TYPE_PRAVETS8A: csbits = &csbits_pravets8C[0]; break; // Apple //e clone
|
||||
|
|
|
@ -21,10 +21,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
|
||||
#include "StdAfx.h"
|
||||
#include "Applewin.h"
|
||||
#include "Video.h"
|
||||
|
||||
#include "NTSC_CharSet.h"
|
||||
|
||||
unsigned char csbits_enhanced2e[2][256][8]; // Enhanced //e
|
||||
unsigned char csbits_enhanced2e[2][256][8]; // Enhanced //e (2732 4K video ROM)
|
||||
static unsigned char csbits_enhanced2e_pal[2][256][8]; // PAL Enhanced //e (2764 8K video ROM - top 4K) via rocker switch under keyboard
|
||||
unsigned char csbits_2e[2][256][8]; // Original //e (no mousetext)
|
||||
unsigned char csbits_a2[1][256][8]; // ][ and ][+
|
||||
unsigned char csbits_pravets82[1][256][8]; // Pravets 82
|
||||
|
@ -86,6 +88,91 @@ static void get_csbits(csbits_t csbits, const char* resourceName, const UINT cy0
|
|||
delete [] pBuffer;
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
// ROM address (RA):
|
||||
// -----------------
|
||||
// . RA10,..,RA3;SEGC,SEGB,SEGA => [2^8][2^3] => 256 chars of 8 lines (total = 2KiB)
|
||||
// . VID7,..,VID0 is the 8-bit video character (eg. from TEXT/$400 memory)
|
||||
//
|
||||
// UTAIIe:8-13, Table 8.2:
|
||||
//
|
||||
// ALTCHRSET | RA10 | RA9
|
||||
//------------------------------------------
|
||||
// 0 | VID7 + VID6.FLASH | VID6.VID7
|
||||
// 1 | VID7 | VID6
|
||||
//
|
||||
// FLASH toggles every 16 VBLs, so alternates between selecting NORMAL control/special and INVERSE control/special
|
||||
//
|
||||
|
||||
void userVideoRom4K(csbits_t csbits, const BYTE* pVideoRom)
|
||||
{
|
||||
int RA = 0; // rom address
|
||||
int i = 0;
|
||||
|
||||
// regular char set
|
||||
|
||||
for (; i<64; i++, RA+=8) // [00..3F] INVERSE / [40..7F] FLASH
|
||||
{
|
||||
for (int y=0; y<8; y++)
|
||||
{
|
||||
csbits[0][i][y] = pVideoRom[RA+y] ^ 0xff; // UTAIIe:8-11 "dot patterns in the video ROM are inverted..."
|
||||
csbits[0][i+64][y] = pVideoRom[RA+y] ^ 0xff; // UTAIIe:8-14 (Table 8.3) we use FLASH=0, so RA=00ccccccsss
|
||||
}
|
||||
}
|
||||
|
||||
RA = (1<<10 | 0<<9); // UTAIIe:8-14 (Table 8.3)
|
||||
|
||||
for (i=128; i<256; i++, RA+=8) // [80..BF] NORMAL
|
||||
{
|
||||
for (int y=0; y<8; y++)
|
||||
{
|
||||
csbits[0][i][y] = pVideoRom[RA+y] ^ 0xff; // UTAIIe:8-11 "dot patterns in the video ROM are inverted..."
|
||||
}
|
||||
}
|
||||
|
||||
RA = (1<<10 | 1<<9); // UTAIIe:8-14 (Table 8.3)
|
||||
|
||||
for (i=192; i<256; i++, RA+=8) // [C0..FF] NORMAL
|
||||
{
|
||||
for (int y=0; y<8; y++)
|
||||
{
|
||||
csbits[0][i][y] = pVideoRom[RA+y] ^ 0xff; // UTAIIe:8-11 "dot patterns in the video ROM are inverted..."
|
||||
}
|
||||
}
|
||||
|
||||
// alt char set
|
||||
|
||||
RA = 0;
|
||||
|
||||
for (i=0; i<256; i++, RA+=8) // [00..7F] INVERSE / [80..FF] NORMAL
|
||||
{
|
||||
for (int y=0; y<8; y++)
|
||||
{
|
||||
csbits[1][i][y] = pVideoRom[RA+y] ^ 0xff; // UTAIIe:8-11 "dot patterns in the video ROM are inverted..."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void userVideoRom(void)
|
||||
{
|
||||
const BYTE* pVideoRom;
|
||||
UINT size = GetVideoRom(pVideoRom); // 4K or 8K
|
||||
if (!size)
|
||||
return;
|
||||
|
||||
if (size == kVideoRomSize4K)
|
||||
{
|
||||
userVideoRom4K(&csbits_enhanced2e[0], pVideoRom);
|
||||
return;
|
||||
}
|
||||
|
||||
userVideoRom4K(&csbits_enhanced2e_pal[0], pVideoRom);
|
||||
userVideoRom4K(&csbits_enhanced2e[0], &pVideoRom[4*1024]);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void make_csbits(void)
|
||||
{
|
||||
get_csbits(&csbits_enhanced2e[0], TEXT("CHARSET40"), 0); // Enhanced //e: Alt char set off
|
||||
|
@ -99,4 +186,15 @@ void make_csbits(void)
|
|||
// Original //e is just Enhanced //e with the 32 mousetext chars [0x40..0x5F] replaced by the non-alt charset chars [0x40..0x5F]
|
||||
memcpy(csbits_2e, csbits_enhanced2e, sizeof(csbits_enhanced2e));
|
||||
memcpy(&csbits_2e[1][64], &csbits_2e[0][64], 32*8);
|
||||
|
||||
// Try to use any user-provided video ROM for Enhanced //e
|
||||
userVideoRom();
|
||||
}
|
||||
|
||||
csbits_t GetEnhanced2e_csbits(void)
|
||||
{
|
||||
if (IsVideoRom4K())
|
||||
return csbits_enhanced2e;
|
||||
|
||||
return GetVideoRomRockerSwitch() == false ? csbits_enhanced2e : csbits_enhanced2e_pal;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
typedef unsigned char (*csbits_t)[256][8];
|
||||
|
||||
extern unsigned char csbits_enhanced2e[2][256][8]; // Enhanced //e
|
||||
extern unsigned char csbits_enhanced2e[2][256][8]; // Enhanced //e (2732 4K video ROM)
|
||||
extern unsigned char csbits_2e[2][256][8]; // Original //e (no mousetext)
|
||||
extern unsigned char csbits_a2[1][256][8]; // ][ and ][+
|
||||
extern unsigned char csbits_pravets82[1][256][8]; // Pravets 82
|
||||
|
@ -10,3 +10,4 @@ extern unsigned char csbits_pravets8M[1][256][8]; // Pravets 8M
|
|||
extern unsigned char csbits_pravets8C[2][256][8]; // Pravets 8A & 8C
|
||||
|
||||
void make_csbits(void);
|
||||
csbits_t GetEnhanced2e_csbits(void);
|
||||
|
|
|
@ -315,6 +315,7 @@ bool Printer_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT
|
|||
inactivity = yamlLoadHelper.LoadUint(SS_YAML_KEY_INACTIVITY);
|
||||
g_PrinterIdleLimit = yamlLoadHelper.LoadUint(SS_YAML_KEY_IDLELIMIT);
|
||||
strncpy(g_szPrintFilename, yamlLoadHelper.LoadString(SS_YAML_KEY_FILENAME).c_str(), sizeof(g_szPrintFilename));
|
||||
g_szPrintFilename[sizeof(g_szPrintFilename)-1] = 0;
|
||||
|
||||
if (yamlLoadHelper.LoadBool(SS_YAML_KEY_FILEOPEN))
|
||||
{
|
||||
|
|
|
@ -373,7 +373,6 @@ static void ParseSlots(YamlLoadHelper& yamlLoadHelper, UINT version)
|
|||
if (!yamlLoadHelper.GetSubMap(std::string(SS_YAML_KEY_STATE)))
|
||||
throw std::string(SS_YAML_KEY_UNIT ": Expected sub-map name: " SS_YAML_KEY_STATE);
|
||||
|
||||
bool bIsCardSupported = true;
|
||||
SS_CARDTYPE type = CT_Empty;
|
||||
bool bRes = false;
|
||||
|
||||
|
@ -422,21 +421,22 @@ static void ParseSlots(YamlLoadHelper& yamlLoadHelper, UINT version)
|
|||
{
|
||||
type = CT_LanguageCard;
|
||||
SetExpansionMemType(type);
|
||||
CreateLanguageCard();
|
||||
bRes = GetLanguageCard()->LoadSnapshot(yamlLoadHelper, slot, version);
|
||||
}
|
||||
else if (card == Saturn128K::GetSnapshotCardName())
|
||||
{
|
||||
type = CT_Saturn128K;
|
||||
SetExpansionMemType(type);
|
||||
CreateLanguageCard();
|
||||
bRes = GetLanguageCard()->LoadSnapshot(yamlLoadHelper, slot, version);
|
||||
}
|
||||
else
|
||||
{
|
||||
bIsCardSupported = false;
|
||||
throw std::string("Slots: Unknown card: " + card); // todo: don't throw - just ignore & continue
|
||||
}
|
||||
|
||||
if (bRes && bIsCardSupported)
|
||||
if (bRes)
|
||||
{
|
||||
m_ConfigNew.m_Slot[slot] = type;
|
||||
}
|
||||
|
@ -607,7 +607,7 @@ void Snapshot_SaveState(void)
|
|||
yamlSaveHelper.UnitHdr(GetSnapshotUnitSlotsName(), UNIT_SLOTS_VER);
|
||||
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
||||
|
||||
if (IsApple2PlusOrClone(GetApple2Type()))
|
||||
if (g_Slot0 != CT_Empty && IsApple2PlusOrClone(GetApple2Type()))
|
||||
GetLanguageCard()->SaveSnapshot(yamlSaveHelper); // Language Card or Saturn 128K
|
||||
|
||||
Printer_SaveSnapshot(yamlSaveHelper);
|
||||
|
|
|
@ -1316,6 +1316,7 @@ char* CSuperSerialCard::GetSerialPortChoices()
|
|||
void CSuperSerialCard::SetSerialPortName(const char* pSerialPortName)
|
||||
{
|
||||
strncpy(m_ayCurrentSerialPortName, pSerialPortName, SIZEOF_SERIALCHOICE_ITEM);
|
||||
m_ayCurrentSerialPortName[SIZEOF_SERIALCHOICE_ITEM-1] = 0;
|
||||
|
||||
// Init m_aySerialPortChoices, so that we have choices to show if serial is active when we 1st open Config dialog
|
||||
GetSerialPortChoices();
|
||||
|
|
|
@ -647,7 +647,7 @@ void VideoResetState ()
|
|||
|
||||
//===========================================================================
|
||||
|
||||
BYTE VideoSetMode (WORD, WORD address, BYTE write, BYTE, ULONG uExecutedCycles)
|
||||
BYTE VideoSetMode(WORD, WORD address, BYTE write, BYTE, ULONG uExecutedCycles)
|
||||
{
|
||||
address &= 0xFF;
|
||||
|
||||
|
@ -1141,6 +1141,65 @@ static void Video_SaveScreenShot( const char *pScreenShotFileName, const VideoSc
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
|
||||
static const UINT kVideoRomSize8K = kVideoRomSize4K*2;
|
||||
static const UINT kVideoRomSize16K = kVideoRomSize8K*2;
|
||||
static const UINT kVideoRomSizeMax = kVideoRomSize16K;
|
||||
static BYTE g_videoRom[kVideoRomSizeMax];
|
||||
static UINT g_videoRomSize = 0;
|
||||
static bool g_videoRomRockerSwitch = false;
|
||||
|
||||
bool ReadVideoRomFile(const char* pRomFile)
|
||||
{
|
||||
g_videoRomSize = 0;
|
||||
|
||||
HANDLE h = CreateFile(pRomFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
const ULONG size = GetFileSize(h, NULL);
|
||||
if (size == kVideoRomSize4K || size == kVideoRomSize8K || size == kVideoRomSize16K)
|
||||
{
|
||||
DWORD bytesRead;
|
||||
if (ReadFile(h, g_videoRom, size, &bytesRead, NULL) && bytesRead == size)
|
||||
g_videoRomSize = size;
|
||||
}
|
||||
|
||||
if (g_videoRomSize == kVideoRomSize16K)
|
||||
{
|
||||
// Use top 8K (assume bottom 8K is all 0xFF's)
|
||||
memcpy(&g_videoRom[0], &g_videoRom[kVideoRomSize8K], kVideoRomSize8K);
|
||||
g_videoRomSize = kVideoRomSize8K;
|
||||
}
|
||||
|
||||
CloseHandle(h);
|
||||
|
||||
return g_videoRomSize != 0;
|
||||
}
|
||||
|
||||
UINT GetVideoRom(const BYTE*& pVideoRom)
|
||||
{
|
||||
pVideoRom = &g_videoRom[0];
|
||||
return g_videoRomSize;
|
||||
}
|
||||
|
||||
bool GetVideoRomRockerSwitch(void)
|
||||
{
|
||||
return g_videoRomRockerSwitch;
|
||||
}
|
||||
|
||||
void SetVideoRomRockerSwitch(bool state)
|
||||
{
|
||||
g_videoRomRockerSwitch = state;
|
||||
}
|
||||
|
||||
bool IsVideoRom4K(void)
|
||||
{
|
||||
return g_videoRomSize == 0 || g_videoRomSize == kVideoRomSize4K;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
void Config_Load_Video()
|
||||
|
@ -1160,8 +1219,6 @@ void Config_Save_Video()
|
|||
REGSAVE(TEXT(REGVALUE_VIDEO_MONO_COLOR ),g_nMonochromeRGB);
|
||||
}
|
||||
|
||||
// ____________________________________________________________________
|
||||
|
||||
//===========================================================================
|
||||
static void videoCreateDIBSection()
|
||||
{
|
||||
|
|
|
@ -198,7 +198,14 @@ enum VideoScreenShot_e
|
|||
void Video_TakeScreenShot( VideoScreenShot_e iScreenShotType );
|
||||
void Video_SetBitmapHeader( WinBmpHeader_t *pBmp, int nWidth, int nHeight, int nBitsPerPixel );
|
||||
|
||||
BYTE VideoSetMode (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG uExecutedCycles);
|
||||
BYTE VideoSetMode(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG uExecutedCycles);
|
||||
|
||||
const UINT kVideoRomSize4K = 4*1024;
|
||||
bool ReadVideoRomFile(const char* pRomFile);
|
||||
UINT GetVideoRom(const BYTE*& pVideoRom);
|
||||
bool GetVideoRomRockerSwitch(void);
|
||||
void SetVideoRomRockerSwitch(bool state);
|
||||
bool IsVideoRom4K(void);
|
||||
|
||||
void Config_Load_Video(void);
|
||||
void Config_Save_Video(void);
|
||||
|
|
Loading…
Add table
Reference in a new issue