Menu

#7 Error calculating address with forward references

1.08
open
nobody
None
5
2021-05-10
2015-04-30
No

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?

Discussion

  • Franco Catrin L.

    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?

     
  • Peter Dell

    Peter Dell - 2015-05-01

    Bug confirmed in V1.08-trunk100. Workaround by reordering is possible here

    lda levelMap+1,x
    lda levelData
    rts
    

    levelData .byte 0
    levelMap = levelData + $1000

     
  • Peter Hinz

    Peter Hinz - 2021-05-10

    For those interested I fixed this bug in V1.10 of atasm
    https://github.com/CycoPH/atasm

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.