OSDN Git Service

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