Wednesday 31 August 2011

Neo-Geo bios project

Yet another project on the stack. My Neo-Geo is begging for some hacks. And this BIOS is a great one. The main inspiration in the Universe BIOS (or UniBIOS for short). A custom BIOS that provides awesome features like region protection bypassing. This BIOS is the probably the best available for Neo-Geo hardware, with a single problem: it's not open source. I know it's being a little picky. You can can freely download the 2.3 version firmware, and get the latest 3.0 already burned in an EEPROM for a reasonable price (25 euros). Well you begin to know me, and I just can't go the simple way. I want to develop my own open source Neo-Geo BIOS.

First step: remove the original BIOS

There are basically two technics for mounting a custom BIOS. First one is piggy back, where you basically kill the existing EPROM and solder the new one on top of it. It is meant to be easier, but as name says it: dirty as pig. I prefer the second option: remove completely the old EPROM and replace it by a socket. Any you can plug whatever you like in this socket. So that will be step one, and let's hope not the final step in case I fry the board.

Step Two: Get/Build a proper EEPROM

The Neo-Geo BIOS chip is a 1M bits (64Kx16bits) memory, operating a 5v and with 120 ns access time (TCS31024P-15). There are some trouble to find these kind of memory nowadays. Most of 64Kx16 bits memory are discontinued, you can find bigger or smaller, but hadly the exact stuff. Here comes the main part of project: building a PCB to replace the original EEPROM with two Flash chips. I checked the measurements and it should fit. I just have to figure out the proper layout.

So let's see how this will go.

Thursday 25 August 2011

PS button difficulties

Activating this PS buttons is more difficult than expected. I found different sources that claims to succesfully make this button work:
The first one is a nice project using a breakout board with an AVR to implement a USB controller for PS3 with home button enabled. The second one is another project with AVR chip, it's a controller simulator that gets its input from a serial port intead of directly checking button states. Both projects provides complete source code which is pretty nice. The third one is a thread discussion of people trying to make the button work, it gives some information of what seems required or not but gives no code whatsoever.

Everybody seems to agree the magic bytes are:
0x21, 0x26, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00
Everybody agree these bytes should be sent to the host after the HID report descriptor. But it is not clear if these bytes should be sent in the data stage of the setup request, or in a spearate transfer just after. But from what people says in the thread, it seems it should be in the data stage. But it's just speculation as I can't find any confirmation in the projects source code. For the first project, the magic bytes are sent when the hosts does a HID class request GET_REPORT (not on a standard request GET_DESCRIPTOR that actually sends the HID report descriptor). And for the second project, the bytes are defined but does not used at all.

As the only project that seems to potentially work is the first one (it actually uses the magic bytes), I tried to use the same HID report descriptor and report data structure they have, added the piece of code sending the magic bytes on GET_REPORT. But no success. I don't event get the regular button events to be catched by the host. I highly doupt the report descriptor does not correspond the actual report data strucutre, in additoin this report descriptor contains some Sony specific stuff. If they are required to make it work on PS3 i'm pretty sure it will make it fail on Mac. The PS3 never send any GET_REPORT request. Not sure if this is due to the fact I use two endpoints (ep0 for control ep1 for Interrupt) whereas the project uses juste one endpoint (ep0). I don't think so as the original PS3 controller uses three endpoints. The number of endpoint should not alter the behavior.

It is pretty unclear what are the conditions the HID report must match to work with the magic bytes and make the PS3 happy. The thread lists some requirements point, but again it's just conversational and not strictly clear (is order important? etc...). It is not clear also if a specific vendor/product ID should be used. I guess no, because I doupt Sony does a firmware update anytime a new controller construcor pops-out.

I'm going to do some more investigation with different report variations. It saw the original PS3 controller defines some Feature fields in the reports, and there features sizes are 8 bytes just like the magic bytes. May be a hint?

Tuesday 23 August 2011

USB Joystick update: It works with PS3!

It works with PS3! After all this time trying to understand what was wrong in the communication protocol (DATA bit setting etc...), I just figured out what was holding my USB Joystick project to work on PS3. And it doesn't really makes sense. Just as a reminder, I'm developing a USB Joystick to work with PS3 and PC (Mac in my case). The Joystick worked just fine on my Mac, but poorly on PS3 (see video here). Turns out the DATA bits were completely messed-up at this time (can't really tel how the Mac managed to make it work nice). I fixed all this and ended up with the joystick still working nicely on the Mac but nothing at all happening on the PS3. After some investigations I noticed the PS3 sends the following request to the device:
HID class request SET_PROTOCOL
This request is supposed to be sent to Boot devices only. But my device is not, I triple checked the descriptors and there is no subclass defined on device or interface. As stated by the USB HID standard this request is required for boot devices only, so I was invalidating the request with a good old Stall. Pretty normal, I was sticking to the specs. Then just to checking I enabled the call: just don't Stall the endpoint. And all of a sudden all just worked nice. The PS3 was accepting my data. I still can't tell whether or not it is normal for a non-boot device to have to implement this call. In fact, just after the SET_PROTOCOL, the PS3 sends a GET_PROTOCOL, I figure just to check if the setting went OK. I Stall on this GET_PROTOCOL call, but it does not seem to bother the console. In a nutshell, I'm pretty happy to have it working at last, but a bit puzzled by what I had to do for it.

Next steps:
Make Home button work. Shouldn't be too difficult there are some projects explaining how you have to send some magic data in the report to have it work.
Retrieve the controller number. I guess I'll need to use a OUT ep with some specific report to get the data from the console. Just hope the PS3 will consent to send me the info.