![Image 1 — [DS]Building a custom Engine Dashboard for My Mx-5 Miata on a Nintendo Ds](https://preview.redd.it/zg71awwtqd2h1.jpg?width=3072&format=pjpg&auto=webp&s=99a9aec539b28cf53654b1a262b47f6703946ef0)
![Image 2 — [DS]Building a custom Engine Dashboard for My Mx-5 Miata on a Nintendo Ds](https://preview.redd.it/q0wu442vqd2h1.jpg?width=3072&format=pjpg&auto=webp&s=78b35f279ce0392812ae05bb6b77efb973886da7)
![Image 3 — [DS]Building a custom Engine Dashboard for My Mx-5 Miata on a Nintendo Ds](https://preview.redd.it/63pgbvfvqd2h1.jpg?width=3072&format=pjpg&auto=webp&s=fc217bea570d5aca42ed422a986a02203efb9071)
![Image 4 — [DS]Building a custom Engine Dashboard for My Mx-5 Miata on a Nintendo Ds](https://preview.redd.it/lra87zzvqd2h1.jpg?width=3072&format=pjpg&auto=webp&s=b652e16d695ba89fd1471173abe1767c1d2ff10c)
![Image 5 — [DS]Building a custom Engine Dashboard for My Mx-5 Miata on a Nintendo Ds](https://preview.redd.it/lf6iwogwqd2h1.jpg?width=1845&format=pjpg&auto=webp&s=4447819370921a96e051b2e053117a19faae24bb)
![Image 6 — [DS]Building a custom Engine Dashboard for My Mx-5 Miata on a Nintendo Ds](https://preview.redd.it/34odabqwqd2h1.jpg?width=3072&format=pjpg&auto=webp&s=9e0d4a43f272af4e3848766a0e87c0e788243c5c)
[DS]Building a custom Engine Dashboard for My Mx-5 Miata on a Nintendo Ds
Hey everyone,
I'm a proud owner of a classic Mazda MX-5 Miata, and instead of installing modern aftermarket gauges that ruin the 90s interior look, I decided to give my old Nintendo DS Lite a permanent home on my dashboard.
The DS receives UDP packets from an ESP32 in the engine bay (reading Oil Temp, Oil Pressure and coolant Temp.) and displays everything in real-time. I'm writing this entirely in C using devkitARM and the gl2d library.
To keep the memory footprint extremely low and ensure a locked 60 FPS, I am drawing almost all UI elements, gauges, and graphs directly via code loops (glBox, glLine, etc.). I am using spritesheets only for the animated 3D car models (like the G-Force indicator and startup sequence); absolutely everything else is code-rendered.
However, I've hit a major roadblock regarding the Dual-Screen rendering and I'm hoping someone can help me Out.
Since the DS only has one 3D core, I am using the standard Display Capture method to achieve hardware-accelerated rendering on both screens. My main loop alternates rendering between the top and bottom screen every frame:
swiWaitForVBlank();
while(REG_DISPCAPCNT & DCAP_ENABLE);
if((frame & 1) == 0) {
lcdMainOnBottom();
vramSetBankC(VRAM_C_LCD);
vramSetBankD(VRAM_D_SUB_SPRITE);
REG_DISPCAPCNT = DCAP_BANK(2) | DCAP_ENABLE | DCAP_SIZE(3);
drawDashboard();
} else {
lcdMainOnTop();
vramSetBankD(VRAM_D_LCD);
vramSetBankC(VRAM_C_SUB_BG);
REG_DISPCAPCNT = DCAP_BANK(3) | DCAP_ENABLE | DCAP_SIZE(3);
drawMenu();
}
glFlush(0);
The Bug: I am experiencing severel "screen swapping" issues (both screens freezing, or the top and bottom screen rapidly flickering/swapping back and forth).
This only happens when the main loop gets stalled by blocking operations:
When I open my internal "Data Logger" menu, which uses libfat to fopen and parse a large .csv file from the SD card.
When the WiFi connection to the ESP32 drops and Wifi_InitDefault() or Wifi_AutoConnect() tries to re-initialize the connection in the background.
It seems that whenever the CPU is blocked by SD I/O or WiFi, swiWaitForVBlank() goes out of sync with the physical refresh rate, causing the VRAM bank swapping and REG_DISPCAPCNT to completely mess up the frame parity.
My Question: What is the standard/best-practice way to handle heavy, blocking FAT/WiFi I/O without breaking the strict (frame & 1) VBlank alternation required for dual-screen 3D capture? Do I need to move the FAT reads to an asynchronous timer, or is there a way to safely "pause" the screen swapping hardware registers before initiating a heavy SD card read, and resume it afterwards without corrupting the VRAM banks?
Any advice on how to handle synchronous stalls while doing display captures would be highly appreciated!