home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 377b.lha / devices / trackdisk / trackcopy.c next >
Encoding:
C/C++ Source or Header  |  1980-02-03  |  7.8 KB  |  273 lines

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