Main Page   Data Structures   File List   Data Fields   Globals   Related Pages  

emu6502.c

Go to the documentation of this file.
00001 
00007 #define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
00008 
00009 #include <windows.h>
00010 #include <stdlib.h>
00011 #include <malloc.h>
00012 #include <memory.h>
00013 #include <tchar.h>
00014 #include <commdlg.h>
00015 #include <commctrl.h>
00016 #include <stdio.h>
00017 
00018 
00019 #include "emu6502.h"
00020 #define MAX_LOADSTRING 512
00021 #define CR 13
00022 #define LF 10
00023 
00025 HINSTANCE hInst;        
00027 HWND hMainWnd;
00029 HWND hToolBar;
00030 
00032 DllMsgList* DMList = NULL;
00034 PtrList* DHInstList = NULL;
00035 
00036 
00037 TCHAR szTitle[MAX_LOADSTRING];
00038 TCHAR szWindowClass[MAX_LOADSTRING];
00039 
00040 
00041 int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
00042                      LPSTR lpCmdLine, int nCmdShow)
00043 {
00044         MSG msg;
00045         int gotMsg = FALSE;
00046         BOOL run = TRUE;
00047         int i = 0;
00048 
00049         LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
00050         LoadString(hInstance, IDC_EMU6502, szWindowClass, MAX_LOADSTRING);
00051         MyRegisterClass(hInstance);
00052 
00053         InitMem();
00054 
00055         if (!InitInstance(hInstance, nCmdShow)) {
00056                 return FALSE;
00057         }
00058 
00059         // Main message loop
00060         while (GetMessage(&msg, NULL, 0, 0)) {
00061                 TranslateMessage(&msg);
00062                 DispatchMessage(&msg);
00063         }
00064 
00065         return msg.wParam;
00066 }
00067 
00068 
00069 ATOM MyRegisterClass(HINSTANCE hInstance)
00070 {
00071         WNDCLASSEX wcex;
00072 
00073         wcex.cbSize = sizeof(WNDCLASSEX); 
00074 
00075         wcex.style                      = CS_HREDRAW | CS_VREDRAW;
00076         wcex.lpfnWndProc        = (WNDPROC)WndProc;
00077         wcex.cbClsExtra         = 0;
00078         wcex.cbWndExtra         = 0;
00079         wcex.hInstance          = hInstance;
00080         wcex.hIcon                      = LoadIcon(hInstance, (LPCTSTR)IDI_EMU6502);
00081         wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);
00082         wcex.hbrBackground      = (HBRUSH)(COLOR_BTNFACE+1);   //(COLOR_WINDOW+1);
00083         wcex.lpszMenuName       = (LPCSTR)IDC_EMU6502;
00084         wcex.lpszClassName      = szWindowClass;
00085         wcex.hIconSm            = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
00086 
00087         return RegisterClassEx(&wcex);
00088 }
00089 
00090 
00091 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
00092 {
00093         RECT rc, rcToolB;
00094 
00095         hInst = hInstance; 
00096 
00097         hMainWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
00098                 0, 0, 0, 0, NULL, NULL, hInstance, NULL);
00099 
00100         if (!hMainWnd) {
00101                 return FALSE;
00102         }
00103 
00104         rc.top = GetSystemMetrics(SM_CYSCREEN) / 2 - 138;
00105         rc.left = GetSystemMetrics(SM_CXSCREEN) / 2 - 128;
00106         rc.right = GetSystemMetrics(SM_CXSCREEN) / 2 + 127;
00107         rc.bottom = GetSystemMetrics(SM_CYSCREEN) / 2 + 117;
00108         AdjustWindowRect(&rc, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, TRUE);
00109 
00110         hToolBar = CreateToolBar(hMainWnd);
00111 
00112         GetWindowRect(hToolBar, &rcToolB);
00113         rc.bottom += rcToolB.bottom - rcToolB.top;
00114 
00115         SetWindowPos(hMainWnd, HWND_TOP, rc.left, rc.top, 
00116                 rc.right - rc.left + 1, rc.bottom - rc.top + 1, SWP_NOZORDER);
00117         SendMessage(hToolBar, TB_AUTOSIZE, 0, 0);
00118 
00119         LoadPlugins(&DMList, &DHInstList);
00120         
00121         ShowWindow(hMainWnd, nCmdShow);
00122         UpdateWindow(hMainWnd);
00123 
00124         return TRUE;
00125 }
00126 
00127 HWND CreateToolBar(HWND hParentWnd)
00128 {
00129         HWND hTb;
00130         TBBUTTON TBtns[3];
00131         INITCOMMONCONTROLSEX iccs;
00132 
00133         iccs.dwSize = sizeof(INITCOMMONCONTROLSEX);
00134         iccs.dwICC = ICC_BAR_CLASSES;
00135 
00136         if (!InitCommonControlsEx(&iccs)) {
00137                 return NULL;
00138         }
00139 
00140         ZeroMemory(&TBtns, sizeof(TBBUTTON) * 1);
00141         TBtns[0].fsState = TBSTATE_ENABLED;
00142         TBtns[0].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE ;
00143         TBtns[0].iBitmap = 0;
00144         TBtns[0].idCommand = IDM_FILE_LOADMEMORYFILE;
00145 
00147         hTb = CreateToolbarEx(hParentWnd, WS_CHILD | TBSTYLE_FLAT,
00148                 0, 1, hInst, IDR_TOOLBAR, TBtns, 1, 16, 16, 16, 16, sizeof(TBBUTTON));
00149 
00150         ShowWindow(hTb, SW_SHOW); 
00151         return hTb;
00152 }
00153 
00154 
00155 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
00156 {
00157         int wmId, wmEvent;
00158         BOOL MsgProcessed;
00159         
00160 
00161         MsgProcessed = ForwardDllMessage(message, wParam, lParam, DMList);
00162 
00163         switch (message) 
00164         {
00165                 case WM_COMMAND:
00166                         wmId    = LOWORD(wParam); 
00167                         wmEvent = HIWORD(wParam); 
00168                         // Parse the menu selections:
00169                         switch (wmId)
00170                         {
00171                                 case IDM_ABOUT:
00172                                         DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
00173                                         break;
00174                                 case IDM_EXIT:
00175                                         DestroyWindow(hWnd);
00176                                         break;
00177                                 case IDM_FILE_LOADMEMORYFILE:
00178                                         LoadMemFile(hWnd);
00179                                         break;
00180                                 default:
00181                                         if (MsgProcessed == FALSE) {
00182                                                 return DefWindowProc(hWnd, message, wParam, lParam);
00183                                         }
00184                         }
00185                         break;
00186                 case WM_DESTROY:
00187                         UnloadPlugins(DHInstList);
00188                         PostQuitMessage(0);
00189                         break;
00190                 default:
00191                         if (MsgProcessed == FALSE) {
00192                                 return DefWindowProc(hWnd, message, wParam, lParam);
00193                         }
00194    }
00195    return 0;
00196 }
00197 
00198 LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
00199 {
00200         switch (message)
00201         {
00202                 case WM_INITDIALOG:
00203                                 return TRUE;
00204 
00205                 case WM_COMMAND:
00206                         if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
00207                         {
00208                                 EndDialog(hDlg, LOWORD(wParam));
00209                                 return TRUE;
00210                         }
00211                         break;
00212         }
00213     return FALSE;
00214 }
00215 
00216 BOOL LoadMemFile(HWND hWnd)
00217 {
00218         OPENFILENAME ofn;
00219         TCHAR FileName[_MAX_PATH];
00220         HANDLE hFile;
00221         DWORD dwSize;
00222         DWORD dwRead;
00223 
00224         //Open file dialog
00225         SendMessage(hWnd, PAUSECPU, 0, 0);
00226         SendMessage(hWnd, WAITEND, 0, 0);
00227 
00228         lstrcpy(FileName, "");
00229         ZeroMemory(&ofn, sizeof(OPENFILENAME));
00230         
00231         ofn.lStructSize = sizeof(OPENFILENAME);
00232         ofn.lpstrFile = FileName;
00233         ofn.hwndOwner = hWnd;
00234         ofn.nMaxFile = sizeof(FileName);
00235         ofn.lpstrFilter = 
00236                 TEXT("Memory image files (*.img)\0*.img\0All Files (*.*)\0*.*\0");
00237         ofn.nFilterIndex = 1;
00238         ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
00239         
00240         if (!GetOpenFileName(&ofn))
00241                 return FALSE;
00242 
00243         //Open given file
00244         hFile=CreateFile((LPCSTR) FileName, GENERIC_READ, 0,NULL, OPEN_EXISTING, 0, NULL);
00245         if (hFile==INVALID_HANDLE_VALUE) {
00246                 error(hWnd, IDS_EOPEN, NULL);
00247                 return FALSE;
00248         }
00249 
00250         dwSize=GetFileSize(hFile, NULL);
00251         if(dwSize!=MEMSIZE) {
00252                 error(hWnd, IDS_ECORRUPT, NULL);
00253                 return FALSE;
00254         }
00255         
00256         SendMessage(hWnd, STOPVIDEO, 0, 0);
00257 
00258         if (!ReadFile(hFile, &memory, dwSize, &dwRead, NULL) ) {
00259                 CloseHandle(hFile);
00260                 error(hWnd, IDS_EREAD, NULL);
00261                 return FALSE;
00262         }
00263         SendMessage(hWnd, RESETMSG, 0, 0);
00264         CloseHandle(hFile);
00265         return TRUE;
00266 }
00267 
00268 void error(HWND hWnd, UINT uID, TCHAR* name)
00269 {
00270         TCHAR msg[MAX_LOADSTRING];
00271         TCHAR out[MAX_LOADSTRING];
00272         LoadString(hInst, uID, msg, MAX_LOADSTRING);
00273         _stprintf(out, msg, name);
00274         MessageBox(hWnd, out, "Error", MB_OK | MB_ICONERROR | MB_DEFBUTTON1);
00275 }
00276 
00277 BOOL ForwardDllMessage(UINT message, WPARAM wParam, LPARAM lParam, DllMsgList* actlist)
00278 {
00279         PtrList* actnode;
00280         MESSAGEDLLSTRUCT mds;
00281 
00282         actlist = DMList;
00283         while (actlist != NULL && actlist->MesgID != message) {
00284                 actlist = actlist->next;
00285         }
00286         if (actlist == NULL) {
00287                 return FALSE;
00288         }
00289         
00290         mds.lParam = lParam;
00291         mds.wParam = wParam;
00292         mds.message = message;
00293 
00294         actnode = actlist->Functions;
00295 
00296         while (actnode != NULL) {
00297                 ((pForwardDllMsgProc) actnode->ptr)(&mds);
00298                 actnode = actnode->next;
00299         }
00300         return TRUE;
00301 }
00302 
00303 void LoadPlugins(DllMsgList** list, PtrList** InstList)
00304 {
00305         HANDLE hFile;
00306         TCHAR buf[65536];
00307         TCHAR* str;
00308         TCHAR* param;
00309         DWORD dwRead;
00310 
00311         hFile = CreateFile("plugins.txt", GENERIC_READ, FILE_SHARE_READ,
00312                 NULL, OPEN_EXISTING, 0, NULL);
00313         if (hFile == INVALID_HANDLE_VALUE) {
00314                 error(hMainWnd, IDS_EPLUGINSTXT, NULL);
00315                 return;
00316         }
00317 
00318         if (!ReadFile(hFile, buf, 65536, &dwRead, NULL)) {
00319                 error(hMainWnd, IDS_EPLUGINSTXT, NULL);
00320                 return;
00321         }
00322         buf[dwRead] = '\0';
00323         
00324         param = (TCHAR*) buf;
00325         while((str = GetNextStrToken(&param)) != NULL) {
00326                 if (LoadPlugin(str, list, InstList) == FALSE) {
00327                         error(hMainWnd, IDS_EPLUGIN, str);
00328                 }
00329         }
00330 
00331         CloseHandle(hFile);
00332 }
00333 
00334 BOOL LoadPlugin(TCHAR* name, DllMsgList** list, PtrList** InstList)
00335 {
00336         HINSTANCE hInstLib;
00337         pInitDllProc IDProc;
00338         pForwardDllMsgProc FDMProc;
00339         pIOFunc IOFunc;
00340         INITDLLSTRUCT ids;
00341         INITDLLINFO idi;
00342         RECT rcT, rcC;
00343         int i;
00344 
00345         // try to load library of given name
00346         hInstLib = LoadLibrary(name);
00347         if (hInstLib == NULL) {
00348                 error(hMainWnd, IDS_EOPEN, NULL);
00349                 return FALSE;
00350         }
00351 
00352         // get handles to the two common plugin procedures
00353         IDProc = (pInitDllProc) GetProcAddress(hInstLib, "InitDll");
00354         FDMProc = (pForwardDllMsgProc) GetProcAddress(hInstLib, "OnMessage");
00355         IOFunc = (pIOFunc) GetProcAddress(hInstLib, "IOFunc");
00356 
00357         // save this library handle
00358         AddToPtrList((void*) hInstLib, InstList);
00359 
00360         // fill ids
00361         ids.hInst = hInst;
00362         ids.hWnd = hMainWnd;
00363         ids.hTb = hToolBar;
00364         ids.memory = memory;
00365         ids.optional = NULL;
00366         ids.CSMemory = CSMemory;
00367         ids.memgetb = &memgetb;
00368         ids.memsetb = &memsetb;
00369         GetClientRect(hMainWnd, &rcC);
00370         GetWindowRect(hToolBar, &rcT);
00371         rcC.top += rcT.bottom  - rcT.top;
00372         ids.rcPaint = rcC;
00373 
00374         
00375         // call InitDll proc, receive list of messages to be catched
00376         // and lower/higher end of demanded io memory
00377         (IDProc) (&ids, &idi);
00378 
00379         // add this list to DllMsgList structure
00380         if (idi.msglist != NULL) {
00381                 for (i=0; idi.msglist[i]!=ENDOFMSGLIST; i++) {
00382                         AddDllMsg(list, idi.msglist[i], FDMProc);
00383                 }
00384         }
00385         
00386         // register the io memory
00387         if (idi.iolo !=0 && idi.iohi != 0) {
00388                 if (IOFunc == NULL) {
00389                         error(hMainWnd, IDS_EIOFNOTFOUND, name);
00390                 } 
00391                 else {
00392                         SetIOFunc(IOFunc, idi.iolo, idi.iohi);
00393                 }
00394         }
00395 
00396         return TRUE;
00397 }
00398 
00399 void AddDllMsg(DllMsgList** list, UINT message, 
00400                            pForwardDllMsgProc FDMProc)
00401 {
00402         DllMsgList* newlist;
00403         DllMsgList* prev = NULL;
00404         DllMsgList* actlist = *list;
00405         
00406         while (actlist != NULL && actlist->MesgID != message) {
00407                 prev = actlist;
00408                 actlist = actlist->next;
00409         }
00410 
00411         if (actlist == NULL) {
00412                 newlist = (DllMsgList*) malloc(sizeof(DllMsgList));
00413                 newlist->MesgID = message;
00414                 newlist->Functions = NULL;
00415                 newlist->next = NULL;
00416                 AddToPtrList((void*) FDMProc, &newlist->Functions);
00417                 // New list
00418                 if (prev == NULL) {
00419                         *list = newlist;
00420                         return;
00421                 }
00422                 else {
00423                 // New message code
00424                         prev->next = newlist;
00425                         return;
00426                 }
00427         }
00428 
00429         // Add function to existing message
00430         AddToPtrList((void*) FDMProc, &actlist->Functions);
00431         return;
00432 }
00433 
00434 void UnloadPlugins(PtrList* list)
00435 {
00436         PtrList* p = list;
00437         while (p != NULL) {
00438                 FreeLibrary((HINSTANCE) list->ptr);
00439                 p = list->next;
00440                 free(list);
00441                 list = p;
00442         }
00443 }
00444 
00445 
00446 void AddToPtrList(void* ptr, PtrList** list)
00447 {
00448         PtrList* node = (PtrList*) malloc(sizeof(PtrList));
00449         node->ptr = ptr;
00450         node->next = *list;
00451         *list = node;
00452 }
00453 
00454 TCHAR* GetNextStrToken(TCHAR** buf)
00455 {
00456         TCHAR* start = *buf;
00457 
00458         if (*buf == NULL || **buf == '\0' || **buf == CR || **buf == LF) {
00459                 return NULL;
00460         }
00461 
00462         while (**buf != CR && **buf != '\0') {
00463                 (*buf)++;
00464         }
00465 
00466         if (**buf == CR) {
00467                 **buf = '\0';
00468                 (*buf)++;
00469                 if (**buf == LF) {
00470                         (*buf)++;
00471                 }
00472         }
00473         return start;
00474 }
00475 
00476         
00477 
00478 

Generated on Fri Sep 6 18:32:14 2002 for Emu6502 by doxygen1.2.17