Project Nested - NES emulator for SNES

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
Myself086
Posts: 28
Joined: Sat Nov 10, 2018 2:49 pm

Project Nested - NES emulator for SNES

Post by Myself086 » Sun Jul 26, 2020 1:20 pm

Project Nested uses a JIT+AOT compiler to convert NES games into SNES games. It runs at roughly full speed depending on the game, 60 fps and mapper support.

Main github page: https://github.com/Myself086/Project-Nested
Download: https://github.com/Myself086/Project-Nested/releases

Specifications requirement for reproduction carts and flash carts:
- Up to 8mb of fast ROM, HiROM format.
- 16kb of SRAM.
- Battery if required by the game.
- No co-processor.

Target specs (planned future updates):
- Up to 8mb of slow/fast ROM, HiROM format.
- 0kb to 256kb of SRAM depending on the game and settings.
- Battery if required by the game.
- No co-processor.

Thank you Memblers for the SPC code!


Mappers: 0, 1, 2, 4

Compatiblity spreadsheet: https://docs.google.com/spreadsheets/d/ ... sp=sharing
If you wish to contribute to this spreadsheet, please let me know what notes to add.

Requests and feedback are welcome.

This top post will be edited over time to reflect the current version.


Smb1.png
Donkey Kong.png
Zelda.png
smb3.png
Last edited by Myself086 on Mon Aug 03, 2020 6:57 pm, edited 2 times in total.

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

Re: Project Nested - NES emulator for SNES

Post by tepples » Sun Jul 26, 2020 2:34 pm

I couldn't get it to work.

I use Ubuntu 18.04 LTS with upstream Wine and Mono repositories. I had to install upstream Mono for Mesen and Mesen-S, which use some features not included in the ancient version of Mono included in Ubuntu's repository.

mono Project.Nested.exe using Mono 6.10.0.104 doesn't open the window at all. Instead, I get this:

Code: Select all

System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies.
File name: 'Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
  at System.Windows.Forms.ComboBox.OnSelectedIndexChanged (System.EventArgs e) [0x00020] in <29ae5f13c05642a1be782372651d31a2>:0 
  at System.Windows.Forms.ComboBox.SetSelectedIndex (System.Int32 value, System.Boolean supressAutoScroll) [0x00093] in <29ae5f13c05642a1be782372651d31a2>:0 
  at System.Windows.Forms.ComboBox.set_SelectedIndex (System.Int32 value) [0x00000] in <29ae5f13c05642a1be782372651d31a2>:0 
  at Project_Nested.Form1.InitProfileList () [0x0005f] in <ea3879e7fc0449d29fadf19f67d450f5>:0 
  at Project_Nested.Form1.Form1_Load (System.Object sender, System.EventArgs e) [0x00018] in <ea3879e7fc0449d29fadf19f67d450f5>:0 
  at System.Windows.Forms.Form.OnLoad (System.EventArgs e) [0x0001f] in <29ae5f13c05642a1be782372651d31a2>:0 
  at System.Windows.Forms.Form.OnLoadInternal (System.EventArgs e) [0x00023] in <29ae5f13c05642a1be782372651d31a2>:0 
wine Project.Nested.exe using Wine Mono in Wine 5.0.1 lets me choose a ROM, but I get this after I choose either Thwaite, Concentration Room, or the Pently demo, each of which is NROM-128:
The type initializer for 'Project_Nested.Injection.Injector' threw an exception.
How should I go about providing more details about this exception so that a fix can be created?

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

Re: Project Nested - NES emulator for SNES

Post by Myself086 » Sun Jul 26, 2020 3:17 pm

I tried this on Mono for Windows and the "Save Snes" button hangs forever. I'm not sure which version of Mono I'm using, I installed it years ago.

Unsupported mappers shouldn't crash the exe.

The first error seems to be triggered by an event for ComboBox index change when changed by code, which it doesn't on Windows.

The second error may be due to out-of-order initialization, this class gave me some problems with its constructor before.

Thanks for the error reports!

EDIT: I misunderstood what you meant at the end. I uploaded a version that should give you a better report. Try Wine again.

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

Re: Project Nested - NES emulator for SNES

Post by tepples » Sun Jul 26, 2020 6:28 pm

Now I get this

Code: Select all

