Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
hendersa
Sep 17, 2006

I've been working on an implementation of the original Nintendo Entertainment System on an FPGA. It is more for the learning experience of designing a larger VHDL system, as well as the various components (PPU, MMU, etc.).




It has been coming along remarkably well so far. I don't have a ton of time to work on it, but I chip away at the project here and there when I have a spare hour or two. I realize that something like Xilinx's WebPack software would be a one-stop shop for this sort of thing, but I have selected a bunch of free apps (GHDL, GTKWave, etc.) to develop it so that I have a chance to see all of the intermediary steps involved in the design process without falling into the trap of seeing one vendor's approach as being the universally correct one.

Also, there is a special place in hell reserved for those that use the vendor-specific std_logic_arith VHDL library, rather than the IEEE numeric_std one.

I began by writing a 6502 disassembler in C, as well as a ROM loader for the .NES format.



I compared my generated dumps against disassemblies already on the web to make sure that I was performing the disassembly right. It turns out that Super Mario Bros has been analyzed to death, so disassembling that ROM was a good place to start. Then, as I developed the chip, I hardcoded the dumps into a VHDL testbench so that I could drive the system state instruction by instruction while monitoring the same instructions on an emulator for a "known good" comparison:



Edit: Added in some links, in case someone wants to check the various tools out. Also added in a few bits about the disassembler.

hendersa fucked around with this message at 16:39 on Jul 5, 2012

Adbot
ADBOT LOVES YOU

hendersa
Sep 17, 2006

mnd posted:

Hey there FPGA-designing, Mendeley-using, VHDL-writing buddy. :respek:

(Also, nice icculus.org shell account. I take it you know Ryan Gordon?)

You do know that you're eventually going to need to use your FPGA's vendor's tools at least to translate your e.g. netlist into their bitcode for use on the FPGA itself, right? GHDL will give you a executable for your design and testbenches, but if you want to synthesize anything, you will probably want to use ISE WebPack or Quartus II Web Edition (or $FREE_VENDOR_TOOL_HERE if you're using some more obscure part) sooner rather than later, even if you don't use it for the bulk of your design work, in order to be able to get realistic reports on resource utilization and PnR. Engineering with FPGAs is still very much tied up with vendor tools no matter what (unfortunately), since each vendor's FPGAs only work with their bitcode formats, IP libraries, and synthesis tools.

I do applaud you going the route you're going through. Specifically regarding GHDL, are you using it on Windows? I have a bunch of half-working old-to-new patches and hacks to GHDL, some Windows-related, some (older ones) OS-X-related, that I ought to clean up and publish. I'm really interested in other user reports of GHDL on Windows and OS X (in that order): gripes, features requests, etc. Bugs should probably still go to Tristan. :)

I've used WebPack in the past for developing on this guy right here, so I had enough gates to burn to be a bit sloppy with it. That's probably similar to the board I'll be using to actually test the physical design. At the time, I was barely scraping the surface of the simulation portion of development, and many details were hidden, so I doubt that what I was creating was "good". I'm just trying to fill in the experience gaps. Since the number of gates available on that platform is huge and the 1.79 MHz clock of the NES's Ricoh 2A03 is far below any point where propagation delay will be a concern (hopefully), and I'm not using anything like the dedicated DLL circuits, I will have a ton of wiggle room during PnR. If I were going for the cheapest FPGA I could get away with as a target, I'd be using far more targeted tools from the get-go. I think I'll learn a few things, too, in reworking the pristine VHDL codebase to get it working on the real hardware when the time comes.

GHDL is, in my opinion, a buggy piece of software that implements the VHDL standard very well. Or, at least, that is the way it appears under Windows. I've found that it likes to hang during testbench execution once things begin to get even slightly complex. I suspect that it is some form of internal signal oscillation going on, which leads to time halting at that point in the simulation. I've also noticed this occurs sometimes when using a single "report" statement before a "wait" at the end of the simulation. In most cases where it freezes (both at the "wait" and at other points during the simulation), you can just stick a "report" statement in there and it won't freeze on you next time. This doesn't make sense, since the simulation is obviously not dependent upon the "report" statements. Oh well.

I used to share an office with Ryan when we both worked at Loki Games back around 2000/2001. Aside from the porting work for our jobs, I joined him in porting a few open-source projects to Linux (stuff like the BUILD engine). Back then, we did that sort of stuff to gain experience, learn some new things, and build a critical mass of example code on the web so that others could start doing the same sort of thing. We were also probably the only ones around at the time that had both the know-how and free time to do it. He decided that he enjoyed that kind of work so much that he became a cross-platform development consultant/contractor full-time. I went off into industry and academia (hence the Mendeley open in the background).

hendersa
Sep 17, 2006

PDP-1 posted:

This is cool as heck, good job so far. I'd love to follow along as it progresses so instead of taking things to PM with individual people please choose a thread here on SA or make a blog or whatever so the rest of us can watch your progress.

The electronics thread might be a good place to go with it, it's fairly active and this kind of work would go over there bigtime.

I've actually PM'd a few folks already that wanted more information. I didn't expect there to be that much interest in the project. I'll have to gather up some information for anyone that would like to see more. I don't know if I would use a thread to cover the progress, since my work is so sporadic that a thread of my own might go a long time between updates. The electronics thread might be a good venue, though. I'll check it out. In the meantime, anyone who wants more information is welcome to PM me and I'll answer questions as soon as I am able to do so.

hendersa
Sep 17, 2006

UraniumAnchor posted:



Nothing special yet, but it's merely the first step...
I just loves me some 6502. :3:

It looks like you've got everything sorted out, but maybe this might help? Here are the macros from my C code for my quickie 6502 disassembler:

