×   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

Float Divide 10

Submitted by Steve Fewell

Routine: adiv10
Name: Float Divide 10
Starting Address: &A478
Entry criteria: The FWA contains the Floating-point number to divide by 10.
Exit: FWA contains the result of [FWA / 10]

Description:
As BASIC handles input and output of base-10 numbers (decimal), but does it's calculations in base-2 (binary), is needs fast routines to multiple and divide by a factor of 10.

The standard Floating-point '/' and '*' routines could be used for this purpose, and BASIC could provide 10 as the second value in the division and multiplication routines. But this wouldn't be a very satisfactory method - as BASIC requires these frequent calculations to be performed as fast as possible.

The problem with the standard Floating-point '/' and '*' routines is that they require loops (iteration), in order to perform the required action on the two variable numbers. The loops will probably be iterated for different numbers of times depending on the values of both of the variable numbers. BASIC requires multiplication and division by 10 as part of its internal routines, and as such cannot accept an undetermined number of iterations until a result is found.

Hence, the BASIC ROM contains separate routines to multiply and divide floating-point numbers by 10. These routines contain no loops (iteration), and run through a set sequence of commands each time (with little variation).

This page contains the complicated code that BASIC performs in order to achieve a Division by 10. The Multiply by 10 routine can be found here.

The routine executes the following steps:

a) 4 is subtracted from the FWA exponent, this divides the number by 16 (as the number is stored in binary). If a borrow occurred, then also decrement the  FWA overflow exponent.

b) Copy the FWA to FWB, and divide the FWB mantissa by 2. Then add the FWB mantissa to the FWA mantissa (Least significant byte first, as usual). If carry if left after adding, then the FWA mantissa overflowed, so divide the FWA mantissa by 2 (making the top bit 1), and increment the FWA exponent & FWA exponent overflow (if necessary) to correct.

c) Copy the FWA to FWB, and divide the FWB mantissa by 16. Then add the FWB mantissa to the FWA mantissa (Least significant byte first, as usual). If carry if left after adding, then the FWA mantissa overflowed, so divide the FWA mantissa by 2 (making the top bit 1), and increment the FWA exponent & FWA exponent overflow (if necessary) to correct.

d) Zero &3D (FWB Mantissa byte 1), and set FWB mantissa byte 2 to FWA mantissa byte 1, FWB mantissa byte 3 to FWA mantissa byte 2, FWB mantissa byte 4 to FWA mantissa byte 3 and FWB mantissa byte 5 to FWA mantissa byte 4. ROL &35 (FWA mantissa byte 5), so that C = mantissa byte 5's top bit. This byte manipulation has resulted in FWB = FWA divided by 256. 
Next add the FWB mantissa to the FWA mantissa (Least significant byte first, as usual). If carry if left after adding, then the FWA mantissa overflowed, so divide the FWA mantissa by 2 (making the top bit 1), and increment the FWA exponent & FWA exponent overflow (if necessary) to correct.

e) Zero &3E (FWB Mantissa byte 2, Note: FWB byte 1 is still zero from the previous step), and set FWB mantissa byte 3 to FWA mantissa byte 1, FWB mantissa byte 4 to FWA mantissa byte 2 and FWB mantissa byte 5 to FWA mantissa byte 3. ROL &34 (FWA mantissa byte 4), so that C = mantissa byte 4's top bit. This byte manipulation has resulted in FWB = FWA divided by 65536.
Next add the FWB mantissa to the FWA mantissa (Least significant byte first, as usual). If carry if left after adding, then the FWA mantissa overflowed, so divide the FWA mantissa by 2 (making the top bit 1), and increment the FWA exponent & FWA exponent overflow (if necessary) to correct.

f) If the mantissa overflowed during the previous step, some extra rounding is performed, to correct the mantissa's value (this rounding correction also takes into account the value in the FWA mantissa byte 5).

g) If no overflow from the mantissa has occurred then end, otherwise divide the FWA mantissa by 2, making the top bit equal to 1 (from carry flag) to account for the overflow. The FWA exponent is then incremented to allow for the carry that was added to the mantissa. The FWA overflow exponent is also incremented if the FWA exponent overflowed.

