
/* pmdcom.c ,Lattice 5.04, public domain-use it,abuse it,lose it */
/* Paul DePetrillo   August, 1990  */
/*  with some help from Rush,Pink Floyd,Mr. Big, MSG, etc.  */


#include "pc8.h"

VOID main(argc,argv)
int argc;
char **argv;
{
    if (argc >1 && argv[1][0]=='w') custom=0;
    doinit();
    asyncRexxCmd("init");
    SendIO((struct IORequest *)serread_req);
    while(go)
    {
        signals=Wait(windowmask|serialmask|rexxbit);
        if (CheckIO((struct IORequest *)serread_req)) doserial();
        if (signals & windowmask ) dowindow();
        if (signals & rexxbit)   dispRexxPort();
    }
    cleanup(24);
}

void doserial()
{
    int actual,i,p,a;
    actual=readserial();
    if (hostmon) {                /* where the protocol autostarts */
        actual=XProtocolHostMon(&io,&serbuf[0],actual,512);
        if (actual==0) {
            serread_req->IOSer.io_Data=(APTR)&serbuf[0];
            serread_req->IOSer.io_Length=1;
            SendIO((struct IORequest *)serread_req);
            return;
        }
    }
    for (i=0;i<actual;i++) {
        serbuf[i] = serbuf[i] & 0x7f;     /* strip high bit */
        if (serbuf[i]<32) {
            switch (serbuf[i])
            {
                case 7:
                case 8:
                case 10:
                case 12:
                case 13:
                case 27:
                    break;
                default:                  /* convert garbage to spaces */
                    serbuf[i]=32;
            }
        }
    }
    conwrite_req->io_Data=(APTR)&serbuf[0];
    conwrite_req->io_Length=actual;
    DoIO((struct IORequest *)conwrite_req);
    p=actual;
    i=0;
    if (capture) {                  /* capture to file with 4k buffer */
        while (p>0) {
            if ( txtpos==4096 ) {
                a=fwrite(&txtbuf[0],512,8,fp);
                if (a < 8) {
                    fclose(fp);
                    printstr("\nError writing to file.\n");
                    capture=0;
                }
                txtpos=0;
            }
            txtbuf[txtpos++]=serbuf[i++];
            --p;
        }
    }
    serread_req->IOSer.io_Data=(APTR)&serbuf[0];
    serread_req->IOSer.io_Length=1;
    SendIO((struct IORequest *)serread_req);

}

int readserial()
{
        int len,actual;
        serret=(struct IOExtSer *)GetMsg((struct MsgPort *)serial_portr);
        actual=1;
        serread_req->IOSer.io_Command=SDCMD_QUERY;
        DoIO((struct IORequest *)serread_req);
        serread_req->IOSer.io_Command=CMD_READ;
        len=(struct IORequest *)serread_req->IOSer.io_Actual;
        if (len>0)  {
            if (len>511) len=511;
            serread_req->IOSer.io_Data=(APTR)&serbuf[1];
            serread_req->IOSer.io_Length=len;
            DoIO((struct IORequest *)serread_req);
            actual=actual+len;
        }
        return(actual);
}

VOID dowindow()
{
    while(message=(struct IntuiMessage *)GetMsg(window->UserPort))
    {
        mclass=message->Class;
        mcode=message->Code;
        iaddress=message->IAddress;
        ReplyMsg((struct Message *)message);
        switch (mclass) {
            case MENUPICK:
                domenu();
                break;
            case VANILLAKEY:
                key=(USHORT)mcode;
                serwrite_req->IOSer.io_Data=(APTR)&key;
                serwrite_req->IOSer.io_Length=1;
                DoIO((struct IORequest *)serwrite_req);
                break;
            default:
                break;
        }
    }
    if (doup) {             /* enter protocol from here */
        doupload(NULL);     /* instead of domenu */
        doup=0;
    }
    if (dodwn) {
        dodownload(NULL);
        dodwn=0;
    }
}