code:
#define IMMEDIATE(op) { printf("%04x: %02x %02x -- %s $%02x\n", (currentIP + 0x8000), *(code+currentIP), (*(code+currentIP+1)), op, (*(code+currentIP+1))); currentIP += 2; break; }
#define ZEROPAGE(op) { printf("%04x: %02x %02x -- %s $00%02x\n", (currentIP + 0x8000), *(code+currentIP), (*(code+currentIP+1)), op, (*(code+currentIP+1))); currentIP += 2; break; }
#define ZEROPAGE_X(op) { printf("%04x: %02x %02x -- %s $00%02x, X\n", (currentIP + 0x8000), *(code+currentIP), (*(code+currentIP+1)), op, (*(code+currentIP+1))); currentIP += 2; break; }
#define ZEROPAGE_Y(op) { printf("%04x: %02x %02x -- %s $00%02x, Y\n", (currentIP + 0x8000), *(code+currentIP), (*(code+currentIP+1)), op, (*(code+currentIP+1))); currentIP += 2; break; }
#define ABSOLUTE(op) { printf("%04x: %02x %02x %02x %s $%02x%02x\n", (currentIP + 0x8000), *(code+currentIP), (*(code+currentIP+1)), (*(code+currentIP+2)), op, (*(code+currentIP+2)), (*(code+currentIP+1))); currentIP += 3; break; }
#define ABSOLUTE_X(op) { printf("%04x: %02x %02x %02x %s $%02x%02x, X\n", (currentIP + 0x8000), *(code+currentIP), (*(code+currentIP+1)), (*(code+currentIP+2)), op, (*(code+currentIP+2)), (*(code+currentIP+1))); currentIP += 3; break; }
#define ABSOLUTE_Y(op) { printf("%04x: %02x %02x %02x %s $%02x%02x, Y\n", (currentIP + 0x8000), *(code+currentIP), (*(code+currentIP+1)), (*(code+currentIP+2)), op, (*(code+currentIP+2)), (*(code+currentIP+1))); currentIP += 3; break; }
#define INDIRECT(op) { printf("%04x: %02x %02x %02x %s ($%02x%02x)\n", (currentIP + 0x8000), *(code+currentIP), (*(code+currentIP+1)), (*(code+currentIP+2)), op, (*(code+currentIP+2)), (*(code+currentIP+1))); currentIP += 3; break; }
#define INDIRECT_X(op) { printf("%04x: %02x %02x -- %s ($%02x, X)\n", (currentIP + 0x8000), *(code+currentIP), (*(code+currentIP+1)), op, (*(code+currentIP+1))); currentIP += 2; break; }
#define INDIRECT_Y(op) { printf("%04x: %02x %02x -- %s ($%02x), Y\n", (currentIP + 0x8000), *(code+currentIP), (*(code+currentIP+1)), op, (*(code+currentIP+1))); currentIP += 2; break; }
#define ACCUMULATOR(op) { printf("%04x: %02x -- -- %s A\n", (currentIP + 0x8000), *(code+currentIP), op); currentIP++; break; }
#define RELATIVE(op) { printf("%04x: %02x %02x -- %s $%02x\n", (currentIP + 0x8000), *(code+currentIP), (*(code+currentIP+1)), op, (*(code+currentIP+1))); currentIP += 2; break; }
#define IMPLIED(op) { printf("%04x: %02x -- -- %s\n", (currentIP + 0x8000), *(code+currentIP), op); currentIP++; break; }
#define INVALID { printf("%04x: %02x -- -- INVALID \n", (currentIP + 0x8000), *(code+currentIP)); currentIP++; break; }
#define INVALID_TWO { printf("%04x: %02x %02x -- INVALID \n", (currentIP + 0x8000), *(code+currentIP), (*(code+currentIP+1))); currentIP += 2; break; }
#define INVALID_THREE { printf("%04x: %02x %02x %02x INVALID \n", (currentIP + 0x8000), *(code+currentIP), (*(code+currentIP+1)),(*(code+currentIP+2))); currentIP += 3; break; }
I set up a large case statement to use them like this:

