The QNX Dreamcast Project

When I first heard about the utter hackability of the Sega Dreamcast, it immediately became a geek fantasy of mine to see QNX running on it. (Cool things running on odd platforms is an obsession of mine, for example, not too long before I tackled this, I ported robotfindskitten to the Commodore 64 and Apple II.) So I managed to track down and buy a Dreamcast. Several months later, I even went so far as to purchase a serial cable, so that I could transfer programs to it without burning CDs. Finally, one day I brought it up to my boss, Rick Duff, that I'd always wanted to see QNX running on this Dreamcast. And the rest is history. Yet to be written.

Sat, September 20, 2003: I am typing this entry with my Dreamcast keyboard!

There is still a small problem wherein my mouse and keyboard drivers don't seem to want to coexist, but I'm sure it's quite simple to fix. I decided that rather than tackle that problem, I would make the keyboard driver work. And at the moment, it works near-flawlessly. Repeat isn't simulated, so I have to hit backspace a bunch of times if I want to delete something, etc. Also, I'm having some funny problems with the arrow keys in this terminal window which I don't quite understand. (The keypad arrows work great, though..)

Once I fix the bug in my maple framework and can use the mouse and keyboard simultaneously, I will be able to use QNX on the Dreamcast without requiring a serial connection. (I still require my laptop to be running and online so that I can run everything over QNET -- that won't change until I write a GD-ROM driver.) A very exciting development indeed!

Someone sent me an email asking if I've got a mailing list set up so that they could be notified when this page was updated. Well, I don't, but if there's some demand, I'll set one up. Send me an email if you're interested in being notified of updates to this page.

Wed, September 17, 2003: Well, it's been over a year since I first saw success putting QNX on the Dreamcast, and the project continues to march on. I've spent a fair bit of time developing a really cool library for creating simple resource managers in QNX, with a straightforward API and directory support "for free". Originally I had intended to use this so that I could write Photon input drivers which talked to /dev/maple/port0/mouse; that sort of thing. Then I realized a way in which my maple-communication framework and Photon drivers could co-exist nicely. All the effort was not wasted; eventually I will use it for the VMU filesystem, as well as any other QNX project which requires a filesystem.

As a first test of my Maple framework, I have a mouse driver which works nicely. Check out this screenshot of me browsing the Boob! forums. It's such a nice feeling to finally be able to interact directly with my Dreamcast, rather than over a serial port. I'm sorely missing my keyboard, so I imagine that'll be next. I'm still debating on how best to utilize the Dreamcast controller; I'm imagining the analogue stick as a mouse, and the ability to map keypresses to various buttons, but efficient keyboard-like input is an interesting problem. I want something sort of like Palm's Graffiti -- something with a bit of a learning curve, but fast enough that you can reasonably use it for pretty much everything once you've learned it. If anyone has any suggestions (or already-proven methods), please toss me an email and let me know!

Fri, June 6, 2003: Figured out why Voyager wasn't looking up domain names -- it uses pipes, and I wasn't running "pipe". Here's an updated blurry screenshot of the Dreamcast browsing my favourite DC news site, taken with a crappy webcam, as the nice digital camera I used for the previous screenshots went with Rick to the lake =]

I'm beginning work on a Maple driver for input. It's annoying that I seem to have to poll my devices, but at least with the DMA features, I can keep it to a minimum. (After all, what's the difference between a timer interrupt going off at 60hz and the mouse interrupting you 60 times a second?) It's the keyboard I'm really worried about, since I've had problems in some DC programs with it not polling fast enough for my 80wpm typing. But I guess the bus really wasn't designed with a keyboard in mind, and I'll have to deal with that as best as I can.

Thurs, June 5, 2003: I'm now on my third Dreamcast, but finally I've got one that works. And great news: Photon works now, too! Check out these screenshots, taken with a decent digital camera:

Memory's starting to get a little tight, especially with Voyager running. If I start Voyager in a low memory-consumption mode, I only have about 2mb of RAM free! (Then again, I'd like to see the DCLinux guys run a full-featured windowing system and a webbrowser and have 2 megs free >=]) If I accelerate the graphics driver to use video RAM more agressively (there's 8mb sitting there gathering dust), maybe use the tiny TCPIP stack.. plenty of room for optimization still. =] And I won't have to run a ramdisk once I get my CDROM stuff up -- ramdisks have a tendency to take up RAM.
Thurs, May 29, 2003: Setback! The replacement Dreamcast I purchased from eBay is broken. Stupid me bought the thing as-is. It's really discouraging to still not be able to test my Photon driver that I wrote last November.

I've been sort of tinkering with a CD-ROM driver, but QNX's block filesystem code isn't documented or even generally distributed. I've read that the GD-ROM interface is actually IDE, and so I've been reading up on ATA/ATAPI a bit to see if I can use QNX's existing IDE driver somehow, but I'm not sure that the registers are the same as what QNX's driver expects. It almost seems like it's poking the registers to its satisfaction, but isn't getting an interrupt; it takes a while to timeout when I give it the proper register address. But it could simply be that it's sending it weird messages that the GD-ROM simply isn't equipped to understand. Hard to say, without the source.

Anyway, I should be picking up yet another replacement Dreamcast right away (one that works, this time) and showing you some nifty Photon screenshots very soon.

Fri, May 16, 2003: Success!

[the Dreamcast talking over the network]

Here we can clearly see the Dreamcast wandering around my laptop's filesystem over QNET, and pinging There was a strange problem where I couldn't talk to my Dreamcast over QNET, but apparently that's because QNET acts weird with alignment fault emulation. Building a new boot script that disabled that fixed the problem. You'll also see that I'm using Rob Krten's ramdisk filesystem; it's been absolutely invaluable. My alternative was to shove everything into /dev/shmem, and since io-net expects to find drivers in /lib/dll, that would have been a problem. =]

The ASIC interrupt problem was solved, with much help from CyRUS64, who has done a great deal of reverse engineering of the Dreamcast for his Dreamcast emulator, Icarus. I didn't realize how sparse documentation for the Dreamcast hardware was until I took this on; thankfully, there are still some knowledgable individuals who'll take the time to help out.

I think I'm going to go collapse, now. It's been two solid weeks of work, but it's finally up and running. =]

Tues, May 13, 2003: After taking a fairly long hiatus, I've been back to working steadily on my Dreamcast. I've written a driver for my Broadband Adapter which appears to be close to functional -- it grabs the MAC address, in any case. However, over the past week, I've been running into a lot of problems with the interrupts on the Dreamcast. It seems like the standard kernel callouts aren't properly masking interrupts, and so when I enable the BBA interrupt, I almost immediately get some sort of data, and the Dreamcast hangs. (If I attach a handler instead of using InterruptAttachEvent, it kernel panics!) If there's anyone out there with knowledge about the masking of ASIC interrupts (both individual ASIC events, if it's possible, and the external IRL interrupts), please come and deliver me from more trudging through the SH-4 docs, and KOS/NetBSD code.

