Error calculating address with forward references
ATasm is a 6502 command-line cross-assembler.
Brought to you by:
schmelze
Hi!
I have this code:
levelMap = levelData + $1000 * = $600 lda levelMap+1,x lda levelData rts levelData .byte 0
The compiler calculates levelData as 0x606, and the final code is:
00:06 BD 07 16 lda levelMap+1,x 03:06 AD 06 06 lda levelData 06:06 60 rts 07:06 00 levelData .byte 0 Equates: LEVELMAP: 1606 Symbol table: LEVELDATA: 0606
The error comes from a previews pass where the addressing mode of levelMap+1 is being calculated. Using some additional logging I see this (logging is mine):
do_cmd process symbol LDA at address 0600 from buf LDA parse_operand.1 get_expression = 0, levelMap+1 parse_operand.6 first pass parse_operand.6 first pass a=0 rel[sym->addr]=ffffffff parse_operand.6 first pass sym->addr=32 vidX=88 a_y[sym->addr]=b9 z_y[sym->addr]=b9 do_cmd process symbol LDA at address 0602 from buf LDA
That log info comes from this:
printf("parse_operand.6 first pass\n"); if ((a<256)||(rel[sym->addr]>=0)) { printf("parse_operand.6 first pass a=%x rel[sym->addr]=%x \n", a, rel[sym->addr]); printf("parse_operand.6 first pass sym->addr=%i vidX=%d a_y[sym->addr]=%x z_y[sym->addr]=%x \n", sym->addr, vidx, a_y[sym->addr], z_y[sym->addr]); if ((sym->addr==30)|| /* pad a few zero-page opcodes */ (sym->addr==31)|| ((vidx=='Y')&&((a_y[sym->addr]==z_y[sym->addr])))) pc+=3; else pc+=2; }
As you can see, only the "Y" case is evaluated. If I change the code with Y indexing, I get the expected results
00:06 B9 08 16 lda levelMap+1,y 03:06 AD 07 06 lda levelData 06:06 60 rts 07:06 00 levelData .byte 0 Equates: LEVELMAP: 1607 Symbol table: LEVELDATA: 0607
I'm not sure why only the "Y" case is evaluated. May be just adding the "X" case will be enough to fix this?
Now that I give it a second look, the problem is that "LDA address,y" is always a 16 bit address, but with X can be in the zero page or above, so there is no way at that point to determine the size of the address, or is there?
Bug confirmed in V1.08-trunk100. Workaround by reordering is possible here
levelData .byte 0
levelMap = levelData + $1000
For those interested I fixed this bug in V1.10 of atasm
https://github.com/CycoPH/atasm