StrawberryNES (6502/NES emulator)

User projects written in or related to FreeBASIC.
Post Reply
squall4226
Posts: 284
Joined: Dec 21, 2008 15:08
Contact:

StrawberryNES (6502/NES emulator)

Post by squall4226 »

Hey guys! I'm back from the dead again. If you remember a while ago I was working on a 6502 emulator in FB. There was a thread a while ago but it seems to have lost some posts and was last posted in on 2014. So I thought to make a new one. Well... tons of progress has been made since I last posted about that a few years ago. It turned into a proper NES emulator project with my friend Nobbs. The 6502 core is REALLY solid - it passes tons of NES CPU test ROMs completely flawlessly. The PPU is a bit suspect - currently I can't figure scrolling out at all and believe me I have tried. But single screen games are working well. There is no audio currently.

Here are some screenshots:
Image
Image
Image

It will run at 140FPS on my i7 3770k @ 4Ghz so you should hit full speed on any reasonably modern machine. Currently only a few mappers are supported(no mapper, unrom, cnrom). It's really not suitable for playing games properly on yet, but it's getting there. Here are some keys:

WSAD - NES D-pad
Left arrow/right arrow - NES buttons
Space - NES SELECT
Enter - NES START
O - options
F1 - save state
F2 - change save state slot
F3 - load state
F11 - ROM info

You can load a ROM by drag and dropping it onto the executable. As I said the 6502 core is really accurate and I am really proud of that. We have put sooooooooo much work in it. Another cool thing about it is the graphics are done in FBGFX! Yes, you read that right! So how are we getting full speed, especially with the image scaled so much when we are plotting using PSET? A simple hack. The emulator only draws pixels that the PPU has changed since the last frame. This reduces the number of PSETs per frame by over 90% in most cases. Currently the only bootable game it causes issues with is Ghosts n Goblins which uses a weird transparency effect that causes havoc:

Image

But most games behave nicely with it. Anyway I just thought it was time to make it a proper thread. Hopefully I can get some help with scrolling from this guy that has been helping me with the PPU stuff(refraction, yes the PCSX2 dev). Without his help we wouldn't have gotten this far on the PPU for sure.

Anyway that's the current situation! Please look forward to future updates!

https://github.com/Sarania/StrawberryNES
Last edited by squall4226 on Jul 29, 2017 2:43, edited 1 time in total.
Nobbs66
Posts: 1
Joined: Jul 29, 2017 2:13

Re: StrawberryNES (6502/NES emulator)

Post by Nobbs66 »

Yeah, you can handle the scrolling. I'll stick to working on the mapper hardware
St_W
Posts: 1626
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: StrawberryNES (6502/NES emulator)

Post by St_W »

Congratulations, that really looks great.

For compiling the source successfully using FB 1.05 32-bit I had to get libz and FreeImage. I used these ones:
http://downloads.sourceforge.net/freeim ... 2Win64.zip
http://users.freebasic-portal.de/stw/fi ... b-1211.zip
To make FreeImage link successfully I had to use the import library, because the automatically generated one (if only using the DLL) caused linker errors.

I tried some of the examples in the "bin" folder. Unfortunately drag & drop didn't work for me on Windows 10, but entering the filename isn't a big issue at all. Maybe I just did something wrong ...

Some hints/suggestions for further improvement:

When playing snake the keyboard input did not always work, especially when keys are pressed for a very short time only. I do not know whether that is an issue of the ROM or the emulator, but it would be nice if this could be fixed.
squall4226 wrote:Another cool thing about it is the graphics are done in FBGFX! Yes, you read that right! So how are we getting full speed, especially with the image scaled so much when we are plotting using PSET? A simple hack. The emulator only draws pixels that the PPU has changed since the last frame. This reduces the number of PSETs per frame by over 90% in most cases.
Wouldn't it be more performant to write to the frame buffer in memory directly? see http://freebasic.net/wiki/wikka.php?wak ... gScreenptr

Is the code 64-bit ready or does it work only with 32-bit FBC?

And from where did you get those ROMs shown in your screenshots above? They look more impressive than the simple included examples :-) I guess they are considered as "Abandonware" as of today?

//edit: tried this one http://www.myabandonware.com/game/prince-of-persia-pd and although it works to some point there are a lot of graphics issues :-(
UEZ
Posts: 988
Joined: May 05, 2017 19:59
Location: Germany

Re: StrawberryNES (6502/NES emulator)

Post by UEZ »

@St_W: can you explain what you did in details with FreeImage to run the code properly please?

I get

Code: Select all

ld.exe: cannot find -lFreeImage
error.

Thx.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: StrawberryNES (6502/NES emulator)

Post by MrSwiss »

UEZ wrote:ld.exe: cannot find -lFreeImage
Simple, the linker (ld.exe) can't find FreeImage (.dll / .a) Library.
You'll have to download it first (before attempting to compile the prog.).

