Need sound help emulating NES on SNES

Discussion of hardware and software development for Super NES and Super Famicom.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Myself086
Posts: 11
Joined: Sat Nov 10, 2018 2:49 pm

Need sound help emulating NES on SNES

Post by Myself086 » Sat Nov 10, 2018 7:40 pm

This summer, I started making a NES emulator running on base SNES as a challenge (no additional processor in game cart).

CPU and PPU emulation are near perfect. I am starting to look into sound and mappers (not all mappers will be supported).

I tried searching for tutorials for both SNES and NES sound but they all seem incomplete. I understand the communication ports and the instruction set for the APU but I'm completely lost when I read anything about playing a sound sample.

User avatar
Memblers
Site Admin
Posts: 3770
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: Need sound help emulating NES on SNES

Post by Memblers » Sat Nov 10, 2018 9:54 pm

Sounds cool. I took a peek at my old SPC code, and it does something basically along these lines:
init:
1: set up a "sample directory"
2: disable ADSR, set gain, main volume, and key-on all channels
play:
1: when duty cycle changes, set new sample #, then key on
2: otherwise, I only write DSP regs for frequency and volume (regs $x0, $x1, $x2, $x3)

Code is in spc.asm if you want to take a peek. http://membler-industries.com/SNES/2a03-src.zip

One problem with my code is that the interpolation totally ruins the sharp edges of the waveforms. IIRC it was _mic who later released a sound emulator showing you can get a cleaner sound by using a set of larger samples played at the highest rates possible, as it will be affected less by the interpolation. My player just had one short sample per waveform that gets scaled over the entire NES frequency.

Myself086
Posts: 11
Joined: Sat Nov 10, 2018 2:49 pm

Re: Need sound help emulating NES on SNES

Post by Myself086 » Sun Nov 11, 2018 9:59 am

Wow, thanks. This looks like exactly what I need.

Are there instructions on how to download the assembler for the SPC-700?
I am using my own assembler for the 65816 and worst case scenario I can adjust it to support the SPC-700.
I don't plan on modifying the SPC code if it already works as intended.

tepples
Posts: 21755
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Need sound help emulating NES on SNES

Post by tepples » Sun Nov 11, 2018 7:14 pm


User avatar
rainwarrior
Posts: 7678
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Need sound help emulating NES on SNES

Post by rainwarrior » Sun Nov 11, 2018 7:20 pm

Thanks for that example, Memblers! Also for the link to that thread, tepples.

psycopathicteen
Posts: 2904
Joined: Wed May 19, 2010 6:12 pm

Re: Need sound help emulating NES on SNES

Post by psycopathicteen » Sun Nov 11, 2018 11:12 pm

How are you going to get around having different PPU registers?

User avatar
Memblers
Site Admin
Posts: 3770
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: Need sound help emulating NES on SNES

Post by Memblers » Mon Nov 12, 2018 3:44 am

Myself086 wrote:Wow, thanks. This looks like exactly what I need.

Are there instructions on how to download the assembler for the SPC-700?
I am using my own assembler for the 65816 and worst case scenario I can adjust it to support the SPC-700.
I don't plan on modifying the SPC code if it already works as intended.
I used "Table-Driven Assembler" (TASM), which was the only option at the time. It's a DOS program, so if you're using something like Win7 64-bit, you'll have to run it in DOSbox. I've attached the SPC700 definition file for it. Command to assemble is "tasm -t700 -b -a spc.asm" (outputs to spc.obj).

If you want to use the code, you're certainly welcome to. The upernes emulator uses it. https://forums.nesdev.com/viewtopic.php?f=3&t=13229
I had thought about going back to it and improving the sound quality (using longer samples like I mentioned previously), but unfortunately I wasn't able to build a windows version of upernes (it was developed for linux), so I didn't take the idea any further.

