home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1992 Peter Edward Cann, all rights reserved.
- * MicroSoft QuickC
- */
-
- #include<stdio.h>
- #include<bios.h>
- #include<dos.h>
- #include<fcntl.h>
- #include<sys\types.h>
- #include<sys\stat.h>
- #include<signal.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 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 256
-
- #define NAK 21
- #define ACK 6
- #define SOH 1
- #define STX 2
- #define EOT 4
- #define CAN 24
-
- int index, basereg;
- unsigned 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)&RXRDYMASK)
- {
- buf[index++]=inp(basereg)&0xff;
- index=index%TBUFSIZ;
- }
- outp(INTBASE1, INTACK);
- outp(INTBASE2, INTACK);
- }
-
- sendchar(c)
- unsigned char c;
- {
- while(!((inp(basereg+STATREG)&TXMTMASK)&&(inp(basereg+MSTATREG)&CTSMASK)));
- outp(basereg, c);
- }
-
- int follow;
-
- int rcharto(ticks)
- int ticks;
- {
- long tstamp, tstamp1, dayofticksp;
- int c;
- _bios_timeofday(_TIME_GETCLOCK, &tstamp);
- dayofticksp=0;
- while(1)
- {
- if(_bios_timeofday(_TIME_GETCLOCK, &tstamp1))
- dayofticksp+=20*60*60*24;
- if(tstamp1+dayofticksp-tstamp>ticks)
- return(-1); /* NOTE: This is an INT!!! */
- if(follow!=index)
- {
- c=buf[follow++];
- follow=follow%TBUFSIZ;
- return(c);
- }
- }
- }
-
- int calccrc(ptr, count)
- char *ptr;
- int count;
- {
- int crc, i;
- crc = 0;
- while(--count >= 0)
- {
- crc = crc ^ (int)*ptr++ << 8;
- for(i = 0; i < 8; ++i)
- if(crc & 0x8000)
- crc = crc << 1 ^ 0x1021;
- else
- crc = crc << 1;
- }
- return (crc & 0xFFFF);
- }
-
- unsigned char block[1024];
-
- sblock(blockn)
- int blockn;
- {
- unsigned char c;
- unsigned short crc, rcrc;
- int i;
- crc=calccrc(block, 1024);
- sendchar(STX);
- sendchar(blockn);
- sendchar((blockn^0xff)&0xff);
- for(i=0;i<1024;++i)
- sendchar(block[i]);
- sendchar((crc>>8)&0xff);
- sendchar(crc&0xff);
- }
-
- unsigned char shortblock[128];
-
- ssblock(blockn)
- int blockn;
- {
- unsigned char c;
- unsigned short crc, rcrc;
- int i;
- crc=calccrc(shortblock, 128);
- sendchar(SOH);
- sendchar(blockn);
- sendchar((blockn^0xff)&0xff);
- for(i=0;i<128;++i)
- sendchar(shortblock[i]);
- sendchar((crc>>8)&0xff);
- sendchar(crc&0xff);
- }
-
- unsigned intnum;
- unsigned char oldintmask;
-
- cleanup()
- {
- if(intnum==10)
- outp(INTMASK2, oldintmask);
- else
- outp(INTMASK1, oldintmask);
- outp(basereg+INTCTLREG, 0x00);
- outp(basereg+MCTLREG, 0x03);
- _dos_setvect(intnum, oldvect);
- }
-
- quit()
- {
- cleanup();
- exit(99);
- }
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- int i, j, k, l, infd, ok, c;
- unsigned char *blkptr;
- unsigned char newintmask, lctl, dlmsb, dllsb, blocknum;
- long nbytes;
- unsigned speed;
- int comnum;
- char stopbits;
- index=follow=0;
- lctl=0;
- printf("Copyright (C) 1992 Peter Edward Cann, all rights reserved.\n");
- printf("xmodem crc 1k send of %s.\n", argv[4]);
- if(argc!=5)
- {
- printf("USAGE: xmodemr <comnum> <bps> <stopbits> <file pathname>\n");
- exit(1);
- }
- if((infd=open(argv[4], O_RDONLY|O_BINARY))==-1)
- {
- printf("Error opening file %s.\n", argv[4]);
- exit(2);
- }
- comnum=atoi(argv[1])-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(argv[2]);
- 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);
- }
- lctl|=DB8;
- stopbits=argv[3][0];
- switch(stopbits)
- {
- case '1':
- break;
- case '2':
- lctl|=STOP2;
- break;
- default:
- printf("Bad stop bits.\n");
- exit(9);
- }
- signal(SIGINT, quit);
- outp(basereg+LCTLREG, DLAB);
- outp(basereg+DLLSBREG, dllsb);
- outp(basereg+DLMSBREG, dlmsb);
- outp(basereg+LCTLREG, lctl);
- oldvect=_dos_getvect(intnum);
- _dos_setvect(intnum, inthndl);
- outp(basereg+INTCTLREG, 0x00);
- outp(basereg+MCTLREG, 0x0b);
- oldintmask=(intnum==10)?inp(INTMASK2):inp(INTMASK1);
- newintmask=diffintmask;
- newintmask&=oldintmask;
- if(intnum==10)
- outp(INTMASK2, newintmask);
- else
- outp(INTMASK1, newintmask);
- outp(INTBASE1, INTACK);
- outp(INTBASE2, INTACK);
- outp(basereg+INTCTLREG, 0x01);
- outp(INTBASE1, INTACK);
- outp(INTBASE2, INTACK);
- nbytes=0;
- if(rcharto(2000)!='C')
- {
- printf("Spurrious char or no C in 100 seconds.\n");
- cleanup();
- exit(10);
- }
- blocknum=1;
- while(1)
- {
- if((j=read(infd, block, 1024))==0)
- {
- printf("\nEnd of file.\n");
- sendchar(EOT);
- do
- c=rcharto(300);
- while((c!=ACK)&&(c!=NAK)&&(c!=CAN)&&(c!=-1));
- if(c!=ACK)
- {
- printf("No ACK of EOT.\n");
- cleanup();
- exit(13);
- }
- else
- {
- printf("Successful.\n");
- cleanup();
- exit(0);
- }
- }
- for(c=j;c<1024;c++)
- block[c]=26;
- if(j>896)
- {
- i=0;
- do
- {
- printf("\nSending block %d. ", blocknum);
- sblock(blocknum);
- do
- c=rcharto(200);
- while((c!=ACK)&&(c!=NAK)&&(c!=CAN)&&(c!=-1));
- }
- while((c==NAK)&&(i++<10));
- if(c==ACK)
- {
- blocknum++;
- nbytes+=1024;
- printf("Successful. Bytes so far: %ld", nbytes);
- }
- }
- else
- {
- for(k=0;k<(j+128);k+=128)
- {
- i=0;
- do
- {
- for(l=0;l<128;++l)
- shortblock[l]=block[k+l];
- printf("\nSending block %d. ", blocknum);
- ssblock(blocknum);
- do
- c=rcharto(200);
- while((c!=ACK)&&(c!=NAK)&&(c!=CAN)&&(c!=-1));
- }
- while((c==NAK)&&(i++<10));
- if(c!=ACK)
- break;
- else
- {
- blocknum++;
- nbytes+=128;
- printf("Successful. Bytes so far: %ld", nbytes);
- }
- }
- }
- if(c!=ACK)
- if(c==NAK)
- {
- printf("\nRetry limit exceeded.\n");
- cleanup();
- exit(14);
- }
- else
- {
- printf("\nSpurrious character hex %02x; ACK or NAK expected.\n", c);
- cleanup();
- exit(11);
- }
- }
- printf("Programming error; fell through end; see code.\n");
- cleanup();
- exit(12);
- }