I reached a point where it was time to switch to a competent interactive debugger, instead of working out of a series of text files that were becoming increasingly difficult to manage.
It took me a good few days to transfer my comments and knowledge to the new system. But the payoff is massive - I've immediately spotted mistakes, and identifying blocks of code has become a lot less painful.
In the screenshot you can see the commented block of code that transfers the in-game timer to the on-screen HUD.
Yesterday I also documented how the main branch table works in memory. In fact, I'm not even sure if branch table is the correct terminology. Figuring this out was important because actually determining the program flow in Outrun is tricky. The list of functions that are finally called is generated at runtime, and differs at different points of the game.
Firstly, there's a portion of ROM that contains a series of long addresses. Each of these addresses is a pointer to another portion of ROM. This second portion of ROM contains a set of properties related to the function, and the final address of the function itself. The final step is to compile these to a table within RAM. This table contains bits so that the functions can be enabled or disabled.
I presume this is some kind of optimisation, but it seems to add a lot of indirection and makes following the flow of code rather tough from the onset. Maybe some level of obfuscation was the idea? Perhaps someone reading who is a 68000 wiz will know.
Update: Figured this out. Some useful information in the comments regarding this from one of the blog readers and myself :)