VOID domenu()
{
    long status;
    char tbuffer[75];
    while(mcode!=MENUNULL) {
        switch(MENUNUM(mcode)) {
            case 0:
                switch(ITEMNUM(mcode)) {
                    case 0:
                        Request(&myreq,window);
                        break;
                    case 1:
                        ColorRequester(1L);
                        break;
                    case 2:
                        if (custom) {
                            if (tit) {
                                ShowTitle(screen,FALSE);
                                tit=0;}
                            else {
                                ShowTitle(screen,TRUE);
                                tit=1;}
                        }
                        else {
                            strcpy(&tbuffer[0],"");
                            status=GetString(&tbuffer[0],(char *)"Title?", window, 50, 74);
                            if (status==TRUE) SetWindowTitles(window,&tbuffer[0],NULL);
                        }
                        break;
                    case 3:
                        go=0;       /* user chose quit */
                        break;
                }
                break;
            case 1:
                switch(ITEMNUM(mcode)) {
                    case 0:
                        if (capture) closecapture();
                        else opencapture(NULL);
                        break;
                    case 1:
                        dodwn=1;
                        break;
                    case 2:
                        doup=1;
                        break;
                    case 3:
                        doprotocol(NULL,NULL);
                        break;
                }
                break;
            case 2:
                switch(ITEMNUM(mcode)) {
                    case 0:
                        switch(SUBNUM(mcode)) {
                            case 0:
                                baud=1200;
                                break;
                            case 1:
                                baud=2400;
                                break;
                            case 2:
                                baud=9600;
                                break;
                        }
                        break;
                    case 1:
                        set=(SUBNUM(mcode)+1);
                        break;
                }
                setserial(baud,set);
                break;
            case 3:
                asyncRexxCmd(&cmd[(ITEMNUM(mcode)*50)]);  /*run a macro*/
                break;
        } /* end switch(menunum) */
        mitem=(struct MenuItem *)ItemAddress((struct Menu *)&mstrip,mcode);
        mcode=mitem->NextSelect;
    }      /* end while menucode!=menunull */
}       /* end domenu() */

VOID dodownload(filen)
char *filen;
{
    int success;
    if (XProtocolBase==NULL) {
        if (filen==NULL) {
            printstr("\nError: no protocol selected.\n");
            return;}
        else {
            ohshit=10;   /* rexx return code */
            return;}
    }
    if (rxreq & (filen==NULL)) {
        myfilereq.Title=(UBYTE *)"Download to file:";
        success=FileRequester(&myfilereq);
        if (success==FALSE) return;
        io.xpr_filename=&frpath[0];
    }
    else io.xpr_filename=filen;
    printstr("\nWaiting for start...\n");
    AbortIO((struct IORequest *)serread_req);
    Wait(serialmask);
    WaitIO((struct IORequest *)serread_req);
    err=XProtocolReceive(&io);
    if (err && filen) ohshit=15;
    serread_req->IOSer.io_Data=(APTR)&serbuf[0];
    serread_req->IOSer.io_Length=1;
    SendIO((struct IORequest *)serread_req);
    SetWindowTitles(window,0,0);
}

VOID doupload(filen)
char *filen;
{
    int success;
    if (XProtocolBase==NULL) {
        if (filen==NULL) {
            printstr("\nError: no protocol selected.\n");
            return;}
        else {
            ohshit=10;
            return;}
    }
    if (sendreq & (filen==NULL)) {
        myfilereq.Title=(UBYTE *)"Upload File:";
        success=FileRequester(&myfilereq);
        if (success==FALSE) return;
        else io.xpr_filename=&frpath[0];
    }
    else io.xpr_filename=filen;
    AbortIO((struct IORequest *)serread_req);
    Wait(serialmask);
    WaitIO((struct IORequest *)serread_req);
    printstr("\nWaiting for start...\n");
    err=XProtocolSend(&io);
    if (err) ohshit=15;
    serread_req->IOSer.io_Data=(APTR)&serbuf[0];
    serread_req->IOSer.io_Length=1;
    SendIO((struct IORequest *)serread_req);
    SetWindowTitles(window,0,0);
}

