6 typedef unsigned char u8;
7 typedef unsigned short u16;
8 typedef unsigned int u32;
9 #define array_size(x) (sizeof(x) / sizeof(x[0]))
12 unsigned short vendor;
13 unsigned short product;
16 { 0x03eb, 0x202a, "16MX+U Game Device" },
17 { 0x03eb, 0x202b, "32MX+U Game Device" },
18 { 0x03eb, 0x202c, "16MX+US Game Device" },
19 { 0x03eb, 0x202d, "32MX+UF Game Device" },
22 /*****************************************************************************/
24 #define CMD_ATM_READY 0x22
25 #define CMD_SEC_GET_NAME 'G' /* filename r/w */
26 #define CMD_SEC_PUT_NAME 'P'
27 #define CMD_SEC_DEVID 'L' /* read flash device ID */
28 #define CMD_SEC_ERASE 'E'
29 #define CMD_SEC_READY 'C' /* is flash ready? */
30 #define CMD_SEC_READ 'R'
33 #define CTL_DATA_BUS 0x55
34 #define CTL_ADDR_BUS 0xAA
36 #define W_COUNTER 0xA0
37 #define W_CNT_WRITE 0x01
38 #define W_CNT_READ 0x00
40 #define FILENAME_ROM0 0
41 #define FILENAME_ROM1 1
42 #define FILENAME_RAM 2
56 u8 addrb2; /* most significant */
59 u8 packets; /* 64 byte usb packets */
92 static const page_table_t p_AM29LV320DB[] =
94 { 0x000000, 0x00ffff, 0x002000 },
95 { 0x010000, 0x3fffff, 0x010000 },
96 { 0x000000, 0x000000, 0x000000 },
99 static const page_table_t p_AM29LV320DT[] =
101 { 0x000000, 0x3effff, 0x010000 },
102 { 0x3f0000, 0x3fffff, 0x002000 },
103 { 0x000000, 0x000000, 0x000000 },
106 static const page_table_t p_2x_16[] =
108 { 0x000000, 0x003fff, 0x004000 },
109 { 0x004000, 0x007fff, 0x002000 },
110 { 0x008000, 0x00ffff, 0x008000 },
111 { 0x010000, 0x1fffff, 0x010000 },
112 { 0x200000, 0x203fff, 0x004000 },
113 { 0x204000, 0x207fff, 0x002000 },
114 { 0x208000, 0x20ffff, 0x008000 },
115 { 0x210000, 0x3fffff, 0x010000 },
116 { 0x000000, 0x000000, 0x000000 },
119 /*****************************************************************************/
121 static void prepare_cmd(dev_cmd_t *dev_cmd, u8 cmd)
123 memset(dev_cmd, 0, sizeof(*dev_cmd));
125 memcpy(dev_cmd->magic, "USBC", 4);
126 dev_cmd->magic2 = 0x67; /* MySCSICommand, EXCOMMAND */
127 dev_cmd->mx_cmd = cmd;
130 static int write_data(struct usb_dev_handle *dev, void *data, int len)
132 int ret = usb_bulk_write(dev, 0x03, data, len, 2000);
134 fprintf(stderr, "failed to write:\n");
135 fprintf(stderr, "%s (%d)\n", usb_strerror(), ret);
136 } else if (ret != len)
137 printf("write_cmd: wrote only %d of %d bytes\n", ret, len);
142 static int write_cmd(struct usb_dev_handle *dev, dev_cmd_t *cmd)
144 return write_data(dev, cmd, sizeof(*cmd));
147 static int read_data(struct usb_dev_handle *dev, void *buff, int size)
149 int ret = usb_bulk_read(dev, 0x82, buff, size, 2000);
151 fprintf(stderr, "failed to read:\n");
152 fprintf(stderr, "%s (%d)\n", usb_strerror(), ret);
153 } else if (ret != size)
154 printf("read_data: read only %d of %d bytes\n", ret, size);
159 static int read_info(struct usb_dev_handle *device, u8 ctl_id, dev_info_t *info)
164 prepare_cmd(&cmd, CMD_ATM_READY);
165 cmd.dev_info.which_device = ctl_id;
166 memset(info, 0, sizeof(*info));
168 ret = write_cmd(device, &cmd);
172 ret = read_data(device, info, sizeof(*info));
179 static void printf_info(dev_info_t *info)
181 printf(" firmware version: %X.%X.%X%c\n", info->firmware_ver[0],
182 info->firmware_ver[1], info->firmware_ver[2], info->firmware_ver[3]);
183 printf(" bootloader version: %X.%X.%X%c\n", info->bootloader_ver[0],
184 info->bootloader_ver[1], info->bootloader_ver[2], info->bootloader_ver[3]);
185 info->names[sizeof(info->names) - 1] = 0;
186 printf(" device name: %s\n", info->names);
189 static void print_progress(u32 done, u32 total)
193 printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
194 printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); /* 20 */
195 printf("\b\b\b\b\b\b");
196 printf("%06x/%06x |", done, total);
199 for (i = step; i <= total; i += step)
200 printf("%c", done >= i ? '=' : '-');
201 printf("| %3d%%", done * 100 / total);
205 static int read_filename(struct usb_dev_handle *dev, char *dst, int len, u8 which)
211 prepare_cmd(&cmd, CMD_SEC_GET_NAME);
212 cmd.filename.which = which;
213 memset(buff, 0, sizeof(buff));
215 ret = write_cmd(dev, &cmd);
219 ret = read_data(dev, buff, 64);
223 strncpy(dst, buff, len);
229 static int write_filename(struct usb_dev_handle *dev, const char *fname, u8 which)
238 strncpy(buff, fname, len);
241 prepare_cmd(&cmd, CMD_SEC_PUT_NAME);
242 cmd.filename.which = which;
244 ret = write_cmd(dev, &cmd);
248 return write_data(dev, buff, len + 1);
251 static int read_w_counter(struct usb_dev_handle *dev, u32 *val)
253 dev_info_t dummy_info;
258 /* must perform dummy info read here,
259 * or else device hangs after close (firmware bug?) */
260 ret = read_info(dev, CTL_DATA_BUS, &dummy_info);
264 prepare_cmd(&cmd, CMD_ATM_READY);
265 cmd.write_cnt.cmd = W_COUNTER;
266 cmd.write_cnt.action = W_CNT_READ;
268 ret = write_cmd(dev, &cmd);
272 ret = read_data(dev, buff, sizeof(buff));
280 static int read_flash_rom_id(struct usb_dev_handle *dev, int is_second, u32 *val)
286 prepare_cmd(&cmd, CMD_SEC_DEVID);
287 cmd.rom_id.which = is_second ? 0x10 : 0;
288 cmd.rom_id.dev_id = 0;
290 ret = write_cmd(dev, &cmd);
294 ret = read_data(dev, buff, sizeof(buff));
298 *val = *(u16 *)buff << 16;
300 cmd.rom_id.dev_id = 1;
301 ret = write_cmd(dev, &cmd);
305 ret = read_data(dev, buff, sizeof(buff));
309 *val |= *(u16 *)buff;
313 static const page_table_t *get_page_table(u32 rom_id)
317 return p_AM29LV320DB;
319 return p_AM29LV320DT;
324 fprintf(stderr, "unrecognized ROM id: %08x\n", rom_id);
330 static int get_page_size(const page_table_t *table, u32 addr, u32 *size)
332 const page_table_t *t;
334 for (t = table; t->end_addr != 0; t++) {
335 if (addr >= t->start_addr && addr <= t->end_addr) {
336 *size = t->page_size;
341 if (addr == t[-1].end_addr + 1)
344 fprintf(stderr, "get_page_size: failed on addr %06x\n", addr);
348 static int erase_page(struct usb_dev_handle *dev, u32 addr)
354 prepare_cmd(&cmd, CMD_SEC_ERASE);
356 cmd.rom_rw.addrb2 = addr >> 16;
357 cmd.rom_rw.addrb1 = addr >> 8;
358 cmd.rom_rw.addrb0 = addr;
360 ret = write_cmd(dev, &cmd);
364 ret = read_data(dev, buff, sizeof(buff));
368 prepare_cmd(&cmd, CMD_SEC_READY);
369 cmd.rom_rw.addrb2 = addr >> 16;
370 cmd.rom_rw.addrb1 = addr >> 8;
371 cmd.rom_rw.addrb0 = addr;
373 for (i = 0; i < 100; i++) {
374 ret = write_cmd(dev, &cmd);
378 ret = read_data(dev, buff, sizeof(buff));
382 if (ret > 4 && buff[4] == 1)
388 printf("i = %d\n", i);
393 * - bytes must be multiple of 64
394 * - bytes must be less than 16k
395 * - must perform even number of reads (firmware bug?) */
396 static int read_rom_block(struct usb_dev_handle *dev, u32 addr, void *buffer, int bytes)
401 prepare_cmd(&cmd, CMD_SEC_READ);
402 cmd.rom_rw.addrb2 = addr >> (16 + 1);
403 cmd.rom_rw.addrb1 = addr >> (8 + 1);
404 cmd.rom_rw.addrb0 = addr >> 1;
405 cmd.rom_rw.packets = bytes / 64;
407 ret = write_cmd(dev, &cmd);
412 ret = read_data(dev, buffer, bytes);
416 fprintf(stderr, "read_rom_block warning: read only %d/%d bytes\n", ret, bytes);
421 #define READ_BLK_SIZE (0x2000) /* 8K */
423 static int read_rom(struct usb_dev_handle *dev, u32 addr, void *buffer, int bytes)
425 int total_bytes = bytes;
431 fprintf(stderr, "read_rom: can't handle odd address %06x, "
432 "LSb will be ignored\n", addr);
434 fprintf(stderr, "read_rom: byte count must be multiple of 64, "
435 "last %d bytes will not be read\n", bytes & 63);
437 printf("reading flash ROM...\n");
440 for (count = 0; bytes >= READ_BLK_SIZE; count++) {
441 print_progress(buff - (u8 *)buffer, total_bytes);
443 ret = read_rom_block(dev, addr, buff, READ_BLK_SIZE);
446 buff += READ_BLK_SIZE;
447 addr += READ_BLK_SIZE;
448 bytes -= READ_BLK_SIZE;
450 print_progress(buff - (u8 *)buffer, total_bytes);
454 ret = read_rom_block(dev, addr, buff, bytes);
456 print_progress(total_bytes, total_bytes);
460 /* work around read_rom_block() limitation 3 */
461 read_rom_block(dev, 0, dummy, sizeof(dummy));
467 static usb_dev_handle *get_device(void)
469 struct usb_dev_handle *handle;
470 struct usb_device *dev;
474 ret = usb_find_busses();
476 fprintf(stderr, "Can't find USB busses\n");
480 ret = usb_find_devices();
482 fprintf(stderr, "Can't find USB devices\n");
486 bus = usb_get_busses();
487 for (; bus; bus = bus->next)
489 for (dev = bus->devices; dev; dev = dev->next)
491 for (i = 0; i < array_size(g_devices); i++)
493 if (dev->descriptor.idVendor == g_devices[i].vendor &&
494 dev->descriptor.idProduct == g_devices[i].product)
500 fprintf(stderr, "device not found.\n");
504 printf("found %s.\n", g_devices[i].name);
506 handle = usb_open(dev);
507 if (handle == NULL) {
508 fprintf(stderr, "failed to open device:\n");
509 fprintf(stderr, "%s\n", usb_strerror());
513 ret = usb_set_configuration(handle, 1);
515 fprintf(stderr, "couldn't set configuration for /*/bus/usb/%s/%s:\n",
516 bus->dirname, dev->filename);
517 fprintf(stderr, "%s (%d)\n", usb_strerror(), ret);
521 ret = usb_claim_interface(handle, 0);
523 fprintf(stderr, "couldn't claim /*/bus/usb/%s/%s:\n",
524 bus->dirname, dev->filename);
525 fprintf(stderr, "%s (%d)\n", usb_strerror(), ret);
532 static void release_device(struct usb_dev_handle *device)
534 usb_release_interface(device, 0);
538 int main(int argc, char *argv[])
540 struct usb_dev_handle *device;
542 u32 counter, rom0_id, rom1_id;
549 device = get_device();
553 printf("data bus controller:\n");
554 ret = read_info(device, CTL_DATA_BUS, &info);
559 printf("address bus controller:\n");
560 ret = read_info(device, CTL_ADDR_BUS, &info);
565 ret = read_filename(device, fname, sizeof(fname), FILENAME_ROM0);
568 printf("ROM filename: %s\n", fname);
570 ret = read_filename(device, fname, sizeof(fname), FILENAME_RAM);
573 printf("SRAM filename: %s\n", fname);
575 ret = read_w_counter(device, &counter);
578 printf("flash writes: %u\n", counter);
580 ret = read_flash_rom_id(device, 0, &rom0_id);
583 printf("flash rom0 id: %08x\n", rom0_id);
585 ret = read_flash_rom_id(device, 1, &rom1_id);
588 printf("flash rom1 id: %08x\n", rom1_id);
590 if (rom0_id != rom1_id)
591 fprintf(stderr, "Warning: flash ROM ids differ: %08x %08x\n",
594 #define XSZ (0x400000)
596 ret = read_rom(device, 0, buff, XSZ);
600 FILE *f = fopen("dump", "wb");
601 fwrite(buff, 1, XSZ, f);
607 release_device(device);