Contacting the Author of ca65?
Moderator: Moderators
Forum rules
- For making cartridges of your Super NES games, see Reproduction.
- Drew Sebastino
- Formerly Espozo
- Posts: 3496
- Joined: Mon Sep 15, 2014 4:35 pm
- Location: Richmond, Virginia
Contacting the Author of ca65?
I'm wondering if maybe the author of ca65 is still around to tell him about how you have to write "a:" if you ever move direct page on the 65816. I know it isn't the biggest deal in the world, but it would be nice if it were fixed and I don't even know if the person is aware of the issue. Is ca65 even still being worked on? I did look on Google, but I didn't find anything. Sorry if I seem pushy or whatnot, I'm just trying to avoid using direct page, but because of this and how my code is set up, a ton of things are going to have to use direct page so I have to keep writing "a:" and it gets a little annoying.
Re: Contacting the Author of ca65?
cc65 is being maintained in github: https://github.com/cc65/cc65
- Drew Sebastino
- Formerly Espozo
- Posts: 3496
- Joined: Mon Sep 15, 2014 4:35 pm
- Location: Richmond, Virginia
Re: Contacting the Author of ca65?
Well, I just emailed the guy who has done the most contributions on it so we'll see what happens...
Re: Contacting the Author of ca65?
Github repo owner has not enabled "Issues" support, therefore bugs/features cannot be requested through there. Instead, the very bottom of http://cc65.github.io/cc65/ provides an Email address to contact for issues/requests. Good luck!
- Drew Sebastino
- Formerly Espozo
- Posts: 3496
- Joined: Mon Sep 15, 2014 4:35 pm
- Location: Richmond, Virginia
Re: Contacting the Author of ca65?
Oops... I guess I sent a message to the wrong email then... You know, could someone tell me the exact problem so I make sense? All I know is that whenever I move direct page, I have to write "a:" for some annoying reason, but I don't know why. I know it's because of something on the 6502, but that's it.
Re: Contacting the Author of ca65?
It's a bit strange that you'd contact the author of a piece of software about something you deem a problem/annoyance without actually understanding why you're having to do what you're doing. I don't think that conversation will end well. :P
Direct page on the 65816 is relocatable via the D register. However, opcodes using direct page (just like 6502/65c02 zero page) are 2 bytes in size (1 byte for opcode, 1 byte for operand/effective address), e.g. lda $10. Assuming 8-bit registers (to make this example simple), if D=$2000, then lda $10 will read from $2010. If D=$0000, then lda $10 will read from $0010.
I cannot find anything in the ca65 manual that denotes what a: prefix represents, but I'm willing to bet it's forcing absolute addressing (full 16-bit address, e.g. lda $0010) rather than direct page addressing. The closest documentation for this syntax I could find was here, with the only example I could find being at the end here, which seems to imply a: forces 16-bit absolute addressing (thus has nothing to do with direct page).
Rephrased/rewritten:
The assembler very likely assumes that if the effective address you've written is within $00-FF (i.e. direct page, or zero page on 6502/65c02) then you probably want the direct page version of the opcode that correlates with it. For example, lda $10 could either be $A510 (opcode $A5 (LDA direct page), address $10), or -- if this is what you want -- it could be $AD1000 (opcode $AD (LDA absolute), address $0010).
This becomes a serious problem/complexity when you start using indexed addressing modes on top of that. Sticking with the examples: lda $10,x could be either $B510 (opcode $B5 (LDA direct page indexed X), address $10) or $BD1000 (opcode $BD (LDA absolute indexed X), address $0010). What happens in both of these cases when X exceeds $EF? The former (direct page) will wrap back around to $00 ($FF->$00), while the latter would read from $0100 ($00FF -> $0100).
This is why you need a way to tell the assembler which addressing mode you want to use, and (I believe it looks like) the a: prefix forces it to use absolute addressing.
Verify it yourself: look at the assembly listing of some code you write where the address is within $00-FF range, both with and without the a: prefix. I bet you'll find without the prefix, the entire instruction uses direct page (is 2 bytes long), while with the prefix it uses absolute addressing (is 3 bytes long), and that the opcodes differ (they would have to).
Direct page on the 65816 is relocatable via the D register. However, opcodes using direct page (just like 6502/65c02 zero page) are 2 bytes in size (1 byte for opcode, 1 byte for operand/effective address), e.g. lda $10. Assuming 8-bit registers (to make this example simple), if D=$2000, then lda $10 will read from $2010. If D=$0000, then lda $10 will read from $0010.
I cannot find anything in the ca65 manual that denotes what a: prefix represents, but I'm willing to bet it's forcing absolute addressing (full 16-bit address, e.g. lda $0010) rather than direct page addressing. The closest documentation for this syntax I could find was here, with the only example I could find being at the end here, which seems to imply a: forces 16-bit absolute addressing (thus has nothing to do with direct page).
Rephrased/rewritten:
The assembler very likely assumes that if the effective address you've written is within $00-FF (i.e. direct page, or zero page on 6502/65c02) then you probably want the direct page version of the opcode that correlates with it. For example, lda $10 could either be $A510 (opcode $A5 (LDA direct page), address $10), or -- if this is what you want -- it could be $AD1000 (opcode $AD (LDA absolute), address $0010).
This becomes a serious problem/complexity when you start using indexed addressing modes on top of that. Sticking with the examples: lda $10,x could be either $B510 (opcode $B5 (LDA direct page indexed X), address $10) or $BD1000 (opcode $BD (LDA absolute indexed X), address $0010). What happens in both of these cases when X exceeds $EF? The former (direct page) will wrap back around to $00 ($FF->$00), while the latter would read from $0100 ($00FF -> $0100).
This is why you need a way to tell the assembler which addressing mode you want to use, and (I believe it looks like) the a: prefix forces it to use absolute addressing.
Verify it yourself: look at the assembly listing of some code you write where the address is within $00-FF range, both with and without the a: prefix. I bet you'll find without the prefix, the entire instruction uses direct page (is 2 bytes long), while with the prefix it uses absolute addressing (is 3 bytes long), and that the opcodes differ (they would have to).
Re: Contacting the Author of ca65?
I assume that Espozo wants a mode that treats all addresses less than $100 as absolute unless specified otherwise.
Re: Contacting the Author of ca65?
Then he loses the benefits of direct page (1 less byte, 1 less cycle). But this is not a "ca65 feature" or "ca65 bug", this is absolutely by design. The programmer needs to understand what he/she is doing. The assembler cannot read the person's mind.tepples wrote:I assume that Espozo wants a mode that treats all addresses less than $100 as absolute unless specified otherwise.
- Drew Sebastino
- Formerly Espozo
- Posts: 3496
- Joined: Mon Sep 15, 2014 4:35 pm
- Location: Richmond, Virginia
Re: Contacting the Author of ca65?
Why does everyone treat it as some sort of bug then?. You know, does anyone know how WLA goes about this?
Re: Contacting the Author of ca65?
I assume that Espozo is willing to "lose[] the benefits of direct page (1 less byte, 1 less cycle)" for addresses $000000-$0000FF in a particular subroutine in favor of gaining "the benefits of direct page" for a different 256-byte area within bank $00 during that subroutine.
Re: Contacting the Author of ca65?
This ""problem"" applies to all 65xx assemblers. This is just how 65xx is -- it's up to the programmer to understand/know if they want direct page addressing or absolute addressing. It's been like this since, well, ever. Merlin816 and ORCA/M both require the same, just that the directives used to tell the assembler what to do varies per assembler.
I can't answer the question of "why people treat it like some kind of bug". You'd need to ask the people who seem to behave/act that way; I'd ask them "what part of 65xx addressing modes vs. code syntax do you not understand? You DO understand the difference between direct page and absolute addressing, yes? If not, learn that!"
Edit: clarify that the situation is the same on 6502/65c02 (regarding zero page vs. absolute); the fact there's no D register / relocatable direct page base doesn't change the situation at all.
I can't answer the question of "why people treat it like some kind of bug". You'd need to ask the people who seem to behave/act that way; I'd ask them "what part of 65xx addressing modes vs. code syntax do you not understand? You DO understand the difference between direct page and absolute addressing, yes? If not, learn that!"
Edit: clarify that the situation is the same on 6502/65c02 (regarding zero page vs. absolute); the fact there's no D register / relocatable direct page base doesn't change the situation at all.
Re: Contacting the Author of ca65?
So what directive should someone use for "I understand/know that I want absolute for all instructions where I do not specify otherwise"? I can reword this feature request in whatever reasonable terminology you come up withkoitsu wrote:This ""problem"" applies to all 65xx assemblers. This is just how 65xx is -- it's up to the programmer to understand/know if they want direct page addressing or absolute addressing.
The bug is the nonexistence of any directive that enables an absolute-by-default, direct-page-only-when-specified addressing mode like that of NESASM.I can't answer the question of "why people treat it like some kind of bug".
Re: Contacting the Author of ca65?
I don't see how this can be implemented reliably. My initial idea was to change the syntax/expression parser to rely on character limits to denote which addressing mode is used. More specifically:
lda $10, lda $10,x, lda label where label = $xx, etc. would use zero page / direct page.
lda $2000, lda $2000,x, lda label where label = $xxxx (or $xxx), etc. would use absolute addressing.
The two problems I can think of with this (and I'm certain there are others):
1. It would break existing code, which means this model would have to default to off, and be a .FEATURE flag,
2. Situations where a label or expression extends past 2 bytes, e.g. label = $26+$f2 (might not be immediately apparent to the programmer). Think of more complex examples and how one could easily end up with an absolute address where one wants zero page or vice versa.
In general I think the feature request being discussed puts more question into the programmer and why they're doing something a certain way vs. actually justifying the need for said feature. I say that with the utmost respect, not judgement. Considering I've used a multitude of assemblers over the years, both cross and native, and I have never seen this come up/discussed/even remotely proposed makes me inclined to think education (of assemblers and addressing modes -- specifically the two together) is a better solution. In other words: don't try to solve what (I deem (IMO)) a social problem with technology.
lda $10, lda $10,x, lda label where label = $xx, etc. would use zero page / direct page.
lda $2000, lda $2000,x, lda label where label = $xxxx (or $xxx), etc. would use absolute addressing.
The two problems I can think of with this (and I'm certain there are others):
1. It would break existing code, which means this model would have to default to off, and be a .FEATURE flag,
2. Situations where a label or expression extends past 2 bytes, e.g. label = $26+$f2 (might not be immediately apparent to the programmer). Think of more complex examples and how one could easily end up with an absolute address where one wants zero page or vice versa.
In general I think the feature request being discussed puts more question into the programmer and why they're doing something a certain way vs. actually justifying the need for said feature. I say that with the utmost respect, not judgement. Considering I've used a multitude of assemblers over the years, both cross and native, and I have never seen this come up/discussed/even remotely proposed makes me inclined to think education (of assemblers and addressing modes -- specifically the two together) is a better solution. In other words: don't try to solve what (I deem (IMO)) a social problem with technology.
- Drew Sebastino
- Formerly Espozo
- Posts: 3496
- Joined: Mon Sep 15, 2014 4:35 pm
- Location: Richmond, Virginia
Re: Contacting the Author of ca65?
So basically, this is what I'm getting from all of this:
If you want to load from a register that is located in the first 256 bytes of ram, you use "a:". If it is outside of it, you don't use "a:". You could move everything outside of the first 256 bytes, but then you are using an extra byte and an extra CPU cycle. Is this correct?
If you want to load from a register that is located in the first 256 bytes of ram, you use "a:". If it is outside of it, you don't use "a:". You could move everything outside of the first 256 bytes, but then you are using an extra byte and an extra CPU cycle. Is this correct?
Re: Contacting the Author of ca65?
No, that's not really correct. If this was 6502/65c02 you would be mostly correct, but this is 65816 we're discussing, so let me go over this one more time.Espozo wrote:So basically, this is what I'm getting from all of this:
If you want to load from a register that is located in the first 256 bytes of ram, you use "a:". If it is outside of it, you don't use "a:". You could move everything outside of the first 256 bytes, but then you are using an extra byte and an extra CPU cycle. Is this correct?
First: you don't "load from registers in the first 256 bytes of RAM". You load a value. I'm pretty sure you know this so it might seem like I'm nitpicking over terminology but more people than just you are reading these threads, so I have to assume this kind of mistake could be picked up by someone else.
Secondly -- and more importantly -- on 6502/65c02, the first 256 bytes of RAM are known as "zero page". When you use zero page addressing in an instruction, e.g. lda $10, you are actually accessing the memory at $0010 (i.e. lda $10 and lda $0010 do the same thing, just that the latter takes up an extra byte and extra cycle due to use of absolute addressing and the extra byte that specifies the page). It's called "zero page" because it's within the "first page (256 bytes) of RAM" and cannot be relocated/moved. Absolute addresses (16-bit) contain the page (e.g. $1234 refers to the $12'th page, memory location $34), which is why it takes an extra byte and an extra cycle.
Does this make sense? Stop reading right now and respond with "no it does not" etc. if it doesn't. You shouldn't read past this part until you understand both 1) zero page and absolute addressing, and 2) the concept of "pages" (256 sections of memory).
Assuming you do understand, onward:
65816's direct page changes the situation -- no longer do you have "zero page", because the D register allows you to move wherever "zero page" is. In other words: if D=$0000 then lda $10 is the same thing as lda $0010 (latter takes up an extra cycle/byte). But if D=$2000, then lda $10 is actually the same thing as lda $2010 (again, latter takes up an extra cycle/byte). In other words: no longer is "zero page" hard-coded to page $00 -- instead, it can be relocated to any other memory location using the D register. You can even set D to something that's not aligned to a page boundary, e.g. D=$1274.
The opcodes for direct page/zero page accesses are different than the ones for absolute addresses.
The a: prefix allows you to tell the assembler "I want you to use absolute addressing regardless of what address I give you".