/* * Emu48.c * * This file is part of Emu48 * * Copyright (C) 1995 Sebastien Carlier * */ #include "pch.h" #include "resource.h" #include "Emu48.h" #include "kml.h" #define VERSION "1.10" // 05.02.99 cg, version changed #define EMU48_INI "Emu48.ini" #define CF_HPOBJ "CF_HPOBJ" // 13.05.98 cg, clipboard format for DDE #define MAXPORTS 16 // 20.05.98 cg, number of COM ports // 30.05.98 cg, new, cards status #define PORT1_PRESENT ((cCurrentRomType=='S')?0x1:0x2) #define PORT1_WRITE ((cCurrentRomType=='S')?0x4:0x8) #define PORT2_PRESENT ((cCurrentRomType=='S')?0x2:0x1) #define PORT2_WRITE ((cCurrentRomType=='S')?0x8:0x4) // #define MONOCHROME // 27.01.99 cg, CF_BITMAP clipboard format #ifdef _DEBUG LPSTR szNoTitle = "Emu48 "VERSION" Debug"; #else LPSTR szNoTitle = "Emu48 "VERSION; // 20.01.98 cg, changed #endif LPSTR szAppName = "Emu48"; // 13.05.98 cg, new, application name for DDE server LPSTR szTopic = "Stack"; // 13.05.98 cg, new, topic for DDE server LPSTR szTitle = NULL; static const char szLicence[] = "This program is free software; you can redistribute it and/or modify\r\n" "it under the terms of the GNU General Public License as published by\r\n" "the Free Software Foundation; either version 2 of the License, or\r\n" "(at your option) any later version.\r\n" "\r\n" "This program is distributed in the hope that it will be useful,\r\n" "but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n" "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\r\n" "See the GNU General Public License for more details.\r\n" "\r\n" "You should have received a copy of the GNU General Public License\r\n" "along with this program; if not, write to the Free Software\r\n" "Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA."; CRITICAL_SECTION csGDILock; // 22.01.98 cg, critical section for hWindowDC CRITICAL_SECTION csKeyLock; // 02.09.98 cg, critical section for key scan CRITICAL_SECTION csIOLock; // 24.02.99 cg, new, critical section for I/O access CRITICAL_SECTION csT1Lock; // 21.04.98 cg, new, critical section for timer1 access CRITICAL_SECTION csT2Lock; // 21.04.98 cg, new, critical section for timer2 access LARGE_INTEGER lFreq; // 24.08.98 cg, new, counter frequency DWORD idDdeInst; // 13.05.98 cg, DDE server id UINT uCF_HpObj; // 13.05.98 cg, DDE clipboard format HINSTANCE hApp = NULL; HWND hWnd = NULL; HDC hWindowDC = NULL; HPALETTE hPalette = NULL; HPALETTE hOldPalette = NULL; // 11.09.98 cg, new, old palette of hWindowDC HANDLE hThread; DWORD lThreadId; BOOL bAutoSave = FALSE; BOOL bAutoSaveOnExit = TRUE; BOOL bAlwaysDisplayLog = TRUE; static BOOL bRealSpeed = FALSE; //################ //# //# Window Status //# //################ VOID SetWindowTitle(LPSTR szString) { if (szTitle) { LocalFree(szTitle); } if (szString) { szTitle = DuplicateString(szString); } else { szTitle = NULL; } if (szTitle) { SetWindowText(hWnd, szTitle); } else { SetWindowText(hWnd, szNoTitle); } return; } VOID UpdateWindowStatus() { HMENU hMenu; if (hWnd == NULL) return; // 30.01.98 cg, bugfix, return if window closed hMenu = GetMenu(hWnd); if ((nState == 0)||(nState == 3)) { if (szCurrentFilename[0]) EnableMenuItem(hMenu,ID_FILE_SAVE,MF_ENABLED); else EnableMenuItem(hMenu,ID_FILE_SAVE,MF_GRAYED); EnableMenuItem(hMenu,ID_FILE_SAVEAS,MF_ENABLED); EnableMenuItem(hMenu,ID_FILE_CLOSE,MF_ENABLED); EnableMenuItem(hMenu,ID_BACKUP_SAVE,MF_GRAYED); EnableMenuItem(hMenu,ID_BACKUP_SAVE,MF_ENABLED); EnableMenuItem(hMenu,ID_VIEW_COPY,MF_ENABLED); EnableMenuItem(hMenu,ID_VIEW_RESET,MF_ENABLED); EnableMenuItem(hMenu,ID_OBJECT_LOAD,MF_ENABLED); EnableMenuItem(hMenu,ID_OBJECT_SAVE,MF_ENABLED); // 17.06.98 cg, new, enable menu entries EnableMenuItem(hMenu,ID_STACK_COPY,MF_ENABLED); EnableMenuItem(hMenu,ID_STACK_PASTE,MF_ENABLED); // 10.11.98 cg, new, enable menu entries EnableMenuItem(hMenu,ID_TOOL_DISASM,MF_ENABLED); } else { EnableMenuItem(hMenu,ID_FILE_SAVE,MF_GRAYED); EnableMenuItem(hMenu,ID_FILE_SAVEAS,MF_GRAYED); EnableMenuItem(hMenu,ID_FILE_CLOSE,MF_ENABLED); EnableMenuItem(hMenu,ID_BACKUP_SAVE,MF_GRAYED); EnableMenuItem(hMenu,ID_VIEW_COPY,MF_GRAYED); EnableMenuItem(hMenu,ID_VIEW_RESET,MF_GRAYED); EnableMenuItem(hMenu,ID_OBJECT_LOAD,MF_GRAYED); EnableMenuItem(hMenu,ID_OBJECT_SAVE,MF_GRAYED); // 17.06.98 cg, new, disable menu entries EnableMenuItem(hMenu,ID_STACK_COPY,MF_GRAYED); EnableMenuItem(hMenu,ID_STACK_PASTE,MF_GRAYED); // 10.11.98 cg, new, enable menu entries EnableMenuItem(hMenu,ID_TOOL_DISASM,MF_GRAYED); } if (bBackup) { EnableMenuItem(hMenu,ID_BACKUP_RESTORE,MF_ENABLED); EnableMenuItem(hMenu,ID_BACKUP_DELETE,MF_ENABLED); } else { EnableMenuItem(hMenu,ID_BACKUP_RESTORE,MF_GRAYED); EnableMenuItem(hMenu,ID_BACKUP_DELETE,MF_GRAYED); } return; } //################ //# //# Settings //# //################ static BOOL WritePrivateProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, int nValue, LPCTSTR lpszFilename) { char s[16]; wsprintf(s,"%i",nValue); return WritePrivateProfileString(lpszSection, lpszEntry, s, lpszFilename); } // 20.05.98 cg, new, set listfield for serial combobox static VOID SetCommList(HWND hDlg,int nIDDlgItem,char *szSetting) { HANDLE hComm; BOOL bAdd; WORD wCount, wIndex = 1; char szBuffer[16]; WPARAM wSelect = 0; // set select to disabled SendDlgItemMessage(hDlg,nIDDlgItem,CB_ADDSTRING,0,(LPARAM) NO_SERIAL); for (wCount = 1;wCount <= MAXPORTS;++wCount) { wsprintf(szBuffer,"COM%u",wCount); if (bAdd = (strcmp(szBuffer,szSetting) == 0)) wSelect = wIndex; // test if COM port is valid hComm = CreateFile(szBuffer,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL); if(hComm != INVALID_HANDLE_VALUE) { BOOL bError = CloseHandle(hComm); _ASSERT(bError); bAdd = TRUE; } if (bAdd) // add item to combobox { SendDlgItemMessage(hDlg,nIDDlgItem,CB_ADDSTRING,0,(LPARAM) szBuffer); ++wIndex; } } SendDlgItemMessage(hDlg,nIDDlgItem,CB_SETCURSEL,wSelect,0L); } static VOID ReadSettings() { // Files // 01.02.98 cg, calculate size of buffer GetPrivateProfileString("Files","Emu48Directory",szCurrentDirectory,szEmu48Directory, sizeof(szEmu48Directory),EMU48_INI); bAutoSave = GetPrivateProfileInt("Files","AutoSave",bAutoSave,EMU48_INI); bAutoSaveOnExit = GetPrivateProfileInt("Files","AutoSaveOnExit",bAutoSaveOnExit,EMU48_INI); // Port2 bPort2IsShared = GetPrivateProfileInt("Port2","IsShared",0,EMU48_INI); // 01.02.98 cg, calculate size of buffer GetPrivateProfileString("Port2","Filename","SHARED.BIN",szPort2Filename,sizeof(szPort2Filename),EMU48_INI); // Timers // 13.06.98 cg, changed default value from unset to set // 10.11.98 cg, removed, not adjustable any more // bAccurateTimer = GetPrivateProfileInt("Timers","AccurateTimer",1,EMU48_INI); // uT1Period = GetPrivateProfileInt("Timers","T1Period",62,EMU48_INI); // KML bAlwaysDisplayLog = GetPrivateProfileInt("KML","AlwaysDisplayLog",bAlwaysDisplayLog,EMU48_INI); // 23.04.98 cg, new, Emulator bRealSpeed = GetPrivateProfileInt("Emulator","RealSpeed",0,EMU48_INI); dwSXCycles = GetPrivateProfileInt("Emulator","SXCycles",82,EMU48_INI); dwGXCycles = GetPrivateProfileInt("Emulator","GXCycles",123,EMU48_INI); SetSpeed(bRealSpeed); // 23.04.98 cg, set speed // 20.05.98 cg, new, Serial GetPrivateProfileString("Serial","Wire",NO_SERIAL,szSerialWire,sizeof(szSerialWire),EMU48_INI); GetPrivateProfileString("Serial","Ir",NO_SERIAL,szSerialIr,sizeof(szSerialIr),EMU48_INI); return; } static VOID WriteSettings() { // Files WritePrivateProfileString("Files","Emu48Directory",szEmu48Directory,EMU48_INI); WritePrivateProfileInt("Files","AutoSave",bAutoSave,EMU48_INI); WritePrivateProfileInt("Files","AutoSaveOnExit",bAutoSaveOnExit,EMU48_INI); // Port2 WritePrivateProfileInt("Port2","IsShared",bPort2IsShared,EMU48_INI); WritePrivateProfileString("Port2","Filename",szPort2Filename,EMU48_INI); // Timers // 10.11.98 cg, removed, not adjustable any more // WritePrivateProfileInt("Timers","AccurateTimer",bAccurateTimer,EMU48_INI); // WritePrivateProfileInt("Timers","T1Period",uT1Period,EMU48_INI); // KML WritePrivateProfileInt("KML","AlwaysDisplayLog",bAlwaysDisplayLog,EMU48_INI); // 23.04.98 cg, new, Emulator WritePrivateProfileInt("Emulator","RealSpeed",bRealSpeed,EMU48_INI); WritePrivateProfileInt("Emulator","SXCycles",dwSXCycles,EMU48_INI); WritePrivateProfileInt("Emulator","GXCycles",dwGXCycles,EMU48_INI); // 20.05.98 cg, new, Serial WritePrivateProfileString("Serial","Wire",szSerialWire,EMU48_INI); WritePrivateProfileString("Serial","Ir",szSerialIr,EMU48_INI); return; } static BOOL CALLBACK SettingsProc(HWND hDlg, UINT message, DWORD wParam, LONG lParam) { switch (message) { case WM_INITDIALOG: // 30.05.98 cg, new, init port1 enable checkbox CheckDlgButton(hDlg,IDC_PORT1EN,(Chipset.cards_status & PORT1_PRESENT) != 0); CheckDlgButton(hDlg,IDC_PORT1WR,Chipset.Port1_Writeable); // 23.04.98 cg, new, init speed checkbox CheckDlgButton(hDlg,IDC_REALSPEED,bRealSpeed); CheckDlgButton(hDlg,IDC_AUTOSAVE,bAutoSave); CheckDlgButton(hDlg,IDC_AUTOSAVEONEXIT,bAutoSaveOnExit); CheckDlgButton(hDlg,IDC_ALWAYSDISPLOG,bAlwaysDisplayLog); CheckDlgButton(hDlg,IDC_PORT2ISSHARED,bPort2IsShared); SetDlgItemText(hDlg,IDC_PORT2,szPort2Filename); // 10.11.98 cg, removed, not adjustable any more // SetDlgItemInt(hDlg,IDC_T1PERIOD,uT1Period,FALSE); // 20.05.98 cg, new, set combobox parameter SetCommList(hDlg,IDC_WIRE,szSerialWire); SetCommList(hDlg,IDC_IR,szSerialIr); // 10.11.98 cg, removed, not adjustable any more // CheckDlgButton(hDlg,IDC_USEMMTIMER,bAccurateTimer); if (nState == 1) { // 30.05.98 cg, new, disable port1 enable box EnableWindow(GetDlgItem(hDlg,IDC_PORT1EN),FALSE); EnableWindow(GetDlgItem(hDlg,IDC_PORT1WR),FALSE); } else { EnableWindow(GetDlgItem(hDlg,IDC_PORT2ISSHARED),FALSE); EnableWindow(GetDlgItem(hDlg,IDC_PORT2),FALSE); } if (CommConnect() != PORT_CLOSE) // 20.05.98 cg, new, disable when port open { EnableWindow(GetDlgItem(hDlg,IDC_WIRE),FALSE); EnableWindow(GetDlgItem(hDlg,IDC_IR),FALSE); } return TRUE; case WM_COMMAND: if (wParam == IDOK) { // BOOL bTranslated; // UINT uNewT1Period; if (Chipset.Port1Size) { UINT nOldState = SwitchToState(3); Chipset.Port1_Writeable = IsDlgButtonChecked(hDlg, IDC_PORT1WR); // 30.05.98 cg, changed, added code for port1 disable Chipset.cards_status = 0; if (IsDlgButtonChecked(hDlg, IDC_PORT1EN)) { Chipset.cards_status |= PORT1_PRESENT; if (Chipset.Port1_Writeable) Chipset.cards_status |= PORT1_WRITE; } if (Chipset.inte) { Chipset.Shutdn = FALSE; Chipset.SoftInt = TRUE; bInterrupt = TRUE; } Map(0x00,0xFF); SwitchToState(nOldState); } // 23.04.98 cg, new, get speed checkbox value bRealSpeed = IsDlgButtonChecked(hDlg,IDC_REALSPEED); bAutoSave = IsDlgButtonChecked(hDlg, IDC_AUTOSAVE); bAutoSaveOnExit = IsDlgButtonChecked(hDlg, IDC_AUTOSAVEONEXIT); bAlwaysDisplayLog = IsDlgButtonChecked(hDlg, IDC_ALWAYSDISPLOG); SetSpeed(bRealSpeed); // 23.04.98 cg, set speed if (nState == 1) { bPort2IsShared = IsDlgButtonChecked(hDlg,IDC_PORT2ISSHARED); // 01.02.98 cg, calculate size of buffer GetDlgItemText(hDlg,IDC_PORT2,szPort2Filename,sizeof(szPort2Filename)); } // 10.11.98 cg, removed, not adjustable any more // bAccurateTimer = IsDlgButtonChecked(hDlg,IDC_USEMMTIMER); // uNewT1Period = GetDlgItemInt(hDlg, IDC_T1PERIOD, &bTranslated, FALSE); // if (bTranslated) // uT1Period = uNewT1Period; // else // uT1Period = 62; // 20.05.98 cg, new, set combobox parameter // 26.08.98 cg, changed implementation GetDlgItemText(hDlg,IDC_WIRE,szSerialWire,sizeof(szSerialWire)); GetDlgItemText(hDlg,IDC_IR ,szSerialIr ,sizeof(szSerialIr)); EndDialog(hDlg, wParam); } if (wParam == IDCANCEL) { EndDialog(hDlg, wParam); } // 10.11.98 cg, removed, not adjustable any more // if (wParam == IDC_T1DEFAULT) // { // SetDlgItemInt(hDlg,IDC_T1PERIOD,62,FALSE); // } break; } return FALSE; UNREFERENCED_PARAMETER(lParam); UNREFERENCED_PARAMETER(hDlg); } //################ //# //# Save Helper //# //################ // // UINT SaveChanges(BOOL bAuto); // Return code : // IDYES File successfuly saved // IDNO File not saved // IDCANCEL Cancel command // static UINT SaveChanges(BOOL bAuto) { UINT uReply; if (pbyRom == NULL) return IDNO; if (bAuto) uReply = IDYES; else uReply = YesNoCancelMessage("Do you want to save changes ?"); if (uReply != IDYES) return uReply; if (szCurrentFilename[0]==0) { // Save As... uReply = GetSaveAsFilename(); if (uReply != IDOK) return uReply; if (!SaveDocumentAs(szBufferFilename)) return IDCANCEL; WritePrivateProfileString("Files","LastDocument",szCurrentFilename,EMU48_INI); return IDYES; } SaveDocument(); return IDYES; } //################ //# //# Message Handlers //# //################ // // WM_CREATE // static LRESULT OnCreate(HWND hWindow) { hWnd = hWindow; hWindowDC = GetDC(hWnd); DragAcceptFiles(hWnd,TRUE); // 05.02.99 cg & Will Laughlin, moved, support dropped files return 0; } // // WM_DESTROY // static LRESULT OnDestroy(HWND hWindow) { DragAcceptFiles(hWnd,FALSE); // 05.02.99 cg & Will Laughlin, no WM_DROPFILES message any more SwitchToState(2); WriteSettings(); ReleaseDC(hWnd, hWindowDC); SetWindowTitle(NULL); // 27.01.98 cg, bugfix, free memory of title hWindowDC = NULL; // 11.09.98 cg, hWindowDC isn't valid any more hWnd = NULL; PostQuitMessage(0); return 0; UNREFERENCED_PARAMETER(hWindow); } // // WM_PAINT // static LRESULT OnPaint(HWND hWindow) { PAINTSTRUCT Paint; HDC hPaintDC; hPaintDC = BeginPaint(hWindow, &Paint); if (hMainDC != NULL) // 30.01.98 cg, bugfix, EndPaint() was not called { BitBlt(hPaintDC, 0, 0, nBackgroundW, nBackgroundH, hMainDC, nBackgroundX, nBackgroundY, SRCCOPY); if ((nState==0)||(nState==3)) { UpdateMainDisplay(); UpdateMenuDisplay(); UpdateAnnunciators(); // 21.07.98 cg, bugfix, redraw annunciators RefreshButtons(); } } EndPaint(hWindow, &Paint); return 0; } // // WM_DROPFILES // // 01.11.98 cg & Will Laughlin, new, support dropped files static LRESULT OnDropFiles(HANDLE hFilesInfo) { char szFileName[MAX_PATH]; WORD wNumFiles,wIndex; BOOL bSuccess; // get number of files dropped wNumFiles = DragQueryFile (hFilesInfo,(UINT)-1,NULL,0); if (!Chipset.dispon) // calculator off, turn on { // turn on HP KeyboardEvent(TRUE,0,0x8000); Sleep(200); KeyboardEvent(FALSE,0,0x8000); } _ASSERT(nState == 0); // Emulator must be in RUN state if (WaitForSleepState()) // wait for cpu SHUTDN then sleep state { DragFinish (hFilesInfo); InfoMessage("The emulator is busy."); return 0; } while (nState!=nNextState) Sleep(0); _ASSERT(nState==3); // get each name and load it into the emulator for (wIndex = 0;wIndex < wNumFiles;++wIndex) { DragQueryFile (hFilesInfo,wIndex,(LPSTR) szFileName,sizeof(szFileName)); // szFileName has file name, now try loading it if ((bSuccess = LoadObject(szFileName)) == FALSE) break; } DragFinish (hFilesInfo); SwitchToState(0); // run state while (nState!=nNextState) Sleep(0); _ASSERT(nState==0); if (bSuccess == FALSE) // data not copied return 0; KeyboardEvent(TRUE,0,0x8000); Sleep(200); KeyboardEvent(FALSE,0,0x8000); // wait for sleep mode while(Chipset.Shutdn == FALSE) Sleep(0); return 0; } // // ID_FILE_NEW // static LRESULT OnFileNew() { UINT uReply; SaveBackup(); if (pbyRom) { SwitchToState(1); uReply = SaveChanges(bAutoSave); if (uReply==IDCANCEL) goto cancel; } NewDocument(); SetWindowTitle("Untitled"); UpdateWindowStatus(); cancel: if (pbyRom) SwitchToState(0); return 0; } // // ID_FILE_OPEN // static LRESULT OnFileOpen() { UINT uReply; if (pbyRom) { SwitchToState(1); uReply = SaveChanges(bAutoSave); if (uReply==IDCANCEL) goto cancel; } if (GetOpenFilename()) { OpenDocument(szBufferFilename); } cancel: if (pbyRom) { SwitchToState(0); } return 0; } // // ID_FILE_SAVE // static LRESULT OnFileSave() { if (pbyRom == NULL) return 0; SwitchToState(1); SaveChanges(TRUE); SwitchToState(0); return 0; } // // ID_FILE_SAVEAS // static LRESULT OnFileSaveAs() { UINT uReply; if (pbyRom == NULL) return 0; SwitchToState(1); uReply = GetSaveAsFilename(); if (uReply != IDOK) { SwitchToState(0); return 0; } if (!SaveDocumentAs(szBufferFilename)) { SwitchToState(0); return 0; } WritePrivateProfileString("Files","LastDocument",szCurrentFilename,EMU48_INI); SwitchToState(0); return 0; } // // ID_FILE_CLOSE // static LRESULT OnFileClose() { if (pbyRom == NULL) return 0; SwitchToState(1); if (SaveChanges(bAutoSave)!=IDCANCEL) { KillKML(); ResetDocument(); SetWindowTitle(NULL); } else { SwitchToState(0); } return 0; } // // ID_FILE_EXIT // static LRESULT OnFileExit() { SwitchToState(2); // 21.02.99 cg, bugfix, hold emulation thread first if (SaveChanges(bAutoSaveOnExit) == IDCANCEL) { return 0; } DestroyWindow(hWnd); return 0; } // // WM_SYS_CLOSE // static LRESULT OnSysClose() { SwitchToState(2); // 21.02.99 cg, bugfix, hold emulation thread first if (SaveChanges(bAutoSaveOnExit) == IDCANCEL) { return 0; } DestroyWindow(hWnd); return 0; } // // ID_STACK_COPY // static LRESULT OnStackCopy() // 17.06.98 cg, new, copy data from stack { HANDLE hClipObj; LPBYTE lpData; DWORD dwAddress,dwSize; _ASSERT(nState == 0); // Emulator must be in RUN state if (WaitForSleepState()) // wait for cpu SHUTDN then sleep state { InfoMessage("The emulator is busy."); return 0; } while (nState!=nNextState) Sleep(0); _ASSERT(nState==3); if ((dwAddress = RPL_Pick(1)) == 0) // pick address of level1 object { MessageBeep(MB_OK); // error beep goto error; } if (Read5(dwAddress) != 0x02A2C) // string object { MessageBeep(MB_OK); // error beep goto error; } dwAddress += 5; // address of string length dwSize = (Read5(dwAddress) - 5) / 2; // length of string // memory allocation for clipboard data if ((hClipObj = GlobalAlloc(GMEM_MOVEABLE,dwSize + 1)) == NULL) goto error; if (lpData = GlobalLock(hClipObj)) // lock memory { // copy data into clipboard buffer for (dwAddress += 5;dwSize-- > 0;dwAddress += 2,++lpData) *lpData = Read2(dwAddress); *lpData = 0; // set end of string GlobalUnlock(hClipObj); // unlock memory if (OpenClipboard(hWnd)) { if (EmptyClipboard()) SetClipboardData(CF_TEXT,hClipObj); else GlobalFree(hClipObj); CloseClipboard(); } } else // lock memory failed { GlobalFree(hClipObj); } error: SwitchToState(0); return 0; } // // ID_STACK_PASTE // static LRESULT OnStackPaste() // 17.06.98 cg, new, paste data to stack { HANDLE hClipObj; LPBYTE lpClipdata,lpData; BOOL bSuccess = FALSE; // 10.11.98 cg, bugfix, moved from bottom of function if (!Chipset.dispon) // calculator off, turn on { KeyboardEvent(TRUE,0,0x8000); Sleep(200); KeyboardEvent(FALSE,0,0x8000); // wait for sleep mode while(Chipset.Shutdn == FALSE) Sleep(0); } _ASSERT(nState == 0); // Emulator must be in RUN state if (WaitForSleepState()) // wait for cpu SHUTDN then sleep state { InfoMessage("The emulator is busy."); return 0; } while (nState!=nNextState) Sleep(0); _ASSERT(nState==3); if (OpenClipboard(hWnd)) { if ( IsClipboardFormatAvailable(CF_TEXT) || IsClipboardFormatAvailable(CF_OEMTEXT)) { if (hClipObj = GetClipboardData(CF_TEXT)) { if (lpClipdata = GlobalLock(hClipObj)) { DWORD dwSize = strlen(lpClipdata); if (lpData = (LPBYTE) LocalAlloc(LMEM_FIXED,dwSize * 2)) { memcpy(lpData+dwSize,lpClipdata,dwSize); // copy data bSuccess = (WriteStack(lpData,dwSize) == S_ERR_NO); LocalFree(lpData); } GlobalUnlock(hClipObj); } } } else // unknown clipboard format { MessageBeep(MB_OK); // error beep } CloseClipboard(); } SwitchToState(0); // run state while (nState!=nNextState) Sleep(0); _ASSERT(nState == 0); if (bSuccess == FALSE) // data not copied return 0; KeyboardEvent(TRUE,0,0x8000); Sleep(200); KeyboardEvent(FALSE,0,0x8000); // wait for sleep mode while(Chipset.Shutdn == FALSE) Sleep(0); return 0; } // // ID_VIEW_COPY // static LRESULT OnViewCopy() { // 22.09.98 cg, bugfix, always close clipboard if (OpenClipboard(hWnd)) { if (EmptyClipboard()) { #if !defined MONOCHROME // 27.01.99 cg, changed implementation for DIB bitmap #define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4) #define PALVERSION 0x300 BITMAP bm; LPBITMAPINFOHEADER lpbi; PLOGPALETTE ppal; HBITMAP hBmp; HDC hBmpDC; HANDLE hClipObj; WORD wBits; DWORD dwLen, dwSizeImage; _ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4); hBmp = CreateCompatibleBitmap(hLcdDC,131*nLcdDoubled,64*nLcdDoubled); hBmpDC = CreateCompatibleDC(hLcdDC); hBmp = SelectObject(hBmpDC,hBmp); BitBlt(hBmpDC, 0, 0, 131*nLcdDoubled, 64*nLcdDoubled, hLcdDC, 0, 0, SRCCOPY); hBmp = SelectObject(hBmpDC,hBmp); // fill BITMAP structure for size information GetObject(hBmp, sizeof(bm), &bm); wBits = bm.bmPlanes * bm.bmBitsPixel; // make sure bits per pixel is valid if (wBits <= 1) wBits = 1; else if (wBits <= 4) wBits = 4; else if (wBits <= 8) wBits = 8; else // if greater than 8-bit, force to 24-bit wBits = 24; dwSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * wBits) * bm.bmHeight; // calculate memory size to store CF_DIB data dwLen = sizeof(BITMAPINFOHEADER) + dwSizeImage; if (wBits != 24) // a 24 bitcount DIB has no color table { // add size for color table dwLen += (1 << wBits) * sizeof(RGBQUAD); } // memory allocation for clipboard data if ((hClipObj = GlobalAlloc(GMEM_MOVEABLE, dwLen)) != NULL) { lpbi = GlobalLock(hClipObj); // initialize BITMAPINFOHEADER lpbi->biSize = sizeof(BITMAPINFOHEADER); lpbi->biWidth = bm.bmWidth; lpbi->biHeight = bm.bmHeight; lpbi->biPlanes = 1; lpbi->biBitCount = wBits; lpbi->biCompression = BI_RGB; lpbi->biSizeImage = dwSizeImage; lpbi->biXPelsPerMeter = 0; lpbi->biYPelsPerMeter = 0; lpbi->biClrUsed = 0; 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); GlobalUnlock(hClipObj); SetClipboardData(CF_DIB, hClipObj); // get number of entries in the logical palette GetObject(hPalette,sizeof(WORD),&wBits); // memory allocation for temporary palette data if ((ppal = LocalAlloc(LPTR, sizeof(LOGPALETTE) + wBits * sizeof(PALETTEENTRY))) != NULL) { ppal->palVersion = PALVERSION; ppal->palNumEntries = wBits; GetPaletteEntries(hPalette, 0, wBits, ppal->palPalEntry); SetClipboardData(CF_PALETTE, CreatePalette(ppal)); LocalFree(ppal); } } DeleteDC(hBmpDC); DeleteObject(hBmp); #undef WIDTHBYTES #undef PALVERSION // 27.01.99 cg, end of changed implementation #else HBITMAP hOldBmp, hBmp; HDC hBmpDC; // 24.08.98 cg, changed implementation _ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4); hBmp = CreateBitmap(131*nLcdDoubled,64*nLcdDoubled,1,1,NULL); hBmpDC = CreateCompatibleDC(NULL); hOldBmp = (HBITMAP)SelectObject(hBmpDC,hBmp); BitBlt(hBmpDC, 0, 0, 131*nLcdDoubled, 64*nLcdDoubled, hLcdDC, 0, 0, SRCCOPY); // 24.08.98 cg, end of changed implementation SetClipboardData(CF_BITMAP,hBmp); SelectObject(hBmpDC,hOldBmp); DeleteDC(hBmpDC); #endif } CloseClipboard(); } // 22.09.98 cg, end of bugfix return 0; } // // ID_VIEW_RESET // static LRESULT OnViewReset() { if (nState!=0) return 0; if (YesNoMessage("Are you sure you want to press the Reset Button ?")==IDYES) { SwitchToState(3); Chipset.pc = 0; Chipset.inte = TRUE; Chipset.Shutdn = FALSE; Chipset.SoftInt = TRUE; Reset(); // 21.01.98 cg, bugfix, must unconfig MMU too bInterrupt = TRUE; SwitchToState(0); } return 0; } // // ID_VIEW_SETTINGS // static LRESULT OnViewSettings() { ReadSettings(); if (nState == 1) UnmapPort2(); if (DialogBox(hApp, MAKEINTRESOURCE(IDD_SETTINGS), hWnd, (DLGPROC)SettingsProc) == -1) AbortMessage("Settings Dialog Creation Error !"); if (nState == 1) MapPort2(szPort2Filename); WriteSettings(); return 0; } // // ID_VIEW_SCRIPT // static LRESULT OnViewScript() { CHAR cType = cCurrentRomType; if (nState!=0) { InfoMessage("You cannot change the KML script when Emu48 is not running.\n" "Use the File,New menu item to create a new calculator."); return 0; } SwitchToState(1); retry: if (!DisplayChooseKml(cType)) goto ok; if (!InitKML(szCurrentKml,FALSE)) { if (AbortMessage("This KML Script has errors.\nPress Ok to try to find a correct script.")==IDCANCEL) { if (szCurrentFilename[0]) OnFileSave(); else OnFileSaveAs(); goto ok; } goto retry; } ok: if (pbyRom) SwitchToState(0); return 0; } // // ID_BACKUP_SAVE // static LRESULT OnBackupSave() { UINT nOldState; if (pbyRom == NULL) return 0; nOldState = SwitchToState(1); SaveBackup(); SwitchToState(nOldState); return 0; } // // ID_BACKUP_RESTORE // static LRESULT OnBackupRestore() { SwitchToState(1); RestoreBackup(); if (pbyRom) SwitchToState(0); return 0; } // // ID_BACKUP_DELETE // static LRESULT OnBackupDelete() { ResetBackup(); return 0; } // // ID_OBJECT_LOAD // static LRESULT OnObjectLoad() { static BOOL bWarning = TRUE; if (!Chipset.dispon) // 10.11.98 cg, new, calculator off, turn on { // turn on HP KeyboardEvent(TRUE,0,0x8000); Sleep(200); KeyboardEvent(FALSE,0,0x8000); } if (nState!=0) { InfoMessage("The emulator must be running to load an object."); return 0; } if (WaitForSleepState()) // 10.11.98 cg, changed, wait for cpu SHUTDN then sleep state { InfoMessage("The emulator is busy."); return 0; } while (nState!=nNextState) Sleep(0); _ASSERT(nState==3); if (bWarning) { UINT uReply = YesNoCancelMessage( "Warning: Trying to load an object while the emulator is busy \n" "will certainly result in a memory lost. Before loading an object \n" "you should be sure that the HP48 is not doing anything. \n" "Do you want to see this warning next time you try to load an object ?"); switch (uReply) { case IDYES: break; case IDNO: bWarning = FALSE; break; case IDCANCEL: SwitchToState(0); return 0; } } if (!GetLoadObjectFilename()) { SwitchToState(0); return 0; } if (!LoadObject(szBufferFilename)) { SwitchToState(0); return 0; } SwitchToState(0); // run state while (nState!=nNextState) Sleep(0); _ASSERT(nState==0); KeyboardEvent(TRUE,0,0x8000); Sleep(200); KeyboardEvent(FALSE,0,0x8000); // 10.11.98 cg, changed, wait for sleep mode while(Chipset.Shutdn == FALSE) Sleep(0); return 0; } // // ID_OBJECT_SAVE // static LRESULT OnObjectSave() { if (nState!=0) { InfoMessage("The emulator must be running to save an object."); return 0; } if (WaitForSleepState()) // 10.11.98 cg, wait for cpu SHUTDN then sleep state return 0; while (nState!=nNextState) Sleep(0); _ASSERT(nState==3); if (!GetSaveObjectFilename()) { SwitchToState(0); return 0; } SaveObject(szBufferFilename); SwitchToState(0); return 0; } // // ID_DISASM // // 15.07.98 cg, new, dialogbox for disassembly static BOOL CALLBACK Disasm(HWND hDlg, UINT message, DWORD wParam, LONG lParam) { static DWORD dwAddress, dwAddressMax; LONG i; LPINT lpnCount; char *cpStop,szAddress[256] = "0"; switch (message) { case WM_INITDIALOG: // 10.11.98 cg, new, 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_MNEMONICS,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); SendDlgItemMessage(hDlg,IDC_DISASM_HP,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); SendDlgItemMessage(hDlg,IDC_DISASM_CLASS,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); SendDlgItemMessage(hDlg,IDC_DISASM_MAP,BM_SETCHECK,1,0); SendDlgItemMessage(hDlg,IDC_DISASM_HP,BM_SETCHECK,1,0); // 10.11.98 cg, end of new part 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)); // 12.02.98 cg, new, set font of new button 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)); SetDlgItemText(hDlg,IDC_DISASM_ADR,szAddress); disassembler_map = MEM_MAP; // 10.11.98 cg, new disassemble with mapped modules disassembler_mode = HP_MNEMONICS; // 10.11.98 cg, new use HP mnemonics for disassembling dwAddress = strtoul(szAddress,&cpStop,16); dwAddressMax = 0x100000; // 10.11.98 cg, new, greatest address (mapped mode) return TRUE; case WM_COMMAND: switch(wParam) { // 10.11.98 cg, new, decode radio buttons case IDC_DISASM_MAP: disassembler_map = MEM_MAP; dwAddressMax = 0x100000; break; case IDC_DISASM_ROM: disassembler_map = MEM_ROM; dwAddressMax = dwRomSize; break; case IDC_DISASM_RAM: disassembler_map = MEM_RAM; dwAddressMax = Chipset.Port0Size * 2048; break; case IDC_DISASM_PORT1: disassembler_map = MEM_PORT1; dwAddressMax = ((Chipset.cards_status & PORT1_PRESENT) != 0) ? (Chipset.Port1Size * 2048) : 0; break; case IDC_DISASM_PORT2: disassembler_map = MEM_PORT2; dwAddressMax = (dwPort2Mask != 0) ? ((dwPort2Mask + 1) << 17) : 0; break; case IDC_DISASM_HP: disassembler_mode = HP_MNEMONICS; break; case IDC_DISASM_CLASS: disassembler_mode = CLASS_MNEMONICS; break; // 10.11.98 cg, end of new part case IDOK: SendDlgItemMessage(hDlg,IDC_DISASM_ADR,EM_SETSEL,0,-1); GetDlgItemText(hDlg,IDC_DISASM_ADR,szAddress,sizeof(szAddress)); // test if valid hex address for (i = 0; i < (LONG) strlen(szAddress); ++i) { if (isxdigit(szAddress[i]) == FALSE) return FALSE; } dwAddress = strtoul(szAddress,&cpStop,16); // no break case IDC_DISASM_NEXT: if (dwAddress >= dwAddressMax) // 10.11.98 cg, bugfix, moved check from IDOK return FALSE; i = wsprintf(szAddress,"%05lX ",dwAddress); dwAddress = disassemble(dwAddress,&szAddress[i]); // 12.02.99 cg, changed, implementation for multi selectable items i = SendDlgItemMessage(hDlg,IDC_DISASM_WIN,LB_ADDSTRING,0,(LPARAM) szAddress); SendDlgItemMessage(hDlg,IDC_DISASM_WIN,LB_SELITEMRANGE,FALSE,MAKELPARAM(0,i)); SendDlgItemMessage(hDlg,IDC_DISASM_WIN,LB_SETSEL,TRUE,i); SendDlgItemMessage(hDlg,IDC_DISASM_WIN,LB_SETTOPINDEX,i,0); break; // 12.02.99 cg, new, copy selected items to clipoard case IDC_DISASM_COPY: // get number of selections if ((i = SendDlgItemMessage(hDlg,IDC_DISASM_WIN,LB_GETSELCOUNT,0,0)) == 0) break; // no items selected if ((lpnCount = (LPINT) LocalAlloc(LMEM_FIXED,i * sizeof(INT))) != NULL) { HANDLE hClipObj; LONG j,lMem = 0; // get indexes of selected items i = SendDlgItemMessage(hDlg,IDC_DISASM_WIN,LB_GETSELITEMS,i,(LPARAM) lpnCount); for (j = 0;j < i;++j) // scan all selected items { // calculate total amount of needed memory lMem += SendDlgItemMessage(hDlg,IDC_DISASM_WIN,LB_GETTEXTLEN,lpnCount[j],0) + 2; } // allocate clipboard data if ((hClipObj = GlobalAlloc(GMEM_MOVEABLE,lMem + 1)) != NULL) { LPBYTE lpData; if (lpData = GlobalLock(hClipObj)) { for (j = 0;j < i;++j) // scan all selected items { lpData += SendDlgItemMessage(hDlg,IDC_DISASM_WIN,LB_GETTEXT,lpnCount[j],(LPARAM) lpData); *lpData++ = '\r'; *lpData++ = '\n'; } *lpData = 0; // set end of string GlobalUnlock(hClipObj); // unlock memory } if (OpenClipboard(hWnd)) { if (EmptyClipboard()) SetClipboardData(CF_TEXT,hClipObj); else GlobalFree(hClipObj); CloseClipboard(); } else // clipboard open failed { GlobalFree(hClipObj); } } LocalFree(lpnCount); // free item table } break; // 12.02.99 cg, end of new part case IDCANCEL: EndDialog(hDlg, wParam); break; } break; } return FALSE; UNREFERENCED_PARAMETER(lParam); UNREFERENCED_PARAMETER(hDlg); } // // ID_ABOUT // static BOOL CALLBACK About(HWND hDlg, UINT message, DWORD wParam, LONG lParam) { switch (message) { case WM_INITDIALOG: SetDlgItemText(hDlg,IDC_VERSION,szNoTitle); SetDlgItemText(hDlg,IDC_LICENSE,szLicence); return TRUE; case WM_COMMAND: if ((wParam==IDOK)||(wParam==IDCANCEL)) { EndDialog(hDlg, wParam); break; } break; } return FALSE; UNREFERENCED_PARAMETER(lParam); UNREFERENCED_PARAMETER(hDlg); } static LRESULT OnToolDisasm() // 15.07.98 cg, new, disasm dialogbox call { if (pbyRom) SwitchToState(3); if (DialogBox(hApp, MAKEINTRESOURCE(IDD_DISASM), hWnd, (DLGPROC)Disasm) == -1) AbortMessage("Disassembler Dialog Box Creation Error !"); if (pbyRom) SwitchToState(0); return 0; } static LRESULT OnAbout() { // if (pbyRom) SwitchToState(3); // 25.01.99 cg, removed, don't stop emulation if (DialogBox(hApp, MAKEINTRESOURCE(IDD_ABOUT), hWnd, (DLGPROC)About) == -1) AbortMessage("About Dialog Box Creation Error !"); // if (pbyRom) SwitchToState(0); // 25.01.99 cg, removed return 0; } static LRESULT OnLButtonDown(UINT nFlags, WORD x, WORD y) { if (nState==0) MouseButtonDownAt(nFlags, x,y); return 0; } static LRESULT OnLButtonUp(UINT nFlags, WORD x, WORD y) { if (nState==0) MouseButtonUpAt(nFlags, x,y); return 0; } static LRESULT OnMouseMove(UINT nFlags, WORD x, WORD y) { if (nState==0) MouseMovesTo(nFlags, x,y); return 0; } static LRESULT OnKeyDown(int nVirtKey, DWORD lKeyData) { // 03.09.98 cg, bugfix, call RunKey() only once (suppress autorepeat feature) if (nState==0 && (lKeyData & 0x40000000)==0) RunKey((BYTE)nVirtKey, TRUE); return 0; } static LRESULT OnKeyUp(int nVirtKey, DWORD lKeyData) { if (nState==0) RunKey((BYTE)nVirtKey, FALSE); return 0; UNREFERENCED_PARAMETER(lKeyData); } static LRESULT CALLBACK MainWndProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CREATE: return OnCreate(hWindow); case WM_DESTROY: return OnDestroy(hWindow); case WM_PAINT: return OnPaint(hWindow); // 01.11.98 cg & Will Laughlin, new, support dropped files case WM_DROPFILES: return OnDropFiles((HANDLE)wParam); case WM_ACTIVATE: if (LOWORD(wParam)==WA_INACTIVE) break; case WM_QUERYNEWPALETTE: if (hPalette) { SelectPalette(hWindowDC, hPalette, FALSE); if (RealizePalette(hWindowDC)) { InvalidateRect(hWindow,NULL,TRUE); return TRUE; } } return FALSE; case WM_PALETTECHANGED: if ((HWND)wParam == hWindow) break; if (hPalette) { SelectPalette(hWindowDC, hPalette, FALSE); if (RealizePalette(hWindowDC)) { // UpdateColors(hWindowDC); InvalidateRect (hWnd, (LPRECT) (NULL), 1); } } return FALSE; case WM_COMMAND: switch (LOWORD(wParam)) { case ID_FILE_NEW: return OnFileNew(); case ID_FILE_OPEN: return OnFileOpen(); case ID_FILE_SAVE: return OnFileSave(); case ID_FILE_SAVEAS: return OnFileSaveAs(); case ID_FILE_CLOSE: return OnFileClose(); case ID_FILE_EXIT: return OnFileExit(); case ID_STACK_COPY: return OnStackCopy(); // 17.06.98 cg, new, copy data from stack case ID_STACK_PASTE: return OnStackPaste(); // 17.06.98 cg, new, paste data to stack case ID_VIEW_COPY: return OnViewCopy(); case ID_VIEW_RESET: return OnViewReset(); case ID_VIEW_SETTINGS: return OnViewSettings(); case ID_VIEW_SCRIPT: return OnViewScript(); case ID_BACKUP_SAVE: return OnBackupSave(); case ID_BACKUP_RESTORE:return OnBackupRestore(); case ID_BACKUP_DELETE: return OnBackupDelete(); case ID_OBJECT_LOAD: return OnObjectLoad(); case ID_OBJECT_SAVE: return OnObjectSave(); case ID_TOOL_DISASM: return OnToolDisasm(); // 15.07.98 cg, new, disassembler dialog box case ID_ABOUT: return OnAbout(); } break; case WM_SYSCOMMAND: switch (LOWORD(wParam)) { case SC_CLOSE: return OnSysClose(); } break; case WM_RBUTTONDOWN: // 01.10.97 cg, for holding key pressed case WM_LBUTTONDOWN: return OnLButtonDown(wParam, LOWORD(lParam), HIWORD(lParam)); case WM_LBUTTONUP: return OnLButtonUp(wParam, LOWORD(lParam), HIWORD(lParam)); case WM_MOUSEMOVE: return OnMouseMove(wParam, LOWORD(lParam), HIWORD(lParam)); case WM_KEYUP: return OnKeyUp((int)wParam, lParam); case WM_KEYDOWN: return OnKeyDown((int)wParam, lParam); } return DefWindowProc(hWindow, uMsg, wParam, lParam); } static BOOL FlushMessages(LPMSG msg) { while (PeekMessage(msg, NULL, 0, 0, PM_REMOVE)) { if (msg->message == WM_QUIT) return TRUE; TranslateMessage(msg); DispatchMessage(msg); } return FALSE; } // 01.11.98 cg, bugfix, changed varible type of first two arguments int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow) { MSG msg; WNDCLASS wc; RECT rectWindow; HSZ hszService, hszTopic; // 13.05.98 cg, new, varibles for DDE server hApp = hInst; wc.style = CS_BYTEALIGNCLIENT; wc.lpfnWndProc = (WNDPROC)MainWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; wc.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_EMU48)); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = NULL; wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU); wc.lpszClassName = "CEmu48"; if (!RegisterClass(&wc)) { AbortMessage( "CEmu48 class registration failed.\n" "This application will now terminate."); return FALSE; } // Create window rectWindow.left = 0; rectWindow.top = 0; rectWindow.right = 256; rectWindow.bottom = 0; AdjustWindowRect(&rectWindow, WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_OVERLAPPED, TRUE); hWnd = CreateWindow("CEmu48", "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 ); if (hWnd == NULL) { AbortMessage("Window creation failed.\n"); return FALSE; } ShowWindow(hWnd, nCmdShow); if (FlushMessages(&msg)) return msg.wParam; // initialization QueryPerformanceFrequency(&lFreq); // 24.08.98 cg, init high resolution counter // 01.02.98 cg, calculate size of buffer GetCurrentDirectory(sizeof(szCurrentDirectory), szCurrentDirectory); ReadSettings(); // szNoTitle = "Emu48 "VERSION; // 20.01.98 cg, removed UpdateWindowStatus(); nState = 1; // thread starts in an invalid state nNextState = 1; hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&WorkerThread, NULL, 0, &lThreadId); if (hThread == NULL) { AbortMessage("Thread creation failed."); return FALSE; } // 20.02.99 cg, changed, use 2nd command line argument if defined MapPort2((__argc < 3) ? szPort2Filename : __argv[2]); // 13.05.98 cg, new, initialize DDE server if (DdeInitialize(&idDdeInst,(PFNCALLBACK) &DdeCallback, APPCLASS_STANDARD | CBF_FAIL_EXECUTES | CBF_FAIL_ADVISES | CBF_SKIP_REGISTRATIONS | CBF_SKIP_UNREGISTRATIONS,0)) { AbortMessage("Could not initialize server!"); return FALSE; } if (__argc >= 2) // 20.02.99 cg, changed, use decoded parameter line { CHAR szTemp[256] = "Loading "; strcat(szTemp, __argv[1]); // 20.02.99 cg, changed, use decoded parameter line SetWindowTitle(szTemp); if (FlushMessages(&msg)) return msg.wParam; if (OpenDocument(__argv[1])) // 20.02.99 cg, changed, use decoded parameter line goto start; } // 09.12.97 cg, bugfix, function parameter GetPrivateProfileString("Files","LastDocument","",szBufferFilename,sizeof(szBufferFilename),EMU48_INI); if (szBufferFilename[0]) { CHAR szTemp[256] = "Loading "; strcat(szTemp, szBufferFilename); SetWindowTitle(szTemp); if (FlushMessages(&msg)) return msg.wParam; if (OpenDocument(szBufferFilename)) goto start; } SetWindowTitle("New Document"); if (FlushMessages(&msg)) return msg.wParam; if (NewDocument()) { SetWindowTitle("Untitled"); goto start; } ResetDocument(); // SetWindowTitle(NULL); // 27.01.98 cg, removed, see WM_DESTROY start: InitializeCriticalSection(&csGDILock); // 03.01.99 cg, bugfix, initialize critical section InitializeCriticalSection(&csKeyLock); // 03.01.99 cg, bugfix, initialize critical section InitializeCriticalSection(&csIOLock); // 24.02.99 cg, new, initialize critical section InitializeCriticalSection(&csT1Lock); // 03.01.99 cg, bugfix, initialize critical section InitializeCriticalSection(&csT2Lock); // 03.01.99 cg, bugfix, initialize critical section // 13.05.98 cg, new, init clipboard format and name service uCF_HpObj = RegisterClipboardFormat(CF_HPOBJ); hszService = DdeCreateStringHandle(idDdeInst,szAppName,0); hszTopic = DdeCreateStringHandle(idDdeInst,szTopic,0); DdeNameService(idDdeInst,hszService,NULL,DNS_REGISTER); // 13.05.98 cg, new, end of init if (pbyRom) SwitchToState(0); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } // 13.05.98 cg, new, clean up DDE server DdeNameService(idDdeInst, hszService, NULL, DNS_UNREGISTER); DdeFreeStringHandle(idDdeInst, hszService); DdeFreeStringHandle(idDdeInst, hszTopic); DdeUninitialize(idDdeInst); // 13.05.98 cg, new, end of clean up DeleteCriticalSection(&csGDILock); // 03.01.99 cg, bugfix, release critical section DeleteCriticalSection(&csKeyLock); // 03.01.99 cg, bugfix, release critical section DeleteCriticalSection(&csIOLock); // 24.02.99 cg, new, release critical section DeleteCriticalSection(&csT1Lock); // 03.01.99 cg, bugfix, release critical section DeleteCriticalSection(&csT2Lock); // 03.01.99 cg, bugfix, release critical section // SwitchToState(2); // 27.01.98 cg, removed, done in WM_DESTROY _ASSERT(nState == 2); // 30.01.98 cg, set by WM_DESTROY ResetDocument(); ResetBackup(); cCurrentRomType = 0; // KillKML(); // 27.01.98 cg, removed, done in ResetDocument() or OnFileClose() _ASSERT(pKml == NULL); // 27.01.98 cg, KML script not closed UnmapPort2(); _ASSERT(szTitle == NULL); // 11.09.98 cg, freed allocated memory _ASSERT(hPalette == NULL); // 11.09.98 cg, freed resource memory return msg.wParam; UNREFERENCED_PARAMETER(lpCmdLine); UNREFERENCED_PARAMETER(hPrevInst); }