Difference between revisions of "Z80 Routines:Math:Division"
m (→Rounded 16/8 division) |
(Added 32/16 division) |
||
| Line 119: | Line 119: | ||
ret | ret | ||
| + | </nowiki> | ||
| + | == 32/16 division == | ||
| + | |||
| + | The following routine divides acix by de and places the quotient in acix and the remainder in hl | ||
| + | |||
| + | <nowiki> | ||
| + | Div32By16: | ||
| + | ; IN: ACIX=dividend, DE=divisor | ||
| + | ; OUT: ACIX=quotient, DE=divisor, HL=remainder, B=0 | ||
| + | ld hl,0 | ||
| + | ld b,32 | ||
| + | Div32By16_Loop: | ||
| + | add ix,ix | ||
| + | rl c | ||
| + | rla | ||
| + | adc hl,hl | ||
| + | jr c,Div32By16_Overflow | ||
| + | sbc hl,de | ||
| + | jr nc,Div32By16_SetBit | ||
| + | add hl,de | ||
| + | djnz Div32By16_Loop | ||
| + | ret | ||
| + | Div32By16_Overflow: | ||
| + | or a | ||
| + | sbc hl,de | ||
| + | Div32By16_SetBit: | ||
| + | .db $DD,$2C ; inc ixl, change to inc ix to avoid undocumented | ||
| + | djnz Div32By16_Loop | ||
| + | ret | ||
</nowiki> | </nowiki> | ||
Revision as of 15:14, 10 July 2012
Contents
Introduction
All these routines use the restoring division algorithm, adapted to the z80 architecture to maximize speed. They can easily be unrolled to gain some speed.
8/8 division
The following routine divides d by e and places the quotient in d and the remainder in a
div_d_e: xor a ld b, 8 _loop: sla d rla cp e jr c, $+4 sub e inc d djnz _loop ret
16/8 division
The following routine divides hl by c and places the quotient in hl and the remainder in a
div_hl_c: xor a ld b, 16 _loop: add hl, hl rla cp c jr c, $+4 sub c inc l djnz _loop ret
16/16 division
The following routine divides ac by de and places the quotient in ac and the remainder in hl
div_ac_de: ld hl, 0 ld b, 16 _loop: sll c rla adc hl, hl sbc hl, de jr nc, $+4 add hl, de dec c djnz _loop ret
24/8 division
The following routine divides ehl by d and places the quotient in ehl and the remainder in a
div_ehl_d: xor a ld b, 24 _loop: add hl, hl rl e rla cp d jr c, $+4 sub d inc l djnz _loop ret
32/8 division
The following routine divides dehl by c and places the quotient in dehl and the remainder in a
div_dehl_c: xor a ld b, 32 _loop: add hl, hl rl e rl d rla cp c jr c, $+4 sub c inc l djnz _loop ret
32/16 division
The following routine divides acix by de and places the quotient in acix and the remainder in hl
Div32By16: ; IN: ACIX=dividend, DE=divisor ; OUT: ACIX=quotient, DE=divisor, HL=remainder, B=0 ld hl,0 ld b,32 Div32By16_Loop: add ix,ix rl c rla adc hl,hl jr c,Div32By16_Overflow sbc hl,de jr nc,Div32By16_SetBit add hl,de djnz Div32By16_Loop ret Div32By16_Overflow: or a sbc hl,de Div32By16_SetBit: .db $DD,$2C ; inc ixl, change to inc ix to avoid undocumented djnz Div32By16_Loop ret
Rounded 16/8 division
The following routine divides hl by c and places the rounded quotient in hl and twice the prerounded remainder in a.
RoundHL_Div_C: xor a ld b, 16 _loop: add hl, hl rla cp c jr c, $+4 sub c inc l djnz _loop ;This part is the rounding add a,a cp c ret c inc hl ret