Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
716 lvd 1
#include "std.h"
2
 
3
#include "emul.h"
4
#include "vars.h"
5
#include "wd93crc.h"
6
 
7
#include "util.h"
8
 
9
int FDD::write_td0(FILE *ff)
10
{
11
   unsigned char zerosec[256] = { 0 };
12
   unsigned char td0hdr[12] = { 0 };
13
 
14
   *(unsigned short*)td0hdr = WORD2('T','D');
15
   td0hdr[4] = 21; td0hdr[6] = 2; td0hdr[9] = (unsigned char)sides;
16
   if (*dsc) td0hdr[7] = 0x80;
17
   *(unsigned short*)(td0hdr + 10) = crc16(td0hdr, 10);
18
   fwrite(td0hdr, 1, 12, ff);
19
   if (*dsc) {
20
      unsigned char inf[0x200] = { 0 };
21
      strcpy((char*)inf+10, dsc);
22
      unsigned len = strlen(dsc)+1;
23
      *(unsigned*)(inf+2) = len;
24
      *(unsigned short*)inf = crc16(inf+2, len+8);
25
      fwrite(inf, 1, len+10, ff);
26
   }
27
 
28
   unsigned c; //Alone Coder 0.36.7
29
   for (/*unsigned*/ c = 0; c < cyls; c++)
30
      for (unsigned s = 0; s < sides; s++) {
31
         t.seek(this,c,s,LOAD_SECTORS);
32
         unsigned char bf[16];
33
         *bf = t.s;
34
         bf[1] = c, bf[2] = s;
35
         bf[3] = (unsigned char)crc16(bf, 3);
36
         fwrite(bf, 1, 4, ff);
37
         for (unsigned sec = 0; sec < t.s; sec++) {
38
            if (!t.hdr[sec].data) { t.hdr[sec].data = zerosec, t.hdr[sec].datlen = 256, t.hdr[sec].l = 1; }
39
            *(unsigned*)bf = *(unsigned*)&t.hdr[sec];
40
            bf[4] = 0; // flags
41
            bf[5] = (unsigned char)crc16(t.hdr[sec].data, t.hdr[sec].datlen);
42
            *(unsigned short*)(bf+6) = t.hdr[sec].datlen + 1;
43
            bf[8] = 0; // compression type = none
44
            fwrite(bf, 1, 9, ff);
45
            if (fwrite(t.hdr[sec].data, 1, t.hdr[sec].datlen, ff) != t.hdr[sec].datlen) return 0;
46
         }
47
      }
48
   c = WORD4(0xFF,0,0,0);
49
   if (fwrite(&c, 1, 4, ff) != 4) return 0;
50
   return 1;
51
}
52
 
53
 
54
unsigned unpack_lzh(unsigned char *src, unsigned size, unsigned char *buf);
55
 
56
// No ID address field was present for this sector,
57
// but there is a data field. The sector information in
58
// the header represents fabricated information.
59
const ULONG TD0_SEC_NO_ID = 0x40;
60
 
61
// This sector's data field is missing; no sector data follows this header.
62
const ULONG TD0_SEC_NO_DATA = 0x20;
63
 
64
// A DOS sector copy was requested; this sector was not allocated.
65
// In this case, no sector data follows this header.
66
const ULONG TD0_SEC_NO_DATA2 = 0x10;
67
 
68
#pragma pack(push, 1)
69
struct TTd0Sec
70
{
71
    u8 c;
72
    u8 h;
73
    u8 s;
74
    u8 n;
75
    u8 flags;
76
    u8 crc;
77
};
78
#pragma pack(pop)
79
 