code:
    switch (*(code+currentIP))
    {
      /**** ADC ****/
      case 0x69: IMMEDIATE("ADC")
      case 0x65: ZEROPAGE("ADC")
      case 0x75: ZEROPAGE_X("ADC")
      case 0x6D: ABSOLUTE("ADC")
      case 0x7D: ABSOLUTE_X("ADC")
      case 0x79: ABSOLUTE_Y("ADC")
      case 0x61: INDIRECT_X("ADC")
      case 0x71: INDIRECT_Y("ADC")
      /**** AND ****/
      ...
Set up the switch for whatever opcodes are supported by your hardware and you are good to go. I use a base address of $8000 because of the hardware I am working with, but you can use whatever for your project. The only gotcha is if there is a large data block in the middle of a binary dump, you can interpret some of the data as instructions, get one or two bytes off, and then get garbage after that point in your disassembly. You get output like:

code:
8000: 78 -- -- SEI
8001: d8 -- -- CLD
8002: a9 10 -- LDA $10
8004: 8d 00 20 STA $2000
8007: a2 ff -- LDX $ff
8009: 9a -- -- TXS
800a: ad 02 20 LDA $2002

hendersa
Sep 17, 2006

Winkle-Daddy posted:

Is there any software that can generate documents like this in which I can provide a series of functions/methods to help organize a loving massive OO project I'm working on? I'm thinking something that will draw boxes for me, the box will be labeled with the method name, then it has input arrows/output arrows for the values in and out. It would really help me collaborate with a small team because we would be able to be responsible for different parts of the application, and so long as everyone follows their input guidelines and provide correct output based on the document, I can modularize dev work with a small team.

I am a programming tinkerer and mostly do system admin stuff, so I've never had the opportunity to see what kinds of tools are used for something like this.

Perhaps Graphviz might help. That's where I'd start.

hendersa
Sep 17, 2006

Wedge of Lime posted:

For a while now I've been working on developing a tracing library for a user land driver under Linux on an embedded arm device called the Allwinner A10.

Here is a screen shot of the output. Its not especially exciting to look at but quite a lot of work went into it. Especially the instruction parsing and processing.



I've got my code up on github with more details https://github.com/iainb/CedarXWrapper if anyone wants to take a look.

This is a nice piece of work. Simple and clean. I thought you were taking an strace/truss approach to get the libc calls that wrap system calls, but I can see that you've got wrappers in wrap.c to handle those. That would explain why you're showing so few functions in your output... you're only catching ioctl() calls and some memory ops.

I don't usually see opcode cases like you have in instructions.c, though. Your way is very clean and logically grouped, and more intuitive to follow. I usually see a big, honking switch statement for every single interesting opcode/addressing mode combo with a default case at the bottom for whatever opcodes you don't care about. The big switch statement is for speed, since you avoid multiple comparisons on each opcode to whittle down to the special case that you want. That way is all about performance. If it isn't that much of a slow down for you, then your way is much easier to follow.

FYI, I've done much the same thing that you have in the past, except it was for developing/debugging an audio driver in userspace. I would lspci to find the memory space for the PCI device, mmap() /dev/mem in my userspace "driver" to get access to the memory-mapped PCI control registers, mprotect() to make those memory pages writable, and then write straight to those mapped registers to control the hardware

It is SO much easier to catch buffer overflows and other assorted bad behavior in userspace than as a kernel driver, so you're definitely taking a good approach. Thanks for putting it out there for others to learn from.

hendersa
Sep 17, 2006

bc87 posted:

I've been working on my own market log analyzer for a game called Eve Online
I once did much the same thing. I had built up a regression model using the market data from http://eve-central.com/dumps/ to decide what the pricing should be for a certain good at a certain system taking factors like region, sec rating, distance from Jita (or other closest market hub), base Jita price, etc. I believe I had something like 9 or 10 variables to start, but I dropped a few because they were shown to not be statistically significant. Using historical data, I adjusted the weights on each factor until I had a pretty decent model. I used a small C program to parse the data dump and then spit it out in a comma delimited format for use in Excel.

For a while, I used it and absolutely cleaned up. I'd load up a freighter in Jita and then make a beeline out to some 0.5 system a few jumps from 0.0. As I went, I'd seed goods in each system per my pricing guidelines. After a while, it got kinda boring and took an hour or two to do a full reseeding run. Just plug certain values into the equation depending upon location and good and out comes the price you should set. It began to feel more like a job, so I stopped doing it (and playing all together, actually).

It is one of the few things that I've actually used my MBA for. :toot:

hendersa
Sep 17, 2006

Time for a status update on stuff. The VHDL NES is coming along, though my work has kept me busy and progress is dragging along. My current plan is to push for my work on the project to be a graduate-level independent study course over the summer. I'm also looking at targeting the XSA-3S1000 platform for the testing on actual hardware, since it has the VGA port built in and enough I/O pins for the cartridge connector. I'll have to rig up an external op-amp circuit for the audio output, but that shouldn't be too tough. I would have liked a built-in DAC, but what are you going to do. It seems silly to buy the big add-on board that provides an audio DAC when I could throw one together for $15.

As for more active work, my embedded systems design class has a course project using an ARM-based BeagleBoard-xM single board computer. The project is left up to each team of students as to what they would like to do with it. Most students are making things like network routers, stepper motor controllers, and traffic light controllers. Of course, me being me, I chose to make a Super Nintendo. If you have that much multimedia capability in your embedded platform, why not make the most out of it? I'm the only one in the class working by myself, rather than being in a team, so that allows me to work on my project during all of that unused idle time in my day that falls between midnight and 3 AM.



The current timing of the S-video NTSC signal is a bit off, leading to a shifted picture, so I need to figure out how to address that. Let me tell you... there are few things more tedious than calculating timing information for video signals. Software adjustments to expand it to fullscreen are costly in terms of performance, but I might be able to get away with a simple rendering offset: render a centered 640x480 subbuffer within the 720x482 native framebuffer with "filler panels" on the sides. I can get enough frames per second to actually play a game with the render offset, so that's a plus. For my testing setup, I'm pushing the S-video's NTSC signal through a VGA converter box so that I can use my desktop monitor as the display.

I have a Linux 3.7.8 kernel with some experimental drivers running the system, and I'm still hacking on the kernel audio codec driver to get the audio working properly. Input is via a Tomee USB SNES controller. I could have gone with an actual SNES controller plugged into a special USB adapter, but you experience some noteworthy input lag using that method. The USB driver and software configuration for the controller also needs some work. Hopefully, that part will be far less hacking on kernel drivers and more user-space work instead.

Once the major subsystems are all working, I'll put together a controller-driven GUI to turn the system into a formal "embedded appliance". I'll also rework the partitions to make as much of the filesystem mounted as read-only as possible, allowing you to turn the power on and off quickly without requiring an filesystem check. Reducing boot time, adding a boot splash screen, etc. also need to be addressed.

hendersa fucked around with this message at 17:35 on Feb 27, 2013

hendersa
Sep 17, 2006

Keebler posted:

Wow nice, that's a lot of work! Are you also writing your own emulator for the SNES or using something off the shelf?

The emulator is SNES9X (v1.5.3). In particular, it is the SNES9X-SDL port. It has fallback C-based emulation cores, and while the fallback cores are slower than their x86 assembly counterparts, there aren't assembly cores for ARM available. Besides, I have enough CPU horsepower to perform the emulation at at least 30 FPS, which is the refresh rate of NTSC. It's actually emulating at 60 FPS, but if the FPS drops because of computing-intensive activity, you never even notice because it doesn't get below the 30 FPS threshold of the video signal.

I chose the SDL port because the base SNES9X only uses X11 as its rendering target and event capture mechanism on the Linux platform. I'm running on a raw, native resolution frame buffer target (/dev/fb0) without an X server, and SDL allows me to use the framebuffer as a video target (the "fbcon" video driver). Using SDL also allows me to use the various SDL test programs to run through each subsystem (audio, video, input) to troubleshoot kernel issues. I've found that the SDL port of SNES9X has a few quirks, but it isn't anything that I can't fix. Joystick/gamepad support was commented out for some reason, it wasn't parsing button configuration from the config file, etc. Little problems that were solved fairly quickly by running through the SDL test programs to capture data and then hard-coding it into SNES9X.

Much of the needed code is out there, but the trick comes in getting it all configured and running. After a while, you get really good at finding all the bits and pieces that you need, since the real work is in designing and configuring the system, rather than writing code for every little subsystem. I've spent more time digging through kernel bug report mailing lists than I have touching code. There are a lot of wikis that contained the info that I needed, but it took some doing to resolve conflicting and outdated information. In a few cases, I just had to look at the kernel source to find out what was really going on, since I was seeing a lot of "I think it works like this..." on mailing lists, and it just wasn't true.

Doctor w-rw-rw- posted:

There are off-the-shelp hardware implementations of the SNES available?

There are a few bits and pieces of hardware SNES implementations out there:

fpgasnes
snes-apu-fpga
SNES SPC music player

Basically, there are a lot of (usually incomplete) available hardware designs for SNES subsystems that could be cobbled together to get something working. For my project, though, I am using a commodity hardware design and am emulating the SNES functionality in software.

hendersa
Sep 17, 2006

I was happy to finally get my last major audio bug diagnosed and taken care of. After a little bit more tuning, the audio now works like a champ with minimal CPU impact. Once I got that part up and rolling, I recorded a clip of the BeagleBoard SNES running in its current state: https://www.youtube.com/watch?v=enscdpjscz0

Still quite a bit to do, but the major subsystems are all up and running now.

hendersa
Sep 17, 2006

Grawl posted:

How well does it go with games like Final Fantasy VI or Plok?
Well, I've only used a few test ROMs, so I'm not really sure. My primary concern was making sure that basic tile layering (SMB All Stars) and Mode 7 (F-Zero) functionalities weren't going to kill the CPU. If a game has gobs and gobs of semi-transparent layers, like FF VI or Chrono Trigger do, then there might be a performance problem. But, that problem will be in the emulator code and will become an optimization problem to be dealt with later, if at all. I'm basically at the mercy of how well the emulator handles that sort of thing. As long as the layers are handled accurately by the emulator, then framedropping will at least keep the emulation time-table on track.

I've not heard of Plok before now, so I'm not familiar with just how fancy it gets with the various features of the SNES. I can't really judge how well it will play.

hendersa
Sep 17, 2006

Le0 posted:

Awesome dude, great work! Do you plan to release anything of your work?
You bet. It's a class project, so I'll have to clean it up a bit and prepare information on it anyway. Might as well get it out there so that others can play with it. At a bare minimum, I'll just "dd" off the raw data from the microSD card and provide an image of it for download so that others can "dd" the image onto a new microSD and use it as-is. I can't distribute ROMs with it, but it shouldn't be too tough for people to copy their own into the image.

I have the source code in the image already, since I only cross-compile for things like the kernel. The emulator app can be built in-place on the board as long as you turn on swapping (the 512 MB of RAM is exhausted when building), so everything that you need to build it (toolchain, source, libraries) will be in there. I'll probably break the source out of the image and then provide that separately as well, so that people can examine it without having to mount the image to get at it. I want to make it easy for people casually interested to take a quick look and see how it works.

hendersa
Sep 17, 2006

I've made a little bit more progress with the graphical front-end to the Beagleboard SNES emulator platform. Here's a screenshot:



The red around the edges acts as a guide for me so that I know where to assume there might be NTSC overscan. I'm going with the Microsoft X-Box developer guideline of assuming 15% overscan (7.5% buffer on all sides). Some TVs cut it off, but some don't, so you need to design with this in mind. The red bars will be removed during final integration.

The crawl across the bottom of the screen is animated, as is the selection overlay on the menu. The transition of the selection overlay from item to item is a smooth animation when changing your selection. It thought it looked nicer than just jumping from one to another immediately. The selection overlay is also animated so that it "pulses" a bit and gets your attention.

I also spent far too long drawing that logo.

There is also tracked background music that plays while the menu is up. You can grab a copy of it from here:

http://icculus.org/~hendersa/virility.xm

I still need to do more animation on the crawl controllers, as well as integrate this front-end into the emulator itself. Overall, though, I think most of the time-consuming "busy work" (getting everything the right size and positioned) is pretty much done. I'm no UI guy or graphic artist, so I spent a good chunk of time fighting with GIMP to create all of these graphics and get it all laid out.

hendersa
Sep 17, 2006

Internet Janitor posted:

hendersa: Looks like a pretty cool project. I'm no expert on design either, but I have a suggestion- you're kind of mixing a number of different styles. The gamepad is pixel art, the logo uses a flat, cartoony look and you're using a neon gradient "next gen" style for the game selection cursor. Any of those can look good, but they clash with one another. I'd put some thought into making these elements match better. For example, if you like the logo, use a flat contrasting hilight color in the game selection menu and find/create an SNES controller graphic in the same style as the logo. It will overall give your project a more polished and coherent appearance.

Thanks for the feedback. The cartoon-y look for the logo comes from the logo for the Beagleboard hardware platform that the system is running on:



Nothing else is based upon the style of the logo, since I prefer the "next gen" style that you mentioned for the other fonts and the selection overlay/cursor. I see what you mean about the pixel art for the gamepad images, so I replaced them with some photo-realistic d-pad and start button images:



I think it looks better now, with the changes. Thanks!

(By the way, if anyone recognizes the font in that Beagleboard logo, let me know so that I can better match it for the project logo.)

hendersa
Sep 17, 2006

Suspicious Dish posted:

The font is a classic: VAG Rounded Bold.

I suggest getting a better grip on typography and font choices, as well.

Thanks for pointing me towards the font. I pulled a TTF version of it from the web and re-did the logo.

I'll be the first to admit that I know hardly anything about fonts or font faces. So, I don't even know where to begin to "get a better grip" on such things. Do you have any specific suggestions that I should try to improve it? Is there anything obviously wrong with the fonts currently in use? Is it because I'm using a single font for the entire interface?

hendersa
Sep 17, 2006

Lumpy posted:

Suspicious Dish can be a bit.. uh... "short" sometimes.

As far as "getting a grip" on such things, there's nothing wrong with using the same typeface throughout, and the one you've chosen is fine. There are some things I would change as UX / Graphic Designer, but what you have is tons better than most programmer made interfaces.

I did a quick 10 minute mock up of what I would consider a modest improvement, and why:

1. Reduced the size of the logo. It doesn't help the user *do* anything, so it should be a non-prominent visual element.
2. Moved game list over to left side. Assuming an english user base, we read left to right, so the thing we do "first" goes on the left.
3. Reduced prominence of instructions. A user should be able to find this, but realistically will only need it once, so move it visually "back" while still being easy to see, and where it's relevant: near the list you need to navigate.
4. Changed the game display slightly: moved the info around a bit, and faded the labels back visually, as the content is what's important ("1991" is what I want to know, so it should be more prominent than it's label "release date")

