home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 19
/
CD_ASCQ_19_010295.iso
/
dos
/
prg
/
bas
/
pcl4b42
/
xypacket.bas
< prev
next >
Wrap
BASIC Source File
|
1994-09-03
|
8KB
|
310 lines
' -- XYPACKET.BAS --
'
' This program is donated to the Public
' Domain by MarshallSoft Computing, Inc.
' It is provided as an example of the use
' of the Personal Communications Library.
'
' LONG (4-byte) variables are used for checksums
' because Visual Basic doesn't support unsigned
' integers. The string Buffer$ is used because
'
'
DEFINT A-Z
'$INCLUDE: 'DEFINES.BI'
'$INCLUDE: 'TIMING.BI'
'$INCLUDE: 'PCL4B.BI'
'$INCLUDE: 'TERM_IO.BI'
'$INCLUDE: 'CRC.BI'
'$INCLUDE: 'XYPACKET.BI'
DECLARE FUNCTION HIGH (BYVAL Word)
CONST xyBufferSize = 1024
CONST MAXTRY = 3, LIMIT = 20
CONST SOH = 1, STX = 2, EOT = 4
CONST ACK = 6, NAK = 21, CAN = 24
CONST FALSE = 0, TRUE = NOT FALSE
FUNCTION RxPacket (BYVAL Port, BYVAL PacketNbr, Buffer$, PacketSize, BYVAL NCGbyte, EOTflag)
'Port : Port # [0..3)
'PacketNbr : Packet # [0,1,2,...)
'PacketSize: Packet size [128,1024) {returned}
'NCGbyte : NAK, "C", or "G"
'EOTflag : EOT was received {returned}
'
PacketNbr = PacketNbr AND 255
FOR Attempt = 1 TO MAXTRY
'wait FOR SOH / STX
Code = SioGetc(Port, LONG_WAIT * ONE_SECOND)
IF Code = -1 THEN
PRINT "Timed out waiting FOR sender"
RxPacket = FALSE
EXIT FUNCTION
END IF
SELECT CASE Code
CASE SOH
'128 byte buffer incoming
PacketType = SOH
PacketSize = 128
CASE STX
'1024 byte buffer incoming
PacketType = STX
PacketSize = 1024
CASE EOT
'all packets have been sent
Code = SioPutc(Port, ACK)
EOTflag = TRUE
RxPacket = TRUE
EXIT FUNCTION
CASE CAN
'sender has canceled !
PRINT "Canceled by remote"
RxPacket = FALSE
CASE ELSE
'error !
PRINT "Expecting SOH/STX/EOT/CAN not "; Code
RxPacket = FALSE
END SELECT
'receive packet #
Code = SioGetc(Port, ONE_SECOND)
IF Code = -1 THEN
PRINT "Timed out waiting for packet #"
EXIT FUNCTION
END IF
RxPacketNbr = Code AND 255
'receive 1's complement
Code = SioGetc(Port, ONE_SECOND)
IF Code = -1 THEN
PRINT "Timed out waiting for complement of packet #"
RxPacket = FALSE
EXIT FUNCTION
END IF
RxPacketNbrC = Code AND 255
'receive data
CheckSum& = 0
Buffer$ = ""
Buffer$ = STRING$(PacketSize, 0)
FOR I = 1 TO PacketSize
Code = SioGetc(Port, ONE_SECOND)
IF Code = -1 THEN
PRINT "Timed out waiting for data for packet #"
RxPacket = FALSE
EXIT FUNCTION
END IF
MID$(Buffer$, I, 1) = CHR$(Code)
'compute CRC or checksum
IF NCGbyte <> NAK THEN
CheckSum& = UpdateCRC&(CheckSum&, Code)
ELSE
CheckSum& = (CheckSum& + Code) AND 255
END IF
NEXT I
'receive CRC/checksum
IF NCGbyte <> NAK THEN
'receive 2 byte CRC
Code = SioGetc(Port, ONE_SECOND)
IF Code = -1 THEN
PRINT "Timed out waiting for 1st CRC byte"
EXIT FUNCTION
END IF
RxCheckSum1& = Code AND 255
Code = SioGetc(Port, ONE_SECOND)
IF Code = -1 THEN
PRINT "Timed out waiting for 2nd CRC byte"
RxPacket = FALSE
EXIT FUNCTION
END IF
RxCheckSum2& = Code AND 255
RxCheckSum& = (256 * RxCheckSum1&) OR RxCheckSum2&
ELSE
'receive one byte checksum
Code = SioGetc(Port, ONE_SECOND)
IF Code = -1 THEN
PRINT "Timed out waiting for checksum"
RxPacket = FALSE
EXIT FUNCTION
END IF
RxCheckSum& = Code AND 255
END IF
'don't send ACK IF "G"
IF NCGbyte = ASC("G") THEN
RxPacket = TRUE
EXIT FUNCTION
END IF
'packet # and checksum OK ?
IF (RxCheckSum& = CheckSum&) AND (RxPacketNbr = PacketNbr) THEN
'ACK the packet
Code = SioPutc(Port, ACK)
RxPacket = TRUE
EXIT FUNCTION
END IF
'bad packet
IF RxCheckSum& = CheckSum& THEN
PRINT "Bad Packet. Received "; RxPacketNbr; ", expected "; PacketNbr
ELSE
PRINT "Bad Checksum. Received "; RxCheckSum&; ", expected "; CheckSum&
END IF
Code = SioPutc(Port, NAK)
NEXT Attempt
'can't receive packet
PRINT "RX packet timeout"
RxPacket = FALSE
END FUNCTION
FUNCTION RxStartup (BYVAL Port, BYVAL NCGbyte)
'clear Rx buffer
Code = SioRxFlush(Port)
'Send NAKs or "C"s
FOR I = 1 TO LIMIT
AnyKey$ = INKEY$
IF AnyKey$ <> "" THEN
PRINT "Canceled by user"
RxStartup = FALSE
EXIT FUNCTION
END IF
'stop attempting CRC after 1st 4 tries
IF (NCGbyte <> NAK) AND (I = 5) THEN NCGbyte = NAK
'tell sender that I am ready to receive
Code = SioPutc(Port, NCGbyte)
Byte = SioGetc(Port, SHORT_WAIT * ONE_SECOND)
IF Byte <> -1 THEN
'no error -- must be incoming byte -- push byte back onto queue !
Code = SioUnGetc(Port, Byte)
RxStartup = TRUE
EXIT FUNCTION
END IF
NEXT I
'no response
PRINT "No response from sender"
RxStartup = FALSE
END FUNCTION
FUNCTION TxEOT (BYVAL Port)
FOR I = 0 TO 10
Code = SioPutc(Port, EOT)
'await response
Code = SioGetc(Port, SHORT_WAIT * ONE_SECOND)
IF Code = ACK THEN
TxEOT = TRUE
EXIT FUNCTION
END IF
NEXT I
TxEOT = FALSE
END FUNCTION
FUNCTION TxPacket (BYVAL Port, BYVAL PacketNbr, Buffer$, BYVAL PacketSize, BYVAL NCGbyte)
'Port : Port # [0..3)
'PacketNbr : Packet # [0,1,2,...)
'PacketSize: Packet size [128,1024)
'NCGbyte : NAK, "C", or "G"
'
'better be 128 or 1024 packet length
'''PRINT "TxP: Port=";Port;"Packet#=";PacketNbr;"LEN=";LEN(Buffer$);"PacketSize=";PacketSize;",NCGbyte=";CHR$(NCGbyte)
IF PacketSize = 1024 THEN
PacketType = STX
ELSE
PacketType = SOH
END IF
PacketNbr = PacketNbr AND 255
'make up to MAXTRY attempts to send this packet
FOR Attempt = 1 TO MAXTRY
'send SOH/STX
Code = SioPutc(Port, PacketType)
'send packet #
Code = SioPutc(Port, PacketNbr)
'send 1's complement of packet
Code = SioPutc(Port, 255 - PacketNbr)
'send data
CheckSum& = 0
FOR I = 1 TO PacketSize
Byte = ASC(MID$(Buffer$, I, 1))
Code = SioPutc(Port, Byte)
'update checksum
IF NCGbyte <> NAK THEN
CheckSum& = UpdateCRC&(CheckSum&, Byte)
ELSE
CheckSum& = CheckSum& + Byte
END IF
NEXT I
'send checksum
IF NCGbyte <> NAK THEN
'send 2 byte CRC
CS = (CheckSum& \ 256)
Code = SioPutc(Port, CS)
CS = (CheckSum& AND 255)
Code = SioPutc(Port, CS)
ELSE
'send one byte checksum
CS = CheckSum&
Code = SioPutc(Port, CS)
END IF
'don't wait for ACK if "G"
IF NCGbyte = ASC("G") THEN
IF PacketNbr = 0 THEN Code = SioDelay(SHORT_WAIT * ONE_SECOND / 2)
TxPacket = TRUE
EXIT FUNCTION
END IF
'wait for receivers ACK
Code = SioGetc(Port, LONG_WAIT * ONE_SECOND)
IF Code = CAN THEN
PRINT "Canceled by remote"
TxPacket = FALSE
EXIT FUNCTION
END IF
IF Code = ACK THEN
TxPacket = TRUE
EXIT FUNCTION
END IF
IF Code <> NAK THEN
PRINT "Out of sync. Expect ACK or NAK, not"; Code
TxPacket = FALSE
EXIT FUNCTION
END IF
NEXT Attempt
'can't send packet !
PRINT 'Packet timeout for port ';Port
TxPacket = FALSE
END FUNCTION
FUNCTION TxStartup (BYVAL Port, NCGbyte)
'clear Rx buffer
Code = SioRxFlush(Port)
'wait for receivers start up NAK or "C"
FOR I = 1 TO LIMIT
AnyKey$ = INKEY$
IF AnyKey$ <> "" THEN
PRINT "Aborted by user"
TxStartup = FALSE
EXIT FUNCTION
END IF
Code = SioGetc(Port, SHORT_WAIT * ONE_SECOND)
IF Code <> -1 THEN
'received a byte
IF Code = NAK THEN
NCGbyte = NAK
TxStartup = TRUE
EXIT FUNCTION
END IF
IF Code = ASC("C") THEN
NCGbyte = ASC("C")
TxStartup = TRUE
EXIT FUNCTION
END IF
IF Code = ASC("G") THEN
NCGbyte = ASC("G")
TxStartup = TRUE
EXIT FUNCTION
END IF
END IF
NEXT I
'no response
PRINT "no response from receiver"
TxStartup = FALSE
END FUNCTION