diff --git a/DEBUGGER.TXT b/DEBUGGER.TXT index d09e7b2..f48cdf9 100644 --- a/DEBUGGER.TXT +++ b/DEBUGGER.TXT @@ -301,9 +301,17 @@ CE1 | nc. | BS | Slt1 32/128KB | BS | BS CE2 | nc. | nc. | Slt2 32/128KB | Slt1 32/128KB | RAM 128KB NCE3 | nc. | RAM 128KB | nc. | Slt2 32KB-4MB | RAM 128KB +- Load Memory Data... + +The "Load Memory Data" dialog box allows loading memory dump files to the specified address inside the Saturn address area. The specified address must point to RAM, writing into ROM areas isn't possible. The memory dump file must be in packed data format, meaning each byte in file contain two Saturn data nibbles with the low nibble containing the even and the high nibble the following odd address. The disadvantage of packed files is that you cannot load memory files with an odd number of data nibbles, but the advantage is that you can directly load an assembler output to memory. + +- Save Memory Data... + +The "Save Memory Data" dialog box allows saving the data of the specified Saturn address area into a memory dump file. The memory dump file contain the data in packed data format, meaning each byte in file contain two Saturn data nibbles with the low nibble containing the even and the high nibble the following odd address. + - RPL Object Viewer... -This opens a small toolbox window showing the decompiled RPL object at the memory address marked by the cursor. If the toolbox window is already open the content will be updated. There's a problem if you want to select an address inside the marked two addresses. The easiest way to switch the address is the use of the + and - keys changing the memory position by one nibble under the cursor. +This opens a small toolbox window showing the decompiled RPL object in the selected memory map mode at the memory address marked by the cursor. If the toolbox window is already open the content will be updated. There's a problem if you want to select an address inside the marked two addresses. The easiest way to switch the address is the use of the + and - keys changing the memory position by one nibble under the cursor. 9.) Stack window @@ -346,4 +354,4 @@ The Miscellaneous window show you the internal state of the interrupt flag, the You can change the values by pressing the left mouse button over the old content. -04/04/09 (c) by Christoph Gießelink +05/02/12 (c) by Christoph Gießelink diff --git a/EMU48.EXE b/EMU48.EXE new file mode 100644 index 0000000..2f613a5 Binary files /dev/null and b/EMU48.EXE differ diff --git a/EMU48.dll b/EMU48.dll new file mode 100644 index 0000000..697ea62 Binary files /dev/null and b/EMU48.dll differ diff --git a/EMU48PLUS.TXT b/EMU48PLUS.TXT index f7910d9..c41e7a9 100644 --- a/EMU48PLUS.TXT +++ b/EMU48PLUS.TXT @@ -1,4 +1,4 @@ -Emu48 1.48+ (based on Emu48 1.50) +Emu48 1.52+ (based on Emu48 1.53) Emu48+ is a modified version of Emu48 to add support for the ARM-based calculators. It does not emulate the ARM CPU, but it enhances the diff --git a/Emu48.dll b/Emu48.dll deleted file mode 100644 index e204fb4..0000000 Binary files a/Emu48.dll and /dev/null differ diff --git a/Emu48.exe b/Emu48.exe deleted file mode 100644 index 4b44b5a..0000000 Binary files a/Emu48.exe and /dev/null differ diff --git a/PROBLEMS.TXT b/PROBLEMS.TXT index b8a2f51..22c63b7 100644 --- a/PROBLEMS.TXT +++ b/PROBLEMS.TXT @@ -1,4 +1,4 @@ -Known bugs and restrictions of Emu48 V1.50 +Known bugs and restrictions of Emu48 V1.53 ------------------------------------------ - the following I/O bits aren't emulated (incomplete) @@ -12,8 +12,7 @@ Known bugs and restrictions of Emu48 V1.50 SRQ1 (0x118) [ISQR] SRQ2 (0x119) [LSRQ] IRC (0x11A) [IRI EIRU EIRI IRE] - LCR (0x11C) [LED ELBE LBZ LBF] - LBR (0x11D) [LBO] + LCR (0x11C) [LBZ LBF] - the baudrates 1920, 3840, 7680 and 15360 aren't emulated on most operating systems Windows 95a 1920, 3840, 7680 work, 15360 fail @@ -41,7 +40,6 @@ Known bugs and restrictions of Emu48 V1.50 - 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 -- no infrared printer support - Shell OS: clock isn't synchronized with real time - HP49G: the flash memory is emulated now with some restrictions - no flash programming times, the flash state machine returns @@ -52,4 +50,4 @@ Known bugs and restrictions of Emu48 V1.50 - quitting the emulator while programming the flash isn't allowed, because the content of flash state machine isn't saved so far -07/27/10 (c) by Christoph Gießelink, c dot giesselink at gmx dot de +08/07/12 (c) by Christoph Gießelink, c dot giesselink at gmx dot de diff --git a/source/APPLE.C b/source/source/APPLE.C similarity index 94% rename from source/APPLE.C rename to source/source/APPLE.C index 169bcce..aca09c2 100644 --- a/source/APPLE.C +++ b/source/source/APPLE.C @@ -259,6 +259,21 @@ VOID o80B24(VOID) return; } +// OUTBYT +VOID o80B65(VOID) +{ + // set Transmitting annunciator + BYTE byAnn = w.IORam[ANNCTRL+1] | 0x2; + WriteIO(&byAnn,ANNCTRL+1,1); + + SendByteUdp((BYTE) Npack(w.A,2)); // send data byte + + w.P = 0; + PCHANGED; + w.carry = FALSE; // no error + return; +} + // CdB for HP: add apples BUSCC commands VOID o80BExt(LPBYTE I) // Saturnator extentions { @@ -330,7 +345,7 @@ VOID o80BExt(LPBYTE I) // Saturnator extentions // case 0x43: ??? // format flash bank case 0x50: break; // REMON not implemented case 0x51: break; // REMOFF not implemented - case 0x56: break; // OUTBYT not implemented + case 0x56: o80B65(); break; // OUTBYT case 0x57: w.D[0]= w.D[1]= 0; break; case 0x60: break; // ACCESSSD not implemented case 0x61: break; // PORTTAG? not implemented diff --git a/source/APPLE.H b/source/source/APPLE.H similarity index 100% rename from source/APPLE.H rename to source/source/APPLE.H diff --git a/source/CHANGES.TXT b/source/source/CHANGES.TXT similarity index 87% rename from source/CHANGES.TXT rename to source/source/CHANGES.TXT index 340ff2d..a387e22 100644 --- a/source/CHANGES.TXT +++ b/source/source/CHANGES.TXT @@ -1,4 +1,412 @@ -------------------------------------------------------------------- +Service Pack 53 for Emu48 Version 1.0 + +DEBUGGER.C +- changed function OnFindOK(), added downwards search direction +- changed function Find(), added and changed message handler for the + "Previous" and "Next" buttons + +EMU48.RC +- changed IDD_FIND, added a "Previous" button for previous search, + shorten the text of the "Find Next" button to "Next" and changed + the ID of the next search button +- changed version + +FILES.C +- changed function SaveBackup() and RestoreBackup(), improved + document available detection and added check at port data copy if + port source buffer is allocated + +KML.C +- added global variable wKeybLocId to hold the keyboard layout input + locale at begin of KML loading +- changed function ParseBlocks(), use variable wKeybLocId instead + of input locale reading +- changed function KillKML(), added reset of variable wKeybLocId +- bugfix in function InitKML(), changed implementation by reading + the current keyboard layout and convert the layout data to the + input locale setting + +RESOURCE.H +- added definitions +- removed IDC_FIND_CASE + + +Service Pack 52 for Emu48 Version 1.0 + +EMU48.C +- changed function SettingsProc(), added infrared printer settings + +EMU48.DSP +- added redeye.c and udp.c sources +- added library Ws2_32.lib + +EMU48.H +- extern declaration of global variables and functions + +EMU48.RC +- changed version and copyright + +EMU48DLL.C +- added function DllMain(), implemented "CEmu48" window class + registration and unregistration in process attach and detach + especially for dynamic DLL load with LoadLibrary() and + FreeLibrary() +- bugfix in function DLLCreateWnd(), moved "CEmu48" window class + registration to DllMain(), so it's now possible to unregister + the window class automatically at DLL detach + +KML.C +- added global variable bLocaleInc for checking if locale block + content already included +- added keyword "Locale" to pLexToken[] and token TOK_LOCALE to + eIsGlobalBlock[] table +- changed function ParseLine() and ParseBlock(), preset szLexString + variable with NULL after freeing +- changed function IncludeLines() and IncludeBlocks(), changed + function prototype by adding a boolean argument for selecting the + text message "Including" or "Parsing" in the log file +- bugfix in function ParseLines(), return a TOK_NONE line for an + empty block instead of a NULL pointer which regular stands for a + syntax error +- bugfix in function ParseLines() and ParseBlocks(), changed + function prototype by adding a boolean argument for selecting the + mode "include" or "parse" for the next lines or blocks and + verifying the "Include" argument was incomplete and may caused + memory leaks at error condition +- bugfix in function ParseBlock(), verifying the block commmand + argument was incomplete and may caused a memory leak at error + condition +- changed function ParseBlocks(), changed function prototype by + adding a boolean argument if an "End" token is also valid and + added implementation of block "Locale" +- changed function KillKML(), added reset of variable bLocaleInc +- changed function ReleaseButton(), for speed optimization skip + function if button is already released +- bugfix in function LoadKMLGlobal(), fixed a memory leak caused by + the error condition that expected block command is a string +- changed function InitKML(), added current keyboard input locale + setting log file text + +KML.H +- added TOK_LOCALE definition + +MOPS.C +- bugfix in function WriteIO(), removed implementation of the ELBE + bit in the LCR (0x11C) register for apples; the Saturnator has no + ELBE bit simulation so the LSRQ bit in SRQ2 register is untouched + +REDEYE.C +- new module for decoding the redeye data stream for a HP82240B + printer + +RESOURCE.H +- added some definitions + +SETTINGS.C +- changed function ReadSettings() and WriteSettings(), added the + items "Address" and "Port" in section [IrPrinter] in the INI-File + +TIMER.C +- changed function SetHP48Time(), time calculation now work properly + for host system dates before 1970/01/01 and after 2106/02/07 + +UDP.C +- new module for sending a byte over UDP + + +Service Pack 51 for Emu48 Version 1.0 + +DEBUGGER.C +- removed structure MODEL_MAP_T, variables pbyNoMEM, MemMap[], + pbyMapData, dwMapDataSize and pMapping, the implementation behind + moved to module DISMEM.C +- changed function SetMappingMenu(), changed to DISMEM.C + implementation and added control of memory data menu items +- changed function GetMemCurAddr(), OnMemGoAdr(), OnKeyUpDown() and + OnKeyPlusMinus(), variable dwMapDataSize isn't global any more, + use function GetMemDataMask() instead +- changed function InitMemMap(), ViewMemWnd() and OnFindOK(), + changed to DISMEM.C implementation +- changed function ViewCodeWnd(), set disassembler to memory mapped + mode +- bugfix in function OnDblClick(), added update of code window +- changed function Debugger(), changed disassembler mode setting and + added calls of "Load Memory Data..." and "Save Memory Data..." + handling functions +- added functions OnBrowseLoadMem(), OnBrowseSaveMem(), + LoadMemData(), SaveMemData(), GetAddr(), DebugMemLoad(), + OnMemLoadData(), DebugMemSave() and OnMemSaveData() to handle the + Load/Save Memory Data feature + +DISASM.C +- removed global variable disassembler_map +- removed functions rn_map(), rn_rom(), rn_ram(), rn_port1() and + rn_port2() +- changed function read_nibble(), call function GetMemNib() from the + new module DISMEM.C for mapping mode memory access and made + function static again + +DISMEM.C +- new module for accessing memory data for debug view purpose + +EMU48.C +- changed function Disasm(), replaced the radio button + implementation for the memory mapping mode by a combo box + solution; the combo box solution don't work with the HP48 module + names any more, it now use the memory controller names used in the + debugger memory viewer for a more general approach for the non + HP48 calculator models + +EMU48.DSP +- added dismem.c sources + +EMU48.H +- replaced old "memory module definitions" by the enum MEM_MAPPING +- extern declaration of global functions +- removed extern declaration of global variables + +EMU48.RC +- changed IDD_DISASM dialog, replaced the radio buttons for the + memory mapping mode by a more general combo box +- added dialogs IDD_DEBUG_MEMSAVE and IDD_DEBUG_MEMLOAD +- added "Load Memory Data..." and "Save Memory Data..." menu entries + in debugger "Memory" context menu +- changed version and copyright + +EMU48DLL.C +- bugfix in function DLLCreateWnd(), when starting an emulator + session the function was trying to register the window class, but + with introducíng the ATOM variable the system tells that only the + first registration for the process was successful and so on any + other further registration the content of the ATOM variable + pointing to window class got lost + +KML.C +- bugfix in function ReloadButtons(), ON key button wasn't handled + +RESOURCE.H +- added several definitions +- deleted some radio button definitions from the IDD_DISASM dialog + + +Service Pack 50 for Emu48 Version 1.0 + +APPLE.C +- added BUSCC 56 (opcode 80B65) implementation + +DDESERV.C +- replaced all HeapAlloc() with malloc() memory requests + +DEBUGGER.C +- replaced all HeapAlloc() with malloc() memory requests +- changed function ToggleBreakpoint() and EditBreakpoint(), minor + code optimization purging breakpoint +- changed function ViewMemWnd(), removed initialized but unused + variable +- bugfix in function OnDblClick(), fixed buffer overflow when + converting a 2 byte hexadecimal string to a byte +- bugfix in function LoadBreakpointList(), added check of breakpoint + entries against breakpoint table size + +DISPLAY.C +- changed DIBPIXEL() define, generates the same code on MSVC6.0 but + made it GCC4 compiler compatible + +EMU48.C +- removed global variable hHeap +- replaced all HeapAlloc() with malloc() memory requests +- changed function SaveChanges(), detect if document is available + now over the variable bDocumentAvail and not over the variable + pbyRom any more; in the case of an illegal KML script there maybe + a document loaded, but no ROM image, so pbyRom will be NULL in + this case +- bugfix function OnViewScript(), when quitted the dialog "Choose + Your KML Script" with the Cancel button when chosen an invalid + script the function returned without the possibility of saving the + current document; now the function try to reload the primarily KML + script and if this also fails then the current document is saved +- changed function WinMain(), replaced multiple class name usage + with atom variable, moved read settings before window creation, + added check for setting "SingleInstance" to switch to an already + running program instance instead of creating a new one and added + call of _CrtDumpMemoryLeaks() at end of program to detect malloc() + memory leaks + +EMU48.H +- removed extern declaration of hHeap +- extern declaration of global variables and functions +- replaced all HeapAlloc() with malloc() memory requests + +EMU48.RC +- changed version + +EMU48DLL.C +- changed function DLLCreateWnd(), replaced multiple class name + usage with atom variable and moved read settings before window + creation + +ENGINE.C +- added global variable nOpcSlow to hold the number of CPU opcodes + slowing down the CPU core +- changed function AdjustSpeed(), added CPU opcode slow down + implementation +- added function InitAdjustSpeed(), initialize CPU slow down part + if necessary +- changed function AdjKeySpeed() and SetSpeed(), use function + InitAdjustSpeed() to initialize the CPU slow down variables + +EXTERNAL.C +- replaced all HeapAlloc() with malloc() memory requests + +FILES.C +- replaced all HeapAlloc() with malloc() memory requests +- changed function CrcRom(), if no ROM available return without + modifying the checksum +- changed function ResetDocument(), NewDocument(), OpenDocument() + and RestoreBackup(), added state variable if document is available +- bugfix in function DecodeBmp() and DecodeGif(), a 2nd bitmap load + allocated and bound a 2nd palette to the main window, now only the + 1st bitmap (mostly the KML background bitmap) bound his palette to + the main window + +IO.H +- added LBR and LBO bit definitions + +KEYMACRO.C +- changed function EventThread(), added minimum key hold time for + keyboard macro playing and subtract minimum key hold time from + saved waiting time, this is more accurate when the user has + selected a different minimum key hold time than the default one +- changed function KeyMacroRecord(), now saving the complete waiting + time including the key state holding time, the key state holding + time is now subtract in the player function thread EventThread() +- changed function OnToolMacroNew(), removed adding the key state + holding time to the reference time, this is not necessary any more + +KML.C +- changed table pLexToken[], defined table as constant and changed + last token id table preset from constant number to member of token + id enumerator +- replaced all HeapAlloc() with malloc() memory requests +- bugfix in function ParseString(), decoding the \" sequence as + quotation mark inside a string was incomplete, so every single '\' + character was also removed +- bugfix in function ParseBlock(), string argument wasn't freed in + error case + +MOPS.C +- added function ReadT2Acc(), reading timer2 value with checking for + CPU speed measurement behaviour +- bugfix in function ReadIO(), added implementation of the LED and + ELBE bit in the LCR (0x11C) register and of the LBO bit in the LBR + (0x11D) register +- changed function ReadIO(), the timer2 register content is now read + by function ReadT2Acc() to analyze the read access scheme +- bugfix in function WriteIO(), added implementation of the ELBE bit + in the LCR (0x11C) register and of the LBO bit in the LBR (0x11D) + register + +MRU.C +- replaced all HeapAlloc() with malloc() memory requests +- changed function MruUpdateMenu(), changed variable type of + variable hMenu +- changed function MruReadList(), removed initialized but unused + variable + +RPL.C +- replaced all HeapAlloc() with malloc() memory requests + +SETTINGS.C +- changed function ReadSettings(), moved CPU speed setting to + MainWndProc() +- changed function ReadSettings() and WriteSettings(), added item + "KeyMinDelay" in section [Macro] and added item "SingleInstance" + in section [Emulator] in the INI-File + +STACK.C +- replaced all HeapAlloc() with malloc() memory requests + +SYMBFILE.C +- replaced all HeapAlloc() with malloc() memory requests + + +Service Pack 49 for Emu48 Version 1.0 + +DEBUGGER.C +- changed function Debugger(), removed all UpdateWindowStatus() + function calls + +EMU48.C +- renamed function UpdateWindowStatus() to OnInitMenu() and modified + it to a WM_INITMENU message handler +- changed function OnFileNew() and WinMain(), removed all + UpdateWindowStatus() function calls +- changed function MainWndProc(), added WM_INITMENU message handler + +EMU48.H +- added definitions to detect Apple platform +- removed declaration of global function UpdateWindowStatus() + +EMU48.RC +- changed version and copyright + +ENGINE.C +- changed function SwitchToState(), removed all UpdateWindowStatus() + function calls + +FILES.C +- changed TREENODE structure, added prev element for a double linked + list +- changed function PatchNibble(), added prev element handling +- bugfix in function UpdatePatches(), in the case an address was + patched more than one time, the ROM was patched in wrong order and + moreover the original content of the double defined ROM address + was destroyed +- changed function ResetDocument(), OpenDocument(), + SaveDocumentAs(), SaveBackup(), RestoreBackup() and ResetBackup(), + removed all UpdateWindowStatus() function calls +- bugfix in function OpenDocument(), added check of KML script name + length against target buffer size +- changed function DibNumColors(), changed function prototype from + UINT to WORD return +- changed function CreateBIPalette(), changed variable + UINT nNumColors to WORD wNumColors to avoid variable overflow + loading palNumEntries of LOGPALETTE structure + +KEYMACRO.C +- changed function OnToolMacroNew(), OnToolMacroPlay() and + OnToolMacroStop(), removed all UpdateWindowStatus() function calls + +KML.C +- changed function ParseLines(), BOOL expression was missing in main + while() loop, worked because TOK_NONE is 0 +- changed function KillKML(), removed UpdateWindowStatus() function + call +- changed function LoadKMLGlobal(), used wrong variable type for + variable eToken + +MOPS.C +- changed function ReadIO() and WriteIO(), on Apple hardware the + BAUD (0x10D) register use 4 bits for baud rate setting, the UCK + bit isn't supported on this platform + +OPS.H +- bugfix in function FASTPTR(), longest opcode calculation from + buffer size was wrong, so MMU boundary fixup wasn't working + properly + +SERIAL.C +- changed function CommSetBaud(), expanded dwBaudrates[] table and + enabled the access to these baud rates on the Apple platform + +STACK.C +- bugfix in function RPL_GetBcd(), fixed possible uninitialized + bExpflag variable +- bugfix in function OnStackCopy(), fixed possible uninitialized + uClipboardFormat variable in DOCSTR case + + Service Pack 48 for Emu48 Version 1.0 DEBUGGER.C diff --git a/source/CHECKBOX.BMP b/source/source/CHECKBOX.BMP similarity index 100% rename from source/CHECKBOX.BMP rename to source/source/CHECKBOX.BMP diff --git a/source/COLOR.H b/source/source/COLOR.H similarity index 100% rename from source/COLOR.H rename to source/source/COLOR.H diff --git a/source/CURSOR.C b/source/source/CURSOR.C similarity index 100% rename from source/CURSOR.C rename to source/source/CURSOR.C diff --git a/source/DBGTOOL.BMP b/source/source/DBGTOOL.BMP similarity index 100% rename from source/DBGTOOL.BMP rename to source/source/DBGTOOL.BMP diff --git a/source/DDESERV.C b/source/source/DDESERV.C similarity index 92% rename from source/DDESERV.C rename to source/source/DDESERV.C index 2ced4d3..a2c9e9a 100644 --- a/source/DDESERV.C +++ b/source/source/DDESERV.C @@ -50,7 +50,7 @@ HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv, DdeUnaccessData(hData); // reserve memory - if ((lpData = HeapAlloc(hHeap,0,dwSize * 2)) == NULL) + if ((lpData = malloc(dwSize * 2)) == NULL) return (HDDEDATA) DDE_FNOTPROCESSED; SuspendDebugger(); // suspend debugger @@ -66,7 +66,7 @@ HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv, if (WaitForSleepState()) // wait for cpu SHUTDN then sleep state { - HeapFree(hHeap,0,lpData); // free memory + free(lpData); // free memory hReturn = DDE_FNOTPROCESSED; goto cancel; } @@ -80,7 +80,7 @@ HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv, dwSize = dwIndex; dwSize = DdeGetData(hData,lpData+dwSize,dwSize,sizeof(DWORD)); bSuccess = (WriteStack(nStkLvl,lpData,dwSize) == S_ERR_NO); - HeapFree(hHeap,0,lpData); // free memory + free(lpData); // free memory SwitchToState(SM_RUN); // run state while (nState!=nNextState) Sleep(0); @@ -138,7 +138,7 @@ cancel: dwSize += dwIndex + sizeof(DWORD); // reserve memory - if ((lpData = HeapAlloc(hHeap,0,dwSize)) == NULL) + if ((lpData = malloc(dwSize)) == NULL) { SwitchToState(SM_RUN); // run state return NULL; @@ -156,7 +156,7 @@ cancel: // write data hReturn = DdeCreateDataHandle(idDdeInst,lpData,dwSize,0,hsz2,iFmt,0); - HeapFree(hHeap,0,lpData); + free(lpData); SwitchToState(SM_RUN); // run state while (nState!=nNextState) Sleep(0); diff --git a/source/DEBUGDLL.C b/source/source/DEBUGDLL.C similarity index 95% rename from source/DEBUGDLL.C rename to source/source/DEBUGDLL.C index 9aa6cb9..b9955f5 100644 --- a/source/DEBUGDLL.C +++ b/source/source/DEBUGDLL.C @@ -237,7 +237,7 @@ DECLSPEC BOOL CALLBACK EmuInitLastInstr( DWORD *pdwArray) // @parm pointer to linear array { if (pdwInstrArray) // circular buffer defined - HeapFree(hHeap,0,pdwInstrArray); // free memory + free(pdwInstrArray); // free memory if (wNoInstr) // new size { @@ -245,7 +245,7 @@ DECLSPEC BOOL CALLBACK EmuInitLastInstr( wInstrSize = wNoInstr + 1; // size of circular buffer wInstrWp = wInstrRp = 0; // init write/read pointer - pdwInstrArray = HeapAlloc(hHeap,0,wInstrSize*sizeof(*pdwInstrArray)); + pdwInstrArray = malloc(wInstrSize*sizeof(*pdwInstrArray)); if (pdwInstrArray == NULL) // allocation error return TRUE; } @@ -478,7 +478,6 @@ DECLSPEC VOID CALLBACK EmuCallBackDebugNotify( pEmuDbgNotify = EmuDbgNotify; // remove handler bInterrupt = TRUE; // exit opcode loop SetEvent(hEventDebug); - UpdateWindowStatus(); // update menu settings } return; } diff --git a/source/DEBUGGER.C b/source/source/DEBUGGER.C similarity index 86% rename from source/DEBUGGER.C rename to source/source/DEBUGGER.C index c638ea6..0b8962e 100644 --- a/source/DEBUGGER.C +++ b/source/source/DEBUGGER.C @@ -52,21 +52,6 @@ typedef struct // type of breakpoint table DWORD dwAddr; // breakpoint address } BP_T; -typedef struct // type of model memory mapping -{ - CONST BYTE byType; // calculator type - CONST LPBYTE *ppbyNCE1; // NCE1 data - CONST DWORD *pdwNCE1Size; // NCE1 size - CONST LPBYTE *ppbyNCE2; // NCE2 data - CONST DWORD *pdwNCE2Size; // NCE2 size - CONST LPBYTE *ppbyCE1; // CE1 data - CONST DWORD *pdwCE1Size; // CE1 size - CONST LPBYTE *ppbyCE2; // CE2 data - CONST DWORD *pdwCE2Size; // CE2 size - CONST LPBYTE *ppbyNCE3; // NCE3 data - CONST DWORD *pdwNCE3Size; // NCE3 size -} MODEL_MAP_T; - static CONST int nCol[] = { IDC_DEBUG_MEM_COL0, IDC_DEBUG_MEM_COL1, IDC_DEBUG_MEM_COL2, IDC_DEBUG_MEM_COL3, @@ -78,92 +63,6 @@ static CONST TCHAR cHex[] = { _T('0'),_T('1'),_T('2'),_T('3'), _T('8'),_T('9'),_T('A'),_T('B'), _T('C'),_T('D'),_T('E'),_T('F') }; -static CONST LPBYTE pbyNoMEM = NULL; // no memory module - -static CONST MODEL_MAP_T MemMap[] = -{ - { - 0, // default - &pbyNoMEM, NULL, // nc. - &pbyNoMEM, NULL, // nc. - &pbyNoMEM, NULL, // nc. - &pbyNoMEM, NULL, // nc. - &pbyNoMEM, NULL // nc. - }, - { - '6', // HP38G (64K) - &pbyRom, &dwRomSize, // ROM - &Port0, &Chipset.Port0Size, // RAM - &pbyNoMEM, NULL, // nc. - &pbyNoMEM, NULL, // nc. - &pbyNoMEM, NULL // nc. - }, - { - 'A', // HP38G - &pbyRom, &dwRomSize, // ROM - &Port0, &Chipset.Port0Size, // RAM - &pbyNoMEM, NULL, // nc. - &pbyNoMEM, NULL, // nc. - &pbyNoMEM, NULL // nc. - }, - { - 'E', // HP39/40G - &pbyRom, &dwRomSize, // ROM - &Port0, &Chipset.Port0Size, // RAM - &pbyNoMEM, NULL, // BS - &pbyNoMEM, NULL, // nc. - &Port2, &Chipset.Port2Size // RAM part 2 - }, - { - 'G', // HP48GX - &pbyRom, &dwRomSize, // ROM - &Port0, &Chipset.Port0Size, // RAM - &pbyNoMEM, NULL, // BS - &Port1, &Chipset.Port1Size, // Card slot 1 - &pbyPort2, &dwPort2Size // Card slot 2 - }, - { - 'S', // HP48SX - &pbyRom, &dwRomSize, // ROM - &Port0, &Chipset.Port0Size, // RAM - &Port1, &Chipset.Port1Size, // Card slot 1 - &pbyPort2, &dwPort2Size, // Card slot 2 - &pbyNoMEM, NULL // nc. - }, - { - 'X', // HP49G - &pbyRom, &dwRomSize, // Flash - &Port0, &Chipset.Port0Size, // RAM - &pbyNoMEM, NULL, // BS - &Port1, &Chipset.Port1Size, // Port 1 part 1 - &Port2, &Chipset.Port2Size // Port 1 part 2 - }, - { // CdB for HP: add Q type - 'Q', // HP49G+ - &pbyRom, &dwRomSize, // Flash - &Port0, &Chipset.Port0Size, // RAM - &pbyNoMEM, NULL, // BS - &Port1, &Chipset.Port1Size, // Port 1 part 1 - &Port2, &Chipset.Port2Size // Port 1 part 2 - }, - { // CdB for HP: add 2 type - '2', // HP48Gii - &pbyRom, &dwRomSize, // ROM - &Port0, &Chipset.Port0Size, // RAM - &pbyNoMEM, NULL, // BS - &pbyNoMEM, NULL, // Port 1 part 1 - &pbyNoMEM, NULL, // Port 1 part 2 - }, - { // CdB for HP: add P type - 'P', // HP39G+ - &pbyRom, &dwRomSize, // ROM - &Port0, &Chipset.Port0Size, // RAM - &pbyNoMEM, NULL, // BS - &pbyNoMEM, NULL, // nc. - &Port2, &Chipset.Port2Size // RAM part 2 - } -}; - static INT nDbgPosX = 0; // position of debugger window static INT nDbgPosY = 0; @@ -182,16 +81,12 @@ static UINT uIDFol = ID_DEBUG_MEM_FNONE; // follow mode static DWORD dwAdrMemFol = 0; // follow address memory window static UINT uIDMap = ID_DEBUG_MEM_MAP; // current memory view mode -static LPBYTE lbyMapData; // data -static DWORD dwMapDataSize; // data size static LONG lCharWidth; // width of a character (is a fix font) static HMENU hMenuCode,hMenuMem,hMenuStack;// handle of context menues static HWND hWndToolbar; // toolbar handle -static MODEL_MAP_T CONST *pMapping; // model specific memory mapping - static DWORD dwDbgRefCycles; // cpu cycles counter from last opcode static CHIPSET OldChipset; // old chipset content @@ -210,6 +105,8 @@ static BOOL OnEditBreakpoint(HWND hDlg); static BOOL OnInfoIntr(HWND hDlg); static BOOL OnInfoWoRegister(HWND hDlg); static VOID UpdateProfileWnd(HWND hDlg); +static BOOL OnMemLoadData(HWND hDlg); +static BOOL OnMemSaveData(HWND hDlg); //################ //# @@ -263,52 +160,53 @@ static VOID DisableMenuKeys(HWND hDlg) // static VOID SetMappingMenu(HWND hDlg,UINT uID) { + enum MEM_MAPPING eMode; LPTSTR szCaption; + UINT uEnable = MF_GRAYED; // disable Memory Data menu items + CheckMenuItem(hMenuMem,uIDMap,MF_UNCHECKED); switch (uID) { case ID_DEBUG_MEM_MAP: szCaption = _T("Memory"); - lbyMapData = NULL; // data - dwMapDataSize = 512; // data size + eMode = MEM_MMU; + uEnable = MF_ENABLED; // enable Memory Data menu items break; case ID_DEBUG_MEM_NCE1: szCaption = _T("Memory (NCE1)"); - lbyMapData = *pMapping->ppbyNCE1; - dwMapDataSize = *pMapping->pdwNCE1Size / 2048; // ROM size is always in nibbles + eMode = MEM_NCE1; break; case ID_DEBUG_MEM_NCE2: szCaption = _T("Memory (NCE2)"); - lbyMapData = *pMapping->ppbyNCE2; - dwMapDataSize = *pMapping->pdwNCE2Size; + eMode = MEM_NCE2; break; case ID_DEBUG_MEM_CE1: szCaption = _T("Memory (CE1)"); - lbyMapData = *pMapping->ppbyCE1; - dwMapDataSize = *pMapping->pdwCE1Size; + eMode = MEM_CE1; break; case ID_DEBUG_MEM_CE2: szCaption = _T("Memory (CE2)"); - lbyMapData = *pMapping->ppbyCE2; - dwMapDataSize = *pMapping->pdwCE2Size; + eMode = MEM_CE2; break; case ID_DEBUG_MEM_NCE3: szCaption = _T("Memory (NCE3)"); - lbyMapData = *pMapping->ppbyNCE3; - dwMapDataSize = *pMapping->pdwNCE3Size; + eMode = MEM_NCE3; break; default: _ASSERT(0); } - dwMapDataSize *= 2048; // size in nibble + VERIFY(SetMemMapType(eMode)); if (uIDMap != uID) dwAdrMem = 0; // view from address 0 uIDMap = uID; CheckMenuItem(hMenuMem,uIDMap,MF_CHECKED); + EnableMenuItem(hMenuMem,ID_DEBUG_MEM_LOAD,uEnable); + EnableMenuItem(hMenuMem,ID_DEBUG_MEM_SAVE,uEnable); + SetDlgItemText(hDlg,IDC_STATIC_MEMORY,szCaption); return; }; @@ -320,6 +218,7 @@ static DWORD GetMemCurAddr(HWND hDlg) { INT i,nPos; DWORD dwAddr = dwAdrMem; + DWORD dwMapDataMask = GetMemDataMask(); for (i = 0; i < MEMWNDMAX; ++i) // scan all memory cols { @@ -327,7 +226,7 @@ static DWORD GetMemCurAddr(HWND hDlg) if ((nPos = (INT) SendDlgItemMessage(hDlg,nCol[i],LB_GETCURSEL,0,0)) != LB_ERR) { dwAddr += (DWORD) (nPos * MEMWNDMAX + i) * 2; - dwAddr &= (dwMapDataSize - 1); + dwAddr &= dwMapDataMask; break; } } @@ -352,8 +251,7 @@ static __inline VOID ToggleBreakpoint(DWORD dwAddr) return; } - // purge breakpoint - for (++i; i < wBreakpointCount; ++i) + while (++i < wBreakpointCount) // purge breakpoint sBreakpoint[i-1] = sBreakpoint[i]; --wBreakpointCount; return; @@ -380,34 +278,23 @@ static __inline VOID ToggleBreakpoint(DWORD dwAddr) static __inline VOID InitMemMap(HWND hDlg) { BOOL bActive; - INT i; - pMapping = MemMap; // init default mapping - - // scan for all table entries - for (i = 0; i < ARRAYSIZEOF(MemMap); ++i) - { - if (MemMap[i].byType == cCurrentRomType) - { - pMapping = &MemMap[i]; // found entry - break; - } - } + SetMemRomType(cCurrentRomType); // set current model _ASSERT(hMenuMem); // enable menu mappings - EnableMenuItem(hMenuMem,ID_DEBUG_MEM_NCE1,(*pMapping->ppbyNCE1) ? MF_ENABLED : MF_GRAYED); - EnableMenuItem(hMenuMem,ID_DEBUG_MEM_NCE2,(*pMapping->ppbyNCE2) ? MF_ENABLED : MF_GRAYED); - EnableMenuItem(hMenuMem,ID_DEBUG_MEM_CE1, (*pMapping->ppbyCE1) ? MF_ENABLED : MF_GRAYED); - EnableMenuItem(hMenuMem,ID_DEBUG_MEM_CE2, (*pMapping->ppbyCE2) ? MF_ENABLED : MF_GRAYED); - EnableMenuItem(hMenuMem,ID_DEBUG_MEM_NCE3,(*pMapping->ppbyNCE3) ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenuMem,ID_DEBUG_MEM_NCE1,GetMemAvail(MEM_NCE1) ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenuMem,ID_DEBUG_MEM_NCE2,GetMemAvail(MEM_NCE2) ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenuMem,ID_DEBUG_MEM_CE1, GetMemAvail(MEM_CE1) ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenuMem,ID_DEBUG_MEM_CE2, GetMemAvail(MEM_CE2) ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenuMem,ID_DEBUG_MEM_NCE3,GetMemAvail(MEM_NCE3) ? MF_ENABLED : MF_GRAYED); - bActive = (ID_DEBUG_MEM_NCE1 == uIDMap && *pMapping->ppbyNCE1 != NULL) - || (ID_DEBUG_MEM_NCE2 == uIDMap && *pMapping->ppbyNCE2 != NULL) - || (ID_DEBUG_MEM_CE1 == uIDMap && *pMapping->ppbyCE1 != NULL) - || (ID_DEBUG_MEM_CE2 == uIDMap && *pMapping->ppbyCE2 != NULL) - || (ID_DEBUG_MEM_NCE3 == uIDMap && *pMapping->ppbyNCE3 != NULL); + bActive = (ID_DEBUG_MEM_NCE1 == uIDMap && GetMemAvail(MEM_NCE1)) + || (ID_DEBUG_MEM_NCE2 == uIDMap && GetMemAvail(MEM_NCE2)) + || (ID_DEBUG_MEM_CE1 == uIDMap && GetMemAvail(MEM_CE1)) + || (ID_DEBUG_MEM_CE2 == uIDMap && GetMemAvail(MEM_CE2)) + || (ID_DEBUG_MEM_NCE3 == uIDMap && GetMemAvail(MEM_NCE3)); SetMappingMenu(hDlg,bActive ? uIDMap : ID_DEBUG_MEM_MAP); return; @@ -473,6 +360,7 @@ static VOID StrToReg(BYTE *pReg, WORD wNib, LPTSTR lpszValue) // static INT ViewCodeWnd(HWND hWnd, DWORD dwAddress) { + enum MEM_MAPPING eMapMode; LPCTSTR lpszName; TCHAR szAddress[64]; DWORD dwNxtAddr; @@ -480,7 +368,9 @@ static INT ViewCodeWnd(HWND hWnd, DWORD dwAddress) nLinePC = -1; // PC not shown (no selection) - _ASSERT(disassembler_map == MEM_MAP); // disassemble in mapped mode + eMapMode = GetMemMapType(); // get current map mode + SetMemMapType(MEM_MMU); // disassemble in mapped mode + dwAddress &= 0xFFFFF; // adjust to Saturn address range SendMessage(hWnd,WM_SETREDRAW,FALSE,0); SendMessage(hWnd,LB_RESETCONTENT,0,0); @@ -530,6 +420,7 @@ static INT ViewCodeWnd(HWND hWnd, DWORD dwAddress) SendMessage(hWnd,LB_ADDSTRING,0,(LPARAM) szAddress); } SendMessage(hWnd,WM_SETREDRAW,TRUE,0); + SetMemMapType(eMapMode); // switch back to old map mode return nLinePC; } @@ -540,12 +431,14 @@ static VOID ViewMemWnd(HWND hDlg, DWORD dwAddress) { #define TEXTOFF 32 - INT i,j,k; + INT i,j; TCHAR szBuffer[16],szItem[4]; + DWORD dwMapDataMask; BYTE cChar; szItem[2] = 0; // end of string dwAdrMem = dwAddress; // save start address of memory window + dwMapDataMask = GetMemDataMask(); // size mask of data mapping // purge all list boxes SendDlgItemMessage(hDlg,IDC_DEBUG_MEM_ADDR,LB_RESETCONTENT,0,0); @@ -559,28 +452,18 @@ static VOID ViewMemWnd(HWND hDlg, DWORD dwAddress) if (ID_DEBUG_MEM_MAP == uIDMap) // mapped memory content { - // fetch mapping data line - Npeek(byLineData, dwAddress, MAXMEMITEMS); - wsprintf(szBuffer,_T("%05lX"),dwAddress); } else // module memory content { - INT i; - - _ASSERT(lbyMapData); // valid module - - // fetch modul data line - for (i = 0; i < MAXMEMITEMS; ++i) - { - byLineData[i] = lbyMapData[(dwAddress + i) & (dwMapDataSize - 1)]; - } - wsprintf(szBuffer,_T("%06lX"),dwAddress); } SendDlgItemMessage(hDlg,IDC_DEBUG_MEM_ADDR,LB_ADDSTRING,0,(LPARAM) szBuffer); - for (k = 0, j = 0; j < MAXMEMITEMS; ++j) + // fetch data line + GetMemPeek(byLineData, dwAddress, MAXMEMITEMS); + + for (j = 0; j < MAXMEMITEMS; ++j) { // read from fetched data line szItem[j&0x1] = cHex[byLineData[j]]; @@ -600,7 +483,7 @@ static VOID ViewMemWnd(HWND hDlg, DWORD dwAddress) szBuffer[j/2] = 0; // end of text string SendDlgItemMessage(hDlg,IDC_DEBUG_MEM_TEXT,LB_ADDSTRING,0,(LPARAM) szBuffer); - dwAddress = (dwAddress + MAXMEMITEMS) & (dwMapDataSize - 1); + dwAddress = (dwAddress + MAXMEMITEMS) & dwMapDataMask; } return; #undef TEXTOFF @@ -988,7 +871,7 @@ static BOOL OnKeyF5(HWND hDlg) SetEvent(hEventDebug); // run emulation } return -1; // call windows default handler - UNREFERENCED_PARAMETER(hDlg); + UNREFERENCED_PARAMETER(hDlg); } // @@ -1022,7 +905,7 @@ static BOOL OnKeyF7(HWND hDlg) SetEvent(hEventDebug); // run emulation } return -1; // call windows default handler - UNREFERENCED_PARAMETER(hDlg); + UNREFERENCED_PARAMETER(hDlg); } // @@ -1052,7 +935,7 @@ static BOOL OnKeyF8(HWND hDlg) SetEvent(hEventDebug); // run emulation } return -1; // call windows default handler - UNREFERENCED_PARAMETER(hDlg); + UNREFERENCED_PARAMETER(hDlg); } // @@ -1070,7 +953,7 @@ static BOOL OnKeyF9(HWND hDlg) SetEvent(hEventDebug); // run emulation } return -1; // call windows default handler - UNREFERENCED_PARAMETER(hDlg); + UNREFERENCED_PARAMETER(hDlg); } // @@ -1082,7 +965,7 @@ static BOOL OnKeyF11(HWND hDlg) if (Chipset.Shutdn) // cpu thread stopped SetEvent(hEventShutdn); // goto debug session return -1; // call windows default handler - UNREFERENCED_PARAMETER(hDlg); + UNREFERENCED_PARAMETER(hDlg); } // @@ -1142,7 +1025,7 @@ static BOOL OnMemGoAdr(HWND hDlg) OnEnterAddress(hDlg, &dwAddress); if (dwAddress != -1) // not Cancel key - OnMemGoDx(hDlg,dwAddress & (dwMapDataSize - 1)); + OnMemGoDx(hDlg,dwAddress & GetMemDataMask()); return -1; // call windows default handler } @@ -1421,19 +1304,22 @@ static BOOL OnLButtonUp(HWND hDlg, LPARAM lParam) // static BOOL OnDblClick(HWND hWnd, WORD wId) { + HWND hDlg,hWndCode; TCHAR szBuffer[4]; BYTE byData; INT i; DWORD dwAddress; + hDlg = GetParent(hWnd); // dialog window handle + hWndCode = GetDlgItem(hDlg,IDC_DEBUG_CODE); + if (wId == IDC_DEBUG_STACK) // stack list box { // get cpu address of selected item i = (INT) SendMessage(hWnd,LB_GETCURSEL,0,0); dwAddress = (DWORD) SendMessage(hWnd,LB_GETITEMDATA,i,0); - // show code of this address - ViewCodeWnd(GetDlgItem(GetParent(hWnd),IDC_DEBUG_CODE),dwAddress); + ViewCodeWnd(hWndCode,dwAddress); // show code of this address return TRUE; } @@ -1453,13 +1339,15 @@ static BOOL OnDblClick(HWND hWnd, WORD wId) // enter new value SendMessage(hWnd,LB_GETTEXT,i,(LPARAM) szBuffer); OnNewValue(szBuffer); - _stscanf(szBuffer,_T("%2X"), &byData); + byData = (BYTE) _tcstoul(szBuffer,NULL,16); byData = (byData >> 4) | (byData << 4); // change nibbles for writing - Write2(dwAddress, byData); // write data - ViewMemWnd(GetParent(hWnd),dwAdrMem); // update memory window + Write2(dwAddress,byData); // write data + ViewCodeWnd(hWndCode,dwAdrLine[0]); // update code window + ViewMemWnd(hDlg,dwAdrMem); // update memory window SendMessage(hWnd,LB_SETCURSEL,i,0); return FALSE; + return FALSE; } // @@ -1564,13 +1452,13 @@ static __inline BOOL OnKeyUpDown(HWND hWnd, WPARAM wParam) switch(LOWORD(wParam)) { case VK_NEXT: - dwAdrMem = (dwAdrMem + MAXMEMITEMS * MAXMEMLINES) & (dwMapDataSize - 1); + dwAdrMem = (dwAdrMem + MAXMEMITEMS * MAXMEMLINES) & GetMemDataMask(); ViewMemWnd(GetParent(hWnd),dwAdrMem); SendMessage(hWnd,LB_SETCURSEL,wY,0); return -2; case VK_PRIOR: - dwAdrMem = (dwAdrMem - MAXMEMITEMS * MAXMEMLINES) & (dwMapDataSize - 1); + dwAdrMem = (dwAdrMem - MAXMEMITEMS * MAXMEMLINES) & GetMemDataMask(); ViewMemWnd(GetParent(hWnd),dwAdrMem); SendMessage(hWnd,LB_SETCURSEL,wY,0); return -2; @@ -1578,7 +1466,7 @@ static __inline BOOL OnKeyUpDown(HWND hWnd, WPARAM wParam) case VK_DOWN: if (wY+1 >= MAXMEMLINES) { - dwAdrMem = (dwAdrMem + MAXMEMITEMS) & (dwMapDataSize - 1); + dwAdrMem = (dwAdrMem + MAXMEMITEMS) & GetMemDataMask(); ViewMemWnd(GetParent(hWnd),dwAdrMem); SendMessage(hWnd,LB_SETCURSEL,wY,0); return -2; @@ -1588,7 +1476,7 @@ static __inline BOOL OnKeyUpDown(HWND hWnd, WPARAM wParam) case VK_UP: if (wY == 0) { - dwAdrMem = (dwAdrMem - MAXMEMITEMS) & (dwMapDataSize - 1); + dwAdrMem = (dwAdrMem - MAXMEMITEMS) & GetMemDataMask(); ViewMemWnd(GetParent(hWnd),dwAdrMem); SendMessage(hWnd,LB_SETCURSEL,wY,0); return -2; @@ -1620,7 +1508,7 @@ static __inline BOOL OnKeyPlusMinus(HWND hWnd, WPARAM wParam) dwAdrMem++; else dwAdrMem--; - dwAdrMem &= (dwMapDataSize - 1); + dwAdrMem &= GetMemDataMask(); ViewMemWnd(GetParent(hWnd),dwAdrMem); // redraw memory view SendMessage(hWnd,LB_SETCURSEL,wY,0); // set focus at old position @@ -1726,7 +1614,7 @@ static __inline BOOL OnDrawCodeWnd(LPDRAWITEMSTRUCT lpdis) crTextColor = SetTextColor(lpdis->hDC,crTextColor); ExtTextOut(lpdis->hDC,(int)(lpdis->rcItem.left)+2,(int)(lpdis->rcItem.top), - ETO_OPAQUE,(LPRECT)&lpdis->rcItem,szBuf,lstrlen(szBuf),NULL); + ETO_OPAQUE,(LPRECT)&lpdis->rcItem,szBuf,lstrlen(szBuf),NULL); SetBkColor(lpdis->hDC,crBkColor); SetTextColor(lpdis->hDC,crTextColor); @@ -1824,7 +1712,7 @@ static __inline HWND CreateToolbar(HWND hWnd) HRSRC hRes; HGLOBAL hGlobal; CToolBarData *pData; - TBBUTTON *ptbb; + TBBUTTON *ptbb; INT i,j; HWND hWndToolbar = NULL; // toolbar window @@ -1843,12 +1731,12 @@ static __inline HWND CreateToolbar(HWND hWnd) _ASSERT(pData->wVersion == 1); // toolbar resource version // alloc memory for TBBUTTON stucture - if (!(ptbb = HeapAlloc(hHeap,0,pData->wItemCount*sizeof(TBBUTTON)))) + if (!(ptbb = malloc(pData->wItemCount*sizeof(TBBUTTON)))) goto unlock; // fill TBBUTTON stucture with resource data for (i = j = 0; i < pData->wItemCount; ++i) - { + { if (pData->aItems[i]) { ptbb[i].iBitmap = j++; @@ -1863,14 +1751,14 @@ static __inline HWND CreateToolbar(HWND hWnd) ptbb[i].fsState = TBSTATE_ENABLED; ptbb[i].dwData = 0; ptbb[i].iString = j; - } + } hWndToolbar = CreateToolbarEx(hWnd,WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS, IDR_DEBUG_TOOLBAR,j,hApp,IDR_DEBUG_TOOLBAR,ptbb,pData->wItemCount, pData->wWidth,pData->wHeight,pData->wWidth,pData->wHeight, sizeof(TBBUTTON)); - HeapFree(hHeap,0,ptbb); + free(ptbb); unlock: FreeResource(hGlobal); @@ -1883,7 +1771,7 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM static HMENU hMenuMainCode,hMenuMainMem,hMenuMainStack; WINDOWPLACEMENT wndpl; - TEXTMETRIC tm; + TEXTMETRIC tm; HDC hDC; HFONT hFont; HMENU hSysMenu; @@ -1946,7 +1834,7 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM SendDlgItemMessage(hDlg,IDC_STATIC_MISC, WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); // init last instruction circular buffer - pdwInstrArray = HeapAlloc(hHeap,0,INSTRSIZE*sizeof(*pdwInstrArray)); + pdwInstrArray = malloc(INSTRSIZE*sizeof(*pdwInstrArray)); wInstrSize = INSTRSIZE; // size of last instruction array wInstrWp = wInstrRp = 0; // write/read pointer @@ -1959,8 +1847,6 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM InitBsArea(hDlg); // init bank switcher list box DisableMenuKeys(hDlg); // set debug menu keys into run state - disassembler_map = MEM_MAP; // disassemble with mapped modules - dwDbgStopPC = -1; // no stop address for goto cursor dwDbgRplPC = -1; // no stop address for RPL breakpoint @@ -1971,7 +1857,6 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM if (Chipset.Shutdn) // cpu thread stopped SetEvent(hEventShutdn); // goto debug session - UpdateWindowStatus(); // disable application menu items OldChipset = Chipset; // save chipset values return TRUE; @@ -1982,7 +1867,7 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM SetEvent(hEventDebug); if (pdwInstrArray) // free last instruction circular buffer { - HeapFree(hHeap,0,pdwInstrArray); + free(pdwInstrArray); pdwInstrArray = NULL; } CloseHandle(hEventDebug); @@ -1995,8 +1880,6 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM DestroyMenu(hMenuMainCode); DestroyMenu(hMenuMainMem); DestroyMenu(hMenuMainStack); - _ASSERT(hWnd); - UpdateWindowStatus(); // enable application menu items hDlgDebug = NULL; // debugger windows closed break; @@ -2069,6 +1952,8 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM case ID_DEBUG_MEM_CE1: case ID_DEBUG_MEM_CE2: case ID_DEBUG_MEM_NCE3: return OnMemMapping(hDlg,LOWORD(wParam)); + case ID_DEBUG_MEM_LOAD: return OnMemLoadData(hDlg); + case ID_DEBUG_MEM_SAVE: return OnMemSaveData(hDlg); case ID_DEBUG_STACK_PUSH: return OnStackPush(hDlg); case ID_DEBUG_STACK_POP: return OnStackPop(hDlg); case ID_DEBUG_STACK_MODIFY: return OnStackModify(hDlg); @@ -2160,7 +2045,7 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM // GetTextMetrics from "Courier New 8" font hFont = CreateFont(-MulDiv(8,GetDeviceCaps(hDC, LOGPIXELSY),72),0,0,0,FW_NORMAL,0,0,0,ANSI_CHARSET, - OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FF_DONTCARE,_T("Courier New")); + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FF_DONTCARE,_T("Courier New")); hFont = SelectObject(hDC,hFont); GetTextMetrics(hDC,&tm); @@ -2179,7 +2064,7 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM LRESULT OnToolDebug(VOID) // debugger dialogbox call { if ((hDlgDebug = CreateDialog(hApp,MAKEINTRESOURCE(IDD_DEBUG),NULL, - (DLGPROC)Debugger)) == NULL) + (DLGPROC)Debugger)) == NULL) AbortMessage(_T("Debugger Dialog Box Creation Error !")); return 0; } @@ -2191,20 +2076,26 @@ LRESULT OnToolDebug(VOID) // debugger dialogbox call //# //################ -static __inline BOOL OnFindOK(HWND hDlg,BOOL bASCII,DWORD *pdwAddrLast) +static __inline BOOL OnFindOK(HWND hDlg,BOOL bASCII,DWORD *pdwAddrLast,INT nSearchDir) { + HWND hWnd; BYTE *lpbySearch; INT i,j; - DWORD dwAddr; + DWORD dwCnt,dwAddr,dwMapDataMask; BOOL bMatch; - HWND hWnd = GetDlgItem(hDlg,IDC_FIND_DATA); + // searching upwards / downwards + _ASSERT(nSearchDir == 1 || nSearchDir == -1); + + hWnd = GetDlgItem(hDlg,IDC_FIND_DATA); + + dwMapDataMask = GetMemDataMask(); // size mask of data mapping i = GetWindowTextLength(hWnd) + 1; // text length incl. EOS j = bASCII ? 2 : sizeof(*(LPTSTR)0); // buffer width // allocate search buffer - if ((lpbySearch = HeapAlloc(hHeap,0,i * j)) != NULL) + if ((lpbySearch = (LPBYTE) malloc(i * j)) != NULL) { // get search text and real length i = GetWindowText(hWnd,(LPTSTR) lpbySearch,i); @@ -2221,8 +2112,8 @@ static __inline BOOL OnFindOK(HWND hDlg,BOOL bASCII,DWORD *pdwAddrLast) { WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, szTmp, -1, - lpbySearch, i+1, NULL, NULL); - HeapFree(hHeap,0,szTmp); + (LPSTR) lpbySearch, i+1, NULL, NULL); + free(szTmp); } } #endif @@ -2264,35 +2155,33 @@ static __inline BOOL OnFindOK(HWND hDlg,BOOL bASCII,DWORD *pdwAddrLast) bMatch = FALSE; // no match dwAddr = dwAdrMem; // calculate search start address if (*pdwAddrLast == dwAddr) - ++dwAddr; + dwAddr += nSearchDir; // scan mapping/module until match - for (; i && !bMatch && dwAddr <= dwAdrMem + dwMapDataSize; ++dwAddr) + for (dwCnt = 0; i && !bMatch && dwCnt <= dwMapDataMask; ++dwCnt) { BYTE byC; // i = no. of nibbles that have to match for (bMatch = TRUE, j = 0;bMatch && j < i; ++j) { - if (ID_DEBUG_MEM_MAP == uIDMap) // mapped memory content - { - Npeek(&byC,(dwAddr + j) & 0xFFFFF,1); - } - else // module memory content - { - byC = lbyMapData[(dwAddr + j) & (dwMapDataSize - 1)]; - } + GetMemPeek(&byC,(dwAddr + j) & dwMapDataMask,1); bMatch = (byC == lpbySearch[j]); } + dwAddr += nSearchDir; } - dwAddr = (dwAddr - 1) & (dwMapDataSize - 1); // possible matching address - HeapFree(hHeap,0,lpbySearch); + free(lpbySearch); // check match result if (bMatch) { + // matching address + dwAddr = (dwAddr - nSearchDir) & dwMapDataMask; + + // update memory window OnMemGoDx(GetParent(hDlg),dwAddr); - *pdwAddrLast = dwAddr; // latest written address + + *pdwAddrLast = dwAddr; // last matching address } else { @@ -2326,7 +2215,8 @@ static INT_PTR CALLBACK Find(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPar switch (LOWORD(wParam)) { case IDC_FIND_ASCII: bASCII = !bASCII; return TRUE; - case IDOK: return OnFindOK(hDlg,bASCII,&dwAddrEntry); + case IDC_FIND_PREV: return OnFindOK(hDlg,bASCII,&dwAddrEntry,-1); + case IDC_FIND_NEXT: return OnFindOK(hDlg,bASCII,&dwAddrEntry,1); case IDCANCEL: DestroyWindow(hDlg); return TRUE; } break; @@ -2475,7 +2365,7 @@ static VOID CopyEditToCombo(HWND hDlg,HWND hWndComboBox) if ((i = (INT) SendMessage(hWndComboBox,CB_GETCURSEL,0,0)) != CB_ERR) { // delete associated name - HeapFree(hHeap,0,(LPVOID) SendMessage(hWndComboBox,CB_GETITEMDATA,i,0)); + free((LPVOID) SendMessage(hWndComboBox,CB_GETITEMDATA,i,0)); // append actual name GetDlgItemText(hDlg,IDC_DEBUG_SET_FILE,szSymbFilename,ARRAYSIZEOF(szSymbFilename)); @@ -2640,7 +2530,7 @@ static INT_PTR CALLBACK Settings(HWND hDlg, UINT message, WPARAM wParam, LPARAM LPTSTR lpszFilename = (LPTSTR) SendMessage(hWnd,CB_GETITEMDATA,i,0); if (lpszFilename != NULL) { - HeapFree(hHeap,0,lpszFilename); + free(lpszFilename); } } EndDialog(hDlg,LOWORD(wParam)); @@ -2648,8 +2538,8 @@ static INT_PTR CALLBACK Settings(HWND hDlg, UINT message, WPARAM wParam, LPARAM } } return FALSE; - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); } static BOOL OnSettings(HWND hDlg) @@ -2712,7 +2602,7 @@ static INT_PTR CALLBACK NewValue(HWND hDlg, UINT message, WPARAM wParam, LPARAM } } return FALSE; - UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(wParam); } static INT_PTR OnNewValue(LPTSTR lpszValue) @@ -2783,7 +2673,7 @@ static INT_PTR CALLBACK EnterAddr(HWND hDlg, UINT message, WPARAM wParam, LPARAM } } return FALSE; - UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(wParam); } static VOID OnEnterAddress(HWND hDlg, DWORD *dwValue) @@ -2848,7 +2738,7 @@ static INT_PTR CALLBACK EnterBreakpoint(HWND hDlg, UINT message, WPARAM wParam, } } return FALSE; - UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(wParam); } static VOID OnEnterBreakpoint(HWND hDlg, BP_T *sValue) @@ -2895,7 +2785,7 @@ static __inline BOOL OnDrawBreakWnd(LPDRAWITEMSTRUCT lpdis) SendMessage(lpdis->hwndItem,LB_GETTEXT,lpdis->itemID,(LPARAM) szBuf); ExtTextOut(lpdis->hDC,(int)(lpdis->rcItem.left)+17,(int)(lpdis->rcItem.top), - ETO_OPAQUE,(LPRECT)&lpdis->rcItem,szBuf,lstrlen(szBuf),NULL); + ETO_OPAQUE,(LPRECT)&lpdis->rcItem,szBuf,lstrlen(szBuf),NULL); SetBkColor(lpdis->hDC,crBkColor); SetTextColor(lpdis->hDC,crTextColor); @@ -3039,7 +2929,7 @@ static INT_PTR CALLBACK EditBreakpoint(HWND hDlg, UINT message, WPARAM wParam, L // only modify memory breakpoints if ( ( sBreakpoint[i].bEnable == FALSE - && (sBreakpoint[i].nType & sBp.nType & (BP_EXEC | BP_RPL)) != 0) + && (sBreakpoint[i].nType & sBp.nType & (BP_EXEC | BP_RPL)) != 0) || ((sBreakpoint[i].nType & BP_ACCESS) && (sBp.nType & BP_ACCESS))) { // replace breakpoint type @@ -3096,7 +2986,7 @@ static INT_PTR CALLBACK EditBreakpoint(HWND hDlg, UINT message, WPARAM wParam, L } // remove breakpoint from breakpoint table - for (++i; i <= wBreakpointCount; ++i) + while (++i <= wBreakpointCount) sBreakpoint[i-1] = sBreakpoint[i]; } } @@ -3130,7 +3020,7 @@ static INT_PTR CALLBACK EditBreakpoint(HWND hDlg, UINT message, WPARAM wParam, L // GetTextMetrics from "Courier New 8" font hFont = CreateFont(-MulDiv(8,GetDeviceCaps(hDC, LOGPIXELSY),72),0,0,0,FW_NORMAL,0,0,0,ANSI_CHARSET, - OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FF_DONTCARE,_T("Courier New")); + OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FF_DONTCARE,_T("Courier New")); hFont = SelectObject(hDC,hFont); GetTextMetrics(hDC,&tm); @@ -3143,8 +3033,8 @@ static INT_PTR CALLBACK EditBreakpoint(HWND hDlg, UINT message, WPARAM wParam, L return TRUE; } return FALSE; - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); } static BOOL OnEditBreakpoint(HWND hDlg) @@ -3223,7 +3113,7 @@ static INT_PTR CALLBACK InfoIntr(HWND hDlg, UINT message, WPARAM wParam, LPARAM } } return FALSE; - UNREFERENCED_PARAMETER(lParam); + UNREFERENCED_PARAMETER(lParam); } static BOOL OnInfoIntr(HWND hDlg) @@ -3260,7 +3150,7 @@ static BOOL CALLBACK InfoWoRegister(HWND hDlg, UINT message, DWORD wParam, LONG } } return FALSE; - UNREFERENCED_PARAMETER(lParam); + UNREFERENCED_PARAMETER(lParam); } static BOOL OnInfoWoRegister(HWND hDlg) @@ -3286,7 +3176,9 @@ VOID LoadBreakpointList(HANDLE hFile) // NULL = clear breakpoint list // read number of breakpoints if (hFile) ReadFile(hFile, &wBreakpointCount, sizeof(wBreakpointCount), &lBytesRead, NULL); - if(lBytesRead) // breakpoints found + + // breakpoints found + if (lBytesRead == sizeof(wBreakpointCount) && wBreakpointCount < ARRAYSIZEOF(sBreakpoint)) { WORD wBreakpointSize; @@ -3303,7 +3195,7 @@ VOID LoadBreakpointList(HANDLE hFile) // NULL = clear breakpoint list wBreakpointCount = 0; // clear breakpoint list } } - else + else // no breakpoints or breakpoint buffer too small { wBreakpointCount = 0; // clear breakpoint list } @@ -3369,3 +3261,232 @@ VOID RestoreBackupBreakpointList(VOID) } return; } + + +//################ +//# +//# Load/Save Memory Data +//# +//################ + +static BOOL OnBrowseLoadMem(HWND hDlg) +{ + TCHAR szBuffer[MAX_PATH]; + OPENFILENAME ofn; + + ZeroMemory(&ofn, sizeof(OPENFILENAME)); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hDlg; + ofn.lpstrFilter = + _T("Memory Dump Files (*.MEM)\0*.MEM\0") + _T("All Files (*.*)\0*.*\0"); + ofn.lpstrDefExt = _T("MEM"); + ofn.nFilterIndex = 1; + ofn.lpstrFile = szBuffer; + ofn.lpstrFile[0] = 0; + ofn.nMaxFile = ARRAYSIZEOF(szBuffer); + ofn.Flags = OFN_EXPLORER|OFN_HIDEREADONLY|OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST; + if (GetOpenFileName(&ofn)) + { + SetDlgItemText(hDlg,IDC_DEBUG_DATA_FILE,szBuffer); + } + return 0; +} + +static BOOL OnBrowseSaveMem(HWND hDlg) +{ + TCHAR szBuffer[MAX_PATH]; + OPENFILENAME ofn; + + ZeroMemory(&ofn, sizeof(OPENFILENAME)); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hDlg; + ofn.lpstrFilter = + _T("Memory Dump Files (*.MEM)\0*.MEM\0") + _T("All Files (*.*)\0*.*\0"); + ofn.lpstrDefExt = _T("MEM"); + ofn.nFilterIndex = 1; + ofn.lpstrFile = szBuffer; + ofn.lpstrFile[0] = 0; + ofn.nMaxFile = ARRAYSIZEOF(szBuffer); + ofn.Flags = OFN_EXPLORER|OFN_HIDEREADONLY|OFN_CREATEPROMPT|OFN_OVERWRITEPROMPT; + if (GetSaveFileName(&ofn)) + { + SetDlgItemText(hDlg,IDC_DEBUG_DATA_FILE,szBuffer); + } + return 0; +} + +// +// write file to memory +// +static BOOL LoadMemData(LPCTSTR lpszFilename,DWORD dwStartAddr) +{ + HANDLE hFile; + DWORD dwRead; + BYTE byData; + + hFile = CreateFile(lpszFilename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL); + if (hFile == INVALID_HANDLE_VALUE) // error, couldn't create a new file + return FALSE; + + while (TRUE) // read until EOF + { + ReadFile(hFile,&byData,sizeof(byData),&dwRead,NULL); + if (dwRead == 0) break; // EOF + + Write2(dwStartAddr,byData); // write byte in map mode + dwStartAddr += 2; + } + + CloseHandle(hFile); + return TRUE; +} + +// +// write memory data to file +// +static BOOL SaveMemData(LPCTSTR lpszFilename,DWORD dwStartAddr,DWORD dwEndAddr) +{ + HANDLE hFile; + DWORD dwAddr,dwWritten; + BYTE byData; + + hFile = CreateFile(lpszFilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) // error, couldn't create a new file + return FALSE; + + for (dwAddr = dwStartAddr; dwAddr <= dwEndAddr; dwAddr += 2) + { + byData = Read2(dwAddr); // read byte in map mode + WriteFile(hFile,&byData,sizeof(byData),&dwWritten,NULL); + } + + CloseHandle(hFile); + return TRUE; +} + +// +// read edit control and decode content as hex number +// +static BOOL GetAddr(HWND hDlg, INT nID, DWORD *pdwAddr) +{ + TCHAR szBuffer[8]; + INT i; + + HWND hWnd = GetDlgItem(hDlg,nID); + + GetWindowText(hWnd,szBuffer,ARRAYSIZEOF(szBuffer)); + + // test if valid hex address + for (i = 0; i < (LONG) lstrlen(szBuffer); ++i) + { + if (_istxdigit(szBuffer[i]) == 0) + { + SendMessage(hWnd,EM_SETSEL,0,-1); + SetFocus(hWnd); // focus to edit control + return FALSE; + } + } + _stscanf(szBuffer,_T("%6X"),pdwAddr); + return TRUE; +} + +// +// memory load data +// +static INT_PTR CALLBACK DebugMemLoad(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + TCHAR szFilename[MAX_PATH]; + DWORD dwStartAddr; + + switch (message) + { + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDC_DEBUG_DATA_BUT: + return OnBrowseLoadMem(hDlg); + + case IDOK: + // get filename + GetDlgItemText(hDlg,IDC_DEBUG_DATA_FILE,szFilename,ARRAYSIZEOF(szFilename)); + + // decode address field + if (!GetAddr(hDlg,IDC_DEBUG_DATA_STARTADDR,&dwStartAddr)) + return FALSE; + + // load memory dump file + if (!LoadMemData(szFilename,dwStartAddr)) + return FALSE; + + // update memory window + UpdateMemoryWnd(GetParent(hDlg)); + + // no break + case IDCANCEL: + EndDialog(hDlg,LOWORD(wParam)); + return TRUE; + } + } + return FALSE; + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); +} + +static BOOL OnMemLoadData(HWND hDlg) +{ + if (DialogBox(hApp, MAKEINTRESOURCE(IDD_DEBUG_MEMLOAD), hDlg, (DLGPROC)DebugMemLoad) == -1) + AbortMessage(_T("DebugLoad Dialog Box Creation Error !")); + + return -1; +} + +// +// memory save data +// +static INT_PTR CALLBACK DebugMemSave(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + TCHAR szFilename[MAX_PATH]; + DWORD dwStartAddr,dwEndAddr; + + switch (message) + { + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDC_DEBUG_DATA_BUT: + return OnBrowseSaveMem(hDlg); + + case IDOK: + // get filename + GetDlgItemText(hDlg,IDC_DEBUG_DATA_FILE,szFilename,ARRAYSIZEOF(szFilename)); + + // decode address fields + if (!GetAddr(hDlg,IDC_DEBUG_DATA_STARTADDR,&dwStartAddr)) + return FALSE; + if (!GetAddr(hDlg,IDC_DEBUG_DATA_ENDADDR,&dwEndAddr)) + return FALSE; + + // save memory dump file + if (!SaveMemData(szFilename,dwStartAddr,dwEndAddr)) + return FALSE; + + // no break + case IDCANCEL: + EndDialog(hDlg,LOWORD(wParam)); + return TRUE; + } + } + return FALSE; + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); +} + +static BOOL OnMemSaveData(HWND hDlg) +{ + if (DialogBox(hApp, MAKEINTRESOURCE(IDD_DEBUG_MEMSAVE), hDlg, (DLGPROC)DebugMemSave) == -1) + AbortMessage(_T("DebugSave Dialog Box Creation Error !")); + + return -1; +} diff --git a/source/DEBUGGER.H b/source/source/DEBUGGER.H similarity index 100% rename from source/DEBUGGER.H rename to source/source/DEBUGGER.H diff --git a/source/DISASM.C b/source/source/DISASM.C similarity index 92% rename from source/DISASM.C rename to source/source/DISASM.C index 944302a..99ebc1c 100644 --- a/source/DISASM.C +++ b/source/source/DISASM.C @@ -16,7 +16,6 @@ BOOL disassembler_mode = HP_MNEMONICS; BOOL disassembler_symb = FALSE; -WORD disassembler_map = MEM_MAP; static LPCTSTR hex[] = { @@ -215,82 +214,13 @@ static LPCTSTR hst_bits[8] = _T("xm"), _T("sb"), _T("sr"), _T("mp") }; - -// static functions - -static BYTE rn_map (DWORD *p) -{ - BYTE byVal; - - Npeek(&byVal, *p, 1); - *p = ++(*p) & 0xFFFFF; - return byVal; -} - -static BYTE rn_rom (DWORD *p) -{ - DWORD d = *p; - - *p = ++(*p) & (dwRomSize - 1); - - _ASSERT(d < dwRomSize); - return *(pbyRom + d); -} - -static BYTE rn_ram (DWORD *p) -{ - DWORD d = *p; - - *p = ++(*p) & (Chipset.Port0Size * 2048 - 1); - - _ASSERT(d < Chipset.Port0Size * 2048); - return *(Port0 + d); -} - -static BYTE rn_port1 (DWORD *p) -{ - DWORD d = *p; - - *p = ++(*p) & (Chipset.Port1Size * 2048 - 1); - - _ASSERT(d < Chipset.Port1Size * 2048); - return *(Port1 + d); -} - -static BYTE rn_port2 (DWORD *p) -{ - BYTE *pbyVal; - DWORD d = *p; - - if (Chipset.Port2Size) // HP39/40G, HP49G - { - *p = ++(*p) & (Chipset.Port2Size * 2048 - 1); - - _ASSERT(d < Chipset.Port2Size * 2048); - pbyVal = Port2; - } - else // HP48SX/GX - { - *p = ++(*p) & (((dwPort2Mask + 1) << 18) - 1); - - _ASSERT(d < ((dwPort2Mask + 1) << 18)); - pbyVal = pbyPort2; - } - return *(pbyVal + d); -} - -// global functions - -BYTE read_nibble (DWORD *p) -{ - BYTE (*pnread[])(DWORD *) = { rn_map, rn_rom, rn_ram, rn_port1, rn_port2 }; - - _ASSERT(disassembler_map < ARRAYSIZEOF(pnread)); - return pnread[disassembler_map](p); -} - // general functions +static BYTE read_nibble (DWORD *p) +{ + return GetMemNib(p); +} + static int read_int (DWORD *addr, int n) { int i, t; diff --git a/source/source/DISMEM.C b/source/source/DISMEM.C new file mode 100644 index 0000000..1784c98 --- /dev/null +++ b/source/source/DISMEM.C @@ -0,0 +1,245 @@ +/* + * dismem.c + * + * This file is part of Emu48 + * + * Copyright (C) 2012 Christoph Gießelink + * + */ +#include "pch.h" +#include "Emu48.h" + +typedef struct // type of model memory mapping +{ + CONST BYTE byType; // calculator type + CONST LPBYTE *ppbyNCE1; // NCE1 data + CONST DWORD *pdwNCE1Size; // NCE1 size + CONST LPBYTE *ppbyNCE2; // NCE2 data + CONST DWORD *pdwNCE2Size; // NCE2 size + CONST LPBYTE *ppbyCE1; // CE1 data + CONST DWORD *pdwCE1Size; // CE1 size + CONST LPBYTE *ppbyCE2; // CE2 data + CONST DWORD *pdwCE2Size; // CE2 size + CONST LPBYTE *ppbyNCE3; // NCE3 data + CONST DWORD *pdwNCE3Size; // NCE3 size +} MODEL_MAP_T; + +static CONST LPBYTE pbyNoMEM = NULL; // no memory module + +static CONST MODEL_MAP_T MemMap[] = +{ + { + 0, // default + &pbyNoMEM, NULL, // nc. + &pbyNoMEM, NULL, // nc. + &pbyNoMEM, NULL, // nc. + &pbyNoMEM, NULL, // nc. + &pbyNoMEM, NULL // nc. + }, + { + '6', // HP38G (64K) + &pbyRom, &dwRomSize, // ROM + &Port0, &Chipset.Port0Size, // RAM + &pbyNoMEM, NULL, // nc. + &pbyNoMEM, NULL, // nc. + &pbyNoMEM, NULL // nc. + }, + { + 'A', // HP38G + &pbyRom, &dwRomSize, // ROM + &Port0, &Chipset.Port0Size, // RAM + &pbyNoMEM, NULL, // nc. + &pbyNoMEM, NULL, // nc. + &pbyNoMEM, NULL // nc. + }, + { + 'E', // HP39/40G + &pbyRom, &dwRomSize, // ROM + &Port0, &Chipset.Port0Size, // RAM part 1 + &pbyNoMEM, NULL, // BS + &pbyNoMEM, NULL, // nc. + &Port2, &Chipset.Port2Size // RAM part 2 + }, + { + 'G', // HP48GX + &pbyRom, &dwRomSize, // ROM + &Port0, &Chipset.Port0Size, // RAM + &pbyNoMEM, NULL, // BS + &Port1, &Chipset.Port1Size, // Card slot 1 + &pbyPort2, &dwPort2Size // Card slot 2 + }, + { + 'S', // HP48SX + &pbyRom, &dwRomSize, // ROM + &Port0, &Chipset.Port0Size, // RAM + &Port1, &Chipset.Port1Size, // Card slot 1 + &pbyPort2, &dwPort2Size, // Card slot 2 + &pbyNoMEM, NULL // nc. + }, + { + 'X', // HP49G + &pbyRom, &dwRomSize, // Flash + &Port0, &Chipset.Port0Size, // RAM + &pbyNoMEM, NULL, // BS + &Port1, &Chipset.Port1Size, // Port 1 part 1 + &Port2, &Chipset.Port2Size // Port 1 part 2 + }, + { // CdB for HP: add Q type + 'Q', // HP49G+ + &pbyRom, &dwRomSize, // Flash + &Port0, &Chipset.Port0Size, // RAM + &pbyNoMEM, NULL, // BS + &Port1, &Chipset.Port1Size, // Port 1 part 1 + &Port2, &Chipset.Port2Size // Port 1 part 2 + }, + { // CdB for HP: add 2 type + '2', // HP48Gii + &pbyRom, &dwRomSize, // ROM + &Port0, &Chipset.Port0Size, // RAM + &pbyNoMEM, NULL, // BS + &pbyNoMEM, NULL, // Port 1 part 1 + &pbyNoMEM, NULL, // Port 1 part 2 + }, + { // CdB for HP: add P type + 'P', // HP39G+ + &pbyRom, &dwRomSize, // ROM + &Port0, &Chipset.Port0Size, // RAM + &pbyNoMEM, NULL, // BS + &pbyNoMEM, NULL, // nc. + &Port2, &Chipset.Port2Size // RAM part 2 + } +}; + +static MODEL_MAP_T CONST *pMapping = MemMap; // model specific memory mapping +static enum MEM_MAPPING eMapType = MEM_MMU; // MMU memory mapping + +static LPBYTE pbyMapData = NULL; +static DWORD dwMapDataSize = 0; +static DWORD dwMapDataMask = 0; + +BOOL SetMemRomType(BYTE cCurrentRomType) +{ + INT i; + + pMapping = MemMap; // init default mapping + + // scan for all table entries + for (i = 0; i < ARRAYSIZEOF(MemMap); ++i) + { + if (MemMap[i].byType == cCurrentRomType) + { + pMapping = &MemMap[i]; // found entry + return TRUE; + } + } + return FALSE; +} + +BOOL SetMemMapType(enum MEM_MAPPING eType) +{ + BOOL bSucc = TRUE; + + eMapType = eType; + + switch (eMapType) + { + case MEM_MMU: + pbyMapData = NULL; // data + dwMapDataSize = 512 * 1024 * 2; // data size + dwMapDataMask = dwMapDataSize - 1; // size mask + break; + case MEM_NCE1: + pbyMapData = *pMapping->ppbyNCE1; + dwMapDataSize = *pMapping->pdwNCE1Size; // ROM size is always in nibbles + dwMapDataMask = dwMapDataSize - 1; // size mask + break; + case MEM_NCE2: + pbyMapData = *pMapping->ppbyNCE2; + dwMapDataSize = *pMapping->pdwNCE2Size * 1024 * 2; + dwMapDataMask = dwMapDataSize - 1; // size mask + break; + case MEM_CE1: + pbyMapData = *pMapping->ppbyCE1; + dwMapDataSize = *pMapping->pdwCE1Size * 1024 * 2; + dwMapDataMask = dwMapDataSize - 1; // size mask + break; + case MEM_CE2: + pbyMapData = *pMapping->ppbyCE2; + dwMapDataSize = *pMapping->pdwCE2Size * 1024 * 2; + dwMapDataMask = dwMapDataSize - 1; // size mask + break; + case MEM_NCE3: + pbyMapData = *pMapping->ppbyNCE3; + dwMapDataSize = *pMapping->pdwNCE3Size * 1024 * 2; + dwMapDataMask = dwMapDataSize - 1; // size mask + break; + default: _ASSERT(FALSE); + pbyMapData = NULL; + dwMapDataSize = 0; + dwMapDataMask = 0; + bSucc = FALSE; + } + return bSucc; +} + +enum MEM_MAPPING GetMemMapType(VOID) +{ + return eMapType; +} + +BOOL GetMemAvail(enum MEM_MAPPING eType) +{ + switch (eType) + { + case MEM_MMU: return TRUE; + case MEM_NCE1: return *pMapping->ppbyNCE1 != NULL; + case MEM_NCE2: return *pMapping->ppbyNCE2 != NULL; + case MEM_CE1: return *pMapping->ppbyCE1 != NULL; + case MEM_CE2: return *pMapping->ppbyCE2 != NULL; + case MEM_NCE3: return *pMapping->ppbyNCE3 != NULL; + default: _ASSERT(FALSE); + } + return FALSE; +} + +DWORD GetMemDataSize(VOID) +{ + return dwMapDataSize; +} + +DWORD GetMemDataMask(VOID) +{ + return dwMapDataMask; +} + +BYTE GetMemNib(DWORD *p) +{ + BYTE byVal; + + if (pbyMapData == NULL) + { + Npeek(&byVal, *p, 1); + } + else + { + byVal = pbyMapData[*p]; + } + *p = (*p + 1) & dwMapDataMask; + return byVal; +} + +VOID GetMemPeek(BYTE *a, DWORD d, UINT s) +{ + if (pbyMapData == NULL) + { + Npeek(a, d, s); + } + else + { + for (; s > 0; --s, ++d) + { + *a++ = pbyMapData[d & dwMapDataMask]; + } + } + return; +} diff --git a/source/DISPLAY.C b/source/source/DISPLAY.C similarity index 95% rename from source/DISPLAY.C rename to source/source/DISPLAY.C index 5565813..e145149 100644 --- a/source/DISPLAY.C +++ b/source/source/DISPLAY.C @@ -29,7 +29,7 @@ |((((c)-1)>>1)<<8) \ |((((c)-1)>>1))) -#define DIBPIXEL(d,p) *((DWORD*)(d)) = ((*((DWORD*)(d)) & dwGrayMask) << 1) | (p); (BYTE *) d += 4 +#define DIBPIXEL(d,p) *((DWORD*)(d)) = ((*((DWORD*)(d)) & dwGrayMask) << 1) | (p); *((LPBYTE*) &(d)) += 4 BOOL bGrayscale = FALSE; // Default is to not emulate grayscale UINT nBackgroundX = 0; diff --git a/source/EMU48.C b/source/source/EMU48.C similarity index 84% rename from source/EMU48.C rename to source/source/EMU48.C index aad92e5..aa3beae 100644 --- a/source/EMU48.C +++ b/source/source/EMU48.C @@ -13,7 +13,7 @@ #include "kml.h" #include "debugger.h" -#define VERSION "1.48+" +#define VERSION "1.53+" // #define MONOCHROME // CF_BITMAP clipboard format @@ -59,7 +59,6 @@ LARGE_INTEGER lFreq; // high performance counter frequency LARGE_INTEGER lAppStart; // high performance counter value at Appl. start DWORD idDdeInst; // DDE server id UINT uCF_HpObj; // DDE clipboard format -HANDLE hHeap; HANDLE hThread; DWORD lThreadId; HANDLE hEventShutdn; // event handle to stop cpu thread @@ -83,6 +82,7 @@ BOOL bAlwaysDisplayLog = TRUE; BOOL bLoadObjectWarning = TRUE; BOOL bAlwaysOnTop = FALSE; // emulator window always on top BOOL bActFollowsMouse = FALSE; // emulator window activation follows mouse +BOOL bSingleInstance = FALSE; // multiple emulator instances allowed //################ @@ -93,7 +93,7 @@ BOOL bActFollowsMouse = FALSE; // emulator window activation follows VOID SetWindowTitle(LPCTSTR szString) { - if (szTitle) HeapFree(hHeap,0,szTitle); + if (szTitle) free(szTitle); _ASSERT(hWnd != NULL); if (szString) @@ -109,44 +109,6 @@ VOID SetWindowTitle(LPCTSTR szString) return; } -VOID UpdateWindowStatus(VOID) -{ - if (hWnd) // window open - { - // disable stack loading items on HP38G, HP39/40G, HP39G+ - BOOL bStackEnable = cCurrentRomType!='6' && cCurrentRomType!='A' && cCurrentRomType!='E' && cCurrentRomType!='P'; // CdB for HP: add apples - BOOL bRun = nState == SM_RUN || nState == SM_SLEEP; - - UINT uStackEnable = (bRun && bStackEnable) ? MF_ENABLED : MF_GRAYED; - UINT uRun = bRun ? MF_ENABLED : MF_GRAYED; - UINT uBackup = bBackup ? MF_ENABLED : MF_GRAYED; - - HMENU hMenu = GetMenu(hWnd); // get menu handle - - EnableMenuItem(hMenu,ID_FILE_NEW,MF_ENABLED); - EnableMenuItem(hMenu,ID_FILE_OPEN,MF_ENABLED); - EnableMenuItem(hMenu,ID_FILE_SAVE,(bRun && szCurrentFilename[0]) ? MF_ENABLED : MF_GRAYED); - EnableMenuItem(hMenu,ID_FILE_SAVEAS,uRun); - EnableMenuItem(hMenu,ID_FILE_CLOSE,uRun); - EnableMenuItem(hMenu,ID_OBJECT_LOAD,uStackEnable); - EnableMenuItem(hMenu,ID_OBJECT_SAVE,uStackEnable); - EnableMenuItem(hMenu,ID_VIEW_COPY,uRun); - EnableMenuItem(hMenu,ID_STACK_COPY,uStackEnable); - EnableMenuItem(hMenu,ID_STACK_PASTE,uStackEnable); - EnableMenuItem(hMenu,ID_VIEW_RESET,uRun); - EnableMenuItem(hMenu,ID_BACKUP_SAVE,uRun); - EnableMenuItem(hMenu,ID_BACKUP_RESTORE,uBackup); - EnableMenuItem(hMenu,ID_BACKUP_DELETE,uBackup); - EnableMenuItem(hMenu,ID_VIEW_SCRIPT,uRun); - EnableMenuItem(hMenu,ID_TOOL_DISASM,uRun); - EnableMenuItem(hMenu,ID_TOOL_DEBUG,(bRun && nDbgState == DBG_OFF) ? MF_ENABLED : MF_GRAYED); - EnableMenuItem(hMenu,ID_TOOL_MACRO_RECORD,(bRun && nMacroState == MACRO_OFF) ? MF_ENABLED : MF_GRAYED); - EnableMenuItem(hMenu,ID_TOOL_MACRO_PLAY,(bRun && nMacroState == MACRO_OFF) ? MF_ENABLED : MF_GRAYED); - EnableMenuItem(hMenu,ID_TOOL_MACRO_STOP,(bRun && nMacroState != MACRO_OFF) ? MF_ENABLED : MF_GRAYED); - } - return; -} - VOID ForceForegroundWindow(HWND hWnd) { // force window to foreground @@ -176,7 +138,7 @@ VOID CopyItemsToClipboard(HWND hWnd) // save selected Listbox Items to Clipboar if ((i = (LONG) SendMessage(hWnd,LB_GETSELCOUNT,0,0)) == 0) return; // no items selected - if ((lpnCount = HeapAlloc(hHeap,0,i * sizeof(INT))) != NULL) + if ((lpnCount = malloc(i * sizeof(INT))) != NULL) { LPTSTR lpszData; HANDLE hClipObj; @@ -221,7 +183,7 @@ VOID CopyItemsToClipboard(HWND hWnd) // save selected Listbox Items to Clipboar GlobalFree(hClipObj); } } - HeapFree(hHeap,0,lpnCount); // free item table + free(lpnCount); // free item table } return; } @@ -327,7 +289,8 @@ static VOID SetCommList(HWND hDlg,LPCTSTR szWireSetting,LPCTSTR szIrSetting) static INT_PTR CALLBACK SettingsProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { - HWND hWndInsertAfter; + TCHAR cPort[8]; + HWND hWndInsertAfter; LPCTSTR szActPort2Filename = _T(""); @@ -359,6 +322,11 @@ static INT_PTR CALLBACK SettingsProc(HWND hDlg, UINT message, WPARAM wParam, LPA CheckDlgButton(hDlg,bWaveBeep ? IDC_SOUND_WAVE : IDC_SOUND_SPEAKER,BST_CHECKED); EnableWindow(GetDlgItem(hDlg,IDC_SOUND_SLIDER),bWaveBeep); + // UDP infrared printer settings + SetDlgItemText(hDlg,IDC_IR_ADDR,szUdpServer); + wsprintf(cPort,_T("%u"),wUdpPort); + SetDlgItemText(hDlg,IDC_IR_PORT,cPort); + // set combobox parameter SetCommList(hDlg,szSerialWire,szSerialIr); if (bCommInit) // disable when port open @@ -567,6 +535,11 @@ static INT_PTR CALLBACK SettingsProc(HWND hDlg, UINT message, WPARAM wParam, LPA // set sound data dwWaveVol = (DWORD) SendDlgItemMessage(hDlg,IDC_SOUND_SLIDER,TBM_GETPOS,0,0); bWaveBeep = IsDlgButtonChecked(hDlg,IDC_SOUND_WAVE); + // UDP infrared printer settings + GetDlgItemText(hDlg,IDC_IR_ADDR,szUdpServer,ARRAYSIZEOF(szUdpServer)); + GetDlgItemText(hDlg,IDC_IR_PORT,cPort,ARRAYSIZEOF(cPort)); + wUdpPort = (WORD) _ttoi(cPort); + ResetUdp(); // invalidate saved UDP address // set combobox parameter GetDlgItemText(hDlg,IDC_WIRE,szSerialWire,ARRAYSIZEOF(szSerialWire)); // HP49G, 48GII, 49G+ Ir port is not connected @@ -607,7 +580,7 @@ static UINT SaveChanges(BOOL bAuto) { UINT uReply; - if (pbyRom == NULL) return IDNO; + if (bDocumentAvail == FALSE) return IDNO; if (bAuto) uReply = IDYES; @@ -758,6 +731,42 @@ static LRESULT OnPaint(HWND hWindow) return 0; } +// +// WM_INITMENU +// +static LRESULT OnInitMenu(HMENU hMenu) +{ + // disable stack loading items on HP38G, HP39/40G, HP39G+ + BOOL bStackEnable = cCurrentRomType!='6' && cCurrentRomType!='A' && cCurrentRomType!='E' && cCurrentRomType!='P'; // CdB for HP: add apples + BOOL bRun = nState == SM_RUN || nState == SM_SLEEP; + + UINT uStackEnable = (bRun && bStackEnable) ? MF_ENABLED : MF_GRAYED; + UINT uRun = bRun ? MF_ENABLED : MF_GRAYED; + UINT uBackup = bBackup ? MF_ENABLED : MF_GRAYED; + + EnableMenuItem(hMenu,ID_FILE_NEW,MF_ENABLED); + EnableMenuItem(hMenu,ID_FILE_OPEN,MF_ENABLED); + EnableMenuItem(hMenu,ID_FILE_SAVE,(bRun && szCurrentFilename[0]) ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu,ID_FILE_SAVEAS,uRun); + EnableMenuItem(hMenu,ID_FILE_CLOSE,uRun); + EnableMenuItem(hMenu,ID_OBJECT_LOAD,uStackEnable); + EnableMenuItem(hMenu,ID_OBJECT_SAVE,uStackEnable); + EnableMenuItem(hMenu,ID_VIEW_COPY,uRun); + EnableMenuItem(hMenu,ID_STACK_COPY,uStackEnable); + EnableMenuItem(hMenu,ID_STACK_PASTE,uStackEnable); + EnableMenuItem(hMenu,ID_VIEW_RESET,uRun); + EnableMenuItem(hMenu,ID_BACKUP_SAVE,uRun); + EnableMenuItem(hMenu,ID_BACKUP_RESTORE,uBackup); + EnableMenuItem(hMenu,ID_BACKUP_DELETE,uBackup); + EnableMenuItem(hMenu,ID_VIEW_SCRIPT,uRun); + EnableMenuItem(hMenu,ID_TOOL_DISASM,uRun); + EnableMenuItem(hMenu,ID_TOOL_DEBUG,(bRun && nDbgState == DBG_OFF) ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu,ID_TOOL_MACRO_RECORD,(bRun && nMacroState == MACRO_OFF) ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu,ID_TOOL_MACRO_PLAY,(bRun && nMacroState == MACRO_OFF) ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu,ID_TOOL_MACRO_STOP,(bRun && nMacroState != MACRO_OFF) ? MF_ENABLED : MF_GRAYED); + return 0; +} + // // WM_DROPFILES // @@ -836,7 +845,6 @@ static LRESULT OnFileNew(VOID) SaveBackup(); } if (NewDocument()) SetWindowTitle(_T("Untitled")); - UpdateWindowStatus(); cancel: if (pbyRom) SwitchToState(SM_RUN); return 0; @@ -1031,7 +1039,7 @@ static LRESULT OnViewCopy(VOID) lpbi->biClrImportant = 0; // get bitmap color table and bitmap data GetDIBits(hBmpDC, hBmp, 0, lpbi->biHeight, (LPBYTE)lpbi + dwLen - dwSizeImage, - (LPBITMAPINFO)lpbi, DIB_RGB_COLORS); + (LPBITMAPINFO)lpbi, DIB_RGB_COLORS); GlobalUnlock(hClipObj); SetClipboardData(CF_DIB, hClipObj); @@ -1039,13 +1047,13 @@ static LRESULT OnViewCopy(VOID) GetObject(hPalette,sizeof(WORD),&wBits); // memory allocation for temporary palette data - if ((ppal = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(LOGPALETTE) + wBits * sizeof(PALETTEENTRY))) != NULL) + if ((ppal = calloc(sizeof(LOGPALETTE) + wBits * sizeof(PALETTEENTRY),1)) != NULL) { ppal->palVersion = PALVERSION; ppal->palNumEntries = wBits; GetPaletteEntries(hPalette, 0, wBits, ppal->palPalEntry); SetClipboardData(CF_PALETTE, CreatePalette(ppal)); - HeapFree(hHeap,0,ppal); + free(ppal); } } DeleteDC(hBmpDC); @@ -1107,6 +1115,9 @@ static LRESULT OnViewSettings(VOID) // static LRESULT OnViewScript(VOID) { + TCHAR szKmlFile[MAX_PATH]; + BOOL bKMLChanged,bSucc; + BYTE cType = cCurrentRomType; if (nState != SM_RUN) { @@ -1116,14 +1127,50 @@ static LRESULT OnViewScript(VOID) } SwitchToState(SM_INVALID); + // make a copy of the current KML script file name + _ASSERT(sizeof(szKmlFile) == sizeof(szCurrentKml)); + lstrcpyn(szKmlFile,szCurrentKml,ARRAYSIZEOF(szKmlFile)); + + bKMLChanged = FALSE; // KML script not changed + bSucc = TRUE; // KML script successful loaded + do { - if (!DisplayChooseKml(cType)) break; - } - while(!InitKML(szCurrentKml,FALSE)); + if (!DisplayChooseKml(cType)) // quit with Cancel + { + if (!bKMLChanged) // KML script not changed + break; // exit loop with current loaded KML script - SetWindowPathTitle(szCurrentFilename); // update window title line - if (pbyRom) SwitchToState(SM_RUN); + // restore KML script file name + lstrcpyn(szCurrentKml,szKmlFile,ARRAYSIZEOF(szCurrentKml)); + + // try to restore old KML script + if ((bSucc = InitKML(szCurrentKml,FALSE))) + break; // exit loop with success + + // restoring failed, save document + if (IDCANCEL != SaveChanges(bAutoSave)) + break; // exit loop with no success + + _ASSERT(bSucc == FALSE); // for continuing loop + } + else // quit with Ok + { + bKMLChanged = TRUE; // KML script changed + bSucc = InitKML(szCurrentKml,FALSE); + } + } + while (!bSucc); // retry if KML script is invalid + + if (bSucc) + { + if (pbyRom) SwitchToState(SM_RUN); // continue emulation + } + else + { + ResetDocument(); // close document + SetWindowTitle(NULL); + } return 0; } @@ -1272,60 +1319,76 @@ static LRESULT OnObjectSave(VOID) // static INT_PTR CALLBACK Disasm(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { - static DWORD dwAddress, dwAddressMax; + static DWORD dwAddress,dwAddressMax; + enum MEM_MAPPING eMode; LONG i; DWORD dwNxtAddr; - TCHAR *cpStop,szAddress[256] = _T("0"); + TCHAR szAddress[256] = _T("0"); switch (message) { case WM_INITDIALOG: + VERIFY(SetMemRomType(cCurrentRomType)); // set current model + // set fonts & cursor SendDlgItemMessage(hDlg,IDC_DISASM_MODULE,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); - SendDlgItemMessage(hDlg,IDC_DISASM_MAP,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); - SendDlgItemMessage(hDlg,IDC_DISASM_ROM,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); - SendDlgItemMessage(hDlg,IDC_DISASM_RAM,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); - SendDlgItemMessage(hDlg,IDC_DISASM_PORT1,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); - SendDlgItemMessage(hDlg,IDC_DISASM_PORT2,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); - SendDlgItemMessage(hDlg,IDC_DISASM_MAP,BM_SETCHECK,1,0); + SendDlgItemMessage(hDlg,IDC_DISASM_MODE_TEXT,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); + SendDlgItemMessage(hDlg,IDC_DISASM_MODE,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); SendDlgItemMessage(hDlg,IDC_ADDRESS,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); SendDlgItemMessage(hDlg,IDC_DISASM_ADR,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); SendDlgItemMessage(hDlg,IDC_DISASM_NEXT,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); SendDlgItemMessage(hDlg,IDC_DISASM_COPY,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); SendDlgItemMessage(hDlg,IDCANCEL,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); + + // fill disassembler mode combo box + { + // disassemble mode window + HWND hWnd = GetDlgItem(hDlg,IDC_DISASM_MODE); + + if (hDlgDebug == NULL) // debugger not open + { + LPCTSTR lpszModes[] = { _T("Map"), _T("NCE1"), _T("NCE2"), _T("CE1"), _T("CE2"), _T("NCE3") }; + + for (eMode = MEM_MMU; eMode <= MEM_NCE3; eMode = (enum MEM_MAPPING) (eMode + 1)) + { + if (GetMemAvail(eMode)) + { + _ASSERT(eMode < ARRAYSIZEOF(lpszModes)); + i = (LONG) SendMessage(hWnd,CB_ADDSTRING,0,(LPARAM) lpszModes[eMode]); + SendMessage(hWnd,CB_SETITEMDATA,i,(LPARAM) eMode); + } + } + VERIFY(SendMessage(hWnd,CB_SETCURSEL,0,0) != LB_ERR); + + // disassemble with mapped modules + VERIFY(SetMemMapType(MEM_MMU)); + } + else // debugger open + { + EnableWindow(hWnd,FALSE); + } + } + SetDlgItemText(hDlg,IDC_DISASM_ADR,szAddress); - disassembler_map = MEM_MAP; // disassemble with mapped modules - dwAddress = _tcstoul(szAddress,&cpStop,16); - dwAddressMax = 0x100000; // greatest address (mapped mode) + dwAddressMax = GetMemDataSize(); + dwAddress = _tcstoul(szAddress,NULL,16); return TRUE; case WM_COMMAND: switch(LOWORD(wParam)) { - // decode radio buttons - case IDC_DISASM_MAP: - disassembler_map = MEM_MAP; - dwAddressMax = 0x100000; - return TRUE; - case IDC_DISASM_ROM: - disassembler_map = MEM_ROM; - dwAddressMax = dwRomSize; - return TRUE; - case IDC_DISASM_RAM: - disassembler_map = MEM_RAM; - dwAddressMax = Chipset.Port0Size * 2048; - return TRUE; - case IDC_DISASM_PORT1: - disassembler_map = MEM_PORT1; - dwAddressMax = ((Chipset.cards_status & PORT1_PRESENT) != 0) ? (Chipset.Port1Size * 2048) : 0; - return TRUE; - case IDC_DISASM_PORT2: - disassembler_map = MEM_PORT2; - dwAddressMax = ((cCurrentRomType=='E' || cCurrentRomType=='X' || cCurrentRomType=='P' || cCurrentRomType=='2' || cCurrentRomType=='Q') // CdB for HP: add apples - ? Chipset.Port2Size - : dwPort2Size) - * 2048; - return TRUE; + // decode memory mode combo box + case IDC_DISASM_MODE: + // new combo box item selected + if (HIWORD(wParam) == CBN_SELENDOK) + { + HWND hWnd = GetDlgItem(hDlg,IDC_DISASM_MODE); + i = (LONG) SendMessage(hWnd,CB_GETCURSEL,0,0); + eMode = (enum MEM_MAPPING) SendMessage(hWnd,CB_GETITEMDATA,i,0); + VERIFY(SetMemMapType(eMode)); + dwAddressMax = GetMemDataSize(); + } + break; case IDOK: SendDlgItemMessage(hDlg,IDC_DISASM_ADR,EM_SETSEL,0,-1); GetDlgItemText(hDlg,IDC_DISASM_ADR,szAddress,ARRAYSIZEOF(szAddress)); @@ -1335,7 +1398,7 @@ static INT_PTR CALLBACK Disasm(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP if (_istxdigit(szAddress[i]) == FALSE) return FALSE; } - dwAddress = _tcstoul(szAddress,&cpStop,16); + dwAddress = _tcstoul(szAddress,NULL,16); // no break case IDC_DISASM_NEXT: if (dwAddress >= dwAddressMax) @@ -1482,7 +1545,8 @@ LRESULT CALLBACK MainWndProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lPar case WM_CREATE: return OnCreate(hWindow); case WM_DESTROY: return OnDestroy(hWindow); case WM_PAINT: return OnPaint(hWindow); - case WM_DROPFILES: return OnDropFiles((HANDLE)wParam); + case WM_INITMENU: return OnInitMenu((HMENU) wParam); + case WM_DROPFILES: return OnDropFiles((HANDLE) wParam); case WM_ACTIVATE: if (LOWORD(wParam)==WA_INACTIVE) break; case WM_QUERYNEWPALETTE: @@ -1562,6 +1626,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC { MSG msg; WNDCLASS wc; + ATOM classAtom; RECT rectWindow; HACCEL hAccel; HSZ hszService, hszTopic; // variables for DDE server @@ -1580,13 +1645,6 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC } #endif - hHeap = GetProcessHeap(); - if (hHeap == NULL) - { - AbortMessage(_T("Heap creation failed.")); - return FALSE; - } - wc.style = CS_BYTEALIGNCLIENT; wc.lpfnWndProc = (WNDPROC)MainWndProc; wc.cbClsExtra = 0; @@ -1598,7 +1656,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU); wc.lpszClassName = _T("CEmu48"); - if (!RegisterClass(&wc)) + if (!(classAtom = RegisterClass(&wc))) { AbortMessage( _T("CEmu48 class registration failed.\n") @@ -1606,6 +1664,21 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC return FALSE; } + // read emulator settings + GetCurrentDirectory(ARRAYSIZEOF(szCurrentDirectory),szCurrentDirectory); + ReadSettings(); + + // running an instance of me? + if (bSingleInstance && (hWnd = FindWindow(MAKEINTATOM(classAtom),NULL)) != NULL) + { + if (IsIconic(hWnd)) // window minimized + ShowWindow(hWnd,SW_RESTORE); // show window + + // put the window into foreground + ForceForegroundWindow(GetLastActivePopup(hWnd)); + return 0; // quit + } + // Create window rectWindow.left = 0; rectWindow.top = 0; @@ -1613,13 +1686,12 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC rectWindow.bottom = 0; AdjustWindowRect(&rectWindow, WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_OVERLAPPED, TRUE); - hWnd = CreateWindow(_T("CEmu48"), _T("Emu48"), + hWnd = CreateWindow(MAKEINTATOM(classAtom),_T("Emu48"), WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_OVERLAPPED, CW_USEDEFAULT, CW_USEDEFAULT, rectWindow.right - rectWindow.left, rectWindow.bottom - rectWindow.top, - NULL,NULL,hApp,NULL - ); + NULL,NULL,hApp,NULL); if (hWnd == NULL) { @@ -1633,13 +1705,10 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC QueryPerformanceFrequency(&lFreq); // init high resolution counter QueryPerformanceCounter(&lAppStart); - GetCurrentDirectory(ARRAYSIZEOF(szCurrentDirectory), szCurrentDirectory); szCurrentKml[0] = 0; // no KML file selected - ReadSettings(); + SetSpeed(bRealSpeed); // set speed MruInit(0); // init MRU entries - UpdateWindowStatus(); - // create auto event handle hEventShutdn = CreateEvent(NULL,FALSE,FALSE,NULL); if (hEventShutdn == NULL) @@ -1667,9 +1736,9 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC idDdeInst = 0; // initialize DDE server if (DdeInitialize(&idDdeInst,(PFNCALLBACK) &DdeCallback, - APPCLASS_STANDARD | - CBF_FAIL_EXECUTES | CBF_FAIL_ADVISES | - CBF_SKIP_REGISTRATIONS | CBF_SKIP_UNREGISTRATIONS,0)) + APPCLASS_STANDARD | + CBF_FAIL_EXECUTES | CBF_FAIL_ADVISES | + CBF_SKIP_REGISTRATIONS | CBF_SKIP_UNREGISTRATIONS,0)) { TerminateThread(hThread, 0); // kill emulation thread CloseHandle(hEventShutdn); // close event handle @@ -1755,6 +1824,7 @@ start: _ASSERT(pKml == NULL); // KML script not closed _ASSERT(szTitle == NULL); // freed allocated memory _ASSERT(hPalette == NULL); // freed resource memory + _CrtDumpMemoryLeaks(); // show memory leaks return (int) msg.wParam; UNREFERENCED_PARAMETER(lpCmdLine); diff --git a/source/EMU48.H b/source/source/EMU48.H similarity index 89% rename from source/EMU48.H rename to source/source/EMU48.H index 7a6fea2..5dc3242 100644 --- a/source/EMU48.H +++ b/source/source/EMU48.H @@ -10,6 +10,7 @@ #define HARDWARE "Yorke" // emulator hardware #define MODELS "26AEGPQSX" // valid calculator models +#define APPLEHARD "2PQ" // Apple platform calculator models #define ARRAYSIZEOF(a) (sizeof(a) / sizeof(a[0])) @@ -47,12 +48,6 @@ #define HP_MNEMONICS FALSE // disassembler mnenomics mode #define CLASS_MNEMONICS TRUE -#define MEM_MAP 0 // memory module definition -#define MEM_ROM 1 -#define MEM_RAM 2 -#define MEM_PORT1 3 -#define MEM_PORT2 4 - #define MACRO_OFF 0 // macro recorder off #define MACRO_NEW 1 #define MACRO_PLAY 2 @@ -64,10 +59,14 @@ // macro to check for valid calculator model #define isModelValid(m) (m != 0 && strchr(MODELS,m) != NULL) +#define isModelApple(m) (m != 0 && strchr(APPLEHARD,m) != NULL) // values for mapping area enum MMUMAP { M_IO, M_ROM, M_RAM, M_P1, M_P2, M_BS }; +// values for disassembler memory mapping modes +enum MEM_MAPPING { MEM_MMU, MEM_NCE1, MEM_NCE2, MEM_CE1, MEM_CE2, MEM_NCE3 }; + // Emu48.c extern HPALETTE hPalette; extern HPALETTE hOldPalette; @@ -90,7 +89,6 @@ extern LARGE_INTEGER lFreq; extern LARGE_INTEGER lAppStart; extern DWORD idDdeInst; extern UINT uCF_HpObj; -extern HANDLE hHeap; extern HINSTANCE hApp; extern HWND hWnd; extern HWND hDlgDebug; @@ -108,11 +106,11 @@ extern BOOL bAlwaysDisplayLog; extern BOOL bLoadObjectWarning; extern BOOL bAlwaysOnTop; extern BOOL bActFollowsMouse; +extern BOOL bSingleInstance; extern HANDLE hThread; extern DWORD lThreadId; extern VOID SetWindowTitle(LPCTSTR szString); extern VOID CopyItemsToClipboard(HWND hWnd); -extern VOID UpdateWindowStatus(VOID); extern VOID ForceForegroundWindow(HWND hWnd); // mru.c @@ -172,6 +170,7 @@ extern UINT nState; extern UINT nNextState; extern BOOL bRealSpeed; extern BOOL bKeySlow; +extern UINT nOpcSlow; extern BOOL bCommInit; extern BOOL bGrayscale; extern CHIPSET Chipset; @@ -199,6 +198,7 @@ extern WORD wInstrRp; extern VOID SuspendDebugger(VOID); extern VOID ResumeDebugger(VOID); extern VOID CheckSerial(VOID); +extern VOID InitAdjustSpeed(VOID); extern VOID AdjKeySpeed(VOID); extern VOID SetSpeed(BOOL bAdjust); extern VOID UpdateKdnBit(VOID); @@ -219,6 +219,7 @@ extern TCHAR szCurrentFilename[MAX_PATH]; extern TCHAR szBackupFilename[MAX_PATH]; extern TCHAR szBufferFilename[MAX_PATH]; extern TCHAR szPort2Filename[MAX_PATH]; +extern BOOL bDocumentAvail; extern BYTE cCurrentRomType; extern UINT nCurrentClass; extern LPBYTE Port0; @@ -306,12 +307,22 @@ extern VOID KeyboardEvent(BOOL bPress, UINT out, UINT in); extern INT nMacroState; extern INT nMacroTimeout; extern BOOL bMacroRealSpeed; +extern DWORD dwMacroMinDelay; extern VOID KeyMacroRecord(BOOL bPress, UINT out, UINT in); extern LRESULT OnToolMacroNew(VOID); extern LRESULT OnToolMacroPlay(VOID); extern LRESULT OnToolMacroStop(VOID); extern LRESULT OnToolMacroSettings(VOID); +// Redeye.c +extern VOID IrPrinter(BYTE c); + +// Udp.c +extern TCHAR szUdpServer[1024]; +extern WORD wUdpPort; +extern VOID ResetUdp(VOID); +extern BOOL SendByteUdp(BYTE byData); + // Stack.c extern BOOL bDetectClpObject; extern LRESULT OnStackCopy(VOID); @@ -336,11 +347,19 @@ extern VOID RCKBp(CHIPSET* w); // DDEserv.c extern HDDEDATA CALLBACK DdeCallback(UINT, UINT, HCONV, HSZ, HSZ, HDDEDATA, DWORD, DWORD); +// Dismem.c +extern BOOL SetMemRomType(BYTE cCurrentRomType); +extern BOOL SetMemMapType(enum MEM_MAPPING eType); +extern enum MEM_MAPPING GetMemMapType(VOID); +extern BOOL GetMemAvail(enum MEM_MAPPING eType); +extern DWORD GetMemDataSize(VOID); +extern DWORD GetMemDataMask(VOID); +extern BYTE GetMemNib(DWORD *p); +extern VOID GetMemPeek(BYTE *a, DWORD d, UINT s); + // Disasm.c extern BOOL disassembler_mode; extern BOOL disassembler_symb; -extern WORD disassembler_map; -extern BYTE read_nibble(DWORD *p); extern DWORD disassemble(DWORD addr, LPTSTR out); // Symbfile.c @@ -382,7 +401,7 @@ static __inline int YesNoCancelMessage(LPCTSTR szMessage,UINT uStyle) {return Me static __inline LPTSTR DuplicateString(LPCTSTR szString) { UINT uLength = lstrlen(szString) + 1; - LPTSTR szDup = HeapAlloc(hHeap,0,uLength*sizeof(szDup[0])); + LPTSTR szDup = malloc(uLength*sizeof(szDup[0])); lstrcpy(szDup,szString); return szDup; } diff --git a/source/EMU48.ICO b/source/source/EMU48.ICO similarity index 100% rename from source/EMU48.ICO rename to source/source/EMU48.ICO diff --git a/source/EMU48.RC b/source/source/EMU48.RC similarity index 84% rename from source/EMU48.RC rename to source/source/EMU48.RC index d632f15..a615aa1 100644 --- a/source/EMU48.RC +++ b/source/source/EMU48.RC @@ -74,7 +74,7 @@ BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 160 TOPMARGIN, 4 - BOTTOMMARGIN, 270 + BOTTOMMARGIN, 319 END IDD_CHOOSEKML, DIALOG @@ -149,6 +149,22 @@ BEGIN BOTTOMMARGIN, 74 END + IDD_DEBUG_MEMSAVE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 257 + TOPMARGIN, 7 + BOTTOMMARGIN, 58 + END + + IDD_DEBUG_MEMLOAD, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 257 + TOPMARGIN, 7 + BOTTOMMARGIN, 58 + END + IDD_DEBUG_SETTINGS, DIALOG BEGIN LEFTMARGIN, 7 @@ -191,9 +207,10 @@ BEGIN LTEXT "Find &what:",IDC_STATIC,7,9,34,8 COMBOBOX IDC_FIND_DATA,46,7,88,41,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP - CONTROL "Find &ASCII",IDC_FIND_ASCII,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,46,30,49,10 - DEFPUSHBUTTON "&Find Next",IDOK,140,7,50,14 + CONTROL "Find &ASCII",IDC_FIND_ASCII,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,141,9,49,10 + PUSHBUTTON "&Previous",IDC_FIND_PREV,6,26,50,14 + DEFPUSHBUTTON "&Next",IDC_FIND_NEXT,74,26,50,14 PUSHBUTTON "Cancel",IDCANCEL,140,26,50,14 END @@ -233,14 +250,14 @@ FONT 8, "MS Sans Serif" BEGIN ICON IDI_EMU48,IDC_STATIC,7,6,20,20,SS_REALSIZEIMAGE LTEXT "",IDC_VERSION,29,6,151,8,NOT WS_GROUP - LTEXT "Copyright © 2010 Christoph Gießelink && Sébastien Carlier", + LTEXT "Copyright © 2012 Christoph Gießelink && Sébastien Carlier", IDC_STATIC,29,18,181,8 DEFPUSHBUTTON "OK",IDOK,215,12,39,14 EDITTEXT IDC_LICENSE,7,33,247,112,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY END -IDD_SETTINGS DIALOG DISCARDABLE 0, 0, 167, 287 +IDD_SETTINGS DIALOG DISCARDABLE 0, 0, 167, 326 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Settings" FONT 8, "MS Sans Serif" @@ -249,10 +266,10 @@ BEGIN 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 "Always On Top",IDC_ALWAYSONTOP,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,13,37,65,10 - CONTROL "Activation Follows Mouse",IDC_ACTFOLLOWSMOUSE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,49,100,10 + CONTROL "Always On Top",IDC_ALWAYSONTOP,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,13,37,65,10 + CONTROL "Activation Follows Mouse",IDC_ACTFOLLOWSMOUSE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,13,49,100,10 CONTROL "Automatically Save Files",IDC_AUTOSAVE,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,13,61,89,10 CONTROL "Automatically Save Files On Exit",IDC_AUTOSAVEONEXIT, @@ -263,39 +280,44 @@ BEGIN "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,97,133,10 GROUPBOX "General",IDC_STATIC,7,4,153,107 CONTROL "HP Mnemonics",IDC_DISASM_HP,"Button",BS_AUTORADIOBUTTON | - WS_GROUP | WS_TABSTOP,13,125,65,11 + WS_GROUP | WS_TABSTOP,13,123,65,11 CONTROL "Class Mnemonics",IDC_DISASM_CLASS,"Button", - BS_AUTORADIOBUTTON,84,125,70,11 - GROUPBOX "Disassembler",IDC_STATIC,7,114,153,28 - LTEXT "Volume",IDC_STATIC,13,158,24,8 + BS_AUTORADIOBUTTON,84,123,70,11 + GROUPBOX "Disassembler",IDC_STATIC,7,114,153,26 + LTEXT "Volume",IDC_STATIC,13,156,24,8 CONTROL "Slider1",IDC_SOUND_SLIDER,"msctls_trackbar32", - TBS_AUTOTICKS | WS_TABSTOP,39,153,68,18 + TBS_AUTOTICKS | WS_TABSTOP,39,151,68,18 CONTROL "Speaker",IDC_SOUND_SPEAKER,"Button",BS_AUTORADIOBUTTON | - WS_GROUP | WS_TABSTOP,111,152,43,10 + WS_GROUP | WS_TABSTOP,111,150,43,10 CONTROL "Wave",IDC_SOUND_WAVE,"Button",BS_AUTORADIOBUTTON,111, - 163,43,10 - GROUPBOX "Sound",IDC_STATIC,7,144,153,34 + 161,43,10 + GROUPBOX "Sound",IDC_STATIC,7,142,153,34 CONTROL "Port 1 is Plugged",IDC_PORT1EN,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,13,189,67,10 + WS_TABSTOP,13,187,67,10 CONTROL "Port 1 is Writeable",IDC_PORT1WR,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,84,189,69,10 + BS_AUTOCHECKBOX | WS_TABSTOP,84,187,69,10 CONTROL "Port 2 is Shared",IDC_PORT2ISSHARED,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,13,201,65,10 + BS_AUTOCHECKBOX | WS_TABSTOP,13,199,65,10 CONTROL "Port 2 is Writeable",IDC_PORT2WR,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,84,201,69,10 - LTEXT "Port 2 File :",IDC_STATIC,13,216,37,8 - EDITTEXT IDC_PORT2,51,214,94,12,ES_AUTOHSCROLL - PUSHBUTTON "...",IDC_PORT2LOAD,145,214,10,12 - GROUPBOX "Memory Cards",IDC_STATIC,7,180,153,51 - LTEXT "Wire:",IDC_STATIC,13,245,17,8 - COMBOBOX IDC_WIRE,31,243,48,42,CBS_DROPDOWNLIST | WS_VSCROLL | + BS_AUTOCHECKBOX | WS_TABSTOP,84,199,69,10 + LTEXT "Port 2 File :",IDC_STATIC,13,214,37,8 + EDITTEXT IDC_PORT2,51,212,94,12,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_PORT2LOAD,145,212,10,12 + GROUPBOX "Memory Cards",IDC_STATIC,7,178,153,51 + LTEXT "IP Address:",IDC_STATIC,13,242,37,8 + LTEXT "Port:",IDC_STATIC,126,242,16,8 + EDITTEXT IDC_IR_ADDR,13,252,110,12,ES_AUTOHSCROLL + EDITTEXT IDC_IR_PORT,126,252,28,12,ES_NUMBER + GROUPBOX "Infrared Printer",IDC_STATIC,7,232,153,38 + LTEXT "Wire:",IDC_STATIC,13,284,17,8 + COMBOBOX IDC_WIRE,31,282,48,42,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "IR:",IDC_STATIC,89,245,9,8 - COMBOBOX IDC_IR,107,243,48,43,CBS_DROPDOWNLIST | WS_VSCROLL | + LTEXT "IR:",IDC_STATIC,89,284,9,8 + COMBOBOX IDC_IR,107,282,48,43,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Serial Ports",IDC_STATIC,7,233,153,27 - DEFPUSHBUTTON "OK",IDOK,9,266,50,14 - PUSHBUTTON "Cancel",IDCANCEL,107,266,50,14 + GROUPBOX "Serial Ports",IDC_STATIC,7,272,153,27 + DEFPUSHBUTTON "OK",IDOK,9,305,50,14 + PUSHBUTTON "Cancel",IDCANCEL,107,305,50,14 END IDD_CHOOSEKML DIALOG DISCARDABLE 0, 0, 195, 66 @@ -343,17 +365,10 @@ BEGIN PUSHBUTTON "&Next Address",IDC_DISASM_NEXT,99,144,47,14 PUSHBUTTON "&Copy Data",IDC_DISASM_COPY,150,144,47,14 PUSHBUTTON "Cancel",IDCANCEL,201,144,47,14 + LTEXT "Mapping Mode:",IDC_DISASM_MODE_TEXT,12,17,45,8 + COMBOBOX IDC_DISASM_MODE,60,14,35,90,CBS_DROPDOWNLIST | + WS_TABSTOP GROUPBOX "Module",IDC_DISASM_MODULE,7,5,241,26 - CONTROL "Map",IDC_DISASM_MAP,"Button",BS_AUTORADIOBUTTON | - WS_GROUP | WS_TABSTOP,14,16,37,10 - CONTROL "ROM",IDC_DISASM_ROM,"Button",BS_AUTORADIOBUTTON,61,16, - 37,10 - CONTROL "RAM",IDC_DISASM_RAM,"Button",BS_AUTORADIOBUTTON,108,16, - 37,10 - CONTROL "Port 1",IDC_DISASM_PORT1,"Button",BS_AUTORADIOBUTTON, - 155,16,37,10 - CONTROL "Port 2",IDC_DISASM_PORT2,"Button",BS_AUTORADIOBUTTON, - 202,16,37,10 LISTBOX IDC_DISASM_WIN,7,37,241,100,NOT LBS_NOTIFY | LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOP @@ -515,7 +530,7 @@ BEGIN LTEXT "Fast",IDC_MACRO_FAST,78,16,14,8,WS_DISABLED CONTROL "Slider1",IDC_MACRO_SLIDER,"msctls_trackbar32", TBS_AUTOTICKS | WS_DISABLED | WS_TABSTOP,12,26,82,21 - CONTROL "&Real",IDC_MACRO_REAL,"Button",BS_AUTORADIOBUTTON | + CONTROL "&Real",IDC_MACRO_REAL,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,103,18,39,10 CONTROL "&Manual",IDC_MACRO_MANUAL,"Button",BS_AUTORADIOBUTTON, 103,32,39,10 @@ -524,6 +539,36 @@ BEGIN PUSHBUTTON "Cancel",IDCANCEL,93,60,50,14 END +IDD_DEBUG_MEMSAVE DIALOG DISCARDABLE 0, 0, 264, 65 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Save Memory Data" +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "File:",IDC_STATIC,7,10,14,8 + EDITTEXT IDC_DEBUG_DATA_FILE,25,7,181,14,ES_AUTOHSCROLL + PUSHBUTTON "Browse",IDC_DEBUG_DATA_BUT,207,7,50,14 + LTEXT "Start Address (hexadecimal):",IDC_STATIC,7,30,90,8 + EDITTEXT IDC_DEBUG_DATA_STARTADDR,101,27,37,14 + LTEXT "End Address (hexadecimal):",IDC_STATIC,7,46,88,8 + EDITTEXT IDC_DEBUG_DATA_ENDADDR,101,44,37,14 + PUSHBUTTON "OK",IDOK,207,27,50,14 + PUSHBUTTON "Cancel",IDCANCEL,207,44,50,14 +END + +IDD_DEBUG_MEMLOAD DIALOG DISCARDABLE 0, 0, 264, 65 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Load Memory Data" +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "File:",IDC_STATIC,7,10,14,8 + EDITTEXT IDC_DEBUG_DATA_FILE,25,7,181,14,ES_AUTOHSCROLL + PUSHBUTTON "Browse",IDC_DEBUG_DATA_BUT,207,7,50,14 + LTEXT "Start Address (hexadecimal):",IDC_STATIC,7,30,90,8 + EDITTEXT IDC_DEBUG_DATA_STARTADDR,101,27,37,14 + PUSHBUTTON "OK",IDOK,207,27,50,14 + PUSHBUTTON "Cancel",IDCANCEL,207,44,50,14 +END + IDD_DEBUG_SETTINGS DIALOG DISCARDABLE 0, 0, 184, 116 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Debugger Settings" @@ -583,8 +628,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,4,8,0 - PRODUCTVERSION 1,4,8,0 + FILEVERSION 1,5,3,0 + PRODUCTVERSION 1,5,3,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -601,12 +646,12 @@ BEGIN BEGIN VALUE "CompanyName", "Christoph Gießelink & Sebastien Carlier\0" VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0" - VALUE "FileVersion", "1, 4, 8, 0\0" + VALUE "FileVersion", "1, 5, 3, 0\0" VALUE "InternalName", "Emu48\0" - VALUE "LegalCopyright", "Copyright © 2010\0" + VALUE "LegalCopyright", "Copyright © 2012\0" VALUE "OriginalFilename", "Emu48.exe\0" VALUE "ProductName", "Emu48\0" - VALUE "ProductVersion", "1, 4, 8, 0\0" + VALUE "ProductVersion", "1, 5, 3, 0\0" END END BLOCK "VarFileInfo" @@ -771,6 +816,9 @@ BEGIN MENUITEM "NCE&3", ID_DEBUG_MEM_NCE3 , GRAYED END + MENUITEM SEPARATOR + MENUITEM "&Load Memory Data...", ID_DEBUG_MEM_LOAD + MENUITEM "S&ave Memory Data...", ID_DEBUG_MEM_SAVE END END diff --git a/source/EMU48.XML b/source/source/EMU48.XML similarity index 100% rename from source/EMU48.XML rename to source/source/EMU48.XML diff --git a/source/source/EMU48.sln b/source/source/EMU48.sln new file mode 100644 index 0000000..9da1601 --- /dev/null +++ b/source/source/EMU48.sln @@ -0,0 +1,46 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EMU48DLL", "EMU48DLL.vcxproj", "{D698708A-34DA-4FDC-80BC-D3AB2EBC5CA9}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Emu48", "Emu48.vcxproj", "{D2111396-0ACD-41C3-B286-3E6599A9720A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug Unicode|Win32 = Debug Unicode|Win32 + Debug|Win32 = Debug|Win32 + DebugRegDebug4x|Win32 = DebugRegDebug4x|Win32 + Release Unicode|Win32 = Release Unicode|Win32 + Release|Win32 = Release|Win32 + ReleaseRegDebug4x|Win32 = ReleaseRegDebug4x|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D698708A-34DA-4FDC-80BC-D3AB2EBC5CA9}.Debug Unicode|Win32.ActiveCfg = Debug|Win32 + {D698708A-34DA-4FDC-80BC-D3AB2EBC5CA9}.Debug Unicode|Win32.Build.0 = Debug|Win32 + {D698708A-34DA-4FDC-80BC-D3AB2EBC5CA9}.Debug|Win32.ActiveCfg = Debug|Win32 + {D698708A-34DA-4FDC-80BC-D3AB2EBC5CA9}.Debug|Win32.Build.0 = Debug|Win32 + {D698708A-34DA-4FDC-80BC-D3AB2EBC5CA9}.DebugRegDebug4x|Win32.ActiveCfg = Debug|Win32 + {D698708A-34DA-4FDC-80BC-D3AB2EBC5CA9}.DebugRegDebug4x|Win32.Build.0 = Debug|Win32 + {D698708A-34DA-4FDC-80BC-D3AB2EBC5CA9}.Release Unicode|Win32.ActiveCfg = Release|Win32 + {D698708A-34DA-4FDC-80BC-D3AB2EBC5CA9}.Release Unicode|Win32.Build.0 = Release|Win32 + {D698708A-34DA-4FDC-80BC-D3AB2EBC5CA9}.Release|Win32.ActiveCfg = Release|Win32 + {D698708A-34DA-4FDC-80BC-D3AB2EBC5CA9}.Release|Win32.Build.0 = Release|Win32 + {D698708A-34DA-4FDC-80BC-D3AB2EBC5CA9}.ReleaseRegDebug4x|Win32.ActiveCfg = Release|Win32 + {D698708A-34DA-4FDC-80BC-D3AB2EBC5CA9}.ReleaseRegDebug4x|Win32.Build.0 = Release|Win32 + {D2111396-0ACD-41C3-B286-3E6599A9720A}.Debug Unicode|Win32.ActiveCfg = Debug Unicode|Win32 + {D2111396-0ACD-41C3-B286-3E6599A9720A}.Debug Unicode|Win32.Build.0 = Debug Unicode|Win32 + {D2111396-0ACD-41C3-B286-3E6599A9720A}.Debug|Win32.ActiveCfg = Debug|Win32 + {D2111396-0ACD-41C3-B286-3E6599A9720A}.Debug|Win32.Build.0 = Debug|Win32 + {D2111396-0ACD-41C3-B286-3E6599A9720A}.DebugRegDebug4x|Win32.ActiveCfg = DebugRegDebug4x|Win32 + {D2111396-0ACD-41C3-B286-3E6599A9720A}.DebugRegDebug4x|Win32.Build.0 = DebugRegDebug4x|Win32 + {D2111396-0ACD-41C3-B286-3E6599A9720A}.Release Unicode|Win32.ActiveCfg = Release Unicode|Win32 + {D2111396-0ACD-41C3-B286-3E6599A9720A}.Release Unicode|Win32.Build.0 = Release Unicode|Win32 + {D2111396-0ACD-41C3-B286-3E6599A9720A}.Release|Win32.ActiveCfg = Release|Win32 + {D2111396-0ACD-41C3-B286-3E6599A9720A}.Release|Win32.Build.0 = Release|Win32 + {D2111396-0ACD-41C3-B286-3E6599A9720A}.ReleaseRegDebug4x|Win32.ActiveCfg = ReleaseRegDebug4x|Win32 + {D2111396-0ACD-41C3-B286-3E6599A9720A}.ReleaseRegDebug4x|Win32.Build.0 = ReleaseRegDebug4x|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/source/EMU48DLL.C b/source/source/EMU48DLL.C similarity index 90% rename from source/EMU48DLL.C rename to source/source/EMU48DLL.C index e971ef1..b648362 100644 --- a/source/EMU48DLL.C +++ b/source/source/EMU48DLL.C @@ -17,6 +17,7 @@ #include "Emu48Dll.h" static LPCTSTR pArgv[3]; // command line memory +static ATOM classAtom = INVALID_ATOM; // window class atom static HACCEL hAccel; // accelerator table static HSZ hszService, hszTopic; // variables for DDE server @@ -35,12 +36,48 @@ static VOID (CALLBACK *pEmuClose)(VOID) = NULL; //# //################ +// +// DllMain +// +BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ + BOOL bSucc = TRUE; + + if (fdwReason == DLL_PROCESS_ATTACH) + { + WNDCLASS wc; + + wc.style = CS_BYTEALIGNCLIENT; + wc.lpfnWndProc = (WNDPROC)MainWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hinstDLL; + wc.hIcon = LoadIcon(hApp, MAKEINTRESOURCE(IDI_EMU48)); + wc.hCursor = NULL; + wc.hbrBackground = NULL; + wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU); + wc.lpszClassName = _T("CEmu48"); + VERIFY(bSucc = ((classAtom = RegisterClass(&wc)) != INVALID_ATOM)); + } + + if (fdwReason == DLL_PROCESS_DETACH) + { + if (INVALID_ATOM != classAtom) + { + VERIFY(UnregisterClass(MAKEINTATOM(classAtom),hinstDLL)); + classAtom = INVALID_ATOM; + } + } + + return bSucc; + UNREFERENCED_PARAMETER(lpvReserved); +} + // // DLLCreateWnd // BOOL DLLCreateWnd(LPCTSTR lpszFilename, LPCTSTR lpszPort2Name) { - WNDCLASS wc; RECT rectWindow; BOOL bFileExist = FALSE; // state file don't exist @@ -48,9 +85,6 @@ BOOL DLLCreateWnd(LPCTSTR lpszFilename, LPCTSTR lpszPort2Name) hApp = GetModuleHandle(_T("EMU48.DLL")); if (hApp == NULL) return TRUE; - hHeap = GetProcessHeap(); // get process heap - if (hHeap == NULL) return TRUE; - nArgc = 1; // no argument if (lpszFilename[0]) { @@ -70,17 +104,9 @@ BOOL DLLCreateWnd(LPCTSTR lpszFilename, LPCTSTR lpszPort2Name) } } - wc.style = CS_BYTEALIGNCLIENT; - wc.lpfnWndProc = (WNDPROC)MainWndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hApp; - wc.hIcon = LoadIcon(hApp, MAKEINTRESOURCE(IDI_EMU48)); - wc.hCursor = NULL; - wc.hbrBackground = NULL; - wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU); - wc.lpszClassName = _T("CEmu48"); - RegisterClass(&wc); + // read emulator settings + GetCurrentDirectory(ARRAYSIZEOF(szCurrentDirectory),szCurrentDirectory); + ReadSettings(); // Create window rectWindow.left = 0; @@ -89,7 +115,7 @@ BOOL DLLCreateWnd(LPCTSTR lpszFilename, LPCTSTR lpszPort2Name) rectWindow.bottom = 0; AdjustWindowRect(&rectWindow, WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_OVERLAPPED, TRUE); - hWnd = CreateWindow(_T("CEmu48"), _T("Emu48"), + hWnd = CreateWindow(MAKEINTATOM(classAtom),_T("Emu48"), WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_OVERLAPPED, CW_USEDEFAULT, CW_USEDEFAULT, rectWindow.right - rectWindow.left, @@ -99,7 +125,6 @@ BOOL DLLCreateWnd(LPCTSTR lpszFilename, LPCTSTR lpszPort2Name) if (hWnd == NULL) { - UnregisterClass(_T("CEmu48"),hApp); return TRUE; } @@ -112,14 +137,10 @@ BOOL DLLCreateWnd(LPCTSTR lpszFilename, LPCTSTR lpszPort2Name) EmuClearAllBreakpoints(); QueryPerformanceFrequency(&lFreq); // init high resolution counter - GetCurrentDirectory(sizeof(szCurrentDirectory), szCurrentDirectory); szCurrentKml[0] = 0; // no KML file selected - - ReadSettings(); + SetSpeed(bRealSpeed); // set speed MruInit(0); // init MRU entries - UpdateWindowStatus(); - // create shutdown auto event handle hEventShutdn = CreateEvent(NULL,FALSE,FALSE,NULL); if (hEventShutdn == NULL) @@ -481,7 +502,7 @@ DECLSPEC BOOL CALLBACK EmuLoadObject( CloseHandle(hFile); goto cancel; } - lpBuf = HeapAlloc(hHeap,0,dwFileSizeLow*2); + lpBuf = malloc(dwFileSizeLow*2); if (lpBuf == NULL) { SwitchToState(SM_RUN); // run state @@ -493,7 +514,7 @@ DECLSPEC BOOL CALLBACK EmuLoadObject( wError = WriteStack(1,lpBuf,dwFileSizeLow); - HeapFree(hHeap,0,lpBuf); + free(lpBuf); SwitchToState(SM_RUN); // run state while (nState!=nNextState) Sleep(0); diff --git a/source/EMU48DLL.DSP b/source/source/EMU48DLL.DSP similarity index 90% rename from source/EMU48DLL.DSP rename to source/source/EMU48DLL.DSP index 9596bd0..954ab40 100644 --- a/source/EMU48DLL.DSP +++ b/source/source/EMU48DLL.DSP @@ -53,7 +53,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib advapi32.lib /nologo /dll /machine:I386 /out:".\Release/Emu48.dll" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib advapi32.lib ws2_32.lib /nologo /dll /machine:I386 /out:".\Release/Emu48.dll" !ELSEIF "$(CFG)" == "Emu48 - Win32 Debug" @@ -79,7 +79,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib advapi32.lib /nologo /dll /debug /machine:I386 /out:".\Debug/Emu48.dll" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib advapi32.lib ws2_32.lib /nologo /dll /debug /machine:I386 /out:".\Debug/Emu48.dll" !ENDIF @@ -112,6 +112,10 @@ SOURCE=.\disasm.c # End Source File # Begin Source File +SOURCE=.\dismem.c +# End Source File +# Begin Source File + SOURCE=.\display.c # End Source File # Begin Source File @@ -177,6 +181,10 @@ SOURCE=.\pch.c # End Source File # Begin Source File +SOURCE=.\redeye.c +# End Source File +# Begin Source File + SOURCE=.\rpl.c # End Source File # Begin Source File @@ -195,6 +203,10 @@ SOURCE=.\stack.c SOURCE=.\timer.c # End Source File +# Begin Source File + +SOURCE=.\udp.c +# End Source File # End Group # Begin Group "Header Files" diff --git a/source/EMU48DLL.DSW b/source/source/EMU48DLL.DSW similarity index 100% rename from source/EMU48DLL.DSW rename to source/source/EMU48DLL.DSW diff --git a/source/EMU48DLL.H b/source/source/EMU48DLL.H similarity index 100% rename from source/EMU48DLL.H rename to source/source/EMU48DLL.H diff --git a/source/source/EMU48DLL.vcproj b/source/source/EMU48DLL.vcproj new file mode 100644 index 0000000..123ca1f --- /dev/null +++ b/source/source/EMU48DLL.vcproj @@ -0,0 +1,808 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/source/EMU48DLL.vcxproj b/source/source/EMU48DLL.vcxproj new file mode 100644 index 0000000..ce536aa --- /dev/null +++ b/source/source/EMU48DLL.vcxproj @@ -0,0 +1,279 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {D698708A-34DA-4FDC-80BC-D3AB2EBC5CA9} + Emu48 + + + + DynamicLibrary + false + MultiByte + + + DynamicLibrary + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\Debug\ + .\Debug\ + true + .\Release\ + .\Release\ + false + EMU48 + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/EMU48DLL.tlb + + + + + /D REGISTRYKEY=\"Software\\Hewlett-Packard\\Debug4x\\Emu48\" %(AdditionalOptions) + Disabled + _DEBUG;WIN32;_WINDOWS;STRICT;_USRDLL;REGISTRY;%(PreprocessorDefinitions) + true + MultiThreadedDebug + Use + pch.h + .\Debug/EMU48DLL.pch + .\Debug/ + .\Debug/ + .\Debug/ + true + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + winmm.lib;%(AdditionalDependencies) + .\Debug/Emu48.dll + true + true + .\Debug/Emu48.pdb + false + + + .\Debug/Emu48.lib + MachineX86 + + + true + .\Debug/EMU48DLL.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/EMU48DLL.tlb + + + + + /D REGISTRYKEY=\"Software\\Hewlett-Packard\\Debug4x\\Emu48\" %(AdditionalOptions) + MaxSpeed + AnySuitable + NDEBUG;WIN32;_WINDOWS;STRICT;_USRDLL;REGISTRY;%(PreprocessorDefinitions) + true + MultiThreaded + true + Use + pch.h + .\Release/EMU48DLL.pch + .\Release/ + .\Release/ + .\Release/ + Level3 + true + FastCall + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + winmm.lib;Ws2_32.lib;%(AdditionalDependencies) + .\Release/Emu48.dll + true + .\Release/Emu48.pdb + false + + + .\Release/Emu48.lib + MachineX86 + + + true + .\Release/EMU48DLL.bsc + + + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + Create + %(PreprocessorDefinitions) + Create + + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/source/EMU48DLL.vcxproj.filters b/source/source/EMU48DLL.vcxproj.filters new file mode 100644 index 0000000..cfa8063 --- /dev/null +++ b/source/source/EMU48DLL.vcxproj.filters @@ -0,0 +1,151 @@ + + + + + {036803d0-e5da-4f5d-adf3-bd23b9dd095f} + cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90 + + + {5602a8c2-47f0-4367-bec1-73dd7c524ed4} + h;hpp;hxx;hm;inl;fi;fd + + + {4fd418f4-ad27-4307-92fe-9cecea80086d} + ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/source/ENGINE.C b/source/source/ENGINE.C similarity index 91% rename from source/ENGINE.C rename to source/source/ENGINE.C index 7d7f5c6..8f76755 100644 --- a/source/ENGINE.C +++ b/source/source/ENGINE.C @@ -19,6 +19,7 @@ UINT nState = SM_INVALID; UINT nNextState = SM_RUN; BOOL bRealSpeed = FALSE; BOOL bKeySlow = FALSE; // slow down for key emulation +UINT nOpcSlow = 0; // no. of opcodes to slow down BOOL bCommInit = FALSE; // COM port not open CHIPSET Chipset; @@ -88,6 +89,7 @@ static __inline VOID Debugger(VOID) // debugger part LPBYTE I = FASTPTR(Chipset.pc); // get opcode stream UpdateDbgCycleCounter(); // update 64 bit cpu cycle counter + SaveInstrAddr(Chipset.pc); // save pc in last instruction buffer nDbgRplBreak = BN_ASM; // notify ASM breakpoint @@ -276,7 +278,7 @@ static __inline VOID CheckDisp(BOOL bSync) static __inline VOID AdjustSpeed(VOID) // adjust emulation speed { - if (bCpuSlow || bKeySlow) // emulation slow down + if (bCpuSlow || bKeySlow || nOpcSlow > 0) // emulation slow down { DWORD dwCycles,dwTicks; @@ -294,11 +296,13 @@ static __inline VOID AdjustSpeed(VOID) // adjust emulation speed dwTicks = lAct.LowPart - dwSpeedRef; } // ticks elapsed or negative number (workaround for QueryPerformanceCounter() in Win2k) - while(dwTicks <= dwTickRef || (dwTicks & 0x80000000) != 0); + while (dwTicks <= dwTickRef || (dwTicks & 0x80000000) != 0); dwOldCyc += T2CYCLES; // adjust cycles reference dwSpeedRef += dwTickRef; // adjust reference time } + + if (nOpcSlow > 0) --nOpcSlow; // decr. slow down opcode counter } LeaveCriticalSection(&csSlowLock); } @@ -322,26 +326,34 @@ VOID CheckSerial(VOID) return; } +VOID InitAdjustSpeed(VOID) +{ + // slow down function not initalized + if (!bCpuSlow && !bKeySlow && nOpcSlow == 0) + { + LARGE_INTEGER lTime; // sample timer ticks + // save reference cycles + dwOldCyc = (DWORD) (Chipset.cycles & 0xFFFFFFFF); + QueryPerformanceCounter(&lTime); // get timer ticks + dwSpeedRef = lTime.LowPart; // save reference time + } + return; +} + VOID AdjKeySpeed(VOID) // slow down key repeat { WORD i; BOOL bKey; - if (bCpuSlow) return; // no need to slow down - bKey = FALSE; // search for a pressed key for (i = 0;i < ARRAYSIZEOF(Chipset.Keyboard_Row) && !bKey;++i) bKey = (Chipset.Keyboard_Row[i] != 0); EnterCriticalSection(&csSlowLock); { - if (!bKeySlow && bKey) // key pressed, init variables + if (bKey) // key pressed { - LARGE_INTEGER lTime; // sample timer ticks - // save reference cycles - dwOldCyc = (DWORD) (Chipset.cycles & 0xFFFFFFFF); - QueryPerformanceCounter(&lTime); // get timer ticks - dwSpeedRef = lTime.LowPart; // save reference time + InitAdjustSpeed(); // init variables if necessary } bKeySlow = bKey; // save new state } @@ -355,11 +367,7 @@ VOID SetSpeed(BOOL bAdjust) // set emulation speed { if (bAdjust) // switch to real speed { - LARGE_INTEGER lTime; // sample timer ticks - // save reference cycles - dwOldCyc = (DWORD) (Chipset.cycles & 0xFFFFFFFF); - QueryPerformanceCounter(&lTime); // get timer ticks - dwSpeedRef = lTime.LowPart; // save reference time + InitAdjustSpeed(); // init variables if necessary } bCpuSlow = bAdjust; // save emulation speed } @@ -413,7 +421,6 @@ UINT SwitchToState(UINT nNewState) bInterrupt = TRUE; SuspendDebugger(); // suspend debugger while (nState!=nNextState) Sleep(0); - UpdateWindowStatus(); break; case SM_RETURN: // -> Return DisableDebugger(); // disable debugger @@ -426,7 +433,6 @@ UINT SwitchToState(UINT nNewState) nNextState = SM_RETURN; SetEvent(hEventShutdn); WaitForSingleObject(hThread,INFINITE); - UpdateWindowStatus(); break; case SM_SLEEP: // -> Sleep nNextState = SM_SLEEP; @@ -450,7 +456,6 @@ UINT SwitchToState(UINT nNewState) ResumeDebugger(); SetEvent(hEventShutdn); while (nState!=nNextState) Sleep(0); - UpdateWindowStatus(); break; case SM_RETURN: // -> Return DisableDebugger(); // disable debugger @@ -462,7 +467,6 @@ UINT SwitchToState(UINT nNewState) nNextState = SM_SLEEP; SetEvent(hEventShutdn); while (nState!=nNextState) Sleep(0); - UpdateWindowStatus(); break; } break; @@ -480,7 +484,6 @@ UINT SwitchToState(UINT nNewState) nNextState = SM_INVALID; SetEvent(hEventShutdn); while (nState!=nNextState) Sleep(0); - UpdateWindowStatus(); break; case SM_RETURN: // -> Return DisableDebugger(); // disable debugger @@ -490,7 +493,6 @@ UINT SwitchToState(UINT nNewState) nNextState = SM_RETURN; SetEvent(hEventShutdn); WaitForSingleObject(hThread,INFINITE); - UpdateWindowStatus(); break; } break; @@ -582,8 +584,8 @@ loop: EvalOpcode(FASTPTR(Chipset.pc)); // execute opcode - if (!bGrayscale) - CheckDisp(!Chipset.Shutdn); // check for display update + // check for display update in BW mode + if (!bGrayscale) CheckDisp(!Chipset.Shutdn); AdjustSpeed(); // adjust emulation speed } bInterrupt = FALSE; // be sure to reenter opcode loop @@ -604,6 +606,7 @@ loop: dwOldCyc = (DWORD) (Chipset.cycles & 0xFFFFFFFF); QueryPerformanceCounter(&lDummyInt); dwSpeedRef = lDummyInt.LowPart; + nOpcSlow = 0; // no opcodes to slow down } } if (Chipset.SoftInt) diff --git a/source/EXTERNAL.C b/source/source/EXTERNAL.C similarity index 94% rename from source/EXTERNAL.C rename to source/source/EXTERNAL.C index c1f9091..44e354b 100644 --- a/source/EXTERNAL.C +++ b/source/source/EXTERNAL.C @@ -66,7 +66,7 @@ static __inline VOID BeepWave(DWORD dwFrequency,DWORD dwDuration) // (samp/sec) * msecs * (secs/msec) = samps wh.dwBufferLength = (DWORD) ((QWORD) MUSIC_FREQ * dwDuration / 1000); - VERIFY(wh.lpData = HeapAlloc(hHeap,0,wh.dwBufferLength)); + VERIFY(wh.lpData = malloc(wh.dwBufferLength)); wh.dwBytesRecorded = 0; wh.dwUser = 0; wh.dwFlags = 0; @@ -86,7 +86,7 @@ static __inline VOID BeepWave(DWORD dwFrequency,DWORD dwDuration) VERIFY(waveOutUnprepareHeader(hSoundDevice,&wh,sizeof(wh)) == MMSYSERR_NOERROR); VERIFY(waveOutClose(hSoundDevice) == MMSYSERR_NOERROR); - HeapFree(hHeap,0,wh.lpData); + free(wh.lpData); CloseHandle(hEventSound); return; } diff --git a/source/Emu48.dsp b/source/source/Emu48.dsp similarity index 90% rename from source/Emu48.dsp rename to source/source/Emu48.dsp index 60b085f..343e65e 100644 --- a/source/Emu48.dsp +++ b/source/source/Emu48.dsp @@ -57,7 +57,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib ws2_32.lib /nologo /subsystem:windows /machine:I386 !ELSEIF "$(CFG)" == "Emu48 - Win32 Debug" @@ -83,7 +83,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib /nologo /subsystem:windows /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib ws2_32.lib /nologo /subsystem:windows /debug /machine:I386 !ELSEIF "$(CFG)" == "Emu48 - Win32 Release Unicode" @@ -110,7 +110,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib ws2_32.lib /nologo /subsystem:windows /machine:I386 !ELSEIF "$(CFG)" == "Emu48 - Win32 Debug Unicode" @@ -137,7 +137,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib /nologo /subsystem:windows /debug /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib /nologo /subsystem:windows /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib ws2_32.lib /nologo /subsystem:windows /debug /machine:I386 !ELSEIF "$(CFG)" == "Emu48 - Win32 DebugRegDebug4x" @@ -164,7 +164,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib /nologo /subsystem:windows /debug /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib /nologo /subsystem:windows /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib ws2_32.lib /nologo /subsystem:windows /debug /machine:I386 !ELSEIF "$(CFG)" == "Emu48 - Win32 ReleaseRegDebug4x" @@ -191,7 +191,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib ws2_32.lib /nologo /subsystem:windows /machine:I386 !ENDIF @@ -228,6 +228,10 @@ SOURCE=.\disasm.c # End Source File # Begin Source File +SOURCE=.\dismem.c +# End Source File +# Begin Source File + SOURCE=.\display.c # End Source File # Begin Source File @@ -289,6 +293,10 @@ SOURCE=.\pch.c # End Source File # Begin Source File +SOURCE=.\redeye.c +# End Source File +# Begin Source File + SOURCE=.\rpl.c # End Source File # Begin Source File @@ -311,6 +319,10 @@ SOURCE=.\symbfile.c SOURCE=.\timer.c # End Source File +# Begin Source File + +SOURCE=.\udp.c +# End Source File # End Group # Begin Group "Header Files" diff --git a/source/Emu48.dsw b/source/source/Emu48.dsw similarity index 100% rename from source/Emu48.dsw rename to source/source/Emu48.dsw diff --git a/source/source/Emu48.vcproj b/source/source/Emu48.vcproj new file mode 100644 index 0000000..a6e133e --- /dev/null +++ b/source/source/Emu48.vcproj @@ -0,0 +1,1980 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/source/Emu48.vcxproj b/source/source/Emu48.vcxproj new file mode 100644 index 0000000..0c521ff --- /dev/null +++ b/source/source/Emu48.vcxproj @@ -0,0 +1,631 @@ + + + + + Debug Unicode + Win32 + + + DebugRegDebug4x + Win32 + + + Debug + Win32 + + + Release Unicode + Win32 + + + ReleaseRegDebug4x + Win32 + + + Release + Win32 + + + + {D2111396-0ACD-41C3-B286-3E6599A9720A} + Emu48 + + + + Application + false + + + Application + false + + + Application + false + + + Application + false + Unicode + + + Application + false + + + Application + false + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\DebugUnicode\ + .\DebugUnicode\ + true + .\Debug\ + .\Debug\ + true + .\ReleaseUnicode\ + .\ReleaseUnicode\ + false + .\Release\ + .\Release\ + false + .\DebugRegDebug4x\ + .\DebugRegDebug4x\ + true + .\ReleaseRegDebug4x\ + .\ReleaseRegDebug4x\ + false + EMU48 + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\DebugUnicode/Emu48.tlb + + + + + Disabled + _DEBUG;WIN32;_WINDOWS;STRICT;UNICODE;%(PreprocessorDefinitions) + true + MultiThreadedDebug + Use + pch.h + .\DebugUnicode/Emu48.pch + .\DebugUnicode/ + .\DebugUnicode/ + .\DebugUnicode/ + true + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + winmm.lib;comctl32.lib;%(AdditionalDependencies) + .\DebugUnicode/Emu48.exe + true + true + .\DebugUnicode/Emu48.pdb + Windows + false + + + MachineX86 + + + true + .\DebugUnicode/Emu48.bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/Emu48.tlb + + + + + Disabled + _DEBUG;WIN32;_WINDOWS;STRICT;%(PreprocessorDefinitions) + true + MultiThreadedDebug + Use + pch.h + .\Debug/Emu48.pch + .\Debug/ + .\Debug/ + .\Debug/ + true + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + winmm.lib;comctl32.lib;%(AdditionalDependencies) + .\Debug/Emu48.exe + true + true + .\Debug/Emu48.pdb + Windows + false + + + MachineX86 + + + true + .\Debug/Emu48.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\ReleaseUnicode/Emu48.tlb + + + + + MaxSpeed + AnySuitable + NDEBUG;WIN32;_WINDOWS;STRICT;UNICODE;%(PreprocessorDefinitions) + true + MultiThreaded + true + Use + pch.h + .\ReleaseUnicode/Emu48.pch + .\ReleaseUnicode/ + .\ReleaseUnicode/ + .\ReleaseUnicode/ + Level3 + true + FastCall + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + winmm.lib;comctl32.lib;%(AdditionalDependencies) + .\ReleaseUnicode/Emu48.exe + true + .\ReleaseUnicode/Emu48.pdb + Windows + false + + + MachineX86 + + + true + .\ReleaseUnicode/Emu48.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/Emu48.tlb + + + + + MaxSpeed + AnySuitable + NDEBUG;WIN32;_WINDOWS;STRICT;%(PreprocessorDefinitions) + true + MultiThreaded + true + Use + pch.h + .\Release/Emu48.pch + .\Release/ + .\Release/ + .\Release/ + Level3 + true + FastCall + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + winmm.lib;comctl32.lib;Ws2_32.lib;%(AdditionalDependencies) + .\Release/Emu48.exe + true + .\Release/Emu48.pdb + Windows + false + + + MachineX86 + + + + + true + .\Release/Emu48.bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\DebugRegDebug4x/Emu48.tlb + + + + + /D REGISTRYKEY=\"Software\\Hewlett-Packard\\Debug4x\\Emu48\" %(AdditionalOptions) + Disabled + _DEBUG;WIN32;_WINDOWS;STRICT;REGISTRY;%(PreprocessorDefinitions) + true + MultiThreadedDebug + Use + pch.h + .\DebugRegDebug4x/Emu48.pch + .\DebugRegDebug4x/ + .\DebugRegDebug4x/ + .\DebugRegDebug4x/ + true + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + winmm.lib;comctl32.lib;%(AdditionalDependencies) + .\DebugRegDebug4x/Emu48.exe + true + true + .\DebugRegDebug4x/Emu48.pdb + Windows + false + + + MachineX86 + + + true + .\DebugRegDebug4x/Emu48.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\ReleaseRegDebug4x/Emu48.tlb + + + + + /D REGISTRYKEY=\"Software\\Hewlett-Packard\\Debug4x\\Emu48\" %(AdditionalOptions) + MaxSpeed + AnySuitable + NDEBUG;WIN32;_WINDOWS;STRICT;REGISTRY;%(PreprocessorDefinitions) + true + MultiThreaded + true + Use + pch.h + .\ReleaseRegDebug4x/Emu48.pch + .\ReleaseRegDebug4x/ + .\ReleaseRegDebug4x/ + .\ReleaseRegDebug4x/ + Level3 + true + FastCall + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + winmm.lib;comctl32.lib;Ws2_32.lib;%(AdditionalDependencies) + .\ReleaseRegDebug4x/Emu48.exe + true + .\ReleaseRegDebug4x/Emu48.pdb + Windows + false + + + MachineX86 + + + true + .\ReleaseRegDebug4x/Emu48.bsc + + + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + Create + %(PreprocessorDefinitions) + Create + %(PreprocessorDefinitions) + Create + %(PreprocessorDefinitions) + Create + %(PreprocessorDefinitions) + Create + %(PreprocessorDefinitions) + Create + + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/source/Emu48.vcxproj.filters b/source/source/Emu48.vcxproj.filters new file mode 100644 index 0000000..3e2ede3 --- /dev/null +++ b/source/source/Emu48.vcxproj.filters @@ -0,0 +1,154 @@ + + + + + {42670a15-cd4b-4b80-bd83-7a6798392302} + cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90 + + + {e57a9ce5-70b4-4e91-9635-7e3594bd1342} + h;hpp;hxx;hm;inl;fi;fd + + + {b18143c3-212e-46b8-a5b1-fd6edcf1377d} + ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + Resource Files + + + Resource Files + + + \ No newline at end of file diff --git a/source/source/Emu48Ini.txt b/source/source/Emu48Ini.txt new file mode 100644 index 0000000..77b154e --- /dev/null +++ b/source/source/Emu48Ini.txt @@ -0,0 +1,348 @@ +Emu48 Settings Description +-------------------------- + +This is a detailed description of the Emu48 program settings. Some of them can +be controlled over a settings dialog, some of them only manually. The Emu48 +versions use different saving locations. Some of them save there data in a INI +file, some of them in the registry. There are some items which aren't supported +in all versions. + +- Emu48 for IA32 +%WINDIR%\Emu48.ini + +- Emu48+ (from the Debug4x package) +HKCU\Software\Hewlett-Packard\Debug4x\Emu48\ + +- Emu48 for Pocket PC +HKCU\Software\Emu48\ + + +The configuration data is divided into sections. Each section may contain one or +more items. Each item has an argument. The argument is one of following three +types: + +[string] : text string in "" +[integer] : signed integer value +[bool] : special integer type with 0 for FALSE and 1 for TRUE + +Before changing the settings content manually, close all Emu48 instances before! + + +1.) Section [Files] + +- Emu48Directory=[string] + +This item contain the default path for the KML-files and other emulator specific +files which are used without a full path name. + +Default: actual path of Emu48.exe at first start + +- LastDocument=[string] + +This item contain the full path name to the last used state file. + +Default: -empty- + +- AutoSave=[bool] + +This item controls the "Automatically Save Files" state file save. This setting +is used when you change the state file during a session. + +0 = Ask if state file should be saved +1 = Save state file automatically + +Default: 0 + +- AutoSaveOnExit=[bool] + +This item controls the "Automatically Save Files On Exit" state file save at +program exit. + +0 = Ask if state file should be saved +1 = Save state file automatically + +Default: 0 + +- SaveDefaultConfirm=[bool] + +This item controls the default button in the "Do you want to save changes ?" +message box. + +0 = No - Button +1 = Yes - Button + +Default: 1 + +- LoadObjectWarning=[bool] + +This item controls the "Show Load Object Warning" warning. + +0 = no warning +1 = warning + +Default: 1 + +- StartupBackup=[bool] + +This item controls if a state file memory backup (Menu Edit/Backup) should be +made at program start. + +0 = no backup +1 = create backup + +Default: 0 + + +2.) Section [KML] + +- AlwaysDisplayLog=[bool] + +This item controls "Always Show KML Compilation Result" view. + +0 = don't show KML compilation result +1 = show KML compilation result after reading the KML file + +Default: 1 + +- ClassicCursor=[bool] + +Obsolete, can be purged. + + +3.) Section [Emulator] + +- RealSpeed=[bool] + +This item controls "Authentic Calculator Speed" setting. + +0 = disabled +1 = enabled + +Default: 0 + +- SXCycles=[integer] + +This item controls the speed in "Authentic Calculator Speed" mode for +calculators base on the "Clarke" chip. The number are the allowed CPU-cycles in +a 16384Hz time frame. + +Default: 82 + +- GXCycles=[integer] + +This item controls the speed in "Authentic Calculator Speed" mode for +calculators base on the "Yorke" chip. The number are the allowed CPU-cycles in a +16384Hz time frame. + +Default: 123 + +- Grayscale=[bool] + +This item controls "Enable Virtual LCD Delay" setting. + +0 = disabled +1 = enable virtual LCD delay for grayscale simulation + +Default: 0 + +- AlwaysOnTop=[bool] + +This item controls "Always On Top" setting. + +0 = disabled +1 = application windows are always on top + +Default: 0 + +- ActivationFollowsMouse=[bool] + +This item controls "Activation Follows Mouse" setting. + +0 = disabled +1 = if mouse is moved over a Emu48 window, application pops up into foreground + +Default: 0 + +- WaveBeep=[bool] + +This item sets the beeper output device. + +0 = PC Speaker +1 = Wave Output over sound card + +Default: 0 + +- WaveVolume=[integer] + +This item sets the volume for the wave output. The valid value range is 0 - 255. + +0 = quietest +255 = loudest + +Default: 64 + + +4.) Section [Port2] + +This section is only interested for the HP48 emulation. Other calculator +emulations aren't affected by this section. + +- IsShared=[bool] + +This item controls the "Port 2 is Shared" setting. + +0 = file not shared +1 = file shared + +Default: 0 + +- Filename=[string] + +This item contain the "Port 2 File" name. + +Default: SHARED.BIN + + +5.) Section [ROM] + +This section is only interested for the HP49G emulation. + +- Writeable=[bool] + +This item controls if data could be saved in the HP49 ROM image file. In "Read +Only" mode all changes in the Flash memory are discarded at session end. + +0 = Discard changes at session exit +1 = Writeable + +Default: 1 + +- WP#=[bool] + +This item don't exist at must be created manually. It controls the WP# pin state +of 28F160 flash chip. On the original HP49G calculator the pin is controlled by +a solder bridge. + +0 = WP# = low, locked blocks cannot be erased +1 = WP# = high, locked blocks can be erased + +Default: 0 + + +6.) Section [LowBat] + +- Disable=[bool] + +This item controls the low battery simulation. On AC powered devices the low +battery simulation is always disabled. On battery powered devices the simulation +is enabled. In some cases, especially when the battery is quite old, the +operating system may return a wrong battery charging level. This could make the +emulator unusable. + +0 = low battery simulation in auto mode +1 = low battery simulation disabled + +Default: 0 + + +7.) Section [Timers] + +Obsolete, can be purged. + +- AccurateTimer=[bool] + +Obsolete, can be purged. + +- T1Period=[integer] + +Obsolete, can be purged. + + +8.) Section [Serial] + +-Wire=[string] + +This item controls the serial port "Wire" setting. The string can contain +"disabled" or the device name of the serial device. + +Default: "disabled" + +-Ir=[string] + +This item controls the serial port "IR" setting. The string can contain +"disabled" or the device name of the serial device. + +Default: "disabled" + + +9.) Section [Macro] + +- RealSpeed=[bool] + +This item controls the macro replay speed setting. + +0 = replay with given given speed +1 = replay with recording speed + +Default: 1 + +- ReplayTimeout=[integer] + +This item controls the macro replay delay time in "replay with given given +speed" mode between two keyboard actions. The unit is ms. The range of the +slider control in the settings dialog is 0 - 500. The emulator itself accepts +larger values than 500. + +Default: 0 + + +10.) Section [MRU] + +- FileCount=[integer] + +This item controls the maximum number of items in the "Most Recently Used" file +list. + +0 = disabled +>0 = maximum number of entries + +Default: 4 + +- FileX=[string] (where X is the slot number >= 1) + +This item controls the file name of the slot number. File1 is the topmost slot +in the MRU list. When you reduce the FileCount setting manually you have to +purge the slot numbers above this value manually. + +Default: -empty- + + +11.) Section [Disassembler] + +- Mnemonics=[bool] + +This item sets the disassembly mode. + +0 = HP Mnemonics +1 = Class Mnemonics + +Default: 0 + +- Symbolic:[bool] + +This item enables the use of symbolic names in the debugger disassembly. + +0 = disabled +1 = enabled + +Default: 0 + +- SymbX=[string] (where X is the model character from the KML file) + +This item contain the full path to the symbol file reference for the +corresponding calculator model. + +Default: -not exist- + + +10/13/08 (c) by Christoph Gießelink diff --git a/source/FETCH.C b/source/source/FETCH.C similarity index 100% rename from source/FETCH.C rename to source/source/FETCH.C diff --git a/source/FILES.C b/source/source/FILES.C similarity index 88% rename from source/FILES.C rename to source/source/FILES.C index fec6518..c7cae49 100644 --- a/source/FILES.C +++ b/source/source/FILES.C @@ -24,6 +24,8 @@ TCHAR szBackupFilename[MAX_PATH]; TCHAR szBufferFilename[MAX_PATH]; TCHAR szPort2Filename[MAX_PATH]; +BOOL bDocumentAvail = FALSE; // document not available + BYTE cCurrentRomType = 0; // Model -> hardware UINT nCurrentClass = 0; // Class -> derivate @@ -210,6 +212,7 @@ typedef struct tnode DWORD dwAddress; // patch address BYTE byROM; // original ROM value BYTE byPatch; // patched ROM value + struct tnode *prev; // previous node struct tnode *next; // next node } TREENODE; @@ -220,14 +223,17 @@ static BOOL PatchNibble(DWORD dwAddress, BYTE byPatch) TREENODE *p; _ASSERT(pbyRom); // ROM defined - if((p = HeapAlloc(hHeap,0,sizeof(TREENODE))) == NULL) + if ((p = malloc(sizeof(TREENODE))) == NULL) return TRUE; p->bPatch = TRUE; // address patched p->dwAddress = dwAddress; // save current values p->byROM = pbyRom[dwAddress]; p->byPatch = byPatch; + p->prev = NULL; p->next = nodePatch; // save node + + if (nodePatch) nodePatch->prev = p; // add as previous element nodePatch = p; pbyRom[dwAddress] = byPatch; // patch ROM @@ -245,7 +251,7 @@ static VOID RestorePatches(VOID) pbyRom[nodePatch->dwAddress] = nodePatch->byROM; p = nodePatch->next; // save pointer to next node - HeapFree(hHeap,0,nodePatch); // free node + free(nodePatch); // free node nodePatch = p; // new node } return; @@ -256,32 +262,42 @@ VOID UpdatePatches(BOOL bPatch) TREENODE *p = nodePatch; _ASSERT(pbyRom); // ROM defined - while (p != NULL) + if (bPatch) // patch ROM { - if (bPatch) // patch ROM + if (p) // something in patch list { - if (!p->bPatch) // patch only if not patched - { - // use original data for patch restore - p->byROM = pbyRom[p->dwAddress]; + // goto last element in list + for (; p->next != NULL; p = p->next) {} - // restore patch data - pbyRom[p->dwAddress] = p->byPatch; - p->bPatch = TRUE; // address patched - } - else + do { - _ASSERT(FALSE); // call ROM patch on a patched ROM + if (!p->bPatch) // patch only if not patched + { + // use original data for patch restore + p->byROM = pbyRom[p->dwAddress]; + + // restore patch data + pbyRom[p->dwAddress] = p->byPatch; + p->bPatch = TRUE; // address patched + } + else + { + _ASSERT(FALSE); // call ROM patch on a patched ROM + } + + p = p->prev; } + while (p != NULL); } - else // restore ROM + } + else // restore ROM + { + for (; p != NULL; p = p->next) { // restore original data pbyRom[p->dwAddress] = p->byROM; p->bPatch = FALSE; // address not patched } - - p = p->next; // next node } return; } @@ -312,7 +328,7 @@ BOOL PatchRom(LPCTSTR szFilename) CloseHandle(hFile); return FALSE; } - lpBuf = HeapAlloc(hHeap,0,dwFileSizeLow+1); + lpBuf = malloc(dwFileSizeLow+1); if (lpBuf == NULL) { CloseHandle(hFile); @@ -361,7 +377,7 @@ BOOL PatchRom(LPCTSTR szFilename) ++nPos; } } - HeapFree(hHeap,0,lpBuf); + free(lpBuf); return TRUE; } @@ -378,6 +394,8 @@ BOOL CrcRom(WORD *pwChk) // calculate fingerprint of ROM DWORD *pdwData,dwSize; DWORD dwChk = 0; + if (pbyRom == NULL) return TRUE; // ROM CRC isn't available + _ASSERT(pbyRom); // view on ROM pdwData = (DWORD *) pbyRom; @@ -671,13 +689,13 @@ VOID ResetDocument(VOID) } szCurrentKml[0] = 0; szCurrentFilename[0]=0; - if (Port0) { HeapFree(hHeap,0,Port0); Port0 = NULL; } - if (Port1) { HeapFree(hHeap,0,Port1); Port1 = NULL; } - if (Port2) { HeapFree(hHeap,0,Port2); Port2 = NULL; } else UnmapPort2(); + if (Port0) { free(Port0); Port0 = NULL; } + if (Port1) { free(Port1); Port1 = NULL; } + if (Port2) { free(Port2); Port2 = NULL; } else UnmapPort2(); ZeroMemory(&Chipset,sizeof(Chipset)); ZeroMemory(&RMap,sizeof(RMap)); // delete MMU mappings ZeroMemory(&WMap,sizeof(WMap)); - UpdateWindowStatus(); + bDocumentAvail = FALSE; // document not available return; } @@ -751,21 +769,22 @@ BOOL NewDocument(VOID) // allocate port memory if (Chipset.Port0Size) { - Port0 = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,Chipset.Port0Size*2048); + Port0 = calloc(Chipset.Port0Size*2048,sizeof(*Port0)); _ASSERT(Port0 != NULL); } if (Chipset.Port1Size) { - Port1 = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,Chipset.Port1Size*2048); + Port1 = calloc(Chipset.Port1Size*2048,sizeof(*Port1)); _ASSERT(Port1 != NULL); } if (Chipset.Port2Size) { - Port2 = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,Chipset.Port2Size*2048); + Port2 = calloc(Chipset.Port2Size*2048,sizeof(*Port2)); _ASSERT(Port2 != NULL); } LoadBreakpointList(NULL); // clear debugger breakpoint list RomSwitch(0); // boot ROM view of HP49G and map memory + bDocumentAvail = TRUE; // document available return TRUE; restore: RestoreBackup(); @@ -848,10 +867,13 @@ BOOL OpenDocument(LPCTSTR szFilename) switch (pbyFileSignature[14]) { case 0xFE: // Win48 2.1 / Emu4x 0.99.x format + // read length of KML script name ReadFile(hFile,&nLength,sizeof(nLength),&lBytesRead,NULL); + // KML script name too long for file buffer + if (nLength >= ARRAYSIZEOF(szCurrentKml)) goto read_err; #if defined _UNICODE { - LPSTR szTmp = HeapAlloc(hHeap,0,nLength); + LPSTR szTmp = malloc(nLength); if (szTmp == NULL) { AbortMessage(_T("Memory Allocation Failure.")); @@ -860,7 +882,7 @@ BOOL OpenDocument(LPCTSTR szFilename) ReadFile(hFile, szTmp, nLength, &lBytesRead, NULL); MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTmp, lBytesRead, szCurrentKml, ARRAYSIZEOF(szCurrentKml)); - HeapFree(hHeap,0,szTmp); + free(szTmp); } #else { @@ -921,13 +943,13 @@ BOOL OpenDocument(LPCTSTR szFilename) goto restore; } // reload old button state - ReloadButtons(Chipset.Keyboard_Row,sizeof(Chipset.Keyboard_Row)); + ReloadButtons(Chipset.Keyboard_Row,ARRAYSIZEOF(Chipset.Keyboard_Row)); FlashInit(); // init flash structure if (Chipset.Port0Size) { - Port0 = HeapAlloc(hHeap,0,Chipset.Port0Size*2048); + Port0 = malloc(Chipset.Port0Size*2048); if (Port0 == NULL) { AbortMessage(_T("Memory Allocation Failure.")); @@ -942,7 +964,7 @@ BOOL OpenDocument(LPCTSTR szFilename) if (Chipset.Port1Size) { - Port1 = HeapAlloc(hHeap,0,Chipset.Port1Size*2048); + Port1 = malloc(Chipset.Port1Size*2048); if (Port1 == NULL) { AbortMessage(_T("Memory Allocation Failure.")); @@ -974,7 +996,7 @@ BOOL OpenDocument(LPCTSTR szFilename) { if (Chipset.Port2Size) { - Port2 = HeapAlloc(hHeap,0,Chipset.Port2Size*2048); + Port2 = malloc(Chipset.Port2Size*2048); if (Port2 == NULL) { AbortMessage(_T("Memory Allocation Failure.")); @@ -1012,7 +1034,7 @@ BOOL OpenDocument(LPCTSTR szFilename) if (pEmuDocumentNotify) pEmuDocumentNotify(szCurrentFilename); #endif SetWindowPathTitle(szCurrentFilename); // update window title line - UpdateWindowStatus(); + bDocumentAvail = TRUE; // document available return TRUE; read_err: @@ -1063,14 +1085,14 @@ BOOL SaveDocument(VOID) WriteFile(hCurrentFile, &nLength, sizeof(nLength), &lBytesWritten, NULL); #if defined _UNICODE { - LPSTR szTmp = HeapAlloc(hHeap,0,nLength); + LPSTR szTmp = malloc(nLength); if (szTmp != NULL) { WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, szCurrentKml, nLength, szTmp, nLength, NULL, NULL); WriteFile(hCurrentFile, szTmp, nLength, &lBytesWritten, NULL); - HeapFree(hHeap,0,szTmp); + free(szTmp); } } #else @@ -1111,7 +1133,6 @@ BOOL SaveDocumentAs(LPCTSTR szFilename) if (pEmuDocumentNotify) pEmuDocumentNotify(szCurrentFilename); #endif SetWindowPathTitle(szCurrentFilename); // update window title line - UpdateWindowStatus(); // and draw it return SaveDocument(); // save current content } @@ -1127,7 +1148,7 @@ BOOL SaveBackup(VOID) { WINDOWPLACEMENT wndpl; - if (pbyRom == NULL) return FALSE; + if (!bDocumentAvail) return FALSE; _ASSERT(nState != SM_RUN); // emulation engine is running @@ -1140,23 +1161,27 @@ BOOL SaveBackup(VOID) lstrcpy(szBackupFilename, szCurrentFilename); lstrcpy(szBackupKml, szCurrentKml); - if (BackupPort0) HeapFree(hHeap,0,BackupPort0); - if (BackupPort1) HeapFree(hHeap,0,BackupPort1); - if (BackupPort2) HeapFree(hHeap,0,BackupPort2); + if (BackupPort0) { free(BackupPort0); BackupPort0 = NULL; } + if (BackupPort1) { free(BackupPort1); BackupPort1 = NULL; } + if (BackupPort2) { free(BackupPort2); BackupPort2 = NULL; } CopyMemory(&BackupChipset, &Chipset, sizeof(Chipset)); - BackupPort0 = HeapAlloc(hHeap,0,Chipset.Port0Size*2048); - CopyMemory(BackupPort0,Port0,Chipset.Port0Size*2048); - BackupPort1 = HeapAlloc(hHeap,0,Chipset.Port1Size*2048); - CopyMemory(BackupPort1,Port1,Chipset.Port1Size*2048); - BackupPort2 = NULL; - if (Chipset.Port2Size) // internal port2 + if (Port0 && Chipset.Port0Size) { - BackupPort2 = HeapAlloc(hHeap,0,Chipset.Port2Size*2048); + BackupPort0 = (LPBYTE) malloc(Chipset.Port0Size*2048); + CopyMemory(BackupPort0,Port0,Chipset.Port0Size*2048); + } + if (Port1 && Chipset.Port1Size) + { + BackupPort1 = (LPBYTE) malloc(Chipset.Port1Size*2048); + CopyMemory(BackupPort1,Port1,Chipset.Port1Size*2048); + } + if (Port2 && Chipset.Port2Size) // internal port2 + { + BackupPort2 = (LPBYTE) malloc(Chipset.Port2Size*2048); CopyMemory(BackupPort2,Port2,Chipset.Port2Size*2048); } CreateBackupBreakpointList(); bBackup = TRUE; - UpdateWindowStatus(); return TRUE; } @@ -1187,30 +1212,36 @@ BOOL RestoreBackup(VOID) } } CopyMemory(&Chipset, &BackupChipset, sizeof(Chipset)); - Port0 = HeapAlloc(hHeap,0,Chipset.Port0Size*2048); - CopyMemory(Port0, BackupPort0, Chipset.Port0Size*2048); - Port1 = HeapAlloc(hHeap,0,Chipset.Port1Size*2048); - CopyMemory(Port1, BackupPort1, Chipset.Port1Size*2048); - if (Chipset.Port2Size) // internal port2 + if (BackupPort0 && Chipset.Port0Size) { - Port2 = HeapAlloc(hHeap,0,Chipset.Port2Size*2048); - CopyMemory(Port2, BackupPort2, Chipset.Port2Size*2048); + Port0 = (LPBYTE) malloc(Chipset.Port0Size*2048); + CopyMemory(Port0,BackupPort0,Chipset.Port0Size*2048); + } + if (BackupPort1 && Chipset.Port1Size) + { + Port1 = (LPBYTE) malloc(Chipset.Port1Size*2048); + CopyMemory(Port1,BackupPort1,Chipset.Port1Size*2048); + } + if (BackupPort2 && Chipset.Port2Size) // internal port2 + { + Port2 = (LPBYTE) malloc(Chipset.Port2Size*2048); + CopyMemory(Port2,BackupPort2,Chipset.Port2Size*2048); } // map port2 else { - if(cCurrentRomType=='S' || cCurrentRomType=='G') // HP48SX/GX + if (cCurrentRomType=='S' || cCurrentRomType=='G') // HP48SX/GX { // use 2nd command line argument if defined MapPort2((nArgc < 3) ? szPort2Filename : ppArgv[2]); } } - Map(0x00,0xFF); + Map(0x00,0xFF); // update memory mapping SetWindowPathTitle(szCurrentFilename); // update window title line SetWindowLocation(hWnd,Chipset.nPosX,Chipset.nPosY); RestoreBackupBreakpointList(); // restore the debugger breakpoint list if (bDbgOpen) OnToolDebug(); // reopen the debugger - UpdateWindowStatus(); + bDocumentAvail = TRUE; // document available return TRUE; } @@ -1219,12 +1250,11 @@ BOOL ResetBackup(VOID) if (!bBackup) return FALSE; szBackupFilename[0] = 0; szBackupKml[0] = 0; - if (BackupPort0) { HeapFree(hHeap,0,BackupPort0); BackupPort0 = NULL; } - if (BackupPort1) { HeapFree(hHeap,0,BackupPort1); BackupPort1 = NULL; } - if (BackupPort2) { HeapFree(hHeap,0,BackupPort2); BackupPort2 = NULL; } + if (BackupPort0) { free(BackupPort0); BackupPort0 = NULL; } + if (BackupPort1) { free(BackupPort1); BackupPort1 = NULL; } + if (BackupPort2) { free(BackupPort2); BackupPort2 = NULL; } ZeroMemory(&BackupChipset,sizeof(BackupChipset)); bBackup = FALSE; - UpdateWindowStatus(); return TRUE; } @@ -1360,12 +1390,12 @@ WORD WriteStack(UINT nStkLevel,LPBYTE lpBuf,DWORD dwSize) // separated from Load DWORD dwAddress, i; bBinary = ((lpBuf[dwSize+0]=='H') - && (lpBuf[dwSize+1]=='P') - && (lpBuf[dwSize+2]=='H') - && (lpBuf[dwSize+3]=='P') - && (lpBuf[dwSize+4]=='4') - && (lpBuf[dwSize+5]==((cCurrentRomType=='X' || cCurrentRomType=='2' || cCurrentRomType=='Q') ? '9' : '8')) // CdB for HP: add apples - && (lpBuf[dwSize+6]=='-')); + && (lpBuf[dwSize+1]=='P') + && (lpBuf[dwSize+2]=='H') + && (lpBuf[dwSize+3]=='P') + && (lpBuf[dwSize+4]=='4') + && (lpBuf[dwSize+5]==((cCurrentRomType=='X' || cCurrentRomType=='2' || cCurrentRomType=='Q') ? '9' : '8')) // CdB for HP: add apples + && (lpBuf[dwSize+6]=='-')); for (dwAddress = 0, i = 0; i < dwSize; i++) { @@ -1418,7 +1448,7 @@ BOOL LoadObject(LPCTSTR szFilename) // separated stack writing part CloseHandle(hFile); return FALSE; } - lpBuf = HeapAlloc(hHeap,0,dwFileSizeLow*2); + lpBuf = malloc(dwFileSizeLow*2); if (lpBuf == NULL) { CloseHandle(hFile); @@ -1438,7 +1468,7 @@ BOOL LoadObject(LPCTSTR szFilename) // separated stack writing part if (wError == S_ERR_ASCII) AbortMessage(_T("The calculator does not have enough\nfree memory to load this text file.")); - HeapFree(hHeap,0,lpBuf); + free(lpBuf); return (wError == S_ERR_NO); } @@ -1498,9 +1528,9 @@ typedef struct _BmpFile LPBYTE pbyFile; // buffer } BMPFILE, FAR *LPBMPFILE, *PBMPFILE; -static __inline UINT DibNumColors(BITMAPINFOHEADER CONST *lpbi) +static __inline WORD DibNumColors(BITMAPINFOHEADER CONST *lpbi) { - if (lpbi->biClrUsed != 0) return (UINT)lpbi->biClrUsed; + if (lpbi->biClrUsed != 0) return (WORD) lpbi->biClrUsed; /* a 24 bitcount DIB has no color table */ return (lpbi->biBitCount <= 8) ? (1 << lpbi->biBitCount) : 0; @@ -1510,7 +1540,7 @@ static HPALETTE CreateBIPalette(BITMAPINFOHEADER CONST *lpbi) { LOGPALETTE* pPal; HPALETTE hpal = NULL; - UINT nNumColors; + WORD wNumColors; BYTE red; BYTE green; BYTE blue; @@ -1525,29 +1555,28 @@ static HPALETTE CreateBIPalette(BITMAPINFOHEADER CONST *lpbi) // Get a pointer to the color table and the number of colors in it pRgb = (RGBQUAD FAR *)((LPBYTE)lpbi + (WORD)lpbi->biSize); - nNumColors = DibNumColors(lpbi); + wNumColors = DibNumColors(lpbi); - if (nNumColors) + if (wNumColors) { // Allocate for the logical palette structure - pPal = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY)); - if (!pPal) - return NULL; + pPal = malloc(sizeof(LOGPALETTE) + wNumColors * sizeof(PALETTEENTRY)); + if (!pPal) return NULL; - pPal->palNumEntries = nNumColors; pPal->palVersion = 0x300; + pPal->palNumEntries = wNumColors; // Fill in the palette entries from the DIB color table and // create a logical color palette. - for (i = 0; i < nNumColors; i++) + for (i = 0; i < pPal->palNumEntries; i++) { pPal->palPalEntry[i].peRed = pRgb[i].rgbRed; pPal->palPalEntry[i].peGreen = pRgb[i].rgbGreen; pPal->palPalEntry[i].peBlue = pRgb[i].rgbBlue; - pPal->palPalEntry[i].peFlags = (BYTE)0; + pPal->palPalEntry[i].peFlags = 0; } hpal = CreatePalette(pPal); - HeapFree(hHeap,0,pPal); + free(pPal); } else { @@ -1555,12 +1584,12 @@ static HPALETTE CreateBIPalette(BITMAPINFOHEADER CONST *lpbi) // 16, 24 and 32 bitcount DIB's have no color table entries so, set the // number of to the maximum value (256). - nNumColors = 256; - pPal = HeapAlloc(hHeap,0,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY)); + wNumColors = 256; + pPal = malloc(sizeof(LOGPALETTE) + wNumColors * sizeof(PALETTEENTRY)); if (!pPal) return NULL; - pPal->palNumEntries = nNumColors; pPal->palVersion = 0x300; + pPal->palNumEntries = wNumColors; red = green = blue = 0; @@ -1578,7 +1607,7 @@ static HPALETTE CreateBIPalette(BITMAPINFOHEADER CONST *lpbi) blue += 64; } hpal = CreatePalette(pPal); - HeapFree(hHeap,0,pPal); + free(pPal); } return hpal; } @@ -1621,7 +1650,7 @@ static HBITMAP DecodeBmp(LPBMPFILE pBmp) else { dwFileSize += WIDTHBYTES(pBmi->bmiHeader.biWidth * pBmi->bmiHeader.biBitCount) - * labs(pBmi->bmiHeader.biHeight); + * labs(pBmi->bmiHeader.biHeight); } if (pBmp->dwFileSize < dwFileSize) return NULL; @@ -1633,12 +1662,13 @@ static HBITMAP DecodeBmp(LPBMPFILE pBmp) pBmi, DIB_RGB_COLORS)); if (hBitmap == NULL) return NULL; - _ASSERT(hPalette == NULL); // resource free - hPalette = CreateBIPalette(&pBmi->bmiHeader); - // save old palette - hOldPalette = SelectPalette(hWindowDC, hPalette, FALSE); - RealizePalette(hWindowDC); - + if (hPalette == NULL) + { + hPalette = CreateBIPalette(&pBmi->bmiHeader); + // save old palette + hOldPalette = SelectPalette(hWindowDC, hPalette, FALSE); + RealizePalette(hWindowDC); + } return hBitmap; } @@ -1727,7 +1757,7 @@ static HBITMAP DecodeGif(LPBMPFILE pBmp) bmi.bmiHeader.biWidth = nWidth; bmi.bmiHeader.biHeight = nHeight; bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 24; // create a true color DIB + bmi.bmiHeader.biBitCount = 24; // create a true color DIB bmi.bmiHeader.biCompression = BI_RGB; ZeroMemory(&sGlb,sizeof(sGlb)); // init global color map @@ -2123,14 +2153,16 @@ static HBITMAP DecodeGif(LPBMPFILE pBmp) } } - _ASSERT(bDecoding == FALSE); // decoding successful + _ASSERT(bDecoding == FALSE); // decoding successful // normal decoding exit - _ASSERT(hPalette == NULL); // resource free - hPalette = CreateBIPalette((PBITMAPINFOHEADER) &bmi); - // save old palette - hOldPalette = SelectPalette(hWindowDC, hPalette, FALSE); - RealizePalette(hWindowDC); + if (hPalette == NULL) + { + hPalette = CreateBIPalette((PBITMAPINFOHEADER) &bmi); + // save old palette + hOldPalette = SelectPalette(hWindowDC, hPalette, FALSE); + RealizePalette(hWindowDC); + } quit: if (hBitmap != NULL && bDecoding) // creation failed diff --git a/source/I28F160.C b/source/source/I28F160.C similarity index 100% rename from source/I28F160.C rename to source/source/I28F160.C diff --git a/source/I28F160.H b/source/source/I28F160.H similarity index 100% rename from source/I28F160.H rename to source/source/I28F160.H diff --git a/source/IO.H b/source/source/IO.H similarity index 94% rename from source/IO.H rename to source/source/IO.H index c9378bb..c622adf 100644 --- a/source/IO.H +++ b/source/source/IO.H @@ -28,6 +28,7 @@ #define SRQ2 0x19 // SRQ2 #define IR_CTRL 0x1a // IR CONTROL #define LCR 0x1c // Led Control Register +#define LBR 0x1d // Led Buffer Register #define DISP1CTL 0x20 // Display Start Address #define LINENIBS 0x25 // Display Line Offset #define LINECOUNT 0x28 // Display Line Counter @@ -125,7 +126,10 @@ #define LBZ 0x02 // Led Port Busy #define LBF 0x01 // Led Buffer Full -// 0x28 Display Line Counter LSB [LC3 LC2 LC1 LC0] +// 0x1d Led Buffer Register [0 0 0 LBO] (bits 1-3 read zero) +#define LBO 0x01 + +// 0x28 Display Line Counter LSB [LC3 LC2 LC1 LC0] #define LC3 0x08 // LC3 - Line Counter Bit3 #define LC2 0x04 // LC2 - Line Counter Bit2 #define LC1 0x02 // LC1 - Line Counter Bit1 diff --git a/source/KEYBOARD.C b/source/source/KEYBOARD.C similarity index 100% rename from source/KEYBOARD.C rename to source/source/KEYBOARD.C diff --git a/source/KEYMACRO.C b/source/source/KEYMACRO.C similarity index 89% rename from source/KEYMACRO.C rename to source/source/KEYMACRO.C index 80eb82a..9d4d930 100644 --- a/source/KEYMACRO.C +++ b/source/source/KEYMACRO.C @@ -13,8 +13,6 @@ #define KEYMACROHEAD "Emu-KeyMacro" // macro signature -#define KEYHOLDTIME 50 - #define MIN_SPEED 0 #define MAX_SPEED 500 @@ -24,9 +22,10 @@ typedef struct DWORD dwKeyEvent; // key code } KeyData; -INT nMacroState = MACRO_OFF; -INT nMacroTimeout = MIN_SPEED; -BOOL bMacroRealSpeed = TRUE; +INT nMacroState = MACRO_OFF; +INT nMacroTimeout = MIN_SPEED; +BOOL bMacroRealSpeed = TRUE; +DWORD dwMacroMinDelay = 0; // minimum macro play key hold time in ms static DWORD dwTimeRef; @@ -49,7 +48,7 @@ static VOID InitializeOFN(LPOPENFILENAME ofn) static DWORD WINAPI EventThread(LPVOID pParam) { DWORD dwRead = 0; - DWORD dwData,dwTime = 0; + DWORD dwData = 0,dwTime = 0; while (WaitForSingleObject(hEventPlay,dwTime) == WAIT_TIMEOUT) { @@ -59,8 +58,7 @@ static DWORD WINAPI EventThread(LPVOID pParam) UINT nOut = (dwData >> 16) & 0xFF; BOOL bPress = (dwData >> 24) & 0xFF; - PlayKey(nOut,nIn,bPress); -// KeyboardEvent(bPress,nOut,nIn); + PlayKey(nOut,nIn,bPress); } dwTime = nMacroTimeout; // set default speed @@ -84,6 +82,13 @@ static DWORD WINAPI EventThread(LPVOID pParam) } continue; } + + // hold the key state the minimum macro play key hold time + if (dwTime < dwMacroMinDelay) dwTime = dwMacroMinDelay; + + dwTime -= dwKeyMinDelay; // remove the actual key hold time + // set negative number to zero + if ((dwTime & 0x80000000) != 0) dwTime = 0; break; // got key information } } @@ -102,9 +107,7 @@ VOID KeyMacroRecord(BOOL bPress, UINT out, UINT in) DWORD dwWritten; dwWritten = GetTickCount(); // time reference - Data.dwTime = (dwWritten - dwTimeRef - KEYHOLDTIME); - // set negative number to zero - if ((Data.dwTime & 0x80000000) != 0) Data.dwTime = 0; + Data.dwTime = (dwWritten - dwTimeRef); Data.dwTime |= 0x80000000; // set time marker dwTimeRef = dwWritten; @@ -161,14 +164,13 @@ LRESULT OnToolMacroNew(VOID) _ASSERT(dwWritten == sizeof(dwExtensionLength)); nMacroState = MACRO_NEW; - UpdateWindowStatus(); MessageBox(hWnd, _T("Press OK to begin to record the Macro."), _T("Macro Recorder"), MB_OK|MB_ICONINFORMATION); - dwTimeRef = GetTickCount() + KEYHOLDTIME; // time reference + dwTimeRef = GetTickCount(); // time reference return 0; } @@ -242,7 +244,6 @@ LRESULT OnToolMacroPlay(VOID) hEventPlay = CreateEvent(NULL,FALSE,FALSE,NULL); nMacroState = MACRO_PLAY; - UpdateWindowStatus(); // start playing thread VERIFY(hThreadEv = CreateThread(NULL,0,&EventThread,NULL,0,&dwThreadId)); @@ -273,7 +274,6 @@ LRESULT OnToolMacroStop(VOID) if (hMacroFile != INVALID_HANDLE_VALUE) CloseHandle(hMacroFile); nMacroState = MACRO_OFF; - UpdateWindowStatus(); } return 0; } diff --git a/source/KML.C b/source/source/KML.C similarity index 81% rename from source/KML.C rename to source/source/KML.C index 870dfd0..6e7afed 100644 --- a/source/KML.C +++ b/source/source/KML.C @@ -19,11 +19,11 @@ static DWORD ParseInteger(VOID); static LPTSTR ParseString(VOID); static TokenId Lex(UINT nMode); static KmlLine* ParseLine(TokenId eCommand); -static KmlLine* IncludeLines(LPCTSTR szFilename); -static KmlLine* ParseLines(VOID); -static KmlBlock* ParseBlock(TokenId eBlock); -static KmlBlock* IncludeBlocks(LPCTSTR szFilename); -static KmlBlock* ParseBlocks(VOID); +static KmlLine* IncludeLines(BOOL bInclude, LPCTSTR szFilename); +static KmlLine* ParseLines(BOOL bInclude); +static KmlBlock* ParseBlock(BOOL bInclude, TokenId eBlock); +static KmlBlock* IncludeBlocks(BOOL bInclude, LPCTSTR szFilename); +static KmlBlock* ParseBlocks(BOOL bInclude, BOOL bEndTokenEn); static VOID FreeLines(KmlLine* pLine); static VOID PressButton(UINT nId); static VOID ReleaseButton(UINT nId); @@ -45,6 +45,8 @@ static UINT nButtons = 0; static UINT nScancodes = 0; static UINT nAnnunciators = 0; static BOOL bDebug = TRUE; +static WORD wKeybLocId = 0; +static BOOL bLocaleInc = FALSE; // no locale block content included static UINT nLexLine; static UINT nLexInteger; static UINT nBlocksIncludeLevel; @@ -59,7 +61,7 @@ static LPCTSTR szLexDelim[] = _T(" \t\r") // valid whitespaces for LEX_PARAM }; -static KmlToken pLexToken[] = +static CONST KmlToken pLexToken[] = { {TOK_ANNUNCIATOR,000001,11,_T("Annunciator")}, {TOK_BACKGROUND, 000000,10,_T("Background")}, @@ -81,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_LOCALE, 000001, 6,_T("Locale")}, {TOK_TITLE, 000002, 5,_T("Title")}, {TOK_OUTIN, 000011, 5,_T("OutIn")}, {TOK_PATCH, 000002, 5,_T("Patch")}, @@ -101,7 +104,7 @@ static KmlToken pLexToken[] = {TOK_ROM, 000002, 3,_T("Rom")}, {TOK_LCD, 000000, 3,_T("Lcd")}, {TOK_END, 000000, 3,_T("End")}, - {0, 000000, 0,_T("")}, + {TOK_NONE, 000000, 0,_T("")} }; static CONST TokenId eIsGlobalBlock[] = @@ -111,7 +114,8 @@ static CONST TokenId eIsGlobalBlock[] = TOK_LCD, TOK_ANNUNCIATOR, TOK_BUTTON, - TOK_SCANCODE + TOK_SCANCODE, + TOK_LOCALE }; static CONST TokenId eIsBlock[] = @@ -126,7 +130,7 @@ static CONST TokenId eIsBlock[] = static BOOL bClicking = FALSE; static UINT uButtonClicked = 0; -static BOOL bKeyPressed = FALSE; // no key pressed +static BOOL bKeyPressed = FALSE; // no key pressed static UINT uLastKeyPressed = 0; // var for last pressed key //################ @@ -143,7 +147,7 @@ static VOID ClearLog() nLogLength = 0; if (szLog != NULL) { - HeapFree(hHeap,0,szLog); + free(szLog); szLog = NULL; } return; @@ -155,7 +159,7 @@ static VOID AddToLog(LPCTSTR szString) if (szLog == NULL) { nLogLength = nLength + 1; // \0 - szLog = HeapAlloc(hHeap,0,nLogLength*sizeof(szLog[0])); + szLog = (LPTSTR) malloc(nLogLength*sizeof(szLog[0])); if (szLog==NULL) { nLogLength = 0; @@ -165,7 +169,7 @@ static VOID AddToLog(LPCTSTR szString) } else { - LPTSTR szLogTmp = HeapReAlloc(hHeap,0,szLog,(nLogLength+nLength)*sizeof(szLog[0])); + LPTSTR szLogTmp = (LPTSTR) realloc(szLog,(nLogLength+nLength)*sizeof(szLog[0])); if (szLogTmp == NULL) { ClearLog(); @@ -265,9 +269,9 @@ static VOID DestroyKmlList(VOID) while (pKmlList) { pList = pKmlList->pNext; - HeapFree(hHeap,0,pKmlList->szFilename); - HeapFree(hHeap,0,pKmlList->szTitle); - HeapFree(hHeap,0,pKmlList); + free(pKmlList->szFilename); + free(pKmlList->szTitle); + free(pKmlList); pKmlList = pList; } return; @@ -310,7 +314,7 @@ static VOID CreateKmlList(VOID) FreeBlocks(pBlock); continue; } - VERIFY(pScript = HeapAlloc(hHeap,0,sizeof(KmlScript))); + VERIFY(pScript = (KmlScript*) malloc(sizeof(KmlScript))); pScript->szFilename = DuplicateString(pFindFileData.cFileName); szTitle = GetStringParam(pBlock,TOK_GLOBAL,TOK_TITLE,0); if (szTitle == NULL) szTitle = pScript->szFilename; @@ -387,7 +391,7 @@ static VOID UpdateScriptList(HWND hDlg) HWND hList; KmlScript* pList; UINT nIndex,nEntries; - DWORD dwActId = CB_ERR; + DWORD dwActId = (DWORD) CB_ERR; // add all script titles to combo box hList = GetDlgItem(hDlg,IDC_KMLSCRIPT); @@ -494,7 +498,7 @@ static LPTSTR MapKMLFile(HANDLE hFile) goto fail; } - lpBuf = HeapAlloc(hHeap,0,(dwFileSizeLow+1)*sizeof(lpBuf[0])); + lpBuf = (LPTSTR) malloc((dwFileSizeLow+1)*sizeof(lpBuf[0])); if (lpBuf == NULL) { PrintfToLog(_T("Cannot allocate %i bytes."), (dwFileSizeLow+1)*sizeof(lpBuf[0])); @@ -502,17 +506,17 @@ static LPTSTR MapKMLFile(HANDLE hFile) } #if defined _UNICODE { - LPSTR szTmp = HeapAlloc(hHeap,0,dwFileSizeLow+1); + LPSTR szTmp = (LPSTR) malloc(dwFileSizeLow+1); if (szTmp == NULL) { - HeapFree(hHeap,0,lpBuf); + free(lpBuf); lpBuf = NULL; PrintfToLog(_T("Cannot allocate %i bytes."), dwFileSizeLow+1); goto fail; } ReadFile(hFile, szTmp, dwFileSizeLow, &lBytesRead, NULL); MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTmp, lBytesRead, lpBuf, dwFileSizeLow+1); - HeapFree(hHeap,0,szTmp); + free(szTmp); } #else { @@ -592,7 +596,7 @@ static VOID SkipWhite(UINT nMode) // search for delimiter if ((pcDelim = _tcschr(szLexDelim[nMode],*szText)) != NULL) { - _ASSERT(*pcDelim != 0); // no EOS + _ASSERT(*pcDelim != 0); // no EOS if (*pcDelim == _T('\n')) nLexLine++; szText++; continue; @@ -631,13 +635,13 @@ static TokenId ParseToken(UINT nMode) } } } - if (bDebug) + if (bDebug) // token not found { // allocate target string memory with token length - LPTSTR szToken = HeapAlloc(hHeap,0,(i+1) * sizeof(szToken[0])); + LPTSTR szToken = (LPTSTR) malloc((i+1) * sizeof(szToken[0])); lstrcpyn(szToken,szText,i+1); // copy token text and append EOS PrintfToLog(_T("%i: Undefined token %s"),nLexLine,szToken); - HeapFree(hHeap,0,szToken); + free(szToken); } return TOK_NONE; } @@ -662,21 +666,33 @@ static LPTSTR ParseString(VOID) szText++; // skip leading '"' nLength = 0; nBlock = 256; - lpszString = HeapAlloc(hHeap,0,nBlock * sizeof(lpszString[0])); + lpszString = (LPTSTR) malloc(nBlock * sizeof(lpszString[0])); while (*szText != _T('"')) { if (nLength == nBlock - 1) // ran out of buffer space { nBlock += 256; - lpszString = HeapReAlloc(hHeap,0,lpszString,nBlock * sizeof(lpszString[0])); + lpszString = realloc(lpszString,nBlock * sizeof(lpszString[0])); + } + + if (*szText == _T('\\')) // escape char + { + // skip a '\' escape char before a quotation to + // decode the \" sequence as a quotation mark inside text + switch (szText[1]) + { + case _T('\"'): + case _T('\\'): + ++szText; // skip escape char '\' + break; + } } - if (*szText == _T('\\')) szText++; // skip '\' escape char to decode \" if (*szText == 0) // EOS found inside string { lpszString[nLength] = 0; // set EOS PrintfToLog(_T("%i: Invalid string %s."), nLexLine, lpszString); - HeapFree(hHeap,0,lpszString); + free(lpszString); return NULL; } lpszString[nLength++] = *szText++; // save char @@ -685,7 +701,7 @@ static LPTSTR ParseString(VOID) lpszString[nLength] = 0; // set EOS // release unnecessary allocated bytes - return HeapReAlloc(hHeap,0,lpszString,(nLength+1) * sizeof(lpszString[0])); + return realloc(lpszString,(nLength+1) * sizeof(lpszString[0])); } static TokenId Lex(UINT nMode) @@ -733,7 +749,7 @@ static KmlLine* ParseLine(TokenId eCommand) } if (pLexToken[i].nLen == 0) return NULL; - pLine = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(KmlLine)); + pLine = (KmlLine*) calloc(1,sizeof(KmlLine)); pLine->eCommand = eCommand; for (j = 0, nParams = pLexToken[i].nParams; TRUE; nParams >>= 3) @@ -769,6 +785,7 @@ static KmlLine* ParseLine(TokenId eCommand) break; // free memory of arguments } pLine->nParam[j++] = (DWORD_PTR) szLexString; + szLexString = NULL; continue; } _ASSERT(FALSE); // unknown parameter type @@ -776,22 +793,26 @@ static KmlLine* ParseLine(TokenId eCommand) } // if last argument was string, free it - if (eToken == TOK_STRING) HeapFree(hHeap,0,szLexString); + if (eToken == TOK_STRING) + { + free(szLexString); + szLexString = NULL; + } nParams = pLexToken[i].nParams; // get argument types of command for (i = 0; i < j; ++i) // handle all scanned arguments { if ((nParams & 7) == TYPE_STRING) // string type { - HeapFree(hHeap,0,(LPVOID)pLine->nParam[i]); + free((LPVOID)pLine->nParam[i]); } nParams >>= 3; // next argument type } - HeapFree(hHeap,0,pLine); + free(pLine); return NULL; } -static KmlLine* IncludeLines(LPCTSTR szFilename) +static KmlLine* IncludeLines(BOOL bInclude, LPCTSTR szFilename) { HANDLE hFile; LPTSTR lpbyBuf; @@ -822,27 +843,30 @@ static KmlLine* IncludeLines(LPCTSTR szFilename) szOldText = szText; nLinesIncludeLevel++; - PrintfToLog(_T("l%i:Including %s"), nLinesIncludeLevel, szFilename); + PrintfToLog(_T("l%i:%s %s"), + nLinesIncludeLevel, + (bInclude) ? _T("Including") : _T("Parsing"), + szFilename); InitLex(lpbyBuf); - pLine = ParseLines(); + pLine = ParseLines(bInclude); CleanLex(); nLinesIncludeLevel--; nLexLine = uOldLine; szText = szOldText; - HeapFree(hHeap,0,lpbyBuf); + free(lpbyBuf); return pLine; } -static KmlLine* ParseLines(VOID) +static KmlLine* ParseLines(BOOL bInclude) { KmlLine* pFirst = NULL; KmlLine* pLine = NULL; TokenId eToken; UINT nLevel = 0; - while ((eToken = Lex(LEX_COMMAND))) + while ((eToken = Lex(LEX_COMMAND)) != TOK_NONE) { if (IsGlobalBlock(eToken)) // check for block command { @@ -856,19 +880,32 @@ static KmlLine* ParseLines(VOID) eToken = Lex(LEX_PARAM); // get include parameter in 'szLexString' if (eToken != TOK_STRING) // not a string (token don't begin with ") { - AddToLog(_T("Include: string expected as parameter.")); + PrintfToLog(_T("%i: Include: string expected as parameter."), nLexLine); goto abort; } szFilename = szLexString; // save pointer to allocated memory + szLexString = NULL; + eToken = Lex(LEX_PARAM); // decode argument + if (eToken != TOK_EOL) + { + free(szFilename); // free filename string + if (eToken == TOK_STRING) + { + free(szLexString); + szLexString = NULL; + } + PrintfToLog(_T("%i: Include: Too many parameters."), nLexLine); + goto abort; + } if (pFirst) { - pLine = pLine->pNext = IncludeLines(szLexString); + pLine = pLine->pNext = IncludeLines(bInclude,szFilename); } else { - pLine = pFirst = IncludeLines(szLexString); + pLine = pFirst = IncludeLines(bInclude,szFilename); } - HeapFree(hHeap,0,szFilename); // free memory + free(szFilename); // free filename string if (pLine == NULL) // parsing error goto abort; while (pLine->pNext) pLine=pLine->pNext; @@ -882,7 +919,14 @@ static KmlLine* ParseLines(VOID) } else { + if (pFirst == NULL) // regular exit with empty block + { + // create an empty line + pLine = pFirst = (KmlLine*) calloc(1,sizeof(KmlLine)); + pLine->eCommand = TOK_NONE; + } if (pLine) pLine->pNext = NULL; + _ASSERT(szLexString == NULL); return pFirst; } } @@ -900,17 +944,16 @@ static KmlLine* ParseLines(VOID) if (nLinesIncludeLevel) { if (pLine) pLine->pNext = NULL; + _ASSERT(szLexString == NULL); return pFirst; } abort: - if (pFirst) - { - FreeLines(pFirst); - } + if (pFirst) FreeLines(pFirst); + _ASSERT(szLexString == NULL); return NULL; } -static KmlBlock* ParseBlock(TokenId eType) +static KmlBlock* ParseBlock(BOOL bInclude, TokenId eType) { UINT i; KmlBlock* pBlock; @@ -918,7 +961,7 @@ static KmlBlock* ParseBlock(TokenId eType) nLinesIncludeLevel = 0; - VERIFY(pBlock = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(KmlBlock))); + VERIFY(pBlock = (KmlBlock *) calloc(1,sizeof(KmlBlock))); pBlock->eType = eType; for (i = 0; pLexToken[i].nLen; ++i) // search for token @@ -934,8 +977,14 @@ static KmlBlock* ParseBlock(TokenId eType) eToken = Lex(LEX_PARAM); // decode argument if (eToken != TOK_INTEGER) { + if (eToken == TOK_STRING) + { + free(szLexString); + szLexString = NULL; + } PrintfToLog(_T("%i: Block %s parameter must be an integer."), nLexLine, pLexToken[i].szName); - HeapFree(hHeap,0,pBlock); + free(pBlock); + _ASSERT(szLexString == NULL); return NULL; } @@ -945,22 +994,28 @@ static KmlBlock* ParseBlock(TokenId eType) eToken = Lex(LEX_PARAM); // decode argument if (eToken != TOK_EOL) { + if (eToken == TOK_STRING) + { + free(szLexString); + szLexString = NULL; + } PrintfToLog(_T("%i: Too many parameters for block %s."), nLexLine, pLexToken[i].szName); - HeapFree(hHeap,0,pBlock); + free(pBlock); + _ASSERT(szLexString == NULL); return NULL; } - pBlock->pFirstLine = ParseLines(); + pBlock->pFirstLine = ParseLines(bInclude); if (pBlock->pFirstLine == NULL) // break on ParseLines error { - HeapFree(hHeap,0,pBlock); + free(pBlock); pBlock = NULL; } - + _ASSERT(szLexString == NULL); return pBlock; } -static KmlBlock* IncludeBlocks(LPCTSTR szFilename) +static KmlBlock* IncludeBlocks(BOOL bInclude, LPCTSTR szFilename) { HANDLE hFile; LPTSTR lpbyBuf; @@ -991,27 +1046,35 @@ static KmlBlock* IncludeBlocks(LPCTSTR szFilename) szOldText = szText; nBlocksIncludeLevel++; - PrintfToLog(_T("b%i:Including %s"), nBlocksIncludeLevel, szFilename); + PrintfToLog(_T("b%i:%s %s"), + nBlocksIncludeLevel, + (bInclude) ? _T("Including") : _T("Parsing"), + szFilename); InitLex(lpbyBuf); - pFirst = ParseBlocks(); + pFirst = ParseBlocks(bInclude, FALSE); CleanLex(); nBlocksIncludeLevel--; nLexLine = uOldLine; szText = szOldText; - HeapFree(hHeap,0,lpbyBuf); + free(lpbyBuf); return pFirst; } -static KmlBlock* ParseBlocks(VOID) +static KmlBlock* ParseBlocks(BOOL bInclude, BOOL bEndTokenEn) { TokenId eToken; KmlBlock* pFirst = NULL; KmlBlock* pBlock = NULL; - while ((eToken=Lex(LEX_BLOCK))!=TOK_NONE) + while ((eToken = Lex(LEX_BLOCK)) != TOK_NONE) { + // allow TOK_END token only as end of a "Locale" block + if (bEndTokenEn && eToken == TOK_END) + { + return pFirst; + } if (eToken == TOK_INCLUDE) { LPTSTR szFilename; @@ -1022,14 +1085,83 @@ static KmlBlock* ParseBlocks(VOID) goto abort; } szFilename = szLexString; // save pointer to allocated memory + szLexString = NULL; + eToken = Lex(LEX_PARAM); // decode argument + if (eToken != TOK_EOL) + { + free(szFilename); // free filename string + PrintfToLog(_T("%i: Include: Too many parameters."), nLexLine); + goto abort; + } if (pFirst) - pBlock = pBlock->pNext = IncludeBlocks(szLexString); + pBlock = pBlock->pNext = IncludeBlocks(bInclude,szFilename); else - pBlock = pFirst = IncludeBlocks(szLexString); - HeapFree(hHeap,0,szFilename); // free memory + pBlock = pFirst = IncludeBlocks(bInclude,szFilename); + free(szFilename); // free filename string if (pBlock == NULL) // parsing error goto abort; - while (pBlock->pNext) pBlock=pBlock->pNext; + while (pBlock->pNext) pBlock = pBlock->pNext; + continue; + } + if (eToken == TOK_LOCALE) + { + WORD wLocId,wKeybId; + KmlBlock* pData; + BOOL bIncludeId; + + eToken = Lex(LEX_PARAM); // get include parameter in 'nLexInteger' + if (eToken != TOK_INTEGER) + { + PrintfToLog(_T("%i: Locale parameter must be an integer."), nLexLine); + goto abort; + } + wLocId = nLexInteger; // requested keyboard locale id + eToken = Lex(LEX_PARAM); // decode argument + if (eToken != TOK_EOL) + { + PrintfToLog(_T("%i: Too many parameters for Locale."), nLexLine); + goto abort; + } + + wKeybId = wKeybLocId; // get current keyboard layout input locale + if (SUBLANGID(wLocId) == SUBLANG_NEUTRAL) + { + wKeybId = (PRIMARYLANGID(wLocId) != LANG_NEUTRAL) + ? PRIMARYLANGID(wKeybId) + : LANG_NEUTRAL; + } + + // check if block should be included or skipped + bIncludeId = bInclude && !bLocaleInc && (wKeybId == wLocId); + + PrintfToLog(_T("b%i:%s \"Locale %i\""), + nBlocksIncludeLevel, + (bIncludeId) ? _T("Including") : _T("Skipping"), + wLocId); + + pData = ParseBlocks(bIncludeId,TRUE); // parse block, allow "End" + if (pData == NULL) // parsing error + { + // don't blame the block twice + if (pFirst) FreeBlocks(pFirst); + return NULL; + } + + if (bIncludeId) // insert blocks to block list + { + if (pFirst) + pBlock = pBlock->pNext = pData; + else + pBlock = pFirst = pData; + + // goto end of insertion + while (pBlock->pNext) pBlock = pBlock->pNext; + bLocaleInc = TRUE; // locale block content included + } + else // skip block + { + if (pData) FreeBlocks(pData); + } continue; } if (!IsGlobalBlock(eToken)) // check for valid block commands @@ -1038,22 +1170,28 @@ static KmlBlock* ParseBlocks(VOID) goto abort; } if (pFirst) - pBlock = pBlock->pNext = ParseBlock(eToken); + pBlock = pBlock->pNext = ParseBlock(bInclude,eToken); else - pBlock = pFirst = ParseBlock(eToken); + pBlock = pFirst = ParseBlock(bInclude,eToken); if (pBlock == NULL) goto abort; } - if (pBlock) pBlock->pNext = NULL; if (*szText != 0) // still KML text left { goto abort; } + _ASSERT(szLexString == NULL); return pFirst; abort: PrintfToLog(_T("Fatal Error at line %i."), nLexLine); + if (szLexString && eToken == TOK_STRING) + { + free(szLexString); + szLexString = NULL; + } if (pFirst) FreeBlocks(pFirst); + _ASSERT(szLexString == NULL); return NULL; } @@ -1319,8 +1457,9 @@ static KmlLine* SkipLines(KmlLine* pLine, TokenId eCommand) while (pLine) { if (IsBlock(pLine->eCommand)) nLevel++; - if (pLine->eCommand==eCommand) + if (pLine->eCommand == eCommand) { + // found token, return command behind token if (nLevel == 0) return pLine->pNext; } if (pLine->eCommand == TOK_END) @@ -1441,13 +1580,13 @@ static VOID FreeLines(KmlLine* pLine) { if ((nParams&7) == TYPE_STRING) // string type { - HeapFree(hHeap,0,(LPVOID)pLine->nParam[i]); + free((LPVOID)pLine->nParam[i]); } i++; // incr. parameter buffer index nParams >>= 3; // next argument type } pLine = pLine->pNext; // get next line - HeapFree(hHeap,0,pThisLine); + free(pThisLine); } return; } @@ -1459,7 +1598,7 @@ VOID FreeBlocks(KmlBlock* pBlock) KmlBlock* pThisBlock = pBlock; pBlock = pBlock->pNext; FreeLines(pThisBlock->pFirstLine); - HeapFree(hHeap,0,pThisBlock); + free(pThisBlock); } return; } @@ -1477,11 +1616,8 @@ VOID KillKML(VOID) DestroyMainBitmap(); if (hPalette) { - BOOL err; - if (hWindowDC) SelectPalette(hWindowDC, hOldPalette, FALSE); - err = DeleteObject(hPalette); - _ASSERT(err != FALSE); // freed resource memory + VERIFY(DeleteObject(hPalette)); hPalette = NULL; } bClicking = FALSE; @@ -1492,6 +1628,8 @@ VOID KillKML(VOID) nScancodes = 0; nAnnunciators = 0; bDebug = TRUE; + wKeybLocId = 0; + bLocaleInc = FALSE; nKMLFlags = 0; ZeroMemory(pButton, sizeof(pButton)); ZeroMemory(pAnnunciator, sizeof(pAnnunciator)); @@ -1504,7 +1642,6 @@ VOID KillKML(VOID) nLcdZoom = 1; cCurrentRomType = 0; nCurrentClass = 0; - UpdateWindowStatus(); ResizeWindow(); return; } @@ -1579,7 +1716,7 @@ static INT iSqrt(INT nNumber) // integer y=sqrt(x) function else b = m; // adjust lower border } - while(t - b > 1); + while (t - b > 1); return b; } @@ -1614,7 +1751,7 @@ static __inline VOID TransparentCircle(UINT cx, UINT cy, UINT r) #define LOWADJ 0x10 // color incr. at border UINT x, y, rr, rrc; - + if (r < 2) return; // radius 2 pixel minimum rr = r * r; // calculate r^2 @@ -1748,20 +1885,21 @@ static VOID DrawButton(UINT nId) static VOID PressButton(UINT nId) { - if (pButton[nId].bDown) return; // key already pressed -> exit - - pButton[nId].bDown = TRUE; - DrawButton(nId); - if (pButton[nId].nIn) + if (!pButton[nId].bDown) // button not pressed { - KeyboardEvent(TRUE,pButton[nId].nOut,pButton[nId].nIn); - } - else - { - KmlLine* pLine = pButton[nId].pOnDown; - while ((pLine)&&(pLine->eCommand!=TOK_END)) + pButton[nId].bDown = TRUE; + DrawButton(nId); + if (pButton[nId].nIn) { - pLine = RunLine(pLine); + KeyboardEvent(TRUE,pButton[nId].nOut,pButton[nId].nIn); + } + else + { + KmlLine* pLine = pButton[nId].pOnDown; + while ((pLine)&&(pLine->eCommand!=TOK_END)) + { + pLine = RunLine(pLine); + } } } return; @@ -1769,18 +1907,21 @@ static VOID PressButton(UINT nId) static VOID ReleaseButton(UINT nId) { - pButton[nId].bDown = FALSE; - DrawButton(nId); - if (pButton[nId].nIn) + if (pButton[nId].bDown) // button not released { - KeyboardEvent(FALSE,pButton[nId].nOut,pButton[nId].nIn); - } - else - { - KmlLine* pLine = pButton[nId].pOnUp; - while ((pLine)&&(pLine->eCommand!=TOK_END)) + pButton[nId].bDown = FALSE; + DrawButton(nId); + if (pButton[nId].nIn) { - pLine = RunLine(pLine); + KeyboardEvent(FALSE,pButton[nId].nOut,pButton[nId].nIn); + } + else + { + KmlLine* pLine = pButton[nId].pOnUp; + while ((pLine)&&(pLine->eCommand!=TOK_END)) + { + pLine = RunLine(pLine); + } } } return; @@ -1831,12 +1972,21 @@ static VOID ReleaseAllButtons(VOID) // release all buttons VOID ReloadButtons(BYTE *Keyboard_Row, UINT nSize) { UINT i; + bKeyPressed = FALSE; // no key pressed for (i=0; ipFirstLine; - byVKeyMap[nId] = bPressed; + byVKeyMap[nId] = (BYTE) bPressed; while (pLine) pLine = RunLine(pLine); } else @@ -2104,7 +2254,7 @@ static KmlBlock* LoadKMLGlobal(LPCTSTR szFilename) HANDLE hFile; LPTSTR lpBuf; KmlBlock* pBlock; - DWORD eToken; + TokenId eToken; SetCurrentDirectory(szEmuDirectory); hFile = CreateFile(szFilename, @@ -2125,19 +2275,25 @@ static KmlBlock* LoadKMLGlobal(LPCTSTR szFilename) { if (eToken == TOK_GLOBAL) { - pBlock = ParseBlock(eToken); + pBlock = ParseBlock(TRUE,eToken); if (pBlock) pBlock->pNext = NULL; break; } + if (eToken == TOK_STRING) + { + free(szLexString); + szLexString = NULL; + } } CleanLex(); ClearLog(); - HeapFree(hHeap,0,lpBuf); + free(lpBuf); return pBlock; } BOOL InitKML(LPCTSTR szFilename, BOOL bNoLog) { + TCHAR szKLID[KL_NAMELENGTH]; HANDLE hFile; LPTSTR lpBuf; KmlBlock* pBlock; @@ -2145,6 +2301,12 @@ BOOL InitKML(LPCTSTR szFilename, BOOL bNoLog) KillKML(); + // get current keyboard layout input locale + if (GetKeyboardLayoutName(szKLID)) + { + wKeybLocId = (WORD) _tcstoul(szKLID,NULL,16); + } + nBlocksIncludeLevel = 0; PrintfToLog(_T("Reading %s"), szFilename); SetCurrentDirectory(szEmuDirectory); @@ -2165,10 +2327,11 @@ BOOL InitKML(LPCTSTR szFilename, BOOL bNoLog) goto quit; InitLex(lpBuf); - pKml = ParseBlocks(); + pKml = ParseBlocks(TRUE, // include blocks + FALSE); // keyword "End" is invalid CleanLex(); - HeapFree(hHeap,0,lpBuf); + free(lpBuf); if (pKml == NULL) goto quit; pBlock = pKml; @@ -2229,6 +2392,7 @@ BOOL InitKML(LPCTSTR szFilename, BOOL bNoLog) PrintfToLog(_T("%i Buttons Defined"), nButtons); PrintfToLog(_T("%i Scancodes Defined"), nScancodes); PrintfToLog(_T("%i Annunciators Defined"), nAnnunciators); + PrintfToLog(_T("Keyboard Locale: %i"), wKeybLocId); bOk = TRUE; diff --git a/source/KML.H b/source/source/KML.H similarity index 78% rename from source/KML.H rename to source/source/KML.H index 54c062a..90aad95 100644 --- a/source/KML.H +++ b/source/source/KML.H @@ -35,30 +35,31 @@ typedef enum eTokenId TOK_IFFLAG, //19 TOK_ONDOWN, //20 TOK_NOHOLD, //21 - 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_IFMEM, //32 - TOK_TYPE, //33 - TOK_SIZE, //34 - TOK_DOWN, //35 - TOK_ZOOM, //36 - TOK_ELSE, //37 - TOK_ONUP, //38 - TOK_EOL, //39 - TOK_MAP, //34 - TOK_ROM, //41 - TOK_VGA, //42 - TOK_LCD, //43 - TOK_NOTFLAG, //44 - TOK_END //45 + TOK_LOCALE, //22 + TOK_TOPBAR, //23 + TOK_TITLE, //24 + TOK_OUTIN, //25 + TOK_PATCH, //26 + TOK_PRINT, //27 + TOK_DEBUG, //28 + TOK_COLOR, //29 + TOK_MODEL, //30 + TOK_CLASS, //31 + TOK_PRESS, //32 + TOK_IFMEM, //33 + TOK_TYPE, //34 + TOK_SIZE, //35 + TOK_DOWN, //36 + TOK_ZOOM, //37 + TOK_ELSE, //38 + TOK_ONUP, //39 + TOK_EOL, //40 + TOK_MAP, //41 + TOK_ROM, //42 + TOK_VGA, //43 + TOK_LCD, //44 + TOK_NOTFLAG, //45 + TOK_END //46 } TokenId; #define TYPE_NONE 00 diff --git a/source/MOPS.C b/source/source/MOPS.C similarity index 91% rename from source/MOPS.C rename to source/source/MOPS.C index 1ff578c..b8e71ec 100644 --- a/source/MOPS.C +++ b/source/source/MOPS.C @@ -400,8 +400,8 @@ VOID Map(BYTE a, BYTE b) // maps 2KB pages with priority // @todo cg, bug if display header area is mapped to addr 0 if (Chipset.d0address!=0) { - RMap[Chipset.d0address]=&(Chipset.d0memory[0]); RMap[Chipset.d0address+1]=&(Chipset.d0memory[2048*2]); - WMap[Chipset.d0address]=&(Chipset.d0memory[0]); WMap[Chipset.d0address+1]=&(Chipset.d0memory[2048*2]); + RMap[Chipset.d0address]=&(Chipset.d0memory[0]); RMap[Chipset.d0address+1]=&(Chipset.d0memory[2048*2]); + WMap[Chipset.d0address]=&(Chipset.d0memory[0]); WMap[Chipset.d0address+1]=&(Chipset.d0memory[2048*2]); } return; } @@ -995,6 +995,29 @@ VOID IOBit(DWORD d, BYTE b, BOOL s) // set/clear bit in I/O section LeaveCriticalSection(&csIOLock); } +static DWORD ReadT2Acc(VOID) +{ + static DWORD dwCyc = 0; // CPU cycle counter at last timer2 read access + + DWORD dwCycDif; + + // CPU cycles since last call + dwCycDif = (DWORD) (Chipset.cycles & 0xFFFFFFFF) - dwCyc; + dwCyc = (DWORD) (Chipset.cycles & 0xFFFFFFFF); + + // maybe CPU speed measurement, slow down the next 10 CPU opcodes + if (dwCycDif < 150) + { + EnterCriticalSection(&csSlowLock); + { + InitAdjustSpeed(); // init variables if necessary + nOpcSlow = 10; // slow down next 10 opcodes + } + LeaveCriticalSection(&csSlowLock); + } + return ReadT2(); +} + VOID ReadIO(BYTE *a, DWORD d, DWORD s, BOOL bUpdate) { BOOL bNINT; @@ -1035,15 +1058,29 @@ VOID ReadIO(BYTE *a, DWORD d, DWORD s, BOOL bUpdate) // case 0x0B: *a = Chipset.IORam[d]; break; // case 0x0C: *a = Chipset.IORam[d]; break; case 0x0D: // BAUD - *a = Chipset.IORam[d] & 0x7; - #if defined DEBUG_SERIAL // return BAUD value + if (isModelApple(cCurrentRomType)) { - TCHAR buffer[256]; - wsprintf(buffer,_T("%.5lx: BAUD Read: %x\n"),Chipset.pc,*a); - OutputDebugString(buffer); + *a = Chipset.IORam[d]; + #if defined DEBUG_SERIAL // return BAUD value + { + TCHAR buffer[256]; + wsprintf(buffer,_T("%.5lx: BAUD Read: %x\n"),Chipset.pc,*a); + OutputDebugString(buffer); + } + #endif + } // Clarke / Yorke chip + else + { + *a = Chipset.IORam[d] & 0x7; + #if defined DEBUG_SERIAL // return BAUD value + { + TCHAR buffer[256]; + wsprintf(buffer,_T("%.5lx: BAUD Read: %x\n"),Chipset.pc,*a); + OutputDebugString(buffer); + } + #endif + *a |= UckBit(*a); // add UCK bit to BAUD rate register } - #endif - *a |= UckBit(*a); // add UCK bit to BAUD rate register break; case 0x0E: // SMP is !NINT and SWINT is always 0 @@ -1166,8 +1203,13 @@ VOID ReadIO(BYTE *a, DWORD d, DWORD s, BOOL bUpdate) #endif break; case 0x1B: *a = 0; break; - case 0x1C: *a = 0; break; // LED CONTROL - case 0x1D: *a = 0; break; // LED BUFFER + case 0x1C: // LED CONTROL + // put LBF and LBZ always to zero to indicate a free REDEYE buffer and formatter + *a = (Chipset.IORam[d] & (LED|ELBE)); + break; + case 0x1D: // LED BUFFER + *a = (Chipset.IORam[d] & LBO); + break; // case 0x1E: *a = Chipset.IORam[d]; break; // case 0x1F: *a = Chipset.IORam[d]; break; case 0x20: *a = 3; break; @@ -1220,14 +1262,14 @@ VOID ReadIO(BYTE *a, DWORD d, DWORD s, BOOL bUpdate) case 0x35: *a = 0; break; case 0x36: *a = 0; break; case 0x37: *a = ReadT1(); break; - case 0x38: Nunpack(a, ReadT2() , s); return; - case 0x39: Nunpack(a, ReadT2()>> 4, s); return; - case 0x3A: Nunpack(a, ReadT2()>> 8, s); return; - case 0x3B: Nunpack(a, ReadT2()>>12, s); return; - case 0x3C: Nunpack(a, ReadT2()>>16, s); return; - case 0x3D: Nunpack(a, ReadT2()>>20, s); return; - case 0x3E: Nunpack(a, ReadT2()>>24, s); return; - case 0x3F: Nunpack(a, ReadT2()>>28, s); return; + case 0x38: Nunpack(a, ReadT2Acc() , s); return; + case 0x39: Nunpack(a, ReadT2Acc()>> 4, s); return; + case 0x3A: Nunpack(a, ReadT2Acc()>> 8, s); return; + case 0x3B: Nunpack(a, ReadT2Acc()>>12, s); return; + case 0x3C: Nunpack(a, ReadT2Acc()>>16, s); return; + case 0x3D: Nunpack(a, ReadT2Acc()>>20, s); return; + case 0x3E: Nunpack(a, ReadT2Acc()>>24, s); return; + case 0x3F: Nunpack(a, ReadT2Acc()>>28, s); return; default: *a = Chipset.IORam[d]; } d++; a++; @@ -1373,7 +1415,15 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s) // 0010D @ Serial baud rate [UCK BD2 BD1 BD0] (bit 3 is read-only) // 0010D @ 3 bits = {1200 1920 2400 3840 4800 7680 9600 15360} case 0x0D: - Chipset.IORam[d]=(Chipset.IORam[d]&8)|(c&7); // bit 3 is read-only + if (isModelApple(cCurrentRomType)) + { + Chipset.IORam[d] = c; + } + else // Clarke / Yorke chip + { + // bit 3 is read-only + Chipset.IORam[d] = (Chipset.IORam[d]&8)|(c&7); + } CommSetBaud(); // set baudrate #if defined DEBUG_SERIAL { @@ -1582,12 +1632,31 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s) } #endif } + // Saturnator on apples has no ELBE bit simulation + if (cCurrentRomType!='Q' && cCurrentRomType!='2' && cCurrentRomType!='P') + { + if ((c^Chipset.IORam[d])&ELBE) // ELBE bit changed + { + // Led Service ReQuest on Led Buffer Empty enabled + BOOL bLSRQ = (c & (ELBE | LBF)) == ELBE; + + IOBit(SRQ2,LSRQ,bLSRQ); // update LSRQ bit + if (bLSRQ) // interrupt on Led Buffer Empty enabled + { + Chipset.SoftInt = TRUE; + bInterrupt = TRUE; + } + } + } Chipset.IORam[d]=c; break; // 0011D = NS:LBR // 0011D @ Led Buffer Register [0 0 0 LBO] (bits 1-3 read zero) - case 0x1D: Chipset.IORam[d]=c&1; break; + case 0x1D: + IrPrinter((BYTE)(c&LBO)); + Chipset.IORam[d]=c&LBO; + break; // 0011E = NS:SCRATCHPAD // 0011E @ Scratch pad diff --git a/source/MRU.C b/source/source/MRU.C similarity index 89% rename from source/MRU.C rename to source/source/MRU.C index 82c62a9..a7a2f72 100644 --- a/source/MRU.C +++ b/source/source/MRU.C @@ -73,7 +73,7 @@ BOOL MruInit(INT nNum) if (nEntry > 0) // allocate MRU table { // create MRU table - if ((ppszFiles = HeapAlloc(hHeap,0,nEntry * sizeof(*ppszFiles))) == NULL) + if ((ppszFiles = malloc(nEntry * sizeof(*ppszFiles))) == NULL) return TRUE; // fill each entry @@ -104,12 +104,12 @@ VOID MruCleanup(VOID) for (i = 0; i < nEntry; ++i) // cleanup each entry { if (ppszFiles[i] != NULL) - HeapFree(hHeap,0,ppszFiles[i]); // cleanup entry + free(ppszFiles[i]); // cleanup entry } if (ppszFiles != NULL) // table defined { - HeapFree(hHeap,0,ppszFiles); // free table + free(ppszFiles); // free table ppszFiles = NULL; } return; @@ -140,7 +140,7 @@ VOID MruAdd(LPCTSTR lpszEntry) i = nEntry - 1; // last index if (ppszFiles[i] != NULL) - HeapFree(hHeap,0,ppszFiles[i]); // free oldest entry + free(ppszFiles[i]); // free oldest entry for (; i > 0; --i) // move old entries 1 line down { @@ -156,7 +156,7 @@ VOID MruAdd(LPCTSTR lpszEntry) VOID MruRemove(INT nIndex) { - HeapFree(hHeap,0,ppszFiles[nIndex]); // free entry + free(ppszFiles[nIndex]); // free entry for (; nIndex < nEntry - 1; ++nIndex) // move below entries 1 line up { @@ -198,10 +198,10 @@ LPCTSTR MruFilename(INT nIndex) VOID MruUpdateMenu(VOID) { - TCHAR szCurPath[MAX_PATH]; - HANDLE hMenu; - BOOL bEmpty; - INT i; + TCHAR szCurPath[MAX_PATH]; + HMENU hMenu; + BOOL bEmpty; + INT i; if (nEntry == 0) return; // no entries @@ -309,7 +309,6 @@ VOID MruReadList(VOID) { TCHAR szFilename[MAX_PATH]; TCHAR szItemname[32]; - LPTSTR lpszValue; INT i; _ASSERT(ppszFiles != NULL); // MRU not initialized @@ -321,9 +320,8 @@ VOID MruReadList(VOID) if (ppszFiles[i] != NULL) // already filled { - HeapFree(hHeap,0,ppszFiles[i]); // free entry + free(ppszFiles[i]); // free entry ppszFiles[i] = NULL; // clear last line - lpszValue = _T(""); } if (*szFilename) // read a valid entry diff --git a/source/OPCODES.C b/source/source/OPCODES.C similarity index 100% rename from source/OPCODES.C rename to source/source/OPCODES.C diff --git a/source/OPCODES.H b/source/source/OPCODES.H similarity index 100% rename from source/OPCODES.H rename to source/source/OPCODES.H diff --git a/source/OPS.H b/source/source/OPS.H similarity index 92% rename from source/OPS.H rename to source/source/OPS.H index 5312027..95c9c36 100644 --- a/source/OPS.H +++ b/source/source/OPS.H @@ -48,7 +48,7 @@ static __inline LPBYTE FASTPTR(DWORD d) if ( !(Chipset.IOCfig && ((d & 0xFFFC0) == Chipset.IOBase)) && RMap[u] != NULL // page valid - && ( v < 0x1000 - ARRAYSIZEOF(lpbyPage) // complete opcode inside page + && ( v < 0x1000 - ARRAYSIZEOF(pbyNULL) // complete opcode inside page // or next page continue linear addressing || (RMap[u] + 0x1000 == RMap[(u+1) & (ARRAYSIZEOF(RMap)-1)]) ) @@ -59,7 +59,7 @@ static __inline LPBYTE FASTPTR(DWORD d) else { lpbyPage = pbyNULL; // memory allocation - Npeek(lpbyPage, d, ARRAYSIZEOF(lpbyPage)); // fill with data (LAHEX + 16 digits = longest opcode) + Npeek(lpbyPage, d, ARRAYSIZEOF(pbyNULL)); // fill with data (LAHEX + 16 digits = longest opcode) } return lpbyPage; } diff --git a/source/PCH.C b/source/source/PCH.C similarity index 100% rename from source/PCH.C rename to source/source/PCH.C diff --git a/source/PCH.H b/source/source/PCH.H similarity index 95% rename from source/PCH.H rename to source/source/PCH.H index 81dddc3..4171343 100644 --- a/source/PCH.H +++ b/source/source/PCH.H @@ -4,6 +4,7 @@ #define _WIN32_IE 0x0200 #define _CRT_SECURE_NO_DEPRECATE +#define _CRTDBG_MAP_ALLOC #include #include diff --git a/source/source/REDEYE.C b/source/source/REDEYE.C new file mode 100644 index 0000000..bd646fe --- /dev/null +++ b/source/source/REDEYE.C @@ -0,0 +1,177 @@ +/* + * redeye.c + * + * This file is part of Emu48 + * + * Copyright (C) 2011 Christoph Gießelink + * + */ +#include "pch.h" +#include "Emu48.h" +#include "io.h" + +#define ERR_CHAR 127 // character for transfer error + +#define H1 0x78 +#define H2 0xE6 +#define H3 0xD5 +#define H4 0x8B + +// HP redeye correction masks +static CONST BYTE byEmask[] = { H1, H2, H3, H4 }; + +static __inline UINT MAX(UINT a, UINT b) +{ + return (a>b)?a:b; +} + +static __inline BYTE Parity(BYTE b) +{ + b ^= (b >> 4); + b ^= (b >> 2); + b ^= (b >> 1); + return b & 1; +} + +static __inline BYTE CreateCorrectionBits(BYTE b) +{ + INT i; + BYTE byVal = 0; + + for (i = 0; i < ARRAYSIZEOF(byEmask);++i) + { + byVal <<= 1; + byVal |= Parity((BYTE) (b & byEmask[i])); + } + return byVal; +} + +static __inline WORD CorrectData(WORD wData,WORD wMissed) +{ + while ((wMissed & 0xFF) != 0) // clear every missed bit in data area + { + BYTE byBitMask; + + // detect valid H(i) mask + WORD wMi = 0x800; // first M(i) bit + INT i = 0; // index to first H(i) mask + + while (TRUE) + { + if ((wMissed & wMi) == 0) // possible valid mask + { + _ASSERT(i < ARRAYSIZEOF(byEmask)); + + // select bit to correct + byBitMask = wMissed & byEmask[i]; + + if (Parity(byBitMask)) // only one bit set (parity odd) + break; // -> valid H(i) mask + } + + wMi >>= 1; // next M(i) bit + i++; // next H(i) mask + } + + // correct bit with H(i) mask + wMissed ^= byBitMask; // clear this missed bit + + // parity odd -> wrong data value + if (Parity((BYTE) ((wData & byEmask[i]) ^ ((wData & wMi) >> 8)))) + wData ^= byBitMask; // correct value + } + return wData & 0xFF; // only data byte is correct +} + +VOID IrPrinter(BYTE c) +{ + static INT nFrame = 0; // frame counter + static DWORD dwData = 0; // half bit data container + static INT nStart = 0; // frame counter disabled + + BOOL bLSRQ; + + dwData = (dwData << 1) | (c & LBO); // grab the last 32 bit send through IR + + // Led Service ReQuest on Led Buffer Empty enabled + bLSRQ = (Chipset.IORam[LCR] & ELBE) != 0; + + IOBit(SRQ2,LSRQ,bLSRQ); // update LSRQ bit + if (bLSRQ) // interrupt on Led Buffer Empty enabled + { + Chipset.SoftInt = TRUE; // execute interrupt + bInterrupt = TRUE; + } + + // HP40G and HP49G have no IR transmitter Led + if ((cCurrentRomType == 'E' && nCurrentClass == 40) || cCurrentRomType == 'X') + return; + + if (nFrame == 0) // waiting for start bit condition + { + if ((dwData & 0x3F) == 0x07) // start bit condition (000111 pattern) + { + nStart = 1; // enable frame counter + } + } + + if (nFrame == 24) // 24 half bit received + { + INT i; + + WORD wData = 0; // data container + WORD wMissed = 0; // missed bit container + INT nCount = 0; // no. of missed bits + + nFrame = 0; // reset for next character + nStart = 0; // disable frame counter + + // separate to data and missed bits + for (i = 0; i < 12; ++i) // 12 bit frames + { + BYTE b = (BYTE) (dwData & 3); // last 2 half bits + + if (b == 0x0 || b == 0x3) // illegal half bit combination + { + wMissed |= (1 << i); // this is a missed bit + ++nCount; // incr. number of missed bits + } + else // valid data bit + { + wData |= ((b >> 1) << i); // add data bit + } + dwData >>= 2; // next 2 half bits + } + + if (nCount <= 2) // error can be fixed + { + BYTE byOrgParity,byNewParity; + + byOrgParity = wData >> 8; // the original parity information with missed bits + byNewParity = ~(wMissed >> 8); // missed bit mask for recalculated parity + + if (nCount > 0) // error correction + { + wData = CorrectData(wData,wMissed); + } + + wData &= 0xFF; // remove parity information + + // recalculate parity data + byNewParity &= CreateCorrectionBits((BYTE) wData); + + // wrong parity + if (byOrgParity != byNewParity) + wData = ERR_CHAR; // character for transfer error + } + else + { + wData = ERR_CHAR; // character for transfer error + } + + SendByteUdp((BYTE) wData); // send data byte + return; + } + nFrame += nStart; // next frame + return; +} diff --git a/source/RESOURCE.H b/source/source/RESOURCE.H similarity index 63% rename from source/RESOURCE.H rename to source/source/RESOURCE.H index 10dcaf7..38c2dd6 100644 --- a/source/RESOURCE.H +++ b/source/source/RESOURCE.H @@ -26,7 +26,9 @@ #define IDD_FIND 120 #define IDD_PROFILE 121 #define IDD_MACROSET 122 -#define IDD_DEBUG_SETTINGS 123 +#define IDD_DEBUG_MEMSAVE 123 +#define IDD_DEBUG_MEMLOAD 124 +#define IDD_DEBUG_SETTINGS 125 #define IDC_REALSPEED 1000 #define IDC_GRAYSCALE 1001 #define IDC_ALWAYSONTOP 1002 @@ -41,23 +43,22 @@ #define IDC_PORT2WR 1011 #define IDC_PORT2 1012 #define IDC_PORT2LOAD 1013 -#define IDC_WIRE 1014 -#define IDC_IR 1015 -#define IDC_EMUDIR 1016 -#define IDC_EMUDIRSEL 1017 -#define IDC_UPDATE 1018 -#define IDC_KMLSCRIPT 1019 -#define IDC_AUTHOR 1020 -#define IDC_TITLE 1021 -#define IDC_KMLLOG 1022 -#define IDC_VERSION 1023 -#define IDC_LICENSE 1024 -#define IDC_DISASM_WIN 1025 -#define IDC_DISASM_MAP 1026 -#define IDC_DISASM_ROM 1027 -#define IDC_DISASM_RAM 1028 -#define IDC_DISASM_PORT1 1029 -#define IDC_DISASM_PORT2 1030 +#define IDC_IR_ADDR 1014 +#define IDC_IR_PORT 1015 +#define IDC_WIRE 1016 +#define IDC_IR 1017 +#define IDC_EMUDIR 1018 +#define IDC_EMUDIRSEL 1019 +#define IDC_UPDATE 1020 +#define IDC_KMLSCRIPT 1021 +#define IDC_AUTHOR 1022 +#define IDC_TITLE 1023 +#define IDC_KMLLOG 1024 +#define IDC_VERSION 1025 +#define IDC_LICENSE 1026 +#define IDC_DISASM_WIN 1028 +#define IDC_DISASM_MODE_TEXT 1029 +#define IDC_DISASM_MODE 1030 #define IDC_DISASM_MODULE 1031 #define IDC_DISASM_HP 1032 #define IDC_DISASM_CLASS 1033 @@ -108,54 +109,59 @@ #define IDC_DEBUG_MEM_COL6 1078 #define IDC_DEBUG_MEM_COL7 1079 #define IDC_DEBUG_MEM_TEXT 1080 -#define IDC_DEBUG_STACK 1081 -#define IDC_STATIC_BREAKPOINT 1082 -#define IDC_BREAKEDIT_ADD 1083 -#define IDC_BREAKEDIT_DELETE 1084 -#define IDC_BREAKEDIT_WND 1085 -#define IDC_STATIC_MMU 1086 -#define IDC_MMU_IO_A 1087 -#define IDC_MMU_NCE2_A 1088 -#define IDC_MMU_CE1_A 1089 -#define IDC_MMU_CE2_A 1090 -#define IDC_MMU_NCE3_A 1091 -#define IDC_MMU_IO_S 1092 -#define IDC_MMU_CE1_S 1093 -#define IDC_MMU_CE2_S 1094 -#define IDC_MMU_NCE2_S 1095 -#define IDC_MMU_NCE3_S 1096 -#define IDC_STATIC_MISC 1097 -#define IDC_MISC_BS_TXT 1098 -#define IDC_INSTR_TEXT 1099 -#define IDC_INSTR_CODE 1100 -#define IDC_INSTR_COPY 1101 -#define IDC_INSTR_CLEAR 1102 -#define IDC_PROFILE_LASTCYCLES 1103 -#define IDC_PROFILE_LASTTIME 1104 -#define IDC_BPCODE 1105 -#define IDC_BPRPL 1106 -#define IDC_BPACCESS 1107 -#define IDC_BPREAD 1108 -#define IDC_BPWRITE 1109 -#define IDC_FIND_DATA 1110 -#define IDC_FIND_ASCII 1111 -#define IDC_FIND_CASE 1112 -#define IDC_ADDR20_24 1113 -#define IDC_ADDR25_27 1114 -#define IDC_ADDR28_29 1115 -#define IDC_ADDR30_34 1116 -#define IDC_MACRO_SLOW 1117 -#define IDC_MACRO_FAST 1118 -#define IDC_MACRO_SLIDER 1119 -#define IDC_MACRO_REAL 1120 -#define IDC_MACRO_MANUAL 1121 -#define IDC_SOUND_SLIDER 1122 -#define IDC_SOUND_SPEAKER 1123 -#define IDC_SOUND_WAVE 1124 -#define IDC_DEBUG_SET_SYMB 1125 -#define IDC_DEBUG_SET_MODEL 1126 -#define IDC_DEBUG_SET_FILE 1227 -#define IDC_DEBUG_SET_BROWSE 1228 +#define IDC_DEBUG_DATA_FILE 1081 +#define IDC_DEBUG_DATA_BUT 1082 +#define IDC_DEBUG_DATA_STARTADDR 1083 +#define IDC_DEBUG_DATA_ENDADDR 1084 +#define IDC_DEBUG_SET_SYMB 1085 +#define IDC_DEBUG_SET_MODEL 1086 +#define IDC_DEBUG_SET_FILE 1087 +#define IDC_DEBUG_SET_BROWSE 1088 +#define IDC_DEBUG_STACK 1089 +#define IDC_STATIC_BREAKPOINT 1090 +#define IDC_BREAKEDIT_ADD 1091 +#define IDC_BREAKEDIT_DELETE 1092 +#define IDC_BREAKEDIT_WND 1093 +#define IDC_STATIC_MMU 1094 +#define IDC_MMU_IO_A 1095 +#define IDC_MMU_NCE2_A 1096 +#define IDC_MMU_CE1_A 1097 +#define IDC_MMU_CE2_A 1098 +#define IDC_MMU_NCE3_A 1099 +#define IDC_MMU_IO_S 1100 +#define IDC_MMU_CE1_S 1101 +#define IDC_MMU_CE2_S 1102 +#define IDC_MMU_NCE2_S 1103 +#define IDC_MMU_NCE3_S 1104 +#define IDC_STATIC_MISC 1105 +#define IDC_MISC_BS_TXT 1106 +#define IDC_INSTR_TEXT 1107 +#define IDC_INSTR_CODE 1108 +#define IDC_INSTR_COPY 1109 +#define IDC_INSTR_CLEAR 1110 +#define IDC_PROFILE_LASTCYCLES 1111 +#define IDC_PROFILE_LASTTIME 1112 +#define IDC_BPCODE 1113 +#define IDC_BPRPL 1114 +#define IDC_BPACCESS 1115 +#define IDC_BPREAD 1116 +#define IDC_BPWRITE 1117 +#define IDC_FIND_DATA 1118 +#define IDC_FIND_PREV 1119 +#define IDC_FIND_NEXT 1120 +#define IDC_FIND_ASCII 1121 +#define IDC_ADDR20_24 1122 +#define IDC_ADDR25_27 1123 +#define IDC_ADDR28_29 1124 +#define IDC_ADDR30_34 1125 +#define IDC_MACRO_SLOW 1126 +#define IDC_MACRO_FAST 1127 +#define IDC_MACRO_SLIDER 1128 +#define IDC_MACRO_REAL 1129 +#define IDC_MACRO_MANUAL 1130 +#define IDC_SOUND_SLIDER 1131 +#define IDC_SOUND_SPEAKER 1132 +#define IDC_SOUND_WAVE 1133 #define ID_FILE_NEW 40001 #define ID_FILE_OPEN 40002 #define ID_FILE_SAVE 40003 @@ -213,22 +219,24 @@ #define ID_DEBUG_MEM_CE1 40057 #define ID_DEBUG_MEM_CE2 40058 #define ID_DEBUG_MEM_NCE3 40059 -#define ID_DEBUG_STACK_PUSH 40060 -#define ID_DEBUG_STACK_POP 40061 -#define ID_DEBUG_STACK_MODIFY 40062 -#define ID_INTR_STEPOVERINT 40063 -#define ID_INFO_LASTINSTRUCTIONS 40064 -#define ID_INFO_PROFILE 40065 -#define ID_INFO_WRITEONLYREG 40066 +#define ID_DEBUG_MEM_SAVE 40060 +#define ID_DEBUG_MEM_LOAD 40061 +#define ID_DEBUG_STACK_PUSH 40062 +#define ID_DEBUG_STACK_POP 40063 +#define ID_DEBUG_STACK_MODIFY 40064 +#define ID_INTR_STEPOVERINT 40065 +#define ID_INFO_LASTINSTRUCTIONS 40066 +#define ID_INFO_PROFILE 40067 +#define ID_INFO_WRITEONLYREG 40068 #define ID_FILE_MRU_FILE1 40100 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 124 -#define _APS_NEXT_COMMAND_VALUE 40067 -#define _APS_NEXT_CONTROL_VALUE 1129 +#define _APS_NEXT_RESOURCE_VALUE 126 +#define _APS_NEXT_COMMAND_VALUE 40069 +#define _APS_NEXT_CONTROL_VALUE 1134 #define _APS_NEXT_SYMED_VALUE 108 #endif #endif diff --git a/source/RPL.C b/source/source/RPL.C similarity index 96% rename from source/RPL.C rename to source/source/RPL.C index 6cd5ff0..db22e8f 100644 --- a/source/RPL.C +++ b/source/source/RPL.C @@ -396,10 +396,10 @@ DWORD RPL_CreateTemp(DWORD l,BOOL bGarbageCol) Write5(TEMPTOP, a+l); // adjust new end of top object Write5(RSKTOP, b+l); // adjust new end of rtn stack Write5(AVMEM, (c-b-l)/5); // calculate free memory (*5 nibbles) - p = HeapAlloc(hHeap,0,b-a); // move down rtn stack + p = malloc(b-a); // move down rtn stack Npeek(p,a,b-a); Nwrite(p,a+l,b-a); - HeapFree(hHeap,0,p); + free(p); Write5(a+l-5,l); // set object length field return a+1; // return base address of new object } diff --git a/source/SERIAL.C b/source/source/SERIAL.C similarity index 92% rename from source/SERIAL.C rename to source/source/SERIAL.C index 2c076fb..c4862b1 100644 --- a/source/SERIAL.C +++ b/source/source/SERIAL.C @@ -201,14 +201,19 @@ VOID CommSetBaud(VOID) { if (hComm != NULL) { - const DWORD dwBaudrates[] = { 1200, 1920, 2400, 3840, 4800, 7680, 9600, 15360 }; -// const DWORD dwAppleBaudrates[] = { 1200, 1920, 2400, 3840, 4800, 7680, 9600, 14400, 15360, 19200, 38400, 57600, 115200 }; + const DWORD dwBaudrates[] = { 1200, 1920, 2400, 3840, 4800, 7680, 9600, 15360, + 14400, 19200, 38400, 57600, 115200, 115200, 115200, 115200 }; - DCB dcb; + DCB dcb; + UINT uBaudIndex; + + uBaudIndex = isModelApple(cCurrentRomType) + ? Chipset.IORam[BAUD] + : Chipset.IORam[BAUD] & 0x7; ZeroMemory(&dcb,sizeof(dcb)); dcb.DCBlength = sizeof(dcb); - dcb.BaudRate = dwBaudrates[Chipset.IORam[BAUD] & 0x7]; + dcb.BaudRate = dwBaudrates[uBaudIndex]; dcb.fBinary = TRUE; dcb.fParity = TRUE; dcb.fOutxCtsFlow = FALSE; diff --git a/source/SETTINGS.C b/source/source/SETTINGS.C similarity index 91% rename from source/SETTINGS.C rename to source/source/SETTINGS.C index 6994a51..88cc139 100644 --- a/source/SETTINGS.C +++ b/source/source/SETTINGS.C @@ -180,6 +180,7 @@ VOID ReadSettings(VOID) // Emulator bAlwaysOnTop = ReadInt(_T("Emulator"),_T("AlwaysOnTop"),bAlwaysOnTop); bActFollowsMouse = ReadInt(_T("Emulator"),_T("ActivationFollowsMouse"),bActFollowsMouse); + bSingleInstance = ReadInt(_T("Emulator"),_T("SingleInstance"),bSingleInstance); bRealSpeed = ReadInt(_T("Emulator"),_T("RealSpeed"),bRealSpeed); dwSXCycles = ReadInt(_T("Emulator"),_T("SXCycles"),dwSXCycles); dwGXCycles = ReadInt(_T("Emulator"),_T("GXCycles"),dwGXCycles); @@ -190,10 +191,13 @@ VOID ReadSettings(VOID) 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); nMacroTimeout = ReadInt(_T("Macro"),_T("ReplayTimeout"),nMacroTimeout); + dwMacroMinDelay = ReadInt(_T("Macro"),_T("KeyMinDelay"),dwMacroMinDelay); + // IrPrinter + ReadString(_T("IrPrinter"),_T("Address"),szUdpServer,szUdpServer,ARRAYSIZEOF(szUdpServer)); + wUdpPort = ReadInt(_T("IrPrinter"),_T("Port"),wUdpPort); // Serial ReadString(_T("Serial"),_T("Wire"),_T(NO_SERIAL),szSerialWire,ARRAYSIZEOF(szSerialWire)); ReadString(_T("Serial"),_T("Ir"),_T(NO_SERIAL),szSerialIr,ARRAYSIZEOF(szSerialIr)); @@ -223,6 +227,7 @@ VOID WriteSettings(VOID) // Emulator WriteInt(_T("Emulator"),_T("AlwaysOnTop"),bAlwaysOnTop); WriteInt(_T("Emulator"),_T("ActivationFollowsMouse"),bActFollowsMouse); + WriteInt(_T("Emulator"),_T("SingleInstance"),bSingleInstance); WriteInt(_T("Emulator"),_T("RealSpeed"),bRealSpeed); WriteInt(_T("Emulator"),_T("SXCycles"),dwSXCycles); WriteInt(_T("Emulator"),_T("GXCycles"),dwGXCycles); @@ -236,6 +241,10 @@ VOID WriteSettings(VOID) // Macro WriteInt(_T("Macro"),_T("RealSpeed"),bMacroRealSpeed); WriteInt(_T("Macro"),_T("ReplayTimeout"),nMacroTimeout); + WriteInt(_T("Macro"),_T("KeyMinDelay"),dwMacroMinDelay); + // IrPrinter + WriteString(_T("IrPrinter"),_T("Address"),szUdpServer); + WriteInt(_T("IrPrinter"),_T("Port"),wUdpPort); // Serial WriteString(_T("Serial"),_T("Wire"),szSerialWire); WriteString(_T("Serial"),_T("Ir"),szSerialIr); diff --git a/source/STACK.C b/source/source/STACK.C similarity index 94% rename from source/STACK.C rename to source/source/STACK.C index e260bef..b0179d4 100644 --- a/source/STACK.C +++ b/source/source/STACK.C @@ -128,6 +128,7 @@ static INT RPL_GetBcd(BYTE CONST *pbyNum,INT nMantLen,INT nExpLen,CONST TCHAR cD i = 0; // first character bPflag = FALSE; // show no decimal point + bExpflag = FALSE; // show no exponent // scan mantissa for (v = (LONG) nMantLen - 1; v >= 0 || bPflag; v--) @@ -402,7 +403,7 @@ static INT RPL_SetComplex(LPCTSTR cp,INT nMantLen,INT nExpLen,CONST TCHAR cDec,L } } } - HeapFree(hHeap,0,pszData); + free(pszData); } return nLen; } @@ -460,12 +461,12 @@ static INT DoInt(DWORD dwAddress,LPTSTR cp,INT nSize) if (nIntLen <= 0) return 0; // error in calculator object nLength = 0; - if ((lpbyData = HeapAlloc(hHeap,0,nIntLen))) + if ((lpbyData = malloc(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); + free(lpbyData); } return nLength; } @@ -551,7 +552,7 @@ LRESULT OnStackCopy(VOID) // copy data from stack if ((hClipObj = GlobalAlloc(GMEM_MOVEABLE,dwSize)) == NULL) goto error; - if ((lpbyData = GlobalLock(hClipObj))) + if ((lpbyData = (LPBYTE) GlobalLock(hClipObj))) { // copy data to memory CopyMemory(lpbyData,cBuffer,dwSize); @@ -572,7 +573,7 @@ LRESULT OnStackCopy(VOID) // copy data from stack if ((hClipObj = GlobalAlloc(GMEM_MOVEABLE,dwSize + 1)) == NULL) goto error; - if ((lpbyData = GlobalLock(hClipObj))) // lock memory + if ((lpbyData = (LPBYTE) GlobalLock(hClipObj))) // lock memory { // copy data into clipboard buffer for (dwAddress += 5;dwSize-- > 0;dwAddress += 2,++lpbyData) @@ -580,8 +581,8 @@ LRESULT OnStackCopy(VOID) // copy data from stack *lpbyData = 0; // set EOS GlobalUnlock(hClipObj); // unlock memory - uClipboardFormat = CF_TEXT; // always text } + uClipboardFormat = CF_TEXT; // always text break; default: MessageBeep(MB_OK); // error beep @@ -739,7 +740,7 @@ LRESULT OnStackPaste(VOID) // paste data to stack // any other format { DWORD dwSize = lstrlen(lpstrClipdata); - if ((lpbyData = HeapAlloc(hHeap,0,dwSize * 2))) + if ((lpbyData = malloc(dwSize * 2))) { LPBYTE lpbySrc,lpbyDest; DWORD dwLoop; @@ -778,7 +779,7 @@ LRESULT OnStackPaste(VOID) // paste data to stack // push object to stack RPL_Push(1,dwAddress); } - HeapFree(hHeap,0,lpbyData); + free(lpbyData); } } } diff --git a/source/SYMBFILE.C b/source/source/SYMBFILE.C similarity index 93% rename from source/SYMBFILE.C rename to source/source/SYMBFILE.C index 3784887..f0d609d 100644 --- a/source/SYMBFILE.C +++ b/source/source/SYMBFILE.C @@ -171,7 +171,7 @@ BOOL RplLoadTable(LPCTSTR lpszFilename) *pcPtr = 0; // set EOS // allocate symbol memory - VERIFY(pData = HeapAlloc(hHeap,0,sizeof(RefData))); + VERIFY(pData = malloc(sizeof(RefData))); pData->lpszName = DuplicateString(szSymbolName); pData->dwAddr = GetBigEndian(byPage+dwPageIndex+38,sizeof(DWORD)); @@ -209,8 +209,8 @@ VOID RplDeleteTable(VOID) while (ppsBase[i] != NULL) // walk through all datasets { pData = ppsBase[i]->pNext; - HeapFree(hHeap,0,ppsBase[i]->lpszName); - HeapFree(hHeap,0,ppsBase[i]); + free(ppsBase[i]->lpszName); + free(ppsBase[i]); ppsBase[i] = pData; } } diff --git a/source/TIMER.C b/source/source/TIMER.C similarity index 93% rename from source/TIMER.C rename to source/source/TIMER.C index fc830bf..678ad02 100644 --- a/source/TIMER.C +++ b/source/source/TIMER.C @@ -244,7 +244,6 @@ static void CALLBACK TimeProc(UINT uEventId, UINT uMsg, DWORD_PTR dwUser, DWORD_ UNREFERENCED_PARAMETER(dw2); } - VOID SetHP48Time(VOID) // set date and time { SYSTEMTIME ts; @@ -257,7 +256,7 @@ VOID SetHP48Time(VOID) // set date and time GetLocalTime(&ts); // local time, _ftime() cause memory/resource leaks - // calculate days until 01.01.1970 + // calculate days until 01.01.0000 (Erlang BIF localtime/0) dw = (DWORD) ts.wMonth; if (dw > 2) dw -= 3L; @@ -269,17 +268,18 @@ VOID SetHP48Time(VOID) // set date and time dw = (DWORD) ts.wDay + (153L * dw + 2L) / 5L; dw += (146097L * (((DWORD) ts.wYear) / 100L)) / 4L; dw += (1461L * (((DWORD) ts.wYear) % 100L)) / 4L; - dw -= 719469L; + dw += (-719469L + 719528L); // days from year 0 + + ticks = (ULONGLONG) dw; // convert to 64 bit // convert into seconds and add time - dw = dw * 24L + (DWORD) ts.wHour; - dw = dw * 60L + (DWORD) ts.wMinute; - dw = dw * 60L + (DWORD) ts.wSecond; + ticks = ticks * 24L + (ULONGLONG) ts.wHour; + ticks = ticks * 60L + (ULONGLONG) ts.wMinute; + ticks = ticks * 60L + (ULONGLONG) ts.wSecond; // create timerticks = (s + ms) * 8192 - ticks = ((ULONGLONG) dw << 13) | (((ULONGLONG) ts.wMilliseconds << 10) / 125); + ticks = (ticks << 13) | (((ULONGLONG) ts.wMilliseconds << 10) / 125); - ticks += UNIX_0_TIME; // add offset ticks from year 0 ticks += Chipset.t2; // add actual timer2 value time = ticks; // save for calc. timeout diff --git a/source/TYPES.H b/source/source/TYPES.H similarity index 100% rename from source/TYPES.H rename to source/source/TYPES.H diff --git a/source/source/UDP.C b/source/source/UDP.C new file mode 100644 index 0000000..753066a --- /dev/null +++ b/source/source/UDP.C @@ -0,0 +1,85 @@ +/* + * udp.c + * + * This file is part of Emu48 + * + * Copyright (C) 2011 Christoph Gießelink + * + */ +#include "pch.h" +#include "Emu48.h" + +TCHAR szUdpServer[1024] = _T("localhost"); +WORD wUdpPort = 5025; // scpi-raw + +static IN_ADDR ip_addr = { 255, 255, 255, 255 }; + +VOID ResetUdp(VOID) +{ + ip_addr.s_addr = INADDR_NONE; // invalidate saved UDP address + return; +} + +BOOL SendByteUdp(BYTE byData) +{ + WSADATA wsd; + SOCKET sClient; + SOCKADDR_IN sServer; + + BOOL bErr = TRUE; + + VERIFY(WSAStartup(MAKEWORD(1,1),&wsd) == 0); + + if (ip_addr.s_addr == INADDR_NONE) // IP address not specified + { + LPSTR lpszIpAddr; + + #if defined _UNICODE + DWORD dwLength = lstrlen(szUdpServer) + 1; + + if ((lpszIpAddr = (LPSTR) malloc(dwLength)) == NULL) + return TRUE; // server not found + + WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, + szUdpServer, dwLength, + lpszIpAddr, dwLength, NULL, NULL); + #else + lpszIpAddr = szUdpServer; + #endif + + ip_addr.s_addr = inet_addr(lpszIpAddr); + + // not a valid ip address -> try to get ip address from name server + if (ip_addr.s_addr == INADDR_NONE) + { + PHOSTENT host = gethostbyname(lpszIpAddr); + if (host == NULL) + { + #if defined _UNICODE + free(lpszIpAddr); + #endif + return TRUE; // server not found + } + + ip_addr.s_addr = ((PIN_ADDR) host->h_addr_list[0])->s_addr; + } + #if defined _UNICODE + free(lpszIpAddr); + #endif + } + + // create UDP socket + if ((sClient = socket(AF_INET, SOCK_DGRAM, 0)) != INVALID_SOCKET) + { + sServer.sin_family = AF_INET; + sServer.sin_port = htons(wUdpPort); + sServer.sin_addr.s_addr = ip_addr.s_addr; + + // transmit data byte + bErr = sendto(sClient, (LPCCH) &byData, sizeof(byData), 0, (LPSOCKADDR) &sServer, sizeof(sServer)) == SOCKET_ERROR; + closesocket(sClient); + } + + WSACleanup(); // cleanup network stack + return bErr; +} diff --git a/source/gpl.txt b/source/source/gpl.txt similarity index 100% rename from source/gpl.txt rename to source/source/gpl.txt