VOID doprotocol(proto,op)
char *proto;
char *op;
{
    int success;
    char t[3];
    t[0]=34;
    t[1]=34;
    t[2]=0;
    if (proto==NULL) {
        myfilereq.Title=(UBYTE *)"Select Protocol:";
        strcpy(&frdir[0],(char *)"libs:");
        myfilereq.Dir=&frdir[0];
        strcpy(myfilereq.Show,(char *)"xpr#?.library");
        myfilereq.File=&frfile[0];
        myfilereq.PathName=&frpath[0];
        success=FileRequester(&myfilereq);
        strcpy(&frdir[0],(char *)"");
        strcpy(myfilereq.Show,(char *)"#?");
        if (success==FALSE) return;
    }
    else strcpy(&frpath[0],proto);
    if (XProtocolBase != NULL) {
             XProtocolCleanup(&io);
             CloseLibrary(XProtocolBase);
    }
    XProtocolBase=OpenLibrary((char *)&frpath[0],0);
    if (XProtocolBase==NULL) {
        ohshit=10;
        printstr("\nError: could not open library.\n");
        return;
    }
    io.xpr_update=xupdate;
    io.xpr_fopen=xfopen;
    io.xpr_fclose=xfclose;
    io.xpr_fread=xfread;
    io.xpr_fwrite=xfwrite;
    io.xpr_finfo=xfinfo;
    io.xpr_fseek=xfseek;
    io.xpr_sread=xsread;
    io.xpr_swrite=xswrite;
    io.xpr_sflush=xsflush;
    io.xpr_gets=xgets;
    io.xpr_chkabort=xchkabort;
    if (proto==NULL) io.xpr_filename=NULL;
    else io.xpr_filename=op;
    err=XProtocolSetup(&io);
    if (err == XPRS_FAILURE) {
            XProtocolCleanup(&io);
            CloseLibrary(XProtocolBase);
            printstr("Error: protocol failed to initialize. Library closed.\n");
            hostmon=0;
            ohshit=10;
            return;
    }
    if (err & XPRS_HOSTMON) hostmon=1;
    else hostmon=0;
    if (err & XPRS_NORECREQ) rxreq=0;
    else rxreq=1;
    if (err & XPRS_NOSNDREQ) sendreq=0;
    else sendreq=1;
}

VOID opencapture(file)
char *file;
{
    int success;
    if (file==NULL) {
        myfilereq.Title=(UBYTE *)"Capture to file:";
        success=FileRequester(&myfilereq);
        if (success==FALSE) return;
    }
    else strcpy(&frpath[0],file);
    fp=fopen(&frpath[0],"w");
    if (fp==NULL) {
            printstr("\nError:could not open file.\n");
            ohshit=10;
            return;
    }
    capture=1;
    txtpos=0;
}

VOID closecapture()
{
        if (capture==0) return;
        if (txtpos==4096) fwrite(&txtbuf[0],512,8,fp);
        else {
                txtbuf[txtpos]=0;
                fputs(&txtbuf[0],fp);}
        fclose(fp);
        capture=0;
}

VOID printstr(str)
char *str;
{
        conwrite_req->io_Data=(APTR)str;
        conwrite_req->io_Length=-1;
        DoIO((struct IORequest *)conwrite_req);
}

VOID cleanup(anum)
int anum;
{
        dnRexxPort();
        closecapture();
        switch(anum) {
                case 24:
                 if (XProtocolBase) XProtocolCleanup(&io);
                case 23:
                 if (XProtocolBase) CloseLibrary(XProtocolBase);
                case 22:
                 CloseDevice((struct IORequest *)timerreq);
                case 21:
                 DeleteExtIO( (struct IORequest *)timerreq);
                case 20:
                 DeletePort((struct MsgPort *)timer_port);
                case 19:
                 CloseDevice((struct IORequest *)serread_req);
                case 18:
                 CloseDevice((struct IORequest *)serwrite_req);
                case 17:
                 FreeMem(serread_req,sizeof(struct IOExtSer));
                case 16:
                 FreeMem(serwrite_req,sizeof(struct IOExtSer));
                case 15:
                 DeletePort((struct MsgPort *)serial_portr);
                case 14:
                 DeletePort((struct MsgPort *)serial_portw);
                case 13:
                case 12:
                 CloseDevice((struct IORequest *)conwrite_req);
                case 11:
                case 10:
                 DeleteStdIO(conwrite_req);
                case 9:
                case 8:
                 DeletePort((struct MsgPort *)console_portw);
                case 7:
                 if (custom) myprocess->pr_WindowPtr=oldwin;
                 ClearMenuStrip(window);
                 CloseWindow(window);
                case 5:
                 if (screen) CloseScreen(screen);
                case 3:
                 CloseLibrary(ReqBase);
                case 2:
                 CloseLibrary(IntuitionBase);
                case 1:
                 exit(1);
        }
}

