Functions for printing floating-point numbers.
Prints "IN " and falls into PrintInt. Used by the error handling code to print stuff like "?SN ERROR IN 50".
0B45
E5
PUSH H
Test FACCUM. If it's positive then write a leading space; if it's negative then write a leading minus sign.
0B47
3620
MVI M,' '
0B4C
362D
MVI M,'-'
Write a '0', and if FACCUM equals 0 then jump to NullTerm-3, which is a convenient shortcut for null-terminating the output buffer. Jumping to NullTerm-3 means that a spurious byte (in C) gets written immediately following the null-terminator, but this isn't a problem because we're nowhere near the end of the buffer plus doing it this way we save a couple of bytes we would have lost had we insisted on jumping to NullTerm with C explicitly set to 0. If FACCUM is not zero then the '0' gets overwritten a few lines down.
0B4E
23
DoZero
INX H
0B4F
3630
MVI M,'0'
Make FACCUM a positive number by negating it if it's negative.
0B54
E5
PUSH H
Initialise Decimal Exponent Adjustment (hereafter shortened to DecExpAdj) to 0.
0B58
AF
XRA A
0B59
F5
PUSH PSW
Here's where we bring FACCUM into range between 100,000 and 1,000,000 by multiplying or dividing by ten a number of times. The first call ensures FACCUM is less than 1,000,000 and the loop that follows makes it more than or equal to 100,000. The decimal exponent that we had to use on FACCUM to get it into this range (referred to as DecExpAdj) is kept on the stack.
0B5D
014391
ToOver100,000
LXI B,9143
BCDE=(float)100,000.
0B60
11F84F
LXI D,4FF8
0B63
CD4C0A
CALL
FCompare
If FACCUM >= 100,000
0B69
F1
POP PSW
A=DecExpAdj
0B6D
F5
PUSH PSW
Divide FACCUM by ten and increment DecExpAdj.
0B71
CD2309
CALL DecimalShiftDown
0B74
F1
POP PSW
0B75
3C
INR A
DecExpAdj++;
0B76
F5
PUSH PSW
Some preparation. We add 0.5 to FACCUM, make it an integer, then finally store the result of that in FACCUM.
0B7D
3C
INR A
fixme.
0B84
010602
LXI B,0206
0B87
F1
POP PSW
A=DecExpAdj+6.
0B88
81
ADD C
0B89
FA950B
JM 0B95
If A<1 or A>6 Then goto fixme.
0B8C
FE07
CPI 07
0B8E
D2950B
JNC 0B95
0B91
3C
INR A
0B92
47
MOV B,A
0B93
3E01
MVI A,01
A=1, indicating scientific notation.
fixme.
0B95
3D
DCR A
0B96
E1
POP H
HL=output buffer
0B97
F5
PUSH PSW
Preserve decimal exponent adjustment (and preserve zero flag used to indicate scientific notation wanted).
NextDigit. This is the outer loop of printing, where each ASCII digit is calculated in turn. We start by writing out the decimal point, but we only advance HL to keep it if B==0, which means (obviously) that the decimal point has been reached.
0B9B
05
NextDigit
DCR B
0B9C
362E
MVI M,'.'
0B9E
CC270A
CZ
IncHL+Return
0A27 just happens to inc HL and RET.
0BA1
C5
PUSH B
0BA2
E5
PUSH H
0BA3
D5
PUSH D
DE=>decimal power
0BA7
E1
POP H
HL=>decimal power.
0BA8
062F
MVI B,'0'-1
Work out the digit corresponding to the current decimal power. We do this by subtracting the decimal power (eg 100) from CDE until it overflows, and incrementing the ASCII digit value in B each time. When it overflows, we have our digit. And when it overflows, we call FAddMantissas to undo the last subtraction which was one step too far.
0BAA
04
DigitLoop
INR B
0BAB
7B
MOV A,E
0BAC
96
SUB M
0BAD
5F
MOV E,A
0BAE
23
INX H
0BAF
7A
MOV A,D
0BB0
9E
SBB M
0BB1
57
MOV D,A
0BB2
23
INX H
0BB3
79
MOV A,C
0BB4
9E
SBB M
0BB5
4F
MOV C,A
0BB6
2B
DCX H
0BB7
2B
DCX H
0BBE
23
INX H
???
Write out the digit. If we still have digits to do then loop back.
0BC2
EB
XCHG
0BC3
E1
POP H
HL=output buffer
0BC4
70
MOV M,B
0BC5
23
INX H
0BC6
C1
POP B
B=decimal point place
0BC7
0D
DCR C
C=digits remaining, minus one.
0BCB
05
DCR B
0BCC
CADB0B
JZ 0BDB
Move HL one byte behind the first trailing zero.
0BCF
2B
DCX H
0BD0
7E
MOV A,M
0BD1
FE30
CPI '0'
0BD3
CACF0B
JZ 0BCF
If we've no decimal point, then increment HL so it's
0BD6
FE2E
CPI '.'
0BDB
F1
POP PSW
Write exponent part of scientific format.
0BDF
3645
MVI M,'E'
Write 'E'
0BE1
23
INX H
0BE2
362B
MVI M,'+'
Write '+' or '-'
0BE4
F2EB0B
JP 0BEB
0BE7
362D
MVI M,'-'
Write '-' if it's negative, also
0BE9
2F
CMA
two's complement the decimal exponent
0BEA
3C
INR A
so printing it will work.
0BEB
062F
MVI B,'0'-1
Work out the first digit of exponent in B. Done by usual method of repeatedly subtracting 10 until it overflows.
0BED
04
ExpDigitLoop
INR B
0BEE
D60A
SUI 0A
0BF3
C63A
ADI 3A
Adding '0'+10 gives us the 2nd digit
0BF5
23
INX H
of the exponent.
0BF6
70
MOV M,B
Write first digit.
0BF8
77
MOV M,A
Write second digit of exponent.
0BF9
23
INX H
0BFA
71
NullTerm
MOV M,C
Null byte terminator.
0BFB
E1
POP H
0BFC
C9
RET
ToUnder1,000,000
Divides FACCUM by ten until it's less than 1,000,000. This function is semi-recursive... if it needs to recurse (ie