Difference between revisions of "Programming:Integer Division"
From CPCWiki - THE Amstrad CPC encyclopedia!
								
												
				|  (→Web links:  added link to division routines for the Sega Master System) |  (the new fast division added) | ||
| Line 169: | Line 169: | ||
| </pre> | </pre> | ||
| + | |||
| + | == Fast 32bit division == | ||
| + | |||
| + | '''Input:''' HL,DE=Value1, BC=Value2 | ||
| + | |||
| + | '''Output:''' BCDE=Value1/Value2, HL=Value1 MOD Value2 | ||
| + | |||
| + | '''Destroyed:''' AF | ||
| + | |||
| + | '''Not used:''' IX, IY | ||
| + | |||
| + | <pre> | ||
| + |  div macro | ||
| + |      local t1,t2 | ||
| + |      ADD   HL, HL | ||
| + |      EX    DE, HL | ||
| + |      ADD   HL, HL | ||
| + |      EX    DE, HL | ||
| + |      JP    NC, t1 | ||
| + | |||
| + |      INC   HL | ||
| + |  t1 | ||
| + |      LD    A, L | ||
| + |      ADD   A, C | ||
| + |      LD    A, H | ||
| + |      ADC   A, B | ||
| + |      JP    NC, t2 | ||
| + | |||
| + |      ADD   HL, BC | ||
| + |      INC   DE | ||
| + |  t2 | ||
| + |      endm | ||
| + | |||
| + |  div32x16 proc  ; BCDE = HLDE/BC, HL = HLDE%BC | ||
| + |      local t1, DIV32_, DIV320 | ||
| + |      DEC   BC | ||
| + |      LD    A, B | ||
| + |      CPL  | ||
| + |      LD    B, A | ||
| + |      LD    A, C | ||
| + |      CPL  | ||
| + |      LD    C, A | ||
| + |      ADD   A, L | ||
| + |      LD    A, B | ||
| + |      ADC   A, H | ||
| + |      JP    NC, DIV32_ | ||
| + | |||
| + |      PUSH  DE | ||
| + |      EX    DE, HL | ||
| + |      LD    HL, 0000 | ||
| + |      CALL  DIV320 | ||
| + |      EX    DE, HL | ||
| + |      EX    (SP), HL | ||
| + |      EX    DE, HL | ||
| + |      CALL  DIV320 | ||
| + |      POP   BC | ||
| + |      RET | ||
| + |  DIV32_ | ||
| + |      CALL  DIV320 | ||
| + |      LD    BC, 0000 | ||
| + |      RET | ||
| + |  DIV320   ; DE = HLDE/(-BC), HL = HLDE%(-BC) | ||
| + |      CALL  t1 | ||
| + |  t1 | ||
| + |      rept 8 | ||
| + |      div | ||
| + |      endm | ||
| + |      RET | ||
| + |      endp  | ||
| + | </pre> | ||
| == Web links == | == Web links == | ||
Revision as of 11:23, 14 November 2015
Contents
8bit division
Input: HL=Value1, C=Value2
Output: L=Value1/Value2, H=Value1 MOD Value2
Destroyed: AF,BC
        LD B,8
Div_Next:
        ADD     HL,HL
        LD      A,H
        SUB     C
        JR      C,Div_NXTB
        LD      H,A
        INC     L
Div_NXTB:
        DJNZ    Div_Next
        RET
16bit division
Input: BC=Value1, DE=Value2
Output: HL=Value1/Value2, DE=Value1 MOD Value2
Destroyed: AF,BC
clcd16  ld a,e
        or d
        ld hl,0
        ret z
        ld a,b
        ld b,16
clcd161 rl c
        rla
        adc hl,hl
        sbc hl,de
        jr nc,clcd162
        add hl,de
clcd162 ccf
        djnz clcd161
        ex de,hl
        rl c
        rla
        ld h,a
        ld l,c
        ret