VOID doinit()
{
    int error;
    IntuitionBase=OpenLibrary("intuition.library",0);
    if ( IntuitionBase==NULL ) cleanup(1);
    ReqBase=OpenLibrary("req.library",0);
    if (ReqBase==NULL) cleanup(2);
    if (custom) {
        screen=(struct Screen *)OpenScreen(&cns);
        if (screen==NULL) cleanup(3);
        cnw.Screen=screen;
        window=(struct Window *)OpenWindow(&cnw);
        if ( window==NULL ) cleanup(5);
        ShowTitle(screen,FALSE);
        SetMenuStrip(window,(struct Menu *)&mstrip);
        myprocess=(struct Process *)FindTask(0);
        oldwin=(struct Window *)myprocess->pr_WindowPtr;
        myprocess->pr_WindowPtr=(APTR)window;
    }
    else {
        window=(struct Window *)OpenWindow(&wnw);
        if ( window==NULL ) cleanup(3);
        SetMenuStrip(window,(struct Menu *)&mstrip);
    }
        console_portw=(struct MsgPort *)CreatePort("conportw",0);
        if ( console_portw==NULL ) cleanup(7);
        conwrite_req=(struct IOStdReq *)CreateStdIO((struct MsgPort *)console_portw);
        if ( conwrite_req==NULL ) cleanup(9);
        conwrite_req->io_Data=(APTR)window;
        conwrite_req->io_Length=sizeof(*window);
        error=OpenDevice("console.device",0,(struct IORequest *)conwrite_req,0);
        if ( error != 0 ) cleanup(11);
        conwrite_req->io_Command=CMD_WRITE;

        serial_portw=(struct MsgPort *)CreatePort("serportw",0);
        if ( serial_portw==NULL ) cleanup(13);
        serial_portr=(struct MsgPort *)CreatePort("serportr",0);
        if ( serial_portr==NULL ) cleanup(14);

        serwrite_req=(struct IOExtSer *)AllocMem(sizeof(struct IOExtSer),MEMF_PUBLIC|MEMF_CLEAR);
        if ( serwrite_req==NULL ) cleanup(15);
        serwrite_req->IOSer.io_Message.mn_ReplyPort=serial_portw;
        serwrite_req->io_SerFlags=SERF_SHARED|SERF_XDISABLED;

        serread_req=(struct IOExtSer *)AllocMem(sizeof(struct IOExtSer),MEMF_PUBLIC|MEMF_CLEAR);
        if ( serread_req==NULL ) cleanup(16);
        serread_req->IOSer.io_Message.mn_ReplyPort=serial_portr;
        serread_req->io_SerFlags=SERF_SHARED|SERF_XDISABLED;

        error=OpenDevice("serial.device",0,(struct IORequest *)serwrite_req,0);
        if (error != 0) cleanup(17);
        error=OpenDevice("serial.device",0,(struct IORequest *)serread_req,0);
        if (error != 0) cleanup(18);

        serread_req->io_Baud=1200;
        serread_req->io_ReadLen=8;
        serread_req->io_WriteLen=8;
        serread_req->io_SerFlags &= ~SERF_PARTY_ON;
        serread_req->IOSer.io_Command=SDCMD_SETPARAMS;
        DoIO((struct IORequest *)serread_req);

        serwrite_req->IOSer.io_Command=CMD_WRITE;
        serread_req->IOSer.io_Command=CMD_READ;
        serread_req->IOSer.io_Data=(APTR)&serbuf[0];
        serread_req->IOSer.io_Length=1;
        serialmask=(1<<serial_portr->mp_SigBit);
        windowmask=(1<<window->UserPort->mp_SigBit);

        timer_port=(struct MsgPort *)CreatePort("pdtimer",0);
        if ( timer_port==NULL ) cleanup(19);
        timerreq=(struct timerequest *)CreateExtIO(timer_port,sizeof(struct timerequest) );
        if (timerreq==NULL) cleanup(20);
        error=OpenDevice("timer.device",UNIT_VBLANK,(struct IORequest *)timerreq,0);
        if (error) cleanup(21);
        timermask=(1<<timer_port->mp_SigBit);

        rexxbit = upRexxPort("pmdcom", rcl, "pmd", &disp) ;
        printstr("\n\n");
        if (!(rexxbit)) printstr("Rexxport not active.");
        baud=1200;
        set=1;
        capture=0;
        txtpos=0;
        strcpy(&words[0],(char *)"macro1");    /* what a waste */
        strcpy(&words[50],(char *)"macro2");
        strcpy(&words[100],(char *)"macro3");
        strcpy(&words[150],(char *)"macro4");
        strcpy(&words[200],(char *)"macro5");
        strcpy(&words[250],(char *)"macro6");
        strcpy(&words[300],(char *)"macro7");
        strcpy(&words[350],(char *)"macro8");
        strcpy(&words[400],(char *)"macro9");
        strcpy(&words[450],(char *)"macro0");
        strcpy(&cmd[0],(char *)"macro1");
        strcpy(&cmd[50],(char *)"macro2");
        strcpy(&cmd[100],(char *)"macro3");
        strcpy(&cmd[150],(char *)"macro4");
        strcpy(&cmd[200],(char *)"macro5");
        strcpy(&cmd[250],(char *)"macro6");
        strcpy(&cmd[300],(char *)"macro7");
        strcpy(&cmd[350],(char *)"macro8");
        strcpy(&cmd[400],(char *)"macro9");
        strcpy(&cmd[450],(char *)"macro0");
        myfilereq.Dir=&frdir[0];
        myfilereq.File=&frfile[0];
        myfilereq.PathName=&frpath[0];
}

  /* here are the xpr routines */

