Revisión | 31d916abdee94df48820456052b534ed7bef8f94 (tree) |
---|---|
Tiempo | 2014-03-14 22:50:06 |
Autor | ttwilb <ttwilb@user...> |
Commiter | ttwilb |
デバッグを試みた。
app0040.tekを読み込むとエラーで止まります。
tek.c:358行目のところ。
tekの仕様がわからない。
@@ -1,347 +1,343 @@ | ||
1 | -#include "osecpu.h" | |
2 | - | |
3 | -int *keybuf, keybuf_r, keybuf_w, keybuf_c; | |
4 | -HOSECPU_Device_Window mainWindow; | |
5 | -//デバッグ用。プログラム中の随所で加算される変数 | |
6 | -int di1_serial; | |
7 | - | |
8 | - | |
9 | - | |
10 | -unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory); | |
11 | -void LoadAppBin(HOSECPU_RuntimeEnvironment *env); | |
12 | - | |
13 | -void putKeybuf(int i) | |
14 | -{ | |
15 | - if (keybuf_c < KEYBUFSIZ) { | |
16 | - keybuf[keybuf_w] = i; | |
17 | - keybuf_c++; | |
18 | - keybuf_w = (keybuf_w + 1) & (KEYBUFSIZ - 1); | |
19 | - } | |
20 | - return; | |
21 | -} | |
22 | - | |
23 | -int HeavyOSECPUMain(int argc, char **argv) | |
24 | -{ | |
25 | - FILE *fp; | |
26 | - unsigned char *jitbuf, *sysjit00, *sysjit; | |
27 | - unsigned char *systmp0, *systmp1, *systmp2; | |
28 | - unsigned char *opTbl; | |
29 | - HOSECPU_LabelListTag *label; | |
30 | - int tmpsiz, i; | |
31 | - double tm0, tm1, tm2; | |
32 | - HOSECPU_PointerControlTag *ptrCtrl; | |
33 | - unsigned char *syslib; | |
34 | - int argDebug = 0, stacksiz = 1; | |
35 | - const char *cp; | |
36 | - HOSECPU_RuntimeEnvironment env; | |
37 | - void(*jitfunc)(char *); | |
38 | - unsigned char *jp; | |
39 | - | |
40 | - //Initialize mainWindow | |
41 | - mainWindow.vram = NULL; | |
42 | - mainWindow.xsize = 0; | |
43 | - mainWindow.ysize = 0; | |
44 | - di1_serial = 0; | |
45 | - | |
46 | - //実行環境初期化 | |
47 | - env.mainArgc = argc; | |
48 | - env.mainArgv = (const char **)argv; | |
49 | - env.appBin = malloc(APPSIZ1); | |
50 | - env.executionLevel = JITC_LV_SLOWEST; | |
51 | - jitbuf = mallocRWE(1024 * 1024); /* とりあえず1MBで */ | |
52 | - //unsigned char *sysjit0 = mallocRWE(SJITSIZ1), *sysjit1 = sysjit0, *sysjit00 = sysjit0; | |
53 | - // syslib.oseのjitc結果を格納する領域を確保。 | |
54 | - sysjit00 = mallocRWE(SJITSIZ1); | |
55 | - sysjit = sysjit00; | |
56 | - // 現在の、jitc結果を格納するメモリへの書き込み位置のアドレス | |
57 | - // sysjit: 現在のjitc書き込み位置 | |
58 | - // sysjit00: jitc結果の先頭 | |
59 | - //ワークメモリを三つくらいもらう | |
60 | - systmp0 = malloc(SYSTMP0SIZ); /* syslibのjitc用 */ | |
61 | - systmp1 = malloc(SYSTMP1SIZ); | |
62 | - systmp2 = malloc(1024 * 1024); | |
63 | - | |
64 | - opTbl = malloc(256); | |
65 | - label = malloc(JITC_MAXLABELS * sizeof (HOSECPU_LabelListTag)); | |
66 | - keybuf = malloc(KEYBUFSIZ * sizeof (int)); | |
67 | - keybuf_r = keybuf_w = keybuf_c = 0; | |
68 | - ptrCtrl = malloc(PTRCTRLSIZ * sizeof (HOSECPU_PointerControlTag)); | |
69 | - | |
70 | - randStatInit((unsigned int)time(NULL)); | |
71 | - for (i = 0; i < PTRCTRLSIZ; i++) { | |
72 | - ptrCtrl[i].liveSign = 0; | |
73 | - ptrCtrl[i].size = -1; | |
74 | - } | |
75 | - ptrCtrl[0].size = -2; | |
76 | - | |
77 | - /* syslibの読み込み */ | |
78 | - syslib = Init_LoadSysLib(argv[0], systmp0); | |
79 | - | |
80 | - sysjit = jitCompInit(sysjit); | |
81 | - sysjit00 = sysjit; | |
82 | - // labelはjitc0()内で初期化される。 | |
83 | - i = jitc0(&sysjit, sysjit00 + SJITSIZ1, syslib + 32, syslib + SYSLIBSIZ1, JITC_LV_SLOWEST+9, label); | |
84 | - if (i != 0){ | |
85 | - fputs("syslib-file JITC error.\n", stderr); | |
86 | - return 1; | |
87 | - } | |
88 | - | |
89 | - // エラー時にデバッグ用に表示する変数を加算 | |
90 | - di1_serial++; | |
91 | - | |
92 | - /* アプリバイナリの読み込み */ | |
93 | - LoadAppBin(&env); | |
94 | - | |
95 | - /* クロック初期化 */ | |
96 | - tm0 = clock() / (double)CLOCKS_PER_SEC; | |
97 | - | |
98 | - if (env.appBin[2] == 0xf0) { | |
99 | - // tek5圧縮がかかっている | |
100 | -#if (USE_TEK5 != 0) | |
101 | - env.appSize1 = tek5Decomp(env.appBin + 2, env.appBin + env.appSize0, systmp0); | |
102 | - if(env.appSize1 == -1){ | |
103 | - fputs("tek decomp error.\n", stderr); | |
104 | - return 1; | |
105 | - } | |
106 | - env.appSize1++; | |
107 | -#else | |
108 | - env.appSize1 = -9; | |
109 | -#endif | |
110 | - if (env.appSize1 < 0) { | |
111 | - fputs("unsupported-format(tek5)\n", stderr); | |
112 | - return 1; | |
113 | - } | |
114 | - } | |
115 | - //デバッグモード指定 | |
116 | - cp = searchArg(argc, (const char **)argv, "debug:", 0); | |
117 | - if (cp != NULL){ | |
118 | - argDebug = *cp - '0'; | |
119 | - } | |
120 | - //スタックサイズ指定(MiB単位) | |
121 | - cp = searchArg(argc, (const char **)argv, "stack:", 0); | |
122 | - if (cp != NULL){ | |
123 | - stacksiz = strtol(cp, NULL, 0); | |
124 | - } | |
125 | - | |
126 | - // jitbufは先頭。 jpは現在位置 | |
127 | - jp = jitbuf; /* JIT-pointer */ | |
128 | - | |
129 | - /* フロントエンドコードをバックエンドコードに変換する */ | |
130 | - if ((env.appBin[2] & 0xf0) != 0) { // 3バイト目が00なら処理しない | |
131 | - systmp0[0] = env.appBin[0]; | |
132 | - systmp0[1] = env.appBin[1]; | |
133 | - env.preg[2].p = systmp0 + 2; | |
134 | - env.preg[3].p = systmp0 + SYSTMP0SIZ; | |
135 | - env.preg[4].p = env.appBin + 2; | |
136 | - env.preg[5].p = env.appBin + env.appSize1; | |
137 | - env.preg[6].p = systmp1; | |
138 | - env.preg[7].p = systmp1 + SYSTMP1SIZ; | |
139 | - env.preg[10].p = systmp2; | |
140 | - int pxxFlag[64], typLabel[4096]; | |
141 | - env.preg[0x0b].p = (void *)pxxFlag; | |
142 | - env.preg[0x0c].p = (void *)typLabel; | |
143 | - env.preg[0x0d].p = opTbl; | |
144 | - jitfunc = (void *)sysjit00; | |
145 | - (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */ | |
146 | - if (env.ireg[0] != 0) { | |
147 | - jp = env.preg[2].p - 1; | |
148 | - fprintf(stderr, "unpack error: %02X (at %06X) (R00=%d)\n", *jp, jp - systmp0, env.ireg[0]); | |
149 | - if ((argDebug & 2) != 0) { | |
150 | - fp = fopen("debug2.bin", "wb"); | |
151 | - fwrite(systmp0, 1, jp - systmp0 + 16, fp); | |
152 | - fclose(fp); | |
153 | - } | |
154 | - exit(1); | |
155 | - } | |
156 | - tmpsiz = env.preg[2].p - systmp0; | |
157 | - } else{ | |
158 | - memcpy(systmp0, env.appBin, env.appSize1); | |
159 | - tmpsiz = env.appSize1; | |
160 | - } | |
161 | - | |
162 | - if ((argDebug & 2) != 0) { | |
163 | - /*変換後のバックエンドコードをファイルへ保存*/ | |
164 | - fp = fopen("debug2.bin", "wb"); | |
165 | - fwrite(systmp0, 1, tmpsiz, fp); | |
166 | - fclose(fp); | |
167 | - } | |
168 | - | |
169 | - //JITコンパイル | |
170 | - i = jitc0(&jp, jitbuf + 1024 * 1024, systmp0, systmp0 + tmpsiz, env.executionLevel, label); | |
171 | - if (i == 1){ | |
172 | - fputs("app-file header error.\n", stderr); | |
173 | - return 1; | |
174 | - } | |
175 | - if (i != 0){ | |
176 | - return 1; | |
177 | - } | |
178 | - di1_serial++; | |
179 | - | |
180 | - int appsiz2 = jp - jitbuf; | |
181 | - | |
182 | - unsigned char *p28 = jp; | |
183 | - jp = jitCompCallFunc(jp, &devFunc); | |
184 | - | |
185 | - tm1 = clock() / (double)CLOCKS_PER_SEC; | |
186 | - | |
187 | - /* レジスタ初期化 */ | |
188 | - for (i = 0; i < 64; i++){ | |
189 | - env.ireg[i] = 0; | |
190 | - } | |
191 | - for (i = 0; i < 64; i++) { | |
192 | - env.preg[i].p = NULL; | |
193 | - env.preg[i].typ = -1; | |
194 | - env.preg[i].p0 = NULL; | |
195 | - env.preg[i].p1 = NULL; | |
196 | - } | |
197 | - | |
198 | - env.buf0 = env.buf1 = NULL; | |
199 | - | |
200 | - // p28にapiをコールするアドレスを設定 | |
201 | - env.preg[0x28].p = p28; // p28には、devFuncをコールするコードが書かれている | |
202 | - env.preg[0x28].typ = 0; // TYP_CODE | |
203 | - env.preg[0x28].p0 = p28; // アドレス演算できる範囲を制限 | |
204 | - env.preg[0x28].p1 = p28 + 1; // アドレス演算できる範囲を制限 | |
205 | - | |
206 | - //env.preg[0x00].p = malloc(1024 * 1024) + (1024 * 1024 - 32); | |
207 | - env.junkStack = malloc(stacksiz << 20); | |
208 | - env.junkStack1 = env.junkStack + (stacksiz << 20); | |
209 | - env.winClosed = 0; | |
210 | - env.autoSleep = 0; | |
211 | - env.lastConsoleChar = '\n'; | |
212 | - | |
213 | - env.label = label; | |
214 | - env.maxLabels = JITC_MAXLABELS; | |
215 | - env.jitbuf = jp; | |
216 | - env.jitbuf1 = jitbuf + 1024 * 1024; | |
217 | - env.errHndl = &errorHandler; | |
218 | - env.appReturnCode = 0; | |
219 | - | |
220 | - env.dbgr = 0; | |
221 | - if (searchArg(argc, (const char **)argv, "dbgr:1", 0) != NULL){ | |
222 | - env.dbgr = 1; | |
223 | - } | |
224 | - | |
225 | - if ((argDebug & 1) != 0) { | |
226 | - fp = fopen("debug1.bin", "wb"); | |
227 | - fwrite(jitbuf, 1, jp - jitbuf, fp); | |
228 | - fclose(fp); | |
229 | - } | |
230 | - | |
231 | - /* JITコード実行 */ | |
232 | - jitfunc = (void *)jitbuf; | |
233 | - if (setjmp(env.setjmpEnv) == 0){ | |
234 | - (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */ | |
235 | - } | |
236 | - if (env.autoSleep != 0) { | |
237 | - if (mainWindow.vram != NULL){ | |
238 | - drv_flshWin(mainWindow.xsize, mainWindow.ysize, 0, 0); | |
239 | - } | |
240 | - while (env.winClosed == 0){ | |
241 | - drv_sleep(100); | |
242 | - } | |
243 | - } | |
244 | - if (env.lastConsoleChar != '\n'){ | |
245 | - putchar('\n'); | |
246 | - } | |
247 | - | |
248 | - tm2 = clock() / (double)CLOCKS_PER_SEC; | |
249 | - | |
250 | - /* 実行結果確認のためのレジスタダンプ */ | |
251 | - if (searchArg(argc, (const char **)argv, "verbose:1", 0) != NULL) { | |
252 | - printf("time: JITC=%.3f[sec], exec=%.3f[sec]\n", tm1 - tm0, tm2 - tm1); | |
253 | - printf("size: OSECPU=%d, decomp=%d, tmp=%d, native=%d\n", env.appSize0, env.appSize1, tmpsiz, appsiz2); | |
254 | - printf("result:\n"); | |
255 | - printf("R00:0x%08X R01:0x%08X R02:0x%08X R03:0x%08X\n", env.ireg[0], env.ireg[1], env.ireg[2], env.ireg[3]); | |
256 | - } | |
257 | -#if (USE_DEBUGGER != 0) | |
258 | - dbgrMain(&env); | |
259 | -#endif | |
260 | - return env.appReturnCode; | |
261 | -} | |
262 | - | |
263 | -unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory) | |
264 | -{ | |
265 | - unsigned char *syslib; | |
266 | - FILE *fp; | |
267 | - unsigned char *up; | |
268 | - int appsize; | |
269 | - | |
270 | - /* syslibの読み込み */ | |
271 | - syslib = malloc(SYSLIBSIZ1); | |
272 | - fp = fopen(SYSLIB_OSE, "rb"); | |
273 | - if (fp == NULL) { | |
274 | - syslib[0] = '/'; | |
275 | - strcpy((char *)syslib + 1, argv0); | |
276 | - up = syslib + 1; | |
277 | - while (*up != '\0'){ | |
278 | - up++; | |
279 | - } | |
280 | - while (*up != '/' && *up != 0x5c){ | |
281 | - up--; | |
282 | - } | |
283 | - up++; | |
284 | - strcpy((char *)up, SYSLIB_OSE); | |
285 | - fp = fopen((char *)syslib + 1, "rb"); | |
286 | - } | |
287 | - if (fp == NULL) { | |
288 | - fputs("syslib-file fopen error.\n", stderr); | |
289 | - exit(EXIT_FAILURE); | |
290 | - } | |
291 | - appsize = fread(syslib, 1, SYSLIBSIZ1 - 4, fp); | |
292 | - fclose(fp); | |
293 | - if (appsize >= SYSLIBSIZ1 - 4) { | |
294 | - fputs("syslib-file too large.\n", stderr); | |
295 | - exit(EXIT_FAILURE); | |
296 | - } | |
297 | - if (syslib[0] == 0x05 && syslib[1] == 0xc1) { | |
298 | - // maklib のライブラリ形式である。 | |
299 | - memcpy(tmpWorkMemory, syslib, appsize); | |
300 | - ComLib_main(tmpWorkMemory + 2, syslib + 2); | |
301 | - syslib[0] = 0x05; | |
302 | - syslib[1] = 0x1b; | |
303 | - } | |
304 | - | |
305 | - fp = fopen("syslib_dbg.ose", "wb"); | |
306 | - fwrite(syslib, 1, SYSLIBSIZ1, fp); | |
307 | - fclose(fp); | |
308 | - return syslib; | |
309 | -} | |
310 | - | |
311 | -void LoadAppBin(HOSECPU_RuntimeEnvironment *env) | |
312 | -{ | |
313 | - FILE *fp; | |
314 | - const char *fileName; | |
315 | - /* アプリバイナリの読み込み */ | |
316 | - if (env->mainArgc <= 1) { | |
317 | - //アプリ名未指定なので何事もなく終了 | |
318 | - exit(EXIT_SUCCESS); | |
319 | - } | |
320 | - fileName = env->mainArgv[1]; | |
321 | - //アプリ名先頭に:n:をつけることでレベルnでの実行が可能? | |
322 | - if (fileName[0] == ':' && fileName[2] == ':') { | |
323 | - env->executionLevel = fileName[1] - '0'; | |
324 | - if (env->executionLevel < 0 || env->executionLevel > 9){ | |
325 | - env->executionLevel = JITC_LV_SLOWEST; | |
326 | - } | |
327 | - fileName += 3; | |
328 | - } | |
329 | - | |
330 | - fp = fopen(fileName, "rb"); | |
331 | - if (fp == NULL) { | |
332 | - fputs("app-file load error.\n", stderr); | |
333 | - exit(EXIT_FAILURE); | |
334 | - } | |
335 | - env->appSize0 = fread(env->appBin, 1, APPSIZ1 - 4, fp); | |
336 | - env->appSize1 = env->appSize0; | |
337 | - fclose(fp); | |
338 | - | |
339 | - if (env->appSize0 >= APPSIZ1 - 4) { | |
340 | - fputs("app-file too large.\n", stderr); | |
341 | - exit(EXIT_FAILURE); | |
342 | - } | |
343 | - if (env->appSize0 < 3) { | |
344 | - fputs("app-file header error.\n", stderr); | |
345 | - exit(EXIT_FAILURE); | |
346 | - } | |
347 | -} | |
1 | +#include "osecpu.h" | |
2 | + | |
3 | +int *keybuf, keybuf_r, keybuf_w, keybuf_c; | |
4 | +HOSECPU_Device_Window mainWindow; | |
5 | +//デバッグ用。プログラム中の随所で加算される変数 | |
6 | +int di1_serial; | |
7 | + | |
8 | + | |
9 | + | |
10 | +unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory); | |
11 | +void LoadAppBin(HOSECPU_RuntimeEnvironment *env); | |
12 | + | |
13 | +void putKeybuf(int i) | |
14 | +{ | |
15 | + if (keybuf_c < KEYBUFSIZ) { | |
16 | + keybuf[keybuf_w] = i; | |
17 | + keybuf_c++; | |
18 | + keybuf_w = (keybuf_w + 1) & (KEYBUFSIZ - 1); | |
19 | + } | |
20 | + return; | |
21 | +} | |
22 | + | |
23 | +int HeavyOSECPUMain(int argc, char **argv) | |
24 | +{ | |
25 | + FILE *fp; | |
26 | + unsigned char *jitbuf, *sysjit00, *sysjit; | |
27 | + unsigned char *systmp0, *systmp1, *systmp2; | |
28 | + unsigned char *opTbl; | |
29 | + HOSECPU_LabelListTag *label; | |
30 | + int tmpsiz, i; | |
31 | + double tm0, tm1, tm2; | |
32 | + HOSECPU_PointerControlTag *ptrCtrl; | |
33 | + unsigned char *syslib; | |
34 | + int argDebug = 0, stacksiz = 1; | |
35 | + const char *cp; | |
36 | + HOSECPU_RuntimeEnvironment env; | |
37 | + void(*jitfunc)(char *); | |
38 | + unsigned char *jp; | |
39 | + | |
40 | + //Initialize mainWindow | |
41 | + mainWindow.vram = NULL; | |
42 | + mainWindow.xsize = 0; | |
43 | + mainWindow.ysize = 0; | |
44 | + di1_serial = 0; | |
45 | + | |
46 | + //実行環境初期化 | |
47 | + env.mainArgc = argc; | |
48 | + env.mainArgv = (const char **)argv; | |
49 | + env.appBin = malloc(APPSIZ1); | |
50 | + env.executionLevel = JITC_LV_SLOWEST; | |
51 | + jitbuf = mallocRWE(1024 * 1024); /* とりあえず1MBで */ | |
52 | + //unsigned char *sysjit0 = mallocRWE(SJITSIZ1), *sysjit1 = sysjit0, *sysjit00 = sysjit0; | |
53 | + // syslib.oseのjitc結果を格納する領域を確保。 | |
54 | + sysjit00 = mallocRWE(SJITSIZ1); | |
55 | + sysjit = sysjit00; | |
56 | + // 現在の、jitc結果を格納するメモリへの書き込み位置のアドレス | |
57 | + // sysjit: 現在のjitc書き込み位置 | |
58 | + // sysjit00: jitc結果の先頭 | |
59 | + //ワークメモリを三つくらいもらう | |
60 | + systmp0 = malloc(SYSTMP0SIZ); /* syslibのjitc用 */ | |
61 | + systmp1 = malloc(SYSTMP1SIZ); | |
62 | + systmp2 = malloc(1024 * 1024); | |
63 | + | |
64 | + opTbl = malloc(256); | |
65 | + label = malloc(JITC_MAXLABELS * sizeof (HOSECPU_LabelListTag)); | |
66 | + keybuf = malloc(KEYBUFSIZ * sizeof (int)); | |
67 | + keybuf_r = keybuf_w = keybuf_c = 0; | |
68 | + ptrCtrl = malloc(PTRCTRLSIZ * sizeof (HOSECPU_PointerControlTag)); | |
69 | + | |
70 | + randStatInit((unsigned int)time(NULL)); | |
71 | + for (i = 0; i < PTRCTRLSIZ; i++) { | |
72 | + ptrCtrl[i].liveSign = 0; | |
73 | + ptrCtrl[i].size = -1; | |
74 | + } | |
75 | + ptrCtrl[0].size = -2; | |
76 | + | |
77 | + /* syslibの読み込み */ | |
78 | + syslib = Init_LoadSysLib(argv[0], systmp0); | |
79 | + | |
80 | + sysjit = jitCompInit(sysjit); | |
81 | + sysjit00 = sysjit; | |
82 | + // labelはjitc0()内で初期化される。 | |
83 | + i = jitc0(&sysjit, sysjit00 + SJITSIZ1, syslib + 32, syslib + SYSLIBSIZ1, JITC_LV_SLOWEST+9, label); | |
84 | + if (i != 0){ | |
85 | + fputs("syslib-file JITC error.\n", stderr); | |
86 | + return 1; | |
87 | + } | |
88 | + | |
89 | + // エラー時にデバッグ用に表示する変数を加算 | |
90 | + di1_serial++; | |
91 | + | |
92 | + /* アプリバイナリの読み込み */ | |
93 | + LoadAppBin(&env); | |
94 | + | |
95 | + /* クロック初期化 */ | |
96 | + tm0 = clock() / (double)CLOCKS_PER_SEC; | |
97 | + | |
98 | + if (env.appBin[2] == 0xf0) { | |
99 | + // tek5圧縮がかかっている | |
100 | +#if (USE_TEK5 != 0) | |
101 | + env.appSize1 = tek5Decomp(env.appBin + 2, env.appBin + env.appSize0, systmp0); // 始めの2byte はOSECPUのシグネチャ(05 E1)だからとばす | |
102 | + env.appSize1 += 2; | |
103 | +#else | |
104 | + env.appSize1 = -9; | |
105 | +#endif | |
106 | + if (env.appSize1 < 0) { | |
107 | + fputs("unsupported-format(tek5)\n", stderr); | |
108 | + return 1; | |
109 | + } | |
110 | + } | |
111 | + //デバッグモード指定 | |
112 | + cp = searchArg(argc, (const char **)argv, "debug:", 0); | |
113 | + if (cp != NULL){ | |
114 | + argDebug = *cp - '0'; | |
115 | + } | |
116 | + //スタックサイズ指定(MiB単位) | |
117 | + cp = searchArg(argc, (const char **)argv, "stack:", 0); | |
118 | + if (cp != NULL){ | |
119 | + stacksiz = strtol(cp, NULL, 0); | |
120 | + } | |
121 | + | |
122 | + // jitbufは先頭。 jpは現在位置 | |
123 | + jp = jitbuf; /* JIT-pointer */ | |
124 | + | |
125 | + /* フロントエンドコードをバックエンドコードに変換する */ | |
126 | + if ((env.appBin[2] & 0xf0) != 0) { // 3バイト目が00なら処理しない | |
127 | + systmp0[0] = env.appBin[0]; | |
128 | + systmp0[1] = env.appBin[1]; | |
129 | + env.preg[2].p = systmp0 + 2; | |
130 | + env.preg[3].p = systmp0 + SYSTMP0SIZ; | |
131 | + env.preg[4].p = env.appBin + 2; | |
132 | + env.preg[5].p = env.appBin + env.appSize1; | |
133 | + env.preg[6].p = systmp1; | |
134 | + env.preg[7].p = systmp1 + SYSTMP1SIZ; | |
135 | + env.preg[10].p = systmp2; | |
136 | + int pxxFlag[64], typLabel[4096]; | |
137 | + env.preg[0x0b].p = (void *)pxxFlag; | |
138 | + env.preg[0x0c].p = (void *)typLabel; | |
139 | + env.preg[0x0d].p = opTbl; | |
140 | + jitfunc = (void *)sysjit00; | |
141 | + (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */ | |
142 | + if (env.ireg[0] != 0) { | |
143 | + jp = env.preg[2].p - 1; | |
144 | + fprintf(stderr, "unpack error: %02X (at %06X) (R00=%d)\n", *jp, jp - systmp0, env.ireg[0]); | |
145 | + if ((argDebug & 2) != 0) { | |
146 | + fp = fopen("debug2.bin", "wb"); | |
147 | + fwrite(systmp0, 1, jp - systmp0 + 16, fp); | |
148 | + fclose(fp); | |
149 | + } | |
150 | + exit(1); | |
151 | + } | |
152 | + tmpsiz = env.preg[2].p - systmp0; | |
153 | + } else{ | |
154 | + memcpy(systmp0, env.appBin, env.appSize1); | |
155 | + tmpsiz = env.appSize1; | |
156 | + } | |
157 | + | |
158 | + if ((argDebug & 2) != 0) { | |
159 | + /*変換後のバックエンドコードをファイルへ保存*/ | |
160 | + fp = fopen("debug2.bin", "wb"); | |
161 | + fwrite(systmp0, 1, tmpsiz, fp); | |
162 | + fclose(fp); | |
163 | + } | |
164 | + | |
165 | + //JITコンパイル | |
166 | + i = jitc0(&jp, jitbuf + 1024 * 1024, systmp0, systmp0 + tmpsiz, env.executionLevel, label); | |
167 | + if (i == 1){ | |
168 | + fputs("app-file header error.\n", stderr); | |
169 | + return 1; | |
170 | + } | |
171 | + if (i != 0){ | |
172 | + return 1; | |
173 | + } | |
174 | + di1_serial++; | |
175 | + | |
176 | + int appsiz2 = jp - jitbuf; | |
177 | + | |
178 | + unsigned char *p28 = jp; | |
179 | + jp = jitCompCallFunc(jp, &devFunc); | |
180 | + | |
181 | + tm1 = clock() / (double)CLOCKS_PER_SEC; | |
182 | + | |
183 | + /* レジスタ初期化 */ | |
184 | + for (i = 0; i < 64; i++){ | |
185 | + env.ireg[i] = 0; | |
186 | + } | |
187 | + for (i = 0; i < 64; i++) { | |
188 | + env.preg[i].p = NULL; | |
189 | + env.preg[i].typ = -1; | |
190 | + env.preg[i].p0 = NULL; | |
191 | + env.preg[i].p1 = NULL; | |
192 | + } | |
193 | + | |
194 | + env.buf0 = env.buf1 = NULL; | |
195 | + | |
196 | + // p28にapiをコールするアドレスを設定 | |
197 | + env.preg[0x28].p = p28; // p28には、devFuncをコールするコードが書かれている | |
198 | + env.preg[0x28].typ = 0; // TYP_CODE | |
199 | + env.preg[0x28].p0 = p28; // アドレス演算できる範囲を制限 | |
200 | + env.preg[0x28].p1 = p28 + 1; // アドレス演算できる範囲を制限 | |
201 | + | |
202 | + //env.preg[0x00].p = malloc(1024 * 1024) + (1024 * 1024 - 32); | |
203 | + env.junkStack = malloc(stacksiz << 20); | |
204 | + env.junkStack1 = env.junkStack + (stacksiz << 20); | |
205 | + env.winClosed = 0; | |
206 | + env.autoSleep = 0; | |
207 | + env.lastConsoleChar = '\n'; | |
208 | + | |
209 | + env.label = label; | |
210 | + env.maxLabels = JITC_MAXLABELS; | |
211 | + env.jitbuf = jp; | |
212 | + env.jitbuf1 = jitbuf + 1024 * 1024; | |
213 | + env.errHndl = &errorHandler; | |
214 | + env.appReturnCode = 0; | |
215 | + | |
216 | + env.dbgr = 0; | |
217 | + if (searchArg(argc, (const char **)argv, "dbgr:1", 0) != NULL){ | |
218 | + env.dbgr = 1; | |
219 | + } | |
220 | + | |
221 | + if ((argDebug & 1) != 0) { | |
222 | + fp = fopen("debug1.bin", "wb"); | |
223 | + fwrite(jitbuf, 1, jp - jitbuf, fp); | |
224 | + fclose(fp); | |
225 | + } | |
226 | + | |
227 | + /* JITコード実行 */ | |
228 | + jitfunc = (void *)jitbuf; | |
229 | + if (setjmp(env.setjmpEnv) == 0){ | |
230 | + (*jitfunc)(((char *)&env) + 128); /* サイズを節約するためにEBPを128バイトずらす */ | |
231 | + } | |
232 | + if (env.autoSleep != 0) { | |
233 | + if (mainWindow.vram != NULL){ | |
234 | + drv_flshWin(mainWindow.xsize, mainWindow.ysize, 0, 0); | |
235 | + } | |
236 | + while (env.winClosed == 0){ | |
237 | + drv_sleep(100); | |
238 | + } | |
239 | + } | |
240 | + if (env.lastConsoleChar != '\n'){ | |
241 | + putchar('\n'); | |
242 | + } | |
243 | + | |
244 | + tm2 = clock() / (double)CLOCKS_PER_SEC; | |
245 | + | |
246 | + /* 実行結果確認のためのレジスタダンプ */ | |
247 | + if (searchArg(argc, (const char **)argv, "verbose:1", 0) != NULL) { | |
248 | + printf("time: JITC=%.3f[sec], exec=%.3f[sec]\n", tm1 - tm0, tm2 - tm1); | |
249 | + printf("size: OSECPU=%d, decomp=%d, tmp=%d, native=%d\n", env.appSize0, env.appSize1, tmpsiz, appsiz2); | |
250 | + printf("result:\n"); | |
251 | + printf("R00:0x%08X R01:0x%08X R02:0x%08X R03:0x%08X\n", env.ireg[0], env.ireg[1], env.ireg[2], env.ireg[3]); | |
252 | + } | |
253 | +#if (USE_DEBUGGER != 0) | |
254 | + dbgrMain(&env); | |
255 | +#endif | |
256 | + return env.appReturnCode; | |
257 | +} | |
258 | + | |
259 | +unsigned char *Init_LoadSysLib(char argv0[], unsigned char *tmpWorkMemory) | |
260 | +{ | |
261 | + unsigned char *syslib; | |
262 | + FILE *fp; | |
263 | + unsigned char *up; | |
264 | + int appsize; | |
265 | + | |
266 | + /* syslibの読み込み */ | |
267 | + syslib = malloc(SYSLIBSIZ1); | |
268 | + fp = fopen(SYSLIB_OSE, "rb"); | |
269 | + if (fp == NULL) { | |
270 | + syslib[0] = '/'; | |
271 | + strcpy((char *)syslib + 1, argv0); | |
272 | + up = syslib + 1; | |
273 | + while (*up != '\0'){ | |
274 | + up++; | |
275 | + } | |
276 | + while (*up != '/' && *up != 0x5c){ | |
277 | + up--; | |
278 | + } | |
279 | + up++; | |
280 | + strcpy((char *)up, SYSLIB_OSE); | |
281 | + fp = fopen((char *)syslib + 1, "rb"); | |
282 | + } | |
283 | + if (fp == NULL) { | |
284 | + fputs("syslib-file fopen error.\n", stderr); | |
285 | + exit(EXIT_FAILURE); | |
286 | + } | |
287 | + appsize = fread(syslib, 1, SYSLIBSIZ1 - 4, fp); | |
288 | + fclose(fp); | |
289 | + if (appsize >= SYSLIBSIZ1 - 4) { | |
290 | + fputs("syslib-file too large.\n", stderr); | |
291 | + exit(EXIT_FAILURE); | |
292 | + } | |
293 | + if (syslib[0] == 0x05 && syslib[1] == 0xc1) { | |
294 | + // maklib のライブラリ形式である。 | |
295 | + memcpy(tmpWorkMemory, syslib, appsize); | |
296 | + ComLib_main(tmpWorkMemory + 2, syslib + 2); | |
297 | + syslib[0] = 0x05; | |
298 | + syslib[1] = 0x1b; | |
299 | + } | |
300 | + | |
301 | + fp = fopen("syslib_dbg.ose", "wb"); | |
302 | + fwrite(syslib, 1, SYSLIBSIZ1, fp); | |
303 | + fclose(fp); | |
304 | + return syslib; | |
305 | +} | |
306 | + | |
307 | +void LoadAppBin(HOSECPU_RuntimeEnvironment *env) | |
308 | +{ | |
309 | + FILE *fp; | |
310 | + const char *fileName; | |
311 | + /* アプリバイナリの読み込み */ | |
312 | + if (env->mainArgc <= 1) { | |
313 | + //アプリ名未指定なので何事もなく終了 | |
314 | + exit(EXIT_SUCCESS); | |
315 | + } | |
316 | + fileName = env->mainArgv[1]; | |
317 | + //アプリ名先頭に:n:をつけることでレベルnでの実行が可能? | |
318 | + if (fileName[0] == ':' && fileName[2] == ':') { | |
319 | + env->executionLevel = fileName[1] - '0'; | |
320 | + if (env->executionLevel < 0 || env->executionLevel > 9){ | |
321 | + env->executionLevel = JITC_LV_SLOWEST; | |
322 | + } | |
323 | + fileName += 3; | |
324 | + } | |
325 | + | |
326 | + fp = fopen(fileName, "rb"); | |
327 | + if (fp == NULL) { | |
328 | + fputs("app-file load error.\n", stderr); | |
329 | + exit(EXIT_FAILURE); | |
330 | + } | |
331 | + env->appSize0 = fread(env->appBin, 1, APPSIZ1 - 4, fp); | |
332 | + env->appSize1 = env->appSize0; | |
333 | + fclose(fp); | |
334 | + | |
335 | + if (env->appSize0 >= APPSIZ1 - 4) { | |
336 | + fputs("app-file too large.\n", stderr); | |
337 | + exit(EXIT_FAILURE); | |
338 | + } | |
339 | + if (env->appSize0 < 3) { // 本来はここで 05 E1もチェックすべきでは? | |
340 | + fputs("app-file header error.\n", stderr); | |
341 | + exit(EXIT_FAILURE); | |
342 | + } | |
343 | +} |
@@ -1,643 +1,680 @@ | ||
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 | - return -1; /* 失敗 */ | |
70 | - } | |
71 | - return 0; /* 成功 */ | |
72 | -} | |
73 | - | |
74 | -#if 0 | |
75 | - | |
76 | -static int tek_lzrestore_stk1(int srcsiz, UCHAR *src, int outsiz, UCHAR *q) | |
77 | -{ | |
78 | - int by, lz, cp, ds; | |
79 | - UCHAR *q1 = q + outsiz, *s7ptr = src, *q0 = q; | |
80 | - do { | |
81 | - if ((by = (lz = *s7ptr++) & 0x0f) == 0) | |
82 | - by = tek_getnum_s7s(&s7ptr); | |
83 | - if ((lz >>= 4) == 0) | |
84 | - lz = tek_getnum_s7s(&s7ptr); | |
85 | - do { | |
86 | - *q++ = *s7ptr++; | |
87 | - } while (--by); | |
88 | - if (q >= q1) | |
89 | - break; | |
90 | - do { | |
91 | - ds = (cp = *s7ptr++) & 0x0f; | |
92 | - if ((ds & 1) == 0) { | |
93 | - do { | |
94 | - ds = ds << 7 | *s7ptr++; | |
95 | - } while ((ds & 1) == 0); | |
96 | - } | |
97 | - ds = ‾(ds >> 1); | |
98 | - if ((cp >>= 4) == 0) { | |
99 | - do { | |
100 | - cp = cp << 7 | *s7ptr++; | |
101 | - } while ((cp & 1) == 0); | |
102 | - cp >>= 1; | |
103 | - } /* 0がこないことをあてにする */ | |
104 | - cp++; | |
105 | - if (q + ds < q0) | |
106 | - goto err; | |
107 | - if (q + cp > q1) | |
108 | - cp = q1 - q; | |
109 | - do { | |
110 | - *q = *(q + ds); | |
111 | - q++; | |
112 | - } while (--cp); | |
113 | - } while (--lz); | |
114 | - } while (q < q1); | |
115 | - return 0; | |
116 | -err: | |
117 | - return 1; | |
118 | -} | |
119 | - | |
120 | -static int tek_decode1(int siz, UCHAR *p, UCHAR *q) | |
121 | -{ | |
122 | - int dsiz, hed, bsiz; | |
123 | - UCHAR *p1 = p + siz; | |
124 | - p += 16; | |
125 | - if ((dsiz = tek_getnum_s7s(&p)) > 0) { | |
126 | - hed = tek_getnum_s7s(&p); | |
127 | - bsiz = 1 << (((hed >> 1) & 0x0f) + 8); | |
128 | - if (dsiz > bsiz || (hed & 0x21) != 0x01) | |
129 | - return 1; | |
130 | - if (hed & 0x40) | |
131 | - tek_getnum_s7s(&p); /* オプション情報へのポインタを読み飛ばす */ | |
132 | - if (tek_getnum_s7s(&p) != 0) | |
133 | - return 1; /* 補助バッファ使用 */ | |
134 | - return tek_lzrestore_stk1(p1 - p, p, dsiz, q); | |
135 | - } | |
136 | - return 0; | |
137 | -} | |
138 | - | |
139 | -static unsigned int tek_getnum_s7(UCHAR **pp) | |
140 | -/* これは必ずbig-endian */ | |
141 | -{ | |
142 | - unsigned int s = 0, b = 0, a = 1; | |
143 | - UCHAR *p = *pp; | |
144 | - for (;;) { | |
145 | - s = s << 7 | *p++; | |
146 | - if (s & 1) | |
147 | - break; | |
148 | - a <<= 7; | |
149 | - b += a; | |
150 | - } | |
151 | - s >>= 1; | |
152 | - *pp = p; | |
153 | - return s + b; | |
154 | -} | |
155 | - | |
156 | -static int tek_lzrestore_stk2(int srcsiz, UCHAR *src, int outsiz, UCHAR *q) | |
157 | -{ | |
158 | - int cp, ds, repdis[4], i, j; | |
159 | - UCHAR *q1 = q + outsiz, *s7ptr = src, *q0 = q, bylz, cbylz; | |
160 | - for (j = 0; j < 4; j++) | |
161 | - repdis[j] = -1 - j; | |
162 | - bylz = cbylz = 0; | |
163 | - if (outsiz) { | |
164 | - if (tek_getnum_s7s(&s7ptr)) | |
165 | - return 1; | |
166 | - do { | |
167 | - /* byフェーズ */ | |
168 | - j = 0; | |
169 | - do { | |
170 | - j++; | |
171 | - if (j >= 17) { | |
172 | - j += tek_getnum_s7s(&s7ptr); | |
173 | - break; | |
174 | - } | |
175 | - if (cbylz == 0) { | |
176 | - cbylz = 8; | |
177 | - bylz = *s7ptr++; | |
178 | - } | |
179 | - cbylz--; | |
180 | - i = bylz & 1; | |
181 | - bylz >>= 1; | |
182 | - } while (i == 0); | |
183 | - do { | |
184 | - *q++ = *s7ptr++; | |
185 | - } while (--j); | |
186 | - if (q >= q1) | |
187 | - break; | |
188 | - | |
189 | - /* lzフェーズ */ | |
190 | - j = 0; | |
191 | - do { | |
192 | - j++; | |
193 | - if (j >= 17) { | |
194 | - j += tek_getnum_s7s(&s7ptr); | |
195 | - break; | |
196 | - } | |
197 | - if (cbylz == 0) { | |
198 | - cbylz = 8; | |
199 | - bylz = *s7ptr++; | |
200 | - } | |
201 | - cbylz--; | |
202 | - i = bylz & 1; | |
203 | - bylz >>= 1; | |
204 | - } while (i == 0); | |
205 | - do { | |
206 | - i = *s7ptr++; | |
207 | - cp = i >> 4; | |
208 | - i &= 0x0f; | |
209 | - if ((i & 1) == 0) | |
210 | - i |= (tek_getnum_s7(&s7ptr) + 1) << 4; | |
211 | - i >>= 1; | |
212 | - ds = ‾(i - 6); | |
213 | - if (i < 4) | |
214 | - ds = repdis[i]; | |
215 | - if (i == 4) | |
216 | - ds = repdis[0] - tek_getnum_s7(&s7ptr) - 1; | |
217 | - if (i == 5) | |
218 | - ds = repdis[0] + tek_getnum_s7(&s7ptr) + 1; | |
219 | - if (cp == 0) | |
220 | - cp = tek_getnum_s7(&s7ptr) + 16; | |
221 | - cp++; | |
222 | - if (i > 0) { | |
223 | - if (i > 1) { | |
224 | - if (i > 2) | |
225 | - repdis[3] = repdis[2]; | |
226 | - repdis[2] = repdis[1]; | |
227 | - } | |
228 | - repdis[1] = repdis[0]; | |
229 | - repdis[0] = ds; | |
230 | - } | |
231 | - if (q + ds < q0) | |
232 | - goto err; | |
233 | - if (q + cp > q1) | |
234 | - cp = q1 - q; | |
235 | - do { | |
236 | - *q = *(q + ds); | |
237 | - q++; | |
238 | - } while (--cp); | |
239 | - } while (--j); | |
240 | - } while (q < q1); | |
241 | - } | |
242 | - return 0; | |
243 | -err: | |
244 | - return 1; | |
245 | -} | |
246 | - | |
247 | -static int tek_decode2(int siz, UCHAR *p, UCHAR *q) | |
248 | -{ | |
249 | - UCHAR *p1 = p + siz; | |
250 | - int dsiz, hed, bsiz, st = 0; | |
251 | - p += 16; | |
252 | - if ((dsiz = tek_getnum_s7s(&p)) > 0) { | |
253 | - hed = tek_getnum_s7s(&p); | |
254 | - bsiz = 1 << (((hed >> 1) & 0x0f) + 8); | |
255 | - if (dsiz > bsiz || (hed & 0x21) != 0x01) | |
256 | - return 1; | |
257 | - if (hed & 0x40) | |
258 | - tek_getnum_s7s(&p); /* オプション情報へのポインタを読み飛ばす */ | |
259 | - st = tek_lzrestore_stk2(p1 - p, p, dsiz, q); | |
260 | - } | |
261 | - return st; | |
262 | -} | |
263 | - | |
264 | -#endif | |
265 | - | |
266 | -static int tek_lzrestore_tek5(int srcsiz, UCHAR *src, int outsiz, UCHAR *outbuf) | |
267 | -{ | |
268 | - int wrksiz, lc, lp, pb, flags = 0, *work, prop0, fl; | |
269 | - | |
270 | - if ((fl = (prop0 = *src) & 0x0f) == 0x01) /* 0001 */ | |
271 | - flags |= -1; | |
272 | - else if (fl == 0x05) | |
273 | - flags = -2; | |
274 | - else if (fl == 0x09) | |
275 | - flags &= 0; | |
276 | - else | |
277 | - return 1; | |
278 | - src++; | |
279 | - prop0 >>= 4; | |
280 | - if (prop0 == 0) | |
281 | - prop0 = *src++; | |
282 | - else { | |
283 | - static UCHAR prop0_table[] = { 0x5d, 0x00 }, prop1_table[] = { 0x00 }; | |
284 | - if (flags == -1) { | |
285 | - if (prop0 >= 3) | |
286 | - return 1; | |
287 | - prop0 = prop0_table[prop0 - 1]; | |
288 | - } else { | |
289 | - if (prop0 >= 2) | |
290 | - return 1; | |
291 | - prop0 = prop1_table[prop0 - 1]; | |
292 | - } | |
293 | - } | |
294 | - lp = prop0 / (9 * 5); | |
295 | - prop0 %= 9 * 5; | |
296 | - pb = prop0 / 9; | |
297 | - lc = prop0 % 9; | |
298 | - if (flags == 0) /* tek5:z2 */ | |
299 | - flags = *src++; | |
300 | - if (flags == -1) { /* stk5 */ | |
301 | - wrksiz = lp; | |
302 | - lp = pb; | |
303 | - pb = wrksiz; | |
304 | - } | |
305 | - wrksiz = 0x180 * sizeof (UINT32) + (0x840 + (0x300 << (lc + lp))) * sizeof (tek_TPRB); /* 最低15KB, lc+lp=3なら、36KB */ | |
306 | - work = (int *) malloc(wrksiz); | |
307 | - if (work == NULL) | |
308 | - return -1; | |
309 | - flags = tek_decmain5(work, src, outsiz, outbuf, lc, pb, lp, flags); | |
310 | - free(work); | |
311 | - return flags; | |
312 | -} | |
313 | - | |
314 | -static void tek_setbm5(struct tek_STR_BITMODEL *bm, int t, int m) | |
315 | -{ | |
316 | - bm->t = t; | |
317 | - bm->m = m; | |
318 | - bm->prb1 = -1 << (m + t); | |
319 | - bm->prb0 = ~bm->prb1; | |
320 | - bm->prb1 |= 1 << t; | |
321 | - bm->tmsk = (-1 << t) & 0xffff; | |
322 | - bm->prb0 &= bm->tmsk; | |
323 | - bm->prb1 &= bm->tmsk; | |
324 | - bm->ntm = ~bm->tmsk; | |
325 | - return; | |
326 | -} | |
327 | - | |
328 | -static int tek_rdget0(struct tek_STR_RNGDEC *rd, int n, int i) | |
329 | -{ | |
330 | - do { | |
331 | - while (rd->range < (UINT32) (1 << 24)) { | |
332 | - rd->range <<= 8; | |
333 | - rd->code = rd->code << 8 | *rd->p++; | |
334 | - } | |
335 | - rd->range >>= 1; | |
336 | - i += i; | |
337 | - if (rd->code >= rd->range) { | |
338 | - rd->code -= rd->range; | |
339 | - i |= 1; | |
340 | - } | |
341 | - } while (--n); | |
342 | - return ~i; | |
343 | -} | |
344 | - | |
345 | -static int tek_rdget1(struct tek_STR_RNGDEC *rd, tek_TPRB *prob0, int n, int j, struct tek_STR_BITMODEL *bm) | |
346 | -{ | |
347 | - UINT32 p, i, *prob, nm = n >> 4; | |
348 | - n &= 0x0f; | |
349 | - prob0 -= j; | |
350 | - do { | |
351 | - p = *(prob = prob0 + j); | |
352 | - if (bm->lt > 0) { | |
353 | - if (--bm->lt == 0) { | |
354 | - /* 寿命切れ */ | |
355 | - if (tek_rdget1(rd, &rd->probs.fchglt, 0x71, 0, &rd->bm[3]) == 0) { | |
356 | - /* 寿命変更はまだサポートしてない */ | |
357 | - err: | |
358 | - longjmp(rd->errjmp, 1); | |
359 | - } | |
360 | - i = bm - rd->bm; | |
361 | - if ((bm->s = tek_rdget1(rd, &rd->probs.fchgprm[i * 2 + bm->s], 0x71, 0, &rd->bm[1])) == 0) { | |
362 | - i = tek_rdget1(rd, rd->probs.tbmt, 0x74, 1, &rd->bm[2]) & 15; | |
363 | - if (i == 15) | |
364 | - goto err; | |
365 | - tek_setbm5(bm, i, ((tek_rdget1(rd, rd->probs.tbmm, 0x74, 1, &rd->bm[2]) - 1) & 15) + 1); | |
366 | - } | |
367 | - bm->lt = bm->lt0; | |
368 | - } | |
369 | - if (p < bm->prb0) { | |
370 | - p = bm->prb0; | |
371 | - goto fixprob; | |
372 | - } | |
373 | - if (p > bm->prb1) { | |
374 | - p = bm->prb1; | |
375 | - goto fixprob; | |
376 | - } | |
377 | - if (p & bm->ntm) { | |
378 | - p &= bm->tmsk; | |
379 | - fixprob: | |
380 | - *prob = p; | |
381 | - } | |
382 | - } | |
383 | - | |
384 | - while (rd->range < (UINT32) (1 << 24)) { | |
385 | - rd->range <<= 8; | |
386 | - rd->code = rd->code << 8 | *rd->p++; | |
387 | - } | |
388 | - j += j; | |
389 | - i = (UINT32)((rd->range & rd->rmsk) * p) >> 16; | |
390 | - if (rd->code < i) { | |
391 | - j |= 1; | |
392 | - rd->range = i; | |
393 | - *prob += ((0x10000 - p) >> bm->m) & bm->tmsk; | |
394 | - } else { | |
395 | - rd->range -= i; | |
396 | - rd->code -= i; | |
397 | - *prob -= (p >> bm->m) & bm->tmsk; | |
398 | - } | |
399 | - --n; | |
400 | - if ((n & nm) == 0) | |
401 | - bm++; | |
402 | - } while (n); | |
403 | - return j; | |
404 | -} | |
405 | - | |
406 | -static UINT32 tek_revbit(UINT32 data, int len) | |
407 | -{ | |
408 | - UINT32 rev = 0; | |
409 | - do { | |
410 | - rev += rev + (data & 1); | |
411 | - data >>= 1; | |
412 | - } while (--len); | |
413 | - return rev; | |
414 | -} | |
415 | - | |
416 | -static int tek_getlen5(struct tek_STR_RNGDEC *rd, int m, int s_pos, int stk) | |
417 | -{ | |
418 | - int i; | |
419 | - if (tek_rdget1(rd, &rd->probs.lensel[m][0], 0x71, 0, rd->ptbm[3]) ^ stk) /* low */ | |
420 | - i = tek_rdget1(rd, rd->probs.pb[s_pos].lenlow[m], 0x73, 1, rd->ptbm[4]) & 7; | |
421 | - else if (tek_rdget1(rd, &rd->probs.lensel[m][1], 0x71, 0, rd->ptbm[3]) ^ stk) /* mid */ | |
422 | - i = tek_rdget1(rd, rd->probs.pb[s_pos].lenmid[m], 0x73, 1, rd->ptbm[5]); | |
423 | - else { | |
424 | - /* high */ | |
425 | - i = tek_rdget1(rd, rd->probs.lenhigh[m], 0x78, 1, rd->ptbm[6]) - (256 + 256 - 8); | |
426 | - if (i > 0) { | |
427 | - if (i < 6 && stk == 0) | |
428 | - i = tek_rdget1(rd, &rd->probs.lenext[(1 << i) - 2], i | 0x70, 1, rd->ptbm[7]) - 1; | |
429 | - else | |
430 | - i = tek_rdget0(rd, i, ~1) - 1; | |
431 | - i = tek_rdget0(rd, i, ~1) - 1; | |
432 | - } | |
433 | - i += 256 - 8 + 16; | |
434 | - } | |
435 | - return i; | |
436 | -} | |
437 | - | |
438 | -static int tek_decmain5(int *work, UCHAR *src, int osiz, UCHAR *q, int lc, int pb, int lp, int flags) | |
439 | -{ | |
440 | - static int state_table[] = { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 }; | |
441 | - int i, j, k, pmch, rep[4], s, pos, m_pos = (1 << pb) - 1, m_lp = (1 << lp) - 1; | |
442 | - int stk = (flags == -1), lcr = 8 - lc, s_pos, lit0cntmsk = 0x78; | |
443 | - UINT32 *lit1; | |
444 | - struct tek_STR_RNGDEC *rd = (struct tek_STR_RNGDEC *) work; | |
445 | - struct tek_STR_PRB *prb = &rd->probs; | |
446 | - | |
447 | - rd->p = &src[4]; | |
448 | - rd->range |= -1; | |
449 | - rd->code = src[0] << 24 | src[1] << 16 | src[2] << 8 | src[3]; | |
450 | - for (i = 0; i < 4; i++) | |
451 | - rep[i] = ~i; | |
452 | - if (setjmp(rd->errjmp)) | |
453 | - goto err; | |
454 | - for (i = sizeof (struct tek_STR_PRB) / sizeof (tek_TPRB) + (0x300 << (lc + lp)) - 2; i >= 0; i--) | |
455 | - ((tek_TPRB *) prb)[i] = 1 << 15; | |
456 | - for (i = 0; i < 32; i++) { | |
457 | - rd->bm[i].lt = (i >= 4); /* 0..3は寿命なし */ | |
458 | - rd->bm[i].lt0 = (i < 24) ? 16 * 1024 : 8 * 1024; | |
459 | - rd->bm[i].s &= 0; | |
460 | - rd->bm[i].t = rd->bm[i].m = 5; | |
461 | - } | |
462 | - lit1 = prb->lit + ((256 << (lc + lp)) - 2); | |
463 | - if (stk) { | |
464 | - rd->rmsk = -1 << 11; | |
465 | - for (i = 0; i < 32; i++) | |
466 | - rd->bm[i].lt = 0; /* 全て寿命なし */ | |
467 | - for (i = 0; i < 14; i++) | |
468 | - rd->ptbm[i] = &rd->bm[0]; | |
469 | - } else { | |
470 | - UCHAR pt[14]; | |
471 | - static UCHAR pt1[14] = { | |
472 | - 8, 8, 8, 8, 8, 8, 8, 8, | |
473 | - 8, 8, 18, 18, 18, 8 | |
474 | - }; | |
475 | - static UCHAR pt2[14] = { | |
476 | - 8, 8, 10, 11, 12, 12, 14, 15, | |
477 | - 16, 16, 18, 18, 20, 21 | |
478 | - }; | |
479 | - /* | |
480 | - 0- 7:mch, mch, lit1, lensel, lenlow, lenmid, lenhigh, lenext | |
481 | - 8-15:pslot, pslot, sdis, sdis, align, rep-repg2 | |
482 | - */ | |
483 | - rd->rmsk |= -1; | |
484 | - rd->bm[1].t = 5; rd->bm[1].m = 3; /* for fchgprm */ | |
485 | - rd->bm[2].t = 9; rd->bm[2].m = 2; /* for tbmt, tbmm */ | |
486 | - if (flags & 0x40) { /* lt-flag */ | |
487 | - rd->bm[3].t = 0; rd->bm[3].m = 1; | |
488 | - prb->fchglt = 0xffff; | |
489 | - } | |
490 | - rd->bm[22].t = 0; rd->bm[22].m = 1; | |
491 | - prb->repg3 = 0xffff; | |
492 | - if (flags == -2) { /* z1 */ | |
493 | - rd->bm[22].lt = 0; /* repg3のltを0に */ | |
494 | - for (i = 0; i < 14; i++) | |
495 | - pt[i] = pt1[i]; | |
496 | - } else { | |
497 | - for (i = 0; i < 14; i++) | |
498 | - pt[i] = pt2[i]; | |
499 | - lit0cntmsk = (7 >> (flags & 3)) << 4 | 8; | |
500 | - pt[ 1] = 8 + ((flags & 0x04) != 0); /* mch */ | |
501 | - pt[ 5] = 12 + ((flags & 0x08) != 0); /* llm */ | |
502 | - pt[ 9] = 16 + ((flags & 0x10) != 0); /* pst */ | |
503 | - pt[11] = 18 + ((flags & 0x20) != 0); /* sds */ | |
504 | - } | |
505 | - for (i = 0; i < 14; i++) | |
506 | - rd->ptbm[i] = &rd->bm[pt[i]]; | |
507 | - } | |
508 | - for (i = 0; i < 32; i++) | |
509 | - tek_setbm5(&rd->bm[i], rd->bm[i].t, rd->bm[i].m); | |
510 | - | |
511 | - if ((tek_rdget1(rd, &prb->pb[0].st[0].mch, 0x71, 0, rd->ptbm[0]) ^ stk) == 0) | |
512 | - goto err; | |
513 | - *q++ = tek_rdget1(rd, prb->lit, lit0cntmsk, 1, &rd->bm[24]) & 0xff; | |
514 | - pmch &= 0; s &= 0; pos = 1; | |
515 | - while (pos < osiz) { | |
516 | - s_pos = pos & m_pos; | |
517 | - if (tek_rdget1(rd, &prb->pb[s_pos].st[s].mch, 0x71, 0, rd->ptbm[s > 0]) ^ stk) { /* 非lz */ | |
518 | - i = (q[-1] >> lcr | (pos & m_lp) << lc) << 8; | |
519 | - s = state_table[s]; | |
520 | - if (pmch == 0) | |
521 | - *q = tek_rdget1(rd, &prb->lit[i], lit0cntmsk, 1, &rd->bm[24]) & 0xff; | |
522 | - else { | |
523 | - struct tek_STR_BITMODEL *bm = &rd->bm[24]; | |
524 | - j = 1; /* lit1は最初から2を減じてある */ | |
525 | - k = 8; | |
526 | - pmch = q[rep[0]]; | |
527 | - do { | |
528 | - j += j + tek_rdget1(rd, &lit1[(i + j) << 1 | pmch >> 7], 0x71, 0, rd->ptbm[2]); | |
529 | - k--; | |
530 | - if ((k & (lit0cntmsk >> 4)) == 0) | |
531 | - bm++; | |
532 | - if ((((pmch >> 7) ^ j) & 1) != 0 && k != 0) { | |
533 | - j = tek_rdget1(rd, &prb->lit[i + j - 1], k | (lit0cntmsk & 0x70), j, bm); | |
534 | - break; | |
535 | - } | |
536 | - pmch <<= 1; | |
537 | - } while (k); | |
538 | - *q = j & 0xff; | |
539 | - pmch &= 0; | |
540 | - } | |
541 | - pos++; | |
542 | - q++; | |
543 | - } else { /* lz */ | |
544 | - pmch |= 1; | |
545 | - if (tek_rdget1(rd, &prb->st[s].rep, 0x71, 0, rd->ptbm[13]) ^ stk) { /* len/dis */ | |
546 | - rep[3] = rep[2]; | |
547 | - rep[2] = rep[1]; | |
548 | - rep[1] = rep[0]; | |
549 | - j = i = tek_getlen5(rd, 0, s_pos, stk); | |
550 | - s = s < 7 ? 7 : 10; | |
551 | - if (j >= 4) | |
552 | - j = 3; | |
553 | - rep[0] = j = tek_rdget1(rd, prb->pslot[j], 0x76, 1, rd->ptbm[8 + (j == 3)]) & 0x3f; | |
554 | - if (j >= 4) { | |
555 | - k = (j >> 1) - 1; /* k = [1, 30] */ | |
556 | - rep[0] = (2 | (j & 1)) << k; | |
557 | - if (j < 14) /* k < 6 */ | |
558 | - rep[0] |= tek_revbit(tek_rdget1(rd, &prb->spdis[j & 1][(1 << k) - 2], k | 0x70, 1, rd->ptbm[10 + (k >= 4)]), k); | |
559 | - else { | |
560 | - if (stk == 0) { | |
561 | - if (k -= 6) | |
562 | - rep[0] |= tek_rdget0(rd, k, ~0) << 6; | |
563 | - rep[0] |= tek_revbit(tek_rdget1(rd, prb->algn, 0x76, 1, rd->ptbm[12]), 6); | |
564 | - } else { | |
565 | - rep[0] |= tek_rdget0(rd, k - 4, ~0) << 4; | |
566 | - rep[0] |= tek_revbit(tek_rdget1(rd, prb->algn, 0x74, 1, rd->ptbm[12]), 4); | |
567 | - } | |
568 | - } | |
569 | - } | |
570 | - rep[0] = ~rep[0]; | |
571 | - } else { /* repeat-dis */ | |
572 | - if (tek_rdget1(rd, &prb->st[s].repg0, 0x71, 0, rd->ptbm[13]) ^ stk) { /* rep0 */ | |
573 | - i |= -1; | |
574 | - if (tek_rdget1(rd, &prb->pb[s_pos].st[s].rep0l1, 0x71, 0, rd->ptbm[13]) == 0) { | |
575 | - s = s < 7 ? 9 : 11; | |
576 | - goto skip; | |
577 | - } | |
578 | - } else { | |
579 | - if (tek_rdget1(rd, &prb->st[s].repg1, 0x71, 0, rd->ptbm[13]) ^ stk) /* rep1 */ | |
580 | - i = rep[1]; | |
581 | - else { | |
582 | - if (tek_rdget1(rd, &prb->st[s].repg2, 0x71, 0, rd->ptbm[13]) ^ stk) /* rep2 */ | |
583 | - i = rep[2]; | |
584 | - else { | |
585 | - if (stk == 0) { | |
586 | - if (tek_rdget1(rd, &prb->repg3, 0x71, 0, &rd->bm[22]) == 0) | |
587 | - goto err; | |
588 | - } | |
589 | - i = rep[3]; /* rep3 */ | |
590 | - rep[3] = rep[2]; | |
591 | - } | |
592 | - rep[2] = rep[1]; | |
593 | - } | |
594 | - rep[1] = rep[0]; | |
595 | - rep[0] = i; | |
596 | - } | |
597 | - i = tek_getlen5(rd, 1, s_pos, stk); | |
598 | - s = s < 7 ? 8 : 11; | |
599 | - } | |
600 | - skip: | |
601 | - i += 2; | |
602 | - if (pos + rep[0] < 0) | |
603 | - goto err; | |
604 | - if (pos + i > osiz) | |
605 | - i = osiz - pos; | |
606 | - pos += i; | |
607 | - do { | |
608 | - *q = q[rep[0]]; | |
609 | - q++; | |
610 | - } while (--i); | |
611 | - } | |
612 | - } | |
613 | - return 0; | |
614 | -err: | |
615 | - return 1; | |
616 | -} | |
617 | - | |
618 | -static int tek_decode5(int siz, UCHAR *p, UCHAR *q) | |
619 | -{ | |
620 | - UCHAR *p1 = p + siz; | |
621 | - int dsiz, hed, bsiz, st = 0; | |
622 | - p += 16; | |
623 | - if ((dsiz = tek_getnum_s7s(&p)) > 0) { | |
624 | - hed = tek_getnum_s7s(&p); | |
625 | - if ((hed & 1) == 0) | |
626 | - st = tek_lzrestore_tek5(p1 - p + 1, p - 1, dsiz, q); | |
627 | - else { | |
628 | - bsiz = 1 << (((hed >> 1) & 0x0f) + 8); | |
629 | - if (hed & 0x20) | |
630 | - return 1; | |
631 | - if (bsiz == 256) | |
632 | - st = tek_lzrestore_tek5(p1 - p, p, dsiz, q); | |
633 | - else { | |
634 | - if (dsiz > bsiz) | |
635 | - return 1; | |
636 | - if (hed & 0x40) | |
637 | - tek_getnum_s7s(&p); /* オプション情報へのポインタを読み飛ばす */ | |
638 | - st = tek_lzrestore_tek5(p1 - p, p, dsiz, q); | |
639 | - } | |
640 | - } | |
641 | - } | |
642 | - return st; | |
643 | -} | |
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 | +} |
@@ -1,53 +1,54 @@ | ||
1 | -// | |
2 | -// tek.h | |
3 | -// HeavyOSECPU | |
4 | -// | |
5 | -// Created by 西田 耀 on 2014/03/13. | |
6 | -// Copyright (c) 2014年 CHNOSProject. All rights reserved. | |
7 | -// | |
8 | - | |
9 | -#ifndef HeavyOSECPU_tek_h | |
10 | -#define HeavyOSECPU_tek_h | |
11 | - | |
12 | -#include "stdio.h" | |
13 | -#include "stdlib.h" | |
14 | -#include "setjmp.h" | |
15 | - | |
16 | -typedef unsigned char UCHAR; | |
17 | -typedef unsigned int UINT32; | |
18 | -typedef UINT32 tek_TPRB; | |
19 | - | |
20 | -struct tek_STR_BITMODEL { | |
21 | - UCHAR t, m, s, dmy; | |
22 | - UINT32 prb0, prb1, tmsk, ntm, lt, lt0, dmy4; | |
23 | -}; | |
24 | - | |
25 | -struct tek_STR_PRB { | |
26 | - struct tek_STR_PRB_PB { | |
27 | - struct tek_STR_PRB_PBST { | |
28 | - tek_TPRB mch, rep0l1; | |
29 | - } st[12]; | |
30 | - tek_TPRB lenlow[2][8], lenmid[2][8]; | |
31 | - } pb[16]; | |
32 | - struct tek_STR_PRB_ST { | |
33 | - tek_TPRB rep, repg0, repg1, repg2; | |
34 | - } st[12]; | |
35 | - tek_TPRB lensel[2][2], lenhigh[2][256], pslot[4][64], algn[64]; | |
36 | - tek_TPRB spdis[2][2+4+8+16+32], lenext[2+4+8+16+32]; | |
37 | - tek_TPRB repg3, fchgprm[2 * 32], tbmt[16], tbmm[16], fchglt; | |
38 | - tek_TPRB lit[1]; | |
39 | -}; | |
40 | - | |
41 | -struct tek_STR_RNGDEC { | |
42 | - UCHAR *p; | |
43 | - UINT32 range, code, rmsk; | |
44 | - jmp_buf errjmp; | |
45 | - struct tek_STR_BITMODEL bm[32], *ptbm[16]; | |
46 | - struct tek_STR_PRB probs; | |
47 | -}; | |
48 | - | |
49 | - | |
50 | -int tek_getsize(unsigned char *p); | |
51 | -int tek_decomp(unsigned char *p, unsigned char *q, int size); | |
52 | - | |
53 | -#endif | |
1 | +// | |
2 | +// tek.h | |
3 | +// HeavyOSECPU | |
4 | +// | |
5 | +// Created by 西田 耀 on 2014/03/13. | |
6 | +// Changed by ttwilb up to now. | |
7 | +// Copyright (c) 2014年 CHNOSProject. All rights reserved.(GPL) | |
8 | +// | |
9 | + | |
10 | +#ifndef HeavyOSECPU_tek_h | |
11 | +#define HeavyOSECPU_tek_h | |
12 | + | |
13 | +#include "stdio.h" | |
14 | +#include "stdlib.h" | |
15 | +#include "setjmp.h" | |
16 | + | |
17 | +typedef unsigned char UCHAR; | |
18 | +typedef unsigned int UINT32; | |
19 | +typedef UINT32 tek_TPRB; | |
20 | + | |
21 | +struct tek_STR_BITMODEL { | |
22 | + UCHAR t, m, s, dmy; | |
23 | + UINT32 prb0, prb1, tmsk, ntm, lt, lt0, dmy4; | |
24 | +}; | |
25 | + | |
26 | +struct tek_STR_PRB { | |
27 | + struct tek_STR_PRB_PB { | |
28 | + struct tek_STR_PRB_PBST { | |
29 | + tek_TPRB mch, rep0l1; | |
30 | + } st[12]; | |
31 | + tek_TPRB lenlow[2][8], lenmid[2][8]; | |
32 | + } pb[16]; | |
33 | + struct tek_STR_PRB_ST { | |
34 | + tek_TPRB rep, repg0, repg1, repg2; | |
35 | + } st[12]; | |
36 | + tek_TPRB lensel[2][2], lenhigh[2][256], pslot[4][64], algn[64]; | |
37 | + tek_TPRB spdis[2][2+4+8+16+32], lenext[2+4+8+16+32]; | |
38 | + tek_TPRB repg3, fchgprm[2 * 32], tbmt[16], tbmm[16], fchglt; | |
39 | + tek_TPRB lit[1]; | |
40 | +}; | |
41 | + | |
42 | +struct tek_STR_RNGDEC { | |
43 | + UCHAR *p; | |
44 | + UINT32 range, code, rmsk; | |
45 | + jmp_buf errjmp; | |
46 | + struct tek_STR_BITMODEL bm[32], *ptbm[16]; | |
47 | + struct tek_STR_PRB probs; | |
48 | +}; | |
49 | + | |
50 | + | |
51 | +int tek_getsize(unsigned char *p); | |
52 | +int tek_decomp(unsigned char *p, unsigned char *q, int size); | |
53 | + | |
54 | +#endif |
@@ -1,86 +1,88 @@ | ||
1 | - | |
2 | -#include "osecpu.h" | |
3 | -#if (USE_TEK5 != 0) | |
4 | -/*----For using tek Begin----*/ | |
5 | -#include "tek.h" | |
6 | - | |
7 | -int appackSub2(const UCHAR **pp, char *pif) | |
8 | -{ | |
9 | - int r = 0; | |
10 | - const UCHAR *p = *pp; | |
11 | - if (*pif == 0) { | |
12 | - r = *p >> 4; | |
13 | - } else { | |
14 | - r = *p & 0x0f; | |
15 | - p++; | |
16 | - *pp = p; | |
17 | - } | |
18 | - *pif ^= 1; | |
19 | - return r; | |
20 | -} | |
21 | - | |
22 | -int appackSub3u(const UCHAR **pp, char *pif) | |
23 | -{ | |
24 | - int r = 0, i; | |
25 | - | |
26 | - r = appackSub2(pp, pif); | |
27 | - if (0x8 <= r && r <= 0xb) { | |
28 | - r = r << 4 | appackSub2(pp, pif); | |
29 | - r &= 0x3f; | |
30 | - } else if (0xc <= r && r <= 0xd) { | |
31 | - r = r << 4 | appackSub2(pp, pif); | |
32 | - r = r << 4 | appackSub2(pp, pif); | |
33 | - r &= 0x1ff; | |
34 | - } else if (r == 0xe) { | |
35 | - r = appackSub2(pp, pif); | |
36 | - r = r << 4 | appackSub2(pp, pif); | |
37 | - r = r << 4 | appackSub2(pp, pif); | |
38 | - } else if (r == 0x7) { | |
39 | - i = appackSub3u(pp, pif); | |
40 | - r = 0; | |
41 | - while (i > 0) { | |
42 | - r = r << 4 | appackSub2(pp, pif); | |
43 | - i--; | |
44 | - } | |
45 | - } | |
46 | - | |
47 | - return r; | |
48 | -} | |
49 | - | |
50 | -int tek5Decomp(UCHAR *buf, UCHAR *buf1, UCHAR *tmp) | |
51 | -{ | |
52 | - static char tek5head[16] = { | |
53 | - 0x89, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, | |
54 | - 0x4f, 0x53, 0x41, 0x53, 0x4b, 0x43, 0x4d, 0x50 | |
55 | - }; | |
56 | - memcpy(tmp, tek5head, 16); | |
57 | - UCHAR *q = tmp + 16; | |
58 | - char iif = 0; | |
59 | - int i, tmpsiz; | |
60 | - const UCHAR *p = &buf[1]; | |
61 | - i = appackSub3u(&p, &iif); | |
62 | - tmpsiz = appackSub3u(&p, &iif); | |
63 | - tmpsiz = tmpsiz << 8 | *p++; | |
64 | - *q++ = (tmpsiz >> 27) & 0xfe; | |
65 | - *q++ = (tmpsiz >> 20) & 0xfe; | |
66 | - *q++ = (tmpsiz >> 13) & 0xfe; | |
67 | - *q++ = (tmpsiz >> 6) & 0xfe; | |
68 | - *q++ = (tmpsiz << 1 | 1) & 0xff; | |
69 | - if (i == 1) *q++ = 0x15; | |
70 | - if (i == 2) *q++ = 0x19; | |
71 | - if (i == 3) *q++ = 0x21; | |
72 | - if (i >= 4) return -9; | |
73 | - while (p < buf1){ | |
74 | - *q++ = *p++; | |
75 | - } | |
76 | - if(tek_decomp(tmp, buf, tmpsiz) != 0){ | |
77 | - // failed | |
78 | - return -1; | |
79 | - } | |
80 | - //success | |
81 | - return tmpsiz; | |
82 | -} | |
83 | - | |
84 | -/*----For using tek End----*/ | |
85 | -#endif | |
86 | - | |
1 | + | |
2 | +#include "osecpu.h" | |
3 | +#if (USE_TEK5 != 0) | |
4 | +/*----For using tek Begin----*/ | |
5 | +#include "tek.h" | |
6 | + | |
7 | +int appackSub2(const UCHAR **pp, char *pif) | |
8 | +{ | |
9 | + int r = 0; | |
10 | + const UCHAR *p = *pp; | |
11 | + if (*pif == 0) { | |
12 | + r = *p >> 4; | |
13 | + } else { | |
14 | + r = *p & 0x0f; | |
15 | + p++; | |
16 | + *pp = p; | |
17 | + } | |
18 | + *pif ^= 1; | |
19 | + | |
20 | + return r; | |
21 | +} | |
22 | + | |
23 | +int appackSub3u(const UCHAR **pp, char *pif) | |
24 | +{ | |
25 | + int r = 0, i; | |
26 | + | |
27 | + r = appackSub2(pp, pif); | |
28 | + if (0x8 <= r && r <= 0xb) { | |
29 | + r = r << 4 | appackSub2(pp, pif); | |
30 | + r &= 0x3f; | |
31 | + } else if (0xc <= r && r <= 0xd) { | |
32 | + r = r << 4 | appackSub2(pp, pif); | |
33 | + r = r << 4 | appackSub2(pp, pif); | |
34 | + r &= 0x1ff; | |
35 | + } else if (r == 0xe) { | |
36 | + r = appackSub2(pp, pif); | |
37 | + r = r << 4 | appackSub2(pp, pif); | |
38 | + r = r << 4 | appackSub2(pp, pif); | |
39 | + } else if (r == 0x7) { | |
40 | + i = appackSub3u(pp, pif); | |
41 | + r = 0; | |
42 | + while (i > 0) { | |
43 | + r = r << 4 | appackSub2(pp, pif); | |
44 | + i--; | |
45 | + } | |
46 | + } | |
47 | + | |
48 | + return r; | |
49 | +} | |
50 | + | |
51 | +int tek5Decomp(UCHAR *buf, UCHAR *buf1, UCHAR *tmp) | |
52 | +{ | |
53 | + static char tek5head[16] = { | |
54 | + 0x89, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, | |
55 | + 0x4f, 0x53, 0x41, 0x53, 0x4b, 0x43, 0x4d, 0x50 | |
56 | + }; | |
57 | + memcpy(tmp, tek5head, 16); | |
58 | + UCHAR *q = tmp + 16; | |
59 | + char iif = 0; | |
60 | + int i, tmpsiz; | |
61 | + const UCHAR *p = &buf[1]; | |
62 | + i = appackSub3u(&p, &iif); | |
63 | + tmpsiz = appackSub3u(&p, &iif); | |
64 | + tmpsiz = tmpsiz << 8 | *p++; | |
65 | + *q++ = (tmpsiz >> 27) & 0xfe; | |
66 | + *q++ = (tmpsiz >> 20) & 0xfe; | |
67 | + *q++ = (tmpsiz >> 13) & 0xfe; | |
68 | + *q++ = (tmpsiz >> 6) & 0xfe; | |
69 | + *q++ = (tmpsiz << 1 | 1) & 0xff; | |
70 | + if (i == 1) *q++ = 0x15; | |
71 | + if (i == 2) *q++ = 0x19; | |
72 | + if (i == 3) *q++ = 0x21; | |
73 | + if (i >= 4) return -9; | |
74 | + while (p < buf1){ | |
75 | + *q++ = *p++; | |
76 | + } | |
77 | + if(tek_decomp(tmp, buf, tmpsiz) != 0){; | |
78 | + // failed | |
79 | + fputs("tek decomp error.\n", stderr); | |
80 | + exit(1); | |
81 | + } | |
82 | + //success | |
83 | + return tmpsiz; | |
84 | +} | |
85 | + | |
86 | +/*----For using tek End----*/ | |
87 | +#endif | |
88 | + |