OSDN Git Service

ce9f02031f1dd4a869aab45aca68bc6019b804cf
[heavyosecpu/HeavyOSECPU.git] / HeavyOSECPU / function.c
1 #include "osecpu.h"
2
3 static struct {
4         unsigned stat[4], mat1, mat2, tmat;
5 } randStat;
6
7 void randStatNext()
8 {
9         unsigned x, y;
10         x = (randStat.stat[0] & 0x7fffffff) ^ randStat.stat[1] ^ randStat.stat[2];
11         y = randStat.stat[3];
12         x ^= x << 1;
13         y ^= (y >> 1) ^ x;
14         randStat.stat[1] = randStat.stat[2] ^ (-((int)(y & 1)) & randStat.mat1);
15         randStat.stat[2] = x ^ (y << 10) ^ (-((int)(y & 1)) & randStat.mat2);
16         randStat.stat[3] = y;
17         return;
18 }
19
20 void randStatInit(unsigned seed)
21 {
22         int i;
23         randStat.stat[0] = seed;
24         randStat.stat[1] = randStat.mat1 = 0x8f7011ee;
25         randStat.stat[2] = randStat.mat2 = 0xfc78ff1f;
26         randStat.stat[3] = randStat.tmat = 0x3793fdff;
27         for (i = 1; i < 8; i++)
28                 randStat.stat[i & 3] ^= i + ((unsigned)1812433253) * (randStat.stat[(i - 1) & 3] ^ (randStat.stat[(i - 1) & 3] >> 30));
29         for (i = 0; i < 8; i++)
30                 randStatNext();
31         return;
32 }
33
34 const unsigned char *searchArg(int argc, const unsigned char **argv, const unsigned char *tag, int i)
35 {
36         int j, l;
37         const unsigned char *r = NULL;
38         if (tag != NULL) {
39                 l = strlen(tag);
40                 for (j = 1; j < argc; j++) {
41                         if (strncmp(argv[j], tag, l) == 0) {
42                                 r = argv[j] + l;
43                                 if (i == 0)     break;
44                                 i--;
45                         }
46                 }
47         }
48         else {
49                 for (j = 1; j < argc; j++) {
50                         if (strchr(argv[j], ':') == NULL) {
51                                 r = argv[j];
52                                 if (i == 0)     break;
53                                 i--;
54                         }
55                 }
56         }
57         if (i != 0) r = NULL;
58         return r;
59 }
60
61 void devFunc0001(int len, unsigned char *puc, struct Regs *r)
62 {
63         while (len > 0) {
64                 putOsaskChar(*puc++, r);
65                 len--;
66         }
67         return;
68 }
69
70 void devFunc0006(int mod, int sx, int sy, int x, int y, int c, int len, unsigned char *puc, struct Regs *r)
71 {
72         if (sy == 0) sy = sx;
73         int xx = x + sx * 8;
74         int yy = y + sy * 16;
75         if (xx <= 0 || xx > v_xsiz || yy <= 0 || yy > v_ysiz)
76                 (*(r->errHndl))(r);
77         if (x < 0 || x >= v_xsiz || y < 0 || y >= v_ysiz)
78                 (*(r->errHndl))(r);
79         int i, ddx, ddy, j, ch, dx, dy;
80
81         if ((mod & 3) == 0 && sx == 1 && sy == 1) {
82                 // \83\81\83W\83\83\81[\83P\81[\83X\82ð\8d\82\91¬\89».
83                 for (i = 0; i < len; i++) {
84                         ch = puc[i];
85                         if (0x10 <= ch && ch <= 0x1f)
86                                 ch = "0123456789ABCDEF"[ch & 0x0f];
87                         for (dy = 0; dy < 16; dy++) {
88                                 j = fontdata[(ch - ' ') * 16 + dy];
89                                 for (dx = 0; dx < 8; dx++) {
90                                         if ((j & (0x80 >> dx)) != 0) vram[(x + dx) + (y + dy) * v_xsiz] = c;
91                                 }
92                         }
93                         x += 8;
94                 }
95                 return;
96         }
97         for (i = 0; i < len; i++) {
98                 ch = puc[i];
99                 if (0x10 <= ch && ch <= 0x1f)
100                         ch = "0123456789ABCDEF"[ch & 0x0f];
101                 for (dy = 0; dy < 16; dy++) {
102                         j = fontdata[(ch - ' ') * 16 + dy];
103                         for (ddy = 0; ddy < sy; ddy++) {
104                                 for (dx = 0; dx < 8; dx++) {
105                                         if ((j & (0x80 >> dx)) != 0) {
106                                                 for (ddx = 0; ddx < sx; ddx++) {
107                                                         if ((mod & 3) == 0) vram[x + y * v_xsiz] = c;
108                                                         if ((mod & 3) == 1) vram[x + y * v_xsiz] |= c;
109                                                         if ((mod & 3) == 2) vram[x + y * v_xsiz] ^= c;
110                                                         if ((mod & 3) == 3) vram[x + y * v_xsiz] &= c;
111                                                         x++;
112                                                 }
113                                         }
114                                         else
115                                                 x += sx;
116                                 }
117                                 x -= sx * 8;
118                                 y++;
119                         }
120                 }
121                 x += sx * 8;
122                 y -= sy * 16;
123         }
124         return;
125 }
126
127 void devFunc0004(int mod, int x0, int y0, int x1, int y1, int c)
128 {
129         int x, y;
130         if (mod == 0) {
131                 for (y = y0; y <= y1; y++) {
132                         for (x = x0; x <= x1; x++) {
133                                 vram[x + y * v_xsiz] = c;
134                         }
135                 }
136         }
137         else {
138                 for (y = y0; y <= y1; y++) {
139                         for (x = x0; x <= x1; x++) {
140                                 if (mod == 1) vram[x + y * v_xsiz] |= c;
141                                 if (mod == 2) vram[x + y * v_xsiz] ^= c;
142                                 if (mod == 3) vram[x + y * v_xsiz] &= c;
143                         }
144                 }
145         }
146         return;
147 }
148
149 int devFunc0016(int buflen, unsigned char *buf, int plen, unsigned char *p, int qlen, int *q, struct Regs *r)
150 {
151         int i = 0, base, j, k;
152         char sign;
153         while (plen > 0) {
154                 if (i >= buflen)
155                         (*(r->errHndl))(r);
156                 if (*p != 0x01) {
157                         buf[i++] = *p++;
158                         plen--;
159                         continue;
160                 }
161                 p++;
162                 plen--;
163                 if (qlen < 4)
164                         (*(r->errHndl))(r);
165                 base = q[0];
166                 sign = 0;
167                 if (base == 0) base = 16;
168 #if (REVISION == 1)
169                 if (base == -3) base = 10;
170 #endif
171                 if (base == -1) base = 10;
172                 if (base < 0 || base > 16)
173                         (*(r->errHndl))(r);
174                 if (q[1] + i > buflen)
175                         (*(r->errHndl))(r);
176                 j = q[3];
177                 if ((q[2] & 4) == 0) {
178                         // j\82Í\95\84\8d\86\95t\82«\90®\90\94.
179                         if ((q[2] & 8) != 0 && j > 0) sign = '+';
180                         if (j < 0) { sign = '-'; j *= -1; }
181                 }
182                 else {
183                         // j\82Í\95\84\8d\86\96³\82µ\90®\90\94.
184                         if ((q[2] & 8) != 0 && j != 0) sign = '+';
185                 }
186                 for (k = q[1] - 1; k >= 0; k--) {
187                         buf[i + k] = (j % base) + 0x10;
188                         j = ((unsigned)j) / base;
189                 }
190                 k = 0;
191                 if ((q[2] & 2) == 0 && j == 0) {
192                         for (k = 0; k < q[1] - 1; k++) {
193                                 if (buf[i + k] != 0x10) break;
194                                 buf[i + k] = ' ';
195                         }
196                 }
197                 if (sign != 0) {
198                         if (k > 0) k--;
199                         buf[i + k] = sign;
200                 }
201                 if ((q[2] & 1) != 0 && buf[i] == ' ') {
202                         for (j = 0; k < q[1]; k++, j++)
203                                 buf[i + j] = buf[i + k];
204                         i += j;
205                 }
206                 else
207                         i += q[1];
208                 qlen -= 4;
209                 q += 4;
210         }
211         return i;
212 }
213
214 void devFunc(struct Regs *r)
215 {
216         FILE *fp;
217         r = (struct Regs *) (((char *)r) - 128); /* \83T\83C\83Y\82ð\90ß\96ñ\82·\82é\82½\82ß\82ÉEBP\82ð128\83o\83C\83g\82¸\82ç\82µ\82Ä\82¢\82é\82Ì\82ð\8c³\82É\96ß\82· */
218         int i, c;
219         int x, y, len, dx, dy;
220         unsigned char *puc;
221         unsigned char pucbuf[256];
222         if (r->winClosed != 0)
223                 longjmp(*(r->setjmpEnv), 1);
224         if (0xff44 <= r->ireg[0x30] && r->ireg[0x30] <= 0xff48) {
225                 if (vram == NULL) {
226                         v_xsiz = 640;
227                         v_ysiz = 480;
228                         vram = malloc(640 * 480 * 4);
229                         drv_openWin(640, 480, (void *)vram, &r->winClosed);
230                         r->autoSleep = 1;
231                         for (i = 640 * 480 - 1; i >= 0; i--)
232                                 vram[i] = 0;
233                 }
234         }
235
236         switch (r->ireg[0x30]) {
237         case 0xff00:
238                 printf("R31=%d(dec)\n", r->ireg[0x31]);
239                 break;
240
241         case 0xff01:
242                 /* return: R30, P31 */
243                 if (r->buf0 == NULL)
244                         r->buf0 = malloc(1024 * 1024);
245                 if (r->argc <= r->ireg[0x31]) {
246                         fprintf(stderr, "devFunc: error: R30=ff01: argc error: R31=%08X\n", r->ireg[0x31]);
247                         exit(1);
248                 }
249                 fp = fopen(r->argv[r->ireg[0x31]], "rb");
250                 if (fp == NULL) {
251                         fprintf(stderr, "devFunc: error: R30=ff01: fopen error: '%s'\n", r->argv[r->ireg[0x31]]);
252                         exit(1);
253                 }
254                 i = fread(r->buf0, 1, 1024 * 1024 - 4, fp);
255                 if (i >= 1024 * 1024 - 4 || i < 0) {
256                         fprintf(stderr, "devFunc: error: R30=ff01: fread error: '%s'\n", r->argv[r->ireg[0x31]]);
257                         exit(1);
258                 }
259                 fclose(fp);
260                 r->preg[0x31].p = r->buf0;
261                 r->preg[0x31].p0 = r->buf0;
262                 r->preg[0x31].p1 = r->buf0 + i;
263                 r->preg[0x31].typ = 3; // T_UINT8
264                 r->ireg[0x30] = i;
265                 break;
266
267         case 0xff02:
268                 /* return: none */
269                 if (r->argc <= r->ireg[0x31]) {
270                         fprintf(stderr, "devFunc: error: R30=ff02: argc error: R31=%08X\n", r->ireg[0x31]);
271                         exit(1);
272                 }
273                 fp = fopen(r->argv[r->ireg[0x31]], "wb");
274                 if (fp == NULL) {
275                         fprintf(stderr, "devFunc: error: R30=ff02: fopen error: '%s'\n", r->argv[r->ireg[0x31]]);
276                         exit(1);
277                 }
278                 if (r->ireg[0x32] >= 1024 * 1024 || r->ireg[0x32] < 0){
279                         fprintf(stderr, "devFunc: error: R30=ff02: fwrite error: R02=%08X\n", r->ireg[0x32]);
280                         exit(1);
281                 }
282                 fwrite(r->preg[0x31].p, 1, r->ireg[0x32], fp);
283                 fclose(fp);
284                 break;
285
286         case 0xff03:
287                 /* return: P31 */
288                 if (r->buf1 == NULL)
289                         r->buf1 = malloc(1024 * 1024);
290                 r->preg[0x31].p = r->buf1;
291                 r->preg[0x31].p0 = r->buf1;
292                 r->preg[0x31].p1 = r->buf1 + 1024 * 1024;
293                 break;
294
295         case 0xff04:
296                 printf("P31.(p-p0)=%d(dec)\n", r->preg[0x31].p - r->preg[0x31].p0);
297                 break;
298
299         case 0xff05:
300                 fwrite(r->preg[0x31].p, 1, r->ireg[0x31], stdout);
301                 break;
302
303         case 0xff06:
304                 // R31\82Í\83\8a\83^\81[\83\93\83R\81[\83h.
305                 // \82±\82ê\82ð\94½\89f\82·\82×\82«\82¾\82ª\81A\8c»\8fó\82Í\8eè\94²\82«\82Å\82¢\82Â\82à\90³\8fí\8fI\97¹.
306                 longjmp(*(r->setjmpEnv), 1);
307                 break;
308
309         case 0xff07:
310                 // \83}\83V\82É\82È\82Á\82½\95\8e\9a\97ñ\95\\8e¦.OSASK\95\8e\9a\97ñ\82É\91Î\89\9e.off\82É\82·\82ê\82Î\92Ê\8fí\82Ì\95\8e\9a\97ñ\8f\88\97\9d\82à\82Å\82«\82é.\8c»\8fó\82Íon\82Ì\82Ý\83T\83|\81[\83g.
311                 checkString(r, 0x31, 0x31);
312                 devFunc0001(r->ireg[0x31], r->preg[0x31].p, r);
313                 break;
314
315         case 0xff08:
316                 // JITC on JITC
317                 // R31: \8c¾\8cê(back-end, front-end, ...
318                 // R32: level
319                 // R33: debugInfo1
320                 checkString(r, 0x34, 0x31);
321                 if (r->ireg[0x33] < 0 || r->ireg[0x33] > 15 || r->debugInfo1 > 15)
322                         (*(r->errHndl))(r);
323                 for (i = 0; i < r->maxLabels; i++)
324                         r->label[i].opt = 0;
325                 puc = r->preg[0x31].p;
326                 i = jitCompiler(r->jitbuf, r->jitbuf1, puc, puc + r->ireg[0x34], puc, r->label, r->maxLabels, r->ireg[0x32], di1_serial, JITC_NOSTARTUP + 0);
327                 if (i == 0) {
328                         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);
329                         if (i >= 0) {
330                                 r->mapDi1s[r->debugInfo1][r->ireg[0x33]] = di1_serial;
331                                 di1_serial++;
332                                 r->ireg[0x30] = 0;
333                                 r->preg[0x31].p = r->jitbuf;
334                                 r->preg[0x31].typ = 0; // TYP_CODE
335                                 r->preg[0x31].p0 = r->jitbuf;
336                                 r->preg[0x31].p1 = r->jitbuf + 1;
337                                 //int j; for (j = 0; j < i; j++) printf("%02X ", r->jitbuf[j]); putchar('\n');
338                                 r->jitbuf += i;
339                                 static unsigned char ff08_ret[3] = { 0x1e, 0x3f, 0x30 };
340                                 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);
341                                 r->jitbuf += i;
342                                 break;
343                         }
344                 }
345                 r->ireg[0x30] = -1;
346                 break;
347
348         case 0xff09:
349                 // \82½\82Ô\82ñbit7\82ð\8eg\82Á\82½\83e\83L\83X\83g\82Í\82¤\82Ü\82­\8f\88\97\9d\82Å\82«\82È\82¢\81i\82±\82ê\82Í\82à\82Í\82â\8ed\97l\82É\82µ\82Ä\82à\96â\91è\82È\82¢\82©\82à\81j.
350                 checkString(r, 0x31, 0x31);
351                 len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x31], r->preg[0x31].p, r->ireg[0x32], (int *)r->preg[0x32].p, r);
352                 devFunc0001(len, pucbuf, r);
353                 break;
354
355         case 0xff40:
356                 /* R31\82ÆR32\82Å\83T\83C\83Y\82ð\8ew\92è */
357                 v_xsiz = r->ireg[0x31];
358                 v_ysiz = r->ireg[0x32];
359                 if (v_xsiz <= 0 || v_ysiz <= 0)
360                         (*(r->errHndl))(r);
361                 r->preg[0x31].p = (void *)(vram = malloc(v_xsiz * v_ysiz * 4));
362                 r->preg[0x31].p0 = r->preg[0x31].p;
363                 r->preg[0x31].p1 = r->preg[0x31].p + v_xsiz * v_ysiz * 4;
364                 drv_openWin(r->ireg[0x31], r->ireg[0x32], r->preg[0x31].p, &r->winClosed);
365                 //      drv_flshWin(r->ireg[1], r->ireg[2], 0, 0);
366                 r->autoSleep = 1;
367                 for (i = v_xsiz * v_ysiz - 1; i >= 0; i--)
368                         vram[i] = 0;
369                 break;
370
371         case 0xff41:
372                 /* R31\82ÆR32\82Å\83T\83C\83Y\82ð\8ew\92è\81AR33\82ÆR34\82Åx0,y0\8ew\92è */
373                 if (r->ireg[0x31] == -1) { r->ireg[0x31] = v_xsiz; r->ireg[0x33] &= 0; }
374                 if (r->ireg[0x32] == -1) { r->ireg[0x32] = v_ysiz; 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 && vram != NULL)
388                         drv_flshWin(v_xsiz, v_ysiz, 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: \83\\81[\83X\8ew\92è.
402                 //      16: shift, lock\8cn\82ð\97L\8cø\89».
403                 //      32: \8d\89E\82Ìshift\8cn\82ð\8bæ\95Ê\82·\82é.
404                 if (r->ireg[0x31] == 2) {       // \82È\82º3\82É\82µ\82È\82©\82Á\82½\82Ì\82©...
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] >= v_xsiz || r->ireg[0x33] < 0 || r->ireg[0x33] >= v_ysiz)
430                         (*(r->errHndl))(r);
431                 if ((r->ireg[0x31] & 3) == 0) vram[r->ireg[0x32] + r->ireg[0x33] * v_xsiz] = c;
432                 if ((r->ireg[0x31] & 3) == 1) vram[r->ireg[0x32] + r->ireg[0x33] * v_xsiz] |= c;
433                 if ((r->ireg[0x31] & 3) == 2) vram[r->ireg[0x32] + r->ireg[0x33] * v_xsiz] ^= c;
434                 if ((r->ireg[0x31] & 3) == 3) vram[r->ireg[0x32] + r->ireg[0x33] * v_xsiz] &= c;
435                 break;
436
437         case 0xff45:
438                 c = loadColor(r, 0x36);
439                 if (r->ireg[0x32] < 0 || r->ireg[0x32] >= v_xsiz || r->ireg[0x33] < 0 || r->ireg[0x33] >= v_ysiz)
440                         (*(r->errHndl))(r);
441                 if (r->ireg[0x34] < 0 || r->ireg[0x34] >= v_xsiz || r->ireg[0x35] < 0 || r->ireg[0x35] >= v_ysiz)
442                         (*(r->errHndl))(r);
443                 dx = r->ireg[0x34] - r->ireg[0x32];
444                 dy = r->ireg[0x35] - r->ireg[0x33];
445                 x = r->ireg[0x32] << 10;
446                 y = r->ireg[0x33] << 10;
447                 if (dx < 0) dx = -dx;
448                 if (dy < 0) dy = -dy;
449                 if (dx >= dy) {
450                         len = dx + 1; dx = 1024;
451                         if (r->ireg[0x32] > r->ireg[0x34]) dx *= -1;
452                         if (r->ireg[0x33] > r->ireg[0x35]) dy *= -1;
453                         dy = (dy << 10) / len;
454                 }
455                 else {
456                         len = dy + 1; dy = 1024;
457                         if (r->ireg[0x33] > r->ireg[0x35]) dy *= -1;
458                         if (r->ireg[0x32] > r->ireg[0x34]) dx *= -1;
459                         dx = (dx << 10) / len;
460                 }
461                 if ((r->ireg[0x31] & 3) == 0) {
462                         for (i = 0; i < len; i++) {
463                                 vram[(x >> 10) + (y >> 10) * v_xsiz] = c;
464                                 x += dx;
465                                 y += dy;
466                         }
467                         break;
468                 }
469                 for (i = 0; i < len; i++) {
470                         //      if ((r->ireg[0x31] & 3) == 0) vram[(x >> 10) + (y >> 10) * v_xsiz] =  c;
471                         if ((r->ireg[0x31] & 3) == 1) vram[(x >> 10) + (y >> 10) * v_xsiz] |= c;
472                         if ((r->ireg[0x31] & 3) == 2) vram[(x >> 10) + (y >> 10) * v_xsiz] ^= c;
473                         if ((r->ireg[0x31] & 3) == 3) vram[(x >> 10) + (y >> 10) * v_xsiz] &= c;
474                         x += dx;
475                         y += dy;
476                 }
477                 break;
478
479         case 0xff46:    // fillRect(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)
480                 c = loadColor(r, 0x36);
481                 if (r->ireg[0x32] == -1) { r->ireg[0x32] = v_xsiz; r->ireg[0x34] &= 0; }
482                 if (r->ireg[0x33] == -1) { r->ireg[0x33] = v_ysiz; r->ireg[0x35] &= 0; }
483                 checkRect(r, 0x32);
484                 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;
485                 if ((r->ireg[0x31] & 0x20) == 0) {
486                         devFunc0004(mod3, x0, y0, x1, y1, c);
487                 }
488                 else {  // drawRect
489                         devFunc0004(mod3, x0, y0, x1, y0, c);
490                         devFunc0004(mod3, x0, y1, x1, y1, c);
491                         devFunc0004(mod3, x0, y0, x0, y1, c);
492                         devFunc0004(mod3, x1, y0, x1, y1, c);
493                 }
494                 break;
495
496         case 0xff47:    // fillOval(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)
497                 // \82±\82ê\82Ì\8cv\8eZ\90¸\93x\82Í\83A\81[\83L\83e\83N\83`\83\83\82É\88Ë\91\82·\82é.
498                 c = loadColor(r, 0x36);
499                 if (r->ireg[0x32] == -1) { r->ireg[0x32] = v_xsiz; r->ireg[0x34] &= 0; }
500                 if (r->ireg[0x33] == -1) { r->ireg[0x33] = v_ysiz; r->ireg[0x35] &= 0; }
501                 checkRect(r, 0x32);
502                 double dcx = 0.5 * (r->ireg[0x32] - 1), dcy = 0.5 * (r->ireg[0x33] - 1), dcxy = (dcx + 0.5) * (dcy + 0.5) - 0.1;
503                 dcxy *= dcxy;
504                 mod3 = r->ireg[0x31] & 3;
505                 x1 = r->ireg[0x32];
506                 y1 = r->ireg[0x33];
507                 if (mod3 == 0 && (r->ireg[0x31] & 0x20) == 0) {
508                         for (y = 0; y < y1; y++) {
509                                 double dty = (y - dcy) * dcx;
510                                 for (x = 0; x < x1; x++) {
511                                         double dtx = (x - dcx) * dcy;
512                                         if (dtx * dtx + dty * dty > dcxy) continue;
513                                         vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * v_xsiz] = c;
514                                 }
515                         }
516                 }
517                 else {
518 #define DRAWOVALPARAM   1
519                         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;
520                         dcxy1 *= dcxy1;
521                         for (y = 0; y < y1; y++) {
522                                 double dty = (y - dcy) * dcx;
523                                 double dty1 = (y - dcy) * dcx1;
524                                 for (x = 0; x < x1; x++) {
525                                         double dtx = (x - dcx) * dcy;
526                                         double dtx1 = (x - dcx) * dcy1;
527                                         if (dtx * dtx + dty * dty > dcxy) continue;
528                                         if (DRAWOVALPARAM <= x && x < x1 - DRAWOVALPARAM && DRAWOVALPARAM <= y && y < y1 - DRAWOVALPARAM) {
529                                                 if (dtx1 * dtx1 + dty1 * dty1 < dcxy1) continue;
530                                         }
531                                         if (mod3 == 0) vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * v_xsiz] = c;
532                                         if (mod3 == 1) vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * v_xsiz] |= c;
533                                         if (mod3 == 2) vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * v_xsiz] ^= c;
534                                         if (mod3 == 3) vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * v_xsiz] &= c;
535                                 }
536                         }
537                 }
538                 break;
539
540         case 0xff48:    // drawString(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36, s.len:R37, s.p:P31)
541                 checkString(r, 0x37, 0x31);
542                 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);
543                 break;
544
545         case 0xff49:    /* \93K\93\96\82È\97\90\90\94\82ð\95Ô\82· */
546                 randStatNext();
547                 unsigned u32t;
548                 u32t = randStat.stat[0] + (randStat.stat[2] >> 8);
549                 r->ireg[0x30] = randStat.stat[3] ^ u32t ^ (-((int)(u32t & 1)) & randStat.tmat);
550                 if (r->ireg[0x31] > 0)
551                         r->ireg[0x30] = (r->ireg[0x30] & 0x7fffffff) % (r->ireg[0x31] + 1);
552                 break;
553
554         case 0xff4a:    /* seed\82Ì\8ew\92è */
555                 randStatInit(r->ireg[0x31]);
556                 break;
557
558         case 0xff4b:    /* \93K\93\96\82Èseed\82ð\92ñ\8b\9f */
559                 r->ireg[0x30] = (int)(time(NULL) ^ (long)0x55555555);
560                 break;
561
562         case 0xff4c:
563                 checkString(r, 0x37, 0x31);
564                 len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x37], r->preg[0x31].p, r->ireg[0x38], (int *)r->preg[0x32].p, r);
565                 devFunc0006(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34], r->ireg[0x35], loadColor(r, 0x36), len, pucbuf, r);
566                 break;
567
568         case 0xff4d:
569                 // bitblt(mod, xsiz, ysiz, xscale, yscale, x0, y0, lineskip, inv, p_buf, typ0, p_table, typ1); 
570                 // mod: 0x20:use_table, 0x40:inv_is_visible & typ1_is_color
571                 puc = r->preg[0x31].p;
572                 mod3 = r->ireg[0x31] & 3;
573                 dx = r->ireg[0x34];
574                 dy = r->ireg[0x35];
575                 if (dy == 0) dy = dx;
576                 if (r->ireg[0x32] == -1) { r->ireg[0x32] = v_xsiz / dx; r->ireg[0x36] &= 0; }
577                 if (r->ireg[0x33] == -1) { r->ireg[0x33] = v_ysiz / dy; r->ireg[0x37] &= 0; }
578                 for (y = 0; y < r->ireg[0x33]; y++) {
579                         y0 = y * dy + r->ireg[0x37];
580                         for (x = 0; x < r->ireg[0x32]; x++) {
581                                 x0 = x * dx + r->ireg[0x36];
582                                 c = iColor1[*puc++];
583                                 devFunc0004(mod3, x0, y0, x0 + dx, y0 + dy, c);
584                         }
585                         puc += r->ireg[0x38];
586                 }
587                 break;
588
589         default:
590                 printf("devFunc: error: R30=%08X\n", r->ireg[0x30]);
591                 exit(1);
592
593         }
594         return;
595 }
596
597
598