home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD1.bin / useful / dev / c / rkrm / trackdisk / track_copy.c < prev   
C/C++ Source or Header  |  1992-09-03  |  10KB  |  346 lines

  1. /*
  2.  * Copyright (c) 1992 Commodore-Amiga, Inc.
  3.  * 
  4.  * This example is provided in electronic form by Commodore-Amiga, Inc. for 
  5.  * use with the "Amiga ROM Kernel Reference Manual: Devices", 3rd Edition, 
  6.  * published by Addison-Wesley (ISBN 0-201-56775-X).
  7.  * 
  8.  * The "Amiga ROM Kernel Reference Manual: Devices" contains additional 
  9.  * information on the correct usage of the techniques and operating system 
  10.  * functions presented in these examples.  The source and executable code 
  11.  * of these examples may only be distributed in free electronic form, via 
  12.  * bulletin board or as part of a fully non-commercial and freely 
  13.  * redistributable diskette.  Both the source and executable code (including 
  14.  * comments) must be included, without modification, in any copy.  This 
  15.  * example may not be published in printed form or distributed with any
  16.  * commercial product.  However, the programming techniques and support
  17.  * routines set forth in these examples may be used in the development
  18.  * of original executable software products for Commodore Amiga computers.
  19.  * 
  20.  * All other rights reserved.
  21.  * 
  22.  * This example is provided "as-is" and is subject to change; no
  23.  * warranties are made.  All use is at your own risk. No liability or
  24.  * responsibility is assumed.
  25.  *
  26.  *****************************************************************************
  27.  *
  28.  *
  29.  * Track_Copy.c
  30.  *
  31.  * This program does a track by track copy from one drive to another
  32.  *
  33.  * Compile with SAS C 5.10  LC -cfist -ms -v -L
  34.  *
  35.  * This program will only run from the CLI.  If started from
  36.  * the Workbench, it will just exit...
  37.  *
  38.  * Usage:  Track_Copy  dfx dfy
  39.  */
  40.  
  41.  
  42. #include <exec/types.h>
  43. #include <exec/memory.h>
  44. #include <devices/trackdisk.h>
  45. #include <dos/dosextens.h> */
  46.  
  47. #include <clib/exec_protos.h>
  48. #include <clib/alib_protos.h>
  49. #include <clib/dos_protos.h>
  50.  
  51. #include <stdio.h>
  52. #include <string.h>
  53.  
  54. #ifdef LATTICE
  55. int CXBRK(void) { return(0); }     /* Disable Lattice CTRL/C handling */
  56. int chkabort(void) { return(0); }  /* really */
  57. #endif
  58.  
  59. #define    TRACK_SIZE    ((LONG)(NUMSECS * TD_SECTOR))
  60. /*
  61.  * Turn the BUSY flag off/on for the drive
  62.  * If onflag is TRUE, the disk will be marked as busy...
  63.  *
  64.  * This is to stop the validator from executing while
  65.  * we are playing with the disks.
  66.  */
  67. VOID disk_busy(UBYTE *drive,LONG onflag)
  68. {
  69. struct StandardPacket *pk;
  70. struct Process        *tsk;
  71.  
  72.     tsk=(struct Process *)FindTask(NULL);
  73.     if (pk=AllocMem(sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR))
  74.     {
  75.         pk->sp_Msg.mn_Node.ln_Name=(UBYTE *)&(pk->sp_Pkt);
  76.  
  77.         pk->sp_Pkt.dp_Link=&(pk->sp_Msg);
  78.         pk->sp_Pkt.dp_Port=&(tsk->pr_MsgPort);
  79.         pk->sp_Pkt.dp_Type=ACTION_INHIBIT;
  80.         pk->sp_Pkt.dp_Arg1=(onflag ? -1L : 0L);
  81.  
  82.         PutMsg(DeviceProc(drive),(struct Message *)pk);
  83.         WaitPort(&(tsk->pr_MsgPort));
  84.         GetMsg(&(tsk->pr_MsgPort));
  85.         FreeMem(pk,(long)sizeof(*pk));
  86.     }
  87. }
  88.  
  89. /*
  90.  * This turns the motor off
  91.  */
  92. VOID Motor_Off(struct IOExtTD *disk)
  93. {
  94.     disk->iotd_Req.io_Length=0;
  95.     disk->iotd_Req.io_Command=TD_MOTOR;
  96.     DoIO((struct IORequest *)disk);
  97. }
  98.  
  99. /*
  100.  * This turns the motor on
  101.  */
  102. VOID    Motor_On(struct IOExtTD *disk)
  103. {
  104.     disk->iotd_Req.io_Length=1;
  105.     disk->iotd_Req.io_Command=TD_MOTOR;
  106.     DoIO((struct IORequest *)disk);
  107. }
  108.  
  109. /*
  110.  * This reads a track, reporting any errors...
  111.  */
  112. SHORT Read_Track(struct IOExtTD *disk,UBYTE *buffer,SHORT track)
  113. {
  114. SHORT All_OK=TRUE;
  115.  
  116.     disk->iotd_Req.io_Length=TRACK_SIZE;
  117.     disk->iotd_Req.io_Data=(APTR)buffer;
  118.     disk->iotd_Req.io_Command=CMD_READ;
  119.     disk->iotd_Req.io_Offset=(ULONG)(TRACK_SIZE * track);
  120.     DoIO((struct IORequest *)disk);
  121.     if (disk->iotd_Req.io_Error)
  122.     {
  123.         All_OK=FALSE;
  124.         printf("Error %u when reading track %d",disk->iotd_Req.io_Error,track);
  125.     }
  126.     return(All_OK);
  127. }
  128.  
  129. /*
  130.  * This writes a track, reporting any errors...
  131.  */
  132. SHORT Write_Track(struct IOExtTD *disk,UBYTE *buffer,SHORT track)
  133. {
  134. SHORT All_OK=TRUE;
  135.  
  136.     disk->iotd_Req.io_Length=TRACK_SIZE;
  137.     disk->iotd_Req.io_Data=(APTR)buffer;
  138.     disk->iotd_Req.io_Command=TD_FORMAT;
  139.     disk->iotd_Req.io_Offset=(ULONG)(TRACK_SIZE * track);
  140.     DoIO((struct IORequest *)disk);
  141.     if (disk->iotd_Req.io_Error)
  142.     {
  143.         All_OK=FALSE;
  144.         printf("Error %d when writing track %d",disk->iotd_Req.io_Error,track);
  145.     }
  146.     return(All_OK);
  147. }
  148.  
  149. /*
  150.  * This function finds the number of TRACKS on the device.
  151.  * NOTE That this is TRACKS and not cylinders.  On a Two-Head
  152.  * drive (such as the standard 3.5" drives) the number of tracks
  153.  * is 160, 80 cylinders, 2-heads.
  154.  */
  155. SHORT FindNumTracks(struct IOExtTD *disk)
  156. {
  157.     disk->iotd_Req.io_Command=TD_GETNUMTRACKS;
  158.     DoIO((struct IORequest *)disk);
  159.     return((SHORT)disk->iotd_Req.io_Actual);
  160. }
  161.  
  162. /*
  163.  * This routine allocates the memory for one track and does
  164.  * the copy loop.
  165.  */
  166. VOID Do_Copy(struct IOExtTD *diskreq0,struct IOExtTD *diskreq1)
  167. {
  168. UBYTE *buffer;
  169. SHORT track;
  170. SHORT All_OK;
  171. SHORT NumTracks;
  172.  
  173.     if (buffer=AllocMem(TRACK_SIZE,MEMF_CHIP|MEMF_PUBLIC))
  174.     {
  175.         printf(" Starting Motors\r");
  176.         Motor_On(diskreq0);
  177.         Motor_On(diskreq1);
  178.         All_OK=TRUE;
  179.  
  180.         NumTracks=FindNumTracks(diskreq0);
  181.  
  182.         for (track=0;(track<NumTracks) && All_OK;track++)
  183.         {
  184.             printf(" Reading track %d\r",track);
  185.  
  186.             if (All_OK=Read_Track(diskreq0,buffer,track))
  187.             {
  188.                 printf(" Writing track %d\r",track);
  189.  
  190.                 All_OK=Write_Track(diskreq1,buffer,track);
  191.             }
  192.         }
  193.         if (All_OK) printf(" * Copy complete *");
  194.         printf("\n");
  195.         Motor_Off(diskreq0);
  196.         Motor_Off(diskreq1);
  197.         FreeMem(buffer,TRACK_SIZE);
  198.     }
  199.     else printf("No memory for track buffer...\n");
  200. }
  201.  
  202. /*
  203.  * Prompts the user to remove one of the disks.
  204.  * Since this program makes an EXACT copy of the disks
  205.  * AmigaDOS would get confused by them so one must be removed
  206.  * before the validator is let loose.  Also, note that the
  207.  * disks may NEVER be in drives on the SAME computer at the
  208.  * SAME time unless one of the disks is renamed.  This is due
  209.  * to a bug in the system.  It would normally be prevented
  210.  * by a diskcopy program that knew the disk format and modified
  211.  * the creation date by one clock-tick such that the disks would
  212.  * be different.
  213.  */
  214. VOID Remove_Disks(VOID)
  215. {
  216.     printf("\nYou *MUST* remove at least one of the disks now.\n");
  217.     printf("\nPress RETURN when ready\n");
  218.     while(getchar()!='\n');
  219. }
  220.  
  221. /*
  222.  * Prompts the user to insert the disks.
  223.  */
  224. VOID Insert_Disks(char drive1[], char drive2[])
  225. {
  226.     printf("\nPlease insert source disk in %s\n",drive1);
  227.     printf("\n          and destination in %s\n",drive2);
  228.     printf("\nPress RETURN when ready\n");
  229.     while(getchar()!='\n');
  230. }
  231.  
  232. /*
  233.  * Open the devices and mark them as busy
  234.  */
  235. VOID Do_OpenDevice(struct IOExtTD *diskreq0,struct IOExtTD *diskreq1, long unit[])
  236. {
  237. char drive1[] = "DFx:";  /* String for source drive */
  238. char drive2[] = "DFx:";  /* String for destination drive */
  239.  
  240.     drive1[2] = unit[0]+ '0';  /* Set drive number for source */
  241.  
  242.     if (!OpenDevice(TD_NAME,unit[0],(struct IORequest *)diskreq0,0L))
  243.     {
  244.  
  245.  
  246.           disk_busy(drive1,TRUE);
  247.  
  248.           drive2[2] = unit[1]+ '0';  /* Set drive number for destination */
  249.  
  250.         if (!OpenDevice(TD_NAME,unit[1],(struct IORequest *)diskreq1,0L))
  251.         {
  252.  
  253.  
  254.             disk_busy(drive2,TRUE);
  255.  
  256.             Insert_Disks(drive1,drive2);
  257.             Do_Copy(diskreq0,diskreq1);
  258.             Remove_Disks();
  259.  
  260.             disk_busy(drive2,FALSE);
  261.             CloseDevice((struct IORequest *)diskreq1);
  262.         }
  263.         else printf("Could not open %s\n",drive2);
  264.  
  265.         disk_busy(drive1,FALSE);
  266.         CloseDevice((struct IORequest *)diskreq0);
  267.     }
  268.     else printf("Could not open %s\n",drive1);
  269. }
  270.  
  271.  
  272. SHORT ParseArgs(int argc, char **argv, long Unit[])
  273.  
  274. #define OKAY 1
  275.  
  276. {
  277. int j=1, params = OKAY;
  278. char *position[]={"First","Second"};
  279.  
  280. if (argc != 3)
  281.     {
  282.     printf("\nYou must specify a source and destination disk\n");
  283.     return(!OKAY);
  284.     }
  285. else if (strcmp(argv[1],argv[2]) == 0)
  286.          {
  287.          printf("\nYou must specify different disks for source and destination\n");
  288.          return(!OKAY);
  289.          }