home *** CD-ROM | disk | FTP | other *** search
- #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);
- }
- }
-
-