Why no SNES homebrew scene?

Discussion of hardware and software development for Super NES and Super Famicom. See the SNESdev wiki for more information.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
User avatar
Bregalad
Posts: 8056
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: Why no SNES homebrew scene?

Post by Bregalad »

Needing to learn two assembly language syntaxes, one for audio and one for everything else. Toward fixing this, byuu developed bass with 6502 syntax for the SPC700, but bass is really more for ROM hacks than for original homebrew. I developed a proof-of-concept reimplementation of 6502 mnemonics in ca65 macro language, which led to blargg's macro packs for SPC700 (both syntaxes) and GBZ80.
Assembler reliability and assembly syntax: Use ca65 with blargg's SPC700 macro pack to avoid problems with the discontinued WLA and to regain familiar (to NES/C64/Atari/Apple II coders) 6502 syntax.
The overall 65xx syntax can be looking quite cryptic (to people who didn't grew up with 6502 computers), myself I don't know (and don't want to know) if TXA transfer from X to A, or from A to X.
I understand the point of Koitsu being annoyed by people whining about the 8/16 bit register swapping, but I am even more annoyed by people whining about mnemonic syntax. I mean, if you can program in assembly for a platform you should able to be flexible and adopt for different architectures.

If you can't code in assembly because some processor uses MOV instead of LDA or whatever, you should seriously question your mental health / sanity.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Why no SNES homebrew scene?

Post by tepples »

I want to share code between music sequence interpretation in an NES game and music sequence interpretation in a Super NES port of the same game. If both assemblers support the same mnemonics, I can write music sequence interpretation once and test twice, and any new features or fixed bugs propagate to the other version. But if they don't, I have to either write my own assembler that takes 6502 mnemonics and spits out something an SPC700 assembler can handle (like blargg's macro pack) or write the music sequence interpreter twice and somehow remember to fix bugs twice and add features twice. I know I have to write the instrument code twice, once for the 2A03 PSG and once for the S-DSP, but reducing what I have to write twice makes the job that much easier.
you should seriously question your mental health / sanity.
If you want to believe that only mentally ill people don't repeat themselves, I'll have to agree to disagree. Wanting to write code with multiple layers of safety doesn't make someone terrible, and wanting to reuse effort doesn't make someone insane.

Besides, it doesn't matter anymore now that blargg's macro pack exists. Line "a." is one of the things that I marked as solved in my follow-up post.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: Why no SNES homebrew scene?

Post by nocash »

What is all that 'whining' about other people's preferences about? I don't see a problem if some prefers a specific syntax. And I can't see how people can feel offended if somebody says the mode switching is uncomfortable to him. In case somebody felt offended because I was saying that mode switching is "insane": Okay, I am sorry, I do admit that it wasn't nice saying that. I just meant it's a unique (and rather uncomfortable) feature of the 65816.

I've never seen a processor - no matter if it's new or old, 4bit, 8bit, 16bit, or 32bit architecture - that requires permanent mode switching. To people being new to that processor (=ongoing homebrew programmers) that means:
  • 1) one must understand what mode switching is about
    2) one may need to select some default setting, like 16bit X/Y and 8bit A, whatever appears best to them
    3) after soon one may notice that the CPU supports 16bit ADC (cool), but it doesn't work in above 8bit mode (damn)
    4) one may need to change the default mode here and where (some games are changing it dozens of times within a single function)
    5) as some people mentioned, one must careful not to mess up different modes (like mode changes in subfunctions, etc.)
The whole subject requires a bunch of design decisions: The default mode, whether to push/pop/change the mode inside of functions (slow on every function call), or to expect the function always being called in proper mode, whether to use 16bit maths, or to use several 8bit opcodes for the same purpose. Once you are familar with it, it may be easier to do that decisions (either you might intuitevely know the best solution, or you might simply decide that you don't care if your code isn't optimal).