The key to good UI design is being able to step into the shoes of somebody else and figure out what they want to do. Then, make that pretty =)
This is very useful feedback, and I do really appreciate it. I'll spend some time reworking my interface to have a similar look and layout to what you have suggested. I'll have to make a few changes to it in order to accommodate the NTSC overscan, but that shouldn't be too difficult. I can shrink down my overscan safety margins a little bit (it can be as little as 3.5% - 5.0% overscan on the vertical axis), but I'll have to "squeeze" everything inward a bit on the horizontal axis to get everything inside the safety zone. The vertical overscan makes the upper gradient of the logo bar a problem, but the lower gradient on the same bar should be fine.

Lumpy posted:

Also, your project is really awesome, thanks for sharing your progress.
Thanks for all of your help! I'll be sure to mention you and Suspicious Dish in the documentation to credit you both for your assistance.

hendersa
Sep 17, 2006

Lumpy posted:

If you'd like some pro-bono design help, PM me, and I'll spend some quality time on it taking into account your technical requirements.
I might check in with you later on for some more pointers and general advice if something needs tweaking. I think that this setup is probably "good enough for who it's for" at the moment, though:



... and with the potential overscan areas marked:



You UI/UX folks really know your stuff! This is a big improvement.

There are a few things that aren't done, like resizing the box images to make them a touch smaller, but it looks pretty good for now. I could push the info panel over to the left a bit more and maybe increase the size of the game description text a point, and my images with alpha blending are a little clunky. Still, I think it will do.

