2009-08-29: Updated to version 1.49

Signed-off-by: Gwenhael Le Moine <gwenhael.le.moine@gmail.com>
This commit is contained in:
Gwenhael Le Moine 2024-03-19 23:35:29 +01:00
parent 38b8f389cf
commit 88250edbe4
No known key found for this signature in database
GPG key ID: FDFE3669426707A7
14 changed files with 246 additions and 51 deletions

BIN
EMU48.EXE

Binary file not shown.

View file

@ -1,4 +1,4 @@
Known bugs and restrictions of Emu48 V1.48 Known bugs and restrictions of Emu48 V1.49
------------------------------------------ ------------------------------------------
- the following I/O bits aren't emulated (incomplete) - the following I/O bits aren't emulated (incomplete)
@ -53,4 +53,4 @@ Known bugs and restrictions of Emu48 V1.48
- quitting the emulator while programming the flash isn't allowed, - quitting the emulator while programming the flash isn't allowed,
because the content of flash state machine isn't saved so far because the content of flash state machine isn't saved so far
07/14/09 (c) by Christoph Gießelink, c dot giesselink at gmx dot de 08/18/09 (c) by Christoph Gießelink, c dot giesselink at gmx dot de

View file

@ -1,3 +1,41 @@
Service Pack 49 for Emu48 Version 1.0
DISRPL.C
- bugfix in function BCDx(), detection for exponent writing was
wrong -> on negative exponents sometimes the result format was
wrong, on positive exponents sometimes the result itself was wrong
EMU48.C
- changed function OnFileMruOpen(), on success move selected entry
to top of MRU table
EMU48.DSP
- changed to REGISTRY (HKCU/Software/Emu48) saving
EMU48.H
- extern declaration of global variable and function
EMU48.RC
- changed version
MRU.C
- changed function MruAdd(), added entry moving to top when the
entry is already in the table
- added function MruMoveTop(), move MRU entry to top of table
STACK.C
- bugfix in function RPL_GetBcd(), detection for exponent writing
was wrong -> on negative exponents sometimes the result format was
wrong, on positive exponents from E12 until E14 with 12 digit
mantissa setting the result itself was wrong
- added helper functions RPL_GetComplex() and RPL_SetComplex() to
handle complex number objects
- added function DoComplex() to handle a complex number object
- changed function OnStackCopy(), added complex number support
- changed function OnStackPaste(), added flag to disable automatic
clipboard object detection and added complex number support
Service Pack 48 for Emu48 Version 1.0 Service Pack 48 for Emu48 Version 1.0
DDESERV.C DDESERV.C

View file

@ -163,7 +163,7 @@ static BOOL BCDx(BYTE CONST *pbyNum,INT nMantLen,INT nExpLen,String *str)
} }
// TRUE at x.E // TRUE at x.E
bExpflag = v + lExp > 14 || v + lExp < -nMantLen; bExpflag = v + lExp >= nMantLen || lExp < -nMantLen;
bPflag = !bExpflag && v < -lExp; // decimal point flag at neg. exponent bPflag = !bExpflag && v < -lExp; // decimal point flag at neg. exponent
} }

View file

@ -13,7 +13,7 @@
#include "kml.h" #include "kml.h"
#include "debugger.h" #include "debugger.h"
#define VERSION "1.48" #define VERSION "1.49"
// #define MONOCHROME // CF_BITMAP clipboard format // #define MONOCHROME // CF_BITMAP clipboard format
@ -881,6 +881,10 @@ static LRESULT OnFileMruOpen(UINT wID)
{ {
MruRemove(wID); // entry not valid any more MruRemove(wID); // entry not valid any more
} }
else
{
MruMoveTop(wID); // move entry to top of MRU list
}
cancel: cancel:
if (pbyRom) SwitchToState(SM_RUN); if (pbyRom) SwitchToState(SM_RUN);
return 0; return 0;

View file