See the end of this message for details on invoking \njust-in-time (JIT) debugging instead of this dialog box.\n\n************** Exception Text **************\nSystem.TypeInitializationException: The type initializer for 'Project_Nested.Injection.Injector' threw an exception. ---> System.IO.FileNotFoundException: Could not find file "Z:\home\pino\Downloads\Project Nested.smc"
  at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean anonymous, System.IO.FileOptions options) [0x0019e] in <a1336bab325642fd867e87ca7626bada>:0 
  at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize) [0x00000] in <a1336bab325642fd867e87ca7626bada>:0 
  at (wrapper remoting-invoke-with-check) System.IO.FileStream..ctor(string,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare,int)
  at System.IO.File.ReadAllBytes (System.String path) [0x00000] in <a1336bab325642fd867e87ca7626bada>:0 
  at Project_Nested.Injection.Injector..cctor () [0x00019] in <3173571227934e8aad5fd8aee0bbec08>:0 
   --- End of inner exception stack trace ---
  at Project_Nested.Form1.btnOpen_Click (System.Object sender, System.EventArgs e) [0x00034] in <3173571227934e8aad5fd8aee0bbec08>:0 
  at System.Windows.Forms.Control.OnClick (System.EventArgs e) [0x0001f] in <afc71676634a41889c6929c14e8a57bd>:0 
  at System.Windows.Forms.Button.OnClick (System.EventArgs e) [0x00037] in <afc71676634a41889c6929c14e8a57bd>:0 
  at System.Windows.Forms.Button.OnMouseUp (System.Windows.Forms.MouseEventArgs mevent) [0x0009a] in <afc71676634a41889c6929c14e8a57bd>:0 
  at System.Windows.Forms.Control.WmMouseUp (System.Windows.Forms.Message& m, System.Windows.Forms.MouseButtons button, System.Int32 clicks) [0x001c3] in <afc71676634a41889c6929c14e8a57bd>:0 
  at System.Windows.Forms.Control.WndProc (System.Windows.Forms.Message& m) [0x005a0] in <afc71676634a41889c6929c14e8a57bd>:0 
  at System.Windows.Forms.ButtonBase.WndProc (System.Windows.Forms.Message& m) [0x0011f] in <afc71676634a41889c6929c14e8a57bd>:0 
  at System.Windows.Forms.Button.WndProc (System.Windows.Forms.Message& m) [0x00056] in <afc71676634a41889c6929c14e8a57bd>:0 
  at System.Windows.Forms.Control+ControlNativeWindow.OnMessage (System.Windows.Forms.Message& m) [0x00001] in <afc71676634a41889c6929c14e8a57bd>:0 
  at System.Windows.Forms.Control+ControlNativeWindow.WndProc (System.Windows.Forms.Message& m) [0x000b3] in <afc71676634a41889c6929c14e8a57bd>:0 
  at System.Windows.Forms.NativeWindow.Callback (System.IntPtr hWnd, System.Int32 msg, System.IntPtr wparam, System.IntPtr lparam) [0x00030] in <afc71676634a41889c6929c14e8a57bd>:0 

\n************** Loaded Assemblies **************\nmscorlib\n    Assembly Version: 4.0.0.0\n    Win32 Version: 4.6.57.0\n    CodeBase: file:///C:/windows/mono/mono-2.0/lib/mono/4.5/mscorlib.dll\n----------------------------------------\nProject Nested\n    Assembly Version: 1.0.0.0\n    Win32 Version: 1.0.0.0\n    CodeBase: file:///Z:/home/pino/Downloads/Project.Nested.exe\n----------------------------------------\nSystem.Windows.Forms\n    Assembly Version: 4.0.0.0\n    Win32 Version: 4.6.57.0\n    CodeBase: file:///C:/windows/mono/mono-2.0/lib/mono/gac/System.Windows.Forms/4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll\n----------------------------------------\nSystem\n    Assembly Version: 4.0.0.0\n    Win32 Version: 4.6.57.0\n    CodeBase: file:///C:/windows/mono/mono-2.0/lib/mono/gac/System/4.0.0.0__b77a5c561934e089/System.dll\n----------------------------------------\nSystem.Drawing\n    Assembly Version: 4.0.0.0\n    Win32 Version: 4.6.57.0\n    CodeBase: file:///C:/windows/mono/mono-2.0/lib/mono/gac/System.Drawing/4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll\n----------------------------------------\nAccessibility\n    Assembly Version: 4.0.0.0\n    Win32 Version: \n    CodeBase: file:///C:/windows/mono/mono-2.0/lib/mono/gac/Accessibility/4.0.0.0__b03f5f7f11d50a3a/Accessibility.dll\n----------------------------------------\nSystem.Configuration\n    Assembly Version: 4.0.0.0\n    Win32 Version: 4.6.57.0\n    CodeBase: file:///C:/windows/mono/mono-2.0/lib/mono/gac/System.Configuration/4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll\n----------------------------------------\nMicrosoft.VisualBasic\n    Assembly Version: 10.0.0.0\n    Win32 Version: 10.0.0.0\n    CodeBase: file:///C:/windows/mono/mono-2.0/lib/mono/gac/Microsoft.VisualBasic/10.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualBasic.dll\n----------------------------------------\n\n************** JIT Debugging **************\n
Turns out it's looking for "Project Nested.smc" when the release names it as "Project.Nested.smc".

