Spherical forums

User-Made => Projects => Topic started by: Eggbertx on April 08, 2016, 03:04:49 am

Title: Sphere 6502 emulator
Post by: Eggbertx on April 08, 2016, 03:04:49 am
I'm working on porting an emulator of the ancient (relatively speaking) 6502 processor (https://en.wikipedia.org/wiki/MOS_Technology_6502) from 6502asm.com (http://6502asm.com/) to run in Sphere. Getting it to draw as it would on the site (without having to worry about flipping buffers) has been a bit of a chore, but I got it mostly working, but I've noticed that it's significantly slower than the website, both compiling and drawing. Because of the upscale and the way it draws to the screen (coloring individual pixels for each draw), I've had to create <scale_width> by <scale_height> surfaces for each pixel and then fill it with a rectangle (surface_obj.rectangle(0,0,fullwidth,fullheight,color). The issue of slow compilation shouldn't (hopefully) be too much of an issue to look into, but do you have any advice for improving drawing? How does Duktape's spead compare with browsers, or could it just be an issue of having to optimize the site's code to work well with minisphere?
(http://i.imgur.com/Huez27G.png)


EDIT: wow, I just checked, and both the 1.5 and 1.6 engines perform far better than minisphere. Could this be an issue with minisphere's javascript engine, or would you like me to upload the game folder (please don't look at the source, it's incredibly hacky and I'm not proud of it) and have someone here try it in Windows?
Title: Re: Sphere 6502 emulator
Post by: Fat Cerberus on April 08, 2016, 03:17:35 am
Duktape is slower than most browsers due to only being interpreted with no JIT.  However in this case it sounds like your bottleneck is rendering related.  Surfaces in minisphere are created in hardware, so that's probably your problem.

If you're working directly with pixels, one thing you can try is set up a Uint32Array instead of a Surface and write your pixels to that.  Then just: `new Image(width, height, u32arr)` and you can blit the image.
Title: Re: Sphere 6502 emulator
Post by: Fat Cerberus on April 08, 2016, 03:29:06 am
Wait a minute, why are you making individual surfaces for solid-color pixels?  You could just use Rectangle() for that...
Title: Re: Sphere 6502 emulator
Post by: Fat Cerberus on April 08, 2016, 08:43:57 am
Thinking about this now that I've had some sleep and looking at both your screenshot and the source code from 6502asm.com, it looks like your primary limiting factor is vsync.  See that 61 fps on the bottom?  What I'm guessing happens is that you're becoming "tidal locked" by vsync and thus only being able to write 60 pixels per second (less than two lines).  Sphere 1.5 and 1.6 with the standard32 plugin is actually software-rendered, so I'm guessing vsync doesn't come into play.  I'd be curious what gets displayed if you press F11 in Sphere 1.x.  I'd wager it's a lot higher than 60fps. ;)

Try turning off forced vsync in your graphics driver and see what happens.  There's no reason minisphere should be slower than Sphere 1.5.

This is actually one of the primary reasons spherun displays the framerate by default.  It can be very useful information when trying to debug something like this!
Title: Re: Sphere 6502 emulator
Post by: Eggbertx on April 08, 2016, 02:59:41 pm
>Duktape is slower than most browsers due to only being interpreted with no JIT.
Thinking about it, that shouldn't be an issue, since I believe that most 6502s are only 1-2 MHz.

Also, it's been a long time since I regularly worked with Sphere (hence my random disapperances). I forgot about the Rectangle function. I was aware that using surfaces could present lag, but I couldn't think of another way to do it.

It's set to true by default, but I turned off forced vsync (or "Sync to VBlank" as it's called in NVIDIA Settings), and it runs much faster. Still not as fast as the 6502asm.com version (probably because of the surface usage), but if you've looked at some of the stuff on there, it seems to run way too fast, like the helicopter game that can barely respond before you crash.



