home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD2.img
/
d4xx
/
d447
/
dfc
/
task.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-02
|
4KB
|
159 lines
#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);
}
}