In simpler terms, this routine is doing the following:

> a) FWA = FWA / 16
> b) FWA = FWA + (FWA / 2)
> c) FWA = FWA + (FWA / 16)
> d) FWA = FWA + (FWA / 256)
> e) FWA = FWA + (FWA / 65536)

Each of the division steps results in the following fractions of the original number:

a) 1 / 16                          [0.0625]
b) 1 / 32                          [0.03125]
c) 3 / 512                        [0.0058593748]
d) 51 / 131072                [0.000389099]
e) 6553 / 4294967296    [0.00000152585]

All of these fractions add up to 0.1 (a tenth) - So this routines basically takes a tenth of the original number.

This gives the same result as FWA / 10, except that the calculations are done using binary powers - which are a lot easier (and faster) to handle in 6502 Assembly language, than other decimal numbers.

Disassembly for the Floating Point divide 10 routine

A478 8 056 38 SEC
A479 0 165 048 A5 30 LDA &30
A47B   233 004 E9 04 SBC#&04
A47D 0 133 048 85 30 STA &30
A47F   176 002 B0 02 BCS 2 --> &A483
A481 / 198 047 C6 2F DEC &2F
A483 ( 032 040 164 20 28 A4 JSR &A428   FWB=FWA/2
A486 G 032 071 164 20 47 A4 JSR &A447   Add FWB to FWA
A489 ( 032 040 164 20 28 A4 JSR &A428   FWB=FWA/2
A48C + 032 043 164 20 2B A4 JSR &A42B   FWB=FWB/2
A48F + 032 043 164 20 2B A4 JSR &A42B   FWB=FWB/2
A492 + 032 043 164 20 2B A4 JSR &A42B   FWB=FWB/2
A495 G 032 071 164 20 47 A4 JSR &A447   Add FWB to FWA
A498 d= 100 061 64 3D STZ &3D
A49A 1 165 049 A5 31 LDA &31
A49C > 133 062 85 3E STA &3E
A49E 2 165 050 A5 32 LDA &32
A4A0 ? 133 063 85 3F STA &3F
A4A2 3 165 051 A5 33 LDA &33
A4A4 @ 133 064 85 40 STA &40
A4A6 4 165 052 A5 34 LDA &34
A4A8 A 133 065 85 41 STA &41
A4AA 5 165 053 A5 35 LDA &35
A4AC * 042 2A ROL A
A4AD G 032 071 164 20 47 A4 JSR &A447   Add FWB to FWA
A4B0 d> 100 062 64 3E STZ &3E
A4B2 1 165 049 A5 31 LDA &31
A4B4 ? 133 063 85 3F STA &3F
A4B6 2 165 050 A5 32 LDA &32
A4B8 @ 133 064 85 40 STA &40
A4BA 3 165 051 A5 33 LDA &33
A4BC A 133 065 85 41 STA &41
A4BE 4 165 052 A5 34 LDA &34
A4C0 * 042 2A ROL A
A4C1 G 032 071 164 20 47 A4 JSR &A447   Add FWB to FWA
A4C4 2 165 050 A5 32 LDA &32
A4C6 * 042 2A ROL A
A4C7 1 165 049 A5 31 LDA &31
A4C9 e5 101 053 65 35 ADC &35
A4CB 5 133 053 85 35 STA &35
A4CD   144 016 90 10 BCC 16 --> &A4DF
A4CF 4 230 052 E6 34 INC &34
A4D1   208 012 D0 0C BNE 12 --> &A4DF
A4D3 3 230 051 E6 33 INC &33
A4D5   208 008 D0 08 BNE 8 --> &A4DF
A4D7 2 230 050 E6 32 INC &32
A4D9   208 004 D0 04 BNE 4 --> &A4DF
A4DB 1 230 049 E6 31 INC &31
A4DD   240 136 F0 88 BEQ -120 --> &A467   Handle Mantissa Overflow
A4DF ` 096 60 RTS

 


 Back to 8BS
Or