User's Manual
Turbo PMAC User Manual
Writing a Host Communications Program 423
Data Format
Data is stored in the buffer in 32-bit sign-extended form. That is, each short (24-bit) word gathered from
Turbo PMAC is sign-extended and stored in 32-bits of DPRAM (LSByte first). The most significant byte
is all ones or all zeros, matching bit 23. Each long (48-bit) word is treated as 2 24-bit words, with each
short word sign-extended to 32 bits. The host computer must reassemble these words into a single value.
To reassemble a long fixed-point word in the host, take the less significant 32-bit word, and mask out the
sign extension (top eight bits). In C, this operation could be done with a bit-by- bit AND: (LSW &
16777215). Treat this result as an unsigned integer. Next, take the more significant word and multiply it
by 16,777,216. Finally, add the two intermediate results.
To reassemble a long floating-point value in the host, we must first split the 64-bit value into its pieces.
Bits 0 to 11 of the 32-bit word at the lower address form the exponent. Bits 12-23 of this word form the
low 12 bits of the 36-bit mantissa. Bits 0-23 of the 32-bit word form the high 24 bits of the mantissa; bits
24-31 are sign extension. The following code shows one way of creating these pieces (not the most
efficient):
exp = first_word & 0x00000FFFL; // Select low 12 bits for exponent
low_mantissa = (first_word >> 12) & 0x00FFFL;
// Select next 12 bits for mantissa
// shift right and mask
high_mantissa = second_word;
The floating point value can then be reconstructed with:
mantissa = high_mantissa * 4096.0 + low_mantissa;
value = mantissa * pow (2.0, exp - 2047 - 35);
2047 is subtracted from the exponent to convert it from an unsigned to a signed value; 35 is subtracted to
put the mantissa in the range of 0.5 to 1.0.
The following procedure in C performs the conversion efficiently and robustly:
double DPRFLoat (long first_word, long second word) {
// return mantissa/2^35 * 2^(exp-2047)
double mantissa;
long int exp;
m = (double)(second_word) * 4096.0 +
(double)((first_word>>12) & 0x00FFFL);
if (m == 0.0) return (0.0);
exp = (first_word & 0x00000FFFL) - 2082;
// 2082=2047+35
return (mantissa * pow(2.0 * (double) exp));
}
To reassemble a long floating-point word in the host, treat the less significant word the same as for the
fixed-point case above. Take the bottom 12 bits of the more significant word (MSW & 4095), multiply
by 16,777,216 and add to the masked less significant word. This forms the mantissa of the floating-point
value. Now take the next 12 bits (MSW & 16773120) of the more significant word. This is the exponent
to the power of two, which can be combined with the mantissa to form the complete value.