home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quake_src / d_scanppc.s < prev    next >
Text File  |  2000-06-17  |  50KB  |  1,534 lines

  1. # Copyright (C) 1996-1997 Id Software, Inc. 
  2. # This program is free software; you can redistribute it and/or 
  3. # modify it under the terms of the GNU General Public License 
  4. # as published by the Free Software Foundation; either version 2 
  5. # of the License, or (at your option) any later version. 
  6. # This program is distributed in the hope that it will be useful, 
  7. # but WITHOUT ANY WARRANTY; without even the implied warranty of 
  8. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   
  9. # See the GNU General Public License for more details. 
  10. # You should have received a copy of the GNU General Public License 
  11. # along with this program; if not, write to the Free Software 
  12. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
  13.  
  14. ##
  15. ## Quake for AMIGA
  16. ##
  17. ## d_scanPPC.s
  18. ##
  19. ## Define WOS for PowerOpen ABI, otherwise SVR4-ABI is used.
  20. ##
  21.  
  22. .set NOLR,1
  23. .include        "macrosPPC.i"
  24.  
  25. .macro    rsreset
  26. .set    rscnt,0
  27. .endm
  28.  
  29. .macro    rs
  30. .set    \1,rscnt
  31. .set    rscnt,rscnt+\2
  32. .endm
  33.  
  34. #
  35. # external references
  36. #
  37.     xrefv    cacheblock
  38.     xrefv    d_sdivzorigin
  39.     xrefv    d_sdivzstepu
  40.     xrefv    d_sdivzstepv
  41.     xrefv    d_tdivzorigin
  42.     xrefv    d_tdivzstepu
  43.     xrefv    d_tdivzstepv
  44.     xrefv    d_ziorigin
  45.     xrefv    d_zistepu
  46.     xrefv    d_zistepv
  47.     xrefv    sadjust
  48.     xrefv    tadjust
  49.     xrefv    sdivz
  50.     xrefv    tdivz
  51.     xrefv    bbextents
  52.     xrefv    bbextentt
  53.     xrefv    d_viewbuffer
  54.     xrefv    screenwidth
  55.     xrefv    cachewidth
  56.     xrefv    d_zwidth
  57.     xrefv    d_pzbuffer
  58.     xrefv    sintable
  59.  
  60.     xrefa    d_subdiv16
  61.     xrefa    cl
  62.     xrefa    intsintable
  63.     xrefa    sintable
  64.     xrefa    vid
  65.     xrefa    scr_vrect
  66.     xrefa    r_refdef
  67.  
  68.     xrefv    INT2DBL_0
  69.     xrefv    c0
  70.     xrefv    c2
  71.     xrefv    c65536
  72.     xrefa    _ReciprocTable
  73.  
  74.  
  75. #
  76. # defines
  77. #
  78.  
  79. .set    QDIV,1
  80. .set    NICE_DIV,1
  81.  
  82. .set    PSPAN_NEXT,0xc
  83. .set    CL_TIME,0x23c
  84. .set    VID_BUFFER,0
  85. .set    VID_ROWBYTES,16
  86.  
  87. .set    SCR_VRECT_X,0
  88. .set    SCR_VRECT_Y,4
  89. .set    SCR_VRECT_WIDTH,8
  90. .set    SCR_VRECT_HEIGHT,12
  91.  
  92. .set    REFDEF_VRECT_X,0
  93. .set    REFDEF_VRECT_Y,4
  94. .set    REFDEF_VRECT_WIDTH,8
  95. .set    REFDEF_VRECT_HEIGHT,12
  96. .set    CVAR_VALUE,16
  97.  
  98. # MUST match the #define in d_iface.h!
  99. .set    CYCLE,128
  100. .set    AMP2,3
  101. .set    SPEED,20
  102.  
  103.  
  104.  
  105.  
  106.  
  107. ###########################################################################
  108. #
  109. #       void D_WarpScreen (void)
  110. #
  111. #       water effect algorithm
  112. #
  113. ###########################################################################
  114.  
  115.     funcdef    D_WarpScreen
  116.  
  117.     rsreset
  118.     rs    int2dbl_tmp1,8
  119.     rs    dbl2int_tmp1,8
  120.     rs    rowptr,1024*4
  121.     rs    column,1280*4
  122.  
  123.     init    0,rscnt+512,8,0
  124.     stmw    r24,gb(r1)
  125.     la    r4,local+rowptr(r1)        #r4 -> rowptr[1024]
  126.     la    r5,local+column(r1)        #r5 -> column[1280]
  127.     lf    f1,INT2DBL_0            #f1 = 0x4330000080000000
  128.     stfd    f1,local+int2dbl_tmp1(r1)    #int2dbl_tmp1 = 0x43300000...
  129.  
  130.     lxa    r6,vid                #r6 -> vid
  131.     lxa    r7,r_refdef            #r7 -> r_refdef
  132.     lxa    r8,scr_vrect            #r8 -> scr_vrect
  133.     lwz    r9,SCR_VRECT_WIDTH(r8)        #r9 = scr_vrect.width
  134.     lwz    r10,SCR_VRECT_HEIGHT(r8)    #r10 = scr_vrect.height
  135.     lwz    r11,REFDEF_VRECT_X(r7)        #r11 = r_refdef.vrect.x
  136.     lwz    r12,REFDEF_VRECT_Y(r7)        #r12 = r_refdef.vrect.y
  137.     lwz    r0,REFDEF_VRECT_WIDTH(r7)
  138.     int2dbl    f2,r0,r0,local+int2dbl_tmp1,f1    #f2 = (float)r_refdef.vrect.width
  139.     lwz    r0,REFDEF_VRECT_HEIGHT(r7)
  140.     int2dbl f3,r0,r0,local+int2dbl_tmp1,f1    #f3 = (float)r_refdef.vrect.height
  141.     lw      r31,screenwidth            #r31 = screenwidth
  142.     ls      f4,cAMP2times2            #f4 = AMP2*2
  143.  
  144. #        w = r_refdef.vrect.width;
  145. #        h = r_refdef.vrect.height;
  146. #
  147. #        wratio = w / (float)scr_vrect.width;
  148. #        hratio = h / (float)scr_vrect.height;
  149.  
  150.     fadds    f5,f2,f4                #f5 = w + AMP2*2
  151.     fadds    f6,f3,f4                #f6 = h + AMP2*2
  152.     int2dbl f0,r9,r0,local+int2dbl_tmp1,f1
  153.     fmuls    f5,f5,f0        #* (float)scr_vrect.width
  154.     int2dbl    f0,r10,r0,local+int2dbl_tmp1,f1
  155.     fmuls    f6,f6,f0        #* (float)scr_vrect.height
  156.     fmuls    f2,f2,f2        #w*w
  157.     fmuls    f3,f3,f3        #h*h
  158.     fdivs    f2,f2,f5        #f2 = wratio*w/(w+AMP2*2)
  159.     fdivs    f3,f3,f6        #f3 = hratio*h/(h+AMP2*2)
  160.     mullw    r12,r12,r31        #r12 = r_refdef.vrect.y*screenwidth
  161.     lw    r29,d_viewbuffer
  162.     add    r12,r12,r29        #r12 = d_viewbuffer + r12
  163.     lwz    r29,VID_ROWBYTES(r6)    #r29 = vid.rowbytes
  164.     addi    r27,r9,AMP2*2
  165.     addi    r28,r10,AMP2*2
  166.  
  167. #        for (v=0 ; v<scr_vrect.height+AMP2*2 ; v++)
  168. #        {
  169. #                rowptr[v] = d_viewbuffer + (r_refdef.vrect.y * screenwidth) +
  170. #                                 (screenwidth * (int)((float)v * hratio * h / (h + AMP2 * 2)));
  171. #        }
  172.  
  173.     li    r26,0            #v = 0
  174.     subi    r25,r4,4        #r25 -> rowptr[0] - 4
  175. .wsloop:
  176.     int2dbl    f7,r26,r0,local+int2dbl_tmp1,f1 #f7 = (float)v
  177.     fmuls    f7,f7,f3                #(float)v*hratio*h/(h+AMP2*2)
  178.     fctiwz    f0,f7
  179.     stfd    f0,local+dbl2int_tmp1(r1)
  180.     lwz    r24,local+dbl2int_tmp1+4(r1) #r24 = (int)f7
  181.     mullw    r24,r24,r31
  182.     add    r24,r24,r12
  183.     addi    r26,r26,1               #v++
  184.     stwu    r24,4(r25)              #rowptr[v] = r24
  185.     cmpw    r26,r28
  186.     blt    .wsloop
  187.  
  188. #        for (u=0 # u<scr_vrect.width+AMP2*2 ; u++)
  189. #        {
  190. #                column[u] = r_refdef.vrect.x +
  191. #                                (int)((float)u * wratio * w / (w + AMP2 * 2));
  192. #        }
  193.     li    r26,0                   #u = 0
  194.     subi    r25,r5,4                #r25 -> column[0]
  195. .wsloop2:
  196.     int2dbl    f7,r26,r0,local+int2dbl_tmp1,f1 #f7 = (float)u
  197.     fmuls    f7,f7,f2        #(float)u*wratio*w/(w+AMP2*2)
  198.     fctiwz    f0,f7
  199.     stfd    f0,local+dbl2int_tmp1(r1)
  200.     lwz    r24,local+dbl2int_tmp1+4(r1) #r24 = (int)f7
  201.     add    r24,r24,r11
  202.     addi    r26,r26,1        #u++
  203.     stwu    r24,4(r25)        #column[u] = r24
  204.     cmpw    r26,r27
  205.     blt    .wsloop2
  206.  
  207. #        turb = intsintable + ((int)(cl.time*SPEED)&(CYCLE-1));
  208. #        dest = vid.buffer + scr_vrect.y * vid.rowbytes + scr_vrect.x;
  209. #        for (v=0 ; v<scr_vrect.height ; v++, dest += vid.rowbytes)
  210. #        {
  211. #                col = &column[turb[v]];
  212. #                row = &rowptr[v];
  213. #                for (u=0 ; u<scr_vrect.width ; u+=4)
  214. #                {
  215. #                        dest[u+0] = row[turb[u+0]][col[u+0]];
  216. #                        dest[u+1] = row[turb[u+1]][col[u+1]];
  217. #                        dest[u+2] = row[turb[u+2]][col[u+2]];
  218. #                        dest[u+3] = row[turb[u+3]][col[u+3]];
  219. #                }
  220. #        }
  221.  
  222.     srawi    r9,r9,2
  223.     lxa    r28,cl
  224.     lfd    f7,CL_TIME(r28)
  225.     ls    f0,cSPEED
  226.     fmuls    f7,f7,f0
  227.     fctiwz    f0,f7
  228.     stfd    f0,local+dbl2int_tmp1(r1)
  229.     lwz    r27,local+dbl2int_tmp1+4(r1)
  230.     andi.    r27,r27,CYCLE-1
  231.     slwi    r27,r27,2
  232.     lxa    r26,intsintable
  233.     add    r27,r27,r26        #r27 = turb = sintable + ...
  234.  
  235.     lwz    r28,SCR_VRECT_Y(r8)
  236.     mullw    r28,r28,r29
  237.     lwz    r26,SCR_VRECT_X(r8)
  238.     add    r26,r26,r28
  239.     lwz    r28,VID_BUFFER(r6)
  240.     add    r26,r26,r28        #r26 = dest = vid.buffer + ...
  241.  
  242.     li    r6,0
  243. .wsloop3:
  244.     slwi    r0,r6,2
  245.     mtctr    r9
  246.     subi    r7,r27,4        #r7 -> turb[u] - 4
  247.     lwzx    r8,r27,r0        #r8 = turb[v]
  248.     subi    r11,r26,1        #r11 -> dest[u] - 1
  249.     slwi    r8,r8,2
  250.     add    r12,r5,r8        #r12 = col = &column[turb[v]]
  251.     subi    r12,r12,4
  252.     add    r31,r4,r0        #r31 = row = &rowptr[v]
  253. .wsloop4:
  254.     lwzu    r0,4(r7)        #r0 = turb[u+0]
  255.     slwi    r0,r0,2
  256.     lwzx    r30,r31,r0        #r30 = row[turb[u+0]]
  257.     lwzu    r0,4(r12)        #r0 = col[u+0]
  258.     lbzx    r0,r30,r0        #r0 = row[turb[u+0][col[u+0]]
  259.     stbu    r0,1(r11)        #dest[u+0] = r0
  260.     lwzu    r0,4(r7)        #r0 = turb[u+0]
  261.     slwi    r0,r0,2
  262.     lwzx    r30,r31,r0        #r30 = row[turb[u+0]]
  263.     lwzu    r0,4(r12)        #r0 = col[u+0]
  264.     lbzx    r0,r30,r0        #r0 = row[turb[u+0][col[u+0]]
  265.     stbu    r0,1(r11)        #dest[u+0] = r0
  266.     lwzu    r0,4(r7)        #r0 = turb[u+0]
  267.     slwi    r0,r0,2
  268.     lwzx    r30,r31,r0        #r30 = row[turb[u+0]]
  269.     lwzu    r0,4(r12)        #r0 = col[u+0]
  270.     lbzx    r0,r30,r0        #r0 = row[turb[u+0][col[u+0]]
  271.     stbu    r0,1(r11)        #dest[u+0] = r0
  272.     lwzu    r0,4(r7)        #r0 = turb[u+0]
  273.     slwi    r0,r0,2
  274.     lwzx    r30,r31,r0        #r30 = row[turb[u+0]]
  275.     lwzu    r0,4(r12)        #r0 = col[u+0]
  276.     lbzx    r0,r30,r0        #r0 = row[turb[u+0][col[u+0]]
  277.     stbu    r0,1(r11)        #dest[u+0] = r0
  278.     bdnz    .wsloop4
  279.     add    r26,r26,r29        #dest += vid.rowbytes
  280.     addi    r6,r6,1
  281.     cmpw    r6,r10
  282.     blt    .wsloop3
  283.  
  284.     lmw    r24,gb(r1)
  285.     exit
  286.  
  287.     funcend    D_WarpScreen
  288.  
  289.  
  290.  
  291.  
  292. ###########################################################################
  293. #
  294. #       void Turbulent8 (espan_t *pspan)
  295. #
  296. #       standard scan drawing function for animated textures
  297. #       Note: The function D_DrawTurbulent8Span was inlined into this
  298. #       function, because it's never used anywhere else.
  299. #
  300. ###########################################################################
  301.  
  302.     funcdef    Turbulent8
  303.  
  304.     init    0,16,7,16        # 16 local bytes for int2dbl/dbl2int
  305.     stmw    r25,gb(r1)
  306.     stfd    f14,fb+0*8(r1)
  307.     stfd    f15,fb+1*8(r1)
  308.     stfd    f16,fb+2*8(r1)
  309.     stfd    f17,fb+3*8(r1)
  310.     stfd    f18,fb+4*8(r1)
  311.     stfd    f19,fb+5*8(r1)
  312.     stfd    f20,fb+6*8(r1)
  313.     stfd    f21,fb+7*8(r1)
  314.     stfd    f22,fb+8*8(r1)
  315.     stfd    f23,fb+9*8(r1)
  316.     stfd    f24,fb+10*8(r1)
  317.     stfd    f25,fb+11*8(r1)
  318.     stfd    f26,fb+12*8(r1)
  319.     stfd    f27,fb+13*8(r1)
  320.     stfd    f28,fb+14*8(r1)
  321.     stfd    f29,fb+15*8(r1)
  322.  
  323.     lxa    r26,_ReciprocTable
  324.     lw      r27,cacheblock          #r27 = r_turb_pbase
  325.     lxa     r5,cl
  326.     lfd     f1,CL_TIME(r5)
  327.     ls      f2,cSPEED
  328.     fmuls   f1,f1,f2
  329.     fctiwz  f0,f1
  330.     stfd    f0,local+8(r1)
  331.     lwz     r4,local+12(r1)
  332.     andi.   r4,r4,CYCLE-1
  333.     slwi    r4,r4,2
  334.     lxa     r5,sintable
  335.     add     r4,r4,r5                #r4 = r_turb_turb = sintable + ...
  336.     ls      f1,d_sdivzstepu         #f1 = d_sdivzstepu
  337.     ls      f2,d_sdivzstepv         #f2 = d_sdivzstepv
  338.     ls      f3,d_sdivzorigin        #f3 = d_sdivzorigin
  339.     ls      f4,d_tdivzstepu         #f4 = d_tdivzstepu
  340.     ls      f5,d_tdivzstepv         #f5 = d_tdivzstepv
  341.     ls      f6,d_tdivzorigin        #f6 = d_tdivzorigin
  342.     ls      f7,d_zistepu            #f7 = d_zistepu
  343.     ls      f8,d_zistepv            #f8 = d_zistepv
  344.     ls      f9,d_ziorigin           #f9 = d_ziorigin
  345.     lf      f10,INT2DBL_0           #for int2dbl_setup
  346.     stfd    f10,local(r1)
  347.     lw      r6,sadjust
  348.     int2dbl f11,r6,r0,local,f10    #f11 = sadjust
  349.     lw      r6,tadjust
  350.     int2dbl f12,r6,r0,local,f10    #f12 = tadjust
  351.     lw      r6,bbextents
  352.     int2dbl f13,r6,r0,local,f10    #f13 = bbextents
  353.     lw      r6,bbextentt
  354.     int2dbl f14,r6,r0,local,f10    #f14 = bbextentt
  355.     lw      r6,d_viewbuffer         #r6 = d_viewbuffer
  356.     lw      r7,screenwidth          #r7 = screenwidth
  357.     ls      f15,c65536              #f15 = 65536
  358.     ls      f16,c16                    #f16 = 16
  359.     ls      f25,c0                  #f25 = 0
  360.     ls      f28,c2                  #f28 = 2
  361.     fmuls   f17,f1,f16              #f17 = sdivz16stepu
  362.     fmuls   f18,f4,f16              #f18 = tdivz16stepu
  363.     fmuls   f19,f7,f16              #f19 = zi16stepu
  364.     subi    r3,r3,4                 #prepare for postincrement
  365.  
  366. ######  First loop. In every iteration one complete span is drawn
  367.  
  368. #        pbase = (unsigned char *)cacheblock;
  369. #
  370. #        sdivz16stepu = d_sdivzstepu * 16;
  371. #        tdivz16stepu = d_tdivzstepu * 16;
  372. #        zi16stepu = d_zistepu * 16;
  373. #
  374. #        do
  375. #        {
  376. #                r_turb_pdest = (unsigned char *)((byte *)d_viewbuffer +
  377. #                                (screenwidth * pspan->v) + pspan->u);
  378. #
  379. #                count = pspan->count;
  380. #
  381. #        // calculate the initial s/z, t/z, 1/z, s, and t and clamp
  382. #                du = (float)pspan->u;
  383. #                dv = (float)pspan->v;
  384. #
  385. #                sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
  386. #                tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
  387. #                zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
  388. #                z = (float)0x10000 / zi;        // prescale to 16.16 fixed-point
  389. #
  390.  
  391. .t8loop:
  392.     lwzu    r8,4(r3)
  393.     int2dbl f20,r8,r0,local,f10    #f20 = du
  394.     lwzu    r9,4(r3)
  395.     int2dbl f21,r9,r0,local,f10    #f21 = dv
  396.     fmadds  f24,f21,f8,f9
  397.     fmadds  f22,f21,f2,f3
  398.     fmadds  f23,f21,f5,f6
  399.     fmadds  f26,f20,f7,f24          #f26 = zi
  400.     fmadds  f22,f20,f1,f22          #f22 = sdivz
  401.     fmadds  f23,f20,f4,f23          #f23 = tdivz
  402.     fmuls   f0,f26,f26
  403.     frsqrte f0,f0
  404.     mullw   r10,r9,r7               #r10 = pspan->v * screenwidth
  405.     fnmsubs f29,f0,f26,f28
  406.     add     r10,r10,r8              #r10 = r10 + pspan->u
  407.     fmuls   f0,f0,f29
  408.     add     r11,r6,r10              #r11 = pdest
  409.     fnmsubs f29,f0,f26,f28
  410.     subi    r11,r11,1               #prepare for postincrement
  411.     fmuls   f0,f0,f29
  412.     lwzu    r12,4(r3)               #r12 = count
  413.     fmuls   f24,f0,f15
  414.     fmadds  f20,f22,f24,f11         #f20 = s
  415.     fsubs   f0,f20,f13
  416.     fsel    f20,f0,f13,f20          #if (s>bb...) s = bbextents
  417.     fsel    f20,f20,f20,f25         #if (s<0) s = 0
  418.     fctiwz  f0,f20
  419.     stfd    f0,local+8(r1)
  420.     lwz     r8,local+12(r1)         #r8 = (int)s
  421.     fmadds  f21,f23,f24,f12         #f21 = t
  422.     fsubs   f0,f21,f14
  423.     fsel    f21,f0,f14,f21          #if (t>bb...) t = bbextentt
  424.     fsel    f21,f21,f21,f25         #if (t<0) t = 0
  425.     fctiwz  f0,f21
  426.     stfd    f0,local+8(r1)
  427.     lwz     r9,local+12(r1)         #r9 = (int)t
  428.  
  429.  
  430. ######  Second loop. In every iteration one part of the whole span is drawn
  431.  
  432. #                do
  433. #                {
  434. #                // calculate s and t at the far end of the span
  435. #                        if (count >= 16)
  436. #                                r_turb_spancount = 16;
  437. #                        else
  438. #                                r_turb_spancount = count;
  439. #
  440. #                        count -= r_turb_spancount;
  441. #
  442. #                        if (count)
  443. #                        {
  444.  
  445. .t8loop2:
  446.     cmpwi   r12,16
  447.     bgt     .t8cont
  448.     mtctr   r12
  449.     subi    r10,r12,1
  450.     int2dbl f21,r10,r0,local,f10    #spancountminus1 = (float)...
  451.     li      r12,0                   #r12 = count -= spancount
  452.     fmadds  f26,f21,f7,f26          #zi += d_zistepu * ...
  453.     b       .t8finalpart
  454. .t8cont:
  455.     fadds   f26,f26,f19             #zi += zi16stepu
  456.     li      r10,16                  #r10 = spancount = 16
  457.     fmuls   f0,f26,f26
  458.     subf    r12,r10,r12             #r12 = count -= spancount
  459.     frsqrte f0,f0
  460.     mtctr   r10
  461.  
  462. ######  Evaluation of the values for the inner loop. This version is used for
  463. ######  span size = 16
  464.  
  465. #                        // calculate s/z, t/z, zi->fixed s and t at far end of span,
  466. #                        // calculate s and t steps across span by shifting
  467. #                                sdivz += sdivz16stepu;
  468. #                                tdivz += tdivz16stepu;
  469. #                                zi += zi16stepu;
  470. #                                z = (float)0x10000 / zi;        // prescale to 16.16 fixed-point
  471. #                                snext = (int)(sdivz * z) + sadjust;
  472. #                                if (snext > bbextents)
  473. #                                        snext = bbextents;
  474. #                                else if (snext < 16)
  475. #                                        snext = 16;      // prevent round-off error on <0 steps from
  476. #                                                                //  from causing overstepping & running off the
  477. #                                                                //  edge of the texture
  478. #                                tnext = (int)(tdivz * z) + tadjust;
  479. #                                if (tnext > bbextentt)
  480. #                                        tnext = bbextentt;
  481. #                                else if (tnext < 16)
  482. #                                        tnext = 16;      // guard against round-off error on <0 steps
  483. #                                r_turb_sstep = (snext - r_turb_s) >> 4;
  484. #                                r_turb_tstep = (tnext - r_turb_t) >> 4;
  485. #                        }
  486.  
  487.     fnmsubs f20,f0,f26,f28
  488.     fadds   f22,f22,f17             #sdivz += sdivz16stepu
  489.     fmuls   f0,f0,f20
  490.     fadds   f23,f23,f18             #tdivz += tdivz16stepu
  491.     fnmsubs f20,f0,f26,f28
  492.     fmuls   f0,f0,f20
  493.     fmuls   f24,f0,f15
  494.     fmadds  f20,f22,f24,f11         #f20 = snext
  495.     fsubs   f0,f20,f13
  496.     fsel    f20,f0,f13,f20          #if (snext>bb...) snext = bbextents
  497.     fsubs   f0,f20,f16
  498.     fsel    f20,f0,f20,f16          #if (snext<16) snext = 16
  499.     fctiwz  f0,f20
  500.     stfd    f0,local+8(r1)
  501.     lwz     r31,local+12(r1)        #r31 = (int)snext
  502.     fmadds  f21,f23,f24,f12         #f21 = tnext
  503.     fsubs   f0,f21,f14
  504.     fsel    f21,f0,f14,f21          #if (tnext>bb...) tnext = bbextentt
  505.     subf    r29,r8,r31
  506.     fsubs   f0,f21,f16
  507.     srawi   r29,r29,4               #r29 = sstep = (snext - s) >> 4
  508.     fsel    f21,f0,f21,f16          #if (tnext<16) tnext = 16
  509.     fctiwz  f0,f21
  510.     stfd    f0,local+8(r1)
  511.     lwz     r30,local+12(r1)        #r30 = (int)tnext
  512.     subf    r28,r9,r30
  513.     srawi   r28,r28,4               #r28 = tstep = (tnext - t) >> 4
  514.     b       .t8mainloop
  515.  
  516. ######  Evaluation of the values for the inner loop. This version is used for
  517. ######  span size < 16
  518.  
  519. ######  The original algorithm has two ugly divisions at the end of this part.
  520. ######  These are removed by the following optimization:
  521. ######  First, the divisors 1,2 and 4 are handled specially to gain speed. The
  522. ######  other divisors are handled using a reciprocal table.
  523.  
  524. #                        // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
  525. #                        // can't step off polygon), clamp, calculate s and t steps across
  526. #                        // span by division, biasing steps low so we don't run off the
  527. #                        // texture
  528. #                                spancountminus1 = (float)(r_turb_spancount - 1);
  529. #                                sdivz += d_sdivzstepu * spancountminus1;
  530. #                                tdivz += d_tdivzstepu * spancountminus1;
  531. #                                zi += d_zistepu * spancountminus1;
  532. #                                z = (float)0x10000 / zi;        // prescale to 16.16 fixed-point
  533. #                                snext = (int)(sdivz * z) + sadjust;
  534. #                                if (snext > bbextents)
  535. #                                        snext = bbextents;
  536. #                                else if (snext < 16)
  537. #                                        snext = 16;      // prevent round-off error on <0 steps from
  538. #                                                                //  from causing overstepping & running off the
  539. #                                                                //  edge of the texture
  540. #
  541. #                                tnext = (int)(tdivz * z) + tadjust;
  542. #                                if (tnext > bbextentt)
  543. #                                        tnext = bbextentt;
  544. #                                else if (tnext < 16)
  545. #                                        tnext = 16;      // guard against round-off error on <0 steps
  546. #
  547. #                                if (r_turb_spancount > 1)
  548. #                                {
  549. #                                        r_turb_sstep = (snext - r_turb_s) / (spancount - 1);
  550. #                                        r_turb_tstep = (tnext - r_turb_t) / (spancount - 1);
  551. #                                }
  552. #                        }
  553.  
  554. .t8finalpart:
  555.     fmuls   f0,f26,f26
  556.     fmadds  f22,f21,f1,f22          #sdivz += d_sdivzstepu * ...
  557.     frsqrte f0,f0
  558.     fmadds  f23,f21,f4,f23          #tdivs += d_tdivzstepu * ...
  559.     fnmsubs f20,f0,f26,f28
  560.     cmplwi  r10,5
  561.     fmuls   f0,f0,f20
  562.     fnmsubs f20,f0,f26,f28
  563.     fmuls   f0,f0,f20
  564.     fmuls   f24,f0,f15
  565.     fmadds  f20,f22,f24,f11         #f27 = snext
  566.     fsubs   f0,f20,f13
  567.     fsel    f20,f0,f13,f20          #if (snext>bb...) snext = bbextents
  568.     fsubs   f0,f20,f16
  569.     fsel    f20,f0,f20,f16          #if (snext<16) snext = 16
  570.     fctiwz  f0,f20
  571.     stfd    f0,local+8(r1)
  572.     lwz     r31,local+12(r1)        #r31 = (int)snext
  573.     fmadds  f21,f23,f24,f12         #f21 = tnext
  574.     fsubs   f0,f21,f14
  575.     fsel    f21,f0,f14,f21          #if (tnext>bb...) tnext = bbextentt
  576.     subf    r29,r8,r31
  577.     fsubs   f0,f21,f16
  578.     fsel    f21,f0,f21,f16          #if (tnext<16) tnext = 16
  579.     fctiwz  f0,f21
  580.     stfd    f0,local+8(r1)
  581.     lwz     r30,local+12(r1)        #r30 = (int)tnext
  582.     subf    r28,r9,r30
  583.     blt     .t8special
  584. .t8qdiv:
  585.     slwi    r0,r10,2
  586.     lwzx    r0,r26,r0
  587.     mulhw   r29,r29,r0
  588.     mulhw   r28,r28,r0
  589.     b       .t8mainloop
  590. .t8special:
  591.     cmplwi  r10,1
  592.     ble     .t8mainloop
  593.     cmplwi  r10,3
  594.     beq     .t8qdiv
  595.     blt     .t8spec_2
  596.     srawi   r29,r29,2
  597.     srawi   r28,r28,2
  598.     b       .t8mainloop
  599. .t8spec_2:
  600.     srawi   r29,r29,1
  601.     srawi   r28,r28,1
  602.  
  603. ######  D_DrawTurbulent8Span (inlined)
  604. ######  Main drawing loop.
  605.  
  606. #        do
  607. #        {
  608. #                sturb = ((r_turb_s + r_turb_turb[(r_turb_t>>16)&(CYCLE-1)])>>16)&63;
  609. #                tturb = ((r_turb_t + r_turb_turb[(r_turb_s>>16)&(CYCLE-1)])>>16)&63;
  610. #                *r_turb_pdest++ = *(r_turb_pbase + (tturb<<6) + sturb);
  611. #                r_turb_s += r_turb_sstep;
  612. #                r_turb_t += r_turb_tstep;
  613. #        } while (--r_turb_spancount > 0);
  614.  
  615.  
  616. .t8mainloop:
  617.     andis.  r8,r8,CYCLE-1
  618.     andis.  r9,r9,CYCLE-1
  619. .t8draw:
  620.     rlwinm  r0,r9,18,23,29        #implicit: CYCLE = 128
  621.     rlwinm  r25,r8,18,23,29        #implicit: CYCLE = 128
  622.     lwzx    r10,r4,r0
  623.     add     r10,r10,r8
  624.     lwzx    r25,r4,r25
  625.     add     r8,r8,r29
  626.     add     r25,r25,r9
  627.     extrwi  r10,r10,6,10
  628.     rlwinm  r25,r25,22,20,25
  629.     add     r10,r10,r25
  630.     add     r9,r9,r28
  631.     lbzx    r0,r27,r10
  632.     stbu    r0,1(r11)
  633.     bdnz    .t8draw
  634.  
  635.     mr      r8,r31
  636.     mr      r9,r30
  637.     mr.    r12,r12
  638.     bgt     .t8loop2
  639.     lwz     r3,4(r3)                #while (...)
  640.     mr.    r3,r3
  641.     subi    r3,r3,4
  642.     bne     .t8loop
  643.  
  644.     lmw    r25,gb(r1)
  645.     lfd    f14,fb+0*8(r1)
  646.     lfd    f15,fb+1*8(r1)
  647.     lfd    f16,fb+2*8(r1)
  648.     lfd    f17,fb+3*8(r1)
  649.     lfd    f18,fb+4*8(r1)
  650.     lfd    f19,fb+5*8(r1)
  651.     lfd    f20,fb+6*8(r1)
  652.     lfd    f21,fb+7*8(r1)
  653.     lfd    f22,fb+8*8(r1)
  654.     lfd    f23,fb+9*8(r1)
  655.     lfd    f24,fb+10*8(r1)
  656.     lfd    f25,fb+11*8(r1)
  657.     lfd    f26,fb+12*8(r1)
  658.     lfd    f27,fb+13*8(r1)
  659.     lfd    f28,fb+14*8(r1)
  660.     lfd    f29,fb+15*8(r1)
  661.     exit
  662.  
  663.     funcend    Turbulent8
  664.  
  665.  
  666.  
  667.  
  668. ###########################################################################
  669. #
  670. #       void D_DrawSpans8 (espan_t *pspan)
  671. #
  672. #       standard scan drawing function (8 pixel subdivision)
  673. #
  674. ###########################################################################
  675.  
  676.     funcdef    D_DrawSpans8
  677.  
  678.     lxa     r4,d_subdiv16        # subdiv16? then call DrawSpans16!
  679.     lfs     f0,CVAR_VALUE(r4)
  680.     ls      f1,c0
  681.     fcmpo   0,f0,f1
  682. .ifdef    WOS
  683.     bne     _D_DrawSpans16
  684. .else
  685.     bne    D_DrawSpans16
  686. .endif
  687.  
  688.     init    0,16,6,16        # 16 local bytes for int2dbl/dbl2int
  689.     stmw    r26,gb(r1)
  690.     stfd    f14,fb+0*8(r1)
  691.     stfd    f15,fb+1*8(r1)
  692.     stfd    f16,fb+2*8(r1)
  693.     stfd    f17,fb+3*8(r1)
  694.     stfd    f18,fb+4*8(r1)
  695.     stfd    f19,fb+5*8(r1)
  696.     stfd    f20,fb+6*8(r1)
  697.     stfd    f21,fb+7*8(r1)
  698.     stfd    f22,fb+8*8(r1)
  699.     stfd    f23,fb+9*8(r1)
  700.     stfd    f24,fb+10*8(r1)
  701.     stfd    f25,fb+11*8(r1)
  702.     stfd    f26,fb+12*8(r1)
  703.     stfd    f27,fb+13*8(r1)
  704.     stfd    f28,fb+14*8(r1)
  705.     stfd    f29,fb+15*8(r1)
  706.  
  707.     lxa     r26,_ReciprocTable
  708.     lw      r27,cacheblock          #r27 = pbase
  709.     lw      r4,cachewidth           #r4 = cachewidth
  710.     ls      f1,d_sdivzstepu         #f1 = d_sdivzstepu
  711.     ls      f2,d_sdivzstepv         #f2 = d_sdivzstepv
  712.     ls      f3,d_sdivzorigin        #f3 = d_sdivzorigin
  713.     ls      f4,d_tdivzstepu         #f4 = d_tdivzstepu
  714.     ls      f5,d_tdivzstepv         #f5 = d_tdivzstepv
  715.     ls      f6,d_tdivzorigin        #f6 = d_tdivzorigin
  716.     ls      f7,d_zistepu            #f7 = d_zistepu
  717.     ls      f8,d_zistepv            #f8 = d_zistepv
  718.     ls      f9,d_ziorigin           #f9 = d_ziorigin
  719.     lf      f10,INT2DBL_0           #for int2dbl_setup
  720.     stfd    f10,local(r1)
  721.     lw      r6,sadjust
  722.     int2dbl f11,r6,r0,local,f10    #f11 = sadjust
  723.     lw      r6,tadjust
  724.     int2dbl f12,r6,r0,local,f10    #f12 = tadjust
  725.     lw      r6,bbextents
  726.     int2dbl f13,r6,r0,local,f10    #f13 = bbextents
  727.     lw      r6,bbextentt
  728.     int2dbl f14,r6,r0,local,f10    #f14 = bbextentt
  729.     lw      r6,d_viewbuffer         #r6 = d_viewbuffer
  730.     lw      r7,screenwidth          #r7 = screenwidth
  731.     ls      f15,c65536              #f15 = 65536
  732.     ls      f16,c8            #f16 = 8
  733.     ls      f25,c0                  #f25 = 0
  734.     ls      f28,c2                  #f28 = 2
  735.     fmuls   f17,f1,f16              #f17 = sdivz8stepu
  736.     fmuls   f18,f4,f16              #f18 = tdivz8stepu
  737.     fmuls   f19,f7,f16              #f19 = zi8stepu
  738.     subi    r3,r3,4                 #prepare for postincrement
  739.  
  740. ######  First loop. In every iteration one complete span is drawn
  741.  
  742. #        pbase = (unsigned char *)cacheblock;
  743. #
  744. #        sdivz8stepu = d_sdivzstepu * 8;
  745. #        tdivz8stepu = d_tdivzstepu * 8;
  746. #        zi8stepu = d_zistepu * 8;
  747. #
  748. #        do
  749. #        {
  750. #                pdest = (unsigned char *)((byte *)d_viewbuffer +
  751. #                                (screenwidth * pspan->v) + pspan->u);
  752. #
  753. #                count = pspan->count;
  754. #
  755. #        // calculate the initial s/z, t/z, 1/z, s, and t and clamp
  756. #                du = (float)pspan->u;
  757. #                dv = (float)pspan->v;
  758. #
  759. #                sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
  760. #                tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
  761. #                zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
  762. #                z = (float)0x10000 / zi;        // prescale to 16.16 fixed-point
  763. #
  764.  
  765. .d8loop:
  766.     lwzu    r8,4(r3)
  767.     int2dbl f20,r8,r0,local,f10    #f20 = du
  768.     lwzu    r9,4(r3)
  769.     int2dbl f21,r9,r0,local,f10    #f21 = dv
  770.     fmadds  f24,f21,f8,f9
  771.     fmadds  f22,f21,f2,f3
  772.     fmadds  f23,f21,f5,f6
  773.     fmadds  f26,f20,f7,f24          #f26 = zi
  774.     fmadds  f22,f20,f1,f22          #f22 = sdivz
  775.     fmadds  f23,f20,f4,f23          #f23 = tdivz
  776.     fmuls   f0,f26,f26
  777.     frsqrte f0,f0
  778.     mullw   r10,r9,r7               #r10 = pspan->v * screenwidth
  779.     fnmsubs f29,f0,f26,f28
  780.     add     r10,r10,r8              #r10 = r10 + pspan->u
  781.     fmuls   f0,f0,f29
  782.     add     r11,r6,r10              #r11 = pdest
  783.     fnmsubs f29,f0,f26,f28
  784.     subi    r11,r11,1               #prepare for postincrement
  785.     fmuls   f0,f0,f29
  786.     lwzu    r12,4(r3)               #r12 = count
  787.     fmuls   f24,f0,f15
  788.     fmadds  f20,f22,f24,f11         #f20 = s
  789.     fsubs   f0,f20,f13
  790.     fsel    f20,f0,f13,f20          #if (s>bb...) s = bbextents
  791.     fsel    f20,f20,f20,f25         #if (s<0) s = 0
  792.     fctiwz  f0,f20
  793.     stfd    f0,local+8(r1)
  794.     lwz     r8,local+12(r1)         #r8 = (int)s
  795.     fmadds  f21,f23,f24,f12         #f21 = t
  796.     fsubs   f0,f21,f14
  797.     fsel    f21,f0,f14,f21          #if (t>bb...) t = bbextentt
  798.     fsel    f21,f21,f21,f25         #if (t<0) t = 0
  799.     fctiwz  f0,f21
  800.     stfd    f0,local+8(r1)
  801.     lwz     r9,local+12(r1)         #r9 = (int)t
  802.     li      r0,1
  803.     dcbtst  r11,r0
  804.  
  805.  
  806. ######  Second loop. In every iteration one part of the whole span is drawn
  807.  
  808. #                do
  809. #                {
  810. #                // calculate s and t at the far end of the span
  811. #                        if (count >= 8)
  812. #                                spancount = 8;
  813. #                        else
  814. #                                spancount = count;
  815. #
  816. #                        count -= spancount;
  817. #
  818. #                        if (count)
  819. #                        {
  820.  
  821. .d8loop2:
  822.     cmpwi   r12,8
  823.     bgt     .d8cont
  824.     mtctr   r12
  825.     subi    r10,r12,1
  826.     int2dbl f21,r10,r0,local,f10    #spancountminus1 = (float)...
  827.     li      r12,0                   #r12 = count -= spancount
  828.     fmadds  f26,f21,f7,f26          #zi += d_zistepu # ...
  829.     b       .d8finalpart
  830. .d8cont:
  831.     fadds   f26,f26,f19             #zi += zi8stepu
  832.     li      r10,8                   #r10 = spancount = 8
  833.     fmuls   f0,f26,f26
  834.     subf    r12,r10,r12             #r12 = count -= spancount
  835.     frsqrte f0,f0
  836.     mtctr   r10
  837.  
  838. ######  Evaluation of the values for the inner loop. This version is used for
  839. ######  span size = 8
  840.  
  841. #                        // calculate s/z, t/z, zi->fixed s and t at far end of span,
  842. #                        // calculate s and t steps across span by shifting
  843. #                                sdivz += sdivz8stepu;
  844. #                                tdivz += tdivz8stepu;
  845. #                                zi += zi8stepu;
  846. #                                z = (float)0x10000 / zi;        // prescale to 16.16 fixed-point
  847. #                                snext = (int)(sdivz * z) + sadjust;
  848. #                                if (snext > bbextents)
  849. #                                        snext = bbextents;
  850. #                                else if (snext < 8)
  851. #                                        snext = 8;      // prevent round-off error on <0 steps from
  852. #                                                                //  from causing overstepping & running off the
  853. #                                                                //  edge of the texture
  854. #                                tnext = (int)(tdivz * z) + tadjust;
  855. #                                if (tnext > bbextentt)
  856. #                                        tnext = bbextentt;
  857. #                                else if (tnext < 8)
  858. #                                        tnext = 8;      // guard against round-off error on <0 steps
  859. #                                sstep = (snext - s) >> 3;
  860. #                                tstep = (tnext - t) >> 3;
  861. #                        }
  862.  
  863.     fnmsubs f20,f0,f26,f28
  864.     fadds   f22,f22,f17             #sdivz += sdivz8stepu
  865.     fmuls   f0,f0,f20
  866.     fadds   f23,f23,f18             #tdivz += tdivz8stepu
  867.     fnmsubs f20,f0,f26,f28
  868.     fmuls   f0,f0,f20
  869.     fmuls   f24,f0,f15
  870.     fmadds  f20,f22,f24,f11         #f20 = snext
  871.     fsubs   f0,f20,f13
  872.     fsel    f20,f0,f13,f20          #if (snext>bb...) snext = bbextents
  873.     fsubs   f0,f20,f16
  874.     fsel    f20,f0,f20,f16          #if (snext<8) snext = 8
  875.     fctiwz  f0,f20
  876.     stfd    f0,local+8(r1)
  877.     lwz     r31,local+12(r1)        #r31 = (int)snext
  878.     fmadds  f21,f23,f24,f12         #f21 = tnext
  879.     fsubs   f0,f21,f14
  880.     fsel    f21,f0,f14,f21          #if (tnext>bb...) tnext = bbextentt
  881.     subf    r29,r8,r31
  882.     fsubs   f0,f21,f16
  883.     srawi   r29,r29,3               #r29 = sstep = (snext - s) >> 3
  884.     fsel    f21,f0,f21,f16          #if (tnext<8) tnext = 8
  885.     fctiwz  f0,f21
  886.     stfd    f0,local+8(r1)
  887.     lwz     r30,local+12(r1)        #r30 = (int)tnext
  888.     subf    r28,r9,r30
  889.     srawi   r28,r28,3               #r28 = tstep = (tnext - t) >> 3
  890.     b       .d8mainloop
  891.  
  892. ######  Evaluation of the values for the inner loop. This version is used for
  893. ######  span size < 8
  894.  
  895. ######  The original algorithm has two ugly divisions at the end of this part.
  896. ######  These are removed by the following optimization:
  897. ######  First, the divisors 1,2 and 4 are handled specially to gain speed. The
  898. ######  other divisors are handled using a reciprocal table.
  899.  
  900. #                        // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
  901. #                        // can't step off polygon), clamp, calculate s and t steps across
  902. #                        // span by division, biasing steps low so we don't run off the
  903. #                        // texture
  904. #                                spancountminus1 = (float)(spancount - 1);
  905. #                                sdivz += d_sdivzstepu * spancountminus1;
  906. #                                tdivz += d_tdivzstepu * spancountminus1;
  907. #                                zi += d_zistepu * spancountminus1;
  908. #                                z = (float)0x10000 / zi;        // prescale to 16.16 fixed-point
  909. #                                snext = (int)(sdivz * z) + sadjust;
  910. #                                if (snext > bbextents)
  911. #                                        snext = bbextents;
  912. #                                else if (snext < 8)
  913. #                                        snext = 8;      // prevent round-off error on <0 steps from
  914. #                                                                //  from causing overstepping & running off the
  915. #                                                                //  edge of the texture
  916. #
  917. #                                tnext = (int)(tdivz * z) + tadjust;
  918. #                                if (tnext > bbextentt)
  919. #                                        tnext = bbextentt;
  920. #                                else if (tnext < 8)
  921. #                                        tnext = 8;      // guard against round-off error on <0 steps
  922. #
  923. #                                if (spancount > 1)
  924. #                                {
  925. #                                        sstep = (snext - s) / (spancount - 1);
  926. #                                        tstep = (tnext - t) / (spancount - 1);
  927. #                                }
  928. #                        }
  929.  
  930. .d8finalpart:
  931.     fmuls   f0,f26,f26
  932.     fmadds  f22,f21,f1,f22          #sdivz += d_sdivzstepu * ...
  933.     frsqrte f0,f0
  934.     fmadds  f23,f21,f4,f23          #tdivs += d_tdivzstepu * ...
  935.     fnmsubs f20,f0,f26,f28
  936.     cmplwi  r10,5
  937.     fmuls   f0,f0,f20
  938.     fnmsubs f20,f0,f26,f28
  939.     fmuls   f0,f0,f20
  940.     fmuls   f24,f0,f15
  941.     fmadds  f20,f22,f24,f11         #f27 = snext
  942.     fsubs   f0,f20,f13
  943.     fsel    f20,f0,f13,f20          #if (snext>bb...) snext = bbextents
  944.     fsubs   f0,f20,f16
  945.     fsel    f20,f0,f20,f16          #if (snext<8) snext = 8
  946.     fctiwz  f0,f20
  947.     stfd    f0,local+8(r1)
  948.     lwz     r31,local+12(r1)        #r31 = (int)snext
  949.     fmadds  f21,f23,f24,f12         #f21 = tnext
  950.     fsubs   f0,f21,f14
  951.     fsel    f21,f0,f14,f21          #if (tnext>bb...) tnext = bbextentt
  952.     subf    r29,r8,r31
  953.     fsubs   f0,f21,f16
  954.     fsel    f21,f0,f21,f16          #if (tnext<8) tnext = 8
  955.     fctiwz  f0,f21
  956.     stfd    f0,local+8(r1)
  957.     lwz     r30,local+12(r1)        #r30 = (int)tnext
  958.     subf    r28,r9,r30
  959.     blt     .d8special
  960. .d8qdiv:
  961.     slwi    r0,r10,2
  962.     lwzx    r0,r26,r0
  963.     mulhw   r29,r29,r0
  964.     mulhw   r28,r28,r0
  965.     b       .d8mainloop
  966. .d8special:
  967.     cmplwi  r10,1
  968.     ble     .d8mainloop
  969.     cmplwi  r10,3
  970.     beq     .d8qdiv
  971.     blt     .d8spec_2
  972.     srawi   r29,r29,2
  973.     srawi   r28,r28,2
  974.     b       .d8mainloop
  975. .d8spec_2:
  976.     srawi   r29,r29,1
  977.     srawi   r28,r28,1
  978.  
  979. ######  Main drawing loop. Here lies the speed.
  980.  
  981. #                        do
  982. #                        {
  983. #                                *pdest++ = *(pbase + (s >> 16) + (t >> 16) * cachewidth);
  984. #                                s += sstep;
  985. #                                t += tstep;
  986. #                        } while (--spancount > 0);
  987.  
  988. .d8mainloop:
  989.     srawi   r0,r9,16
  990.     srawi   r10,r8,16
  991.     mullw   r0,r0,r4
  992.     add     r9,r9,r28
  993.     add     r0,r0,r10
  994.     add     r8,r8,r29
  995.     lbzx    r0,r27,r0
  996.     stbu    r0,1(r11)
  997.     bdnz    .d8mainloop
  998.     mr      r8,r31
  999.     mr      r9,r30
  1000.     mr.    r12,r12
  1001.     bgt     .d8loop2
  1002.     lwz     r3,4(r3)                #while (...)
  1003.     mr.    r3,r3
  1004.     subi    r3,r3,4
  1005.     bne     .d8loop
  1006.  
  1007.     lmw    r26,gb(r1)
  1008.     lfd    f14,fb+0*8(r1)
  1009.     lfd    f15,fb+1*8(r1)
  1010.     lfd    f16,fb+2*8(r1)
  1011.     lfd    f17,fb+3*8(r1)
  1012.     lfd    f18,fb+4*8(r1)
  1013.     lfd    f19,fb+5*8(r1)
  1014.     lfd    f20,fb+6*8(r1)
  1015.     lfd    f21,fb+7*8(r1)
  1016.     lfd    f22,fb+8*8(r1)
  1017.     lfd    f23,fb+9*8(r1)
  1018.     lfd    f24,fb+10*8(r1)
  1019.     lfd    f25,fb+11*8(r1)
  1020.     lfd    f26,fb+12*8(r1)
  1021.     lfd    f27,fb+13*8(r1)
  1022.     lfd    f28,fb+14*8(r1)
  1023.     lfd    f29,fb+15*8(r1)
  1024.     exit
  1025.  
  1026.     funcend    D_DrawSpans8
  1027.  
  1028.  
  1029.  
  1030.  
  1031. ###########################################################################
  1032. #
  1033. #       void D_DrawSpans16 (espan_t *pspan)
  1034. #
  1035. #       standard scan drawing function (16 pixel subdivision)
  1036. #
  1037. ###########################################################################
  1038.  
  1039.     funcdef    D_DrawSpans16
  1040.  
  1041.     init    0,16,6,16        # 16 local bytes for int2dbl/dbl2int
  1042.     stmw    r26,gb(r1)
  1043.     stfd    f14,fb+0*8(r1)
  1044.     stfd    f15,fb+1*8(r1)
  1045.     stfd    f16,fb+2*8(r1)
  1046.     stfd    f17,fb+3*8(r1)
  1047.     stfd    f18,fb+4*8(r1)
  1048.     stfd    f19,fb+5*8(r1)
  1049.     stfd    f20,fb+6*8(r1)
  1050.     stfd    f21,fb+7*8(r1)
  1051.     stfd    f22,fb+8*8(r1)
  1052.     stfd    f23,fb+9*8(r1)
  1053.     stfd    f24,fb+10*8(r1)
  1054.     stfd    f25,fb+11*8(r1)
  1055.     stfd    f26,fb+12*8(r1)
  1056.     stfd    f27,fb+13*8(r1)
  1057.     stfd    f28,fb+14*8(r1)
  1058.     stfd    f29,fb+15*8(r1)
  1059.  
  1060.     lxa     r26,_ReciprocTable
  1061.     lw      r27,cacheblock          #r27 = pbase
  1062.     lw      r4,cachewidth           #r4 = cachewidth
  1063.     ls      f1,d_sdivzstepu         #f1 = d_sdivzstepu
  1064.     ls      f2,d_sdivzstepv         #f2 = d_sdivzstepv
  1065.     ls      f3,d_sdivzorigin        #f3 = d_sdivzorigin
  1066.     ls      f4,d_tdivzstepu         #f4 = d_tdivzstepu
  1067.     ls      f5,d_tdivzstepv         #f5 = d_tdivzstepv
  1068.     ls      f6,d_tdivzorigin        #f6 = d_tdivzorigin
  1069.     ls      f7,d_zistepu            #f7 = d_zistepu
  1070.     ls      f8,d_zistepv            #f8 = d_zistepv
  1071.     ls      f9,d_ziorigin           #f9 = d_ziorigin
  1072.     lf      f10,INT2DBL_0           #for int2dbl_setup
  1073.     stfd    f10,local(r1)
  1074.     lw      r6,sadjust
  1075.     int2dbl f11,r6,r0,local,f10    #f11 = sadjust
  1076.     lw      r6,tadjust
  1077.     int2dbl f12,r6,r0,local,f10    #f12 = tadjust
  1078.     lw      r6,bbextents
  1079.     int2dbl f13,r6,r0,local,f10    #f13 = bbextents
  1080.     lw      r6,bbextentt
  1081.     int2dbl f14,r6,r0,local,f10    #f14 = bbextentt
  1082.     lw      r6,d_viewbuffer         #r6 = d_viewbuffer
  1083.     lw      r7,screenwidth          #r7 = screenwidth
  1084.     ls      f15,c65536              #f15 = 65536
  1085.     ls      f16,c16                 #f16 = 16
  1086.     ls      f25,c0                  #f25 = 0
  1087.     ls      f28,c2                  #f28 = 2
  1088.     fmuls   f17,f1,f16              #f17 = sdivz16stepu
  1089.     fmuls   f18,f4,f16              #f18 = tdivz16stepu
  1090.     fmuls   f19,f7,f16              #f19 = zi16stepu
  1091.     subi    r3,r3,4                 #prepare for postincrement
  1092.  
  1093. ######  First loop. In every iteration one complete span is drawn
  1094.  
  1095. #        pbase = (unsigned char *)cacheblock;
  1096. #
  1097. #        sdivz16stepu = d_sdivzstepu * 16;
  1098. #        tdivz16stepu = d_tdivzstepu * 16;
  1099. #        zi16stepu = d_zistepu * 16;
  1100. #
  1101. #        do
  1102. #        {
  1103. #                pdest = (unsigned char *)((byte *)d_viewbuffer +
  1104. #                                (screenwidth * pspan->v) + pspan->u);
  1105. #
  1106. #                count = pspan->count;
  1107. #
  1108. #        // calculate the initial s/z, t/z, 1/z, s, and t and clamp
  1109. #                du = (float)pspan->u;
  1110. #                dv = (float)pspan->v;
  1111. #
  1112. #                sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
  1113. #                tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
  1114. #                zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
  1115. #                z = (float)0x10000 / zi;        // prescale to 16.16 fixed-point
  1116. #
  1117.  
  1118. .d16loop:
  1119.     lwzu    r8,4(r3)
  1120.     int2dbl f20,r8,r0,local,f10    #f20 = du
  1121.     lwzu    r9,4(r3)
  1122.     int2dbl f21,r9,r0,local,f10    #f21 = dv
  1123.     fmadds  f24,f21,f8,f9
  1124.     fmadds  f22,f21,f2,f3
  1125.     fmadds  f23,f21,f5,f6
  1126.     fmadds  f26,f20,f7,f24          #f26 = zi
  1127.     fmadds  f22,f20,f1,f22          #f22 = sdivz
  1128.     fmadds  f23,f20,f4,f23          #f23 = tdivz
  1129.     fmuls   f0,f26,f26
  1130.     frsqrte f0,f0
  1131.     mullw   r10,r9,r7               #r10 = pspan->v * screenwidth
  1132.     fnmsubs f29,f0,f26,f28
  1133.     add     r10,r10,r8              #r10 = r10 + pspan->u
  1134.     fmuls   f0,f0,f29
  1135.     add     r11,r6,r10              #r11 = pdest
  1136.     fnmsubs f29,f0,f26,f28
  1137.     subi    r11,r11,1               #prepare for postincrement
  1138.     fmuls   f0,f0,f29
  1139.     lwzu    r12,4(r3)               #r12 = count
  1140.     fmuls   f24,f0,f15
  1141.     fmadds  f20,f22,f24,f11         #f20 = s
  1142.     fsubs   f0,f20,f13
  1143.     fsel    f20,f0,f13,f20          #if (s>bb...) s = bbextents
  1144.     fsel    f20,f20,f20,f25         #if (s<0) s = 0
  1145.     fctiwz  f0,f20
  1146.     stfd    f0,local+8(r1)
  1147.     lwz     r8,local+12(r1)         #r8 = (int)s
  1148.     fmadds  f21,f23,f24,f12         #f21 = t
  1149.     fsubs   f0,f21,f14
  1150.     fsel    f21,f0,f14,f21          #if (t>bb...) t = bbextentt
  1151.     fsel    f21,f21,f21,f25         #if (t<0) t = 0
  1152.     fctiwz  f0,f21
  1153.     stfd    f0,local+8(r1)
  1154.     lwz     r9,local+12(r1)         #r9 = (int)t
  1155.     li      r0,1
  1156.     dcbtst  r11,r0
  1157.  
  1158. ######  Second loop. In every iteration one part of the whole span is drawn
  1159.  
  1160. #                do
  1161. #                {
  1162. #                // calculate s and t at the far end of the span
  1163. #                        if (count >= 16)
  1164. #                                spancount = 16;
  1165. #                        else
  1166. #                                spancount = count;
  1167. #
  1168. #                        count -= spancount;
  1169. #
  1170. #                        if (count)
  1171. #                        {
  1172.  
  1173. .d16loop2:
  1174.     cmpwi   r12,16
  1175.     bgt     .d16cont
  1176.     mtctr   r12
  1177.     subi    r10,r12,1
  1178.     int2dbl f21,r10,r0,local,f10    #spancountminus1 = (float)...
  1179.     li      r12,0                   #r12 = count -= spancount
  1180.     fmadds  f26,f21,f7,f26          #zi += d_zistepu * ...
  1181.     b       .d16finalpart
  1182. .d16cont:
  1183.     fadds   f26,f26,f19             #zi += zi16stepu
  1184.     li      r10,16                  #r10 = spancount = 16
  1185.     fmuls   f0,f26,f26
  1186.     subf    r12,r10,r12             #r12 = count -= spancount
  1187.     frsqrte f0,f0
  1188.     mtctr   r10
  1189.  
  1190. #######  Evaluation of the values for the inner loop. This version is used for
  1191. #######  span size = 16
  1192.  
  1193. #                        // calculate s/z, t/z, zi->fixed s and t at far end of span,
  1194. #                        // calculate s and t steps across span by shifting
  1195. #                                sdivz += sdivz16stepu;
  1196. #                                tdivz += tdivz16stepu;
  1197. #                                zi += zi16stepu;
  1198. #                                z = (float)0x10000 / zi;        // prescale to 16.16 fixed-point
  1199. #                                snext = (int)(sdivz * z) + sadjust;
  1200. #                                if (snext > bbextents)
  1201. #                                        snext = bbextents;
  1202. #                                else if (snext < 16)
  1203. #                                        snext = 16;      // prevent round-off error on <0 steps from
  1204. #                                                                //  from causing overstepping & running off the
  1205. #                                                                //  edge of the texture
  1206. #                                tnext = (int)(tdivz * z) + tadjust;
  1207. #                                if (tnext > bbextentt)
  1208. #                                        tnext = bbextentt;
  1209. #                                else if (tnext < 16)
  1210. #                                        tnext = 16;      // guard against round-off error on <0 steps
  1211. #                                sstep = (snext - s) >> 4;
  1212. #                                tstep = (tnext - t) >> 4;
  1213. #                        }
  1214.  
  1215.     fnmsubs f20,f0,f26,f28
  1216.     fadds   f22,f22,f17             #sdivz += sdivz16stepu
  1217.     fmuls   f0,f0,f20
  1218.     fadds   f23,f23,f18             #tdivz += tdivz16stepu
  1219.     fnmsubs f20,f0,f26,f28
  1220.     fmuls   f0,f0,f20
  1221.     fmuls   f24,f0,f15
  1222.     fmadds  f20,f22,f24,f11         #f20 = snext
  1223.     fsubs   f0,f20,f13
  1224.     fsel    f20,f0,f13,f20          #if (snext>bb...) snext = bbextents
  1225.     fsubs   f0,f20,f16
  1226.     fsel    f20,f0,f20,f16          #if (snext<16) snext = 16
  1227.     fctiwz  f0,f20
  1228.     stfd    f0,local+8(r1)
  1229.     lwz     r31,local+12(r1)        #r31 = (int)snext
  1230.     fmadds  f21,f23,f24,f12         #f21 = tnext
  1231.     fsubs   f0,f21,f14
  1232.     fsel    f21,f0,f14,f21          #if (tnext>bb...) tnext = bbextentt
  1233.     subf    r29,r8,r31
  1234.     fsubs   f0,f21,f16
  1235.     srawi   r29,r29,4               #r29 = sstep = (snext - s) >> 4
  1236.     fsel    f21,f0,f21,f16          #if (tnext<16) tnext = 16
  1237.     fctiwz  f0,f21
  1238.     stfd    f0,local+8(r1)
  1239.     lwz     r30,local+12(r1)        #r30 = (int)tnext
  1240.     subf    r28,r9,r30
  1241.     srawi   r28,r28,4               #r28 = tstep = (tnext - t) >> 4
  1242.     b       .d16mainloop
  1243.  
  1244. ######  Evaluation of the values for the inner loop. This version is used for
  1245. ######  span size < 16
  1246.  
  1247. ######  The original algorithm has two ugly divisions at the end of this part.
  1248. ######  These are removed by the following optimization:
  1249. ######  First, the divisors 1,2 and 4 are handled specially to gain speed. The
  1250. ######  other divisors are handled using a reciprocal table.
  1251.  
  1252. #                        // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
  1253. #                        // can't step off polygon), clamp, calculate s and t steps across
  1254. #                        // span by division, biasing steps low so we don't run off the
  1255. #                        // texture
  1256. #                                spancountminus1 = (float)(spancount - 1);
  1257. #                                sdivz += d_sdivzstepu * spancountminus1;
  1258. #                                tdivz += d_tdivzstepu * spancountminus1;
  1259. #                                zi += d_zistepu * spancountminus1;
  1260. #                                z = (float)0x10000 / zi;        // prescale to 16.16 fixed-point
  1261. #                                snext = (int)(sdivz * z) + sadjust;
  1262. #                                if (snext > bbextents)
  1263. #                                        snext = bbextents;
  1264. #                                else if (snext < 16)
  1265. #                                        snext = 16;      // prevent round-off error on <0 steps from
  1266. #                                                                //  from causing overstepping & running off the
  1267. #                                                                //  edge of the texture
  1268. #
  1269. #                                tnext = (int)(tdivz * z) + tadjust;
  1270. #                                if (tnext > bbextentt)
  1271. #                                        tnext = bbextentt;
  1272. #                                else if (tnext < 16)
  1273. #                                        tnext = 16;      // guard against round-off error on <0 steps
  1274. #
  1275. #                                if (spancount > 1)
  1276. #                                {
  1277. #                                        sstep = (snext - s) / (spancount - 1);
  1278. #                                        tstep = (tnext - t) / (spancount - 1);
  1279. #                                }
  1280. #                        }
  1281.  
  1282. .d16finalpart:
  1283.     fmuls   f0,f26,f26
  1284.     fmadds  f22,f21,f1,f22          #sdivz += d_sdivzstepu * ...
  1285.     frsqrte f0,f0
  1286.     fmadds  f23,f21,f4,f23          #tdivs += d_tdivzstepu * ...
  1287.     fnmsubs f20,f0,f26,f28
  1288.     cmplwi  r10,5
  1289.     fmuls   f0,f0,f20
  1290.     fnmsubs f20,f0,f26,f28
  1291.     fmuls   f0,f0,f20
  1292.     fmuls   f24,f0,f15
  1293.     fmadds  f20,f22,f24,f11         #f27 = snext
  1294.     fsubs   f0,f20,f13
  1295.     fsel    f20,f0,f13,f20          #if (snext>bb...) snext = bbextents
  1296.     fsubs   f0,f20,f16
  1297.     fsel    f20,f0,f20,f16          #if (snext<16) snext = 16
  1298.     fctiwz  f0,f20
  1299.     stfd    f0,local+8(r1)
  1300.     lwz     r31,local+12(r1)        #r31 = (int)snext
  1301.     fmadds  f21,f23,f24,f12         #f21 = tnext
  1302.     fsubs   f0,f21,f14
  1303.     fsel    f21,f0,f14,f21          #if (tnext>bb...) tnext = bbextentt
  1304.     subf    r29,r8,r31
  1305.     fsubs   f0,f21,f16
  1306.     fsel    f21,f0,f21,f16          #if (tnext<16) tnext = 16
  1307.     fctiwz  f0,f21
  1308.     stfd    f0,local+8(r1)
  1309.     lwz     r30,local+12(r1)        #r30 = (int)tnext
  1310.     subf    r28,r9,r30
  1311.     blt     .d16special
  1312. .d16qdiv:
  1313.     slwi    r0,r10,2
  1314.     lwzx    r0,r26,r0
  1315.     mulhw   r29,r29,r0
  1316.     mulhw   r28,r28,r0
  1317.     b       .d16mainloop
  1318. .d16special:
  1319.     cmplwi  r10,1
  1320.     ble     .d16mainloop
  1321.     cmplwi  r10,3
  1322.     beq     .d16qdiv
  1323.     blt     .d16spec_2
  1324.     srawi   r29,r29,2
  1325.     srawi   r28,r28,2
  1326.     b       .d16mainloop
  1327. .d16spec_2:
  1328.     srawi   r29,r29,1
  1329.     srawi   r28,r28,1
  1330.  
  1331. ######  Main drawing loop. Here lies the speed.
  1332.  
  1333. #                        do
  1334. #                        {
  1335. #                                *pdest++ = *(pbase + (s >> 16) + (t >> 16) * cachewidth);
  1336. #                                s += sstep;
  1337. #                                t += tstep;
  1338. #                        } while (--spancount > 0);
  1339.  
  1340. .d16mainloop:
  1341.     srawi   r0,r9,16
  1342.     srawi   r10,r8,16
  1343.     mullw   r0,r0,r4
  1344.     add     r9,r9,r28
  1345.     add     r0,r0,r10
  1346.     add     r8,r8,r29
  1347.     lbzx    r0,r27,r0
  1348.     stbu    r0,1(r11)
  1349.     bdnz    .d16mainloop
  1350.     mr      r8,r31
  1351.     mr      r9,r30
  1352.     mr.    r12,r12
  1353.     bgt     .d16loop2
  1354.     lwz     r3,4(r3)                #while (...)
  1355.     mr.    r3,r3
  1356.     subi    r3,r3,4
  1357.     bne     .d16loop
  1358.  
  1359.     lmw    r26,gb(r1)
  1360.     lfd    f14,fb+0*8(r1)
  1361.     lfd    f15,fb+1*8(r1)
  1362.     lfd    f16,fb+2*8(r1)
  1363.     lfd    f17,fb+3*8(r1)
  1364.     lfd    f18,fb+4*8(r1)
  1365.     lfd    f19,fb+5*8(r1)
  1366.     lfd    f20,fb+6*8(r1)
  1367.     lfd    f21,fb+7*8(r1)
  1368.     lfd    f22,fb+8*8(r1)
  1369.     lfd    f23,fb+9*8(r1)
  1370.     lfd    f24,fb+10*8(r1)
  1371.     lfd    f25,fb+11*8(r1)
  1372.     lfd    f26,fb+12*8(r1)
  1373.     lfd    f27,fb+13*8(r1)
  1374.     lfd    f28,fb+14*8(r1)
  1375.     lfd    f29,fb+15*8(r1)
  1376.     exit
  1377.  
  1378.     funcend    D_DrawSpans16
  1379.  
  1380.  
  1381.  
  1382.  
  1383. ###########################################################################
  1384. #
  1385. #       void D_DrawZSpans (espan_t *pspan)
  1386. #                          r3
  1387. #
  1388. #       standard z-scan drawing function
  1389. #
  1390. ###########################################################################
  1391.  
  1392.     funcdef    D_DrawZSpans
  1393.  
  1394.     init    0,16,0,0        # 16 local bytes for int2dbl/dbl2int
  1395.     lf      f1,INT2DBL_0            #for int2dbl_setup
  1396.     stfd    f1,local(r1)
  1397.  
  1398.     ls      f2,cHUGE                #f2 = 0x8000*0x10000
  1399.     ls      f3,d_zistepu            #f3 = d_zistepu
  1400.     ls      f4,d_zistepv            #f4 = d_zistepv
  1401.     ls      f5,d_ziorigin           #f5 = d_ziorigin
  1402.     lw      r5,d_pzbuffer           #r5 = d_pzbuffer
  1403.     lw      r6,d_zwidth             #r6 = d_zwidth
  1404.  
  1405. #        izistep = (int)(d_zistepu * 0x8000 * 0x10000);
  1406.  
  1407.     fmuls   f6,f3,f2
  1408.     fctiwz  f0,f6
  1409.     stfd    f0,local+8(r1)
  1410.     lwz     r7,local+12(r1)         #r7 = izistep
  1411.     subi    r3,r3,4                 #prepare for postincrement
  1412.  
  1413. #                pdest = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
  1414. #
  1415. #                count = pspan->count;
  1416. #
  1417. #        // calculate the initial 1/z
  1418. #                du = (float)pspan->u;
  1419. #                dv = (float)pspan->v;
  1420. #
  1421. #                zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
  1422. #        // we count on FP exceptions being turned off to avoid range problems
  1423. #                izi = (int)(zi * 0x8000 * 0x10000);
  1424.  
  1425.  
  1426. .zloop:
  1427.     lwzu    r8,4(r3)                #r8 = pspan->u
  1428.     lwzu    r9,4(r3)                #r9 = pspan->v
  1429.     lwzu    r10,4(r3)               #r10 = pspan->count
  1430.     mullw   r11,r9,r6
  1431.     add     r11,r11,r8
  1432.     add     r11,r11,r11
  1433.     add     r12,r5,r11              #r12 = pdest = d_pzbuffer + ...
  1434.     int2dbl f7,r8,r0,local,f1    #f7 = du
  1435.     int2dbl f8,r9,r0,local,f1    #f8 = dv
  1436.     fmadds  f10,f8,f4,f5
  1437.     subi    r12,r12,4
  1438.     fmadds  f10,f7,f3,f10           #zi = d_ziorigin + ...
  1439.     fmuls   f7,f10,f2
  1440.     fctiwz  f0,f7
  1441.     stfd    f0,local+8(r1)
  1442.     lwz     r8,local+12(r1)         #r8 = izi = (int)(zi * ...)
  1443.  
  1444. #                if ((long)pdest & 0x02)
  1445. #                {
  1446. #                        *pdest++ = (short)(izi >> 16);
  1447. #                        izi += izistep;
  1448. #                        count--;
  1449. #                }
  1450.  
  1451.     andi.   r0,r12,2                #if (long)pdest & 0x02
  1452.     beq     .zcont
  1453.     srawi   r0,r8,16
  1454.     sth     r0,4(r12)               #*pdest++ (short)(izi >> 16)
  1455.     addi    r12,r12,2
  1456.     add     r8,r8,r7                #izi += izistep
  1457.     subi    r10,r10,1               #count--
  1458. .zcont:
  1459.  
  1460.  
  1461. #                if ((doublecount = count >> 1) > 0)
  1462. #                {
  1463. #                        do
  1464. #                        {
  1465. #                                ltemp = izi >> 16;
  1466. #                                izi += izistep;
  1467. #                                ltemp |= izi & 0xFFFF0000;
  1468. #                                izi += izistep;
  1469. #                                *(int *)pdest = ltemp;
  1470. #                                pdest += 2;
  1471. #                        } while (--doublecount > 0);
  1472. #                }
  1473.  
  1474.     srawi.  r0,r10,1                #if ((doublecount = count >> 1))
  1475.     ble     .zcont2
  1476.     mtctr   r0
  1477. .zloop2:
  1478.     srawi   r0,r8,16                #ltemp = izi >> 16
  1479.     add     r8,r8,r7                #izi += izistep
  1480.     inslwi  r0,r8,16,0              #ltemp |= izi & 0xFFFF0000
  1481.     add     r8,r8,r7                #izi += izistep
  1482.     stwu    r0,4(r12)               #*(int *)pdest = ltemp
  1483.     bdnz    .zloop2
  1484. .zcont2:
  1485.  
  1486. #                if (count & 1)
  1487. #                        *pdest = (short)(izi >> 16);
  1488.  
  1489.     andi.   r0,r10,1                #if (count & 1)
  1490.     beq     .zcont3
  1491.     srawi   r0,r8,16                #*pdest = (short)(izi >> 16)
  1492.     sth     r0,4(r12)
  1493. .zcont3:
  1494.  
  1495. #        } while ((pspan = pspan->pnext) != NULL);
  1496.  
  1497.     lwz     r3,4(r3)                #while (...)
  1498.     mr.    r3,r3
  1499.     subi    r3,r3,4
  1500.     bne     .zloop
  1501.  
  1502.     exit
  1503.  
  1504.     funcend    D_DrawZSpans
  1505.  
  1506.  
  1507.  
  1508.  
  1509. .ifdef    WOS
  1510.     .tocd
  1511. .else
  1512.     .data
  1513. .endif
  1514.  
  1515. lab c8
  1516.     .float    8.0
  1517. lab c16
  1518.     .float    16.0
  1519. lab cHUGE
  1520.     .float    2147483648.0
  1521. lab cSPEED
  1522.     .float    20
  1523. lab cAMP2times2
  1524.     .float    6.0    # 2 * AMP2
  1525. .ifne AMP2-3
  1526. .fail "AMP2 must be 3!"
  1527. .endif
  1528.