After renaming it, I can run it and it produces some .smc file. When I quit, I get this

Code: Select all

Unhandled Exception:
System.InvalidOperationException: Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
  at System.Windows.Forms.Control.MarshaledInvoke (System.Windows.Forms.Control caller, System.Delegate method, System.Object[] args, System.Boolean synchronous) [0x00011] in <afc71676634a41889c6929c14e8a57bd>:0 
  at (wrapper remoting-invoke-with-check) System.Windows.Forms.Control.MarshaledInvoke(System.Windows.Forms.Control,System.Delegate,object[],bool)
  at System.Windows.Forms.Control.BeginInvoke (System.Delegate method, System.Object[] args) [0x0000f] in <afc71676634a41889c6929c14e8a57bd>:0 
  at (wrapper remoting-invoke-with-check) System.Windows.Forms.Control.BeginInvoke(System.Delegate,object[])
  at System.Windows.Forms.WindowsFormsSynchronizationContext.Post (System.Threading.SendOrPostCallback d, System.Object state) [0x0000f] in <afc71676634a41889c6929c14e8a57bd>:0 
  at System.__ComObject.Finalize () [0x0001a] in <a1336bab325642fd867e87ca7626bada>:0 
[ERROR] FATAL UNHANDLED EXCEPTION: System.InvalidOperationException: Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
  at System.Windows.Forms.Control.MarshaledInvoke (System.Windows.Forms.Control caller, System.Delegate method, System.Object[] args, System.Boolean synchronous) [0x00011] in <afc71676634a41889c6929c14e8a57bd>:0 
  at (wrapper remoting-invoke-with-check) System.Windows.Forms.Control.MarshaledInvoke(System.Windows.Forms.Control,System.Delegate,object[],bool)
  at System.Windows.Forms.Control.BeginInvoke (System.Delegate method, System.Object[] args) [0x0000f] in <afc71676634a41889c6929c14e8a57bd>:0 
  at (wrapper remoting-invoke-with-check) System.Windows.Forms.Control.BeginInvoke(System.Delegate,object[])
  at System.Windows.Forms.WindowsFormsSynchronizationContext.Post (System.Threading.SendOrPostCallback d, System.Object state) [0x0000f] in <afc71676634a41889c6929c14e8a57bd>:0 
  at System.__ComObject.Finalize () [0x0001a] in <a1336bab325642fd867e87ca7626bada>:0 
you are registering the same counter address twice: Discarded method code at 6C8F4100
you are registering the same counter address twice: Time spent JITting discarded code at 6C8F40F8
you are registering the same counter address twice: Try holes memory size at 6C8F40F0
you are registering the same counter address twice: Dynamic code allocs at 6C8FF274
you are registering the same counter address twice: Dynamic code bytes at 6C8FF270
you are registering the same counter address twice: Dynamic code frees at 6C8FF26C
you are registering the same counter address twice: Unwind info size at 6C8F494C
you are registering the same counter address twice: Calls to trampolines at 6C8F4788
you are registering the same counter address twice: JIT trampolines at 6C8F4784
you are registering the same counter address twice: Unbox trampolines at 6C8F4780
you are registering the same counter address twice: Static rgctx trampolines at 6C8F477C
you are registering the same counter address twice: RGCTX unmanaged lookups at 6C8F4778
you are registering the same counter address twice: RGCTX num lazy fetch trampolines at 6C8F4774
you are registering the same counter address twice: Async JIT info size at 6C8F45B4
* Assertion: should not be reached at /vagrant/mono/mono/metadata/domain.c:505


abnormal program termination
002d:err:mscoree:expect_no_runtimes Process exited with a Mono runtime loaded.
It builds ROMs, but in Mesen-S, they all just freeze at a black screen. I tried Concentration Room, Thwaite, NROM template, RHDE, the Pently demo, and the NES port of 240p Test Suite. If you want links to the ROMs I used, let me know.

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

Re: Project Nested - NES emulator for SNES

