/********************************************************************
 ** PARALLEL PORT SUPPORT (PACKET DRIVER)
 **
 ** (c) Spak, Darrell Tam, c9107253@ee.newcastle.edu.au (1994)
 ** phone (Australia) 049-829-710
 **                    49-829-710
 ** (c) SST 1994
 **
 ** THE MAIN CALLER
 **
 ** Sets up an interrupt on the "ACK" line of the parallel port (CIA-B)
 ** And receives packets of data
 ** Sends data if requested
 **
 ** TABS to 4
 ********************************************************************/

#include "packets.h"
#include "globs_protos.h"
#include "wingdings_protos.h"
#include "receive_protos.h"
#include "send_protos.h"
#include "regcmd_protos.h"

/* get this machine's ID from the first character of the first argument */
/********************************************************************/
			int main(int argc, char *argv[])
/********************************************************************/
{
long	mask, waitmask, commask, regmask, eatmask, delaymask;
char	delay;

	dbzero(DMARecvHash, sizeof(DMARecvHash));
	dbzero(ServicePort, sizeof(ServicePort));

	out = Output(); in = Input();

	if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0))
	|| !(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0)) )
			goto nomore;

	if(!OpenTimers() || !OpenCIA()) goto nomore;
	if(!(comport = CreatePort("ParServer", 0)) ||
	   !(regport = CreatePort("ParRegister", 0)) ||
	   !(eatport = CreatePort(0, 0)) ) {
		fpf(out, "No port\n");
		goto nomore;
	}
	fpf(out, "This machine's ID = '%lc'\n", cir.machine = (argv[1])[0]);


/** WAIT FOR SOMEONE TO SEND US SOMETHING */
	fpf(out, "waiting... (CTRL-C TO KILL)\n");

	delaymask = 1<<timersysport->mp_SigBit;
	commask = 1<<comport->mp_SigBit;

	waitmask =	cir.sigmask |
				SIGBREAKF_CTRL_C |
				SIGBREAKF_CTRL_D |
				(eatmask = 1<<eatport->mp_SigBit) |
				(regmask = 1<<regport->mp_SigBit);
	delay = 0;

/** SPIN AROUND UNTIL WE FIND A CTRL-C */
	while(!((mask = Wait(waitmask | (delay?delaymask:commask))) & SIGBREAKF_CTRL_C)) {

	/** HAVE WE SOMETHING TO READ FROM OUR HARDWARE PORT ??? */
		if(mask & cir.sigmask)  ReceiveFromHWPort();

	/** GOT BACK THE DELAY TIMER SO SEND THE NEXT MSG */
		if(mask & delaymask /* && delay == 1 (implicit) */ ) {
		struct StdMsg *msg;
			if(msg = (struct StdMsg *)GetMsg(comport)) {
				if(HandleSend((struct PktMsg *)msg) != PAR_OK)
					START_TIMER(timedelayio, 0, ERRORBACKAWAYMICROS);
				else
					START_TIMER(timedelayio, 0, BACKAWAYMICROS);
			}
			else delay = 0;
		}

	/** SOMETHING TO SEND TO ANOTHER MACHINE (THRU THE HW PORT) ?? */
		if(mask & commask /* && delay == 0 (implicit) */ ) {
		struct StdMsg *msg;

		/** BACK AWAY AFTER SENDING?? */
			if(BACKAWAYMICROS) {
				if(msg = (struct StdMsg *)GetMsg(comport)) {
					if(HandleSend((struct PktMsg *)msg) != PAR_OK)
						START_TIMER(timedelayio, 0, ERRORBACKAWAYMICROS);
					else
						START_TIMER(timedelayio, 0, BACKAWAYMICROS);
					delay = 1;
				}
			}

		/** OR HOG THE PORT ?? */
			else while(delay == 0 && (msg = (struct StdMsg *)GetMsg(comport))) {
				if(HandleSend((struct PktMsg *)msg) != PAR_OK) {
					START_TIMER(timedelayio, 0, ERRORBACKAWAYMICROS);
					delay = 1;
				}
				else if(SetSignal(0, cir.sigmask))
						ReceiveFromHWPort();
			}
		}

	/** REGISTER PORT - WHERE "SERVICES" MUST "REGISTER" */
		if(mask & regmask) {
		struct StdMsg *msg;
			while(msg = (struct StdMsg *)GetMsg(regport))
				RegisterCommand((struct RegisterMsg *)msg);
		}

	/** EXCLUSIVELY FOR EATING MESSAGES WE SENT OUT AND SOMEONE RETURNED */
		if(mask & eatmask) {
		struct PktMsgRecv *pmr;
			while(pmr = (void *)GetMsg(eatport))
					FREE_PKTMSGRECV(pmr);
		}
	}

nomore:
	ReplyAllHashNodes(DMARecvHash, HASH_TABLE_SIZE);
	if(comport) DeletePort(comport);
	if(regport) DeletePort(regport);
	if(eatport) DeletePort(eatport);
	CloseTimers();
	CloseCIA();
	FreeRemember(&mem, TRUE);
	if(GfxBase) CloseLibrary((struct Library *)GfxBase);
	if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
}