long __saveds __regargs xsflush()
{
       long err;
       serread_req->IOSer.io_Command=CMD_CLEAR;
       DoIO((struct IORequest *)serread_req);
       err=(UBYTE)serread_req->IOSer.io_Error;
       serread_req->IOSer.io_Command=CMD_READ;
       if (err) return(1);
       else return(0);
}

long __saveds __regargs xchkabort()
{
   int abort=0;
   while(message=(struct IntuiMessage *)GetMsg(window->UserPort))
   {
        mclass=message->Class;
        mcode=message->Code;
        iaddress=message->IAddress;
        ReplyMsg((struct Message *)message);
        switch (mclass) {
            case VANILLAKEY:
                key=(USHORT)mcode;
                if (key==0x1b) abort=1;
                break;
            default:
                break;
        }
   }
   if (abort) {
      abort=0;
      return(1);
   }
   else return(0);
}

long __saveds __regargs xfinfo(filename,type)
char *filename;
long type;
{
        struct FileInfoBlock fib;
        long ret;
        if (type==2) return(1);    /* cheat, always say it's binary */
        ret=dfind(&fib,filename,0);
        if (ret) return(0);
        ret=fib.fib_Size;
        return(ret);
}

long __saveds __regargs xgets(prompt,buffer)
char *prompt,*buffer;
{
        long status;
        status = GetString(buffer, prompt, window, 50, 255);
        return(status);
}

long __saveds __regargs xfopen(filename,accessmode)
char *filename,*accessmode;
{
        long ret;
        FILE *xfp;
        xfp=fopen(filename,accessmode);
        ret=(FILE *)xfp;
        return(ret);
}

long __saveds __regargs xfclose(xfp)
FILE *xfp;
{
        long ret;
        ret=fclose(xfp);
        return(ret);
}

long __saveds __regargs xfread(buf,size,count,xfp)
char *buf;
long size,count;
FILE *xfp;
{
        long ret;
        ret=fread(buf,size,count,xfp);
        return(ret);
}

long __saveds __regargs xfwrite(buf,size,count,fp)
char *buf;
long size,count;
FILE *fp;
{
        long ret;
        ret=fwrite(buf,size,count,fp);
        return(ret);
}

long __saveds __regargs xfseek(fp,offset,origin)
FILE *fp;
long offset,origin;
{
        long ret;
        ret=fseek(fp,offset,origin);
        return(ret);
}

           /* read from serial port, with timeout */

long __saveds __regargs xsread(buff,length,micros)
char *buff;
long length,micros;
{
   long secs = 0L;
   long i = 0L;
   long l;
   ULONG sigs;

   if (buff == NULL) return(-1L);
   if (micros) {
      if (micros > 1000000L) {             /* recognize this? */
         secs   = micros / 1000000L;
         micros = micros % 1000000L;
      }
      if (micros<2) micros=3;
      timerreq->tr_node.io_Command=TR_ADDREQUEST;
      timerreq->tr_time.tv_secs=secs;
      timerreq->tr_time.tv_micro=micros;
      serread_req->IOSer.io_Command=CMD_READ;
      serread_req->IOSer.io_Data=(APTR)buff;
      serread_req->IOSer.io_Length=1;
      SendIO((struct IORequest *)serread_req);
      SendIO((struct IORequest *)timerreq);
      while(1)
      {
        sigs=Wait(timermask|serialmask);
        if (CheckIO((struct IORequest *)serread_req)) {
                serret=(struct IOExtSer *)GetMsg(serial_portr);
                i++;
                buff++;
                if (i==length) {
                        AbortIO((struct IORequest *)timerreq);
                        Wait(timermask);
                        WaitIO((struct IORequest *)timerreq);
                        return(i);
                }
                serread_req->IOSer.io_Command=CMD_READ;
                serread_req->IOSer.io_Data=(APTR)buff;
                serread_req->IOSer.io_Length=1;
                SendIO((struct IORequest *)serread_req);
        }
        if (CheckIO((struct IORequest *)timerreq)) {
                timerreq=(struct IORequest *)GetMsg(timer_port);
                AbortIO((struct IORequest *)serread_req);
                WaitIO((struct IORequest *)serread_req);
                return(i);
        }
      }
    }
    else {
        serread_req->IOSer.io_Command=SDCMD_QUERY;
        DoIO((struct IORequest *)serread_req);
        l=serread_req->IOSer.io_Actual;
        serread_req->IOSer.io_Command=CMD_READ;
        if (l) {
            serread_req->IOSer.io_Data=(APTR)buff;
            serread_req->IOSer.io_Length=l;
            DoIO((struct IORequest *)serread_req);
        }
        return(l);
    }
}



