home *** CD-ROM | disk | FTP | other *** search
/ Fujiology Archive / fujiology_archive_v1_0.iso / !FALCON / LINEOUT / OUT.ZIP / SOURCE.ZIP / GRIDH.ASM < prev    next >
Assembly Source File  |  2004-01-15  |  19KB  |  804 lines

  1. ; gouraud lines on dsp:
  2. ;
  3. ; rotation + translation
  4. ; ->
  5. ; z clipping and culling (also depthculling!)
  6. ; ->
  7. ; perspectivation
  8. ; ->
  9. ; x/y clipping
  10. ; ->
  11. ; sorting
  12. ; ->
  13. ; transmission
  14. ;
  15. ; yep, host only does actual bresenham + some interpolation.
  16. ;
  17. ; todo: z intersection in x/y clip..
  18. ;
  19. ; quite well optimised, even max optimised cpu always has to wait..
  20.  
  21. ;======== GLOBAL EQUATES ========
  22.  
  23. PBC:                =    $FFE0            ; Port B Control Register
  24. HSR:                =    $FFE9            ; Host Status Register
  25. HTX:                =    $FFEB            ; Host Transmit Register
  26.  
  27. ; Host Status Register Bit Flags
  28. HRDF:                =    0            ; Host Receive Data Full
  29. HTDE:                =    1            ; Host Transmit Data Empty
  30.  
  31. INVBUF_SIZE:            =    4095
  32. MAX_LINES:            =    1000
  33. MAX_VERTICES:            =    1000
  34.  
  35. CULLDIST:            =    1550
  36.  
  37. ;======= Vertex
  38.  
  39. ; That's right. For speedreasons the Y comes before the X!
  40. Vertex.Y:    =    0
  41. Vertex.X:    =    1
  42. Vertex.Z:    =    2
  43. Vertex.SIZE:    =    3
  44.  
  45. ;======== Matrix
  46.  
  47. Matrix.MAX_DEPTH:    =    8                ; max number of rotations in the world
  48.  
  49. Matrix.XX:        =    0
  50. Matrix.XY:        =    1
  51. Matrix.XZ:        =    2
  52. Matrix.YX:        =    3
  53. Matrix.YY:        =    4
  54. Matrix.YZ:        =    5
  55. Matrix.ZX:        =    6
  56. Matrix.ZY:        =    7
  57. Matrix.ZZ:        =    8
  58. Matrix.SIZE:        =    9
  59.  
  60. ;======== GLOBAL MACROS ========
  61.  
  62. get:    MACRO
  63.     jclr    #0,X:<<HSR,*
  64.     movep    X:<<HTX,\1
  65.     ENDM
  66.  
  67. send:    MACRO
  68.     jclr    #1,X:<<HSR,*
  69.     movep    \1,X:<<HTX
  70.     ENDM
  71.  
  72. ;======== P-Memory Code ========
  73.  
  74.     ORG    P:$0000
  75.     jmp    <start
  76.  
  77.     ORG    P:$0040
  78. start:    jsr    <InitPipeline
  79.  
  80. _loop:
  81. ; synced to host: reception of rot+trans
  82.     jsr    <ReceiveTranslation
  83.     jsr    <ReceiveRotation
  84.  
  85. ; parallel with host: transformation, clipping, sorting
  86. ; beware, r0-r5 must be set with correct addys!
  87.     jsr    <Matrix.generate
  88.     jsr    <transform
  89.     jsr    <clipZ
  90. ;    jsr    <cullZ
  91.     move            x:<visibleLines,a
  92.     tst    a
  93.     jeq    <_send
  94.     jsr    <perspectivate
  95.     jsr    <clipXY
  96.     jsr    <cullShit
  97.     jsr    <sort
  98.  
  99. ; synced to host: send lines
  100. _send:    jsr    <sendLines
  101.  
  102.     jmp    <_loop
  103.  
  104. ; Receives rotation cos/sin values from CPU.
  105. ReceiveRotation:
  106.     move            #<SineX,r0
  107.     move            #<CosineX,r1
  108.     move            #<SineY,r2
  109.     move            #<CosineY,r3
  110.     move            #<SineZ,r4
  111.     move            #<CosineZ,r5
  112.     get    x:(r0)
  113.     get    x:(r1)
  114.     get    x:(r2)
  115.     get    x:(r3)
  116.     get    y:(r4)
  117.     get    y:(r5)
  118.     rts
  119.  
  120. ReceiveTranslation:
  121.     move            #<TransX,r0
  122.     do    #3,_loop
  123.     get    x:(r0)+
  124. _loop:    rts
  125.  
  126. transform:
  127.     move            #<Matrix,r4
  128.     move            #>-8,n4
  129.     move            #>transformedVertices,r5
  130.     move            #>vertices,r0
  131.     move            #<TransX,r1
  132.     move            #>-2,n1
  133.     move            x:(r1)+,a            ; a=TX
  134.     move            x:(r0)+,x0    y:(r4)+,y0
  135.     do    x:<numVertices,_loop
  136.     mac    x0,y0,a        x:(r0)+,x1    y:(r4)+,y0    ; x * MXX +
  137.     mac    x1,y0,a        x:(r0)-,x1    y:(r4)+,y0    ; y * MXY +
  138.     macr    x1,y0,a                y:(r4)+,y0    ; z * MXZ
  139.     move            x:(r1)+,a    a,y:(r5)+    ; Store X.
  140.     mac    x0,y0,a        x:(r0)+,x1    y:(r4)+,y0    ; x * MYX +
  141.     mac    x1,y0,a        x:(r0)-,x1    y:(r4)+,y0    ; y * MYY +
  142.     macr    x1,y0,a                y:(r4)+,y0    ; z * MYZ
  143.     move            x:(r1)+n1,a    a,y:(r5)+    ; Store Y.
  144.     mac    x0,y0,a        x:(r0)+,x1    y:(r4)+,y0    ; x * MZX +
  145.     mac    x1,y0,a        x:(r0)+,x1    y:(r4)+n4,y0    ; y * MZY +
  146.     macr    x1,y0,a        x:(r0)+,x0    y:(r4)+,y0    ; z * MZZ
  147.     move            x:(r1)+,a    a,y:(r5)+    ; Store Z.
  148. _loop:    rts    
  149.  
  150. ; This uses the transformed vertices and line-structures as input.
  151. ; It outputs transformed edgestructures without references.
  152. ; Also outputs z averages used later on..
  153. ; Now z culls and depthculls too!
  154. clipZ:    move            #>lines,r0
  155.     move            #>transformedVertices,r4
  156.     move            #>ZCenterTable,r1        ; count=0
  157.     move            #>TransformedLines,r5
  158.     move            #<Vertex.SIZE,n6
  159.     move            #<Vertex.SIZE,n3
  160.     move            r1,n4                ; Zlinebufstart
  161.     move            #>-2,n1
  162.     do    x:<numLines,_loop
  163.     move            x:(r0)+,b
  164.     asl    b        b,x0
  165.     add    x0,b        r4,y1                ; b=v1offset
  166.     add    y1,b                        ; b=v1adr
  167.     move            b,r6                ; y:(r6):v1
  168.     move            x:(r0)+,a
  169.     move                    y:(r6)+,x0    ; x0=v1.x
  170.     asl    a        a,x1        y:(r6)+,y0    ; y0=v1.y
  171.     add    x1,a                y:(r6)+,b    ; a=v2offset, b=v1.z
  172.     add    y1,a                        ; a=v2adr
  173.     move            a,r6                ; y:(r6):v2
  174.     move            r5,r3                ; r3: current trans. line
  175.  
  176.     IFNE    1
  177. ; special depthculling!!!
  178.     move            #>CULLDIST,x1
  179.     cmp    x1,b
  180.     jlt    <_bla
  181.  
  182.     move            (r6)+
  183.     move                    y:(r6)+,y1    ; y1=v2.y
  184.     move                    y:(r6)-,a    ; a=v2.z
  185.     cmp    x1,a                y:-(r6),x1    ; x1=v2.x
  186.     move            (r6)+n6
  187.     jge    <_next
  188.     tst    a        r5,r6                ; r6: current trans. line
  189.     jmi    <_clip2                        ; just cull..
  190.     jsr    <_store
  191.     jmp    <_next
  192.     ENDC
  193.  
  194. _bla:    move                    y:(r6)+,x1    ; x1=v2.x
  195.     move                    y:(r6)+,y1    ; y1=v2.y
  196.     tst    b                y:(r6)+,a    ; a=v2.z
  197.     jmi    <_clip
  198.     tst    a        r5,r6                ; r6: current trans. line
  199.     jmi    <_clip2                        ; just cull..
  200.     jsr    <_store
  201. _next:    move            r1,a                ; a=zlineadr
  202. _loop:    move            n4,x0                ; x0=zlinebuf
  203.     sub    x0,a                        ; a=zlineoffset
  204.     lsr    a                        ; a=#lines
  205.     move            a,x:<visibleLines        ; Store #unculled_lines.
  206.     rts
  207.  
  208. ; Clip the goddamn edge against the z-plane.
  209. ; v1 outside, v2 dunno yet
  210. _clip:    tst    a        r5,r6
  211.     jmi    <_next
  212.     jsr    <_store
  213.     move            #<0,x0
  214.     move            (r6)+
  215.     move            (r6)+
  216.     do    #2,_iloop
  217.     move                    y:(r6),x1    ; x1='ystart'=v1.z
  218.     move                    y:(r3),y1    ; y1='xstart'=v1.x/y
  219.     move                    y:(r6+n6),a    ; a='yend'=v2.x
  220.     sub    x1,a                y:(r3+n3),b    ; a='dy', b='xend'=v2.x/y
  221.     jsr    <intersect
  222.     add    y1,a
  223.     move                    a,y:(r3)+    ; Store intersected coord, proceed to next coord.
  224. _iloop:    move                    x0,y:(r6)    ; Store cut.
  225.     move                    x0,y:(r1+n1)    ; adjust z_avg!
  226.     jmp    <_next
  227.  
  228. ; Clip the goddamn edge against the z-plane.
  229. ; v2 outside, v1 inside
  230. _clip2:    jsr    <_store
  231.     move            #<0,x0
  232.     move            (r6)+
  233.     move            (r6)+
  234.     do    #2,_iloop2
  235.     move                    y:(r6+n6),x1    ; x1='ystart'=v1.z
  236.     move                    y:(r3+n3),y1    ; y1='xstart'=v1.x/y
  237.      move                    y:(r6),a    ; a='yend'=v2.z
  238.     sub    x1,a                y:(r3),b    ; a='dy', b='xend'=v2.x/y
  239.     jsr    <intersect
  240.     add    y1,a
  241.     move                    a,y:(r3+n3)    ; Store intersected coord, proceed to next coord.
  242.     move            (r3)+
  243. _iloop2:move                    x0,y:(r6+n6)    ; Store cut.
  244.     move                    x0,y:(r1+n1)    ; adjust z_avg!
  245.     jmp    <_next
  246.  
  247. ; Just store..
  248. _store:    move                    x0,y:(r5)+
  249.     move                    y0,y:(r5)+
  250.     move                    b,y:(r5)+
  251.     move                    x1,y:(r5)+
  252.     move                    y1,y:(r5)+
  253.     add    a,b                a,y:(r5)+
  254.     move                    b,y:(r1)+    ; Store average and increase linecount.
  255.     move                    r3,y:(r1)+    ; Store zlineadr.
  256.     rts
  257.  
  258. ; Perspectivate the transformed lines..
  259. ; Also transforms to screenspace (ie. centers it to screen coords).
  260. perspectivate:
  261.     move            #>TransformedLines,r0
  262.     move            #<Vertex.SIZE,n0
  263.     move            #>$80,y1
  264.     move            x:<visibleLines,a
  265.     lsl    a        #>InverseTable+$100,r1
  266.     do    a,_loop
  267.     IFNE    1
  268.     move                    y:(r0)+,x0    ; x0=X
  269.     mpy    x0,y1,a                y:(r0)+,x0    ; a=$100X,x0=Y
  270.     move                    y:(r0)-,n1    ; n1=Z
  271.     mpy    x0,y1,a        a0,x0                ; a=$100Y, x0=$100X
  272.     move            a0,y0
  273.     clr    b        x:(r1+n1),x1            ; x1=1/(Z+$100)
  274.     move            x1,y1
  275.     mpy    x1,y1,a        #>$80,y1
  276.     rep    #15
  277.     asr    a
  278.     move            a0,x1
  279.     clr    a        #<100,b1
  280.     mac    x1,y0,b        #<160,a1            ; b=Y'=$100Y/(Z+$100)
  281.     mac    x1,x0,a                b,y:(r0)-    ; a=X'=$100X/(Z+$100), Store Y'.
  282.     move                    a,y:(r0)+n0    ; Store X'.
  283.     ELSE
  284.     move                    y:(r0)+,x0    ; x0=X
  285.     mpy    x0,y1,a                y:(r0)+,x0    ; a=$100X,x0=Y
  286.     move                    y:(r0)-,n1    ; n1=Z
  287.     mpy    x0,y1,a        a0,x0                ; a=$100Y, x0=$100X
  288.     move            a0,y0
  289.     clr    b        x:(r1+n1),x1            ; x1=1/(Z+$100)
  290.     clr    a        #<100,b1
  291.     mac    x1,y0,b        #<160,a1            ; b=Y'=$100Y/(Z+$100)
  292.     mac    x1,x0,a                b,y:(r0)-    ; a=X'=$100X/(Z+$100), Store Y'.
  293.     move                    a,y:(r0)+n0    ; Store X'.
  294.     ENDC
  295. _loop:    rts
  296.  
  297. ; Cull out unwanted edges..
  298. cullShit:
  299. ; 3: collapse z_avg table to remove culled lines..
  300.     move            #<0,r3                ; visible count=0
  301.     move            #>ZCenterTable,r0        ; y:(r0):source
  302.     move            #<1,n0
  303.     move            r0,r1                ; y:(r1):dest
  304.     move                    y:(r0)+,a
  305.     do    x:<visibleLines,_cloop
  306.     tst    a                y:(r0)+,b
  307.     jmi    <_cnext
  308.     move                    a,y:(r1)+
  309.     move                    b,y:(r1)+
  310.     move            (r3)+                ; Increase visible count.
  311. _cnext:    move                    y:(r0)+,a
  312. _cloop:    move            r3,x:<visibleLines        ; Store # visible lines.
  313.     rts
  314.  
  315.     IFNE    0
  316. ; Separate z culling function.
  317. ; Edges too far away are culled, but also ones that are behind the camera.
  318. ; PRE: z avg table needs to be filled!
  319. cullZ:
  320. ; 2: Apply depthculling first..
  321.     move            #>ZCenterTable,r0
  322.     move            #>-2,n0
  323.     move            #>CULLDIST,y0            ; y0=culling depth
  324.     move            #<2,n1
  325.     move                    y:(r0)+,a    ; a=z(cullflag)
  326.     do    x:<visibleLines,_dloop
  327.     tst    a                y:(r0)+,r1    ; y:(r1): edge.
  328.     jmi    <_dnext
  329.     move            (r1)+n1                ; y:(r1): z1
  330.     move                    y:(r1)+,a    ; a=z1
  331.     cmp    y0,a                y:(r1+n1),b    ; b=z2
  332.     jlt    <_dnext
  333.     cmp    y0,b        #<$FF,x0
  334.     jlt    <_dnext
  335.     move                    x0,y:(r0+n0)    ; Mark as culled.
  336. _dnext:    move                    y:(r0)+,a    ; a=z(cullflag)
  337. _dloop:
  338.     rts
  339.     ENDC
  340.  
  341. ; Clips the lines against the sides of the screen..
  342. ; This also marks entries in the z_avg table as culled..
  343. clipXY:    move            #>TransformedLines,r0
  344.     move            #>ZCenterTable,r5
  345.     move            #<2,n5
  346.     move            #<Vertex.SIZE,n1
  347.     move            #<2,n0
  348.     move            r0,r1                ; y:(r1): current line
  349.     do    x:<visibleLines,_lineloop
  350.  
  351. ; left
  352.     move                    y:(r0)+,a
  353.     move                    y:(r0+n0),y1
  354.     or    y1,a        a,b
  355.     jpl    <_left_done
  356.     and    y1,b        b,a
  357.     jmi    <_cull
  358.     tst    a        #<0,x0                ; x0='cut_y'
  359.     jpl    <_left2nd
  360.     move            a,x1        y:(r0)+n0,y1    ; x1='ystart'=v1.x, y1='xstart'=v1.y
  361.     move                    y:(r0)+,a    ; a='yend'=v2.x
  362.     sub    x1,a                y:(r0),b    ; a='dy', b='xend'=v2.y
  363.     jsr    <intersect
  364.     add    y1,a                x0,y:(r1)+    ; Store cut.
  365.     move                    a,y:(r1)-    ; Store intersected coord.
  366.     jmp    <_left_done    
  367. _left2nd:
  368.     move                    y:(r0)+n0,b    ; b='xend'=v1.y
  369.     move                    y:(r0)+,x1    ; x1='ystart'=v2.x
  370.     sub    x1,a                y:(r0)-,y1    ; a='dy', y1='xstart'=v2.y
  371.     jsr    <intersect
  372.     add    y1,a                x0,y:(r0)+    ; Store cut.
  373.     move                    a,y:(r0)    ; Store intersected coord.
  374. _left_done:
  375.  
  376. ; right
  377.     move            r1,r0
  378.     move            #>320-1,x0            ; x0='cut_y'
  379.     move                    y:(r0)+,a
  380.     cmp    x0,a                y:(r0+n0),b
  381.     jgt    <_right1st
  382.     cmp    x0,b
  383.     jle    <_right_done
  384.     move            a,x1        y:(r0)+n0,y1    ; x1='ystart'=v1.x, y1='xstart'=v1.y
  385.     move                    y:(r0)+,a    ; a='yend'=v2.x
  386.     sub    x1,a                y:(r0)-,b    ; a='dy', b='xend'=v2.y
  387.     jsr    <intersect
  388.     add    y1,a                x0,y:(r0)+    ; Store cut.
  389.     move                    a,y:(r0)    ; Store intersected coord.
  390.     jmp    <_right_done    
  391. _right1st:
  392.     cmp    x0,b
  393.     jgt    <_cull
  394.     move                    y:(r0)+n0,b    ; b='xend'=v1.y
  395.     move                    y:(r0)+,x1    ; x1='ystart'=v2.x
  396.     sub    x1,a                y:(r0)-,y1    ; a='dy', y1='xstart'=v2.y
  397.     jsr    <intersect
  398.     add    y1,a                x0,y:(r1)+    ; Store cut.
  399.     move                    a,y:(r1)-    ; Store intersected coord.
  400. _right_done:
  401.  
  402. ; above
  403.     move            r1,r0
  404.     move            #<0,x0                ; x0='cut_y'
  405.     move            (r0)+
  406.     move                    y:(r0)+,x1
  407.     move                    y:(r0+n0),b
  408.     and    x1,b        b,a
  409.     jmi    <_cull                        ; both above? -> cull it!
  410.     or    x1,a        x1,a
  411.     jpl    <_above_done
  412.     tst    a        (r0)-n0
  413.     jpl    <_above2nd
  414.     move            a,x1        y:(r0)+n0,y1    ; x1='ystart'=v1.y, y1='xstart'=v1.x
  415.     move                    y:(r0+n0),a    ; a='yend'=v2.y
  416.     sub    x1,a                y:(r1+n1),b    ; a='dy', b='xend'=v2.x
  417.     jsr    <intersect
  418.     add    y1,a                x0,y:-(r0)    ; Store intersected coord.
  419.     move                    a,y:-(r0)    ; Store cut.
  420.     jmp    <_above_done    
  421. _above2nd:
  422.     move                    y:(r0)+n0,b    ; b='xend'=v1.x
  423.     move                    y:(r0+n0),x1    ; x1='ystart'=v2.y
  424.     sub    x1,a                y:(r1+n1),y1    ; a='dy', y1='xstart'=v2.x
  425.     jsr    <intersect
  426.     add    y1,a                x0,y:(r0+n0)    ; Store cut.
  427.     move                    a,y:(r1+n1)    ; Store intersected coord.
  428. _above_done:
  429.  
  430. ; under
  431.     move            r1,r0
  432.     move            #>200-1,x0            ; x0='cut_y'
  433.     move            (r0)+
  434.     move                    y:(r0)+,a
  435.     cmp    x0,a                y:(r0+n0),b
  436.     jle    <_under2nd
  437.     cmp    x0,b        (r0)-n0
  438.     jgt    <_cull                        ; Both under -> cull!
  439.     move                    y:(r0)+n0,b    ; b='xend'=v1.x
  440.     move                    y:(r0+n0),x1    ; x1='ystart'=v2.y
  441.     sub    x1,a                y:(r1+n1),y1    ; a='dy', y1='xstart'=v2.x
  442.     jsr    <intersect
  443.     add    y1,a                x0,y:-(r0)    ; Store intersected coord.
  444.     move                    a,y:-(r0)    ; Store cut.
  445.     jmp    <_under_done
  446. _under2nd:
  447.     cmp    x0,b        (r0)-n0
  448.     jle    <_under_done                    ; Both above -> leave it!
  449.     move            a,x1        y:(r0)+n0,y1    ; x1='ystart'=v1.y, y1='xstart'=v1.x
  450.     move                    y:(r0+n0),a    ; a='yend'=v2.y
  451.     sub    x1,a                y:(r1+n1),b    ; a='dy', b='xend'=v2.x
  452.     jsr    <intersect
  453.     add    y1,a                x0,y:(r0+n0)    ; Store cut.
  454.     move                    a,y:(r1+n1)    ; Store intersected coord.
  455. _under_done:
  456.  
  457. ; Check x after y clipping is done (due to inaccuracies of clipping!).
  458.     move                    y:(r1),a
  459.     move            #>320,x0
  460.     cmp    x0,a                y:(r1+n1),b
  461.     jhs    <_cull
  462.     cmp    x0,b
  463.     jhs    <_cull
  464.  
  465. _inc:    move            (r1)+n1
  466.     move            (r1)+n1                ; y:(r1): next edge
  467.     move            r1,r0                ; y:(r0): next edge
  468.     move            (r5)+n5                ; y:(r5): next z_avg
  469. _lineloop:
  470.  
  471. ; z culling was here!
  472.  
  473. _end:    rts
  474.  
  475. _cull:    move            #<$FF,x0
  476.     move                    x0,y:(r5)    ; Mark as invisible.
  477.     jmp    <_inc
  478.  
  479. ; Generic intersection routine.
  480. ; INPUT:
  481. ; x0: cut_y
  482. ; x1: ystart
  483. ; y1: xstart
  484. ; a: yend - ystart (=dy)
  485. ; b: xend
  486. ; OUTPUT:
  487. ; a0: intersected coord
  488. intersect:
  489.     IFNE    1
  490.  
  491. ; Warning, we assume r2,n2 isn't used!
  492.     sub    y1,b        x0,x:<shit            ; b=dx
  493.     move            #>$000040,x0        b,y0    ; x0=scalar, y0=dx
  494.     mpy    x0,y0,b        #<InverseTable,r2        ; b0=dx<<8
  495.     move            a,n2
  496.     abs    b        b0,a                ; n2=dy
  497.     move            b0,y0                ; y0=dx<<8
  498.     move            x:(r2+n2),x0            ; x0=1/dy
  499.     mpyr    y0,x0,b                        ; b=dx<<8/dy
  500.     tst    a
  501.     jpl    <_ok
  502.     neg    b
  503. _ok:    move                        b,y0
  504.     mpy    -x1,y0,a    x:<shit,x0
  505. ;    mac    +x0,y0,a
  506. ;    rep    #8
  507. ;    asr    a        
  508. ;    move            a0,a
  509.     mac    +x0,y0,a    #>$008000,x1
  510.     move            a0,y0
  511.     mpy    x1,y0,a
  512.  
  513.     ELSE
  514.  
  515.     sub    y1,b        a,x:<bla            ; b= xend-xstart (=dx)
  516.     tfr    b,a                        ; a=dx, Store dy.
  517.     abs    b        x0,x:<shit            ; b=abs(dx)
  518.     move            #>$000080,x0        b,y0    ; x0=scalar, y0=abs(dx)
  519.     mpy    x0,y0,b        x:<shit,x0            ; b=abs(dx)<<8
  520.     tst    a        x:<bla,y0            ; test denominator, y0=dy
  521.     andi    #$fe,ccr                    ; carry bit cleared by mpy
  522.     rep    #24
  523.     div    y0,b                        ; b := dx/dy (=slope)
  524.     jpl    <_divisorpos
  525.     neg    b
  526. _divisorpos:
  527.     move            b0,y0                ; a= yi= cut_y-ystart, y0= int(slope)
  528. ; a := yi(frac) * slope(fixedpoint)
  529.     mpy    +x0,y0,a
  530.     mac    -x1,y0,a
  531.     rep    #8
  532.     asr    a        
  533.     move            a0,a
  534.  
  535.     ENDC
  536.  
  537.     rts
  538.  
  539. ; Combsort implementation. In place sorting, not the fastest available
  540. ; algorithm... With little RAM there is no choice I'm afraid.
  541. sort:    clr    a        x:<visibleLines,b
  542.     move            #<1,a1
  543.     cmp    a,b        #<2,n1
  544.     jle    <_end
  545.     move            #<2,n2
  546.     move            #<2,n3                ; n3=element size
  547.     move            #>ZCenterTable,r0
  548.     lsr    b        b,y0                ; b=gapsize[0]=#elements/2
  549.     jmp    <_end_calculate_gap
  550.     
  551. _loop:    cmp    x0,b        #>0.769230769,y1
  552.     tlt    x0,b
  553.     move            b,x1
  554.     mpy    y1,x1,b                        ; b=gapsize
  555. _end_calculate_gap:
  556.     tfr    y0,a        b,x1
  557.     sub    x1,a        n3,x0
  558.     mpy    x0,x1,a        a,n6
  559.     asr    a        #<0,r4                ; r4=swapcount=0
  560.     move            a0,n0
  561.     move            r0,r2
  562.     lua    (r0)+n0,r1
  563.  
  564.     do    n6,_element_loop
  565.     move                    y:(r2)+n2,a    ; a=z1
  566.     move                    y:(r1)+n1,x0    ; b=z2
  567.     cmp    x0,a                        ; Decrement swapcount (assuming we'll correct it later)..
  568.     jge    <_no_swap
  569.     move                    y:-(r2),x1    ; x1=adr1
  570.     move                    y:-(r1),y1    ; y1=adr2
  571.     move                    x1,y:(r1)-    ; Store adr1.
  572.     move                    y1,y:(r2)-    ; Store adr2.
  573.     move                    a,y:(r1)+n1    ; Store z1.
  574.     move                    x0,y:(r2)+n2    ; Store z2.
  575.     move            (r4)+                ; Increment swapcount.
  576. _no_swap:
  577.     nop
  578. _element_loop:
  579.  
  580.     move            r4,a
  581.     tst    a        #>2,x0
  582.     jne    <_loop
  583.     cmp    x0,b
  584.     jge    <_loop
  585.  
  586. _end:    rts
  587.  
  588. ; Send lines (2*[x,y,z]) to host..
  589. sendLines:
  590.     move            #>ZCenterTable+1,r0
  591.     move            #<InverseTable,r2
  592.     move            #>5,y1                ; Scalar to transform to fixedpoint.
  593.     move            #<2,n0
  594.     move            x:<visibleLines,a
  595.     tst    a        #<3,n1
  596.     send    a
  597.     jeq    <_end
  598.     do    a,_edgeloop
  599.     move                    y:(r0)+n0,r1    ; Fetch edge addy.
  600.     move            #<$05,y0            ; Scalar to transform to integer.
  601.     move                    y:(r1+n1),x0    ; x0=X2
  602.      move                    y:(r1)+,a    ; a=X1
  603.     send    a                        ; Send X1.
  604.     sub    x0,a                y:(r1+n1),x1    ; a=dX=X2-X1, x1=Y2
  605.     move                    y:(r1)+,b    ; b=Y1
  606.     send    b                        ; Send Y1.
  607.     send    x0                        ; Send X2.
  608.     sub    x1,b        a,x0                ; b=dY=Y2-Y1, x0=dX
  609.     send    x1                        ; Send Y2.
  610.     cmpm    b,a                        ; If a > b..
  611.     tgt    x0,b                        ; .. d=dX, else d=dY
  612.     abs    b                y:(r1)+n1,x0    ; b=|d|, x0=g1
  613.     mpy    x0,y0,a        b,n2                ; a=g1 (int), n2=|d|
  614.     send    a                        ; Send g1 (int).
  615.     mpy    -x0,y1,a            y:(r1)+,x0    ; a0=-g1 (fp), x0=g2
  616.     mac    +x0,y1,a    x:(r2+n2),x0            ; a0=dg=g2-g1 (fp), x0=1/|d|
  617.     move            a0,x1                ; x1=dg (fp)
  618.     mpy    x0,x1,a                        ; a=g_step=dg/|d| (fp)
  619.     send    a                        ; Send g_step.
  620. _edgeloop:
  621. _end:    rts
  622.  
  623. ;======== non time-crucial stuff, all in external P-RAM ========
  624.  
  625. ; This initialises the pipeline in pixel-mode.
  626. InitPipeline:
  627. ; Set to linear addressing!
  628.     movec    #$FFFF,m0
  629.     movec    m0,m1
  630.     movec    m0,m2
  631.     movec    m0,m3
  632.     movec    m0,m4
  633.     movec    m0,m5
  634.     movec    m0,m6
  635.  
  636.     jsr    <GetInvTable
  637.     jsr    <GetObject
  638.     rts
  639.  
  640. ; Calculates 1/n table.
  641. GetInvTable:
  642.     move            #<InverseTable,r0
  643.     clr    a        #>1,x0
  644.     do    #INVBUF_SIZE,_loop
  645.     move            a,x1
  646.     move            x0,b
  647.     rep    #24
  648.     div    x1,b
  649.     add    x0,a        b0,x:(r0)+
  650. _loop:    rts
  651.  
  652. ; Gets wireframe object from host..
  653. GetObject:
  654.     get    a
  655.     lsl    a        a,x0
  656.     add    x0,a        x0,x:<numVertices        ; a=3*#vertices
  657.     move            #>vertices,r0
  658.     do    a,_vloop
  659.     get    x:(r0)+
  660. _vloop:    get    a
  661.     move            a,x:<numLines
  662.     lsl    a        #>lines,r0            ; a=2*#lines
  663.     do    a,_lloop
  664.     get    x:(r0)+
  665. _lloop:    rts
  666.  
  667. ;======== Matrix
  668.  
  669. ; This is perfection.
  670. ; Total cycles on 56001: 58 (!)
  671. ; INPUT:
  672. ; r0: X-sine
  673. ; r1: X-cosine
  674. ; r2: Y-sine
  675. ; r3: Y-cosine
  676. ; r4: Z-sine
  677. ; r5: Z-cosine
  678. Matrix.generate:
  679.     move            #<Matrix,r6
  680.  
  681. ; XX := + x*cos(b)*cos(c)
  682. ; XY := - y*cos(b)*sin(c)
  683. ; XZ := + z*sin(b)
  684.     move            x:(r3),x1    y:(r5),y1
  685. ; x0:-- x1:r3 y0:-- y1:r5
  686.     mpyr    +x1,y1,a    x:(r0),x0    y:(r4),y0    ; r3*r5
  687.  
  688. ; x0:r0 x1:r3 y0:r4 y1:r5
  689.     mpyr    -x1,y0,a    x:(r2),x1    a,y:(r6)+    ; -r3*r4
  690. ; x0:r0 x1:r3 y0:r2 y1:r5
  691.     move                    a,y:(r6)+
  692.  
  693.     move                    x1,y:(r6)+    ; r2
  694.     
  695. ; YX := + x*sin(a)*sin(b)*cos(c)+cos(a)*sin(c)
  696. ; YY := + y*cos(a)*cos(c)-sin(a)*sin(b)*sin(c)
  697. ; YZ := - z*sin(a)*cos(b)
  698.     mpyr    +x0,x1,a            y:(r5),y0    ; r0*r2
  699. ; x0:r0 x1:r3 y0:r5 y1:r5
  700.     move            a,y1
  701.     mpy    +y0,y1,a    x:(r1),x1    y:(r4),y1    ; a*r5
  702. ; x0:r0 x1:r1 y0:r5 y1:r4
  703.     macr    +x1,y1,a            y:(r5),y1    ; a+r1*r4
  704. ; x0:r0 x1:r1 y0:r5 y1:r5
  705.  
  706.     mpy    +x1,y1,a    x:(r2),x1    a,y:(r6)+    ; r1*r5
  707. ; x0:r0 x1:r2 y0:r5 y1:r5
  708.     mpyr    -x0,x1,b            y:(r4),y0    ; r0*r2
  709. ; x0:r0 x1:r2 y0:r4 y1:r5
  710.     move            b,y1
  711.     macr    +y0,y1,a    x:(r3),x1    y:(r4),y1    ; a+b*r4
  712. ; x0:r0 x1:r3 y0:r4 y1:r4
  713.  
  714.     mpyr    -x0,x1,a    x:(r2),x1    a,y:(r6)+    ; r0*r3
  715. ; x0:r0 x1:r2 y0:r4 y1:r4
  716.  
  717. ; ZX := + x*sin(a)*sin(c)-cos(a)*sin(b)*cos(c)
  718. ; ZY := + y*cos(a)*sin(b)*sin(c)+sin(a)*cos(c)
  719. ; ZZ := + z*cos(a)*cos(b)
  720.     mpy    +x0,y1,a    x:(r1),x0    a,y:(r6)+    ; r0*r4
  721. ; x0:r1 x1:r2 y0:r4 y1:r4
  722.     mpyr    -x0,x1,b    x:(r2),x0    y:(r5),y1    ; r1*r2
  723. ; x0:r2 x1:r2 y0:r4 y1:r5
  724.     move            b,x1
  725.     macr    +x1,y1,a    x:(r1),x1    y:(r4),y0    ; a+b*r5
  726. ; x0:r2 x1:r1 y0:r4 y1:r5
  727.  
  728.     mpyr    +x1,x0,a    x:(r3),x0    a,y:(r6)+    ; r1*r2
  729. ; x0:r3 x1:r1 y0:r4 y1:r5
  730.     move            a,y1
  731.     mpy    +y0,y1,a    x:(r0),x1    y:(r5),y1    ; a*r4
  732. ; x0:r3 x1:r0 y0:r4 y1:r5
  733.     macr    +x1,y1,a    x:(r1),x1            ; r0*r5
  734. ; x0:r3 x1:r1 y0:r4 y1:r5
  735.  
  736.     mpyr    +x1,x0,a            a,y:(r6)+    ; r1*r3
  737.  
  738.     move                    a,y:(r6)+
  739.     rts
  740.  
  741. p_memory_end:
  742.  
  743. ;======== X-Memory Code ========
  744.  
  745.     ORG    X:$0000
  746.  
  747. SineX:    DS    1
  748. CosineX:DS    1
  749. SineY:    DS    1
  750. CosineY:DS    1
  751.  
  752. TransX:    DS    1
  753. TransY:    DS    1
  754. TransZ:    DS    1
  755.  
  756. numVertices:
  757.     DS    1
  758. numLines:
  759.     DS    1
  760. visibleLines:
  761.     DS    1
  762. bla:    DS    1
  763. shit:    DS    1
  764.  
  765. InverseTable:
  766.     DS    INVBUF_SIZE
  767.  
  768. ;======== EXTERNAL X RAM
  769.  
  770. vertices:
  771.     DS    Vertex.SIZE*MAX_VERTICES
  772. lines:    DS    2*MAX_LINES
  773.  
  774. x_memory_end:
  775. ; X<$3000 !!
  776.  
  777.     ORG    X:$3BDB                        ; for mixer
  778.  
  779. ;======== Y-Memory Code ========
  780.  
  781.     ORG    Y:$0000
  782.  
  783. SineZ:    DS    1
  784. CosineZ:DS    1
  785.  
  786. ;======== Matrix
  787.  
  788. Matrix:    DS    Matrix.SIZE
  789.  
  790. ;======== EXTERNAL Y RAM
  791.  
  792.     ORG    Y:p_memory_end                    ; out of range from p-code
  793.  
  794. ;======== PrimitiveMesh
  795.  
  796. transformedVertices:
  797.     DS    Vertex.SIZE*MAX_VERTICES
  798. TransformedLines:
  799.     DS    Vertex.SIZE*2*MAX_LINES
  800. ZCenterTable:
  801.     DS    MAX_LINES*2                    ; z, linenum
  802. y_memory_end:
  803. ; Y<$3BF2 !!
  804.