home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff225.lzh / AmigaTCP / src / amiga.c next >
C/C++ Source or Header  |  1989-06-24  |  15KB  |  654 lines

  1. /*
  2.  *  Modifications to existing pc.c module are --
  3.  *
  4.  *  Copyright (c) 1987
  5.  *  Louis A. Mamakos
  6.  *
  7.  *  This work, or any derivations thereof may be used for non-commercial
  8.  *  purposes only.  So there.
  9.  */
  10.  
  11. /* OS- and machine-dependent stuff for the Commodore-Amiga 1000 */
  12.  
  13. #define    AMIGAVERSION    "3"
  14.  
  15. #include <exec/types.h>
  16. #include <functions.h>        
  17. /* for Manx Aztec C, get func returns */
  18. #include <exec/nodes.h>
  19. #include <exec/lists.h>
  20. #include <exec/ports.h>
  21. #include <exec/devices.h>
  22. #include <exec/io.h>
  23.  
  24. #include <devices/console.h>
  25. #include <devices/serial.h>
  26. #include <devices/timer.h>
  27. #include <libraries/dos.h>
  28. #include <libraries/dosextens.h>
  29. #include <intuition/intuition.h>
  30.  
  31. #include <stdio.h>
  32. #include "machdep.h"
  33. #include "amiga.h"
  34. #include "mbuf.h"
  35. #include "internet.h"
  36. #include "iface.h"
  37. #include "cmdparse.h"
  38. #include "slip.h"
  39. #include "timer.h"
  40. #include "netuser.h"
  41. #include "ip.h"
  42. #include "tcp.h"
  43. #ifdef    TRACE
  44. #include "trace.h"
  45. #endif
  46.  
  47. static char *copyright_notice[2] = {
  48.     "AMIGA port of KA9Q TCP/IP (C) Copyright 1987 Louis A. Mamakos\r\n",
  49.     "for non-commercial, non-profic use only\r\n"};
  50.  
  51. struct asy asy[ASY_MAX];
  52.  
  53. void *malloc();
  54.  
  55. void setiss();
  56.  
  57. /* Interface list header */
  58. struct interface *ifaces;
  59.  
  60. struct IntuitionBase *IntuitionBase;
  61. static char banner[80];
  62. static struct NewWindow nw = {
  63.     0, 0, 640, 200,        /* left, top, (max) width, (max) height */
  64.     0, 1,            /* detail pen, block pen */
  65.     0,            /* IDCMP flags */
  66.     SMART_REFRESH | WINDOWDRAG | WINDOWDEPTH | WINDOWSIZING |
  67.         SIZEBBOTTOM | ACTIVATE | NOCAREREFRESH,    /* window flags */
  68.     NULL, NULL,        /* gadget, checkmark */
  69.     (UBYTE *)&banner[0],    /* title of window */
  70.     NULL, NULL,        /* screen, bitmap */
  71.     200, 50, -1, -1,    /* sizing limits */
  72.     WBENCHSCREEN,        /* on the workbench */
  73. };
  74.  
  75. APTR    oldwindowptr;
  76. struct Process *mytask;
  77.  
  78. struct MsgPort *keyboard, *consinp, *consoutp, *serinp, *seroutp,
  79.               *timerp;
  80. struct IOExtSer serin, serout;
  81. struct IOStdReq consin, consout;
  82. struct timerequest tr;
  83. struct Window *win;
  84.  
  85. char InputCharacter;
  86.  
  87. int timeropen, serialopen;
  88. #ifdef AMIGADEVDRV
  89. int DeviceSignal;
  90. #endif
  91. struct timer worktimer;        /* this is NOT a timer.device timer */
  92. void worker();
  93. #ifdef LATTICE
  94. extern struct { short error; char *msg; } os_errlist[];
  95. extern int _OSERR, os_nerr;
  96. #endif
  97. static
  98. clean(why)
  99.     char *why;
  100. {
  101.     int i;
  102.  
  103. #ifdef AMIGADEVDRV
  104.     if (DeviceSignal >= 0)
  105.         FreeSignal(DeviceSignal);
  106. #endif
  107.     if (timeropen)
  108.         CloseDevice(&tr);
  109.     if (serialopen)
  110.         CloseDevice(&serin);
  111.     if (win)
  112.         CloseWindow(win);
  113.     if (consinp)
  114.         DeletePort(consinp);
  115.     if (consoutp)
  116.         DeletePort(consoutp);
  117.     if (serinp)
  118.         DeletePort(serinp);
  119.     if (seroutp)
  120.         DeletePort(seroutp);
  121.     if (timerp)
  122.         DeletePort(timerp);
  123.  
  124.     mytask->pr_WindowPtr = oldwindowptr;
  125.  
  126.     if (why) {
  127.            myoserr(why);
  128.     }
  129.     exit(0);
  130. }
  131. myoserr(why)
  132. char *why;
  133. {
  134.   int i;
  135.         fprintf(stderr, "%s: ", why); 
  136. #ifdef LATTICE
  137.         fprintf(stderr, "%d: ", _OSERR);
  138.  
  139.         for(i = 0; os_errlist[i].error < os_nerr; i++)
  140.           if (os_errlist[i].error == _OSERR)
  141.             fprintf(stderr, os_errlist[i].msg);
  142. #endif
  143.         fprintf(stderr, "\r\n");
  144. }
  145. /* Called at startup time to set up console I/O, memory heap */
  146. ioinit()
  147. {
  148.     extern char major_rev[], minor_rev[];
  149.     struct Screen *scr;
  150.  
  151.     mytask = (struct Process *) FindTask((char *) NULL);
  152.     oldwindowptr = mytask->pr_WindowPtr;
  153.     mytask->pr_WindowPtr = (APTR) -1;    /* disable DOS requestors */
  154.  
  155.     if ((IntuitionBase = (struct IntuitionBase *)
  156.        OpenLibrary("intuition.library", 33L)) == NULL)
  157.         clean("No intuition: Version 1.2 of Amiga Systems Software required");
  158.  
  159.     sprintf(banner,
  160. #ifdef    AMIGADEVDRV
  161.     "KA9Q Internet Protocol Package, v%s.%s (Amiga version %sD)",
  162. #else
  163.     "KA9Q Internet Protocol Package, v%s.%s (Amiga version %s)",
  164. #endif
  165.         major_rev, minor_rev, AMIGAVERSION);
  166.  
  167.     /*
  168.      *  Try to determine the size of the workbench screen
  169.      */
  170.     scr = malloc(sizeof(struct Screen));
  171.     if (scr==NULL)
  172.         clean("Can't alloc screen");
  173.  
  174.     if (GetScreenData(scr, (ULONG) sizeof(struct Screen),
  175.               WBENCHSCREEN, NULL) == TRUE) {
  176.         nw.Width = scr->Width;
  177.         nw.Height = scr->Height-20;
  178.         nw.TopEdge = 19;
  179.     } else
  180.         fprintf(stderr, "Can't GetScreenData()\n");
  181.  
  182.     free((char *)scr);
  183.     if ((win = OpenWindow(&nw)) == NULL)
  184.         clean("Can't open window");
  185.  
  186.     if ((consinp = CreatePort("net:console in", 0L)) == NULL)
  187.         clean("Can't create console port");
  188.  
  189.     if ((consoutp = CreatePort("net:console out", 0L)) == NULL)
  190.         clean("Can't create console port");
  191.  
  192.     if ((timerp = CreatePort("net:timer", 0L)) == NULL)
  193.         clean("Can't create timer port");
  194.  
  195.     consin.io_Data = (APTR) win;
  196.     consin.io_Length = sizeof(struct Window);
  197.  
  198.     if (OpenDevice("console.device", 0L, &consin, 0L) != 0L)
  199.         clean("Can't open console device");
  200.  
  201.     consout = consin;
  202.  
  203.     consin.io_Message.mn_ReplyPort = consinp;
  204.     consin.io_Length = 1;
  205.     consin.io_Data = (APTR) &InputCharacter;
  206.     consin.io_Command = CMD_READ;
  207.     SendIO(&consin);
  208.     consout.io_Message.mn_ReplyPort = consoutp;
  209.     consout.io_Command = CMD_WRITE;
  210.  
  211.     /* create and start up timer */
  212.     tr.tr_node.io_Message.mn_ReplyPort = timerp;
  213.     if (OpenDevice("timer.device", UNIT_VBLANK, &tr, 0L) != 0L)
  214.         clean("Can't open timer");
  215. #ifdef AMIGADEVDRV
  216.     if ((DeviceSignal = AllocSignal(-1)) == -1)
  217.       clean("Can't allocate device signal");
  218. #endif
  219.     timeropen++;
  220.     tr.tr_node.io_Command = TR_GETSYSTIME;
  221.     DoIO(&tr);
  222. #ifdef    DEBUG
  223.     printf("System time is %ld\n", tr.tr_time.tv_secs);
  224. #endif
  225.     setiss(tr.tr_time.tv_secs);
  226.     tr.tr_node.io_Command = TR_ADDREQUEST;
  227.     tr.tr_time.tv_secs = 0;
  228.     tr.tr_time.tv_micro = MSPTICK*1000L;    /* convert to microseconds */
  229.     SendIO(&tr);
  230.  
  231.     set_timer(&worktimer, 1500);    /* set for 1.5 seconds */
  232.     worktimer.func = worker;
  233. #ifdef    AMIGADEVDRV
  234.     DriverInit();            /* install internet.device driver */
  235. #endif
  236.     start_timer(&worktimer);
  237. }
  238.  
  239. /* Called just before exiting to restore console state */
  240. iostop()
  241. {
  242.     while(ifaces != NULLIF){
  243.         if(ifaces->stop != NULLFP)
  244.             (*ifaces->stop)(ifaces);
  245.         ifaces = ifaces->next;
  246.     }
  247. #ifdef    AMIGADEVDRV
  248.     DriverShutdown();
  249. #endif
  250.     clean((char *)0);
  251. }
  252.  
  253. #define    BUFMAXCNT    150
  254. static char conbuf[BUFMAXCNT];
  255. static int concnt = 0;
  256.  
  257. int
  258. amigaputchar(c)
  259.     char c;
  260. {
  261.     conbuf[concnt++] = c;
  262.     if ((c == '\n') || (concnt == BUFMAXCNT))
  263.         amigaflush();
  264.     return c;
  265. }
  266.  
  267. amigaflush()
  268. {
  269.     if (concnt == 0)
  270.         return;
  271.     consout.io_Data = (APTR) conbuf;
  272.     consout.io_Length = concnt;
  273.     consout.io_Command = CMD_WRITE;
  274.     DoIO(&consout);
  275.     concnt = 0;
  276. }
  277.     
  278. /*
  279.  *  Begin terrible, horrible hack.  All output should be printed upon (into?)
  280.  *  the window we opened before.  Here goes nothing...
  281.  */
  282. void
  283. printf(a, b, c, d, e, f, g, h, i, j, k)
  284.     char *a;
  285.     int b, c, d, e, f, g, h, i, j, k;
  286. {
  287.     if (concnt)
  288.         amigaflush();
  289.  
  290.     sprintf(conbuf, a, b, c, d, e, f, g, h, i, j, k);
  291.     consout.io_Data = (APTR) conbuf;
  292.     consout.io_Length = strlen(conbuf);
  293.     consout.io_Command = CMD_WRITE;
  294.     DoIO(&consout);        /* no use in doing this async */
  295. }
  296.  
  297.     
  298. /* check active connections and update titles */
  299. void
  300. check_connections()
  301. {
  302.     extern struct tcb *tcbs[NTCB];
  303.     register struct tcb *tcb;
  304.     register int i;
  305.     int newlisten, newopn;
  306.     static int listen = -1, opn = -1;
  307.     static msg[80];
  308.  
  309.     newlisten = newopn = 0;
  310.  
  311.     for(i=0; i<NTCB; i++)
  312.         for(tcb=tcbs[i]; tcb != NULLTCB; tcb = tcb->next)
  313.             if (tcb->state == LISTEN)
  314.                 newlisten++;
  315.             else
  316.                 newopn++;
  317.  
  318.     if (newlisten != listen || newopn != opn) {
  319.         listen = newlisten;
  320.         opn = newopn;
  321.         sprintf(msg,
  322.        "Amiga Port by WA3YMH (TCP: listen: %d   open: %d)", listen, opn);
  323.         SetWindowTitles(win, -1L, msg);
  324.     }
  325. }
  326.  
  327. /* called every second or so */
  328. void
  329. worker()
  330. {
  331.     check_connections();
  332.     start_timer(&worktimer);
  333. }
  334.  
  335. #if    0
  336. /* processes any messages that Intuition sends us */
  337. void
  338. Do_Intuition_Message(m)
  339.     register struct IntuiMessage *m;
  340. {
  341.     ULONG class;
  342.     USHORT code, qualifier;
  343.  
  344.     class = m->Class;
  345.     code = m->Code;
  346.     qualifier = m->Qualifier;
  347.     ReplyMsg((struct Message *) m);       /* reply msg back to Intuition */
  348.     switch (class) {
  349.     case INTUITICKS:
  350.         check_connections();        
  351.         break;
  352.     }
  353. }
  354. #endif
  355.  
  356.     
  357. /*
  358.  * wait for something to happen
  359.  */
  360. eihalt()
  361. {
  362.     register struct IntuiMessage *msg;
  363.     static ULONG mask = 0;
  364.  
  365.     if (mask == 0L)
  366.         mask =     1L << consinp->mp_SigBit |
  367.             1L << serinp->mp_SigBit |
  368.             1L << timerp->mp_SigBit |
  369. #ifdef AMIGDEVDRV
  370.             1L << DeviceSignal    |
  371. #endif
  372. #if    0
  373.             1L << win->UserPort->mp_SigBit |
  374. #endif
  375.             1L << seroutp->mp_SigBit;
  376.  
  377.     (void) Wait(mask);
  378. #if    0
  379.     while (msg = (struct IntuiMessage *)GetMsg(win->UserPort))
  380.         Do_Intuition_Message(msg);
  381. #endif
  382. }
  383.  
  384. /* checks the time then ticks and updates ISS */
  385. void
  386. check_time()
  387. {
  388.     int32 iss();
  389.  
  390.     if (CheckIO(&tr)) {
  391.         WaitIO(&tr);
  392.         (void) GetMsg(timerp);
  393.         tick();
  394.         (void)iss();
  395.         tr.tr_time.tv_secs = 0;
  396.         tr.tr_time.tv_micro = MSPTICK*1000L;
  397.                     /* convert to microseconds */
  398.         SendIO(&tr);
  399.     }
  400. }
  401.  
  402. /* Initialize asynch port "dev" */
  403.  
  404.  
  405. /*
  406.  *  We will make the bold and rash assumption that the asy link will be used
  407.  *  for slip and slip-like stuff.  That is, we assume that there is an
  408.  *  an end-of-frame character that we can have the serial.device driver look
  409.  *  for.  Thus, we can fire up a single I/O request and have the whole frame
  410.  *  come back at once.
  411.  */
  412. int
  413. asy_init(dev, bufsize)
  414. int16 dev;
  415. unsigned bufsize;
  416. {
  417.     char serinitstr[1];
  418.     int serinitlen;
  419.  
  420.     serinitstr[0] = FR_END;    /* initialize initialization string to a */
  421.     serinitlen = 1;        /* frame end to flush receiver */
  422.  
  423.     if (serialopen) {
  424.         printf("\namiga: Error - serial device already open.\n");
  425.         return 0;
  426.     }
  427.     if ((serinp = CreatePort("net:serin", 0L)) == NULL)
  428.         clean("Can't create serial input port");
  429.  
  430.     if ((seroutp = CreatePort("net:serout", 0L)) == NULL)
  431.         clean("Can't create serial output port");
  432.  
  433.     /*
  434.      * Open serial device.
  435.      */
  436.     serin.io_SerFlags = SERF_XDISABLED | SERF_RAD_BOOGIE;  /* ? */
  437.     serin.io_Status = 0;
  438.     serin.io_RBufLen = bufsize;
  439.     asy[dev].speed = serin.io_Baud = 2400;    /* default speed */
  440.     if (OpenDevice("serial.device", 0L, &serin, 0L) != 0L)
  441.         clean("Can't open serial device");
  442.     serialopen++;
  443.     serin.IOSer.io_Message.mn_ReplyPort = serinp;
  444.     serout = serin;
  445.     serout.IOSer.io_Message.mn_ReplyPort = seroutp;
  446.     asy[dev].buflen = bufsize;
  447.     /* alloc input buffer */
  448.     if((asy[dev].input_buffer = malloc(asy[dev].buflen)) == NULL)
  449.         clean("Can't allocate serial input buf");
  450.     serin.IOSer.io_Data = (APTR) asy[dev].input_buffer;
  451.     serin.IOSer.io_Length = asy[dev].buflen;
  452.     asy[dev].input_len = 0;        /* clear input buffer */
  453.     serin.io_SerFlags = SERF_XDISABLED|SERF_EOFMODE|SERF_RAD_BOOGIE;
  454.     serin.IOSer.io_Flags = 0;
  455.     SendIO(&serin);
  456.     serout.IOSer.io_Data = (APTR) serinitstr;
  457.     serout.IOSer.io_Length = serinitlen;
  458.     serout.IOSer.io_Command = CMD_WRITE;
  459.     serout.IOSer.io_Flags = 0;
  460.     serout.io_SerFlags = SERF_XDISABLED | SERF_RAD_BOOGIE;
  461.     DoIO(&serout);
  462. }
  463.  
  464. int
  465. asy_stop(iface)
  466. struct interface *iface;
  467. {
  468.     if (iface->dev >= ASY_MAX) {
  469.         fprintf(stderr, "asy_stop: bad dev %d\n", iface->dev);
  470.         return;
  471.     }
  472.     AbortIO(&serin);
  473.     AbortIO(&serout);
  474.     CloseDevice(&serin);
  475.     free(asy[iface->dev].input_buffer);    /* release buffer */
  476.     serialopen--;
  477. }
  478.  
  479. /* Set asynch line speed */
  480. int
  481. asy_speed(dev,speed)
  482. int dev;
  483. int speed;
  484. {
  485.     if (serialopen == 0)
  486.         return;
  487.  
  488.     AbortIO(&serin);
  489.     WaitIO(&serin);
  490.     (void) GetMsg(serinp);
  491.     asy[dev].speed = serin.io_Baud = speed;
  492.     serin.io_ReadLen = 8;
  493.     serin.io_WriteLen = 8;
  494.     serin.io_StopBits = 1;
  495.     serin.io_TermArray.TermArray0 =    serin.io_TermArray.TermArray1 = 
  496.        (ULONG)FR_END << 24 | (ULONG)FR_END << 16 | FR_END << 8 | FR_END;
  497.     serin.IOSer.io_Command = SDCMD_SETPARAMS;
  498.     serin.IOSer.io_Flags = 0;
  499.     DoIO(&serin);
  500.     if (serin.IOSer.io_Error)
  501.         printf("Bad I/O status %d on SETPARAMS\n",
  502.                     serin.IOSer.io_Error);
  503.  
  504.     serin.IOSer.io_Command = CMD_READ;
  505.     serin.IOSer.io_Data = (APTR) asy[dev].input_buffer;
  506.     serin.IOSer.io_Length = asy[dev].buflen;
  507.     asy[dev].input_len = 0;        /* clear input buffer */
  508.     serin.io_SerFlags = SERF_XDISABLED|SERF_EOFMODE|SERF_RAD_BOOGIE;
  509.     serin.IOSer.io_Flags = 0;    /* no quick I/O */
  510.     SendIO(&serin);
  511. }
  512.  
  513. /* Send a buffer to serial transmitter */
  514. asy_output(dev,buf,cnt)
  515. unsigned dev;
  516. char *buf;
  517. unsigned short cnt;
  518. {
  519.     /*
  520.      *  We 'know' that the transmitter is ready since we would not have
  521.      *  been called unless the previous I/O has been completed.
  522.      */
  523.     WaitIO(&serout);
  524.     GetMsg(seroutp);
  525.     serout.IOSer.io_Data = (APTR) buf;
  526.     serout.IOSer.io_Length = cnt;
  527.     serout.io_SerFlags = SERF_XDISABLED | SERF_RAD_BOOGIE;
  528.     serout.IOSer.io_Flags = 0;    /* no quick I/O */
  529.     serout.IOSer.io_Command = CMD_WRITE;
  530.     SendIO(&serout);
  531. }
  532.  
  533. /* Read characters from the keyboard, translating them to "real" ASCII
  534.  * If none are ready, return the -1 from kbraw()
  535.  */
  536. kbread()
  537. {
  538.     char c;
  539.  
  540.     if (CheckIO(&consin)) {
  541.         WaitIO(&consin);
  542.         (void) GetMsg(consinp);
  543.         c = InputCharacter;
  544.         consin.io_Length = 1;
  545.         consin.io_Data = (APTR) &InputCharacter;
  546.         consin.io_Command = CMD_READ;
  547.         SendIO(&consin);        /* start next read up */
  548.         return (c & 0xff);
  549.     }
  550.  
  551.     return -1;        /* nuthin here */
  552. }
  553.  
  554. /* Receive characters from asynch line
  555.  * Returns count of characters read
  556.  */
  557. unsigned
  558. asy_recv(dev,buf,cnt)
  559. int dev;
  560. char *buf;
  561. unsigned cnt;
  562. {
  563.     register int actual = 0;
  564.     register long error;
  565.  
  566.     if (asy[dev].input_len == 0) {        /* if buffer is empty.. */
  567.         if (CheckIO(&serin) == NULL)    /* see if I/O has completed */
  568.             return 0;        /* nope, not yet. */
  569.         if (error = WaitIO(&serin))
  570.             printf("(SERIN) WaitIO returns %d\n", error);
  571.         if (serin.IOSer.io_Error)
  572.             printf("Bad I/O stat %d (SERIN)\n",
  573.                     serin.IOSer.io_Error);
  574.         (void) GetMsg(serinp);
  575.         /* input has completed.  fill in state variables */
  576.         asy[dev].input_len = serin.IOSer.io_Actual;
  577.         asy[dev].input_p = asy[dev].input_buffer;
  578. #ifdef    TRACE
  579.         if (trace & 0x40000000) {
  580.             int a, n, l = asy[dev].input_len;
  581.             unsigned char *b = asy[dev].input_buffer;
  582.  
  583.             a = 0;
  584.             printf("Raw serial input:\r\n");
  585.             while (l) {
  586.                 n = min(l, 16);
  587.                 fmtline(a, b, n);
  588.                 a += n;
  589.                 b += n;
  590.                 l -= n;
  591.             }
  592.             fflush(stdout);
  593.         }
  594. #endif            
  595.     }
  596.  
  597.     if (asy[dev].input_len) {    /* any chars in buffer left?  */
  598.         actual = min(asy[dev].input_len, cnt);
  599.         if (actual == 1)
  600.             *buf = *asy[dev].input_p;    /* usual case */
  601.         else
  602.             movmem(asy[dev].input_p, buf, actual);
  603.         asy[dev].input_len -= actual;
  604.         asy[dev].input_p += actual;
  605.     }
  606.  
  607.     if (asy[dev].input_len == 0) {        /* if buffer is now empty */
  608.         serin.IOSer.io_Command = CMD_READ;
  609.         serin.IOSer.io_Data = (APTR) asy[dev].input_buffer;
  610.         serin.IOSer.io_Length = asy[dev].buflen;
  611.         serin.io_SerFlags = 
  612.             SERF_XDISABLED|SERF_EOFMODE|SERF_RAD_BOOGIE;
  613.         serin.IOSer.io_Flags = 0;    /* no quick I/O */
  614.         SendIO(&serin);
  615.     }
  616.  
  617.     return actual;
  618. }
  619.  
  620. int
  621. stxrdy(dev)
  622. {
  623.     return (CheckIO(&serout) != NULL);
  624. }
  625.  
  626. /* Create a directory listing in a temp file and return the resulting file
  627.  * descriptor. If full == 1, give a full listing; else return just a list
  628.  * of names.
  629.  *
  630.  * This function is very dependent on the workings of Aztec standard I/O;
  631.  * it uses their mechanism for generating and deleting temporary files.
  632.  */
  633. FILE *
  634. dir(path,full)
  635. char *path;
  636. int full;
  637. {
  638.     /*return (FILE *)NULL;*/
  639.     return(0L);
  640. }
  641.  
  642. #if    0
  643. bcmp(a,b,n)
  644. register char *a,*b;
  645. register int16 n;
  646. {
  647.     while(n-- != 0){
  648.         if(*a++ != *b++)
  649.             return 1;
  650.     }
  651.     return 0;
  652. }
  653. #endif
  654.