It is currently Tue Dec 12, 2017 2:49 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 27 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Fri Oct 31, 2014 10:54 am 
Offline

Joined: Tue Aug 02, 2011 3:11 am
Posts: 7
Hello all, this might come across as a noobish question and I apologize if it's been asked before (or I am missing something obvious), but I've noticed that nesasm always uses absolute addressing, even if I want to address the zero page. This happens regardless of whether I use labels or addresses, so both lda $00 and lda label (with label being a variable at $00) result in an AD 00 00 opcode. Also, sty $00, x results in an assembler error, as nesasm interprets $00 as an absolute address.
Now, my question is whether I can do something against it (other than manually writing every line as .db $A5, $00, for lda,zp), or whether it's about time I switched assemblers.
Cheers, -scrimpeh


Top
 Profile  
 
PostPosted: Fri Oct 31, 2014 11:13 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19335
Location: NE Indiana, USA (NTSC)
This is a known difference in syntax between NESASM and other popular 6502 assemblers. To switch to zero page, use explicit zero page addressing: lda <$FF or lda <some_var.


Top
 Profile  
 
PostPosted: Fri Oct 31, 2014 11:15 am 
Offline
User avatar

Joined: Mon Oct 01, 2012 3:47 pm
Posts: 153
Location: freemland (NTSC-U)
NESASM requires < before a zero page variable due to the fact that it's derived from a PC Engine/TurboGrafx 16 assembler (on that system, Zero Page is in the $2000 area).

My suggestions for alternative assemblers include asm6 (simpler) and ca65 (more complex).


Top
 Profile  
 
PostPosted: Fri Oct 31, 2014 11:20 am 
Offline

Joined: Tue Aug 02, 2011 3:11 am
Posts: 7
tepples wrote:
This is a known difference in syntax between NESASM and other popular 6502 assemblers. To switch to zero page, use explicit zero page addressing: lda <$FF or lda <some_var.



freem wrote:
NESASM requires < before a zero page variable due to the fact that it's derived from a PC Engine/TurboGrafx 16 assembler (on that system, Zero Page is in the $2000 area).

My suggestions for alternative assemblers include asm6 (simpler) and ca65 (more complex).


Oh wow, this is really simple. Thanks for the quick answers, too!


Top
 Profile  
 
PostPosted: Fri Oct 31, 2014 12:56 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10164
Location: Rio de Janeiro - Brazil
freem wrote:
asm6 (simpler)

ASM6 on the other hand never uses absolute addressing for $0000-$00FF. If you happen to need that for timing reasons or something, you'll either have to use .db (for the opcode) and .dw (for the address) or a mirror of ZP ($0800-$08FF, for example).


Top
 Profile  
 
PostPosted: Fri Oct 31, 2014 1:13 pm 
Offline
User avatar

Joined: Mon Oct 01, 2012 3:47 pm
Posts: 153
Location: freemland (NTSC-U)
tokumaru wrote:
freem wrote:
asm6 (simpler)

ASM6 on the other hand never uses absolute addressing for $0000-$00FF.


good to know, I thought it would do that if you just put $00xx. (guess that's something I should look into for my fork)


Top
 Profile  
 
PostPosted: Fri Oct 31, 2014 2:48 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10164
Location: Rio de Janeiro - Brazil
Yeah, that's the one annoying ASM6 flaw that affects me in any significant way. It's still my assembler of choice, though.

I don't think I ever needed absolute addressing for $0000-$00FF on the NES, but it happens quite often when I'm programming kernels for Atari 2600 games.


Top
 Profile  
 
PostPosted: Fri Oct 31, 2014 3:21 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 10:52 pm
Posts: 361
Location: UT
What's the preferred way of handling it?

Assembler directive? (.zopt on/off)
Per instruction? (lda.w $ff, lda >$ff, lda $00ff ...?)


Top
 Profile  
 
PostPosted: Fri Oct 31, 2014 3:31 pm 
Offline
User avatar

Joined: Mon Oct 01, 2012 3:47 pm
Posts: 153
Location: freemland (NTSC-U)
My preferences are unprefixed $00ff (which might not be simple/easy to handle; it's been a bit since I've looked at the code) or an a:$00ff prefix like ca65 supports. The former would be my preferred solution in a perfect world, and the latter would be my preferred solution in the real world :)


Top
 Profile  
 
PostPosted: Fri Oct 31, 2014 4:02 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 10:52 pm
Posts: 361
Location: UT
It does make the parsing more tricky, I'd have to add some special cases. 15 = %1111 = $f = $00000f, they all just evaluate to a number. What happens if you want to throw in arithmetic or labels?


