?? zmisc.c
字號:
/*--------------------------------------------------------------------------*/
/* FILE: zmisc.c (Opus zmodem routines used by send and receive) */
/* */
/* */
/* The Opus Computer-Based Conversation System */
/* (c) Copyright 1986, Wynn Wagner III, All Rights Reserved */
/* */
/* This implementation of Chuck Forsberg's ZMODEM protocol was */
/* for Opus by Rick Huebner and Wynn Wagner III */
/* */
/* (MSC/4 with /Zp /Ox) */
/* */
/* */
/* */
/* */
/* This module is similar to a routine used by Opus-Cbcs (1.00). It is */
/* provided for your information only. You will find routines that need */
/* to be coded and identifiers to be resolved. */
/* */
/* There is absolutely no guarantee that anything here will work. If you */
/* break this routine, you own both pieces. */
/* */
/* USAGE: You may use this material in any program with no obligation */
/* as long as there is no charge for your program. For more */
/* information about commercial use, contact the "OPUSinfo HERE" */
/* BBS (124/111). */
/* */
/* NOTE: There are a couple of things the Opus implementation does that */
/* aren't part of the original ZModem protocol. They all deal */
/* with WaZOO type ("ZedZap") netmail and should only show up when */
/* used under that condition. */
/* */
/* * The maximum packet size can grow larger than 1k. It is */
/* sensitive to the baud rate. (2400b=2048k; 9600b=8192k) */
/* * The sender must be able to send nothing. In other words, */
/* the sending system must be able to initiate and terminate */
/* a zmodem send session without having to actually send a */
/* file. Normally this kind of thing would never happen in */
/* zmodem. */
/* */
/* */
/*--------------------------------------------------------------------------*/
#include "zmodem.h"
static int Rxtype; /* Type of header received */
static int Rxframeind; /* ZBIN ZBIN32,ZHEX type of frame received */
static char hex[] = "0123456789abcdef";
/* Send a byte as two hex digits */
#define Z_PUTHEX(i,c) {i=(c);SENDBYTE(hex[((i)&0xF0)>>4]);SENDBYTE(hex[(i)&0xF]);}
/*--------------------------------------------------------------------------*/
/* Routines used by other ZModem modules... */
/*--------------------------------------------------------------------------*/
int pascal Z_GetByte(int);
void pascal Z_PutString(unsigned char *);
void pascal Z_SendHexHeader(unsigned short,unsigned char *);
int pascal Z_GetHeader(unsigned char *);
int pascal Z_GetZDL(void);
void pascal Z_PutLongIntoHeader(long);
unsigned short pascal Z_UpdateCRC(unsigned short,unsigned short);
/*--------------------------------------------------------------------------*/
/* Private routines */
/*--------------------------------------------------------------------------*/
static int pascal _Z_qk_read(void);
static int pascal _Z_GetBinaryHeader(unsigned char *);
static int pascal _Z_GetHexHeader(unsigned char *);
static int pascal _Z_GetHex(void);
static int pascal _Z_TimedRead(void);
static long pascal _Z_PullLongFromHeader(unsigned char *);
extern byte *local_CEOL;
extern char *KBD_msg;
void pascal z_message( s )
byte *s;
begin
gotoxy( locate_x+20, locate_y );
if (s) cputs(s);
cputs( local_CEOL );
end
void z_log(s)
byte *s;
begin
word x, y;
z_message(s);
x = locate_x;
y = locate_y;
status_line(s); /* also does disk file logging */
locate_x = x;
locate_y = y;
end
void show_loc(l,w)
unsigned long l;
unsigned int w;
begin
gotoxy( locate_x+35, locate_y );
cprintf("Ofs=%ld Retries=%d%s",l,w,local_CEOL);
end
byte * pascal zalloc()
begin
byte *sptr;
sptr = malloc(WAZOOMAX);
if (!sptr)
begin
status_line("!Z-MEMOVFL");
adios(2);
end
return sptr;
end
/*--------------------------------------------------------------------------*/
/* Z GET BYTE */
/* Get a byte from the modem; */
/* return TIMEOUT if no read within timeout tenths, */
/* return RCDO if carrier lost */
/*--------------------------------------------------------------------------*/
int pascal Z_GetByte(tenths)
register int tenths;
begin
register int i;
i^=i;
do
begin
if (CHAR_AVAIL()) return MODEM_IN();
end
while((i++)<2000);
i = tenths/10;
if (i<1) i = 1;
if (i>58) i = 58;
i = set_timer(i);
while(!CHAR_AVAIL())
begin
if (!CARRIER) return RCDO;
time_release();
if (time_gone(i)) return TIMEOUT;
end
return MODEM_IN();
end
/*--------------------------------------------------------------------------*/
/* QK_READ (like Z_GetByte, but assumes the time to be Rxtimeout) */
/* Get a byte from the modem; */
/* return TIMEOUT if no read within timeout tenths, */
/* return RCDO if carrier lost */
/*--------------------------------------------------------------------------*/
static int pascal _Z_qk_read()
begin
register int i;
register int time_val;
time_val^=time_val;
do
begin
if ((i=MODEM_STATUS())&DATA_READY) return MODEM_IN();
if (!(i&ctl.carrier_mask)) return RCDO;
end
while((time_val++)<2000);
time_val = set_timer(Rxtimeout);
do
begin
if ((i=MODEM_STATUS())&DATA_READY) return MODEM_IN();
if (!(i&ctl.carrier_mask)) return RCDO;
time_release();
end
while(time_left(time_val));
return TIMEOUT;
end
/*--------------------------------------------------------------------------*/
/* Z PUT STRING */
/* Send a string to the modem, processing for \336 (sleep 1 sec) */
/* and \335 (break signal, ignored) */
/*--------------------------------------------------------------------------*/
void pascal Z_PutString(s)
register unsigned char *s;
begin
register int c;
while (*s)
begin
switch (c = *s++)
begin
case '\336': big_pause(2);
case '\335': break;
default: SENDBYTE(c);
end /* switch */
end /* while */
end /* Z_PutString */
/*--------------------------------------------------------------------------*/
/* Z UPDATE CRC */
/* update CRC */
/*--------------------------------------------------------------------------*/
unsigned short pascal Z_UpdateCRC(c, crc)
unsigned short c;
unsigned short crc;
begin
register int count;
register word temp;
temp = crc;
for (count=8; --count>=0; )
begin
if (temp & 0x8000)
begin
temp <<= 1;
temp += (((c<<=1) & 0400) != 0);
temp ^= 0x1021;
end
else
begin
temp <<= 1;
temp += (((c<<=1) & 0400) != 0);
end
end /* for */
return temp;
end /* z_crc update */
/*--------------------------------------------------------------------------*/
/* Z SEND HEX HEADER */
/* Send ZMODEM HEX header hdr of type type */
/*--------------------------------------------------------------------------*/
void pascal Z_SendHexHeader(type, hdr)
unsigned short type;
unsigned char *hdr;
begin
register int n;
register int i;
unsigned short crc;
SENDBYTE(ZPAD);
SENDBYTE(ZPAD);
SENDBYTE(ZDLE);
SENDBYTE(ZHEX);
Z_PUTHEX(i,type);
crc = Z_UpdateCRC(type, 0);
for (n=4; --n >= 0;)
begin
Z_PUTHEX(i,(*hdr));
crc = Z_UpdateCRC(((unsigned short)(*hdr++)), crc);
end
crc = Z_UpdateCRC(0,crc);
crc = Z_UpdateCRC(0,crc);
Z_PUTHEX(i,(crc>>8));
Z_PUTHEX(i,crc);
/* Make it printable on remote machine */
SENDBYTE('\r');
SENDBYTE('\n');
/* Uncork the remote in case a fake XOFF has stopped data flow */
if (type != ZFIN) SENDBYTE(021);
wait_for_clear();
end /* Z_SendHexHeader */
/*--------------------------------------------------------------------------*/
/* Z GET HEADER */
/* Read a ZMODEM header to hdr, either binary or hex. */
/* On success, set Zmodem to 1 and return type of header. */
/* Otherwise return negative on error */
/*--------------------------------------------------------------------------*/
int pascal Z_GetHeader(hdr)
byte *hdr;
begin
register int c;
register int n;
int cancount;
n = cur_baud; /* Max characters before start of frame */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -