Standardizing 6502-style SPC700 syntax
Moderator: Moderators
Forum rules
- For making cartridges of your Super NES games, see Reproduction.
Standardizing 6502-style SPC700 syntax
There is one "official" syntax for SPC700 opcodes, which Sony allegedly made to hide the fact that there's a 6502 struggling to get out. There have been several attempts to adapt 6502-like mnemonics for the SPC700, such as byuu's bass and blargg's macro pack, which use slightly different syntax. In order to promote sharing of applicable code between NES and Super NES music engines, I'd recommend standardizing 6502-style assembly syntax as byuu suggested. A different syntax for the basic instructions in each assembler makes it harder to move code from one assembler to another or even to read code that someone else posted to a forum or pastebin. I'd like to get as many SNES developer and music hacking communities as possible to join in this standardization effort so that all views can be represented.
My goal is to be able to share as much code as possible between an NES game and the Super NES port of the same game, on the principle of not repeating oneself. Anything that the NES and Super NES versions share would be written in plain 6502 mnemonics, and anything specific to the Super NES could use 65816 or SPC700 instructions. A music engine, for instance, can be divided into music sequence interpretation (which should be shared) and instrument playing (which obviously can't be shared because the 2A03 PSG is not the S-DSP). Sharing code allows a bug fix or feature addition to propagate to the other platform. But anything not shared can use the extra instructions.
Another goal is to ease 6502 and 65816 programmers into SPC700 more gently, even if they're making Super NES-exclusive projects. I prefer to try to make the world a better place by avoiding or correcting misfortunes instead of blindly submitting to them.
First off, what assemblers support SPC700-in-drag? And what are the differences among their syntaxes?
My goal is to be able to share as much code as possible between an NES game and the Super NES port of the same game, on the principle of not repeating oneself. Anything that the NES and Super NES versions share would be written in plain 6502 mnemonics, and anything specific to the Super NES could use 65816 or SPC700 instructions. A music engine, for instance, can be divided into music sequence interpretation (which should be shared) and instrument playing (which obviously can't be shared because the 2A03 PSG is not the S-DSP). Sharing code allows a bug fix or feature addition to propagate to the other platform. But anything not shared can use the extra instructions.
Another goal is to ease 6502 and 65816 programmers into SPC700 more gently, even if they're making Super NES-exclusive projects. I prefer to try to make the world a better place by avoiding or correcting misfortunes instead of blindly submitting to them.
First off, what assemblers support SPC700-in-drag? And what are the differences among their syntaxes?
Re: Standardizing 6502-style SPC700 syntax
I'm assuming that the common 6502 instructions will have 6502 syntax. Is the goal to make up new three-character 6502-like mnemonics for all non-6502 instructions, so that one can take full advantage of the instruction set without ever using the official syntax? In my own code using the macro pack I've mostly used 6502, with some SPC-700-specific instructions occasionally. For some test code I've stuck to SPC-700 only, for clarity.
Re: Standardizing 6502-style SPC700 syntax
Reply to message from Why no SNES homebrew scene?
So far I've done two things, which don't seem to preclude anything you and tepples are talking about: I made a macro package that accepts standard SPC-700 syntax. I made another optional macro package that accepts the subset of 6502 instructions that have essentially direct equivalents (slight differences, e.g. PUSH PSW doesn't have all the exact same flags on the stack, POP A needs a comparison with zero afterwards to implement PLA). This macro package works with the first so that the standard SPC-700 syntax is still fully-supported. Thus, unless your proposal suggests to make the 6502 instructions behave differently (which would seem to break 6502 code reassembled with this), it is a compatible extension of what I've done.
I made a specific point to not innovate anything in these macro packages. I had to make a concession with direct versus absolute addressing, due to the lack of a macro to differentiate and the conflicting approaches for 6502 and SPC-700 and that they share some mnemonics. My thought was that it should either consistently use direct-page where possible, or require the user to do it manually. Since the former can't be done, I chose the latter, rather than inconsistent behavior.
EDIT: additions
I just looked at some of your SPC-700 instructions in 6502 clothing and I'm wondering what the benefit is. For a 6502 programmer using the SPC-700, you'll have to learn new mnemonics either way, so why not learn SPC-700 ones for non-6052 operations?
This highlights that making a 6502-like instruction set is yet a third distinct macro pack project. The first allows SPC-700 on ca65. The second allows common 6502 code shared between a 65xx and SPC-700, or just more familiar coding most of the time. The third that's being discussed here is a new instruction set that's 6502-like for 6502 programmers to learn instead of SPC-700. It's designed to be familiar. It's a new language so besides being familiar to a 6502 programmer, it doesn't give any benefits over using SPC-700 assembly.
I went back and found the message and I had never seen it, or it appeared to just be a pitch for your assembler at the time.byuu wrote:Well right off the bat, I offered to work on a consensus, but blargg already went his own way with his project. Given it had slightly different goals, but not a good omen.
So far I've done two things, which don't seem to preclude anything you and tepples are talking about: I made a macro package that accepts standard SPC-700 syntax. I made another optional macro package that accepts the subset of 6502 instructions that have essentially direct equivalents (slight differences, e.g. PUSH PSW doesn't have all the exact same flags on the stack, POP A needs a comparison with zero afterwards to implement PLA). This macro package works with the first so that the standard SPC-700 syntax is still fully-supported. Thus, unless your proposal suggests to make the 6502 instructions behave differently (which would seem to break 6502 code reassembled with this), it is a compatible extension of what I've done.
I made a specific point to not innovate anything in these macro packages. I had to make a concession with direct versus absolute addressing, due to the lack of a macro to differentiate and the conflicting approaches for 6502 and SPC-700 and that they share some mnemonics. My thought was that it should either consistently use direct-page where possible, or require the user to do it manually. Since the former can't be done, I chose the latter, rather than inconsistent behavior.
I have little interest in trying to make custom 6502-like mnemonics for SPC-700 instructions, so you'll have no differing opinions on how it should be done. If there are current incompatibilities with my 6502 macro pack, I'd be fine getting that fixed.For what it's worth, I am open to changing my SPC700-6502 syntax if anyone wants to discuss it. There's some really hairy issues, like two-operand opcodes that the 65816 lacks (which is a problem as 65816 already uses , for + for some mindfucked reason), and some interesting problems like "ora" not really applying to the non-A or modes (eg or carry and or bit), which is inconsistent with "and" that is the same for carry and bit.
EDIT: additions
I just looked at some of your SPC-700 instructions in 6502 clothing and I'm wondering what the benefit is. For a 6502 programmer using the SPC-700, you'll have to learn new mnemonics either way, so why not learn SPC-700 ones for non-6052 operations?
This highlights that making a 6502-like instruction set is yet a third distinct macro pack project. The first allows SPC-700 on ca65. The second allows common 6502 code shared between a 65xx and SPC-700, or just more familiar coding most of the time. The third that's being discussed here is a new instruction set that's 6502-like for 6502 programmers to learn instead of SPC-700. It's designed to be familiar. It's a new language so besides being familiar to a 6502 programmer, it doesn't give any benefits over using SPC-700 assembly.
Re: Standardizing 6502-style SPC700 syntax
Yeah, like I said, some major goal differences separate us on the SPC700.
Yes, when it comes to things like pla acting differently on flags between the processors, I don't attempt to compensate. It has to be a 1:1 mapping for a debugger/tracer to work with it. But then "pop a" really doesn't tell you that the flags are different from 65816's "pla", either. You still have to learn to work with the chip you are on.
The benefit to me is that SPC700 syntax is awful. Really awful. It looks ugly, and it takes me longer to visually parse out "mov x,y" than "txy"
The 65816-like syntax is nearly twice as compact while accomplishing the same thing, and avoids the nasty "src,dest" vs "dest,src" confusion. That's a real problem for me because I hop between lots of assembly languages all the time: x86/amd64, ARM, SPC700, 65816, 6502, GBZ80, HG51B, NEC uPD, GSU1, etc. Have also done minor stuff in MIPS, SPARC and PPC.
But yes, it also requires making 6502-analogues for the SPC700-only instructions. And those instructions definitely deviate strongly from a traditional 6502.
If you really see no value in what I'm trying to do, then I suppose we can at least classify your pack and my table as separate goals. I don't think there's too much overlap. I'm not trying to have 100% portable code between 6502 and SPC700. I'm trying to make reading and writing SPC700 more bearable.
Yes, when it comes to things like pla acting differently on flags between the processors, I don't attempt to compensate. It has to be a 1:1 mapping for a debugger/tracer to work with it. But then "pop a" really doesn't tell you that the flags are different from 65816's "pla", either. You still have to learn to work with the chip you are on.
The benefit to me is that SPC700 syntax is awful. Really awful. It looks ugly, and it takes me longer to visually parse out "mov x,y" than "txy"
The 65816-like syntax is nearly twice as compact while accomplishing the same thing, and avoids the nasty "src,dest" vs "dest,src" confusion. That's a real problem for me because I hop between lots of assembly languages all the time: x86/amd64, ARM, SPC700, 65816, 6502, GBZ80, HG51B, NEC uPD, GSU1, etc. Have also done minor stuff in MIPS, SPARC and PPC.
But yes, it also requires making 6502-analogues for the SPC700-only instructions. And those instructions definitely deviate strongly from a traditional 6502.
If you really see no value in what I'm trying to do, then I suppose we can at least classify your pack and my table as separate goals. I don't think there's too much overlap. I'm not trying to have 100% portable code between 6502 and SPC700. I'm trying to make reading and writing SPC700 more bearable.
Re: Standardizing 6502-style SPC700 syntax
The very title of this thread (Standardizing 6502-style SPC700 syntax) is self-contradictory. You want to standardize something which is inherently non-standard.
CMOS. CMOS run.
So I see two separate goals: covering all instructions with a self-consistent set of mnemonics and allowing code sharing. I'd say that if an SPC700 instruction also exists on 65C02, 65816, or HuC6280 (such as txy), use the mnemonic from that CPU. That might mean exceeding 3 characters for things like smb3.
Bregalad: Standardizing need not involve ISO, IEC, ITU, IEEE, Ecma, or any comparable organization. It can also mean "creating a parallel community practice that will be treated as a standard by the community".
Bregalad: Standardizing need not involve ISO, IEC, ITU, IEEE, Ecma, or any comparable organization. It can also mean "creating a parallel community practice that will be treated as a standard by the community".
- cpow
- NESICIDE developer
- Posts: 1097
- Joined: Mon Oct 13, 2008 7:55 pm
- Location: Minneapolis, MN
- Contact:
Re: CMOS. CMOS run.
Oh the xkcd of it all.tepples wrote:It can also mean "creating a parallel community practice that will be treated as a standard by the community".
Re: Standardizing 6502-style SPC700 syntax
Which is why we need to get as many of the 14 standards' stakeholders on board as possible.
Re: Standardizing 6502-style SPC700 syntax
I'm not going to say "absolutely not" to four-letter opcodes, but I'd really like to avoid it if possible.
Definitely many opcodes where it'd help a lot, had to make dbnz <label> into bne --y=label. There's no three-letter abbreviation for "decrement and branch if not zero" which makes sense, so we have to express the decrement behavior in the operand section.
But I'm a really, really big fan of the visual symmetry that equally sized opcodes adds. It's one of my favorite features of 6502 syntax.
Definitely many opcodes where it'd help a lot, had to make dbnz <label> into bne --y=label. There's no three-letter abbreviation for "decrement and branch if not zero" which makes sense, so we have to express the decrement behavior in the operand section.
But I'm a really, really big fan of the visual symmetry that equally sized opcodes adds. It's one of my favorite features of 6502 syntax.
Re: Standardizing 6502-style SPC700 syntax
DBNZ and CBNE appear to be literally just macros for a DEC, DEY, or CMP followed by a BNE. A disassembler could just treat it as one opcode that expands to two instructions, which would cause a problem for the assembler. The 6502 assembler would want to emit two instructions, while the SPC700 assembler would emit one.
Code: Select all
dey bne label
dec dd bne label
cmp dd bne label
cmp dd,x bne labelRe: Standardizing 6502-style SPC700 syntax
You keep framing these differences as separation, conflict, but I'm not understanding where the conflict is.byuu wrote:Yeah, like I said, some major goal differences separate us on the SPC700.
Even with this 1:1 mapping it just means that a PLA will show up on yours as PLA; AND #$FF. It seems that the way to think about this is not that with my sp65c02 macro pack its meaning of PLA is differeny, but that its PLA is a macro that expands to (the real) PLA; AND #$FF (since the point of the macro pack is to share code between this and 6502).byuu wrote:Yes, when it comes to things like pla acting differently on flags between the processors, I don't attempt to compensate. It has to be a 1:1 mapping for a debugger/tracer to work with it.
nocash uses traditional OPERATION OPERAND [,OPERAND...] syntax for 6502, because it's beneficial to him, and there's no conflict, because he can use his, you can use yours, I can use mine, tepples can use his, etc.The benefit to me is that SPC700 syntax is awful. Really awful. It looks ugly, and it takes me longer to visually parse out "mov x,y" than "txy"
I don't understand the implicication that we have to have the same values, goals, and do things the same way. So what if I see little value to me in making 65xx-style syntax for all instructions? It doesn't matter what I think regarding its value to you and others that like 65xx-style syntax and are able to code more quickly in it. It's not like I'm going to try to stop you or try to make it difficult for my macros to work with yours.But yes, it also requires making 6502-analogues for the SPC700-only instructions. And those instructions definitely deviate strongly from a traditional 6502.
If you really see no value in what I'm trying to do, then I suppose we can at least classify your pack and my table as separate goals.
Yes, exactly as I understand it.I don't think there's too much overlap. I'm not trying to have 100% portable code between 6502 and SPC700. I'm trying to make reading and writing SPC700 more bearable.
Actually, it's people in a community wanting to make an intentional shared language that attempts to meet everyone's needs, rather than each person doing their own thing and having multiple incompatible variations that hamper code sharing and learning.Bregalad wrote:The very title of this thread (Standardizing 6502-style SPC700 syntax) is self-contradictory. You want to standardize something which is inherently non-standard.
Yeah, when I saw TSB in byuu's 65xx-style SPC-700 instruction list, I thought of HuC6280 and how ones like that would be a good source for ideas and "closer" adherence to 65xx.tepples wrote:So I see two separate goals: covering all instructions with a self-consistent set of mnemonics and allowing code sharing. I'd say that if an SPC700 instruction also exists on 65C02, 65816, or HuC6280 (such as txy), use the mnemonic from that CPU. That might mean exceeding 3 characters for things like smb3.
That's an interesting solution. Why would a 6502 assembler be a problem, since this code isn't meant for 6502 assembly in the first place?tepples wrote:DBNZ and CBNE appear to be literally just macros for a DEC, DEY, or CMP followed by a BNE. A disassembler could just treat it as one opcode that expands to two instructions, which would cause a problem for the assembler. The 6502 assembler would want to emit two instructions, while the SPC700 assembler would emit one.Code: Select all
dey bne label dec dd bne label cmp dd bne label cmp dd,x bne label
if you're suggesting that the macro pack for shared code between 6502 and SPC-700 support this, I don't think it results in any speedup, just a savings of one byte, so it's pretty underwhelming.
Re: Standardizing 6502-style SPC700 syntax
> You keep framing these differences as separation, conflict, but I'm not understanding where the conflict is.
They're different. If one writes code for one, it either won't work or will be behave differently in the other. Eg my pla won't set flags as yours will. Yours will reject my version of dbnz.
But believe me, I'm very, very well acquainted with the idea of having different implementation styles for different purposes. I make my own everything, just about. XML->BML, IPS->BPS, Snes9X->bsnes, pth->libco, Qt->phoenix, SDL->ruby, boost/zlib/libpng->nall, iNES->manifests, etc.
It's just, you know, kind of the reason tepples made this thread was to discuss a unified syntax. I'm always open to the idea of changing my design when people raise good points, so I don't mind this discussion even if nothing comes of it. But I'm also not going to let it stop me from trying out my idea, either.
> Actually, it's people in a community wanting to make an intentional shared language that attempts to meet everyone's needs, rather than each person doing their own thing and having multiple incompatible variations that hamper code sharing and learning.
You see, you just say you don't get it, and then you respond showing that you do get it. That's why tepples made the thread, and I'm happy to at least make an attempt to collaborate and compromise, different goals be damned. If nobody else wants to compromise on their different goals, then that basically just proves the original point I was making in the other thread. It's like herding cats.
Am I all for a universal goal? You bet. Is there a rat's chance in hell of that happening? Nope. And that's fine, it's to be expected.
That said, even if we can't come to an agreement, I am sure if we listen to each other we can at least each improve our own implementations.
> Yeah, when I saw TSB in byuu's 65xx-style SPC-700 instruction list, I thought of HuC6280 and how ones like that would be a good source for ideas and "closer" adherence to 65xx.
Heh, I took TSB from the 65816. Good idea though to look at other 6502 derivatives like HuC for inspiration. I think I'll do just that.
They're different. If one writes code for one, it either won't work or will be behave differently in the other. Eg my pla won't set flags as yours will. Yours will reject my version of dbnz.
But believe me, I'm very, very well acquainted with the idea of having different implementation styles for different purposes. I make my own everything, just about. XML->BML, IPS->BPS, Snes9X->bsnes, pth->libco, Qt->phoenix, SDL->ruby, boost/zlib/libpng->nall, iNES->manifests, etc.
It's just, you know, kind of the reason tepples made this thread was to discuss a unified syntax. I'm always open to the idea of changing my design when people raise good points, so I don't mind this discussion even if nothing comes of it. But I'm also not going to let it stop me from trying out my idea, either.
> Actually, it's people in a community wanting to make an intentional shared language that attempts to meet everyone's needs, rather than each person doing their own thing and having multiple incompatible variations that hamper code sharing and learning.
You see, you just say you don't get it, and then you respond showing that you do get it. That's why tepples made the thread, and I'm happy to at least make an attempt to collaborate and compromise, different goals be damned. If nobody else wants to compromise on their different goals, then that basically just proves the original point I was making in the other thread. It's like herding cats.
Am I all for a universal goal? You bet. Is there a rat's chance in hell of that happening? Nope. And that's fine, it's to be expected.
That said, even if we can't come to an agreement, I am sure if we listen to each other we can at least each improve our own implementations.
> Yeah, when I saw TSB in byuu's 65xx-style SPC-700 instruction list, I thought of HuC6280 and how ones like that would be a good source for ideas and "closer" adherence to 65xx.
Heh, I took TSB from the 65816. Good idea though to look at other 6502 derivatives like HuC for inspiration. I think I'll do just that.
Re: Standardizing 6502-style SPC700 syntax
byuu, your messages to me here and in the other thread have been hurtful and I dread them. I'd really appreciate if you could stick to the technical arguments. You keep lamenting about how things can't happen, and these negative predictions are detrimental to me even participating at this point. I'm trying to understand the situation and offer my ideas, but I don't want to get attacked for misunderstanding or asking for clarification.
The topic here is syntax, which I understand to be the characters you enter into an assembler source file.
As I understand it, the goal here is to create a 65xx-style syntax for all SPC-700 instructions.
I'm not clear on how this relates to 6502 code and SPC-700 code using official syntax. From what I can tell, one can port 6502 code to this new ISA. One can also write fresh code with this new ISA as well. Am I on track so far?
From what you've said, this new ISA doesn't aim for compatibility with 65xx, only a similar style of instructions. Thus, it's not 6502 (semantic differences) and it's not official SPC-700 (syntactic differences). Am I following correctly here?
The topic here is syntax, which I understand to be the characters you enter into an assembler source file.
As I understand it, the goal here is to create a 65xx-style syntax for all SPC-700 instructions.
I'm not clear on how this relates to 6502 code and SPC-700 code using official syntax. From what I can tell, one can port 6502 code to this new ISA. One can also write fresh code with this new ISA as well. Am I on track so far?
From what you've said, this new ISA doesn't aim for compatibility with 65xx, only a similar style of instructions. Thus, it's not 6502 (semantic differences) and it's not official SPC-700 (syntactic differences). Am I following correctly here?
Re: Standardizing 6502-style SPC700 syntax
It's easier to discuss semantic differences between similar syntaxes if the disputed semantics are right in front of us. Apart from anything related to decimal mode or interrupts, what are all the semantic differences between SPC instructions and corresponding instructions of the 65C02?
Re: Standardizing 6502-style SPC700 syntax
* POP A, POP X, and POP Y don't affect the flags.
* RET doesn't increment the return address by one as on the 65C02, and likewise CALL pushes the address of the opcode of the next instruction.
* The N, V, Z, and C flags are set the same for all supported instructions, including in the same bit positions for PUSH PSW etc. but the other flags differ.
* RET doesn't increment the return address by one as on the 65C02, and likewise CALL pushes the address of the opcode of the next instruction.
* The N, V, Z, and C flags are set the same for all supported instructions, including in the same bit positions for PUSH PSW etc. but the other flags differ.