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.
Near
Founder of higan project
Posts: 1553
Joined: Mon Mar 27, 2006 5:23 pm

Re: Why no SNES homebrew scene?

Post by Near »

I always prefer 8-bit A, 16-bit X/Y. Switch to 16-bit A only when it helps performance (eg inner shift loop of a VWF routine, block transfer that has a catch which prevents simple DMA/MV[NP], etc)

I have tried in the past implementing assembler directives to catch A/X/Y sizes. I find that all it does is trade one set of problems for another, and makes the code uglier.

Catching rep and sep is easy, sure. But what do you do after plp, or rti, or even just a regular rts/rtl? The next function may have different expected sizes when invoked. What happens when you blur the line between functions and jump around with relative offsets? (jump tables and the like.) You're just as capable of getting lazy and missing a force size marker that results in non-working code.

Like koitsu said, it's not really hard. I've written several megabytes worth of 65816 source, and mixing up sizes has only happened to me a few times at the beginning.

But if I really wanted protection against this, here's the way I'd do it: create a usage file format. For each ROM address output by the assembler, store a byte in a usage.bin file that has the following bit-fields for each address: <read, write, execute, M flag, X flag, ...>. M/X flag only matters here for #const opcodes, where it can be detected by the assembler. Now have the emulator generate the same information as the program runs. If it detects a mismatch between the assembler-output and emulator-input M/X flags on a #const opcode, it should alert in the terminal. Even better if you store more usage information (source code line#, previous function name, etc.) Yes, it's one of those annoying run-time instead of compile-time detections, but it's a transparent behavior catch without you having to try and label M/X flag settings all throughout your source.
ARM9
Posts: 57
Joined: Sun Aug 11, 2013 6:07 am

Re: Why no SNES homebrew scene?

Post by ARM9 »

koitsu wrote: It just pisses me off when I see people crying/whining over this shit.
There there, calm your tits. It's quite amusing how many times you've called me a whiner when you don't even understand what I'm talking about. :roll:
I never said that it's hard to keep track of the processor status, I said that it's an inconvenience (admittedly mostly for beginners) that could be further diminished ever so slightly with some fairly basic features. If you don't like it then don't use it, no harm done.

Byuu's approach is probably the most foolproof, but using plp without php sounds questionable.
User avatar
Jarhmander
Formerly ~J-@D!~
Posts: 569
Joined: Sun Mar 12, 2006 12:36 am
Location: Rive nord de Montréal

Re: Why no SNES homebrew scene?

Post by Jarhmander »

ARM9 wrote:
koitsu wrote: It just pisses me off when I see people crying/whining over this shit.
There there, calm your tits. It's quite amusing how many times you've called me a whiner when you don't even understand what I'm talking about. :roll:
I never said that it's hard to keep track of the processor status, I said that it's an inconvenience (admittedly mostly for beginners) that could be further diminished ever so slightly with some fairly basic features. If you don't like it then don't use it, no harm done.

Byuu's approach is probably the most foolproof, but using plp without php sounds questionable.
Use of php with plp is probably implied.
((λ (x) (x x)) (λ (x) (x x)))
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 »

So let me try to wrap up the answers to my original post:
  1. 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.
  2. WAVs: Find some CC-BY or otherwise permissively licensed sound font, or find or write a few quick synth programs. Convert the waves to the sampling rate that is a multiple of 16 times the note frequency, such as a multiple of 4186 for a middle C, and the loop points will line up. Making the sample rate a power of 2 times the note frequency will also make your note frequency tables sane.
  3. Color use: Start by making normal, highlight, and shadow shades of skin, clothing 1, and clothing 2 colors. This allows more freedom than the NES, where you typically get one shadow, one color, and one highlight/skin without having to use overlap.
  4. Layers: The common practice is to use mode 1 with three layers for playfield, parallax, and status, or use OPT mode 2 with two layers for playfield and parallax and sprites for the status bar. But your artists still need to determine what to put in the parallax layer.
  5. A full SPC700 image will eat up 1/4 of 2 Mbit right away, and graphics may compress twice as big as they did on the NES.
  6. Save up for a PowerPak. Accept the misfortune of having to wait years until you're old enough to work, accept the misfortune of having to check retrousb.com daily until the PowerPak is no longer Temporarily Unavailable, and accept the misfortune of having to move a CF card back and forth between your PC and your Super NES. But this still leaves open the difference between the power-up state of the Super NES and the state that the PowerPak menu leaves it in. Are there tests for the power-up state of the Super NES, and does higan pass them?
  7. It's not just copying the CHR assets into VRAM. With all the registers that must be set to a sane value to get a display going, it's best to start from an example that exercises the feature you are looking for. I made a minimal working example for the NES. mic_ lists a few for the Super NES.
  8. Use 816-tcc in the SNES SDK. Or just learn assembly and accept the misfortune. The rep/sep problem can be worked around by establishing calling conventions such as 8-bit A and 16-bit XY set for the parts of your program that interact with I/O registers.
