It is currently Thu Oct 19, 2017 8:29 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Thu Jan 22, 2009 6:22 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
The LDH instruction is the Game Boy's equivalent of zero-page addressing, faster than the usual three-byte instructions that can address any byte of memory. It is encoded in two bytes, with the second forming the low byte of the address. The high byte is fixed at $FF, so the page is at the end of memory, which is where the I/O registers and $80 bytes of RAM are located.

The syntax of the LDH instruction is inconvenient when dealing with symbolic address constants. For example, to access NR52 symbolically, one must subtract $FF00 when using LDH (using wla-dx), or define the constant as just the low byte, which makes it error-prone with all other instructions
Code:
; First approach: subtract $FF00 when using LDH
.define NR52 $FF26
LDH A,(NR52-$FF00)  ; LD A,($FF26)

; Second approach: define with $FF00 already subtracted, then remember to add $FF00 when using other instructions
.define NR52 $26
LDH A,(NR52)    ; LD A,($FF26)
LD  HL,NR52+$FF00
XXX (HL)
LD  BC,NR52     ; oops, forgot to add $FF00
XXX (BC)        ; so this accesses $0026 rather than $FF26

In my code I've been using macros named LDA and STA, which internally do the subtraction. This way, I can always work in terms of the actual addresses.
Code:
.macro LDA ; addr
    LDH A,(\1 - $FF00)
.endm

.macro STA ; addr
    LDH (\1 - $FF00),A
.endm

.define NR52 $FF26
LDA NR52      ; macro expands to LDH A,($26)
STA NR52      ; macro expands to LDH ($26),A

In my opinion, the assembler syntax for LDH should have been such that the address was a normal one that is in the range $FF00-$FFFF, with the assembler dealing with the encoding. This would have allowed code to be unconcerned with the details:
Code:
; Hypothetical; NOT how GB-Z80 assemblers work!
LDH A,($FF26)  ; encoded as $E0 $26
LDH ($FF26),A  ; encoded as $F0 $26


Am I overlooking something that eliminates this issue entirely? wla-dx includes some automatic usage of LDH, similar to how 65xx assemblers use it when the high byte of an address is zero, but wla-dx requires that the address be of the form $FF00+offset, and I'd rather not rely on a non-standard transformation like this, as lots of my code depends on timing.
Code:
LD A,($FF00+$26)  ; wla-dx automatically optimizes this into LDH A,($26)
LD A,($FF26)      ; wla-dx does not optimize this


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2009 10:23 pm 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3943
Go macro crazy?

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 23, 2009 2:26 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7231
Location: Chexbres, VD, Switzerland
I don't think WLA will optimize anything automatically, WLA-6502 requires you to either choose zero-page or word as default, and when using the other you'll have to always type .w or .b after your instructions which is annoying. I guess I can't count how many time I got the "Argument out of 8-bit range" because of that.

Probably you were supposed to type something like that :
LDH A,(<Adress)
So that only the low byte is taken in account ? This somewhat remembers me Nesasm.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 23, 2009 3:51 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
I can't believe I missed LDH A,(<addr). Still, it's silly that the assembler syntax doesn't do that implicitly. Then LDH A,($FF24) would work, but if you tried to do LDH A,($1234), you'd get an assembler error. Checking the operands for valid ranges is nothing new; LD A,$1234 will fail, as will LD HL,$12345.

BTW, wla-dx does convert LD A,($FF00+<addr) into LDH A,(<addr); I just double-checked. It doesn't convert something like LD A,((<addr)+$FF00) though.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 23, 2009 3:56 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7231
Location: Chexbres, VD, Switzerland
Quote:
BTW, wla-dx does convert LD A,($FF00+<addr) into LDH A,(<addr); I just double-checked. It doesn't convert something like LD A,((<addr)+$FF00) though.

Well, it's really weird. What about if you actually wanted a 16-bit LD instruction for some reason ? I guess there is not much reason anyway. On 6502 :
Code:
ldx #$01
lda $ff,X        ;Reads from $00
lda $00ff,X    ;Reads from $100

