7 typedef unsigned char u8;
8 typedef unsigned short u16;
9 typedef unsigned int u32;
10 #define array_size(x) (sizeof(x) / sizeof(x[0]))
13 unsigned short vendor;
14 unsigned short product;
17 { 0x03eb, 0x202a, "16MX+U Game Device" },
18 { 0x03eb, 0x202b, "32MX+U Game Device" },
19 { 0x03eb, 0x202c, "16MX+US Game Device" },
20 { 0x03eb, 0x202d, "32MX+UF Game Device" },
25 #define IO_BLK_SIZE 0x2000 /* 8K */
26 #define IO_RAM_BLK_SIZE 256
28 #define CMD_ATM_READY 0x22
29 #define CMD_SEC_GET_NAME 'G' /* filename r/w */
30 #define CMD_SEC_PUT_NAME 'P'
31 #define CMD_SEC_DEVID 'L' /* read flash device ID */
32 #define CMD_SEC_ERASE 'E'
33 #define CMD_SEC_READY 'C' /* is flash ready? */
34 #define CMD_SEC_READ 'R'
35 #define CMD_SEC_WRITE 'W'
36 #define CMD_SEC_RAM_READ 'D' /* not implemented? */
37 #define CMD_SEC_RAM_WRITE 'U'
38 #define CMD_SEC_COMPAT '$' /* set RAM mode */
41 #define CTL_DATA_BUS 0x55
42 #define CTL_ADDR_BUS 0xAA
44 #define W_COUNTER 0xA0
45 #define W_CNT_WRITE 0x01
46 #define W_CNT_READ 0x00
48 #define FILENAME_ROM0 0
49 #define FILENAME_ROM1 1
50 #define FILENAME_RAM 2
52 /* windows app sets to 0x80 on init
53 * checkboxes use 0x41 0x42 0x43 (?)
54 * r,w Ram/ROM uses 0x23/0x21
56 #define C_RAM_OFF 0x41 /* RAM always off */
57 #define C_RAM_SWITCH 0x42 /* RAM switched by game */
59 #define C_RAM_TMP_OFF 0x21
60 #define C_RAM_TMP_ON 0x23
74 u8 addrb2; /* most significant (BE) */
77 u8 param; /* 64 byte usb packets for i/o */
101 u8 bootloader_ver[4];
111 static const page_table_t p_AM29LV320DB[] =
113 { 0x000000, 0x00ffff, 0x002000 },
114 { 0x010000, 0x3fffff, 0x010000 },
115 { 0x000000, 0x000000, 0x000000 },
118 static const page_table_t p_AM29LV320DT[] =
120 { 0x000000, 0x3effff, 0x010000 },
121 { 0x3f0000, 0x3fffff, 0x002000 },
122 { 0x000000, 0x000000, 0x000000 },
125 static const page_table_t p_2x_16[] =
127 { 0x000000, 0x003fff, 0x004000 },
128 { 0x004000, 0x007fff, 0x002000 },
129 { 0x008000, 0x00ffff, 0x008000 },
130 { 0x010000, 0x1fffff, 0x010000 },
131 { 0x200000, 0x203fff, 0x004000 },
132 { 0x204000, 0x207fff, 0x002000 },
133 { 0x208000, 0x20ffff, 0x008000 },
134 { 0x210000, 0x3fffff, 0x010000 },
135 { 0x000000, 0x000000, 0x000000 },
138 /*****************************************************************************/
140 static void prepare_cmd(dev_cmd_t *dev_cmd, u8 cmd)
142 memset(dev_cmd, 0, sizeof(*dev_cmd));
144 memcpy(dev_cmd->magic, "USBC", 4);
145 dev_cmd->magic2 = 0x67; /* MySCSICommand, EXCOMMAND */
146 dev_cmd->mx_cmd = cmd;
149 static int write_data(struct usb_dev_handle *dev, void *data, int len)
151 int ret = usb_bulk_write(dev, 0x03, data, len, 2000);
153 fprintf(stderr, "failed to write:\n");
154 fprintf(stderr, "%s (%d)\n", usb_strerror(), ret);
155 } else if (ret != len)
156 printf("write_cmd: wrote only %d of %d bytes\n", ret, len);
161 static int write_cmd(struct usb_dev_handle *dev, dev_cmd_t *cmd)
163 return write_data(dev, cmd, sizeof(*cmd));
166 static int read_data(struct usb_dev_handle *dev, void *buff, int size)
168 int ret = usb_bulk_read(dev, 0x82, buff, size, 2000);
170 fprintf(stderr, "failed to read:\n");
171 fprintf(stderr, "%s (%d)\n", usb_strerror(), ret);
174 else if (ret != size)
175 printf("read_data: read only %d of %d bytes\n", ret, size);
180 static int read_info(struct usb_dev_handle *device, u8 ctl_id, dev_info_t *info)
185 prepare_cmd(&cmd, CMD_ATM_READY);
186 cmd.dev_info.which_device = ctl_id;
187 memset(info, 0, sizeof(*info));
189 ret = write_cmd(device, &cmd);
193 ret = read_data(device, info, sizeof(*info));
200 static void printf_info(dev_info_t *info)
202 printf(" firmware version: %X.%X.%X%c\n", info->firmware_ver[0],
203 info->firmware_ver[1], info->firmware_ver[2], info->firmware_ver[3]);
204 printf(" bootloader version: %X.%X.%X%c\n", info->bootloader_ver[0],
205 info->bootloader_ver[1], info->bootloader_ver[2], info->bootloader_ver[3]);
206 info->names[sizeof(info->names) - 1] = 0;
207 printf(" device name: %s\n", info->names);
210 static void print_progress(u32 done, u32 total)
214 printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
215 printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); /* 20 */
216 printf("\b\b\b\b\b\b");
217 printf("%06x/%06x |", done, total);
220 for (i = step; i <= total; i += step)
221 printf("%c", done >= i ? '=' : '-');
222 printf("| %3d%%", done * 100 / total);
226 static int read_filename(struct usb_dev_handle *dev, char *dst, int len, u8 which)
232 prepare_cmd(&cmd, CMD_SEC_GET_NAME);
233 cmd.filename.which = which;
234 memset(buff, 0, sizeof(buff));
236 ret = write_cmd(dev, &cmd);
240 ret = read_data(dev, buff, 64);
244 strncpy(dst, buff, len);
250 static int write_filename(struct usb_dev_handle *dev, const char *fname, u8 which)
259 strncpy(buff, fname, len);
262 prepare_cmd(&cmd, CMD_SEC_PUT_NAME);
263 cmd.filename.which = which;
265 ret = write_cmd(dev, &cmd);
269 return write_data(dev, buff, len + 1);
272 static int read_erase_counter(struct usb_dev_handle *dev, u32 *val)
274 dev_info_t dummy_info;
279 /* must perform dummy info read here,
280 * or else device hangs after close (firmware bug?) */
281 ret = read_info(dev, CTL_DATA_BUS, &dummy_info);
285 prepare_cmd(&cmd, CMD_ATM_READY);
286 cmd.write_cnt.cmd = W_COUNTER;
287 cmd.write_cnt.action = W_CNT_READ;
289 ret = write_cmd(dev, &cmd);
293 ret = read_data(dev, buff, sizeof(buff));
301 static int read_flash_rom_id(struct usb_dev_handle *dev, int is_second, u32 *val)
307 prepare_cmd(&cmd, CMD_SEC_DEVID);
308 cmd.rom_id.which = is_second ? 0x10 : 0;
309 cmd.rom_id.dev_id = 0;
311 ret = write_cmd(dev, &cmd);
315 ret = read_data(dev, buff, sizeof(buff));
319 *val = *(u16 *)buff << 16;
321 cmd.rom_id.dev_id = 1;
322 ret = write_cmd(dev, &cmd);
326 ret = read_data(dev, buff, sizeof(buff));
330 *val |= *(u16 *)buff;
334 static const page_table_t *get_page_table(u32 rom_id)
338 return p_AM29LV320DB;
340 return p_AM29LV320DT;
345 fprintf(stderr, "unrecognized ROM id: %08x\n", rom_id);
351 static int get_page_size(const page_table_t *table, u32 addr, u32 *size)
353 const page_table_t *t;
355 for (t = table; t->end_addr != 0; t++) {
356 if (addr >= t->start_addr && addr <= t->end_addr) {
357 *size = t->page_size;
362 if (addr == t[-1].end_addr + 1)
363 return 1; /* no more */
365 fprintf(stderr, "get_page_size: failed on addr %06x\n", addr);
369 static int set_ram_mode(struct usb_dev_handle *dev, u8 mode)
375 prepare_cmd(&cmd, CMD_SEC_COMPAT);
377 cmd.mode.which = mode;
379 ret = write_cmd(dev, &cmd);
383 ret = read_data(dev, buff, sizeof(buff));
387 fprintf(stderr, "warning: failed to set RAM mode\n");
392 * - bytes must be multiple of 64
393 * - bytes must be less than 16k
394 * - must perform even number of reads, or dev hangs on exit (firmware bug?) */
395 static int rw_dev_block(struct usb_dev_handle *dev, u32 addr, void *buffer, int bytes, int mx_cmd)
400 prepare_cmd(&cmd, mx_cmd);
401 if (mx_cmd == CMD_SEC_WRITE || mx_cmd == CMD_SEC_RAM_WRITE)
403 cmd.rom_rw.addrb2 = addr >> (16 + 1);
404 cmd.rom_rw.addrb1 = addr >> (8 + 1);
405 cmd.rom_rw.addrb0 = addr >> 1;
406 cmd.rom_rw.param = bytes / 64;
407 if (mx_cmd == CMD_SEC_WRITE || mx_cmd == CMD_SEC_RAM_WRITE)
408 cmd.rom_rw.param2 = 1; /* ? */
410 ret = write_cmd(dev, &cmd);
416 if (mx_cmd == CMD_SEC_WRITE || mx_cmd == CMD_SEC_RAM_WRITE)
417 ret = write_data(dev, buffer, bytes);
419 ret = read_data(dev, buffer, bytes);
424 fprintf(stderr, "rw_dev_block warning: done only %d/%d bytes\n", ret, bytes);
429 static int read_write_rom(struct usb_dev_handle *dev, u32 addr, void *buffer, int bytes, int is_write)
431 int mx_cmd = is_write ? CMD_SEC_WRITE : CMD_SEC_READ;
432 int total_bytes = bytes;
438 fprintf(stderr, "read_write_rom: can't handle odd address %06x, "
439 "LSb will be ignored\n", addr);
441 fprintf(stderr, "read_write_rom: byte count must be multiple of 64, "
442 "last %d bytes will not be handled\n", bytes & 63);
444 set_ram_mode(dev, C_RAM_TMP_OFF);
446 printf("%s flash ROM...\n", is_write ? "writing to" : "reading");
448 /* do i/o in blocks */
449 for (count = 0; bytes >= IO_BLK_SIZE; count++) {
450 print_progress(buff - (u8 *)buffer, total_bytes);
452 ret = rw_dev_block(dev, addr, buff, IO_BLK_SIZE, mx_cmd);
457 bytes -= IO_BLK_SIZE;
459 print_progress(buff - (u8 *)buffer, total_bytes);
463 ret = rw_dev_block(dev, addr, buff, bytes, mx_cmd);
465 print_progress(total_bytes, total_bytes);
469 /* work around rw_dev_block() limitation 3 (works for reads only?) */
470 rw_dev_block(dev, 0, dummy, sizeof(dummy), 0);
476 static int read_write_ram(struct usb_dev_handle *dev, void *buffer, int bytes, int is_write)
478 int mx_cmd = is_write ? CMD_SEC_RAM_WRITE : CMD_SEC_READ;
479 int total_bytes = bytes;
484 if (bytes % IO_RAM_BLK_SIZE)
485 fprintf(stderr, "read_write_ram: byte count must be multiple of %d, "
486 "last %d bytes will not be handled\n", IO_RAM_BLK_SIZE,
487 bytes % IO_RAM_BLK_SIZE);
489 set_ram_mode(dev, C_RAM_TMP_ON);
491 printf("%s RAM...\n", is_write ? "writing to" : "reading");
493 /* do i/o in blocks */
494 while (bytes >= IO_RAM_BLK_SIZE) {
495 print_progress(buff - (u8 *)buffer, total_bytes);
497 ret = rw_dev_block(dev, addr, buff, IO_RAM_BLK_SIZE, mx_cmd);
500 buff += IO_RAM_BLK_SIZE;
501 addr += IO_RAM_BLK_SIZE;
502 bytes -= IO_RAM_BLK_SIZE;
504 print_progress(buff - (u8 *)buffer, total_bytes);
506 /* only D0-D7 connected.. */
507 for (i = 0; i < total_bytes; i += 2)
508 ((u8 *)buffer)[i] = 0;
515 static int increment_erase_cnt(struct usb_dev_handle *dev)
522 ret = read_erase_counter(dev, &cnt);
526 if (cnt == (u32)-1) {
527 fprintf(stderr, "flash erase counter maxed out!\n");
528 fprintf(stderr, "(wow, did you really erase so many times?)\n");
534 prepare_cmd(&cmd, CMD_ATM_READY);
535 cmd.write_cnt.cmd = W_COUNTER;
536 cmd.write_cnt.action = W_CNT_WRITE;
537 cmd.write_cnt.b3 = cnt >> 24;
538 cmd.write_cnt.b2 = cnt >> 16;
539 cmd.write_cnt.b1 = cnt >> 8;
540 cmd.write_cnt.b0 = cnt;
542 ret = write_cmd(dev, &cmd);
546 ret = read_data(dev, buff, sizeof(buff));
553 static int erase_page(struct usb_dev_handle *dev, u32 addr, int whole)
559 prepare_cmd(&cmd, CMD_SEC_ERASE);
561 cmd.rom_rw.addrb2 = addr >> (16 + 1);
562 cmd.rom_rw.addrb1 = addr >> (8 + 1);
563 cmd.rom_rw.addrb0 = addr >> 1;
564 cmd.rom_rw.param = whole ? 0x10 : 0;
566 ret = write_cmd(dev, &cmd);
570 ret = read_data(dev, buff, sizeof(buff));
574 prepare_cmd(&cmd, CMD_SEC_READY);
575 cmd.rom_rw.addrb2 = addr >> (16 + 1);
576 cmd.rom_rw.addrb1 = addr >> (8 + 1);
577 cmd.rom_rw.addrb0 = addr >> 1;
579 for (i = 0; i < 100; i++) {
580 ret = write_cmd(dev, &cmd);
584 ret = read_data(dev, buff, sizeof(buff));
588 if (ret > 4 && buff[4] == 1)
591 usleep((whole ? 600 : 20) * 1000);
595 fprintf(stderr, "\ntimeout waiting for erase to complete\n");
602 static int erase_seq(struct usb_dev_handle *dev, u32 size)
604 const page_table_t *table;
605 u32 addr, page_size = 0;
606 u32 rom0_id, rom1_id;
609 ret = read_flash_rom_id(dev, 0, &rom0_id);
613 ret = read_flash_rom_id(dev, 1, &rom1_id);
617 if (rom0_id != rom1_id)
618 fprintf(stderr, "Warning: flash ROM ids differ: %08x %08x\n",
621 table = get_page_table(rom0_id);
625 ret = increment_erase_cnt(dev);
627 fprintf(stderr, "warning: coun't increase erase counter\n");
629 printf("erasing flash... (erase count=%u)\n", ret);
631 for (addr = 0, count = 0; addr < size; addr += page_size, count++) {
632 print_progress(addr, size);
634 ret = erase_page(dev, addr, 0);
638 ret = get_page_size(table, addr, &page_size);
645 /* must submit even number of erase commands (fw bug?) */
646 erase_page(dev, 0, 0);
648 print_progress(addr, size);
654 static int erase_all(struct usb_dev_handle *dev, u32 size)
658 ret = increment_erase_cnt(dev);
660 fprintf(stderr, "warning: couldn't increase erase counter\n");
662 printf("erasing flash0, count=%u ...", ret);
665 ret = erase_page(dev, 0xaaa, 1);
669 if (size > 0x200000) {
671 printf("erasing flash1...");
674 ret = erase_page(dev, 0x200aaa, 1);
681 static int print_device_info(struct usb_dev_handle *dev)
683 u32 counter, rom0_id, rom1_id;
687 printf("data bus controller:\n");
688 ret = read_info(dev, CTL_DATA_BUS, &info);
693 printf("address bus controller:\n");
694 ret = read_info(dev, CTL_ADDR_BUS, &info);
699 ret = read_erase_counter(dev, &counter);
702 printf("flash erase count: %u\n", counter);
704 ret = read_flash_rom_id(dev, 0, &rom0_id);
707 printf("flash rom0 id: %08x\n", rom0_id);
709 ret = read_flash_rom_id(dev, 1, &rom1_id);
712 printf("flash rom1 id: %08x\n", rom1_id);
717 static int print_game_info(struct usb_dev_handle *dev)
722 ret = read_filename(dev, fname, sizeof(fname), FILENAME_ROM0);
725 printf("ROM filename: %s\n", fname);
727 ret = read_filename(dev, fname, sizeof(fname), FILENAME_RAM);
730 printf("SRAM filename: %s\n", fname);
735 static int read_file(const char *fname, void **buff_out, int *size, int limit)
741 file = fopen(fname, "rb");
743 fprintf(stderr, "can't open file: %s\n", fname);
747 fseek(file, 0, SEEK_END);
748 file_size = ftell(file);
749 fseek(file, 0, SEEK_SET);
750 if (file_size > limit)
751 fprintf(stderr, "warning: input file \"%s\" too large\n", fname);
753 fprintf(stderr, "bad/empty file: %s\n", fname);
757 data = malloc(file_size);
759 fprintf(stderr, "low memory\n");
763 ret = fread(data, 1, file_size, file);
764 if (ret != file_size) {
765 fprintf(stderr, "failed to read file: %s", fname);
780 static int write_file(const char *fname, void *buff, int size)
785 file = fopen(fname, "wb");
787 fprintf(stderr, "can't open for writing: %s\n", fname);
791 ret = fwrite(buff, 1, size, file);
793 fprintf(stderr, "write failed to %s", fname);
796 printf("saved to \"%s\".\n", fname);
802 static usb_dev_handle *get_device(void)
804 struct usb_dev_handle *handle;
805 struct usb_device *dev;
809 ret = usb_find_busses();
811 fprintf(stderr, "Can't find USB busses\n");
815 ret = usb_find_devices();
817 fprintf(stderr, "Can't find USB devices\n");
821 bus = usb_get_busses();
822 for (; bus; bus = bus->next)
824 for (dev = bus->devices; dev; dev = dev->next)
826 for (i = 0; i < array_size(g_devices); i++)
828 if (dev->descriptor.idVendor == g_devices[i].vendor &&
829 dev->descriptor.idProduct == g_devices[i].product)
835 fprintf(stderr, "device not found.\n");
839 printf("found %s.\n", g_devices[i].name);
841 handle = usb_open(dev);
842 if (handle == NULL) {
843 fprintf(stderr, "failed to open device:\n");
844 fprintf(stderr, "%s\n", usb_strerror());
848 ret = usb_set_configuration(handle, 1);
850 fprintf(stderr, "couldn't set configuration for /*/bus/usb/%s/%s:\n",
851 bus->dirname, dev->filename);
852 fprintf(stderr, "%s (%d)\n", usb_strerror(), ret);
856 ret = usb_claim_interface(handle, 0);
858 fprintf(stderr, "couldn't claim /*/bus/usb/%s/%s:\n",
859 bus->dirname, dev->filename);
860 fprintf(stderr, "%s (%d)\n", usb_strerror(), ret);
867 static void release_device(struct usb_dev_handle *device)
869 usb_release_interface(device, 0);
873 static void usage(const char *app_name)
875 printf("Flasher tool for MX game devices\n"
876 "written by Grazvydas \"notaz\" Ignotas\n");
877 printf("v" VERSION " (" __DATE__ ")\n\n");
879 "%s [-i] [-g] [-e] [-r [file]] [-w <file>] ...\n"
880 " -i print some info about connected device\n"
881 " -g print some info about game ROM inside device\n"
882 " -e[1] erase whole flash ROM in device, '1' uses different erase method\n"
883 " -f skip file check\n"
884 " -r [file] copy game image from device to file; can autodetect filename\n"
885 " -w <file> write file to device; also does erase\n"
886 " -sr [file] read save RAM to file\n"
887 " -sw <file> write save RAM file to device\n"
888 " -sc clear save RAM\n"
889 " -sm[1-3] set save RAM mode: off, special (>2M games + save), on\n"
890 " -v with -w or -sw: verify written file\n",
894 int main(int argc, char *argv[])
896 char *r_fname = NULL, *w_fname = NULL, *sr_fname = NULL, *sw_fname = NULL;
897 void *r_fdata = NULL, *w_fdata = NULL, *sr_fdata = NULL, *sw_fdata = NULL;
898 int do_read_ram = 0, do_clear_ram = 0, do_verify = 0, do_check = 1;
899 int pr_dev_info = 0, pr_rom_info = 0, do_read = 0, sram_mode = 0;
900 int erase_method = 0, do_erase_size = 0;
901 int w_fsize = 0, sw_fsize = 0;
902 struct usb_dev_handle *device;
906 for (i = 1; i < argc; i++)
908 if (argv[i][0] != '-')
911 switch (argv[i][1]) {
919 do_erase_size = 0x400000;
920 if (argv[i][2] == '1')
931 if (argv[i+1] && argv[i+1][0] != '-')
935 if (argv[i+1] && argv[i+1][0] != '-')
941 switch (argv[i][2]) {
944 if (argv[i+1] && argv[i+1][0] != '-')
945 sr_fname = argv[++i];
948 if (argv[i+1] && argv[i+1][0] != '-')
949 sw_fname = argv[++i];
957 sram_mode = argv[i][3];
969 if (i <= 1 || i < argc) {
975 if (w_fname != NULL) {
976 /* check extension */
977 ret = strlen(w_fname);
978 if (do_check && (w_fname[ret - 4] == '.' || w_fname[ret - 3] == '.' ||
979 w_fname[ret - 2] == '.') &&
980 strcasecmp(&w_fname[ret - 4], ".gen") != 0 &&
981 strcasecmp(&w_fname[ret - 4], ".bin") != 0) {
982 fprintf(stderr, "\"%s\" doesn't look like a game ROM, aborting "
983 "(use -f to disable this check)\n", w_fname);
987 ret = read_file(w_fname, &w_fdata, &w_fsize, 0x400000);
991 if (do_erase_size < w_fsize)
992 do_erase_size = w_fsize;
994 if (sw_fname != NULL) {
995 ret = read_file(sw_fname, &sw_fdata, &sw_fsize, 0x8000*2);
999 if (sw_fdata != NULL || do_clear_ram) {
1000 if (sw_fsize < 0x8000*2) {
1001 sw_fdata = realloc(sw_fdata, 0x8000*2);
1002 if (sw_fdata == NULL) {
1003 fprintf(stderr, "low mem\n");
1006 memset((u8 *)sw_fdata + sw_fsize, 0, 0x8000*2 - sw_fsize);
1008 sw_fsize = 0x8000*2;
1010 if (w_fname == NULL && sw_fname == NULL && do_verify) {
1011 fprintf(stderr, "warning: -w or -sw not specified, -v ignored.\n");
1018 device = get_device();
1024 ret = print_device_info(device);
1030 ret = print_game_info(device);
1036 if (do_erase_size != 0) {
1038 ret = erase_all(device, do_erase_size);
1040 ret = erase_seq(device, do_erase_size);
1046 if (w_fdata != NULL) {
1049 ret = read_write_rom(device, 0, w_fdata, w_fsize, 1);
1053 p = strrchr(w_fname, '/');
1054 p = (p == NULL) ? w_fname : p + 1;
1056 ret = write_filename(device, p, FILENAME_ROM0);
1058 fprintf(stderr, "warning: failed to save ROM filename\n");
1062 if (sw_fdata != NULL) {
1065 ret = read_write_ram(device, sw_fdata, sw_fsize, 1);
1069 memset(fname_buff, 0, sizeof(fname_buff));
1071 if (sw_fname != NULL) {
1072 p = strrchr(sw_fname, '/');
1073 p = (p == NULL) ? sw_fname : p + 1;
1074 } else if (w_fname != NULL) {
1075 t = strrchr(w_fname, '/');
1076 t = (t == NULL) ? w_fname : t + 1;
1078 strncpy(fname_buff, t, sizeof(fname_buff));
1079 fname_buff[sizeof(fname_buff) - 1] = 0;
1080 ret = strlen(fname_buff);
1081 if (ret > 4 && fname_buff[ret - 4] == '.')
1082 strcpy(&fname_buff[ret - 4], ".srm");
1085 ret = write_filename(device, p, FILENAME_RAM);
1087 fprintf(stderr, "warning: failed to save RAM filename\n");
1091 if (do_read && r_fname == NULL) {
1092 ret = read_filename(device, fname_buff, sizeof(fname_buff), FILENAME_ROM0);
1095 r_fname = fname_buff;
1096 if (r_fname[0] == 0)
1097 r_fname = "rom.gen";
1100 if (r_fname != NULL || do_verify) {
1101 r_fdata = malloc(0x400000);
1102 if (r_fdata == NULL) {
1103 fprintf(stderr, "low mem\n");
1107 ret = read_write_rom(device, 0, r_fdata, 0x400000, 0);
1112 if (r_fname != NULL)
1113 write_file(r_fname, r_fdata, 0x400000);
1116 if (do_read_ram && sr_fname == NULL) {
1117 ret = read_filename(device, fname_buff, sizeof(fname_buff), FILENAME_RAM);
1120 sr_fname = fname_buff;
1121 if (sr_fname[0] == 0)
1122 sr_fname = "rom.srm";
1125 if (sr_fname != NULL || do_verify) {
1126 sr_fdata = malloc(0x8000*2);
1127 if (sr_fdata == NULL) {
1128 fprintf(stderr, "low mem\n");
1132 ret = read_write_ram(device, sr_fdata, 0x8000*2, 0);
1137 if (sr_fname != NULL)
1138 write_file(sr_fname, sr_fdata, 0x8000*2);
1141 if (do_verify && w_fdata != NULL && r_fdata != NULL) {
1142 ret = memcmp(w_fdata, r_fdata, w_fsize);
1144 printf("flash verification passed.\n");
1146 printf("flash verification FAILED!\n");
1149 if (do_verify && sw_fdata != NULL && sr_fdata != NULL) {
1150 ret = memcmp(sw_fdata, sr_fdata, 0x8000*2);
1152 printf("RAM verification passed.\n");
1154 printf("RAM verification FAILED!\n");
1158 if (sram_mode || w_fsize != 0) {
1160 sram_mode = w_fsize > 0x200000 ? '2' : '3';
1161 printf("Save RAM mode set to ");
1162 switch (sram_mode) {
1165 sram_mode = C_RAM_OFF;
1168 printf("ON for >2M games.\n");
1169 sram_mode = C_RAM_SWITCH;
1172 printf("always ON.\n");
1173 sram_mode = C_RAM_ON;
1176 set_ram_mode(device, sram_mode);
1179 printf("all done.\n");
1183 if (w_fdata != NULL)
1185 if (r_fdata != NULL)
1188 release_device(device);