<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://oldwiki.cpcwiki.eu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Litwr</id>
		<title>CPCWiki - THE Amstrad CPC encyclopedia! - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://oldwiki.cpcwiki.eu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Litwr"/>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php/Special:Contributions/Litwr"/>
		<updated>2026-08-29T14:50:47Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.25.1</generator>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Quicksort&amp;diff=107764</id>
		<title>Programming:Quicksort</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Quicksort&amp;diff=107764"/>
				<updated>2021-02-07T15:49:14Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Does a Quicksort (ascending) on a memory range in 67 bytes. An optimization for space is possible if you replace the absolute jumps with relative jumps (saves 6 bytes).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
;&lt;br /&gt;
; Usage: bc-&amp;gt;first, de-&amp;gt;last,&lt;br /&gt;
; call qsort&lt;br /&gt;
; Destroys: abcdefhl&lt;br /&gt;
;&lt;br /&gt;
qsort   ld      hl,0&lt;br /&gt;
        push    hl&lt;br /&gt;
qsloop  ld      h,b&lt;br /&gt;
        ld      l,c&lt;br /&gt;
        or      a&lt;br /&gt;
        sbc     hl,de&lt;br /&gt;
        jp      c,next1 ;loop until lo&amp;amp;lt;hi&lt;br /&gt;
        pop     bc&lt;br /&gt;
        ld      a,b&lt;br /&gt;
        or      c&lt;br /&gt;
        ret     z       ;bottom of stack&lt;br /&gt;
        pop     de&lt;br /&gt;
        jp      qsloop&lt;br /&gt;
next1   push    de      ;save hi,lo&lt;br /&gt;
        push    bc&lt;br /&gt;
        ld      a,(bc)  ;pivot&lt;br /&gt;
        ld      h,a&lt;br /&gt;
        dec     bc&lt;br /&gt;
        inc     de&lt;br /&gt;
fleft   inc     bc      ;do i++ while cur&amp;amp;lt;piv&lt;br /&gt;
        ld      a,(bc)&lt;br /&gt;
        cp      h&lt;br /&gt;
        jp      c,fleft&lt;br /&gt;
fright  dec     de      ;do i-- while cur&amp;gt;piv&lt;br /&gt;
        ld      a,(de)&lt;br /&gt;
        ld      l,a&lt;br /&gt;
        ld      a,h&lt;br /&gt;
        cp      l&lt;br /&gt;
        jp      c,fright&lt;br /&gt;
        push    hl      ;save pivot&lt;br /&gt;
        ld      h,d     ;exit if lo&amp;gt;hi&lt;br /&gt;
        ld      l,e&lt;br /&gt;
        or      a&lt;br /&gt;
        sbc     hl,bc&lt;br /&gt;
        jp      c,next2&lt;br /&gt;
        ld      a,(bc)  ;swap (bc),(de)&lt;br /&gt;
        ld      h,a&lt;br /&gt;
        ld      a,(de)&lt;br /&gt;
        ld      (bc),a&lt;br /&gt;
        ld      a,h&lt;br /&gt;
        ld      (de),a&lt;br /&gt;
        pop     hl      ;restore pivot&lt;br /&gt;
        jp      fleft&lt;br /&gt;
next2   pop     hl      ;restore pivot&lt;br /&gt;
        pop     hl      ;pop lo&lt;br /&gt;
        push    bc      ;stack=left-hi&lt;br /&gt;
        ld      b,h&lt;br /&gt;
        ld      c,l     ;bc=lo,de=right&lt;br /&gt;
        jp      qsloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Division&amp;diff=94857</id>
		<title>Programming:Integer Division</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Division&amp;diff=94857"/>
				<updated>2015-12-26T13:27:00Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: /* Fast 32bit division */ a bit faster&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== 8bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' HL=Value1, C=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' L=Value1/Value2, H=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF,BC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        LD B,8&lt;br /&gt;
Div_Next:&lt;br /&gt;
        ADD     HL,HL&lt;br /&gt;
        LD      A,H&lt;br /&gt;
        SUB     C&lt;br /&gt;
        JR      C,Div_NXTB&lt;br /&gt;
        LD      H,A&lt;br /&gt;
        INC     L&lt;br /&gt;
Div_NXTB:&lt;br /&gt;
        DJNZ    Div_Next&lt;br /&gt;
        RET&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 16bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' BC=Value1, DE=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL=Value1/Value2, DE=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF,BC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clcd16  ld a,e&lt;br /&gt;
        or d&lt;br /&gt;
        ld hl,0&lt;br /&gt;
        ret z&lt;br /&gt;
        ld a,b&lt;br /&gt;
        ld b,16&lt;br /&gt;
clcd161 rl c&lt;br /&gt;
        rla&lt;br /&gt;
        adc hl,hl&lt;br /&gt;
        sbc hl,de&lt;br /&gt;
        jr nc,clcd162&lt;br /&gt;
        add hl,de&lt;br /&gt;
clcd162 ccf&lt;br /&gt;
        djnz clcd161&lt;br /&gt;
        ex de,hl&lt;br /&gt;
        rl c&lt;br /&gt;
        rla&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld l,c&lt;br /&gt;
        ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 24bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A,BC=Value1, DE=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL=Value1/Value2, DE=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF,BC,IX,IYL&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clcdiv  db #dd:ld l,e&lt;br /&gt;
        db #dd:ld h,d   ;IX=Value2&lt;br /&gt;
        ld e,a          ;E,BC=Value1(Counter)&lt;br /&gt;
        ld hl,0&lt;br /&gt;
        db #dd:ld a,l&lt;br /&gt;
        db #dd:or h&lt;br /&gt;
        ret z&lt;br /&gt;
        ld d,l          ;D,HL=CalcVar&lt;br /&gt;
        db #fd:ld l,24  ;IYL=Counter&lt;br /&gt;
clcdiv1 rl c&lt;br /&gt;
        rl b&lt;br /&gt;
        rl e&lt;br /&gt;
        rl l&lt;br /&gt;
        rl h&lt;br /&gt;
        rl d&lt;br /&gt;
        ld a,l&lt;br /&gt;
        db #dd:sub l&lt;br /&gt;
        ld l,a&lt;br /&gt;
        ld a,h&lt;br /&gt;
        db #dd:sbc h&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld a,d&lt;br /&gt;
        sbc 0&lt;br /&gt;
        ld d,a          ;D,HL=D,HL-IX&lt;br /&gt;
        jr nc,clcdiv2&lt;br /&gt;
        ld a,l&lt;br /&gt;
        db #dd:add l&lt;br /&gt;
        ld l,a&lt;br /&gt;
        ld a,h&lt;br /&gt;
        db #dd:adc h&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld a,d&lt;br /&gt;
        adc 0&lt;br /&gt;
        ld d,a&lt;br /&gt;
        scf&lt;br /&gt;
clcdiv2 ccf&lt;br /&gt;
        db #fd:dec l&lt;br /&gt;
        jr nz,clcdiv1&lt;br /&gt;
        ex de,hl        ;DE=Value1 MOD Value2&lt;br /&gt;
        rl c&lt;br /&gt;
        rl b&lt;br /&gt;
        ld l,c&lt;br /&gt;
        ld h,b          ;HL=Value1 DIV Value2&lt;br /&gt;
        ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 32bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' IY,BC=Value1, IX=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' IY,BC=Value1/Value2, HL=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF,DE,IY&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' approximately 7800, 1900 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:'''  91 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clcd32c db 0&lt;br /&gt;
clcd32  ld hl,0&lt;br /&gt;
        db #dd:ld a,l&lt;br /&gt;
        db #dd:or h&lt;br /&gt;
        ret z           ;IY,BC=Value1(Counter)&lt;br /&gt;
        ld de,0         ;DE,HL=CalcVar&lt;br /&gt;
        ld a,32         ;Set Counter to 32&lt;br /&gt;
clcd321 ld (clcd32c),a&lt;br /&gt;
        rl c&lt;br /&gt;
        rl b&lt;br /&gt;
        db #fd:ld a,l:rla:db #fd:ld l,a&lt;br /&gt;
        db #fd:ld a,h:rla:db #fd:ld h,a&lt;br /&gt;
        rl l&lt;br /&gt;
        rl h&lt;br /&gt;
        rl e&lt;br /&gt;
        rl d&lt;br /&gt;
        ld a,l&lt;br /&gt;
        db #dd:sub l&lt;br /&gt;
        ld l,a&lt;br /&gt;
        ld a,h&lt;br /&gt;
        db #dd:sbc h&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld a,e&lt;br /&gt;
        sbc 0&lt;br /&gt;
        ld e,a&lt;br /&gt;
        ld a,d&lt;br /&gt;
        sbc 0&lt;br /&gt;
        ld d,a&lt;br /&gt;
        jr nc,clcd322&lt;br /&gt;
        ld a,l&lt;br /&gt;
        db #dd:add l&lt;br /&gt;
        ld l,a&lt;br /&gt;
        ld a,h&lt;br /&gt;
        db #dd:adc h&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld a,e&lt;br /&gt;
        adc 0&lt;br /&gt;
        ld e,a&lt;br /&gt;
        ld a,d&lt;br /&gt;
        adc 0&lt;br /&gt;
        ld d,a&lt;br /&gt;
        scf&lt;br /&gt;
clcd322 ccf&lt;br /&gt;
        ld a,(clcd32c)&lt;br /&gt;
        dec a&lt;br /&gt;
        jr nz,clcd321   ;HL=Value1 MOD Value2&lt;br /&gt;
        rl c&lt;br /&gt;
        rl b&lt;br /&gt;
        db #fd:ld a,l:rla:db #fd:ld l,a&lt;br /&gt;
        db #fd:ld a,h:rla:db #fd:ld h,a&lt;br /&gt;
        ret             ;IY,BC=Value1 DIV Value2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast 32bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' HL,DE=Value1, BC=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' BCDE=Value1/Value2, HL=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF&lt;br /&gt;
&lt;br /&gt;
'''Not used:''' IX, IY&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 1016-2444 (1730 on average), 254-611 usec (432 on average)&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 277 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
div_r macro&lt;br /&gt;
     local t2&lt;br /&gt;
     SLA   E&lt;br /&gt;
     RL    D&lt;br /&gt;
     ADC   HL, HL&lt;br /&gt;
&lt;br /&gt;
     LD    A, L&lt;br /&gt;
     ADD   A, C&lt;br /&gt;
     LD    A, H&lt;br /&gt;
     ADC   A, B&lt;br /&gt;
     JR    NC, t2&lt;br /&gt;
&lt;br /&gt;
     ADD   HL, BC&lt;br /&gt;
     INC   DE&lt;br /&gt;
t2&lt;br /&gt;
     endm&lt;br /&gt;
div_e macro&lt;br /&gt;
     local t1,t2&lt;br /&gt;
     SLA   E&lt;br /&gt;
     RL    D&lt;br /&gt;
     ADC   HL, HL&lt;br /&gt;
     JR    C, t1&lt;br /&gt;
&lt;br /&gt;
     LD    A, L&lt;br /&gt;
     ADD   A, C&lt;br /&gt;
     LD    A, H&lt;br /&gt;
     ADC   A, B&lt;br /&gt;
     JR    NC, t2&lt;br /&gt;
t1&lt;br /&gt;
     ADD   HL, BC&lt;br /&gt;
     INC   DE&lt;br /&gt;
t2&lt;br /&gt;
     endm&lt;br /&gt;
div32x16 proc  ; BCDE = HLDE/BC, HL = HLDE%BC&lt;br /&gt;
     local DIV16, DIV32R, DIV32E&lt;br /&gt;
     DEC   BC&lt;br /&gt;
     LD    A, B&lt;br /&gt;
     CPL &lt;br /&gt;
     LD    B, A&lt;br /&gt;
     LD    A, C&lt;br /&gt;
     CPL &lt;br /&gt;
     LD    C, A&lt;br /&gt;
     ADD   A, L&lt;br /&gt;
     LD    A, B&lt;br /&gt;
     ADC   A, H&lt;br /&gt;
     JR    NC, DIV16&lt;br /&gt;
&lt;br /&gt;
     PUSH  DE&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     LD    HL, 0000&lt;br /&gt;
     CALL  DIV32R&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     EX    (SP), HL&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     CALL  DIV32E&lt;br /&gt;
     POP   BC&lt;br /&gt;
     RET&lt;br /&gt;
DIV16&lt;br /&gt;
     CALL  DIV32E&lt;br /&gt;
     LD    BC, 0000&lt;br /&gt;
     RET&lt;br /&gt;
DIV32R   ; DE = HLDE/(-BC), HL = HLDE%(-BC), -BC &amp;lt; $8000&lt;br /&gt;
     CALL  $+3&lt;br /&gt;
     rept 8&lt;br /&gt;
     div_r&lt;br /&gt;
     endm&lt;br /&gt;
     RET&lt;br /&gt;
DIV32E   ; DE = HLDE/(-BC), HL = HLDE%(-BC)&lt;br /&gt;
     CALL  $+3&lt;br /&gt;
     rept 8&lt;br /&gt;
     div_e&lt;br /&gt;
     endm&lt;br /&gt;
     RET&lt;br /&gt;
     endp &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.smspower.org/Development/DivMod Division implementation for the Sega Master System]&lt;br /&gt;
* [http://map.tni.nl/articles/mult_div_shifts.php Multiplications and divisions on the MSX Assembly Page]&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Division&amp;diff=94628</id>
		<title>Programming:Integer Division</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Division&amp;diff=94628"/>
				<updated>2015-11-16T16:51:46Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: /* 32bit division */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== 8bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' HL=Value1, C=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' L=Value1/Value2, H=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF,BC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        LD B,8&lt;br /&gt;
Div_Next:&lt;br /&gt;
        ADD     HL,HL&lt;br /&gt;
        LD      A,H&lt;br /&gt;
        SUB     C&lt;br /&gt;
        JR      C,Div_NXTB&lt;br /&gt;
        LD      H,A&lt;br /&gt;
        INC     L&lt;br /&gt;
Div_NXTB:&lt;br /&gt;
        DJNZ    Div_Next&lt;br /&gt;
        RET&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 16bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' BC=Value1, DE=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL=Value1/Value2, DE=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF,BC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clcd16  ld a,e&lt;br /&gt;
        or d&lt;br /&gt;
        ld hl,0&lt;br /&gt;
        ret z&lt;br /&gt;
        ld a,b&lt;br /&gt;
        ld b,16&lt;br /&gt;
clcd161 rl c&lt;br /&gt;
        rla&lt;br /&gt;
        adc hl,hl&lt;br /&gt;
        sbc hl,de&lt;br /&gt;
        jr nc,clcd162&lt;br /&gt;
        add hl,de&lt;br /&gt;
clcd162 ccf&lt;br /&gt;
        djnz clcd161&lt;br /&gt;
        ex de,hl&lt;br /&gt;
        rl c&lt;br /&gt;
        rla&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld l,c&lt;br /&gt;
        ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 24bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A,BC=Value1, DE=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL=Value1/Value2, DE=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF,BC,IX,IYL&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clcdiv  db #dd:ld l,e&lt;br /&gt;
        db #dd:ld h,d   ;IX=Value2&lt;br /&gt;
        ld e,a          ;E,BC=Value1(Counter)&lt;br /&gt;
        ld hl,0&lt;br /&gt;
        db #dd:ld a,l&lt;br /&gt;
        db #dd:or h&lt;br /&gt;
        ret z&lt;br /&gt;
        ld d,l          ;D,HL=CalcVar&lt;br /&gt;
        db #fd:ld l,24  ;IYL=Counter&lt;br /&gt;
clcdiv1 rl c&lt;br /&gt;
        rl b&lt;br /&gt;
        rl e&lt;br /&gt;
        rl l&lt;br /&gt;
        rl h&lt;br /&gt;
        rl d&lt;br /&gt;
        ld a,l&lt;br /&gt;
        db #dd:sub l&lt;br /&gt;
        ld l,a&lt;br /&gt;
        ld a,h&lt;br /&gt;
        db #dd:sbc h&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld a,d&lt;br /&gt;
        sbc 0&lt;br /&gt;
        ld d,a          ;D,HL=D,HL-IX&lt;br /&gt;
        jr nc,clcdiv2&lt;br /&gt;
        ld a,l&lt;br /&gt;
        db #dd:add l&lt;br /&gt;
        ld l,a&lt;br /&gt;
        ld a,h&lt;br /&gt;
        db #dd:adc h&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld a,d&lt;br /&gt;
        adc 0&lt;br /&gt;
        ld d,a&lt;br /&gt;
        scf&lt;br /&gt;
clcdiv2 ccf&lt;br /&gt;
        db #fd:dec l&lt;br /&gt;
        jr nz,clcdiv1&lt;br /&gt;
        ex de,hl        ;DE=Value1 MOD Value2&lt;br /&gt;
        rl c&lt;br /&gt;
        rl b&lt;br /&gt;
        ld l,c&lt;br /&gt;
        ld h,b          ;HL=Value1 DIV Value2&lt;br /&gt;
        ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 32bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' IY,BC=Value1, IX=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' IY,BC=Value1/Value2, HL=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF,DE,IY&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' approximately 7800, 1900 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:'''  91 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clcd32c db 0&lt;br /&gt;
clcd32  ld hl,0&lt;br /&gt;
        db #dd:ld a,l&lt;br /&gt;
        db #dd:or h&lt;br /&gt;
        ret z           ;IY,BC=Value1(Counter)&lt;br /&gt;
        ld de,0         ;DE,HL=CalcVar&lt;br /&gt;
        ld a,32         ;Set Counter to 32&lt;br /&gt;
clcd321 ld (clcd32c),a&lt;br /&gt;
        rl c&lt;br /&gt;
        rl b&lt;br /&gt;
        db #fd:ld a,l:rla:db #fd:ld l,a&lt;br /&gt;
        db #fd:ld a,h:rla:db #fd:ld h,a&lt;br /&gt;
        rl l&lt;br /&gt;
        rl h&lt;br /&gt;
        rl e&lt;br /&gt;
        rl d&lt;br /&gt;
        ld a,l&lt;br /&gt;
        db #dd:sub l&lt;br /&gt;
        ld l,a&lt;br /&gt;
        ld a,h&lt;br /&gt;
        db #dd:sbc h&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld a,e&lt;br /&gt;
        sbc 0&lt;br /&gt;
        ld e,a&lt;br /&gt;
        ld a,d&lt;br /&gt;
        sbc 0&lt;br /&gt;
        ld d,a&lt;br /&gt;
        jr nc,clcd322&lt;br /&gt;
        ld a,l&lt;br /&gt;
        db #dd:add l&lt;br /&gt;
        ld l,a&lt;br /&gt;
        ld a,h&lt;br /&gt;
        db #dd:adc h&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld a,e&lt;br /&gt;
        adc 0&lt;br /&gt;
        ld e,a&lt;br /&gt;
        ld a,d&lt;br /&gt;
        adc 0&lt;br /&gt;
        ld d,a&lt;br /&gt;
        scf&lt;br /&gt;
clcd322 ccf&lt;br /&gt;
        ld a,(clcd32c)&lt;br /&gt;
        dec a&lt;br /&gt;
        jr nz,clcd321   ;HL=Value1 MOD Value2&lt;br /&gt;
        rl c&lt;br /&gt;
        rl b&lt;br /&gt;
        db #fd:ld a,l:rla:db #fd:ld l,a&lt;br /&gt;
        db #fd:ld a,h:rla:db #fd:ld h,a&lt;br /&gt;
        ret             ;IY,BC=Value1 DIV Value2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast 32bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' HL,DE=Value1, BC=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' BCDE=Value1/Value2, HL=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF&lt;br /&gt;
&lt;br /&gt;
'''Not used:''' IX, IY&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 1080-2572 (1826 on average), 270-643 usec (456 on average)&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 261 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
div_r macro&lt;br /&gt;
     local t2&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     ADD   HL, HL&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     ADC   HL, HL&lt;br /&gt;
&lt;br /&gt;
     LD    A, L&lt;br /&gt;
     ADD   A, C&lt;br /&gt;
     LD    A, H&lt;br /&gt;
     ADC   A, B&lt;br /&gt;
     JR    NC, t2&lt;br /&gt;
&lt;br /&gt;
     ADD   HL, BC&lt;br /&gt;
     INC   DE&lt;br /&gt;
t2&lt;br /&gt;
     endm&lt;br /&gt;
div_e macro&lt;br /&gt;
     local t1,t2&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     ADD   HL, HL&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     ADC   HL, HL&lt;br /&gt;
     JR    C, t1&lt;br /&gt;
&lt;br /&gt;
     LD    A, L&lt;br /&gt;
     ADD   A, C&lt;br /&gt;
     LD    A, H&lt;br /&gt;
     ADC   A, B&lt;br /&gt;
     JR    NC, t2&lt;br /&gt;
t1&lt;br /&gt;
     ADD   HL, BC&lt;br /&gt;
     INC   DE&lt;br /&gt;
t2&lt;br /&gt;
     endm&lt;br /&gt;
div32x16 proc  ; BCDE = HLDE/BC, HL = HLDE%BC&lt;br /&gt;
     local DIV16, DIV32R, DIV32E&lt;br /&gt;
     DEC   BC&lt;br /&gt;
     LD    A, B&lt;br /&gt;
     CPL &lt;br /&gt;
     LD    B, A&lt;br /&gt;
     LD    A, C&lt;br /&gt;
     CPL &lt;br /&gt;
     LD    C, A&lt;br /&gt;
     ADD   A, L&lt;br /&gt;
     LD    A, B&lt;br /&gt;
     ADC   A, H&lt;br /&gt;
     JR    NC, DIV16&lt;br /&gt;
&lt;br /&gt;
     PUSH  DE&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     LD    HL, 0000&lt;br /&gt;
     CALL  DIV32R&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     EX    (SP), HL&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     CALL  DIV32E&lt;br /&gt;
     POP   BC&lt;br /&gt;
     RET&lt;br /&gt;
DIV16&lt;br /&gt;
     CALL  DIV32E&lt;br /&gt;
     LD    BC, 0000&lt;br /&gt;
     RET&lt;br /&gt;
DIV32R   ; DE = HLDE/(-BC), HL = HLDE%(-BC), -BC &amp;lt; $8000&lt;br /&gt;
     CALL  $+3&lt;br /&gt;
     rept 8&lt;br /&gt;
     div_r&lt;br /&gt;
     endm&lt;br /&gt;
     RET&lt;br /&gt;
DIV32E   ; DE = HLDE/(-BC), HL = HLDE%(-BC)&lt;br /&gt;
     CALL  $+3&lt;br /&gt;
     rept 8&lt;br /&gt;
     div_e&lt;br /&gt;
     endm&lt;br /&gt;
     RET&lt;br /&gt;
     endp &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.smspower.org/Development/DivMod Division implementation for the Sega Master System]&lt;br /&gt;
* [http://map.tni.nl/articles/mult_div_shifts.php Multiplications and divisions on the MSX Assembly Page]&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Division&amp;diff=94627</id>
		<title>Programming:Integer Division</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Division&amp;diff=94627"/>
				<updated>2015-11-16T16:47:21Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: /* Fast 32bit division */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== 8bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' HL=Value1, C=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' L=Value1/Value2, H=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF,BC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        LD B,8&lt;br /&gt;
Div_Next:&lt;br /&gt;
        ADD     HL,HL&lt;br /&gt;
        LD      A,H&lt;br /&gt;
        SUB     C&lt;br /&gt;
        JR      C,Div_NXTB&lt;br /&gt;
        LD      H,A&lt;br /&gt;
        INC     L&lt;br /&gt;
Div_NXTB:&lt;br /&gt;
        DJNZ    Div_Next&lt;br /&gt;
        RET&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 16bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' BC=Value1, DE=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL=Value1/Value2, DE=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF,BC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clcd16  ld a,e&lt;br /&gt;
        or d&lt;br /&gt;
        ld hl,0&lt;br /&gt;
        ret z&lt;br /&gt;
        ld a,b&lt;br /&gt;
        ld b,16&lt;br /&gt;
clcd161 rl c&lt;br /&gt;
        rla&lt;br /&gt;
        adc hl,hl&lt;br /&gt;
        sbc hl,de&lt;br /&gt;
        jr nc,clcd162&lt;br /&gt;
        add hl,de&lt;br /&gt;
clcd162 ccf&lt;br /&gt;
        djnz clcd161&lt;br /&gt;
        ex de,hl&lt;br /&gt;
        rl c&lt;br /&gt;
        rla&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld l,c&lt;br /&gt;
        ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 24bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A,BC=Value1, DE=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL=Value1/Value2, DE=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF,BC,IX,IYL&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clcdiv  db #dd:ld l,e&lt;br /&gt;
        db #dd:ld h,d   ;IX=Value2&lt;br /&gt;
        ld e,a          ;E,BC=Value1(Counter)&lt;br /&gt;
        ld hl,0&lt;br /&gt;
        db #dd:ld a,l&lt;br /&gt;
        db #dd:or h&lt;br /&gt;
        ret z&lt;br /&gt;
        ld d,l          ;D,HL=CalcVar&lt;br /&gt;
        db #fd:ld l,24  ;IYL=Counter&lt;br /&gt;
clcdiv1 rl c&lt;br /&gt;
        rl b&lt;br /&gt;
        rl e&lt;br /&gt;
        rl l&lt;br /&gt;
        rl h&lt;br /&gt;
        rl d&lt;br /&gt;
        ld a,l&lt;br /&gt;
        db #dd:sub l&lt;br /&gt;
        ld l,a&lt;br /&gt;
        ld a,h&lt;br /&gt;
        db #dd:sbc h&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld a,d&lt;br /&gt;
        sbc 0&lt;br /&gt;
        ld d,a          ;D,HL=D,HL-IX&lt;br /&gt;
        jr nc,clcdiv2&lt;br /&gt;
        ld a,l&lt;br /&gt;
        db #dd:add l&lt;br /&gt;
        ld l,a&lt;br /&gt;
        ld a,h&lt;br /&gt;
        db #dd:adc h&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld a,d&lt;br /&gt;
        adc 0&lt;br /&gt;
        ld d,a&lt;br /&gt;
        scf&lt;br /&gt;
clcdiv2 ccf&lt;br /&gt;
        db #fd:dec l&lt;br /&gt;
        jr nz,clcdiv1&lt;br /&gt;
        ex de,hl        ;DE=Value1 MOD Value2&lt;br /&gt;
        rl c&lt;br /&gt;
        rl b&lt;br /&gt;
        ld l,c&lt;br /&gt;
        ld h,b          ;HL=Value1 DIV Value2&lt;br /&gt;
        ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 32bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' IY,BC=Value1, IX=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' IY,BC=Value1/Value2, HL=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF,DE,IY&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clcd32c db 0&lt;br /&gt;
clcd32  ld hl,0&lt;br /&gt;
        db #dd:ld a,l&lt;br /&gt;
        db #dd:or h&lt;br /&gt;
        ret z           ;IY,BC=Value1(Counter)&lt;br /&gt;
        ld de,0         ;DE,HL=CalcVar&lt;br /&gt;
        ld a,32         ;Set Counter to 32&lt;br /&gt;
clcd321 ld (clcd32c),a&lt;br /&gt;
        rl c&lt;br /&gt;
        rl b&lt;br /&gt;
        db #fd:ld a,l:rla:db #fd:ld l,a&lt;br /&gt;
        db #fd:ld a,h:rla:db #fd:ld h,a&lt;br /&gt;
        rl l&lt;br /&gt;
        rl h&lt;br /&gt;
        rl e&lt;br /&gt;
        rl d&lt;br /&gt;
        ld a,l&lt;br /&gt;
        db #dd:sub l&lt;br /&gt;
        ld l,a&lt;br /&gt;
        ld a,h&lt;br /&gt;
        db #dd:sbc h&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld a,e&lt;br /&gt;
        sbc 0&lt;br /&gt;
        ld e,a&lt;br /&gt;
        ld a,d&lt;br /&gt;
        sbc 0&lt;br /&gt;
        ld d,a&lt;br /&gt;
        jr nc,clcd322&lt;br /&gt;
        ld a,l&lt;br /&gt;
        db #dd:add l&lt;br /&gt;
        ld l,a&lt;br /&gt;
        ld a,h&lt;br /&gt;
        db #dd:adc h&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld a,e&lt;br /&gt;
        adc 0&lt;br /&gt;
        ld e,a&lt;br /&gt;
        ld a,d&lt;br /&gt;
        adc 0&lt;br /&gt;
        ld d,a&lt;br /&gt;
        scf&lt;br /&gt;
clcd322 ccf&lt;br /&gt;
        ld a,(clcd32c)&lt;br /&gt;
        dec a&lt;br /&gt;
        jr nz,clcd321   ;HL=Value1 MOD Value2&lt;br /&gt;
        rl c&lt;br /&gt;
        rl b&lt;br /&gt;
        db #fd:ld a,l:rla:db #fd:ld l,a&lt;br /&gt;
        db #fd:ld a,h:rla:db #fd:ld h,a&lt;br /&gt;
        ret             ;IY,BC=Value1 DIV Value2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Fast 32bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' HL,DE=Value1, BC=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' BCDE=Value1/Value2, HL=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF&lt;br /&gt;
&lt;br /&gt;
'''Not used:''' IX, IY&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 1080-2572 (1826 on average), 270-643 usec (456 on average)&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 261 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
div_r macro&lt;br /&gt;
     local t2&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     ADD   HL, HL&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     ADC   HL, HL&lt;br /&gt;
&lt;br /&gt;
     LD    A, L&lt;br /&gt;
     ADD   A, C&lt;br /&gt;
     LD    A, H&lt;br /&gt;
     ADC   A, B&lt;br /&gt;
     JR    NC, t2&lt;br /&gt;
&lt;br /&gt;
     ADD   HL, BC&lt;br /&gt;
     INC   DE&lt;br /&gt;
t2&lt;br /&gt;
     endm&lt;br /&gt;
div_e macro&lt;br /&gt;
     local t1,t2&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     ADD   HL, HL&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     ADC   HL, HL&lt;br /&gt;
     JR    C, t1&lt;br /&gt;
&lt;br /&gt;
     LD    A, L&lt;br /&gt;
     ADD   A, C&lt;br /&gt;
     LD    A, H&lt;br /&gt;
     ADC   A, B&lt;br /&gt;
     JR    NC, t2&lt;br /&gt;
t1&lt;br /&gt;
     ADD   HL, BC&lt;br /&gt;
     INC   DE&lt;br /&gt;
t2&lt;br /&gt;
     endm&lt;br /&gt;
div32x16 proc  ; BCDE = HLDE/BC, HL = HLDE%BC&lt;br /&gt;
     local DIV16, DIV32R, DIV32E&lt;br /&gt;
     DEC   BC&lt;br /&gt;
     LD    A, B&lt;br /&gt;
     CPL &lt;br /&gt;
     LD    B, A&lt;br /&gt;
     LD    A, C&lt;br /&gt;
     CPL &lt;br /&gt;
     LD    C, A&lt;br /&gt;
     ADD   A, L&lt;br /&gt;
     LD    A, B&lt;br /&gt;
     ADC   A, H&lt;br /&gt;
     JR    NC, DIV16&lt;br /&gt;
&lt;br /&gt;
     PUSH  DE&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     LD    HL, 0000&lt;br /&gt;
     CALL  DIV32R&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     EX    (SP), HL&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     CALL  DIV32E&lt;br /&gt;
     POP   BC&lt;br /&gt;
     RET&lt;br /&gt;
DIV16&lt;br /&gt;
     CALL  DIV32E&lt;br /&gt;
     LD    BC, 0000&lt;br /&gt;
     RET&lt;br /&gt;
DIV32R   ; DE = HLDE/(-BC), HL = HLDE%(-BC), -BC &amp;lt; $8000&lt;br /&gt;
     CALL  $+3&lt;br /&gt;
     rept 8&lt;br /&gt;
     div_r&lt;br /&gt;
     endm&lt;br /&gt;
     RET&lt;br /&gt;
DIV32E   ; DE = HLDE/(-BC), HL = HLDE%(-BC)&lt;br /&gt;
     CALL  $+3&lt;br /&gt;
     rept 8&lt;br /&gt;
     div_e&lt;br /&gt;
     endm&lt;br /&gt;
     RET&lt;br /&gt;
     endp &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.smspower.org/Development/DivMod Division implementation for the Sega Master System]&lt;br /&gt;
* [http://map.tni.nl/articles/mult_div_shifts.php Multiplications and divisions on the MSX Assembly Page]&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Division&amp;diff=94626</id>
		<title>Programming:Integer Division</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Division&amp;diff=94626"/>
				<updated>2015-11-16T16:31:19Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: /* Fast 32bit division */  correction and additional information is added&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== 8bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' HL=Value1, C=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' L=Value1/Value2, H=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF,BC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        LD B,8&lt;br /&gt;
Div_Next:&lt;br /&gt;
        ADD     HL,HL&lt;br /&gt;
        LD      A,H&lt;br /&gt;
        SUB     C&lt;br /&gt;
        JR      C,Div_NXTB&lt;br /&gt;
        LD      H,A&lt;br /&gt;
        INC     L&lt;br /&gt;
Div_NXTB:&lt;br /&gt;
        DJNZ    Div_Next&lt;br /&gt;
        RET&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 16bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' BC=Value1, DE=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL=Value1/Value2, DE=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF,BC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clcd16  ld a,e&lt;br /&gt;
        or d&lt;br /&gt;
        ld hl,0&lt;br /&gt;
        ret z&lt;br /&gt;
        ld a,b&lt;br /&gt;
        ld b,16&lt;br /&gt;
clcd161 rl c&lt;br /&gt;
        rla&lt;br /&gt;
        adc hl,hl&lt;br /&gt;
        sbc hl,de&lt;br /&gt;
        jr nc,clcd162&lt;br /&gt;
        add hl,de&lt;br /&gt;
clcd162 ccf&lt;br /&gt;
        djnz clcd161&lt;br /&gt;
        ex de,hl&lt;br /&gt;
        rl c&lt;br /&gt;
        rla&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld l,c&lt;br /&gt;
        ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 24bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A,BC=Value1, DE=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL=Value1/Value2, DE=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF,BC,IX,IYL&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clcdiv  db #dd:ld l,e&lt;br /&gt;
        db #dd:ld h,d   ;IX=Value2&lt;br /&gt;
        ld e,a          ;E,BC=Value1(Counter)&lt;br /&gt;
        ld hl,0&lt;br /&gt;
        db #dd:ld a,l&lt;br /&gt;
        db #dd:or h&lt;br /&gt;
        ret z&lt;br /&gt;
        ld d,l          ;D,HL=CalcVar&lt;br /&gt;
        db #fd:ld l,24  ;IYL=Counter&lt;br /&gt;
clcdiv1 rl c&lt;br /&gt;
        rl b&lt;br /&gt;
        rl e&lt;br /&gt;
        rl l&lt;br /&gt;
        rl h&lt;br /&gt;
        rl d&lt;br /&gt;
        ld a,l&lt;br /&gt;
        db #dd:sub l&lt;br /&gt;
        ld l,a&lt;br /&gt;
        ld a,h&lt;br /&gt;
        db #dd:sbc h&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld a,d&lt;br /&gt;
        sbc 0&lt;br /&gt;
        ld d,a          ;D,HL=D,HL-IX&lt;br /&gt;
        jr nc,clcdiv2&lt;br /&gt;
        ld a,l&lt;br /&gt;
        db #dd:add l&lt;br /&gt;
        ld l,a&lt;br /&gt;
        ld a,h&lt;br /&gt;
        db #dd:adc h&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld a,d&lt;br /&gt;
        adc 0&lt;br /&gt;
        ld d,a&lt;br /&gt;
        scf&lt;br /&gt;
clcdiv2 ccf&lt;br /&gt;
        db #fd:dec l&lt;br /&gt;
        jr nz,clcdiv1&lt;br /&gt;
        ex de,hl        ;DE=Value1 MOD Value2&lt;br /&gt;
        rl c&lt;br /&gt;
        rl b&lt;br /&gt;
        ld l,c&lt;br /&gt;
        ld h,b          ;HL=Value1 DIV Value2&lt;br /&gt;
        ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 32bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' IY,BC=Value1, IX=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' IY,BC=Value1/Value2, HL=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF,DE,IY&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clcd32c db 0&lt;br /&gt;
clcd32  ld hl,0&lt;br /&gt;
        db #dd:ld a,l&lt;br /&gt;
        db #dd:or h&lt;br /&gt;
        ret z           ;IY,BC=Value1(Counter)&lt;br /&gt;
        ld de,0         ;DE,HL=CalcVar&lt;br /&gt;
        ld a,32         ;Set Counter to 32&lt;br /&gt;
clcd321 ld (clcd32c),a&lt;br /&gt;
        rl c&lt;br /&gt;
        rl b&lt;br /&gt;
        db #fd:ld a,l:rla:db #fd:ld l,a&lt;br /&gt;
        db #fd:ld a,h:rla:db #fd:ld h,a&lt;br /&gt;
        rl l&lt;br /&gt;
        rl h&lt;br /&gt;
        rl e&lt;br /&gt;
        rl d&lt;br /&gt;
        ld a,l&lt;br /&gt;
        db #dd:sub l&lt;br /&gt;
        ld l,a&lt;br /&gt;
        ld a,h&lt;br /&gt;
        db #dd:sbc h&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld a,e&lt;br /&gt;
        sbc 0&lt;br /&gt;
        ld e,a&lt;br /&gt;
        ld a,d&lt;br /&gt;
        sbc 0&lt;br /&gt;
        ld d,a&lt;br /&gt;
        jr nc,clcd322&lt;br /&gt;
        ld a,l&lt;br /&gt;
        db #dd:add l&lt;br /&gt;
        ld l,a&lt;br /&gt;
        ld a,h&lt;br /&gt;
        db #dd:adc h&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld a,e&lt;br /&gt;
        adc 0&lt;br /&gt;
        ld e,a&lt;br /&gt;
        ld a,d&lt;br /&gt;
        adc 0&lt;br /&gt;
        ld d,a&lt;br /&gt;
        scf&lt;br /&gt;
clcd322 ccf&lt;br /&gt;
        ld a,(clcd32c)&lt;br /&gt;
        dec a&lt;br /&gt;
        jr nz,clcd321   ;HL=Value1 MOD Value2&lt;br /&gt;
        rl c&lt;br /&gt;
        rl b&lt;br /&gt;
        db #fd:ld a,l:rla:db #fd:ld l,a&lt;br /&gt;
        db #fd:ld a,h:rla:db #fd:ld h,a&lt;br /&gt;
        ret             ;IY,BC=Value1 DIV Value2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Fast 32bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' HL,DE=Value1, BC=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' BCDE=Value1/Value2, HL=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF&lt;br /&gt;
&lt;br /&gt;
'''Not used:''' IX, IY&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 1080-2572 (1826 on average), 270-643 usec (456 on average)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
div_r macro&lt;br /&gt;
     local t2&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     ADD   HL, HL&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     ADC   HL, HL&lt;br /&gt;
&lt;br /&gt;
     LD    A, L&lt;br /&gt;
     ADD   A, C&lt;br /&gt;
     LD    A, H&lt;br /&gt;
     ADC   A, B&lt;br /&gt;
     JR    NC, t2&lt;br /&gt;
&lt;br /&gt;
     ADD   HL, BC&lt;br /&gt;
     INC   DE&lt;br /&gt;
t2&lt;br /&gt;
     endm&lt;br /&gt;
div_e macro&lt;br /&gt;
     local t1,t2&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     ADD   HL, HL&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     ADC   HL, HL&lt;br /&gt;
     JR    C, t1&lt;br /&gt;
&lt;br /&gt;
     LD    A, L&lt;br /&gt;
     ADD   A, C&lt;br /&gt;
     LD    A, H&lt;br /&gt;
     ADC   A, B&lt;br /&gt;
     JR    NC, t2&lt;br /&gt;
t1&lt;br /&gt;
     ADD   HL, BC&lt;br /&gt;
     INC   DE&lt;br /&gt;
t2&lt;br /&gt;
     endm&lt;br /&gt;
 div32x16 proc  ; BCDE = HLDE/BC, HL = HLDE%BC&lt;br /&gt;
     local DIV16, DIV32R, DIV32F&lt;br /&gt;
     DEC   BC&lt;br /&gt;
     LD    A, B&lt;br /&gt;
     CPL &lt;br /&gt;
     LD    B, A&lt;br /&gt;
     LD    A, C&lt;br /&gt;
     CPL &lt;br /&gt;
     LD    C, A&lt;br /&gt;
     ADD   A, L&lt;br /&gt;
     LD    A, B&lt;br /&gt;
     ADC   A, H&lt;br /&gt;
     JR    NC, DIV16&lt;br /&gt;
&lt;br /&gt;
     PUSH  DE&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     LD    HL, 0000&lt;br /&gt;
     CALL  DIV32R&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     EX    (SP), HL&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     CALL  DIV32F&lt;br /&gt;
     POP   BC&lt;br /&gt;
     RET&lt;br /&gt;
DIV16&lt;br /&gt;
     CALL  DIV32F&lt;br /&gt;
     LD    BC, 0000&lt;br /&gt;
     RET&lt;br /&gt;
DIV32R   ; DE = HLDE/(-BC), HL = HLDE%(-BC), -BC &amp;lt; $8000&lt;br /&gt;
     CALL  $+3&lt;br /&gt;
     rept 8&lt;br /&gt;
     div_r&lt;br /&gt;
     endm&lt;br /&gt;
     RET&lt;br /&gt;
     endp &lt;br /&gt;
DIV32E   ; DE = HLDE/(-BC), HL = HLDE%(-BC)&lt;br /&gt;
     CALL  $+3&lt;br /&gt;
     rept 8&lt;br /&gt;
     div_e&lt;br /&gt;
     endm&lt;br /&gt;
     RET&lt;br /&gt;
     endp &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.smspower.org/Development/DivMod Division implementation for the Sega Master System]&lt;br /&gt;
* [http://map.tni.nl/articles/mult_div_shifts.php Multiplications and divisions on the MSX Assembly Page]&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Division&amp;diff=94615</id>
		<title>Programming:Integer Division</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Division&amp;diff=94615"/>
				<updated>2015-11-14T15:23:54Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: the new fast division added&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== 8bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' HL=Value1, C=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' L=Value1/Value2, H=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF,BC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        LD B,8&lt;br /&gt;
Div_Next:&lt;br /&gt;
        ADD     HL,HL&lt;br /&gt;
        LD      A,H&lt;br /&gt;
        SUB     C&lt;br /&gt;
        JR      C,Div_NXTB&lt;br /&gt;
        LD      H,A&lt;br /&gt;
        INC     L&lt;br /&gt;
Div_NXTB:&lt;br /&gt;
        DJNZ    Div_Next&lt;br /&gt;
        RET&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 16bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' BC=Value1, DE=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL=Value1/Value2, DE=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF,BC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clcd16  ld a,e&lt;br /&gt;
        or d&lt;br /&gt;
        ld hl,0&lt;br /&gt;
        ret z&lt;br /&gt;
        ld a,b&lt;br /&gt;
        ld b,16&lt;br /&gt;
clcd161 rl c&lt;br /&gt;
        rla&lt;br /&gt;
        adc hl,hl&lt;br /&gt;
        sbc hl,de&lt;br /&gt;
        jr nc,clcd162&lt;br /&gt;
        add hl,de&lt;br /&gt;
clcd162 ccf&lt;br /&gt;
        djnz clcd161&lt;br /&gt;
        ex de,hl&lt;br /&gt;
        rl c&lt;br /&gt;
        rla&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld l,c&lt;br /&gt;
        ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 24bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A,BC=Value1, DE=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL=Value1/Value2, DE=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF,BC,IX,IYL&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clcdiv  db #dd:ld l,e&lt;br /&gt;
        db #dd:ld h,d   ;IX=Value2&lt;br /&gt;
        ld e,a          ;E,BC=Value1(Counter)&lt;br /&gt;
        ld hl,0&lt;br /&gt;
        db #dd:ld a,l&lt;br /&gt;
        db #dd:or h&lt;br /&gt;
        ret z&lt;br /&gt;
        ld d,l          ;D,HL=CalcVar&lt;br /&gt;
        db #fd:ld l,24  ;IYL=Counter&lt;br /&gt;
clcdiv1 rl c&lt;br /&gt;
        rl b&lt;br /&gt;
        rl e&lt;br /&gt;
        rl l&lt;br /&gt;
        rl h&lt;br /&gt;
        rl d&lt;br /&gt;
        ld a,l&lt;br /&gt;
        db #dd:sub l&lt;br /&gt;
        ld l,a&lt;br /&gt;
        ld a,h&lt;br /&gt;
        db #dd:sbc h&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld a,d&lt;br /&gt;
        sbc 0&lt;br /&gt;
        ld d,a          ;D,HL=D,HL-IX&lt;br /&gt;
        jr nc,clcdiv2&lt;br /&gt;
        ld a,l&lt;br /&gt;
        db #dd:add l&lt;br /&gt;
        ld l,a&lt;br /&gt;
        ld a,h&lt;br /&gt;
        db #dd:adc h&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld a,d&lt;br /&gt;
        adc 0&lt;br /&gt;
        ld d,a&lt;br /&gt;
        scf&lt;br /&gt;
clcdiv2 ccf&lt;br /&gt;
        db #fd:dec l&lt;br /&gt;
        jr nz,clcdiv1&lt;br /&gt;
        ex de,hl        ;DE=Value1 MOD Value2&lt;br /&gt;
        rl c&lt;br /&gt;
        rl b&lt;br /&gt;
        ld l,c&lt;br /&gt;
        ld h,b          ;HL=Value1 DIV Value2&lt;br /&gt;
        ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 32bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' IY,BC=Value1, IX=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' IY,BC=Value1/Value2, HL=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF,DE,IY&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clcd32c db 0&lt;br /&gt;
clcd32  ld hl,0&lt;br /&gt;
        db #dd:ld a,l&lt;br /&gt;
        db #dd:or h&lt;br /&gt;
        ret z           ;IY,BC=Value1(Counter)&lt;br /&gt;
        ld de,0         ;DE,HL=CalcVar&lt;br /&gt;
        ld a,32         ;Set Counter to 32&lt;br /&gt;
clcd321 ld (clcd32c),a&lt;br /&gt;
        rl c&lt;br /&gt;
        rl b&lt;br /&gt;
        db #fd:ld a,l:rla:db #fd:ld l,a&lt;br /&gt;
        db #fd:ld a,h:rla:db #fd:ld h,a&lt;br /&gt;
        rl l&lt;br /&gt;
        rl h&lt;br /&gt;
        rl e&lt;br /&gt;
        rl d&lt;br /&gt;
        ld a,l&lt;br /&gt;
        db #dd:sub l&lt;br /&gt;
        ld l,a&lt;br /&gt;
        ld a,h&lt;br /&gt;
        db #dd:sbc h&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld a,e&lt;br /&gt;
        sbc 0&lt;br /&gt;
        ld e,a&lt;br /&gt;
        ld a,d&lt;br /&gt;
        sbc 0&lt;br /&gt;
        ld d,a&lt;br /&gt;
        jr nc,clcd322&lt;br /&gt;
        ld a,l&lt;br /&gt;
        db #dd:add l&lt;br /&gt;
        ld l,a&lt;br /&gt;
        ld a,h&lt;br /&gt;
        db #dd:adc h&lt;br /&gt;
        ld h,a&lt;br /&gt;
        ld a,e&lt;br /&gt;
        adc 0&lt;br /&gt;
        ld e,a&lt;br /&gt;
        ld a,d&lt;br /&gt;
        adc 0&lt;br /&gt;
        ld d,a&lt;br /&gt;
        scf&lt;br /&gt;
clcd322 ccf&lt;br /&gt;
        ld a,(clcd32c)&lt;br /&gt;
        dec a&lt;br /&gt;
        jr nz,clcd321   ;HL=Value1 MOD Value2&lt;br /&gt;
        rl c&lt;br /&gt;
        rl b&lt;br /&gt;
        db #fd:ld a,l:rla:db #fd:ld l,a&lt;br /&gt;
        db #fd:ld a,h:rla:db #fd:ld h,a&lt;br /&gt;
        ret             ;IY,BC=Value1 DIV Value2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Fast 32bit division ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' HL,DE=Value1, BC=Value2&lt;br /&gt;
&lt;br /&gt;
'''Output:''' BCDE=Value1/Value2, HL=Value1 MOD Value2&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' AF&lt;br /&gt;
&lt;br /&gt;
'''Not used:''' IX, IY&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 div macro&lt;br /&gt;
     local t1,t2&lt;br /&gt;
     ADD   HL, HL&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     ADD   HL, HL&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     JP    NC, t1&lt;br /&gt;
&lt;br /&gt;
     INC   HL&lt;br /&gt;
 t1&lt;br /&gt;
     LD    A, L&lt;br /&gt;
     ADD   A, C&lt;br /&gt;
     LD    A, H&lt;br /&gt;
     ADC   A, B&lt;br /&gt;
     JP    NC, t2&lt;br /&gt;
&lt;br /&gt;
     ADD   HL, BC&lt;br /&gt;
     INC   DE&lt;br /&gt;
 t2&lt;br /&gt;
     endm&lt;br /&gt;
&lt;br /&gt;
 div32x16 proc  ; BCDE = HLDE/BC, HL = HLDE%BC&lt;br /&gt;
     local t1, DIV32_, DIV320&lt;br /&gt;
     DEC   BC&lt;br /&gt;
     LD    A, B&lt;br /&gt;
     CPL &lt;br /&gt;
     LD    B, A&lt;br /&gt;
     LD    A, C&lt;br /&gt;
     CPL &lt;br /&gt;
     LD    C, A&lt;br /&gt;
     ADD   A, L&lt;br /&gt;
     LD    A, B&lt;br /&gt;
     ADC   A, H&lt;br /&gt;
     JP    NC, DIV32_&lt;br /&gt;
&lt;br /&gt;
     PUSH  DE&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     LD    HL, 0000&lt;br /&gt;
     CALL  DIV320&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     EX    (SP), HL&lt;br /&gt;
     EX    DE, HL&lt;br /&gt;
     CALL  DIV320&lt;br /&gt;
     POP   BC&lt;br /&gt;
     RET&lt;br /&gt;
 DIV32_&lt;br /&gt;
     CALL  DIV320&lt;br /&gt;
     LD    BC, 0000&lt;br /&gt;
     RET&lt;br /&gt;
 DIV320   ; DE = HLDE/(-BC), HL = HLDE%(-BC)&lt;br /&gt;
     CALL  t1&lt;br /&gt;
 t1&lt;br /&gt;
     rept 8&lt;br /&gt;
     div&lt;br /&gt;
     endm&lt;br /&gt;
     RET&lt;br /&gt;
     endp &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.smspower.org/Development/DivMod Division implementation for the Sega Master System]&lt;br /&gt;
* [http://map.tni.nl/articles/mult_div_shifts.php Multiplications and divisions on the MSX Assembly Page]&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94472</id>
		<title>Programming:Integer Multiplication</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94472"/>
				<updated>2015-10-24T07:47:31Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: /* Fast 8bit * 8bit Unsigned with only 512 bytes of tables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Classic 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' H = ''Multiplier'', E = ''Multiplicand'', L = 0, D = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 188-244 (216 on average) = 47-61 (54) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 33 bytes&lt;br /&gt;
&lt;br /&gt;
The additional clocks and bytes maybe required to set up D and L and for RET.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sla h  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+3&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
jr nc,$+3  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Classic 16bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', DE = ''Multiplicand'', HL = 0, C = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A:HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 212-300 (256 on average) = 53-75 (64) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 47 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add a,a  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+4&lt;br /&gt;
ld h,d&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
rla   ; ...&lt;br /&gt;
jr nc,$+4  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
adc a,c  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast 8bit * 8bit Unsigned (using log / antilog tables) ==&lt;br /&gt;
&lt;br /&gt;
The original routine was written by Jeff Frohwein for the Nintendo Gameboy. You can find it on [http://www.devrs.com/gb/files/logmult.txt Devrs.com].&lt;br /&gt;
&lt;br /&gt;
Because of the usage of log / antilog tables this routine is less accurate, but very fast. It takes advantage of the fact that if you take the log of two numbers, add the results and then take the antilog of the total you have done the equivalent of multiplying the two numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 x^a * x^b = x^(a+b)&lt;br /&gt;
&lt;br /&gt;
 a * b = x^(logx(a) + logx(b))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Input:''' B = ''Multiplier'', C = ''Multiplicant''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 124 = 31 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 1024 bytes (768 bytes for the tables)&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' It is VERY approximate routine, e.g., 0*7=7, 1*28=27, 10*81=790, 100*100=9742, ...&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FastMult:&lt;br /&gt;
  ld      l,c&lt;br /&gt;
  ld      h,&amp;amp;82&lt;br /&gt;
  ld      d,(hl)          ; d = 32 * log_2(c)&lt;br /&gt;
  &lt;br /&gt;
  ld      l,b&lt;br /&gt;
  ld      a,(hl)          ; a = 32 * log_2(b)&lt;br /&gt;
  &lt;br /&gt;
  add     a,d&lt;br /&gt;
  ld      l,a&lt;br /&gt;
  ld      a,0&lt;br /&gt;
  adc     a,0&lt;br /&gt;
  ld      h,a             ; hl = d + a&lt;br /&gt;
  &lt;br /&gt;
  add     hl,hl&lt;br /&gt;
  set     2,h             ; hl = hl + $0400&lt;br /&gt;
  set     7,h             ; hl = hl + &amp;amp;8000&lt;br /&gt;
  &lt;br /&gt;
  ld      e,(hl)&lt;br /&gt;
  inc     hl&lt;br /&gt;
  ld      d,(hl)          ; de = 2^((hl)/32)&lt;br /&gt;
  &lt;br /&gt;
  ret&lt;br /&gt;
&lt;br /&gt;
; 32*Log_2(x) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 TO 255&lt;br /&gt;
;     C=4 &lt;br /&gt;
;     B=2&lt;br /&gt;
;     FOR Z=1 TO 10&lt;br /&gt;
;       IF (2^C) &amp;gt; A THEN C=C-B ELSE C=C+B&lt;br /&gt;
;       B=B/2&lt;br /&gt;
;     NEXT Z&lt;br /&gt;
;     PRINT INT(C*32);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8200&lt;br /&gt;
&lt;br /&gt;
logtable:&lt;br /&gt;
  db 0 , 0 , 32 , 50 , 64 , 74 , 82 , 89 , 96 , 101 , 106 , 110 , 114 , 118 , 121&lt;br /&gt;
  db 125 , 128 , 130 , 133 , 135 , 138 , 140 , 142 , 144 , 146 , 148 , 150 , 152&lt;br /&gt;
  db 153 , 155 , 157 , 158 , 160 , 161 , 162 , 164 , 165 , 166 , 167 , 169 , 170&lt;br /&gt;
  db 171 , 172 , 173 , 174 , 175 , 176 , 177 , 178 , 179 , 180 , 181 , 182 , 183&lt;br /&gt;
  db 184 , 185 , 185 , 186 , 187 , 188 , 189 , 189 , 190 , 191 , 192 , 192 , 193&lt;br /&gt;
  db 194 , 194 , 195 , 196 , 196 , 197 , 198 , 198 , 199 , 199 , 200 , 201 , 201&lt;br /&gt;
  db 202 , 202 , 203 , 204 , 204 , 205 , 205 , 206 , 206 , 207 , 207 , 208 , 208&lt;br /&gt;
  db 209 , 209 , 210 , 210 , 211 , 211 , 212 , 212 , 213 , 213 , 213 , 214 , 214&lt;br /&gt;
  db 215 , 215 , 216 , 216 , 217 , 217 , 217 , 218 , 218 , 219 , 219 , 219 , 220&lt;br /&gt;
  db 220 , 221 , 221 , 221 , 222 , 222 , 222 , 223 , 223 , 224 , 224 , 224 , 225&lt;br /&gt;
  db 225 , 225 , 226 , 226 , 226 , 227 , 227 , 227 , 228 , 228 , 228 , 229 , 229&lt;br /&gt;
  db 229 , 230 , 230 , 230 , 231 , 231 , 231 , 231 , 232 , 232 , 232 , 233 , 233&lt;br /&gt;
  db 233 , 234 , 234 , 234 , 234 , 235 , 235 , 235 , 236 , 236 , 236 , 236 , 237&lt;br /&gt;
  db 237 , 237 , 237 , 238 , 238 , 238 , 238 , 239 , 239 , 239 , 239 , 240 , 240&lt;br /&gt;
  db 240 , 241 , 241 , 241 , 241 , 241 , 242 , 242 , 242 , 242 , 243 , 243 , 243&lt;br /&gt;
  db 243 , 244 , 244 , 244 , 244 , 245 , 245 , 245 , 245 , 245 , 246 , 246 , 246&lt;br /&gt;
  db 246 , 247 , 247 , 247 , 247 , 247 , 248 , 248 , 248 , 248 , 249 , 249 , 249&lt;br /&gt;
  db 249 , 249 , 250 , 250 , 250 , 250 , 250 , 251 , 251 , 251 , 251 , 251 , 252&lt;br /&gt;
  db 252 , 252 , 252 , 252 , 253 , 253 , 253 , 253 , 253 , 253 , 254 , 254 , 254&lt;br /&gt;
  db 254 , 254 , 255 , 255 , 255 , 255 , 255&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; AntiLog 2^(x/32) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 to 510&lt;br /&gt;
;   PRINT INT(2^(A/32)+.5);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8400&lt;br /&gt;
&lt;br /&gt;
antilog:&lt;br /&gt;
  dw 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 , 4&lt;br /&gt;
  dw 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 6&lt;br /&gt;
  dw 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 8 , 9&lt;br /&gt;
  dw 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , 12 , 12 , 12&lt;br /&gt;
  dw 13 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17&lt;br /&gt;
  dw 18 , 18 , 19 , 19 , 19 , 20 , 20 , 21 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25&lt;br /&gt;
  dw 25 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , 30 , 31 , 31 , 32 , 33 , 33 , 34 , 35&lt;br /&gt;
  dw 36 , 36 , 37 , 38 , 39 , 40 , 41 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49&lt;br /&gt;
  dw 50 , 52 , 53 , 54 , 55 , 56 , 57 , 59 , 60 , 61 , 63 , 64 , 65 , 67 , 68 , 70&lt;br /&gt;
  dw 71 , 73 , 74 , 76 , 78 , 79 , 81 , 83 , 85 , 87 , 89 , 91 , 92 , 95 , 97 , 99&lt;br /&gt;
  dw 101 , 103 , 105 , 108 , 110 , 112 , 115 , 117 , 120 , 123 , 125 , 128 , 131&lt;br /&gt;
  dw 134 , 137 , 140 , 143 , 146 , 149 , 152 , 156 , 159 , 162 , 166 , 170 , 173&lt;br /&gt;
  dw 177 , 181 , 185 , 189 , 193 , 197 , 202 , 206 , 211 , 215 , 220 , 225 , 230&lt;br /&gt;
  dw 235 , 240 , 245 , 251 , 256 , 262 , 267 , 273 , 279 , 285 , 292 , 298 , 304&lt;br /&gt;
  dw 311 , 318 , 325 , 332 , 339 , 347 , 354 , 362 , 370 , 378 , 386 , 395 , 403&lt;br /&gt;
  dw 412 , 421 , 431 , 440 , 450 , 459 , 470 , 480 , 490 , 501 , 512 , 523 , 535&lt;br /&gt;
  dw 546 , 558 , 571 , 583 , 596 , 609 , 622 , 636 , 650 , 664 , 679 , 693 , 709&lt;br /&gt;
  dw 724 , 740 , 756 , 773 , 790 , 807 , 825 , 843 , 861 , 880 , 899 , 919 , 939&lt;br /&gt;
  dw 960 , 981 , 1002 , 1024 , 1046 , 1069 , 1093 , 1117 , 1141 , 1166 , 1192&lt;br /&gt;
  dw 1218 , 1244 , 1272 , 1300 , 1328 , 1357 , 1387 , 1417 , 1448 , 1480 , 1512&lt;br /&gt;
  dw 1545 , 1579 , 1614 , 1649 , 1685 , 1722 , 1760 , 1798 , 1838 , 1878 , 1919&lt;br /&gt;
  dw 1961 , 2004 , 2048 , 2093 , 2139 , 2186 , 2233 , 2282 , 2332 , 2383 , 2435&lt;br /&gt;
  dw 2489 , 2543 , 2599 , 2656 , 2714 , 2774 , 2834 , 2896 , 2960 , 3025 , 3091&lt;br /&gt;
  dw 3158 , 3228 , 3298 , 3371 , 3444 , 3520 , 3597 , 3676 , 3756 , 3838 , 3922&lt;br /&gt;
  dw 4008 , 4096 , 4186 , 4277 , 4371 , 4467 , 4565 , 4664 , 4767 , 4871 , 4978&lt;br /&gt;
  dw 5087 , 5198 , 5312 , 5428 , 5547 , 5668 , 5793 , 5919 , 6049 , 6182 , 6317&lt;br /&gt;
  dw 6455 , 6597 , 6741 , 6889 , 7039 , 7194 , 7351 , 7512 , 7677 , 7845 , 8016&lt;br /&gt;
  dw 8192 , 8371 , 8555 , 8742 , 8933 , 9129 , 9329 , 9533 , 9742 , 9955 , 10173&lt;br /&gt;
  dw 10396 , 10624 , 10856 , 11094 , 11337 , 11585 , 11839 , 12098 , 12363 , 12634&lt;br /&gt;
  dw 12910 , 13193 , 13482 , 13777 , 14079 , 14387 , 14702 , 15024 , 15353 , 15689&lt;br /&gt;
  dw 16033 , 16384 , 16743 , 17109 , 17484 , 17867 , 18258 , 18658 , 19066 , 19484&lt;br /&gt;
  dw 19911 , 20347 , 20792 , 21247 , 21713 , 22188 , 22674 , 23170 , 23678 , 24196&lt;br /&gt;
  dw 24726 , 25268 , 25821 , 26386 , 26964 , 27554 , 28158 , 28774 , 29404 , 30048&lt;br /&gt;
  dw 30706 , 31379 , 32066 , 32768 , 33485 , 34219 , 34968 , 35734 , 36516 , 37316&lt;br /&gt;
  dw 38133 , 38968 , 39821 , 40693 , 41584 , 42495 , 43425 , 44376 , 45348 , 46341&lt;br /&gt;
  dw 47356 , 48393 , 49452 , 50535 , 51642 , 52772 , 53928 , 55109 , 56316 , 57549&lt;br /&gt;
  dw  58809 , 60097 , 61413 , 62757&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fastest, accurate 8bit * 8bit Unsigned  with 16 KB tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' L = Multiplier, C = Multiplicand&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 80 = 20 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 14 bytes of code + 16 KB tables&lt;br /&gt;
&lt;br /&gt;
I'm currently working on a new routine, based on a routine by Kirk Meyer [http://www.ticalc.org/pub/86/asm/source/routines/vfmult.asm] which uses nibble multiplication tables.&lt;br /&gt;
&lt;br /&gt;
I have a working, tested version which uses 16K of tables and can perform multiplication in 20&amp;amp;mu;s.&lt;br /&gt;
&lt;br /&gt;
The code to produce the tables is below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp1&lt;br /&gt;
ld a,l&lt;br /&gt;
rla&lt;br /&gt;
and #1e&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp1&lt;br /&gt;
inc h&lt;br /&gt;
.makelp2&lt;br /&gt;
ld a,l&lt;br /&gt;
rra:rra:rra&lt;br /&gt;
and #1e&lt;br /&gt;
jr z,usez&lt;br /&gt;
add restab2 - restab / 256 - 2&lt;br /&gt;
.usez&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp2&lt;br /&gt;
inc h			; restab&lt;br /&gt;
.makelp3&lt;br /&gt;
ld a,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
add l&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,0&lt;br /&gt;
adc d&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h:dec h:dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256 - 2&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
ld b,h&lt;br /&gt;
ld c,l&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp4&lt;br /&gt;
ld e,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
dec h&lt;br /&gt;
ex de,hl&lt;br /&gt;
add hl,hl:add hl,hl:add hl,hl:add hl,hl&lt;br /&gt;
ex de,hl&lt;br /&gt;
ld a,e&lt;br /&gt;
ld (bc),a&lt;br /&gt;
inc b&lt;br /&gt;
ld a,d&lt;br /&gt;
ld (bc),a&lt;br /&gt;
dec b&lt;br /&gt;
inc l&lt;br /&gt;
inc c&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
.restab2&lt;br /&gt;
ds 512 * 15&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code to perform the multiplication (DE = L * C):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ld h,hltab1 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
inc h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(bc)		; 10&lt;br /&gt;
add (hl)		; 12&lt;br /&gt;
ld e,a			; 13&lt;br /&gt;
inc b			; 14&lt;br /&gt;
inc h			; 15&lt;br /&gt;
ld a,(bc)		; 17&lt;br /&gt;
adc (hl)		; 19&lt;br /&gt;
ld d,a			; 20&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast, accurate 8bit * 8bit Unsigned  with 8 KB tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' L = Multiplier, C = Multiplicand&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 100 = 25 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 19 bytes of code + 8 KB tables&lt;br /&gt;
&lt;br /&gt;
16K is a lot of memory to use for tables, but I'm working on a way to reduce this to 8K while maintaining similar performance (around 26&amp;amp;mu;s). The idea is rather than using tables for the low and high nibbles, use tables for alternate bits. So there would be 16 tables for the values #00, #01, #04, #05, #10, #11, #14, #15, #40, #41, #44, #45, #50, #51, #54, #55. The values can be shifted by 1 (rather than 4) to give values for the alternate bits using a simple ADD HL,HL.&lt;br /&gt;
&lt;br /&gt;
This routine should be easy to adapt to a 16bit * 8bit unsigned multiplication or even a 16bit * 16bit, using simple additions.&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 03:58, 8 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
Ok, here is the new 8K routine, first the routine to build the tables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp5&lt;br /&gt;
ld a,l&lt;br /&gt;
ld bc,0&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
ld a,b&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,c&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp5&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp6&lt;br /&gt;
ld (hl),l&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp6&lt;br /&gt;
inc h:inc h&lt;br /&gt;
ld b,2&lt;br /&gt;
.makelp8&lt;br /&gt;
push bc&lt;br /&gt;
xor a&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
.makelp7&lt;br /&gt;
push hl&lt;br /&gt;
push af&lt;br /&gt;
call mulLbyA&lt;br /&gt;
ex de,hl&lt;br /&gt;
pop af&lt;br /&gt;
pop hl&lt;br /&gt;
ld (hl),e&lt;br /&gt;
inc h&lt;br /&gt;
ld (hl),d&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp7&lt;br /&gt;
inc h:inc h&lt;br /&gt;
pop bc&lt;br /&gt;
inc b&lt;br /&gt;
bit 4,b&lt;br /&gt;
jr z,makelp8&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
.mulLbyA	; MAX times	; MIN times&lt;br /&gt;
ld e,l		; 1		; 1&lt;br /&gt;
ld d,0		; 3		; 3&lt;br /&gt;
add a		; 4		; 4&lt;br /&gt;
ld h,a		; 5		; 5&lt;br /&gt;
jr c,ncad0	; 8		; 8&lt;br /&gt;
ld l,d		&lt;br /&gt;
.ncad0&lt;br /&gt;
add hl,hl	; 11		; 11&lt;br /&gt;
jr nc,ncad1	; 13		; 14&lt;br /&gt;
add hl,de	; 16&lt;br /&gt;
.ncad1&lt;br /&gt;
add hl,hl	; 19		; 17&lt;br /&gt;
jr nc,ncad2	; 21		; 20&lt;br /&gt;
add hl,de	; 24&lt;br /&gt;
.ncad2&lt;br /&gt;
add hl,hl	; 27		; 23&lt;br /&gt;
jr nc,ncad3	; 29		; 26&lt;br /&gt;
add hl,de	; 32&lt;br /&gt;
.ncad3&lt;br /&gt;
add hl,hl	; 35		; 29&lt;br /&gt;
jr nc,ncad4	; 37		; 32&lt;br /&gt;
add hl,de	; 40&lt;br /&gt;
.ncad4&lt;br /&gt;
add hl,hl	; 43		; 35&lt;br /&gt;
jr nc,ncad5	; 45		; 38&lt;br /&gt;
add hl,de	; 48&lt;br /&gt;
.ncad5&lt;br /&gt;
add hl,hl	; 51		; 41&lt;br /&gt;
jr nc,ncad6	; 53		; 44&lt;br /&gt;
add hl,de	; 56&lt;br /&gt;
.ncad6&lt;br /&gt;
add hl,hl	; 59		; 47&lt;br /&gt;
ld a,h		; 60		; 48&lt;br /&gt;
ret nc		; 61		; 50?&lt;br /&gt;
add hl,de	; 64&lt;br /&gt;
ld a,h		; 65&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the routine to do the multiplication:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.umultCL		; Using 8 bit only (25us - DE = L * C)&lt;br /&gt;
ld h,hltab2 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
dec h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(hl)		; 10&lt;br /&gt;
add a			; 11&lt;br /&gt;
inc h			; 12&lt;br /&gt;
ld d,(hl)		; 14&lt;br /&gt;
rl d			; 16&lt;br /&gt;
ld h,b			; 17&lt;br /&gt;
add (hl)		; 19&lt;br /&gt;
ld e,a			; 20&lt;br /&gt;
inc h			; 21&lt;br /&gt;
ld a,(hl)		; 23&lt;br /&gt;
adc d			; 24&lt;br /&gt;
ld d,a			; 25&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Very fast 8bit * 8bit Unsigned with only 1K of tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', L = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles''': 104-112 (108 on average) = 26-28 (27) usec&lt;br /&gt;
&lt;br /&gt;
'''Size''': 24 bytes of code and 1024 bytes for the tables&lt;br /&gt;
&lt;br /&gt;
Here's a new routine I've developed which uses the formula ab = ((a + b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - (a - b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) / 4. It's based on a routine for the 6502 by Stephen Judd in a C= Hacking article. Because of differences between the way the 6502 does register indexing it was quite difficult to actually get this working, but it's a great compromise between speed and space since it only uses 1K of tables (as opposed to the 16K or 8K table routines above), and can still manage to do the job in a maximum of 28 microseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Firstly, once again, we need some code to generate the tables. These tables contain values for&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;/4 for 9 bit values of x, with the LSB when bit 8 is zero first followed by the MSB.&lt;br /&gt;
&amp;lt;pre&amp;gt;.gen_sq4&lt;br /&gt;
	xor a&lt;br /&gt;
	ld de,umul_tab + #1ff&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	ld h,d&lt;br /&gt;
	ld l,e&lt;br /&gt;
	inc e&lt;br /&gt;
	ld c,e&lt;br /&gt;
	ld b,2&lt;br /&gt;
&lt;br /&gt;
	.sq4_lp&lt;br /&gt;
	ld a,b&lt;br /&gt;
	cp 2&lt;br /&gt;
	ld a,e&lt;br /&gt;
	rra&lt;br /&gt;
	add (hl)&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	inc h&lt;br /&gt;
	inc d&lt;br /&gt;
	ld a,(hl)&lt;br /&gt;
	adc c&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld h,d&lt;br /&gt;
	inc l&lt;br /&gt;
	inc e&lt;br /&gt;
	jr nz,sq4_lp&lt;br /&gt;
	inc d&lt;br /&gt;
	inc d&lt;br /&gt;
	djnz sq4_lp&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
align #100&lt;br /&gt;
.umul_tab ds #400&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now for the actual multiply routine:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ld h,umul_tab_lo / #100	; 2&lt;br /&gt;
	ld b,h			; 3&lt;br /&gt;
	add l			; 4&lt;br /&gt;
	ld c,a			; 5&lt;br /&gt;
	jr nc,@noovf		; 7&lt;br /&gt;
	inc b			; 8&lt;br /&gt;
	inc b			; 9&lt;br /&gt;
.@noovf&lt;br /&gt;
	sub l			; 10&lt;br /&gt;
	sub l			; 11&lt;br /&gt;
	jr nc,@noneg		; 13&lt;br /&gt;
	neg			; 15&lt;br /&gt;
.@noneg&lt;br /&gt;
	ld l,a			; 16&lt;br /&gt;
	ld a,(bc)		; 18&lt;br /&gt;
	sub (hl)		; 20&lt;br /&gt;
	ld e,a			; 21&lt;br /&gt;
	inc b			; 22&lt;br /&gt;
	inc h			; 23&lt;br /&gt;
	ld a,(bc)		; 25&lt;br /&gt;
	sbc (hl)		; 27&lt;br /&gt;
	ld d,a			; 28&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This code could easily be converted to a macro as it's only 24 bytes. I've tried to optimize it further but with no luck!&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 06:25, 4 April 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Fast 8bit * 8bit Unsigned with only 512 bytes of tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input''': A = Multiplier, B = Multiplicant&lt;br /&gt;
&lt;br /&gt;
'''Output''': A:E = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles''': 136-172 (154 on average) = 34-43 (38.5) usec&lt;br /&gt;
&lt;br /&gt;
'''Size''': 44 bytes of code and 512 bytes for the tables&lt;br /&gt;
&lt;br /&gt;
Fast 8 bit unsigned multiplication with 16 bit result. It uses formula&lt;br /&gt;
&amp;lt;br&amp;gt;x*y = ((x+y)/2)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - ((x-y)/2)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;, if x+y is even&lt;br /&gt;
&amp;lt;br&amp;gt;      = ((x+y-1)/2)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - ((x-y-1)/2)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; + y, if x+y is odd and x&amp;gt;=y&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;    cp b&lt;br /&gt;
    jr nc,l1&lt;br /&gt;
&lt;br /&gt;
    ld e,a&lt;br /&gt;
    ld a,b&lt;br /&gt;
    ld b,e&lt;br /&gt;
&lt;br /&gt;
l1  ld c,a&lt;br /&gt;
    sub b&lt;br /&gt;
    rra&lt;br /&gt;
    ld d,a&lt;br /&gt;
    ld a,c&lt;br /&gt;
    add a,b&lt;br /&gt;
    rra&lt;br /&gt;
    ld l,a&lt;br /&gt;
    ld h,high(sqrlo)&lt;br /&gt;
    ld a,(hl)&lt;br /&gt;
    ld e,l&lt;br /&gt;
    ld l,d&lt;br /&gt;
    jr nc,l2&lt;br /&gt;
&lt;br /&gt;
    sub (hl)   ;odd&lt;br /&gt;
    ld l,e&lt;br /&gt;
    ld e,a&lt;br /&gt;
    inc h      ;loads high(sqrhi)&lt;br /&gt;
    ld a,(hl)&lt;br /&gt;
    ld l,d&lt;br /&gt;
    sbc a,(hl)&lt;br /&gt;
    ld d,a&lt;br /&gt;
&lt;br /&gt;
    ld a,e&lt;br /&gt;
    add a,b&lt;br /&gt;
    ld e,a&lt;br /&gt;
    ld a,d&lt;br /&gt;
    adc a,0&lt;br /&gt;
    ret&lt;br /&gt;
&lt;br /&gt;
l2  sub (hl)   ;even&lt;br /&gt;
    ld l,e&lt;br /&gt;
    ld e,a&lt;br /&gt;
    inc h&lt;br /&gt;
    ld a,(hl)&lt;br /&gt;
    ld l,d&lt;br /&gt;
    sbc a,(hl)&lt;br /&gt;
    ret&lt;br /&gt;
&lt;br /&gt;
sqrlo ;low(x*x)   should be at the page border&lt;br /&gt;
    db 0,1,4,9,$10,$19,$24,$31,$40,$51,$64,$79,$90,$a9,$c4,$e1&lt;br /&gt;
    db 0,$21,$44,$69,$90,$b9,$e4,$11,$40,$71,$a4,$d9,$10,$49,$84,$c1&lt;br /&gt;
    db 0,$41,$84,$c9,$10,$59,$a4,$f1,$40,$91,$e4,$39,$90,$e9,$44,$a1&lt;br /&gt;
    db 0,$61,$c4,$29,$90,$f9,$64,$d1,$40,$b1,$24,$99,$10,$89,4,$81&lt;br /&gt;
    db 0,$81,4,$89,$10,$99,$24,$b1,$40,$d1,$64,$f9,$90,$29,$c4,$61&lt;br /&gt;
    db 0,$a1,$44,$e9,$90,$39,$e4,$91,$40,$f1,$a4,$59,$10,$c9,$84,$41&lt;br /&gt;
    db 0,$c1,$84,$49,$10,$d9,$a4,$71,$40,$11,$e4,$b9,$90,$69,$44,$21&lt;br /&gt;
    db 0,$e1,$c4,$a9,$90,$79,$64,$51,$40,$31,$24,$19,$10,9,4,$1&lt;br /&gt;
    db 0,1,4,9,$10,$19,$24,$31,$40,$51,$64,$79,$90,$a9,$c4,$e1&lt;br /&gt;
    db 0,$21,$44,$69,$90,$b9,$e4,$11,$40,$71,$a4,$d9,$10,$49,$84,$c1&lt;br /&gt;
    db 0,$41,$84,$c9,$10,$59,$a4,$f1,$40,$91,$e4,$39,$90,$e9,$44,$a1&lt;br /&gt;
    db 0,$61,$c4,$29,$90,$f9,$64,$d1,$40,$b1,$24,$99,$10,$89,4,$81&lt;br /&gt;
    db 0,$81,4,$89,$10,$99,$24,$b1,$40,$d1,$64,$f9,$90,$29,$c4,$61&lt;br /&gt;
    db 0,$a1,$44,$e9,$90,$39,$e4,$91,$40,$f1,$a4,$59,$10,$c9,$84,$41&lt;br /&gt;
    db 0,$c1,$84,$49,$10,$d9,$a4,$71,$40,$11,$e4,$b9,$90,$69,$44,$21&lt;br /&gt;
    db 0,$e1,$c4,$a9,$90,$79,$64,$51,$40,$31,$24,$19,$10,9,4,$1&lt;br /&gt;
sqrhi ;high(x*x)&lt;br /&gt;
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
    db 1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3&lt;br /&gt;
    db 4,4,4,4,5,5,5,5,6,6,6,7,7,7,8,8&lt;br /&gt;
    db 9,9,9,$a,$a,$a,$b,$b,$c,$c,$d,$d,$e,$e,$f,$f&lt;br /&gt;
    db $10,$10,$11,$11,$12,$12,$13,$13,$14,$14,$15,$15,$16,$17,$17,$18&lt;br /&gt;
    db $19,$19,$1a,$1a,$1b,$1c,$1c,$1d,$1e,$1e,$1f,$20,$21,$21,$22,$23&lt;br /&gt;
    db $24,$24,$25,$26,$27,$27,$28,$29,$2a,$2b,$2b,$2c,$2d,$2e,$2f,$30&lt;br /&gt;
    db $31,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f&lt;br /&gt;
    db $40,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f&lt;br /&gt;
    db $51,$52,$53,$54,$55,$56,$57,$59,$5a,$5b,$5c,$5d,$5f,$60,$61,$62&lt;br /&gt;
    db $64,$65,$66,$67,$69,$6a,$6b,$6c,$6e,$6f,$70,$72,$73,$74,$76,$77&lt;br /&gt;
    db $79,$7a,$7b,$7d,$7e,$7f,$81,$82,$84,$85,$87,$88,$8a,$8b,$8d,$8e&lt;br /&gt;
    db $90,$91,$93,$94,$96,$97,$99,$9a,$9c,$9d,$9f,$a0,$a2,$a4,$a5,$a7&lt;br /&gt;
    db $a9,$aa,$ac,$ad,$af,$b1,$b2,$b4,$b6,$b7,$b9,$bb,$bd,$be,$c0,$c2&lt;br /&gt;
    db $c4,$c5,$c7,$c9,$cb,$cc,$ce,$d0,$d2,$d4,$d5,$d7,$d9,$db,$dd,$df&lt;br /&gt;
    db $e1,$e2,$e4,$e6,$e8,$ea,$ec,$ee,$f0,$f2,$f4,$f6,$f8,$fa,$fc,$fe&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[User:Litwr|Litwr]] 10:25, 24 October 2015 (CEST)&lt;br /&gt;
&lt;br /&gt;
== 16bit * 16bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' BC = ''Multiplier'', DE = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A,HL = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;ld ix,0&lt;br /&gt;
 ld hl,0&lt;br /&gt;
.mul24b1:&lt;br /&gt;
 ld a,c&lt;br /&gt;
 or b&lt;br /&gt;
 jr z,mul24b3&lt;br /&gt;
 srl b&lt;br /&gt;
 rr c&lt;br /&gt;
 jr nc,mul24b2&lt;br /&gt;
 add ix,de&lt;br /&gt;
 ld a,h&lt;br /&gt;
 adc l&lt;br /&gt;
 ld h,a&lt;br /&gt;
.mul24b2:&lt;br /&gt;
 sla e&lt;br /&gt;
 rl d&lt;br /&gt;
 rl l&lt;br /&gt;
 jr mul24b1:&lt;br /&gt;
.mul24b3:&lt;br /&gt;
 ld a,h&lt;br /&gt;
 db #dd:ld e,l&lt;br /&gt;
 db #dd:ld d,h&lt;br /&gt;
 ex de,hl&lt;br /&gt;
 ret&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://map.tni.nl/articles/mult_div_shifts.php Multiplications and divisions on the MSX Assembly Page]&lt;br /&gt;
* [http://www.mccw.hetlab.tk/92/Multiplication/en.html &amp;quot;Multiplication on a Z80&amp;quot; ( MSX Computer &amp;amp; Club Webmagazine)]&lt;br /&gt;
* [http://www.andreadrian.de/oldcpu/Z80_number_cruncher.html The Z80 number cruncher (Andre Adrian)] (16/32bit multiplication, addition, right shift)&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94471</id>
		<title>Programming:Integer Multiplication</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94471"/>
				<updated>2015-10-24T07:41:18Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: /* Fast 8bit * 8bit Unsigned with only 512 bytes of tables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Classic 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' H = ''Multiplier'', E = ''Multiplicand'', L = 0, D = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 188-244 (216 on average) = 47-61 (54) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 33 bytes&lt;br /&gt;
&lt;br /&gt;
The additional clocks and bytes maybe required to set up D and L and for RET.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sla h  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+3&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
jr nc,$+3  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Classic 16bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', DE = ''Multiplicand'', HL = 0, C = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A:HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 212-300 (256 on average) = 53-75 (64) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 47 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add a,a  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+4&lt;br /&gt;
ld h,d&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
rla   ; ...&lt;br /&gt;
jr nc,$+4  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
adc a,c  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast 8bit * 8bit Unsigned (using log / antilog tables) ==&lt;br /&gt;
&lt;br /&gt;
The original routine was written by Jeff Frohwein for the Nintendo Gameboy. You can find it on [http://www.devrs.com/gb/files/logmult.txt Devrs.com].&lt;br /&gt;
&lt;br /&gt;
Because of the usage of log / antilog tables this routine is less accurate, but very fast. It takes advantage of the fact that if you take the log of two numbers, add the results and then take the antilog of the total you have done the equivalent of multiplying the two numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 x^a * x^b = x^(a+b)&lt;br /&gt;
&lt;br /&gt;
 a * b = x^(logx(a) + logx(b))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Input:''' B = ''Multiplier'', C = ''Multiplicant''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 124 = 31 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 1024 bytes (768 bytes for the tables)&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' It is VERY approximate routine, e.g., 0*7=7, 1*28=27, 10*81=790, 100*100=9742, ...&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FastMult:&lt;br /&gt;
  ld      l,c&lt;br /&gt;
  ld      h,&amp;amp;82&lt;br /&gt;
  ld      d,(hl)          ; d = 32 * log_2(c)&lt;br /&gt;
  &lt;br /&gt;
  ld      l,b&lt;br /&gt;
  ld      a,(hl)          ; a = 32 * log_2(b)&lt;br /&gt;
  &lt;br /&gt;
  add     a,d&lt;br /&gt;
  ld      l,a&lt;br /&gt;
  ld      a,0&lt;br /&gt;
  adc     a,0&lt;br /&gt;
  ld      h,a             ; hl = d + a&lt;br /&gt;
  &lt;br /&gt;
  add     hl,hl&lt;br /&gt;
  set     2,h             ; hl = hl + $0400&lt;br /&gt;
  set     7,h             ; hl = hl + &amp;amp;8000&lt;br /&gt;
  &lt;br /&gt;
  ld      e,(hl)&lt;br /&gt;
  inc     hl&lt;br /&gt;
  ld      d,(hl)          ; de = 2^((hl)/32)&lt;br /&gt;
  &lt;br /&gt;
  ret&lt;br /&gt;
&lt;br /&gt;
; 32*Log_2(x) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 TO 255&lt;br /&gt;
;     C=4 &lt;br /&gt;
;     B=2&lt;br /&gt;
;     FOR Z=1 TO 10&lt;br /&gt;
;       IF (2^C) &amp;gt; A THEN C=C-B ELSE C=C+B&lt;br /&gt;
;       B=B/2&lt;br /&gt;
;     NEXT Z&lt;br /&gt;
;     PRINT INT(C*32);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8200&lt;br /&gt;
&lt;br /&gt;
logtable:&lt;br /&gt;
  db 0 , 0 , 32 , 50 , 64 , 74 , 82 , 89 , 96 , 101 , 106 , 110 , 114 , 118 , 121&lt;br /&gt;
  db 125 , 128 , 130 , 133 , 135 , 138 , 140 , 142 , 144 , 146 , 148 , 150 , 152&lt;br /&gt;
  db 153 , 155 , 157 , 158 , 160 , 161 , 162 , 164 , 165 , 166 , 167 , 169 , 170&lt;br /&gt;
  db 171 , 172 , 173 , 174 , 175 , 176 , 177 , 178 , 179 , 180 , 181 , 182 , 183&lt;br /&gt;
  db 184 , 185 , 185 , 186 , 187 , 188 , 189 , 189 , 190 , 191 , 192 , 192 , 193&lt;br /&gt;
  db 194 , 194 , 195 , 196 , 196 , 197 , 198 , 198 , 199 , 199 , 200 , 201 , 201&lt;br /&gt;
  db 202 , 202 , 203 , 204 , 204 , 205 , 205 , 206 , 206 , 207 , 207 , 208 , 208&lt;br /&gt;
  db 209 , 209 , 210 , 210 , 211 , 211 , 212 , 212 , 213 , 213 , 213 , 214 , 214&lt;br /&gt;
  db 215 , 215 , 216 , 216 , 217 , 217 , 217 , 218 , 218 , 219 , 219 , 219 , 220&lt;br /&gt;
  db 220 , 221 , 221 , 221 , 222 , 222 , 222 , 223 , 223 , 224 , 224 , 224 , 225&lt;br /&gt;
  db 225 , 225 , 226 , 226 , 226 , 227 , 227 , 227 , 228 , 228 , 228 , 229 , 229&lt;br /&gt;
  db 229 , 230 , 230 , 230 , 231 , 231 , 231 , 231 , 232 , 232 , 232 , 233 , 233&lt;br /&gt;
  db 233 , 234 , 234 , 234 , 234 , 235 , 235 , 235 , 236 , 236 , 236 , 236 , 237&lt;br /&gt;
  db 237 , 237 , 237 , 238 , 238 , 238 , 238 , 239 , 239 , 239 , 239 , 240 , 240&lt;br /&gt;
  db 240 , 241 , 241 , 241 , 241 , 241 , 242 , 242 , 242 , 242 , 243 , 243 , 243&lt;br /&gt;
  db 243 , 244 , 244 , 244 , 244 , 245 , 245 , 245 , 245 , 245 , 246 , 246 , 246&lt;br /&gt;
  db 246 , 247 , 247 , 247 , 247 , 247 , 248 , 248 , 248 , 248 , 249 , 249 , 249&lt;br /&gt;
  db 249 , 249 , 250 , 250 , 250 , 250 , 250 , 251 , 251 , 251 , 251 , 251 , 252&lt;br /&gt;
  db 252 , 252 , 252 , 252 , 253 , 253 , 253 , 253 , 253 , 253 , 254 , 254 , 254&lt;br /&gt;
  db 254 , 254 , 255 , 255 , 255 , 255 , 255&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; AntiLog 2^(x/32) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 to 510&lt;br /&gt;
;   PRINT INT(2^(A/32)+.5);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8400&lt;br /&gt;
&lt;br /&gt;
antilog:&lt;br /&gt;
  dw 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 , 4&lt;br /&gt;
  dw 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 6&lt;br /&gt;
  dw 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 8 , 9&lt;br /&gt;
  dw 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , 12 , 12 , 12&lt;br /&gt;
  dw 13 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17&lt;br /&gt;
  dw 18 , 18 , 19 , 19 , 19 , 20 , 20 , 21 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25&lt;br /&gt;
  dw 25 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , 30 , 31 , 31 , 32 , 33 , 33 , 34 , 35&lt;br /&gt;
  dw 36 , 36 , 37 , 38 , 39 , 40 , 41 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49&lt;br /&gt;
  dw 50 , 52 , 53 , 54 , 55 , 56 , 57 , 59 , 60 , 61 , 63 , 64 , 65 , 67 , 68 , 70&lt;br /&gt;
  dw 71 , 73 , 74 , 76 , 78 , 79 , 81 , 83 , 85 , 87 , 89 , 91 , 92 , 95 , 97 , 99&lt;br /&gt;
  dw 101 , 103 , 105 , 108 , 110 , 112 , 115 , 117 , 120 , 123 , 125 , 128 , 131&lt;br /&gt;
  dw 134 , 137 , 140 , 143 , 146 , 149 , 152 , 156 , 159 , 162 , 166 , 170 , 173&lt;br /&gt;
  dw 177 , 181 , 185 , 189 , 193 , 197 , 202 , 206 , 211 , 215 , 220 , 225 , 230&lt;br /&gt;
  dw 235 , 240 , 245 , 251 , 256 , 262 , 267 , 273 , 279 , 285 , 292 , 298 , 304&lt;br /&gt;
  dw 311 , 318 , 325 , 332 , 339 , 347 , 354 , 362 , 370 , 378 , 386 , 395 , 403&lt;br /&gt;
  dw 412 , 421 , 431 , 440 , 450 , 459 , 470 , 480 , 490 , 501 , 512 , 523 , 535&lt;br /&gt;
  dw 546 , 558 , 571 , 583 , 596 , 609 , 622 , 636 , 650 , 664 , 679 , 693 , 709&lt;br /&gt;
  dw 724 , 740 , 756 , 773 , 790 , 807 , 825 , 843 , 861 , 880 , 899 , 919 , 939&lt;br /&gt;
  dw 960 , 981 , 1002 , 1024 , 1046 , 1069 , 1093 , 1117 , 1141 , 1166 , 1192&lt;br /&gt;
  dw 1218 , 1244 , 1272 , 1300 , 1328 , 1357 , 1387 , 1417 , 1448 , 1480 , 1512&lt;br /&gt;
  dw 1545 , 1579 , 1614 , 1649 , 1685 , 1722 , 1760 , 1798 , 1838 , 1878 , 1919&lt;br /&gt;
  dw 1961 , 2004 , 2048 , 2093 , 2139 , 2186 , 2233 , 2282 , 2332 , 2383 , 2435&lt;br /&gt;
  dw 2489 , 2543 , 2599 , 2656 , 2714 , 2774 , 2834 , 2896 , 2960 , 3025 , 3091&lt;br /&gt;
  dw 3158 , 3228 , 3298 , 3371 , 3444 , 3520 , 3597 , 3676 , 3756 , 3838 , 3922&lt;br /&gt;
  dw 4008 , 4096 , 4186 , 4277 , 4371 , 4467 , 4565 , 4664 , 4767 , 4871 , 4978&lt;br /&gt;
  dw 5087 , 5198 , 5312 , 5428 , 5547 , 5668 , 5793 , 5919 , 6049 , 6182 , 6317&lt;br /&gt;
  dw 6455 , 6597 , 6741 , 6889 , 7039 , 7194 , 7351 , 7512 , 7677 , 7845 , 8016&lt;br /&gt;
  dw 8192 , 8371 , 8555 , 8742 , 8933 , 9129 , 9329 , 9533 , 9742 , 9955 , 10173&lt;br /&gt;
  dw 10396 , 10624 , 10856 , 11094 , 11337 , 11585 , 11839 , 12098 , 12363 , 12634&lt;br /&gt;
  dw 12910 , 13193 , 13482 , 13777 , 14079 , 14387 , 14702 , 15024 , 15353 , 15689&lt;br /&gt;
  dw 16033 , 16384 , 16743 , 17109 , 17484 , 17867 , 18258 , 18658 , 19066 , 19484&lt;br /&gt;
  dw 19911 , 20347 , 20792 , 21247 , 21713 , 22188 , 22674 , 23170 , 23678 , 24196&lt;br /&gt;
  dw 24726 , 25268 , 25821 , 26386 , 26964 , 27554 , 28158 , 28774 , 29404 , 30048&lt;br /&gt;
  dw 30706 , 31379 , 32066 , 32768 , 33485 , 34219 , 34968 , 35734 , 36516 , 37316&lt;br /&gt;
  dw 38133 , 38968 , 39821 , 40693 , 41584 , 42495 , 43425 , 44376 , 45348 , 46341&lt;br /&gt;
  dw 47356 , 48393 , 49452 , 50535 , 51642 , 52772 , 53928 , 55109 , 56316 , 57549&lt;br /&gt;
  dw  58809 , 60097 , 61413 , 62757&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fastest, accurate 8bit * 8bit Unsigned  with 16 KB tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' L = Multiplier, C = Multiplicand&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 80 = 20 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 14 bytes of code + 16 KB tables&lt;br /&gt;
&lt;br /&gt;
I'm currently working on a new routine, based on a routine by Kirk Meyer [http://www.ticalc.org/pub/86/asm/source/routines/vfmult.asm] which uses nibble multiplication tables.&lt;br /&gt;
&lt;br /&gt;
I have a working, tested version which uses 16K of tables and can perform multiplication in 20&amp;amp;mu;s.&lt;br /&gt;
&lt;br /&gt;
The code to produce the tables is below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp1&lt;br /&gt;
ld a,l&lt;br /&gt;
rla&lt;br /&gt;
and #1e&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp1&lt;br /&gt;
inc h&lt;br /&gt;
.makelp2&lt;br /&gt;
ld a,l&lt;br /&gt;
rra:rra:rra&lt;br /&gt;
and #1e&lt;br /&gt;
jr z,usez&lt;br /&gt;
add restab2 - restab / 256 - 2&lt;br /&gt;
.usez&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp2&lt;br /&gt;
inc h			; restab&lt;br /&gt;
.makelp3&lt;br /&gt;
ld a,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
add l&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,0&lt;br /&gt;
adc d&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h:dec h:dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256 - 2&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
ld b,h&lt;br /&gt;
ld c,l&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp4&lt;br /&gt;
ld e,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
dec h&lt;br /&gt;
ex de,hl&lt;br /&gt;
add hl,hl:add hl,hl:add hl,hl:add hl,hl&lt;br /&gt;
ex de,hl&lt;br /&gt;
ld a,e&lt;br /&gt;
ld (bc),a&lt;br /&gt;
inc b&lt;br /&gt;
ld a,d&lt;br /&gt;
ld (bc),a&lt;br /&gt;
dec b&lt;br /&gt;
inc l&lt;br /&gt;
inc c&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
.restab2&lt;br /&gt;
ds 512 * 15&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code to perform the multiplication (DE = L * C):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ld h,hltab1 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
inc h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(bc)		; 10&lt;br /&gt;
add (hl)		; 12&lt;br /&gt;
ld e,a			; 13&lt;br /&gt;
inc b			; 14&lt;br /&gt;
inc h			; 15&lt;br /&gt;
ld a,(bc)		; 17&lt;br /&gt;
adc (hl)		; 19&lt;br /&gt;
ld d,a			; 20&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast, accurate 8bit * 8bit Unsigned  with 8 KB tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' L = Multiplier, C = Multiplicand&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 100 = 25 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 19 bytes of code + 8 KB tables&lt;br /&gt;
&lt;br /&gt;
16K is a lot of memory to use for tables, but I'm working on a way to reduce this to 8K while maintaining similar performance (around 26&amp;amp;mu;s). The idea is rather than using tables for the low and high nibbles, use tables for alternate bits. So there would be 16 tables for the values #00, #01, #04, #05, #10, #11, #14, #15, #40, #41, #44, #45, #50, #51, #54, #55. The values can be shifted by 1 (rather than 4) to give values for the alternate bits using a simple ADD HL,HL.&lt;br /&gt;
&lt;br /&gt;
This routine should be easy to adapt to a 16bit * 8bit unsigned multiplication or even a 16bit * 16bit, using simple additions.&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 03:58, 8 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
Ok, here is the new 8K routine, first the routine to build the tables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp5&lt;br /&gt;
ld a,l&lt;br /&gt;
ld bc,0&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
ld a,b&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,c&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp5&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp6&lt;br /&gt;
ld (hl),l&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp6&lt;br /&gt;
inc h:inc h&lt;br /&gt;
ld b,2&lt;br /&gt;
.makelp8&lt;br /&gt;
push bc&lt;br /&gt;
xor a&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
.makelp7&lt;br /&gt;
push hl&lt;br /&gt;
push af&lt;br /&gt;
call mulLbyA&lt;br /&gt;
ex de,hl&lt;br /&gt;
pop af&lt;br /&gt;
pop hl&lt;br /&gt;
ld (hl),e&lt;br /&gt;
inc h&lt;br /&gt;
ld (hl),d&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp7&lt;br /&gt;
inc h:inc h&lt;br /&gt;
pop bc&lt;br /&gt;
inc b&lt;br /&gt;
bit 4,b&lt;br /&gt;
jr z,makelp8&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
.mulLbyA	; MAX times	; MIN times&lt;br /&gt;
ld e,l		; 1		; 1&lt;br /&gt;
ld d,0		; 3		; 3&lt;br /&gt;
add a		; 4		; 4&lt;br /&gt;
ld h,a		; 5		; 5&lt;br /&gt;
jr c,ncad0	; 8		; 8&lt;br /&gt;
ld l,d		&lt;br /&gt;
.ncad0&lt;br /&gt;
add hl,hl	; 11		; 11&lt;br /&gt;
jr nc,ncad1	; 13		; 14&lt;br /&gt;
add hl,de	; 16&lt;br /&gt;
.ncad1&lt;br /&gt;
add hl,hl	; 19		; 17&lt;br /&gt;
jr nc,ncad2	; 21		; 20&lt;br /&gt;
add hl,de	; 24&lt;br /&gt;
.ncad2&lt;br /&gt;
add hl,hl	; 27		; 23&lt;br /&gt;
jr nc,ncad3	; 29		; 26&lt;br /&gt;
add hl,de	; 32&lt;br /&gt;
.ncad3&lt;br /&gt;
add hl,hl	; 35		; 29&lt;br /&gt;
jr nc,ncad4	; 37		; 32&lt;br /&gt;
add hl,de	; 40&lt;br /&gt;
.ncad4&lt;br /&gt;
add hl,hl	; 43		; 35&lt;br /&gt;
jr nc,ncad5	; 45		; 38&lt;br /&gt;
add hl,de	; 48&lt;br /&gt;
.ncad5&lt;br /&gt;
add hl,hl	; 51		; 41&lt;br /&gt;
jr nc,ncad6	; 53		; 44&lt;br /&gt;
add hl,de	; 56&lt;br /&gt;
.ncad6&lt;br /&gt;
add hl,hl	; 59		; 47&lt;br /&gt;
ld a,h		; 60		; 48&lt;br /&gt;
ret nc		; 61		; 50?&lt;br /&gt;
add hl,de	; 64&lt;br /&gt;
ld a,h		; 65&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the routine to do the multiplication:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.umultCL		; Using 8 bit only (25us - DE = L * C)&lt;br /&gt;
ld h,hltab2 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
dec h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(hl)		; 10&lt;br /&gt;
add a			; 11&lt;br /&gt;
inc h			; 12&lt;br /&gt;
ld d,(hl)		; 14&lt;br /&gt;
rl d			; 16&lt;br /&gt;
ld h,b			; 17&lt;br /&gt;
add (hl)		; 19&lt;br /&gt;
ld e,a			; 20&lt;br /&gt;
inc h			; 21&lt;br /&gt;
ld a,(hl)		; 23&lt;br /&gt;
adc d			; 24&lt;br /&gt;
ld d,a			; 25&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Very fast 8bit * 8bit Unsigned with only 1K of tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', L = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles''': 104-112 (108 on average) = 26-28 (27) usec&lt;br /&gt;
&lt;br /&gt;
'''Size''': 24 bytes of code and 1024 bytes for the tables&lt;br /&gt;
&lt;br /&gt;
Here's a new routine I've developed which uses the formula ab = ((a + b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - (a - b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) / 4. It's based on a routine for the 6502 by Stephen Judd in a C= Hacking article. Because of differences between the way the 6502 does register indexing it was quite difficult to actually get this working, but it's a great compromise between speed and space since it only uses 1K of tables (as opposed to the 16K or 8K table routines above), and can still manage to do the job in a maximum of 28 microseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Firstly, once again, we need some code to generate the tables. These tables contain values for&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;/4 for 9 bit values of x, with the LSB when bit 8 is zero first followed by the MSB.&lt;br /&gt;
&amp;lt;pre&amp;gt;.gen_sq4&lt;br /&gt;
	xor a&lt;br /&gt;
	ld de,umul_tab + #1ff&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	ld h,d&lt;br /&gt;
	ld l,e&lt;br /&gt;
	inc e&lt;br /&gt;
	ld c,e&lt;br /&gt;
	ld b,2&lt;br /&gt;
&lt;br /&gt;
	.sq4_lp&lt;br /&gt;
	ld a,b&lt;br /&gt;
	cp 2&lt;br /&gt;
	ld a,e&lt;br /&gt;
	rra&lt;br /&gt;
	add (hl)&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	inc h&lt;br /&gt;
	inc d&lt;br /&gt;
	ld a,(hl)&lt;br /&gt;
	adc c&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld h,d&lt;br /&gt;
	inc l&lt;br /&gt;
	inc e&lt;br /&gt;
	jr nz,sq4_lp&lt;br /&gt;
	inc d&lt;br /&gt;
	inc d&lt;br /&gt;
	djnz sq4_lp&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
align #100&lt;br /&gt;
.umul_tab ds #400&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now for the actual multiply routine:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ld h,umul_tab_lo / #100	; 2&lt;br /&gt;
	ld b,h			; 3&lt;br /&gt;
	add l			; 4&lt;br /&gt;
	ld c,a			; 5&lt;br /&gt;
	jr nc,@noovf		; 7&lt;br /&gt;
	inc b			; 8&lt;br /&gt;
	inc b			; 9&lt;br /&gt;
.@noovf&lt;br /&gt;
	sub l			; 10&lt;br /&gt;
	sub l			; 11&lt;br /&gt;
	jr nc,@noneg		; 13&lt;br /&gt;
	neg			; 15&lt;br /&gt;
.@noneg&lt;br /&gt;
	ld l,a			; 16&lt;br /&gt;
	ld a,(bc)		; 18&lt;br /&gt;
	sub (hl)		; 20&lt;br /&gt;
	ld e,a			; 21&lt;br /&gt;
	inc b			; 22&lt;br /&gt;
	inc h			; 23&lt;br /&gt;
	ld a,(bc)		; 25&lt;br /&gt;
	sbc (hl)		; 27&lt;br /&gt;
	ld d,a			; 28&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This code could easily be converted to a macro as it's only 24 bytes. I've tried to optimize it further but with no luck!&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 06:25, 4 April 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Fast 8bit * 8bit Unsigned with only 512 bytes of tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input''': A = Multiplier, B = Multiplicant&lt;br /&gt;
&lt;br /&gt;
'''Output''': A:E = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles''': 136-172 (154 on average) = 34-43 (38.5) usec&lt;br /&gt;
&lt;br /&gt;
'''Size''': 44 bytes of code and 512 bytes for the tables&lt;br /&gt;
&lt;br /&gt;
Fast 8 bit unsigned multiplication with 16 bit result. It uses formula&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  x*y = ((x+y)/2)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - ((x-y)/2)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;, if x+y is even&lt;br /&gt;
      = ((x+y-1)/2)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - ((x-y-1)/2)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; + y, if x+y is odd and x&amp;gt;=y&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;    cp b&lt;br /&gt;
    jr nc,l1&lt;br /&gt;
&lt;br /&gt;
    ld e,a&lt;br /&gt;
    ld a,b&lt;br /&gt;
    ld b,e&lt;br /&gt;
&lt;br /&gt;
l1  ld c,a&lt;br /&gt;
    sub b&lt;br /&gt;
    rra&lt;br /&gt;
    ld d,a&lt;br /&gt;
    ld a,c&lt;br /&gt;
    add a,b&lt;br /&gt;
    rra&lt;br /&gt;
    ld l,a&lt;br /&gt;
    ld h,high(sqrlo)&lt;br /&gt;
    ld a,(hl)&lt;br /&gt;
    ld e,l&lt;br /&gt;
    ld l,d&lt;br /&gt;
    jr nc,l2&lt;br /&gt;
&lt;br /&gt;
    sub (hl)   ;odd&lt;br /&gt;
    ld l,e&lt;br /&gt;
    ld e,a&lt;br /&gt;
    inc h      ;loads high(sqrhi)&lt;br /&gt;
    ld a,(hl)&lt;br /&gt;
    ld l,d&lt;br /&gt;
    sbc a,(hl)&lt;br /&gt;
    ld d,a&lt;br /&gt;
&lt;br /&gt;
    ld a,e&lt;br /&gt;
    add a,b&lt;br /&gt;
    ld e,a&lt;br /&gt;
    ld a,d&lt;br /&gt;
    adc a,0&lt;br /&gt;
    ret&lt;br /&gt;
&lt;br /&gt;
l2  sub (hl)   ;even&lt;br /&gt;
    ld l,e&lt;br /&gt;
    ld e,a&lt;br /&gt;
    inc h&lt;br /&gt;
    ld a,(hl)&lt;br /&gt;
    ld l,d&lt;br /&gt;
    sbc a,(hl)&lt;br /&gt;
    ret&lt;br /&gt;
&lt;br /&gt;
sqrlo ;low(x*x)   should be at the page border&lt;br /&gt;
    db 0,1,4,9,$10,$19,$24,$31,$40,$51,$64,$79,$90,$a9,$c4,$e1&lt;br /&gt;
    db 0,$21,$44,$69,$90,$b9,$e4,$11,$40,$71,$a4,$d9,$10,$49,$84,$c1&lt;br /&gt;
    db 0,$41,$84,$c9,$10,$59,$a4,$f1,$40,$91,$e4,$39,$90,$e9,$44,$a1&lt;br /&gt;
    db 0,$61,$c4,$29,$90,$f9,$64,$d1,$40,$b1,$24,$99,$10,$89,4,$81&lt;br /&gt;
    db 0,$81,4,$89,$10,$99,$24,$b1,$40,$d1,$64,$f9,$90,$29,$c4,$61&lt;br /&gt;
    db 0,$a1,$44,$e9,$90,$39,$e4,$91,$40,$f1,$a4,$59,$10,$c9,$84,$41&lt;br /&gt;
    db 0,$c1,$84,$49,$10,$d9,$a4,$71,$40,$11,$e4,$b9,$90,$69,$44,$21&lt;br /&gt;
    db 0,$e1,$c4,$a9,$90,$79,$64,$51,$40,$31,$24,$19,$10,9,4,$1&lt;br /&gt;
    db 0,1,4,9,$10,$19,$24,$31,$40,$51,$64,$79,$90,$a9,$c4,$e1&lt;br /&gt;
    db 0,$21,$44,$69,$90,$b9,$e4,$11,$40,$71,$a4,$d9,$10,$49,$84,$c1&lt;br /&gt;
    db 0,$41,$84,$c9,$10,$59,$a4,$f1,$40,$91,$e4,$39,$90,$e9,$44,$a1&lt;br /&gt;
    db 0,$61,$c4,$29,$90,$f9,$64,$d1,$40,$b1,$24,$99,$10,$89,4,$81&lt;br /&gt;
    db 0,$81,4,$89,$10,$99,$24,$b1,$40,$d1,$64,$f9,$90,$29,$c4,$61&lt;br /&gt;
    db 0,$a1,$44,$e9,$90,$39,$e4,$91,$40,$f1,$a4,$59,$10,$c9,$84,$41&lt;br /&gt;
    db 0,$c1,$84,$49,$10,$d9,$a4,$71,$40,$11,$e4,$b9,$90,$69,$44,$21&lt;br /&gt;
    db 0,$e1,$c4,$a9,$90,$79,$64,$51,$40,$31,$24,$19,$10,9,4,$1&lt;br /&gt;
sqrhi ;high(x*x)&lt;br /&gt;
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
    db 1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3&lt;br /&gt;
    db 4,4,4,4,5,5,5,5,6,6,6,7,7,7,8,8&lt;br /&gt;
    db 9,9,9,$a,$a,$a,$b,$b,$c,$c,$d,$d,$e,$e,$f,$f&lt;br /&gt;
    db $10,$10,$11,$11,$12,$12,$13,$13,$14,$14,$15,$15,$16,$17,$17,$18&lt;br /&gt;
    db $19,$19,$1a,$1a,$1b,$1c,$1c,$1d,$1e,$1e,$1f,$20,$21,$21,$22,$23&lt;br /&gt;
    db $24,$24,$25,$26,$27,$27,$28,$29,$2a,$2b,$2b,$2c,$2d,$2e,$2f,$30&lt;br /&gt;
    db $31,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f&lt;br /&gt;
    db $40,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f&lt;br /&gt;
    db $51,$52,$53,$54,$55,$56,$57,$59,$5a,$5b,$5c,$5d,$5f,$60,$61,$62&lt;br /&gt;
    db $64,$65,$66,$67,$69,$6a,$6b,$6c,$6e,$6f,$70,$72,$73,$74,$76,$77&lt;br /&gt;
    db $79,$7a,$7b,$7d,$7e,$7f,$81,$82,$84,$85,$87,$88,$8a,$8b,$8d,$8e&lt;br /&gt;
    db $90,$91,$93,$94,$96,$97,$99,$9a,$9c,$9d,$9f,$a0,$a2,$a4,$a5,$a7&lt;br /&gt;
    db $a9,$aa,$ac,$ad,$af,$b1,$b2,$b4,$b6,$b7,$b9,$bb,$bd,$be,$c0,$c2&lt;br /&gt;
    db $c4,$c5,$c7,$c9,$cb,$cc,$ce,$d0,$d2,$d4,$d5,$d7,$d9,$db,$dd,$df&lt;br /&gt;
    db $e1,$e2,$e4,$e6,$e8,$ea,$ec,$ee,$f0,$f2,$f4,$f6,$f8,$fa,$fc,$fe&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[User:Litwr|Litwr]] 10:25, 24 October 2015 (CEST)&lt;br /&gt;
&lt;br /&gt;
== 16bit * 16bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' BC = ''Multiplier'', DE = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A,HL = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;ld ix,0&lt;br /&gt;
 ld hl,0&lt;br /&gt;
.mul24b1:&lt;br /&gt;
 ld a,c&lt;br /&gt;
 or b&lt;br /&gt;
 jr z,mul24b3&lt;br /&gt;
 srl b&lt;br /&gt;
 rr c&lt;br /&gt;
 jr nc,mul24b2&lt;br /&gt;
 add ix,de&lt;br /&gt;
 ld a,h&lt;br /&gt;
 adc l&lt;br /&gt;
 ld h,a&lt;br /&gt;
.mul24b2:&lt;br /&gt;
 sla e&lt;br /&gt;
 rl d&lt;br /&gt;
 rl l&lt;br /&gt;
 jr mul24b1:&lt;br /&gt;
.mul24b3:&lt;br /&gt;
 ld a,h&lt;br /&gt;
 db #dd:ld e,l&lt;br /&gt;
 db #dd:ld d,h&lt;br /&gt;
 ex de,hl&lt;br /&gt;
 ret&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://map.tni.nl/articles/mult_div_shifts.php Multiplications and divisions on the MSX Assembly Page]&lt;br /&gt;
* [http://www.mccw.hetlab.tk/92/Multiplication/en.html &amp;quot;Multiplication on a Z80&amp;quot; ( MSX Computer &amp;amp; Club Webmagazine)]&lt;br /&gt;
* [http://www.andreadrian.de/oldcpu/Z80_number_cruncher.html The Z80 number cruncher (Andre Adrian)] (16/32bit multiplication, addition, right shift)&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94470</id>
		<title>Programming:Integer Multiplication</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94470"/>
				<updated>2015-10-24T07:39:52Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: /* Very fast 8bit * 8bit Unsigned with only 1K of tables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Classic 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' H = ''Multiplier'', E = ''Multiplicand'', L = 0, D = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 188-244 (216 on average) = 47-61 (54) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 33 bytes&lt;br /&gt;
&lt;br /&gt;
The additional clocks and bytes maybe required to set up D and L and for RET.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sla h  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+3&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
jr nc,$+3  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Classic 16bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', DE = ''Multiplicand'', HL = 0, C = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A:HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 212-300 (256 on average) = 53-75 (64) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 47 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add a,a  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+4&lt;br /&gt;
ld h,d&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
rla   ; ...&lt;br /&gt;
jr nc,$+4  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
adc a,c  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast 8bit * 8bit Unsigned (using log / antilog tables) ==&lt;br /&gt;
&lt;br /&gt;
The original routine was written by Jeff Frohwein for the Nintendo Gameboy. You can find it on [http://www.devrs.com/gb/files/logmult.txt Devrs.com].&lt;br /&gt;
&lt;br /&gt;
Because of the usage of log / antilog tables this routine is less accurate, but very fast. It takes advantage of the fact that if you take the log of two numbers, add the results and then take the antilog of the total you have done the equivalent of multiplying the two numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 x^a * x^b = x^(a+b)&lt;br /&gt;
&lt;br /&gt;
 a * b = x^(logx(a) + logx(b))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Input:''' B = ''Multiplier'', C = ''Multiplicant''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 124 = 31 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 1024 bytes (768 bytes for the tables)&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' It is VERY approximate routine, e.g., 0*7=7, 1*28=27, 10*81=790, 100*100=9742, ...&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FastMult:&lt;br /&gt;
  ld      l,c&lt;br /&gt;
  ld      h,&amp;amp;82&lt;br /&gt;
  ld      d,(hl)          ; d = 32 * log_2(c)&lt;br /&gt;
  &lt;br /&gt;
  ld      l,b&lt;br /&gt;
  ld      a,(hl)          ; a = 32 * log_2(b)&lt;br /&gt;
  &lt;br /&gt;
  add     a,d&lt;br /&gt;
  ld      l,a&lt;br /&gt;
  ld      a,0&lt;br /&gt;
  adc     a,0&lt;br /&gt;
  ld      h,a             ; hl = d + a&lt;br /&gt;
  &lt;br /&gt;
  add     hl,hl&lt;br /&gt;
  set     2,h             ; hl = hl + $0400&lt;br /&gt;
  set     7,h             ; hl = hl + &amp;amp;8000&lt;br /&gt;
  &lt;br /&gt;
  ld      e,(hl)&lt;br /&gt;
  inc     hl&lt;br /&gt;
  ld      d,(hl)          ; de = 2^((hl)/32)&lt;br /&gt;
  &lt;br /&gt;
  ret&lt;br /&gt;
&lt;br /&gt;
; 32*Log_2(x) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 TO 255&lt;br /&gt;
;     C=4 &lt;br /&gt;
;     B=2&lt;br /&gt;
;     FOR Z=1 TO 10&lt;br /&gt;
;       IF (2^C) &amp;gt; A THEN C=C-B ELSE C=C+B&lt;br /&gt;
;       B=B/2&lt;br /&gt;
;     NEXT Z&lt;br /&gt;
;     PRINT INT(C*32);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8200&lt;br /&gt;
&lt;br /&gt;
logtable:&lt;br /&gt;
  db 0 , 0 , 32 , 50 , 64 , 74 , 82 , 89 , 96 , 101 , 106 , 110 , 114 , 118 , 121&lt;br /&gt;
  db 125 , 128 , 130 , 133 , 135 , 138 , 140 , 142 , 144 , 146 , 148 , 150 , 152&lt;br /&gt;
  db 153 , 155 , 157 , 158 , 160 , 161 , 162 , 164 , 165 , 166 , 167 , 169 , 170&lt;br /&gt;
  db 171 , 172 , 173 , 174 , 175 , 176 , 177 , 178 , 179 , 180 , 181 , 182 , 183&lt;br /&gt;
  db 184 , 185 , 185 , 186 , 187 , 188 , 189 , 189 , 190 , 191 , 192 , 192 , 193&lt;br /&gt;
  db 194 , 194 , 195 , 196 , 196 , 197 , 198 , 198 , 199 , 199 , 200 , 201 , 201&lt;br /&gt;
  db 202 , 202 , 203 , 204 , 204 , 205 , 205 , 206 , 206 , 207 , 207 , 208 , 208&lt;br /&gt;
  db 209 , 209 , 210 , 210 , 211 , 211 , 212 , 212 , 213 , 213 , 213 , 214 , 214&lt;br /&gt;
  db 215 , 215 , 216 , 216 , 217 , 217 , 217 , 218 , 218 , 219 , 219 , 219 , 220&lt;br /&gt;
  db 220 , 221 , 221 , 221 , 222 , 222 , 222 , 223 , 223 , 224 , 224 , 224 , 225&lt;br /&gt;
  db 225 , 225 , 226 , 226 , 226 , 227 , 227 , 227 , 228 , 228 , 228 , 229 , 229&lt;br /&gt;
  db 229 , 230 , 230 , 230 , 231 , 231 , 231 , 231 , 232 , 232 , 232 , 233 , 233&lt;br /&gt;
  db 233 , 234 , 234 , 234 , 234 , 235 , 235 , 235 , 236 , 236 , 236 , 236 , 237&lt;br /&gt;
  db 237 , 237 , 237 , 238 , 238 , 238 , 238 , 239 , 239 , 239 , 239 , 240 , 240&lt;br /&gt;
  db 240 , 241 , 241 , 241 , 241 , 241 , 242 , 242 , 242 , 242 , 243 , 243 , 243&lt;br /&gt;
  db 243 , 244 , 244 , 244 , 244 , 245 , 245 , 245 , 245 , 245 , 246 , 246 , 246&lt;br /&gt;
  db 246 , 247 , 247 , 247 , 247 , 247 , 248 , 248 , 248 , 248 , 249 , 249 , 249&lt;br /&gt;
  db 249 , 249 , 250 , 250 , 250 , 250 , 250 , 251 , 251 , 251 , 251 , 251 , 252&lt;br /&gt;
  db 252 , 252 , 252 , 252 , 253 , 253 , 253 , 253 , 253 , 253 , 254 , 254 , 254&lt;br /&gt;
  db 254 , 254 , 255 , 255 , 255 , 255 , 255&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; AntiLog 2^(x/32) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 to 510&lt;br /&gt;
;   PRINT INT(2^(A/32)+.5);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8400&lt;br /&gt;
&lt;br /&gt;
antilog:&lt;br /&gt;
  dw 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 , 4&lt;br /&gt;
  dw 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 6&lt;br /&gt;
  dw 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 8 , 9&lt;br /&gt;
  dw 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , 12 , 12 , 12&lt;br /&gt;
  dw 13 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17&lt;br /&gt;
  dw 18 , 18 , 19 , 19 , 19 , 20 , 20 , 21 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25&lt;br /&gt;
  dw 25 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , 30 , 31 , 31 , 32 , 33 , 33 , 34 , 35&lt;br /&gt;
  dw 36 , 36 , 37 , 38 , 39 , 40 , 41 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49&lt;br /&gt;
  dw 50 , 52 , 53 , 54 , 55 , 56 , 57 , 59 , 60 , 61 , 63 , 64 , 65 , 67 , 68 , 70&lt;br /&gt;
  dw 71 , 73 , 74 , 76 , 78 , 79 , 81 , 83 , 85 , 87 , 89 , 91 , 92 , 95 , 97 , 99&lt;br /&gt;
  dw 101 , 103 , 105 , 108 , 110 , 112 , 115 , 117 , 120 , 123 , 125 , 128 , 131&lt;br /&gt;
  dw 134 , 137 , 140 , 143 , 146 , 149 , 152 , 156 , 159 , 162 , 166 , 170 , 173&lt;br /&gt;
  dw 177 , 181 , 185 , 189 , 193 , 197 , 202 , 206 , 211 , 215 , 220 , 225 , 230&lt;br /&gt;
  dw 235 , 240 , 245 , 251 , 256 , 262 , 267 , 273 , 279 , 285 , 292 , 298 , 304&lt;br /&gt;
  dw 311 , 318 , 325 , 332 , 339 , 347 , 354 , 362 , 370 , 378 , 386 , 395 , 403&lt;br /&gt;
  dw 412 , 421 , 431 , 440 , 450 , 459 , 470 , 480 , 490 , 501 , 512 , 523 , 535&lt;br /&gt;
  dw 546 , 558 , 571 , 583 , 596 , 609 , 622 , 636 , 650 , 664 , 679 , 693 , 709&lt;br /&gt;
  dw 724 , 740 , 756 , 773 , 790 , 807 , 825 , 843 , 861 , 880 , 899 , 919 , 939&lt;br /&gt;
  dw 960 , 981 , 1002 , 1024 , 1046 , 1069 , 1093 , 1117 , 1141 , 1166 , 1192&lt;br /&gt;
  dw 1218 , 1244 , 1272 , 1300 , 1328 , 1357 , 1387 , 1417 , 1448 , 1480 , 1512&lt;br /&gt;
  dw 1545 , 1579 , 1614 , 1649 , 1685 , 1722 , 1760 , 1798 , 1838 , 1878 , 1919&lt;br /&gt;
  dw 1961 , 2004 , 2048 , 2093 , 2139 , 2186 , 2233 , 2282 , 2332 , 2383 , 2435&lt;br /&gt;
  dw 2489 , 2543 , 2599 , 2656 , 2714 , 2774 , 2834 , 2896 , 2960 , 3025 , 3091&lt;br /&gt;
  dw 3158 , 3228 , 3298 , 3371 , 3444 , 3520 , 3597 , 3676 , 3756 , 3838 , 3922&lt;br /&gt;
  dw 4008 , 4096 , 4186 , 4277 , 4371 , 4467 , 4565 , 4664 , 4767 , 4871 , 4978&lt;br /&gt;
  dw 5087 , 5198 , 5312 , 5428 , 5547 , 5668 , 5793 , 5919 , 6049 , 6182 , 6317&lt;br /&gt;
  dw 6455 , 6597 , 6741 , 6889 , 7039 , 7194 , 7351 , 7512 , 7677 , 7845 , 8016&lt;br /&gt;
  dw 8192 , 8371 , 8555 , 8742 , 8933 , 9129 , 9329 , 9533 , 9742 , 9955 , 10173&lt;br /&gt;
  dw 10396 , 10624 , 10856 , 11094 , 11337 , 11585 , 11839 , 12098 , 12363 , 12634&lt;br /&gt;
  dw 12910 , 13193 , 13482 , 13777 , 14079 , 14387 , 14702 , 15024 , 15353 , 15689&lt;br /&gt;
  dw 16033 , 16384 , 16743 , 17109 , 17484 , 17867 , 18258 , 18658 , 19066 , 19484&lt;br /&gt;
  dw 19911 , 20347 , 20792 , 21247 , 21713 , 22188 , 22674 , 23170 , 23678 , 24196&lt;br /&gt;
  dw 24726 , 25268 , 25821 , 26386 , 26964 , 27554 , 28158 , 28774 , 29404 , 30048&lt;br /&gt;
  dw 30706 , 31379 , 32066 , 32768 , 33485 , 34219 , 34968 , 35734 , 36516 , 37316&lt;br /&gt;
  dw 38133 , 38968 , 39821 , 40693 , 41584 , 42495 , 43425 , 44376 , 45348 , 46341&lt;br /&gt;
  dw 47356 , 48393 , 49452 , 50535 , 51642 , 52772 , 53928 , 55109 , 56316 , 57549&lt;br /&gt;
  dw  58809 , 60097 , 61413 , 62757&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fastest, accurate 8bit * 8bit Unsigned  with 16 KB tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' L = Multiplier, C = Multiplicand&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 80 = 20 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 14 bytes of code + 16 KB tables&lt;br /&gt;
&lt;br /&gt;
I'm currently working on a new routine, based on a routine by Kirk Meyer [http://www.ticalc.org/pub/86/asm/source/routines/vfmult.asm] which uses nibble multiplication tables.&lt;br /&gt;
&lt;br /&gt;
I have a working, tested version which uses 16K of tables and can perform multiplication in 20&amp;amp;mu;s.&lt;br /&gt;
&lt;br /&gt;
The code to produce the tables is below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp1&lt;br /&gt;
ld a,l&lt;br /&gt;
rla&lt;br /&gt;
and #1e&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp1&lt;br /&gt;
inc h&lt;br /&gt;
.makelp2&lt;br /&gt;
ld a,l&lt;br /&gt;
rra:rra:rra&lt;br /&gt;
and #1e&lt;br /&gt;
jr z,usez&lt;br /&gt;
add restab2 - restab / 256 - 2&lt;br /&gt;
.usez&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp2&lt;br /&gt;
inc h			; restab&lt;br /&gt;
.makelp3&lt;br /&gt;
ld a,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
add l&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,0&lt;br /&gt;
adc d&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h:dec h:dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256 - 2&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
ld b,h&lt;br /&gt;
ld c,l&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp4&lt;br /&gt;
ld e,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
dec h&lt;br /&gt;
ex de,hl&lt;br /&gt;
add hl,hl:add hl,hl:add hl,hl:add hl,hl&lt;br /&gt;
ex de,hl&lt;br /&gt;
ld a,e&lt;br /&gt;
ld (bc),a&lt;br /&gt;
inc b&lt;br /&gt;
ld a,d&lt;br /&gt;
ld (bc),a&lt;br /&gt;
dec b&lt;br /&gt;
inc l&lt;br /&gt;
inc c&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
.restab2&lt;br /&gt;
ds 512 * 15&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code to perform the multiplication (DE = L * C):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ld h,hltab1 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
inc h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(bc)		; 10&lt;br /&gt;
add (hl)		; 12&lt;br /&gt;
ld e,a			; 13&lt;br /&gt;
inc b			; 14&lt;br /&gt;
inc h			; 15&lt;br /&gt;
ld a,(bc)		; 17&lt;br /&gt;
adc (hl)		; 19&lt;br /&gt;
ld d,a			; 20&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast, accurate 8bit * 8bit Unsigned  with 8 KB tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' L = Multiplier, C = Multiplicand&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 100 = 25 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 19 bytes of code + 8 KB tables&lt;br /&gt;
&lt;br /&gt;
16K is a lot of memory to use for tables, but I'm working on a way to reduce this to 8K while maintaining similar performance (around 26&amp;amp;mu;s). The idea is rather than using tables for the low and high nibbles, use tables for alternate bits. So there would be 16 tables for the values #00, #01, #04, #05, #10, #11, #14, #15, #40, #41, #44, #45, #50, #51, #54, #55. The values can be shifted by 1 (rather than 4) to give values for the alternate bits using a simple ADD HL,HL.&lt;br /&gt;
&lt;br /&gt;
This routine should be easy to adapt to a 16bit * 8bit unsigned multiplication or even a 16bit * 16bit, using simple additions.&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 03:58, 8 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
Ok, here is the new 8K routine, first the routine to build the tables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp5&lt;br /&gt;
ld a,l&lt;br /&gt;
ld bc,0&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
ld a,b&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,c&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp5&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp6&lt;br /&gt;
ld (hl),l&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp6&lt;br /&gt;
inc h:inc h&lt;br /&gt;
ld b,2&lt;br /&gt;
.makelp8&lt;br /&gt;
push bc&lt;br /&gt;
xor a&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
.makelp7&lt;br /&gt;
push hl&lt;br /&gt;
push af&lt;br /&gt;
call mulLbyA&lt;br /&gt;
ex de,hl&lt;br /&gt;
pop af&lt;br /&gt;
pop hl&lt;br /&gt;
ld (hl),e&lt;br /&gt;
inc h&lt;br /&gt;
ld (hl),d&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp7&lt;br /&gt;
inc h:inc h&lt;br /&gt;
pop bc&lt;br /&gt;
inc b&lt;br /&gt;
bit 4,b&lt;br /&gt;
jr z,makelp8&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
.mulLbyA	; MAX times	; MIN times&lt;br /&gt;
ld e,l		; 1		; 1&lt;br /&gt;
ld d,0		; 3		; 3&lt;br /&gt;
add a		; 4		; 4&lt;br /&gt;
ld h,a		; 5		; 5&lt;br /&gt;
jr c,ncad0	; 8		; 8&lt;br /&gt;
ld l,d		&lt;br /&gt;
.ncad0&lt;br /&gt;
add hl,hl	; 11		; 11&lt;br /&gt;
jr nc,ncad1	; 13		; 14&lt;br /&gt;
add hl,de	; 16&lt;br /&gt;
.ncad1&lt;br /&gt;
add hl,hl	; 19		; 17&lt;br /&gt;
jr nc,ncad2	; 21		; 20&lt;br /&gt;
add hl,de	; 24&lt;br /&gt;
.ncad2&lt;br /&gt;
add hl,hl	; 27		; 23&lt;br /&gt;
jr nc,ncad3	; 29		; 26&lt;br /&gt;
add hl,de	; 32&lt;br /&gt;
.ncad3&lt;br /&gt;
add hl,hl	; 35		; 29&lt;br /&gt;
jr nc,ncad4	; 37		; 32&lt;br /&gt;
add hl,de	; 40&lt;br /&gt;
.ncad4&lt;br /&gt;
add hl,hl	; 43		; 35&lt;br /&gt;
jr nc,ncad5	; 45		; 38&lt;br /&gt;
add hl,de	; 48&lt;br /&gt;
.ncad5&lt;br /&gt;
add hl,hl	; 51		; 41&lt;br /&gt;
jr nc,ncad6	; 53		; 44&lt;br /&gt;
add hl,de	; 56&lt;br /&gt;
.ncad6&lt;br /&gt;
add hl,hl	; 59		; 47&lt;br /&gt;
ld a,h		; 60		; 48&lt;br /&gt;
ret nc		; 61		; 50?&lt;br /&gt;
add hl,de	; 64&lt;br /&gt;
ld a,h		; 65&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the routine to do the multiplication:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.umultCL		; Using 8 bit only (25us - DE = L * C)&lt;br /&gt;
ld h,hltab2 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
dec h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(hl)		; 10&lt;br /&gt;
add a			; 11&lt;br /&gt;
inc h			; 12&lt;br /&gt;
ld d,(hl)		; 14&lt;br /&gt;
rl d			; 16&lt;br /&gt;
ld h,b			; 17&lt;br /&gt;
add (hl)		; 19&lt;br /&gt;
ld e,a			; 20&lt;br /&gt;
inc h			; 21&lt;br /&gt;
ld a,(hl)		; 23&lt;br /&gt;
adc d			; 24&lt;br /&gt;
ld d,a			; 25&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Very fast 8bit * 8bit Unsigned with only 1K of tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', L = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles''': 104-112 (108 on average) = 26-28 (27) usec&lt;br /&gt;
&lt;br /&gt;
'''Size''': 24 bytes of code and 1024 bytes for the tables&lt;br /&gt;
&lt;br /&gt;
Here's a new routine I've developed which uses the formula ab = ((a + b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - (a - b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) / 4. It's based on a routine for the 6502 by Stephen Judd in a C= Hacking article. Because of differences between the way the 6502 does register indexing it was quite difficult to actually get this working, but it's a great compromise between speed and space since it only uses 1K of tables (as opposed to the 16K or 8K table routines above), and can still manage to do the job in a maximum of 28 microseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Firstly, once again, we need some code to generate the tables. These tables contain values for&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;/4 for 9 bit values of x, with the LSB when bit 8 is zero first followed by the MSB.&lt;br /&gt;
&amp;lt;pre&amp;gt;.gen_sq4&lt;br /&gt;
	xor a&lt;br /&gt;
	ld de,umul_tab + #1ff&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	ld h,d&lt;br /&gt;
	ld l,e&lt;br /&gt;
	inc e&lt;br /&gt;
	ld c,e&lt;br /&gt;
	ld b,2&lt;br /&gt;
&lt;br /&gt;
	.sq4_lp&lt;br /&gt;
	ld a,b&lt;br /&gt;
	cp 2&lt;br /&gt;
	ld a,e&lt;br /&gt;
	rra&lt;br /&gt;
	add (hl)&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	inc h&lt;br /&gt;
	inc d&lt;br /&gt;
	ld a,(hl)&lt;br /&gt;
	adc c&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld h,d&lt;br /&gt;
	inc l&lt;br /&gt;
	inc e&lt;br /&gt;
	jr nz,sq4_lp&lt;br /&gt;
	inc d&lt;br /&gt;
	inc d&lt;br /&gt;
	djnz sq4_lp&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
align #100&lt;br /&gt;
.umul_tab ds #400&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now for the actual multiply routine:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ld h,umul_tab_lo / #100	; 2&lt;br /&gt;
	ld b,h			; 3&lt;br /&gt;
	add l			; 4&lt;br /&gt;
	ld c,a			; 5&lt;br /&gt;
	jr nc,@noovf		; 7&lt;br /&gt;
	inc b			; 8&lt;br /&gt;
	inc b			; 9&lt;br /&gt;
.@noovf&lt;br /&gt;
	sub l			; 10&lt;br /&gt;
	sub l			; 11&lt;br /&gt;
	jr nc,@noneg		; 13&lt;br /&gt;
	neg			; 15&lt;br /&gt;
.@noneg&lt;br /&gt;
	ld l,a			; 16&lt;br /&gt;
	ld a,(bc)		; 18&lt;br /&gt;
	sub (hl)		; 20&lt;br /&gt;
	ld e,a			; 21&lt;br /&gt;
	inc b			; 22&lt;br /&gt;
	inc h			; 23&lt;br /&gt;
	ld a,(bc)		; 25&lt;br /&gt;
	sbc (hl)		; 27&lt;br /&gt;
	ld d,a			; 28&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This code could easily be converted to a macro as it's only 24 bytes. I've tried to optimize it further but with no luck!&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 06:25, 4 April 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Fast 8bit * 8bit Unsigned with only 512 bytes of tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input''': A = Multiplier, B = Multiplicant&lt;br /&gt;
&lt;br /&gt;
'''Output''': A:E = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles''': 136-172 (154 on average) = 34-43 (38.5) usec&lt;br /&gt;
&lt;br /&gt;
'''Size''': 44 bytes of code and 512 bytes for the tables&lt;br /&gt;
&lt;br /&gt;
Fast 8 bit unsigned multiplication with 16 bit result. It uses formula&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  x*y = ((x+y)/2)^2 - ((x-y)/2)^2, if x+y is even&lt;br /&gt;
      = ((x+y-1)/2)^2 - ((x-y-1)/2)^2 + y, if x+y is odd and x&amp;gt;=y&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;    cp b&lt;br /&gt;
    jr nc,l1&lt;br /&gt;
&lt;br /&gt;
    ld e,a&lt;br /&gt;
    ld a,b&lt;br /&gt;
    ld b,e&lt;br /&gt;
&lt;br /&gt;
l1  ld c,a&lt;br /&gt;
    sub b&lt;br /&gt;
    rra&lt;br /&gt;
    ld d,a&lt;br /&gt;
    ld a,c&lt;br /&gt;
    add a,b&lt;br /&gt;
    rra&lt;br /&gt;
    ld l,a&lt;br /&gt;
    ld h,high(sqrlo)&lt;br /&gt;
    ld a,(hl)&lt;br /&gt;
    ld e,l&lt;br /&gt;
    ld l,d&lt;br /&gt;
    jr nc,l2&lt;br /&gt;
&lt;br /&gt;
    sub (hl)   ;odd&lt;br /&gt;
    ld l,e&lt;br /&gt;
    ld e,a&lt;br /&gt;
    inc h      ;loads high(sqrhi)&lt;br /&gt;
    ld a,(hl)&lt;br /&gt;
    ld l,d&lt;br /&gt;
    sbc a,(hl)&lt;br /&gt;
    ld d,a&lt;br /&gt;
&lt;br /&gt;
    ld a,e&lt;br /&gt;
    add a,b&lt;br /&gt;
    ld e,a&lt;br /&gt;
    ld a,d&lt;br /&gt;
    adc a,0&lt;br /&gt;
    ret&lt;br /&gt;
&lt;br /&gt;
l2  sub (hl)   ;even&lt;br /&gt;
    ld l,e&lt;br /&gt;
    ld e,a&lt;br /&gt;
    inc h&lt;br /&gt;
    ld a,(hl)&lt;br /&gt;
    ld l,d&lt;br /&gt;
    sbc a,(hl)&lt;br /&gt;
    ret&lt;br /&gt;
&lt;br /&gt;
sqrlo ;low(x*x)   should be at the page border&lt;br /&gt;
    db 0,1,4,9,$10,$19,$24,$31,$40,$51,$64,$79,$90,$a9,$c4,$e1&lt;br /&gt;
    db 0,$21,$44,$69,$90,$b9,$e4,$11,$40,$71,$a4,$d9,$10,$49,$84,$c1&lt;br /&gt;
    db 0,$41,$84,$c9,$10,$59,$a4,$f1,$40,$91,$e4,$39,$90,$e9,$44,$a1&lt;br /&gt;
    db 0,$61,$c4,$29,$90,$f9,$64,$d1,$40,$b1,$24,$99,$10,$89,4,$81&lt;br /&gt;
    db 0,$81,4,$89,$10,$99,$24,$b1,$40,$d1,$64,$f9,$90,$29,$c4,$61&lt;br /&gt;
    db 0,$a1,$44,$e9,$90,$39,$e4,$91,$40,$f1,$a4,$59,$10,$c9,$84,$41&lt;br /&gt;
    db 0,$c1,$84,$49,$10,$d9,$a4,$71,$40,$11,$e4,$b9,$90,$69,$44,$21&lt;br /&gt;
    db 0,$e1,$c4,$a9,$90,$79,$64,$51,$40,$31,$24,$19,$10,9,4,$1&lt;br /&gt;
    db 0,1,4,9,$10,$19,$24,$31,$40,$51,$64,$79,$90,$a9,$c4,$e1&lt;br /&gt;
    db 0,$21,$44,$69,$90,$b9,$e4,$11,$40,$71,$a4,$d9,$10,$49,$84,$c1&lt;br /&gt;
    db 0,$41,$84,$c9,$10,$59,$a4,$f1,$40,$91,$e4,$39,$90,$e9,$44,$a1&lt;br /&gt;
    db 0,$61,$c4,$29,$90,$f9,$64,$d1,$40,$b1,$24,$99,$10,$89,4,$81&lt;br /&gt;
    db 0,$81,4,$89,$10,$99,$24,$b1,$40,$d1,$64,$f9,$90,$29,$c4,$61&lt;br /&gt;
    db 0,$a1,$44,$e9,$90,$39,$e4,$91,$40,$f1,$a4,$59,$10,$c9,$84,$41&lt;br /&gt;
    db 0,$c1,$84,$49,$10,$d9,$a4,$71,$40,$11,$e4,$b9,$90,$69,$44,$21&lt;br /&gt;
    db 0,$e1,$c4,$a9,$90,$79,$64,$51,$40,$31,$24,$19,$10,9,4,$1&lt;br /&gt;
sqrhi ;high(x*x)&lt;br /&gt;
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
    db 1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3&lt;br /&gt;
    db 4,4,4,4,5,5,5,5,6,6,6,7,7,7,8,8&lt;br /&gt;
    db 9,9,9,$a,$a,$a,$b,$b,$c,$c,$d,$d,$e,$e,$f,$f&lt;br /&gt;
    db $10,$10,$11,$11,$12,$12,$13,$13,$14,$14,$15,$15,$16,$17,$17,$18&lt;br /&gt;
    db $19,$19,$1a,$1a,$1b,$1c,$1c,$1d,$1e,$1e,$1f,$20,$21,$21,$22,$23&lt;br /&gt;
    db $24,$24,$25,$26,$27,$27,$28,$29,$2a,$2b,$2b,$2c,$2d,$2e,$2f,$30&lt;br /&gt;
    db $31,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f&lt;br /&gt;
    db $40,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f&lt;br /&gt;
    db $51,$52,$53,$54,$55,$56,$57,$59,$5a,$5b,$5c,$5d,$5f,$60,$61,$62&lt;br /&gt;
    db $64,$65,$66,$67,$69,$6a,$6b,$6c,$6e,$6f,$70,$72,$73,$74,$76,$77&lt;br /&gt;
    db $79,$7a,$7b,$7d,$7e,$7f,$81,$82,$84,$85,$87,$88,$8a,$8b,$8d,$8e&lt;br /&gt;
    db $90,$91,$93,$94,$96,$97,$99,$9a,$9c,$9d,$9f,$a0,$a2,$a4,$a5,$a7&lt;br /&gt;
    db $a9,$aa,$ac,$ad,$af,$b1,$b2,$b4,$b6,$b7,$b9,$bb,$bd,$be,$c0,$c2&lt;br /&gt;
    db $c4,$c5,$c7,$c9,$cb,$cc,$ce,$d0,$d2,$d4,$d5,$d7,$d9,$db,$dd,$df&lt;br /&gt;
    db $e1,$e2,$e4,$e6,$e8,$ea,$ec,$ee,$f0,$f2,$f4,$f6,$f8,$fa,$fc,$fe&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[User:Litwr|Litwr]] 10:25, 24 October 2015 (CEST)&lt;br /&gt;
&lt;br /&gt;
== 16bit * 16bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' BC = ''Multiplier'', DE = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A,HL = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;ld ix,0&lt;br /&gt;
 ld hl,0&lt;br /&gt;
.mul24b1:&lt;br /&gt;
 ld a,c&lt;br /&gt;
 or b&lt;br /&gt;
 jr z,mul24b3&lt;br /&gt;
 srl b&lt;br /&gt;
 rr c&lt;br /&gt;
 jr nc,mul24b2&lt;br /&gt;
 add ix,de&lt;br /&gt;
 ld a,h&lt;br /&gt;
 adc l&lt;br /&gt;
 ld h,a&lt;br /&gt;
.mul24b2:&lt;br /&gt;
 sla e&lt;br /&gt;
 rl d&lt;br /&gt;
 rl l&lt;br /&gt;
 jr mul24b1:&lt;br /&gt;
.mul24b3:&lt;br /&gt;
 ld a,h&lt;br /&gt;
 db #dd:ld e,l&lt;br /&gt;
 db #dd:ld d,h&lt;br /&gt;
 ex de,hl&lt;br /&gt;
 ret&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://map.tni.nl/articles/mult_div_shifts.php Multiplications and divisions on the MSX Assembly Page]&lt;br /&gt;
* [http://www.mccw.hetlab.tk/92/Multiplication/en.html &amp;quot;Multiplication on a Z80&amp;quot; ( MSX Computer &amp;amp; Club Webmagazine)]&lt;br /&gt;
* [http://www.andreadrian.de/oldcpu/Z80_number_cruncher.html The Z80 number cruncher (Andre Adrian)] (16/32bit multiplication, addition, right shift)&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94469</id>
		<title>Programming:Integer Multiplication</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94469"/>
				<updated>2015-10-24T07:36:59Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: /* Fast 8bit * 8bit Unsigned with only 512 bytes of tables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Classic 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' H = ''Multiplier'', E = ''Multiplicand'', L = 0, D = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 188-244 (216 on average) = 47-61 (54) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 33 bytes&lt;br /&gt;
&lt;br /&gt;
The additional clocks and bytes maybe required to set up D and L and for RET.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sla h  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+3&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
jr nc,$+3  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Classic 16bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', DE = ''Multiplicand'', HL = 0, C = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A:HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 212-300 (256 on average) = 53-75 (64) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 47 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add a,a  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+4&lt;br /&gt;
ld h,d&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
rla   ; ...&lt;br /&gt;
jr nc,$+4  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
adc a,c  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast 8bit * 8bit Unsigned (using log / antilog tables) ==&lt;br /&gt;
&lt;br /&gt;
The original routine was written by Jeff Frohwein for the Nintendo Gameboy. You can find it on [http://www.devrs.com/gb/files/logmult.txt Devrs.com].&lt;br /&gt;
&lt;br /&gt;
Because of the usage of log / antilog tables this routine is less accurate, but very fast. It takes advantage of the fact that if you take the log of two numbers, add the results and then take the antilog of the total you have done the equivalent of multiplying the two numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 x^a * x^b = x^(a+b)&lt;br /&gt;
&lt;br /&gt;
 a * b = x^(logx(a) + logx(b))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Input:''' B = ''Multiplier'', C = ''Multiplicant''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 124 = 31 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 1024 bytes (768 bytes for the tables)&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' It is VERY approximate routine, e.g., 0*7=7, 1*28=27, 10*81=790, 100*100=9742, ...&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FastMult:&lt;br /&gt;
  ld      l,c&lt;br /&gt;
  ld      h,&amp;amp;82&lt;br /&gt;
  ld      d,(hl)          ; d = 32 * log_2(c)&lt;br /&gt;
  &lt;br /&gt;
  ld      l,b&lt;br /&gt;
  ld      a,(hl)          ; a = 32 * log_2(b)&lt;br /&gt;
  &lt;br /&gt;
  add     a,d&lt;br /&gt;
  ld      l,a&lt;br /&gt;
  ld      a,0&lt;br /&gt;
  adc     a,0&lt;br /&gt;
  ld      h,a             ; hl = d + a&lt;br /&gt;
  &lt;br /&gt;
  add     hl,hl&lt;br /&gt;
  set     2,h             ; hl = hl + $0400&lt;br /&gt;
  set     7,h             ; hl = hl + &amp;amp;8000&lt;br /&gt;
  &lt;br /&gt;
  ld      e,(hl)&lt;br /&gt;
  inc     hl&lt;br /&gt;
  ld      d,(hl)          ; de = 2^((hl)/32)&lt;br /&gt;
  &lt;br /&gt;
  ret&lt;br /&gt;
&lt;br /&gt;
; 32*Log_2(x) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 TO 255&lt;br /&gt;
;     C=4 &lt;br /&gt;
;     B=2&lt;br /&gt;
;     FOR Z=1 TO 10&lt;br /&gt;
;       IF (2^C) &amp;gt; A THEN C=C-B ELSE C=C+B&lt;br /&gt;
;       B=B/2&lt;br /&gt;
;     NEXT Z&lt;br /&gt;
;     PRINT INT(C*32);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8200&lt;br /&gt;
&lt;br /&gt;
logtable:&lt;br /&gt;
  db 0 , 0 , 32 , 50 , 64 , 74 , 82 , 89 , 96 , 101 , 106 , 110 , 114 , 118 , 121&lt;br /&gt;
  db 125 , 128 , 130 , 133 , 135 , 138 , 140 , 142 , 144 , 146 , 148 , 150 , 152&lt;br /&gt;
  db 153 , 155 , 157 , 158 , 160 , 161 , 162 , 164 , 165 , 166 , 167 , 169 , 170&lt;br /&gt;
  db 171 , 172 , 173 , 174 , 175 , 176 , 177 , 178 , 179 , 180 , 181 , 182 , 183&lt;br /&gt;
  db 184 , 185 , 185 , 186 , 187 , 188 , 189 , 189 , 190 , 191 , 192 , 192 , 193&lt;br /&gt;
  db 194 , 194 , 195 , 196 , 196 , 197 , 198 , 198 , 199 , 199 , 200 , 201 , 201&lt;br /&gt;
  db 202 , 202 , 203 , 204 , 204 , 205 , 205 , 206 , 206 , 207 , 207 , 208 , 208&lt;br /&gt;
  db 209 , 209 , 210 , 210 , 211 , 211 , 212 , 212 , 213 , 213 , 213 , 214 , 214&lt;br /&gt;
  db 215 , 215 , 216 , 216 , 217 , 217 , 217 , 218 , 218 , 219 , 219 , 219 , 220&lt;br /&gt;
  db 220 , 221 , 221 , 221 , 222 , 222 , 222 , 223 , 223 , 224 , 224 , 224 , 225&lt;br /&gt;
  db 225 , 225 , 226 , 226 , 226 , 227 , 227 , 227 , 228 , 228 , 228 , 229 , 229&lt;br /&gt;
  db 229 , 230 , 230 , 230 , 231 , 231 , 231 , 231 , 232 , 232 , 232 , 233 , 233&lt;br /&gt;
  db 233 , 234 , 234 , 234 , 234 , 235 , 235 , 235 , 236 , 236 , 236 , 236 , 237&lt;br /&gt;
  db 237 , 237 , 237 , 238 , 238 , 238 , 238 , 239 , 239 , 239 , 239 , 240 , 240&lt;br /&gt;
  db 240 , 241 , 241 , 241 , 241 , 241 , 242 , 242 , 242 , 242 , 243 , 243 , 243&lt;br /&gt;
  db 243 , 244 , 244 , 244 , 244 , 245 , 245 , 245 , 245 , 245 , 246 , 246 , 246&lt;br /&gt;
  db 246 , 247 , 247 , 247 , 247 , 247 , 248 , 248 , 248 , 248 , 249 , 249 , 249&lt;br /&gt;
  db 249 , 249 , 250 , 250 , 250 , 250 , 250 , 251 , 251 , 251 , 251 , 251 , 252&lt;br /&gt;
  db 252 , 252 , 252 , 252 , 253 , 253 , 253 , 253 , 253 , 253 , 254 , 254 , 254&lt;br /&gt;
  db 254 , 254 , 255 , 255 , 255 , 255 , 255&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; AntiLog 2^(x/32) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 to 510&lt;br /&gt;
;   PRINT INT(2^(A/32)+.5);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8400&lt;br /&gt;
&lt;br /&gt;
antilog:&lt;br /&gt;
  dw 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 , 4&lt;br /&gt;
  dw 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 6&lt;br /&gt;
  dw 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 8 , 9&lt;br /&gt;
  dw 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , 12 , 12 , 12&lt;br /&gt;
  dw 13 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17&lt;br /&gt;
  dw 18 , 18 , 19 , 19 , 19 , 20 , 20 , 21 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25&lt;br /&gt;
  dw 25 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , 30 , 31 , 31 , 32 , 33 , 33 , 34 , 35&lt;br /&gt;
  dw 36 , 36 , 37 , 38 , 39 , 40 , 41 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49&lt;br /&gt;
  dw 50 , 52 , 53 , 54 , 55 , 56 , 57 , 59 , 60 , 61 , 63 , 64 , 65 , 67 , 68 , 70&lt;br /&gt;
  dw 71 , 73 , 74 , 76 , 78 , 79 , 81 , 83 , 85 , 87 , 89 , 91 , 92 , 95 , 97 , 99&lt;br /&gt;
  dw 101 , 103 , 105 , 108 , 110 , 112 , 115 , 117 , 120 , 123 , 125 , 128 , 131&lt;br /&gt;
  dw 134 , 137 , 140 , 143 , 146 , 149 , 152 , 156 , 159 , 162 , 166 , 170 , 173&lt;br /&gt;
  dw 177 , 181 , 185 , 189 , 193 , 197 , 202 , 206 , 211 , 215 , 220 , 225 , 230&lt;br /&gt;
  dw 235 , 240 , 245 , 251 , 256 , 262 , 267 , 273 , 279 , 285 , 292 , 298 , 304&lt;br /&gt;
  dw 311 , 318 , 325 , 332 , 339 , 347 , 354 , 362 , 370 , 378 , 386 , 395 , 403&lt;br /&gt;
  dw 412 , 421 , 431 , 440 , 450 , 459 , 470 , 480 , 490 , 501 , 512 , 523 , 535&lt;br /&gt;
  dw 546 , 558 , 571 , 583 , 596 , 609 , 622 , 636 , 650 , 664 , 679 , 693 , 709&lt;br /&gt;
  dw 724 , 740 , 756 , 773 , 790 , 807 , 825 , 843 , 861 , 880 , 899 , 919 , 939&lt;br /&gt;
  dw 960 , 981 , 1002 , 1024 , 1046 , 1069 , 1093 , 1117 , 1141 , 1166 , 1192&lt;br /&gt;
  dw 1218 , 1244 , 1272 , 1300 , 1328 , 1357 , 1387 , 1417 , 1448 , 1480 , 1512&lt;br /&gt;
  dw 1545 , 1579 , 1614 , 1649 , 1685 , 1722 , 1760 , 1798 , 1838 , 1878 , 1919&lt;br /&gt;
  dw 1961 , 2004 , 2048 , 2093 , 2139 , 2186 , 2233 , 2282 , 2332 , 2383 , 2435&lt;br /&gt;
  dw 2489 , 2543 , 2599 , 2656 , 2714 , 2774 , 2834 , 2896 , 2960 , 3025 , 3091&lt;br /&gt;
  dw 3158 , 3228 , 3298 , 3371 , 3444 , 3520 , 3597 , 3676 , 3756 , 3838 , 3922&lt;br /&gt;
  dw 4008 , 4096 , 4186 , 4277 , 4371 , 4467 , 4565 , 4664 , 4767 , 4871 , 4978&lt;br /&gt;
  dw 5087 , 5198 , 5312 , 5428 , 5547 , 5668 , 5793 , 5919 , 6049 , 6182 , 6317&lt;br /&gt;
  dw 6455 , 6597 , 6741 , 6889 , 7039 , 7194 , 7351 , 7512 , 7677 , 7845 , 8016&lt;br /&gt;
  dw 8192 , 8371 , 8555 , 8742 , 8933 , 9129 , 9329 , 9533 , 9742 , 9955 , 10173&lt;br /&gt;
  dw 10396 , 10624 , 10856 , 11094 , 11337 , 11585 , 11839 , 12098 , 12363 , 12634&lt;br /&gt;
  dw 12910 , 13193 , 13482 , 13777 , 14079 , 14387 , 14702 , 15024 , 15353 , 15689&lt;br /&gt;
  dw 16033 , 16384 , 16743 , 17109 , 17484 , 17867 , 18258 , 18658 , 19066 , 19484&lt;br /&gt;
  dw 19911 , 20347 , 20792 , 21247 , 21713 , 22188 , 22674 , 23170 , 23678 , 24196&lt;br /&gt;
  dw 24726 , 25268 , 25821 , 26386 , 26964 , 27554 , 28158 , 28774 , 29404 , 30048&lt;br /&gt;
  dw 30706 , 31379 , 32066 , 32768 , 33485 , 34219 , 34968 , 35734 , 36516 , 37316&lt;br /&gt;
  dw 38133 , 38968 , 39821 , 40693 , 41584 , 42495 , 43425 , 44376 , 45348 , 46341&lt;br /&gt;
  dw 47356 , 48393 , 49452 , 50535 , 51642 , 52772 , 53928 , 55109 , 56316 , 57549&lt;br /&gt;
  dw  58809 , 60097 , 61413 , 62757&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fastest, accurate 8bit * 8bit Unsigned  with 16 KB tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' L = Multiplier, C = Multiplicand&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 80 = 20 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 14 bytes of code + 16 KB tables&lt;br /&gt;
&lt;br /&gt;
I'm currently working on a new routine, based on a routine by Kirk Meyer [http://www.ticalc.org/pub/86/asm/source/routines/vfmult.asm] which uses nibble multiplication tables.&lt;br /&gt;
&lt;br /&gt;
I have a working, tested version which uses 16K of tables and can perform multiplication in 20&amp;amp;mu;s.&lt;br /&gt;
&lt;br /&gt;
The code to produce the tables is below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp1&lt;br /&gt;
ld a,l&lt;br /&gt;
rla&lt;br /&gt;
and #1e&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp1&lt;br /&gt;
inc h&lt;br /&gt;
.makelp2&lt;br /&gt;
ld a,l&lt;br /&gt;
rra:rra:rra&lt;br /&gt;
and #1e&lt;br /&gt;
jr z,usez&lt;br /&gt;
add restab2 - restab / 256 - 2&lt;br /&gt;
.usez&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp2&lt;br /&gt;
inc h			; restab&lt;br /&gt;
.makelp3&lt;br /&gt;
ld a,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
add l&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,0&lt;br /&gt;
adc d&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h:dec h:dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256 - 2&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
ld b,h&lt;br /&gt;
ld c,l&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp4&lt;br /&gt;
ld e,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
dec h&lt;br /&gt;
ex de,hl&lt;br /&gt;
add hl,hl:add hl,hl:add hl,hl:add hl,hl&lt;br /&gt;
ex de,hl&lt;br /&gt;
ld a,e&lt;br /&gt;
ld (bc),a&lt;br /&gt;
inc b&lt;br /&gt;
ld a,d&lt;br /&gt;
ld (bc),a&lt;br /&gt;
dec b&lt;br /&gt;
inc l&lt;br /&gt;
inc c&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
.restab2&lt;br /&gt;
ds 512 * 15&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code to perform the multiplication (DE = L * C):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ld h,hltab1 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
inc h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(bc)		; 10&lt;br /&gt;
add (hl)		; 12&lt;br /&gt;
ld e,a			; 13&lt;br /&gt;
inc b			; 14&lt;br /&gt;
inc h			; 15&lt;br /&gt;
ld a,(bc)		; 17&lt;br /&gt;
adc (hl)		; 19&lt;br /&gt;
ld d,a			; 20&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast, accurate 8bit * 8bit Unsigned  with 8 KB tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' L = Multiplier, C = Multiplicand&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 100 = 25 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 19 bytes of code + 8 KB tables&lt;br /&gt;
&lt;br /&gt;
16K is a lot of memory to use for tables, but I'm working on a way to reduce this to 8K while maintaining similar performance (around 26&amp;amp;mu;s). The idea is rather than using tables for the low and high nibbles, use tables for alternate bits. So there would be 16 tables for the values #00, #01, #04, #05, #10, #11, #14, #15, #40, #41, #44, #45, #50, #51, #54, #55. The values can be shifted by 1 (rather than 4) to give values for the alternate bits using a simple ADD HL,HL.&lt;br /&gt;
&lt;br /&gt;
This routine should be easy to adapt to a 16bit * 8bit unsigned multiplication or even a 16bit * 16bit, using simple additions.&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 03:58, 8 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
Ok, here is the new 8K routine, first the routine to build the tables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp5&lt;br /&gt;
ld a,l&lt;br /&gt;
ld bc,0&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
ld a,b&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,c&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp5&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp6&lt;br /&gt;
ld (hl),l&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp6&lt;br /&gt;
inc h:inc h&lt;br /&gt;
ld b,2&lt;br /&gt;
.makelp8&lt;br /&gt;
push bc&lt;br /&gt;
xor a&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
.makelp7&lt;br /&gt;
push hl&lt;br /&gt;
push af&lt;br /&gt;
call mulLbyA&lt;br /&gt;
ex de,hl&lt;br /&gt;
pop af&lt;br /&gt;
pop hl&lt;br /&gt;
ld (hl),e&lt;br /&gt;
inc h&lt;br /&gt;
ld (hl),d&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp7&lt;br /&gt;
inc h:inc h&lt;br /&gt;
pop bc&lt;br /&gt;
inc b&lt;br /&gt;
bit 4,b&lt;br /&gt;
jr z,makelp8&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
.mulLbyA	; MAX times	; MIN times&lt;br /&gt;
ld e,l		; 1		; 1&lt;br /&gt;
ld d,0		; 3		; 3&lt;br /&gt;
add a		; 4		; 4&lt;br /&gt;
ld h,a		; 5		; 5&lt;br /&gt;
jr c,ncad0	; 8		; 8&lt;br /&gt;
ld l,d		&lt;br /&gt;
.ncad0&lt;br /&gt;
add hl,hl	; 11		; 11&lt;br /&gt;
jr nc,ncad1	; 13		; 14&lt;br /&gt;
add hl,de	; 16&lt;br /&gt;
.ncad1&lt;br /&gt;
add hl,hl	; 19		; 17&lt;br /&gt;
jr nc,ncad2	; 21		; 20&lt;br /&gt;
add hl,de	; 24&lt;br /&gt;
.ncad2&lt;br /&gt;
add hl,hl	; 27		; 23&lt;br /&gt;
jr nc,ncad3	; 29		; 26&lt;br /&gt;
add hl,de	; 32&lt;br /&gt;
.ncad3&lt;br /&gt;
add hl,hl	; 35		; 29&lt;br /&gt;
jr nc,ncad4	; 37		; 32&lt;br /&gt;
add hl,de	; 40&lt;br /&gt;
.ncad4&lt;br /&gt;
add hl,hl	; 43		; 35&lt;br /&gt;
jr nc,ncad5	; 45		; 38&lt;br /&gt;
add hl,de	; 48&lt;br /&gt;
.ncad5&lt;br /&gt;
add hl,hl	; 51		; 41&lt;br /&gt;
jr nc,ncad6	; 53		; 44&lt;br /&gt;
add hl,de	; 56&lt;br /&gt;
.ncad6&lt;br /&gt;
add hl,hl	; 59		; 47&lt;br /&gt;
ld a,h		; 60		; 48&lt;br /&gt;
ret nc		; 61		; 50?&lt;br /&gt;
add hl,de	; 64&lt;br /&gt;
ld a,h		; 65&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the routine to do the multiplication:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.umultCL		; Using 8 bit only (25us - DE = L * C)&lt;br /&gt;
ld h,hltab2 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
dec h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(hl)		; 10&lt;br /&gt;
add a			; 11&lt;br /&gt;
inc h			; 12&lt;br /&gt;
ld d,(hl)		; 14&lt;br /&gt;
rl d			; 16&lt;br /&gt;
ld h,b			; 17&lt;br /&gt;
add (hl)		; 19&lt;br /&gt;
ld e,a			; 20&lt;br /&gt;
inc h			; 21&lt;br /&gt;
ld a,(hl)		; 23&lt;br /&gt;
adc d			; 24&lt;br /&gt;
ld d,a			; 25&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Very fast 8bit * 8bit Unsigned with only 1K of tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input''': B = Multiplier, C = Multiplicant&lt;br /&gt;
&lt;br /&gt;
'''Output''': DE = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles''': 104-112 (108 on average) = 26-28 (27) usec&lt;br /&gt;
&lt;br /&gt;
'''Size''': 24 bytes of code and 1024 bytes for the tables&lt;br /&gt;
&lt;br /&gt;
Here's a new routine I've developed which uses the formula ab = ((a + b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - (a - b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) / 4. It's based on a routine for the 6502 by Stephen Judd in a C= Hacking article. Because of differences between the way the 6502 does register indexing it was quite difficult to actually get this working, but it's a great compromise between speed and space since it only uses 1K of tables (as opposed to the 16K or 8K table routines above), and can still manage to do the job in a maximum of 28 microseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Firstly, once again, we need some code to generate the tables. These tables contain values for&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;/4 for 9 bit values of x, with the LSB when bit 8 is zero first followed by the MSB.&lt;br /&gt;
&amp;lt;pre&amp;gt;.gen_sq4&lt;br /&gt;
	xor a&lt;br /&gt;
	ld de,umul_tab + #1ff&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	ld h,d&lt;br /&gt;
	ld l,e&lt;br /&gt;
	inc e&lt;br /&gt;
	ld c,e&lt;br /&gt;
	ld b,2&lt;br /&gt;
&lt;br /&gt;
	.sq4_lp&lt;br /&gt;
	ld a,b&lt;br /&gt;
	cp 2&lt;br /&gt;
	ld a,e&lt;br /&gt;
	rra&lt;br /&gt;
	add (hl)&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	inc h&lt;br /&gt;
	inc d&lt;br /&gt;
	ld a,(hl)&lt;br /&gt;
	adc c&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld h,d&lt;br /&gt;
	inc l&lt;br /&gt;
	inc e&lt;br /&gt;
	jr nz,sq4_lp&lt;br /&gt;
	inc d&lt;br /&gt;
	inc d&lt;br /&gt;
	djnz sq4_lp&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
align #100&lt;br /&gt;
.umul_tab ds #400&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now for the actual multiply routine:&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', L = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ld h,umul_tab_lo / #100	; 2&lt;br /&gt;
	ld b,h			; 3&lt;br /&gt;
	add l			; 4&lt;br /&gt;
	ld c,a			; 5&lt;br /&gt;
	jr nc,@noovf		; 7&lt;br /&gt;
	inc b			; 8&lt;br /&gt;
	inc b			; 9&lt;br /&gt;
.@noovf&lt;br /&gt;
	sub l			; 10&lt;br /&gt;
	sub l			; 11&lt;br /&gt;
	jr nc,@noneg		; 13&lt;br /&gt;
	neg			; 15&lt;br /&gt;
.@noneg&lt;br /&gt;
	ld l,a			; 16&lt;br /&gt;
	ld a,(bc)		; 18&lt;br /&gt;
	sub (hl)		; 20&lt;br /&gt;
	ld e,a			; 21&lt;br /&gt;
	inc b			; 22&lt;br /&gt;
	inc h			; 23&lt;br /&gt;
	ld a,(bc)		; 25&lt;br /&gt;
	sbc (hl)		; 27&lt;br /&gt;
	ld d,a			; 28&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This code could easily be converted to a macro as it's only 24 bytes. I've tried to optimize it further but with no luck!&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 06:25, 4 April 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Fast 8bit * 8bit Unsigned with only 512 bytes of tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input''': A = Multiplier, B = Multiplicant&lt;br /&gt;
&lt;br /&gt;
'''Output''': A:E = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles''': 136-172 (154 on average) = 34-43 (38.5) usec&lt;br /&gt;
&lt;br /&gt;
'''Size''': 44 bytes of code and 512 bytes for the tables&lt;br /&gt;
&lt;br /&gt;
Fast 8 bit unsigned multiplication with 16 bit result. It uses formula&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  x*y = ((x+y)/2)^2 - ((x-y)/2)^2, if x+y is even&lt;br /&gt;
      = ((x+y-1)/2)^2 - ((x-y-1)/2)^2 + y, if x+y is odd and x&amp;gt;=y&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;    cp b&lt;br /&gt;
    jr nc,l1&lt;br /&gt;
&lt;br /&gt;
    ld e,a&lt;br /&gt;
    ld a,b&lt;br /&gt;
    ld b,e&lt;br /&gt;
&lt;br /&gt;
l1  ld c,a&lt;br /&gt;
    sub b&lt;br /&gt;
    rra&lt;br /&gt;
    ld d,a&lt;br /&gt;
    ld a,c&lt;br /&gt;
    add a,b&lt;br /&gt;
    rra&lt;br /&gt;
    ld l,a&lt;br /&gt;
    ld h,high(sqrlo)&lt;br /&gt;
    ld a,(hl)&lt;br /&gt;
    ld e,l&lt;br /&gt;
    ld l,d&lt;br /&gt;
    jr nc,l2&lt;br /&gt;
&lt;br /&gt;
    sub (hl)   ;odd&lt;br /&gt;
    ld l,e&lt;br /&gt;
    ld e,a&lt;br /&gt;
    inc h      ;loads high(sqrhi)&lt;br /&gt;
    ld a,(hl)&lt;br /&gt;
    ld l,d&lt;br /&gt;
    sbc a,(hl)&lt;br /&gt;
    ld d,a&lt;br /&gt;
&lt;br /&gt;
    ld a,e&lt;br /&gt;
    add a,b&lt;br /&gt;
    ld e,a&lt;br /&gt;
    ld a,d&lt;br /&gt;
    adc a,0&lt;br /&gt;
    ret&lt;br /&gt;
&lt;br /&gt;
l2  sub (hl)   ;even&lt;br /&gt;
    ld l,e&lt;br /&gt;
    ld e,a&lt;br /&gt;
    inc h&lt;br /&gt;
    ld a,(hl)&lt;br /&gt;
    ld l,d&lt;br /&gt;
    sbc a,(hl)&lt;br /&gt;
    ret&lt;br /&gt;
&lt;br /&gt;
sqrlo ;low(x*x)   should be at the page border&lt;br /&gt;
    db 0,1,4,9,$10,$19,$24,$31,$40,$51,$64,$79,$90,$a9,$c4,$e1&lt;br /&gt;
    db 0,$21,$44,$69,$90,$b9,$e4,$11,$40,$71,$a4,$d9,$10,$49,$84,$c1&lt;br /&gt;
    db 0,$41,$84,$c9,$10,$59,$a4,$f1,$40,$91,$e4,$39,$90,$e9,$44,$a1&lt;br /&gt;
    db 0,$61,$c4,$29,$90,$f9,$64,$d1,$40,$b1,$24,$99,$10,$89,4,$81&lt;br /&gt;
    db 0,$81,4,$89,$10,$99,$24,$b1,$40,$d1,$64,$f9,$90,$29,$c4,$61&lt;br /&gt;
    db 0,$a1,$44,$e9,$90,$39,$e4,$91,$40,$f1,$a4,$59,$10,$c9,$84,$41&lt;br /&gt;
    db 0,$c1,$84,$49,$10,$d9,$a4,$71,$40,$11,$e4,$b9,$90,$69,$44,$21&lt;br /&gt;
    db 0,$e1,$c4,$a9,$90,$79,$64,$51,$40,$31,$24,$19,$10,9,4,$1&lt;br /&gt;
    db 0,1,4,9,$10,$19,$24,$31,$40,$51,$64,$79,$90,$a9,$c4,$e1&lt;br /&gt;
    db 0,$21,$44,$69,$90,$b9,$e4,$11,$40,$71,$a4,$d9,$10,$49,$84,$c1&lt;br /&gt;
    db 0,$41,$84,$c9,$10,$59,$a4,$f1,$40,$91,$e4,$39,$90,$e9,$44,$a1&lt;br /&gt;
    db 0,$61,$c4,$29,$90,$f9,$64,$d1,$40,$b1,$24,$99,$10,$89,4,$81&lt;br /&gt;
    db 0,$81,4,$89,$10,$99,$24,$b1,$40,$d1,$64,$f9,$90,$29,$c4,$61&lt;br /&gt;
    db 0,$a1,$44,$e9,$90,$39,$e4,$91,$40,$f1,$a4,$59,$10,$c9,$84,$41&lt;br /&gt;
    db 0,$c1,$84,$49,$10,$d9,$a4,$71,$40,$11,$e4,$b9,$90,$69,$44,$21&lt;br /&gt;
    db 0,$e1,$c4,$a9,$90,$79,$64,$51,$40,$31,$24,$19,$10,9,4,$1&lt;br /&gt;
sqrhi ;high(x*x)&lt;br /&gt;
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
    db 1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3&lt;br /&gt;
    db 4,4,4,4,5,5,5,5,6,6,6,7,7,7,8,8&lt;br /&gt;
    db 9,9,9,$a,$a,$a,$b,$b,$c,$c,$d,$d,$e,$e,$f,$f&lt;br /&gt;
    db $10,$10,$11,$11,$12,$12,$13,$13,$14,$14,$15,$15,$16,$17,$17,$18&lt;br /&gt;
    db $19,$19,$1a,$1a,$1b,$1c,$1c,$1d,$1e,$1e,$1f,$20,$21,$21,$22,$23&lt;br /&gt;
    db $24,$24,$25,$26,$27,$27,$28,$29,$2a,$2b,$2b,$2c,$2d,$2e,$2f,$30&lt;br /&gt;
    db $31,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f&lt;br /&gt;
    db $40,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f&lt;br /&gt;
    db $51,$52,$53,$54,$55,$56,$57,$59,$5a,$5b,$5c,$5d,$5f,$60,$61,$62&lt;br /&gt;
    db $64,$65,$66,$67,$69,$6a,$6b,$6c,$6e,$6f,$70,$72,$73,$74,$76,$77&lt;br /&gt;
    db $79,$7a,$7b,$7d,$7e,$7f,$81,$82,$84,$85,$87,$88,$8a,$8b,$8d,$8e&lt;br /&gt;
    db $90,$91,$93,$94,$96,$97,$99,$9a,$9c,$9d,$9f,$a0,$a2,$a4,$a5,$a7&lt;br /&gt;
    db $a9,$aa,$ac,$ad,$af,$b1,$b2,$b4,$b6,$b7,$b9,$bb,$bd,$be,$c0,$c2&lt;br /&gt;
    db $c4,$c5,$c7,$c9,$cb,$cc,$ce,$d0,$d2,$d4,$d5,$d7,$d9,$db,$dd,$df&lt;br /&gt;
    db $e1,$e2,$e4,$e6,$e8,$ea,$ec,$ee,$f0,$f2,$f4,$f6,$f8,$fa,$fc,$fe&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[User:Litwr|Litwr]] 10:25, 24 October 2015 (CEST)&lt;br /&gt;
&lt;br /&gt;
== 16bit * 16bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' BC = ''Multiplier'', DE = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A,HL = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;ld ix,0&lt;br /&gt;
 ld hl,0&lt;br /&gt;
.mul24b1:&lt;br /&gt;
 ld a,c&lt;br /&gt;
 or b&lt;br /&gt;
 jr z,mul24b3&lt;br /&gt;
 srl b&lt;br /&gt;
 rr c&lt;br /&gt;
 jr nc,mul24b2&lt;br /&gt;
 add ix,de&lt;br /&gt;
 ld a,h&lt;br /&gt;
 adc l&lt;br /&gt;
 ld h,a&lt;br /&gt;
.mul24b2:&lt;br /&gt;
 sla e&lt;br /&gt;
 rl d&lt;br /&gt;
 rl l&lt;br /&gt;
 jr mul24b1:&lt;br /&gt;
.mul24b3:&lt;br /&gt;
 ld a,h&lt;br /&gt;
 db #dd:ld e,l&lt;br /&gt;
 db #dd:ld d,h&lt;br /&gt;
 ex de,hl&lt;br /&gt;
 ret&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://map.tni.nl/articles/mult_div_shifts.php Multiplications and divisions on the MSX Assembly Page]&lt;br /&gt;
* [http://www.mccw.hetlab.tk/92/Multiplication/en.html &amp;quot;Multiplication on a Z80&amp;quot; ( MSX Computer &amp;amp; Club Webmagazine)]&lt;br /&gt;
* [http://www.andreadrian.de/oldcpu/Z80_number_cruncher.html The Z80 number cruncher (Andre Adrian)] (16/32bit multiplication, addition, right shift)&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94468</id>
		<title>Programming:Integer Multiplication</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94468"/>
				<updated>2015-10-24T07:33:26Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: /* Very fast 8bit * 8bit Unsigned with only 512 bytes of tables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Classic 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' H = ''Multiplier'', E = ''Multiplicand'', L = 0, D = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 188-244 (216 on average) = 47-61 (54) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 33 bytes&lt;br /&gt;
&lt;br /&gt;
The additional clocks and bytes maybe required to set up D and L and for RET.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sla h  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+3&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
jr nc,$+3  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Classic 16bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', DE = ''Multiplicand'', HL = 0, C = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A:HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 212-300 (256 on average) = 53-75 (64) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 47 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add a,a  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+4&lt;br /&gt;
ld h,d&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
rla   ; ...&lt;br /&gt;
jr nc,$+4  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
adc a,c  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast 8bit * 8bit Unsigned (using log / antilog tables) ==&lt;br /&gt;
&lt;br /&gt;
The original routine was written by Jeff Frohwein for the Nintendo Gameboy. You can find it on [http://www.devrs.com/gb/files/logmult.txt Devrs.com].&lt;br /&gt;
&lt;br /&gt;
Because of the usage of log / antilog tables this routine is less accurate, but very fast. It takes advantage of the fact that if you take the log of two numbers, add the results and then take the antilog of the total you have done the equivalent of multiplying the two numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 x^a * x^b = x^(a+b)&lt;br /&gt;
&lt;br /&gt;
 a * b = x^(logx(a) + logx(b))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Input:''' B = ''Multiplier'', C = ''Multiplicant''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 124 = 31 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 1024 bytes (768 bytes for the tables)&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' It is VERY approximate routine, e.g., 0*7=7, 1*28=27, 10*81=790, 100*100=9742, ...&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FastMult:&lt;br /&gt;
  ld      l,c&lt;br /&gt;
  ld      h,&amp;amp;82&lt;br /&gt;
  ld      d,(hl)          ; d = 32 * log_2(c)&lt;br /&gt;
  &lt;br /&gt;
  ld      l,b&lt;br /&gt;
  ld      a,(hl)          ; a = 32 * log_2(b)&lt;br /&gt;
  &lt;br /&gt;
  add     a,d&lt;br /&gt;
  ld      l,a&lt;br /&gt;
  ld      a,0&lt;br /&gt;
  adc     a,0&lt;br /&gt;
  ld      h,a             ; hl = d + a&lt;br /&gt;
  &lt;br /&gt;
  add     hl,hl&lt;br /&gt;
  set     2,h             ; hl = hl + $0400&lt;br /&gt;
  set     7,h             ; hl = hl + &amp;amp;8000&lt;br /&gt;
  &lt;br /&gt;
  ld      e,(hl)&lt;br /&gt;
  inc     hl&lt;br /&gt;
  ld      d,(hl)          ; de = 2^((hl)/32)&lt;br /&gt;
  &lt;br /&gt;
  ret&lt;br /&gt;
&lt;br /&gt;
; 32*Log_2(x) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 TO 255&lt;br /&gt;
;     C=4 &lt;br /&gt;
;     B=2&lt;br /&gt;
;     FOR Z=1 TO 10&lt;br /&gt;
;       IF (2^C) &amp;gt; A THEN C=C-B ELSE C=C+B&lt;br /&gt;
;       B=B/2&lt;br /&gt;
;     NEXT Z&lt;br /&gt;
;     PRINT INT(C*32);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8200&lt;br /&gt;
&lt;br /&gt;
logtable:&lt;br /&gt;
  db 0 , 0 , 32 , 50 , 64 , 74 , 82 , 89 , 96 , 101 , 106 , 110 , 114 , 118 , 121&lt;br /&gt;
  db 125 , 128 , 130 , 133 , 135 , 138 , 140 , 142 , 144 , 146 , 148 , 150 , 152&lt;br /&gt;
  db 153 , 155 , 157 , 158 , 160 , 161 , 162 , 164 , 165 , 166 , 167 , 169 , 170&lt;br /&gt;
  db 171 , 172 , 173 , 174 , 175 , 176 , 177 , 178 , 179 , 180 , 181 , 182 , 183&lt;br /&gt;
  db 184 , 185 , 185 , 186 , 187 , 188 , 189 , 189 , 190 , 191 , 192 , 192 , 193&lt;br /&gt;
  db 194 , 194 , 195 , 196 , 196 , 197 , 198 , 198 , 199 , 199 , 200 , 201 , 201&lt;br /&gt;
  db 202 , 202 , 203 , 204 , 204 , 205 , 205 , 206 , 206 , 207 , 207 , 208 , 208&lt;br /&gt;
  db 209 , 209 , 210 , 210 , 211 , 211 , 212 , 212 , 213 , 213 , 213 , 214 , 214&lt;br /&gt;
  db 215 , 215 , 216 , 216 , 217 , 217 , 217 , 218 , 218 , 219 , 219 , 219 , 220&lt;br /&gt;
  db 220 , 221 , 221 , 221 , 222 , 222 , 222 , 223 , 223 , 224 , 224 , 224 , 225&lt;br /&gt;
  db 225 , 225 , 226 , 226 , 226 , 227 , 227 , 227 , 228 , 228 , 228 , 229 , 229&lt;br /&gt;
  db 229 , 230 , 230 , 230 , 231 , 231 , 231 , 231 , 232 , 232 , 232 , 233 , 233&lt;br /&gt;
  db 233 , 234 , 234 , 234 , 234 , 235 , 235 , 235 , 236 , 236 , 236 , 236 , 237&lt;br /&gt;
  db 237 , 237 , 237 , 238 , 238 , 238 , 238 , 239 , 239 , 239 , 239 , 240 , 240&lt;br /&gt;
  db 240 , 241 , 241 , 241 , 241 , 241 , 242 , 242 , 242 , 242 , 243 , 243 , 243&lt;br /&gt;
  db 243 , 244 , 244 , 244 , 244 , 245 , 245 , 245 , 245 , 245 , 246 , 246 , 246&lt;br /&gt;
  db 246 , 247 , 247 , 247 , 247 , 247 , 248 , 248 , 248 , 248 , 249 , 249 , 249&lt;br /&gt;
  db 249 , 249 , 250 , 250 , 250 , 250 , 250 , 251 , 251 , 251 , 251 , 251 , 252&lt;br /&gt;
  db 252 , 252 , 252 , 252 , 253 , 253 , 253 , 253 , 253 , 253 , 254 , 254 , 254&lt;br /&gt;
  db 254 , 254 , 255 , 255 , 255 , 255 , 255&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; AntiLog 2^(x/32) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 to 510&lt;br /&gt;
;   PRINT INT(2^(A/32)+.5);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8400&lt;br /&gt;
&lt;br /&gt;
antilog:&lt;br /&gt;
  dw 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 , 4&lt;br /&gt;
  dw 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 6&lt;br /&gt;
  dw 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 8 , 9&lt;br /&gt;
  dw 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , 12 , 12 , 12&lt;br /&gt;
  dw 13 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17&lt;br /&gt;
  dw 18 , 18 , 19 , 19 , 19 , 20 , 20 , 21 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25&lt;br /&gt;
  dw 25 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , 30 , 31 , 31 , 32 , 33 , 33 , 34 , 35&lt;br /&gt;
  dw 36 , 36 , 37 , 38 , 39 , 40 , 41 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49&lt;br /&gt;
  dw 50 , 52 , 53 , 54 , 55 , 56 , 57 , 59 , 60 , 61 , 63 , 64 , 65 , 67 , 68 , 70&lt;br /&gt;
  dw 71 , 73 , 74 , 76 , 78 , 79 , 81 , 83 , 85 , 87 , 89 , 91 , 92 , 95 , 97 , 99&lt;br /&gt;
  dw 101 , 103 , 105 , 108 , 110 , 112 , 115 , 117 , 120 , 123 , 125 , 128 , 131&lt;br /&gt;
  dw 134 , 137 , 140 , 143 , 146 , 149 , 152 , 156 , 159 , 162 , 166 , 170 , 173&lt;br /&gt;
  dw 177 , 181 , 185 , 189 , 193 , 197 , 202 , 206 , 211 , 215 , 220 , 225 , 230&lt;br /&gt;
  dw 235 , 240 , 245 , 251 , 256 , 262 , 267 , 273 , 279 , 285 , 292 , 298 , 304&lt;br /&gt;
  dw 311 , 318 , 325 , 332 , 339 , 347 , 354 , 362 , 370 , 378 , 386 , 395 , 403&lt;br /&gt;
  dw 412 , 421 , 431 , 440 , 450 , 459 , 470 , 480 , 490 , 501 , 512 , 523 , 535&lt;br /&gt;
  dw 546 , 558 , 571 , 583 , 596 , 609 , 622 , 636 , 650 , 664 , 679 , 693 , 709&lt;br /&gt;
  dw 724 , 740 , 756 , 773 , 790 , 807 , 825 , 843 , 861 , 880 , 899 , 919 , 939&lt;br /&gt;
  dw 960 , 981 , 1002 , 1024 , 1046 , 1069 , 1093 , 1117 , 1141 , 1166 , 1192&lt;br /&gt;
  dw 1218 , 1244 , 1272 , 1300 , 1328 , 1357 , 1387 , 1417 , 1448 , 1480 , 1512&lt;br /&gt;
  dw 1545 , 1579 , 1614 , 1649 , 1685 , 1722 , 1760 , 1798 , 1838 , 1878 , 1919&lt;br /&gt;
  dw 1961 , 2004 , 2048 , 2093 , 2139 , 2186 , 2233 , 2282 , 2332 , 2383 , 2435&lt;br /&gt;
  dw 2489 , 2543 , 2599 , 2656 , 2714 , 2774 , 2834 , 2896 , 2960 , 3025 , 3091&lt;br /&gt;
  dw 3158 , 3228 , 3298 , 3371 , 3444 , 3520 , 3597 , 3676 , 3756 , 3838 , 3922&lt;br /&gt;
  dw 4008 , 4096 , 4186 , 4277 , 4371 , 4467 , 4565 , 4664 , 4767 , 4871 , 4978&lt;br /&gt;
  dw 5087 , 5198 , 5312 , 5428 , 5547 , 5668 , 5793 , 5919 , 6049 , 6182 , 6317&lt;br /&gt;
  dw 6455 , 6597 , 6741 , 6889 , 7039 , 7194 , 7351 , 7512 , 7677 , 7845 , 8016&lt;br /&gt;
  dw 8192 , 8371 , 8555 , 8742 , 8933 , 9129 , 9329 , 9533 , 9742 , 9955 , 10173&lt;br /&gt;
  dw 10396 , 10624 , 10856 , 11094 , 11337 , 11585 , 11839 , 12098 , 12363 , 12634&lt;br /&gt;
  dw 12910 , 13193 , 13482 , 13777 , 14079 , 14387 , 14702 , 15024 , 15353 , 15689&lt;br /&gt;
  dw 16033 , 16384 , 16743 , 17109 , 17484 , 17867 , 18258 , 18658 , 19066 , 19484&lt;br /&gt;
  dw 19911 , 20347 , 20792 , 21247 , 21713 , 22188 , 22674 , 23170 , 23678 , 24196&lt;br /&gt;
  dw 24726 , 25268 , 25821 , 26386 , 26964 , 27554 , 28158 , 28774 , 29404 , 30048&lt;br /&gt;
  dw 30706 , 31379 , 32066 , 32768 , 33485 , 34219 , 34968 , 35734 , 36516 , 37316&lt;br /&gt;
  dw 38133 , 38968 , 39821 , 40693 , 41584 , 42495 , 43425 , 44376 , 45348 , 46341&lt;br /&gt;
  dw 47356 , 48393 , 49452 , 50535 , 51642 , 52772 , 53928 , 55109 , 56316 , 57549&lt;br /&gt;
  dw  58809 , 60097 , 61413 , 62757&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fastest, accurate 8bit * 8bit Unsigned  with 16 KB tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' L = Multiplier, C = Multiplicand&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 80 = 20 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 14 bytes of code + 16 KB tables&lt;br /&gt;
&lt;br /&gt;
I'm currently working on a new routine, based on a routine by Kirk Meyer [http://www.ticalc.org/pub/86/asm/source/routines/vfmult.asm] which uses nibble multiplication tables.&lt;br /&gt;
&lt;br /&gt;
I have a working, tested version which uses 16K of tables and can perform multiplication in 20&amp;amp;mu;s.&lt;br /&gt;
&lt;br /&gt;
The code to produce the tables is below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp1&lt;br /&gt;
ld a,l&lt;br /&gt;
rla&lt;br /&gt;
and #1e&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp1&lt;br /&gt;
inc h&lt;br /&gt;
.makelp2&lt;br /&gt;
ld a,l&lt;br /&gt;
rra:rra:rra&lt;br /&gt;
and #1e&lt;br /&gt;
jr z,usez&lt;br /&gt;
add restab2 - restab / 256 - 2&lt;br /&gt;
.usez&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp2&lt;br /&gt;
inc h			; restab&lt;br /&gt;
.makelp3&lt;br /&gt;
ld a,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
add l&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,0&lt;br /&gt;
adc d&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h:dec h:dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256 - 2&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
ld b,h&lt;br /&gt;
ld c,l&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp4&lt;br /&gt;
ld e,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
dec h&lt;br /&gt;
ex de,hl&lt;br /&gt;
add hl,hl:add hl,hl:add hl,hl:add hl,hl&lt;br /&gt;
ex de,hl&lt;br /&gt;
ld a,e&lt;br /&gt;
ld (bc),a&lt;br /&gt;
inc b&lt;br /&gt;
ld a,d&lt;br /&gt;
ld (bc),a&lt;br /&gt;
dec b&lt;br /&gt;
inc l&lt;br /&gt;
inc c&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
.restab2&lt;br /&gt;
ds 512 * 15&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code to perform the multiplication (DE = L * C):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ld h,hltab1 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
inc h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(bc)		; 10&lt;br /&gt;
add (hl)		; 12&lt;br /&gt;
ld e,a			; 13&lt;br /&gt;
inc b			; 14&lt;br /&gt;
inc h			; 15&lt;br /&gt;
ld a,(bc)		; 17&lt;br /&gt;
adc (hl)		; 19&lt;br /&gt;
ld d,a			; 20&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast, accurate 8bit * 8bit Unsigned  with 8 KB tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' L = Multiplier, C = Multiplicand&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 100 = 25 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 19 bytes of code + 8 KB tables&lt;br /&gt;
&lt;br /&gt;
16K is a lot of memory to use for tables, but I'm working on a way to reduce this to 8K while maintaining similar performance (around 26&amp;amp;mu;s). The idea is rather than using tables for the low and high nibbles, use tables for alternate bits. So there would be 16 tables for the values #00, #01, #04, #05, #10, #11, #14, #15, #40, #41, #44, #45, #50, #51, #54, #55. The values can be shifted by 1 (rather than 4) to give values for the alternate bits using a simple ADD HL,HL.&lt;br /&gt;
&lt;br /&gt;
This routine should be easy to adapt to a 16bit * 8bit unsigned multiplication or even a 16bit * 16bit, using simple additions.&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 03:58, 8 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
Ok, here is the new 8K routine, first the routine to build the tables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp5&lt;br /&gt;
ld a,l&lt;br /&gt;
ld bc,0&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
ld a,b&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,c&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp5&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp6&lt;br /&gt;
ld (hl),l&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp6&lt;br /&gt;
inc h:inc h&lt;br /&gt;
ld b,2&lt;br /&gt;
.makelp8&lt;br /&gt;
push bc&lt;br /&gt;
xor a&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
.makelp7&lt;br /&gt;
push hl&lt;br /&gt;
push af&lt;br /&gt;
call mulLbyA&lt;br /&gt;
ex de,hl&lt;br /&gt;
pop af&lt;br /&gt;
pop hl&lt;br /&gt;
ld (hl),e&lt;br /&gt;
inc h&lt;br /&gt;
ld (hl),d&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp7&lt;br /&gt;
inc h:inc h&lt;br /&gt;
pop bc&lt;br /&gt;
inc b&lt;br /&gt;
bit 4,b&lt;br /&gt;
jr z,makelp8&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
.mulLbyA	; MAX times	; MIN times&lt;br /&gt;
ld e,l		; 1		; 1&lt;br /&gt;
ld d,0		; 3		; 3&lt;br /&gt;
add a		; 4		; 4&lt;br /&gt;
ld h,a		; 5		; 5&lt;br /&gt;
jr c,ncad0	; 8		; 8&lt;br /&gt;
ld l,d		&lt;br /&gt;
.ncad0&lt;br /&gt;
add hl,hl	; 11		; 11&lt;br /&gt;
jr nc,ncad1	; 13		; 14&lt;br /&gt;
add hl,de	; 16&lt;br /&gt;
.ncad1&lt;br /&gt;
add hl,hl	; 19		; 17&lt;br /&gt;
jr nc,ncad2	; 21		; 20&lt;br /&gt;
add hl,de	; 24&lt;br /&gt;
.ncad2&lt;br /&gt;
add hl,hl	; 27		; 23&lt;br /&gt;
jr nc,ncad3	; 29		; 26&lt;br /&gt;
add hl,de	; 32&lt;br /&gt;
.ncad3&lt;br /&gt;
add hl,hl	; 35		; 29&lt;br /&gt;
jr nc,ncad4	; 37		; 32&lt;br /&gt;
add hl,de	; 40&lt;br /&gt;
.ncad4&lt;br /&gt;
add hl,hl	; 43		; 35&lt;br /&gt;
jr nc,ncad5	; 45		; 38&lt;br /&gt;
add hl,de	; 48&lt;br /&gt;
.ncad5&lt;br /&gt;
add hl,hl	; 51		; 41&lt;br /&gt;
jr nc,ncad6	; 53		; 44&lt;br /&gt;
add hl,de	; 56&lt;br /&gt;
.ncad6&lt;br /&gt;
add hl,hl	; 59		; 47&lt;br /&gt;
ld a,h		; 60		; 48&lt;br /&gt;
ret nc		; 61		; 50?&lt;br /&gt;
add hl,de	; 64&lt;br /&gt;
ld a,h		; 65&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the routine to do the multiplication:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.umultCL		; Using 8 bit only (25us - DE = L * C)&lt;br /&gt;
ld h,hltab2 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
dec h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(hl)		; 10&lt;br /&gt;
add a			; 11&lt;br /&gt;
inc h			; 12&lt;br /&gt;
ld d,(hl)		; 14&lt;br /&gt;
rl d			; 16&lt;br /&gt;
ld h,b			; 17&lt;br /&gt;
add (hl)		; 19&lt;br /&gt;
ld e,a			; 20&lt;br /&gt;
inc h			; 21&lt;br /&gt;
ld a,(hl)		; 23&lt;br /&gt;
adc d			; 24&lt;br /&gt;
ld d,a			; 25&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Very fast 8bit * 8bit Unsigned with only 1K of tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input''': B = Multiplier, C = Multiplicant&lt;br /&gt;
&lt;br /&gt;
'''Output''': DE = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles''': 104-112 (108 on average) = 26-28 (27) usec&lt;br /&gt;
&lt;br /&gt;
'''Size''': 24 bytes of code and 1024 bytes for the tables&lt;br /&gt;
&lt;br /&gt;
Here's a new routine I've developed which uses the formula ab = ((a + b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - (a - b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) / 4. It's based on a routine for the 6502 by Stephen Judd in a C= Hacking article. Because of differences between the way the 6502 does register indexing it was quite difficult to actually get this working, but it's a great compromise between speed and space since it only uses 1K of tables (as opposed to the 16K or 8K table routines above), and can still manage to do the job in a maximum of 28 microseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Firstly, once again, we need some code to generate the tables. These tables contain values for&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;/4 for 9 bit values of x, with the LSB when bit 8 is zero first followed by the MSB.&lt;br /&gt;
&amp;lt;pre&amp;gt;.gen_sq4&lt;br /&gt;
	xor a&lt;br /&gt;
	ld de,umul_tab + #1ff&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	ld h,d&lt;br /&gt;
	ld l,e&lt;br /&gt;
	inc e&lt;br /&gt;
	ld c,e&lt;br /&gt;
	ld b,2&lt;br /&gt;
&lt;br /&gt;
	.sq4_lp&lt;br /&gt;
	ld a,b&lt;br /&gt;
	cp 2&lt;br /&gt;
	ld a,e&lt;br /&gt;
	rra&lt;br /&gt;
	add (hl)&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	inc h&lt;br /&gt;
	inc d&lt;br /&gt;
	ld a,(hl)&lt;br /&gt;
	adc c&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld h,d&lt;br /&gt;
	inc l&lt;br /&gt;
	inc e&lt;br /&gt;
	jr nz,sq4_lp&lt;br /&gt;
	inc d&lt;br /&gt;
	inc d&lt;br /&gt;
	djnz sq4_lp&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
align #100&lt;br /&gt;
.umul_tab ds #400&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now for the actual multiply routine:&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', L = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ld h,umul_tab_lo / #100	; 2&lt;br /&gt;
	ld b,h			; 3&lt;br /&gt;
	add l			; 4&lt;br /&gt;
	ld c,a			; 5&lt;br /&gt;
	jr nc,@noovf		; 7&lt;br /&gt;
	inc b			; 8&lt;br /&gt;
	inc b			; 9&lt;br /&gt;
.@noovf&lt;br /&gt;
	sub l			; 10&lt;br /&gt;
	sub l			; 11&lt;br /&gt;
	jr nc,@noneg		; 13&lt;br /&gt;
	neg			; 15&lt;br /&gt;
.@noneg&lt;br /&gt;
	ld l,a			; 16&lt;br /&gt;
	ld a,(bc)		; 18&lt;br /&gt;
	sub (hl)		; 20&lt;br /&gt;
	ld e,a			; 21&lt;br /&gt;
	inc b			; 22&lt;br /&gt;
	inc h			; 23&lt;br /&gt;
	ld a,(bc)		; 25&lt;br /&gt;
	sbc (hl)		; 27&lt;br /&gt;
	ld d,a			; 28&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This code could easily be converted to a macro as it's only 24 bytes. I've tried to optimize it further but with no luck!&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 06:25, 4 April 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Fast 8bit * 8bit Unsigned with only 512 bytes of tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input''': A = Multiplier, B = Multiplicant&lt;br /&gt;
&lt;br /&gt;
'''Output''': A:E = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles''': 136-172 (154 on average) = 26-28 (27) usec&lt;br /&gt;
&lt;br /&gt;
'''Size''': 44 bytes of code and 512 bytes for the tables&lt;br /&gt;
&lt;br /&gt;
Fast 8 bit unsigned multiplication with 16 bit result. It uses formula&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  x*y = ((x+y)/2)^2 - ((x-y)/2)^2, if x+y is even&lt;br /&gt;
      = ((x+y-1)/2)^2 - ((x-y-1)/2)^2 + y, if x+y is odd and x&amp;gt;=y&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;    cp b&lt;br /&gt;
    jr nc,l1&lt;br /&gt;
&lt;br /&gt;
    ld e,a&lt;br /&gt;
    ld a,b&lt;br /&gt;
    ld b,e&lt;br /&gt;
&lt;br /&gt;
l1  ld c,a&lt;br /&gt;
    sub b&lt;br /&gt;
    rra&lt;br /&gt;
    ld d,a&lt;br /&gt;
    ld a,c&lt;br /&gt;
    add a,b&lt;br /&gt;
    rra&lt;br /&gt;
    ld l,a&lt;br /&gt;
    ld h,high(sqrlo)&lt;br /&gt;
    ld a,(hl)&lt;br /&gt;
    ld e,l&lt;br /&gt;
    ld l,d&lt;br /&gt;
    jr nc,l2&lt;br /&gt;
&lt;br /&gt;
    sub (hl)   ;odd&lt;br /&gt;
    ld l,e&lt;br /&gt;
    ld e,a&lt;br /&gt;
    inc h      ;loads high(sqrhi)&lt;br /&gt;
    ld a,(hl)&lt;br /&gt;
    ld l,d&lt;br /&gt;
    sbc a,(hl)&lt;br /&gt;
    ld d,a&lt;br /&gt;
&lt;br /&gt;
    ld a,e&lt;br /&gt;
    add a,b&lt;br /&gt;
    ld e,a&lt;br /&gt;
    ld a,d&lt;br /&gt;
    adc a,0&lt;br /&gt;
    ret&lt;br /&gt;
&lt;br /&gt;
l2  sub (hl)   ;even&lt;br /&gt;
    ld l,e&lt;br /&gt;
    ld e,a&lt;br /&gt;
    inc h&lt;br /&gt;
    ld a,(hl)&lt;br /&gt;
    ld l,d&lt;br /&gt;
    sbc a,(hl)&lt;br /&gt;
    ret&lt;br /&gt;
&lt;br /&gt;
sqrlo ;low(x*x)   should be at the page border&lt;br /&gt;
    db 0,1,4,9,$10,$19,$24,$31,$40,$51,$64,$79,$90,$a9,$c4,$e1&lt;br /&gt;
    db 0,$21,$44,$69,$90,$b9,$e4,$11,$40,$71,$a4,$d9,$10,$49,$84,$c1&lt;br /&gt;
    db 0,$41,$84,$c9,$10,$59,$a4,$f1,$40,$91,$e4,$39,$90,$e9,$44,$a1&lt;br /&gt;
    db 0,$61,$c4,$29,$90,$f9,$64,$d1,$40,$b1,$24,$99,$10,$89,4,$81&lt;br /&gt;
    db 0,$81,4,$89,$10,$99,$24,$b1,$40,$d1,$64,$f9,$90,$29,$c4,$61&lt;br /&gt;
    db 0,$a1,$44,$e9,$90,$39,$e4,$91,$40,$f1,$a4,$59,$10,$c9,$84,$41&lt;br /&gt;
    db 0,$c1,$84,$49,$10,$d9,$a4,$71,$40,$11,$e4,$b9,$90,$69,$44,$21&lt;br /&gt;
    db 0,$e1,$c4,$a9,$90,$79,$64,$51,$40,$31,$24,$19,$10,9,4,$1&lt;br /&gt;
    db 0,1,4,9,$10,$19,$24,$31,$40,$51,$64,$79,$90,$a9,$c4,$e1&lt;br /&gt;
    db 0,$21,$44,$69,$90,$b9,$e4,$11,$40,$71,$a4,$d9,$10,$49,$84,$c1&lt;br /&gt;
    db 0,$41,$84,$c9,$10,$59,$a4,$f1,$40,$91,$e4,$39,$90,$e9,$44,$a1&lt;br /&gt;
    db 0,$61,$c4,$29,$90,$f9,$64,$d1,$40,$b1,$24,$99,$10,$89,4,$81&lt;br /&gt;
    db 0,$81,4,$89,$10,$99,$24,$b1,$40,$d1,$64,$f9,$90,$29,$c4,$61&lt;br /&gt;
    db 0,$a1,$44,$e9,$90,$39,$e4,$91,$40,$f1,$a4,$59,$10,$c9,$84,$41&lt;br /&gt;
    db 0,$c1,$84,$49,$10,$d9,$a4,$71,$40,$11,$e4,$b9,$90,$69,$44,$21&lt;br /&gt;
    db 0,$e1,$c4,$a9,$90,$79,$64,$51,$40,$31,$24,$19,$10,9,4,$1&lt;br /&gt;
sqrhi ;high(x*x)&lt;br /&gt;
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
    db 1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3&lt;br /&gt;
    db 4,4,4,4,5,5,5,5,6,6,6,7,7,7,8,8&lt;br /&gt;
    db 9,9,9,$a,$a,$a,$b,$b,$c,$c,$d,$d,$e,$e,$f,$f&lt;br /&gt;
    db $10,$10,$11,$11,$12,$12,$13,$13,$14,$14,$15,$15,$16,$17,$17,$18&lt;br /&gt;
    db $19,$19,$1a,$1a,$1b,$1c,$1c,$1d,$1e,$1e,$1f,$20,$21,$21,$22,$23&lt;br /&gt;
    db $24,$24,$25,$26,$27,$27,$28,$29,$2a,$2b,$2b,$2c,$2d,$2e,$2f,$30&lt;br /&gt;
    db $31,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f&lt;br /&gt;
    db $40,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f&lt;br /&gt;
    db $51,$52,$53,$54,$55,$56,$57,$59,$5a,$5b,$5c,$5d,$5f,$60,$61,$62&lt;br /&gt;
    db $64,$65,$66,$67,$69,$6a,$6b,$6c,$6e,$6f,$70,$72,$73,$74,$76,$77&lt;br /&gt;
    db $79,$7a,$7b,$7d,$7e,$7f,$81,$82,$84,$85,$87,$88,$8a,$8b,$8d,$8e&lt;br /&gt;
    db $90,$91,$93,$94,$96,$97,$99,$9a,$9c,$9d,$9f,$a0,$a2,$a4,$a5,$a7&lt;br /&gt;
    db $a9,$aa,$ac,$ad,$af,$b1,$b2,$b4,$b6,$b7,$b9,$bb,$bd,$be,$c0,$c2&lt;br /&gt;
    db $c4,$c5,$c7,$c9,$cb,$cc,$ce,$d0,$d2,$d4,$d5,$d7,$d9,$db,$dd,$df&lt;br /&gt;
    db $e1,$e2,$e4,$e6,$e8,$ea,$ec,$ee,$f0,$f2,$f4,$f6,$f8,$fa,$fc,$fe&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[User:Litwr|Litwr]] 10:25, 24 October 2015 (CEST)&lt;br /&gt;
&lt;br /&gt;
== 16bit * 16bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' BC = ''Multiplier'', DE = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A,HL = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;ld ix,0&lt;br /&gt;
 ld hl,0&lt;br /&gt;
.mul24b1:&lt;br /&gt;
 ld a,c&lt;br /&gt;
 or b&lt;br /&gt;
 jr z,mul24b3&lt;br /&gt;
 srl b&lt;br /&gt;
 rr c&lt;br /&gt;
 jr nc,mul24b2&lt;br /&gt;
 add ix,de&lt;br /&gt;
 ld a,h&lt;br /&gt;
 adc l&lt;br /&gt;
 ld h,a&lt;br /&gt;
.mul24b2:&lt;br /&gt;
 sla e&lt;br /&gt;
 rl d&lt;br /&gt;
 rl l&lt;br /&gt;
 jr mul24b1:&lt;br /&gt;
.mul24b3:&lt;br /&gt;
 ld a,h&lt;br /&gt;
 db #dd:ld e,l&lt;br /&gt;
 db #dd:ld d,h&lt;br /&gt;
 ex de,hl&lt;br /&gt;
 ret&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://map.tni.nl/articles/mult_div_shifts.php Multiplications and divisions on the MSX Assembly Page]&lt;br /&gt;
* [http://www.mccw.hetlab.tk/92/Multiplication/en.html &amp;quot;Multiplication on a Z80&amp;quot; ( MSX Computer &amp;amp; Club Webmagazine)]&lt;br /&gt;
* [http://www.andreadrian.de/oldcpu/Z80_number_cruncher.html The Z80 number cruncher (Andre Adrian)] (16/32bit multiplication, addition, right shift)&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94467</id>
		<title>Programming:Integer Multiplication</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94467"/>
				<updated>2015-10-24T07:32:38Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: /* Very fast 8bit * 8bit Unsigned with only 1K of tables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Classic 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' H = ''Multiplier'', E = ''Multiplicand'', L = 0, D = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 188-244 (216 on average) = 47-61 (54) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 33 bytes&lt;br /&gt;
&lt;br /&gt;
The additional clocks and bytes maybe required to set up D and L and for RET.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sla h  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+3&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
jr nc,$+3  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Classic 16bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', DE = ''Multiplicand'', HL = 0, C = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A:HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 212-300 (256 on average) = 53-75 (64) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 47 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add a,a  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+4&lt;br /&gt;
ld h,d&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
rla   ; ...&lt;br /&gt;
jr nc,$+4  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
adc a,c  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast 8bit * 8bit Unsigned (using log / antilog tables) ==&lt;br /&gt;
&lt;br /&gt;
The original routine was written by Jeff Frohwein for the Nintendo Gameboy. You can find it on [http://www.devrs.com/gb/files/logmult.txt Devrs.com].&lt;br /&gt;
&lt;br /&gt;
Because of the usage of log / antilog tables this routine is less accurate, but very fast. It takes advantage of the fact that if you take the log of two numbers, add the results and then take the antilog of the total you have done the equivalent of multiplying the two numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 x^a * x^b = x^(a+b)&lt;br /&gt;
&lt;br /&gt;
 a * b = x^(logx(a) + logx(b))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Input:''' B = ''Multiplier'', C = ''Multiplicant''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 124 = 31 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 1024 bytes (768 bytes for the tables)&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' It is VERY approximate routine, e.g., 0*7=7, 1*28=27, 10*81=790, 100*100=9742, ...&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FastMult:&lt;br /&gt;
  ld      l,c&lt;br /&gt;
  ld      h,&amp;amp;82&lt;br /&gt;
  ld      d,(hl)          ; d = 32 * log_2(c)&lt;br /&gt;
  &lt;br /&gt;
  ld      l,b&lt;br /&gt;
  ld      a,(hl)          ; a = 32 * log_2(b)&lt;br /&gt;
  &lt;br /&gt;
  add     a,d&lt;br /&gt;
  ld      l,a&lt;br /&gt;
  ld      a,0&lt;br /&gt;
  adc     a,0&lt;br /&gt;
  ld      h,a             ; hl = d + a&lt;br /&gt;
  &lt;br /&gt;
  add     hl,hl&lt;br /&gt;
  set     2,h             ; hl = hl + $0400&lt;br /&gt;
  set     7,h             ; hl = hl + &amp;amp;8000&lt;br /&gt;
  &lt;br /&gt;
  ld      e,(hl)&lt;br /&gt;
  inc     hl&lt;br /&gt;
  ld      d,(hl)          ; de = 2^((hl)/32)&lt;br /&gt;
  &lt;br /&gt;
  ret&lt;br /&gt;
&lt;br /&gt;
; 32*Log_2(x) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 TO 255&lt;br /&gt;
;     C=4 &lt;br /&gt;
;     B=2&lt;br /&gt;
;     FOR Z=1 TO 10&lt;br /&gt;
;       IF (2^C) &amp;gt; A THEN C=C-B ELSE C=C+B&lt;br /&gt;
;       B=B/2&lt;br /&gt;
;     NEXT Z&lt;br /&gt;
;     PRINT INT(C*32);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8200&lt;br /&gt;
&lt;br /&gt;
logtable:&lt;br /&gt;
  db 0 , 0 , 32 , 50 , 64 , 74 , 82 , 89 , 96 , 101 , 106 , 110 , 114 , 118 , 121&lt;br /&gt;
  db 125 , 128 , 130 , 133 , 135 , 138 , 140 , 142 , 144 , 146 , 148 , 150 , 152&lt;br /&gt;
  db 153 , 155 , 157 , 158 , 160 , 161 , 162 , 164 , 165 , 166 , 167 , 169 , 170&lt;br /&gt;
  db 171 , 172 , 173 , 174 , 175 , 176 , 177 , 178 , 179 , 180 , 181 , 182 , 183&lt;br /&gt;
  db 184 , 185 , 185 , 186 , 187 , 188 , 189 , 189 , 190 , 191 , 192 , 192 , 193&lt;br /&gt;
  db 194 , 194 , 195 , 196 , 196 , 197 , 198 , 198 , 199 , 199 , 200 , 201 , 201&lt;br /&gt;
  db 202 , 202 , 203 , 204 , 204 , 205 , 205 , 206 , 206 , 207 , 207 , 208 , 208&lt;br /&gt;
  db 209 , 209 , 210 , 210 , 211 , 211 , 212 , 212 , 213 , 213 , 213 , 214 , 214&lt;br /&gt;
  db 215 , 215 , 216 , 216 , 217 , 217 , 217 , 218 , 218 , 219 , 219 , 219 , 220&lt;br /&gt;
  db 220 , 221 , 221 , 221 , 222 , 222 , 222 , 223 , 223 , 224 , 224 , 224 , 225&lt;br /&gt;
  db 225 , 225 , 226 , 226 , 226 , 227 , 227 , 227 , 228 , 228 , 228 , 229 , 229&lt;br /&gt;
  db 229 , 230 , 230 , 230 , 231 , 231 , 231 , 231 , 232 , 232 , 232 , 233 , 233&lt;br /&gt;
  db 233 , 234 , 234 , 234 , 234 , 235 , 235 , 235 , 236 , 236 , 236 , 236 , 237&lt;br /&gt;
  db 237 , 237 , 237 , 238 , 238 , 238 , 238 , 239 , 239 , 239 , 239 , 240 , 240&lt;br /&gt;
  db 240 , 241 , 241 , 241 , 241 , 241 , 242 , 242 , 242 , 242 , 243 , 243 , 243&lt;br /&gt;
  db 243 , 244 , 244 , 244 , 244 , 245 , 245 , 245 , 245 , 245 , 246 , 246 , 246&lt;br /&gt;
  db 246 , 247 , 247 , 247 , 247 , 247 , 248 , 248 , 248 , 248 , 249 , 249 , 249&lt;br /&gt;
  db 249 , 249 , 250 , 250 , 250 , 250 , 250 , 251 , 251 , 251 , 251 , 251 , 252&lt;br /&gt;
  db 252 , 252 , 252 , 252 , 253 , 253 , 253 , 253 , 253 , 253 , 254 , 254 , 254&lt;br /&gt;
  db 254 , 254 , 255 , 255 , 255 , 255 , 255&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; AntiLog 2^(x/32) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 to 510&lt;br /&gt;
;   PRINT INT(2^(A/32)+.5);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8400&lt;br /&gt;
&lt;br /&gt;
antilog:&lt;br /&gt;
  dw 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 , 4&lt;br /&gt;
  dw 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 6&lt;br /&gt;
  dw 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 8 , 9&lt;br /&gt;
  dw 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , 12 , 12 , 12&lt;br /&gt;
  dw 13 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17&lt;br /&gt;
  dw 18 , 18 , 19 , 19 , 19 , 20 , 20 , 21 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25&lt;br /&gt;
  dw 25 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , 30 , 31 , 31 , 32 , 33 , 33 , 34 , 35&lt;br /&gt;
  dw 36 , 36 , 37 , 38 , 39 , 40 , 41 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49&lt;br /&gt;
  dw 50 , 52 , 53 , 54 , 55 , 56 , 57 , 59 , 60 , 61 , 63 , 64 , 65 , 67 , 68 , 70&lt;br /&gt;
  dw 71 , 73 , 74 , 76 , 78 , 79 , 81 , 83 , 85 , 87 , 89 , 91 , 92 , 95 , 97 , 99&lt;br /&gt;
  dw 101 , 103 , 105 , 108 , 110 , 112 , 115 , 117 , 120 , 123 , 125 , 128 , 131&lt;br /&gt;
  dw 134 , 137 , 140 , 143 , 146 , 149 , 152 , 156 , 159 , 162 , 166 , 170 , 173&lt;br /&gt;
  dw 177 , 181 , 185 , 189 , 193 , 197 , 202 , 206 , 211 , 215 , 220 , 225 , 230&lt;br /&gt;
  dw 235 , 240 , 245 , 251 , 256 , 262 , 267 , 273 , 279 , 285 , 292 , 298 , 304&lt;br /&gt;
  dw 311 , 318 , 325 , 332 , 339 , 347 , 354 , 362 , 370 , 378 , 386 , 395 , 403&lt;br /&gt;
  dw 412 , 421 , 431 , 440 , 450 , 459 , 470 , 480 , 490 , 501 , 512 , 523 , 535&lt;br /&gt;
  dw 546 , 558 , 571 , 583 , 596 , 609 , 622 , 636 , 650 , 664 , 679 , 693 , 709&lt;br /&gt;
  dw 724 , 740 , 756 , 773 , 790 , 807 , 825 , 843 , 861 , 880 , 899 , 919 , 939&lt;br /&gt;
  dw 960 , 981 , 1002 , 1024 , 1046 , 1069 , 1093 , 1117 , 1141 , 1166 , 1192&lt;br /&gt;
  dw 1218 , 1244 , 1272 , 1300 , 1328 , 1357 , 1387 , 1417 , 1448 , 1480 , 1512&lt;br /&gt;
  dw 1545 , 1579 , 1614 , 1649 , 1685 , 1722 , 1760 , 1798 , 1838 , 1878 , 1919&lt;br /&gt;
  dw 1961 , 2004 , 2048 , 2093 , 2139 , 2186 , 2233 , 2282 , 2332 , 2383 , 2435&lt;br /&gt;
  dw 2489 , 2543 , 2599 , 2656 , 2714 , 2774 , 2834 , 2896 , 2960 , 3025 , 3091&lt;br /&gt;
  dw 3158 , 3228 , 3298 , 3371 , 3444 , 3520 , 3597 , 3676 , 3756 , 3838 , 3922&lt;br /&gt;
  dw 4008 , 4096 , 4186 , 4277 , 4371 , 4467 , 4565 , 4664 , 4767 , 4871 , 4978&lt;br /&gt;
  dw 5087 , 5198 , 5312 , 5428 , 5547 , 5668 , 5793 , 5919 , 6049 , 6182 , 6317&lt;br /&gt;
  dw 6455 , 6597 , 6741 , 6889 , 7039 , 7194 , 7351 , 7512 , 7677 , 7845 , 8016&lt;br /&gt;
  dw 8192 , 8371 , 8555 , 8742 , 8933 , 9129 , 9329 , 9533 , 9742 , 9955 , 10173&lt;br /&gt;
  dw 10396 , 10624 , 10856 , 11094 , 11337 , 11585 , 11839 , 12098 , 12363 , 12634&lt;br /&gt;
  dw 12910 , 13193 , 13482 , 13777 , 14079 , 14387 , 14702 , 15024 , 15353 , 15689&lt;br /&gt;
  dw 16033 , 16384 , 16743 , 17109 , 17484 , 17867 , 18258 , 18658 , 19066 , 19484&lt;br /&gt;
  dw 19911 , 20347 , 20792 , 21247 , 21713 , 22188 , 22674 , 23170 , 23678 , 24196&lt;br /&gt;
  dw 24726 , 25268 , 25821 , 26386 , 26964 , 27554 , 28158 , 28774 , 29404 , 30048&lt;br /&gt;
  dw 30706 , 31379 , 32066 , 32768 , 33485 , 34219 , 34968 , 35734 , 36516 , 37316&lt;br /&gt;
  dw 38133 , 38968 , 39821 , 40693 , 41584 , 42495 , 43425 , 44376 , 45348 , 46341&lt;br /&gt;
  dw 47356 , 48393 , 49452 , 50535 , 51642 , 52772 , 53928 , 55109 , 56316 , 57549&lt;br /&gt;
  dw  58809 , 60097 , 61413 , 62757&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fastest, accurate 8bit * 8bit Unsigned  with 16 KB tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' L = Multiplier, C = Multiplicand&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 80 = 20 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 14 bytes of code + 16 KB tables&lt;br /&gt;
&lt;br /&gt;
I'm currently working on a new routine, based on a routine by Kirk Meyer [http://www.ticalc.org/pub/86/asm/source/routines/vfmult.asm] which uses nibble multiplication tables.&lt;br /&gt;
&lt;br /&gt;
I have a working, tested version which uses 16K of tables and can perform multiplication in 20&amp;amp;mu;s.&lt;br /&gt;
&lt;br /&gt;
The code to produce the tables is below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp1&lt;br /&gt;
ld a,l&lt;br /&gt;
rla&lt;br /&gt;
and #1e&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp1&lt;br /&gt;
inc h&lt;br /&gt;
.makelp2&lt;br /&gt;
ld a,l&lt;br /&gt;
rra:rra:rra&lt;br /&gt;
and #1e&lt;br /&gt;
jr z,usez&lt;br /&gt;
add restab2 - restab / 256 - 2&lt;br /&gt;
.usez&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp2&lt;br /&gt;
inc h			; restab&lt;br /&gt;
.makelp3&lt;br /&gt;
ld a,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
add l&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,0&lt;br /&gt;
adc d&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h:dec h:dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256 - 2&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
ld b,h&lt;br /&gt;
ld c,l&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp4&lt;br /&gt;
ld e,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
dec h&lt;br /&gt;
ex de,hl&lt;br /&gt;
add hl,hl:add hl,hl:add hl,hl:add hl,hl&lt;br /&gt;
ex de,hl&lt;br /&gt;
ld a,e&lt;br /&gt;
ld (bc),a&lt;br /&gt;
inc b&lt;br /&gt;
ld a,d&lt;br /&gt;
ld (bc),a&lt;br /&gt;
dec b&lt;br /&gt;
inc l&lt;br /&gt;
inc c&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
.restab2&lt;br /&gt;
ds 512 * 15&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code to perform the multiplication (DE = L * C):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ld h,hltab1 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
inc h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(bc)		; 10&lt;br /&gt;
add (hl)		; 12&lt;br /&gt;
ld e,a			; 13&lt;br /&gt;
inc b			; 14&lt;br /&gt;
inc h			; 15&lt;br /&gt;
ld a,(bc)		; 17&lt;br /&gt;
adc (hl)		; 19&lt;br /&gt;
ld d,a			; 20&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast, accurate 8bit * 8bit Unsigned  with 8 KB tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' L = Multiplier, C = Multiplicand&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 100 = 25 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 19 bytes of code + 8 KB tables&lt;br /&gt;
&lt;br /&gt;
16K is a lot of memory to use for tables, but I'm working on a way to reduce this to 8K while maintaining similar performance (around 26&amp;amp;mu;s). The idea is rather than using tables for the low and high nibbles, use tables for alternate bits. So there would be 16 tables for the values #00, #01, #04, #05, #10, #11, #14, #15, #40, #41, #44, #45, #50, #51, #54, #55. The values can be shifted by 1 (rather than 4) to give values for the alternate bits using a simple ADD HL,HL.&lt;br /&gt;
&lt;br /&gt;
This routine should be easy to adapt to a 16bit * 8bit unsigned multiplication or even a 16bit * 16bit, using simple additions.&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 03:58, 8 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
Ok, here is the new 8K routine, first the routine to build the tables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp5&lt;br /&gt;
ld a,l&lt;br /&gt;
ld bc,0&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
ld a,b&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,c&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp5&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp6&lt;br /&gt;
ld (hl),l&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp6&lt;br /&gt;
inc h:inc h&lt;br /&gt;
ld b,2&lt;br /&gt;
.makelp8&lt;br /&gt;
push bc&lt;br /&gt;
xor a&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
.makelp7&lt;br /&gt;
push hl&lt;br /&gt;
push af&lt;br /&gt;
call mulLbyA&lt;br /&gt;
ex de,hl&lt;br /&gt;
pop af&lt;br /&gt;
pop hl&lt;br /&gt;
ld (hl),e&lt;br /&gt;
inc h&lt;br /&gt;
ld (hl),d&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp7&lt;br /&gt;
inc h:inc h&lt;br /&gt;
pop bc&lt;br /&gt;
inc b&lt;br /&gt;
bit 4,b&lt;br /&gt;
jr z,makelp8&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
.mulLbyA	; MAX times	; MIN times&lt;br /&gt;
ld e,l		; 1		; 1&lt;br /&gt;
ld d,0		; 3		; 3&lt;br /&gt;
add a		; 4		; 4&lt;br /&gt;
ld h,a		; 5		; 5&lt;br /&gt;
jr c,ncad0	; 8		; 8&lt;br /&gt;
ld l,d		&lt;br /&gt;
.ncad0&lt;br /&gt;
add hl,hl	; 11		; 11&lt;br /&gt;
jr nc,ncad1	; 13		; 14&lt;br /&gt;
add hl,de	; 16&lt;br /&gt;
.ncad1&lt;br /&gt;
add hl,hl	; 19		; 17&lt;br /&gt;
jr nc,ncad2	; 21		; 20&lt;br /&gt;
add hl,de	; 24&lt;br /&gt;
.ncad2&lt;br /&gt;
add hl,hl	; 27		; 23&lt;br /&gt;
jr nc,ncad3	; 29		; 26&lt;br /&gt;
add hl,de	; 32&lt;br /&gt;
.ncad3&lt;br /&gt;
add hl,hl	; 35		; 29&lt;br /&gt;
jr nc,ncad4	; 37		; 32&lt;br /&gt;
add hl,de	; 40&lt;br /&gt;
.ncad4&lt;br /&gt;
add hl,hl	; 43		; 35&lt;br /&gt;
jr nc,ncad5	; 45		; 38&lt;br /&gt;
add hl,de	; 48&lt;br /&gt;
.ncad5&lt;br /&gt;
add hl,hl	; 51		; 41&lt;br /&gt;
jr nc,ncad6	; 53		; 44&lt;br /&gt;
add hl,de	; 56&lt;br /&gt;
.ncad6&lt;br /&gt;
add hl,hl	; 59		; 47&lt;br /&gt;
ld a,h		; 60		; 48&lt;br /&gt;
ret nc		; 61		; 50?&lt;br /&gt;
add hl,de	; 64&lt;br /&gt;
ld a,h		; 65&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the routine to do the multiplication:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.umultCL		; Using 8 bit only (25us - DE = L * C)&lt;br /&gt;
ld h,hltab2 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
dec h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(hl)		; 10&lt;br /&gt;
add a			; 11&lt;br /&gt;
inc h			; 12&lt;br /&gt;
ld d,(hl)		; 14&lt;br /&gt;
rl d			; 16&lt;br /&gt;
ld h,b			; 17&lt;br /&gt;
add (hl)		; 19&lt;br /&gt;
ld e,a			; 20&lt;br /&gt;
inc h			; 21&lt;br /&gt;
ld a,(hl)		; 23&lt;br /&gt;
adc d			; 24&lt;br /&gt;
ld d,a			; 25&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Very fast 8bit * 8bit Unsigned with only 1K of tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input''': B = Multiplier, C = Multiplicant&lt;br /&gt;
&lt;br /&gt;
'''Output''': DE = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles''': 104-112 (108 on average) = 26-28 (27) usec&lt;br /&gt;
&lt;br /&gt;
'''Size''': 24 bytes of code and 1024 bytes for the tables&lt;br /&gt;
&lt;br /&gt;
Here's a new routine I've developed which uses the formula ab = ((a + b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - (a - b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) / 4. It's based on a routine for the 6502 by Stephen Judd in a C= Hacking article. Because of differences between the way the 6502 does register indexing it was quite difficult to actually get this working, but it's a great compromise between speed and space since it only uses 1K of tables (as opposed to the 16K or 8K table routines above), and can still manage to do the job in a maximum of 28 microseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Firstly, once again, we need some code to generate the tables. These tables contain values for&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;/4 for 9 bit values of x, with the LSB when bit 8 is zero first followed by the MSB.&lt;br /&gt;
&amp;lt;pre&amp;gt;.gen_sq4&lt;br /&gt;
	xor a&lt;br /&gt;
	ld de,umul_tab + #1ff&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	ld h,d&lt;br /&gt;
	ld l,e&lt;br /&gt;
	inc e&lt;br /&gt;
	ld c,e&lt;br /&gt;
	ld b,2&lt;br /&gt;
&lt;br /&gt;
	.sq4_lp&lt;br /&gt;
	ld a,b&lt;br /&gt;
	cp 2&lt;br /&gt;
	ld a,e&lt;br /&gt;
	rra&lt;br /&gt;
	add (hl)&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	inc h&lt;br /&gt;
	inc d&lt;br /&gt;
	ld a,(hl)&lt;br /&gt;
	adc c&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld h,d&lt;br /&gt;
	inc l&lt;br /&gt;
	inc e&lt;br /&gt;
	jr nz,sq4_lp&lt;br /&gt;
	inc d&lt;br /&gt;
	inc d&lt;br /&gt;
	djnz sq4_lp&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
align #100&lt;br /&gt;
.umul_tab ds #400&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now for the actual multiply routine:&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', L = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ld h,umul_tab_lo / #100	; 2&lt;br /&gt;
	ld b,h			; 3&lt;br /&gt;
	add l			; 4&lt;br /&gt;
	ld c,a			; 5&lt;br /&gt;
	jr nc,@noovf		; 7&lt;br /&gt;
	inc b			; 8&lt;br /&gt;
	inc b			; 9&lt;br /&gt;
.@noovf&lt;br /&gt;
	sub l			; 10&lt;br /&gt;
	sub l			; 11&lt;br /&gt;
	jr nc,@noneg		; 13&lt;br /&gt;
	neg			; 15&lt;br /&gt;
.@noneg&lt;br /&gt;
	ld l,a			; 16&lt;br /&gt;
	ld a,(bc)		; 18&lt;br /&gt;
	sub (hl)		; 20&lt;br /&gt;
	ld e,a			; 21&lt;br /&gt;
	inc b			; 22&lt;br /&gt;
	inc h			; 23&lt;br /&gt;
	ld a,(bc)		; 25&lt;br /&gt;
	sbc (hl)		; 27&lt;br /&gt;
	ld d,a			; 28&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This code could easily be converted to a macro as it's only 24 bytes. I've tried to optimize it further but with no luck!&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 06:25, 4 April 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Very fast 8bit * 8bit Unsigned with only 512 bytes of tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input''': A = Multiplier, B = Multiplicant&lt;br /&gt;
&lt;br /&gt;
'''Output''': A:E = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles''': 136-172 (154 on average) = 26-28 (27) usec&lt;br /&gt;
&lt;br /&gt;
'''Size''': 44 bytes of code and 512 bytes for the tables&lt;br /&gt;
&lt;br /&gt;
Fast 8 bit unsigned multiplication with 16 bit result. It uses formula&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  x*y = ((x+y)/2)^2 - ((x-y)/2)^2, if x+y is even&lt;br /&gt;
      = ((x+y-1)/2)^2 - ((x-y-1)/2)^2 + y, if x+y is odd and x&amp;gt;=y&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;    cp b&lt;br /&gt;
    jr nc,l1&lt;br /&gt;
&lt;br /&gt;
    ld e,a&lt;br /&gt;
    ld a,b&lt;br /&gt;
    ld b,e&lt;br /&gt;
&lt;br /&gt;
l1  ld c,a&lt;br /&gt;
    sub b&lt;br /&gt;
    rra&lt;br /&gt;
    ld d,a&lt;br /&gt;
    ld a,c&lt;br /&gt;
    add a,b&lt;br /&gt;
    rra&lt;br /&gt;
    ld l,a&lt;br /&gt;
    ld h,high(sqrlo)&lt;br /&gt;
    ld a,(hl)&lt;br /&gt;
    ld e,l&lt;br /&gt;
    ld l,d&lt;br /&gt;
    jr nc,l2&lt;br /&gt;
&lt;br /&gt;
    sub (hl)   ;odd&lt;br /&gt;
    ld l,e&lt;br /&gt;
    ld e,a&lt;br /&gt;
    inc h      ;loads high(sqrhi)&lt;br /&gt;
    ld a,(hl)&lt;br /&gt;
    ld l,d&lt;br /&gt;
    sbc a,(hl)&lt;br /&gt;
    ld d,a&lt;br /&gt;
&lt;br /&gt;
    ld a,e&lt;br /&gt;
    add a,b&lt;br /&gt;
    ld e,a&lt;br /&gt;
    ld a,d&lt;br /&gt;
    adc a,0&lt;br /&gt;
    ret&lt;br /&gt;
&lt;br /&gt;
l2  sub (hl)   ;even&lt;br /&gt;
    ld l,e&lt;br /&gt;
    ld e,a&lt;br /&gt;
    inc h&lt;br /&gt;
    ld a,(hl)&lt;br /&gt;
    ld l,d&lt;br /&gt;
    sbc a,(hl)&lt;br /&gt;
    ret&lt;br /&gt;
&lt;br /&gt;
sqrlo ;low(x*x)   should be at the page border&lt;br /&gt;
    db 0,1,4,9,$10,$19,$24,$31,$40,$51,$64,$79,$90,$a9,$c4,$e1&lt;br /&gt;
    db 0,$21,$44,$69,$90,$b9,$e4,$11,$40,$71,$a4,$d9,$10,$49,$84,$c1&lt;br /&gt;
    db 0,$41,$84,$c9,$10,$59,$a4,$f1,$40,$91,$e4,$39,$90,$e9,$44,$a1&lt;br /&gt;
    db 0,$61,$c4,$29,$90,$f9,$64,$d1,$40,$b1,$24,$99,$10,$89,4,$81&lt;br /&gt;
    db 0,$81,4,$89,$10,$99,$24,$b1,$40,$d1,$64,$f9,$90,$29,$c4,$61&lt;br /&gt;
    db 0,$a1,$44,$e9,$90,$39,$e4,$91,$40,$f1,$a4,$59,$10,$c9,$84,$41&lt;br /&gt;
    db 0,$c1,$84,$49,$10,$d9,$a4,$71,$40,$11,$e4,$b9,$90,$69,$44,$21&lt;br /&gt;
    db 0,$e1,$c4,$a9,$90,$79,$64,$51,$40,$31,$24,$19,$10,9,4,$1&lt;br /&gt;
    db 0,1,4,9,$10,$19,$24,$31,$40,$51,$64,$79,$90,$a9,$c4,$e1&lt;br /&gt;
    db 0,$21,$44,$69,$90,$b9,$e4,$11,$40,$71,$a4,$d9,$10,$49,$84,$c1&lt;br /&gt;
    db 0,$41,$84,$c9,$10,$59,$a4,$f1,$40,$91,$e4,$39,$90,$e9,$44,$a1&lt;br /&gt;
    db 0,$61,$c4,$29,$90,$f9,$64,$d1,$40,$b1,$24,$99,$10,$89,4,$81&lt;br /&gt;
    db 0,$81,4,$89,$10,$99,$24,$b1,$40,$d1,$64,$f9,$90,$29,$c4,$61&lt;br /&gt;
    db 0,$a1,$44,$e9,$90,$39,$e4,$91,$40,$f1,$a4,$59,$10,$c9,$84,$41&lt;br /&gt;
    db 0,$c1,$84,$49,$10,$d9,$a4,$71,$40,$11,$e4,$b9,$90,$69,$44,$21&lt;br /&gt;
    db 0,$e1,$c4,$a9,$90,$79,$64,$51,$40,$31,$24,$19,$10,9,4,$1&lt;br /&gt;
sqrhi ;high(x*x)&lt;br /&gt;
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
    db 1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3&lt;br /&gt;
    db 4,4,4,4,5,5,5,5,6,6,6,7,7,7,8,8&lt;br /&gt;
    db 9,9,9,$a,$a,$a,$b,$b,$c,$c,$d,$d,$e,$e,$f,$f&lt;br /&gt;
    db $10,$10,$11,$11,$12,$12,$13,$13,$14,$14,$15,$15,$16,$17,$17,$18&lt;br /&gt;
    db $19,$19,$1a,$1a,$1b,$1c,$1c,$1d,$1e,$1e,$1f,$20,$21,$21,$22,$23&lt;br /&gt;
    db $24,$24,$25,$26,$27,$27,$28,$29,$2a,$2b,$2b,$2c,$2d,$2e,$2f,$30&lt;br /&gt;
    db $31,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f&lt;br /&gt;
    db $40,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f&lt;br /&gt;
    db $51,$52,$53,$54,$55,$56,$57,$59,$5a,$5b,$5c,$5d,$5f,$60,$61,$62&lt;br /&gt;
    db $64,$65,$66,$67,$69,$6a,$6b,$6c,$6e,$6f,$70,$72,$73,$74,$76,$77&lt;br /&gt;
    db $79,$7a,$7b,$7d,$7e,$7f,$81,$82,$84,$85,$87,$88,$8a,$8b,$8d,$8e&lt;br /&gt;
    db $90,$91,$93,$94,$96,$97,$99,$9a,$9c,$9d,$9f,$a0,$a2,$a4,$a5,$a7&lt;br /&gt;
    db $a9,$aa,$ac,$ad,$af,$b1,$b2,$b4,$b6,$b7,$b9,$bb,$bd,$be,$c0,$c2&lt;br /&gt;
    db $c4,$c5,$c7,$c9,$cb,$cc,$ce,$d0,$d2,$d4,$d5,$d7,$d9,$db,$dd,$df&lt;br /&gt;
    db $e1,$e2,$e4,$e6,$e8,$ea,$ec,$ee,$f0,$f2,$f4,$f6,$f8,$fa,$fc,$fe&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[User:Litwr|Litwr]] 10:25, 24 October 2015 (CEST)&lt;br /&gt;
&lt;br /&gt;
== 16bit * 16bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' BC = ''Multiplier'', DE = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A,HL = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;ld ix,0&lt;br /&gt;
 ld hl,0&lt;br /&gt;
.mul24b1:&lt;br /&gt;
 ld a,c&lt;br /&gt;
 or b&lt;br /&gt;
 jr z,mul24b3&lt;br /&gt;
 srl b&lt;br /&gt;
 rr c&lt;br /&gt;
 jr nc,mul24b2&lt;br /&gt;
 add ix,de&lt;br /&gt;
 ld a,h&lt;br /&gt;
 adc l&lt;br /&gt;
 ld h,a&lt;br /&gt;
.mul24b2:&lt;br /&gt;
 sla e&lt;br /&gt;
 rl d&lt;br /&gt;
 rl l&lt;br /&gt;
 jr mul24b1:&lt;br /&gt;
.mul24b3:&lt;br /&gt;
 ld a,h&lt;br /&gt;
 db #dd:ld e,l&lt;br /&gt;
 db #dd:ld d,h&lt;br /&gt;
 ex de,hl&lt;br /&gt;
 ret&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://map.tni.nl/articles/mult_div_shifts.php Multiplications and divisions on the MSX Assembly Page]&lt;br /&gt;
* [http://www.mccw.hetlab.tk/92/Multiplication/en.html &amp;quot;Multiplication on a Z80&amp;quot; ( MSX Computer &amp;amp; Club Webmagazine)]&lt;br /&gt;
* [http://www.andreadrian.de/oldcpu/Z80_number_cruncher.html The Z80 number cruncher (Andre Adrian)] (16/32bit multiplication, addition, right shift)&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94466</id>
		<title>Programming:Integer Multiplication</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94466"/>
				<updated>2015-10-24T07:29:58Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: a new fast multiplication routine added&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Classic 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' H = ''Multiplier'', E = ''Multiplicand'', L = 0, D = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 188-244 (216 on average) = 47-61 (54) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 33 bytes&lt;br /&gt;
&lt;br /&gt;
The additional clocks and bytes maybe required to set up D and L and for RET.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sla h  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+3&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
jr nc,$+3  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Classic 16bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', DE = ''Multiplicand'', HL = 0, C = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A:HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 212-300 (256 on average) = 53-75 (64) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 47 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add a,a  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+4&lt;br /&gt;
ld h,d&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
rla   ; ...&lt;br /&gt;
jr nc,$+4  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
adc a,c  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast 8bit * 8bit Unsigned (using log / antilog tables) ==&lt;br /&gt;
&lt;br /&gt;
The original routine was written by Jeff Frohwein for the Nintendo Gameboy. You can find it on [http://www.devrs.com/gb/files/logmult.txt Devrs.com].&lt;br /&gt;
&lt;br /&gt;
Because of the usage of log / antilog tables this routine is less accurate, but very fast. It takes advantage of the fact that if you take the log of two numbers, add the results and then take the antilog of the total you have done the equivalent of multiplying the two numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 x^a * x^b = x^(a+b)&lt;br /&gt;
&lt;br /&gt;
 a * b = x^(logx(a) + logx(b))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Input:''' B = ''Multiplier'', C = ''Multiplicant''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 124 = 31 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 1024 bytes (768 bytes for the tables)&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' It is VERY approximate routine, e.g., 0*7=7, 1*28=27, 10*81=790, 100*100=9742, ...&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FastMult:&lt;br /&gt;
  ld      l,c&lt;br /&gt;
  ld      h,&amp;amp;82&lt;br /&gt;
  ld      d,(hl)          ; d = 32 * log_2(c)&lt;br /&gt;
  &lt;br /&gt;
  ld      l,b&lt;br /&gt;
  ld      a,(hl)          ; a = 32 * log_2(b)&lt;br /&gt;
  &lt;br /&gt;
  add     a,d&lt;br /&gt;
  ld      l,a&lt;br /&gt;
  ld      a,0&lt;br /&gt;
  adc     a,0&lt;br /&gt;
  ld      h,a             ; hl = d + a&lt;br /&gt;
  &lt;br /&gt;
  add     hl,hl&lt;br /&gt;
  set     2,h             ; hl = hl + $0400&lt;br /&gt;
  set     7,h             ; hl = hl + &amp;amp;8000&lt;br /&gt;
  &lt;br /&gt;
  ld      e,(hl)&lt;br /&gt;
  inc     hl&lt;br /&gt;
  ld      d,(hl)          ; de = 2^((hl)/32)&lt;br /&gt;
  &lt;br /&gt;
  ret&lt;br /&gt;
&lt;br /&gt;
; 32*Log_2(x) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 TO 255&lt;br /&gt;
;     C=4 &lt;br /&gt;
;     B=2&lt;br /&gt;
;     FOR Z=1 TO 10&lt;br /&gt;
;       IF (2^C) &amp;gt; A THEN C=C-B ELSE C=C+B&lt;br /&gt;
;       B=B/2&lt;br /&gt;
;     NEXT Z&lt;br /&gt;
;     PRINT INT(C*32);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8200&lt;br /&gt;
&lt;br /&gt;
logtable:&lt;br /&gt;
  db 0 , 0 , 32 , 50 , 64 , 74 , 82 , 89 , 96 , 101 , 106 , 110 , 114 , 118 , 121&lt;br /&gt;
  db 125 , 128 , 130 , 133 , 135 , 138 , 140 , 142 , 144 , 146 , 148 , 150 , 152&lt;br /&gt;
  db 153 , 155 , 157 , 158 , 160 , 161 , 162 , 164 , 165 , 166 , 167 , 169 , 170&lt;br /&gt;
  db 171 , 172 , 173 , 174 , 175 , 176 , 177 , 178 , 179 , 180 , 181 , 182 , 183&lt;br /&gt;
  db 184 , 185 , 185 , 186 , 187 , 188 , 189 , 189 , 190 , 191 , 192 , 192 , 193&lt;br /&gt;
  db 194 , 194 , 195 , 196 , 196 , 197 , 198 , 198 , 199 , 199 , 200 , 201 , 201&lt;br /&gt;
  db 202 , 202 , 203 , 204 , 204 , 205 , 205 , 206 , 206 , 207 , 207 , 208 , 208&lt;br /&gt;
  db 209 , 209 , 210 , 210 , 211 , 211 , 212 , 212 , 213 , 213 , 213 , 214 , 214&lt;br /&gt;
  db 215 , 215 , 216 , 216 , 217 , 217 , 217 , 218 , 218 , 219 , 219 , 219 , 220&lt;br /&gt;
  db 220 , 221 , 221 , 221 , 222 , 222 , 222 , 223 , 223 , 224 , 224 , 224 , 225&lt;br /&gt;
  db 225 , 225 , 226 , 226 , 226 , 227 , 227 , 227 , 228 , 228 , 228 , 229 , 229&lt;br /&gt;
  db 229 , 230 , 230 , 230 , 231 , 231 , 231 , 231 , 232 , 232 , 232 , 233 , 233&lt;br /&gt;
  db 233 , 234 , 234 , 234 , 234 , 235 , 235 , 235 , 236 , 236 , 236 , 236 , 237&lt;br /&gt;
  db 237 , 237 , 237 , 238 , 238 , 238 , 238 , 239 , 239 , 239 , 239 , 240 , 240&lt;br /&gt;
  db 240 , 241 , 241 , 241 , 241 , 241 , 242 , 242 , 242 , 242 , 243 , 243 , 243&lt;br /&gt;
  db 243 , 244 , 244 , 244 , 244 , 245 , 245 , 245 , 245 , 245 , 246 , 246 , 246&lt;br /&gt;
  db 246 , 247 , 247 , 247 , 247 , 247 , 248 , 248 , 248 , 248 , 249 , 249 , 249&lt;br /&gt;
  db 249 , 249 , 250 , 250 , 250 , 250 , 250 , 251 , 251 , 251 , 251 , 251 , 252&lt;br /&gt;
  db 252 , 252 , 252 , 252 , 253 , 253 , 253 , 253 , 253 , 253 , 254 , 254 , 254&lt;br /&gt;
  db 254 , 254 , 255 , 255 , 255 , 255 , 255&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; AntiLog 2^(x/32) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 to 510&lt;br /&gt;
;   PRINT INT(2^(A/32)+.5);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8400&lt;br /&gt;
&lt;br /&gt;
antilog:&lt;br /&gt;
  dw 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 , 4&lt;br /&gt;
  dw 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 6&lt;br /&gt;
  dw 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 8 , 9&lt;br /&gt;
  dw 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , 12 , 12 , 12&lt;br /&gt;
  dw 13 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17&lt;br /&gt;
  dw 18 , 18 , 19 , 19 , 19 , 20 , 20 , 21 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25&lt;br /&gt;
  dw 25 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , 30 , 31 , 31 , 32 , 33 , 33 , 34 , 35&lt;br /&gt;
  dw 36 , 36 , 37 , 38 , 39 , 40 , 41 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49&lt;br /&gt;
  dw 50 , 52 , 53 , 54 , 55 , 56 , 57 , 59 , 60 , 61 , 63 , 64 , 65 , 67 , 68 , 70&lt;br /&gt;
  dw 71 , 73 , 74 , 76 , 78 , 79 , 81 , 83 , 85 , 87 , 89 , 91 , 92 , 95 , 97 , 99&lt;br /&gt;
  dw 101 , 103 , 105 , 108 , 110 , 112 , 115 , 117 , 120 , 123 , 125 , 128 , 131&lt;br /&gt;
  dw 134 , 137 , 140 , 143 , 146 , 149 , 152 , 156 , 159 , 162 , 166 , 170 , 173&lt;br /&gt;
  dw 177 , 181 , 185 , 189 , 193 , 197 , 202 , 206 , 211 , 215 , 220 , 225 , 230&lt;br /&gt;
  dw 235 , 240 , 245 , 251 , 256 , 262 , 267 , 273 , 279 , 285 , 292 , 298 , 304&lt;br /&gt;
  dw 311 , 318 , 325 , 332 , 339 , 347 , 354 , 362 , 370 , 378 , 386 , 395 , 403&lt;br /&gt;
  dw 412 , 421 , 431 , 440 , 450 , 459 , 470 , 480 , 490 , 501 , 512 , 523 , 535&lt;br /&gt;
  dw 546 , 558 , 571 , 583 , 596 , 609 , 622 , 636 , 650 , 664 , 679 , 693 , 709&lt;br /&gt;
  dw 724 , 740 , 756 , 773 , 790 , 807 , 825 , 843 , 861 , 880 , 899 , 919 , 939&lt;br /&gt;
  dw 960 , 981 , 1002 , 1024 , 1046 , 1069 , 1093 , 1117 , 1141 , 1166 , 1192&lt;br /&gt;
  dw 1218 , 1244 , 1272 , 1300 , 1328 , 1357 , 1387 , 1417 , 1448 , 1480 , 1512&lt;br /&gt;
  dw 1545 , 1579 , 1614 , 1649 , 1685 , 1722 , 1760 , 1798 , 1838 , 1878 , 1919&lt;br /&gt;
  dw 1961 , 2004 , 2048 , 2093 , 2139 , 2186 , 2233 , 2282 , 2332 , 2383 , 2435&lt;br /&gt;
  dw 2489 , 2543 , 2599 , 2656 , 2714 , 2774 , 2834 , 2896 , 2960 , 3025 , 3091&lt;br /&gt;
  dw 3158 , 3228 , 3298 , 3371 , 3444 , 3520 , 3597 , 3676 , 3756 , 3838 , 3922&lt;br /&gt;
  dw 4008 , 4096 , 4186 , 4277 , 4371 , 4467 , 4565 , 4664 , 4767 , 4871 , 4978&lt;br /&gt;
  dw 5087 , 5198 , 5312 , 5428 , 5547 , 5668 , 5793 , 5919 , 6049 , 6182 , 6317&lt;br /&gt;
  dw 6455 , 6597 , 6741 , 6889 , 7039 , 7194 , 7351 , 7512 , 7677 , 7845 , 8016&lt;br /&gt;
  dw 8192 , 8371 , 8555 , 8742 , 8933 , 9129 , 9329 , 9533 , 9742 , 9955 , 10173&lt;br /&gt;
  dw 10396 , 10624 , 10856 , 11094 , 11337 , 11585 , 11839 , 12098 , 12363 , 12634&lt;br /&gt;
  dw 12910 , 13193 , 13482 , 13777 , 14079 , 14387 , 14702 , 15024 , 15353 , 15689&lt;br /&gt;
  dw 16033 , 16384 , 16743 , 17109 , 17484 , 17867 , 18258 , 18658 , 19066 , 19484&lt;br /&gt;
  dw 19911 , 20347 , 20792 , 21247 , 21713 , 22188 , 22674 , 23170 , 23678 , 24196&lt;br /&gt;
  dw 24726 , 25268 , 25821 , 26386 , 26964 , 27554 , 28158 , 28774 , 29404 , 30048&lt;br /&gt;
  dw 30706 , 31379 , 32066 , 32768 , 33485 , 34219 , 34968 , 35734 , 36516 , 37316&lt;br /&gt;
  dw 38133 , 38968 , 39821 , 40693 , 41584 , 42495 , 43425 , 44376 , 45348 , 46341&lt;br /&gt;
  dw 47356 , 48393 , 49452 , 50535 , 51642 , 52772 , 53928 , 55109 , 56316 , 57549&lt;br /&gt;
  dw  58809 , 60097 , 61413 , 62757&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fastest, accurate 8bit * 8bit Unsigned  with 16 KB tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' L = Multiplier, C = Multiplicand&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 80 = 20 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 14 bytes of code + 16 KB tables&lt;br /&gt;
&lt;br /&gt;
I'm currently working on a new routine, based on a routine by Kirk Meyer [http://www.ticalc.org/pub/86/asm/source/routines/vfmult.asm] which uses nibble multiplication tables.&lt;br /&gt;
&lt;br /&gt;
I have a working, tested version which uses 16K of tables and can perform multiplication in 20&amp;amp;mu;s.&lt;br /&gt;
&lt;br /&gt;
The code to produce the tables is below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp1&lt;br /&gt;
ld a,l&lt;br /&gt;
rla&lt;br /&gt;
and #1e&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp1&lt;br /&gt;
inc h&lt;br /&gt;
.makelp2&lt;br /&gt;
ld a,l&lt;br /&gt;
rra:rra:rra&lt;br /&gt;
and #1e&lt;br /&gt;
jr z,usez&lt;br /&gt;
add restab2 - restab / 256 - 2&lt;br /&gt;
.usez&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp2&lt;br /&gt;
inc h			; restab&lt;br /&gt;
.makelp3&lt;br /&gt;
ld a,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
add l&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,0&lt;br /&gt;
adc d&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h:dec h:dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256 - 2&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
ld b,h&lt;br /&gt;
ld c,l&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp4&lt;br /&gt;
ld e,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
dec h&lt;br /&gt;
ex de,hl&lt;br /&gt;
add hl,hl:add hl,hl:add hl,hl:add hl,hl&lt;br /&gt;
ex de,hl&lt;br /&gt;
ld a,e&lt;br /&gt;
ld (bc),a&lt;br /&gt;
inc b&lt;br /&gt;
ld a,d&lt;br /&gt;
ld (bc),a&lt;br /&gt;
dec b&lt;br /&gt;
inc l&lt;br /&gt;
inc c&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
.restab2&lt;br /&gt;
ds 512 * 15&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code to perform the multiplication (DE = L * C):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ld h,hltab1 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
inc h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(bc)		; 10&lt;br /&gt;
add (hl)		; 12&lt;br /&gt;
ld e,a			; 13&lt;br /&gt;
inc b			; 14&lt;br /&gt;
inc h			; 15&lt;br /&gt;
ld a,(bc)		; 17&lt;br /&gt;
adc (hl)		; 19&lt;br /&gt;
ld d,a			; 20&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast, accurate 8bit * 8bit Unsigned  with 8 KB tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' L = Multiplier, C = Multiplicand&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 100 = 25 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 19 bytes of code + 8 KB tables&lt;br /&gt;
&lt;br /&gt;
16K is a lot of memory to use for tables, but I'm working on a way to reduce this to 8K while maintaining similar performance (around 26&amp;amp;mu;s). The idea is rather than using tables for the low and high nibbles, use tables for alternate bits. So there would be 16 tables for the values #00, #01, #04, #05, #10, #11, #14, #15, #40, #41, #44, #45, #50, #51, #54, #55. The values can be shifted by 1 (rather than 4) to give values for the alternate bits using a simple ADD HL,HL.&lt;br /&gt;
&lt;br /&gt;
This routine should be easy to adapt to a 16bit * 8bit unsigned multiplication or even a 16bit * 16bit, using simple additions.&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 03:58, 8 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
Ok, here is the new 8K routine, first the routine to build the tables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp5&lt;br /&gt;
ld a,l&lt;br /&gt;
ld bc,0&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
ld a,b&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,c&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp5&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp6&lt;br /&gt;
ld (hl),l&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp6&lt;br /&gt;
inc h:inc h&lt;br /&gt;
ld b,2&lt;br /&gt;
.makelp8&lt;br /&gt;
push bc&lt;br /&gt;
xor a&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
.makelp7&lt;br /&gt;
push hl&lt;br /&gt;
push af&lt;br /&gt;
call mulLbyA&lt;br /&gt;
ex de,hl&lt;br /&gt;
pop af&lt;br /&gt;
pop hl&lt;br /&gt;
ld (hl),e&lt;br /&gt;
inc h&lt;br /&gt;
ld (hl),d&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp7&lt;br /&gt;
inc h:inc h&lt;br /&gt;
pop bc&lt;br /&gt;
inc b&lt;br /&gt;
bit 4,b&lt;br /&gt;
jr z,makelp8&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
.mulLbyA	; MAX times	; MIN times&lt;br /&gt;
ld e,l		; 1		; 1&lt;br /&gt;
ld d,0		; 3		; 3&lt;br /&gt;
add a		; 4		; 4&lt;br /&gt;
ld h,a		; 5		; 5&lt;br /&gt;
jr c,ncad0	; 8		; 8&lt;br /&gt;
ld l,d		&lt;br /&gt;
.ncad0&lt;br /&gt;
add hl,hl	; 11		; 11&lt;br /&gt;
jr nc,ncad1	; 13		; 14&lt;br /&gt;
add hl,de	; 16&lt;br /&gt;
.ncad1&lt;br /&gt;
add hl,hl	; 19		; 17&lt;br /&gt;
jr nc,ncad2	; 21		; 20&lt;br /&gt;
add hl,de	; 24&lt;br /&gt;
.ncad2&lt;br /&gt;
add hl,hl	; 27		; 23&lt;br /&gt;
jr nc,ncad3	; 29		; 26&lt;br /&gt;
add hl,de	; 32&lt;br /&gt;
.ncad3&lt;br /&gt;
add hl,hl	; 35		; 29&lt;br /&gt;
jr nc,ncad4	; 37		; 32&lt;br /&gt;
add hl,de	; 40&lt;br /&gt;
.ncad4&lt;br /&gt;
add hl,hl	; 43		; 35&lt;br /&gt;
jr nc,ncad5	; 45		; 38&lt;br /&gt;
add hl,de	; 48&lt;br /&gt;
.ncad5&lt;br /&gt;
add hl,hl	; 51		; 41&lt;br /&gt;
jr nc,ncad6	; 53		; 44&lt;br /&gt;
add hl,de	; 56&lt;br /&gt;
.ncad6&lt;br /&gt;
add hl,hl	; 59		; 47&lt;br /&gt;
ld a,h		; 60		; 48&lt;br /&gt;
ret nc		; 61		; 50?&lt;br /&gt;
add hl,de	; 64&lt;br /&gt;
ld a,h		; 65&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the routine to do the multiplication:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.umultCL		; Using 8 bit only (25us - DE = L * C)&lt;br /&gt;
ld h,hltab2 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
dec h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(hl)		; 10&lt;br /&gt;
add a			; 11&lt;br /&gt;
inc h			; 12&lt;br /&gt;
ld d,(hl)		; 14&lt;br /&gt;
rl d			; 16&lt;br /&gt;
ld h,b			; 17&lt;br /&gt;
add (hl)		; 19&lt;br /&gt;
ld e,a			; 20&lt;br /&gt;
inc h			; 21&lt;br /&gt;
ld a,(hl)		; 23&lt;br /&gt;
adc d			; 24&lt;br /&gt;
ld d,a			; 25&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Very fast 8bit * 8bit Unsigned with only 1K of tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input''': B = Multiplier, C = Multiplicant&lt;br /&gt;
&lt;br /&gt;
'''Output''': DE = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles''': 104-112 (108 on average) = 26-28 (27) usec&lt;br /&gt;
&lt;br /&gt;
'''Size''': 24 bytes of code and 1024 bytes for the tables&lt;br /&gt;
&lt;br /&gt;
Here's a new routine I've developed which uses the formula ab = ((a + b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - (a - b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) / 4. It's based on a routine for the 6502 by Stephen Judd in a C= Hacking article. Because of differences between the way the 6502 does register indexing it was quite difficult to actually get this working, but it's a great compromise between speed and space since it only uses 1K of tables (as opposed to the 16K or 8K table routines above), and can still manage to do the job in a maximum of 28 microseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Firstly, once again, we need some code to generate the tables. These tables contain values for&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;/4 for 9 bit values of x, with the LSB when bit 8 is zero first followed by the MSB.&lt;br /&gt;
&amp;lt;pre&amp;gt;.gen_sq4&lt;br /&gt;
	xor a&lt;br /&gt;
	ld de,umul_tab + #1ff&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	ld h,d&lt;br /&gt;
	ld l,e&lt;br /&gt;
	inc e&lt;br /&gt;
	ld c,e&lt;br /&gt;
	ld b,2&lt;br /&gt;
&lt;br /&gt;
	.sq4_lp&lt;br /&gt;
	ld a,b&lt;br /&gt;
	cp 2&lt;br /&gt;
	ld a,e&lt;br /&gt;
	rra&lt;br /&gt;
	add (hl)&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	inc h&lt;br /&gt;
	inc d&lt;br /&gt;
	ld a,(hl)&lt;br /&gt;
	adc c&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld h,d&lt;br /&gt;
	inc l&lt;br /&gt;
	inc e&lt;br /&gt;
	jr nz,sq4_lp&lt;br /&gt;
	inc d&lt;br /&gt;
	inc d&lt;br /&gt;
	djnz sq4_lp&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
align #100&lt;br /&gt;
.umul_tab ds #400&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now for the actual multiply routine:&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', L = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ld h,umul_tab_lo / #100	; 2&lt;br /&gt;
	ld b,h			; 3&lt;br /&gt;
	add l			; 4&lt;br /&gt;
	ld c,a			; 5&lt;br /&gt;
	jr nc,@noovf		; 7&lt;br /&gt;
	inc b			; 8&lt;br /&gt;
	inc b			; 9&lt;br /&gt;
.@noovf&lt;br /&gt;
	sub l			; 10&lt;br /&gt;
	sub l			; 11&lt;br /&gt;
	jr nc,@noneg		; 13&lt;br /&gt;
	neg			; 15&lt;br /&gt;
.@noneg&lt;br /&gt;
	ld l,a			; 16&lt;br /&gt;
	ld a,(bc)		; 18&lt;br /&gt;
	sub (hl)		; 20&lt;br /&gt;
	ld e,a			; 21&lt;br /&gt;
	inc b			; 22&lt;br /&gt;
	inc h			; 23&lt;br /&gt;
	ld a,(bc)		; 25&lt;br /&gt;
	sbc (hl)		; 27&lt;br /&gt;
	ld d,a			; 28&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This code could easily be converted to a macro as it's only 24 bytes. I've tried to optimize it further but with no luck!&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 06:25, 4 April 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Output''': A:E = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles''': 136-172 (154 on average) = 26-28 (27) usec&lt;br /&gt;
&lt;br /&gt;
'''Size''': 44 bytes of code and 512 bytes for the tables&lt;br /&gt;
&lt;br /&gt;
Fast 8 bit unsigned multiplication with 16 bit result. It uses formula&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  x*y = ((x+y)/2)^2 - ((x-y)/2)^2, if x+y is even&lt;br /&gt;
      = ((x+y-1)/2)^2 - ((x-y-1)/2)^2 + y, if x+y is odd and x&amp;gt;=y&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;    cp b&lt;br /&gt;
    jr nc,l1&lt;br /&gt;
&lt;br /&gt;
    ld e,a&lt;br /&gt;
    ld a,b&lt;br /&gt;
    ld b,e&lt;br /&gt;
&lt;br /&gt;
l1  ld c,a&lt;br /&gt;
    sub b&lt;br /&gt;
    rra&lt;br /&gt;
    ld d,a&lt;br /&gt;
    ld a,c&lt;br /&gt;
    add a,b&lt;br /&gt;
    rra&lt;br /&gt;
    ld l,a&lt;br /&gt;
    ld h,high(sqrlo)&lt;br /&gt;
    ld a,(hl)&lt;br /&gt;
    ld e,l&lt;br /&gt;
    ld l,d&lt;br /&gt;
    jr nc,l2&lt;br /&gt;
&lt;br /&gt;
    sub (hl)   ;odd&lt;br /&gt;
    ld l,e&lt;br /&gt;
    ld e,a&lt;br /&gt;
    inc h      ;loads high(sqrhi)&lt;br /&gt;
    ld a,(hl)&lt;br /&gt;
    ld l,d&lt;br /&gt;
    sbc a,(hl)&lt;br /&gt;
    ld d,a&lt;br /&gt;
&lt;br /&gt;
    ld a,e&lt;br /&gt;
    add a,b&lt;br /&gt;
    ld e,a&lt;br /&gt;
    ld a,d&lt;br /&gt;
    adc a,0&lt;br /&gt;
    ret&lt;br /&gt;
&lt;br /&gt;
l2  sub (hl)   ;even&lt;br /&gt;
    ld l,e&lt;br /&gt;
    ld e,a&lt;br /&gt;
    inc h&lt;br /&gt;
    ld a,(hl)&lt;br /&gt;
    ld l,d&lt;br /&gt;
    sbc a,(hl)&lt;br /&gt;
    ret&lt;br /&gt;
&lt;br /&gt;
sqrlo ;low(x*x)   should be at the page border&lt;br /&gt;
    db 0,1,4,9,$10,$19,$24,$31,$40,$51,$64,$79,$90,$a9,$c4,$e1&lt;br /&gt;
    db 0,$21,$44,$69,$90,$b9,$e4,$11,$40,$71,$a4,$d9,$10,$49,$84,$c1&lt;br /&gt;
    db 0,$41,$84,$c9,$10,$59,$a4,$f1,$40,$91,$e4,$39,$90,$e9,$44,$a1&lt;br /&gt;
    db 0,$61,$c4,$29,$90,$f9,$64,$d1,$40,$b1,$24,$99,$10,$89,4,$81&lt;br /&gt;
    db 0,$81,4,$89,$10,$99,$24,$b1,$40,$d1,$64,$f9,$90,$29,$c4,$61&lt;br /&gt;
    db 0,$a1,$44,$e9,$90,$39,$e4,$91,$40,$f1,$a4,$59,$10,$c9,$84,$41&lt;br /&gt;
    db 0,$c1,$84,$49,$10,$d9,$a4,$71,$40,$11,$e4,$b9,$90,$69,$44,$21&lt;br /&gt;
    db 0,$e1,$c4,$a9,$90,$79,$64,$51,$40,$31,$24,$19,$10,9,4,$1&lt;br /&gt;
    db 0,1,4,9,$10,$19,$24,$31,$40,$51,$64,$79,$90,$a9,$c4,$e1&lt;br /&gt;
    db 0,$21,$44,$69,$90,$b9,$e4,$11,$40,$71,$a4,$d9,$10,$49,$84,$c1&lt;br /&gt;
    db 0,$41,$84,$c9,$10,$59,$a4,$f1,$40,$91,$e4,$39,$90,$e9,$44,$a1&lt;br /&gt;
    db 0,$61,$c4,$29,$90,$f9,$64,$d1,$40,$b1,$24,$99,$10,$89,4,$81&lt;br /&gt;
    db 0,$81,4,$89,$10,$99,$24,$b1,$40,$d1,$64,$f9,$90,$29,$c4,$61&lt;br /&gt;
    db 0,$a1,$44,$e9,$90,$39,$e4,$91,$40,$f1,$a4,$59,$10,$c9,$84,$41&lt;br /&gt;
    db 0,$c1,$84,$49,$10,$d9,$a4,$71,$40,$11,$e4,$b9,$90,$69,$44,$21&lt;br /&gt;
    db 0,$e1,$c4,$a9,$90,$79,$64,$51,$40,$31,$24,$19,$10,9,4,$1&lt;br /&gt;
sqrhi ;high(x*x)&lt;br /&gt;
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0&lt;br /&gt;
    db 1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3&lt;br /&gt;
    db 4,4,4,4,5,5,5,5,6,6,6,7,7,7,8,8&lt;br /&gt;
    db 9,9,9,$a,$a,$a,$b,$b,$c,$c,$d,$d,$e,$e,$f,$f&lt;br /&gt;
    db $10,$10,$11,$11,$12,$12,$13,$13,$14,$14,$15,$15,$16,$17,$17,$18&lt;br /&gt;
    db $19,$19,$1a,$1a,$1b,$1c,$1c,$1d,$1e,$1e,$1f,$20,$21,$21,$22,$23&lt;br /&gt;
    db $24,$24,$25,$26,$27,$27,$28,$29,$2a,$2b,$2b,$2c,$2d,$2e,$2f,$30&lt;br /&gt;
    db $31,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f&lt;br /&gt;
    db $40,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f&lt;br /&gt;
    db $51,$52,$53,$54,$55,$56,$57,$59,$5a,$5b,$5c,$5d,$5f,$60,$61,$62&lt;br /&gt;
    db $64,$65,$66,$67,$69,$6a,$6b,$6c,$6e,$6f,$70,$72,$73,$74,$76,$77&lt;br /&gt;
    db $79,$7a,$7b,$7d,$7e,$7f,$81,$82,$84,$85,$87,$88,$8a,$8b,$8d,$8e&lt;br /&gt;
    db $90,$91,$93,$94,$96,$97,$99,$9a,$9c,$9d,$9f,$a0,$a2,$a4,$a5,$a7&lt;br /&gt;
    db $a9,$aa,$ac,$ad,$af,$b1,$b2,$b4,$b6,$b7,$b9,$bb,$bd,$be,$c0,$c2&lt;br /&gt;
    db $c4,$c5,$c7,$c9,$cb,$cc,$ce,$d0,$d2,$d4,$d5,$d7,$d9,$db,$dd,$df&lt;br /&gt;
    db $e1,$e2,$e4,$e6,$e8,$ea,$ec,$ee,$f0,$f2,$f4,$f6,$f8,$fa,$fc,$fe&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[User:Litwr|Litwr]] 10:25, 24 October 2015 (CEST)&lt;br /&gt;
&lt;br /&gt;
== 16bit * 16bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' BC = ''Multiplier'', DE = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A,HL = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;ld ix,0&lt;br /&gt;
 ld hl,0&lt;br /&gt;
.mul24b1:&lt;br /&gt;
 ld a,c&lt;br /&gt;
 or b&lt;br /&gt;
 jr z,mul24b3&lt;br /&gt;
 srl b&lt;br /&gt;
 rr c&lt;br /&gt;
 jr nc,mul24b2&lt;br /&gt;
 add ix,de&lt;br /&gt;
 ld a,h&lt;br /&gt;
 adc l&lt;br /&gt;
 ld h,a&lt;br /&gt;
.mul24b2:&lt;br /&gt;
 sla e&lt;br /&gt;
 rl d&lt;br /&gt;
 rl l&lt;br /&gt;
 jr mul24b1:&lt;br /&gt;
.mul24b3:&lt;br /&gt;
 ld a,h&lt;br /&gt;
 db #dd:ld e,l&lt;br /&gt;
 db #dd:ld d,h&lt;br /&gt;
 ex de,hl&lt;br /&gt;
 ret&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://map.tni.nl/articles/mult_div_shifts.php Multiplications and divisions on the MSX Assembly Page]&lt;br /&gt;
* [http://www.mccw.hetlab.tk/92/Multiplication/en.html &amp;quot;Multiplication on a Z80&amp;quot; ( MSX Computer &amp;amp; Club Webmagazine)]&lt;br /&gt;
* [http://www.andreadrian.de/oldcpu/Z80_number_cruncher.html The Z80 number cruncher (Andre Adrian)] (16/32bit multiplication, addition, right shift)&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94465</id>
		<title>Programming:Integer Multiplication</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94465"/>
				<updated>2015-10-24T07:20:04Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: /* Very fast 8bit * 8bit Unsigned with only 1K of tables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Classic 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' H = ''Multiplier'', E = ''Multiplicand'', L = 0, D = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 188-244 (216 on average) = 47-61 (54) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 33 bytes&lt;br /&gt;
&lt;br /&gt;
The additional clocks and bytes maybe required to set up D and L and for RET.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sla h  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+3&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
jr nc,$+3  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Classic 16bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', DE = ''Multiplicand'', HL = 0, C = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A:HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 212-300 (256 on average) = 53-75 (64) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 47 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add a,a  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+4&lt;br /&gt;
ld h,d&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
rla   ; ...&lt;br /&gt;
jr nc,$+4  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
adc a,c  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast 8bit * 8bit Unsigned (using log / antilog tables) ==&lt;br /&gt;
&lt;br /&gt;
The original routine was written by Jeff Frohwein for the Nintendo Gameboy. You can find it on [http://www.devrs.com/gb/files/logmult.txt Devrs.com].&lt;br /&gt;
&lt;br /&gt;
Because of the usage of log / antilog tables this routine is less accurate, but very fast. It takes advantage of the fact that if you take the log of two numbers, add the results and then take the antilog of the total you have done the equivalent of multiplying the two numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 x^a * x^b = x^(a+b)&lt;br /&gt;
&lt;br /&gt;
 a * b = x^(logx(a) + logx(b))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Input:''' B = ''Multiplier'', C = ''Multiplicant''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 124 = 31 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 1024 bytes (768 bytes for the tables)&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' It is VERY approximate routine, e.g., 0*7=7, 1*28=27, 10*81=790, 100*100=9742, ...&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FastMult:&lt;br /&gt;
  ld      l,c&lt;br /&gt;
  ld      h,&amp;amp;82&lt;br /&gt;
  ld      d,(hl)          ; d = 32 * log_2(c)&lt;br /&gt;
  &lt;br /&gt;
  ld      l,b&lt;br /&gt;
  ld      a,(hl)          ; a = 32 * log_2(b)&lt;br /&gt;
  &lt;br /&gt;
  add     a,d&lt;br /&gt;
  ld      l,a&lt;br /&gt;
  ld      a,0&lt;br /&gt;
  adc     a,0&lt;br /&gt;
  ld      h,a             ; hl = d + a&lt;br /&gt;
  &lt;br /&gt;
  add     hl,hl&lt;br /&gt;
  set     2,h             ; hl = hl + $0400&lt;br /&gt;
  set     7,h             ; hl = hl + &amp;amp;8000&lt;br /&gt;
  &lt;br /&gt;
  ld      e,(hl)&lt;br /&gt;
  inc     hl&lt;br /&gt;
  ld      d,(hl)          ; de = 2^((hl)/32)&lt;br /&gt;
  &lt;br /&gt;
  ret&lt;br /&gt;
&lt;br /&gt;
; 32*Log_2(x) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 TO 255&lt;br /&gt;
;     C=4 &lt;br /&gt;
;     B=2&lt;br /&gt;
;     FOR Z=1 TO 10&lt;br /&gt;
;       IF (2^C) &amp;gt; A THEN C=C-B ELSE C=C+B&lt;br /&gt;
;       B=B/2&lt;br /&gt;
;     NEXT Z&lt;br /&gt;
;     PRINT INT(C*32);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8200&lt;br /&gt;
&lt;br /&gt;
logtable:&lt;br /&gt;
  db 0 , 0 , 32 , 50 , 64 , 74 , 82 , 89 , 96 , 101 , 106 , 110 , 114 , 118 , 121&lt;br /&gt;
  db 125 , 128 , 130 , 133 , 135 , 138 , 140 , 142 , 144 , 146 , 148 , 150 , 152&lt;br /&gt;
  db 153 , 155 , 157 , 158 , 160 , 161 , 162 , 164 , 165 , 166 , 167 , 169 , 170&lt;br /&gt;
  db 171 , 172 , 173 , 174 , 175 , 176 , 177 , 178 , 179 , 180 , 181 , 182 , 183&lt;br /&gt;
  db 184 , 185 , 185 , 186 , 187 , 188 , 189 , 189 , 190 , 191 , 192 , 192 , 193&lt;br /&gt;
  db 194 , 194 , 195 , 196 , 196 , 197 , 198 , 198 , 199 , 199 , 200 , 201 , 201&lt;br /&gt;
  db 202 , 202 , 203 , 204 , 204 , 205 , 205 , 206 , 206 , 207 , 207 , 208 , 208&lt;br /&gt;
  db 209 , 209 , 210 , 210 , 211 , 211 , 212 , 212 , 213 , 213 , 213 , 214 , 214&lt;br /&gt;
  db 215 , 215 , 216 , 216 , 217 , 217 , 217 , 218 , 218 , 219 , 219 , 219 , 220&lt;br /&gt;
  db 220 , 221 , 221 , 221 , 222 , 222 , 222 , 223 , 223 , 224 , 224 , 224 , 225&lt;br /&gt;
  db 225 , 225 , 226 , 226 , 226 , 227 , 227 , 227 , 228 , 228 , 228 , 229 , 229&lt;br /&gt;
  db 229 , 230 , 230 , 230 , 231 , 231 , 231 , 231 , 232 , 232 , 232 , 233 , 233&lt;br /&gt;
  db 233 , 234 , 234 , 234 , 234 , 235 , 235 , 235 , 236 , 236 , 236 , 236 , 237&lt;br /&gt;
  db 237 , 237 , 237 , 238 , 238 , 238 , 238 , 239 , 239 , 239 , 239 , 240 , 240&lt;br /&gt;
  db 240 , 241 , 241 , 241 , 241 , 241 , 242 , 242 , 242 , 242 , 243 , 243 , 243&lt;br /&gt;
  db 243 , 244 , 244 , 244 , 244 , 245 , 245 , 245 , 245 , 245 , 246 , 246 , 246&lt;br /&gt;
  db 246 , 247 , 247 , 247 , 247 , 247 , 248 , 248 , 248 , 248 , 249 , 249 , 249&lt;br /&gt;
  db 249 , 249 , 250 , 250 , 250 , 250 , 250 , 251 , 251 , 251 , 251 , 251 , 252&lt;br /&gt;
  db 252 , 252 , 252 , 252 , 253 , 253 , 253 , 253 , 253 , 253 , 254 , 254 , 254&lt;br /&gt;
  db 254 , 254 , 255 , 255 , 255 , 255 , 255&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; AntiLog 2^(x/32) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 to 510&lt;br /&gt;
;   PRINT INT(2^(A/32)+.5);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8400&lt;br /&gt;
&lt;br /&gt;
antilog:&lt;br /&gt;
  dw 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 , 4&lt;br /&gt;
  dw 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 6&lt;br /&gt;
  dw 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 8 , 9&lt;br /&gt;
  dw 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , 12 , 12 , 12&lt;br /&gt;
  dw 13 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17&lt;br /&gt;
  dw 18 , 18 , 19 , 19 , 19 , 20 , 20 , 21 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25&lt;br /&gt;
  dw 25 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , 30 , 31 , 31 , 32 , 33 , 33 , 34 , 35&lt;br /&gt;
  dw 36 , 36 , 37 , 38 , 39 , 40 , 41 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49&lt;br /&gt;
  dw 50 , 52 , 53 , 54 , 55 , 56 , 57 , 59 , 60 , 61 , 63 , 64 , 65 , 67 , 68 , 70&lt;br /&gt;
  dw 71 , 73 , 74 , 76 , 78 , 79 , 81 , 83 , 85 , 87 , 89 , 91 , 92 , 95 , 97 , 99&lt;br /&gt;
  dw 101 , 103 , 105 , 108 , 110 , 112 , 115 , 117 , 120 , 123 , 125 , 128 , 131&lt;br /&gt;
  dw 134 , 137 , 140 , 143 , 146 , 149 , 152 , 156 , 159 , 162 , 166 , 170 , 173&lt;br /&gt;
  dw 177 , 181 , 185 , 189 , 193 , 197 , 202 , 206 , 211 , 215 , 220 , 225 , 230&lt;br /&gt;
  dw 235 , 240 , 245 , 251 , 256 , 262 , 267 , 273 , 279 , 285 , 292 , 298 , 304&lt;br /&gt;
  dw 311 , 318 , 325 , 332 , 339 , 347 , 354 , 362 , 370 , 378 , 386 , 395 , 403&lt;br /&gt;
  dw 412 , 421 , 431 , 440 , 450 , 459 , 470 , 480 , 490 , 501 , 512 , 523 , 535&lt;br /&gt;
  dw 546 , 558 , 571 , 583 , 596 , 609 , 622 , 636 , 650 , 664 , 679 , 693 , 709&lt;br /&gt;
  dw 724 , 740 , 756 , 773 , 790 , 807 , 825 , 843 , 861 , 880 , 899 , 919 , 939&lt;br /&gt;
  dw 960 , 981 , 1002 , 1024 , 1046 , 1069 , 1093 , 1117 , 1141 , 1166 , 1192&lt;br /&gt;
  dw 1218 , 1244 , 1272 , 1300 , 1328 , 1357 , 1387 , 1417 , 1448 , 1480 , 1512&lt;br /&gt;
  dw 1545 , 1579 , 1614 , 1649 , 1685 , 1722 , 1760 , 1798 , 1838 , 1878 , 1919&lt;br /&gt;
  dw 1961 , 2004 , 2048 , 2093 , 2139 , 2186 , 2233 , 2282 , 2332 , 2383 , 2435&lt;br /&gt;
  dw 2489 , 2543 , 2599 , 2656 , 2714 , 2774 , 2834 , 2896 , 2960 , 3025 , 3091&lt;br /&gt;
  dw 3158 , 3228 , 3298 , 3371 , 3444 , 3520 , 3597 , 3676 , 3756 , 3838 , 3922&lt;br /&gt;
  dw 4008 , 4096 , 4186 , 4277 , 4371 , 4467 , 4565 , 4664 , 4767 , 4871 , 4978&lt;br /&gt;
  dw 5087 , 5198 , 5312 , 5428 , 5547 , 5668 , 5793 , 5919 , 6049 , 6182 , 6317&lt;br /&gt;
  dw 6455 , 6597 , 6741 , 6889 , 7039 , 7194 , 7351 , 7512 , 7677 , 7845 , 8016&lt;br /&gt;
  dw 8192 , 8371 , 8555 , 8742 , 8933 , 9129 , 9329 , 9533 , 9742 , 9955 , 10173&lt;br /&gt;
  dw 10396 , 10624 , 10856 , 11094 , 11337 , 11585 , 11839 , 12098 , 12363 , 12634&lt;br /&gt;
  dw 12910 , 13193 , 13482 , 13777 , 14079 , 14387 , 14702 , 15024 , 15353 , 15689&lt;br /&gt;
  dw 16033 , 16384 , 16743 , 17109 , 17484 , 17867 , 18258 , 18658 , 19066 , 19484&lt;br /&gt;
  dw 19911 , 20347 , 20792 , 21247 , 21713 , 22188 , 22674 , 23170 , 23678 , 24196&lt;br /&gt;
  dw 24726 , 25268 , 25821 , 26386 , 26964 , 27554 , 28158 , 28774 , 29404 , 30048&lt;br /&gt;
  dw 30706 , 31379 , 32066 , 32768 , 33485 , 34219 , 34968 , 35734 , 36516 , 37316&lt;br /&gt;
  dw 38133 , 38968 , 39821 , 40693 , 41584 , 42495 , 43425 , 44376 , 45348 , 46341&lt;br /&gt;
  dw 47356 , 48393 , 49452 , 50535 , 51642 , 52772 , 53928 , 55109 , 56316 , 57549&lt;br /&gt;
  dw  58809 , 60097 , 61413 , 62757&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Faster, accurate 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' L = Multiplier, C = Multiplicand&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 80 = 20 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 14 bytes of code + 16 KB tables&lt;br /&gt;
&lt;br /&gt;
I'm currently working on a new routine, based on a routine by Kirk Meyer [http://www.ticalc.org/pub/86/asm/source/routines/vfmult.asm] which uses nibble multiplication tables.&lt;br /&gt;
&lt;br /&gt;
I have a working, tested version which uses 16K of tables and can perform multiplication in 20&amp;amp;mu;s.&lt;br /&gt;
&lt;br /&gt;
The code to produce the tables is below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp1&lt;br /&gt;
ld a,l&lt;br /&gt;
rla&lt;br /&gt;
and #1e&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp1&lt;br /&gt;
inc h&lt;br /&gt;
.makelp2&lt;br /&gt;
ld a,l&lt;br /&gt;
rra:rra:rra&lt;br /&gt;
and #1e&lt;br /&gt;
jr z,usez&lt;br /&gt;
add restab2 - restab / 256 - 2&lt;br /&gt;
.usez&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp2&lt;br /&gt;
inc h			; restab&lt;br /&gt;
.makelp3&lt;br /&gt;
ld a,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
add l&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,0&lt;br /&gt;
adc d&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h:dec h:dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256 - 2&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
ld b,h&lt;br /&gt;
ld c,l&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp4&lt;br /&gt;
ld e,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
dec h&lt;br /&gt;
ex de,hl&lt;br /&gt;
add hl,hl:add hl,hl:add hl,hl:add hl,hl&lt;br /&gt;
ex de,hl&lt;br /&gt;
ld a,e&lt;br /&gt;
ld (bc),a&lt;br /&gt;
inc b&lt;br /&gt;
ld a,d&lt;br /&gt;
ld (bc),a&lt;br /&gt;
dec b&lt;br /&gt;
inc l&lt;br /&gt;
inc c&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
.restab2&lt;br /&gt;
ds 512 * 15&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code to perform the multiplication (DE = L * C):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ld h,hltab1 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
inc h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(bc)		; 10&lt;br /&gt;
add (hl)		; 12&lt;br /&gt;
ld e,a			; 13&lt;br /&gt;
inc b			; 14&lt;br /&gt;
inc h			; 15&lt;br /&gt;
ld a,(bc)		; 17&lt;br /&gt;
adc (hl)		; 19&lt;br /&gt;
ld d,a			; 20&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
16K is a lot of memory to use for tables, but I'm working on a way to reduce this to 8K while maintaining similar performance (around 26&amp;amp;mu;s). The idea is rather than using tables for the low and high nibbles, use tables for alternate bits. So there would be 16 tables for the values #00, #01, #04, #05, #10, #11, #14, #15, #40, #41, #44, #45, #50, #51, #54, #55. The values can be shifted by 1 (rather than 4) to give values for the alternate bits using a simple ADD HL,HL.&lt;br /&gt;
&lt;br /&gt;
This routine should be easy to adapt to a 16bit * 8bit unsigned multiplication or even a 16bit * 16bit, using simple additions.&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 03:58, 8 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 100 = 25 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 19 bytes of code + 8 KB tables&lt;br /&gt;
&lt;br /&gt;
Ok, here is the new 8K routine, first the routine to build the tables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp5&lt;br /&gt;
ld a,l&lt;br /&gt;
ld bc,0&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
ld a,b&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,c&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp5&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp6&lt;br /&gt;
ld (hl),l&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp6&lt;br /&gt;
inc h:inc h&lt;br /&gt;
ld b,2&lt;br /&gt;
.makelp8&lt;br /&gt;
push bc&lt;br /&gt;
xor a&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
.makelp7&lt;br /&gt;
push hl&lt;br /&gt;
push af&lt;br /&gt;
call mulLbyA&lt;br /&gt;
ex de,hl&lt;br /&gt;
pop af&lt;br /&gt;
pop hl&lt;br /&gt;
ld (hl),e&lt;br /&gt;
inc h&lt;br /&gt;
ld (hl),d&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp7&lt;br /&gt;
inc h:inc h&lt;br /&gt;
pop bc&lt;br /&gt;
inc b&lt;br /&gt;
bit 4,b&lt;br /&gt;
jr z,makelp8&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
.mulLbyA	; MAX times	; MIN times&lt;br /&gt;
ld e,l		; 1		; 1&lt;br /&gt;
ld d,0		; 3		; 3&lt;br /&gt;
add a		; 4		; 4&lt;br /&gt;
ld h,a		; 5		; 5&lt;br /&gt;
jr c,ncad0	; 8		; 8&lt;br /&gt;
ld l,d		&lt;br /&gt;
.ncad0&lt;br /&gt;
add hl,hl	; 11		; 11&lt;br /&gt;
jr nc,ncad1	; 13		; 14&lt;br /&gt;
add hl,de	; 16&lt;br /&gt;
.ncad1&lt;br /&gt;
add hl,hl	; 19		; 17&lt;br /&gt;
jr nc,ncad2	; 21		; 20&lt;br /&gt;
add hl,de	; 24&lt;br /&gt;
.ncad2&lt;br /&gt;
add hl,hl	; 27		; 23&lt;br /&gt;
jr nc,ncad3	; 29		; 26&lt;br /&gt;
add hl,de	; 32&lt;br /&gt;
.ncad3&lt;br /&gt;
add hl,hl	; 35		; 29&lt;br /&gt;
jr nc,ncad4	; 37		; 32&lt;br /&gt;
add hl,de	; 40&lt;br /&gt;
.ncad4&lt;br /&gt;
add hl,hl	; 43		; 35&lt;br /&gt;
jr nc,ncad5	; 45		; 38&lt;br /&gt;
add hl,de	; 48&lt;br /&gt;
.ncad5&lt;br /&gt;
add hl,hl	; 51		; 41&lt;br /&gt;
jr nc,ncad6	; 53		; 44&lt;br /&gt;
add hl,de	; 56&lt;br /&gt;
.ncad6&lt;br /&gt;
add hl,hl	; 59		; 47&lt;br /&gt;
ld a,h		; 60		; 48&lt;br /&gt;
ret nc		; 61		; 50?&lt;br /&gt;
add hl,de	; 64&lt;br /&gt;
ld a,h		; 65&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the routine to do the multiplication:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.umultCL		; Using 8 bit only (25us - DE = L * C)&lt;br /&gt;
ld h,hltab2 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
dec h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(hl)		; 10&lt;br /&gt;
add a			; 11&lt;br /&gt;
inc h			; 12&lt;br /&gt;
ld d,(hl)		; 14&lt;br /&gt;
rl d			; 16&lt;br /&gt;
ld h,b			; 17&lt;br /&gt;
add (hl)		; 19&lt;br /&gt;
ld e,a			; 20&lt;br /&gt;
inc h			; 21&lt;br /&gt;
ld a,(hl)		; 23&lt;br /&gt;
adc d			; 24&lt;br /&gt;
ld d,a			; 25&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Very fast 8bit * 8bit Unsigned with only 1K of tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input''': B = Multiplier, C = Multiplicant&lt;br /&gt;
&lt;br /&gt;
'''Output''': DE = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles''': 104-112 (108 on average) = 26-28 (27)&lt;br /&gt;
&lt;br /&gt;
'''Size''': 24 bytes of code and 1024 bytes for the tables&lt;br /&gt;
&lt;br /&gt;
Here's a new routine I've developed which uses the formula ab = ((a + b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - (a - b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) / 4. It's based on a routine for the 6502 by Stephen Judd in a C= Hacking article. Because of differences between the way the 6502 does register indexing it was quite difficult to actually get this working, but it's a great compromise between speed and space since it only uses 1K of tables (as opposed to the 16K or 8K table routines above), and can still manage to do the job in a maximum of 28 microseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Firstly, once again, we need some code to generate the tables. These tables contain values for&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;/4 for 9 bit values of x, with the LSB when bit 8 is zero first followed by the MSB.&lt;br /&gt;
&amp;lt;pre&amp;gt;.gen_sq4&lt;br /&gt;
	xor a&lt;br /&gt;
	ld de,umul_tab + #1ff&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	ld h,d&lt;br /&gt;
	ld l,e&lt;br /&gt;
	inc e&lt;br /&gt;
	ld c,e&lt;br /&gt;
	ld b,2&lt;br /&gt;
&lt;br /&gt;
	.sq4_lp&lt;br /&gt;
	ld a,b&lt;br /&gt;
	cp 2&lt;br /&gt;
	ld a,e&lt;br /&gt;
	rra&lt;br /&gt;
	add (hl)&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	inc h&lt;br /&gt;
	inc d&lt;br /&gt;
	ld a,(hl)&lt;br /&gt;
	adc c&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld h,d&lt;br /&gt;
	inc l&lt;br /&gt;
	inc e&lt;br /&gt;
	jr nz,sq4_lp&lt;br /&gt;
	inc d&lt;br /&gt;
	inc d&lt;br /&gt;
	djnz sq4_lp&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
align #100&lt;br /&gt;
.umul_tab ds #400&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now for the actual multiply routine:&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', L = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ld h,umul_tab_lo / #100	; 2&lt;br /&gt;
	ld b,h			; 3&lt;br /&gt;
	add l			; 4&lt;br /&gt;
	ld c,a			; 5&lt;br /&gt;
	jr nc,@noovf		; 7&lt;br /&gt;
	inc b			; 8&lt;br /&gt;
	inc b			; 9&lt;br /&gt;
.@noovf&lt;br /&gt;
	sub l			; 10&lt;br /&gt;
	sub l			; 11&lt;br /&gt;
	jr nc,@noneg		; 13&lt;br /&gt;
	neg			; 15&lt;br /&gt;
.@noneg&lt;br /&gt;
	ld l,a			; 16&lt;br /&gt;
	ld a,(bc)		; 18&lt;br /&gt;
	sub (hl)		; 20&lt;br /&gt;
	ld e,a			; 21&lt;br /&gt;
	inc b			; 22&lt;br /&gt;
	inc h			; 23&lt;br /&gt;
	ld a,(bc)		; 25&lt;br /&gt;
	sbc (hl)		; 27&lt;br /&gt;
	ld d,a			; 28&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This code could easily be converted to a macro as it's only 24 bytes. I've tried to optimize it further but with no luck!&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 06:25, 4 April 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== 16bit * 16bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' BC = ''Multiplier'', DE = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A,HL = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;ld ix,0&lt;br /&gt;
 ld hl,0&lt;br /&gt;
.mul24b1:&lt;br /&gt;
 ld a,c&lt;br /&gt;
 or b&lt;br /&gt;
 jr z,mul24b3&lt;br /&gt;
 srl b&lt;br /&gt;
 rr c&lt;br /&gt;
 jr nc,mul24b2&lt;br /&gt;
 add ix,de&lt;br /&gt;
 ld a,h&lt;br /&gt;
 adc l&lt;br /&gt;
 ld h,a&lt;br /&gt;
.mul24b2:&lt;br /&gt;
 sla e&lt;br /&gt;
 rl d&lt;br /&gt;
 rl l&lt;br /&gt;
 jr mul24b1:&lt;br /&gt;
.mul24b3:&lt;br /&gt;
 ld a,h&lt;br /&gt;
 db #dd:ld e,l&lt;br /&gt;
 db #dd:ld d,h&lt;br /&gt;
 ex de,hl&lt;br /&gt;
 ret&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://map.tni.nl/articles/mult_div_shifts.php Multiplications and divisions on the MSX Assembly Page]&lt;br /&gt;
* [http://www.mccw.hetlab.tk/92/Multiplication/en.html &amp;quot;Multiplication on a Z80&amp;quot; ( MSX Computer &amp;amp; Club Webmagazine)]&lt;br /&gt;
* [http://www.andreadrian.de/oldcpu/Z80_number_cruncher.html The Z80 number cruncher (Andre Adrian)] (16/32bit multiplication, addition, right shift)&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94464</id>
		<title>Programming:Integer Multiplication</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94464"/>
				<updated>2015-10-24T07:18:22Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: /* Faster, accurate 8bit * 8bit Unsigned */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Classic 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' H = ''Multiplier'', E = ''Multiplicand'', L = 0, D = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 188-244 (216 on average) = 47-61 (54) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 33 bytes&lt;br /&gt;
&lt;br /&gt;
The additional clocks and bytes maybe required to set up D and L and for RET.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sla h  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+3&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
jr nc,$+3  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Classic 16bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', DE = ''Multiplicand'', HL = 0, C = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A:HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 212-300 (256 on average) = 53-75 (64) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 47 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add a,a  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+4&lt;br /&gt;
ld h,d&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
rla   ; ...&lt;br /&gt;
jr nc,$+4  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
adc a,c  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast 8bit * 8bit Unsigned (using log / antilog tables) ==&lt;br /&gt;
&lt;br /&gt;
The original routine was written by Jeff Frohwein for the Nintendo Gameboy. You can find it on [http://www.devrs.com/gb/files/logmult.txt Devrs.com].&lt;br /&gt;
&lt;br /&gt;
Because of the usage of log / antilog tables this routine is less accurate, but very fast. It takes advantage of the fact that if you take the log of two numbers, add the results and then take the antilog of the total you have done the equivalent of multiplying the two numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 x^a * x^b = x^(a+b)&lt;br /&gt;
&lt;br /&gt;
 a * b = x^(logx(a) + logx(b))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Input:''' B = ''Multiplier'', C = ''Multiplicant''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 124 = 31 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 1024 bytes (768 bytes for the tables)&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' It is VERY approximate routine, e.g., 0*7=7, 1*28=27, 10*81=790, 100*100=9742, ...&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FastMult:&lt;br /&gt;
  ld      l,c&lt;br /&gt;
  ld      h,&amp;amp;82&lt;br /&gt;
  ld      d,(hl)          ; d = 32 * log_2(c)&lt;br /&gt;
  &lt;br /&gt;
  ld      l,b&lt;br /&gt;
  ld      a,(hl)          ; a = 32 * log_2(b)&lt;br /&gt;
  &lt;br /&gt;
  add     a,d&lt;br /&gt;
  ld      l,a&lt;br /&gt;
  ld      a,0&lt;br /&gt;
  adc     a,0&lt;br /&gt;
  ld      h,a             ; hl = d + a&lt;br /&gt;
  &lt;br /&gt;
  add     hl,hl&lt;br /&gt;
  set     2,h             ; hl = hl + $0400&lt;br /&gt;
  set     7,h             ; hl = hl + &amp;amp;8000&lt;br /&gt;
  &lt;br /&gt;
  ld      e,(hl)&lt;br /&gt;
  inc     hl&lt;br /&gt;
  ld      d,(hl)          ; de = 2^((hl)/32)&lt;br /&gt;
  &lt;br /&gt;
  ret&lt;br /&gt;
&lt;br /&gt;
; 32*Log_2(x) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 TO 255&lt;br /&gt;
;     C=4 &lt;br /&gt;
;     B=2&lt;br /&gt;
;     FOR Z=1 TO 10&lt;br /&gt;
;       IF (2^C) &amp;gt; A THEN C=C-B ELSE C=C+B&lt;br /&gt;
;       B=B/2&lt;br /&gt;
;     NEXT Z&lt;br /&gt;
;     PRINT INT(C*32);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8200&lt;br /&gt;
&lt;br /&gt;
logtable:&lt;br /&gt;
  db 0 , 0 , 32 , 50 , 64 , 74 , 82 , 89 , 96 , 101 , 106 , 110 , 114 , 118 , 121&lt;br /&gt;
  db 125 , 128 , 130 , 133 , 135 , 138 , 140 , 142 , 144 , 146 , 148 , 150 , 152&lt;br /&gt;
  db 153 , 155 , 157 , 158 , 160 , 161 , 162 , 164 , 165 , 166 , 167 , 169 , 170&lt;br /&gt;
  db 171 , 172 , 173 , 174 , 175 , 176 , 177 , 178 , 179 , 180 , 181 , 182 , 183&lt;br /&gt;
  db 184 , 185 , 185 , 186 , 187 , 188 , 189 , 189 , 190 , 191 , 192 , 192 , 193&lt;br /&gt;
  db 194 , 194 , 195 , 196 , 196 , 197 , 198 , 198 , 199 , 199 , 200 , 201 , 201&lt;br /&gt;
  db 202 , 202 , 203 , 204 , 204 , 205 , 205 , 206 , 206 , 207 , 207 , 208 , 208&lt;br /&gt;
  db 209 , 209 , 210 , 210 , 211 , 211 , 212 , 212 , 213 , 213 , 213 , 214 , 214&lt;br /&gt;
  db 215 , 215 , 216 , 216 , 217 , 217 , 217 , 218 , 218 , 219 , 219 , 219 , 220&lt;br /&gt;
  db 220 , 221 , 221 , 221 , 222 , 222 , 222 , 223 , 223 , 224 , 224 , 224 , 225&lt;br /&gt;
  db 225 , 225 , 226 , 226 , 226 , 227 , 227 , 227 , 228 , 228 , 228 , 229 , 229&lt;br /&gt;
  db 229 , 230 , 230 , 230 , 231 , 231 , 231 , 231 , 232 , 232 , 232 , 233 , 233&lt;br /&gt;
  db 233 , 234 , 234 , 234 , 234 , 235 , 235 , 235 , 236 , 236 , 236 , 236 , 237&lt;br /&gt;
  db 237 , 237 , 237 , 238 , 238 , 238 , 238 , 239 , 239 , 239 , 239 , 240 , 240&lt;br /&gt;
  db 240 , 241 , 241 , 241 , 241 , 241 , 242 , 242 , 242 , 242 , 243 , 243 , 243&lt;br /&gt;
  db 243 , 244 , 244 , 244 , 244 , 245 , 245 , 245 , 245 , 245 , 246 , 246 , 246&lt;br /&gt;
  db 246 , 247 , 247 , 247 , 247 , 247 , 248 , 248 , 248 , 248 , 249 , 249 , 249&lt;br /&gt;
  db 249 , 249 , 250 , 250 , 250 , 250 , 250 , 251 , 251 , 251 , 251 , 251 , 252&lt;br /&gt;
  db 252 , 252 , 252 , 252 , 253 , 253 , 253 , 253 , 253 , 253 , 254 , 254 , 254&lt;br /&gt;
  db 254 , 254 , 255 , 255 , 255 , 255 , 255&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; AntiLog 2^(x/32) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 to 510&lt;br /&gt;
;   PRINT INT(2^(A/32)+.5);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8400&lt;br /&gt;
&lt;br /&gt;
antilog:&lt;br /&gt;
  dw 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 , 4&lt;br /&gt;
  dw 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 6&lt;br /&gt;
  dw 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 8 , 9&lt;br /&gt;
  dw 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , 12 , 12 , 12&lt;br /&gt;
  dw 13 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17&lt;br /&gt;
  dw 18 , 18 , 19 , 19 , 19 , 20 , 20 , 21 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25&lt;br /&gt;
  dw 25 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , 30 , 31 , 31 , 32 , 33 , 33 , 34 , 35&lt;br /&gt;
  dw 36 , 36 , 37 , 38 , 39 , 40 , 41 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49&lt;br /&gt;
  dw 50 , 52 , 53 , 54 , 55 , 56 , 57 , 59 , 60 , 61 , 63 , 64 , 65 , 67 , 68 , 70&lt;br /&gt;
  dw 71 , 73 , 74 , 76 , 78 , 79 , 81 , 83 , 85 , 87 , 89 , 91 , 92 , 95 , 97 , 99&lt;br /&gt;
  dw 101 , 103 , 105 , 108 , 110 , 112 , 115 , 117 , 120 , 123 , 125 , 128 , 131&lt;br /&gt;
  dw 134 , 137 , 140 , 143 , 146 , 149 , 152 , 156 , 159 , 162 , 166 , 170 , 173&lt;br /&gt;
  dw 177 , 181 , 185 , 189 , 193 , 197 , 202 , 206 , 211 , 215 , 220 , 225 , 230&lt;br /&gt;
  dw 235 , 240 , 245 , 251 , 256 , 262 , 267 , 273 , 279 , 285 , 292 , 298 , 304&lt;br /&gt;
  dw 311 , 318 , 325 , 332 , 339 , 347 , 354 , 362 , 370 , 378 , 386 , 395 , 403&lt;br /&gt;
  dw 412 , 421 , 431 , 440 , 450 , 459 , 470 , 480 , 490 , 501 , 512 , 523 , 535&lt;br /&gt;
  dw 546 , 558 , 571 , 583 , 596 , 609 , 622 , 636 , 650 , 664 , 679 , 693 , 709&lt;br /&gt;
  dw 724 , 740 , 756 , 773 , 790 , 807 , 825 , 843 , 861 , 880 , 899 , 919 , 939&lt;br /&gt;
  dw 960 , 981 , 1002 , 1024 , 1046 , 1069 , 1093 , 1117 , 1141 , 1166 , 1192&lt;br /&gt;
  dw 1218 , 1244 , 1272 , 1300 , 1328 , 1357 , 1387 , 1417 , 1448 , 1480 , 1512&lt;br /&gt;
  dw 1545 , 1579 , 1614 , 1649 , 1685 , 1722 , 1760 , 1798 , 1838 , 1878 , 1919&lt;br /&gt;
  dw 1961 , 2004 , 2048 , 2093 , 2139 , 2186 , 2233 , 2282 , 2332 , 2383 , 2435&lt;br /&gt;
  dw 2489 , 2543 , 2599 , 2656 , 2714 , 2774 , 2834 , 2896 , 2960 , 3025 , 3091&lt;br /&gt;
  dw 3158 , 3228 , 3298 , 3371 , 3444 , 3520 , 3597 , 3676 , 3756 , 3838 , 3922&lt;br /&gt;
  dw 4008 , 4096 , 4186 , 4277 , 4371 , 4467 , 4565 , 4664 , 4767 , 4871 , 4978&lt;br /&gt;
  dw 5087 , 5198 , 5312 , 5428 , 5547 , 5668 , 5793 , 5919 , 6049 , 6182 , 6317&lt;br /&gt;
  dw 6455 , 6597 , 6741 , 6889 , 7039 , 7194 , 7351 , 7512 , 7677 , 7845 , 8016&lt;br /&gt;
  dw 8192 , 8371 , 8555 , 8742 , 8933 , 9129 , 9329 , 9533 , 9742 , 9955 , 10173&lt;br /&gt;
  dw 10396 , 10624 , 10856 , 11094 , 11337 , 11585 , 11839 , 12098 , 12363 , 12634&lt;br /&gt;
  dw 12910 , 13193 , 13482 , 13777 , 14079 , 14387 , 14702 , 15024 , 15353 , 15689&lt;br /&gt;
  dw 16033 , 16384 , 16743 , 17109 , 17484 , 17867 , 18258 , 18658 , 19066 , 19484&lt;br /&gt;
  dw 19911 , 20347 , 20792 , 21247 , 21713 , 22188 , 22674 , 23170 , 23678 , 24196&lt;br /&gt;
  dw 24726 , 25268 , 25821 , 26386 , 26964 , 27554 , 28158 , 28774 , 29404 , 30048&lt;br /&gt;
  dw 30706 , 31379 , 32066 , 32768 , 33485 , 34219 , 34968 , 35734 , 36516 , 37316&lt;br /&gt;
  dw 38133 , 38968 , 39821 , 40693 , 41584 , 42495 , 43425 , 44376 , 45348 , 46341&lt;br /&gt;
  dw 47356 , 48393 , 49452 , 50535 , 51642 , 52772 , 53928 , 55109 , 56316 , 57549&lt;br /&gt;
  dw  58809 , 60097 , 61413 , 62757&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Faster, accurate 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' L = Multiplier, C = Multiplicand&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = Product&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 80 = 20 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 14 bytes of code + 16 KB tables&lt;br /&gt;
&lt;br /&gt;
I'm currently working on a new routine, based on a routine by Kirk Meyer [http://www.ticalc.org/pub/86/asm/source/routines/vfmult.asm] which uses nibble multiplication tables.&lt;br /&gt;
&lt;br /&gt;
I have a working, tested version which uses 16K of tables and can perform multiplication in 20&amp;amp;mu;s.&lt;br /&gt;
&lt;br /&gt;
The code to produce the tables is below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp1&lt;br /&gt;
ld a,l&lt;br /&gt;
rla&lt;br /&gt;
and #1e&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp1&lt;br /&gt;
inc h&lt;br /&gt;
.makelp2&lt;br /&gt;
ld a,l&lt;br /&gt;
rra:rra:rra&lt;br /&gt;
and #1e&lt;br /&gt;
jr z,usez&lt;br /&gt;
add restab2 - restab / 256 - 2&lt;br /&gt;
.usez&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp2&lt;br /&gt;
inc h			; restab&lt;br /&gt;
.makelp3&lt;br /&gt;
ld a,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
add l&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,0&lt;br /&gt;
adc d&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h:dec h:dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256 - 2&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
ld b,h&lt;br /&gt;
ld c,l&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp4&lt;br /&gt;
ld e,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
dec h&lt;br /&gt;
ex de,hl&lt;br /&gt;
add hl,hl:add hl,hl:add hl,hl:add hl,hl&lt;br /&gt;
ex de,hl&lt;br /&gt;
ld a,e&lt;br /&gt;
ld (bc),a&lt;br /&gt;
inc b&lt;br /&gt;
ld a,d&lt;br /&gt;
ld (bc),a&lt;br /&gt;
dec b&lt;br /&gt;
inc l&lt;br /&gt;
inc c&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
.restab2&lt;br /&gt;
ds 512 * 15&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code to perform the multiplication (DE = L * C):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ld h,hltab1 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
inc h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(bc)		; 10&lt;br /&gt;
add (hl)		; 12&lt;br /&gt;
ld e,a			; 13&lt;br /&gt;
inc b			; 14&lt;br /&gt;
inc h			; 15&lt;br /&gt;
ld a,(bc)		; 17&lt;br /&gt;
adc (hl)		; 19&lt;br /&gt;
ld d,a			; 20&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
16K is a lot of memory to use for tables, but I'm working on a way to reduce this to 8K while maintaining similar performance (around 26&amp;amp;mu;s). The idea is rather than using tables for the low and high nibbles, use tables for alternate bits. So there would be 16 tables for the values #00, #01, #04, #05, #10, #11, #14, #15, #40, #41, #44, #45, #50, #51, #54, #55. The values can be shifted by 1 (rather than 4) to give values for the alternate bits using a simple ADD HL,HL.&lt;br /&gt;
&lt;br /&gt;
This routine should be easy to adapt to a 16bit * 8bit unsigned multiplication or even a 16bit * 16bit, using simple additions.&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 03:58, 8 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 100 = 25 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 19 bytes of code + 8 KB tables&lt;br /&gt;
&lt;br /&gt;
Ok, here is the new 8K routine, first the routine to build the tables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp5&lt;br /&gt;
ld a,l&lt;br /&gt;
ld bc,0&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
ld a,b&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,c&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp5&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp6&lt;br /&gt;
ld (hl),l&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp6&lt;br /&gt;
inc h:inc h&lt;br /&gt;
ld b,2&lt;br /&gt;
.makelp8&lt;br /&gt;
push bc&lt;br /&gt;
xor a&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
.makelp7&lt;br /&gt;
push hl&lt;br /&gt;
push af&lt;br /&gt;
call mulLbyA&lt;br /&gt;
ex de,hl&lt;br /&gt;
pop af&lt;br /&gt;
pop hl&lt;br /&gt;
ld (hl),e&lt;br /&gt;
inc h&lt;br /&gt;
ld (hl),d&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp7&lt;br /&gt;
inc h:inc h&lt;br /&gt;
pop bc&lt;br /&gt;
inc b&lt;br /&gt;
bit 4,b&lt;br /&gt;
jr z,makelp8&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
.mulLbyA	; MAX times	; MIN times&lt;br /&gt;
ld e,l		; 1		; 1&lt;br /&gt;
ld d,0		; 3		; 3&lt;br /&gt;
add a		; 4		; 4&lt;br /&gt;
ld h,a		; 5		; 5&lt;br /&gt;
jr c,ncad0	; 8		; 8&lt;br /&gt;
ld l,d		&lt;br /&gt;
.ncad0&lt;br /&gt;
add hl,hl	; 11		; 11&lt;br /&gt;
jr nc,ncad1	; 13		; 14&lt;br /&gt;
add hl,de	; 16&lt;br /&gt;
.ncad1&lt;br /&gt;
add hl,hl	; 19		; 17&lt;br /&gt;
jr nc,ncad2	; 21		; 20&lt;br /&gt;
add hl,de	; 24&lt;br /&gt;
.ncad2&lt;br /&gt;
add hl,hl	; 27		; 23&lt;br /&gt;
jr nc,ncad3	; 29		; 26&lt;br /&gt;
add hl,de	; 32&lt;br /&gt;
.ncad3&lt;br /&gt;
add hl,hl	; 35		; 29&lt;br /&gt;
jr nc,ncad4	; 37		; 32&lt;br /&gt;
add hl,de	; 40&lt;br /&gt;
.ncad4&lt;br /&gt;
add hl,hl	; 43		; 35&lt;br /&gt;
jr nc,ncad5	; 45		; 38&lt;br /&gt;
add hl,de	; 48&lt;br /&gt;
.ncad5&lt;br /&gt;
add hl,hl	; 51		; 41&lt;br /&gt;
jr nc,ncad6	; 53		; 44&lt;br /&gt;
add hl,de	; 56&lt;br /&gt;
.ncad6&lt;br /&gt;
add hl,hl	; 59		; 47&lt;br /&gt;
ld a,h		; 60		; 48&lt;br /&gt;
ret nc		; 61		; 50?&lt;br /&gt;
add hl,de	; 64&lt;br /&gt;
ld a,h		; 65&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the routine to do the multiplication:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.umultCL		; Using 8 bit only (25us - DE = L * C)&lt;br /&gt;
ld h,hltab2 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
dec h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(hl)		; 10&lt;br /&gt;
add a			; 11&lt;br /&gt;
inc h			; 12&lt;br /&gt;
ld d,(hl)		; 14&lt;br /&gt;
rl d			; 16&lt;br /&gt;
ld h,b			; 17&lt;br /&gt;
add (hl)		; 19&lt;br /&gt;
ld e,a			; 20&lt;br /&gt;
inc h			; 21&lt;br /&gt;
ld a,(hl)		; 23&lt;br /&gt;
adc d			; 24&lt;br /&gt;
ld d,a			; 25&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Very fast 8bit * 8bit Unsigned with only 1K of tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input''': B = Multiplier, C = Multiplicant&lt;br /&gt;
&lt;br /&gt;
'''Output''': DE = Product&lt;br /&gt;
&lt;br /&gt;
'''Clocks''': 104-112 (108 on average)&lt;br /&gt;
&lt;br /&gt;
'''Size''': 24 bytes of code and 1024 bytes for the tables&lt;br /&gt;
&lt;br /&gt;
Here's a new routine I've developed which uses the formula ab = ((a + b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - (a - b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) / 4. It's based on a routine for the 6502 by Stephen Judd in a C= Hacking article. Because of differences between the way the 6502 does register indexing it was quite difficult to actually get this working, but it's a great compromise between speed and space since it only uses 1K of tables (as opposed to the 16K or 8K table routines above), and can still manage to do the job in a maximum of 28 microseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Firstly, once again, we need some code to generate the tables. These tables contain values for&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;/4 for 9 bit values of x, with the LSB when bit 8 is zero first followed by the MSB.&lt;br /&gt;
&amp;lt;pre&amp;gt;.gen_sq4&lt;br /&gt;
	xor a&lt;br /&gt;
	ld de,umul_tab + #1ff&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	ld h,d&lt;br /&gt;
	ld l,e&lt;br /&gt;
	inc e&lt;br /&gt;
	ld c,e&lt;br /&gt;
	ld b,2&lt;br /&gt;
&lt;br /&gt;
	.sq4_lp&lt;br /&gt;
	ld a,b&lt;br /&gt;
	cp 2&lt;br /&gt;
	ld a,e&lt;br /&gt;
	rra&lt;br /&gt;
	add (hl)&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	inc h&lt;br /&gt;
	inc d&lt;br /&gt;
	ld a,(hl)&lt;br /&gt;
	adc c&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld h,d&lt;br /&gt;
	inc l&lt;br /&gt;
	inc e&lt;br /&gt;
	jr nz,sq4_lp&lt;br /&gt;
	inc d&lt;br /&gt;
	inc d&lt;br /&gt;
	djnz sq4_lp&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
align #100&lt;br /&gt;
.umul_tab ds #400&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now for the actual multiply routine:&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', L = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ld h,umul_tab_lo / #100	; 2&lt;br /&gt;
	ld b,h			; 3&lt;br /&gt;
	add l			; 4&lt;br /&gt;
	ld c,a			; 5&lt;br /&gt;
	jr nc,@noovf		; 7&lt;br /&gt;
	inc b			; 8&lt;br /&gt;
	inc b			; 9&lt;br /&gt;
.@noovf&lt;br /&gt;
	sub l			; 10&lt;br /&gt;
	sub l			; 11&lt;br /&gt;
	jr nc,@noneg		; 13&lt;br /&gt;
	neg			; 15&lt;br /&gt;
.@noneg&lt;br /&gt;
	ld l,a			; 16&lt;br /&gt;
	ld a,(bc)		; 18&lt;br /&gt;
	sub (hl)		; 20&lt;br /&gt;
	ld e,a			; 21&lt;br /&gt;
	inc b			; 22&lt;br /&gt;
	inc h			; 23&lt;br /&gt;
	ld a,(bc)		; 25&lt;br /&gt;
	sbc (hl)		; 27&lt;br /&gt;
	ld d,a			; 28&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This code could easily be converted to a macro as it's only 24 bytes. I've tried to optimize it further but with no luck!&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 06:25, 4 April 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== 16bit * 16bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' BC = ''Multiplier'', DE = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A,HL = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;ld ix,0&lt;br /&gt;
 ld hl,0&lt;br /&gt;
.mul24b1:&lt;br /&gt;
 ld a,c&lt;br /&gt;
 or b&lt;br /&gt;
 jr z,mul24b3&lt;br /&gt;
 srl b&lt;br /&gt;
 rr c&lt;br /&gt;
 jr nc,mul24b2&lt;br /&gt;
 add ix,de&lt;br /&gt;
 ld a,h&lt;br /&gt;
 adc l&lt;br /&gt;
 ld h,a&lt;br /&gt;
.mul24b2:&lt;br /&gt;
 sla e&lt;br /&gt;
 rl d&lt;br /&gt;
 rl l&lt;br /&gt;
 jr mul24b1:&lt;br /&gt;
.mul24b3:&lt;br /&gt;
 ld a,h&lt;br /&gt;
 db #dd:ld e,l&lt;br /&gt;
 db #dd:ld d,h&lt;br /&gt;
 ex de,hl&lt;br /&gt;
 ret&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://map.tni.nl/articles/mult_div_shifts.php Multiplications and divisions on the MSX Assembly Page]&lt;br /&gt;
* [http://www.mccw.hetlab.tk/92/Multiplication/en.html &amp;quot;Multiplication on a Z80&amp;quot; ( MSX Computer &amp;amp; Club Webmagazine)]&lt;br /&gt;
* [http://www.andreadrian.de/oldcpu/Z80_number_cruncher.html The Z80 number cruncher (Andre Adrian)] (16/32bit multiplication, addition, right shift)&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94463</id>
		<title>Programming:Integer Multiplication</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94463"/>
				<updated>2015-10-24T07:10:52Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: /* Fast 8bit * 8bit Unsigned (using log / antilog tables) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Classic 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' H = ''Multiplier'', E = ''Multiplicand'', L = 0, D = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 188-244 (216 on average) = 47-61 (54) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 33 bytes&lt;br /&gt;
&lt;br /&gt;
The additional clocks and bytes maybe required to set up D and L and for RET.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sla h  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+3&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
jr nc,$+3  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Classic 16bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', DE = ''Multiplicand'', HL = 0, C = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A:HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 212-300 (256 on average) = 53-75 (64) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 47 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add a,a  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+4&lt;br /&gt;
ld h,d&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
rla   ; ...&lt;br /&gt;
jr nc,$+4  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
adc a,c  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast 8bit * 8bit Unsigned (using log / antilog tables) ==&lt;br /&gt;
&lt;br /&gt;
The original routine was written by Jeff Frohwein for the Nintendo Gameboy. You can find it on [http://www.devrs.com/gb/files/logmult.txt Devrs.com].&lt;br /&gt;
&lt;br /&gt;
Because of the usage of log / antilog tables this routine is less accurate, but very fast. It takes advantage of the fact that if you take the log of two numbers, add the results and then take the antilog of the total you have done the equivalent of multiplying the two numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 x^a * x^b = x^(a+b)&lt;br /&gt;
&lt;br /&gt;
 a * b = x^(logx(a) + logx(b))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Input:''' B = ''Multiplier'', C = ''Multiplicant''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 124 = 31 usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 1024 bytes (768 bytes for the tables)&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' It is VERY approximate routine, e.g., 0*7=7, 1*28=27, 10*81=790, 100*100=9742, ...&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FastMult:&lt;br /&gt;
  ld      l,c&lt;br /&gt;
  ld      h,&amp;amp;82&lt;br /&gt;
  ld      d,(hl)          ; d = 32 * log_2(c)&lt;br /&gt;
  &lt;br /&gt;
  ld      l,b&lt;br /&gt;
  ld      a,(hl)          ; a = 32 * log_2(b)&lt;br /&gt;
  &lt;br /&gt;
  add     a,d&lt;br /&gt;
  ld      l,a&lt;br /&gt;
  ld      a,0&lt;br /&gt;
  adc     a,0&lt;br /&gt;
  ld      h,a             ; hl = d + a&lt;br /&gt;
  &lt;br /&gt;
  add     hl,hl&lt;br /&gt;
  set     2,h             ; hl = hl + $0400&lt;br /&gt;
  set     7,h             ; hl = hl + &amp;amp;8000&lt;br /&gt;
  &lt;br /&gt;
  ld      e,(hl)&lt;br /&gt;
  inc     hl&lt;br /&gt;
  ld      d,(hl)          ; de = 2^((hl)/32)&lt;br /&gt;
  &lt;br /&gt;
  ret&lt;br /&gt;
&lt;br /&gt;
; 32*Log_2(x) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 TO 255&lt;br /&gt;
;     C=4 &lt;br /&gt;
;     B=2&lt;br /&gt;
;     FOR Z=1 TO 10&lt;br /&gt;
;       IF (2^C) &amp;gt; A THEN C=C-B ELSE C=C+B&lt;br /&gt;
;       B=B/2&lt;br /&gt;
;     NEXT Z&lt;br /&gt;
;     PRINT INT(C*32);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8200&lt;br /&gt;
&lt;br /&gt;
logtable:&lt;br /&gt;
  db 0 , 0 , 32 , 50 , 64 , 74 , 82 , 89 , 96 , 101 , 106 , 110 , 114 , 118 , 121&lt;br /&gt;
  db 125 , 128 , 130 , 133 , 135 , 138 , 140 , 142 , 144 , 146 , 148 , 150 , 152&lt;br /&gt;
  db 153 , 155 , 157 , 158 , 160 , 161 , 162 , 164 , 165 , 166 , 167 , 169 , 170&lt;br /&gt;
  db 171 , 172 , 173 , 174 , 175 , 176 , 177 , 178 , 179 , 180 , 181 , 182 , 183&lt;br /&gt;
  db 184 , 185 , 185 , 186 , 187 , 188 , 189 , 189 , 190 , 191 , 192 , 192 , 193&lt;br /&gt;
  db 194 , 194 , 195 , 196 , 196 , 197 , 198 , 198 , 199 , 199 , 200 , 201 , 201&lt;br /&gt;
  db 202 , 202 , 203 , 204 , 204 , 205 , 205 , 206 , 206 , 207 , 207 , 208 , 208&lt;br /&gt;
  db 209 , 209 , 210 , 210 , 211 , 211 , 212 , 212 , 213 , 213 , 213 , 214 , 214&lt;br /&gt;
  db 215 , 215 , 216 , 216 , 217 , 217 , 217 , 218 , 218 , 219 , 219 , 219 , 220&lt;br /&gt;
  db 220 , 221 , 221 , 221 , 222 , 222 , 222 , 223 , 223 , 224 , 224 , 224 , 225&lt;br /&gt;
  db 225 , 225 , 226 , 226 , 226 , 227 , 227 , 227 , 228 , 228 , 228 , 229 , 229&lt;br /&gt;
  db 229 , 230 , 230 , 230 , 231 , 231 , 231 , 231 , 232 , 232 , 232 , 233 , 233&lt;br /&gt;
  db 233 , 234 , 234 , 234 , 234 , 235 , 235 , 235 , 236 , 236 , 236 , 236 , 237&lt;br /&gt;
  db 237 , 237 , 237 , 238 , 238 , 238 , 238 , 239 , 239 , 239 , 239 , 240 , 240&lt;br /&gt;
  db 240 , 241 , 241 , 241 , 241 , 241 , 242 , 242 , 242 , 242 , 243 , 243 , 243&lt;br /&gt;
  db 243 , 244 , 244 , 244 , 244 , 245 , 245 , 245 , 245 , 245 , 246 , 246 , 246&lt;br /&gt;
  db 246 , 247 , 247 , 247 , 247 , 247 , 248 , 248 , 248 , 248 , 249 , 249 , 249&lt;br /&gt;
  db 249 , 249 , 250 , 250 , 250 , 250 , 250 , 251 , 251 , 251 , 251 , 251 , 252&lt;br /&gt;
  db 252 , 252 , 252 , 252 , 253 , 253 , 253 , 253 , 253 , 253 , 254 , 254 , 254&lt;br /&gt;
  db 254 , 254 , 255 , 255 , 255 , 255 , 255&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; AntiLog 2^(x/32) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 to 510&lt;br /&gt;
;   PRINT INT(2^(A/32)+.5);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8400&lt;br /&gt;
&lt;br /&gt;
antilog:&lt;br /&gt;
  dw 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 , 4&lt;br /&gt;
  dw 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 6&lt;br /&gt;
  dw 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 8 , 9&lt;br /&gt;
  dw 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , 12 , 12 , 12&lt;br /&gt;
  dw 13 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17&lt;br /&gt;
  dw 18 , 18 , 19 , 19 , 19 , 20 , 20 , 21 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25&lt;br /&gt;
  dw 25 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , 30 , 31 , 31 , 32 , 33 , 33 , 34 , 35&lt;br /&gt;
  dw 36 , 36 , 37 , 38 , 39 , 40 , 41 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49&lt;br /&gt;
  dw 50 , 52 , 53 , 54 , 55 , 56 , 57 , 59 , 60 , 61 , 63 , 64 , 65 , 67 , 68 , 70&lt;br /&gt;
  dw 71 , 73 , 74 , 76 , 78 , 79 , 81 , 83 , 85 , 87 , 89 , 91 , 92 , 95 , 97 , 99&lt;br /&gt;
  dw 101 , 103 , 105 , 108 , 110 , 112 , 115 , 117 , 120 , 123 , 125 , 128 , 131&lt;br /&gt;
  dw 134 , 137 , 140 , 143 , 146 , 149 , 152 , 156 , 159 , 162 , 166 , 170 , 173&lt;br /&gt;
  dw 177 , 181 , 185 , 189 , 193 , 197 , 202 , 206 , 211 , 215 , 220 , 225 , 230&lt;br /&gt;
  dw 235 , 240 , 245 , 251 , 256 , 262 , 267 , 273 , 279 , 285 , 292 , 298 , 304&lt;br /&gt;
  dw 311 , 318 , 325 , 332 , 339 , 347 , 354 , 362 , 370 , 378 , 386 , 395 , 403&lt;br /&gt;
  dw 412 , 421 , 431 , 440 , 450 , 459 , 470 , 480 , 490 , 501 , 512 , 523 , 535&lt;br /&gt;
  dw 546 , 558 , 571 , 583 , 596 , 609 , 622 , 636 , 650 , 664 , 679 , 693 , 709&lt;br /&gt;
  dw 724 , 740 , 756 , 773 , 790 , 807 , 825 , 843 , 861 , 880 , 899 , 919 , 939&lt;br /&gt;
  dw 960 , 981 , 1002 , 1024 , 1046 , 1069 , 1093 , 1117 , 1141 , 1166 , 1192&lt;br /&gt;
  dw 1218 , 1244 , 1272 , 1300 , 1328 , 1357 , 1387 , 1417 , 1448 , 1480 , 1512&lt;br /&gt;
  dw 1545 , 1579 , 1614 , 1649 , 1685 , 1722 , 1760 , 1798 , 1838 , 1878 , 1919&lt;br /&gt;
  dw 1961 , 2004 , 2048 , 2093 , 2139 , 2186 , 2233 , 2282 , 2332 , 2383 , 2435&lt;br /&gt;
  dw 2489 , 2543 , 2599 , 2656 , 2714 , 2774 , 2834 , 2896 , 2960 , 3025 , 3091&lt;br /&gt;
  dw 3158 , 3228 , 3298 , 3371 , 3444 , 3520 , 3597 , 3676 , 3756 , 3838 , 3922&lt;br /&gt;
  dw 4008 , 4096 , 4186 , 4277 , 4371 , 4467 , 4565 , 4664 , 4767 , 4871 , 4978&lt;br /&gt;
  dw 5087 , 5198 , 5312 , 5428 , 5547 , 5668 , 5793 , 5919 , 6049 , 6182 , 6317&lt;br /&gt;
  dw 6455 , 6597 , 6741 , 6889 , 7039 , 7194 , 7351 , 7512 , 7677 , 7845 , 8016&lt;br /&gt;
  dw 8192 , 8371 , 8555 , 8742 , 8933 , 9129 , 9329 , 9533 , 9742 , 9955 , 10173&lt;br /&gt;
  dw 10396 , 10624 , 10856 , 11094 , 11337 , 11585 , 11839 , 12098 , 12363 , 12634&lt;br /&gt;
  dw 12910 , 13193 , 13482 , 13777 , 14079 , 14387 , 14702 , 15024 , 15353 , 15689&lt;br /&gt;
  dw 16033 , 16384 , 16743 , 17109 , 17484 , 17867 , 18258 , 18658 , 19066 , 19484&lt;br /&gt;
  dw 19911 , 20347 , 20792 , 21247 , 21713 , 22188 , 22674 , 23170 , 23678 , 24196&lt;br /&gt;
  dw 24726 , 25268 , 25821 , 26386 , 26964 , 27554 , 28158 , 28774 , 29404 , 30048&lt;br /&gt;
  dw 30706 , 31379 , 32066 , 32768 , 33485 , 34219 , 34968 , 35734 , 36516 , 37316&lt;br /&gt;
  dw 38133 , 38968 , 39821 , 40693 , 41584 , 42495 , 43425 , 44376 , 45348 , 46341&lt;br /&gt;
  dw 47356 , 48393 , 49452 , 50535 , 51642 , 52772 , 53928 , 55109 , 56316 , 57549&lt;br /&gt;
  dw  58809 , 60097 , 61413 , 62757&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Faster, accurate 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
I'm currently working on a new routine, based on a routine by Kirk Meyer [http://www.ticalc.org/pub/86/asm/source/routines/vfmult.asm] which uses nibble multiplication tables.&lt;br /&gt;
&lt;br /&gt;
I have a working, tested version which uses 16K of tables and can perform multiplication in 20&amp;amp;mu;s.&lt;br /&gt;
&lt;br /&gt;
The code to produce the tables is below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp1&lt;br /&gt;
ld a,l&lt;br /&gt;
rla&lt;br /&gt;
and #1e&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp1&lt;br /&gt;
inc h&lt;br /&gt;
.makelp2&lt;br /&gt;
ld a,l&lt;br /&gt;
rra:rra:rra&lt;br /&gt;
and #1e&lt;br /&gt;
jr z,usez&lt;br /&gt;
add restab2 - restab / 256 - 2&lt;br /&gt;
.usez&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp2&lt;br /&gt;
inc h			; restab&lt;br /&gt;
.makelp3&lt;br /&gt;
ld a,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
add l&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,0&lt;br /&gt;
adc d&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h:dec h:dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256 - 2&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
ld b,h&lt;br /&gt;
ld c,l&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp4&lt;br /&gt;
ld e,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
dec h&lt;br /&gt;
ex de,hl&lt;br /&gt;
add hl,hl:add hl,hl:add hl,hl:add hl,hl&lt;br /&gt;
ex de,hl&lt;br /&gt;
ld a,e&lt;br /&gt;
ld (bc),a&lt;br /&gt;
inc b&lt;br /&gt;
ld a,d&lt;br /&gt;
ld (bc),a&lt;br /&gt;
dec b&lt;br /&gt;
inc l&lt;br /&gt;
inc c&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
.restab2&lt;br /&gt;
ds 512 * 15&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code to perform the multiplication (DE = L * C):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ld h,hltab1 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
inc h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(bc)		; 10&lt;br /&gt;
add (hl)		; 12&lt;br /&gt;
ld e,a			; 13&lt;br /&gt;
inc b			; 14&lt;br /&gt;
inc h			; 15&lt;br /&gt;
ld a,(bc)		; 17&lt;br /&gt;
adc (hl)		; 19&lt;br /&gt;
ld d,a			; 20&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
16K is a lot of memory to use for tables, but I'm working on a way to reduce this to 8K while maintaining similar performance (around 26&amp;amp;mu;s). The idea is rather than using tables for the low and high nibbles, use tables for alternate bits. So there would be 16 tables for the values #00, #01, #04, #05, #10, #11, #14, #15, #40, #41, #44, #45, #50, #51, #54, #55. The values can be shifted by 1 (rather than 4) to give values for the alternate bits using a simple ADD HL,HL.&lt;br /&gt;
&lt;br /&gt;
This routine should be easy to adapt to a 16bit * 8bit unsigned multiplication or even a 16bit * 16bit, using simple additions.&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 03:58, 8 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
Ok, here is the new 8K routine, first the routine to build the tables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp5&lt;br /&gt;
ld a,l&lt;br /&gt;
ld bc,0&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
ld a,b&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,c&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp5&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp6&lt;br /&gt;
ld (hl),l&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp6&lt;br /&gt;
inc h:inc h&lt;br /&gt;
ld b,2&lt;br /&gt;
.makelp8&lt;br /&gt;
push bc&lt;br /&gt;
xor a&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
.makelp7&lt;br /&gt;
push hl&lt;br /&gt;
push af&lt;br /&gt;
call mulLbyA&lt;br /&gt;
ex de,hl&lt;br /&gt;
pop af&lt;br /&gt;
pop hl&lt;br /&gt;
ld (hl),e&lt;br /&gt;
inc h&lt;br /&gt;
ld (hl),d&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp7&lt;br /&gt;
inc h:inc h&lt;br /&gt;
pop bc&lt;br /&gt;
inc b&lt;br /&gt;
bit 4,b&lt;br /&gt;
jr z,makelp8&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
.mulLbyA	; MAX times	; MIN times&lt;br /&gt;
ld e,l		; 1		; 1&lt;br /&gt;
ld d,0		; 3		; 3&lt;br /&gt;
add a		; 4		; 4&lt;br /&gt;
ld h,a		; 5		; 5&lt;br /&gt;
jr c,ncad0	; 8		; 8&lt;br /&gt;
ld l,d		&lt;br /&gt;
.ncad0&lt;br /&gt;
add hl,hl	; 11		; 11&lt;br /&gt;
jr nc,ncad1	; 13		; 14&lt;br /&gt;
add hl,de	; 16&lt;br /&gt;
.ncad1&lt;br /&gt;
add hl,hl	; 19		; 17&lt;br /&gt;
jr nc,ncad2	; 21		; 20&lt;br /&gt;
add hl,de	; 24&lt;br /&gt;
.ncad2&lt;br /&gt;
add hl,hl	; 27		; 23&lt;br /&gt;
jr nc,ncad3	; 29		; 26&lt;br /&gt;
add hl,de	; 32&lt;br /&gt;
.ncad3&lt;br /&gt;
add hl,hl	; 35		; 29&lt;br /&gt;
jr nc,ncad4	; 37		; 32&lt;br /&gt;
add hl,de	; 40&lt;br /&gt;
.ncad4&lt;br /&gt;
add hl,hl	; 43		; 35&lt;br /&gt;
jr nc,ncad5	; 45		; 38&lt;br /&gt;
add hl,de	; 48&lt;br /&gt;
.ncad5&lt;br /&gt;
add hl,hl	; 51		; 41&lt;br /&gt;
jr nc,ncad6	; 53		; 44&lt;br /&gt;
add hl,de	; 56&lt;br /&gt;
.ncad6&lt;br /&gt;
add hl,hl	; 59		; 47&lt;br /&gt;
ld a,h		; 60		; 48&lt;br /&gt;
ret nc		; 61		; 50?&lt;br /&gt;
add hl,de	; 64&lt;br /&gt;
ld a,h		; 65&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the routine to do the multiplication:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.umultCL		; Using 8 bit only (25us - DE = L * C)&lt;br /&gt;
ld h,hltab2 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
dec h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(hl)		; 10&lt;br /&gt;
add a			; 11&lt;br /&gt;
inc h			; 12&lt;br /&gt;
ld d,(hl)		; 14&lt;br /&gt;
rl d			; 16&lt;br /&gt;
ld h,b			; 17&lt;br /&gt;
add (hl)		; 19&lt;br /&gt;
ld e,a			; 20&lt;br /&gt;
inc h			; 21&lt;br /&gt;
ld a,(hl)		; 23&lt;br /&gt;
adc d			; 24&lt;br /&gt;
ld d,a			; 25&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Very fast 8bit * 8bit Unsigned with only 1K of tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input''': B = Multiplier, C = Multiplicant&lt;br /&gt;
&lt;br /&gt;
'''Output''': DE = Product&lt;br /&gt;
&lt;br /&gt;
'''Clocks''': 104-112 (108 on average)&lt;br /&gt;
&lt;br /&gt;
'''Size''': 24 bytes of code and 1024 bytes for the tables&lt;br /&gt;
&lt;br /&gt;
Here's a new routine I've developed which uses the formula ab = ((a + b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - (a - b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) / 4. It's based on a routine for the 6502 by Stephen Judd in a C= Hacking article. Because of differences between the way the 6502 does register indexing it was quite difficult to actually get this working, but it's a great compromise between speed and space since it only uses 1K of tables (as opposed to the 16K or 8K table routines above), and can still manage to do the job in a maximum of 28 microseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Firstly, once again, we need some code to generate the tables. These tables contain values for&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;/4 for 9 bit values of x, with the LSB when bit 8 is zero first followed by the MSB.&lt;br /&gt;
&amp;lt;pre&amp;gt;.gen_sq4&lt;br /&gt;
	xor a&lt;br /&gt;
	ld de,umul_tab + #1ff&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	ld h,d&lt;br /&gt;
	ld l,e&lt;br /&gt;
	inc e&lt;br /&gt;
	ld c,e&lt;br /&gt;
	ld b,2&lt;br /&gt;
&lt;br /&gt;
	.sq4_lp&lt;br /&gt;
	ld a,b&lt;br /&gt;
	cp 2&lt;br /&gt;
	ld a,e&lt;br /&gt;
	rra&lt;br /&gt;
	add (hl)&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	inc h&lt;br /&gt;
	inc d&lt;br /&gt;
	ld a,(hl)&lt;br /&gt;
	adc c&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld h,d&lt;br /&gt;
	inc l&lt;br /&gt;
	inc e&lt;br /&gt;
	jr nz,sq4_lp&lt;br /&gt;
	inc d&lt;br /&gt;
	inc d&lt;br /&gt;
	djnz sq4_lp&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
align #100&lt;br /&gt;
.umul_tab ds #400&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now for the actual multiply routine:&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', L = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ld h,umul_tab_lo / #100	; 2&lt;br /&gt;
	ld b,h			; 3&lt;br /&gt;
	add l			; 4&lt;br /&gt;
	ld c,a			; 5&lt;br /&gt;
	jr nc,@noovf		; 7&lt;br /&gt;
	inc b			; 8&lt;br /&gt;
	inc b			; 9&lt;br /&gt;
.@noovf&lt;br /&gt;
	sub l			; 10&lt;br /&gt;
	sub l			; 11&lt;br /&gt;
	jr nc,@noneg		; 13&lt;br /&gt;
	neg			; 15&lt;br /&gt;
.@noneg&lt;br /&gt;
	ld l,a			; 16&lt;br /&gt;
	ld a,(bc)		; 18&lt;br /&gt;
	sub (hl)		; 20&lt;br /&gt;
	ld e,a			; 21&lt;br /&gt;
	inc b			; 22&lt;br /&gt;
	inc h			; 23&lt;br /&gt;
	ld a,(bc)		; 25&lt;br /&gt;
	sbc (hl)		; 27&lt;br /&gt;
	ld d,a			; 28&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This code could easily be converted to a macro as it's only 24 bytes. I've tried to optimize it further but with no luck!&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 06:25, 4 April 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== 16bit * 16bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' BC = ''Multiplier'', DE = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A,HL = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;ld ix,0&lt;br /&gt;
 ld hl,0&lt;br /&gt;
.mul24b1:&lt;br /&gt;
 ld a,c&lt;br /&gt;
 or b&lt;br /&gt;
 jr z,mul24b3&lt;br /&gt;
 srl b&lt;br /&gt;
 rr c&lt;br /&gt;
 jr nc,mul24b2&lt;br /&gt;
 add ix,de&lt;br /&gt;
 ld a,h&lt;br /&gt;
 adc l&lt;br /&gt;
 ld h,a&lt;br /&gt;
.mul24b2:&lt;br /&gt;
 sla e&lt;br /&gt;
 rl d&lt;br /&gt;
 rl l&lt;br /&gt;
 jr mul24b1:&lt;br /&gt;
.mul24b3:&lt;br /&gt;
 ld a,h&lt;br /&gt;
 db #dd:ld e,l&lt;br /&gt;
 db #dd:ld d,h&lt;br /&gt;
 ex de,hl&lt;br /&gt;
 ret&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://map.tni.nl/articles/mult_div_shifts.php Multiplications and divisions on the MSX Assembly Page]&lt;br /&gt;
* [http://www.mccw.hetlab.tk/92/Multiplication/en.html &amp;quot;Multiplication on a Z80&amp;quot; ( MSX Computer &amp;amp; Club Webmagazine)]&lt;br /&gt;
* [http://www.andreadrian.de/oldcpu/Z80_number_cruncher.html The Z80 number cruncher (Andre Adrian)] (16/32bit multiplication, addition, right shift)&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94462</id>
		<title>Programming:Integer Multiplication</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94462"/>
				<updated>2015-10-24T07:08:15Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: /* Classic 16bit * 8bit Unsigned */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Classic 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' H = ''Multiplier'', E = ''Multiplicand'', L = 0, D = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 188-244 (216 on average) = 47-61 (54) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 33 bytes&lt;br /&gt;
&lt;br /&gt;
The additional clocks and bytes maybe required to set up D and L and for RET.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sla h  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+3&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
jr nc,$+3  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Classic 16bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', DE = ''Multiplicand'', HL = 0, C = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A:HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 212-300 (256 on average) = 53-75 (64) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 47 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add a,a  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+4&lt;br /&gt;
ld h,d&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
rla   ; ...&lt;br /&gt;
jr nc,$+4  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
adc a,c  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast 8bit * 8bit Unsigned (using log / antilog tables) ==&lt;br /&gt;
&lt;br /&gt;
The original routine was written by Jeff Frohwein for the Nintendo Gameboy. You can find it on [http://www.devrs.com/gb/files/logmult.txt Devrs.com].&lt;br /&gt;
&lt;br /&gt;
Because of the usage of log / antilog tables this routine is less accurate, but very fast. It takes advantage of the fact that if you take the log of two numbers, add the results and then take the antilog of the total you have done the equivalent of multiplying the two numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 x^a * x^b = x^(a+b)&lt;br /&gt;
&lt;br /&gt;
 a * b = x^(logx(a) + logx(b))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Input:''' B = ''Multiplier'', C = ''Multiplicant''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''Clocks:''' 124&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 1024 bytes (768 bytes for the tables)&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' It is VERY approximate routine, e.g., 0*7=7, 1*28=27, 10*81=790, 100*100=9742, ...&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FastMult:&lt;br /&gt;
  ld      l,c&lt;br /&gt;
  ld      h,&amp;amp;82&lt;br /&gt;
  ld      d,(hl)          ; d = 32 * log_2(c)&lt;br /&gt;
  &lt;br /&gt;
  ld      l,b&lt;br /&gt;
  ld      a,(hl)          ; a = 32 * log_2(b)&lt;br /&gt;
  &lt;br /&gt;
  add     a,d&lt;br /&gt;
  ld      l,a&lt;br /&gt;
  ld      a,0&lt;br /&gt;
  adc     a,0&lt;br /&gt;
  ld      h,a             ; hl = d + a&lt;br /&gt;
  &lt;br /&gt;
  add     hl,hl&lt;br /&gt;
  set     2,h             ; hl = hl + $0400&lt;br /&gt;
  set     7,h             ; hl = hl + &amp;amp;8000&lt;br /&gt;
  &lt;br /&gt;
  ld      e,(hl)&lt;br /&gt;
  inc     hl&lt;br /&gt;
  ld      d,(hl)          ; de = 2^((hl)/32)&lt;br /&gt;
  &lt;br /&gt;
  ret&lt;br /&gt;
&lt;br /&gt;
; 32*Log_2(x) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 TO 255&lt;br /&gt;
;     C=4 &lt;br /&gt;
;     B=2&lt;br /&gt;
;     FOR Z=1 TO 10&lt;br /&gt;
;       IF (2^C) &amp;gt; A THEN C=C-B ELSE C=C+B&lt;br /&gt;
;       B=B/2&lt;br /&gt;
;     NEXT Z&lt;br /&gt;
;     PRINT INT(C*32);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8200&lt;br /&gt;
&lt;br /&gt;
logtable:&lt;br /&gt;
  db 0 , 0 , 32 , 50 , 64 , 74 , 82 , 89 , 96 , 101 , 106 , 110 , 114 , 118 , 121&lt;br /&gt;
  db 125 , 128 , 130 , 133 , 135 , 138 , 140 , 142 , 144 , 146 , 148 , 150 , 152&lt;br /&gt;
  db 153 , 155 , 157 , 158 , 160 , 161 , 162 , 164 , 165 , 166 , 167 , 169 , 170&lt;br /&gt;
  db 171 , 172 , 173 , 174 , 175 , 176 , 177 , 178 , 179 , 180 , 181 , 182 , 183&lt;br /&gt;
  db 184 , 185 , 185 , 186 , 187 , 188 , 189 , 189 , 190 , 191 , 192 , 192 , 193&lt;br /&gt;
  db 194 , 194 , 195 , 196 , 196 , 197 , 198 , 198 , 199 , 199 , 200 , 201 , 201&lt;br /&gt;
  db 202 , 202 , 203 , 204 , 204 , 205 , 205 , 206 , 206 , 207 , 207 , 208 , 208&lt;br /&gt;
  db 209 , 209 , 210 , 210 , 211 , 211 , 212 , 212 , 213 , 213 , 213 , 214 , 214&lt;br /&gt;
  db 215 , 215 , 216 , 216 , 217 , 217 , 217 , 218 , 218 , 219 , 219 , 219 , 220&lt;br /&gt;
  db 220 , 221 , 221 , 221 , 222 , 222 , 222 , 223 , 223 , 224 , 224 , 224 , 225&lt;br /&gt;
  db 225 , 225 , 226 , 226 , 226 , 227 , 227 , 227 , 228 , 228 , 228 , 229 , 229&lt;br /&gt;
  db 229 , 230 , 230 , 230 , 231 , 231 , 231 , 231 , 232 , 232 , 232 , 233 , 233&lt;br /&gt;
  db 233 , 234 , 234 , 234 , 234 , 235 , 235 , 235 , 236 , 236 , 236 , 236 , 237&lt;br /&gt;
  db 237 , 237 , 237 , 238 , 238 , 238 , 238 , 239 , 239 , 239 , 239 , 240 , 240&lt;br /&gt;
  db 240 , 241 , 241 , 241 , 241 , 241 , 242 , 242 , 242 , 242 , 243 , 243 , 243&lt;br /&gt;
  db 243 , 244 , 244 , 244 , 244 , 245 , 245 , 245 , 245 , 245 , 246 , 246 , 246&lt;br /&gt;
  db 246 , 247 , 247 , 247 , 247 , 247 , 248 , 248 , 248 , 248 , 249 , 249 , 249&lt;br /&gt;
  db 249 , 249 , 250 , 250 , 250 , 250 , 250 , 251 , 251 , 251 , 251 , 251 , 252&lt;br /&gt;
  db 252 , 252 , 252 , 252 , 253 , 253 , 253 , 253 , 253 , 253 , 254 , 254 , 254&lt;br /&gt;
  db 254 , 254 , 255 , 255 , 255 , 255 , 255&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; AntiLog 2^(x/32) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 to 510&lt;br /&gt;
;   PRINT INT(2^(A/32)+.5);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8400&lt;br /&gt;
&lt;br /&gt;
antilog:&lt;br /&gt;
  dw 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 , 4&lt;br /&gt;
  dw 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 6&lt;br /&gt;
  dw 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 8 , 9&lt;br /&gt;
  dw 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , 12 , 12 , 12&lt;br /&gt;
  dw 13 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17&lt;br /&gt;
  dw 18 , 18 , 19 , 19 , 19 , 20 , 20 , 21 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25&lt;br /&gt;
  dw 25 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , 30 , 31 , 31 , 32 , 33 , 33 , 34 , 35&lt;br /&gt;
  dw 36 , 36 , 37 , 38 , 39 , 40 , 41 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49&lt;br /&gt;
  dw 50 , 52 , 53 , 54 , 55 , 56 , 57 , 59 , 60 , 61 , 63 , 64 , 65 , 67 , 68 , 70&lt;br /&gt;
  dw 71 , 73 , 74 , 76 , 78 , 79 , 81 , 83 , 85 , 87 , 89 , 91 , 92 , 95 , 97 , 99&lt;br /&gt;
  dw 101 , 103 , 105 , 108 , 110 , 112 , 115 , 117 , 120 , 123 , 125 , 128 , 131&lt;br /&gt;
  dw 134 , 137 , 140 , 143 , 146 , 149 , 152 , 156 , 159 , 162 , 166 , 170 , 173&lt;br /&gt;
  dw 177 , 181 , 185 , 189 , 193 , 197 , 202 , 206 , 211 , 215 , 220 , 225 , 230&lt;br /&gt;
  dw 235 , 240 , 245 , 251 , 256 , 262 , 267 , 273 , 279 , 285 , 292 , 298 , 304&lt;br /&gt;
  dw 311 , 318 , 325 , 332 , 339 , 347 , 354 , 362 , 370 , 378 , 386 , 395 , 403&lt;br /&gt;
  dw 412 , 421 , 431 , 440 , 450 , 459 , 470 , 480 , 490 , 501 , 512 , 523 , 535&lt;br /&gt;
  dw 546 , 558 , 571 , 583 , 596 , 609 , 622 , 636 , 650 , 664 , 679 , 693 , 709&lt;br /&gt;
  dw 724 , 740 , 756 , 773 , 790 , 807 , 825 , 843 , 861 , 880 , 899 , 919 , 939&lt;br /&gt;
  dw 960 , 981 , 1002 , 1024 , 1046 , 1069 , 1093 , 1117 , 1141 , 1166 , 1192&lt;br /&gt;
  dw 1218 , 1244 , 1272 , 1300 , 1328 , 1357 , 1387 , 1417 , 1448 , 1480 , 1512&lt;br /&gt;
  dw 1545 , 1579 , 1614 , 1649 , 1685 , 1722 , 1760 , 1798 , 1838 , 1878 , 1919&lt;br /&gt;
  dw 1961 , 2004 , 2048 , 2093 , 2139 , 2186 , 2233 , 2282 , 2332 , 2383 , 2435&lt;br /&gt;
  dw 2489 , 2543 , 2599 , 2656 , 2714 , 2774 , 2834 , 2896 , 2960 , 3025 , 3091&lt;br /&gt;
  dw 3158 , 3228 , 3298 , 3371 , 3444 , 3520 , 3597 , 3676 , 3756 , 3838 , 3922&lt;br /&gt;
  dw 4008 , 4096 , 4186 , 4277 , 4371 , 4467 , 4565 , 4664 , 4767 , 4871 , 4978&lt;br /&gt;
  dw 5087 , 5198 , 5312 , 5428 , 5547 , 5668 , 5793 , 5919 , 6049 , 6182 , 6317&lt;br /&gt;
  dw 6455 , 6597 , 6741 , 6889 , 7039 , 7194 , 7351 , 7512 , 7677 , 7845 , 8016&lt;br /&gt;
  dw 8192 , 8371 , 8555 , 8742 , 8933 , 9129 , 9329 , 9533 , 9742 , 9955 , 10173&lt;br /&gt;
  dw 10396 , 10624 , 10856 , 11094 , 11337 , 11585 , 11839 , 12098 , 12363 , 12634&lt;br /&gt;
  dw 12910 , 13193 , 13482 , 13777 , 14079 , 14387 , 14702 , 15024 , 15353 , 15689&lt;br /&gt;
  dw 16033 , 16384 , 16743 , 17109 , 17484 , 17867 , 18258 , 18658 , 19066 , 19484&lt;br /&gt;
  dw 19911 , 20347 , 20792 , 21247 , 21713 , 22188 , 22674 , 23170 , 23678 , 24196&lt;br /&gt;
  dw 24726 , 25268 , 25821 , 26386 , 26964 , 27554 , 28158 , 28774 , 29404 , 30048&lt;br /&gt;
  dw 30706 , 31379 , 32066 , 32768 , 33485 , 34219 , 34968 , 35734 , 36516 , 37316&lt;br /&gt;
  dw 38133 , 38968 , 39821 , 40693 , 41584 , 42495 , 43425 , 44376 , 45348 , 46341&lt;br /&gt;
  dw 47356 , 48393 , 49452 , 50535 , 51642 , 52772 , 53928 , 55109 , 56316 , 57549&lt;br /&gt;
  dw  58809 , 60097 , 61413 , 62757&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Faster, accurate 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
I'm currently working on a new routine, based on a routine by Kirk Meyer [http://www.ticalc.org/pub/86/asm/source/routines/vfmult.asm] which uses nibble multiplication tables.&lt;br /&gt;
&lt;br /&gt;
I have a working, tested version which uses 16K of tables and can perform multiplication in 20&amp;amp;mu;s.&lt;br /&gt;
&lt;br /&gt;
The code to produce the tables is below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp1&lt;br /&gt;
ld a,l&lt;br /&gt;
rla&lt;br /&gt;
and #1e&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp1&lt;br /&gt;
inc h&lt;br /&gt;
.makelp2&lt;br /&gt;
ld a,l&lt;br /&gt;
rra:rra:rra&lt;br /&gt;
and #1e&lt;br /&gt;
jr z,usez&lt;br /&gt;
add restab2 - restab / 256 - 2&lt;br /&gt;
.usez&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp2&lt;br /&gt;
inc h			; restab&lt;br /&gt;
.makelp3&lt;br /&gt;
ld a,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
add l&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,0&lt;br /&gt;
adc d&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h:dec h:dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256 - 2&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
ld b,h&lt;br /&gt;
ld c,l&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp4&lt;br /&gt;
ld e,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
dec h&lt;br /&gt;
ex de,hl&lt;br /&gt;
add hl,hl:add hl,hl:add hl,hl:add hl,hl&lt;br /&gt;
ex de,hl&lt;br /&gt;
ld a,e&lt;br /&gt;
ld (bc),a&lt;br /&gt;
inc b&lt;br /&gt;
ld a,d&lt;br /&gt;
ld (bc),a&lt;br /&gt;
dec b&lt;br /&gt;
inc l&lt;br /&gt;
inc c&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
.restab2&lt;br /&gt;
ds 512 * 15&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code to perform the multiplication (DE = L * C):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ld h,hltab1 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
inc h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(bc)		; 10&lt;br /&gt;
add (hl)		; 12&lt;br /&gt;
ld e,a			; 13&lt;br /&gt;
inc b			; 14&lt;br /&gt;
inc h			; 15&lt;br /&gt;
ld a,(bc)		; 17&lt;br /&gt;
adc (hl)		; 19&lt;br /&gt;
ld d,a			; 20&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
16K is a lot of memory to use for tables, but I'm working on a way to reduce this to 8K while maintaining similar performance (around 26&amp;amp;mu;s). The idea is rather than using tables for the low and high nibbles, use tables for alternate bits. So there would be 16 tables for the values #00, #01, #04, #05, #10, #11, #14, #15, #40, #41, #44, #45, #50, #51, #54, #55. The values can be shifted by 1 (rather than 4) to give values for the alternate bits using a simple ADD HL,HL.&lt;br /&gt;
&lt;br /&gt;
This routine should be easy to adapt to a 16bit * 8bit unsigned multiplication or even a 16bit * 16bit, using simple additions.&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 03:58, 8 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
Ok, here is the new 8K routine, first the routine to build the tables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp5&lt;br /&gt;
ld a,l&lt;br /&gt;
ld bc,0&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
ld a,b&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,c&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp5&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp6&lt;br /&gt;
ld (hl),l&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp6&lt;br /&gt;
inc h:inc h&lt;br /&gt;
ld b,2&lt;br /&gt;
.makelp8&lt;br /&gt;
push bc&lt;br /&gt;
xor a&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
.makelp7&lt;br /&gt;
push hl&lt;br /&gt;
push af&lt;br /&gt;
call mulLbyA&lt;br /&gt;
ex de,hl&lt;br /&gt;
pop af&lt;br /&gt;
pop hl&lt;br /&gt;
ld (hl),e&lt;br /&gt;
inc h&lt;br /&gt;
ld (hl),d&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp7&lt;br /&gt;
inc h:inc h&lt;br /&gt;
pop bc&lt;br /&gt;
inc b&lt;br /&gt;
bit 4,b&lt;br /&gt;
jr z,makelp8&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
.mulLbyA	; MAX times	; MIN times&lt;br /&gt;
ld e,l		; 1		; 1&lt;br /&gt;
ld d,0		; 3		; 3&lt;br /&gt;
add a		; 4		; 4&lt;br /&gt;
ld h,a		; 5		; 5&lt;br /&gt;
jr c,ncad0	; 8		; 8&lt;br /&gt;
ld l,d		&lt;br /&gt;
.ncad0&lt;br /&gt;
add hl,hl	; 11		; 11&lt;br /&gt;
jr nc,ncad1	; 13		; 14&lt;br /&gt;
add hl,de	; 16&lt;br /&gt;
.ncad1&lt;br /&gt;
add hl,hl	; 19		; 17&lt;br /&gt;
jr nc,ncad2	; 21		; 20&lt;br /&gt;
add hl,de	; 24&lt;br /&gt;
.ncad2&lt;br /&gt;
add hl,hl	; 27		; 23&lt;br /&gt;
jr nc,ncad3	; 29		; 26&lt;br /&gt;
add hl,de	; 32&lt;br /&gt;
.ncad3&lt;br /&gt;
add hl,hl	; 35		; 29&lt;br /&gt;
jr nc,ncad4	; 37		; 32&lt;br /&gt;
add hl,de	; 40&lt;br /&gt;
.ncad4&lt;br /&gt;
add hl,hl	; 43		; 35&lt;br /&gt;
jr nc,ncad5	; 45		; 38&lt;br /&gt;
add hl,de	; 48&lt;br /&gt;
.ncad5&lt;br /&gt;
add hl,hl	; 51		; 41&lt;br /&gt;
jr nc,ncad6	; 53		; 44&lt;br /&gt;
add hl,de	; 56&lt;br /&gt;
.ncad6&lt;br /&gt;
add hl,hl	; 59		; 47&lt;br /&gt;
ld a,h		; 60		; 48&lt;br /&gt;
ret nc		; 61		; 50?&lt;br /&gt;
add hl,de	; 64&lt;br /&gt;
ld a,h		; 65&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the routine to do the multiplication:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.umultCL		; Using 8 bit only (25us - DE = L * C)&lt;br /&gt;
ld h,hltab2 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
dec h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(hl)		; 10&lt;br /&gt;
add a			; 11&lt;br /&gt;
inc h			; 12&lt;br /&gt;
ld d,(hl)		; 14&lt;br /&gt;
rl d			; 16&lt;br /&gt;
ld h,b			; 17&lt;br /&gt;
add (hl)		; 19&lt;br /&gt;
ld e,a			; 20&lt;br /&gt;
inc h			; 21&lt;br /&gt;
ld a,(hl)		; 23&lt;br /&gt;
adc d			; 24&lt;br /&gt;
ld d,a			; 25&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Very fast 8bit * 8bit Unsigned with only 1K of tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input''': B = Multiplier, C = Multiplicant&lt;br /&gt;
&lt;br /&gt;
'''Output''': DE = Product&lt;br /&gt;
&lt;br /&gt;
'''Clocks''': 104-112 (108 on average)&lt;br /&gt;
&lt;br /&gt;
'''Size''': 24 bytes of code and 1024 bytes for the tables&lt;br /&gt;
&lt;br /&gt;
Here's a new routine I've developed which uses the formula ab = ((a + b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - (a - b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) / 4. It's based on a routine for the 6502 by Stephen Judd in a C= Hacking article. Because of differences between the way the 6502 does register indexing it was quite difficult to actually get this working, but it's a great compromise between speed and space since it only uses 1K of tables (as opposed to the 16K or 8K table routines above), and can still manage to do the job in a maximum of 28 microseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Firstly, once again, we need some code to generate the tables. These tables contain values for&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;/4 for 9 bit values of x, with the LSB when bit 8 is zero first followed by the MSB.&lt;br /&gt;
&amp;lt;pre&amp;gt;.gen_sq4&lt;br /&gt;
	xor a&lt;br /&gt;
	ld de,umul_tab + #1ff&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	ld h,d&lt;br /&gt;
	ld l,e&lt;br /&gt;
	inc e&lt;br /&gt;
	ld c,e&lt;br /&gt;
	ld b,2&lt;br /&gt;
&lt;br /&gt;
	.sq4_lp&lt;br /&gt;
	ld a,b&lt;br /&gt;
	cp 2&lt;br /&gt;
	ld a,e&lt;br /&gt;
	rra&lt;br /&gt;
	add (hl)&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	inc h&lt;br /&gt;
	inc d&lt;br /&gt;
	ld a,(hl)&lt;br /&gt;
	adc c&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld h,d&lt;br /&gt;
	inc l&lt;br /&gt;
	inc e&lt;br /&gt;
	jr nz,sq4_lp&lt;br /&gt;
	inc d&lt;br /&gt;
	inc d&lt;br /&gt;
	djnz sq4_lp&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
align #100&lt;br /&gt;
.umul_tab ds #400&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now for the actual multiply routine:&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', L = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ld h,umul_tab_lo / #100	; 2&lt;br /&gt;
	ld b,h			; 3&lt;br /&gt;
	add l			; 4&lt;br /&gt;
	ld c,a			; 5&lt;br /&gt;
	jr nc,@noovf		; 7&lt;br /&gt;
	inc b			; 8&lt;br /&gt;
	inc b			; 9&lt;br /&gt;
.@noovf&lt;br /&gt;
	sub l			; 10&lt;br /&gt;
	sub l			; 11&lt;br /&gt;
	jr nc,@noneg		; 13&lt;br /&gt;
	neg			; 15&lt;br /&gt;
.@noneg&lt;br /&gt;
	ld l,a			; 16&lt;br /&gt;
	ld a,(bc)		; 18&lt;br /&gt;
	sub (hl)		; 20&lt;br /&gt;
	ld e,a			; 21&lt;br /&gt;
	inc b			; 22&lt;br /&gt;
	inc h			; 23&lt;br /&gt;
	ld a,(bc)		; 25&lt;br /&gt;
	sbc (hl)		; 27&lt;br /&gt;
	ld d,a			; 28&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This code could easily be converted to a macro as it's only 24 bytes. I've tried to optimize it further but with no luck!&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 06:25, 4 April 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== 16bit * 16bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' BC = ''Multiplier'', DE = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A,HL = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;ld ix,0&lt;br /&gt;
 ld hl,0&lt;br /&gt;
.mul24b1:&lt;br /&gt;
 ld a,c&lt;br /&gt;
 or b&lt;br /&gt;
 jr z,mul24b3&lt;br /&gt;
 srl b&lt;br /&gt;
 rr c&lt;br /&gt;
 jr nc,mul24b2&lt;br /&gt;
 add ix,de&lt;br /&gt;
 ld a,h&lt;br /&gt;
 adc l&lt;br /&gt;
 ld h,a&lt;br /&gt;
.mul24b2:&lt;br /&gt;
 sla e&lt;br /&gt;
 rl d&lt;br /&gt;
 rl l&lt;br /&gt;
 jr mul24b1:&lt;br /&gt;
.mul24b3:&lt;br /&gt;
 ld a,h&lt;br /&gt;
 db #dd:ld e,l&lt;br /&gt;
 db #dd:ld d,h&lt;br /&gt;
 ex de,hl&lt;br /&gt;
 ret&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://map.tni.nl/articles/mult_div_shifts.php Multiplications and divisions on the MSX Assembly Page]&lt;br /&gt;
* [http://www.mccw.hetlab.tk/92/Multiplication/en.html &amp;quot;Multiplication on a Z80&amp;quot; ( MSX Computer &amp;amp; Club Webmagazine)]&lt;br /&gt;
* [http://www.andreadrian.de/oldcpu/Z80_number_cruncher.html The Z80 number cruncher (Andre Adrian)] (16/32bit multiplication, addition, right shift)&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94461</id>
		<title>Programming:Integer Multiplication</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94461"/>
				<updated>2015-10-24T07:06:47Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: added timing and size info&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Classic 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' H = ''Multiplier'', E = ''Multiplicand'', L = 0, D = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 188-244 (216 on average) = 47-61 (54) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 33 bytes&lt;br /&gt;
&lt;br /&gt;
The additional clocks and bytes maybe required to set up D and L and for RET.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sla h  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+3&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
jr nc,$+3  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Classic 16bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', DE = ''Multiplicand'', HL = 0, C = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A:HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 212-300 (256 on average) = 53-75 (64) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 46 bytes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add a,a  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+4&lt;br /&gt;
ld h,d&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
rla   ; ...&lt;br /&gt;
jr nc,$+4  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
adc a,c  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast 8bit * 8bit Unsigned (using log / antilog tables) ==&lt;br /&gt;
&lt;br /&gt;
The original routine was written by Jeff Frohwein for the Nintendo Gameboy. You can find it on [http://www.devrs.com/gb/files/logmult.txt Devrs.com].&lt;br /&gt;
&lt;br /&gt;
Because of the usage of log / antilog tables this routine is less accurate, but very fast. It takes advantage of the fact that if you take the log of two numbers, add the results and then take the antilog of the total you have done the equivalent of multiplying the two numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 x^a * x^b = x^(a+b)&lt;br /&gt;
&lt;br /&gt;
 a * b = x^(logx(a) + logx(b))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Input:''' B = ''Multiplier'', C = ''Multiplicant''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''Clocks:''' 124&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 1024 bytes (768 bytes for the tables)&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' It is VERY approximate routine, e.g., 0*7=7, 1*28=27, 10*81=790, 100*100=9742, ...&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FastMult:&lt;br /&gt;
  ld      l,c&lt;br /&gt;
  ld      h,&amp;amp;82&lt;br /&gt;
  ld      d,(hl)          ; d = 32 * log_2(c)&lt;br /&gt;
  &lt;br /&gt;
  ld      l,b&lt;br /&gt;
  ld      a,(hl)          ; a = 32 * log_2(b)&lt;br /&gt;
  &lt;br /&gt;
  add     a,d&lt;br /&gt;
  ld      l,a&lt;br /&gt;
  ld      a,0&lt;br /&gt;
  adc     a,0&lt;br /&gt;
  ld      h,a             ; hl = d + a&lt;br /&gt;
  &lt;br /&gt;
  add     hl,hl&lt;br /&gt;
  set     2,h             ; hl = hl + $0400&lt;br /&gt;
  set     7,h             ; hl = hl + &amp;amp;8000&lt;br /&gt;
  &lt;br /&gt;
  ld      e,(hl)&lt;br /&gt;
  inc     hl&lt;br /&gt;
  ld      d,(hl)          ; de = 2^((hl)/32)&lt;br /&gt;
  &lt;br /&gt;
  ret&lt;br /&gt;
&lt;br /&gt;
; 32*Log_2(x) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 TO 255&lt;br /&gt;
;     C=4 &lt;br /&gt;
;     B=2&lt;br /&gt;
;     FOR Z=1 TO 10&lt;br /&gt;
;       IF (2^C) &amp;gt; A THEN C=C-B ELSE C=C+B&lt;br /&gt;
;       B=B/2&lt;br /&gt;
;     NEXT Z&lt;br /&gt;
;     PRINT INT(C*32);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8200&lt;br /&gt;
&lt;br /&gt;
logtable:&lt;br /&gt;
  db 0 , 0 , 32 , 50 , 64 , 74 , 82 , 89 , 96 , 101 , 106 , 110 , 114 , 118 , 121&lt;br /&gt;
  db 125 , 128 , 130 , 133 , 135 , 138 , 140 , 142 , 144 , 146 , 148 , 150 , 152&lt;br /&gt;
  db 153 , 155 , 157 , 158 , 160 , 161 , 162 , 164 , 165 , 166 , 167 , 169 , 170&lt;br /&gt;
  db 171 , 172 , 173 , 174 , 175 , 176 , 177 , 178 , 179 , 180 , 181 , 182 , 183&lt;br /&gt;
  db 184 , 185 , 185 , 186 , 187 , 188 , 189 , 189 , 190 , 191 , 192 , 192 , 193&lt;br /&gt;
  db 194 , 194 , 195 , 196 , 196 , 197 , 198 , 198 , 199 , 199 , 200 , 201 , 201&lt;br /&gt;
  db 202 , 202 , 203 , 204 , 204 , 205 , 205 , 206 , 206 , 207 , 207 , 208 , 208&lt;br /&gt;
  db 209 , 209 , 210 , 210 , 211 , 211 , 212 , 212 , 213 , 213 , 213 , 214 , 214&lt;br /&gt;
  db 215 , 215 , 216 , 216 , 217 , 217 , 217 , 218 , 218 , 219 , 219 , 219 , 220&lt;br /&gt;
  db 220 , 221 , 221 , 221 , 222 , 222 , 222 , 223 , 223 , 224 , 224 , 224 , 225&lt;br /&gt;
  db 225 , 225 , 226 , 226 , 226 , 227 , 227 , 227 , 228 , 228 , 228 , 229 , 229&lt;br /&gt;
  db 229 , 230 , 230 , 230 , 231 , 231 , 231 , 231 , 232 , 232 , 232 , 233 , 233&lt;br /&gt;
  db 233 , 234 , 234 , 234 , 234 , 235 , 235 , 235 , 236 , 236 , 236 , 236 , 237&lt;br /&gt;
  db 237 , 237 , 237 , 238 , 238 , 238 , 238 , 239 , 239 , 239 , 239 , 240 , 240&lt;br /&gt;
  db 240 , 241 , 241 , 241 , 241 , 241 , 242 , 242 , 242 , 242 , 243 , 243 , 243&lt;br /&gt;
  db 243 , 244 , 244 , 244 , 244 , 245 , 245 , 245 , 245 , 245 , 246 , 246 , 246&lt;br /&gt;
  db 246 , 247 , 247 , 247 , 247 , 247 , 248 , 248 , 248 , 248 , 249 , 249 , 249&lt;br /&gt;
  db 249 , 249 , 250 , 250 , 250 , 250 , 250 , 251 , 251 , 251 , 251 , 251 , 252&lt;br /&gt;
  db 252 , 252 , 252 , 252 , 253 , 253 , 253 , 253 , 253 , 253 , 254 , 254 , 254&lt;br /&gt;
  db 254 , 254 , 255 , 255 , 255 , 255 , 255&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; AntiLog 2^(x/32) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 to 510&lt;br /&gt;
;   PRINT INT(2^(A/32)+.5);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8400&lt;br /&gt;
&lt;br /&gt;
antilog:&lt;br /&gt;
  dw 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 , 4&lt;br /&gt;
  dw 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 6&lt;br /&gt;
  dw 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 8 , 9&lt;br /&gt;
  dw 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , 12 , 12 , 12&lt;br /&gt;
  dw 13 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17&lt;br /&gt;
  dw 18 , 18 , 19 , 19 , 19 , 20 , 20 , 21 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25&lt;br /&gt;
  dw 25 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , 30 , 31 , 31 , 32 , 33 , 33 , 34 , 35&lt;br /&gt;
  dw 36 , 36 , 37 , 38 , 39 , 40 , 41 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49&lt;br /&gt;
  dw 50 , 52 , 53 , 54 , 55 , 56 , 57 , 59 , 60 , 61 , 63 , 64 , 65 , 67 , 68 , 70&lt;br /&gt;
  dw 71 , 73 , 74 , 76 , 78 , 79 , 81 , 83 , 85 , 87 , 89 , 91 , 92 , 95 , 97 , 99&lt;br /&gt;
  dw 101 , 103 , 105 , 108 , 110 , 112 , 115 , 117 , 120 , 123 , 125 , 128 , 131&lt;br /&gt;
  dw 134 , 137 , 140 , 143 , 146 , 149 , 152 , 156 , 159 , 162 , 166 , 170 , 173&lt;br /&gt;
  dw 177 , 181 , 185 , 189 , 193 , 197 , 202 , 206 , 211 , 215 , 220 , 225 , 230&lt;br /&gt;
  dw 235 , 240 , 245 , 251 , 256 , 262 , 267 , 273 , 279 , 285 , 292 , 298 , 304&lt;br /&gt;
  dw 311 , 318 , 325 , 332 , 339 , 347 , 354 , 362 , 370 , 378 , 386 , 395 , 403&lt;br /&gt;
  dw 412 , 421 , 431 , 440 , 450 , 459 , 470 , 480 , 490 , 501 , 512 , 523 , 535&lt;br /&gt;
  dw 546 , 558 , 571 , 583 , 596 , 609 , 622 , 636 , 650 , 664 , 679 , 693 , 709&lt;br /&gt;
  dw 724 , 740 , 756 , 773 , 790 , 807 , 825 , 843 , 861 , 880 , 899 , 919 , 939&lt;br /&gt;
  dw 960 , 981 , 1002 , 1024 , 1046 , 1069 , 1093 , 1117 , 1141 , 1166 , 1192&lt;br /&gt;
  dw 1218 , 1244 , 1272 , 1300 , 1328 , 1357 , 1387 , 1417 , 1448 , 1480 , 1512&lt;br /&gt;
  dw 1545 , 1579 , 1614 , 1649 , 1685 , 1722 , 1760 , 1798 , 1838 , 1878 , 1919&lt;br /&gt;
  dw 1961 , 2004 , 2048 , 2093 , 2139 , 2186 , 2233 , 2282 , 2332 , 2383 , 2435&lt;br /&gt;
  dw 2489 , 2543 , 2599 , 2656 , 2714 , 2774 , 2834 , 2896 , 2960 , 3025 , 3091&lt;br /&gt;
  dw 3158 , 3228 , 3298 , 3371 , 3444 , 3520 , 3597 , 3676 , 3756 , 3838 , 3922&lt;br /&gt;
  dw 4008 , 4096 , 4186 , 4277 , 4371 , 4467 , 4565 , 4664 , 4767 , 4871 , 4978&lt;br /&gt;
  dw 5087 , 5198 , 5312 , 5428 , 5547 , 5668 , 5793 , 5919 , 6049 , 6182 , 6317&lt;br /&gt;
  dw 6455 , 6597 , 6741 , 6889 , 7039 , 7194 , 7351 , 7512 , 7677 , 7845 , 8016&lt;br /&gt;
  dw 8192 , 8371 , 8555 , 8742 , 8933 , 9129 , 9329 , 9533 , 9742 , 9955 , 10173&lt;br /&gt;
  dw 10396 , 10624 , 10856 , 11094 , 11337 , 11585 , 11839 , 12098 , 12363 , 12634&lt;br /&gt;
  dw 12910 , 13193 , 13482 , 13777 , 14079 , 14387 , 14702 , 15024 , 15353 , 15689&lt;br /&gt;
  dw 16033 , 16384 , 16743 , 17109 , 17484 , 17867 , 18258 , 18658 , 19066 , 19484&lt;br /&gt;
  dw 19911 , 20347 , 20792 , 21247 , 21713 , 22188 , 22674 , 23170 , 23678 , 24196&lt;br /&gt;
  dw 24726 , 25268 , 25821 , 26386 , 26964 , 27554 , 28158 , 28774 , 29404 , 30048&lt;br /&gt;
  dw 30706 , 31379 , 32066 , 32768 , 33485 , 34219 , 34968 , 35734 , 36516 , 37316&lt;br /&gt;
  dw 38133 , 38968 , 39821 , 40693 , 41584 , 42495 , 43425 , 44376 , 45348 , 46341&lt;br /&gt;
  dw 47356 , 48393 , 49452 , 50535 , 51642 , 52772 , 53928 , 55109 , 56316 , 57549&lt;br /&gt;
  dw  58809 , 60097 , 61413 , 62757&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Faster, accurate 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
I'm currently working on a new routine, based on a routine by Kirk Meyer [http://www.ticalc.org/pub/86/asm/source/routines/vfmult.asm] which uses nibble multiplication tables.&lt;br /&gt;
&lt;br /&gt;
I have a working, tested version which uses 16K of tables and can perform multiplication in 20&amp;amp;mu;s.&lt;br /&gt;
&lt;br /&gt;
The code to produce the tables is below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp1&lt;br /&gt;
ld a,l&lt;br /&gt;
rla&lt;br /&gt;
and #1e&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp1&lt;br /&gt;
inc h&lt;br /&gt;
.makelp2&lt;br /&gt;
ld a,l&lt;br /&gt;
rra:rra:rra&lt;br /&gt;
and #1e&lt;br /&gt;
jr z,usez&lt;br /&gt;
add restab2 - restab / 256 - 2&lt;br /&gt;
.usez&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp2&lt;br /&gt;
inc h			; restab&lt;br /&gt;
.makelp3&lt;br /&gt;
ld a,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
add l&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,0&lt;br /&gt;
adc d&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h:dec h:dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256 - 2&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
ld b,h&lt;br /&gt;
ld c,l&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp4&lt;br /&gt;
ld e,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
dec h&lt;br /&gt;
ex de,hl&lt;br /&gt;
add hl,hl:add hl,hl:add hl,hl:add hl,hl&lt;br /&gt;
ex de,hl&lt;br /&gt;
ld a,e&lt;br /&gt;
ld (bc),a&lt;br /&gt;
inc b&lt;br /&gt;
ld a,d&lt;br /&gt;
ld (bc),a&lt;br /&gt;
dec b&lt;br /&gt;
inc l&lt;br /&gt;
inc c&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
.restab2&lt;br /&gt;
ds 512 * 15&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code to perform the multiplication (DE = L * C):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ld h,hltab1 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
inc h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(bc)		; 10&lt;br /&gt;
add (hl)		; 12&lt;br /&gt;
ld e,a			; 13&lt;br /&gt;
inc b			; 14&lt;br /&gt;
inc h			; 15&lt;br /&gt;
ld a,(bc)		; 17&lt;br /&gt;
adc (hl)		; 19&lt;br /&gt;
ld d,a			; 20&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
16K is a lot of memory to use for tables, but I'm working on a way to reduce this to 8K while maintaining similar performance (around 26&amp;amp;mu;s). The idea is rather than using tables for the low and high nibbles, use tables for alternate bits. So there would be 16 tables for the values #00, #01, #04, #05, #10, #11, #14, #15, #40, #41, #44, #45, #50, #51, #54, #55. The values can be shifted by 1 (rather than 4) to give values for the alternate bits using a simple ADD HL,HL.&lt;br /&gt;
&lt;br /&gt;
This routine should be easy to adapt to a 16bit * 8bit unsigned multiplication or even a 16bit * 16bit, using simple additions.&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 03:58, 8 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
Ok, here is the new 8K routine, first the routine to build the tables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp5&lt;br /&gt;
ld a,l&lt;br /&gt;
ld bc,0&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
ld a,b&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,c&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp5&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp6&lt;br /&gt;
ld (hl),l&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp6&lt;br /&gt;
inc h:inc h&lt;br /&gt;
ld b,2&lt;br /&gt;
.makelp8&lt;br /&gt;
push bc&lt;br /&gt;
xor a&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
.makelp7&lt;br /&gt;
push hl&lt;br /&gt;
push af&lt;br /&gt;
call mulLbyA&lt;br /&gt;
ex de,hl&lt;br /&gt;
pop af&lt;br /&gt;
pop hl&lt;br /&gt;
ld (hl),e&lt;br /&gt;
inc h&lt;br /&gt;
ld (hl),d&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp7&lt;br /&gt;
inc h:inc h&lt;br /&gt;
pop bc&lt;br /&gt;
inc b&lt;br /&gt;
bit 4,b&lt;br /&gt;
jr z,makelp8&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
.mulLbyA	; MAX times	; MIN times&lt;br /&gt;
ld e,l		; 1		; 1&lt;br /&gt;
ld d,0		; 3		; 3&lt;br /&gt;
add a		; 4		; 4&lt;br /&gt;
ld h,a		; 5		; 5&lt;br /&gt;
jr c,ncad0	; 8		; 8&lt;br /&gt;
ld l,d		&lt;br /&gt;
.ncad0&lt;br /&gt;
add hl,hl	; 11		; 11&lt;br /&gt;
jr nc,ncad1	; 13		; 14&lt;br /&gt;
add hl,de	; 16&lt;br /&gt;
.ncad1&lt;br /&gt;
add hl,hl	; 19		; 17&lt;br /&gt;
jr nc,ncad2	; 21		; 20&lt;br /&gt;
add hl,de	; 24&lt;br /&gt;
.ncad2&lt;br /&gt;
add hl,hl	; 27		; 23&lt;br /&gt;
jr nc,ncad3	; 29		; 26&lt;br /&gt;
add hl,de	; 32&lt;br /&gt;
.ncad3&lt;br /&gt;
add hl,hl	; 35		; 29&lt;br /&gt;
jr nc,ncad4	; 37		; 32&lt;br /&gt;
add hl,de	; 40&lt;br /&gt;
.ncad4&lt;br /&gt;
add hl,hl	; 43		; 35&lt;br /&gt;
jr nc,ncad5	; 45		; 38&lt;br /&gt;
add hl,de	; 48&lt;br /&gt;
.ncad5&lt;br /&gt;
add hl,hl	; 51		; 41&lt;br /&gt;
jr nc,ncad6	; 53		; 44&lt;br /&gt;
add hl,de	; 56&lt;br /&gt;
.ncad6&lt;br /&gt;
add hl,hl	; 59		; 47&lt;br /&gt;
ld a,h		; 60		; 48&lt;br /&gt;
ret nc		; 61		; 50?&lt;br /&gt;
add hl,de	; 64&lt;br /&gt;
ld a,h		; 65&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the routine to do the multiplication:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.umultCL		; Using 8 bit only (25us - DE = L * C)&lt;br /&gt;
ld h,hltab2 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
dec h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(hl)		; 10&lt;br /&gt;
add a			; 11&lt;br /&gt;
inc h			; 12&lt;br /&gt;
ld d,(hl)		; 14&lt;br /&gt;
rl d			; 16&lt;br /&gt;
ld h,b			; 17&lt;br /&gt;
add (hl)		; 19&lt;br /&gt;
ld e,a			; 20&lt;br /&gt;
inc h			; 21&lt;br /&gt;
ld a,(hl)		; 23&lt;br /&gt;
adc d			; 24&lt;br /&gt;
ld d,a			; 25&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Very fast 8bit * 8bit Unsigned with only 1K of tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input''': B = Multiplier, C = Multiplicant&lt;br /&gt;
&lt;br /&gt;
'''Output''': DE = Product&lt;br /&gt;
&lt;br /&gt;
'''Clocks''': 104-112 (108 on average)&lt;br /&gt;
&lt;br /&gt;
'''Size''': 24 bytes of code and 1024 bytes for the tables&lt;br /&gt;
&lt;br /&gt;
Here's a new routine I've developed which uses the formula ab = ((a + b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - (a - b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) / 4. It's based on a routine for the 6502 by Stephen Judd in a C= Hacking article. Because of differences between the way the 6502 does register indexing it was quite difficult to actually get this working, but it's a great compromise between speed and space since it only uses 1K of tables (as opposed to the 16K or 8K table routines above), and can still manage to do the job in a maximum of 28 microseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Firstly, once again, we need some code to generate the tables. These tables contain values for&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;/4 for 9 bit values of x, with the LSB when bit 8 is zero first followed by the MSB.&lt;br /&gt;
&amp;lt;pre&amp;gt;.gen_sq4&lt;br /&gt;
	xor a&lt;br /&gt;
	ld de,umul_tab + #1ff&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	ld h,d&lt;br /&gt;
	ld l,e&lt;br /&gt;
	inc e&lt;br /&gt;
	ld c,e&lt;br /&gt;
	ld b,2&lt;br /&gt;
&lt;br /&gt;
	.sq4_lp&lt;br /&gt;
	ld a,b&lt;br /&gt;
	cp 2&lt;br /&gt;
	ld a,e&lt;br /&gt;
	rra&lt;br /&gt;
	add (hl)&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	inc h&lt;br /&gt;
	inc d&lt;br /&gt;
	ld a,(hl)&lt;br /&gt;
	adc c&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld h,d&lt;br /&gt;
	inc l&lt;br /&gt;
	inc e&lt;br /&gt;
	jr nz,sq4_lp&lt;br /&gt;
	inc d&lt;br /&gt;
	inc d&lt;br /&gt;
	djnz sq4_lp&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
align #100&lt;br /&gt;
.umul_tab ds #400&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now for the actual multiply routine:&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', L = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ld h,umul_tab_lo / #100	; 2&lt;br /&gt;
	ld b,h			; 3&lt;br /&gt;
	add l			; 4&lt;br /&gt;
	ld c,a			; 5&lt;br /&gt;
	jr nc,@noovf		; 7&lt;br /&gt;
	inc b			; 8&lt;br /&gt;
	inc b			; 9&lt;br /&gt;
.@noovf&lt;br /&gt;
	sub l			; 10&lt;br /&gt;
	sub l			; 11&lt;br /&gt;
	jr nc,@noneg		; 13&lt;br /&gt;
	neg			; 15&lt;br /&gt;
.@noneg&lt;br /&gt;
	ld l,a			; 16&lt;br /&gt;
	ld a,(bc)		; 18&lt;br /&gt;
	sub (hl)		; 20&lt;br /&gt;
	ld e,a			; 21&lt;br /&gt;
	inc b			; 22&lt;br /&gt;
	inc h			; 23&lt;br /&gt;
	ld a,(bc)		; 25&lt;br /&gt;
	sbc (hl)		; 27&lt;br /&gt;
	ld d,a			; 28&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This code could easily be converted to a macro as it's only 24 bytes. I've tried to optimize it further but with no luck!&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 06:25, 4 April 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== 16bit * 16bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' BC = ''Multiplier'', DE = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A,HL = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;ld ix,0&lt;br /&gt;
 ld hl,0&lt;br /&gt;
.mul24b1:&lt;br /&gt;
 ld a,c&lt;br /&gt;
 or b&lt;br /&gt;
 jr z,mul24b3&lt;br /&gt;
 srl b&lt;br /&gt;
 rr c&lt;br /&gt;
 jr nc,mul24b2&lt;br /&gt;
 add ix,de&lt;br /&gt;
 ld a,h&lt;br /&gt;
 adc l&lt;br /&gt;
 ld h,a&lt;br /&gt;
.mul24b2:&lt;br /&gt;
 sla e&lt;br /&gt;
 rl d&lt;br /&gt;
 rl l&lt;br /&gt;
 jr mul24b1:&lt;br /&gt;
.mul24b3:&lt;br /&gt;
 ld a,h&lt;br /&gt;
 db #dd:ld e,l&lt;br /&gt;
 db #dd:ld d,h&lt;br /&gt;
 ex de,hl&lt;br /&gt;
 ret&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://map.tni.nl/articles/mult_div_shifts.php Multiplications and divisions on the MSX Assembly Page]&lt;br /&gt;
* [http://www.mccw.hetlab.tk/92/Multiplication/en.html &amp;quot;Multiplication on a Z80&amp;quot; ( MSX Computer &amp;amp; Club Webmagazine)]&lt;br /&gt;
* [http://www.andreadrian.de/oldcpu/Z80_number_cruncher.html The Z80 number cruncher (Andre Adrian)] (16/32bit multiplication, addition, right shift)&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94460</id>
		<title>Programming:Integer Multiplication</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94460"/>
				<updated>2015-10-24T06:57:42Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: /* Classic 8bit * 8bit Unsigned */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Classic 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' H = ''Multiplier'', E = ''Multiplicand'', L = 0, D = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''CPC Cycles:''' 188-244 (216 on average) = 47-61 (54) usec&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 33 bytes&lt;br /&gt;
&lt;br /&gt;
The additional clocks and bytes maybe required to set up D and L and for RET.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sla h  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+3&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
jr nc,$+3  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Classic 16bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', DE = ''Multiplicand'', HL = 0, C = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A:HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add a,a  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+4&lt;br /&gt;
ld h,d&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
rla   ; ...&lt;br /&gt;
jr nc,$+4  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
adc a,c  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Fast 8bit * 8bit Unsigned (using log / antilog tables) ==&lt;br /&gt;
&lt;br /&gt;
The original routine was written by Jeff Frohwein for the Nintendo Gameboy. You can find it on [http://www.devrs.com/gb/files/logmult.txt Devrs.com].&lt;br /&gt;
&lt;br /&gt;
Because of the usage of log / antilog tables this routine is less accurate, but very fast. It takes advantage of the fact that if you take the log of two numbers, add the results and then take the antilog of the total you have done the equivalent of multiplying the two numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 x^a * x^b = x^(a+b)&lt;br /&gt;
&lt;br /&gt;
 a * b = x^(logx(a) + logx(b))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Input:''' B = ''Multiplier'', C = ''Multiplicant''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''Clocks:''' 124&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 1024 bytes (768 bytes for the tables)&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' It is VERY approximate routine, e.g., 0*7=7, 1*28=27, 10*81=790, 100*100=9742, ...&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FastMult:&lt;br /&gt;
  ld      l,c&lt;br /&gt;
  ld      h,&amp;amp;82&lt;br /&gt;
  ld      d,(hl)          ; d = 32 * log_2(c)&lt;br /&gt;
  &lt;br /&gt;
  ld      l,b&lt;br /&gt;
  ld      a,(hl)          ; a = 32 * log_2(b)&lt;br /&gt;
  &lt;br /&gt;
  add     a,d&lt;br /&gt;
  ld      l,a&lt;br /&gt;
  ld      a,0&lt;br /&gt;
  adc     a,0&lt;br /&gt;
  ld      h,a             ; hl = d + a&lt;br /&gt;
  &lt;br /&gt;
  add     hl,hl&lt;br /&gt;
  set     2,h             ; hl = hl + $0400&lt;br /&gt;
  set     7,h             ; hl = hl + &amp;amp;8000&lt;br /&gt;
  &lt;br /&gt;
  ld      e,(hl)&lt;br /&gt;
  inc     hl&lt;br /&gt;
  ld      d,(hl)          ; de = 2^((hl)/32)&lt;br /&gt;
  &lt;br /&gt;
  ret&lt;br /&gt;
&lt;br /&gt;
; 32*Log_2(x) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 TO 255&lt;br /&gt;
;     C=4 &lt;br /&gt;
;     B=2&lt;br /&gt;
;     FOR Z=1 TO 10&lt;br /&gt;
;       IF (2^C) &amp;gt; A THEN C=C-B ELSE C=C+B&lt;br /&gt;
;       B=B/2&lt;br /&gt;
;     NEXT Z&lt;br /&gt;
;     PRINT INT(C*32);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8200&lt;br /&gt;
&lt;br /&gt;
logtable:&lt;br /&gt;
  db 0 , 0 , 32 , 50 , 64 , 74 , 82 , 89 , 96 , 101 , 106 , 110 , 114 , 118 , 121&lt;br /&gt;
  db 125 , 128 , 130 , 133 , 135 , 138 , 140 , 142 , 144 , 146 , 148 , 150 , 152&lt;br /&gt;
  db 153 , 155 , 157 , 158 , 160 , 161 , 162 , 164 , 165 , 166 , 167 , 169 , 170&lt;br /&gt;
  db 171 , 172 , 173 , 174 , 175 , 176 , 177 , 178 , 179 , 180 , 181 , 182 , 183&lt;br /&gt;
  db 184 , 185 , 185 , 186 , 187 , 188 , 189 , 189 , 190 , 191 , 192 , 192 , 193&lt;br /&gt;
  db 194 , 194 , 195 , 196 , 196 , 197 , 198 , 198 , 199 , 199 , 200 , 201 , 201&lt;br /&gt;
  db 202 , 202 , 203 , 204 , 204 , 205 , 205 , 206 , 206 , 207 , 207 , 208 , 208&lt;br /&gt;
  db 209 , 209 , 210 , 210 , 211 , 211 , 212 , 212 , 213 , 213 , 213 , 214 , 214&lt;br /&gt;
  db 215 , 215 , 216 , 216 , 217 , 217 , 217 , 218 , 218 , 219 , 219 , 219 , 220&lt;br /&gt;
  db 220 , 221 , 221 , 221 , 222 , 222 , 222 , 223 , 223 , 224 , 224 , 224 , 225&lt;br /&gt;
  db 225 , 225 , 226 , 226 , 226 , 227 , 227 , 227 , 228 , 228 , 228 , 229 , 229&lt;br /&gt;
  db 229 , 230 , 230 , 230 , 231 , 231 , 231 , 231 , 232 , 232 , 232 , 233 , 233&lt;br /&gt;
  db 233 , 234 , 234 , 234 , 234 , 235 , 235 , 235 , 236 , 236 , 236 , 236 , 237&lt;br /&gt;
  db 237 , 237 , 237 , 238 , 238 , 238 , 238 , 239 , 239 , 239 , 239 , 240 , 240&lt;br /&gt;
  db 240 , 241 , 241 , 241 , 241 , 241 , 242 , 242 , 242 , 242 , 243 , 243 , 243&lt;br /&gt;
  db 243 , 244 , 244 , 244 , 244 , 245 , 245 , 245 , 245 , 245 , 246 , 246 , 246&lt;br /&gt;
  db 246 , 247 , 247 , 247 , 247 , 247 , 248 , 248 , 248 , 248 , 249 , 249 , 249&lt;br /&gt;
  db 249 , 249 , 250 , 250 , 250 , 250 , 250 , 251 , 251 , 251 , 251 , 251 , 252&lt;br /&gt;
  db 252 , 252 , 252 , 252 , 253 , 253 , 253 , 253 , 253 , 253 , 254 , 254 , 254&lt;br /&gt;
  db 254 , 254 , 255 , 255 , 255 , 255 , 255&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; AntiLog 2^(x/32) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 to 510&lt;br /&gt;
;   PRINT INT(2^(A/32)+.5);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8400&lt;br /&gt;
&lt;br /&gt;
antilog:&lt;br /&gt;
  dw 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 , 4&lt;br /&gt;
  dw 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 6&lt;br /&gt;
  dw 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 8 , 9&lt;br /&gt;
  dw 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , 12 , 12 , 12&lt;br /&gt;
  dw 13 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17&lt;br /&gt;
  dw 18 , 18 , 19 , 19 , 19 , 20 , 20 , 21 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25&lt;br /&gt;
  dw 25 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , 30 , 31 , 31 , 32 , 33 , 33 , 34 , 35&lt;br /&gt;
  dw 36 , 36 , 37 , 38 , 39 , 40 , 41 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49&lt;br /&gt;
  dw 50 , 52 , 53 , 54 , 55 , 56 , 57 , 59 , 60 , 61 , 63 , 64 , 65 , 67 , 68 , 70&lt;br /&gt;
  dw 71 , 73 , 74 , 76 , 78 , 79 , 81 , 83 , 85 , 87 , 89 , 91 , 92 , 95 , 97 , 99&lt;br /&gt;
  dw 101 , 103 , 105 , 108 , 110 , 112 , 115 , 117 , 120 , 123 , 125 , 128 , 131&lt;br /&gt;
  dw 134 , 137 , 140 , 143 , 146 , 149 , 152 , 156 , 159 , 162 , 166 , 170 , 173&lt;br /&gt;
  dw 177 , 181 , 185 , 189 , 193 , 197 , 202 , 206 , 211 , 215 , 220 , 225 , 230&lt;br /&gt;
  dw 235 , 240 , 245 , 251 , 256 , 262 , 267 , 273 , 279 , 285 , 292 , 298 , 304&lt;br /&gt;
  dw 311 , 318 , 325 , 332 , 339 , 347 , 354 , 362 , 370 , 378 , 386 , 395 , 403&lt;br /&gt;
  dw 412 , 421 , 431 , 440 , 450 , 459 , 470 , 480 , 490 , 501 , 512 , 523 , 535&lt;br /&gt;
  dw 546 , 558 , 571 , 583 , 596 , 609 , 622 , 636 , 650 , 664 , 679 , 693 , 709&lt;br /&gt;
  dw 724 , 740 , 756 , 773 , 790 , 807 , 825 , 843 , 861 , 880 , 899 , 919 , 939&lt;br /&gt;
  dw 960 , 981 , 1002 , 1024 , 1046 , 1069 , 1093 , 1117 , 1141 , 1166 , 1192&lt;br /&gt;
  dw 1218 , 1244 , 1272 , 1300 , 1328 , 1357 , 1387 , 1417 , 1448 , 1480 , 1512&lt;br /&gt;
  dw 1545 , 1579 , 1614 , 1649 , 1685 , 1722 , 1760 , 1798 , 1838 , 1878 , 1919&lt;br /&gt;
  dw 1961 , 2004 , 2048 , 2093 , 2139 , 2186 , 2233 , 2282 , 2332 , 2383 , 2435&lt;br /&gt;
  dw 2489 , 2543 , 2599 , 2656 , 2714 , 2774 , 2834 , 2896 , 2960 , 3025 , 3091&lt;br /&gt;
  dw 3158 , 3228 , 3298 , 3371 , 3444 , 3520 , 3597 , 3676 , 3756 , 3838 , 3922&lt;br /&gt;
  dw 4008 , 4096 , 4186 , 4277 , 4371 , 4467 , 4565 , 4664 , 4767 , 4871 , 4978&lt;br /&gt;
  dw 5087 , 5198 , 5312 , 5428 , 5547 , 5668 , 5793 , 5919 , 6049 , 6182 , 6317&lt;br /&gt;
  dw 6455 , 6597 , 6741 , 6889 , 7039 , 7194 , 7351 , 7512 , 7677 , 7845 , 8016&lt;br /&gt;
  dw 8192 , 8371 , 8555 , 8742 , 8933 , 9129 , 9329 , 9533 , 9742 , 9955 , 10173&lt;br /&gt;
  dw 10396 , 10624 , 10856 , 11094 , 11337 , 11585 , 11839 , 12098 , 12363 , 12634&lt;br /&gt;
  dw 12910 , 13193 , 13482 , 13777 , 14079 , 14387 , 14702 , 15024 , 15353 , 15689&lt;br /&gt;
  dw 16033 , 16384 , 16743 , 17109 , 17484 , 17867 , 18258 , 18658 , 19066 , 19484&lt;br /&gt;
  dw 19911 , 20347 , 20792 , 21247 , 21713 , 22188 , 22674 , 23170 , 23678 , 24196&lt;br /&gt;
  dw 24726 , 25268 , 25821 , 26386 , 26964 , 27554 , 28158 , 28774 , 29404 , 30048&lt;br /&gt;
  dw 30706 , 31379 , 32066 , 32768 , 33485 , 34219 , 34968 , 35734 , 36516 , 37316&lt;br /&gt;
  dw 38133 , 38968 , 39821 , 40693 , 41584 , 42495 , 43425 , 44376 , 45348 , 46341&lt;br /&gt;
  dw 47356 , 48393 , 49452 , 50535 , 51642 , 52772 , 53928 , 55109 , 56316 , 57549&lt;br /&gt;
  dw  58809 , 60097 , 61413 , 62757&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Faster, accurate 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
I'm currently working on a new routine, based on a routine by Kirk Meyer [http://www.ticalc.org/pub/86/asm/source/routines/vfmult.asm] which uses nibble multiplication tables.&lt;br /&gt;
&lt;br /&gt;
I have a working, tested version which uses 16K of tables and can perform multiplication in 20&amp;amp;mu;s.&lt;br /&gt;
&lt;br /&gt;
The code to produce the tables is below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp1&lt;br /&gt;
ld a,l&lt;br /&gt;
rla&lt;br /&gt;
and #1e&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp1&lt;br /&gt;
inc h&lt;br /&gt;
.makelp2&lt;br /&gt;
ld a,l&lt;br /&gt;
rra:rra:rra&lt;br /&gt;
and #1e&lt;br /&gt;
jr z,usez&lt;br /&gt;
add restab2 - restab / 256 - 2&lt;br /&gt;
.usez&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp2&lt;br /&gt;
inc h			; restab&lt;br /&gt;
.makelp3&lt;br /&gt;
ld a,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
add l&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,0&lt;br /&gt;
adc d&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h:dec h:dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256 - 2&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
ld b,h&lt;br /&gt;
ld c,l&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp4&lt;br /&gt;
ld e,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
dec h&lt;br /&gt;
ex de,hl&lt;br /&gt;
add hl,hl:add hl,hl:add hl,hl:add hl,hl&lt;br /&gt;
ex de,hl&lt;br /&gt;
ld a,e&lt;br /&gt;
ld (bc),a&lt;br /&gt;
inc b&lt;br /&gt;
ld a,d&lt;br /&gt;
ld (bc),a&lt;br /&gt;
dec b&lt;br /&gt;
inc l&lt;br /&gt;
inc c&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
.restab2&lt;br /&gt;
ds 512 * 15&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code to perform the multiplication (DE = L * C):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ld h,hltab1 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
inc h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(bc)		; 10&lt;br /&gt;
add (hl)		; 12&lt;br /&gt;
ld e,a			; 13&lt;br /&gt;
inc b			; 14&lt;br /&gt;
inc h			; 15&lt;br /&gt;
ld a,(bc)		; 17&lt;br /&gt;
adc (hl)		; 19&lt;br /&gt;
ld d,a			; 20&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
16K is a lot of memory to use for tables, but I'm working on a way to reduce this to 8K while maintaining similar performance (around 26&amp;amp;mu;s). The idea is rather than using tables for the low and high nibbles, use tables for alternate bits. So there would be 16 tables for the values #00, #01, #04, #05, #10, #11, #14, #15, #40, #41, #44, #45, #50, #51, #54, #55. The values can be shifted by 1 (rather than 4) to give values for the alternate bits using a simple ADD HL,HL.&lt;br /&gt;
&lt;br /&gt;
This routine should be easy to adapt to a 16bit * 8bit unsigned multiplication or even a 16bit * 16bit, using simple additions.&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 03:58, 8 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
Ok, here is the new 8K routine, first the routine to build the tables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp5&lt;br /&gt;
ld a,l&lt;br /&gt;
ld bc,0&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
ld a,b&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,c&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp5&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp6&lt;br /&gt;
ld (hl),l&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp6&lt;br /&gt;
inc h:inc h&lt;br /&gt;
ld b,2&lt;br /&gt;
.makelp8&lt;br /&gt;
push bc&lt;br /&gt;
xor a&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
.makelp7&lt;br /&gt;
push hl&lt;br /&gt;
push af&lt;br /&gt;
call mulLbyA&lt;br /&gt;
ex de,hl&lt;br /&gt;
pop af&lt;br /&gt;
pop hl&lt;br /&gt;
ld (hl),e&lt;br /&gt;
inc h&lt;br /&gt;
ld (hl),d&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp7&lt;br /&gt;
inc h:inc h&lt;br /&gt;
pop bc&lt;br /&gt;
inc b&lt;br /&gt;
bit 4,b&lt;br /&gt;
jr z,makelp8&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
.mulLbyA	; MAX times	; MIN times&lt;br /&gt;
ld e,l		; 1		; 1&lt;br /&gt;
ld d,0		; 3		; 3&lt;br /&gt;
add a		; 4		; 4&lt;br /&gt;
ld h,a		; 5		; 5&lt;br /&gt;
jr c,ncad0	; 8		; 8&lt;br /&gt;
ld l,d		&lt;br /&gt;
.ncad0&lt;br /&gt;
add hl,hl	; 11		; 11&lt;br /&gt;
jr nc,ncad1	; 13		; 14&lt;br /&gt;
add hl,de	; 16&lt;br /&gt;
.ncad1&lt;br /&gt;
add hl,hl	; 19		; 17&lt;br /&gt;
jr nc,ncad2	; 21		; 20&lt;br /&gt;
add hl,de	; 24&lt;br /&gt;
.ncad2&lt;br /&gt;
add hl,hl	; 27		; 23&lt;br /&gt;
jr nc,ncad3	; 29		; 26&lt;br /&gt;
add hl,de	; 32&lt;br /&gt;
.ncad3&lt;br /&gt;
add hl,hl	; 35		; 29&lt;br /&gt;
jr nc,ncad4	; 37		; 32&lt;br /&gt;
add hl,de	; 40&lt;br /&gt;
.ncad4&lt;br /&gt;
add hl,hl	; 43		; 35&lt;br /&gt;
jr nc,ncad5	; 45		; 38&lt;br /&gt;
add hl,de	; 48&lt;br /&gt;
.ncad5&lt;br /&gt;
add hl,hl	; 51		; 41&lt;br /&gt;
jr nc,ncad6	; 53		; 44&lt;br /&gt;
add hl,de	; 56&lt;br /&gt;
.ncad6&lt;br /&gt;
add hl,hl	; 59		; 47&lt;br /&gt;
ld a,h		; 60		; 48&lt;br /&gt;
ret nc		; 61		; 50?&lt;br /&gt;
add hl,de	; 64&lt;br /&gt;
ld a,h		; 65&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the routine to do the multiplication:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.umultCL		; Using 8 bit only (25us - DE = L * C)&lt;br /&gt;
ld h,hltab2 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
dec h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(hl)		; 10&lt;br /&gt;
add a			; 11&lt;br /&gt;
inc h			; 12&lt;br /&gt;
ld d,(hl)		; 14&lt;br /&gt;
rl d			; 16&lt;br /&gt;
ld h,b			; 17&lt;br /&gt;
add (hl)		; 19&lt;br /&gt;
ld e,a			; 20&lt;br /&gt;
inc h			; 21&lt;br /&gt;
ld a,(hl)		; 23&lt;br /&gt;
adc d			; 24&lt;br /&gt;
ld d,a			; 25&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Very fast 8bit * 8bit Unsigned with only 1K of tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input''': B = Multiplier, C = Multiplicant&lt;br /&gt;
&lt;br /&gt;
'''Output''': DE = Product&lt;br /&gt;
&lt;br /&gt;
'''Clocks''': 104-112 (108 on average)&lt;br /&gt;
&lt;br /&gt;
'''Size''': 24 bytes of code and 1024 bytes for the tables&lt;br /&gt;
&lt;br /&gt;
Here's a new routine I've developed which uses the formula ab = ((a + b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - (a - b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) / 4. It's based on a routine for the 6502 by Stephen Judd in a C= Hacking article. Because of differences between the way the 6502 does register indexing it was quite difficult to actually get this working, but it's a great compromise between speed and space since it only uses 1K of tables (as opposed to the 16K or 8K table routines above), and can still manage to do the job in a maximum of 28 microseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Firstly, once again, we need some code to generate the tables. These tables contain values for&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;/4 for 9 bit values of x, with the LSB when bit 8 is zero first followed by the MSB.&lt;br /&gt;
&amp;lt;pre&amp;gt;.gen_sq4&lt;br /&gt;
	xor a&lt;br /&gt;
	ld de,umul_tab + #1ff&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	ld h,d&lt;br /&gt;
	ld l,e&lt;br /&gt;
	inc e&lt;br /&gt;
	ld c,e&lt;br /&gt;
	ld b,2&lt;br /&gt;
&lt;br /&gt;
	.sq4_lp&lt;br /&gt;
	ld a,b&lt;br /&gt;
	cp 2&lt;br /&gt;
	ld a,e&lt;br /&gt;
	rra&lt;br /&gt;
	add (hl)&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	inc h&lt;br /&gt;
	inc d&lt;br /&gt;
	ld a,(hl)&lt;br /&gt;
	adc c&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld h,d&lt;br /&gt;
	inc l&lt;br /&gt;
	inc e&lt;br /&gt;
	jr nz,sq4_lp&lt;br /&gt;
	inc d&lt;br /&gt;
	inc d&lt;br /&gt;
	djnz sq4_lp&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
align #100&lt;br /&gt;
.umul_tab ds #400&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now for the actual multiply routine:&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', L = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ld h,umul_tab_lo / #100	; 2&lt;br /&gt;
	ld b,h			; 3&lt;br /&gt;
	add l			; 4&lt;br /&gt;
	ld c,a			; 5&lt;br /&gt;
	jr nc,@noovf		; 7&lt;br /&gt;
	inc b			; 8&lt;br /&gt;
	inc b			; 9&lt;br /&gt;
.@noovf&lt;br /&gt;
	sub l			; 10&lt;br /&gt;
	sub l			; 11&lt;br /&gt;
	jr nc,@noneg		; 13&lt;br /&gt;
	neg			; 15&lt;br /&gt;
.@noneg&lt;br /&gt;
	ld l,a			; 16&lt;br /&gt;
	ld a,(bc)		; 18&lt;br /&gt;
	sub (hl)		; 20&lt;br /&gt;
	ld e,a			; 21&lt;br /&gt;
	inc b			; 22&lt;br /&gt;
	inc h			; 23&lt;br /&gt;
	ld a,(bc)		; 25&lt;br /&gt;
	sbc (hl)		; 27&lt;br /&gt;
	ld d,a			; 28&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This code could easily be converted to a macro as it's only 24 bytes. I've tried to optimize it further but with no luck!&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 06:25, 4 April 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== 16bit * 16bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' BC = ''Multiplier'', DE = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A,HL = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;ld ix,0&lt;br /&gt;
 ld hl,0&lt;br /&gt;
.mul24b1:&lt;br /&gt;
 ld a,c&lt;br /&gt;
 or b&lt;br /&gt;
 jr z,mul24b3&lt;br /&gt;
 srl b&lt;br /&gt;
 rr c&lt;br /&gt;
 jr nc,mul24b2&lt;br /&gt;
 add ix,de&lt;br /&gt;
 ld a,h&lt;br /&gt;
 adc l&lt;br /&gt;
 ld h,a&lt;br /&gt;
.mul24b2:&lt;br /&gt;
 sla e&lt;br /&gt;
 rl d&lt;br /&gt;
 rl l&lt;br /&gt;
 jr mul24b1:&lt;br /&gt;
.mul24b3:&lt;br /&gt;
 ld a,h&lt;br /&gt;
 db #dd:ld e,l&lt;br /&gt;
 db #dd:ld d,h&lt;br /&gt;
 ex de,hl&lt;br /&gt;
 ret&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://map.tni.nl/articles/mult_div_shifts.php Multiplications and divisions on the MSX Assembly Page]&lt;br /&gt;
* [http://www.mccw.hetlab.tk/92/Multiplication/en.html &amp;quot;Multiplication on a Z80&amp;quot; ( MSX Computer &amp;amp; Club Webmagazine)]&lt;br /&gt;
* [http://www.andreadrian.de/oldcpu/Z80_number_cruncher.html The Z80 number cruncher (Andre Adrian)] (16/32bit multiplication, addition, right shift)&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94409</id>
		<title>Programming:Integer Multiplication</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94409"/>
				<updated>2015-10-18T10:18:14Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: additional info&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Classic 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' H = ''Multiplier'', E = ''Multiplicand'', L = 0, D = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''Clocks:''' 188-244 (216 on average)&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 33 bytes&lt;br /&gt;
&lt;br /&gt;
The additional clocks and bytes maybe required to set up D and L and for RET.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sla h  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+3&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
jr nc,$+3  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Classic 16bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', DE = ''Multiplicand'', HL = 0, C = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A:HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add a,a  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+4&lt;br /&gt;
ld h,d&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
rla   ; ...&lt;br /&gt;
jr nc,$+4  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
adc a,c  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Fast 8bit * 8bit Unsigned (using log / antilog tables) ==&lt;br /&gt;
&lt;br /&gt;
The original routine was written by Jeff Frohwein for the Nintendo Gameboy. You can find it on [http://www.devrs.com/gb/files/logmult.txt Devrs.com].&lt;br /&gt;
&lt;br /&gt;
Because of the usage of log / antilog tables this routine is less accurate, but very fast. It takes advantage of the fact that if you take the log of two numbers, add the results and then take the antilog of the total you have done the equivalent of multiplying the two numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 x^a * x^b = x^(a+b)&lt;br /&gt;
&lt;br /&gt;
 a * b = x^(logx(a) + logx(b))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Input:''' B = ''Multiplier'', C = ''Multiplicant''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''Clocks:''' 124&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 1024 bytes (768 bytes for the tables)&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' It is VERY approximate routine, e.g., 0*7=7, 1*28=27, 10*81=790, 100*100=9742, ...&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FastMult:&lt;br /&gt;
  ld      l,c&lt;br /&gt;
  ld      h,&amp;amp;82&lt;br /&gt;
  ld      d,(hl)          ; d = 32 * log_2(c)&lt;br /&gt;
  &lt;br /&gt;
  ld      l,b&lt;br /&gt;
  ld      a,(hl)          ; a = 32 * log_2(b)&lt;br /&gt;
  &lt;br /&gt;
  add     a,d&lt;br /&gt;
  ld      l,a&lt;br /&gt;
  ld      a,0&lt;br /&gt;
  adc     a,0&lt;br /&gt;
  ld      h,a             ; hl = d + a&lt;br /&gt;
  &lt;br /&gt;
  add     hl,hl&lt;br /&gt;
  set     2,h             ; hl = hl + $0400&lt;br /&gt;
  set     7,h             ; hl = hl + &amp;amp;8000&lt;br /&gt;
  &lt;br /&gt;
  ld      e,(hl)&lt;br /&gt;
  inc     hl&lt;br /&gt;
  ld      d,(hl)          ; de = 2^((hl)/32)&lt;br /&gt;
  &lt;br /&gt;
  ret&lt;br /&gt;
&lt;br /&gt;
; 32*Log_2(x) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 TO 255&lt;br /&gt;
;     C=4 &lt;br /&gt;
;     B=2&lt;br /&gt;
;     FOR Z=1 TO 10&lt;br /&gt;
;       IF (2^C) &amp;gt; A THEN C=C-B ELSE C=C+B&lt;br /&gt;
;       B=B/2&lt;br /&gt;
;     NEXT Z&lt;br /&gt;
;     PRINT INT(C*32);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8200&lt;br /&gt;
&lt;br /&gt;
logtable:&lt;br /&gt;
  db 0 , 0 , 32 , 50 , 64 , 74 , 82 , 89 , 96 , 101 , 106 , 110 , 114 , 118 , 121&lt;br /&gt;
  db 125 , 128 , 130 , 133 , 135 , 138 , 140 , 142 , 144 , 146 , 148 , 150 , 152&lt;br /&gt;
  db 153 , 155 , 157 , 158 , 160 , 161 , 162 , 164 , 165 , 166 , 167 , 169 , 170&lt;br /&gt;
  db 171 , 172 , 173 , 174 , 175 , 176 , 177 , 178 , 179 , 180 , 181 , 182 , 183&lt;br /&gt;
  db 184 , 185 , 185 , 186 , 187 , 188 , 189 , 189 , 190 , 191 , 192 , 192 , 193&lt;br /&gt;
  db 194 , 194 , 195 , 196 , 196 , 197 , 198 , 198 , 199 , 199 , 200 , 201 , 201&lt;br /&gt;
  db 202 , 202 , 203 , 204 , 204 , 205 , 205 , 206 , 206 , 207 , 207 , 208 , 208&lt;br /&gt;
  db 209 , 209 , 210 , 210 , 211 , 211 , 212 , 212 , 213 , 213 , 213 , 214 , 214&lt;br /&gt;
  db 215 , 215 , 216 , 216 , 217 , 217 , 217 , 218 , 218 , 219 , 219 , 219 , 220&lt;br /&gt;
  db 220 , 221 , 221 , 221 , 222 , 222 , 222 , 223 , 223 , 224 , 224 , 224 , 225&lt;br /&gt;
  db 225 , 225 , 226 , 226 , 226 , 227 , 227 , 227 , 228 , 228 , 228 , 229 , 229&lt;br /&gt;
  db 229 , 230 , 230 , 230 , 231 , 231 , 231 , 231 , 232 , 232 , 232 , 233 , 233&lt;br /&gt;
  db 233 , 234 , 234 , 234 , 234 , 235 , 235 , 235 , 236 , 236 , 236 , 236 , 237&lt;br /&gt;
  db 237 , 237 , 237 , 238 , 238 , 238 , 238 , 239 , 239 , 239 , 239 , 240 , 240&lt;br /&gt;
  db 240 , 241 , 241 , 241 , 241 , 241 , 242 , 242 , 242 , 242 , 243 , 243 , 243&lt;br /&gt;
  db 243 , 244 , 244 , 244 , 244 , 245 , 245 , 245 , 245 , 245 , 246 , 246 , 246&lt;br /&gt;
  db 246 , 247 , 247 , 247 , 247 , 247 , 248 , 248 , 248 , 248 , 249 , 249 , 249&lt;br /&gt;
  db 249 , 249 , 250 , 250 , 250 , 250 , 250 , 251 , 251 , 251 , 251 , 251 , 252&lt;br /&gt;
  db 252 , 252 , 252 , 252 , 253 , 253 , 253 , 253 , 253 , 253 , 254 , 254 , 254&lt;br /&gt;
  db 254 , 254 , 255 , 255 , 255 , 255 , 255&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; AntiLog 2^(x/32) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 to 510&lt;br /&gt;
;   PRINT INT(2^(A/32)+.5);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8400&lt;br /&gt;
&lt;br /&gt;
antilog:&lt;br /&gt;
  dw 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 , 4&lt;br /&gt;
  dw 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 6&lt;br /&gt;
  dw 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 8 , 9&lt;br /&gt;
  dw 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , 12 , 12 , 12&lt;br /&gt;
  dw 13 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17&lt;br /&gt;
  dw 18 , 18 , 19 , 19 , 19 , 20 , 20 , 21 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25&lt;br /&gt;
  dw 25 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , 30 , 31 , 31 , 32 , 33 , 33 , 34 , 35&lt;br /&gt;
  dw 36 , 36 , 37 , 38 , 39 , 40 , 41 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49&lt;br /&gt;
  dw 50 , 52 , 53 , 54 , 55 , 56 , 57 , 59 , 60 , 61 , 63 , 64 , 65 , 67 , 68 , 70&lt;br /&gt;
  dw 71 , 73 , 74 , 76 , 78 , 79 , 81 , 83 , 85 , 87 , 89 , 91 , 92 , 95 , 97 , 99&lt;br /&gt;
  dw 101 , 103 , 105 , 108 , 110 , 112 , 115 , 117 , 120 , 123 , 125 , 128 , 131&lt;br /&gt;
  dw 134 , 137 , 140 , 143 , 146 , 149 , 152 , 156 , 159 , 162 , 166 , 170 , 173&lt;br /&gt;
  dw 177 , 181 , 185 , 189 , 193 , 197 , 202 , 206 , 211 , 215 , 220 , 225 , 230&lt;br /&gt;
  dw 235 , 240 , 245 , 251 , 256 , 262 , 267 , 273 , 279 , 285 , 292 , 298 , 304&lt;br /&gt;
  dw 311 , 318 , 325 , 332 , 339 , 347 , 354 , 362 , 370 , 378 , 386 , 395 , 403&lt;br /&gt;
  dw 412 , 421 , 431 , 440 , 450 , 459 , 470 , 480 , 490 , 501 , 512 , 523 , 535&lt;br /&gt;
  dw 546 , 558 , 571 , 583 , 596 , 609 , 622 , 636 , 650 , 664 , 679 , 693 , 709&lt;br /&gt;
  dw 724 , 740 , 756 , 773 , 790 , 807 , 825 , 843 , 861 , 880 , 899 , 919 , 939&lt;br /&gt;
  dw 960 , 981 , 1002 , 1024 , 1046 , 1069 , 1093 , 1117 , 1141 , 1166 , 1192&lt;br /&gt;
  dw 1218 , 1244 , 1272 , 1300 , 1328 , 1357 , 1387 , 1417 , 1448 , 1480 , 1512&lt;br /&gt;
  dw 1545 , 1579 , 1614 , 1649 , 1685 , 1722 , 1760 , 1798 , 1838 , 1878 , 1919&lt;br /&gt;
  dw 1961 , 2004 , 2048 , 2093 , 2139 , 2186 , 2233 , 2282 , 2332 , 2383 , 2435&lt;br /&gt;
  dw 2489 , 2543 , 2599 , 2656 , 2714 , 2774 , 2834 , 2896 , 2960 , 3025 , 3091&lt;br /&gt;
  dw 3158 , 3228 , 3298 , 3371 , 3444 , 3520 , 3597 , 3676 , 3756 , 3838 , 3922&lt;br /&gt;
  dw 4008 , 4096 , 4186 , 4277 , 4371 , 4467 , 4565 , 4664 , 4767 , 4871 , 4978&lt;br /&gt;
  dw 5087 , 5198 , 5312 , 5428 , 5547 , 5668 , 5793 , 5919 , 6049 , 6182 , 6317&lt;br /&gt;
  dw 6455 , 6597 , 6741 , 6889 , 7039 , 7194 , 7351 , 7512 , 7677 , 7845 , 8016&lt;br /&gt;
  dw 8192 , 8371 , 8555 , 8742 , 8933 , 9129 , 9329 , 9533 , 9742 , 9955 , 10173&lt;br /&gt;
  dw 10396 , 10624 , 10856 , 11094 , 11337 , 11585 , 11839 , 12098 , 12363 , 12634&lt;br /&gt;
  dw 12910 , 13193 , 13482 , 13777 , 14079 , 14387 , 14702 , 15024 , 15353 , 15689&lt;br /&gt;
  dw 16033 , 16384 , 16743 , 17109 , 17484 , 17867 , 18258 , 18658 , 19066 , 19484&lt;br /&gt;
  dw 19911 , 20347 , 20792 , 21247 , 21713 , 22188 , 22674 , 23170 , 23678 , 24196&lt;br /&gt;
  dw 24726 , 25268 , 25821 , 26386 , 26964 , 27554 , 28158 , 28774 , 29404 , 30048&lt;br /&gt;
  dw 30706 , 31379 , 32066 , 32768 , 33485 , 34219 , 34968 , 35734 , 36516 , 37316&lt;br /&gt;
  dw 38133 , 38968 , 39821 , 40693 , 41584 , 42495 , 43425 , 44376 , 45348 , 46341&lt;br /&gt;
  dw 47356 , 48393 , 49452 , 50535 , 51642 , 52772 , 53928 , 55109 , 56316 , 57549&lt;br /&gt;
  dw  58809 , 60097 , 61413 , 62757&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Faster, accurate 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
I'm currently working on a new routine, based on a routine by Kirk Meyer [http://www.ticalc.org/pub/86/asm/source/routines/vfmult.asm] which uses nibble multiplication tables.&lt;br /&gt;
&lt;br /&gt;
I have a working, tested version which uses 16K of tables and can perform multiplication in 20&amp;amp;mu;s.&lt;br /&gt;
&lt;br /&gt;
The code to produce the tables is below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp1&lt;br /&gt;
ld a,l&lt;br /&gt;
rla&lt;br /&gt;
and #1e&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp1&lt;br /&gt;
inc h&lt;br /&gt;
.makelp2&lt;br /&gt;
ld a,l&lt;br /&gt;
rra:rra:rra&lt;br /&gt;
and #1e&lt;br /&gt;
jr z,usez&lt;br /&gt;
add restab2 - restab / 256 - 2&lt;br /&gt;
.usez&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp2&lt;br /&gt;
inc h			; restab&lt;br /&gt;
.makelp3&lt;br /&gt;
ld a,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
add l&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,0&lt;br /&gt;
adc d&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h:dec h:dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256 - 2&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
ld b,h&lt;br /&gt;
ld c,l&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp4&lt;br /&gt;
ld e,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
dec h&lt;br /&gt;
ex de,hl&lt;br /&gt;
add hl,hl:add hl,hl:add hl,hl:add hl,hl&lt;br /&gt;
ex de,hl&lt;br /&gt;
ld a,e&lt;br /&gt;
ld (bc),a&lt;br /&gt;
inc b&lt;br /&gt;
ld a,d&lt;br /&gt;
ld (bc),a&lt;br /&gt;
dec b&lt;br /&gt;
inc l&lt;br /&gt;
inc c&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
.restab2&lt;br /&gt;
ds 512 * 15&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code to perform the multiplication (DE = L * C):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ld h,hltab1 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
inc h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(bc)		; 10&lt;br /&gt;
add (hl)		; 12&lt;br /&gt;
ld e,a			; 13&lt;br /&gt;
inc b			; 14&lt;br /&gt;
inc h			; 15&lt;br /&gt;
ld a,(bc)		; 17&lt;br /&gt;
adc (hl)		; 19&lt;br /&gt;
ld d,a			; 20&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
16K is a lot of memory to use for tables, but I'm working on a way to reduce this to 8K while maintaining similar performance (around 26&amp;amp;mu;s). The idea is rather than using tables for the low and high nibbles, use tables for alternate bits. So there would be 16 tables for the values #00, #01, #04, #05, #10, #11, #14, #15, #40, #41, #44, #45, #50, #51, #54, #55. The values can be shifted by 1 (rather than 4) to give values for the alternate bits using a simple ADD HL,HL.&lt;br /&gt;
&lt;br /&gt;
This routine should be easy to adapt to a 16bit * 8bit unsigned multiplication or even a 16bit * 16bit, using simple additions.&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 03:58, 8 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
Ok, here is the new 8K routine, first the routine to build the tables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp5&lt;br /&gt;
ld a,l&lt;br /&gt;
ld bc,0&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
ld a,b&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,c&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp5&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp6&lt;br /&gt;
ld (hl),l&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp6&lt;br /&gt;
inc h:inc h&lt;br /&gt;
ld b,2&lt;br /&gt;
.makelp8&lt;br /&gt;
push bc&lt;br /&gt;
xor a&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
.makelp7&lt;br /&gt;
push hl&lt;br /&gt;
push af&lt;br /&gt;
call mulLbyA&lt;br /&gt;
ex de,hl&lt;br /&gt;
pop af&lt;br /&gt;
pop hl&lt;br /&gt;
ld (hl),e&lt;br /&gt;
inc h&lt;br /&gt;
ld (hl),d&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp7&lt;br /&gt;
inc h:inc h&lt;br /&gt;
pop bc&lt;br /&gt;
inc b&lt;br /&gt;
bit 4,b&lt;br /&gt;
jr z,makelp8&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
.mulLbyA	; MAX times	; MIN times&lt;br /&gt;
ld e,l		; 1		; 1&lt;br /&gt;
ld d,0		; 3		; 3&lt;br /&gt;
add a		; 4		; 4&lt;br /&gt;
ld h,a		; 5		; 5&lt;br /&gt;
jr c,ncad0	; 8		; 8&lt;br /&gt;
ld l,d		&lt;br /&gt;
.ncad0&lt;br /&gt;
add hl,hl	; 11		; 11&lt;br /&gt;
jr nc,ncad1	; 13		; 14&lt;br /&gt;
add hl,de	; 16&lt;br /&gt;
.ncad1&lt;br /&gt;
add hl,hl	; 19		; 17&lt;br /&gt;
jr nc,ncad2	; 21		; 20&lt;br /&gt;
add hl,de	; 24&lt;br /&gt;
.ncad2&lt;br /&gt;
add hl,hl	; 27		; 23&lt;br /&gt;
jr nc,ncad3	; 29		; 26&lt;br /&gt;
add hl,de	; 32&lt;br /&gt;
.ncad3&lt;br /&gt;
add hl,hl	; 35		; 29&lt;br /&gt;
jr nc,ncad4	; 37		; 32&lt;br /&gt;
add hl,de	; 40&lt;br /&gt;
.ncad4&lt;br /&gt;
add hl,hl	; 43		; 35&lt;br /&gt;
jr nc,ncad5	; 45		; 38&lt;br /&gt;
add hl,de	; 48&lt;br /&gt;
.ncad5&lt;br /&gt;
add hl,hl	; 51		; 41&lt;br /&gt;
jr nc,ncad6	; 53		; 44&lt;br /&gt;
add hl,de	; 56&lt;br /&gt;
.ncad6&lt;br /&gt;
add hl,hl	; 59		; 47&lt;br /&gt;
ld a,h		; 60		; 48&lt;br /&gt;
ret nc		; 61		; 50?&lt;br /&gt;
add hl,de	; 64&lt;br /&gt;
ld a,h		; 65&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the routine to do the multiplication:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.umultCL		; Using 8 bit only (25us - DE = L * C)&lt;br /&gt;
ld h,hltab2 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
dec h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(hl)		; 10&lt;br /&gt;
add a			; 11&lt;br /&gt;
inc h			; 12&lt;br /&gt;
ld d,(hl)		; 14&lt;br /&gt;
rl d			; 16&lt;br /&gt;
ld h,b			; 17&lt;br /&gt;
add (hl)		; 19&lt;br /&gt;
ld e,a			; 20&lt;br /&gt;
inc h			; 21&lt;br /&gt;
ld a,(hl)		; 23&lt;br /&gt;
adc d			; 24&lt;br /&gt;
ld d,a			; 25&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Very fast 8bit * 8bit Unsigned with only 1K of tables ==&lt;br /&gt;
&lt;br /&gt;
'''Input''': B = Multiplier, C = Multiplicant&lt;br /&gt;
&lt;br /&gt;
'''Output''': DE = Product&lt;br /&gt;
&lt;br /&gt;
'''Clocks''': 104-112 (108 on average)&lt;br /&gt;
&lt;br /&gt;
'''Size''': 24 bytes of code and 1024 bytes for the tables&lt;br /&gt;
&lt;br /&gt;
Here's a new routine I've developed which uses the formula ab = ((a + b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - (a - b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) / 4. It's based on a routine for the 6502 by Stephen Judd in a C= Hacking article. Because of differences between the way the 6502 does register indexing it was quite difficult to actually get this working, but it's a great compromise between speed and space since it only uses 1K of tables (as opposed to the 16K or 8K table routines above), and can still manage to do the job in a maximum of 28 microseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Firstly, once again, we need some code to generate the tables. These tables contain values for&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;/4 for 9 bit values of x, with the LSB when bit 8 is zero first followed by the MSB.&lt;br /&gt;
&amp;lt;pre&amp;gt;.gen_sq4&lt;br /&gt;
	xor a&lt;br /&gt;
	ld de,umul_tab + #1ff&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	ld h,d&lt;br /&gt;
	ld l,e&lt;br /&gt;
	inc e&lt;br /&gt;
	ld c,e&lt;br /&gt;
	ld b,2&lt;br /&gt;
&lt;br /&gt;
	.sq4_lp&lt;br /&gt;
	ld a,b&lt;br /&gt;
	cp 2&lt;br /&gt;
	ld a,e&lt;br /&gt;
	rra&lt;br /&gt;
	add (hl)&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	inc h&lt;br /&gt;
	inc d&lt;br /&gt;
	ld a,(hl)&lt;br /&gt;
	adc c&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld h,d&lt;br /&gt;
	inc l&lt;br /&gt;
	inc e&lt;br /&gt;
	jr nz,sq4_lp&lt;br /&gt;
	inc d&lt;br /&gt;
	inc d&lt;br /&gt;
	djnz sq4_lp&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
align #100&lt;br /&gt;
.umul_tab ds #400&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now for the actual multiply routine:&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', L = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ld h,umul_tab_lo / #100	; 2&lt;br /&gt;
	ld b,h			; 3&lt;br /&gt;
	add l			; 4&lt;br /&gt;
	ld c,a			; 5&lt;br /&gt;
	jr nc,@noovf		; 7&lt;br /&gt;
	inc b			; 8&lt;br /&gt;
	inc b			; 9&lt;br /&gt;
.@noovf&lt;br /&gt;
	sub l			; 10&lt;br /&gt;
	sub l			; 11&lt;br /&gt;
	jr nc,@noneg		; 13&lt;br /&gt;
	neg			; 15&lt;br /&gt;
.@noneg&lt;br /&gt;
	ld l,a			; 16&lt;br /&gt;
	ld a,(bc)		; 18&lt;br /&gt;
	sub (hl)		; 20&lt;br /&gt;
	ld e,a			; 21&lt;br /&gt;
	inc b			; 22&lt;br /&gt;
	inc h			; 23&lt;br /&gt;
	ld a,(bc)		; 25&lt;br /&gt;
	sbc (hl)		; 27&lt;br /&gt;
	ld d,a			; 28&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This code could easily be converted to a macro as it's only 24 bytes. I've tried to optimize it further but with no luck!&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 06:25, 4 April 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== 16bit * 16bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' BC = ''Multiplier'', DE = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A,HL = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;ld ix,0&lt;br /&gt;
 ld hl,0&lt;br /&gt;
.mul24b1:&lt;br /&gt;
 ld a,c&lt;br /&gt;
 or b&lt;br /&gt;
 jr z,mul24b3&lt;br /&gt;
 srl b&lt;br /&gt;
 rr c&lt;br /&gt;
 jr nc,mul24b2&lt;br /&gt;
 add ix,de&lt;br /&gt;
 ld a,h&lt;br /&gt;
 adc l&lt;br /&gt;
 ld h,a&lt;br /&gt;
.mul24b2:&lt;br /&gt;
 sla e&lt;br /&gt;
 rl d&lt;br /&gt;
 rl l&lt;br /&gt;
 jr mul24b1:&lt;br /&gt;
.mul24b3:&lt;br /&gt;
 ld a,h&lt;br /&gt;
 db #dd:ld e,l&lt;br /&gt;
 db #dd:ld d,h&lt;br /&gt;
 ex de,hl&lt;br /&gt;
 ret&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://map.tni.nl/articles/mult_div_shifts.php Multiplications and divisions on the MSX Assembly Page]&lt;br /&gt;
* [http://www.mccw.hetlab.tk/92/Multiplication/en.html &amp;quot;Multiplication on a Z80&amp;quot; ( MSX Computer &amp;amp; Club Webmagazine)]&lt;br /&gt;
* [http://www.andreadrian.de/oldcpu/Z80_number_cruncher.html The Z80 number cruncher (Andre Adrian)] (16/32bit multiplication, addition, right shift)&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94408</id>
		<title>Programming:Integer Multiplication</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94408"/>
				<updated>2015-10-18T09:56:18Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: some additions&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Classic 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' H = ''Multiplier'', E = ''Multiplicand'', L = 0, D = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''Clocks:''' 188-244 (216 on average)&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 33 bytes&lt;br /&gt;
&lt;br /&gt;
The additional clocks and bytes maybe required to set up D and L and for RET.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sla h  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+3&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
jr nc,$+3  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Classic 16bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', DE = ''Multiplicand'', HL = 0, C = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A:HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add a,a  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+4&lt;br /&gt;
ld h,d&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
rla   ; ...&lt;br /&gt;
jr nc,$+4  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
adc a,c  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Fast 8bit * 8bit Unsigned (using log / antilog tables) ==&lt;br /&gt;
&lt;br /&gt;
The original routine was written by Jeff Frohwein for the Nintendo Gameboy. You can find it on [http://www.devrs.com/gb/files/logmult.txt Devrs.com].&lt;br /&gt;
&lt;br /&gt;
Because of the usage of log / antilog tables this routine is less accurate, but very fast. It takes advantage of the fact that if you take the log of two numbers, add the results and then take the antilog of the total you have done the equivalent of multiplying the two numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 x^a * x^b = x^(a+b)&lt;br /&gt;
&lt;br /&gt;
 a * b = x^(logx(a) + logx(b))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Input:''' B = ''Multiplier'', C = ''Multiplicant''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''Clocks:''' 124&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 1024 bytes (768 bytes for the tables)&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' It is VERY approximate routine, e.g., 0*7=7, 1*28=27, 10*81=790, 100*100=9742, ...&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FastMult:&lt;br /&gt;
  ld      l,c&lt;br /&gt;
  ld      h,&amp;amp;82&lt;br /&gt;
  ld      d,(hl)          ; d = 32 * log_2(c)&lt;br /&gt;
  &lt;br /&gt;
  ld      l,b&lt;br /&gt;
  ld      a,(hl)          ; a = 32 * log_2(b)&lt;br /&gt;
  &lt;br /&gt;
  add     a,d&lt;br /&gt;
  ld      l,a&lt;br /&gt;
  ld      a,0&lt;br /&gt;
  adc     a,0&lt;br /&gt;
  ld      h,a             ; hl = d + a&lt;br /&gt;
  &lt;br /&gt;
  add     hl,hl&lt;br /&gt;
  set     2,h             ; hl = hl + $0400&lt;br /&gt;
  set     7,h             ; hl = hl + &amp;amp;8000&lt;br /&gt;
  &lt;br /&gt;
  ld      e,(hl)&lt;br /&gt;
  inc     hl&lt;br /&gt;
  ld      d,(hl)          ; de = 2^((hl)/32)&lt;br /&gt;
  &lt;br /&gt;
  ret&lt;br /&gt;
&lt;br /&gt;
; 32*Log_2(x) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 TO 255&lt;br /&gt;
;     C=4 &lt;br /&gt;
;     B=2&lt;br /&gt;
;     FOR Z=1 TO 10&lt;br /&gt;
;       IF (2^C) &amp;gt; A THEN C=C-B ELSE C=C+B&lt;br /&gt;
;       B=B/2&lt;br /&gt;
;     NEXT Z&lt;br /&gt;
;     PRINT INT(C*32);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8200&lt;br /&gt;
&lt;br /&gt;
logtable:&lt;br /&gt;
  db 0 , 0 , 32 , 50 , 64 , 74 , 82 , 89 , 96 , 101 , 106 , 110 , 114 , 118 , 121&lt;br /&gt;
  db 125 , 128 , 130 , 133 , 135 , 138 , 140 , 142 , 144 , 146 , 148 , 150 , 152&lt;br /&gt;
  db 153 , 155 , 157 , 158 , 160 , 161 , 162 , 164 , 165 , 166 , 167 , 169 , 170&lt;br /&gt;
  db 171 , 172 , 173 , 174 , 175 , 176 , 177 , 178 , 179 , 180 , 181 , 182 , 183&lt;br /&gt;
  db 184 , 185 , 185 , 186 , 187 , 188 , 189 , 189 , 190 , 191 , 192 , 192 , 193&lt;br /&gt;
  db 194 , 194 , 195 , 196 , 196 , 197 , 198 , 198 , 199 , 199 , 200 , 201 , 201&lt;br /&gt;
  db 202 , 202 , 203 , 204 , 204 , 205 , 205 , 206 , 206 , 207 , 207 , 208 , 208&lt;br /&gt;
  db 209 , 209 , 210 , 210 , 211 , 211 , 212 , 212 , 213 , 213 , 213 , 214 , 214&lt;br /&gt;
  db 215 , 215 , 216 , 216 , 217 , 217 , 217 , 218 , 218 , 219 , 219 , 219 , 220&lt;br /&gt;
  db 220 , 221 , 221 , 221 , 222 , 222 , 222 , 223 , 223 , 224 , 224 , 224 , 225&lt;br /&gt;
  db 225 , 225 , 226 , 226 , 226 , 227 , 227 , 227 , 228 , 228 , 228 , 229 , 229&lt;br /&gt;
  db 229 , 230 , 230 , 230 , 231 , 231 , 231 , 231 , 232 , 232 , 232 , 233 , 233&lt;br /&gt;
  db 233 , 234 , 234 , 234 , 234 , 235 , 235 , 235 , 236 , 236 , 236 , 236 , 237&lt;br /&gt;
  db 237 , 237 , 237 , 238 , 238 , 238 , 238 , 239 , 239 , 239 , 239 , 240 , 240&lt;br /&gt;
  db 240 , 241 , 241 , 241 , 241 , 241 , 242 , 242 , 242 , 242 , 243 , 243 , 243&lt;br /&gt;
  db 243 , 244 , 244 , 244 , 244 , 245 , 245 , 245 , 245 , 245 , 246 , 246 , 246&lt;br /&gt;
  db 246 , 247 , 247 , 247 , 247 , 247 , 248 , 248 , 248 , 248 , 249 , 249 , 249&lt;br /&gt;
  db 249 , 249 , 250 , 250 , 250 , 250 , 250 , 251 , 251 , 251 , 251 , 251 , 252&lt;br /&gt;
  db 252 , 252 , 252 , 252 , 253 , 253 , 253 , 253 , 253 , 253 , 254 , 254 , 254&lt;br /&gt;
  db 254 , 254 , 255 , 255 , 255 , 255 , 255&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; AntiLog 2^(x/32) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 to 510&lt;br /&gt;
;   PRINT INT(2^(A/32)+.5);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8400&lt;br /&gt;
&lt;br /&gt;
antilog:&lt;br /&gt;
  dw 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 , 4&lt;br /&gt;
  dw 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 6&lt;br /&gt;
  dw 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 8 , 9&lt;br /&gt;
  dw 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , 12 , 12 , 12&lt;br /&gt;
  dw 13 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17&lt;br /&gt;
  dw 18 , 18 , 19 , 19 , 19 , 20 , 20 , 21 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25&lt;br /&gt;
  dw 25 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , 30 , 31 , 31 , 32 , 33 , 33 , 34 , 35&lt;br /&gt;
  dw 36 , 36 , 37 , 38 , 39 , 40 , 41 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49&lt;br /&gt;
  dw 50 , 52 , 53 , 54 , 55 , 56 , 57 , 59 , 60 , 61 , 63 , 64 , 65 , 67 , 68 , 70&lt;br /&gt;
  dw 71 , 73 , 74 , 76 , 78 , 79 , 81 , 83 , 85 , 87 , 89 , 91 , 92 , 95 , 97 , 99&lt;br /&gt;
  dw 101 , 103 , 105 , 108 , 110 , 112 , 115 , 117 , 120 , 123 , 125 , 128 , 131&lt;br /&gt;
  dw 134 , 137 , 140 , 143 , 146 , 149 , 152 , 156 , 159 , 162 , 166 , 170 , 173&lt;br /&gt;
  dw 177 , 181 , 185 , 189 , 193 , 197 , 202 , 206 , 211 , 215 , 220 , 225 , 230&lt;br /&gt;
  dw 235 , 240 , 245 , 251 , 256 , 262 , 267 , 273 , 279 , 285 , 292 , 298 , 304&lt;br /&gt;
  dw 311 , 318 , 325 , 332 , 339 , 347 , 354 , 362 , 370 , 378 , 386 , 395 , 403&lt;br /&gt;
  dw 412 , 421 , 431 , 440 , 450 , 459 , 470 , 480 , 490 , 501 , 512 , 523 , 535&lt;br /&gt;
  dw 546 , 558 , 571 , 583 , 596 , 609 , 622 , 636 , 650 , 664 , 679 , 693 , 709&lt;br /&gt;
  dw 724 , 740 , 756 , 773 , 790 , 807 , 825 , 843 , 861 , 880 , 899 , 919 , 939&lt;br /&gt;
  dw 960 , 981 , 1002 , 1024 , 1046 , 1069 , 1093 , 1117 , 1141 , 1166 , 1192&lt;br /&gt;
  dw 1218 , 1244 , 1272 , 1300 , 1328 , 1357 , 1387 , 1417 , 1448 , 1480 , 1512&lt;br /&gt;
  dw 1545 , 1579 , 1614 , 1649 , 1685 , 1722 , 1760 , 1798 , 1838 , 1878 , 1919&lt;br /&gt;
  dw 1961 , 2004 , 2048 , 2093 , 2139 , 2186 , 2233 , 2282 , 2332 , 2383 , 2435&lt;br /&gt;
  dw 2489 , 2543 , 2599 , 2656 , 2714 , 2774 , 2834 , 2896 , 2960 , 3025 , 3091&lt;br /&gt;
  dw 3158 , 3228 , 3298 , 3371 , 3444 , 3520 , 3597 , 3676 , 3756 , 3838 , 3922&lt;br /&gt;
  dw 4008 , 4096 , 4186 , 4277 , 4371 , 4467 , 4565 , 4664 , 4767 , 4871 , 4978&lt;br /&gt;
  dw 5087 , 5198 , 5312 , 5428 , 5547 , 5668 , 5793 , 5919 , 6049 , 6182 , 6317&lt;br /&gt;
  dw 6455 , 6597 , 6741 , 6889 , 7039 , 7194 , 7351 , 7512 , 7677 , 7845 , 8016&lt;br /&gt;
  dw 8192 , 8371 , 8555 , 8742 , 8933 , 9129 , 9329 , 9533 , 9742 , 9955 , 10173&lt;br /&gt;
  dw 10396 , 10624 , 10856 , 11094 , 11337 , 11585 , 11839 , 12098 , 12363 , 12634&lt;br /&gt;
  dw 12910 , 13193 , 13482 , 13777 , 14079 , 14387 , 14702 , 15024 , 15353 , 15689&lt;br /&gt;
  dw 16033 , 16384 , 16743 , 17109 , 17484 , 17867 , 18258 , 18658 , 19066 , 19484&lt;br /&gt;
  dw 19911 , 20347 , 20792 , 21247 , 21713 , 22188 , 22674 , 23170 , 23678 , 24196&lt;br /&gt;
  dw 24726 , 25268 , 25821 , 26386 , 26964 , 27554 , 28158 , 28774 , 29404 , 30048&lt;br /&gt;
  dw 30706 , 31379 , 32066 , 32768 , 33485 , 34219 , 34968 , 35734 , 36516 , 37316&lt;br /&gt;
  dw 38133 , 38968 , 39821 , 40693 , 41584 , 42495 , 43425 , 44376 , 45348 , 46341&lt;br /&gt;
  dw 47356 , 48393 , 49452 , 50535 , 51642 , 52772 , 53928 , 55109 , 56316 , 57549&lt;br /&gt;
  dw  58809 , 60097 , 61413 , 62757&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Faster, accurate 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
I'm currently working on a new routine, based on a routine by Kirk Meyer [http://www.ticalc.org/pub/86/asm/source/routines/vfmult.asm] which uses nibble multiplication tables.&lt;br /&gt;
&lt;br /&gt;
I have a working, tested version which uses 16K of tables and can perform multiplication in 20&amp;amp;mu;s.&lt;br /&gt;
&lt;br /&gt;
The code to produce the tables is below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp1&lt;br /&gt;
ld a,l&lt;br /&gt;
rla&lt;br /&gt;
and #1e&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp1&lt;br /&gt;
inc h&lt;br /&gt;
.makelp2&lt;br /&gt;
ld a,l&lt;br /&gt;
rra:rra:rra&lt;br /&gt;
and #1e&lt;br /&gt;
jr z,usez&lt;br /&gt;
add restab2 - restab / 256 - 2&lt;br /&gt;
.usez&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp2&lt;br /&gt;
inc h			; restab&lt;br /&gt;
.makelp3&lt;br /&gt;
ld a,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
add l&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,0&lt;br /&gt;
adc d&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h:dec h:dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256 - 2&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
ld b,h&lt;br /&gt;
ld c,l&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp4&lt;br /&gt;
ld e,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
dec h&lt;br /&gt;
ex de,hl&lt;br /&gt;
add hl,hl:add hl,hl:add hl,hl:add hl,hl&lt;br /&gt;
ex de,hl&lt;br /&gt;
ld a,e&lt;br /&gt;
ld (bc),a&lt;br /&gt;
inc b&lt;br /&gt;
ld a,d&lt;br /&gt;
ld (bc),a&lt;br /&gt;
dec b&lt;br /&gt;
inc l&lt;br /&gt;
inc c&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
.restab2&lt;br /&gt;
ds 512 * 15&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code to perform the multiplication (DE = L * C):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ld h,hltab1 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
inc h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(bc)		; 10&lt;br /&gt;
add (hl)		; 12&lt;br /&gt;
ld e,a			; 13&lt;br /&gt;
inc b			; 14&lt;br /&gt;
inc h			; 15&lt;br /&gt;
ld a,(bc)		; 17&lt;br /&gt;
adc (hl)		; 19&lt;br /&gt;
ld d,a			; 20&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
16K is a lot of memory to use for tables, but I'm working on a way to reduce this to 8K while maintaining similar performance (around 26&amp;amp;mu;s). The idea is rather than using tables for the low and high nibbles, use tables for alternate bits. So there would be 16 tables for the values #00, #01, #04, #05, #10, #11, #14, #15, #40, #41, #44, #45, #50, #51, #54, #55. The values can be shifted by 1 (rather than 4) to give values for the alternate bits using a simple ADD HL,HL.&lt;br /&gt;
&lt;br /&gt;
This routine should be easy to adapt to a 16bit * 8bit unsigned multiplication or even a 16bit * 16bit, using simple additions.&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 03:58, 8 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
Ok, here is the new 8K routine, first the routine to build the tables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp5&lt;br /&gt;
ld a,l&lt;br /&gt;
ld bc,0&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
ld a,b&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,c&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp5&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp6&lt;br /&gt;
ld (hl),l&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp6&lt;br /&gt;
inc h:inc h&lt;br /&gt;
ld b,2&lt;br /&gt;
.makelp8&lt;br /&gt;
push bc&lt;br /&gt;
xor a&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
.makelp7&lt;br /&gt;
push hl&lt;br /&gt;
push af&lt;br /&gt;
call mulLbyA&lt;br /&gt;
ex de,hl&lt;br /&gt;
pop af&lt;br /&gt;
pop hl&lt;br /&gt;
ld (hl),e&lt;br /&gt;
inc h&lt;br /&gt;
ld (hl),d&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp7&lt;br /&gt;
inc h:inc h&lt;br /&gt;
pop bc&lt;br /&gt;
inc b&lt;br /&gt;
bit 4,b&lt;br /&gt;
jr z,makelp8&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
.mulLbyA	; MAX times	; MIN times&lt;br /&gt;
ld e,l		; 1		; 1&lt;br /&gt;
ld d,0		; 3		; 3&lt;br /&gt;
add a		; 4		; 4&lt;br /&gt;
ld h,a		; 5		; 5&lt;br /&gt;
jr c,ncad0	; 8		; 8&lt;br /&gt;
ld l,d		&lt;br /&gt;
.ncad0&lt;br /&gt;
add hl,hl	; 11		; 11&lt;br /&gt;
jr nc,ncad1	; 13		; 14&lt;br /&gt;
add hl,de	; 16&lt;br /&gt;
.ncad1&lt;br /&gt;
add hl,hl	; 19		; 17&lt;br /&gt;
jr nc,ncad2	; 21		; 20&lt;br /&gt;
add hl,de	; 24&lt;br /&gt;
.ncad2&lt;br /&gt;
add hl,hl	; 27		; 23&lt;br /&gt;
jr nc,ncad3	; 29		; 26&lt;br /&gt;
add hl,de	; 32&lt;br /&gt;
.ncad3&lt;br /&gt;
add hl,hl	; 35		; 29&lt;br /&gt;
jr nc,ncad4	; 37		; 32&lt;br /&gt;
add hl,de	; 40&lt;br /&gt;
.ncad4&lt;br /&gt;
add hl,hl	; 43		; 35&lt;br /&gt;
jr nc,ncad5	; 45		; 38&lt;br /&gt;
add hl,de	; 48&lt;br /&gt;
.ncad5&lt;br /&gt;
add hl,hl	; 51		; 41&lt;br /&gt;
jr nc,ncad6	; 53		; 44&lt;br /&gt;
add hl,de	; 56&lt;br /&gt;
.ncad6&lt;br /&gt;
add hl,hl	; 59		; 47&lt;br /&gt;
ld a,h		; 60		; 48&lt;br /&gt;
ret nc		; 61		; 50?&lt;br /&gt;
add hl,de	; 64&lt;br /&gt;
ld a,h		; 65&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the routine to do the multiplication:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.umultCL		; Using 8 bit only (25us - DE = L * C)&lt;br /&gt;
ld h,hltab2 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
dec h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(hl)		; 10&lt;br /&gt;
add a			; 11&lt;br /&gt;
inc h			; 12&lt;br /&gt;
ld d,(hl)		; 14&lt;br /&gt;
rl d			; 16&lt;br /&gt;
ld h,b			; 17&lt;br /&gt;
add (hl)		; 19&lt;br /&gt;
ld e,a			; 20&lt;br /&gt;
inc h			; 21&lt;br /&gt;
ld a,(hl)		; 23&lt;br /&gt;
adc d			; 24&lt;br /&gt;
ld d,a			; 25&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Very fast 8bit * 8bit Unsigned with only 1K of tables ==&lt;br /&gt;
&lt;br /&gt;
Here's a new routine I've developed which uses the formula ab = ((a + b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - (a - b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) / 4. It's based on a routine for the 6502 by Stephen Judd in a C= Hacking article. Because of differences between the way the 6502 does register indexing it was quite difficult to actually get this working, but it's a great compromise between speed and space since it only uses 1K of tables (as opposed to the 16K or 8K table routines above), and can still manage to do the job in a maximum of 28 microseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Firstly, once again, we need some code to generate the tables. These tables contain values for&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;/4 for 9 bit values of x, with the LSB when bit 8 is zero first followed by the MSB.&lt;br /&gt;
&amp;lt;pre&amp;gt;.gen_sq4&lt;br /&gt;
	xor a&lt;br /&gt;
	ld de,umul_tab + #1ff&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	ld h,d&lt;br /&gt;
	ld l,e&lt;br /&gt;
	inc e&lt;br /&gt;
	ld c,e&lt;br /&gt;
	ld b,2&lt;br /&gt;
&lt;br /&gt;
	.sq4_lp&lt;br /&gt;
	ld a,b&lt;br /&gt;
	cp 2&lt;br /&gt;
	ld a,e&lt;br /&gt;
	rra&lt;br /&gt;
	add (hl)&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	inc h&lt;br /&gt;
	inc d&lt;br /&gt;
	ld a,(hl)&lt;br /&gt;
	adc c&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld h,d&lt;br /&gt;
	inc l&lt;br /&gt;
	inc e&lt;br /&gt;
	jr nz,sq4_lp&lt;br /&gt;
	inc d&lt;br /&gt;
	inc d&lt;br /&gt;
	djnz sq4_lp&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
align #100&lt;br /&gt;
.umul_tab ds #400&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now for the actual multiply routine:&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', L = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ld h,umul_tab_lo / #100	; 2&lt;br /&gt;
	ld b,h			; 3&lt;br /&gt;
	add l			; 4&lt;br /&gt;
	ld c,a			; 5&lt;br /&gt;
	jr nc,@noovf		; 7&lt;br /&gt;
	inc b			; 8&lt;br /&gt;
	inc b			; 9&lt;br /&gt;
.@noovf&lt;br /&gt;
	sub l			; 10&lt;br /&gt;
	sub l			; 11&lt;br /&gt;
	jr nc,@noneg		; 13&lt;br /&gt;
	neg			; 15&lt;br /&gt;
.@noneg&lt;br /&gt;
	ld l,a			; 16&lt;br /&gt;
	ld a,(bc)		; 18&lt;br /&gt;
	sub (hl)		; 20&lt;br /&gt;
	ld e,a			; 21&lt;br /&gt;
	inc b			; 22&lt;br /&gt;
	inc h			; 23&lt;br /&gt;
	ld a,(bc)		; 25&lt;br /&gt;
	sbc (hl)		; 27&lt;br /&gt;
	ld d,a			; 28&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This code could easily be converted to a macro as it's only 24 bytes. I've tried to optimise it further but with no luck!&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 06:25, 4 April 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== 16bit * 16bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' BC = ''Multiplier'', DE = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A,HL = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;ld ix,0&lt;br /&gt;
 ld hl,0&lt;br /&gt;
.mul24b1:&lt;br /&gt;
 ld a,c&lt;br /&gt;
 or b&lt;br /&gt;
 jr z,mul24b3&lt;br /&gt;
 srl b&lt;br /&gt;
 rr c&lt;br /&gt;
 jr nc,mul24b2&lt;br /&gt;
 add ix,de&lt;br /&gt;
 ld a,h&lt;br /&gt;
 adc l&lt;br /&gt;
 ld h,a&lt;br /&gt;
.mul24b2:&lt;br /&gt;
 sla e&lt;br /&gt;
 rl d&lt;br /&gt;
 rl l&lt;br /&gt;
 jr mul24b1:&lt;br /&gt;
.mul24b3:&lt;br /&gt;
 ld a,h&lt;br /&gt;
 db #dd:ld e,l&lt;br /&gt;
 db #dd:ld d,h&lt;br /&gt;
 ex de,hl&lt;br /&gt;
 ret&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://map.tni.nl/articles/mult_div_shifts.php Multiplications and divisions on the MSX Assembly Page]&lt;br /&gt;
* [http://www.mccw.hetlab.tk/92/Multiplication/en.html &amp;quot;Multiplication on a Z80&amp;quot; ( MSX Computer &amp;amp; Club Webmagazine)]&lt;br /&gt;
* [http://www.andreadrian.de/oldcpu/Z80_number_cruncher.html The Z80 number cruncher (Andre Adrian)] (16/32bit multiplication, addition, right shift)&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94407</id>
		<title>Programming:Integer Multiplication</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Integer_Multiplication&amp;diff=94407"/>
				<updated>2015-10-18T09:01:54Z</updated>
		
		<summary type="html">&lt;p&gt;Litwr: added information about size and time of the execution&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Classic 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' H = ''Multiplier'', E = ''Multiplicand'', L = 0, D = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
'''Clocks:''' 188-244 (216 on average)&lt;br /&gt;
&lt;br /&gt;
'''Size:''' 33 bytes&lt;br /&gt;
&lt;br /&gt;
The additional clocks and bytes maybe required to set up D and L and for RET.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sla h  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+3&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
jr nc,$+3  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Classic 16bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', DE = ''Multiplicand'', HL = 0, C = 0&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A:HL = ''Product''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add a,a  ; optimised 1st iteration&lt;br /&gt;
jr nc,$+4&lt;br /&gt;
ld h,d&lt;br /&gt;
ld l,e&lt;br /&gt;
&lt;br /&gt;
add hl,hl  ; unroll 7 times&lt;br /&gt;
rla   ; ...&lt;br /&gt;
jr nc,$+4  ; ...&lt;br /&gt;
add hl,de  ; ...&lt;br /&gt;
adc a,c  ; ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Fast 8bit * 8bit Unsigned (using log / antilog tables) ==&lt;br /&gt;
&lt;br /&gt;
The original routine was written by Jeff Frohwein for the Nintendo Gameboy. You can find it on [http://www.devrs.com/gb/files/logmult.txt Devrs.com].&lt;br /&gt;
&lt;br /&gt;
Because of the usage of log / antilog tables this routine is less accurate, but very fast. It takes advantage of the fact that if you take the log of two numbers, add the results and then take the antilog of the total you have done the equivalent of multiplying the two numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 x^a * x^b = x^(a+b)&lt;br /&gt;
&lt;br /&gt;
 a * b = x^(logx(a) + logx(b))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Input:''' B = ''Multiplier'', C = ''Multiplicant''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FastMult:&lt;br /&gt;
  ld      l,c&lt;br /&gt;
  ld      h,&amp;amp;82&lt;br /&gt;
  ld      d,(hl)          ; d = 32 * log_2(c)&lt;br /&gt;
  &lt;br /&gt;
  ld      l,b&lt;br /&gt;
  ld      a,(hl)          ; a = 32 * log_2(b)&lt;br /&gt;
  &lt;br /&gt;
  add     a,d&lt;br /&gt;
  ld      l,a&lt;br /&gt;
  ld      a,0&lt;br /&gt;
  adc     a,0&lt;br /&gt;
  ld      h,a             ; hl = d + a&lt;br /&gt;
  &lt;br /&gt;
  add     hl,hl&lt;br /&gt;
  set     2,h             ; hl = hl + $0400&lt;br /&gt;
  set     7,h             ; hl = hl + &amp;amp;8000&lt;br /&gt;
  &lt;br /&gt;
  ld      e,(hl)&lt;br /&gt;
  inc     hl&lt;br /&gt;
  ld      d,(hl)          ; de = 2^((hl)/32)&lt;br /&gt;
  &lt;br /&gt;
  ret&lt;br /&gt;
&lt;br /&gt;
; 32*Log_2(x) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 TO 255&lt;br /&gt;
;     C=4 &lt;br /&gt;
;     B=2&lt;br /&gt;
;     FOR Z=1 TO 10&lt;br /&gt;
;       IF (2^C) &amp;gt; A THEN C=C-B ELSE C=C+B&lt;br /&gt;
;       B=B/2&lt;br /&gt;
;     NEXT Z&lt;br /&gt;
;     PRINT INT(C*32);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8200&lt;br /&gt;
&lt;br /&gt;
logtable:&lt;br /&gt;
  db 0 , 0 , 32 , 50 , 64 , 74 , 82 , 89 , 96 , 101 , 106 , 110 , 114 , 118 , 121&lt;br /&gt;
  db 125 , 128 , 130 , 133 , 135 , 138 , 140 , 142 , 144 , 146 , 148 , 150 , 152&lt;br /&gt;
  db 153 , 155 , 157 , 158 , 160 , 161 , 162 , 164 , 165 , 166 , 167 , 169 , 170&lt;br /&gt;
  db 171 , 172 , 173 , 174 , 175 , 176 , 177 , 178 , 179 , 180 , 181 , 182 , 183&lt;br /&gt;
  db 184 , 185 , 185 , 186 , 187 , 188 , 189 , 189 , 190 , 191 , 192 , 192 , 193&lt;br /&gt;
  db 194 , 194 , 195 , 196 , 196 , 197 , 198 , 198 , 199 , 199 , 200 , 201 , 201&lt;br /&gt;
  db 202 , 202 , 203 , 204 , 204 , 205 , 205 , 206 , 206 , 207 , 207 , 208 , 208&lt;br /&gt;
  db 209 , 209 , 210 , 210 , 211 , 211 , 212 , 212 , 213 , 213 , 213 , 214 , 214&lt;br /&gt;
  db 215 , 215 , 216 , 216 , 217 , 217 , 217 , 218 , 218 , 219 , 219 , 219 , 220&lt;br /&gt;
  db 220 , 221 , 221 , 221 , 222 , 222 , 222 , 223 , 223 , 224 , 224 , 224 , 225&lt;br /&gt;
  db 225 , 225 , 226 , 226 , 226 , 227 , 227 , 227 , 228 , 228 , 228 , 229 , 229&lt;br /&gt;
  db 229 , 230 , 230 , 230 , 231 , 231 , 231 , 231 , 232 , 232 , 232 , 233 , 233&lt;br /&gt;
  db 233 , 234 , 234 , 234 , 234 , 235 , 235 , 235 , 236 , 236 , 236 , 236 , 237&lt;br /&gt;
  db 237 , 237 , 237 , 238 , 238 , 238 , 238 , 239 , 239 , 239 , 239 , 240 , 240&lt;br /&gt;
  db 240 , 241 , 241 , 241 , 241 , 241 , 242 , 242 , 242 , 242 , 243 , 243 , 243&lt;br /&gt;
  db 243 , 244 , 244 , 244 , 244 , 245 , 245 , 245 , 245 , 245 , 246 , 246 , 246&lt;br /&gt;
  db 246 , 247 , 247 , 247 , 247 , 247 , 248 , 248 , 248 , 248 , 249 , 249 , 249&lt;br /&gt;
  db 249 , 249 , 250 , 250 , 250 , 250 , 250 , 251 , 251 , 251 , 251 , 251 , 252&lt;br /&gt;
  db 252 , 252 , 252 , 252 , 253 , 253 , 253 , 253 , 253 , 253 , 254 , 254 , 254&lt;br /&gt;
  db 254 , 254 , 255 , 255 , 255 , 255 , 255&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; AntiLog 2^(x/32) Table&lt;br /&gt;
;&lt;br /&gt;
;   FOR A=0 to 510&lt;br /&gt;
;   PRINT INT(2^(A/32)+.5);&amp;quot;,&amp;quot;;&lt;br /&gt;
;   NEXT A&lt;br /&gt;
ORG &amp;amp;8400&lt;br /&gt;
&lt;br /&gt;
antilog:&lt;br /&gt;
  dw 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2&lt;br /&gt;
  dw 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 , 4&lt;br /&gt;
  dw 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 6&lt;br /&gt;
  dw 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 8 , 9&lt;br /&gt;
  dw 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , 12 , 12 , 12&lt;br /&gt;
  dw 13 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17&lt;br /&gt;
  dw 18 , 18 , 19 , 19 , 19 , 20 , 20 , 21 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25&lt;br /&gt;
  dw 25 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , 30 , 31 , 31 , 32 , 33 , 33 , 34 , 35&lt;br /&gt;
  dw 36 , 36 , 37 , 38 , 39 , 40 , 41 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49&lt;br /&gt;
  dw 50 , 52 , 53 , 54 , 55 , 56 , 57 , 59 , 60 , 61 , 63 , 64 , 65 , 67 , 68 , 70&lt;br /&gt;
  dw 71 , 73 , 74 , 76 , 78 , 79 , 81 , 83 , 85 , 87 , 89 , 91 , 92 , 95 , 97 , 99&lt;br /&gt;
  dw 101 , 103 , 105 , 108 , 110 , 112 , 115 , 117 , 120 , 123 , 125 , 128 , 131&lt;br /&gt;
  dw 134 , 137 , 140 , 143 , 146 , 149 , 152 , 156 , 159 , 162 , 166 , 170 , 173&lt;br /&gt;
  dw 177 , 181 , 185 , 189 , 193 , 197 , 202 , 206 , 211 , 215 , 220 , 225 , 230&lt;br /&gt;
  dw 235 , 240 , 245 , 251 , 256 , 262 , 267 , 273 , 279 , 285 , 292 , 298 , 304&lt;br /&gt;
  dw 311 , 318 , 325 , 332 , 339 , 347 , 354 , 362 , 370 , 378 , 386 , 395 , 403&lt;br /&gt;
  dw 412 , 421 , 431 , 440 , 450 , 459 , 470 , 480 , 490 , 501 , 512 , 523 , 535&lt;br /&gt;
  dw 546 , 558 , 571 , 583 , 596 , 609 , 622 , 636 , 650 , 664 , 679 , 693 , 709&lt;br /&gt;
  dw 724 , 740 , 756 , 773 , 790 , 807 , 825 , 843 , 861 , 880 , 899 , 919 , 939&lt;br /&gt;
  dw 960 , 981 , 1002 , 1024 , 1046 , 1069 , 1093 , 1117 , 1141 , 1166 , 1192&lt;br /&gt;
  dw 1218 , 1244 , 1272 , 1300 , 1328 , 1357 , 1387 , 1417 , 1448 , 1480 , 1512&lt;br /&gt;
  dw 1545 , 1579 , 1614 , 1649 , 1685 , 1722 , 1760 , 1798 , 1838 , 1878 , 1919&lt;br /&gt;
  dw 1961 , 2004 , 2048 , 2093 , 2139 , 2186 , 2233 , 2282 , 2332 , 2383 , 2435&lt;br /&gt;
  dw 2489 , 2543 , 2599 , 2656 , 2714 , 2774 , 2834 , 2896 , 2960 , 3025 , 3091&lt;br /&gt;
  dw 3158 , 3228 , 3298 , 3371 , 3444 , 3520 , 3597 , 3676 , 3756 , 3838 , 3922&lt;br /&gt;
  dw 4008 , 4096 , 4186 , 4277 , 4371 , 4467 , 4565 , 4664 , 4767 , 4871 , 4978&lt;br /&gt;
  dw 5087 , 5198 , 5312 , 5428 , 5547 , 5668 , 5793 , 5919 , 6049 , 6182 , 6317&lt;br /&gt;
  dw 6455 , 6597 , 6741 , 6889 , 7039 , 7194 , 7351 , 7512 , 7677 , 7845 , 8016&lt;br /&gt;
  dw 8192 , 8371 , 8555 , 8742 , 8933 , 9129 , 9329 , 9533 , 9742 , 9955 , 10173&lt;br /&gt;
  dw 10396 , 10624 , 10856 , 11094 , 11337 , 11585 , 11839 , 12098 , 12363 , 12634&lt;br /&gt;
  dw 12910 , 13193 , 13482 , 13777 , 14079 , 14387 , 14702 , 15024 , 15353 , 15689&lt;br /&gt;
  dw 16033 , 16384 , 16743 , 17109 , 17484 , 17867 , 18258 , 18658 , 19066 , 19484&lt;br /&gt;
  dw 19911 , 20347 , 20792 , 21247 , 21713 , 22188 , 22674 , 23170 , 23678 , 24196&lt;br /&gt;
  dw 24726 , 25268 , 25821 , 26386 , 26964 , 27554 , 28158 , 28774 , 29404 , 30048&lt;br /&gt;
  dw 30706 , 31379 , 32066 , 32768 , 33485 , 34219 , 34968 , 35734 , 36516 , 37316&lt;br /&gt;
  dw 38133 , 38968 , 39821 , 40693 , 41584 , 42495 , 43425 , 44376 , 45348 , 46341&lt;br /&gt;
  dw 47356 , 48393 , 49452 , 50535 , 51642 , 52772 , 53928 , 55109 , 56316 , 57549&lt;br /&gt;
  dw  58809 , 60097 , 61413 , 62757&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Faster, accurate 8bit * 8bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
I'm currently working on a new routine, based on a routine by Kirk Meyer [http://www.ticalc.org/pub/86/asm/source/routines/vfmult.asm] which uses nibble multiplication tables.&lt;br /&gt;
&lt;br /&gt;
I have a working, tested version which uses 16K of tables and can perform multiplication in 20&amp;amp;mu;s.&lt;br /&gt;
&lt;br /&gt;
The code to produce the tables is below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp1&lt;br /&gt;
ld a,l&lt;br /&gt;
rla&lt;br /&gt;
and #1e&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp1&lt;br /&gt;
inc h&lt;br /&gt;
.makelp2&lt;br /&gt;
ld a,l&lt;br /&gt;
rra:rra:rra&lt;br /&gt;
and #1e&lt;br /&gt;
jr z,usez&lt;br /&gt;
add restab2 - restab / 256 - 2&lt;br /&gt;
.usez&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp2&lt;br /&gt;
inc h			; restab&lt;br /&gt;
.makelp3&lt;br /&gt;
ld a,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
add l&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,0&lt;br /&gt;
adc d&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h:dec h:dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256 - 2&lt;br /&gt;
jr nz,makelp3&lt;br /&gt;
ld b,h&lt;br /&gt;
ld c,l&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp4&lt;br /&gt;
ld e,(hl)&lt;br /&gt;
inc h&lt;br /&gt;
ld d,(hl)&lt;br /&gt;
dec h&lt;br /&gt;
ex de,hl&lt;br /&gt;
add hl,hl:add hl,hl:add hl,hl:add hl,hl&lt;br /&gt;
ex de,hl&lt;br /&gt;
ld a,e&lt;br /&gt;
ld (bc),a&lt;br /&gt;
inc b&lt;br /&gt;
ld a,d&lt;br /&gt;
ld (bc),a&lt;br /&gt;
dec b&lt;br /&gt;
inc l&lt;br /&gt;
inc c&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
inc h&lt;br /&gt;
inc h&lt;br /&gt;
inc b&lt;br /&gt;
inc b&lt;br /&gt;
ld a,h&lt;br /&gt;
cp restab2 / 256&lt;br /&gt;
jr nz,makelp4&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
.restab2&lt;br /&gt;
ds 512 * 15&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code to perform the multiplication (DE = L * C):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ld h,hltab1 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
inc h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(bc)		; 10&lt;br /&gt;
add (hl)		; 12&lt;br /&gt;
ld e,a			; 13&lt;br /&gt;
inc b			; 14&lt;br /&gt;
inc h			; 15&lt;br /&gt;
ld a,(bc)		; 17&lt;br /&gt;
adc (hl)		; 19&lt;br /&gt;
ld d,a			; 20&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
16K is a lot of memory to use for tables, but I'm working on a way to reduce this to 8K while maintaining similar performance (around 26&amp;amp;mu;s). The idea is rather than using tables for the low and high nibbles, use tables for alternate bits. So there would be 16 tables for the values #00, #01, #04, #05, #10, #11, #14, #15, #40, #41, #44, #45, #50, #51, #54, #55. The values can be shifted by 1 (rather than 4) to give values for the alternate bits using a simple ADD HL,HL.&lt;br /&gt;
&lt;br /&gt;
This routine should be easy to adapt to a 16bit * 8bit unsigned multiplication or even a 16bit * 16bit, using simple additions.&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 03:58, 8 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
Ok, here is the new 8K routine, first the routine to build the tables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.maketabs&lt;br /&gt;
ld hl,hltab1&lt;br /&gt;
.makelp5&lt;br /&gt;
ld a,l&lt;br /&gt;
ld bc,0&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
rla:rl b:rla:rl c&lt;br /&gt;
ld a,b&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
inc h&lt;br /&gt;
ld a,c&lt;br /&gt;
add a&lt;br /&gt;
add restab / 256&lt;br /&gt;
ld (hl),a&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp5&lt;br /&gt;
ld h,restab / 256 + 2&lt;br /&gt;
.makelp6&lt;br /&gt;
ld (hl),l&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp6&lt;br /&gt;
inc h:inc h&lt;br /&gt;
ld b,2&lt;br /&gt;
.makelp8&lt;br /&gt;
push bc&lt;br /&gt;
xor a&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
rr b:rra:rrca&lt;br /&gt;
.makelp7&lt;br /&gt;
push hl&lt;br /&gt;
push af&lt;br /&gt;
call mulLbyA&lt;br /&gt;
ex de,hl&lt;br /&gt;
pop af&lt;br /&gt;
pop hl&lt;br /&gt;
ld (hl),e&lt;br /&gt;
inc h&lt;br /&gt;
ld (hl),d&lt;br /&gt;
dec h&lt;br /&gt;
inc l&lt;br /&gt;
jr nz,makelp7&lt;br /&gt;
inc h:inc h&lt;br /&gt;
pop bc&lt;br /&gt;
inc b&lt;br /&gt;
bit 4,b&lt;br /&gt;
jr z,makelp8&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
.mulLbyA	; MAX times	; MIN times&lt;br /&gt;
ld e,l		; 1		; 1&lt;br /&gt;
ld d,0		; 3		; 3&lt;br /&gt;
add a		; 4		; 4&lt;br /&gt;
ld h,a		; 5		; 5&lt;br /&gt;
jr c,ncad0	; 8		; 8&lt;br /&gt;
ld l,d		&lt;br /&gt;
.ncad0&lt;br /&gt;
add hl,hl	; 11		; 11&lt;br /&gt;
jr nc,ncad1	; 13		; 14&lt;br /&gt;
add hl,de	; 16&lt;br /&gt;
.ncad1&lt;br /&gt;
add hl,hl	; 19		; 17&lt;br /&gt;
jr nc,ncad2	; 21		; 20&lt;br /&gt;
add hl,de	; 24&lt;br /&gt;
.ncad2&lt;br /&gt;
add hl,hl	; 27		; 23&lt;br /&gt;
jr nc,ncad3	; 29		; 26&lt;br /&gt;
add hl,de	; 32&lt;br /&gt;
.ncad3&lt;br /&gt;
add hl,hl	; 35		; 29&lt;br /&gt;
jr nc,ncad4	; 37		; 32&lt;br /&gt;
add hl,de	; 40&lt;br /&gt;
.ncad4&lt;br /&gt;
add hl,hl	; 43		; 35&lt;br /&gt;
jr nc,ncad5	; 45		; 38&lt;br /&gt;
add hl,de	; 48&lt;br /&gt;
.ncad5&lt;br /&gt;
add hl,hl	; 51		; 41&lt;br /&gt;
jr nc,ncad6	; 53		; 44&lt;br /&gt;
add hl,de	; 56&lt;br /&gt;
.ncad6&lt;br /&gt;
add hl,hl	; 59		; 47&lt;br /&gt;
ld a,h		; 60		; 48&lt;br /&gt;
ret nc		; 61		; 50?&lt;br /&gt;
add hl,de	; 64&lt;br /&gt;
ld a,h		; 65&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
ds -$ and #ff&lt;br /&gt;
&lt;br /&gt;
.hltab1&lt;br /&gt;
ds 256&lt;br /&gt;
.hltab2&lt;br /&gt;
ds 256&lt;br /&gt;
.restab&lt;br /&gt;
ds 512 * 16&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the routine to do the multiplication:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.umultCL		; Using 8 bit only (25us - DE = L * C)&lt;br /&gt;
ld h,hltab2 / 256	; 2&lt;br /&gt;
ld b,(hl)		; 4&lt;br /&gt;
dec h			; 5&lt;br /&gt;
ld h,(hl)		; 7&lt;br /&gt;
ld l,c			; 8&lt;br /&gt;
ld a,(hl)		; 10&lt;br /&gt;
add a			; 11&lt;br /&gt;
inc h			; 12&lt;br /&gt;
ld d,(hl)		; 14&lt;br /&gt;
rl d			; 16&lt;br /&gt;
ld h,b			; 17&lt;br /&gt;
add (hl)		; 19&lt;br /&gt;
ld e,a			; 20&lt;br /&gt;
inc h			; 21&lt;br /&gt;
ld a,(hl)		; 23&lt;br /&gt;
adc d			; 24&lt;br /&gt;
ld d,a			; 25&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Very fast 8bit * 8bit Unsigned with only 1K of tables ==&lt;br /&gt;
&lt;br /&gt;
Here's a new routine I've developed which uses the formula ab = ((a + b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; - (a - b)&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;) / 4. It's based on a routine for the 6502 by Stephen Judd in a C= Hacking article. Because of differences between the way the 6502 does register indexing it was quite difficult to actually get this working, but it's a great compromise between speed and space since it only uses 1K of tables (as opposed to the 16K or 8K table routines above), and can still manage to do the job in a maximum of 28 microseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Firstly, once again, we need some code to generate the tables. These tables contain values for&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;/4 for 9 bit values of x, with the LSB when bit 8 is zero first followed by the MSB.&lt;br /&gt;
&amp;lt;pre&amp;gt;.gen_sq4&lt;br /&gt;
	xor a&lt;br /&gt;
	ld de,umul_tab + #1ff&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	ld h,d&lt;br /&gt;
	ld l,e&lt;br /&gt;
	inc e&lt;br /&gt;
	ld c,e&lt;br /&gt;
	ld b,2&lt;br /&gt;
&lt;br /&gt;
	.sq4_lp&lt;br /&gt;
	ld a,b&lt;br /&gt;
	cp 2&lt;br /&gt;
	ld a,e&lt;br /&gt;
	rra&lt;br /&gt;
	add (hl)&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	inc h&lt;br /&gt;
	inc d&lt;br /&gt;
	ld a,(hl)&lt;br /&gt;
	adc c&lt;br /&gt;
	ld (de),a&lt;br /&gt;
	dec d&lt;br /&gt;
	ld h,d&lt;br /&gt;
	inc l&lt;br /&gt;
	inc e&lt;br /&gt;
	jr nz,sq4_lp&lt;br /&gt;
	inc d&lt;br /&gt;
	inc d&lt;br /&gt;
	djnz sq4_lp&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
align #100&lt;br /&gt;
.umul_tab ds #400&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now for the actual multiply routine:&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''Multiplier'', L = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' DE = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ld h,umul_tab_lo / #100	; 2&lt;br /&gt;
	ld b,h			; 3&lt;br /&gt;
	add l			; 4&lt;br /&gt;
	ld c,a			; 5&lt;br /&gt;
	jr nc,@noovf		; 7&lt;br /&gt;
	inc b			; 8&lt;br /&gt;
	inc b			; 9&lt;br /&gt;
.@noovf&lt;br /&gt;
	sub l			; 10&lt;br /&gt;
	sub l			; 11&lt;br /&gt;
	jr nc,@noneg		; 13&lt;br /&gt;
	neg			; 15&lt;br /&gt;
.@noneg&lt;br /&gt;
	ld l,a			; 16&lt;br /&gt;
	ld a,(bc)		; 18&lt;br /&gt;
	sub (hl)		; 20&lt;br /&gt;
	ld e,a			; 21&lt;br /&gt;
	inc b			; 22&lt;br /&gt;
	inc h			; 23&lt;br /&gt;
	ld a,(bc)		; 25&lt;br /&gt;
	sbc (hl)		; 27&lt;br /&gt;
	ld d,a			; 28&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This code could easily be converted to a macro as it's only 24 bytes. I've tried to optimise it further but with no luck!&lt;br /&gt;
&lt;br /&gt;
[[User:Executioner|Executioner]] 06:25, 4 April 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== 16bit * 16bit Unsigned ==&lt;br /&gt;
&lt;br /&gt;
'''Input:''' BC = ''Multiplier'', DE = ''Multiplicand''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A,HL = ''Product''&lt;br /&gt;
&amp;lt;pre&amp;gt;ld ix,0&lt;br /&gt;
 ld hl,0&lt;br /&gt;
.mul24b1:&lt;br /&gt;
 ld a,c&lt;br /&gt;
 or b&lt;br /&gt;
 jr z,mul24b3&lt;br /&gt;
 srl b&lt;br /&gt;
 rr c&lt;br /&gt;
 jr nc,mul24b2&lt;br /&gt;
 add ix,de&lt;br /&gt;
 ld a,h&lt;br /&gt;
 adc l&lt;br /&gt;
 ld h,a&lt;br /&gt;
.mul24b2:&lt;br /&gt;
 sla e&lt;br /&gt;
 rl d&lt;br /&gt;
 rl l&lt;br /&gt;
 jr mul24b1:&lt;br /&gt;
.mul24b3:&lt;br /&gt;
 ld a,h&lt;br /&gt;
 db #dd:ld e,l&lt;br /&gt;
 db #dd:ld d,h&lt;br /&gt;
 ex de,hl&lt;br /&gt;
 ret&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://map.tni.nl/articles/mult_div_shifts.php Multiplications and divisions on the MSX Assembly Page]&lt;br /&gt;
* [http://www.mccw.hetlab.tk/92/Multiplication/en.html &amp;quot;Multiplication on a Z80&amp;quot; ( MSX Computer &amp;amp; Club Webmagazine)]&lt;br /&gt;
* [http://www.andreadrian.de/oldcpu/Z80_number_cruncher.html The Z80 number cruncher (Andre Adrian)] (16/32bit multiplication, addition, right shift)&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Litwr</name></author>	</entry>

	</feed>