Read FB-Documentation: External Libraries Index --> FreeImage
St_W
Posts: 1626
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: StrawberryNES (6502/NES emulator)

Post by St_W »

UEZ wrote:@St_W: can you explain what you did in details with FreeImage to run the code properly please?
Just put the (32-bit) FreeImage.lib and libz.a (or libz.dll.a) (e.g. from the archive files linked above) into the root folder of the game, where the .fbp and main .bas reside. The exe will be in the "bin" folder and will require FreeImage.dll (and zlib1.dll if you chose libz.dll.a) to run. Additionally there's freetype6.dll, but that did work out of the box - maybe it is loaded at runtime or not used at all? - I didn't take a closer look into the code yet.
I haven't tried a 64-bit build yet, but I guess it could cause troubles, thus the question to squall4226.
UEZ
Posts: 988
Joined: May 05, 2017 19:59
Location: Germany

Re: StrawberryNES (6502/NES emulator)

Post by UEZ »

@St_W: thanks, I can compile it yet properly - no errors.

But when I start the exe I get only a black window for some seconds and afterwards it crashes.

Code: Select all

Unhandled exception at 0x004016A1 in Project Strawberry.exe: 0xC0000005: Access violation reading location 0x00000010. occurred
I used the x86 DLLs for this.
St_W
Posts: 1626
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: StrawberryNES (6502/NES emulator)

Post by St_W »

UEZ wrote:@St_W: thanks, I can compile it yet properly - no errors.
But when I start the exe I get only a black window for some seconds and afterwards it crashes.

Code: Select all

Unhandled exception at 0x004016A1 in Project Strawberry.exe: 0xC0000005: Access violation reading location 0x00000010. occurred
I used the x86 DLLs for this.
Strange ... it didn't crash for me on Win 10 x64 using FB 1.05 x86 using the libz.a and FreeImage.lib as described and otherwise keeping the original DLLs in the "bin" directory. However, I also tried a few different combinations and couldn't reproduce that error. In case you want to try - I've uploaded my build here: http://dropcanvas.com/4u0j3 or http://ge.tt/3iH8Gzl2 or https://ufile.io/w3e8p (valid only for 30 days or less)
//edit: tried/added some different hosters, but unfortunately none is really good ... I'd suggest to use an ad-blocker ;-)

@squall4226: btw, you could use https://github.com/Sarania/StrawberryNES/releases to provide compiled (pre-)release versions of your software. Some users may would like an easy-to-run solution. (just in case you think about putting compiled binaries or other generated artifacts into the GIT repo at this place: that is not a good idea / considered bad practice) ;-)
squall4226
Posts: 284
Joined: Dec 21, 2008 15:08
Contact:

Re: StrawberryNES (6502/NES emulator)

Post by squall4226 »

@ST_W - Yeah I did actually plan to put a release on GITHUB once I got scrolling working but I haven't quite gotten there yet. TBH I didn't expect anyone to really try to run it that quickly lol. So here are a few more things I forgot to point out:

Yes, there are dependencies as you guys have noted - specifically libz and freeimage. It's been so long since I set up my dev environment that I forgot to point that out. Sorry!

As for the crash - I really don't know why it would do that. Hmmm. Of course things are very much WIP here and there are bound to be bugs we don't know about but yeah off the top of my head I don't know what would cause that. It wouldn't surprise me if it was some type of array access out of bounds or something as I am bad to make off by 1 errors >_< Other than that I've ran it on Windows 10 x64, Windows 7 x64 personally. I've only compiled it with 32bit FB.

Now as for the games - the ones included in the source are just extremely simple demo programs that are made to test a 6502 emulator. These programs are free to distribute and have nothing to do with the NES and compatibility for those was only left in because I could. If you are having trouble with input not parsing you can try lowering the goal ops per second in the options mention(which btw I forgot to mention use mousewheel to change options that you mouse over). Anyway if you want to see real NES games you need NES roms - dumps of the cartridges that used to run on the NES. There is copyright law involved so I can't link them or put them in the source, but you can easily find them if you Google it.

Example of some NES games that work pretty much flawlessly(of course no sound):
Balloon Fight
Donkey Kong 1/2/3/Jr
Mario. Bros

Examples of some games that would work if scrolling was implemented(without it you can boot them but when the screen would scroll it will cause a lot of graphical problems - I think this is what you saw with Prince of Persia):
Super Mario Bros.
Contra
Megaman
Castlevania
Bomberman

So yeah. Anyway sorry I forgot to explain some things up above, I had been coding all day and was tired and just wanted to make a thread before I went to bed lol!

Edit: Oh and yes there are much more efficient ways to do the graphics. I just wanted something quick and dirty that would show the output and run at a reasonable speed. However I never expected to get fullspeed using PSET (or in this case using LINE to draw a scaled pixel). I was pleased that I was able. This is the actual code here:

Code: Select all

