mmvm.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. #include "../mmage/mmage.h"
  2. #include "../mmage/preference.h"
  3. #include "../resource/resource.h"
  4. #include "wwstruct.h"
  5. #include "mmvm.h"
  6. #include "filesys.h"
  7. #include "kanjifont.h"
  8. #include <windows.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <ctype.h>
  12. #include <process.h>
  13. #include <tchar.h>
  14. #ifdef __GNUC__
  15. #if defined(_MBCS)
  16. #define _tmakepath _makepath
  17. #define _tsplitpath _splitpath
  18. #elif defined(_UNICODE)
  19. #define _tmakepath _wmakepath
  20. #define _tsplitpath _wplitpath
  21. #else
  22. #define _tmakepath _makepath
  23. #define _tsplitpath _splitpath
  24. #endif
  25. #endif
  26. /*
  27. IL は CS:ip が特定アドレスになったところでトラップすることで実現する
  28. IlibIL は 0100:0000 に配置。
  29. IlibIL の関数は 0100:0000 から 1byte ずつ順に配置されているように見せる。
  30. _get_info() は 0100:0000
  31. _open() は 0100:0001
  32. _open_system() は 0100:0002
  33. という具合に。
  34. Ilib の ILInfo は 0100:0100 に配置。
  35. Ilib の ILInfo が指す文字列は 0100:(0100 + ILInfo のサイズ) に配置。
  36. なので IL の関数の数は(_get_info() を含めて) 0x0100 個まで。
  37. ProcIL は 0200:0000 から、FsIL は 0300:0000 から同じように配置。
  38. こんなんでええんか?
  39. */
  40. #define MMVM_ILIBILADDR 0x01000000
  41. #define MMVM_PROCILADDR 0x02000000
  42. #define MMVM_FSILADDR 0x03000000
  43. static MMVM_IL mmvmil_struct;
  44. static MMVM mmvm_struct;
  45. static MMVM_APPINFO appinfo_struct;
  46. LPMMVM mmvm;
  47. BYTE *memory;
  48. static void HandleIlibIL();
  49. static void HandleProcIL();
  50. static LRESULT CALLBACK GetArgument(HWND, UINT, WPARAM, LPARAM);
  51. static void StartThread(LPVOID arg);
  52. BOOL CreateVM() {
  53. LPBYTE rom0;
  54. TCHAR fontfile[MAX_PATH + 1];
  55. char drive[_MAX_DRIVE + 1];
  56. char dir[_MAX_DIR + 1];
  57. mmvm = &mmvm_struct;
  58. mmvm->memory = memory = (BYTE *)malloc(MEMORYSIZE);
  59. if(!memory) {
  60. return FALSE;
  61. }
  62. memset(memory, 0, MEMORYSIZE);
  63. mmvm->il = &mmvmil_struct;
  64. mmvm->appinfo = &appinfo_struct;
  65. mmvm->il->il.farptr = MMVM_ILIBILADDR;
  66. strcpy(mmvm->il->ilinfo.className, "ILibIL");
  67. strcpy(mmvm->il->ilinfo.name, "ILibIL");
  68. strcpy(mmvm->il->ilinfo.version, "1.0");
  69. strcpy(mmvm->il->ilinfo.description, "MMVM default ILibIL");
  70. mmvm->il->ilinfo.depends = NULL;
  71. mmvm->il->proc.farptr = MMVM_PROCILADDR;
  72. strcpy(mmvm->il->procinfo.className, "ProcIL");
  73. strcpy(mmvm->il->procinfo.name, "ProcIL");
  74. strcpy(mmvm->il->procinfo.version, "1.0");
  75. strcpy(mmvm->il->procinfo.description, "MMVM default ProcIL");
  76. mmvm->il->procinfo.depends = NULL;
  77. mmvm->il->fs.farptr = MMVM_FSILADDR;
  78. strcpy(mmvm->il->fsinfo.className, "FsIL");
  79. strcpy(mmvm->il->fsinfo.name, "FsIL");
  80. strcpy(mmvm->il->fsinfo.version, "1.0");
  81. strcpy(mmvm->il->fsinfo.description, "MMVM default FsIL");
  82. mmvm->il->fsinfo.depends = NULL;
  83. mmvm->swork = (LPWW_SRAMWork)&memory[SRAMWORK_SEG << 4];
  84. rom0 = (LPBYTE)&(mmvm->swork->_root_fs_entries[DIRENT_ROM0]);
  85. mmvm->cwfs.segoff.seg = SRAMWORK_SEG;
  86. mmvm->cwfs.segoff.off = rom0 - (LPBYTE)(mmvm->swork);
  87. mmvm->lcdseg = 0;
  88. GetModuleFileName(NULL, fontfile, MAX_PATH);
  89. _tsplitpath(fontfile, drive, dir, NULL, NULL);
  90. _tmakepath(fontfile, drive, dir, ELISA_FONTFILE, NULL);
  91. InitKanjiFont(fontfile);
  92. return TRUE;
  93. }
  94. void InitVM() {
  95. LPWW_IlibIL ilil;
  96. LPWW_ProcIL procil;
  97. LPWW_FsIL fsil;
  98. LPWW_ILInfo ilinfo, procinfo, fsinfo;
  99. unsigned int tmp1;
  100. init_cpu();
  101. sregs[CS] = APP_CSEG;
  102. sregs[DS] = APP_CSEG; // ここでは何に設定しても同じ
  103. sregs[ES] = APP_CSEG; // ここでは何に設定しても同じ
  104. sregs[SS] = STACK_SEG;
  105. ip = 0;
  106. c_cs = SegToMemPtr(CS);
  107. c_ds = SegToMemPtr(DS);
  108. c_es = SegToMemPtr(ES);
  109. c_stack = c_ss = SegToMemPtr(SS);
  110. // set return address
  111. tmp1 = (WORD)(ReadWord(&wregs[SP]) - 2);
  112. PutMemW(c_stack, tmp1, 0x0010);
  113. tmp1 = (WORD)(tmp1 - 2);
  114. PutMemW(c_stack, tmp1, 0x0000);
  115. WriteWord(&wregs[SP], tmp1);
  116. ilil = (LPWW_IlibIL)&memory[FARPTR2ADDR(mmvm->il->il)];
  117. ilil->super.n_methods = 2;
  118. ilil->super.link_pos.farptr = GETFARPTR(mmvm->il->il);
  119. ilil->super._get_info.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->il), 0);
  120. ilil->_open.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->il), 1);
  121. ilil->_open_system.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->il), 2);
  122. ilinfo = (LPWW_ILInfo)&memory[GETSEG(mmvm->il->il) << 4 | 0x0100];
  123. memcpy((LPBYTE)ilinfo + sizeof(WW_ILInfo), &mmvm->il->ilinfo, sizeof(mmvm->il->ilinfo));
  124. ilinfo->className.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->il), 0x0100 + sizeof(WW_ILInfo) );
  125. ilinfo->name.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->il), 0x0100 + sizeof(WW_ILInfo) + 32);
  126. ilinfo->version.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->il), 0x0100 + sizeof(WW_ILInfo) + 64);
  127. ilinfo->description.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->il), 0x0100 + sizeof(WW_ILInfo) + 96);
  128. ilinfo->depends.farptr = SEGOFF2FARPTR(0, 0);
  129. procil = (LPWW_ProcIL)&memory[FARPTR2ADDR(mmvm->il->proc)];
  130. procil->super.n_methods = 8;
  131. procil->super.link_pos.farptr = GETFARPTR(mmvm->il->proc);
  132. procil->super._get_info.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 0);
  133. procil->_load.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 1);
  134. procil->_run.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 2);
  135. procil->_exec.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 3);
  136. procil->_exit.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 4);
  137. procil->_yield.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 5);
  138. procil->_suspend.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 6);
  139. procil->_resume.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 7);
  140. procil->_swap.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 8);
  141. procinfo = (LPWW_ILInfo)&memory[GETSEG(mmvm->il->proc) << 4 | 0x0100];
  142. memcpy((LPBYTE)procinfo + sizeof(WW_ILInfo), &mmvm->il->procinfo, sizeof(mmvm->il->procinfo));
  143. procinfo->className.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 0x0100 + sizeof(WW_ILInfo) );
  144. procinfo->name.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 0x0100 + sizeof(WW_ILInfo) + 32);
  145. procinfo->version.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 0x0100 + sizeof(WW_ILInfo) + 64);
  146. procinfo->description.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 0x0100 + sizeof(WW_ILInfo) + 96);
  147. procinfo->depends.farptr = SEGOFF2FARPTR(0, 0);
  148. fsil = (LPWW_FsIL)&memory[FARPTR2ADDR(mmvm->il->fs)];
  149. fsil->super.link_pos.farptr = GETFARPTR(mmvm->il->il);
  150. fsil->super.n_methods = 18;
  151. fsil->super._get_info.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 0);
  152. fsil->_entries.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 1);
  153. fsil->_n_entries.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 2);
  154. fsil->_getent.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 3);
  155. fsil->_findent.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 4);
  156. fsil->_mmap.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 5);
  157. fsil->_open.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 6);
  158. fsil->_close.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 7);
  159. fsil->_read.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 8);
  160. fsil->_write.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 9);
  161. fsil->_lseek.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 10);
  162. fsil->_chmod.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 11);
  163. fsil->_freeze.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 12);
  164. fsil->_melt.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 13);
  165. fsil->_creat.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 14);
  166. fsil->_unlink.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 15);
  167. fsil->_newfs.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 16);
  168. fsil->_defrag.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 17);
  169. fsil->_space.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 18);
  170. fsinfo = (LPWW_ILInfo)&memory[GETSEG(mmvm->il->fs) << 4 | 0x0100];
  171. memcpy((LPBYTE)fsinfo + sizeof(WW_ILInfo), &mmvm->il->fsinfo, sizeof(mmvm->il->fsinfo));
  172. fsinfo->className.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 0x0100 + sizeof(WW_ILInfo) );
  173. fsinfo->name.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 0x0100 + sizeof(WW_ILInfo) + 32);
  174. fsinfo->version.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 0x0100 + sizeof(WW_ILInfo) + 64);
  175. fsinfo->description.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 0x0100 + sizeof(WW_ILInfo) + 96);
  176. fsinfo->depends.farptr = SEGOFF2FARPTR(0, 0);
  177. mmvm->lcdseg = 0;
  178. mmvm->appinfo->loadended = FALSE;
  179. mmvm->appinfo->maincalled = FALSE;
  180. }
  181. void UpdateVM() {
  182. LPWW_PCB pcb;
  183. unsigned int tmp1;
  184. WORD argptr;
  185. WORD argc;
  186. WORD args[256];
  187. int i;
  188. BOOL quote;
  189. if(sregs[CS] == GETSEG(mmvm->il->il)) {
  190. HandleIlibIL();
  191. return;
  192. }
  193. if(sregs[CS] == GETSEG(mmvm->il->proc)) {
  194. HandleProcIL();
  195. return;
  196. }
  197. if(sregs[CS] == GETSEG(mmvm->il->fs)) {
  198. HandleFsIL(mmvm);
  199. return;
  200. }
  201. if(sregs[CS] == 0x0010 && ip == 0x0000) { // if load routine returned
  202. mmvm->appinfo->loadended = TRUE;
  203. ip = wregs[AX];
  204. sregs[CS] = wregs[DX];
  205. c_cs = SegToMemPtr(CS);
  206. c_ds = SegToMemPtr(DS);
  207. c_es = SegToMemPtr(ES);
  208. c_stack = c_ss = SegToMemPtr(SS);
  209. pcb = (LPWW_PCB)SegToMemPtr(ES);
  210. // init dseg_start
  211. pcb->pid = 1;
  212. pcb->ppid = 0;
  213. pcb->pcbid = 1;
  214. pcb->ppcbid = 0;
  215. pcb->cwfs.farptr = GETFARPTR(mmvm->cwfs);
  216. pcb->ilib.farptr = GETFARPTR(mmvm->il->il);
  217. pcb->proc.farptr = GETFARPTR(mmvm->il->proc);
  218. pcb->resource.farptr = (sregs[CS] << 16) | mmvm->appinfo->fent.resource;
  219. strcpy(pcb->currentdir, "/rom0");
  220. argptr = pcb->argv;
  221. argc = 0;
  222. args[0] = argptr;
  223. quote = FALSE;
  224. for(i = 0; i < (int)strlen(mmvm->appinfo->commandline) + 1; i++) {
  225. if(mmvm->appinfo->commandline[i] == TEXT('\\')) {
  226. if(i < (int)strlen(mmvm->appinfo->commandline)) {
  227. i++;
  228. memory[(FIRST_DSEG << 4) + argptr++] = mmvm->appinfo->commandline[i];
  229. }
  230. } else if(_istspace(mmvm->appinfo->commandline[i]) && !quote) {
  231. argc++;
  232. memory[(FIRST_DSEG << 4) + argptr++] = TEXT('\0');
  233. args[argc] = argptr;
  234. while(isspace(mmvm->appinfo->commandline[i]))
  235. i++;
  236. if(!mmvm->appinfo->commandline[i])
  237. argc--;
  238. i--;
  239. } else if(quote && (mmvm->appinfo->commandline[i] == TEXT('\"') || mmvm->appinfo->commandline[i] == TEXT('\''))) {
  240. quote = FALSE;
  241. } else if(!quote && (mmvm->appinfo->commandline[i] == TEXT('\"') || mmvm->appinfo->commandline[i] == TEXT('\''))) {
  242. quote = TRUE;
  243. } else {
  244. memory[(FIRST_DSEG << 4) + argptr++] = mmvm->appinfo->commandline[i];
  245. }
  246. }
  247. argc++;
  248. // push argv
  249. tmp1 = (WORD)(ReadWord(&wregs[SP]) - 2);
  250. PutMemW(c_stack, tmp1, argptr);
  251. pcb->argv = argptr;
  252. // set argv
  253. for(i = 0; i < argc; i++) {
  254. memory[(FIRST_DSEG << 4) + argptr++] = args[i] & 0xff;
  255. memory[(FIRST_DSEG << 4) + argptr++] = (args[i] >> 8) & 0xff;
  256. }
  257. // push argc
  258. tmp1 = (WORD)(tmp1 - 2);
  259. PutMemW(c_stack, tmp1, argc);
  260. // set _heap address
  261. pcb->heap = argptr;
  262. // push return address
  263. tmp1 = (WORD)(tmp1 - 2);
  264. PutMemW(c_stack, tmp1, 0x0010);
  265. tmp1 = (WORD)(tmp1 - 2);
  266. PutMemW(c_stack, tmp1, 0x0000);
  267. WriteWord(&wregs[SP], tmp1);
  268. memcpy(&memory[FINAL_DSEG << 4], &memory[FIRST_DSEG << 4], 0x10000);
  269. sregs[DS] = FINAL_DSEG; // どうせ run ルーチンで変更されるけど
  270. sregs[ES] = FINAL_DSEG; // どうせ run ルーチンで変更されるけど
  271. c_ds = SegToMemPtr(DS);
  272. c_es = SegToMemPtr(ES);
  273. InitFilesys(mmvm);
  274. }
  275. // main が呼ばれる直前に無理矢理 DS、ES を 0x2000 にする
  276. if(mmvm->appinfo->loadended && !mmvm->appinfo->maincalled && *(c_cs + ip) == 0xe8) {
  277. sregs[DS] = FINAL_DSEG;
  278. sregs[ES] = FINAL_DSEG;
  279. c_ds = SegToMemPtr(DS);
  280. c_es = SegToMemPtr(ES);
  281. mmvm->appinfo->maincalled = TRUE;
  282. }
  283. }
  284. void OpenDlgAndRun() {
  285. OPENFILENAME ofn;
  286. TCHAR filename[MAX_PATH + 1];
  287. TCHAR wndName[1024];
  288. filename[0] = TEXT('\0');
  289. ZeroMemory(&ofn, sizeof(OPENFILENAME));
  290. ofn.lStructSize = sizeof(OPENFILENAME);
  291. ofn.hwndOwner = wonw32ctx->hWnd;
  292. ofn.lpstrFilter = TEXT("WonderWitch 転送形式ファイル (*.fx)\0*.fx\0すべてのファイル (*.*)\0*.*\0\0");
  293. ofn.lpstrFile = filename;
  294. ofn.nMaxFile = sizeof(filename);
  295. ofn.Flags = OFN_FILEMUSTEXIST;
  296. if(GetOpenFileName(&ofn)) {
  297. if(wonw32ctx->running) {
  298. StopExecution(5000);
  299. }
  300. wonw32ctx->loaded = LoadFXFile(filename, APP_CSEG, &(mmvm->appinfo->fent));
  301. if(!wonw32ctx->loaded) {
  302. SetWindowText(wonw32ctx->hWnd, THIS_APP_TITLE);
  303. MessageBox(wonw32ctx->hWnd, "ファイルの読み込みに失敗しました", NULL, MB_OK);
  304. wonw32ctx->loaded = FALSE;
  305. return;
  306. }
  307. wsprintf(wndName, "%s - %s", (LPCTSTR)mmvm->appinfo->fent.info, THIS_APP_TITLE);
  308. SetWindowText(wonw32ctx->hWnd, wndName);
  309. sprintf(mmvm->appinfo->commandline, "%s ", mmvm->appinfo->fent.name);
  310. if(mmconfig->queryarg) {
  311. DialogBoxParam(wonw32ctx->hInst, MAKEINTRESOURCE(IDD_ARGUMENT), wonw32ctx->hWnd,
  312. (DLGPROC)GetArgument, (LPARAM)mmvm->appinfo->commandline);
  313. } else {
  314. sprintf(mmvm->appinfo->commandline, "%s %s", mmvm->appinfo->fent.name, mmconfig->argument);
  315. }
  316. RunWWApp();
  317. }
  318. return;
  319. }
  320. void OpenAndRun(LPCTSTR filename, LPCTSTR cmdline) {
  321. TCHAR wndName[1024];
  322. if(wonw32ctx->running) {
  323. StopExecution(5000);
  324. }
  325. wonw32ctx->loaded = LoadFXFile(filename, APP_CSEG, &(mmvm->appinfo->fent));
  326. if(!wonw32ctx->loaded) {
  327. SetWindowText(wonw32ctx->hWnd, THIS_APP_TITLE);
  328. MessageBox(wonw32ctx->hWnd, "ファイルの読み込みに失敗しました", NULL, MB_OK);
  329. wonw32ctx->loaded = FALSE;
  330. return;
  331. }
  332. wsprintf(wndName, "%s - %s", (LPCTSTR)mmvm->appinfo->fent.info, THIS_APP_TITLE);
  333. SetWindowText(wonw32ctx->hWnd, wndName);
  334. sprintf(mmvm->appinfo->commandline, "%s %s", mmvm->appinfo->fent.name, cmdline);
  335. RunWWApp();
  336. return;
  337. }
  338. void RunWWApp() {
  339. wonw32ctx->cputhread = (HANDLE)_beginthread(StartThread, 0, NULL);
  340. }
  341. BOOL LoadFXFile(LPCTSTR filename, WORD seg, WW_FENT_T *fentp) {
  342. LPBYTE b;
  343. int c;
  344. FILE *fp;
  345. int i;
  346. b = (LPBYTE)fentp;
  347. fp = fopen(filename, "rb");
  348. if(!fp)
  349. goto error;
  350. for(i = 0; i < 64; i++) {
  351. if((c = fgetc(fp)) == EOF)
  352. goto error;
  353. b[i] = (BYTE)(c & 0xff);
  354. if((i == 0) && (b[i] != 0x23)) goto error;
  355. if((i == 1) && (b[i] != 0x21)) goto error;
  356. if((i == 2) && (b[i] != 0x77)) goto error;
  357. if((i == 3) && (b[i] != 0x73)) goto error;
  358. }
  359. for(i = 0; i < 64; i++) {
  360. if((c = fgetc(fp)) == EOF)
  361. goto error;
  362. b[i] = (BYTE)(c & 0xff);
  363. }
  364. i = seg << 4;
  365. while((c = fgetc(fp)) != EOF)
  366. memory[i++] = (BYTE)(c & 0xff);
  367. return TRUE;
  368. error:
  369. if(fp)
  370. fclose(fp);
  371. return FALSE;
  372. }
  373. static LRESULT CALLBACK GetArgument( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
  374. {
  375. static LPTSTR arg;
  376. HWND argwnd;
  377. HWND ok;
  378. switch( message )
  379. {
  380. case WM_INITDIALOG:
  381. arg = (LPTSTR)lParam;
  382. argwnd = GetDlgItem(hDlg, IDC_ARGUMENT);
  383. SetWindowText(argwnd, arg);
  384. SendMessage(argwnd, EM_SETSEL, -1, 0);
  385. return TRUE;
  386. case WM_COMMAND:
  387. argwnd = GetDlgItem(hDlg, IDC_ARGUMENT);
  388. GetWindowText(argwnd, arg, 1024);
  389. if( LOWORD(wParam) == IDOK) {
  390. if(lstrlen(arg) > 0)
  391. {
  392. EndDialog(hDlg, 0);
  393. return TRUE;
  394. }
  395. } else if(LOWORD(wParam) == IDC_ARGUMENT && HIWORD(wParam) == EN_UPDATE) {
  396. ok = GetDlgItem(hDlg, IDOK);
  397. if(lstrlen(arg) > 0) {
  398. EnableWindow(ok, TRUE);
  399. } else {
  400. EnableWindow(ok, FALSE);
  401. }
  402. return TRUE;
  403. }
  404. break;
  405. }
  406. return FALSE;
  407. }
  408. void Restart() {
  409. if(wonw32ctx->running) {
  410. StopExecution(5000);
  411. }
  412. RunWWApp();
  413. }
  414. void StopExecution(DWORD wait) {
  415. wonw32ctx->running = FALSE;
  416. PulseEvent(wonw32ctx->syncevent);
  417. TerminateThread(wonw32ctx->cputhread, 0);
  418. if(WaitForSingleObject(wonw32ctx->cputhread, wait) != WAIT_OBJECT_0) {
  419. MessageBox(wonw32ctx->hWnd, TEXT("MiracleMage 内部エラーです\nMiracleMage を再起動してください"), NULL, MB_OK);
  420. }
  421. }
  422. void StartThread(LPVOID arg) {
  423. wonw32ctx->running = TRUE;
  424. InitVM();
  425. InvalidateRect(wonw32ctx->hWnd, NULL, FALSE);
  426. UpdateWindow(wonw32ctx->hWnd);
  427. while(wonw32ctx->running) {
  428. execute();
  429. UpdateVM();
  430. }
  431. CloseFilesys();
  432. mmvm->lcdseg = 0;
  433. InvalidateRect(wonw32ctx->hWnd, NULL, FALSE);
  434. UpdateWindow(wonw32ctx->hWnd);
  435. _endthread();
  436. }
  437. static void HandleIlibIL() {
  438. WW_FARPTR ilname;
  439. WW_FARPTR ilbuf;
  440. switch(ip) {
  441. case 0: // ILInfo far *super._get_info();
  442. wregs[DX] = GETSEG(mmvm->il->il);
  443. wregs[AX] = 0x0100;
  444. break;
  445. case 1: // int _open(char far *ilname, IL far *ilbuf);
  446. case 2: // int _open_system(char far *ilname, IL far *ilbuf);
  447. ilname = *((WW_FARPTR *)GetArgAddr(0));
  448. ilbuf = *((WW_FARPTR *)GetArgAddr(4));
  449. memory[FARPTR2ADDR(ilbuf) ] = 0;
  450. memory[FARPTR2ADDR(ilbuf) + 1] = 0;
  451. memory[FARPTR2ADDR(ilbuf) + 2] = 0;
  452. memory[FARPTR2ADDR(ilbuf) + 3] = 0;
  453. wregs[AX] = 0xffff;
  454. break;
  455. default:
  456. wregs[AX] = 0xffff;
  457. break;
  458. }
  459. ILReturn();
  460. }
  461. static void HandleProcIL() {
  462. switch(ip) {
  463. case 0: // ILInfo far *super._get_info();
  464. wregs[DX] = GETSEG(mmvm->il->proc);
  465. wregs[AX] = 0x0100;
  466. break;
  467. default:
  468. wregs[AX] = 0xffff;
  469. break;
  470. }
  471. ILReturn();
  472. }
  473. void ILReturn() {
  474. unsigned tmp = ReadWord(&wregs[SP]);
  475. ip = GetMemW(c_stack,tmp);
  476. tmp = (WORD)(tmp+2);
  477. sregs[CS] = GetMemW(c_stack,tmp);
  478. c_cs = SegToMemPtr(CS);
  479. tmp += 2;
  480. WriteWord(&wregs[SP],tmp);
  481. }
  482. LPBYTE GetArgAddr(int pos) {
  483. return c_stack + ReadWord(&wregs[SP]) + 4 + pos;
  484. }