diff --git a/29_day/app_make.txt b/29_day/app_make.txt index 2bca4bc..30421f4 100644 --- a/29_day/app_make.txt +++ b/29_day/app_make.txt @@ -11,6 +11,7 @@ OBJ2BIM = $(TOOLPATH)obj2bim.exe MAKEFONT = $(TOOLPATH)makefont.exe BIN2OBJ = $(TOOLPATH)bin2obj.exe BIM2HRB = $(TOOLPATH)bim2hrb.exe +BIM2BIN = $(TOOLPATH)bim2bin.exe RULEFILE = ../haribote.rul EDIMG = $(TOOLPATH)edimg.exe IMGTOL = $(TOOLPATH)imgtol.com @@ -29,15 +30,13 @@ $(APP).bim : $(APP).obj $(APILIBPATH)apilib.lib Makefile ../app_make.txt $(OBJ2BIM) @$(RULEFILE) out:$(APP).bim map:$(APP).map stack:$(STACK) \ $(APP).obj $(APILIBPATH)apilib.lib -$(APP).hrb : $(APP).bim Makefile ../app_make.txt - $(BIM2HRB) $(APP).bim $(APP).hrb $(MALLOC) - -haribote.img : ../haribote/ipl10.bin ../haribote/haribote.sys $(APP).hrb \ +haribote.img : ../haribote/ipl20.bin ../haribote/haribote.sys $(APP).hrb \ Makefile ../app_make.txt $(EDIMG) imgin:../../z_tools/fdimg0at.tek \ - wbinimg src:../haribote/ipl10.bin len:512 from:0 to:0 \ + wbinimg src:../haribote/ipl20.bin len:512 from:0 to:0 \ copy from:../haribote/haribote.sys to:@: \ copy from:$(APP).hrb to:@: \ + copy from:../nihongo/nihongo.fnt to:@: \ imgout:haribote.img #一般规则 @@ -51,6 +50,12 @@ haribote.img : ../haribote/ipl10.bin ../haribote/haribote.sys $(APP).hrb \ %.obj : %.nas Makefile ../app_make.txt $(NASK) $*.nas $*.obj $*.lst +%.org : %.bim Makefile ../app_make.txt + $(BIM2HRB) $*.bim $*.org $(MALLOC) + +%.hrb : %.org Makefile ../app_make.txt + $(BIM2BIN) -osacmp in:$*.org out:$*.hrb + #命令 run : @@ -72,6 +77,7 @@ clean : -$(DEL) *.obj -$(DEL) *.map -$(DEL) *.bim + -$(DEL) *.org -$(DEL) haribote.img src_only : diff --git a/29_day/haribote/Makefile b/29_day/haribote/Makefile index 374bba7..a5dd10c 100644 --- a/29_day/haribote/Makefile +++ b/29_day/haribote/Makefile @@ -1,6 +1,6 @@ OBJS_BOOTPACK = bootpack.obj naskfunc.obj hankaku.obj graphic.obj dsctbl.obj \ int.obj fifo.obj keyboard.obj mouse.obj memory.obj sheet.obj timer.obj \ - mtask.obj window.obj console.obj file.obj + mtask.obj window.obj console.obj file.obj tek.obj TOOLPATH = ../../z_tools/ INCPATH = ../../z_tools/haribote/ diff --git a/29_day/haribote/bootpack.c b/29_day/haribote/bootpack.c index 92754c6..4a0000b 100644 --- a/29_day/haribote/bootpack.c +++ b/29_day/haribote/bootpack.c @@ -106,15 +106,17 @@ void HariMain(void) fifo32_put(&keycmd, key_leds); /* 载入nihongo.fnt */ - nihongo = (unsigned char *) memman_alloc_4k(memman, 16 * 256 + 32 * 94 * 47); fat = (int *) memman_alloc_4k(memman, 4 * 2880); file_readfat(fat, (unsigned char *) (ADR_DISKIMG + 0x000200)); + finfo = file_search("nihongo.fnt", (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224); if (finfo != 0) { - file_loadfile(finfo->clustno, finfo->size, nihongo, fat, (char *) (ADR_DISKIMG + 0x003e00)); + i = finfo->size; + nihongo = file_loadfile2(finfo->clustno, &i, fat); } else { + nihongo = (unsigned char *) memman_alloc_4k(memman, 16 * 256 + 32 * 94 * 47); for (i = 0; i < 16 * 256; i++) { - nihongo[i] = hankaku[i]; /* 没有字库,半角部分直接复制英文字库 */ + nihongo[i] = hankaku[i]; /*没有字库,半角部分直接复制英文字库*/ } for (i = 16 * 256; i < 16 * 256 + 32 * 94 * 47; i++) { nihongo[i] = 0xff; /* 没有字库,全角部分以0xff填充 */ diff --git a/29_day/haribote/bootpack.h b/29_day/haribote/bootpack.h index f2e8243..bb195ff 100644 --- a/29_day/haribote/bootpack.h +++ b/29_day/haribote/bootpack.h @@ -286,7 +286,12 @@ struct FILEINFO { void file_readfat(int *fat, unsigned char *img); void file_loadfile(int clustno, int size, char *buf, int *fat, char *img); struct FILEINFO *file_search(char *name, struct FILEINFO *finfo, int max); +char *file_loadfile2(int clustno, int *psize, int *fat); /* bootpack.c */ struct TASK *open_constask(struct SHEET *sht, unsigned int memtotal); struct SHEET *open_console(struct SHTCTL *shtctl, unsigned int memtotal); + +/* tek.c */ +int tek_getsize(unsigned char *p); +int tek_decomp(unsigned char *p, char *q, int size); diff --git a/29_day/haribote/console.c b/29_day/haribote/console.c index b231d2b..44047b0 100644 --- a/29_day/haribote/console.c +++ b/29_day/haribote/console.c @@ -350,7 +350,7 @@ int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline) struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; char name[18], *p, *q; struct TASK *task = task_now(); - int i, segsiz, datsiz, esp, dathrb; + int i, segsiz, datsiz, esp, dathrb, appsiz; struct SHTCTL *shtctl; struct SHEET *sht; @@ -376,10 +376,10 @@ int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline) } if (finfo != 0) { - /*找到文件的情况*/ - p = (char *) memman_alloc_4k(memman, finfo->size); - file_loadfile(finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); - if (finfo->size >= 36 && strncmp(p + 4, "Hari", 4) == 0 && *p == 0x00) { + /*如果找到文件*/ + appsiz = finfo->size; + p = file_loadfile2(finfo->clustno, &appsiz, fat); + if (appsiz >= 36 && strncmp(p + 4, "Hari", 4) == 0 && *p == 0x00) { segsiz = *((int *) (p + 0x0000)); esp = *((int *) (p + 0x000c)); datsiz = *((int *) (p + 0x0010)); @@ -412,7 +412,7 @@ int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline) } else { cons_putstr0(cons, ".hrb file format error.\n"); } - memman_free_4k(memman, (int) p, finfo->size); + memman_free_4k(memman, (int) p, appsiz); cons_newline(cons); return 1; } @@ -566,7 +566,7 @@ int *hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int fh->buf = (char *) memman_alloc_4k(memman, finfo->size); fh->size = finfo->size; fh->pos = 0; - file_loadfile(finfo->clustno, finfo->size, fh->buf, task->fat, (char *) (ADR_DISKIMG + 0x003e00)); + file_loadfile2(finfo->clustno, &fh->size, task->fat); } } } else if (edx == 22) { diff --git a/29_day/haribote/file.c b/29_day/haribote/file.c index bf9d063..a4bf405 100644 --- a/29_day/haribote/file.c +++ b/29_day/haribote/file.c @@ -72,3 +72,23 @@ next: } return 0; /*没有找到*/ } + +char *file_loadfile2(int clustno, int *psize, int *fat) +{ + int size = *psize, size2; + struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; + char *buf, *buf2; + buf = (char *) memman_alloc_4k(memman, size); + file_loadfile(clustno, size, buf, fat, (char *) (ADR_DISKIMG + 0x003e00)); + if (size >= 17) { + size2 = tek_getsize(buf); + if (size2 > 0) { /*使用tek格式压缩的文件*/ + buf2 = (char *) memman_alloc_4k(memman, size2); + tek_decomp(buf, buf2, size2); + memman_free_4k(memman, (int) buf, size); + buf = buf2; + *psize = size2; + } + } + return buf; +} diff --git a/29_day/haribote/tek.c b/29_day/haribote/tek.c new file mode 100644 index 0000000..4062dcc --- /dev/null +++ b/29_day/haribote/tek.c @@ -0,0 +1,646 @@ +#include "bootpack.h" +#include +#include +#define NULL 0 + +typedef unsigned char UCHAR; +typedef unsigned int UINT32; +typedef UINT32 tek_TPRB; + +static int tek_decode1(int siz, UCHAR *p, UCHAR *q); +static int tek_decode2(int siz, UCHAR *p, UCHAR *q); +static int tek_decode5(int siz, UCHAR *p, UCHAR *q); + +static unsigned int tek_getnum_s7s(UCHAR **pp) +{ + unsigned int s = 0; + UCHAR *p = *pp; + do { + s = s << 7 | *p++; + } while ((s & 1) == 0); + s >>= 1; + *pp = p; + return s; +} + +int tek_getsize(unsigned char *p) +{ + static char header[15] = { + 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x4f, 0x53, 0x41, 0x53, 0x4b, 0x43, 0x4d, 0x50 + }; + int size = -1; + if (memcmp(p + 1, header, 15) == 0 && (*p == 0x83 || *p == 0x85 || *p == 0x89)) { + p += 16; + size = tek_getnum_s7s(&p); + } + return size; +} /* (注)memcmp和strncmp差不多,这个函数忽略字符串中的0并一直比较到指定的15个字符为止*/ + +int tek_decomp(unsigned char *p, char *q, int size) +{ + int err = -1; + if (*p == 0x83) { + err = tek_decode1(size, p, q); + } else if (*p == 0x85) { + err = tek_decode2(size, p, q); + } else if (*p == 0x89) { + err = tek_decode5(size, p, q); + } + if (err != 0) { + return -1; /*失败*/ + } + return 0; /*成功*/ +} + +static int tek_lzrestore_stk1(int srcsiz, UCHAR *src, int outsiz, UCHAR *q) +{ + int by, lz, cp, ds; + UCHAR *q1 = q + outsiz, *s7ptr = src, *q0 = q; + do { + if ((by = (lz = *s7ptr++) & 0x0f) == 0) + by = tek_getnum_s7s(&s7ptr); + if ((lz >>= 4) == 0) + lz = tek_getnum_s7s(&s7ptr); + do { + *q++ = *s7ptr++; + } while (--by); + if (q >= q1) + break; + do { + ds = (cp = *s7ptr++) & 0x0f; + if ((ds & 1) == 0) { + do { + ds = ds << 7 | *s7ptr++; + } while ((ds & 1) == 0); + } + ds = ~(ds >> 1); + if ((cp >>= 4) == 0) { + do { + cp = cp << 7 | *s7ptr++; + } while ((cp & 1) == 0); + cp >>= 1; + } + cp++; + if (q + ds < q0) + goto err; + if (q + cp > q1) + cp = q1 - q; + do { + *q = *(q + ds); + q++; + } while (--cp); + } while (--lz); + } while (q < q1); + return 0; +err: + return 1; +} + +static int tek_decode1(int siz, UCHAR *p, UCHAR *q) +{ + int dsiz, hed, bsiz; + UCHAR *p1 = p + siz; + p += 16; + if ((dsiz = tek_getnum_s7s(&p)) > 0) { + hed = tek_getnum_s7s(&p); + bsiz = 1 << (((hed >> 1) & 0x0f) + 8); + if (dsiz > bsiz || (hed & 0x21) != 0x01) + return 1; + if (hed & 0x40) + tek_getnum_s7s(&p); + if (tek_getnum_s7s(&p) != 0) + return 1; + return tek_lzrestore_stk1(p1 - p, p, dsiz, q); + } + return 0; +} + +static unsigned int tek_getnum_s7(UCHAR **pp) +{ + unsigned int s = 0, b = 0, a = 1; + UCHAR *p = *pp; + for (;;) { + s = s << 7 | *p++; + if (s & 1) + break; + a <<= 7; + b += a; + } + s >>= 1; + *pp = p; + return s + b; +} + +static int tek_lzrestore_stk2(int srcsiz, UCHAR *src, int outsiz, UCHAR *q) +{ + int cp, ds, repdis[4], i, j; + UCHAR *q1 = q + outsiz, *s7ptr = src, *q0 = q, bylz, cbylz; + for (j = 0; j < 4; j++) + repdis[j] = -1 - j; + bylz = cbylz = 0; + if (outsiz) { + if (tek_getnum_s7s(&s7ptr)) + return 1; + do { + j = 0; + do { + j++; + if (j >= 17) { + j += tek_getnum_s7s(&s7ptr); + break; + } + if (cbylz == 0) { + cbylz = 8; + bylz = *s7ptr++; + } + cbylz--; + i = bylz & 1; + bylz >>= 1; + } while (i == 0); + do { + *q++ = *s7ptr++; + } while (--j); + if (q >= q1) + break; + + j = 0; + do { + j++; + if (j >= 17) { + j += tek_getnum_s7s(&s7ptr); + break; + } + if (cbylz == 0) { + cbylz = 8; + bylz = *s7ptr++; + } + cbylz--; + i = bylz & 1; + bylz >>= 1; + } while (i == 0); + do { + i = *s7ptr++; + cp = i >> 4; + i &= 0x0f; + if ((i & 1) == 0) + i |= (tek_getnum_s7(&s7ptr) + 1) << 4; + i >>= 1; + ds = ~(i - 6); + if (i < 4) + ds = repdis[i]; + if (i == 4) + ds = repdis[0] - tek_getnum_s7(&s7ptr) - 1; + if (i == 5) + ds = repdis[0] + tek_getnum_s7(&s7ptr) + 1; + if (cp == 0) + cp = tek_getnum_s7(&s7ptr) + 16; + cp++; + if (i > 0) { + if (i > 1) { + if (i > 2) + repdis[3] = repdis[2]; + repdis[2] = repdis[1]; + } + repdis[1] = repdis[0]; + repdis[0] = ds; + } + if (q + ds < q0) + goto err; + if (q + cp > q1) + cp = q1 - q; + do { + *q = *(q + ds); + q++; + } while (--cp); + } while (--j); + } while (q < q1); + } + return 0; +err: + return 1; +} + +static int tek_decode2(int siz, UCHAR *p, UCHAR *q) +{ + UCHAR *p1 = p + siz; + int dsiz, hed, bsiz, st = 0; + p += 16; + if ((dsiz = tek_getnum_s7s(&p)) > 0) { + hed = tek_getnum_s7s(&p); + bsiz = 1 << (((hed >> 1) & 0x0f) + 8); + if (dsiz > bsiz || (hed & 0x21) != 0x01) + return 1; + if (hed & 0x40) + tek_getnum_s7s(&p); + st = tek_lzrestore_stk2(p1 - p, p, dsiz, q); + } + return st; +} + +static int tek_decmain5(int *work, UCHAR *src, int osiz, UCHAR *q, int lc, int pb, int lp, int flags); + +static int tek_lzrestore_tek5(int srcsiz, UCHAR *src, int outsiz, UCHAR *outbuf) +{ + int wrksiz, lc, lp, pb, flags, *work, prop0, fl; + + if ((fl = (prop0 = *src) & 0x0f) == 0x01) /* 0001 */ + flags |= -1; + else if (fl == 0x05) + flags = -2; + else if (fl == 0x09) + flags &= 0; + else + return 1; + src++; + prop0 >>= 4; + if (prop0 == 0) + prop0 = *src++; + else { + static UCHAR prop0_table[] = { 0x5d, 0x00 }, prop1_table[] = { 0x00 }; + if (flags == -1) { + if (prop0 >= 3) + return 1; + prop0 = prop0_table[prop0 - 1]; + } else { + if (prop0 >= 2) + return 1; + prop0 = prop1_table[prop0 - 1]; + } + } + lp = prop0 / (9 * 5); + prop0 %= 9 * 5; + pb = prop0 / 9; + lc = prop0 % 9; + if (flags == 0) /* tek5:z2 */ + flags = *src++; + if (flags == -1) { /* stk5 */ + wrksiz = lp; + lp = pb; + pb = wrksiz; + } + wrksiz = 0x180 * sizeof (UINT32) + (0x840 + (0x300 << (lc + lp))) * sizeof (tek_TPRB); /* Å’á15KB, lc+lp=3‚È‚çA36KB */ + work = (int *) memman_alloc_4k((struct MEMMAN *) MEMMAN_ADDR, wrksiz); + if (work == NULL) + return -1; + flags = tek_decmain5(work, src, outsiz, outbuf, lc, pb, lp, flags); + memman_free_4k((struct MEMMAN *) MEMMAN_ADDR, (int) work, wrksiz); + return flags; +} + +struct tek_STR_BITMODEL { + UCHAR t, m, s, dmy; + UINT32 prb0, prb1, tmsk, ntm, lt, lt0, dmy4; +}; + +struct tek_STR_PRB { + struct tek_STR_PRB_PB { + struct tek_STR_PRB_PBST { + tek_TPRB mch, rep0l1; + } st[12]; + tek_TPRB lenlow[2][8], lenmid[2][8]; + } pb[16]; + struct tek_STR_PRB_ST { + tek_TPRB rep, repg0, repg1, repg2; + } st[12]; + tek_TPRB lensel[2][2], lenhigh[2][256], pslot[4][64], algn[64]; + tek_TPRB spdis[2][2+4+8+16+32], lenext[2+4+8+16+32]; + tek_TPRB repg3, fchgprm[2 * 32], tbmt[16], tbmm[16], fchglt; + tek_TPRB lit[1]; +}; + +struct tek_STR_RNGDEC { + UCHAR *p; + UINT32 range, code, rmsk; + jmp_buf errjmp; + struct tek_STR_BITMODEL bm[32], *ptbm[16]; + struct tek_STR_PRB probs; +}; + +static void tek_setbm5(struct tek_STR_BITMODEL *bm, int t, int m) +{ + bm->t = t; + bm->m = m; + bm->prb1 = -1 << (m + t); + bm->prb0 = ~bm->prb1; + bm->prb1 |= 1 << t; + bm->tmsk = (-1 << t) & 0xffff; + bm->prb0 &= bm->tmsk; + bm->prb1 &= bm->tmsk; + bm->ntm = ~bm->tmsk; + return; +} + +static int tek_rdget0(struct tek_STR_RNGDEC *rd, int n, int i) +{ + do { + while (rd->range < (UINT32) (1 << 24)) { + rd->range <<= 8; + rd->code = rd->code << 8 | *rd->p++; + } + rd->range >>= 1; + i += i; + if (rd->code >= rd->range) { + rd->code -= rd->range; + i |= 1; + } + } while (--n); + return ~i; +} + +static int tek_rdget1(struct tek_STR_RNGDEC *rd, tek_TPRB *prob0, int n, int j, struct tek_STR_BITMODEL *bm) +{ + UINT32 p, i, *prob, nm = n >> 4; + n &= 0x0f; + prob0 -= j; + do { + p = *(prob = prob0 + j); + if (bm->lt > 0) { + if (--bm->lt == 0) { + if (tek_rdget1(rd, &rd->probs.fchglt, 0x71, 0, &rd->bm[3]) == 0) { +err: + longjmp(rd->errjmp, 1); + } + i = bm - rd->bm; + if ((bm->s = tek_rdget1(rd, &rd->probs.fchgprm[i * 2 + bm->s], 0x71, 0, &rd->bm[1])) == 0) { + i = tek_rdget1(rd, rd->probs.tbmt, 0x74, 1, &rd->bm[2]) & 15; + if (i == 15) + goto err; + tek_setbm5(bm, i, ((tek_rdget1(rd, rd->probs.tbmm, 0x74, 1, &rd->bm[2]) - 1) & 15) + 1); + } + bm->lt = bm->lt0; + } + if (p < bm->prb0) { + p = bm->prb0; + goto fixprob; + } + if (p > bm->prb1) { + p = bm->prb1; + goto fixprob; + } + if (p & bm->ntm) { + p &= bm->tmsk; + fixprob: + *prob = p; + } + } + + while (rd->range < (UINT32) (1 << 24)) { + rd->range <<= 8; + rd->code = rd->code << 8 | *rd->p++; + } + j += j; + i = ((unsigned long long) (rd->range & rd->rmsk) * p) >> 16; + if (rd->code < i) { + j |= 1; + rd->range = i; + *prob += ((0x10000 - p) >> bm->m) & bm->tmsk; + } else { + rd->range -= i; + rd->code -= i; + *prob -= (p >> bm->m) & bm->tmsk; + } + --n; + if ((n & nm) == 0) + bm++; + } while (n); + return j; +} + +static UINT32 tek_revbit(UINT32 data, int len) +{ + UINT32 rev = 0; + do { + rev += rev + (data & 1); + data >>= 1; + } while (--len); + return rev; +} + +static int tek_getlen5(struct tek_STR_RNGDEC *rd, int m, int s_pos, int stk) +{ + int i; + if (tek_rdget1(rd, &rd->probs.lensel[m][0], 0x71, 0, rd->ptbm[3]) ^ stk) /* low */ + i = tek_rdget1(rd, rd->probs.pb[s_pos].lenlow[m], 0x73, 1, rd->ptbm[4]) & 7; + else if (tek_rdget1(rd, &rd->probs.lensel[m][1], 0x71, 0, rd->ptbm[3]) ^ stk) /* mid */ + i = tek_rdget1(rd, rd->probs.pb[s_pos].lenmid[m], 0x73, 1, rd->ptbm[5]); + else { + /* high */ + i = tek_rdget1(rd, rd->probs.lenhigh[m], 0x78, 1, rd->ptbm[6]) - (256 + 256 - 8); + if (i > 0) { + if (i < 6 && stk == 0) + i = tek_rdget1(rd, &rd->probs.lenext[(1 << i) - 2], i | 0x70, 1, rd->ptbm[7]) - 1; + else + i = tek_rdget0(rd, i, ~1) - 1; + i = tek_rdget0(rd, i, ~1) - 1; + } + i += 256 - 8 + 16; + } + return i; +} + +static int tek_decmain5(int *work, UCHAR *src, int osiz, UCHAR *q, int lc, int pb, int lp, int flags) +{ + static int state_table[] = { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 }; + int i, j, k, pmch, rep[4], s, pos, m_pos = (1 << pb) - 1, m_lp = (1 << lp) - 1; + int stk = (flags == -1), lcr = 8 - lc, s_pos, lit0cntmsk = 0x78; + UINT32 *lit1; + struct tek_STR_RNGDEC *rd = (struct tek_STR_RNGDEC *) work; + struct tek_STR_PRB *prb = &rd->probs; + + rd->p = &src[4]; + rd->range |= -1; + rd->code = src[0] << 24 | src[1] << 16 | src[2] << 8 | src[3]; + for (i = 0; i < 4; i++) + rep[i] = ~i; + if (setjmp(rd->errjmp)) + goto err; + for (i = sizeof (struct tek_STR_PRB) / sizeof (tek_TPRB) + (0x300 << (lc + lp)) - 2; i >= 0; i--) + ((tek_TPRB *) prb)[i] = 1 << 15; + for (i = 0; i < 32; i++) { + rd->bm[i].lt = (i >= 4); + rd->bm[i].lt0 = (i < 24) ? 16 * 1024 : 8 * 1024; + rd->bm[i].s &= 0; + rd->bm[i].t = rd->bm[i].m = 5; + } + lit1 = prb->lit + ((256 << (lc + lp)) - 2); + if (stk) { + rd->rmsk = -1 << 11; + for (i = 0; i < 32; i++) + rd->bm[i].lt = 0; + for (i = 0; i < 14; i++) + rd->ptbm[i] = &rd->bm[0]; + } else { + UCHAR pt[14]; + static UCHAR pt1[14] = { + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 18, 18, 18, 8 + }; + static UCHAR pt2[14] = { + 8, 8, 10, 11, 12, 12, 14, 15, + 16, 16, 18, 18, 20, 21 + }; + /* + 0- 7:mch, mch, lit1, lensel, lenlow, lenmid, lenhigh, lenext + 8-15:pslot, pslot, sdis, sdis, align, rep-repg2 + */ + rd->rmsk |= -1; + rd->bm[1].t = 5; rd->bm[1].m = 3; /* for fchgprm */ + rd->bm[2].t = 9; rd->bm[2].m = 2; /* for tbmt, tbmm */ + if (flags & 0x40) { /* lt-flag */ + rd->bm[3].t = 0; rd->bm[3].m = 1; + prb->fchglt = 0xffff; + } + rd->bm[22].t = 0; rd->bm[22].m = 1; + prb->repg3 = 0xffff; + if (flags == -2) { /* z1 */ + rd->bm[22].lt = 0; + for (i = 0; i < 14; i++) + pt[i] = pt1[i]; + } else { + for (i = 0; i < 14; i++) + pt[i] = pt2[i]; + lit0cntmsk = (7 >> (flags & 3)) << 4 | 8; + pt[ 1] = 8 + ((flags & 0x04) != 0); /* mch */ + pt[ 5] = 12 + ((flags & 0x08) != 0); /* llm */ + pt[ 9] = 16 + ((flags & 0x10) != 0); /* pst */ + pt[11] = 18 + ((flags & 0x20) != 0); /* sds */ + } + for (i = 0; i < 14; i++) + rd->ptbm[i] = &rd->bm[pt[i]]; + } + for (i = 0; i < 32; i++) + tek_setbm5(&rd->bm[i], rd->bm[i].t, rd->bm[i].m); + + if ((tek_rdget1(rd, &prb->pb[0].st[0].mch, 0x71, 0, rd->ptbm[0]) ^ stk) == 0) + goto err; + *q++ = tek_rdget1(rd, prb->lit, lit0cntmsk, 1, &rd->bm[24]) & 0xff; + pmch &= 0; s &= 0; pos = 1; + while (pos < osiz) { + s_pos = pos & m_pos; + if (tek_rdget1(rd, &prb->pb[s_pos].st[s].mch, 0x71, 0, rd->ptbm[s > 0]) ^ stk) { + i = (q[-1] >> lcr | (pos & m_lp) << lc) << 8; + s = state_table[s]; + if (pmch == 0) + *q = tek_rdget1(rd, &prb->lit[i], lit0cntmsk, 1, &rd->bm[24]) & 0xff; + else { + struct tek_STR_BITMODEL *bm = &rd->bm[24]; + j = 1; + k = 8; + pmch = q[rep[0]]; + do { + j += j + tek_rdget1(rd, &lit1[(i + j) << 1 | pmch >> 7], 0x71, 0, rd->ptbm[2]); + k--; + if ((k & (lit0cntmsk >> 4)) == 0) + bm++; + if ((((pmch >> 7) ^ j) & 1) != 0 && k != 0) { + j = tek_rdget1(rd, &prb->lit[i + j - 1], k | (lit0cntmsk & 0x70), j, bm); + break; + } + pmch <<= 1; + } while (k); + *q = j & 0xff; + pmch &= 0; + } + pos++; + q++; + } else { /* lz */ + pmch |= 1; + if (tek_rdget1(rd, &prb->st[s].rep, 0x71, 0, rd->ptbm[13]) ^ stk) { /* len/dis */ + rep[3] = rep[2]; + rep[2] = rep[1]; + rep[1] = rep[0]; + j = i = tek_getlen5(rd, 0, s_pos, stk); + s = s < 7 ? 7 : 10; + if (j >= 4) + j = 3; + rep[0] = j = tek_rdget1(rd, prb->pslot[j], 0x76, 1, rd->ptbm[8 + (j == 3)]) & 0x3f; + if (j >= 4) { + k = (j >> 1) - 1; /* k = [1, 30] */ + rep[0] = (2 | (j & 1)) << k; + if (j < 14) /* k < 6 */ + rep[0] |= tek_revbit(tek_rdget1(rd, &prb->spdis[j & 1][(1 << k) - 2], k | 0x70, 1, rd->ptbm[10 + (k >= 4)]), k); + else { + if (stk == 0) { + if (k -= 6) + rep[0] |= tek_rdget0(rd, k, ~0) << 6; + rep[0] |= tek_revbit(tek_rdget1(rd, prb->algn, 0x76, 1, rd->ptbm[12]), 6); + } else { + rep[0] |= tek_rdget0(rd, k - 4, ~0) << 4; + rep[0] |= tek_revbit(tek_rdget1(rd, prb->algn, 0x74, 1, rd->ptbm[12]), 4); + } + } + } + rep[0] = ~rep[0]; + } else { /* repeat-dis */ + if (tek_rdget1(rd, &prb->st[s].repg0, 0x71, 0, rd->ptbm[13]) ^ stk) { /* rep0 */ + i |= -1; + if (tek_rdget1(rd, &prb->pb[s_pos].st[s].rep0l1, 0x71, 0, rd->ptbm[13]) == 0) { + s = s < 7 ? 9 : 11; + goto skip; + } + } else { + if (tek_rdget1(rd, &prb->st[s].repg1, 0x71, 0, rd->ptbm[13]) ^ stk) /* rep1 */ + i = rep[1]; + else { + if (tek_rdget1(rd, &prb->st[s].repg2, 0x71, 0, rd->ptbm[13]) ^ stk) /* rep2 */ + i = rep[2]; + else { + if (stk == 0) { + if (tek_rdget1(rd, &prb->repg3, 0x71, 0, &rd->bm[22]) == 0) + goto err; + } + i = rep[3]; /* rep3 */ + rep[3] = rep[2]; + } + rep[2] = rep[1]; + } + rep[1] = rep[0]; + rep[0] = i; + } + i = tek_getlen5(rd, 1, s_pos, stk); + s = s < 7 ? 8 : 11; + } +skip: + i += 2; + if (pos + rep[0] < 0) + goto err; + if (pos + i > osiz) + i = osiz - pos; + pos += i; + do { + *q = q[rep[0]]; + q++; + } while (--i); + } + } + return 0; +err: + return 1; +} + +static int tek_decode5(int siz, UCHAR *p, UCHAR *q) +{ + UCHAR *p1 = p + siz; + int dsiz, hed, bsiz, st = 0; + p += 16; + if ((dsiz = tek_getnum_s7s(&p)) > 0) { + hed = tek_getnum_s7s(&p); + if ((hed & 1) == 0) + st = tek_lzrestore_tek5(p1 - p + 1, p - 1, dsiz, q); + else { + bsiz = 1 << (((hed >> 1) & 0x0f) + 8); + if (hed & 0x20) + return 1; + if (bsiz == 256) + st = tek_lzrestore_tek5(p1 - p, p, dsiz, q); + else { + if (dsiz > bsiz) + return 1; + if (hed & 0x40) + tek_getnum_s7s(&p); + st = tek_lzrestore_tek5(p1 - p, p, dsiz, q); + } + } + } + return st; +} diff --git a/29_day/hello4/Makefile b/29_day/hello4/Makefile index f4cb8d2..557a184 100644 --- a/29_day/hello4/Makefile +++ b/29_day/hello4/Makefile @@ -3,3 +3,6 @@ STACK = 1k MALLOC = 0k include ../app_make.txt + +$(APP).hrb : $(APP).org Makefile + $(COPY) $(APP).org $(APP).hrb diff --git a/29_day/hello5/Makefile b/29_day/hello5/Makefile index 366ff9d..e07f802 100644 --- a/29_day/hello5/Makefile +++ b/29_day/hello5/Makefile @@ -3,3 +3,6 @@ STACK = 1k MALLOC = 0k include ../app_make.txt + +$(APP).hrb : $(APP).org Makefile + $(COPY) $(APP).org $(APP).hrb diff --git a/29_day/nihongo/nihongo.fnt b/29_day/nihongo/nihongo.fnt index e312bf5..4faa31d 100644 Binary files a/29_day/nihongo/nihongo.fnt and b/29_day/nihongo/nihongo.fnt differ diff --git a/29_day/nihongo/nihongo.org b/29_day/nihongo/nihongo.org new file mode 100644 index 0000000..e312bf5 Binary files /dev/null and b/29_day/nihongo/nihongo.org differ diff --git a/29_day/tek/autodec_.c b/29_day/tek/autodec_.c new file mode 100644 index 0000000..4d5454b --- /dev/null +++ b/29_day/tek/autodec_.c @@ -0,0 +1,649 @@ +#include /* NULL */ +#include /* malloc, free */ +#include + +typedef unsigned char UCHAR; +typedef unsigned int UINT32; +typedef UINT32 tek_TPRB; + +static int tek_decode1(int siz, UCHAR *p, UCHAR *q); +static int tek_decode2(int siz, UCHAR *p, UCHAR *q); +static int tek_decode5(int siz, UCHAR *p, UCHAR *q); + +static unsigned int tek_getnum_s7s(UCHAR **pp) +{ + unsigned int s = 0; + UCHAR *p = *pp; + do { + s = s << 7 | *p++; + } while ((s & 1) == 0); + s >>= 1; + *pp = p; + return s; +} + +int autodecomp(int siz0, UCHAR *p0, int siz) +{ + unsigned char *b = p0, *c, *c0; + int s, i, e = 0; + if ((*(int *) &b[0x08] == 0x5341534f) && (*(int *) &b[0x0c] == 0x504d434b)) { + if (*(int *) &b[0x04] == 0x00000001) { + unsigned int t = *(int *) &b[0x00]; + e |= 1; + if (0xffffff83 <= t && t <= 0xffffff89) { + c = &b[0x10]; + s = tek_getnum_s7s(&c); + if (s + siz - 0x10 <= siz0) { + c0 = c = b + siz0 - siz; + for (i = siz - 1; i >= 0x10; i--) + c[i] = b[i]; + c += 0x10; + tek_getnum_s7s(&c); + if (t == 0xffffff83) + e = tek_decode1(siz, c0, b); + if (t == 0xffffff85) + e = tek_decode2(siz, c0, b); + if (t == 0xffffff89) + e = tek_decode5(siz, c0, b); + siz = s; + } + } + } + } + if (e) + siz |= -1; + return siz; +} + +static int tek_lzrestore_stk1(int srcsiz, UCHAR *src, int outsiz, UCHAR *q) +{ + int by, lz, cp, ds; + UCHAR *q1 = q + outsiz, *s7ptr = src, *q0 = q; + do { + if ((by = (lz = *s7ptr++) & 0x0f) == 0) + by = tek_getnum_s7s(&s7ptr); + if ((lz >>= 4) == 0) + lz = tek_getnum_s7s(&s7ptr); + do { + *q++ = *s7ptr++; + } while (--by); + if (q >= q1) + break; + do { + ds = (cp = *s7ptr++) & 0x0f; + if ((ds & 1) == 0) { + do { + ds = ds << 7 | *s7ptr++; + } while ((ds & 1) == 0); + } + ds = ~(ds >> 1); + if ((cp >>= 4) == 0) { + do { + cp = cp << 7 | *s7ptr++; + } while ((cp & 1) == 0); + cp >>= 1; + } + cp++; + if (q + ds < q0) + goto err; + if (q + cp > q1) + cp = q1 - q; + do { + *q = *(q + ds); + q++; + } while (--cp); + } while (--lz); + } while (q < q1); + return 0; +err: + return 1; +} + +static int tek_decode1(int siz, UCHAR *p, UCHAR *q) +{ + int dsiz, hed, bsiz; + UCHAR *p1 = p + siz; + p += 16; + if ((dsiz = tek_getnum_s7s(&p)) > 0) { + hed = tek_getnum_s7s(&p); + bsiz = 1 << (((hed >> 1) & 0x0f) + 8); + if (dsiz > bsiz || (hed & 0x21) != 0x01) + return 1; + if (hed & 0x40) + tek_getnum_s7s(&p); + if (tek_getnum_s7s(&p) != 0) + return 1; + return tek_lzrestore_stk1(p1 - p, p, dsiz, q); + } + return 0; +} + +static unsigned int tek_getnum_s7(UCHAR **pp) +{ + unsigned int s = 0, b = 0, a = 1; + UCHAR *p = *pp; + for (;;) { + s = s << 7 | *p++; + if (s & 1) + break; + a <<= 7; + b += a; + } + s >>= 1; + *pp = p; + return s + b; +} + +static int tek_lzrestore_stk2(int srcsiz, UCHAR *src, int outsiz, UCHAR *q) +{ + int cp, ds, repdis[4], i, j; + UCHAR *q1 = q + outsiz, *s7ptr = src, *q0 = q, bylz, cbylz; + for (j = 0; j < 4; j++) + repdis[j] = -1 - j; + bylz = cbylz = 0; + if (outsiz) { + if (tek_getnum_s7s(&s7ptr)) + return 1; + do { + j = 0; + do { + j++; + if (j >= 17) { + j += tek_getnum_s7s(&s7ptr); + break; + } + if (cbylz == 0) { + cbylz = 8; + bylz = *s7ptr++; + } + cbylz--; + i = bylz & 1; + bylz >>= 1; + } while (i == 0); + do { + *q++ = *s7ptr++; + } while (--j); + if (q >= q1) + break; + + j = 0; + do { + j++; + if (j >= 17) { + j += tek_getnum_s7s(&s7ptr); + break; + } + if (cbylz == 0) { + cbylz = 8; + bylz = *s7ptr++; + } + cbylz--; + i = bylz & 1; + bylz >>= 1; + } while (i == 0); + do { + i = *s7ptr++; + cp = i >> 4; + i &= 0x0f; + if ((i & 1) == 0) + i |= (tek_getnum_s7(&s7ptr) + 1) << 4; + i >>= 1; + ds = ~(i - 6); + if (i < 4) + ds = repdis[i]; + if (i == 4) + ds = repdis[0] - tek_getnum_s7(&s7ptr) - 1; + if (i == 5) + ds = repdis[0] + tek_getnum_s7(&s7ptr) + 1; + if (cp == 0) + cp = tek_getnum_s7(&s7ptr) + 16; + cp++; + if (i > 0) { + if (i > 1) { + if (i > 2) + repdis[3] = repdis[2]; + repdis[2] = repdis[1]; + } + repdis[1] = repdis[0]; + repdis[0] = ds; + } + if (q + ds < q0) + goto err; + if (q + cp > q1) + cp = q1 - q; + do { + *q = *(q + ds); + q++; + } while (--cp); + } while (--j); + } while (q < q1); + } + return 0; +err: + return 1; +} + +static int tek_decode2(int siz, UCHAR *p, UCHAR *q) +{ + UCHAR *p1 = p + siz; + int dsiz, hed, bsiz, st = 0; + p += 16; + if ((dsiz = tek_getnum_s7s(&p)) > 0) { + hed = tek_getnum_s7s(&p); + bsiz = 1 << (((hed >> 1) & 0x0f) + 8); + if (dsiz > bsiz || (hed & 0x21) != 0x01) + return 1; + if (hed & 0x40) + tek_getnum_s7s(&p); + st = tek_lzrestore_stk2(p1 - p, p, dsiz, q); + } + return st; +} + +static int tek_decmain5(int *work, UCHAR *src, int osiz, UCHAR *q, int lc, int pb, int lp, int flags); + +static int tek_lzrestore_tek5(int srcsiz, UCHAR *src, int outsiz, UCHAR *outbuf) +{ + int wrksiz, lc, lp, pb, flags, *work, prop0, fl; + + if ((fl = (prop0 = *src) & 0x0f) == 0x01) /* 0001 */ + flags |= -1; + else if (fl == 0x05) + flags = -2; + else if (fl == 0x09) + flags &= 0; + else + return 1; + src++; + prop0 >>= 4; + if (prop0 == 0) + prop0 = *src++; + else { + static UCHAR prop0_table[] = { 0x5d, 0x00 }, prop1_table[] = { 0x00 }; + if (flags == -1) { + if (prop0 >= 3) + return 1; + prop0 = prop0_table[prop0 - 1]; + } else { + if (prop0 >= 2) + return 1; + prop0 = prop1_table[prop0 - 1]; + } + } + lp = prop0 / (9 * 5); + prop0 %= 9 * 5; + pb = prop0 / 9; + lc = prop0 % 9; + if (flags == 0) /* tek5:z2 */ + flags = *src++; + if (flags == -1) { /* stk5 */ + wrksiz = lp; + lp = pb; + pb = wrksiz; + } + wrksiz = 0x180 * sizeof (UINT32) + (0x840 + (0x300 << (lc + lp))) * sizeof (tek_TPRB); + work = malloc(wrksiz); + if (work == NULL) + return -1; + flags = tek_decmain5(work, src, outsiz, outbuf, lc, pb, lp, flags); + free(work); + return flags; +} + +struct tek_STR_BITMODEL { + UCHAR t, m, s, dmy; + UINT32 prb0, prb1, tmsk, ntm, lt, lt0, dmy4; +}; + +struct tek_STR_PRB { + struct tek_STR_PRB_PB { + struct tek_STR_PRB_PBST { + tek_TPRB mch, rep0l1; + } st[12]; + tek_TPRB lenlow[2][8], lenmid[2][8]; + } pb[16]; + struct tek_STR_PRB_ST { + tek_TPRB rep, repg0, repg1, repg2; + } st[12]; + tek_TPRB lensel[2][2], lenhigh[2][256], pslot[4][64], algn[64]; + tek_TPRB spdis[2][2+4+8+16+32], lenext[2+4+8+16+32]; + tek_TPRB repg3, fchgprm[2 * 32], tbmt[16], tbmm[16], fchglt; + tek_TPRB lit[1]; +}; + +struct tek_STR_RNGDEC { + UCHAR *p; + UINT32 range, code, rmsk; + jmp_buf errjmp; + struct tek_STR_BITMODEL bm[32], *ptbm[16]; + struct tek_STR_PRB probs; +}; + +static void tek_setbm5(struct tek_STR_BITMODEL *bm, int t, int m) +{ + bm->t = t; + bm->m = m; + bm->prb1 = -1 << (m + t); + bm->prb0 = ~bm->prb1; + bm->prb1 |= 1 << t; + bm->tmsk = (-1 << t) & 0xffff; + bm->prb0 &= bm->tmsk; + bm->prb1 &= bm->tmsk; + bm->ntm = ~bm->tmsk; + return; +} + +static int tek_rdget0(struct tek_STR_RNGDEC *rd, int n, int i) +{ + do { + while (rd->range < (UINT32) (1 << 24)) { + rd->range <<= 8; + rd->code = rd->code << 8 | *rd->p++; + } + rd->range >>= 1; + i += i; + if (rd->code >= rd->range) { + rd->code -= rd->range; + i |= 1; + } + } while (--n); + return ~i; +} + +static int tek_rdget1(struct tek_STR_RNGDEC *rd, tek_TPRB *prob0, int n, int j, struct tek_STR_BITMODEL *bm) +{ + UINT32 p, i, *prob, nm = n >> 4; + n &= 0x0f; + prob0 -= j; + do { + p = *(prob = prob0 + j); + if (bm->lt > 0) { + if (--bm->lt == 0) { + if (tek_rdget1(rd, &rd->probs.fchglt, 0x71, 0, &rd->bm[3]) == 0) { +err: + longjmp(rd->errjmp, 1); + } + i = bm - rd->bm; + if ((bm->s = tek_rdget1(rd, &rd->probs.fchgprm[i * 2 + bm->s], 0x71, 0, &rd->bm[1])) == 0) { + i = tek_rdget1(rd, rd->probs.tbmt, 0x74, 1, &rd->bm[2]) & 15; + if (i == 15) + goto err; + tek_setbm5(bm, i, ((tek_rdget1(rd, rd->probs.tbmm, 0x74, 1, &rd->bm[2]) - 1) & 15) + 1); + } + bm->lt = bm->lt0; + } + if (p < bm->prb0) { + p = bm->prb0; + goto fixprob; + } + if (p > bm->prb1) { + p = bm->prb1; + goto fixprob; + } + if (p & bm->ntm) { + p &= bm->tmsk; + fixprob: + *prob = p; + } + } + + while (rd->range < (UINT32) (1 << 24)) { + rd->range <<= 8; + rd->code = rd->code << 8 | *rd->p++; + } + j += j; + i = ((unsigned long long) (rd->range & rd->rmsk) * p) >> 16; + if (rd->code < i) { + j |= 1; + rd->range = i; + *prob += ((0x10000 - p) >> bm->m) & bm->tmsk; + } else { + rd->range -= i; + rd->code -= i; + *prob -= (p >> bm->m) & bm->tmsk; + } + --n; + if ((n & nm) == 0) + bm++; + } while (n); + return j; +} + +static UINT32 tek_revbit(UINT32 data, int len) +{ + UINT32 rev = 0; + do { + rev += rev + (data & 1); + data >>= 1; + } while (--len); + return rev; +} + +static int tek_getlen5(struct tek_STR_RNGDEC *rd, int m, int s_pos, int stk) +{ + int i; + if (tek_rdget1(rd, &rd->probs.lensel[m][0], 0x71, 0, rd->ptbm[3]) ^ stk) /* low */ + i = tek_rdget1(rd, rd->probs.pb[s_pos].lenlow[m], 0x73, 1, rd->ptbm[4]) & 7; + else if (tek_rdget1(rd, &rd->probs.lensel[m][1], 0x71, 0, rd->ptbm[3]) ^ stk) /* mid */ + i = tek_rdget1(rd, rd->probs.pb[s_pos].lenmid[m], 0x73, 1, rd->ptbm[5]); + else { + /* high */ + i = tek_rdget1(rd, rd->probs.lenhigh[m], 0x78, 1, rd->ptbm[6]) - (256 + 256 - 8); + if (i > 0) { + if (i < 6 && stk == 0) + i = tek_rdget1(rd, &rd->probs.lenext[(1 << i) - 2], i | 0x70, 1, rd->ptbm[7]) - 1; + else + i = tek_rdget0(rd, i, ~1) - 1; + i = tek_rdget0(rd, i, ~1) - 1; + } + i += 256 - 8 + 16; + } + return i; +} + +static int tek_decmain5(int *work, UCHAR *src, int osiz, UCHAR *q, int lc, int pb, int lp, int flags) +{ + static int state_table[] = { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 }; + int i, j, k, pmch, rep[4], s, pos, m_pos = (1 << pb) - 1, m_lp = (1 << lp) - 1; + int stk = (flags == -1), lcr = 8 - lc, s_pos, lit0cntmsk = 0x78; + UINT32 *lit1; + struct tek_STR_RNGDEC *rd = (struct tek_STR_RNGDEC *) work; + struct tek_STR_PRB *prb = &rd->probs; + + rd->p = &src[4]; + rd->range |= -1; + rd->code = src[0] << 24 | src[1] << 16 | src[2] << 8 | src[3]; + for (i = 0; i < 4; i++) + rep[i] = ~i; + if (setjmp(rd->errjmp)) + goto err; + for (i = sizeof (struct tek_STR_PRB) / sizeof (tek_TPRB) + (0x300 << (lc + lp)) - 2; i >= 0; i--) + ((tek_TPRB *) prb)[i] = 1 << 15; + for (i = 0; i < 32; i++) { + rd->bm[i].lt = (i >= 4); + rd->bm[i].lt0 = (i < 24) ? 16 * 1024 : 8 * 1024; + rd->bm[i].s &= 0; + rd->bm[i].t = rd->bm[i].m = 5; + } + lit1 = prb->lit + ((256 << (lc + lp)) - 2); + if (stk) { + rd->rmsk = -1 << 11; + for (i = 0; i < 32; i++) + rd->bm[i].lt = 0; + for (i = 0; i < 14; i++) + rd->ptbm[i] = &rd->bm[0]; + } else { + UCHAR pt[14]; + static UCHAR pt1[14] = { + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 18, 18, 18, 8 + }; + static UCHAR pt2[14] = { + 8, 8, 10, 11, 12, 12, 14, 15, + 16, 16, 18, 18, 20, 21 + }; + /* + 0- 7:mch, mch, lit1, lensel, lenlow, lenmid, lenhigh, lenext + 8-15:pslot, pslot, sdis, sdis, align, rep-repg2 + */ + rd->rmsk |= -1; + rd->bm[1].t = 5; rd->bm[1].m = 3; /* for fchgprm */ + rd->bm[2].t = 9; rd->bm[2].m = 2; /* for tbmt, tbmm */ + if (flags & 0x40) { /* lt-flag */ + rd->bm[3].t = 0; rd->bm[3].m = 1; + prb->fchglt = 0xffff; + } + rd->bm[22].t = 0; rd->bm[22].m = 1; + prb->repg3 = 0xffff; + if (flags == -2) { /* z1 */ + rd->bm[22].lt = 0; + for (i = 0; i < 14; i++) + pt[i] = pt1[i]; + } else { + for (i = 0; i < 14; i++) + pt[i] = pt2[i]; + lit0cntmsk = (7 >> (flags & 3)) << 4 | 8; + pt[ 1] = 8 + ((flags & 0x04) != 0); /* mch */ + pt[ 5] = 12 + ((flags & 0x08) != 0); /* llm */ + pt[ 9] = 16 + ((flags & 0x10) != 0); /* pst */ + pt[11] = 18 + ((flags & 0x20) != 0); /* sds */ + } + for (i = 0; i < 14; i++) + rd->ptbm[i] = &rd->bm[pt[i]]; + } + for (i = 0; i < 32; i++) + tek_setbm5(&rd->bm[i], rd->bm[i].t, rd->bm[i].m); + + if ((tek_rdget1(rd, &prb->pb[0].st[0].mch, 0x71, 0, rd->ptbm[0]) ^ stk) == 0) + goto err; + *q++ = tek_rdget1(rd, prb->lit, lit0cntmsk, 1, &rd->bm[24]) & 0xff; + pmch &= 0; s &= 0; pos = 1; + while (pos < osiz) { + s_pos = pos & m_pos; + if (tek_rdget1(rd, &prb->pb[s_pos].st[s].mch, 0x71, 0, rd->ptbm[s > 0]) ^ stk) { + i = (q[-1] >> lcr | (pos & m_lp) << lc) << 8; + s = state_table[s]; + if (pmch == 0) + *q = tek_rdget1(rd, &prb->lit[i], lit0cntmsk, 1, &rd->bm[24]) & 0xff; + else { + struct tek_STR_BITMODEL *bm = &rd->bm[24]; + j = 1; /* lit1‚͍ŏ‰‚©‚ç2‚ðŒ¸‚¶‚Ä‚ ‚é */ + k = 8; + pmch = q[rep[0]]; + do { + j += j + tek_rdget1(rd, &lit1[(i + j) << 1 | pmch >> 7], 0x71, 0, rd->ptbm[2]); + k--; + if ((k & (lit0cntmsk >> 4)) == 0) + bm++; + if ((((pmch >> 7) ^ j) & 1) != 0 && k != 0) { + j = tek_rdget1(rd, &prb->lit[i + j - 1], k | (lit0cntmsk & 0x70), j, bm); + break; + } + pmch <<= 1; + } while (k); + *q = j & 0xff; + pmch &= 0; + } + pos++; + q++; + } else { /* lz */ + pmch |= 1; + if (tek_rdget1(rd, &prb->st[s].rep, 0x71, 0, rd->ptbm[13]) ^ stk) { /* len/dis */ + rep[3] = rep[2]; + rep[2] = rep[1]; + rep[1] = rep[0]; + j = i = tek_getlen5(rd, 0, s_pos, stk); + s = s < 7 ? 7 : 10; + if (j >= 4) + j = 3; + rep[0] = j = tek_rdget1(rd, prb->pslot[j], 0x76, 1, rd->ptbm[8 + (j == 3)]) & 0x3f; + if (j >= 4) { + k = (j >> 1) - 1; /* k = [1, 30] */ + rep[0] = (2 | (j & 1)) << k; + if (j < 14) /* k < 6 */ + rep[0] |= tek_revbit(tek_rdget1(rd, &prb->spdis[j & 1][(1 << k) - 2], k | 0x70, 1, rd->ptbm[10 + (k >= 4)]), k); + else { + if (stk == 0) { + if (k -= 6) + rep[0] |= tek_rdget0(rd, k, ~0) << 6; + rep[0] |= tek_revbit(tek_rdget1(rd, prb->algn, 0x76, 1, rd->ptbm[12]), 6); + } else { + rep[0] |= tek_rdget0(rd, k - 4, ~0) << 4; + rep[0] |= tek_revbit(tek_rdget1(rd, prb->algn, 0x74, 1, rd->ptbm[12]), 4); + } + } + } + rep[0] = ~rep[0]; + } else { /* repeat-dis */ + if (tek_rdget1(rd, &prb->st[s].repg0, 0x71, 0, rd->ptbm[13]) ^ stk) { /* rep0 */ + i |= -1; + if (tek_rdget1(rd, &prb->pb[s_pos].st[s].rep0l1, 0x71, 0, rd->ptbm[13]) == 0) { + s = s < 7 ? 9 : 11; + goto skip; + } + } else { + if (tek_rdget1(rd, &prb->st[s].repg1, 0x71, 0, rd->ptbm[13]) ^ stk) /* rep1 */ + i = rep[1]; + else { + if (tek_rdget1(rd, &prb->st[s].repg2, 0x71, 0, rd->ptbm[13]) ^ stk) /* rep2 */ + i = rep[2]; + else { + if (stk == 0) { + if (tek_rdget1(rd, &prb->repg3, 0x71, 0, &rd->bm[22]) == 0) + goto err; + } + i = rep[3]; /* rep3 */ + rep[3] = rep[2]; + } + rep[2] = rep[1]; + } + rep[1] = rep[0]; + rep[0] = i; + } + i = tek_getlen5(rd, 1, s_pos, stk); + s = s < 7 ? 8 : 11; + } +skip: + i += 2; + if (pos + rep[0] < 0) + goto err; + if (pos + i > osiz) + i = osiz - pos; + pos += i; + do { + *q = q[rep[0]]; + q++; + } while (--i); + } + } + return 0; +err: + return 1; +} + +int tek_decode5(int siz, UCHAR *p, UCHAR *q) +{ + UCHAR *p1 = p + siz; + int dsiz, hed, bsiz, st = 0; + p += 16; + if ((dsiz = tek_getnum_s7s(&p)) > 0) { + hed = tek_getnum_s7s(&p); + if ((hed & 1) == 0) + st = tek_lzrestore_tek5(p1 - p + 1, p - 1, dsiz, q); + else { + bsiz = 1 << (((hed >> 1) & 0x0f) + 8); + if (hed & 0x20) + return 1; + if (bsiz == 256) + st = tek_lzrestore_tek5(p1 - p, p, dsiz, q); + else { + if (dsiz > bsiz) + return 1; + if (hed & 0x40) + tek_getnum_s7s(&p); + st = tek_lzrestore_tek5(p1 - p, p, dsiz, q); + } + } + } + return st; +} diff --git a/29_day/tek/tek.c b/29_day/tek/tek.c new file mode 100644 index 0000000..4062dcc --- /dev/null +++ b/29_day/tek/tek.c @@ -0,0 +1,646 @@ +#include "bootpack.h" +#include +#include +#define NULL 0 + +typedef unsigned char UCHAR; +typedef unsigned int UINT32; +typedef UINT32 tek_TPRB; + +static int tek_decode1(int siz, UCHAR *p, UCHAR *q); +static int tek_decode2(int siz, UCHAR *p, UCHAR *q); +static int tek_decode5(int siz, UCHAR *p, UCHAR *q); + +static unsigned int tek_getnum_s7s(UCHAR **pp) +{ + unsigned int s = 0; + UCHAR *p = *pp; + do { + s = s << 7 | *p++; + } while ((s & 1) == 0); + s >>= 1; + *pp = p; + return s; +} + +int tek_getsize(unsigned char *p) +{ + static char header[15] = { + 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x4f, 0x53, 0x41, 0x53, 0x4b, 0x43, 0x4d, 0x50 + }; + int size = -1; + if (memcmp(p + 1, header, 15) == 0 && (*p == 0x83 || *p == 0x85 || *p == 0x89)) { + p += 16; + size = tek_getnum_s7s(&p); + } + return size; +} /* (注)memcmp和strncmp差不多,这个函数忽略字符串中的0并一直比较到指定的15个字符为止*/ + +int tek_decomp(unsigned char *p, char *q, int size) +{ + int err = -1; + if (*p == 0x83) { + err = tek_decode1(size, p, q); + } else if (*p == 0x85) { + err = tek_decode2(size, p, q); + } else if (*p == 0x89) { + err = tek_decode5(size, p, q); + } + if (err != 0) { + return -1; /*失败*/ + } + return 0; /*成功*/ +} + +static int tek_lzrestore_stk1(int srcsiz, UCHAR *src, int outsiz, UCHAR *q) +{ + int by, lz, cp, ds; + UCHAR *q1 = q + outsiz, *s7ptr = src, *q0 = q; + do { + if ((by = (lz = *s7ptr++) & 0x0f) == 0) + by = tek_getnum_s7s(&s7ptr); + if ((lz >>= 4) == 0) + lz = tek_getnum_s7s(&s7ptr); + do { + *q++ = *s7ptr++; + } while (--by); + if (q >= q1) + break; + do { + ds = (cp = *s7ptr++) & 0x0f; + if ((ds & 1) == 0) { + do { + ds = ds << 7 | *s7ptr++; + } while ((ds & 1) == 0); + } + ds = ~(ds >> 1); + if ((cp >>= 4) == 0) { + do { + cp = cp << 7 | *s7ptr++; + } while ((cp & 1) == 0); + cp >>= 1; + } + cp++; + if (q + ds < q0) + goto err; + if (q + cp > q1) + cp = q1 - q; + do { + *q = *(q + ds); + q++; + } while (--cp); + } while (--lz); + } while (q < q1); + return 0; +err: + return 1; +} + +static int tek_decode1(int siz, UCHAR *p, UCHAR *q) +{ + int dsiz, hed, bsiz; + UCHAR *p1 = p + siz; + p += 16; + if ((dsiz = tek_getnum_s7s(&p)) > 0) { + hed = tek_getnum_s7s(&p); + bsiz = 1 << (((hed >> 1) & 0x0f) + 8); + if (dsiz > bsiz || (hed & 0x21) != 0x01) + return 1; + if (hed & 0x40) + tek_getnum_s7s(&p); + if (tek_getnum_s7s(&p) != 0) + return 1; + return tek_lzrestore_stk1(p1 - p, p, dsiz, q); + } + return 0; +} + +static unsigned int tek_getnum_s7(UCHAR **pp) +{ + unsigned int s = 0, b = 0, a = 1; + UCHAR *p = *pp; + for (;;) { + s = s << 7 | *p++; + if (s & 1) + break; + a <<= 7; + b += a; + } + s >>= 1; + *pp = p; + return s + b; +} + +static int tek_lzrestore_stk2(int srcsiz, UCHAR *src, int outsiz, UCHAR *q) +{ + int cp, ds, repdis[4], i, j; + UCHAR *q1 = q + outsiz, *s7ptr = src, *q0 = q, bylz, cbylz; + for (j = 0; j < 4; j++) + repdis[j] = -1 - j; + bylz = cbylz = 0; + if (outsiz) { + if (tek_getnum_s7s(&s7ptr)) + return 1; + do { + j = 0; + do { + j++; + if (j >= 17) { + j += tek_getnum_s7s(&s7ptr); + break; + } + if (cbylz == 0) { + cbylz = 8; + bylz = *s7ptr++; + } + cbylz--; + i = bylz & 1; + bylz >>= 1; + } while (i == 0); + do { + *q++ = *s7ptr++; + } while (--j); + if (q >= q1) + break; + + j = 0; + do { + j++; + if (j >= 17) { + j += tek_getnum_s7s(&s7ptr); + break; + } + if (cbylz == 0) { + cbylz = 8; + bylz = *s7ptr++; + } + cbylz--; + i = bylz & 1; + bylz >>= 1; + } while (i == 0); + do { + i = *s7ptr++; + cp = i >> 4; + i &= 0x0f; + if ((i & 1) == 0) + i |= (tek_getnum_s7(&s7ptr) + 1) << 4; + i >>= 1; + ds = ~(i - 6); + if (i < 4) + ds = repdis[i]; + if (i == 4) + ds = repdis[0] - tek_getnum_s7(&s7ptr) - 1; + if (i == 5) + ds = repdis[0] + tek_getnum_s7(&s7ptr) + 1; + if (cp == 0) + cp = tek_getnum_s7(&s7ptr) + 16; + cp++; + if (i > 0) { + if (i > 1) { + if (i > 2) + repdis[3] = repdis[2]; + repdis[2] = repdis[1]; + } + repdis[1] = repdis[0]; + repdis[0] = ds; + } + if (q + ds < q0) + goto err; + if (q + cp > q1) + cp = q1 - q; + do { + *q = *(q + ds); + q++; + } while (--cp); + } while (--j); + } while (q < q1); + } + return 0; +err: + return 1; +} + +static int tek_decode2(int siz, UCHAR *p, UCHAR *q) +{ + UCHAR *p1 = p + siz; + int dsiz, hed, bsiz, st = 0; + p += 16; + if ((dsiz = tek_getnum_s7s(&p)) > 0) { + hed = tek_getnum_s7s(&p); + bsiz = 1 << (((hed >> 1) & 0x0f) + 8); + if (dsiz > bsiz || (hed & 0x21) != 0x01) + return 1; + if (hed & 0x40) + tek_getnum_s7s(&p); + st = tek_lzrestore_stk2(p1 - p, p, dsiz, q); + } + return st; +} + +static int tek_decmain5(int *work, UCHAR *src, int osiz, UCHAR *q, int lc, int pb, int lp, int flags); + +static int tek_lzrestore_tek5(int srcsiz, UCHAR *src, int outsiz, UCHAR *outbuf) +{ + int wrksiz, lc, lp, pb, flags, *work, prop0, fl; + + if ((fl = (prop0 = *src) & 0x0f) == 0x01) /* 0001 */ + flags |= -1; + else if (fl == 0x05) + flags = -2; + else if (fl == 0x09) + flags &= 0; + else + return 1; + src++; + prop0 >>= 4; + if (prop0 == 0) + prop0 = *src++; + else { + static UCHAR prop0_table[] = { 0x5d, 0x00 }, prop1_table[] = { 0x00 }; + if (flags == -1) { + if (prop0 >= 3) + return 1; + prop0 = prop0_table[prop0 - 1]; + } else { + if (prop0 >= 2) + return 1; + prop0 = prop1_table[prop0 - 1]; + } + } + lp = prop0 / (9 * 5); + prop0 %= 9 * 5; + pb = prop0 / 9; + lc = prop0 % 9; + if (flags == 0) /* tek5:z2 */ + flags = *src++; + if (flags == -1) { /* stk5 */ + wrksiz = lp; + lp = pb; + pb = wrksiz; + } + wrksiz = 0x180 * sizeof (UINT32) + (0x840 + (0x300 << (lc + lp))) * sizeof (tek_TPRB); /* Å’á15KB, lc+lp=3‚È‚çA36KB */ + work = (int *) memman_alloc_4k((struct MEMMAN *) MEMMAN_ADDR, wrksiz); + if (work == NULL) + return -1; + flags = tek_decmain5(work, src, outsiz, outbuf, lc, pb, lp, flags); + memman_free_4k((struct MEMMAN *) MEMMAN_ADDR, (int) work, wrksiz); + return flags; +} + +struct tek_STR_BITMODEL { + UCHAR t, m, s, dmy; + UINT32 prb0, prb1, tmsk, ntm, lt, lt0, dmy4; +}; + +struct tek_STR_PRB { + struct tek_STR_PRB_PB { + struct tek_STR_PRB_PBST { + tek_TPRB mch, rep0l1; + } st[12]; + tek_TPRB lenlow[2][8], lenmid[2][8]; + } pb[16]; + struct tek_STR_PRB_ST { + tek_TPRB rep, repg0, repg1, repg2; + } st[12]; + tek_TPRB lensel[2][2], lenhigh[2][256], pslot[4][64], algn[64]; + tek_TPRB spdis[2][2+4+8+16+32], lenext[2+4+8+16+32]; + tek_TPRB repg3, fchgprm[2 * 32], tbmt[16], tbmm[16], fchglt; + tek_TPRB lit[1]; +}; + +struct tek_STR_RNGDEC { + UCHAR *p; + UINT32 range, code, rmsk; + jmp_buf errjmp; + struct tek_STR_BITMODEL bm[32], *ptbm[16]; + struct tek_STR_PRB probs; +}; + +static void tek_setbm5(struct tek_STR_BITMODEL *bm, int t, int m) +{ + bm->t = t; + bm->m = m; + bm->prb1 = -1 << (m + t); + bm->prb0 = ~bm->prb1; + bm->prb1 |= 1 << t; + bm->tmsk = (-1 << t) & 0xffff; + bm->prb0 &= bm->tmsk; + bm->prb1 &= bm->tmsk; + bm->ntm = ~bm->tmsk; + return; +} + +static int tek_rdget0(struct tek_STR_RNGDEC *rd, int n, int i) +{ + do { + while (rd->range < (UINT32) (1 << 24)) { + rd->range <<= 8; + rd->code = rd->code << 8 | *rd->p++; + } + rd->range >>= 1; + i += i; + if (rd->code >= rd->range) { + rd->code -= rd->range; + i |= 1; + } + } while (--n); + return ~i; +} + +static int tek_rdget1(struct tek_STR_RNGDEC *rd, tek_TPRB *prob0, int n, int j, struct tek_STR_BITMODEL *bm) +{ + UINT32 p, i, *prob, nm = n >> 4; + n &= 0x0f; + prob0 -= j; + do { + p = *(prob = prob0 + j); + if (bm->lt > 0) { + if (--bm->lt == 0) { + if (tek_rdget1(rd, &rd->probs.fchglt, 0x71, 0, &rd->bm[3]) == 0) { +err: + longjmp(rd->errjmp, 1); + } + i = bm - rd->bm; + if ((bm->s = tek_rdget1(rd, &rd->probs.fchgprm[i * 2 + bm->s], 0x71, 0, &rd->bm[1])) == 0) { + i = tek_rdget1(rd, rd->probs.tbmt, 0x74, 1, &rd->bm[2]) & 15; + if (i == 15) + goto err; + tek_setbm5(bm, i, ((tek_rdget1(rd, rd->probs.tbmm, 0x74, 1, &rd->bm[2]) - 1) & 15) + 1); + } + bm->lt = bm->lt0; + } + if (p < bm->prb0) { + p = bm->prb0; + goto fixprob; + } + if (p > bm->prb1) { + p = bm->prb1; + goto fixprob; + } + if (p & bm->ntm) { + p &= bm->tmsk; + fixprob: + *prob = p; + } + } + + while (rd->range < (UINT32) (1 << 24)) { + rd->range <<= 8; + rd->code = rd->code << 8 | *rd->p++; + } + j += j; + i = ((unsigned long long) (rd->range & rd->rmsk) * p) >> 16; + if (rd->code < i) { + j |= 1; + rd->range = i; + *prob += ((0x10000 - p) >> bm->m) & bm->tmsk; + } else { + rd->range -= i; + rd->code -= i; + *prob -= (p >> bm->m) & bm->tmsk; + } + --n; + if ((n & nm) == 0) + bm++; + } while (n); + return j; +} + +static UINT32 tek_revbit(UINT32 data, int len) +{ + UINT32 rev = 0; + do { + rev += rev + (data & 1); + data >>= 1; + } while (--len); + return rev; +} + +static int tek_getlen5(struct tek_STR_RNGDEC *rd, int m, int s_pos, int stk) +{ + int i; + if (tek_rdget1(rd, &rd->probs.lensel[m][0], 0x71, 0, rd->ptbm[3]) ^ stk) /* low */ + i = tek_rdget1(rd, rd->probs.pb[s_pos].lenlow[m], 0x73, 1, rd->ptbm[4]) & 7; + else if (tek_rdget1(rd, &rd->probs.lensel[m][1], 0x71, 0, rd->ptbm[3]) ^ stk) /* mid */ + i = tek_rdget1(rd, rd->probs.pb[s_pos].lenmid[m], 0x73, 1, rd->ptbm[5]); + else { + /* high */ + i = tek_rdget1(rd, rd->probs.lenhigh[m], 0x78, 1, rd->ptbm[6]) - (256 + 256 - 8); + if (i > 0) { + if (i < 6 && stk == 0) + i = tek_rdget1(rd, &rd->probs.lenext[(1 << i) - 2], i | 0x70, 1, rd->ptbm[7]) - 1; + else + i = tek_rdget0(rd, i, ~1) - 1; + i = tek_rdget0(rd, i, ~1) - 1; + } + i += 256 - 8 + 16; + } + return i; +} + +static int tek_decmain5(int *work, UCHAR *src, int osiz, UCHAR *q, int lc, int pb, int lp, int flags) +{ + static int state_table[] = { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 }; + int i, j, k, pmch, rep[4], s, pos, m_pos = (1 << pb) - 1, m_lp = (1 << lp) - 1; + int stk = (flags == -1), lcr = 8 - lc, s_pos, lit0cntmsk = 0x78; + UINT32 *lit1; + struct tek_STR_RNGDEC *rd = (struct tek_STR_RNGDEC *) work; + struct tek_STR_PRB *prb = &rd->probs; + + rd->p = &src[4]; + rd->range |= -1; + rd->code = src[0] << 24 | src[1] << 16 | src[2] << 8 | src[3]; + for (i = 0; i < 4; i++) + rep[i] = ~i; + if (setjmp(rd->errjmp)) + goto err; + for (i = sizeof (struct tek_STR_PRB) / sizeof (tek_TPRB) + (0x300 << (lc + lp)) - 2; i >= 0; i--) + ((tek_TPRB *) prb)[i] = 1 << 15; + for (i = 0; i < 32; i++) { + rd->bm[i].lt = (i >= 4); + rd->bm[i].lt0 = (i < 24) ? 16 * 1024 : 8 * 1024; + rd->bm[i].s &= 0; + rd->bm[i].t = rd->bm[i].m = 5; + } + lit1 = prb->lit + ((256 << (lc + lp)) - 2); + if (stk) { + rd->rmsk = -1 << 11; + for (i = 0; i < 32; i++) + rd->bm[i].lt = 0; + for (i = 0; i < 14; i++) + rd->ptbm[i] = &rd->bm[0]; + } else { + UCHAR pt[14]; + static UCHAR pt1[14] = { + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 18, 18, 18, 8 + }; + static UCHAR pt2[14] = { + 8, 8, 10, 11, 12, 12, 14, 15, + 16, 16, 18, 18, 20, 21 + }; + /* + 0- 7:mch, mch, lit1, lensel, lenlow, lenmid, lenhigh, lenext + 8-15:pslot, pslot, sdis, sdis, align, rep-repg2 + */ + rd->rmsk |= -1; + rd->bm[1].t = 5; rd->bm[1].m = 3; /* for fchgprm */ + rd->bm[2].t = 9; rd->bm[2].m = 2; /* for tbmt, tbmm */ + if (flags & 0x40) { /* lt-flag */ + rd->bm[3].t = 0; rd->bm[3].m = 1; + prb->fchglt = 0xffff; + } + rd->bm[22].t = 0; rd->bm[22].m = 1; + prb->repg3 = 0xffff; + if (flags == -2) { /* z1 */ + rd->bm[22].lt = 0; + for (i = 0; i < 14; i++) + pt[i] = pt1[i]; + } else { + for (i = 0; i < 14; i++) + pt[i] = pt2[i]; + lit0cntmsk = (7 >> (flags & 3)) << 4 | 8; + pt[ 1] = 8 + ((flags & 0x04) != 0); /* mch */ + pt[ 5] = 12 + ((flags & 0x08) != 0); /* llm */ + pt[ 9] = 16 + ((flags & 0x10) != 0); /* pst */ + pt[11] = 18 + ((flags & 0x20) != 0); /* sds */ + } + for (i = 0; i < 14; i++) + rd->ptbm[i] = &rd->bm[pt[i]]; + } + for (i = 0; i < 32; i++) + tek_setbm5(&rd->bm[i], rd->bm[i].t, rd->bm[i].m); + + if ((tek_rdget1(rd, &prb->pb[0].st[0].mch, 0x71, 0, rd->ptbm[0]) ^ stk) == 0) + goto err; + *q++ = tek_rdget1(rd, prb->lit, lit0cntmsk, 1, &rd->bm[24]) & 0xff; + pmch &= 0; s &= 0; pos = 1; + while (pos < osiz) { + s_pos = pos & m_pos; + if (tek_rdget1(rd, &prb->pb[s_pos].st[s].mch, 0x71, 0, rd->ptbm[s > 0]) ^ stk) { + i = (q[-1] >> lcr | (pos & m_lp) << lc) << 8; + s = state_table[s]; + if (pmch == 0) + *q = tek_rdget1(rd, &prb->lit[i], lit0cntmsk, 1, &rd->bm[24]) & 0xff; + else { + struct tek_STR_BITMODEL *bm = &rd->bm[24]; + j = 1; + k = 8; + pmch = q[rep[0]]; + do { + j += j + tek_rdget1(rd, &lit1[(i + j) << 1 | pmch >> 7], 0x71, 0, rd->ptbm[2]); + k--; + if ((k & (lit0cntmsk >> 4)) == 0) + bm++; + if ((((pmch >> 7) ^ j) & 1) != 0 && k != 0) { + j = tek_rdget1(rd, &prb->lit[i + j - 1], k | (lit0cntmsk & 0x70), j, bm); + break; + } + pmch <<= 1; + } while (k); + *q = j & 0xff; + pmch &= 0; + } + pos++; + q++; + } else { /* lz */ + pmch |= 1; + if (tek_rdget1(rd, &prb->st[s].rep, 0x71, 0, rd->ptbm[13]) ^ stk) { /* len/dis */ + rep[3] = rep[2]; + rep[2] = rep[1]; + rep[1] = rep[0]; + j = i = tek_getlen5(rd, 0, s_pos, stk); + s = s < 7 ? 7 : 10; + if (j >= 4) + j = 3; + rep[0] = j = tek_rdget1(rd, prb->pslot[j], 0x76, 1, rd->ptbm[8 + (j == 3)]) & 0x3f; + if (j >= 4) { + k = (j >> 1) - 1; /* k = [1, 30] */ + rep[0] = (2 | (j & 1)) << k; + if (j < 14) /* k < 6 */ + rep[0] |= tek_revbit(tek_rdget1(rd, &prb->spdis[j & 1][(1 << k) - 2], k | 0x70, 1, rd->ptbm[10 + (k >= 4)]), k); + else { + if (stk == 0) { + if (k -= 6) + rep[0] |= tek_rdget0(rd, k, ~0) << 6; + rep[0] |= tek_revbit(tek_rdget1(rd, prb->algn, 0x76, 1, rd->ptbm[12]), 6); + } else { + rep[0] |= tek_rdget0(rd, k - 4, ~0) << 4; + rep[0] |= tek_revbit(tek_rdget1(rd, prb->algn, 0x74, 1, rd->ptbm[12]), 4); + } + } + } + rep[0] = ~rep[0]; + } else { /* repeat-dis */ + if (tek_rdget1(rd, &prb->st[s].repg0, 0x71, 0, rd->ptbm[13]) ^ stk) { /* rep0 */ + i |= -1; + if (tek_rdget1(rd, &prb->pb[s_pos].st[s].rep0l1, 0x71, 0, rd->ptbm[13]) == 0) { + s = s < 7 ? 9 : 11; + goto skip; + } + } else { + if (tek_rdget1(rd, &prb->st[s].repg1, 0x71, 0, rd->ptbm[13]) ^ stk) /* rep1 */ + i = rep[1]; + else { + if (tek_rdget1(rd, &prb->st[s].repg2, 0x71, 0, rd->ptbm[13]) ^ stk) /* rep2 */ + i = rep[2]; + else { + if (stk == 0) { + if (tek_rdget1(rd, &prb->repg3, 0x71, 0, &rd->bm[22]) == 0) + goto err; + } + i = rep[3]; /* rep3 */ + rep[3] = rep[2]; + } + rep[2] = rep[1]; + } + rep[1] = rep[0]; + rep[0] = i; + } + i = tek_getlen5(rd, 1, s_pos, stk); + s = s < 7 ? 8 : 11; + } +skip: + i += 2; + if (pos + rep[0] < 0) + goto err; + if (pos + i > osiz) + i = osiz - pos; + pos += i; + do { + *q = q[rep[0]]; + q++; + } while (--i); + } + } + return 0; +err: + return 1; +} + +static int tek_decode5(int siz, UCHAR *p, UCHAR *q) +{ + UCHAR *p1 = p + siz; + int dsiz, hed, bsiz, st = 0; + p += 16; + if ((dsiz = tek_getnum_s7s(&p)) > 0) { + hed = tek_getnum_s7s(&p); + if ((hed & 1) == 0) + st = tek_lzrestore_tek5(p1 - p + 1, p - 1, dsiz, q); + else { + bsiz = 1 << (((hed >> 1) & 0x0f) + 8); + if (hed & 0x20) + return 1; + if (bsiz == 256) + st = tek_lzrestore_tek5(p1 - p, p, dsiz, q); + else { + if (dsiz > bsiz) + return 1; + if (hed & 0x40) + tek_getnum_s7s(&p); + st = tek_lzrestore_tek5(p1 - p, p, dsiz, q); + } + } + } + return st; +} diff --git a/29_day/winhelo/Makefile b/29_day/winhelo/Makefile index 44ac359..91d9264 100644 --- a/29_day/winhelo/Makefile +++ b/29_day/winhelo/Makefile @@ -3,3 +3,7 @@ STACK = 8k MALLOC = 0k include ../app_make.txt + +$(APP).hrb : $(APP).org Makefile + $(COPY) $(APP).org $(APP).hrb + \ No newline at end of file