I Need assembly code,z80 microprocessor, multiplication of two 16 bit - Programmers Heaven

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

I Need assembly code,z80 microprocessor, multiplication of two 16 bit

I need assistance in writing the code for 16bit multiplied by 16 bit number in assembly language for Z80 microprocessor...

Comments

  • blipblip Posts: 756Member
    I wrote a bunch of routines for a TI-8x OS I was writing... and put on hold. Here's a whole bunch that might come in useful:

    [code]
    ;------------------------------PROCEDURES:--------------------------------------

    ;Input: C
    ;Output: A
    ;Destroyed: F
    SignExtend:
    ld a,c
    add a,a ;Shift A left once to get its sign bit into CF.
    ld a,0
    sbc a,0
    ret

    ;Input: HL, DE
    ;Output: Proper flag setup: ZF and CF
    ;Destroyed: AF
    CPHLDE:
    ld a,h
    cp d
    ret nz
    ld a,l
    cp e
    ret

    ;Input: B
    ;Output: B, C
    ;Destroyed: AF
    GetShiftCountB:
    ld c,0
    GSCBloop:
    ld a,b
    and 1
    ret nz
    srl b
    inc c
    jr GSCBloop

    ;Input: HL
    ;Output: HL, C
    ;Destroyed: AF
    GetShiftCountHL:
    ld c,0
    GSCHLloop:
    ld a,b
    and 1
    ret nz
    srl h
    rrc l
    inc c
    jr GSCHLloop

    ;Input: DE:HL = # to shift left, A = Count
    ;Output: Shifted DE:HL
    ;Destroyed: AF
    ShiftLeftDEHL:
    cp 8
    Mod8Loop_L:
    jr nc,DoneMod8_L
    ld l,h
    ld h,e
    ld e,d
    ld d,0
    sub 8
    jr nz,Mod8Loop_L ;This eliminates the possible zero count bug.
    ret
    DoneMod8_L:
    add hl,hl
    rlc e
    rlc d
    dec a
    jr nz,DoneMod8_L
    ret

    ;Input: DE:HL = # to shift right, A = Count
    ;Output: Shifted DE:HL
    ;Destroyed: AF
    ShiftRightDEHL:
    cp 8
    Mod8Loop_R:
    jr nc,DoneMod8_R
    ld d,e
    ld e,h
    ld h,l
    ld l,0
    sub 8
    jr nz,Mod8Loop_R ;This eliminates the possible zero count bug.
    ret
    DoneMod8_R:
    srl d
    rrc e
    rrc h
    rrc l
    dec a
    jr nz,DoneMod8_R
    ret

    ;Input: HL / BC
    ;Output: DE r HL
    ;Destroyed: A
    UnsignedDiv16:
    ld a,b
    or c
    jr z,AttemptedDivByZero
    KeepReducing:
    ld a,l
    or e
    and 1
    jr nz,DoneReducing
    srl b
    rrc c
    srl h
    rrc l
    jr KeepReducing
    DoneReducing:
    ld de,0 ;DE will be the quotient.
    Div16Loop:
    sbc hl,bc ;CF should be cleared from the previous instructions.
    inc de ;Increment the quotient, INCs don't modify CF.
    jr nc,Div16Loop ;If there wasn't a sign change, keep dividing.
    add hl,bc ;Fix up the remainder...
    dec de ;...and quotient.
    or a ;Clear CF to show there were no errors, it was set during the ADD.
    ret
    AttemptedDivByZero:
    scf
    ret

    ;Input: HL * DE
    ;Output: DE:HL
    ;Destroyed: AF, BC, IX
    UnsignedMul16:
    call GetShiftCountHL
    ex de,hl
    ld b,c
    call GetShiftCountHL
    ld a,b
    add a,c
    push af ;Save the shift count to later apply to the product on the stack.
    call CPHLDE
    jr nc,SkipEXDEHL ;This will make the loop have to do less iterations.
    ex de,hl
    SkipEXDEHL:
    ld b,h
    ld c,l
    ld (TempSP),sp
    di
    ld sp,0
    Mul16Loop:
    add hl,bc
    adc ix,sp
    dec de
    jr nz,Mul16Loop
    ld sp,(TempSP)
    pop af ;No EI needed: POP AF will restore the interrupt state correctly.
    call ShiftLeftDEHL ;A contains the shift count previously extracted to use.
    ret
    TempSP: dw ?

    ;Input: B * DE
    ;Output: AHL
    ;Destroyed: IXL
    UnsignedMul12:
    push af
    call GetShiftCountB
    pop af
    ld h,d
    ld l,e
    xor a
    cp c
    jr z,SkipShiftLeftAHL
    ShiftLeftAHL:
    add hl,hl
    rlc a
    dec c
    jr nz,ShiftLeftAHL
    ld d,h
    ld e,l
    ld ixl,a
    Mul12Loop:
    add hl,de
    adc a,ixl
    djnz Mul12Loop
    ret
    [/code]
Sign In or Register to comment.