home *** CD-ROM | disk | FTP | other *** search
/ Vectronix 2 / VECTRONIX2.iso / FILES_03 / JAGDOX.ZIP / OBJECT.TXT < prev    next >
Text File  |  1995-12-10  |  23KB  |  613 lines

  1. # -------------------------------------------------------------------
  2. # OBJECTPROCESSOR              (c) Copyright 1995 Nat! & KKP
  3. # -------------------------------------------------------------------
  4. # These are some of the results/guesses that Klaus and I (Nat!) found
  5. # out about the Jaguar. Since we are not under NDA or anything from
  6. # Atari we feel free to give this to you for educational purposes
  7. # only.
  8. #
  9. # Please note, that this is not official documentation from Atari
  10. # or derived work thereof (both of us have never seen the Atari docs)
  11. # and Atari isn't connected with this in any way.
  12. #
  13. # Please use this informationphile as a starting point for your own
  14. # exploration and not as a reference. If you find anything innacurate,
  15. # missing, needing more explanation etc. by all means please write
  16. # to us:
  17. #     nat@zumdick.rhein-main.de
  18. # or
  19. #     kkp@gamma.dou.dk
  20. #
  21. # If you could do us a small favor, don't use this information for
  22. # those lame flamewars on r.g.v.a or the mailing list.
  23. #
  24. # HTML soon ?
  25. # -------------------------------------------------------------------
  26. # $Id: op.txt,v 1.3 1995/12/08 17:57:09 nat Exp $
  27. # -------------------------------------------------------------------
  28. # Lots of thanks to "Blakatz" who cleared up quite a bit of loose
  29. # tails
  30. # -------------------------------------------------------------------
  31. Things to know about the Objectprocessor (OP):
  32.  
  33. -1  Imagine a phrase being an entity of 64 bits (or 8 bytes for that
  34.     matter).
  35.  
  36. 0.  The object list is a linked list.
  37.  
  38. 1.  The object list is traversed by the object processor for
  39.     each! scanline. This means that if you have 64 scaled
  40.     bitmaps objects in your object list and a vertical rez
  41.     going of 240 lines and a refreshrate of 60Hz the
  42.     Objectprozessor is pulling
  43.  
  44.     60hz * 240lines * 64objects * 2 phrases =  1.8 Mphrases/s
  45.     ~ 14.7Mb/s  for the object processor alone!
  46.     If you figure you're using 128x128x16bit sprites, fully
  47.     visible, you're doing:
  48.  
  49.     128x128*16bits/64bits = 4096 phrases a sprite
  50.     64 sprites in 60hz    = 3840 sprites
  51.     yields 15728640 phrases/s (R/W ops) giving
  52.     31457280 bus accesses for a total of
  53.     251658240 bytes/s
  54.  
  55.     So it is fairly easy to unknowingly saturate the bus with
  56.     a nice object list...
  57.  
  58. 1.1 It should be obvious that non-"truecolor" sprites still make
  59.     lotsa sense, when you're using the OP heavily.
  60.  
  61. 1.2 It looks like the Objectprocessor is loading the Objectlist
  62.     in lots of four phrases. (This is a guess, because there
  63.     are four object phrase registers)
  64.  
  65. 2.  The last object must be a STOP object.
  66.  
  67. 4.  The Objectlist must be doublephrase aligned. This means
  68.     that the lower nybble of the address must be zero.
  69.  
  70. 5.  The Objectprocessor probably works like this:
  71.  
  72.     Whenever a new scanline needs to be displayed, the
  73.     objectprocessor provides a linebuffer to the videosystem. While
  74.     the videosystem is busy displaying this, the OP readies the next
  75.     scanline. (It uses a doublebuffering strategy) It does
  76.     this by traversing the objectlist and interpreting each
  77.     object in sequence. Each object has per scanline the chance
  78.     ONCE to fill the linebuffer. It fills the linebuffer at
  79.     a specified horizontal position for a specified width. The data
  80.     in the linebuffer is always overwritten (except when the
  81.     Read-Modify-Write bit is set). If the active object has the
  82.     transparent bit set, it will not overwrite values in the
  83.     linebuffer when its source pixel has the value zero.
  84.     The 'transparency' check is done before looking up the pixel's
  85.     color in the CLUT (1 - 256 color modes) CLUT.
  86.  
  87. 5.1 The sooner a object appears in the list the more
  88.     in the background it appears. The linebuffer is initalized with
  89.     the linebufferbackgroundcolor (BG) before the objectprocessor
  90.     starts filling  the linebuffer.
  91.  
  92.     One may also assume that the OP normally traverses the
  93.     linebuffer from left to right, except when the horizontal flip
  94.     bit is set.
  95.     Each bitmap object is made up of pixels. These pixels can be either
  96.     contain the color itself (direct) as in CrY and TrueColor modes
  97.     or be an index into a Colorlookuptable (indirect).
  98.  
  99. 5.2.    The videosystem can deal with 16bit RGB/Crycolor and 32bit RGB (?)
  100.     pixels, the size of the pixels the OP writes into the linebuffer
  101.     and pulls out of the CLUT, depends on the pixeltype chosen for
  102.     the videosystem.
  103.  
  104. 5.3 The object in the objectlist are *modified* by the OP. This means
  105.     that an object list is only good for one frame. You need to
  106.     continually refresh your object list each VBLANK.
  107.  
  108. 7.  The address of the image of an object must be (as expected)
  109.     phrase aligned (zero in the lower 3 bits)
  110.  
  111. 8.  There are five different objects that the Objectprocessor knows
  112.     about. These are:
  113.  
  114.     1.  Bitmapped Object
  115.     2.  Scaled bitmapped object
  116.     3.  GPU-Object (Calls the GPU to do the displaying ?? )
  117.     4.  Branchobject (for what ?)
  118.     5.  Stopobject (marks the end of the object list)
  119.  
  120.     The objects have different sizes. The minimum size of an object
  121.     is a "phrase".
  122.  
  123.     Object type Number    Size in phrases
  124.     -----------------------------------------
  125.     BIMAP       0       2
  126.     SCALE       1       3 (4?)
  127.     GPU     2       1
  128.     BRANCH      3       1
  129.     STOP        4       1
  130.  
  131.     It looks like you need to pad your scale objects to four phrases...
  132.  
  133. 9.  The branch objects are used to compare the current scanline
  134.     with the value stored in the branch object. Depending on the
  135.     branch instructions comparison mode, the branch is taken
  136.     either on < == != or > (just a guess). The branch taken takes
  137.     the information from the Linkinfo and branches to the phraseindexed
  138.     object. If the comparison fails it simply examines and handles
  139.     the next object in the list.
  140.  
  141. 9.1 To keep the Objectprocessor from fetching data (and wasting bandwidth)
  142.     during the VBLANK you usually put two branch objects at the beginning
  143.     of the display list, that branch to the stop object if the first
  144.     displayable scanline has not been reached or the last displayable
  145.     scanline has already been displayed.
  146.  
  147.  
  148. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  149. 10  This is what a branch object looks like:
  150. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  151.  
  152. Phrase #0:
  153.  
  154.    63      56        48       40       32        24       16       8    3   0
  155.   +--------+---------+---------+--------+--------+--------+--------+--------+
  156.   |        unused          |      Link-address   |CC| unknown|   VCnt   |011|
  157.   +--------+---------+---------+--------+--------+--------+--------+--------+
  158.       63 .............43         42..........24   23           13 .... 3
  159.                           .
  160.                           22
  161.  
  162. Conditioncodes:
  163.  
  164.          Values     Comparison/Branch
  165.     ------------------------------------------------
  166.         00  Branch on not equal  (Guess)
  167.         01  Branch on less than
  168.         10  Branch on greater than
  169.         11  Branch on equal      (Guess)
  170.  
  171. VCnt:       This is the value you compare the vertical scanline
  172. counter with. For CC code 10 the operation goes:
  173.  
  174.     if( Actual_scanline > object->YCnt)
  175.        goto object->link;
  176.  
  177.  
  178. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  179. 11  This is what a stop object looks like:
  180. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  181.  
  182. Phrase #0 (1 of 1):
  183.  
  184.    63      56        48       40       32        24       16       8    3   0
  185.   +--------+---------+---------+--------+--------+--------+--------+--------+
  186.   |                            unused            |      datafield       |100|
  187.   +--------+---------+---------+--------+--------+--------+--------+--------+
  188.  
  189.  There is a datafield in this instruction of unkown size. This may or
  190.  may not be a way to generate horizontal interrupts. Maybe this is just
  191.  a flag that someone can poll from somewhere...
  192.  
  193.  
  194. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  195. 12. This is what a bitmap object looks like:
  196. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  197. Phrase #0 (1 of 2):
  198.  
  199.    63      56        48       40       32        24       16       8    3   0
  200.   +--------+---------+---------+--------+--------+--------+--------+--------+
  201.   |        data-address    |     Link-address    |   Height  |   YPos   |000|
  202.   +--------+---------+---------+--------+--------+--------+--------+--------+
  203.       63 .............43         42..........24   23 ..... 14 13 ..... 3 2.0
  204.          21 bits             19 bits        10 bits     11 bits  3 bits
  205.  
  206.  
  207.   data-address:     Pointer to the bitmap       *?*DESTROYED BY THE OP*?*
  208.   link-address:     Pointer to the next object
  209.   height:       Height in pixels
  210.   y-pos:        Vertical position       ***DESTROYED BY THE OP***
  211.   type:         Object type
  212.  
  213.  
  214.   data-address:
  215.     An address is a memory address in terms of phrases. To get the
  216.     byte address you have to shift it up by 3. (or in this example
  217.     to get the data-address you would fetch the upper lword with
  218.     the 68K and do):
  219.  
  220.         move.l  (a0),d0     ; fetch it  (bits 63-32)
  221.         moveq   #11,d1      ; or some other less lame way
  222.         lsr.l   d1,d0       ; shift it down for phrase address
  223.         lsl.l   d1,d0       ; shift it up for byte address
  224.  
  225.    link-address:
  226.     The link address strings the object list together. So it really
  227.     is a linked list, not just an array. OK an array would have
  228.     been better and the link could have been a number of phrases
  229.     to skip. It misses the upper two bits two form a proper full
  230.     24 bit address. This means that objects must reside in the
  231.     lower 4 MB.
  232.  
  233.    height:
  234.     The height of the object is also stored in the first phrase.
  235.     This is the number of pixels an object has in it vertical extent.
  236.  
  237.    ypos:
  238.     The YPos is predictably the vertical position of the object on
  239.     the screen. The vertical position is the halfline vertical
  240.     position. This means that in interlace mode this is the "true"
  241.     vertical position on the screen. In non-interlaced modes
  242.     (non-flicker)   modes, you should multiply your Y-Pos by two and
  243.     stuff that into the object. (That's why its eleven bits, and the
  244.     height is only 10 bits.)
  245.  
  246.    type:
  247.     Lastly the object type indicates with a 0 (000) that this object
  248.     is a normal non-scaled bitmap object.
  249.  
  250.  
  251. Phrase #1 (2 of 2):
  252.  
  253.    63      56        48       40       32        24       16       8       0
  254.   +--------+---------+---------+--------+--------+--------+--------+--------+
  255.   | unused | 1stpix  |flags | idx | iwidth  | dwidth  | p | d |    <XPos>   |
  256.   +--------+---------+---------+--------+--------+--------+--------+--------+
  257.     63...57 56....49  48..45 44.38  37...28    27..18 17.15 14.12   11.....0
  258.                8bit 4bit  7bit   10bit  10bit  3bit  3bit     12bit
  259.  
  260.     Curiously there seem to be some unused bits in the top half of
  261.     this second phrase. Anyway starting from the left:
  262.  
  263.    firstpix:    Pixels to skip              ***DESTROYES ???***
  264.    flags:   How to handle the source data
  265.    index:   Index into the CLUT
  266.    iwidth:  Width of the image
  267.    dwidth:  Offset to the next line of the image
  268.    pitch:   Increment for the Datapointer
  269.    depth:   Pixeldepth of the bitmap
  270.    x-pos:   Horizontal position of the object   ***DESTROYED BY THE OP***
  271.  
  272.  
  273. 1stpix: this is a field of 8 bits that contains the number of
  274.     'bits' to skip before fetching the first pixel. This is
  275.     probably most useful for CLUT modes, where you want to
  276.     specify an offset into the first phrase to get the pixel you
  277.     want. You get the value you want to write here by calculating:
  278.  
  279.     pixelindex * bits_per_pixel (f.e. 8 for 256 color mode)
  280.  
  281.  
  282. flags:  You can tell the Objectprocessor the way it should
  283. handle the display data. These are the values you set here:
  284.  
  285.     Bit0        Bit1        Bit2        Bit3
  286.     --------------------------------------------------------------
  287.      Horizontal Flip   ReadWriteModify   Transparent   Release
  288.  
  289. A few guesses as to what each flag does:
  290.  
  291. Horizonal flip:     Lets the Objectprocessor run
  292. its path from the other end of the spritedata, which should
  293. effectively flip you sprite data.
  294. [ Since this is a hairy calculation, it is doubtful that the
  295. hardware pulls this off faultlessly with firstpix set to anything
  296. but zero ?? ]
  297.  
  298. ReadWriteModify:    The object data reads the data in the
  299. line buffer does something with the bitmap pixel value
  300. and the linebuffer pixel value and stores the result back into
  301. the linebuffer. For Crycolor the lower byte of the bitmap pixel value
  302. is sign extended and added to the lower byte of the linebuffer pixel
  303. value, thereby increasing or decreasing (depending on the sign)
  304. the intensity of the linebuffer pixel. This is a 'saturating add'
  305. meaning that you don't wrap around, but subtractions stick at 0 and
  306. additions stick at 255.
  307. The cryhues (upper byte) are mangled even more strangely, the effect
  308. could (with the right values) be like looking through a colored
  309. glass (your bitmap object with the RMW-flag set) onto the
  310. background (the other bitmap objects below it)
  311.  
  312. Transparent:        When the source pixel is zero, this
  313. pixel will not be written. This is the way to achieve
  314. transparent sprites with the GPU. (Both CLUT and non-CLUT pixels)
  315.  
  316. Release:        If cleared then the OP 'hogs' the bus for
  317. the time it takes to fetch the scanline data of the object. If this
  318. bit is set, then the bustime is shared with other processors. If you
  319. have lotsa interrupts going, this might be worthwhile.
  320.  
  321. index (idx):    Index into the ColorLookUpTable (CLUT)
  322. This information is only used for 1 - 2 or 4 bitplane objects,
  323. to determine the offset in the CLUT to use.
  324.  
  325.     1 bitplane  2 bitplane  4 bitplane
  326.         iiiiiiii          iiiiii0         iiiii00
  327.  
  328. The value is shifted left once and then used as an index into
  329. the CLUT. Note that in 2 + 4 bitplane modes not all bits are in
  330. used, because the lower bits are replaced with the pixel value.
  331.  
  332. For example in 4-bits-per-pixel mode pixel #7 and an idx value of
  333. 64 gives you an index of (64*2)+7 -> 135
  334.  
  335. So you preload the CLUT with the colors you want to use, for
  336. example green at index #241. When you want to display a small
  337. green arrow on the screen (as a pointer) for example you set
  338. your object to transparent, and the index to 120. When the
  339. object pointer fetches a set pixel, it will write the green
  340. value into the linebuffer.
  341.  
  342.  
  343. iwidth:     Tell the OP how many *phrases* to draw in each
  344. line. This is the actual number of phrases to draw, not the
  345. horizontal index to index the next line (dwidth). This is
  346. probably not just  #pixels_to_draw / bits_per_pixel, but rather
  347. the number of phrases the object spans. If a 32bit object spans
  348. two phrases you should enter a two here.
  349.  
  350. dwidth:     The horizontal phrase offset the OP should use
  351. to index to the next line. If you data is laid out in
  352. consecutive strips of horizontal data like this:
  353.  
  354. screen <destination>:
  355.     00000000000
  356.     11111111111
  357.     22222222222
  358.     33333333333
  359.  
  360. memory <source>:
  361.     00000000000111111111112222222222233333333333
  362.  
  363. then this will be just the same as <iwidth>. But if your data
  364. is laid out like this:
  365.  
  366.     00000000000xxxxx11111111111xxxxx22222222222xxxxx33333333333xxxxx
  367.  
  368. you should set <dwidth> to the proper offset so that adding
  369. <dwidth> to the phrase-address will bring you to the next line.
  370. (This might be useful for 'horizontally scrolling' objects).
  371.  
  372. depth (d):  The number of bits of each pixel. This
  373. specifies the rez of the object. You have the choice between
  374. direct pixel modes (16 or 24/32 bits) and indirect (CLUT)
  375. pixel modes. Note that using transparency effectively
  376. reduces the number of available colors by one (color #0).
  377.  
  378. Values:
  379.     0   1 bits per pixel    2 colors    CLUT
  380.     1   2 bits per pixel    4 colors    CLUT
  381.     2   4 bits per pixel    16 colors   CLUT
  382.     3   8 bits per pixel    256 colors  CLUT
  383.     4   16 bits per pixel   65536 colors    CRY
  384.     5   24 bits per pixel   16 Mio Colors   TrueColor
  385.     6   unused
  386.     7   unused
  387.  
  388.  
  389. pitch (p):  If you so desire you can organize your bitmap
  390. data in even stranger ways than one would think possible. With
  391. this value you control the datapointer that the OP uses to
  392. traverse your bitmap data. This value is added to the
  393. datapointer after the last fetch. If you use a 0 you will be
  394. always fetching the same phrase over and over again. Normally
  395. you set <pitch> to 1, to advance through memory contigously.
  396. (Note: If the designers of the OP were clever, you can save a
  397. lot of bandwidth with the background by putting an object in
  398. front of the object list that contains a single pixel bitmap
  399. with the background color and setting <pitch> to zero)
  400.  
  401.  
  402. xpos:       The horizontal position of the object on the
  403. screen (or in the linebuffer if you will)
  404.  
  405.  
  406.  
  407. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  408. 13.     This is what a scaled bitmap object looks like.
  409. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  410.  
  411. Phrase #0 (1 of 3):
  412.  
  413.    63      56        48       40       32        24       16       8    3   0
  414.   +--------+---------+---------+--------+--------+--------+--------+--------+
  415.   |       <data-address>   |    <Link-address>   | < Height >|  <YPos>  |001|
  416.   +--------+---------+---------+--------+--------+--------+--------+--------+
  417.       63 .............43         42..........24   23 ..... 14 13 ..... 3 2.0
  418.          21 bits             19 bits        10 bits     11 bits  3 bits
  419.  
  420.     Except for the type, which is different, this is just
  421.     the same as the first phrase of the bitmap (non-scaled)
  422.     object.
  423.  
  424.  
  425. Phrase #1 (2 of 3): This is the same as the the 'bitmapped' object
  426.  
  427.  
  428. Phrase #2 (3 of 3):
  429.  
  430.    63      56        48       40       32        24       16       8       0
  431.   +--------+---------+---------+--------+--------+--------+--------+--------+
  432.   |                  unused                      | remain | VScale | HScale |
  433.   +--------+---------+---------+--------+--------+--------+--------+--------+
  434.                                    23...16  15...8   7...0
  435.  
  436.   remainder:    Keeps the VScale remainder  ***DESTROYED BY THE OP***
  437.   v-scale:      Vertical scaling factor
  438.   h-scale:  Horizontal scaling factor
  439.  
  440.  
  441.   The scale is a fractional representation, using 3 bits for the integer
  442.   part and 5 bits for the fractional part. Or in ASCII-Graphics:
  443.  
  444.     76543210    00100000 or 0x20 is 1.0
  445.     iiifffff    00010000 or 0x10 is 0.5
  446.  
  447.   The remainder is used by the objectprocessor for the vertical scaling,
  448.   as a memory place. You should initialize it to 0.5 for best results,
  449.   although in a lot of democode its initialized to 1.0.
  450.  
  451.  
  452. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  453. 14.        The elusive GPU-object
  454. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  455.  
  456. Phrase #0 (1 of 1):
  457.  
  458.    63      56        48       40       32        24       16       8    3   0
  459.   +--------+---------+---------+--------+--------+--------+--------+--------+
  460.   |                            unknown                                  |010|
  461.   +--------+---------+---------+--------+--------+--------+--------+--------+
  462.  
  463.    Predictably just the opcode is used in this object type
  464.  
  465.  
  466. A speculation might be that the GPU object sends an Interrupt to the GPU
  467. and puts itself into sleep mode (really??) until the GPU has done its
  468. refresh of the Linebuffer. Maybe the OP continues and just gives the GPU
  469. a chance to sync. Maybe there's a subroutine address encoded in the
  470. object... Who knows.
  471.  
  472. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  473. 15  You can also look at the object in terms of C-structs, that's how
  474.     they'd look like.
  475. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  476.  
  477. /* DON'T USE THESE BITFIELDS WITH ANYTHING ELSE THAN A
  478.    ***GOOD*** C-COMPILER AND A MOTOROLA PROCESSOR
  479. */
  480.  
  481.  
  482.     #define byte    unsigned char
  483.     #define word    unsigned short
  484.     #define lword   unsigned long
  485.     #define phrase  unsigned long long
  486.  
  487.  
  488.     typedef struct
  489.     {
  490.         lword   data:21;
  491.         lword   link:19;
  492.         word    height:10;
  493.             word    ypos:11;
  494.         word    type:3;
  495.     } bitmap_obj_phrase_0;
  496.  
  497.  
  498.     typedef struct
  499.     {
  500.        word   unused:7;
  501.            word   firstpix:8;
  502.        word   flags:4;
  503.        word   index:7;
  504.        word   iwidth:10;
  505.        word   dwith:10;
  506.        word   pitch:3;
  507.        word   depth:3;
  508.        word   x_pos:12;
  509.     } bitmap_obj_phrase_1;
  510.  
  511.  
  512.     typedef struct
  513.     {
  514.        lword  unused:24;
  515.        word   remainder:8;
  516.        word   v_scale:8;
  517.        word   h_scale:8;
  518.     } scale_obj_phrase_2;
  519.  
  520.  
  521.     typedef struct
  522.     {
  523.         lword   unused:21;
  524.         lword   link:19;
  525.         word    conditioncode:2;
  526.         word    unused:8;   ;; maybe index to register ?
  527.             word    ypos:11;
  528.         word    type:3;
  529.     } branch_obj_phrase_0;
  530.  
  531.  
  532.     typedef struct
  533.     {
  534.         phrase  unused:61;
  535.         word    type:3;
  536.     } stop_obj_phrase_0;
  537.  
  538.     typedef struct
  539.     {
  540.         phrase  unknown:61;
  541.         word    type:3;
  542.     } gpu_obj_phrase_0;
  543.  
  544.  
  545.     typedef struct
  546.     {
  547.        stop_obj_phrase_0    p0;
  548.     } stop_obj;
  549.  
  550.  
  551.     typedef struct
  552.     {
  553.        branch_obj_phrase_0  p0;
  554.     } branch_obj;
  555.  
  556.  
  557.     typedef struct
  558.     {
  559.        gpu_obj_phrase_0 p0;
  560.     } gpu_obj;
  561.  
  562.  
  563.     typedef struct
  564.     {
  565.        bitmap_obj_phrase_0  p0;
  566.        bitmap_obj_phrase_1  p1;
  567.     } bitmap_obj;
  568.  
  569.  
  570.     typedef struct
  571.     {
  572.        bitmap_obj_phrase_0  p0;
  573.        bitmap_obj_phrase_1  p1;
  574.        scale_obj_phrase_2   p2;
  575.     } scale_obj;
  576.  
  577.  
  578.  
  579. OPEN QUESTIONS:
  580.  
  581.     Klaus thinks that the OP is smart, and that therefore the
  582.     nearest object comes first. Nat! thinks that the OP is
  583.     stupid and that the background comes first.
  584.  
  585.     If Klaus is right, then the OP with nontransparent objects
  586.     runs at a rather constant (if a background is used) out at:
  587.  
  588.         hrez * vrez * refresh * average_bits_per_pixel
  589.         ---------------------------------------------- phrases/s
  590.                     64
  591.  
  592.     which is GOOD. For 320x200x60x16 this means 0.916 Mphrases/s
  593.  
  594.  
  595.     If Nat! is right then the OP needs:
  596.  
  597.         #sprites * average_sprite_size
  598.         ------------------------------ phrases/s
  599.                64
  600.  
  601.     This is exceedingly bad...
  602.  
  603.  
  604.  
  605. NEEDED STUFF:
  606.     Need to document the logic setting up objects, that cross
  607.     boundaries (especially the scaled bitmaps)
  608.  
  609.  
  610.  
  611. --- uugate 0.40 (SunOS 4.1.3)
  612.  * Origin: Internet gateway [cindy] (2:200/427.1)
  613.