About the syntax: I am using a rather uncommon 80x86-style syntax. For example, it's using "MOV dst,src" opcodes (instead of the official LDA, STA, LDX, STX, LDY, STY, TAY, TAX, TSX, TYA, TXA, TXS, TXY, TXY, TDC, TCD, TSC, TCS opcodes with implied operands). The "MOV" variant can be easier to read, and one doesn't need to memorize all the official mnemonics. On the other hand, the official syntax is shorter (less typing time when writing source code), and may be also useful for discussing specific opcodes (like saying that "TXS and TCS don't affect any flags").
Of course any inofficial syntax may look like a sacrilege to some people. That's good. I do like sacrileges. Anyways, in no$sns, I've spent days and weeks on implementing both official & inofficial syntaxes (both in the disassembler as well as in the built-in assembler) for the 65816, for the APU, and also for several coprocessors. Hope that it'll satisfy almost everybody (only, it doesn't include 6502-like APU syntax, sorry).
For homebrew code, I'd be glad is somebody would feel like using or adopting my syntax. The 'clearer' syntax might be making things easier for beginners. The downside is that it doesn't match up with any existing tutorials.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Why no SNES homebrew scene?

Post by tepples »

Z80 has "prefixes" that set a mode, but the next instruction clears the mode. Intel x86 has real, virtual, protected, and now (with AMD64) long mode. I guess that puts 65816's rep/sep somewhere in the middle.

Anyway, for the avoidance of doubt, unsolved problems have been cut down for the moment to d. what to put in the parallax layer, and f. waiting for byuu's new debugger.
User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Re: Why no SNES homebrew scene?

Post by blargg »

nocash wrote:I've never seen a processor - no matter if it's new or old, 4bit, 8bit, 16bit, or 32bit architecture - that requires permanent mode switching.
I'm not that familiar but I think the earlier x86 processors had various addressing modes for 16/32-bit addressing or some such. PowerPC has a little-endian mode. The ARM series has a thumb mode, and the 64-bit ARM (A64?) has a 32-bit mode that might be used a lot for current software.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: Why no SNES homebrew scene?

Post by nocash »

tepples wrote:Z80 has "prefixes" that set a mode, but the next instruction clears the mode. Intel x86 has real, virtual, protected, and now (with AMD64) long mode. I guess that puts 65816's rep/sep somewhere in the middle.
The x86 real/virtual/protected mode and it's 16bit/32bit modes are needed to configured only once (usually done by the operating system), and thereafter one won't need to care about them (and with prefixes, one can still use 16bit values in 32bit mode, and vice versa).
Eventually the REP/SEP opcodes could be compared to that prefixes, except that one must place them manually, and if needed, also restore the old mode manually. That's making the 65816 a bit more challenging than any other processors.
blargg wrote:I'm not that familiar but I think the earlier x86 processors had various addressing modes for 16/32-bit addressing or some such. PowerPC has a little-endian mode. The ARM series has a thumb mode, and the 64-bit ARM (A64?) has a 32-bit mode that might be used a lot for current software.
Disassembling mixed ARM/THUMB can be actually as hard as 65816 code. On the other hand, programming ARM/THUMB is quite easy: one could easly write a complete function (or a whole program) using only one mode.
I didn't knew that PowerPC supports little-endian, but one would probably need it only rarely; like when dealing with little-endian file formats. I've never used 64-bit ARM. But there's one general rule for ARM devrs: 99% of them are using HLL code. I suspect that they won't even know if their compiler should actually happen to do any mode switches.

On the SNES, about 99% of all games are looking like asm code. Only exception that comes to my mind is the X-Band modem bios (it's binary code doesn't look too beautiful, it reminds me a lot of the HLL code that Nintendo is now using on GBA and DS).
Anyways, the SNES hardware includes support for OAMs and scrolling BG layers, so it might be quite possible to write reasonably fast games in HLL code. I wonder if anybody already did so?
User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Re: Why no SNES homebrew scene?

Post by blargg »

My point was simply that there are other processors with modes that you set based on your design and rarely/never change, in response to this:
nocash wrote:I've never seen a processor - no matter if it's new or old, 4bit, 8bit, 16bit, or 32bit architecture - that requires permanent mode switching.
I didn't see it as a question of how justified their modes are, just that they exist in many other architectures.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Why no SNES homebrew scene?

Post by tepples »

