home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / Amiga_Mail_Vol1 / Trackdisk / Notes1.2Track < prev   
Encoding:
Text File  |  1999-10-27  |  10.8 KB  |  295 lines

  1. (c)  Copyright 1989-1999 Amiga, Inc.   All rights reserved.
  2. The information contained herein is subject to change without notice, and 
  3. is provided "as is" without warranty of any kind, either expressed or implied.  
  4. The entire risk as to the use of this information is assumed by the user.
  5.  
  6.  
  7.  
  8.                      Notes on 1.2 Amiga Trackdisk Format 
  9.  
  10.                       Carolyn Scheppner and Andy Finkel
  11.  
  12.  
  13.    The following notes provide some detailed information on the format of
  14. a 3.5" floppy under the current AmigaDOS 1.2 filing system.  These notes
  15. are for informational purposes only and relate only to the layout under the
  16. current filing system.  The structures and layout are private, and are 
  17. subject to change in the future.  In other words, if you write your own
  18. Format code, or use any part of these structures or blocks for your own
  19. purposes, or make any other assumptions based on the current layout, there
  20. is a good chance that you will be incompatible with future filing system
  21. enhancements.  Future enhancements may support additional formats or use 
  22. some of the currently unused areas in the reserved blocks.
  23.  
  24.    Other information about the current disk layout can be found in the Amiga
  25. manuals.  The format of directory, file header, file list, and data blocks is
  26. discussed in the AmigaDOS Manual (Bantam).  A description of Amiga MFM encoding
  27. can be found on pages C9-C10 of the ROM Kernel Exec manual (Addison-Wesley).  
  28.  
  29.  
  30. 1)  ROOT BLOCK
  31.  
  32. The Root block is normally in the middle of the disk halfway through the 
  33. blocks.  On a 3.5" floppy, this is block 880 (track 40, sector 0, first 
  34. surface).
  35.  
  36.  
  37. /* Rootblock structure (private)
  38.  * Copyright (c) 1985-1999  Amiga, Inc.   All Rights Reserved 
  39.  */
  40.  
  41. #define WORDSPERBLOCK    128          /* NOTE - WORDS means LONGWORDS 
  42.                              (BCPLese) */
  43. #define HASHSIZE    (WORDSPERBLOCK - 56)
  44. #define NUMBMPAGES    26
  45.  
  46. struct RootBlock {
  47.     ULONG rb_Type;                    /* type */
  48.     ULONG rb_HeaderKey;                  /* header key (always zero) */
  49.     ULONG rb_HighSeqNum;              /* highest sequence number (always 0) */
  50.     ULONG rb_HashSize;                /* hash size (= BLOCKSIZE-56)*/
  51.     ULONG rb_Reserved;                /* reserved */
  52.     ULONG rb_CheckSum;                  /* checksum */
  53.     ULONG rb_HashTable[HASHSIZE];     /* hash table */
  54.     ULONG rb_BMFlag;              /* TRUE if Bitmap on disk is valid */
  55.     ULONG rb_BitMapPages[NUMBMPAGES]; /* indicates blocks containing bitmap */
  56.     struct DateStamp rb_LastDate;     /* volume last altered date and time */
  57.     UBYTE rb_DiskName[13*4];          /* volume name BCPL string <= 30 chars*/
  58.     struct DateStamp rb_CreateDate;   /* volume creation date and time */
  59.     ULONG rb_HashChain;      /* next entry in the hash chain (always zero)*/
  60.     ULONG rb_Parent;                  /* parent directory (always zero) */
  61.     ULONG rb_Extension;                  /* extension (always zero) */
  62.     ULONG rb_SecondaryType;           /* secondary type indicates root block*/
  63. };
  64.  
  65.  
  66.    When an Amiga 3.5" diskette is formatted, the Format command sets up
  67. a new Root block.  Format sets up the RootBlock and BitMap block in a ram
  68. buffer, then writes them to the disk as block 880 and 881.  First it
  69. sets up the RootBlock by clearing the first 128 longwords of the buffer to
  70. zero, then initializing the following RootBlock fields (start of RootBlock
  71. structure is start of buffer):
  72.  
  73.    rb_Type     = T_SHORT;        /* T_SHORT = 2 */
  74.    rb_HashSize = HASHSIZE;       /* defined above */
  75.    rb_SecondaryType = ST_ROOT;   /* ST_ROOT = 1 */
  76.    DateStamp(&rb_CreateDate);    /* Set up the CreateDate first */
  77.    DateStamp(&rb_LastDate);      /* Then the LastDate */
  78.  
  79.    /* Format puts the initial BitMap block right after the RootBlock
  80.     * This value is calculated as follows for 3.5" Amiga disk:
  81.     *   (((BlocksPerCyl * N_Cyl) - 1 + N_ResBlocks) / 2) + 1
  82.     *   (((    22       *  80  ) - 1 +      2     ) / 2) + 1  = 881
  83.     */
  84.  
  85.    rb_BitMapPages[0] = 881;      /* Where format places BitMap block */
  86.  
  87.    rb_BMFlag = TRUE              /* BitMap valid */
  88.    
  89.    The disk name is copied to &rb_DiskName[1], and rb_DiskName[0] is
  90.       set to the length of the name (BCPL string).
  91.  
  92.    Then the 128 longword buffer is summed and the CheckSum is set to 0-sum.
  93.  
  94.    rb_CheckSum = 0 - sum;
  95.  
  96.    Then Format sets up the second 128 longwords of its buffer as the BitMap
  97. block as described below, and writes both block to the disk.
  98.   
  99.    
  100. 2)  BITMAP
  101.  
  102.    Format places the initial BitMap block right after the RootBlock.  
  103. On a 3.5" floppy, the RootBlock is placed at block 880, and the
  104. initial BitMap block at 881.
  105.  
  106.    The first longword is the checksum of the Bitmap block.  This is 
  107. calculated in the same way as the RootBlock checksum.
  108.  
  109.    The second longword is the start of the BitMap, with the LSB representing
  110. the first unreserved block on the disk.  On the 3.5" floppy, blocks 0 and 1
  111. are reserved as BootBlocks.  So the LSB of the floppy's first BitMap longword
  112. represents block 2, the next bit represents block 3, etc.  The bit is set
  113. to 1 if the block is free, and to 0 if the block is used.
  114.  
  115.    When setting up the BitMap block for a 3.5" floppy which has 1758
  116. unreserved blocks (blocks 2 through 1759), Format starts with 128 longwords
  117. set to zero.  Starting at the second longword, it initializes 54 longwords
  118. to 0xffffffff (54 * 32 bits = 1728 blocks marked as unused), then sets
  119. the next longword to  0xffffffff >> 2 to mark the remaining 30 blocks as
  120. unused.  It then clears the two bits representing blocks 880 and 881 to
  121. mark the RootBlock and BitMap block as used.  Format then sums the 128
  122. longwords, places 0-sum in the initial CheckSum longword, and writes the
  123. RootBlock and the BitMap block to the disk.
  124.  
  125.  
  126. 3)  BOOT BLOCKS
  127.  
  128.    Blocks 0 and 1 of the 3.5" floppy are reserved as BootBlocks.  
  129. Block 0 of a Kickstart disk contains a BootBlock structure with a bb_id
  130. of "KICK".  Blocks 1 through 512 contain the binary image of KickStart.
  131. Block 0 of a bootable DOS disk starts with a BootBlock structure with a
  132. bb_id of "DOS\0", followed currently by the boot code shown below, or
  133. alternate boot code in the case of some games.
  134.  
  135. /* BootBlock definition: */
  136. struct BootBlock {
  137.    UBYTE   bb_id[4];      /* 4 character identifier */
  138.    LONG    bb_chksum;     /* boot block checksum (balance) */
  139.    LONG    bb_dosblock;   /* reserved for DOS patch */
  140. };
  141.  
  142. #define        BOOTSECTS    2    /* 1K bootstrap */
  143.  
  144. #define BBID_DOS    { 'D', 'O', 'S', '\0' }
  145. #define BBID_KICK    { 'K', 'I', 'C', 'K' }
  146.  
  147. #define BBNAME_DOS    (('D'<<24)|('O'<<16)|('S'<<8))
  148. #define BBNAME_KICK    (('K'<<24)|('I'<<16)|('C'<<8)|('K'))
  149.  
  150. ************************************************************************
  151. *
  152. * Copyright (c) 1985-1999  Amiga, Inc.   All Rights Reserved 
  153. *
  154. * the disk resident bootstrap code.  This code MUST be pc - relative.
  155. *
  156. * it is called with:
  157. *
  158. *       A1 -- ptr to IOB to the disk (must be closed unless we return)
  159. *       A6 -- sysbase
  160. *
  161. *
  162. * return value:
  163. *       D0 -- failure code -- to be given to alert?
  164. *       A0 -- if failure code is null, then A0 is address to jump to
  165. *               (after bootstrap cleans up)
  166. *
  167. ************************************************************************
  168.  
  169.         INCLUDE 'exec/types.i'
  170.         INCLUDE 'exec/resident.i'
  171.         INCLUDE 'devices/bootblock.i'
  172.  
  173.         INCLUDE 'boot_rev.i'
  174.  
  175.         XREF    _LVOFindResident
  176.  
  177. abslabel:
  178.                 BBID_DOS                ; magic number
  179.                 DC.L    0               ; checksum
  180.                 DC.L    0               ; dos starting block (unused)
  181.  
  182. start:
  183.                 LEA     dosname(PC),A1
  184.                 JSR     _LVOFindResident(A6)
  185.  
  186.                 TST.L   D0
  187.                 BEQ.S   nodos
  188.  
  189.  
  190.                 ;------ and let the strap call the dos
  191.                 MOVE.L  D0,A0
  192.                 MOVE.L  RT_INIT(A0),A0
  193.                 MOVEQ   #0,D0
  194.  
  195. start_end:
  196.                 RTS
  197.  
  198. nodos:
  199.                 MOVEQ   #-1,D0
  200.                 BRA.S   start_end
  201.  
  202. dosname:
  203.                 DC.B    'dos.library',0
  204.                 VSTRING
  205.                 DS.W    0
  206.  
  207.                 END
  208.  
  209.  
  210.  
  211. 4)  HASH FUNCTION
  212.  
  213.    The hash function is applied to the name of a file or directory, and the
  214. resulting value provides an offset into the HashTable which contains either
  215. zero or a key to the first block on a chain linking blocks with the same
  216. hash value.  Each block contains a name field which identifies it.  The
  217. directory and file header block fields are described in the AmigaDOS manual.
  218.  
  219.  
  220. int HashName(str,hlen)
  221.  
  222. char    *str;           /* The string to find the hash number for       */
  223. int     hlen;           /* The length of the hash table                 */
  224.  
  225. {
  226.   char  xchar;
  227.   int   i, result;
  228.  
  229.   result = strlen(str);
  230.   for (i=0; i<strlen(str); i++) {
  231.     if (isalpha(str[i])) xchar = toupper(str[i]);
  232.     else xchar = str[i];
  233.     result = ((result * 13) + xchar) & 0x7ff;
  234.   }
  235.   result = result % hlen;
  236.   return(result);
  237. }
  238.  
  239.  
  240.  
  241. 5)  CHECKSUMS
  242.  
  243. BLOCK CHECKSUM
  244. --------------
  245. The format of the actual file blocks is documented in the white DOS Technical 
  246. Reference and the Bantam AmigaDOS manual.  In these blocks the checksum is 
  247. calculated as follows.
  248.  
  249. Treat the 512 byte sector as an array of 128 signed 32 bit numbers. So
  250. a data block would be:
  251.  
  252. Byte Address            Long Word       Data Block Format
  253.  
  254. 0000                    0               T.DATA
  255. 0004                    1               Block Number of File Header
  256. 0008                    2               Sequence Number
  257. 000C                    3               Data Size
  258. 0010                    4               Next Data Block
  259. 0014                    5               CheckSum
  260. 0018 thru 01FF          6 - 127         Data Bytes [488]
  261.  
  262. To calculate the checksum of this block set longword 5 to zero then
  263. add up all of the longwords in the block (0-127) ignoring any overflow. 
  264. Now take that sum and invert it (eg sum = 0 - sum ) and save it in 
  265. longword 5.  You now have a valid data block.
  266.  
  267.  
  268. HEADER and SECTOR CHECKSUM
  269. ---------------------------
  270.  
  271. In addition to the block checksum, there are two more checksums in each
  272. sector's header.  There are a total of 16 encoded longwords in the header:
  273.  
  274.    2 longwords of encoded mfm and sync codes (AAAA  4489)
  275.    2 longwords of encoded format, track#, sector#, sectors-to-end-write 
  276.    8 longwords for encoded O/S recovery info
  277.    2 longwords for encoded header checksum
  278.    2 longwords for encoded data-area checksum
  279.  
  280. The data-area checksum is a checksum only on the data and is computed on the 
  281. encoded data in the sector.  To calculate the data-area checksum, EOR the 
  282. first longword with the second with the third, etc.  Then AND with $55555555 
  283. to get the checksum.
  284.  
  285. For the header checksum, you take a long, and with $55555555, EOR with the 
  286. next long and loop until you've gotten to the end of the OS recovery info.  
  287. The EORs are done from the front of the header - the format longword - to
  288. the end of the OS recovery info.  The first longword of mfm/sync code is 
  289. not included.   The checksum starts with the format longword.
  290.  
  291.  
  292.  
  293.  
  294.  
  295.