Trailing-Edge
-
PDP-10 Archives
-
bb-r775d-bm_tops20_ks_upd_4
-
sources/dixlib.bli
There are 21 other files named dixlib.bli in the archive. Click here to see a list.
%TITLE 'Library of definitions for the DIX'
! COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1983, 1985.
! ALL RIGHTS RESERVED.
!
! THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND
! COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH
! THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR
! ANY OTHER COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE
! AVAILABLE TO ANY OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE
! SOFTWARE IS HEREBY TRANSFERRED.
!
! THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT
! NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL
! EQUIPMENT CORPORATION.
!
! DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF
! ITS SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL.
!++
! .Chapter DIXLIB
! The module DIXLIB defines global data structures and code values for
! the DIX package.
!
! This was done for two reasons: The obvious one of isolating such
! definitions to one module, and a secondary one. The secondary reason
! is that, by placing code value definitions in a library file, it is
! possible to write programs which, by calling that library file, get
! lists of code values which they write out to files in various ways.
! This allows you to implement automatic generation of interface support
! files.
!--
!++
! .HL 1 Library files used
!--
%BLISS32 ( ! ; .P;If we're BLISS 32, then
LIBRARY 'SYS$LIBRARY:XPORT'; ! \\ and
LIBRARY 'SYS$LIBRARY:STARLET'; ! \\
)
%BLISS36 ( ! ; .p;If we're BLISS 36 then
LIBRARY 'BLI:XPORT'; ! \\ and
LIBRARY 'STAR36'; ! \\
)
! ; .P;In either case,
LIBRARY 'FIELDS'; ! \\
MACRO
blf$comma =
%; ! Hack to format $OVERLAY right
%sbttl 'Edit History' ! [7] Add this entire subsection
!++
! .hl 1 Edit History
!
! The edit history/version number information in this file is used
! to build a literal, dix$k_library_version, giving the full version
! information. The history modules that use this library make an OWN
! location called dix$g_library_version and initialize it to
! dix$k_library_version. This makes it possible to tell at debug time
! what version of the library was actually compiled against.
!--
LIBRARY 'VERSION';
! ; .autotable
!++ COPY
new_version (1, 0)
edit (7, '23-Aug-82', 'David Dyer-Bennet')
%( Change version and revision standards everywhere.
Files: All. )%
edit (8, '15-Sep-82', 'David Dyer-Bennet')
%( Definition of XCGEN as pseudonym for DIX$BY_DIX_DES was missing from
DIXLIB.
Files: DIXLIB.BLI )%
Edit (%O'26', '17-Jan-83', 'David Dyer-Bennet')
%( Change error message for DIX$_IMPOSSIBLE.
Files: DIXLIB.BLI
)%
Edit (%O'30', '19-Jan-83', 'David Dyer-Bennet')
%( Update copyright notices, add mark at end of edit histories.
)%
Edit (%O'35', '7-June-83', 'Charlotte L. Richardson')
%( Declare version 1 complete. All modules.
)%
new_version (1, 1)
new_version (2, 0)
Edit (%O'36', '11-Apr-84', 'Sandy Clemens')
%( Put all Version 2 DIX development files under edit control. Some of
the files listed below have major code edits, or are new modules. Others
have relatively minor changes, such as cleaning up a comment.
FILES: COMDIX.VAX-COM, COMPDX.CTL, DIXCST.BLI, DIXDEB.BLI,
DIXDN.BLI (NEW), DIXFBN.BLI, DIXFP.BLI, DIXGBL.BLI, DIXGEN.BLI,
DIXHST.BLI, DIXINT.PR1, DIXINT.PR2, DIXLIB.BLI, DIXPD.BLI (NEW),
DIXREQ.REQ, DIXSTR.BLI, DIXUTL.BLI, DXCM10.10-CTL, MAKDIXMSG.BLI,
STAR36.BLI, VERSION.REQ.
)%
Edit (%O'50', '8-Oct-84', 'Sandy Clemens')
%( Add new format of COPYRIGHT notice. FILES: ALL )%
! **EDIT**
!-- .autoparagraph
%BLISS36 (
MACRO
dix$k_library_version = %NAME ('lib%ve') %;
)
LITERAL
dix$k_library_version = version_number
(major = major_version,
minor = minor_version,
edit_no = edit_number);
UNDECLARE
major_version, minor_version, edit_number, sequence_check_edits;
%SBTTL 'Debugging Declarations'
!++
! .HL 1 Debugging Declarations
!
! There is extensive debugging code and many special definitions in
! the DIX code. All of it is conditional (at compiletime) on a literal.
! Further, if that literal is set, there are run-time variables
! defined in each module and routine that control whether any special
! debugging code actually executes. These may be poked with a debugger
! to give you dynamic control of debugging prints.
!
! >DIX$K_DEBUG controls compiletime generation of all this debugging
! code.
!
! >DIX$GG_DEBUG controls run-time debugging for the entire package.
! If this is false, no debugging prints or other code will execute.
!
! >MODULE_DEBUG (defined in each module) must be true for any debugging
! code in the module to execute. Note that, if DIX$GG_DEBUG is not true,
! the setting of MODULE_DEBUG is irrelevant.
!
! >ROUTINE_DEBUG (defined in each routine) must be true for any
! debugging code in the routine to execute. Note that, if DIX$GG_DEBUG or
! MODULE_DEBUG is not true, the setting of ROUTINE_DEBUG is irrelevant.
!
! >DEBUG_FLAG is dynamically bound at the start of each routine to
! be the logical AND of the above three flags. This is the flag that
! actual debugging code checks.
!--
!++
! The require file >DIXDEB.REQ does nothing but define a value for
! >dix$k_debug>, a literal. By doing the require within the library file,
! debugging/non-debugging becomes an attribute of the version of DIXLIB
! with which other modules are compiled.
!--
REQUIRE 'DIXDEB';
!++
! .hl 2 Debugging macros
!
! Described below are macros which help set up and use the debugging
! control fields:
!--
MACRO
DIX$DEBUG ! \.HL 3 >\
!++
! This macro expands to its arguments (%REMAINING) if
! dix$k_debug is true, to null otherwise.
!--
[] = ! ; This is a conditional macro with no arguements.
%IF dix$k_debug %THEN %REMAINING %FI %,
DIX$module_debug ! \.hl 3 >\
!++
! This macro defines MODULE_DEBUG as its argument. It should
! be called at the start of every module. It should not be followed
! by a semi-colon.
!
! Arguments:
!--
( ! ; .s 1.list 1
module_debug_flag ! \.le;\: True if debugging wanted
) = ! ; .end list
DIX$DEBUG (OWN module_debug: INITIAL (module_debug_flag) VOLATILE;
EXTERNAL dix$GG_debug;)
% ,
dix$routine_debug ! \.hl 3 >\
!++
! This macro defines ROUTINE_DEBUG as its argument. It should be
! called at the start of every routine. It should not be followed
! by a semi-colon.
!
! Arguments:
!--
( ! ; .s 1.list 1
routine_debug_flag ! \.le;\: True if debugging wanted
) = ! ; .end list
DIX$DEBUG (OWN routine_debug: INITIAL (routine_debug_flag);
BIND debug_flag = .DIX$GG_DEBUG AND .module_debug AND .routine_debug;
) %,
debug_code ! \.hl 3 >\
!++
! This macro expands to its arguments if dix$k_debug is set at
! compile time. It executes the code generated if debug_flag is
! set at run-time. Executable debugging code should be included
! within a call to debug-code.
!
! This macro expands to an expression that performs the indicated
! tasks. It may be used without bracketing in contexts where a
! single expression/statement is required. Where it is not being
! used as an expression, it should be followed by a semi-colon.
! This may result in null expressions when debugging is turned
! off at compiletime.
!--
[] = ! ; This is a conditional macro with no arguements.
dix$debug (IF debug_flag THEN BEGIN %REMAINING END) % ;
!++
! .HL 2 Terminal I/O macros
! These macros look and perform like the macros defined in TUTIO, but
! they function by calling external routines defined in DIXDEB. (The
! routines called perform their functions by calling TUTIO).
!
! The Terminal Output Macros are intended to make it easier to
! print on the terminal, especially during debugging.
!
! >TUTIO does various system-dependent things including searching
! libraries and defining globals. I'm having enough trouble balancing
! that sort of thing across systems that I don't need somebody else
! helping, so I isolated that stuff to DIXDEB. Note that DIXDEB must
! also search DIXLIB. To avoid having these definitions conflict with
! the definitions in TUTIO, I did some undeclaring in DIXDEB (q.v.).
!
! The macros defined here are:
!--
MACRO ! ;.s 1 .list 1, "o"
tty_put_quo (str_lit) = ! \.le;MACRO >\ Type quoted string literal.
typasz (UPLIT (%ASCIZ str_lit)) %,
tty_put_crlf (dummy) = ! \.le;MACRO >\ Type a cr/lf.
typnel () %,
tty_put_integer (int, rad, lng) = ! \.le;MACRO >\ Type value of integer.
typint (int, rad, lng) %,
tty_get_integer (rad) = ! \.le;MACRO >\ Get integer from terminal.
ttygin (rad) %;
MACRO
dtype (crlf) [] = ! \.le;MACRO >\Type if DEBUG_FLAG set.
!++
! If debug_code (defined above) is satisfied,
! this types a mixed bag of quoted string and integer
! items on the terminal (it uses the standard tty_put_quo and
! tty_put_integer macros to get to the terminal). The first actual
! controls whether a crlf is put out at the end of the line -- 1 means
! yes, 0 means no.
!
! To type a quoted string, simply place the string in the argument
! list. To type the value of an expression, put the expression in the
! argument list. The default radix is decimal, the default field
! width is 11. To override these, specify (exp, length, radix) (the
! parens are vital). The radix may be omitted to override just
! the length.
!
! Both this and TERMO (below) produce an expression. You supply your
! own semi-colon if that's what you want.
!--
debug_code (termo (crlf, %REMAINING))
% ,
termo (crlf) [] = ! \.le;MACRO >\Type mixed quoted strings and integers.
!++
! This is exactly like dtype above, except for the dependency on
! debugging flags.
!--
BEGIN ! This provides left context for iterative macro pr1
pr1 (%REMAINING) ;
%IF crlf %THEN
tty_put_crlf ()
%FI
END
% ,
pr1 [item] = ! \.le;MACRO >\Type n generic items.
!++
! Type out an arbitrary number of generic items (this is an iterative
! macro with no fixed parameters).
!--
pr2 (%REMOVE (item)) %, !
pr2 (item, length, base) = ! \.le;MACRO >\Type one generic item.
!++
! Type exactly one generic item. This is a simple macro except
! for the kludge to supply default values for missing arguments.
!
!.end list
!--
%IF %ISSTRING (item) %THEN
tty_put_quo (item)
%ELSE
tty_put_integer ((item),
(%IF %LENGTH GTR 2 %THEN ! Fudge a default value
base
%ELSE
10 ! Default base is 10
%FI)
,
(%IF %LENGTH GTR 1 %THEN ! Fudge a default value
length
%ELSE
11 ! Default length is 11
%FI)
)
%FI
%;
%SBTTL 'Misc declarations'
!++
! .HL 1 Miscellaneous declarations
! These assorted declarations go here so that they can be referred to
! later in the file. A few more miscellaneous declarations
! (system-dependent) are put in the require file >DIXREQ.REQ>. They
! are there only when BLISS or system restrictions force that for one
! system or another.
! .s1
!--
LITERAL
unit_offset_size = %BLISS16 (3) %BLISS32 (3) %BLISS36 (6); ! \ >\ This is the number of bits required
! ;to represent the maximum bit offset within an addressable unit on the
! ;current host system. It is used for optimizing structure declarations on
! ;each system.
!++
! Small-integer codes for the various types of systems which the DIX
! must know about:
! .list 0, " "
!--
$literal
sys_lcg = $distinct, ! \.le;>\ (36-bit addressable systems),
sys_8bit = $distinct, ! \.le;>\ (8-bit addressable systems),
sys_ult = $distinct; ! \.le;>\ (for hackery),
LITERAL
sys_max = sys_ult - 1; ! \.le;>\ (max sys code assigned).
! ;.end list
!++
! Define macro >readonly_psect which expands to the name of a
! write-protected psect on whatever system we are compiling on. This
! lets me put static data tables into the sharable part of the image
! in a manner that looks system-independent in the later code.
!--
MACRO
readonly_psect = %BLISS36 ($HIGH$) %BLISS32 ($PLIT$) % ;
!++
! Convenience names for booleans:
! .list 0, " "
!--
LITERAL
true = 1, false = 0, ! \.le;
on = 1, off = 0; ! \.le;
! ;.end list
%SBTTL 'Array structure'
!++
! .HL 1 Array structure
! The structure >ARRAY is defined as a two-dimensional array of
! fullwords with minimum and maximum subscript bounds for each dimension
! specified by the user. This was implemented for the table
! >gen_dispatch_tbl in module DIXGEN, which lets you look up a routine
! address given a source and destination data-type.
!--
STRUCTURE array [row, col; row_min, row_max, col_min, col_max] =
[(row_max - row_min + 1) * (col_max - col_min + 1) * %UPVAL]
(array + ((col - col_min) + (row - row_min) * (row_max - row_min + 1)) * %UPVAL);
%SBTTL 'Foreign Field Descriptor (FFD)'
!++
! .HL 1 The Foreign Field Descriptor (FFD)
!
! This structure is the descriptor used to describe a foreign field
! anywhere within the DIX package. The structure code is >FFD.
!
! A single occurrence of an FFD points to and identifies a (foreign
! or local) field somewhere in local memory. This is the structure
! used to identify a field to the conversion routines (below the user
! interface level).
!
! .index data type codes
! A data type code has two parts: a data class code, and a
! within-class type code. The classes are as described in the
! functional specification: string, fixed binary, floating point,
! boolean, complex, display-numeric, packed decimal, etc. The sizes
! of the fields are controlled by the following parameters:
!--
LITERAL
class_code_bits = 4, ! \.P;\Size of data class code
type_code_bits = 8; ! \.P;\Size of within-class type code
!++
! Here are the field definitions for the FFD:
! .s 1
! .literal
!--
!++ copy
$field
ffd_fields =
SET
ffd$v_unit = [$address], ! Address of lowest unit
! containing some bit of the
! field
ffd$v_length = [$bits (16)], ! Length of field in "natural"
! units (listed explicitly
! with data type definitions)
ffd$v_scale = [$short_integer], ! Scale factor for fixed-point
! decimal-based data types
ffd$v_offset = [$bits (unit_offset_size)], ! Bit offset within
! addressable unit to
! low-order bit of
! field
ffd$v_type = [$bits (class_code_bits + type_code_bits)],
! Data type code
$overlay (ffd$v_type) blf$comma
ffd$v_dt_type = [$bits (type_code_bits)], ! Type subfield
ffd$v_dt_class = [$bits (class_code_bits)], ! Class subfield
$continue
ffd$v_align = [$bits (6)], ! Bit offset within original
! system addressable unit to
! low-order bit of field
ffd$v_sys_orig = [$bits (2)] ! system of origin code
TES;
LITERAL
ffd$k_size = $field_set_size;
!-- .END LITERAL
!++
! To declare a data segment to be of type FFD, use the >forgn_descr
! macro in place of the structure and field attributes in the data
! declaration. It works with both immediate and REF structures.
!--
MACRO
forgn_descr =
BLOCK [ffd$k_size]
FIELD
(ffd_fields) %;
!++
! .hl 2 Data type codes
!
! Data type codes are sometimes accessed outside of an FFD. These
! definitions give you access to the fields from a fullword value.
!--
FIELD
dt_fields =
SET ! ;.list 0, "o"
dt_class_sep = ! \.le;>\Data class code only
[0, type_code_bits, %BPVAL - type_code_bits, 0],
! Make sure def looks at whole word,
! or garbage may sneak through
dt_code_sep = ! \.le;>\With-in class type code only
[0, 0, type_code_bits, 0]
TES; ! ;.end list
MACRO
data_type_sep = BLOCK [1] FIELD (dt_fields) % ;
%SBTTL 'DEC-10/20 standard calling sequence'
!++
! .hl 1 DEC-10/20 Standard Calling Sequence
!
! Define symbolic names for various fields used in processing
! routine calls made through the standard calling sequence on tens and
! twenties.
!--
!++
! First, entries in the standard calling sequence argument list have
! various fields within them:
! .list 1, "o"
!--
FIELD
scs_arg_fields =
SET
scs$v_type = [0, 23, 4, 0], ! \.le;\Type of argument
scs$v_adr = [0, 0, 23, 0] ! \.le;\Address of argument or descriptor
TES;
! ;.end list
!++
! To declare a data-segment to be of type scs_arg, use the macro
! >scs_arg in place of the structure and field attributes in the data
! declaration. This is useful for code which must see inside the
! structure of the standard calling sequence, such as routines that
! interpret descriptors.
!--
MACRO
scs_arg =
BLOCK [1]
FIELD
(scs_arg_fields) %;
!++
! The type code field in a data-segment of type scs_arg has the
! following possible meanings:
! .list 1, "o"
!--
LITERAL
!++ copy /strip .le;>
scs$k_unspecified = 0, ! [2] Unspecified type (assume its right)
scs$k_for36_bool = 1, ! FORTRAN-10/20 Boolean
scs$k_sbf36 = 2, ! DEC-10/20 one-word integer
scs$k_float36 = 4, ! DEC-10/20 one-word floating
scs$k_rtnadr = 7, ! The address of a routine
scs$k_float72 = %O'10', ! DEC-10/20 two-word floating (not G)
scs$k_sbf72 = %O'11', ! DEC-10/20 two-word integer
scs$k_fcmplx36 = %O'14', ! DEC-10/20 single-precision complex
scs$k_display = %O'15', ! 'address' points to descriptor
scs$k_asciz = %O'17'; ! DEC-10/20 ASCII string terminated by NUL
!-- .END LIST
!++
! And now, the fields of the full SCS descriptor. See the COBOL-74
! Language Reference Manual for the official definition of this
! descriptor:
!
! .s 1.literal
!--
!++ copy
FIELD
scs_descriptor_fields =
SET
scs$v_bytpntr = [0, 0, 36, 0],
scs$v_bytsiz = [0, 24, 6, 0],
scs$v_numflg = [1, 35, 1, 0],
scs$v_pscalflg = [1, 23, 1, 0],
scs$v_scalfac = [1, 18, 5, 1],
scs$v_lng = [1, 0, 18, 0]
TES;
!-- .end literal
!++
! To declare a data-segment as type SCS descriptor, use the
! >scs_descr macro in place of the structure and field attributes in
! the data declaration.
!--
MACRO
scs_descr =
BLOCK [2]
FIELD
(scs_descriptor_fields) %;
!++
! To get at unit-aligned data passed using the SCS without knowing its type,
! use argadr (.foo) instead of .foo and .(argadr (.foo)) instead of ..foo.
!
! The macro for BLISS32 is defined simply for compatibility.
! The BLISS36 variant does more -- it calls dix$$get_argadr, which returns
! the address of the unit in which the field starts, regardless of the type
! of the field. Remember, this works only for unit-aligned data.
!--
%BLISS36 (
MACRO
argadr (foo) = dix$$get_argadr (foo) % ;
)
%BLISS32 (
MACRO
argadr (foo) = foo % ; ! [3]
)
%SBTTL 'MACRO36 linkage declaration'
%IF %BLISS (BLISS36)
%THEN
!++
! .HL 1 MACRO36 linkage declaration
! .index macro36 linkage
! This linkage is particularly convenient for calling MACRO subroutines from
! BLISS36.
!
! The standard stack (17) and frame pointers (15) are used. Register
! 0 is the value return register. The first five parameters are
! passed in registers 1 through 5. Further parameters would be passed
! on the stack, in the "standard" way for PUSHJ linkage. If you have
! that many parameters to a MACRO subroutine, think about changing
! something.
!--
LINKAGE
macro36 = PUSHJ (REGISTER = 1, REGISTER = 2, REGISTER = 3, REGISTER = 4, REGISTER = 5) : !
LINKAGE_REGS (15, 13, 0) ! 17, 15, 0 in decimal
PRESERVE (6, 7, 8, 9, 10);
%FI
%sbttl 'Intermediate Forms'
!++
! .HL 1 Intermediate Forms
!--
!++
! .HL 2 CANONICAL BINARY (CB)
! .INDEX CANONICAL BINARY
! .index cb -- canonical binary
!
! The CB (canonical binary) format represents an arbitrary precision
! binary integer as a multi-digit number in some large base which fits
! comfortably into a BLISS fullword value on the system compiled for.
!--
LITERAL
cb$k_precision = 128, ! \.p;\Constant precision, in bits of
! ; twos-complement precision.
cb$k_base_bits = %BPVAL - 6, ! \.p;\Largest calculation that must
! ; be done on a CB segment is seg * 10 + carry, where carry is
! ; no larger than a segment in practical cases. Thus, this segment
! ; size lets the largest calculation done from segments fit in a
! ; fullword without using the sign bit.
cb$k_base = 1^cb$k_base_bits, ! ;.p;cb$k_base = 1`^cb$k_base_bits, The actual base.
cb$k_segments = cb$k_precision / cb$k_base_bits + 1; ! \.p;\Number of digits needed
! ; in selected base to represent the
! ; required precision.
%PRINT (cb$k_precision , '=', %NUMBER (cb$k_precision ))
%PRINT (cb$k_base_bits , '=', %NUMBER (cb$k_base_bits ))
%PRINT (cb$k_base , '=', %NUMBER (cb$k_base ))
%PRINT (cb$k_segments , '=', %NUMBER (cb$k_segments ))
$show (fields)
$field
cb_fields =
SET
cb$v_dig = [$bits (cb$k_base_bits)],
cb$v_oflo = [$bit],
$overlay (cb$v_dig)
cb$v_fill = [$bits (cb$k_base_bits - 1)],
cb$v_sign = [$bit],
$continue
$overlay (cb$v_dig)
cb$v_all = [$integer]
$continue
TES;
MACRO
cb = BLOCKVECTOR [cb$k_segments, 1] FIELD (cb_fields) % ;
!++
! .HL 2 Fixed Intermediate Form (XI)
! .INDEX FIXED INTERMEDIATE FORM
! .INDEX XI -- fixed intermediate form
! This is the internal intermediate form used for all decimal-based types.
! It will also be used for floating-binary to decimal based, when that is
! implemented.
! A number in fixed intermediate form consists of a signed binary scale
! factor, a sign, and an unsigned decimal integer. The actual value can be
! computed as (sign * integer * 10 ** scale).
! Parameters are as follows:
!--
LITERAL ! ;.s1 .list 0, "o"
xi$k_digits = 39, ! \.le;>\(number of digits to store)
xi$k_scale_bits = 16; ! \.le;>\(number of bits for scale factor)
! ;.end list
STRUCTURE
xi_structure ! \.hl 3 Structure >
!++
! This structure is used to represent a number in fixed intermediate form.
!
! Access formals:
!--
[ ! ; .s 1.list 1
type, ! \.le;\: 0 = scale, 1 = sign, 2 = digit
digit_number ! \.le;\: selects digit 0 thru max (max is xi$k_digits)
; ! ; .end list
! ; .P;Allocation formals:
! ; .s 1.list 1
digits, ! \.le;\: Number of digits of precision
scale_bits ! \.le;\: Number of bits for scale factor
] = ! ; .end list
! ; .P;Size of space to allocate (in addressable units):
[(scale_bits + 1) / %BPUNIT + SIGN ((scale_bits + 1) MOD %BPUNIT) +
! ; Scale + sign are in one set of units,
digits / (%BPUNIT / 4) + SIGN (digits MOD (%BPUNIT / 4))]
! ; the digits are in another.
! ; .P;Field reference actually made is complicated. Note that the whole
! ; mess is a compile-time constant expression if the actuals are (which they
! ; often will be, particularly the first one).
(xi_structure + (CASE type FROM 0 TO 2 OF
SET
[0]: 0; ! Scale
[1]: scale_bits / %BPUNIT; ! Sign
[2]: (scale_bits + 1) / %BPUNIT +
SIGN ((scale_bits + 1) MOD %BPUNIT) +
digit_number * 4 / %BPUNIT;
TES)
) <(CASE type FROM 0 TO 2 OF
SET
[0]: 0; ! Scale
[1]: scale_bits MOD %BPUNIT; ! Sign is past scale
[2]: (digit_number * 4) MOD %BPUNIT;
TES),
(CASE type FROM 0 TO 2 OF
SET
[0]: scale_bits; ! Scale
[1]: 1; ! Sign
[2]: 4; ! Digit
TES),
(CASE type FROM 0 TO 2 OF
SET
[0]: 1; ! Scale is signed
[1, 2]: 0; ! Others are unsigned
TES)
>;
FIELD
xi_fields = ! ;.hl 2 Field Set XI_fields
!++
! These fields allow the user to refer to the parts of an XI field
! conveniently.
!--
SET
xi$v_scale = [0, 0], ! \.p;>\Scale factor.
xi$v_sign = [1, 0], ! \.p;>\Sign.
xi$v_digit = [2] ! \.p;>\A digit. User supplies digit number following.
TES;
MACRO
xi = xi_structure [xi$k_digits, xi$k_scale_bits] FIELD (xi_fields) % ;
!++
! .hl 2 Canonical Floating point (CF)
! .index canonical floating point
! .entry cf -- canonical floating point
!
! The Canonical Floating point (CF) form represents a number as a sort of
! generic binary floating point. The relatively large mantissa is represented
! as a series of segments of some convenient size (i.e. a compile-time
! parameter).
!
! This form is used in internal processing of floating point numbers being
! converted. By converting all specific forms to this canonical form before
! processing, the need to implement all needed operations on all needed
! representations is avoided.
!
! A number in CF form consists of three pieces: A three-valued sign
! (positive, zero, and negative), a large binary mantissa, and a large
! signed (twos-complement) exponent.
!
! The exponent occupies a fullword. Each segment of the mantissa
! occupies a fullword. Thus, unfortunately, the sign occupies a
! fullword. There is no point in attempting to minimize space used,
! since only one of these things will be allocated at any given time
! anyway. Speed of access is much more important.
!
! The mantissa segment of index 0 is considered the highest order
! segment. Segments of increasing index contain bits of decreasing
! significance. This ordering, which the opposite of the way significance
! goes everywhere else, is used because the mantissa is normally processed from
! high order to low order, and in fact the uncertainty in its length
! is at the low order, not the high order, end.
!
! Parameters are as follows:
! .list 0, "o"
!--
LITERAL
! ;.no justify
cf$k_mantissa_bits = 113, ! \.le;\Minimum mantissa bits
cf$k_mantissa_seg_bits = %BPVAL - 2, ! \.le;\Segment size
cf$k_mantissa_segs = (cf$k_mantissa_bits - 1) / cf$k_mantissa_seg_bits + 1, ! \.le;\Number of segments
! ;.justify
! ;.end list
! ; Sign values are
! ;.list 0, "o"
cf$k_sign_pos = 1, ! \.le;\: positive,
cf$k_sign_zero = 2, ! \.le;\: zero,
cf$k_sign_neg = 3; ! \.le;\: negative.
! ;.end list
! ; The order of the sign values is important to the continued well-being
! ; of the code that uses them.
STRUCTURE
cf_structure ! \.hl 3 structure >
!++
! The cf_structure (canonical floating point structure) is used to
! represent a number in canonical binary form.
!
! Access formals:
!--
[ ! ; .s 1.list 1
type, ! \.le;\: 0 = sign, 1 = exponent, 2 = mantissa
seg_ndx ! \.le;\: Select segs 0 to max if type is mantissa.
; ! ; .end list
! ; Allocation formals:
! ;.s 1.list 1
segments ! \.le;\: Number of segments
] = ! ;.end list
! ; Size of space to allocate (in addressable units):
[(segments + 2) * %UPVAL] ! ; specified number of segments + 2.
! ; Field reference actually made is relatively complicated. Note that the
! ; first case, at least, is a compile-time constant. If all the actuals are
! ; compile-time constants, the result full reference is.
(cf_structure + ! unit address
( ! offset from structure start
CASE type FROM 0 TO 2 OF
SET
[0]: 0; ! Sign
[1]: 1 * %UPVAL; ! Exponent
[2]: (2 + seg_ndx) * %UPVAL;! Segment
TES) ! offset from structure start
) ! unit address
< ! Field reference
0, ! Bit offset
%BPVAL, ! Field width,
( ! Sign
CASE type FROM 0 TO 2 OF
SET
[0,2]: 0; ! Sign and segments are unsigned
[1]: 1; ! Exponent is signed
TES
) ! Sign
>; ! Field reference
FIELD
cf_fields = ! ;.hl 2 Field Set CF_fields
!++
! These fields allow the user to refer to the parts of a CF field
! conveniently.
!--
SET
cf$v_sign = [0,0], ! \.p;>\Sign.
cf$v_exponent = [1,0], ! \.p;>\Exponent.
cf$v_mantissa = [2] ! \.p;>\Mantissa segment. User
! ; supplies segment index following.
TES;
MACRO
cf = cf_structure [cf$k_mantissa_segs] FIELD (cf_fields) % ;
%SBTTL 'Condition handling and status values'
!++
! .hl 1 Condition handling and status values
! Define general condition handling and status value structures and literals.
! We use the VAX-based status-value (condition-value) concept
! described in the BLISS language manual chapter on condition handling.
! >STS is the standard naming-prefix for the status-code facility.
! Specific values for conditions are defined in another section.
!--
!++
! .hl 2 Facility Name
! The macro >DIX$facility_name expands to the facility prefix for the
! DIX. This is used within macros that construct names from their
! parameters.
!--
MACRO
DIX$facility_name =
'DIX' %;
LITERAL
!
! ;.hl 2 Facility code
!
dix$k_facility = 232; ! \.P;>\This is the formally registered
! ; DIX facility code (registered in
! ; VAX-land).
!++
! To declare a data segment to be of type condition_value, use the
! >condition_value macro instead of the structure and field attributes
! in the data declaration.
!--
MACRO
condition_value =
BLOCK [1]
! STARLET avoids the need to declare these fields, so we have to follow suit.
! FIELD
! (
! sts$v_severity,
! sts$v_success,
! sts$v_cond_id,
! sts$v_msg_no,
! sts$v_fac_sp,
! sts$v_code,
! sts$v_fac_no,
! sts$v_cust_def
! )
% ;
!++
! The keyword macro >sts$value generates a numeric condition value
! in the format suitable for the system on which it was compiled. The
! keywords and defaults are as follows:
! .list 0, "o"
!--
KEYWORDMACRO
sts$value (
!++ copy /strip .le;
severity = sts$k_severe,
CODE,
fac_sp = 1, ! Default is facility specific
fac_no = 0, ! Customer use desires this default
cust_def = 0 ! Default is Digital defined
!-- .end list
) =
(
position_field (sts$m_severity, severity) OR
position_field (sts$m_CODE, CODE) OR
position_field (sts$m_fac_sp, fac_sp) OR
position_field (sts$m_fac_no, fac_no) OR
position_field (sts$m_cust_def, cust_def)
)
%;
%SBTTL 'Define conditions used by the DIX'
!++
!
! .hl 1 Conditions used by the DIX
!
! All the conditions used by the DIX are defined here.
!
! Each definition results in a literal of the form DIX$_name whose
! value is the condition with the default severity. The message
! numbers are assigned sequentially using the compiletime variable
! >cnd_seq>.
!
! The macro >DIX$DEF_CONS is also defined. When expanded, it
! generates calls to a user-defined macro >COND_DAT, passing the
! full condition name as a string literal ('DIX$_name'), the
! FORTRAN pseudonym (6 chars) as a string literal, the
! condition value as a numeric literal, and the text of the standard
! message as a string literal.
!
! To make a list of condition names and messages, for example, you
! would do the following: Write a program that searched this library.
! Define COND_DAT to build the data structures you want containing
! selected condition information. Then call DIX$DEF_CONS. You now
! have your data structures containing everything you wanted to print.
! It should be a simple problem to print it out.
!--
COMPILETIME
cnd_seq = 0;
MACRO
! ; Macro information:
DIX$def_con (cond_nam, fort_pseud, default_severity, msg_txt) = ! \ .P;>\
%QUOTE %EXPAND %ASSIGN (cnd_seq, cnd_seq + 1) !
%QUOTE %EXPAND %PRINT !
( ! Begin %PRINT actuals
cond_nam, ! %PRINT actual
' code is ', ! %PRINT actual
%QUOTE %EXPAND %NUMBER (cnd_seq) ! %PRINT actual
) ! End %PRINT actuals
cond_dat !
( ! Begin cond_dat actuals
%QUOTE %EXPAND %NAME ! cond_dat actual
( ! Begin %NAME actuals
%QUOTE %EXPAND DIX$facility_name, ! %NAME actual
'$_', ! %NAME actual
cond_nam ! %NAME actual
), ! End %NAME actuals
fort_pseud, ! cond_dat actual
%QUOTE %EXPAND sts$value ! cond_dat actual
( ! Begin sts$value actuals
fac_no = DIX$k_facility, ! sts$value actual
CODE = %QUOTE %EXPAND %NUMBER(cnd_seq), ! sts$value actual
severity = (default_severity) ! sts$value actual
), ! End sts$value actuals
msg_txt ! cond_dat actual
) ! End cond_dat actuals
%, ! end DIX$def_con definition
!++
! .hl 2 >DIX$def_cons details
! Definitions of new conditions should be put into the macro definition
! in a manner consistent with the existing entries:
! .i 5;%EXPAND DIX$def_con ('name', 'fortpseud', default-severity, 'message text')
! In particular, note the absence of commas and semicolons at the end of
! the macro call to DIX$def_con.
! The "%EXPAND" is necessary to cause the generation of message
! codes to occur at library compile time. It is necessary that
! literal values be contained in the defined DIX$def_cons so that
! all calls to it are guaranteed of getting the same values.
!--
DIX$def_cons =
%EXPAND DIX$def_con('rounded', 'rnded', sts$k_info,
'Result is rounded')
%EXPAND DIX$def_con ('toobig', 'toobig', sts$k_severe,
'Converted source field too large for destination field')
%EXPAND DIX$def_con ('invdattyp', 'dattyp', sts$k_severe,
'Invalid data type code')
%EXPAND DIX$def_con ('unkargtyp', 'argtyp', sts$k_severe,
'Argument passed by descriptor is unknown type')
%EXPAND DIX$def_con ('unksys', 'unksys', sts$k_severe,
'Unknown system of origin specified')
%EXPAND DIX$def_con ('invlng', 'invlng', sts$k_severe,
'Length invalid or unspecified')
%EXPAND DIX$def_con ('invscal', 'invscl', sts$k_severe,
'Scale factor invalid or unspecified')
%EXPAND DIX$def_con ('graphic', 'graphc', sts$k_warning,
'Graphic character changed in conversion')
%EXPAND DIX$def_con ('fmtlost', 'fmtlst', sts$k_warning,
'Format effector gained or lost in conversion')
%EXPAND DIX$def_con ('nonprint', 'nonprn', sts$k_warning,
'Non-printing character gained or lost in conversion')
%EXPAND DIX$def_con ('trunc', 'trunc', sts$k_info,
'String too long for destination -- truncated')
%EXPAND DIX$def_con ('unimp', 'unimp', sts$k_severe,
'Unimplemented conversion')
%EXPAND DIX$def_con ('invalchar', 'invchr', sts$k_error,
'Invalid character in source field or conversion table')
%EXPAND DIX$def_con ('align', 'align', sts$k_severe,
'Invalid alignment for data type')
%EXPAND DIX$def_con ('unnorm', 'unnorm', sts$k_severe,
'Floating point number improperly normalized')
%EXPAND DIX$def_con ('impossible', 'imposs', sts$k_severe,
'Severe internal error') ! [%O'26']
%EXPAND DIX$def_con ('unsigned', 'unsign', sts$k_error,
'Negative value moved to unsigned field')
%EXPAND dix$def_con ('invbytsiz', 'bytsiz', sts$k_severe,
'Invalid byte size specified')
%EXPAND dix$def_con ('invdnumchr','dnmchr',sts$k_severe,
'Invalid source display numeric character')
%EXPAND dix$def_con ('invdnumsgn','dnmsgn',sts$k_severe,
'Invalid source display numeric sign character')
%EXPAND dix$def_con ('invpddgt', 'pddgt', sts$k_severe,
'Invalid source packed decimal digit')
%EXPAND dix$def_con ('invpdsgn', 'pdsgn', sts$k_severe,
'Invalid source packed decimal sign')
%, ! End DIX$def_cons definition
!++
! .hl 2 Literals for status codes
! Now that DIX$def_cons is defined, we can construct the
! literals for the status codes by creating a local definition of
! >cond_dat (which is undeclared after use) and expanding
! DIX$def_cons.
!
! [5] In BLISS32, the literals declared are external literal declarations.
! The actual message definitions come from the >DIX.MSG file, produced
! by the >dixmsg program from the other info in def_cons.
!--
cond_dat (cond_nam, fort_pseud, cond_value, cond_msg_txt) = ! \.P;>\
cond_nam %BLISS36 ( = cond_value) , %; ! [5]
%BLISS32 (EXTERNAL) LITERAL ! [5]
dix$def_cons ! Expand above cond_dat for each dix$def_con
! call above, thus defining literals for
! all conditions
dix$$foo %BLISS36 ( = 0) ; ! [5]
LITERAL ! [5]
max_condition = %NUMBER (cnd_seq);
UNDECLARE ! This stuff is too wierd for the public
cnd_seq,
dix$$foo, ! [5]
%QUOTE cond_dat,
%QUOTE dix$def_con;
%SBTTL 'Macros for data type declarations'
!++
! .hl 1 Macros for data type declaration
!
! All the information about each data type will be embedded in a macro
! declaration below.
!
! A macro called >dt_class_`<class name`>_def will be defined for each
! class which, when expanded, calls the locally-defined macro
! >decl_`<class name`>_item once for each data item in the class,
! passing all the information provided in the initial definition.
!
! This approach centralizes all the data type characteristics in a
! single place, making them easy to change and to find.
!
! There are some special macros used here to set up the macros
! described above. First, an example:
! .s 1
! .index declare_class
! .index dt_class
! .index dt_code
! .index data_type
! .index end_class
! .index dix$k_max_class
! .index dt_class_`<name`>_max
! .index dt_`<name`>
! .literal
! COMPILETIME
! dt_class = 0,
! dt_code = 0;
!
! declare_class (class_name);
! %EXPAND data_type (type_name, short_name);
! .
! .
! .
! %EXPAND end_class;
! declare_class (class_name);
! %EXPAND data_type (type_name, short_name);
! .
! .
! .
! %EXPAND end_class;
! .
! .
! .
!
! This produces the following literal declarations:
! DT_class Class number for each class
! DT_CLASS_class_MAX Max data type code assigned in that class
! (min is always 1)
! DIX$K_MAX_CLASS Highest class code assigned
!
! It also declares the macro DT_CLASS_class_DEF, described below.
!
! Then, when you want to build a table (or whatever) based on the
! information you gave for each data type:
!
! MACRO
! DECL_class_name_ITEM (class_code, item_name, short_name, type_code,
! user_specified ...) =
! Appropriate_code; %;
!
! DT_CLASS_class_name_DEF;
! .end literal
!--
MACRO
!++
! .hl 2 >declare_class macro
! Call the declare_class macro at the start of the list of
! items for each class:
!--
!++ NO
! ; The MACRO declare_class basically does the following:
! ; 1) Define the MACRO current_class (which is undeclared
! ; in the MACRO end_class.
! ; 2) %ASSIGN dt_code = 0.
! ; 3) %ASSIGN dt_class = dt_class + 1.
! ; 4) Define the LITERAL dt_<class_name> = dt_class.
! ; 5) Define the MACRO dt_class_<class_name>_def. This is a little
! ; unusual because the definition is left open-ended. The MACRO
! ; declare_class is defined such that it expands to the following
! ; definition of dt_class_<class_name>_def ==>
! ;
! ; MACRO %NAME ('dt_class', class_name, '_def') =
! ; %, ! End declare_class
! ; This means that when declare_class is invoked, the call must be
! ; followed by the code that the user wishes to be the body of the
! ; MACRO dt_class_<class_name>_def.
! ;
!--
declare_class (class_name) = ! \ .p;>\
MACRO
current_class =
class_name %QUOTE %;
%ASSIGN (dt_code, 0) ! Initialize type code
%ASSIGN (dt_class, dt_class + 1)
LITERAL
%NAME ('dt_', class_name) = %NUMBER (dt_class);
!
! ; At compile time, prints the number assigned to this class.
!
%PRINT (%NAME ('dt_', class_name), '=', %NUMBER (%NAME ('dt_', class_name)))
! Define the name of the MACRO whose body directly follows the call
! to declare_class (class_name). The name is built using the parameter
! "class_name" and is the following: dt_class_<class_name>_def.
! NOTE: The body of this MACRO does not appear here, but rather
! appears in the code directly after the call to declare_class.
MACRO
%NAME ('dt_class_', class_name, '_def') =
%, ! End declare_class
!++
! .hl 2 >data_type
! The data_type macro is used to declare a specific data type
! within a class declaration. It assigns the within-class type
! code from compiletime variable >dt_code>, which is incremented.
!--
data_type (item_name, short_name) = ! \.P;>\
%QUOTE %EXPAND %ASSIGN (dt_code, dt_code + 1)
!++
! Expansion calls macro >decl_`<class name`>_item (which the user
! must define) to do whatever is wanted for each item in the class.
!--
%QUOTE %EXPAND %NAME ('decl_', current_class, '_item') ! Name of macro to invoke
( ! MACRO-actuals enclosed
%QUOTE %EXPAND %NAME ('dt_', current_class), ! MACRO actual
item_name, ! Macro actual
short_name, ! Macro actual
%QUOTE %EXPAND %NUMBER(dt_code), ! Macro actual
%QUOTE %EXPAND %REMAINING ! Macro actual
) ! End of MACRO-actuals
!
! ; At compile-time, data_type prints the within-class code assigned
! ; to each data type.
!
%QUOTE %EXPAND %PRINT !
( ! %PRINT actuals enclosed
item_name, ! %PRINT actual
' type code=', ! %PRINT actual
%QUOTE %EXPAND %NUMBER(dt_code) ! %PRINT actual
) ! End %PRINT actuals
%, ! End data_type definition
!++
! .hl 2 >end_class
! The macro end_class handles termination of the declarations for a
! class of data items.
!--
end_class =
%QUOTE %;
LITERAL ! ; The literal >dt_class_`<name`>_max> is
! ; defined as the maximum code in the class.
%QUOTE %EXPAND %NAME
( ! %NAME actuals enclosed
'dt_class_', ! %NAME actual
current_class, ! %NAME actual
'_max' ! %NAME actual
) ! End %NAME actuals
= !
%QUOTE %EXPAND %NUMBER (dt_code);
!
! ; At compile-time, print the max code in the class from the
! ; literal just defined.
!
%QUOTE %EXPAND %PRINT ( ! Begin actuals to %PRINT
%QUOTE %EXPAND %NAME ! Actual to %PRINT
( ! Begin actuals to %NAME
'dt_class_', ! Actual to %NAME
current_class, ! Actual to %NAME
'_max' ! Actual to %NAME
), ! End actuals to %NAME
'=', ! Actual to %PRINT
%QUOTE %EXPAND %NUMBER ! Actual to %PRINT
( ! Begin actuals to %NUMBER
%QUOTE %EXPAND %NAME ! Actual to %NUMBER
( ! Begin actuals to %NAME
'dt_class_', ! Actual to %NAME
current_class, ! Actual to %NAME
'_max' ! Actual to %NAME
) ! End of actuals to %NAME
) ! End of actuals to %NUMBER
) ! End of actuals to %PRINT
UNDECLARE ! Get rid of one-shot variables
%QUOTE %QUOTE current_class;
%; ! End definition of end_class
%SBTTL 'Data type definitions'
!++
! .hl 1 Data type definitions
!
! The characteristics of all data types in all classes will be defined
! here.
!
! The resulting information will be stored mostly as macro
! definitions (described above) and will be expanded into tables as
! necessary in the general and type-specific conversion modules.
!--
COMPILETIME
dt_class = 0,
dt_code = 0;
%sbttl 'Class String data type definitions'
!++
! .hl 2 Class string
! .index class string
!
! Information to be provided for each data type:
! .list 1, "o"
! .le;Name as quoted string
! .le;Short name as quoted string
! .le;Byte size
! .le;System of origin
! .le;Length indicating technique (value indicating whether a length must
! be given or if a null length is expected)
! .le;Name of character set as quoted string. Since the build_cst macro
! (defined and used in DIXSTR) names everything consistently based on
! the character set name, this is all that is needed to find everything.
! .le;Fill character to use (numeric)
! .le;Character to substitute if no matching char in set (numeric)
! .end list
!--
!
! ; Names for methods of indicating length:
! ;.list 0, "o"
$literal
std$k_lng_spec = $distinct, ! \.le;>\
std$k_lng_nul = $distinct, ! \.le;>\
std$k_lng_ult = $distinct; ! \.le;>\
LITERAL
std$k_max_lng_indic = %NUMBER (std$k_lng_ult) - 1 ; !\.le;>\
! ;.end list
UNDECLARE std$k_lng_ult;
declare_class ('string') ! call declare_class
!
! The code following the call to declare_class is actually the body of the
! MACRO dt_class_string_def.
!
%EXPAND
data_type ('ASCII_7', 'ASCII7', 7, sys_lcg, std$k_lng_spec, 'ascii', 32, 92)
%EXPAND
data_type ('ASCII_8', 'ASCII8', 8, sys_8bit, std$k_lng_spec, 'ascii', 32, 92)
%EXPAND
data_type ('ASCIZ', 'ASCIZ', 7, sys_lcg, std$k_lng_nul, 'ascii', 0, 92)
%EXPAND
data_type ('EBCDIC_8', 'EBCDC8', 8, sys_8bit, std$k_lng_spec, 'ebcdic', 64, 224)
%EXPAND
data_type ('EBCDIC_9', 'EBCDC9', 9, sys_lcg, std$k_lng_spec, 'ebcdic', 64, 224)
%EXPAND
data_type ('SIXBIT', 'SIXBIT', 6, sys_lcg, std$k_lng_spec, 'sixbit', 0, 60)
!
%EXPAND
end_class
%SBTTL 'String data table (STD)'
!++
! .hl 3 String data table (>std>)
! Format for the alphanumeric string data table.
! This table is indexed by data subtype (within its class).
! .literal
!--
$field
std_fields =
SET
!++ copy
std$v_byt_siz = [$bits (6)], ! Byte size of string
std$v_sys_orig = [$bits (3)], ! Code for system of origin
std$v_lng_indic = [$bits (2)] ! Length indication
! (values std$k_lng_<something> defined above)
!-- .end literal
TES;
LITERAL
std$k_size = $field_set_size;
!++
! To declare a data segment to be of type std, use the macro dtt_st
! in place of the structure and field attributes in the data item
! declaration.
!--
MACRO
dtt_st = BLOCKVECTOR [dt_class_string_max + 1, std$k_size] FIELD (std_fields) % ;
%sbttl 'Class fixed binary data type definitions'
!++
! .hl 2 Class fixed binary
!
! Information to be provided for each data type:
!
! .list 1
! .le;Name as quoted string
! .le;Short name as quoted string
! .le;Fixed or variable length (use literals)
! .le;Signed or unsigned (use literals)
! .le;Minimum length if variable (unsigned) (zero if not variable)
! .le;Maximum length if variable (unsigned)
! .le;Minimum scale factor (signed)
! .le;Maximum scale factor (signed)
! .le;Program for BPM/BIM
! .end list
!--
!++
! Literals for specifying above parameters:
! .list 0, "o"
!--
LITERAL
fbd$k_lng_fixed = 1, ! \.le;\ Type is fixed-length
fbd$k_lng_variable = 2, ! \.le;\ Type is variable-length
fbd$k_signed = 3, ! \.le;\ Type is signed
fbd$k_unsigned = 4; ! \.le;\ Type is unsigned
! ; .end list
!++
! .hl 3 Binary pseudo-machine (BPM)
! .index pseudo-machine BPM
! .index binary pseudo-machine BPM
! .index bpm
! Define the pseudo-machine to run (in different directions) in the
! routines that convert FB to CB and vs.
!
! Each pseudo-instruction has an op code and two signed integer (small)
! operands. The structure to represent a single instruction is defined as a
! block with the following fields:
!--
$field ! ; .s 1.list 0, "o"
bpm_fields =
SET
!++ copy /strip .le;>
bpm$v_opcode = [$byte], ! Op code is this size for VAX alignment
bpm$v_op_1 = [$tiny_integer], ! Must be signed, at least +/- 128
bpm$v_op_2 = [$tiny_integer] ! Must be signed, at least +/- 128
!-- .end list
TES;
LITERAL
bpm$k_size = $field_set_size,
bpm$b_opcode = 0, ! OFFSET
bpm$s_opcode = %BLISS36 (9) %BLISS32 (8), ! Size of field
bpm$b_op_1 = %BLISS36 (9) %BLISS32 (8), ! These fields depend on the
bpm$s_op_1 = %BLISS36 (9) %BLISS32 (8), ! way XPORT processes the
bpm$b_op_2 = %BLISS36 (18) %BLISS32 (16), ! definitions above!!!
bpm$s_op_2 = %BLISS36 (9) %BLISS32 (8); ! Watch out!!!
!++
! The op-codes for the pseudo-machine are as follows:
!--
$literal ! ; .s 1.list 1
!++ copy /strip .le;>
bpm$k_op_move = $distinct, ! Move contiguous bits
bpm$k_op_move_var = $distinct, ! Move contiguous bits with variable length
bpm$k_op_sign = $distinct, ! Process sign
bpm$k_op_sign_var = $distinct, ! Process sign in variable length
bpm$k_op_done = $distinct; ! Do cleanup and terminate.
!--
! ; Must be last in list!!
! ; .END LIST
LITERAL
bpm$k_op_max = bpm$k_op_done - 1; ! \.p;Largest bpm opcode is \
!++
! .hl 3 Building BPM instructions
! Macros to build pseudo-machine instructions:
!--
MACRO
bpm_any ! \.hl 4 \
!++
! builds any pseudo-machine instruction.
!
! Formal arguments:
!--
( ! ; .list 1
op_code, ! \.le;\: opcode for instruction
op_1, ! \.le;\: signed value for first op
op_2 ! \.le;\: signed value for second op
) = ! ; .end list
op_code OR
(op_1 AND (1^bpm$s_op_1 - 1))^bpm$b_op_1 OR
(op_2 AND (1^bpm$s_op_2 - 1))^bpm$b_op_2 %,
bpm_move ! \.hl 4\
!++
! builds the pseudo-machine instruction to move continuous bits
! between FB and CB fields.
!
! Formal arguments:
!--
( ! ; .list 1
Offset, ! \.le;\: from LO bit of FB
length ! \.le;\: number of bits to move
) = ! ; .end list
bpm_any (bpm$k_op_move, offset, length) %,
bpm_move_var ! \.hl 4\
!++
! builds the pseudo-machine instruction to move continuous bits
! between FB and CB variable length fields.
!
! Formal arguments:
!--
( ! ; .list 1
Offset, ! \.le;\: from LO bit of FB
length ! \.le;\: number of bits to move - length
) = ! ; .end list
bpm_any (bpm$k_op_move_var, offset, length) %,
bpm_sign ! \.hl 4\
!++
! builds the pseudo-machine instruction to move sign information
! between FB and CB fields.
!
! Formal arguments:
!--
( ! ; .list 1
Offset ! \.le;\: from LO bit of FB
) = ! ; .end list
bpm_any (bpm$k_op_sign, offset, 0) %,
bpm_sign_var ! \.hl 4\
!++
! builds the pseudo-machine instruction to move sign information
! between FB and CB variable length fields.
!
! Formal arguments:
!--
( ! ; .list 1
Offset ! \.le;\: from LO bit of FB - length
) = ! ; .end list
bpm_any (bpm$k_op_sign_var, offset, 0) %,
bpm_done ! \.hl 4\
!++
! builds the pseudo-machine instruction to terminate a pseudo-program.
!
! Formal arguments: none.
!--
=
bpm_any (bpm$k_op_done, 0, 0) % ;
!
! And now, the real class fixed binary definitions in terms of this glop.
!
declare_class ('fbin') ! call declare_class
!
! The code following the call to declare_class is actually the body of the
! MACRO dt_class_fbin_def.
!
%EXPAND data_type ('SBF128', 'SBF128', fbd$k_lng_fixed, fbd$k_signed,0,0,0,0,
(bpm_move (0, 127), bpm_sign (127), bpm_done))
%EXPAND data_type ('SBF16', 'SBF16', fbd$k_lng_fixed, fbd$k_signed,0,0,-18,18,
(bpm_move (0, 15), bpm_sign (15), bpm_done))
%EXPAND data_type ('SBF32', 'SBF32', fbd$k_lng_fixed, fbd$k_signed,0,0,-18,18,
(bpm_move (0, 31), bpm_sign (31), bpm_done))
%EXPAND data_type ('SBF36', 'SBF36', fbd$k_lng_fixed, fbd$k_signed,0,0,-18,18,
(bpm_move (0, 35), bpm_sign (35), bpm_done))
%EXPAND data_type ('SBF48', 'SBF48', fbd$k_lng_fixed, fbd$k_signed,0,0,0,0,
(bpm_move (0, 47), bpm_sign (47), bpm_done))
%EXPAND data_type ('SBF64', 'SBF64', fbd$k_lng_fixed, fbd$k_signed,0,0,-18,18,
(bpm_move (0, 63), bpm_sign (63), bpm_done))
%EXPAND data_type ('SBF72', 'SBF72', fbd$k_lng_fixed, fbd$k_signed,0,0,-18,18,
(bpm_move (0, 35), bpm_move (-36, 35), bpm_sign (-1), bpm_done))
%EXPAND data_type ('SBF8', 'SBF8', fbd$k_lng_fixed, fbd$k_signed,0,0,0,0,
(bpm_move (0, 7), bpm_sign (7), bpm_done))
%EXPAND data_type ('SBFVAR', 'SBFVAR', fbd$k_lng_variable, fbd$k_signed,0,36,0,0,
(bpm_move_var (0, -1), bpm_sign_var (-1), bpm_done))
%EXPAND data_type ('UBF16', 'UBF16', fbd$k_lng_fixed, fbd$k_unsigned,0,0,0,0,
(bpm_move (0, 16), bpm_done))
%EXPAND data_type ('UBF32', 'UBF32', fbd$k_lng_fixed, fbd$k_unsigned,0,0,0,0,
(bpm_move (0, 32), bpm_done))
%EXPAND data_type ('UBF8', 'UBF8', fbd$k_lng_fixed, fbd$k_unsigned,0,0,0,0,
(bpm_move (0, 8), bpm_done))
%EXPAND data_type ('UBFVAR', 'UBFVAR', fbd$k_lng_variable, fbd$k_unsigned,0,36,0,0,
(bpm_move_var (0, 0), bpm_done))
%EXPAND end_class
%sbttl 'Fixed Binary data table (FBD)'
!++
! .hl 3 Fixed binary data table (>fbd>)
! Format for the fixed binary data table. This table is indexed by
! data subtype (within class).
! .s 1
! .literal
!--
$field
fbd_fields =
SET
!++ copy
fbd$v_bpm_program = [$address], ! Address of BPM program
! These two bits occupy HO part of word on 36-bit
fbd$v_signed = [$bit], ! Bit set if field is signed
fbd$v_variable = [$bit], ! Bit set if field length variable
$align (byte) ! Align remaining fields
fbd$v_min_lng = [$byte], ! Minimum length (unsigned field)
fbd$v_max_lng = [$byte], ! Maximum length (unsigned)
fbd$v_min_scale = [$tiny_integer], ! Signed minimum scale
fbd$v_max_scale = [$tiny_integer] ! Signed maximum scale
!-- .end literal
TES;
LITERAL
fbd$k_size = $field_set_size;
MACRO
dtt_fbin ! \.p;Macro >\
!++
! declares an item to have the right structure and field attributes for
! the fixed binary data table.
!--
= BLOCKVECTOR [dt_class_fbin_max + 1, fbd$k_size] FIELD (fbd_fields) % ;
%SBTTL 'Class floating point data type definitions'
!++
! .hl 2 Class floating point
!
! Information to be provided for each data type:
!
! .list 1
! .le;Name as quoted string
! .le;Short name as quoted string
! .le;Representation (use literals)
! .le;Exponent offset
! .le;Number of significant bits in mantissa (including hidden high-order
! bit if there is one)
! .le;Program for FPM/FIM
! .end list
!
! Literals for specifying above:
! .list 0, "o"
!--
$literal
!++ copy /strip .le;
fpd$k_lcg = $distinct, ! Number is in LCG representation
fpd$k_vax = $distinct, ! Number is in VAX/PDP-11 representation
fpd$k_rep_ult = $distinct;
!-- .end list
LITERAL
fpd$k_rep_max = fpd$k_rep_ult - 1; ! \.p;Max representation value is \
UNDECLARE
fpd$k_rep_ult;
!++
! .hl 3 Floating point pseudo-machine FPM
! .index pseudo-machine FPM
! .index floating point pseudo-machine FPM
! .index fpm
!
! Define the pseudo-machine used to convert fp to cf and vs (the programs
! are also run to convert cf to fp; of course the interpretation
! of the instructions changes).
!
! Each instruction has an op code and two signed small integer operands.
! The structure to represent a single instruction is defined as a block with
! the following fields:
!--
$field
fpm_fields = ! ; .s 1 .list 0, "o"
SET
!++ copy /strip .le;>
fpm$v_opcode = [$byte], ! Op code is large for alignment on vax
fpm$v_op_1 = [$tiny_integer], ! Must be signed, +/- 128
fpm$v_op_2 = [$tiny_integer] ! Must be signed, +/- 128
!-- .end list
TES;
LITERAL
fpm$k_size = $field_set_size,
!++
! Create names for bit positions of above fields. These definitions depend
! on how XPORT process the above stuff, so be extremely careful whem
! mucking about with either one!!!
!--
!++ copy /strip .i 5;
fpm$b_opcode = 0, ! Offset
fpm$s_opcode = %BLISS36 (9) %BLISS32 (8), ! Size of field
fpm$b_op_1 = %BLISS36 (9) %BLISS32 (8),
fpm$s_op_1 = %BLISS36 (9) %BLISS32 (8),
fpm$b_op_2 = %BLISS36 (18) %BLISS32 (16),
fpm$s_op_2 = %BLISS36 (9) %BLISS32 (8);
!--
!++
! Op-codes for the FPM:
!--
$literal ! ;.list 1
!++ copy /strip .le;>
fpm$k_op_sign = $distinct, ! Set sign to pos or neg
fpm$k_op_exp = $distinct, ! Move exponent bits
fpm$k_op_mant = $distinct, ! Move mantissa bits
fpm$k_op_mant1 = $distinct, ! Create hidden leading mantissa bit
fpm$k_op_done = $distinct; ! Do cleanup and terminate.
!--
! ; "done" must be last!!!
! ; .end list
!++
! .hl 3 Building FPM instructions
! Macros to build pseudo-machine instructions:
!--
MACRO
fpm_any ! \.hl 4 \
!++
! builds any pseudo-machine instruction.
!
! Formal arguments:
!--
( ! ; .list 1
op_code, ! \.le;\: opcode for instruction
op_1, ! \.le;\: signed value for first op
op_2 ! \.le;\: signed value for second op
) = ! ; .end list
op_code OR
(op_1 AND (1^fpm$s_op_1 - 1))^fpm$b_op_1 OR
(op_2 AND (1^fpm$s_op_2 - 1))^fpm$b_op_2 %,
fpm_sign ! \.hl 4\
!++
! builds the pseudo-machine instruction to set the CF sign to positive or
! negative (zero is handled in the done routine).
!
! Formal arguments:
!--
( ! ;.s 1.list 1
offset ! \.le;\: Offset from low order bit of FP
) = ! ;.end list
fpm_any (fpm$k_op_sign, offset, 0) % ,
fpm_exp ! \.hl 4\
!++
! builds the pseudo-machine instruction to move exponent bits.
! Exponent bits are moved from low order to high order. No sign
! extension is done -- this must be handled by the done routine.
! This instruction may only be called once -- segmented exponents
! are not supported. Exponents larger than a fullword are not
! supported.
!
! Formal arguments:
!--
( ! ;.s 1.list 1
offset, ! \.le;\: Offset from low order bit of FP
length ! \.le;\: Number of bits to move
) = ! ;.end list
fpm_any (fpm$k_op_exp, offset, length) % ,
fpm_mant ! \.hl 4\
!++
! builds the psedo-machine instruction to move mantissa bits.
!
! Mantissa bits are moved from high order to low order. Therefore
! the offset specified is to the highest-order bit to be moved.
!
! This instruction may be used several times to move non-contiguous
! mantissa fields.
!
! Formal arguments:
!--
( ! ;.s 1.list 1
offset, ! \.le;\: Offset from LO bit of FP
! ; to HO bit to move.
length ! \.le;\: Number of bits to move
! ; (lower-order bits).
) = ! ;.end list
fpm_any (fpm$k_op_mant, offset, length) % ,
fpm_mant1 ! \.hl 4\
!++
! builds the instruction for creating the leading mantissa bit, which is
! not represented in some implementations.
!
! Formal arguments: None
!--
=
fpm_any (fpm$k_op_mant1, 0, 0) % ,
fpm_done ! \.hl 4\
!++
! builds the done instruction. This terminates processing of the
! pseudo-program and executes the final cleanup routine.
!
! The final cleanup routine transforms the broken-down bit fields made
! by the simple moves of the other instructions into the true canonical
! form.
!
! Formal arguments: None.
!--
=
fpm_any (fpm$k_op_done, 0, 0) % ;
!
! And now, the real class floating point definitions in terms of this glop.
!
declare_class ('fp') ! call declare_class
!
! The code following the call to declare_class is actually the body of the
! MACRO dt_class_fp_def.
!
%EXPAND data_type ('D_FLOAT', 'DFLOAT', fpd$k_vax, 128, 56,
(fpm_sign (15), fpm_exp (7, 8), fpm_mant1, fpm_mant (6, 7),
fpm_mant (31, 16), fpm_mant (47, 16), fpm_mant (63, 16), fpm_done ))
%EXPAND data_type ('F_FLOAT', 'FFLOAT', fpd$k_vax, 128, 24,
(fpm_sign (15), fpm_exp (7, 8), fpm_mant1, fpm_mant (6, 7),
fpm_mant (31, 16), fpm_done ))
%EXPAND data_type ('FLOAT_36', 'FLOT36', fpd$k_lcg, 128, 27,
(fpm_sign (35), fpm_exp (27, 8), fpm_mant (26, 27), fpm_done ))
%EXPAND data_type ('FLOAT_72', 'FLOT72', fpd$k_lcg, 128, 62,
(fpm_sign (-1), fpm_exp (-9, 8), fpm_mant (-10, 27), fpm_mant (34, 35),
fpm_done ))
%EXPAND data_type ('G_FLOAT', 'GFLOAT', fpd$k_vax, 1024, 53,
(fpm_sign (15), fpm_exp (4, 11), fpm_mant1, fpm_mant (3, 4),
fpm_mant (31, 16), fpm_mant (47, 16), fpm_mant (63, 16), fpm_done ))
%EXPAND data_type ('G_FLOAT72', 'GFLO72', fpd$k_lcg, 1024, 59,
(fpm_sign (-1), fpm_exp (-12, 11), fpm_mant (-13, 24), fpm_mant (34, 35),
fpm_done ))
%EXPAND data_type ('H_FLOAT', 'HFLOAT', fpd$k_vax, 16384, 113,
(fpm_sign (15), fpm_exp (0, 15), fpm_mant1, fpm_mant (31, 16),
fpm_mant (47, 16), fpm_mant (63, 16), fpm_mant (79, 16),
fpm_mant (95, 16), fpm_mant (111, 16), fpm_mant (127, 16), fpm_done ))
%EXPAND end_class
%SBTTL 'Floating point data table'
!++
! .hl 3 Floating point data table (>fpd>)
! Format for the floating point data table. This table is indexed
! by the data subtype (within its class).
! .literal
!--
$field
fpd_fields =
SET
!++ COPY
fpd$v_fpm_program = [$address], ! Address of FPM program for type
fpd$v_representation = [$byte], ! Encodes details of representation
! within the 3 standard fields
fpd$v_exp_offset = [$bytes (2)], ! Unsigned offset to apply to exponent
fpd$v_mant_bits = [$byte] ! Unsigned number of significant bits in mantissa
!-- .END LITERAL
TES;
LITERAL
fpd$k_size = $field_set_size;
MACRO
dtt_fp ! \.p;Macro >\
!++
! declares an item to have the right structure and field attributes for
! the floating point data table.
!--
= BLOCKVECTOR [dt_class_fp_max + 1, fpd$k_size] FIELD (fpd_fields) % ;
%SBTTL 'Class Display Numeric data type definitions'
!++
! .hl 2 Class Display Numeric
! .index class display numeric
!
! Information to be provided for each data type:
! .list 1, "o"
! .le;Name as quoted string
! .le;Short name as quoted string
! .le;Byte size
! .le;System of origin
! .le;code indicating sign type (use literals provided below)
! .le;Maximum length allowed
! .le;Character set used
! .le;Size of character set
! .end list
!--
! ; Literal names used to indicate different sign representations:
! ;.s1.list 0, "o"
LITERAL
dnd$k_unsigned = 0, ! \.le;>\ unsigned
dnd$k_lead_sep = 1, ! \.le;>\ signed/leading/separate
dnd$k_lead_over = 2, ! \.le;>\ signed/leading/overpunched
dnd$k_trail_sep = 3, ! \.le;>\ signed/trailing/separate
dnd$k_trail_over = 4; ! \.le;>\ signed/trailing/overpunched
! ;.end list
! ; Literals for display numeric character set reference codes:
LITERAL ! ;.s 1 .list 0, "o"
cs_ascii = 0, ! \.le;\ ascii char set
cs_asciix = 1, ! \.le;\ ascii extended char set
cs_ebcdic = 2, ! \.le;\ ebcdic char set
cs_sixbit = 3, ! \.le;\ sixbit char set
cs_max = 4; ! ;.end list
! ; Literals for display numeric character set sizes:
LITERAL ! ;.s 1 .list 0, "o"
ovp$k_ascii_max = 10, ! \.le;\size of ascii dn character set
ovp$k_asciix_max = 35, ! \.le;\size of ascii dn extended char set
ovp$k_ebcdic_max = 10, ! \.le;\size of ebcdic dn character set
ovp$k_sixbit_max = 10; ! \.le;\size of sixbit dn character set
! ;.end list
declare_class ('dnum') ! call declare_class
!
! The code following the call to declare_class is actually the body of the
! MACRO dt_class_dnum_def.
!
%EXPAND
data_type ('DN6LO', 'DN6LO', 6, sys_lcg, dnd$k_lead_over, 'sixbit', 18)
%EXPAND
data_type ('DN6LS', 'DN6LS', 6, sys_lcg, dnd$k_lead_sep, 'sixbit', 19)
%EXPAND
data_type ('DN6TO', 'DN6TO', 6, sys_lcg, dnd$k_trail_over, 'sixbit', 18)
%EXPAND
data_type ('DN6TS', 'DN6TS', 6, sys_lcg, dnd$k_trail_sep, 'sixbit', 19)
%EXPAND
data_type ('DN6U', 'DN6U', 6, sys_lcg, dnd$k_unsigned, 'sixbit', 18)
%EXPAND
data_type ('DN7LO', 'DN7LO', 7, sys_lcg, dnd$k_lead_over, 'ascii', 18)
%EXPAND
data_type ('DN7LS', 'DN7LS', 7, sys_lcg, dnd$k_lead_sep, 'ascii', 19)
%EXPAND
data_type ('DN7TO', 'DN7TO', 7, sys_lcg, dnd$k_trail_over, 'ascii', 18)
%EXPAND
data_type ('DN7TS', 'DN7TS', 7, sys_lcg, dnd$k_trail_sep, 'ascii', 19)
%EXPAND
data_type ('DN7U', 'DN7U', 7, sys_lcg, dnd$k_unsigned, 'ascii', 18)
%EXPAND
data_type ('DN8LO', 'DN8LO', 8, sys_8bit, dnd$k_lead_over, 'ascii', 31)
%EXPAND
data_type ('DN8LS', 'DN8LS', 8, sys_8bit, dnd$k_lead_sep, 'ascii', 32)
%EXPAND
data_type ('DN8TO', 'DN8TO', 8, sys_8bit, dnd$k_trail_over, 'asciix',31)
%EXPAND
data_type ('DN8TS', 'DN8TS', 8, sys_8bit, dnd$k_trail_sep, 'ascii', 32)
%EXPAND
data_type ('DN8U', 'DN8U', 8, sys_8bit, dnd$k_unsigned, 'ascii', 31)
%EXPAND
data_type ('DN9LO', 'DN9LO', 9, sys_lcg, dnd$k_lead_over, 'ebcdic', 18)
%EXPAND
data_type ('DN9LS', 'DN9LS', 9, sys_lcg, dnd$k_lead_sep, 'ebcdic', 19)
%EXPAND
data_type ('DN9TO', 'DN9TO', 9, sys_lcg, dnd$k_trail_over, 'ebcdic', 18)
%EXPAND
data_type ('DN9TS', 'DN9TS', 9, sys_lcg, dnd$k_trail_sep, 'ebcdic', 19)
%EXPAND
data_type ('DN9U', 'DN9U', 9, sys_lcg, dnd$k_unsigned, 'ebcdic', 18)
%EXPAND
end_class ! call MACRO end_class
%SBTTL 'Display Numeric date table (DND)'
!++
! .hl 3 Display Numeric data table (>dnd>)
! The format for the display numeric data table is below. This
! table is indexed by the data subtype (within its class).
!
! .literal
!--
$field
dnd_fields =
SET
!++ copy
dnd$v_byt_siz = [$bits(6)], ! byte size
dnd$v_sys_orig = [$bits(3)], ! system of origin
dnd$v_sign_type = [$bits(3)], ! sign type indicator
dnd$v_ovp_max_index = [$byte], ! maximum index of OVP
dnd$v_max_length = [$bits(6)], ! maximum field length
dnd$v_char_set = [$bits(3)] ! character set code
!-- .end literal
TES;
LITERAL dnd$k_size = $field_set_size;
MACRO
dtt_dn ! \.p;Macro >\
!++
! declares an item to have the right structure and field attributes for the
! display numeric data table.
!--
= BLOCKVECTOR [dt_class_dnum_max + 1, dnd$k_size]
FIELD (dnd_fields) % ;
%SBTTL 'Class Packed Decimal data type definitions'
!++
! .hl 2 Class Packed Decimal
! .index class packed decimal
!
! Information to be provided for each data type:
! .list 1, "o"
! .le;Name as quoted string
! .le;Short name as quoted string
! .le;Byte size
! .le;System of origin
! .le;Maximum length allowed
! .le;Name of sign set to be used. Note that valid sign set names are:
! .list
! .le;DECSTD
! .index packed decimal sign set names
! .end list
! .le;size of sign set
! .end list
!--
! ; Literal for packed decimal sign table sizes:
LITERAL ! ;.s1.list 0, "o"
pds$k_decstd_max = 6; ! \.le;\
! ;.end list
! ; Literals for packed decimal sign set reference codes:
LITERAL ! ;.s 1 .list 0, "o"
ss_decstd = 0, ! ;.le;ss_decstd -- DEC-10/DEC-20 COBOL and VAX COBOL packed decimal standard sign set
ss_max = 1; ! ;.end list
declare_class ('pdec')
!
! The code following the call to declare_class is actually the body of the
! MACRO dt_class_pdec_def.
!
%EXPAND
data_type ('PD8', 'PD8', 8, 4, sys_8bit, 31, 'decstd')
%EXPAND
data_type ('PD9', 'PD9', 9, 4, sys_lcg, 18, 'decstd')
%EXPAND
end_class ! call MACRO end_class
%SBTTL 'Packed Decimal data table (PDD)'
!++
! .hl 3 Packed decimal data table (>pdd>)
! Format for the packed decimal data table. This table is indexed
! by the data subtype (within its class).
!
! .literal
!--
$field
pdd_fields =
SET
!++ copy
pdd$v_byt_siz = [$bits(6)], ! byte size
pdd$v_nbl_siz = [$bits(6)], ! nibble size (within a byte)
pdd$v_sys_orig = [$bits(3)], ! system of origin
pdd$v_max_length = [$byte], ! maximum field length
pdd$v_sign_set = [$bits(4)] ! addr of sign table to use
!-- .end literal
TES;
LITERAL pdd$k_size = $field_set_size;
MACRO
dtt_pd ! \.p;Macro >\
!++
! Declares an item to have the right structure and field attributes for
! the packed decimal data table.
!--
= BLOCKVECTOR [dt_class_pdec_max + 1, pdd$k_size]
FIELD (pdd_fields) % ;
%SBTTL 'Clean up'
LITERAL ! ; .hl 2 Maximum class code value
dix$k_max_class = dt_class; ! \ .p;Maximum class code used: >
! ; This is set to max class code used.
%PRINT (dix$k_max_class, '=', %NUMBER (dix$k_max_class))
!
! Clean up
!
UNDECLARE
dt_class,
dt_code,
%QUOTE declare_class,
%QUOTE data_type,
%QUOTE end_class;
%SBTTL 'Short routine names for BLISS36'
!++
! .hl 1 Short routine names for BLISS36
! Short routine names are needed for all global routines, for use by BLISS36.
! To make things look as neat as possible, this will be done by defining
! macros with the long names, which expand to the short names.
!
! Here are the long and short name equivalences:
! .list 0, "o"
!--
%IF %BLISS (BLISS36)
%THEN
MACRO
!
! Routines
!
!++ copy /strip .le;
dix$$bit_offset = dixbof %,
dix$$check_alignment = dixcal %,
dix$$check_ffd = dixcfd %,
dix$$check_type = dixctp %,
dix$$con_cb_fb = dixcxb %,
dix$$con_cb_xi = dixcxx %,
dix$$con_cf_fp = dixcxf %,
dix$$con_fbin = dixfbn %,
dix$$con_fb_cb = dixbxc %,
dix$$con_fb_xi = dixbxx %,
dix$$con_fp = dixfp %,
dix$$con_fp_cf = dixfxc %,
dix$$con_gen = dixgen %,
dix$$con_str = dixstr %,
dix$$con_dn = dixdn %,
dix$$con_dn_xi = dixdxx %,
dix$$con_xi_dn = dixxxd %,
dix$$con_pd = dixpd %,
dix$$con_pd_xi = dixpxx %,
dix$$con_xi_pd = dixxxp %,
dix$$con_xi_cb = dixxxc %,
dix$$con_xi_fb = dixxxb %,
dix$$con_dn_pd = dixdxp %,
dix$$con_dn_fb = dixdxf %,
dix$$con_pd_dn = dixpxd %,
dix$$con_pd_fb = dixpxf %,
dix$$con_fb_pd = dixfxp %,
dix$$con_fb_dn = dixfxd %,
dix$$copy_structure = dixcpy %,
dix$$des_by_det = dixdbd %,
dix$$fetch_bits = dixfbt %,
dix$$get_argadr = dixadr %,
dix$$incr_des = dixifd %,
dix$$adj_xi_scal = dixajx %,
dix$$port_hand = dixpeh %,
dil$$return_kludge = dilret %,
dix$$round_cf = dixrcf %,
dix$$stuff_bits = dixsbt %,
dil$$usr_intrfc_hand = diluih %,
dix$by_det = cvgen %,
dix$by_dix_des = xcgen %, ! [8] Insert missing pseudonym
dil$init = dilini %,
dix$mak_des_det = xdescr %,
dix$xcvpd = xcvpd %,
dix$xcvdn = xcvdn %,
dix$xcvfb = xcvfb %,
dix$xcvfp = xcvfp %,
dix$xcvst = xcvst %,
dix$xcfbdn = xcfbdn %,
dix$xcfbpd = xcfbpd %,
dix$xcdnfb = xcdnfb %,
dix$xcdnpd = xcdnpd %,
dix$xcpddn = xcpddn %,
dix$xcpdfb = xcpdfb %,
!-- .end list
!
! ; Data structures need short names, too:
!
! ;.list 0, "o"
!++ copy /strip .le;
dil$a_copyright = cpyrgh %, ! [7]
dil$g_module_version = modver %, ! [7]
dil$g_version = dilver %, ! [7]
dil$k_version = %NAME ('DIL%VE') %, ! [7]
dit$k_version = %NAME ('dit%ve') %, ! [7]
dix$a_copyright = cpyrgh %, ! [7]
dix$acst_ascii = dixasc %,
dix$acst_ebcdic = dixebc %,
dix$acst_sixbit = dixsix %,
dix$adtt_fbin = dixfbd %,
dix$adtt_fp = dixfpd %,
dix$adttx_st = dixsdx %,
dix$adtt_st = dixstd %,
dix$adtt_dn = dixdnd %,
dix$adtt_pd = dixpdd %,
dix$at_max_dt_cod = dixmdt %,
dix$ag_sys_bpunit = dixbpu %,
dix$g_module_version = modver %, ! [7]
dix$g_version = dixver %, ! [7]
dix$gg_debug = dixdbf %,
dil$gg_return_severity = dilsev %,
dil$gg_return_msg_id = dilmid %,
dil$gg_return_stat_val = dilstv %,
dix$g_library_version = libver %, ! [7]
dix$g_dixcst_version = cstver %, ! [7]
dix$k_dixcst_version = %NAME ('CST%VE') %, ! [7]
dix$k_version = %NAME ('DIX%VE') %, ! [7]
dix$adnovp_ascii = dixoa %,
dix$adnovp_asciix = dixoax %,
dix$adnovp_ebcdic = dixoe %,
dix$adnovp_sixbit = dixos %,
dix$apds_decstd = dixpds %;
!-- .end list
;
%FI ! End %IF %BLISS (BLISS36)
!++
! .HL 1 Clean up after XPORT
! XPORT seems to be in the habit of leaving the following definition
! lying around, but won't tolerate its existence at the start of a
! file. Therefore it must be UNDECLAREd here:
!--
UNDECLARE ! \\
%QUOTE $descriptor; ! \\