My Dreamcast has also recently decided not to output a video signal anymore, so I'm hoping to score a replacement for cheap from eBay. This doesn't hold up BBA production, but once that's up and going, Photon is next. Also, I miss my Jet Grind Radio. =]

Sun, Nov. 10, 2002: It's been awhile since I've had a chance to work on this stuff, but I've finally got a bit of progress to report once again. I've taken Marcus Comstedt's sample video code, converted it from SH4 assembly into straight C, stripped out the text routines, and managed to get the whole contraption to run as root under QNX! Here's a "screenshot" taken by a crappy webcam:

What this means is that a Photon graphics driver is not far behind! (I have, in fact, already begun work on making a simple, unaccelerated driver based on this code; the trick is getting a working Photon environment to test it on.)

I've been playing with Marcus' "Hello, world" example for some time, but I was trying to use it in its assembly-language form. As the assembly code accesses memory directly, I had to do some serious kludging to wedge in the proper mmap_device_memory calls. This was generally unsuccessful, results ranging from no video output to segment violations to even kernel panics! (I'd certainly never seen a QNX kernel panic before -- I assume this is due to an undiscovered bug in my startup-dc program.) Once I decided to convert it into C code, it only took a few hours of work to get it up and running.

Monday, Sept. 9, 2002: A few of you have been curious as to how fast the Dreamcast can crunch keys. This is probably because it's the only concrete thing that the Dreamcast has managed to do under QNX. Here are the results of dnetc -benchmark:

RC5 (Generic RC5 core): 14,131 keys/sec
OGR (GARSP 5.13): 367,425 nodes/sec

Just for reference, my K6/2 350MhZ desktop PC (although to be fair, the Dreamcast is only 200MhZ) scored:

RC5 (RG RISC-rotate II): 572,788 keys/sec
OGR (GARSP 5.13-A): 1,538,279 nodes/sec

Also, to be fair, I don't think there is an SH4 assembly core, so it'd be dealing with the unoptimized ANSI C core.

Nothing more to report; school started last week, my girlfriend got back in town last week, and one of our customers is in town this week, so forgive me if progress is slow. A broadband adapter is supposedly in the mail, meaning, of course, that it may soon be feasable to have network up and running under QNX.

Tuesday, Sept. 3, 2002: I have successfully gotten QNX to boot on the Dreamcast, and pipe a shell over the serial port. I've even gone so far as putting lrz on it, and sending files over it via zmodem (for example, I'm currently running the Neutrino client on it).

Here is a pretty screenshot:

You may notice from the output of "pidin in" that the boot time is the UNIX epoch. This is because the Dreamcast doesn't use a standard SH4 realtime clock, and I have yet to write the code to use the RTC actually in the Dreamcast.

I'm currently using Marcus Comstedt's Serial upload slave to send the images over the serial port, as porting the dcload-serial client, which allows for such things as compression and "not sending the data using the bloated SREC format", to QNX proved difficult. Burning this image to a CD should prove trivial, as the Dreamcast BIOS should load the QNX image automatically. Hooray for not having to write an IPL!

In fact, the job was actually fairly easy. Despite having never done anything like this before, I found QNX's BSP stuff to be quite easy to work with. Basically, I had to take the startup- program of one of the existing SH boards (I picked the Solution Engine, as it seemed the most generic of my choices) and funge it to report where the Dreamcast maps its devices, user RAM, etc.

The hardest part of this was probably getting some semblance of debugging output working; I never managed to get the built-in serial debugging output to work! Instead, I hacked together my own "debug driver" which displayed the debugging output to the screen. This meant I got a TV in my office for a few days =] One interesting hangup I had was that when I specified where the user RAM was, my screen output a garbage character and hung. Turns out that the bios routines that I was using to get the font data were located in the first 32kb of RAM. Oops. =]

So, that's about as impressive as it gets at the moment. Now begins the ever-so-fun task of writing driver after driver =]

The QNX Dreamcast Project is maintained and basically entirely undertaken by Jeremy Penner (whose various other wacky adventures are generally chronicled here.) Fun things like "paying me to play with the Dreamcast" and "webspace in which to babble" graciously given to me by my employer, Astra Network, Inc. QNX and related stuff property of QNX Software Systems. Dreamcast is a registered trademark of Sega. Melee Island (tm) is a registered trademark of... gosh, they never explained that, did they?