It does work well for what it does, but there are several things it doesn't even attempt to do:
-no DPCM channel
-no periodic noise
-frame counter alternate timing is ignored (I'm not sure if games really used this, anyways it was usually omitted from NSF rips back at the time anyways)
-doesn't reset pulse phase when $4003 or $4007 is written

Also, the length counter emulation (60hz rate) is done on the 65816 side. SPC does linear counter (240 hz), and sweep register (120hz). It uses timers for those, not sure if I was worried about the SPC getting bogged down, or if I ran out of timers, or what. If you look through that upernes thread, I explained a little more about how it works.
psycopathicteen wrote: How are you going to get around having different PPU registers?
I'm curious too. Presumably it's static recompilation (like replacing register reads/writes with a JSR), which has it's own challenges, but any other way seems pretty difficult.
Attachments
TASM700.zip
(2.13 KiB) Downloaded 274 times

User avatar
koitsu
Posts: 4216
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Need sound help emulating NES on SNES

Post by koitsu » Mon Nov 12, 2018 4:29 am

Other SPC700 assembler possibilities include xkas-plus (see Releases tab for Win32 binaries), or bass. One would have to port the code from TASM to one of the aforementioned. That said: this thread made me happy to see classic TASM getting a shout-out.

Myself086
Posts: 11
Joined: Sat Nov 10, 2018 2:49 pm

Re: Need sound help emulating NES on SNES

Post by Myself086 » Mon Nov 12, 2018 4:36 am

psycopathicteen wrote:How are you going to get around having different PPU registers?
This is a dynamic recompiler emulator which means each function is translated into native code for the Snes at runtime. Some opcodes and IO ports yield different instructions than in the original code. IO ports become JSL to code that emulates them (except gamepad). Some ports are slower to emulate than others, mostly writing to Vram.

tepples
Posts: 21755
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Need sound help emulating NES on SNES

Post by tepples » Mon Nov 12, 2018 6:43 am

Is this anything like upernes?

Myself086
Posts: 11
Joined: Sat Nov 10, 2018 2:49 pm

Re: Need sound help emulating NES on SNES

Post by Myself086 » Mon Nov 12, 2018 8:01 am

tepples wrote:Is this anything like upernes?
I only took a quick look at upernes, upernes is a static recompiler while mine is a dynamic recompiler.

This means that recompiling is done by the Snes itself which has pros and cons.

I only tested SMB so far. First playable version ran the intro at about 15% but now it runs the intro at just over 200% (if uncapped). Sprite 0 is emulated but bit 8 of scrolling seems to have some conflicts for the top part (flickers). The SMB logo is missing in the intro.

I should start a proper thread for this emulator, I was only looking for sound help here.

psycopathicteen
Posts: 2904
Joined: Wed May 19, 2010 6:12 pm

Re: Need sound help emulating NES on SNES

Post by psycopathicteen » Mon Nov 12, 2018 10:24 am

How do you tell the difference between a STA $2007, and data that resembles a STA $2007 instruction?

User avatar
tokumaru
Posts: 11467
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Need sound help emulating NES on SNES

Post by tokumaru » Mon Nov 12, 2018 12:01 pm

I suppose you could recompile only the parts that the PC actually hits (possibly causing slowdown the first time they're executed), or you could keep a copy of the original ROM to use exclusively as data in read operations... The real challenge IMO is self-modifiable code, but thankfully I don't think that's very common in NES games.

Myself086
Posts: 11
Joined: Sat Nov 10, 2018 2:49 pm

Re: Need sound help emulating NES on SNES

Post by Myself086 » Mon Nov 12, 2018 12:12 pm

psycopathicteen wrote:How do you tell the difference between a STA $2007, and data that resembles a STA $2007 instruction?
It only reads whole instructions, it starts from the entry point of the function and reads until something ends the execution (rts, jmp, beq+bne not recognized yet). Branches and jumps within the same bank will be recompiled as part of the same function.

It may derail sometimes but the new code will never affect data, if you attempt to read the STA $2007 by using LDA it will return just that. But during execution, PC register never points to the original addresses. If your code is at $90CC then PC could be at $7F0219 executing a translated copy.

Myself086
Posts: 11
Joined: Sat Nov 10, 2018 2:49 pm

Re: Need sound help emulating NES on SNES

Post by Myself086 » Mon Nov 19, 2018 12:04 am

I decided to implement the SPC instruction set into my personal assembler. The syntax is very close to the original and 2 incomplete lines threw errors. I used the binary from upernes to compare builds.

I optimized part of the CPU code while porting to my assembler. I lost about 2500 cycles per frame and I'm not even doing 240 hz updates yet, it looks like 240 hz were on CPU side because calling emulate_length_counter 4 times in a row fixed most length issues. I don't know how much free time the SPC has but I'd like to move as much code as possible over there. Possibly even transfer data using HDMA.

It sounds kinda bad, I haven't tried upernes but I'm guessing part of my code isn't right.

I sent the Rom to 2 friends and they couldn't get sound to work on various Snes emulators nor console. Either the sound wasn't working or black screen. Which tells me my first uploader is wrong. Sound worked on snes9x v1.53.


EDIT: Here's a clip from a friend after some fixes https://youtu.be/Kvs9MQyCi_s

Post Reply