.TITLE FTTRANS FTCOPY CHARACTER TRANSLATION ROUTINE. .IDENT /12-DEC-1983 V01.B/ ; ; V01.A TWD 12-APR-83 INITIAL RELEASE. ; V01.B TWD 12-DEC-1983 Put in check for R0=0 at the end ; of processing an ESCAPE. This is the exit ; from a potential endless loop. ; ; Subroutine used to deblock, block and translate data during ; FTCOPY. The actual work is done by the MOVTUC instruction which ; will move input to output and translate in the process and flag ; untranslateable bytes. This subroutine includes the padding ; or truncating of trailing data in both records and blocks and ; the padding of output records. ; ; The calling procedure is as follows: ; PUSHL # output records/block ; PUSHL # characters in output remainder. ; PUSHL # input records/block. ; PUSHL # characters in input remainder. ; PUSHL destination length. ; PUSHL source length. ; CALLS #6,FT_TRANS ; ; Items passed through the data block: ; FTCB_B_PREC Character to use when padding output records. ; FTCB_B_TRAILR Character to use when filling input trailing ; data in records. ; FTCB_B_TRAILB Character to use when filling input trailing ; data in blocks. ; FTCB_L_BLK_READ Number of blocks read on input. ; FTCB_L_BLK_WRITE Number of blocks written on output. ; FTCB_L_REC_READ Number of records read on input. ; FTCB_L_REC_WRITE Number of records written on output. ; ; FLAG_V_OUT_COMP Bit flag indicating that a write has just been ; completed (=1). ; FLAG_V_INIT_COP Bit flag indicating that the output buffer ; address and output record count need to be ; initialized. ; ; Registers used: ; R11 - Pointer to the FT I/O block. ; R10 - Pointer to the FT control block ; R8 - Current count of records to be blocked into output block. ; This is initialized and kept current in this suborutine. ; R7 - Count of records to be deblocked from the input block. ; R6 - Used as a local pointer. ; ; The following are used with the MOVTUC instruction: ; R5 - Pointer to the output data buffer. ; R4 - Used as output string length. ; R3 - Pointer to the translation table. ; R2 - Not really used - returned from MOVTUC as = 0. ; R1 - Pointer to the input data buffer. ; R0 - Number of bytes in the source string. ; ; FTCBDEF ; .PAGE .SUBTITLE DATA TRANSLATION TABLES. ; ; TRANSLATION TABLES ; .SAVE .PSECT FTC$TRANTAB,OVR,NOEXE,GBL,PIC,SHR,BYTE ; AS8_7AS_TAB: .BYTE ^X80,^X81,^X82,^X83,^X84,^X85,^X86,^X87 .BYTE ^X88,^X89,^X8A,^X8B,^X8C,^X8D,^X8E,^X8F .BYTE ^X90,^X91,^X92,^X93,^X94,^X95,^X96,^X97 .BYTE ^X98,^X99,^X9A,^X9B,^X9C,^X9D,^X9E,^X9F .BYTE ^XA0,^XA1,^XA2,^XA3,^XA4,^XA5,^XA6,^XA7 .BYTE ^XA8,^XA9,^XAA,^XAB,^XAC,^XAD,^XAE,^XAF .BYTE ^XB0,^XB1,^XB2,^XB3,^XB4,^XB5,^XB6,^XB7 .BYTE ^XB8,^XB9,^XBA,^XBB,^XBC,^XBD,^XBE,^XBF .BYTE ^XC0,^XC1,^XC2,^XC3,^XC4,^XC5,^XC6,^XC7 .BYTE ^XC8,^XC9,^XCA,^XCB,^XCC,^XCD,^XCE,^XCF .BYTE ^XD0,^XD1,^XD2,^XD3,^XD4,^XD5,^XD6,^XD7 .BYTE ^XD8,^XD9,^XDA,^XDB,^XDC,^XDD,^XDE,^XDF .BYTE ^XE0,^XE1,^XE2,^XE3,^XE4,^XE5,^XE6,^XE7 .BYTE ^XE8,^XE9,^XEA,^XEB,^XEC,^XED,^XEE,^XEF .BYTE ^XF0,^XF1,^XF2,^XF3,^XF4,^XF5,^XF6,^XF7 .BYTE ^XF8,^XF9,^XFA,^XFB,^XFC,^XFD,^XFE,^XFF .BYTE 0[128] ; ; AS7_8AS_TAB: .BYTE 0[128] .BYTE ^X00,^X01,^X02,^X03,^X04,^X05,^X06,^X07 .BYTE ^X08,^X09,^X0A,^X0B,^X0C,^X0D,^X0E,^X0F .BYTE ^X10,^X11,^X12,^X13,^X14,^X15,^X16,^X17 .BYTE ^X18,^X19,^X1A,^X1B,^X1C,^X1D,^X1E,^X1F .BYTE ^X20,^X21,^X22,^X23,^X24,^X25,^X26,^X27 .BYTE ^X28,^X29,^X2A,^X2B,^X2C,^X2D,^X2E,^X2F .BYTE ^X30,^X31,^X32,^X33,^X34,^X35,^X36,^X37 .BYTE ^X38,^X39,^X3A,^X3B,^X3C,^X3D,^X3E,^X3F .BYTE ^X40,^X41,^X42,^X43,^X44,^X45,^X46,^X47 .BYTE ^X48,^X49,^X4A,^X4B,^X4C,^X4D,^X4E,^X4F .BYTE ^X50,^X51,^X52,^X53,^X54,^X55,^X56,^X57 .BYTE ^X58,^X59,^X5A,^X5B,^X5C,^X5D,^X5E,^X5F .BYTE ^X60,^X61,^X62,^X63,^X64,^X65,^X66,^X67 .BYTE ^X68,^X69,^X6A,^X6B,^X6C,^X6D,^X6E,^X6F .BYTE ^X70,^X71,^X72,^X73,^X74,^X75,^X76,^X77 .BYTE ^X78,^X79,^X7A,^X7B,^X7C,^X7D,^X7E,^X7F ; ; BCD TO ASCII AND ASCII TO BCD TRANSLATION TABLES ; THESE ARE ONLY DEFINED FOR FUTURE USE IF NEEDED. ; NOT USED IN FTCOPY. ; ;BCD_ASC_TAB: .BYTE ^X1A[64] ; 00-3F ; .BYTE ^X20,^X1A,^X1A,^X1A,^X1A,^X1A,^X1A,^X1A ; 40-47 ; .BYTE ^X1A,^X1A,^X1A,^X2E,^X29,^X5B,^X3C,^X1A ; 48-4F ; .BYTE ^X2B,^X1A,^X1A,^X1A,^X1A,^X1A,^X1A,^X1A ; 50-57 ; .BYTE ^X1A,^X1A,^X1A,^X24,^X2A,^X5D,^X3B,^X1A ; 58-5F ; .BYTE ^X2D,^X2F,^X1A,^X1A,^X1A,^X1A,^X1A,^X1A ; 60-67 ; .BYTE ^X1A,^X1A,^X1A,^X2C,^X28,^X1A,^X5C,^X1A ; 68-6F ; .BYTE ^X1A,^X1A,^X1A,^X1A,^X1A,^X1A,^X1A,^X1A ; 70-77 ; .BYTE ^X1A,^X1A,^X1A,^X3D,^X40,^X3A,^X3E,^X1A ; 78-7F ; .BYTE ^X1A[64] ; 80-BF ; .BYTE ^X3F,^X41,^X42,^X43,^X44,^X45,^X46,^X47 ; C0-C7 ; .BYTE ^X48,^X49,^X1A,^X1A,^X1A,^X1A,^X1A,^X1A ; C8-CF ; .BYTE ^X21,^X4A,^X4B,^X4C,^X4D,^X4E,^X4F,^X50 ; D0-D7 ; .BYTE ^X51,^X52,^X1A,^X1A,^X1A,^X1A,^X1A,^X1A ; D8-DF ; .BYTE ^X1A,^X1A,^X53,^X54,^X55,^X56,^X57,^X58 ; E0-E7 ; .BYTE ^X59,^X5A,^X1A,^X1A,^X1A,^X1A,^X1A,^X1A ; E8-EF ; .BYTE ^X30,^X31,^X32,^X33,^X34,^X35,^X36,^X37 ; F0-F7 ; .BYTE ^X38,^X39,^X1A,^X1A,^X1A,^X1A,^X1A,^X1A ; F8-FF ; ; ;ASC_BCD_TAB: .BYTE ^X3F[32] ; 00-1F ; .BYTE ^X40,^XD0,^X3F,^X7B,^X5B,^X6C,^X50,^X7C ; 20-27 ; .BYTE ^X6C,^X4C,^X5C,^X50,^X6B,^X60,^X4B,^X61 ; 28-2F ; .BYTE ^XF0,^XF1,^XF2,^XF3,^XF4,^XF5,^XF6,^XF7 ; 30-37 ; .BYTE ^XF8,^XF9,^X7D,^X5E,^X4E,^X7B,^X7E,^XC0 ; 38-3F ; .BYTE ^X7C,^XC1,^XC2,^XC3,^XC4,^XC5,^XC6,^XC7 ; 40-47 ; .BYTE ^XC8,^XC9,^XD1,^XD2,^XD3,^XD4,^XD5,^XD6 ; 48-4F ; .BYTE ^XD7,^XD8,^XD9,^XE2,^XE3,^XE4,^XE5,^XE6 ; 50-57 ; .BYTE ^XD7,^XE8,^XE9,^X4D,^X6E,^X5D,^X3F,^X3F ; 58-5F ; .BYTE ^X3F[160] ; 60-FF ; ; .RESTORE ; .PAGE .SUBTITLE TRANSLATION DATA AREAS - POINTERS, ETC. ; ; POINTERS TO THE TRANSLATION TABLES. ; TRAN_TBL_PTR:: .LONG 0 ; ASCII -> EBCDIC TABLE .LONG 0 ; EBCDIC -> ASCII TABLE .ADDRESS AS8_7AS_TAB ; 8 BIT -> 7 BIT TABLE .ADDRESS AS7_8AS_TAB ; 7 BIT -> 8 BIT TABLE .ADDRESS FT_TRANS_DATA ; USER DEFINED TABLE ; ; ESCAPE CHARACTERS FOR THE ABOVE TABLES. ; TRAN_ESC_TAB:: .BYTE ^X3F ; ASCII TO EBCDIC "" IN ASCII .BYTE ^X5C ; EBCDIC TO ASCII "\" IN ASCII .BYTE ^X00 ; 8 BIT TO 7 BIT "" IN 8 BIT .BYTE ^X80 ; 7 BIT TO 8 BIT "" IN 7 BIT .BYTE 0 ; USER DEFINED - THE 257TH BYTE IN USER TABLE. ; .PAGE .SUBTITLE INITIALIZE VARIABLES AND DO MAJOR COPY. ; .ENTRY FT_TRANS,^M<> ; NO REGISTERS SAVED. ; ; CLEAR THE ESCAPE FLAG AND CHECK TO SEE IF THE OUTPUT ; POINTER AND COUNTER SHOULD BE INITIALIZED. ; BBSC #FLAG_V_ESCAPE,FTCB_W_FLAG(R10),5$ 5$: BBC #FLAG_V_INIT_COP,FTCB_W_FLAG(R10),20$ ; IF INIT. CLEAR, BRANCH ; 10$: MOVAL FT_OUT_DATA,R5 ; POINT TO THE OUTPUT DATA. MOVL 24(AP),R8 ; # RECORDS TO PUT INTO OUTPUT BLOCK. MOVL FTCB_L_TRAPTR(R10),R3 ; SET UP THE TRANSLATION TABLE POINTER. ; BBSC #FLAG_V_INIT_COP,FTCB_W_FLAG(R10),15$ ; CLEAR INIT COPY BIT. 15$: BRB SET_INPUT ; ; IF OUTPUT COMPLETE (BIT SET), BRANCH TO REINITIALIZE. 20$: BBS #FLAG_V_OUT_COMP,FTCB_W_FLAG(R10),10$ ; ; ; RESTORE THE OLD VALUE OF THE OUTPUT COUNT. ; MOVL T_OUT_COUNT,R8 ; ; SET UP THE INPUT POINTER AND THE NUMBER OF RECORDS ; TO COPY FROM THE INPUT BLOCK. ; SET_INPUT: MOVL 16(AP),R7 ; NUMBER OF RECORDS TO COPY. MOVAL FT_IN_DATA,R1 ; INPUT POINTER. ; ; ; DECREMENT THE COUNTER OF RECORDS TO COPY FROM INPUT AND ; BRANCH TO COPY IF GREATER THAN OF EQUAL TO 0. ; START_TRANS: SOBGEQ R7,TR_REC ; IF OK, GO TRANSLATE DATA. BRB END_INPUT ; ALL FINISHED FOR THIS BUFFER. ; ; SET UP THE COPY STRING LENGTHS. ; TR_REC: MOVL 4(AP),R0 ; INPUT STRING LENGTH MOVL 8(AP),R4 ; OUTPUT STRING LENGTH. ; ; MOVE AND TRANSLATE THE DATA TO THE OUTPUT BUFFER. IF ; THERE IS AN ESCAPE, MOVE THE OFFENDING CHARACTER AND ; PUT ERROR TO USER. ; TR_REC_1: MOVTUC R0,(R1),FTCB_B_ESCAPE(R10),(R3),R4,(R5) ; ; CHECK FOR ESCAPE. ; BVC 10$ ; IF OVERFLOW CLEAR, NO ESCAPE. ; ESCAPE FOUND - HANDLE THIS CONDITION AND THEN CHECK ; FOR END OF TRANSLATION RECORD. BSBW ESCAPE ; GO HANDLE THE ESCAPE. ; CHECK FOR END OF THE STRING BEFORE GOING BACK TO ; RESTART THE TRANSLATION. TSTL R0 ; IF R0 = 0, END OF INPUT RECORD. BEQL 10$ ; GET OUT OF LOOP. ; BRB TR_REC_1 ; CONTINUE THE COPY FROM POINT OF ESCAPE. ; ; CHECK FOR RECORD PADDING. 10$: BSBW PAD_REC ; ENTRY TO PAD OUTPUT RECORDS. ; ; INCREMENT THE RECORD READ COUNT AND THE RECORD WRITTEN COUNT. ; INCL FTCB_L_REC_READ(R10) INCL FTCB_L_REC_WRIT(R10) ; ; CHECK FOR MOVING ANY TRAILING DATA FROM THE INPUT. ; TSTL R0 ; IF NOT = 0, MORE DATA. BEQL T_UPDATE ; ; GO TO THE TRAIL RECORD ROUTINE TO DECIDE IF TRAILING DATA ; NEEDS TO BE MOVED AND THEN MOVE IT IF NECESSARY. ; BSBW TRAIL_TR ; ; ; UPDATE AND CHECK FOR OUTPUT BEFORE GOING BACK TO THE ; TOP OF THE MOVE CYCLE. ; T_UPDATE: BBSC #FLAG_V_OUT_COMP,FTCB_W_FLAG(R10),10$ ; CLEAR OUTPUT COMPLETE. ; ; GO TO CHECK FOR DOING OUTPUT. ; 10$: BSBW TR_OUTPUT ; ; IF AN ESCAPE DURING THE TRANSLATION, PUT THE MESSAGE. BBC #FLAG_V_ESCAPE,FTCB_W_FLAG(R10),20$ ; BRANCH IF CLEAR. CALL_MSG PUT_SYS,#FTC_TRANERR,#2,FTCB_L_REC_READ(R10),- FTCB_L_BLK_READ(R10) BBCC #FLAG_V_ESCAPE,FTCB_W_FLAG(R10),20$ ; CLEAR ESCAPE. ; 20$: BRB START_TRANS ; HANDLE NEXT RECORD. ; .PAGE .SUBTITLE END THE INPUT BLOCK AND KEEP TRAILING DATA IF DESIRED. ; END_INPUT: TSTL 12(AP) ; TEST FOR TRAILING BLOCK DATA. BEQL TR_RETURN ; IF NONE, RETURN TO CALLING ROUTINE. ; ; TRAILING DATA FOUND, SHOULD WE KEEP IT. IF TRAIL ; BLOCK BIT CLEAR, THROW THE EXTRA STUFF AWAY. ; BBC #FLAG_V_TRAILB,FTCB_W_FLAG(R10),TR_RETURN ; ; MOVE THE TRAILING BLOCK DATA. MOVL 12(AP),R0 ; COUNT OF INPUT STRING. MOVL 8(AP),R4 ; COUNT OF OUTPUT STRING. ; END_I_1: MOVTUC R0,(R1),FTCB_B_ESCAPE(R10),(R3),R4,(R5) ; BVC 10$ ; CHECK FOR ESCAPE. BSBW ESCAPE ; ESCAPE HAPPENED, GO HANDLE. BRB END_I_1 ; FINISH THE CURRENT MOVE. ; 10$: BSBW PAD_TRAILB ; FINISH KEEPING THE TRAILING BLOCK DATA. INCL FTCB_L_REC_WRIT(R10) ; INCREMENT RECORD WRITTEN. ; BSBB TR_OUTPUT ; GO CHECK ON WRITING A FULL BUFFER. ; ; ; SAVE THE OUTPUT COUNTER FROM R8 AND RETURN. TR_RETURN: MOVL R8,T_OUT_COUNT RET ; .PAGE .SUBTITLE TRANSLATION COPY TRAILING RECORD SUBROUTINE. ; TRAIL_TR: ; IF TRAIL RECORD BIT SET, KEEP THE DATA - ELSE RETURN. BBS #FLAG_V_TRAILR,FTCB_W_FLAG(R10),TRAIL_2 ; ; SOURCE STRING LARGER THAN DESTINATION STRING, NEED TO ; UPDATE POINTER TO BEGINNING OF NEXT "RECORD" IN THE SOURCE. ADDL2 R0,R1 ; ADD NUMBER OF REMAINING BYTES TO POINTER. 5$: RSB ; RETURN ; ; BEFORE MOVING THE TRAILING DATA, CHECK THE OUTPUT ; BUFFER TO SEE IF IT NEEDS TO BE WRITTEN. ; TRAIL_2: BSBB TR_OUTPUT ; MOVL 8(AP),R4 ; GET THE OUTPUT STRING LENGTH. ; ; SAVE THE EXTRA BYTES IN A RECORD. ; TRAIL_1: MOVTUC R0,(R1),FTCB_B_ESCAPE(R10),(R3),R4,(R5) ; BVC 10$ ; CHECK FOR ESCAPE CONDITION. BSBW ESCAPE ; ESCAPE FOUND, GO HANDLE. BRB TRAIL_1 ; GO CONTINUE COPYING THE CURRENT RECORD. ; 10$: INCL FTCB_L_REC_WRIT(R10) ; INCREMENT RECORD COUNT. BSBW PAD_TRAILR ; CHECK ON PADDING TRAILING RECORD DATA. ; ; TEST FOR MORE TRAILING DATA AND MOVE MORE IF NECESSARY. ; TSTL R0 ; IF R0 <> 0, THEN MORE TO MOVE. BNEQ TRAIL_2 ; MOVE SOME MORE. RSB ; NO MORE, RETURN. ; .PAGE .SUBTITLE OUTPUT CHECKING SUBROUTINE. ; TR_OUTPUT: SOBGTR R8,10$ ; DECREMENT THE OUTPUT COUNT AND BRANCH ; IF OUTPUT BLOCK NOT FULL. ; MOVQ R0,TR_SAVE ; SAVE THE R0 AND R1 VALUES. ; PUSHL R5 ; PUSH THE DESTINATION ADDRESS. PUSHL 20(AP) ; PUSH THE # BYTES REMAINING IN BLOCK . CALLS #2,G^FT_PADEVEN ; PAD/EVEN THE OUTPUT BLOCK ; CALLS #0,G^FT_OUTPUT ; WRITE THE BLOCK. ; ; RESET THE POINTER AND COUNTER FOR THE DATA IN THE OUTPUT. ; MOVAL FT_OUT_DATA,R5 ; ADDRESS OF THE OUTPUT DATA BUFFER. MOVL 24(AP),R8 ; NUMBER OF RECORDS IN OUTPUT BLOCK. ; MOVQ TR_SAVE,R0 ; RESTORE R0 AND R1 VALUES. ; 10$: RSB ; RETURN. ; .PAGE .SUBTITLE ESCAPE HANDLING SUBROUTINE. ; ; SET ESCAPE FLAG, PUT THE ESCAPE CHARACTER INTO THE ; OUTPUT BUFFER, AND INCREMENT THE POINTERS. ; ESCAPE: BBSS #FLAG_V_ESCAPE,FTCB_W_FLAG(R10),5$ ; SET ESCAPE FLAG. ; 5$: MOVB FTCB_B_ESCAPE(R10),(R5)+ ; MOVE BYTE AND INC. POINTER. INCL R1 ; INCREMENT THE POINTER TO INPUT STRING. DECL R0 ; DECREMENT THE SOURCE STRING LENGTH. DECL R4 ; DECREMENT THE DESTINATION STRING LENGTH. ; RSB ; .PAGE .SUBTITLE PAD CHARACTER SUBROUTINES - MULTIPLE ENTRY POINTS. ; ; SET THE PAD CHARACTER FOR PADDING RECORDS. ; PAD_REC: MOVZBL FTCB_B_PREC(R10),R6 ; PUT PAD CHARACTER INTO R6. BRB PAD_10 ; ; SET FOR KEEPING TRAILING DATA. PAD_TRAILR: MOVZBL FTCB_B_TRAILR(R10),R6 ; PUT TRAIL REC. CHARACTER INTO R6 BRB PAD_10 ; ; SET FOR KEEPING TRAILING BLOCK DATA. PAD_TRAILB: MOVZBL FTCB_B_TRAILB(R10),R6 ; PUT TRAIL BLOCK CHARACTER INTO R6. ; ; ; CHECK FOR PAD NEEDED AND RETURN IF NOT. ; PAD_10: TSTL R4 ; PAD NEEDED. BNEQ 10$ ; YES, GO PAD. RSB ; NO, RETURN. ; 10$: MOVQ R0,TR_SAVE ; SAVE R0,R1 MOVQ R2,TR_SAVE_1 ; SAVE R2,R3 MOVQ R4,TR_SAVE_2 ; SAVE R4,R5 ; MOVC5 #0,T_OUT_COUNT,R6,R4,(R5) ; PAD THE OUTPUT. ; MOVQ TR_SAVE_2,R4 ; RESTORE R4,R5 MOVQ TR_SAVE_1,R2 ; RESTORE R2,R3 MOVQ TR_SAVE,R0 ; RESTORE R0,R1 ; ADDL2 R4,R5 ; UPDATE ADDRESS OF OUTPUT ADDL2 R4,R1 ; UPDATE ADDRESS OF INPUT. ; RSB ; T_OUT_COUNT: .LONG 0 ; SAVE AREA FOR THE OUTPUT COUNTER. TR_SAVE: .QUAD 0 ; SAVE AREA FOR R0 AND R1. TR_SAVE_1: .QUAD 0 TR_SAVE_2: .QUAD 0 ; .END