OSDN Git Service

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