Interfacing with Sony's VGP-XL1B 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 chip is Oxford Semiconductor FW911ATAPI-TQAG. The datasheet is here. The changer is controlled using SCSI commands over the SBP-2 protocol. 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 developed the firmware for this device here. I'd love to get my hands on the firmware source code!!

Media changer board

This board contains the robotics controller and CPU. It is connected to the FireWire controller board via a simple serial protocol. The main CPU chip is a Innovasic IA188ES which is a long term Am188ES (AMD 80C186/188) replacement. This chip receives the SCSI commands from the FireWire controller chip over a simple serial protocol. It also has battery backed SRAM to keep track of the carousel slot status. The robotics are likely controlled by an 8051 Phillips 89C51RD2 chip.

Determining the protocol between the two boards

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.

The protocol is fairly simple. SCSI requests are sent from OXFW911 to 188ES with a custom header, SCSI CDB, and checksum. Displayed in hex:

Header                   SCSI CDB                 Checksum
  001500184B040084DCA25600 120000003800000000000000 E1

The response (188ES to OXFW911) is 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 the program 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.


< Back home