hendersa
Sep 17, 2006

I've been a bit sick and haven't been too responsive, though I am collecting everyone's feedback. Depending on how much time I have to spare to polish up the GUI, I'll be making some changes. For now, though, I'm inclined to leave it because I have a lot of other technical work to do to get it all integrated together.

My analog-to-VGA converter box really washes out the colors and introduces a lot of signal noise, so this doesn't look nearly as nice in this picture as it will in a direct connection a TV:



Most of the NTSC overscan is happening on the left side of the screen. Remember, the red bar on the left side of the screen is the same size as the red bar on the right in the "logical" video framebuffer. Maybe five or six pixels are lost to overscan on the top and bottom red bars of the screen. The item selection marker should be OK, even though it is hard to see in the picture because of the NTSC signal degradation.

I put up a YouTube video clip of the GUI (without the red overscan indicator bars) here.

hendersa
Sep 17, 2006

Internet Janitor posted:

Your selection cursor seems to be using a linear tween. Pop a sigmoid easing function on that puppy and speed it up a little- I think you'll find it feels more responsive.
I just hacked this in really quick and it looks good. It looks more like the bar speeds up and "snaps" into place on the next item. You can really tell when you hold down up or down and watch the selection cursor move through the list of items. Thanks for the suggestion!

(I also now know what a modified logistic sigmoid function looks like.)

hendersa
Sep 17, 2006

I've made some real progress on the BeagleSNES, but I need to set it aside for a while because I have plenty of other projects to take care of. I made another YouTube video of my progress, which is here: https://www.youtube.com/watch?v=ZUJBxtNpcys

My latest work has focused on system stability and speed. This has involved the following tasks:

- Research and compare a bunch of kernel patches for each Linux kernel version to best judge which one is the right trade-off of bugs versus features.
- Start building custom kernels to incorporate those patches and to trim down the kernel to reduce memory footprint, build time, and loading time.
- Build a custom bootloader to match the kernel and hard-code some of the features that I want.

I decided to clock the CPU at 800 MHz via the bootloader and the cpufreq modules in the kernel. The base speed for the CPU is 600 MHz, though 600, 800, and 1000 MHz are all acceptable (according to the documentation). The catch with clocking at 1 GHz is that the drivers for TI's voltage-regulation subsystems aren't in recent kernels. There was a stretch back around the 2.6.30+ to 3.0.x kernels that allowed you to safely clock the CPU at 1 GHz, but those kernels also include a bunch of USB bugs that have since been fixed. I did fall back to those old kernels and tried them (pulling the 2.6 kernel from the demo Angstrom distro that came with the board and the 3.0.17 kernel from here), but the system seemed a little quirky. I'd see the emulator crash every now and then for no good reason.

