Page 2 of 4
Re: Reimplementing 6502 syntax in ca65
Posted: Mon Nov 18, 2013 10:25 pm
by thefox
Code: Select all
.if (arg) < $100
; .out .sprintf("ZP %x", argvalue)
.byte $04 | (inst), argvalue
These kind of checks won't work if
arg is a forward reference or if it is imported from another module. This is the reason why ca65 has separate
.import and
.importzp control commands (it always needs to know the address size of the symbols as it's generating the code). I guess in theory it could solve the
.if foo < $100 as a special case if the symbol has been imported as zero page, but I don't think it's smart enough to do that (yet?). And I don't think there's any way to check from code if a symbol has been defined as being on zeropage or not.
If ca65 doesn't know the address size of a symbol (i.e. it's a forward reference), it uses absolute addressing for it, and if it later realizes the address would've fit in 8 bits, it spits out a warning:
Code: Select all
lda foo
foo = 123
>cl65 -t none forward-ref.s
forward-ref.s(1): Warning: Didn't use zeropage addressing for `foo'
Re: Reimplementing 6502 syntax in ca65
Posted: Tue Nov 19, 2013 10:32 am
by Movax12
To solve zeropage you need one of these:
- Identifier must be constant at assemble. (.res doesn't get you this)
Explicit zeropage syntax specified in code and evaluated by the macro
You could declare your zeropage identifiers as:
foo = $00
And so on and there would be no issue.
You could also take advantage of .struct
Code: Select all
.struct
foo .byte
bar .byte
.endstruct
This would work well for single module projects, but won't work for multiple modules.
For syntax:
ca65 supports (by default) a
z: prefix to force zeropage, or the lowbyte operator will work as well
<
Maybe copy that idea?
Re: Reimplementing 6502 syntax in ca65
Posted: Tue Nov 19, 2013 10:43 am
by tepples
So is there a way to fix up the macros, or would one have to give up and implement other assembly languages directly in the C source code of ca65?
Re: Reimplementing 6502 syntax in ca65
Posted: Tue Nov 19, 2013 10:50 am
by Movax12
What else needs to be fixed up? I think this zeropage issue is the only thing that is an issue and I think it can be worked around. I suppose you lose compatibility with regular ca65 source files.
Re: Reimplementing 6502 syntax in ca65
Posted: Tue Nov 19, 2013 12:37 pm
by blargg
GB-Z80 has as I remember a special syntax for its direct page ($FFxx). And SPC-700 ! before absolute addresses.
In my code I always use < where timing is important, since you can never trust the assembler to use zero-page anyway. So it's an only optimization issue in my eyes. Compared to the other assemblers I'm using, I'd take this to have ca65's goodness (like great macros that don't cower at a task like this) any day.
Re: Reimplementing 6502 syntax in ca65
Posted: Tue Nov 19, 2013 1:29 pm
by tepples
I see what you mean: ca65's .if statement isn't smart enough to determine that a label explicitly imported as zero page is less than $100.
Code: Select all
; Import tests
.importzp boo
lda boo
produces
Code: Select all
ca65none.s(835): Error: Constant expression expected
ca65none.s(304): Note: Macro was defined here
ca65none.s(247): Note: Macro was defined here
So how should I change the macros to incorporate useful workarounds?
Re: Reimplementing 6502 syntax in ca65
Posted: Tue Nov 19, 2013 2:19 pm
by thefox
tepples wrote:So how should I change the macros to incorporate useful workarounds?
If you don't mind losing ca65 compatibility, you could make it work similar to NESASM, where < in the beginning would use zero page addressing, and otherwise it would always use absolute addressing. When you use absolute addressing, you could of course also set up asserts (maybe user configurable?) so that the user gets a warning if absolute addressing is used when it's not needed. Naturally assert could also be useful if user specifies zero page addressing but the address ends up being >= $100.
Or you could coerce somebody to add a new pseudo function to ca65 that returns the address size of a symbol.

That might be reasonable if this is indeed the only problematic part of the implementation.
Re: Reimplementing 6502 syntax in ca65
Posted: Tue Nov 19, 2013 2:32 pm
by qbradq
This may not be of interest to you, but from a HLL language implementer's perspective having to explicitly specify that a reference is in zero-page is a bummer. That said I already have to do that for my language that targets ca65 due to how imports and exports work.
Re: Reimplementing 6502 syntax in ca65
Posted: Tue Nov 19, 2013 3:10 pm
by Movax12
thefox wrote:..you could coerce somebody to add a new pseudo function to ca65 that returns the address size of a symbol.
This is the best idea, I don't know how open the new maintainer is to ideas like this though.
Another idea (workaround with nice syntax):
Code: Select all
; define macros
.macro setZP ident
.scope ident
isZP = 1
.endscope
.endmacro
.macro myImportZP ident
.importzp ident
setZP ident
.endmacro
; ... somewhere else in source:
.zeropage
foo: .res 1
bar: .res 2
setZP foo
setZP bar
; inside tepples' macro code:
.ifdef arg::isZP
; implement ZP addressing
.else
; implement other
.end
Re: Reimplementing 6502 syntax in ca65
Posted: Tue Nov 19, 2013 3:50 pm
by lidnariq
Movax12 wrote:thefox wrote:..you could coerce somebody to add a new pseudo function to ca65 that returns the address size of a symbol.
This is the best idea, I don't know how open the new maintainer is to ideas like this though.
He's been accepting quite a number of pull requests on github:
https://github.com/oliverschmidt/cc65/p ... ate=closed
Re: Reimplementing 6502 syntax in ca65
Posted: Tue Nov 19, 2013 5:13 pm
by blargg
On the one hand, having an operator that allows implementing the instruction set entirely with macros seems like a worthwhile thing, just because it means that its facilities are "complete" in some way (assuming there aren't other problems as well). On the other hand, this is only needed to implement the 65xx instruction set, which the assembler already implements.
Re: Reimplementing 6502 syntax in ca65
Posted: Tue Nov 19, 2013 6:48 pm
by tepples
blargg wrote:On the other hand, this is only needed to implement the 65xx instruction set, which the assembler already implements.
It's also needed for SPC700, which the assembler does not already implement.
Re: Reimplementing 6502 syntax in ca65
Posted: Wed Nov 20, 2013 11:19 am
by thefox
If you fork ca65, implement the feature, then demonstrate the 6502 reimplementation can work with the fork, I think there's a good chance it will be accepted into the main branch. I don't think it's a good idea to bring it to the main branch before it has been demonstrated to be useful.
Re: Reimplementing 6502 syntax in ca65
Posted: Sun Nov 24, 2013 9:32 pm
by tepples
The missing feature is a function to get a label's address size. I think the place to start is to use .referenced(label) or something as a model to make .addrsize(label), which queries SymEntry::AddrSize defined in symentry.h. A quick
search of the source code reveals that changes would be needed in expr.c (translate TOK_REFERENCED into calls to FuncReferenced), scanner.c (translate ".REF" and ".REFERENCED" into TOK_REFERENCED), and pseudo.c (handle unexpected occurrences of ".REFERENCED"). Who has more experience hacking ca65?
Re: Reimplementing 6502 syntax in ca65
Posted: Mon Nov 25, 2013 1:41 am
by Movax12
I decided to try and add this. I added
.addrsize(ident), and it works..for an identifier, but it doesn't solve the problem, since there is often code with an offset added, such as:
To decide what addressing mode that example is would take a lot more macro code and searching for identifiers etc. You could assume a simple case like that, and get away with it most of the time, but using scopes and more complex expressions won't work. I'm not sure how ca65 decides by default what to do actually.
To really do this right I think it should be implemented in the ca65 source.
BTW files changed:
expr.c
pseudo.c
scanner.c
token.h