sbprojects / sbasm3

SB-Assembler Version 3 - Cross Macro Assembler
https://www.sbprojects.net/sbasm
Creative Commons Zero v1.0 Universal
35 stars 8 forks source link

Incorrect PC relative codegen for 6809 #15

Closed mseminatore closed 5 months ago

mseminatore commented 6 months ago

I may be wrong but I believe that the code generated for the following test cases is incorrect:

LDA $1234,PC LDA -$1234,PC

03DA-A6 8D 12 34 468 (10) LDA $1234,PC 03DE-A6 8D ED CC 469 (10) LDA -$1234,PC

The offset of $1234 looks incorrect for a PC relative address. I believe that the correct code for test.hex should be:

A6 8D 0E56 A6 8D E9EA

This would be based on a PC of $3DA, and an address target of $1234. Computing the PCR Offset is then $1234 - $3DA - 4 bytes for instruction length = $E56. My own 6809 assembler and EDTASM+ seem to agree. As does the example provided in Barden's TRS-80 Color Computer Assembly Language book p224.

Here is the .hex output file diff from test/motorola/6809.asm from my assembler to yours:

62,63c62,63
< :1003D000ABE6AB96ABB5ABDBABF6A68D0E56A68DFA
< :0203E000E9EA48
---
> :1003D000ABE6AB96ABB5ABDBABF6A68D1234A68D18
> :0203E000EDCC62

If you agree LMK if you'd like me to send a PR.

sbprojects commented 5 months ago

Hi Mark,

You had me convinced for a moment. I had to read some documentation again. It's been many years since I've programmed the first version of the 6809 assembler. And slowly things got back to me.

I have also compared the output from the SB-Assembler with the output of ASM6809, and they both agree with one another.

There are two PC indexed modes:

LDAA offset,PC LDAA destination,PCR

With the first version you'll have to calculate the offset yourself. Thus the offset itself is directly included in the data field. With the second version the offset is calculated for you by the assembler.

Back in the days I used this book as a reference https://dn790009.ca.archive.org/0/items/6809_Assembly_Language_Programming_by_Lance_Leventhal/6809_Assembly_Language_Programming_by_Lance_Leventhal.pdf You can view the description about the difference between PC and PCR on page 3-24.

If your assembler does the calculation for the PC mode, they don't follow the original behaviour. This is not necessarily wrong, but both are not compatible with one another.

On Fri, 3 May 2024 at 08:21, Mark Seminatore @.***> wrote:

I may be wrong but I believe that the code generated for the following test cases is incorrect:

LDA $1234,PC LDA -$1234,PC

03DA-A6 8D 12 34 468 (10) LDA $1234,PC 03DE-A6 8D ED CC 469 (10) LDA -$1234,PC

The offset of $1234 looks incorrect for a PC relative address. I believe that the correct code for test.hex should be:

A6 8D 0E56 A6 8D E9EA

This would be based on a PC of $3DA, and an address target of $1234. Computing the PCR Offset is then $1234 - $3DA - 4 bytes for instruction length = $E56. My own assembler and EDTASM+ seem to agree. As does the example provided in Barden's TRS-80 Color Computer Assembly Language book p224.

If you agree LMK if you'd like me to send a PR.

— Reply to this email directly, view it on GitHub https://github.com/sbprojects/sbasm3/issues/15, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQHRIOGBEZANIJ3PC3HLXLZAMUFVAVCNFSM6AAAAABHE6TNOOVHI2DSMVQWIX3LMV43ASLTON2WKOZSGI3TOMBQGU3DMOA . You are receiving this because you are subscribed to this thread.Message ID: @.***>

-- Met vriendelijke groet, Kind regards,

San Bergmans

mseminatore commented 5 months ago

Thank you for that citation. Interestingly neither EDTASM+ nor the Barden book mention PC vs. PCR addressing. I guess because the PC version is not very practical given the need to compute the offset considering instruction length manually.

If you try the following in EDTASM+ it shows that only one mode is supported.

LDA $12, PC       ; error bad operand!
LDA $12, PCR      ; OK

But it explains what I was seeing. My assembler only supports PCR. I can confirm that ensuring that I use PCR we generate the same result.