OSDN Git Service

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