[9] | 1 | #ifndef MTOOLS_MSDOS_H
|
---|
| 2 | #define MTOOLS_MSDOS_H
|
---|
| 3 |
|
---|
| 4 | /*
|
---|
| 5 | * msdos common header file
|
---|
| 6 | */
|
---|
| 7 |
|
---|
| 8 | #define MAX_SECTOR 8192 /* largest sector size */
|
---|
| 9 | #define MDIR_SIZE 32 /* MSDOS directory entry size in bytes*/
|
---|
| 10 | #define MAX_CLUSTER 8192 /* largest cluster size */
|
---|
| 11 | #define MAX_PATH 128 /* largest MSDOS path length */
|
---|
| 12 | #define MAX_DIR_SECS 64 /* largest directory (in sectors) */
|
---|
| 13 | #define MSECTOR_SIZE msector_size
|
---|
| 14 |
|
---|
| 15 | #define NEW 1
|
---|
| 16 | #define OLD 0
|
---|
| 17 |
|
---|
| 18 | #define _WORD(x) ((unsigned char)(x)[0] + (((unsigned char)(x)[1]) << 8))
|
---|
| 19 | #define _DWORD(x) (_WORD(x) + (_WORD((x)+2) << 16))
|
---|
| 20 |
|
---|
| 21 | #define DELMARK ((char) 0xe5)
|
---|
| 22 |
|
---|
| 23 | struct directory {
|
---|
| 24 | char name[8]; /* 0 file name */
|
---|
| 25 | char ext[3]; /* 8 file extension */
|
---|
| 26 | unsigned char attr; /* 11 attribute byte */
|
---|
| 27 | unsigned char Case; /* 12 case of short filename */
|
---|
| 28 | unsigned char ctime_ms; /* 13 creation time, milliseconds (?) */
|
---|
| 29 | unsigned char ctime[2]; /* 14 creation time */
|
---|
| 30 | unsigned char cdate[2]; /* 16 creation date */
|
---|
| 31 | unsigned char adate[2]; /* 18 last access date */
|
---|
| 32 | unsigned char startHi[2]; /* 20 start cluster, Hi */
|
---|
| 33 | unsigned char time[2]; /* 22 time stamp */
|
---|
| 34 | unsigned char date[2]; /* 24 date stamp */
|
---|
| 35 | unsigned char start[2]; /* 26 starting cluster number */
|
---|
| 36 | unsigned char size[4]; /* 28 size of the file */
|
---|
| 37 | };
|
---|
| 38 |
|
---|
| 39 | #define EXTCASE 0x10
|
---|
| 40 | #define BASECASE 0x8
|
---|
| 41 |
|
---|
| 42 | #define MAX32 0xffffffff
|
---|
| 43 | #define MAX_SIZE 0x7fffffff
|
---|
| 44 |
|
---|
| 45 | #define FILE_SIZE(dir) (_DWORD((dir)->size))
|
---|
| 46 | #define START(dir) (_WORD((dir)->start))
|
---|
| 47 | #define STARTHI(dir) (_WORD((dir)->startHi))
|
---|
| 48 |
|
---|
| 49 | /* ASSUMPTION: long is at least 32 bits */
|
---|
| 50 | UNUSED(static inline void set_dword(unsigned char *data, unsigned long value))
|
---|
| 51 | {
|
---|
| 52 | data[3] = (value >> 24) & 0xff;
|
---|
| 53 | data[2] = (value >> 16) & 0xff;
|
---|
| 54 | data[1] = (value >> 8) & 0xff;
|
---|
| 55 | data[0] = (value >> 0) & 0xff;
|
---|
| 56 | }
|
---|
| 57 |
|
---|
| 58 |
|
---|
| 59 | /* ASSUMPTION: short is at least 16 bits */
|
---|
| 60 | UNUSED(static inline void set_word(unsigned char *data, unsigned short value))
|
---|
| 61 | {
|
---|
| 62 | data[1] = (value >> 8) & 0xff;
|
---|
| 63 | data[0] = (value >> 0) & 0xff;
|
---|
| 64 | }
|
---|
| 65 |
|
---|
| 66 |
|
---|
| 67 | /*
|
---|
| 68 | * hi byte | low byte
|
---|
| 69 | * |7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
|
---|
| 70 | * | | | | | | | | | | | | | | | | |
|
---|
| 71 | * \ 7 bits /\4 bits/\ 5 bits /
|
---|
| 72 | * year +80 month day
|
---|
| 73 | */
|
---|
| 74 | #define DOS_YEAR(dir) (((dir)->date[1] >> 1) + 1980)
|
---|
| 75 | #define DOS_MONTH(dir) (((((dir)->date[1]&0x1) << 3) + ((dir)->date[0] >> 5)))
|
---|
| 76 | #define DOS_DAY(dir) ((dir)->date[0] & 0x1f)
|
---|
| 77 |
|
---|
| 78 | /*
|
---|
| 79 | * hi byte | low byte
|
---|
| 80 | * |7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
|
---|
| 81 | * | | | | | | | | | | | | | | | | |
|
---|
| 82 | * \ 5 bits /\ 6 bits /\ 5 bits /
|
---|
| 83 | * hour minutes sec*2
|
---|
| 84 | */
|
---|
| 85 | #define DOS_HOUR(dir) ((dir)->time[1] >> 3)
|
---|
| 86 | #define DOS_MINUTE(dir) (((((dir)->time[1]&0x7) << 3) + ((dir)->time[0] >> 5)))
|
---|
| 87 | #define DOS_SEC(dir) (((dir)->time[0] & 0x1f) * 2)
|
---|
| 88 |
|
---|
| 89 |
|
---|
| 90 | typedef struct InfoSector_t {
|
---|
| 91 | unsigned char signature1[4];
|
---|
| 92 | unsigned char filler1[0x1e0];
|
---|
| 93 | unsigned char signature2[4];
|
---|
| 94 | unsigned char count[4];
|
---|
| 95 | unsigned char pos[4];
|
---|
| 96 | unsigned char filler2[14];
|
---|
| 97 | unsigned char signature3[2];
|
---|
| 98 | } InfoSector_t;
|
---|
| 99 |
|
---|
| 100 | #define INFOSECT_SIGNATURE1 0x41615252
|
---|
| 101 | #define INFOSECT_SIGNATURE2 0x61417272
|
---|
| 102 |
|
---|
| 103 |
|
---|
| 104 | typedef struct label_blk_t {
|
---|
| 105 | unsigned char physdrive; /* 36 physical drive ? */
|
---|
| 106 | unsigned char reserved; /* 37 reserved */
|
---|
| 107 | unsigned char dos4; /* 38 dos > 4.0 diskette */
|
---|
| 108 | unsigned char serial[4]; /* 39 serial number */
|
---|
| 109 | char label[11]; /* 43 disk label */
|
---|
| 110 | char fat_type[8]; /* 54 FAT type */
|
---|
| 111 | } label_blk_t;
|
---|
| 112 |
|
---|
| 113 | /* FAT32 specific info in the bootsector */
|
---|
| 114 | typedef struct fat32_t {
|
---|
| 115 | unsigned char bigFat[4]; /* 36 nb of sectors per FAT */
|
---|
| 116 | unsigned char extFlags[2]; /* 40 extension flags */
|
---|
| 117 | unsigned char fsVersion[2]; /* 42 ? */
|
---|
| 118 | unsigned char rootCluster[4]; /* 44 start cluster of root dir */
|
---|
| 119 | unsigned char infoSector[2]; /* 48 changeable global info */
|
---|
| 120 | unsigned char backupBoot[2]; /* 50 back up boot sector */
|
---|
| 121 | unsigned char reserved[6]; /* 52 ? */
|
---|
| 122 | unsigned char reserved2[6]; /* 52 ? */
|
---|
| 123 | struct label_blk_t labelBlock;
|
---|
| 124 | } fat32; /* ends at 58 */
|
---|
| 125 |
|
---|
| 126 | typedef struct oldboot_t {
|
---|
| 127 | struct label_blk_t labelBlock;
|
---|
| 128 | unsigned char res_2m; /* 62 reserved by 2M */
|
---|
| 129 | unsigned char CheckSum; /* 63 2M checksum (not used) */
|
---|
| 130 | unsigned char fmt_2mf; /* 64 2MF format version */
|
---|
| 131 | unsigned char wt; /* 65 1 if write track after format */
|
---|
| 132 | unsigned char rate_0; /* 66 data transfer rate on track 0 */
|
---|
| 133 | unsigned char rate_any; /* 67 data transfer rate on track<>0 */
|
---|
| 134 | unsigned char BootP[2]; /* 68 offset to boot program */
|
---|
| 135 | unsigned char Infp0[2]; /* 70 T1: information for track 0 */
|
---|
| 136 | unsigned char InfpX[2]; /* 72 T2: information for track<>0 */
|
---|
| 137 | unsigned char InfTm[2]; /* 74 T3: track sectors size table */
|
---|
| 138 | unsigned char DateF[2]; /* 76 Format date */
|
---|
| 139 | unsigned char TimeF[2]; /* 78 Format time */
|
---|
| 140 | unsigned char junk[1024 - 80]; /* 80 remaining data */
|
---|
| 141 | } oldboot_t;
|
---|
| 142 |
|
---|
| 143 | struct bootsector {
|
---|
| 144 | unsigned char jump[3]; /* 0 Jump to boot code */
|
---|
| 145 | char banner[8] PACKED; /* 3 OEM name & version */
|
---|
| 146 | unsigned char secsiz[2] PACKED; /* 11 Bytes per sector hopefully 512 */
|
---|
| 147 | unsigned char clsiz; /* 13 Cluster size in sectors */
|
---|
| 148 | unsigned char nrsvsect[2]; /* 14 Number of reserved (boot) sectors */
|
---|
| 149 | unsigned char nfat; /* 16 Number of FAT tables hopefully 2 */
|
---|
| 150 | unsigned char dirents[2] PACKED;/* 17 Number of directory slots */
|
---|
| 151 | unsigned char psect[2] PACKED; /* 19 Total sectors on disk */
|
---|
| 152 | unsigned char descr; /* 21 Media descriptor=first byte of FAT */
|
---|
| 153 | unsigned char fatlen[2]; /* 22 Sectors in FAT */
|
---|
| 154 | unsigned char nsect[2]; /* 24 Sectors/track */
|
---|
| 155 | unsigned char nheads[2]; /* 26 Heads */
|
---|
| 156 | unsigned char nhs[4]; /* 28 number of hidden sectors */
|
---|
| 157 | unsigned char bigsect[4]; /* 32 big total sectors */
|
---|
| 158 |
|
---|
| 159 | union {
|
---|
| 160 | struct fat32_t fat32;
|
---|
| 161 | struct oldboot_t old;
|
---|
| 162 | } ext;
|
---|
| 163 | };
|
---|
| 164 |
|
---|
| 165 | #define CHAR(x) (boot->x[0])
|
---|
| 166 | #define WORD(x) (_WORD(boot->x))
|
---|
| 167 | #define DWORD(x) (_DWORD(boot->x))
|
---|
| 168 | #define OFFSET(x) (((char *) (boot->x)) - ((char *)(boot->jump)))
|
---|
| 169 |
|
---|
| 170 |
|
---|
| 171 | extern struct OldDos_t {
|
---|
| 172 | int tracks;
|
---|
| 173 | int sectors;
|
---|
| 174 | int heads;
|
---|
| 175 |
|
---|
| 176 | int dir_len;
|
---|
| 177 | int cluster_size;
|
---|
| 178 | int fat_len;
|
---|
| 179 |
|
---|
| 180 | int media;
|
---|
| 181 | } old_dos[];
|
---|
| 182 |
|
---|
| 183 | #define FAT12 4085 /* max. number of clusters described by a 12 bit FAT */
|
---|
| 184 | #define FAT16 65525
|
---|
| 185 |
|
---|
| 186 | #define ATTR_ARCHIVE 0x20
|
---|
| 187 | #define ATTR_DIR 0x10
|
---|
| 188 | #define ATTR_LABEL 0x8
|
---|
| 189 | #define ATTR_SYSTEM 0x4
|
---|
| 190 | #define ATTR_HIDDEN 0x2
|
---|
| 191 | #define ATTR_READONLY 0x1
|
---|
| 192 |
|
---|
| 193 | #define HAS_BIT(entry,x) ((entry)->dir.attr & (x))
|
---|
| 194 |
|
---|
| 195 | #define IS_ARCHIVE(entry) (HAS_BIT((entry),ATTR_ARCHIVE))
|
---|
| 196 | #define IS_DIR(entry) (HAS_BIT((entry),ATTR_DIR))
|
---|
| 197 | #define IS_LABEL(entry) (HAS_BIT((entry),ATTR_LABEL))
|
---|
| 198 | #define IS_SYSTEM(entry) (HAS_BIT((entry),ATTR_SYSTEM))
|
---|
| 199 | #define IS_HIDDEN(entry) (HAS_BIT((entry),ATTR_HIDDEN))
|
---|
| 200 | #define IS_READONLY(entry) (HAS_BIT((entry),ATTR_READONLY))
|
---|
| 201 |
|
---|
| 202 |
|
---|
| 203 | #define MAX_SECT_PER_CLUSTER 64
|
---|
| 204 | /* Experimentally, it turns out that DOS only accepts cluster sizes
|
---|
| 205 | * which are powers of two, and less than 128 sectors (else it gets a
|
---|
| 206 | * divide overflow) */
|
---|
| 207 |
|
---|
| 208 |
|
---|
| 209 | #define FAT_SIZE(bits, sec_siz, clusters) \
|
---|
| 210 | ((((clusters)+2) * ((bits)/4) - 1) / 2 / (sec_siz) + 1)
|
---|
| 211 |
|
---|
| 212 | #define NEEDED_FAT_SIZE(x) FAT_SIZE((x)->fat_bits, (x)->sector_size, \
|
---|
| 213 | (x)->num_clus)
|
---|
| 214 |
|
---|
| 215 | /* disk size taken by FAT and clusters */
|
---|
| 216 | #define DISK_SIZE(bits, sec_siz, clusters, n, cluster_size) \
|
---|
| 217 | ((n) * FAT_SIZE(bits, sec_siz, clusters) + \
|
---|
| 218 | (clusters) * (cluster_size))
|
---|
| 219 |
|
---|
| 220 | #define TOTAL_DISK_SIZE(bits, sec_siz, clusters, n, cluster_size) \
|
---|
| 221 | (DISK_SIZE(bits, sec_siz, clusters, n, cluster_size) + 2)
|
---|
| 222 | /* approx. total disk size: assume 1 boot sector and one directory sector */
|
---|
| 223 |
|
---|
| 224 | extern const char *mversion;
|
---|
| 225 | extern const char *mdate;
|
---|
| 226 |
|
---|
| 227 | extern char *Version;
|
---|
| 228 | extern char *Date;
|
---|
| 229 |
|
---|
| 230 |
|
---|
| 231 | int init(char drive, int mode);
|
---|
| 232 |
|
---|
| 233 | #define MT_READ 1
|
---|
| 234 | #define MT_WRITE 2
|
---|
| 235 |
|
---|
| 236 | #endif
|
---|
| 237 |
|
---|