Post by Myself086 » Sun Jul 26, 2020 8:16 pm

Yes, I can look into them real quick. I see some of them on the Wiki.

Concentration Room's menu look fine but selecting anything in the menus crash the emulator.
The crash happens because a return address is pushed using PHA

Code: Select all

	lda	$....,x
	pha
	lda	$....,x
	pha
	...
	rts
This will be supported soon and is near the top of my priority list. Use indirect JMP for the time being or create a patch to replace the RTS opcode to a $62 (RTS+2 illegal opcode) which forces the RTS to compile as an original return.

Thwaite seems to sprites issues and crashes shortly into the menus. BG looks fine though.
Sprite issues are from writing $88 to $4014 (only supports $00-$07 at the moment).
Crash due to the same RTS issue as above game.

RHDE seems to be missing graphics at the bottom, advancing past the second screen crashes the emulator.
Sprite 0 detection could be failing. I can look into the specifics later if you want, I just don't have good debug tools for this one.
Crash due to the same RTS issue as above games.


I'm surprised that all 3 of these got at least the main menus working. I haven't tried MESEN-S though and I have no clue why you're only getting black screens.
tepples wrote:
Sun Jul 26, 2020 6:28 pm
Turns out it's looking for "Project Nested.smc" when the release names it as "Project.Nested.smc".
I never realized that github changed my space to a dot, will fix asap.

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

Re: Project Nested - NES emulator for SNES

Post by Memblers » Mon Aug 03, 2020 6:33 am

This emulator is great. I haven't had this much fun loading games into a partially-working emulator since the early NES emulation days. It's tough to find games that fully work, but that makes it more rewarding when you stumble into one. Plus, it's sometimes fun to see severely glitched-out games. Had a couple games that run OK for a while, then crashed when I died and another one that crashed when I lost all lives (hard game over). With a lot of Konami games you can apparently see a different RAM page for OAM. You can see the variables in the music, and watch timers slide across the screen during title screen transitions, it's kinda funny.

The emulation is kinda quirky, it's interesting to see a lot of simpler games fail on it, then load up something like Zelda or Blaster Master and it play without any major problems. There's non-deterministic stuff going on, sometimes you see very different things happen between resets. I've kind of assumed it's related to the JIT compiler taking over the program. Gyromite kind of sticks out in that regard, because the first time you play (mode A) after a reset, your character sometimes will immediately fall though the floor. Never happens after you die, or game over and start again. Prince of Persia has multiple funny things that can happen if you reset it a lot of times. Sometimes it gets into a glitchy but somewhat playable state, I managed to fall through the floor and walk across a bunch of screens in the game, avoiding everything.

The audio sounds good, the scaled-up samples are a huge improvement compared to how the emulation sounded in the old NSF player.

Has the emulator been tested on a "plain" flash cart yet? I noticed in HIGAN there's usually not much showing up on screen (though the games are running), that makes me wonder if there's some missing S-PPU initialization. By plain I mean just a ROM chip, as the SD2SNES, PowerPak etc, menus won't be leaving the S-PPU in it's power-on default state. Maybe someone here could test that, I can't because I only have an SD2SNES for now.

Loading an SRM file doesn't work for me, it says "illegal character in path". Whether I launch it from Visual Studio, or build the exe and move it somewhere else. I've been curious to see how the feedback from that will affect things. Am I right to suppose this step takes the JIT-compiled parts and makes it into AOT? Whatever it's doing, it sounds fascinating.

I didn't see an EXE file in the release, but I was able to open it in Visual Studio. That could be why I'm getting that error, if it's a different version.
VS Community 2019 16.4.3
C# Tools 3.4.1-beta4
any other info that would help?

It might be helpful to attach the built program in a zip file here in the forum. Also, this won't matter unless there is an updated version, but I don't see any way to tell what version the program is.

edit: I've been doing most testing with ZSNESW (it's old, I know), but so far it seems to show the same results as running the files on my SD2SNES. I haven't seen anything work on Mesen-S, and stuff does work on HIGAN but usually the graphics are hosed (I think I saw Excitebike displayed on it one time somehow, unless I'm imagining that happened).

User avatar
Quietust
Posts: 1566
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: Project Nested - NES emulator for SNES

Post by Quietust » Mon Aug 03, 2020 12:44 pm

I just tried building it in Visual Studio 2015, but it failed due to a ton of syntax errors. Apparently, you need VS 2017 to build this thing...
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.

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

Re: Project Nested - NES emulator for SNES

Post by Myself086 » Mon Aug 03, 2020 5:06 pm