24bit division
Input: A,BC=Value1, DE=Value2
Output: HL=Value1/Value2, DE=Value1 MOD Value2
Destroyed: AF,BC,IX,IYL
clcdiv  db #dd:ld l,e
        db #dd:ld h,d   ;IX=Value2
        ld e,a          ;E,BC=Value1(Counter)
        ld hl,0
        db #dd:ld a,l
        db #dd:or h
        ret z
        ld d,l          ;D,HL=CalcVar
        db #fd:ld l,24  ;IYL=Counter
clcdiv1 rl c
        rl b
        rl e
        rl l
        rl h
        rl d
        ld a,l
        db #dd:sub l
        ld l,a
        ld a,h
        db #dd:sbc h
        ld h,a
        ld a,d
        sbc 0
        ld d,a          ;D,HL=D,HL-IX
        jr nc,clcdiv2
        ld a,l
        db #dd:add l
        ld l,a
        ld a,h
        db #dd:adc h
        ld h,a
        ld a,d
        adc 0
        ld d,a
        scf
clcdiv2 ccf
        db #fd:dec l
        jr nz,clcdiv1
        ex de,hl        ;DE=Value1 MOD Value2
        rl c
        rl b
        ld l,c
        ld h,b          ;HL=Value1 DIV Value2
        ret
32bit division
Input: IY,BC=Value1, IX=Value2
Output: IY,BC=Value1/Value2, HL=Value1 MOD Value2
Destroyed: AF,DE,IY
clcd32c db 0
clcd32  ld hl,0
        db #dd:ld a,l
        db #dd:or h
        ret z           ;IY,BC=Value1(Counter)
        ld de,0         ;DE,HL=CalcVar
        ld a,32         ;Set Counter to 32
clcd321 ld (clcd32c),a
        rl c
        rl b
        db #fd:ld a,l:rla:db #fd:ld l,a
        db #fd:ld a,h:rla:db #fd:ld h,a
        rl l
        rl h
        rl e
        rl d
        ld a,l
        db #dd:sub l
        ld l,a
        ld a,h
        db #dd:sbc h
        ld h,a
        ld a,e
        sbc 0
        ld e,a
        ld a,d
        sbc 0
        ld d,a
        jr nc,clcd322
        ld a,l
        db #dd:add l
        ld l,a
        ld a,h
        db #dd:adc h
        ld h,a
        ld a,e
        adc 0
        ld e,a
        ld a,d
        adc 0
        ld d,a
        scf
clcd322 ccf
        ld a,(clcd32c)
        dec a
        jr nz,clcd321   ;HL=Value1 MOD Value2
        rl c
        rl b
        db #fd:ld a,l:rla:db #fd:ld l,a
        db #fd:ld a,h:rla:db #fd:ld h,a
        ret             ;IY,BC=Value1 DIV Value2
Fast 32bit division
Input: HL,DE=Value1, BC=Value2
Output: BCDE=Value1/Value2, HL=Value1 MOD Value2
Destroyed: AF
Not used: IX, IY
 div macro
     local t1,t2
     ADD   HL, HL
     EX    DE, HL
     ADD   HL, HL
     EX    DE, HL
     JP    NC, t1
     INC   HL
 t1
     LD    A, L
     ADD   A, C
     LD    A, H
     ADC   A, B
     JP    NC, t2
     ADD   HL, BC
     INC   DE
 t2
     endm
 div32x16 proc  ; BCDE = HLDE/BC, HL = HLDE%BC
     local t1, DIV32_, DIV320
     DEC   BC
     LD    A, B
     CPL 
     LD    B, A
     LD    A, C
     CPL 
     LD    C, A
     ADD   A, L
     LD    A, B
     ADC   A, H
     JP    NC, DIV32_
     PUSH  DE
     EX    DE, HL
     LD    HL, 0000
     CALL  DIV320
     EX    DE, HL
     EX    (SP), HL
     EX    DE, HL
     CALL  DIV320
     POP   BC
     RET
 DIV32_
     CALL  DIV320
     LD    BC, 0000
     RET
 DIV320   ; DE = HLDE/(-BC), HL = HLDE%(-BC)
     CALL  t1
 t1
     rept 8
     div
     endm
     RET
     endp 
