The purpose of this thread is to gauge interest in a collaborative Virtual Boy emulator project within the PVB community. First and foremost: you don’t have to be a developer to help out! There’s a lot of thinking that needs to be done, and I know this community has a lot of dedicated, talented and diverse members, so my hopes are high.
Before any work can be done, though, it’s important to see where everyone stands and how to best tackle the project. Ergo, this thread you’re reading.
Open Source
Developers welcome, but even if I do the programming myself, I’m totally fine with that. Either way, the project will be open-source and a version-controlled source repository will be open to the public… well, it might be restricted to PVB members, but that’s public enough.
I have made one executive decision, though: the main trunk of the project will be written in the C programming language. Not C++, but vanilla C, for the sake of simplicity. C is about as close as you can get to machine code without writing architecture-dependent programs, meaning it’ll be about as fast and memory-efficient as they come.
Additional languages are welcome as ports, and I’d love to see a Java version maintained alongside the C project, but even if it’s just C, that’s fine for now.
Now my question to you guys: What kind of version control solutions are out there? I have a passing familiarity with git and Mercurial, but I don’t know what would be best to use because I don’t work with collaborative projects all that much. I understand git is about the most common, so there’s a better chance of people being able to use it (Linux command line is a big boon here). I welcome any input, as this is not my area of expertise.
Emulation Core
At minimum, the job of the emulator will be to run Virtual Boy software on computers that are not Virtual Boys. That’s what emulators do, and emulators don’t need to do any more than that. The core module of the emulator project will be just that: something that runs the software and nothing more. Let me explain…
Envision a C library with a source file or two and a header file. You build these into your application. You prompt the user for a VB ROM file, and with just a couple function calls, you’ve got a fully-functional Virtual Boy emulator at your disposal! Granted, I/O will be handled by your application, but you just pass in the user input, process a frame, and all of a sudden you have audio buffers and image pixel data that you can display to the user. Easy!
Also, 3DS homebrew. Just sayin’.
The emulation core module of the project will be only the code required to emulate a game. No I/O stuff (not even disk access for loading files), no GUI stuff, no nothing. Just the emulation part. This will enable the core to be portable to just about any application capable of running C code. Or if not, it can be built into a dynamic library (think Windows DLL) that can be used from just about any language.
Debugger
One of my pet peeves with emulators is that they seldom have useful debugging tools. I like to do a lot of hacking, and when I have things like memory-access breakpoints or “step out” at my disposal, things get a lot easier.
Some of the things I’d like to see:
• Runtime disassembler with break, step/in, step out and step over.
• Read, write and execute breakpoints on ranges of addresses.
• Pattern breakpoints. For example, pause execution whenever a certain pixel pattern gets written to CHR memory. Could also apply to audio memory or RAM in general if known data is being hacked.
• Function isolator that tracks the addresses of functions at runtime as the are called, and can parse apart where each function starts and ends within a ROM. Notes or high-level code can be associated with each function and saved to disk, aiding in reverse engineering or decompiling games.
• GUI interfaces for CPU state, RAM, video memory, audio memory and hardware components like the timer or link port.
Anyone else with a hacking background have anything to bring to light?
Recorder
Once upon a time, recording features were used in emulators to produce “movies” that you could send to other users, perhaps demonstrating how to do something in a game. Lately, recording and re-recording from savestates has become more popular in the “TAS” community (or tool-assisted speedrun). I want to accommodate TAS users.
While I’m no TASer myself, I’ve done some research on some of the ways people do it:
• Slow-motion and frame-step are required for frame-precise input.
• An on-screen controller should be present to allow the user to determine input via mouse for each button on each frame.
• Savestates are used extensively for when something goes awry. A particular path through an RPG dungeon might avoid any random encounters, for instance. In the spirit of “try, try again”, a state might be loaded several times in order to produce just the right results.
Bundling this all together, I’m thinking about a record file that contains not only save states along with the input log, but also allows for branching input paths using save states as nodes in a tree. That way, the user can examine which path is most efficient depending on what parts of the game they try to skip or whatever. I can see it working where multiple branches can be played back simultaneously on-screen, giving the user a much better picture of which branch is best.
Somehow or other I need to devise a practical means of frame-stepping in reverse. I’ve thought about it many times over the years but never settled on a satisfactory technique.
How about you guys? Any experienced TASers have any insights or wishes?
Guy Perfect wrote:
The purpose of this thread is to gauge interest in a collaborative Virtual Boy emulator project…
It would be cool to have a more advanced emulator. Mednafen and Reality Boy are ok but especially when it comes to debugging I have to hop through a lot of loops right now.
Guy Perfect wrote:
Open SourceDevelopers welcome, but even if I do the programming myself, I’m totally fine with that. Either way, the project will be open-source and a version-controlled source repository will be open to the public… well, it might be restricted to PVB members, but that’s public enough.
Open source is always great. If you really want a collaborative project, I would suggest to be completely open from the first line of code. That way people can see where you are going and share their thoughts early. And if you fail early on the wrong idea, you wasted less time working into the wrong direction.
Guy Perfect wrote:
I have made one executive decision, though: the main trunk of the project will be written in the C programming language. Not C++, but vanilla C, for the sake of simplicity. C is about as close as you can get to machine code without writing architecture-dependent programs, meaning it’ll be about as fast and memory-efficient as they come.Additional languages are welcome as ports, and I’d love to see a Java version maintained alongside the C project, but even if it’s just C, that’s fine for now.
Do you consider writing unit tests? Projects with more then a couple of developers usually need this kind of safety net. Plus, they help keeping the code readable so that you don’t need extensive comments or documentation. Coding conventions and clean code rules also help.
Guy Perfect wrote:
Now my question to you guys: What kind of version control solutions are out there?
I would go for git.
Guy Perfect wrote:
DebuggerAnyone else with a hacking background have anything to bring to light?
There are some features I would like to see. I will make a list when I have some free time.
Guy Perfect wrote:
Developers welcome, but even if I do the programming myself, I’m totally fine with that. Either way, the project will be open-source and a version-controlled source repository will be open to the public… well, it might be restricted to PVB members, but that’s public enough.
If you want to do it yourself, and have a personal passion to write an emulator, then good for you!
But if you just want a “better” emulator than what’s available, have you considered not throwing away the years of work that other people have done, and to actually save yourself a lot of time and build upon one of the existing emulators and improve it?
Any major project is a huge commitment in time. Lots of people start things, and then the projects die because all the details mount up and things get frustrating and no longer “fun”.
May I ask what major software projects have you completed?
Guy Perfect wrote:
One of my pet peeves with emulators is that they seldom have useful debugging tools. I like to do a lot of hacking, and when I have things like memory-access breakpoints or “step out” at my disposal, things get a lot easier.
…
Anyone else with a hacking background have anything to bring to light?
In the last couple of years I’ve used Mednafen to hack a large PC-FX CD game, and two PC Engine CD games.
Unless I’m hallucinating, it’s already got 70% of what you want, and the rest isn’t hard to add, because a lot of it is already supported on Mednafen’s other emulations.
For instance VRAM viewing/breakpoints don’t seem to work on Mednafen’s VirtualBoy emulator, but they do work on Mednafen’s PC-FX and PC Engine emulators. So the framework is already there, it just needs someone to add the missing bits for the VirtualBoy.
Might that not be an easier (i.e. more likely to happen) route than just starting from nothing?
Mednafen’s debugger certainly has room for improvement … which is why I spent the time to improve it for my own use, and intend to keep on doing so to add more new features.
But that’s because my goal is to use an emulator to do other things, and not to write an emulator.
You just have to be very, very careful to decide where it is that your programming passion (and capability) lies.
thunderstruck wrote:
It would be cool to have a more advanced emulator. Mednafen and Reality Boy are ok but especially when it comes to debugging I have to hop through a lot of loops right now.
May I ask what debugging features you are missing in Mednafen and Reality Boy, and whether you’ve actually tried to do anything about it?
- This reply was modified 8 years, 5 months ago by ElmerPCFX.
ElmerPCFX wrote:
Guy Perfect wrote:
thunderstruck wrote:
It would be cool to have a more advanced emulator. Mednafen and Reality Boy are ok but especially when it comes to debugging I have to hop through a lot of loops right now.
May I ask what debugging features you are missing in Mednafen and Reality Boy, and whether you’ve actually tried to do anything about it?
Well, it’s not like Mednafen and Reality Boy are bad in any way. They actually extend each other quite well. Guy already mentioned some cool features. Conditional breakpoints, pattern breakpoints, function identification, being able to map code, leaving notes along the code, stuff like that would be cool to have. What I’m missing mostly are ease of use features like seeing the bgmaps, worlds, charmem and so on (Reality Boy can do that). Just clicking a part in the visual representation of an bgmap and thereby creating a breakpoint for that address would be cool. I often do a binary search in wram which Mednafen can do, but it’s tedious. So making that easier would help allot. There’s allot more stuff like that. I guess there are many features in Mednafen that I’m not using right now though.
And no, I never tried changing Mednafen or Reality Boy. I never even considered it, to be honest.
- This reply was modified 8 years, 5 months ago by thunderstruck.
- This reply was modified 8 years, 5 months ago by thunderstruck.
ElmerPCFX wrote:
Guy Perfect wrote:
Developers welcome, but even if I do the programming myself, I’m totally fine with that. Either way, the project will be open-source and a version-controlled source repository will be open to the public… well, it might be restricted to PVB members, but that’s public enough.
If you want to do it yourself, and have a personal passion to write an emulator, then good for you!
But if you just want a “better” emulator than what’s available, have you considered not throwing away the years of work that other people have done, and to actually save yourself a lot of time and build upon one of the existing emulators and improve it?
Any major project is a huge commitment in time. Lots of people start things, and then the projects die because all the details mount up and things get frustrating and no longer “fun”.
In the last couple of years I’ve used Mednafen to hack a large PC-FX CD game, and two PC Engine CD games.
Unless I’m hallucinating, it’s already got 70% of what you want, and the rest isn’t hard to add, because a lot of it is already supported on Mednafen’s other emulations.
For instance VRAM viewing/breakpoints don’t seem to work on Mednafen’s VirtualBoy emulator, but they do work on Mednafen’s PC-FX and PC Engine emulators. So the framework is already there, it just needs someone to add the missing bits for the VirtualBoy.
Might that not be an easier (i.e. more likely to happen) route than just starting from nothing?
Mednafen’s debugger certainly has room for improvement … which is why I spent the time to improve it for my own use, and intend to keep on doing so to add more new features.
But that’s because my goal is to use an emulator to do other things, and not to write an emulator.
You just have to be very, very careful to decide where it is that your programming passion (and capability) lies.
This. All of this.
Creating a new emulator from scratch seems like we’re throwing the baby out with the bathwater. Mednafen works well, has an amazing project lead, has the benefit of being maintained and patched over the years of its existence by countless contributors, and from my evaluation has no technical reasons why it couldn’t be extended to do the things mentioned in the OP.
The VB community is *tiny*– I don’t think I can stress this enough– and we’re lucky to have folks like ElmerPCFX stop by from the PC-FX community to help us out. We should *encourage* folks not in the VB community to contribute to our tools, especially if it’s mutually beneficial. A Virtual Boy-exclusive emulator such as this one only serves to isolate us from possible contributions. Improvements to Mednafen’s debugging facilities, though maybe not always VB-specific, are improvements we get for free. Likewise, do you think the PC-FX community would be interested in helping to develop a Virtual Boy-exclusive emulator? Why would they? (Consider why Red Dragon and Reality Boy are no longer maintained. Hmmm…)
Guy Perfect wrote:
I have made one executive decision, though: the main trunk of the project will be written in the C programming language. Not C++, but vanilla C, for the sake of simplicity. C is about as close as you can get to machine code without writing architecture-dependent programs, meaning it’ll be about as fast and memory-efficient as they come.
I’m going to assume you know what you’re talking about and that you have other reasons for choosing C, and would love to know those reasons, but for the benefit of others, choosing C over C++ for performance reasons is a mistake. C has no advantage over C++ performance-wise, and vice versa. C++ is a superset of C, meaning that you can use some or none of the extra features provided by the language, with no penalty in the latter case.
That aside, C++ affords the programmer many features now taken for granted that simply aren’t present in vanilla C– operator overloading, access specifiers, better const correctness– these are things that make the programmer’s life easier and/or help them not make silly mistakes (We’re all human, after all). Aside from compatibility with legacy code or compilers, I cannot understand why a strictly C-based project is necessary in 2016, but if you continue to insist, then please use at least C99.
Haven’t we had this conversation already?
As for the existing emulators: I think they’re decent, but as Thunderstruck pointed out, they each have their annoyances and better debugging/reverse engineering features could be added.
A big problem for me is portability. Mednafen, as far as I know, requires GCC, a POSIX/GNU environment, and a whole host of dependencies to compile, and it’s been 2 years since Ryphecha told me the DOS port would be done “soon”. (And before someone asks why I care about DOS, let me remind you that we’re developing software for a not very popular 20-year old game console, so why not?) The last time I tried to compile it on Haiku, it failed because of some dependency error (libcdio? I don’t remember) and I gave up after that because I consider configure scripts and seas of makefiles a sign of brittle and badly engineered software. And the last time I looked at the source code, it was sparsely commented, so there goes any chance of me improving it (and let’s not discuss licensing).
Reality Boy and Red Dragon should in theory compile with any compiler that can also compile Allegro, which is all they depend on. I have compiled them for DOS, but so far only with GCC/DJGPP. I got as far as compiling Reality Boy on Haiku, but it didn’t accept input; not sure whether the problem was in Reality Boy, Allegro, or Haiku, but it just shows that depending on a specific library (even if only one) can make or break portability.
If I understand Guy Perfect correctly, he wants to make a callback-based emulator that could use any user interface and run anywhere. Imagine having an IDE/compiler that uses this emulator and lets you not only debug code, but change it and have the changes applied in almost real time. Sounds cool (if utopic), no?
As for the PC-FX: sure, let’s do a PC-FX emulator while we’re at it. Mednafen is a usable emulator (but see above), Xe is dead, and Magic Engine FX seems to be targeted only at players; I hoped that my work on homebrew PC-FX development would encourage emulator developers, but I might help if that’s what it takes.
Thanks for your feedback, everyone. I feel like I’m getting a pretty good picture of what people want to do and what everyone’s expectations are. Very helpful for planning purposes!
HorvatM wrote:
Haven’t we had this conversation already?
Pretty close, yeah. (-: But the difference this time is that I’m actually prioritizing this in my life because I feel I owe it to the PVB community to give back in a big way.
ElmerPCFX wrote:
[… I]f you just want a “better” emulator than what’s available, have you considered not throwing away the years of work that other people have done, and to actually save yourself a lot of time and build upon one of the existing emulators and improve it?
I do appreciate your insights, since if things were as quoted, the lion’s share of the work could be sidestepped. However, it’s not having an emulator that I’m after with this activity; it’s making one.
One of my desires is to help lift the veil on the internet that enshrouds emulation in an air of mysticism. An emulator isn’t some arcane box of hocus-pocus: it’s a rigidly-defined set of rules that get from point A to point B. I want people from all over the industry to be able to look at Planet Virtual Boy and, in doing so, learn a lot about how emulation works and maybe take the system a little more seriously in the process. (-:
Alongside development of the emulator for its own sake–which was the focus of the previous thread–I will be writing up articles about how different parts of the emulator operate. My hope is that someone who is interested in their own emulator endeavors can find these articles helpful.
blitter wrote:
The VB community is *tiny*– I don’t think I can stress this enough– […] A Virtual Boy-exclusive emulator such as this one only serves to isolate us from possible contributions.
I wouldn’t worry about that too much since the project isn’t trying to attract a lot of people to work on it. At minimum, I’ll still have my little monthly goals–I promise–so it will be completed eventually. Should someone choose another project to contribute to instead of this one, that’s perfectly fine. This one has its own ambitions.
If nothing else, working on an in-house emulator is better than sitting around scratching our heads waiting for the next reproduction to be sent out.
blitter wrote:
C has no advantage over C++ performance-wise, and vice versa. C++ is a superset of C, meaning that you can use some or none of the extra features provided by the language, with no penalty in the latter case.
You’re correct, and I will consider C++ for this project. Even if C is specifically desired for whatever portion of the code base, they can still be used verbatim in a C++ project. The ease-of-use benefits of C++ may be conductive to better collaborative support.
I’ll need to research it a bit. I’m a big proponent of the “don’t allocate for every individual object” camp, and I have a feeling C++’s “new” keyword falls into that category upon object instantiation. I’ll get with a colleague of mine who deals more in such things and see what insights he can offer.
Guy Perfect wrote:
One of my desires is to help lift the veil on the internet that enshrouds emulation in an air of mysticism. An emulator isn’t some arcane box of hocus-pocus: it’s a rigidly-defined set of rules that get from point A to point B. I want people from all over the industry to be able to look at Planet Virtual Boy and, in doing so, learn a lot about how emulation works and maybe take the system a little more seriously in the process. (-:
That was an especially interesting speech. Thank you for sharing it. I’m tickled to death by the notion that Nintendo downloaded Super Mario Bros. from the internet and then sold it.
Saying that, it’s not what I had in mind. I’m more interested in shedding light on how emulator’s work internally.
__________
After some discussion with my associate, I’ve decided to stick with C over C++ for two prominent reasons:
1) Some of the features of C++ necessarily have more demanding runtime requirements to compensate. I mentioned the “new” keyword, which was confirmed to allocate a small block of memory every time an object is created. But it was also brought up that trapping exceptions–one of the most powerful features C++ offers over C–has a host of overhead making it work. The runtime library required to use a C++ program has a larger memory footprint than the C runtime. While the difference in performance is negligible, there’s still a relevant impact when using C++ instead of C.
2) It’s imperative that the project is portable–especially the emulation core. While it’s true that C code can be used in a C++ project, that’s not necessarily true if you flip it around. Even in the case of the user interface, I’d really rather design it in such a way that if someone wanted to use parts of it in some other project, they’d be able to. This point more than the previous one is what’s pulling me to the C side of things. No amount of C++ trickery is going to make the emulation core work in a C environment, performance notwithstanding.
Guy Perfect wrote:
1) Some of the features of C++ necessarily have more demanding runtime requirements to compensate. I mentioned the “new” keyword, which was confirmed to allocate a small block of memory every time an object is created.
Not any more memory than malloc() does for the same object. Literally. The GNU implementation of new is a sanity-checking wrapper around malloc(). Don’t like it? Write your own. (Note that due to lack of function overloading, you can’t easily replace malloc() in C.)
But it was also brought up that trapping exceptions–one of the most powerful features C++ offers over C–has a host of overhead making it work. The runtime library required to use a C++ program has a larger memory footprint than the C runtime. While the difference in performance is negligible, there’s still a relevant impact when using C++ instead of C.
pssst… you don’t have to use them… 😉
No amount of C++ trickery is going to make the emulation core work in a C environment, performance notwithstanding.
Absolutely false. (Seriously, this is the first Google result returned for “c wrapper for c++ library”– did you do any research yourself or are you blindly going by what your “associate” says?)
Look, you personally can write your project in whatever language you want, and that’s fine, but when you as a project leader open it up to the world and then place arbitrary restrictions on its development without supporting arguments that make technical sense, you’re not getting off on the right foot. Code conventions are one thing, but shutting out a huge part of the language that’s been in use for over 20 years because of some preconceived notions that it’s less performant, top-heavy, memory-intensive, or what-have-you without confirming it for yourself first in practice, is at best silly and at worst irresponsible. Are these concerns really all that significant in the overall scope? Is it worth shooing away good C++ coders so you can recoup that .00001%? Worrying about speed or space issues is premature optimization that should be done only after profiling a project to see where the bottlenecks are– otherwise it’s time wasted over a mostly futile effort.
blitter wrote:
Absolutely false. (Seriously, this is the first Google result returned for “c wrapper for c++ library”– did you do any research yourself or are you blindly going by what your “associate” says?)
I understand that you have an emotional investment in using C++ (or, as the case may be, in not using C), but I remind you to think carefully before accusing someone of making unsubstantiated claims. I don’t want a constructive debate to devolve into name calling and hearsay.
The article you linked details a technique for implementing a C interface to a C++ library. I would posit that a superior approach would be to export to a DLL or something similar so that virtually any target language could load in the compiled library code at runtime. Heck, I was doing OpenGL in Visual Basic this way for years before switching to C. (-: From a literal standpoint, I will concede that this is a manner by which you can use C++ code in a C project.
That being said, as the article points out, this is not necessarily an elegant transition: every access to a C++ class’s fields or methods has to have a dedicated function for C to use. We’re left with a situation where we’re weighing a matter of convenience. Do we use C, where the source files can be used directly in a C++ project; or do we use C++, where a C interface will need to be maintained in order to use the code in a C project?
And what about porting to other languages? Many languages have classes, some have exceptions, and a few have operator overloading (the popular Java, incidentally, does not). If we leverage the powerful features that C++ brings to the party, what impact will that have on portability? It hardly needs to be said that C code will generally port with minimal modifications.
Like I said in my previous post, the main thing drawing me to C over C++ is portability. C can get tricky with indirection, but beyond that I believe a very strong case can be made that C is far more accommodating than C++ in this regard, and I consider that a significant factor in choosing which language to use.
blitter wrote:
[…] arbitrary restrictions […] preconceived notions […] less performant, top-heavy, memory-intensive […] without confirming it […] at best silly and at worst irresponsible […] recoup that .00001% […] speed or space issues […] time wasted over a mostly futile effort.
My priorities are portability and constructive discourse.
If anyone else feels that I’m being unreasonable, please say so in a reply to this thread or to me directly via PM. It’s not my intention to be stubborn or narrow-minded, and if additional feedback can put this project in a better direction, then I’d say only good can come of it.
blitter wrote:
Is it worth shooing away good C++ coders so you can recoup that .00001%?
I don’t believe that this is an actual issue: a good C++ programmer should be able to make heads or tails of a C program (and vice-versa).
Of course, there’s also the fact that C is trending nearly double what C++ is on the internet right now. If I were concerned with alienating programmers, I’d be more hesitant to decide on C++ for fear of driving away potential C developers.
Guy Perfect wrote:
I understand that you have an emotional investment in using C++ (or, as the case may be, in not using C), but I remind you to think carefully before accusing someone of making unsubstantiated claims. I don’t want a constructive debate to devolve into name calling and hearsay.
Perhaps that was a little harsh and if so, I apologize. My point still stands though– many of your claims so far about your preference for C are unsubstantiated.
Like I said, I don’t care what language you use for your own personal projects– if you love C and want to write in it, great! But starting a topic and making claims like “C is about as close as you can get to machine code without writing architecture-dependent programs, meaning it’ll be about as fast and memory-efficient as they come” and “While the difference in performance is negligible, there’s still a relevant impact when using C++ instead of C” is pretty disingenuous and a bit of a red flag to me. No offense intended to you, but this discussion doesn’t fill me with a whole lot of confidence about this project from the get-go. If I have an “emotional investment” in anything around here, it’s in seeing VB devs succeed– while I’m sure you’ll pull more than your fair share of the weight on this project alone, I predict it will take a much longer time without help or adoption, and I’m having a hard time envisioning a number of folks signing up.
Good luck with the project. 🙂
blitter wrote:
Like I said, I don’t care what language you use for your own personal projects– if you love C and want to write in it, great! But starting a topic and making claims like “C is about as close as you can get to machine code without writing architecture-dependent programs, meaning it’ll be about as fast and memory-efficient as they come” and “While the difference in performance is negligible, there’s still a relevant impact when using C++ instead of C” is pretty disingenuous and a bit of a red flag to me.
I’m sorry, but I’ve got to agree with what Blitter is saying here … and I’m someone who treats a lot of C++’s features with suspicion or outright dislike.
In fact, when I program in C++ instead of C, I tend to stick to the features of the language that closely correspond to “Embedded C++” precisely to avoid the costs of rampant overuse of some of C++’s heavier weight features. (https://en.wikipedia.org/wiki/Embedded_C%2B%2B)
But, at the end-of-the-day … it’s still legal C++.
When you do a large project in C, you’re probably going to end up using C’s macros to solve some problems.
That’s fine … but that’s one of those language features that’s going to make porting to other languages much, much harder … not that anyone that I know in the normal world ever actually switches programming languages in a project, because not needing to is one of the major points of writing in a multi-platform high-level language in the first place.
The things that you’ve said, and the way that you’ve said them, really make me believe that you don’t have much experience in software development.
As such … frankly … I would suggest that you use C rather than C++, because you’re less likely to get into a mess of evangelized design techniques that just tend to make things over-complicated and sometimes fragile.
If you write a large project in C, then you’ll be in a better position in the future to judge which language features of C++ (or Java, or Python, or …) might have made things easier and cleaner, and which wouldn’t.
That will be a good programming lesson, and will help make you a better programmer in any language in the long term.
BTW, if you want some good information and ammunition to be wary of some of C++’s features …
http://yosefk.com/c++fqa/
http://yosefk.com/blog/c11-fqa-anyone.html
And honestly … as correct as he is (IMHO) … that’s still not a reason to avoid C++ entirely, just a warning to be careful in which features you do use.
Dude, I am totally down. Two years ago I was about to dive into attempting to learn how to make a game for VB, I’d just read through all the documentation on here like the sacred scroll and such, then you posted that original emulator development thread. And talked about using C, and SDL which I’d just been using in a games programming course the years prior. Right at a time when I was looking for something to get my programming going again. Plus all your other threads were fascinating reads, and you really seemed to know your stuff. It seemed perfect.
Then suddenly I got pulled aside by some spontaneous full-time employment, and got well and truly side-tracked dealing with everything there, and kinda forgot about it all for a while.
Now I randomly decide to poke around on the forums again, and you’ve reappeared, proposing a similar thing, right as I’ve come off having another chance to refresh the old programming chops fall through (promising side-project at work which didn’t get off the ground before everything there came crashing down) and started pondering something else I could do. I don’t know what they say about second chances, but I’m sure it’s something.
So yeah, I’m keen 😛
Also, you lost a chunk of life to Splatoon too? Man I played that thing every day for three months straight when it came out. Went off for a while to play other things, but got back into it again recently in preparation for the final Splatfest. Such a good game.
Hey! Glad to have you on board. I came on to write up the goals for August and saw you posted. Check your PMs, I’ve got something for you. (-:
Many thanks to those who have pitched in ideas so far. I’ve got a good idea of where to start and how to proceed, which is what I set out to do so hooray. (-:
I started this write-up before Gookanheimer came about, and I haven’t had a chance to discuss things with him yet, so I’ll just say this: until such a time that others are interested in working on the project with me, I’ll be working independently. As such, I will not be setting up a git repository at this time (just as well, since I’m no expert at git), and will be posting ZIP files from time to time containing the current progress and binaries for the project.
So hey, let’s get started.
__________
License
I’m in prime position to piss off a fair number of people by doing this, but I’m going to make another executive decision: no traces of GPL in any way, shape or form, at all, ever. I’m all for keeping open software open, but there are certain ways to take that ideology too far, and GPL’s requirement to make the source of your entire project available on request just because you used that one library is one of them. I will not reconsider my position on this matter.
This project will be released under the terms of the zlib license. This means anyone can use any part of the emulator code for any purpose–commercial or non-commercial–with or without making the source code to their software available. Heck, Nintendo themselves would be within their rights to use the Planet Virtual Boy emulator in Virtual Console releases and never tell anyone where they got it. (-:
GUI Stuff
Before getting into the emulation side of things, let’s take a moment to talk about GUI. The project will need to work with the native windowing systems of the target platforms, and in the interest of maintainability, a solution should be selected that minimizes the amount of code that will differ by platform.
And before getting into that, what are the target platforms? I specifically want to support Linux, Microsoft Windows and Apple OS X as operating systems. Exactly how far back to support kinda hinges on the dependencies of the GUI library, but it’d be cool to support as far back as Windows 95 and OS X Tiger. Even though usage share is trending for 64-bit OSes, 32-bit releases of the emulator are still important since some people still use them and they’re not really that big a deal to build for.
With that out of the way, the GUI solution should ideally support basic window management across all three target OSes, but without hogging resources or introducing some staggering runtime footprint.
The GUI library I want to go with is Simple DirectMedia Layer: it’s free, fairly minimal, supports many architectures and is supported by many game development platforms. It’s missing a few things like directory listing and exposing the POSIX sockets API, but anything that’s missing can be implemented without too much of a hassle. And hey, maybe we can improve SDL while we’re at it, right?
SDL is so minimal, in fact, that it doesn’t actually provide a GUI library out-of-the-box. What it does is gives you a system window into which you can draw pictures (and receive input, etc.). It has a built-in API for 2D accelerated graphics, but I think we should cut out the middle-man and use OpenGL directly. Let me explain… although SDL is supported on many platforms, and OpenGL on even more, there’s never going to be The One GUI Solution™ that works absolutely everywhere. By using OpenGL instead of SDL’s 2D library, that’s one part of the program that gets to be that much more portable as a result.
An additional complication is which OpenGL features to use. I’m leaning towards 1.1 since it’s supported on the oldest versions of Windows (and in software-rendered situations like virtual RDP), and I myself have some tablets and netbooks that don’t support shaders (and I really like programming with shaders). When it’s all said and done, OpenGL 1.1 seems to be the least common multiple and should hypothetically cast the broadest net for the user base of the emulator application.
As for GUI controls themselves, well… I’d really rather just implement those myself. Sure, it’s reinventing the wheel, but the application only needs some simple buttons and scroll bars and stuff. I really don’t feel like kissing frogs trying to find the right GUI library that works with our license and bloating the code base with controls we don’t need.
So that’s what I have in mind. If you know a better way, say so now, before something gets set in stone. (-:
Portability
Portability is paramount, especially for the emulation core. If the core library is to be useful in as many applications as possible, then it has to be written in such a way as to minimize the requirements of the application trying to use it.
This section applies mainly to the emulation core, so don’t get discouraged. The following are some considerations to increase portability of this central library:
• Common compilers. A language should be chosen to maximize the likelihood someone will be able to compile the emulation core on their target system. This is a bit of a sticky subject, since using old programming languages can be seen as failure to get with the times. But at least one PVB member has expressed interest in getting it to run on DOS, so it’s worth consideration. Much to everyone’s dismay, I want to support stock C89, even so far as to require /* style comments. If it won’t compile in gcc with [font=Courier New]-std=c89 -pedantic[/font], then maybe it shouldn’t be used. I’m open to suggestions if an argument can be made for using newer C features.
• No C runtime. Not every system using the emulation core will necessarily have a C runtime to draw from. This means any standard library functions that would otherwise be used by the core (such as math, string or memory allocation functions) will need to be implemented in C code to avoid the C runtime requirement.
• Architecture-independent implementation. Certain CPU architectures process the same instructions differently, even if the C code itself is unchanged. There are two key ways this can occur in my experience: endianness and alignment. No assumptions can be made regarding the order of bytes within data types, and unaligned memory accesses need to be avoided. Has anyone else dealt with any other architecture-specific gotchas we might need to watch out for?
Again, these considerations are primarily for the emulation core library. The GUI application with the debugger and stuff won’t be held to such strict rules.
Conventions
I started writing up coding conventions, then I remembered I would probably be working independently. Basically how this is going to go down is that I’ll establish a coding convention, then if anyone contributes to the code base, consistency should be maintained. (-:
With all that out of the way, let’s talk about the emulation core.
Emulation Core
In its simplest form, the emulation core library defines an object type representing an emulated Virtual Boy, and various functions for working with an instance of such an object. The core is self-contained and is not useful unless the application supplies input and output buffers. The application can extend the functionality of the emulation core by hooking into key control points.
I think the most appropriate name for this library is [font=Courier New]vue[/font], since that’s the acronym used by Nintendo to represent the system’s internal workings.
If the application invokes the main emulation routine without configuring any breakpoints, the program will effectively hang because the emulation will loop indefinitely. The following control points are available:
• Memory Access (Read, Write). The address and data size are passed to the control point handlers. If an instruction requested the access, a descriptor of the instruction is also passed to the handler before the instruction is executed. If instead an instruction is being fetched by the CPU, a Read handler will be triggered with some control value for the instruction parameter.
• Execute. A descriptor of the instruction is passed to the control point handler before the instruction is executed. The address can be determined by examining the CPU state, and the instruction’s size can be determined by examining the instruction data.
• Exception. The exception code is passed to the control point handler before the CPU state is modified according to the exception. Exceptions include instruction errors, interrupts, hardware breakpoints and duplexed exceptions.
• Fatal Exception. The control point handler is called before the CPU writes its debugging information to the bus. This condition only occurs if a third exception occurs during the processing of a duplexed exception.
If an emulation break isn’t required, the control point handler will return zero. Otherwise, the value returned will be ultimately given back to the application when execution stops.
The following special tasks can be performed during control point handling:
• Perform the default behavior for the memory access
• Execute the default behavior for the the instruction
• Update CPU state according to the exception
• Perform fatal exception operations
• Perform a memory access that bypasses control points and CPU processing
• Advance the program counter to the next instruction
• Advance the CPU timer by some number of cycles
I’m sure a few things will come and go as things get implemented, but this particular approach I think will work well because 1) it’s simple to implement in the emulation core library and 2) it’s flexible enough that a debugger can do a lot with it. If you wanted to, you could put an Execute trap on the entire address range and filter out everything except a particular instruction (like, say, [font=Courier New]JMP [r31][/font]).
Bus Routing
Those Read and Write control points form the basis of the interconnected web of components that will become the emulation core. They’re responsible for routing accesses to the appropriate components, fetching memory or carrying out actions according to the hardware component being accessed.
By simplifying the control points to just two functions, the core logic of routing bus addresses becomes simplified.
CPU Operations
For those who didn’t take CS101, a CPU hypothetically does the following three things over and over:
• Fetch – Load the next instruction from memory
• Decode – Figure out what the instruction’s bits mean
• Execute – Perform the task specified by the instruction
Additionally, each instruction takes a certain amount of time to complete, and not all instructions take the same amount of time. For the purposes of this emulator, the key interval of time here is the cycle. Since the VB’s processor runs at 20MHz, one cycle is one twenty-millionth of a second. To be accurate, we need to keep track of these as best we can.
Virtual Boy instructions are loaded in 16-bit units. The upper 6 bits of the first 16 bits read specify the instruction’s opcode, which is a unique identifier for which instruction is being represented. Each instruction (by opcode) is stored in one of seven different formats, with formats I through III requiring only 16 bits and formats IV through VII requiring 32. Therefore, depending on the value of the opcode, a second 16-bit read may be required to fully load the instruction.
The “fetch” and “decode” stages of our virtual CPU pipeline will happen concurrently. First, a 16-bit unit is read, then the opcode parsed from that, indirectly yielding the instruction’s format. An additional read may be performed, followed by parsing all of the instruction’s operands. This descriptor of the instruction will be stored in a temporary object, which is then passed to the execute processor.
The “execute” stage differs depending on the opcode. While certain common tasks can be split out into their own functions, the end result is that every opcode will result in calling a different function. Each of these execute handlers will be responsible for updating the CPU state and keeping track of how many cycles they take.
An exception can take place at four different locations within this process:
• If the hardware breakpoint is enabled and the instruction being fetched is located at the address specified by the [font=Courier New]ADTRE[/font] register, the address trap exception is processed prior to the “fetch” step.
• Illegal opcodes are detected during the “decode” step. You can’t execute an opcode that doesn’t correspond with an instruction, and VB does have a handful of those.
• General exceptions occur during the “execute” step. This includes things like division by zero, using NaNs in a floating-point operation, or trying to convert to a data type that can’t represent the result.
• Interrupts are checked after the instruction that was executing when they were raised finishes. That is to say, interrupts are accepted between the “execute” step of one instruction and the “fetch” step of the next.
Simple Disassembler
I’m a firm believer that any program function can be analyzed to the point where it can be determined with certainty that it operates correctly in all situations and is therefore free of bugs without even testing it. I’m also painfully aware that I tend to make silly mistakes while programming, so I don’t dare trust myself to do it right without sitting down and looking it over real close.
I also like to see things happen, rather than just knowing they happen. To that end, I want a way to verify the CPU emulator is working properly by using my eyeballs. This is a perfect place to implement a disassembler: it requires hooking into the emulation core’s control points, and although it’s GUI work, it’s work that needs to be done eventually anyway, so why the heck not?
A disassembler is a program that accepts compiled machine code as input and produces the equivalent human-readable assembly as output. (It’s possible to go a step further and make a decompiler that produces something like C code as output, but that’s way more work and isn’t really in the scope of this project.) In an emulator, a disassembler can be present while the guest program is executing, giving the developer some very good insight into exactly what’s going on in there.
This first-iteration disassembler won’t be fully-featured, but it will provide a reliable basis for testing and later expansion. It will have three primary jobs: 1) present the user with a disassembly of the program relative to its current execution address, 2) allow the user to advance one instruction at a time, and 3) display the current CPU state to the user.
A typical disassembler displays program code to the user one instruction per line, with multiple columns of information. This initial disassembler will have the following columns:
• Machine code bytes, in the order they appear in the ROM data
• The instruction’s mnemonic (human-readable “name”)
• The instruction’s operands
Later iterations will include a fourth column for automatic comments, such as a known function name for the instruction that calls the function. This will also use the standard V810 operand ordering, register names and SETF notation, but the final version will allow these things to be configured by the user.
__________
Phew, that was a lot of things to say. I’ll get right on it. If you don’t hear from me, then expect to see all these things in glorious compiled-o-vision come August 31.
The concept of an “in house” VB emulator sounds really exciting! I’d be especially interested in that 3DS homebrew version you mentioned 😉
I also think it would be interesting to learn from your development process. As someone who sees emulators as mysterious “black boxes”, it would be neat to gain a better understanding of how one is made.
Finally got the architecture design nailed down and mostly implemented. Gookanheimer actually jumped in and is reportedly working on implementing the CPU instructions while I start on the GUI stuff. With any luck, we can actually get this done quickly without getting bored. (-:
I spent the last week considering the best way to handle GUI stuff, and settled on a disappointing conclusion: it will be most appropriate to treat SDL as the target plaform, rather than try to make everything platform-independent.
When considering how to implement GUI things in a platform-independent way, the solution I kept coming back to was basically “write a generic API that wraps around SDL for one implementation and whatever else for other implementations.” Since SDL is already doing that with native windows and I/O, it just adds another layer of abstraction where there doesn’t really need to be one. If some port of the emulator application needs to implement its internal API regardless, it may as well implement a stand-in for the SDL functionality directly.
In other, more exciting news, I’ve decided to add [font=Courier New]armhf[/font] and [font=Courier New]arm64[/font] to the list of supported architectures for Linux. This benefits the general mobile market, but has particular significance for single-board development. Raspberry Pi in particular has a community with a strong emphasis on video game emulation.
__________
EDIT:
Oh yeah, forgot to mention… As part of the initiative to treat SDL as the target platform, I’ve also opted to forego OpenGL directly and use the SDL 2D rendering API instead. This was an easy decision because there’s about one finity ways to implement something, and even if my OpenGL code works one place, it may not be suitable in another. May as well code up the GUI renderer in such a way that it’s best-suited for the platform at hand, and that would be through letting SDL decide how to best carry out its drawing instructions.
A 3DS version of this emulator will probably just wind up using the emulation core library and implementing its own GUI from scratch…
- This reply was modified 8 years, 4 months ago by Guy Perfect.