User avatar
MottZilla
Posts: 2837
Joined: Wed Dec 06, 2006 8:18 pm

Re: Why no SNES homebrew scene?

Post by MottZilla »

Besides a PowerPAK you could use one of INL's SNES boards, or a Super EverDrive, or one of many Backup Units. So there are other and cheaper options to test on real hardware.
Near
Founder of higan project
Posts: 1553
Joined: Mon Mar 27, 2006 5:23 pm

Re: Why no SNES homebrew scene?

Post by Near »

> Are there tests for the power-up state of the Super NES, and does higan pass them?

higan is extremely conservative. If I don't know the power-on state of a register (many are write-only, and very challenging to determine initial values for), I default it to a random value that changes with each power cycle / run of the emulator.

I most likely randomize things that shouldn't be. I'd rather have your game break only on higan than only on real hardware.
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 »

While byuu and I don't usually see eye-to-eye, his approach with higan is completely understandable.

I don't ever remember seeing "documented" power-on values (in any document, official or unofficial), all I remember is Nintendo very specifically outlining in their documentation the values values you need to assign to all memory-mapped registers in your RESET routine, ditto with standard sei/clc/xce and the necessary jml/jmp long (where long is bank $80 or higher) for games using high-speed mode (and also in NMI) to properly set the K register.

