Advertisement
Guest User

superfx matrix thing

a guest
Feb 28th, 2020
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.22 KB | None | 0 0
  1.     // this is the (single row) inner loop of a matrix plot function
  2.     // i didn't write the outer loop bc i still got stuff to do today
  3.    
  4.     // the Super FX has an instruction, `merge`, which is designed for texture
  5.     // fetching, but how it relates to texture fetching isn't obvious
  6.     // so here's an explanation
  7.     // the instruction:
  8.     //   merge %r0;
  9.     // does the following operation:
  10.     //   %r0 = (%r7 & $ff00) | (%r8 >> 8)
  11.     // (there is no way to pick registers other than %r7 and %r8 sadly)
  12.     // in other words, if %r7 = $aabb and %r8 = $ccdd,
  13.     // %r0 will come out as $aacc.
  14.     // this lets you use %r7 and %r8 as texture coordinates into a 256x256
  15.     // texture bank, with 8 bits of fraction that allow you to move
  16.     // less than a pixel at a time.
  17.     // note that %r7 is the vertical and %r8 is the horizontal coordinate
  18.     // (so, in the loop below, if %r4 = $0080, it will move %r8 one pixel
  19.     //  right in the texture for every two pixels plotted,
  20.     //  so every pixel will be plotted twice, making the texture twice as wide)
  21.     // in the loop below, %r3 serves the same purpose as the mode 7 C parameter,
  22.     // and %r4 serves the same purpose as the mode 7 A parameter.
  23.     // parameters B and D are part of the outer loop so screw them.
  24.     // we use this to fetch a pixel from the rom buffer.
  25.     // the rom buffer works by setting the romb to the bank the data is in,
  26.     // kind of like the data bank on the snes cpu,
  27.     // and then setting %r14 to the lower 16 bits of the address.
  28.     // after %r14 is set, the cpu starts fetching a byte from rom,
  29.     // which you can put in a register using `getb %rN` (to get a byte)
  30.     // or use as the plot color using `getc`.
  31.     // fetching a byte takes 5 cycles, and if it's not ready by the time
  32.     // the cpu hits the get instruction, it just stalls for a while til it is
  33.     // ready.
  34.     // so you want a few instructions between setting %r14 and getting the data.
  35.     // here we use:
  36.     // merge %r0;
  37.     // and %r0, %r5;
  38.     // add %r14, %r0, %r6;
  39.     // to calculate our fetch address.
  40.     // this treats the whole romb as a 256x256 texture, but we get a 32x32
  41.     // section (by masking with r5) and the upper left corner is
  42.     // (X,Y) where %r6 = $YYXX.
  43.     // this means that the area outside the texture is filled with copies of the
  44.     // texture, whereas in a game like YI you would want them filled with
  45.     // transparency, but that's more annoying to write so i didn't
  46.     // you can also put textures in RAM instead of ROM, which lets you compress
  47.     // them (i'm pretty sure YI compresses them tbh),
  48.     // but there's no RAM prefetcher and there is a ROM prefetcher
  49.     // so having the textures in ROM is faster
  50.  
  51.     ldw %r5, #$1f1f;    // %r5 = mask for a 32x32 texture
  52.     // set up the loop
  53.     merge %r0;          // %r0 = merged UV coordinates
  54.     and %r0, %r5;       // mask
  55.     add %r14, %r0, %r6; // request the first pixel from the rom buffer
  56.  
  57.     mov %r13, %r15;     // set loop address
  58.     add %r7, %r3;       // advance our texture's U coordinate
  59.     add %r8, %r4;       // advance our texture's V coordinate
  60.     merge %r0;          // %r0 = merged UV coordinates
  61.     and %r0, %r5;       // mask
  62.     getc;               // get the pixel color from the rom buffer
  63.     add %r14, %r0, %r6; // request the next pixel from the rom buffer
  64.     loop; plot;         // plot our pixel and loop
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement