home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / GXY-INF.LHA / infos / diskstruc.txt < prev    next >
Encoding:
Text File  |  1996-03-09  |  9.9 KB  |  294 lines

  1. `                DISK STRUKTURE
  2.  
  3.  As we all know disks contain tracks,data on the disk is stored on those
  4.  tracks. There are 80 (official) cylinders on the disk, each cylinder
  5.  containing two tracks (upper and lower).
  6.  
  7.  When we number things as 0-79, we really talk about cylinders, but
  8.  usualy this numbering is called track numbering.
  9.  The system numbers tracks 0-159 and numbering starts from lower side,
  10.  where is track 0, track 1 is really cylinder 0 upper side.
  11.  Data on these tracks is usually MFM-decoded.  Each track contains 11
  12.  sectors of 512 bytes of data.  Each sector has a header, which tells us
  13.  track number, sector number and some additional data.
  14.  
  15. Contents of normal DOS-format track is;
  16.  
  17.                          ...(gap)...(track)...(gap)...
  18.  
  19.     (gap) is normally 0-bytes decoded into MFM. 00 -> AAAA
  20.     (track) contains 11 sectors which are:
  21.  
  22.     (00)(00)(sync)(sync)(header)(fill)(headerchecksum)(datachecksum)(data)
  23.  
  24.     (00) is zero byte (in MFM AAAA)
  25.     (sync) is (A1)-bytes converted to MFM and clock pulse is dropped so that
  26.            result is 4489, which is standard syncword.  Any data never converts
  27.            into this pattern (in MFM)
  28.     (header) is sector header.  More later.
  29.     (fill) is 16 bytes of zeros.  These are intended for use by dos, but dos
  30.            doesn't use them.
  31.     (headerchecksum) is checksum of header info. Checksum is calculated using
  32.                      exclusive-or and contains only databits.
  33.     (datachecksum) is same for data.
  34.     (data) is 512-byte data block.
  35.  
  36.  
  37. Sector header consists from;
  38.  
  39.     (format)(track)(sector)(length)
  40.  
  41.     (format) is FF for normal format
  42.     (track) is track number
  43.     (sector) is sector number
  44.     (length) is count of sectors before gap (end of track)
  45.  
  46.  
  47. This stuff is converted into MFM before writing and is is done as follows:
  48.  
  49.     (sector header) is converted as one longword
  50.     (fill) is converted as one 16-byte block
  51.     (checksums) are converted as longword
  52.     (data) is converted as one 512-byte block
  53.  
  54.  
  55. MFM conversion is in the following principle;
  56.  
  57. Take two data bits and add one clock bit between them.
  58. Clock bit is 1, if both data bits are 0 otherwise 0.
  59.  
  60.     so 01001110 goes to;
  61.  
  62.         C0C1C0C0C1C1C1C0 -> 0001001001010100
  63.  
  64. Each byte converts into a word.
  65.  
  66. As streching bytes is quite hard to do on the Amiga, data is first split into
  67. two halves; odd and even.
  68.  
  69. First even bits are converted and then odd ones.
  70.    
  71. So in Amiga:
  72.  
  73.     01001110 -> 0011 1010
  74.                 even odd
  75.  
  76.     C0C0C1C1C1C0C1C0 -> 0010010101000100
  77.  
  78.  
  79. This lead into faster operation, because extracting odd and even halves can be
  80. done by logical ops.
  81.  
  82.     Even_half = ((data & 0xAAAA) >> 1)
  83.  
  84.     Odd_half = (data & 0x5555)
  85.  
  86.  
  87. And values for clock bits are:
  88.  
  89.     clock_bit = not( previous_bit or next_bit )
  90.  
  91. So
  92.  
  93.     Result = ( ~( (Half>>1) | (Half<<1) ) ) | Half
  94.  
  95.  
  96. Conversion of one block (in Amiga style) can be done with following code:
  97.  
  98. ; Input:
  99. ; a0 - address of data to be converted
  100. ; a1 - address of destination block
  101. ; d0 - length of block (in bytes)
  102. ; d1 - continuation flag (is end of previous block ok)
  103. ;
  104. ; Result:
  105. ; decoded data in destination buffer
  106. ; checksum in d0
  107. ;   d2,d3,d4 also used
  108.  
  109. _encodeblock:
  110.     movem.l d2-d4,-(sp)         ; save working regs
  111.     clr.l   d4                  ; initialize checksum
  112.     move.l  d1,-(sp)            ; flag is saved
  113.     move.l  d0,d1               ; copy length into index
  114.     move.l  a1,-(sp)            ; save start of dst buffer
  115.     asr.l   #1,d1               ; create word count
  116.     bra     2$
  117.  
  118. ; Copy loop first
  119.  
  120. 1$:
  121.     move.w  (a0)+,d2            ; pick word from src
  122.     move.w  d2,0(a1,d0)         ; put odd bits into latter half ...
  123.     asr.w   #1,d2               ; ... and even bits ...
  124.     move.w  d2,(a1)+            ; ... into first half
  125.  
  126. 2$:
  127.     dbra    d1,1$               ; done
  128.  
  129. ; Now convert from dst to dst one word at time
  130.  
  131.     move.l  (sp)+,a1            ; restore dst address
  132.     move.l  (sp)+,d1            ; pick flag
  133.     beq     4$                  ; no continuation
  134.     move.l  -2(a1),d1           ; or previous block before this one
  135.     bra     4$                  ; last word is picked from there
  136.  
  137. ; conversion loop as each word of source
  138. ; converts into longword we convert length count of words
  139.  
  140.  
  141. 3$:
  142.     move.w  (a1),d1             ; take first word to convert
  143.     and.l   #$55555555,d1       ; pick bits to convert
  144.     move.l  d1,d2               ; copy longword in reg ...
  145.     move.l  d1,d3               ; ... twice into work regs ...
  146.     asr.l   #1,d2               ; other is shifted right
  147.     add.l   d3,d3               ; and other left
  148.     or.l    d3,d2               ; combine these
  149.     not.l   d2                  ; and complement
  150.     or.l    #$AAAAAAAA,d1       ; turn all clocks up
  151.     and.l   d2,d1               ; turn some of them down
  152.     move.w  d1,(a1)+            ; put resulting word into buffer
  153.     eor.w   d1,d4               ; update checksum
  154.     swap    d4                  ; swap checksum
  155.     swap    d1                  ; push last word into upper half
  156. 4$:
  157.     dbra    d0,3$               ; and here we go for next word
  158.     swap    d4                  ; take checksum
  159.     move.l  d4,d0               ; put into result reg
  160.     and.l   #$55555555,d0       ; and drop clock bits
  161.     movem.l (sp)+,d2-d4         ; restore regs
  162.     rts                         ; and retrun into caller
  163.  
  164.  
  165.  
  166.  
  167. In real life this is done with the blitter, which may very well be slower if
  168. faster processors than normal are used.  We need four blits for each block and
  169. for tiny blocks this is slower.  But for large blocks, situaion is something
  170. else because blitter ops are effectively parallel with processor.
  171.  
  172. Decoding a block is even easier and can be done with one blit.  Very quick,
  173. except for single longword (as header).
  174.  
  175. Decoding in principle is;
  176.  
  177.     data = (odd_word & 0x5555) | ((even_word & 0x5555)<<1)
  178.  
  179. And can be done with following code
  180.  
  181. ; long decodeblock( char * from, char * to, int len )
  182. ;                       a0           a1       d0
  183. _decodeblock:
  184.     movem.l d2-d4,-(sp)     ; save working regs
  185.     clr.l   d4              ; init checksum
  186.     move.l  d0,d1           ; save src legth for indexing
  187.     asr.l   #2,d0           ; src bytecount to dst wordcount
  188.     bra     2$
  189.  
  190. 1$:
  191.     move.l  (a0)+,d2        ; get even_word
  192.     and.l   #$55555555,d2   ; drop clockbits
  193.     eor.l   d2,d4           ; update checksum
  194.     add.l   d2,d2           ; shift left
  195.     move.l  -4(a0,d1),d3    ; get odd_word
  196.     and.l   #$55555555,d3   ; drop clocks
  197.     eor.l   d3,d4           ; update checksum
  198.     or.l    d3,d2           ; combine words
  199.     move.l  d2,(a1)+        ; save results
  200.  
  201. 2$:
  202.     dbra    d0,1$           ; count words
  203.     add.l   d1,a0           ; update pointer
  204.     move.l  d4,d0           ; put checksum in result reg
  205.     movem.l (sp)+,d2-d4     ; restore working regs
  206.     rts                     ; go back where you belong
  207. ;
  208.  
  209. Usually disks are decoded as MFM and standard sync word is used.  There is no
  210. actual reason for this, but it is so.
  211.  
  212.  
  213.  
  214. {2{A                            O T H E R   T O P I C S
  215.  
  216. {1    Length of a normal track is;
  217.  
  218.         2   (zeros)
  219.         2   (syncs)
  220.         4   (header)
  221.        16   (zeros)
  222.         4   (header checksum)
  223.         4   (data checksum)
  224.      +512   (data)
  225.      ----
  226.       544 bytes (sector)
  227.      * 11   (sector count)
  228.      ----
  229.      5984 bytes (normally)
  230.      *  2   ( factor from MFM-decode)
  231.     -----
  232.     11968 bytes in MFM
  233.  
  234.  As each track is circular, between track end and track start there is gap,
  235.  which is usually about 670 bytes.
  236.  
  237.  
  238. Normal variations to normal track format are;
  239.  
  240.  
  241.               S I N G L E   S E C T O R
  242.  Track contains only one sector. Length of sector is about 11968, so it
  243.  must be correctly found in order to copy it.
  244.  
  245.               N O N   E M P T Y   G A P
  246.  Normally the gap is empty, but somebody may store some id data on it.
  247.  
  248.                   L O N G   T R A C K
  249.  More data than normally is put into the track.  Length of data is more
  250.  than 11968 + gap.  It is (oficially) impossible write these kind of disks
  251.  on the Amiga (without extra hardware), but the Amiga is able to read them.
  252.  Some other variations also exist and more are to come.  With visual mode,
  253.  it is possible to look at a track closely and analyze its contents (in
  254.  your head).
  255.  
  256. Normal track usually looks as follows:
  257.  
  258.     (end of track)(gap)(track)(gap)
  259.     (start of track)
  260.  
  261.  In order to copy this correctly, end  of write should be positioned on the
  262.  latter gap. As we read little more than two track lengths into the buffer,
  263.  we ensure that track is in buffer at least once. What we need to find 
  264.  is the position where the write originally terminated and use the same 
  265.  position. Sounds simple, but for normal track do the following;
  266.  
  267.  At the beginning, you are positioned at the last sync on the buffer.  You
  268.  know the thing here: Position and alignment.
  269.  Search the syncs towards the start, until the alignment changes.  This
  270.  usually means that you have just passed the gap.
  271.  
  272.  Move back to the previous sync (alignment changes back) and put an
  273.  end of write about 100 bytes before sync.
  274.  Sometimes alignment stays the same for all syncs. This means that the length
  275.  of physical track happens to be an even multiple of 8 (not too likely).
  276.  You must recognize the gap from the destination between two consecutive
  277.  syncs.  Track syncs are about 1088 bytes from each other and a longer
  278.  distance means a gap.
  279.  
  280.  This all applies to normal tracks, but usually you don't need to copy normal
  281.  tracks with visual mode.  On some disks, when dirty gaps are used, you
  282.  should recognize gap and decide how to copy it correctly.
  283.  Also, if index sync is needed, you should usually use visual mode.
  284.  
  285.  Always write a whole track (writing less than about 12500 bytes may leave
  286.  some old contents visible).  A track is circular, don't forget it.  When
  287.  writing more than about 12500 bytes, the last written stuff overwrites the
  288.  first written data.  This is usually wanted, because we normally write:
  289.  
  290.     (pregap)(track)(postgap)
  291.  
  292.  where pregap is partly overwritten with postgap.  We don't exactly know
  293.  how much, because of variations in drive speeds etc.
  294.