The manual says something to the effect of "{memory-mapped} register values are unknown when power is applied; initialisation must be done ASAP". It's easier to just do the initialisation per Nintendo and not get OCD about the power-on state. If you're worried about what the actual CPU registers are on power-on, those are actually documented in the official WDC 65816 manual (but I've given hints above :-) ).
Near
Founder of higan project
Posts: 1553
Joined: Mon Mar 27, 2006 5:23 pm

Re: Why no SNES homebrew scene?

Post by Near »

Amusingly, you could reduce "sei/clc/xce" to just "xce", as P is always #$34 after both power cycle and soft reset. But yeah, you're saving two whole bytes. Not worth the brain space to remember that detail.

One of the more evil things I've found ... the stack pointer decrements with each reset, and the Super UFO in particular defaults the stack to #$0100 (it probably set it to zero and then switched to emulation mode.) So if your first instruction is a jsr/jsl, then you switch to native mode and return, your game will crash always on the UFO, and after every ~256/3 resets otherwise. Overwriting the entry point with a JSL is a pretty common ROM hacking way to add an intro splash screen or a trainer.
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 »

So as I understand your post, there's no one-frame delay before the regs become writable like there is on NES. I'll have to study the worked examples more. Can I get a pre-release copy of the source code for higan with this new text-based debugger so that I can compile it in Xubuntu (a Debian derivative) and play with it for a while?
Near
Founder of higan project
Posts: 1553
Joined: Mon Mar 27, 2006 5:23 pm

Re: Why no SNES homebrew scene?

Post by Near »

> So as I understand your post, there's no one-frame delay before the regs become writable like there is on NES.

Not that I've observed, hard to capture the very first video frame output from a running system with the tools I have.

One fun side effect I've seen is that VIRQs trigger one scanline late during only the first frame.

> Can I get a pre-release copy of the source code for higan with this new text-based debugger so that I can compile it in Xubuntu (a Debian derivative) and play with it for a while?

It's currently too unstable to use (only started on it this week), but I'll point you at a pre-release WIP once things are a bit more stable.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: Why no SNES homebrew scene?

Post by nocash »

I've never noticed anything like a one-frame power up delay on SNES either. The initial I/O port settings are documented here http://nocash.emubase.de/fullsnes.htm#snesiomap and here http://nocash.emubase.de/fullsnes.htm#s ... ryandiomap (in the rightmost columns) (values in brackets tend to be so on initial power-up, but are left unchanged on /reset, it. they depend on if/how the game has changed, or when doing things like hotswapping cartridges, they might even contain values from the previously played game, so they could be actually total random).
The write-only PPU register are mostly unknown. Only way to test them would be writing a dozen of test programs, and then examining the TV picture (eg. initialize all PPU registers, but leave one register uninitialized, and then look how that uninitialized register affects the picture). I am assuming that the uninitialized PPU registers are all FFh on power-up (at least some are known to be so: the ppu multiplier input, the vram increment mode, and I think Anomie mentioned that the BG scroll offsets are also like so).
Anyways, it would be best to initialize or zerofill all I/O ports when the game starts (best do that twice, for the 'write-twice' registers). And of course, initialize RAM, VRAM, and Sound RAM too. If that's done right, then it should be quite safe to assume that the game works on both directly booting retail cartridges, as well on flash cartidges with bootstrap loaders.
User avatar
cpow
NESICIDE developer
Posts: 1097
Joined: Mon Oct 13, 2008 7:55 pm
Location: Minneapolis, MN
Contact:

Re: Why no SNES homebrew scene?

Post by cpow »

Funny what one finds when trolling threads not otherwise of interest. I still owe you on this, tepples. :oops:
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: Why no SNES homebrew scene?

Post by nocash »

ARM9 wrote: My wishlist for no$sns features:
  • Being able to set breakpoints on ROM/VRAM/WRAM/etc reads/writes (basically the entire memorymap + isolated stuff like vram and aram) would also be useful.
  • A way to view the contents of VRAM/CGRAM/OAM in hex.
  • A better organized I/O map window, or perhaps even just a simple list view like the debug window interface with the data next to each register, this way you could also map in additional registers easily like GSU and SA-1 mmio.
  • Being able to set breakpoints on coprocessor execution would be nice.
  • Support for .sym files. WLA can generate them but no$sns always complains about corruption (I tried all sorts of modifications but no dice). It'd be really convenient to have symbolic debugging.
Breakpoints for main cpu bug out sometimes, it's impossible to remove one without clearing all breakpoints. It rarely happens and I haven't been able to observe a pattern yet.
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).
Vram/Palette/oam hex viewing for BG Maps, Palette, and OAM you can view HEX values (when moving the mouse across the VRAM viewer windows). Downside is that it doesn't cover non-BG-Map portions of VRAM, and of course there are cases where it'd be nicer to see all values at once, without needing to move the mouse on certain entries.
better organized I/O map window - alltogether I like the I/O map windows as is. They are currently resolving the meaning of the separate bits, which I wouldn't know how to do that in a list view. And they somehow sorted by categories. All sound registers in one tab, the DMA (and misc) registers in another tab. And the PPU registers in two tabs - that's the point where I am occassionally getting lost myself. Maybe I should rearrange those two tabs: One tab that contains solely BG related registers, one for basic control/status, and maybe a third tab for special effects like window & color math.
NB. The coprocessor I/O ports can be viewed in the "Cart Profile" window, but it's really uncomfortable to use (need to reopen the window and scroll down each time when viewing them), but then, coprocessors are probably rarely used in homebrew projects, so it doesn't matter too much.
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).
Breakpoints for main cpu bug out sometimes - whoops. Might have something to do with the new dynamically allocated lists that I had implemented in January 2013. I remember that there has been some problem... but I can't find any release notes about when I have fixed it. Maybe the bug does still exist in current no$sns version - you are using v1.5, don't you?
Support for .sym files that's supported. Allthough I don't seem have to documented how :-) best pick the magicsns source code http://nocash.emubase.de/magicflr.htm store it in no$sns's "STUFF" folder, then use no$sns Utility -> Assemble File to build the binary and .sym file. As for the breakpoints, it's lacking the "for-which-cpu" info, I'll need to change the format someday to something like "APU:NNNN apu_label" and "CX4:NNNN capcom_label".
tepples wrote:Do you test in Wine? Or should I be your Linux guinea pig?
Yes, why not? Would be nice. I haven't tested in Wine. Judging from the latest posts, I am having the impression it does work under wine. Though I got some bug reports about debug font issues some years ago (unsupported GetGlyphOutline function, which is hopefully implemented meanwhile, and, some glitch where wine was using a proportional font, instead of the desired fixed width font). I know that lidnariq has tested the hardware accellerated video zooming under wine, so it seems that no$sns is somehow working, hopefully without font glitches.