Memblers wrote:
Mon Aug 03, 2020 6:33 am
The audio sounds good, the scaled-up samples are a huge improvement compared to how the emulation sounded in the old NSF player.
Your code helped a lot, thank you very much!
Memblers wrote:
Mon Aug 03, 2020 6:33 am
Has the emulator been tested on a "plain" flash cart yet? I noticed in HIGAN there's usually not much showing up on screen (though the games are running), that makes me wonder if there's some missing S-PPU initialization. By plain I mean just a ROM chip, as the SD2SNES, PowerPak etc, menus won't be leaving the S-PPU in it's power-on default state. Maybe someone here could test that, I can't because I only have an SD2SNES for now.
It was tested on SD2SNES multiple times and on Super Everdrive a few times. The latter only offers 8mb of ROM+RAM combined and nothing else, as plain as you can get and it works fine. I had to send multiple builds to friends until it worked fine on console. The emulators I use just zero out all PPU RAMs which was kind of annoying.
Memblers wrote:
Mon Aug 03, 2020 6:33 am
Loading an SRM file doesn't work for me, it says "illegal character in path". Whether I launch it from Visual Studio, or build the exe and move it somewhere else. I've been curious to see how the feedback from that will affect things. Am I right to suppose this step takes the JIT-compiled parts and makes it into AOT? Whatever it's doing, it sounds fascinating.
I forgot to upload the fix. For v1.0.1, you have to create a profile before clicking "Save Snes" so the profile name is written into the ROM. Also, loading SRM doesn't require loading the correct profile and multi file select is enabled. Loading unrelated SRM files shouldn't cause any problems.

As for AOT, your assumption is correct. The emulator will save sub-routine entry points as bank:addr format. Mapper games usually run out of memory (see smb3 screenshot) and AOT also gives a nice small speed boost from the faster memory. There's no AOT prediction nor optimization yet.
Memblers wrote:
Mon Aug 03, 2020 6:33 am
I didn't see an EXE file in the release, but I was able to open it in Visual Studio. That could be why I'm getting that error, if it's a different version.
VS Community 2019 16.4.3
C# Tools 3.4.1-beta4
any other info that would help?
https://github.com/Myself086/Project-Nested/releases
There's a side link for "releases" on the page that I linked but I'll make it more obvious on the top post, thanks for the feedback.
Memblers wrote:
Mon Aug 03, 2020 6:33 am
It might be helpful to attach the built program in a zip file here in the forum. Also, this won't matter unless there is an updated version, but I don't see any way to tell what version the program is.
I forgot to show version number but v1.1 will show version numbers for exe and smc. They are mostly independent and you'll be able to mix versions between those files, not that it's useful but someone can accidentally only update one or the other and there's less back-and-forth when I'm updating either side.
Memblers wrote:
Mon Aug 03, 2020 6:33 am
edit: I've been doing most testing with ZSNESW (it's old, I know), but so far it seems to show the same results as running the files on my SD2SNES. I haven't seen anything work on Mesen-S, and stuff does work on HIGAN but usually the graphics are hosed (I think I saw Excitebike displayed on it one time somehow, unless I'm imagining that happened).
As for Mesen-S not working, it may be due to some unusual code not supported. Here are some examples:
- At start up, I use the stack pointer and PEA to set my clear-memory DMAs.
- Some leftover WDM for debugging, they aren't removed for the released version as they don't cause any significant time loss.
- I use some of the unused DMA bytes for highly used variables, including $43xB.
- IRQ is set where NMI is supposed to be so I can use SEI for locking thread faster.
- 16-bit STZ to $2180. I use this for queuing VRAM updates. During vblank, I write a 0 at the end before resetting the address (page aligned).
I can't think of anything else at the moment.

I ran into some problems with snes9x during development:
- SRAM seems to be mirrored wrong, I had a bug that only happened on snes9x v1.53 (not the latest, I know) but worked fine on my private emulator + SD2SNES.
- APU echo buffer was located at $2345 by default but you can only select page aligned addresses, strange. There's a bug with my assembler that assigns the wrong address range to SPC code but still works. I found this bug very recently so I have yet to fix the code's address range.
- Some crashes would persist through resets and I had to reload the emulator. I didn't keep a ROM to replicate it, I think it had something to do with DMAs but my memory about this one is a bit foggy.

I develop this NES emulator on my private SNES emulator and the only difference from other SNES emulators/console is smb3's intro not flickering nor lagging, so I can't debug it. If anybody wants to find it, be my guest.

Post Reply