blob: 4c48663e0910d3497380d4e19b87b00edc5c60f7 [file] [log] [blame]
wdenk591dda52002-11-18 00:14:45 +00001/*
2 * (C) Copyright 2002
Albert ARIBAUD60fbc8d2011-08-04 18:45:45 +02003 * Stäubli Faverges - <www.staubli.com>
wdenk591dda52002-11-18 00:14:45 +00004 * Pierre AUBERT p.aubert@staubli.com
5 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02006 * SPDX-License-Identifier: GPL-2.0+
wdenk591dda52002-11-18 00:14:45 +00007 */
8
9#include <common.h>
10#include <config.h>
11
12#include "dos.h"
13#include "fdos.h"
14
wdenk591dda52002-11-18 00:14:45 +000015#define NB_HEADS 2
16#define NB_TRACKS 80
17#define NB_SECTORS 18
18
19
20static int lastwhere;
21
22/*-----------------------------------------------------------------------------
wdenk57b2d802003-06-27 21:31:46 +000023 * dev_open --
wdenk591dda52002-11-18 00:14:45 +000024 *-----------------------------------------------------------------------------
25 */
26int dev_open (void)
27{
28 lastwhere = 0;
29 return (0);
30}
31
32/*-----------------------------------------------------------------------------
33 * dev_read -- len and where are sectors number
34 *-----------------------------------------------------------------------------
35 */
36int dev_read (void *buffer, int where, int len)
37{
38 PRINTF ("dev_read (len = %d, where = %d)\n", len, where);
39
40 /* Si on ne desire pas lire a la position courante, il faut un seek */
41 if (where != lastwhere) {
wdenk57b2d802003-06-27 21:31:46 +000042 if (!fdc_fdos_seek (where)) {
43 PRINTF ("seek error in dev_read");
44 lastwhere = -1;
45 return (-1);
46 }
wdenk591dda52002-11-18 00:14:45 +000047 }
wdenk57b2d802003-06-27 21:31:46 +000048
wdenk591dda52002-11-18 00:14:45 +000049 if (!fdc_fdos_read (buffer, len)) {
wdenk57b2d802003-06-27 21:31:46 +000050 PRINTF ("read error\n");
51 lastwhere = -1;
52 return (-1);
wdenk591dda52002-11-18 00:14:45 +000053 }
54 lastwhere = where + len;
55 return (0);
56}
57/*-----------------------------------------------------------------------------
58 * check_dev -- verify the diskette format
59 *-----------------------------------------------------------------------------
60 */
61int check_dev (BootSector_t *boot, Fs_t *fs)
62{
63 unsigned int heads, sectors, tracks;
64 int BootP, Infp0, InfpX, InfTm;
65 int sect_per_track;
66
67 /* Display Boot header */
68 PRINTF ("Jump to boot code 0x%02x 0x%02x 0x%02x\n",
wdenk57b2d802003-06-27 21:31:46 +000069 boot -> jump [0], boot -> jump [1], boot -> jump[2]);
wdenk591dda52002-11-18 00:14:45 +000070 PRINTF ("OEM name & version '%*.*s'\n",
wdenk57b2d802003-06-27 21:31:46 +000071 BANNER_LG, BANNER_LG, boot -> banner );
wdenk591dda52002-11-18 00:14:45 +000072 PRINTF ("Bytes per sector hopefully 512 %d\n",
wdenk57b2d802003-06-27 21:31:46 +000073 __le16_to_cpu (boot -> secsiz));
wdenk591dda52002-11-18 00:14:45 +000074 PRINTF ("Cluster size in sectors %d\n",
wdenk57b2d802003-06-27 21:31:46 +000075 boot -> clsiz);
wdenk591dda52002-11-18 00:14:45 +000076 PRINTF ("Number of reserved (boot) sectors %d\n",
wdenk57b2d802003-06-27 21:31:46 +000077 __le16_to_cpu (boot -> nrsvsect));
wdenk591dda52002-11-18 00:14:45 +000078 PRINTF ("Number of FAT tables hopefully 2 %d\n",
wdenk57b2d802003-06-27 21:31:46 +000079 boot -> nfat);
wdenk591dda52002-11-18 00:14:45 +000080 PRINTF ("Number of directory slots %d\n",
wdenk57b2d802003-06-27 21:31:46 +000081 __le16_to_cpu (boot -> dirents));
wdenk591dda52002-11-18 00:14:45 +000082 PRINTF ("Total sectors on disk %d\n",
wdenk57b2d802003-06-27 21:31:46 +000083 __le16_to_cpu (boot -> psect));
wdenk591dda52002-11-18 00:14:45 +000084 PRINTF ("Media descriptor=first byte of FAT %d\n",
wdenk57b2d802003-06-27 21:31:46 +000085 boot -> descr);
wdenk591dda52002-11-18 00:14:45 +000086 PRINTF ("Sectors in FAT %d\n",
wdenk57b2d802003-06-27 21:31:46 +000087 __le16_to_cpu (boot -> fatlen));
wdenk591dda52002-11-18 00:14:45 +000088 PRINTF ("Sectors/track %d\n",
wdenk57b2d802003-06-27 21:31:46 +000089 __le16_to_cpu (boot -> nsect));
wdenk591dda52002-11-18 00:14:45 +000090 PRINTF ("Heads %d\n",
wdenk57b2d802003-06-27 21:31:46 +000091 __le16_to_cpu (boot -> nheads));
wdenk591dda52002-11-18 00:14:45 +000092 PRINTF ("number of hidden sectors %d\n",
wdenk57b2d802003-06-27 21:31:46 +000093 __le32_to_cpu (boot -> nhs));
wdenk591dda52002-11-18 00:14:45 +000094 PRINTF ("big total sectors %d\n",
wdenk57b2d802003-06-27 21:31:46 +000095 __le32_to_cpu (boot -> bigsect));
wdenk591dda52002-11-18 00:14:45 +000096 PRINTF ("physical drive ? %d\n",
wdenk57b2d802003-06-27 21:31:46 +000097 boot -> physdrive);
wdenk591dda52002-11-18 00:14:45 +000098 PRINTF ("reserved %d\n",
wdenk57b2d802003-06-27 21:31:46 +000099 boot -> reserved);
wdenk591dda52002-11-18 00:14:45 +0000100 PRINTF ("dos > 4.0 diskette %d\n",
wdenk57b2d802003-06-27 21:31:46 +0000101 boot -> dos4);
wdenk591dda52002-11-18 00:14:45 +0000102 PRINTF ("serial number %d\n",
wdenk57b2d802003-06-27 21:31:46 +0000103 __le32_to_cpu (boot -> serial));
wdenk591dda52002-11-18 00:14:45 +0000104 PRINTF ("disk label %*.*s\n",
wdenk57b2d802003-06-27 21:31:46 +0000105 LABEL_LG, LABEL_LG, boot -> label);
wdenk591dda52002-11-18 00:14:45 +0000106 PRINTF ("FAT type %8.8s\n",
wdenk57b2d802003-06-27 21:31:46 +0000107 boot -> fat_type);
wdenk591dda52002-11-18 00:14:45 +0000108 PRINTF ("reserved by 2M %d\n",
wdenk57b2d802003-06-27 21:31:46 +0000109 boot -> res_2m);
wdenk591dda52002-11-18 00:14:45 +0000110 PRINTF ("2M checksum (not used) %d\n",
wdenk57b2d802003-06-27 21:31:46 +0000111 boot -> CheckSum);
wdenk591dda52002-11-18 00:14:45 +0000112 PRINTF ("2MF format version %d\n",
wdenk57b2d802003-06-27 21:31:46 +0000113 boot -> fmt_2mf);
wdenk591dda52002-11-18 00:14:45 +0000114 PRINTF ("1 if write track after format %d\n",
wdenk57b2d802003-06-27 21:31:46 +0000115 boot -> wt);
wdenk591dda52002-11-18 00:14:45 +0000116 PRINTF ("data transfer rate on track 0 %d\n",
wdenk57b2d802003-06-27 21:31:46 +0000117 boot -> rate_0);
wdenk591dda52002-11-18 00:14:45 +0000118 PRINTF ("data transfer rate on track<>0 %d\n",
wdenk57b2d802003-06-27 21:31:46 +0000119 boot -> rate_any);
wdenk591dda52002-11-18 00:14:45 +0000120 PRINTF ("offset to boot program %d\n",
wdenk57b2d802003-06-27 21:31:46 +0000121 __le16_to_cpu (boot -> BootP));
wdenk591dda52002-11-18 00:14:45 +0000122 PRINTF ("T1: information for track 0 %d\n",
wdenk57b2d802003-06-27 21:31:46 +0000123 __le16_to_cpu (boot -> Infp0));
wdenk591dda52002-11-18 00:14:45 +0000124 PRINTF ("T2: information for track<>0 %d\n",
wdenk57b2d802003-06-27 21:31:46 +0000125 __le16_to_cpu (boot -> InfpX));
wdenk591dda52002-11-18 00:14:45 +0000126 PRINTF ("T3: track sectors size table %d\n",
wdenk57b2d802003-06-27 21:31:46 +0000127 __le16_to_cpu (boot -> InfTm));
wdenk591dda52002-11-18 00:14:45 +0000128 PRINTF ("Format date 0x%04x\n",
wdenk57b2d802003-06-27 21:31:46 +0000129 __le16_to_cpu (boot -> DateF));
wdenk591dda52002-11-18 00:14:45 +0000130 PRINTF ("Format time 0x%04x\n",
wdenk57b2d802003-06-27 21:31:46 +0000131 __le16_to_cpu (boot -> TimeF));
132
wdenk591dda52002-11-18 00:14:45 +0000133
wdenkcc1e2562003-03-06 13:39:27 +0000134 /* information is extracted from boot sector */
wdenk591dda52002-11-18 00:14:45 +0000135 heads = __le16_to_cpu (boot -> nheads);
136 sectors = __le16_to_cpu (boot -> nsect);
137 fs -> tot_sectors = __le32_to_cpu (boot -> bigsect);
138 if (__le16_to_cpu (boot -> psect) != 0) {
wdenk57b2d802003-06-27 21:31:46 +0000139 fs -> tot_sectors = __le16_to_cpu (boot -> psect);
wdenk591dda52002-11-18 00:14:45 +0000140 }
wdenk57b2d802003-06-27 21:31:46 +0000141
wdenk591dda52002-11-18 00:14:45 +0000142 sect_per_track = heads * sectors;
143 tracks = (fs -> tot_sectors + sect_per_track - 1) / sect_per_track;
wdenk57b2d802003-06-27 21:31:46 +0000144
wdenk591dda52002-11-18 00:14:45 +0000145 BootP = __le16_to_cpu (boot -> BootP);
146 Infp0 = __le16_to_cpu (boot -> Infp0);
147 InfpX = __le16_to_cpu (boot -> InfpX);
148 InfTm = __le16_to_cpu (boot -> InfTm);
wdenk57b2d802003-06-27 21:31:46 +0000149
wdenk591dda52002-11-18 00:14:45 +0000150 if (boot -> dos4 == EXTENDED_BOOT &&
wdenk57b2d802003-06-27 21:31:46 +0000151 strncmp( boot->banner,"2M", 2 ) == 0 &&
152 BootP < SZ_STD_SECTOR &&
153 Infp0 < SZ_STD_SECTOR &&
154 InfpX < SZ_STD_SECTOR &&
155 InfTm < SZ_STD_SECTOR &&
156 BootP >= InfTm + 2 &&
157 InfTm >= InfpX &&
158 InfpX >= Infp0 &&
159 Infp0 >= 76 ) {
wdenk591dda52002-11-18 00:14:45 +0000160
wdenk57b2d802003-06-27 21:31:46 +0000161 return (-1);
wdenk591dda52002-11-18 00:14:45 +0000162 }
163
164 if (heads != NB_HEADS ||
wdenk57b2d802003-06-27 21:31:46 +0000165 tracks != NB_TRACKS ||
166 sectors != NB_SECTORS ||
167 __le16_to_cpu (boot -> secsiz) != SZ_STD_SECTOR ||
168 fs -> tot_sectors == 0 ||
169 (fs -> tot_sectors % sectors) != 0) {
170 return (-1);
wdenk591dda52002-11-18 00:14:45 +0000171 }
wdenk57b2d802003-06-27 21:31:46 +0000172
wdenk591dda52002-11-18 00:14:45 +0000173 return (0);
174}