home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xibm.zip / apa16 / fs.spp < prev    next >
Text File  |  1991-12-17  |  11KB  |  607 lines

  1.     # This file has 4 functions.  The first is solid fill spans,
  2.     # the second is a tile fill spans (currently not used because
  3.     # it doesn't work), the third draws vertical rectangles, and
  4.     # the fourth draws horizontal rectangles ("vertical" and
  5.     # "horizontal" refer to the way these routines are optimized).
  6.  
  7.     # Fill spans (int *pwidth, struct {short x,y} *ppts,
  8.     #        int nspans, int rop)
  9.     # Tile fill spans (int *pwidth, struct {short x,y} *ppts,
  10.     #        int nspans, int rop, int *pTile, int w, int h,
  11.     #        int pw, int xorg, int yorg)
  12.     # {vert,horz} fill rects (int *px, int *py, int *pw, int *ph, n, rop)
  13.  
  14.     # notes:
  15.     # read from bit map (0xf4dxxxxx) takes 3.1 us
  16.     # write to bit map takes 2.5 us
  17.     # read from I/O register (0xf00xxxxx) takes 2.7 us
  18.     # write to I/O register takes 2.2 us
  19.     # A lot of code here would seem to be inefficient except that
  20.     # it overlaps I/O to the apa16.
  21.  
  22.     # This function used to draw lines for FillSpans, but that code was
  23.     # broken, it is expensive to switch from queue to frame buffer, and
  24.     # the break-even point is large (greater than 100 pixels).
  25.  
  26.     # registers used in fill spans and tile fill spans:
  27.     #    r0    -1 or tile value
  28.     #    r2    pwidth
  29.     #    r3    ppts
  30.     #    r4    nspans
  31.     #    r5    rop << 4 (const part of MR)
  32.     #    r6    Mode register value
  33.     #    r7    screen addr
  34.     #    r8    x
  35.     #    r9    y
  36.     #    r10    width
  37.     #    r11    tmp (width % 16)
  38.     #    r12    tmp (bit offset in word, MR)
  39.     #    r13    queue length
  40.     #    r14    tile line pointer (tile FS only)
  41.     #    r15    &queue_counter (solid), x (tile)
  42.  
  43.     # constants
  44.     .set    screen_addr,0xf4d80000
  45.     .set    queue_counter,0xf4d9f804
  46.     .set    queue_pointer,0xf4d9f806
  47.     .set    mode_shadow,0xf4d9f812
  48.     .set    mode_register,0xf0000d10
  49.  
  50.     .globl    .oVncs
  51.  
  52.     .data
  53.     .align    2
  54.     .globl    _apa16FastFS
  55. _apa16FastFS:    .long    _.apa16FastFS
  56.     .text
  57.     .align    2
  58.     .globl    _.apa16FastFS
  59. _.apa16FastFS:
  60.     stm    r6,-0x5c(sp)
  61.     cal    sp,-0x64(sp)
  62.  
  63.     # assume that it is valid to dereference the width pointer
  64.     # even if there are 0 spans
  65.  
  66.     ls    r10,0(r2)        # prefetch first width
  67.     lda    r15,queue_counter
  68.     lhs    r13,0(r15)
  69.     inc    r2,4            # pwidth++
  70.     sli    r5,4            # convert rop to mode register value
  71.     setbl    r5,0            # set horizontal access bit
  72.     lhs    r8,0(r3)        # prefetch first x
  73.     lh    r9,2(r3)        # prefetch first y    [stall 4]
  74.     lda     r7,screen_addr
  75.     cis    r4,0
  76.     loadh    r6,mode_shadow        #            [stall 1]
  77.     jle    ret            # note that epilogue requires r6 valid
  78.                     # so this test can't be moved earlier
  79.     bx    0f
  80.     cal    r0,-1(r0)
  81.  
  82. loop:
  83.     # get span info
  84.     ls    r10,0(r2)        # width = *pwidth++
  85.     inc    r2,4
  86.     lhs    r8,0(r3)        # x = ppts->x
  87.     lda    r7,screen_addr
  88.     lh    r9,2(r3)        # y = ppts->y
  89. 0:
  90.     inc    r3,4            # ppts++
  91.     nilz    r12,r8,15        # bit offset within word
  92.     nilz    r11,r10,15        # width % 16
  93.     bnex    0f
  94.     o    r12,r5            # new mode register
  95.     cal    r10,-16(r10)        # "partial" last word is really full word
  96. 0:
  97.     sri    r8,3            # byte offset in scan line
  98.     clrbl    r8,15            # with low bit forced to 0
  99.     a    r7,r8
  100.  
  101.     cis    r13,0            # graphics processor active?
  102.     beqx    0f
  103.     sli    r9,7            # byte offset of scan line
  104.     bali    r0,queue_wait        # wait for queue to drain
  105.     cal    r0,-1(r0)
  106. 0:
  107.     sri    r10,4            # number of full words to write
  108.     beqx    short            # 1 word is fast
  109.     a    r7,r9            # addr of left end of line
  110.  
  111.     # write r10 + 1 full words plus r11 bits
  112.     # bit offset is in r12
  113.     c    r12,r6            # mode register unchanged?    [stall 8]
  114.     jeq    write_bits
  115.     storeh    r12,mode_register,r6
  116.     mr    r6,r12
  117.  
  118. write_bits:
  119.     sths    r0,0(r7)
  120.     inc    r7,2
  121.     sis    r10,1
  122.     jh    write_bits
  123.  
  124. short:
  125.     sli    r11,8
  126.     o    r12,r11            # set write mask
  127.     c    r6,r12
  128.     jeq    0f
  129.     storeh    r12,mode_register,r6
  130.     mr    r6,r12
  131. 0:
  132.     sths    r0,0(r7)
  133.     sis    r4,1
  134.     jh    loop
  135.  
  136. ret:
  137.     # reset merge mode to copy
  138.     cal16    r11,0x90(r0)
  139.     store    r11,_apa16Qvars+8,r15    # apa16Qmerge_mode_old    
  140.     setbl    r11,0            # horizontal access bit
  141.     c    r6,r11
  142.     jeq    2f
  143.     storeh    r11,mode_register,r15
  144. 2:
  145.     lm    r6,8(sp)
  146.     brx    r15
  147.     cal    sp,0x64(sp)
  148.  
  149.     #####
  150.  
  151. queue_wait:
  152.     # mode register must be 80x0 to read queue counter
  153.     nilz    r13,r6,0xff0f
  154.     cal16    r12,0x8000(r0)
  155.     c    r13,r12
  156.     jeq    0f
  157.     nilz    r6,r5,0x00f0
  158.     o    r12,r6
  159.     storeh    r12,mode_register,r6
  160.     mr    r6,r12
  161. 0:
  162.     lhs    r13,0(r15)
  163.     cis    r13,0
  164.     jne    0b
  165.     br    r0
  166.  
  167.     .long    0xdf02df00
  168.  
  169.  
  170. #ifdef FAST_TILE
  171.     # apa16FastTileFS is similar to apa16TileFS except that it
  172.     # has to compute the value to write each word.  Register use
  173.     # is a bit different because of this.
  174.  
  175.     # Note: this does not depend on the tile being a multiple of
  176.     # 32 bits wide.  It does require that the tile be at least 16 bits
  177.     # wide.
  178.  
  179.     .globl    _apa16FastTileFS
  180.     .globl    _.apa16FastTileFS
  181.  
  182.     .data
  183.     .align    2
  184. _apa16FastTileFS:
  185.     .long    _.apa16FastTileFS
  186.  
  187.     .text
  188.     .align    2
  189. _.apa16FastTileFS:
  190.     stm    r6,-0x5c(sp)
  191.     cal    sp,-0x64(sp)
  192.  
  193.     ls    r10,0(r2)        # prefetch first width
  194.     loadh    r13,queue_counter
  195.     inc    r2,4            # pwidth++
  196.     lhs    r8,0(r3)        # prefetch first x
  197.     sli    r5,4
  198.     setbl    r5,0            # set horizontal access bit
  199.     cis    r4,0            # (this check is free, overlapped
  200.     jeq    ret            #  with memory access)
  201.     lh    r9,2(r3)        # prefetch first y
  202.     lda    r7,screen_addr
  203.     loadh    r6,mode_shadow        #            [stall 2]
  204.     j    0f
  205.  
  206. tile_loop:
  207.     # get span info
  208.     ls    r10,0(r2)        # width = *pwidth++
  209.     inc    r2,4
  210.     lhs    r8,0(r3)        # x = ppts->x
  211.     lda    r7,screen_addr
  212.     lh    r9,2(r3)        # y = ppts->y
  213. 0:
  214.     inc    r3,4            # ppts++
  215.     bx    tile_line_init
  216.     mr    r15,r8
  217. tile_line_init_ret:
  218.     nilz    r12,r8,15        # bit offset within word
  219.     nilz    r11,r10,15        # width % 16
  220.     bnex    0f
  221.     o    r12,r5            # new mode register
  222.     cal    r10,-16(r10)        # "partial" last word is really full word
  223. 0:
  224.     sri    r8,3            # byte offset in scan line
  225.     clrbl    r8,15            # with low bit forced to 0
  226.     a    r7,r8
  227.  
  228.     cis    r13,0
  229.     beqx    0f
  230.     sli    r9,7            # byte offset of scan line
  231.  
  232.     sts    r15,4(sp)
  233.     lda    r15,queue_counter
  234.     balix    r0,queue_wait
  235.     sts    r12,0(sp)
  236.     ls    r12,0(sp)
  237.     ls    r15,4(sp)
  238. 0:
  239.     sri    r10,4            # number of full words to write
  240.     beqx    tile_short        # 1 word is fast
  241.     a    r7,r9            # addr of left end of line
  242.  
  243.     # write r10 + 1 full words plus r11 bits
  244.     # bit offset is in r12
  245.     c    r12,r6            # mode register unchanged?    [stall 8]
  246.     jeq    tile_write_bits
  247.     storeh    r12,mode_register,r6
  248.     mr    r6,r12
  249.  
  250. tile_write_bits:
  251.     bali    r0,tile_get_word
  252.     sths    r0,0(r7)
  253.     sis    r10,1
  254.     bhx    tile_write_bits
  255.     inc    r7,2
  256.  
  257. tile_short:
  258.     sli    r11,8
  259.     o    r12,r11            # set write mask
  260.     c    r6,r12
  261.     jeq    0f
  262.     storeh    r12,mode_register,r6
  263.     mr    r6,r12
  264. 0:
  265.     bali    r0,tile_get_word
  266.     sths    r0,0(r7)
  267.     sis    r4,1
  268.     jh    tile_loop
  269.     b    ret
  270.  
  271.  
  272.     # The next 2 routines use r13 and r0 as temporary registers
  273.  
  274. tile_line_init:
  275.     # Compute the address of the start of the tile scan line
  276.     # and save it in r14.
  277.     # inputs:
  278.     # r9 = y
  279.     # 0x64(sp) = tile pointer
  280.     # 0x68(sp) = tile w (bits)
  281.     # 0x6c(sp) = tile h
  282.     # 0x70(sp) = tile padded w (bytes)
  283.     # 0x74(sp) = x origin of tile
  284.     # 0x78(sp) = y origin of tile
  285.  
  286.     l    r0,0x78(sp)
  287.     l    r13,0x6c(sp)
  288.     l    r14,0x64(sp)        # load tile pointer
  289.     sf    r0,r9        # r0 = (y - yorg) 
  290.     sli16    r0,0        # r0 = (y - yorg) << 16
  291.  
  292.     mts    r10,r0
  293.     lis    r0,0        # r0:mq = y << 16
  294.  
  295.     d    r0,r13        # compute (y - yorg) % h
  296.     d    r0,r13
  297.     d    r0,r13
  298.     d    r0,r13
  299.     d    r0,r13
  300.     d    r0,r13
  301.     d    r0,r13
  302.     d    r0,r13
  303.  
  304.     d    r0,r13
  305.     d    r0,r13
  306.     d    r0,r13
  307.     d    r0,r13
  308.     d    r0,r13
  309.     d    r0,r13
  310.     d    r0,r13
  311.     d    r0,r13
  312.  
  313.     jc0    0f
  314.     a    r0,r13
  315. 0:
  316.     mts    r10,r0        # r10 = y % h
  317.     l    r13,0x70(sp)    # r13 = pw
  318.  
  319.     s    r0,r0
  320.  
  321.     m    r0,r13
  322.     m    r0,r13
  323.     m    r0,r13
  324.     m    r0,r13
  325.     m    r0,r13
  326.     m    r0,r13
  327.     m    r0,r13
  328.     m    r0,r13        # mq = ((y % h) * w) << 16
  329.  
  330.     mfs    r10,r0
  331.     sri16    r0,0        # (y % h) * pw
  332.     nilo    r0,r0,0xfffc    # word align
  333.     cas    r14,r0,r14
  334.     get    r0,$0x10000000
  335.     tlt    r14,r0
  336.     get    r0,$0x20000000
  337.     tgte    r14,r0
  338.     j    tile_line_init_ret
  339.  
  340.  
  341.  
  342.     # tile_get_word: 
  343.     # inputs:
  344.     # r14 = start of scan line
  345.     # r15 = x
  346.     # 0x7c(sp) = w
  347.     # 0x84(sp) = xorg
  348.     # r0 = return addr
  349.     # output:
  350.     # r0 = word to write
  351.     # r13 is used as a temporary
  352.  
  353. tile_get_word:
  354.     sts    r0,0(sp)
  355.     sts    r2,4(sp)
  356.     l    r0,0x74(sp)    # xorg
  357.     l    r13,0x6c(sp)    # w
  358.     sf    r0,r15        # (x - xorg)
  359.     sli16    r0,0        # (x - xorg) << 16
  360.     mts    r10,r0
  361.     lis    r0,0        # r0:mq = x << 16
  362.  
  363.     d    r0,r13
  364.     d    r0,r13
  365.     d    r0,r13
  366.     d    r0,r13
  367.     d    r0,r13
  368.     d    r0,r13
  369.     d    r0,r13
  370.     d    r0,r13
  371.  
  372.     d    r0,r13
  373.     d    r0,r13
  374.     d    r0,r13
  375.     d    r0,r13
  376.     d    r0,r13
  377.     d    r0,r13
  378.     d    r0,r13
  379.     d    r0,r13
  380.  
  381.     jc0    0f
  382.     a    r0,r13
  383. 0:
  384.     exts    r0,r0        # clear high bits of r0 = (x - xorg) % w
  385.     ail    r2,r0,16
  386.     c    r2,r13
  387.     jh    tile_split    # wrap around
  388.  
  389.     # Tile access does not wrap.  Read two halfwords and combine them.
  390.     sri    r0,3        # make a byte count
  391.     clrbl    r0,15        # force even
  392.     cas    r13,r0,r14
  393.     nilz    r2,r2,15    # (x - xorg) % 16
  394.     beqx    tile_halfword
  395.     lhs    r0,0(r13)
  396.     lh    r13,2(r13)
  397.     # 16 of the bits in r0||r13, starting with bit #r2, are the ones we want
  398.     # shift r0 left r2 bits, shift r13 right (16 - r2) bits
  399.     sl    r0,r2
  400.     sfi    r2,r2,16
  401.     sr    r13,r2
  402.     l    r2,4(sp)
  403.     o    r0,r13
  404.     ls    r13,0(sp)
  405.     br    r13
  406.  
  407.     # this is separate to avoid reading past the end of the tile
  408.     # bitmap if the last 16 bits of the tile are to be read
  409. tile_halfword:
  410.     ls    r13,0(sp)
  411.     brx    r13
  412.     ls    r2,4(sp)
  413.  
  414.     # Tile access wraps around.
  415.     # Compute 16 bit word by concatenating last # bits of 
  416.     # tile with first (16-#) bits of tile.
  417. tile_split:
  418.     st    r3,-4(sp)
  419.     lhs    r2,0(r14)
  420.     nilz    r3,r0,0xfff0
  421.     sri    r3,3
  422.     cas    r3,r3,r14
  423.     lhs    r3,0(r3)
  424.     # r2 = left end of tile, r3 = right end of tile
  425.     # r13 - r0 is number of bits to take from r3
  426.     s    r13,r0
  427.     sr    r2,r13        # clear high bits of r2
  428.     sfi    r13,r13,16
  429.     sl    r3,r13        # clear low bits of r2
  430.     o    r2,r3
  431.     ls    r13,0(sp)
  432.     l    r3,-4(sp)
  433.     mr    r0,r2
  434.     brx    r13
  435.     ls    r2,4(sp)
  436.  
  437.     .long    0xdf02df00
  438. #endif
  439. #ifdef FAST_RECT
  440.  
  441.     # draw a vertical rectangle
  442.  
  443.     .globl    _apa16FastVertFS
  444.     .globl    _.apa16FastVertFS
  445.  
  446.     .data
  447.     .align    2
  448. _apa16FastVertFS:
  449.     .long    _.apa16FastVertFS
  450.  
  451.     .text
  452.     .align    2
  453. _.apa16FastVertFS:
  454.     stm    r6,-0x5c(sp)
  455.     cal    sp,-0x64(sp)
  456.  
  457.     lda    r15,queue_counter
  458.     lhs    r13,0(r15)
  459.     loadh    r6,mode_shadow
  460.     cis    r13,0
  461.     jeq    0f
  462.     bali    r0,queue_wait
  463. 0:
  464.     l    r15,0x68(sp)        # n
  465.     cal    r0,-1(r0)
  466. nloop:
  467.     lhs    r10,0(r4)        # w
  468.     lhs    r14,0(r2)        # x
  469. xloop:
  470.     l    r7,0x64(sp)        # rop
  471.     lhs    r9,0(r3)        # y
  472.     mr    r8,r14
  473.     nilz    r12,r8,15        # x & 15
  474.     lhs    r11,0(r5)        # h
  475.  
  476.     sli    r7,4
  477.     o    r12,r7            # mode register
  478.     sri    r8,3            # x >> 3
  479.     clrbl    r8,15
  480.     lda    r7,screen_addr(r8)
  481.     sli    r9,7
  482.     a    r7,r9
  483.     sri    r9,7
  484.  
  485.     nilz    r13,r11,0xf
  486.     jne    1f
  487.     ail    r11,r11,-16
  488.     jc0    veloop            # h was 0?
  489. 1:
  490.     sri    r11,4
  491.     jeq    vshort            # only one word
  492.  
  493.     c    r6,r12
  494.     jeq    2f
  495.     storeh    r12,mode_register,r6
  496.     mr    r6,r12
  497. 2:
  498.     sths    r0,0(r7)
  499.     cal    r7,2048(r7)
  500.     sis    r11,1
  501.     jh    2b
  502. vshort:
  503.     o    r12,r13            # bit mask
  504.     c    r6,r12
  505.     jeq    3f
  506.     storeh    r12,mode_register,r6
  507.     mr    r6,r12
  508. 3:
  509.     sths    r0,0(r7)
  510.  
  511.     sis    r10,1            # while (--width > 0)
  512.     bhx    xloop
  513.     inc    r14,1            # x++
  514.  
  515. veloop:
  516.     sis    r15,1
  517.     jnh    ret
  518.     inc    r2,2            # px++
  519.     inc    r3,2            # py++
  520.     inc    r4,2            # pw++
  521.     bx    nloop
  522.     inc    r5,2            # ph++
  523.     b    ret
  524.  
  525.     .globl    _apa16FastHorzFS
  526.     .globl    _.apa16FastHorzFS
  527.  
  528.     .data
  529.     .align    2
  530. _apa16FastHorzFS:
  531.     .long    _.apa16FastHorzFS
  532.  
  533.     .text
  534.     .align    2
  535. _.apa16FastHorzFS:
  536.     stm    r6,-0x5c(sp)
  537.     cal    sp,-0x64(sp)
  538.  
  539.     get    r15,$queue_counter
  540.     lhs    r13,0(r15)
  541.     loadh    r6,mode_shadow
  542.     cis    r13,0
  543.     jeq    0f
  544.     bali    r0,queue_wait
  545. 0:
  546.     l    r15,0x68(sp)        # n
  547.     cal    r0,-1(r0)
  548. hnloop:
  549.     lhs    r11,0(r5)        # h
  550.     lhs    r14,0(r3)        # y
  551. hyloop:
  552.     l    r7,0x64(sp)        # rop
  553.     lhs    r8,0(r2)        # x
  554.     lhs    r10,0(r4)        # w
  555.  
  556.     mr    r9,r14            # y
  557.     nilz    r12,r8,15        # x & 15
  558.     sli    r7,4
  559.     setbl    r7,0            # horizontal access bit
  560.     o    r12,r7            # mode register
  561.     sri    r8,3            # x >> 3
  562.     clrbl    r8,15
  563.     get    r7,$screen_addr
  564.     a    r7,r8
  565.     sli    r9,7
  566.     a    r7,r9
  567.     sri    r9,7
  568.  
  569.     nilz    r13,r10,0xf
  570.     jeq    1f
  571.     cal    r10,-16(r10)
  572. 1:
  573.     sri    r10,4
  574.     jeq    hshort            # only one word
  575.  
  576.     c    r6,r12
  577.     jeq    2f
  578.     storeh    r12,mode_register,r6
  579.     mr    r6,r12
  580. 2:
  581.     sths    r0,0(r7)
  582.     inc    r7,2
  583.     sis    r11,1
  584.     jh    2b
  585. hshort:
  586.     o    r12,r13            # bit mask
  587.     c    r6,r12
  588.     jeq    3f
  589.     storeh    r12,mode_register,r6
  590.     mr    r6,r12
  591. 3:
  592.     sths    r0,0(r7)
  593.  
  594.     sis    r11,1            # while (--height > 0)
  595.     bhx    hyloop
  596.     inc    r14,1            # y++
  597.  
  598.     sis    r15,1
  599.     bnh    ret
  600.     inc    r2,2            # px++
  601.     inc    r3,2            # py++
  602.     inc    r4,2            # pw++
  603.     bx    hnloop
  604.     inc    r5,2            # ph++
  605.     b    ret
  606. #endif
  607.