👏

Z80符号付き16ビット乗算ルーチン

に公開

Z80の符号付き16ビット乗算ルーチンです。HL=HL*DE、

デザイン、僕。コーディング、ChatGPT。

; =================================================
; Z80 Signed 16-bit Multiply
; HL = HL * DE
; =================================================
; input :
;   HL = multiplicand (signed)
;   DE = multiplier   (signed)
;
; output:
;   HL = result (lower 16-bit)
;
; destroys:
;   AF, BC, DE
; =================================================

            ; -------------------------------
            ; Signed multiply entry
            ; -------------------------------
MUL16S:
            ; ---- determine sign (HL ^ DE) ----
            ld      A,H
            xor     D
            and     80h
            push    AF              ; save result sign

            ; ---- HL = abs(HL) ----
            bit     7,H
            jr      z,MUL_HL_POS
            xor     A
            sub     L
            ld      L,A
            sbc     A,A
            sub     H
            ld      H,A
MUL_HL_POS:

            ; ---- DE = abs(DE) ----
            bit     7,D
            jr      z,MUL_DE_POS
            xor     A
            sub     E
            ld      E,A
            sbc     A,A
            sub     D
            ld      D,A
MUL_DE_POS:

            ; ---- unsigned multiply ----
            call    MUL16U

            ; ---- restore sign ----
            pop     AF
            jr      z,MUL_END

            ; HL = -HL
            xor     A
            sub     L
            ld      L,A
            sbc     A,A
            sub     H
            ld      H,A

MUL_END:
            ret


; =================================================
; Unsigned 16-bit Multiply
; HL = HL * DE
; =================================================
; input :
;   HL = multiplicand
;   DE = multiplier
;
; output:
;   HL = result (lower 16-bit)
;
; destroys:
;   AF, BC, DE
; =================================================

MUL16U:
            ld      BC,HL           ; BC = multiplicand
            ld      HL,0            ; HL = result
            ld      A,16

MUL16U_LOOP:
            srl     E
            rr      D               ; DE >>= 1
            jr      nc,MUL16U_SKIP

            add     HL,BC           ; add multiplicand

MUL16U_SKIP:
            add     BC,BC           ; BC <<= 1
            dec     A
            jr      nz,MUL16U_LOOP
            ret

Discussion