I now use the "performance" CPU frequency stepping module in the kernel. Before, it was just the "ondemand". I'm basically just running the CPU at 800 MHz all the time, and the only downside I see is that sometime the NTSC video remains blank if the chips are hot. If you give them a few minutes to cool, it usually comes up with no problem. It's a hardware issue, rather than software, so I'm not too worried.

The U-Boot bootloader in BeagleSNES is now running a custom build of v2013.01.01 that I cross-compiled to ARM from my x86 Linux development VM. I built an x86 host, ARMv7 target toolchain using crosstool-ng, which was pretty painless. There were a few quirks, but a bit of googling got it all sorted out. My custom kernel is also compiled using that same toolchain.

While I am disappointed that I couldn't just clock at 1 GHz and go, it isn't too much of a loss. I can't run Star Fox because the Super FX chip emulation just doesn't run very well at 800 MHz (only 4 or 5 FPS, typically). It does run well at 1 GHz, but that doesn't do much for you if it crashes all of the time.

hendersa
Sep 17, 2006

Delta-Wye posted:

What ARM processor is on there? I had a similar problem with an OMAP2 processor - it would run at 1GHz, it just wasn't stable at all :smith:
It is a DM3730, which is an ARM Cortex A8 processor. For Linux kernel configuration purposes, it is an OMAP3.

hendersa
Sep 17, 2006

The BeagleSNES project is moving right along, and I just finished up a simple project launch trailer for it: https://www.youtube.com/watch?v=8pl87z0w8B0

I don't have the video publicly searchable, so it is really only you guys that will see it for now. I've registered a domain name (beaglesnes.org), and I'll be opening a project at SourceForge for it and getting the DNS to point there as soon as I get a webpage up and make the code and file system images ready for download. My development task list is still pretty long, but I think it is solid enough to take a snapshot and get the project out there for people to look at it.

:toot:

hendersa
Sep 17, 2006

Doctor w-rw-rw- posted:

SourceForge? Really? What advantages do you see SF giving you over, say, GitHub?

I'll have web hosting of my project domain directed to a vhost at SourceForge. I will not be using the source control repositories because my project is a collection of large components, several binary-only. I am making a single, large filesystem image available (about 4GB decompressed) and tarballs of individual components available so that people are able to examine particular components that they are interested in. SourceForge offers a project wiki, just like GitHub, for any documentation that I need to make available.

I just need web hosting for my project's domain and unlimited, free bandwidth for downloading the massive files of my project for end users. SourceForge fits the bill.

hendersa
Sep 17, 2006

I'm happy to report that http://www.beaglesnes.org is up and running. If you want my SNES emulator for your BeagleBoard-xM, go download it and go to town. I'm still working on the docs and all, but the code and filesystem images are available, at least.

Also, Internet Janitor, Suspicious Dish, and Lumpy: I'd like to credit you three for providing assistance with my GUI development. If you can PM me or shoot me a mail at hendersa (at) icculus.org with the name and contact e-mail (if you want one listed) that you want to be credited under, I'll get you guys in the docs as soon as I can.

hendersa
Sep 17, 2006

I've been fighting with the logistics of releasing BeagleSNES as an open source project. I think that far too many people release software by just sticking it on the web as a tarball and saying "help yourself". There's a lot of documentation and packaging that goes into making software "useful" to an interested end-user or developer. The documentation is particularly important, since complex systems can be really difficult to get set up and running without good guidance.

As I started gathering up all of my various sheets of notes and began writing documentation, I have found that I keep identifying more and more things that should probably be documented. I could probably write a book on all of it. So, why not?




Man, I hope there's some open source software award out there that is given for "most awesome documentation".

hendersa
Sep 17, 2006

Top Quark posted:

I hate to do this to such an awesome project, but my inner OCD requires me to inform you that "funtionality" is spelled wrong on the second image, second paragraph, second line.

I will say though that I wish all the projects I used had such good documentation, props to you for sticking with what is usually one of the dullest parts of development.

No problem at all. I welcome all feedback! Otherwise, how would it get any better? It has not been run through a grammar or spell check yet, so I'm sure there are plenty of typos in there. I'll probably sic a bunch of goons on it as editors prior to release, if I can get a few volunteers.

hendersa
Sep 17, 2006

More documentation pages in progress! :stare:

Troubleshooting:


Kernel/bootloader timeline:


OK. That's enough screenshots of documentation.

hendersa
Sep 17, 2006

Ephphatha posted:

I don't suppose you've got a link to the WIP pdf anywhere? It's hell reading halfway through a paragraph and not having the next page available.

Sure. Here you go.

hendersa
Sep 17, 2006

I've been hacking on the bootloader for BeagleSNES. I'm trying to get the video to initialize properly so that I can display a custom splash screen immediately upon system power up. Right now, I either get no signal at all or a bunch of flashing over the S-Video output. Adding a splash screen has been done before, and there is a patch floating around that adds it. But, the patch sets up the registers for the 1280x720 HDMI output, rather than the 720x482 NTSC S-Video output.

Once the kernel is decompressed into memory and begins booting, I have a splash screen pop up. I actually replace the 80x80 penguin icon in the upper left corner with a much bigger image that acts as a splash screen. That splash pops up at roughly the 5 second mark, leaving me with 5 seconds of "dead air".

