home *** CD-ROM | disk | FTP | other *** search
- (c) Copyright 1989-1999 Amiga, Inc. All rights reserved.
- The information contained herein is subject to change without notice, and
- is provided "as is" without warranty of any kind, either expressed or implied.
- The entire risk as to the use of this information is assumed by the user.
-
-
-
- Notes on 1.2 Amiga Trackdisk Format
-
- Carolyn Scheppner and Andy Finkel
-
-
- The following notes provide some detailed information on the format of
- a 3.5" floppy under the current AmigaDOS 1.2 filing system. These notes
- are for informational purposes only and relate only to the layout under the
- current filing system. The structures and layout are private, and are
- subject to change in the future. In other words, if you write your own
- Format code, or use any part of these structures or blocks for your own
- purposes, or make any other assumptions based on the current layout, there
- is a good chance that you will be incompatible with future filing system
- enhancements. Future enhancements may support additional formats or use
- some of the currently unused areas in the reserved blocks.
-
- Other information about the current disk layout can be found in the Amiga
- manuals. The format of directory, file header, file list, and data blocks is
- discussed in the AmigaDOS Manual (Bantam). A description of Amiga MFM encoding
- can be found on pages C9-C10 of the ROM Kernel Exec manual (Addison-Wesley).
-
-
- 1) ROOT BLOCK
-
- The Root block is normally in the middle of the disk halfway through the
- blocks. On a 3.5" floppy, this is block 880 (track 40, sector 0, first
- surface).
-
-
- /* Rootblock structure (private)
- * Copyright (c) 1985-1999 Amiga, Inc. All Rights Reserved
- */
-
- #define WORDSPERBLOCK 128 /* NOTE - WORDS means LONGWORDS
- (BCPLese) */
- #define HASHSIZE (WORDSPERBLOCK - 56)
- #define NUMBMPAGES 26
-
- struct RootBlock {
- ULONG rb_Type; /* type */
- ULONG rb_HeaderKey; /* header key (always zero) */
- ULONG rb_HighSeqNum; /* highest sequence number (always 0) */
- ULONG rb_HashSize; /* hash size (= BLOCKSIZE-56)*/
- ULONG rb_Reserved; /* reserved */
- ULONG rb_CheckSum; /* checksum */
- ULONG rb_HashTable[HASHSIZE]; /* hash table */
- ULONG rb_BMFlag; /* TRUE if Bitmap on disk is valid */
- ULONG rb_BitMapPages[NUMBMPAGES]; /* indicates blocks containing bitmap */
- struct DateStamp rb_LastDate; /* volume last altered date and time */
- UBYTE rb_DiskName[13*4]; /* volume name BCPL string <= 30 chars*/
- struct DateStamp rb_CreateDate; /* volume creation date and time */
- ULONG rb_HashChain; /* next entry in the hash chain (always zero)*/
- ULONG rb_Parent; /* parent directory (always zero) */
- ULONG rb_Extension; /* extension (always zero) */
- ULONG rb_SecondaryType; /* secondary type indicates root block*/
- };
-
-
- When an Amiga 3.5" diskette is formatted, the Format command sets up
- a new Root block. Format sets up the RootBlock and BitMap block in a ram
- buffer, then writes them to the disk as block 880 and 881. First it
- sets up the RootBlock by clearing the first 128 longwords of the buffer to
- zero, then initializing the following RootBlock fields (start of RootBlock
- structure is start of buffer):
-
- rb_Type = T_SHORT; /* T_SHORT = 2 */
- rb_HashSize = HASHSIZE; /* defined above */
- rb_SecondaryType = ST_ROOT; /* ST_ROOT = 1 */
- DateStamp(&rb_CreateDate); /* Set up the CreateDate first */
- DateStamp(&rb_LastDate); /* Then the LastDate */
-
- /* Format puts the initial BitMap block right after the RootBlock
- * This value is calculated as follows for 3.5" Amiga disk:
- * (((BlocksPerCyl * N_Cyl) - 1 + N_ResBlocks) / 2) + 1
- * ((( 22 * 80 ) - 1 + 2 ) / 2) + 1 = 881
- */
-
- rb_BitMapPages[0] = 881; /* Where format places BitMap block */
-
- rb_BMFlag = TRUE /* BitMap valid */
-
- The disk name is copied to &rb_DiskName[1], and rb_DiskName[0] is
- set to the length of the name (BCPL string).
-
- Then the 128 longword buffer is summed and the CheckSum is set to 0-sum.
-
- rb_CheckSum = 0 - sum;
-
- Then Format sets up the second 128 longwords of its buffer as the BitMap
- block as described below, and writes both block to the disk.
-
-
- 2) BITMAP
-
- Format places the initial BitMap block right after the RootBlock.
- On a 3.5" floppy, the RootBlock is placed at block 880, and the
- initial BitMap block at 881.
-
- The first longword is the checksum of the Bitmap block. This is
- calculated in the same way as the RootBlock checksum.
-
- The second longword is the start of the BitMap, with the LSB representing
- the first unreserved block on the disk. On the 3.5" floppy, blocks 0 and 1
- are reserved as BootBlocks. So the LSB of the floppy's first BitMap longword
- represents block 2, the next bit represents block 3, etc. The bit is set
- to 1 if the block is free, and to 0 if the block is used.
-
- When setting up the BitMap block for a 3.5" floppy which has 1758
- unreserved blocks (blocks 2 through 1759), Format starts with 128 longwords
- set to zero. Starting at the second longword, it initializes 54 longwords
- to 0xffffffff (54 * 32 bits = 1728 blocks marked as unused), then sets
- the next longword to 0xffffffff >> 2 to mark the remaining 30 blocks as
- unused. It then clears the two bits representing blocks 880 and 881 to
- mark the RootBlock and BitMap block as used. Format then sums the 128
- longwords, places 0-sum in the initial CheckSum longword, and writes the
- RootBlock and the BitMap block to the disk.
-
-
- 3) BOOT BLOCKS
-
- Blocks 0 and 1 of the 3.5" floppy are reserved as BootBlocks.
- Block 0 of a Kickstart disk contains a BootBlock structure with a bb_id
- of "KICK". Blocks 1 through 512 contain the binary image of KickStart.
- Block 0 of a bootable DOS disk starts with a BootBlock structure with a
- bb_id of "DOS\0", followed currently by the boot code shown below, or
- alternate boot code in the case of some games.
-
- /* BootBlock definition: */
- struct BootBlock {
- UBYTE bb_id[4]; /* 4 character identifier */
- LONG bb_chksum; /* boot block checksum (balance) */
- LONG bb_dosblock; /* reserved for DOS patch */
- };
-
- #define BOOTSECTS 2 /* 1K bootstrap */
-
- #define BBID_DOS { 'D', 'O', 'S', '\0' }
- #define BBID_KICK { 'K', 'I', 'C', 'K' }
-
- #define BBNAME_DOS (('D'<<24)|('O'<<16)|('S'<<8))
- #define BBNAME_KICK (('K'<<24)|('I'<<16)|('C'<<8)|('K'))
-
- ************************************************************************
- *
- * Copyright (c) 1985-1999 Amiga, Inc. All Rights Reserved
- *
- * the disk resident bootstrap code. This code MUST be pc - relative.
- *
- * it is called with:
- *
- * A1 -- ptr to IOB to the disk (must be closed unless we return)
- * A6 -- sysbase
- *
- *
- * return value:
- * D0 -- failure code -- to be given to alert?
- * A0 -- if failure code is null, then A0 is address to jump to
- * (after bootstrap cleans up)
- *
- ************************************************************************
-
- INCLUDE 'exec/types.i'
- INCLUDE 'exec/resident.i'
- INCLUDE 'devices/bootblock.i'
-
- INCLUDE 'boot_rev.i'
-
- XREF _LVOFindResident
-
- abslabel:
- BBID_DOS ; magic number
- DC.L 0 ; checksum
- DC.L 0 ; dos starting block (unused)
-
- start:
- LEA dosname(PC),A1
- JSR _LVOFindResident(A6)
-
- TST.L D0
- BEQ.S nodos
-
-
- ;------ and let the strap call the dos
- MOVE.L D0,A0
- MOVE.L RT_INIT(A0),A0
- MOVEQ #0,D0
-
- start_end:
- RTS
-
- nodos:
- MOVEQ #-1,D0
- BRA.S start_end
-
- dosname:
- DC.B 'dos.library',0
- VSTRING
- DS.W 0
-
- END
-
-
-
- 4) HASH FUNCTION
-
- The hash function is applied to the name of a file or directory, and the
- resulting value provides an offset into the HashTable which contains either
- zero or a key to the first block on a chain linking blocks with the same
- hash value. Each block contains a name field which identifies it. The
- directory and file header block fields are described in the AmigaDOS manual.
-
-
- int HashName(str,hlen)
-
- char *str; /* The string to find the hash number for */
- int hlen; /* The length of the hash table */
-
- {
- char xchar;
- int i, result;
-
- result = strlen(str);
- for (i=0; i<strlen(str); i++) {
- if (isalpha(str[i])) xchar = toupper(str[i]);
- else xchar = str[i];
- result = ((result * 13) + xchar) & 0x7ff;
- }
- result = result % hlen;
- return(result);
- }
-
-
-
- 5) CHECKSUMS
-
- BLOCK CHECKSUM
- --------------
- The format of the actual file blocks is documented in the white DOS Technical
- Reference and the Bantam AmigaDOS manual. In these blocks the checksum is
- calculated as follows.
-
- Treat the 512 byte sector as an array of 128 signed 32 bit numbers. So
- a data block would be:
-
- Byte Address Long Word Data Block Format
-
- 0000 0 T.DATA
- 0004 1 Block Number of File Header
- 0008 2 Sequence Number
- 000C 3 Data Size
- 0010 4 Next Data Block
- 0014 5 CheckSum
- 0018 thru 01FF 6 - 127 Data Bytes [488]
-
- To calculate the checksum of this block set longword 5 to zero then
- add up all of the longwords in the block (0-127) ignoring any overflow.
- Now take that sum and invert it (eg sum = 0 - sum ) and save it in
- longword 5. You now have a valid data block.
-
-
- HEADER and SECTOR CHECKSUM
- ---------------------------
-
- In addition to the block checksum, there are two more checksums in each
- sector's header. There are a total of 16 encoded longwords in the header:
-
- 2 longwords of encoded mfm and sync codes (AAAA 4489)
- 2 longwords of encoded format, track#, sector#, sectors-to-end-write
- 8 longwords for encoded O/S recovery info
- 2 longwords for encoded header checksum
- 2 longwords for encoded data-area checksum
-
- The data-area checksum is a checksum only on the data and is computed on the
- encoded data in the sector. To calculate the data-area checksum, EOR the
- first longword with the second with the third, etc. Then AND with $55555555
- to get the checksum.
-
- For the header checksum, you take a long, and with $55555555, EOR with the
- next long and loop until you've gotten to the end of the OS recovery info.
- The EORs are done from the front of the header - the format longword - to
- the end of the OS recovery info. The first longword of mfm/sync code is
- not included. The checksum starts with the format longword.
-
-
-
-
-
-