long __saveds __regargs xswrite(buf,size)
char *buf;
long size;
{
        long ret;
        serwrite_req->IOSer.io_Data=(APTR)buf;
        serwrite_req->IOSer.io_Length=size;
        DoIO((struct IORequest *)serwrite_req);
        ret=(ULONG)serwrite_req->IOSer.io_Actual;
        return(ret);
}


long __saveds __regargs xupdate(ud)   /* display some info about transfer*/
struct XPR_UPDATE *ud;
{
        char out[100];
        char stat[70];
        strcpy(&stat[0],(char *)"   ");
        if (!tit & custom) {
            ShowTitle(screen,TRUE);
            tit=1;
        }
        if (ud->xpru_updatemask & XPRU_PROTOCOL) {
                printstr(ud->xpru_protocol);
                printstr("\n");}
        if (ud->xpru_updatemask & XPRU_FILENAME) {
                printstr(ud->xpru_filename);
                printstr("\n");}
        if (ud->xpru_updatemask & XPRU_MSG) {
                printstr(ud->xpru_msg);
                printstr("\n");}
        if (ud->xpru_updatemask & XPRU_ERRORMSG) {
                printstr(ud->xpru_errormsg);
                printstr("\n");}
        if (ud->xpru_updatemask & XPRU_ERRORS) {
                stci_d(&out[0],ud->xpru_errors);
                printstr(&out);
                printstr(" errors\n");}
        if (ud->xpru_updatemask & XPRU_BYTES) {
                stci_d(&out[0],ud->xpru_bytes);
                strcpy(&stat[0],&out[0]);
                strcat(&stat[0],(char *)" bytes ");}
        if (ud->xpru_updatemask & XPRU_BLOCKS) {
                stci_d(&out[0],ud->xpru_blocks);
                strcat(&stat[0],&out[0]);
                strcat(&stat[0],(char *)" blocks ");}
        if (ud->xpru_updatemask & XPRU_DATARATE) {
                stci_d(&out[0],ud->xpru_datarate);
                strcat(&stat[0],&out[0]);
                strcat(&stat[0],(char *)"cps ");}
        if (ud->xpru_updatemask & XPRU_ELAPSEDTIME) {
                strcat(&stat[0],ud->xpru_elapsedtime);}
        if (ud->xpru_updatemask & XPRU_EXPECTTIME) {
                strcat(&stat[0],(char *)"/");
                strcat(&stat[0],ud->xpru_expecttime);}
        if (custom) SetWindowTitles(window,NULL,(char *)&stat);
        else SetWindowTitles(window,(char *)&stat,NULL);
        return(0);
}


/* the dispatch function for rexx-see arexx disk, minrexx.c example */


int disp(msg, dat, p)
register struct RexxMsg *msg ;
register struct rexxCommandList *dat ;
char *p ;
{
   replyed=0;
   ((int (*)())(dat->userdata))(msg, p) ;
   if (!replyed) replyRexxCmd(msg, 0L, 0L, NULL) ;
   return(0);
}

void rexxquitcom(msg, p)
struct RexxMsg *msg ;
char *p ;
{
   go=0;
}

void rexxdownload(msg, p)
struct RexxMsg *msg;
char *p;
{
   ohshit=0;
   dodownload();
   if (ohshit) {
       replyRexxCmd(msg,ohshit,0,NULL);
       replyed=1;
       return;
   }

}

void rexxupload(msg, p)
struct RexxMsg *msg;
char *p;
{
   ohshit=0;
   doupload();
   if (ohshit) {
       replyRexxCmd(msg,ohshit,0,NULL);
       replyed=1;
       return;
   }

}


