Binary Coded Decimal
As I explained in the Variable Manipulation section, the OP_ Registers are also used to store Binary Coded Numbers (BCD) for use with math routines.The OP_ Registers are 11 bytes long. They store what are called Floating Point Numbers (the decimal point is not in a fixed position). When you are putting variable's names into the OP_ Register, you usually use all 11 bytes; however, when you are using the OP_ Registers for BCD numbers, you only use the first 10. The last byte doesn't matter.
The first 10 bytes are broken up into three different parts:
.db type/sign .dw exponent relative to $fc00 .db BCD number for 7 bytes
Type and Sign
The first byte is broken up into two things.- If bit 7 is set the number is negative,
- if bit 7 is reset the number is positive.
- If bit 0 is set the number is complex,
- if bit 0 is reset then it's a real number
$00
positive real number$80
negative real number$01
positive complex part of a number$81
negative complex part of a number
Exponent
The next two bytes (second and third) of theOP_
Register are the exponent bytes. Remember that the z80 works
by storing an address, say for example $1234
, backwords as
$3412
in the memory. This is called Little Indian or something.
This applies to these next two exponent bytes. They are stored $fc00
as
$00fc
. This is kinda
weird and took me a while to get used to how the number $fc00
has anything
to do with the exponent. When you consider exponents
([number]*10^[exponent]
) you have to probably switch to Scientific
Mode on your calculator to refresh yourself on how numbers are represented in
Scientific Notation. The number 1,234,567
would be
1.234567E6
in Scientific Notation.
Let's do a quick review of Scientific Notation. When you have a number
that is normal, you move the decimal point to the left or right until you've
only got one digit before the decimal point (which has to be between 1 and
9), then you count how many decimal places you had to move it over to get
there...that number is positive if you moved the decimal place to the
left...negative if you moved it to the right. The number of places you
moved the number to the right or two the left is the exponent on the
10
. The remaining decimal number is put before the 10
to the [exponent] power.
Normal | Scientific | ||||||||||||||||
12345
|
The decimal number that is before
the E
is called the mantissa, the part on the
other side is called the exponent or the power. $fc00
is
used as the "zero" for the exponent, everything is relative to
that. You add whatever exponent you
want to $fc00
. Here's the simple formula where X
is the number relative to $fc00
and P
is the power you are wanting to use:
$fc00+P=X
So, a power of 1
is $fc01
, a power of 0
is $fc00
, a power of -1
is $fbff
, a
power of 3
is $fc03
, and a power of -3
is $fbfd
. Practice with that or something. Remember that it is
stored backwards, so $fbfc
as a result would be stored in memory
$fcfb
.
Binary Coded Decimal
The next 7 bytes of theOP_
Register (remember the 8th byte which isn't
used) are used to store a number in BCD. This is simpler than it
sounds. The number 123456
is stored as $12,$34,$56
(or 12 34 56
). The number 4521345323
(or broken up as 45 21 34 53 23
) would be stored as
$45,$21,$34,$53,$23
in memory. It's so simple that I don't think
you need specific examples for this.
Now that you know all the components of the Floating Point Number, let's put it all together in some examples in yet another table!
Sign Type | Exponent | BCD | BCD | BCD | BCD | BCD | BCD | BCD | Normal Style |
$00 | $fc00 | $12 | $34 | $56 | $00 | $00 | $00 | $00 | 1.23456 |
$00 | $fc05 | $12 | $34 | $56 | $00 | $00 | $00 | $00 | 123456 |
$00 | $fc00 | $12 | $34 | $56 | $78 | $90 | $12 | $34 | 1.2345678901234 |
$80 | $fc01 | $32 | $98 | $97 | $40 | $00 | $00 | $00 | -32.98974 |
$80 | $fc05 | $56 | $45 | $89 | $32 | $33 | $40 | $12 | -564589.32334012 |
$00 | $fc00 | $00 | $00 | $00 | $00 | $00 | $00 | $00 | 0 |
$00 | $fc00 | $10 | $00 | $00 | $00 | $00 | $00 | $00 | 1 |
$80 | $fc00 | $10 | $00 | $00 | $00 | $00 | $00 | $00 | -1 |
$00 | $fc0e | $99 | $99 | $59 | $99 | $95 | $99 | $99 | 99995999959999 |
$00 | $fbfc | $23 | $00 | $00 | $00 | $00 | $00 | $00 | 0.00023 |
.db $80 .dw $fc00 .db $10,$00,$00,$00,$00,$00,$00 ; = -1
Real numbers take up 10 bytes to represent, complex numbers take up 20 bytes: the first 10 are for the real part of the number and the next 10 are for the complex part of the number. They use the same format that the ones above do for each part. The only difference is that if bit 0 is set it is complex. Bit 0 of the first byte of the real part and the first byte of the complex part will both be set if the number is complex. Remember that the TI86 displays Complex numbers in parenthesis: (Real part, Complex part). Here's how a complex number would be displayed like the above numbers.
Sign Type | Exponent | BCD | BCD | BCD | BCD | BCD | BCD | BCD | Final Number | |
Real part | $01 | $fc00 | $12 | $34 | $56 | $00 | $00 | $00 | $00 | (1.23456,1.23456) |
Complex part | $01 | $fc00 | $12 | $34 | $56 | $00 | $00 | $00 | $00 | |
Real part | $01 | $fc01 | $23 | $46 | $50 | $00 | $00 | $00 | $00 | (23.465,-0.234) |
Complex part | $81 | $fbff | $23 | $40 | $00 | $00 | $00 | $00 | $00 | |
Real part | $81 | $fc02 | $30 | $04 | $50 | $00 | $00 | $00 | $00 | (-300.45,-0.03234) |
Complex part | $81 | $fbfe | $32 | $34 | $00 | $00 | $00 | $00 | $00 |
.db $01 .dw $fc00 .db $10,$00,$00,$00,$00,$00,$00 .db $81 .dw $fc00 .db $10,$00,$00,$00,$00,$00,$00 ; = (-1,1)
A good exercise you can do is to make a routine that will take a
string pointed to be hl
with length b
and convert it into a
BCD number in OP1
. I saw an example of this by
Joshua Seagoe called
AtoF. It will help solidify your understanding of
the format of these numbers. The AtoF routine takes a string with length
b
and changes it into a Floating Point BCD number in OP1
.
- Find where the decimal point is and count left or right until you have the decimal in the right place.
- Add the number of places moved to
$fc00
and store that. - Put the digits in BCD through the rest of the
OP1
register (any digits over the allowed 14 are left out).
More from z80 » Variables
Absolute Addressing // Binary Coded Decimal // Creating Variables // External Levels // _FindSym // Messing with Variable Data // OP Math // TI-OS Variable Manipulation // Variable Name Format // VAT Searches