Remix.run Logo
▲ Lerc 18 hours ago

I've been meaning to show you some of the stuff I have been working on.

This is my scanline at a time renderer.

https://fingswotidun.com/cruft/2350LCD_5.mp4

The text mode is generated per Scanline using an ARM core, Tile, image, and sprite layers are all DMA+PIO generated.

So a Tile Layer is

         TileMapDMA
             |
             V
        TileIndexPIO
             |
             V
        TileDataDMA
             |
             V
     UnpackPixelIndex_PIO
             |
             V
      PaletteReadDMA
             |
             V
      TransparencyPIO   <-- ScanlineBufferReadDMA
             |
             V
   ScanlineBufferWriteDMA    (Yes this was as hard to debug as it looks)
To do the entire tile map with paletted tileset happens in a single chained DMA operation, the other layers are a little simpler. It could generate the entire display without using the CPU, but the memory for the display Descriptors would take up too much memory, so there is a simple interrupt at the start of each scanline that updates the pointers in the DMA descriptors for the source and destination addresses that change per scanline.

I did have a text mode running without CPU as well but it was cumbersome due to the attribute color lookup adding another map lookup. Now it is spending just a little CPU time per scanline to do the ReadChar, Read Attribute, read Font to convert it into a 1 bit-per-pixel image with a color per byte.

Performance is better that way, even if it does make a little more work for the CPU, the scanline renders quicker. Since they all render into the single scanline buffer, you can do as many layers as you have time for, so using no CPU is no good if it still takes too long.

▲raphlinus 7 hours ago | parent [-]

That's quite cool. I haven't dug deep into using the PIO but it clearly has potential, as shown by Linus Åkesson's demo work.