A little digging brought me to something interesting. I found that in the kernel driver for the BeagleBoard video ($KERNEL_PATH/drivers/video/omap2/dss/*) there are a lot of debugfs DUMPREG() calls. By enabling debugfs in BeagleSNES's kernel (Kernel Hacking -> Debug Filesystem in the kernel configuration), I can just cat out files in the /sys/kernel/debug file structure and get a TON of register values:



This is going to save me a LOT of time.

Also, I rewrote the gamepad code to handle dynamic plugging and unplugging of controllers. I've designated specific physical USB ports for "player one" and "player two". Only gamepads plugged into these ports will be recognized by BeagleSNES. I can stat() the entries of the device files for these specific USB ports in the devfs filesystem to find out which joystick device they correlate to, and I dynamically remap joystick events according to this. Now, it doesn't matter if you add and remove controllers, plug the player two controller in first, etc. It handles it all. The overhead is minimal in the standard case (no change in the plugged in gamepads), so there isn't a noticeable performance impact. There's a 100 ms or so hiccup when you add a gamepad or remove one, though.

I also sped up the boot time of the system by about 5 seconds, along with some other system optimizations. I'm at around 30 pages of documentation and climbing. :dance:

SourceForge is telling me that I've had downloads of BeagleSNES from all over the place. Argentina, Australia, China, Colombia, Estonia, France, Indonesia, Japan, Philippines, Poland, Portugal, Switzerland, and the US. I was not expecting such a diverse audience. Yikes.

hendersa
Sep 17, 2006

BeagleSNES v0.2 is just about ready for release, and I plan on getting it packaged up and out the door this weekend. I'm also going to get that pile of documentation that I've been writing all wrapped up, too. I put together another video of the system for the upcoming release, which shows how it is running as of this evening: https://www.youtube.com/watch?v=uh0YgscO3no

hendersa
Sep 17, 2006

The BeagleSNES documentation is all typed up! Check it out. Print out a copy and keep it in the bathroom for reading. I worked hard on that thing.

EDIT: I forgot to mention that I mentioned you guys! Thanks for the help!



I had the opportunity to see BeagleSNES on an HDMI TV this weekend, and the analog signal looked awful. For my tiny video captures, I had assumed that most of the garbage in the signal was due to the capture device. Unfortunately, all of that snow, crawling, and poor color was the signal itself. So, I made the command decision to rework the registers a bit and configure the system to push everything out over the HDMI connector as a DVI signal. It took me about four hours to switch the configuration in the kernel and bootloader, and then another three to four hours to get the game selection menu and emulator adapted for the new video output.

The difference was incredible. It looks nice. I mean, I know a digital signal is going to be sharper than an analog one, but having all of the garbage removed from the signal makes a world of difference.

Analog:


Look at all the garbage in that signal. And all that noise moves around the screen, too.

Digital:


This is taken with the camera, and is not a screen capture in software. That is how much cleaner the signal is. The colors are also not anywhere near as washed out as they are in the analog signal.


The whole system with the new digital output.

As an added bonus, the video encoder (VENC) kernel driver (for analog output) is slower than the LCD kernel driver (for digital output), so performance has increased a few FPS. That's enough for me to add in a smoothing 2x2 scaling filter, rather than the raw 2x1 block filter that I has before. I don't get NTSC overscan on the digital signal, but the resolution I am now using is smaller than the old one. It used to be 720x482 at 30Hz for analog, but now it is 640x480 at 60 Hz for digital. I had to tighten up the game selection menu a bit for the smaller resolution, but it was certainly worth it.

I was also surprised to see on the BeagleBoard-xM product page that BeagleSNES was one of the three highlighted projects listed in the "BeagleBoard-xM Projects" area. :toot:

hendersa fucked around with this message at 01:22 on Apr 23, 2013

hendersa
Sep 17, 2006

BeagleSNES v0.2 escaped into the wild this evening. These software releases are going to kill me.

Here is the latest and greatest trailer that shows off its new digital video support: https://www.youtube.com/watch?v=QzwZX1AFjIU

I think that right now is a great time for me to curl up on the floor and sleep for about a day-and-a-half.

hendersa
Sep 17, 2006

After I released v0.2 of BeagleSNES for the BeagleBoard-xM, I figured that would be the end of it. I did a demo of my project for my final project report in the graduate class that I originally made BeagleSNES for, and that went well. Students passing by the lab heard the sounds of F-Zero leaking out into the hallway, so there were a lot of heads poking in during the demo.

There were a few extra faces in the lab during the demo, but I just figured that they were faculty that were invited to view the various final project demos. I guess one of them was a representative from Texas Instruments, and my professor had invited him to view my demo in particular and use it as an example of why TI should donate more BeagleBoard hardware to the university. Hopefully, this project will pay off for the university, too!

Anyway, I stuck a PayPal donation button on the BeagleSNES webpage because that is what all of these other open-source projects do. I never would have expected it, but people actually DO donate:



So, with donation money in hand, I purchased a BeagleBone Black with the intention of getting BeagleSNES running on it. It isn't as mature as the BB-xM, so I'm running into kernel bugs here and there: https://www.youtube.com/watch?v=JZEn6VOoGuc. I'm doing my best to communicate these issues back to TI, along with my findings, so hopefully we can get the kernel stabilized and I can get the entire BeagleSNES system up and running. On the bright side, the BeagleSNES code itself (GUI and emulator) appear to work just fine with only a few minimal changes. It runs much nicer on the 1GHz BBB than on the 800 MHz BB-xM, so that's a plus. Still a touch too slow for Star Fox, though. :(

hendersa
Sep 17, 2006

Bahama.Llama posted:

Helping out your university community in addition to anyone who wants to get involved is awesome... but maybe this rep can persuade someone who makes hiring decisions.

Well, I am a PhD student, so I still have a few years to go until I worry about that sort of thing. But, if I can get TI to look more closely at hiring some of the masters students here at the university, that would be very nice!

So anyway, check this out:



That's BeagleSNES running on the $45 BeagleBone Black! I suspect that these boards will be everywhere fairly soon, since the closest alternative is the Raspberry Pi at $35 (which is way less powerful). The BeagleBoard-xM is a nice platform, but it costs about $150 (and is ALSO less powerful). The BeagleBone Black is also tiny. It is smaller than the gamepad and it could literally fit inside of an SNES catridge. Maybe I should track down a 3-D printer and make a tiny SNES shell for it?

$45 for the board, $10 for the USB gamepad, $10 for the microHDMI-to-HDMI cable, and $15 for the power supply. Plug it into your HDMI TV and you've got a makeshift SNES you can use to play ROMs in your living room with a gamepad for $80. Not too shabby!

I'm getting video and audio over HDMI now that I have that kernel bug all sorted out. Turns out that my HDMI signal flickering was due to a problem with how the AVI InfoFrames were formed by the HDMI framing chip. It sent out bad data, which was causing the loss of signal sync when it reached my HDMI video capture device. :science:

There are still some kernel bugs to be worked out (640x480 video mode is valid, but SDL won't initialize with it, USB hotplug doesn't work, etc.), but it is actually playable now. I'll keep working with TI to get these other issues sorted out, and then I'll get another BeagleSNES release out once everything is a bit more solid.

hendersa
Sep 17, 2006


Nixie tubes are awesome. And they aren't that expensive, if you can find someone to sell you some.

I worked around a nasty problem for my BeagleBone Black port of BeagleSNES. Due to the implementation of USB support in the Linux kernel for the BBB, hotplugged USB devices won't work. That means that if you unplug a gamepad, it won't be recognized when you plug it back in. The USB port goes "dead" at that point. Luckily, after picking through the BBB-specific kernel patches and the kernel source, I found a workaround!

https://www.youtube.com/watch?v=Jf8twsuxXBc

I can force a USB bus rescan and "bring it back alive" using some trickery from userspace. And it works! It's clunky, but it gets the job done. I can plug and unplug my USB gamepad all day long now.

hendersa
Sep 17, 2006

I finally managed to get a new release of BeagleSNES out. This one has full support for the BeagleBone Black in it. A gentleman from TI was speaking with me about my work via e-mail and asking me for assistance because he was tinkering around with my previously released work and trying to get it built on the BeagleBone Black. I took that as an indication that I needed to hurry up and get a new release out. Here is the trailer video that shows off the system:

https://www.youtube.com/watch?v=iuwP4Nd26C4

I forget who asked me if Plok! ran under BeagleSNES, so I tracked the game down and used it in the trailer. The answer to the question is "it works really well!"

hendersa
Sep 17, 2006

I took a picture of my BeagleBone Black running BeagleSNES next to an actual SNES cartridge and the gamepad.



One of these days, I need to cram that board inside of an SNES cartridge casing and print up an awesome label for it...

hendersa
Sep 17, 2006

One of these days, I'm going to get back to making stuff that can actually be shown on a screen for a screenshot!



Since I have spent so much time working with the BeagleBone Black, I decided to run with it for my FPGA work. All of the FPGA cape boards are still in the beta/prototyping stage and aren't yet available for sale, so I decided to take an existing FPGA prototype board and interface that with the BBB as a sort of cape. It is my hope that I can use the BBB's SPI interface through the expansion header to communicate with the secondary FPGA board so that I can build a custom co-processor to crunch numbers or emulate an NES. Any data (data buffers, graphics, audio data, etc.) can be passed back over SPI to the BBB, where I can either bit-bang it into userspace for display or create a nice interrupt-driven kernel driver to pull the data over SPI without eating up CPU while polling.

Over at opencores.org there is a nice SPI master/slave VHDL core that I can drop into my FPGA design to handle the interfacing with the BBB. My FPGA board is a XuLA-200, which takes care of most of the glue circuitry that I need between the BBB and my FPGA. The 7-segment LED is just for debugging purposes.

The footprint of that setup is about the same as two credit cards side-by-side.

hendersa
Sep 17, 2006

I just pushed out another release of BeagleSNES. Among other things, it now supports:



... two gamepads for the BeagleBone Black. This might not seem like a big deal, but there are actually a family of community kernel patches that I needed to apply in order to support recovery from voltage noise from external hubs ("babble"), USB device discovery and enumeration, and hot-plugging. It wouldn't be a new release without a video, so here you go:

https://www.youtube.com/watch?v=RMdrskg66bQ

I also took a gamble and started BeagleSNES as the init process for the kernel. That shaves about 8-9 seconds off of the system boot time, but it also makes the system completely dependent on that process. The init process never terminates, so if BeagleSNES quits, the kernel panics. But hey... it boots fast, so that's good, right?

Lumpy was kind enough to assist me by whipping up a scrollbar thumb that I now use in the game selection menu. Now you can throw as many titles in there as you like.

Adbot
ADBOT LOVES YOU

hendersa
Sep 17, 2006

Salvador Dalvik posted:

Good stuff. Any chance of scanning the ROM folder for entries and falling back to the filename if game-list entry doesn't exist for a ROM? It's annoying to create an entry for every game, especially since I don't care about the date/genre/ect.

Those microSD cards are slow, slow, slow, so I avoid doing file system scans like that. What I should really be doing is making it even worse: make the end users place the ROMs and box images into a cramfs loop file and then mount the thing to pull everything out. That way, a scan like that will go much faster, since you're looking through the index of the file in memory, rather than hitting the disk over and over. Plus, you're pulling far less data off of the disk because it is compressed. But, I think that what I'll eventually end up doing is make a desktop app that builds the games.cfg and an archive file like that for you. Then you just drop the generated files into your system and be done with it.

quote:

Otherwise it's been working fine for me, and the documentation on your site is incredibly detailed.

Thanks! The documentation is about a version and a half behind at the moment, so I need to get it up to date. It is my hope that my docs will help out some other developers that are working on single-purpose multimedia apps like this. There isn't a whole lot of easy-to-understand docs out there for these platforms, and not everyone is up to picking through code to figure out what is going on, so I do what I can to help other devs out.

I received a mail earlier this morning from a fellow over at Texas Instruments. TI will be using BeagleSNES for a "large demo event" next Thursday:

The TI guy posted:

Also, just for your entertainment, I will have this running on a 46" LCD (capable of touch, but no use with SNES :) ) and got it to stretch to the full resolution. I'll send some pictures of the setup next week!

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply