home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 620.lha / CopyMemQuicker_v2.1 / CopyMemQuicker.asm < prev    next >
Assembly Source File  |  1992-02-10  |  6KB  |  274 lines

  1.     nolist
  2. **********************************************************************
  3. *             CopyMemQuicker 2.1 - (C) 1991, 1992 Arthur Hagen       *
  4. *     Parts of code: (C) 1985-1991 Commodore Business Machines Ltd.  *
  5. *                    Posted to the Public Domain                     *
  6. **********************************************************************
  7.  
  8.     xref    _LVOOldOpenLibrary
  9.     xref    _LVOCloseLibrary
  10.     xref    _LVOOutput
  11.     xref    _LVOWrite
  12.     xref    _LVOAllocMem
  13.     xref    _LVOFreeMem
  14.     xref    _LVOSetFunction
  15.     xref    _LVOCopyMem
  16.     xref    _LVOCopyMemQuick
  17.     include    'exec/execbase.i'
  18.  
  19.     public    _QuickMem
  20.     list
  21. _QuickMem
  22.     movea.l    (4).w,a6            ; ExecBase
  23.     lea    dosname(pc),a1
  24.     jsr    _LVOOldOpenLibrary(a6)        ; Any version will do
  25.     movea.l    d0,a5
  26.     exg.l    a5,a6
  27.     jsr    _LVOOutput(a6)
  28.     exg.l    a5,a6
  29.     move.l    d0,d7
  30.     moveq    #title_end-title,d3
  31.     lea    title(pc),a0
  32.     bsr.s    wrt
  33.     move.l    #(CopyEnd-CopyStart),d4
  34.     movea.l    _LVOCopyMem+2(a6),a0
  35.     lea    CopyStart-CopyMemQuicker(a0),a3
  36.     move.l    Identity-CopyStart(a3),d1
  37.     cmpi.l    #'*Art',d1
  38.     beq.s    isquicker
  39.  
  40.     move.l    d4,d0
  41.     moveq    #0,d1                ; Any memory type
  42.     jsr    _LVOAllocMem(a6)
  43.     tst.l    d0
  44.     beq.s    nomem
  45.  
  46.     movea.l    d0,a3
  47.     movea.l    a3,a1
  48.     lea    CopyStart(pc),a0
  49.     move.l    d4,d0
  50.     bsr.s    CopyMemQuicker            ; beats jsr _LVOCopyMem(a6)
  51.  
  52. * The movem-trick uses some extra cycles for setting up, so
  53. * if we run the loop < n times, we will actually slow things down.
  54. * For 68000:  n = 2;  for 68010: n = 8;  for 68020+: n = 4
  55. * The reason is that the 68010 has a loop mode for dbf-loops, but no
  56. * cache, whereas the 68020+'es run all code faster.
  57.  
  58.     moveq    #44*2,d0
  59.     btst    #AFB_68020,AttnFlags+1(a6)
  60.     beq.s    tst10
  61.     add.w    d0,d0            ; We have a 020 or higher
  62.     bra.s    cmpset
  63. tst10    btst    #AFB_68010,AttnFlags+1(a6)
  64.     bne.s    cmpok            ; We have a 010
  65. cmpset    move.w    d0,CmpValS-CopyStart(a3)
  66.     move.w    d0,CmpValQ-CopyStart(a3)
  67. cmpok    moveq    #255-(CopyMemQuickest-CopyStart),d0
  68.     not.b    d0
  69.     add.l    a3,d0
  70.     bsr.s    setcmq
  71.     move.l    d0,(a3)
  72.     moveq    #CopyMemQuicker-CopyStart,d0
  73.     add.l    a3,d0
  74.     bsr.s    setcm
  75.     move.l    d0,4(a3)
  76. quit    movea.l    a5,a1
  77.     jmp    _LVOCloseLibrary(a6)    ; faster than jsr + rts
  78.  
  79. nomem    moveq    #memerr_end-memerr,d3
  80.     lea    memerr(pc),a0
  81.     pea    quit(pc)        ; faster than 'bsr.s wrt' + 'bra.s quit'
  82.  
  83. wrt    move.l    a0,d2
  84.     move.l    d7,d1
  85.     exg.l    a5,a6
  86.     jsr    _LVOWrite(a6)
  87.     exg.l    a5,a6
  88.     rts
  89.  
  90. isquicker
  91.     moveq    #already_end-already,d3
  92.     lea    already(pc),a0
  93.     bsr.s    wrt
  94.     move.l    4(a3),d0
  95.     bsr.s    setcm
  96.     move.l    (a3),d0
  97.  
  98. * Too darn dangerous!  Some other program might be using the routine
  99. * in the background, and freeing the code it is running just won't do!
  100. ;    bsr.s    setcmq
  101. ;    move.l    d4,d0
  102. ;    movea.l    a3,a1
  103. ;    jsr    _LVOFreeMem(a6)
  104. ;    bra.s    quit
  105.  
  106.     pea    quit(pc)    ; faster than 'bsr.s setcmq' + 'bra.s quit'
  107.  
  108. setcmq    lea    (_LVOCopyMemQuick).w,a0
  109.     bra.s    setit
  110.  
  111. setcm    lea    (_LVOCopyMem).w,a0
  112. setit    movea.l    a6,a1
  113.     jmp    _LVOSetFunction(a6)
  114.  
  115.  
  116. ************************************************************
  117.  
  118. CopyStart
  119.  
  120. OldCopyMemQuick
  121.     dc.l    0
  122. OldCopyMem
  123.     dc.l    0
  124. Identity
  125.     dc.l    '*Art'
  126. CopyMemQuicker
  127.     moveq    #12,d1
  128.     cmp.l    d1,d0
  129.     bcs.s    tinycpy        ; too small to gain anything
  130.     move.w    a0,d1
  131.     lsr.b    #1,d1        ; fastest test for evenness
  132.     bcc.s    evena0
  133.     move.b    (a0)+,(a1)+
  134.     subq.l    #1,d0
  135. evena0    move.w    a1,d1
  136.     lsr.b    #1,d1
  137.     bcc.s    CopyMemEvenQuicker
  138.  
  139.     moveq    #36*3,d1
  140.     cmp.l    d1,d0
  141.     bcs.s    tinycpy
  142.  
  143. * This is tricky!  They said it couldn't be done...
  144. unevcpy    movem.l    a2-a4/d2-d7,-(sp)
  145.     moveq    #32,d1        ; 8 registers of 4 bytes
  146.     move.w    d1,a3
  147.     moveq    #36,d1        ; as above plus 4 "roundoff" bytes
  148.     move.w    d1,a4
  149.     sub.l    d1,d0
  150.     move.l    d0,a2
  151. uloop    movem.l    (a0)+,d0-d7
  152.     rol.l    #8,d0
  153.     rol.l    #8,d1
  154.     rol.l    #8,d2
  155.     rol.l    #8,d3
  156.     rol.l    #8,d4
  157.     rol.l    #8,d5
  158.     rol.l    #8,d6
  159.     rol.l    #8,d7
  160.     move.b    d0,(a1)+
  161.     move.b    d1,d0
  162.     move.b    d2,d1
  163.     move.b    d3,d2
  164.     move.b    d4,d3
  165.     move.b    d5,d4
  166.     move.b    d6,d5
  167.     move.b    d7,d6
  168.     move.b    (a0)+,d7
  169.     movem.l    d0-d7,(a1)
  170.     adda.w    a3,a1
  171.     move.b    (a0)+,(a1)+    ; even up to next longword
  172.     move.b    (a0)+,(a1)+
  173.     move.b    (a0)+,(a1)+
  174.     move.l    a2,d0
  175.     sub.l    a4,d0
  176.     movea.l    d0,a2
  177.     bcc.s    uloop
  178.     add.w    a4,d0
  179.     movem.l    (sp)+,a2-a4/d2-d7
  180.     subq.b    #1,d0
  181.     bcs.s    tdone
  182.  
  183. tloop    move.b    (a0)+,(a1)+
  184. tinycpy    dbf    d0,tloop
  185. tdone    rts
  186.  
  187. CopyMemEvenQuicker
  188.     dc.w    $0c80        ; cmpi.l #nnnn,d0
  189.     dc.w    0        ; Need 8 loops to be economical on 68010
  190. CmpValS    dc.w    44*8        ; (on 68000 this will be set to 44*2
  191.                 ; and on 68020+ this will be 44*4
  192.     bcs.s    smlmov
  193.     moveq    #44,d1        ; 11 registers of 4 bytes
  194.     sub.l    d1,d0
  195.     movem.l    d2-d7/a2-a6,-(sp)
  196. bigmov    movem.l    (a0)+,d2-d7/a2-a6
  197.     movem.l    d2-d7/a2-a6,(a1)
  198.     adda.w    d1,a1
  199.     sub.l    d1,d0
  200.     bcc.s    bigmov
  201.     add.w    d1,d0
  202.     movem.l    (sp)+,d2-d7/a2-a6
  203.  
  204. smlmov    lsr.w    #1,d0
  205.     beq.s    even01
  206.     bcs.s    sm13
  207.     lsr.w    #1,d0
  208.     beq.s    even2
  209.     bcs.s    sm2
  210. sm0    subq.w    #1,d0
  211. loop0    move.l    (a0)+,(a1)+
  212.     dbf    d0,loop0
  213. even0    rts
  214. sm2    subq.w    #1,d0
  215. loop2    move.l    (a0)+,(a1)+
  216.     dbf    d0,loop2
  217. even2    move.w    (a0),(a1)
  218.     rts
  219. sm13    lsr.w    #1,d0
  220.     beq.s    even3
  221.     bcs.s    sm3
  222. sm1    subq.w    #1,d0
  223. loop1    move.l    (a0)+,(a1)+
  224.     dbf    d0,loop1
  225. even1    move.b    (a0),(a1)
  226.     rts
  227. sm3    subq.w    #1,d0
  228. loop3    move.l    (a0)+,(a1)+
  229.     dbf    d0,loop3
  230. even3    move.w    (a0)+,(a1)+
  231.     move.b    (a0),(a1)
  232.     rts
  233. even01    bcs.s    even1
  234.     rts
  235.  
  236. CopyMemQuickest
  237.     dc.w    $0c80        ; cmpi.l #nnnn,d0
  238.     dc.w    0        ; Need 8 loops to be economical on 68010
  239. CmpValQ    dc.w    44*8        ; (on 68000 this will be set to 44*2
  240.                 ; and on 68020+ this will be 44*4
  241.     bcs.s    smlmovQ
  242.     moveq    #44,d1        ; 11 registers of 4 bytes
  243.     sub.l    d1,d0
  244.     movem.l    d2-d7/a2-a6,-(sp)
  245. bigmovQ    movem.l    (a0)+,d2-d7/a2-a6
  246.     movem.l    d2-d7/a2-a6,(a1)
  247.     adda.w    d1,a1
  248.     sub.l    d1,d0
  249.     bcc.s    bigmovQ
  250.     add.w    d1,d0
  251.     movem.l    (sp)+,d2-d7/a2-a6
  252. smlmovQ    lsr.w    #2,d0
  253.     beq.s    done
  254.     subq.w    #1,d0
  255. qloop    move.l    (a0)+,(a1)+
  256.     dbf    d0,qloop
  257. done    rts
  258. CopyEnd
  259.  
  260. ************************************************************
  261.  
  262. *    Leave this for the 2.0 Version function!!!
  263. version    dc.b    '$VER: '
  264. title    dc.b    'CopyMemQuicker 2.1 (8 Feb 1992)',$0A,$0D
  265.     dc.b    'Copyright ',$A9,' 1992 Arthur Hagen.',$0A
  266. title_end
  267. already    dc.b    'Restoring vectors.',$0A
  268. already_end
  269. memerr    dc.b    'No memory!',$0A
  270. memerr_end
  271. dosname    dc.b    'dos.library',0
  272.     even
  273.     end
  274.