OSDN Git Service

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