/*** SFT : serial file transfer for atari portfolio callin sequence: sft [baudrate] terminal emulation * send file * receive file compatible to bruce carbrey's tinyterm, ssend, sreceive r. henze 08.12.89 (transfer.s) last edit 05.01.95 04.01.96 version 4.0 machine type recognized automatically, minor bugs fixed 19.07.93 Cnrtl-C/Cntrl/Break abgeschaltet (Funktion nobreak() anwahl COM-Port ueber tmio_setup 11.06.92 Funktion redit (remote editing) eingefhrt nur fr IBM-PC 09.04.92 send_com, get_com: uebertragung von cr: (ibm-workstation rs6000 uebersetzt cr nach lf im tastaturtreiber) lf --> lf, lf cr --> lf, ff 01.05.90 senden von hexfiles eingefuehrt 19.05.90 ver. 2.0: master/slave-version filetransfer, backup 01.08.90 ver. 3.0: serial port routines replaced by interrupt driven version: tmio.asm 05.10.90 ver. 3.1: machine specific routines extracted to files: sftata.c, sftibm.c 06.11.90 ver. 3.2: output to screen in hex code possible logging of incoming data 09.12.90 : blockwise file-write 08.07.91 ver. 3.3: optionale verz”gerung in put_com (fuer lang- same empf„nger ohne interrupt und puffer, cp/m) ***/ #define ibm 0 #define atari 1 #define machine ibm /* ibm, atari */ /* ibm, portfolio : tmio.asm, assembler routines, interrupt driven */ /* ------------------------------------------------------------------------ */ #if machine == ibm #include #include #include #include #include #endif #include #include #include #define f1 0xbb #define f2 0xbc #define f3 0xbd #define f4 0xbe #define f5 0xbf #define f6 0xc0 #define f7 0xc1 #define f8 0xc2 #define f9 0xc3 #define f10 0xc4 #define cf1 0xde #define cf2 0xdf #define cf3 0xe0 #define cf4 0xe1 #define cf5 0xe2 #define cf6 0xe3 #define cf7 0xe4 #define cf8 0xe5 #define cf9 0xe6 #define cf10 0xe7 #define bufsz 0x400 /* buffer size = block size*/ #define max_retry 5 #define ack 0x06 /* ascii ack = positive acknowlege*/ #define nak 0x15 #define esc 0x1b #define cr 0x0d #define lf 0x0a #define ff 0x0c #define eot 0x04 #define xon 0x11 /*dl1*/ #define xof 0x13 /*dl3*/ #define true 1 #define false 0 #define filnamlen 14 /* laenge filename incl. ext. und laufwerkskennung*/ int xoff_flg ; /* ==1 : xoff was sent */ int chr ; /* character received*/ unsigned char keydown ; /* key pressed*/ unsigned char line[80] ; /* line buffer*/ unsigned char bcheck ; /* checksum transmitted*/ unsigned char checksum ; /* computed checksum*/ unsigned char retry ; /* retry counter*/ unsigned char buf[bufsz]; /* buffer for received data*/ unsigned char dummy; unsigned char hexflg; /* ==true : hex output to screen */ unsigned char logflg; /* ==true : logging incoming data to file */ unsigned int blksz ; /* transmitted block size*/ unsigned int bnum ; /* transmitted block #*/ unsigned int blknum ; /* current block sequence #*/ unsigned int delay ; /* optional delay in put_com */ unsigned int com_port ; /* COM-port # (0,1) == COM1, COM2 */ int speed ; /* baudrate*/ int ser_stat ; /* status serial port */ int cbuf_ful ; /* flag serial port buffer full*/ int i ; /* buffer index*/ int file ; /* file handle for output*/ int scratch; static int baudlist[]= 110,150,300,600,1200,2400,4800,9600,0 ; extern void nobreak(); extern int get_ctc(); /* ------------------------------------------------------------------------ */ /*** Pre-references ***/ void quit(char* msg); unsigned char get_com(); void put_com (unsigned char chr); /*------------------------------------------------------------------------- */ /* ----- error messages and string constants ------------------------------ */ /*------------------------------------------------------------------------- */ #include /*------------------------------------------------------------------------- */ /* ----- machine scpecific code ------------------------------------------- */ /*------------------------------------------------------------------------- */ #if machine == atari #include #include #endif /*------------------------------------------------------------------------- */ #if machine == ibm #include #endif /*------------------------------------------------------------------------- */ /* ----- end of machine scpecific code ----------------------------------- */ /*------------------------------------------------------------------------- */ void getname(line) unsigned char *line; { int i; unsigned char c; i=0; do c = conin(); if (c == 0x08 && i>0) conout(c); i--; else if(i 0) /*puffer nicht leer?*/ *ib = rbuf[staptr]; if (staptr < rbuflen-1) staptr++; else staptr=0; chrnum--; return true; else return false; } /*---------------------------------------*/ void bufini() { staptr=0; endptr=0; chrnum=0; } /*---------------------------------------*/ void savebuf() { unsigned char ib; put(m_filename); getname(line); file = out_open(line); if (file != -1) while (chrnum > 0) if (frombuf(&ib)) write(file,&(unsigned char)ib,1); close(file); put(m_file); put(line); put(m_closed); } /*---------------------------------------*/ void showbuf() { unsigned short wptr; unsigned short wnum; unsigned char ib; wnum = chrnum; wptr = staptr; /*staptr und chrnum retten*/ while(frombuf(&ib) || kbhit()) conout(ib); chrnum = wnum; staptr = wptr; /*staptr und chrnum restaurieren*/ } /*----------------------------------------------------------------------------*/ void quit(msg) char *msg; { exit_com(); close(file); put(nl); put(msg); exit (1); } /* ------------------------------------------------------------------------ */ void wait(delay) unsigned int delay; unsigned int i; unsigned int k; for (i=0; i key on keyboard and aborts if pressed.*/ { int chr; register unsigned char c; do if (kbhit()) c = conin(); if (c == esc) quit(m_escp); while (!receive_com(&chr)); return((unsigned char)chr); } /* ------------------------------------------------------------------------ */ unsigned char get_com_8b() /* wait for byte from aux port. return data byte. tests for key on keyboard and aborts if pressed.*/ register int i; register unsigned char chr; i = (get_com()&0x03)<<7; i = i + get_com() - 32; return((unsigned char)(i&0x00ff)); /* ------------------------------------------------------------------------ */ void put_com (chr) /* output byte to com port;*/ /* if error, display error; if esc key pressed, abort.*/ unsigned char chr; { do if (delay) wait(delay); /*optionale verz”gerung*/ if (send_com(chr)) return; if (kbhit()) if (conin() == esc) quit(m_escp); while (true); } /* ------------------------------------------------------------------------ */ void put_com_8b (chr) /* output 8 Bit char splitted into two bytes */ unsigned char chr; register int i; i=chr+32; put_com((unsigned char)(((i&0x0180)>>7)|0x0040)); put_com((unsigned char)(i&0x007f)); /* ------------------------------------------------------------------------ */ void out_blk() /* output block number blknum to port*/ /* buf holds data*/ /* blksz is size of block, 0 for eof*/ { unsigned char ib; retry = 0; do checksum=0; ib = blknum & 0x00ff; checksum = checksum ^ ib; put_com_8b(ib); ib = (blknum>>8) & 0x00ff; checksum = checksum ^ ib; put_com_8b(ib); ib = blksz & 0x00ff; checksum = checksum ^ ib; put_com_8b(ib); ib = (blksz>>8) & 0x00ff; checksum = checksum ^ ib; put_com_8b(ib); if ( blksz > 0) for (i=0; i 1) put_com(ack); /* ack the receipt of prior block*/ if (blknum == 2) put(nl); conout(cr); put(m_block); hex(blknum); do checksum=0; ib = get_com_8b(); checksum=checksum ^ ib; bnum = ib; ib = get_com_8b(); checksum=checksum ^ ib; bnum = bnum | (ib<<8); if (blknum != bnum) quit(m_bse); ib = get_com_8b(); checksum=checksum ^ ib; blksz = ib; ib = get_com_8b(); checksum=checksum ^ ib; blksz = blksz | (ib<<8); for (i=0; i 0) put(m_recov); if (blksz==0) put_com(ack); /* ack final block*/ return; retry++; if (retry==1) put(m_chserr); put_com(nak); /* negative acknowlege, retry*/ while (retry < max_retry); quit(m_irrecov); } /* ------------------------------------------------------------------------ */ void input_fil() { blknum=0; /* block sequence #*/ do blknum++; input_blk() ; if (blksz > 0) write(file,buf,blksz); while (blksz > 0); } /* ------------------------------------------------------------------------ */ void receive() { put(m_rec); getname(line); file = out_open(line); if (file == -1) quit(fo_errmess); while (receive_com(&scratch)) /* empty serial port reciever*/ ; put (m_startsend); put (m_esce); input_fil(); close(file); put(m_sucrec); } /* ------------------------------------------------------------------------ */ void mreceive(str) unsigned char *str; { int status; int i; while (receive_com(&scratch)) /* empty serial port reciever*/ ; if (send_com(f2)) do chr = get_com(); while(chr != ack); i=0; do put_com(str[i]); i++; while (str[i-1] != 0); file = out_open(line); if (file == -1) quit(fo_errmess); put_com(ack); getftimdat(); do chr = get_com(); while(chr != ack); put(m_receivng); put(line); put(m_esce); put_com(ack); input_fil(); setfiletime(file); close(file); put(m_sucrec); } /* ------------------------------------------------------------------------ */ void sreceive() { put_com(ack); i = 0; do line[i] = get_com(); i++; while (line[i-1] != 0); put(".start"); file = out_open(line); if (file == -1) quit(fo_errmess); put(".start"); put_com(ack); getftimdat(); while (receive_com(&scratch)) /* empty serial port reciever*/ ; put(m_receivng); put(line); put(m_esce); put_com(ack); input_fil(); setfiletime(file); close(file); put (m_sucrec); } /* ------------------------------------------------------------------------ */ void send() { put(m_send); getname(line); file = in_open(line); if (file == -1) quit(fi_errmess); while (receive_com(&scratch)) /* empty serial port reciever*/ ; out_fil(line); close(file); } /* ------------------------------------------------------------------------ */ void msend(str) unsigned char *str; { int i; file = in_open(str); if (file == -1) quit(fi_errmess); while (receive_com(&scratch)) /* empty serial port receiver*/ ; if (send_com(f1)) do chr = get_com(); while(chr != ack); i=0; do put_com(str[i]); i++; while (str[i-1] != 0); getfiletime(file); do chr = get_com(); while(chr != ack); putftimdat(); do chr = get_com(); while(chr != ack); out_fil(str); close(file); } /* ------------------------------------------------------------------------ */ void ssend() { put_com(ack); i = 0; do line[i] = get_com(); i++; while (line[i-1] != 0); file = in_open(line); if (file == -1) quit(fi_errmess); getfiletime(file); do chr = get_com(); while(chr != ack && chr != nak); if(chr==ack) putftimdat(); while (receive_com(&scratch)) /* empty serial port reciever*/ ; put_com(ack); do chr = get_com(); while(chr != ack); out_fil(line); else put(fe_errmess); close(file); } /* ------------------------------------------------------------------------ */ void sshex() { FILE *infile; put(m_send); getname(line); infile = fopen(line,"r"); if (infile == NULL) quit(fi_errmess); put(m_sending); put(line); put(m_esce); while (fgets(line,80,infile)) i = strlen(line); if (i>0) line[i-1] = 0; /* LF entfernen ! */ i = 0; while (i < 80 && line[i] != 0) put_com(line[i]); if (receive_com(&chr)) /* any input from com port?*/ conout(chr); /* display it on screen*/ /* wait(5000);*/ i++; chr = get_com(); if(chr == ack) put(m_nack); else if(chr == nak) quit(m_nack); if(chr == eot) break; fclose(infile); put(m_transm); } /* ------------------------------------------------------------------------ */ void backup() { int stat; struct ffblk fblock; stat = findfirst("*.*", &fblock, 0); do if (!stat) strcpy(line,fblock.ff_name); msend(line); stat = findnext(&fblock); while (!stat); put(m_backuprdy); } /* ------------------------------------------------------------------------ */ void help() { put (m_help0); put (m_help1); put (m_help2); put (m_help3); put (m_help4); put (m_help5); put (m_help6); } /* ------------------------------------------------------------------------ */ void main(argc,argv) int argc; char *argv[]; { help(); hexflg = false; logflg = false; xoff_flg = false; bufini(); if (argc > 1) speed = atoi(argv[1]); else speed = 9600; if (argc > 2) com_port = atoi(argv[2]); else com_port = 0; if (argc > 3) delay = atoi(argv[3]); else delay = 0; i=0; while (baudlist[i]) if (speed == baudlist[i]) init_com(i,com_port); break; i++; if (!baudlist[i]) put(m_badbaud); exit(1); nobreak(); keydown = 0; do if (kbhit()) keydown = conin(); if (keydown == f8 || keydown == esc) /* terminate?*/ break; /* yes, exit*/ switch(keydown) case f1: /*f1 ? receive */ receive(); break; case f2: /*f2 ? send */ send(); break; case f3: /*f3 ? sshex */ sshex(); break; case f5: /*f5 ? toggle hex output flag */ if (hexflg == false) hexflg = true; else hexflg = false; break; case f6: /*f6 ? toggle logging of incoming data */ if (logflg == false) put(m_logging); logflg = true; else savebuf(); logflg = false; break; case f9: /*f9 ? display logbuffer */ showbuf(); break; case cf1: /*cf1 ? mreceive */ put(m_rec); getname(line); mreceive(line); break; case cf2: /*cf2 ? msend */ put(m_send); getname(line); msend(line); break; case cf4: /*cf4 ? backup */ backup(); break; case f7: /*f7 ? help */ help(); break; default: if (send_com(keydown)) /* able to send key on comx?*/ ; else show_port_error(m_sendcom,ser_stat); /* display why we can't transmit*/ if (get_ctc()) if (send_com(03)) ; if ((xoff_flg == true) && (tmdp_cnt < 10)) send_com(xon); xoff_flg = false; if (receive_com(&chr)) /* any input from com port?*/ if (tmdp_cnt > tmdp_lim && xoff_flg == false) send_com(xof); xoff_flg = true; switch(chr) case f1: /*f1 ? sreceive */ sreceive(); break; case f2: /*f2 ? ssend */ ssend(); break; case f10: /*f10 ? acknowledge connction*/ put_com(cr); put_com(lf); i= 0; while (connection[i] != 0) put_com(connection[i]); i++; break; default: if (hexflg == true) hex8(chr); /*display it in hex code*/ else conout(chr); /* display it on screen*/ if (logflg == true) if (!tobuf((unsigned char)chr)) put(m_ringbfful); while (keydown!=f8); close(file); exit_com(); put(m_exit); } /*---------------------- end of file sft.i -------------------------------*/