home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 5 / FreshFish_July-August1994.bin / bbs / dev / c2p.lha / C2P / CPU+Blitter / c2p8.s < prev    next >
Text File  |  1994-07-01  |  21KB  |  834 lines

  1.  
  2.         opt o+,l+,d+
  3.  
  4.         incdir    inc:
  5.  
  6.         include    "exec/exec_lib.i"
  7.         include "exec/exec.i"
  8.         include    "graphics/graphics_lib.i"
  9.         include "hardware/custom.i"
  10.  
  11.         xdef    _c2p8_init
  12.         xdef    _c2p8_go
  13.  
  14. ; ---------------------------------------------------------------------
  15.  
  16. ; void __asm c2p8_init (register __a0 UBYTE *chunky,
  17. ;            register __a1 UBYTE *chunky_cmp,
  18. ;            register __a2 PLANEPTR *planes,
  19. ;            register __d0 ULONG signals1,
  20. ;            register __d1 ULONG signals2,
  21. ;            register __d2 ULONG pixels,     // width*height
  22. ;            register __d3 ULONG offset,     // byte offset into plane
  23. ;            register __d4 UBYTE *buff2,    // Chip buffer width*height
  24. ;            register __d5 UBYTE *buff3,    // Chip buffer width*height
  25. ;            register __a3 struct GfxBase *GfxBase);
  26. ;
  27. ; void c2p8_go();
  28. ;
  29. ; -------------------------------------------------------------------
  30. ;
  31. ; Pipelined CPU+blitter 8-plane chunky to planar converter.
  32. ; Optimised for 68020/30 with fastmem.
  33. ;
  34. ; Author: Peter McGavin (e-mail peterm@maths.grace.cri.nz), 21 April 1994
  35. ; Based on James McCoull's 4-pass blitter algorithm.
  36. ;
  37. ; Modified by Conrad Sanderson (g.sanderson@ais.gu.edu.au), 4 June 1994
  38. ;
  39. ; This code is public domain.
  40. ;
  41. ; algorithm:
  42. ;
  43. ; Uses chunky comparison buffer.  Returns immediately if no diffs found.
  44. ; Performs first 2 passes (Fast->Chip) with the CPU (in 1 pass).
  45. ; Only converts 32-pixel "units" that changed since last time.
  46. ; Updates chunky comparison buffer.
  47. ; If nothing has changed, signals signals1 and return immediately.
  48. ; Waits for previous QBlit() to completely finish (signals2).
  49. ; Then launches passes 3 & 4 with QBlit().
  50. ; Return immediately after launching passes 3 & 4.
  51. ; ** your task can render the next frame while the converter is still going **
  52. ; Signals via signals1 (asynchronously) after completion of pass 3.
  53. ; Signals via signals2 from CleanUp() on completion of QBlit().
  54. ;
  55. ; Approx timing for A4000/030, (320x200x8):
  56. ;    CPU pass min 13ms, max 37ms, depending how different (then return)
  57. ;    Asynchronous blitter passes add 62ms
  58. ;    Max framerate (with changes every frame) is 62ms/frame = 16fps
  59. ;        occurs when fBUFFER rendering time <= 25ms (= 62ms-37ms)
  60. ;
  61. ; Approx timing for A1200+fast ram, (320x200x8):
  62. ;     CPU pass min 18ms, max 55ms
  63. ;
  64. ;
  65. ; see c2p8_demo.c for example usage
  66. ; -------------------------------------------------------------------
  67.  
  68.  
  69.         section chunks,code
  70.  
  71. _c2p8_init:
  72.         movem.l    d2-d3/a2-a4/a6,-(sp)
  73.  
  74.         lea    mybltnode(pc),a4
  75.  
  76.         move.l    a0,(chunky-mybltnode,a4)
  77.         move.l    a1,(chunky_cmp-mybltnode,a4)
  78.         move.l    a2,(planes-mybltnode,a4)
  79.         move.l    d0,(signals1-mybltnode,a4)
  80.         move.l    d1,(signals2-mybltnode,a4)
  81.  
  82.         move.l    d2,(pixels-mybltnode,a4)
  83.         lsr.l    #1,d2
  84.         move.l    d2,(pixels2-mybltnode,a4)
  85.         lsr.l    #1,d2
  86.         move.l    d2,(pixels4-mybltnode,a4)
  87.         lsr.l    #1,d2
  88.         move.l    d2,(pixels8-mybltnode,a4)
  89.         lsr.l    #1,d2
  90.         move.l    d2,(pixels16-mybltnode,a4)
  91.         move.l    d3,(offset-mybltnode,a4)
  92.         move.l    d4,(tmp_buff2-mybltnode,a4)
  93.         move.l    d5,(tmp_buff3-mybltnode,a4)
  94.  
  95.  
  96.         move.l    a3,(gfxbase-mybltnode,a4)
  97.  
  98.         move.l    (4).w,a6
  99.         move.l    a6,(sysbase-mybltnode,a4)
  100.  
  101.         move.l    (ThisTask,a6),(task-mybltnode,a4) ; save task ptr
  102.  
  103.         movem.l    (sp)+,d2-d3/a2-a4/a6
  104.         rts
  105.  
  106.  
  107.         cnop    0,4
  108.  
  109. _c2p8_go:    movem.l    d2-d7/a2-a6,-(sp)
  110.  
  111.         lea    mybltnode(pc),a2
  112.         move.l    a2,a0
  113.  
  114. ; wait for previous call to c2p4 to finish pass 3
  115.  
  116.         move.l    (signals1-mybltnode,a0),d0
  117.         move.l    (sysbase,pc),a6
  118.         jsr    (_LVOWait,a6)              ; signals1 in d0
  119.  
  120.         move.l    a2,a0
  121.         move.l    (chunky-mybltnode,a0),a2
  122.         move.l    (chunky_cmp-mybltnode,a0),a3
  123.  
  124. ;-------------------------------------------------
  125. ;original chunky data
  126. ;0        a7a6a5a4a3a2a1a0 b7b6b5b4b3b2b1b0
  127. ;2        c7c6c5c4c3c2c1c0 d7d6d5d4d3d2d1d0
  128. ;4        e7e6e5e4e3e2e1e0 f7f6f5f4f3f2f1f0
  129. ;6        g7g6g5g4g3g2g1g0 h7h6h5h4h3h2h1h0
  130. ;8        i7i6i5i4i3i2i1i0 j7j6j5j4j3j2j1j0
  131. ;10        k7k6k5k4k3k2k1k0 l7l6l5l4l3l2l1l0
  132. ;12        m7m6m5m4m3m2m1m0 n7n6n5n4n3n2n1n0
  133. ;14        o7o6o5o4o3o2o1o0 p7p6p5p4p3p2p1p0
  134. ;16        q7q6q5q4q3q2q1q0 r7r6r5r4r3r2r1r0
  135. ;18        s7s6s5s4s3s2s1s0 t7t6t5t4t3t2t1t0
  136. ;20        u7u6u5u4u3u2u1u0 v7v6v5v4v3v2v1v0
  137. ;22        w7w6w5w4w3w2w1w0 x7x6x5x4x3x2x1x0
  138. ;24        y7y6y5y4y3y2y1y0 z7z6z5z4z3z2z1z0
  139. ;26        A7A6A5A4A3A2A1A0 B7B6B5B4B3B2B1B0
  140. ;28        C7C6C5C4C3C2C1C0 D7D6D5D4D3D2D1D0
  141. ;30        E7E6E5E4E3E2E1E0 F7F6F5F4F3F2F1F0
  142. ;-------------------------------------------------
  143.  
  144.         move.l    (pixels16-mybltnode,a0),d6
  145.         lsr.l    #1,d6        ; loop count = pixels/32
  146.  
  147.         move.l    (pixels4-mybltnode,a0),d0
  148.         move.l    (tmp_buff2,pc),a0
  149.  
  150.         lea    (a0,d0.l),a1    ; a1 -> buff2+pixels/4
  151.         lea    (a1,d0.l),a4    ; a4 -> buff2+pixels/2
  152.         lea    (a4,d0.l),a5    ; a5 -> buff2+3*pixels/4
  153.  
  154.         move.l    #$0f0f0f0f,d7    ; constant
  155.         move.l    #$00ff00ff,a6    ; constant
  156.  
  157.         bra.b    end_pass1loop
  158.  
  159.         cnop    0,4        ; align to 32 bits 
  160.  
  161. ; main loop (starts here) processes 32 chunky pixels at a time
  162. ; compare next 32 pixels with compare page, looking for differences
  163.  
  164. initpass1loop:    cmpm.l    (a2)+,(a3)+
  165.         bne.w    fix1
  166.         cmpm.l    (a2)+,(a3)+
  167.         bne.w    fix2
  168.         cmpm.l    (a2)+,(a3)+
  169.         bne.w    fix3
  170.         cmpm.l    (a2)+,(a3)+
  171.         bne.b    fix4
  172.         cmpm.l    (a2)+,(a3)+
  173.         bne.b    fix5
  174.         cmpm.l    (a2)+,(a3)+
  175.         bne.b    fix6
  176.         cmpm.l    (a2)+,(a3)+
  177.         bne.b    fix7
  178.         cmpm.l    (a2)+,(a3)+
  179.         bne.b    fix8
  180.  
  181.         addq.l    #8,a0        ; skip 8 bytes in output
  182.         addq.l    #8,a1        ; skip 8 bytes in output
  183.         addq.l    #8,a4        ; skip 8 bytes in output
  184.         addq.l    #8,a5        ; skip 8 bytes in output
  185.  
  186. end_pass1loop:    dbra    d6,initpass1loop
  187.  
  188.         bra.w    done2
  189.  
  190.         cnop    0,4
  191.  
  192. ; This becomes the main loop after the first difference is found
  193.  
  194. pass1loop:    cmpm.l    (a2)+,(a3)+
  195.         bne.b    fix1
  196.         cmpm.l    (a2)+,(a3)+
  197.         bne.b    fix2
  198.         cmpm.l    (a2)+,(a3)+
  199.         bne.b    fix3
  200.         cmpm.l    (a2)+,(a3)+
  201.         bne.b    fix4
  202.         cmpm.l    (a2)+,(a3)+
  203.         bne.b    fix5
  204.         cmpm.l    (a2)+,(a3)+
  205.         bne.b    fix6
  206.         cmpm.l    (a2)+,(a3)+
  207.         bne.b    fix7
  208.         cmpm.l    (a2)+,(a3)+
  209.         bne.b    fix8
  210.  
  211.         addq.l    #8,a0        ; skip 8 bytes in output
  212.         addq.l    #8,a1        ; skip 8 bytes in output
  213.         addq.l    #8,a4        ; skip 8 bytes in output
  214.         addq.l    #8,a5        ; skip 8 bytes in output
  215.  
  216.         dbra    d6,pass1loop
  217.  
  218.         bra.w    done
  219.  
  220.         cnop 0,4
  221.  
  222. ; difference found, restore a2 and a3
  223.  
  224. fix8:        sub.w    #32,a2
  225.         sub.w    #32,a3
  226.         bra.b    go_c2p
  227.  
  228. fix7:        sub.w    #28,a2
  229.         sub.w    #28,a3
  230.         bra.b    go_c2p
  231.  
  232. fix6:        sub.w    #24,a2
  233.         sub.w    #24,a3
  234.         bra.b    go_c2p
  235.  
  236. fix5:        sub.w    #20,a2
  237.         sub.w    #20,a3
  238.         bra.b    go_c2p
  239.  
  240. fix4:        sub.w    #16,a2
  241.         sub.w    #16,a3
  242.         bra.b    go_c2p
  243.  
  244.         cnop    0,4
  245.  
  246. fix3:        subq.l    #4,a2
  247.         subq.l    #4,a3
  248. fix2:        subq.l    #4,a2
  249.         subq.l    #4,a3
  250. fix1:        subq.l    #4,a2
  251.         subq.l    #4,a3
  252.  
  253. ; convert 32 pixels (passes 1 and 2 combined)
  254.  
  255. go_c2p:        movem.l    (a2)+,d0-d3    ; AaBbCcDd EeFfGgHh IiJjKkLl MmNnOoPp
  256.  
  257.         movem.l    d0-d3,(a3)    ; update compare buffer
  258.         adda.w    #16,a3
  259.  
  260.         exg    d7,a6        ; d7=$00ff00ff
  261.  
  262.         move.l    d0,d4        ; AaBbCcDd
  263.         and.l    d7,d4        ; ..Bb..Dd
  264.         eor.l    d4,d0        ; Aa..Cc..
  265.         lsl.l    #8,d4        ; Bb..Dd..
  266.  
  267.         move.l    d2,d5        ; IiJjKkLl
  268.         and.l    d7,d5        ; ..Jj..Ll
  269.         eor.l    d5,d2        ; Ii..Kk..
  270.         lsr.l    #8,d2        ; ..Ii..Kk
  271.  
  272.         or.l    d2,d0        ; AaIiCcKk
  273.         or.l    d5,d4        ; BbJjDdLl
  274.  
  275.         move.l    d1,d2        ; EeFfGgHh
  276.         and.l    d7,d2        ; ..Ff..Hh
  277.         eor.l    d2,d1        ; Ee..Gg..
  278.         lsl.l    #8,d2        ; Ff..Hh..
  279.  
  280.         move.l    d3,d5        ; MmNnOoPp
  281.         and.l    d7,d5        ; ..Nn..Pp
  282.         eor.l    d5,d3        ; Mm..Oo..
  283.         lsr.l    #8,d3        ; ..Mm..Oo
  284.  
  285.         or.l    d3,d1        ; EeMmGgOo
  286.         or.l    d5,d2        ; FfNnHhPp
  287.  
  288.         exg    d7,a6        ; d7 = $0f0f0f0f
  289.  
  290.         move.l    d0,d3        ; AaIiCcKk
  291.         and.l    d7,d3        ; .a.i.c.k
  292.         eor.l    d3,d0        ; A.I.C.K.
  293.         lsl.l    #4,d3        ; a.i.c.k.
  294.  
  295.         move.l    d1,d5        ; EeMmGgOo
  296.         and.l    d7,d5        ; .e.m.g.o
  297.  
  298.         or.l    d5,d3        ; aeimcgko
  299.         move.l    d3,(a4)+
  300.  
  301.         eor.l    d5,d1        ; E.M.G.O.
  302.         lsr.l    #4,d1        ; .E.M.G.O
  303.  
  304.         or.l    d1,d0        ; AEIMCGKO
  305.         move.l    d0,(a0)+
  306.  
  307.         move.l    d4,d1        ; BbJjDdLl
  308.         and.l    d7,d1        ; .b.j.d.l
  309.         eor.l    d1,d4        ; B.J.D.L.
  310.         lsl.l    #4,d1        ; b.j.d.l.
  311.  
  312.         move.l    d2,d5        ; FfNnHhPp
  313.         and.l    d7,d5        ; .f.n.h.p
  314.  
  315.         or.l    d5,d1        ; bfjndhlp
  316.         move.l    d1,(a5)+
  317.  
  318.         eor.l    d5,d2        ; F.N.H.P.
  319.         lsr.l    #4,d2        ; .F.N.H.P
  320.  
  321.         or.l    d2,d4        ; BFJNDHLP
  322.         move.l    d4,(a1)+
  323.  
  324.         bchg    #16,d6        ; repeat inner loop twice
  325.         beq.b    go_c2p
  326.  
  327.         dbra    d6,pass1loop
  328.  
  329. ; wait until previous QBlit() has completely finished (signals2)
  330. ; then start the blitter in the background for passes 3 & 4
  331.  
  332. done:        lea    mybltnode(pc),a2    ; a2->mybltnode
  333.         move.l    sysbase(pc),a6        ; a6->SysBase
  334.         move.l    (signals2-mybltnode,a2),d0
  335.         jsr    (_LVOWait,a6)
  336.  
  337.         move.l    a2,a1
  338.         move.l    (gfxbase-mybltnode,a2),a6
  339.         jsr    (_LVOQBlit,a6)
  340.  
  341.         bra.b    ret
  342.  
  343.  
  344. ; If we get to here then no difference was found.
  345. ; Signal the task (signals1) and return.
  346.  
  347.         cnop 0,4
  348.  
  349. done2:        lea    mybltnode(pc),a2
  350.         move.l    (signals1-mybltnode,a2),d0
  351.         move.l    d0,d1
  352.         mov