#include "DFC5.h" extern char *df[]; void MemCleanup(void) { } /* we don't need it */ /* * The MainPort is used for the handshaking with our DiskTask(). TPort is a temporary * port we use when we have sync stuff to do, like inhibit a drive, waiting for * the opening/closing message of a DiskTask, etc. TPort has *NEVER* pending * messages. */ static char SeveralPassesMsg[] = "You'll need x passes."; struct MsgPort *TaskPort[6], *MainPort, *TPort; struct IMsg IMsg[6] = { { { { NULL, NULL, NT_MESSAGE, NULL, NULL }, NULL, sizeof(struct IMsg)-sizeof(struct Message) }, NULL, 0 }, { { { NULL, NULL, NT_MESSAGE, NULL, NULL }, NULL, sizeof(struct IMsg)-sizeof(struct Message) }, NULL, 1 }, { { { NULL, NULL, NT_MESSAGE, NULL, NULL }, NULL, sizeof(struct IMsg)-sizeof(struct Message) }, NULL, 2 }, { { { NULL, NULL, NT_MESSAGE, NULL, NULL }, NULL, sizeof(struct IMsg)-sizeof(struct Message) }, NULL, 3 }, { { { NULL, NULL, NT_MESSAGE, NULL, NULL }, NULL, sizeof(struct IMsg)-sizeof(struct Message) }, NULL, 4 }, { { { NULL, NULL, NT_MESSAGE, NULL, NULL }, NULL, sizeof(struct IMsg)-sizeof(struct Message) }, NULL, 5 } }; char *Stack[5]; char NullName[1] = ""; /* stuff in public lists can't have NULL as a name */ struct Task Task[5]; /* * This routines sets up the main port and the replyport of the internal msgs. * Note that the sixth TaskPort is MainPort itself---a little trick for when * formatting. */ int SetUpPorts(void) { register int i; TaskPort[5] = MainPort = CreatePort(NULL,0); TPort = CreatePort(NULL,0); for(i=0; i<6; i++) IMsg[i].im_Message.mn_ReplyPort = MainPort; return(MainPort && TPort); } /* * Here we close our ports. */ void ClosePorts(void) { if (MainPort) DeletePort(MainPort); if (TPort) DeletePort(TPort); } /* * This routine sets up the internal message for a specified Unit and sends it. */ void SendMsg(int Unit, int Action, int n) { IMsg[Unit].im_Action = Action; IMsg[Unit].im_n = n; PutMsg(TaskPort[Unit], (struct Message *)&IMsg[Unit]); } /* * This routine gives us those pretty little DF0:BUSY things, which keep * AmigaDOS from futzing with the drives when we are playing with them. * Uses TPort. */ void Inhibit(int unit, int bool) { register struct MsgPort *handler ; static struct StandardPacket packet ; if (unit==4) return; handler = (struct MsgPort *)DeviceProc(df[unit]) ; if (handler == NULL) return ; packet.sp_Msg.mn_Node.ln_Name = (char *)&(packet.sp_Pkt) ; packet.sp_Pkt.dp_Link = &(packet.sp_Msg) ; packet.sp_Pkt.dp_Port = TPort ; packet.sp_Pkt.dp_Type = ACTION_INHIBIT ; packet.sp_Pkt.dp_Arg1 = bool ; PutMsg(handler, (void *)&packet) ; while (!GetMsg(TPort)) WaitPort(TPort) ; } /* * Here we open a DiskTask. 0 on failure, non 0 if all is OK. If the disk opened * was the unit 4, the RAM buffer, the number of passes needed is returned. * Note that we remind internally the number of passes, otherwise an OpenDiskTask(4) * with the unit 4 already opened could return a wrong answer. We use TPort. */ int OpenDiskTask(int Unit) { static char Passes; struct IMsg *Message; if (TaskPort[Unit]) return(Unit == 4 ? Passes : 1); if ((Stack[Unit] = AllocMem(STACKSIZE, MEMF_PUBLIC)) == NULL) return(0); Task[Unit].tc_Node.ln_Pri = 127; Task[Unit].tc_Node.ln_Type = NT_TASK; Task[Unit].tc_Node.ln_Name = NullName; Task[Unit].tc_UserData = (APTR)Unit; Task[Unit].tc_SPLower=(void *)(Stack[Unit]); Task[Unit].tc_SPReg=Task[Unit].tc_SPUpper=(void *)(Stack[Unit]+STACKSIZE); Task[Unit].tc_Node.ln_Pri = 127; AddTask(&Task[Unit], (void *)DiskTask, NULL); while (!(Message = (struct IMsg*)GetMsg(TPort))) WaitPort(TPort); if (Message->im_RC) { Inhibit(Unit, TRUE); if (Unit == 4) { Passes = Message->im_n; if (Passes>1) { SeveralPassesMsg[12] = Passes+48; Acknowledge(SeveralPassesMsg); } return((int)Passes); } return(1); } else { FreeMem(Stack[Unit], STACKSIZE); return(0); } } /* * Here we close a DiskTask. We use TPort. */ void CloseDiskTask(int Unit) { if (TaskPort[Unit]) { IMsg[Unit].im_Action = EXIT; PutMsg(TaskPort[Unit], (struct Message *)&IMsg[Unit]); while(!GetMsg(TPort)) WaitPort(TPort); Inhibit(Unit, FALSE); FreeMem(Stack[Unit], STACKSIZE); } }