80
int FDD::read_td0()
81
{
82
   if (*(short*)snbuf == WORD2('t','d'))
83
   { // packed disk
84
      unsigned char *tmp = (unsigned char*)malloc(snapsize);
85
      memcpy(tmp, snbuf+12, snapsize-12);
86
      snapsize = 12+unpack_lzh(tmp, snapsize-12, snbuf+12);
87
      ::free(tmp);
88
      //*(short*)snbuf = WORD2('T','D');
89
   }
90
 
91
   char dscbuffer[sizeof(dsc)];
92
   *dscbuffer = 0;
93
 
94
   unsigned char *start = snbuf+12;
95
   if (snbuf[7] & 0x80) // coment record
96
   {
97
      start += 10;
98
      unsigned len = *(unsigned short*)(snbuf+14);
99
      start += len;
100
      if (len >= sizeof dsc)
101
          len = sizeof(dsc)-1;
102
      memcpy(dscbuffer, snbuf+12+10, len);
103
      dscbuffer[len] = 0;
104
   }
105
   unsigned char *td0_src = start;
106
 
107
   unsigned sides = (snbuf[9] == 1 ? 1 : 2);
108
   unsigned max_cyl = 0;
109
 
110
   for (;;)
111
   {
112
      unsigned char s = *td0_src; // Sectors
113
      if (s == 0xFF)
114
          break;
115
      max_cyl = max(max_cyl, unsigned(td0_src[1])); // PhysTrack
116
      td0_src += 4; // sizeof(track_rec)
117
      for (; s; s--)
118
      {
119
         unsigned char flags = td0_src[4];
120
         td0_src += 6; // sizeof(sec_rec)
121
 
122
         assert(td0_src <= snbuf + snapsize);
123
 
124
         if (td0_src > snbuf + snapsize)
125
             return 0;
126
         td0_src += *(unsigned short*)td0_src + 2; // data_len
127
      }
128
   }
129
 
130
   if(max_cyl+1 > MAX_CYLS)
131
   {
132
       err_printf("cylinders (%d) > MAX_CYLS(%d)", max_cyl, MAX_CYLS);
133
       return 0;
134
   }
135
 
136
   newdisk(max_cyl+1, sides);
137
   memcpy(dsc, dscbuffer, sizeof dsc);
138
 
139
   td0_src = start;
140
   for (;;)
141
   {
142
      unsigned char t0[16384];
143
      unsigned char *dst = t0;
144
      unsigned char *trkh = td0_src;
145
      td0_src += 4; // sizeof(track_rec)
146
 
147
      if(*trkh == 0xFF)
148
          break;
149
 
150
      t.seek(this, trkh[1], trkh[2], JUST_SEEK);
151
 
152
      unsigned s = 0;
153
      for (unsigned se = 0; se < trkh[0]; se++)
154
      {
155
         TTd0Sec *SecHdr = (TTd0Sec *)td0_src;
156
         unsigned sec_size = 128U << (SecHdr->n & 3); // [vv]
157
         unsigned char flags = SecHdr->flags;
158
//         printf("fl=%x\n", flags);
159
//         printf("c=%d, h=%d, s=%d, n=%d\n", SecHdr->c, SecHdr->h, SecHdr->s, SecHdr->n);
160
         if(flags & (TD0_SEC_NO_ID | TD0_SEC_NO_DATA | TD0_SEC_NO_DATA2)) // skip sectors with no data & sectors without headers
161
         {
162
             td0_src += sizeof(TTd0Sec); // sizeof(sec_rec)
163
 
164
             unsigned src_size = *(unsigned short*)td0_src;
165
//             printf("sz=%d\n", src_size);
166
             td0_src += 2; // data_len
167
             unsigned char *end_packed_data = td0_src + src_size;
168
/*
169
             u8 method = *td0_src++;
170
             printf("m=%d\n", method);
171
             switch(method)
172
             {
173
             case 0:
174
                 {
175
                     char name[MAX_PATH];
176
                     sprintf(name, "%02d-%d-%03d-%d.trk", SecHdr->c, SecHdr->h, SecHdr->s, SecHdr->n);
177
                     FILE *f = fopen(name, "wb");
178
                     fwrite(td0_src, 1, src_size - 1, f);
179
                     fclose(f);
180
                     break;
181
                 }
182
             case 1:
183
                 {
184
                     unsigned n = *(unsigned short*)td0_src;
185
                     td0_src += 2;
186
                     unsigned short data = *(unsigned short*)td0_src;
187
                     printf("len=%d, data=%04X\n", n, data);
188
                     break;
189
                 }
190
             }
191
*/
192
             td0_src = end_packed_data;
193
             continue;
194
         }
195
 
196
          // c, h, s, n
197
         t.hdr[s].c = SecHdr->c;
198
         t.hdr[s].s = SecHdr->h;
199
         t.hdr[s].n = SecHdr->s;
200
         t.hdr[s].l = SecHdr->n;
201
         t.hdr[s].c1 = t.hdr[s].c2 = 0;
202
         t.hdr[s].data = dst;
203
 
204
         td0_src += sizeof(TTd0Sec); // sizeof(sec_rec)
205
 
206
         unsigned src_size = *(unsigned short*)td0_src;
207
         td0_src += 2; // data_len
208
         unsigned char *end_packed_data = td0_src + src_size;
209
 
210
         memset(dst, 0, sec_size);
211
 
212
         switch (*td0_src++) // Method
213
         {
214
            case 0:  // raw sector
215
               memcpy(dst, td0_src, src_size-1);
216
               break;
217
            case 1:  // repeated 2-byte pattern
218
            {
219
               unsigned n = *(unsigned short*)td0_src;
220
               td0_src += 2;
221
               unsigned short data = *(unsigned short*)td0_src;
222
               for (unsigned i = 0; i < n; i++)
223
                  *(unsigned short*)(dst+2*i) = data;
224
               break;
225
            }
226
            case 2: // RLE block
227
            {
228
               unsigned short data;
229
               unsigned char s;
230
               unsigned char *d0 = dst;
231
               do
232
               {
233
                  switch (*td0_src++)
234
                  {
235
                     case 0: // Zero count means a literal data block
236
                        for (s = *td0_src++; s; s--)
237
                           *dst++ = *td0_src++;
238
                        break;
239
                     case 1:    // repeated fragment
240
                        s = *td0_src++;
241
                        data = *(unsigned short*)td0_src;
242
                        td0_src += 2;
243
                        for ( ; s; s--)
244
                        {
245
                            *(unsigned short*)dst = data;
246
                            dst += 2;
247
                        }
248
                        break;
249
                     default:
250
                         errmsg("unknown RLE block type");
251
                         goto shit;
252
                  }
253
               } while (td0_src < end_packed_data);
254
               dst = d0;
255
               break;
256
            }
257
            default: // error!
258
            errmsg("unknown block type");
259
 
260
            shit:
261
               errmsg("bad TD0 file");
262
               return 0;
263
         }
264
         dst += sec_size;
265
         td0_src = end_packed_data;
266
         s++;
267
      }
268
      t.s = s;
269
      t.format();
270
   }
271
   return 1;
272
}
273
 