void rexxecho(msg, p)
struct RexxMsg *msg;
char *p;
{
   printstr(p);
   printstr("\n");
}

void rexxsend(msg,p)
struct RexMsg *msg;
char *p;
{
   int i=0;
   char lineout[80];
   p=stpblk(p);
   while ( (!(*p==0)) & i<78 ) {
        if (*p=='^') {
            *p++;
            lineout[i]=(*p-64);
            i++;
            *p++;
        }
        else {
            lineout[i]=*p;
            i++;
            *p++;
        }
   }
   lineout[i]=0;
   serwrite_req->IOSer.io_Data=(APTR)&lineout;
   serwrite_req->IOSer.io_Length=-1;
   DoIO((struct IORequest *)serwrite_req);
}



void rexxgetstr(msg, p)
struct RexxMsg *msg;
char *p;
{
    char buffer[256];
    long status;
    status = GetString(&buffer, p, window, 50, 255);
    replyRexxCmd(msg, 0, 0, &buffer);
    replyed=1;
    return;

}


void rexxmacro(msg,p)
struct RexxMsg *msg;
char *p;
{
    char num[10],xword[16],xcmd[50];
    p=stpblk(p);
    p=stptok(p,&num,10," ");
    p=stpblk(p);
    p=stptok(p,&xword,16," ");
    p=stpblk(p);
    p=stptok(p,&xcmd,50," ");
    if ( (atoi(&num)<0) | (atoi(&num)>10) ) {
        replyRexxCmd(msg,10,0,NULL);
        replyed=1;
        return;
    }
    strcpy(&words[(((atoi(&num))-1)*50)],&xword[0]);
    strcpy(&cmd[(((atoi(&num))-1)*50)],&xcmd[0]);
}


void rexxproto(msg,p)
struct RexxMsg *msg;
char *p;
{
    char a[32],b[32];
    p=stpblk(p);
    p=stptok(p,&a[0],32," ");
    p=stpblk(p);
    p=stptok(p,&b[0],32," ");
    ohshit=0;
    doprotocol(&a[0],&b[0]);
    if (ohshit) {
        replyRexxCmd(msg,ohshit,0,NULL);
        replyed=1;
        return;
    }
}


void rexxserial(msg,p)
struct RexxMsg *msg;
char *p;
{
    int i,e;
    char b[10],s[10];
    p=stpblk(p);
    if (!(*p)) return;
    p=stptok(p,&b,10," ");
    p=stpblk(p);
    p=stptok(p,&s,10," ");
    e=setserial(atol(&b),atol(&s));
    if (e) {
        replyRexxCmd(msg,10,0,NULL);
        replyed=1;
        return;
    }
    ClearMenuStrip(window);
    for (i=1;i<4;i++) m2i[i].Flags &= ~CHECKED;
    if (atol(&b)==1200) i=1;
    else if (atol(&b)==2400) i=2;
        else i=3;
    m2i[i].Flags |= CHECKED;
    for (i=5;i<9;i++) m2i[i].Flags &= ~CHECKED;
    m2i[atoi(&s)+4].Flags |= CHECKED;
    SetMenuStrip(window,(struct Menu *)&mstrip);
}

int setserial(baud,set)
long baud;
long set;
{
    int err;
    AbortIO((struct IORequest *)serread_req);
    Wait(serialmask);
    WaitIO((struct IORequest *)serread_req);
    serread_req->IOSer.io_Command=CMD_FLUSH;
    DoIO((struct IORequest *)serread_req);
    serread_req->IOSer.io_Command=CMD_CLEAR;
    DoIO((struct IORequest *)serread_req);
    serread_req->io_Baud=baud;
    if (set==1) {
        serread_req->io_ReadLen=8;
        serread_req->io_WriteLen=8;
        serread_req->io_SerFlags &= ~SERF_PARTY_ON;}
        else if (set==2) {
            serread_req->io_ReadLen=7;
            serread_req->io_WriteLen=7;
            serread_req->io_SerFlags &= ~SERF_PARTY_ON;}
            else if (set==3) {
                serread_req->io_ReadLen=7;
                serread_req->io_WriteLen=7;
                serread_req->io_SerFlags |= SERF_PARTY_ON;
                serread_req->io_SerFlags &= ~SERF_PARTY_ODD;}
                else {
                    serread_req->io_ReadLen=7;
                    serread_req->io_WriteLen=7;
                    serread_req->io_SerFlags |= SERF_PARTY_ON;
                    serread_req->io_SerFlags |= SERF_PARTY_ODD;}
        serread_req->IOSer.io_Command=SDCMD_SETPARAMS;
        DoIO((struct IORequest *)serread_req);
        err=serread_req->IOSer.io_Error;
        serread_req->IOSer.io_Command=CMD_READ;
        serread_req->IOSer.io_Data=(APTR)&serbuf[0];
        serread_req->IOSer.io_Length=1;
        SendIO((struct IORequest *)serread_req);
        return(err);
}


