!
! NAME: XTRANS
!
! FUNCTION: This is the transmit module for the XMODEM protocol
! support on the AlphaMicro. XRECV provides the receive support.
! First, the receiver sends a NAK sequence to tell the sender to
! begin transmission. Then the sender starts sending blocks. Each
! block consists of 1) SOH; 2) block number; 3) complemented block
! number; 4) 128 data bytes; and 5) a one-byte checksum. The
! receiver responds with an ACK or a NAK depending on whether or
! not the block was successfully received. If not, it is resent.
! If so, the next block is sent. When the entire file has been
! sent, the sender sends an EOT to which the receiver responds with
! an ACK. This program may be interrupted by hitting CTL-C three
! times in a row.
!
! AUTHOR: Tom Dahlquist
!
! EDIT HISTORY:
! When Who What
! 01/17/85 TAD Written (from MTRANS).
! 01/24/85 TAD Allow either three DEL's or CTL-C's to kill us.
!
! This map is for the entire contents of one XMODEM transmission.
! First is the SOH, then the block #, then the inverted block #,
! then 128 data bytes, and finally the checksum.
!
MAP1 WHOLE'BLOCK,X
MAP2 SOH,X,1,CHR$(1)
MAP2 BLOCK'NUMBER,B,1,1
MAP2 NOT'BLOCK'NUMBER,B,1
MAP2 IO'BLOCK,X,128
MAP2 CHECK'SUM'BYTE,X,1
GET'FILENAME:
INPUT LINE "Name of file to be transmitted: ",DISK'FSPEC
DISK'FSPEC=UCS(DISK'FSPEC)
IF DISK'FSPEC[-2,-1]="/D" THEN &
DISK'FSPEC=DISK'FSPEC[1,-3] : &
OPEN #99,"XTRANS.LST",OUTPUT : &
DEBUG=TRUE
I=INSTR(1,DISK'FSPEC,".")
IF I=0 THEN DISK'FSPEC=DISK'FSPEC+".DAT"
LOOKUP DISK'FSPEC,I
IF I=0 THEN &
CALL TRY'AGAIN : &
GOTO GET'FILENAME
XCALL IMG
XCALL FILEIN,1,AREA,DISK'FSPEC
! OPEN #OUT'UNIT, "TRM:", OUTPUT
!
! We first wait for a NAK from the receiver. Then we send
! each block as SOH, block #, inverse block #, 128 data bytes, and
! a one byte checksum. Then we wait for an ACK; if we get a NAK,
! we retransmit the block. After the last block (of each fork) we
! send an EOT and wait for an ACK. That's all folks!
!
START:
CALL GET'ONE
IF TIMEOUT GOTO TIMEOUT
IF IN'CHR=CTRLC THEN &
CALL CTRLC'ABORT : &
GOTO START
IF IN'CHR=DEL THEN &
CALL DEL'ABORT : &
GOTO START
IF IN'CHR#NAK GOTO START
BLOCK'NUMBER=1
LOOP:
XCALL FILEIN,2,AREA,IO'BLOCK,LENGTH
IF LENGTH=0 GOTO EOF
RETRY'BLOCK:
CALL SEND'BLOCK
IF GOT'NAK OR TIMEOUT GOTO RETRY'BLOCK
BLOCK'NUMBER = BLOCK'NUMBER+1
GOTO LOOP
EOF:
CALL SEND'EOT
XCALL FILEIN,3,AREA
END
SEND'BLOCK:
NOT'BLOCK'NUMBER=NOT BLOCK'NUMBER
! CHECK'SUM = 0
! FOR I = 1 TO 131
! CHECK'SUM = CHECK'SUM+ASC(WHOLE'BLOCK[I;1])
! NEXT
! CHECK'SUM'BYTE=CHR$(CHECK'SUM AND 255)
XCALL CMPCRC,IO'BLOCK,CHECK'SUM'BYTE
WAIT'ACK:
GOT'NAK=FALSE
CALL GET'ONE
IF TIMEOUT RETURN
IF IN'CHR = CTRLC THEN &
CALL CTRLC'ABORT : &
GOTO WAIT'ACK
IF IN'CHR=DEL THEN &
CALL DEL'ABORT : &
GOTO WAIT'ACK
IF IN'CHR = NAK THEN &
GOT'NAK=TRUE : &
RETURN
IF IN'CHR <> ACK GOTO WAIT'ACK
RETURN
SEND'EOT:
OUT'CHR=EOT
CALL SEND'ONE
CALL WAIT'ACK
IF GOT'NAK GOTO SEND'EOT
IF TIMEOUT GOTO TIMEOUT
RETURN
GET'ONE:
TIMEOUT=FALSE
XCALL TIMEIN,60,IN'CHR,LENGTH
IF DEBUG AND LENGTH#0 THEN &
?#99,STR(ASC(IN'CHR))
IF LENGTH=0 THEN TIMEOUT=TRUE
RETURN
SEND'ONE:
?#OUT'UNIT,OUT'CHR;
IF DEBUG THEN &
?#99,"-";STR(ASC(OUT'CHR))
RETURN
DEL'ABORT:
TEST'CHR=DEL
GOTO TEST'ABORT
CTRLC'ABORT:
TEST'CHR=CTRLC
TEST'ABORT:
FOR I=1 TO 2
XCALL TIMEIN,2,IN'CHR,LENGTH
IF LENGTH=0 OR IN'CHR#TEST'CHR RETURN
NEXT
?"Ending due to operator interrupt!"
IF DEBUG THEN &
?#99,"Ended due to CTL-C"
END
TIMEOUT:
?"Sorry, your Mac isn't talking to me--ending."
IF DEBUG THEN &
?#99,"Timed out."
END
BAD'FILE:
END
!===================================================================
TRY'AGAIN:
? "That file --- "DISK'FSPEC " --- could not be found. "
?
? "Would you like to: "
? " 1 -- Try Again! "
? " 2 -- Return to the Menu."
INPUT " (enter the number of your choice --- > ", CHOICE
IF CHOICE=1 RETURN
IF CHOICE#2 GOTO TRY'AGAIN
END