Sunday, May 19, 2019

ESP8266 GameBoy Emulator, attempt.

I had an idea, to port a GameBoy emulator to an ESP8266 with an LCD screen.
found a good candidate for porting Peanut-GB, it's only a single file (.H) and with
plenty of examples.



Very little setup required and a single lcd_draw_line callback, implement LCD drawing
there and voila, GB emulator on the ESP8266 (node MCU clone), but it seems
the raw power of C is not sufficient for this task, and the LCD library
that I've chosen (TFT_eSPI) and modified was also insufficient to make
the emulator run at adequate speeds.

Games are stored in the flash using bin2hex.

The LCD in use is ST7789 based 240x240 connected to the SPI bus running at 40 Mhz.

Pinout:
NodeMCU - LCD
GND -> GND
3.3V -> VCC
3.3V -> BLK
D3 -> DC
D4 -> RES
D5 -> SCL
D7 -> SDA

So what do we have:
1. The emulator runs, tried with "super mario land", Tetris and a demo.
2. Uhm... Profit ?

What we don't have.
1. Good frame time, each frame takes between 70~200 ms which translates between 14~5 FPS.
2. Audio (There was not enough time for smooth frame rates.. so ...)
3. Key input (Yeah.. no..)


It seems that no matter how hard I tried to optimize the code the drawing part
would always lag, if we remove the LCD part, the core did have enough
time to emulate the game, but I think an emulator without a screen
is not a good emulator :)





What did I try to do:
1. ESP runs at 160 MHz, I can try to use NO_SDK (run at 340 Mhz) by CNLohr but the SPI bus is        affected by it.
2. Optimize the gb_draw_line up the wazoo, replaced all multiplications with right shifts.
3. Added per line hash drawing capabilities, so if the pixels of the line did not change, don;t draw            them, helpful with static games, not so much with scrolling.
4. Moving the game code to DRAM, did not produce significant speed ups. *
5. DynaRec? will probably require a lot of RAM and we have only 32000 bytes left.

* One of the issues that I've encountered is that the game needs to reside on the flash,  but because of alignment issues (the game is a an array of bytes [8-bit] but the memory of the ESP is 32Bit) the reading is slower.



Everything was developed using Sloeber, highly recommended for Android development.
Sources: primary project.
Sources: TFT_eSPI modified library
Hope that helps anybody.

R.