home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / disk / misc / TransADF.lha / TransADF / Source / device.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-05  |  6.9 KB  |  267 lines

  1. /* device.c - Handle all device IO.
  2. ** Copyright (C) 1998 Karl J. Ots
  3. ** 
  4. ** This program is free software; you can redistribute it and/or modify
  5. ** it under the terms of the GNU General Public License as published by
  6. ** the Free Software Foundation; either version 2 of the License, or
  7. ** (at your option) any later version.
  8. ** 
  9. ** This program is distributed in the hope that it will be useful,
  10. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ** GNU General Public License for more details.
  13. ** 
  14. ** You should have received a copy of the GNU General Public License
  15. ** along with this program; if not, write to the Free Software
  16. ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17. */
  18.  
  19. #include <exec/types.h>
  20. #include <exec/ports.h>
  21. #include <exec/io.h>
  22. #include <devices/trackdisk.h>
  23. #include <dos/dos.h>
  24. #include <dos/dosextens.h>
  25. #include <dos/filehandler.h>
  26. #include <clib/exec_protos.h>
  27. #include <clib/dos_protos.h>
  28.  
  29. #include <string.h>
  30.  
  31. #include "device.h"
  32. #include "main.h"
  33. #include "util.h"
  34. #include "errors.h"
  35.  
  36.  
  37. /* Global variable that holds the size of a single track */
  38. /* I hate the fact tat this is global :(                 */
  39. ULONG trackSize;
  40.  
  41. /* Priate Functions */
  42. BYTE rwTrack (APTR  Buffer, UWORD NumTracks, UWORD TrackNum, 
  43.               struct IOStdReq *DiskReq);
  44.  
  45. extern struct DosLibrary *DOSBase;
  46.  
  47.  
  48. /*
  49. ** Get information about dosDev.
  50. ** Returns a DeviceInfo structure or NULL.
  51. */
  52. struct DeviceInfo *
  53. getDeviceInfo (STRPTR dosDev)
  54. {
  55.   static struct DeviceInfo  devInfo;
  56.   struct DeviceInfo        *rDevInfo = NULL;
  57.   struct DosList           *dosList;
  58.   struct FileSysStartupMsg *suMsg;
  59.   struct DosEnvec          *dosEnv;
  60.   int l;
  61.   
  62.   /* Strip ':' from dosDev if present */
  63.   dosDev = strdup (dosDev);
  64.   l = strlen (dosDev) - 1;
  65.   if (dosDev[l] == ':') dosDev[l] = 0;
  66.   
  67.   /* Make sure the list doesn't change while we're looking at it */
  68.   dosList = LockDosList (LDF_DEVICES | LDF_READ);
  69.   if (( dosList = FindDosEntry (dosList, dosDev, LDF_DEVICES) ))
  70.   {
  71.     if (( suMsg = (struct FileSysStartupMsg *) 
  72.                   BADDR (dosList->dol_misc.dol_handler.dol_Startup) ))
  73.     {
  74.       dosEnv = (struct DosEnvec *) BADDR (suMsg->fssm_Environ);
  75.       
  76.       devInfo.dosName    = dosDev;
  77.       devInfo.deviceName = strdup (b2cstr (suMsg->fssm_Device));
  78.       devInfo.deviceUnit = suMsg->fssm_Unit;
  79.       
  80.       devInfo.trackSize  = (dosEnv->de_SizeBlock << 2) * dosEnv->de_BlocksPerTrack;
  81.       devInfo.numHeads   = dosEnv->de_Surfaces;
  82.       devInfo.lowTrack   = dosEnv->de_LowCyl * dosEnv->de_Surfaces;
  83.       devInfo.highTrack  = ((dosEnv->de_HighCyl + 1) * dosEnv->de_Surfaces) - 1;
  84.       
  85.       /* Set global track size */
  86.       trackSize = devInfo.trackSize;
  87.       
  88.       /* Set the return type */
  89.       rDevInfo = &devInfo;          
  90.     }
  91.   }
  92.   /* Allow others to use the DOS Lists */
  93.   UnLockDosList (LDF_DEVICES | LDF_READ);
  94.  
  95.   return rDevInfo;
  96. }
  97.  
  98.  
  99. /*
  100. ** Open an exec device.  Allocate all structures nessesary.
  101. ** Return an IO Request structure or NULL if failure.
  102. */
  103. struct IOStdReq *
  104. openDev (STRPTR devName, ULONG devUnit)
  105. {
  106.   struct MsgPort    *diskPort;
  107.   struct IOStdReq   *diskReq;
  108.   BYTE   IOError;
  109.     
  110.   /* Attempt to create a Message Port */
  111.   diskPort = CreateMsgPort();
  112.   if (diskPort)
  113.   {
  114.     /* Attempt to create an IO Request */
  115.     diskReq = (struct IOStdReq *)
  116.               CreateIORequest (diskPort, sizeof (struct IOStdReq));
  117.     if (diskReq)
  118.     {
  119.       /* Attempt to open device */
  120.       IOError = OpenDevice (devName, devUnit, 
  121.                            (struct IORequest *)diskReq, NULL);
  122.       if (!IOError)
  123.       {
  124.         /* Success - ready to go */
  125.         return diskReq;
  126.       }
  127.       else
  128.       {
  129.         /* Couldn't open device */
  130.         FPrintf (StdErr, "%s: Couldn't open %s unit %d - ", ProgName,
  131.                                                             devName,
  132.                                                             devUnit);
  133.         reportIOError (IOError);
  134.       }
  135.       
  136.       DeleteIORequest (diskReq);        
  137.     }
  138.     else
  139.     {
  140.       /* Couldn't create an IO Request */
  141.       FPrintf (StdErr,
  142.                "%s: Couldn't create an IO Request for %s IO.\n",
  143.                ProgName, devName);
  144.     }
  145.     
  146.     DeleteMsgPort (diskPort);
  147.   }
  148.   else
  149.   {
  150.     /* Couln't create a Message Port */
  151.     FPrintf (StdErr,
  152.              "%s: Couldn't create a Message Port for %s IO.\n",
  153.              ProgName, devName);
  154.   }
  155.   
  156.   return NULL;
  157. }
  158.  
  159.  
  160. /*
  161. ** Close exec device associated with diskReq.
  162. ** It is safe to call this with diskReq == NULL.
  163. */
  164. void
  165. closeDev (struct IOStdReq *diskReq)
  166. {
  167.   struct MsgPort *diskPort;
  168.   
  169.   if (diskReq)
  170.   {
  171.     diskPort = diskReq->io_Message.mn_ReplyPort;
  172.     
  173.     /* Flush any unwritten buffers */
  174.     flushTrack (diskReq);
  175.     
  176.     /* Turn off the drive motor */
  177.     diskReq->io_Command = TD_MOTOR;
  178.     diskReq->io_Length  = 0;
  179.     DoIO ((struct IORequest *)diskReq);
  180.     
  181.     /* Close the device and release memory */
  182.     CloseDevice ((struct IORequest *) diskReq);
  183.     DeleteIORequest (diskReq);
  184.     DeleteMsgPort (diskPort);
  185.   }
  186. }
  187.  
  188.  
  189. /* 
  190. ** Read a number of complete tracks from the specified unit.
  191. ** Return DoIO()'s return value.
  192. */
  193. BYTE 
  194. readTrack (APTR   rBuffer,
  195.            UBYTE  rNumTracks,
  196.            UBYTE  rTrackNum,
  197.            struct IOStdReq *rDiskReq)
  198. {
  199.   rDiskReq->io_Command = CMD_READ;
  200.   return rwTrack (rBuffer, rNumTracks, rTrackNum, rDiskReq);
  201. }
  202.  
  203.  
  204. /*
  205. ** Write a number of complete tracks to the specified unit.
  206. ** Return DoIO()'s return value.
  207. */
  208. BYTE 
  209. writeTrack (APTR   wBuffer, 
  210.             UBYTE  wNumTracks, 
  211.             UBYTE  wTrackNum, 
  212.             struct IOStdReq *wDiskReq)
  213. {
  214.   wDiskReq->io_Command = CMD_WRITE;
  215.   return rwTrack (wBuffer, wNumTracks, wTrackNum, wDiskReq);
  216. }
  217.  
  218.  
  219. /*
  220. ** Format a number of complete tracks on the the specified device.
  221. ** This can only be called if device either supports or ignores
  222. ** the TD_FORMAT command.  If it implemets the value of TD_FORMAT
  223. ** (= CMD_NONSTD+2 = 11) as some other command, the results are undefined.
  224. ** Return DoIO()'s return value.  This may be IOERR_NOCMD, 
  225. ** which can be safely ignored.
  226. */
  227. BYTE 
  228. formatTrack (APTR   fBuffer, 
  229.              UBYTE  fNumTracks, 
  230.              UBYTE  fTrackNum, 
  231.              struct IOStdReq *fDiskReq)
  232. {
  233.   fDiskReq->io_Command = TD_FORMAT;
  234.   return rwTrack (fBuffer, fNumTracks, fTrackNum, fDiskReq);
  235. }
  236.  
  237.  
  238. /*
  239. ** Flush the track buffer on the specified unit.
  240. ** Return DoIO()'s return value.
  241. */
  242. BYTE 
  243. flushTrack (struct IOStdReq *DiskReq)
  244. {
  245.   DiskReq->io_Command = CMD_UPDATE;
  246.   return DoIO ((struct IORequest *)DiskReq);
  247. }
  248.  
  249.  
  250. /*
  251. ** Perform track-sized IO on specified unit.
  252. ** Return DoIO()'s return value
  253. */
  254. BYTE
  255. rwTrack (APTR  Buffer,
  256.          UWORD NumTracks,
  257.          UWORD TrackNum,
  258.          struct IOStdReq *DiskReq)
  259. {
  260.   DiskReq->io_Flags   = 0;
  261.   DiskReq->io_Data    = Buffer;
  262.   DiskReq->io_Length  = NumTracks * trackSize;
  263.   DiskReq->io_Offset  = TrackNum  * trackSize;
  264.   
  265.   return DoIO ((struct IORequest *) DiskReq);
  266. }
  267.