PS. The no$sns debugger can be found here: http://nocash.emubase.de/sns.htm
User avatar
benjaminsantiago
Posts: 84
Joined: Mon Jan 20, 2014 9:40 pm
Location: Astoria, NY
Contact:

Re: Why no SNES homebrew scene?

Post by benjaminsantiago »

tepples wrote:So let me try to wrap up the answers to my original post:
  1. 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.
  2. WAVs: Find some CC-BY or otherwise permissively licensed sound font, or find or write a few quick synth programs. Convert the waves to the sampling rate that is a multiple of 16 times the note frequency, such as a multiple of 4186 for a middle C, and the loop points will line up. Making the sample rate a power of 2 times the note frequency will also make your note frequency tables sane.
  3. Color use: Start by making normal, highlight, and shadow shades of skin, clothing 1, and clothing 2 colors. This allows more freedom than the NES, where you typically get one shadow, one color, and one highlight/skin without having to use overlap.
  4. Layers: The common practice is to use mode 1 with three layers for playfield, parallax, and status, or use OPT mode 2 with two layers for playfield and parallax and sprites for the status bar. But your artists still need to determine what to put in the parallax layer.
  5. A full SPC700 image will eat up 1/4 of 2 Mbit right away, and graphics may compress twice as big as they did on the NES.
  6. Save up for a PowerPak. Accept the misfortune of having to wait years until you're old enough to work, accept the misfortune of having to check retrousb.com daily until the PowerPak is no longer Temporarily Unavailable, and accept the misfortune of having to move a CF card back and forth between your PC and your Super NES. But this still leaves open the difference between the power-up state of the Super NES and the state that the PowerPak menu leaves it in. Are there tests for the power-up state of the Super NES, and does higan pass them?
  7. It's not just copying the CHR assets into VRAM. With all the registers that must be set to a sane value to get a display going, it's best to start from an example that exercises the feature you are looking for. I made a minimal working example for the NES. mic_ lists a few for the Super NES.
  8. Use 816-tcc in the SNES SDK. Or just learn assembly and accept the misfortune. The rep/sep problem can be worked around by establishing calling conventions such as 8-bit A and 16-bit XY set for the parts of your program that interact with I/O registers.
Not sure if this is mentioned other places in the thread, but don't underestimate the power of dithering:
http://upload.wikimedia.org/wikipedia/e ... dither.png

Depends on your taste, but you can reduce the amount of colors significantly depending on how much you are willing to put up with. I do it by hand sometimes, but you can also get interesting results out of Photoshop with the save for web option. If you save it as a .gif you can reduce the amount of colors and play with how the dithering works (pattern, noise, etc)
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 »

benjaminsantiago wrote:Not sure if this is mentioned other places in the thread, but don't underestimate the power of dithering
Trust me; I've played with dithering before as a way to compensate for another platform's lack of HDMA. That's why I've suggested breaking each 15-color palette into five 3-color subpalettes, to allow each color to be dithered light and dark.
If you save it as a .gif you can reduce the amount of colors and play with how the dithering works (pattern, noise, etc)
I had to alternate strips of pattern and noise to get things to look good.
Post Reply