wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 1 | /* |
| 2 | * (C) Copyright 2002 |
| 3 | * Stäubli Faverges - <www.staubli.com> |
| 4 | * Pierre AUBERT p.aubert@staubli.com |
| 5 | * |
| 6 | * See file CREDITS for list of people who contributed to this |
| 7 | * project. |
| 8 | * |
| 9 | * This program is free software; you can redistribute it and/or |
| 10 | * modify it under the terms of the GNU General Public License as |
| 11 | * published by the Free Software Foundation; either version 2 of |
| 12 | * the License, or (at your option) any later version. |
| 13 | * |
| 14 | * This program is distributed in the hope that it will be useful, |
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 17 | * GNU General Public License for more details. |
| 18 | * |
| 19 | * You should have received a copy of the GNU General Public License |
| 20 | * along with this program; if not, write to the Free Software |
| 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
| 22 | * MA 02111-1307 USA |
| 23 | */ |
| 24 | |
| 25 | #include <common.h> |
| 26 | #include <config.h> |
| 27 | |
| 28 | #include "dos.h" |
| 29 | #include "fdos.h" |
| 30 | |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 31 | #define NB_HEADS 2 |
| 32 | #define NB_TRACKS 80 |
| 33 | #define NB_SECTORS 18 |
| 34 | |
| 35 | |
| 36 | static int lastwhere; |
| 37 | |
| 38 | /*----------------------------------------------------------------------------- |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 39 | * dev_open -- |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 40 | *----------------------------------------------------------------------------- |
| 41 | */ |
| 42 | int dev_open (void) |
| 43 | { |
| 44 | lastwhere = 0; |
| 45 | return (0); |
| 46 | } |
| 47 | |
| 48 | /*----------------------------------------------------------------------------- |
| 49 | * dev_read -- len and where are sectors number |
| 50 | *----------------------------------------------------------------------------- |
| 51 | */ |
| 52 | int dev_read (void *buffer, int where, int len) |
| 53 | { |
| 54 | PRINTF ("dev_read (len = %d, where = %d)\n", len, where); |
| 55 | |
| 56 | /* Si on ne desire pas lire a la position courante, il faut un seek */ |
| 57 | if (where != lastwhere) { |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 58 | if (!fdc_fdos_seek (where)) { |
| 59 | PRINTF ("seek error in dev_read"); |
| 60 | lastwhere = -1; |
| 61 | return (-1); |
| 62 | } |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 63 | } |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 64 | |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 65 | if (!fdc_fdos_read (buffer, len)) { |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 66 | PRINTF ("read error\n"); |
| 67 | lastwhere = -1; |
| 68 | return (-1); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 69 | } |
| 70 | lastwhere = where + len; |
| 71 | return (0); |
| 72 | } |
| 73 | /*----------------------------------------------------------------------------- |
| 74 | * check_dev -- verify the diskette format |
| 75 | *----------------------------------------------------------------------------- |
| 76 | */ |
| 77 | int check_dev (BootSector_t *boot, Fs_t *fs) |
| 78 | { |
| 79 | unsigned int heads, sectors, tracks; |
| 80 | int BootP, Infp0, InfpX, InfTm; |
| 81 | int sect_per_track; |
| 82 | |
| 83 | /* Display Boot header */ |
| 84 | PRINTF ("Jump to boot code 0x%02x 0x%02x 0x%02x\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 85 | boot -> jump [0], boot -> jump [1], boot -> jump[2]); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 86 | PRINTF ("OEM name & version '%*.*s'\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 87 | BANNER_LG, BANNER_LG, boot -> banner ); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 88 | PRINTF ("Bytes per sector hopefully 512 %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 89 | __le16_to_cpu (boot -> secsiz)); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 90 | PRINTF ("Cluster size in sectors %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 91 | boot -> clsiz); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 92 | PRINTF ("Number of reserved (boot) sectors %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 93 | __le16_to_cpu (boot -> nrsvsect)); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 94 | PRINTF ("Number of FAT tables hopefully 2 %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 95 | boot -> nfat); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 96 | PRINTF ("Number of directory slots %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 97 | __le16_to_cpu (boot -> dirents)); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 98 | PRINTF ("Total sectors on disk %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 99 | __le16_to_cpu (boot -> psect)); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 100 | PRINTF ("Media descriptor=first byte of FAT %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 101 | boot -> descr); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 102 | PRINTF ("Sectors in FAT %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 103 | __le16_to_cpu (boot -> fatlen)); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 104 | PRINTF ("Sectors/track %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 105 | __le16_to_cpu (boot -> nsect)); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 106 | PRINTF ("Heads %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 107 | __le16_to_cpu (boot -> nheads)); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 108 | PRINTF ("number of hidden sectors %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 109 | __le32_to_cpu (boot -> nhs)); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 110 | PRINTF ("big total sectors %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 111 | __le32_to_cpu (boot -> bigsect)); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 112 | PRINTF ("physical drive ? %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 113 | boot -> physdrive); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 114 | PRINTF ("reserved %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 115 | boot -> reserved); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 116 | PRINTF ("dos > 4.0 diskette %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 117 | boot -> dos4); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 118 | PRINTF ("serial number %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 119 | __le32_to_cpu (boot -> serial)); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 120 | PRINTF ("disk label %*.*s\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 121 | LABEL_LG, LABEL_LG, boot -> label); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 122 | PRINTF ("FAT type %8.8s\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 123 | boot -> fat_type); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 124 | PRINTF ("reserved by 2M %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 125 | boot -> res_2m); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 126 | PRINTF ("2M checksum (not used) %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 127 | boot -> CheckSum); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 128 | PRINTF ("2MF format version %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 129 | boot -> fmt_2mf); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 130 | PRINTF ("1 if write track after format %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 131 | boot -> wt); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 132 | PRINTF ("data transfer rate on track 0 %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 133 | boot -> rate_0); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 134 | PRINTF ("data transfer rate on track<>0 %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 135 | boot -> rate_any); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 136 | PRINTF ("offset to boot program %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 137 | __le16_to_cpu (boot -> BootP)); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 138 | PRINTF ("T1: information for track 0 %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 139 | __le16_to_cpu (boot -> Infp0)); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 140 | PRINTF ("T2: information for track<>0 %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 141 | __le16_to_cpu (boot -> InfpX)); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 142 | PRINTF ("T3: track sectors size table %d\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 143 | __le16_to_cpu (boot -> InfTm)); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 144 | PRINTF ("Format date 0x%04x\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 145 | __le16_to_cpu (boot -> DateF)); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 146 | PRINTF ("Format time 0x%04x\n", |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 147 | __le16_to_cpu (boot -> TimeF)); |
| 148 | |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 149 | |
wdenk | 47cd00f | 2003-03-06 13:39:27 +0000 | [diff] [blame] | 150 | /* information is extracted from boot sector */ |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 151 | heads = __le16_to_cpu (boot -> nheads); |
| 152 | sectors = __le16_to_cpu (boot -> nsect); |
| 153 | fs -> tot_sectors = __le32_to_cpu (boot -> bigsect); |
| 154 | if (__le16_to_cpu (boot -> psect) != 0) { |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 155 | fs -> tot_sectors = __le16_to_cpu (boot -> psect); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 156 | } |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 157 | |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 158 | sect_per_track = heads * sectors; |
| 159 | tracks = (fs -> tot_sectors + sect_per_track - 1) / sect_per_track; |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 160 | |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 161 | BootP = __le16_to_cpu (boot -> BootP); |
| 162 | Infp0 = __le16_to_cpu (boot -> Infp0); |
| 163 | InfpX = __le16_to_cpu (boot -> InfpX); |
| 164 | InfTm = __le16_to_cpu (boot -> InfTm); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 165 | |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 166 | if (boot -> dos4 == EXTENDED_BOOT && |
| 167 | strncmp( boot->banner,"2M", 2 ) == 0 && |
| 168 | BootP < SZ_STD_SECTOR && |
| 169 | Infp0 < SZ_STD_SECTOR && |
| 170 | InfpX < SZ_STD_SECTOR && |
| 171 | InfTm < SZ_STD_SECTOR && |
| 172 | BootP >= InfTm + 2 && |
| 173 | InfTm >= InfpX && |
| 174 | InfpX >= Infp0 && |
| 175 | Infp0 >= 76 ) { |
| 176 | |
| 177 | return (-1); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 178 | } |
| 179 | |
| 180 | if (heads != NB_HEADS || |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 181 | tracks != NB_TRACKS || |
| 182 | sectors != NB_SECTORS || |
| 183 | __le16_to_cpu (boot -> secsiz) != SZ_STD_SECTOR || |
| 184 | fs -> tot_sectors == 0 || |
| 185 | (fs -> tot_sectors % sectors) != 0) { |
| 186 | return (-1); |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 187 | } |
wdenk | 8bde7f7 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 188 | |
wdenk | 2262cfe | 2002-11-18 00:14:45 +0000 | [diff] [blame] | 189 | return (0); |
| 190 | } |