home *** CD-ROM | disk | FTP | other *** search
- ; void bcopy(void *src, void *dst, long cnt)
- ; handle overlap (both ways), odd/even alignment etc
- ; ++jrb bammi@dsrgsun.ces.cwru.edu
- ;
- .text
- .even
- .globl _bcopy
- _bcopy:
- move.l 4(sp),a0 ; src -> a0
- move.l 8(sp),a1 ; dst -> a1
- move.l 12(sp),d0 ; cnt -> d0
- ble return ; cnt <= 0
- move.l d2,-(sp) ; save d2
-
- ; check overlap
- move.l a0,d1 ; (abs(src - dst)) < cnt => overlap
- sub.l a1,d1
- bge L1
- neg.l d1
- L1: cmp.l d1,d0
- bgt overlap
-
- ; check for odd src or dst
- move.w a0,d1
- move.w a1,d2
- eor.b d1,d2
- btst #0,d2
- bne oddeven
- btst #0,d1
- beq eveneven
- move.b (a0)+,(a1)+ ; odd odd
- subq.l #1,d0 ; now even even
-
- eveneven: ; may want long alignment for 020/030 etc
- move.l d0,d1
- and.b #$1c,d1 ; 4 bytes/copy 32 bytes max/iter
- lsr.l #1,d1 ; calc index into loop (each move.l == 2bytes)
- neg.l d1 ;
- add.l #18,d1 ; 16 + 2 bytes for jmp ext word - d1 == index
- jmp 0(pc,d1) ; dive into loop at appro spot
- loop1:
- move.l (a0)+,(a1)+
- move.l (a0)+,(a1)+
- move.l (a0)+,(a1)+
- move.l (a0)+,(a1)+
-
- move.l (a0)+,(a1)+
- move.l (a0)+,(a1)+
- move.l (a0)+,(a1)+
- move.l (a0)+,(a1)+
-
- sub.l #32,d0
- bge loop1
-
- btst #1,d0
- beq L4
- move.w (a0)+,(a1)+ ; residual word
- L4: btst #0,d0
- beq ret
- move.b (a0),(a1) ; residual byte
-
- ret: move.l (sp)+,d2
- return: rts
-
- oddeven:
- upcopy: ; byte-by-byte forward
- subq.l #1,d0
- blt ret
- move.b (a0)+,(a1)+
- bra upcopy
-
- overlap:
- cmp.l a0,a1
- bmi upcopy ; (src > dst) go do byte/byte forward copy
- add.l d0,a0 ; otherwise backwards copy
- add.l d0,a1 ; note we use predec so 1 is not sub from addr
-
- downcopy: ; byte-by-byte backward
- subq.l #1,d0
- blt ret
- move.b -(a0),-(a1)
- bra downcopy
-