EDIT: Even with the surface replaced with Rectangle(), it's still very slow. I'm not sure if this is because of poorly optimized code on my part or issues with misplaced FlipScreens, but I'm looking into it now. Just for testing, since 6502asm.com was put up ~10 years ago (according to the header), I'm creating a Windows XP VM with roughly the specs of an average computer then to test the speed.
Title: Re: Sphere 6502 emulator
Post by: Fat Cerberus on April 08, 2016, 04:07:43 pm
Hm, it's hard to say without seeing your code.  Duktape is definitely faster by far (at least twice as fast on average) compared to the SpiderMonkey in Sphere 1.5, and probably about on par with 1.6.  With vsync turned off and no SetFrameRate() calls, your only limiting factor for FlipScreen is how fast the hardware can flip the backbuffer.  On modern machines that tends to be north of 2,000 fps in most of my benchmarks.  Now that sounds like a lot, but here's the thing: Your emulated display is 32x32 (= 1K pixels).  If you do a FlipScreen() for every pixel written and fully update the screen every frame, 2,000fps only gets you just south of 2 (!) emulated frames per second.  3,000 fps would net you 3.

Now I'm not sure how Sphere 1.x implements FlipScreen(), but minisphere performs an actual backbuffer flip every time you call it, along with event loop processing, etc.  I think you'll have to limit the number of times you call it.
Title: Re: Sphere 6502 emulator
Post by: Flying Jester on April 08, 2016, 04:09:01 pm

>Duktape is slower than most browsers due to only being interpreted with no JIT.
Thinking about it, that shouldn't be an issue, since I believe that most 6502s are only 1-2 MHz.


You may be surprised what it can take for accurate emulation.

It takes well over 2 GHz with Higan (nee bsnes) just to emulate a SNES, and that's using a combination of highly tuned C, C++, and assembly (including some crazy hacks like libco which uses some CPU instructions that no compiler can take advantage of).

On the other hand, for a system with few chips, you can almost always get away with slower languages. There is a GB, GBC, and GBA emulator written in JS that runs acceptably with pretty good accuracy, even on the pre-JIT Firefox versions. If you are mostly worried about a single chip emulation (which is what the GB is, almost entirely) then you will be just fine. Once you start adding other components of the system it may become an issue.
Title: Re: Sphere 6502 emulator
Post by: Eggbertx on April 08, 2016, 04:11:28 pm
Wow, this is embarrasing. Even on Windows XP, running ye olde Netscape 7, with the execution cap lowered to make the speed more realistic, it's still significantly faster
https://db.tt/jgZZ9lYL (https://db.tt/jgZZ9lYL)
Title: Re: Sphere 6502 emulator
Post by: Fat Cerberus on April 08, 2016, 04:17:24 pm

It takes well over 2 GHz with Higan (nee bsnes) just to emulate a SNES, and that's using a combination of highly tuned C, C++, and assembly (including some crazy hacks like libco which uses some CPU instructions that no compiler can take advantage of).


...why?  This seems excessive.  I've been using SNES emulators since I had an 83MHz Pentium OverDrive (basically a 486 on steroids) and it ran well enough there.  Granted, that was with ZSNES on DOS where there is practically zero overhead from the OS, so we'll use a more fair comparison: Snes9x for Windows.  I've been running that since I had a 500MHz Celeron that could barely run Windows XP, and I don't remember seeing any lag.  The emulation seemed pretty damn accurate, too. What kind of crazy things is Higan emulating that it needs 2+ GHz?
Title: Re: Sphere 6502 emulator
Post by: Fat Cerberus on April 08, 2016, 04:18:30 pm

Wow, this is embarrasing. Even on Windows XP, running ye olde Netscape 7, with the execution cap lowered to make the speed more realistic, it's still significantly faster
https://db.tt/jgZZ9lYL (https://db.tt/jgZZ9lYL)


See my post above.  My suspicion is that you need to cool it on the FlipScreen() calls.  Like I said though, without seeing your code it's hard to know what's wrong.
Title: Re: Sphere 6502 emulator
Post by: Eggbertx on April 08, 2016, 04:48:05 pm

