image of READY prompt

Wang2200.org

The Wang 2200 BASIC used a BCD floating point number system. All numbers are double precision and occupy eight bytes of memory. Internally, the format is: Signs nibble, Exp. Low nibble, Exp. High nibble, Mantissa (13 nibbles). Both the mantissa and exponent are represented as BCD sign/magnitude form.

Signs Low Exp. High Exp. MS Mantissa digit ... LS Mantissa digit
1 nibble 1 nibble 1 nibble 1 nibble 11 more nibbles 1 nibble

The mantissa is always normalized. If the exponent gets too small, the value simply flushes to zero (which is encoded as all zero bytes).

The signs nibble has four bits. The ms bit of the sign nibble is 1 if the exponent is negative. The ls bit of the sign nibble is 1 if the mantissa is negative. The other two bits are always zero, or in a Verilog-ish syntax, { exponent_sign, 0, 0, mantissa_sign }. Stated another way, there are four legal values for this sign nibble:

Sign nibble value indicates Example value
0 mantissa and exponent both positive +1.0
8 mantissa positive, exponent negative +0.1
9 mantissa and exponent both negative -0.1
1 mantissa negative, exponent positive -1.0

Wang BASIC-2, which ran on the 2200VP and related CPU, is also BCD and also occupied eight bytes. It is very likely similar if not identical, but it hasn't yet been researched.

Google books turned up an interesting reference in the book Mothers and daughters of invention: notes for a revised history of technology, by Autumn Stanley. Page 482 says that the 2200 microcode for floating point operation was written by Jenny Chuang.

The microcode for the floating routines in BASIC-2 was written by Dave Angel (verified by personal email).

CPU Microarchitecture Synergy (link)

The 2200 CPU had a few features to make working with floating point BCD numbers more efficient.

Synergy occurs when these separate features work together to mutually enhance the usefulness of each individual feature. In the case of Wang BASIC, the interpreter would place the two operands of whatever operation was being performed (addition, multiplication, etc.) into memory aligned to a 16 nibble boundary with the two operands 16 nibbles apart. By using the vertical read mode, corresponding nibbles of the two operands could be fetched in one memory access. By using autoincrementing addressing, each ALU operation would have the side effect of advancing to the next nibble in the operands. By using the wrapping feature the CPU could sometimes avoid having to reset the nibble pointer at the end of the mantissa operation.

Exploration (link)

Wang BASIC has a few functions for converting between numeric and alphanumeric representations (ASCII or packed hex). Attempts to feed the string to number conversion command malformed strings to see what kind of number is generate has met with no interesting results. For example:

10 A$=HEX(0000000000000000)
20 CONVERT (+#.############^^^^) A$ TO A
30 PRINT A

Produces 0 (mantissa and exponent signs are positive, all mantissa nibbles are zero, exponent is zero). First, some vanilla values; to make it easier to decode, the nibble with the S over it is the signs nibble, the M nibbles are the mantissa digits, and EE are the exponent digits.

          SMMMMMMMMMMMMMEE
10 A$=HEX(0000000000000000) --> 0
10 A$=HEX(0100000000000000) --> 1
10 A$=HEX(0150000000000000) --> 1.5
10 A$=HEX(0100000000000001) --> 10  (exponent of positive 01)
10 A$=HEX(8100000000000001) --> 0.1 (exponent of negative 01)
10 A$=HEX(1100000000000000) --> -1  (negative mantissa sign bit)

Now throw in some values that stretch the rules:

          SMMMMMMMMMMMMMEE
10 A$=HEX(0010000000000001) --> 1     (unnormalized mantissa is accepted)
10 A$=HEX(8010000000000099) --> error (would be 1E-100; not flushed to zero)
10 A$=HEX(010000000000000A) --> error (illegal exponent nibble value)
10 A$=HEX(2100000000000001) --> 10    (unspecified sign bit is ignored)
10 A$=HEX(4100000000000001) --> 10    (unspecified sign bit is ignored)

The two middle bits of the signs nibble appear to be completely ignored.