RSX11M HEXADECIMAL COMMAND LINE NUMERICS Carl T. Mickelson Goodyear Aerospace Corporation Akron, Ohio 44315 ABSTRACT ________ This paper describes a set of modifications to RSX11M SYSLIB and FCSRES to support the processing and display of numeric quantities as hexadecimal character strings. The modifications provide additional system subroutine entry points to allow application programs to parse hexadecimal quantities from command lines and to display numeric values as hexadecimal numbers when outputting data to the user. BACKGROUND Since RSX11M was first released, the operating system has been limited to representing numeric quantities on command lines and in program generated output as either octal or decimal character strings. Some programs such as DuMP provide a hexadecimal dump mode supported by routines within the program. However, RSX11M does not provide a means within SYSLIB for any program to "hear" or "speak" hex by way of a simple subroutine call. The tools provided by RSX11M include a number of system library entry poiints to convert byte wide, word wide, and double-word wide data to and from octal and decimal character strings. Some of the applications developed at the author's site required a similar facility for processing MCR-like command switch parameters in hexadecimal. The goal of this effort then was to develop a set of modifications to the numeric conversion routines in SYSLIB to provide a similar set of facilities for processing hexadecimal quantities as already exist for processing octal and decimal quantities. ISSUES NEEDING CONSIDERATION The code that processes octal and decimal numeric strings is contained in a number of modules in SYSLIB, the system object library. These routines also reside in the system resident library, if this option is selected during system generation. The changes discussed here are changes to these modules that make the modules larger. Programs that need to use these new functions can simply link copies of the modules into their task images to do hexadecimal numeric conversions. A potential problem exists, however, if these modules are replaced in a resident library. If these larger modules are included in a resident library on a single system, it could prevent tasks that do not use the new functions from being transferred between systems with different resident libraries because of differences in entry point addresses for the two library versions. The solution to this problem was introduced in Update B to RSX11M V4.1. The entry points into the resident library were vectored into the code portion of the library using a technique that is similar to the way VMS vectors calls to system functions through a transfer vector. The transfer vector consists of a JMP instruction to each entry point within the resident library task. Any task linking to a library routine transfers control to one of the JMP instructions which transfers control to the local entry within the library. By keeping the order of the JMP instructions, and hence the library entries, fixed within the transfer vector, the internal library modules can be changed without effecting a task's ability to find entries in the modified module. Tasks that are linked to a library containing modules supporting the new hexadecimal functions, but that make no use of them, can successfully be moved to a system with a resident library that does not support the hex conversions. All that is required is that the order of the transfer vector entry points are preserved between the library versions. The module entry point addresses within the library are different between the two versions, but are important only within the context of the library task. NUMERIC CONVERSION TOOLS IN SYSLIB Table 1 summarizes the numeric conversion facilities supplied with the standard RSX11M distribution. These routines are documented in chapters 4, 5, and 6 of the RSX11M System Library Routines Reference Manual. There are entry points available for input conversions from octal and decimal ASCII digit character strings to internal binary, and output conversion entries for translating from internal binary to octal or decimal ASCII digit character strings. In addition, a generalized formatting subroutine is provided that permits a MACRO programmer to create character oriented output records from a buffer of binary data. The record format is determined by a control string that is interpreted by the subroutine in a manner analogous to a FORTRAN FORMAT statement. The subroutine supports both octal and decimal format specifiers. The new hexadecimal functions added to these SYSLIB modules are summarized in Table 2. The changes include support for both input and output conversions using a hexadecimal radix. In addition, format descriptors are added to the formatting subroutine to support hexadecimal output. The calling sequences for these new functions are the same as the calling sequences for the existing functions. Detailed documentation on the use of the new functions is included as an appendix to this paper. ASCII to Binary Conversions Data Length Radix Word Double-Word Octal $COTB .OD2CT Decimal $CDTB .DD2CT Binary to ASCII Conversions Data Length Radix Word Double-Word Octal (Magnitude) $CBOMG $CBTMG (byte) (Signed) $CBOSG Decimal (Magnitude) $CBDMG $CDDMG (Signed) $CBDSG Generalized Formatting Descriptors ($EDMSG) %B Binary Byte to Octal String %D Binary Word to Signed Decimal String %M Binary Word to Decimal Magnitude String %O Binary Word to Signed Octal String %P Binary Word to Leading Zero Octal Magnitude String %Q Binary Word to Zero Suppressed Octal Magnitude String %T Binary Double Word to Decimal Magnitude String %U Binary Word to Zero Suppressed Decimal Magnitude String Table 1 - Standard RSX11M Numeric Conversions ASCII to Binary Conversions Data Length Radix Word Double-Word Hexadecimal $CHTB .HD2CT Binary to ASCII Conversions Data Length Radix Word Byte Hexadecimal (Magnitude) $CBHMG $CBGMG (Signed) $CBHSG Generalized Formatting Descriptors ($EDMSG) %G Binary Byte to Hexadecimal String %H Binary Word to Hexadecimal Magnitude String %J Binary Word to Signed Hexadecimal String Table 2 - Hexadecimal Numeric Conversions DEVELOPING THE ADDED FUNCTIONS There are six modules in SYSLIB that are changed to support the hexadecimal functions described earlier. The modules CATB, CBTA, .ODCVT and OD2CT have additional instructions inserted to perform the actual conversions of character strings to and from binary. The EDMSG and .TPARS modules are modified to make reference to the new function entry points when hexadecimal numbers are to be converted. The changes to these modules are designed and implemented as source language update (SLP) correction files to be applied to a source file for the module. The sources for the modules are generated by an object code disassembler. Once the modules are changed, the updated source files are re-assembled and replaced into the system library object file. Any program needing access to these functions can link the revised modules into the task image to use the new functions. In addition to the changes made to these SYSLIB modules, two system macro definitions, CSI$SV and ISTAT$, are enhanced to allow a MACRO programmer to access these hexadecimal conversions from the Command String Interpreter, CSI1 and CSI2, and the Table Driven Parser, TPARS. The only remaining detail is to include the new functionality in any resident library that is built during SYSGEN. The resident library built during the SYSGEN procedure is approximately 7 Kwords long, and is organized into two overlay sections so that the entire library can be accessed using only one 4 Kword APR. During the SYSGEN procedure, the resident library symbol table is created from the object modules FCSST1 and FCSST2. The library task includes the modules FCSLB1 and FCSLB2, each linked into the beginning of an overlay segment. The FCSLBx modules contain the library entry point transfer vectors, while the FCSSTx modules define the externally available entry point addresses to each transfer vector in the library. It is critical that the order of the entries in the FCSSTx and FCSLBx modules are and remain the same. To maintain compatibility with other libraries, any new entry points must be added at the end of the transfer vector list. The new hexadecimal support entry points are added to the end of the DEC specified transfer vector list, leaving some empty vectors available for additional DEC supplied functions in a future release of RSX11M. The modules FCSSTx and FCSLBx are disassembled, changed with a SLP correction file, re-assembled and replaced into SYSLIB. The resident library task build driver file, FCSRS1BLD.BLD, is changed to include the new entry points in the overlay symbol table. Finally, the modified resident library is built by the SYSGEN procedure in the normal fashion. USING THE MODIFICATION KIT The modifications described here are performed by a set of command procedures that will be available on the RSX SIG tape from the New Orleans DECUS. They should be used in accordance with the following procedure. First copy the RSX11M baseline distribution kit to scratch media as described in the RSX11M SYSGEN reference manual. Then apply DEC's distributed Update D patch procedure to recreate the RSX11M baseline kit against which these modifications are performed. Finally, apply the procedure described in this paper by invoking the DECUSMODS.CMD command procedure. This command procedure supports all three types of RSX11M distribution kit and will ask the user to specify which kit is in use. The indirect command processor re-build step can be skipped if the SYSGEN procedural modifications described the the companion paper "Loadable Device Driver Data Bases in RSX11M SYSGEN" are not being performed. Application of the HEXMOD command procedure should be selected to install the functionality described in this paper. The procedure is designed to verify the modified files against expected results, but due to DECUS restrictions about copyrighted source code content on SIG tape submissions, not all the required files can be included. This should pose no problems, so long as Update D of V4.1 is used as the baseline for the procedure. After the modifications are performed, the normal SYSGEN procedure is initiated as described in the SYSGEN manual. CONCLUSIONS AND COMMENTS The techniques discussed here and embodied in the files of the modification kit permit support to be provided for processing and generating hexadecimal numerics in PDP-11/RSX11M programs. These techniques have been successfully used on PDP 11/34, PDP 11/24, and PDP 11/40 processors. However the following comments and cautions are applicable when considering using these changes. 1. The changes apply to Update D of RSX11M V4.1. Proper application to other updates of V4.1 is not guaranteed. 2. The extra code added to certain SYSLIB modules to support hexadecimal numerics may make large programs that include copies of the modules within their task images too large to be built successfully. Tasks mapping a resident library should not be affected by this size increase. The changes do not make the library bigger than the single APR already required to map the resident library code. CAVEAT The kit of files comprising the hexadecimal changes described here are supplied for information purposes only. Use of these changes at any PDP-11/RSX11M site is entirely at the risk of the using organization. Neither the author, nor Goodyear Aerospace Corporation, nor DECUS, nor the RSX SIG is responsible if these changes do not perform successfully in any particular system. APPENDIX The following information provides documentation on using the hexadecimal conversion functions added to SYSLIB and described in this paper. The structure of this documentation is similar to that appearing in Chapters 4, 5, and 6 of the RSX11M System Subroutine Library Reference Manual, and should be regarded as a supplement to that manual. The changes made to the macro definitions CSI$SV and ISTAT$ are also documented here. This information supplements data appearing in the RSX11M IO Operations Reference Manual. The details of using the macros are explained in Chapters 6 and 7. Only the changes made to the macros, and the additional functionality these changes provide is discussed here. Hexadecimal to Binary Double-word Routine (.HD2CT) ___________ __ ______ ___________ _______ ________ The .HD2CT routine converts an ASCII hexadecimal string to a double length (two-word) binary number. The routine accepts leading plus (+) or minus (-) signs, and the numbers 0 - F. A preceding ! symbol is legal in the hexadecimal number string. A ! symbol and a period in the same string is invalid. A trailing decimal point will be accepted in the input string, but will cause the decimal, rather than hexadecimal, radix to be used. This condition exists because the .HD2CT routine is an entry point in the .DD2CT routine, which converts decimal number strings to binary double-word values. Any other characters in the ASCII hexadecimal number string will cause the .HD2CT routine to terminate the conversion procedure. The value range of a hexadecimal number to be converted is - 2^31 to +( 2^31 - 1). To call the .HD2CT routine: 1. Supply three input arguments in the task's source code: a. in Register 3, the address of the two-word field in which the converted number is to be stored. b. in Register 4, the number of characters in the string to be converted. c. in Register 5, the address of the character string to be converted. 2. Include the statement CALL .HD2CT in the source program. The .HD2CT routine saves and restores all the calling task's registers. Outputs from the .HD2CT routine are: 1. The converted number, where the high order 16 bits are stored in word 1 of the field specified in R3 input, and the low order 16 bits are stored in word 2 of the field. 2. Condition Code: C bit = clear if conversion was successful. C bit = set if an illegal character was found and conversion was incomplete. The user can determine, in the task, whether conversion was complete by testing the C bit in the Condition Code. Hexadecimal to Binary Conversion Routine ($CHTB) ___________ __ ______ __________ _______ _______ The $CHTB routine converts an ASCII hexadecimal number to binary. Valid characters in the number to be converted are 0 - F. The end of the string must be marked by a terminating character, which may be any ASCII character except the numbers 0 - F. Examples of terminating characters are: blank, a tab character, an alphabetic character other than A - F, and a special symbol. Leading blanks and tab characters are ignored. The maximum value of a hexadecimal number that can be converted by the $CHTB routine is FFFF. To call the $CHTB routine: 1. Input, in Register 0, the address of the first byte of the ASCII characters to be converted. 2. Include the statement CALL $CHTB in the source program. The $CHTB routine calls the $SAVRG routine to save and restore registers 3 - 5 of the calling task. The outputs returned from the $CHTB routine are: 1. R0 = the address of the next byte in the input buffer. 2. R1 = the converted number. 3. R2 = the terminating character. The user can determine, in the task, whether an input string was successfully converted by testing the content of R2. If the content is other than the expected terminating character, the conversion was incomplete, since some other invalid character was found in the input string. Successive input string conversion may be effected by setting up a processing loop to repetitively call $CHTB. BINARY TO HEXADECIMAL CONVERSION There are three system library routines that convert internally formatted binary numbers to external ASCII hexadecimal format: 1. Convert Binary to Hexadecimal Magnitude Routine ($CBHMG), which converts an internally stored binary number to a 4-digit unsigned ASCII hexadecimal magnitude number. 2. Convert Binary to Signed Hexadecimal ($CBHSG), which converts an internally stored binary number to a 4-digit signed ASCII hexadecimal number. 3. Convert Binary Byte to Hexadecimal Magnitude Routine ($CBGMG), which converts an internally stored binary byte to a 2-digit ASCII hexadecimal number. These routines use predefined parameters that are passed to the general purpose conversion routine ($CBTA), which performs the actual binary to ASCII conversion. Convert Binary to Hex Magnitude Routine ($CBHMG) _______ ______ __ ___ _________ _______ ________ The $CBHMG routine converts an internally stored binary number to a 4-digit unsigned ASCII hexadecimal magnitude number. The $CBHMG routine uses the following predefined conversion parameters: radix = 16. field width = 4. characters sign flag = UNSIGNED leading zeroes flag = NOSUP (no supression) To call the $CBHMG routine: 1. Supply three input arguments in the task's source code: a. in Register 0, the starting address of the output area in which the converted 4-digit number is to be stored. b. in Register 1, the binary number to be converted. c. in Register 2, the zero supression indicator, where: R2 = 0 to specify supression of leading zeroes in the converted number. The output number will be left-justified. R2 = nonzero to specify that leading zeroes are not to be suppressed. 2. Include the statement CALL $CBHMG in the source program. The predefined conversion parameters are automatically pushed to the stack on entry to the $CBHMG routine. If the user specifies, via R2 = 0, that leading zeroes are to be suppressed, the NOSUP parameter is reset. In any case, the $CBHMG routine passes the parameters in Register 2 to the General Purpose Binary to ASCII Conversion Routine ($CBTA), which performs the actual conversion of the binary number. The $CBTA routine calls the $SAVRG routine to save and restore registers 3 - 5 of the calling task. Registers 1 and 2 are destroyed. Outputs from the $CBHMG routine are: 1. The converted number, a maximum of four digits in length, in the specified output area. 2. R0 = the next available address in the output area (the pointer to the location following the last digit stored). The $CBHMG routine does not return error conditions to the caller. Convert Binary to Signed Hex Routine ($CBHSG) _______ ______ __ ______ ___ _______ ________ The $CBHSG routine converts an internally stored binary number to a 4-digit signed ASCII hexadecimal number. The $CBHSG routine uses the following predefined conversion parameters: radix = 16. field width = 4. characters sign flag = SIGNED leading zeroes flag = NOSUP (no supression) To call the $CBHSG routine: 1. Supply three input arguments in the task's source code: a. in Register 0, the starting address of the output area in which the converted 4-digit number is to be stored. b. in Register 1, the binary number to be converted. c. in Register 2, the zero supression indicator, where: R2 = 0 to specify supression of leading zeroes in the converted number. The output number will be left-justified. R2 = nonzero to specify that leading zeroes are not to be suppressed. 2. Include the statement CALL $CBHSG in the source program. The predefined conversion parameters are automatically pushed to the stack on entry to the $CBHSG routine. If the user specifies, via R2 = 0, that leading zeroes are to be suppressed, the NOSUP parameter is reset. In any case, the $CBHSG routine passes the parameters in Register 2 to the General Purpose Binary to ASCII Conversion Routine ($CBTA), which performs the actual conversion of the binary number. The $CBTA routine calls the $SAVRG routine to save and restore registers 3 - 5 of the calling task. Registers 1 and 2 are destroyed. Outputs from the $CBHSG routine are: 1. The converted number, a maximum of four digits in length, in the specified output area. 2. R0 = the next available address in the output area (the pointer to the location following the last digit stored). The $CBHSG routine does not return error conditions to the caller. Convert Binary Byte to Hex Magnitude Routine ($CBGMG) _______ ______ ____ __ ___ _________ _______ ________ The $CBGMG routine converts an internally stored binary number to a 2-digit ASCII hexadecimal number. The $CBGMG routine uses the following predefined conversion parameters: radix = 16. field width = 2. characters sign flag = UNSIGNED leading zeroes flag = NOSUP (no supression) To call the $CBGMG routine: 1. Supply three input arguments in the task's source code: a. in Register 0, the starting address of the output area in which the converted 2-digit number is to be stored. b. in Register 1, the binary byte to be converted in the low order byte. c. in Register 2, the zero supression indicator, where: R2 = 0 to specify supression of leading zeroes in the converted number. The output number will be left-justified. R2 = nonzero to specify that leading zeroes are not to be suppressed. 2. Include the statement CALL $CBGMG in the source program. The predefined conversion parameters are automatically pushed to the stack on entry to the $CBGMG routine. If the user specifies, via R2 = 0, that leading zeroes are to be suppressed, the NOSUP parameter is reset. In any case, the $CBGMG routine passes the parameters in Register 2 to the General Purpose Binary to ASCII Conversion Routine ($CBTA), which performs the actual conversion of the binary byte. The $CBTA routine calls the $SAVRG routine to save and restore registers 3 - 5 of the calling task. Registers 1 and 2 are destroyed. Outputs from the $CBGMG routine are: 1. The converted number, a maximum of two digits in length, in the specified output area. 2. R0 = the next available address in the output area (the pointer to the location following the last digit stored). 3. R1 = low order byte is unchanged; high order byte is cleared by the $CBGMG routine. The $CBGMG routine does not return error conditions to the caller. GENERALIZED FORMATTING Generalized output formatting is provided by the Edit Message Routine ($EDMSG). The changes described in this paper have added three types of output format conversions to the capabilities of this routine. These format conversions are documented here. The terms used in explaining these conversions have the same meaning as that used in Table 6-1 in the RSX11M System Library Routine Reference Manual. Directive Form Operation G %G Convert the next binary byte (binary byte address in ARGBLK to hexa- to hexa- decimal and store result in decimal conv) OUTBLK. %nG Convert the next n binary bytes from address in ARGBLK to hexadecimal numbers, and store results in OUTBLK; insert space between numbers. %VG Use the value in the next word in ARGBLK as repeat count, convert the specified number of binary bytes from address in ARGBLK to hexa- decimal numbers, and store results in OUTBLK; space between numbers. H %H Convert the binary value (binary to in the next word in ARGBLK hexadecimal to hexadecimal magnitude magnitude and store result in OUTBLK. conversion) %nH Convert the next n binary values in ARGBLK to hexa- decimal magnitude and store results in OUTBLK; insert tab between numbers. %VH Use the value in the next word in ARGBLK as repeat count, convert the specified number of binary values to hexadecimal magnitude, and store the results in OUTBLK; insert tab between numbers. J %J Convert the binary value in (binary to the next word in ARGBLK to signed signed hexadecimal and store hexadecimal the result in OUTBLK. conversion) %nJ Convert the next n binary values in ARGBLK to signed hexadecimal and store the results in OUTBLK; insert tab between numbers. %VJ Use the value in the next word in ARGBLK as repeat count, convert the specified number of binary values to hexadecimal and store the results in OUTBLK; insert tab between numbers. COMMAND STRING INTERPRETER MACRO CHANGES The use of the Command String Interpreter switch value macro CSI$SV enhancement is explained below. This information supplements the explanation of the 'type' parameter to the macro. See the RSX11M IO Operations Reference Manual, section 6.2.4.2 for more information. The conversion-type argument can take on the value: HEX - Indicating that a numeric switch value is to be converted to binary using hexadecimal as a default conversion radix. On the next page of the referenced manual the last two paragraphs describing numeric conversions should be replaced with the following: On numeric conversions, the default conversion type specified for a switch value can be overridden by means of a pound sign (#), an exclamation point (!), or a dot (.). A numeric value preceded by a pound sign (for example, #10) forces the conversion type to octal; a numeric value preceded by an exclamation point (for example, !10) forces the conversion type to hexadecimal; a numeric value followed by a dot (for example, 10.) forces the conversion type to decimal. Note also that a numeric value can be preceded by a plus sign (+) or a minus sign (-). The plus sign is the default assumption. If an explicit octal or hexadecimal value is specified using the pound sign (#) or exclamation point (!), as described above, the arithmetic sign indicator (+ or -), if included, must precede the pound sign or exclamation point (for example -#10). If the conversion type is decimal, the switch value is evaluated as a single number; an overflow into the high-order bit (bit 15) results in an error condition. However, if the conversion type is octal or hexadecimal, a full 16-bit value may be specified. TABLE DRIVER PARSER MACRO CHANGES The use of the Table Driven Parser has been enhanced to include two state transitions based on a hexadecimal digit or a hexadecimal number. This information supplements sections 7.1.2 and 7.2.1 of the RSX11M IO Operations Reference Manual. The following two state transitions are defined for use in the 'type' parameter to the TRAN$ macro: $HXDIG - Matches any single hexadecimal digit (0 - F). $HXNUM - Matches a hexadecimal number. Such a number consists of hexadecimal digits, followed optionally by a period. If number is not followed by a period, it is interpreted as hexadecimal. Numbers followed by a period are interpreted as decimal and the decimal point is included in the matching string. A number is terminated by any non-hexadecimal character. Values through 2^32 - 1 are converted to 32-bit unsigned integers. The transitions in a state may represent several syntax types; a portion of a string being scanned often matches more than one syntax type. Therefore, the order in which the types are entered in the state table is critical. Transitions are always scanned in the order in which they are entered and the first transition matching a string being scanned is the transition taken. Therefore, the following order is recommended for states containing more than one syntax type: char keyword $EOS $HXDIG $ALPHA $DIGIT $BLANK $HXNUM $NUMBER $DNUMB $STRNG $RAD50 $ANY $LAMDA Placement of !label transitions in a state depends on the types and positions of other syntax types in the state as well as on the syntax types in the starting state of the subexpression.