Posts for Alyosha

Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
Thanks to RetroEdit for providing a resync, one of the Warioland 4 runs has now been console verified. Awesome! RetroEdit's resync workflow is a huge advancement and should greatly accelerate console verification of GBA games in the future. Cool stuff happening all around. Link to video
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
It looks like GBAHawk is not making a correct save file here, which is probably why console verification fails. I'm going to look into this and see if I can get a fix and hopefully get this verified.
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
GoddessMaria wrote:
Thanks so much! So... after floundering about like an idiot, I managed to get my movie to play on console. Unfortunately said movie, Sonic Advance, desynced at the start in Secret Base Zone Act 2 on console. It played back fine on emulator, though, which makes me wonder if there's additional timing differences not being accounted for or cart reading issues. Link to video
Cool, nice progress! Comparing your video to the publication video, it looks like the A press to start the level is happening at a different time, probably due to Flash timing. Since the python script doesn't need the movie to sync to create inputs, you could potentially try adding / removing frames in the movie file to get something that works, as was done in the Super Mario Advance 4: SMB3 case. I haven't tested Flash timings at all yet, so this is just a guess.
ViGadeomes wrote:
Hello, Convert console verified movies made on other GBA emulators to GBAHawk that are then known to sync on console would also be cool at one point to test if they sync on GBAHawk:
The games you listed use Flash for saving, so it's probably not worth converting them yet until I work on timing testing, as the results will probably change in the future. At the moment I'm bogged down with other things, I doubt I'll make significant progress before 2024 comes around.
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
GoddessMaria wrote:
I was wondering something... how do you go about converting the movies from GBAHawk to what's expected by console? Do you utilize the same script that is on the TASbot site or something else?
I use this python script to convert the movie file to GBI inputs,: https://github.com/alyosha-tas/GBA_replay_files/blob/main/gba_script.py It is a small modification from this one by TIKevin83: https://pastebin.com/6jaPXm4H After that the machinery for playback all comes from GBI (just the same as for GBC.)
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
EDIT: Video removed, superseded by improvement. I finished a run of Flintstones that now syncs on console so that is one mystery solved. I haven't had time to properly test all the necessary cases so this won't be a submitted TAS for a while (will be with version 2.0.2 of GBAHawk eventfully.) This was a very interesting example of just how far apart cause and effect of accuracy errors can be, and was also why it took so long to track down. RetroEdit made a resync of Shrek 2 but it currently desyncs on the next to last level on console. Haven't been able to dig into it very deeply yet but seems it could be an accuracy issue rather than a EEPROM issue. So one mystery solved but another one takes its place. I tried another EEPROM game Ty 2, but it is extremely sensitive to EEPROM timing so it desynced almost right away. I might put an EEPROM timing parameter into GBAHawk eventually to give more games a chance of syncing, still too early though. RetroEdit also managed to make a resync of WarioLand 4, so I think that will be next. Testing continues.
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
I was able to splice one of my timing test ROMs into Flintstones to try to track down the source of the timing error. With this I could break into the test ROM at any point and compare against console. The resolution of this particular test is 14 cycles, and the reported error was 28 cycles. I narrowed down when the error appeared to one loop of code where nothing interesting seemed to be happening. This also happened to be when audio is turned on. The game resets audio by turning on the system, then resetting the FIFO unit, then manually writing 8 words to the FIFO buffers to fill them up before enabling auto filling via DMA. The amount of error seemd like the time one FIFO DMA would take, but I had tested pretty thoroughly and nothing seemed off. Except it seems something was off. It turns out that writing a full 32 bytes to the FIFO seems to actually reset it back to zero. A quick test ROM verified that this seems to be the case and it fixes Flintstones. This is very unexpected. I think I'll have to make a few more tests before committing this fix. On the right track though.
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
I've released GBAHawk v2.0.1 as a cumulative bug fix / emulation improvement release, it also adds an about tab. Originally I was going to wait until I fixed Flintstones for this, but right now I'm honestly stumped. The issue is quite simple, a lag frame appears in emulator that doesn't on console. I can see where it is. The game decides what's a lag frame by whether or not the previous frame entered the halt loop. On emulator, this is missed by < 20 cycles, (out of 280896 in a frame.) The problem is the error isn't necessarily in that frame, as FIFO DMAs and a timer interrupt effect the timing, and those are started at the very beginning of the game loading and not changed. So the first thing I need to do is audit the timing of all the initialization code the game does until starting the timers and FIFO DMA, and if that doesn't fix anything I have to audit the timing on the error frame. So, I'll be doing that in between continuing verification testing on other games, maybe one of the Castlevanias.
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
I'm starting to make some more involved tests that test interactions amongst system components. The first thing I wanted to do was test an assumption I made a long while ago about how DMA occurs in BIOS. This assumption came about from weird behaviour in 'haltcnt' NBA test ROM that triggers a halt via a DMA started with an SWI. The result on emulator is 3 cycles off from hardware. My original fix was just guessing that maybe DMA started earlier in BIOS. So I made a test ROM to run the same thing the halt test does but start a timer instead. Results were as expected with normal DMA start time. SO what is the proper fix? If you assume: -Halt only stops the cpu on instruction boundaries: you get 3 cycles too few, 2 of them because DMA stops cpu on memory access boundaries, and the boundary here is after the first cycle of branch. So two more cycles (pipeline refill) would occur before the halt. -Halt immediately stops clocks to the cpu: you get 1 cycle off, the 2 refill cycles that need to run happen after halt instead of before as above. This is why i assumed the fix I did, because it was the only way I could think to get the extra cycle. So the actual fix, whatever it may be, is more complicated than these 2 options. I have no more guesses what it might be. For now I simply reverted the incorrect fix and I'll just have to take the failure until I can more carefully test what's going on.
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
Thanks to RetroEdit doing some resyncs, I was able to verify DK; King of Swing, pretty cool! Link to video In the coming days I will also do 200% and Diddy mode. RetroEdit says these resyncs were very simple, so this probably isn't pushing accuracy very much , but it's still nice to see some success. I will also return to Metroid Fusion when I get a chance and try to redo the resync so I can give it a check mark, and also look at 100%. EDIT: 3 for 3 on King of swing verifications, awesome!
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
I FINALLY figured out how to pass the 'cancel-irq-ie.gba' test. It seems that when enabling the timer after it was previously disabled while it has an internal value of 0xFFFF, then an interrupt can occur if they are enabled. I think internally the timer ticks for one cycle before getting reset when it is enabling, which means it is ticking from 0xFFFF to 0 and overflowing, causing the interrupt. I made a simple test ROM that verifies this behaviour on hardware, and it indeed fixes the issue. So far I only have a rough draft of this fix, I need to think a bit more about how exactly to implement it in a clean way, but at least now the issue is known. In hindsight this probably could have been found sooner since a very similar thing happens with a reload value of 0xFFFF, which is well known since it's part of the mGBA test suit tests. But, lots of things seem simple in hindsight. So once that is fixed, the only failing test will be one that does a decrement DMA in ROM area near a 0x20000 boundary. I think I know what to do with this one, but it's messy to implement and needs more testing. This still doesn't fix Flintstones though. That game turns on the timers right after boot and never touches them again, so couldn't really be a fix anyway. No idea what is happening there.
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
Pretty neat and polished homebrew, and nice TAS as well. Here is a console verification video: Link to video
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
Today I found a new way to crash the GBA. For some background info, the GBA has a prefetch unit that can read instructions from the cartridge ahead of time and store them in a buffer that can be read quickly by the cpu. Also, the ARM7TDMI has two modes of operation, ARM mode which uses 32 bit instruction, and Thumb mode which uses 16 bit instructions. Finally, the cpu has a 3 stage pipeline, so the currently read instruction is 2 ahead of the one being executed. The prefetch unit doesn't care what mode the cpu is in, it just reads 16 bit values. If the prefetch buffer has only 1 16 bit value available, the next fetch just carries on as normal to complete the 32 bits needed. You can branch back and forth between ARM and Thumb modes with a single instruction. So, if you branch two instructions ahead, the next value you have to read will also be the next value in the prefetch buffer, because of the 3 stage pipeline (it if has that many values available of course.) In this case you can continue to read values from the prefetch unit even if you changed execution modes from 16 to 32 bits. Except, the prefetch unit will halt if its limit is reached, which is 8 16 bit values. In this case it waits until it is empty to do anything else, and it also waits for the start of the next instruction read to be re-enabled. So, if you were to fill the buffer in Thumb mode, then branch to ARM mode 2 instructions ahead with an odd number of values in the prefetch buffer, you will still read from the buffer but run out of values half way through reading a 32 bit ARM instruction. In this case, the console will crash, as it cannot the read for the next instruction. (At least this is my understanding of what I'm seeing.) This is not such a contrived setup as it may seem. Games branch 2 instruction ahead pretty commonly, they just don't do so between cpu modes that I've observed. Also the prefetch buffer can be quickly filled up if repeatedly reading values from EWRAM, and this also happens in games, and is important to emulate for console verification. I'd be curious to know if Nintendo was aware of this possibility. Obviously this isn't very helpful, but it's cool to see something new.
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
It's pretty surprising how easy it still is to write test ROMs that fail in GBAHawk but pass on hardware with just a few assembly instructions. Some things are nonsense, like only writing the first half of a BL instruction in thumb mode, which hopefully no games do. Other things are important, like writing modes to CPSR with upper mode bit clear, which is well known in various emulator issue trackers to break Grunty's Revenge if you don't emulate keeping the bit set. So far I haven't been able to conjure up the correct test that fixes Flinstones though. I've tried to resync other games that look short and glitchy enough to be interesting test cases, but without much success. Bionicle desyncs about half way through the game in a way I can't figure out how to fix. But on console it desyncs even earlier than that, I think due to inconsistent input read times. Ty 2 is very sensitive to EEPROM timings, may or may not be workable depending on EEPROM consistency. I still think the most likely problem for Flintstones is somehow the prefetcher, I just have no idea how. The next game I will try is DK: King of Swing
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
Unsurprisingly I'm facing a desync on console on the very first game I tried after Metroid Fusion (which happened to be Flintstones.) So far I can't figure out what the problem might be. The up side of game testing is that it stresses the console much more than crafted tests do, but the down side is that when a problem shows up, it's very challenging to figure out what it might be, since it could be anything in the system. At first I expected it to still be the prefetcher, and I made several new tests, fixed a few bugs, and cleaned up prefetcher code quite a bit. This didn't fix the desync though. Currently I am out of ideas. I think all I can do for now is keep testing with other games and see if any patterns emerge. So, testing continues.
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
despoa wrote:
Can you put an "About" tab that shows the version number so it will be easier to keep track of various versions for movie playback purposes?
Yeah I'll do that for next rtelease.
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
I've released GBAHawk v2.0.0 now that Metroid Fusion is finally console verified. This also contains misc. other bug fixes, including to EEPROM timing where I thought I was following the GBA Tek spec for timing but I made a mistake and things were happening instantly. I'll be focusing on resyncing and testing various other games now. There are a lot of cool GBA games, but also a lot of them use Flash or EEPROM which may have timings imprecise enough to cause problems in verification. For now I'll focus on SRAM games or games without saving to make sure I'm not missing anything common enough to effect a lot of games, then I'll try some of the other save types. In terms of emulation there are still a multitude of untested / unimplemented edge case behaviours, but I'm content for now to take a break and work on verifications. If past verification efforts have taught me anything its that unexpected emulation typically show up in testing, so I'll probably have plenty to keep me busy for a long while to come.
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
EDIT: Video removed, superceded by proper resync retaining original inputs Finally was able to console verify (a resync of) Metroid Fusion. It turns out there is some quirky edge cases of branching to the next address the prefetcher will fetch, and emulation of this needs to be correct enough for Metroid Fusion to sync. This run ended up requiring many precise timings and careful emulation of edge cases, so I'm cautiously optimistic that other games will console verify as well. RetroEdit's Shrek 2 input hack also now works in GBAHawk, so that's another good sign (although the actual game uses EEPROM which has imprecise timings.) But hopefully many SRAM games will work at least. Console verifying this game has been my goal ever since I started working on GBAHawk, so its really cool to finally see it working. I have a little clean up to do in the code and will release GBAHawk 2.0.0 with the emulation fixes needed for this to work. Now the grind to resync other runs can start. I'm really interested in Castlevania and mega Man Zero series. Would be cool to see those working. I can't figure out how to resync Fire Emblem, so I'm going to put that one on hold for now. Eventually I also have to characterize EEPROM and Flash timings, but that's something for later.
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
With a bit more work on the prefetcher I was able to get correct values in RetroEdit's Skrek 2 ROM Hack: I just needed to be a bit more careful with the full prefetch buffer behaviour to get things to work. Metroid Fusion currently desyncs on the Nightmare fight. Probably something is still missing with the prefetcher not covered by Shrek 2, possibly LDM / STM as I noticed those used quite a bit in the trace log. Getting really close to console verification now.
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
Making test ROMs is going pretty well. I found a new (but obvious in hindsight) audio FIFO behaviour (can't add samples to the FIFO manually while audio power is off) and nailed down exact timing of FIFO DMA. I also found an interesting prefetcher behaviour. When the prefetcher is full, it seems to stall until it is empty again, and then continue with non-sequential timing on the next access. This behaviour is actually important for Shrek 2. That game uses EWRAM a lot, and also runs a lot of code from ROM, so the prefetcher has a lot of time to work. When I implement this behaviour in GBAHawk, I get 0x25FC on the final time, only 21 frames from the correct value of 0x2611. I imagine the remaining issues with Shrek are prefetcher related, but I currently have ideas of what to test. I may just make tests running long lists of various instructions and see if anything unusual pops up.
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
The lag frame at the start is because FCEUX is hard coded to idle for an extra frame at power on.
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
I've released version 1.7 of GBAHawk which has more stable linking and improved emulation accuracy, particularly for prefetch. It also cleans up numerous minor bugs. With this release I've finally reached the point where I'll have to develop some of my own tests to make more progress. Things are finally starting to come together and it's refreshing to be on the frontier of emulation for a change. Audio DMA tests will definitely need to be first, so progress will slow down for a while as I figure out how to put things together.
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
Since it seemed to me like prefetch was the most likely source of sync error, I decided to recompile the tte_demo with prefetch enabled to see what errors popped up. To my surprise there was only one failing count. Looking into it, the only possible fix (that didn't break everything else) was for ROM accesses that aren't instruction fetches to completely reset the prefetcher. Previously I had only reset the current fetch. The prefetcher can have up to 8 values buffered, but rarely has more than 1, so this behaviour escaped previous testing. Implementing this finally brings further sync progress to Fire Emblem: EDIT: video removed, superceded by complete resync Unfortunately re-syncing Fire Emblem is incredibly tedious as the current run was made on VBA, so many lag frames have to be added. So it will be a slow grind working on more stages from here. Metroid Fusion now syncs up to 30 minutes into the run, surprisingly easily. Lots of good progress there. Finally RetroEdit's Shrek 2 with built in inputs now gives 25DA as opposed to 2520 previously, much better but still not quite there (supposed to be 2611.) I'm going to keep working on Fire Emblem and see how far I can get. I'm also going to look for shorter runs to work on now that I'm starting to see some progress.
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
It turns out that until now I had missed an important detail in prefetch emulation, in that the prefetcher only runs when executing code from ROM. This is stated pretty clearly in mGBA's article on the matter, and it makes sense (no point running a whole separate component if you are say executing code from IWRAM) but I evidently just glossed over it. After implementing this, Metroid Fusion now syncs to as far as I have managed to resync the movie file itself: EDIT: video removed, superceded by complete resync. It's cool to see some new progress on first party games syncing on console. This fix doesn't seem to help Fire Emblem at all though, so still improvements left to be made. EDIT: Oh, and also in testing I realized Sushi the Cat actually wasn't behaving the same on console as in the TAS. It turns out there are two LESS lag frames at one point in loading. The run still plays out ok, but you can see the difference in how enemy animation frames line up. GBAHawk gave the correct lag, so I resynced the movie and redid the verificaiton from it.
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
Cool and very obscure new discovery, nice. I wonder how many other games have stuff like this? I managed to console verify this (I used BizHawk which has one less lag frame at the start but is otherwise identical.) Link to video
Alyosha
He/Him
Editor, Experienced Forum User, Published Author, Expert player (3572)
Joined: 11/30/2014
Posts: 2744
Location: US
I took another look at 'world_map_gba' to try to resolver the issue. The first thing I did was try out the ROM on GBP to see the expected result: The interesting scanline is the one with a single brown pixel that sticks out on the right side of the castle into the grass approximately at the height of the player's eyes. This scanline is indicative of audio DMA delaying execution of the code that updates the reference regs when HBL IRQ happens. GBP seems to internally blend frames together, and this is why the effected scanline is slightly duller and blurrier than the others, as it is flickering between frames. In fact this is exactly what NanoboyAdvance gets if you turn on LCD ghosting (without it the flickering is noticeable, but this is a display issue not an emulation issue.) Then I looked at the code the game was using to see what the driver of the issue is and why GBAHawk wasn't matching hardware. It turns out pretty much everything except FIFO DMA is a non-factor. The timer that ultimately runs the FIFO is turned on after a VBlank IRQ, and the prefetcher isn't turned on at the time, and as these are well studied things, the absolute timing of when FIFO ticks happen is set. The latching of various involved ppu parameters is also well tested. So really the only movable parameter is timing of the FIFO DMAs. Before I could mess with that though I had several small bugs in the audio code (off by one errors and not clearing fifo on reset) as well as the ppu (a mish-mash old and new code from when I was working on reference point latching.) Once those were fixed it was just a matter of checking which FIFO ticks the DMA needed to run on to match hardware. Having done so however, the results are kind of awkward, new DMAs occur when the sample buffer has 14 samples left, instead of the expected and more natural 16. So something still likely isn't right. I implemented what I had for now though, as it was still better than before and fixes some definite bugs. A more thorough testing of FIFO DMA is still needed.