OSDN Git Service

キーボード関連の構造体化
[heavyosecpu/HeavyOSECPU.git] / function.c
1 #include "osecpu.h"\r
2 #include "jitc.h"\r
3 \r
4 extern unsigned char fontdata[];    // @fontdata.c\r
5 \r
6 const char *searchArg(int argc, const char **argv, const char *tag, int i)\r
7 {\r
8         // 引数リストargvの中から、文字列tagが前方一致する引数のi番目を探し出し、\r
9         // その引数の文字列の、tagに続く部分の文字へのポインタを返す。\r
10         int j, l;\r
11         const char *r = NULL;\r
12         \r
13         if (tag != NULL) {\r
14                 l = (int)strlen(tag);\r
15                 for (j = 1; j < argc; j++) {\r
16                         if (strncmp(argv[j], tag, l) == 0) {\r
17                                 r = argv[j] + l;\r
18                                 if (i == 0){\r
19                                         break;\r
20                                 }\r
21                                 i--;\r
22                         }\r
23                 }\r
24         }\r
25         /*\r
26          // 未使用\r
27         else {\r
28                 for (j = 1; j < argc; j++) {\r
29                         if (strchr(argv[j], ':') == NULL) {\r
30                                 r = argv[j];\r
31                                 if (i == 0){\r
32                                         break;\r
33                                 }\r
34                                 i--;\r
35                         }\r
36                 }\r
37         }\r
38          */\r
39         if (i != 0){\r
40                 r = NULL;\r
41         }\r
42         return r;\r
43 }\r
44 \r
45 void devFunc0001(int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r)\r
46 {\r
47         // OSASK文字列の出力\r
48         while (len > 0) {\r
49                 putOsaskChar(*puc++, r);\r
50                 len--;\r
51         }\r
52         return;\r
53 }\r
54 \r
55 void devFunc0006(int mod, int sx, int sy, int x, int y, int c, int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r)\r
56 {\r
57         // drawString\r
58         int xx;\r
59         int yy;\r
60         int i, ddx, ddy, j, ch, dx, dy;\r
61         \r
62         if (sy == 0){\r
63                 sy = sx;\r
64         }\r
65         xx = x + sx * 8;\r
66         yy = y + sy * 16;\r
67         if (xx <= 0 || xx > mainWindow.xsize || yy <= 0 || yy > mainWindow.ysize){\r
68                 (*(r->errHndl))(r);\r
69         }\r
70         if (x < 0 || x >= mainWindow.xsize || y < 0 || y >= mainWindow.ysize){\r
71                 (*(r->errHndl))(r);\r
72         }\r
73         \r
74         \r
75         if ((mod & 3) == 0 && sx == 1 && sy == 1) {\r
76                 // メジャーケースを高速化.\r
77                 for (i = 0; i < len; i++) {\r
78                         ch = puc[i];\r
79                         if (0x10 <= ch && ch <= 0x1f)\r
80                                 ch = "0123456789ABCDEF"[ch & 0x0f];\r
81                         for (dy = 0; dy < 16; dy++) {\r
82                                 j = fontdata[(ch - ' ') * 16 + dy];\r
83                                 for (dx = 0; dx < 8; dx++) {\r
84                                         if ((j & (0x80 >> dx)) != 0){\r
85                                                 mainWindow.vram[(x + dx) + (y + dy) * mainWindow.xsize] = c;\r
86                                         }\r
87                                 }\r
88                         }\r
89                         x += 8;\r
90                 }\r
91                 return;\r
92         }\r
93         for (i = 0; i < len; i++) {\r
94                 ch = puc[i];\r
95                 if (0x10 <= ch && ch <= 0x1f)\r
96                         ch = "0123456789ABCDEF"[ch & 0x0f];\r
97                 for (dy = 0; dy < 16; dy++) {\r
98                         j = fontdata[(ch - ' ') * 16 + dy];\r
99                         for (ddy = 0; ddy < sy; ddy++) {\r
100                                 for (dx = 0; dx < 8; dx++) {\r
101                                         if ((j & (0x80 >> dx)) != 0) {\r
102                                                 for (ddx = 0; ddx < sx; ddx++) {\r
103                                                         switch (mod & 3) {\r
104                                                                 case 0:\r
105                                                                         mainWindow.vram[x + y * mainWindow.xsize] = c;\r
106                                                                         break;\r
107                                                                 case 1:\r
108                                                                         mainWindow.vram[x + y * mainWindow.xsize] |= c;\r
109                                                                         break;\r
110                                                                 case 2:\r
111                                                                         mainWindow.vram[x + y * mainWindow.xsize] ^= c;\r
112                                                                         break;\r
113                                                                 case 3:\r
114                                                                         mainWindow.vram[x + y * mainWindow.xsize] &= c;\r
115                                                                         break;\r
116                                                         }\r
117                                                         x++;\r
118                                                 }\r
119                                         } else{\r
120                                                 x += sx;\r
121                                         }\r
122                                 }\r
123                                 x -= sx * 8;\r
124                                 y++;\r
125                         }\r
126                 }\r
127                 x += sx * 8;\r
128                 y -= sy * 16;\r
129         }\r
130         return;\r
131 }\r
132 \r
133 void devFunc0004(int mod, int x0, int y0, int x1, int y1, int c)\r
134 {\r
135         // FillRect\r
136         int x, y;\r
137         if (mod == 0) {\r
138                 for (y = y0; y <= y1; y++) {\r
139                         for (x = x0; x <= x1; x++) {\r
140                                 mainWindow.vram[x + y * mainWindow.xsize] = c;\r
141                         }\r
142                 }\r
143         }\r
144         else {\r
145                 for (y = y0; y <= y1; y++) {\r
146                         for (x = x0; x <= x1; x++) {\r
147                                 switch (mod) {\r
148                                         case 1:\r
149                                                 mainWindow.vram[x + y * mainWindow.xsize] |= c;\r
150                                                 break;\r
151                                         case 2:\r
152                                                 mainWindow.vram[x + y * mainWindow.xsize] ^= c;\r
153                                                 break;\r
154                                         case 3:\r
155                                                 mainWindow.vram[x + y * mainWindow.xsize] &= c;\r
156                                                 break;\r
157                                 }\r
158                         }\r
159                 }\r
160         }\r
161         return;\r
162 }\r
163 \r
164 int devFunc0016(int buflen, unsigned char *buf, int plen, unsigned char *p, int qlen, int *q, HOSECPU_RuntimeEnvironment *r)\r
165 {\r
166         // OSASK文字列への変換?\r
167         int i = 0, base, j, k;\r
168         char sign;\r
169         \r
170         while (plen > 0) {\r
171                 if (i >= buflen){\r
172                         (*(r->errHndl))(r);\r
173                 }\r
174                 if (*p != 0x01) {\r
175                         buf[i++] = *p++;\r
176                         plen--;\r
177                         continue;\r
178                 }\r
179                 p++;\r
180                 plen--;\r
181                 if (qlen < 4){\r
182                         (*(r->errHndl))(r);\r
183                 }\r
184                 base = q[0];\r
185                 sign = 0;\r
186                 if (base == 0){\r
187                         base = 16;\r
188                 }\r
189 #if (REVISION == 1)\r
190                 if (base == -3){\r
191                         base = 10;\r
192                 }\r
193 #endif\r
194                 if (base == -1){\r
195                         base = 10;\r
196                 }\r
197                 if (base < 0 || base > 16){\r
198                         (*(r->errHndl))(r);\r
199                 }\r
200                 if (q[1] + i > buflen){\r
201                         (*(r->errHndl))(r);\r
202                 }\r
203                 j = q[3];\r
204                 if ((q[2] & 4) == 0) {\r
205                         // jは符号付き整数.\r
206                         if ((q[2] & 8) != 0 && j > 0){\r
207                                 sign = '+';\r
208                         }\r
209                         if (j < 0) {\r
210                                 sign = '-'; j *= -1;\r
211                         }\r
212                 } else{\r
213                         // jは符号無し整数.\r
214                         if ((q[2] & 8) != 0 && j != 0){\r
215                                 sign = '+';\r
216                         }\r
217                 }\r
218                 for (k = q[1] - 1; k >= 0; k--) {\r
219                         buf[i + k] = (j % base) + 0x10;\r
220                         j = ((unsigned)j) / base;\r
221                 }\r
222                 k = 0;\r
223                 if ((q[2] & 2) == 0 && j == 0) {\r
224                         for (k = 0; k < q[1] - 1; k++) {\r
225                                 if (buf[i + k] != 0x10){\r
226                                         break;\r
227                                 }\r
228                                 buf[i + k] = ' ';\r
229                         }\r
230                 }\r
231                 if (sign != 0) {\r
232                         if (k > 0){\r
233                                 k--;\r
234                         }\r
235                         buf[i + k] = sign;\r
236                 }\r
237                 if ((q[2] & 1) != 0 && buf[i] == ' ') {\r
238                         for (j = 0; k < q[1]; k++, j++){\r
239                                 buf[i + j] = buf[i + k];\r
240                         }\r
241                         i += j;\r
242                 } else{\r
243                         i += q[1];\r
244                 }\r
245                 qlen -= 4;\r
246                 q += 4;\r
247         }\r
248         return i;\r
249 }\r
250 \r
251 void devFunc(HOSECPU_RuntimeEnvironment *r)\r
252 {\r
253         FILE *fp;\r
254         int i, c;\r
255         int x, y, len, dx, dy;\r
256         unsigned char *puc;\r
257         unsigned char pucbuf[256];\r
258         \r
259         //サイズを節約するためにEBPを128バイトずらしているのを元に戻す\r
260         r = (HOSECPU_RuntimeEnvironment *) (((char *)r) - jitCompA0001_EBP128);\r
261         \r
262         if (r->winClosed != 0){\r
263                 longjmp(r->setjmpEnv, 1);\r
264         }\r
265         if (0xff44 <= r->ireg[0x30] && r->ireg[0x30] <= 0xff48) {\r
266                 if (mainWindow.vram == NULL) {\r
267                         mainWindow.xsize = 640;\r
268                         mainWindow.ysize = 480;\r
269                         mainWindow.vram = malloc(640 * 480 * 4);\r
270                         drv_openWin(640, 480, (void *)mainWindow.vram, &r->winClosed);\r
271                         r->autoSleep = 1;\r
272                         for (i = 640 * 480 - 1; i >= 0; i--){\r
273                                 mainWindow.vram[i] = 0;\r
274                         }\r
275                 }\r
276         }\r
277         \r
278         switch (r->ireg[0x30]){\r
279                 case 0xff00:\r
280                         printf("R31=%d(dec)\n", r->ireg[0x31]);\r
281                         break;\r
282                         \r
283                 case 0xff01:\r
284                         // junkApi_fopenRead(_filesize, _p, arg)\r
285                         // args: R31=arg, R30=_filesize, P31=_p\r
286                         // retv: R30, P31\r
287                         if (r->buf0 == NULL){\r
288                                 r->buf0 = malloc(1024 * 1024);\r
289                         }\r
290                         if (r->mainArgc <= r->ireg[0x31]) {\r
291                                 fprintf(stderr, "devFunc: error: R30=ff01: argc error: R31=%08X\n", r->ireg[0x31]);\r
292                                 exit(1);\r
293                         }\r
294                         fp = fopen(r->mainArgv[r->ireg[0x31]], "rb");\r
295                         if (fp == NULL) {\r
296                                 fprintf(stderr, "devFunc: error: R30=ff01: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]);\r
297                                 exit(1);\r
298                         }\r
299                         i = (int)fread(r->buf0, 1, 1024 * 1024 - 4, fp);\r
300                         if (i >= 1024 * 1024 - 4 || i < 0) {\r
301                                 fprintf(stderr, "devFunc: error: R30=ff01: fread error: '%s'\n", r->mainArgv[r->ireg[0x31]]);\r
302                                 exit(1);\r
303                         }\r
304                         fclose(fp);\r
305                         r->preg[0x31].p = r->buf0;\r
306                         r->preg[0x31].p0 = r->buf0;\r
307                         r->preg[0x31].p1 = r->buf0 + i;\r
308                         r->preg[0x31].typ = 3; // T_UINT8\r
309                         r->ireg[0x30] = i;\r
310                         break;\r
311                         \r
312                 case 0xff02:\r
313                         // junkApi_fopenWrite(arg, filesize, p)\r
314                         // args: R31=arg, R32=filesize, P31=p\r
315                         // retv: (none)\r
316                         if (r->mainArgc <= r->ireg[0x31]) {\r
317                                 fprintf(stderr, "devFunc: error: R30=ff02: argc error: R31=%08X\n", r->ireg[0x31]);\r
318                                 exit(1);\r
319                         }\r
320                         fp = fopen(r->mainArgv[r->ireg[0x31]], "wb");\r
321                         if (fp == NULL) {\r
322                                 fprintf(stderr, "devFunc: error: R30=ff02: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]);\r
323                                 exit(1);\r
324                         }\r
325                         if (r->ireg[0x32] >= 1024 * 1024 || r->ireg[0x32] < 0){\r
326                                 fprintf(stderr, "devFunc: error: R30=ff02: fwrite error: R02=%08X\n", r->ireg[0x32]);\r
327                                 exit(1);\r
328                         }\r
329                         fwrite(r->preg[0x31].p, 1, r->ireg[0x32], fp);\r
330                         fclose(fp);\r
331                         break;\r
332                         \r
333                 case 0xff03:\r
334                         // junkApi_allocBuf(_p)\r
335                         // args: P31=_p\r
336                         // retv: P31\r
337                         if (r->buf1 == NULL){\r
338                                 r->buf1 = malloc(1024 * 1024);\r
339                         }\r
340                         r->preg[0x31].p = r->buf1;\r
341                         r->preg[0x31].p0 = r->buf1;\r
342                         r->preg[0x31].p1 = r->buf1 + 1024 * 1024;\r
343                         break;\r
344                         \r
345                 case 0xff04:\r
346                         printf("P31.(p-p0)=%d(dec)\n", (int)(r->preg[0x31].p - r->preg[0x31].p0));\r
347                         break;\r
348                         \r
349                 case 0xff05:\r
350                         // junkApi_writeStdout(len, p)\r
351                         // args: R31=len, P31=p\r
352                         // retv: (none)\r
353                         fwrite(r->preg[0x31].p, 1, r->ireg[0x31], stdout);\r
354                         break;\r
355                         \r
356                 case 0xff06:\r
357                         // junkApi_exit(i)\r
358                         // args: R31=i\r
359                         // retv: (none)\r
360                         r->appReturnCode = r->ireg[31];\r
361                         longjmp(r->setjmpEnv, 1);\r
362                         break;\r
363                         \r
364                 case 0xff07:\r
365                         // junkApi_putConstString0(s)\r
366                         // DB(0xff,0x00,0x00); DB%(s,0x00);\r
367                         // マシになった文字列表示.\r
368                         // OSASK文字列に対応.offにすれば通常の文字列処理もできる.\r
369                         // 現状はonのみサポート.\r
370                         checkString(r, 0x31, 0x31);\r
371                         devFunc0001(r->ireg[0x31], r->preg[0x31].p, r);\r
372                         break;\r
373                         \r
374                 case 0xff08:\r
375                         // junkApi_jitc2(_rc, _p, mod, lev, di1, len, s)\r
376                         // R31=mod; R32=lev; R33=di1; R34=len; P31=s; _rc=R30; _p=P31\r
377                         // JITC on JITC\r
378                         // R31: 言語(back-end, front-end, ...\r
379                         // R32: level\r
380                         // R33: debugInfo1\r
381                         checkString(r, 0x34, 0x31);\r
382                         if (r->ireg[0x33] < 0 || r->ireg[0x33] > 15 || r->debugInfo1 > 15){\r
383                                 (*(r->errHndl))(r);\r
384                         }\r
385                         for (i = 0; i < r->maxLabels; i++){\r
386                                 r->label[i].opt = 0;\r
387                         }\r
388                         puc = r->preg[0x31].p;\r
389                         i = jitCompiler(r->jitbuf, r->jitbuf1, puc, puc + r->ireg[0x34], puc, r->label, r->maxLabels, r->ireg[0x32], 0, JITC_NOSTARTUP + 0);\r
390                         if (i == 0) {\r
391                                 i = jitCompiler(r->jitbuf, r->jitbuf1, puc, puc + r->ireg[0x34], puc, r->label, r->maxLabels, r->ireg[0x32], 0, JITC_NOSTARTUP + JITC_PHASE1 + 0);\r
392                                 if (i >= 0) {\r
393                                         r->mapDi1s[r->debugInfo1][r->ireg[0x33]] = 0;\r
394                                         r->ireg[0x30] = 0;\r
395                                         r->preg[0x31].p = r->jitbuf;\r
396                                         r->preg[0x31].typ = 0; // TYP_CODE\r
397                                         r->preg[0x31].p0 = r->jitbuf;\r
398                                         r->preg[0x31].p1 = r->jitbuf + 1;\r
399                                         //int j; for (j = 0; j < i; j++) printf("%02X ", r->jitbuf[j]); putchar('\n');\r
400                                         r->jitbuf += i;\r
401                                         static unsigned char ff08_ret[3] = { 0x1e, 0x3f, 0x30 };\r
402                                         i = jitCompiler(r->jitbuf, r->jitbuf1, ff08_ret, ff08_ret + 3, puc, r->label, r->maxLabels, r->ireg[0x32], -1, JITC_NOSTARTUP + JITC_PHASE1 + 0);\r
403                                         r->jitbuf += i;\r
404                                         break;\r
405                                 }\r
406                         }\r
407                         r->ireg[0x30] = -1;\r
408                         break;\r
409                         \r
410                 case 0xff09:\r
411                         //putStringDec\r
412                         // たぶんbit7を使ったテキストはうまく処理できない(これはもはや仕様にしても問題ないかも).\r
413                         checkString(r, 0x31, 0x31);\r
414                         len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x31], r->preg[0x31].p, r->ireg[0x32], (int *)r->preg[0x32].p, r);\r
415                         devFunc0001(len, pucbuf, r);\r
416                         break;\r
417                         \r
418                 case 0xff40:\r
419                         // junkApi_openWin(xsiz, ysiz) R31=xsiz; R32=ysiz;\r
420                         /* R31とR32でサイズを指定 */\r
421                         mainWindow.xsize = r->ireg[0x31];\r
422                         mainWindow.ysize = r->ireg[0x32];\r
423                         if (mainWindow.xsize <= 0 || mainWindow.ysize <= 0){\r
424                                 (*(r->errHndl))(r);\r
425                         }\r
426                         r->preg[0x31].p = (void *)(mainWindow.vram = malloc(mainWindow.xsize * mainWindow.ysize * 4));\r
427                         r->preg[0x31].p0 = r->preg[0x31].p;\r
428                         r->preg[0x31].p1 = r->preg[0x31].p + mainWindow.xsize * mainWindow.ysize * 4;\r
429                         drv_openWin(r->ireg[0x31], r->ireg[0x32], r->preg[0x31].p, &r->winClosed);\r
430                         //      drv_flshWin(r->ireg[1], r->ireg[2], 0, 0);\r
431                         r->autoSleep = 1;\r
432                         for (i = mainWindow.xsize * mainWindow.ysize - 1; i >= 0; i--){\r
433                                 mainWindow.vram[i] = 0;\r
434                         }\r
435                         break;\r
436                         \r
437                 case 0xff41:\r
438                         // junkApi_flushWin(xsiz, ysiz, x0, y0)\r
439                         // R31=xsiz; R32=ysiz; R33=x0; R34=y0\r
440                         /* R31とR32でサイズを指定、R33とR34でx0,y0指定 */\r
441                         if (r->ireg[0x31] == -1) {\r
442                                 r->ireg[0x31] = mainWindow.xsize; r->ireg[0x33] &= 0;\r
443                         }\r
444                         if (r->ireg[0x32] == -1) {\r
445                                 r->ireg[0x32] = mainWindow.ysize; r->ireg[0x34] &= 0;\r
446                         }\r
447                         checkRect(r, 0x31);\r
448                         drv_flshWin(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34]);\r
449                         break;\r
450                         \r
451                 case 0xff42:\r
452                         // junkApi_sleep(opt, msec) R31=opt; R32=msec\r
453                         // opt:\r
454                         //              1 = ついでにウィンドウを更新する\r
455                         //              2 = キー入力されるまでずっと待つ\r
456                         if (r->ireg[0x32] == -1) {\r
457                                 // sleep forever (事実上実行は終了)\r
458                                 r->autoSleep = 1;\r
459                                 longjmp(r->setjmpEnv, 1);\r
460                         }\r
461                         if (r->ireg[0x32] < 0){\r
462                                 // マイナス秒スリープするなんておかしい\r
463                                 (*(r->errHndl))(r);\r
464                         }\r
465                         //スリープしたので終了時の自動スリープ無効\r
466                         r->autoSleep = 0;\r
467                         if ((r->ireg[0x31] & 1) == 0 && mainWindow.vram != NULL){\r
468                                 // opt1:ついでにウィンドウを更新する\r
469                                 drv_flshWin(mainWindow.xsize, mainWindow.ysize, 0, 0);\r
470                         }\r
471                         for (;;) {\r
472                                 if (r->winClosed != 0){\r
473                                         longjmp(r->setjmpEnv, 1);\r
474                                 }\r
475                                 drv_sleep(r->ireg[0x32]);\r
476                                 if ((r->ireg[0x31] & 2) != 0 && mainKeyboard.c <= 0){\r
477                                         // opt2:キー入力があったので戻る\r
478                                         continue;\r
479                                 }\r
480                                 // 時間指定ならここに来て終了\r
481                                 break;\r
482                         }\r
483                         break;\r
484                         \r
485                 case 0xff43:\r
486                         // junkApi_inkey(_i, mod) R31=mod; _i=R30\r
487                         //  1:peek(キーを「のぞき見る」だけで、バッファは進めない)\r
488                         //  2:stdin\r
489                         //      4,8: ソース指定.\r
490                         //      16: shift, lock系を有効化.\r
491                         //      32: 左右のshift系を区別する.\r
492                         // カーソルキーの左右でR32は減少,増加する。\r
493                         // カーソルキーの上下でR33は減少,増加する。\r
494                         if (r->ireg[0x31] == 2) {\r
495                                 // 標準入力から\r
496                                 r->ireg[0x30] = fgetc(stdin);\r
497                                 if (r->ireg[0x30] == EOF){\r
498                                         r->ireg[0x30] = KEY_EMPTY;\r
499                                 }\r
500                                 break;\r
501                         }\r
502                         r->ireg[0x30] |= -1;\r
503                         if (mainKeyboard.c > 0) {\r
504                                 // 入力された文字がある\r
505                                 r->ireg[0x30] = mainKeyboard.buf[mainKeyboard.r];\r
506                                 if ((r->ireg[0x31] & 16) == 0){\r
507                                         // shift, lockキー([C]マークのあるキー)の無効化\r
508                                         r->ireg[0x30] &= 0x3e3effff;\r
509                                 }\r
510                                 if ((r->ireg[0x31] & 32) == 0){\r
511                                         // 左右の区別を無効化\r
512                                         r->ireg[0x30] |= (r->ireg[0x30] >> 8) & 0xff0000;\r
513                                 }\r
514                                 if ((r->ireg[0x31] & 1) != 0) {\r
515                                         // peekでないならバッファを進める\r
516                                         mainKeyboard.c--;\r
517                                         mainKeyboard.r = (mainKeyboard.r + 1) & (KEYBUFSIZ - 1);\r
518                                 }\r
519                         }\r
520                         r->ireg[0x32] = r->ireg[0x33] = 0;\r
521                         if (r->ireg[0x30] == KEY_LEFT){\r
522                                 r->ireg[0x32]--;\r
523                         }\r
524                         if (r->ireg[0x30] == KEY_UP){\r
525                                 r->ireg[0x33]--;\r
526                         }\r
527                         if (r->ireg[0x30] == KEY_RIGHT){\r
528                                 r->ireg[0x32]++;\r
529                         }\r
530                         if (r->ireg[0x30] == KEY_DOWN){\r
531                                 r->ireg[0x33]++;\r
532                         }\r
533                         break;\r
534                         \r
535                 case 0xff44:\r
536                         // junkApi_drawPoint(mod, x, y, c) R31=mod; R32=x; R33=y; R34=c\r
537                         c = loadColor(r, 0x34);\r
538                         if (r->ireg[0x32] < 0 || r->ireg[0x32] >= mainWindow.xsize ||\r
539                                 r->ireg[0x33] < 0 || r->ireg[0x33] >= mainWindow.ysize){\r
540                                 (*(r->errHndl))(r);\r
541                         }\r
542                         \r
543                         switch ((r->ireg[0x31] & 3)) {\r
544                                 case 0:\r
545                                         mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] = c;\r
546                                         break;\r
547                                 case 1:\r
548                                         mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] |= c;\r
549                                         break;\r
550                                 case 2:\r
551                                         mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] ^= c;\r
552                                         break;\r
553                                 case 3:\r
554                                         mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] &= c;\r
555                                         break;\r
556                         }\r
557                         break;\r
558                         \r
559                 case 0xff45:\r
560                         // junkApi_drawLine(mod, x0, y0, x1, y1, c)     DB(0xfe,0x05,0x01); DDBE(0x0003); R30=0xff45; R31=mod; R32=x0; R33=y0; R34=x1; R35=y1; R36=c\r
561                         //drawLine\r
562                         c = loadColor(r, 0x36);\r
563                         if (r->ireg[0x32] < 0 || r->ireg[0x32] >= mainWindow.xsize ||\r
564                                 r->ireg[0x33] < 0 || r->ireg[0x33] >= mainWindow.ysize){\r
565                                 (*(r->errHndl))(r);\r
566                         }\r
567                         if (r->ireg[0x34] < 0 || r->ireg[0x34] >= mainWindow.xsize ||\r
568                                 r->ireg[0x35] < 0 || r->ireg[0x35] >= mainWindow.ysize){\r
569                                 (*(r->errHndl))(r);\r
570                         }\r
571                         dx = r->ireg[0x34] - r->ireg[0x32];\r
572                         dy = r->ireg[0x35] - r->ireg[0x33];\r
573                         x = r->ireg[0x32] << 10;\r
574                         y = r->ireg[0x33] << 10;\r
575                         if (dx < 0){\r
576                                 dx = -dx;\r
577                         }\r
578                         if (dy < 0){\r
579                                 dy = -dy;\r
580                         }\r
581                         if (dx >= dy) {\r
582                                 len = dx + 1; dx = 1024;\r
583                                 if (r->ireg[0x32] > r->ireg[0x34]){\r
584                                         dx *= -1;\r
585                                 }\r
586                                 if (r->ireg[0x33] > r->ireg[0x35]){\r
587                                         dy *= -1;\r
588                                 }\r
589                                 dy = (dy << 10) / len;\r
590                         } else {\r
591                                 len = dy + 1; dy = 1024;\r
592                                 if (r->ireg[0x33] > r->ireg[0x35]){\r
593                                         dy *= -1;\r
594                                 }\r
595                                 if (r->ireg[0x32] > r->ireg[0x34]){\r
596                                         dx *= -1;\r
597                                 }\r
598                                 dx = (dx << 10) / len;\r
599                         }\r
600                         if ((r->ireg[0x31] & 3) == 0) {\r
601                                 for (i = 0; i < len; i++) {\r
602                                         mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] = c;\r
603                                         x += dx;\r
604                                         y += dy;\r
605                                 }\r
606                                 break;\r
607                         }\r
608                         for (i = 0; i < len; i++) {\r
609                                 //      if ((r->ireg[0x31] & 3) == 0) vram[(x >> 10) + (y >> 10) * v_xsiz] =  c;\r
610                                 switch ((r->ireg[0x31] & 3)) {\r
611                                         case 1:\r
612                                                 mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] |= c;\r
613                                                 break;\r
614                                         case 2:\r
615                                                 mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] ^= c;\r
616                                                 break;\r
617                                         case 3:\r
618                                                 mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] &= c;\r
619                                                 break;\r
620                                         default:\r
621                                                 break;\r
622                                 }\r
623                                 x += dx;\r
624                                 y += dy;\r
625                         }\r
626                         break;\r
627                         \r
628                 case 0xff46:\r
629                         // fillRect(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)\r
630                         c = loadColor(r, 0x36);\r
631                         if (r->ireg[0x32] == -1) { r->ireg[0x32] = mainWindow.xsize; r->ireg[0x34] &= 0; }\r
632                         if (r->ireg[0x33] == -1) { r->ireg[0x33] = mainWindow.ysize; r->ireg[0x35] &= 0; }\r
633                         checkRect(r, 0x32);\r
634                         int mod3 = r->ireg[0x31] & 3, x0 = r->ireg[0x34], y0 = r->ireg[0x35], x1 = r->ireg[0x34] + r->ireg[0x32] - 1, y1 = r->ireg[0x35] + r->ireg[0x33] - 1;\r
635                         if ((r->ireg[0x31] & 0x20) == 0) {\r
636                                 devFunc0004(mod3, x0, y0, x1, y1, c);\r
637                         } else {        // drawRect\r
638                                 devFunc0004(mod3, x0, y0, x1, y0, c);\r
639                                 devFunc0004(mod3, x0, y1, x1, y1, c);\r
640                                 devFunc0004(mod3, x0, y0, x0, y1, c);\r
641                                 devFunc0004(mod3, x1, y0, x1, y1, c);\r
642                         }\r
643                         break;\r
644                         \r
645                 case 0xff47:\r
646                         // fillOval(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)\r
647                         // これの計算精度はアーキテクチャに依存する.\r
648                         c = loadColor(r, 0x36);\r
649                         if (r->ireg[0x32] == -1) {\r
650                                 r->ireg[0x32] = mainWindow.xsize; r->ireg[0x34] &= 0;\r
651                         }\r
652                         if (r->ireg[0x33] == -1) {\r
653                                 r->ireg[0x33] = mainWindow.ysize; r->ireg[0x35] &= 0;\r
654                         }\r
655                         checkRect(r, 0x32);\r
656                         double dcx = 0.5 * (r->ireg[0x32] - 1);\r
657                         double dcy = 0.5 * (r->ireg[0x33] - 1);\r
658                         double dcxy = (dcx + 0.5) * (dcy + 0.5) - 0.1;\r
659                         dcxy *= dcxy;\r
660                         mod3 = r->ireg[0x31] & 3;\r
661                         x1 = r->ireg[0x32];\r
662                         y1 = r->ireg[0x33];\r
663                         if (mod3 == 0 && (r->ireg[0x31] & 0x20) == 0) {\r
664                                 for (y = 0; y < y1; y++) {\r
665                                         double dty = (y - dcy) * dcx;\r
666                                         for (x = 0; x < x1; x++) {\r
667                                                 double dtx = (x - dcx) * dcy;\r
668                                                 if (dtx * dtx + dty * dty > dcxy){\r
669                                                         continue;\r
670                                                 }\r
671                                                 mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] = c;\r
672                                         }\r
673                                 }\r
674                         } else {\r
675 #define DRAWOVALPARAM   1\r
676                                 double dcx1 = 0.5 * (r->ireg[0x32] - (1 + DRAWOVALPARAM * 2));\r
677                                 double dcy1 = 0.5 * (r->ireg[0x33] - (1 + DRAWOVALPARAM * 2));\r
678                                 double dcxy1 = (dcx1 + 0.5) * (dcy1 + 0.5) - 0.1;\r
679                                 dcxy1 *= dcxy1;\r
680                                 for (y = 0; y < y1; y++) {\r
681                                         double dty = (y - dcy) * dcx;\r
682                                         double dty1 = (y - dcy) * dcx1;\r
683                                         for (x = 0; x < x1; x++) {\r
684                                                 double dtx = (x - dcx) * dcy;\r
685                                                 double dtx1 = (x - dcx) * dcy1;\r
686                                                 if (dtx * dtx + dty * dty > dcxy){\r
687                                                         continue;\r
688                                                 }\r
689                                                 if (DRAWOVALPARAM <= x && x < x1 - DRAWOVALPARAM && DRAWOVALPARAM <= y && y < y1 - DRAWOVALPARAM) {\r
690                                                         if (dtx1 * dtx1 + dty1 * dty1 < dcxy1){\r
691                                                                 continue;\r
692                                                         }\r
693                                                 }\r
694                                                 switch (mod3) {\r
695                                                         case 0:\r
696                                                                 mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] = c;\r
697                                                                 break;\r
698                                                         case 1:\r
699                                                                 mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] |= c;\r
700                                                                 break;\r
701                                                         case 2:\r
702                                                                 mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] ^= c;\r
703                                                                 break;\r
704                                                         case 3:\r
705                                                                 mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] &= c;\r
706                                                                 break;\r
707                                                 }\r
708                                         }\r
709                                 }\r
710                         }\r
711                         break;\r
712                         \r
713                 case 0xff48:\r
714                         // drawString(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36, s.len:R37, s.p:P31)\r
715                         checkString(r, 0x37, 0x31);\r
716                         devFunc0006(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34], r->ireg[0x35], loadColor(r, 0x36), r->ireg[0x37], r->preg[0x31].p, r);\r
717                         break;\r
718                         \r
719                 case 0xff49:\r
720                         // junkApi_rand(_r, range) R31=range; _r=R30\r
721                         // **** junkApi_rand(i, max) ****\r
722                         // 0 <= i <= maxとなるiを返す。\r
723                         // max==0のとき、iはSINT32全体を範囲とする乱数となる。\r
724                         r->ireg[0x30] = randGetNextUInt32();\r
725                         if (r->ireg[0x31] > 0){\r
726                                 r->ireg[0x30] = (r->ireg[0x30] & 0x7fffffff) % (r->ireg[0x31] + 1);\r
727                         }\r
728                         break;\r
729                         \r
730                 case 0xff4a:\r
731                         // srand\r
732                         randStatInit(r->ireg[0x31]);\r
733                         break;\r
734                         \r
735                 case 0xff4b:\r
736                         // srand(random)\r
737                         r->ireg[0x30] = (int)(time(NULL) ^ (long)0x55555555);\r
738                         break;\r
739                         \r
740                 case 0xff4c:\r
741                         // drawStringDec\r
742                         checkString(r, 0x37, 0x31);\r
743                         len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x37], r->preg[0x31].p, r->ireg[0x38], (int *)r->preg[0x32].p, r);\r
744                         devFunc0006(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34], r->ireg[0x35], loadColor(r, 0x36), len, pucbuf, r);\r
745                         break;\r
746                         \r
747                 case 0xff4d:\r
748                         // bitblt(mod, xsiz, ysiz, xscale, yscale, x0, y0, lineskip, inv, p_buf, typ0, p_table, typ1); \r
749                         // mod: 0x20:use_table, 0x40:inv_is_visible & typ1_is_color\r
750                         puc = r->preg[0x31].p;\r
751                         mod3 = r->ireg[0x31] & 3;\r
752                         dx = r->ireg[0x34];\r
753                         dy = r->ireg[0x35];\r
754                         if (dy == 0){\r
755                                 dy = dx;\r
756                         }\r
757                         if (r->ireg[0x32] == -1) {\r
758                                 r->ireg[0x32] = mainWindow.xsize / dx; r->ireg[0x36] &= 0;\r
759                         }\r
760                         if (r->ireg[0x33] == -1) {\r
761                                 r->ireg[0x33] = mainWindow.ysize / dy; r->ireg[0x37] &= 0;\r
762                         }\r
763                         for (y = 0; y < r->ireg[0x33]; y++) {\r
764                                 y0 = y * dy + r->ireg[0x37];\r
765                                 for (x = 0; x < r->ireg[0x32]; x++) {\r
766                                         x0 = x * dx + r->ireg[0x36];\r
767                                         c = iColor1[*puc++];\r
768                                         devFunc0004(mod3, x0, y0, x0 + dx, y0 + dy, c);\r
769                                 }\r
770                                 puc += r->ireg[0x38];\r
771                         }\r
772                         break;\r
773                         \r
774                 default:\r
775                         printf("devFunc: error: R30=%08X\n", r->ireg[0x30]);\r
776                         exit(EXIT_FAILURE);\r
777                         \r
778         }\r
779         return;\r
780 }\r
781 \r
782 \r
783 \r