On the other hand, for a system with few chips, you can almost always get away with slower languages. There is a GB, GBC, and GBA emulator written in JS that runs acceptably with pretty good accuracy, even on the pre-JIT Firefox versions. If you are mostly worried about a single chip emulation (which is what the GB is, almost entirely) then you will be just fine. Once you start adding other components of the system it may become an issue.

Yeah, I remember I posted a link to that HTML5 GBA emulator. It ran poorly on my old laptop, but it was very much an "economy" laptop.

And I was going to post that the FPS takes a nosedive if the game makes calls to $FF, which holds keypresses, but I just had it run the adventure one, which is one of the most complex ones on the site, and it ran pretty decently.



See my post above.  My suspicion is that you need to cool it on the FlipScreen() calls.  Like I said though, without seeing your code it's hard to know what's wrong.

I'm going to upload my code in just a bit, but how would you normally write to the screen and keep it updated regularly while writing to different pixels, as in this case? The original doesn't use buffers, since because it's drawing to table elements as pixels, it doesn't need to.
Title: Re: Sphere 6502 emulator
Post by: Eggbertx on April 08, 2016, 04:49:54 pm
Also, my actual FPS doesn't seem to be that bad, even when the CPU screen's is. For example, the skier.asm has horrible FPS, yet it shows the actual FPS at around 1000
Title: Re: Sphere 6502 emulator
Post by: Eggbertx on April 08, 2016, 04:51:51 pm
here is the game's folder (https://db.tt/OGtYd93s)
Title: Re: Sphere 6502 emulator
Post by: Flying Jester on April 08, 2016, 05:46:28 pm
@Lord English: That's because ZSNES is not accurate in the slightest, though. Neither is snes9x. They emulate a machine that only somewhat represents an SNES, and happens to work properly with some well known games like Super Mario World and Zelda: LttP. In fact, at one point one of the two (I forget which) shipped with copies of textures of all games that used a certain format, just because they didn't want to (or couldn't) implement some feature that would let them actually load those textures.

Once you actually make accuracy a goal, performance is tricky. The SNES requires sub-cycle precision to emulate the interactions of the coprocessors in it. You can just not do that, and just YOLO it. That's what ZSNES and Snes9x do, and because of it only a handful of games really work properly, and most obscure games simply do not work at all. Higan/bsnes has actually achieved 100% compatibility with all commercial games, and it still isn't truly 100% accurate (some homebrew exists that has different behaviour on hardware as it does on Higan).

There's a balance to be sure, but the accuracy of snes9xand ZSNES is just embarrassing. People tend to accept the poor accuracy, but that doesn't mean that it isn't inaccurate.

My point is that "it shouldn't be hard to emulate a system with a 2MHz CPU" isn't always true. There's a lot more to the performance of an emulator than the clock speeds of the chips.
Title: Re: Sphere 6502 emulator
Post by: Fat Cerberus on April 09, 2016, 12:29:48 am
@Eggbert:
I did some testing.  Compilation actually seems faster with minisphere compared to Sphere, which is what I expected.  I think a big cause of your slowness there was that you do FlipScreen() after each line compiled to show progress.  With vsync on, you can then only compile 60 lines per second, and since test.asm has 600+, that's 10 full seconds to compile.  With vsync off compilation is pretty much instantaneous.  It's probably better to remove the FlipScreen there.  If you're worried a long compilation will make the OS think minisphere is locked up, replace the FlipScreen() with DoEvents().

All that said, minisphere does seem to perform a bit slower in actually running the compiled code.  So I compared framerates: Sphere 1.5 ran at around 1500fps for me, while minisphere hovered around 1000.  Since you perform a FlipScreen() for every pixel written, that's your limiting factor.  In any case Duktape's performance doesn't seem to have anything to do with it: As I suspected, you're being bottlenecked by rendering.  Thinking about it a bit, I think I know the reason why Sphere 1.x is faster: It uses DirectX, while minisphere uses OpenGL, which tends to get lower framerates on Windows for whatever reason.

The browser version doesn't have the same issue.  It can set pixels in the canvas instantaneously and the browser will worry about actually updating the screen at its own pace.  Sphere is not multithreaded however, so you're going to have to fake it.  What I would do is store the pixel values (which you should already know since you're emulating video memory anyway) and after executing X instructions, render the contents of video memory and call FlipScreen().  If you call SetFrameRate(60) at startup, you can then tweak the speed of the emulated hardware by changing the number of instructions between flips.
Title: Re: Sphere 6502 emulator
Post by: Mooch on September 14, 2016, 11:22:35 am
Not sure if you're still playing around with this but I just had a random thought -- the NES and SNES run off of modified 6502 chips. Would it be possible to program an emulator in Sphere if this got up and running?
Title: Re: Sphere 6502 emulator
Post by: Eggbertx on September 15, 2016, 06:02:41 am
This is just a basic MOS 6502 emulator, the cpu itself with some stuff for drawing and taking input. For NES emulation, you also need to add code to handle palletes, sprite data, tile data and much more. And while the SNES's CPU is based on the 6502, that would take even more work.
Either way, it definitely wouldn't be at all impossible, but this would end up being a very small fraction of the overall code.
Title: Re: Sphere 6502 emulator
Post by: Flying Jester on September 15, 2016, 01:03:56 pm
I will go ahead and say that for anything resembling accurate SNES emulation, JS (or really almost any non-native language) is just way too slow. The NES may be another matter, though.
Title: Re: Sphere 6502 emulator
Post by: Eggbertx on September 15, 2016, 03:32:11 pm
Why is that? There's an x86 virtual machine written in Javascript (http://copy.sh/v86/), and while it obviously doesn't perform as well as it would natively, the x86 instruction set is a lot more complex than the SNES's CPU's instruction set.
Title: Re: Sphere 6502 emulator
Post by: Eggbertx on March 19, 2018, 08:48:36 pm
Making a new thread when this one is still on the first page seems kind of pointless, so I'll just resurrect this one.
Like how I've resurrected the 6502asm.com -> miniSphere port! And it actually (sort of) works this time, though rendering is kind of sluggish.
(https://i.imgur.com/th460CR.png)
It also has a ROM hexdump function.
(https://i.imgur.com/71WXZpZ.png)
Title: Re: Sphere 6502 emulator
Post by: Fat Cerberus on March 19, 2018, 09:03:35 pm
I'm intrigued and looking forward to seeing more. :D
Title: Re: Sphere 6502 emulator
Post by: Eggbertx on March 20, 2018, 08:52:49 pm
Aaand done. Thanks for the help, Fat Cerberus and rhuan!
Title: Re: Sphere 6502 emulator
Post by: Fat Cerberus on March 21, 2018, 12:03:22 am
This is a pretty awesome little assembler/emulator, me likey. :smiley:  Is there a specific device this is meant to emulate?
Title: Re: Sphere 6502 emulator
Post by: Eggbertx on March 21, 2018, 12:44:16 am
As far as I know, it isn't meant to emulate a specific system, and it doesn't have interrupts for input. ASCII values from keypress events are written to memory location $ff, and Math.random()*255 is written to memory location $fe, and for graphics, you simply read from/write to $200-$600 (1 KB or 32x32 px)
Title: Re: Sphere 6502 emulator
Post by: DaVince on March 22, 2018, 09:14:22 am
This is very neat. I played a little bit of adventure.asm.

I guess in a way this adds compatibility to a whole bunch of (simple) games to miniSphere all at once! :P
Title: Re: Sphere 6502 emulator
Post by: Rhuan on March 25, 2018, 12:56:58 pm
Glad I could help - I'm almost always happy to spend time optimising code :)

Nice to see this running smoothly at high FPS now.