Last edited by loopy on Fri Oct 31, 2014 4:46 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Fri Oct 31, 2014 4:38 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
Matter of opinion, but this is my take on it, with some actual historical assembler reference documentation to back it up:

lda $00 through lda $ff (more specifically: a 2-digit address, or an address that's less than 256 in value (in case some crazy decided to do lda 257)) should get assembled as the zero page version. Addresses $100 or larger should get assembled as 16-bit addresses. For equates or mathematical operations, the equates or math should get expanded first (which has to be done anyways since they're assemble-time and not run-time generated) and the decision based off the calculated result. If someone wants to force the 16-bit equivalent, then they should be able to do either a) lda $0000 to lda $00ff, or, b) lda >$00 to lda >$ff (use of > modifier). If you support things like .w pseudo-ops then that should also force 16-bit equivalents (e.g. lda.w $ff would assemble to the 16-bit address).

Justification for this stems from the model/methodology implemented by the Apple IIGS ORCA/M assembler. Here's the manual. The relevant section that describes the above is on PDF pages 335/336 (actual document pages 309/310).

Likewise, the Apple II Merlin 8/16 assembler uses the same model but with a different syntax/modifier/methodology (and fairly risky/scary -- it's accomplished by adding any character to the end of the operand, other than "D" or "L", i.e. LDAq $ff would use 16-bit addressing, as would LDA- $ff or LDAq $ff. I believe they did this to be compatible with other assemblers). Here's that manual. The relevant section is PDF page 97 (document page 85).


Top
 Profile  
 
PostPosted: Fri Oct 31, 2014 5:33 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19335
Location: NE Indiana, USA (NTSC)
tokumaru wrote:
I don't think I ever needed absolute addressing for $0000-$00FF on the NES, but it happens quite often when I'm programming kernels for Atari 2600 games.

If you happen to need that for timing reasons or something on the 2600, you'll either have to use .db (for the opcode) and .dw (for the address) or a mirror of ZP ($0100-$01FF, for example).

koitsu wrote:
lda $00 through lda $ff (more specifically: a 2-digit address, or an address that's less than 256 in value (in case some crazy decided to do lda 257)) should get assembled as the zero page version. Addresses $100 or larger should get assembled as 16-bit addresses.

Unless the address is a label defined later or imported from another file. For the latter situation, ca65 has .globalzp vs. .global.

Quote:
For equates or mathematical operations, the equates or math should get expanded first (which has to be done anyways since they're assemble-time and not run-time generated) and the decision based off the calculated result. If someone wants to force the 16-bit equivalent, then they should be able to do either a) lda $0000 to lda $00ff

$0000 to $00FF expands to $0 to $FF. I'd recommend things like a: modifiers on an address expression to force its size.

Quote:
lda >$00 to lda >$ff (use of > modifier).

Where I come from, >x means (x & $FF00) >> 8, the "high" byte of a value.


Top
 Profile  
 
PostPosted: Fri Oct 31, 2014 5:39 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10164
Location: Rio de Janeiro - Brazil
We're not supposed to used hardcoded addresses in instructions, so the solution has to be something that works well for variables and expressions too.

being able to turn ZP addressing on and off is nice if for some reason you want this to affect several instructions, but you really need per instruction control in order to write timed code efficiently.

Personally I'd go for the operator suffix (.w), because it doesn't mess with the operand. When I'm coding for the Atari 2600, I may need to write to the same address but using different addressing modes each time depending on how many cycles I want. If the solution was something about how many 0's the address has, would I have to define the same variable twice? Once as $07 and again as $0007, giving them different names? should I add $0000 to it to force absolute addressing? none of that makes any sense. Modifying the operator is much cleaner.


Top
 Profile  
 
PostPosted: Fri Oct 31, 2014 5:42 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10164
Location: Rio de Janeiro - Brazil
tepples wrote:
If you happen to need that for timing reasons or something on the 2600, you'll either have to use .db (for the opcode) and .dw (for the address) or a mirror of ZP ($0100-$01FF, for example).

Exactly, which is why I suggested the same be done the NES, if necessary. So far I've been using +$100 after variable names in my Atari 2600 programs, but I don't really like this.


Top
 Profile  
 
PostPosted: Fri Oct 31, 2014 5:51 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5891
Location: Canada
I don't think it really requires a special case for the assembler. You can just do it as data:
Code:
.byte $AD ; LDA absolute
.word foo

If needed frequently, it can become a macro very easily.


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 2 guests


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