home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / language / fixes / lmemcpy.s < prev    next >
Encoding:
Text File  |  1985-11-19  |  2.5 KB  |  68 lines

  1. * lmemcpy.s - replacement for a code in dLibs 1.2
  2. *
  3. * After memcpy by David Brooks  - Michal Jaegermann, 11 Mar 89
  4. *
  5. *       char *lmemcpy(dest, source, len)
  6. *               char *dest              at 4(sp)
  7. *               char *source            at 8(sp)
  8. *               unsigned long len       at 12(sp)
  9. *
  10. * Avoid "btst #n,dn" because of a bug in the Sozobon assembler.
  11. * If parity of both adresses the same - copies in 16 byte blocks.
  12. * One has to stop loop unrolling somewhere.
  13.  
  14. .text
  15. .globl _lmemcpy
  16. _lmemcpy:
  17.         lea     4(a7),a2        ; Point to argument list
  18.         move.l  (a2)+,a1        ; a1 = dest
  19.         move.l  (a2)+,a0        ; a0 = source
  20.         move.l  (a2),d2         ; d2 = len
  21.         beq     lmemcpy6        ; return if zero
  22.  
  23.         move.l  a0,d1           ; Check for odd/even alignment
  24.         add.w   a1,d1           ; This is really eor.w on the lsb.  Really.
  25.         asr.w   #1,d1           ; Get lsb into C.  If it's 1, alignment is off.
  26.         bcs     lmemcpy7        ; Go do it slowly
  27.  
  28.         move.l  a0,d1           ; Check for initial odd byte
  29.         asr.w   #1,d1           ; Get lsb
  30.         bcc     lmemcpy1
  31.         subq.l  #1,d2           ; Move initial byte
  32.         move.b  (a0)+,(a1)+     ; 
  33. lmemcpy1:
  34.         moveq.l #15,d1          ; Split into a longword count and remainder
  35.         and.w   d2,d1
  36.         lsr.l   #4,d2           ; for 16 bytes at a time
  37.         move.l  d2,d0           ; a second counter for dbra
  38.         swap    d0
  39.         bra     lmemcpy3        ; Words (!!) d2 and d0 could equal 0.
  40. lmemcpy2:
  41.         move.l  (a0)+,(a1)+     ; Copy 16 bytes
  42.         move.l  (a0)+,(a1)+
  43.         move.l  (a0)+,(a1)+
  44.         move.l  (a0)+,(a1)+
  45. lmemcpy3:
  46.         dbra    d2,lmemcpy2
  47.         dbra    d0,lmemcpy2
  48.  
  49.         bra     lmemcpy5        ; Enter final loop.  Again d1 could equal 0.
  50. lmemcpy4:
  51.         move.b  (a0)+,(a1)+     ; Up to 15 trailing bytes
  52. lmemcpy5:
  53.         dbra    d1,lmemcpy4
  54. lmemcpy6:
  55.         move.l  4(a7),d0        ; stick return value into d0
  56.         rts                     ; All done.
  57.  
  58. lmemcpy7:
  59.         move.l  a1,d0           ; Handle the odd/even aligned case, d0=dest
  60.         subq    #1,d2           ; here d2 was positive!
  61.         move.l  d2,d1
  62.         swap    d1              ; second dbra counter
  63. lmemcpy8:
  64.         move.b  (a0)+,(a1)+    ; move byte-by-byte
  65.         dbra    d2,lmemcpy8
  66.         dbra    d1,lmemcpy8
  67.         rts                     ; and exit normally
  68.