chysn wrote:What I've learned is that my first drafts are just super-inefficient, [...]
... or just straightforward, which is a good thing, IMO, if you want *working* code right from the beginning.
and I can gain vast swaths of memory by just staring at code.
Though 65xx code has the tendency to 'decay' beneath your fingers when you employ more aggressive strategies to reduce code size, like: continuing with register or flag values from preceding code in further, unrelated code; tailoring code to work only for certain ranges of values; double-use or re-ordering of instructions, mixing them from two or more different routines. Once you try to extend the functions of the code, these optimizations break - and you'll wish you had kept a version with the straightforward code.
The new feature is one that I particularly love, because trying to guess future relative branch addresses makes me pause and lose my mojo. This feature allows you to enter an * as an operand for a relative branch instruction with an unknown address, and then * in the future to resolve the original instruction's offset.
*Really* nice!
A similar method is probably adopted by most single-pass symbolic assemblers. Forward references of a label are put in a list, and when that label finally has been defined all its occurences in earlier places are resolved.
As you can see from my monitor primer thread, I've adopted the method of just writing the instruction address (which is always valid for 65xx branches!) as branch/jump target operand, and using the screen editor to keep an equivalent of the list just mentioned as long as the forward branch/jump distance isn't too far. Otherwise, when the forward reference 'threatens' to scroll off the screen I note down the branch, or mark it on the draft paper (you know, the one with all the arrows left and right to denote jumps and branches).