Open dwsJason opened 5 years ago
More info, it seems to be specifically, full 24 bit addresses, for example, code that looks like this
sta >(pjmp+1)
pjmp jmp $1234
If I define the bytes out
; causes a patch at the wrong address db.c $8f ; stal dc.t pjmp+1
; Generates correct patch, and code runs dc.b $8f dc.w (pjmp+1) dc.b ^pjmp
This get's more weird. If I put a dc.t in the first segment, then the dc.t, and ldal / stal addresses get patched appropriately in the merged in segment.
The first dc.t encountered in the dump from the OMF analyzer will have a Reference of 0000, which is really weird, and possibly related.
+--------+-----------+-------------+----------+-------------+
| # | # Bytes | Bit Shift | Offset | Reference |
+--------+-----------+-------------+----------+-------------+
| 0000 | 02 | | 0003 | 00F1 |
| 0001 | 03 | | 0007 | 0000 |
| 0002 | 02 | | 000B | 004A |
Thanks for all the details, can't remember how I tested this in the first place. I think I can piece together something from the information you have provided.
I have been trying to narrow this down more. I've put some printfs into the code to try and figure it out. Everything in the pReloc list looks fine to me. I'm pretty convinced this is something to do with the first triple exported out by the OMF export. Unfortunately, I don't really understand how the SUPERLOC works. For now, I've just defined a dc.t in my first segment, in the first code page... (which in itself seems to be fine). So I thin it's some issue when the first triple encounterd, is not in code page 0.
Still very much enjoying your assembler!
I've reworked some of the linking for another issue I found, it is possible it has an effect on this issue as well. I think in some cases pReloc might point to the wrong section or certain externals would just be resolved to 0 too early.
I pulled latest. The issue reported still exists. I'm still convinced its a bug in the OMF Export. Let me see if I can put together a test case for you (worst cast I just send you my code).
The bug can be seen in the OMFAnalyzer. This archive includes test.s, which can reproduce the issue. Unarchive into a directory, and make sure x65.exe is in your path. Just run test.bat, it should output the test.s16 GSOS executable, then do an OMF dump into test.s16.txt. You can load up test.s16.txt. Look at the relocation dicttionary output.
As provided:
+--------+-----------+-------------+----------+-------------+ | # | # Bytes | Bit Shift | Offset | Reference | +--------+-----------+-------------+----------+-------------+ | 0000 | 03 | | 0002 | 0000 | <- patch in page 1 works, because page 0 exists | 0001 | 02 | | 0008 | 0021 | | 0002 | 02 | | 000B | 000D | | 0003 | 04 | | 0013 | 0017 | | 0004 | 03 | | 0103 | 0107 | <- this looks good +--------+-----------+-------------+----------+-------------+
Comment out line 29 in the test.s source file, and run the .bat file again
+--------+-----------+-------------+----------+-------------+
| # | # Bytes | Bit Shift | Offset | Reference |
+--------+-----------+-------------+----------+-------------+
| 0000 | 03 | | 0000 | 0080 | <-- should be offset 0100, not 0!
| 0001 | 02 | | 0005 | 001E |
| 0002 | 02 | | 0008 | 000A |
| 0003 | 04 | | 0010 | 0014 |
+--------+-----------+-------------+----------+-------------+
In WriteA2GS_OMF, where the SUPERLOCS are export, near line 7103. (I guess this would be easier with a pull request). if prev_page is initialized to -1, instead of to 0, this appears to fix the issue I'm seeing. Which has nothing to do with merging sections, and everything to do with the first page with relocatable offsets, simply not containing any relocatable offsets.
I'm not familiar with how they have to be encoded, but I noticed the export looked like it would have problems with pages about 32KB. I tested that theory, and the offsets do wrap around back to zero, if the patch needs to happen above offset $8000, I don't know if this is an OMF limitation. I don't think it is, because on Merlin, I know that I have created code banks that take up nearly 64k without any issues.
Thanks for all the research, I don't remember enough to follow it all, so rather than fixing the wrong thing it would be great to have a pull request. You are probably correct about the max size, I haven't considered that large page, I can try to dig in to it, let me know if you find anything.
I have a branch, with a very small change, to fix this. I can't seem to push to origin, can I get permission to create a branch on your depot? Or if I fork the project, will be be able to submit a Pull Request from the fork?
On a separate note, I'd like to contribute a few demo Apple IIgs OMF applications to your depot. (or maybe just an Apple IIgs OMF demo)
I've added you to the project!
Thank you! I'll get the PR posted, as soon as I'm able.
It appears that the patches provided to GSOS, do not get offset with the code, when that code is merged into another segment. If a bit of code, has something like lda #jumptableaddress, and this is near the top of the code segment, (so lets say address say We have offset 0 in the code file is A9 jumptableaddress&0xFF (jumptableaddress>>8)&0xFF. Then that code segment is merged into another code segment, so it's new offset in memory is 0x1000. The code patch for the LDA #jumptableaddress, is still applied to offset 0x0001, instead of 0x1001. This basically causes the code to become corrupted.
Hopefully this makes sense. Took me a while to figure out why things were crashing on me.