/* * SERNET.C * * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved. * * NetWork device interface. */ #include "dnet.h" typedef struct IOExtSer IOSER; #define WPEND 1 #define WONE 1 /* defined if WPEND == 1 */ IOSER Iowq[WPEND]; ubyte Iowact[WPEND]; NetOpen(pior, piow, iosink, devname, unitnum, baud) IOSER **pior, **piow; PORT *iosink; char *devname; { IOSER ios; IOSER *ior, *iow; short i; bzero(&ios, sizeof(ios)); ios.io_CtlChar = 0x11130102; ios.io_SerFlags = SERF_SHARED|SERF_XDISABLED|SERF_RAD_BOOGIE; if (OpenDevice(devname, unitnum, &ios, 0)) dneterror(devname); *pior = ior = (IOSER *)AllocMem(sizeof(IOSER), MEMF_PUBLIC); *piow = iow = (IOSER *)AllocMem(sizeof(IOSER), MEMF_PUBLIC); *ior = ios; *iow = ios; ior->IOSer.io_Command = SDCMD_QUERY; DoIO(ior); ior->IOSer.io_Command = SDCMD_SETPARAMS; ior->io_SerFlags = SERF_SHARED|SERF_XDISABLED|SERF_RAD_BOOGIE; ior->io_ExtFlags = 0; ior->io_ReadLen = ior->io_WriteLen = 8; ior->io_CtlChar = 0x01020304; if (baud) ior->io_Baud = baud; Baud = ior->io_Baud; if (DoIO(ior) != 0) dneterror("Unable to set serial parameters"); ior->IOSer.io_Command = CMD_READ; iow->IOSer.io_Command = CMD_WRITE; ior->IOSer.io_Message.mn_ReplyPort = iosink; iow->IOSer.io_Message.mn_ReplyPort = iosink; iow->IOSer.io_Message.mn_Node.ln_Name = (char *)WNET_REQ; ior->IOSer.io_Message.mn_Node.ln_Name = (char *)RNET_REQ; for (i = 0; i < WPEND; ++i) Iowq[i] = *iow; } /* * Closedown the network. */ NetClose(pior, piow) IOSER **pior, **piow; { IOSER *ior = *pior; IOSER *iow = *piow; if (ior) { CloseDevice(ior); FreeMem(ior, sizeof(IOSER)); FreeMem(iow, sizeof(IOSER)); } *pior = NULL; *piow = NULL; } /* * NETCLWRITE() * * Clear write request which was GetMsg()'d in DNET.C instead of * WaitIO()'d here. */ NetClWrite(ior) IOSER *ior; { short i = ior - &Iowq[0]; if (i >= WPEND) { printf("NetClWrite: Software error %ld\n", i); } else { Iowact[i] = 0; } } /* * NETWRITE() * * Write data to the network. Up to WPEND requests may be made pending * before this call blocks. This call also controls whether the last * sent packet is to start a timeout sequence or not (by being returned * as WNET_REQ or not). */ void NetWrite(buf, bytes, expectreply) APTR buf; { short i; static short j; #ifdef WONE static short last = -1; #else static short last; #endif if (buf == NULL) { for (i = 0; i < WPEND; ++i) { if (Iowact[i]) { WaitIO(&Iowq[i]); Iowact[i] = 0; } } fixsignal(Iowq[0].IOSer.io_Message.mn_ReplyPort); return; } /* * Find an open slot. Do not use the last timeout-ok used slot. * Remove requests that are done. */ for (i = 0; i < WPEND; ++i) { if (Iowact[i] && CheckIO(&Iowq[i]) && last != i) { WaitIO(&Iowq[i]); Iowact[i] = 0; } if (!Iowact[i]) break; } if (bytes) { if (i == WPEND) { /* all requests active, wait for one */ if (j == last) /* but not the WNET_REQ one (if any) */ j = (j + 1) % WPEND; WaitIO(&Iowq[i=j]); Iowact[i] = 0; j = (j + 1) % WPEND; } /* * If we expect a reply to this packet, name it WNET_REQ (when * returned starts a timeout sequence), else name it IGWNET_REQ. */ #ifndef WONE if (expectreply) { Iowq[last].IOSer.io_Message.mn_Node.ln_Name = (char *)IGWNET_REQ; Iowq[i].IOSer.io_Message.mn_Node.ln_Name = (char *)WNET_REQ; last = i; } else { Iowq[i].IOSer.io_Message.mn_Node.ln_Name = (char *)IGWNET_REQ; } #endif Iowq[i].IOSer.io_Data = buf; Iowq[i].IOSer.io_Length = bytes; SendIO(&Iowq[i]); Iowact[i] = 1; } fixsignal(Iowq[0].IOSer.io_Message.mn_ReplyPort); } NetBreak() { NetWrite(NULL,0,0); Iowq[0].IOSer.io_Command = SDCMD_BREAK; DoIO(&Iowq[0]); Iowq[0].IOSer.io_Command = CMD_WRITE; fixsignal(Iowq[0].IOSer.io_Message.mn_ReplyPort); } /* * NETREADY() * * Using the specified inactive request, return the # bytes ready and * the carrier status. */ NetReady(ior, cd) IOSER *ior; ubyte *cd; { register ubyte oldcmd = ior->IOSer.io_Command; register long n = 0; ior->IOSer.io_Command = SDCMD_QUERY; if (DoIO(ior) == 0) n = ior->IOSer.io_Actual; ior->IOSer.io_Command = oldcmd; *cd = !(ior->io_Status & (1 << 5)); return(n); }