Sub ppuRender
	Dim As UInteger xoff = screenx - (256*sf)
	Dim As UInteger yoff = screeny - (240*sf)
	For yyy As Integer = 0 To 239
		For xxx As Integer = 0 To 255
			For zzz As Integer = 0 To sf-1
				If ppubuffer(xxx,yyy) <>  oldbuffer(xxx,yyy) Andalso ppubuffer(xxx,yyy) <> -1 Then
					Line nesbuffer, (xoff+(xxx*sf-sf),yoff+(yyy*sf-zzz))-(xoff+(xxx*sf),yoff+(yyy*sf-zzz)), masterpalette(ppubuffer(xxx,yyy))
				ElseIf forcerender = 1 Then
					Line nesbuffer, (xoff+(xxx*sf-sf),yoff+(yyy*sf-zzz))-(xoff+(xxx*sf),yoff+(yyy*sf-zzz)), masterpalette(ppubuffer(xxx,yyy))
					forcerender = 0
				End if
			Next
		Next
	Next
	Put framebuffer,(0,0),nesbuffer, trans
End Sub
What we are doing is having the emulated PPU (think of this as the GPU on the NES) write it's output as color values to an array. Then on scanline 241(i.e. the PPU has finished drawing a frame) we call this sub and dump the changed pixels out to an FB.IMAGE. It works well and is more than fast enough on modern hardware. Maybe at some point later I would make a faster way, but for now I am pleased with it.
St_W
Posts: 1626
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: StrawberryNES (6502/NES emulator)

Post by St_W »

squall4226 wrote:Yeah I did actually plan to put a release on GITHUB once I got scrolling working but I haven't quite gotten there yet. TBH I didn't expect anyone to really try to run it that quickly lol.
Ok for something like (pre-)alpha stage this is totally fine. I'll be following this project for updates.
squall4226 wrote:I've only compiled it with 32bit FB.
hm, then you probably haven't thought about 64-bit compatibility when writing the code, did you? Especially using the appropriate data types (long vs integer) is typically done wrong and prevents a successful 64-bit port. After having a quick look into the code this seems to apply also to your code, unfortunately.
squall4226 wrote:Examples of some games that would work if scrolling was implemented(without it you can boot them but when the screen would scroll it will cause a lot of graphical problems - I think this is what you saw with Prince of Persia)
Yes, I noted that, but Prince of Persia seems to have some other issues too (e.g. it does not show any loading screens and a lot of graphic elements seem to be wrong and flickering even when not moving). Just FYI (I guess there are many compatibility issues with games).
squall4226 wrote:What we are doing is having the emulated PPU (think of this as the GPU on the NES) write it's output as color values to an array. Then on scanline 241(i.e. the PPU has finished drawing a frame) we call this sub and dump the changed pixels out to an FB.IMAGE. It works well and is more than fast enough on modern hardware. Maybe at some point later I would make a faster way, but for now I am pleased with it.
If it's fast enough it's fine. Initially I thought you were drawing directly to the screen (IMHO drawing to a FB.IMAGE first is already way better).
squall4226
Posts: 284
Joined: Dec 21, 2008 15:08
Contact:

Re: StrawberryNES (6502/NES emulator)

Post by squall4226 »

Yeah no, I didn't think about 64 bits at all. I first started the project in late 2013 and I didn't even know there was 64 bit FB(IDK when it actually became a thing tbh). So it's quite possible that compiling it for 64 bits would break things horribly XD.

Nobbs and I took a look at Prince of Persia and we suspect the issue is with nametable mirroring. As I said though the CPU core is really good I've struggled with the PPU(which is what handles graphics). The way the NES does graphics is absolutely insane lol. Slowly we have been making progress on it. Nametables will actually be worked on soon because I think that's what's preventing me from getting scrolling working.

And yeah drawing directly to the screen would be much slower of course. I always use an FB.IMAGE as a framebuffer if I'm using FBGFX. I have a main framebuffer which is just called framebuffer and then another framebuffer which is called nesbuffer. The NES image is written to NES buffer and everything else to the main one and then when we actually update the screen we put the NES buffer down first and then the other over the top with transparency. That way everything you need to see can be seen.

If the project does continue to go forward then at some point I intend to use one of the many UIs people have written for FB to make a much nicer UI. Right now what I've got is functional but not pretty.

Anyway I'm glad to see people take interest in the project. There are of course many NES emulators in the world but there is only one other one that I know of in FB. It's pretty impressive but it has a lot of issues with it's CPU core(though the PPU is further along than mine and it has rudimentary sound). My CHIP-8 emulator in FB is literally one of the most compatible in existence and I am really proud of it. Hopefully we can get this project up to snuff!
UEZ
Posts: 988
Joined: May 05, 2017 19:59
Location: Germany

Re: StrawberryNES (6502/NES emulator)

Post by UEZ »

I got the problem fixed by moving the compiled exe to the bin folder where both dlls are located in.

Might be that I didn't read the instructions carefully - sorry. ^^

Btw, my system is also Win10 x64.

@squall4226: great work!!!
Post Reply