.TITLE VAXLINK
; Entry FTODEV ... RMS BLOCK READ FILE ... QIO TO DEVICE
; Entry DEVTOF ... QIO FROM DEVICE ... RMS BLOCK WRITE TO FILE
; Sender (FTODEV) puts filename in first block to go
; data blocks are 512 bytes with a count in bytes 513,514(word)
; a block sequence no. in 515..518(longword)
; and a checksum in bytes 519..522(longword)
;
; Receiver (DEVTOF) $CREATEs the output file with record attributes
; according to the filename extension. All files except .BCK
; .EXE,.OBJ,.OLB are assumed to be text files with variable
; record length and carriage control attribute.
;
;
; Device characteristics are changed and not reset
; ... reset should be done at command level for
; PARITY/EIGHTBIT/PASSALL/ECHO/TYPEAHEAD/SPEED.
;
; Retransmission of bad blocks June'84 KMW
; Timeout on receiver read & transmitter read of reply. Feb.'86
;
.PSECT DATA,LONG
$SSDEF GLOBAL
$RMSDEF GLOBAL
$TTDEF
.MACRO TESTREP ARG1,ARG2
BLBS R0,ARG1
MOVL ARG2,REPLY
BRW ERROR
.ENDM TESTREP
TREAD: .LONG 0
.LONG 0 ;READ TERMINATOR BIT MASK
REPLY: .LONG 0
XR0: .LONG 0
TDESC: .LONG 12
.LONG TBUF
TBUF: .LONG 0
CBUF: .LONG 0
TC: .LONG 0 ;TERMINAL CHARACTERISTICS
SETM: $QIO EFN=1,FUNC=IO$_SETCHAR,IOSB=IOSBS,-
P1=CBUF,P3=TT$C_BAUD_2400,P5=TT$M_ALTRPAR
BUF: .LONG 512
.LONG BUFA
BUFA: .BLKB 512
RSZ: .WORD 0
SBLKNUM: .LONG 0 ; Sender block sequence number
CSUM: .LONG 0 ; CHECKSUM
XCSUM: .LONG 0
CHANI: .WORD 0
CHANO: .WORD 0 ;INPUT AND OUTPUT CHANNELS
IOSBS: .BLKW 1
IOSBL: .BLKW 1
IOSBD: .BLKL 1
XRIO: $QIO EFN=1,FUNC=IO$_READPBLK!IO$M_NOECHO!IO$M_PURGE!IO$M_TRMNOECHO,IOSB=IOSBS,-
P1=BUFA,P2=522,P4=TREAD
RIO: $QIO EFN=1,FUNC=IO$_READPBLK!IO$M_TIMED!IO$M_NOECHO!IO$M_TRMNOECHO,IOSB=IOSBS,-
P1=BUFA,P2=522,P3=10,P4=TREAD ; as above with timeout
WIO: $QIO EFN=2,FUNC=IO$_WRITEPBLK!IO$M_NOFORMAT,IOSB=IOSBS,-
P1=BUFA,P2=522
XRCS: $QIO EFN=1,FUNC=IO$_READPBLK!IO$M_NOECHO!IO$M_PURGE!IO$M_TRMNOECHO,IOSB=IOSBS,-
P1=XCSUM,P2=8,P4=TREAD
RCS: $QIO EFN=1,FUNC=IO$_READPBLK!IO$M_TIMED!IO$M_NOECHO!IO$M_TRMNOECHO,IOSB=IOSBS,-
P1=XCSUM,P2=8,P3=10,P4=TREAD ; as above with timeout
WCS: $QIO EFN=2,FUNC=IO$_WRITEPBLK!IO$M_NOFORMAT,IOSB=IOSBS,-
P1=XCSUM,P2=8
TIN: .ASCID/TERMIN/
TOUT: .ASCID/TERMOUT/
TUSER: .ASCID/CONSOLE/
DEVIL:
DEVI: .LONG 63 ;INPUT DEVICE DESC
DIA: .LONG DIB
DIB: .BLKB 63
DEVOL:
DEVO: .LONG 63
DOA: .LONG DOB
DOB: .BLKB 63
.ALIGN LONG
INFAB: $FAB FAC=<GET,BIO>,-
FNM=<INFILE>
OUTFAB:$FAB FAC=<PUT,BIO>,-
RAT=CR,-
FNM=<OUTFILE>
IRAB: $RAB FAB=INFAB,-
BKT=0,-
UBF=BUFA,-
USZ=512
ORAB: $RAB FAB=OUTFAB,-
BKT=0,-
RBF=BUFA,-
RSZ=512
LINDX: .WORD 0 ;LOOP INDEX WORD
TEXE: .ASCID/.EXE/
TOBJ: .ASCID/.OBJ/
TOLB: .ASCID/.OLB/
TBCK: .ASCID/.BCK/ ;BACKUP SAVE SET FILE
OUTFILE: .ASCID/OUTFILE/
OUTFL:
OUTFSD: .LONG 512
OUTFSB: .LONG OUTF
OUTF: .BLKB 512 ;MORE THAN ENOUGH
INFILE: .ASCID/INFILE/
INFL:
INFSD: .LONG 512
INFSB: .LONG INF
INF: .BLKB 512
EOFM: .ASCID/End of file/
SENDM: .ASCID/Sending/
RECM: .ASCID/Received ok/
FAILM: .ASCID/!!! Fatal error .. reply codes follow !!!/
ALLOCM: .ASCID/VAXLINK: Channel allocated ok/
LINKFM: .ASCID/VAXLINK: Link failed !/
MODE: .ASCID/MODE/
MODL: .LONG 0
MODT: .LONG 12
.LONG MODA
MODA: .BLKB 12
BELL: .LONG 1
.LONG BELLA
BELLA: .BYTE 7
RBLKNUM: .LONG 0 ; Receiver block sequence no.
WBLKNUM: .LONG 0 ; Write to file check block no.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SENDER ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.PSECT CODE
FTODEV:: .WORD 0
$TRNLOG_S MODE,MODL,MODT
TESTREP T100,#100
T100:
$SETPRI_S PRI=#5
TESTREP T0,#0
T0:
$TRNLOG_S TOUT,DEVOL,DEVO
TESTREP T1,#1
T1: $ALLOC_S DEVNAM=DEVO
TESTREP T11,#11
T11: $ASSIGN_S DEVNAM=DEVO,CHAN=CHANO
TESTREP T2,#2
T2: MOVZWL CHANO,QIO$_CHAN+WIO
MOVZWL CHANO,QIO$_CHAN+RIO
MOVZWL CHANO,QIO$_CHAN+XRIO
MOVZWL CHANO,QIO$_CHAN+WCS
MOVZWL CHANO,QIO$_CHAN+RCS
MOVZWL CHANO,QIO$_CHAN+XRCS
MOVZWL CHANO,QIO$_CHAN+SETM
$GETCHN_S CHAN=CHANO,PRIBUF=TDESC
MOVL #20,REPLY
CMPL R0,#SS$_BUFFEROVF
BEQL SCW
BRW ERROR
SCW: BISL2 #TT$M_NOECHO,TC
BISL2 #TT$M_PASSALL,TC
BISL2 #TT$M_EIGHTBIT,TC
BISL2 #TT$M_NOTYPEAHD,TC
$QIOW_G SETM ; SET TERMINAL CHARACTERISTICS
TESTREP T21,#21
T21:
$OPEN FAB=INFAB
TESTREP T3,#3
T3:
$TRNLOG_S INFILE,INFL,INFSD
TESTREP T31,#31
T31:
MOVW INFL,RSZ
MOVC3 INFL,INF,BUFA
CLRL SBLKNUM ; Clear block sequence no.
$QIOW_G WIO ;SEND FILENAME
TESTREP T32,#32
T32:
$QIOW_G XRCS ;WAIT FOR REPLY no timeout here
TESTREP T33,#33
T33:
$CONNECT RAB=IRAB
TESTREP T4,#4
T4:
INCL SBLKNUM ; block sequence no. (excludes 1st filename blk)
$READ RAB=IRAB
CMPL #RMS$_EOF,R0
BNEQ T49
BRW CLOSEW ;END OF FILE
T49:
TESTREP T5,#5
T5: MOVW IRAB+RAB$W_RSZ,RSZ ;BYTES TRANSFERED
MOVZWL RSZ,XR0
CMPB MODA,#^A/B/ ;BATCH ?
BEQL XMES1
PUSHAL SENDM
CALLS #1,G^LIB$PUT_OUTPUT
XMES1:
MOVW #0,LINDX
CLRL R4
MLOOP:
MOVZWL LINDX,R1
MOVZBL BUFA[R1],R2
ADDL2 R2,R4
ACBW #517,#1,LINDX,MLOOP
MOVL R4,CSUM ;checksum 512 data + 2 count + 4 sequence no.
$QIOW_G WIO
TESTREP T6,#6
T6:
; PUSHAL SBLKNUM
; CALLS #1,TRACE
$QIOW_G RCS
TESTREP T7,#7
T7:
CMPW IOSBS,#SS$_TIMEOUT
BNEQ XRTIM
MOVL #-1,XCSUM ; flag reply timeout
BRW FMESS
XRTIM: CMPL CSUM,XCSUM
BEQL RCOK
FMESS: PUSHAL XCSUM ; XCSUM=0 means other half timed out on last block
; XCSUM=-1 means we timed out reading reply
; else other half reporting checksum fail.
PUSHAL SBLKNUM
CALLS #2,CSFMESS ; output fail message
BRW T5 ; and try sending this block again
; repeat limit 10 set in CSFMESS
RCOK:
CMPB MODA,#^A/B/
BEQL XMES2
PUSHAL RECM
CALLS #1,G^LIB$PUT_OUTPUT
PUSHAL BELL
CALLS #1,G^LIB$PUT_OUTPUT
XMES2:
BRW T4 ;NEXT BLOCK
CLOSEW:
MOVW #0,RSZ
$QIOW_G WIO ;SEND EOF TO RECEIVER
$CLOSE FAB=INFAB
$DASSGN_S CHAN=CHANO
MOVL #63,DEVOL
MOVL #512,INFSD ;RESET DESCRIPTOR
PUSHAL EOFM
CALLS #1,G^LIB$PUT_OUTPUT
;RET
$EXIT_S
ERROR:
MOVL R0,XR0
$CLOSE FAB=INFAB
$CLOSE FAB=OUTFAB
$DASSGN_S CHAN=CHANI
$DASSGN_S CHAN=CHANO
$BRDCST_S LINKFM,TUSER ;Broadcast from batch job
PUSHAL FAILM
CALLS #1,G^LIB$PUT_OUTPUT
PUSHAL REPLY
PUSHAL XR0
CALLS #2,MONITOR
$EXIT_S
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RECEIVER ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DEVTOF:: .WORD 0
$SETPRI_S PRI=#5
TESTREP K0,#0
K0:
$TRNLOG_S TIN,DEVIL,DEVI
TESTREP K1,#1
K1: $ALLOC_S DEVNAM=DEVI
TESTREP K11,#11
K11: $ASSIGN_S DEVNAM=DEVI,CHAN=CHANI
TESTREP K2,#2
K2: MOVZWL CHANI,QIO$_CHAN+RIO
MOVZWL CHANI,QIO$_CHAN+XRIO
MOVZWL CHANI,QIO$_CHAN+WIO
MOVZWL CHANI,QIO$_CHAN+RCS
MOVZWL CHANI,QIO$_CHAN+XRCS
MOVZWL CHANI,QIO$_CHAN+WCS
MOVZWL CHANI,QIO$_CHAN+SETM
MOVL #20,REPLY
$GETCHN_S CHAN=CHANI,PRIBUF=TDESC
CMPL R0,#SS$_BUFFEROVF
BEQL SCR
BRW ERROR
SCR: BISL2 #TT$M_NOECHO,TC
BISL2 #TT$M_PASSALL,TC
BISL2 #TT$M_EIGHTBIT,TC
BISL2 #TT$M_NOTYPEAHD,TC
$QIOW_G SETM
TESTREP K21,#21
K21:
;Channel set up & ready to receive filename
$BRDCST_S ALLOCM,TUSER
$QIOW_G XRIO ; no timeout here
TESTREP K22,#22
K22:
MOVZWL RSZ,OUTFSD
MOVC3 RSZ,BUFA,OUTF
CMPW #0,RSZ
BNEQ K23
MOVL #23,REPLY
BRW ERROR
K23:
$CRELOG_S TBLFLG=#2,LOGNAM=OUTFILE,EQLNAM=OUTFSD
TESTREP K24,#24
K24:
PUSHAL OUTFSD
CALLS #1,G^LIB$PUT_OUTPUT
PUSHAL TEXE
PUSHAL OUTFL
CALLS #2,G^STR$POSITION
CMPL #0,R0
BNEQ EXE
PUSHAL TOBJ
PUSHAL OUTFL
CALLS #2,G^STR$POSITION
CMPL #0,R0
BNEQ OBJ
PUSHAL TOLB
PUSHAL OUTFL
CALLS #2,G^STR$POSITION
CMPL #0,R0
BNEQ EXE ; .OLB SAME AS .EXE
PUSHAL TBCK
PUSHAL OUTFL
CALLS #2,G^STR$POSITION
CMPL #0,R0
BNEQ BCK ;BACKUP SAVE SET FILE
; ELSE TEXT FILE
TEXT:
MOVB #FAB$C_VAR,OUTFAB+FAB$B_RFM ;RFM=VAR
BISB2 #FAB$M_CR,OUTFAB+FAB$B_RAT ;RAT=CR
BISL2 #FAB$M_TEF,OUTFAB+FAB$L_FOP ;FOP=TEF ;TRUNCATE EOF
BRW CREATE
OBJ:
MOVB #FAB$C_VAR,OUTFAB+FAB$B_RFM ;RFM=VAR
CLRB OUTFAB+FAB$B_RAT ;RAT=NONE
BISL2 #FAB$M_TEF,OUTFAB+FAB$L_FOP ;FOP=TEF
BRW CREATE
EXE:
MOVB #FAB$C_FIX,OUTFAB+FAB$B_RFM ;RFM=FIX
MOVW #512,OUTFAB+FAB$W_MRS ;MRS=512
CLRB OUTFAB+FAB$B_RAT ;RAT=NONE
BISL2 #FAB$M_CBT,OUTFAB+FAB$L_FOP ;FOP=CBT ;CONTIGUOUS BEST TRY
BISL2 #FAB$M_TEF,OUTFAB+FAB$L_FOP ;FOP=TEF
MOVL #11,OUTFAB+FAB$L_ALQ ;ALQ=11 ;INITIAL ALLOCATION
BRW CREATE
BCK:
MOVB #FAB$C_FIX,OUTFAB+FAB$B_RFM ;RFM=FIX
MOVW #32256,OUTFAB+FAB$W_MRS ;MRS=32256
CLRB OUTFAB+FAB$B_RAT ;RAT=NONE
BISL2 #FAB$M_TEF,OUTFAB+FAB$L_FOP ;FOP=TEF
MOVL #11,OUTFAB+FAB$L_ALQ ;ALQ=11 INITIAL
CREATE:
$CREATE FAB=OUTFAB
TESTREP K3,#3
K3: $CONNECT RAB=ORAB
TESTREP K4,#4
K4:
CLRL RBLKNUM
CLRL WBLKNUM
$QIOW_G WCS ;READY TO RECEIVE
K41: $QIOW_G RIO ; READ NEXT BLOCK
TESTREP K5,#5
K5:
INCL RBLKNUM ; receiver block no.
; PUSHAL RBLKNUM
; CALLS #1,TRACE
CMPW IOSBS,#SS$_TIMEOUT
BNEQ XTIM
MOVL #0,XCSUM ; flag timeout
BRW RETRY ; report as per checksum fail
XTIM:
MOVW RSZ,ORAB+RAB$W_RSZ ;NO OF BYTES TO WRITE
CMPW #0,RSZ
BNEQ K51
BRW CLOSER ;END OF FILE FROM SENDER
K51:
MOVW #0,LINDX
CLRL R4
NLOOP:
MOVZWL LINDX,R1
MOVZBL BUFA[R1],R2
ADDL2 R2,R4
ACBW #517,#1,LINDX,NLOOP
CMPL R4,CSUM ;CHECKSUM OK ?
BEQL COK
MOVL R4,XCSUM
RETRY: $QIOW_G WCS ;REPORT FAIL TO SENDER
TESTREP K52,#52
K52:
; PUSHAL XCSUM
; PUSHAL RBLKNUM
; CALLS #2,CSFMESS ; report timeout & checksum fails
DECL RBLKNUM ;reset expected sequence no.
BRW K41 ;get block again
COK:
CMPL RBLKNUM,SBLKNUM ; checksum ok so check sequence nos.
BEQL NUMOK
DECL RBLKNUM
CMPL RBLKNUM,SBLKNUM
BNEQ SEQER ; irrecoverable sequence error
; else got previous block again, so just report ok
; & don't write it away. This can happen if the
; sender times out on reading our ok reply.
MOVL R4,XCSUM
BRW K6
SEQER: MOVL #99,REPLY
MOVL #99,R0
BRW ERROR ; fatal error if out of sequence
NUMOK:
MOVL R4,XCSUM
INCL WBLKNUM
CMPL RBLKNUM,WBLKNUM
BEQL WRTBLK ; ok in sequence
DECL WBLKNUM
CMPL RBLKNUM,WBLKNUM ; previous block again ?
BEQL K6 ; yes so ignore it, as timeout repeat
MOVL #98,REPLY
MOVL #98,R0
BRW ERROR ; else can't handle it
WRTBLK:
PUSHAW RSZ
PUSHAL RBLKNUM
CALLS #2,REPORT
$WRITE RAB=ORAB
TESTREP K6,#6
K6: $QIOW_G WCS
TESTREP K7,#7
K7: BRW K41
CLOSER:
$CLOSE FAB=OUTFAB
$DASSGN_S CHAN=CHANI
MOVL #63,DEVIL ;RESET DESCRIPTOR COUNTS
MOVL #512,OUTFSD
PUSHAL EOFM
CALLS #1,G^LIB$PUT_OUTPUT
;RET
$EXIT_S
.END