OPTIONS /CHECK=NOOVERFLOW INTEGER*2 FUNCTION IRAD50(ICNT,INPUT,OUTPUT) C+ C C ABSTRACT: C C Fortran version of the IRAD50 function. C C FUNCTIONAL DESCRIPTION: C C IRAD50 converts ASCII characters to Radix-50 form, storing them C as three characters per output 16-bit word. C C FORMAL PARAMETERS: C C ICNT: C Specifies the number of characters of INPUT C to be converted. INTEGER*2 C C INPUT: C The Hollerith string to be converted, passed C by reference or by descriptor. C C OUTPUT: C A numeric variable or array element where the C Radix-50 results are stored. C C C FUNCTION VALUE: C C The number of characters converted. Conversion stops when a C non-Radix-50 character is seen; the last converted word will C appear to be blank-filled on the left (this is not what one might C expect from the documentation, but it is what the VAX C implementation does.) C C DESIGN: C C See section B.3 of the DEC Fortran Language Reference Manual C and Appendix F of the DEC Fortran User Manual for OpenVMS VAX C C- IMPLICIT NONE INCLUDE '($DSCDEF)' ! Descriptor definitions STRUCTURE /DSC/ ! Descriptor structure INTEGER*2 DSC$W_LENGTH BYTE DSC$B_DTYPE BYTE DSC$B_CLASS INTEGER*4 DSC$A_POINTER END STRUCTURE INTEGER*2 ICNT RECORD /DSC/ INPUT INTEGER*2 OUTPUT(*) BYTE INPUT_CHARS(*) POINTER (INPUT_P, INPUT_CHARS) BYTE ASCII_RAD50(0:255) /32*-1,O'00',3*-1,O'33',9*-1,O'34',-1, 1 O'36',O'37',O'40',O'41',O'42',O'43',O'44',O'45',O'46',O'47', 2 7*-1,O'1',O'2',O'3',O'4',O'5',O'6',O'7',O'10',O'11',O'12', 3 O'13',O'14',O'15',O'16',O'17',O'20',O'21',O'22',O'23',O'24', 4 O'25',O'26',O'27',O'30',O'31',O'32',37*-1,128*-1/ INTEGER*2 OUTPUT_COUNT,TRANS INTEGER*4 I ! Determine if INPUT was passed by reference or by descriptor. ! We can't tell for sure, but the VAX code used the following ! checks. ! INPUT_P = %LOC(INPUT) ! Assume reference IF ((INPUT.DSC$W_LENGTH .LE. 255) .AND. 1 (INPUT.DSC$B_DTYPE .EQ. DSC$K_DTYPE_T) .AND. 2 (INPUT.DSC$B_CLASS .EQ. DSC$K_CLASS_S)) 3 INPUT_P = INPUT.DSC$A_POINTER ! Looks as if by descriptor IRAD50 = 0 ! Initial return value OUTPUT_COUNT = 0 ! Loop through INPUT three characters at a time, building ! the Radix-50 representation. ! DO WHILE (IRAD50 .LT. ICNT) OUTPUT_COUNT = OUTPUT_COUNT + 1 OUTPUT(OUTPUT_COUNT) = 0 DO I = 1,3 IF (IRAD50 .GE. ICNT) THEN ! Pad last word with blanks OUTPUT(OUTPUT_COUNT) = OUTPUT(OUTPUT_COUNT) * O'50' ELSE TRANS = ASCII_RAD50(INPUT_CHARS(I)) IF (TRANS .LT. 0) RETURN ! Exit due to bad character OUTPUT(OUTPUT_COUNT) = (OUTPUT(OUTPUT_COUNT) * O'50') + 1 TRANS IRAD50 = IRAD50 + 1 ! Indicate one more character translated END IF END DO INPUT_P = INPUT_P + 3 ! Move to next three characters END DO RETURN END REAL*4 FUNCTION RAD50(NAME) C+ C C ABSTRACT: C C Fortran version of the RAD50 function. C C FUNCTIONAL DESCRIPTION: C C RAD50 converts six ASCII characters to Radix-50 C C FORMAL PARAMETERS: C C NAME: C A numeric variable or array element corresponding to a C six-character Hollerith string, passed by reference or by C descriptor C C FUNCTION VALUE: C C The Radix-50 translation of NAME. Conversion stops when a C non-Radix-50 character is seen C C DESIGN: C C See section B.3 of the DEC Fortran Language Reference Manual C and Appendix F of the DEC Fortran User Manual for OpenVMS VAX C C- IMPLICIT NONE INTEGER*4 NAME,ICNT,IRAD50 EXTERNAL IRAD50 ! Call IRAD50 to do the conversion, discarding the count ! ICNT = IRAD50 (6,NAME,RAD50) RETURN END OPTIONS /CHECK=NOOVERFLOW SUBROUTINE R50ASC(ICNT,INPUT,OUTPUT) C+ C C ABSTRACT: C C Fortran version of the R50ASC function. C C FUNCTIONAL DESCRIPTION: C C R50ASC converts Radix-50 characters to ASCII characters. C C FORMAL PARAMETERS: C C ICNT: C Specifies the number of characters of OUTPUT C to be produced. INTEGER*2 C C INPUT: C The Radix-50 variable or array element to be converted, passed C by reference. C C OUTPUT: C A numeric variable or array element where the C ASCII results are stored. C C C DESIGN: C C See section B.3 of the DEC Fortran Language Reference Manual C and Appendix F of the DEC Fortran User Manual for OpenVMS VAX C C If an individual Radix-50 character is invalid (O'35') or if the C word to be translated is greater than O'174777', question mark C characters are used for the result C- IMPLICIT NONE INTEGER*2 ICNT,INPUT(*) BYTE OUTPUT(*) CHARACTER*1 TCHARS(3) CHARACTER*1 RAD50_ASCII(0:39) /' ','A','B','C','D','E','F', 1 'G','H','I','J','K','L','M','N','O','P','Q','R','S','T', 2 'U','V','W','X','Y','Z','$','.','?','0','1','2', 3 '3','4','5','6','7','8','9'/ INTEGER*4 TMP,INPUT_POS,OUTPUT_POS,I INPUT_POS = 0 OUTPUT_POS = 0 ! Loop through input array, converting up to three characters ! from each word. ! DO WHILE (OUTPUT_POS .LT. ICNT) INPUT_POS = INPUT_POS + 1 TMP = ZEXT(INPUT(INPUT_POS)) IF (TMP .GT. O'174777') TMP = O'134745' ! '???' DO I=3,1,-1 TCHARS(I) = RAD50_ASCII(MOD(TMP,O'50')) TMP = TMP / O'50' END DO DO I=1,3 IF (OUTPUT_POS .GE. ICNT) RETURN OUTPUT_POS = OUTPUT_POS + 1 OUTPUT(OUTPUT_POS) = ICHAR(TCHARS(I)) END DO END DO RETURN END