Reverse engineering the Sony VGP-XL1B DVD-ROM Media Changer

A couple years ago a bought this 200 disc Firewire media changer from eBay. I wanted to see if I could replace the DVD-ROM drive with a Blu-Ray one. I then proceeded to not touch it for a while, but recently I spent a few weeks diving into the internals of the device. This page details the experience, including the protocol between the Firewire controller and media changer board.

This changer is based on the PowerFile C200 which debuted way back in 1997. I believe that PowerFile was acquired by Hitachi Data Systems, but I could be wrong about that. The internals are fairly modular. You have a Firewire controller board, media changer controller board, an IDE DVD-ROM drive, 200 disc carousel, and robotics to control disc insertion and access.

Firewire controller board

The Firewire controller is Oxford Semiconductor FW911ATAPI-TQAG. The datasheet is here. The change is controlled using SCSI commands over the SBP-2 protocol on top of Firewire. The target presents 2 LUNs, one for the DVD-ROM drive and the other for the media changer. It will not start unless the IDE drive is connected and powered on. The power is delivered by the changer, the power pins on the Firewire ports aren't connected. I found a company that claims to have devised the firmware for this device here. I'd love to have the source for the firmware!!

Media changer board

This board has a Innovasic IA188ES which is a long term Am188ES replacement. This chip is the media changer SCSI controller. The board also has a Phillips 89C51RD2 chip. I believe this 8051 processor controls the carousel and insert/eject mechanism. The 188 has a battery backed SRAM which I think stores which slots are in use.

Reversing the protocol

As you can see in the picture there are 8 wires between the two boards. I purchased a Digilent Digital Discovery logic analyzer to determine what the purpose of these are. I wanted to figure out how the Firewire controller communicates with the media changer board. Turns out it is just a TTL serial at 38400 baud. I put on a TTL to RS-232 converter and I was in business.

Unfortunately I didn't capture a picture of the setup. However, I did take notes. I used the mtx tool to drive the changer and HTerm to capture the serial communication. I took two screen captures of the communication from the OXFW911 to the IA188ES. Screenshot 1 and Screenshot 2.

The protocol is fairly simple. In the incoming direction (OXFW911 to 188) there is a header, SCSI CDB, and checksum. Displayed in hex:

Header                   SCSI CDB                 Checksum
001500184B040084DCA25600 120000003800000000000000 E1

In the outgoing direction (188 to OXFW911) it's split into SCSI response or status, checksum, and footer:

Data response:

Size   SCSI Response                                                              Checksum Footer
802400 08000302A8000000536F6E79202020205641494F4368616E676572312020202030313030   24       8504000000000076
802500 08000302A8000000536F6E79202020205641494F4368616E67657231202020203031303000 23       8504000000000076

Status response:

Size   Status Key/ASC/ASCQ Checksum
850400 02     052000       4F

To determine the checksum, I searched around for awhile stumbling on RevEng. That reported no matches. Then I tried many other 8-bit CRCs with online calculators but none of them matched up. I found a page describing that XOR and Twos Complement are possible "checksums". I had tried INQUIRY with incrementing length and noticed that the checksum was just simply incrementing leading me to believe it is not any 8-bit CRC. I tried a few XOR, sum, Twos complement options and was lead to 'sum all bytes' from this StackExchange answer. I continued to prototype in C ending with the solution:

int main()
{
    const signed char raw[] = {
        0x80,0x24,0x00, // Size
        0x08,0x00,0x03,0x02,0xA8,0x00, // SCSI Response
        0x00,0x00,0x53,0x6F,0x6E,0x79,
        0x20,0x20,0x20,0x20,0x56,0x41,
        0x49,0x4F,0x43,0x68,0x61,0x6E,
        0x67,0x65,0x72,0x31,0x20,0x20,
        0x20,0x20,0x30,0x31,0x30,0x30};
    signed char checksum = 0;
    for (int i = 0; i < sizeof(raw); i++) {
        checksum += raw[i]; // Sum of the bytes
    }
    printf("result: %x", (~checksum)); // 1's compliment
    return 0;
}

The resulting "algorithm" is the sum of the bytes, 1's compliment.

Continue to my attempt at a SATA replacement controller board...