void rexxcapon(msg,p)
struct RexxMsg *msg;
char *p;
{
    ohshit=0;
    p=stpblk(p);
    opencapture(p);
    if (ohshit) {
        replyRexxCmd(msg,ohshit,0,NULL);
        replyed=1;
        return;
    }
}

void rexxcapoff(msg,p)
struct RexxMsg *msg;
char *p;
{
    closecapture();
}

void rexxwaitstr(msg,p)   /*apparently this doesn't work to well at */
struct RexxMsg *msg;      /* 2400. sorry */
char *p;
{
    char dlay[10];
    ULONG sig;
    int actu,i,d;
    p=stpblk(p);
    p=stptok(p,&matchstr[0],10," ");
    p=stpblk(p);
    p=stptok(p,&dlay[0],10," ");
    d=atoi(&dlay[0]);
    timerreq->tr_node.io_Command=TR_ADDREQUEST;
    timerreq->tr_time.tv_secs=d;
    timerreq->tr_time.tv_micro=0;
    match=1;
    matched=0;
    matchptr=&matchstr[0];
    SendIO((struct IORequest *)timerreq);
    while (!matched) {
        sig=Wait(serialmask|windowmask|timermask);
        if (sig & windowmask) dowindow();
        if (CheckIO((struct IORequest *)timerreq)) {
            timerreq=(struct IORequest *)GetMsg(timer_port);
            replyRexxCmd(msg,15,0,NULL);
            replyed=1;
            return;
        }
        if (CheckIO((struct IORequest *)serread_req)) {
            actu=readserial();
            for (i=0;i<actu;i++) {
                if (serbuf[i]==*matchptr) {
                    matchptr++;
                    if (!(*matchptr)) {
                        matched=1;
                        matchptr=&matchstr[0];
                        goto here;
                    }
                }
                else matchptr=&matchstr[0];
            }
here:
            if (actu>0) {
                for (i=0;i<actu;i++) serbuf[i] &= 0x7f;
                conwrite_req->io_Data=(APTR)&serbuf[0];
                conwrite_req->io_Length=actu;
                DoIO((struct IORequest *)conwrite_req);
            }
            serread_req->IOSer.io_Data=(APTR)&serbuf[0];
            serread_req->IOSer.io_Length=1;
            SendIO((struct IORequest *)serread_req);
        }
    }
    AbortIO((struct IORequest *)timerreq);
    Wait(timermask);
    WaitIO((struct IORequest *)timerreq);
}

void rexxpause(msg,p)
struct RexxMsg *msg;
char *p;
{
    int i,d,actu;
    char dlay[10];
    p=stpblk(p);
    p=stptok(p,&dlay[0],10," ");
    d=atoi(&dlay[0]);
    timerreq->tr_node.io_Command=TR_ADDREQUEST;
    timerreq->tr_time.tv_secs=d;
    timerreq->tr_time.tv_micro=0;
    SendIO((struct IORequest *)timerreq);
    while(1) {
        Wait(timermask|serialmask);
        if (CheckIO((struct IORequest *)serread_req)) {
            actu=readserial();
            if (actu>0) {
                for (i=0;i<actu;i++) {
                    serbuf[i] = serbuf[i] & 0x7f;
                    if (serbuf[i]<32) {
                        switch (serbuf[i])
                        {
                            case 7:      /* where have i seen this before */
                            case 8:
                            case 10:
                            case 12:
                            case 13:
                            case 27:
                                break;
                            default:
                                serbuf[i]=32;
                        }
                    }
                }
                conwrite_req->io_Data=(APTR)&serbuf[0];
                conwrite_req->io_Length=actu;
                DoIO((struct IORequest *)conwrite_req);
            }
            serread_req->IOSer.io_Data=(APTR)&serbuf[0];
            serread_req->IOSer.io_Length=1;
            SendIO((struct IORequest *)serread_req);
        }
        if (CheckIO((struct IORequest *)timerreq)) {
            timerreq=(struct IORequest *)GetMsg(timer_port);
            return;
        }
    }
}



