3 extern unsigned char fontdata[]; // @fontdata.c
5 const char *searchArg(int argc, const char **argv, const char *tag, int i)
11 for (j = 1; j < argc; j++) {
12 if (strncmp(argv[j], tag, l) == 0) {
22 for (j = 1; j < argc; j++) {
23 if (strchr(argv[j], ':') == NULL) {
38 void devFunc0001(int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r)
41 putOsaskChar(*puc++, r);
48 void devFunc0006(int mod, int sx, int sy, int x, int y, int c, int len, unsigned char *puc, HOSECPU_RuntimeEnvironment *r)
52 int i, ddx, ddy, j, ch, dx, dy;
59 if (xx <= 0 || xx > mainWindow.xsize || yy <= 0 || yy > mainWindow.ysize){
62 if (x < 0 || x >= mainWindow.xsize || y < 0 || y >= mainWindow.ysize){
67 if ((mod & 3) == 0 && sx == 1 && sy == 1) {
69 for (i = 0; i < len; i++) {
71 if (0x10 <= ch && ch <= 0x1f)
72 ch = "0123456789ABCDEF"[ch & 0x0f];
73 for (dy = 0; dy < 16; dy++) {
74 j = fontdata[(ch - ' ') * 16 + dy];
75 for (dx = 0; dx < 8; dx++) {
76 if ((j & (0x80 >> dx)) != 0){
77 mainWindow.vram[(x + dx) + (y + dy) * mainWindow.xsize] = c;
85 for (i = 0; i < len; i++) {
87 if (0x10 <= ch && ch <= 0x1f)
88 ch = "0123456789ABCDEF"[ch & 0x0f];
89 for (dy = 0; dy < 16; dy++) {
90 j = fontdata[(ch - ' ') * 16 + dy];
91 for (ddy = 0; ddy < sy; ddy++) {
92 for (dx = 0; dx < 8; dx++) {
93 if ((j & (0x80 >> dx)) != 0) {
94 for (ddx = 0; ddx < sx; ddx++) {
97 mainWindow.vram[x + y * mainWindow.xsize] = c;
100 mainWindow.vram[x + y * mainWindow.xsize] |= c;
103 mainWindow.vram[x + y * mainWindow.xsize] ^= c;
106 mainWindow.vram[x + y * mainWindow.xsize] &= c;
125 void devFunc0004(int mod, int x0, int y0, int x1, int y1, int c)
129 for (y = y0; y <= y1; y++) {
130 for (x = x0; x <= x1; x++) {
131 mainWindow.vram[x + y * mainWindow.xsize] = c;
136 for (y = y0; y <= y1; y++) {
137 for (x = x0; x <= x1; x++) {
140 mainWindow.vram[x + y * mainWindow.xsize] |= c;
143 mainWindow.vram[x + y * mainWindow.xsize] ^= c;
146 mainWindow.vram[x + y * mainWindow.xsize] &= c;
155 int devFunc0016(int buflen, unsigned char *buf, int plen, unsigned char *p, int qlen, int *q, HOSECPU_RuntimeEnvironment *r)
157 int i = 0, base, j, k;
187 if (base < 0 || base > 16){
190 if (q[1] + i > buflen){
194 if ((q[2] & 4) == 0) {
196 if ((q[2] & 8) != 0 && j > 0){
204 if ((q[2] & 8) != 0 && j != 0){
208 for (k = q[1] - 1; k >= 0; k--) {
209 buf[i + k] = (j % base) + 0x10;
210 j = ((unsigned)j) / base;
213 if ((q[2] & 2) == 0 && j == 0) {
214 for (k = 0; k < q[1] - 1; k++) {
215 if (buf[i + k] != 0x10){
227 if ((q[2] & 1) != 0 && buf[i] == ' ') {
228 for (j = 0; k < q[1]; k++, j++){
229 buf[i + j] = buf[i + k];
241 void devFunc(HOSECPU_RuntimeEnvironment *r)
245 int x, y, len, dx, dy;
247 unsigned char pucbuf[256];
249 //サイズを節約するためにEBPを128バイトずらしているのを元に戻す
250 r = (HOSECPU_RuntimeEnvironment *) (((char *)r) - 128);
252 if (r->winClosed != 0){
253 longjmp(*(r->setjmpEnv), 1);
255 if (0xff44 <= r->ireg[0x30] && r->ireg[0x30] <= 0xff48) {
256 if (mainWindow.vram == NULL) {
257 mainWindow.xsize = 640;
258 mainWindow.ysize = 480;
259 mainWindow.vram = malloc(640 * 480 * 4);
260 drv_openWin(640, 480, (void *)mainWindow.vram, &r->winClosed);
262 for (i = 640 * 480 - 1; i >= 0; i--){
263 mainWindow.vram[i] = 0;
268 switch (r->ireg[0x30]){
270 printf("R31=%d(dec)\n", r->ireg[0x31]);
273 case 0xff01: // junkApi_fopenRead(_filesize, _p, arg) R31=arg; PCALL(P28); _filesize=R30; _p=P31
275 /* return: R30, P31 */
276 if (r->buf0 == NULL){
277 r->buf0 = malloc(1024 * 1024);
279 if (r->mainArgc <= r->ireg[0x31]) {
280 fprintf(stderr, "devFunc: error: R30=ff01: argc error: R31=%08X\n", r->ireg[0x31]);
283 fp = fopen(r->mainArgv[r->ireg[0x31]], "rb");
285 fprintf(stderr, "devFunc: error: R30=ff01: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]);
288 i = (int)fread(r->buf0, 1, 1024 * 1024 - 4, fp);
289 if (i >= 1024 * 1024 - 4 || i < 0) {
290 fprintf(stderr, "devFunc: error: R30=ff01: fread error: '%s'\n", r->mainArgv[r->ireg[0x31]]);
294 r->preg[0x31].p = r->buf0;
295 r->preg[0x31].p0 = r->buf0;
296 r->preg[0x31].p1 = r->buf0 + i;
297 r->preg[0x31].typ = 3; // T_UINT8
301 case 0xff02: // junkApi_fopenWrite(arg, filesize, p) R31=arg; R32=filesize; P31=p;
303 if (r->mainArgc <= r->ireg[0x31]) {
304 fprintf(stderr, "devFunc: error: R30=ff02: argc error: R31=%08X\n", r->ireg[0x31]);
307 fp = fopen(r->mainArgv[r->ireg[0x31]], "wb");
309 fprintf(stderr, "devFunc: error: R30=ff02: fopen error: '%s'\n", r->mainArgv[r->ireg[0x31]]);
312 if (r->ireg[0x32] >= 1024 * 1024 || r->ireg[0x32] < 0){
313 fprintf(stderr, "devFunc: error: R30=ff02: fwrite error: R02=%08X\n", r->ireg[0x32]);
316 fwrite(r->preg[0x31].p, 1, r->ireg[0x32], fp);
320 case 0xff03: // junkApi_allocBuf(_p) _p=P31
322 if (r->buf1 == NULL){
323 r->buf1 = malloc(1024 * 1024);
325 r->preg[0x31].p = r->buf1;
326 r->preg[0x31].p0 = r->buf1;
327 r->preg[0x31].p1 = r->buf1 + 1024 * 1024;
331 printf("P31.(p-p0)=%d(dec)\n", (int)(r->preg[0x31].p - r->preg[0x31].p0));
334 case 0xff05: // junkApi_writeStdout(len, p) R31=len; P31=p;
335 fwrite(r->preg[0x31].p, 1, r->ireg[0x31], stdout);
338 case 0xff06: // jnukApi_exit(i) R31=i;
340 // これを反映すべきだが、現状は手抜きでいつも正常終了.
341 longjmp(*(r->setjmpEnv), 1);
344 case 0xff07: // junkApi_putConstString0(s) DB(0xff,0x00,0x00); DB%(s,0x00);
345 // マシになった文字列表示.OSASK文字列に対応.offにすれば通常の文字列処理もできる.現状はonのみサポート.
346 checkString(r, 0x31, 0x31);
347 devFunc0001(r->ireg[0x31], r->preg[0x31].p, r);
350 case 0xff08: // junkApi_jitc2(_rc, _p, mod, lev, di1, len, s) R31=mod; R32=lev; R33=di1; R34=len; P31=s; _rc=R30; _p=P31
352 // R31: 言語(back-end, front-end, ...
355 checkString(r, 0x34, 0x31);
356 if (r->ireg[0x33] < 0 || r->ireg[0x33] > 15 || r->debugInfo1 > 15){
359 for (i = 0; i < r->maxLabels; i++){
362 puc = r->preg[0x31].p;
363 i = jitCompiler(r->jitbuf, r->jitbuf1, puc, puc + r->ireg[0x34], puc, r->label, r->maxLabels, r->ireg[0x32], di1_serial, JITC_NOSTARTUP + 0);
365 i = jitCompiler(r->jitbuf, r->jitbuf1, puc, puc + r->ireg[0x34], puc, r->label, r->maxLabels, r->ireg[0x32], di1_serial, JITC_NOSTARTUP + JITC_PHASE1 + 0);
367 r->mapDi1s[r->debugInfo1][r->ireg[0x33]] = di1_serial;
370 r->preg[0x31].p = r->jitbuf;
371 r->preg[0x31].typ = 0; // TYP_CODE
372 r->preg[0x31].p0 = r->jitbuf;
373 r->preg[0x31].p1 = r->jitbuf + 1;
374 //int j; for (j = 0; j < i; j++) printf("%02X ", r->jitbuf[j]); putchar('\n');
376 static unsigned char ff08_ret[3] = { 0x1e, 0x3f, 0x30 };
377 i = jitCompiler(r->jitbuf, r->jitbuf1, ff08_ret, ff08_ret + 3, puc, r->label, r->maxLabels, r->ireg[0x32], -1, JITC_NOSTARTUP + JITC_PHASE1 + 0);
385 case 0xff09: //putStringDec
386 // たぶんbit7を使ったテキストはうまく処理できない(これはもはや仕様にしても問題ないかも).
387 checkString(r, 0x31, 0x31);
388 len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x31], r->preg[0x31].p, r->ireg[0x32], (int *)r->preg[0x32].p, r);
389 devFunc0001(len, pucbuf, r);
392 case 0xff40: // junkApi_openWin(xsiz, ysiz) R31=xsiz; R32=ysiz;
394 mainWindow.xsize = r->ireg[0x31];
395 mainWindow.ysize = r->ireg[0x32];
396 if (mainWindow.xsize <= 0 || mainWindow.ysize <= 0){
399 r->preg[0x31].p = (void *)(mainWindow.vram = malloc(mainWindow.xsize * mainWindow.ysize * 4));
400 r->preg[0x31].p0 = r->preg[0x31].p;
401 r->preg[0x31].p1 = r->preg[0x31].p + mainWindow.xsize * mainWindow.ysize * 4;
402 drv_openWin(r->ireg[0x31], r->ireg[0x32], r->preg[0x31].p, &r->winClosed);
403 // drv_flshWin(r->ireg[1], r->ireg[2], 0, 0);
405 for (i = mainWindow.xsize * mainWindow.ysize - 1; i >= 0; i--){
406 mainWindow.vram[i] = 0;
410 case 0xff41: // junkApi_flushWin(xsiz, ysiz, x0, y0) R31=xsiz; R32=ysiz; R33=x0; R34=y0
411 /* R31とR32でサイズを指定、R33とR34でx0,y0指定 */
412 if (r->ireg[0x31] == -1) {
413 r->ireg[0x31] = mainWindow.xsize; r->ireg[0x33] &= 0;
415 if (r->ireg[0x32] == -1) {
416 r->ireg[0x32] = mainWindow.ysize; r->ireg[0x34] &= 0;
419 drv_flshWin(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34]);
422 case 0xff42: // junkApi_sleep(opt, msec) R31=opt; R32=msec
423 if (r->ireg[0x32] == -1) {
425 longjmp(*(r->setjmpEnv), 1);
427 if (r->ireg[0x32] < 0){
431 if ((r->ireg[0x31] & 1) == 0 && mainWindow.vram != NULL){
432 drv_flshWin(mainWindow.xsize, mainWindow.ysize, 0, 0);
435 if (r->winClosed != 0){
436 longjmp(*(r->setjmpEnv), 1);
438 drv_sleep(r->ireg[0x32]);
439 if ((r->ireg[0x31] & 2) != 0 && keybuf_c <= 0){
446 case 0xff43: // junkApi_inkey(_i, mod) R31=mod; _i=R30
450 // 16: shift, lock系を有効化.
451 // 32: 左右のshift系を区別する.
452 if (r->ireg[0x31] == 2) { // なぜ3にしなかったのか...
453 r->ireg[0x30] = fgetc(stdin);
454 if (r->ireg[0x30] == EOF){
461 r->ireg[0x30] = keybuf[keybuf_r];
462 if ((r->ireg[0x31] & 16) == 0){
463 r->ireg[0x30] &= 0x3e3effff;
465 if ((r->ireg[0x31] & 32) == 0){
466 r->ireg[0x30] |= (r->ireg[0x30] >> 8) & 0xff0000;
468 if ((r->ireg[0x31] & 1) != 0) {
470 keybuf_r = (keybuf_r + 1) & (KEYBUFSIZ - 1);
473 r->ireg[0x32] = r->ireg[0x33] = 0;
474 if (r->ireg[0x30] == 4132) r->ireg[0x32]--;
475 if (r->ireg[0x30] == 4133) r->ireg[0x33]--;
476 if (r->ireg[0x30] == 4134) r->ireg[0x32]++;
477 if (r->ireg[0x30] == 4135) r->ireg[0x33]++;
480 case 0xff44: // junkApi_drawPoint(mod, x, y, c) R31=mod; R32=x; R33=y; R34=c
481 c = loadColor(r, 0x34);
482 if (r->ireg[0x32] < 0 || r->ireg[0x32] >= mainWindow.xsize ||
483 r->ireg[0x33] < 0 || r->ireg[0x33] >= mainWindow.ysize){
487 switch ((r->ireg[0x31] & 3)) {
489 mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] = c;
492 mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] |= c;
495 mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] ^= c;
498 mainWindow.vram[r->ireg[0x32] + r->ireg[0x33] * mainWindow.xsize] &= c;
503 case 0xff45: // junkApi_drawLine(mod, x0, y0, x1, y1, c) DB(0xfe,0x05,0x01); DDBE(0x0003); R30=0xff45; R31=mod; R32=x0; R33=y0; R34=x1; R35=y1; R36=c
505 c = loadColor(r, 0x36);
506 if (r->ireg[0x32] < 0 || r->ireg[0x32] >= mainWindow.xsize ||
507 r->ireg[0x33] < 0 || r->ireg[0x33] >= mainWindow.ysize){
510 if (r->ireg[0x34] < 0 || r->ireg[0x34] >= mainWindow.xsize ||
511 r->ireg[0x35] < 0 || r->ireg[0x35] >= mainWindow.ysize){
514 dx = r->ireg[0x34] - r->ireg[0x32];
515 dy = r->ireg[0x35] - r->ireg[0x33];
516 x = r->ireg[0x32] << 10;
517 y = r->ireg[0x33] << 10;
525 len = dx + 1; dx = 1024;
526 if (r->ireg[0x32] > r->ireg[0x34]){
529 if (r->ireg[0x33] > r->ireg[0x35]){
532 dy = (dy << 10) / len;
534 len = dy + 1; dy = 1024;
535 if (r->ireg[0x33] > r->ireg[0x35]){
538 if (r->ireg[0x32] > r->ireg[0x34]){
541 dx = (dx << 10) / len;
543 if ((r->ireg[0x31] & 3) == 0) {
544 for (i = 0; i < len; i++) {
545 mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] = c;
551 for (i = 0; i < len; i++) {
552 // if ((r->ireg[0x31] & 3) == 0) vram[(x >> 10) + (y >> 10) * v_xsiz] = c;
553 switch ((r->ireg[0x31] & 3)) {
555 mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] |= c;
558 mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] ^= c;
561 mainWindow.vram[(x >> 10) + (y >> 10) * mainWindow.xsize] &= c;
571 case 0xff46: // fillRect(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)
572 c = loadColor(r, 0x36);
573 if (r->ireg[0x32] == -1) { r->ireg[0x32] = mainWindow.xsize; r->ireg[0x34] &= 0; }
574 if (r->ireg[0x33] == -1) { r->ireg[0x33] = mainWindow.ysize; r->ireg[0x35] &= 0; }
576 int mod3 = r->ireg[0x31] & 3, x0 = r->ireg[0x34], y0 = r->ireg[0x35], x1 = r->ireg[0x34] + r->ireg[0x32] - 1, y1 = r->ireg[0x35] + r->ireg[0x33] - 1;
577 if ((r->ireg[0x31] & 0x20) == 0) {
578 devFunc0004(mod3, x0, y0, x1, y1, c);
580 devFunc0004(mod3, x0, y0, x1, y0, c);
581 devFunc0004(mod3, x0, y1, x1, y1, c);
582 devFunc0004(mod3, x0, y0, x0, y1, c);
583 devFunc0004(mod3, x1, y0, x1, y1, c);
587 case 0xff47: // fillOval(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36)
588 // これの計算精度はアーキテクチャに依存する.
589 c = loadColor(r, 0x36);
590 if (r->ireg[0x32] == -1) {
591 r->ireg[0x32] = mainWindow.xsize; r->ireg[0x34] &= 0;
593 if (r->ireg[0x33] == -1) {
594 r->ireg[0x33] = mainWindow.ysize; r->ireg[0x35] &= 0;
597 double dcx = 0.5 * (r->ireg[0x32] - 1);
598 double dcy = 0.5 * (r->ireg[0x33] - 1);
599 double dcxy = (dcx + 0.5) * (dcy + 0.5) - 0.1;
601 mod3 = r->ireg[0x31] & 3;
604 if (mod3 == 0 && (r->ireg[0x31] & 0x20) == 0) {
605 for (y = 0; y < y1; y++) {
606 double dty = (y - dcy) * dcx;
607 for (x = 0; x < x1; x++) {
608 double dtx = (x - dcx) * dcy;
609 if (dtx * dtx + dty * dty > dcxy){
612 mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] = c;
616 #define DRAWOVALPARAM 1
617 double dcx1 = 0.5 * (r->ireg[0x32] - (1 + DRAWOVALPARAM * 2));
618 double dcy1 = 0.5 * (r->ireg[0x33] - (1 + DRAWOVALPARAM * 2));
619 double dcxy1 = (dcx1 + 0.5) * (dcy1 + 0.5) - 0.1;
621 for (y = 0; y < y1; y++) {
622 double dty = (y - dcy) * dcx;
623 double dty1 = (y - dcy) * dcx1;
624 for (x = 0; x < x1; x++) {
625 double dtx = (x - dcx) * dcy;
626 double dtx1 = (x - dcx) * dcy1;
627 if (dtx * dtx + dty * dty > dcxy){
630 if (DRAWOVALPARAM <= x && x < x1 - DRAWOVALPARAM && DRAWOVALPARAM <= y && y < y1 - DRAWOVALPARAM) {
631 if (dtx1 * dtx1 + dty1 * dty1 < dcxy1){
637 mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] = c;
640 mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] |= c;
643 mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] ^= c;
646 mainWindow.vram[(x + r->ireg[0x34]) + (y + r->ireg[0x35]) * mainWindow.xsize] &= c;
654 case 0xff48: // drawString(opt:R31, xsiz:R32, ysiz:R33, x0:R34, y0:R35, c:R36, s.len:R37, s.p:P31)
655 checkString(r, 0x37, 0x31);
656 devFunc0006(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34], r->ireg[0x35], loadColor(r, 0x36), r->ireg[0x37], r->preg[0x31].p, r);
659 case 0xff49: // junkApi_rand(_r, range) R31=range; _r=R30
660 // **** junkApi_rand(i, max) ****
661 // 0 <= i <= maxとなるiを返す。
662 // max==0のとき、iはSINT32全体を範囲とする乱数となる。
663 r->ireg[0x30] = randGetNextUInt32();
664 if (r->ireg[0x31] > 0){
665 r->ireg[0x30] = (r->ireg[0x30] & 0x7fffffff) % (r->ireg[0x31] + 1);
669 case 0xff4a: /* seedの指定 */
670 randStatInit(r->ireg[0x31]);
673 case 0xff4b: /* 適当なseedを提供 */
674 r->ireg[0x30] = (int)(time(NULL) ^ (long)0x55555555);
677 case 0xff4c: // drawStringDec
678 checkString(r, 0x37, 0x31);
679 len = devFunc0016(sizeof pucbuf, pucbuf, r->ireg[0x37], r->preg[0x31].p, r->ireg[0x38], (int *)r->preg[0x32].p, r);
680 devFunc0006(r->ireg[0x31], r->ireg[0x32], r->ireg[0x33], r->ireg[0x34], r->ireg[0x35], loadColor(r, 0x36), len, pucbuf, r);
684 // bitblt(mod, xsiz, ysiz, xscale, yscale, x0, y0, lineskip, inv, p_buf, typ0, p_table, typ1);
685 // mod: 0x20:use_table, 0x40:inv_is_visible & typ1_is_color
686 puc = r->preg[0x31].p;
687 mod3 = r->ireg[0x31] & 3;
693 if (r->ireg[0x32] == -1) {
694 r->ireg[0x32] = mainWindow.xsize / dx; r->ireg[0x36] &= 0;
696 if (r->ireg[0x33] == -1) {
697 r->ireg[0x33] = mainWindow.ysize / dy; r->ireg[0x37] &= 0;
699 for (y = 0; y < r->ireg[0x33]; y++) {
700 y0 = y * dy + r->ireg[0x37];
701 for (x = 0; x < r->ireg[0x32]; x++) {
702 x0 = x * dx + r->ireg[0x36];
704 devFunc0004(mod3, x0, y0, x0 + dx, y0 + dy, c);
706 puc += r->ireg[0x38];
711 printf("devFunc: error: R30=%08X\n", r->ireg[0x30]);