So there is a difference. Since there is no indexed adressing on the GB-Z80, it's probably assummed there is no reason you want to use LD when you could use LDH.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 23, 2009 5:38 am 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3943
The assembler looks specifically for the $FF00+ symbol, as if it's a different instruction. So the $FF00 is more like an IX or IY than an address.

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 23, 2009 7:01 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
And on the 65816:
Code:
pea $1234
pld        ; direct page = $1234, rather than the default of $0000
lda $34    ; accesses $0034 if assembled to AD 34 00, $1268 if assembled to A5 34

And on the SPC-700:
Code:
setp       ; direct page = $100
mov a,$34  ; accesses $0034 if assembled to E5 34 00, $0134 if assembled to E4 34


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 23, 2009 9:11 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7231
Location: Chexbres, VD, Switzerland
I remember having to do a lot of manual defines when working with direct page 1 on the SPC-700 instead of the default '0'. WLA-SPC700 didn't handle it very efficiently. Not counting the fact that often WLA-SPC700 didn't even assemble what I wrote due to bugs, but it's the only SPC700 assembler in the wolrd so...

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 31, 2009 6:52 pm 
Offline
User avatar

Joined: Sat Jan 31, 2009 6:25 pm
Posts: 4
Is wla-dx where it's at these days? rgbasm should handle ldh like you want, but I guess it's a pain in the rear to switch assembler once you're used to the other one.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 31, 2009 10:39 pm 
Offline
User avatar

Joined: Sun Jun 05, 2005 2:04 pm
Posts: 2130
Location: Minneapolis, Minnesota, United States
lai wrote:
Is wla-dx where it's at these days?


I'm actually rather surprised at how much wla-dx is used in the GB Dev forum. But I'm pretty sure for 6502/NES programming, I and like two other people use it. Everyone else seems to use other assemblers. But I never took the time to look for a GB-Z80 assembler, since I had the WLA bundle it was included so I just used that because it was there.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Feb 01, 2009 10:43 am 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3943
I just use TASM.

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Top
 Profile  
 
 Post subject:
PostPosted: Sun Feb 01, 2009 11:26 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
lai wrote:
Is wla-dx where it's at these days? rgbasm should handle ldh like you want, but I guess it's a pain in the rear to switch assembler once you're used to the other one.

wla-dx is all there is for some processors, so some of us begrudgingly use it. I encounter obscure bugs every day I use it. Working with the source code, it's an awful mess inside, so it's not surprising. I looked at rgbasm and it uses lots of unconventional syntax that looks like asm from 20 years ago, different from all the other assemblers I've used. For example, directives don't start with . as in modern assemblers. I'll have to give it a try, along with TASM (assuming TASM's source is also available).


Top
 Profile  
 
 Post subject:
PostPosted: Sun Feb 01, 2009 11:40 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7231
Location: Chexbres, VD, Switzerland
I've had encounter an incredible number of bugs for WLA-SPC700, in fact very often it just didn't assemble to what I told it to but if you add parenthesis arround the argument of your opcode or if you change the order of the instructions it fixes up by itself.
For WLA-6502 I never encountered such bugs, but there is a lack of features (which assembler doesn't have any ?), for instance it assumes your code is running from ROM and make your life harder if you code for a machine where the code is downloaded to RAM, such as the C64.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Feb 01, 2009 12:15 pm 
Offline
User avatar

Joined: Sat Jan 31, 2009 6:25 pm
Posts: 4
Quote:
I looked at rgbasm and it uses lots of unconventional syntax that looks like asm from 20 years ago, different from all the other assemblers I've used. For example, directives don't start with . as in modern assemblers. I'll have to give it a try, along with TASM (assuming TASM's source is also available).


When I use other assemblers than rgbasm I feel the other ones are strange and unnatural. Guess I'm in the minority. :)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 02, 2009 11:09 am 
Offline
User avatar

Joined: Thu Nov 11, 2004 5:30 am
Posts: 121
Location: San Francisco, CA
I used RGBASM for several commercial titles. While the syntax is kind of wacky, as many have noted, it was *way* more stable and had more features than the official assemblers from Nintendo.

_________________
...patience...


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group