Show HN: Gameslab, a FPGA powered handheld game console
craigjb.com
craigjb.com
I love that retro game emulation has spawned this massive culture of super complicated and roundabout ways to replicate $50 consoles. It’s everything I love about DIY projects in general.
I actually didn't originally intend it to be for retro game emulation, more for experimenting with custom hardware for each game and with 3D acceleration hardware. But, the idea of putting retro emulators in the FPGA fabric is so easy.
In fact, over the holidays, I'm working on porting some of the MiSTer FPGA retro emulators to the Gameslab: https://github.com/MiSTer-devel/Main_MiSTer/wiki
It's 64k ram 8-bit avr instruction set and a blitter doing a variety of data formats. It's not quite ready for prime-time yet, but you can see some of it online. The virtual hardware registers can be seen at https://k8.fingswotidun.com/static/docs/io_registers.html It might be quite amenable to something like this.
The read area and the write area are separate spaces. It is strictly main RAM to frame buffer.
It is pixel based instead of bit-planes, so a lot of the features of the Amiga blitter aren't required. The minterms , multiple sources and the shifter were great for masking and sliding the bits to the right place, but once you go to chunky pixels they aren't so useful.
It does pixel format conversions to convert various compact data forms to colour graphics. 8 pixels per byte in 2 colours, 4 pixels per byte in 4 colours, 3 pixels per byte (where each 3 pixel block can have 4 colours from one of 4 micropalettes), 2 pixels per byte in 16 colours.
It supports Cell modes were it can decode cells of pixels from data, mode 0 has 3x3 blocks described in two bytes each. Cells may have any two of 16 colours. mode 1 is quite similar to the NES tiled graphics mode with 8x8 cells chosen by index to a table and individually coloured and flipped.
I don't have a line drawing option but I was wondering about having some registers to accumulate with each pixel written and if the accumulators overflow the X or Y pixel position increments. It would add some rudimentary skewing for little cost.
A lot of it comes down to the fact that the blitter is doing much of the job of the display hardware in other systems. The frame buffer is the output device with no smarts at all.
Analogue does great products usually so I can't wait for it.
(I'm not affiliated at all with them, I just love their products).
You're slowly becoming a software guy after all...
Just mastering Ki-CAD is an accomplishment. I learned circuit design with P-CAD. And it was anything else but intuitive. Playing around with Ki-CAD reminded my of thise days.
Can you recommend a good Ki-CAD tutorial?
Can you elaborate a little bit on the mistakes you made and what led to the choices you made? E.g. first time read about Das U-Boot.
To be honest, I really don't know a good KiCad tutorial. I kind of just banged myself against it until I learned. But, I had previous experience with Eagle, Altium, and Cadence Allegro.
Das U-Boot is the embedded bootloader and is pretty standard for embedded ARM systems (and others! https://github.com/u-boot/u-boot/tree/master/arch).
On a dev-board prototype before, I had also used Buildroot (https://buildroot.org) to create the minimal root filesystem image. This time around, I decided to use Debian since it makes installing packages I want much easier. For example, I can just apt-get install the USB wifi firmware packages instead of hunting them down and including in a manually generated image. It's still using a custom compiled kernel though, since I have custom drivers for things like the graphics hardware.
I'm trying to use Rust for as much as possible (I like Rust a lot). The STM32L0 runs rust, I bodged together a framebuffer driver in Rust, and the games in userspace are also in Rust. I'll post about the Rust framebuffer driver at some point.
Shout out to the Real Time For the Masses project (it's an RTOS) I used: https://github.com/rtfm-rs/cortex-m-rtfm
P.S: I'm the ultimate noob on these topics.
https://www.youtube.com/watch?v=vaCVh2SAZY4
(first video of a series of 10)
Curious, can you both execute code on the FPGA and simultaneously write other parts of it? Or do you have to write it in one go, than "start it"? And in the latter case, can you write it incrementally or do you have to erase it first?
Every time I've been involved with one, it's been basically a CPU with various accelerators for specific functions done in the fabric, with the design being CPU-forward. I've never seen anyone approach them from a FPGA-forward angle. Interesting!
With regard to Verilog/VHDL, you'll have to learn at least verilog at some point, but I stay away as much as I can. SpinalHDL (based on Scala) is my goto. Some people like the Python based ones like migen, but I like me some strong typing.
I have a couple of blog posts about starting to put together a Gameboy CPU on craigjb.com (not finished yet).
It's verilog, but you're going to have to learn some anyway. All of the new-generation HDLs compile down to verilog, which then goes into the various synthesis tools.
I had it fabricated for me by a company by Front Panel Express. In a DIY audiophile forum I saw people using them, and if they're good enough for audiophile gear, probably good enough for me :P
Basically the holy grail of emulation... Not-emulation.
First time I’ve seen a real project using this.
How far is embedded rust away from “prime time” you think?
Also, the STM32 is a system supervisor, did it really need an RTOS?
I'm actually working on a post about restarting my firmware using the latest and greatest (I started working on this firmware over a year ago).
I used the RFTM real-time OS (RTOS) because it's super light-weight and handy for checking at compile time that my interrupt handlers don't cause conflicts. It's really a nice framework for any event-based firmware (a big chunk).
Most game engines are about throughput and I don't think you'd see a lot of use for them, heck we had a hard enough time using the PS3 back when I was in the industry and that wasn't nearly as wide as a FPGA can be.
Good work!