The Museum of HP Calculators

HP Forum Archive 21

[ Return to Index | Top of Index ]

OT: primitive mult/div algorithms
Message #1 Posted by Egan Ford on 24 May 2012, 8:28 p.m.

Hello all,

I am look for some very fast integer mult/div algorithms for 8 and 16 bit systems. Mult is easy using tables (e.g. http://www.6502.org/source/integers/fastmult.htm), but I have not found anything like this for div. Before I started working it out for myself I thought I'd try to see what was already out there.

Thanks.

      
Re: OT: primitive mult/div algorithms
Message #2 Posted by Bob Patton on 24 May 2012, 10:17 p.m.,
in response to message #1 by Egan Ford

About 2 weeks ago I finally tossed a set of notes from my Kim-1 microprocessor class of 1977. This included hand-drawn flow charts and a listing for integer division. I first thought: "Murphy's Law." Then I remembered saving all the blank-backed papers for scratch. Yep; still have them. The algorithm wasn't declared to be particularly fast, but if it might be useful, I could scan and e-mail. I think the Kim-1 used a 6502 chip.

            
Re: OT: primitive mult/div algorithms
Message #3 Posted by Egan Ford on 25 May 2012, 6:58 p.m.,
in response to message #2 by Bob Patton

Quote:
The algorithm wasn't declared to be particularly fast, but if it might be useful, I could scan and e-mail. I think the Kim-1 used a 6502 chip.
Bob, that would be great. I'd love to examine them. Please send to egan@sense.net

Thanks again. BTW, no rush, take your time.

      
Re: OT: primitive mult/div algorithms
Message #4 Posted by Garth Wilson on 24 May 2012, 10:54 p.m.,
in response to message #1 by Egan Ford

How much memory can you afford for tables? I'm preparing a section of my website http://wilsonminesco.com/ to have Intel Hex files for large look-up tables for 16-bit fixed-point/scaled-integer math in EPROM (or you can load them into RAM if you wish). I hope to eventually be able to supply the EPROMs too for those who want them but don't have a way to program them. Most of the tables are 128KB (65,536 16-bit answers), for trig and log functions, multiplication, square-root, etc.. The table of inverses is 256KB, because each of the 65,536 answers is 32-bit. You can multiply by the inverse to speed up the divide, and use the 256x256 multiplication table to speed up the multiplication too. These can be used with any 8-bitter, but will need banking or other I/O hardware to access the 2MB if the processor only has a 16-bit address bus. Looking up functions in pre-calculated tables that give all 16 bits correct is much faster than a single multiplication, let alone many multiplications and divisions as would otherwise be needed for some functions.

I calculated the tables and formed the Intel Hex files using the HP-71. The actual HP-71 programs will be on the website too, in case any one is interested and might to take it further and form additional tables.

On the same website you referenced, my solution to the common 6502 division bug is at http://www.6502.org/source/integers/ummodfix/ummodfix.htm . Bruce clark has a version that's supposedly slightly faster on the 6502 wiki at http://6502org.wikidot.com/software-math .

Edited: 24 May 2012, 11:17 p.m.

            
Re: OT: primitive mult/div algorithms
Message #5 Posted by Egan Ford on 25 May 2012, 7:03 p.m.,
in response to message #4 by Garth Wilson

Quote:
How much memory can you afford for tables?
1-2K.
Quote:
On the same website you referenced, my solution to the common 6502 division bug is at http://www.6502.org/source/integers/ummodfix/ummodfix.htm . Bruce clark has a version that's supposedly slightly faster on the 6502 wiki at http://6502org.wikidot.com/software-math .
This one (http://6502org.wikidot.com/software-math-fastdiv) seem interesting, but I need more information.

Thanks again.

                  
Re: OT: primitive mult/div algorithms
Message #6 Posted by Garth Wilson on 26 May 2012, 2:11 a.m.,
in response to message #5 by Egan Ford

Quote:
Quote:
How much memory can you afford for tables?
1-2K.
You can also interface a large ROM through I/O. I've even done it through a 6522's synchronous serial port and shift registers, with three wires, and it was still faster than actually calculating the answers.
      
Re: OT: primitive mult/div algorithms
Message #7 Posted by Mike T. on 25 May 2012, 7:09 p.m.,
in response to message #1 by Egan Ford

I have or possibly had though I don't remember throwing them out a pile of bound volumes of early PCW issues.

Where abouts are you..?

            
Re: OT: primitive mult/div algorithms
Message #8 Posted by Egan Ford on 26 May 2012, 10:35 a.m.,
in response to message #7 by Mike T.

Quote:
Where abouts are you..?
Salt Lake City.
      
Re: OT: primitive mult/div algorithms
Message #9 Posted by Gerson W. Barbosa on 26 May 2012, 6:02 p.m.,
in response to message #1 by Egan Ford

While not the fastest multiplication algorithm around, Russian peasant multiplication is interesting and easy to implement. Once I used it for arbitrary length integer multiplication on the Z80 microprocessor. The following is a simple 8-bit operands, 16-bit result Z80 program:

	org $c000              ; sorry, no comments.
	ld hl,0
	ld c,$ff
	ld de,$ff
loop:	ld a,c
	cp 0
	ret z 
	and 1
	jr z,loop0
	add hl,de
loop0:  srl c
	sla e
	rl d
	jr loop
The equivalent 6502 code below is somewhat lengthy, but someone not so rusty at 6502 assembly language programming as I am might be able to make it shorter:
        * = $0300               
        LDA $0340      
        STA *$00           
        LDA $0341        
        STA *$01           
        LDA #$00          
        STA *$02
        STA *$03
        STA *$04
LOOP    LDA *$00
        BEQ END
        AND #$01
        BEQ LOOP0
        CLC
        LDA $01
        ADC *$03
        STA *$03
        LDA $02
        ADC *$04
        STA *$04
LOOP0   LSR *$00
        ASL *$01
        ROL *$02  
        JMP LOOP        
END     RTS
This can be assembled at http://www.masswerk.at/6502/assembler.html, giving the following object-code:
AD 40 03 85 00 AD 41 03
85 01 A9 00 85 02 85 03
85 04 A5 00 F0 1C 29 01
F0 0F 18 AD 01 00 65 03
85 03 AD 02 00 65 04 85
04 46 00 06 01 26 02 4C
12 03 60
As I didn't find an online hex to dec convert that would convert all bytes at once, I did it on Emu71:
10 DESTROY ALL
20 FOR I=1 TO 51
30 READ B$
40 PRINT HTD(B$);
50 NEXT I
60 DATA AD, 40, 03, 85, 00, AD, 41, 03, 85, 01, A9, 00, 85, 02, 85, 03, 85
70 DATA 04, A5, 00, F0, 1C, 29, 01, F0, 0F, 18, AD, 01, 00, 65, 03, 85, 03
80 DATA AD, 02, 00, 65, 04, 85, 04, 46, 00, 06, 01, 26, 02, 4C, 12, 03, 60
The AppleWin emulator can be used to test this and other algorithms:
 10  HOME : PRINT "ENTER A,B"
 20  FOR I = 768 TO 818
 30  READ BT: POKE I,BT
 40  NEXT I
 50  INPUT A,B: POKE 832,A: POKE 
     833,B
 60  CALL 768: PRINT "A * B = "; PEEK 
     (3) + 256 *  PEEK (4)
 70  DATA  173,64,3,133,0,173,65,
     3,133,1,169,0,133,2,133,3,13
     3
 80  DATA  4,165,0,240,28,41,1,24
     0,15,24,173,1,0,101,3,133,3
 90  DATA  173,2,0,101,4,133,4,70
     ,0,6,1,38,2,76,18,3,96

RUN

ENTER A,B ?217,253 A * B = 54901 ]

Gerson.

Edited: 26 May 2012, 6:07 p.m.

            
Re: OT: primitive mult/div algorithms
Message #10 Posted by Egan Ford on 27 May 2012, 9:27 p.m.,
in response to message #9 by Gerson W. Barbosa

Very interesting. Thanks.


[ Return to Index | Top of Index ]

Go back to the main exhibit hall