OSDN Git Service

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