Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Andrea Odetti 2018-08-25 21:18:04 +01:00
commit d0bb3f5815
12 changed files with 142 additions and 108 deletions

View file

@ -8,6 +8,15 @@ https://github.com/AppleWin/AppleWin/issues/new
Tom Charlesworth
1.27.7.0 - 6 Aug 2018
---------------------
. [Bug #564] Fixed 'Save State on Exit' not working correctly when there's a Configuration change to the hardware.
. [Bug #556] Reverted default so that ALT+TAB is not hooked (#556)
- Support new command line switch: -hook-alt-tab to support hooking ALT+TAB.
. [Bug #558] Reverted default so that ALT GR's fake LEFT CONTROL is not hooked (#558)
- Support new command line switch: -hook-altgr-control to suppess ALR GR's fake LEFT CONTROL.
1.27.6.0 - 28 Jul 2018
----------------------
. [Bug #570] Fixed lag when repeat-stepping in debugger.

View file

@ -43,7 +43,14 @@
-no-printscreen-key<br>
Prevent the PrintScreen key from being registered<br><br>
-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+&lt;key&gt; combinations won't work within the emulator.<br><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+&lt;key&gt; combinations won't work within the emulator.<br>
NB. This switch takes precedence over -hook-alt-tab and -hook-altgr-control.<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>
By default the emulator doesn't suppress ALT GR's (Right Alt's) fake LEFT CONTROL. Use this to suppress this fake LEFT CONTROL to allow Closed Apple+CTRL+&lt;key&gt; to be readable by the emulated machine.<br>
NB. Suppressing this fake LEFT CONTROL seems to prevent international keyboards from being able to type certain keys.
<br><br>
-use-real-printer<br>
Enables Advanced configuration control to allow dumping to a real printer<br><br>
-noreg<br>

View file

@ -29,7 +29,7 @@
The Solid Apple key was introduced on the Apple //e and later renamed to the
Option key. This key is emulated with the PC's
<span style="font-style: italic;">Right Alt</span>
key, which is in the same position as the Solid Apple key on the original //e.
key (or <span style="font-style: italic;">Alt Gr</span> key), which is in the same position as the Solid Apple key on the original //e.
</p>
<p><span style="font-weight: bold;">Numeric Keypad:</span><br>
The numeric keypad, introduced on the Extended Keyboard //e, is emulated

View file

@ -13,7 +13,8 @@
<p>The complete<sub style="FONT-WEIGHT: bold">1</sub> Apple //e state can be saved
to a PC file at any time. This can be useful for continuity across AppleWin
sessions or to help with games that don't have a save option.</p>
<p>This is controlled by the AppleWin Configuration tab labelled <em>Advanced</em>.</p>
<p>The state can optionally be automatically saved on AppleWin exit, and (automatically) restored on AppleWin restart.</p>
<p>This is all controlled by the AppleWin <a href="cfg-advanced.html">Configuration</a> tab labeled <em>Advanced</em>.</p>
<p style="FONT-WEIGHT: bold">Details:</p>
<p>The entire Apple //e state is saved to a human-readable (.yaml) file.</p>
<p><span style="FONT-WEIGHT: bold">1</span>
@ -28,6 +29,7 @@
<li>Mouse card</li>
<li>CP/M SoftCard</li>
<li>Parallel Printer card</li>
<li>Super Serial card</li>
</ul>
The following are not yet persisted to the file:
<ul>

View file

@ -252,8 +252,8 @@ DISK_ICON ICON "DISK.ICO"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,27,6,0
PRODUCTVERSION 1,27,6,0
FILEVERSION 1,27,7,0
PRODUCTVERSION 1,27,7,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, 6, 0"
VALUE "FileVersion", "1, 27, 7, 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, 6, 0"
VALUE "ProductVersion", "1, 27, 7, 0"
END
END
BLOCK "VarFileInfo"

View file

@ -1399,6 +1399,8 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
unsigned long fix_minor = g_AppleWinVersion[3] = pFixedFileInfo->dwFileVersionLS & 0xffff;
sprintf(VERSIONSTRING, "%d.%d.%d.%d", major, minor, fix, fix_minor); // potential buffer overflow
}
delete [] pVerInfoBlock;
}
LogFileOutput("AppleWin version: %s\n", VERSIONSTRING);

View file

@ -1214,41 +1214,53 @@ ImageError_e CImageHelperBase::CheckZipFile(LPCTSTR pszImageFilename, ImageInfo*
return eIMAGE_ERROR_UNABLE_TO_OPEN_ZIP;
unz_global_info global_info;
int nRes = unzGetGlobalInfo(hZipFile, &global_info);
if (nRes != UNZ_OK)
return eIMAGE_ERROR_ZIP;
nRes = unzGoToFirstFile(hZipFile); // Only support 1st file in zip archive for now
if (nRes != UNZ_OK)
return eIMAGE_ERROR_ZIP;
unz_file_info file_info;
char szFilename[MAX_PATH];
memset(szFilename, 0, sizeof(szFilename));
nRes = unzGetCurrentFileInfo(hZipFile, &file_info, szFilename, MAX_PATH, NULL, 0, NULL, 0);
if (nRes != UNZ_OK)
return eIMAGE_ERROR_ZIP;
int nRes = 0, nLen = 0;
const UINT uFileSize = file_info.uncompressed_size;
if (uFileSize > GetMaxImageSize())
return eIMAGE_ERROR_BAD_SIZE;
pImageInfo->pImageBuffer = new BYTE[uFileSize];
nRes = unzOpenCurrentFile(hZipFile);
if (nRes != UNZ_OK)
return eIMAGE_ERROR_ZIP;
int nLen = unzReadCurrentFile(hZipFile, pImageInfo->pImageBuffer, uFileSize);
if (nLen < 0)
try
{
unzCloseCurrentFile(hZipFile); // Must CloseCurrentFile before Close
return eIMAGE_ERROR_UNSUPPORTED;
}
nRes = unzGetGlobalInfo(hZipFile, &global_info);
if (nRes != UNZ_OK)
throw eIMAGE_ERROR_ZIP;
nRes = unzCloseCurrentFile(hZipFile);
if (nRes != UNZ_OK)
return eIMAGE_ERROR_ZIP;
nRes = unzGoToFirstFile(hZipFile); // Only support 1st file in zip archive for now
if (nRes != UNZ_OK)
throw eIMAGE_ERROR_ZIP;
nRes = unzGetCurrentFileInfo(hZipFile, &file_info, szFilename, MAX_PATH, NULL, 0, NULL, 0);
if (nRes != UNZ_OK)
throw eIMAGE_ERROR_ZIP;
const UINT uFileSize = file_info.uncompressed_size;
if (uFileSize > GetMaxImageSize())
throw eIMAGE_ERROR_BAD_SIZE;
pImageInfo->pImageBuffer = new BYTE[uFileSize];
nRes = unzOpenCurrentFile(hZipFile);
if (nRes != UNZ_OK)
throw eIMAGE_ERROR_ZIP;
nLen = unzReadCurrentFile(hZipFile, pImageInfo->pImageBuffer, uFileSize);
if (nLen < 0)
{
unzCloseCurrentFile(hZipFile); // Must CloseCurrentFile before Close
throw eIMAGE_ERROR_UNSUPPORTED;
}
nRes = unzCloseCurrentFile(hZipFile);
if (nRes != UNZ_OK)
throw eIMAGE_ERROR_ZIP;
}
catch (ImageError_e error)
{
if (hZipFile)
unzClose(hZipFile);
return error;
}
nRes = unzClose(hZipFile);
hZipFile = NULL;

View file

@ -1886,7 +1886,7 @@ static void GenerateVideoTables( void )
g_uVideoMode = VF_HIRES;
for (UINT i=0, cycle=VIDEO_SCANNER_HORZ_START; i<VIDEO_SCANNER_MAX_VERT; i++, cycle+=VIDEO_SCANNER_MAX_HORZ)
{
g_aClockVertOffsetsHGR[i] = VideoGetScannerAddressPartialV(cycle);
g_aClockVertOffsetsHGR[i] = VideoGetScannerAddress(cycle, VS_PartialAddrV);
_ASSERT(g_aClockVertOffsetsHGR[i] == g_kClockVertOffsetsHGR[i]);
}
@ -1897,7 +1897,7 @@ static void GenerateVideoTables( void )
g_uVideoMode = VF_TEXT;
for (UINT i=0, cycle=VIDEO_SCANNER_HORZ_START; i<(256+8)/8; i++, cycle+=VIDEO_SCANNER_MAX_HORZ*8)
{
g_aClockVertOffsetsTXT[i] = VideoGetScannerAddressPartialV(cycle);
g_aClockVertOffsetsTXT[i] = VideoGetScannerAddress(cycle, VS_PartialAddrV);
_ASSERT(g_aClockVertOffsetsTXT[i] == g_kClockVertOffsetsTXT[i]);
}
@ -1911,7 +1911,7 @@ static void GenerateVideoTables( void )
{
for (UINT i=0, cycle=j*64*VIDEO_SCANNER_MAX_HORZ; i<VIDEO_SCANNER_MAX_HORZ; i++, cycle++)
{
APPLE_IIP_HORZ_CLOCK_OFFSET[j][i] = VideoGetScannerAddressPartialH(cycle);
APPLE_IIP_HORZ_CLOCK_OFFSET[j][i] = VideoGetScannerAddress(cycle, VS_PartialAddrH);
_ASSERT(APPLE_IIP_HORZ_CLOCK_OFFSET[j][i] == kAPPLE_IIP_HORZ_CLOCK_OFFSET[j][i]);
}
}
@ -1926,7 +1926,7 @@ static void GenerateVideoTables( void )
{
for (UINT i=0, cycle=j*64*VIDEO_SCANNER_MAX_HORZ; i<VIDEO_SCANNER_MAX_HORZ; i++, cycle++)
{
APPLE_IIE_HORZ_CLOCK_OFFSET[j][i] = VideoGetScannerAddressPartialH(cycle);
APPLE_IIE_HORZ_CLOCK_OFFSET[j][i] = VideoGetScannerAddress(cycle, VS_PartialAddrH);
_ASSERT(APPLE_IIE_HORZ_CLOCK_OFFSET[j][i] == kAPPLE_IIE_HORZ_CLOCK_OFFSET[j][i]);
}
}

View file

@ -29,6 +29,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "StdAfx.h"
#include "Applewin.h"
#include "Frame.h" // g_hFrameWindow
#include "Memory.h"
#include "ParallelPrinter.h"
#include "Registry.h"
@ -234,14 +235,26 @@ char* Printer_GetFilename()
void Printer_SetFilename(char* prtFilename)
{
if(*prtFilename)
if (*prtFilename)
{
strcpy(g_szPrintFilename, (const char *) prtFilename);
}
else //No registry entry is available
{
_tcsncpy(g_szPrintFilename, g_sProgramDir, MAX_PATH);
g_szPrintFilename[MAX_PATH - 1] = 0;
_tcsncat(g_szPrintFilename, _T(DEFAULT_PRINT_FILENAME), MAX_PATH);
RegSaveString(TEXT("Configuration"),REGVALUE_PRINTER_FILENAME,1,g_szPrintFilename);
// NB. _tcsncat_s() terminates program if buffer is too small! So continue to use manual buffer check & _tcsncat()
int nLen = sizeof(g_szPrintFilename) - strlen(g_szPrintFilename) - (sizeof(DEFAULT_PRINT_FILENAME)-1) - 1;
if (nLen < 0)
{
MessageBox(g_hFrameWindow, "Printer - SetFilename(): folder too deep", "Warning", MB_ICONWARNING | MB_OK);
return;
}
_tcsncat(g_szPrintFilename, DEFAULT_PRINT_FILENAME, sizeof(DEFAULT_PRINT_FILENAME)-1);
RegSaveString(REG_CONFIG, REGVALUE_PRINTER_FILENAME, 1, g_szPrintFilename);
}
}

View file

@ -216,6 +216,7 @@ bool CSuperSerialCard::CheckComm()
// have socket so attempt to bind it
SOCKADDR_IN saAddress;
memset(&saAddress, 0, sizeof(SOCKADDR_IN));
saAddress.sin_family = AF_INET;
saAddress.sin_port = htons(TCP_SERIAL_PORT); // TODO: get from registry / GUI
saAddress.sin_addr.s_addr = htonl(INADDR_ANY);

View file

@ -93,7 +93,7 @@ uint32_t g_uVideoMode = VF_TEXT; // Current Video Mode (this is the last se
DWORD g_eVideoType = VT_COLOR_TV;
DWORD g_uHalfScanLines = 1; // drop 50% scan lines for a more authentic look
static const bool bVideoScannerNTSC = true; // NTSC video scanning (or PAL)
static const bool g_bVideoScannerNTSC = true; // NTSC video scanning (or PAL)
//-------------------------------------
@ -542,7 +542,7 @@ void VideoRedrawScreenDuringFullSpeed(DWORD dwCyclesThisFrame, bool bInit /*=fal
void VideoRedrawScreenAfterFullSpeed(DWORD dwCyclesThisFrame)
{
if (bVideoScannerNTSC)
if (g_bVideoScannerNTSC)
{
NTSC_VideoClockResync(dwCyclesThisFrame);
}
@ -770,35 +770,20 @@ void VideoLoadSnapshot(YamlLoadHelper& yamlLoadHelper)
// References to Jim Sather's books are given as eg:
// UTAIIe:5-7,P3 (Understanding the Apple IIe, chapter 5, page 7, Paragraph 3)
//
static WORD g_PartialV=0, g_PartialH=0;
WORD VideoGetScannerAddressPartialV(DWORD nCycles)
{
VideoGetScannerAddress(nCycles);
return g_PartialV;
}
WORD VideoGetScannerAddressPartialH(DWORD nCycles)
{
VideoGetScannerAddress(nCycles);
return g_PartialH;
}
WORD VideoGetScannerAddress(DWORD nCycles)
WORD VideoGetScannerAddress(DWORD nCycles, VideoScanner_e videoScannerAddr /*= VS_FullAddr*/)
{
// machine state switches
//
int nHires = (SW_HIRES && !SW_TEXT) ? 1 : 0;
int nPage2 = SW_PAGE2 ? 1 : 0;
int n80Store = SW_80STORE ? 1 : 0;
bool bHires = VideoGetSWHIRES() && !VideoGetSWTEXT();
bool bPage2 = VideoGetSWPAGE2();
bool b80Store = VideoGetSW80STORE();
// calculate video parameters according to display standard
//
int nScanLines = bVideoScannerNTSC ? kNTSCScanLines : kPALScanLines;
int nVSyncLine = bVideoScannerNTSC ? kNTSCVSyncLine : kPALVSyncLine;
int nScanCycles = nScanLines * kHClocks;
nCycles %= nScanCycles;
const int kScanLines = g_bVideoScannerNTSC ? kNTSCScanLines : kPALScanLines;
const int kScanCycles = kScanLines * kHClocks;
_ASSERT(nCycles < kScanCycles);
nCycles %= kScanCycles;
// calculate horizontal scanning state
//
@ -821,7 +806,7 @@ WORD VideoGetScannerAddress(DWORD nCycles)
int nVState = kVLine0State + nVLine; // V state bits
if (nVLine >= kVPresetLine) // check for previous vertical state preset
{
nVState -= nScanLines; // compensate for preset
nVState -= kScanLines; // compensate for preset
}
int v_A = (nVState >> 0) & 1; // get vertical state bits
int v_B = (nVState >> 1) & 1;
@ -835,9 +820,9 @@ WORD VideoGetScannerAddress(DWORD nCycles)
// calculate scanning memory address
//
if (nHires && SW_MIXED && v_4 && v_2) // HIRES TIME signal (UTAIIe:5-7,P3)
if (bHires && SW_MIXED && v_4 && v_2) // HIRES TIME signal (UTAIIe:5-7,P3)
{
nHires = 0; // address is in text memory for mixed hires
bHires = false; // address is in text memory for mixed hires
}
int nAddend0 = 0x0D; // 1 1 0 1
@ -845,54 +830,58 @@ WORD VideoGetScannerAddress(DWORD nCycles)
int nAddend2 = (v_4 << 3) | (v_3 << 2) | (v_4 << 1) | (v_3 << 0);
int nSum = (nAddend0 + nAddend1 + nAddend2) & 0x0F; // SUM (UTAIIe:5-9)
int nAddress = 0; // build address from video scanner equations (UTAIIe:5-8,T5.1)
nAddress |= h_0 << 0; // a0
nAddress |= h_1 << 1; // a1
nAddress |= h_2 << 2; // a2
nAddress |= nSum << 3; // a3 - a6
g_PartialH = nAddress;
WORD nAddressH = 0; // build address from video scanner equations (UTAIIe:5-8,T5.1)
nAddressH |= h_0 << 0; // a0
nAddressH |= h_1 << 1; // a1
nAddressH |= h_2 << 2; // a2
nAddressH |= nSum << 3; // a3 - a6
if (!bHires)
{
// Apple ][ (not //e) and HBL?
//
if (IS_APPLE2 && // Apple II only (UTAIIe:I-4,#5)
!h_5 && (!h_4 || !h_3)) // HBL (UTAIIe:8-10,F8.5)
{
nAddressH |= 1 << 12; // Y: a12 (add $1000 to address!)
}
}
nAddress |= v_0 << 7; // a7
nAddress |= v_1 << 8; // a8
nAddress |= v_2 << 9; // a9
WORD nAddressV = 0;
nAddressV |= v_0 << 7; // a7
nAddressV |= v_1 << 8; // a8
nAddressV |= v_2 << 9; // a9
int p2a = !(nPage2 && !n80Store);
int p2b = nPage2 && !n80Store;
int p2a = !(bPage2 && !b80Store) ? 1 : 0;
int p2b = (bPage2 && !b80Store) ? 1 : 0;
if (nHires) // hires?
WORD nAddressP = 0; // Page bits
if (bHires) // hires?
{
// Y: insert hires-only address bits
//
nAddress |= v_A << 10; // a10
nAddress |= v_B << 11; // a11
nAddress |= v_C << 12; // a12
g_PartialV = nAddress - g_PartialH;
nAddress |= p2a << 13; // a13
nAddress |= p2b << 14; // a14
nAddressV |= v_A << 10; // a10
nAddressV |= v_B << 11; // a11
nAddressV |= v_C << 12; // a12
nAddressP |= p2a << 13; // a13
nAddressP |= p2b << 14; // a14
}
else
{
// N: insert text-only address bits
//
g_PartialV = nAddress - g_PartialH;
// Apple ][ (not //e) and HBL?
//
if (IS_APPLE2 && // Apple II only (UTAIIe:I-4,#5)
!h_5 && (!h_4 || !h_3)) // HBL (UTAIIe:8-10,F8.5)
{
nAddress |= 1 << 12; // Y: a12 (add $1000 to address!)
g_PartialH |= 1 << 12;
}
nAddress |= p2a << 10; // a10
nAddress |= p2b << 11; // a11
nAddressP |= p2a << 10; // a10
nAddressP |= p2b << 11; // a11
}
// VBL' = v_4' | v_3' = (v_4 & v_3)' (UTAIIe:5-10,#3)
return static_cast<WORD>(nAddress);
if (videoScannerAddr == VS_PartialAddrH)
return nAddressH;
if (videoScannerAddr == VS_PartialAddrV)
return nAddressV;
return nAddressP | nAddressV | nAddressH;
}
//===========================================================================
@ -903,7 +892,7 @@ bool VideoGetVblBar(const DWORD uExecutedCycles)
int nCycles = CpuGetCyclesThisVideoFrame(uExecutedCycles);
// calculate video parameters according to display standard
const int kScanLines = bVideoScannerNTSC ? kNTSCScanLines : kPALScanLines;
const int kScanLines = g_bVideoScannerNTSC ? kNTSCScanLines : kPALScanLines;
const int kScanCycles = kScanLines * kHClocks;
nCycles %= kScanCycles;

View file

@ -169,9 +169,8 @@ void VideoRedrawScreen (void);
void VideoRefreshScreen (uint32_t uRedrawWholeScreenVideoMode = 0, bool bRedrawWholeScreen = false);
void VideoReinitialize ();
void VideoResetState ();
WORD VideoGetScannerAddressPartialV(DWORD nCycles);
WORD VideoGetScannerAddressPartialH(DWORD nCycles);
WORD VideoGetScannerAddress(DWORD nCycles);
enum VideoScanner_e {VS_FullAddr, VS_PartialAddrV, VS_PartialAddrH};
WORD VideoGetScannerAddress(DWORD nCycles, VideoScanner_e videoScannerAddr = VS_FullAddr);
bool VideoGetVblBar(DWORD uExecutedCycles);
bool VideoGetSW80COL(void);