827 lines
21 KiB
C
827 lines
21 KiB
C
|
/*****************************************************************************/
|
||
|
/* Copyright (c) 1987 - 1988, Future Soft Engineering, Inc. */
|
||
|
/* Houston, Texas */
|
||
|
/*****************************************************************************/
|
||
|
|
||
|
#define NOLSTRING TRUE /* jtf win3 mod */
|
||
|
#include <windows.h>
|
||
|
#include "port1632.h"
|
||
|
#include "dcrc.h"
|
||
|
#include "dynacomm.h"
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
#define XM_ABORT 0x8000
|
||
|
#define XM_COMPLETE 0x4000
|
||
|
#define XM_BLKREPEAT 0x2000
|
||
|
#define XM_CRC 0x0800
|
||
|
#define YM_1KBLK 0x0400
|
||
|
#define YM_GOPTION 0x0200
|
||
|
#define XM_RETRYMASK 0x001F /* mbbx 1.04: relax 15 -> 31 */
|
||
|
|
||
|
#define XM_RETRIES 0x0014 /* mbbx 1.04: relax 10 -> 20 */
|
||
|
#define XM_RETRYINITCRC 4
|
||
|
#define XM_RETRYINITCKS 10
|
||
|
|
||
|
#define XM_WAITRCVINIT 50 /* mbbx 1.04: relax... */
|
||
|
#define XM_WAITNEXTBLK 100
|
||
|
#define XM_WAITNEXTCHAR 50 //sdj: was 20 to get rid of xmodem
|
||
|
//sdj: retries when moused moved..move to 50
|
||
|
#define XM_WAITSNDINIT 600
|
||
|
|
||
|
|
||
|
BOOL YM_RcvBatch(WORD);
|
||
|
BOOL NEAR YM_RcvFileInfo(WORD *, WORD *);
|
||
|
|
||
|
BOOL XM_RcvFile(WORD);
|
||
|
BOOL NEAR XM_RcvInit(WORD *, WORD *);
|
||
|
BOOL NEAR XM_RcvData(WORD *, WORD *);
|
||
|
BOOL NEAR XM_RcvBlockHeader(WORD *, WORD *);
|
||
|
BOOL NEAR XM_RcvBlockData(WORD *blockNumber, WORD blockSize,WORD *rcvStatus);
|
||
|
VOID NEAR XM_RcvBlockAbort(WORD *);
|
||
|
BOOL NEAR XM_RcvEnd();
|
||
|
VOID NEAR XM_RcvAbort();
|
||
|
|
||
|
BOOL YM_SndBatch(WORD);
|
||
|
BOOL NEAR YM_SndFileInfo(WORD *, BOOL);
|
||
|
|
||
|
BOOL XM_SndFile(WORD sndStatus);
|
||
|
BOOL NEAR XM_SndInit(WORD *);
|
||
|
BOOL NEAR XM_SndData(WORD *);
|
||
|
BOOL NEAR XM_SndBlockData(WORD *, WORD *, WORD *);
|
||
|
BOOL NEAR XM_SndEnd();
|
||
|
VOID NEAR XM_SndAbort();
|
||
|
|
||
|
BYTE XM_CheckSum(BYTE *dataBlock, WORD blockSize); /* mbbx 2.00: NEAR -> FAR */
|
||
|
WORD XM_CalcCRC(BYTE *, INT); /* mbbx 2.00: NEAR -> FAR */
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* UTILITIES --> RCVBFILE.C */
|
||
|
|
||
|
BOOL initXfrBuffer(WORD wBufSize);
|
||
|
VOID fillXfrBuffer(BYTE *, WORD);
|
||
|
WORD readXfrBuffer(BYTE *dataBlock,WORD blockSize,BOOL bBlkRepeat);
|
||
|
BOOL writeXfrBuffer(BYTE *dataBlock, WORD blockSize,BOOL bBlkRepeat);
|
||
|
VOID grabXfrBuffer(BYTE *, WORD);
|
||
|
BOOL clearXfrBuffer();
|
||
|
VOID freeXfrBuffer();
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* XM_RcvFile() - [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
BOOL XM_RcvFile(WORD rcvStatus)
|
||
|
{
|
||
|
WORD blockSize;
|
||
|
|
||
|
if(XM_RcvInit(&blockSize, &rcvStatus))
|
||
|
if(XM_RcvData(&blockSize, &rcvStatus))
|
||
|
if(XM_RcvEnd())
|
||
|
return(TRUE);
|
||
|
|
||
|
XM_RcvAbort();
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* XM_RcvInit() - [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
BOOL NEAR XM_RcvInit(WORD *blockSize, WORD *rcvStatus)
|
||
|
{
|
||
|
BYTE work[3];
|
||
|
WORD retry;
|
||
|
|
||
|
LoadString(hInst, STR_RI, (LPSTR) work, 4); /* mbbx 1.04: REZ... */
|
||
|
bSetup(work);
|
||
|
|
||
|
*blockSize = 128;
|
||
|
*rcvStatus |= XM_RETRIES;
|
||
|
|
||
|
if(*rcvStatus & (YM_1KBLK | YM_GOPTION))
|
||
|
*rcvStatus |= XM_CRC;
|
||
|
|
||
|
while(*rcvStatus & XM_CRC)
|
||
|
{
|
||
|
for(retry = XM_RETRYINITCRC; retry > 0; retry -= 1)
|
||
|
{
|
||
|
modemWr('C');
|
||
|
|
||
|
if(xferPSChar) /* mbbx 1.02: packet switching */
|
||
|
modemWr(xferPSChar);
|
||
|
|
||
|
if(waitRcvChar(work, XM_WAITRCVINIT, 0, CHSTX, CHSOH, CHEOT, CHCAN, NULL))
|
||
|
{
|
||
|
switch(work[0])
|
||
|
{
|
||
|
case CHSTX:
|
||
|
*blockSize = 1024;
|
||
|
/* then fall thru... */
|
||
|
case CHSOH:
|
||
|
return(TRUE);
|
||
|
|
||
|
case CHEOT:
|
||
|
*rcvStatus |= XM_COMPLETE;
|
||
|
return(TRUE);
|
||
|
|
||
|
case CHCAN:
|
||
|
return(FALSE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(xferStopped)
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
*rcvStatus &= ((*rcvStatus & YM_GOPTION) ? ~YM_GOPTION : ~XM_CRC);
|
||
|
}
|
||
|
|
||
|
for(retry = XM_RETRYINITCKS; retry > 0; retry -= 1) /* mbbx 1.04: relax */
|
||
|
{
|
||
|
modemWr(CHNAK);
|
||
|
if(xferPSChar) /* mbbx 1.02: packet switching */
|
||
|
modemWr(xferPSChar);
|
||
|
|
||
|
if(waitRcvChar(work, XM_WAITRCVINIT, 0, CHSTX, CHSOH, CHEOT, CHCAN, NULL))
|
||
|
{
|
||
|
switch(work[0])
|
||
|
{
|
||
|
case CHSTX:
|
||
|
*blockSize = 1024;
|
||
|
/* then fall thru... */
|
||
|
case CHSOH:
|
||
|
return(TRUE);
|
||
|
|
||
|
case CHEOT:
|
||
|
*rcvStatus |= XM_COMPLETE;
|
||
|
return(TRUE);
|
||
|
|
||
|
case CHCAN:
|
||
|
return(FALSE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(xferStopped)
|
||
|
break;
|
||
|
|
||
|
showBErrors(++xferErrors);
|
||
|
}
|
||
|
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* XM_RcvData() - [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
BOOL NEAR XM_RcvData(WORD *blockSize, WORD *rcvStatus)
|
||
|
{
|
||
|
BYTE work[3];
|
||
|
WORD blockNumber = 1;
|
||
|
|
||
|
if(*rcvStatus & XM_COMPLETE)
|
||
|
return(TRUE);
|
||
|
|
||
|
LoadString(hInst, STR_DF, (LPSTR) work, 4); /* mbbx 1.04: REZ... */
|
||
|
bSetup(work);
|
||
|
|
||
|
if(initXfrBuffer(12 * 1024))
|
||
|
{
|
||
|
XM_RcvBlockData(&blockNumber, *blockSize, rcvStatus);
|
||
|
|
||
|
while(!(*rcvStatus & (XM_COMPLETE | XM_ABORT)))
|
||
|
{
|
||
|
if(XM_RcvBlockHeader(blockSize, rcvStatus))
|
||
|
XM_RcvBlockData(&blockNumber, *blockSize, rcvStatus);
|
||
|
}
|
||
|
|
||
|
if(!(*rcvStatus & XM_ABORT))
|
||
|
if(!clearXfrBuffer())
|
||
|
*rcvStatus |= XM_ABORT;
|
||
|
|
||
|
freeXfrBuffer();
|
||
|
}
|
||
|
|
||
|
return(!(*rcvStatus & XM_ABORT));
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* XM_RcvBlockHeader() - [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
BOOL NEAR XM_RcvBlockHeader(WORD *blockSize, WORD *rcvStatus)
|
||
|
{
|
||
|
BYTE work[1];
|
||
|
|
||
|
if(waitRcvChar(work, XM_WAITNEXTBLK, 0, CHSTX, CHSOH, CHEOT, CHCAN, NULL))
|
||
|
{
|
||
|
switch(work[0])
|
||
|
{
|
||
|
case CHSTX:
|
||
|
*blockSize = 1024;
|
||
|
return(TRUE);
|
||
|
|
||
|
case CHSOH:
|
||
|
*blockSize = 128;
|
||
|
return(TRUE);
|
||
|
|
||
|
case CHEOT:
|
||
|
*rcvStatus |= XM_COMPLETE;
|
||
|
return(FALSE);
|
||
|
|
||
|
case CHCAN:
|
||
|
xferStopped = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
XM_RcvBlockAbort(rcvStatus);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* XM_RcvBlockData() - [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
BOOL NEAR XM_RcvBlockData(WORD *blockNumber, WORD blockSize,WORD *rcvStatus)
|
||
|
{
|
||
|
BYTE work[2];
|
||
|
BOOL bBlkRepeat;
|
||
|
WORD ndx;
|
||
|
BYTE dataBlock[1024];
|
||
|
signed char i,j;
|
||
|
|
||
|
while(waitRcvChar(work, XM_WAITNEXTCHAR, 0, 0) &&
|
||
|
waitRcvChar(work+1, XM_WAITNEXTCHAR, 0, 0) &&
|
||
|
( (j=(signed char)work[0]) == ~(i = (signed char)work[1]) ) )
|
||
|
|
||
|
//sdj: on mips xmodem rcv was broken due to (BYTE)~work[1]
|
||
|
|
||
|
{
|
||
|
if(bBlkRepeat = (work[0] != (BYTE) *blockNumber))
|
||
|
if(work[0] != (BYTE) (*blockNumber-1))
|
||
|
break;
|
||
|
|
||
|
for(ndx = 0; ndx < blockSize; ndx += 1)
|
||
|
if(!waitRcvChar(dataBlock+ndx, XM_WAITNEXTCHAR, 0, 0))
|
||
|
break;
|
||
|
if(ndx < blockSize)
|
||
|
break;
|
||
|
|
||
|
if(!waitRcvChar(work, XM_WAITNEXTCHAR, 0, 0))
|
||
|
break;
|
||
|
if(!(*rcvStatus & XM_CRC))
|
||
|
{
|
||
|
if(XM_CheckSum(dataBlock, blockSize) != work[0])
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(!waitRcvChar(work+1, XM_WAITNEXTCHAR, 0, 0) || (XM_CalcCRC(dataBlock, blockSize) != ((work[0] << 8) | work[1])))
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(!writeXfrBuffer(dataBlock, blockSize, bBlkRepeat))
|
||
|
{
|
||
|
xferStopped = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(!bBlkRepeat) /* mbb: reset retry counter */
|
||
|
{
|
||
|
*blockNumber += 1;
|
||
|
*rcvStatus = (*rcvStatus & ~XM_RETRYMASK) | XM_RETRIES;
|
||
|
|
||
|
if(*blockNumber > 1) /* mbb: skip block 0 */
|
||
|
{
|
||
|
if(xferOrig > 0)
|
||
|
{
|
||
|
xferBytes -= blockSize;
|
||
|
updateProgress(FALSE);
|
||
|
}
|
||
|
else
|
||
|
showBBytes(xferLength += blockSize, FALSE); /* mbbx 2.00: xfer ctrls */
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(!(*rcvStatus & YM_GOPTION))
|
||
|
{
|
||
|
modemWr(CHACK);
|
||
|
if(xferPSChar) /* mbbx 1.02: packet switching */
|
||
|
modemWr(xferPSChar);
|
||
|
}
|
||
|
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
XM_RcvBlockAbort(rcvStatus);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* XM_RcvBlockAbort() - [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
VOID NEAR XM_RcvBlockAbort(WORD *rcvStatus)
|
||
|
{
|
||
|
BYTE work[1];
|
||
|
|
||
|
if(xferStopped || (((*rcvStatus -= 1) & XM_RETRYMASK) == 0))
|
||
|
*rcvStatus |= XM_ABORT;
|
||
|
else
|
||
|
{
|
||
|
while(waitRcvChar(work, XM_WAITNEXTCHAR, 0, 0));
|
||
|
modemWr(CHNAK);
|
||
|
if(xferPSChar) /* mbbx 1.02: packet switching */
|
||
|
modemWr(xferPSChar);
|
||
|
}
|
||
|
|
||
|
if(!xferStopped)
|
||
|
showBErrors(++xferErrors);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* XM_RcvEnd() - [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
BOOL NEAR XM_RcvEnd()
|
||
|
{
|
||
|
BYTE work[3];
|
||
|
WORD retry;
|
||
|
|
||
|
LoadString(hInst, STR_RE, (LPSTR) work, 4); /* mbbx 1.04: REZ... */
|
||
|
bSetup(work);
|
||
|
|
||
|
modemWr(CHACK);
|
||
|
if(xferPSChar) /* mbbx 1.02: packet switching */
|
||
|
modemWr(xferPSChar);
|
||
|
|
||
|
for(retry = XM_RETRIES; retry > 0; retry -= 1) /* mbbx 1.04: relax */
|
||
|
{
|
||
|
if(waitRcvChar(work, XM_WAITNEXTBLK / 2, 0, CHEOT, CHCAN, NULL))
|
||
|
{
|
||
|
switch(work[0])
|
||
|
{
|
||
|
case CHEOT:
|
||
|
modemWr(CHACK);
|
||
|
if(xferPSChar) /* mbbx 1.02: packet switching */
|
||
|
modemWr(xferPSChar);
|
||
|
showBErrors(++xferErrors);
|
||
|
continue;
|
||
|
|
||
|
case CHCAN:
|
||
|
xferStopped = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(xferStopped)
|
||
|
break;
|
||
|
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* XM_RcvAbort() - [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
VOID NEAR XM_RcvAbort()
|
||
|
{
|
||
|
BYTE work[1];
|
||
|
|
||
|
rcvAbort();
|
||
|
|
||
|
while(waitRcvChar(work, XM_WAITNEXTCHAR, 0, 0));
|
||
|
modemWr(CHCAN);
|
||
|
modemWr(CHCAN);
|
||
|
modemWr(CHCAN);
|
||
|
modemWr(CHCAN);
|
||
|
modemWr(CHCAN);
|
||
|
modemWr(BS);
|
||
|
modemWr(BS);
|
||
|
modemWr(BS);
|
||
|
modemWr(BS);
|
||
|
modemWr(BS);
|
||
|
if(xferPSChar) /* mbbx 1.02: packet switching */
|
||
|
modemWr(xferPSChar);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* XM_SndFile() - [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
BOOL XM_SndFile(WORD sndStatus)
|
||
|
{
|
||
|
if(XM_SndInit(&sndStatus))
|
||
|
if(XM_SndData(&sndStatus))
|
||
|
if(XM_SndEnd())
|
||
|
return(TRUE);
|
||
|
|
||
|
XM_SndAbort();
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* XM_SndInit() - [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
BOOL NEAR XM_SndInit(WORD *sndStatus)
|
||
|
{
|
||
|
BYTE work[3];
|
||
|
|
||
|
LoadString(hInst, STR_SI, (LPSTR) work, 4); /* mbbx 1.04: REZ... */
|
||
|
bSetup(work);
|
||
|
|
||
|
*sndStatus |= XM_RETRIES;
|
||
|
|
||
|
if(waitRcvChar(work, XM_WAITSNDINIT, 0, 'C', CHNAK, CHCAN, 0))
|
||
|
{
|
||
|
switch(work[0])
|
||
|
{
|
||
|
case 'C':
|
||
|
*sndStatus |= XM_CRC;
|
||
|
if(!(*sndStatus & YM_1KBLK) && waitRcvChar(work, XM_WAITNEXTCHAR / 2, 0, 'K', 0))
|
||
|
*sndStatus |= YM_1KBLK;
|
||
|
return(TRUE);
|
||
|
|
||
|
case CHNAK:
|
||
|
*sndStatus &= ~(XM_CRC | YM_1KBLK);
|
||
|
return(TRUE);
|
||
|
|
||
|
case CHCAN:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* XM_SndData() - [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
BOOL NEAR XM_SndData(WORD *sndStatus)
|
||
|
{
|
||
|
BYTE work[3];
|
||
|
WORD blockNumber = 1;
|
||
|
WORD blockSize;
|
||
|
|
||
|
LoadString(hInst, STR_DF, (LPSTR) work, 4); /* mbbx 1.04: REZ... */
|
||
|
bSetup(work);
|
||
|
|
||
|
if(initXfrBuffer(12 * 1024))
|
||
|
{
|
||
|
blockSize = (!(*sndStatus & YM_1KBLK) ? 128 : 1024);
|
||
|
|
||
|
while(!(*sndStatus & (XM_COMPLETE | XM_ABORT)))
|
||
|
XM_SndBlockData(&blockNumber, &blockSize, sndStatus);
|
||
|
|
||
|
freeXfrBuffer();
|
||
|
}
|
||
|
|
||
|
return(!(*sndStatus & XM_ABORT));
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* XM_SndBlockData() - [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
BOOL NEAR XM_SndBlockData(WORD *blockNumber, WORD *blockSize, WORD *sndStatus)
|
||
|
{
|
||
|
BYTE dataBlock[1024];
|
||
|
WORD dataBytes;
|
||
|
WORD wCRC;
|
||
|
BYTE work[1];
|
||
|
BOOL writeGood;
|
||
|
|
||
|
switch(dataBytes = readXfrBuffer(dataBlock, *blockSize, (*sndStatus & XM_BLKREPEAT)))
|
||
|
{
|
||
|
case (WORD)-1:
|
||
|
xferStopped = TRUE;
|
||
|
break;
|
||
|
|
||
|
case 0:
|
||
|
*sndStatus |= XM_COMPLETE;
|
||
|
return(TRUE);
|
||
|
|
||
|
default:
|
||
|
if((*blockSize == 1024) && (dataBytes <= (5 * 128)) && !(*sndStatus & XM_BLKREPEAT))
|
||
|
readXfrBuffer(dataBlock, *blockSize = 128, TRUE);
|
||
|
|
||
|
modemWr((*blockSize == 128) ? CHSOH : CHSTX);
|
||
|
modemWr((BYTE) *blockNumber);
|
||
|
modemWr((BYTE) ~*blockNumber);
|
||
|
|
||
|
writeGood = modemWrite((LPSTR) dataBlock, (INT)(*blockSize));
|
||
|
|
||
|
if(!writeGood)
|
||
|
{
|
||
|
wCRC = 0;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(!(*sndStatus & XM_CRC))
|
||
|
modemWr(XM_CheckSum(dataBlock, *blockSize));
|
||
|
else
|
||
|
{
|
||
|
wCRC = XM_CalcCRC(dataBlock, *blockSize);
|
||
|
modemWr(HIBYTE(wCRC));
|
||
|
modemWr(LOBYTE(wCRC));
|
||
|
}
|
||
|
if(xferPSChar) /* mbbx 1.02: packet switching */
|
||
|
modemWr(xferPSChar);
|
||
|
|
||
|
if(!waitRcvChar(work, XM_WAITSNDINIT, 0, CHACK, CHNAK, CHCAN, (*blockNumber <= 1) ? 'C' : 0, 0))
|
||
|
{
|
||
|
xferStopped = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
switch(work[0])
|
||
|
{
|
||
|
case CHACK:
|
||
|
*blockNumber += 1;
|
||
|
*sndStatus = (*sndStatus & ~(XM_BLKREPEAT | XM_RETRYMASK)) | XM_RETRIES;
|
||
|
|
||
|
if(*blockNumber > 1)
|
||
|
{
|
||
|
xferBytes -= *blockSize;
|
||
|
updateProgress(FALSE);
|
||
|
}
|
||
|
return(TRUE);
|
||
|
|
||
|
case CHNAK:
|
||
|
break;
|
||
|
|
||
|
case CHCAN:
|
||
|
xferStopped = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(xferStopped || (((*sndStatus -= 1) & XM_RETRYMASK) == 0))
|
||
|
*sndStatus |= XM_ABORT;
|
||
|
else
|
||
|
*sndStatus |= XM_BLKREPEAT;
|
||
|
|
||
|
if(!xferStopped)
|
||
|
showBErrors(++xferErrors);
|
||
|
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* XM_SndEnd() - [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
BOOL NEAR XM_SndEnd()
|
||
|
{
|
||
|
BYTE work[3];
|
||
|
WORD retry;
|
||
|
|
||
|
LoadString(hInst, STR_SE, (LPSTR) work, 4); /* mbbx 1.04: REZ... */
|
||
|
bSetup(work);
|
||
|
|
||
|
for(retry = XM_RETRIES; retry > 0; retry -= 1) /* mbbx 1.04: relax */
|
||
|
{
|
||
|
modemWr(CHEOT);
|
||
|
if(xferPSChar) /* mbbx 1.02: packet switching... */
|
||
|
modemWr(xferPSChar);
|
||
|
|
||
|
if(waitRcvChar(work, XM_WAITNEXTBLK, 0, CHACK, CHCAN, 0)) /* mbbx 1.04: relax 15 -> 60 */
|
||
|
{
|
||
|
switch(work[0])
|
||
|
{
|
||
|
case CHACK:
|
||
|
return(TRUE);
|
||
|
|
||
|
case CHCAN:
|
||
|
xferStopped = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(xferStopped)
|
||
|
break;
|
||
|
|
||
|
showBErrors(++xferErrors);
|
||
|
}
|
||
|
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* XM_SndAbort() - [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
VOID NEAR XM_SndAbort()
|
||
|
{
|
||
|
BYTE work[1];
|
||
|
|
||
|
sndAbort();
|
||
|
|
||
|
modemWr(CHCAN);
|
||
|
modemWr(CHCAN);
|
||
|
modemWr(CHCAN);
|
||
|
modemWr(CHCAN);
|
||
|
modemWr(CHCAN);
|
||
|
modemWr(BS);
|
||
|
modemWr(BS);
|
||
|
modemWr(BS);
|
||
|
modemWr(BS);
|
||
|
modemWr(BS);
|
||
|
if(xferPSChar) /* mbbx 1.02: packet switching */
|
||
|
modemWr(xferPSChar);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* XM_CheckSum() - [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
BYTE XM_CheckSum(BYTE *dataBlock, WORD blockSize) /* mbbx 2.00: NEAR -> FAR */
|
||
|
{
|
||
|
BYTE XM_CheckSum = 0;
|
||
|
|
||
|
while(blockSize > 0)
|
||
|
XM_CheckSum += dataBlock[--blockSize];
|
||
|
|
||
|
return(XM_CheckSum);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* XM_CalcCRC() - [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
WORD XM_CalcCRC(BYTE *dataBlock, INT blockSize)
|
||
|
{
|
||
|
WORD XM_CalcCRC = 0;
|
||
|
INT ndx;
|
||
|
|
||
|
while(--blockSize >= 0)
|
||
|
{
|
||
|
XM_CalcCRC = XM_CalcCRC ^ (((WORD) *dataBlock++) << 8);
|
||
|
for(ndx = 0; ndx < 8; ndx += 1)
|
||
|
{
|
||
|
if(XM_CalcCRC & 0x8000)
|
||
|
XM_CalcCRC = (XM_CalcCRC << 1) ^ 0x1021;
|
||
|
else
|
||
|
XM_CalcCRC = (XM_CalcCRC << 1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(XM_CalcCRC & 0xFFFF);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
/* UTILITIES --> file buffering to be used by all RCV protocols !!! [mbb] */
|
||
|
/*---------------------------------------------------------------------------*/
|
||
|
|
||
|
HANDLE hXfrBuf;
|
||
|
LPSTR lpXfrBuf;
|
||
|
WORD wXfrBufSize;
|
||
|
WORD wXfrBufBytes;
|
||
|
WORD wXfrBufIndex;
|
||
|
WORD wXfrBufExtend;
|
||
|
|
||
|
|
||
|
BOOL initXfrBuffer(WORD wBufSize)
|
||
|
{
|
||
|
wXfrBufSize = wBufSize;
|
||
|
if((hXfrBuf = GlobalAlloc(GMEM_MOVEABLE, (DWORD) wXfrBufSize)) != NULL)
|
||
|
{
|
||
|
#ifdef ORGCODE
|
||
|
if((lpXfrBuf = GlobalWire(hXfrBuf)) != NULL)
|
||
|
#else
|
||
|
if((lpXfrBuf = GlobalLock(hXfrBuf)) != NULL)
|
||
|
#endif
|
||
|
|
||
|
{
|
||
|
wXfrBufBytes = 0;
|
||
|
wXfrBufIndex = 0;
|
||
|
wXfrBufExtend = 0;
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
GlobalFree(hXfrBuf);
|
||
|
}
|
||
|
|
||
|
rcvFileErr();
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
WORD readXfrBuffer(BYTE *dataBlock, WORD blockSize, BOOL bBlkRepeat)
|
||
|
{
|
||
|
if(!bBlkRepeat)
|
||
|
wXfrBufIndex += wXfrBufExtend;
|
||
|
|
||
|
if((wXfrBufIndex+blockSize) > wXfrBufBytes)
|
||
|
{
|
||
|
if((wXfrBufBytes -= wXfrBufIndex) > 0)
|
||
|
lmovmem(lpXfrBuf+wXfrBufIndex, lpXfrBuf, wXfrBufBytes);
|
||
|
|
||
|
if((wXfrBufIndex = (WORD)_lread(xferRefNo, lpXfrBuf, wXfrBufSize-wXfrBufBytes)) == (WORD)-1)
|
||
|
{
|
||
|
return((WORD)-1);
|
||
|
}
|
||
|
|
||
|
wXfrBufBytes += wXfrBufIndex;
|
||
|
wXfrBufIndex = 0;
|
||
|
}
|
||
|
|
||
|
if((wXfrBufExtend = (wXfrBufBytes-wXfrBufIndex)) > 0)
|
||
|
{
|
||
|
if(wXfrBufExtend > blockSize)
|
||
|
wXfrBufExtend = blockSize;
|
||
|
lmovmem(lpXfrBuf+wXfrBufIndex, (LPSTR) dataBlock, wXfrBufExtend);
|
||
|
if(wXfrBufExtend < blockSize)
|
||
|
memset(dataBlock+wXfrBufExtend, CNTRLZ, blockSize-wXfrBufExtend);
|
||
|
}
|
||
|
|
||
|
return(wXfrBufExtend);
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL writeXfrBuffer(BYTE *dataBlock, WORD blockSize,BOOL bBlkRepeat)
|
||
|
{
|
||
|
if(!bBlkRepeat)
|
||
|
wXfrBufBytes += wXfrBufExtend;
|
||
|
|
||
|
if((wXfrBufBytes+blockSize) > wXfrBufSize)
|
||
|
{
|
||
|
if(_lwrite(xferRefNo, lpXfrBuf, wXfrBufBytes) != wXfrBufBytes)
|
||
|
{
|
||
|
rcvFileErr();
|
||
|
return(FALSE);
|
||
|
}
|
||
|
wXfrBufBytes = 0;
|
||
|
}
|
||
|
|
||
|
lmovmem((LPSTR) dataBlock, lpXfrBuf+wXfrBufBytes, wXfrBufExtend = blockSize);
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL clearXfrBuffer()
|
||
|
{
|
||
|
if(wXfrBufExtend > 0)
|
||
|
{
|
||
|
while(wXfrBufExtend > 0) /* mbbx 1.04 ... */
|
||
|
{
|
||
|
if(*(lpXfrBuf+(wXfrBufBytes+wXfrBufExtend-1)) != CNTRLZ)
|
||
|
break;
|
||
|
wXfrBufExtend -= 1;
|
||
|
}
|
||
|
wXfrBufBytes += wXfrBufExtend;
|
||
|
wXfrBufExtend = 0;
|
||
|
}
|
||
|
|
||
|
if(wXfrBufBytes > 0)
|
||
|
{
|
||
|
if(_lwrite(xferRefNo, lpXfrBuf, wXfrBufBytes) != wXfrBufBytes)
|
||
|
{
|
||
|
rcvFileErr();
|
||
|
return(FALSE);
|
||
|
}
|
||
|
wXfrBufBytes = 0;
|
||
|
}
|
||
|
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID freeXfrBuffer()
|
||
|
{
|
||
|
#ifdef ORGCODE
|
||
|
GlobalUnWire(hXfrBuf);
|
||
|
#else
|
||
|
GlobalUnlock(hXfrBuf);
|
||
|
#endif
|
||
|
|
||
|
GlobalFree(hXfrBuf);
|
||
|
}
|