! ! 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 MAP1 BLOCK'LENGTH,F,,128 MAP1 IN'CHR,X,1 MAP1 TEST'CHR,X,1 MAP1 OUT'CHR,X,1 MAP1 DISK'FSPEC,S,25 MAP1 OUT'UNIT,F,,0 MAP1 CHECK'SUM,F MAP1 CTRLC,X,1,CHR$(3) MAP1 DEL,X,1,CHR$(255) MAP1 EOT,X,1,CHR$(4) MAP1 ACK,X,1,CHR$(6) MAP1 BELL,X,1,CHR$(7) MAP1 NAK,X,1,CHR$(21) MAP1 ESCAPE,X,1,CHR$(27) MAP1 I,F MAP1 COUNT'BLOCKS,F MAP1 GOT'NAK,F MAP1 DEBUG,F MAP1 TRUE,F,,-1 MAP1 FALSE,F,,0 MAP1 TIMER,F MAP1 CHOICE,F MAP1 AREA,X,616 ! for FILEIN MAP1 LENGTH,F ! from FILEIN and TIMEIN MAP1 TIMEOUT,F 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 IF DEBUG THEN & ?#99,"-";STR(ASC(SOH)) : & ?#99,"-";STR(BLOCK'NUMBER) : & ?#99,"-";STR(NOT'BLOCK'NUMBER) : & ?#99,"DATA BLOCK" : & ?#99,"-";STR(ASC(CHECK'SUM'BYTE)) PRINT #OUT'UNIT,WHOLE'BLOCK; CALL WAIT'ACK RETURN 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