nocash wrote:The x86 real/virtual/protected mode and it's 16bit/32bit modes are needed to configured only once (usually done by the operating system), and thereafter one won't need to care about them
Didn't your pre-Win9x emulators have a DOS port that used some sort of DPMI to run the app in protected mode and switch in and out of virtual mode to run DOS?
But there's one general rule for ARM devrs: 99% of them are using HLL code.
And the other 1%, at least on the GBA, were writing the inner loops of sound mixers or 3D software renderers. This goes back to the "same syntax" issue: I used to have a game compiling out of one tree with PC, GBA, and DS ports differing only on input, video, and audio, and most of the video code was shared between GBA and DS versions.
I suspect that they won't even know if their compiler should actually happen to do any mode switches.
On ARM with Thumb interworking, mode switches happen at the start or end of a subroutine. The majority of a GBA program would be in Thumb mode in ROM (or slow RAM in the case of multiboot clients), with certain inner loops or math functions (the kind of things one would do on a Super FX) in fast RAM.
Anyways, the SNES hardware includes support for OAMs and scrolling BG layers, so it might be quite possible to write reasonably fast games in HLL code. I wonder if anybody already did so?
It's been done on the NES: Alter Ego, Zooming Secretary, and MineShaft are in C.

Perhaps once this debate dies down I can take a look at some examples in no$sns in Wine.
User avatar
koitsu
Posts: 4201
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Why no SNES homebrew scene?

Post by koitsu »

Couple random tidbits:

- Certain models of PIC chips, if my memory serves me right, also offer similar features that are adjustable at runtime (register sizes or some kind of memory model, I forget which).

- There are SNES/SFC games which were written in combinations of both assembly and C. Some of the later RPGs were done that way, based on (again if my memory serves me correct) interviews with some developers and/or reverse engineering efforts. If other examples are needed, I could ask Toshi Morita (I'm not sure he'd remember me though, as I met him back in 1993); look him up if you don't know who he is -- not exactly a "unknown" fellow. I wouldn't be surprised if he did a bit of C in Zombies Ate My Neighbors, given his background with compilers.
User avatar
Bregalad
Posts: 8056
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: Why no SNES homebrew scene?

Post by Bregalad »

Of course any inofficial syntax may look like a sacrilege to some people.
This is exactly what I was thinking. It's a sacrilege.
On the other hand, programming ARM/THUMB is quite easy: one could easly write a complete function (or a whole program) using only one mode.
Yeah, usually there is no reason to switch constantly between both : If you want speed you use ARM, if you want to save ROM/RAM space you use THUMB (GBA is a bit of a weird beast here, because THUMB will ALSO be faster when executing from ROM because the CPU lacks an I-Cache and ROM fetches are 16-bit). However, a 100% Thumb program isn't possible as the processors resets in ARM mode, and automatically switch to ARM when an interrupt is executed.
could ask Toshi Morita (I'm not sure he'd remember me though, as I met him back in 1993)
You mean the guy from 6502.org ? I didn't know he wrote SNES games !
User avatar
koitsu
Posts: 4201
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Why no SNES homebrew scene?

Post by koitsu »

"Probably" the guy from 6502.org, since Apple IIGS stuff is how I originally met him. Toshi does a lot of things and is extremely well-versed in, well... everything. Especially 65xxx. Yep, he did some commercial games (for Genesis/Megadrive and SNES/SFC), has worked on gcc (including porting it to some Sega console, I forget which one) and also has some patents. He's very friendly, very professional, and mindblowingly smart.

The guy I'm referring to (sorry, have to use a Google cached copy due to LinkedIn privacy stuff): http://webcache.googleusercontent.com/s ... =firefox-a
AWJ
Posts: 433
Joined: Mon Nov 10, 2008 3:09 pm

Re: Why no SNES homebrew scene?

Post by AWJ »

nocash wrote:On the SNES, about 99% of all games are looking like asm code.
Try disassembling Romancing Sa-Ga's bank 02 (i.e. 02/8000 in SNES address space; ROM offset 0x010000) If that shit isn't compiled C code (complete with hilariously cycle-wasting malloc() and memcpy() library functions) I'll eat my hat.
Near
Founder of higan project
Posts: 1553
Joined: Mon Mar 27, 2006 5:23 pm

Re: Why no SNES homebrew scene?

Post by Near »

> Memory access breaks would be nice. I am afraid it'd be some work (more as for RISC cpus) since the SNES has so many different opcodes with different addressing modes (not to mention all the coprocessors). For performance reasons, I'd need to implement each opcode twice (for normal fast execution, and slower debugging checks).

I have all of my opcodes call out to generic opcode read/write functions, so I only need a breakpoint hook in one place.