274
// ------------------------------------------------------ LZH unpacker
275
 
276
 
277
unsigned char *packed_ptr, *packed_end;
278
 
279
int readChar(void)
280
{
281
  if (packed_ptr < packed_end) return *packed_ptr++;
282
  else return -1;
283
}
284
 
285
unsigned char d_code[256] =
286
{
287
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
288
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
290
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291
        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
292
        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
293
        0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
294
        0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
295
        0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
296
        0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
297
        0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
298
        0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
299
        0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
300
        0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
301
        0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
302
        0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
303
        0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
304
        0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
305
        0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
306
        0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
307
        0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
308
        0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
309
        0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
310
        0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
311
        0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B,
312
        0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F,
313
        0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23,
314
        0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
315
        0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B,
316
        0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F,
317
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
318
        0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
319
};
320
 
321
unsigned char d_len[256] =
322
{
323
        0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
324
        0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
325
        0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
326
        0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
327
        0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
328
        0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
329
        0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
330
        0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
331
        0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
332
        0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
333
        0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
334
        0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
335
        0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
336
        0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
337
        0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
338
        0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
339
        0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
340
        0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
341
        0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
342
        0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
343
        0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
344
        0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
345
        0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
346
        0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
347
        0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
348
        0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
349
        0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
350
        0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
351
        0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
352
        0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
353
        0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
354
        0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
355
};
356
 
357
 
358
const int N = 4096;     // buffer size
359
const int F = 60;       // lookahead buffer size
360
const int THRESHOLD =   2;
361
const int NIL = N;      // leaf of tree
362
 
363
unsigned char text_buf[N + F - 1];
364
 
365
const int N_CHAR = (256 - THRESHOLD + F);       // kinds of characters (character code = 0..N_CHAR-1)
366
const int T =   (N_CHAR * 2 - 1);       // size of table
367
const int R = (T - 1);                  // position of root
368
const int MAX_FREQ = 0x8000;            // updates tree when the
369
                                    // root frequency comes to this value.
370
 
371
unsigned short freq[T + 1];        // frequency table
372
 
373
short prnt[T + N_CHAR]; // pointers to parent nodes, except for the
374
                        // elements [T..T + N_CHAR - 1] which are used to get
375
                        // the positions of leaves corresponding to the codes.
376
short son[T];           // pointers to child nodes (son[], son[] + 1)
377
 
378
 
379
int r;
380
 
381
unsigned getbuf;
382
unsigned char getlen;
383
 
384
int GetBit(void)      /* get one bit */
385
{
386
  int i;
387
 
388
  while (getlen <= 8)
389
  {
390
    if((i = readChar()) == -1) i = 0;
391
    getbuf |= i << (8 - getlen);
392
    getlen += 8;
393
  }
394
  i = getbuf;
395
  getbuf <<= 1;
396
  getlen--;
397
  return ((i>>15) & 1);
398
}
399
 
400
int GetByte(void)     /* get one byte */
401
{
402
  unsigned i;
403
 
404
  while (getlen <= 8)
405
  {
406
    if((i = readChar()) == -1) i = 0;
407
    getbuf |= i << (8 - getlen);
408
    getlen += 8;
409
  }
410
  i = getbuf;
411
  getbuf <<= 8;
412
  getlen -= 8;
413
  return (i >> 8) & 0xFF;
414
}
415
 
