Main Page   Data Structures   File List   Data Fields   Globals   Related Pages  

cpudll.c

Go to the documentation of this file.
00001 
00008 //#define BENCHMARK
00009 
00010 // Windows Header Files:
00011 #include <windows.h>
00012 
00013 // C RunTime Header Files
00014 #include <stdlib.h>
00015 #include <tchar.h>
00016 
00017 #include "../dllkit/dllkit.h"
00018 #include "cpu.h"
00019 #include "../usrmsgs.h"
00020 
00021 
00022 
00024 UINT Freq = 1790000;
00026 UINT Frms = 1790;
00027 
00028 /* ----- Forward declarations */
00029 
00030 DWORD WINAPI CpuThreadFunc(LPVOID lpParam);
00031 void CreateCpuThread();
00032 void ExitCpuThread();
00033 void ContExe();
00034 
00035 /* ----- End of forward declarations */
00036 
00037 
00038 UINT start;     
00039 UINT total;     
00040 UINT secstart;  
00041 UINT ticks;     
00043 typedef enum { NOTSTARTED, RUNNING, ENDED } THRSTATE;
00044 
00045 BOOL volatile Running;  
00046 THRSTATE volatile ThreadState;  
00048 typedef enum { NONE, IRQ, NMI, RESET } INTR;
00049 
00050 INTR volatile Interrupt; 
00052 HANDLE CpuThreadHandle; 
00053 DWORD CpuThreadID;      
00055 HANDLE hThisModule;
00056 MSGLIST Msgs;
00057 INITDLLSTRUCT info;
00058 
00062 BOOL APIENTRY DllMain(HANDLE hModule, DWORD  ul_reason_for_call, 
00063                                           LPVOID lpReserved)
00064 {
00065         hThisModule = hModule;
00066         switch (ul_reason_for_call) {
00067         case DLL_PROCESS_ATTACH:
00068                 break;
00069         case DLL_PROCESS_DETACH:
00070                 break;
00071         }       
00072     return TRUE;
00073 }
00074                                         
00075 DLLEXPORT void __cdecl InitDll(INITDLLSTRUCT* ids, INITDLLINFO* idi)
00076 {
00077         Running = FALSE;
00078         ThreadState = NOTSTARTED;
00079 
00080         CreateMsgList(&Msgs, 11);
00081         AddMessage(Msgs, NMIMSG);
00082         AddMessage(Msgs, IRQMSG);
00083         AddMessage(Msgs, RESETMSG);
00084         AddMessage(Msgs, SETFREQ);
00085         AddMessage(Msgs, GETREGS);
00086         AddMessage(Msgs, ISRUNNING);
00087         AddMessage(Msgs, ISTEP);
00088         AddMessage(Msgs, WAITEND);
00089         AddMessage(Msgs, IRQD);
00090         AddMessage(Msgs, NMID);
00091         AddMessage(Msgs, RESETD);
00092         AddMessage(Msgs, STARTCPU);
00093         AddMessage(Msgs, PAUSECPU);
00094 
00095         info.CSMemory = ids->CSMemory;
00096         info.hInst = ids->hInst;
00097         info.hWnd = ids->hWnd;
00098         info.memory = ids->memory;
00099         info.memgetb = ids->memgetb;
00100         memgetb = ids->memgetb;
00101         info.memsetb = ids->memsetb;
00102         memsetb = ids->memsetb;
00103         info.optional = ids->optional;
00104 
00105         Interrupt = RESET;
00106 
00107         idi->iolo = 0;  /* No io memory needed */
00108         idi->iohi = 0;
00109         idi->msglist = Msgs;
00110 }
00111 
00113 DLLEXPORT void __cdecl OnMessage(MESSAGEDLLSTRUCT* mds)
00114 {
00115         switch (mds->message) {
00116         case STARTCPU:
00117                 CreateCpuThread();
00118                 SendMessage(info.hWnd, CPURUNNING, 0, 0);
00119                 break;
00120         case PAUSECPU:
00121                 ExitCpuThread();
00122                 SendMessage(info.hWnd, CPUSTOPPED, 0, 0);
00123                 break;
00124         case NMIMSG:
00125                 Interrupt = NMI;
00126                 break;
00127         case IRQMSG:
00128                 Interrupt = IRQ;
00129                 break;
00130         case RESETMSG:
00131                 Interrupt = RESET;
00132                 break;
00133         case SETFREQ:
00134                 Freq = (UINT) mds->lParam;
00135                 Frms = Freq / 1000;
00136                 break;
00137 
00138 
00139         // Debugger messages:
00140 
00141         case WAITEND:
00142                 // wait until CpuThread stops
00143                 while (ThreadState != ENDED && ThreadState != NOTSTARTED)
00144                         ;
00145                 break;
00146         case GETREGS:
00147                 if (Running == TRUE) {
00148                         *(Regs**)(mds->lParam) = NULL;
00149                         break;
00150                 }
00151                 *(Regs**)(mds->lParam) = GetRegs();
00152                 break;
00153         case ISTEP:
00154                 if (Running == TRUE) {
00155                         *(UINT*)(mds->lParam) = 0;
00156                         break;
00157                 }
00158                 *(UINT*)(mds->lParam) = InstrStep();
00159                 break;
00160         case IRQD:
00161                 Irq();
00162                 break;
00163         case NMID:
00164                 Nmi();
00165                 break;
00166         case RESETD:
00167                 Reset();
00168                 break;
00169         }
00170 }
00171 
00172 DLLEXPORT void __cdecl IOFunc(UINT adr, unsigned char* data, 
00173                                                                                   iomode mode)
00174 {
00175 }
00176 
00187 void CreateCpuThread()
00188 {
00189         secstart = start = GetTickCount();
00190         total = 0;
00191         Running = TRUE;
00192         CpuThreadHandle = CreateThread(NULL, 0, &CpuThreadFunc, NULL, 0, &CpuThreadID);
00193 }
00194 
00202 DWORD WINAPI CpuThreadFunc(LPVOID lpParam)
00203 {
00204         ThreadState = RUNNING;
00205         while (Running) {
00206                         ContExe();
00207         }
00208         ThreadState = ENDED;
00209         return 0;
00210 }
00211 
00219 void ContExe()
00220 {  
00221         UINT i;
00222         UINT todo = ((ticks = GetTickCount()) - secstart) * Frms;
00223         UINT tmp = 0;
00224         secstart = ticks + todo / Freq;
00225 
00226         for (i = 1; (i <= todo) && (Interrupt == NONE); i += tmp) {
00227                 tmp = InstrStep();
00228                 total = (total + tmp) % 0xFFFFFFF0;
00229         }
00230         if (Interrupt != NONE) {
00231                 switch (Interrupt) {
00232                 case IRQ:
00233                         Irq();
00234                         break;
00235                 case NMI:
00236                         Nmi();
00237                         break;
00238                 case RESET:
00239                         Reset();
00240                         break;
00241                 }
00242         }
00243         Interrupt = NONE;
00244 }
00245 
00250 void ExitCpuThread()
00251 {
00252         Running = FALSE;
00253 }

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