User blog:RottenBlock/System 1 Another Hang-up

This is going to be one of my "talking out loud to myself" posts to try to walk through a problem.

I've been meaning to push a new version of Sys0 for a few days now, but I've been caught-up on an issue that has no tidy solution. The $ command in Sys1-3.0 has two forms. If it's followed by a label, it will cause the menu code that's (presumably) at that label's address to become the new active menu. If it's not followed by anything, it will revert to the default menu. The problem is that both System and the decompmiler move through the code one byte at a time, and rely on extremely strict code structure rules to ensure it's treating each byte as the correct kind of code. Unforutnately, Alicesoft didn't leave any distinguishing marks to tell one $ apart from the other once they're compiled. Labels become two-byte addresses, and nothing becomes... well, nothing! Even TTSys throws up its hands about this: it assumes that a $ encountered when an alternate menu is open is a standalone $, and that a $ encountered when the default menu is opened will be followed by a label address, and if it's mistaken, a crash is inevitable.

Since decompiling doesn't follow any sort of "program flow," I can't even make the same assumptions as TTSys. If I assume a $ is standalone and isn't, I'll end up treating an address as though it were a command and its first paremeter. If I do the reverse, I eat up the next two bytes of code and do god knows what damage.

The two closest things I have to fixes are as follows. A standalone $ would assuredly be followed by another command or the end of file. In the latter case, we're laughing, and if it's also not the former case, we're just as good - it must be an address (or a user error). Unfortunately, if we do confirm the next byte is a valid command, that doesn't mean it actually is a command, as it might still be an address that just happened to share a command's ASCII code in its low end. lbl52, lbl152, lbl252, etc are all indistinguishable from R when you're only looking at the first byte.

Another answer would be to check to make sure that the prospective address actually points to menu code, but remember that I'm moving through the code one byte at a time to confirm what any of it even is. Thus, I can only confirm if a label points to menu code if the label points to code from earlier in the file. Anything after the current location can't be confirmed because I don't know what to do with the next two bytes!

The I can think to do is to check if the next byte is a command, since the odds are better that it won't be than that it will, and then (if the next byte might be a command) to check previous labels even though I can't check later ones. If the answer still can't be confirmed, I guess the only solution is to mark the current location, assume the $ is standalone, and to attempt to carry on. If an error occurs in the rest of the file, that suggests I made the wrong decision and should go back to the marked location and assume $ is followed by an address. If an error occurs again, then there's a genuine error and... well frankly I don't know what to do then, but it shouldn't be possible in a compile file.

To avoid this hash in the future, my new-style files will have to be retrofit to use $0 instead of standalone $, and to compile it to match, so that $ will be followed by a 16-bit 0 (0 is an impossible address for labels, since the first two bytes of a sco file are reserved for the address of the first menu in the file. Appropriately enough that's exactly where the $0 sign is telling the code to go!). This has the benefit of being in line with the "return" codes for label and page calls.

Kind of pissed off to go through all this fuss for literally a single dollar sign.