source: vital-to8-sdk/sap/dfloppy.c

Last change on this file was 1, checked in by svn, 5 years ago

Import initial

File size: 6.9 KB
Line 
1/*  Lecture des disquettes Thomson sous MS-DOS
2 *  Version 2.1
3 *  Copyright (C) 2000-2003 Eric Botcazou
4 *
5 *  This program is free software; you can redistribute it and/or modify
6 *  it under the terms of the GNU General Public License as published by
7 *  the Free Software Foundation; either version 2 of the License, or
8 *  (at your option) any later version.
9 *
10 *  This program is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 *  GNU General Public License for more details.
14 *
15 *  You should have received a copy of the GNU General Public License
16 *  along with this program; if not, write to the Free Software
17 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19
20/* Limitations:
21 *  - les faces 1 des disquettes ne sont pas accessibles,
22 *  - les disquettes simple densité (format FM) ne sont pas lisibles.
23 */
24
25#ifndef SCAN_DEPEND
26   #include <stdio.h>
27   #include <stddef.h>
28   #include <bios.h>
29   #include <dpmi.h>
30   #include <sys/movedata.h>
31#endif
32
33#include "floppy.h"
34
35
36#define DISK_RETRY     3
37
38struct floppy_cmd {
39   int cmd;
40   int head;
41   int track;
42   int sector;
43   int nsects;
44   void *buffer;
45};
46
47static int drive_type[2];
48static int dpt_addr = 0;
49
50#define DPT_SIZE      11
51
52static unsigned char pc_dpt[DPT_SIZE];
53
54
55
56/* SetDiskParameters:
57 *  Initialise les paramètres disquette pour le format Thomson.
58 */
59static void SetDiskParameters(int density)
60{
61   unsigned char to_dpt[DPT_SIZE];
62
63   if (!dpt_addr) {
64      /* on récupère le vecteur 0x1E du BIOS qui pointe sur la table
65         des paramètres de la disquette */
66      _dosmemgetl(0x1E*4, 1, &dpt_addr);
67
68      /* on sauvegarde les paramètres originaux */
69      _dosmemgetb(dpt_addr, DPT_SIZE, pc_dpt);
70   }
71
72   /* on fixe les nouveaux paramètres */
73   to_dpt[0x0]=0xDF;  /* spec1                      */
74   to_dpt[0x1]=0x02;  /* spec2                      */
75   to_dpt[0x2]=0x25;  /* motor turn off delay       */
76   to_dpt[0x3]=density - 1;  /* sector size = 128*2^n */
77   to_dpt[0x4]=0x10;  /* 16 sectors/track           */
78   to_dpt[0x5]=0x1B;  /* gap between sectors        */
79   to_dpt[0x6]=(density == 1 ? 0x80 : 0xFF);  /* data length */
80   to_dpt[0x7]=0x2C;  /* gap when formatting        */
81   to_dpt[0x8]=0xE5;  /* filler byte                */
82   to_dpt[0x9]=0x0F;  /* head settle time           */
83   to_dpt[0xA]=0x08;  /* motor start time           */
84   _dosmemputb(to_dpt, DPT_SIZE, dpt_addr);
85
86   /* reset */
87   biosdisk(0, 0, 0, 0, 1, 0, NULL);
88}
89
90
91
92/* ExecCommand:
93 *  Exécute la commande spécifiée (via l'interruption 13h du BIOS).
94 */
95static int ExecCommand(int drive, int density, struct floppy_cmd *fd_cmd)
96{
97   int i;
98   int ret=0x10;
99
100   SetDiskParameters(density);
101
102   for (i=0; i<DISK_RETRY; i++) {
103      ret=biosdisk(fd_cmd->cmd, drive, fd_cmd->head, fd_cmd->track,
104                    fd_cmd->sector, fd_cmd->nsects, fd_cmd->buffer);
105
106      if (ret==0)  /* commande OK? */
107         break;
108
109      if ((i>1) && (ret==0x11)) { /* commande non OK mais corrigée par ctrl? */
110         ret=0;
111         break;
112      }
113
114      /* reset du lecteur */
115      biosdisk(0, 0, 0, 0, 1, 0, NULL);
116   }
117
118   switch (ret) {
119
120      case 0x02:  /* address mark not found */
121         return 0x04;   /* erreur sur l'adresse */
122
123      case 0x03:  /* disk write-protected */
124         return 0x01;   /* disk protégé en écriture */
125
126      case 0x04:  /* sector not found */
127      case 0x07:  /* drive parameter activity failed */
128      case 0x10:  /* data read (CRC or ECC) error */
129      case 0x0A:  /* bad sector flag detected */
130      case 0x0B:  /* bad track flag detected */
131         return 0x08;   /* erreur sur les données */
132
133      case 0x06:  /* floppy disk removed */
134      case 0x80:  /* disk timed out or failed to respond */
135         return 0x10;   /* lecteur non prêt */
136
137      default:
138         return 0;  /* OK */
139   }
140}
141
142
143
144/* FloppyReadSector:
145 *  Lit le secteur spécifié sur la disquette.
146 */
147int FloppyReadSector(int drive, int density, int track, int sector, int nsects, unsigned char data[])
148{
149   struct floppy_cmd fd_cmd;
150
151   fd_cmd.cmd    = 2;
152   fd_cmd.head   = drive%2;
153   fd_cmd.track  = track;
154   fd_cmd.sector = sector;
155   fd_cmd.nsects = nsects;
156   fd_cmd.buffer = data;
157
158   return ExecCommand(drive/2, density, &fd_cmd);
159}
160
161
162
163/* FloppyWriteSector:
164 *  Ecrit le secteur spécifié sur la disquette.
165 */
166int FloppyWriteSector(int drive, int density, int track, int sector, int nsects, const unsigned char data[])
167{
168   struct floppy_cmd fd_cmd;
169
170   fd_cmd.cmd    = 3;
171   fd_cmd.head   = drive%2;
172   fd_cmd.track  = track;
173   fd_cmd.sector = sector;
174   fd_cmd.nsects = nsects;
175   fd_cmd.buffer = (unsigned char *)data;
176
177   return ExecCommand(drive/2, density, &fd_cmd);
178}
179
180
181
182/* FloppyFormatTrack:
183 *  Formate la piste en utilisant la table des headers spécifiée.
184 */
185int FloppyFormatTrack(int drive, int density, int track, const unsigned char header_table[])
186{
187   struct floppy_cmd fd_cmd;
188   int format_type = 0;
189
190   /* sélection du format de formatage */
191   switch (drive_type[drive/2]) {
192
193      case 1:
194         /* 320/360 kb in 360 kb drive */
195         format_type = 1;
196         break;
197
198      case 2:
199         /* 320/360 kb in 1.2 Mb drive */
200         format_type = 2;
201         break;
202
203      case 3:
204      case 4:
205      case 5:
206      case 6:
207         /* 720 kb in 720 kb/1.44 Mb/2.88 Mb drive */
208         format_type = 4;
209         break;
210   }
211
212   biosdisk(23, drive/2, 0, 0, 1, format_type, NULL);
213
214   fd_cmd.cmd    = 5;
215   fd_cmd.head   = drive%2;
216   fd_cmd.track  = track;
217   fd_cmd.sector = 1;
218   fd_cmd.nsects = 16;
219   fd_cmd.buffer = (unsigned char *)header_table;
220
221   return ExecCommand(drive/2, density, &fd_cmd);
222}
223
224
225
226/* FloppyInit:
227 *  Initialise le module de lecture de disquettes.
228 */
229int FloppyInit(struct floppy_info *fi, int enable_write_support)
230{
231   __dpmi_regs r;
232   int i, num_drives = 0;
233
234   (void) enable_write_support;
235
236   for (i=0; i<2; i++) {
237      /* get drive parameters (int 13h, function 08h) */
238      r.h.ah = 0x08;
239      r.h.dl = i;
240
241      __dpmi_int(0x13, &r);
242
243      if (r.x.flags&1) {  /* CF set? */
244         drive_type[i] = 0;
245
246         fi->drive_type[2*i] = 0;
247         fi->drive_type[2*i+1] = 0;
248      }
249      else {
250         if (r.h.bl > 6) {
251            drive_type[i] = 0;
252
253            fi->drive_type[2*i] = 0;
254            fi->drive_type[2*i+1] = 0;
255         }
256         else {
257            drive_type[i] = r.h.bl;
258
259            fi->drive_type[2*i] = r.h.bl;
260            fi->drive_type[2*i+1] = 0;  /* face 1 unsupported */
261         }
262
263         num_drives++;
264      }
265   }
266
267   fi->num_drives = num_drives;
268   fi->fm_support = 0;
269   fi->write_support = 1;
270
271   return num_drives;
272}
273
274
275
276/* FloppyExit:
277 *  Met au repos le module de lecture de disquettes.
278 */
279void FloppyExit(void)
280{
281   if (dpt_addr) {
282      /* restaure les paramètres originaux */
283      _dosmemputb(pc_dpt, DPT_SIZE, dpt_addr);
284
285      /* reset */
286      biosdisk(0, 0, 0, 0, 1, 0, NULL);
287
288      dpt_addr = 0;
289   }
290}
291
Note: See TracBrowser for help on using the repository browser.