aboutsummaryrefslogtreecommitdiff
path: root/libgcobol/common-defs.h
diff options
context:
space:
mode:
Diffstat (limited to 'libgcobol/common-defs.h')
-rw-r--r--libgcobol/common-defs.h53
1 files changed, 47 insertions, 6 deletions
diff --git a/libgcobol/common-defs.h b/libgcobol/common-defs.h
index 15d0683..80e524c 100644
--- a/libgcobol/common-defs.h
+++ b/libgcobol/common-defs.h
@@ -52,12 +52,53 @@
// COBOL tables can have up to seven subscripts
#define MAXIMUM_TABLE_DIMENSIONS 7
-// This bit gets turned on in the first or last byte (depending on the leading_e attribute
-// phrase) of a NumericDisplay to indicate that the value is negative.
-
-// When running the EBCDIC character set, the meaning of this bit is flipped,
-// because an EBCDIC zero is 0xF0, while ASCII is 0x30
-#define NUMERIC_DISPLAY_SIGN_BIT 0x40
+/* COBOL has the concept of Numeric Display values, which use an entire byte
+ per digit. IBM also calls this "Zoned Decimal".
+
+ In ASCII, the digits are '0' through '9' (0x30 through 0x39'. Signed
+ values are indicated by turning on the 0x40 bit in either the first
+ byte (for LEADING variables) or the last byte (for TRAILING).
+
+ In IBM EBCDIC, the representation is slightly more complex, because the
+ concept of Zone carries a little more information. Unsigned numbers are
+ made up of just the EBCDIC digits '0' through '9' (0xF0 through 0xF9).
+
+ The TRAILING signed value +1234 has the byte sequence 0xF1 0xF2 0xF3 0xC3.
+ The TRAILING signed value -1234 has the byte sequence 0xF1 0xF2 0xF3 0xD3.
+ The LEADING signed value +1234 has the byte sequence 0xC1 0xF2 0xF3 0xF3.
+ The LEADING signed value -1234 has the byte sequence 0xD1 0xF2 0xF3 0xF3.
+
+ Note that for IBM EBCDIC, the nybble indicating sign has the same meaning
+ as for COMP-3/packed-decimal numbers.
+
+ The effective result of this is that for ASCII, the byte carrying the sign
+ is made negative by turning on the 0x40 bit.
+
+ For EBCDIC, the value must be constructed properly as a positive value by
+ setting the high nybble of the sign-carrying byte to 0xC0, after which the
+ value is flagged negative by turning on the 0x10 bit, turning the 0xC0 to
+ 0xD0. */
+
+#define EBCDIC_MINUS (0x60)
+#define EBCDIC_PLUS (0x4E)
+#define EBCDIC_ZERO (0xF0)
+#define EBCDIC_NINE (0xF9)
+
+#define PACKED_NYBBLE_PLUS 0x0C
+#define PACKED_NYBBLE_MINUS 0x0D
+#define PACKED_NYBBLE_UNSIGNED 0x0F
+
+#define NUMERIC_DISPLAY_SIGN_BIT_ASCII 0x40
+#define NUMERIC_DISPLAY_SIGN_BIT_EBCDIC 0x10
+
+#define NUMERIC_DISPLAY_SIGN_BIT (__gg__ebcdic_codeset_in_use ? \
+ NUMERIC_DISPLAY_SIGN_BIT_EBCDIC : \
+ NUMERIC_DISPLAY_SIGN_BIT_ASCII)
+
+#define SEPARATE_PLUS (__gg__ebcdic_codeset_in_use ? EBCDIC_PLUS : '+')
+#define SEPARATE_MINUS (__gg__ebcdic_codeset_in_use ? EBCDIC_MINUS : '-')
+#define ZONED_ZERO (__gg__ebcdic_codeset_in_use ? EBCDIC_ZERO : '0')
+#define ZONE_SIGNED_EBCDIC (0xC0)
#define LEVEL01 (1)
#define LEVEL49 (49)