TANGLEWOOD vs. the AtGames Flashback Console
Moving on from the – thankfully almost resolved – troubles of the AtGames Firecore, my QA team and I continued running through our stash of other weird and wonderful Mega Drive clone consoles, when once again we were rudely interrupted by the postman with another AtGames machine. You can thank our friends over at Bitmap Bureau for this one – the makers of Xeno Crisis, another successfully Kickstarter funded game for the world’s greatest videogame console. We’ve been pooling our resources together to help our projects along, and they’ve sent us an AtGames Flashback HD to play with!
It’s an entirely different design to the Firecore, right from the ground up. It looks more the part, a slightly shrunken Mega Drive 1-style casing, which houses an ARM-based Android system (as opposed to the Firecore’s proprietary probably-a-system-on-chip core) running a software emulator this time, with HDMI output pushing 720p, bluetooth gamepads, a scanline filter, and a slick new menu system. Nice to see things have improved! The audio from the built-in games sounded crisp and in tune, and the new HDMI output was a game changer with regards to visual quality, so we had high hopes for TANGLEWOOD running on it. How naive of us…
TANGLEWOOD fired up in complete silence. No intro theme, no menu UI sounds, nada, until we started the sound test and noticed that PCM sound effects and PSG sound was working. FM emulation was DOA, then. At least the PSG was in tune!
It was probably sensible to assume that we’d have to start over with our diagnostics, since the system is completely different from the Firecore so none of our previous findings would be of any use. We gave those special registers a quick poke just in case the manufacturers had carried over the concept for convenience, but there was no response.
Cracking open the case to look for clues immediately revealed an unexpected aide – the board was straight-up sporting a mini USB port!
Since it’s an Android based system, and we are wishful thinkers, we hooked it up to ADB to see if would respond, and to our surprise it did, root and all! A quick Google search showed this wasn’t new information (should have looked there first…) and the machine has already had a bit of probing from the SEGA fan community, but unfortunately it was all related to getting more games on the machine; nothing revealed anything about the emulator powering its games, and no sign of any other games suffering from the same problem as ours. We dumped the whole flash to poke around with and closed it back up.
The first thing to check was if any of its built-in games had been modified to work around any issues. With the flash dump to hand we were able to extract the ROM files, and started firing each one up in our modified megaEx build to log any unknown register pokes or other out-of-the-ordinary behaviour. Unlike our Firefore diagnostics, this unfortunately showed nothing.
The next thing to check was if any other games in our library suffered from the same issue. Popular games probably would have shown up in Google results if they had compatibility problems, so it was wise to start with some lesser known titles. We have quite the collection of homebrew carts! We tried things like Daytrip, Escape 2042, and some feature test carts, which all worked, but Miniplanets was silent!
Miniplanets and TANGLEWOOD share a common denominator: they both use the Echo Sound System from Sik – a rather superb Z80 driver for music, SFX, and PCM playback for the Mega Drive. Echo also comes with its own test program called Echoster, so we fired that up, and verified it suffered from the same issue.
Luckily, Echo is open source. Unluckily, I’ve never touched a line of Z80 assembly in my life, and those of you who already follow my blog will know I stopped writing devblog posts when I got to the PSG chip – I’ve never actually touched the YM2612 either! One 12 hour crash course in Z80 later (thanks, everyone at Plutiedev!) and I was totally not ready to track down a bug in a language I barely knew, on a chip I barely knew, on a clone I barely knew, at 3 o’clock in the morning. The first issue was figuring out how to debug anything on the Z80, since it has limited ways with which to communicate with the 68000 – it would require some sort of status byte or command queue to send data back to the 68000 to display info on screen. With limited time, I needed some debug output – or at least some way to identify if a particular line of code had been hit – available from the Z80 itself. It’s capable of sound output, so how about some sound queues to tell me if a condition was met? It’s primitive, sure, but it does the job.
With a PlayPiano routine written, I got a piano note when interesting code was hit! Jog on, printf()!
From there I was able to determine which parts of the codebase were being executed within Echo, and check some assertions – the initialisation, instrument loading, and note on/off routines were all being called. One thing I’d noticed was that once my debug piano note had played, all subsequent Note On events from that channel also triggered the same note, which meant that the AtGames was fully capable of producing sound output from Echo, but the instrument data didn’t seem to be written (or overwritten, after my piano had been loaded).
After some head scratching and fruitless attempts at tinkering with the instrument loading code, this desperate attempt at getting an answer worked:
ex af, af' ; Backup A+F ld c,iyh ; Load top byte of IY ld a,c ; To register A cp $40 ; Check it's $40 jp z,.ok ; If correct, bail .piano: call Piano ; IY is not $40XX .ok: ex af, af'
On a genuine Mega Drive, this code ran silently. On the Flashback, it played a piano note.
Interesting. For those who have been following along with my assembly adventures, this should be quick to explain – the Z80 has a bunch (actual terminology) of 8-bit registers used for arithmetic and counters, and a handful of 16-bit registers used for addresses. The 16-bit registers have pairs of 8-bit counterparts allowing access to the upper or lower byte. For example, IY is a 16-bit register, IYH allows access to the top byte (IY High), IYL allows access to the bottom byte (IY Low).
In Echo, the YM chip is accessed via four ports – $4000 and $4001 for modifying parameters of channels 1-3, and $4002 and $4003 for modifying channels 4-6. During Echo’s initialisation, this happens:
ld iyh, $40
This keeps $40 in the upper byte of the IY register for the entirety of the program, and the lower byte is set to $00, $01, $02 or $03 when needed, depending on the channel being accessed.
It turns out the AtGames Z80 emulator doesn’t correctly emulate loading to/from IYH! Another quick test determined that it does, however correctly emulate loading to/from IYL. The simple fix to the problem is just to initialise the IY register in full:
ld iy, $4000
Easy! TANGLEWOOD now boots up with the main menu playing, and all is well! Almost. Once again, the SSG-EG feature of the YM has not been emulated in this machine, resulting in the same screeching and whining as the Firecore when playing notes configured with it.
Thankfully, we already have a simple way to test if we’re running on this machine and disable SSG-EG during initialisation – just try accessing that IYH register:
ld iy, $1234 ld iyh, $40 ld a, iyh cp $40 jp nz, .disableSSGEG
And that’s a wrap!