Submitted by Steve Fewell
Routine: adivb
Name: Floating-Point Division (FWA=FWB/FWA)
Starting Address: &A5FA
Entry criteria: The FWA
contains the Divisor and the FWB
contains the Dividend.
Exit: The routine evaluates the expression FWB / FWA and puts the
resulting Floating-Point number is the FWA.
Description:
Store the sign of the result in the FWA Sign byte [FWB sign EOR FWA sign]. If
FWA & FWB signs are different, then the result will be negative, otherwise
it will be positive.
Add #&82 to the FWB exponent, to remove the #&80 offset for the
exponent. [E.g. 128+130 = 2], rotate the overflow (if FWB was > =1 then there
will be an overflow) into the FWA overflow byte (low bit). Subtract the FWA
Exponent from the "FWB Exponent + #&82" result to obtain the
results exponent [this automatically adds the #&80 again] store the result
as the FWA exponent. Decrement the FWA overflow if a borrow occurred during the
subtraction. The overflow considerations cater for very large and very small
numbers. The FWB exponent - the FWA exponent gives the unnormalised exponent of
the result.
This routine uses the Binary Division method known as "Shift and Subtract".
At a higher level, the routine is doing the following:
* Set the Quotient to 0
* Align the leftmost digits in the dividend and divisor (already done in BASIC!)
* Repeat:
* If the portion of the dividend above the divisor is greater than or equal
to the divisor then (1)Subtract the divisor from that portion of
the Dividend and (2) Concatentate 1 to the right hand end of the quotient;
Otherwise, concatentate 0 to the right hand end of the quotient.
* Shift the divisor to the right for one bit.
* Until the dividend is less than the divisor
* The quotient is correct and the dividend is the remainder.
Description of the Mantissa division:
Initialize some variables: Y = 4 (Number of bytes to process); ?&3C =
4 (backup of Y); A = ?&3D (FWB Mantissa byte 1); and X = 8 (Number of
bits left in current byte). For speed optimizations, the first byte of the FWB
Mantissa is stored in A. The result will be stored in bytes &43 to &46.
&3B is temporary storage for the current byte of the Result.
*1) [A622] Compare the FWB Mantissa (bytes 1 to 4) with the FWA Mantissa (stopping when the bytes differ). If the first differing byte in the FWB Mantissa is less than the first differing byte in the FWA Mantissa then [A64F] (FWB < FWA). Multiply the result byte (&3B) by 2 [shift the bits left a place] (this adds a binary 0 to the LSB end of the value) and go on to the next bit (step *3)).
*2) Otherwise, [A638] Subtract the FWA Mantissa (the divisor) from the FWB Mantissa, multiply the result byte (&3B) by 2 [shift the bits left a place] and add 1. (This tags a 1 on to the end of the result). Then go on to the next bit (Step 3).
*3) To move on to the next bit, the bits in the FWB Mantissa are shifted along one position (loosing the most significant bit). X is decremented. [A620] if X is not zero, and the bit that was just lost from the FWB Mantissa was 1, then go to step *2) to subtract and update the result again.
*4) [A620] If X hasn't reached zero then go back to step *1) to process the next bit.
*5) Decrement Y. If Y is less than zero, then jump to step *7) as all of the required bytes have been processed. Otherwise, store the current result byte (&3B), which is now complete in the next result location (that is location &46 for the first byte, &43 for the last byte, as we calculate the result most significant byte first). Next, store Y in &3C [temporary storage during processing of steps *1) to *4)]. Set X to the number of bits that need processing in the next FWB Mantissa byte - for the first 4 bytes, 8 bits are processed, and in the last (least significant) byte, only 2 bits need to be processed. The number of bytes to process is stored in BASIC ROM locations &A5E5 to &A5E8.
*6) [A620] If the bit that was just lost from the FWB Mantissa was 1, then go to step *2) to subtract and update the result again, otherwise go back to step *1) to process the next bit.
*7) Now, all of the bits have been processed, and we have a result, normalise the result [&81F7].
Next exit by rounding the FWA Mantissa to 4 bytes (loosing the rounding byte).
943.34 / 33.33 = 28.3030303030303030303030
FWA = 3333000000 Exponent = 2
FWB = 9433400000 Exponent = 3
*1) FWB > FWA, so do step *2) subtraction ==>
*2) FWB = 91001, Result = Result + 1 = 1
FWB = 87668, Result = Result + 1 = 2
FWB = 84335, Result = Result + 1 = 3
FWB = 81002, Result = Result + 1 = 4
FWB = 77669, Result = Result + 1 = 5
FWB = 74336, Result = Result + 1 = 6
FWB = 71003, Result = Result + 1 = 7
FWB = 67670, Result = Result + 1 = 8
FWB = 64337, Result = Result + 1 = 9
FWB = 61004, Result = Result + 1 = 10
FWB = 57671, Result = Result + 1 = 11
FWB = 54338, Result = Result + 1 = 12
FWB = 51005, Result = Result + 1 = 13
FWB = 47672, Result = Result + 1 = 14
FWB = 44339, Result = Result + 1 = 15
FWB = 41006, Result = Result + 1 = 16
FWB = 37673, Result = Result + 1 = 17
FWB = 34340, Result = Result + 1 = 18
FWB = 31007, Result = Result + 1 = 19
FWB = 27674, Result = Result + 1 = 20 @
FWB = 24341, Result = Result + 1 = 21
FWB = 21008, Result = Result + 1 = 22
FWB = 17675, Result = Result + 1 = 23
FWB = 14342, Result = Result + 1 = 24
FWB = 11009, Result = Result + 1 = 25
FWB = 07676, Result = Result + 1 = 26
FWB = 04343, Result = Result + 1 = 27
FWB = 01010, Result = Result + 1 = 28
*3) FWB = 1010, Result = Result * 10 = 280
*1) FWB < FWA, So Result = Result + Carry [3] = 283,
*3) FWB = 010, Result = Result * 10 = 2830
*1) FWB < FWA, So Result = Result + Carry [3] = 28303,
*3) FWB = 10, Result = Result * 10 = 283030
*1) FWB < FWA, So Result = Result + Carry [3] = 2830303,
*3) FWB = 0, Result = Result * 10 = 28303030.
Result Exponent = FWB Exponent (3) - FWA Exponent (2) + 1 = 2, So result is
28.30303030
This disassembly also contains code that is not used within Floating-Point division.
Code at &A68A is the call point for Floating-Point Minus
Code at &A68D is the call point for Floating-Point Addition
&A68A just compliments the FWA and then continues with Floating-Point Addition.
&A68D Unpacks the variable pointed to by (&2A, &2B) into the FWB and then, if FWB is not zero,
calls the Floating-Point addition routine (&8368).
Disassembly for the Floating-Point Division routine
A5E5 | 002 | 02 | EQUB &02 | |
A5E6 | 008 | 08 | EQUB &08 | |
A5E7 | 008 | 08 | EQUB &08 | |
A5E8 | 008 | 08 | EQUB &08 | |
A5FA | ; | 165 059 | A5 3B | LDA &3B |
A5FC | E. | 069 046 | 45 2E | EOR &2E |
A5FE | . | 133 046 | 85 2E | STA &2E |
A600 | 8 | 056 | 38 | SEC |
A601 | < | 165 060 | A5 3C | LDA &3C |
A603 | i | 105 129 | 69 81 | ADC#&81 |
A605 | &/ | 038 047 | 26 2F | ROL &2F |
A607 | 0 | 229 048 | E5 30 | SBC &30 |
A609 | 176 002 | B0 02 | BCS 2 --> &A60D | |
A60B | / | 198 047 | C6 2F | DEC &2F |
A60D | 0 | 133 048 | 85 30 | STA &30 |
A60F | 160 004 | A0 04 | LDY#&04 | |
A611 | < | 132 060 | 84 3C | STY &3C |
A613 | = | 165 061 | A5 3D | LDA &3D |
A615 | 162 008 | A2 08 | LDX#&08 | |
A617 | 128 009 | 80 09 | BRA 9 --> &A622 | |
A619 | C | 150 067 | 96 43 | STX &43,Y |
A61B | 190 229 165 | BE E5 A5 | LDX &A5E5,Y | |
A61E | < | 132 060 | 84 3C | STY &3C |
A620 | 176 022 | B0 16 | BCS 22 --> &A638 | |
A622 | 1 | 197 049 | C5 31 | CMP &31 |
A624 | 208 016 | D0 10 | BNE 16 --> &A636 | |
A626 | > | 164 062 | A4 3E | LDY &3E |
A628 | 2 | 196 050 | C4 32 | CPY &32 |
A62A | 208 010 | D0 0A | BNE 10 --> &A636 | |
A62C | ? | 164 063 | A4 3F | LDY &3F |
A62E | 3 | 196 051 | C4 33 | CPY &33 |
A630 | 208 004 | D0 04 | BNE 4 --> &A636 | |
A632 | @ | 164 064 | A4 40 | LDY &40 |
A634 | 4 | 196 052 | C4 34 | CPY &34 |
A636 | 144 023 | 90 17 | BCC 23 --> &A64F | |
A638 | 168 | A8 | TAY | |
A639 | @ | 165 064 | A5 40 | LDA &40 |
A63B | 4 | 229 052 | E5 34 | SBC &34 |
A63D | @ | 133 064 | 85 40 | STA &40 |
A63F | ? | 165 063 | A5 3F | LDA &3F |
A641 | 3 | 229 051 | E5 33 | SBC &33 |
A643 | ? | 133 063 | 85 3F | STA &3F |
A645 | > | 165 062 | A5 3E | LDA &3E |
A647 | 2 | 229 050 | E5 32 | SBC &32 |
A649 | > | 133 062 | 85 3E | STA &3E |
A64B | 152 | 98 | TYA | |
A64C | 1 | 229 049 | E5 31 | SBC &31 |
A64E | 8 | 056 | 38 | SEC |
A64F | &; | 038 059 | 26 3B | ROL &3B |
A651 | @ | 006 064 | 06 40 | ASL &40 |
A653 | &? | 038 063 | 26 3F | ROL &3F |
A655 | &> | 038 062 | 26 3E | ROL &3E |
A657 | * | 042 | 2A | ROL A |
A658 | 202 | CA | DEX | |
A659 | 208 197 | D0 C5 | BNE -59 --> &A620 | |
A65B | ; | 166 059 | A6 3B | LDX &3B |
A65D | < | 164 060 | A4 3C | LDY &3C |
A65F | 136 | 88 | DEY | |
A660 | 016 183 | 10 B7 | BPL -73 --> &A619 | |
A662 | > | 005 062 | 05 3E | ORA &3E |
A664 | ? | 005 063 | 05 3F | ORA &3F |
A666 | @ | 005 064 | 05 40 | ORA &40 |
A668 | 240 001 | F0 01 | BEQ 1 --> &A66B | |
A66A | 8 | 056 | 38 | SEC |
A66B | 138 | 8A | TXA | |
A66C | j | 106 | 6A | ROR A |
A66D | j | 106 | 6A | ROR A |
A66E | j | 106 | 6A | ROR A |
A66F | ) | 041 224 | 29 E0 | AND#&E0 |
A671 | 5 | 133 053 | 85 35 | STA &35 |
A673 | C | 165 067 | A5 43 | LDA &43 |
A675 | 4 | 133 052 | 85 34 | STA &34 |
A677 | D | 165 068 | A5 44 | LDA &44 |
A679 | 3 | 133 051 | 85 33 | STA &33 |
A67B | E | 165 069 | A5 45 | LDA &45 |
A67D | 2 | 133 050 | 85 32 | STA &32 |
A67F | F | 165 070 | A5 46 | LDA &46 |
A681 | 1 | 133 049 | 85 31 | STA &31 |
A683 | 0 | 048 016 | 30 10 | BMI 16 --> &A695 |
A685 | * | 032 042 130 | 20 2A 82 | JSR &822A part of Normalise FWA |
A688 | 128 011 | 80 0B | BRA 11 --> &A695 Round FWA Mantissa to 4 bytes |