Pristine Ack-5.5
[Ack-5.5.git] / mach / z80 / int / mli4.s
1 .define .mli4
2 .sect .text
3 .sect .rom
4 .sect .data
5 .sect .bss
6 .sect .text
7
8 ! 32-bit multiply routine for z80
9 ! parameters:
10 !   on stack
11
12
13
14 ! register utilization:
15 !   ix: least significant 2 bytes of result
16 !   hl: most  significant 2 bytes of result
17 !   bc: least significant 2 bytes of multiplicand
18 !   de: most  significant 2 bytes of multiplicand
19 !   iy: 2 bytes of multiplier (first most significant,
20 !       later least significant)
21 !   a:  bit count
22 .mli4:
23         !initialization
24         pop hl          ! return address
25         pop de
26         ld (.mplier+2),de! least significant bytes of
27                         ! multiplier
28         pop de
29         ld (.mplier),de ! most sign. bytes
30         pop de          ! least significant bytes of
31                         ! multiplicand
32         pop bc          ! most sign. bytes
33         push hl         ! return address
34         push iy         ! LB
35         ld ix,0
36         xor a
37         ld h,a          ! clear result
38         ld l,a
39         ld (.flag),a    ! indicate that this is
40                         ! first pass of main loop
41         ld iy,(.mplier)
42         ! main loop, done twice, once for each part (2 bytes)
43         ! of multiplier
44 1:
45         ld a,16
46         ! sub-loop, done 16 times
47 2:
48         add iy,iy       ! shift left multiplier
49         jr nc,3f        ! skip if most sign. bit is 0
50         add ix,de       ! 32-bit add
51         adc hl,bc
52 3:
53         dec a
54         jr z,4f         ! done with this part of multiplier
55         add ix,ix       ! 32-bit shift left
56         adc hl,hl
57         jr 2b
58 4:
59         ! see if we have just processed the first part
60         ! of the multiplier (flag = 0) or the second
61         ! part (flag = 1)
62         ld a,(.flag)
63         or a
64         jr nz,5f
65         inc a           ! a := 1
66         ld (.flag),a    ! set flag
67         ld iy,(.mplier+2)! least significant 2 bytes now in iy
68         add ix,ix       ! 32-bit shift left
69         adc hl,hl
70         jr 1b
71 5:
72         ! clean up
73         pop iy          ! restore LB
74         ex (sp),hl      ! put most sign. 2 bytes of result
75                         ! on stack;  put return address in hl
76         push ix         ! least sign. 2 bytes of result
77         jp (hl)         ! return
78 .sect .data
79 .flag:  .data1 0
80 .mplier: .space 4