6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu May 02, 2024 8:54 am

All times are UTC




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: DIVISION and MOD tables
PostPosted: Mon Dec 21, 2020 10:01 am 
Offline

Joined: Sun Apr 26, 2020 3:08 am
Posts: 357
After searching and unable to find any division or mod tables, decided to try my hand at creating them.
The result is not what I expected. We are looking at 32 pages of tables just for 8-bit division and the max value for the dividend must also be 8-bit.

The code is written entirely in 6502, no monitor calls.

* Set up division table

DIV EQU $4 ; Dividend
DR EQU $5 ; Divisor
QUOT EQU $8 ; Quotient

ORG $300

LDA #01
STA $FE
LDA #00
STA $FF

]LOOP INC $FF
LDX #00
]LRP LDY $FF
]LP LDA $FE
L0310 STA $4000,X
BNE L031D

CPY #03
BCS L031D
DEY

L031D INX
BEQ L0328
DEY
BNE ]LP

INC $FE
TXA
BNE ]LRP

L0328 INC L0310+2
LDA #00
STA $FE
LDY $FF
CPY #$10
BNE ]LOOP
RTS
RTS ; filler byte so next routine falls on an even number at 820 ($334)

* To use POKE 4,DIV: POKE 5,DV: CALL 820: ? PEEK(8)

lda #00
sta $06

ldx $05 ; divisor
dex
lda table,x
sta $07

ldy $04 ; dividend
dey
lda ($06),y
sta $08 ; quotient
rts

table hex 40,41,42,43,44,45,46,47,48,49,4a,4b,4c,4d,4e,4f

0300:A9 01 85 FE A9 00 85 FF E6 FF A2 00 A4 FF A5 FE
0310:9D 00 40 D0 05 C0 03 B0 01 88 E8 F0 08 88 D0 EE
0320:E6 FE 8A D0 E7 EE 12 03 A9 00 85 FE A4 FF C0 10
0330:D0 D6 60 60 A9 00 85 06 A6 05 CA BD 48 03 85 07
0340:A4 04 88 B1 06 85 08 60 40 41 42 43 44 45 46 47
0350:48 49 4A 4B 4C 4D 4E 4F

1 REM DIV=DIVIDEND DV=DIVISOR
2 REM FOR THIS TABLE, PEEK (8) IS THE QUOTIENT
10 DIV = 249
20 FOR DV = 1 TO 8 : GOSUB 30: NEXT : END
30 PRINT DV ": "DIV / DV " "
40 POKE 4,DIV: POKE 5,DV: CALL 820
50 ?"The QUOTIENT of "PEEK(4)" / "PEEK(5)" = " PEEK (8)
60 RETURN



* Set up MOD tables
DIV EQU $4 ; Dividend
DR EQU $5 ; Divisor
QUOT EQU $8 ; Remainder

ORG $300

lda #$40
sta $07
lda #00
sta $06

ldx #$10
ldy #00
]lp sta ($06),y
iny
bne ]lp
inc $07
dex
bne ]lp

lda #01
sta $ff

]lrp ora #$40
sta $07

ldy #01
sty $fe

inc $ff
ldx $ff
stx $fd
dex

]loop ldy $fd

]lp lda $fe
sta ($06),y
clc
tya
adc $ff
tay
bcc ]lp

inc $fd
inc $fe
dex
bne ]loop

lda $ff
cmp #$10
bcc ]lrp
rts

hex 00,00,60 ; filler bytes so next routine falls at 840 ($348)

* To use POKE 4,DIV: POKE 5,DV: CALL 840: ? PEEK(8)

lda #0
sta $06

ldx $05
dex
lda table,x
sta $07

ldy $04
dey
lda ($06),y
sta $08
rts

table hex 40,41,42,43,44,45,46,47,48,49,4a,4b,4c,4d,4e,4f

0300:A9 40 85 07 A9 00 85 06 A2 10 A0 00 91 06 C8 D0
0310:FB E6 07 CA D0 F6 A9 01 85 FF 09 40 85 07 A0 01
0320:84 FE A6 FF E8 86 FD CA E6 FF A4 FD A5 FE 91 06
0330:18 98 65 FF A8 90 F5 E6 FD E6 FE CA D0 EC A5 FF
0340:C9 10 90 D6 60 00 00 60 A9 00 85 06 A6 05 CA BD
0350:5C 03 85 07 A4 04 88 B1 06 85 08 60 40 41 42 43
0360:44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 00 00 00 00

1 REM DIV=DIVIDEND DV=DIVISOR
2 REM FOR THIS MOD TABLE, PEEK (8) IS THE REMAINDER
10 DIV = 249
20 FOR DV = 1 TO 8 : GOSUB 30: NEXT : END
30 X= INT (DIV / DV): PRINT DV ": "DIV - DV * X " ";
40 POKE 4,DIV: POKE 5,DV: CALL 840
50 ?"The MOD of "PEEK(4)" / "PEEK(5)" = " PEEK (8)
60 RETURN


Top
 Profile  
Reply with quote  
PostPosted: Mon Dec 21, 2020 10:16 am 
Offline