@ -45,7 +45,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /Gr /MT /W3 /GX /O2 /Ob2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "STRICT" /Yu"pch.h" /FD /c # ADD CPP /nologo /Gr /MT /W3 /GX /O2 /Ob2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "STRICT" /D "REGISTRY" /Yu"pch.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32 # ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x40c /d "NDEBUG" # ADD BASE RSC /l 0x40c /d "NDEBUG"
@ -71,7 +71,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "STRICT" /FR /Yu"pch.h" /FD /c # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "STRICT" /D "REGISTRY" /FR /Yu"pch.h" /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /win32 # ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x40c /d "_DEBUG" # ADD BASE RSC /l 0x40c /d "_DEBUG"
@ -98,7 +98,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /Gr /MT /W3 /GX /O2 /Ob2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "STRICT" /Yu"pch.h" /FD /c # ADD BASE CPP /nologo /Gr /MT /W3 /GX /O2 /Ob2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "STRICT" /Yu"pch.h" /FD /c
# ADD CPP /nologo /Gr /MT /W3 /GX /O2 /Ob2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "STRICT" /D "_UNICODE" /D "UNICODE" /Yu"pch.h" /FD /c # ADD CPP /nologo /Gr /MT /W3 /GX /O2 /Ob2 /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "STRICT" /D "REGISTRY" /Yu"pch.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x40c /d "NDEBUG" # ADD BASE RSC /l 0x40c /d "NDEBUG"
@ -125,7 +125,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "STRICT" /FR /Yu"pch.h" /FD /c # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "STRICT" /FR /Yu"pch.h" /FD /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "STRICT" /D "_UNICODE" /D "UNICODE" /FR /Yu"pch.h" /FD /c # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "STRICT" /D "REGISTRY" /FR /Yu"pch.h" /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x40c /d "_DEBUG" # ADD BASE RSC /l 0x40c /d "_DEBUG"

View file

@ -121,6 +121,7 @@ extern BOOL MruInit(INT nNum);
extern VOID MruCleanup(VOID); extern VOID MruCleanup(VOID);
extern VOID MruAdd(LPCTSTR lpszEntry); extern VOID MruAdd(LPCTSTR lpszEntry);
extern VOID MruRemove(INT nIndex); extern VOID MruRemove(INT nIndex);
extern VOID MruMoveTop(INT nIndex);
extern INT MruEntries(VOID); extern INT MruEntries(VOID);
extern LPCTSTR MruFilename(INT nIndex); extern LPCTSTR MruFilename(INT nIndex);
extern VOID MruUpdateMenu(VOID); extern VOID MruUpdateMenu(VOID);
@ -312,6 +313,7 @@ extern LRESULT OnToolMacroStop(VOID);
extern LRESULT OnToolMacroSettings(VOID); extern LRESULT OnToolMacroSettings(VOID);
// Stack.c // Stack.c
extern BOOL bDetectClpObject;
extern LRESULT OnStackCopy(VOID); extern LRESULT OnStackCopy(VOID);
extern LRESULT OnStackPaste(VOID); extern LRESULT OnStackPaste(VOID);

View file

@ -602,8 +602,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,4,8,0 FILEVERSION 1,4,9,0
PRODUCTVERSION 1,4,8,0 PRODUCTVERSION 1,4,9,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -620,12 +620,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "Christoph Gießelink & Sebastien Carlier\0" VALUE "CompanyName", "Christoph Gießelink & Sebastien Carlier\0"
VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0" VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0"
VALUE "FileVersion", "1, 4, 8, 0\0" VALUE "FileVersion", "1, 4, 9, 0\0"
VALUE "InternalName", "Emu48\0" VALUE "InternalName", "Emu48\0"
VALUE "LegalCopyright", "Copyright © 2009\0" VALUE "LegalCopyright", "Copyright © 2009\0"
VALUE "OriginalFilename", "Emu48.exe\0" VALUE "OriginalFilename", "Emu48.exe\0"
VALUE "ProductName", "Emu48\0" VALUE "ProductName", "Emu48\0"
VALUE "ProductVersion", "1, 4, 8, 0\0" VALUE "ProductVersion", "1, 4, 9, 0\0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View file