I really think one should have a debugger build and a regular build without the debug checks. With a bit of clever coding, you don't even need unsightly #ifdef DEBUGGER blocks around all your debugging hooks. So I'll have:

Code: Select all

alwaysinline void CPU::op_read(unsigned addr) {
  mdr = bus.read(addr);
  add_clocks(speed(addr));
  debugger.op_read(addr, mdr);
  return mdr;
}
And the debugger.op_read(), when DEBUGGER is not defined, is reduced to a no-operation, and thus zero overhead. The forced inlining makes sure that we don't pay for the abstraction, and we get to adhere better to DRY.

Similarly, I have read/write/execute breakpoints for CPU, SMP, APU, VRAM, OAM, CGRAM with the read/write breakpoints accepting an optional "only if read/write value == N" condition. They are indeed immensely useful for ROM hacking / fan translations.

> breakpoints on coprocessor - yup, would be great, especially for the APU, currently only the one-shot breaks (F4-key) are working on APU side. The issue with normal (F2-key) breaks is that I'd need to store some "which break is for which cpu" info in the breakpoint list (and of course, needing to implement them on the different cpus).

Yeah, interleaving operations between the multiple processors is a real bitch. Gets even nastier when your emulator runs at cycle granularity and one processor may be in the middle of an opcode at an instruction breakpoint boundary on another CPU.

Cooperative threading also adds fun limitations to debugging in my own case.

There's a definite struggle between accuracy and debugging power. But in our case all of the less accurate SNES emulators have either no debuggers or shit debuggers, so the bar is pretty low.

> There are SNES/SFC games which were written in combinations of both assembly and C. Some of the later RPGs were done that way, based on (again if my memory serves me correct)

Yeah, it's a big library, probably all variations of anything you can imagine.

Square seems to have made their own bytecode language for their games, which I assume they had large script files and a compiler for. Masaya built games entirely from portable macro code (it was a nightmare to hack, the unrolling was legendary.)

The main issue is that the 65816 is just an absolute shit architecture for compiling C code on. You have exactly one register that you can add and subtract on. You can't even multiply or divide with the base processor.

Any code produced by a compiler is going to be inherently slow. You can definitely write your non-critical code sections with this slow code and probably be okay, but given the processor is effectively ~2.68MHz, with a throughput of less than half of one MIPS, you're going to end up degrading your game the more you use C. It's not like a desktop app where you can just code a few hot functions in ASM and have great performance. Some of the best games choke down the CPU despite being in pure assembler. Absolutely anything called at least once per frame would have hurt those games.

> This is exactly what I was thinking. It's a sacrilege.

It makes it vastly more difficult to share code, that's for sure.

The SMP mnemonics just drove me absolutely nuts. It was the most blatant 6502++ ripoff imaginable, yet they came up with this insane syntax. I would really be shocked if they didn't internally have a 6502-like mnemonic set for their CPU. I'd bet money that their public syntax was strictly a legal decision.

Of course the real fun in deviating from official syntax is that you'll never, ever get two people to agree to the same unofficial instruction set, so you end up with 15 variations.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Why no SNES homebrew scene?

Post by tepples »

byuu wrote:Of course the real fun in deviating from official syntax is that you'll never, ever get two people to agree to the same unofficial instruction set, so you end up with 15 variations.
I think it'd be worthwhile for the community to come to a consensus on a 6502-style syntax for the SPC700, starting from your work on bass. Is there a well-known SNESdev forum, or is this it?
Near
Founder of higan project
Posts: 1553
Joined: Mon Mar 27, 2006 5:23 pm

Re: Why no SNES homebrew scene?

Post by Near »

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. If you look to the Cx4, you see the same thing. segher came up with a temporary syntax for his reverse engineered instruction set. I tried to make it all consistent and nice in my implementation. Then Overload came up with his own mnemonics for it. And then finally nocash came up with his own. So we have four Cx4 mnemonic sets, and in this case, no official one to go by (HG51B169 is undocumented publicly.)

SNES emu dev is mostly on my own board, but even there it's died down substantially since we've fixed all known bugs.

There's some SNES programming forums like RHDN, but ROM hackers don't have the same depth of system knowledge as emulator authors. That and I really don't think the place is run very well.

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.
Post Reply