Joined: Sun Apr 26, 2020 3:08 am
Posts: 357
Another possible method of division using tables. A binary search could be done on the multiplication table to find the quotient.

* Set up a multiplication table

MUD EQU $4 ; multiplicand
MR EQU $5 ; multiplier
PROD EQU $8 ; product

ORG $300

LDA #01
STA $FF

LDX #00
]LOOP LDY #00
]LP STA $4000,X
CLC
ADC $FF
INX
INY
CPY #$10
BCC ]LP

INC $FF
LDA $FF
CPX #0
BNE ]LOOP
RTS

0300:A9 01 85 FF A2 00 A0 00 9D 00 40 18 65 FF E8 C8
0310:C0 10 90 F4 E6 FF A5 FF E0 00 D0 EA 60 00 00 60
0320:A9 40 85 07 A6 04 A4 05 CA 88 BD 34 03 85 06 B1
0330:06 85 08 60 00 10 20 30 40 50 60 70 80 90 A0 B0
0340:C0 D0 E0 F0 60


Using this 16x16 multiplication table, let's see how this would work

I think most know how to do a binary search. You have a max-length and min-length which are the number of entries for each value. The max would then be 15 ($F) and the min starts out at 0. We add the two lengths and divide by 2 with a simple LSR. We also have to check that the difference between MIN and MAX is <= 1 to signal the end of a search.

Say for instance we want to find 12/5. The 5 being the divisor is the fifth row we start our search (starts at $4040)
We start with (MIN=0 + MAX=15)/2 = 15/2 = 7. We then put 7 into the x-reg and add to $4040,x. We see that the 7th value of the 5th line = 40 ($28). Compare the value 12 with 40 makes it less-than and also NOT-EQUAL, so we will store MAX as 7 and keep MIN as 0. If it is greater-than, we would make MIN=7 and keep MAX as 15. If they are equal then we stop.

Now get the half way point of the 2 ranges again with a simple LSR. Also check that the difference between MIN and MAX is <= 1.

(MIN=0 + MAX=7)/2 = 7/2 = 3. The 3rd value of $4040,x is 20 ($14). Our original value is still less-than this value, so halve the MIN/MAX values again.

(MIN=0 + MAX=3)/2 = 1. The 1st value of $4040,x is 10 ($0A). Our original value of 12 is now greater-than this value, now we make MIN=1.

(MIN=1 + MAX=3)/2 = 2. The 2nd value of $4040,x is 15 ($0F). Our original value of 12 is now less-than this value, and we make MAX =2.

(MIN=1 + MAX=2)/2 = 1. Our program should now have caught the MIN/MAX difference of <= 1. and we have also determined that our original value and last value found do not match. Which means we have a value between the number at MIN and the number at MAX. All that is left is to subtract the value at MIN from the original to get our remainder. And since our look-up table is using an index of 0-15 (0-$F), but our division factors deal with 1-16 (1-$10), we have to increment MIN by 1 to get the actual integer part of the quotient.

12 (original value) - 10 (x=MIN=1; value at $4040,x) = 2 (remainder)
MIN + 1 = quotient

RESULT: 12/5 = quotient = 2 and remainder = 2

This only took 4 times thru the loop to find the result, which one will find that is pretty much standard times through the loop for division of any two 8-bit numbers.

BTW: since this search method takes longer for smaller factors, we can do a simple quick check to decide which routine would be faster. The cut-off line seems to be with 4-5 times through the loop. So if we look at the 4th or 5th column of the divisor and compare the value there with the dividend. If less-than we use this next routine. If greater-than then the above binary-search method will be faster.

LDA #DIVIDEND
LDY #0
SEC

]LP INY
SBC #DIVISOR
BCS ]LP

DEY
ADC #DIVISOR

* subroutine would return with ACC = remainder, Y-reg = quotient

As an example, a division of 46/5 using the first-post method will take 9 times through the loop. This binary-search method will still only take 3-4 loops. This doesn't seem like much time savings being twice as fast, but this is just a small table. Imagine the time saving on 16-bit, 24-bit or 32-bit values.


Top
 Profile  
Reply with quote  
PostPosted: Mon Dec 21, 2020 11:23 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10793
Location: England
I've never tried to code this, but it seems once you have a fast multiplication (perhaps table-based) it's a popular choice to use Newton-Raphson iteration to converge on a reciprocal, and then one final multiplication by the numerator:
https://en.wikipedia.org/wiki/Division_ ... on_methods


Top
 Profile  
Reply with quote  
PostPosted: Mon Dec 21, 2020 5:02 pm 
Offline

Joined: Sun Apr 26, 2020 3:08 am
Posts: 357
BigEd wrote:
I've never tried to code this, but it seems once you have a fast multiplication (perhaps table-based) it's a popular choice to use Newton-Raphson iteration to converge on a reciprocal, and then one final multiplication by the numerator:
https://en.wikipedia.org/wiki/Division_ ... on_methods

I think for the most part I would like to stick with integer based division in this discussion that allows an integer remainder.

But since I am not very good at turning those types of methods into 6502 code, if you want to try your hand at it and start a new thread, there are probably some spreadsheet calculations that can benefit from floating-point division.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 12 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: