.define .mli4 .sect .text .sect .rom .sect .data .sect .bss .sect .text ! 32-bit multiply routine for z80 ! parameters: ! on stack ! register utilization: ! ix: least significant 2 bytes of result ! hl: most significant 2 bytes of result ! bc: least significant 2 bytes of multiplicand ! de: most significant 2 bytes of multiplicand ! iy: 2 bytes of multiplier (first most significant, ! later least significant) ! a: bit count .mli4: !initialization pop hl ! return address pop de ld (.mplier+2),de! least significant bytes of ! multiplier pop de ld (.mplier),de ! most sign. bytes pop de ! least significant bytes of ! multiplicand pop bc ! most sign. bytes push hl ! return address push iy ! LB ld ix,0 xor a ld h,a ! clear result ld l,a ld (.flag),a ! indicate that this is ! first pass of main loop ld iy,(.mplier) ! main loop, done twice, once for each part (2 bytes) ! of multiplier 1: ld a,16 ! sub-loop, done 16 times 2: add iy,iy ! shift left multiplier jr nc,3f ! skip if most sign. bit is 0 add ix,de ! 32-bit add adc hl,bc 3: dec a jr z,4f ! done with this part of multiplier add ix,ix ! 32-bit shift left adc hl,hl jr 2b 4: ! see if we have just processed the first part ! of the multiplier (flag = 0) or the second ! part (flag = 1) ld a,(.flag) or a jr nz,5f inc a ! a := 1 ld (.flag),a ! set flag ld iy,(.mplier+2)! least significant 2 bytes now in iy add ix,ix ! 32-bit shift left adc hl,hl jr 1b 5: ! clean up pop iy ! restore LB ex (sp),hl ! put most sign. 2 bytes of result ! on stack! put return address in hl push ix ! least sign. 2 bytes of result jp (hl) ! return .sect .data .flag: .data1 0 .mplier: .space 4