Menu

#49 pc bank crossing

1.55.2200
closed-fixed
nobody
None
5
2021-04-25
2020-10-17
No

I made a bad choice back in 2015 for the PC bank crossing corner case when it was turned into bank wrapping.

The CPU program counter of the 65816 wraps at a 64 KiB boundary as only the least significant 16 bits are incremented. I thought it's a good idea to replicate this in the assembler.

Here's an example:

.cpu "65816"
*=$fffe
 bra label ; 2 bytes
 label     ; so this at $0000
 nop

Which after that compiled fine with the program counter bank wrapping in place. Apart from a warning that the pc had overflown.

Code execution is not supposed to cross a bank boundary as the program bank is not updated by the CPU, hence the warning. However the 65816 handles bank crossing over to the next bank for data access and that use case is actually more likely than executing code over a bank boundary.

;Offset ;PC     ;Hex            ;Monitor        ;Source
                                                      .cpu "65816"
                                                      *= $1c000
>01c000                                         data1 .fill $8000
>024000 014000                                  data2 .fill $8000

                                                      *=$30000
.040000 030000  ea              nop             nop

What happens is that if the image file was larger than 64 KiB then data1 and data2 will follow each other nicely in the image file (offset column) and very likely in CPU memory as well. However the address of data2 will be "wrong" (PC column) by not matching the real memory address of the data. Worse from there on the image offset and PC won't align which can be really confusing if it was not intended.

For those who took the program counter overflow warning seriously and avoided bank crossings of data/code everything was working fine.

However for those who choose to ignore the warning it could get really confusing due to the bank wrapping behaviour and the unexpected PC/offset split. Sorry about that.

In r2245 I got rid of the fancy and complicated modulo arithmetic on PC calculations which made this bank wrapping "work". Instead it's now back to a relatively straight forward bank rollover which is what everyone would expect I guess:

;Offset ;Hex            ;Monitor        ;Source
                                        .cpu "65816"
                                        *= $1c000
>01c000                                 data1 .fill $8000
>024000                                 data2 .fill $8000

                                        *=$30000
.030000 ea              nop             nop

The bank cross over warning is still there to raise attention to the bank cross over as it might or might not need special care. For the latter case it can be turned off by "-Wno-wrap-pc".

It seems like such a design mistake would be recognized soon but I didn't really did large 65816 projects where data or code crossed banks. No one reported it either so I guess it was not encountered or was just worked around by rearranging/splitting data.

Anyway that's what happened. At least it'll work a bit more sane in the next release.

Discussion

  • Soci/Singular

    Soci/Singular - 2020-10-17
    • status: open --> pending-fixed
     
  • Daniel Tremblay

    Daniel Tremblay - 2021-02-28

    I have the same issue with labels, when I use binary files that are larger than 64kB. Subsequent labels have the incorrect bank. It seems that the only way to correct the issue is use " * = " and copy the addresses, which makes the code brittle.

     
  • Soci/Singular

    Soci/Singular - 2021-02-28

    This should work better now in theory. I've sent you a link for a win32 test build.

     
  • Daniel Tremblay

    Daniel Tremblay - 2021-02-28

    Yes this works as expected! Thanks!

     
  • Soci/Singular

    Soci/Singular - 2021-04-25
    • status: pending-fixed --> closed-fixed
     

Log in to post a comment.

MongoDB Logo MongoDB