ENTRY(w16zero)
movl 8(%sp), %d0 | get our count
beq 6f | return if count is zero
movl 4(%sp), %a0 | get our address
| align %a0 to a 16-bit boundary:
movl %a0, %d1
btst #0, %d1 | is %a0 even?
beq 1f | if so, skip ahead
clrb (%a0)+ | zero one byte
subql #1, %d0 | decrement count
| now zero 32 bits at a time:
1: movl %d0, %d1 | copy count into %d1
lsrl #2, %d1 | turn %d1 into long count
subqw #1, %d1 | set up for dbf
bcs 3f | skip ahead if long count % 64k == 0
#ifdef __mc68010__
| on a 68010, 32-bit accesses become 16-bit accesses externally:
2: clrl (%a0)+
dbf %d1, 2b | will use the 68010 loop mode
#else
2: clrw (%a0)+
clrw (%a0)+
dbf %d1, 2b
#endif
| since DBcc only uses the low 16-bits of the count
| register, we have to decrement the high 16-bits:
3: subil #0x10000, %d1
bcc 2b
| zero the odd bytes:
4: andil #3, %d0 | odd byte count in %d0
subqw #1, %d0 | set up for dbf
bcs 6f | skip ahead if no odd bytes
5: clrb (%a0)+
dbf %d0, 5b | will use the 68010 loop mode
6: rts
ENTRY(w16copy)
movl 12(%sp), %d0 | get our count
beq 8f | return if count is zero
movl 4(%sp), %a0 | get our source address
movl 8(%sp), %a1 | get our destination address
| align %a0 to a 16-bit boundary:
movl %a0, %d1
btst #0, %d1 | is %a0 even?
beq 1f | if so, skip ahead
movb (%a0)+, (%a1)+ | copy one byte
subql #1, %d0 | decrement count
| branch on whether or not %a1 is aligned to a 16-bit boundary:
1: movl %a1, %d1
btst #0, %d1 | is %a1 even?
bne 4f | if not, skip ahead
| %a1 is also aligned to a 16-bit boundary, so we can copy
| the easy way, 32 bits at a time:
movl %d0, %d1 | copy count into %d1
lsrl #2, %d1 | turn %d1 into long count
subqw #1, %d1 | set up for dbf
bcs 3f | skip ahead if long count % 64k == 0
#ifdef __mc68010__
| on a 68010, 32-bit accesses become 16-bit accesses externally:
2: movl (%a0)+, (%a1)+
dbf %d1, 2b | will use the 68010 loop mode
#else
2: movw (%a0)+, (%a1)+
movw (%a0)+, (%a1)+
dbf %d1, 2b
#endif
| since DBcc only uses the low 16-bits of the count
| register, we have to decrement the high 16-bits:
3: subil #0x10000, %d1
bcc 2b
bra 6f | jump ahead to copy the odd bytes
| %a1 is misaligned, so we're forced to copy the hard way.
| if there are fewer than four bytes, copy only odd bytes:
4: cmpil #4, %d0 | is count less than 4?
bcs 6f | if so, skip ahead
| prime the FIFO:
movw (%a0)+, %d1 | FIFO: xx01
rorl #8, %d1 | FIFO: 1xx0
movb %d1, (%a1)+ | FIFO: 1xxx
subql #4, %d0 | subtract 4 from count
| run the FIFO:
5: rorl #8, %d1 | FIFO: x1xx
movw (%a0)+, %d1 | FIFO: x123
rorl #8, %d1 | FIFO: 3x12
movw %d1, (%a1)+ | FIFO: 3xxx -> 1xxx
subql #2, %d0 | two or more bytes remaining?
bcc 5b | loop back, if so.
| flush the FIFO:
roll #8, %d1 | FIFO: xxx1
movb %d1, (%a1)+ | FIFO: xxxx
addl #2, %d0 | fix up count
| copy the odd bytes:
6: andil #3, %d0 | odd byte count in %d0
subqw #1, %d0 | set up for dbf
bcs 8f | skip ahead if no odd bytes
7: movb (%a0)+, (%a1)+
dbf %d0, 7b | use loop mode
8: rts