Fetching lower 16 bits of a label for loading memory in Asar

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Fetching lower 16 bits of a label for loading memory in Asar
by on (#230622)
I was doing some work today to try and get the Z3Randomizer ASM code assembling in Asar, instead of Xkas, and one problem I found particularly vexing was this line, specifically: https://github.com/KatDevsGames/z3rando ... g.asm#L265

Code:
DialogItemReceive:
   BCS .noMessage ; if doubling the item value overflowed it must be a rando item
   CPY #$98 : !BLT + ;if the item is $4C or greater it must be a rando item
      .noMessage
      LDA.w #$FFFF
      BRA .done
   +
   LDA Ancilla_ReceiveItem_item_messages, Y ; <--- this line specifically
   .done
   CMP.w #$FFFF
RTL


Asar attempts to do a lot of work to try and suss out if 16-bit jumps to labels are valid, in particular by seeing if the bank of the target label is in the same bank as the current pc being written to. In this case, though, the code is loading data from a label, and the databank should already be set up by the program, and that db does match where the label lives in, so theoretically it's doable, but Asar won’t treat the label as a 16-bit value. Instead, it just claims it does not know how to compile a LDA abs,Y instruction with a 24-bit absolute value.

On Xkas, I'm told that the top 8 bits are just thrown out, and the label is just converted into its 16-bit value - and Asar's emulation of xkas does incorporate this behaviour. However, it seems Asar is at a point where xkas emulation is becoming very unreliable, for example, I was getting more compiler errors - kind of similar to this - by enabling xkas emulation, than by living without it.

So, this problem was mildly vexing to me: is there some obscure behaviour in Asar where I can declare "Only get the lower 16-bits of this label, I know what I'm doing!" or something? I was able to get around this with a small change to Asar's logic, at least, by checking if you're doing some very specific math (see here) but if this isn't actually an issue with Asar, and there is a workaround I'm unaware of, then of course such a change shouldn't go into the trunk, y'know?
Re: Fetching lower 16 bits of a label for loading memory in
by on (#230630)
I'm not familiar with this assembler (Asar), but in some assemblers:

- ...such as x816 (DOS), ! will get you the lower 16-bits of a label/address/expression/value, e.g. lda !label,y or lda #!label
- ...such as ORCA/M, | (pipe symbol) will achieve the above, e.g. lda |label,y or lda #|label
- ...such as TRASM (Trick Assembler, DOS), WLA DX, and (apparently) xkas, the .w suffix on the opcode can achieve the above, e.g. lda.w label,y or lda.w #label. WLA DX also allows you to put the suffix on the end of the expression, e.g. lda label.w,y or lda #label.w. Many people using WLA DX do this unconditionally even when it's obvious due to habit or being bit by direct-page-vs-absolute-addressing decisions made "by mistake" by the assembler

If my answer is irrelevant/crummy then I apologise.
Re: Fetching lower 16 bits of a label for loading memory in
by on (#230639)
Eh, not entirely. It did drive me to look at the documentation in another way, again. It seems that the solution that exists is to add the following:

Code:
DialogItemReceive:
   BCS .noMessage ; if doubling the item value overflowed it must be a rando item
   CPY #$98 : !BLT + ;if the item is $4C or greater it must be a rando item
      .noMessage
      LDA.w #$FFFF
      BRA .done
   +
   ; need to indicate to Asar that we know Ancilla_ReceiveItem_item_messages
   ; is in the $08 databank, so that it uses the lower 16 bits of the label
   ; for LDA {abs},Y
   bank $08
   LDA Ancilla_ReceiveItem_item_messages, Y
   bank auto

   .done
   CMP.w #$FFFF
RTL


Ultimately this may be a bit better, because we're saying exactly what bank we expect the label to be in - e.g. if the label moves to a different bank, then Asar will throw a compiler error. It makes the coupling of code across files explicit, if nothing else.
Re: Fetching lower 16 bits of a label for loading memory in
by on (#230648)
Ugh, never mind, I misread the the part in the manual about the opcode length specification. Changing
Code:
   LDA Ancilla_ReceiveItem_item_messages, Y

to
Code:
   LDA.w Ancilla_ReceiveItem_item_messages, Y

not only works, but creates the same generated assembly as xkas.

In any case, it seems there are a lot of other cases where Asar seems to be pretty aggressive about the assumed with of many uses of labels. It's practically trivial to argue that this is something where it should be throwing up Warnings to developers whenever a bank is assumed by the assembler on any non-jump instruction that may be using a databank, instead of the programbank that Asar thinks is being worked with :? Ran into a lot of other issues like this trying to get Z3rando not just assembling, but assembling to the same ROM as what xkas would produce. Edit: Apparently that warning does exist, but it's off by default. Cool. Cool cool cool. :)

( :roll: )