cvghivebrain / s1disasm

Sonic the Hedgehog (Mega Drive) Hivebrain 2022 disassembly
41 stars 8 forks source link

ptr macro needs a distance check #30

Open LuigiXHero opened 2 years ago

LuigiXHero commented 2 years ago

I added the revision 00 object position files to be included with their rev 01 counterparts and that caused the SBZ conveyor platforms to super lag the game and not load after a lot of trial and error and randomly guessing what the issue was I finally moved the SBZ platform include to be above the rest and it then functioned fine. Here's the include section if you want to see what causes it include.txt

cvghivebrain commented 2 years ago

If a pointer points to something out of range, the game won't compile and asm68k displays an illegal value error. I'm not sure how ptr would cause the problem you described. What did you do with the index just before the includes?

Awuwunya commented 2 years ago

dc.w allows for any signed OR UNSIGNED value. Hence, values > $7FFF will also assemble, which is invalid for a signed pointer. However, since ASM68K is a single-pass assembler, there is no way to fix this pre-emptively; a check done after the fact must be done to ensure invalid values are not present. This is why my Z80 macro set had the option to check for invalid values after the fact, and it did this by using a negative byte value, which if out of range, will throw an error, and then patching up the output afterwards.

cvghivebrain commented 2 years ago

I was going to add a check after the dc.w like this:

        if index_start=-1
        dc.\index_width \1-*                ; pointer is relative to the pointer itself
        else
        dc.\index_width \1-index_start          ; pointer is relative to start of index
        endc

        ptr_dist: = \1-index_start

But I get an "Expression must evaluate" error when ptr_dist is defined, and I'm not sure why. It's after the dc.w so the addresses should all be set in stone by then.

Awuwunya commented 2 years ago

If \1 comes after the macro, then \1 can not be defined. Your only option is to use EQU, which can be checked in pass 2, but you still have a potential issue if you use an if statement. That should happen in pass 1, hence it MUST come after whatever \1 is. So probably the only way to have it work, is checking at the very end of assembly in pass 1.

cvghivebrain commented 2 years ago

I haven't been able to come up with anything that works. I'll probably try again later. Until then it'll just have to be incumbent on the user to make sure pointers are within range.

In LuigiXHero's case I recommend switching to longword pointers. The alterations needed should be minimal.