Recently RoccoLox and I have been working on adding a ZGC4 machine to QEMU. It's been an interesting learning experience, since neither of us had done much with emulation / reverse engineering hardware prior to this. I'll provide a little write-up of some of the process, but first here's some eye candy:



QEMU integrates quite nicely with gdb, which made debugging a lot easier. Additionally, the emulator will print data the calculator sends over UART to the console:



Process
Turns out before you can make an emulator you have to actually know what you're emulating, so the first thing we did was identify the peripherals. Some of the stuff on the board was more obvious (everything that was labeled), but a few things proved to be trickier. By dumping the firmware (shoutout to this little tool that was super helpful!) and looking through a decomp in Ghidra, I was able to make a guess as to the LCD controller model and identify the remainder of the peripherals, along with the pins / interfaces they were connected to. Here's what we came up with:

  • MCU is a GD32F470ZKT6
  • External flash is a Winbond W25Q64JV on SPI5
  • External RAM is an ISSI IS42S16400J on EXMC SDRAM
  • UART is on USART1
  • LED uses PA6-8 for BGR respectively
  • USB is using the USBFS interface
  • The display controller seems to be in the ST7789 family. The command register is at 0x60000000 and the data register is at 0x60000002
  • The battery gauge seems to be an STC3100 on I2C0

Since the GD32 is essentially an STM32 clone, we were able to re-use some of the pre-existing STM32 code in QEMU as a starting point. Additionally, the Numworks also has an ST7789 display controller, so we were able to work off the pre-existing numworks-qemu fork for a few things.

Status
While it's certainly by no means complete, most general OS stuff seems to be working as expected. We haven't been able to test on the latest firmware yet, though it does seem to work at least up v2.24.0. There are a few things that most certainly do not work right now, the obvious ones being anything USB related and RTC (which is completely un-implemented). So for now the clock is permanently stuck in 1999 :P



Interestingly, we also found that the HW version (presumably ZGC3 vs ZGC4) is determined based on the value of PB11, which messed us up initially since we hadn't accounted for that and the emulator expected a different keypad layout. I'm not sure what the other differences between the ZGC3 and 4 are, but for now you can spoof either hardware version if you feel like it!

Using / GitHub etc
The source is available on GitHub: https://github.com/EzCE/qemu-zero
Since this was our first attempt at working with QEMU, the code is likely a bit messy. Feel free to contribute or give any feedback about stuff we should improve / fix.

You can build it following the instructions for building QEMU here. It's pretty straightforward, just install the dependencies required and then:

Code:
./configure --enable-sdl --target-list=arm-softmmu
make


To run it, you'll need both a dump of internal flash from 0x08000000 - 0x082FFFFF, and a dump of the external flash (All 8MB. Doesn't seem to be memory mapped so you need to connect to the chip). Then run:

Code:
./qemu-system-arm -M zgc4 --kernel <internal flash>.bin -drive file=<external-flash>.bin,if=mtd,format=raw
This is so awesome!! I’m excited to see where development goes with this and maybe we can get a new dedicated emulator!
It's great to see the progress on this!
That reminds me, there are a lot of QEMU forks out there for calculators (and most of them derived from my original N0100 work it seems):

Too bad it's scattered all over the place and bitrotting... It'd be nice if there was one calculator-oriented QEMU fork maintained with all of that.
I've made some scripts to simplify some tasks when using the emulator: https://github.com/TIny-Hacker/zgc4-flash-tools

The first script (build-main-flash.sh) can be used to generate a usable internal flash file without dumping one from physical hardware. It requires the v2.25.0 flasher update file, available in Zero's Discord server. The flasher update file contains the flasher code with a 32 byte header, so by stripping the header and expanding it to 3MB it can be used as an internal flash file. You'll have to provide an 8MB external flash file (this can be empty - it'll be formatted by the flasher / emulator) with a firmware update file, which the flasher will then detect and install, giving you a working internal flash.

The second script (send-file.sh) can be used to copy a file to the filesystem on an external flash image. It requires GNU Mtools for working with the filesystem. This saves the trouble of manually extracting the filesystem, mounting it, moving files around, and then rebuilding the external flash file. The official simulator lacks a way to transfer files and there's no on-calc Python editor, so this makes it a lot easier to test Python programs (and take screenshots!) šŸ™‚

Here's LessThanPro's Zejewled game in action:


Edit:
It appears that the latest firmware version (2.27.1) has switched to using littlefs rather than a FAT based filesystem, so I'll need to rework the send-file script accordingly. It should still work fine with older firmware for now though.
With some help from LessThanPro, I've got the [on] button working and mapped to the F12 key. For documentation purposes, [on] is handled differently than the majority of the keypad and is connected to GPIOA Pin 15 (configured in pull-up mode and as an interrupt line).
Really impressive effort guys! How long would you say you've been working on this for?
tr1p1ea wrote:
Really impressive effort guys! How long would you say you've been working on this for?


Thanks! It's been off and on, but the bulk of work has mainly been the reverse engineering side of things. Since a lot of the components are fairly standard and have good documentation / pre-existing QEMU implementations, making the QEMU machine didn't take that long.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement