home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / chunky2planar / pllbc2p / pllbc2p_release.txt < prev   
Text File  |  1980-01-05  |  21KB  |  572 lines

  1.  
  2.  *=------------------------------------------------------------------------=*
  3.  
  4.                    >> Precalc Linear lookup Blitter C2P <<
  5.  
  6.                              Version: 1.05
  7.  
  8.                          Released: 7th-05-1996
  9.  
  10.                    Written & Designed By:  Kevin Picone 
  11.  
  12.           (c) Copyright 1996 by Kevin Picone of Underware Design
  13.  
  14.                           All Rights Reserved.
  15.  
  16.  *=------------------------------------------------------------------------=*
  17.  
  18.          Contact: 'Kevin Picone' at Email: uwdesign@lin.cbl.com.au
  19.  
  20.  *=------------------------------------------------------------------------=*
  21.  
  22.  
  23.  Features: 
  24.  
  25.                   * Linear Chunky Frame Buffer
  26.  
  27.                   * Single,Double & Quad Pixel widths are supported
  28.  
  29.                   * Uses Normal (none resorted Pixels)
  30.  
  31.                   * 256/64/16 Colour Versions
  32.  
  33.                   * Various Specialized C2P methods.
  34.                  
  35.                           * Normal
  36.                           * Delta
  37.                           * Null Skip & Clear
  38.                           * Delta Null Skip & Clear      (NEW to V1.04)
  39.  
  40.                   * 16bit conversion with 32bit Writes to ChipRAM
  41.  
  42.   
  43.  Special Requirements:
  44.  
  45.                   * ECS/AGA Blitter for long blits.
  46.  
  47.                   * Fastram for Precalc buffer (from 512k -> 2meg ;)
  48.  
  49.                   * Normal Planar Screen  (NOT interleaved)
  50.  
  51.                   * No Screen modulo is allowed
  52.  
  53.  Disadvantages:
  54.  
  55.                   * Rather Hungry upon FASTRAM
  56.  
  57.                   * Extra ChipRAM demands 
  58.  
  59.                   * Uses the Blitter    
  60.                      
  61.                   * Provided Sources are very bulky 
  62.  
  63.                   * Can be cumbersome to initially add
  64.  
  65.                   * No 'C' support (sorry!)
  66.  
  67.  
  68.  *=------------------------------------------------------------------------=*
  69.  
  70.  
  71.  * Copyright:
  72.  ============
  73.  
  74.  The included source codes, intellectual properties, documentation and
  75.  their contained description of methods, remain the (c) copyright of
  76.  Kevin Picone 1996.
  77.  
  78.  I hereby grant permission for this code to be used freely in either  
  79.  P.D./Freeware/Shareware/commercial software releases or used as the basis
  80.  for a better C2P solution in PD/Freeware/Shareware/Commercial software
  81.  releases, with only one condition, you *MUST* please credit me for my
  82.  work.
  83.  
  84.  This archive may be freely distributed via any means.
  85.   
  86.  
  87.  
  88.  * Disclaimer:
  89.  =============
  90.  
  91.  I in no way imply either directly or indirectly, that the described methods
  92.  or included source code(s) are the best (fastest) possible C2P solutions
  93.  in any/some/all cases or situations, they are provided as purely _optional_
  94.  methods to solve the c2p bottleneck.  
  95.  
  96.  
  97.  
  98.  * What is PLLB-C2P ?
  99.  ====================
  100.  
  101.  Precalc Linear Lookup Blitter - Chunky To Planar is actually a C2P
  102.  system and not just a few assorted routines.  The system (although it was
  103.  originally designed purely for my own use) attempts to allow the programmer
  104.  too easily setup and support various bitplane depths, pixel widths and
  105.  conversion methods with relative ease.
  106.  
  107.  
  108.  
  109.  * What are 'Normal' 'Delta' & 'Nullskip' c2p routines ?
  110.  =======================================================
  111.  
  112.  Pllpc2p has built in support for various types of c2p conversion.  These
  113.  methods are 'Normal', 'Delta', 'NullSkip' & 'DeltaNullSkip'.  I've done
  114.  this for one rather obvious reason, as it's quite common that specific
  115.  rendering algorithms can have their performance enhanced by using
  116.  customized c2p solutions.  Hence, I've given you as many choices as I
  117.  possibly could, actually I've probably gone overboard, but who cares. ;)
  118.  
  119.  
  120.  * Normal       - This method is the simplest type of C2P possible, each
  121.                   frame it will convert the entire chunky frame buffer into
  122.                   planar.
  123.  
  124.                   Normal C2P is probably best used when your chunky frame
  125.                   buffer is constantly changing by say %80->%100.
  126.                    
  127.  
  128.  * Delta        - Delta c2p is a little more complex, it constantly takes
  129.                   two chunky frame buffers, the chunky frame just rendered
  130.                   and the last chunky frame rendered, and then compares
  131.                   them, looking for differences.  Each time a difference
  132.                   is found, it converts that group of pixels into planar. 
  133.  
  134.                   Delta c2p can be very powerful, and not too mention
  135.                   quite fast in various situations. Personally, I'd recommend
  136.                   that you use it over 'normal' c2p, or at least do some
  137.                   performance tests for your self.
  138.  
  139.                   Those Familiar with Delta C2P algo's will notice that PLLB
  140.                   c2p allows for double buffering of your 'planar' image.
  141.                   i.e. you don't just render over the current visible
  142.                   frame. (So no ugly frame cuts)
  143.  
  144.                   Moreover, Pllbc2p Delta routines, work in 16 pixel (or
  145.                   less, depends upon the pixel width) delta fields, for
  146.                   improved delta frequency and only shift data to ChipRAM
  147.                   when a difference is found and converted.
  148.  
  149.  
  150.  * NullSkip     - Is a specialize C2P algorithm that scans for groups of
  151.                   NULL pixels (groups of pixel 0).  Each time it locates
  152.                   a NULL pixel group, it performs a quick clear operation
  153.                   to the planar buffer and then continues on, instead of
  154.                   passing the null pixels through the c2p process.
  155.  
  156.                   NullSkip C2P is probably best used, when you can be fairly
  157.                   sure that a large part of chunky frame buffer is going to
  158.                   be constantly clear.
  159.  
  160.                   Nullskip also clears your chunky buffer as it goes.
  161.  
  162.  
  163.  * DeltaNUllSkip- Is just a logical extension to 'NUllSKIP', and NO it's
  164.                   not a combination of the 'DELTA' + 'NULLSKIP" Methods.
  165.                   It's actually a rather clever way to reduce the chipram
  166.                   access in the null skip algorithm.  Which should be very
  167.                   useful on high end CPU's like the 060 (not tested) and
  168.                   the 040, and probably even 50mhz 030 systems.
  169.  
  170.                   It works via remembering if the present group of NULL
  171.                   pixels was cleared in the planar buffer during the last
  172.                   c2p sweep or not. If it was, then it doesn't write to chip
  173.                   at all, if not, it performs the clear and sets the delta
  174.                   tag for this group of pixels.  Hence, this reduces the
  175.                   amount of chipram access and provides a small speed-up
  176.                   in the process.
  177.  
  178.                   DeltaNullSkip also clears out the chunky buffer while it
  179.                   processes it.
  180.  
  181.    
  182.             
  183.  
  184.  * I don't understand this Pixelwidth stuff ?
  185.  ============================================
  186.  
  187.  Pllbc2p, like most other C2p routines supports various pixel widths,
  188.  including single, double and even quad pixel modes.
  189.  
  190.  In double & Quad pixel mode, pllbc2p allows you to render a halved or
  191.  quarter sized (width) chunky image, that the c2p routine will automatically
  192.  blow it up to your selected planar screen width.  This can greatly improve
  193.  both your our algorithms performance and of course the c2p routines
  194.  performance.
  195.  
  196.  Pllbc2p doesn't support Pixel height modes, you'll have to set those up
  197.  yourself.  I normally just use the copper to blur the scan lines.
  198.  
  199.  
  200.  
  201.  * The Bizarre Method:
  202.  =====================
  203.  
  204.  The following method outline is based upon the 256 colour single pixel
  205.  width, other c2p modes may and do vary..
  206.  
  207.  PLLB-C2P is a 16bit combination processor sweep / lookup array and
  208.  Blitter resort algorithm, which is really only designed for 020/030 and
  209.  ECS/AGA systems, But it can also be fairly useful on 040 processors.
  210.  
  211.  
  212.  NOTE:   PLLB-C2p performance on 040's is largely untested, and has never
  213.  =====  been tested on 060's AFAIK, But, if the right conditions present
  214.         themselves, I would suspect that possibly DELTA'd versions and
  215.         the new DELTANULLSKIP routines could be of *SOME* use in avoiding
  216.         the infamous a4000/040 to ChipRAM bottleneck.
  217.  
  218.  
  219.  
  220.  The basic idea behind the algorithm is the usage of large (sometimes
  221.  very large) Pre calculated pixel combination tables. These tables gives us
  222.  the ability to directly use the chunky input pixels as lookup array
  223.  pointers, into the Pre calculated conversion table.  The chunky lookup table,
  224.  contains all the possible combinations of two 8bit chunky pixels in their
  225.  unrolled planar format. (I.e. 8 bytes...)
  226.  
  227.  
  228.  Examples. (256colour Pixel width of 1)
  229.  
  230.                     (p=plane)    p0  p1  p2  p3  p4  p5  p6  p7
  231.  
  232.          Chunky Input $00,$0f = $01,$01,$01,$01,$00,$00,$00,$00
  233.          Chunky Input $0f,$00 = $02,$02,$02,$02,$00,$00,$00,$00
  234.          Chunky Input $01,$0f = $03,$01,$01,$01,$00,$00,$00,$00
  235.          Chunky Input $88,$55 = $01,$00,$01,$02,$01,$00,$01,$02
  236.          Chunky Input $ff,$0f = $03,$03,$03,$03,$02,$02,$02,$02
  237.  
  238.  
  239.  Obviously, with a little simple maths you'll quickly notices that this
  240.  means the lookup array for two 8bit chunky pixels ='s (256*256*8) = 512K ;) 
  241.  and can be as large as 2 megabytes, if available.
  242.  
  243.  Since the tables are unrolled into precalced groups of 8 bytes (2 longwords)
  244.  well obviously, the idea is too always MOVE/logical OR from these tables
  245.  in longwords, into our tempory data registers on the CPU..
  246.  
  247.  So to overview the conversion process of 16 chunky pixels into planar,
  248.  we've got the following simple routine.
  249.  
  250.  
  251.  Convert the first 8pixels, Pixels 0->7
  252.  
  253.  ; A0 = pointer to CHunky pixel buffer
  254.  
  255.  ; A5 = Base pointer to the Precalc comb's buffer
  256.  
  257.  ; Process 8 Chunky bits into planar
  258.  
  259.     clr.l d1        ; Clear out d1
  260.     move.l (a0)+,d0        ; Move Bytes ABCD from chunky buffer
  261.     move.w d0,d1        ; move bytes CD into d1
  262.     clr.w d0        ; AB-- clear low word of D0
  263.     swap d0            ; --AB exchange upper word for lower word
  264.  
  265.     lsl.l #3,d0        ; mult d0 * 8 (width of precalc buffer)
  266.  
  267.     move.l (a5,d0),d3    ; grab planes 1,2,3,4 for pixels AB
  268.     move.l 4(a5,d0),d4    ; grab planes 5,6,7,8 for Pixels AB
  269.  
  270.         lsl.l #2,d3    ; Shift PLanes 1,2,3,4 up 2 bits 
  271.         lsl.l #2,d4    ; sift planes 5,6,7,8 up 2 bits
  272.  
  273.     lsl.l #3,d1        ; mult by 8 (width of precalc Buff)
  274.     or.l (a5,d1),d3        ; or on planes 1,2,3,4 for pixels CD 
  275.     or.l 4(a5,d1),d4    ; or on planes 5,6,7,8 for pixels CD    
  276.  
  277.         lsl.l #2,d3    ; Shift PLanes 1,2,3,4 up 2 bits 
  278.         lsl.l #2,d4    ; sift planes 5,6,7,8 up 2 bits
  279.  
  280.        ;(first 4 pixels are processed at this point)
  281.  
  282.     clr.l d1        ; Clear out d1
  283.     move.l (a0)+,d0        ; Move pixels EFGH from chunky buffer intoD0
  284.     move.w d0,d1        ; move pixels GH into d1
  285.     clr.w d0        ; EF-- clear low word of D0
  286.     swap d0            ; --EF exchange upper word for lower word
  287.  
  288.     lsl.l #3,d0        ; mult EF * 8 (width of precalc buffer)
  289.  
  290.     or.l (a5,d0),d3        ; grab planes 1,2,3,4 for pixels EF
  291.     or.l 4(a5,d0),d4    ; grab planes 5,6,7,8 for Pixels EF
  292.  
  293.         lsl.l #2,d3    ; Shift PLanes 1,2,3,4 up 2 bits 
  294.         lsl.l #2,d4    ; sift planes 5,6,7,8 up 2 bits
  295.  
  296.     lsl.l #3,d1        ; mult GH by 8 (width of precalc Buff)
  297.  
  298.     or.l (a5,d1),d3        ; or on planes 1,2,3,4 for pixels GH 
  299.     or.l 4(a5,d1),d4    ; or on planes 5,6,7,8 for pixels GH    
  300.  
  301.  
  302.  d3 = a1b1c1d1e1f1g1h1a2b2c2d2e2f2g2h2a3b3c3d3e3f3g3h3a4b4c4d4e4f4g4h4
  303.  d4 = a5b5c5d5e5f5g5h5a6b6c6d6e6f6g6h6a7b7c7d7e7f7g7h7a8b8c8d8e8f8g8h8
  304.  
  305.  
  306.  Above, I mentioned that the precalc array could be as large as 2 megabytes
  307.  of FASTRAM, which is (unfortunately) true.  The reason for this is a
  308.  simple speedup which enables us to remove the two required 'lsl.l #2,d3'
  309.  & 'lsl.l #2,d4' instructions after each 'Move/logical or' completely
  310.  from the C2P loop.  The idea is to create 4 versions of the Precalced
  311.  Array with each one being already shifted into position.  Cumbersome
  312.  I know, but can make the routine(s) much faster....
  313.  
  314.  
  315.  Note:     The Pllb-C2p system handles all the possible buffer combinations
  316.  =====     all by it's  self.
  317.  
  318.  
  319.  Anyway, above also I stated that this is a 16bit routine, (which
  320.  is needed for the blitter resort pass) so after we've processed
  321.  the first 8 chunky pixels into planar,  we then repeat the process,
  322.  but this time storing the second converted 8 planes of pixels 8 to 15
  323.  into say registers d5,d6...
  324.  
  325.  
  326.  Now, all that's needed is a simple merge process, and then to move the
  327.  merged data into CHIP for the Blitter resort pass.
  328.  
  329.  ; a1 = output buffer in CHIPRAM
  330.  
  331.  ; d2 = $ff00ff00
  332.  
  333.  ; d3 = planes 1,2,3,4 pixels 0-7
  334.  ; d4 = planes 5,6,7,8 pixels 0-7
  335.  
  336.  ; d5 = planes 1,2,3,4 pixels 8-15
  337.  ; d6 = planes 5,6,7,8 pixels 8-15
  338.  
  339.  
  340.  ; resort the planar bytes into words 
  341.  
  342.  
  343.     move.l d3,d0    ; move Planes 1,2,3,4 to d0 (first 8 pixels_    
  344.     move.l d5,d1    ; move planes 1,2,3,4 to d1 (second 8 pixels)
  345.  
  346.     and.l d2,d0    ; mask with $ff00ff00  d0 ='s planes 1,-,3,-
  347.     and.l d2,d1    ; mask with $ff00ff00  d1 ='s planes 1,-,3,-
  348.                         ;                           (second 8 pixels)
  349.  
  350.     eor.l d0,d3    ; mask off planes 1,-,3,- from planes 1,2,3,4
  351.             ; d3 = -,2,-4
  352.     eor.l d1,d5    ; mask off planes 1,-,3,- from planes 1,2,3,4
  353.             ; d5 = -,2,-4 second 8 pixels
  354.  
  355.     lsr.l #8,d1    ; d1 = -,1,-,3 .. Second 8 pixels
  356.     or.l d1,d0    ; d0 = 1,1,3,3
  357.  
  358.     move.l d0,(a1)+        ; Dump out 32bits (16bits of planes 1 & 3)
  359.  
  360.     lsl.l #8,d3    ; d3 = 2,-,4,- 
  361.     or.l d5,d3    ; d3 = 2,2,4,4
  362.  
  363.     move.l d3,(a1)+        ; Dump out 32bits (16bits of planes 2 & 4)
  364.  
  365.  
  366.     (then repeat the process for Planes 4,5,6,7)
  367.  
  368.  
  369.  
  370.  One thing, you've no doubt already noticed, is that via this method your
  371.  able to write to CHIPRAM in Longwords without a great amount of fuss...
  372.  Plus, the routine(s) are small enought to fit nicely within the 68020's
  373.  small instruction cache, which should help a great deal.  In theory
  374.  pllbc2p on an 28mhz 020's should be as if it was running on a 25mhz 030's,
  375.  obviously various conditions might hinder this.
  376.  
  377.  
  378.  Unfortunately, we still need to use the blitter to move/resort the mixed
  379.  processed display (which is now in Chipram) from the Tempory Image buffer
  380.  to it's final resting place, the screen.  To avoid having too mess with the
  381.  blitter constantly the final screen(s) need to be defined as normal planar
  382.  and *NOT* interleaved, as this allows us to blit move an entire BitPLane
  383.  worth of Pixels, per each useage of the blitter.
  384.  
  385.  Hence, a simple hardware bashing routine to Move/Resort a single bitplane
  386.  from the tempory image buffer to the display screen, would look something
  387.  like this.
  388.  
  389.  
  390.  Bitter_Moveresort_TempImageBitplane_to_Display:    (NICE LABEL ;)
  391.      
  392.      lea.l $dff000,a6        
  393.  
  394.     jsr waitblitter            ; wait for Blitter ;)
  395.  
  396.     move.l #$09f00000,$40(a6)    ; setup blitter miniterms and chan's
  397.     move.l #$ffffffff,$44(a6)    ; init masks
  398.     move.l #((16-2)*$10000),$64(a6) ; setup source and dest modulo's
  399.  
  400.     lea.l BlitterTemp_ImageBuffer,a0
  401.     Move.l Display_buffer,a1
  402.  
  403.     add.l d0,a0    ; add on any source plane offset
  404.     add.l d1,a1    ; add on any dest plane offset
  405.  
  406.     move.l a0,$50(a6)    ; set blitter Chan A pointer to source buf 
  407.     move.l a1,$54(a6)    ; set blitter Chan D pointer to dest Buf
  408.     move.w #20*256,$5c(a6)    ; (20 words wide * 256 lines in Height
  409.     move.w #1,$5e(a6)    ; init width (1 word) and START!
  410.     rts
  411.  
  412.  
  413.  
  414.  The basic idea is to work out some way (depends on what your doing really)
  415.  that allows you to trigger the blitter and then just forget about it,
  416.  which could be via say, Async blits, Interrupts, Copper or perhaps even
  417.  another Task or something.  Personally, I just found it simpler (in the
  418.  Tmap engine it was originally designed for) to check it's progress at
  419.  preselected times. ie. between mapping textures, objects, floors etc etc..
  420.  which added minimal (if any really) overhead, and seemed to work just
  421.  fine.. ;)..... lazy I know ;)
  422.  
  423.  
  424.  
  425.  
  426.  * What Memory Is needed ?:
  427.  ==========================
  428.  
  429.  Well this depends upon the type of game/demo or perhaps util your trying
  430.  to create.
  431.  
  432.  Since, i've included Normal, Delta, Nullskip & now Delta Nullskip versions
  433.  of each routine, well obviously your Buffer requirements will differ.
  434.  
  435.  
  436.  * NORMAL C2P
  437.  
  438.  In FASTRAM, all that you require (min) is too firstly allocate your
  439.  source CHUNKY PIXEL buffer and than the number of Precalc tables you wish
  440.  to use.. 1->4 ie. 512k->2meg ..
  441.  
  442.  In CHIPRAM, you'll need to allocate the tempory image buffer ie.
  443.  ((ScreenWidthInPixels/8) * ScreenHeight*bitplanes)='s size of Tempory
  444.  image buffer.  So if you were only using Two displays for double
  445.  buffering originally well now, you'll need an extra display for the
  446.  Tempory Image buffer.  (sorry)
  447.  
  448.  
  449.  * DELTA C2P
  450.  
  451.  The only different requirement for using the delta versions, is that
  452.  you'll need a second CHUNKY PIXEL buffer.  It should also be noted,
  453.  that you have to swap chunky pixel buffer pointers after each frame is
  454.  rendered, just as you would do normally for double/triple or even
  455.  Quad buffering purposes.
  456.  
  457.  
  458.  * NULL SKIP C2P
  459.  
  460.  The Nullskip versions have the same memory requirements as the Normal
  461.  C2P versions...
  462.  
  463.  
  464.  * DELTA NULLSKIP C2P
  465.  
  466.  Delta Nullskip has the same memory requirements as the Normal c2p version,
  467.  except it also needs a special 'delta' buffer so it can remember which
  468.  groups of null pixels it's cleared in the planar buffer.
  469.  
  470.  This buffer needs to be in FASTRAM and at least the size of your chunky
  471.  buffer divided by 4.  
  472.  
  473.  Ie. (ChunkyScreenwidth*ChunkyScreenheight)/4
  474.  
  475.  
  476.  
  477.  
  478.  PLEASE NOTE: Neither the Normal or Delta versions of the routine CLEAR
  479.               the source Chunky Frame Buffer.
  480.  
  481.  
  482.  
  483.  
  484.  * Linear Frame Buffer:
  485.  ======================
  486.  
  487.  After messing with various Tmapped & Gouraud Shaded engines (just like
  488.  everybody else) where the requirement of a chunky frame buffer for gfx is
  489.  high, the one rather obvious thing I found is that,  it's _normally_ much
  490.  better to save say a couple of cycles per chunky pixel, via rendering 
  491.  / copying across the linear buffer, than to save say a couple of cycles
  492.  in the C2P loop, particularly when your constantly rendering a full
  493.  frame buffer of pixels, where pixel (texture/gouraud) overlap (ie. polygons
  494.  that share the same screen space) is high.
  495.  
  496.  Pllb-c2p is probably quite unique, since it uses Precalc tables to preform
  497.  the actual bit shifting process, well we obtain a free linear buffer 
  498.  and we also achive slightly faster C2P in the process.
  499.  
  500.  
  501.  
  502.  * A possible C2P Hint for 'Wolf 3D' or 'Doom' texture mapped engines:
  503.  =====================================================================
  504.  
  505.  Without wanting to sound critical of *ANY* of the presently available
  506.  Tmap Engines, and having written a 'Blade Stone' styled engine myself,
  507.  so I do know just how hard the task actually is, the one thing I noticed
  508.  is the lack of specialized C2P for when floor/Ceiling texture mapping isn't
  509.  present.  Personally, I consider this the ideal time for either a delta'd
  510.  C2P routine or a specialized NUll SKIP/CLEAR (you could make it use a
  511.  pattern) routine.  Via using the latter method, i've been able to obtain
  512.  8->9fps refresh updates upon just a a1200/020 14mhz+fastram, with a screen
  513.  size of 320*256, 256colour, 1x*2y pixel res, while the engine includes
  514.  lightsources, Solid & See through Texture Mapped Walls & 2D mapped
  515.  objects.
  516.  
  517.  
  518.  Also, it becomes pretty obvious that for a Delta'd C2P routine to be all
  519.  that useful while Floor/Ceiling Mapping is present, that the artist
  520.  should  probably think more about making the floors & ceilings (and even
  521.  walls where possible) textures a little less complex, which will enchance 
  522.  preformance greatly.  It might also be a nice option for Full or reduced
  523.  detail floors & Ceilings, instead of turning them off completely.
  524.  
  525.  
  526.  
  527.  * Why supply Quad Pixel width versions ?:
  528.  =========================================
  529.  
  530.  Well, what can I say, they give you an optional 'Copper' styled screen
  531.  resolution, but without the loss of 24bit colour. (not that it matters
  532.  too much at this res ;)  Perhaps they can be best used in effects like
  533.  'Fire' / 'Water' & 'Life' effects. 
  534.  
  535.  
  536.  
  537.  * Some Future Idea's:
  538.  =====================
  539.  
  540.  
  541.  * Auto 8bit to 6bit colour reduce/remapping.    (Coming Soon)
  542.  
  543.  * Ham 8 with auto interpolation.       (Just a crazy idea at the moment ;)
  544.  
  545.  
  546.  
  547.  * That's it from me:
  548.  ====================
  549.  
  550.  Well, hopefully the enclosed routine(s) are of some use to you, or perhaps
  551.  they might inspire you to take this method further than I have, as this
  552.  is really only the initial working version(s) of PLLB-C2P, so I've *NO*
  553.  doubt there's any number of possible speed-ups just waiting to be found. 
  554.  
  555.  If you do bother too enhance any of the pllbc2p routines, well, I'd
  556.  appreciated it greatly if you'd let me know, so I can pass this
  557.  information to others in future releases of pllbc2p.
  558.  
  559.  
  560.  
  561.  Cya,
  562.  
  563.  Kevin Picone
  564.  Underware Design
  565.  
  566.  
  567.  *=----------------------------------------------------------------------=*
  568.  
  569.                                T H E    E N D
  570.  
  571.  *=----------------------------------------------------------------------=*
  572.