mirror of
https://github.com/gbdk-2020/gbdk-2020.git
synced 2026-02-20 00:32:21 +01:00
@@ -29,7 +29,8 @@
|
|||||||
;--------------------------------------------------------------------------
|
;--------------------------------------------------------------------------
|
||||||
|
|
||||||
;; Originally from GBDK by Pascal Felber.
|
;; Originally from GBDK by Pascal Felber.
|
||||||
|
;; Updated by Phidias618.
|
||||||
|
|
||||||
.module mul
|
.module mul
|
||||||
.area _CODE
|
.area _CODE
|
||||||
|
|
||||||
@@ -41,118 +42,83 @@
|
|||||||
|
|
||||||
; operands with different sign
|
; operands with different sign
|
||||||
|
|
||||||
__mulsuchar:
|
|
||||||
ld c, a
|
|
||||||
jr signexte
|
|
||||||
|
|
||||||
__muluschar:
|
__muluschar:
|
||||||
ld c, e
|
ld b, a
|
||||||
ld e, a
|
ld a, e
|
||||||
|
ld e, b
|
||||||
signexte:
|
__mulsuchar:
|
||||||
ld a,e
|
; sign extends E while preserving A
|
||||||
rla
|
ld l, #0
|
||||||
sbc a,a
|
ld d, l
|
||||||
ld d,a
|
bit 7, e
|
||||||
|
jr z, .mul_acc_adel
|
||||||
xor a
|
dec d
|
||||||
jr .mul8
|
jr .mul_acc_adel
|
||||||
|
|
||||||
__mulschar:
|
|
||||||
; Sign-extend before going in.
|
|
||||||
ld c,a
|
|
||||||
|
|
||||||
rla
|
|
||||||
sbc a,a
|
|
||||||
ld b,a
|
|
||||||
|
|
||||||
ld a,e
|
|
||||||
rla
|
|
||||||
sbc a,a
|
|
||||||
ld d,a
|
|
||||||
|
|
||||||
__mulint:
|
|
||||||
;; 16-bit multiplication
|
|
||||||
;;
|
|
||||||
;; Entry conditions
|
|
||||||
;; BC = multiplicand
|
|
||||||
;; DE = multiplier
|
|
||||||
;;
|
|
||||||
;; Exit conditions
|
|
||||||
;; BC = less significant word of product
|
|
||||||
;;
|
|
||||||
;; Register used: AF,BC,DE,HL
|
|
||||||
.mul16:
|
|
||||||
;; Let the smaller number loop
|
|
||||||
ld a,b
|
|
||||||
cp a,d
|
|
||||||
jr c, keep
|
|
||||||
;; d <= b
|
|
||||||
ld a, e
|
|
||||||
ld e, c
|
|
||||||
ld c, a
|
|
||||||
ld a, d
|
|
||||||
ld d, b
|
|
||||||
ld b, a
|
|
||||||
keep:
|
|
||||||
;; Optimise for the case when this side has 8 bits of data or
|
|
||||||
;; less. This is often the case with support address calls.
|
|
||||||
or a
|
|
||||||
jp Z, .mul8
|
|
||||||
|
|
||||||
ld l,#0
|
|
||||||
ld b,#16
|
|
||||||
loop16:
|
|
||||||
;; Taken from z88dk, which originally borrowed from the
|
|
||||||
;; Spectrum rom.
|
|
||||||
add hl,hl
|
|
||||||
rl c
|
|
||||||
rla ;DLE 27/11/98
|
|
||||||
jr NC,skip16
|
|
||||||
add hl,de
|
|
||||||
skip16:
|
|
||||||
dec b
|
|
||||||
jr NZ,loop16
|
|
||||||
|
|
||||||
;; Return in bc
|
|
||||||
ld c,l
|
|
||||||
ld b,h
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
__muluchar:
|
__muluchar:
|
||||||
ld c, a
|
ld l, #0
|
||||||
xor a
|
ld d, l
|
||||||
;; Clear the top
|
jr .mul_acc_adel
|
||||||
ld d, a
|
__mulschar:
|
||||||
|
; sign extends A into BC
|
||||||
|
ld c, a
|
||||||
|
add a
|
||||||
|
sbc a
|
||||||
|
ld b, a
|
||||||
|
|
||||||
|
; sign extends E into DE
|
||||||
|
ld a, e
|
||||||
|
add a
|
||||||
|
sbc a
|
||||||
|
ld d, a
|
||||||
|
; Fall through __mulint
|
||||||
|
__mulint:
|
||||||
|
; computes BC * DE by using the following identity :
|
||||||
|
; BC * DE = (B * E * 256) + (C * DE)
|
||||||
|
|
||||||
|
; if D = 0 computes E * BC instead
|
||||||
|
ld a, d
|
||||||
|
OR a
|
||||||
|
jr z, shortcut_swap
|
||||||
|
|
||||||
|
; computes B * E
|
||||||
|
xor a
|
||||||
|
sla b
|
||||||
|
jr nc, 0$
|
||||||
|
add e
|
||||||
|
0$:
|
||||||
|
; skips the rest of the loop if either B = 0 or (B >= 128 and E = 0)
|
||||||
|
jr z, .mul_acc_cdea
|
||||||
|
.irp label, 1$, 2$, 3$, 4$, 5$, 6$, 7$
|
||||||
|
add a
|
||||||
|
sla b
|
||||||
|
jr nc, label
|
||||||
|
add e
|
||||||
|
label:
|
||||||
|
.endm
|
||||||
|
; B * E is now stored in A
|
||||||
|
|
||||||
|
.mul_acc_cdea:
|
||||||
|
; computes (C * DE) + (256 * A)
|
||||||
|
ld l, a
|
||||||
|
ld a, c
|
||||||
|
.mul_acc_adel:
|
||||||
|
; computes (A * DE) + (256 * L)
|
||||||
|
.irp label, 0$, 1$, 2$, 3$, 4$, 5$, 6$, 7$
|
||||||
|
add hl, hl
|
||||||
|
add a
|
||||||
|
jr nc, label
|
||||||
|
add hl, de
|
||||||
|
label:
|
||||||
|
.endm
|
||||||
|
ld b, h
|
||||||
|
ld c, l
|
||||||
|
ret
|
||||||
|
|
||||||
;; Version that uses an 8bit multiplicand
|
shortcut_swap:
|
||||||
;;
|
ld l, a ; a = 0
|
||||||
;; Entry conditions
|
ld a, e
|
||||||
;; C = multiplicand
|
ld d, b
|
||||||
;; DE = multiplier
|
ld e, c
|
||||||
;; A = 0
|
jr .mul_acc_adel
|
||||||
;;
|
|
||||||
;; Exit conditions
|
|
||||||
;; BC = less significant word of product
|
|
||||||
;;
|
|
||||||
;; Register used: AF,BC,DE,HL
|
|
||||||
.mul8:
|
|
||||||
ld l,a
|
|
||||||
ld b,#8
|
|
||||||
ld a,c
|
|
||||||
loop8:
|
|
||||||
add hl,hl
|
|
||||||
rla
|
|
||||||
jr NC,skip8
|
|
||||||
add hl,de
|
|
||||||
skip8:
|
|
||||||
dec b
|
|
||||||
jr NZ,loop8
|
|
||||||
|
|
||||||
;; Return in bc
|
|
||||||
ld c,l
|
|
||||||
ld b,h
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user