home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1992 Peter Edward Cann, all rights reserved.
- * MicroSoft QuickC: >qcl term.c graphics.lib
- */
-
- #include<stdio.h>
- #include<bios.h>
- #include<dos.h>
- #include<fcntl.h>
- #include<signal.h>
- #include<process.h>
-
- #define DLLSBREG 0
- #define DLMSBREG 1
- #define INTCTLREG 1
- #define INTIDREG 2
- #define LCTLREG 3
- #define MCTLREG 4
- #define STATREG 5
- #define MSTATREG 6
-
- #define DCDMASK 0x80
- #define CTSMASK 0x10
- #define TXMTMASK 0x20
- #define RXRDYMASK 0x01
-
- #define INTACK 0x20
-
- #define DB7 0x02
- #define DB8 0x03
- #define STOP2 0x04
- #define PARITYEN 0x08
- #define PARITYEVEN 0x10
- #define DLAB 0x80
-
- #define INTBASE1 0x20
- #define INTMASK1 0x21
- #define INTBASE2 0xa0
- #define INTMASK2 0xa1
-
- #define TBUFSIZ 4096
-
- #define PROGSIZ 256
-
- struct line
- {
- char type;
- union
- {
- unsigned char byte;
- int number;
- struct
- {
- int retries;
- int hits;
- unsigned char label;
- }
- retry;
- struct
- {
- unsigned char label;
- unsigned char string[81];
- }
- l_and_s;
- unsigned char string[81];
- }
- stuff;
- }
- program[PROGSIZ];
-
- #define MAXNSCANS 16
-
- struct
- {
- unsigned char index;
- unsigned char *str;
- unsigned char hitlabel;
- }
- scans[MAXNSCANS];
-
- int nscans;
-
- short int labels[256]; /* Not a #define cause we use unsigned char all over */
-
- int index, basereg;
- char buf[TBUFSIZ];
- unsigned char diffintmask, irqnum;
- void (interrupt far *oldvect)();
-
- void interrupt far inthndl(_es, _ds, _di, _si, _bp, _sp,
- _bx, _dx, _cx, _ax, _ip, _cs, _flags)
- unsigned _es, _ds, _di, _si, _bp, _sp;
- unsigned _bx, _dx, _cx, _ax, _ip, _cs, _flags;
- {
- if(inp(basereg+STATREG)&0x01)
- {
- buf[index++]=inp(basereg)&0xff;
- index=index%TBUFSIZ;
- }
- outp(INTBASE1, INTACK);
- outp(INTBASE2, INTACK);
- }
-
- unsigned char newintmask, oldintmask, lctl, dlmsb, dllsb;
- unsigned intnum;
- unsigned char oldlctl, olddllsb, olddlmsb, oldintctl, oldmctl;
-
- setup()
- {
- outp(basereg+LCTLREG, DLAB);
- olddllsb=inp(basereg+DLLSBREG);
- olddlmsb=inp(basereg+DLMSBREG);
- outp(basereg+DLLSBREG, dllsb);
- outp(basereg+DLMSBREG, dlmsb);
- oldlctl=inp(basereg+LCTLREG);
- outp(basereg+LCTLREG, lctl);
- _dos_setvect(intnum, inthndl);
- oldintctl=inp(basereg+INTCTLREG);
- outp(basereg+INTCTLREG, 0x00);
- oldmctl=inp(basereg+MCTLREG);
- outp(basereg+MCTLREG, 0x0b);
- newintmask=diffintmask;
- newintmask&=oldintmask;
- if(intnum==10)
- outp(INTMASK2, newintmask);
- else
- outp(INTMASK1, newintmask);
- outp(INTBASE1, INTACK); /* Clean up leftovers */
- outp(INTBASE2, INTACK);
- outp(basereg+INTCTLREG, 0x01);
- outp(INTBASE1, INTACK); /* What a zoo! */
- outp(INTBASE2, INTACK);
- }
-
- cleanup()
- {
- if(intnum==10)
- outp(INTMASK2, oldintmask);
- else
- outp(INTMASK1, oldintmask);
- outp(basereg+LCTLREG, DLAB);
- outp(basereg+DLLSBREG, olddllsb);
- outp(basereg+DLMSBREG, olddlmsb);
- outp(basereg+LCTLREG, oldlctl);
- outp(basereg+INTCTLREG, oldintctl);
- outp(basereg+MCTLREG, oldmctl);
- _dos_setvect(intnum, oldvect);
- }
-
- quit()
- {
- cleanup();
- exit(99);
- }
-
- sendchar(c)
- unsigned char c;
- {
- while(!((inp(basereg+STATREG)&TXMTMASK)&&(inp(basereg+MSTATREG)&CTSMASK)))
- {
- if(kbhit())
- getch(); /* Give chance for ^C */
- }
- outp(basereg, c);
- return(0);
- }
-
- int follow;
-
- sleep()
- {
- long tod, tod1, day;
- day=0;
- _bios_timeofday(_TIME_GETCLOCK, &tod);
- while(1)
- {
- if(_bios_timeofday(_TIME_GETCLOCK, &tod1))
- day=20*60*60*24;
- if((tod1+day-tod)>8)
- break;
- }
- }
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- FILE *scriptfd;
- char c, fpname[256], str[81], *strptr;
- char comstr[16], speedstr[16], bitsstr[16];
- int i, j, proglen, value[8], flag, progcnt;
- unsigned speed;
- int comnum;
- char databits, parity, stopbits;
- long timestamp;
- index=follow=0;
- lctl=0;
- printf("Copyright (C) 1992 Peter Edward Cann, all rights reserved.\n");
- if(!strcmp(getenv("REMOTE"), "YES"))
- {
- printf("You appear to be logged in remotely, judging by the environment\n");
- printf("variable REMOTE, so it strikes me as somewhat peculiar that you\n");
- printf("want to run COMSCRPT. Are you sure you want to do it? (y or n) --> ");
- if(getchar()!='y') /* Note getchar() and not getch()! */
- {
- printf("I didn't think so!\n");
- exit(99);
- }
- else
- printf("OK, you're the boss!");
- }
- if(argc!=2)
- {
- printf("USAGE: comscrpt <script file basename>\n");
- printf("The environment variable TERMPATH is used for the script file if set.\n");
- exit(1);
- }
- fpname[0]='\0';
- if(getenv("TERMPATH")==NULL)
- sprintf(fpname, "%s.scr", argv[1]);
- else
- sprintf(fpname, "%s\\%s.scr", getenv("TERMPATH"), argv[1]);
- if((scriptfd=fopen(fpname, "r"))==NULL)
- {
- printf("Error opening script file %s.\n", fpname);
- exit(2);
- }
- fgets(str, 80, scriptfd);
- if(sscanf(str, "%s %s %s", comstr, speedstr, bitsstr)!=3)
- {
- printf("Can't read init params.\n");
- exit(10);
- }
- comnum=atoi(comstr)-1;
- newintmask=0;
- switch(comnum)
- {
- case 0:
- irqnum=4;
- diffintmask=0xff&~0x10;
- basereg=0x3f8;
- break;
- case 1:
- irqnum=3;
- diffintmask=0xff&~0x08;
- basereg=0x2f8;
- break;
- case 2:
- irqnum=4;
- diffintmask=0xff&~0x10;
- basereg=0x3e8;
- break;
- case 3:
- irqnum=3;
- diffintmask=0xff&~0x08;
- basereg=0x2e8;
- break;
- case 4:
- irqnum=2;
- diffintmask=0xff&~0x02;
- basereg=0x3e8;
- break;
- case 5:
- irqnum=2;
- diffintmask=0xff&~0x02;
- basereg=0x2e8;
- break;
- case 6:
- irqnum=5;
- diffintmask=0xff&~0x20;
- basereg=0x3e8;
- break;
- case 7:
- irqnum=5;
- diffintmask=0xff&~0x20;
- basereg=0x2e8;
- break;
- default:
- printf("Bad port choice.\n");
- exit(4);
- }
- intnum=irqnum+8;
- speed=atoi(speedstr);
- switch(speed)
- {
- case 300:
- dlmsb=0;
- dllsb=0xc0;
- break;
- case 1200:
- dlmsb=0;
- dllsb=0x60;
- break;
- case 2400:
- dlmsb=0;
- dllsb=0x30;
- break;
- case 9600:
- dlmsb=0;
- dllsb=0x0c;
- break;
- case 19200:
- dlmsb=0;
- dllsb=0x06;
- break;
- case 38400:
- dlmsb=0;
- dllsb=0x03;
- break;
- case 57600:
- dlmsb=0;
- dllsb=0x02;
- break;
- default:
- printf("Bad speed.\n");
- exit(5);
- }
- parity=bitsstr[1];
- switch(parity)
- {
- case 'e':
- case 'E':
- lctl |= PARITYEN | PARITYEVEN;
- break;
- case 'o':
- case 'O':
- lctl|=PARITYEN;
- break;
- case 'n':
- case 'N':
- break;
- default:
- printf("Bad parity.\n");
- exit(7);
- }
- databits=bitsstr[0];
- switch(databits)
- {
- case '7':
- lctl|=DB7;
- break;
- case '8':
- lctl|=DB8;
- break;
- default:
- printf("Bad data bits.\n");
- exit(8);
- }
- stopbits=bitsstr[2];
- switch(stopbits)
- {
- case '1':
- break;
- case '2':
- lctl|=STOP2;
- break;
- default:
- printf("Bad stop bits.\n");
- exit(9);
- }
- for(i=0;i<256;++i)
- labels[i]=-1;
- oldintmask=(intnum==10)?inp(INTMASK2):inp(INTMASK1);
- oldvect=_dos_getvect(intnum);
- signal(SIGINT, quit);
- setup();
- /* Parse */
- printf("Parsing...\n");
- flag=0;
- for(proglen=0;proglen<PROGSIZ;++proglen)
- {
- if(fgets(str, 80, scriptfd)==NULL)
- {
- flag=1;
- proglen++;
- break;
- }
- for(i=0;i<80;++i)
- if(str[i]=='\n')
- {
- str[i]='\0';
- break;
- }
- else if(str[i]=='\0')
- break;
- if(!strlen(str))
- proglen--;
- else
- {
- if((str[0]!=';')&&(str[1]!=' '))
- {
- printf("Missing first delimiting space at statement %d.\n", proglen);
- printf("Statement reads:\n%s\n", str);
- cleanup();
- exit(11);
- }
- switch(str[0])
- {
- case ':':
- if(sscanf(str, "%*c %d", &value[0])!=1)
- {
- printf("Bad scan of label (:) before statement %d.\n", proglen);
- cleanup();
- exit(11);
- }
- if((value[0]<0)||(value[0]>255))
- {
- printf("Label %d out of range.\n", value[0]);
- cleanup();
- exit(11);
- }
- if(labels[value[0]]!=-1)
- {
- printf("Label %d duplicated at statement %d.\n", value[0], proglen);
- cleanup();
- exit(11);
- }
- labels[value[0]]=proglen;
- proglen--;
- break;
- case 'g':
- case 'G':
- program[proglen].type='g';
- if(sscanf(str, "%*c %d", &value[0])!=1)
- {
- printf("Bad scan of Goto at statement %d.\n", proglen);
- printf("Statement reads:\n%s\n", str);
- cleanup();
- exit(11);
- }
- program[proglen].stuff.byte=(unsigned char)value[0];
- break;
- case 'r':
- case 'R':
- program[proglen].type='r';
- if(sscanf(str, "%*c %d %d", &value[0], &value[1])!=2)
- {
- printf("Bad scan of Retry at statement %d.\n", proglen);
- printf("Statement reads:\n%s\n", str);
- cleanup();
- exit(11);
- }
- program[proglen].stuff.retry.hits=0;
- program[proglen].stuff.retry.label=(unsigned char)value[0];
- program[proglen].stuff.retry.retries=value[1];
- break;
- case 'p':
- case 'P':
- program[proglen].type='p';
- if(sscanf(str, "%*c %d", &value[0])!=1)
- {
- printf("Bad scan of Process at statement %d.\n", proglen);
- printf("Statement reads:\n%s\n", str);
- cleanup();
- exit(11);
- }
- program[proglen].stuff.number=value[0];
- break;
- case '>':
- program[proglen].type='>';
- if(sscanf(str, "%*c %d", &value[0])!=1)
- {
- printf("Bad scan of > at statement %d.\n", proglen);
- printf("Statement reads:\n%s\n", str);
- cleanup();
- exit(11);
- }
- program[proglen].stuff.l_and_s.label=(unsigned char)value[0];
- flag=j=0;
- for(i=2;i<80;++i)
- {
- if(flag)
- if(str[i]=='|')
- program[proglen].stuff.l_and_s.string[j++]='\r';
- else
- program[proglen].stuff.l_and_s.string[j++]=str[i];
- if(str[i]==' ')
- flag=1;
- if(str[i]=='\0')
- break;
- }
- break;
- case '?':
- program[proglen].type='?';
- if(sscanf(str, "%*c %d", &value[0])!=1)
- {
- printf("Bad scan of ? at statement %d.\n", proglen);
- printf("Statement reads:\n%s\n", str);
- cleanup();
- exit(11);
- }
- program[proglen].stuff.byte=value[0];
- break;
- case '<':
- program[proglen].type='<';
- j=0;
- for(i=2;i<80;++i)
- {
- if(str[i]=='|')
- program[proglen].stuff.string[j++]='\r';
- else
- program[proglen].stuff.string[j++]=str[i];
- if(str[i]=='\0')
- break;
- }
- break;
- case '!':
- program[proglen].type='!';
- j=0;
- for(i=2;i<80;++i)
- {
- if(str[i]=='|')
- program[proglen].stuff.string[j++]='\n';
- else if(str[i]=='~')
- program[proglen].stuff.string[j++]='\007';
- else
- program[proglen].stuff.string[j++]=str[i];
- if(str[i]=='\0')
- break;
- }
- break;
- case 's':
- program[proglen].type='s';
- if(sscanf(str, "%*c %d", &value[0])!=1)
- {
- printf("Bad scan of System at statement %d.\n", proglen);
- printf("Statement reads:\n%s\n", str);
- cleanup();
- exit(11);
- }
- program[proglen].stuff.l_and_s.label=value[0];
- flag=j=0;
- for(i=2;i<80;++i)
- {
- if(flag)
- if(str[i]=='|')
- program[proglen].stuff.l_and_s.string[j++]='\r';
- else
- program[proglen].stuff.l_and_s.string[j++]=str[i];
- if(str[i]==' ')
- flag=1;
- if(str[i]=='\0')
- break;
- }
- break;
- case 'q':
- case 'Q':
- program[proglen].type='q';
- if(sscanf(str, "%*c %d", &value[0])!=1)
- {
- printf("Bad scan of Quit at statement %d.\n", proglen);
- printf("Statement reads:\n%s\n", str);
- cleanup();
- exit(11);
- }
- if((value[0]<128)||(value[0]==0))
- {
- printf("Quit with reserved exit code (!=0&&<128) at statement %d.\n", proglen);
- cleanup();
- exit(11);
- }
- program[proglen].stuff.number=value[0];
- break;
- case ';':
- proglen--;
- break;
- default:
- printf("Bad command character %c at statement %d.\n", str[0], proglen);
- printf("Statement reads:\n%s\n", str);
- cleanup();
- exit(10);
- }
- }
- }
- if(!flag)
- {
- printf("Program too long.\n");
- cleanup();
- exit(11);
- }
- /* Check labels */
- printf("Checking branch label validity...\n");
- for(i=0;i<proglen;i++)
- switch(program[i].type)
- {
- case 'g':
- case '?':
- if(labels[program[i].stuff.byte]==-1)
- {
- printf("Unlisted label %d at statement %d (%c).\n", program[i].stuff.byte, i, program[i].type);
- cleanup();
- exit(13);
- }
- break;
- case 'r':
- if(labels[program[i].stuff.retry.label]==-1)
- {
- printf("Unlisted label %d at statement %d (%c).\n", program[i].stuff.retry.label, i, program[i].type);
- cleanup();
- exit(13);
- }
- break;
- case '>':
- if(labels[program[i].stuff.l_and_s.label]==-1)
- {
- printf("Unlisted label %d at statement %d (%c).\n", program[i].stuff.l_and_s.label, i, program[i].type);
- cleanup();
- exit(13);
- }
- break;
- case 's':
- if(labels[program[i].stuff.l_and_s.label]==-1)
- {
- printf("Unlisted label %d at statement %d (%c).\n", program[i].stuff.l_and_s.label, i, program[i].type);
- cleanup();
- exit(13);
- }
- break;
- }
- printf("Executing...\n");
- /* Execute */
- progcnt=nscans=0;
- while(1)
- {
- if(progcnt>=proglen)
- {
- printf("\nFell through end of program.\n");
- cleanup();
- exit(100);
- }
- switch(program[progcnt].type)
- {
- case 'g':
- progcnt=labels[program[progcnt].stuff.byte];
- break;
- case 'r':
- if(++program[progcnt].stuff.retry.hits>=program[progcnt].stuff.retry.retries)
- {
- program[progcnt].stuff.retry.hits=0;
- progcnt=labels[program[progcnt].stuff.retry.label];
- }
- else
- progcnt++;
- break;
- case 'p':
- timestamp=time(NULL);
- flag=1;
- while(flag)
- {
- while(1)
- {
- if((time(NULL)-timestamp)>program[progcnt].stuff.number)
- {
- progcnt++;
- flag=0;
- break;
- }
- if(follow!=index)
- {
- putch(c=buf[follow++]);
- if((c&0x7f)!='\n')
- break;
- }
- if(kbhit())
- getch();
- }
- if(!flag)
- break;
- for(i=0;i<nscans;++i)
- if((scans[i].str[scans[i].index]&0x7f)==(c&0x7f))
- if(scans[i].str[++scans[i].index]=='\0')
- {
- if(labels[scans[i].hitlabel]==-1)
- {
- printf("\nGoto unlisted label %d at statement %d.\n", scans[i].hitlabel, progcnt);
- cleanup();
- exit(12);
- }
- progcnt=labels[scans[i].hitlabel];
- flag=0;
- break;
- }
- else;
- else
- scans[i].index=0;
- }
- nscans=0;
- break;
- case '>':
- if(nscans>=MAXNSCANS)
- {
- printf("Too many lookfors (>).\n");
- progcnt++;
- break;
- }
- scans[nscans].index=0;
- scans[nscans].str=program[progcnt].stuff.l_and_s.string;
- scans[nscans++].hitlabel=program[progcnt].stuff.l_and_s.label;
- progcnt++;
- break;
- case '?':
- if(!((inp(basereg+STATREG)&TXMTMASK)&&(inp(basereg+MSTATREG)&CTSMASK)))
- progcnt=labels[program[progcnt].stuff.byte];
- else
- progcnt++;
- break;
- case '<':
- for(i=0;i<80;i++)
- if(program[progcnt].stuff.string[i]=='\0')
- break;
- else if(program[progcnt].stuff.string[i]=='~')
- sleep();
- else
- sendchar(program[progcnt].stuff.string[i]);
- progcnt++;
- break;
- case '!':
- printf("%s", program[progcnt].stuff.string);
- progcnt++;
- break;
- case 's':
- printf("\n");
- cleanup();
- if(system(program[progcnt].stuff.l_and_s.string)==-1)
- {
- progcnt=labels[program[progcnt].stuff.l_and_s.label];
- }
- else
- progcnt++;
- setup();
- printf("\nBack to script.\n");
- break;
- case 'q':
- cleanup();
- exit(program[progcnt].stuff.number);
- }
- }
- }