2014-10-18: Updated to version 1.56
Signed-off-by: Gwenhael Le Moine <gwenhael.le.moine@gmail.com>
This commit is contained in:
parent
769c17c88a
commit
625fd3f663
30 changed files with 1115 additions and 976 deletions
BIN
EMU48.EXE
BIN
EMU48.EXE
Binary file not shown.
BIN
Emu48.exe
Executable file
BIN
Emu48.exe
Executable file
Binary file not shown.
|
@ -1,4 +1,4 @@
|
|||
Known bugs and restrictions of Emu48 V1.55
|
||||
Known bugs and restrictions of Emu48 V1.56
|
||||
------------------------------------------
|
||||
|
||||
- the following I/O bits aren't emulated (incomplete)
|
||||
|
@ -47,4 +47,4 @@ Known bugs and restrictions of Emu48 V1.55
|
|||
- quitting the emulator while programming the flash isn't allowed,
|
||||
because the content of flash state machine isn't saved so far
|
||||
|
||||
05/21/13 (c) by Christoph Gießelink, c dot giesselink at gmx dot de
|
||||
04/29/14 (c) by Christoph Gießelink, c dot giesselink at gmx dot de
|
||||
|
|
|
@ -1,3 +1,114 @@
|
|||
Service Pack 56 for Emu48 Version 1.0
|
||||
|
||||
DEBUGGER.C
|
||||
- removed INSTRSIZE definition
|
||||
- changed function GetAddr(), made function more general by adding
|
||||
address range check and the ability of decoding a symbolic entry
|
||||
into an address
|
||||
- bugfix in function OnSetCursor(), on "Activation follows mouse"
|
||||
enabled child dialogs lost focus when cursor moved over parent
|
||||
debugger dialog
|
||||
- changed function Debugger(), removed initialization of global
|
||||
variable wInstrSize
|
||||
- changed function EnterAddr(), changed parameter storage from
|
||||
static variable to window user data and replaced address decoder
|
||||
code by GetAddr() function call
|
||||
- changed function EnterBreakpoint(), replaced address decoder code
|
||||
by GetAddr() function call and so added decoding a symbolic entry
|
||||
into an address
|
||||
- bugfix in function LoadMemData(), forgot to check if file content
|
||||
fit into Saturn address range, loading now stops also after last
|
||||
Saturn address written
|
||||
- changed function SaveMemData(), added assertion for Saturn address
|
||||
verification
|
||||
- bugfix in function DebugMemLoad() and DebugMemSave(), adjusted to
|
||||
new prototype of function GetAddr() and so added checking if the
|
||||
given addresses are in the Saturn address range because Saturn
|
||||
read/write functions don't do the range check; this also cause a
|
||||
change in behavior, on empty address fields the operation fails
|
||||
and the dialog still remains open
|
||||
|
||||
EMU48.C
|
||||
- changed function SetSoundDeviceList(), replaced "Standard Audio"
|
||||
device ID from constant to definition
|
||||
- bugfix in function SettingsGeneralProc(), on "Activation follows
|
||||
mouse" enabled debugger dialog maybe got focus even if it's not
|
||||
the last active one
|
||||
- bugfix in function SettingsPeripheralProc(), restart the sound
|
||||
engine by calling the clean up and initialization functions now
|
||||
- changed function OnFileNew(), removed call of function
|
||||
SaveBackup() which is already a part of function NewDocument()
|
||||
- changed function OnFileNew(), OnFileOpen(), OnFileMruOpen(),
|
||||
OnFileSave(), OnFileSaveAs() and OnFileClose(), switched detection
|
||||
of document is available from variable pbyRom (ROM image loaded)
|
||||
to variable bDocumentAvail
|
||||
- changed function OnViewCopy(), removed MONOCHROME source code part
|
||||
- changed function WinMain(), added sound engine initialization and
|
||||
clean up
|
||||
|
||||
EMU48.RC
|
||||
- changed version and copyright
|
||||
|
||||
ENGINE.C
|
||||
- initialized variable wInstrSize with size of last instruction
|
||||
array (the circular buffer can hold (wInstrSize-1) instructions)
|
||||
- bugfix in function WorkerThread(), moved sound engine
|
||||
initialization and clean up from SM_RUN state to main function,
|
||||
this prevents a non responding Saturn CPU emulation when changing
|
||||
from SM_SLEEP to SM_RUN state during sound engine initialization
|
||||
|
||||
FETCH.C
|
||||
- made typedef of jump table struct constant, so the const keyword
|
||||
was removed from all references of JMPTAB
|
||||
- changed function EvalOpcode(), minor code optimization
|
||||
|
||||
FILES.C
|
||||
- bugfix in function PatchRom(), removed limitation that patch file
|
||||
must have 6 characters minimum, fixed a buffer overflow when end
|
||||
of patch file consists of white space characters, recalculate
|
||||
CRC's only on address patch written and return failture on syntax
|
||||
errors now
|
||||
|
||||
PCH.H
|
||||
- added GWLP_USERDATA, SetWindowLongPtr, GetWindowLongPtr and
|
||||
LONG_PTR definitions for MSVC6.0 SDK and earlier
|
||||
|
||||
SETTINGS.C
|
||||
- changed function ReadSettings() and WriteSettings(), added item
|
||||
"LastInstrBufSize" in section [Debugger] in the INI-File
|
||||
|
||||
SOUND.C
|
||||
- bugfix in function DestroyWaveThread(), the WM_QUIT message may
|
||||
failed and so the sound message thread wasn't shut down
|
||||
- changed function SoundOpen(), added additional check if the sound
|
||||
device support the necessary audio format
|
||||
|
||||
STACK.C
|
||||
- added function Trim(), create a trimmed copy of the input string
|
||||
- added function SetZInt(), contain implementation of prior function
|
||||
RPL_SetZInt()
|
||||
- changed function RPL_SetZInt(), wrapper for function SetZInt() to
|
||||
trim data before decoding
|
||||
- added function SetBcd(), contain implementation of prior function
|
||||
RPL_SetBcd()
|
||||
- changed function RPL_SetBcd(), wrapper for function SetBcd() to
|
||||
trim data before decoding
|
||||
- changed function RPL_SetComplex(), create a trimmed working copy
|
||||
before decoding the outline brackets and because of the changed
|
||||
function RPL_SetBcd() the real number arguments are accepted with
|
||||
white spaces around now
|
||||
- removed disabled function IsRealNumber(), it was more or less
|
||||
functional compatible with actual modified function RPL_SetBcd()
|
||||
|
||||
TIMER.C
|
||||
- removed UNIX_0_TIME definition
|
||||
|
||||
UDP.C
|
||||
- changed function SendByteUdp(), replaced malloc() by _alloca()
|
||||
call for UNICODE wchar to char string translation to get rid of
|
||||
freeing the allocated memory manually
|
||||
|
||||
|
||||
Service Pack 55 for Emu48 Version 1.0
|
||||
|
||||
DISMEM.C
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
// assert for register update
|
||||
#define _ASSERTREG(r) _ASSERT(r >= REG_START && r <= REG_STOP)
|
||||
|
||||
#define INSTRSIZE 256 // size of last instruction buffer
|
||||
|
||||
#define WM_UPDATE (WM_USER+0x1000) // update debugger dialog box
|
||||
|
||||
#define MEMWNDMAX (sizeof(nCol) / sizeof(nCol[0]))
|
||||
|
@ -158,6 +156,50 @@ static VOID DisableMenuKeys(HWND hDlg)
|
|||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// read edit control and decode content as hex number or if enabled as symbol name
|
||||
//
|
||||
static BOOL GetAddr(HWND hDlg,INT nID,DWORD *pdwAddr,DWORD dwMaxAddr,BOOL bSymbEnable)
|
||||
{
|
||||
TCHAR szBuffer[48];
|
||||
INT i;
|
||||
BOOL bSucc = TRUE;
|
||||
|
||||
HWND hWnd = GetDlgItem(hDlg,nID);
|
||||
|
||||
GetWindowText(hWnd,szBuffer,ARRAYSIZEOF(szBuffer));
|
||||
|
||||
if (*szBuffer != 0)
|
||||
{
|
||||
// if address is not a symbol name decode number
|
||||
if ( !bSymbEnable || szBuffer[0] != _T('=')
|
||||
|| RplGetAddr(&szBuffer[1],pdwAddr))
|
||||
{
|
||||
// test if valid hex address
|
||||
for (i = 0; bSucc && i < (LONG) lstrlen(szBuffer); ++i)
|
||||
{
|
||||
bSucc = (_istxdigit(szBuffer[i]) != 0);
|
||||
}
|
||||
|
||||
if (bSucc) // valid characters
|
||||
{
|
||||
// convert string to number
|
||||
*pdwAddr = _tcstoul(szBuffer,NULL,16);
|
||||
}
|
||||
}
|
||||
|
||||
// inside address range?
|
||||
bSucc = bSucc && (*pdwAddr <= dwMaxAddr);
|
||||
|
||||
if (!bSucc) // invalid address
|
||||
{
|
||||
SendMessage(hWnd,EM_SETSEL,0,-1);
|
||||
SetFocus(hWnd); // focus to edit control
|
||||
}
|
||||
}
|
||||
return bSucc;
|
||||
}
|
||||
|
||||
//
|
||||
// set mapping menu
|
||||
//
|
||||
|
@ -1426,7 +1468,8 @@ static BOOL OnSetCursor(HWND hDlg)
|
|||
// debugger not active but cursor is over debugger window
|
||||
if (bActFollowsMouse && GetActiveWindow() != hDlg)
|
||||
{
|
||||
ForceForegroundWindow(hDlg); // force debugger window to foreground
|
||||
// force debugger window to foreground
|
||||
ForceForegroundWindow(GetLastActivePopup(hDlg));
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1866,8 +1909,7 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM
|
|||
SendDlgItemMessage(hDlg,IDC_STATIC_MISC, WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0));
|
||||
|
||||
// init last instruction circular buffer
|
||||
pdwInstrArray = (DWORD *) malloc(INSTRSIZE*sizeof(*pdwInstrArray));
|
||||
wInstrSize = INSTRSIZE; // size of last instruction array
|
||||
pdwInstrArray = (DWORD *) malloc(wInstrSize*sizeof(*pdwInstrArray));
|
||||
wInstrWp = wInstrRp = 0; // write/read pointer
|
||||
|
||||
// init "Follow" menu entry in debugger "Memory" context menu
|
||||
|
@ -2749,41 +2791,22 @@ static INT_PTR OnNewValue(LPTSTR lpszValue)
|
|||
//
|
||||
static INT_PTR CALLBACK EnterAddr(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static DWORD *pdwAddress;
|
||||
|
||||
HWND hWnd;
|
||||
TCHAR szBuffer[64];
|
||||
LONG i;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
pdwAddress = (DWORD *) lParam;
|
||||
SetWindowLongPtr(hDlg,GWLP_USERDATA,(LONG_PTR) lParam);
|
||||
return TRUE;
|
||||
case WM_COMMAND:
|
||||
wParam = LOWORD(wParam);
|
||||
switch(wParam)
|
||||
{
|
||||
case IDOK:
|
||||
hWnd = GetDlgItem(hDlg,IDC_ENTERADR);
|
||||
GetWindowText(hWnd,szBuffer,ARRAYSIZEOF(szBuffer));
|
||||
|
||||
// if address is not a symbol name decode number
|
||||
if ( !disassembler_symb || szBuffer[0] != _T('=')
|
||||
|| RplGetAddr(&szBuffer[1],pdwAddress))
|
||||
{
|
||||
// test if valid hex address
|
||||
for (i = 0; i < (LONG) lstrlen(szBuffer); ++i)
|
||||
{
|
||||
if (_istxdigit(szBuffer[i]) == 0)
|
||||
{
|
||||
SendMessage(hWnd,EM_SETSEL,0,-1);
|
||||
SetFocus(hWnd); // focus to edit control
|
||||
if (!GetAddr(hDlg,
|
||||
IDC_ENTERADR,
|
||||
(DWORD *) GetWindowLongPtr(hDlg,GWLP_USERDATA),
|
||||
0xFFFFFFFF,
|
||||
disassembler_symb))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (*szBuffer) _stscanf(szBuffer,_T("%8X"),pdwAddress);
|
||||
}
|
||||
// no break
|
||||
case IDCANCEL:
|
||||
EndDialog(hDlg,wParam);
|
||||
|
@ -2814,9 +2837,7 @@ static INT_PTR CALLBACK EnterBreakpoint(HWND hDlg, UINT message, WPARAM wParam,
|
|||
{
|
||||
static BP_T *sBp;
|
||||
|
||||
HWND hWnd;
|
||||
TCHAR szBuffer[8];
|
||||
LONG i;
|
||||
DWORD dwAddr;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
|
@ -2836,19 +2857,9 @@ static INT_PTR CALLBACK EnterBreakpoint(HWND hDlg, UINT message, WPARAM wParam,
|
|||
case IDC_BPREAD: sBp->nType = BP_READ; return TRUE;
|
||||
case IDC_BPWRITE: sBp->nType = BP_WRITE; return TRUE;
|
||||
case IDOK:
|
||||
hWnd = GetDlgItem(hDlg,IDC_ENTERADR);
|
||||
GetWindowText(hWnd,szBuffer,ARRAYSIZEOF(szBuffer));
|
||||
// test if valid hex address
|
||||
for (i = 0; i < (LONG) lstrlen(szBuffer); ++i)
|
||||
{
|
||||
if (_istxdigit(szBuffer[i]) == 0)
|
||||
{
|
||||
SendMessage(hWnd,EM_SETSEL,0,-1);
|
||||
SetFocus(hWnd);
|
||||
if (!GetAddr(hDlg,IDC_ENTERADR,&dwAddr,0xFFFFF,disassembler_symb))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (*szBuffer) _stscanf(szBuffer,_T("%5X"),&sBp->dwAddr);
|
||||
sBp->dwAddr = dwAddr;
|
||||
// no break
|
||||
case IDCANCEL:
|
||||
EndDialog(hDlg,wParam);
|
||||
|
@ -3448,14 +3459,23 @@ static BOOL LoadMemData(LPCTSTR lpszFilename,DWORD dwStartAddr)
|
|||
if (hFile == INVALID_HANDLE_VALUE) // error, couldn't create a new file
|
||||
return FALSE;
|
||||
|
||||
while (TRUE) // read until EOF
|
||||
while (dwStartAddr <= 0xFFFFF) // read until EOF or end of Saturn address space
|
||||
{
|
||||
ReadFile(hFile,&byData,sizeof(byData),&dwRead,NULL);
|
||||
if (dwRead == 0) break; // EOF
|
||||
|
||||
if (dwStartAddr < 0xFFFFF)
|
||||
{
|
||||
Write2(dwStartAddr,byData); // write byte in map mode
|
||||
dwStartAddr += 2;
|
||||
}
|
||||
else // special handling to avoid address wrap around
|
||||
{
|
||||
byData &= 0xF;
|
||||
Nwrite(&byData,dwStartAddr,1); // write nibble in map mode
|
||||
++dwStartAddr;
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(hFile);
|
||||
return TRUE;
|
||||
|
@ -3476,6 +3496,7 @@ static BOOL SaveMemData(LPCTSTR lpszFilename,DWORD dwStartAddr,DWORD dwEndAddr)
|
|||
|
||||
for (dwAddr = dwStartAddr; dwAddr <= dwEndAddr; dwAddr += 2)
|
||||
{
|
||||
_ASSERT(dwAddr <= 0xFFFFF);
|
||||
byData = Read2(dwAddr); // read byte in map mode
|
||||
WriteFile(hFile,&byData,sizeof(byData),&dwWritten,NULL);
|
||||
}
|
||||
|
@ -3484,32 +3505,6 @@ static BOOL SaveMemData(LPCTSTR lpszFilename,DWORD dwStartAddr,DWORD dwEndAddr)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// read edit control and decode content as hex number
|
||||
//
|
||||
static BOOL GetAddr(HWND hDlg, INT nID, DWORD *pdwAddr)
|
||||
{
|
||||
TCHAR szBuffer[8];
|
||||
INT i;
|
||||
|
||||
HWND hWnd = GetDlgItem(hDlg,nID);
|
||||
|
||||
GetWindowText(hWnd,szBuffer,ARRAYSIZEOF(szBuffer));
|
||||
|
||||
// test if valid hex address
|
||||
for (i = 0; i < (LONG) lstrlen(szBuffer); ++i)
|
||||
{
|
||||
if (_istxdigit(szBuffer[i]) == 0)
|
||||
{
|
||||
SendMessage(hWnd,EM_SETSEL,0,-1);
|
||||
SetFocus(hWnd); // focus to edit control
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
_stscanf(szBuffer,_T("%6X"),pdwAddr);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// memory load data
|
||||
//
|
||||
|
@ -3527,13 +3522,18 @@ static INT_PTR CALLBACK DebugMemLoad(HWND hDlg, UINT message, WPARAM wParam, LPA
|
|||
return OnBrowseLoadMem(hDlg);
|
||||
|
||||
case IDOK:
|
||||
dwStartAddr = -1; // no address given
|
||||
|
||||
// get filename
|
||||
GetDlgItemText(hDlg,IDC_DEBUG_DATA_FILE,szFilename,ARRAYSIZEOF(szFilename));
|
||||
|
||||
// decode address field
|
||||
if (!GetAddr(hDlg,IDC_DEBUG_DATA_STARTADDR,&dwStartAddr))
|
||||
if ( !GetAddr(hDlg,IDC_DEBUG_DATA_STARTADDR,&dwStartAddr,0xFFFFF,FALSE)
|
||||
|| dwStartAddr == -1)
|
||||
return FALSE;
|
||||
|
||||
_ASSERT(dwStartAddr <= 0xFFFFF);
|
||||
|
||||
// load memory dump file
|
||||
if (!LoadMemData(szFilename,dwStartAddr))
|
||||
return FALSE;
|
||||
|
@ -3577,15 +3577,22 @@ static INT_PTR CALLBACK DebugMemSave(HWND hDlg, UINT message, WPARAM wParam, LPA
|
|||
return OnBrowseSaveMem(hDlg);
|
||||
|
||||
case IDOK:
|
||||
dwStartAddr = dwEndAddr = -1; // no address given
|
||||
|
||||
// get filename
|
||||
GetDlgItemText(hDlg,IDC_DEBUG_DATA_FILE,szFilename,ARRAYSIZEOF(szFilename));
|
||||
|
||||
// decode address fields
|
||||
if (!GetAddr(hDlg,IDC_DEBUG_DATA_STARTADDR,&dwStartAddr))
|
||||
if ( !GetAddr(hDlg,IDC_DEBUG_DATA_STARTADDR,&dwStartAddr,0xFFFFF,FALSE)
|
||||
|| dwStartAddr == -1)
|
||||
return FALSE;
|
||||
if (!GetAddr(hDlg,IDC_DEBUG_DATA_ENDADDR,&dwEndAddr))
|
||||
if ( !GetAddr(hDlg,IDC_DEBUG_DATA_ENDADDR,&dwEndAddr,0xFFFFF,FALSE)
|
||||
|| dwEndAddr == -1)
|
||||
return FALSE;
|
||||
|
||||
_ASSERT(dwStartAddr <= 0xFFFFF);
|
||||
_ASSERT(dwEndAddr <= 0xFFFFF);
|
||||
|
||||
// save memory dump file
|
||||
if (!SaveMemData(szFilename,dwStartAddr,dwEndAddr))
|
||||
return FALSE;
|
||||
|
|
|
@ -13,9 +13,7 @@
|
|||
#include "kml.h"
|
||||
#include "debugger.h"
|
||||
|
||||
#define VERSION "1.55"
|
||||
|
||||
// #define MONOCHROME // CF_BITMAP clipboard format
|
||||
#define VERSION "1.56"
|
||||
|
||||
#ifdef _DEBUG
|
||||
LPCTSTR szNoTitle = _T("Emu48 ")_T(VERSION)_T(" Debug");
|
||||
|
@ -222,7 +220,7 @@ static VOID SetSoundDeviceList(HWND hWnd,UINT uDeviceID)
|
|||
|
||||
// preset selector
|
||||
uSelectDevice = (UINT) SendMessage(hWnd,CB_ADDSTRING,0,(LPARAM) _T("Standard Audio"));
|
||||
SendMessage(hWnd,CB_SETITEMDATA,uSelectDevice,(UINT) -1);
|
||||
SendMessage(hWnd,CB_SETITEMDATA,uSelectDevice,WAVE_MAPPER);
|
||||
|
||||
uDevNo = waveOutGetNumDevs();
|
||||
for (uDevID = 0; uDevID < uDevNo; ++uDevID)
|
||||
|
@ -374,7 +372,7 @@ static BOOL CALLBACK SettingsGeneralProc(HWND hDlg, UINT uMsg, DWORD wParam, LON
|
|||
SetWindowPos(hWnd,hWndInsertAfter,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);
|
||||
if (hDlgDebug != NULL)
|
||||
{
|
||||
SetWindowPos(hDlgDebug,hWndInsertAfter,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);
|
||||
SetWindowPos(GetLastActivePopup(hDlgDebug),hWndInsertAfter,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -620,10 +618,17 @@ static BOOL CALLBACK SettingsPeripheralProc(HWND hDlg, UINT uMsg, DWORD wParam,
|
|||
uDevId = (UINT) SendDlgItemMessage(hDlg,IDC_SOUND_DEVICE,CB_GETITEMDATA,i,0);
|
||||
if (uWaveDevId != uDevId) // sound device id changed
|
||||
{
|
||||
UINT nActState;
|
||||
|
||||
uWaveDevId = uDevId; // set new sound device id
|
||||
|
||||
nActState = SwitchToState(SM_SLEEP);
|
||||
|
||||
// restart sound engine with new device id
|
||||
SwitchToState(SwitchToState(SM_SLEEP));
|
||||
SoundClose(); // close waveform-audio output device
|
||||
SoundOpen(uWaveDevId); // open waveform-audio output device
|
||||
|
||||
SwitchToState(nActState);
|
||||
}
|
||||
// UDP infrared printer settings
|
||||
GetDlgItemText(hDlg,IDC_IR_ADDR,szUdpServer,ARRAYSIZEOF(szUdpServer));
|
||||
|
@ -913,13 +918,11 @@ cancel:
|
|||
//
|
||||
static LRESULT OnFileNew(VOID)
|
||||
{
|
||||
if (pbyRom)
|
||||
if (bDocumentAvail)
|
||||
{
|
||||
SwitchToState(SM_INVALID);
|
||||
if (IDCANCEL == SaveChanges(bAutoSave))
|
||||
goto cancel;
|
||||
|
||||
SaveBackup();
|
||||
}
|
||||
if (NewDocument()) SetWindowTitle(_T("Untitled"));
|
||||
cancel:
|
||||
|
@ -932,7 +935,7 @@ cancel:
|
|||
//
|
||||
static LRESULT OnFileOpen(VOID)
|
||||
{
|
||||
if (pbyRom)
|
||||
if (bDocumentAvail)
|
||||
{
|
||||
SwitchToState(SM_INVALID);
|
||||
if (IDCANCEL == SaveChanges(bAutoSave))
|
||||
|
@ -941,7 +944,7 @@ static LRESULT OnFileOpen(VOID)
|
|||
if (GetOpenFilename())
|
||||
{
|
||||
if (OpenDocument(szBufferFilename))
|
||||
MruAdd(szCurrentFilename);
|
||||
MruAdd(szBufferFilename);
|
||||
}
|
||||
cancel:
|
||||
if (pbyRom) SwitchToState(SM_RUN);
|
||||
|
@ -959,7 +962,7 @@ static LRESULT OnFileMruOpen(UINT wID)
|
|||
lpszFilename = MruFilename(wID); // full filename from MRU list
|
||||
if (lpszFilename == NULL) return 0; // MRU slot not filled
|
||||
|
||||
if (pbyRom)
|
||||
if (bDocumentAvail)
|
||||
{
|
||||
SwitchToState(SM_INVALID);
|
||||
if (IDCANCEL == SaveChanges(bAutoSave))
|
||||
|
@ -983,10 +986,12 @@ cancel:
|
|||
//
|
||||
static LRESULT OnFileSave(VOID)
|
||||
{
|
||||
if (pbyRom == NULL) return 0;
|
||||
if (bDocumentAvail)
|
||||
{
|
||||
SwitchToState(SM_INVALID);
|
||||
SaveChanges(TRUE);
|
||||
SwitchToState(SM_RUN);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -995,16 +1000,16 @@ static LRESULT OnFileSave(VOID)
|
|||
//
|
||||
static LRESULT OnFileSaveAs(VOID)
|
||||
{
|
||||
if (pbyRom == NULL) return 0;
|
||||
if (bDocumentAvail)
|
||||
{
|
||||
SwitchToState(SM_INVALID);
|
||||
|
||||
if (GetSaveAsFilename())
|
||||
{
|
||||
if (SaveDocumentAs(szBufferFilename))
|
||||
MruAdd(szCurrentFilename);
|
||||
}
|
||||
|
||||
SwitchToState(SM_RUN);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1013,7 +1018,8 @@ static LRESULT OnFileSaveAs(VOID)
|
|||
//
|
||||
static LRESULT OnFileClose(VOID)
|
||||
{
|
||||
if (pbyRom == NULL) return 0;
|
||||
if (bDocumentAvail)
|
||||
{
|
||||
SwitchToState(SM_INVALID);
|
||||
if (SaveChanges(bAutoSave) != IDCANCEL)
|
||||
{
|
||||
|
@ -1024,6 +1030,7 @@ static LRESULT OnFileClose(VOID)
|
|||
{
|
||||
SwitchToState(SM_RUN);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1053,7 +1060,6 @@ static LRESULT OnViewCopy(VOID)
|
|||
{
|
||||
if (EmptyClipboard())
|
||||
{
|
||||
#if !defined MONOCHROME
|
||||
// DIB bitmap
|
||||
#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
|
||||
#define PALVERSION 0x300
|
||||
|
@ -1137,20 +1143,6 @@ static LRESULT OnViewCopy(VOID)
|
|||
DeleteObject(hBmp);
|
||||
#undef WIDTHBYTES
|
||||
#undef PALVERSION
|
||||
#else
|
||||
HBITMAP hOldBmp, hBmp;
|
||||
HDC hBmpDC;
|
||||
|
||||
// don't work with background index <> 0
|
||||
_ASSERT(nLcdZoom == 1 || nLcdZoom == 2 || nLcdZoom == 4);
|
||||
hBmp = CreateBitmap(131*nLcdZoom,64*nLcdZoom,1,1,NULL);
|
||||
hBmpDC = CreateCompatibleDC(NULL);
|
||||
hOldBmp = (HBITMAP)SelectObject(hBmpDC,hBmp);
|
||||
BitBlt(hBmpDC,0,0,131*nLcdZoom,64*nLcdZoom,hLcdDC,Chipset.boffset*nLcdZoom,0,SRCCOPY);
|
||||
SetClipboardData(CF_BITMAP,hBmp);
|
||||
SelectObject(hBmpDC,hOldBmp);
|
||||
DeleteDC(hBmpDC);
|
||||
#endif
|
||||
}
|
||||
CloseClipboard();
|
||||
}
|
||||
|
@ -2021,6 +2013,8 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC
|
|||
hszTopic = DdeCreateStringHandle(idDdeInst,szTopic,0);
|
||||
DdeNameService(idDdeInst,hszService,NULL,DNS_REGISTER);
|
||||
|
||||
SoundOpen(uWaveDevId); // open waveform-audio output device
|
||||
|
||||
_ASSERT(hWnd != NULL);
|
||||
_ASSERT(hWindowDC != NULL);
|
||||
|
||||
|
@ -2075,6 +2069,8 @@ start:
|
|||
DdeFreeStringHandle(idDdeInst, hszTopic);
|
||||
DdeUninitialize(idDdeInst);
|
||||
|
||||
SoundClose(); // close waveform-audio output device
|
||||
|
||||
// get full path name of szCurrentFilename
|
||||
if (GetFullPathName(szCurrentFilename,ARRAYSIZEOF(szBufferFilename),szBufferFilename,&lpFilePart) == 0)
|
||||
szBufferFilename[0] = 0; // no last document name
|
||||
|
|
|
@ -296,7 +296,7 @@ FONT 8, "MS Sans Serif"
|
|||
BEGIN
|
||||
ICON IDI_EMU48,IDC_STATIC,7,6,20,20,SS_REALSIZEIMAGE
|
||||
LTEXT "",IDC_VERSION,29,6,151,8,NOT WS_GROUP
|
||||
LTEXT "Copyright © 2013 Christoph Gießelink && Sébastien Carlier",
|
||||
LTEXT "Copyright © 2014 Christoph Gießelink && Sébastien Carlier",
|
||||
IDC_STATIC,29,18,181,8
|
||||
DEFPUSHBUTTON "OK",IDOK,215,12,39,14
|
||||
EDITTEXT IDC_LICENSE,7,33,247,112,ES_MULTILINE | ES_AUTOHSCROLL |
|
||||
|
@ -687,8 +687,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,5,5,0
|
||||
PRODUCTVERSION 1,5,5,0
|
||||
FILEVERSION 1,5,6,0
|
||||
PRODUCTVERSION 1,5,6,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -705,12 +705,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "Christoph Gießelink & Sebastien Carlier\0"
|
||||
VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0"
|
||||
VALUE "FileVersion", "1, 5, 5, 0\0"
|
||||
VALUE "FileVersion", "1, 5, 6, 0\0"
|
||||
VALUE "InternalName", "Emu48\0"
|
||||
VALUE "LegalCopyright", "Copyright © 2013\0"
|
||||
VALUE "LegalCopyright", "Copyright © 2014\0"
|
||||
VALUE "OriginalFilename", "Emu48.exe\0"
|
||||
VALUE "ProductName", "Emu48\0"
|
||||
VALUE "ProductVersion", "1, 5, 5, 0\0"
|
||||
VALUE "ProductVersion", "1, 5, 6, 0\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -51,7 +51,7 @@ DWORD dwDbgRstkp; // stack recursion level of step over end
|
|||
DWORD dwDbgRstk; // possible return address
|
||||
|
||||
DWORD *pdwInstrArray = NULL; // last instruction array
|
||||
WORD wInstrSize; // size of last instruction array
|
||||
WORD wInstrSize = 256; // size of last instruction array
|
||||
WORD wInstrWp; // write pointer of instruction array
|
||||
WORD wInstrRp; // read pointer of instruction array
|
||||
|
||||
|
@ -566,7 +566,6 @@ loop:
|
|||
SetHP48Time(); // update HP48 time & date
|
||||
// start display counter/update engine
|
||||
StartDisplay((BYTE)(((Chipset.IORam[LINECOUNT+1]<<4)|Chipset.IORam[LINECOUNT])&0x3F));
|
||||
SoundOpen(uWaveDevId); // open waveform-audio output device
|
||||
StartBatMeasure(); // start battery measurement
|
||||
StartTimers();
|
||||
}
|
||||
|
@ -628,7 +627,6 @@ loop:
|
|||
StopDisplay(); // stop display counter/update
|
||||
StopBatMeasure(); // stop battery measurement
|
||||
StopTimers();
|
||||
SoundClose(); // close waveform-audio output device
|
||||
|
||||
while (nNextState == SM_SLEEP) // go into sleep state
|
||||
{
|
||||
|
|
|
@ -11,14 +11,14 @@
|
|||
|
||||
#define F 0xFF // F = function
|
||||
|
||||
typedef struct
|
||||
typedef const struct
|
||||
{
|
||||
const VOID *pLnk;
|
||||
const DWORD dwTyp;
|
||||
} JMPTAB, *PJMPTAB;
|
||||
|
||||
// jump tables
|
||||
static const JMPTAB oF_[] =
|
||||
static JMPTAB oF_[] =
|
||||
{
|
||||
oF0, F,
|
||||
oF1, F,
|
||||
|
@ -38,7 +38,7 @@ static const JMPTAB oF_[] =
|
|||
oFF, F
|
||||
};
|
||||
|
||||
static const JMPTAB oE_[] =
|
||||
static JMPTAB oE_[] =
|
||||
{
|
||||
oE0, F,
|
||||
oE1, F,
|
||||
|
@ -58,7 +58,7 @@ static const JMPTAB oE_[] =
|
|||
oEF, F
|
||||
};
|
||||
|
||||
static const JMPTAB oD_[] =
|
||||
static JMPTAB oD_[] =
|
||||
{
|
||||
oD0, F,
|
||||
oD1, F,
|
||||
|
@ -78,7 +78,7 @@ static const JMPTAB oD_[] =
|
|||
oDF, F
|
||||
};
|
||||
|
||||
static const JMPTAB oC_[] =
|
||||
static JMPTAB oC_[] =
|
||||
{
|
||||
oC0, F,
|
||||
oC1, F,
|
||||
|
@ -98,7 +98,7 @@ static const JMPTAB oC_[] =
|
|||
oCF, F
|
||||
};
|
||||
|
||||
static const JMPTAB oBb_[] =
|
||||
static JMPTAB oBb_[] =
|
||||
{
|
||||
oBb0, F,
|
||||
oBb1, F,
|
||||
|
@ -118,7 +118,7 @@ static const JMPTAB oBb_[] =
|
|||
oBbF, F
|
||||
};
|
||||
|
||||
static const JMPTAB oBa_[] =
|
||||
static JMPTAB oBa_[] =
|
||||
{
|
||||
oBa0, F,
|
||||
oBa1, F,
|
||||
|
@ -138,7 +138,7 @@ static const JMPTAB oBa_[] =
|
|||
oBaF, F
|
||||
};
|
||||
|
||||
static const JMPTAB oB_[] =
|
||||
static JMPTAB oB_[] =
|
||||
{
|
||||
oBa_, 2,
|
||||
oBa_, 2,
|
||||
|
@ -158,7 +158,7 @@ static const JMPTAB oB_[] =
|
|||
oBb_, 2
|
||||
};
|
||||
|
||||
static const JMPTAB oAb_[] =
|
||||
static JMPTAB oAb_[] =
|
||||
{
|
||||
oAb0, F,
|
||||
oAb1, F,
|
||||
|
@ -178,7 +178,7 @@ static const JMPTAB oAb_[] =
|
|||
oAbF, F
|
||||
};
|
||||
|
||||
static const JMPTAB oAa_[] =
|
||||
static JMPTAB oAa_[] =
|
||||
{
|
||||
oAa0, F,
|
||||
oAa1, F,
|
||||
|
@ -198,7 +198,7 @@ static const JMPTAB oAa_[] =
|
|||
oAaF, F
|
||||
};
|
||||
|
||||
static const JMPTAB oA_[] =
|
||||
static JMPTAB oA_[] =
|
||||
{
|
||||
oAa_, 2,
|
||||
oAa_, 2,
|
||||
|
@ -218,7 +218,7 @@ static const JMPTAB oA_[] =
|
|||
oAb_, 2
|
||||
};
|
||||
|
||||
static const JMPTAB o9b_[] =
|
||||
static JMPTAB o9b_[] =
|
||||
{
|
||||
o9b0, F,
|
||||
o9b1, F,
|
||||
|
@ -238,7 +238,7 @@ static const JMPTAB o9b_[] =
|
|||
o9bF, F
|
||||
};
|
||||
|
||||
static const JMPTAB o9a_[] =
|
||||
static JMPTAB o9a_[] =
|
||||
{
|
||||
o9a0, F,
|
||||
o9a1, F,
|
||||
|
@ -258,7 +258,7 @@ static const JMPTAB o9a_[] =
|
|||
o9aF, F
|
||||
};
|
||||
|
||||
static const JMPTAB o9_[] =
|
||||
static JMPTAB o9_[] =
|
||||
{
|
||||
o9a_, 2,
|
||||
o9a_, 2,
|
||||
|
@ -278,7 +278,7 @@ static const JMPTAB o9_[] =
|
|||
o9b_, 2
|
||||
};
|
||||
|
||||
static const JMPTAB o8B_[] =
|
||||
static JMPTAB o8B_[] =
|
||||
{
|
||||
o8B0, F,
|
||||
o8B1, F,
|
||||
|
@ -298,7 +298,7 @@ static const JMPTAB o8B_[] =
|
|||
o8BF, F
|
||||
};
|
||||
|
||||
static const JMPTAB o8A_[] =
|
||||
static JMPTAB o8A_[] =
|
||||
{
|
||||
o8A0, F,
|
||||
o8A1, F,
|
||||
|
@ -318,7 +318,7 @@ static const JMPTAB o8A_[] =
|
|||
o8AF, F
|
||||
};
|
||||
|
||||
static const JMPTAB o81B_[] =
|
||||
static JMPTAB o81B_[] =
|
||||
{
|
||||
o_invalid4, F,
|
||||
o81B1, F, // normally o_invalid4, beep patch
|
||||
|
@ -338,7 +338,7 @@ static const JMPTAB o81B_[] =
|
|||
o_invalid4, F
|
||||
};
|
||||
|
||||
static const JMPTAB o81Af2_[] =
|
||||
static JMPTAB o81Af2_[] =
|
||||
{
|
||||
o81Af20, F,
|
||||
o81Af21, F,
|
||||
|
@ -358,7 +358,7 @@ static const JMPTAB o81Af2_[] =
|
|||
o_invalid6, F
|
||||
};
|
||||
|
||||
static const JMPTAB o81Af1_[] =
|
||||
static JMPTAB o81Af1_[] =
|
||||
{
|
||||
o81Af10, F,
|
||||
o81Af11, F,
|
||||
|
@ -378,7 +378,7 @@ static const JMPTAB o81Af1_[] =
|
|||
o_invalid6, F
|
||||
};
|
||||
|
||||
static const JMPTAB o81Af0_[] =
|
||||
static JMPTAB o81Af0_[] =
|
||||
{
|
||||
o81Af00, F,
|
||||
o81Af01, F,
|
||||
|
@ -398,7 +398,7 @@ static const JMPTAB o81Af0_[] =
|
|||
o_invalid6, F
|
||||
};
|
||||
|
||||
static const JMPTAB o81A_[] =
|
||||
static JMPTAB o81A_[] =
|
||||
{
|
||||
o81Af0_, 5,
|
||||
o81Af1_, 5,
|
||||
|
@ -418,7 +418,7 @@ static const JMPTAB o81A_[] =
|
|||
o_invalid6, F
|
||||
};
|
||||
|
||||
static const JMPTAB o819_[] =
|
||||
static JMPTAB o819_[] =
|
||||
{
|
||||
o819f0, F,
|
||||
o819f1, F,
|
||||
|
@ -438,7 +438,7 @@ static const JMPTAB o819_[] =
|
|||
o_invalid5, F
|
||||
};
|
||||
|
||||
static const JMPTAB o818_[] =
|
||||
static JMPTAB o818_[] =
|
||||
{
|
||||
o818f0x, F,
|
||||
o818f1x, F,
|
||||
|
@ -458,7 +458,7 @@ static const JMPTAB o818_[] =
|
|||
o_invalid6, F
|
||||
};
|
||||
|
||||
static const JMPTAB o81_[] =
|
||||
static JMPTAB o81_[] =
|
||||
{
|
||||
o810, F,
|
||||
o811, F,
|
||||
|
@ -478,7 +478,7 @@ static const JMPTAB o81_[] =
|
|||
o81F, F
|
||||
};
|
||||
|
||||
static const JMPTAB o8081_[] =
|
||||
static JMPTAB o8081_[] =
|
||||
{
|
||||
o80810, F,
|
||||
o_invalid5, F,
|
||||
|
@ -498,7 +498,7 @@ static const JMPTAB o8081_[] =
|
|||
o_invalid5, F
|
||||
};
|
||||
|
||||
static const JMPTAB o808_[] =
|
||||
static JMPTAB o808_[] =
|
||||
{
|
||||
o8080, F,
|
||||
o8081_, 4,
|
||||
|
@ -518,7 +518,7 @@ static const JMPTAB o808_[] =
|
|||
o808F, F
|
||||
};
|
||||
|
||||
static const JMPTAB o80_[] =
|
||||
static JMPTAB o80_[] =
|
||||
{
|
||||
o800, F,
|
||||
o801, F,
|
||||
|
@ -538,7 +538,7 @@ static const JMPTAB o80_[] =
|
|||
o80Fn, F
|
||||
};
|
||||
|
||||
static const JMPTAB o8_[] =
|
||||
static JMPTAB o8_[] =
|
||||
{
|
||||
o80_, 2,
|
||||
o81_, 2,
|
||||
|
@ -558,7 +558,7 @@ static const JMPTAB o8_[] =
|
|||
o8Fd5, F
|
||||
};
|
||||
|
||||
static const JMPTAB o15_[] =
|
||||
static JMPTAB o15_[] =
|
||||
{
|
||||
o150a, F,
|
||||
o151a, F,
|
||||
|
@ -578,7 +578,7 @@ static const JMPTAB o15_[] =
|
|||
o15Fx, F
|
||||
};
|
||||
|
||||
static const JMPTAB o14_[] =
|
||||
static JMPTAB o14_[] =
|
||||
{
|
||||
o140, F,
|
||||
o141, F,
|
||||
|
@ -598,7 +598,7 @@ static const JMPTAB o14_[] =
|
|||
o14F, F
|
||||
};
|
||||
|
||||
static const JMPTAB o13_[] =
|
||||
static JMPTAB o13_[] =
|
||||
{
|
||||
o130, F,
|
||||
o131, F,
|
||||
|
@ -618,7 +618,7 @@ static const JMPTAB o13_[] =
|
|||
o13F, F
|
||||
};
|
||||
|
||||
static const JMPTAB o12_[] =
|
||||
static JMPTAB o12_[] =
|
||||
{
|
||||
o120, F,
|
||||
o121, F,
|
||||
|
@ -638,7 +638,7 @@ static const JMPTAB o12_[] =
|
|||
o_invalid3, F
|
||||
};
|
||||
|
||||
static const JMPTAB o11_[] =
|
||||
static JMPTAB o11_[] =
|
||||
{
|
||||
o110, F,
|
||||
o111, F,
|
||||
|
@ -658,7 +658,7 @@ static const JMPTAB o11_[] =
|
|||
o_invalid3, F
|
||||
};
|
||||
|
||||
static const JMPTAB o10_[] =
|
||||
static JMPTAB o10_[] =
|
||||
{
|
||||
o100, F,
|
||||
o101, F,
|
||||
|
@ -678,7 +678,7 @@ static const JMPTAB o10_[] =
|
|||
o_invalid3, F
|
||||
};
|
||||
|
||||
static const JMPTAB o1_[] =
|
||||
static JMPTAB o1_[] =
|
||||
{
|
||||
o10_, 2,
|
||||
o11_, 2,
|
||||
|
@ -698,7 +698,7 @@ static const JMPTAB o1_[] =
|
|||
o1Fd5, F
|
||||
};
|
||||
|
||||
static const JMPTAB o0E_[] =
|
||||
static JMPTAB o0E_[] =
|
||||
{
|
||||
o0Ef0, F,
|
||||
o0Ef1, F,
|
||||
|
@ -718,7 +718,7 @@ static const JMPTAB o0E_[] =
|
|||
o0EfF, F
|
||||
};
|
||||
|
||||
static const JMPTAB o0_[] =
|
||||
static JMPTAB o0_[] =
|
||||
{
|
||||
o00, F,
|
||||
o01, F,
|
||||
|
@ -738,7 +738,7 @@ static const JMPTAB o0_[] =
|
|||
o0F, F
|
||||
};
|
||||
|
||||
static const JMPTAB o_[] =
|
||||
static JMPTAB o_[] =
|
||||
{
|
||||
o0_, 1,
|
||||
o1_, 1,
|
||||
|
@ -761,15 +761,15 @@ static const JMPTAB o_[] =
|
|||
// opcode dispatcher
|
||||
VOID EvalOpcode(LPBYTE I)
|
||||
{
|
||||
DWORD dwTemp,dwIndex = 0;
|
||||
JMPTAB const *pJmpTab = o_;
|
||||
DWORD dwIndex = 0;
|
||||
PJMPTAB pJmpTab = o_;
|
||||
|
||||
do
|
||||
{
|
||||
dwTemp = I[dwIndex]; // table entry
|
||||
_ASSERT(dwTemp <= 0xf); // found packed data
|
||||
dwIndex = pJmpTab[dwTemp].dwTyp; // next pointer type
|
||||
pJmpTab = (PJMPTAB) pJmpTab[dwTemp].pLnk; // next pointer to table/function
|
||||
_ASSERT(I[dwIndex] <= 0xf); // found packed data
|
||||
pJmpTab = &pJmpTab[I[dwIndex]]; // table entry by opcode
|
||||
dwIndex = pJmpTab->dwTyp; // next pointer type
|
||||
pJmpTab = (PJMPTAB) pJmpTab->pLnk; // next pointer to table/function
|
||||
}
|
||||
while (dwIndex != F); // reference to table? -> again
|
||||
|
||||
|
|
|
@ -312,6 +312,7 @@ BOOL PatchRom(LPCTSTR szFilename)
|
|||
PSZ lpStop,lpBuf = NULL;
|
||||
DWORD dwAddress = 0;
|
||||
UINT nPos = 0;
|
||||
BOOL bSucc = TRUE;
|
||||
|
||||
if (pbyRom == NULL) return FALSE;
|
||||
SetCurrentDirectory(szEmuDirectory);
|
||||
|
@ -319,13 +320,8 @@ BOOL PatchRom(LPCTSTR szFilename)
|
|||
SetCurrentDirectory(szCurrentDirectory);
|
||||
if (hFile == INVALID_HANDLE_VALUE) return FALSE;
|
||||
dwFileSizeLow = GetFileSize(hFile, &dwFileSizeHigh);
|
||||
if (dwFileSizeLow <= 5)
|
||||
{ // file is too small.
|
||||
CloseHandle(hFile);
|
||||
return FALSE;
|
||||
}
|
||||
if (dwFileSizeHigh != 0)
|
||||
{ // file is too large.
|
||||
if (dwFileSizeHigh != 0 || dwFileSizeLow == 0)
|
||||
{ // file is too large or empty
|
||||
CloseHandle(hFile);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -341,14 +337,9 @@ BOOL PatchRom(LPCTSTR szFilename)
|
|||
nPos = 0;
|
||||
while (lpBuf[nPos])
|
||||
{
|
||||
do // remove blank space
|
||||
{
|
||||
if ( (lpBuf[nPos]!=' ')
|
||||
&&(lpBuf[nPos]!='\n')
|
||||
&&(lpBuf[nPos]!='\r')
|
||||
&&(lpBuf[nPos]!='\t')) break;
|
||||
nPos++;
|
||||
} while (lpBuf[nPos]);
|
||||
// skip whitespace characters
|
||||
nPos += (UINT) strspn(&lpBuf[nPos]," \t\n\r");
|
||||
|
||||
if (lpBuf[nPos] == ';') // comment?
|
||||
{
|
||||
do
|
||||
|
@ -363,10 +354,22 @@ BOOL PatchRom(LPCTSTR szFilename)
|
|||
continue;
|
||||
}
|
||||
dwAddress = strtoul(&lpBuf[nPos], &lpStop, 16);
|
||||
nPos += (UINT) (lpStop - &lpBuf[nPos]) + 1;
|
||||
if (*lpStop != ':' || *lpStop == 0)
|
||||
nPos = (UINT) (lpStop - lpBuf); // position of lpStop
|
||||
|
||||
if (*lpStop != 0) // data behind address
|
||||
{
|
||||
if (*lpStop != ':') // invalid syntax
|
||||
{
|
||||
// skip to end of line
|
||||
while (lpBuf[nPos] != '\n' && lpBuf[nPos] != 0)
|
||||
{
|
||||
++nPos;
|
||||
}
|
||||
bSucc = FALSE;
|
||||
continue;
|
||||
while (lpBuf[nPos])
|
||||
}
|
||||
|
||||
while (lpBuf[++nPos])
|
||||
{
|
||||
if (isxdigit(lpBuf[nPos]) == FALSE) break;
|
||||
if (dwAddress < dwRomSize) // patch ROM
|
||||
|
@ -375,11 +378,12 @@ BOOL PatchRom(LPCTSTR szFilename)
|
|||
PatchNibble(dwAddress, Asc2Nib(lpBuf[nPos]));
|
||||
}
|
||||
++dwAddress;
|
||||
++nPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ASSERT(nPos <= dwFileSizeLow); // buffer overflow?
|
||||
free(lpBuf);
|
||||
return TRUE;
|
||||
return bSucc;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -37,12 +37,19 @@
|
|||
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
|
||||
#endif
|
||||
|
||||
#if !defined GWLP_USERDATA
|
||||
#define GWLP_USERDATA GWL_USERDATA
|
||||
#endif
|
||||
|
||||
#if !defined IDC_HAND // Win2k specific definition
|
||||
#define IDC_HAND MAKEINTRESOURCE(32649)
|
||||
#endif
|
||||
|
||||
#if _MSC_VER <= 1200 // missing type definition in the MSVC6.0 SDK and earlier
|
||||
#define SetWindowLongPtr SetWindowLong
|
||||
#define GetWindowLongPtr GetWindowLong
|
||||
typedef SIZE_T DWORD_PTR, *PDWORD_PTR;
|
||||
typedef LONG LONG_PTR, *PLONG_PTR;
|
||||
#endif
|
||||
|
||||
#if _MSC_VER >= 1400 // valid for VS2005 and later
|
||||
|
|
|
@ -175,6 +175,8 @@ VOID ReadSettings(VOID)
|
|||
ReadString(_T("Port2"),_T("Filename"),_T("SHARED.BIN"),szPort2Filename,ARRAYSIZEOF(szPort2Filename));
|
||||
// KML
|
||||
bAlwaysDisplayLog = ReadInt(_T("KML"),_T("AlwaysDisplayLog"),bAlwaysDisplayLog);
|
||||
// Debugger
|
||||
wInstrSize = ReadInt(_T("Debugger"),_T("LastInstrBufSize"),wInstrSize);
|
||||
// Disassembler
|
||||
disassembler_mode = ReadInt(_T("Disassembler"),_T("Mnemonics"),disassembler_mode);
|
||||
disassembler_symb = ReadInt(_T("Disassembler"),_T("Symbolic"),disassembler_symb);
|
||||
|
@ -223,6 +225,8 @@ VOID WriteSettings(VOID)
|
|||
WriteString(_T("Port2"),_T("Filename"),szPort2Filename);
|
||||
// KML
|
||||
WriteInt(_T("KML"),_T("AlwaysDisplayLog"),bAlwaysDisplayLog);
|
||||
// Debugger
|
||||
WriteInt(_T("Debugger"),_T("LastInstrBufSize"),wInstrSize);
|
||||
// Disassembler
|
||||
WriteInt(_T("Disassembler"),_T("Mnemonics"),disassembler_mode);
|
||||
WriteInt(_T("Disassembler"),_T("Symbolic"),disassembler_symb);
|
||||
|
|
|
@ -96,7 +96,8 @@ static VOID DestroyWaveThread(VOID)
|
|||
if (hThreadWave != NULL) // sound message handler thread running
|
||||
{
|
||||
// shut down thread
|
||||
PostThreadMessage(dwThreadWaveId,WM_QUIT,0,0);
|
||||
while (!PostThreadMessage(dwThreadWaveId,WM_QUIT,0,0))
|
||||
Sleep(0);
|
||||
WaitForSingleObject(hThreadWave,INFINITE);
|
||||
CloseHandle(hThreadWave);
|
||||
hThreadWave = NULL;
|
||||
|
@ -345,7 +346,8 @@ BOOL SoundGetDeviceID(UINT *puDeviceID)
|
|||
//
|
||||
BOOL SoundOpen(UINT uDeviceID)
|
||||
{
|
||||
if (hWaveDevice == NULL) // no sound device
|
||||
// check if sound device is already open
|
||||
if (hWaveDevice == NULL && SoundAvailable(uDeviceID))
|
||||
{
|
||||
WAVEFORMATEX wf;
|
||||
BOOL bSucc;
|
||||
|
|
|
@ -27,6 +27,31 @@ BOOL bDetectClpObject = TRUE; // try to detect clipboard object
|
|||
//#
|
||||
//################
|
||||
|
||||
static LPTSTR Trim(LPCTSTR cp)
|
||||
{
|
||||
LPCTSTR pcWs = _T(" \t\n\r"); // valid whitespace characters
|
||||
|
||||
LPTSTR pc;
|
||||
DWORD dwFirst,dwLast;
|
||||
|
||||
dwLast = lstrlen(cp); // last position in string (EOS)
|
||||
|
||||
// trim leading and tailing whitespace characters
|
||||
dwFirst = (DWORD) _tcsspn(cp,pcWs); // position of 1st non whitespace character
|
||||
|
||||
// search for position behind last non whitespace character
|
||||
while (dwLast > dwFirst && _tcschr(pcWs,cp[dwLast-1]) != NULL)
|
||||
--dwLast;
|
||||
|
||||
dwLast = 1 + dwLast - dwFirst; // calculate buffer length
|
||||
|
||||
if ((pc = (LPTSTR) malloc(dwLast * sizeof(*pc))) != NULL)
|
||||
{
|
||||
lstrcpyn(pc,&cp[dwFirst],dwLast); // copy relevant data + EOS
|
||||
}
|
||||
return pc;
|
||||
}
|
||||
|
||||
static INT RPL_GetZInt(BYTE CONST *pbyNum,INT nIntLen,LPTSTR cp,INT nSize)
|
||||
{
|
||||
INT i = 0; // character counter
|
||||
|
@ -60,7 +85,7 @@ static INT RPL_GetZInt(BYTE CONST *pbyNum,INT nIntLen,LPTSTR cp,INT nSize)
|
|||
return i;
|
||||
}
|
||||
|
||||
static INT RPL_SetZInt(LPCTSTR cp,LPBYTE pbyNum,INT nSize)
|
||||
static __inline INT SetZInt(LPCTSTR cp,LPBYTE pbyNum,INT nSize)
|
||||
{
|
||||
BYTE bySign;
|
||||
INT nStrLen,nNumSize;
|
||||
|
@ -109,6 +134,20 @@ static INT RPL_SetZInt(LPCTSTR cp,LPBYTE pbyNum,INT nSize)
|
|||
return nNumSize;
|
||||
}
|
||||
|
||||
static INT RPL_SetZInt(LPCTSTR cp,LPBYTE pbyNum,INT nSize)
|
||||
{
|
||||
LPTSTR pszData;
|
||||
|
||||
INT s = 0;
|
||||
|
||||
if ((pszData = Trim(cp)) != NULL) // create a trimmed working copy of the string
|
||||
{
|
||||
s = SetZInt(pszData,pbyNum,nSize);
|
||||
free(pszData);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static INT RPL_GetBcd(BYTE CONST *pbyNum,INT nMantLen,INT nExpLen,CONST TCHAR cDec,LPTSTR cp,INT nSize)
|
||||
{
|
||||
BYTE byNib;
|
||||
|
@ -198,7 +237,7 @@ static INT RPL_GetBcd(BYTE CONST *pbyNum,INT nMantLen,INT nExpLen,CONST TCHAR cD
|
|||
return i;
|
||||
}
|
||||
|
||||
static INT RPL_SetBcd(LPCTSTR cp,INT nMantLen,INT nExpLen,CONST TCHAR cDec,LPBYTE pbyNum,INT nSize)
|
||||
static __inline INT SetBcd(LPCTSTR cp,INT nMantLen,INT nExpLen,CONST TCHAR cDec,LPBYTE pbyNum,INT nSize)
|
||||
{
|
||||
TCHAR cVc[] = _T(".0123456789eE+-");
|
||||
|
||||
|
@ -318,6 +357,20 @@ static INT RPL_SetBcd(LPCTSTR cp,INT nMantLen,INT nExpLen,CONST TCHAR cDec,LPBYT
|
|||
return nMantLen + nExpLen + 1;
|
||||
}
|
||||
|
||||
static INT RPL_SetBcd(LPCTSTR cp,INT nMantLen,INT nExpLen,CONST TCHAR cDec,LPBYTE pbyNum,INT nSize)
|
||||
{
|
||||
LPTSTR pszData;
|
||||
|
||||
INT s = 0;
|
||||
|
||||
if ((pszData = Trim(cp)) != NULL) // create a trimmed working copy of the string
|
||||
{
|
||||
s = SetBcd(pszData,nMantLen,nExpLen,cDec,pbyNum,nSize);
|
||||
free(pszData);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static INT RPL_GetComplex(BYTE CONST *pbyNum,INT nMantLen,INT nExpLen,CONST TCHAR cDec,LPTSTR cp,INT nSize)
|
||||
{
|
||||
INT nLen,nPos;
|
||||
|
@ -371,8 +424,7 @@ static INT RPL_SetComplex(LPCTSTR cp,INT nMantLen,INT nExpLen,CONST TCHAR cDec,L
|
|||
? _T(',') // radix mark '.' -> ',' separator
|
||||
: _T(';'); // radix mark ',' -> ';' separator
|
||||
|
||||
// create a working copy of the string
|
||||
if ((pszData = DuplicateString(cp)) != NULL)
|
||||
if ((pszData = Trim(cp)) != NULL) // create a trimmed working copy of the string
|
||||
{
|
||||
INT nStrLength = lstrlen(pszData); // string length
|
||||
|
||||
|
@ -415,35 +467,6 @@ static INT RPL_SetComplex(LPCTSTR cp,INT nMantLen,INT nExpLen,CONST TCHAR cDec,L
|
|||
//#
|
||||
//################
|
||||
|
||||
#if 0
|
||||
static INT IsRealNumber(LPCTSTR cp,INT nMantLen,INT nExpLen,CONST TCHAR cDec,LPBYTE pbyNum,INT nSize)
|
||||
{
|
||||
LPTSTR lpszNumber;
|
||||
INT nLength = 0;
|
||||
|
||||
if ((lpszNumber = DuplicateString(cp)) != NULL)
|
||||
{
|
||||
LPTSTR p = lpszNumber;
|
||||
INT i;
|
||||
|
||||
// cut heading whitespaces
|
||||
for (; *p == _T(' ') || *p == _T('\t'); ++p) { }
|
||||
|
||||
// cut tailing whitespaces
|
||||
for (i = lstrlen(p); --i >= 0;)
|
||||
{
|
||||
if (p[i] != _T(' ') && p[i] != _T('\t'))
|
||||
break;
|
||||
}
|
||||
p[++i] = 0; // new EOS
|
||||
|
||||
nLength = RPL_SetBcd(p,nMantLen,nExpLen,cDec,pbyNum,nSize);
|
||||
HeapFree(hHeap,0,lpszNumber);
|
||||
}
|
||||
return nLength;
|
||||
}
|
||||
#endif
|
||||
|
||||
static TCHAR GetRadix(VOID)
|
||||
{
|
||||
// get locale decimal point
|
||||
|
|
|
@ -13,9 +13,6 @@
|
|||
|
||||
#define AUTO_OFF 10 // Time in minutes for 'auto off'
|
||||
|
||||
// Ticks for 01.01.1970 00:00:00
|
||||
#define UNIX_0_TIME ((ULONGLONG) 0x0001cf2e8f800000)
|
||||
|
||||
// Ticks for 'auto off'
|
||||
#define OFF_TIME ((ULONGLONG) (AUTO_OFF * 60) << 13)
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ BOOL SendByteUdp(BYTE byData)
|
|||
#if defined _UNICODE
|
||||
DWORD dwLength = lstrlen(szUdpServer) + 1;
|
||||
|
||||
if ((lpszIpAddr = (LPSTR) malloc(dwLength)) == NULL)
|
||||
if ((lpszIpAddr = (LPSTR) _alloca(dwLength)) == NULL)
|
||||
return TRUE; // server not found
|
||||
|
||||
WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK,
|
||||
|
@ -55,17 +55,11 @@ BOOL SendByteUdp(BYTE byData)
|
|||
PHOSTENT host = gethostbyname(lpszIpAddr);
|
||||
if (host == NULL)
|
||||
{
|
||||
#if defined _UNICODE
|
||||
free(lpszIpAddr);
|
||||
#endif
|
||||
return TRUE; // server not found
|
||||
}
|
||||
|
||||
ip_addr.s_addr = ((PIN_ADDR) host->h_addr_list[0])->s_addr;
|
||||
}
|
||||
#if defined _UNICODE
|
||||
free(lpszIpAddr);
|
||||
#endif
|
||||
}
|
||||
|
||||
// create UDP socket
|
||||
|
|
|
@ -296,7 +296,7 @@ FONT 8, "MS Sans Serif"
|
|||
BEGIN
|
||||
ICON IDI_EMU48,IDC_STATIC,7,6,20,20,SS_REALSIZEIMAGE
|
||||
LTEXT "",IDC_VERSION,29,6,151,8,NOT WS_GROUP
|
||||
LTEXT "Copyright © 2013 Christoph Gießelink && Sébastien Carlier",
|
||||
LTEXT "Copyright © 2014 Christoph Gießelink && Sébastien Carlier",
|
||||
IDC_STATIC,29,18,181,8
|
||||
DEFPUSHBUTTON "OK",IDOK,215,12,39,14
|
||||
EDITTEXT IDC_LICENSE,7,33,247,112,ES_MULTILINE | ES_AUTOHSCROLL |
|
||||
|
@ -715,8 +715,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,5,5,0
|
||||
PRODUCTVERSION 1,5,5,0
|
||||
FILEVERSION 1,5,6,0
|
||||
PRODUCTVERSION 1,5,6,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -733,12 +733,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "Christoph Gießelink & Sebastien Carlier\0"
|
||||
VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0"
|
||||
VALUE "FileVersion", "1, 5, 5, 0\0"
|
||||
VALUE "FileVersion", "1, 5, 6, 0\0"
|
||||
VALUE "InternalName", "Emu48\0"
|
||||
VALUE "LegalCopyright", "Copyright © 2013\0"
|
||||
VALUE "LegalCopyright", "Copyright © 2014\0"
|
||||
VALUE "OriginalFilename", "Emu48.exe\0"
|
||||
VALUE "ProductName", "Emu48\0"
|
||||
VALUE "ProductVersion", "1, 5, 5, 0\0"
|
||||
VALUE "ProductVersion", "1, 5, 6, 0\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -45,10 +45,10 @@ cleanobj:
|
|||
cleanexe:
|
||||
-rm -f $(TARGET)
|
||||
|
||||
cursor.o: cursor.c pch.h emu48.h
|
||||
cursor.o: cursor.c pch.h emu48.h types.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o cursor.o cursor.c
|
||||
|
||||
ddeserv.o: ddeserv.c pch.h emu48.h types.h
|
||||
ddeserv.o: ddeserv.c pch.h emu48.h types.h io.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o ddeserv.o ddeserv.c
|
||||
|
||||
debugger.o: debugger.c pch.h resource.h emu48.h \
|
||||
|
@ -65,7 +65,7 @@ display.o: display.c pch.h resource.h emu48.h \
|
|||
types.h io.h kml.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o display.o display.c
|
||||
|
||||
disrpl.o: disrpl.c pch.h Emu48.h disrpl.h
|
||||
disrpl.o: disrpl.c pch.h Emu48.h types.h disrpl.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o disrpl.o disrpl.c
|
||||
|
||||
emu48.o: emu48.c pch.h resource.h emu48.h types.h \
|
||||
|
@ -73,16 +73,16 @@ emu48.o: emu48.c pch.h resource.h emu48.h types.h \
|
|||
$(CC) $(CFLAGS) $(DEFINES) -c -o emu48.o emu48.c
|
||||
|
||||
engine.o: engine.c pch.h emu48.h types.h opcodes.h \
|
||||
io.h debugger.h ops.h
|
||||
io.h debugger.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o engine.o engine.c
|
||||
|
||||
external.o: external.c pch.h emu48.h types.h
|
||||
external.o: external.c pch.h emu48.h types.h ops.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o external.o external.c
|
||||
|
||||
fetch.o: fetch.c pch.h opcodes.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o fetch.o fetch.c
|
||||
|
||||
files.o: files.c pch.h emu48.h types.h io.h \
|
||||
files.o: files.c pch.h emu48.h types.h ops.h io.h \
|
||||
kml.h i28f160.h debugger.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o files.o files.c
|
||||
|
||||
|
@ -92,33 +92,33 @@ i28f160.o: i28f160.c pch.h emu48.h types.h i28f160.h
|
|||
keyboard.o: keyboard.c pch.h emu48.h types.h io.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o keyboard.o keyboard.c
|
||||
|
||||
keymacro.o: keymacro.c pch.h resource.h Emu48.h kml.h
|
||||
keymacro.o: keymacro.c pch.h resource.h Emu48.h types.h kml.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o keymacro.o keymacro.c
|
||||
|
||||
kml.o: kml.c pch.h resource.h emu48.h types.h kml.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o kml.o kml.c
|
||||
|
||||
lowbat.o: lowbat.c pch.h Emu48.h io.h
|
||||
lowbat.o: lowbat.c pch.h emu48.h types.h io.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o lowbat.o lowbat.c
|
||||
|
||||
mops.o: mops.c pch.h emu48.h types.h opcodes.h io.h \
|
||||
mops.o: mops.c pch.h emu48.h types.h ops.h opcodes.h io.h \
|
||||
i28f160.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o mops.o mops.c
|
||||
|
||||
mru.o: mru.c pch.h resource.h emu48.h
|
||||
mru.o: mru.c pch.h resource.h emu48.h types.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o mru.o mru.c
|
||||
|
||||
opcodes.o: opcodes.c pch.h emu48.h types.h opcodes.h \
|
||||
io.h ops.h
|
||||
io.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o opcodes.o opcodes.c
|
||||
|
||||
# pch.o: pch.c pch.h
|
||||
# $(CC) $(CFLAGS) $(DEFINES) -c -o pch.o pch.c
|
||||
|
||||
redeye.o: redeye.c pch.h emu48.h io.h
|
||||
redeye.o: redeye.c pch.h emu48.h types.h io.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o redeye.o redeye.c
|
||||
|
||||
rpl.o: rpl.c pch.h emu48.h types.h io.h
|
||||
rpl.o: rpl.c pch.h emu48.h types.h ops.h io.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o rpl.o rpl.c
|
||||
|
||||
serial.o: serial.c pch.h emu48.h types.h io.h
|
||||
|
@ -127,19 +127,19 @@ serial.o: serial.c pch.h emu48.h types.h io.h
|
|||
settings.o: settings.c pch.h emu48.h types.h i28f160.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o settings.o settings.c
|
||||
|
||||
sound.o: sound.c pch.h emu48.h
|
||||
sound.o: sound.c pch.h emu48.h types.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o sound.o sound.c
|
||||
|
||||
stack.o: stack.c pch.h resource.h emu48.h io.h
|
||||
stack.o: stack.c pch.h resource.h emu48.h types.h io.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o stack.o stack.c
|
||||
|
||||
symbfile.o: symbfile.c pch.h emu48.h
|
||||
symbfile.o: symbfile.c pch.h emu48.h types.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o symbfile.o symbfile.c
|
||||
|
||||
timer.o: timer.c pch.h emu48.h types.h io.h
|
||||
timer.o: timer.c pch.h emu48.h types.h ops.h io.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o timer.o timer.c
|
||||
|
||||
udp.o: udp.c pch.h io.h
|
||||
udp.o: udp.c pch.h emu48.h types.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o udp.o udp.c
|
||||
|
||||
$(RSRCOBJ): $(RSRC) resource.h emu48.ico dbgtool.bmp checkbox.bmp Emu48.xml
|
||||
|
|
|
@ -18,14 +18,6 @@
|
|||
#include <conio.h>
|
||||
// #include <crtdbg.h> // missing file
|
||||
|
||||
#if !defined VERIFY
|
||||
#if defined _DEBUG
|
||||
#define VERIFY(f) _ASSERT(f)
|
||||
#else // _DEBUG
|
||||
#define VERIFY(f) ((VOID)(f))
|
||||
#endif // _DEBUG
|
||||
#endif // _VERIFY
|
||||
|
||||
#if !defined IDC_HAND // Win2k specific definition
|
||||
#define IDC_HAND MAKEINTRESOURCE(32649)
|
||||
#endif
|
||||
|
@ -38,12 +30,16 @@
|
|||
#define __min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
// normally defined in CONIO.H
|
||||
int __cdecl _inp(unsigned short);
|
||||
int __cdecl _outp(unsigned short, int);
|
||||
|
||||
// normally defined in missing CRTDBG.H
|
||||
#if !defined _ASSERT
|
||||
#define _ASSERT(a)
|
||||
#endif
|
||||
#define _CrtDumpMemoryLeaks() ((int)0)
|
||||
#define _CrtDumpMemoryLeaks()
|
||||
|
||||
#if !defined VERIFY
|
||||
#if defined _DEBUG
|
||||
#define VERIFY(f) _ASSERT(f)
|
||||
#else // _DEBUG
|
||||
#define VERIFY(f) ((VOID)(f))
|
||||
#endif // _DEBUG
|
||||
#endif // VERIFY
|
||||
|
|
|
@ -48,4 +48,4 @@ Many thanks to Pedro A. Arranda Guti
|
|||
compatible.
|
||||
|
||||
|
||||
04/30/13 (c) by Christoph Gießelink
|
||||
04/29/14 (c) by Christoph Gießelink
|
||||
|
|
BIN
uninst.exe
BIN
uninst.exe
Binary file not shown.
Loading…
Reference in a new issue