Well damn, I had a huge and well-written-out post that compounded 93143's post, but then I went messing about trying to find old posts to reference and ended up losing my stuff by accidentally clicking "Edit" on someone's post. Doh. :(
One thing I did want to mention here: I've tried to figure out (per the docs) how WLA DX decides whether to use direct page or absolute addressing opcodes (more specifically: if it tracks
tcd like Tepples asked, or if there's an explicit syntax modifier for forcing one or the other (common in IIGS assemblers)), and it isn't mentioned in the docs anywhere that I can find, nor in the examples. I read the Assembler Syntax and 65816 sections and neither state anything useful (sigh). I did find this, however, describing
.struct:
Code: Select all
A WORD OF WARNING: Don't use labels b, B, w and W inside a struct as e.g.,
WLA sees enemy.b as a byte sized reference to enemy. All other labels should
be safe.
lda enemy1.b ; load a byte from zeropage address enemy1 or from the address
; of enemy1.b??? i can't tell you, and WLA can't tell you...
This is a great example of WLA DX's horrible documentation. Honestly I've been sitting here for a good 5 full minutes trying to work out exactly what the author is trying to convey. It's specifically referring to 6502 here, but seriously, my brain is a circular bunch of mush:
I start thinking: "okay, he means that within a
.struct block, you should not use labels named
b or
w or else the parser won't know if you're..... wait, no, that makes no sense:
.b and
.w are used to specify the "size" of an address or immediate value at expansion-time, what does that have to do with the actual label itself?"
But then I read the code comment and I think "oh wait, I see,
lda enemy1.b (which should syntactically be the same as
lda.b enemy1) doesn't allow the assembler to determine if you want to expand
enemy1 into an 8-bit address for zero page access, or refer directly to the (presumably) 16-bit address of label
enemy1.b... except what does that have to do with structs and
b and
w? There's no
. (period/dot), so what the heck is going on? What is the parser doing?!"
My gut feeling is that in 65816 mode, it probably uses absolute addresses all the time unless specifically told not to... except for the beautiful bug that psychopathicteen pointed out and I expanded upon, where the assembler is ridiculously choosing to start referring to 8-bit addresses in direct/zero page for no reason. (I haven't had time to look into that, but I still have those couple of gut feelings...)
The only thing I could find in the WLA DX docs about that assemble-time decision is with regards to using the
.b modifier, or the
.8bit directive:
Code: Select all
For example:
LSR 11 ; $46 $0B
LSR $A000 ; $4E $00 $A0
The first one could also be
LSR 11 ; $4E $0B $00
.8BIT is here to help WLA to decide to choose which one of the opcodes it
selects. When you give .8BIT (default) no 8bit address/value is expanded
to 16bits.
By default WLA uses the smallest possible size. This is true also when WLA
finds a computation it can't solve right away. WLA assumes the result will
be inside the smallest possible bounds, which depends on the type of the
mnemonic.
The last paragraph is awfully damning, but the phrase "can't solve right away" makes my brain explode.
Right away? So, what, it can figure it out
later? What does that even mean?
With regards to the bug psychopathicteen pointed out, it's literally like the assembler's internal logic is somehow suddenly deciding to use direct page/zero page addressing when it most definitely shouldn't. But that last paragraph implies that some kind of "computational mistake" that caused it to do this, and the code (to me) doesn't give any indication that the assembler would have any difficulty.
I even bothered to check in the IIGS mini-assembler writing the same code -- and it does the right thing.