home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / dirs / dfc_447.lzh / DFC / Task.c < prev    next >
C/C++ Source or Header  |  1991-02-02  |  4KB  |  159 lines

  1. #include "DFC5.h"
  2.  
  3. extern char *df[];
  4.  
  5. void MemCleanup(void) {
  6. }                                 /* we don't need it */
  7.  
  8. /*
  9.  * The MainPort is used for the handshaking with our DiskTask(). TPort is a temporary
  10.  * port we use when we have sync stuff to do, like inhibit a drive, waiting for
  11.  * the opening/closing message of a DiskTask, etc. TPort has *NEVER* pending
  12.  * messages.
  13.  */
  14.  
  15. static char SeveralPassesMsg[] = "You'll need x passes.";
  16.  
  17. struct MsgPort *TaskPort[6], *MainPort, *TPort;
  18.  
  19. struct IMsg IMsg[6] = {
  20.     {    {    {    NULL, NULL, NT_MESSAGE, NULL, NULL    }, NULL, sizeof(struct IMsg)-sizeof(struct Message)    }, NULL, 0    },
  21.     {    {    {    NULL, NULL, NT_MESSAGE, NULL, NULL    }, NULL, sizeof(struct IMsg)-sizeof(struct Message)    }, NULL, 1    },
  22.     {    {    {    NULL, NULL, NT_MESSAGE, NULL, NULL    }, NULL, sizeof(struct IMsg)-sizeof(struct Message)    }, NULL, 2    },
  23.     {    {    {    NULL, NULL, NT_MESSAGE, NULL, NULL    }, NULL, sizeof(struct IMsg)-sizeof(struct Message)    }, NULL, 3    },
  24.     {    {    {    NULL, NULL, NT_MESSAGE, NULL, NULL    }, NULL, sizeof(struct IMsg)-sizeof(struct Message)    }, NULL, 4    },
  25.     {    {    {    NULL, NULL, NT_MESSAGE, NULL, NULL    }, NULL, sizeof(struct IMsg)-sizeof(struct Message)    }, NULL, 5    }
  26. };
  27.  
  28.  
  29. char *Stack[5];
  30.  
  31. char NullName[1] = ""; /* stuff in public lists can't have NULL as a name */
  32. struct Task Task[5];
  33.  
  34. /*
  35.  * This routines sets up the main port and the replyport of the internal msgs.
  36.  * Note that the sixth TaskPort is MainPort itself---a little trick for when
  37.  * formatting.
  38.  */
  39.  
  40. int SetUpPorts(void) {
  41.  
  42.     register int i;
  43.  
  44.     TaskPort[5] = MainPort = CreatePort(NULL,0);
  45.     TPort = CreatePort(NULL,0);
  46.     for(i=0; i<6; i++) IMsg[i].im_Message.mn_ReplyPort = MainPort;
  47.     return(MainPort && TPort);
  48. }
  49.  
  50. /*
  51.  * Here we close our ports.
  52.  */
  53.  
  54. void ClosePorts(void) {
  55.  
  56.     if (MainPort) DeletePort(MainPort);
  57.     if (TPort) DeletePort(TPort);
  58. }
  59.  
  60. /*
  61.  * This routine sets up the internal message for a specified Unit and sends it.
  62.  */
  63.  
  64. void SendMsg(int Unit, int Action, int n) {
  65.  
  66.     IMsg[Unit].im_Action = Action;
  67.     IMsg[Unit].im_n = n;
  68.     PutMsg(TaskPort[Unit], (struct Message *)&IMsg[Unit]);
  69. }
  70.  
  71.  
  72.  
  73. /*
  74.  *      This routine gives us those pretty little DF0:BUSY things, which keep
  75.  *      AmigaDOS from futzing with the drives when we are playing with them.
  76.  *      Uses TPort.
  77.  */
  78.  
  79. void Inhibit(int unit, int bool) {
  80.  
  81.     register struct MsgPort *handler ;
  82.     static struct StandardPacket packet ;
  83.  
  84.     if (unit==4) return;
  85.     handler = (struct MsgPort *)DeviceProc(df[unit]) ;
  86.     if (handler == NULL) return ;
  87.  
  88.     packet.sp_Msg.mn_Node.ln_Name = (char *)&(packet.sp_Pkt) ;
  89.     packet.sp_Pkt.dp_Link = &(packet.sp_Msg) ;
  90.     packet.sp_Pkt.dp_Port = TPort ;
  91.     packet.sp_Pkt.dp_Type = ACTION_INHIBIT ;
  92.     packet.sp_Pkt.dp_Arg1 = bool ;
  93.     PutMsg(handler, (void *)&packet) ;
  94.     while (!GetMsg(TPort)) WaitPort(TPort) ;
  95. }
  96.  
  97. /*
  98.  * Here we open a DiskTask. 0 on failure, non 0 if all is OK. If the disk opened
  99.  * was the unit 4, the RAM buffer, the number of passes needed is returned.
  100.  * Note that we remind internally the number of passes, otherwise an OpenDiskTask(4)
  101.  * with the unit 4 already opened could return a wrong answer. We use TPort.
  102.  */
  103.  
  104. int OpenDiskTask(int Unit) {
  105.  
  106.     static char Passes;
  107.     struct IMsg *Message;
  108.  
  109.     if (TaskPort[Unit]) return(Unit == 4 ? Passes : 1);
  110.  
  111.     if ((Stack[Unit] = AllocMem(STACKSIZE, MEMF_PUBLIC)) == NULL) return(0);
  112.  
  113.     Task[Unit].tc_Node.ln_Pri = 127;
  114.     Task[Unit].tc_Node.ln_Type = NT_TASK;
  115.     Task[Unit].tc_Node.ln_Name = NullName;
  116.     Task[Unit].tc_UserData = (APTR)Unit;
  117.  
  118.     Task[Unit].tc_SPLower=(void *)(Stack[Unit]);
  119.     Task[Unit].tc_SPReg=Task[Unit].tc_SPUpper=(void *)(Stack[Unit]+STACKSIZE);
  120.     Task[Unit].tc_Node.ln_Pri = 127;
  121.  
  122.     AddTask(&Task[Unit], (void *)DiskTask, NULL);
  123.  
  124.     while (!(Message = (struct IMsg*)GetMsg(TPort))) WaitPort(TPort);
  125.  
  126.     if (Message->im_RC) {
  127.         Inhibit(Unit, TRUE);
  128.         if (Unit == 4) {
  129.             Passes = Message->im_n;
  130.             if (Passes>1) {
  131.                 SeveralPassesMsg[12] = Passes+48;
  132.                 Acknowledge(SeveralPassesMsg);
  133.             }
  134.             return((int)Passes);
  135.         }
  136.         return(1);
  137.     }
  138.     else {
  139.         FreeMem(Stack[Unit], STACKSIZE);
  140.         return(0);
  141.     }
  142. }
  143.  
  144. /*
  145.  * Here we close a DiskTask. We use TPort.
  146.  */
  147.  
  148. void CloseDiskTask(int Unit) {
  149.  
  150.     if (TaskPort[Unit]) {
  151.         IMsg[Unit].im_Action = EXIT;
  152.         PutMsg(TaskPort[Unit], (struct Message *)&IMsg[Unit]);
  153.         while(!GetMsg(TPort)) WaitPort(TPort);
  154.         Inhibit(Unit, FALSE);
  155.         FreeMem(Stack[Unit], STACKSIZE);
  156.     }
  157. }
  158.  
  159.