リビジョン | 324d2e02f2deb4b9bdcb5345040404ef90a8c2b3 (tree) |
---|---|
日時 | 2014-06-11 23:17:34 |
作者 | hikarupsp <hikarupsp@user...> |
コミッター | hikarupsp |
osecpu110d
@@ -1,7 +1,7 @@ | ||
1 | 1 | #include "osecpu_ask.h" |
2 | 2 | |
3 | 3 | Int32s c:R00, x:R01, y:R02; |
4 | - api_openWin(256, 256); | |
4 | + api_openWin(256, 0); | |
5 | 5 | // c = 0; |
6 | 6 | for (x = 0; x != 256; x++) { |
7 | 7 | for (y = 0; y != 256; y++) { |
@@ -1,4 +1,4 @@ | ||
1 | 1 | #include "osecpu_ask.h" |
2 | 2 | |
3 | - api_fillRect(MODE_COL3, 7, 640, 480, 0, 0); | |
4 | - api_fillOval(MODE_COL3, 4, 300, 300, 320-150, 240-150); | |
3 | + api_fillRect(MODE_COL3, 7, -1, -1, 0, 0); | |
4 | + api_fillOval(MODE_COL3, 1, 300, 0, 320-150, 240-150); |
@@ -3,6 +3,6 @@ | ||
3 | 3 | Int32s x:R00; |
4 | 4 | |
5 | 5 | for (x = 0; x != 640; x++) { |
6 | - api_drawLine(MODE_XOR, 6, x, 0, 0, 479); | |
7 | - api_drawLine(MODE_XOR, 6, x, 479, 639, 0 ); | |
6 | + api_drawLine(MODE_XOR, 3, x, 0, 0, -1); | |
7 | + api_drawLine(MODE_XOR, 3, x, -1, -1, 0); | |
8 | 8 | } |
@@ -0,0 +1,31 @@ | ||
1 | +#include "osecpu_ask.h" | |
2 | + | |
3 | +%define L_POINT LOCAL(0) | |
4 | + | |
5 | +LOCALLABELS(1); | |
6 | + | |
7 | + | |
8 | + Int32s col:R00, x0:R01, y0:R02, x1:R03, y1:R04, i:R05, j:R06; | |
9 | + | |
10 | +// PLIMM(P01, L_POINT); | |
11 | + | |
12 | +DAT_SA(L_POINT, T_UINT8, 16 * 2); | |
13 | + DB(196, 100, 187, 61, 164, 29, 129, 9, 90, 5); | |
14 | + DB( 53, 17, 23, 44, 7, 81, 7, 119, 23, 156); | |
15 | + DB( 53, 183, 90, 195, 129, 191, 164, 171, 187, 139); | |
16 | + DB(196, 100); | |
17 | +DAT_END(); | |
18 | + | |
19 | + for (i = 0; i != 15; i++) { | |
20 | + LMEM0PP(32, R01, T_UINT8, P01); LMEM0PP(32, R02, T_UINT8, P01); // x0, y0. | |
21 | + PLIMM(P02, L_POINT); | |
22 | + for (j = -8; j != 8; j++) { | |
23 | + LMEM0PP(32, R03, T_UINT8, P02); LMEM0PP(32, R04, T_UINT8, P02); // x1, y1. | |
24 | + col = i - j; | |
25 | + if (col <= 0) { col = 1 - col; } | |
26 | + if (col <= 7) { | |
27 | + api_drawLine(MODE_OR, col, x0, y0, x1, y1); | |
28 | + } | |
29 | + } | |
30 | + } | |
31 | + |
@@ -0,0 +1,14 @@ | ||
1 | +#include "osecpu_ask.h" | |
2 | + | |
3 | + Int32s xsiz:R01, ysiz:R02, x0:R03, y0:R04, col:R00, i:R05; | |
4 | + | |
5 | + for (i = 0; i != 128; i++) { | |
6 | + col = i * 0x020201; | |
7 | + xsiz = 144 - i; | |
8 | + xsiz *= 2; | |
9 | + // ysiz = xsiz; | |
10 | + y0 = (240 - 144) + i; | |
11 | + x0 = (320 - 144) + i; | |
12 | + api_fillOval(MODE_COL24, col, xsiz, ysiz, x0, y0); | |
13 | + } | |
14 | + |
@@ -0,0 +1 @@ | ||
1 | +禀[、妨R黒lP@lー4ニES | |
\ No newline at end of file |
@@ -0,0 +1,15 @@ | ||
1 | +このパッケージには ext_tols フォルダが省略されているので、osecpu109aからコピーしてください。 | |
2 | +ext_tolsフォルダがなくても、コンパイル済みのアプリケーションを実行することはできます。 | |
3 | + | |
4 | +prompt>amake app0100 | |
5 | +とするとapp0100.askからapp0100.oseが生成されます。 | |
6 | +prompt>osecpu app0100.ose | |
7 | +とするとapp0100.oseが実行できます。 | |
8 | + | |
9 | +ファイル名の末尾が_になっている.oseファイルは、川合がハンドアセンブルでフロントエンドコードを | |
10 | +書いたものです。とても小さいですが、ちゃんと動きます。 | |
11 | + | |
12 | +http://osecpu.osask.jp/wiki/?page0036 に旧バージョン向けのアプリケーションの作り方の資料があります。 | |
13 | +今のバージョンと細かいところが違っていますが、雰囲気は似ているので見比べればわかるでしょう。 | |
14 | +分からなければ、 http://osecpu.osask.jp/wiki/?impressions で質問してもらえれば、説明できると思います。 | |
15 | + |
@@ -49,7 +49,7 @@ | ||
49 | 49 | #define TOELSE lbstk1(1,1) |
50 | 50 | #define TOENDIF lbstk1(1,2) |
51 | 51 | |
52 | -#define DAT_SA0(label, typ32, length) LB(1, label); DB(0x34); DDBE(typ32, length) /* simple-array */ | |
52 | +#define DAT_SA0(label, typ32, length) LB(1, label); DB(0xae); typ(typ32); imm(length) /* simple-array */ | |
53 | 53 | |
54 | 54 | #define PADDINGPREFIX() DB(0xfe,0x01,0xff) |
55 | 55 | #define ALIGNPREFIX0() DB(0xfe,0x01,0xfc) |
@@ -0,0 +1 @@ | ||
1 | +%ComSpec% | |
\ No newline at end of file |
@@ -172,9 +172,9 @@ int main(int argc, const UCHAR **argv) | ||
172 | 172 | " aska ver.0.20\n"//108 |
173 | 173 | " prepro ver.0.01\n" |
174 | 174 | " lbstk ver.0.03\n" |
175 | - " db2bin ver.0.13\n" | |
175 | + " db2bin ver.0.15\n"//110 | |
176 | 176 | " disasm ver.0.02\n" |
177 | - " appack ver.0.19\n" | |
177 | + " appack ver.0.20\n"//110 | |
178 | 178 | " maklib ver.0.01\n" |
179 | 179 | " getint ver.0.06\n" |
180 | 180 | " osastr ver.0.00\n" |
@@ -2462,6 +2462,8 @@ int db2binSub0(struct Work *w, const UCHAR **pp, UCHAR **qq); | ||
2462 | 2462 | UCHAR *db2binSub1(const UCHAR **pp, UCHAR *q, int width); |
2463 | 2463 | UCHAR *db2binSub2(UCHAR *p0, UCHAR *p1); // ラベル番号の付け直し. |
2464 | 2464 | |
2465 | +#define DB2BIN_HEADER_LENGTH 3 | |
2466 | + | |
2465 | 2467 | int db2bin(struct Work *w) |
2466 | 2468 | { |
2467 | 2469 | const UCHAR *pi = w->ibuf; |
@@ -2481,11 +2483,11 @@ int db2bin(struct Work *w) | ||
2481 | 2483 | } |
2482 | 2484 | putchar(0); // これがないとGCCがおかしくなる. |
2483 | 2485 | if ((w->flags & 1) == 0 && q != NULL) |
2484 | - q = db2binSub2(w->obuf + 4, q); | |
2486 | + q = db2binSub2(w->obuf + DB2BIN_HEADER_LENGTH, q); | |
2485 | 2487 | #if 0 |
2486 | 2488 | if (*pi == '\0' && q != NULL /* && (w->obuf[4] & 0xf0) != 0 */) { |
2487 | 2489 | // fputs("osecpu binary first byte error.\n", stderr); |
2488 | - for (r = q - w->obuf - 1; r >= 2; r--) | |
2490 | + for (r = q - w->obuf - 1; r >= DB2BIN_HEADER_LENGTH; r--) | |
2489 | 2491 | w->obuf[r + 1] = w->obuf[r]; |
2490 | 2492 | w->obuf[2] = 0x00; |
2491 | 2493 | q++; |
@@ -2529,39 +2531,46 @@ int db2binSub0(struct Work *w, const UCHAR **pp, UCHAR **qq) | ||
2529 | 2531 | } |
2530 | 2532 | |
2531 | 2533 | static UCHAR *table1[] = { |
2532 | - "0OSECPU_HEADER(", "DB(0x05,0xec,0x02,0x00);", | |
2534 | + "0OSECPU_HEADER(", "DB(0x05,0xe2,0x00);", | |
2535 | + | |
2536 | + "1bit(", "DB(0xf7,0x88); DDBE(%0);", // 6bytes. | |
2537 | + "1imm(", "DB(0xf7,0x88); DDBE(%0);", // 6bytes. | |
2538 | + "1typ(", "DB(0xf7,0x88); DDBE(%0);", // 6bytes. | |
2539 | + "1r(", "DB(%0+0x80);", // 1byte. | |
2540 | + "1p(", "DB(%0-0x40+0x80);", // 1byte. | |
2541 | + | |
2533 | 2542 | "0NOP(", "DB(0xf0);", |
2534 | - "2LB(", "DB(0xf1,0xf7,0x88); DDBE(%1); DB(0xf7,0x88); DDBE(%0);", | |
2535 | - "3LIMM(", "DB(0xf2,0xf7,0x88); DDBE(%2); DB(%1+0x80,0xfc,%0);", | |
2536 | - "2PLIMM(", "DB(0xf3,0xf7,0x88); DDBE(%1); DB(%0-0x40+0x80);", | |
2537 | - "1CND(", "DB(0xf4,%0+0x80);", | |
2538 | - // "4LMEM(", "DB(0x08,%0); DDBE(%1); DB(%2-0x40,%3);", | |
2543 | + "2LB(", "DB(0xf1); imm(%1); imm(%0);", | |
2544 | + "3LIMM(", "DB(0xf2); imm(%2); r(%1); bit(%0);", | |
2545 | + "2PLIMM(", "DB(0xf3); imm(%1); p(%0);", | |
2546 | + "1CND(", "DB(0xf4); r(%0);", | |
2547 | + "5LMEM(", "DB(0x88); p(%3); typ(%2); imm(%4); r(%1); bit(%0);", | |
2539 | 2548 | // "4SMEM(", "DB(0x09,%0); DDBE(%1); DB(%2-0x40,%3);", |
2540 | 2549 | // "4PLMEM(", "DB(0x0a,%0-0x40); DDBE(%1); DB(%2-0x40,%3);", |
2541 | 2550 | // "4PSMEM(", "DB(0x0b,%0-0x40); DDBE(%1); DB(%2-0x40,%3);", |
2542 | - // "4PADD(", "DB(0x0e,%0-0x40); DDBE(%1); DB(%2-0x40,%3);", | |
2551 | + "5PADD(", "DB(0x8e); p(%3); typ(%2); r(%4); bit(%0); p(%1);", | |
2543 | 2552 | // "4PDIF(", "DB(0x0f,%0); DDBE(%1); DB(%2-0x40,%3-0x40);", |
2544 | - "3CP(", "DB(0x90,%2+0x80,%2+0x80,%1+0x80,0xfc,%0);", | |
2545 | - // "3OR(", "DB(0x10,%0,%1,%2);", | |
2546 | - // "3XOR(", "DB(0x11,%0,%1,%2);", | |
2547 | - // "3AND(", "DB(0x12,%0,%1,%2);", | |
2548 | - // "3SBX(", "DB(0x13,%0,%1,%2);", | |
2549 | - "4ADD(", "DB(0x94,%2+0x80,%3+0x80,%1+0x80,0xfc,%0);", | |
2550 | - // "3SUB(", "DB(0x15,%0,%1,%2);", | |
2551 | - // "3MUL(", "DB(0x16,%0,%1,%2);", | |
2552 | - // "3SHL(", "DB(0x18,%0,%1,%2);", | |
2553 | - // "3SAR(", "DB(0x19,%0,%1,%2);", | |
2554 | - // "3DIV(", "DB(0x1a,%0,%1,%2);", | |
2555 | - // "3MOD(", "DB(0x1b,%0,%1,%2);", | |
2556 | - "2PCP(", "DB(0x9e,%1-0x40+0x80,%0-0x40+0x80);", | |
2557 | - // "3CMPE(", "DB(0x20,%0,%1,%2);", | |
2558 | - "5CMPNE(", "DB(0xa1,%3+0x80,%4+0x80,0xfc,%1,%2+0x80,0xfc,%0);", | |
2559 | - // "3CMPL(", "DB(0x22,%0,%1,%2);", | |
2560 | - // "3CMPGE(", "DB(0x23,%0,%1,%2);", | |
2561 | - // "3CMPLE(", "DB(0x24,%0,%1,%2);", | |
2562 | - // "3CMPG(", "DB(0x25,%0,%1,%2);", | |
2563 | - // "3TSTZ(", "DB(0x26,%0,%1,%2);", | |
2564 | - // "3TSTNZ(", "DB(0x27,%0,%1,%2);", | |
2553 | + "3CP(", "DB(0x90); r(%2); r(%2); r(%1); bit(%0);", | |
2554 | + "4OR(", "DB(0x90); r(%2); r(%3); r(%1); bit(%0);", | |
2555 | + "4XOR(", "DB(0x91); r(%2); r(%3); r(%1); bit(%0);", | |
2556 | + "4AND(", "DB(0x92); r(%2); r(%3); r(%1); bit(%0);", | |
2557 | + "4SBX(", "DB(0x93); r(%2); r(%3); r(%1); bit(%0);", | |
2558 | + "4ADD(", "DB(0x94); r(%2); r(%3); r(%1); bit(%0);", | |
2559 | + "4SUB(", "DB(0x95); r(%2); r(%3); r(%1); bit(%0);", | |
2560 | + "4MUL(", "DB(0x96); r(%2); r(%3); r(%1); bit(%0);", | |
2561 | + "4SHL(", "DB(0x98); r(%2); r(%3); r(%1); bit(%0);", | |
2562 | + "4SAR(", "DB(0x99); r(%2); r(%3); r(%1); bit(%0);", | |
2563 | + "4DIV(", "DB(0x9a); r(%2); r(%3); r(%1); bit(%0);", | |
2564 | + "4MOD(", "DB(0x9b); r(%2); r(%3); r(%1); bit(%0);", | |
2565 | + "2PCP(", "DB(0x9e); p(%1); p(%0);", | |
2566 | + "5CMPE(", "DB(0xa0); r(%3); r(%4); bit(%1); r(%2); bit(%0);", | |
2567 | + "5CMPNE(", "DB(0xa1); r(%3); r(%4); bit(%1); r(%2); bit(%0);", | |
2568 | + "5CMPL(", "DB(0xa2); r(%3); r(%4); bit(%1); r(%2); bit(%0);", | |
2569 | + "5CMPGE(", "DB(0xa3); r(%3); r(%4); bit(%1); r(%2); bit(%0);", | |
2570 | + "5CMPLE(", "DB(0xa4); r(%3); r(%4); bit(%1); r(%2); bit(%0);", | |
2571 | + "5CMPG(", "DB(0xa5); r(%3); r(%4); bit(%1); r(%2); bit(%0);", | |
2572 | + "5TSTZ(", "DB(0xa6); r(%3); r(%4); bit(%1); r(%2); bit(%0);", | |
2573 | + "5TSTNZ(", "DB(0xa7); r(%3); r(%4); bit(%1); r(%2); bit(%0);", | |
2565 | 2574 | // "3PCMPE(", "DB(0x28,%0,%1-0x40,%2-0x40);", |
2566 | 2575 | // "3PCMPNE(", "DB(0x29,%0,%1-0x40,%2-0x40);", |
2567 | 2576 | // "3PCMPL(", "DB(0x2a,%0,%1-0x40,%2-0x40);", |
@@ -2575,24 +2584,24 @@ int db2binSub0(struct Work *w, const UCHAR **pp, UCHAR **qq) | ||
2575 | 2584 | // "1DBGINFO(", "DBGINFO0(%0);", |
2576 | 2585 | "1JMP(", "PLIMM(P3F, %0);", |
2577 | 2586 | "1PJMP(", "PCP(P3F, %0);", |
2578 | - // "4PADDI(", "LIMM(%0, R3F, %3); PADD(%0, %1, %2, R3F);", | |
2579 | - // "3ORI(", "LIMM(R3F, %2); OR( %0, %1, R3F);", | |
2580 | - // "3XORI(", "LIMM(R3F, %2); XOR(%0, %1, R3F);", | |
2581 | - // "3ANDI(", "LIMM(R3F, %2); AND(%0, %1, R3F);", | |
2582 | - // "3SBXI(", "LIMM(R3F, %2); SBX(%0, %1, R3F);", | |
2587 | + "5PADDI(", "LIMM(%0, R3F, %4); PADD(%0, %1, %2, %3, R3F);", | |
2588 | + "4ORI(", "LIMM(%0, R3F, %3); OR( %0, %1, %2, R3F);", | |
2589 | + "4XORI(", "LIMM(%0, R3F, %3); XOR(%0, %1, %2, R3F);", | |
2590 | + "4ANDI(", "LIMM(%0, R3F, %3); AND(%0, %1, %2, R3F);", | |
2591 | + "4SBXI(", "LIMM(%0, R3F, %3); SBX(%0, %1, %2, R3F);", | |
2583 | 2592 | "4ADDI(", "LIMM(%0, R3F, %3); ADD(%0, %1, %2, R3F);", |
2584 | - // "3SUBI(", "LIMM(R3F, %2); SUB(%0, %1, R3F);", | |
2585 | - // "3MULI(", "LIMM(R3F, %2); MUL(%0, %1, R3F);", | |
2586 | - // "3SHLI(", "LIMM(R3F, %2); SHL(%0, %1, R3F);", | |
2587 | - // "3SARI(", "LIMM(R3F, %2); SAR(%0, %1, R3F);", | |
2588 | - // "3DIVI(", "LIMM(R3F, %2); DIV(%0, %1, R3F);", | |
2589 | - // "3MODI(", "LIMM(R3F, %2); MOD(%0, %1, R3F);", | |
2590 | - // "3CMPEI(", "LIMM(R3F, %2); CMPE( %0, %1, R3F);", | |
2593 | + "4SUBI(", "LIMM(%0, R3F, %3); SUB(%0, %1, %2, R3F);", | |
2594 | + "4MULI(", "LIMM(%0, R3F, %3); MUL(%0, %1, %2, R3F);", | |
2595 | + "4SHLI(", "LIMM(%0, R3F, %3); SHL(%0, %1, %2, R3F);", | |
2596 | + "4SARI(", "LIMM(%0, R3F, %3); SAR(%0, %1, %2, R3F);", | |
2597 | + "4DIVI(", "LIMM(%0, R3F, %3); DIV(%0, %1, %2, R3F);", | |
2598 | + "4MODI(", "LIMM(%0, R3F, %3); MOD(%0, %1, %2, R3F);", | |
2599 | + "5CMPEI(", "LIMM(%1, R3F, %4); CMPE( %0, %1, %2, %3, R3F);", | |
2591 | 2600 | "5CMPNEI(", "LIMM(%1, R3F, %4); CMPNE(%0, %1, %2, %3, R3F);", |
2592 | - // "3CMPLI(", "LIMM(R3F, %2); CMPL( %0, %1, R3F);", | |
2593 | - // "3CMPGEI(", "LIMM(R3F, %2); CMPGE(%0, %1, R3F);", | |
2594 | - // "3CMPLEI(", "LIMM(R3F, %2); CMPLE(%0, %1, R3F);", | |
2595 | - // "3CMPGI(", "LIMM(R3F, %2); CMPG( %0, %1, R3F);", | |
2601 | + "5CMPLI(", "LIMM(%1, R3F, %4); CMPL( %0, %1, %2, %3, R3F);", | |
2602 | + "5CMPGEI(", "LIMM(%1, R3F, %4); CMPGE(%0, %1, %2, %3, R3F);", | |
2603 | + "5CMPLEI(", "LIMM(%1, R3F, %4); CMPLE(%0, %1, %2, %3, R3F);", | |
2604 | + "5CMPGI(", "LIMM(%1, R3F, %4); CMPG( %0, %1, %2, %3, R3F);", | |
2596 | 2605 | NULL |
2597 | 2606 | }; |
2598 | 2607 | for (i = 0; table1[i] != NULL; i += 2) { |
@@ -2738,12 +2747,24 @@ int db2binSub2Len(const UCHAR *src) | ||
2738 | 2747 | int i = 0, j; |
2739 | 2748 | if (*src == 0xf0) i = 1; // NOP |
2740 | 2749 | if (src[0] == 0xf1 && src[1] == 0xf7 && src[2] == 0x88 && src[7] == 0xf7 && src[8] == 0x88) i = 13; // LB |
2741 | - if (src[0] == 0xf2 && src[1] == 0xf7 && src[2] == 0x88) i = 10; // LIMM | |
2750 | + if (src[0] == 0xf2 && src[1] == 0xf7 && src[2] == 0x88) i = 14; // LIMM | |
2742 | 2751 | if (src[0] == 0xf3 && src[1] == 0xf7 && src[2] == 0x88) i = 8; // PLIMM |
2743 | 2752 | if (src[0] == 0xf4) i = 2; // CND |
2744 | - if (0x90 <= src[0] && src[0] <= 0x9b && src[0] != 0x97 && src[4] == 0xfc) i = 6; // OR...MOD | |
2753 | + if (src[0] == 0x88 && src[2] == 0xf7 && src[3] == 0x88 && src[8] == 0xf7 && src[9] == 0x88 && src[15] == 0xf7 && src[16] == 0x88) i = 21; | |
2754 | + if (src[0] == 0x8e && src[2] == 0xf7 && src[3] == 0x88 && src[9] == 0xf7 && src[10] == 0x88) i = 16; | |
2755 | + if (0x90 <= src[0] && src[0] <= 0x9b && src[0] != 0x97 && src[4] == 0xf7 && src[5] == 0x88) i = 10; // OR...MOD | |
2745 | 2756 | if (src[0] == 0x9e) i = 3; // PCP |
2746 | - if (0xa0 <= src[0] && src[0] <= 0xa7 && src[3] == 0xfc && src[6] == 0xfc) i = 8; // CMPcc | |
2757 | + if (0xa0 <= src[0] && src[0] <= 0xa7 && src[3] == 0xf7 && src[4] == 0x88 && src[10] == 0xf7 && src[11] == 0x88) i = 16; // CMPcc | |
2758 | + if (src[0] == 0xae && src[1] == 0xf7 && src[2] == 0x88 && src[7] == 0xf7 && src[8] == 0x88) { | |
2759 | + j = src[ 3] << 24 | src[ 4] << 16 | src[ 5] << 8 | src[ 6]; | |
2760 | + i = src[ 9] << 24 | src[10] << 16 | src[11] << 8 | src[12]; | |
2761 | + j = db2binDataWidth(j); | |
2762 | + if (j <= 0) | |
2763 | + fputs("db2binSub2Len: error: F0\n", stderr); | |
2764 | + if (((i * j) & 7) != 0) | |
2765 | + fprintf(stderr, "db2binSub2Len: error: F0 (align 8bit) bit=%d len=%d\n", j, i); | |
2766 | + i = 13 + ((i * j) >> 3); | |
2767 | + } | |
2747 | 2768 | if (src[0] == 0xfc && src[1] == 0xfd && src[2] == 0xf7 && src[3] == 0x88 && src[8] == 0xf0) i = 9; // LIDR |
2748 | 2769 | if (src[0] == 0xfc && src[1] == 0xfe && src[2] == 0x00) i = 3; // remark-0 |
2749 | 2770 | if (src[0] == 0xfc && src[1] == 0xfe && src[2] == 0x10) i = 3; // remark-1 |
@@ -2808,7 +2829,7 @@ UCHAR *db2binSub2(UCHAR *p0, UCHAR *p1) | ||
2808 | 2829 | if (*p == 0xf3) |
2809 | 2830 | t[j]--; // このラベルは参照されているので消さない. |
2810 | 2831 | if (*p == 0xf1 && p[12] != 0x00) // bugfix: hinted by yao, 2013.09.17. thanks! |
2811 | - t[j]--; // データラベルの暗黙代入があるのでこのラベルは消せない. | |
2832 | + t[j]--; // データラベルの暗黙代入がありえるのでこのラベルは消せない. | |
2812 | 2833 | } |
2813 | 2834 | p += db2binSub2Len(p); |
2814 | 2835 | } |
@@ -3136,7 +3157,7 @@ void appackSub1(UCHAR **qq, char *pof, int i, char uf) | ||
3136 | 3157 | |
3137 | 3158 | int appackEncodeConst(int i) |
3138 | 3159 | { |
3139 | - if (i <= -16) i -= 0x50; /* -0x60以下へ */ | |
3160 | + if (i <= -0x11) i -= 0x50; /* -0x61以下へ */ | |
3140 | 3161 | if (0x100 <= i && i <= 0x10000 && (i & (i - 1)) == 0) { |
3141 | 3162 | i = - askaLog2(i) - 0x48; /* -0x50から-0x58へ (-0x59から-0x5fはリザーブ) */ |
3142 | 3163 | } |
@@ -3405,6 +3426,79 @@ void appackSub1op(UCHAR **qq, char *pof, int i, int *hist, UCHAR *opTbl) | ||
3405 | 3426 | return; |
3406 | 3427 | } |
3407 | 3428 | |
3429 | +typedef struct _AppackWork { | |
3430 | + const unsigned char *p; | |
3431 | + unsigned char *q; | |
3432 | + char pHalf; | |
3433 | + int rep0, rep1, rep0p, rep1p, rep0f, rep1f; | |
3434 | + int pxxTyp[64], labelTyp[MAXLABEL]; | |
3435 | + int hist[0x40]; | |
3436 | + unsigned char opTbl[256]; | |
3437 | +} AppackWork; | |
3438 | + | |
3439 | +void appack_setRep(AppackWork *aw, int reg, int typ) | |
3440 | +{ | |
3441 | + if (typ == 0) { | |
3442 | + aw->rep1 = aw->rep0; | |
3443 | + aw->rep0 = reg; | |
3444 | + } | |
3445 | + if (typ == 1) { | |
3446 | + aw->rep1p = aw->rep0p; | |
3447 | + aw->rep0p = reg; | |
3448 | + } | |
3449 | + if (typ == 2) { | |
3450 | + aw->rep1f = aw->rep0f; | |
3451 | + aw->rep0f = reg; | |
3452 | + } | |
3453 | + return; | |
3454 | +} | |
3455 | + | |
3456 | +void appack_initWork(AppackWork *aw) | |
3457 | +{ | |
3458 | + int i; | |
3459 | + for (i = 0; i < 0x40; i++) | |
3460 | + aw->pxxTyp[i] = TYP_UNKNOWN; | |
3461 | + for (i = 0; i < MAXLABEL; i++) | |
3462 | + aw->labelTyp[i] = TYP_UNKNOWN; | |
3463 | + for (i = 0; i < 0x40; i++) | |
3464 | + aw->hist[i] = 0; | |
3465 | + for (i = 0; i < 256; i++) | |
3466 | + aw->opTbl[i] = i; | |
3467 | + return; | |
3468 | +} | |
3469 | + | |
3470 | +void appack_initLabelTyp(struct Work *w, AppackWork *aw) | |
3471 | +{ | |
3472 | + int i; | |
3473 | + const unsigned char *p, *pp; | |
3474 | + for (p = w->ibuf + DB2BIN_HEADER_LENGTH; p < w->ibuf + w->isiz; ) { | |
3475 | + if (*p == 0xf1) { | |
3476 | + i = p[3] << 24 | p[4] << 16 | p[5] << 8 | p[6]; | |
3477 | + aw->labelTyp[i] = TYP_CODE; | |
3478 | + pp = p; | |
3479 | + for (;;) { | |
3480 | + if (pp >= w->ibuf + w->isiz) break; | |
3481 | + if (*pp != 0xf1) break; | |
3482 | + pp += db2binSub2Len(pp); | |
3483 | + } | |
3484 | + if (pp < w->ibuf + w->isiz && *pp == 0xae) { | |
3485 | + aw->labelTyp[i] = pp[3] << 24 | pp[4] << 16 | pp[5] << 8 | pp[6]; | |
3486 | + if (aw->pxxTyp[4] == TYP_UNKNOWN) { | |
3487 | + if (aw->pxxTyp[1] == TYP_UNKNOWN) | |
3488 | + aw->pxxTyp[1] = aw->labelTyp[i]; | |
3489 | + else if (aw->pxxTyp[2] == TYP_UNKNOWN) | |
3490 | + aw->pxxTyp[2] = aw->labelTyp[i]; | |
3491 | + else if (aw->pxxTyp[3] == TYP_UNKNOWN) | |
3492 | + aw->pxxTyp[3] = aw->labelTyp[i]; | |
3493 | + else /* if (pxxTyp[4] == TYP_UNKNOWN) */ | |
3494 | + aw->pxxTyp[4] = aw->labelTyp[i]; | |
3495 | + } | |
3496 | + } | |
3497 | + } | |
3498 | + p += db2binSub2Len(p); | |
3499 | + } | |
3500 | + return; | |
3501 | +} | |
3408 | 3502 | |
3409 | 3503 | int appack0(struct Work *w) |
3410 | 3504 | { |
@@ -3412,39 +3506,16 @@ int appack0(struct Work *w) | ||
3412 | 3506 | UCHAR *q = w->obuf, *qq; |
3413 | 3507 | *q++ = *p++; |
3414 | 3508 | *q++ = *p++; |
3415 | -// *q++ = *p++; | |
3416 | -// *q++ = *p++; | |
3417 | 3509 | char of = 0, f, oof, ff, fe0103 = 0; |
3418 | - UCHAR opTbl[256]; | |
3419 | 3510 | int r3f = 0, lastLabel = -1, i, j, wait7 = 0, firstDataLabel = -1; |
3420 | - int hist[0x40], pxxTyp[64], labelTyp[MAXLABEL]; | |
3421 | - for (i = 0; i < 0x40; i++) | |
3422 | - hist[i] = 0; | |
3423 | - for (i = 0; i < 0x40; i++) { | |
3424 | - pxxTyp[i] = TYP_UNKNOWN; | |
3425 | - } | |
3426 | - for (i = 0; i < MAXLABEL; i++) { | |
3427 | - labelTyp[i] = TYP_UNKNOWN; | |
3428 | - } | |
3429 | - for (i = 0; i < 256; i++) | |
3430 | - opTbl[i] = i; | |
3431 | - qq = db2binSub2(w->ibuf + 2, w->ibuf + w->isiz); | |
3511 | + AppackWork aw; | |
3512 | + qq = db2binSub2(w->ibuf + DB2BIN_HEADER_LENGTH, w->ibuf + w->isiz); // ラベル番号の付け直し. | |
3432 | 3513 | w->isiz = qq - w->ibuf; |
3514 | + appack_initWork(&aw); | |
3515 | + appack_initLabelTyp(w, &aw); | |
3516 | + | |
3517 | +#if 0 | |
3433 | 3518 | *qq = '\0'; |
3434 | - while (*p != 0x00 || p == &w->ibuf[2]) { | |
3435 | - if (*p == 0x01) { | |
3436 | - i = p[2] << 24 | p[3] << 16 | p[4] << 8 | p[5]; | |
3437 | - labelTyp[i] = 1; | |
3438 | - if (p[6] == 0x34 || p[6] == 0xf0) { | |
3439 | - labelTyp[i] = p[7] << 24 | p[8] << 16 | p[9] << 8 | p[10]; | |
3440 | - if (pxxTyp[1] == TYP_UNKNOWN) { | |
3441 | - pxxTyp[1] = labelTyp[i]; | |
3442 | - firstDataLabel = i; | |
3443 | - } | |
3444 | - } | |
3445 | - } | |
3446 | - p += db2binSub2Len(p); | |
3447 | - } | |
3448 | 3519 | p = w->ibuf + 2; |
3449 | 3520 | while (*p != 0x00 || p == &w->ibuf[2]) { |
3450 | 3521 | //printf("%02X at %06X\n", *p, p - w->ibuf); |
@@ -3964,6 +4035,7 @@ op_f0: | ||
3964 | 4035 | } |
3965 | 4036 | #endif |
3966 | 4037 | } |
4038 | +#endif | |
3967 | 4039 | return putBuf(w->argOut, w->obuf, q); |
3968 | 4040 | } |
3969 | 4041 |
@@ -4,7 +4,7 @@ | ||
4 | 4 | // OsecpuMain()はこのapi.cにあります! |
5 | 5 | |
6 | 6 | typedef struct _ApiWork { |
7 | - char winClosed, autoSleep; | |
7 | + char winClosed, autoSleep /* , col3bgr */; | |
8 | 8 | // jmp_buf setjmpEnv; |
9 | 9 | jmp_buf setjmpErr; |
10 | 10 | unsigned char lastConsoleChar; |
@@ -25,7 +25,7 @@ int OsecpuMain(int argc, const unsigned char **argv) | ||
25 | 25 | OsecpuVm vm; |
26 | 26 | unsigned char *byteBuf0 = malloc(BUFFER_SIZE); |
27 | 27 | Int32 *j32buf = malloc(BUFFER_SIZE * sizeof (Int32)); |
28 | - int fileSize, rc; | |
28 | + int fileSize, rc, i; | |
29 | 29 | FILE *fp; |
30 | 30 | jitc.defines = &defs; |
31 | 31 | vm.defines = &defs; |
@@ -44,26 +44,53 @@ int OsecpuMain(int argc, const unsigned char **argv) | ||
44 | 44 | fputs("app-file too large.\n", stderr); |
45 | 45 | exit(1); |
46 | 46 | } |
47 | - if (byteBuf0[0] != 0x05 || byteBuf0[1] != 0xec || byteBuf0[2] != 0x02 || byteBuf0[3] != 0x00) { | |
47 | + if (byteBuf0[0] != 0x05 || byteBuf0[1] != 0xe2 || fileSize < 3) { | |
48 | 48 | fputs("app-file signature mismatch.\n", stderr); |
49 | 49 | exit(1); |
50 | 50 | } |
51 | - hh4ReaderInit(&jitc.hh4r, byteBuf0 + 4, 0, byteBuf0 + fileSize, 0); | |
51 | + for (;;) { | |
52 | + if (fileSize < 0) break; | |
53 | + if (byteBuf0[2] == 0x02) { | |
54 | + fileSize = decode_tek5 (byteBuf0 + 3, byteBuf0 + fileSize, byteBuf0 + 2, byteBuf0 + BUFFER_SIZE); | |
55 | + if (fileSize > 0) fileSize += 2; | |
56 | + continue; | |
57 | + } | |
58 | + if (byteBuf0[2] == 0x01) { | |
59 | + fileSize = decode_upx (byteBuf0 + 3, byteBuf0 + fileSize, byteBuf0 + 2, byteBuf0 + BUFFER_SIZE); | |
60 | + if (fileSize > 0) fileSize += 2; | |
61 | + continue; | |
62 | + } | |
63 | + if (byteBuf0[2] >= 0x10) { | |
64 | + fileSize = decode_fcode(byteBuf0 + 2, byteBuf0 + fileSize, byteBuf0 + 2, byteBuf0 + BUFFER_SIZE); | |
65 | + if (fileSize > 0) fileSize += 2; | |
66 | + continue; | |
67 | + } | |
68 | + break; | |
69 | + } | |
70 | + if (fileSize <= 0 || byteBuf0[2] != 0x00) { | |
71 | + fputs("app-file decode error.\n", stderr); | |
72 | + exit(1); | |
73 | + } | |
74 | + hh4ReaderInit(&jitc.hh4r, byteBuf0 + 3, 0, byteBuf0 + fileSize, 0); | |
52 | 75 | jitc.dst = j32buf; |
53 | 76 | jitc.dst1 = j32buf + BUFFER_SIZE; |
54 | 77 | rc = jitcAll(&jitc); |
55 | 78 | if (rc != 0) { |
56 | - fprintf(stderr, "jitcAll()=%d\n", rc); | |
79 | + fprintf(stderr, "jitcAll()=%d, DR0=%d\n", rc, jitc.dr[0]); | |
57 | 80 | exit(1); |
58 | 81 | } |
59 | - *jitc.dst = -1; // 終端のための特殊opecode. | |
82 | +// *jitc.dst = -1; // 終端のための特殊opecode. | |
60 | 83 | vm.ip = j32buf; |
61 | 84 | vm.ip1 = jitc.dst; |
62 | 85 | |
63 | 86 | apiInit(&vm); |
87 | +// for (i = 1; i < argc; i++) { | |
88 | +// if (strcmp(argv[i], "-col3bgr") == 0) | |
89 | +// apiWork.col3bgr = 1; | |
90 | +// } | |
64 | 91 | rc = execAll(&vm); |
65 | - if (rc != 65535) { | |
66 | - fprintf(stderr, "execAll()=%d\n", rc); // 65535なら成功(EXEC_ABORT_OPECODE_M1). | |
92 | + if (rc != EXEC_SRC_OVERRUN) { | |
93 | + fprintf(stderr, "execAll()=%d, DR0=%d\n", rc, vm.dr[0]); // EXEC_SRC_OVERRUNなら成功. | |
67 | 94 | exit(1); |
68 | 95 | } |
69 | 96 | apiEnd(&vm); |
@@ -79,15 +106,25 @@ extern int *vram, v_xsiz, v_ysiz; | ||
79 | 106 | |
80 | 107 | void apiInit(OsecpuVm *vm) |
81 | 108 | { |
82 | - int i; | |
109 | + int i, j; | |
83 | 110 | for (i = 0; i <= 0x3f; i++) { |
84 | 111 | vm->r[i] = 0; vm->bit[i] = 32; // Rxx: すべて32ビットの0. |
85 | 112 | vm->p[i].typ = PTR_TYP_INVALID; // Pxx: すべて不正. |
86 | 113 | } |
114 | + j = 1; | |
115 | + for (i = 0; i < DEFINES_MAXLABELS; i++) { | |
116 | + if (j > 4) break; | |
117 | + if (vm->defines->label[i].typ == 0) continue; // 未使用. | |
118 | + if (vm->defines->label[i].opt == 0) continue; | |
119 | + if (vm->defines->label[i].typ == PTR_TYP_CODE) continue; | |
120 | + execStep_plimm(vm, j, i); | |
121 | + j++; | |
122 | + } | |
87 | 123 | vm->p[0x28].typ = PTR_TYP_NATIVECODE; |
88 | 124 | vm->p[0x28].p = (void *) &apiEntry; |
89 | 125 | apiWork.winClosed = 0; |
90 | 126 | apiWork.autoSleep = 0; |
127 | +// apiWork.col3bgr = 0; | |
91 | 128 | apiWork.lastConsoleChar = '\n'; |
92 | 129 | // if (setjmp(apiWork.setjmpEnv) != 0) |
93 | 130 | // apiEnd(vm); |
@@ -164,8 +201,8 @@ Int32 apiGetRxx(OsecpuVm *vm, int r, int bit) | ||
164 | 201 | } |
165 | 202 | |
166 | 203 | static int iColor1[] = { |
167 | - 0x000000, 0x0000ff, 0x00ff00, 0x00ffff, | |
168 | - 0xff0000, 0xff00ff, 0xffff00, 0xffffff | |
204 | + 0x000000, 0xff0000, 0x00ff00, 0xffff00, | |
205 | + 0x0000ff, 0xff00ff, 0x00ffff, 0xffffff | |
169 | 206 | }; |
170 | 207 | |
171 | 208 | void putOsaskChar(int c) |
@@ -281,8 +318,11 @@ int apiLoadColor(OsecpuVm *vm, int rxx) | ||
281 | 318 | int c = apiGetRxx(vm, rxx, 16), m, rr, gg, bb; |
282 | 319 | m = apiGetRxx(vm, 0x31, 2) & 3; |
283 | 320 | if (m == 0x00) { |
321 | + // static col3_bgr_table[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; | |
284 | 322 | if (c < -1 || c > 7) |
285 | 323 | jitcSetRetCode(&vm->errorCode, EXEC_API_ERROR); |
324 | + // if (apiWork.col3bgr != 0) | |
325 | + // c = col3_bgr_table[c & 7]; | |
286 | 326 | c = iColor1[c & 0x07]; |
287 | 327 | } |
288 | 328 | if (m == 0x01) { |
@@ -369,8 +409,14 @@ void api0003_drawLine(OsecpuVm *vm) | ||
369 | 409 | int x0 = apiGetRxx(vm, 0x33, 16), y0 = apiGetRxx(vm, 0x34, 16); |
370 | 410 | int x1 = apiGetRxx(vm, 0x35, 16), y1 = apiGetRxx(vm, 0x36, 16); |
371 | 411 | int dx, dy, x, y, len, i; |
372 | - apiCheckPoint(vm, x0, y0); | |
373 | - apiCheckPoint(vm, x1, y1); | |
412 | + if (1) { // クリッピングOFFの場合. | |
413 | + if (x0 == -1) x0 = v_xsiz - 1; | |
414 | + if (y0 == -1) y0 = v_ysiz - 1; | |
415 | + if (x1 == -1) x1 = v_xsiz - 1; | |
416 | + if (y1 == -1) y1 = v_ysiz - 1; | |
417 | + apiCheckPoint(vm, x0, y0); | |
418 | + apiCheckPoint(vm, x1, y1); | |
419 | + } | |
374 | 420 | dx = x1 - x0; |
375 | 421 | dy = y1 - y0; |
376 | 422 | x = x0 << 10; |
@@ -413,6 +459,8 @@ void api0004_rect(OsecpuVm *vm) | ||
413 | 459 | int xsiz = apiGetRxx(vm, 0x33, 16), ysiz = apiGetRxx(vm, 0x34, 16), x0, y0, x1, y1; |
414 | 460 | if (xsiz == -1) { xsiz = v_xsiz; x0 = 0; } else { x0 = apiGetRxx(vm, 0x35, 16); } |
415 | 461 | if (ysiz == -1) { ysiz = v_ysiz; y0 = 0; } else { y0 = apiGetRxx(vm, 0x36, 16); } |
462 | + if (ysiz == 0) ysiz = xsiz; | |
463 | +//printf("c=%06X %d %d %d %d", c, xsiz, ysiz, x0, y0); | |
416 | 464 | x1 = x0 + xsiz - 1; |
417 | 465 | y1 = y0 + ysiz - 1; |
418 | 466 | apiCheckPoint(vm, x0, y0); |
@@ -438,6 +486,7 @@ void api0005_oval(OsecpuVm *vm) | ||
438 | 486 | int x, y, modeC; |
439 | 487 | if (xsiz == -1) { xsiz = v_xsiz; x0 = 0; } else { x0 = apiGetRxx(vm, 0x35, 16); } |
440 | 488 | if (ysiz == -1) { ysiz = v_ysiz; y0 = 0; } else { y0 = apiGetRxx(vm, 0x36, 16); } |
489 | + if (ysiz == 0) ysiz = xsiz; | |
441 | 490 | x1 = x0 + xsiz - 1; |
442 | 491 | y1 = y0 + ysiz - 1; |
443 | 492 | apiCheckPoint(vm, x0, y0); |
@@ -446,7 +495,7 @@ void api0005_oval(OsecpuVm *vm) | ||
446 | 495 | dcy = 0.5 * (ysiz - 1); |
447 | 496 | dcxy = (dcx + 0.5) * (dcy + 0.5) - 0.1; |
448 | 497 | dcxy *= dcxy; |
449 | - if (mode == 0) { | |
498 | + if ((mode & ~3) == 0) { | |
450 | 499 | for (y = 0; y < ysiz; y++) { |
451 | 500 | dty = (y - dcy) * dcx; |
452 | 501 | for (x = 0; x < xsiz; x++) { |
@@ -505,7 +554,8 @@ void api0010_openWin(OsecpuVm *vm) | ||
505 | 554 | jitcSetRetCode(&vm->errorCode, EXEC_API_ERROR); |
506 | 555 | v_xsiz = apiGetRxx(vm, 0x31, 16); |
507 | 556 | v_ysiz = apiGetRxx(vm, 0x32, 16); |
508 | - if (v_xsiz <= 0 || 4096 < v_xsiz || v_ysiz <= 0 || 4096 < v_ysiz) | |
557 | + if (v_ysiz == 0) v_ysiz = v_xsiz; | |
558 | + if (v_xsiz <= 0 || 4096 < v_xsiz || v_ysiz < 0 || 4096 < v_ysiz) | |
509 | 559 | jitcSetRetCode(&vm->errorCode, EXEC_API_ERROR); |
510 | 560 | if (vm->errorCode > 0) goto fin; |
511 | 561 | vram = malloc(v_xsiz * v_ysiz * 4); |
@@ -0,0 +1,27 @@ | ||
1 | +rev1からrev2でのアプリサイズ変化: | |
2 | + | |
3 | +app0100( 13バイト) vs app0006( 17バイト) : グラデーション | |
4 | + app0006は17.5バイトだったのをうまく省略して17.0バイトにしていた。 | |
5 | + 正方形指定ができるようになったので-1.0バイト。 | |
6 | + 256を1.0バイトで書けるようになったので、-2.0バイト。 | |
7 | + forが初期値0を省略できるようになったので-1.0バイト。 | |
8 | + ADDのオペコードを0で代用できるようになったので-0.5バイト。 | |
9 | + | |
10 | +app0101( 14バイト) vs app0087改( 17バイト) : 日本の国旗 | |
11 | + 5までの整数が4ビット形式で書けるようになったことで-2.0バイト。 | |
12 | + ysiz=0で正円が描けるようになったことで、-1.5バイト。 | |
13 | + | |
14 | +app0102( 14バイト) vs app0022( 20バイト) : XOR描画のテスト | |
15 | + rep0の導入のおかげで-1.0バイト。 | |
16 | + xやyの-1のサポートのおかげで、-4.5バイト。 | |
17 | + forが初期値0を省略できるようになったので-0.5バイト。 | |
18 | + | |
19 | +app0103() vs app | |
20 | + | |
21 | +app0104( 26バイト) vs app0039( 31バイト) : メタリックなボール | |
22 | + 5までの整数が4ビット形式で書けるようになったことで-0.5バイト。 | |
23 | + 128が1.00バイトで書けるようになったので、-0.5バイト。 | |
24 | + ysiz = xsiz; が不要になって-2.0バイト。 | |
25 | + ADDのオペコードを0で代用できるようになったので-1.0バイト。 | |
26 | + そのほかいろいろで-1.0バイト。 | |
27 | + |
@@ -0,0 +1,763 @@ | ||
1 | +#include "osecpu-vm.h" | |
2 | + | |
3 | +#include "tek.c" | |
4 | + | |
5 | +// typedef unsigned char UCHAR; | |
6 | + | |
7 | +// upx関係. | |
8 | + | |
9 | +typedef struct _DecodeUpxStr { | |
10 | + const UCHAR *p; | |
11 | + int bitBuf, bitBufLen; | |
12 | + int tmp; | |
13 | +} DecodeUpxStr; | |
14 | + | |
15 | +int decode_upx_getBit(DecodeUpxStr *s) | |
16 | +{ | |
17 | + if (s->bitBufLen == 0) { | |
18 | + s->bitBuf = s->p[0] | s->p[1] << 8; | |
19 | + s->p += 2; | |
20 | + s->bitBufLen |= 16; | |
21 | + } | |
22 | + s->bitBufLen--; | |
23 | + return (s->bitBuf >> s->bitBufLen) & 1; | |
24 | +} | |
25 | + | |
26 | +int decode_upx_getTmpBit(DecodeUpxStr *s) | |
27 | +{ | |
28 | + s->tmp = (s->tmp << 1 | decode_upx_getBit(s)) & 0xffff; | |
29 | + return decode_upx_getBit(s); | |
30 | +} | |
31 | + | |
32 | +int decode_upx(const UCHAR *p, const UCHAR *p1, UCHAR *q, UCHAR *q1) | |
33 | +{ | |
34 | + DecodeUpxStr s; | |
35 | + int i, dis; | |
36 | + UCHAR *q0 = q; | |
37 | + i = p1 - p; | |
38 | + memmove(q1 - 8 - i, p, i); | |
39 | + s.p = q1 - 8 - i; | |
40 | + dis |= -1; | |
41 | + s.bitBufLen &= 0; | |
42 | + goto l1; | |
43 | +l0: | |
44 | + if (s.p <= q) goto err; | |
45 | + *q++ = *s.p++; | |
46 | +l1: | |
47 | + i = decode_upx_getBit(&s); | |
48 | + if (i != 0) goto l0; | |
49 | + s.tmp = 1; | |
50 | + do { | |
51 | + i = decode_upx_getTmpBit(&s); | |
52 | + if (s.tmp == 0) goto fin; | |
53 | + } while (i == 0); | |
54 | + if (s.tmp >= 3) | |
55 | + dis = ~((s.tmp - 3) << 8 | *s.p++); | |
56 | + s.tmp &= 0; | |
57 | + i = decode_upx_getTmpBit(&s); | |
58 | + s.tmp = s.tmp << 1 | i; | |
59 | + if (s.tmp == 0) { | |
60 | + s.tmp |= 1; | |
61 | + do { | |
62 | + i = decode_upx_getTmpBit(&s); | |
63 | + } while (i == 0); | |
64 | + s.tmp += 2; | |
65 | + } | |
66 | + s.tmp++; | |
67 | + if (dis < -0xd00) s.tmp++; | |
68 | + if (s.p <= q + s.tmp) goto err; | |
69 | + for (i = 0; i < s.tmp; i++) | |
70 | + q[i] = q[i + dis]; | |
71 | + q += s.tmp; | |
72 | + goto l1; | |
73 | +err: | |
74 | + q = q0 - 1; | |
75 | +fin: | |
76 | + return q - q0; | |
77 | +} | |
78 | + | |
79 | +// tek5関係. | |
80 | + | |
81 | +int decode_tek5(const UCHAR *p, const UCHAR *p1, UCHAR *q, UCHAR *q1) | |
82 | +{ | |
83 | + return -1; | |
84 | +} | |
85 | + | |
86 | +// フロントエンドコード関係. | |
87 | + | |
88 | +typedef struct _DecodeForLoop { | |
89 | + int r, bit, v1t, v1v, step, label; | |
90 | +} DecodeForLoop; | |
91 | + | |
92 | +typedef struct _DecodeFcodeStr { | |
93 | + Hh4Reader hh4r; | |
94 | + unsigned char *q; | |
95 | + char flag4, flagD, err; | |
96 | + int rep[3][8], bitR[0x40]; | |
97 | + int getIntTyp, getIntBit, getIntOrg, lastLabel; | |
98 | + DecodeForLoop floop[16]; | |
99 | + int floopDepth; | |
100 | +} DecodeFcodeStr; | |
101 | + | |
102 | +void decode_fcodeStep(DecodeFcodeStr *s); | |
103 | +void fcode_updateRep(DecodeFcodeStr *s, int typ, int r); | |
104 | +int fcode_getSigned(DecodeFcodeStr *s); | |
105 | +int fcode_getReg(DecodeFcodeStr *s, int typ); | |
106 | +int fcode_getInteger(DecodeFcodeStr *s, const int *len3table); | |
107 | +void fcode_putOpecode1(DecodeFcodeStr *s, int i); | |
108 | +void fcode_putLb(DecodeFcodeStr *s, int opt, int i); | |
109 | +void fcode_putLimm(DecodeFcodeStr *s, int bit, int r, int i); | |
110 | +void fcode_putPlimm(DecodeFcodeStr *s, int p, int i); | |
111 | +void fcode_putCnd(DecodeFcodeStr *s, int r); | |
112 | +void fcode_putAlu(DecodeFcodeStr *s, int opecode, int bit, int r0, int r1, int r2); | |
113 | +void fcode_putCp(DecodeFcodeStr *s, int bit, int r0, int r1); | |
114 | +void fcode_putPcp(DecodeFcodeStr *s, int p0, int p1); | |
115 | +int fcode_putLimmOrCp(DecodeFcodeStr *s, int bit, int r); | |
116 | +void fcode_ope06(DecodeFcodeStr *s); | |
117 | +void fcode_ope07(DecodeFcodeStr *s); | |
118 | +void fcode_opeAlu(DecodeFcodeStr *s, int opecode); | |
119 | +void fcode_api0002(DecodeFcodeStr *s); | |
120 | +void fcode_api0003(DecodeFcodeStr *s); | |
121 | +void fcode_api0004(DecodeFcodeStr *s); | |
122 | +void fcode_api0005(DecodeFcodeStr *s); | |
123 | +void fcode_api0010(DecodeFcodeStr *s); | |
124 | + | |
125 | +static int len3table0[7] = { -1, 0, 1, 2, 3, 4, -0x10 /* rep0 */ }; | |
126 | + | |
127 | +#define BIT_UNKNOWN 0x7fffffff // とにかく大きな値にする. | |
128 | +#define MIN(a, b) ((a) < (b) ? (a) : (b)) | |
129 | + | |
130 | +int decode_fcode(const unsigned char *p, const unsigned char *p1, unsigned char *q, unsigned char *q1) | |
131 | +{ | |
132 | + DecodeFcodeStr s; | |
133 | + int i, j; | |
134 | + unsigned char *q0 = q; | |
135 | + i = p1 - p; | |
136 | + memmove(q1 - i, p, i); | |
137 | + hh4ReaderInit(&s.hh4r, q1 - i, 0, q1, 0); | |
138 | + s.q = q; | |
139 | + s.err = 0; | |
140 | + s.flag4 = 0; | |
141 | + s.flagD = 0; | |
142 | + s.lastLabel = -1; | |
143 | + s.floopDepth = 0; | |
144 | + for (i = 0; i < 0x40; i++) | |
145 | + s.bitR[i] = BIT_UNKNOWN; | |
146 | + for (j = 0; j < 3; j++) { | |
147 | + for (i = 0; i < 8; i++) | |
148 | + s.rep[j][i] = 0x30 + i; | |
149 | + } | |
150 | + *s.q++ = 0x00; | |
151 | + while (s.err == 0) { | |
152 | + decode_fcodeStep(&s); | |
153 | + if (hh4ReaderEnd(&s.hh4r) != 0) break; | |
154 | + } | |
155 | + while (s.err == 0 && s.floopDepth > 0) | |
156 | + fcode_ope07(&s); | |
157 | + if (s.err != 0) | |
158 | + s.q = q0 - 1; | |
159 | + return s.q - q0; | |
160 | +} | |
161 | + | |
162 | +int fcode_swapOpecode(int i) | |
163 | +// 0を14に代用可能にする. | |
164 | +// osecpu-110より試験的に導入. | |
165 | +// OSWP命令によりキャンセルされる(未実装). | |
166 | +// コード末尾の0.5バイトを埋めるためには1を使う. | |
167 | +{ | |
168 | + if (i == 0x00) i = 0x14; | |
169 | + return i; | |
170 | +} | |
171 | + | |
172 | +void decode_fcodeStep(DecodeFcodeStr *s) | |
173 | +{ | |
174 | + int opecode, i; | |
175 | + if (s->err == 0) { | |
176 | + opecode = hh4ReaderGetUnsigned(&s->hh4r); | |
177 | + if (opecode == 0 && hh4ReaderEnd(&s->hh4r) != 0) | |
178 | + goto fin; // 末尾の0.5バイトを埋めていた0を発見. これは無視する. | |
179 | + opecode = fcode_swapOpecode(opecode); | |
180 | + if (opecode == 0x0) { | |
181 | + if (s->flag4 == 0) { | |
182 | + fcode_putOpecode1(s, 0xf0); | |
183 | + goto fin; | |
184 | + } | |
185 | + } | |
186 | + if (opecode == 0x4) { | |
187 | + if (s->flag4 == 0) { | |
188 | + s->flag4 = 1; | |
189 | + goto fin; | |
190 | + } | |
191 | + s->flag4 = 0; | |
192 | + fcode_putCnd(s, fcode_getReg(s, 0)); | |
193 | + goto fin; | |
194 | + } | |
195 | + if (opecode == 0x5) { | |
196 | + i = fcode_getSigned(s); | |
197 | + if (i == 0x0002) { fcode_api0002(s); goto fin; } | |
198 | + if (i == 0x0003) { fcode_api0003(s); goto fin; } | |
199 | + if (i == 0x0004) { fcode_api0004(s); goto fin; } | |
200 | + if (i == 0x0005) { fcode_api0005(s); goto fin; } | |
201 | + if (i == 0x0010) { fcode_api0010(s); goto fin; } | |
202 | + } | |
203 | + if (opecode == 0x6) { | |
204 | + if (s->floopDepth >= 16) goto err; | |
205 | + fcode_ope06(s); | |
206 | + goto fin; | |
207 | + } | |
208 | + if (opecode == 0x07) { | |
209 | + if (s->floopDepth <= 0) goto err; | |
210 | + fcode_ope07(s); | |
211 | + goto fin; | |
212 | + } | |
213 | + if (opecode == 0x0d) { | |
214 | + if (s->flagD != 0) goto err; | |
215 | + s->flagD = 1; | |
216 | + goto fin; | |
217 | + } | |
218 | + if (0x10 <= opecode && opecode <= 0x1b && opecode != 0x17) { | |
219 | + fcode_opeAlu(s, opecode); | |
220 | + goto fin; | |
221 | + } | |
222 | +err: | |
223 | + s->err = 1; | |
224 | + } | |
225 | +fin: | |
226 | + return; | |
227 | +} | |
228 | + | |
229 | +void fcode_updateRep(DecodeFcodeStr *s, int typ, int r) | |
230 | +{ | |
231 | + int tmp0 = r, tmp1, i; | |
232 | + for (i = 0; i < 8; i++) { | |
233 | + tmp1 = s->rep[typ][i]; | |
234 | + s->rep[typ][i] = tmp0; | |
235 | + if (tmp1 == r) break; | |
236 | + tmp0 = tmp1; | |
237 | + } | |
238 | + return; | |
239 | +} | |
240 | + | |
241 | +int fcode_getSigned(DecodeFcodeStr *s) | |
242 | +{ | |
243 | + int i = hh4ReaderGetSigned(&s->hh4r); | |
244 | + if (s->hh4r.length == 3) { // 0,1,2,3,4,5,-1. | |
245 | + i &= 7; | |
246 | + if (i == 6) | |
247 | + i = -1; | |
248 | + } | |
249 | + return i; | |
250 | +} | |
251 | + | |
252 | +int fcode_getReg(DecodeFcodeStr *s, int typ) | |
253 | +// 4ビット形式の場合(0〜6): R00〜R04, rep0〜rep1. | |
254 | +// そのほかの場合(0〜0x47): R00〜R17, rep0〜rep7, R20〜R3F, R18〜R1F | |
255 | +{ | |
256 | + int i = hh4ReaderGetUnsigned(&s->hh4r); | |
257 | + if (s->hh4r.length == 3) { | |
258 | + if (i >= 5) | |
259 | + i += 0x18 - 5; | |
260 | + } | |
261 | + if (0x18 <= i && i <= 0x1f) | |
262 | + i = s->rep[typ][i & 7]; | |
263 | + else if (0x40 <= i && i <= 0x47) | |
264 | + i += 0x18 - 0x40; | |
265 | + return i; | |
266 | +} | |
267 | + | |
268 | +int fcode_getInteger(DecodeFcodeStr *s, const int *len3table) | |
269 | +{ | |
270 | + int i = fcode_getSigned(s), typ = 0; | |
271 | + s->getIntOrg = i; | |
272 | + if (s->hh4r.length == 3) | |
273 | + i = len3table[i + 1]; | |
274 | + if (-0x08 <= i && i <= -0x05) | |
275 | + i = 0x20 << (i & 3); // 0x20, 0x40, 0x80, 0x100. | |
276 | + else if (-0x10 <= i && i <= -0x09) { | |
277 | + i = s->rep[0][i & 7]; // rep0-7. | |
278 | + typ = 1; | |
279 | + } else if (i == -0x11) { | |
280 | + i = 0x3f; // R3F. | |
281 | + typ = 1; | |
282 | + } else if (-0x20 <= i && i <= -0x12) { | |
283 | + i &= 0x0f; // R00-R0E. | |
284 | + typ = 1; | |
285 | + } else if (i == -0x21) { | |
286 | + i = 0x0f; // R0F. | |
287 | + typ = 1; | |
288 | + } else if (-0x50 <= i && i <= -0x22) { | |
289 | + i += 0x60; // R10-R3E. | |
290 | + typ = 1; | |
291 | + } else if (-0x68 <= i && i <= -0x51) | |
292 | + i = 0x200 << (i + 0x68); // 0x200-4G. | |
293 | + else if (-0x6c <= i && i <= -0x69) { | |
294 | + s->getIntBit = 4 << (i + 0x6c); // 4, 8, 16, 32. | |
295 | + i = fcode_getInteger(s, len3table); | |
296 | + typ = s->getIntTyp; | |
297 | + } else if (i == -0x6d) { | |
298 | + i = hh4ReaderGetUnsigned(&s->hh4r); | |
299 | + if (i <= 16) | |
300 | + s->getIntBit = 1 << i; | |
301 | + else | |
302 | + s->getIntBit = i - 17; | |
303 | + i = fcode_getInteger(s, len3table); | |
304 | + typ = s->getIntTyp; | |
305 | + } else if (i <= -0x71) | |
306 | + i += 0x71 - 5; | |
307 | + s->getIntTyp = typ; | |
308 | + return i; | |
309 | +} | |
310 | + | |
311 | +void fcode_putInt32(DecodeFcodeStr *s, int i) | |
312 | +{ | |
313 | + if (s->hh4r.p.p < s->q + 16) | |
314 | + s->err = 1; | |
315 | + if (s->err == 0) { | |
316 | + s->q[ 0] = 0xf7; | |
317 | + s->q[ 1] = 0x88; | |
318 | + s->q[ 2] = (i >> 24) & 0xff; | |
319 | + s->q[ 3] = (i >> 16) & 0xff; | |
320 | + s->q[ 4] = (i >> 8) & 0xff; | |
321 | + s->q[ 5] = i & 0xff; | |
322 | + s->q += 6; | |
323 | + } | |
324 | + return; | |
325 | +} | |
326 | + | |
327 | +void fcode_putR(DecodeFcodeStr *s, int i) | |
328 | +{ | |
329 | + if (s->hh4r.p.p < s->q + 16) | |
330 | + s->err = 1; | |
331 | + if (s->err == 0) | |
332 | + *s->q++ = i + 0x80; | |
333 | + return; | |
334 | +} | |
335 | + | |
336 | +void fcode_putP(DecodeFcodeStr *s, int i) | |
337 | +{ | |
338 | + if (s->hh4r.p.p < s->q + 16) | |
339 | + s->err = 1; | |
340 | + if (s->err == 0) | |
341 | + *s->q++ = i + 0x80; | |
342 | + return; | |
343 | +} | |
344 | + | |
345 | +void fcode_putBit(DecodeFcodeStr *s, int i) | |
346 | +{ | |
347 | + if (s->hh4r.p.p < s->q + 16) | |
348 | + s->err = 1; | |
349 | + if (s->err == 0) { | |
350 | + s->q[ 0] = 0xf7; | |
351 | + s->q[ 1] = 0x88; | |
352 | + s->q[ 2] = (i >> 24) & 0xff; | |
353 | + s->q[ 3] = (i >> 16) & 0xff; | |
354 | + s->q[ 4] = (i >> 8) & 0xff; | |
355 | + s->q[ 5] = i & 0xff; | |
356 | + s->q += 6; | |
357 | + } | |
358 | + return; | |
359 | +} | |
360 | + | |
361 | +void fcode_putOpecode1(DecodeFcodeStr *s, int i) | |
362 | +{ | |
363 | + if (s->hh4r.p.p < s->q + 16) | |
364 | + s->err = 1; | |
365 | + if (s->err == 0) | |
366 | + *s->q++ = i; | |
367 | + return; | |
368 | +} | |
369 | + | |
370 | +void fcode_putLb(DecodeFcodeStr *s, int opt, int i) | |
371 | +{ | |
372 | + fcode_putOpecode1(s, 0xf1); | |
373 | + fcode_putInt32(s, i); | |
374 | + fcode_putInt32(s, opt); | |
375 | + return; | |
376 | +} | |
377 | + | |
378 | +void fcode_putLimm(DecodeFcodeStr *s, int bit, int r, int i) | |
379 | +{ | |
380 | + fcode_putOpecode1(s, 0xf2); | |
381 | + fcode_putInt32(s, i); | |
382 | + fcode_putR(s, r); | |
383 | + fcode_putBit(s, bit); | |
384 | + if (r != 0x3f) | |
385 | + s->bitR[r] = bit; | |
386 | + return; | |
387 | +} | |
388 | + | |
389 | +void fcode_putPlimm(DecodeFcodeStr *s, int p, int i) | |
390 | +{ | |
391 | + fcode_putOpecode1(s, 0xf3); | |
392 | + fcode_putInt32(s, i); | |
393 | + fcode_putP(s, p); | |
394 | + return; | |
395 | +} | |
396 | + | |
397 | +void fcode_putCnd(DecodeFcodeStr *s, int r) | |
398 | +{ | |
399 | + fcode_putOpecode1(s, 0xf4); | |
400 | + fcode_putR(s, r); | |
401 | + return; | |
402 | +} | |
403 | + | |
404 | +void fcode_putAlu(DecodeFcodeStr *s, int opecode, int bit, int r0, int r1, int r2) | |
405 | +{ | |
406 | + fcode_putOpecode1(s, opecode); | |
407 | + fcode_putR(s, r1); | |
408 | + fcode_putR(s, r2); | |
409 | + fcode_putR(s, r0); | |
410 | + fcode_putBit(s, bit); | |
411 | + if (r0 != 0x3f) | |
412 | + s->bitR[r0] = bit; | |
413 | + return; | |
414 | +} | |
415 | + | |
416 | +void fcode_putCp(DecodeFcodeStr *s, int bit, int r0, int r1) | |
417 | +{ | |
418 | + fcode_putAlu(s, 0x90, bit, r0, r1, r1); | |
419 | + return; | |
420 | +} | |
421 | + | |
422 | +void fcode_putPcp(DecodeFcodeStr *s, int p0, int p1) | |
423 | +{ | |
424 | + fcode_putOpecode1(s, 0x9e); | |
425 | + fcode_putP(s, p1); | |
426 | + fcode_putP(s, p0); | |
427 | + return; | |
428 | +} | |
429 | + | |
430 | +void fcode_putCmp(DecodeFcodeStr *s, int opecode, int bit0, int bit1, int r0, int r1, int r2) | |
431 | +{ | |
432 | + fcode_putOpecode1(s, opecode); | |
433 | + fcode_putR(s, r1); | |
434 | + fcode_putR(s, r2); | |
435 | + fcode_putBit(s, bit1); | |
436 | + fcode_putR(s, r0); | |
437 | + fcode_putBit(s, bit0); | |
438 | + if (r0 != 0x3f) | |
439 | + s->bitR[r0] = bit0; | |
440 | + return; | |
441 | +} | |
442 | + | |
443 | +void fcode_putRemark0(DecodeFcodeStr *s) | |
444 | +{ | |
445 | + if (s->hh4r.p.p < s->q + 16) | |
446 | + s->err = 1; | |
447 | + if (s->err == 0) { | |
448 | + s->q[ 0] = 0xfc; | |
449 | + s->q[ 1] = 0xfe; | |
450 | + s->q[ 2] = 0x00; | |
451 | + s->q += 3; | |
452 | + } | |
453 | + return; | |
454 | +} | |
455 | + | |
456 | +void fcode_putRemark1(DecodeFcodeStr *s) | |
457 | +{ | |
458 | + if (s->hh4r.p.p < s->q + 16) | |
459 | + s->err = 1; | |
460 | + if (s->err == 0) { | |
461 | + s->q[ 0] = 0xfc; | |
462 | + s->q[ 1] = 0xfe; | |
463 | + s->q[ 2] = 0x10; | |
464 | + s->q += 3; | |
465 | + } | |
466 | + return; | |
467 | +} | |
468 | + | |
469 | +void fcode_putRemark2(DecodeFcodeStr *s, int i) | |
470 | +{ | |
471 | + if (s->hh4r.p.p < s->q + 16) | |
472 | + s->err = 1; | |
473 | + if (s->err == 0) { | |
474 | + s->q[ 0] = 0xfc; | |
475 | + s->q[ 1] = 0xfe; | |
476 | + s->q[ 2] = 0x21; | |
477 | + s->q += 3; | |
478 | + fcode_putInt32(s, i); | |
479 | + } | |
480 | + return; | |
481 | +} | |
482 | + | |
483 | +void fcode_putRemark3(DecodeFcodeStr *s) | |
484 | +{ | |
485 | + if (s->hh4r.p.p < s->q + 16) | |
486 | + s->err = 1; | |
487 | + if (s->err == 0) { | |
488 | + s->q[ 0] = 0xfc; | |
489 | + s->q[ 1] = 0xfe; | |
490 | + s->q[ 2] = 0x30; | |
491 | + s->q += 3; | |
492 | + } | |
493 | + return; | |
494 | +} | |
495 | + | |
496 | + | |
497 | +void fcode_putjmp(DecodeFcodeStr *s, int i) | |
498 | +{ | |
499 | + fcode_putPlimm(s, 0x3f, i); | |
500 | + return; | |
501 | +} | |
502 | + | |
503 | +void fcode_putPjmp(DecodeFcodeStr *s, int p) | |
504 | +{ | |
505 | + fcode_putPcp(s, 0x3f, p); | |
506 | + return; | |
507 | +} | |
508 | + | |
509 | +int fcode_putLimmOrCp(DecodeFcodeStr *s, int bit, int r) | |
510 | +{ | |
511 | + int i; | |
512 | + s->getIntBit = BIT_UNKNOWN; | |
513 | + i = fcode_getInteger(s, len3table0); | |
514 | + if (s->getIntTyp == 0) { | |
515 | + if (s->getIntBit == BIT_UNKNOWN) | |
516 | + s->getIntBit = bit; | |
517 | + fcode_putLimm(s, s->getIntBit, r, i); | |
518 | + } else { | |
519 | + if (s->getIntBit == BIT_UNKNOWN) | |
520 | + s->getIntBit = s->bitR[i]; | |
521 | + if (s->getIntBit == BIT_UNKNOWN) | |
522 | + s->getIntBit = bit; | |
523 | + fcode_putCp(s, s->getIntBit, r, i); | |
524 | + } | |
525 | + return i; | |
526 | +} | |
527 | + | |
528 | +void fcode_putPcallP28(DecodeFcodeStr *s) | |
529 | +{ | |
530 | + s->lastLabel++; | |
531 | + fcode_putPlimm(s, 0x30, s->lastLabel); | |
532 | + fcode_putPjmp(s, 0x28); | |
533 | + fcode_putLb(s, 1, s->lastLabel); | |
534 | + fcode_putRemark0(s); | |
535 | + return; | |
536 | +} | |
537 | + | |
538 | +void fcode_ope06(DecodeFcodeStr *s) | |
539 | +// プリフィクス4: カウンタ初期値は0以外. | |
540 | +// プリフィクスD: stepの変更(未実装). | |
541 | +// bitはカウンタ比較値のほうで指定できる. | |
542 | +{ | |
543 | + int v0v = 0, v0t = 0, v0b = BIT_UNKNOWN; | |
544 | + DecodeForLoop *dfl = &s->floop[s->floopDepth]; | |
545 | + if (s->flagD != 0) { s->err = 1; return; } // 未実装. | |
546 | + dfl->r = fcode_getReg(s, 0); // reg. | |
547 | + if (s->flag4 != 0) { | |
548 | + s->getIntBit = BIT_UNKNOWN; | |
549 | + v0v = fcode_getInteger(s, len3table0); // v0. | |
550 | + v0t = s->getIntTyp; | |
551 | + v0b = s->getIntBit; | |
552 | + } | |
553 | + s->lastLabel++; | |
554 | + dfl->label = s->lastLabel; | |
555 | + dfl->step = 1; | |
556 | + s->getIntBit = BIT_UNKNOWN; | |
557 | + dfl->v1v = fcode_getInteger(s, len3table0); | |
558 | + dfl->v1t = s->getIntTyp; | |
559 | + if (v0t == 0 && dfl->v1t == 0 && v0v > dfl->v1v) | |
560 | + dfl->step = -1; | |
561 | + fcode_putRemark2(s, s->getIntOrg); | |
562 | + dfl->bit = MIN(s->getIntBit, v0b); | |
563 | + if (dfl->bit == BIT_UNKNOWN) { | |
564 | + if (v0t != 0) | |
565 | + dfl->bit = s->bitR[v0v]; | |
566 | + if (dfl->v1t != 0) | |
567 | + dfl->bit = MIN(dfl->bit, s->bitR[dfl->v1v]); | |
568 | + if (dfl->bit == BIT_UNKNOWN) | |
569 | + dfl->bit = 32; | |
570 | + } | |
571 | + if (v0t == 0) | |
572 | + fcode_putLimm(s, dfl->bit, dfl->r, v0v); | |
573 | + else | |
574 | + fcode_putCp(s, dfl->bit, dfl->r, v0v); | |
575 | + fcode_putLb(s, 0, s->lastLabel); | |
576 | + s->floopDepth++; | |
577 | + fcode_updateRep(s, 0, dfl->r); | |
578 | + s->flag4 = 0; | |
579 | + return; | |
580 | +} | |
581 | + | |
582 | +void fcode_ope07(DecodeFcodeStr *s) | |
583 | +{ | |
584 | + int i; | |
585 | + DecodeForLoop *dfl; | |
586 | + fcode_putRemark3(s); | |
587 | + s->floopDepth--; | |
588 | + dfl = &s->floop[s->floopDepth]; | |
589 | + fcode_putLimm(s, dfl->bit, 0x3f, dfl->step); | |
590 | + fcode_putAlu(s, 0x94, dfl->bit, dfl->r, dfl->r, 0x3f); | |
591 | + i = dfl->v1v; | |
592 | + if (dfl->v1t == 0) { | |
593 | + fcode_putLimm(s, dfl->bit, 0x3f, dfl->v1v); | |
594 | + i = 0x3f; | |
595 | + } | |
596 | + fcode_putCmp(s, 0xa1, 1, dfl->bit, 0x3f, dfl->r, i); | |
597 | + fcode_putCnd(s, 0x3f); | |
598 | + fcode_putPlimm(s, 0x3f, dfl->label); | |
599 | + return; | |
600 | +} | |
601 | + | |
602 | +#define R0 -0x10+0 /* rep0 */ | |
603 | +#define R1 -0x10+1 /* rep1 */ | |
604 | + | |
605 | +void fcode_opeAlu(DecodeFcodeStr *s, int opecode) | |
606 | +// プリフィクス4: r0はr1とは異なる(三項演算モード). | |
607 | +// プリフィクスD: 演算方向の変更. | |
608 | +{ | |
609 | + static int len3table[12][7] = { | |
610 | + // { -1, 0, 1, 2, 3, 4, R0 }, // general | |
611 | + { R1, 16, 1, 2, 8, 4, R0 }, // OR | |
612 | + { -1, R1, 1, 2, 3, 4, R0 }, // XOR | |
613 | + { R1, 15, 1, 7, 3, 5, R0 }, // AND | |
614 | + { 64, 16, 1, 2, 8, 4, 32 }, // SBX | |
615 | + { R1, R0, 1, 2, 3, 4, 5 }, // ADD | |
616 | + { R1, R0, 1, 2, 3, 4, 5 }, // SUB | |
617 | + { -1, R0, R1, 7, 3, 6, 5 }, // MUL | |
618 | + { 0, 0, 0, 0, 0, 0, 0 }, | |
619 | + { R1, R0, 1, 2, 3, 4, 5 }, // SHL | |
620 | + { R1, R0, 1, 2, 3, 4, 5 }, // SAR | |
621 | + { 9, R0, R1, 7, 3, 6, 5 }, // DIV | |
622 | + { 9, R0, R1, 7, 3, 6, 5 }, // MOD | |
623 | + }; | |
624 | + int i, r0, r1, bit, tmp; | |
625 | + r1 = fcode_getReg(s, 0); | |
626 | + s->getIntBit = BIT_UNKNOWN; | |
627 | + i = fcode_getInteger(s, len3table[opecode & 0xf]); | |
628 | + bit = s->getIntBit; | |
629 | + if (bit == BIT_UNKNOWN) { | |
630 | + bit = s->bitR[r1]; | |
631 | + if (s->getIntTyp != 0) | |
632 | + bit = MIN(bit, s->bitR[i]); | |
633 | + if (bit == BIT_UNKNOWN) | |
634 | + bit = 32; | |
635 | + } | |
636 | + r0 = r1; | |
637 | + if (s->flag4 != 0) | |
638 | + r0 = fcode_getReg(s, 0); | |
639 | + if (s->getIntTyp == 0) { | |
640 | + fcode_putLimm(s, bit, 0x3f, i); | |
641 | + i = 0x3f; | |
642 | + } | |
643 | + if (s->flagD != 0) { | |
644 | + tmp = i; | |
645 | + i = r1; | |
646 | + r1 = tmp; | |
647 | + } | |
648 | + fcode_putAlu(s, opecode | 0x80, bit, r0, r1, i); | |
649 | + if (r1 != 0x3f) fcode_updateRep(s, 0, r1); | |
650 | + if (i != 0x3f) fcode_updateRep(s, 0, i); | |
651 | + fcode_updateRep(s, 0, r0); | |
652 | + s->flag4 = s->flagD = 0; | |
653 | + return; | |
654 | +} | |
655 | + | |
656 | +#undef R0 | |
657 | +#undef R1 | |
658 | + | |
659 | +void fcode_api0002(DecodeFcodeStr *s) | |
660 | +// api_drawPoint(mod, c, x, y). | |
661 | +{ | |
662 | + fcode_putRemark1(s); | |
663 | + fcode_putLimm(s, 16, 0x30, 0x0002); | |
664 | + fcode_putLimmOrCp(s, 16, 0x31); // mod. | |
665 | + if (s->flag4 == 0) { | |
666 | + fcode_putLimmOrCp(s, 32, 0x32); // c. | |
667 | + fcode_putLimmOrCp(s, 16, 0x33); // x. | |
668 | + fcode_putLimmOrCp(s, 16, 0x34); // y. | |
669 | + } else { | |
670 | + fcode_putCp(s, 32, 0x32, 0x00); // c. | |
671 | + fcode_putCp(s, 16, 0x33, 0x01); // x. | |
672 | + fcode_putCp(s, 16, 0x34, 0x02); // y. | |
673 | + s->flag4 = 0; | |
674 | + } | |
675 | + fcode_putPcallP28(s); | |
676 | + return; | |
677 | +} | |
678 | + | |
679 | +void fcode_api0003(DecodeFcodeStr *s) | |
680 | +// api_drawLine(mod, c, x0, y0, x1, y1). | |
681 | +{ | |
682 | + fcode_putRemark1(s); | |
683 | + fcode_putLimm(s, 16, 0x30, 0x0003); | |
684 | + fcode_putLimmOrCp(s, 16, 0x31); // mod. | |
685 | + if (s->flag4 == 0) { | |
686 | + fcode_putLimmOrCp(s, 32, 0x32); // c. | |
687 | + fcode_putLimmOrCp(s, 16, 0x33); // x0. | |
688 | + fcode_putLimmOrCp(s, 16, 0x34); // y0. | |
689 | + fcode_putLimmOrCp(s, 16, 0x35); // x1. | |
690 | + fcode_putLimmOrCp(s, 16, 0x36); // y1. | |
691 | + } else { | |
692 | + fcode_putCp(s, 32, 0x32, 0x00); // c. | |
693 | + fcode_putCp(s, 16, 0x33, 0x01); // x0. | |
694 | + fcode_putCp(s, 16, 0x34, 0x02); // y0. | |
695 | + fcode_putCp(s, 16, 0x35, 0x03); // x0. | |
696 | + fcode_putCp(s, 16, 0x36, 0x04); // y0. | |
697 | + s->flag4 = 0; | |
698 | + } | |
699 | + fcode_putPcallP28(s); | |
700 | + return; | |
701 | +} | |
702 | + | |
703 | +void fcode_api0004(DecodeFcodeStr *s) | |
704 | +// api_fillRect(mod, c, xsiz, ysiz, x0, y0). | |
705 | +// api_drawRect(mod, c, xsiz, ysiz, x0, y0). | |
706 | +{ | |
707 | + fcode_putRemark1(s); | |
708 | + fcode_putLimm(s, 16, 0x30, 0x0004); | |
709 | + fcode_putLimmOrCp(s, 16, 0x31); // mod. | |
710 | + if (s->flag4 == 0) { | |
711 | + fcode_putLimmOrCp(s, 32, 0x32); // c. | |
712 | + fcode_putLimmOrCp(s, 16, 0x33); // xsiz. | |
713 | + fcode_putLimmOrCp(s, 16, 0x34); // ysiz. | |
714 | + fcode_putLimmOrCp(s, 16, 0x35); // x1. | |
715 | + fcode_putLimmOrCp(s, 16, 0x36); // y1. | |
716 | + } else { | |
717 | + fcode_putCp(s, 32, 0x32, 0x00); // c. | |
718 | + fcode_putCp(s, 16, 0x33, 0x01); // xsiz. | |
719 | + fcode_putCp(s, 16, 0x34, 0x02); // ysiz. | |
720 | + fcode_putCp(s, 16, 0x35, 0x03); // x0. | |
721 | + fcode_putCp(s, 16, 0x36, 0x04); // y0. | |
722 | + s->flag4 = 0; | |
723 | + } | |
724 | + fcode_putPcallP28(s); | |
725 | + return; | |
726 | +} | |
727 | + | |
728 | +void fcode_api0005(DecodeFcodeStr *s) | |
729 | +// api_fillOval(mod, c, xsiz, ysiz, x0, y0). | |
730 | +// api_drawOval(mod, c, xsiz, ysiz, x0, y0). | |
731 | +{ | |
732 | + fcode_putRemark1(s); | |
733 | + fcode_putLimm(s, 16, 0x30, 0x0005); | |
734 | + fcode_putLimmOrCp(s, 16, 0x31); // mod. | |
735 | + if (s->flag4 == 0) { | |
736 | + fcode_putLimmOrCp(s, 32, 0x32); // c. | |
737 | + fcode_putLimmOrCp(s, 16, 0x33); // xsiz. | |
738 | + fcode_putLimmOrCp(s, 16, 0x34); // ysiz. | |
739 | + fcode_putLimmOrCp(s, 16, 0x35); // x0. | |
740 | + fcode_putLimmOrCp(s, 16, 0x36); // y0. | |
741 | + } else { | |
742 | + fcode_putCp(s, 32, 0x32, 0x00); // c. | |
743 | + fcode_putCp(s, 16, 0x33, 0x01); // xsiz. | |
744 | + fcode_putCp(s, 16, 0x34, 0x02); // ysiz. | |
745 | + fcode_putCp(s, 16, 0x35, 0x03); // x0. | |
746 | + fcode_putCp(s, 16, 0x36, 0x04); // y0. | |
747 | + s->flag4 = 0; | |
748 | + } | |
749 | + fcode_putPcallP28(s); | |
750 | + return; | |
751 | +} | |
752 | + | |
753 | +void fcode_api0010(DecodeFcodeStr *s) | |
754 | +// api_openWin(xsiz, ysiz). | |
755 | +{ | |
756 | + fcode_putRemark1(s); | |
757 | + fcode_putLimm(s, 16, 0x30, 0x0010); | |
758 | + fcode_putLimmOrCp(s, 16, 0x31); // xsiz. | |
759 | + fcode_putLimmOrCp(s, 16, 0x32); // ysiz. | |
760 | + fcode_putPcallP28(s); | |
761 | + return; | |
762 | +} | |
763 | + |
@@ -0,0 +1,20 @@ | ||
1 | +フロントエンドコードの仕様: | |
2 | + | |
3 | +0: NOP | |
4 | +1: LB(0, ++lastLabel) | |
5 | +4-1-(opt|(imm-lastLabel) <<8)): LB(opt, imm) | |
6 | +2-r-(c/r) | |
7 | + | |
8 | +rについて: | |
9 | + 0:rep0, 1:rep1, 2:R00, 3:R01,... (R3CとR3Dを後ろへ追い出す) | |
10 | + | |
11 | +c/rについて: | |
12 | + -11:R00,...,-20:R0F,-50:R3F,-51:+100,-52:+200,-53:+400,-54:+800, | |
13 | + -55:+1000,-56:+2000,-57:+4000,-58:+8000,-59:+64K,-5a...-5e:reserve, | |
14 | + -5f:rep0,-60:rep1,-61:-11,... | |
15 | +・LIMMと関数呼び出しの場合: | |
16 | + -1,0,1,2,3,4,rep0 | |
17 | + | |
18 | + | |
19 | + | |
20 | + |
@@ -158,6 +158,8 @@ int jitcAfterStepInteger(OsecpuJitc *jitc) | ||
158 | 158 | } |
159 | 159 | |
160 | 160 | Int32 execStep_checkBitsRange(Int32 value, int bit, OsecpuVm *vm, int bit1, int bit2) |
161 | +// 関数名はcheckになっているものの、prefix2f[0]!=0の場合はチェックをクリアできるような値に補正をする. | |
162 | +// つまりprefix2f[0]!=0の場合はチェックするのではなく値を補正する. | |
161 | 163 | { |
162 | 164 | int max, min, i; |
163 | 165 | if (bit1 != BIT_DISABLE_REG && bit2 != BIT_DISABLE_REG && vm->prefix2f[0] == 0) { |
@@ -269,11 +271,11 @@ void execStepInteger(OsecpuVm *vm) | ||
269 | 271 | jitcSetRetCode(&vm->errorCode, EXEC_BAD_BITS); |
270 | 272 | goto fin; |
271 | 273 | } |
272 | - if (bit <= vm->r[0x3f] || vm->r[0x3f] < 0) { | |
274 | + if (bit < vm->r[0x3f] || vm->r[0x3f] <= 0) { | |
273 | 275 | jitcSetRetCode(&vm->errorCode, EXEC_BAD_R2); |
274 | 276 | goto fin; |
275 | 277 | } |
276 | - vm->r[r0] = execStep_SignBitExtend(vm->r[r1], vm->r[0x3f]); | |
278 | + vm->r[r0] = execStep_SignBitExtend(vm->r[r1], vm->r[0x3f] - 1); | |
277 | 279 | vm->bit[r0] = bit; |
278 | 280 | vm->r[r0] = execStep_checkBitsRange(vm->r[r0], bit, vm, vm->bit[r1], 0); |
279 | 281 | ip += 5; |
@@ -323,11 +325,11 @@ void execStepInteger(OsecpuVm *vm) | ||
323 | 325 | } |
324 | 326 | if (0x20 <= opecode && opecode <= 0x27) { |
325 | 327 | r1 = ip[1]; r2 = ip[2]; bit1 = ip[3]; r0 = ip[4]; bit0 = ip[5]; |
326 | - if (vm->bit[r1] != BIT_DISABLE_REG && bit > vm->bit[r1]) { | |
328 | + if (vm->bit[r1] != BIT_DISABLE_REG && bit1 > vm->bit[r1]) { | |
327 | 329 | jitcSetRetCode(&vm->errorCode, EXEC_BAD_BITS); |
328 | 330 | goto fin; |
329 | 331 | } |
330 | - if (vm->bit[r2] != BIT_DISABLE_REG && bit > vm->bit[r2]) { | |
332 | + if (vm->bit[r2] != BIT_DISABLE_REG && bit1 > vm->bit[r2]) { | |
331 | 333 | jitcSetRetCode(&vm->errorCode, EXEC_BAD_BITS); |
332 | 334 | goto fin; |
333 | 335 | } |
@@ -1 +1 @@ | ||
1 | -c:\mingw\bin\gcc.exe -o osecpu.exe -Os osecpu-vm.c other.c integer.c pointer.c float.c extend.c api.c driver.c -Wl,-s,-lgdi32 | |
\ No newline at end of file | ||
1 | +c:\mingw\bin\gcc.exe -o osecpu.exe -Os osecpu-vm.c other.c integer.c pointer.c float.c extend.c api.c driver.c decode.c -Wl,-s,-lgdi32 | |
\ No newline at end of file |
@@ -121,3 +121,6 @@ | ||
121 | 121 | cfe-7-0 : ALIGNPREFIX1 |
122 | 122 | hh4は788を付ければ32bitで書ける。 |
123 | 123 | |
124 | +2014.06.06金: | |
125 | + chars: 05e2 460b8ba5145 : 7.5バイト。おしい。 | |
126 | + |
@@ -247,15 +247,15 @@ int execStep(OsecpuVm *vm) | ||
247 | 247 | { |
248 | 248 | const Int32 *ip = vm->ip; |
249 | 249 | vm->errorCode = 0; |
250 | + if (ip >= vm->ip1) { | |
251 | + vm->errorCode = EXEC_SRC_OVERRUN; | |
252 | + goto fin; | |
253 | + } | |
250 | 254 | execStepInteger(vm); if (ip != vm->ip || vm->errorCode != 0) goto fin; |
251 | 255 | execStepOther(vm); if (ip != vm->ip || vm->errorCode != 0) goto fin; |
252 | 256 | execStepPointer(vm); if (ip != vm->ip || vm->errorCode != 0) goto fin; |
253 | 257 | execStepFloat(vm); if (ip != vm->ip || vm->errorCode != 0) goto fin; |
254 | 258 | execStepExtend(vm); if (ip != vm->ip || vm->errorCode != 0) goto fin; |
255 | - if (*ip == -1) { | |
256 | - vm->errorCode = EXEC_ABORT_OPECODE_M1; // デバッグ用. | |
257 | - goto fin; | |
258 | - } | |
259 | 259 | |
260 | 260 | fprintf(stderr, "Error: execStep: opecode=0x%02X\n", *ip); // 内部エラー. |
261 | 261 | exit(1); |
@@ -121,15 +121,15 @@ int jitcAll(OsecpuJitc *jitc); | ||
121 | 121 | int execStep(OsecpuVm *r); // 検証済みのOSECPU命令を一つだけ実行する. |
122 | 122 | int execAll(OsecpuVm *vm); |
123 | 123 | |
124 | -#define EXEC_BAD_BITS 1 | |
125 | -#define EXEC_BITS_RANGE_OVER 2 | |
126 | -#define EXEC_BAD_R2 3 // SBX, SHL, SARのr2が不適切. | |
127 | -#define EXEC_DIVISION_BY_ZERO 4 | |
128 | -#define EXEC_SRC_OVERRUN 5 | |
129 | -#define EXEC_TYP_MISMATCH 6 | |
130 | -#define EXEC_PTR_RANGE_OVER 7 | |
131 | -#define EXEC_BAD_ACCESS 8 | |
132 | -#define EXEC_API_ERROR 9 | |
124 | +#define EXEC_BAD_BITS 1+256 | |
125 | +#define EXEC_BITS_RANGE_OVER 2+256 | |
126 | +#define EXEC_BAD_R2 3+256 // SBX, SHL, SARのr2が不適切. | |
127 | +#define EXEC_DIVISION_BY_ZERO 4+256 | |
128 | +#define EXEC_SRC_OVERRUN 5+256 | |
129 | +#define EXEC_TYP_MISMATCH 6+256 | |
130 | +#define EXEC_PTR_RANGE_OVER 7+256 | |
131 | +#define EXEC_BAD_ACCESS 8+256 | |
132 | +#define EXEC_API_ERROR 9+256 | |
133 | 133 | #define EXEC_ABORT_OPECODE_M1 0xffff |
134 | 134 | |
135 | 135 | #define EXEC_CMA_FLAG_SEEK 1 |
@@ -170,6 +170,7 @@ void execStepPointer(OsecpuVm *vm); | ||
170 | 170 | void getTypSize(int typ, int *typSize0, int *typSize1, int *typSign); // これは直すべき. |
171 | 171 | void jitcStep_checkPxx(int *pRC, int pxx); |
172 | 172 | void execStep_checkMemAccess(OsecpuVm *vm, int p, int typ, int flag); |
173 | +void execStep_plimm(OsecpuVm *vm, int p, int i); | |
173 | 174 | |
174 | 175 | // float.c : 浮動小数点命令 |
175 | 176 | void jitcInitFloat(OsecpuJitc *jitc); |
@@ -188,3 +189,9 @@ void jitcInitExtend(OsecpuJitc *jitc); | ||
188 | 189 | int jitcStepExtend(OsecpuJitc *jitc); |
189 | 190 | int jitcAfterStepExtend(OsecpuJitc *jitc); |
190 | 191 | void execStepExtend(OsecpuVm *vm); |
192 | + | |
193 | +// decode.c : フロントエンドコード関係. | |
194 | +int decode_upx (const unsigned char *p, const unsigned char *p1, unsigned char *q, unsigned char *q1); | |
195 | +int decode_tek5 (const unsigned char *p, const unsigned char *p1, unsigned char *q, unsigned char *q1); | |
196 | +int decode_fcode(const unsigned char *p, const unsigned char *p1, unsigned char *q, unsigned char *q1); | |
197 | + |
@@ -71,9 +71,9 @@ int jitcStepPointer(OsecpuJitc *jitc) | ||
71 | 71 | jitcSetRetCode(pRC, JITC_BAD_LABEL_TYPE); // P3Fにデータラベルを代入できない. |
72 | 72 | goto fin; |
73 | 73 | } |
74 | - if (opecode == 0x0e) { // PADD(r, bit, p1, typ, p0); | |
74 | + if (opecode == 0x0e) { // PADD(p1, typ, r, bit, p0); | |
75 | 75 | jitcSetHh4BufferSimple(jitc, 6); |
76 | - r = ip[1]; bit = ip[2]; p1 = ip[3]; typ = ip[4]; p0 = ip[5]; | |
76 | + p1 = ip[1]; typ = ip[2]; r = ip[3]; bit = ip[4]; p0 = ip[5]; | |
77 | 77 | jitcStep_checkPxx(pRC, p0); |
78 | 78 | jitcStep_checkPxx(pRC, p1); |
79 | 79 | jitcStep_checkRxx(pRC, r); |
@@ -187,31 +187,13 @@ void execStepPointer(OsecpuVm *vm) | ||
187 | 187 | if (p == 0x3f) |
188 | 188 | ip = (const Int32 *) vm->defines->label[i].dst; |
189 | 189 | else { |
190 | - typ = vm->defines->label[i].typ; | |
191 | - vm->p[p].typ = typ; | |
192 | - if (typ >= 2) { | |
193 | - vm->p[p].p = (unsigned char *) (vm->defines->label[i].dst + 3); | |
194 | - vm->p[p].p0 = vm->p[p].p; | |
195 | - len = vm->defines->label[i].dst[2]; // 2e(data)のlenフィールド値. | |
196 | - getTypSize(typ, &typSize0, &typSize1, &typSign); | |
197 | - vm->p[p].p1 = vm->p[p].p + typSize1 * len; | |
198 | - vm->p[p].bit = vm->p[p].p + ((typSize1 * len + 3) / 4) * 4; | |
199 | - vm->p[p].flags = 6; // over-seek:ok, read:ok, write:ok | |
200 | - } | |
201 | - if (typ == PTR_TYP_CODE) { // コードラベル. | |
202 | - vm->p[p].p = (unsigned char *) vm->defines->label[i].dst; | |
203 | - vm->p[p].p0 = vm->p[p].p; | |
204 | - vm->p[p].p1 = vm->p[p].p + 1; | |
205 | - vm->p[p].flags = 0; // over-seek:ok, read:err, write:err | |
206 | - } | |
207 | - if (typ == 1) { // VPtr. | |
208 | - } | |
190 | + execStep_plimm(vm, p, i); | |
209 | 191 | ip += 3; |
210 | 192 | } |
211 | 193 | goto fin; |
212 | 194 | } |
213 | - if (opecode == 0x0e) { // PADD(r, bit, p1, typ, p0); | |
214 | - r = ip[1]; bit = ip[2]; p1 = ip[3]; typ = ip[4]; p0 = ip[5]; | |
195 | + if (opecode == 0x0e) { // PADD(p1, typ, r, bit, p0); | |
196 | + p1 = ip[1]; typ = ip[2]; r = ip[3]; bit = ip[4]; p0 = ip[5]; | |
215 | 197 | getTypSize(typ, &typSize0, &typSize1, &typSign); |
216 | 198 | i = execStep_checkBitsRange(vm->r[r], bit, vm, 0, 0); |
217 | 199 | vm->p[p0] = vm->p[p1]; |
@@ -283,3 +265,28 @@ void execStep_checkMemAccess(OsecpuVm *vm, int p, int typ, int flag) | ||
283 | 265 | return; |
284 | 266 | } |
285 | 267 | |
268 | +void execStep_plimm(OsecpuVm *vm, int p, int i) | |
269 | +{ | |
270 | + int r, p0, p1, bit, typ, len, typSign, typSize0, typSize1; | |
271 | + typ = vm->defines->label[i].typ; | |
272 | + vm->p[p].typ = typ; | |
273 | + if (typ >= 2) { | |
274 | + vm->p[p].p = (unsigned char *) (vm->defines->label[i].dst + 3); | |
275 | + vm->p[p].p0 = vm->p[p].p; | |
276 | + len = vm->defines->label[i].dst[2]; // 2e(data)のlenフィールド値. | |
277 | + getTypSize(typ, &typSize0, &typSize1, &typSign); | |
278 | + vm->p[p].p1 = vm->p[p].p + typSize1 * len; | |
279 | + vm->p[p].bit = vm->p[p].p + ((typSize1 * len + 3) / 4) * 4; | |
280 | + vm->p[p].flags = 6; // over-seek:ok, read:ok, write:ok | |
281 | + } | |
282 | + if (typ == PTR_TYP_CODE) { // コードラベル. | |
283 | + vm->p[p].p = (unsigned char *) vm->defines->label[i].dst; | |
284 | + vm->p[p].p0 = vm->p[p].p; | |
285 | + vm->p[p].p1 = vm->p[p].p + 1; | |
286 | + vm->p[p].flags = 0; // over-seek:ok, read:err, write:err | |
287 | + } | |
288 | + if (typ == 1) { // VPtr. | |
289 | + } | |
290 | + return; | |
291 | +} | |
292 | + |
@@ -0,0 +1,670 @@ | ||
1 | +#include <setjmp.h> | |
2 | +#include <string.h> | |
3 | +#include <stdlib.h> | |
4 | + | |
5 | +#if (!defined(NULL)) | |
6 | + #define NULL 0 | |
7 | +#endif | |
8 | + | |
9 | +typedef unsigned char UCHAR; | |
10 | +typedef unsigned int UINT32; | |
11 | +typedef UINT32 tek_TPRB; | |
12 | + | |
13 | +static int tek_decode1(int siz, UCHAR *p, UCHAR *q); | |
14 | +static int tek_decode2(int siz, UCHAR *p, UCHAR *q); | |
15 | +static int tek_decode5(int siz, UCHAR *p, UCHAR *q); | |
16 | + | |
17 | +static unsigned int tek_getnum_s7s(UCHAR **pp) | |
18 | +/* これは必ずbig-endian */ | |
19 | +/* 下駄がないので中身をいじりやすい */ | |
20 | +{ | |
21 | + unsigned int s = 0; | |
22 | + UCHAR *p = *pp; | |
23 | + do { | |
24 | + s = s << 7 | *p++; | |
25 | + } while ((s & 1) == 0); | |
26 | + s >>= 1; | |
27 | + *pp = p; | |
28 | + return s; | |
29 | +} | |
30 | + | |
31 | +#if 0 | |
32 | + | |
33 | +int tek_getsize(unsigned char *p) | |
34 | +{ | |
35 | + static char header[15] = { | |
36 | + 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x4f, 0x53, 0x41, 0x53, 0x4b, 0x43, 0x4d, 0x50 | |
37 | + }; | |
38 | + int size = -1; | |
39 | + if (memcmp(p + 1, header, 15) == 0 && (*p == 0x83 || *p == 0x85 || *p == 0x89)) { | |
40 | + p += 16; | |
41 | + size = tek_getnum_s7s(&p); | |
42 | + } | |
43 | + return size; | |
44 | +} /* (註)memcmpはstrncmpの仲間で、文字列中に0があっても指定された15文字まで比較する関数 */ | |
45 | + | |
46 | +#endif | |
47 | + | |
48 | +int tek_decomp(unsigned char *p, char *q, int size) | |
49 | +{ | |
50 | + int err = -1; | |
51 | +#if 0 | |
52 | + if (*p == 0x83) { | |
53 | + err = tek_decode1(size, p, q); | |
54 | + } else if (*p == 0x85) { | |
55 | + err = tek_decode2(size, p, q); | |
56 | + } else if (*p == 0x89) { | |
57 | + err = tek_decode5(size, p, q); | |
58 | + } | |
59 | +#else | |
60 | +if (*p == 0x89) { | |
61 | + err = tek_decode5(size, p, q); | |
62 | + } | |
63 | +#endif | |
64 | + if (err != 0) { | |
65 | + return -1; /* 失敗 */ | |
66 | + } | |
67 | + return 0; /* 成功 */ | |
68 | +} | |
69 | + | |
70 | +#if 0 | |
71 | + | |
72 | +static int tek_lzrestore_stk1(int srcsiz, UCHAR *src, int outsiz, UCHAR *q) | |
73 | +{ | |
74 | + int by, lz, cp, ds; | |
75 | + UCHAR *q1 = q + outsiz, *s7ptr = src, *q0 = q; | |
76 | + do { | |
77 | + if ((by = (lz = *s7ptr++) & 0x0f) == 0) | |
78 | + by = tek_getnum_s7s(&s7ptr); | |
79 | + if ((lz >>= 4) == 0) | |
80 | + lz = tek_getnum_s7s(&s7ptr); | |
81 | + do { | |
82 | + *q++ = *s7ptr++; | |
83 | + } while (--by); | |
84 | + if (q >= q1) | |
85 | + break; | |
86 | + do { | |
87 | + ds = (cp = *s7ptr++) & 0x0f; | |
88 | + if ((ds & 1) == 0) { | |
89 | + do { | |
90 | + ds = ds << 7 | *s7ptr++; | |
91 | + } while ((ds & 1) == 0); | |
92 | + } | |
93 | + ds = ~(ds >> 1); | |
94 | + if ((cp >>= 4) == 0) { | |
95 | + do { | |
96 | + cp = cp << 7 | *s7ptr++; | |
97 | + } while ((cp & 1) == 0); | |
98 | + cp >>= 1; | |
99 | + } /* 0がこないことをあてにする */ | |
100 | + cp++; | |
101 | + if (q + ds < q0) | |
102 | + goto err; | |
103 | + if (q + cp > q1) | |
104 | + cp = q1 - q; | |
105 | + do { | |
106 | + *q = *(q + ds); | |
107 | + q++; | |
108 | + } while (--cp); | |
109 | + } while (--lz); | |
110 | + } while (q < q1); | |
111 | + return 0; | |
112 | +err: | |
113 | + return 1; | |
114 | +} | |
115 | + | |
116 | +static int tek_decode1(int siz, UCHAR *p, UCHAR *q) | |
117 | +{ | |
118 | + int dsiz, hed, bsiz; | |
119 | + UCHAR *p1 = p + siz; | |
120 | + p += 16; | |
121 | + if ((dsiz = tek_getnum_s7s(&p)) > 0) { | |
122 | + hed = tek_getnum_s7s(&p); | |
123 | + bsiz = 1 << (((hed >> 1) & 0x0f) + 8); | |
124 | + if (dsiz > bsiz || (hed & 0x21) != 0x01) | |
125 | + return 1; | |
126 | + if (hed & 0x40) | |
127 | + tek_getnum_s7s(&p); /* オプション情報へのポインタを読み飛ばす */ | |
128 | + if (tek_getnum_s7s(&p) != 0) | |
129 | + return 1; /* 補助バッファ使用 */ | |
130 | + return tek_lzrestore_stk1(p1 - p, p, dsiz, q); | |
131 | + } | |
132 | + return 0; | |
133 | +} | |
134 | + | |
135 | +static unsigned int tek_getnum_s7(UCHAR **pp) | |
136 | +/* これは必ずbig-endian */ | |
137 | +{ | |
138 | + unsigned int s = 0, b = 0, a = 1; | |
139 | + UCHAR *p = *pp; | |
140 | + for (;;) { | |
141 | + s = s << 7 | *p++; | |
142 | + if (s & 1) | |
143 | + break; | |
144 | + a <<= 7; | |
145 | + b += a; | |
146 | + } | |
147 | + s >>= 1; | |
148 | + *pp = p; | |
149 | + return s + b; | |
150 | +} | |
151 | + | |
152 | +static int tek_lzrestore_stk2(int srcsiz, UCHAR *src, int outsiz, UCHAR *q) | |
153 | +{ | |
154 | + int cp, ds, repdis[4], i, j; | |
155 | + UCHAR *q1 = q + outsiz, *s7ptr = src, *q0 = q, bylz, cbylz; | |
156 | + for (j = 0; j < 4; j++) | |
157 | + repdis[j] = -1 - j; | |
158 | + bylz = cbylz = 0; | |
159 | + if (outsiz) { | |
160 | + if (tek_getnum_s7s(&s7ptr)) | |
161 | + return 1; | |
162 | + do { | |
163 | + /* byフェーズ */ | |
164 | + j = 0; | |
165 | + do { | |
166 | + j++; | |
167 | + if (j >= 17) { | |
168 | + j += tek_getnum_s7s(&s7ptr); | |
169 | + break; | |
170 | + } | |
171 | + if (cbylz == 0) { | |
172 | + cbylz = 8; | |
173 | + bylz = *s7ptr++; | |
174 | + } | |
175 | + cbylz--; | |
176 | + i = bylz & 1; | |
177 | + bylz >>= 1; | |
178 | + } while (i == 0); | |
179 | + do { | |
180 | + *q++ = *s7ptr++; | |
181 | + } while (--j); | |
182 | + if (q >= q1) | |
183 | + break; | |
184 | + | |
185 | + /* lzフェーズ */ | |
186 | + j = 0; | |
187 | + do { | |
188 | + j++; | |
189 | + if (j >= 17) { | |
190 | + j += tek_getnum_s7s(&s7ptr); | |
191 | + break; | |
192 | + } | |
193 | + if (cbylz == 0) { | |
194 | + cbylz = 8; | |
195 | + bylz = *s7ptr++; | |
196 | + } | |
197 | + cbylz--; | |
198 | + i = bylz & 1; | |
199 | + bylz >>= 1; | |
200 | + } while (i == 0); | |
201 | + do { | |
202 | + i = *s7ptr++; | |
203 | + cp = i >> 4; | |
204 | + i &= 0x0f; | |
205 | + if ((i & 1) == 0) | |
206 | + i |= (tek_getnum_s7(&s7ptr) + 1) << 4; | |
207 | + i >>= 1; | |
208 | + ds = ~(i - 6); | |
209 | + if (i < 4) | |
210 | + ds = repdis[i]; | |
211 | + if (i == 4) | |
212 | + ds = repdis[0] - tek_getnum_s7(&s7ptr) - 1; | |
213 | + if (i == 5) | |
214 | + ds = repdis[0] + tek_getnum_s7(&s7ptr) + 1; | |
215 | + if (cp == 0) | |
216 | + cp = tek_getnum_s7(&s7ptr) + 16; | |
217 | + cp++; | |
218 | + if (i > 0) { | |
219 | + if (i > 1) { | |
220 | + if (i > 2) | |
221 | + repdis[3] = repdis[2]; | |
222 | + repdis[2] = repdis[1]; | |
223 | + } | |
224 | + repdis[1] = repdis[0]; | |
225 | + repdis[0] = ds; | |
226 | + } | |
227 | + if (q + ds < q0) | |
228 | + goto err; | |
229 | + if (q + cp > q1) | |
230 | + cp = q1 - q; | |
231 | + do { | |
232 | + *q = *(q + ds); | |
233 | + q++; | |
234 | + } while (--cp); | |
235 | + } while (--j); | |
236 | + } while (q < q1); | |
237 | + } | |
238 | + return 0; | |
239 | +err: | |
240 | + return 1; | |
241 | +} | |
242 | + | |
243 | +static int tek_decode2(int siz, UCHAR *p, UCHAR *q) | |
244 | +{ | |
245 | + UCHAR *p1 = p + siz; | |
246 | + int dsiz, hed, bsiz, st = 0; | |
247 | + p += 16; | |
248 | + if ((dsiz = tek_getnum_s7s(&p)) > 0) { | |
249 | + hed = tek_getnum_s7s(&p); | |
250 | + bsiz = 1 << (((hed >> 1) & 0x0f) + 8); | |
251 | + if (dsiz > bsiz || (hed & 0x21) != 0x01) | |
252 | + return 1; | |
253 | + if (hed & 0x40) | |
254 | + tek_getnum_s7s(&p); /* オプション情報へのポインタを読み飛ばす */ | |
255 | + st = tek_lzrestore_stk2(p1 - p, p, dsiz, q); | |
256 | + } | |
257 | + return st; | |
258 | +} | |
259 | + | |
260 | +#endif | |
261 | + | |
262 | +static int tek_decmain5(int *work, UCHAR *src, int osiz, UCHAR *q, int lc, int pb, int lp, int flags); | |
263 | + | |
264 | +static int tek_lzrestore_tek5(int srcsiz, UCHAR *src, int outsiz, UCHAR *outbuf) | |
265 | +{ | |
266 | + int wrksiz, lc, lp, pb, flags, *work, prop0, fl; | |
267 | + | |
268 | + if ((fl = (prop0 = *src) & 0x0f) == 0x01) /* 0001 */ | |
269 | + flags |= -1; | |
270 | + else if (fl == 0x05) | |
271 | + flags = -2; | |
272 | + else if (fl == 0x09) | |
273 | + flags &= 0; | |
274 | + else | |
275 | + return 1; | |
276 | + src++; | |
277 | + prop0 >>= 4; | |
278 | + if (prop0 == 0) | |
279 | + prop0 = *src++; | |
280 | + else { | |
281 | + static UCHAR prop0_table[] = { 0x5d, 0x00 }, prop1_table[] = { 0x00 }; | |
282 | + if (flags == -1) { | |
283 | + if (prop0 >= 3) | |
284 | + return 1; | |
285 | + prop0 = prop0_table[prop0 - 1]; | |
286 | + } else { | |
287 | + if (prop0 >= 2) | |
288 | + return 1; | |
289 | + prop0 = prop1_table[prop0 - 1]; | |
290 | + } | |
291 | + } | |
292 | + lp = prop0 / (9 * 5); | |
293 | + prop0 %= 9 * 5; | |
294 | + pb = prop0 / 9; | |
295 | + lc = prop0 % 9; | |
296 | + if (flags == 0) /* tek5:z2 */ | |
297 | + flags = *src++; | |
298 | + if (flags == -1) { /* stk5 */ | |
299 | + wrksiz = lp; | |
300 | + lp = pb; | |
301 | + pb = wrksiz; | |
302 | + } | |
303 | + wrksiz = 0x180 * sizeof (UINT32) + (0x840 + (0x300 << (lc + lp))) * sizeof (tek_TPRB); /* 最低15KB, lc+lp=3なら、36KB */ | |
304 | + work = (int *) malloc(wrksiz); | |
305 | + if (work == NULL) | |
306 | + return -1; | |
307 | + flags = tek_decmain5(work, src, outsiz, outbuf, lc, pb, lp, flags); | |
308 | + free(work); | |
309 | + return flags; | |
310 | +} | |
311 | + | |
312 | +struct tek_STR_BITMODEL { | |
313 | + UCHAR t, m, s, dmy; | |
314 | + UINT32 prb0, prb1, tmsk, ntm, lt, lt0, dmy4; | |
315 | +}; | |
316 | + | |
317 | +struct tek_STR_PRB { | |
318 | + struct tek_STR_PRB_PB { | |
319 | + struct tek_STR_PRB_PBST { | |
320 | + tek_TPRB mch, rep0l1; | |
321 | + } st[12]; | |
322 | + tek_TPRB lenlow[2][8], lenmid[2][8]; | |
323 | + } pb[16]; | |
324 | + struct tek_STR_PRB_ST { | |
325 | + tek_TPRB rep, repg0, repg1, repg2; | |
326 | + } st[12]; | |
327 | + tek_TPRB lensel[2][2], lenhigh[2][256], pslot[4][64], algn[64]; | |
328 | + tek_TPRB spdis[2][2+4+8+16+32], lenext[2+4+8+16+32]; | |
329 | + tek_TPRB repg3, fchgprm[2 * 32], tbmt[16], tbmm[16], fchglt; | |
330 | + tek_TPRB lit[1]; | |
331 | +}; | |
332 | + | |
333 | +struct tek_STR_RNGDEC { | |
334 | + UCHAR *p; | |
335 | + UINT32 range, code, rmsk; | |
336 | + jmp_buf errjmp; | |
337 | + struct tek_STR_BITMODEL bm[32], *ptbm[16]; | |
338 | + struct tek_STR_PRB probs; | |
339 | +}; | |
340 | + | |
341 | +static void tek_setbm5(struct tek_STR_BITMODEL *bm, int t, int m) | |
342 | +{ | |
343 | + bm->t = t; | |
344 | + bm->m = m; | |
345 | + bm->prb1 = -1 << (m + t); | |
346 | + bm->prb0 = ~bm->prb1; | |
347 | + bm->prb1 |= 1 << t; | |
348 | + bm->tmsk = (-1 << t) & 0xffff; | |
349 | + bm->prb0 &= bm->tmsk; | |
350 | + bm->prb1 &= bm->tmsk; | |
351 | + bm->ntm = ~bm->tmsk; | |
352 | + return; | |
353 | +} | |
354 | + | |
355 | +static int tek_rdget0(struct tek_STR_RNGDEC *rd, int n, int i) | |
356 | +{ | |
357 | + do { | |
358 | + while (rd->range < (UINT32) (1 << 24)) { | |
359 | + rd->range <<= 8; | |
360 | + rd->code = rd->code << 8 | *rd->p++; | |
361 | + } | |
362 | + rd->range >>= 1; | |
363 | + i += i; | |
364 | + if (rd->code >= rd->range) { | |
365 | + rd->code -= rd->range; | |
366 | + i |= 1; | |
367 | + } | |
368 | + } while (--n); | |
369 | + return ~i; | |
370 | +} | |
371 | + | |
372 | +static int tek_rdget1(struct tek_STR_RNGDEC *rd, tek_TPRB *prob0, int n, int j, struct tek_STR_BITMODEL *bm) | |
373 | +{ | |
374 | + UINT32 p, i, *prob, nm = n >> 4; | |
375 | + n &= 0x0f; | |
376 | + prob0 -= j; | |
377 | + do { | |
378 | + p = *(prob = prob0 + j); | |
379 | + if (bm->lt > 0) { | |
380 | + if (--bm->lt == 0) { | |
381 | + /* 寿命切れ */ | |
382 | + if (tek_rdget1(rd, &rd->probs.fchglt, 0x71, 0, &rd->bm[3]) == 0) { | |
383 | + /* 寿命変更はまだサポートしてない */ | |
384 | +err: | |
385 | + longjmp(rd->errjmp, 1); | |
386 | + } | |
387 | + i = bm - rd->bm; | |
388 | + if ((bm->s = tek_rdget1(rd, &rd->probs.fchgprm[i * 2 + bm->s], 0x71, 0, &rd->bm[1])) == 0) { | |
389 | + i = tek_rdget1(rd, rd->probs.tbmt, 0x74, 1, &rd->bm[2]) & 15; | |
390 | + if (i == 15) | |
391 | + goto err; | |
392 | + tek_setbm5(bm, i, ((tek_rdget1(rd, rd->probs.tbmm, 0x74, 1, &rd->bm[2]) - 1) & 15) + 1); | |
393 | + } | |
394 | + bm->lt = bm->lt0; | |
395 | + } | |
396 | + if (p < bm->prb0) { | |
397 | + p = bm->prb0; | |
398 | + goto fixprob; | |
399 | + } | |
400 | + if (p > bm->prb1) { | |
401 | + p = bm->prb1; | |
402 | + goto fixprob; | |
403 | + } | |
404 | + if (p & bm->ntm) { | |
405 | + p &= bm->tmsk; | |
406 | + fixprob: | |
407 | + *prob = p; | |
408 | + } | |
409 | + } | |
410 | + | |
411 | + while (rd->range < (UINT32) (1 << 24)) { | |
412 | + rd->range <<= 8; | |
413 | + rd->code = rd->code << 8 | *rd->p++; | |
414 | + } | |
415 | + j += j; | |
416 | + i = ((unsigned long long) (rd->range & rd->rmsk) * p) >> 16; | |
417 | + if (rd->code < i) { | |
418 | + j |= 1; | |
419 | + rd->range = i; | |
420 | + *prob += ((0x10000 - p) >> bm->m) & bm->tmsk; | |
421 | + } else { | |
422 | + rd->range -= i; | |
423 | + rd->code -= i; | |
424 | + *prob -= (p >> bm->m) & bm->tmsk; | |
425 | + } | |
426 | + --n; | |
427 | + if ((n & nm) == 0) | |
428 | + bm++; | |
429 | + } while (n); | |
430 | + return j; | |
431 | +} | |
432 | + | |
433 | +static UINT32 tek_revbit(UINT32 data, int len) | |
434 | +{ | |
435 | + UINT32 rev = 0; | |
436 | + do { | |
437 | + rev += rev + (data & 1); | |
438 | + data >>= 1; | |
439 | + } while (--len); | |
440 | + return rev; | |
441 | +} | |
442 | + | |
443 | +static int tek_getlen5(struct tek_STR_RNGDEC *rd, int m, int s_pos, int stk) | |
444 | +{ | |
445 | + int i; | |
446 | + if (tek_rdget1(rd, &rd->probs.lensel[m][0], 0x71, 0, rd->ptbm[3]) ^ stk) /* low */ | |
447 | + i = tek_rdget1(rd, rd->probs.pb[s_pos].lenlow[m], 0x73, 1, rd->ptbm[4]) & 7; | |
448 | + else if (tek_rdget1(rd, &rd->probs.lensel[m][1], 0x71, 0, rd->ptbm[3]) ^ stk) /* mid */ | |
449 | + i = tek_rdget1(rd, rd->probs.pb[s_pos].lenmid[m], 0x73, 1, rd->ptbm[5]); | |
450 | + else { | |
451 | + /* high */ | |
452 | + i = tek_rdget1(rd, rd->probs.lenhigh[m], 0x78, 1, rd->ptbm[6]) - (256 + 256 - 8); | |
453 | + if (i > 0) { | |
454 | + if (i < 6 && stk == 0) | |
455 | + i = tek_rdget1(rd, &rd->probs.lenext[(1 << i) - 2], i | 0x70, 1, rd->ptbm[7]) - 1; | |
456 | + else | |
457 | + i = tek_rdget0(rd, i, ~1) - 1; | |
458 | + i = tek_rdget0(rd, i, ~1) - 1; | |
459 | + } | |
460 | + i += 256 - 8 + 16; | |
461 | + } | |
462 | + return i; | |
463 | +} | |
464 | + | |
465 | +static int tek_decmain5(int *work, UCHAR *src, int osiz, UCHAR *q, int lc, int pb, int lp, int flags) | |
466 | +{ | |
467 | + static int state_table[] = { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 }; | |
468 | + int i, j, k, pmch, rep[4], s, pos, m_pos = (1 << pb) - 1, m_lp = (1 << lp) - 1; | |
469 | + int stk = (flags == -1), lcr = 8 - lc, s_pos, lit0cntmsk = 0x78; | |
470 | + UINT32 *lit1; | |
471 | + struct tek_STR_RNGDEC *rd = (struct tek_STR_RNGDEC *) work; | |
472 | + struct tek_STR_PRB *prb = &rd->probs; | |
473 | + | |
474 | + rd->p = &src[4]; | |
475 | + rd->range |= -1; | |
476 | + rd->code = src[0] << 24 | src[1] << 16 | src[2] << 8 | src[3]; | |
477 | + for (i = 0; i < 4; i++) | |
478 | + rep[i] = ~i; | |
479 | + if (setjmp(rd->errjmp)) | |
480 | + goto err; | |
481 | + for (i = sizeof (struct tek_STR_PRB) / sizeof (tek_TPRB) + (0x300 << (lc + lp)) - 2; i >= 0; i--) | |
482 | + ((tek_TPRB *) prb)[i] = 1 << 15; | |
483 | + for (i = 0; i < 32; i++) { | |
484 | + rd->bm[i].lt = (i >= 4); /* 0..3は寿命なし */ | |
485 | + rd->bm[i].lt0 = (i < 24) ? 16 * 1024 : 8 * 1024; | |
486 | + rd->bm[i].s &= 0; | |
487 | + rd->bm[i].t = rd->bm[i].m = 5; | |
488 | + } | |
489 | + lit1 = prb->lit + ((256 << (lc + lp)) - 2); | |
490 | + if (stk) { | |
491 | + rd->rmsk = -1 << 11; | |
492 | + for (i = 0; i < 32; i++) | |
493 | + rd->bm[i].lt = 0; /* 全て寿命なし */ | |
494 | + for (i = 0; i < 14; i++) | |
495 | + rd->ptbm[i] = &rd->bm[0]; | |
496 | + } else { | |
497 | + UCHAR pt[14]; | |
498 | + static UCHAR pt1[14] = { | |
499 | + 8, 8, 8, 8, 8, 8, 8, 8, | |
500 | + 8, 8, 18, 18, 18, 8 | |
501 | + }; | |
502 | + static UCHAR pt2[14] = { | |
503 | + 8, 8, 10, 11, 12, 12, 14, 15, | |
504 | + 16, 16, 18, 18, 20, 21 | |
505 | + }; | |
506 | + /* | |
507 | + 0- 7:mch, mch, lit1, lensel, lenlow, lenmid, lenhigh, lenext | |
508 | + 8-15:pslot, pslot, sdis, sdis, align, rep-repg2 | |
509 | + */ | |
510 | + rd->rmsk |= -1; | |
511 | + rd->bm[1].t = 5; rd->bm[1].m = 3; /* for fchgprm */ | |
512 | + rd->bm[2].t = 9; rd->bm[2].m = 2; /* for tbmt, tbmm */ | |
513 | + if (flags & 0x40) { /* lt-flag */ | |
514 | + rd->bm[3].t = 0; rd->bm[3].m = 1; | |
515 | + prb->fchglt = 0xffff; | |
516 | + } | |
517 | + rd->bm[22].t = 0; rd->bm[22].m = 1; | |
518 | + prb->repg3 = 0xffff; | |
519 | + if (flags == -2) { /* z1 */ | |
520 | + rd->bm[22].lt = 0; /* repg3のltを0に */ | |
521 | + for (i = 0; i < 14; i++) | |
522 | + pt[i] = pt1[i]; | |
523 | + } else { | |
524 | + for (i = 0; i < 14; i++) | |
525 | + pt[i] = pt2[i]; | |
526 | + lit0cntmsk = (7 >> (flags & 3)) << 4 | 8; | |
527 | + pt[ 1] = 8 + ((flags & 0x04) != 0); /* mch */ | |
528 | + pt[ 5] = 12 + ((flags & 0x08) != 0); /* llm */ | |
529 | + pt[ 9] = 16 + ((flags & 0x10) != 0); /* pst */ | |
530 | + pt[11] = 18 + ((flags & 0x20) != 0); /* sds */ | |
531 | + } | |
532 | + for (i = 0; i < 14; i++) | |
533 | + rd->ptbm[i] = &rd->bm[pt[i]]; | |
534 | + } | |
535 | + for (i = 0; i < 32; i++) | |
536 | + tek_setbm5(&rd->bm[i], rd->bm[i].t, rd->bm[i].m); | |
537 | + | |
538 | + if ((tek_rdget1(rd, &prb->pb[0].st[0].mch, 0x71, 0, rd->ptbm[0]) ^ stk) == 0) | |
539 | + goto err; | |
540 | + *q++ = tek_rdget1(rd, prb->lit, lit0cntmsk, 1, &rd->bm[24]) & 0xff; | |
541 | + pmch &= 0; s &= 0; pos = 1; | |
542 | + while (pos < osiz) { | |
543 | + s_pos = pos & m_pos; | |
544 | + if (tek_rdget1(rd, &prb->pb[s_pos].st[s].mch, 0x71, 0, rd->ptbm[s > 0]) ^ stk) { /* 非lz */ | |
545 | + i = (q[-1] >> lcr | (pos & m_lp) << lc) << 8; | |
546 | + s = state_table[s]; | |
547 | + if (pmch == 0) | |
548 | + *q = tek_rdget1(rd, &prb->lit[i], lit0cntmsk, 1, &rd->bm[24]) & 0xff; | |
549 | + else { | |
550 | + struct tek_STR_BITMODEL *bm = &rd->bm[24]; | |
551 | + j = 1; /* lit1は最初から2を減じてある */ | |
552 | + k = 8; | |
553 | + pmch = q[rep[0]]; | |
554 | + do { | |
555 | + j += j + tek_rdget1(rd, &lit1[(i + j) << 1 | pmch >> 7], 0x71, 0, rd->ptbm[2]); | |
556 | + k--; | |
557 | + if ((k & (lit0cntmsk >> 4)) == 0) | |
558 | + bm++; | |
559 | + if ((((pmch >> 7) ^ j) & 1) != 0 && k != 0) { | |
560 | + j = tek_rdget1(rd, &prb->lit[i + j - 1], k | (lit0cntmsk & 0x70), j, bm); | |
561 | + break; | |
562 | + } | |
563 | + pmch <<= 1; | |
564 | + } while (k); | |
565 | + *q = j & 0xff; | |
566 | + pmch &= 0; | |
567 | + } | |
568 | + pos++; | |
569 | + q++; | |
570 | + } else { /* lz */ | |
571 | + pmch |= 1; | |
572 | + if (tek_rdget1(rd, &prb->st[s].rep, 0x71, 0, rd->ptbm[13]) ^ stk) { /* len/dis */ | |
573 | + rep[3] = rep[2]; | |
574 | + rep[2] = rep[1]; | |
575 | + rep[1] = rep[0]; | |
576 | + j = i = tek_getlen5(rd, 0, s_pos, stk); | |
577 | + s = s < 7 ? 7 : 10; | |
578 | + if (j >= 4) | |
579 | + j = 3; | |
580 | + rep[0] = j = tek_rdget1(rd, prb->pslot[j], 0x76, 1, rd->ptbm[8 + (j == 3)]) & 0x3f; | |
581 | + if (j >= 4) { | |
582 | + k = (j >> 1) - 1; /* k = [1, 30] */ | |
583 | + rep[0] = (2 | (j & 1)) << k; | |
584 | + if (j < 14) /* k < 6 */ | |
585 | + rep[0] |= tek_revbit(tek_rdget1(rd, &prb->spdis[j & 1][(1 << k) - 2], k | 0x70, 1, rd->ptbm[10 + (k >= 4)]), k); | |
586 | + else { | |
587 | + if (stk == 0) { | |
588 | + if (k -= 6) | |
589 | + rep[0] |= tek_rdget0(rd, k, ~0) << 6; | |
590 | + rep[0] |= tek_revbit(tek_rdget1(rd, prb->algn, 0x76, 1, rd->ptbm[12]), 6); | |
591 | + } else { | |
592 | + rep[0] |= tek_rdget0(rd, k - 4, ~0) << 4; | |
593 | + rep[0] |= tek_revbit(tek_rdget1(rd, prb->algn, 0x74, 1, rd->ptbm[12]), 4); | |
594 | + } | |
595 | + } | |
596 | + } | |
597 | + rep[0] = ~rep[0]; | |
598 | + } else { /* repeat-dis */ | |
599 | + if (tek_rdget1(rd, &prb->st[s].repg0, 0x71, 0, rd->ptbm[13]) ^ stk) { /* rep0 */ | |
600 | + i |= -1; | |
601 | + if (tek_rdget1(rd, &prb->pb[s_pos].st[s].rep0l1, 0x71, 0, rd->ptbm[13]) == 0) { | |
602 | + s = s < 7 ? 9 : 11; | |
603 | + goto skip; | |
604 | + } | |
605 | + } else { | |
606 | + if (tek_rdget1(rd, &prb->st[s].repg1, 0x71, 0, rd->ptbm[13]) ^ stk) /* rep1 */ | |
607 | + i = rep[1]; | |
608 | + else { | |
609 | + if (tek_rdget1(rd, &prb->st[s].repg2, 0x71, 0, rd->ptbm[13]) ^ stk) /* rep2 */ | |
610 | + i = rep[2]; | |
611 | + else { | |
612 | + if (stk == 0) { | |
613 | + if (tek_rdget1(rd, &prb->repg3, 0x71, 0, &rd->bm[22]) == 0) | |
614 | + goto err; | |
615 | + } | |
616 | + i = rep[3]; /* rep3 */ | |
617 | + rep[3] = rep[2]; | |
618 | + } | |
619 | + rep[2] = rep[1]; | |
620 | + } | |
621 | + rep[1] = rep[0]; | |
622 | + rep[0] = i; | |
623 | + } | |
624 | + i = tek_getlen5(rd, 1, s_pos, stk); | |
625 | + s = s < 7 ? 8 : 11; | |
626 | + } | |
627 | +skip: | |
628 | + i += 2; | |
629 | + if (pos + rep[0] < 0) | |
630 | + goto err; | |
631 | + if (pos + i > osiz) | |
632 | + i = osiz - pos; | |
633 | + pos += i; | |
634 | + do { | |
635 | + *q = q[rep[0]]; | |
636 | + q++; | |
637 | + } while (--i); | |
638 | + } | |
639 | + } | |
640 | + return 0; | |
641 | +err: | |
642 | + return 1; | |
643 | +} | |
644 | + | |
645 | +static int tek_decode5(int siz, UCHAR *p, UCHAR *q) | |
646 | +{ | |
647 | + UCHAR *p1 = p + siz; | |
648 | + int dsiz, hed, bsiz, st = 0; | |
649 | + p += 16; | |
650 | + if ((dsiz = tek_getnum_s7s(&p)) > 0) { | |
651 | + hed = tek_getnum_s7s(&p); | |
652 | + if ((hed & 1) == 0) | |
653 | + st = tek_lzrestore_tek5(p1 - p + 1, p - 1, dsiz, q); | |
654 | + else { | |
655 | + bsiz = 1 << (((hed >> 1) & 0x0f) + 8); | |
656 | + if (hed & 0x20) | |
657 | + return 1; | |
658 | + if (bsiz == 256) | |
659 | + st = tek_lzrestore_tek5(p1 - p, p, dsiz, q); | |
660 | + else { | |
661 | + if (dsiz > bsiz) | |
662 | + return 1; | |
663 | + if (hed & 0x40) | |
664 | + tek_getnum_s7s(&p); /* オプション情報へのポインタを読み飛ばす */ | |
665 | + st = tek_lzrestore_tek5(p1 - p, p, dsiz, q); | |
666 | + } | |
667 | + } | |
668 | + } | |
669 | + return st; | |
670 | +} |