diff --git a/EMU48.EXE b/EMU48.EXE index faa28da..c3da645 100755 Binary files a/EMU48.EXE and b/EMU48.EXE differ diff --git a/Keyboard.kmi b/KEYBOARD.KMI similarity index 100% rename from Keyboard.kmi rename to KEYBOARD.KMI diff --git a/MkShared.exe b/MKSHARED.EXE similarity index 100% rename from MkShared.exe rename to MKSHARED.EXE diff --git a/PROBLEMS.TXT b/PROBLEMS.TXT index d50cc8c..4de01a1 100644 --- a/PROBLEMS.TXT +++ b/PROBLEMS.TXT @@ -1,4 +1,4 @@ -Known bugs and restrictions of Emu48 V1.44 +Known bugs and restrictions of Emu48 V1.45 ------------------------------------------ - the following I/O bits aren't emulated (incomplete) @@ -53,4 +53,4 @@ Known bugs and restrictions of Emu48 V1.44 - quitting the emulator while programming the flash isn't allowed, because the content of flash state machine isn't saved so far -05/22/07 (c) by Christoph Gießelink, c dot giesselink at gmx dot de +08/07/07 (c) by Christoph Gießelink, c dot giesselink at gmx dot de diff --git a/Sources/Emu48/CHANGES.TXT b/Sources/Emu48/CHANGES.TXT index 3e72d9b..6cdd83f 100644 --- a/Sources/Emu48/CHANGES.TXT +++ b/Sources/Emu48/CHANGES.TXT @@ -1,3 +1,48 @@ +Service Pack 45 for Emu48 Version 1.0 + +EMU48.C +- bugfix in function SaveChanges(), function GetSaveAsFilename() + returns a boolean and not a button id and removed call of last + document saving +- changed function OnFileOpen(), added MruAdd() call +- added new function OnFileMruOpen(), command handler for MRU menu + selections +- bugfix in function OnFileSaveAs(), function GetSaveAsFilename() + returns a boolean and not a button id, minor optimizations, + removed call of last document saving and added MruAdd() call +- changed function OnObjectSave(), minor optimization +- changed function MainWndProc(), added MRU message handler +- changed function WinMain(), added MRU handling and added last + document saving at end of program + +EMU48.DSP +- added mru.c sources + +EMU48.H +- extern declaration of global functions + +EMU48.RC +- added Menuitem Files "Recent Files..." +- changed version + +MRU.C +- new module for MRU routines + +RESOURCE.H +- added definition for MRU handling + +SETTINGS.C +- added function DelReg() for deleting a registry item +- added functions ReadSettingsString(), WriteSettingsString(), + ReadSettingsInt(), WriteSettingsInt() and DelSettingsKey(), + universal settings interface used for MRU data handling + +TIMER.C +- bugfix in function TimeProc(), under certain conditions this + function is called with a zero uEventId and this may clash with a + reset timer event identifier + + Service Pack 44 for Emu48 Version 1.0 DEBUGGER.C diff --git a/Sources/Emu48/EMU48.C b/Sources/Emu48/EMU48.C index b58516a..0e2fea3 100644 --- a/Sources/Emu48/EMU48.C +++ b/Sources/Emu48/EMU48.C @@ -13,7 +13,7 @@ #include "kml.h" #include "debugger.h" -#define VERSION "1.44" +#define VERSION "1.45" // #define MONOCHROME // CF_BITMAP clipboard format @@ -612,19 +612,20 @@ static UINT SaveChanges(BOOL bAuto) else { UINT uStyle = bSaveDefConfirm ? 0 : MB_DEFBUTTON2; - uReply = YesNoCancelMessage(_T("Do you want to save changes ?"),uStyle); } if (uReply != IDYES) return uReply; - if (szCurrentFilename[0]==0) + if (szCurrentFilename[0] == 0) { // Save As... - uReply = GetSaveAsFilename(); - if (uReply != IDOK) return uReply; - if (!SaveDocumentAs(szBufferFilename)) return IDCANCEL; - WriteLastDocument(szCurrentFilename); - return IDYES; + if (GetSaveAsFilename()) + { + if (SaveDocumentAs(szBufferFilename)) + return IDYES; + // error on saving file + } + return IDCANCEL; } SaveDocument(); @@ -843,7 +844,34 @@ static LRESULT OnFileOpen(VOID) } if (GetOpenFilename()) { - OpenDocument(szBufferFilename); + if (OpenDocument(szBufferFilename)) + MruAdd(szCurrentFilename); + } +cancel: + if (pbyRom) SwitchToState(SM_RUN); + return 0; +} + +// +// ID_FILE_MRU_FILE1 +// +static LRESULT OnFileMruOpen(UINT wID) +{ + LPCTSTR lpszFilename; + + wID -= ID_FILE_MRU_FILE1; // zero based MRU index + lpszFilename = MruFilename(wID); // full filename from MRU list + if (lpszFilename == NULL) return 0; // MRU slot not filled + + if (pbyRom) + { + SwitchToState(SM_INVALID); + if (IDCANCEL == SaveChanges(bAutoSave)) + goto cancel; + } + if (!OpenDocument(lpszFilename)) // document loading failed + { + MruRemove(wID); // entry not valid any more } cancel: if (pbyRom) SwitchToState(SM_RUN); @@ -867,23 +895,14 @@ static LRESULT OnFileSave(VOID) // static LRESULT OnFileSaveAs(VOID) { - UINT uReply; - if (pbyRom == NULL) return 0; SwitchToState(SM_INVALID); - uReply = GetSaveAsFilename(); - if (uReply != IDOK) + if (GetSaveAsFilename()) { - SwitchToState(SM_RUN); - return 0; + if (SaveDocumentAs(szBufferFilename)) + MruAdd(szCurrentFilename); } - if (!SaveDocumentAs(szBufferFilename)) - { - SwitchToState(SM_RUN); - return 0; - } - WriteLastDocument(szCurrentFilename); SwitchToState(SM_RUN); return 0; @@ -1223,16 +1242,12 @@ static LRESULT OnObjectSave(VOID) _ASSERT(nState == SM_SLEEP); - if (!GetSaveObjectFilename()) + if (GetSaveObjectFilename()) { - SwitchToState(SM_RUN); - return 0; + SaveObject(szBufferFilename); } - SaveObject(szBufferFilename); - SwitchToState(SM_RUN); - return 0; } @@ -1487,6 +1502,10 @@ LRESULT CALLBACK MainWndProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lPar case ID_TOOL_MACRO_SETTINGS: return OnToolMacroSettings(); case ID_ABOUT: return OnAbout(); } + // check if command ID belongs to MRU file area + if ( (LOWORD(wParam) >= ID_FILE_MRU_FILE1) + && (LOWORD(wParam) < ID_FILE_MRU_FILE1 + MruEntries())) + return OnFileMruOpen(LOWORD(wParam)); break; case WM_SYSCOMMAND: switch (wParam & 0xFFF0) @@ -1581,8 +1600,8 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC GetCurrentDirectory(ARRAYSIZEOF(szCurrentDirectory), szCurrentDirectory); szCurrentKml[0] = 0; // no KML file selected - ReadSettings(); + MruInit(4); // init MRU entries UpdateWindowStatus(); @@ -1649,6 +1668,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC SetWindowTitle(szTemp); if (OpenDocument(szBufferFilename)) { + MruAdd(szBufferFilename); ShowWindow(hWnd,nCmdShow); goto start; } @@ -1682,6 +1702,7 @@ start: DdeFreeStringHandle(idDdeInst, hszTopic); DdeUninitialize(idDdeInst); + WriteLastDocument(szCurrentFilename); // save last document setting WriteSettings(); // save emulation settings CloseHandle(hThread); // close thread handle @@ -1689,6 +1710,7 @@ start: _ASSERT(nState == SM_RETURN); // emulation thread down? ResetDocument(); ResetBackup(); + MruCleanup(); _ASSERT(pbyRom == NULL); // rom file unmapped _ASSERT(pbyPort2 == NULL); // port2 file unmapped _ASSERT(pKml == NULL); // KML script not closed diff --git a/Sources/Emu48/EMU48.DSP b/Sources/Emu48/EMU48.DSP index 39f90bc..3bb4144 100644 --- a/Sources/Emu48/EMU48.DSP +++ b/Sources/Emu48/EMU48.DSP @@ -7,21 +7,21 @@ CFG=Emu48 - Win32 Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "Emu48.mak". -!MESSAGE +!MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "Emu48.mak" CFG="Emu48 - Win32 Release" -!MESSAGE +!MESSAGE !MESSAGE Possible choices for configuration are: -!MESSAGE +!MESSAGE !MESSAGE "Emu48 - Win32 Release" (based on "Win32 (x86) Application") !MESSAGE "Emu48 - Win32 Debug" (based on "Win32 (x86) Application") !MESSAGE "Emu48 - Win32 Release Unicode" (based on "Win32 (x86) Application") !MESSAGE "Emu48 - Win32 Debug Unicode" (based on "Win32 (x86) Application") -!MESSAGE +!MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 @@ -137,7 +137,7 @@ 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 -!ENDIF +!ENDIF # Begin Target @@ -218,6 +218,10 @@ SOURCE=.\mops.c # End Source File # Begin Source File +SOURCE=.\mru.c +# End Source File +# Begin Source File + SOURCE=.\opcodes.c # End Source File # Begin Source File diff --git a/Sources/Emu48/EMU48.H b/Sources/Emu48/EMU48.H index 85cdf78..155bf87 100644 --- a/Sources/Emu48/EMU48.H +++ b/Sources/Emu48/EMU48.H @@ -114,11 +114,27 @@ extern VOID CopyItemsToClipboard(HWND hWnd); extern VOID UpdateWindowStatus(VOID); extern VOID ForceForegroundWindow(HWND hWnd); +// mru.c +extern BOOL MruInit(INT nNum); +extern VOID MruCleanup(VOID); +extern VOID MruAdd(LPCTSTR lpszEntry); +extern VOID MruRemove(INT nIndex); +extern INT MruEntries(VOID); +extern LPCTSTR MruFilename(INT nIndex); +extern VOID MruUpdateMenu(VOID); +extern VOID MruWriteList(VOID); +extern VOID MruReadList(VOID); + // Settings.c extern VOID ReadSettings(VOID); extern VOID WriteSettings(VOID); extern VOID ReadLastDocument(LPTSTR szFileName, DWORD nSize); extern VOID WriteLastDocument(LPCTSTR szFilename); +extern VOID ReadSettingsString(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpDefault, LPTSTR lpData, DWORD dwSize); +extern VOID WriteSettingsString(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPTSTR lpData); +extern INT ReadSettingsInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, INT nDefault); +extern VOID WriteSettingsInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, INT nValue); +extern VOID DelSettingsKey(LPCTSTR lpszSection, LPCTSTR lpszEntry); // Display.c extern BOOL bGrayscale; diff --git a/Sources/Emu48/EMU48.RC b/Sources/Emu48/EMU48.RC index c9c6317..2ffb370 100644 --- a/Sources/Emu48/EMU48.RC +++ b/Sources/Emu48/EMU48.RC @@ -553,8 +553,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,4,4,0 - PRODUCTVERSION 1,4,4,0 + FILEVERSION 1,4,5,0 + PRODUCTVERSION 1,4,5,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -571,12 +571,12 @@ BEGIN BEGIN VALUE "CompanyName", "Sebastien Carlier & Christoph Gießelink\0" VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0" - VALUE "FileVersion", "1, 4, 4, 0\0" + VALUE "FileVersion", "1, 4, 5, 0\0" VALUE "InternalName", "Emu48\0" VALUE "LegalCopyright", "Copyright © 2007\0" VALUE "OriginalFilename", "Emu48.exe\0" VALUE "ProductName", "Emu48\0" - VALUE "ProductVersion", "1, 4, 4, 0\0" + VALUE "ProductVersion", "1, 4, 5, 0\0" END END BLOCK "VarFileInfo" @@ -614,6 +614,8 @@ BEGIN MENUITEM SEPARATOR MENUITEM "S&ettings...", ID_VIEW_SETTINGS MENUITEM SEPARATOR + MENUITEM "Recent File List", ID_FILE_MRU_FILE1, GRAYED + MENUITEM SEPARATOR MENUITEM "E&xit", ID_FILE_EXIT END POPUP "&Edit" diff --git a/Sources/Emu48/MRU.C b/Sources/Emu48/MRU.C new file mode 100644 index 0000000..00316f8 --- /dev/null +++ b/Sources/Emu48/MRU.C @@ -0,0 +1,320 @@ +/* + * mru.c + * + * This file is part of Emu48 + * + * Copyright (C) 2007 Christoph Gießelink + * + */ +#include "pch.h" +#include "resource.h" +#include "Emu48.h" + +static TCHAR szOriginal[MAX_PATH] = _T(""); + +static LPTSTR *ppszFiles = NULL; // pointer to MRU table +static INT nEntry = 0; // no. of MRU entries + +static HMENU hMruMenu = NULL; // menu handle for MRU list +static INT nMruPos; // insert position for MRU list + +static BOOL GetMenuPosForId(HMENU hMenu, UINT nItem) +{ + HMENU hSubMenu; + UINT nID; + INT i,nMaxID; + + nMaxID = GetMenuItemCount(hMenu); + for (i = 0; i < nMaxID; ++i) + { + nID = GetMenuItemID(hMenu,i); // get ID + + if (nID == 0) continue; // separator or invalid command + + if (nID == (UINT)-1) // possibly a popup menu + { + hSubMenu = GetSubMenu(hMenu,i); // try to get handle to popup menu + if (hSubMenu != NULL) // it's a popup menu + { + // recursive search + if (GetMenuPosForId(hSubMenu,nItem)) + return TRUE; + } + continue; + } + + if (nID == nItem) // found ID + { + hMruMenu = hMenu; // remember menu and position + nMruPos = i; + return TRUE; + } + } + return FALSE; +} + +BOOL MruInit(INT nNum) +{ + HMENU hMenu = GetMenu(hWnd); // main menu + + _ASSERT(ppszFiles == NULL); // MRU already initialized + + if (*szOriginal == 0) // get orginal value of first MRU entry + { + VERIFY(GetMenuString(hMenu,ID_FILE_MRU_FILE1,szOriginal,ARRAYSIZEOF(szOriginal),MF_BYCOMMAND)); + } + + // no. of files in MRU list + nEntry = ReadSettingsInt(_T("MRU"),_T("FileCount"),nNum); + + // look for menu position of ID_FILE_MRU_FILE1 + VERIFY(GetMenuPosForId(hMenu,ID_FILE_MRU_FILE1)); + + if (nEntry > 0) // allocate MRU table + { + // create MRU table + if((ppszFiles = HeapAlloc(hHeap,0,nEntry * sizeof(*ppszFiles))) == NULL) + return TRUE; + + // fill each entry + for (nNum = 0; nNum < nEntry; ++nNum) + ppszFiles[nNum] = NULL; + + MruReadList(); // read actual MRU list + MruUpdateMenu(); // update menu + } + else // kill MRU menu entries + { + // delete MRU menu + DeleteMenu(hMruMenu,nMruPos,MF_BYPOSITION); + + // delete following separator + _ASSERT((GetMenuState(hMruMenu,nMruPos,MF_BYPOSITION) & MF_SEPARATOR) != 0); + DeleteMenu(hMruMenu,nMruPos,MF_BYPOSITION); + } + return FALSE; +} + +VOID MruCleanup(VOID) +{ + INT i; + + MruWriteList(); // write actual MRU list + + for (i = 0; i < nEntry; ++i) // cleanup each entry + { + if (ppszFiles[i] != NULL) + HeapFree(hHeap,0,ppszFiles[i]); // cleanup entry + } + + if (ppszFiles != NULL) // table defined + { + HeapFree(hHeap,0,ppszFiles); // free table + ppszFiles = NULL; + } + return; +} + +VOID MruAdd(LPCTSTR lpszEntry) +{ + TCHAR szFilename[MAX_PATH]; + LPTSTR lpFilePart; + INT i; + + if (nEntry == 0) return; // no entries + + // get full path name + GetFullPathName(lpszEntry,ARRAYSIZEOF(szFilename),szFilename,&lpFilePart); + + // look if entry is already in table + for (i = 0; i < nEntry; ++i) + { + // already in table -> quit + if ( ppszFiles[i] != NULL + && lstrcmpi(ppszFiles[i],szFilename) == 0) + { + MruUpdateMenu(); // update menu + return; + } + } + + i = nEntry - 1; // last index + if (ppszFiles[i] != NULL) + HeapFree(hHeap,0,ppszFiles[i]); // free oldest entry + + for (; i > 0; --i) // move old entries 1 line down + { + ppszFiles[i] = ppszFiles[i-1]; + } + + // add new entry to top + ppszFiles[0] = DuplicateString(szFilename); + + MruUpdateMenu(); // update menu + return; +} + +VOID MruRemove(INT nIndex) +{ + HeapFree(hHeap,0,ppszFiles[nIndex]); // free entry + + for (; nIndex < nEntry - 1; ++nIndex) // move old entries 1 line up + { + ppszFiles[nIndex] = ppszFiles[nIndex+1]; + } + + ppszFiles[nIndex] = NULL; // clear last line + + MruUpdateMenu(); // update menu + return; +} + +INT MruEntries(VOID) +{ + return nEntry; +} + +LPCTSTR MruFilename(INT nIndex) +{ + _ASSERT(ppszFiles != NULL); // MRU not initialized + _ASSERT(nIndex >= 0 && nIndex < nEntry); // inside range + return ppszFiles[nIndex]; +} + +VOID MruUpdateMenu(VOID) +{ + TCHAR szCurPath[MAX_PATH]; + HANDLE hMenu; + BOOL bEmpty; + INT i; + + if (nEntry == 0) return; // no entries + + _ASSERT(ppszFiles != NULL); // MRU not initialized + _ASSERT(hWnd != NULL); + VERIFY(hMenu = GetMenu(hWnd)); // main menu + + bEmpty = TRUE; // MRU list empty + for (i = 0; i < nEntry; ++i) // delete all menu entries + { + DeleteMenu(hMenu,ID_FILE_MRU_FILE1+i,MF_BYCOMMAND); + + if (ppszFiles[i] != NULL) // valid entry + bEmpty = FALSE; // MRU list not empty + } + + if (bEmpty) // empty MRU list + { + // fill with orginal string + VERIFY(InsertMenu(hMruMenu,nMruPos,MF_STRING|MF_BYPOSITION|MF_GRAYED,ID_FILE_MRU_FILE1,szOriginal)); + return; + } + + // current directory + GetCurrentDirectory(ARRAYSIZEOF(szCurPath),szCurPath); + + for (i = 0; i < nEntry; ++i) // add menu entries + { + if (ppszFiles[i] != NULL) // valid entry + { + TCHAR szMenuname[2*MAX_PATH+3]; + TCHAR szFilename[MAX_PATH]; + LPTSTR lpFilePart,lpszPtr; + + // check if file path and current path is identical + if (GetFullPathName(ppszFiles[i],ARRAYSIZEOF(szFilename),szFilename,&lpFilePart)) + { + TCHAR szCutname[MAX_PATH]; + + *(lpFilePart-1) = 0; // devide path and name + + // name is current directory -> use only name + if (lstrcmpi(szCurPath,szFilename) == 0) + { + // short name view + } + else + { + // full name view + lpFilePart = ppszFiles[i]; + } + + // cut filename to fit into menu + GetCutPathName(lpFilePart,szCutname,ARRAYSIZEOF(szCutname),36); + lpFilePart = szCutname; + + lpszPtr = szMenuname; // adding accelerator key + *lpszPtr++ = _T('&'); + *lpszPtr++ = _T('0') + ((i + 1) % 10); + *lpszPtr++ = _T(' '); + + // copy file to view buffer and expand & to && + while (*lpFilePart != 0) + { + if (*lpFilePart == _T('&')) + { + *lpszPtr++ = *lpFilePart; + } + *lpszPtr++ = *lpFilePart++; + } + *lpszPtr = 0; + + VERIFY(InsertMenu(hMruMenu,nMruPos+i,MF_STRING|MF_BYPOSITION,ID_FILE_MRU_FILE1+i,szMenuname)); + } + } + } + return; +} + +VOID MruWriteList(VOID) +{ + TCHAR szItemname[32]; + INT i; + + // no. of files in MRU list + WriteSettingsInt(_T("MRU"),_T("FileCount"),nEntry); + + for (i = 0; i < nEntry; ++i) // add menu entries + { + _ASSERT(ppszFiles != NULL); // MRU not initialized + wsprintf(szItemname,_T("File%d"),i+1); + if (ppszFiles[i] != NULL) + { + WriteSettingsString(_T("MRU"),szItemname,ppszFiles[i]); + } + else + { + DelSettingsKey(_T("MRU"),szItemname); + } + } + return; +} + +VOID MruReadList(VOID) +{ + TCHAR szFilename[MAX_PATH]; + TCHAR szItemname[32]; + LPTSTR lpszValue; + INT i; + + _ASSERT(ppszFiles != NULL); // MRU not initialized + + for (i = 0; i < nEntry; ++i) // add menu entries + { + wsprintf(szItemname,_T("File%d"),i+1); + ReadSettingsString(_T("MRU"),szItemname,_T(""),szFilename,ARRAYSIZEOF(szFilename)); + + if (ppszFiles[i] != NULL) // already filled + { + HeapFree(hHeap,0,ppszFiles[i]); // free entry + ppszFiles[i] = NULL; // clear last line + lpszValue = _T(""); + } + + if (*szFilename) // read a valid entry + { + ppszFiles[i] = DuplicateString(szFilename); + } + } + return; +} diff --git a/Sources/Emu48/RESOURCE.H b/Sources/Emu48/RESOURCE.H index 4d9155e..c40a2e2 100644 --- a/Sources/Emu48/RESOURCE.H +++ b/Sources/Emu48/RESOURCE.H @@ -214,6 +214,7 @@ #define ID_INFO_LASTINSTRUCTIONS 40064 #define ID_INFO_PROFILE 40065 #define ID_INFO_WRITEONLYREG 40066 +#define ID_FILE_MRU_FILE1 40100 // Next default values for new objects // diff --git a/Sources/Emu48/SETTINGS.C b/Sources/Emu48/SETTINGS.C index c505cfe..76d748a 100644 --- a/Sources/Emu48/SETTINGS.C +++ b/Sources/Emu48/SETTINGS.C @@ -30,6 +30,7 @@ #define ReadInt(sec,key,dv) GetPrivateProfileInt(sec,key,dv,_T(EMU48_INI)); #define WriteString(sec,key,v) WritePrivateProfileString(sec,key,v,_T(EMU48_INI)) #define WriteInt(sec,key,v) WritePrivateProfileInt(sec,key,v,_T(EMU48_INI)) +#define DelKey(sec,key) WritePrivateProfileString(sec,key,NULL,_T(EMU48_INI)) static BOOL WritePrivateProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, int nValue, LPCTSTR lpszFilename) { @@ -50,6 +51,7 @@ static BOOL WritePrivateProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, int n #define ReadInt(sec,key,dv) GetRegistryInt(sec,key,dv) #define WriteString(sec,key,v) WriteReg(sec,key,REG_SZ,(BYTE *) v,(lstrlen(v)+1) * sizeof(*v)) #define WriteInt(sec,key,v) WriteReg(sec,key,REG_DWORD,(BYTE *) &v,sizeof(int)) +#define DelKey(sec,key) DelReg(sec,key) static VOID ReadReg(LPCTSTR lpSubKey, LPCTSTR lpValueName, LPBYTE lpData, DWORD *pdwSize) { @@ -99,7 +101,29 @@ static VOID WriteReg(LPCTSTR lpSubKey, LPCTSTR lpValueName, DWORD dwType, CONST RegSetValueEx(hKey,lpValueName,0,dwType,lpData,cbData); RegCloseKey(hKey); return; -} +} + +static VOID DelReg(LPCTSTR lpSubKey, LPCTSTR lpValueName) +{ + TCHAR lpKey[256] = _T(REGISTRYKEY) _T("\\"); + + DWORD retCode; + HKEY hKey; + + lstrcat(lpKey, lpSubKey); // full registry key + + retCode = RegOpenKeyEx(HKEY_CURRENT_USER, + lpKey, + 0, + KEY_SET_VALUE, + &hKey); + if (retCode == ERROR_SUCCESS) + { + retCode = RegDeleteValue(hKey,lpValueName); + RegCloseKey(hKey); + } + return; +} static DWORD GetRegistryString(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpDefault, LPTSTR lpData, DWORD dwSize) { @@ -220,3 +244,32 @@ VOID WriteLastDocument(LPCTSTR szFilename) WriteString(_T("Files"),_T("LastDocument"),szFilename); return; } + +VOID ReadSettingsString(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpDefault, LPTSTR lpData, DWORD dwSize) +{ + ReadString(lpszSection,lpszEntry,lpDefault,lpData,dwSize); + return; +} + +VOID WriteSettingsString(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPTSTR lpData) +{ + WriteString(lpszSection,lpszEntry,lpData); + return; +} + +INT ReadSettingsInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, INT nDefault) +{ + return ReadInt(lpszSection,lpszEntry,nDefault); +} + +VOID WriteSettingsInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, INT nValue) +{ + WriteInt(lpszSection,lpszEntry,nValue); + return; +} + +VOID DelSettingsKey(LPCTSTR lpszSection, LPCTSTR lpszEntry) +{ + DelKey(lpszSection,lpszEntry); + return; +} diff --git a/Sources/Emu48/TIMER.C b/Sources/Emu48/TIMER.C index d71cea9..b784928 100644 --- a/Sources/Emu48/TIMER.C +++ b/Sources/Emu48/TIMER.C @@ -209,7 +209,7 @@ static VOID AbortT2(VOID) static void CALLBACK TimeProc(UINT uEventId, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) { - _ASSERT(uEventId); // illegal EventId + if (uEventId == 0) return; // illegal EventId if (uEventId == uT1TimerId) // called from timer1 event (default period 16 Hz) { diff --git a/Sources/GCCPatch/EMU48GCC.RC b/Sources/GCCPatch/EMU48GCC.RC index c3c5254..12dac7c 100644 --- a/Sources/GCCPatch/EMU48GCC.RC +++ b/Sources/GCCPatch/EMU48GCC.RC @@ -581,8 +581,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,4,4,0 - PRODUCTVERSION 1,4,4,0 + FILEVERSION 1,4,5,0 + PRODUCTVERSION 1,4,5,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -599,12 +599,12 @@ BEGIN BEGIN VALUE "CompanyName", "Sebastien Carlier & Christoph Gießelink\0" VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0" - VALUE "FileVersion", "1, 4, 4, 0\0" + VALUE "FileVersion", "1, 4, 5, 0\0" VALUE "InternalName", "Emu48\0" VALUE "LegalCopyright", "Copyright © 2007\0" VALUE "OriginalFilename", "Emu48.exe\0" VALUE "ProductName", "Emu48\0" - VALUE "ProductVersion", "1, 4, 4, 0\0" + VALUE "ProductVersion", "1, 4, 5, 0\0" END END BLOCK "VarFileInfo" @@ -642,6 +642,8 @@ BEGIN MENUITEM SEPARATOR MENUITEM "S&ettings...", ID_VIEW_SETTINGS MENUITEM SEPARATOR + MENUITEM "Recent File List", ID_FILE_MRU_FILE1, GRAYED + MENUITEM SEPARATOR MENUITEM "E&xit", ID_FILE_EXIT END POPUP "&Edit" diff --git a/Sources/GCCPatch/Makefile b/Sources/GCCPatch/Makefile index 908aa2d..09a8e2f 100644 --- a/Sources/GCCPatch/Makefile +++ b/Sources/GCCPatch/Makefile @@ -23,8 +23,8 @@ RSRCOBJ=$(PRJ).o OBJS=cursor.o disasm.o display.o debugger.o ddeserv.o \ emu48.o engine.o external.o fetch.o files.o i28f160.o keyboard.o \ - keymacro.o kml.o lowbat.o mops.o opcodes.o rpl.o serial.o settings.o \ - stack.o timer.o \ + keymacro.o kml.o lowbat.o mru.o mops.o opcodes.o rpl.o serial.o \ + settings.o stack.o timer.o \ $(RSRCOBJ) LIBS=-lwinmm -lcomctl32 @@ -61,7 +61,7 @@ display.o: display.c pch.h resource.h emu48.h \ types.h io.h kml.h $(CC) $(CFLAGS) $(DEFINES) -c -o display.o display.c -emu48.o: emu48.c pch.h resource.h emu48.h types.h \ +emu48.o: emu48.c pch.h resource.h emu48.h types.h \ io.h kml.h debugger.h $(CC) $(CFLAGS) $(DEFINES) -c -o emu48.o emu48.c @@ -98,6 +98,9 @@ mops.o: mops.c pch.h emu48.h types.h opcodes.h io.h \ i28f160.h $(CC) $(CFLAGS) $(DEFINES) -c -o mops.o mops.c +mru.o: mru.c pch.h resource.h emu48.h + $(CC) $(CFLAGS) $(DEFINES) -c -o mru.o mru.c + opcodes.o: opcodes.c pch.h emu48.h types.h opcodes.h \ io.h ops.h $(CC) $(CFLAGS) $(DEFINES) -c -o opcodes.o opcodes.c diff --git a/Sources/GCCPatch/README.TXT b/Sources/GCCPatch/README.TXT index 6b68aa0..2a48121 100644 --- a/Sources/GCCPatch/README.TXT +++ b/Sources/GCCPatch/README.TXT @@ -41,4 +41,4 @@ Many thanks to Pedro A. Arranda Guti compatible. -04/12/07 (c) by Christoph Gießelink +08/07/07 (c) by Christoph Gießelink diff --git a/uninst.exe b/uninst.exe index 0bae7a5..8bd2780 100755 Binary files a/uninst.exe and b/uninst.exe differ