Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // this is the (single row) inner loop of a matrix plot function
- // i didn't write the outer loop bc i still got stuff to do today
- // the Super FX has an instruction, `merge`, which is designed for texture
- // fetching, but how it relates to texture fetching isn't obvious
- // so here's an explanation
- // the instruction:
- // merge %r0;
- // does the following operation:
- // %r0 = (%r7 & $ff00) | (%r8 >> 8)
- // (there is no way to pick registers other than %r7 and %r8 sadly)
- // in other words, if %r7 = $aabb and %r8 = $ccdd,
- // %r0 will come out as $aacc.
- // this lets you use %r7 and %r8 as texture coordinates into a 256x256
- // texture bank, with 8 bits of fraction that allow you to move
- // less than a pixel at a time.
- // note that %r7 is the vertical and %r8 is the horizontal coordinate
- // (so, in the loop below, if %r4 = $0080, it will move %r8 one pixel
- // right in the texture for every two pixels plotted,
- // so every pixel will be plotted twice, making the texture twice as wide)
- // in the loop below, %r3 serves the same purpose as the mode 7 C parameter,
- // and %r4 serves the same purpose as the mode 7 A parameter.
- // parameters B and D are part of the outer loop so screw them.
- // we use this to fetch a pixel from the rom buffer.
- // the rom buffer works by setting the romb to the bank the data is in,
- // kind of like the data bank on the snes cpu,
- // and then setting %r14 to the lower 16 bits of the address.
- // after %r14 is set, the cpu starts fetching a byte from rom,
- // which you can put in a register using `getb %rN` (to get a byte)
- // or use as the plot color using `getc`.
- // fetching a byte takes 5 cycles, and if it's not ready by the time
- // the cpu hits the get instruction, it just stalls for a while til it is
- // ready.
- // so you want a few instructions between setting %r14 and getting the data.
- // here we use:
- // merge %r0;
- // and %r0, %r5;
- // add %r14, %r0, %r6;
- // to calculate our fetch address.
- // this treats the whole romb as a 256x256 texture, but we get a 32x32
- // section (by masking with r5) and the upper left corner is
- // (X,Y) where %r6 = $YYXX.
- // this means that the area outside the texture is filled with copies of the
- // texture, whereas in a game like YI you would want them filled with
- // transparency, but that's more annoying to write so i didn't
- // you can also put textures in RAM instead of ROM, which lets you compress
- // them (i'm pretty sure YI compresses them tbh),
- // but there's no RAM prefetcher and there is a ROM prefetcher
- // so having the textures in ROM is faster
- ldw %r5, #$1f1f; // %r5 = mask for a 32x32 texture
- // set up the loop
- merge %r0; // %r0 = merged UV coordinates
- and %r0, %r5; // mask
- add %r14, %r0, %r6; // request the first pixel from the rom buffer
- mov %r13, %r15; // set loop address
- add %r7, %r3; // advance our texture's U coordinate
- add %r8, %r4; // advance our texture's V coordinate
- merge %r0; // %r0 = merged UV coordinates
- and %r0, %r5; // mask
- getc; // get the pixel color from the rom buffer
- add %r14, %r0, %r6; // request the next pixel from the rom buffer
- loop; plot; // plot our pixel and loop
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement