home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / telecomm / nhclb120 / st.c < prev    next >
C/C++ Source or Header  |  1993-09-26  |  20KB  |  1,004 lines

  1. /* OS- and machine-dependent stuff for Atari-ST
  2.  * Adapted from the PC version to compile under Lattice C
  3.  * by Walter Doerr, DG2KK (dg2kk@cup.portal.com)
  4.  *
  5.  * 20-2-88:    added code from the Atari MWC version by Rob Janssen PE1CHL 
  6.  * 13-1-88:    added code needed for the 871225.1 version
  7.  * 24-12-87:    first version, adapted from PC.C from the 870412 release
  8.  */
  9.  
  10. #include <stdio.h>
  11. #include "global.h"
  12. #include "config.h"
  13. #include "mbuf.h"
  14. #include "internet.h"
  15. #include "iface.h"
  16. #include "st.h"
  17. #include "cmdparse.h"
  18. #include "asy.h"
  19.  
  20. /* #include "stdlib.h"    chkml() , malloc , free */
  21.  
  22. #ifdef LATTICE
  23. #include "dos.h"    /* dfind */
  24. #endif
  25. #include "osbind.h"
  26.  
  27. #ifdef    MWC
  28. #include <stat.h>
  29. #include <path.h>
  30. #include <time.h>
  31. #include <signal.h>
  32. FILE *stdprt;
  33. extern    char **environ;
  34. #endif
  35. #if !defined( GNUC) && !defined(MWC)
  36. #define Crawcin() gemdos(7) 
  37. #endif
  38.  
  39.  
  40.  
  41. int Sixteen;
  42.  
  43. #define TRUE -1
  44. #define FALSE 0
  45.  
  46. struct asy asy[ASY_MAX];
  47.  
  48. /* Interface list header */
  49. struct interface *ifaces;
  50.  
  51. static struct TempList {
  52.     struct TempList *next;
  53.     char *name;
  54. } *Head;
  55.  
  56. unsigned nasy;            /* needed in v871225.1 */
  57.  
  58. char *ttbuf;
  59. char *rsbuf;            /* location of memory alloc'd for rs232 buf */
  60.  
  61. #ifdef SCREEN
  62. char *newscreen, *newscradr;    /* 32k memory allocated to 2nd video screen */
  63. long logscreen, physcreen;
  64. int toggle = 0;            /* toggle between normal and trace screen */
  65. int printtrace = 0;        /* send trace to printer (controlled by F2) */
  66. #endif
  67.  
  68. char *shell,*getenv();        /* Name of command shell for exec */
  69. int    rows=25;        /* Number of text rows on screen (may be 50) */
  70.  
  71. /* called during init b4 anything is printed on the screen.
  72.  * PC.C does a lot of memory allocation stuff here.
  73.  * We just set the cursor to "blink" and allocate memory for a second video
  74.  * screen.
  75.  */
  76. ioinit()
  77. {
  78.        
  79.     char *lmalloc();    /* Takes a long arg */
  80.     unsigned long ptr;
  81. #ifdef GNUC
  82. /* hope GCC has not been set to 16bit int mode ! */
  83. #define lmalloc(s) malloc(s)
  84. #endif
  85. #ifdef SCREEN
  86.     newscradr = lmalloc(32*1024L);    /* allocate 32k for 2nd video screen */
  87.     ptr = (unsigned long)newscradr;
  88.     newscreen = (char *)((ptr+255) & 0xffffff00L);    /* 256 byte boundary */
  89.  
  90.     physcreen = (long)Physbase();    /* remember displayed screen address */
  91.     logscreen = (long)Logbase();    /* remember output screen address */
  92.     Cconws("\033j");        /* Save cursor position */
  93.     (void) Setscreen(newscreen,-1L,-1);    /* switch to 2nd screen */
  94.     (void) Vsync();            /* wait for vsync */
  95.     Cconws("\033H\033J");        /* cursor home, clear screen */
  96.     Cconws("\033k");        /* restore cursor position */
  97.     (void) Setscreen(logscreen,-1L,-1);    /* restore old screen */
  98.     (void) Vsync();            /* wait for vsync */
  99. #endif
  100.     printf("\033v\033e\n");        /* Autowrap on, Cursor on */
  101.     (void) Cursconf(2,0);        /* make the cursor blink (3=steady) */
  102. #ifdef MWC
  103.     stdprt = fopen("prn:","w");
  104.     signal(SIGINT, SIG_IGN);    /* Ignore ^C in GEMDOS I/O  -- hyc */
  105. #endif
  106.  
  107.     shell = getenv("NROWS");
  108.     if (shell != NULL)
  109.         rows=atoi(shell);
  110.  
  111.     shell = getenv("SHELL");
  112.     if (shell == NULL)
  113.         shell="\\bin\\gulam.prg";
  114. }
  115.  
  116. /* Called just before exiting. 
  117.  * delete temp files.
  118.  * free memory allocated to the rs-232 and midi buffers.
  119.  */
  120. iostop()
  121. {
  122.     register struct TempList *tptr;
  123.  
  124.     /* free memory allocated to 2nd video screen */
  125.  
  126. #ifdef SCREEN
  127.     dispscreen(0);        /* switch back to original screen */
  128.     free(newscradr);
  129. #endif
  130.  
  131. #if  !defined(MWC) && !defined(GNUC)
  132.     /* delete all temp files that have accumulated. */
  133.     /* MWC does not create temp files, GNUC does, but a tmpdel()
  134.      * function will have to wait.  Just use a pooper-scooper for now.
  135.      */
  136.     (void) tmpdel();
  137. #endif
  138.  
  139.     /* free memory allocated to RS-232/MIDI I/O buffers */
  140.     while (ifaces != NULLIF) {
  141.         if (ifaces->stop != NULLFP)
  142.             (*ifaces->stop)(ifaces);
  143.         ifaces = ifaces->next;
  144.     }
  145.  
  146.     tptr = Head;            /* Delete all temp files */
  147.     while( tptr != NULL) {
  148.         if(tptr->name != NULL)
  149.             unlink(tptr->name);
  150.         tptr = tptr->next;
  151.     }
  152.     printf("\n");
  153. }
  154.  
  155. #ifndef    MWC
  156. /* checks the time then ticks and updates ISS */
  157. static int32 clkval = 0;
  158. void
  159. check_time()
  160. {
  161.     int32 iss();            /* initial sequence number */
  162.     int32 clksec();
  163.     if(clkval != clksec()){
  164.          clkval = clksec();
  165.         icmpclk();
  166.         tick();
  167.         (void)iss();
  168.     }
  169. }
  170.  
  171. /* returns the number of seconds from system clock */
  172. static int32
  173. clksec()
  174. {
  175.     long tloc;
  176.     time(&tloc);
  177.     return (tloc);
  178. }
  179. #else
  180. static    clock_t    clkval=0;
  181. void
  182. check_time()
  183. {
  184.     int32 iss();
  185.  
  186.     /* System clock is 200Hz or 5ms/tick. Skip 11 ticks to match the
  187.      * definition in timer.h (MSPTICK = 55 there.) -- hyc
  188.      */
  189.     if((clock() - clkval) > 10) {
  190.         clkval = clock();
  191.         icmpclk();
  192.         tick();
  193.         (void)iss();
  194.     }
  195. }
  196. #endif
  197.  
  198. /* Initialize async port "dev" (adapted from PE1CHL) */
  199. int
  200. asy_init(dev,addr,vec,bufsize)
  201. int16 dev;
  202. char *addr, *vec;
  203. unsigned bufsize;
  204. {
  205.     register struct iorec *ip;
  206.     register struct asy *ap;
  207.     char *bufp;
  208.  
  209. #ifdef DEBUG
  210.     printf("asy_init: dev=%d bufsize=%d\n",dev,bufsize);
  211.     fflush(stdout);
  212. #endif
  213.     ap = &asy[dev];
  214.  
  215. /* ---- Moved here from slip.c - originally by DG2KK... -- hyc ----- */
  216.     /* addr    (COM Port address) is the Atari device name
  217.      *         (either "AUX:" or "MIDI")
  218.      * vec    (Interrupt vector) is used as a flag to indicate if 
  219.      *         bytes received on that interface should be sent out on
  220.      *         another interface (1 = AUX: 3 = MIDI).
  221.      */
  222.     ap->vec = atoi(vec);        /* dev to resend bytes to */
  223.     ap->addr = 0;            /* use as error flag */
  224.     if (strcmp(addr,"AUX:") == 0) {
  225.         ap->addr = 1;
  226.     } else if (strcmp(addr,"CON:") == 0) {    /* This would be stupid. */
  227.         ap->addr = 2;
  228.     } else if (strcmp(addr,"MIDI") == 0) {
  229.         ap->addr = 3;
  230.     }
  231. /* ----- end of paraphrase of slip.c... -- hyc ------- */
  232.     if (ap->addr == 0) {
  233.         printf("asy_init(%d): unknown interface\n",dev);
  234.         return -1;
  235.     }
  236.  
  237.     /* force user to allocate more memory than he already has.
  238.      * If no memory is allocated, asy_stop() may behave funny...
  239.      */
  240.     if (bufsize <= 256)    /* only allocate a bigger buffer */
  241.         return -1;
  242.  
  243.     if ((bufp = malloc(bufsize)) == NULLCHAR){
  244.         printf("asy_init(%d): no memory for rx buffer\n",dev);
  245.         return -1;
  246.     }
  247.  
  248.     /* Save original IOREC values */
  249.  
  250.     ip = Iorec((ap->addr)-1);    /* Iorec wants AUX: = 0, MIDI = 2 */
  251.  
  252.     Jdisint(12);            /* disable RS-232 interrupt */
  253.  
  254.     ap->in = ip;
  255.     memcpy(&ap->oldin,ip, sizeof(struct iorec));  /* prev version was 
  256.                                * not right ! */
  257.     if (ap->addr == RS232) {    /* increase RS-232 transmit buffer? */
  258.         ip++;
  259.         ap->out = ip;
  260.         memcpy(&ap->oldout,ip,sizeof(struct iorec));
  261.     }
  262.  
  263.     /* Set up receiver FIFO */
  264.     ap->in->ibuf = bufp;
  265.     ap->in->ibufsiz = bufsize;
  266.     ap->in->ibufhd = ap->in->ibuftl = 0;
  267.     ap->in->ibuflow = 0;
  268.     ap->in->ibufhi = bufsize;
  269.  
  270.     if (ap->addr == RS232) {
  271.         /* clear transmitter FIFO */
  272.         ap->out->ibufhd = ap->out->ibuftl = 0;
  273.         ap->out->ibuflow = 0;
  274.         ap->out->ibufhi = ap->out->ibufsiz;
  275.     }
  276.  
  277.     Jenabint(12);            /* enable RS-232 interrupts */
  278.  
  279.     if (ap->addr == RS232)
  280.         Rsconf(-1,0,-1,0,0,0);    /* 8 bits, no parity */
  281.  
  282. #ifdef DEBUG
  283.     printf("asy_init: Iorecs in: 0x%lx out: 0x%lx\n",ap->in,ap->out);
  284.     printf("    inbuf: 0x%lx outbuf: 0x%lx\n",ap->in->ibuf,
  285.         ap->out->ibuf);
  286. #endif
  287. }
  288.  
  289.  
  290. /* asy_stop restores old iorec and frees memory allocated to the RS-232/MIDI
  291.  * buffers. (from PE1CHL)
  292.  */
  293. int
  294. asy_stop(iface)
  295. struct interface *iface;
  296. {
  297.     register struct asy *ap;
  298. /*    char i_state; */
  299.  
  300. #ifdef DEBUG
  301.     printf("asy_stop: iface=0x%lx dev=%d\n",iface,iface->dev);
  302.     fflush(stdout);
  303. #endif
  304.     ap = &asy[iface->dev];
  305.  
  306.     (void) Jdisint(12);        /* disable RS-232 interrupts */
  307.  
  308.     free(ap->in->ibuf);        /* free the buffer */
  309.  
  310.     /* Restore old iorecs */
  311.     memcpy(ap->in,&ap->oldin,sizeof(struct iorec));
  312.     if (ap->addr == RS232)
  313.         memcpy(ap->out,&ap->oldout,sizeof(struct iorec));
  314.  
  315.     (void) Jenabint(12);        /* enable RS-232 interrupts */ 
  316. }
  317.  
  318.  
  319. /* Set async line speed */
  320. int
  321. asy_speed(dev,speed)
  322. int dev;
  323. int speed;
  324. {
  325.     int baud; /* int result; */
  326.     register int sp;
  327.     long sav_ssp;
  328.  
  329.     if (speed <= 0 || dev >= nasy)
  330.         return -1;
  331.  
  332.     asy[dev].speed = speed;        /* shouldn't this be done in slip.c? */
  333.  
  334.     switch (asy[dev].addr) {
  335.  
  336.     case RS232:
  337.         switch (speed) {
  338.         case 300:
  339.             baud = 9;    /* how slow can you get? :-) */
  340.             break;
  341.         case 1200:
  342.             baud = 7;
  343.             break;
  344.         case 2400:
  345.             baud = 4;
  346.             break;
  347.         case 4800:
  348.             baud = 2;
  349.             break;
  350.         case 9600:
  351.             baud = 1;
  352.             break;
  353.         case 19200:
  354.             baud = 0;
  355.             break;
  356.         default:
  357.             printf("asy_speed: unknown RS-232 speed (%d).\n",speed);
  358.             return -1;
  359.         }
  360.         (void) Rsconf(baud,0,0x88,-1,-1,-1);    /* no flow control */
  361.         break;
  362.  
  363.     case MIDI:
  364.         /* midi can run on 500000 or 614400Hz clock (hardware mod)
  365.          */
  366.         switch (speed)
  367.         {
  368.         case 0x9600:        /* = 38400 unsigned... (hardware mod) */
  369.         case 31250:        /* normal MIDI baudrate */
  370.             sp = 0x95;    /* /16 */
  371.             break;
  372.  
  373.         case 9600:        /* 9600 Baud requires hardware mod */
  374.         case 7812:        /* 7812 Baud on an unmodified Atari */
  375.             sp = 0x96;    /* /64 */
  376.             break;
  377.  
  378.         default:
  379.             printf("asy_speed: unknown MIDI speed (%d).\n",speed);
  380.             return -1;
  381.         }
  382.  
  383.         sav_ssp = Super(NULL);        /* switch to Supervisor mode */
  384.         *((char *) 0xfffffc04L) = 0x03; /* Reset 6850 */
  385.         hiword(0);            /* spend some time */
  386.         *((char *) 0xfffffc04L) = sp;    /* set new divider ratio */
  387.         Super(sav_ssp);            /* back to User mode */
  388.  
  389.         break;
  390.     }
  391.     asy_flush(dev);
  392. }
  393.  
  394.  
  395. /* flush the input buffer of device dev (either aux: or midi).
  396.  * May be useful, because setting the baudrate causes an 0x7f to be sent.
  397.  */
  398. asy_flush(dev)
  399. int dev;
  400. {
  401.     int st_dev;
  402.     long c;                    /* Bconin returns a long */
  403.     st_dev = asy[dev].addr;
  404.  
  405.     while (Bconstat(st_dev) == -1) {    /* at least 1 char avlb */
  406.         c = Bconin(st_dev);
  407.     }
  408. }
  409.  
  410.  
  411. /* Send a buffer to serial transmitter */
  412. asy_output(dev,buf,cnt)
  413. unsigned dev;
  414. char *buf;
  415. unsigned short cnt;
  416. {
  417.     int st_dev;
  418.     unsigned short i = 0;
  419.  
  420.     if (dev >= nasy)
  421.         return -1;
  422.  
  423.     st_dev = asy[dev].addr;
  424.     for (i = 0 ; i < cnt ; ++i) {
  425.         (void)Bconout(st_dev,buf[i]);    /* 1= AUX: 3=MIDI: */
  426.     }
  427. }
  428.  
  429.  
  430. /* Receive characters from async line
  431.  * Returns count of characters received
  432.  * dev is the device 
  433.  * buf is the buffer where received characters are stored
  434.  * cnt is the number of characters the calling routine expects to find in buf.
  435.  * On return, the no of chars still in the rs-232 buffer should be returned!??
  436.  * Quick and dirty hack: 
  437.  * since this routine is called from one location (slip.c) only, with cnt=1
  438.  * we just return the AUX: state (char avlb or not (bios(1,1) bconstat)).
  439.  * 
  440.  */
  441. unsigned
  442. asy_recv(dev,buf,cnt)
  443. int dev;
  444. char *buf;
  445. unsigned cnt;
  446. {
  447.     char c;
  448.     int rs_state;
  449.     int st_dev = asy[dev].addr;    /* AUX: device on the Atari ST */
  450.     int snd_dev = asy[dev].vec;
  451.  
  452.     rs_state = Bconstat(st_dev);    /* 0 = no char, -1 = char avlb */
  453.  
  454.     if (rs_state == -1) {
  455.         rs_state = 1;        /* at least one char available */
  456.         c = (char)Bconin(st_dev);
  457. #ifdef    RETRANSMIT
  458.         /* this does the actual retransmitting of received bytes
  459.          * depending on the vector field in the 'attach asy' command.
  460.          * remove it, if you don't have use for it.
  461.          */
  462.         if (snd_dev == 1 || snd_dev == 3) {    /* if AUX: or MIDI */
  463.             (void)Bconout(snd_dev,c & 0xff);
  464.         }
  465. #endif
  466.         *buf = c & 0xff;
  467.     }
  468.     return (rs_state);    /* 0 = no char, 1 = at least 1 more char */
  469. }
  470.  
  471. #ifdef    MWC
  472. int                /* Just for argument's sake... -- hyc */
  473. kbhit()
  474. {
  475.     return(Cconis());
  476. }
  477. #endif
  478.  
  479. int kbread()
  480. {
  481.     int c;
  482.     long    raw;
  483.  
  484.     if (Cconis() == 0){    /* no key hit: just return */
  485.         return (-1);
  486.     }
  487.  
  488.     raw = Crawcin();    /* Read ASCII and scan code from keyboard */
  489.     c = raw & 0x7f;        /* get rid of scan codes !!!! */
  490.  
  491. #ifdef    ESCAPEOUT        /* Why would you *ever* do this???  -- hyc */
  492.     if (c == 0x1b)
  493.         c = -2;        /* ESCAPE behaves like F10 */
  494. #endif
  495.     /* process function keys */
  496.     if (c == 0) {        /* we have an F key */
  497.         switch((int) ((raw >> 16) & 0xff)) {
  498.         case 0x3b:            /* F1 */
  499.             toggle = ~toggle;
  500.             (void) dispscreen(toggle);
  501.             c = -1;
  502.             break;
  503.  
  504.         case 0x3c:            /* F2 */
  505.             printtrace = 0;        /* printer off */
  506.             c = -1;
  507.             break;
  508.  
  509.         case 0x55:            /* Shift F2 */
  510.             printtrace = 1;        /* printer on */
  511.             c = -1;
  512.             break;
  513.  
  514.         case 0x44:            /* F10 */
  515.             c = -2;
  516.             break;
  517.         default:
  518.             c = -1;            /* ignore other keys */
  519.             break;
  520.         }
  521.     }
  522.     return (c);
  523. }
  524.  
  525. #ifndef    MWC        /* see vfile.c for MWC -- hyc */
  526. /* Create a temporary file and return the filepointer
  527.  * (adapted from the routine in mac_io.c)
  528.  */
  529. FILE *
  530. tmpfile()
  531. {
  532.     FILE *tmp;
  533.     char    name[32];
  534.     struct    TempList *tptr;
  535.     long tt;
  536.  
  537.     tt = clksec();
  538.     tt &= 0x007fffffL;
  539.     sprintf(name,"\\X%07.7ld.tmp",tt);
  540.     if ((tmp = fopen(name,"wrb")) == NULL) {
  541.         printf("tmpfile: could not create temp file. (%s)\n",name);
  542.         return(tmp);
  543.     }
  544.     tptr = (struct TempList *)malloc(sizeof(struct TempList));
  545.     if (tptr == NULL) {
  546.         printf("tmpfile: not enough memory for TempList\n");
  547.         return(tptr);
  548.     }
  549.     if(Head != NULL)
  550.         tptr->next = Head->next;
  551.     else
  552.         tptr->next = NULL;
  553.     if((tptr->name = malloc(strlen(name)+1)) == NULL) {
  554.         printf("tmpfile: not enough memory for name\n");
  555.         return(tptr);
  556.     }
  557.     strcpy(tptr->name,name);
  558.     if(Head != NULL)
  559.         Head->next = tptr;
  560.     else
  561.         Head = tptr;
  562.     return (tmp);
  563. }
  564. #endif
  565.  
  566. #ifndef    disable
  567. int disable()
  568. {
  569.     return 1;
  570. }
  571.  
  572. int restore(istate)
  573. int istate;
  574. {
  575. }
  576. #endif
  577.  
  578. void eihalt()
  579. {
  580. }
  581.  
  582.  
  583. /* the following is new stuff from version 871225.1 */
  584.  
  585. asy_ioctl(interface,argc,argv)
  586. struct interface *interface;
  587. int argc;
  588. char * argv[];
  589. {
  590.     if (argc < 1) {
  591.         printf("speed: %d baud\n",asy[interface->dev].speed);
  592.         return 0;
  593.     }
  594.     return asy_speed(interface->dev,atoi(argv[0]));
  595. }
  596.  
  597. int asy_rxint()
  598. {
  599.     printf("asy_rxint\n");
  600. }
  601.  
  602. int asy_txint()
  603. {
  604.     printf("asy_txint\n");
  605. }
  606.  
  607. int setbit()
  608. {
  609.     printf("setbit\n");
  610. }
  611.  
  612. int clrbit()
  613. {
  614.     printf("clrbit\n");
  615. }
  616. #ifndef GNUC
  617. /* GCC has rename in the library */
  618. void
  619. rename(s,d)
  620.     char *s, *d;        /* Source and dest name */
  621. {
  622.     Frename(0, s, d);    /* Ignore return code... */
  623. }
  624. #endif /* GNUC */
  625.  
  626. doshell(argc,argv)
  627. int argc; char *argv[];
  628. {
  629.     long execstat;
  630.     char *args[2];
  631. #ifndef GNUC
  632. #ifdef SCREEN
  633.     /* make sure that we are on the right (main) screen */
  634.     dispscreen(0);
  635.     toggle = 0;
  636. #endif /* SCREEN */
  637.     if (argc < 2) {
  638.         args[0]="shell";
  639.         args[1]=NULL;
  640.         execstat = exec(shell,args);
  641.     } else
  642.         execstat = exec(argv[1],&argv[1]);
  643.  
  644.     if (execstat != 0)
  645.         printf("Pexec: errorcode: %ld\n",execstat);
  646.  
  647.     printf("\n");
  648.     (void)Cursconf(1,0);        /* cursor on */
  649.     (void)Cursconf(2,0);        /* cursor blink */
  650. #endif /* GNUC */
  651. }
  652.  
  653.  
  654. dotype(argc,argv)
  655. int argc;
  656. char *argv[];
  657. {
  658.     char tstring[200];
  659.     char fname[50];
  660.     FILE *tfile;
  661.     int linecnt = 0;
  662.  
  663.     if (argc != 2) {
  664.         printf("Usage: type <filename>\n");
  665.         return;
  666.     }
  667.  
  668.     strcpy(fname,argv[1]);
  669.     if ((tfile = fopen(fname, "r")) == NULLFILE) {
  670.         printf("type: cannot open '%s'\n",fname);
  671.         return;
  672.     }
  673.  
  674.     while (!feof(tfile)) {
  675.         fgets(tstring,200,tfile);
  676.         linecnt++;
  677.         if (strlen(tstring) > 79)
  678.             linecnt++;
  679.         printf("%s",tstring);
  680.         if ((linecnt % 23) == 0) {
  681.             printf("\033p more \033q");
  682.  
  683.             if((Crawcin() & 0x7f) == 'q')
  684.  
  685.               {
  686.                 printf("\033l\n");
  687.                 break;
  688.             }
  689.             printf("\033l");
  690.         }
  691.     }
  692.     fclose(tfile);
  693. }
  694.  
  695. giveup()
  696. {
  697. }
  698.  
  699. int stxrdy(dev)
  700. int dev;
  701. {
  702.     int stat;
  703.     int st_dev;
  704.  
  705.     st_dev = asy[dev].addr;
  706.     stat=(int)Bcostat(st_dev);    /* Bcostat:  -1 ready , 0 not ready */
  707.     if (stat == -1) {
  708.         stat = 1;
  709.     }
  710.     return (stat);
  711. }
  712.  
  713. #ifdef    LATTICE
  714. /*
  715.  * replacement for buggy Lattice memchr function used in telnet.c
  716.  */
  717. char *
  718. memchr_st(str,c,n)
  719. char *str;
  720. char c;
  721. unsigned n;
  722. {
  723.     while (n-- != 0) {
  724.         if (*str++ == c)
  725.             return (str);
  726.     }
  727.     return NULLCHAR;
  728. }
  729.  
  730.  
  731. /* move (copy) a block of memory */
  732. /* this function assumes the blocks do not overlap */
  733. memcpy (d,s,c)
  734. register char *d;            /* destination pointer */
  735. register char *s;            /* source pointer */
  736. register int  c;            /* bytecount */
  737. {
  738.     if (c)                /* nonzero count? */
  739.     do
  740.     {
  741.         *d++ = *s++;        /* then move on */
  742.     } while (--c);            /* while more to go */
  743. }
  744.  
  745. /* fill a block of memory */
  746. void memset (p,c,n)
  747. register char *p;            /* block pointer */
  748. register char c;            /* initialization value */
  749. register int  n;            /* bytecount */
  750. {
  751.     if (n)                /* nonzero count? */
  752.     do
  753.     {
  754.         *p++ = c;        /* then do it */
  755.     } while (--n);            /* more to fill? */
  756. }
  757.  
  758. /* compare memory blocks, return 0 if equal */
  759. int memcmp (d,s,c)
  760. register char *d;            /* destination pointer */
  761. register char *s;            /* source pointer */
  762. register int  c;            /* bytecount */
  763. {
  764.     if (c)                /* nonzero count? */
  765.     do
  766.     {
  767.         if (*s++ != *d++)    /* compare */
  768.         return (*--d - *--s);    /* when unequal, return diff */
  769.     } while (--c);            /* while more to go */
  770.  
  771.     return (0);                /* equal! */
  772. }
  773.  
  774. /* lookup some character in a memory block */
  775. char *memchr (p,c,n)
  776. register char *p;            /* block pointer */
  777. register char c;            /* value to look for */
  778. register int  n;            /* bytecount */
  779. {
  780.     while (n--)
  781.     if (*p == c)
  782.         return (p);
  783.     else
  784.         p++;
  785.  
  786.     return (NULLCHAR);
  787. }
  788. #endif    /* LATTICE */
  789.  
  790. memstat()
  791. {
  792. #if   defined(    AX25)  && 0  /* can't find digisent in *.c */
  793.     extern int digisent;
  794. #endif
  795.     long size;
  796.  
  797.     size = Malloc(-1L);
  798.     printf("\nFree memory: %ld bytes.\n\n",size);
  799. #if    defined(    AX25) && 0
  800.     printf("Digisent: %d frames.\n\n",digisent);
  801. #endif
  802.     printf("AUX:");
  803.     iosize(0);
  804.     printf("MIDI:");
  805.     iosize(2);
  806. }
  807.  
  808. iosize(i)
  809. int i;
  810. {
  811.     struct iorec *rsbuffer;
  812.  
  813.     rsbuffer = (struct iorec*) Iorec(i);        /* get iorec */
  814.     printf("\tIorec:  %08lx\n",rsbuffer);
  815.     printf("\tBuffer: %08x\n",rsbuffer->ibuf);
  816.     printf("\tSize:   %d bytes\n",rsbuffer->ibufsiz);
  817. }
  818.  
  819. #ifdef    LATTICE  
  820. #define    DMABUFFER    struct FILEINFO
  821. #define d_fname        name
  822.  
  823. /* delete all temp files which have accumulated */
  824. tmpdel()
  825. {
  826.     DMABUFFER info;
  827.     char delnam[20];
  828.     int error;
  829.  
  830.     Fsetdta(&info);
  831.  
  832.     if ((error = Fsfirst("\\x*.tmp",0)) != 0){
  833.         info.d_fname[0] = '\0';
  834.     }
  835.     while (info.d_fname[0] != '\0') {
  836.         sprintf(delnam,"\\%s",info.d_fname);
  837.         unlink(delnam);
  838.         if ((error = Fsnext()) != 0) {
  839.             info.d_fname[0] = '\0';
  840.         }
  841.     }
  842. }
  843.  
  844.     /* The MWC version seems OK. -- hyc */
  845. /* the access() call doesn't seem to work in Lattice-C.
  846.  * this is a quick and dirty hack...
  847.  * it returns -1 if the file exists and 0 if it doesn't.
  848.  */
  849. int
  850. access(name,mode)
  851. char *name;
  852. int mode;
  853. {
  854.     struct FILEINFO *info;
  855.     int ret;
  856.  
  857.     Fsetdta(&info);
  858.     if ((ret = Fsfirst(name,0)) != 0)
  859.         return -1;
  860.     return 0;
  861. }
  862. #endif    /* LATTICE */
  863.  
  864. #ifdef SCREEN
  865.  
  866. /* dispscreen selects the screen to be displayed by the video hardware.
  867.  * this routine is called from within kbread()
  868.  * flag:  =0: display normal screen
  869.  *       <>0: display trace screen
  870.  */
  871. dispscreen(flag)
  872. int flag;
  873. {
  874.     if (flag == 0) {
  875.         (void) Setscreen(-1L,physcreen,-1);
  876.         (void) Vsync();
  877.         printf("\033e");    /* turn on cursor */
  878.     } else {
  879.         (void) Setscreen(-1L,newscreen,-1);
  880.         (void) Vsync();
  881.         printf("\033f");    /* turn off cursor */
  882.     }
  883. }
  884.  
  885.  
  886. /* outscreen selects one of two screens where display output (printf's) should
  887.  * go to.
  888.  * outscreen is called from trace.c before/after trace output is done
  889.  */
  890. outscreen(flag)
  891. int flag;
  892. {
  893.     if (flag == 0) {
  894.         (void) Setscreen(logscreen,-1L,-1);
  895.         (void) Vsync();
  896.         printf("\033k");    /* restore cursor pos on main screen */
  897.     } else {
  898.         (void) Setscreen(newscreen,-1L,-1);
  899.         (void) Vsync();
  900.         printf("\033j");    /* save cursor pos on main screen */
  901.         printf("\033Y%c%c",rows+31,32);
  902.     }
  903. }
  904. #endif
  905.  
  906. #ifdef    MWC
  907. static exec(command,args)
  908. char *command;
  909. char *args[];
  910. {
  911.     char **envx,*pt,*com;
  912.     register int i,j,k,l;
  913.  
  914.     pt=getenv("PATH");        /* Find an executable file named */
  915.     if(pt == NULL)            /* command in the path... */
  916.         pt=DEFPATH;
  917.  
  918.     com=path(pt,command,1);
  919.     if(com != NULL)
  920.         command = com;
  921.  
  922.     j=(-1);
  923.     for(i=0;environ[i]!=0;i++)    /* Count vars in environment */
  924.         if(!strncmp(environ[i],"ARGV",4))    /* Skip ARGV */
  925.             j=i;
  926.  
  927.     if(j<0)
  928.         i++;
  929.  
  930.     envx=(char **)malloc(i*sizeof(char *));    /* Copy environment */
  931.     i--;
  932.     envx[i] = NULL;
  933.  
  934.     for(k=0,l=0;k<i;l++)
  935.         if(l!=j) {
  936.             envx[k]=malloc(strlen(environ[l])+1);
  937.             strcpy(envx[k],environ[l]);
  938.             k++;
  939.         }
  940.     
  941.     return(execve(command,args,envx));
  942. }
  943. #endif
  944.     
  945. /* Do a warm boot, I think. -- hyc */
  946. void
  947. sysreset()
  948. {
  949.     long *resvec,(*resjump)();
  950.  
  951.     Super(NULL);    /* Get into supervisor mode to read sys vars */
  952.     resvec = (long *)0x42a;
  953.     resjump = *resvec;
  954.     (*resjump)();
  955. }
  956.  
  957.  
  958. /*
  959.  * set console output to binary or ascii mode (raw or cooked...)
  960.  * mode == 1 means raw, anything else means cooked.
  961.  * This is a compiler/library dependent hack. Too bad I can't
  962.  * come up with a better way.  -- hyc
  963.  */
  964.  
  965. void
  966. set_stdout(mode)
  967. int mode;
  968. {
  969.  
  970.     FILE *fp, *_fopen();
  971.     char *fmode;
  972.  
  973.     if (mode == 1)
  974.         fmode = "wb";
  975.     else
  976.         fmode = "w";
  977.  
  978.     fflush(stdout);
  979. #ifdef    MWC
  980.     fp=_fopen(NULL, fmode, stdout, 1);
  981. #endif
  982. /* I am open to suggestions for GNUC stuff to put here - dje */
  983. #ifdef GNUC
  984.     setbuf(stdout,NULL);  /* disable all buffering */
  985. #endif
  986. }
  987.  
  988.  
  989.  
  990.  
  991. flowoff() {}  /* compatibilty for Telnet */
  992. flowon() {}  
  993. flowdefault(){}
  994. clearout(){}
  995.  
  996.  
  997. xmkdir( s,m)
  998. char *s;
  999. int m;
  1000. {
  1001. /* Confucius, he say "No makee directoree" */
  1002. return(-1);
  1003. }
  1004.