@ -133,7 +133,7 @@ VOID MruAdd(LPCTSTR lpszEntry)
if ( ppszFiles[i] != NULL if ( ppszFiles[i] != NULL
&& lstrcmpi(ppszFiles[i],szFilename) == 0) && lstrcmpi(ppszFiles[i],szFilename) == 0)
{ {
MruUpdateMenu(); // update menu MruMoveTop(i); // move to top and update menu
return; return;
} }
} }
@ -158,7 +158,7 @@ VOID MruRemove(INT nIndex)
{ {
HeapFree(hHeap,0,ppszFiles[nIndex]); // free entry HeapFree(hHeap,0,ppszFiles[nIndex]); // free entry
for (; nIndex < nEntry - 1; ++nIndex) // move old entries 1 line up for (; nIndex < nEntry - 1; ++nIndex) // move below entries 1 line up
{ {
ppszFiles[nIndex] = ppszFiles[nIndex+1]; ppszFiles[nIndex] = ppszFiles[nIndex+1];
} }
@ -169,6 +169,21 @@ VOID MruRemove(INT nIndex)
return; return;
} }
VOID MruMoveTop(INT nIndex)
{
LPTSTR lpszEntry = ppszFiles[nIndex]; // remember selected entry
for (; nIndex > 0; --nIndex) // move above entries 1 line down
{
ppszFiles[nIndex] = ppszFiles[nIndex-1];
}
ppszFiles[0] = lpszEntry; // insert entry on top
MruUpdateMenu(); // update menu
return;
}
INT MruEntries(VOID) INT MruEntries(VOID)
{ {
return nEntry; return nEntry;

View file

@ -16,8 +16,11 @@
#define DOINT 0x02614 // Precision Integer (HP49G) #define DOINT 0x02614 // Precision Integer (HP49G)
#define DOREAL 0x02933 // Real #define DOREAL 0x02933 // Real
#define DOCMP 0x02977 // Complex
#define DOCSTR 0x02A2C // String #define DOCSTR 0x02A2C // String
BOOL bDetectClpObject = TRUE; // try to detect clipboard object
//################ //################
//# //#
//# Low level subroutines //# Low level subroutines
@ -143,7 +146,7 @@ static INT RPL_GetBcd(BYTE CONST *pbyNum,INT nMantLen,INT nExpLen,CONST TCHAR cD
} }
// TRUE at x.E // TRUE at x.E
bExpflag = v + lExp > 14 || v + lExp < -nMantLen; bExpflag = v + lExp >= nMantLen || lExp < -nMantLen;
bPflag = !bExpflag && v < -lExp; // decimal point flag at neg. exponent bPflag = !bExpflag && v < -lExp; // decimal point flag at neg. exponent
} }
@ -314,6 +317,97 @@ static INT RPL_SetBcd(LPCTSTR cp,INT nMantLen,INT nExpLen,CONST TCHAR cDec,LPBYT
return nMantLen + nExpLen + 1; return nMantLen + nExpLen + 1;
} }
static INT RPL_GetComplex(BYTE CONST *pbyNum,INT nMantLen,INT nExpLen,CONST TCHAR cDec,LPTSTR cp,INT nSize)
{
INT nLen,nPos;
TCHAR cSep;
cSep = (cDec == _T('.')) // current separator
? _T(',') // radix mark '.' -> ',' separator
: _T(';'); // radix mark ',' -> ';' separator
nPos = 0; // write buffer position
if (nSize < 5) return 0; // target buffer to small
nSize -= 4; // reserved room for (,)\0
cp[nPos++] = _T('('); // start of complex number
// real part
nLen = RPL_GetBcd(pbyNum,12,3,cDec,&cp[1],nSize);
if (nLen == 0) return 0; // target buffer to small
_ASSERT(nLen <= nSize);
nPos += nLen; // actual buffer postion
nSize -= nLen; // remainder target buffer size
cp[nPos++] = cSep; // write of complex number seperator
// imaginary part
nLen = RPL_GetBcd(&pbyNum[16],12,3,cDec,&cp[nPos],nSize);
if (nLen == 0) return 0; // target buffer to small
nPos += nLen; // actual buffer postion
cp[nPos++] = _T(')'); // end of complex number
cp[nPos] = 0; // EOS
_ASSERT(lstrlen(cp) == nPos);
return nPos;
}
static INT RPL_SetComplex(LPCTSTR cp,INT nMantLen,INT nExpLen,CONST TCHAR cDec,LPBYTE pbyNum,INT nSize)
{
LPTSTR pcSep,pszData;
INT nLen;
TCHAR cSep;
nLen = 0; // read data length
cSep = (cDec == _T('.')) // current separator
? _T(',') // radix mark '.' -> ',' separator
: _T(';'); // radix mark ',' -> ';' separator
// create a working copy of the string
if ((pszData = DuplicateString(cp)) != NULL)
{
INT nStrLength = lstrlen(pszData); // string length
// complex number with brackets around
if ( nStrLength > 0
&& pszData[0] == _T('(')
&& pszData[nStrLength - 1] == _T(')'))
{
pszData[--nStrLength] = 0; // replace ')' with EOS
// search for number separator
if ((pcSep = _tcschr(pszData+1,cSep)) != NULL)
{
INT nLen1st;
*pcSep = 0; // set EOS for 1st substring
// decode 1st substring
nLen1st = RPL_SetBcd(pszData+1,nMantLen,nExpLen,cDec,&pbyNum[0],nSize);
if (nLen1st > 0)
{
// decode 2nd substring
nLen = RPL_SetBcd(pcSep+1,nMantLen,nExpLen,cDec,&pbyNum[nMantLen+nExpLen+1],nSize-nLen1st);
if (nLen > 0)
{
nLen += nLen1st; // complete Bcd length
}
}
}
}
HeapFree(hHeap,0,pszData);
}
return nLen;
}
//################ //################
//# //#
//# Object subroutines //# Object subroutines
@ -385,6 +479,15 @@ static INT DoReal(DWORD dwAddress,LPTSTR cp,INT nSize)
return RPL_GetBcd(byNumber,12,3,GetRadix(),cp,nSize); return RPL_GetBcd(byNumber,12,3,GetRadix(),cp,nSize);
} }
static INT DoComplex(DWORD dwAddress,LPTSTR cp,INT nSize)
{
BYTE byNumber[32];
// get complex object content and decode it
Npeek(byNumber,dwAddress,ARRAYSIZEOF(byNumber));
return RPL_GetComplex(byNumber,12,3,GetRadix(),cp,nSize);
}
//################ //################
//# //#
@ -422,6 +525,7 @@ LRESULT OnStackCopy(VOID) // copy data from stack
{ {
case DOINT: // Precision Integer (HP49G) case DOINT: // Precision Integer (HP49G)
case DOREAL: // real object case DOREAL: // real object
case DOCMP: // complex object
dwAddress += 5; // object content dwAddress += 5; // object content
switch (dwObject) switch (dwObject)
@ -434,6 +538,10 @@ LRESULT OnStackCopy(VOID) // copy data from stack
// get real object content and decode it // get real object content and decode it
dwSize = DoReal(dwAddress,cBuffer,ARRAYSIZEOF(cBuffer)); dwSize = DoReal(dwAddress,cBuffer,ARRAYSIZEOF(cBuffer));
break; break;
case DOCMP: // complex object
// get complex object content and decode it
dwSize = DoComplex(dwAddress,cBuffer,ARRAYSIZEOF(cBuffer));
break;
} }
// calculate buffer size // calculate buffer size
@ -557,6 +665,8 @@ LRESULT OnStackPaste(VOID) // paste data to stack
INT s; INT s;
do do
{
if (bDetectClpObject) // autodetect clipboard object enabled
{ {
// HP49G in exact mode // HP49G in exact mode
if (cCurrentRomType == 'X' && !RPL_GetSystemFlag(fnApprox)) if (cCurrentRomType == 'X' && !RPL_GetSystemFlag(fnApprox))
@ -582,10 +692,13 @@ LRESULT OnStackPaste(VOID) // paste data to stack
} }
// try to convert string to real format // try to convert string to real format
_ASSERT(16 <= ARRAYSIZEOF(byNumber));
s = RPL_SetBcd(lpstrClipdata,12,3,GetRadix(),byNumber,sizeof(byNumber)); s = RPL_SetBcd(lpstrClipdata,12,3,GetRadix(),byNumber,sizeof(byNumber));
if (s > 0) // is a real number if (s > 0) // is a real number
{ {
_ASSERT(s == 16); // length of real number BCD coded
// get TEMPOB memory for real object // get TEMPOB memory for real object
dwAddress = RPL_CreateTemp(16+5); dwAddress = RPL_CreateTemp(16+5);
if ((bSuccess = (dwAddress > 0))) if ((bSuccess = (dwAddress > 0)))
@ -599,6 +712,28 @@ LRESULT OnStackPaste(VOID) // paste data to stack
break; break;
} }
// try to convert string to complex format
_ASSERT(32 <= ARRAYSIZEOF(byNumber));
s = RPL_SetComplex(lpstrClipdata,12,3,GetRadix(),byNumber,sizeof(byNumber));
if (s > 0) // is a real complex
{
_ASSERT(s == 32); // length of complex number BCD coded
// get TEMPOB memory for complex object
dwAddress = RPL_CreateTemp(16+16+5);
if ((bSuccess = (dwAddress > 0)))
{
Write5(dwAddress,DOCMP); // prolog
Nwrite(byNumber,dwAddress+5,s); // data
// push object to stack
RPL_Push(1,dwAddress);
}
break;
}
}
// any other format // any other format
{ {
DWORD dwSize = lstrlen(lpstrClipdata); DWORD dwSize = lstrlen(lpstrClipdata);

View file

@ -630,8 +630,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,4,8,0 FILEVERSION 1,4,9,0
PRODUCTVERSION 1,4,8,0 PRODUCTVERSION 1,4,9,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -648,12 +648,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "Sebastien Carlier & Christoph Gießelink\0" VALUE "CompanyName", "Sebastien Carlier & Christoph Gießelink\0"
VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0" VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0"
VALUE "FileVersion", "1, 4, 8, 0\0" VALUE "FileVersion", "1, 4, 9, 0\0"
VALUE "InternalName", "Emu48\0" VALUE "InternalName", "Emu48\0"
VALUE "LegalCopyright", "Copyright © 2009\0" VALUE "LegalCopyright", "Copyright © 2009\0"
VALUE "OriginalFilename", "Emu48.exe\0" VALUE "OriginalFilename", "Emu48.exe\0"
VALUE "ProductName", "Emu48\0" VALUE "ProductName", "Emu48\0"
VALUE "ProductVersion", "1, 4, 8, 0\0" VALUE "ProductVersion", "1, 4, 9, 0\0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View file

@ -8,7 +8,8 @@ LD=gcc
CFLAGS= -Wall -Wno-missing-braces -Wno-format -Wno-uninitialized \ CFLAGS= -Wall -Wno-missing-braces -Wno-format -Wno-uninitialized \
-Wno-strict-aliasing -Wno-unused-function -O3 -Wno-strict-aliasing -Wno-unused-function -O3
DEFINES= -DIDC_STATIC=-1 DEFINES= -DIDC_STATIC=-1 \
-DREGISTRY
LDFLAGS= -s -mwindows LDFLAGS= -s -mwindows

View file

@ -34,4 +34,4 @@ Many thanks to Pedro A. Arranda Guti
compatible. compatible.
06/14/09 (c) by Christoph Gießelink 08/17/09 (c) by Christoph Gießelink

Binary file not shown.