.TITLE FTCOPY MAIN PROGRAM FOR FOREIGN TAPE COPYING.
.IDENT /30-APR-1984 V01.D/
; Foreign tape copy.
;
; V01.D TWD 30-APR-1984 Add copyright note and check buffer
; length for output to TT: and LP: type devices.
; V01.C TWD 29-DEC-1983 Remove device restrictions to allow I/O
; with NL: and TT: and others which can use RMS
; for I/O handling. Specific to this module,
; change the call to FT_INI_FILE to allow us to
; save the device class of both the input and
; output devices.
; V01.B TWD 12-DEC-1983 Minor release to fix bugs in:
; FTEXIT and FTTRANS
; V1.a T.W.D. 01-Mar-1982 Initail release.
;
$SSDEF
$NAMDEF ; NAM BLOCK DEFINITIONS.
$RMSDEF ; RMS STATUS DEFINITIONS
$DCDEF ; DEVICE CLASSES.
$STSDEF ; EXIT STATUS DEFINITIONS.
;
FTCBDEF ; FTCOPY CONTROL BLOCK DEFINITIONS
FTIODEF ; FTCOPY IO BLOCK DEFINITIONS
;
; FTCOPY input_file output_file
; Information on the format of the command is in the module
; FTCOMND - the command parsing subroutine.
;
;==========================================================================
;
; Register usage -
; Registers are used with the general condition of grouping
; their use for status, move character instructions, general purpose,
; and pointers to data areas. Registers 12, 13, 14, 15 are only used
; by the system for subroutine pointers.
;
; Status registers are generally R0 and R1.
; Move character registers are R0 - R5. Their use is confined to the
; FT_PCOPY and FT_TRANS subroutines and surrounding code in the main
; program.
; General purpose registers are R6 - R9.
; Pointer registers are R10 and R11.
;
; Usage specific to this routine -
; R0 - Status from subroutine calls.
; R1 - Temporary counter for the number of data blocks read.
; R2 - not used.
; R3 - Not used.
; R4 - Not used.
; R5 - Used as address pointer for translating "pad" characters.
; R6 - Scratch register.
; R7 - Scratch register.
; R8 - Pointer to RAB's and temporary block counter.
; R9 - Pointer to FAB's and temporary message pointer.
; R10 - Pointer to the FTCB.
; R11 - Pointer to the FT I/O block.
;
; In the area where data is read from the input device and passed to the
; copy routines, registers R0-R8 may be critical and not saved from
; routine to routine. Care must be taken in this area to maintain the
; integrity of all of the data pointers and counters. The important
; area is noted in the code.
;
;
.PAGE
.SUBTITLE DATA FOR FTCOPY MAIN PROGRAM.
;
DEV_NAME_DESC: .BLKL 2 ; STRING DESCRIPTOR FOR THE IN/OUT
; PARSED FILE NAME.
;
; EXPANDED FILE NAME AREAS FOR INPUT FILES AND OUTPUT FILES.
;
EX_IN_NAME:: .BLKB NAM$C_MAXRSS ; INPUT EXPANDED STRING AREA.
EX_OUT_NAME:: .BLKB NAM$C_MAXRSS ; OUTPUT EXPANDED STRING AREA.
EX_TMP_NAME:: .BLKB NAM$C_MAXRSS ; TEMP. EXPANDED STRING AREA.
;
.EVEN
CUR_REC: .LONG 0 ; CURRENT OUTPUT RECORD SIZE.
CUR_BLK: .LONG 0 ; CURRENT OUTPUT BLOCK SIZE.
IN_BYTE: .LONG 0 ; NUMBER OF BYTES READ FROM FOREIGN TAPE.
READ_BYTE: .LONG 65535 ; NUMBER OF BYTES TO READ FROM FOREIGN TAPE.
;
COUNT_FILE: .LONG 0 ; COUNT OF FILES TO COPY.
;
.PAGE
.SUBTITLE ERROR MESSAGE STRINGS
;
; CHARACTER STRINGS AND NUMBERS USED IN CONJUNCTION
; WITH THE FTCOPY ERROR MESSAGES.
;
;
NUM_1:: .LONG 65535 ; MAXIMUM SIZE OF FT BLOCK
NUM_2:: .LONG 9991 ; MAXIMUM SIZE OF ANSI TAPE BLOCK
NUM_3:: .LONG 32767 ; MAX SIZE OF RMS DISK RECORD.
;
;
DESCRIPTOR MSG_1,
DESCRIPTOR MSG_2,
DESCRIPTOR MSG_3,
;
DESCRIPTOR MSG_4,
DESCRIPTOR MSG_5,
DESCRIPTOR MSG_6,
;
DESCRIPTOR MSG_7,
DESCRIPTOR MSG_8,
DESCRIPTOR MSG_9,
;
DESCRIPTOR MSG_10,
DESCRIPTOR MSG_12,
DESCRIPTOR MSG_13,
;
DESCRIPTOR MSG_14,
DESCRIPTOR MSG_15,
DESCRIPTOR MSG_16,
;
DESCRIPTOR MSG_17,
DESCRIPTOR MSG_18,
DESCRIPTOR MSG_19,
;
DESCRIPTOR MSG_20,
DESCRIPTOR MSG_21,
DESCRIPTOR MSG_22,
;
DESCRIPTOR MSG_23,
;
.PAGE
.SUBTITLE FOREIGN TAPE CONTROL BLOCK & I/O DATA BLOCKS
; FOREIGN TAPE CONTROL BLOCK
;
.SAVE
.PSECT FTCB_DATA,OVR,NOEXE,GBL,PIC,SHR,LONG
FTCB:: .BLKB FTCB_K_LEN ; DEFINED BY LENGTH IN THE DEFINITIONS
;
; FOREIGN TAPE I/O BLOCK
;
.PSECT FTIO_DATA,OVR,NOEXE,GBL,PIC,SHR,LONG
FTIO:: .BLKB FTIO_K_LEN ; DEFINED BY LENGTH IN THE DEFINITIONS.
;
; FOREIGN TAPE INPUT DATA BLOCK
;
.PSECT FT_IN_BUF,OVR,NOEXE,GBL,PIC,SHR,BYTE
FT_IN_DATA:: .BLKB 65535
;
; FOREIGN TAPE OUTPUT DATA BLOCK
;
.PSECT FT_OUT_BUF,OVR,NOEXE,GBL,PIC,SHR,BYTE
FT_OUT_DATA:: .BLKB 65535
;
; DATA TRANSLATION BUFFERS.
;
.PSECT FT_TRANSB,OVR,NOEXE,GBL,PIC,SHR,BYTE
FT_BLANK_DATA:: .BLKB 256
FT_TRANS_DATA:: .BLKB 256
.RESTORE
;
.PAGE
.SUBTITLE FILE ACCESS AND NAME BLOCKS FOR FTCOPY
;
.SAVE
.PSECT FTCOP_RMS,OVR,NOEXE,GBL,PIC,SHR,LONG
; INPUT DATA FILE IF RMS.
;
IN_NAM:: $NAM ESA=EX_IN_NAME,- ; INPUT NAME BLOCK WITH EXPANDED
ESS=NAM$C_MAXRSS ; STRING ADDR. AND SIZE.
;
IN_XAB: $XABFHC ; THE FILE HEADER - AVENUE TO LRL.
;
IN_FAB:: $FAB FAC=,- ; GET AND FIND ACCESS.
FOP=NAM,- ; SPECIFY NAME BLOCK PROCESSING.
NAM=IN_NAM,-
XAB=IN_XAB
; NEED TO SPECIFY THE NAME ADDRESS AND
; THE NAME SIZE AT RUN TIME.
IN_RAB:: $RAB FAB=IN_FAB,- ; INPUT RECORD ACCESS BLOCK.
RAC=SEQ,- ; SEQUENTIAL ACCESS.
UBF=FT_IN_DATA,- ; INPUT BUFFER.
USZ=65535 ; INPUT BUFFER SIZE.
;
; OUTPUT DATA FILE IF RMS USED.
;
OUT_NAM:: $NAM ESA=EX_OUT_NAME,- ; OUTPUT NAME BLOCK WITH EXPND.
ESS=NAM$C_MAXRSS ; STRING ADDR. AND SIZE.
;
OUT_FAB:: $FAB FAC=,- ; PUT, UPDATE AND TRUNCATE.
FOP=,- ; OPTIONS.
ORG=SEQ,- ; SEQUENTIAL ORGANIZATION.
RAT=CR,- ; IMPLIED AFTER EACH REC.
RFM=VAR,- ; VARIABLE LENGTH RECORDS.
NAM=OUT_NAM
;
OUT_RAB:: $RAB FAB=OUT_FAB,-
RAC=SEQ,- ; SEQUENTIAL ACCESS.
RBF=FT_OUT_DATA ; OUTPUT BUFFER START.
;
;
; TEMPORARY FAB - USED FOR BLANKEDIT, USER TRANSLATE, ....
;
TMP_NAM:: $NAM ESA=EX_TMP_NAME,- ; TEMP EXPANDED STRING AREA.
ESS=NAM$C_MAXRSS ; EXPANDED STRING SIZE.
;
TMP_FAB:: $FAB FAC=,- ; GET AND FIND ACCESS.
NAM=TMP_NAM
; NEED TO SPECIFY THE NAME ADDRESS AND
; THE NAME SIZE AT RUN TIME.
;
TMP_RAB:: $RAB FAB=TMP_FAB,-
RAC=SEQ
;
.RESTORE
;
.PAGE
.SUBTITLE START PROGRAM AND PARSE THE COMMAND.
;
FTCOPY:: .WORD 0
;
; INITIAIZE THE CONTROL BLOCK AND I/O BLOCK.
;
MOVAL FTCB,R10 ; LOAD ADDRESS OF THE CONTROL BLOCK
MOVAL FTIO,R11 ; LOAD ADDRESS OF THE I/O BLOCK
;
MOVAL OUT_RAB,FTCB_L_OUT_RAB(R10) ; POINTER TO OUTPUT RAB.
MOVAL FTCB+FTCB_B_INSTR,FTCB_L_INSPTR(R10) ; POINT TO INPUT STR.
MOVAL FTIO+FTIO_B_INFIL,FTIO_L_INPTR(R11) ; POINT TO IN FILE
MOVAL FTIO+FTIO_B_OUTFIL,FTIO_L_OUTPTR(R11) ; POINT TO OUT FILE.
MOVAL FTIO+FTIO_B_BLAFIL,FTIO_L_BLAPTR(R11) ; POINT TO BLANK EDIT.
;
MOVW #^X0FFFF,FTCB_W_DEFS(R10) ; INITIALIZE THE DEFAULT
; SWITCHES FOR "ALL DEFAULTS."
MOVW #^X0007,FTCB_W_FLAG(R10) ; INITIALIZE THE FLAGS.
MOVZWL #40,FTCB_L_INLUN(R10) ; INITIALIZE THE INPUT LUN
MOVZWL #45,FTCB_L_OUTLUN(R10) ; INIT. THE OUTPUT LUN.
;
MOVL #SS$_NORMAL,FTCB_L_SEVERITY(R10) ; INIT. SEVERITY TO SUCCESS.
MOVL #1,FTCB_L_EXIT_FLG(R10) ; INIT. EXIT FLAG - REMOVE
; WHEN CHECKING STARTS FOR COMPLETE COMMAND
; SYNTAX BEFORE EXIT ON ERROR.
;
; ISSUE COPYRIGHT NOTICE.
;
CALL_MSG PUT_SYS,#FTC_NOTICE,#0
;
; CALL THE FTCOPY COMMAND PARSER AND FIND OUT WHAT TO DO.
;
5$: CALLS #0,G^FTCOMND
;
BLBS R0,IN_DVI
;
$EXIT_S R0 ; IF THE PARSER QUITS - THEN PROG WILL QUIT.
;
.PAGE
.SUBTITLE GET INFORMATION ABOUT INPUT DEVICE AND OPEN FILE.
;
IN_DVI: MOVAL IN_FAB,R9 ; POINTER TO THE INPUT FAB
MOVAL IN_NAM,R8 ; POINTER TO THE INPUT NAM
;
PUSHAL FTCB+FTCB_W_IN_BUF ; LOCATION FOR THE DEVICE BUFFER SIZE.
PUSHAL FTCB+FTCB_B_IN_CLAS ; LOCATION TO SAVE THE IN DEVICE CLASS.
PUSHL #FLAG_V_FTIN ; PUSH THE FT IN FLAG NUMBER.
PUSHAL FTCB+FTCB_L_INLUN ; PUSH THE ADDR OF THE IN LUN NUMBER.
PUSHAL FTIO+FTIO_Q_INDESC ; PUSH THE ADDR OF THE IN FILE DESCRIP.
CALLS #5,G^FT_INI_FILE ; CALL INITIALIZE FT FILES SUBR.
;
; THE FILE HAS BEEN CHECKED OUT AND OPENED, FIND OUT IF RMS
; OR FOREIGN TAPE AND BRANCH TO THE CORRECT LOCATION TO CONTINUE
; THE ANALYSIS AND OPENING.
;
BBC #FLAG_V_FTIN,FTCB_W_FLAG(R10),IN_RMS
BRB GET_OUT_INFO
;
; RMS FILE --
; OPENING AN RMS FILE
;
IN_RMS: CMPL #1,FTCB_L_NFILES(R10) ; CHECK TO SEE IF AN RMS INPUT IS FOR
BEQL 15$ ; ONLY ONE FILE. BRANCH IF TRUE.
;
MOVL #1,FTCB_L_NFILES(R10) ; FORCE NFILES = 1.
CALL_MSG PUT_SYS,#FTC_FILELIM,#0 ; ISSUE A WARNING MESSAGE.
;
; CONNECT TO THE FILE.
;
15$: $CONNECT RAB=IN_RAB ; SET DATA STREAM TO INPUT FILE.
BLBC R0,55$ ; IF CLEAR - ERROR.
;
BRB GET_OUT_INFO ; GO CHECK OUT THE OUTPUT FILE.
;
55$: MOVZBL NAM$B_ESL(R8),R5 ; GET THE STRING SIZE INTO LONG WORD.
CALL_MSG EXIT_SYS,#FTC_RMSERROR,#4,- ; EXIT - RMS ERROR MESSAGE.
MSG_9,MSG_9+4,R5,NAM$L_ESA(R8),R0,IN_RAB+RAB$L_STV
;
.PAGE
.SUBTITLE GET INFORMATION ABOUT OUTPUT DEVICE AND OPEN FILE.
;
GET_OUT_INFO:
MOVAL OUT_FAB,R9 ; GET OUTPUT FAB ADDR.
MOVAL OUT_NAM,R8 ; GET OUTPUT NAM ADDR.
;
PUSHAL FTCB+FTCB_W_OUT_BUF ; LOCATION FOR OUTPUT BUFFER SIZE.
PUSHAL FTCB+FTCB_B_OUT_CLAS ; SAVE LOCATION FOR OUT DEVICE CLASS.
PUSHL #FLAG_V_FTOUT ; OUTPUT FOREIGN FLAG.
PUSHAL FTCB+FTCB_L_OUTLUN ; FOREIGN TAPE LUN.
PUSHAL FTIO+FTIO_Q_OUTDESC ; OUTPUT FILE DESCRIPTOR.
CALLS #5,G^FT_INI_FILE
;
; CHECK THE OUTPUT FOREIGN FLAG AND BRANCH TO OPEN FOR RMS
; OR FOREIGN TAPE
;
20$: BBC #FLAG_V_FTOUT,FTCB_W_FLAG(R10),OUT_RMS
BRB GET_BLNK_INFO ; FOREIGN TAPE -- THERE ARE NO SPECIFIC
; CHECKS FOR A FOREIGN TAPE.
;
;
; RMS FILE --
; CHECK FOR A TT: OR LP: TYPE OF OUTPUT DEVICE AND, IF TRUE, SET
; THE CHECK BUFFER SIZE FLAG.
;
OUT_RMS:
CMPB #DC$_TERM,FTCB_B_OUT_CLAS(R10) ; CHECK FOR TERMINAL CLASS.
BNEQ 10$
BISW2 #FLAG_M_CKBUF,FTCB_W_FLAG(R10) ; SET FLAG SO BUFFER IS CHECKED
;
10$: CMPB #DC$_LP,FTCB_B_OUT_CLAS(R10) ; CHECK FOR LINE PRINTER CLASS.
BNEQ 20$
BISW2 #FLAG_M_CKBUF,FTCB_W_FLAG(R10) ; SET FLAG SO BUFFER IS CHECKED
;
;
; PUT THE OUTPUT BLOCK SIZE INTO THE MAX. RECORD SIZE OF
; THE FAB - THIS WILL ALLOW FTCOPY TO DEBLOCK OR BLOCK AN
; RMS FILE WITHIN ITS RECORDS.
;
20$: PUSHL R9 ; PUSH THE OUTPUT FAB ADDRESS.
PUSHAL OUT_RAB ; PUSH THE OUTPUT RAB ADDRESS.
CALLS #2,G^FT_CREATE ; CALL SUBR. TO CREATE AND CONNECT FILE
;
;
.PAGE
.SUBTITLE BLANK EDIT OF THE DATA - GET INFORMATION.
;
GET_BLNK_INFO:
MOVAL TMP_FAB,R9 ; GET POINTER TO THE TEMP FAB.
MOVAL TMP_RAB,R8 ; GET POINTER TO THE TEMP RAB INTO R8.
;
; IF BLANK EDIT CLEAR, BRANCH
BBC #FLAG_V_BLANK,FTCB_W_FLAG(R10),GET_TRANS_INFO
;
; GO INITIALIZE THE BLANK EDIT MASK.
;
CALLS #0,G^BLNK_INIT
;
.PAGE
.SUBTITLE USER TRANSLATE TABLE - GET INFORMATION.
;
; GET INFORMATION ABOUT THE USER TRANSLATE FILE.
;
GET_TRANS_INFO:
; BRANCH IF TRANSLATION BIT CLEAR.
BBC #FLAG_V_TRANS,FTCB_W_FLAG(R10),START_LOOP
;
; CALL ROUTINE TO INITIALIZE THE TRANSLATION POINTERS,
; GET USER TRANSLATION INFORMATION, AND TRANSLATE ANY
; PAD BYTES.
;
CALLS #0,G^TRAN_INIT
;
.PAGE
.SUBTITLE LOOP TO GET RECORDS, DEBLOCK/BLOCK, AND PUT RECS.
;
;
;============================================================================
;
; NOTE:
; Care must be taken to maintain the integrity of R0-R8 in the following
; sections of the program. All of these registers may be passed in
; and out of subroutines with out being saved. The most critical are
; R0-R5 as these are used as pointers and counters for the copy
; operations. Subroutines which may be called are documented as to
; what registers they preserve and what registers are used and
; how they used. FTCOPY depends on the integrity of the registers for
; completing the copies correctly.
;
;
;
START_LOOP:
MOVL FTCB_L_NFILES(R10),COUNT_FILE ; SET UP FILE COUNTER.
;
; CHECK FOR FOREIGN OR RMS INPUT AND GET NEXT RECORD.
;
INPUT_REC:
BBS #FLAG_V_FTIN,FTCB_W_FLAG(R10),5$
BRB 10$ ; GO TO THE RMS INPUT.
;
5$: BRW INPUT_FT ; GO TO THE FOREIGN TAPE INPUT.
;
;
; RMS INPUT - GET THE RECORD AND CHECK FOR END OF FILE.
;
10$: MOVAL IN_RAB,R6 ; GET THE ADDR OF THE INPUT RAB.
$GET RAB=IN_RAB
BLBS R0,20$ ; CHECK FOR SUCCESSFUL GET.
;
CMPL #RMS$_EOF,R0 ; CHECK FOR END OF FILE.
BEQL 15$ ; IF NOT - BRANCH TO GIVE ERROR.
;
MOVL FAB$L_NAM(R6),R5 ; GET NAME BLOCK ADDRESS.
MOVZBL NAM$B_ESL(R5),R4 ; GET EXPANDED FILE NAME LENGTH.
CALL_MSG EXIT_SYS,#FTC_RMSERROR,#4,MSG_8,- ; FATAL - RMS.
MSG_8+4,R4,NAM$L_ESA(R5),R0,IN_RAB+RAB$L_STV
;
15$: BRW CLOSE_FILE ; END OF FILE FOUND -- CLOSE THE FILE.
;
; INPUT OK - CHECK ON USING THE DEFAULT BLOCK SIZE OR
; A USER SPECIFIED SIZE.
;
20$: BBS #DEFS_V_INBLK,FTCB_W_DEFS(R10),30$ ; USE DEFAULT IF SET.
;
ADDL3 #1,FTCB_L_BLK_READ(R10),R1 ; TEMPORARY BLOCK COUNT.
;
CMPW RAB$W_RSZ(R6),FTCB_L_INBLK(R10) ; ARE IN BLK AND IN REC. SAME?
BEQL 30$ ; IF EQUAL, GO SET THE ACTUAL IN BLOCK SIZE.
BLSS 25$ ; IF IN LESS THAN SPECIFIED, USE IN WITH WARN.
;
; INPUT BLOCK GREATER THAN SPECIFIED BLOCKSIZE - USE SPECIFIED.
CALL_MSG PUT_SYS,#FTC_INPGTRSPEC,#0,-
#FTC_DATALOST,#0,#FTC_BLOCKNUM,#2,R1,FTCB_L_BLK_WRIT(R10)
;
MOVL FTCB_L_INBLK(R10),FTCB_L_ACT_INBLK(R10) ; USE THE SPECIFIED SIZE
BRW SET_RECORD
;
; ISSUE MESSAGE SAYING THE SMALLER INPUT SIZE WILL BE USED AND
; THEN GO TO SET INPUT BLOCK TO THE SMALLER SIZE.
25$: CALL_MSG PUT_SYS,#FTC_INPLTSPEC,#0,-
#FTC_SMALLUSED,#0,#FTC_BLOCKNUM,#2,R1,FTCB_L_BLK_WRIT(R10)
;
30$: MOVZWL RAB$W_RSZ(R6),FTCB_L_ACT_INBLK(R10) ; SET INPUT BLOCK SIZE.
BRW SET_RECORD ; GO CHECK THE RECORD SIZE AND SET IT.
;
;
; FOREIGN TAPE INPUT - READ TAPE AND CHECK THE INPUT BLOCK SIZE.
;
INPUT_FT:
PUSHAL FTCB+FTCB_Q_ISTAT ; ADDRESS OF I/O STATUS BLOCK
PUSHAL IN_BYTE ; ADDRESS OF # BYTES READ.
PUSHAL READ_BYTE ; ADDRESS OF BYTES TO READ.
PUSHAL FT_IN_DATA ; ADDRESS OF INPUT DATA AREA.
PUSHAL FTCB+FTCB_L_INLUN ; ADDRESS OF LUN FOR READ.
CALLS #5,G^RITAPE ; READ TAPE.
;
ADDL3 #1,FTCB_L_BLK_READ(R10),R1 ; TEMPORARY BLOCK COUNT.
CASEL FTCB_Q_ISTAT(R10),#1,#6 ; CHECK FOR ERROR
;
1$: .WORD 10$-1$ ; NORMAL BRANCH
.WORD 20$-1$ ; EOF BRANCH
.WORD 30$-1$ ; EOT BRANCH.
.WORD 40$-1$ ; EOV BRANCH.
.WORD 50$-1$ ; DATACHECK BRANCH - NOT APPLICABLE.
.WORD 60$-1$ ; PARITY BRANCH.
.WORD 70$-1$ ; DATA OVERUN BRANCH.
;
; ISTAT > 7 - FATAL SYSTEM ERROR.
;
CALL_MSG EXIT_SYS,#FTC_FTERROR,#2,- ; FATAL TAPE READ ERROR.
MSG_8,MSG_8+4,#FTC_ERRCODE,#1,FTCB_Q_ISTAT(R10),-
FTCB_Q_ISTAT(R10)
;
10$: CLRB FTCB_B_EOV(R10) ; CLEAR THE COUNT OF EOF'S FOUND.
BRW INPUT_FT_1 ; NORMAL END
;
20$: INCB FTCB_B_EOV(R10) ; INCREMENT THE COUNT OF EOF'S
BRW CLOSE_FILE ; END OF FILE FOUND.
;
30$: CALL_MSG EXIT_SYS,#FTC_FTEOT,#2,MSG_8,- ; END OF TAPE
MSG_8+4,#FTC_OPERTERM
;
40$: CALL_MSG EXIT_SYS,#FTC_FTEOV,#0 ; END OF VOLUME
;
50$: CALL_MSG EXIT_SYS,#FTC_FTERROR,#2,MSG_8,- ; DATA CHECK
MSG_8+4,#SS$_DATACHECK
;
60$: CALL_MSG PUT_SYS,#FTC_FTERROR,#2,MSG_8,- ; PARITY
MSG_8+4,#FTC_BLOCKNUM,#2,R1,FTCB_L_BLK_WRIT(R10),-
#SS$_PARITY
BRB INPUT_FT_1 ; HANDLE THE BLOCK ANYWAY.
;
70$: CALL_MSG EXIT_SYS,#FTC_FTERROR,#2,MSG_8,- ; DATA OVERUN
MSG_8+4,#FTC_BLOCKNUM,#2,R1,FTCB_L_BLK_WRIT(R10),-
#SS$_DATAOVERUN
;
;
; CHECK ON USING THE DEFAULT INPUT BLOCK AND THEN
; SET THE ACTUAL BLOCK SIZE.
;
INPUT_FT_1:
BBS #DEFS_V_INBLK,FTCB_W_DEFS(R10),20$
;
CMPL IN_BYTE,FTCB_L_INBLK(R10) ; IN BLOCK = SPECIFIED BLOCK?
BEQL 20$ ; IF YES, CONTINUE.
BLSS 15$ ; INPUT SIZE LESS THAN SPECIFIED - WARN USER.
;
; INPUT SIZE > SPECIFIED - WARN USER AND USE ANYWAY.
CALL_MSG PUT_SYS,#FTC_INPGTRSPEC,#0,- ; WARN
#FTC_DATALOST,#0,#FTC_BLOCKNUM,#2,R1,FTCB_L_BLK_WRIT(R10)
;
MOVL FTCB_L_INBLK(R10),FTCB_L_ACT_INBLK(R10) ; USE THE SPECIFIED SIZE
BISW2 #FLAG_M_ODDSIZ,FTCB_W_FLAG(R10) ; SET THE ODDSIZE FLAG.
BRB SET_RECORD
;
; INPUT SIZE LESS THAN SPEC. - USE THE SMALLER AND WARN USER.
15$: CALL_MSG PUT_SYS,#FTC_INPLTSPEC,#0,- ; WARN
#FTC_SMALLUSED,#0,#FTC_BLOCKNUM,#2,R1,FTCB_L_BLK_WRIT(R10)
;
20$: MOVL IN_BYTE,FTCB_L_ACT_INBLK(R10) ; ACTUAL BLOCK = BYTES READ.
;
.PAGE
.SUBTITLE CHECK INPUT AND OUTPUT RECORD SIZES.
;
; CHECK ON USING THE DEFAULT INPUT RECORD SIZE OR
; A SPECIFIED RECORD SIZE.
;
SET_RECORD:
INCL FTCB_L_BLK_READ(R10) ; INCREMENT COUNT OF BLOCKS READ.
BBS #DEFS_V_INREC,FTCB_W_DEFS(R10),30$ ; BRANCH FOR DEFAULT.
;
; SET FOR SPECIFIED RECORD SIZE.
;
MOVL FTCB_L_INREC(R10),FTCB_L_ACT_INREC(R10)
BRB 40$
;
; SET UP THE DEFAULT INPUT RECORD SIZE.
;
30$: MOVL FTCB_L_ACT_INBLK(R10),FTCB_L_ACT_INREC(R10)
;
; CHECK THE INPUT RECORD SIZE TO BE SURE IT IS > 0 BEFORE
; DOING THE DIVIDE BELOW - I.E. AVOID A DIVIDE BY ZERO FAULT.
;
40$: TSTL FTCB_L_ACT_INREC(R10) ; IS INPUT <= 0??
BGTR 45$ ; NOT <= 0, BRANCH TO DIVIDE.
;
MOVL #1,FTCB_L_INRECS(R10) ; SET NUMBER OF RECORDS = 1.
CLRL FTCB_L_INREM(R10) ; CLEAR REMAINDER OF BYTES
BRB 48$ ; SKIP THE DIVIDE.
;
; EXTNDED DIVIDE THE ACTUAL INPUT RECORD INTO THE ACTUAL
; INPUT BLOCK TO GET THE NUMBER OF RECORDS/BLOCK AND
; THE NUMBER OF ANY REMAINING BYTES IN THE INPUT
; BLOCK.
;
45$: MOVL FTCB_L_ACT_INBLK(R10),FTCB_Q_ISTAT(R10) ;SET UP QUAD
CLRL FTCB_Q_ISTAT+4(R10) ;WORD DIVIDEND
EDIV FTCB_L_ACT_INREC(R10),FTCB_Q_ISTAT(R10),-
FTCB_L_INRECS(R10),FTCB_L_INREM(R10)
;
;
; SET UP OUTPUT RECORD SIZE AND OUTPUT BLOCK SIZE.
;
48$: BBS #DEFS_V_OUTREC,FTCB_W_DEFS(R10),50$ ; USE DEFAULT IF SET.
;
; USE SPECIFIED RECORD SIZE.
MOVL FTCB_L_OUTREC(R10),FTCB_L_ACT_OUTREC(R10)
BRB 60$
;
50$: MOVL FTCB_L_ACT_INREC(R10),FTCB_L_ACT_OUTREC(R10) ; USE DEFAULT.
;
60$: BBS #DEFS_V_OUTBLK,FTCB_W_DEFS(R10),70$ ; USE DEFAULT IF SET.
;
; USE SPECIFIED BLOCK SIZE.
MOVL FTCB_L_OUTBLK(R10),FTCB_L_ACT_OUTBLK(R10)
BRB 80$
;
70$: MOVL FTCB_L_ACT_OUTREC(R10),FTCB_L_ACT_OUTBLK(R10) ; USE DEFAULT.
;
; CHECK THE OUTPUT RECORD SIZE TO BE SURE IT IS > 0 BEFORE
; DOING EXTENDED DIVIDE BELOW.
;
80$: TSTL FTCB_L_ACT_OUTREC(R10) ; IS RECORD <= 0??
BNEQ 85$ ; NOT <= 0, GO TO DIVIDE.
;
MOVL #1,FTCB_L_OUTRECS(R10) ; CLEAR # OUTPUT RECORDS.
CLRL FTCB_L_OUTREM(R10) ; CLEAR REMAINDER OF OUTPUT BYTES.
BRB CK_RECS ; SKIP THE DIVIDE.
;
; EXTENDED DIVIDE THE ACTUAL OUTPUT RECORD SIZE INTO THE ACTUAL
; OUTPUT BLOCK SIZE TO GET THE NUBMER OF RECORDS/BLOCK AND
; THE NUMBER OF BYTES REMAINING TO BE PADDED IN THE OUTPUT
; BLOCK.
;
85$: MOVL FTCB_L_ACT_OUTBLK(R10),FTCB_Q_ISTAT(R10) ; BUILD QUAD
CLRL FTCB_Q_ISTAT+4(R10) ; WORD DIVIDEND.
EDIV FTCB_L_ACT_OUTREC(R10),FTCB_Q_ISTAT(R10),-
FTCB_L_OUTRECS(R10),FTCB_L_OUTREM(R10)
;
.PAGE
.SUBTITLE CHECK RECORD SIZES AND PADDING AND TRAILING.
;
CK_RECS:
; CHECK TO SEE IF THE OUTPUT WAS JUST COMPLETED AND
; IF NOT CHECK TO SEE IF THE CURRENT OUTREC SIZE = THE NEW
; OUTREC SIZE FROM THE MOST RECENT READ. ALSO, CHECK THE
; OUTBLOCK SIZES.
;
15$: BBS #FLAG_V_INIT_COP,FTCB_W_FLAG(R10),35$ ; INIT. COPY?
;
BBS #FLAG_V_OUT_COMP,FTCB_W_FLAG(R10),35$ ; COPY COMPLETE?
;
CMPL CUR_REC,FTCB_L_ACT_OUTREC(R10)
BEQL 30$ ; BRANCH IF OK TO TEST BLOCKS.
;
; RECORD/BLOCK SIZES CHANGED.
20$: CALL_MSG EXIT_SYS,#FTC_SIZECHNG,#0,#FTC_BLOCKNUM,#2,-
FTCB_L_BLK_READ(R10),FTCB_L_BLK_WRIT(R10),-
#FTC_SIZECHNG1,#2,CUR_REC,FTCB_L_ACT_OUTREC(R10),-
#FTC_SIZECHNG2,#2,CUR_BLK,FTCB_L_ACT_OUTBLK(R10)
;
30$: CMPL CUR_BLK,FTCB_L_ACT_OUTBLK(R10)
BNEQ 20$ ; BRANCH IF NOT OK.
BRB 40$ ; BYPASS THE SAVING OF THE CURRENT SIZES.
;
; SAVE THE CURRENT OUTPUT RECORD AND BLOCK SIZES.
;
35$: MOVL FTCB_L_ACT_OUTREC(R10),CUR_REC ; SAVE RECORD.
MOVL FTCB_L_ACT_OUTBLK(R10),CUR_BLK ; SAVE BLOCK.
;
;
; CHECK FOR PADDING RECORDS ON OUTPUT OR KEEPING TRAILING
; DATA IN INPUT RECORDS.
;
40$: CMPL FTCB_L_ACT_INREC(R10),FTCB_L_ACT_OUTREC(R10)
; IF IN >= OUT, SIZES OK - DON'T CHECK TRAILING.
BGEQ 60$
;
; IF IN= 14 BYTES.
BLSS 7$
BRW COPY ; IF OK, GO AND COPY.
;
; FATAL - BLOCK TOO SMALL FOR TAPE.
7$: CALL_MSG EXIT_SYS,#FTC_BLKSIZ,#4,MSG_2,MSG_2+4,MSG_6,MSG_6+4,-
#FTC_BLOCKNUM,#2,FTCB_L_BLK_READ(R10),FTCB_L_BLK_WRIT(R10),-
#FTC_MINSIZE,#1,FTCB_L_ACT_OUTBLK(R10)
;
; RMS BLOCK SIZES.
;
10$: CMPB #DC$_DISK,FTCB_B_OUT_CLAS(R10) ; CHECK FOR DISK OR TAPE.
BEQL 20$ ; IF DISK, BRANCH.
;
CMPL #9991,FTCB_L_ACT_OUTBLK(R10) ; CHECK OUT RMS TAPE BLOCK.
BLSS 15$
BRW COPY ; IF OK, BRANCH.
;
; ABORT - ILLEGAL BLOCK SIZE.
15$: CALL_MSG EXIT_SYS,#FTC_BLKSIZ,#4,MSG_2,MSG_2+4,MSG_7,MSG_7+4,-
#FTC_BLOCKNUM,#2,FTCB_L_BLK_READ(R10),FTCB_L_BLK_WRIT(R10),-
#FTC_MAXSIZE,#2,NUM_2,FTCB_L_ACT_OUTBLK(R10)
;
20$: CMPL #32767,FTCB_L_ACT_OUTBLK(R10) ; CHECK FOR RMS DISK BLOCK.
BGEQ COPY ; IF OK, BRANCH.
;
; ABORT - ILLEGAL BLOCK SIZE.
CALL_MSG EXIT_SYS,#FTC_BLKSIZ,#4,MSG_2,MSG_2+4,MSG_7,MSG_7+4,-
#FTC_BLOCKNUM,#2,FTCB_L_BLK_READ(R10),FTCB_L_BLK_WRIT(R10),-
#FTC_MAXSIZE,#2,NUM_3,FTCB_L_ACT_OUTBLK(R10)
;
.PAGE
.SUBTITLE BLANK EDIT AND COPY OR TRANSLATE DATA.
;
COPY: BBC #FLAG_V_BLANK,FTCB_W_FLAG(R10),20$ ; IF NOT BLANK, BRANCH.
;
CALLS #0,G^FT_BLANK ; BLANK EDIT DATA - DUMMY ROUTINE.
;
20$: BBS #FLAG_V_TRANS,FTCB_W_FLAG(R10),30$ ; IF TRANSLATE, BRANCH.
;
PUSHL FTCB_L_OUTRECS(R10) ; # OUTPUT RECORDS/BLOCK
PUSHL FTCB_L_OUTREM(R10) ; OUTPUT REMAINDER.
PUSHL FTCB_L_INRECS(R10) ; # INPUT RECORDS/BLOCK.
PUSHL FTCB_L_INREM(R10) ; INPUT REMAINDER.
PUSHL FTCB_L_ACT_OUTREC(R10) ; DESTINATION LENGTH.
PUSHL FTCB_L_ACT_INREC(R10) ; SOURCE LENGTH.
CALLS #6,G^FT_PCOPY ; CALL PLAIN COPY.
;
BRW INPUT_REC ; GO READ NEXT RECORD.
;
30$: PUSHL FTCB_L_OUTRECS(R10) ; # OUTPUT RECORDS/BLOCK
PUSHL FTCB_L_OUTREM(R10) ; OUTPUT REMAINDER.
PUSHL FTCB_L_INRECS(R10) ; # INPUT RECORDS/BLOCK.
PUSHL FTCB_L_INREM(R10) ; INPUT REMAINDER.
PUSHL FTCB_L_ACT_OUTREC(R10) ; DESTINATION LENGTH.
PUSHL FTCB_L_ACT_INREC(R10) ; SOURCE LENGTH.
CALLS #6,G^FT_TRANS ; DUMMY TRANSLATION ROUTINE.
;
BRW INPUT_REC ; GO READ NEXT RECORD.
;
.PAGE
.SUBTITLE CLOSE FILES AND CHECK FILE COUNTER FOR MORE.
;
; CHECK TO SEE IF OUTPUT JUST COMPLETED AND IF NOT,
; WRITE THE FINAL BLOCK.
;
CLOSE_FILE:
; CHECK FOR FINISH ING UP AT THE END OF FT INPUT.
CMPB FTCB_B_EOV(R10),#1 ; IF > 1, THEN EOV FOUND ON FT.
BLEQ 5$
;
CALL_MSG PUT_SYS,#FTC_FTEOV,#0 ; END-OF-VOLUME FOUND.
BRW FINISH_UP ; GO TO CLOSE AN OUTPUT RMS FILE.
;
5$: BBC #FLAG_V_OUT_COMP,FTCB_W_FLAG(R10),10$ ; IF CLEAR, WRITE.
;
BRB CLOSE_FILE_1 ; JUST GO END THE FILES.
;
10$: BBS #FLAG_V_PBLK,FTCB_W_FLAG(R10),30$ ; IF SET, PAD.
;
;
; DO NOT PAD THE LAST BLOCK -- JUST WRITE IT AS IS.
;
CLRL FTCB_L_OUTREM(R10) ; CLEAR THE NUMBER OF BYTES REMAINING.
SUBL2 R8,FTCB_L_OUTRECS(R10) ; FIGURE THE NUMBER OF RECORDS ACTUALLY
; WRITTEN TO THE BLOCK AND THEN
MULL3 FTCB_L_ACT_OUTREC(R10),FTCB_L_OUTRECS(R10),- ; THE NUMBER OF
FTCB_L_ACT_OUTBLK(R10) ; BYTES TO WRITE TO THE LAST BLOCK.
;
BRB 40$ ; GO WRITE.
;
; PAD THE LAST BLOCK.
;
; CALCULATE THE NUMBER OF BYTES REMAINING TO BE
; PADDED INTO THE BLOCK.
30$: MULL3 R8,FTCB_L_ACT_OUTREC(R10),R7 ; PUT INTO TEMP. LOCATION AND
ADDL2 R7,FTCB_L_OUTREM(R10) ; ADD IN THE CURRENT REMAINDER.
;
; CALL THE OUTPUT ROUTINE
;
; IS TRANSLATION BEING DONE?
BBS #FLAG_V_TRANS,FTCB_W_FLAG(R10),35$
; PUSH THE ADDRESS OF THE PLAIN COPY OUTPUT.
PUSHL R3
BRB 40$
; PUSH THE ADDRESS OF THE TRANSLATION ROUTINE.
35$: PUSHL R5
;
40$: PUSHL FTCB_L_OUTREM(R10) ; PUSH THE NUMBER OF BYTES REMAINING.
CALLS #2,G^FT_PADEVEN ; PAD/EVEN THE OUTPUT BLOCK.
;
CALLS #0,G^FT_OUTPUT ; WRITE THE LAST BLOCK.
;
; CHECK ON CLOSING AN FT OR AN RMS FILE AND CLOSE.
;
CLOSE_FILE_1:
BBS #FLAG_V_FTOUT,FTCB_W_FLAG(R10),20$ ; IF SET, FOREIGN TAPE.
;
$CLOSE FAB=OUT_FAB ; CLOSE THE OUTPUT RMS FILE.
;
BLBC R0,10$ ; IF LBC, ERROR
BRW RECYCLE ; START THE CYCLE OVER AGAIN.
;
; FATAL - ERROR ON CLOSE.
10$: MOVAL OUT_NAM,R6 ; GET ADDRESS OF OUTPUT NAM BLOCK.
MOVZBL NAM$B_ESL(R6),R5 ; GET LENGTH OF EXPANDED STRING.
CALL_MSG EXIT_SYS,#FTC_RMSERROR,#4,MSG_12,MSG_12+4,-
R5,NAM$L_ESA(R6),R0,OUT_FAB+FAB$L_STV
;
;
; FOREIGN TAPE FINISH UP.
;
20$: PUSHAL FTCB+FTCB_Q_ISTAT ; ADDRESS OF STATUS BLOCK
PUSHAL FTCB+FTCB_L_OUTLUN ; ADDRESS OF LUN.
CALLS #2,G^TAPE_EOF
;
CMPL FTCB_Q_ISTAT(R10),#SS$_NORMAL ; CHECK FOR NORMAL COMPLETION.
BNEQ 25$
BRB RECYCLE ; START CYCLE OVER AGAIN.
;
25$: CMPL #3,FTCB_Q_ISTAT(R10) ; CHECK FOR E-O-T FOUND.
BNEQ 30$
;
CALL_MSG PUT_SYS,#FTC_FTEOT,#2,MSG_15,MSG_15+4,-
#FTC_OPERTERM,#0 ; END-OF-TAPE FOUND.
CLRL COUNT_FILE ; MAKE NUMBER OF FILES REMAINING = 0
BRB RE_CYC_2
;
30$: CMPL #5,FTCB_Q_ISTAT(R10) ; CHECK FOR DATACHECK.
BNEQ 40$
;
; DATA CHECK FOUND - EXIT.
CALL_MSG EXIT_SYS,#FTC_FTERROR,#2,MSG_5,MSG_5+4,#SS$_DATACHECK
;
; UNKNOWN ERROR - EXIT.
40$: CALL_MSG EXIT_SYS,#FTC_FTERROR,#2,MSG_5,MSG_5+4,-
#FTC_ERRCODE,#1,FTCB_Q_ISTAT(R10),FTCB_Q_ISTAT(R10)
;
;
; RE START THE CYCLE OF READING AND DEBLOCKING AND WRITING.
;
RECYCLE:
INCL FTCB_L_FILCOP(R10) ; COUNT OF FILES COPIED.
RE_CYC_2:
CALLS #0,G^FT_COP_MSG ; PRINT THE NUMBER COPIED MESSAGE.
;
SOBGTR COUNT_FILE,RECYC_2 ; DECREMENT THE FILE COUNT AND EXIT
; IF NOT GREATER THAN 0.
;
;
; EXIT PROGRAM WITH A NORMAL STATUS BUT DON'T
; PRINT THE MESSAGE.
;
RECYC_1:
CALLS #0,G^FT_STOP ; EXIT THE PROGRAM WITH PROPER SEVERITY
;
;
; SET THE INITIALIZE COPY FLAG TO START ALL OVER AND
; CLEAR THE BLOCK AND RECORD COUNTERS.
;
RECYC_2:
BBSS #FLAG_V_INIT_COP,FTCB_W_FLAG(R10),15$
;
15$: CLRL FTCB_L_REC_READ(R10) ; CLEAR THE RECORDS READ.
CLRL FTCB_L_REC_WRIT(R10) ; CLEAR THE RECORDS WRITTEN.
CLRL FTCB_L_BLK_READ(R10) ; CLEAR THE BLOCKS READ.
CLRL FTCB_L_BLK_WRIT(R10) ; CLEAR THE BLOCKS WRITTEN.
;
; CHECK TO SEE IF RMS AND CREATE NEW VERSION OF
; FILE BEFORE GOING BACK FOR MORE.
;
20$: BBC #FLAG_V_FTOUT,FTCB_W_FLAG(R10),30$
;
BRW INPUT_REC ; GO TO READ NEXT INPUT BLOCK.
;
; CALL THE CREATE ROUTINE.
;
30$: PUSHAL OUT_FAB ; ADDRESS OF THE OUTPUT FAB.
PUSHAL OUT_RAB ; ADDRESS OF THE OUTPUT RAB.
CALLS #2,G^FT_CREATE
;
BRW INPUT_REC ; GO BACK TO READ NEXT RECORD.
;
;
; IF THE END OF FOREIGN TAPE INPUT, CHECK FOR RMS OUTPUT AND
; CLOSE AN OPEN FILE IF NECESSARY.
;
FINISH_UP:
BBS #FLAG_V_FTOUT,FTCB_W_FLAG(R10),RECYC_1 ; IF FT OUT, GO BACK.
;
MOVAL OUT_FAB,R8 ; GET ADDRESS OF OUTPUT FAB
BISL2 #FAB$M_DLT,FAB$L_FOP(R8) ; SET FLAG TO DELETE ON CLOSE.
$CLOSE FAB=R8 ; CLOSE THE EXTRA OUTPUT FILE & DELETE.
;
BLBC R0,10$ ; IF NOT GOOD, PUT ERROR MESSAGE.
BRW RECYC_1 ; GOOD CLOSE, NORMAL EXIT.
;
; FATAL - RMS CLOSE FILE ERROR.
10$: MOVL FAB$L_NAM(R8),R6 ; GET NAM ADDRESS.
MOVZBL NAM$B_ESL(R6),R5 ; GET EXPANDED NAME STRING ADDRESS.
CALL_MSG EXIT_SYS,#FTC_RMSERROR,#4,MSG_12,MSG_12+4,-
R5,NAM$L_ESA(R6),R0,FAB$L_STV(R8)
;
.END FTCOPY