×   Main Menu ALL The 8BS News Manuals (New menu) Links Worth a Look Tools Disc and Basic Webring Site Map 8BS Guestbook Old Guest Book Me The Barnsley Rovers   
8-Bit Software

The BBC and Master Computer Public Domain Library

Floating-Point Division

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

 


 Back to 8BS
Or