home *** CD-ROM | disk | FTP | other *** search
/ Fujiology Archive / fujiology_archive_v1_0.iso / !FALCON / LINEOUT / OUT.ZIP / SOURCE.ZIP / S_FLY.ASM < prev    next >
Assembly Source File  |  2003-10-21  |  74KB  |  2,969 lines

  1. ; --------------------------------------------------------------------------
  2. ;
  3. ; human fly - dsp part
  4. ;
  5. ; Global:
  6. ;
  7. ; This is useable as both:
  8. ; - a serial CPU<->DSP pipeline
  9. ; - a parallel CPU<->DSP pipeline
  10. ;
  11. ; This program leaves enough DSP RAM free to enable the use of a dsp module
  12. ; player. Some sacrifices had to be made.
  13. ;
  14. ; Limitations:
  15. ; - max viewport width = 320
  16. ; - max viewport height = 200
  17. ;
  18. ; NOTE: you can increase these when you decrease #polys or don't want dsp
  19. ; mixer!
  20. ;
  21. ; Remote Procedure Calls and a command stack are provided to provide
  22. ; generic behaviour.
  23. ;
  24. ; Please note there are two ways to do texturemapping. The first is storing
  25. ; textures in dsp ram and sending pixels. This enables the fastest
  26. ; texturemapping. The second is sending offsets, which is somewhat slower.
  27. ; "Polygon.storeTexture" can store two highcolor and two 7bpp
  28. ; 64*64 textures.
  29. ;
  30.  
  31. ; TODO: Optimise texture-vertex table -> in poly stuff
  32. ;       This would save loads of space!
  33.  
  34. ; TODO: Optimize MeshElement to only 2 words. This saves alot of
  35. ;       X RAM. Requires changing TransformObject.transform,
  36. ;       PrimitiveMesh.sort and PrimitiveMesh.paint.
  37. ;       $oopppp:$--zzzz (o: object handle, p: primitive address, z: depth)
  38.  
  39. ;======== GLOBAL EQUATES ========
  40.  
  41. PBC:                =    $FFE0            ; Port B Control Register
  42. HSR:                =    $FFE9            ; Host Status Register
  43. HRX:                =    $FFEB            ; Host Receive Register
  44. HTX:                =    $FFEB            ; Host Transmit Register
  45.  
  46. ; Host Status Register Bit Flags
  47. HRDF:                =    0            ; Host Receive Data Full
  48. HTDE:                =    1            ; Host Transmit Data Empty
  49.  
  50. INVBUF_SIZE:            =    320            ; = max(MAX_X,MAX_Y)
  51.  
  52.     INCLUDE    H_FLYRPC.I
  53.  
  54. ;======== Dispatcher
  55.  
  56. Dispatcher.MAX_COMMANDS:    =    512
  57.  
  58. ;======== ObjectRegistry
  59.  
  60. Object.CAPACITY:        =    8192
  61. Object.MAX_OBJECTS:        =    32            ; max. amount of transformed objects
  62.  
  63. ;======== BoundingBox
  64.  
  65. ; yes it's true, there are 8 corners in a box, now go somewhere else,
  66. ; fartface. i.e. 2 corner notation..
  67. BoundingBox.SIZE:        =    3*2
  68.  
  69. ;======== Viewport
  70.  
  71. Viewport.MAX_Y:            =    200            ; Unfortunate... But this eats mem!
  72. Viewport.SIZE:            =    Viewport.settingsTableEnd-Viewport.settingsTable
  73.  
  74. ;======== Polygon
  75.  
  76. Polygon.TEXTUREBUFFER_SIZE:    =    64*64*2            ; able to store two 64*64 bitmaps
  77.  
  78. ; wrappable texturing on/off
  79. WRAPCRAP:            =    1
  80.  
  81. ;======== PrimitiveMesh
  82.  
  83. PrimitiveMesh.MAX_ELEMENTS:    =    1000
  84. PrimitiveMesh.MAX_VERTICES:    =    900            ; Depends on MAX_Y.
  85.  
  86. ;======= Vertex
  87.  
  88. ; That's right. For speedreasons the Y comes before the X!
  89. Vertex.Y:    =    0
  90. Vertex.X:    =    1
  91. Vertex.Z:    =    2
  92. Vertex.SIZE:    =    3
  93.  
  94. ;======= Primitive
  95.  
  96. Primitive.TYPE:    =    0                    ; primitive/shading/extended type
  97.  
  98. ;======= Line
  99.  
  100. Line.TYPE:    =    0                    ; primitive/shading/extended type
  101. Line.VERTEX1:    =    1                    ; offset to vertex 1
  102. Line.VERTEX2:    =    2                    ; offset to vertex 2
  103. Line.SIZE:    =    3
  104.  
  105. ;======= Sprite
  106.  
  107. Sprite.TYPE:    =    0                    ; primitive/shading/extended type
  108. Sprite.VERTEX:    =    1                    ; offset to vertex
  109. Sprite.SIZE:    =    2
  110.  
  111. Primitive.SHADEMASK:    =    %1110000000000000
  112. Primitive.SHADEMUL:    =    %10000000000
  113.  
  114. ; Shade types for sprites
  115. Sprite.REPLACED:    =    %0000000000000000
  116. Sprite.MIXED:        =    %0010000000000000
  117.  
  118. ; Shade types for polygons
  119. Line.FLATSHADED:    =    %0000000000000000
  120. Line.GOURAUDSHADED:    =    %0010000000000000
  121. Line.PHONGSHADED:    =    %0100000000000000
  122.  
  123. ; Shade types for polygons
  124. Polygon.FLATSHADED:    =    %0000000000000000
  125. Polygon.GOURAUDSHADED:    =    %0010000000000000
  126. Polygon.PHONGSHADED:    =    %0100000000000000
  127. Polygon.TEXTUREMAPPED:    =    %0110000000000000
  128. Polygon.ENVMAPPED:    =    %1000000000000000
  129. Polygon.ALPHATEXTURED:    =    %1010000000000000
  130. Polygon.BUMPMAPPED:    =    %1100000000000000
  131.  
  132. ; Primitive types
  133. Primitive.TYPEMASK:    =    %0001110000000000
  134. Primitive.TYPESHIFT:    =    10
  135. Primitive.TYPEMUL:    =    1<<(-(Primitive.TYPESHIFT-23))
  136. Primitive.SPRITETYPE:    =    %0000000000000000
  137. Primitive.LINETYPE:    =    %0000010000000000
  138. ; Other types are polygons, %10 :== triangle, %11 :== quadrangle, etc.
  139.  
  140. ; TableLookup mask
  141. Primitive.TEXTUREMASK:    =    %0000001111111111
  142.  
  143. ;======== MeshElement
  144.  
  145. MeshElement.BASE:    =    0                ; startaddress of vertex table
  146. MeshElement.REF:    =    1                ; address of element
  147. MeshElement.Z:        =    2                ; Z coordinate of element
  148. MeshElement.SIZE:    =    3
  149.  
  150. ;======== Matrix
  151.  
  152. Matrix.MAX_DEPTH:    =    8                ; max number of rotations in the world
  153.  
  154. Matrix.XX:        =    0
  155. Matrix.XY:        =    1
  156. Matrix.XZ:        =    2
  157. Matrix.YX:        =    3
  158. Matrix.YY:        =    4
  159. Matrix.YZ:        =    5
  160. Matrix.ZX:        =    6
  161. Matrix.ZY:        =    7
  162. Matrix.ZZ:        =    8
  163. Matrix.TX:        =    9
  164. Matrix.TY:        =    10
  165. Matrix.TZ:        =    11
  166. Matrix.SIZE:        =    12
  167.  
  168. ;======== GLOBAL MACROS ========
  169.  
  170. get:    MACRO
  171.     jclr    #0,X:<<HSR,*
  172.     movep    X:<<HTX,\1
  173.     ENDM
  174.  
  175. send:    MACRO
  176.     jclr    #1,X:<<HSR,*
  177.     movep    \1,X:<<HTX
  178.     ENDM
  179.  
  180. ;======== P-Memory Code ========
  181.  
  182.     ORG    P:$0000
  183.     jmp    <START
  184.  
  185.     ORG    P:$0040
  186.  
  187. ;======== TransformObject
  188.  
  189. ; Now transform this puppy. Nasty thing is we only have a 256 word inverse
  190. ; table. With some algebra tricks we can use full range division, using
  191. ; little extra cycles. Better than some 32 cycles normally required for rep
  192. ; and 15 div combination.
  193. ; INPUT:
  194. ; x:(r0)=src vertices, x:(r1)=center coords, y:(r2)=invtable,
  195. ; y:(r3)=invtable (+offset), y:(r4)=matrix, y:(r5)=dst vertices
  196. ; y:(r6)=translation vector
  197. ; n4= matrix jumpback, n6= translation jumpback
  198. ; a=TZ, b=#vertices, x0=1st vertex.Y, y0=Matrix.ZX
  199. Vertex.transInt:
  200.     do    b,_vertexloop
  201.  
  202. ; 32.000.0000 / 58 cycles > 550.000 rotate-perspectivations / sec.
  203. ; calc z
  204.     mac    x0,y0,a        x:(r0)+,x1    y:(r4)+,y0
  205.     mac    x1,y0,a        x:(r0)-,x1    y:(r4)+n4,y0
  206.     macr    x1,y0,a        x:<Viewport.Focal,x1        ; a := Z, x1 := focal length
  207.  
  208. ; Calc 1/Z and prepare for the x coordinate.
  209.     add    x1,a                a,y:(r5)-    ; Z := Z + focal, Store Z.
  210.     move            a,x1        y:(r3),y1    ; x1 := Z, y1 := 1/128
  211.     mpyr    x1,y1,a                y:(r6)+,b    ; a := Z div 128, b := TX
  212.     move            a,n2                ; n2 := Z div 128
  213.     move                    y:(r4)+,y0
  214.     mac    x0,y0,b                y:(r2+n2),y1    ; y1 := 1 div (Z div 128)
  215.     mpyr    y1,x1,a        x:(r0)+,x1    y:(r4)+,y0    ; a := Z div (Z div 128)
  216.     mac    x1,y0,b        a,n2                ; n2 := Z div (Z div 128)
  217.     move            x:(r0)-,x1    y:(r4)+,y0
  218.     macr    x1,y0,b                y:(r2+n2),x1    ; x1 := 1 div (Z div (Z div 128))
  219.     mpyr    y1,x1,a        n3,x1                ; a := (1 div (Z div 128))(1 div (Z div (Z div 128))) ~= 1 / Z, x1 := 128
  220.     move            a,y1                ; 
  221.     mpy    x1,y1,a        x:(r1)+,b    b,y1        ; a := (1/Z)<<8, b := XCenter, y1 := X
  222.  
  223. ; calc x
  224.     move                    y:(r4)+,y0
  225.     move            a0,x1                ; x1 := 1/Z
  226.     macr    y1,x1,b        x:<Viewport.Aspect,y1        ; X' = b := XCenter + X * 1/Z, x1 := aspect ratio
  227.     move                    y:(r6)+,a    ; a := TY
  228.  
  229. ; calc y
  230.     mac    x0,y0,a        x:(r0)+,x0    y:(r4)+,y0
  231.     mac    x0,y0,a        x:(r0)+,x0    y:(r4)+,y0
  232.     macr    x0,y0,a                b,y:(r5)-    ; b := YCenter, store X'.
  233.     move            a,x0                ; x0 := Y
  234.  
  235.     mpy    x0,y1,a        x:(r1)-,b            ; a = Ys := Y*aspect
  236.     move                    a,y1        ; y1 := Ys
  237.     mac    y1,x1,b                y:(r6)+n6,a    ; Y' = b := YCenter + Y * 1/Z, a := TZ
  238.     macr    y1,x1,b                y:(r4)+,y0
  239.     move            x:(r0)+,x0    b,y:(r5)+n5    ; Store Y'.
  240. _vertexloop:
  241.     rts
  242.  
  243. ; INPUT:
  244. ; x:r0: stored parameter (object handle)
  245. TransformObject.transformStored:
  246.     move            x:(r0)+,n0
  247.  
  248. ; INPUT:
  249. ; n0: objecthandle
  250. TransformObject.transform:
  251.     jsr    <BoundingBox.calcRectangle
  252.     tst    a
  253.     jeq    <_end
  254.  
  255. ; n0: objecthandle
  256.     jsr    <Object.get
  257. ; x:r0: object (untransformed)
  258.  
  259. ; Increase baseHandle.
  260.     move            x:>PrimitiveMesh.baseHandle,a
  261.     move            #>1,x0
  262.     add    x0,a        x:>PrimitiveMesh.nextVertex,r5
  263.     move            a,x:>PrimitiveMesh.baseHandle
  264.  
  265.     move            x:(r0)+,b            ; a= #vertices+#normals
  266.     move            x:(r0)+,x0            ; x0= #normals
  267.     sub    x0,b        x0,n0                ; b= #vertices, n0= #normals
  268.  
  269.     jsr    <Vertex.transform
  270. ; n0 = normalcount
  271. ; r4 = matrix
  272. ; r5 = dest. normals
  273.  
  274.     move            n0,a
  275.     tst    a
  276.     jeq    <_end_normals
  277.  
  278. ; 32.000.0000 / 24 cycles = 1.333.333 normalrotations / sec.
  279.     do    n0,_normalloop
  280.     mpy    x0,y0,a        x:(r0)+,x1    y:(r4)+,y0    ; x * MZX +
  281.     mac    x1,y0,a        x:(r0)-,x1    y:(r4)+n4,y0    ; y * MZY +
  282.     mac    x1,y0,a                y:(r4)+,y0    ; z * MZZ
  283.     move                    a,y:(r5)-    ; Store Z.
  284.     mpy    x0,y0,a        x:(r0)+,x1    y:(r4)+,y0    ; x * MXX +
  285.     mac    x1,y0,a        x:(r0)-,x1    y:(r4)+,y0    ; y * MXY +
  286.     mac    x1,y0,a                y:(r4)+,y0    ; z * MXZ
  287.     move                    a,y:(r5)-    ; Store X.
  288.     mpy    x0,y0,a        x:(r0)+,x1    y:(r4)+,y0    ; x * MYX +
  289.     mac    x1,y0,a        x:(r0)+,x1    y:(r4)+,y0    ; y * MYY +
  290.     mac    x1,y0,a        x:(r0)+,x0    y:(r4)+,y0    ; z * MYZ
  291.     move                    a,y:(r5)+n5    ; Store Y.
  292. _normalloop:
  293. _end_normals:
  294.     move            (r0)-
  295.     move            (r5)-
  296.     move            (r5)-
  297.  
  298. ; Kick primitives onto mesh right here...
  299.     move            x:>PrimitiveMesh.nextVertex,r6
  300.     move            r5,x:>PrimitiveMesh.nextVertex    ; Store address for next transformed vertices.
  301.     move            #>PrimitiveMesh.primitiveTable,r2
  302.     move            x:(r0)+,a            ; a= number of 2d vertices
  303.     asl    a        r0,y:(r6)            ; Store address of 2d vertices.
  304.     move            a,n0
  305.     move            x:(r2)+,a            ; a= primitivecounter
  306.     move            a,r3
  307.     asl    a        a,x0
  308.     add    x0,a        r6,r5                ; r5= address of transformed vertices
  309.     move            a,n2                ; n2= offset to next primitive in mesh
  310.     move            (r0)+n0                ; r0= primitivetable
  311.     move            (r2)+n2                ; r2= address of next primitive in mesh
  312.  
  313.     move            #>PrimitiveMesh.baseTable,r1
  314.     move            x:>PrimitiveMesh.baseHandle,n1
  315.     move            #<2,n2
  316.     move            r5,x:(r1+n1)            ; Store address of vertexbase in table.
  317.  
  318.     do    x:(r0)+,_calc_z_loop
  319.     IFNE    1
  320.     move            r5,x:(r2)+            ; Store pointer to vertices-base.
  321.     clr    a        r0,x:(r2)+            ; Store object primitive address in the mesh.
  322.     ELSE
  323. ; TODO: possibly introduce the efficient prim-table handling here.
  324.     move            x:>PrimitiveMesh.baseHandle,x0
  325.     move            #>$008000,x1
  326.     mpy    x0,x1,b        r0,a
  327.     move            b1,x0
  328.     or    x0,a
  329.     clr    a        a,x:(r2)+            ; Store vertexbasehandle|primitive address
  330.     ENDC
  331.     move            x:(r0)+,a1            ; a1= primitivetype
  332.     move            a1,n3                ; n3= primitivetype
  333.     move            #>Primitive.TYPEMASK,x0
  334.     and    x0,a        #>Primitive.LINETYPE,x0
  335.     move            a1,n1
  336.     move            r0,y:<PrimitiveMesh.primitive
  337.     tst    a        x:(r0)+,y0            ; y0= index of 1st vertex
  338.     jne    <_not_sprite
  339.     move            #>Vertex.SIZE,x0        ; / Get offset to sprite vertex.
  340.     mpy    x0,y0,a        (r5)+                ; |
  341.     asr    a        (r5)+                ; |
  342.     move            a0,n5                ; \
  343.     move            (r5)+
  344.     move                    y:(r5+n5),x0    ; x0= z
  345.     move            (r5)-
  346.     tfr    x0,b        (r5)-                ; b= z
  347.     tst    b        #<1,n0
  348.     jle    <_dont_store
  349.     jmp    <_store_primitive
  350. _not_sprite:
  351.     cmp    x0,a        #>Vertex.SIZE,x0        ; Get offset to line vertex.
  352.     jne    <_not_line
  353.     mpy    x0,y0,a        #<3,n5
  354.     asr    a
  355.     move            (r5)+n5
  356.     move            a0,n5
  357.     move            x:(r0)+,a
  358.     asl    a        a,y0
  359.     add    y0,a                y:(r5+n5),b
  360.     move            a1,n5
  361.     move            #<2,n0
  362.     tfr    b,a                y:(r5+n5),x0
  363.     or    x0,a        (r5)-                ; v1 or v2 behind cam -> out
  364.     move            (r5)-
  365.     jmi    <_dont_store
  366.     add    x0,b
  367.     asr    b                        ; b=(v1.z+v2.z)/2
  368.     move            b,x0
  369.     jmp    <_store_primitive
  370. _not_line:
  371. _polygon:
  372.     ;move            #>Vertex.SIZE,x0        ; / Get offset to p0 vertex.
  373.     mpy    x0,y0,a        (r5)+                ; |
  374.     asr    a        x:(r0)+,y0            ; |
  375.     move            a0,n5                ; \
  376.     mpy    x0,y0,a
  377.     lua    (r5)+n5,r1
  378.  
  379.     asr    a        x:(r0)+,y0            ; 
  380.     move            a0,n5                ; 
  381.     mpy    x0,y0,b                y:(r1)+,a    ; a := p0.y
  382.     lua    (r5)+n5,r6
  383.  
  384.     nop
  385.     asr    b                y:(r6)+,x0    ; x0= p1.y
  386.     move            b0,n5                ; 
  387.     sub    x0,a                y:(r6)+,y1    ; a= p0.y - p1.y, y1= p1.x
  388.     move                    y:(r6),b    ; x1= p1.z
  389.     lua    (r5)+n5,r6
  390.  
  391.     tst    b        b,x:<Polygon.z
  392.     jle    <_dont_store
  393.  
  394.     move            a,x1        y:(r6)+,b    ; b= p2.y, x1= p0.y - p1.y
  395.     sub    x0,b                y:(r1)+,a    ; a= p0.x
  396.     sub    y1,a        b,y0                ; y0= p2.y - p1.y
  397.     move                    y:(r6)+,b    ; b= p2.x
  398.     sub    y1,b        a,y1                ; y1= p0.x - p1.x
  399.  
  400.     mpy    +y0,y1,a    b,x0        y:(r1),b    ; a= (p0.x - p1.x)(p2.y - p1.y), x0= p2.x - p1.x, b= p0.z
  401.  
  402.     tst    b        x:<Polygon.z,y1
  403.     jle    <_dont_store
  404.     add    y1,b        n1,y0
  405.  
  406. ; Okay fine.. now we need to test the other points for negative Z as well!
  407.     move            #1<<(-(Primitive.TYPESHIFT-23)),y1
  408.     mpy    y0,y1,b        b,x:<Polygon.z
  409.     move            b,r1                ; r1= points-1
  410.     move            b,x:<Polygon.points
  411.     move            (r1)-
  412.     move            (r1)-                ; r1= points-(1+2)
  413.     move                    y:(r6),b    ; b=p2.z
  414. _addloop:
  415.     tst    b        x:<Polygon.z,y1
  416.     jle    <_dont_store
  417.     add    y1,b                        ; Add z to z total.
  418.     move            b,x:<Polygon.z
  419.     move            r1,b
  420.     tst    b        x:(r0)+,b            ; b= index
  421.     jeq    <_all_done
  422.     asl    b        b,y0
  423.     add    y0,b        r5,y0                ; b=index*3=offset
  424.     add    y0,b        #<Vertex.Z,n6            ; b=offset to next vertex
  425.     move            b1,r6                ; r6= vertex
  426.     move            (r1)-                ; Decrease loopcounter.
  427.     move                    y:(r6+n6),b    ; b= Vertex.Z
  428.     jmp    <_addloop
  429. _all_done:
  430.  
  431. ; Calculate z average and normal-direction.
  432.     move            x:<Polygon.points,r1
  433.     move            #>InverseTable,r4
  434.     move            (r1)+
  435.     move            r1,n4
  436.     move            x:<Polygon.z,y0
  437.     move                    y:(r4+n4),y1
  438.     mpyr    y0,y1,b                        ; b= ztotal/pointnum
  439.     mac    -x0,x1,a    b,x0                ; -(p0.y - p1.y)*(p2.x - p1.x)
  440. _jmp_instr:
  441.     jge    <_store_primitive
  442. _dont_store:
  443.     move            (r2)-n2                ; Culled primitive, don't store base
  444.  
  445. ; Increase sourceaddress to next primitive...
  446. _end_calc_z_loop:
  447.     clr    a        (r5)-
  448. ; Calculate tailsize of vertex-reference.
  449.     move            n3,a1                ; a= primitivetype
  450.     move            #>1,b
  451.     move            #>Primitive.SHADEMASK,x0
  452.     and    x0,a        b,x1
  453.     jeq    <_got_size
  454.     add    x1,b        #>Polygon.ALPHATEXTURED,x0
  455.     cmp    x0,a
  456.     jlt    <_got_size
  457.     add    x1,b
  458. _got_size:
  459.     move                    y:<PrimitiveMesh.primitive,r0
  460.     move            n1,x0
  461.     tfr    x1,a        #1<<(-(Primitive.TYPESHIFT-23)),y0
  462.     mac    x0,y0,a        b,n0                ; a= (points-1+1)*tailsize
  463. ; Now add the tailsizes to get address of next primitive.
  464.     rep    a
  465.     move            (r0)+n0
  466. _calc_z_loop:
  467.  
  468. ; Store primitivecounter.
  469.     move            r3,x:PrimitiveMesh.primitiveTable
  470. _end:    rts
  471.  
  472. _store_primitive:
  473.     move            x0,x:(r2)+            ; Store Z.
  474.     move            (r3)+                ; Increase primitivecounter.
  475.     jmp    <_end_calc_z_loop
  476.  
  477. ;======== Polygon
  478.  
  479. EDGE_ROUNDING:    =    1                    ; 0: compatible with 68K, 1: more accurate
  480.  
  481. ; Definetely the fastest scan converter around.
  482. ; USES:
  483. ; x:Polygon.vsize: 1=flat shade, 2=gouraud, 3=tmap, 4=gourtmap, 5=envtmap/bump
  484. ; INPUT:
  485. ; x:(r6): polygon table
  486. Polygon.drawEdges:
  487.     move            x:<Polygon.vsize,n6
  488.     move            #>InverseTable,r3
  489.     move            #>Polygon.LeftEdge,r0
  490.     move            #>Polygon.RightEdge,r1
  491.     move            n6,n5
  492.     move            n6,r4
  493.     move            r6,r5
  494.     move            (r4)+
  495.     move            (r6)+n6                ; to next point
  496.     move            (r6)+
  497.     move            r4,n4                ; n4= offset to next point
  498.  
  499. ; r5= pt1, r6= next pt
  500.     do    x:<Polygon.points,_do_line
  501.     move            x:(r5)+,a            ; a=current point's y
  502.     move            r6,r4
  503.     move            x:(r6)+,b            ; b=next point's y
  504.     sub    a,b        x:<Polygon.top,y1
  505.     jlt    <_do_left_side
  506.     jeq    <_end_line
  507.     move            b,n3
  508.     move            r0,b0
  509.     jmp    <_end_swap
  510. _do_left_side:
  511. ; Calculate start y offset.
  512. ; Swap left and right edges.
  513.     add    b,a        r5,x0
  514.     neg    b        r6,r5
  515.     move            b,n3
  516.     move            x0,r6
  517.     move            r1,b0
  518. _end_swap:
  519.     sub    y1,a        n6,x0                 ; a=startoffset
  520.     move            a,y1
  521.     mpy    x0,y1,a                y:(r3+n3),y1    ; a0=startoffset*vsize*2, y1=1/dy
  522.     asr    a        n6,n2                ; a0=startoffset*vsize 
  523.     add    a,b        r0,y0
  524.     move            b0,r0
  525.     IFNE    EDGE_ROUNDING
  526.     move            #<$80,x1
  527.     ELSE
  528.     move            #<0,x1
  529.     ENDC
  530.  
  531. ; Speedy.. but could be better when doing u and v in one go.
  532.     do    n6,_coord_loop
  533.     move            x:(r6)+,x0            ; x0= right x
  534.     mpy    +x0,y1,b    x:(r5)+,x0            ; b= rx/dy, x0= left x
  535.     tfr    x0,a        r0,r2                ; a= left x, r2=edge
  536.     mac    -x0,y1,b    x1,a0                 ; b= dx/dy, a0=x.frac (for rounding)
  537.  
  538. ; rep is shit with interrupts :(
  539. ;    rep    n3
  540.     do    n3,_bla
  541.     add    b,a                a1,y:(r2)+n2    ; a=lx:=lx+step, store lx
  542. _bla:
  543.  
  544.     move            (r0)+                ; Proceed to next coord.
  545. _coord_loop:
  546.     move            y0,r0                ; Back to x coord
  547.  
  548. _end_line:
  549.     move            r4,r5                ; r5=current point
  550.     lua    (r4)+n4,r6                    ; r6=next point
  551. _do_line:
  552.  
  553.     rts
  554.  
  555. ; INPUT:
  556. ; r0=l edge, r1=r edge, n6=#scanlines
  557. Polygon.paintFlat
  558.     do    n6,_yloop
  559.     send    y:(r0)+                        ; Send left x.
  560.     send    y:(r1)+                        ; Send right x.
  561. _yloop:    rts
  562.  
  563. ; INPUT:
  564. ; r0=l edge, r1=r edge, r2=inv tbl, n6=#scanlines
  565. Polygon.paintGouraudShaded:
  566.     do    n6,_yloop
  567.     move                    y:(r0)+,x0    ; x0= left x
  568.     send    x0                        ; Send left x.
  569.     move                    y:(r1)+,a    ; a= right x
  570.     sub    x0,a                y:(r0)+,x0    ; a= dx , x0= left u
  571.     move            a1,n2                ; n2= dx
  572.     send    a1                        ; Send width.
  573.     move                    y:(r1)+,a    ; a= right u
  574.     sub    x0,a                y:(r2+n2),x1    ; a=du= right u - left u, x1= divisor
  575.     send    x0                        ; Send left u.
  576.     move            a,y1                ; y1= du
  577.     mpy    x1,y1,a                        ; a1=u_step= du / divisor
  578.     send    a1                        ; Send u_step.
  579. _yloop:    rts
  580.  
  581. ; INPUT:
  582. ; y0=texturenum, r3=HTX, r4=textureaddy
  583. ; r0=l edge, r1=r edge, r2=inv tbl, n6=#scanlines
  584. Polygon.paintTextured:
  585.     clr    a        #>64*64/2,y1
  586.     move            r4,a0
  587.     mac    y0,y1,a
  588.     move            a0,r4
  589.  
  590. ; hline loop
  591.     do    n6,_yloop
  592.  
  593.     move                    y:(r0)+,x0    ; x0=lx
  594.     move                    y:(r1)+,a    ; a=rx
  595.     send    x0                        ; Send lx.
  596.     sub    x0,a                y:(r0)+,x0    ; x0=u_start
  597.     move                    y:(r0)+,y0    ; y0=v_start
  598.     move            a1,n2                ; n2=width
  599.     send    a1                        ; Send width.
  600.     move                    y:(r1)+,a    ; a=u_end
  601.     move                    y:(r1)+,b    ; b=v_end
  602.     jle    <_skip_line
  603.  
  604.     IFNE    WRAPCRAP
  605.     sub    x0,a                y:(r2+n2),x1    ; du=u_end-u_start, x1=divisor
  606.     sub    y0,b        a1,y1                ; dv=v_end-v_start, y1=du
  607.     mpy    x1,y1,a        b1,y1                ; a=u_step=du/divisor, y1=dv
  608.     mpy    x1,y1,b        a,n5                 ; b=v_step=dv/divisor, n5=u_step
  609.     move                    y:<v_scale,y1    ; y1=scalar (int:frac->texturesize)
  610.     mpy    y1,y0,a        b,x1                ; a=v (12b), x1=v_step
  611.     mpy    y1,x1,b        x0,r5                ; b=v_step (12b), r5=u
  612.     move            b1,x1
  613.     tfr    a,b        #<0,x0    ;b0,x0            ; b=v (12b), x=v_step (12b)
  614.     move            x:<u_scale,y0            ; y0=scalar (int:frac -> int)
  615.     move            #<0,b0
  616.     ELSE
  617.     sub    x0,a                y:(r2+n2),x1    ; du=u_end-u_start, x1=divisor
  618.     sub    y0,b        a1,y1                ; dv=v_end-v_start, y1=du
  619.     mpy    x1,y1,a        b1,y1                ; a=u_step=du/divisor, y1=dv
  620.     mpy    x1,y1,b        a1,x:<u0_step             ; b=v_step=dv/divisor, Store u_step.
  621.     tfr    x0,a                b1,y:<u0_step     ; a1=u, Store v_step.
  622.     move            y0,a0                ; a0=v
  623. ; a1=u, a0=v, x1=u_step, x0=v_step
  624.     move            x:<texturesize,y0
  625.     move            a1,y1
  626.     ENDC
  627.  
  628. ; 5 calculation instructions = 5*2 = 10 cycles
  629. ; 1 host send >= 8 or 10 cycles
  630. ; total >= 18 or 20 cycles per pixel
  631.     do    n2,_send_pixel
  632.     IFNE    WRAPCRAP
  633.     tfr    b,a                y:<texturemask,y1    ; a=V[n] (12.24), y1=$FC0
  634.     and    y1,a        r5,y1                ; a=wrapped(int(V[n])), y1=U[n] (6:10)
  635.     mac    y1,y0,a        (r5)+n5                ; a=%VVVVVVUUUUUU[n], r1=u[n+1] (6:10)
  636.     add    x,b        a1,n4                ; b=V[n+1], n4=%VVVVVVUUUUUU[n] (=offset)
  637.     ELSE
  638.     mpyr    y1,y0,b        l:<texturemask,x        ; b=offset=u*texturesize, x1=width, x0=mask
  639.     and    x0,b        a0,y1                ; kill frag_u, y1=v
  640.     mac    y1,x1,b        l:<u0_step,x            ; offset:=offset+v, x1=u_step, x0=v_step
  641.     add    x,a        b1,n4                ; u:=u+u_step, v:=v+v_step
  642.     move            a1,y1                ; y1=u
  643.     ENDC
  644.     jclr    #1,x:<<HSR,*                    ; Wait until host is ready.
  645. _pixelinstruction:
  646.     nop                            ; Send word.
  647. _send_pixel:
  648.  
  649. _skip_line:
  650.     nop
  651. _yloop:    rts
  652.  
  653. ; Alpha texturing requires interleaved textures in dsp ram.
  654. ; The pixels are aligned like so: iixxxx, aaxxxx, where 'a' denotes alpha
  655. ; and 'i' the index in a 256 color palette. the x denotes a highcolor word.
  656. ; Yes, that means alpha textures occupy the same space as normal textures!
  657. ; INPUT:
  658. ; y0=texturenum, r3=HTX, r4=colortexture, 5r=alphatexture
  659. ; r0=l edge, r1=r edge, r2=inv tbl, n6=#scanlines
  660. Polygon.paintV4:
  661.     move            #<4,n0                ; #coordinates in edge-entry
  662.     move            #<4,n1                ; #coordinates in edge-entry
  663.  
  664. ; hline loop
  665.     do    n6,_scan_send_sides
  666.  
  667.     move                    y:(r0)+,x0    ; x0=lx
  668.     send    x0                        ; Send left x.
  669.     move                    y:(r1)+,a    ; a=rx
  670.     sub    x0,a        #<u0,r6                ; r6= start of uv-storage
  671.     send    a1                        ; Send width.
  672.     tst    a        a1,n2                ; test for 0-width, n2 := width
  673.     jgt    <_go_on
  674.  
  675.     move            (r0)+n0
  676.     move            (r1)+n1
  677.     jmp    <_skip_line
  678.  
  679. _go_on:    do    #2,_init_uv_loop
  680.     move                    y:(r0)+,x0    ; x0= u_start
  681.     move                    y:(r1)+,a    ; a= u_end
  682.     move                    y:(r0)+,y0    ; y0= v_start
  683.     move                    y:(r1)+,b    ; b= v_end
  684.     sub    x0,a                y:(r2+n2),x1    ; du= u_end - u_start, x1= divisor
  685.     sub    y0,b        x0,x:(r6)    a,y1        ; dv= v_end - v_start, store u_start, y1= du
  686.     mpy    x1,y1,a        b,x0        y0,y:(r6)+    ; u_step= du / divisor, x0= dv, store v_start
  687.     mpy    x1,x0,b        a,x:(r6)            ; v_step= dv / divisor, x1= u_step, store u_step
  688.     move                    b,y:(r6)+    ; Store v_step.
  689. _init_uv_loop:
  690.  
  691.     move            l:<u0,a
  692.     move            l:<u0_step,x
  693.     move            #>64*64,y0
  694.     move                    y:<Polygon.v4RoutineAddress,r6
  695.     move            a,x0
  696.     move            a,y1
  697.     jsr    (r6)
  698.  
  699. _skip_line:
  700.     nop
  701. _scan_send_sides:
  702.     rts
  703.  
  704. _send_alpha_hline:
  705. ; 16 instructions.. 32 cycles. Crappy, but better than a CPU implementation.
  706.     do    n2,_send_alphapixel
  707.     mpyr    y1,y0,b        l:<texturemask,x        ; offset := u0 * v_width
  708. ; x1: 128, x0: -128
  709.     and    x0,b                y:<v0,x0    ; kill frag_u0
  710.     mac    x0,x1,b        l:<u0_step,x            ; offset := offset + v0
  711. ; x1: u0_step, x0: v0_step
  712.     add    x,a        b1,n4
  713.     move            l:<u1,b                ; u0 := u0 + u0_step, v0 := v0 + v0_step
  714.     move            a,l:<u0                ; Store u0, v0.
  715.     move            b,x0        y:(r4+n4),y1    ; x0 := u1_step, y1 := color
  716.     mpyr    x0,y0,a        l:<texturemask,x        ; offset := u1 * v_width
  717. ; x1: 128, x0: -128
  718.     and    x0,a        b0,x0                ; kill frag_u1
  719.     mac    x0,x1,a        l:<u1_step,x            ; offset := offset + v1
  720. ; x1: u1_step, x0: v1_step
  721.     add    x,b        a1,n5
  722.     move            l:<colorshift,x            ; Get shift value x1, mask in x0
  723.     mpyr    x1,y1,b        b,l:<u1                ; u1 := u1 + u1_step, v1 := v1 + v1_step, a1 := u0, a0 := v0
  724.     and    x0,b        x:<alphashift,x1        ; Mask off alpha bits, store u1, v1.
  725.     move                    y:(r5+n5),y1    ; Shift color to b1's mid byte, y1 := alpha
  726.     mac    x1,y1,b        l:<u0,a                ; Shift alpha to b1's lsb, x0 := u0
  727.     jclr    #1,x:<<HSR,*                    ; Wait until host is ready.
  728.     move            b,x:(r3)    a,y1        ; Send pixel.
  729. _send_alphapixel:
  730.     rts
  731.  
  732. _send_bump_hline:
  733. ; 14 instructions.. 28 cycles. Crappy, but better than a CPU implementation.
  734.     do    n2,_send_bumppixel
  735.     mpyr    x0,y0,b        l:<texturemask,x        ; offset := u0 * v_width
  736. ; x1: 128, x0: -128
  737.     and    x0,b                y:<v0,x0    ; kill frag_u0
  738.     mac    x0,x1,b        l:<u0_step,x            ; offset := offset + v0
  739. ; x1: u0_step, x0: v0_step
  740.     move            b1,n4
  741.     move            l:<u1,b                ; u0 := u0 + u0_step, v0 := v0 + v0_step
  742.     add    x,a        b,x0        y:(r4+n4),y1    ; x0 := u1_step
  743.     move            a,l:<u0                ; Store u0, v0.
  744.     mpyr    x0,y0,a        l:<texturemask,x        ; offset := u1 * v_width
  745. ; x1: 128, x0: -128
  746.     and    x0,a        b0,x0                ; kill frag_u1
  747.     mac    x0,x1,a        l:<u1_step,x            ; offset := offset + v1
  748. ; x1: u1_step, x0: v1_step
  749.     add    x,b        x:<u0,x0            ; u1 := u1 + u1_step, v1 := v1 + v1_step, x0 := u0
  750.     add    y1,a        b,l:<u1                ; Add bump-offset to offset, store u1, v1.
  751.     move            a1,n5
  752.     move            l:<u0,a
  753.     send    y:(r5+n5)                    ; Send pixel to host.
  754. _send_bumppixel:
  755.     rts
  756.  
  757.  
  758. ;======== Code that only uses X memory, fits in Y memory nicely
  759.  
  760.  
  761. ;======== PrimitiveMesh
  762.  
  763. ; Combsort implementation. In place sorting, not the fastest available
  764. ; algorithm... With little RAM there is no choice I'm afraid.
  765. PrimitiveMesh.sort:
  766.     move            #>PrimitiveMesh.primitiveTable,r0
  767.     move            #<MeshElement.SIZE,n3
  768.     move            x:(r0)+,a
  769.     tst    a        a,b
  770.     jeq    <_end
  771.     lsr    b        a,y0                ; Resize gap.
  772.     jmp    <_end_calculate_gap
  773.     
  774. _loop:    move            #>2,x0
  775.     cmp    x0,b
  776.     jgt    <_calculate_gap
  777.     tfr    x0,b
  778. _calculate_gap:
  779.     move            #>0.769230769,x0
  780.     move            b,x1
  781.     mpy    x0,x1,b
  782. _end_calculate_gap:
  783.     tfr    y0,a        b,x1
  784.     sub    x1,a        n3,x0
  785.     mpy    x0,x1,a        a,n6
  786.     asr    a        #<0,r4                ; swapcount := 0
  787.     move            a0,n0
  788.     move            #<MeshElement.SIZE,n2
  789.     move            #<MeshElement.SIZE,n1
  790.     move            r0,r2
  791.     lua    (r0)+n0,r1
  792.  
  793.     do    n6,_element_loop
  794.     move            (r2)+n2
  795.     move            (r1)+n1
  796.     move            x:-(r2),a
  797.     move            x:-(r1),x0
  798.     cmp    x0,a        (r2)+
  799.     move            (r1)+
  800.     jge    <_no_swap
  801.     IFNE    1
  802.     move            a,x:-(r1)
  803.     move            x0,x:-(r2)
  804.     move            x:-(r2),x0
  805.     move            x:-(r1),x1
  806.     move            x0,x:(r1)
  807.     move            x1,x:(r2)
  808.     move            x:-(r2),x0
  809.     move            x:-(r1),x1
  810.     move            x0,x:(r1)+n1
  811.     move            x1,x:(r2)+n2
  812.     ELSE
  813. ; TODO: When all routines are adapted for small elements, activate this!
  814.     move            a,x:-(r1)
  815.     move            x0,x:-(r2)
  816.     move            x:-(r2),x0
  817.     move            x:-(r1),x1
  818.     move            x0,x:(r1)+n1
  819.     move            x1,x:(r2)+n2
  820.     ENDC
  821.     move            (r4)+
  822. _no_swap:
  823.     nop
  824. _element_loop:
  825.  
  826.     move            r4,a
  827.     tst    a        #>2,x0
  828.     jne    <_loop
  829.     cmp    x0,b
  830.     jge    <_loop
  831.  
  832. _end:    rts
  833.  
  834. ;======== non time-crucial stuff, all in external P-RAM ========
  835.  
  836. START:    jsr    <InitPipeline
  837.  
  838. Dispatcher.dispatch:
  839. ; Receive command... This is parallel mode. I.e. fetch, store a number of
  840. ; commands. After this host-synchronized period, it starts running through
  841. ; all commands in parallel.
  842. _store:    move            #>Dispatcher.commandTable,x0
  843.     move            x0,x:>Dispatcher.commandTablePosition
  844.  
  845. _storebigloop:
  846.     move            #>Dispatcher.commandSizeTable,r0
  847.     move            x:>Dispatcher.commandTablePosition,r1
  848.     move            #>RPC_PAINT_PRIMITIVES,x0
  849.  
  850. ; First store all received commands including arguments.
  851. _storeloop:
  852.     get    n0
  853.     move            n0,a
  854.     cmp    x0,a        x:(r0+n0),b
  855.     jeq    <_end_store
  856.     tst    b        a,x:(r1)+
  857.     jeq    <_storeloop
  858.     jmi    <_execute_direct
  859.  
  860. ; This is for asynchronous commands. They are stored and executed later on
  861. ; in parallel.
  862.     do    b,_store_word_loop
  863.     get    x:(r1)+
  864. _store_word_loop:
  865.     jmp    <_storeloop
  866.  
  867. ; Some commands have to be completed synchronously! i.e. texture/object-
  868. ; storage!!!!
  869. _execute_direct:
  870.     move            #>Dispatcher.rpcTable,r2
  871.     move            n0,n2
  872.     move            (r1)-                ; Correct last store (not needed!).
  873.     move            x:(r2+n2),r2
  874.     move            r1,x:>Dispatcher.commandTablePosition
  875.     jsr    (r2)
  876.     jmp    <_storebigloop
  877.  
  878. _end_store:
  879.     move            a,x:(r1)+
  880.     move            #>Dispatcher.commandTable,x0
  881.     move            x0,x:>Dispatcher.commandTablePosition
  882.  
  883. ; Then execute all commands.
  884. _execute_loop
  885.     move            x:>Dispatcher.commandTablePosition,r0
  886.     move            #>Dispatcher.commandSizeTable,r1
  887.     move            x:(r0)+,a
  888.     move            #>RPC_PAINT_PRIMITIVES,x0
  889. ; Check for a paint command..
  890.     cmp    x0,a        a,n1
  891.     jeq    <_complete
  892.     move            x:(r1+n1),n0            ; Fetch command size.
  893.     move            #>Dispatcher.storedRpcTable,r1
  894.     lua    (r0)+n0,r2                    ; Jump to next command.
  895.     move            x:(r1+n1),r1
  896. ; Store next command position and execute current.
  897.     move            r2,x:>Dispatcher.commandTablePosition
  898.     jsr    (r1)
  899.     jmp    <_execute_loop
  900.  
  901. _complete:
  902.     jsr    <PrimitiveMesh.paint
  903.     jmp    <_store    
  904.  
  905. Dispatcher.doNothing:
  906.     rts
  907.  
  908. ; Receives rotation cos/sin values from CPU.
  909. ; INPUT:
  910. ; r0: X-sine
  911. ; r1: X-cosine
  912. ; r2: Y-sine
  913. ; r3: Y-cosine
  914. ; r4: Z-sine
  915. ; r5: Z-cosine
  916. ReceiveRotation:
  917.     get    x:(r0)
  918.     get    x:(r1)
  919.     get    x:(r2)
  920.     get    x:(r3)
  921.     get    y:(r4)
  922.     get    y:(r5)
  923.     rts
  924.  
  925. ;======== Vertex
  926.  
  927. ; INPUT:
  928. ; x:(r0): vertices
  929. ; y:(r5): transformed vertices (dest.)
  930. ; b: vertexcount (excluding normals!)
  931. Vertex.transform:
  932.     move            #<Viewport.XCenter,r1
  933.  
  934. ; Get current matrix.
  935.     move            x:<Matrix.stackTop,a
  936.     move            #>1,x1
  937.     sub    x1,a        #>Matrix.SIZE,x0
  938.     move            a,x1
  939.     mpy    x0,x1,a        #<Matrix.stack,r4
  940.     asr    a        (r5)+                ; Adjust for fractional madness, skip 2d vertex pointer.
  941.     move            a0,n4
  942.     move            #<Vertex.SIZE+2,n5
  943.     move            (r4)+n4                ; r4 := matrix
  944.     move            #<Matrix.TZ,n4
  945.     move            (r5)+
  946.     lua    (r4)+n4,r6                    ; r6 := matrix.TZ
  947.  
  948.     move            #<Matrix.ZX,n4
  949.     move            (r5)+
  950.     move            (r4)+n4                ; r4 := matrix.ZX
  951.     move            #>-8,n4                ; n4 := jumpbackvalue for matrix
  952.     move            #>-2,n6                ; n6 := jumpbackvalue for translation
  953.     move            #>InverseTable,r3        ; r3 := start of 1/Z table
  954.     move            #<128,n3
  955.     move            r3,r2                ; r2 := start of 1/Z table
  956.     move            (r3)+n3
  957.     move                    y:(r6)+n6,a    ; a := TZ
  958.     move            x:(r0)+,x0    y:(r4)+,y0
  959.     move            #<127,n3
  960.     jmp    <Vertex.transInt
  961.  
  962.  
  963. ;======== Polygon
  964.  
  965. ; Reads polygon data from memory and decodes it's dimension, it's number of
  966. ; vertices and it's shading type.
  967. ; INPUT:
  968. ; y:(r1): 2d-vertices pointer, vertices
  969. ; x:(r2): primitive
  970. Polygon.decode:
  971.     clr    a        #<Polygon.polygonTable,r4
  972.     clr    b        x:(r2),a1
  973.     move            #>Primitive.TEXTUREMASK,x0
  974.  
  975. ; Get texturenumber.
  976.     and    x0,a        a1,b1
  977.     move            a,x:<Polygon.textureNumber
  978.  
  979. ; Get number of points in polygon.
  980.     clr    a        #>Primitive.TYPEMASK,x0
  981.     and    x0,b        #>Primitive.TYPEMUL,x1
  982.     move            x:(r2)+,a1
  983.     move            b,y0
  984.     move            #>1,b
  985.     mac    y0,x1,b        (r1)+
  986.     move            b,x:<Polygon.points
  987.  
  988. ; Get shadetype.
  989.     move            #>Primitive.SHADEMASK,x0
  990.     and    x0,a        #>Primitive.SHADEMUL,x1
  991.     move            a,x0
  992.     mpy    x0,x1,a        #>Polygon.shadeJumpTable,r6
  993.     move            a,n6
  994.  
  995. ; Fill the polygon table...
  996. ; y:(r1): vertices
  997. ; x:(r2): 1st index in primitive
  998. ; y:(r4): polygon table
  999.     nop
  1000.     move            p:(r6+n6),r6
  1001.     nop
  1002.     jmp    (r6)
  1003.  
  1004. Polygon.shadeJumpTable:
  1005.     DC    Polygon.decodeFlatshaded
  1006.     DC    Polygon.decodeGouraudshaded
  1007.     DC    Polygon.decodePhongshaded
  1008.     DC    Polygon.decodeTextured
  1009.     DC    Polygon.decodeEnvmapped
  1010.     DC    Polygon.decodeAlphatextured
  1011.     DC    Polygon.decodeBumpmapped
  1012.  
  1013. ; INPUT:
  1014. ; x:(r4): end of polygon data
  1015. Polygon.copyLast:
  1016. ; Copy the first point (wrap-crap).
  1017.     move            #<Polygon.polygonTable,r3
  1018.     nop
  1019.     move            x:(r3)+,x0
  1020.     move            x0,x:(r4)+
  1021.     do    x:<Polygon.vsize,_loop
  1022.     move            x:(r3)+,x0
  1023.     move            x0,x:(r4)+
  1024. _loop:
  1025.     rts
  1026.  
  1027. ;-------- Polygon decoders
  1028.  
  1029. Polygon.decodeFlatshaded:
  1030.     clr    a        #>2-1,x0
  1031.     move            x0,x:<Polygon.vsize
  1032.     move            a,x:<Polygon.shadeType
  1033.     do    x:<Polygon.points,_loop
  1034.     move            x:(r2)+,a            ; Get index of Vertex.
  1035.     asl    a        a,x0
  1036.     add    x0,a
  1037.     move            a,n1
  1038.     nop
  1039.     lua    (r1)+n1,r3
  1040. ; Write points to the polygontable.
  1041.     do    #2,_coordloop
  1042.     move                    y:(r3)+,x0
  1043.     move            x0,x:(r4)+
  1044. _coordloop:
  1045.     nop
  1046. _loop:
  1047.     jmp    <Polygon.copyLast
  1048.  
  1049. Polygon.decodeGouraudshaded:
  1050.     move            #>3-1,x0
  1051.     move            x0,x:<Polygon.vsize
  1052.     move            #>RPC_GOURAUDSHADED,x0
  1053.     move            x0,x:<Polygon.shadeType
  1054.     move            x:<Polygon.points,n2
  1055.     move            #>$8000,y0
  1056.     do    x:<Polygon.points,_loop
  1057.     move            x:(r2)+n2,a            ; Get index of Vertex.
  1058.     asl    a        a,x0
  1059.     add    x0,a        x:(r2)-n2,x1            ; Fetch gouraud value.
  1060.     mpy    x1,y0,a        a,n1                ; Scale gouraud value.
  1061.     move            (r2)+                ; Proceed to next index.
  1062.     lua    (r1)+n1,r3
  1063. ; Write points to the polygontable.
  1064.     do    #2,_coordloop
  1065.     move                    y:(r3)+,x0
  1066.     move            x0,x:(r4)+
  1067. _coordloop:
  1068.     move            a0,x:(r4)+            ; Write gouraud value.
  1069. _loop:
  1070.     jmp    <Polygon.copyLast
  1071.  
  1072. Polygon.decodePhongshaded:
  1073.     move            #>3-1,x0
  1074.     move            x0,x:<Polygon.vsize
  1075.     move            #>RPC_GOURAUDSHADED,x0
  1076.     move            x0,x:<Polygon.shadeType
  1077.     move            x:<Polygon.points,n2
  1078.     move            #>127,x1
  1079.     move            #>$3FFF,y0
  1080.     do    x:<Polygon.points,_loop
  1081.     move            x:(r2)+n2,a            ; a= vertex index.
  1082.     asl    a        a,x0
  1083.     add    x0,a        x:(r2)-n2,b            ; b= gouraud index.
  1084.     move            a,n1
  1085.     asl    b        b,x0
  1086.     lua    (r1)+n1,r3                    ; r3= vertex
  1087.     add    x0,b        #<Vertex.Z,n5            ; n5= offset to Z coordinate in normal
  1088.     move            b,n1
  1089.     move            (r2)+                ; Proceed to next point.
  1090.     lua    (r1)+n1,r5                    ; r5= normal
  1091. ; Write points to the polygontable.
  1092.     do    #2,_coordloop
  1093.     move                    y:(r3)+,x0
  1094.     move            x0,x:(r4)+
  1095. _coordloop:
  1096.     move                    y:(r5+n5),a    ; Fetch gouraud value.
  1097.     add    x1,a
  1098.     move            a,x0
  1099.     mpy    x0,y0,a
  1100.     move            a0,x:(r4)+            ; Write gouraud value.
  1101. _loop:
  1102.     jmp    <Polygon.copyLast
  1103.  
  1104. Polygon.decodeTextured:
  1105.     move                    y:-(r1),r5    ; r5= 2d vertices base.
  1106.     move            #>4-1,x0
  1107.     move            x0,x:<Polygon.vsize
  1108.     move            #>RPC_TEXTUREMAPPED,x0
  1109.     move            x0,x:<Polygon.shadeType
  1110.     move            x:<Polygon.points,n2
  1111.     move            (r1)+
  1112.     move            #>1<<7,x1        ; 1<<14
  1113.     do    x:<Polygon.points,_loop
  1114.     move            x:(r2)+n2,a            ; Get index of Vertex.
  1115.     asl    a        a,x0
  1116.     add    x0,a        x:(r2)-n2,b            ; Fetch 2d Vertex index.
  1117.     asl    b        a,n1
  1118.     move            b,n5
  1119.     lua    (r1)+n1,r3                    ; r3 := Vertex
  1120.     move            (r2)+                ; Proceed to next point.
  1121.     lua    (r5)+n5,r6                    ; r6 := 2d Vertex
  1122. ; Write points to the polygontable.
  1123.     do    #2,_coordloop
  1124.     move                    y:(r3)+,x0
  1125.     move            x0,x:(r4)+
  1126. _coordloop:
  1127.     move            x:(r6)+,x0            ; Fetch u.
  1128.     mpy    x1,x0,a        x:(r6),x0            ; Fetch v.
  1129.     mpy    x1,x0,a        a0,x:(r4)+            ; Write u.
  1130.     move            a0,x:(r4)+            ; Write v.
  1131. _loop:
  1132.     jmp    <Polygon.copyLast
  1133.  
  1134. Polygon.decodeEnvmapped:
  1135.     move            #<4-1,a1
  1136.     move            a1,x:<Polygon.vsize
  1137.     move            #<RPC_TEXTUREMAPPED,a1
  1138.     move            a1,x:<Polygon.shadeType
  1139.     move            x:<Polygon.points,n2
  1140.     IFNE    WRAPCRAP
  1141.     move            #>1<<7,x1
  1142.     move            #>$008000,y1
  1143.     ELSE
  1144.     move            #>1<<14,x1
  1145.     move            #>$400000,y1
  1146.     ENDC
  1147.     do    x:<Polygon.points,_loop
  1148.     move            x:(r2)+n2,a            ; Get index of Vertex.
  1149.     asl    a        a,x0
  1150.     add    x0,a        x:(r2)-n2,b            ; Fetch normal index.
  1151.     asl    b        b,x0
  1152.     add    x0,b        a,n1
  1153.     move            (r2)+                ; Proceed to next point.
  1154.     lua    (r1)+n1,r3                    ; r3 := Vertex
  1155.     move            b,n1
  1156. ; Write points to the polygontable.
  1157.     move                    y:(r3)+,x0
  1158.     move            x0,x:(r4)+    y:(r3),y0
  1159.     lua    (r1)+n1,r3                    ; r3 := Normal
  1160.     clr    a        y0,x:(r4)+
  1161.     clr    b        y1,a0
  1162.     move            y1,b0
  1163.     move                    y:(r3)+,x0    ; Fetch Normal.X (=u).
  1164.     mac    x0,x1,a                y:(r3),y0    ; Fetch Normal.Y (=v).
  1165.     mac    y0,x1,b        a0,x:(r4)+            ; Write u.
  1166.     move            b0,x:(r4)+            ; Write v.
  1167. _loop:    jmp    <Polygon.copyLast
  1168.  
  1169. Polygon.decodeAlphatextured:
  1170.     move            #>RPC_ALPHATEXTURED,x0
  1171.     move            x0,x:<Polygon.shadeType
  1172.     jsr    <Polygon.setV4AlphaMode
  1173.     jmp    <Polygon.decodeV4
  1174.  
  1175. Polygon.decodeBumpmapped:
  1176.     move            #>RPC_BUMPMAPPED,x0
  1177.     move            x0,x:<Polygon.shadeType
  1178.     jsr    <Polygon.setV4BumpMode
  1179.  
  1180. Polygon.decodeV4:
  1181.     move            #<6-1,n2
  1182.     move                    y:-(r1),r5    ; r5 := 2d vertices base.
  1183.     move            n2,x:<Polygon.vsize
  1184.     move            x:<Polygon.points,n2
  1185.     move            (r1)+
  1186.     lua    (r2)+n2,r0
  1187.     move            #>1<<14,x1
  1188.     move            #>$400000,y1
  1189.     do    n2,_loop
  1190.     move            x:(r2)+,a            ; Get index of Vertex.
  1191.     asl    a        a,x0
  1192.     add    x0,a        x:(r0)+,b            ; Fetch 2d vertex index.
  1193.     asl    b        a,n1
  1194.     move            x:(r0)+,a            ; Fetch normal index.
  1195.     lua    (r1)+n1,r3                    ; r3 := Vertex
  1196.     asl    a        a,x0
  1197.     add    x0,a        b,n5
  1198.     move            a,n1
  1199.     lua    (r5)+n5,r6                    ; r6 := 2d vertex
  1200. ; Write points to the polygontable.
  1201.     do    #2,_coordloop
  1202.     move                    y:(r3)+,x0
  1203.     move            x0,x:(r4)+
  1204. _coordloop:
  1205.     move            x:(r6)+,x0            ; Fetch u1.
  1206.     mpy    x0,x1,a        x:(r6),x0            ; Fetch v1.
  1207.     mpy    x0,x1,b        a0,x:(r4)+            ; Write u1.
  1208.     lua    (r1)+n1,r6                    ; r6 := Normal
  1209.     clr    a        b0,x:(r4)+            ; Write v1.
  1210.     clr    b        y1,a0
  1211.     move            y1,b0
  1212.     move                    y:(r6)+,y0    ; Fetch Normal.X (=u2).
  1213.     mac    y0,x1,a                y:(r6),y0    ; Fetch Normal.Y (=v2).
  1214.     mac    y0,x1,b        a0,x:(r4)+            ; Write u2.
  1215.     move            b0,x:(r4)+            ; Write v2.
  1216. _loop:
  1217.     jmp    <Polygon.copyLast
  1218.  
  1219. ; Clips the polygon against the viewport. This subroutine is generic and
  1220. ; works for all shadetypes. The used algorithm is sutherland hodgman.
  1221. ; OUTPUT:
  1222. ; a: =0 offscreen, >0 onscreen
  1223. Polygon.clip:
  1224. ; First of all we check which sides of the viewport this baby clips against.
  1225.     move            #<Polygon.polygonTable,r0
  1226.     move            x:<Polygon.vsize,n0
  1227.     move            x:<Viewport.XStart,x0
  1228.     move            x:<Viewport.XEnd,x1
  1229.     move            x:<Viewport.YStart,y0
  1230.     move            #<%0001,n1
  1231.     move            #<%0010,n2
  1232.     move            #<%0100,n3
  1233.     move            #<%1000,n4
  1234.     move            #<$ffffff,r1            ; Clear AND flags.
  1235.     move            #<0,r2                ; Clear OR flags.
  1236.     do    x:<Polygon.points,_check_loop
  1237.     clr    b        x:(r0)+,a            ; a := y
  1238.     cmp    y0,a        n1,y1
  1239.     jge    <_check_bottom
  1240.     or    y1,b                        ; if y above viewport, then raise flag
  1241. _check_bottom:
  1242.     move            x:<Viewport.YEnd,y1
  1243.     cmp    y1,a        n2,y1
  1244.     jlt    <_check_left
  1245.     or    y1,b                        ; if y below viewport, then raise flag
  1246. _check_left:
  1247.     move            x:(r0)+n0,a            ; a := x, proceed to next point
  1248.     cmp    x0,a        n3,y1
  1249.     jge    <_check_right
  1250.     or    y1,b                        ; if x left of viewport, then raise flag
  1251. _check_right:
  1252.     cmp    x1,a        n4,y1
  1253.     jlt    <_not_right
  1254.     or    y1,b                        ; if x right of viewport, then raise flag
  1255. _not_right:
  1256.     move            r1,a
  1257.     move            b,y1
  1258.     and    y1,a        r2,b
  1259.     or    y1,b        a,r1                ; Update AND flags.
  1260.     move            b,r2                ; Update OR flags.
  1261. _check_loop:
  1262.  
  1263.     tst    a        #<Polygon.polygonTable,r0
  1264.     jeq    <_on_screen
  1265. _offscreen:
  1266. ; All points are clipped at one side of the Viewport, no need to process it
  1267. ; any further.
  1268.     clr    a
  1269.     rts
  1270. _on_screen:
  1271.     tst    b        b,x:<Polygon.clipFlags
  1272.     jeq    <_end                        ; No clipflags? Then don't clip at all!
  1273.  
  1274. ; Here cumms tha clips. 8========D----*
  1275.  
  1276. ; Here we scale the coordinates up for accuracy reasons.
  1277.     move            x:<Polygon.points,r1
  1278.     move            #1<<7,x0
  1279.     move            (r1)+
  1280.     do    r1,_scaleup_loop
  1281.     move            x:(r0)+,x1
  1282.     mpy    x0,x1,a        x:(r0)-,x1
  1283.     mpy    x0,x1,a        a0,x:(r0)+
  1284.     move            a0,x:(r0)+n0
  1285. _scaleup_loop:
  1286.  
  1287. ; Clip this bitch against the Viewport according to the flags.
  1288.     move            #<Polygon.polygonTable,r0
  1289.     move            #<Polygon.polygonTable2,r1
  1290.     move            r0,r5
  1291.     move            r1,r6
  1292.     move            n0,n2
  1293.  
  1294. _cornerloop:
  1295.     jset    #0,x:<Polygon.clipFlags,_clip_top
  1296.     jset    #1,x:<Polygon.clipFlags,_clip_bottom
  1297.     jset    #2,x:<Polygon.clipFlags,_clip_left
  1298.     jset    #3,x:<Polygon.clipFlags,_clip_right
  1299.     jmp    <_end_cornerloop
  1300.  
  1301. ; I.R. clipping top side.
  1302.  
  1303. _clip_top:
  1304.     move            x:<Viewport.YStart,x0        ; x0 := Viewport.YStart
  1305.     move            #>_top,r4
  1306.     bclr    #0,x:<Polygon.clipFlags
  1307.     jmp    <_clip_corner
  1308. _clip_bottom:
  1309.     move            x:<Viewport.YEnd,x0        ; x0 := Viewport.YEnd
  1310.     move            #>_bottom,r4
  1311.     bclr    #1,x:<Polygon.clipFlags
  1312.     jmp    <_clip_corner
  1313. _clip_left:
  1314.     move            x:<Viewport.XStart,x0        ; x0 := Viewport.XStart
  1315.     move            #>_left,r4
  1316.     bclr    #2,x:<Polygon.clipFlags
  1317.     jmp    <_clip_corner
  1318. _clip_right:
  1319.     move            x:<Viewport.XEnd,x0        ; x0 := Viewport.XEnd
  1320.     move            #>_right,r4
  1321.     bclr    #3,x:<Polygon.clipFlags
  1322.     jmp    <_clip_corner
  1323.  
  1324. _clip_corner:
  1325.     move            #1<<7,x1
  1326.     mpy    x0,x1,a        #<0,r3                ; r3 := destination pointcounter = 0
  1327.     move            a0,x0                ; x0 := Viewport.YStart << 8
  1328.  
  1329.     do    x:<Polygon.points,_cliploop
  1330.     jmp    (r4)
  1331. _end_loop:
  1332.     nop
  1333. _cliploop:
  1334.  
  1335.     move            r3,a
  1336.     tst    a        r6,r2
  1337.     jeq    <_offscreen
  1338.  
  1339. ; wrap-crap...
  1340.     move            r3,x:<Polygon.points
  1341.     move            x:(r2)+,a
  1342.     move            a,x:(r1)+
  1343.     do    x:<Polygon.vsize,_lastloop
  1344.     move            x:(r2)+,a
  1345.     move            a,x:(r1)+
  1346. _lastloop:
  1347.  
  1348.     move            r5,x0
  1349.     move            r6,r5
  1350.     move            x0,r6
  1351.     move            r5,r0
  1352.     move            r6,r1
  1353.  
  1354.     jmp    <_cornerloop
  1355. _end_cornerloop:
  1356.  
  1357. ; Here we scale the coordinates down again. Yawn.
  1358.     move            r0,r2
  1359.     move            x:<Polygon.points,r1
  1360.     move            #1<<(23-8),x0
  1361.     move            (r1)+
  1362.     do    r1,_scaledown_loop
  1363.     move            x:(r2)+,x1
  1364.     mpyr    x0,x1,a        x:(r2)-,x1
  1365.     mpyr    x0,x1,a        a,x:(r2)+
  1366.     move            a,x:(r2)+n2
  1367. _scaledown_loop:
  1368.  
  1369. ; Polygon is visible and fully within the viewport.
  1370. _end:    move            #<1,a
  1371.     rts
  1372.  
  1373. ;
  1374. ;     /\
  1375. ;------------        ------------
  1376. ;   /    \     -->      /    \
  1377. ;   \    /     -->      \    /
  1378. ;    \  /                \  /
  1379. ;     \/                  \/
  1380. ;
  1381. ; This clips an edge against the top of the Viewport.
  1382. ;
  1383. _top:    move            x:(r0)+,a            ; a := ystart
  1384.     cmp    x0,a        x:(r0+n0),b            ; b := yend
  1385.     jlt    <_top_check_2ndout                ; if 1st point is outside, jump.
  1386.     cmp    x0,b        r0,r2
  1387.     jge    <_inside                    ; if 2nd point is inside, jump.
  1388.  
  1389. ; The source edge goes from inside to outside.
  1390. ; Write the clipped point.
  1391. _top_inout:
  1392.     move            x0,x:(r1)+
  1393.     move            (r0)-
  1394.     do    x:<Polygon.vsize,_top_inoutloop
  1395. ; Prepare for intersection with preset side.
  1396.     move            x:(r0)+,a            ; x1 := ystart
  1397.     move            x:(r0+n0),x1            ; a := yend
  1398.     sub    x1,a        x:(r2)+,b            ; a := yend - ystart (=dy), y1 := xstart
  1399.     move            x:(r2+n2),y1            ; b := xend
  1400. ; a := xstart - yi(frac) * slope(fixedpoint)
  1401.     jsr    <_intersect
  1402.     add    y1,a                        ; Add xstart.
  1403.     move            a,x:(r1)+            ; Store new x.
  1404. _top_inoutloop:
  1405.     move            (r3)+                ; Increase pointcount.
  1406.     move            r2,r0
  1407.     jmp    <_end_loop
  1408.     
  1409. _top_check_2ndout:
  1410.     cmp    x0,b        r0,r2
  1411.     jge    <_top_outin
  1412.  
  1413. ; Source edge is outside. Don't write it out.
  1414.     move            (r0)+n0
  1415.     jmp    <_end_loop
  1416.  
  1417. ; The source edge goes from outside to inside.
  1418. ; Write the clipped point and the inside point as well.
  1419. _top_outin:
  1420.     move            x0,x:(r1)+
  1421.     move            (r0)-
  1422.     do    x:<Polygon.vsize,_top_outinloop
  1423. ; Prepare for intersection with preset side.
  1424.     move            x:(r0)+,x1            ; x1 := ystart
  1425.     move            x:(r0+n0),a            ; a := yend
  1426.     sub    x1,a        x:(r2)+,y1            ; a := yend - ystart (=dy), y1 := xstart
  1427.     move            x:(r2+n2),b            ; b := xend
  1428. ; a := xstart + yi(frac) * slope(fixedpoint)
  1429.     jsr    <_intersect
  1430.     add    y1,a                        ; Add xstart.
  1431.     move            a,x:(r1)+            ; Store new x.
  1432. _top_outinloop:
  1433.  
  1434.     move            (r0)+                ; Adjust point position.
  1435.     move            (r3)+                ; Increase pointcount.
  1436.     jmp    <_inside
  1437.  
  1438. ;
  1439. ;     /\                  /\
  1440. ;    /  \                /  \
  1441. ;   /    \     -->      /    \
  1442. ;   \    /     -->      \    /
  1443. ;------------        ------------
  1444. ;     \/
  1445. ;
  1446. ; This clips an edge against the bottom of the Viewport.
  1447. ;
  1448. _bottom:
  1449.     move            x:(r0)+,a            ; a := ystart
  1450.     cmp    x0,a        x:(r0+n0),b            ; b := yend
  1451.     jge    <_bottom_check_2ndout                ; if 1st point is outside, jump.
  1452.     cmp    x0,b        r0,r2
  1453.     jlt    <_inside                    ; if 2nd point is inside, jump.
  1454.  
  1455. ; The source edge goes from inside to outside.
  1456. ; Write the clipped point.
  1457. _bottom_inout:
  1458.     move            x0,x:(r1)+
  1459.     move            (r0)-
  1460.     do    x:<Polygon.vsize,_bottom_inoutloop
  1461. ; Prepare for intersection with preset side.
  1462.     move            x:(r0)+,a            ; x1 := ystart
  1463.     move            x:(r0+n0),x1            ; a := yend
  1464.     sub    x1,a        x:(r2)+,b            ; a := yend - ystart (=dy), y1 := xstart
  1465.     move            x:(r2+n2),y1            ; a := -dy, b := xend
  1466. ; a := xstart + yi(frac) * slope(fixedpoint)
  1467.     jsr    <_intersect
  1468.     neg    a
  1469.     add    y1,a                        ; Add xstart.
  1470.     move            a,x:(r1)+            ; Store new x.
  1471. _bottom_inoutloop:
  1472.     move            (r3)+                ; Increase pointcount.
  1473.     move            r2,r0
  1474.     jmp    <_end_loop
  1475.     
  1476. _bottom_check_2ndout:
  1477.     cmp    x0,b        r0,r2
  1478.     jlt    <_bottom_outin
  1479.  
  1480. ; Source edge is outside. Don't write it out.
  1481.     move            (r0)+n0
  1482.     jmp    <_end_loop
  1483.  
  1484. ; The source edge goes from outside to inside.
  1485. ; Write the clipped point and the inside point as well.
  1486. _bottom_outin:
  1487.     move            x0,x:(r1)+
  1488.     move            (r0)-
  1489.     do    x:<Polygon.vsize,_bottom_outinloop
  1490. ; Prepare for intersection with preset side.
  1491.     move            x:(r0)+,x1            ; x1 := ystart
  1492.     move            x:(r0+n0),a            ; a := yend
  1493.     sub    x1,a        x:(r2)+,y1            ; a := yend - ystart (=dy), y1 := xstart
  1494.     neg    a        x:(r2+n2),b            ; a := -dy, b := xend
  1495. ; a := xstart - yi(frac) * slope(fixedpoint)
  1496.     jsr    <_intersect
  1497.     neg    a
  1498.     add    y1,a                        ; Add xstart.
  1499.     move            a,x:(r1)+            ; Store new x.
  1500. _bottom_outinloop:
  1501.  
  1502.     move            (r0)+                ; Adjust point position.
  1503.     move            (r3)+                ; Increase pointcount.
  1504.     jmp    <_inside
  1505.  
  1506. ;
  1507. ;    |/\                 |/\
  1508. ;    |  \                |  \
  1509. ;   /|   \     -->       |   \
  1510. ;   \|   /     -->       |   /
  1511. ;    |  /                |  /
  1512. ;    |\/                 |\/
  1513. ;
  1514. ; This clips an edge against the left side of the Viewport.
  1515. ;
  1516. _left:    move            (r0)+
  1517.     move            r0,r2
  1518.     move            x:(r0)+,a            ; a := xstart
  1519.     move            x:(r0+n0),b            ; b := xend
  1520.     cmp    x0,a        (r0)-
  1521.     jlt    <_left_check_2ndout                ; if 1st point is outside, jump.
  1522.     cmp    x0,b        
  1523.     jge    <_inside                    ; if 2nd point is inside, jump.
  1524.  
  1525. ; The source edge goes from inside to outside.
  1526. ; Write the clipped point.
  1527. _left_inout:
  1528.     move            (r0)-                ; x:(r0) : source y start
  1529.     move            (r1)+                ; x:(r1) : dest. x start
  1530.     move            x0,x:(r1)-            ; X := Viewport.XStart
  1531.                                 ; x:(r1) : dest. y start
  1532. ; Prepare for intersection with preset side.
  1533.     move            x:(r2)+,a            ; y1 := xstart
  1534.     move            x:(r2+n2),x1            ; a := xend
  1535.     sub    x1,a        x:(r0)+,b            ; a := xend - xstart (=dx), y1 := ystart
  1536.     move            x:(r0+n0),y1            ; b := yend
  1537. ; a := ystart - xi(frac) * slope(fixedpoint)
  1538.     jsr    <_intersect
  1539.     add    y1,a        (r0)+                ; Add ystart.
  1540.     move            a,x:(r1)+            ; Store new y, x:(r1) : dest. x coord
  1541.  
  1542. ; loopcounter = amount of coords except x,y
  1543.     move            x:<Polygon.vsize,a
  1544.     move            #>1,x1
  1545.     sub    x1,a        (r1)+                ; Proceed to next dest. coord.
  1546.     jeq    <_end_left_inout
  1547.  
  1548.     do    a,_left_inoutloop
  1549. ; Prepare for intersection with preset side.
  1550.     move            x:(r0)+,x1            ; x1 := xstart
  1551.     move            x:(r0+n0),a            ; a := xend
  1552.     sub    x1,a        x:(r2)+,y1            ; a := xend - xstart (=dx), y1 := ustart
  1553.     move            x:(r2+n2),b            ; b := uend
  1554. ; a := ustart - xi(frac) * slope(fixedpoint)
  1555.     jsr    <_intersect
  1556.     neg    a
  1557.     add    y1,a                        ; Add ustart.
  1558.     move            a,x:(r1)+            ; Store new u.
  1559. _left_inoutloop:
  1560. _end_left_inout:
  1561.     move            (r3)+                ; Increase pointcount.
  1562.     move            r2,r0
  1563.     jmp    <_end_loop
  1564.     
  1565. _left_check_2ndout:
  1566.     cmp    x0,b
  1567.     jge    <_left_outin
  1568.  
  1569. ; Source edge is outside. Don't write it out.
  1570.     move            (r0)+n0
  1571.     jmp    <_end_loop
  1572.  
  1573. ; The source edge goes from outside to inside.
  1574. ; Write the clipped point and the inside point as well.
  1575. _left_outin:
  1576.     move            (r1)+
  1577.     move            x0,x:(r1)-            ; X := Viewport.XStart
  1578.     move            (r0)-
  1579.  
  1580. ; Prepare for intersection with preset side.
  1581.     move            x:(r2)+,x1            ; y1 := xstart
  1582.     move            x:(r2+n2),a            ; a := xend
  1583.     sub    x1,a        x:(r0)+,y1            ; a := xend - xstart (=dx), y1 := ystart
  1584.     move            x:(r0+n0),b            ; b := yend
  1585. ; a := xstart - yi(frac) * slope(fixedpoint)
  1586.     jsr    <_intersect
  1587.     add    y1,a        (r0)+                ; Add ystart.
  1588.     move            a,x:(r1)+            ; Store new y.
  1589.  
  1590. ; loopcounter = amount of coords except x,y
  1591.     move            x:<Polygon.vsize,a
  1592.     move            #>1,x1
  1593.     sub    x1,a        (r1)+                ; Proceed to next dest. coord.
  1594.     jeq    <_end_left_outin
  1595.  
  1596.     do    a,_left_outinloop
  1597. ; Prepare for intersection with preset side.
  1598.     move            x:(r0)+,x1            ; x1 := xstart
  1599.     move            x:(r0+n0),a            ; a := xend
  1600.     sub    x1,a        x:(r2)+,y1            ; a := xend - xstart (=dx), y1 := ustart
  1601.     move            x:(r2+n2),b            ; b := uend
  1602. ; a := ustart + xi(frac) * slope(fixedpoint)
  1603.     jsr    <_intersect
  1604.     add    y1,a                        ; Add ustart.
  1605.     move            a,x:(r1)+            ; Store new u.
  1606. _left_outinloop:
  1607. _end_left_outin:
  1608.     move            (r3)+                ; Increase pointcount.
  1609.     jmp    <_inside
  1610.  
  1611. ;
  1612. ;     /\|                 /\|
  1613. ;    /  |                /  |
  1614. ;   /   |\     -->      /   |
  1615. ;   \   |/     -->      \   |
  1616. ;    \  |                \  |
  1617. ;     \/|                 \/|
  1618. ;
  1619. ; This clips an edge against the right side of the Viewport.
  1620. ;
  1621. _right:    move            (r0)+
  1622.     move            r0,r2
  1623.     move            x:(r0)+,a            ; a := xstart
  1624.     move            x:(r0+n0),b            ; b := xend
  1625.     cmp    x0,a        (r0)-
  1626.     jge    <_right_check_2ndout                ; if 1st point is outside, jump.
  1627.     cmp    x0,b        
  1628.     jlt    <_inside                    ; if 2nd point is inside, jump.
  1629.  
  1630. ; The source edge goes from inside to outside.
  1631. ; Write the clipped point.
  1632. _right_inout:
  1633.     move            (r0)-                ; x:(r0) : source y start
  1634.     move            (r1)+                ; x:(r1) : dest. x start
  1635.     move            x0,x:(r1)-            ; X := Viewport.XStart
  1636.                                 ; x:(r1) : dest. y start
  1637. ; Prepare for intersection with preset side.
  1638.     move            x:(r2)+,a            ; y1 := xstart
  1639.     move            x:(r2+n2),x1            ; a := xend
  1640.     sub    x1,a        x:(r0)+,b            ; a := xend - xstart (=dx), y1 := ystart
  1641.     move            x:(r0+n0),y1            ; b := yend
  1642. ; a := ystart - xi(frac) * slope(fixedpoint)
  1643.     jsr    <_intersect
  1644.     neg    a
  1645.     add    y1,a        (r0)+                ; Add ystart.
  1646.     move            a,x:(r1)+            ; Store new y, x:(r1) : dest. x coord
  1647.  
  1648. ; loopcounter = amount of coords except x,y
  1649.     move            x:<Polygon.vsize,a
  1650.     move            #>1,x1
  1651.     sub    x1,a        (r1)+                ; Proceed to next dest. coord.
  1652.     jeq    <_end_right_inout
  1653.  
  1654.     do    a,_right_inoutloop
  1655. ; Prepare for intersection with preset side.
  1656.     move            x:(r0)+,x1            ; x1 := xstart
  1657.     move            x:(r0+n0),a            ; a := xend
  1658.     sub    x1,a        x:(r2)+,y1            ; a := xend - xstart (=dx), y1 := ustart
  1659.     move            x:(r2+n2),b            ; b := uend
  1660. ; a := ustart - xi(frac) * slope(fixedpoint)
  1661.     jsr    <_intersect
  1662.     add    y1,a                        ; Add ustart.
  1663.     move            a,x:(r1)+            ; Store new u.
  1664. _right_inoutloop:
  1665. _end_right_inout:
  1666.     move            (r3)+                ; Increase pointcount.
  1667.     move            r2,r0
  1668.     jmp    <_end_loop
  1669.     
  1670. _right_check_2ndout:
  1671.     cmp    x0,b
  1672.     jlt    <_right_outin
  1673.  
  1674. ; Source edge is outside. Don't write it out.
  1675.     move            (r0)+n0
  1676.     jmp    <_end_loop
  1677.  
  1678. ; The source edge goes from outside to inside.
  1679. ; Write the clipped point and the inside point as well.
  1680. _right_outin:
  1681.     move            (r1)+
  1682.     move            x0,x:(r1)-            ; X := Viewport.XStart
  1683.     move            (r0)-
  1684.  
  1685. ; Prepare for intersection with preset side.
  1686.     move            x:(r2)+,x1            ; y1 := xstart
  1687.     move            x:(r2+n2),a            ; a := xend
  1688.     sub    x1,a        x:(r0)+,y1            ; a := xend - xstart (=dx), y1 := ystart
  1689.     move            x:(r0+n0),b            ; b := yend
  1690. ; a := xstart - yi(frac) * slope(fixedpoint)
  1691.     jsr    <_intersect
  1692.     neg    a
  1693.     add    y1,a        (r0)+                ; Add ystart.
  1694.     move            a,x:(r1)+            ; Store new y.
  1695.  
  1696. ; loopcounter = amount of coords except x,y
  1697.     move            x:<Polygon.vsize,a
  1698.     move            #>1,x1
  1699.     sub    x1,a        (r1)+                ; Proceed to next dest. coord.
  1700.     jeq    <_end_right_outin
  1701.  
  1702.     do    a,_right_outinloop
  1703. ; Prepare for intersection with preset side.
  1704.     move            x:(r0)+,x1            ; x1 := xstart
  1705.     move            x:(r0+n0),a            ; a := xend
  1706.     sub    x1,a        x:(r2)+,y1            ; a := xend - xstart (=dx), y1 := ustart
  1707.     move            x:(r2+n2),b            ; b := uend
  1708. ; a := ustart + xi(frac) * slope(fixedpoint)
  1709.     jsr    <_intersect
  1710.     neg    a
  1711.     add    y1,a                        ; Add ustart.
  1712.     move            a,x:(r1)+            ; Store new u.
  1713. _right_outinloop:
  1714. _end_right_outin:
  1715.     move            (r3)+                ; Increase pointcount.
  1716.     jmp    <_inside
  1717.  
  1718. ; The source edge is inside -> write the second point to the destination.
  1719. _inside:
  1720.     move            (r0)+n0                ; Proceed to next point.
  1721.     move            r0,r2
  1722.     move            (r3)+                ; Increase pointcount.
  1723.     move            x:(r2)+,x1
  1724.     move            x1,x:(r1)+
  1725.     do    x:<Polygon.vsize,_copy_loop
  1726.     move            x:(r2)+,x1
  1727.     move            x1,x:(r1)+
  1728. _copy_loop:
  1729.     jmp    <_end_loop
  1730.  
  1731. ; Generic intersection routine.
  1732. ; INPUT:
  1733. ; x1: ystart
  1734. ; y1: xstart
  1735. ; a: yend - ystart (=dy)
  1736. ; b: xend
  1737. _intersect:
  1738.     sub    y1,b        a,y0                ; b := xend - xstart (=dx), y0 := dy
  1739.     abs    b        b,a                ; b := abs(b), a := dx
  1740.     move            b,b0
  1741.     move            #<0,b1
  1742.     rep    #8
  1743.     asl    b
  1744.     andi    #$fe,ccr
  1745.     rep    #24
  1746.     div    y0,b                        ; b := dx/dy (=slope)
  1747.     tst    a        b0,b
  1748.     jpl    <_divisorpos
  1749.     neg    b
  1750. _divisorpos:
  1751.     move            x0,a                ; a := Viewport.YStart
  1752.     sub    x1,a        b,y0                ; a := Viewport.YStart - ystart (=yi), y0 := int(slope)
  1753.     move            a,x1                ; x1 := yi
  1754. ; a := yi(frac) * slope(fixedpoint)
  1755.     mpy    +x1,y0,a    (r0)-
  1756.     rep    #8
  1757.     asr    a        
  1758.     move            a0,a
  1759.     rts
  1760.  
  1761. ; Get top and bottom of polygon.
  1762. ; INPUT:
  1763. ; x:(r0): polygon table
  1764. Polygon.getDimensions:
  1765.     move            r0,r1
  1766.     move            #>$7fffff,a            ; top := MAX_INT
  1767.     move            #>$800000,b            ; bottom := MIN_INT
  1768.     move            x:<Polygon.vsize,n1
  1769.  
  1770.     do    x:<Polygon.points,_loop
  1771.     move            x:(r1)+,y0            ; Fetch Vertex.Y.
  1772.     cmp    y0,a        (r1)+n1                ; Proceed to next Vertex.
  1773.     tgt    y0,a                        ; If new value is lower, set new top.
  1774.     cmp    y0,b
  1775.     tlt    y0,b                        ; If new value is higher, set new bottom.
  1776. _loop:
  1777.     sub     a,b        a,x:<Polygon.top        ; Store top, height := bottom-top
  1778.     move            b,x:<Polygon.height        ; Store height.
  1779.     rts
  1780.  
  1781. ; Sends a mapped polygon over.
  1782. Polygon.send:
  1783.     move            x:<Polygon.textureNumber,y0
  1784.     send    y0                        ; Send texture number.
  1785.  
  1786.     send    x:<Polygon.top                    ; Send minimum y.
  1787.  
  1788.     move            x:<Polygon.height,a
  1789.     send    a                        ; Send height.
  1790.     tst    a        a,n6
  1791.     jgt    <_go_on
  1792. ; Poly is 0 high, don't paint.
  1793.     rts
  1794. _go_on:
  1795. ; x0=top, y0=texturenum, a=height
  1796.  
  1797.     move            x:<Polygon.vsize,b
  1798.     move            #>Polygon.LeftEdge,r0
  1799.     move            #>Polygon.RightEdge,r1
  1800.     move            #>1,x0
  1801.     sub    x0,b        #>InverseTable,r2
  1802.     jeq    <Polygon.paintFlat
  1803.     sub    x0,b        #>Polygon.texture,r4        ; r4= (color) texture
  1804.     jeq    <Polygon.paintGouraudShaded
  1805.     sub    x0,b        #>HTX,r3
  1806.     jeq    <Polygon.paintTextured
  1807.     move            #>Polygon.texture+64*64,r5    ; r5= alpha texture
  1808.     jmp    <Polygon.paintV4
  1809.  
  1810. ; Receives polygon data from the cpu and stores it.
  1811. ; This works for any shade type. (flat, gouraud, texture, gouraudtexture, alpha/bump)
  1812. Polygon.receive:
  1813.     move            #<Polygon.points,r0
  1814.     move            #<Polygon.vsize,r1
  1815.     move            #<Polygon.polygonTable,r2
  1816.     get            x:>Polygon.textureNumber    ; Get texturenumber.
  1817.     get    x:(r0)                        ; Get number of points in polygon.
  1818.     get    x:(r1)                        ; Get number of coordinates-1 in point.
  1819.     move            x:(r1),r3
  1820.     move            #>$7fffff,a            ; top := MAX_INT
  1821.     move            #>$800000,b            ; bottom := MIN_INT
  1822.  
  1823.     do    x:(r0),_receiveloop
  1824.     get    y0
  1825.     cmp    y0,a        y0,x:(r2)+            ; Store y.
  1826.     tgt    y0,a                        ; If new value is lower, set new top.
  1827.     cmp    y0,b
  1828.     tlt    y0,b                        ; If new value is higher, set new bottom.
  1829.     do    r3,_receivecoord
  1830.     get    x:(r2)+
  1831. _receivecoord:
  1832.     nop
  1833. _receiveloop:
  1834.  
  1835. ; Copy first point as last also. (wrap-crap)
  1836.     move            (r3)+
  1837.     move            #<Polygon.polygonTable,r1
  1838.     do    r3,_repeatloop
  1839.     move            x:(r1)+,x0
  1840.     move            x0,x:(r2)+
  1841. _repeatloop:
  1842.  
  1843.     sub    a,b        a,x:<Polygon.top        ; Store top, height := bottom-top.
  1844.     move            b,x:<Polygon.height        ; Store height.
  1845.     rts
  1846.  
  1847. ; This stores textures sent by the host.
  1848. ; The texturebuffer allows up to 8192 interleaved (7b,16b) pixels
  1849. ; (0aaaaaaahhhhhhhhhhhhhhhh).
  1850. Polygon.storeTexture:
  1851.     move            #>8192,n6
  1852.     move            #>$7F0000,x0
  1853.     move            #>Polygon.texture,r0
  1854.  
  1855. ; We do this one for the alpha's. 8bpp -> 7bpp (for signed sillyness).
  1856.     do    n6,_rescale7bitloop
  1857.     get    a
  1858.     asr    a        a,b
  1859.     and    x0,a        #>$00FFFF,x1
  1860.     and    x1,b
  1861.     move            b,y0
  1862.     or    y0,a
  1863.     move                    a1,y:(r0)+
  1864. _rescale7bitloop:
  1865.  
  1866. ; Sets texturing to pixel-mode. Implies 64*64 mapping!
  1867. Polygon.setPixelMode:
  1868.     move            #>64,x0
  1869.     move            x:<Polygon.sendPixelInstruction,y0
  1870.     jmp    <Polygon.setTextureSize
  1871.  
  1872. ; Sets texturing to offset-mode. Implies 256*256 mapping!
  1873. Polygon.setOffsetMode:
  1874.     move            #>256,x0
  1875.     move            x:<Polygon.sendOffsetInstruction,y0
  1876.  
  1877. ; x0=dimension {2,4,8,16,32,64,128,256,...}
  1878. Polygon.setTextureSize:
  1879.     move    y0,p:>Polygon.paintTextured_pixelinstruction
  1880.     mpy    x0,x0,a        x0,x:<texturewidth
  1881.     asr    a        #>1,x1
  1882.     tfr    x0,b        a0,a
  1883.     sub    x1,a        a,x:<texturesize
  1884.     neg    b        a1,x1
  1885.     and    x1,b        #>64,y1
  1886.     mpy    x0,y1,a                b1,y:<texturemask
  1887. ; U scaling (6:10 -> 6 or 8:8 -> 8) :
  1888. ; $002000 for 64
  1889. ; $008000 for 256
  1890.     move            a0,x:<u_scale
  1891. ; V scaling (6:10 -> 6:6 or 8:8 -> 8:8) :
  1892. ; $080000 for 64x64 $1000
  1893. ; $800000 for 256x256 $10000 (isn't this negative?)
  1894.     move            #>$40,y1
  1895.     move            x:<texturesize,x0
  1896.     mpy    x0,y1,a
  1897.     move            a0,y:v_scale
  1898.     rts
  1899.  
  1900. Polygon.setV4AlphaMode:
  1901.     move    #Polygon.paintV4_send_alpha_hline,x0
  1902.     move    x0,y:<Polygon.v4RoutineAddress
  1903.     rts
  1904.  
  1905. Polygon.setV4BumpMode:
  1906.     move    #Polygon.paintV4_send_bump_hline,x0
  1907.     move    x0,y:<Polygon.v4RoutineAddress
  1908.     rts
  1909.  
  1910. ; RPC call routine!
  1911. Polygon.paintReceivedClipped:
  1912.     jsr    <Polygon.receive
  1913.     jsr    <Polygon.clip
  1914. ; a = clipped/unclipped flag, r0 = polygon table
  1915.     tst    a
  1916.     jeq    <_culled
  1917.  
  1918. ; Send the shadetype.
  1919.     send    x:<Polygon.shadeType
  1920.     jmp    <Polygon.paintClipped_proceed
  1921.  
  1922. ; Send negative shadetype = terminator!
  1923. _culled:send    #-1
  1924.     rts
  1925.  
  1926. Polygon.paintClipped:
  1927. ; Clip the polyon..
  1928.     jsr    <Polygon.clip
  1929. ; a = clipped/unclipped flag, r0 = polygon table
  1930.     tst    a
  1931.     jeq    <_end
  1932.  
  1933. ; Send the shadetype first.
  1934.     send    x:<Polygon.shadeType
  1935.  
  1936. ; Outline stuff.. Only needed when painted from mesh in dsp mem..
  1937.     move            x:>PrimitiveMesh.shadowOn,b
  1938.     tst    b        x:<Polygon.vsize,n1
  1939.     jeq    <_proceed
  1940.  
  1941. ; Send outlines to host..
  1942.     move            #<1,n0
  1943.     move            x:<Polygon.points,x1
  1944.     send    x1                        ; Send #points.
  1945.     lua    (r0)+n0,r1                    ; r1: first x in polytable
  1946.  
  1947.     do    x1,_loop
  1948.     send    x:(r1)-                        ; Send x.
  1949.     send    x:(r1)+                        ; Send y.
  1950.     move            (r1)+n1
  1951.     move            (r1)+
  1952. _loop:
  1953.  
  1954. _proceed:
  1955. ; Sends polygon scanlinewise.
  1956. ; r0= polygontable
  1957.     jsr    <Polygon.getDimensions
  1958.     move            r0,r6
  1959.     jsr    <Polygon.drawEdges
  1960.     jmp    <Polygon.send
  1961.  
  1962. _end:    rts
  1963.  
  1964. ; RPC call routine!
  1965. ; Beware: unclipped painter!
  1966. Polygon.paint:
  1967.     jsr    <Polygon.receive
  1968.     move            #<Polygon.polygonTable,r6
  1969.     jsr    <Polygon.drawEdges
  1970.     jmp    <Polygon.send
  1971.  
  1972. ; This initialises the pipeline in pixel-mode.
  1973. InitPipeline:
  1974. ; Set to linear addressing!
  1975.     movec    #$FFFF,m0
  1976.     movec    m0,m1
  1977.     movec    m0,m2
  1978.     movec    m0,m3
  1979.     movec    m0,m4
  1980.     movec    m0,m5
  1981.     movec    m0,m6
  1982.  
  1983.     jsr    <GetInvTable
  1984.     jsr    <Polygon.setPixelMode
  1985.     jsr    <Object.clear
  1986.     clr    a
  1987.     move            a,x:<Matrix.stackTop
  1988.     rts
  1989.  
  1990. ; Calculates 1/n table.
  1991. GetInvTable:
  1992.     move            #>InverseTable,r0
  1993.     clr    a        #>1,x0
  1994.     move            #>$7FFF00,y0
  1995.     do    #INVBUF_SIZE,_loop
  1996.     move            a1,x1
  1997.     move            #>1,b
  1998.     rep    #24
  1999.     div    x1,b
  2000.     move            b0,b
  2001.     and    y0,b                        ; And to get same low precision as 68K
  2002.     add    x0,a                b,y:(r0)+
  2003. _loop:    rts
  2004.  
  2005. ;======== Viewport
  2006.  
  2007. ; Get new viewport settings from cpu.
  2008. Viewport.update:
  2009.     move            #<Viewport.settingsTable,r0
  2010.     do    #Viewport.SIZE,_loop
  2011.     get    x:(r0)+
  2012. _loop:
  2013.     move            x:<Viewport.Aspect,x0
  2014.     move            #1<<13,x1
  2015.     mpy    x0,x1,a
  2016.     move            a0,x:<Viewport.Aspect
  2017.     rts
  2018.  
  2019. ;======== Matrix
  2020.  
  2021. ; This is perfection.
  2022. ; Total cycles on 56001: 58 (!)
  2023. ; INPUT:
  2024. ; r0: X-sine
  2025. ; r1: X-cosine
  2026. ; r2: Y-sine
  2027. ; r3: Y-cosine
  2028. ; r4: Z-sine
  2029. ; r5: Z-cosine
  2030. Matrix.generate:
  2031.     move            #<Matrix.temp,r6
  2032.  
  2033. ; XX := + x*cos(b)*cos(c)
  2034. ; XY := - y*cos(b)*sin(c)
  2035. ; XZ := + z*sin(b)
  2036.     move            x:(r3),x1    y:(r5),y1
  2037. ; x0:-- x1:r3 y0:-- y1:r5
  2038.     mpyr    +x1,y1,a    x:(r0),x0    y:(r4),y0    ; r3*r5
  2039.  
  2040. ; x0:r0 x1:r3 y0:r4 y1:r5
  2041.     mpyr    -x1,y0,a    x:(r2),x1    a,y:(r6)+    ; -r3*r4
  2042. ; x0:r0 x1:r3 y0:r2 y1:r5
  2043.     move                    a,y:(r6)+
  2044.  
  2045.     move                    x1,y:(r6)+    ; r2
  2046.     
  2047. ; YX := + x*sin(a)*sin(b)*cos(c)+cos(a)*sin(c)
  2048. ; YY := + y*cos(a)*cos(c)-sin(a)*sin(b)*sin(c)
  2049. ; YZ := - z*sin(a)*cos(b)
  2050.     mpyr    +x0,x1,a            y:(r5),y0    ; r0*r2
  2051. ; x0:r0 x1:r3 y0:r5 y1:r5
  2052.     move            a,y1
  2053.     mpy    +y0,y1,a    x:(r1),x1    y:(r4),y1    ; a*r5
  2054. ; x0:r0 x1:r1 y0:r5 y1:r4
  2055.     macr    +x1,y1,a            y:(r5),y1    ; a+r1*r4
  2056. ; x0:r0 x1:r1 y0:r5 y1:r5
  2057.  
  2058.     mpy    +x1,y1,a    x:(r2),x1    a,y:(r6)+    ; r1*r5
  2059. ; x0:r0 x1:r2 y0:r5 y1:r5
  2060.     mpyr    -x0,x1,b            y:(r4),y0    ; r0*r2
  2061. ; x0:r0 x1:r2 y0:r4 y1:r5
  2062.     move            b,y1
  2063.     macr    +y0,y1,a    x:(r3),x1    y:(r4),y1    ; a+b*r4
  2064. ; x0:r0 x1:r3 y0:r4 y1:r4
  2065.  
  2066.     mpyr    -x0,x1,a    x:(r2),x1    a,y:(r6)+    ; r0*r3
  2067. ; x0:r0 x1:r2 y0:r4 y1:r4
  2068.  
  2069. ; ZX := + x*sin(a)*sin(c)-cos(a)*sin(b)*cos(c)
  2070. ; ZY := + y*cos(a)*sin(b)*sin(c)+sin(a)*cos(c)
  2071. ; ZZ := + z*cos(a)*cos(b)
  2072.     mpy    +x0,y1,a    x:(r1),x0    a,y:(r6)+    ; r0*r4
  2073. ; x0:r1 x1:r2 y0:r4 y1:r4
  2074.     mpyr    -x0,x1,b    x:(r2),x0    y:(r5),y1    ; r1*r2
  2075. ; x0:r2 x1:r2 y0:r4 y1:r5
  2076.     move            b,x1
  2077.     macr    +x1,y1,a    x:(r1),x1    y:(r4),y0    ; a+b*r5
  2078. ; x0:r2 x1:r1 y0:r4 y1:r5
  2079.  
  2080.     mpyr    +x1,x0,a    x:(r3),x0    a,y:(r6)+    ; r1*r2
  2081. ; x0:r3 x1:r1 y0:r4 y1:r5
  2082.     move            a,y1
  2083.     mpy    +y0,y1,a    x:(r0),x1    y:(r5),y1    ; a*r4
  2084. ; x0:r3 x1:r0 y0:r4 y1:r5
  2085.     macr    +x1,y1,a    x:(r1),x1            ; r0*r5
  2086. ; x0:r3 x1:r1 y0:r4 y1:r5
  2087.  
  2088.     mpyr    +x1,x0,a            a,y:(r6)+    ; r1*r3
  2089.  
  2090. ; Set translation vector to origin.
  2091.     clr    a                a,y:(r6)+
  2092.     move                    a,y:(r6)+
  2093.     move                    a,y:(r6)+
  2094.     move                    a,y:(r6)+
  2095.     rts
  2096.  
  2097. ; INPUT:
  2098. ; y:r0: matrix to multiply with (source)
  2099. ; y:r3: (new) destination matrix
  2100. Matrix.multiply:
  2101. ; Get source and destination matrices and flip them.
  2102.     move            #<Matrix.temp,r2
  2103.     move            r0,r4                ; r4 := source
  2104.     move            r2,r5
  2105.     move            #<3,n2
  2106.  
  2107. ; Multiply the matrix.
  2108.     do    #3,_row_loop
  2109. ; Fetch new row.
  2110.     move                    y:(r0)+,x0
  2111.     move                    y:(r0)+,x1
  2112.     move                    y:(r0)+,y0
  2113.  
  2114.     do    #3,_cell_loop
  2115. ; Multiply column with row.
  2116.     move                    y:(r2)+n2,y1
  2117.     mpy    x0,y1,a                y:(r2)+n2,y1
  2118.     mac    x1,y1,a                y:(r2)-n2,y1
  2119.     macr    y0,y1,a        (r2)-n2
  2120.     move                    a,y:(r3)+    ; Store product.
  2121.     move            (r2)+                ; Proceed to next column.
  2122. _cell_loop:
  2123.  
  2124.     move            (r2)-n2                ; Back to first column.
  2125. _row_loop:
  2126.  
  2127. ; Multiply the object translation vector with the world matrix.
  2128.     move            #<Matrix.temp+Matrix.TX,r2
  2129.     move                    y:(r4)+,y1
  2130.     move                    y:(r2)+,x0
  2131.     move                    y:(r2)+,x1
  2132.     move                    y:(r2)+,y0
  2133.     do    #3,_transloop
  2134.     move                    y:(r0)+,a    ; a := source TX
  2135.     mac    x0,y1,a                y:(r4)+,y1    ; TX * MXX +
  2136.     mac    x1,y1,a                y:(r4)+,y1    ; TY * MXY +
  2137.     macr    y0,y1,a                y:(r4)+,y1    ; TZ * MXZ
  2138.     move                    a,y:(r3)+    ; Store TX'.
  2139. _transloop:
  2140.     rts
  2141.  
  2142. Matrix.convertStoredQuaternion:
  2143.     rts
  2144.  
  2145. Matrix.convertQuaternion:
  2146.     rts
  2147.  
  2148. Matrix.convertRotation:
  2149.     move    #<SineX,r0
  2150.     move    #<CosineX,r1
  2151.     move    #<SineY,r2
  2152.     move    #<CosineY,r3
  2153.     move    #<SineZ,r4
  2154.     move    #<CosineZ,r5
  2155.     jsr    <ReceiveRotation
  2156.     jmp    <Matrix.generate
  2157.  
  2158. ; INPUT:
  2159. ; x:r0: sin/cos values
  2160. Matrix.convertStoredRotation:
  2161.     move            r0,r6
  2162.     move            #<SineX,r0
  2163.     move            #<CosineX,r1
  2164.     move            #<SineY,r2
  2165.     move            #<CosineY,r3
  2166.     move            #<SineZ,r4
  2167.     move            #<CosineZ,r5
  2168.     move            x:(r6)+,x0
  2169.     move            x0,x:(r0)
  2170.     move            x:(r6)+,x0
  2171.     move            x0,x:(r1)
  2172.     move            x:(r6)+,x0
  2173.     move            x0,x:(r2)
  2174.     move            x:(r6)+,x0
  2175.     move            x0,x:(r3)
  2176.     move            x:(r6)+,x0
  2177.     move                    x0,y:(r4)
  2178.     move            x:(r6)+,x0
  2179.     move                    x0,y:(r5)
  2180.     jmp    <Matrix.generate
  2181.  
  2182. Matrix.rpcTranslate:
  2183.     get    x0
  2184.     get    x1
  2185.     get    y0
  2186.     jmp    <Matrix.translate
  2187.  
  2188. ; INPUT:
  2189. ; x:r0: stored parameters
  2190. Matrix.translateStored:
  2191.     move            x:(r0)+,x0
  2192.     move            x:(r0)+,x1
  2193.     move            x:(r0)+,y0
  2194.  
  2195. ; INPUT:
  2196. ; x0: X
  2197. ; x1: Y
  2198. ; y0: Z
  2199. Matrix.translate:
  2200.     move            #<Matrix.temp+Matrix.TX,r0
  2201.     move            #<1,n0
  2202.     move                    y:(r0)+,a
  2203.     add    x0,a                y:(r0)-,b
  2204.     add    x1,b                a,y:(r0)+
  2205.     move                    y:(r0+n0),a
  2206.     add    y0,a                b,y:(r0)+
  2207.     move                    a,y:(r0)
  2208.     rts
  2209.  
  2210. ; Pushes a previously generated matrix on the stack.
  2211. Matrix.push:
  2212. ; First check for stack overflow.
  2213.     move            #<Matrix.stack,r0
  2214.     move            x:<Matrix.stackTop,a
  2215.     tst    a        #>Matrix.MAX_DEPTH,x0
  2216.     jeq    <_first_entry
  2217.     cmp    x0,a        #>Matrix.SIZE,x0
  2218.     jhs    <_end
  2219. ; The stack is not full..
  2220.  
  2221. _not_first_entry:
  2222.     move            a,x1
  2223.     mpy    x0,x1,a
  2224.     asr    a
  2225.     move            a0,n0                ; n0 := offset to dest. matrix
  2226.     move            x0,n1
  2227.     move            (r0)+n0                ; r0 := dest. matrix
  2228.     move            r0,r1
  2229.     move            r0,r3                ; r3 := dest. matrix
  2230.     move            (r1)-n1                ; r1 := source matrix
  2231.     move            r1,r0                ; r0 := source matrix
  2232.     jsr    <Matrix.multiply
  2233.     jmp    <_end_multiply_matrix
  2234. ; If this is the first matrix on the stack, then simply copy it.
  2235. _first_entry:
  2236.     move            #<Matrix.temp,r1
  2237.     do    #Matrix.SIZE,_copy_loop
  2238.     move                    y:(r1)+,x0
  2239.     move                    x0,y:(r0)+
  2240. _copy_loop:
  2241. _end_multiply_matrix:
  2242.  
  2243. ; Increase the stacktop by one.
  2244.     move            x:<Matrix.stackTop,a
  2245.     move            #>1,x0
  2246.     add    x0,a
  2247.     move            a,x:<Matrix.stackTop
  2248.  
  2249. _end:    rts
  2250.  
  2251. ; Pops the top matrix off the stack.
  2252. Matrix.pop:
  2253.     move            x:<Matrix.stackTop,a
  2254.     tst    a        #>1,x0
  2255.     jle    <_end
  2256.     sub    x0,a
  2257.     move            a,x:<Matrix.stackTop
  2258. _end:    rts
  2259.  
  2260. ;======== PrimitiveMesh
  2261.  
  2262. ; INPUT:
  2263. ; x:r0: stored parameter (shadow-flag)
  2264. PrimitiveMesh.new:
  2265. ; Store shadow-flag..
  2266.     move            x:(r0)+,a
  2267.     move            a,x:>PrimitiveMesh.shadowOn
  2268. ; Reset pointers..
  2269.     clr    a        #>PrimitiveMesh.vertexTable,x0
  2270.     move            x0,x:>PrimitiveMesh.nextVertex
  2271.     move            a,x:>PrimitiveMesh.primitiveTable
  2272.     move            a,x:>BoundingBox.rectangleCount
  2273.     move            a,x:>PrimitiveMesh.baseHandle
  2274.     rts
  2275.  
  2276. ; Paints all primitives.
  2277. PrimitiveMesh.paint:
  2278.     move            #<PrimitiveMesh.primitiveTable,r0
  2279.     nop
  2280.     move            x:(r0)+,a
  2281.     tst    a
  2282.     jeq    <_end
  2283.  
  2284.     do    a,_loop
  2285.     move            #>Primitive.TYPEMASK,x0
  2286.     IFNE    1
  2287.     move            x:(r0)+,r1            ; r1= base of primitive's vertices
  2288.     move            x:(r0)+,r2            ; r2= address of primitive
  2289.     ELSE
  2290.     move            x:(r0)+,x1
  2291.     move            #>$000080,x0
  2292.     mpy    x0,x1,a        #>PrimitiveMesh.baseTable,r1
  2293.     move            a1,n1                ; r1= vertexbase handle
  2294.     move            x1,r2                ; r2= address of primitive
  2295.     move            x:(r1+n1),r1            ; r1= vertex base address
  2296.     ENDC
  2297.     clr    a        (r0)+
  2298.     move            x:(r2),a1            ; a= primitive's type
  2299.     move            r0,p:>PrimitiveMesh.currentElement
  2300.     and    x0,a        #>Primitive.SPRITETYPE,x0
  2301.     cmp    x0,a        #>Primitive.LINETYPE,x0
  2302.     jgt    _test_line
  2303.  
  2304. ; Handle a sprite.
  2305. _is_sprite:
  2306.     send    #RPC_SPRITE
  2307.     move            (r1)+
  2308.     send    x:(r2)+
  2309.     move            x:(r2)+,a            ; Fetch vertex index.
  2310.     asl    a        a,x0
  2311.     add    x0,a        r1,b
  2312.     add    a,b
  2313.     move            b,r1
  2314.     do    #3,_spriteloop
  2315.     send    y:(r1)+
  2316. _spriteloop:
  2317.     move            (r1)-
  2318.     jmp    <_end_loop
  2319. _test_line:
  2320.     cmp    x0,a
  2321.     jgt    _is_polygon
  2322.  
  2323. ; Handle a line.
  2324. _is_line:
  2325.     send    #RPC_LINE
  2326.     move            (r1)+
  2327.     move            x:(r2)+,x1
  2328.     send    x1
  2329.     do    #2,_lineloop
  2330.     move            x:(r2)+,a            ; Fetch vertex index.
  2331.     asl    a        a,x0
  2332.     add    x0,a        r1,b
  2333.     add    a,b        r1,r3
  2334.     move            b,r1
  2335.     do    #2,_linecoordloop
  2336.     send    y:(r1)+
  2337. _linecoordloop:
  2338.     move            r3,r1
  2339. _lineloop:
  2340.     tfr    x1,a        #>Primitive.SHADEMASK,x0
  2341.     and    x0,a        #>Line.GOURAUDSHADED,x0
  2342.     cmp    x0,a
  2343.     jeq    <_gouraudshaded
  2344.     jgt    <_phongshaded
  2345. _flatshaded:
  2346.     move            (r1)-
  2347.     jmp    <_end_loop
  2348.  
  2349. _gouraudshaded:
  2350.     move            (r1)-
  2351.     send    x:(r2)+
  2352.     send    x:(r2)+
  2353.     jmp    <_end_loop
  2354.  
  2355. _phongshaded:
  2356.     move            #<Vertex.Z,n1
  2357.     move            #>$80,x1
  2358.     do    #2,_phongloop
  2359.     move            x:(r2)+,a            ; Fetch vertex index.
  2360.     asl    a        a,x0
  2361.     add    x0,a        r1,b
  2362.     add    a,b        r1,r3
  2363.     move            b,r1
  2364.     nop
  2365.     move                    y:(r1+n1),a
  2366.     add    x1,a
  2367.     asr    a        r3,r1
  2368.     send    a
  2369. _phongloop:
  2370.     move            (r1)-
  2371.     jmp    <_end_loop
  2372.  
  2373. ; Handle a polygon.
  2374. _is_polygon:
  2375.     jsr    <Polygon.decode
  2376.     jsr    <Polygon.paintClipped
  2377.  
  2378. _end_loop:
  2379.     move            p:>PrimitiveMesh.currentElement,r0
  2380. _loop:
  2381.  
  2382. ; All primitives are painted, now send the terminator: "I'll be back"... ;)
  2383. _end:    move            #>$ffffff,x0
  2384.     send    x0
  2385.  
  2386. ; Now send them bounding rectangle critters.
  2387.     move            x:>BoundingBox.rectangleCount,a
  2388.     send    a                        ; Send rectanglecount.
  2389.     lsl    a        #>BoundingBox.rectangles,r0
  2390.     jeq    <_die
  2391.     lsl    a
  2392.     do    a,_rectloop
  2393.     send            x:(r0)+
  2394. _rectloop:
  2395. _die:    rts
  2396.  
  2397. PrimitiveMesh.currentElement:
  2398.     DS    1
  2399.  
  2400. ;======== TransformObject
  2401.  
  2402. ; RPC call routine!
  2403. TransformObject.rpcTransform:
  2404.     get    n0
  2405.     jmp    <TransformObject.transform
  2406.  
  2407. ;======== ObjectRegistry
  2408.  
  2409. ; Adds a 3d-object to the registry and returns a handle to host.
  2410. ; Returns -1 if not added.
  2411. Object.set:
  2412.     move            x:>Object.newHandleAddress,r1
  2413.     get    a                        ; Get #objwords+#bufwords.
  2414.     move            #>Object.CAPACITY,x0
  2415.     cmp    x0,a        x:(r1)+,r0            ; Get designated address in object-buffer.
  2416.     jgt    <_error
  2417.     move            r0,r2                ; backup start of object
  2418.     move            #>Object.handlesEnd,b
  2419.     move            r1,x0
  2420.     cmp    x0,b        #<0,x0
  2421. ; Inform the host the object is accepted (result = 0)..
  2422.     send    x0
  2423.     get    a                        ; Get #objwords
  2424.  
  2425.     do    a,_get_object_loop
  2426.     get    x:(r0)+                        ; Receive one object word from cpu.
  2427. _get_object_loop:
  2428.  
  2429. ; Store pointer to next handle..
  2430.     move            r1,x:>Object.newHandleAddress
  2431.     move            #>Object.handleTable,n1
  2432.     move            r0,x:(r1)-            ; Store start of free space.
  2433.     move            (r1)-n1
  2434.     move            r1,x0                ; x0=boundingbox handle
  2435.     jmp    <BoundingBox.init
  2436.  
  2437. ; Inform the host the object is rejected (result = -1)..
  2438. _error:    move            #>-1,a
  2439.     send    a
  2440.     rts
  2441.  
  2442. ; Returns the objectaddress of the specified handle.
  2443. ; No checking for invalid handles!!
  2444. ; INPUT:
  2445. ; n0: ObjectHandle
  2446. ; OUTPUT:
  2447. ; r0: ObjectAddress
  2448. Object.get:
  2449.     move            #>Object.handleTable,r0
  2450.     nop
  2451.     move            x:(r0+n0),r0
  2452.     rts
  2453.  
  2454. ; Clears the registry. All handles become invalid.
  2455. Object.clear:
  2456.     move            #Object.handleTable,x0
  2457.     move            x0,x:>Object.newHandleAddress
  2458.     move            #Object.buffer,x0
  2459.     move            x0,x:>Object.handleTable
  2460.     rts
  2461.  
  2462. ; Replaces object's primitives/vertices/normals/texels.
  2463. ; Reads these from the host.
  2464. Object.replace:
  2465.     move            #>Object.handleTable,r0
  2466.     get    n0                        ; n0=handle
  2467.     get    a                        ; a=replacemode
  2468.     move            x:(r0+n0),r0            ; r0=object
  2469.     move            n0,n6                ; n6=handle
  2470.     move            r0,r6                ; r6=object
  2471.  
  2472. ; Calculate addresses of tables and lists.
  2473.     move            x:(r0)+,b            ; b=#vertices+#normals
  2474.     lsl    b        b,x0
  2475.     add    x0,b        x:(r0)+,x0            ; x0=#normals
  2476.     move            b1,n0                ; n0=(#vertices+#normals)*3=offset to texels
  2477.     move            x0,b
  2478.     lua    (r0)+n0,r2
  2479.     asl    b
  2480.     add    x0,b
  2481.     move            b1,n2                ; n2=#normals*3
  2482.     move            x:(r2)+,n3            ; n3=#texels
  2483.     lua    (r2)-n2,r1
  2484.     move            r2,r3
  2485.     nop
  2486.     move            (r3)+n3
  2487.     move            (r3)+n3
  2488. ; r0=vertices
  2489. ; r1=normals
  2490. ; r2=texels
  2491. ; r3=primitives
  2492.  
  2493. ; Get vertices..
  2494.     lsr    a
  2495.     jcc    <_end_vertices    
  2496.     get    b                        ; b=#words
  2497.     tst    b
  2498.     jeq    <_end_vertices
  2499.     do    b,_ver_loop
  2500.  
  2501.     get    x:(r0)+    
  2502. _ver_loop:
  2503. _end_vertices:
  2504.  
  2505. ; Get normals..
  2506.     lsr    a
  2507.     jcc    <_end_normals
  2508.     get    b                        ; b=#words
  2509.     tst    b
  2510.     jeq    <_end_normals
  2511.     do    b,_nor_loop
  2512.  
  2513.     get    x:(r1)+    
  2514. _nor_loop:
  2515. _end_normals:
  2516.  
  2517. ; Get texels..
  2518.     lsr    a
  2519.     jcc    <_end    
  2520.     get    b                        ; b=#words
  2521.     tst    b
  2522.     jeq    <_end
  2523.     do    b,_tex_loop
  2524.  
  2525.     get    x:(r2)+    
  2526. _tex_loop:
  2527.  
  2528. ; Get primitives..
  2529.     lsr    a
  2530.     jcc    <_end
  2531.     get    b                        ; b=#words
  2532.     tst    b
  2533.     jeq    <_end
  2534.     do    b,_prim_loop
  2535.  
  2536.     get    x:(r3)+    
  2537. _prim_loop:
  2538.  
  2539. _end:    move            n6,x0                ; x0=handle
  2540.     move            r6,r2                ; r2=object
  2541.     jmp    <BoundingBox.init
  2542.  
  2543. ; Processes an object into a bounding box.
  2544. ; A bounding box is represented by axxiii (what's that spelled like?)
  2545. ; Each axis has an upper and a lower bound.
  2546. ; INPUT:
  2547. ; x0: bounding box handle
  2548. ; x:r2: ufly.2 object
  2549. BoundingBox.init:
  2550. ; First initialize the destination structure.
  2551.     move            #>BoundingBox.SIZE,x1
  2552.     mpy    x0,x1,a        x1,n0
  2553.     asr    a        #>BoundingBox.table,x0
  2554.     move            a0,a
  2555.     add    x0,a        #>$800000,b            ; initial highest
  2556.     move            a,r0
  2557.     move            #>$7fffff,a            ; initial lowest
  2558.     do    #3,_resetloop
  2559.     move            a,x:(r0)+
  2560.     move            b,x:(r0)+
  2561. _resetloop:
  2562.  
  2563.     move            x:(r2)+,x0
  2564.     move            (r2)+
  2565.     move            (r0)-n0
  2566.  
  2567.     do    x0,_vertexloop
  2568.     do    #3,_coordloop
  2569.     move            x:(r0)+,a            ; a= lowest
  2570.     move            x:(r2)+,x0            ; x0= coord
  2571.     cmp    x0,a        x:(r0)-,b            ; b= highest
  2572.     tgt    x0,a
  2573.     cmp    x0,b        a,x:(r0)+
  2574.     tlt    x0,b
  2575.     move            b,x:(r0)+
  2576. _coordloop
  2577.     move            (r0)-n0
  2578. _vertexloop:    
  2579.     rts
  2580.  
  2581. ; Transforms a bounding box into a bounding rectangle.
  2582. ; INPUT:
  2583. ; n0: objecthandle
  2584. ; OUTPUT:
  2585. ; a: 1=visible, 0=invisible
  2586. BoundingBox.calcRectangle:
  2587.     move            n0,x0
  2588.     move            #>BoundingBox.SIZE,x1
  2589.     mpy    x0,x1,a        #>BoundingBox.decoded,r1
  2590.     asr    a        #>BoundingBox.table,r2
  2591.     move            a0,n2
  2592.     clr    a        #>1,x1
  2593.     move            (r2)+n2
  2594.     move            #<5,n2
  2595.  
  2596. ; x:r0 = address of encoded box (src)
  2597. ; x:r1 = address of decoded box (dst)
  2598.     move            #>%111,b
  2599.     do    #8,_loop
  2600. _do_x:    move            x:(r2)+,a
  2601.     move            x:(r2)+,x0
  2602.     jclr    #0,b,_no_x
  2603.     tfr    x0,a
  2604. _no_x:    move            a,x:(r1)+
  2605. _do_y:    move            x:(r2)+,a
  2606.     move            x:(r2)+,x0
  2607.     jclr    #1,b,_no_y
  2608.     tfr    x0,a
  2609. _no_y:    move            a,x:(r1)+
  2610. _do_z:    move            x:(r2)+,a
  2611.     move            x:(r2)-n2,x0
  2612.     jclr    #2,b,_no_z
  2613.     tfr    x0,a
  2614. _no_z:    sub    x1,b        a,x:(r1)+
  2615. _loop:
  2616.  
  2617.     move            #>BoundingBox.decoded,r0
  2618.     move            #>BoundingBox.transformed-1,r5
  2619.     move            #>8,b
  2620.     jsr    <Vertex.transform
  2621.  
  2622. ; Check if behind cam...
  2623.     move            #>BoundingBox.transformed+2,r2
  2624.     move            #<3,n2
  2625.     clr    a
  2626.     move                    y:(r2)+n2,x0
  2627.     rep    #7
  2628.     or    x0,a                y:(r2)+n2,x0
  2629.  
  2630.     tst    a
  2631.     jmi    <_invisible
  2632.  
  2633. ; Transform the box into a rectangle...
  2634. ; dim??? D1m??!?!?! That's sounds like *yich* BASIC! :P
  2635.     move            x:>BoundingBox.rectangleCount,a
  2636.     lsl    a        #>BoundingBox.transformed,r2
  2637.     lsl    a        #>BoundingBox.rectangles,x0
  2638.     add    x0,a        #<8*3-1,n2
  2639.     move            a,r1                ; r1= new rectangle
  2640.     move            a,r3
  2641.     do    #2,_outloop
  2642.     move            #>$7fffff,a            ; a= min
  2643.     move            #<$80,b                ; b= max
  2644.     do    #8,_dimloop
  2645.     move                    y:(r2)+,x0    ; x0= coord
  2646.     cmp    x0,a        (r2)+
  2647.     tgt    x0,a
  2648.     cmp    x0,b        (r2)+
  2649.     tlt    x0,b
  2650. _dimloop:
  2651.     move            a,x:(r1)+            ; Store min.
  2652.     move            b,x:(r1)+            ; Store max.
  2653.     move            (r2)-n2
  2654. _outloop:
  2655.  
  2656. ; Store rectangle....
  2657.     move            #<0,r0
  2658.     move            x:(r3)+,a
  2659.     move            x:(r3)+,b
  2660.     move            x:<Viewport.YStart,x0
  2661.     cmp    x0,b        x:<Viewport.YEnd,x1
  2662.     jgt    <_end_left
  2663.     move            #<1,r0
  2664. _end_left:
  2665.     cmp    x1,a        x:<Viewport.XStart,y0
  2666.     jle    <_end_right
  2667.     move            #<1,r0
  2668. _end_right:
  2669.     move            x:(r3)+,a
  2670.     move            x:(r3)+,b
  2671.     cmp    y0,b        x:<Viewport.XEnd,y1
  2672.     jgt    <_end_top
  2673.     move            #<1,r0
  2674. _end_top:
  2675.     cmp    y1,a
  2676.     jle    <_end_bottom
  2677.     move            #<1,r0
  2678. _end_bottom:
  2679.  
  2680.     nop
  2681.     move            r0,a
  2682.     tst    a
  2683.     jeq    <_visible
  2684.  
  2685. ; Return the invisibility.
  2686. _invisible:
  2687.     clr    a
  2688.     rts
  2689.  
  2690. _visible:
  2691.     move            x:>BoundingBox.rectangleCount,r0
  2692.     move            #>1,a
  2693.     move            (r0)+
  2694.     move            r0,x:>BoundingBox.rectangleCount
  2695.     rts
  2696.  
  2697. p_memory_end:
  2698.  
  2699. ;======== X-Memory Code ========
  2700.  
  2701.     ORG    X:$0000
  2702.  
  2703. texturewidth:
  2704.     DS    1                        ; texture v width
  2705. u_scale:DS    1
  2706. u0:    DS    1
  2707. u0_step:DS    1                        ; u_step storage
  2708. u1:    DS    1
  2709. u1_step:DS    1                        ; u_step storage
  2710. colorshift:
  2711.     DC    $008000
  2712. alphashift:
  2713.     DC    $000100
  2714.  
  2715. texturesize:
  2716.     DS    1                        ; texture size
  2717.  
  2718. spaceometer:
  2719.     DC    Polygon.TEXTUREBUFFER_SIZE
  2720.  
  2721. SineX:    DS    1
  2722. CosineX:DS    1
  2723. SineY:    DS    1
  2724. CosineY:DS    1
  2725.  
  2726. ;======== Matrix
  2727.  
  2728. Matrix.stackTop:
  2729.     DC    0
  2730.  
  2731. ;======== TransformObject
  2732.  
  2733. TransformObject.vertexadr:
  2734.     DS    1
  2735.  
  2736. ;======== Viewport
  2737.  
  2738. Viewport.settingsTable:
  2739. Viewport.XScreen:
  2740.     DS    1
  2741. Viewport.YScreen:
  2742.     DS    1
  2743. Viewport.XStart:
  2744.     DS    1
  2745. Viewport.XEnd:
  2746.     DS    1
  2747. Viewport.YStart:
  2748.     DS    1
  2749. Viewport.YEnd:
  2750.     DS    1
  2751. Viewport.XCenter:
  2752.     DS    1
  2753. Viewport.YCenter:
  2754.     DS    1
  2755. Viewport.Focal:
  2756.     DS    1
  2757. Viewport.Aspect:
  2758.     DS    1                        ; 8:8 Y scale
  2759. Viewport.settingsTableEnd:
  2760.  
  2761. ;======== Polygon
  2762.  
  2763. Polygon.points:
  2764.     DS    1
  2765. Polygon.vsize:
  2766.     DS    1
  2767. Polygon.z:
  2768.     DS    1
  2769. Polygon.clipFlags:
  2770.     DS    1
  2771. Polygon.height:
  2772.     DS    1
  2773. Polygon.top:
  2774.     DS    1
  2775. Polygon.shadeType:
  2776.     DS    1
  2777. Polygon.textureNumber:
  2778.     DS    1
  2779. Polygon.sendPixelInstruction:
  2780.     movep    y:(r4+n4),x:<<HTX                ; Send texturepixel.
  2781. Polygon.sendOffsetInstruction:
  2782.     move            b,x:(r3)    a,y1        ; Send textureoffset.
  2783. Polygon.polygonTable:
  2784.     DS    (12+1)*6                    ; max 12 points (x,y,u0,v0,u1,v1)
  2785. Polygon.polygonTable2:
  2786.     DS    (12+1)*6                    ; max 12 points (x,y,u0,v0,u1,v1)
  2787.  
  2788. ;======== EXTERNAL X RAM
  2789.  
  2790. ;======== PrimitiveMesh
  2791.  
  2792. PrimitiveMesh.shadowOn:
  2793.     DS    1
  2794. PrimitiveMesh.nextVertex:
  2795.     DS    1
  2796. PrimitiveMesh.baseHandle:
  2797.     DS    1
  2798. PrimitiveMesh.baseTable:
  2799.     DS    Object.MAX_OBJECTS                ; space for transformed object pointers!
  2800. PrimitiveMesh.primitiveTable:
  2801.     DS    1
  2802.     DS    PrimitiveMesh.MAX_ELEMENTS*MeshElement.SIZE
  2803.  
  2804. ;======== Object
  2805.  
  2806. Object.buffer:
  2807.     DS    Object.CAPACITY                    ; Maximum of 8192 words for all scene objects!
  2808. x_memory_end:
  2809. ; X<$3000 !!
  2810.  
  2811.     ORG    X:$3BDB                        ; for mixer
  2812.  
  2813. ;======== Object
  2814.  
  2815. Object.newHandleAddress:
  2816.     DS    1
  2817. Object.handleTable:
  2818.     DS    Object.MAX_OBJECTS
  2819. Object.handlesEnd:
  2820.  
  2821. ;======== BoundingBox
  2822.  
  2823. BoundingBox.table:
  2824.     DS    Object.MAX_OBJECTS*BoundingBox.SIZE
  2825. BoundingBox.decoded:
  2826.     DS    8*3                        ; 8 points in decoded box
  2827. BoundingBox.rectangleCount:
  2828.     DS    1
  2829. BoundingBox.rectangles:
  2830.     DS    4*Object.MAX_OBJECTS
  2831.  
  2832. ;======== Dispatcher
  2833.  
  2834. Dispatcher.commandTablePosition:
  2835.     DS    1
  2836. Dispatcher.commandTable:
  2837.     DS    Dispatcher.MAX_COMMANDS
  2838.  
  2839. Dispatcher.rpcTable:
  2840.     DC    Dispatcher.doNothing                ; RPC_TRANSMISSION_END
  2841.     DC    Object.clear                    ; RPC_CLEAR_REGISTRY
  2842.     DC    Object.set                    ; RPC_REGISTER_OBJECT
  2843.     DC    PrimitiveMesh.new                ; RPC_NEW_PRIMITIVEMESH
  2844.     DC    PrimitiveMesh.sort                ; RPC_SORT_PRIMITIVEMESH
  2845.     DC    PrimitiveMesh.paint                ; RPC_PAINT_PRIMITIVES
  2846.     DC    Matrix.convertRotation                ; RPC_GENERATE_ROTMATRIX
  2847.     DC    Matrix.convertQuaternion            ; RPC_GENERATE_QUATMATRIX
  2848.     DC    Matrix.push                    ; RPC_PUSH_MATRIX
  2849.     DC    Matrix.pop                    ; RPC_POP_MATRIX
  2850.     DC    Matrix.rpcTranslate                ; RPC_TRANSLATE_MATRIX
  2851.     DC    TransformObject.rpcTransform            ; RPC_TRANSFORM_OBJECT
  2852.     DC    Polygon.storeTexture                ; RPC_STORE_TEXTURE
  2853.     DC    Polygon.setPixelMode                ; RPC_SET_TEXTUREPIXEL
  2854.     DC    Polygon.setOffsetMode                ; RPC_SET_OFFSETPIXEL
  2855.     DC    Polygon.paint                    ; RPC_PAINT_POLYGON
  2856.     DC    Viewport.update                    ; RPC_UPDATE_VIEWPORT
  2857.     DC    Polygon.setV4AlphaMode                ; RPC_SET_V4ALPHA
  2858.     DC    Polygon.setV4BumpMode                ; RPC_SET_V4BUMP
  2859.     DC    Polygon.paintReceivedClipped            ; RPC_CLIPPAINT_POLYGON
  2860.     DC    Object.replace                    ; RPC_REPLACE_OBJECT
  2861.  
  2862. Dispatcher.storedRpcTable:
  2863.     DC    Dispatcher.doNothing                ; RPC_TRANSMISSION_END
  2864.     DC    Object.clear                    ; RPC_CLEAR_REGISTRY
  2865.     DC    Object.set                    ; RPC_REGISTER_OBJECT
  2866.     DC    PrimitiveMesh.new                ; RPC_NEW_PRIMITIVEMESH
  2867.     DC    PrimitiveMesh.sort                ; RPC_SORT_PRIMITIVEMESH
  2868.     DC    PrimitiveMesh.paint                ; RPC_PAINT_PRIMITIVES
  2869.     DC    Matrix.convertStoredRotation            ; RPC_GENERATE_ROTMATRIX
  2870.     DC    Matrix.convertStoredQuaternion            ; RPC_GENERATE_QUATMATRIX
  2871.     DC    Matrix.push                    ; RPC_PUSH_MATRIX
  2872.     DC    Matrix.pop                    ; RPC_POP_MATRIX
  2873.     DC    Matrix.translateStored                ; RPC_TRANSLATE_MATRIX
  2874.     DC    TransformObject.transformStored            ; RPC_TRANSFORM_OBJECT
  2875.     DC    Polygon.storeTexture                ; RPC_STORE_TEXTURE
  2876.     DC    Polygon.setPixelMode                ; RPC_SET_TEXTUREPIXEL
  2877.     DC    Polygon.setOffsetMode                ; RPC_SET_OFFSETPIXEL
  2878.     DC    Polygon.paint                    ; RPC_PAINT_POLYGON
  2879.     DC    Viewport.update                    ; RPC_UPDATE_VIEWPORT
  2880.     DC    Polygon.setV4AlphaMode                ; RPC_SET_V4ALPHA
  2881.     DC    Polygon.setV4BumpMode                ; RPC_SET_V4BUMP
  2882.     DC    Polygon.paintReceivedClipped            ; RPC_CLIPPAINT_POLYGON
  2883.     DC    Object.replace                    ; RPC_REPLACE_OBJECT
  2884.  
  2885. ; -1 indicates synchronous commandmode.
  2886. Dispatcher.commandSizeTable:
  2887.     DC    0                        ; RPC_TRANSMISSION_END
  2888.     DC    -1                        ; RPC_CLEAR_REGISTRY
  2889.     DC    -1                        ; RPC_REGISTER_OBJECT
  2890.     DC    1                        ; RPC_NEW_PRIMITIVEMESH
  2891.     DC    0                        ; RPC_SORT_PRIMITIVEMESH
  2892.     DC    0                        ; RPC_PAINT_PRIMITIVES
  2893.     DC    6                        ; RPC_GENERATE_ROTMATRIX
  2894.     DC    4                        ; RPC_GENERATE_QUATMATRIX
  2895.     DC    0                        ; RPC_PUSH_MATRIX
  2896.     DC    0                        ; RPC_POP_MATRIX
  2897.     DC    3                        ; RPC_TRANSLATE_MATRIX
  2898.     DC    1                        ; RPC_TRANSFORM_OBJECT
  2899.     DC    -1                        ; RPC_STORE_TEXTURE
  2900.     DC    -1                        ; RPC_SET_TEXTUREPIXEL
  2901.     DC    -1                        ; RPC_SET_OFFSETPIXEL
  2902.     DC    -1                        ; RPC_PAINT_POLYGON
  2903.     DC    -1                        ; RPC_UPDATE_VIEWPORT
  2904.     DC    0                        ; RPC_SET_V4ALPHA
  2905.     DC    0                        ; RPC_SET_V4BUMP
  2906.     DC    -1                        ; RPC_CLIPPAINT_POLYGON
  2907.     DC    -1                        ; RPC_REPLACE_OBJECT
  2908.  
  2909. ;======== Y-Memory Code ========
  2910.  
  2911.     ORG    Y:$0000
  2912.  
  2913. texturemask:
  2914.     DS    1                        ; v_frag mask
  2915. v_scale:DS    1
  2916. v0:    DS    1
  2917. v0_step:DS    1                        ; v_step storage
  2918. v1:    DS    1
  2919. v1_step:DS    1                        ; v_step storage
  2920. colormask:
  2921.     DC    $00ff00
  2922. Polygon.v4RoutineAddress:
  2923.     DS    1
  2924.  
  2925. next_texture:
  2926.     DC    Polygon.texture
  2927.  
  2928. SineZ:    DS    1
  2929. CosineZ:DS    1
  2930.  
  2931. ;======== PrimitiveMesh
  2932.  
  2933. PrimitiveMesh.primitive:
  2934.     DS    1
  2935.  
  2936. ;======== Matrix
  2937.  
  2938. Matrix.temp:
  2939.     DS    Matrix.SIZE
  2940. Matrix.stack:
  2941.     DS    Matrix.SIZE*Matrix.MAX_DEPTH            ; stack containing multi rotation
  2942.  
  2943. ;======== BoundingBox
  2944.  
  2945. BoundingBox.transformed:
  2946.     DS    8*3
  2947.  
  2948. ;======== EXTERNAL Y RAM
  2949.  
  2950.     ORG    Y:p_memory_end                    ; out of range from p-code
  2951.  
  2952. ;======== Polygon
  2953.  
  2954. Polygon.texture:
  2955.     DS    Polygon.TEXTUREBUFFER_SIZE            ; room for the interleaved textures
  2956. Polygon.LeftEdge:
  2957.     DS    5*Viewport.MAX_Y                ; (x,u0,v0,u1,v1)
  2958. Polygon.RightEdge:
  2959.     DS    5*Viewport.MAX_Y
  2960.  
  2961. ;======== PrimitiveMesh
  2962.  
  2963. InverseTable:
  2964.     DS    INVBUF_SIZE
  2965. PrimitiveMesh.vertexTable:
  2966.     DS    PrimitiveMesh.MAX_VERTICES*Vertex.SIZE        ; room for the transformed vertices
  2967. y_memory_end:
  2968. ; Y<$3BF2 !!
  2969.