Monday, 28 March 2011

Preaching To The Unconverted

There I was, merrily chugging along turning pseudocode into real 6502, when I hit a roadblock. The thing about roadblocks is that they stop you in your tracks - you have to back up, have a look around, figure out an alternate route, and then forge a path forwards. Sometimes you have to back up quite a way before being able to proceed again - this is both irksome and time-consuming, because all the effort you're putting into reversing and finding a way forward again is of course effort you're not putting into actual real forward progress.

It's even worse when the roadblock is a chunk of rubble you've dropped, all unwitting, into your own path. Grr.

In my last post, I gloried in my own cleverness; I'd found a way to preconvert PETSCII strings in the sourcecode so that they were assembled that way and thus already in screen-code when the program ran, meaning I didn't need a couple of chunks of code in the app itself to do that conversion at startup. I wrote a little C# utility to run prior to the assembly, turning strings into codes and letting the development rig do the work of the conversion instead of the VIC. How jolly efficient.

Yeah. But.

Something I didn't anticipate jumped up and bit me over the weekend. The converter utility has been working perfectly over the past couple of weeks, quite happily chewing through the bits of sourcecode I've fed it, and spitting-out nice results - until yesterday, when DASM started falling-over in a heap complaining about unreadable junk in a source file and politely but firmly telling me it frankly wasn't good enough and would I please sort it out before trying again. So I had a look and, as you can probably guess, the offending lines were where my converted strings were. Something had gone wrong in the conversion process, flying in the face of weeks of faultless operation.

It was immediately obvious what was wrong - the build script runs the converter when the file with strings in changes, and I'd just added a couple more messages to the list, so it'd been converted. The resultant source file looked mostly OK, apart from a line I'd changed which now included an 'M'. Incredibly, no other message prior to this point had had an 'M' in it, so this was the first time it had been encountered. The converter duly took that ASCII 'M' and turned it into screen code 13 before writing it back to the source file. And ASCII code 13 is CR, Carriage Return - which meant the line of source now had a line-break in it and DASM didn't like it.

So, I'm now having to back-up and rethink the converter, since I can't really brag about it if it won't handle the letter 'M' - it's embarrassing, and I'm not going to expend effort in trying to write messages in my games that don't have 'M's in! Obviously preconverting the sourcecode isn't working, so I think I shall have to post-process the assembled code and convert the strings inside the executable binary itself. But how to find them?

I could embed a few marker bytes in the sourcecode around the string area, and then zero-terminate each string within that region so that a post-processor could find and identify each one - but that requires that the strings be contiguous, and have nothing else around them. So you wouldn't be able to have strings defined as part of larger structures, because the converter wouldn't be able to differentiate between a string byte and any other byte.

So instead, I'm thinking of writing a DASM macro that handles the embedding of strings, with some sort of identifier byte combination to indicate where a string starts, and a zero terminator to show where it ends. This naturally adds a few bytes to the length of each string, but would mean that the post-processor could just scan the entire binary looking for the string marker and converting everything until hitting a zero. What could be tricky is labelling - wherever the code refers to a string, it's usually via a label, and that label will have to point to the actual start of the string rather than the marker bytes. Or maybe I'll just accept the fact that the label will be a couple of bytes off. This is something I won't know for sure what the solution is until I get into writing the macro itself.

Why bother with all this? After all, the 6502-based converter code works perfectly well, so why not just revert to doing the conversion on the VIC when the app starts? Well, if all else fails, I will - but having got so close to a working solution that saves on code size and execution time (on the VIC) I'm loathe to give up without a fight.

0 comments:

Post a Comment