2005-12-17: Updated to version 1.40
Signed-off-by: Gwenhael Le Moine <gwenhael.le.moine@gmail.com>
This commit is contained in:
parent
0c2f128039
commit
2cc9402f4d
25 changed files with 1382 additions and 407 deletions
Binary file not shown.
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
BIN
EMU48.EXE
BIN
EMU48.EXE
Binary file not shown.
|
@ -1,4 +1,4 @@
|
|||
Known bugs and restrictions of Emu48 V1.38
|
||||
Known bugs and restrictions of Emu48 V1.40
|
||||
------------------------------------------
|
||||
|
||||
- the following I/O bits aren't emulated (incomplete)
|
||||
|
@ -42,8 +42,7 @@ Known bugs and restrictions of Emu48 V1.38
|
|||
- no MP interrupt on card control circuit or timer restart
|
||||
- no beeper support with OUT command -> all programs that aren't
|
||||
use the "=makebeep" subroutine, like alarm wake up, have no sound
|
||||
- beeper emulation, ATTN key doesn't work,
|
||||
Windows 9x: plays only default sound event or standard system beep
|
||||
- beeper emulation, ATTN key doesn't work
|
||||
- no infrared printer support
|
||||
- Shell OS: clock isn't synchronized with real time
|
||||
- HP49G: the flash memory is emulated now with some restrictions
|
||||
|
@ -55,4 +54,4 @@ Known bugs and restrictions of Emu48 V1.38
|
|||
- quitting the emulator while programming the flash isn't allowed,
|
||||
because the content of flash state machine isn't saved so far
|
||||
|
||||
08/30/05 (c) by Christoph Gießelink, c dot giesselink at gmx dot de
|
||||
12/13/05 (c) by Christoph Gießelink, c dot giesselink at gmx dot de
|
||||
|
|
|
@ -1,3 +1,133 @@
|
|||
Service Pack 40 for Emu48 Version 1.0
|
||||
|
||||
DISPLAY.C
|
||||
- bugfix in function UpdateContrast(), used background Color 0 in
|
||||
calculator off state even if Color 32 was defined
|
||||
- bugfix in function CreateLcdBitmap(), DIB section shouldn't
|
||||
created from the memory DC
|
||||
|
||||
EMU48.C
|
||||
- added function IsPort2Writeable() to check if read only file
|
||||
attribute is not set on port2 file
|
||||
- major changes in function SettingsProc(), added "Port 2 is
|
||||
Writeable" handling and make port2 changeable without closing the
|
||||
current emulation session
|
||||
- changed function SaveChanges(), default button for confirming the
|
||||
"Do you want to save changes ?" message depends now on the
|
||||
"SaveDefaultConfirm" INI-File setting (1=yes / 0=no button)
|
||||
|
||||
EMU48.H
|
||||
- extern declaration of global variable and functions
|
||||
|
||||
EMU48.RC
|
||||
- added item "Port 2 is Writeable" in settings dialog
|
||||
- changed version
|
||||
|
||||
ENGINE.C
|
||||
- bugfix in function WorkerThread(), when changing into SM_RUN state
|
||||
display constrast must also be restored
|
||||
|
||||
FILES.C
|
||||
- changed function CrcPort2(), made it global accessible
|
||||
|
||||
KML.C
|
||||
- added keywords "Topbar" and "Vga" to pLexToken[] table -> scripts
|
||||
using these keywords now are parsed with warnings and not quit
|
||||
with a fatal error any more
|
||||
- bugfix in function SkipWhite(), skipping remark text hadn't stop
|
||||
at string end
|
||||
- bugfix in function ParseBlocks(), stopped script parsing without
|
||||
error at unknown block token
|
||||
- bugfix in function SkipLines(), TOK_END was handeled wrong ->
|
||||
this caused a RunKey end if condition of TOK_IFPRESSED or
|
||||
TOK_IFFLAG was false and there was no TOK_ELSE inside this level
|
||||
- bugfix in function KillKML(), ROM type wasn't reset to the preset
|
||||
value at the end
|
||||
|
||||
KML.H
|
||||
- added TOK_TOPBAR and TOK_VGA definition
|
||||
|
||||
RESOURCE.H
|
||||
- added definition
|
||||
|
||||
RPL.C
|
||||
- added function RPL_GetSystemFlag() returning the state of the
|
||||
given system flag
|
||||
|
||||
SETTINGS.C
|
||||
- changed function ReadSettings() and WriteSettings(), added item
|
||||
"SaveDefaultConfirm" in section [File] in the INI-File
|
||||
|
||||
STACK.C
|
||||
- added helper functions RPL_GetZInt() and RPL_SetZInt() to handle
|
||||
HP49G Precision Integer objects
|
||||
- added function DoInt() to handle a HP49G Precision Integer object
|
||||
- changed function OnStackCopy() and OnStackPaste(), added HP49G
|
||||
Precision Integer support (limited to 127/128 digits incl. sign)
|
||||
|
||||
TIMER.C
|
||||
- changed function CheckT1() and CheckT2(), minor optimization in
|
||||
checking if INT or WAKE bit is set
|
||||
|
||||
|
||||
Service Pack 39 for Emu48 Version 1.0
|
||||
|
||||
DISPLAY.C
|
||||
- bugfix in function CreateMainBitmap(), in error case hMainDC
|
||||
variable wasn't cleared
|
||||
|
||||
EMU48.C
|
||||
- changed function SettingsProc(), added sound handling
|
||||
- moved function OnStackCopy() and OnStackPaste() to STACK.C
|
||||
- changed function WinMain(), added accelerator key access for menus
|
||||
|
||||
EMU48.DSP
|
||||
- added stack.c sources
|
||||
|
||||
EMU48.H
|
||||
- extern declaration of global variables and functions
|
||||
|
||||
EMU48.RC
|
||||
- added "Sound" group in Settings dialog
|
||||
- changed menu text "Copy String" to "Copy Stack" and menu text
|
||||
"Paste String" to "Paste Stack"
|
||||
- added accelerator resource
|
||||
- changed version
|
||||
|
||||
EXTERNAL.C
|
||||
- added function BeepWave(), beeper function using sound card
|
||||
- added function BeepWin9x(), PC speaker function for working on
|
||||
Win9x
|
||||
- changed function External(), removed range checking of duration;
|
||||
call function BeepWin9x() on Win9x instead of Beep() or in the
|
||||
case of wave sound the function BeepWave()
|
||||
|
||||
KML.C
|
||||
- bugfix in function InitKML(), changed log message for no "Model"
|
||||
definition found and a missing "Bitmap" definition wasn't detected
|
||||
|
||||
PCH.H
|
||||
- added include conio.h
|
||||
|
||||
RESOURCE.H
|
||||
- added several definitions
|
||||
|
||||
SETTINGS.C
|
||||
- changed function ReadSettings() and WriteSettings(), added item
|
||||
"WaveBeep" and "WaveVolume" in section [Emulator] in the INI-File
|
||||
|
||||
STACK.C
|
||||
- new modul with the message handler functions OnStackCopy() and
|
||||
OnStackPaste() prior located in EMU48.C
|
||||
- changed function OnStackCopy() and OnStackPaste(), they can now
|
||||
also copy real numbers from and to the clipboard
|
||||
|
||||
TIMER.C
|
||||
- bugfix in function SetT1(), fixed unsynchronized access to timer1
|
||||
value, stop timer1 only if running and restart timer1 only when
|
||||
timer2 is running
|
||||
|
||||
|
||||
Service Pack 38 for Emu48 Version 1.0
|
||||
|
||||
DISPLAY.C
|
||||
|
|
|
@ -124,15 +124,20 @@ static __inline VOID BuildPattern(VOID)
|
|||
|
||||
VOID UpdateContrast(BYTE byContrast)
|
||||
{
|
||||
RGBQUAD c,b;
|
||||
INT i,nColors;
|
||||
|
||||
// table for max. 8 colors
|
||||
const INT nCAdj[] = { 0, 1, 1, 2, 1, 2, 2, 3 };
|
||||
|
||||
RGBQUAD c = *(RGBQUAD*)&dwKMLColor[byContrast]; // pixel on color
|
||||
RGBQUAD b = *(RGBQUAD*)&dwKMLColor[byContrast+32]; // pixel off color
|
||||
if ((Chipset.IORam[BITOFFSET] & DON) == 0 || I == *(DWORD*)&b)
|
||||
b = *(RGBQUAD*)&dwKMLColor[0];
|
||||
// when display is off use contrast 0
|
||||
if ((Chipset.IORam[BITOFFSET] & DON) == 0) byContrast = 0;
|
||||
|
||||
c = *(RGBQUAD*)&dwKMLColor[byContrast]; // pixel on color
|
||||
b = *(RGBQUAD*)&dwKMLColor[byContrast+32]; // pixel off color
|
||||
|
||||
// if background color is undefined, use color 0 for compatibility
|
||||
if (I == *(DWORD*)&b) b = *(RGBQUAD*)&dwKMLColor[0];
|
||||
|
||||
nColors = bGrayscale ? (NOCOLORSGRAY-1) : (NOCOLORSBW-1);
|
||||
|
||||
|
@ -189,7 +194,7 @@ VOID CreateLcdBitmap(VOID)
|
|||
bmiLcd.Lcd_bmih.biHeight = -64 * nLcdZoom;
|
||||
_ASSERT(hLcdDC == NULL);
|
||||
VERIFY(hLcdDC = CreateCompatibleDC(hWindowDC));
|
||||
VERIFY(hLcdBitmap = CreateDIBSection(hLcdDC,(BITMAPINFO*)&bmiLcd,DIB_RGB_COLORS,(VOID **)&pbyLcd,NULL,0));
|
||||
VERIFY(hLcdBitmap = CreateDIBSection(hWindowDC,(BITMAPINFO*)&bmiLcd,DIB_RGB_COLORS,(VOID **)&pbyLcd,NULL,0));
|
||||
hLcdBitmap = SelectObject(hLcdDC,hLcdBitmap);
|
||||
_ASSERT(hPalette != NULL);
|
||||
SelectPalette(hLcdDC,hPalette,FALSE); // set palette for LCD DC
|
||||
|
@ -230,6 +235,7 @@ BOOL CreateMainBitmap(LPCTSTR szFilename)
|
|||
if (hMainBitmap == NULL)
|
||||
{
|
||||
DeleteDC(hMainDC);
|
||||
hMainDC = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
hMainBitmap = SelectObject(hMainDC,hMainBitmap);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "kml.h"
|
||||
#include "debugger.h"
|
||||
|
||||
#define VERSION "1.38"
|
||||
#define VERSION "1.40"
|
||||
#define CF_HPOBJ "CF_HPOBJ" // clipboard format for DDE
|
||||
|
||||
#define MAXPORTS 256 // number of COM ports
|
||||
|
@ -80,6 +80,7 @@ HCURSOR hCursorHand = NULL;
|
|||
BOOL bClassicCursor = FALSE; // use hand instead of arrow cursor
|
||||
BOOL bAutoSave = FALSE;
|
||||
BOOL bAutoSaveOnExit = TRUE;
|
||||
BOOL bSaveDefConfirm = TRUE; // yes
|
||||
BOOL bAlwaysDisplayLog = TRUE;
|
||||
BOOL bLoadObjectWarning = TRUE;
|
||||
|
||||
|
@ -221,6 +222,21 @@ VOID CopyItemsToClipboard(HWND hWnd) // save selected Listbox Items to Clipboar
|
|||
//#
|
||||
//################
|
||||
|
||||
// get R/W state of port2 file
|
||||
static BOOL IsPort2Writeable(VOID)
|
||||
{
|
||||
DWORD dwFileAtt;
|
||||
|
||||
BOOL bWriteable = FALSE;
|
||||
|
||||
SetCurrentDirectory(szEmuDirectory);
|
||||
dwFileAtt = GetFileAttributes(szPort2Filename);
|
||||
if (dwFileAtt != 0xFFFFFFFF)
|
||||
bWriteable = ((dwFileAtt & FILE_ATTRIBUTE_READONLY) == 0);
|
||||
SetCurrentDirectory(szCurrentDirectory);
|
||||
return bWriteable;
|
||||
}
|
||||
|
||||
// set listfield for serial combobox
|
||||
static VOID SetCommList(HWND hDlg,int nIDDlgItem,LPCTSTR szSetting)
|
||||
{
|
||||
|
@ -257,6 +273,9 @@ static VOID SetCommList(HWND hDlg,int nIDDlgItem,LPCTSTR szSetting)
|
|||
|
||||
static BOOL CALLBACK SettingsProc(HWND hDlg, UINT message, DWORD wParam, LONG lParam)
|
||||
{
|
||||
BOOL bPort2CfgChange = FALSE;
|
||||
BOOL bPort2AttChange = FALSE;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
|
@ -271,6 +290,15 @@ static BOOL CALLBACK SettingsProc(HWND hDlg, UINT message, DWORD wParam, LONG lP
|
|||
// set disassebler mode
|
||||
CheckDlgButton(hDlg,(disassembler_mode == HP_MNEMONICS) ? IDC_DISASM_HP : IDC_DISASM_CLASS,BST_CHECKED);
|
||||
|
||||
// set sound slider
|
||||
SendDlgItemMessage(hDlg,IDC_SOUND_SLIDER,TBM_SETRANGE,FALSE,MAKELONG(0,255));
|
||||
SendDlgItemMessage(hDlg,IDC_SOUND_SLIDER,TBM_SETTICFREQ,256/8,0);
|
||||
SendDlgItemMessage(hDlg,IDC_SOUND_SLIDER,TBM_SETPOS,TRUE,dwWaveVol);
|
||||
|
||||
// set sound radio button
|
||||
CheckDlgButton(hDlg,bWaveBeep ? IDC_SOUND_WAVE : IDC_SOUND_SPEAKER,BST_CHECKED);
|
||||
EnableWindow(GetDlgItem(hDlg,IDC_SOUND_SLIDER),bWaveBeep);
|
||||
|
||||
// set combobox parameter
|
||||
SetCommList(hDlg,IDC_WIRE,szSerialWire);
|
||||
SetCommList(hDlg,IDC_IR,szSerialIr);
|
||||
|
@ -281,13 +309,14 @@ static BOOL CALLBACK SettingsProc(HWND hDlg, UINT message, DWORD wParam, LONG lP
|
|||
}
|
||||
|
||||
// HP48SX/GX
|
||||
if (cCurrentRomType=='S' || cCurrentRomType=='G')
|
||||
if (cCurrentRomType=='S' || cCurrentRomType=='G' || cCurrentRomType==0)
|
||||
{
|
||||
// init port1 enable checkbox
|
||||
CheckDlgButton(hDlg,IDC_PORT1EN,(Chipset.cards_status & PORT1_PRESENT) != 0);
|
||||
CheckDlgButton(hDlg,IDC_PORT1WR,(Chipset.cards_status & PORT1_WRITE) != 0);
|
||||
// init port2 shared checkbox and set port2 filename
|
||||
// init port2 shared and writeable checkbox and set port2 filename
|
||||
CheckDlgButton(hDlg,IDC_PORT2ISSHARED,bPort2IsShared);
|
||||
CheckDlgButton(hDlg,IDC_PORT2WR,IsPort2Writeable());
|
||||
SetDlgItemText(hDlg,IDC_PORT2,szPort2Filename);
|
||||
if (nState == SM_INVALID) // Invalid State
|
||||
{
|
||||
|
@ -299,29 +328,26 @@ static BOOL CALLBACK SettingsProc(HWND hDlg, UINT message, DWORD wParam, LONG lP
|
|||
{
|
||||
EnableWindow(GetDlgItem(hDlg,IDC_PORT1EN),FALSE);
|
||||
EnableWindow(GetDlgItem(hDlg,IDC_PORT1WR),FALSE);
|
||||
if (nState == SM_INVALID) // Invalid State
|
||||
{
|
||||
// init port2 shared checkbox and set port2 filename
|
||||
CheckDlgButton(hDlg,IDC_PORT2ISSHARED,bPort2IsShared);
|
||||
SetDlgItemText(hDlg,IDC_PORT2,szPort2Filename);
|
||||
}
|
||||
EnableWindow(GetDlgItem(hDlg,IDC_PORT2ISSHARED),FALSE);
|
||||
EnableWindow(GetDlgItem(hDlg,IDC_PORT2WR),FALSE);
|
||||
EnableWindow(GetDlgItem(hDlg,IDC_PORT2),FALSE);
|
||||
EnableWindow(GetDlgItem(hDlg,IDC_PORT2LOAD),FALSE);
|
||||
if (cCurrentRomType=='X') // HP49G
|
||||
{
|
||||
SendDlgItemMessage(hDlg,IDC_IR,CB_RESETCONTENT,0,0);
|
||||
EnableWindow(GetDlgItem(hDlg,IDC_IR),FALSE);
|
||||
}
|
||||
}
|
||||
if (nState != SM_INVALID) // not in Invalid State
|
||||
{
|
||||
// hide port2 settings
|
||||
EnableWindow(GetDlgItem(hDlg,IDC_PORT2ISSHARED),FALSE);
|
||||
EnableWindow(GetDlgItem(hDlg,IDC_PORT2),FALSE);
|
||||
EnableWindow(GetDlgItem(hDlg,IDC_PORT2LOAD),FALSE);
|
||||
}
|
||||
return TRUE;
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_SOUND_SPEAKER:
|
||||
EnableWindow(GetDlgItem(hDlg,IDC_SOUND_SLIDER),FALSE);
|
||||
return TRUE;
|
||||
case IDC_SOUND_WAVE:
|
||||
EnableWindow(GetDlgItem(hDlg,IDC_SOUND_SLIDER),TRUE);
|
||||
return TRUE;
|
||||
case IDC_PORT2LOAD:
|
||||
if (GetLoadObjectFilename())
|
||||
{
|
||||
|
@ -366,9 +392,37 @@ static BOOL CALLBACK SettingsProc(HWND hDlg, UINT message, DWORD wParam, LONG lP
|
|||
Chipset.SoftInt = TRUE; // set interrupt
|
||||
bInterrupt = TRUE;
|
||||
}
|
||||
Map(0x00,0xFF);
|
||||
SwitchToState(nOldState);
|
||||
}
|
||||
// HP48SX/GX port2 change settings detection
|
||||
if(cCurrentRomType=='S' || cCurrentRomType=='G' || cCurrentRomType==0)
|
||||
{
|
||||
TCHAR szFilename[MAX_PATH];
|
||||
BOOL bPortShared;
|
||||
|
||||
// shared port
|
||||
bPortShared = IsDlgButtonChecked(hDlg,IDC_PORT2ISSHARED);
|
||||
if (bPort2IsShared != bPortShared)
|
||||
{
|
||||
bPort2IsShared = bPortShared;
|
||||
bPort2CfgChange = TRUE; // slot2 configuration changed
|
||||
}
|
||||
|
||||
// get current filename and notify difference
|
||||
GetDlgItemText(hDlg,IDC_PORT2,szFilename,ARRAYSIZEOF(szFilename));
|
||||
if (lstrcmp(szPort2Filename,szFilename) != 0)
|
||||
{
|
||||
lstrcpyn(szPort2Filename,szFilename,ARRAYSIZEOF(szPort2Filename));
|
||||
bPort2CfgChange = TRUE; // slot2 configuration changed
|
||||
}
|
||||
|
||||
// R/W port
|
||||
if (IsDlgButtonChecked(hDlg,IDC_PORT2WR) != (UINT) IsPort2Writeable())
|
||||
{
|
||||
bPort2AttChange = TRUE; // slot2 file R/W attribute changed
|
||||
bPort2CfgChange = TRUE; // slot2 configuration changed
|
||||
}
|
||||
}
|
||||
// get speed checkbox value
|
||||
bRealSpeed = IsDlgButtonChecked(hDlg,IDC_REALSPEED);
|
||||
bAutoSave = IsDlgButtonChecked(hDlg, IDC_AUTOSAVE);
|
||||
|
@ -383,13 +437,54 @@ static BOOL CALLBACK SettingsProc(HWND hDlg, UINT message, DWORD wParam, LONG lP
|
|||
SetLcdMode(!bGrayscale); // set new display mode
|
||||
SwitchToState(nOldState);
|
||||
}
|
||||
if (nState == SM_INVALID)
|
||||
if (bPort2CfgChange) // slot2 configuration changed
|
||||
{
|
||||
bPort2IsShared = IsDlgButtonChecked(hDlg,IDC_PORT2ISSHARED);
|
||||
GetDlgItemText(hDlg,IDC_PORT2,szPort2Filename,ARRAYSIZEOF(szPort2Filename));
|
||||
UINT nOldState = SwitchToState(SM_INVALID);
|
||||
|
||||
UnmapPort2(); // unmap port2
|
||||
|
||||
if (bPort2AttChange) // slot2 R/W mode changed
|
||||
{
|
||||
DWORD dwFileAtt;
|
||||
|
||||
SetCurrentDirectory(szEmuDirectory);
|
||||
dwFileAtt = GetFileAttributes(szPort2Filename);
|
||||
if (dwFileAtt != 0xFFFFFFFF)
|
||||
{
|
||||
if (IsDlgButtonChecked(hDlg,IDC_PORT2WR))
|
||||
dwFileAtt &= ~FILE_ATTRIBUTE_READONLY;
|
||||
else
|
||||
dwFileAtt |= FILE_ATTRIBUTE_READONLY;
|
||||
|
||||
SetFileAttributes(szPort2Filename,dwFileAtt);
|
||||
}
|
||||
// set disassebler mode
|
||||
SetCurrentDirectory(szCurrentDirectory);
|
||||
}
|
||||
|
||||
if (cCurrentRomType) // ROM defined
|
||||
{
|
||||
// use 2nd command line argument if defined
|
||||
MapPort2((nArgc < 3) ? szPort2Filename : ppArgv[2]);
|
||||
// port2 changed and card detection enabled
|
||||
if ( (bPort2AttChange || Chipset.wPort2Crc != CrcPort2())
|
||||
&& (Chipset.IORam[CARDCTL] & ECDT) != 0 && (Chipset.IORam[TIMER2_CTRL] & RUN) != 0
|
||||
)
|
||||
{
|
||||
Chipset.HST |= MP; // set Module Pulled
|
||||
IOBit(SRQ2,NINT,FALSE); // set NINT to low
|
||||
Chipset.SoftInt = TRUE; // set interrupt
|
||||
bInterrupt = TRUE;
|
||||
}
|
||||
// save fingerprint of port2
|
||||
Chipset.wPort2Crc = CrcPort2();
|
||||
}
|
||||
SwitchToState(nOldState);
|
||||
}
|
||||
// set disassembler mode
|
||||
disassembler_mode = IsDlgButtonChecked(hDlg,IDC_DISASM_HP) ? HP_MNEMONICS : CLASS_MNEMONICS;
|
||||
// set sound data
|
||||
dwWaveVol = SendDlgItemMessage(hDlg,IDC_SOUND_SLIDER,TBM_GETPOS,0,0);
|
||||
bWaveBeep = IsDlgButtonChecked(hDlg,IDC_SOUND_WAVE);
|
||||
// set combobox parameter
|
||||
GetDlgItemText(hDlg,IDC_WIRE,szSerialWire,ARRAYSIZEOF(szSerialWire));
|
||||
if (cCurrentRomType!='X') // HP49G Ir port is not connected
|
||||
|
@ -427,7 +522,11 @@ static UINT SaveChanges(BOOL bAuto)
|
|||
if (bAuto)
|
||||
uReply = IDYES;
|
||||
else
|
||||
uReply = YesNoCancelMessage(_T("Do you want to save changes ?"));
|
||||
{
|
||||
UINT uStyle = bSaveDefConfirm ? 0 : MB_DEFBUTTON2;
|
||||
|
||||
uReply = YesNoCancelMessage(_T("Do you want to save changes ?"),uStyle);
|
||||
}
|
||||
|
||||
if (uReply != IDYES) return uReply;
|
||||
|
||||
|
@ -739,148 +838,6 @@ static LRESULT OnFileExit(VOID)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// ID_STACK_COPY
|
||||
//
|
||||
static LRESULT OnStackCopy(VOID) // copy data from stack
|
||||
{
|
||||
HANDLE hClipObj;
|
||||
LPBYTE lpData;
|
||||
DWORD dwAddress,dwSize;
|
||||
|
||||
_ASSERT(nState == SM_RUN); // emulator must be in RUN state
|
||||
if (WaitForSleepState()) // wait for cpu SHUTDN then sleep state
|
||||
{
|
||||
InfoMessage(_T("The emulator is busy."));
|
||||
return 0;
|
||||
}
|
||||
|
||||
_ASSERT(nState == SM_SLEEP);
|
||||
|
||||
if ((dwAddress = RPL_Pick(1)) == 0) // pick address of level1 object
|
||||
{
|
||||
MessageBeep(MB_OK); // error beep
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (Read5(dwAddress) != 0x02A2C) // string object
|
||||
{
|
||||
MessageBeep(MB_OK); // error beep
|
||||
goto error;
|
||||
}
|
||||
|
||||
dwAddress += 5; // address of string length
|
||||
dwSize = (Read5(dwAddress) - 5) / 2; // length of string
|
||||
|
||||
// memory allocation for clipboard data
|
||||
if ((hClipObj = GlobalAlloc(GMEM_MOVEABLE,dwSize + 1)) == NULL)
|
||||
goto error;
|
||||
|
||||
if ((lpData = GlobalLock(hClipObj))) // lock memory
|
||||
{
|
||||
// copy data into clipboard buffer
|
||||
for (dwAddress += 5;dwSize-- > 0;dwAddress += 2,++lpData)
|
||||
*lpData = Read2(dwAddress);
|
||||
*lpData = 0; // set end of string
|
||||
|
||||
GlobalUnlock(hClipObj); // unlock memory
|
||||
|
||||
if (OpenClipboard(hWnd))
|
||||
{
|
||||
if (EmptyClipboard())
|
||||
SetClipboardData(CF_TEXT,hClipObj);
|
||||
else
|
||||
GlobalFree(hClipObj);
|
||||
CloseClipboard();
|
||||
}
|
||||
}
|
||||
else // lock memory failed
|
||||
{
|
||||
GlobalFree(hClipObj);
|
||||
}
|
||||
|
||||
error:
|
||||
SwitchToState(SM_RUN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// ID_STACK_PASTE
|
||||
//
|
||||
static LRESULT OnStackPaste(VOID) // paste data to stack
|
||||
{
|
||||
HANDLE hClipObj;
|
||||
LPBYTE lpClipdata,lpData;
|
||||
|
||||
BOOL bSuccess = FALSE;
|
||||
|
||||
// check if clipboard format is available
|
||||
if (!IsClipboardFormatAvailable(CF_TEXT))
|
||||
{
|
||||
MessageBeep(MB_OK); // error beep
|
||||
return 0;
|
||||
}
|
||||
|
||||
SuspendDebugger(); // suspend debugger
|
||||
bDbgAutoStateCtrl = FALSE; // disable automatic debugger state control
|
||||
|
||||
// calculator off, turn on
|
||||
if (!(Chipset.IORam[BITOFFSET]&DON))
|
||||
{
|
||||
KeyboardEvent(TRUE,0,0x8000);
|
||||
KeyboardEvent(FALSE,0,0x8000);
|
||||
|
||||
// wait for sleep mode
|
||||
while(Chipset.Shutdn == FALSE) Sleep(0);
|
||||
}
|
||||
|
||||
_ASSERT(nState == SM_RUN); // emulator must be in RUN state
|
||||
if (WaitForSleepState()) // wait for cpu SHUTDN then sleep state
|
||||
{
|
||||
InfoMessage(_T("The emulator is busy."));
|
||||
goto cancel;
|
||||
}
|
||||
|
||||
_ASSERT(nState == SM_SLEEP);
|
||||
|
||||
if (OpenClipboard(hWnd))
|
||||
{
|
||||
if ((hClipObj = GetClipboardData(CF_TEXT)))
|
||||
{
|
||||
if ((lpClipdata = GlobalLock(hClipObj)))
|
||||
{
|
||||
DWORD dwSize = strlen(lpClipdata);
|
||||
if ((lpData = HeapAlloc(hHeap,0,dwSize * 2)))
|
||||
{
|
||||
memcpy(lpData+dwSize,lpClipdata,dwSize); // copy data
|
||||
bSuccess = (WriteStack(lpData,dwSize) == S_ERR_NO);
|
||||
HeapFree(hHeap,0,lpData);
|
||||
}
|
||||
GlobalUnlock(hClipObj);
|
||||
}
|
||||
}
|
||||
CloseClipboard();
|
||||
}
|
||||
|
||||
SwitchToState(SM_RUN); // run state
|
||||
while (nState!=nNextState) Sleep(0);
|
||||
_ASSERT(nState == SM_RUN);
|
||||
|
||||
if (bSuccess == FALSE) // data not copied
|
||||
goto cancel;
|
||||
|
||||
KeyboardEvent(TRUE,0,0x8000);
|
||||
KeyboardEvent(FALSE,0,0x8000);
|
||||
|
||||
// wait for sleep mode
|
||||
while(Chipset.Shutdn == FALSE) Sleep(0);
|
||||
|
||||
cancel:
|
||||
bDbgAutoStateCtrl = TRUE; // enable automatic debugger state control
|
||||
ResumeDebugger();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// ID_VIEW_COPY
|
||||
//
|
||||
|
@ -1127,7 +1084,7 @@ static LRESULT OnObjectLoad(VOID)
|
|||
_T("Warning: Trying to load an object while the emulator is busy\n")
|
||||
_T("will certainly result in a memory lost. Before loading an object\n")
|
||||
_T("you should be sure that the calculator is not doing anything.\n")
|
||||
_T("Do you want to see this warning next time you try to load an object ?"));
|
||||
_T("Do you want to see this warning next time you try to load an object ?"),0);
|
||||
switch (uReply)
|
||||
{
|
||||
case IDYES:
|
||||
|
@ -1452,6 +1409,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC
|
|||
MSG msg;
|
||||
WNDCLASS wc;
|
||||
RECT rectWindow;
|
||||
HACCEL hAccel;
|
||||
HSZ hszService, hszTopic; // variables for DDE server
|
||||
DWORD dwAffMask;
|
||||
|
||||
|
@ -1514,6 +1472,8 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
VERIFY(hAccel = LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_MENU)));
|
||||
|
||||
// initialization
|
||||
QueryPerformanceFrequency(&lFreq); // init high resolution counter
|
||||
QueryPerformanceCounter(&lAppStart);
|
||||
|
@ -1607,7 +1567,8 @@ start:
|
|||
|
||||
while (GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
if( (hDlgDebug == NULL || !IsDialogMessage(hDlgDebug, &msg))
|
||||
if( !TranslateAccelerator(hWnd, hAccel, &msg)
|
||||
&& (hDlgDebug == NULL || !IsDialogMessage(hDlgDebug, &msg))
|
||||
&& (hDlgFind == NULL || !IsDialogMessage(hDlgFind, &msg))
|
||||
&& (hDlgProfile == NULL || !IsDialogMessage(hDlgProfile, &msg)))
|
||||
{
|
||||
|
|
|
@ -235,6 +235,10 @@ SOURCE=.\settings.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\stack.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\timer.c
|
||||
# End Source File
|
||||
# End Group
|
||||
|
|
|
@ -93,6 +93,7 @@ extern HCURSOR hCursorHand;
|
|||
extern BOOL bClassicCursor;
|
||||
extern BOOL bAutoSave;
|
||||
extern BOOL bAutoSaveOnExit;
|
||||
extern BOOL bSaveDefConfirm;
|
||||
extern BOOL bAlwaysDisplayLog;
|
||||
extern BOOL bLoadObjectWarning;
|
||||
extern HANDLE hThread;
|
||||
|
@ -203,6 +204,7 @@ extern VOID UpdatePatches(BOOL bPatch);
|
|||
extern BOOL PatchRom(LPCTSTR szFilename);
|
||||
extern BOOL MapRom(LPCTSTR szFilename);
|
||||
extern VOID UnmapRom(VOID);
|
||||
extern WORD CrcPort2(VOID);
|
||||
extern BOOL MapPort2(LPCTSTR szFilename);
|
||||
extern VOID UnmapPort2(VOID);
|
||||
extern VOID ResetDocument(VOID);
|
||||
|
@ -268,7 +270,12 @@ extern LRESULT OnToolMacroPlay(VOID);
|
|||
extern LRESULT OnToolMacroStop(VOID);
|
||||
extern LRESULT OnToolMacroSettings(VOID);
|
||||
|
||||
// Stack.c
|
||||
extern LRESULT OnStackCopy(VOID);
|
||||
extern LRESULT OnStackPaste(VOID);
|
||||
|
||||
// RPL.c
|
||||
extern BOOL RPL_GetSystemFlag(INT nFlag);
|
||||
extern DWORD RPL_SkipOb(DWORD d);
|
||||
extern DWORD RPL_ObjectSize(BYTE *o);
|
||||
extern DWORD RPL_CreateTemp(DWORD l);
|
||||
|
@ -277,6 +284,8 @@ extern VOID RPL_Replace(DWORD n);
|
|||
extern VOID RPL_Push(DWORD n);
|
||||
|
||||
// External.c
|
||||
extern BOOL bWaveBeep;
|
||||
extern DWORD dwWaveVol;
|
||||
extern VOID External(CHIPSET* w);
|
||||
|
||||
// DDEserv.c
|
||||
|
@ -310,7 +319,7 @@ extern BOOL DLLDestroyWnd(VOID);
|
|||
static __inline int InfoMessage(LPCTSTR szMessage) {return MessageBox(hWnd, szMessage, szTitle, MB_APPLMODAL|MB_OK|MB_ICONINFORMATION|MB_SETFOREGROUND);}
|
||||
static __inline int AbortMessage(LPCTSTR szMessage) {return MessageBox(hWnd, szMessage, szTitle, MB_APPLMODAL|MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);}
|
||||
static __inline int YesNoMessage(LPCTSTR szMessage) {return MessageBox(hWnd, szMessage, szTitle, MB_APPLMODAL|MB_YESNO|MB_ICONEXCLAMATION|MB_SETFOREGROUND);}
|
||||
static __inline int YesNoCancelMessage(LPCTSTR szMessage) {return MessageBox(hWnd, szMessage, szTitle, MB_APPLMODAL|MB_YESNOCANCEL|MB_ICONEXCLAMATION|MB_SETFOREGROUND);}
|
||||
static __inline int YesNoCancelMessage(LPCTSTR szMessage,UINT uStyle) {return MessageBox(hWnd, szMessage, szTitle, MB_APPLMODAL|MB_YESNOCANCEL|MB_ICONEXCLAMATION|MB_SETFOREGROUND|uStyle);}
|
||||
|
||||
// Missing Win32 API calls
|
||||
static __inline LPTSTR DuplicateString(LPCTSTR szString)
|
||||
|
|
|
@ -74,7 +74,7 @@ BEGIN
|
|||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 160
|
||||
TOPMARGIN, 4
|
||||
BOTTOMMARGIN, 222
|
||||
BOTTOMMARGIN, 256
|
||||
END
|
||||
|
||||
IDD_CHOOSEKML, DIALOG
|
||||
|
@ -232,15 +232,15 @@ BEGIN
|
|||
ES_READONLY
|
||||
END
|
||||
|
||||
IDD_SETTINGS DIALOG DISCARDABLE 0, 0, 167, 229
|
||||
IDD_SETTINGS DIALOG DISCARDABLE 0, 0, 167, 263
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Settings"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
CONTROL "Authentic Calculator Speed",IDC_REALSPEED,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,13,13,100,10
|
||||
CONTROL "Enable Virtual LCD Delay",IDC_GRAYSCALE,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,25,100,10
|
||||
CONTROL "Enable Virtual LCD Delay",IDC_GRAYSCALE,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,13,25,100,10
|
||||
CONTROL "Automatically Save Files",IDC_AUTOSAVE,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,13,37,89,10
|
||||
CONTROL "Automatically Save Files On Exit",IDC_AUTOSAVEONEXIT,
|
||||
|
@ -255,25 +255,35 @@ BEGIN
|
|||
CONTROL "Class Mnemonics",IDC_DISASM_CLASS,"Button",
|
||||
BS_AUTORADIOBUTTON,84,101,70,11
|
||||
GROUPBOX "Disassembler",IDC_STATIC,7,90,153,28
|
||||
LTEXT "Volume",IDC_STATIC,13,134,24,8
|
||||
CONTROL "Slider1",IDC_SOUND_SLIDER,"msctls_trackbar32",
|
||||
TBS_AUTOTICKS | WS_TABSTOP,39,129,68,18
|
||||
CONTROL "Speaker",IDC_SOUND_SPEAKER,"Button",BS_AUTORADIOBUTTON |
|
||||
WS_GROUP | WS_TABSTOP,111,128,43,10
|
||||
CONTROL "Wave",IDC_SOUND_WAVE,"Button",BS_AUTORADIOBUTTON,111,
|
||||
139,43,10
|
||||
GROUPBOX "Sound",IDC_STATIC,7,120,153,34
|
||||
CONTROL "Port 1 is Plugged",IDC_PORT1EN,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,13,131,67,10
|
||||
WS_TABSTOP,13,165,67,10
|
||||
CONTROL "Port 1 is Writeable",IDC_PORT1WR,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,84,131,69,10
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,84,165,69,10
|
||||
CONTROL "Port 2 is Shared",IDC_PORT2ISSHARED,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,13,143,65,10
|
||||
LTEXT "Port 2 File :",IDC_STATIC,13,159,37,8
|
||||
EDITTEXT IDC_PORT2,51,156,94,12,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "...",IDC_PORT2LOAD,145,156,10,12
|
||||
GROUPBOX "Memory Cards",IDC_STATIC,7,122,153,51
|
||||
LTEXT "Wire:",IDC_STATIC,13,188,17,8
|
||||
COMBOBOX IDC_WIRE,31,186,48,42,CBS_DROPDOWNLIST | WS_VSCROLL |
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,13,177,65,10
|
||||
CONTROL "Port 2 is Writeable",IDC_PORT2WR,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,84,177,69,10
|
||||
LTEXT "Port 2 File :",IDC_STATIC,13,192,37,8
|
||||
EDITTEXT IDC_PORT2,51,190,94,12,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "...",IDC_PORT2LOAD,145,190,10,12
|
||||
GROUPBOX "Memory Cards",IDC_STATIC,7,156,153,51
|
||||
LTEXT "Wire:",IDC_STATIC,13,221,17,8
|
||||
COMBOBOX IDC_WIRE,31,219,48,42,CBS_DROPDOWNLIST | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
LTEXT "IR:",IDC_STATIC,89,188,9,8
|
||||
COMBOBOX IDC_IR,107,186,48,43,CBS_DROPDOWNLIST | WS_VSCROLL |
|
||||
LTEXT "IR:",IDC_STATIC,89,221,9,8
|
||||
COMBOBOX IDC_IR,107,219,48,43,CBS_DROPDOWNLIST | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
GROUPBOX "Serial Ports",IDC_STATIC,7,176,153,27
|
||||
DEFPUSHBUTTON "&Ok",IDOK,9,208,50,14
|
||||
PUSHBUTTON "&Cancel",IDCANCEL,107,208,50,14
|
||||
GROUPBOX "Serial Ports",IDC_STATIC,7,209,153,27
|
||||
DEFPUSHBUTTON "&Ok",IDOK,9,242,50,14
|
||||
PUSHBUTTON "&Cancel",IDCANCEL,107,242,50,14
|
||||
END
|
||||
|
||||
IDD_CHOOSEKML DIALOG DISCARDABLE 0, 0, 195, 66
|
||||
|
@ -538,8 +548,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,3,8,0
|
||||
PRODUCTVERSION 1,3,8,0
|
||||
FILEVERSION 1,4,0,0
|
||||
PRODUCTVERSION 1,4,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -556,12 +566,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "Sebastien Carlier & Christoph Gießelink\0"
|
||||
VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0"
|
||||
VALUE "FileVersion", "1, 3, 8, 0\0"
|
||||
VALUE "FileVersion", "1, 4, 0, 0\0"
|
||||
VALUE "InternalName", "Emu48\0"
|
||||
VALUE "LegalCopyright", "Copyright © 2005\0"
|
||||
VALUE "OriginalFilename", "Emu48.exe\0"
|
||||
VALUE "ProductName", "Emu48\0"
|
||||
VALUE "ProductVersion", "1, 3, 8, 0\0"
|
||||
VALUE "ProductVersion", "1, 4, 0, 0\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
@ -607,8 +617,8 @@ BEGIN
|
|||
MENUITEM "&Save Object...", ID_OBJECT_SAVE
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "C&opy Screen", ID_VIEW_COPY
|
||||
MENUITEM "&Copy String", ID_STACK_COPY
|
||||
MENUITEM "&Paste String", ID_STACK_PASTE
|
||||
MENUITEM "&Copy Stack", ID_STACK_COPY
|
||||
MENUITEM "&Paste Stack", ID_STACK_PASTE
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Reset Calculator", ID_VIEW_RESET, GRAYED
|
||||
POPUP "&Backup"
|
||||
|
@ -755,6 +765,25 @@ END
|
|||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 24
|
||||
//
|
||||
|
||||
CREATEPROCESS_MANIFEST_RESOURCE_ID 24 MOVEABLE PURE "Emu48.xml"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Accelerator
|
||||
//
|
||||
|
||||
IDR_MENU ACCELERATORS DISCARDABLE
|
||||
BEGIN
|
||||
"C", ID_STACK_COPY, VIRTKEY, CONTROL, NOINVERT
|
||||
"V", ID_STACK_PASTE, VIRTKEY, CONTROL, NOINVERT
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
|
@ -773,14 +802,6 @@ BEGIN
|
|||
ID_BREAKPOINTS_CODEEDIT "Breakpoint List"
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Manifest
|
||||
//
|
||||
|
||||
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "Emu48.xml"
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
|
@ -549,6 +549,7 @@ loop:
|
|||
IOBit(SRQ2,NINT,bNINT);
|
||||
}
|
||||
RomSwitch(Chipset.Bank_FF); // select HP49G ROM bank and update memory mapping
|
||||
UpdateContrast(Chipset.contrast);
|
||||
UpdateDisplayPointers();
|
||||
UpdateMainDisplay();
|
||||
UpdateMenuDisplay();
|
||||
|
|
|
@ -4,12 +4,15 @@
|
|||
* This file is part of Emu48
|
||||
*
|
||||
* Copyright (C) 1995 Sebastien Carlier
|
||||
* Copyright (C) 2005 Christoph Gießelink
|
||||
*
|
||||
*/
|
||||
#include "pch.h"
|
||||
#include "Emu48.h"
|
||||
#include "ops.h"
|
||||
|
||||
#define MUSIC_FREQ 11025 // this can be adjusted for quality
|
||||
|
||||
//| 38G | 39G | 40G | 48SX | 48GX | 49G | Name
|
||||
//#F0E4F #80F0F #80F0F #706D2 #80850 #80F0F =SFLAG53_56
|
||||
|
||||
|
@ -28,6 +31,102 @@
|
|||
) \
|
||||
)
|
||||
|
||||
BOOL bWaveBeep = FALSE; // PC speaker
|
||||
DWORD dwWaveVol = 64; // wave sound volume
|
||||
|
||||
static __inline VOID BeepWave(DWORD dwFrequency,DWORD dwDuration)
|
||||
{
|
||||
HWAVEOUT hSoundDevice;
|
||||
WAVEFORMATEX wf;
|
||||
WAVEHDR wh;
|
||||
HANDLE hEventSound;
|
||||
DWORD i;
|
||||
|
||||
if (dwFrequency == 0) // this is just a delay
|
||||
{
|
||||
Sleep(dwDuration);
|
||||
return;
|
||||
}
|
||||
|
||||
hEventSound = CreateEvent(NULL,FALSE,FALSE,NULL);
|
||||
|
||||
wf.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wf.nChannels = 1;
|
||||
wf.nSamplesPerSec = MUSIC_FREQ;
|
||||
wf.nAvgBytesPerSec = MUSIC_FREQ;
|
||||
wf.nBlockAlign = 1;
|
||||
wf.wBitsPerSample = 8;
|
||||
wf.cbSize = 0;
|
||||
|
||||
if (waveOutOpen(&hSoundDevice,WAVE_MAPPER,&wf,(DWORD)hEventSound,0,CALLBACK_EVENT) != 0)
|
||||
{
|
||||
CloseHandle(hEventSound); // no sound available
|
||||
return;
|
||||
}
|
||||
|
||||
// (samp/sec) * msecs * (secs/msec) = samps
|
||||
wh.dwBufferLength = (DWORD) ((QWORD) MUSIC_FREQ * dwDuration / 1000);
|
||||
VERIFY(wh.lpData = HeapAlloc(hHeap,0,wh.dwBufferLength));
|
||||
wh.dwBytesRecorded = 0;
|
||||
wh.dwUser = 0;
|
||||
wh.dwFlags = 0;
|
||||
wh.dwLoops = 0;
|
||||
|
||||
for (i = 0; i < wh.dwBufferLength; ++i) // generate square wave
|
||||
{
|
||||
wh.lpData[i] = (BYTE) ((((QWORD) 2 * dwFrequency * i / MUSIC_FREQ) & 1) * dwWaveVol);
|
||||
}
|
||||
|
||||
VERIFY(waveOutPrepareHeader(hSoundDevice,&wh,sizeof(wh)) == MMSYSERR_NOERROR);
|
||||
|
||||
ResetEvent(hEventSound); // prepare event for finishing
|
||||
VERIFY(waveOutWrite(hSoundDevice,&wh,sizeof(wh)) == MMSYSERR_NOERROR);
|
||||
WaitForSingleObject(hEventSound,INFINITE); // wait for finishing
|
||||
|
||||
VERIFY(waveOutUnprepareHeader(hSoundDevice,&wh,sizeof(wh)) == MMSYSERR_NOERROR);
|
||||
VERIFY(waveOutClose(hSoundDevice) == MMSYSERR_NOERROR);
|
||||
|
||||
HeapFree(hHeap,0,wh.lpData);
|
||||
CloseHandle(hEventSound);
|
||||
return;
|
||||
}
|
||||
|
||||
static __inline VOID BeepWin9x(DWORD dwFrequency,DWORD dwDuration)
|
||||
{
|
||||
#define PIT8254_CNT2 0x42
|
||||
#define PIT8254_MCR 0x43
|
||||
#define PPI8255_PBO 0x61
|
||||
|
||||
BYTE bySpk = _inp(PPI8255_PBO); // get current status
|
||||
|
||||
if (dwFrequency != 0)
|
||||
{
|
||||
WORD wCount;
|
||||
|
||||
// limit low frequency
|
||||
if (lFreq.QuadPart / 65535 >= dwFrequency)
|
||||
dwFrequency = (DWORD) (lFreq.QuadPart / 65535) + 1;
|
||||
|
||||
// determine the timer frequency
|
||||
wCount = (WORD) (lFreq.QuadPart / dwFrequency);
|
||||
|
||||
_outp(PIT8254_MCR,0xB6); // set up the timer
|
||||
|
||||
_outp(PIT8254_CNT2,wCount&0xff);
|
||||
_outp(PIT8254_CNT2,wCount>>8);
|
||||
|
||||
_outp(PPI8255_PBO,bySpk | 0x03); // turn on the speaker
|
||||
}
|
||||
|
||||
Sleep(dwDuration);
|
||||
|
||||
_outp(PPI8255_PBO,bySpk & 0xFC); // turn off the speaker
|
||||
return;
|
||||
#undef PIT8254_CNT2
|
||||
#undef PIT8254_MCR
|
||||
#undef PPI8255_PBO
|
||||
}
|
||||
|
||||
static __inline VOID Return(CHIPSET* w)
|
||||
{
|
||||
w->rstkp=(w->rstkp-1)&7;
|
||||
|
@ -48,13 +147,30 @@ VOID External(CHIPSET* w) // Beep patch
|
|||
w->carry = TRUE; // setting of no beep
|
||||
if (!(fbeep & 0x8) && freq) // bit -56 clear and frequency > 0 Hz
|
||||
{
|
||||
if (freq < 37) freq = 37; // low limit of freqency (NT)
|
||||
if (freq > 4400) freq = 4400; // high limit of HP (SX)
|
||||
|
||||
if (dur > 1048575) // high limit of HP (SX)
|
||||
dur = 1048575;
|
||||
if (bWaveBeep)
|
||||
{
|
||||
BeepWave(freq,dur); // wave output over sound card
|
||||
}
|
||||
else
|
||||
{
|
||||
OSVERSIONINFO version;
|
||||
version.dwOSVersionInfoSize = sizeof(version);
|
||||
GetVersionEx(&version);
|
||||
|
||||
if (version.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
|
||||
{
|
||||
BeepWin9x(freq,dur); // do it the hard way on '9x / Me
|
||||
}
|
||||
else // VER_PLATFORM_WIN32_NT
|
||||
{
|
||||
if (freq < 37) freq = 37; // low limit of freqency (NT)
|
||||
|
||||
_ASSERT(freq >= 0x25 && freq <= 0x7FFF);
|
||||
Beep(freq,dur); // NT: ok, Windows 95: default sound or standard system beep
|
||||
}
|
||||
}
|
||||
|
||||
// estimate cpu cycles for beeping time (2MHz / 4MHz)
|
||||
w->cycles += dur * ((cCurrentRomType=='S') ? 2000 : 4000);
|
||||
|
|
|
@ -422,7 +422,7 @@ VOID UnmapRom(VOID)
|
|||
//#
|
||||
//################
|
||||
|
||||
static WORD CrcPort2(VOID) // calculate fingerprint of port2
|
||||
WORD CrcPort2(VOID) // calculate fingerprint of port2
|
||||
{
|
||||
DWORD dwCount;
|
||||
DWORD dwFileSize;
|
||||
|
|
|
@ -83,6 +83,7 @@ static KmlToken pLexToken[] =
|
|||
{TOK_IFFLAG, 000001, 6,_T("IfFlag")},
|
||||
{TOK_ONDOWN, 000000, 6,_T("OnDown")},
|
||||
{TOK_NOHOLD, 000000, 6,_T("NoHold")},
|
||||
{TOK_TOPBAR, 000001, 6,_T("Topbar")}, // for PPC compatibility reasons
|
||||
{TOK_TITLE, 000002, 5,_T("Title")},
|
||||
{TOK_OUTIN, 000011, 5,_T("OutIn")},
|
||||
{TOK_PATCH, 000002, 5,_T("Patch")},
|
||||
|
@ -100,6 +101,7 @@ static KmlToken pLexToken[] =
|
|||
{TOK_ONUP, 000000, 4,_T("OnUp")},
|
||||
{TOK_MAP, 000011, 3,_T("Map")},
|
||||
{TOK_ROM, 000002, 3,_T("Rom")},
|
||||
{TOK_VGA, 000001, 3,_T("Vga")}, // for PPC compatibility reasons
|
||||
{TOK_LCD, 000000, 3,_T("Lcd")},
|
||||
{TOK_END, 000000, 3,_T("End")},
|
||||
{0, 000000, 0,_T("")},
|
||||
|
@ -574,7 +576,7 @@ loop:
|
|||
}
|
||||
if (*szText==_T('#'))
|
||||
{
|
||||
do szText++; while (*szText != _T('\n'));
|
||||
do szText++; while (*szText != _T('\n') && *szText != 0);
|
||||
if (nMode != LEX_PARAM) goto loop;
|
||||
}
|
||||
return;
|
||||
|
@ -1024,6 +1026,11 @@ static KmlBlock* ParseBlocks(VOID)
|
|||
}
|
||||
}
|
||||
if (pFirst) pBlock->pNext = NULL;
|
||||
if (*szText != 0) // still KML text left
|
||||
{
|
||||
FatalError(); // error unknown block token
|
||||
goto abort;
|
||||
}
|
||||
return pFirst;
|
||||
abort:
|
||||
if (pFirst) FreeBlocks(pFirst);
|
||||
|
@ -1290,6 +1297,7 @@ static KmlLine* SkipLines(KmlLine* pLine, TokenId eCommand)
|
|||
if (IsBlock(pLine->eCommand)) nLevel++;
|
||||
if (pLine->eCommand == eCommand)
|
||||
{
|
||||
// found token, return command behind token
|
||||
if (nLevel == 0) return pLine->pNext;
|
||||
}
|
||||
if (pLine->eCommand == TOK_END)
|
||||
|
@ -1297,7 +1305,7 @@ static KmlLine* SkipLines(KmlLine* pLine, TokenId eCommand)
|
|||
if (nLevel)
|
||||
nLevel--;
|
||||
else
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
pLine = pLine->pNext;
|
||||
}
|
||||
|
@ -1467,6 +1475,7 @@ VOID KillKML(VOID)
|
|||
nBackgroundW = 256;
|
||||
nBackgroundH = 0;
|
||||
nLcdZoom = 1;
|
||||
cCurrentRomType = 0;
|
||||
UpdateWindowStatus();
|
||||
ResizeWindow();
|
||||
return;
|
||||
|
@ -2156,7 +2165,7 @@ BOOL InitKML(LPCTSTR szFilename, BOOL bNoLog)
|
|||
|
||||
if (cCurrentRomType == 0)
|
||||
{
|
||||
AddToLog(_T("This KML Script doesn't specify the ROM Type."));
|
||||
AddToLog(_T("This KML Script doesn't specify the model."));
|
||||
goto quit;
|
||||
}
|
||||
if (pbyRom == NULL)
|
||||
|
@ -2164,6 +2173,12 @@ BOOL InitKML(LPCTSTR szFilename, BOOL bNoLog)
|
|||
AddToLog(_T("This KML Script doesn't specify the ROM to use, or the ROM could not be loaded."));
|
||||
goto quit;
|
||||
}
|
||||
if (hMainDC == NULL)
|
||||
{
|
||||
AddToLog(_T("This KML Script doesn't specify the background bitmap, or bitmap could not be loaded."));
|
||||
goto quit;
|
||||
}
|
||||
|
||||
CreateLcdBitmap();
|
||||
|
||||
PrintfToLog(_T("%i Buttons Defined"), nButtons);
|
||||
|
|
|
@ -35,27 +35,29 @@ typedef enum eTokenId
|
|||
TOK_IFFLAG, //19
|
||||
TOK_ONDOWN, //20
|
||||
TOK_NOHOLD, //21
|
||||
TOK_TITLE, //22
|
||||
TOK_OUTIN, //23
|
||||
TOK_PATCH, //24
|
||||
TOK_PRINT, //25
|
||||
TOK_DEBUG, //26
|
||||
TOK_COLOR, //27
|
||||
TOK_MODEL, //28
|
||||
TOK_CLASS, //29
|
||||
TOK_PRESS, //30
|
||||
TOK_TYPE, //31
|
||||
TOK_SIZE, //32
|
||||
TOK_DOWN, //33
|
||||
TOK_ZOOM, //34
|
||||
TOK_ELSE, //35
|
||||
TOK_ONUP, //36
|
||||
TOK_EOL, //37
|
||||
TOK_MAP, //38
|
||||
TOK_ROM, //39
|
||||
TOK_LCD, //40
|
||||
TOK_NOTFLAG, //41
|
||||
TOK_END //42
|
||||
TOK_TOPBAR, //22
|
||||
TOK_TITLE, //23
|
||||
TOK_OUTIN, //24
|
||||
TOK_PATCH, //25
|
||||
TOK_PRINT, //26
|
||||
TOK_DEBUG, //27
|
||||
TOK_COLOR, //28
|
||||
TOK_MODEL, //29
|
||||
TOK_CLASS, //30
|
||||
TOK_PRESS, //31
|
||||
TOK_TYPE, //32
|
||||
TOK_SIZE, //33
|
||||
TOK_DOWN, //34
|
||||
TOK_ZOOM, //35
|
||||
TOK_ELSE, //36
|
||||
TOK_ONUP, //37
|
||||
TOK_EOL, //38
|
||||
TOK_MAP, //39
|
||||
TOK_ROM, //40
|
||||
TOK_VGA, //41
|
||||
TOK_LCD, //42
|
||||
TOK_NOTFLAG, //43
|
||||
TOK_END //44
|
||||
} TokenId;
|
||||
|
||||
#define TYPE_NONE 00
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <direct.h>
|
||||
#include <conio.h>
|
||||
#include <crtdbg.h>
|
||||
|
||||
#if !defined VERIFY
|
||||
|
|
|
@ -36,116 +36,120 @@
|
|||
#define IDC_PORT1EN 1006
|
||||
#define IDC_PORT1WR 1007
|
||||
#define IDC_PORT2ISSHARED 1008
|
||||
#define IDC_PORT2 1009
|
||||
#define IDC_PORT2LOAD 1010
|
||||
#define IDC_WIRE 1011
|
||||
#define IDC_IR 1012
|
||||
#define IDC_EMUDIR 1013
|
||||
#define IDC_EMUDIRSEL 1014
|
||||
#define IDC_UPDATE 1015
|
||||
#define IDC_KMLSCRIPT 1016
|
||||
#define IDC_AUTHOR 1017
|
||||
#define IDC_TITLE 1018
|
||||
#define IDC_KMLLOG 1019
|
||||
#define IDC_VERSION 1020
|
||||
#define IDC_LICENSE 1021
|
||||
#define IDC_DISASM_WIN 1022
|
||||
#define IDC_DISASM_MAP 1023
|
||||
#define IDC_DISASM_ROM 1024
|
||||
#define IDC_DISASM_RAM 1025
|
||||
#define IDC_DISASM_PORT1 1026
|
||||
#define IDC_DISASM_PORT2 1027
|
||||
#define IDC_DISASM_MODULE 1028
|
||||
#define IDC_DISASM_HP 1029
|
||||
#define IDC_DISASM_CLASS 1030
|
||||
#define IDC_ADDRESS 1031
|
||||
#define IDC_DISASM_ADR 1032
|
||||
#define IDC_DISASM_NEXT 1033
|
||||
#define IDC_DISASM_COPY 1034
|
||||
#define IDC_DEBUG_CODE 1035
|
||||
#define IDC_STATIC_CODE 1036
|
||||
#define IDC_STATIC_REGISTERS 1037
|
||||
#define IDC_STATIC_MEMORY 1038
|
||||
#define IDC_STATIC_STACK 1039
|
||||
#define IDC_REG_A 1040
|
||||
#define IDC_REG_B 1041
|
||||
#define IDC_REG_C 1042
|
||||
#define IDC_REG_D 1043
|
||||
#define IDC_REG_R0 1044
|
||||
#define IDC_REG_R1 1045
|
||||
#define IDC_REG_R2 1046
|
||||
#define IDC_REG_R3 1047
|
||||
#define IDC_REG_R4 1048
|
||||
#define IDC_REG_D0 1049
|
||||
#define IDC_REG_D1 1050
|
||||
#define IDC_REG_P 1051
|
||||
#define IDC_REG_PC 1052
|
||||
#define IDC_REG_OUT 1053
|
||||
#define IDC_REG_IN 1054
|
||||
#define IDC_REG_ST 1055
|
||||
#define IDC_REG_CY 1056
|
||||
#define IDC_REG_MODE 1057
|
||||
#define IDC_REG_MP 1058
|
||||
#define IDC_REG_SR 1059
|
||||
#define IDC_REG_SB 1060
|
||||
#define IDC_REG_XM 1061
|
||||
#define IDC_MISC_INT 1062
|
||||
#define IDC_MISC_KEY 1063
|
||||
#define IDC_MISC_BS 1064
|
||||
#define IDC_NEWVALUE 1065
|
||||
#define IDC_ENTERADR 1066
|
||||
#define IDC_DEBUG_MEM 1067
|
||||
#define IDC_DEBUG_MEM_ADDR 1068
|
||||
#define IDC_DEBUG_MEM_COL0 1069
|
||||
#define IDC_DEBUG_MEM_COL1 1070
|
||||
#define IDC_DEBUG_MEM_COL2 1071
|
||||
#define IDC_DEBUG_MEM_COL3 1072
|
||||
#define IDC_DEBUG_MEM_COL4 1073
|
||||
#define IDC_DEBUG_MEM_COL5 1074
|
||||
#define IDC_DEBUG_MEM_COL6 1075
|
||||
#define IDC_DEBUG_MEM_COL7 1076
|
||||
#define IDC_DEBUG_MEM_TEXT 1077
|
||||
#define IDC_DEBUG_STACK 1078
|
||||
#define IDC_STATIC_BREAKPOINT 1079
|
||||
#define IDC_BREAKEDIT_ADD 1080
|
||||
#define IDC_BREAKEDIT_DELETE 1081
|
||||
#define IDC_BREAKEDIT_WND 1082
|
||||
#define IDC_STATIC_MMU 1083
|
||||
#define IDC_MMU_IO_A 1084
|
||||
#define IDC_MMU_NCE2_A 1085
|
||||
#define IDC_MMU_CE1_A 1086
|
||||
#define IDC_MMU_CE2_A 1087
|
||||
#define IDC_MMU_NCE3_A 1088
|
||||
#define IDC_MMU_IO_S 1089
|
||||
#define IDC_MMU_CE1_S 1090
|
||||
#define IDC_MMU_CE2_S 1091
|
||||
#define IDC_MMU_NCE2_S 1092
|
||||
#define IDC_MMU_NCE3_S 1093
|
||||
#define IDC_STATIC_MISC 1094
|
||||
#define IDC_MISC_BS_TXT 1095
|
||||
#define IDC_INSTR_TEXT 1096
|
||||
#define IDC_INSTR_CODE 1097
|
||||
#define IDC_INSTR_COPY 1098
|
||||
#define IDC_INSTR_CLEAR 1099
|
||||
#define IDC_PROFILE_LASTCYCLES 1100
|
||||
#define IDC_PROFILE_LASTTIME 1101
|
||||
#define IDC_BPCODE 1102
|
||||
#define IDC_BPRPL 1103
|
||||
#define IDC_BPACCESS 1104
|
||||
#define IDC_BPREAD 1105
|
||||
#define IDC_BPWRITE 1106
|
||||
#define IDC_FIND_DATA 1107
|
||||
#define IDC_FIND_ASCII 1108
|
||||
#define IDC_FIND_CASE 1109
|
||||
#define IDC_ADDR20_24 1110
|
||||
#define IDC_ADDR25_27 1111
|
||||
#define IDC_ADDR28_29 1112
|
||||
#define IDC_ADDR30_34 1113
|
||||
#define IDC_MACRO_SLOW 1114
|
||||
#define IDC_MACRO_FAST 1115
|
||||
#define IDC_MACRO_SLIDER 1116
|
||||
#define IDC_MACRO_REAL 1117
|
||||
#define IDC_MACRO_MANUAL 1118
|
||||
#define IDC_PORT2WR 1009
|
||||
#define IDC_PORT2 1010
|
||||
#define IDC_PORT2LOAD 1011
|
||||
#define IDC_WIRE 1012
|
||||
#define IDC_IR 1013
|
||||
#define IDC_EMUDIR 1014
|
||||
#define IDC_EMUDIRSEL 1015
|
||||
#define IDC_UPDATE 1016
|
||||
#define IDC_KMLSCRIPT 1017
|
||||
#define IDC_AUTHOR 1018
|
||||
#define IDC_TITLE 1019
|
||||
#define IDC_KMLLOG 1020
|
||||
#define IDC_VERSION 1021
|
||||
#define IDC_LICENSE 1022
|
||||
#define IDC_DISASM_WIN 1023
|
||||
#define IDC_DISASM_MAP 1024
|
||||
#define IDC_DISASM_ROM 1025
|
||||
#define IDC_DISASM_RAM 1026
|
||||
#define IDC_DISASM_PORT1 1027
|
||||
#define IDC_DISASM_PORT2 1028
|
||||
#define IDC_DISASM_MODULE 1029
|
||||
#define IDC_DISASM_HP 1030
|
||||
#define IDC_DISASM_CLASS 1031
|
||||
#define IDC_ADDRESS 1032
|
||||
#define IDC_DISASM_ADR 1033
|
||||
#define IDC_DISASM_NEXT 1034
|
||||
#define IDC_DISASM_COPY 1035
|
||||
#define IDC_DEBUG_CODE 1036
|
||||
#define IDC_STATIC_CODE 1037
|
||||
#define IDC_STATIC_REGISTERS 1038
|
||||
#define IDC_STATIC_MEMORY 1039
|
||||
#define IDC_STATIC_STACK 1040
|
||||
#define IDC_REG_A 1041
|
||||
#define IDC_REG_B 1042
|
||||
#define IDC_REG_C 1043
|
||||
#define IDC_REG_D 1044
|
||||
#define IDC_REG_R0 1045
|
||||
#define IDC_REG_R1 1046
|
||||
#define IDC_REG_R2 1047
|
||||
#define IDC_REG_R3 1048
|
||||
#define IDC_REG_R4 1049
|
||||
#define IDC_REG_D0 1050
|
||||
#define IDC_REG_D1 1051
|
||||
#define IDC_REG_P 1052
|
||||
#define IDC_REG_PC 1053
|
||||
#define IDC_REG_OUT 1054
|
||||
#define IDC_REG_IN 1055
|
||||
#define IDC_REG_ST 1056
|
||||
#define IDC_REG_CY 1057
|
||||
#define IDC_REG_MODE 1058
|
||||
#define IDC_REG_MP 1059
|
||||
#define IDC_REG_SR 1060
|
||||
#define IDC_REG_SB 1061
|
||||
#define IDC_REG_XM 1062
|
||||
#define IDC_MISC_INT 1063
|
||||
#define IDC_MISC_KEY 1064
|
||||
#define IDC_MISC_BS 1065
|
||||
#define IDC_NEWVALUE 1066
|
||||
#define IDC_ENTERADR 1067
|
||||
#define IDC_DEBUG_MEM 1068
|
||||
#define IDC_DEBUG_MEM_ADDR 1069
|
||||
#define IDC_DEBUG_MEM_COL0 1070
|
||||
#define IDC_DEBUG_MEM_COL1 1071
|
||||
#define IDC_DEBUG_MEM_COL2 1072
|
||||
#define IDC_DEBUG_MEM_COL3 1073
|
||||
#define IDC_DEBUG_MEM_COL4 1074
|
||||
#define IDC_DEBUG_MEM_COL5 1075
|
||||
#define IDC_DEBUG_MEM_COL6 1076
|
||||
#define IDC_DEBUG_MEM_COL7 1077
|
||||
#define IDC_DEBUG_MEM_TEXT 1078
|
||||
#define IDC_DEBUG_STACK 1079
|
||||
#define IDC_STATIC_BREAKPOINT 1080
|
||||
#define IDC_BREAKEDIT_ADD 1081
|
||||
#define IDC_BREAKEDIT_DELETE 1082
|
||||
#define IDC_BREAKEDIT_WND 1083
|
||||
#define IDC_STATIC_MMU 1084
|
||||
#define IDC_MMU_IO_A 1085
|
||||
#define IDC_MMU_NCE2_A 1086
|
||||
#define IDC_MMU_CE1_A 1087
|
||||
#define IDC_MMU_CE2_A 1088
|
||||
#define IDC_MMU_NCE3_A 1089
|
||||
#define IDC_MMU_IO_S 1090
|
||||
#define IDC_MMU_CE1_S 1091
|
||||
#define IDC_MMU_CE2_S 1092
|
||||
#define IDC_MMU_NCE2_S 1093
|
||||
#define IDC_MMU_NCE3_S 1094
|
||||
#define IDC_STATIC_MISC 1095
|
||||
#define IDC_MISC_BS_TXT 1096
|
||||
#define IDC_INSTR_TEXT 1097
|
||||
#define IDC_INSTR_CODE 1098
|
||||
#define IDC_INSTR_COPY 1099
|
||||
#define IDC_INSTR_CLEAR 1100
|
||||
#define IDC_PROFILE_LASTCYCLES 1101
|
||||
#define IDC_PROFILE_LASTTIME 1102
|
||||
#define IDC_BPCODE 1103
|
||||
#define IDC_BPRPL 1104
|
||||
#define IDC_BPACCESS 1105
|
||||
#define IDC_BPREAD 1106
|
||||
#define IDC_BPWRITE 1107
|
||||
#define IDC_FIND_DATA 1108
|
||||
#define IDC_FIND_ASCII 1109
|
||||
#define IDC_FIND_CASE 1110
|
||||
#define IDC_ADDR20_24 1111
|
||||
#define IDC_ADDR25_27 1112
|
||||
#define IDC_ADDR28_29 1113
|
||||
#define IDC_ADDR30_34 1114
|
||||
#define IDC_MACRO_SLOW 1115
|
||||
#define IDC_MACRO_FAST 1116
|
||||
#define IDC_MACRO_SLIDER 1117
|
||||
#define IDC_MACRO_REAL 1118
|
||||
#define IDC_MACRO_MANUAL 1119
|
||||
#define IDC_SOUND_SLIDER 1120
|
||||
#define IDC_SOUND_SPEAKER 1121
|
||||
#define IDC_SOUND_WAVE 1122
|
||||
#define ID_FILE_NEW 40001
|
||||
#define ID_FILE_OPEN 40002
|
||||
#define ID_FILE_SAVE 40003
|
||||
|
@ -212,7 +216,7 @@
|
|||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 123
|
||||
#define _APS_NEXT_COMMAND_VALUE 40062
|
||||
#define _APS_NEXT_CONTROL_VALUE 1119
|
||||
#define _APS_NEXT_CONTROL_VALUE 1122
|
||||
#define _APS_NEXT_SYMED_VALUE 108
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
//#F0697 #806F8 #806F8 #70579 #806F8 #806F8 =DSKTOP (D1)
|
||||
//#F0DEA #80E9B #80E9B #7066E #807ED #80E9B =AVMEM (D)
|
||||
//#F0705 #8076B #8076B #705B0 #8072F #8076B =INTRPPTR (D0)
|
||||
// #80F02 #80F02 #706C5 #80843 #80F02 =SystemFlags
|
||||
|
||||
#define TEMPOB ((cCurrentRomType=='S')?0x7056A:0x806E9)
|
||||
#define TEMPTOP ((cCurrentRomType=='S')?0x7056F:0x806EE)
|
||||
|
@ -25,6 +26,7 @@
|
|||
#define DSKTOP ((cCurrentRomType=='S')?0x70579:0x806F8)
|
||||
#define AVMEM ((cCurrentRomType!='X')?((cCurrentRomType=='S')?0x7066E:0x807ED):0x80E9B)
|
||||
#define INTRPPTR ((cCurrentRomType!='X')?((cCurrentRomType=='S')?0x705B0:0x8072F):0x8076B)
|
||||
#define SYSTEMFLAGS ((cCurrentRomType!='X')?((cCurrentRomType=='S')?0x706C5:0x80843):0x80F02)
|
||||
|
||||
#define DOINT 0x02614 // Precision Integer (HP49G)
|
||||
#define DOLNGREAL 0x0263A // Precision Real (HP49G)
|
||||
|
@ -93,6 +95,21 @@ static BOOL Metakernel(VOID)
|
|||
return bMkDetect;
|
||||
}
|
||||
|
||||
BOOL RPL_GetSystemFlag(INT nFlag)
|
||||
{
|
||||
DWORD dwAddr;
|
||||
BYTE byMask,byFlag;
|
||||
|
||||
_ASSERT(nFlag > 0); // first flag is 1
|
||||
|
||||
// calculate memory address and bit mask
|
||||
dwAddr = SYSTEMFLAGS + (nFlag - 1) / 4;
|
||||
byMask = 1 << ((nFlag - 1) & 0x3);
|
||||
|
||||
Npeek(&byFlag,dwAddr,sizeof(byFlag));
|
||||
return (byFlag & byMask) != 0;
|
||||
}
|
||||
|
||||
DWORD RPL_SkipOb(DWORD d)
|
||||
{
|
||||
BYTE X[8];
|
||||
|
|
|
@ -141,6 +141,7 @@ VOID ReadSettings(VOID)
|
|||
ReadString(_T("Files"),_T("Emu48Directory"),szCurrentDirectory,szEmuDirectory,ARRAYSIZEOF(szEmuDirectory));
|
||||
bAutoSave = ReadInt(_T("Files"),_T("AutoSave"),bAutoSave);
|
||||
bAutoSaveOnExit = ReadInt(_T("Files"),_T("AutoSaveOnExit"),bAutoSaveOnExit);
|
||||
bSaveDefConfirm = ReadInt(_T("Files"),_T("SaveDefaultConfirm"),bSaveDefConfirm);
|
||||
bLoadObjectWarning = ReadInt(_T("Files"),_T("LoadObjectWarning"),bLoadObjectWarning);
|
||||
// Port2
|
||||
bPort2IsShared = ReadInt(_T("Port2"),_T("IsShared"),bPort2IsShared);
|
||||
|
@ -152,9 +153,11 @@ VOID ReadSettings(VOID)
|
|||
disassembler_mode = ReadInt(_T("Disassembler"),_T("Mnemonics"),disassembler_mode);
|
||||
// Emulator
|
||||
bRealSpeed = ReadInt(_T("Emulator"),_T("RealSpeed"),bRealSpeed);
|
||||
bGrayscale = ReadInt(_T("Emulator"),_T("Grayscale"),bGrayscale);
|
||||
dwSXCycles = ReadInt(_T("Emulator"),_T("SXCycles"),dwSXCycles);
|
||||
dwGXCycles = ReadInt(_T("Emulator"),_T("GXCycles"),dwGXCycles);
|
||||
bGrayscale = ReadInt(_T("Emulator"),_T("Grayscale"),bGrayscale);
|
||||
bWaveBeep = ReadInt(_T("Emulator"),_T("WaveBeep"),bWaveBeep);
|
||||
dwWaveVol = ReadInt(_T("Emulator"),_T("WaveVolume"),dwWaveVol);
|
||||
SetSpeed(bRealSpeed); // set speed
|
||||
// Macro
|
||||
bMacroRealSpeed = ReadInt(_T("Macro"),_T("RealSpeed"),bMacroRealSpeed);
|
||||
|
@ -174,6 +177,7 @@ VOID WriteSettings(VOID)
|
|||
WriteString(_T("Files"),_T("Emu48Directory"),szEmuDirectory);
|
||||
WriteInt(_T("Files"),_T("AutoSave"),bAutoSave);
|
||||
WriteInt(_T("Files"),_T("AutoSaveOnExit"),bAutoSaveOnExit);
|
||||
WriteInt(_T("Files"),_T("SaveDefaultConfirm"),bSaveDefConfirm);
|
||||
WriteInt(_T("Files"),_T("LoadObjectWarning"),bLoadObjectWarning);
|
||||
// Port2
|
||||
WriteInt(_T("Port2"),_T("IsShared"),bPort2IsShared);
|
||||
|
@ -185,9 +189,11 @@ VOID WriteSettings(VOID)
|
|||
WriteInt(_T("Disassembler"),_T("Mnemonics"),disassembler_mode);
|
||||
// Emulator
|
||||
WriteInt(_T("Emulator"),_T("RealSpeed"),bRealSpeed);
|
||||
WriteInt(_T("Emulator"),_T("Grayscale"),bGrayscale);
|
||||
WriteInt(_T("Emulator"),_T("SXCycles"),dwSXCycles);
|
||||
WriteInt(_T("Emulator"),_T("GXCycles"),dwGXCycles);
|
||||
WriteInt(_T("Emulator"),_T("Grayscale"),bGrayscale);
|
||||
WriteInt(_T("Emulator"),_T("WaveBeep"),bWaveBeep);
|
||||
WriteInt(_T("Emulator"),_T("WaveVolume"),dwWaveVol);
|
||||
// Macro
|
||||
WriteInt(_T("Macro"),_T("RealSpeed"),bMacroRealSpeed);
|
||||
WriteInt(_T("Macro"),_T("ReplayTimeout"),nMacroTimeout);
|
||||
|
|
646
Sources/Emu48/STACK.C
Normal file
646
Sources/Emu48/STACK.C
Normal file
|
@ -0,0 +1,646 @@
|
|||
/*
|
||||
* stack.c
|
||||
*
|
||||
* This file is part of Emu48
|
||||
*
|
||||
* Copyright (C) 2005 Christoph Gießelink
|
||||
*
|
||||
*/
|
||||
#include "pch.h"
|
||||
#include "resource.h"
|
||||
#include "Emu48.h"
|
||||
#include "io.h"
|
||||
|
||||
#define fnRadix 51 // fraction mark
|
||||
#define fnApprox 105 // exact / approx. mode (HP49G)
|
||||
|
||||
#define DOINT 0x02614 // Precision Integer (HP49G)
|
||||
#define DOREAL 0x02933 // Real
|
||||
#define DOCSTR 0x02A2C // String
|
||||
|
||||
//################
|
||||
//#
|
||||
//# Low level subroutines
|
||||
//#
|
||||
//################
|
||||
|
||||
static INT RPL_GetZInt(BYTE CONST *pbyNum,INT nIntLen,LPTSTR cp,INT nSize)
|
||||
{
|
||||
INT i = 0; // character counter
|
||||
|
||||
_ASSERT(nSize > 0); // target buffer size
|
||||
|
||||
if (nIntLen > 1) // has sign nibble
|
||||
{
|
||||
--nIntLen; // remove sign from digit length
|
||||
|
||||
// check for valid sign
|
||||
_ASSERT(pbyNum[nIntLen] == 0 || pbyNum[nIntLen] == 9);
|
||||
if (pbyNum[nIntLen] == 9) // negative number
|
||||
{
|
||||
*cp++ = _T('-'); // add sign
|
||||
--nSize; // dec dest buffer size
|
||||
++i; // wrote one character
|
||||
}
|
||||
}
|
||||
|
||||
if (nIntLen >= nSize) return 0; // dest buffer overflow
|
||||
i += nIntLen; // adjust character counter
|
||||
|
||||
while (nIntLen-- > 0) // write all digits
|
||||
{
|
||||
// check for valid digit
|
||||
_ASSERT(pbyNum[nIntLen] >= 0 && pbyNum[nIntLen] <= 9);
|
||||
*cp++ = _T('0') + pbyNum[nIntLen]; // and write
|
||||
}
|
||||
*cp = 0; // set EOS
|
||||
return i;
|
||||
}
|
||||
|
||||
static INT RPL_SetZInt(LPCTSTR cp,LPBYTE pbyNum,INT nSize)
|
||||
{
|
||||
BYTE bySign;
|
||||
INT nStrLen,nNumSize;
|
||||
|
||||
_ASSERT(nSize > 0); // target buffer size
|
||||
|
||||
nStrLen = lstrlen(cp); // source string length
|
||||
|
||||
if ( nStrLen == 0 // empty string
|
||||
// precisition integer contain only these numbers
|
||||
|| _tcsspn(cp,_T("0123456789+-")) != (SIZE_T) nStrLen)
|
||||
return 0;
|
||||
|
||||
bySign = (*cp != _T('-')) ? 0 : 9; // set sign nibble
|
||||
if (*cp == _T('-') || *cp == _T('+')) // skip sign character
|
||||
{
|
||||
++cp;
|
||||
--nStrLen;
|
||||
}
|
||||
|
||||
if (nStrLen == 1 && *cp == _T('0')) // special code for zero
|
||||
{
|
||||
*pbyNum = 0; // zero data
|
||||
return 1; // finish
|
||||
}
|
||||
|
||||
// nStrLen = no. of digits without sign
|
||||
if (nStrLen >= nSize) // destination buffer too small
|
||||
return 0;
|
||||
|
||||
nNumSize = nStrLen + 1; // no. of written data
|
||||
|
||||
while (--nStrLen >= 0) // eval all digits
|
||||
{
|
||||
TCHAR c = cp[nStrLen];
|
||||
|
||||
// only '0' .. '9' are valid here
|
||||
if (!((c >= _T('0')) || (c <= _T('9'))))
|
||||
return 0;
|
||||
|
||||
c -= _T('0');
|
||||
*pbyNum++ = (BYTE) c;
|
||||
}
|
||||
*pbyNum = bySign; // add sign
|
||||
|
||||
return nNumSize;
|
||||
}
|
||||
|
||||
static INT RPL_GetBcd(BYTE CONST *pbyNum,INT nMantLen,INT nExpLen,CONST TCHAR cDec,LPTSTR cp,INT nSize)
|
||||
{
|
||||
BYTE byNib;
|
||||
LONG v,lExp;
|
||||
BOOL bPflag,bExpflag;
|
||||
INT i;
|
||||
|
||||
lExp = 0;
|
||||
for (v = 1; nExpLen--; v *= 10) // fetch exponent
|
||||
{
|
||||
lExp += (LONG) *pbyNum++ * v; // calc. exponent
|
||||
}
|
||||
|
||||
if (lExp > v / 2) lExp -= v; // negative exponent
|
||||
|
||||
lExp -= nMantLen - 1; // set decimal point to end of mantissa
|
||||
|
||||
i = 0; // first character
|
||||
bPflag = FALSE; // show no decimal point
|
||||
|
||||
// scan mantissa
|
||||
for (v = (LONG) nMantLen - 1; v >= 0 || bPflag; v--)
|
||||
{
|
||||
if (v >= 0L) // still mantissa digits left
|
||||
byNib = *pbyNum++;
|
||||
else
|
||||
byNib = 0; // zero for negativ exponent
|
||||
|
||||
if (!i) // still delete zeros at end
|
||||
{
|
||||
if (byNib == 0 && lExp && v > 0) // delete zeros
|
||||
{
|
||||
lExp++; // adjust exponent
|
||||
continue;
|
||||
}
|
||||
|
||||
// TRUE at x.E
|
||||
bExpflag = v + lExp > 14 || v + lExp < -nMantLen;
|
||||
bPflag = !bExpflag && v < -lExp; // decimal point flag at neg. exponent
|
||||
}
|
||||
|
||||
// set decimal point
|
||||
if ((bExpflag && v == 0) || (!lExp && i))
|
||||
{
|
||||
if (i >= nSize) return 0; // dest buffer overflow
|
||||
cp[i++] = cDec; // write decimal point
|
||||
if (v < 0) // no mantissa digits any more
|
||||
{
|
||||
if (i >= nSize) return 0; // dest buffer overflow
|
||||
cp[i++] = _T('0'); // write heading zero
|
||||
}
|
||||
bPflag = FALSE; // finished with negativ exponents
|
||||
}
|
||||
|
||||
if (v >= 0 || bPflag)
|
||||
{
|
||||
if (i >= nSize) return 0; // dest buffer overflow
|
||||
cp[i++] = (TCHAR) byNib + _T('0'); // write character
|
||||
}
|
||||
|
||||
lExp++; // next position
|
||||
}
|
||||
|
||||
if (*pbyNum == 9) // negative number
|
||||
{
|
||||
if (i >= nSize) return 0; // dest buffer overflow
|
||||
cp[i++] = _T('-'); // write sign
|
||||
}
|
||||
|
||||
if (i >= nSize) return 0; // dest buffer overflow
|
||||
cp[i] = 0; // set EOS
|
||||
|
||||
for (v = 0; v < (i / 2); v++) // reverse string
|
||||
{
|
||||
TCHAR cNib = cp[v]; // swap chars
|
||||
cp[v] = cp[i-v-1];
|
||||
cp[i-v-1] = cNib;
|
||||
}
|
||||
|
||||
// write number with exponent
|
||||
if (bExpflag)
|
||||
{
|
||||
if (i + 5 >= nSize) return 0; // dest buffer overflow
|
||||
i += wsprintf(&cp[i],_T("E%d"),lExp-1);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static INT RPL_SetBcd(LPCTSTR cp,INT nMantLen,INT nExpLen,CONST TCHAR cDec,LPBYTE pbyNum,INT nSize)
|
||||
{
|
||||
TCHAR cVc[] = _T(".0123456789eE+-");
|
||||
|
||||
BYTE byNum[80];
|
||||
INT i,nIp,nDp,nMaxExp;
|
||||
LONG lExp;
|
||||
|
||||
cVc[0] = cDec; // replace decimal char
|
||||
|
||||
if ( nMantLen + nExpLen >= nSize // destination buffer too small
|
||||
|| !*cp // empty string
|
||||
|| _tcsspn(cp,cVc) != (SIZE_T) lstrlen(cp) // real contain only these numbers
|
||||
|| lstrlen(cp) >= ARRAYSIZEOF(byNum)) // ignore too long reals
|
||||
return 0;
|
||||
|
||||
byNum[0] = (*cp != _T('-')) ? 0 : 9; // set sign nibble
|
||||
if (*cp == _T('-') || *cp == _T('+')) // skip sign character
|
||||
cp++;
|
||||
|
||||
// only '.', '0' .. '9' are valid here
|
||||
if (!((*cp == cDec) || (*cp >= _T('0')) || (*cp <= _T('9'))))
|
||||
return 0;
|
||||
|
||||
nIp = 0; // length of integer part
|
||||
if (*cp != cDec) // no decimal point
|
||||
{
|
||||
// count integer part
|
||||
while (*cp >= _T('0') && *cp <= _T('9'))
|
||||
byNum[++nIp] = *cp++ - _T('0');
|
||||
if (!nIp) return 0;
|
||||
}
|
||||
|
||||
// only '.', 'E', 'e' or end are valid here
|
||||
if (!(!*cp || (*cp == cDec) || (*cp == _T('E')) || (*cp == _T('e'))))
|
||||
return 0;
|
||||
|
||||
nDp = 0; // length of decimal part
|
||||
if (*cp == cDec) // decimal point
|
||||
{
|
||||
cp++; // skip '.'
|
||||
|
||||
// count decimal part
|
||||
while (*cp >= _T('0') && *cp <= _T('9'))
|
||||
byNum[nIp + ++nDp] = *cp++ - _T('0');
|
||||
}
|
||||
|
||||
// count number of heading zeros in mantissa
|
||||
for (i = 0; byNum[i+1] == 0 && i + 1 < nIp + nDp; ++i) { }
|
||||
|
||||
if (i > 0) // have to normalize
|
||||
{
|
||||
INT j;
|
||||
|
||||
nIp -= i; // for later ajust of exponent
|
||||
for (j = 1; j <= nIp + nDp; ++j) // normalize mantissa
|
||||
byNum[j] = byNum[j + i];
|
||||
}
|
||||
|
||||
if(byNum[1] == 0) // number is 0
|
||||
{
|
||||
ZeroMemory(pbyNum,nMantLen + nExpLen + 1);
|
||||
return nMantLen + nExpLen + 1;
|
||||
}
|
||||
|
||||
for (i = nIp + nDp; i < nMantLen;) // fill rest of mantissa with 0
|
||||
byNum[++i] = 0;
|
||||
|
||||
// must be 'E', 'e' or end
|
||||
if (!(!*cp || (*cp == _T('E')) || (*cp == _T('e'))))
|
||||
return 0;
|
||||
|
||||
lExp = 0;
|
||||
if (*cp == _T('E') || *cp == _T('e'))
|
||||
{
|
||||
cp++; // skip 'E'
|
||||
|
||||
i = FALSE; // positive exponent
|
||||
if (*cp == _T('-') || *cp == _T('+'))
|
||||
{
|
||||
i = (*cp++ == _T('-')); // adjust exponent sign
|
||||
}
|
||||
|
||||
// exponent symbol must be followed by number
|
||||
if (*cp < _T('0') || *cp > _T('9')) return 0;
|
||||
|
||||
while (*cp >= _T('0') && *cp <= _T('9'))
|
||||
lExp = lExp * 10 + *cp++ - _T('0');
|
||||
|
||||
if(i) lExp = -lExp;
|
||||
}
|
||||
|
||||
if (*cp != 0) return 0;
|
||||
|
||||
// adjust exponent value with exponent from normalized mantissa
|
||||
lExp += nIp - 1;
|
||||
|
||||
// calculate max. posive exponent
|
||||
for (nMaxExp = 5, i = 1; i < nExpLen; ++i)
|
||||
nMaxExp *= 10;
|
||||
|
||||
// check range of exponent
|
||||
if ((lExp < 0 && -lExp >= nMaxExp) || (lExp >= nMaxExp))
|
||||
return 0;
|
||||
|
||||
if (lExp < 0) lExp += 2 * nMaxExp; // adjust negative offset
|
||||
|
||||
for (i = nExpLen; i > 0; --i) // convert number into digits
|
||||
{
|
||||
byNum[nMantLen + i] = lExp % 10;
|
||||
lExp /= 10;
|
||||
}
|
||||
|
||||
// copy to target in reversed order
|
||||
for (i = nMantLen + nExpLen; i >= 0; --i)
|
||||
*pbyNum++ = byNum[i];
|
||||
|
||||
return nMantLen + nExpLen + 1;
|
||||
}
|
||||
|
||||
//################
|
||||
//#
|
||||
//# Object subroutines
|
||||
//#
|
||||
//################
|
||||
|
||||
#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
|
||||
// GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_SDECIMAL,&cDecimal,1);
|
||||
|
||||
return RPL_GetSystemFlag(fnRadix) ? _T(',') : _T('.');
|
||||
}
|
||||
|
||||
static INT DoInt(DWORD dwAddress,LPTSTR cp,INT nSize)
|
||||
{
|
||||
LPBYTE lpbyData;
|
||||
INT nLength,nIntLen;
|
||||
|
||||
nIntLen = Read5(dwAddress) - 5; // no. of digits
|
||||
if (nIntLen <= 0) return 0; // error in calculator object
|
||||
|
||||
nLength = 0;
|
||||
if ((lpbyData = HeapAlloc(hHeap,0,nIntLen)))
|
||||
{
|
||||
// get precisition integer object content and decode it
|
||||
Npeek(lpbyData,dwAddress+5,nIntLen);
|
||||
nLength = RPL_GetZInt(lpbyData,nIntLen,cp,nSize);
|
||||
HeapFree(hHeap,0,lpbyData);
|
||||
}
|
||||
return nLength;
|
||||
}
|
||||
|
||||
static INT DoReal(DWORD dwAddress,LPTSTR cp,INT nSize)
|
||||
{
|
||||
BYTE byNumber[16];
|
||||
|
||||
// get real object content and decode it
|
||||
Npeek(byNumber,dwAddress,ARRAYSIZEOF(byNumber));
|
||||
return RPL_GetBcd(byNumber,12,3,GetRadix(),cp,nSize);
|
||||
}
|
||||
|
||||
|
||||
//################
|
||||
//#
|
||||
//# Stack routines
|
||||
//#
|
||||
//################
|
||||
|
||||
//
|
||||
// ID_STACK_COPY
|
||||
//
|
||||
LRESULT OnStackCopy(VOID) // copy data from stack
|
||||
{
|
||||
TCHAR cBuffer[128];
|
||||
HANDLE hClipObj;
|
||||
LPBYTE lpbyData;
|
||||
DWORD dwAddress,dwObject,dwSize;
|
||||
UINT uClipboardFormat;
|
||||
|
||||
_ASSERT(nState == SM_RUN); // emulator must be in RUN state
|
||||
if (WaitForSleepState()) // wait for cpu SHUTDN then sleep state
|
||||
{
|
||||
InfoMessage(_T("The emulator is busy."));
|
||||
return 0;
|
||||
}
|
||||
|
||||
_ASSERT(nState == SM_SLEEP);
|
||||
|
||||
if ((dwAddress = RPL_Pick(1)) == 0) // pick address of level1 object
|
||||
{
|
||||
MessageBeep(MB_OK); // error beep
|
||||
goto error;
|
||||
}
|
||||
|
||||
switch (dwObject = Read5(dwAddress)) // select object
|
||||
{
|
||||
case DOINT: // Precision Integer (HP49G)
|
||||
case DOREAL: // real object
|
||||
dwAddress += 5; // object content
|
||||
|
||||
switch (dwObject)
|
||||
{
|
||||
case DOINT: // Precision Integer (HP49G)
|
||||
// get precision integer object content and decode it
|
||||
dwSize = DoInt(dwAddress,cBuffer,ARRAYSIZEOF(cBuffer));
|
||||
break;
|
||||
case DOREAL: // real object
|
||||
// get real object content and decode it
|
||||
dwSize = DoReal(dwAddress,cBuffer,ARRAYSIZEOF(cBuffer));
|
||||
break;
|
||||
}
|
||||
|
||||
// calculate buffer size
|
||||
dwSize = (dwSize + 1) * sizeof(*cBuffer);
|
||||
|
||||
// memory allocation for clipboard data
|
||||
if ((hClipObj = GlobalAlloc(GMEM_MOVEABLE,dwSize)) == NULL)
|
||||
goto error;
|
||||
|
||||
if ((lpbyData = GlobalLock(hClipObj)))
|
||||
{
|
||||
// copy data to memory
|
||||
CopyMemory(lpbyData,cBuffer,dwSize);
|
||||
GlobalUnlock(hClipObj); // unlock memory
|
||||
}
|
||||
|
||||
#if defined _UNICODE
|
||||
uClipboardFormat = CF_UNICODETEXT;
|
||||
#else
|
||||
uClipboardFormat = CF_TEXT;
|
||||
#endif
|
||||
break;
|
||||
case DOCSTR: // string
|
||||
dwAddress += 5; // address of string length
|
||||
dwSize = (Read5(dwAddress) - 5) / 2; // length of string
|
||||
|
||||
// memory allocation for clipboard data
|
||||
if ((hClipObj = GlobalAlloc(GMEM_MOVEABLE,dwSize + 1)) == NULL)
|
||||
goto error;
|
||||
|
||||
if ((lpbyData = GlobalLock(hClipObj))) // lock memory
|
||||
{
|
||||
// copy data into clipboard buffer
|
||||
for (dwAddress += 5;dwSize-- > 0;dwAddress += 2,++lpbyData)
|
||||
*lpbyData = Read2(dwAddress);
|
||||
*lpbyData = 0; // set EOS
|
||||
|
||||
GlobalUnlock(hClipObj); // unlock memory
|
||||
uClipboardFormat = CF_TEXT; // always text
|
||||
}
|
||||
break;
|
||||
default:
|
||||
MessageBeep(MB_OK); // error beep
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (OpenClipboard(hWnd))
|
||||
{
|
||||
if (EmptyClipboard())
|
||||
SetClipboardData(uClipboardFormat,hClipObj);
|
||||
else
|
||||
GlobalFree(hClipObj);
|
||||
CloseClipboard();
|
||||
}
|
||||
else // clipboard open failed
|
||||
{
|
||||
GlobalFree(hClipObj);
|
||||
}
|
||||
|
||||
error:
|
||||
SwitchToState(SM_RUN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// ID_STACK_PASTE
|
||||
//
|
||||
LRESULT OnStackPaste(VOID) // paste data to stack
|
||||
{
|
||||
#if defined _UNICODE
|
||||
#define CF_TEXTFORMAT CF_UNICODETEXT
|
||||
#else
|
||||
#define CF_TEXTFORMAT CF_TEXT
|
||||
#endif
|
||||
|
||||
HANDLE hClipObj;
|
||||
|
||||
BOOL bSuccess = FALSE;
|
||||
|
||||
// check if clipboard format is available
|
||||
if (!IsClipboardFormatAvailable(CF_TEXTFORMAT))
|
||||
{
|
||||
MessageBeep(MB_OK); // error beep
|
||||
return 0;
|
||||
}
|
||||
|
||||
SuspendDebugger(); // suspend debugger
|
||||
bDbgAutoStateCtrl = FALSE; // disable automatic debugger state control
|
||||
|
||||
// calculator off, turn on
|
||||
if (!(Chipset.IORam[BITOFFSET]&DON))
|
||||
{
|
||||
KeyboardEvent(TRUE,0,0x8000);
|
||||
KeyboardEvent(FALSE,0,0x8000);
|
||||
|
||||
// wait for sleep mode
|
||||
while(Chipset.Shutdn == FALSE) Sleep(0);
|
||||
}
|
||||
|
||||
_ASSERT(nState == SM_RUN); // emulator must be in RUN state
|
||||
if (WaitForSleepState()) // wait for cpu SHUTDN then sleep state
|
||||
{
|
||||
InfoMessage(_T("The emulator is busy."));
|
||||
goto cancel;
|
||||
}
|
||||
|
||||
_ASSERT(nState == SM_SLEEP);
|
||||
|
||||
if (OpenClipboard(hWnd))
|
||||
{
|
||||
if ((hClipObj = GetClipboardData(CF_TEXTFORMAT)))
|
||||
{
|
||||
LPCTSTR lpstrClipdata;
|
||||
LPBYTE lpbyData;
|
||||
|
||||
if ((lpstrClipdata = GlobalLock(hClipObj)))
|
||||
{
|
||||
BYTE byNumber[128];
|
||||
DWORD dwAddress;
|
||||
INT s;
|
||||
|
||||
do
|
||||
{
|
||||
// HP49G in exact mode
|
||||
if (cCurrentRomType == 'X' && !RPL_GetSystemFlag(fnApprox))
|
||||
{
|
||||
// try to convert string to HP49 precision integer
|
||||
s = RPL_SetZInt(lpstrClipdata,byNumber,sizeof(byNumber));
|
||||
|
||||
if (s > 0) // is a real number for exact mode
|
||||
{
|
||||
// get TEMPOB memory for HP49 precision integer object
|
||||
dwAddress = RPL_CreateTemp(s+5+5);
|
||||
if ((bSuccess = (dwAddress > 0)))
|
||||
{
|
||||
Write5(dwAddress,DOINT); // prolog
|
||||
Write5(dwAddress+5,s+5); // size
|
||||
Nwrite(byNumber,dwAddress+10,s); // data
|
||||
|
||||
// push object to stack
|
||||
RPL_Push(dwAddress);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// try to convert string to real format
|
||||
s = RPL_SetBcd(lpstrClipdata,12,3,GetRadix(),byNumber,sizeof(byNumber));
|
||||
|
||||
if (s > 0) // is a real number
|
||||
{
|
||||
// get TEMPOB memory for real object
|
||||
dwAddress = RPL_CreateTemp(16+5);
|
||||
if ((bSuccess = (dwAddress > 0)))
|
||||
{
|
||||
Write5(dwAddress,DOREAL); // prolog
|
||||
Nwrite(byNumber,dwAddress+5,s); // data
|
||||
|
||||
// push object to stack
|
||||
RPL_Push(dwAddress);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// any other format
|
||||
{
|
||||
DWORD dwSize = lstrlen(lpstrClipdata);
|
||||
if ((lpbyData = HeapAlloc(hHeap,0,dwSize * 2)))
|
||||
{
|
||||
#if defined _UNICODE
|
||||
// copy data UNICODE -> ASCII
|
||||
WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK,
|
||||
lpstrClipdata, dwSize,
|
||||
lpbyData+dwSize, dwSize, NULL, NULL);
|
||||
#else
|
||||
// copy data
|
||||
memcpy(lpbyData+dwSize,lpstrClipdata,dwSize);
|
||||
#endif
|
||||
bSuccess = (WriteStack(lpbyData,dwSize) == S_ERR_NO);
|
||||
HeapFree(hHeap,0,lpbyData);
|
||||
}
|
||||
}
|
||||
}
|
||||
while(FALSE);
|
||||
|
||||
GlobalUnlock(hClipObj);
|
||||
}
|
||||
}
|
||||
CloseClipboard();
|
||||
}
|
||||
|
||||
SwitchToState(SM_RUN); // run state
|
||||
while (nState!=nNextState) Sleep(0);
|
||||
_ASSERT(nState == SM_RUN);
|
||||
|
||||
if (bSuccess == FALSE) // data not copied
|
||||
goto cancel;
|
||||
|
||||
KeyboardEvent(TRUE,0,0x8000);
|
||||
KeyboardEvent(FALSE,0,0x8000);
|
||||
|
||||
// wait for sleep mode
|
||||
while(Chipset.Shutdn == FALSE) Sleep(0);
|
||||
|
||||
cancel:
|
||||
bDbgAutoStateCtrl = TRUE; // enable automatic debugger state control
|
||||
ResumeDebugger();
|
||||
return 0;
|
||||
#undef CF_TEXTFORMAT
|
||||
}
|
|
@ -108,9 +108,8 @@ static VOID CheckT1(BYTE nT1)
|
|||
|
||||
_ASSERT((nT1&8) != 0); // timer1 MSB set
|
||||
|
||||
// timer MSB is one and either INT or WAKE is set
|
||||
if ( (Chipset.IORam[TIMER1_CTRL]&WKE)
|
||||
|| (Chipset.IORam[TIMER1_CTRL]&INTR))
|
||||
// timer MSB and INT or WAKE bit is set
|
||||
if ((Chipset.IORam[TIMER1_CTRL]&(WKE|INTR)) != 0)
|
||||
Chipset.IORam[TIMER1_CTRL] |= SRQ; // set SRQ
|
||||
// cpu not sleeping and T1 -> Interrupt
|
||||
if ( (!Chipset.Shutdn || (Chipset.IORam[TIMER1_CTRL]&WKE))
|
||||
|
@ -143,9 +142,8 @@ static VOID CheckT2(DWORD dwT2)
|
|||
|
||||
_ASSERT((dwT2&0x80000000) != 0); // timer2 MSB set
|
||||
|
||||
// timer MSB is one and either INT or WAKE is set
|
||||
if ( (Chipset.IORam[TIMER2_CTRL]&WKE)
|
||||
|| (Chipset.IORam[TIMER2_CTRL]&INTR))
|
||||
// timer MSB and INT or WAKE bit is set
|
||||
if ((Chipset.IORam[TIMER2_CTRL]&(WKE|INTR)) != 0)
|
||||
Chipset.IORam[TIMER2_CTRL] |= SRQ; // set SRQ
|
||||
// cpu not sleeping and T2 -> Interrupt
|
||||
if ( (!Chipset.Shutdn || (Chipset.IORam[TIMER2_CTRL]&WKE))
|
||||
|
@ -185,7 +183,7 @@ static VOID RescheduleT2(BOOL bRefPoint)
|
|||
uDelay = __max(tc.wPeriodMin,uDelay); // wait minimum delay of timer
|
||||
_ASSERT(uDelay <= tc.wPeriodMax); // inside maximum event delay
|
||||
// start timer2; schedule event, when Chipset.t2 will be zero
|
||||
VERIFY(uT2TimerId = timeSetEvent(uDelay,0,(LPTIMECALLBACK)&TimeProc,2,TIME_ONESHOT));
|
||||
VERIFY(uT2TimerId = timeSetEvent(uDelay,0,&TimeProc,2,TIME_ONESHOT));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -323,7 +321,7 @@ VOID StartTimers(VOID)
|
|||
// set timer resolution to greatest possible one
|
||||
bAccurateTimer = (timeBeginPeriod(tc.wPeriodMin) == TIMERR_NOERROR);
|
||||
// set timer1 with given period
|
||||
VERIFY(uT1TimerId = timeSetEvent(T1_FREQ,0,(LPTIMECALLBACK)&TimeProc,1,TIME_PERIODIC));
|
||||
VERIFY(uT1TimerId = timeSetEvent(T1_FREQ,0,&TimeProc,1,TIME_PERIODIC));
|
||||
RescheduleT2(TRUE); // start timer2
|
||||
}
|
||||
return;
|
||||
|
@ -398,20 +396,32 @@ BYTE ReadT1(VOID)
|
|||
|
||||
VOID SetT1(BYTE byValue)
|
||||
{
|
||||
BOOL bEqual;
|
||||
|
||||
_ASSERT(byValue < 0x10); // timer1 is only a 4bit counter
|
||||
|
||||
if (Chipset.t1 == byValue) // same value doesn't restart timer period
|
||||
return;
|
||||
EnterCriticalSection(&csT1Lock);
|
||||
{
|
||||
bEqual = (Chipset.t1 == byValue); // check for same value
|
||||
}
|
||||
LeaveCriticalSection(&csT1Lock);
|
||||
if (bEqual) return; // same value doesn't restart timer period
|
||||
|
||||
if (uT1TimerId != 0) // timer1 running
|
||||
{
|
||||
timeKillEvent(uT1TimerId); // stop timer1
|
||||
uT1TimerId = 0; // set flag timer1 stopped
|
||||
}
|
||||
EnterCriticalSection(&csT1Lock);
|
||||
{
|
||||
Chipset.t1 = byValue; // set new timer1 value
|
||||
CheckT1(Chipset.t1); // test timer1 control bits
|
||||
}
|
||||
LeaveCriticalSection(&csT1Lock);
|
||||
if (bStarted) // timer running
|
||||
{
|
||||
// restart timer1 to get full period of frequency
|
||||
VERIFY(uT1TimerId = timeSetEvent(T1_FREQ,0,(LPTIMECALLBACK)&TimeProc,1,TIME_PERIODIC));
|
||||
VERIFY(uT1TimerId = timeSetEvent(T1_FREQ,0,&TimeProc,1,TIME_PERIODIC));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ BEGIN
|
|||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 160
|
||||
TOPMARGIN, 4
|
||||
BOTTOMMARGIN, 210
|
||||
BOTTOMMARGIN, 256
|
||||
END
|
||||
|
||||
IDD_CHOOSEKML, DIALOG
|
||||
|
@ -232,15 +232,15 @@ BEGIN
|
|||
ES_READONLY
|
||||
END
|
||||
|
||||
IDD_SETTINGS DIALOG DISCARDABLE 0, 0, 167, 229
|
||||
IDD_SETTINGS DIALOG DISCARDABLE 0, 0, 167, 263
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Settings"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
CONTROL "Authentic Calculator Speed",IDC_REALSPEED,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,13,13,100,10
|
||||
CONTROL "Enable Virtual LCD Delay",IDC_GRAYSCALE,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,25,100,10
|
||||
CONTROL "Enable Virtual LCD Delay",IDC_GRAYSCALE,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,13,25,100,10
|
||||
CONTROL "Automatically Save Files",IDC_AUTOSAVE,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,13,37,89,10
|
||||
CONTROL "Automatically Save Files On Exit",IDC_AUTOSAVEONEXIT,
|
||||
|
@ -255,25 +255,35 @@ BEGIN
|
|||
CONTROL "Class Mnemonics",IDC_DISASM_CLASS,"Button",
|
||||
BS_AUTORADIOBUTTON,84,101,70,11
|
||||
GROUPBOX "Disassembler",IDC_STATIC,7,90,153,28
|
||||
LTEXT "Volume",IDC_STATIC,13,134,24,8
|
||||
CONTROL "Slider1",IDC_SOUND_SLIDER,"msctls_trackbar32",
|
||||
TBS_AUTOTICKS | WS_TABSTOP,39,129,68,18
|
||||
CONTROL "Speaker",IDC_SOUND_SPEAKER,"Button",BS_AUTORADIOBUTTON |
|
||||
WS_GROUP | WS_TABSTOP,111,128,43,10
|
||||
CONTROL "Wave",IDC_SOUND_WAVE,"Button",BS_AUTORADIOBUTTON,111,
|
||||
139,43,10
|
||||
GROUPBOX "Sound",IDC_STATIC,7,120,153,34
|
||||
CONTROL "Port 1 is Plugged",IDC_PORT1EN,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,13,131,67,10
|
||||
WS_TABSTOP,13,165,67,10
|
||||
CONTROL "Port 1 is Writeable",IDC_PORT1WR,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,84,131,69,10
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,84,165,69,10
|
||||
CONTROL "Port 2 is Shared",IDC_PORT2ISSHARED,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,13,143,65,10
|
||||
LTEXT "Port 2 File :",IDC_STATIC,13,159,37,8
|
||||
EDITTEXT IDC_PORT2,51,156,94,12,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "...",IDC_PORT2LOAD,145,156,10,12
|
||||
GROUPBOX "Memory Cards",IDC_STATIC,7,122,153,51
|
||||
LTEXT "Wire:",IDC_STATIC,13,188,17,8
|
||||
COMBOBOX IDC_WIRE,31,186,48,42,CBS_DROPDOWNLIST | WS_VSCROLL |
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,13,177,65,10
|
||||
CONTROL "Port 2 is Writeable",IDC_PORT2WR,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,84,177,69,10
|
||||
LTEXT "Port 2 File :",IDC_STATIC,13,192,37,8
|
||||
EDITTEXT IDC_PORT2,51,190,94,12,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "...",IDC_PORT2LOAD,145,190,10,12
|
||||
GROUPBOX "Memory Cards",IDC_STATIC,7,156,153,51
|
||||
LTEXT "Wire:",IDC_STATIC,13,221,17,8
|
||||
COMBOBOX IDC_WIRE,31,219,48,42,CBS_DROPDOWNLIST | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
LTEXT "IR:",IDC_STATIC,89,188,9,8
|
||||
COMBOBOX IDC_IR,107,186,48,43,CBS_DROPDOWNLIST | WS_VSCROLL |
|
||||
LTEXT "IR:",IDC_STATIC,89,221,9,8
|
||||
COMBOBOX IDC_IR,107,219,48,43,CBS_DROPDOWNLIST | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
GROUPBOX "Serial Ports",IDC_STATIC,7,176,153,27
|
||||
DEFPUSHBUTTON "&Ok",IDOK,9,208,50,14
|
||||
PUSHBUTTON "&Cancel",IDCANCEL,107,208,50,14
|
||||
GROUPBOX "Serial Ports",IDC_STATIC,7,209,153,27
|
||||
DEFPUSHBUTTON "&Ok",IDOK,9,242,50,14
|
||||
PUSHBUTTON "&Cancel",IDCANCEL,107,242,50,14
|
||||
END
|
||||
|
||||
IDD_CHOOSEKML DIALOG DISCARDABLE 0, 0, 195, 66
|
||||
|
@ -566,8 +576,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,3,7,0
|
||||
PRODUCTVERSION 1,3,7,0
|
||||
FILEVERSION 1,4,0,0
|
||||
PRODUCTVERSION 1,4,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -584,12 +594,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "Sebastien Carlier & Christoph Gießelink\0"
|
||||
VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0"
|
||||
VALUE "FileVersion", "1, 3, 7, 0\0"
|
||||
VALUE "FileVersion", "1, 4, 0, 0\0"
|
||||
VALUE "InternalName", "Emu48\0"
|
||||
VALUE "LegalCopyright", "Copyright © 2005\0"
|
||||
VALUE "OriginalFilename", "Emu48.exe\0"
|
||||
VALUE "ProductName", "Emu48\0"
|
||||
VALUE "ProductVersion", "1, 3, 7, 0\0"
|
||||
VALUE "ProductVersion", "1, 4, 0, 0\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
@ -634,9 +644,9 @@ BEGIN
|
|||
MENUITEM "&Load Object...", ID_OBJECT_LOAD
|
||||
MENUITEM "&Save Object...", ID_OBJECT_SAVE
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Copy String", ID_STACK_COPY
|
||||
MENUITEM "C&opy Screen", ID_VIEW_COPY
|
||||
MENUITEM "&Paste String", ID_STACK_PASTE
|
||||
MENUITEM "&Copy Stack", ID_STACK_COPY
|
||||
MENUITEM "&Paste Stack", ID_STACK_PASTE
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Reset Calculator", ID_VIEW_RESET, GRAYED
|
||||
POPUP "&Backup"
|
||||
|
@ -783,6 +793,18 @@ END
|
|||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Accelerator
|
||||
//
|
||||
|
||||
IDR_MENU ACCELERATORS DISCARDABLE
|
||||
BEGIN
|
||||
"C", ID_STACK_COPY, VIRTKEY, CONTROL, NOINVERT
|
||||
"V", ID_STACK_PASTE, VIRTKEY, CONTROL, NOINVERT
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
|
|
|
@ -24,7 +24,8 @@ RSRCOBJ=$(PRJ).o
|
|||
|
||||
OBJS=cursor.o disasm.o display.o debugger.o ddeserv.o \
|
||||
emu48.o engine.o external.o fetch.o files.o i28f160.o keyboard.o \
|
||||
keymacro.o kml.o mops.o opcodes.o rpl.o serial.o settings.o timer.o \
|
||||
keymacro.o kml.o mops.o opcodes.o rpl.o serial.o settings.o stack.o \
|
||||
timer.o \
|
||||
$(RSRCOBJ)
|
||||
|
||||
LIBS=-lwinmm -lcomctl32
|
||||
|
@ -111,6 +112,9 @@ 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
|
||||
|
||||
stack.o: stack.c pch.h resource.h Emu48.h io.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o stack.o stack.c
|
||||
|
||||
timer.o: timer.c pch.h emu48.h types.h io.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o timer.o timer.c
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <direct.h>
|
||||
#include <conio.h>
|
||||
// #include <crtdbg.h> // missing file
|
||||
|
||||
#if !defined VERIFY
|
||||
|
|
|
@ -29,7 +29,7 @@ or
|
|||
MinGW-3.1.0-1.exe
|
||||
w32api-3.3.tar.gz
|
||||
mingw-runtime-3.8.tar.gz
|
||||
binutils-2.15.94-20050118-1.tar.gz
|
||||
binutils-2.16.91-20050827-1.tar.gz
|
||||
gcc-core-3.4.4-20050522-1.tar.gz
|
||||
|
||||
Older versions of the MinGW package might not work, because there are several
|
||||
|
@ -43,4 +43,4 @@ Many thanks to Pedro A. Arranda Guti
|
|||
compatible.
|
||||
|
||||
|
||||
08/22/05 (c) by Christoph Gießelink
|
||||
12/05/05 (c) by Christoph Gießelink
|
||||
|
|
BIN
uninst.exe
BIN
uninst.exe
Binary file not shown.
Loading…
Reference in a new issue