vhelin / wla-dx

WLA DX - Yet Another GB-Z80/Z80/Z80N/6502/65C02/65CE02/65816/68000/6800/6801/6809/8008/8080/HUC6280/SPC-700/SuperFX Multi Platform Cross Assembler Package
Other
549 stars 98 forks source link

"Get low word" assembler directive #32

Closed Ramsis-SNES closed 3 years ago

Ramsis-SNES commented 9 years ago

Say you have an .ENUM starting with a 24-bit value, like this:

.ENUM $7E2000
    TileMapBG1  dsb 2048
.ENDE

Next, when you try to get the low word of TileMapBG1 into a 16-bit index register (e.g. for DMA) like this:

    ldx #TileMapBG1

... WLA will throw up an error:

INPUT_NUMBER: Out of 16bit range.
ERROR: Couldn't parse "ldx".

I couldn't find any assembler directive that gets the low word of a 24-bit value ($2000 in this case), so I'm currently doing this as a workaround:

    ldx #(>TileMapBG1)<<8+(<TileMapBG1)

... which despite looking rather clumsy works just fine. However, other people reading my code will most likely go, "Oh my god, what was he thinking??" Until they realize there's no other way to get the desired value.

So, I'd suggest adding a simple "get low word" assembler directive, which would be most useful. :-)

cr1901 commented 9 years ago

I've thought about this problem before. Western Design Center, the company who makes the 65816, recommend the following syntax for byte selection on page 50, section 6.3.3.3-6.3.3.4 of their current '816 datasheet:

Operand One Byte Result Two Byte Result
#$01020304 04 04 03
#<$01020304 04 04 03
#>$01020304 03 03 02
#^$01020304 02 02 01

As it turns out, this is completely compatible with what WLA does already. I think when Ville designed the '816 backend, he based it off the datasheet's recommendations- WLA even implements most (not all) of the alternate mnemonics. The byte selection operators just need to be updated to work with 24-32 bit values, and to determine based on context (either using .8BIT, .16BIT, .24BIT, the assembler's heuristics, or instructions where a specific addressing mode is forced, like Direct Indirect) where to use a one-byte or two-byte value. This should be specific to 16-bit archs, like the '816 in Native Mode, and above 16-bit if WLA supports it in the future.

Unfortunately, "^" is used already for exponentiation. I'd suggest substituting "**" for exponentiation, and using "^" for 3rd byte selection for 24-bit values, but that will break code that used ^ previously. Maybe for now, stick to "<" and ">". I believe this is what prevented me from making this change when I previously looked into this.

nicklausw commented 9 years ago

edit: me being stupid.

Ramsis-SNES commented 9 years ago

@NicklausW, thanks for telling us all again what I already wrote in my initial posting.

nicklausw commented 9 years ago

edit: me being stupid.

nicklausw commented 9 years ago

edit: me being stupid.

vhelin commented 9 years ago

Back in the day when I coded asm and needed the lowest 16bits of a bigger value, I just anded it with $ffff - would it work here?

On Thu, Apr 16, 2015 at 12:17 AM, NicklausW notifications@github.com wrote:

Guess I should elaborate on what I mean...I was suggesting a macro on the basis that it wouldn't make your code look quite as crazy. Instead of "ldx [crazy stuff]", you can use "m_ldx TileMapBG1" and it'll work the same.

— Reply to this email directly or view it on GitHub https://github.com/vhelin/wla-dx/issues/32#issuecomment-93572024.

Ramsis-SNES commented 9 years ago

I was suggesting a macro on the basis that it wouldn't make your code look quite as crazy. Instead of "ldx [crazy stuff]", you can use "m_ldx TileMapBG1" and it'll work the same.

Thank you. But I've been using workarounds like yours for three years now, and am looking for not a workaround this time. ;-)

Back in the day when I coded asm and needed the lowest 16bits of a bigger value, I just anded it with $ffff - would it work here?

With reference to the example in my first post, could you please elaborate on what you mean exactly? :)

vhelin commented 9 years ago

On Mon, Apr 27, 2015 at 8:17 PM, Ramsis notifications@github.com wrote:

I was suggesting a macro on the basis that it wouldn't make your code look quite as crazy. Instead of "ldx [crazy stuff]", you can use "m_ldx TileMapBG1" and it'll work the same.

Thank you. But I've been using workarounds like yours for three years now, and am looking for not a workaround this time. ;-)

Back in the day when I coded asm and needed the lowest 16bits of a bigger value, I just anded it with $ffff - would it work here?

With reference to the example in my first post, could you please elaborate on what you mean exactly? :)

I can't test it at the moment, but would something like this work:

ldx #(TileMapBG1 & $ffff)

???

Reply to this email directly or view it on GitHub https://github.com/vhelin/wla-dx/issues/32#issuecomment-96746575.

Ramsis-SNES commented 9 years ago

I can't test it at the moment, but would something like this work:

ldx #(TileMapBG1 & $ffff)

I just tested this, and can confirm that it apparently works indeed.

But nevertheless ... it's yet another clumsy workaround. ;-)

vhelin commented 9 years ago

On Mon, Apr 27, 2015 at 8:27 PM, Ramsis notifications@github.com wrote:

I can't test it at the moment, but would something like this work:

ldx #(TileMapBG1 & $ffff)

I just tested this, and can confirm that it apparently works indeed.

But nevertheless ... it's yet another clumsy workaround. ;-)

I've always used that, even back in the day when I wrote 68000 asm code for Amiga computers... :) You guys sure this is not good enough? :)

— Reply to this email directly or view it on GitHub https://github.com/vhelin/wla-dx/issues/32#issuecomment-96750445.

nicklausw commented 9 years ago

I can't really see a better solution than what vhelin suggested. It's kinda the closest you can get to a non-workaround. Not sure what you'd even be asking for otherwise. XD

Ramsis-SNES commented 9 years ago

You guys sure this is not good enough? :)

It's certainly good enough for creating working machine code. It's not good enough however when it comes to writing sourcecode that's easy to read, and self-explanatory. ;-)

Not sure what you'd even be asking for otherwise. XD

Well, simply something along the lines of cr1901's reply. ;-)

cr1901 commented 9 years ago

I'll see how difficult it is to implement rudimentary support for this feature, because it's something I've also wanted to have.

I'm going to wait before I break the exponentiation operator though.

vhelin commented 3 years ago

After all these years I have to say that I still think that VALUE & $FFFF is the right way to do this. It worked for Amiga assembly coding (and C, and JavaScript, and C#...) and it should work elsewhere as well. If you are a programmer, and understanding what VALUE & $FFFF does in under a second is too much for you, I think you might have to train a little more. :)

I have to add that operators '<' and '>' were IMHO quite unnecessary, but at the time I added support for them for some reason. Perhaps it felt nostalgic after reading some 8-bit asm?

Ramsis-SNES commented 3 years ago

Fixed in https://github.com/vhelin/wla-dx/commit/7f98845767c0880bb5df6e9687091f6c42b27c4b.

Well, thanks! :D