416
void StartHuff(void)
417
{
418
  int i, j;
419
 
420
  getbuf = 0, getlen = 0;
421
  for (i = 0; i < N_CHAR; i++) {
422
    freq[i] = 1;
423
    son[i] = i + T;
424
    prnt[i + T] = i;
425
  }
426
  i = 0; j = N_CHAR;
427
  while (j <= R) {
428
    freq[j] = freq[i] + freq[i + 1];
429
    son[j] = i;
430
    prnt[i] = prnt[i + 1] = j;
431
    i += 2; j++;
432
  }
433
  freq[T] = 0xffff;
434
  prnt[R] = 0;
435
 
436
  for (i = 0; i < N - F; i++) text_buf[i] = ' ';
437
  r = N - F;
438
}
439
 
440
/* reconstruction of tree */
441
void reconst(void)
442
{
443
  int i, j, k;
444
  int f, l;
445
 
446
  /* collect leaf nodes in the first half of the table */
447
  /* and replace the freq by (freq + 1) / 2. */
448
  j = 0;
449
  for(i = 0; i < T; i++)
450
  {
451
    if(son[i] >= T)
452
    {
453
      freq[j] = (freq[i] + 1) / 2;
454
      son[j] = son[i];
455
      j++;
456
    }
457
  }
458
  /* begin constructing tree by connecting sons */
459
  for(i = 0, j = N_CHAR; j < T; i += 2, j++)
460
  {
461
    k = i + 1;
462
    f = freq[j] = freq[i] + freq[k];
463
    for(k = j - 1; f < freq[k]; k--);
464
    k++;
465
    l = (j - k) * sizeof(*freq);
466
    MoveMemory(&freq[k + 1], &freq[k], l);
467
    freq[k] = f;
468
    MoveMemory(&son[k + 1], &son[k], l);
469
    son[k] = i;
470
  }
471
  /* connect prnt */
472
  for (i = 0; i < T; i++)
473
    if ((k = son[i]) >= T) prnt[k] = i;
474
    else prnt[k] = prnt[k + 1] = i;
475
}
476
 
477
 
478
/* increment frequency of given code by one, and update tree */
479
 
480
void update(int c)
481
{
482
  int i, j, k, l;
483
 
484
  if(freq[R] == MAX_FREQ) reconst();
485
 
486
  c = prnt[c + T];
487
  do {
488
    k = ++freq[c];
489
 
490
    /* if the order is disturbed, exchange nodes */
491
    if (k > freq[l = c + 1])
492
    {
493
      while (k > freq[++l]);
494
      l--;
495
      freq[c] = freq[l];
496
      freq[l] = k;
497
 
498
      i = son[c];
499
      prnt[i] = l;
500
      if (i < T) prnt[i + 1] = l;
501
 
502
      j = son[l];
503
      son[l] = i;
504
 
505
      prnt[j] = c;
506
      if (j < T) prnt[j + 1] = c;
507
      son[c] = j;
508
 
509
      c = l;
510
    }
511
  } while ((c = prnt[c]) != 0);  /* repeat up to root */
512
}
513
 
514
int DecodeChar(void)
515
{
516
  int c;
517
 
518
  c = son[R];
519
 
520
  /* travel from root to leaf, */
521
  /* choosing the smaller child node (son[]) if the read bit is 0, */
522
  /* the bigger (son[]+1} if 1 */
523
  while(c < T) c = son[c + GetBit()];
524
  c -= T;
525
  update(c);
526
  return c;
527
}
528
 
529
int DecodePosition(void)
530
{
531
  int i, j, c;
532
 
533
  /* recover upper 6 bits from table */
534
  i = GetByte();
535
  c = (int)d_code[i] << 6;
536
  j = d_len[i];
537
  /* read lower 6 bits verbatim */
538
  j -= 2;
539
  while (j--) i = (i << 1) + GetBit();
540
  return c | (i & 0x3f);
541
}
542
 
543
unsigned unpack_lzh(unsigned char *src, unsigned size, unsigned char *buf)
544
{
545
  packed_ptr = src; packed_end = src+size;
546
  int  i, j, k, c;
547
  unsigned count = 0;
548
  StartHuff();
549
 
550
//  while (count < textsize)  // textsize - sizeof unpacked data
551
  while (packed_ptr < packed_end)
552
  {
553
    c = DecodeChar();
554
    if(c < 256)
555
    {
556
      *buf++ = c;
557
      text_buf[r++] = c;
558
      r &= (N - 1);
559
      count++;
560
    } else {
561
      i = (r - DecodePosition() - 1) & (N - 1);
562
      j = c - 255 + THRESHOLD;
563
      for (k = 0; k < j; k++)
564
      {
565
        c = text_buf[(i + k) & (N - 1)];
566
        *buf++ = c;
567
        text_buf[r++] = c;
568
        r &= (N - 1);
569
        count++;
570
      }
571
    }
572
  }
573
  return count;
574
}