OSDN Git Service

MacOSXでのキーボード入力対応!
[heavyosecpu/HeavyOSECPU.git] / function.c
index 23c11a6..2a5765e 100644 (file)
-#include "osecpu.h"
-
-extern unsigned char fontdata[];    // @fontdata.c
-
-const char *searchArg(int argc, const char **argv, const char *tag, int i)
-{
-       int j, l;
-       const char *r = NULL;
-       if (tag != NULL) {
-               l = (int)strlen(tag);
-               for (j = 1; j < argc; j++) {
-                       if (strncmp(argv[j], tag, l) == 0) {
-                               r = argv[j] + l;
-                               if (i == 0){
-                    break;
-                }
-                               i--;
-                       }
-               }
-       }
-       else {
-               for (j = 1; j < argc; j++) {
-                       if (strchr(argv[j], ':') == NULL) {
-                               r = argv[j];
-                               if (i == 0){
-                    break;
-                }
-                               i--;
-                       }
-               }
-       }
-       if (i != 0){
-        r = NULL;
-    }
-       return r;
-}
-
-void devFunc0001(int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r)
-{
-       while (len > 0) {
-               putOsaskChar(*puc++, r);
-               len--;
-       }
-       return;
-}
-
-void devFunc0006(int mod, int sx, int sy, int x, int y, int c, int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r)
-{
-    int xx;
-    int yy;
-    int i, ddx, ddy, j, ch, dx, dy;
-    
-       if (sy == 0){
-        sy = sx;
-    }
-       xx = x + sx * 8;
-       yy = y + sy * 16;
-       if (xx <= 0 || xx > mainWindow.xsize || yy <= 0 || yy > mainWindow.ysize){
-               (*(r->errHndl))(r);
-    }
-       if (x < 0 || x >= mainWindow.xsize || y < 0 || y >= mainWindow.ysize){
-               (*(r->errHndl))(r);
-    }
-       
-    
-       if ((mod & 3) == 0 && sx == 1 && sy == 1) {
-               // メジャーケースを高速化.
-               for (i = 0; i < len; i++) {
-                       ch = puc[i];
-                       if (0x10 <= ch && ch <= 0x1f)
-                               ch = "0123456789ABCDEF"[ch & 0x0f];
-                       for (dy = 0; dy < 16; dy++) {
-                               j = fontdata[(ch - ' ') * 16 + dy];
-                               for (dx = 0; dx < 8; dx++) {
-                                       if ((j & (0x80 >> dx)) != 0){
-                        mainWindow.vram[(x + dx) + (y + dy) * mainWindow.xsize] = c;
-                    }
-                               }
-                       }
-                       x += 8;
-               }
-               return;
-       }
-       for (i = 0; i < len; i++) {
-               ch = puc[i];
-               if (0x10 <= ch && ch <= 0x1f)
-                       ch = "0123456789ABCDEF"[ch & 0x0f];
-               for (dy = 0; dy < 16; dy++) {
-                       j = fontdata[(ch - ' ') * 16 + dy];
-                       for (ddy = 0; ddy < sy; ddy++) {
-                               for (dx = 0; dx < 8; dx++) {
-                                       if ((j & (0x80 >> dx)) != 0) {
-                                               for (ddx = 0; ddx < sx; ddx++) {
-                            switch (mod & 3) {
-                                case 0:
-                                    mainWindow.vram[x + y * mainWindow.xsize] = c;
-                                    break;
-                                case 1:
-                                    mainWindow.vram[x + y * mainWindow.xsize] |= c;
-                                    break;
-                                case 2:
-                                    mainWindow.vram[x + y * mainWindow.xsize] ^= c;
-                                    break;
-                                case 3:
-                                    mainWindow.vram[x + y * mainWindow.xsize] &= c;
-                                    break;
-                            }
-                                                       x++;
-                                               }
-                                       }
-                                       else
-                                               x += sx;
-                               }
-                               x -= sx * 8;
-                               y++;
-                       }
-               }
-               x += sx * 8;
-               y -= sy * 16;
-       }
-       return;
-}
-
-void devFunc0004(int mod, int x0, int y0, int x1, int y1, int c)
-{
-       int x, y;
-       if (mod == 0) {
-               for (y = y0; y <= y1; y++) {
-                       for (x = x0; x <= x1; x++) {
-                               mainWindow.vram[x + y * mainWindow.xsize] = c;
-                       }
-               }
-       }
-       else {
-               for (y = y0; y <= y1; y++) {
-                       for (x = x0; x <= x1; x++) {
-                               if (mod == 1) mainWindow.vram[x + y * mainWindow.xsize] |= c;
-                               if (mod == 2) mainWindow.vram[x + y * mainWindow.xsize] ^= c;
-                               if (mod == 3) mainWindow.vram[x + y * mainWindow.xsize] &= c;
-                       }
-               }
-       }
-       return;
-}
-
-int devFunc0016(int buflen, unsigned char *buf, int plen, unsigned char *p, int qlen, int *q, HOSECPU_RuntimeEnvironment *r)
-{
-       int i = 0, base, j, k;
-       char sign;
-       while (plen > 0) {
-               if (i >= buflen)
-                       (*(r->errHndl))(r);
-               if (*p != 0x01) {
-                       buf[i++] = *p++;
-                       plen--;
-                       continue;
-               }
-               p++;
-               plen--;
-               if (qlen < 4)
-                       (*(r->errHndl))(r);
-               base = q[0];
-               sign = 0;
-               if (base == 0) base = 16;
-#if (REVISION == 1)
-               if (base == -3) base = 10;
-#endif
-               if (base == -1) base = 10;
-               if (base < 0 || base > 16)
-                       (*(r->errHndl))(r);
-               if (q[1] + i > buflen)
-                       (*(r->errHndl))(r);
-               j = q[3];
-               if ((q[2] & 4) == 0) {
-                       // jは符号付き整数.
-                       if ((q[2] & 8) != 0 && j > 0) sign = '+';
-                       if (j < 0) { sign = '-'; j *= -1; }
-               }
-               else {
-                       // jは符号無し整数.
-                       if ((q[2] & 8) != 0 && j != 0) sign = '+';
-               }
-               for (k = q[1] - 1; k >= 0; k--) {
-                       buf[i + k] = (j % base) + 0x10;
-                       j = ((unsigned)j) / base;
-               }
-               k = 0;
-               if ((q[2] & 2) == 0 && j == 0) {
-                       for (k = 0; k < q[1] - 1; k++) {
-                               if (buf[i + k] != 0x10) break;
-                               buf[i + k] = ' ';
-                       }
-               }
-               if (sign != 0) {
-                       if (k > 0) k--;
-                       buf[i + k] = sign;
-               }
-               if ((q[2] & 1) != 0 && buf[i] == ' ') {
-                       for (j = 0; k < q[1]; k++, j++)
-                               buf[i + j] = buf[i + k];
-                       i += j;
-               }
-               else
-                       i += q[1];
-               qlen -= 4;
-               q += 4;
-       }
-       return i;
-}
-
-void devFunc(HOSECPU_RuntimeEnvironment *r)
-{
-       FILE *fp;
-       r = (HOSECPU_RuntimeEnvironment *) (((char *)r) - 128); /* サイズを節約するためにEBPを128バイトずらしているのを元に戻す */
-       int i, c;
-       int x, y, len, dx, dy;
-       unsigned char *puc;
-       unsigned char pucbuf[256];
-       if (r->winClosed != 0)
-               longjmp(*(r->setjmpEnv), 1);
-       if (0xff44 <= r->ireg[0x30] && r->ireg[0x30] <= 0xff48) {
-               if (mainWindow.vram == NULL) {
-                       mainWindow.xsize = 640;
-                       mainWindow.ysize = 480;
-                       mainWindow.vram = malloc(640 * 480 * 4);
-                       drv_openWin(640, 480, (void *)mainWindow.vram, &r->winClosed);
-                       r->autoSleep = 1;
-                       for (i = 640 * 480 - 1; i >= 0; i--){
-                               mainWindow.vram[i] = 0;
-            }
-               }
-       }
-    
-       switch (r->ireg[0x30]) {
-        case 0xff00:
-            printf("R31=%d(dec)\n", r->ireg[0x31]);
-            break;
-            
-        case 0xff01:
-            /* return: R30, P31 */
-            if (r->buf0 == NULL)
-                r->buf0 = malloc(1024 * 1024);
-            if (r->mainArgc <= r->ireg[0x31]) {
-                fprintf(stderr, "devFunc: error: R30=ff01: argc error: R31=%08X\n", r->ireg[0x31]);
-                exit(1);
-            }
-            fp = fopen(r->mainArgv[r->ireg[0x31]], "rb");
-            if (fp == NULL) {
-                fprintf(stderr, "devFunc: error: R30=ff01: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]);
-                exit(1);
-            }
-            i = (int)fread(r->buf0, 1, 1024 * 1024 - 4, fp);
-            if (i >= 1024 * 1024 - 4 || i < 0) {
-                fprintf(stderr, "devFunc: error: R30=ff01: fread error: '%s'\n", r->mainArgv[r->ireg[0x31]]);
-                exit(1);
-            }
-            fclose(fp);
-            r->preg[0x31].p = r->buf0;
-            r->preg[0x31].p0 = r->buf0;
-            r->preg[0x31].p1 = r->buf0 + i;
-            r->preg[0x31].typ = 3; // T_UINT8
-            r->ireg[0x30] = i;
-            break;
-            
-        case 0xff02:
-            /* return: none */
-            if (r->mainArgc <= r->ireg[0x31]) {
-                fprintf(stderr, "devFunc: error: R30=ff02: argc error: R31=%08X\n", r->ireg[0x31]);
-                exit(1);
-            }
-            fp = fopen(r->mainArgv[r->ireg[0x31]], "wb");
-            if (fp == NULL) {
-                fprintf(stderr, "devFunc: error: R30=ff02: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]);
-                exit(1);
-            }
-            if (r->ireg[0x32] >= 1024 * 1024 || r->ireg[0x32] < 0){
-                fprintf(stderr, "devFunc: error: R30=ff02: fwrite error: R02=%08X\n", r->ireg[0x32]);
-                exit(1);
-            }
-            fwrite(r->preg[0x31].p, 1, r->ireg[0x32], fp);
-            fclose(fp);
-            break;
-            
-        case 0xff03:
-            /* return: P31 */
-            if (r->buf1 == NULL)
-                r->buf1 = malloc(1024 * 1024);
-            r->preg[0x31].p = r->buf1;
-            r->preg[0x31].p0 = r->buf1;
-            r->preg[0x31].p1 = r->buf1 + 1024 * 1024;
-            break;
-            
-        case 0xff04:
-            printf("P31.(p-p0)=%d(dec)\n", (int)(r->preg[0x31].p - r->preg[0x31].p0));
-            break;
-            
-        case 0xff05:
-            fwrite(r->preg[0x31].p, 1, r->ireg[0x31], stdout);
-            break;
-            
-        case 0xff06:
-            // R31はリターンコード.
-            // これを反映すべきだが、現状は手抜きでいつも正常終了.
-            longjmp(*(r->setjmpEnv), 1);
-            break;
-            
-        case 0xff07:
-            // マシになった文字列表示.OSASK文字列に対応.offにすれば通常の文字列処理もできる.現状はonのみサポート.
-            checkString(r, 0x31, 0x31);
-            devFunc0001(r->ireg[0x31], r->preg[0x31].p, r);
-            break;
-            
-        case 0xff08:
-            // JITC on JITC
-            // R31: 言語(back-end, front-end, ...
-            // R32: level
-            // R33: debugInfo1
-            checkString(r, 0x34, 0x31);
-            if (r->ireg[0x33] < 0 || r->ireg[0x33] > 15 || r->debugInfo1 > 15)
-                (*(r->errHndl))(r);
-            for (i = 0; i < r->maxLabels; i++)
-                r->label[i].opt = 0;
-            puc = r->preg[0x31].p;
-            i = jitCompiler(r->jitbuf, r->jitbuf1, puc, puc + r->ireg[0x34], puc, r->label, r->maxLabels, r->ireg[0x32], di1_serial, JITC_NOSTARTUP + 0);
-            if (i == 0) {
-                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);
-                if (i >= 0) {
-                    r->mapDi1s[r->debugInfo1][r->ireg[0x33]] = di1_serial;
-                    di1_serial++;
-                    r->ireg[0x30] = 0;
-                    r->preg[0x31].p = r->jitbuf;
-                    r->preg[0x31].typ = 0; // TYP_CODE
-                    r->preg[0x31].p0 = r->jitbuf;
-                    r->preg[0x31].p1 = r->jitbuf + 1;
-                    //int j; for (j = 0; j < i; j++) printf("%02X ", r->jitbuf[j]); putchar('\n');
-                    r->jitbuf += i;
-                    static unsigned char ff08_ret[3] = { 0x1e, 0x3f, 0x30 };
-                    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);
-                    r->jitbuf += i;
-                    break;
-                }
-            }
-            r->ireg[0x30] = -1;
-            break;
-            
-        case 0xff09:
-            // たぶんbit7を使ったテキストはうまく処理できない(これはもはや仕様にしても問題ないかも).
-            checkString(r, 0x31, 0x31);
-            len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x31], r->preg[0x31].p, r->ireg[0x32], (int *)r->preg[0x32].p, r);
-            devFunc0001(len, pucbuf, r);
-            break;
-            
-        case 0xff40:
-            /* R31とR32でサイズを指定 */
-            mainWindow.xsize = r->ireg[0x31];
-            mainWindow.ysize = r->ireg[0x32];
-            if (mainWindow.xsize <= 0 || mainWindow.ysize <= 0){
-                (*(r->errHndl))(r);
-            }
-            r->preg[0x31].p = (void *)(mainWindow.vram = malloc(mainWindow.xsize * mainWindow.ysize * 4));
-            r->preg[0x31].p0 = r->preg[0x31].p;
-            r->preg[0x31].p1 = r->preg[0x31].p + mainWindow.xsize * mainWindow.ysize * 4;
-            drv_openWin(r->ireg[0x31], r->ireg[0x32], r->preg[0x31].p, &r->winClosed);
-            // drv_flshWin(r->ireg[1], r->ireg[2], 0, 0);
-            r->autoSleep = 1;
-            for (i = mainWindow.xsize * mainWindow.ysize - 1; i >= 0; i--){
-                mainWindow.vram[i] = 0;
-            }
-            break;
-            
-        case 0xff41:
-            /* R31とR32でサイズを指定、R33とR34でx0,y0指定 */
-            if (r->ireg[0x31] == -1) { r->ireg[0x31] = mainWindow.xsize; r->ireg[0x33] &= 0; }
-            if (r->ireg[0x32] == -1) { r->ireg[0x32] = mainWindow.ysize; r->ireg[0x34] &= 0; }
-            checkRect(r, 0x31);
-            drv_flshWin(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34]);
-            break;
-            
-        case 0xff42:
-            if (r->ireg[0x32] == -1) {
-                r->autoSleep = 1;
-                longjmp(*(r->setjmpEnv), 1);
-            }
-            if (r->ireg[0x32] < 0)
-                (*(r->errHndl))(r);
-            r->autoSleep = 0;
-            if ((r->ireg[0x31] & 1) == 0 && mainWindow.vram != NULL)
-                drv_flshWin(mainWindow.xsize, mainWindow.ysize, 0, 0);
-            for (;;) {
-                if (r->winClosed != 0)
-                    longjmp(*(r->setjmpEnv), 1);
-                drv_sleep(r->ireg[0x32]);
-                if ((r->ireg[0x31] & 2) != 0 && keybuf_c <= 0) continue;
-                break;
-            }
-            break;
-            
-        case 0xff43:
-            //  1:peek
-            //  2:stdin
-            // 4,8: ソース指定.
-            // 16: shift, lock系を有効化.
-            // 32: 左右のshift系を区別する.
-            if (r->ireg[0x31] == 2) {  // なぜ3にしなかったのか...
-                r->ireg[0x30] = fgetc(stdin);
-                if (r->ireg[0x30] == EOF)
-                    r->ireg[0x30] = -1;
-                break;
-            }
-            r->ireg[0x30] |= -1;
-            if (keybuf_c > 0) {
-                r->ireg[0x30] = keybuf[keybuf_r];
-                if ((r->ireg[0x31] & 16) == 0) r->ireg[0x30] &= 0x3e3effff;
-                if ((r->ireg[0x31] & 32) == 0) r->ireg[0x30] |= (r->ireg[0x30] >> 8) & 0xff0000;
-                if ((r->ireg[0x31] & 1) != 0) {
-                    keybuf_c--;
-                    keybuf_r = (keybuf_r + 1) & (KEYBUFSIZ - 1);
-                }
-            }
-            r->ireg[0x32] = r->ireg[0x33] = 0;
-            if (r->ireg[0x30] == 4132) r->ireg[0x32]--;
-            if (r->ireg[0x30] == 4133) r->ireg[0x33]--;
-            if (r->ireg[0x30] == 4134) r->ireg[0x32]++;
-            if (r->ireg[0x30] == 4135) r->ireg[0x33]++;
-            break;
-            
-        case 0xff44:
-            c = loadColor(r, 0x34);
-            if (r->ireg[0x32] < 0 || r->ireg[0x32] >= mainWindow.xsize || r->ireg[0x33] < 0 || r->ireg[0x33] >= mainWindow.ysize)
-                (*(r->errHndl))(r);
-            if ((r->ireg[0x31] & 3) == 0) mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] = c;
-            if ((r->ireg[0x31] & 3) == 1) mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] |= c;
-            if ((r->ireg[0x31] & 3) == 2) mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] ^= c;
-            if ((r->ireg[0x31] & 3) == 3) mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] &= c;
-            break;
-            
-        case 0xff45:
-            //drawLine
-            c = loadColor(r, 0x36);
-            if (r->ireg[0x32] < 0 || r->ireg[0x32] >= mainWindow.xsize || r->ireg[0x33] < 0 || r->ireg[0x33] >= mainWindow.ysize)
-                (*(r->errHndl))(r);
-            if (r->ireg[0x34] < 0 || r->ireg[0x34] >= mainWindow.xsize || r->ireg[0x35] < 0 || r->ireg[0x35] >= mainWindow.ysize)
-                (*(r->errHndl))(r);
-            dx = r->ireg[0x34] - r->ireg[0x32];
-            dy = r->ireg[0x35] - r->ireg[0x33];
-            x = r->ireg[0x32] << 10;
-            y = r->ireg[0x33] << 10;
-            if (dx < 0) dx = -dx;
-            if (dy < 0) dy = -dy;
-            if (dx >= dy) {
-                len = dx + 1; dx = 1024;
-                if (r->ireg[0x32] > r->ireg[0x34]) dx *= -1;
-                if (r->ireg[0x33] > r->ireg[0x35]) dy *= -1;
-                dy = (dy << 10) / len;
-            }
-            else {
-                len = dy + 1; dy = 1024;
-                if (r->ireg[0x33] > r->ireg[0x35]) dy *= -1;
-                if (r->ireg[0x32] > r->ireg[0x34]) dx *= -1;
-                dx = (dx << 10) / len;
-            }
-            if ((r->ireg[0x31] & 3) == 0) {
-                for (i = 0; i < len; i++) {
-                    mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] = c;
-                    x += dx;
-                    y += dy;
-                }
-                break;
-            }
-            for (i = 0; i < len; i++) {
-                //     if ((r->ireg[0x31] & 3) == 0) vram[(x >> 10) + (y >> 10) * v_xsiz] =  c;
-                if ((r->ireg[0x31] & 3) == 1) mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] |= c;
-                if ((r->ireg[0x31] & 3) == 2) mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] ^= c;
-                if ((r->ireg[0x31] & 3) == 3) mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] &= c;
-                x += dx;
-                y += dy;
-            }
-            break;
-            
-        case 0xff46:   // fillRect(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)
-            c = loadColor(r, 0x36);
-            if (r->ireg[0x32] == -1) { r->ireg[0x32] = mainWindow.xsize; r->ireg[0x34] &= 0; }
-            if (r->ireg[0x33] == -1) { r->ireg[0x33] = mainWindow.ysize; r->ireg[0x35] &= 0; }
-            checkRect(r, 0x32);
-            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;
-            if ((r->ireg[0x31] & 0x20) == 0) {
-                devFunc0004(mod3, x0, y0, x1, y1, c);
-            }
-            else {     // drawRect
-                devFunc0004(mod3, x0, y0, x1, y0, c);
-                devFunc0004(mod3, x0, y1, x1, y1, c);
-                devFunc0004(mod3, x0, y0, x0, y1, c);
-                devFunc0004(mod3, x1, y0, x1, y1, c);
-            }
-            break;
-            
-        case 0xff47:   // fillOval(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)
-            // これの計算精度はアーキテクチャに依存する.
-            c = loadColor(r, 0x36);
-            if (r->ireg[0x32] == -1) { r->ireg[0x32] = mainWindow.xsize; r->ireg[0x34] &= 0; }
-            if (r->ireg[0x33] == -1) { r->ireg[0x33] = mainWindow.ysize; r->ireg[0x35] &= 0; }
-            checkRect(r, 0x32);
-            double dcx = 0.5 * (r->ireg[0x32] - 1), dcy = 0.5 * (r->ireg[0x33] - 1), dcxy = (dcx + 0.5) * (dcy + 0.5) - 0.1;
-            dcxy *= dcxy;
-            mod3 = r->ireg[0x31] & 3;
-            x1 = r->ireg[0x32];
-            y1 = r->ireg[0x33];
-            if (mod3 == 0 && (r->ireg[0x31] & 0x20) == 0) {
-                for (y = 0; y < y1; y++) {
-                    double dty = (y - dcy) * dcx;
-                    for (x = 0; x < x1; x++) {
-                        double dtx = (x - dcx) * dcy;
-                        if (dtx * dtx + dty * dty > dcxy) continue;
-                        mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] = c;
-                    }
-                }
-            }
-            else {
-#define DRAWOVALPARAM  1
-                double dcx1 = 0.5 * (r->ireg[0x32] - (1 + DRAWOVALPARAM * 2)), dcy1 = 0.5 * (r->ireg[0x33] - (1 + DRAWOVALPARAM * 2)), dcxy1 = (dcx1 + 0.5) * (dcy1 + 0.5) - 0.1;
-                dcxy1 *= dcxy1;
-                for (y = 0; y < y1; y++) {
-                    double dty = (y - dcy) * dcx;
-                    double dty1 = (y - dcy) * dcx1;
-                    for (x = 0; x < x1; x++) {
-                        double dtx = (x - dcx) * dcy;
-                        double dtx1 = (x - dcx) * dcy1;
-                        if (dtx * dtx + dty * dty > dcxy) continue;
-                        if (DRAWOVALPARAM <= x && x < x1 - DRAWOVALPARAM && DRAWOVALPARAM <= y && y < y1 - DRAWOVALPARAM) {
-                            if (dtx1 * dtx1 + dty1 * dty1 < dcxy1) continue;
-                        }
-                        if (mod3 == 0) mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] = c;
-                        if (mod3 == 1) mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] |= c;
-                        if (mod3 == 2) mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] ^= c;
-                        if (mod3 == 3) mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] &= c;
-                    }
-                }
-            }
-            break;
-            
-        case 0xff48:   // drawString(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36, s.len:R37, s.p:P31)
-            checkString(r, 0x37, 0x31);
-            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);
-            break;
-            
-        case 0xff49:
-            // **** junkApi_rand(i, max) ****
-            // 0 <= i <= maxとなるiを返す。
-            // max==0のとき、iはSINT32全体を範囲とする乱数となる。
-            
-            r->ireg[0x30] = randGetNextUInt32();
-            if (r->ireg[0x31] > 0){
-                r->ireg[0x30] = (r->ireg[0x30] & 0x7fffffff) % (r->ireg[0x31] + 1);
-            }
-            break;
-            
-        case 0xff4a:   /* seedの指定 */
-            randStatInit(r->ireg[0x31]);
-            break;
-            
-        case 0xff4b:   /* 適当なseedを提供 */
-            r->ireg[0x30] = (int)(time(NULL) ^ (long)0x55555555);
-            break;
-            
-        case 0xff4c:
-            checkString(r, 0x37, 0x31);
-            len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x37], r->preg[0x31].p, r->ireg[0x38], (int *)r->preg[0x32].p, r);
-            devFunc0006(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34], r->ireg[0x35], loadColor(r, 0x36), len, pucbuf, r);
-            break;
-            
-        case 0xff4d:
-            // bitblt(mod, xsiz, ysiz, xscale, yscale, x0, y0, lineskip, inv, p_buf, typ0, p_table, typ1); 
-            // mod: 0x20:use_table, 0x40:inv_is_visible & typ1_is_color
-            puc = r->preg[0x31].p;
-            mod3 = r->ireg[0x31] & 3;
-            dx = r->ireg[0x34];
-            dy = r->ireg[0x35];
-            if (dy == 0) dy = dx;
-            if (r->ireg[0x32] == -1) { r->ireg[0x32] = mainWindow.xsize / dx; r->ireg[0x36] &= 0; }
-            if (r->ireg[0x33] == -1) { r->ireg[0x33] = mainWindow.ysize / dy; r->ireg[0x37] &= 0; }
-            for (y = 0; y < r->ireg[0x33]; y++) {
-                y0 = y * dy + r->ireg[0x37];
-                for (x = 0; x < r->ireg[0x32]; x++) {
-                    x0 = x * dx + r->ireg[0x36];
-                    c = iColor1[*puc++];
-                    devFunc0004(mod3, x0, y0, x0 + dx, y0 + dy, c);
-                }
-                puc += r->ireg[0x38];
-            }
-            break;
-            
-        default:
-            printf("devFunc: error: R30=%08X\n", r->ireg[0x30]);
-            exit(1);
-            
-       }
-       return;
-}
-
-
-
+#include "osecpu.h"\r
+#include "jitc.h"\r
+\r
+extern unsigned char fontdata[];    // @fontdata.c\r
+\r
+const char *searchArg(int argc, const char **argv, const char *tag, int i)\r
+{\r
+       // 引数リストargvの中から、文字列tagが前方一致する引数のi番目を探し出し、\r
+       // その引数の文字列の、tagに続く部分の文字へのポインタを返す。\r
+       int j, l;\r
+       const char *r = NULL;\r
+       \r
+       if (tag != NULL) {\r
+               l = (int)strlen(tag);\r
+               for (j = 1; j < argc; j++) {\r
+                       if (strncmp(argv[j], tag, l) == 0) {\r
+                               r = argv[j] + l;\r
+                               if (i == 0){\r
+                                       break;\r
+                               }\r
+                               i--;\r
+                       }\r
+               }\r
+       }\r
+       /*\r
+        // 未使用\r
+       else {\r
+               for (j = 1; j < argc; j++) {\r
+                       if (strchr(argv[j], ':') == NULL) {\r
+                               r = argv[j];\r
+                               if (i == 0){\r
+                                       break;\r
+                               }\r
+                               i--;\r
+                       }\r
+               }\r
+       }\r
+        */\r
+       if (i != 0){\r
+               r = NULL;\r
+       }\r
+       return r;\r
+}\r
+\r
+void devFunc0001(int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r)\r
+{\r
+       // OSASK文字列の出力\r
+       while (len > 0) {\r
+               putOsaskChar(*puc++, r);\r
+               len--;\r
+       }\r
+       return;\r
+}\r
+\r
+void devFunc0006(int mod, int sx, int sy, int x, int y, int c, int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r)\r
+{\r
+       // drawString\r
+       int xx;\r
+       int yy;\r
+       int i, ddx, ddy, j, ch, dx, dy;\r
+       \r
+       if (sy == 0){\r
+               sy = sx;\r
+       }\r
+       xx = x + sx * 8;\r
+       yy = y + sy * 16;\r
+       if (xx <= 0 || xx > mainWindow.xsize || yy <= 0 || yy > mainWindow.ysize){\r
+               (*(r->errHndl))(r);\r
+       }\r
+       if (x < 0 || x >= mainWindow.xsize || y < 0 || y >= mainWindow.ysize){\r
+               (*(r->errHndl))(r);\r
+       }\r
+       \r
+       \r
+       if ((mod & 3) == 0 && sx == 1 && sy == 1) {\r
+               // メジャーケースを高速化.\r
+               for (i = 0; i < len; i++) {\r
+                       ch = puc[i];\r
+                       if (0x10 <= ch && ch <= 0x1f)\r
+                               ch = "0123456789ABCDEF"[ch & 0x0f];\r
+                       for (dy = 0; dy < 16; dy++) {\r
+                               j = fontdata[(ch - ' ') * 16 + dy];\r
+                               for (dx = 0; dx < 8; dx++) {\r
+                                       if ((j & (0x80 >> dx)) != 0){\r
+                                               mainWindow.vram[(x + dx) + (y + dy) * mainWindow.xsize] = c;\r
+                                       }\r
+                               }\r
+                       }\r
+                       x += 8;\r
+               }\r
+               return;\r
+       }\r
+       for (i = 0; i < len; i++) {\r
+               ch = puc[i];\r
+               if (0x10 <= ch && ch <= 0x1f)\r
+                       ch = "0123456789ABCDEF"[ch & 0x0f];\r
+               for (dy = 0; dy < 16; dy++) {\r
+                       j = fontdata[(ch - ' ') * 16 + dy];\r
+                       for (ddy = 0; ddy < sy; ddy++) {\r
+                               for (dx = 0; dx < 8; dx++) {\r
+                                       if ((j & (0x80 >> dx)) != 0) {\r
+                                               for (ddx = 0; ddx < sx; ddx++) {\r
+                                                       switch (mod & 3) {\r
+                                                               case 0:\r
+                                                                       mainWindow.vram[x + y * mainWindow.xsize] = c;\r
+                                                                       break;\r
+                                                               case 1:\r
+                                                                       mainWindow.vram[x + y * mainWindow.xsize] |= c;\r
+                                                                       break;\r
+                                                               case 2:\r
+                                                                       mainWindow.vram[x + y * mainWindow.xsize] ^= c;\r
+                                                                       break;\r
+                                                               case 3:\r
+                                                                       mainWindow.vram[x + y * mainWindow.xsize] &= c;\r
+                                                                       break;\r
+                                                       }\r
+                                                       x++;\r
+                                               }\r
+                                       } else{\r
+                                               x += sx;\r
+                                       }\r
+                               }\r
+                               x -= sx * 8;\r
+                               y++;\r
+                       }\r
+               }\r
+               x += sx * 8;\r
+               y -= sy * 16;\r
+       }\r
+       return;\r
+}\r
+\r
+void devFunc0004(int mod, int x0, int y0, int x1, int y1, int c)\r
+{\r
+       // FillRect\r
+       int x, y;\r
+       if (mod == 0) {\r
+               for (y = y0; y <= y1; y++) {\r
+                       for (x = x0; x <= x1; x++) {\r
+                               mainWindow.vram[x + y * mainWindow.xsize] = c;\r
+                       }\r
+               }\r
+       }\r
+       else {\r
+               for (y = y0; y <= y1; y++) {\r
+                       for (x = x0; x <= x1; x++) {\r
+                               switch (mod) {\r
+                                       case 1:\r
+                                               mainWindow.vram[x + y * mainWindow.xsize] |= c;\r
+                                               break;\r
+                                       case 2:\r
+                                               mainWindow.vram[x + y * mainWindow.xsize] ^= c;\r
+                                               break;\r
+                                       case 3:\r
+                                               mainWindow.vram[x + y * mainWindow.xsize] &= c;\r
+                                               break;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       return;\r
+}\r
+\r
+int devFunc0016(int buflen, unsigned char *buf, int plen, unsigned char *p, int qlen, int *q, HOSECPU_RuntimeEnvironment *r)\r
+{\r
+       // OSASK文字列への変換?\r
+       int i = 0, base, j, k;\r
+       char sign;\r
+       \r
+       while (plen > 0) {\r
+               if (i >= buflen){\r
+                       (*(r->errHndl))(r);\r
+               }\r
+               if (*p != 0x01) {\r
+                       buf[i++] = *p++;\r
+                       plen--;\r
+                       continue;\r
+               }\r
+               p++;\r
+               plen--;\r
+               if (qlen < 4){\r
+                       (*(r->errHndl))(r);\r
+               }\r
+               base = q[0];\r
+               sign = 0;\r
+               if (base == 0){\r
+                       base = 16;\r
+               }\r
+#if (REVISION == 1)\r
+               if (base == -3){\r
+                       base = 10;\r
+               }\r
+#endif\r
+               if (base == -1){\r
+                       base = 10;\r
+               }\r
+               if (base < 0 || base > 16){\r
+                       (*(r->errHndl))(r);\r
+               }\r
+               if (q[1] + i > buflen){\r
+                       (*(r->errHndl))(r);\r
+               }\r
+               j = q[3];\r
+               if ((q[2] & 4) == 0) {\r
+                       // jは符号付き整数.\r
+                       if ((q[2] & 8) != 0 && j > 0){\r
+                               sign = '+';\r
+                       }\r
+                       if (j < 0) {\r
+                               sign = '-'; j *= -1;\r
+                       }\r
+               } else{\r
+                       // jは符号無し整数.\r
+                       if ((q[2] & 8) != 0 && j != 0){\r
+                               sign = '+';\r
+                       }\r
+               }\r
+               for (k = q[1] - 1; k >= 0; k--) {\r
+                       buf[i + k] = (j % base) + 0x10;\r
+                       j = ((unsigned)j) / base;\r
+               }\r
+               k = 0;\r
+               if ((q[2] & 2) == 0 && j == 0) {\r
+                       for (k = 0; k < q[1] - 1; k++) {\r
+                               if (buf[i + k] != 0x10){\r
+                                       break;\r
+                               }\r
+                               buf[i + k] = ' ';\r
+                       }\r
+               }\r
+               if (sign != 0) {\r
+                       if (k > 0){\r
+                               k--;\r
+                       }\r
+                       buf[i + k] = sign;\r
+               }\r
+               if ((q[2] & 1) != 0 && buf[i] == ' ') {\r
+                       for (j = 0; k < q[1]; k++, j++){\r
+                               buf[i + j] = buf[i + k];\r
+                       }\r
+                       i += j;\r
+               } else{\r
+                       i += q[1];\r
+               }\r
+               qlen -= 4;\r
+               q += 4;\r
+       }\r
+       return i;\r
+}\r
+\r
+void devFunc(HOSECPU_RuntimeEnvironment *r)\r
+{\r
+       FILE *fp;\r
+       int i, c;\r
+       int x, y, len, dx, dy;\r
+       unsigned char *puc;\r
+       unsigned char pucbuf[256];\r
+       \r
+       //サイズを節約するためにEBPを128バイトずらしているのを元に戻す\r
+       r = (HOSECPU_RuntimeEnvironment *) (((char *)r) - jitCompA0001_EBP128);\r
+       \r
+       if (r->winClosed != 0){\r
+               longjmp(r->setjmpEnv, 1);\r
+       }\r
+       if (0xff44 <= r->ireg[0x30] && r->ireg[0x30] <= 0xff48) {\r
+               if (mainWindow.vram == NULL) {\r
+                       mainWindow.xsize = 640;\r
+                       mainWindow.ysize = 480;\r
+                       mainWindow.vram = malloc(640 * 480 * 4);\r
+                       drv_openWin(640, 480, (void *)mainWindow.vram, &r->winClosed);\r
+                       r->autoSleep = 1;\r
+                       for (i = 640 * 480 - 1; i >= 0; i--){\r
+                               mainWindow.vram[i] = 0;\r
+                       }\r
+               }\r
+       }\r
+       \r
+       switch (r->ireg[0x30]){\r
+               case 0xff00:\r
+                       printf("R31=%d(dec)\n", r->ireg[0x31]);\r
+                       break;\r
+                       \r
+               case 0xff01:\r
+                       // junkApi_fopenRead(_filesize, _p, arg)\r
+                       // args: R31=arg, R30=_filesize, P31=_p\r
+                       // retv: R30, P31\r
+                       if (r->buf0 == NULL){\r
+                               r->buf0 = malloc(1024 * 1024);\r
+                       }\r
+                       if (r->mainArgc <= r->ireg[0x31]) {\r
+                               fprintf(stderr, "devFunc: error: R30=ff01: argc error: R31=%08X\n", r->ireg[0x31]);\r
+                               exit(1);\r
+                       }\r
+                       fp = fopen(r->mainArgv[r->ireg[0x31]], "rb");\r
+                       if (fp == NULL) {\r
+                               fprintf(stderr, "devFunc: error: R30=ff01: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]);\r
+                               exit(1);\r
+                       }\r
+                       i = (int)fread(r->buf0, 1, 1024 * 1024 - 4, fp);\r
+                       if (i >= 1024 * 1024 - 4 || i < 0) {\r
+                               fprintf(stderr, "devFunc: error: R30=ff01: fread error: '%s'\n", r->mainArgv[r->ireg[0x31]]);\r
+                               exit(1);\r
+                       }\r
+                       fclose(fp);\r
+                       r->preg[0x31].p = r->buf0;\r
+                       r->preg[0x31].p0 = r->buf0;\r
+                       r->preg[0x31].p1 = r->buf0 + i;\r
+                       r->preg[0x31].typ = 3; // T_UINT8\r
+                       r->ireg[0x30] = i;\r
+                       break;\r
+                       \r
+               case 0xff02:\r
+                       // junkApi_fopenWrite(arg, filesize, p)\r
+                       // args: R31=arg, R32=filesize, P31=p\r
+                       // retv: (none)\r
+                       if (r->mainArgc <= r->ireg[0x31]) {\r
+                               fprintf(stderr, "devFunc: error: R30=ff02: argc error: R31=%08X\n", r->ireg[0x31]);\r
+                               exit(1);\r
+                       }\r
+                       fp = fopen(r->mainArgv[r->ireg[0x31]], "wb");\r
+                       if (fp == NULL) {\r
+                               fprintf(stderr, "devFunc: error: R30=ff02: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]);\r
+                               exit(1);\r
+                       }\r
+                       if (r->ireg[0x32] >= 1024 * 1024 || r->ireg[0x32] < 0){\r
+                               fprintf(stderr, "devFunc: error: R30=ff02: fwrite error: R02=%08X\n", r->ireg[0x32]);\r
+                               exit(1);\r
+                       }\r
+                       fwrite(r->preg[0x31].p, 1, r->ireg[0x32], fp);\r
+                       fclose(fp);\r
+                       break;\r
+                       \r
+               case 0xff03:\r
+                       // junkApi_allocBuf(_p)\r
+                       // args: P31=_p\r
+                       // retv: P31\r
+                       if (r->buf1 == NULL){\r
+                               r->buf1 = malloc(1024 * 1024);\r
+                       }\r
+                       r->preg[0x31].p = r->buf1;\r
+                       r->preg[0x31].p0 = r->buf1;\r
+                       r->preg[0x31].p1 = r->buf1 + 1024 * 1024;\r
+                       break;\r
+                       \r
+               case 0xff04:\r
+                       printf("P31.(p-p0)=%d(dec)\n", (int)(r->preg[0x31].p - r->preg[0x31].p0));\r
+                       break;\r
+                       \r
+               case 0xff05:\r
+                       // junkApi_writeStdout(len, p)\r
+                       // args: R31=len, P31=p\r
+                       // retv: (none)\r
+                       fwrite(r->preg[0x31].p, 1, r->ireg[0x31], stdout);\r
+                       break;\r
+                       \r
+               case 0xff06:\r
+                       // junkApi_exit(i)\r
+                       // args: R31=i\r
+                       // retv: (none)\r
+                       r->appReturnCode = r->ireg[31];\r
+                       longjmp(r->setjmpEnv, 1);\r
+                       break;\r
+                       \r
+               case 0xff07:\r
+                       // junkApi_putConstString0(s)\r
+                       // DB(0xff,0x00,0x00); DB%(s,0x00);\r
+                       // マシになった文字列表示.\r
+                       // OSASK文字列に対応.offにすれば通常の文字列処理もできる.\r
+                       // 現状はonのみサポート.\r
+                       checkString(r, 0x31, 0x31);\r
+                       devFunc0001(r->ireg[0x31], r->preg[0x31].p, r);\r
+                       break;\r
+                       \r
+               case 0xff08:\r
+                       // junkApi_jitc2(_rc, _p, mod, lev, di1, len, s)\r
+                       // R31=mod; R32=lev; R33=di1; R34=len; P31=s; _rc=R30; _p=P31\r
+                       // JITC on JITC\r
+                       // R31: 言語(back-end, front-end, ...\r
+                       // R32: level\r
+                       // R33: debugInfo1\r
+                       checkString(r, 0x34, 0x31);\r
+                       if (r->ireg[0x33] < 0 || r->ireg[0x33] > 15 || r->debugInfo1 > 15){\r
+                               (*(r->errHndl))(r);\r
+                       }\r
+                       for (i = 0; i < r->maxLabels; i++){\r
+                               r->label[i].opt = 0;\r
+                       }\r
+                       puc = r->preg[0x31].p;\r
+                       i = jitCompiler(r->jitbuf, r->jitbuf1, puc, puc + r->ireg[0x34], puc, r->label, r->maxLabels, r->ireg[0x32], di1_serial, JITC_NOSTARTUP + 0);\r
+                       if (i == 0) {\r
+                               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);\r
+                               if (i >= 0) {\r
+                                       r->mapDi1s[r->debugInfo1][r->ireg[0x33]] = di1_serial;\r
+                                       di1_serial++;\r
+                                       r->ireg[0x30] = 0;\r
+                                       r->preg[0x31].p = r->jitbuf;\r
+                                       r->preg[0x31].typ = 0; // TYP_CODE\r
+                                       r->preg[0x31].p0 = r->jitbuf;\r
+                                       r->preg[0x31].p1 = r->jitbuf + 1;\r
+                                       //int j; for (j = 0; j < i; j++) printf("%02X ", r->jitbuf[j]); putchar('\n');\r
+                                       r->jitbuf += i;\r
+                                       static unsigned char ff08_ret[3] = { 0x1e, 0x3f, 0x30 };\r
+                                       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);\r
+                                       r->jitbuf += i;\r
+                                       break;\r
+                               }\r
+                       }\r
+                       r->ireg[0x30] = -1;\r
+                       break;\r
+                       \r
+               case 0xff09:\r
+                       //putStringDec\r
+                       // たぶんbit7を使ったテキストはうまく処理できない(これはもはや仕様にしても問題ないかも).\r
+                       checkString(r, 0x31, 0x31);\r
+                       len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x31], r->preg[0x31].p, r->ireg[0x32], (int *)r->preg[0x32].p, r);\r
+                       devFunc0001(len, pucbuf, r);\r
+                       break;\r
+                       \r
+               case 0xff40:\r
+                       // junkApi_openWin(xsiz, ysiz) R31=xsiz; R32=ysiz;\r
+                       /* R31とR32でサイズを指定 */\r
+                       mainWindow.xsize = r->ireg[0x31];\r
+                       mainWindow.ysize = r->ireg[0x32];\r
+                       if (mainWindow.xsize <= 0 || mainWindow.ysize <= 0){\r
+                               (*(r->errHndl))(r);\r
+                       }\r
+                       r->preg[0x31].p = (void *)(mainWindow.vram = malloc(mainWindow.xsize * mainWindow.ysize * 4));\r
+                       r->preg[0x31].p0 = r->preg[0x31].p;\r
+                       r->preg[0x31].p1 = r->preg[0x31].p + mainWindow.xsize * mainWindow.ysize * 4;\r
+                       drv_openWin(r->ireg[0x31], r->ireg[0x32], r->preg[0x31].p, &r->winClosed);\r
+                       //      drv_flshWin(r->ireg[1], r->ireg[2], 0, 0);\r
+                       r->autoSleep = 1;\r
+                       for (i = mainWindow.xsize * mainWindow.ysize - 1; i >= 0; i--){\r
+                               mainWindow.vram[i] = 0;\r
+                       }\r
+                       break;\r
+                       \r
+               case 0xff41:\r
+                       // junkApi_flushWin(xsiz, ysiz, x0, y0)\r
+                       // R31=xsiz; R32=ysiz; R33=x0; R34=y0\r
+                       /* R31とR32でサイズを指定、R33とR34でx0,y0指定 */\r
+                       if (r->ireg[0x31] == -1) {\r
+                               r->ireg[0x31] = mainWindow.xsize; r->ireg[0x33] &= 0;\r
+                       }\r
+                       if (r->ireg[0x32] == -1) {\r
+                               r->ireg[0x32] = mainWindow.ysize; r->ireg[0x34] &= 0;\r
+                       }\r
+                       checkRect(r, 0x31);\r
+                       drv_flshWin(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34]);\r
+                       break;\r
+                       \r
+               case 0xff42:\r
+                       // junkApi_sleep(opt, msec) R31=opt; R32=msec\r
+                       // opt:\r
+                       //              1 = ついでにウィンドウを更新する\r
+                       //              2 = キー入力されるまでずっと待つ\r
+                       if (r->ireg[0x32] == -1) {\r
+                               // sleep forever (事実上実行は終了)\r
+                               r->autoSleep = 1;\r
+                               longjmp(r->setjmpEnv, 1);\r
+                       }\r
+                       if (r->ireg[0x32] < 0){\r
+                               // マイナス秒スリープするなんておかしい\r
+                               (*(r->errHndl))(r);\r
+                       }\r
+                       //スリープしたので終了時の自動スリープ無効\r
+                       r->autoSleep = 0;\r
+                       if ((r->ireg[0x31] & 1) == 0 && mainWindow.vram != NULL){\r
+                               // opt1:ついでにウィンドウを更新する\r
+                               drv_flshWin(mainWindow.xsize, mainWindow.ysize, 0, 0);\r
+                       }\r
+                       for (;;) {\r
+                               if (r->winClosed != 0){\r
+                                       longjmp(r->setjmpEnv, 1);\r
+                               }\r
+                               drv_sleep(r->ireg[0x32]);\r
+                               if ((r->ireg[0x31] & 2) != 0 && keybuf_c <= 0){\r
+                                       // opt2:キー入力があったので戻る\r
+                                       continue;\r
+                               }\r
+                               // 時間指定ならここに来て終了\r
+                               break;\r
+                       }\r
+                       break;\r
+                       \r
+               case 0xff43:\r
+                       // junkApi_inkey(_i, mod) R31=mod; _i=R30\r
+                       //  1:peek(キーを「のぞき見る」だけで、バッファは進めない)\r
+                       //  2:stdin\r
+                       //      4,8: ソース指定.\r
+                       //      16: shift, lock系を有効化.\r
+                       //      32: 左右のshift系を区別する.\r
+                       // カーソルキーの左右でR32は減少,増加する。\r
+                       // カーソルキーの上下でR33は減少,増加する。\r
+                       if (r->ireg[0x31] == 2) {\r
+                               // 標準入力から\r
+                               r->ireg[0x30] = fgetc(stdin);\r
+                               if (r->ireg[0x30] == EOF){\r
+                                       r->ireg[0x30] = KEY_EMPTY;\r
+                               }\r
+                               break;\r
+                       }\r
+                       r->ireg[0x30] |= -1;\r
+                       if (keybuf_c > 0) {\r
+                               // 入力された文字がある\r
+                               r->ireg[0x30] = keybuf[keybuf_r];\r
+                               if ((r->ireg[0x31] & 16) == 0){\r
+                                       // shift, lockキー([C]マークのあるキー)の無効化\r
+                                       r->ireg[0x30] &= 0x3e3effff;\r
+                               }\r
+                               if ((r->ireg[0x31] & 32) == 0){\r
+                                       // 左右の区別を無効化\r
+                                       r->ireg[0x30] |= (r->ireg[0x30] >> 8) & 0xff0000;\r
+                               }\r
+                               if ((r->ireg[0x31] & 1) != 0) {\r
+                                       // peekでないならバッファを進める\r
+                                       keybuf_c--;\r
+                                       keybuf_r = (keybuf_r + 1) & (KEYBUFSIZ - 1);\r
+                               }\r
+                       }\r
+                       r->ireg[0x32] = r->ireg[0x33] = 0;\r
+                       if (r->ireg[0x30] == KEY_LEFT){\r
+                               r->ireg[0x32]--;\r
+                       }\r
+                       if (r->ireg[0x30] == KEY_UP){\r
+                               r->ireg[0x33]--;\r
+                       }\r
+                       if (r->ireg[0x30] == KEY_RIGHT){\r
+                               r->ireg[0x32]++;\r
+                       }\r
+                       if (r->ireg[0x30] == KEY_DOWN){\r
+                               r->ireg[0x33]++;\r
+                       }\r
+                       break;\r
+                       \r
+               case 0xff44:\r
+                       // junkApi_drawPoint(mod, x, y, c) R31=mod; R32=x; R33=y; R34=c\r
+                       c = loadColor(r, 0x34);\r
+                       if (r->ireg[0x32] < 0 || r->ireg[0x32] >= mainWindow.xsize ||\r
+                               r->ireg[0x33] < 0 || r->ireg[0x33] >= mainWindow.ysize){\r
+                               (*(r->errHndl))(r);\r
+                       }\r
+                       \r
+                       switch ((r->ireg[0x31] & 3)) {\r
+                               case 0:\r
+                                       mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] = c;\r
+                                       break;\r
+                               case 1:\r
+                                       mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] |= c;\r
+                                       break;\r
+                               case 2:\r
+                                       mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] ^= c;\r
+                                       break;\r
+                               case 3:\r
+                                       mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] &= c;\r
+                                       break;\r
+                       }\r
+                       break;\r
+                       \r
+               case 0xff45:\r
+                       // 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\r
+                       //drawLine\r
+                       c = loadColor(r, 0x36);\r
+                       if (r->ireg[0x32] < 0 || r->ireg[0x32] >= mainWindow.xsize ||\r
+                               r->ireg[0x33] < 0 || r->ireg[0x33] >= mainWindow.ysize){\r
+                               (*(r->errHndl))(r);\r
+                       }\r
+                       if (r->ireg[0x34] < 0 || r->ireg[0x34] >= mainWindow.xsize ||\r
+                               r->ireg[0x35] < 0 || r->ireg[0x35] >= mainWindow.ysize){\r
+                               (*(r->errHndl))(r);\r
+                       }\r
+                       dx = r->ireg[0x34] - r->ireg[0x32];\r
+                       dy = r->ireg[0x35] - r->ireg[0x33];\r
+                       x = r->ireg[0x32] << 10;\r
+                       y = r->ireg[0x33] << 10;\r
+                       if (dx < 0){\r
+                               dx = -dx;\r
+                       }\r
+                       if (dy < 0){\r
+                               dy = -dy;\r
+                       }\r
+                       if (dx >= dy) {\r
+                               len = dx + 1; dx = 1024;\r
+                               if (r->ireg[0x32] > r->ireg[0x34]){\r
+                                       dx *= -1;\r
+                               }\r
+                               if (r->ireg[0x33] > r->ireg[0x35]){\r
+                                       dy *= -1;\r
+                               }\r
+                               dy = (dy << 10) / len;\r
+                       } else {\r
+                               len = dy + 1; dy = 1024;\r
+                               if (r->ireg[0x33] > r->ireg[0x35]){\r
+                                       dy *= -1;\r
+                               }\r
+                               if (r->ireg[0x32] > r->ireg[0x34]){\r
+                                       dx *= -1;\r
+                               }\r
+                               dx = (dx << 10) / len;\r
+                       }\r
+                       if ((r->ireg[0x31] & 3) == 0) {\r
+                               for (i = 0; i < len; i++) {\r
+                                       mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] = c;\r
+                                       x += dx;\r
+                                       y += dy;\r
+                               }\r
+                               break;\r
+                       }\r
+                       for (i = 0; i < len; i++) {\r
+                               //      if ((r->ireg[0x31] & 3) == 0) vram[(x >> 10) + (y >> 10) * v_xsiz] =  c;\r
+                               switch ((r->ireg[0x31] & 3)) {\r
+                                       case 1:\r
+                                               mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] |= c;\r
+                                               break;\r
+                                       case 2:\r
+                                               mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] ^= c;\r
+                                               break;\r
+                                       case 3:\r
+                                               mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] &= c;\r
+                                               break;\r
+                                       default:\r
+                                               break;\r
+                               }\r
+                               x += dx;\r
+                               y += dy;\r
+                       }\r
+                       break;\r
+                       \r
+               case 0xff46:\r
+                       // fillRect(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)\r
+                       c = loadColor(r, 0x36);\r
+                       if (r->ireg[0x32] == -1) { r->ireg[0x32] = mainWindow.xsize; r->ireg[0x34] &= 0; }\r
+                       if (r->ireg[0x33] == -1) { r->ireg[0x33] = mainWindow.ysize; r->ireg[0x35] &= 0; }\r
+                       checkRect(r, 0x32);\r
+                       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;\r
+                       if ((r->ireg[0x31] & 0x20) == 0) {\r
+                               devFunc0004(mod3, x0, y0, x1, y1, c);\r
+                       } else {        // drawRect\r
+                               devFunc0004(mod3, x0, y0, x1, y0, c);\r
+                               devFunc0004(mod3, x0, y1, x1, y1, c);\r
+                               devFunc0004(mod3, x0, y0, x0, y1, c);\r
+                               devFunc0004(mod3, x1, y0, x1, y1, c);\r
+                       }\r
+                       break;\r
+                       \r
+               case 0xff47:\r
+                       // fillOval(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)\r
+                       // これの計算精度はアーキテクチャに依存する.\r
+                       c = loadColor(r, 0x36);\r
+                       if (r->ireg[0x32] == -1) {\r
+                               r->ireg[0x32] = mainWindow.xsize; r->ireg[0x34] &= 0;\r
+                       }\r
+                       if (r->ireg[0x33] == -1) {\r
+                               r->ireg[0x33] = mainWindow.ysize; r->ireg[0x35] &= 0;\r
+                       }\r
+                       checkRect(r, 0x32);\r
+                       double dcx = 0.5 * (r->ireg[0x32] - 1);\r
+                       double dcy = 0.5 * (r->ireg[0x33] - 1);\r
+                       double dcxy = (dcx + 0.5) * (dcy + 0.5) - 0.1;\r
+                       dcxy *= dcxy;\r
+                       mod3 = r->ireg[0x31] & 3;\r
+                       x1 = r->ireg[0x32];\r
+                       y1 = r->ireg[0x33];\r
+                       if (mod3 == 0 && (r->ireg[0x31] & 0x20) == 0) {\r
+                               for (y = 0; y < y1; y++) {\r
+                                       double dty = (y - dcy) * dcx;\r
+                                       for (x = 0; x < x1; x++) {\r
+                                               double dtx = (x - dcx) * dcy;\r
+                                               if (dtx * dtx + dty * dty > dcxy){\r
+                                                       continue;\r
+                                               }\r
+                                               mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] = c;\r
+                                       }\r
+                               }\r
+                       } else {\r
+#define DRAWOVALPARAM  1\r
+                               double dcx1 = 0.5 * (r->ireg[0x32] - (1 + DRAWOVALPARAM * 2));\r
+                               double dcy1 = 0.5 * (r->ireg[0x33] - (1 + DRAWOVALPARAM * 2));\r
+                               double dcxy1 = (dcx1 + 0.5) * (dcy1 + 0.5) - 0.1;\r
+                               dcxy1 *= dcxy1;\r
+                               for (y = 0; y < y1; y++) {\r
+                                       double dty = (y - dcy) * dcx;\r
+                                       double dty1 = (y - dcy) * dcx1;\r
+                                       for (x = 0; x < x1; x++) {\r
+                                               double dtx = (x - dcx) * dcy;\r
+                                               double dtx1 = (x - dcx) * dcy1;\r
+                                               if (dtx * dtx + dty * dty > dcxy){\r
+                                                       continue;\r
+                                               }\r
+                                               if (DRAWOVALPARAM <= x && x < x1 - DRAWOVALPARAM && DRAWOVALPARAM <= y && y < y1 - DRAWOVALPARAM) {\r
+                                                       if (dtx1 * dtx1 + dty1 * dty1 < dcxy1){\r
+                                                               continue;\r
+                                                       }\r
+                                               }\r
+                                               switch (mod3) {\r
+                                                       case 0:\r
+                                                               mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] = c;\r
+                                                               break;\r
+                                                       case 1:\r
+                                                               mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] |= c;\r
+                                                               break;\r
+                                                       case 2:\r
+                                                               mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] ^= c;\r
+                                                               break;\r
+                                                       case 3:\r
+                                                               mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] &= c;\r
+                                                               break;\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+                       break;\r
+                       \r
+               case 0xff48:\r
+                       // drawString(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36, s.len:R37, s.p:P31)\r
+                       checkString(r, 0x37, 0x31);\r
+                       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);\r
+                       break;\r
+                       \r
+               case 0xff49:\r
+                       // junkApi_rand(_r, range) R31=range; _r=R30\r
+                       // **** junkApi_rand(i, max) ****\r
+                       // 0 <= i <= maxとなるiを返す。\r
+                       // max==0のとき、iはSINT32全体を範囲とする乱数となる。\r
+                       r->ireg[0x30] = randGetNextUInt32();\r
+                       if (r->ireg[0x31] > 0){\r
+                               r->ireg[0x30] = (r->ireg[0x30] & 0x7fffffff) % (r->ireg[0x31] + 1);\r
+                       }\r
+                       break;\r
+                       \r
+               case 0xff4a:\r
+                       // srand\r
+                       randStatInit(r->ireg[0x31]);\r
+                       break;\r
+                       \r
+               case 0xff4b:\r
+                       // srand(random)\r
+                       r->ireg[0x30] = (int)(time(NULL) ^ (long)0x55555555);\r
+                       break;\r
+                       \r
+               case 0xff4c:\r
+                       // drawStringDec\r
+                       checkString(r, 0x37, 0x31);\r
+                       len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x37], r->preg[0x31].p, r->ireg[0x38], (int *)r->preg[0x32].p, r);\r
+                       devFunc0006(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34], r->ireg[0x35], loadColor(r, 0x36), len, pucbuf, r);\r
+                       break;\r
+                       \r
+               case 0xff4d:\r
+                       // bitblt(mod, xsiz, ysiz, xscale, yscale, x0, y0, lineskip, inv, p_buf, typ0, p_table, typ1); \r
+                       // mod: 0x20:use_table, 0x40:inv_is_visible & typ1_is_color\r
+                       puc = r->preg[0x31].p;\r
+                       mod3 = r->ireg[0x31] & 3;\r
+                       dx = r->ireg[0x34];\r
+                       dy = r->ireg[0x35];\r
+                       if (dy == 0){\r
+                               dy = dx;\r
+                       }\r
+                       if (r->ireg[0x32] == -1) {\r
+                               r->ireg[0x32] = mainWindow.xsize / dx; r->ireg[0x36] &= 0;\r
+                       }\r
+                       if (r->ireg[0x33] == -1) {\r
+                               r->ireg[0x33] = mainWindow.ysize / dy; r->ireg[0x37] &= 0;\r
+                       }\r
+                       for (y = 0; y < r->ireg[0x33]; y++) {\r
+                               y0 = y * dy + r->ireg[0x37];\r
+                               for (x = 0; x < r->ireg[0x32]; x++) {\r
+                                       x0 = x * dx + r->ireg[0x36];\r
+                                       c = iColor1[*puc++];\r
+                                       devFunc0004(mod3, x0, y0, x0 + dx, y0 + dy, c);\r
+                               }\r
+                               puc += r->ireg[0x38];\r
+                       }\r
+                       break;\r
+                       \r
+               default:\r
+                       printf("devFunc: error: R30=%08X\n", r->ireg[0x30]);\r
+                       exit(EXIT_FAILURE);\r
+                       \r
+       }\r
+       return;\r
+}\r
+\r
+\r
+\r