00001
00008
00009
00010
00011 #include <windows.h>
00012
00013
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
00029
00030 DWORD WINAPI CpuThreadFunc(LPVOID lpParam);
00031 void CreateCpuThread();
00032 void ExitCpuThread();
00033 void ContExe();
00034
00035
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;
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
00140
00141 case WAITEND:
00142
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 }