-#include "osecpu.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) - 128);\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
- if (r->ireg[0x32] == -1) {\r
- r->autoSleep = 1;\r
- longjmp(r->setjmpEnv, 1);\r
- }\r
- if (r->ireg[0x32] < 0){\r
- (*(r->errHndl))(r);\r
- }\r
- r->autoSleep = 0;\r
- if ((r->ireg[0x31] & 1) == 0 && mainWindow.vram != NULL){\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
- continue;\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
- if (r->ireg[0x31] == 2) { // なぜ3にしなかったのか...\r
- r->ireg[0x30] = fgetc(stdin);\r
- if (r->ireg[0x30] == EOF){\r
- r->ireg[0x30] = -1;\r
- }\r
- break;\r
- }\r
- r->ireg[0x30] |= -1;\r
- if (keybuf_c > 0) {\r
- r->ireg[0x30] = keybuf[keybuf_r];\r
- if ((r->ireg[0x31] & 16) == 0){\r
- r->ireg[0x30] &= 0x3e3effff;\r
- }\r
- if ((r->ireg[0x31] & 32) == 0){\r
- r->ireg[0x30] |= (r->ireg[0x30] >> 8) & 0xff0000;\r
- }\r
- if ((r->ireg[0x31] & 1) != 0) {\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] == 4132) r->ireg[0x32]--;\r
- if (r->ireg[0x30] == 4133) r->ireg[0x33]--;\r
- if (r->ireg[0x30] == 4134) r->ireg[0x32]++;\r
- if (r->ireg[0x30] == 4135) r->ireg[0x33]++;\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
+#include "osecpu.h"
+#include "jitc.h"
+
+extern unsigned char fontdata[]; // @fontdata.c
+
+const char *searchArg(int argc, const char **argv, const char *tag, int i)
+{
+ // 引数リストargvの中から、文字列tagが前方一致する引数のi番目を探し出し、
+ // その引数の文字列の、tagに続く部分の文字へのポインタを返す。
+ 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)
+{
+ // OSASK文字列の出力
+ 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)
+{
+ // drawString
+ 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)
+{
+ // FillRect
+ 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++) {
+ switch (mod) {
+ 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;
+ }
+ }
+ }
+ }
+ return;
+}
+
+int devFunc0016(int buflen, unsigned char *buf, int plen, unsigned char *p, int qlen, int *q, HOSECPU_RuntimeEnvironment *r)
+{
+ // OSASK文字列への変換?
+ 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;
+ int i, c;
+ int x, y, len, dx, dy;
+ unsigned char *puc;
+ unsigned char pucbuf[256];
+
+ //サイズを節約するためにEBPを128バイトずらしているのを元に戻す
+ r = (HOSECPU_RuntimeEnvironment *) (((char *)r) - jitCompA0001_EBP128);
+
+ 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:
+ // junkApi_fopenRead(_filesize, _p, arg)
+ // args: R31=arg, R30=_filesize, P31=_p
+ // retv: 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:
+ // junkApi_fopenWrite(arg, filesize, p)
+ // args: R31=arg, R32=filesize, P31=p
+ // retv: (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:
+ // junkApi_allocBuf(_p)
+ // args: P31=_p
+ // retv: 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:
+ // junkApi_writeStdout(len, p)
+ // args: R31=len, P31=p
+ // retv: (none)
+ fwrite(r->preg[0x31].p, 1, r->ireg[0x31], stdout);
+ break;
+
+ case 0xff06:
+ // junkApi_exit(i)
+ // args: R31=i
+ // retv: (none)
+ r->appReturnCode = r->ireg[31];
+ longjmp(r->setjmpEnv, 1);
+ break;
+
+ case 0xff07:
+ // junkApi_putConstString0(s)
+ // DB(0xff,0x00,0x00); DB%(s,0x00);
+ // マシになった文字列表示.
+ // OSASK文字列に対応.offにすれば通常の文字列処理もできる.
+ // 現状はonのみサポート.
+ checkString(r, 0x31, 0x31);
+ devFunc0001(r->ireg[0x31], r->preg[0x31].p, r);
+ break;
+
+ 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
+ // 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:
+ //putStringDec
+ // たぶん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:
+ // junkApi_openWin(xsiz, ysiz) R31=xsiz; R32=ysiz;
+ /* 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:
+ // junkApi_flushWin(xsiz, ysiz, x0, y0)
+ // R31=xsiz; R32=ysiz; R33=x0; R34=y0
+ /* 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:
+ // junkApi_sleep(opt, msec) R31=opt; R32=msec
+ 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:
+ // junkApi_inkey(_i, mod) R31=mod; _i=R30
+ // 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:
+ // junkApi_drawPoint(mod, x, y, c) R31=mod; R32=x; R33=y; R34=c
+ 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);
+ }
+
+ switch ((r->ireg[0x31] & 3)) {
+ case 0:
+ mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] = c;
+ break;
+ case 1:
+ mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] |= c;
+ break;
+ case 2:
+ mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] ^= c;
+ break;
+ case 3:
+ mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] &= c;
+ break;
+ }
+ break;
+
+ 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
+ //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;
+ switch ((r->ireg[0x31] & 3)) {
+ case 1:
+ mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] |= c;
+ break;
+ case 2:
+ mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] ^= c;
+ break;
+ case 3:
+ mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] &= c;
+ break;
+ default:
+ break;
+ }
+ 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);
+ double dcy = 0.5 * (r->ireg[0x33] - 1);
+ double 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));
+ double dcy1 = 0.5 * (r->ireg[0x33] - (1 + DRAWOVALPARAM * 2));
+ double 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;
+ }
+ }
+ switch (mod3) {
+ case 0:
+ mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] = c;
+ break;
+ case 1:
+ mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] |= c;
+ break;
+ case 2:
+ mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] ^= c;
+ break;
+ case 3:
+ mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] &= c;
+ break;
+ }
+ }
+ }
+ }
+ 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(_r, range) R31=range; _r=R30
+ // **** 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:
+ // srand
+ randStatInit(r->ireg[0x31]);
+ break;
+
+ case 0xff4b:
+ // srand(random)
+ r->ireg[0x30] = (int)(time(NULL) ^ (long)0x55555555);
+ break;
+
+ case 0xff4c:
+ // drawStringDec
+ 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(EXIT_FAILURE);
+
+ }
+ return;
+}
+
+
+