You are not logged in.
Lost Password?


Register To Post



 Bottom   Previous Topic   Next Topic

#11
Re: PVB Collaborative Emulator
Posted on: 2016/7/11 5:20
VUE(xpert)
Joined 2012/12/4
324 Posts
CoderLong Time User (5 Years)
Quote:

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.

Quote:

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.

Quote:

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.
Top

#12
Re: PVB Collaborative Emulator
Posted on: 2016/7/11 6:11
Nintendoid!
Joined 2007/12/14
164 Posts
CoderLong Time User (10 Years) App Coder
Quote:

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. :)
Top

#13
Re: PVB Collaborative Emulator
Posted on: 2016/7/11 19:02
VB Gamer
Joined 2016/3/13
34 Posts
Long Time User (1 Year)
Quote:

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.
Top

#14
Re: PVB Collaborative Emulator
Posted on: 2016/7/11 23:33
VB Gamer
Joined 2016/3/13
34 Posts
Long Time User (1 Year)
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.
Edited by ElmerPCFX on 2016/7/11 23:44
Edited by ElmerPCFX on 2016/7/12 0:48
Top

#15
Re: PVB Collaborative Emulator
Posted on: 2016/7/31 19:21
VB Gamer
Joined 2012/12/21
Australia
26 Posts
Long Time User (4 Years)
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 :P

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.
Top

#16
Re: PVB Collaborative Emulator
Posted on: 2016/7/31 23:12
VUE(xpert)
Joined 2012/12/4
324 Posts
CoderLong Time User (5 Years)
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. (-:
Top

#17
Re: PVB Collaborative Emulator
Posted on: 2016/8/1 1:44
VUE(xpert)
Joined 2012/12/4
324 Posts
CoderLong Time User (5 Years)
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 -std=c89 -pedantic, 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. (-:
Top

#18
Re: PVB Collaborative Emulator
Posted on: 2016/8/1 1:46
VUE(xpert)
Joined 2012/12/4
324 Posts
CoderLong Time User (5 Years)
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 vue, 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, JMP [r31]).

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 ADTRE 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.
Top

#19
Re: PVB Collaborative Emulator
Posted on: 2016/8/5 8:33
Newbie
Joined 2014/12/24
USA
3 Posts
Long Time User (2 Years)
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.
Top

#20
Re: PVB Collaborative Emulator
Posted on: 2016/8/14 2:39
VUE(xpert)
Joined 2012/12/4
324 Posts
CoderLong Time User (5 Years)
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. (-:
Top

 Top   Previous Topic   Next Topic


Register To Post