-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtd0notes.txt
572 lines (374 loc) · 21.8 KB
/
td0notes.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
Teledisk
Image File Format
Notes
PRELIMINARY
Dave Dunfield
April 2, 2007
Last revised: July 28, 2008
Teledisk .TD0 notes
TABLE OF CONTENTS
Page
1. Introduction 1
1.1 Acknowlegements 1
2. Image file Format 2
3. Image Header 2
3.1 Signature (2 bytes) 2
3.2 Sequence (1 byte) 2
3.3 CheckSequence (1 byte) 3
3.4 Teledisk version (1 byte) 3
3.5 Data rate (1 byte) 3
3.6 Drive type (1 byte) 3
3.7 Stepping (1 byte) 3
3.8 DOS allocation flag (1 byte) 4
3.9 Sides (1 byte) 4
3.10 Cyclic Redundancy Check (2 bytes) 4
4. Comment Header / Data block 4
4.1 Cyclic Redundancy Check (2 bytes) 4
4.2 Data length (2 bytes) 4
4.3 Year (1 byte) 5
4.4 Month (1 byte) 5
4.5 Day (1 byte) 5
4.6 Hour, Minite, Second (1 byte each) 5
4.7 Comment data block (variable size) 5
5. Track Header 6
5.1 Number of sectors (1 byte) 6
5.2 Cylinder number (1 byte) 6
5.3 Side/Head number (1 byte) 6
5.4 Cyclic Redundancy Check (1 byte) 6
6. Sector Header 7
6.1 Cylinder number (1 byte) 7
6.2 Side/Head (1 byte) 7
6.3 Sector number (1 byte) 7
6.4 Sector size (1 byte) 8
6.5 Flags 8
6.6 Cyclic Redundancy Check (1 byte) 8
7. Sector Data Header 9
Teledisk .TD0 notes Table of Contents
Page
7.1 Data block size (2 bytes) 9
7.2 Encoding method (1 byte) 9
Teledisk .TD0 notes Page: 1
1. Introduction
Teledisk is a program which reads non-PC format diskettes into image
files for archival and can later recreate a copy of the original disk
from the image file. Once popular for archival of classic computer
software, Teledisk has been withdrawn from the market by it's
manufacturer and is no longer legally available. This presents a
problem for those people who have data archived with Teledisk,
because the file format is proprietary and not documented rendering
the data useless without the program.
In my development of ImageDisk (a replacement for Teledisk), I have
created a utility to convert Teledisk .TD0 images into ImageDisk .IMD
format - in doing so, I have researched the Teledisk format, read
other peoples notes, done some reverse engineering myself, and come
to what I believe is a somewhat complete understanding of the
contents of a .TD0 image file.
This document presents my notes on the Teledisk .TD0 image file
format.
This document is a work in progress. If you have any information to
add, corrections etc. Please contact me. I can be reached via the
contact information on my web site.
http://www.classiccmp.org/dunfield
1.1 Acknowlegements
The following people whom I have never met have saved me tons of
time by making the results of their related efforts freely
available.
Will Krantz - Wrote a program called wteledisk which converts
TX50 .TD0 into binary files for an emulator.
Published a web page with his notes and source.
Sergey Erokhin - Provided more details for Wills web page.
Simon Owen - Published source code to read some .TD0 files
for his SimCoupe emulator.
Haruhika - Published LZSS-Huffman source code which has
Okumura become "the reference" for many implementations.
Teledisk .TD0 notes Page: 2
2. Image file Format
The overall disk image file has this format:
Image header (12 bytes)
;If the image was created using "Advanced Compression", everything
;below this line is compressed with LZSS-Huffman encoding.
Optional comment header (10 bytes)
Optional comment data (Variable size)
;For each track on the disk ...
Track header (4 bytes)
;For each sector within the track
Sector header (6 bytes)
Optional data header (3 bytes)
Optional data block (variable size)
;Image ends with Trackheader beginning with 255 (FF hex)
If the Teledisk image was generated with "Advanced Data Compression",
all parts of the file following "Image Header" are compressed as a
single block with LZSS-Huffman encoding with the string lookup buffer
preset to all spaces (ASCII 20). With "normal" compression, the
remainder of the file is not compressed/encoded (other than the
sector RLE compression).
3. Image Header
The image header describes global information about the disk image.
It is never compressed, and is laid out in the following format:
Signature (2 bytes)
Sequence (1 byte)
Checksequence (1 byte)
Teledisk version (1 byte)
Data rate (1 byte)
Drive type (1 byte)
Stepping (1 byte)
DOS allocation flag (1 byte)
Sides (1 byte)
Cyclic Redundancy Check (2 bytes)
3.1 Signature (2 bytes)
- Contains 'TD' for normal compression
- Contains 'td' for advanced compression
3.2 Sequence (1 byte)
- Early Teledisk document indicates that this begins with 00 and
increments for each member of a multi-volume set.
- TDCHECK reports "bad header" if this value is set to anything
other than 00.
Teledisk .TD0 notes Page: 3
3.3 CheckSequence (1 byte)
- Early Teledisk document indicates that this must be the same for
each member of a multi-volume set
3.4 Teledisk version (1 byte)
- Encodes the version number of the Teledisk program which created
the image in the form High-nibble.low-nibble. eg: 15 = 1.5
3.5 Data rate (1 byte)
- Encodes the data rate used for the diskette in lower 2 bits.
0 = 250kbps
1 = 300kbps
2 = 500kbps
- High bit indicates single-density diskette (I believe this is for
older versions only which did not support mixed density disks).
3.6 Drive type (1 byte)
- Indicates the type of drive the disk was made on.
- Early Teledisk document indicates the encoding is:
1 = 360k
2 = 1.2M
3 = 720k
4 = 1.44M
- Experimentation with TDCHECK indicates that the text generated
from the various encoding is:
0 = 5.25 96 tpi disk in 48 tpi drive
1 = 5.25
2 = 5.25 48-tpi
3 = 3.5
4 = 3.5
5 = 8-inch
6 = 3.5
- Use Data rate to determine appropriate drive density.
3.7 Stepping (1 byte)
- Encodes step type in lower 2 bits
0 = Single-Step
1 = Double-step
2 = Even-only step (96 tpi disk in 48 tpi drive)
- High bit indicates presence of optional comment block
Teledisk .TD0 notes Page: 4
3.8 DOS allocation flag (1 byte)
- non-zero means the disk was read using the DOS FAT table to skip
unallocted sectors.
3.9 Sides (1 byte)
- Encodes the number of sides read from the disk.
01 = One
anything-else = Two
3.10 Cyclic Redundancy Check (2 bytes)
This field contains the error-checking cyclic redundancy check for
the header calculated with the polynomial value 41111 (A097 hex)
using an input preset value of 0. The CRC is calculated over the
first 10 bytes of the header, and should match the value stored in
this field.
4. Comment Header / Data block
The comment block encodes an ASCII comment as well as the creation
date. It's presence is indicated by the high bit of the "Stepping"
field in the image header being set.
When present, it occurs immediately after the Image header in the
following format:
Cyclic Redundancy Check (2 bytes)
Data length (2 bytes)
Year since 1900 (1 byte)
Month (1 byte)
Day (1 byte)
Hour (1 byte)
Minite (1 byte)
Second (1 byte)
Following the comment header are comment line records, consisting of
ASCII text terminated by NUL (00) bytes.
4.1 Cyclic Redundancy Check (2 bytes)
This 16-bit field contains the error-checking cyclic redundancy
check for the header calculated with the polynomial value 41111
(A097 hex) using an input preset value of 0. The CRC is calculated
over the entire header block (beginning at offset 2 - just after
the CRC) and the data records.
4.2 Data length (2 bytes)
This is the length of the comment data block which follows the
comment header. To display the comment data, read and output this
many bytes following the header, translating NUL (00) bytes into
newline sequences.
Teledisk .TD0 notes Page: 5
4.3 Year (1 byte)
Gives the year the image was created as an offset from 1900. eg:
2007 is encoded as 2007 - 1900 = 107 (6B hex).
4.4 Month (1 byte)
Gives the month the image was created using a zero index. ie:
0=January, 11=December.
4.5 Day (1 byte)
Gives the day (of the month) the image was created using a range
of 1-31.
4.6 Hour, Minite, Second (1 byte each)
Gives the time of day the image was created using 24-hour time.
4.7 Comment data block (variable size)
Contains the ASCII text of the comment as NUL (00) terminated
lines. The size of this block is given by "Data length" in the
comment header. To display the comment, read and output "Data
length bytes" from this block, translating NUL (00) bytes into
newline sequences.
Teledisk .TD0 notes Page: 6
5. Track Header
Every disk track recorded in the image will begin with a track
header, which has the following format:
Number of sectors (1 byte)
Cylinder number (1 byte)
Side/Head number (1 byte)
Cyclic Redundancy Check (1 byte)
5.1 Number of sectors (1 byte)
This field indicates how many sectors are recorded for this track.
This also indicates how many sector headers to expect following
the track header.
A number of sectors of 255 (FF hex) indicates the end of the track
list. No other fields occur in this record, and the CRC is not
checked.
5.2 Cylinder number (1 byte)
This field encodes the physical cylinder number (head position)
for this track, in a range of 0-(#tracks on drive-1).
5.3 Side/Head number (1 byte)
This field encodes the disk side (0 or 1) that this track occurs
on in it's lower bit.
The high bit of this field is used to indicate the track was
recorded in single-density. This allows mixed-density disks to be
represented (FM on some tracks, and MFM on others).
FM disks that I recorded had this bit set for every track, and NOT
the FM indicator in bit 7 of the "Data rate" field of the image
header. I cannot confirm this, but I suspect that early versions
of Teledisk did not support mixed density disks, using only the FM
bit in the image header. If this is the case, then a track should
be interpreted as single density if either of the two FM indicator
bits are set.
5.4 Cyclic Redundancy Check (1 byte)
This 8-bit field contains the lower byte of a 16-bit
error-checking cyclic redundancy check for the header calculated
with the polynomial value 41111 (A097 hex) using an input preset
value of 0. The CRC is calculated over the first three bytes of
the header and should match the forth byte.
Track headers and sector block lists occur until all tracks on the
disk have been accounted for. When the last track record and sector
block list has been read, a 255 (FF hex) byte indicates the end of
the image.
Teledisk .TD0 notes Page: 7
6. Sector Header
Following the Track header will be a number of sector blocks
consisting of a sector header and optional data header/data block.
The number of sector blocks is indicated by the "Number of sectors"
field in the track header.
Each sector header has the following format:
Cylinder number (1 byte)
Side/Head (1 byte)
Sector number (1 byte)
Sector size (1 byte)
Flags (1 byte)
Cyclic Redundancy Check (1 byte)
6.1 Cylinder number (1 byte)
This field indicates the logical cylinder number which is written
in the ID field of the disk sector. For most disk formats it
matches the Cylinder number indicated in the track header, however
this does NOT have to be the case - some formats encode
non-physical cylinder numbers.
6.2 Side/Head (1 byte)
This field indicates the logical Side/Head indicator which is
written in the ID field of the disk sector. For most disk formats
it matches the Side/Head number indicated in the track header,
however this does NOT have to be the case - some formats encode
non-physical Side/Head numbers.
6.3 Sector number (1 byte)
This field indicates the logical sector number which is wrtten in
the ID field of the disk sector. Sector numbers do not have to be
in any particular order (the ordering of the sectors determines
the interleave factor of the track), do not necessarily begin at 0
or 1, and are not necessarily an unbroken series of numbers. Some
formats encode seemingly arbitrary sector numbers.
Teledisk sometimes creates bogus sectors headers to describe data
that is not in a properly formatted sector. These extra sectors
appear to be created with sector numbers begining at 100.
Teledisk .TD0 notes Page: 8
6.4 Sector size (1 byte)
Indicates the size of the sector, according to the following
table:
0 = 128 bytes 4 = 2048 bytes
1 = 256 bytes 5 = 4096 bytes
2 = 512 bytes 6 = 8192 bytes
3 = 1024 bytes
Note that disk formats exist which have different sector sizes
within the same track, and Teledisk will encode them this way,
however the PC 765 floppy disk controller cannot format such
tracks, and the disk can not be recreated.
6.5 Flags
This is a bit field indicating characteristics that Teledisk noted
about the sector when it was recorded. The field contain the
logical OR of the following byte values:
01 = Sector was duplicated within a track
02 = Sector was read with a CRC error
04 = Sector has a "deleted-data" address mark
10 = Sector data was skipped based on DOS allocation [note]
20 = Sector had an ID field but not data [note]
40 = Sector had data but no ID field (bogus header)
note: Bit values 20 or 10 indicate that NO SECTOR DATA BLOCK
FOLLOWS.
The meaning of some of these bits was taken from early Teledisk
documentation, and may not be accurate - For example, I've seen
images where sectors were duplicated within a track and the 01 bit
was NOT set.
6.6 Cyclic Redundancy Check (1 byte)
This 8-bit field contains the lower byte of a 16-bit
error-checking cyclic redundancy check for the sector header, data
header and sector data calculated with the polynomial value 41111
(A097 hex) using an input preset value of 0. The CRC is calculated
over the first five bytes of the sector header, the entire sector
data header and the sector data block. The calculated CRC should
match the value stored in the fourth byte of the sector header.
Teledisk .TD0 notes Page: 9
7. Sector Data Header
The sector data header occurs following the sector header only when
sector data is present. This is indicated by bits 10 and 20 of the
Flags value NOT being set. When present it has the following format:
Data block size (2 bytes)
Encoding method (1 byte)
7.1 Data block size (2 bytes)
This indicates the size of the sector data block, including the
encoding method (ie: data block size + 1).
7.2 Encoding method (1 byte)
This field describes how the sector data is encoded. It can have
three possible values:
7.2.1 0 - Raw sector data
Encoding method == 0 indicates that "sector size" bytes of raw
sector data follow. This is the actual data content for the
sector.
7.2.2 1 - Repeated 2-byte pattern
Encoding method == 1 indicates that a repeated 2-byte pattern
is used. Note that this may occur multiple times until the
entire sector has been recreated, as determined by "sector
size" in the sector header.
Each entry consits of two 16-bit values. The first is a count
value indicating how many times the second (the data value) is
repeated.
7.2.3 2 - Run Length Encoded data
Encoding == 2 indicates that an RLE data block occurs. Note
that this may occur multiple times until the entire sector has
been recreated, as determined by "sector size" in the sector
header.
Each entry begins with a 1 byte length value or 00.
If 00, then this entry is for a literal block. The next byte
indicates a length 'n', and the following 'n' bytes are copied
into the sector data as raw bytes (similar to Encoding
method==0 except for only a portion of the sector).
If not 00, then the length 'l' is determined as the value * 2
(ie: 2-510). The next byte indicates a repeat count 'r'. A
block of 'l' bytes is then read once from the file, and
repeated in the sector data 'r' times.
Sector headers and data blocks occur until all sectors for the
track have been accounted for.