This is a work post.
That pesky Worlds tab is finally done. After over 9000 revisions to the underlying code of the VIP window, all tabs are now simplified and playing nice with one another. And worlds are implemented.
By this point I’ve kinda forgotten exactly what I need to say about it… The Objects and Worlds tabs are now present, which do a simple anaglyph output for the time being. The default colors are red and blue, but you can toggle between the perception-calibrated colors sets with Ctrl+3.
The Framebuffer and Registers tabs remain, but I need to sit down and figure out what comes next. I’ve been fighting with Java’s middle-of-the-road graphics support for so long that my train of thought derailed a couple weeks ago and never got back on track. O-:
The current build is attached to this post, and the Sacred Tech Scroll has been updated on the project page with the latest revisions.
Still workin’ on that Worlds tab. Tabs are of course related to one another, plus the VIP brightness and anaglyph colors, so it’s important to make sure everything’s following the same rules and duplication is kept to a minimum. It’s been an interesting game of cat and mouse each time I add a tab, as something winds up getting revised or rewritten in order to accommodate the new tab’s needs.
The approach I’m going with processes the output image directly without going through the hoops of drawing every individual element of every world. For each pixel in the image, worlds are sampled from front to back (the hardware draws back to front). The world itself handles the details of how to find out what the pixel value is, depending on its coordinates, background or object group. As soon as a left or right pixel receives a value, that pixel is no longer processed. Once both eyes receive pixel values, drawing ends for that pixel and the process moves onto the next one.
I’m considering adding a feature to the emulation core that can process VIP rendering either as efficiently as possible using the above method, or as accurately possible using some method calibrated to the VIP operations on the hardware (which needs to be researched someday). That way, time-critical applications like 3DS can just produce a frame image as fast as possible, while development settings can help profile performance without running on the hardware.
Happy Memorial Day weekend to those who observe it! I had hot dogs. Delicious, char-grilled hot dogs.
I’ll see about scanline interleaving. There’s no graceful way to pull that off, especially in Java, but where there’s a will, there’s a way!
Worlds, Scene, Framebuffer and Registers tabs remain. There are many fields between many registers, so depending on how much space things take up, there might be multiple tabs. On the one hand, the window can be resized, but on the other hand, there is such a thing as “too cluttered”, and lots of emulators have that.
This is a work post.
Okay, I admit, I slouched a bit for a couple of days. I was thinking the project would get demoted to “personal project” status and didn’t really grind at it like I have been. But since it’s once again officially my job, I went ahead and finished up the Objects tab this afternoon:
By this point you know what to expect from those controls on the left. Editing those will change the current emulation state to match.
The right-hand side is a different story. That area displays a simulation of what the object looks like in the scene. The black rectangle is 384×224 pixels, which is the size of the system’s frame buffer. So by previewing an object in this tab, you’ll see exactly where and how it contributes to the final frame image.
This marks the first instance of stereoscopy in the project. The only available method to achieve this in Java is the usual anaglyph, which encodes each eye’s image with specific colors such that they can be masked out for the appropriate eye with a set of 3D glasses worn by the viewer.
The most common anaglyph configuration is red for the left eye and cyan for the right eye. Ordinarily this can lead to a color imbalance because of the way the human eye is more sensitive to green light than either red or blue light, causing erroneous distribution of light intensity for each eye.
However, as you can see in this macro example, the overlapping pixels are not white, but sort of a light peach color. I’ve done my best to equalize the apparent intensity of colors by default, although this will of course be configurable by the user.
Because the human eye is so sensitive to green light as compared to red and blue, I recommend using green-magenta anaglyph glasses instead of red-cyan, if you can get your hands on some. I want to say it’s fairly common in the wild, so it shouldn’t be hard to find a set. The amount of color correction needed for this combination is less than in the first example.
Attachments:
In light of the recent situation, an anonymous benefactor plunked down enough money to keep the project going for a couple more months. We back in business, bois!
This is a work post.
Development of VIP debugger tabs is ongoing, creeping steadily closer to its completed state. I keep reworking the back-end, since every iteration brings new insights and I want to make sure it’s as good as it can be while still fulfilling all of the requirements. I feel like I’ve boiled it down to its essential format now, so fortunately all that’s left is plopping down some controls and coding in their event handlers.
Working with the Java2D API has been a reliable headache since I started work on this window. It’s completely lacking what I consider to be basic, barebones functionality such as volatile palettes and rudimentary block transfer compositing, and working around that has been an exercise in head-shakery. What I ultimately wound up with has the best performance of everything I tried, but I’ll always know that behind the scenes, it’s inelegant and sub-optimal. Perhaps it’s not one of the intended uses of Java2D, but they wouldn’t have to go out of their way to support doing stuff like this…
On the bright side, this window is the last big chunk of the picky graphics stuff. What’s left after this is sweet, sweet data-centric processing that I do have control over. The worst is nearly over. (-:
Important Notice
Once again, I’d like to thank all of the financial supporters, Patreon or otherwise.
The good news is that in a little over a month, 18 Patrons have pledged $122/mo (gross), and that’s awesome! It’s good to know that Virtual Boy still means enough to people that they’d be willing to support something like this, especially considering the only real confidence they had was that some dude said he was worth it.
The bad news is that in a little over a month, the level of interest has pretty much established itself and settled in place. Regrettably, the bills don’t have the same enthusiasm for Virtual Boy that the rest of us do. There’s no great way to say it, but the truth is that the current level of support is insufficient to keep the project moving at its current pace. I unfortunately don’t think it will be sustainable going forward.
Later this week, in the interest of living indoors and eating food daily, I will be submitting applications for employment seeking another source of income. Depending on how that goes, my time to work on the emulator initiative may become limited, being relegated to time off that isn’t spent doing other things. I will continue to work at it on at least a weekly basis at worst, but it won’t be anything like this past month.
To the current Patrons: be advised that beginning in the month of June, I will likely be doing other work instead of focusing on this emulator initiative. I don’t want anyone to feel betrayed by sending their money into a black hole–if you chose to donate in the interest of producing results, then you may consider canceling your Patronage, as I can’t guarantee that your generosity will be spent towards that end.
To everyone, know that the project isn’t dying–far from it. This is still my passion and is first-and-foremost in my list of things to do in my spare time. I may not end up getting to do this as my day job, but at least for the last month I did get to live that dream. (-:
This is a work post.
Still working on the VIP debugger window, but I’ve finally hammered out all the rough spots and what’s left is just a matter of sitting down and doing it–which is quite fun and has been keeping me awake at night! I’d be farther along by now, of course, but a day went to R&D regarding the character subsystem and another day went to replacing my hot water heater… But that hasn’t discouraged progress, no siree.
Attached to this post is a JAR file containing the current build of the application, which contains the Characters and BG Maps tabs of the VIP debugger window. I reworked several things on the back-end to improve simplicity and resource management, and the GridBagLayout error I was encountering before seems to have vanished, so that’s good.
Let’s take a quick look at what’s in there…
Characters
All of the features for this tab are the same as they were in this post, but the presentation is a bit different. You can view all 2,048 character patterns in VIP memory, previewing with any palette or a set of generic colors, and even edit the pixel data by hand.
BG Maps
New to the party is this tab, which displays any of the 64×64 character BG maps in VIP memory. Each individual cell of a BG map contains various properties, such as which character to draw, with what palette, and any flipping that needs to be applied. As expected, all fields can be edited to apply changes back into the emulation state.
The upper Index field selects the BG map displayed in the window, from 0 to 15.
The Index field inside the Cell group selects the global BG map cell, which starts at 0 for the first cell in BG map 0 all the way up to 65535, which technically comes from memory reserved for OBJ attributes, but can be indexed as though it were the 4,096th cell of BG map 15. Changing this field will update the contents of the window to display the corresponding cell from the correct BG map.
Alternatively, the Address field allows you to enter the exact bus address of the cell to select, which will likewise update the window accordingly.
Character, Palette, Horizontal flip and Vertical flip are the formal properties of the selected cell. Only BG palettes can be used here for obvious reasons. Changing any of these fields will write changes back into the emulation state and update the contents of the debugger UI.
Scale works as it does on the Characters tab: by sliding it to the right, the preview of the BG map in the right-hand region of the window will grow.
Checking “Generic colors” will use the generic red gradient colors for all characters in the display. This is primarily useful for previewing graphics while the brightness settings of the VIP are dark or invisible, but ordinarily you won’t need to use it.
Checking “Show grid” will display a grid pattern between BG map cells as seen on the Characters tab. This can be useful for identifying the scope of a cell when the pixels it represents blend together with neighboring cells.
Well, I’m not happy with BufferedImageOp’s performance. I’m afraid we might have to let him go…
Before resorting to the Composite approach, I took the YOLO route and just told the characters to draw themselves to the screen using the built-in Graphics.fillRect() method, one for each pixel of each character being drawn… And it really worked quite well! Ordinarily I hate the idea of calling a graphics method on a per-pixel basis, but when that’s the fastest solution available, sometimes crazy ideas pan out!
Yeti_dude wrote:
Since those sections of memory all reference char memory, are you going to be able to visually show each of those memory spaces? Maybe if you’re looking at a background segment, when you hover over a tile, you can see the values of all the fields in that cell.
You’ve got the right idea. Each graphical element type will have its own tab: these include Characters, BG Maps, Objects, Worlds and Frame Buffer. All of the properties of all of them will be user-editable right there in the VIP debugger window.
I’m not a believer of the mouse-hover ideology, so in this software, if you want to select a character for review from the output, you have to click on it. The idea is that actions are dictated by the user, and it’s up to them to decide what happens. It’s kinda like a link in a web page opening a new browser tab or window. That’s discouraged, since a middle-click or control-click will explicitly do that anyway, so links should never try to make that decision for the user.
To the future Java developer who stumbles on this thread in a web search while trying to do something similar:
Modern Java applications use the Swing API for user interface stuff. The JComponent class used by all Swing controls supplies a pantComponent() method, which can be overridden to provide arbitrary graphical commands to the Java2D graphical subsystem each time the component is drawn to the screen. While paintComponent() receives a Graphics object as its argument, it is an instance of Graphics2D and can safely be cast as such.
If you intend to circumvent the intrinsic drawing functionality provided by Java2D, the most comprehensive low-level control over pixel operations is given by Graphics2D.setComposite() using a custom Composite object. In doing so, you’ll ultimately implement CompositeContext.compose(), which operates on two input Raster objects (one for input source pixels and one for input destination pixels), and a WriteableRaster object for output.
When performing raster operations, you get access to individual component samples for each pixel in the area to be drawn for both the input and output contexts. Care must be taken, as the storage primitive type and number of components per pixel may be different between source and destination. While the methods to access pixel data are able to do type conversions for you, the logic regarding how many components each pixel has is the responsibility of the program. Furthermore, I couldn’t find any simple way to determine the significance of the ordering of pixel components (Does red come first? Last? How about alpha?), but I didn’t really look into it…
Note: Composite requires the execution environment to be allowed to read pixels from the device. This is a potential security risk and may be restricted in some cases such as applets.
While it’s absolutely possible to, for instance, process all of the transformations necessary to render an affine world from within a Composite object, performance considerations suggest that might not be a great idea. Java2D is capable of optimizing image processing through a number of means, most notably caching the contents of BufferedImage objects in some device-compatible way. Accessing simulated VIP memory each time an image is drawn makes caching completely impossible and offers no benefits over pre-rendering the world into a BufferedImage to begin with.
On the opposite end of the spectrum, the VIP debugger window allows the user to select which palette to preview graphics with, meaning just one cached BufferedImage isn’t sufficient for every variation on the output for any given image.
At first I considered using indexed colors on a BufferedImage object. The idea was that the pixel data can be cached as usual, but before drawing the image I could update the palette according to the colors I needed it to use. However, BufferedImage color models happen to be immutable, preventing this from being an option.
The only other solution I found was the variant of Graphics2D.drawImage() that accepts a BufferedImageOp. The filter() method of BufferedImageOp accepts a BufferedImage as input and transforms its pixels (coordinates and colors) into an output BufferedImage. Bulk operations can be performed via getRGB() and setRGB() as usual, and a palette can be dynamically applied to an image in this manner.
While at face value it doesn’t look like this approach would provide any benefits over changing the contents of the source BufferedImage before drawing it, it’s quite likely that the destination BufferedImage object passed to the filter() method is of a different disposition than the ones you can create in userland. According to accounts from developers who have used BufferedImageOp, its performance benefits are significant.
Tomorrow, I will rework the Characters tab to use this technique and then I’ll be able to move onto the remaining tabs.
This is a work post.
Here comes Tenerence Love with an R&D break! Progress on the VIP debugger window is going great, but before I go any further on it, I need to get all my ducks in a row or else face the reality of a bogged-down, ham-fisted kludge of an implementation. And no one wants that.
Progress So Far
The interface for the Characters tab is all done and lookin’ snazzy:
On the right is a list of all 2,048 character patterns currently in CHR RAM. They can be displayed at a configurable scale and palette.
One character is always the focus of attention, which is displayed with jumbo proportions in the top-left corner. It has an index and an address, as well as an address mirror that you can read about here. All three of those controls can be edited by the user in order to select the character they’re most interested in. You can also just click on it in the list on the right if you can find it.
The Scale slider affects the size of the list of characters over on the right-hand side. In the image, they’re being displayed with a scale of 3×.
One of nine palettes can be selected, which is applied to every character in the window. The four BG palettes, four OBJ palettes and a generic palette can be used. The generic palette is a conventional red gradient that is useful for identifying the exact pixel values as well as previewing patterns while the brightness settings are all black (which is the case in Wario Land’s startup screen). The exact colors being displayed for each pixel value are shown as large squares below the palette combo box.
You’ll notice one of the shades of red is selected and that there is a smiley face inside the “O” of “IMPORTANT”. That’s because this interface allows the user to modify the contents of character memory visually at runtime.
Keen observers will note that the black pixels in the output are not fully black: they are a wee bit translucent to let the background window color show through a little bit. This is because black is a valid color for palette entries, so it’s necessary to be able to distinguish between black pixels and empty pixels. I tried drawing no color at all for empty pixels, but red on light gray looks very very bad.
The Hold-Up
So if things are going so swimmingly, what’s the problem? Well, there’s no problem. Yet. And I would like that there never is one, so I need to do some research to determine a satisfactory solution to the upcoming design challenge…
Java has a feature-rich 2D graphics infrastructure that offers hardware acceleration for things such as drawing and filling paths with textures and gradients, or painting image contents, all of which can be transformed and displayed at arbitrary scales and orientations. However, all that fanciness is not well-suited for the type of graphics work being done here, where volatile pixel patterns are used to construct larger images.
Ideally, when drawing images in Java, the contents of the images need to be static so that the JVM can cache them efficiently in order to make the most effective use of the hardware. If the images keeps changing, which is the case for characters in Virtual Boy video memory, that cached data is quickly invalidated and more time winds up getting spent on the caching process than the drawing process by the time it’s all said and done. That’s the problem: the usual Java approach won’t work here.
Granted, the official JVM is also very smart and should be able to optimize image memory performance based on how it’s being used. I don’t know for sure if that’s the case, but even if it is, there are still challenges going forward with regards to composing larger images with character data. Background maps and worlds (namely affine worlds) need to be able to sample from character memory arbitrarily, putting me in a situation where all of the rendering gets done in software in the end regardless. And while that is an option, I’d like to come up with a way to solve both problems with one… stone.
What I would like to do is fairly simple in OpenGL:
• Supply the rendering system with one image containing all character patterns in a 2bpp format
• Sample from any location of any character with or without flipping
• Apply a 4-color palette to the character samples
• Apply transformations to source coordinates in order to sample from normal, H-bias or affine backgrounds
From what I’ve seen so far, this should be doable in Java, although it requires me implementing my own Raster objects among other things. I don’t know how long I’ll spend working on this (shouldn’t be more than a couple days), but I can’t progress with the VIP debugger until I sort it all out.
Stay tuned! This thing keeps on getting better.
Attachments:
This is a work post.
Time for some vidja GUI stuff. This week’s task is already outlined in yonder post intended for last week, but the research and documentation effort went all the way up until Friday so I didn’t get a start on it yet. But now I shall.
We’re gonna have graphics this week, bois!
This is a work post.
Aaaaand there goes a week, entirely to documentation. The CPU stuff, despite being like two and a half times as long, came together more quickly because the available literature was complete and accurate. The VIP stuff, not so much. I had to do a lot of testing on the hardware, and cross-referenced three different sources through it all, but I made due.
New content has been added to the work-in-progress draft of Sacred Tech Scroll v1.0:
http://perfectkiosk.net/stsvb1.html
New content includes the following:
• System memory map with details on various address ranges and the nature of the pseudostatic WRAM
• ROM Format, including Nintendo’s game header and V810’s exception handlers.
• Game Pak, which is the official name for those cartridges we all know and love.
• Updated System Reset section to account for new document content.
• Redlinks to ghosts of the sections yet to come!
Did I forget anything? I think that’s it–OH WAIT, there’s this:
• The VIP stuff. All the VIP stuff!
I painstakingly tested every scenario I could think of in order to determine the proper format and behavior of every little thing in that video unit. I ran across many inaccuracies in the emulator I was using, which made testing a bit tricky, but there was a will and therefore a way.
At long last, now I can begin work on video stuff in the emulator. This is going to be the part in the project where it all looks like it’s coming together, and I can’t wait.
Hey, some actual feedback and discussion… I don’t know what to do! (-:
Before anyone gets disappointed on Friday, it’s looking like this week will only have documentation to serve up. Between researching specs across multiple sources, formatting and rewriting a document and producing testing software, it’s taking longer than I would have liked. But it’s gotta be done, and I need to make sure that everything in the Tech Scroll is 100% accurate.
As of the time of this post, I’ve put all my current additions to the Tech Scroll up on the project page. You can review it here:
http://perfectkiosk.net/stsvb1.html
A fair chunk of the VIP stuff is in there now, so if anyone in the know could take a look at it and let me know what you think, that’d be swell.
DaVince wrote:
I’ll try to spread the word around as well. 🙂
Excellent, and thanks! This is gonna be the key to the project’s ongoing success.
Yeti_dude wrote:
How many iterations of the graphics code have you managed in the past? You know it always takes a few whacks at it.
That’d be approximately zero. However, compared to CPU operations, the VIP is soooooo simple. Just configure some structs in memory and draw a picture with them. It’ll take a fair amount of planning to do it right, but I don’t see spending more than maybe a day on that.
Yeti_dude wrote:
As you’re rewriting the VIP portion of the tech scroll, make sure to switch over to KR155E and community’s terminology.
Once again, I really want to stress that this isn’t “the community’s” terminology, but Nintendo’s, and that’s the only reason I’m using it. I don’t like certain things about it (use of the word “world” makes no sense, something named DPSTTS surely isn’t called “Display Control Read Register”, etc.), but it all needs to be as official as possible to be done correctly.
Yeti_dude wrote:
[Regarding the VIP debugger window] Guy, you can do it! This would be a huge boon to VBDE and it’s sprite engine.
Could you elaborate on why you feel this would be so helpful? I’m interested to know the thought processes of other developers. I’ve generally been able to visualize my graphics when doing my own software, but I’m not the best case study.
Yeti_dude wrote:
I know it’s blasphemy, but it wouldn’t even be the end of the world if the column table wasn’t fully emulated. Like, what good is it anyways?
For the sake of accuracy I’d like to implement it eventually, but it’s a rare case a game system being able to modify not just pixel colors, but pixel dimensions as well. I’m not especially worried about it right now, since I don’t know of any software that ever changes the column widths.
Yeti_dude wrote:
Let’s see if you can get graphics emulated within a week AND then a home-brew demo! Next step looks like VSU, and then busses?
The software I’m using to research the VIP is extremely basic and not worthy of release. It’s literally just this:
Enough to get the information I need, but not fancy by any stretch of the imagination. The only reason VSU Workshop and CPU Workshop came into being was because I needed comprehensive control over those subsystems and it made sense to make them presentable. So I’m sorry to say, no VIP Workshop this time. (-:
The memory bus was the first thing I implemented, since the CPU requires it for fetching instructions and loads/stores. The source file vue/JavaVUE.java contains generic implementations for read and write methods, which the CPU module uses during its internal operations. Those methods are responsible for routing accesses to the appropriate hardware components, and adding, for instance, VIP support is a simple matter of just putting a line in there to tell it where to forward the access request.
Next step is probably going to be the game pad. I’d like to see things operating sooner than later. (-:
Yeti_dude wrote:
What if the PC emulator could make copies of raw rom & ram data: graphics, instructions, registers and interrupt routines? Let the user edit the code or graphics and then save out a usable home-brew resource.
I’ve considered a “Save ROM” command since the debugger window will eventually have assembler functionality, but beyond that it’s a tricky matter to automatically re-pack things like graphics data back into a ROM image. But don’t let the dream die here! Keep the ideas coming, because this is a community effort after all!
Attachments:
This is a work post.
Right this moment, I’m sitting in front of the most progress I’ve ever made on this project. I can see what the CPU sees, and I can change registers and memory. It’s all fairly simple stuff (heck, it came together in a week), but it’s more than I’ve ever had in the past. At first it was trying to implement the emulation core with no real output for debugging, and then it was trying to figure out the best way to make a cross-platform GUI. But now… all of that’s been solved and new tech has been implemented. We’re about to dive into unswum waters!
What do you say we have us some graphics by the end of the week? That’d be cool, right?
To Do – Week of May 7, 2018
Do it all. All the video things. While the VIP is by a wide margin the most complex auxiliary system component, it’s still far simpler than the CPU, which is already implemented. It has maybe like, I dunno, 20% as much going on as the CPU, so this should come together pretty quickly.
• Document VIP operations in the Tech Scroll
The vast majority of the content of the Tech Scroll is the CPU, but in a distant second place is VIP. It has several individual things that need to be researched and documented, but all-in-all it amounts to little more than a bunch of [font=Courier New]struct[/font]s.
Last time I was looking into this, certain behaviors resulting from abnormal configurations of VIP data structures were… perplexing and difficult to describe. For the time being, I won’t be trying to nail down everything in minute detail, so be prepared to see several editor’s notes calling for additional research.
Up until now, revisions of the Tech Scroll have used fairly descriptive names for I/O ports and logical constructs. In particular, I despise the name “world” for describing the windowing functionality, but I think it’s better in the long run to use the official names where available. KR155E rejoices, but let the records show that I decided in this way for reasons not related to his objections!
• Implement a VIP debugger window in the emulator
I’m thinking a conventional tabbed dialog like other emulators have should be sufficient. There will be tabs for characters, background segments, objects, worlds, frame buffers, “current” (see below), the column table, palettes, miscellaneous (see below).
The characters tab will display all 2048 character patterns in a scrollable area with a selectable palette. They can be scaled to some degree (up to maybe 4x?), and clicking one will bring up its data in another panel for editing. The index, address and mirrored address of the selected character will be displayed.
The background segments tab will have a spinner for selecting or entering the index of a segment to display. The image itself will be displayed in a scrollable area with custom scaling. By clicking on a cell within the segment, the cell’s properties (character, flipping, palette, etc.) can be edited. The cell’s address will be displayed.
The objects tab will contain a spinner for picking a particular object, which is displayed in its appropriate position in a mock frame image. Its properties (character, flipping, palette, etc.) can be edited and its address will be displayed.
The worlds tab will contain a spinner for selecting a particular world, which is displayed fully-rendered in a mock frame image. Its properties (position, size, mode, etc.) can be edited and its address will be displayed. Additional controls for h-bias and affine worlds will be available where appropriate.
The “current” tab shows in a mock image what the next frame will look like when drawn, with all worlds fully rendered and layered according to their order. Individual worlds can be toggled on and off in the display. Various statistics regarding the scene will be presented, such as the number of worlds, characters and objects that are in use.
The column table tab contains… um… Honestly, I’ll need to think on this before deciding how to design it. For the time being, column table controls might just be relegated to the misc tab and edited per-column.
The misc tab contains all other VIP settings not included in any other tab. These include the version ID, palettes, brightness levels, interrupt status, the frame repeat setting, drawing and display status/control, frame buffer index and object groups.
• Create some simple test software
This is a homebrew VB program to run on the hardware for research purposes. It’s not a fully-fledged “VIP Workshop”, but it will allow modification of all element properties to inspect their effects on the VIP.
Teknodromen wrote:
I don’t understand the technical stuff here, but would it be possible to make physical copies or a “everdrive” cartridge of some sort?
Someone or other (UncleTusker maybe?) does complete-in-box reproductions of VB software, both commercial and unofficial. Not sure what they’ve got going on at the moment.
As for flash cartridges, you’re looking for MineStorm and his FlashBoy+ wizardry: link
Reel Big Fish wrote:
Ok random question, but is emulating the virtual boy pushing the 3ds hardware to it’s limits?
It shouldn’t be an issue, but testing will tell for sure. While the vanilla 3DS’s CPU is only around ten times as fast as the Virtual Boy’s, emulated software generally isn’t running full-throttle during the entire frame interval. As long as it gets to its halt point/waiting loop in time on the 3DS, it will function just fine without issue, even if the exact number of simulated CPU cycles was less than the actual amount of time that went by.
As a bonus, there’s another CPU in the system that can be used to off-load certain tasks such as video processing and communications. So the faster processor can be dedicated to the simulation and the slower one can take care of auxiliary tasks.
Worse comes to worse, there’s always the recompiler option: take the Virtual Boy program code and transform it into genuine 3DS machine code that runs directly on the CPU. This vastly improves the performance of the simulated software, as most instructions are processed on a 1:1 basis, but the trade-off is that there’s more sophisticated infrastructure required to pull it off.
Either way it has to be done, it will be done. The 3DS is absolutely powerful enough to do anything the Virtual Boy can do, so it’s more a matter of making sure the simulated software turns into the right commands within the right time frame.
Raverrevolution wrote:
I’ve been DYING for a VB emulator on the 3DS and I’m really surprised there hasn’t been a good one released yet. You are doing the lord’s work.
My pleasure! I’ve been wanting to do this for years and years but never really had the opportunity. But benefiting from the support of people in the community can really make it happen, and I’m glad to be a part of it!
This is a work post.
Down to the wire! And that’s just how I like it. Normally I try to have my weekly duties done by end of day on Friday, but obviously this is end of day on Sunday, which is not Friday. When I got the GUI stuff caught back up to the point where I had it in the old project, I went on an improvement spree and made everything about a… a jillion times better than it was. I’m happy to report that everything I wasn’t completely happy with in the old code is no longer a problem in the new code.
Attached to this post is the .jar file of the current build (with the source code inside it). As expected, it looks about the same as the original build, but I can assure you that behind the scenes it’s vastly different and vastly superior.
There is also an image attached to this post. I will be referring to it henceforth…
File Menu
When you start the program, you’ll just get a big gray box and a menu bar. There are two options under File: Load ROM and Exit, and they do about what you’d expect. You can select any Virtual Boy ROM file, and it will attempt to detect incorrect files.
Once a ROM is loaded, the meat and potatoes of the user interface are displayed. There are four main panels, described below.
Disassembler – Upper left
The disassembler pane displays the game program from the perspective of the CPU, where each line is one instruction. A translation module in the project converts the machine code to human-readable assembly for your human viewing pleasure. There are literally dozens of configuration options in this module (debugger/Disassembler.java), but for the moment none of them can be configured with the front-end. The settings provided will display instructions using standard V810 conventions.
The hilighted line is the current value of the CPU’s program counter, which represents the instruction that will be executed next.
The Up and Down arrow keys will scroll the contents of the display one line at a time, and Page Up and Page Down will do so one “screen” at a time (the number of fully-visible lines). Additionally, the mouse scroll wheel can be used to navigate in this manner.
In contrast to most debuggers, there is no scroll bar in the disassembler. A scroll bar that covers an entire 32-bit memory range really isn’t usable, since even small movements can skip hundreds of megabytes at a time. I decided to leave it out, since I can’t find a good reason to put one in there.
In order to seek to a particular address, Ctrl+G will bring up a Goto prompt. By typing an address into this box and clicking Ok, the output of the disassembler will be repositioned to include the address you entered.
You can seek to the value of the program counter with Ctrl+P.
The second column of output is the binary data that contains the instructions’ bits, and for most purposes isn’t all that useful. You can toggle whether this bytes column is shown with Ctrl+H.
The F11 key is Single Step, which executes the instruction at PC, the hilighted line. Most CPU instructions are implemented and fully-functional, with the exception of floating-point and bit string instructions, as they require additional research before being implemented.
The F10 key is Step Over, which attempts to execute until the instruction immediately following the current instruction is reached. This is useful for skipping over function calls as well as breaking out of loops like the one very early on in the crt0 routine. In order to prevent endless loops from hanging the application, a limit of 20 megacycles is placed on this command, which will make it stop automatically after executing one second’s worth of CPU cycles.
Hex Editor – Lower left
The Hex Editor pane displays memory values on the bus as the CPU would see them if it were to perform a read operation. This is useful for examining and editing the memory in use by the simulated Virtual Boy software.
By default, no byte is selected for editing. In this state, the Up and Down arrow keys will scroll the contents of the display one line at a time. Page Up and Page Down will always scroll by one “screen” of lines. The mouse scroll wheel can also be used to navigate.
By clicking any byte value with the mouse, it will be selected for editing. In this state, the arrow keys will move the cursor around as expected. At this point, typing any hex digit will begin composing a new byte value at the selected address. After the first digit is typed, the temporary staged value is only that low digit, but by typing a second digit, a full 8-bit value is written into memory and the cursor is advanced to the next byte. In order to commit an edit after only one digit, press the Enter key.
To de-select the selected byte value and return to the default state, press the Escape key.
Ctrl+G will present a Goto prompt where you can type an exact address to seek to. In addition to navigating to that location, the byte at the specified address will be selected for editing.
Registers – Right-hand side
Both of the right-hand panes are for CPU registers. The top pane contains the special “system regsiters”, while the bottom pane contains the usual “program registers”. Any register with a “+” next to its name can be expanded by clicking on it, revealing additional controls.
The value of each register, shown next to its name, is displayed in a flat text box and can be edited directly with the keyboard by clicking it and typing into it. The new value is stored into the register either when the text box loses focus or the Enter key is pressed. Although any value can be entered, certain bits of certain registers cannot be written and this will be reflected in the value that is immediately displayed after editing.
Certain system registers represent multiple values that are packed into a 32-bit unit. By expanding these registers, the individual fields can be inspected and edited. The I field in PSW, and both fields in ECR, are text boxes that can be typed in. The remaining fields are 1-bit flags that are controlled via text boxes.
Although TKCW has bit fields that are displayed in the expanded controls, the register is in fact read-only and the expansion controls cannot be interacted with.
All program registers have options for representing the value in different presentation formats. The available formats are Hex, Signed decimal, Unsigned decimal and Float. When a particular format is active on a program register, the value displayed is in that format and any values entered with the keyboard will be processed as that format.
Debug Writes
Like I mentioned in last week’s report, I set up the new back-end to support “debug” accesses for read and write operations. This is useful for the person doing the debugging, as it allows for test situations that aren’t technically possible within the simulated software.
The debug accesses in use by the debugger are as follows:
• ECR is read-only to emulated software, but can be changed in the debugger.
• System register 31 provides the absolute value of the most recent value written to it, but the debugger can store any value.
• Editing ROM data in the hex editor will update the backing memory, even though the simulated software cannot write to it.
Known Issues
What appears to be a long-standing bug in Java is creating a layout error intermittently with no known cause. If, after you select a ROM to load, the window goes white or otherwise doesn’t display correctly, you’ll need to close the program and try again. Hopefully I can find out how to work around this issue, or maybe someone else can help track it down. Or maybe my RAM is going bad and that has something to do with it…
SmokeMonster wrote:
Backed! Congrats and thanks for taking this project on.
Awesome! Thanks again for everyone who has pitched in. For the month of April, we raised $137.34. Although I can’t live off of that, it’s still a great start considering all anyone had to go on was me saying “gimme moneys” and they believed in me. So all-in-all, this is a big win!
We should be playing games by the end of May, and hopefully be playing them on 3DS sometime in June. Expect it to get really interesting really quickly.