OSDN Git Service

デバッグを試みた。
[heavyosecpu/HeavyOSECPU.git] / tek.c
1 #include "tek.h"
2
3 static unsigned int tek_getnum_s7s(UCHAR **pp);
4 /*
5 // not used.
6 static int tek_lzrestore_stk1(int srcsiz, UCHAR *src, int outsiz, UCHAR *q);
7 static int tek_decode1(int siz, UCHAR *p, UCHAR *q);
8 static unsigned int tek_getnum_s7(UCHAR **pp);
9 static int tek_lzrestore_stk2(int srcsiz, UCHAR *src, int outsiz, UCHAR *q);
10 static int tek_decode2(int siz, UCHAR *p, UCHAR *q);
11  */
12 static int tek_lzrestore_tek5(int srcsiz, UCHAR *src, int outsiz, UCHAR *outbuf);
13 static void tek_setbm5(struct tek_STR_BITMODEL *bm, int t, int m);
14 static int tek_rdget0(struct tek_STR_RNGDEC *rd, int n, int i);
15 static int tek_rdget1(struct tek_STR_RNGDEC *rd, tek_TPRB *prob0, int n, int j, struct tek_STR_BITMODEL *bm);
16 static UINT32 tek_revbit(UINT32 data, int len);
17 static int tek_getlen5(struct tek_STR_RNGDEC *rd, int m, int s_pos, int stk);
18 static int tek_decmain5(int *work, UCHAR *src, int osiz, UCHAR *q, int lc, int pb, int lp, int flags);
19 static int tek_decode5(int siz, UCHAR *p, UCHAR *q);
20
21 static unsigned int tek_getnum_s7s(UCHAR **pp)
22 /* これは必ずbig-endian */
23 /* 下駄がないので中身をいじりやすい */
24 {
25         unsigned int s = 0;
26         UCHAR *p = *pp;
27         do {
28                 s = s << 7 | *p++;
29         } while ((s & 1) == 0);
30         s >>= 1;
31         *pp = p;
32         return s;
33 }
34
35 #if 0
36
37 int tek_getsize(unsigned char *p)
38 {
39         static char header[15] = {
40                 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x4f, 0x53, 0x41, 0x53, 0x4b, 0x43, 0x4d, 0x50
41         };
42         int size = -1;
43         if (memcmp(p + 1, header, 15) == 0 && (*p == 0x83 || *p == 0x85 || *p == 0x89)) {
44                 p += 16;
45                 size = tek_getnum_s7s(&p);
46         }
47         return size;
48 }         /* (註)memcmpはstrncmpの仲間で、文字列中に0があっても指定された15文字まで比較する関数 */
49
50 #endif
51
52 int tek_decomp(unsigned char *p, unsigned char *q, int size)
53 {
54         int err = -1;
55 #if 0
56         if (*p == 0x83) {
57                 err = tek_decode1(size, p, q);
58         } else if (*p == 0x85) {
59                 err = tek_decode2(size, p, q);
60         } else if (*p == 0x89) {
61                 err = tek_decode5(size, p, q);
62         }
63 #else
64         if (*p == 0x89) {
65                 err = tek_decode5(size, p, q);
66         }
67 #endif
68         if (err != 0) {
69
70                 printf("tek_decomp() serious error, err: %d\n", err);
71                 return -1;      /* 失敗 */
72         }
73         return 0;       /* 成功 */
74 }
75
76 #if 0
77
78 static int tek_lzrestore_stk1(int srcsiz, UCHAR *src, int outsiz, UCHAR *q)
79 {
80         int by, lz, cp, ds;
81         UCHAR *q1 = q + outsiz, *s7ptr = src, *q0 = q;
82         do {
83                 if ((by = (lz = *s7ptr++) & 0x0f) == 0)
84                         by = tek_getnum_s7s(&s7ptr);
85                 if ((lz >>= 4) == 0)
86                         lz = tek_getnum_s7s(&s7ptr);
87                 do {
88                         *q++ = *s7ptr++;
89                 } while (--by);
90                 if (q >= q1)
91                         break;
92                 do {
93                         ds = (cp = *s7ptr++) & 0x0f;
94                         if ((ds & 1) == 0) {
95                                 do {
96                                         ds = ds << 7 | *s7ptr++;
97                                 } while ((ds & 1) == 0);
98                         }
99                         ds = ‾(ds >> 1);
100                         if ((cp >>= 4) == 0) {
101                                 do {
102                                         cp = cp << 7 | *s7ptr++;
103                                 } while ((cp & 1) == 0);
104                                 cp >>= 1;
105                         } /* 0がこないことをあてにする */
106                         cp++;
107                         if (q + ds < q0)
108                                 goto err;
109                         if (q + cp > q1)
110                                 cp = q1 - q;
111                         do {
112                                 *q = *(q + ds);
113                                 q++;
114                         } while (--cp);
115                 } while (--lz);
116         } while (q < q1);
117         return 0;
118 err:
119         return 1;
120 }
121
122 static int tek_decode1(int siz, UCHAR *p, UCHAR *q)
123 {
124         int dsiz, hed, bsiz;
125         UCHAR *p1 = p + siz;
126         p += 16;
127         if ((dsiz = tek_getnum_s7s(&p)) > 0) {
128                 hed = tek_getnum_s7s(&p);
129                 bsiz = 1 << (((hed >> 1) & 0x0f) + 8);
130                 if (dsiz > bsiz || (hed & 0x21) != 0x01)
131                         return 1;
132                 if (hed & 0x40)
133                         tek_getnum_s7s(&p); /* オプション情報へのポインタを読み飛ばす */
134                 if (tek_getnum_s7s(&p) != 0)
135                         return 1; /* 補助バッファ使用 */
136                 return tek_lzrestore_stk1(p1 - p, p, dsiz, q);
137         }
138         return 0;
139 }
140
141 static unsigned int tek_getnum_s7(UCHAR **pp)
142 /* これは必ずbig-endian */
143 {
144         unsigned int s = 0, b = 0, a = 1;
145         UCHAR *p = *pp;
146         for (;;) {
147                 s = s << 7 | *p++;
148                 if (s & 1)
149                         break;
150                 a <<= 7;
151                 b += a;
152         }
153         s >>= 1;
154         *pp = p;
155         return s + b;
156 }
157
158 static int tek_lzrestore_stk2(int srcsiz, UCHAR *src, int outsiz, UCHAR *q)
159 {
160         int cp, ds, repdis[4], i, j;
161         UCHAR *q1 = q + outsiz, *s7ptr = src, *q0 = q, bylz, cbylz;
162         for (j = 0; j < 4; j++)
163                 repdis[j] = -1 - j;
164         bylz = cbylz = 0;
165         if (outsiz) {
166                 if (tek_getnum_s7s(&s7ptr))
167                         return 1;
168                 do {
169                         /* byフェーズ */
170                         j = 0;
171                         do {
172                                 j++;
173                                 if (j >= 17) {
174                                         j += tek_getnum_s7s(&s7ptr);
175                                         break;
176                                 }
177                                 if (cbylz == 0) {
178                                         cbylz = 8;
179                                         bylz = *s7ptr++;
180                                 }
181                                 cbylz--;
182                                 i = bylz & 1;
183                                 bylz >>= 1;
184                         } while (i == 0);
185                         do {
186                                 *q++ = *s7ptr++;
187                         } while (--j);
188                         if (q >= q1)
189                                 break;
190                         
191                         /* lzフェーズ */
192                         j = 0;
193                         do {
194                                 j++;
195                                 if (j >= 17) {
196                                         j += tek_getnum_s7s(&s7ptr);
197                                         break;
198                                 }
199                                 if (cbylz == 0) {
200                                         cbylz = 8;
201                                         bylz = *s7ptr++;
202                                 }
203                                 cbylz--;
204                                 i = bylz & 1;
205                                 bylz >>= 1;
206                         } while (i == 0);
207                         do {
208                                 i = *s7ptr++;
209                                 cp = i >> 4;
210                                 i &= 0x0f;
211                                 if ((i & 1) == 0)
212                                         i |= (tek_getnum_s7(&s7ptr) + 1) << 4;
213                                 i >>= 1;
214                                 ds = ‾(i - 6);
215                                 if (i < 4)
216                                         ds = repdis[i];
217                                 if (i == 4)
218                                         ds = repdis[0] - tek_getnum_s7(&s7ptr) - 1;
219                                 if (i == 5)
220                                         ds = repdis[0] + tek_getnum_s7(&s7ptr) + 1;
221                                 if (cp == 0)
222                                         cp = tek_getnum_s7(&s7ptr) + 16;
223                                 cp++;
224                                 if (i > 0) {
225                                         if (i > 1) {
226                                                 if (i > 2)
227                                                         repdis[3] = repdis[2];
228                                                 repdis[2] = repdis[1];
229                                         }
230                                         repdis[1] = repdis[0];
231                                         repdis[0] = ds;
232                                 }
233                                 if (q + ds < q0)
234                                         goto err;
235                                 if (q + cp > q1)
236                                         cp = q1 - q;
237                                 do {
238                                         *q = *(q + ds);
239                                         q++;
240                                 } while (--cp);
241                         } while (--j);
242                 } while (q < q1);
243         }
244         return 0;
245 err:
246         return 1;
247 }
248
249 static int tek_decode2(int siz, UCHAR *p, UCHAR *q)
250 {
251         UCHAR *p1 = p + siz;
252         int dsiz, hed, bsiz, st = 0;
253         p += 16;
254         if ((dsiz = tek_getnum_s7s(&p)) > 0) {
255                 hed = tek_getnum_s7s(&p);
256                 bsiz = 1 << (((hed >> 1) & 0x0f) + 8);
257                 if (dsiz > bsiz || (hed & 0x21) != 0x01)
258                         return 1;
259                 if (hed & 0x40)
260                         tek_getnum_s7s(&p); /* オプション情報へのポインタを読み飛ばす */
261                 st = tek_lzrestore_stk2(p1 - p, p, dsiz, q);
262         }
263         return st;
264 }
265
266 #endif
267
268 static int tek_lzrestore_tek5(int srcsiz, UCHAR *src, int outsiz, UCHAR *outbuf)
269 {
270         int wrksiz, lc, lp, pb, flags = 0, *work, prop0, fl;
271         
272         if ((fl = (prop0 = *src) & 0x0f) == 0x01) /* 0001 */
273                 flags |= -1;
274         else if (fl == 0x05)
275                 flags = -2;
276         else if (fl == 0x09)
277                 flags &= 0;
278         else
279                 return 1;
280         src++;
281         prop0 >>= 4;
282         if (prop0 == 0)
283                 prop0 = *src++;
284         else {
285                 static UCHAR prop0_table[] = { 0x5d, 0x00 }, prop1_table[] = { 0x00 };
286                 if (flags == -1) {
287                         if (prop0 >= 3)
288                                 return 1;
289                         prop0 = prop0_table[prop0 - 1];
290                 } else {
291                         if (prop0 >= 2)
292                                 return 1;
293                         prop0 = prop1_table[prop0 - 1];
294                 }
295         }
296         lp = prop0 / (9 * 5);
297         prop0 %= 9 * 5;
298         pb = prop0 / 9;
299         lc = prop0 % 9;
300         if (flags == 0) /* tek5:z2 */
301                 flags = *src++;
302         if (flags == -1) { /* stk5 */
303                 wrksiz = lp;
304                 lp = pb;
305                 pb = wrksiz;
306         }
307         wrksiz = 0x180 * sizeof (UINT32) + (0x840 + (0x300 << (lc + lp))) * sizeof (tek_TPRB); /* 最低15KB, lc+lp=3なら、36KB */
308         work = (int *) malloc(wrksiz);
309         if (work == NULL)
310                 return -1;
311         flags = tek_decmain5(work, src, outsiz, outbuf, lc, pb, lp, flags);
312         free(work);
313         return flags;
314 }
315
316 static void tek_setbm5(struct tek_STR_BITMODEL *bm, int t, int m)
317 {
318         bm->t = t;
319         bm->m = m;
320         bm->prb1 = -1 << (m + t);
321         bm->prb0 = ~bm->prb1;
322         bm->prb1 |= 1 << t;
323         bm->tmsk = (-1 << t) & 0xffff;
324         bm->prb0 &= bm->tmsk;
325         bm->prb1 &= bm->tmsk;
326         bm->ntm = ~bm->tmsk;
327         return;
328 }
329
330 static int tek_rdget0(struct tek_STR_RNGDEC *rd, int n, int i)
331 {
332         do {
333                 while (rd->range < (UINT32) (1 << 24)) {
334                         rd->range <<= 8;
335                         rd->code = rd->code << 8 | *rd->p++;
336                 }
337                 rd->range >>= 1;
338                 i += i;
339                 if (rd->code >= rd->range) {
340                         rd->code -= rd->range;
341                         i |= 1;
342                 }
343         } while (--n);
344         return ~i;
345 }
346
347 static int tek_rdget1(struct tek_STR_RNGDEC *rd, tek_TPRB *prob0, int n, int j, struct tek_STR_BITMODEL *bm)
348 {
349         UINT32 p, i, *prob, nm = n >> 4;
350         n &= 0x0f;
351         prob0 -= j;
352         do {
353                 p = *(prob = prob0 + j);
354                 if (bm->lt > 0) {
355                         if (--bm->lt == 0) {
356                                 /* 寿命切れ */
357                                 if (tek_rdget1(rd, &rd->probs.fchglt, 0x71, 0, &rd->bm[3]) == 0) {
358                                         /* 寿命変更はまだサポートしてない */
359                                         printf("Fatal: Life change is not supported. in tek_rdget1\n");
360                                         printf("  rd->range: %lu, rd->code: %lu, rd->rmsk: %lu\n", rd->range, rd->code, rd->rmsk);
361                                 err:
362                                         longjmp(rd->errjmp, 1);
363                                 }
364                                 i = bm - rd->bm;
365                                 if ((bm->s = tek_rdget1(rd, &rd->probs.fchgprm[i * 2 + bm->s], 0x71, 0, &rd->bm[1])) == 0) {
366                                         i = tek_rdget1(rd, rd->probs.tbmt, 0x74, 1, &rd->bm[2]) & 15;
367                                         if (i == 15)
368                                         {
369                                                 goto err;
370                                         }
371                                         tek_setbm5(bm, i, ((tek_rdget1(rd, rd->probs.tbmm, 0x74, 1, &rd->bm[2]) - 1) & 15) + 1);
372                                 }
373                                 bm->lt = bm->lt0;
374                         }
375                         if (p < bm->prb0) {
376                                 p = bm->prb0;
377                                 goto fixprob;
378                         }
379                         if (p > bm->prb1) {
380                                 p = bm->prb1;
381                                 goto fixprob;
382                         }
383                         if (p & bm->ntm) {
384                                 p &= bm->tmsk;
385                         fixprob:
386                                 *prob = p;
387                         }
388                 }
389                 
390                 while (rd->range < (UINT32) (1 << 24)) {
391                         rd->range <<= 8;
392                         rd->code = rd->code << 8 | *rd->p++;
393                 }
394                 j += j;
395                 i = (UINT32)((rd->range & rd->rmsk) * p) >> 16;
396                 if (rd->code < i) {
397                         j |= 1;
398                         rd->range = i;
399                         *prob += ((0x10000 - p) >> bm->m) & bm->tmsk;
400                 } else {
401                         rd->range -= i;
402                         rd->code -= i;
403                         *prob -= (p >> bm->m) & bm->tmsk;
404                 }
405                 --n;
406                 if ((n & nm) == 0)
407                         bm++;
408         } while (n);
409         return j;
410 }
411
412 static UINT32 tek_revbit(UINT32 data, int len)
413 {
414         UINT32 rev = 0;
415         do {
416                 rev += rev + (data & 1);
417                 data >>= 1;
418         } while (--len);
419         return rev;
420 }
421
422 static int tek_getlen5(struct tek_STR_RNGDEC *rd, int m, int s_pos, int stk)
423 {
424         int i;
425         if (tek_rdget1(rd, &rd->probs.lensel[m][0], 0x71, 0, rd->ptbm[3]) ^ stk) /* low */
426                 i = tek_rdget1(rd, rd->probs.pb[s_pos].lenlow[m], 0x73, 1, rd->ptbm[4]) & 7;
427         else if (tek_rdget1(rd, &rd->probs.lensel[m][1], 0x71, 0, rd->ptbm[3]) ^ stk) /* mid */
428                 i = tek_rdget1(rd, rd->probs.pb[s_pos].lenmid[m], 0x73, 1, rd->ptbm[5]);
429         else {
430                 /* high */
431                 i = tek_rdget1(rd, rd->probs.lenhigh[m], 0x78, 1, rd->ptbm[6]) - (256 + 256 - 8);
432                 if (i > 0) {
433                         if (i < 6 && stk == 0)
434                                 i = tek_rdget1(rd, &rd->probs.lenext[(1 << i) - 2], i | 0x70, 1, rd->ptbm[7]) - 1;
435                         else
436                                 i = tek_rdget0(rd, i, ~1) - 1;
437                         i = tek_rdget0(rd, i, ~1) - 1;
438                 }
439                 i += 256 - 8 + 16;
440         }
441         return i;
442 }
443
444 static int tek_decmain5(int *work, UCHAR *src, int osiz, UCHAR *q, int lc, int pb, int lp, int flags)
445 {
446         static int state_table[] = { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 };
447         int i, j, k, pmch, rep[4], s, pos, m_pos = (1 << pb) - 1, m_lp = (1 << lp) - 1;
448         int stk = (flags == -1), lcr = 8 - lc, s_pos, lit0cntmsk = 0x78;
449         UINT32 *lit1;
450         struct tek_STR_RNGDEC *rd = (struct tek_STR_RNGDEC *) work;
451         struct tek_STR_PRB *prb = &rd->probs;
452         
453         rd->p = &src[4];
454         rd->range |= -1;
455         rd->code = src[0] << 24 | src[1] << 16 | src[2] << 8 | src[3];
456         for (i = 0; i < 4; i++)
457                 rep[i] = ~i;
458         if (setjmp(rd->errjmp)) // tek_rdget1() 内でエラーが発生したときに飛んでくる
459         {
460                 goto err;
461         }
462                 
463         for (i = sizeof (struct tek_STR_PRB) / sizeof (tek_TPRB)+(0x300 << (lc + lp)) - 2; i >= 0; i--)
464         {
465                 ((tek_TPRB *) prb)[i] = 1 << 15;
466         }
467         for (i = 0; i < 32; i++) {
468                 rd->bm[i].lt = (i >= 4); /* 0..3は寿命なし */
469                 rd->bm[i].lt0 = (i < 24) ? 16 * 1024 : 8 * 1024;
470                 rd->bm[i].s &= 0;
471                 rd->bm[i].t = rd->bm[i].m = 5;
472         }
473         lit1 = prb->lit + ((256 << (lc + lp)) - 2);
474         if (stk) {
475                 rd->rmsk = -1 << 11;
476                 for (i = 0; i < 32; i++)
477                 {
478                         rd->bm[i].lt = 0; /* 全て寿命なし */
479                 }
480                 for (i = 0; i < 14; i++)
481                 {
482                         rd->ptbm[i] = &rd->bm[0];
483                 }
484         } else {
485                 UCHAR pt[14];
486                 static UCHAR pt1[14] = {
487                         8,  8,  8,  8,  8,  8,  8,  8,
488                         8,  8, 18, 18, 18,  8
489                 };
490                 static UCHAR pt2[14] = {
491                         8,  8, 10, 11, 12, 12, 14, 15,
492                         16, 16, 18, 18, 20, 21
493                 };
494                 /*
495                  0- 7:mch, mch, lit1, lensel, lenlow, lenmid, lenhigh, lenext
496                  8-15:pslot, pslot, sdis, sdis, align, rep-repg2
497                  */
498                 rd->rmsk |= -1;
499                 rd->bm[1].t = 5; rd->bm[1].m = 3; /* for fchgprm */
500                 rd->bm[2].t = 9; rd->bm[2].m = 2; /* for tbmt, tbmm */
501                 if (flags & 0x40) { /* lt-flag */
502                         rd->bm[3].t = 0; rd->bm[3].m = 1;
503                         prb->fchglt = 0xffff;
504                 }
505                 rd->bm[22].t = 0; rd->bm[22].m = 1;
506                 prb->repg3 = 0xffff;
507                 if (flags == -2) { /* z1 */
508                         rd->bm[22].lt = 0; /* repg3のltを0に */
509                         for (i = 0; i < 14; i++)
510                         {
511                                 pt[i] = pt1[i];
512                         }
513                 } else {
514                         for (i = 0; i < 14; i++)
515                         {
516                                 pt[i] = pt2[i];
517                         }
518                         lit0cntmsk = (7 >> (flags & 3)) << 4 | 8;
519                         pt[ 1] =  8 + ((flags & 0x04) != 0); /* mch */
520                         pt[ 5] = 12 + ((flags & 0x08) != 0); /* llm */
521                         pt[ 9] = 16 + ((flags & 0x10) != 0); /* pst */
522                         pt[11] = 18 + ((flags & 0x20) != 0); /* sds */
523                 }
524                 for (i = 0; i < 14; i++)
525                 {
526                         rd->ptbm[i] = &rd->bm[pt[i]];
527                 }
528         }
529         for (i = 0; i < 32; i++)
530         {
531                 tek_setbm5(&rd->bm[i], rd->bm[i].t, rd->bm[i].m);
532         }
533         
534         if ((tek_rdget1(rd, &prb->pb[0].st[0].mch, 0x71, 0, rd->ptbm[0]) ^ stk) == 0)
535         {
536                 goto err;
537         }
538                 
539         *q++ = tek_rdget1(rd, prb->lit, lit0cntmsk, 1, &rd->bm[24]) & 0xff;
540         pmch &= 0; s &= 0; pos = 1;
541         while (pos < osiz) {
542                 s_pos = pos & m_pos;
543                 if (tek_rdget1(rd, &prb->pb[s_pos].st[s].mch, 0x71, 0, rd->ptbm[s > 0]) ^ stk) { /* 非lz */
544                         i = (q[-1] >> lcr | (pos & m_lp) << lc) << 8;
545                         s = state_table[s];
546                         if (pmch == 0)
547                         {
548                                 *q = tek_rdget1(rd, &prb->lit[i], lit0cntmsk, 1, &rd->bm[24]) & 0xff;
549                         }
550                         else {
551                                 struct tek_STR_BITMODEL *bm = &rd->bm[24];
552                                 j = 1; /* lit1は最初から2を減じてある */
553                                 k = 8;
554                                 pmch = q[rep[0]];
555                                 do {
556                                         j += j + tek_rdget1(rd, &lit1[(i + j) << 1 | pmch >> 7], 0x71, 0, rd->ptbm[2]);
557                                         k--;
558                                         if ((k & (lit0cntmsk >> 4)) == 0)
559                                         {
560                                                 bm++;
561                                         }
562                                         if ((((pmch >> 7) ^ j) & 1) != 0 && k != 0) {
563                                                 j = tek_rdget1(rd, &prb->lit[i + j - 1], k | (lit0cntmsk & 0x70), j, bm);
564                                                 break;
565                                         }
566                                         pmch <<= 1;
567                                 } while (k);
568                                 *q = j & 0xff;
569                                 pmch &= 0;
570                         }
571                         pos++;
572                         q++;
573                 } else { /* lz */
574                         pmch |= 1;
575                         if (tek_rdget1(rd, &prb->st[s].rep, 0x71, 0, rd->ptbm[13]) ^ stk) { /* len/dis */
576                                 rep[3] = rep[2];
577                                 rep[2] = rep[1];
578                                 rep[1] = rep[0];
579                                 j = i = tek_getlen5(rd, 0, s_pos, stk);
580                                 s = s < 7 ? 7 : 10;
581                                 if (j >= 4) j = 3;
582                                 rep[0] = j = tek_rdget1(rd, prb->pslot[j], 0x76, 1, rd->ptbm[8 + (j == 3)]) & 0x3f;
583                                 if (j >= 4) {
584                                         k = (j >> 1) - 1; /* k = [1, 30] */
585                                         rep[0] = (2 | (j & 1)) << k;
586                                         if (j < 14){ /* k < 6 */
587                                                 rep[0] |= tek_revbit(tek_rdget1(rd, &prb->spdis[j & 1][(1 << k) - 2], k | 0x70, 1, rd->ptbm[10 + (k >= 4)]), k);
588                                         } else {
589                                                 if (stk == 0) {
590                                                         if (k -= 6)
591                                                                 rep[0] |= tek_rdget0(rd, k, ~0) << 6;
592                                                         rep[0] |= tek_revbit(tek_rdget1(rd, prb->algn, 0x76, 1, rd->ptbm[12]), 6);
593                                                 } else {
594                                                         rep[0] |= tek_rdget0(rd, k - 4, ~0) << 4;
595                                                         rep[0] |= tek_revbit(tek_rdget1(rd, prb->algn, 0x74, 1, rd->ptbm[12]), 4);
596                                                 }
597                                         }
598                                 }
599                                 rep[0] = ~rep[0];
600                         } else { /* repeat-dis */
601                                 if (tek_rdget1(rd, &prb->st[s].repg0, 0x71, 0, rd->ptbm[13]) ^ stk) { /* rep0 */
602                                         i |= -1;
603                                         if (tek_rdget1(rd, &prb->pb[s_pos].st[s].rep0l1, 0x71, 0, rd->ptbm[13]) == 0) {
604                                                 s = s < 7 ? 9 : 11;
605                                                 goto skip;
606                                         }
607                                 } else {
608                                         if (tek_rdget1(rd, &prb->st[s].repg1, 0x71, 0, rd->ptbm[13]) ^ stk){ /* rep1 */
609                                                 i = rep[1];
610                                         } else {
611                                                 if (tek_rdget1(rd, &prb->st[s].repg2, 0x71, 0, rd->ptbm[13]) ^ stk){ /* rep2 */
612                                                         i = rep[2];
613                                                 } else {
614                                                         if (stk == 0) {
615                                                                 if (tek_rdget1(rd, &prb->repg3, 0x71, 0, &rd->bm[22]) == 0)
616                                                                 {
617                                                                         goto err;
618                                                                 }
619                                                                         
620                                                         }
621                                                         i = rep[3]; /* rep3 */
622                                                         rep[3] = rep[2];
623                                                 }
624                                                 rep[2] = rep[1];
625                                         }
626                                         rep[1] = rep[0];
627                                         rep[0] = i;
628                                 }
629                                 i = tek_getlen5(rd, 1, s_pos, stk);
630                                 s = s < 7 ? 8 : 11;
631                         }
632                 skip:
633                         i += 2;
634                         if (pos + rep[0] < 0)
635                         {
636                                 goto err;
637                         }
638                                 
639                         if (pos + i > osiz) i = osiz - pos;
640                         pos += i;
641                         do {
642                                 *q = q[rep[0]];
643                                 q++;
644                         } while (--i);
645                 }
646         }
647         return 0;
648 err:
649         return 1;
650 }
651
652 static int tek_decode5(int siz, UCHAR *p, UCHAR *q)
653 {
654         UCHAR *p1 = p + siz;
655         int dsiz, hed, bsiz, st = 0;
656         p += 16;
657         if ((dsiz = tek_getnum_s7s(&p)) > 0) {
658                 hed = tek_getnum_s7s(&p);
659                 if ((hed & 1) == 0)
660                 {
661                         st = tek_lzrestore_tek5(p1 - p + 1, p - 1, dsiz, q);
662                         printf("tek_lzrestore_tek5(%d, %d, %d, %d)\n", p1 - p + 1, p - 1, dsiz, q);
663                 }
664                 else {
665                         bsiz = 1 << (((hed >> 1) & 0x0f) + 8);
666                         if (hed & 0x20)
667                                 return 1;
668                         if (bsiz == 256)
669                                 st = tek_lzrestore_tek5(p1 - p, p, dsiz, q);
670                         else {
671                                 if (dsiz > bsiz)
672                                         return 1;
673                                 if (hed & 0x40)
674                                         tek_getnum_s7s(&p); /* オプション情報へのポインタを読み飛ばす */
675                                 st = tek_lzrestore_tek5(p1 - p, p, dsiz, q);
676                         }
677                 }
678         }
679         return st;
680 }