2 * Copyright (c) 2009, GraÅžvydas Ignotas
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the organization nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 typedef unsigned char u8;
33 typedef unsigned short u16;
34 typedef unsigned int u32;
35 #define array_size(x) (sizeof(x) / sizeof(x[0]))
38 unsigned short vendor;
39 unsigned short product;
42 { 0x03eb, 0x202a, "16MX+U Game Device" },
43 { 0x03eb, 0x202b, "32MX+U Game Device" },
44 { 0x03eb, 0x202c, "16MX+US Game Device" },
45 { 0x03eb, 0x202d, "32MX+UF Game Device" },
48 #define VERSION "0.91"
50 //#define IO_BLK_SIZE 0x2000 /* 8K - unreliable? */
51 #define IO_BLK_SIZE 0x800
52 #define IO_RAM_BLK_SIZE 256
54 #define CMD_ATM_READY 0x22
55 #define CMD_SEC_GET_NAME 'G' /* filename r/w */
56 #define CMD_SEC_PUT_NAME 'P'
57 #define CMD_SEC_DEVID 'L' /* read flash device ID */
58 #define CMD_SEC_ERASE 'E'
59 #define CMD_SEC_READY 'C' /* is flash ready? */
60 #define CMD_SEC_READ 'R'
61 #define CMD_SEC_WRITE 'W'
62 #define CMD_SEC_RAM_READ 'D' /* not implemented? */
63 #define CMD_SEC_RAM_WRITE 'U'
64 #define CMD_SEC_COMPAT '$' /* set RAM mode */
67 #define CTL_DATA_BUS 0x55
68 #define CTL_ADDR_BUS 0xAA
70 #define W_COUNTER 0xA0
71 #define W_CNT_WRITE 0x01
72 #define W_CNT_READ 0x00
74 #define FILENAME_ROM0 0
75 #define FILENAME_ROM1 1
76 #define FILENAME_RAM 2
78 /* windows app sets to 0x80 on init
79 * checkboxes use 0x41 0x42 0x43 (?)
80 * r,w Ram/ROM uses 0x23/0x21
82 #define C_MODE_4M_NORAM 0x41 /* RAM always off */
83 #define C_MODE_4M_RAM 0x42 /* RAM switched by game */
84 #define C_MODE_2M_RAM 0x43
85 #define C_RAM_TMP_OFF 0x21
86 #define C_RAM_TMP_ON 0x23
100 u8 addrb2; /* most significant (BE) */
103 u8 param; /* 64 byte usb packets for i/o */
127 u8 bootloader_ver[4];
137 static const page_table_t p_AM29LV320DB[] =
139 { 0x000000, 0x00ffff, 0x002000 },
140 { 0x010000, 0x3fffff, 0x010000 },
141 { 0x000000, 0x000000, 0x000000 },
144 static const page_table_t p_AM29LV320DT[] =
146 { 0x000000, 0x3effff, 0x010000 },
147 { 0x3f0000, 0x3fffff, 0x002000 },
148 { 0x000000, 0x000000, 0x000000 },
151 static const page_table_t p_2x_16[] =
153 { 0x000000, 0x003fff, 0x004000 },
154 { 0x004000, 0x007fff, 0x002000 },
155 { 0x008000, 0x00ffff, 0x008000 },
156 { 0x010000, 0x1fffff, 0x010000 },
157 { 0x200000, 0x203fff, 0x004000 },
158 { 0x204000, 0x207fff, 0x002000 },
159 { 0x208000, 0x20ffff, 0x008000 },
160 { 0x210000, 0x3fffff, 0x010000 },
161 { 0x000000, 0x000000, 0x000000 },
164 /*****************************************************************************/
166 static void prepare_cmd(dev_cmd_t *dev_cmd, u8 cmd)
168 memset(dev_cmd, 0, sizeof(*dev_cmd));
170 memcpy(dev_cmd->magic, "USBC", 4);
171 dev_cmd->magic2 = 0x67; /* MySCSICommand, EXCOMMAND */
172 dev_cmd->mx_cmd = cmd;
175 static int write_data(struct usb_dev_handle *dev, void *data, int len)
177 int ret = usb_bulk_write(dev, 0x03, data, len, 2000);
179 fprintf(stderr, "failed to write:\n");
180 fprintf(stderr, "%s (%d)\n", usb_strerror(), ret);
181 } else if (ret != len)
182 printf("write_cmd: wrote only %d of %d bytes\n", ret, len);
187 static int write_cmd(struct usb_dev_handle *dev, dev_cmd_t *cmd)
189 return write_data(dev, cmd, sizeof(*cmd));
192 static int read_data(struct usb_dev_handle *dev, void *buff, int size)
194 int ret = usb_bulk_read(dev, 0x82, buff, size, 2000);
196 fprintf(stderr, "failed to read:\n");
197 fprintf(stderr, "%s (%d)\n", usb_strerror(), ret);
200 else if (ret != size)
201 printf("read_data: read only %d of %d bytes\n", ret, size);
206 static int read_info(struct usb_dev_handle *device, u8 ctl_id, dev_info_t *info)
211 prepare_cmd(&cmd, CMD_ATM_READY);
212 cmd.dev_info.which_device = ctl_id;
213 memset(info, 0, sizeof(*info));
215 ret = write_cmd(device, &cmd);
219 ret = read_data(device, info, sizeof(*info));
226 static void printf_info(dev_info_t *info)
228 printf(" firmware version: %X.%X.%X%c\n", info->firmware_ver[0],
229 info->firmware_ver[1], info->firmware_ver[2], info->firmware_ver[3]);
230 printf(" bootloader version: %X.%X.%X%c\n", info->bootloader_ver[0],
231 info->bootloader_ver[1], info->bootloader_ver[2], info->bootloader_ver[3]);
232 info->names[sizeof(info->names) - 1] = 0;
233 printf(" device name: %s\n", info->names);
236 static void print_progress(u32 done, u32 total)
240 printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
241 printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); /* 20 */
242 printf("\b\b\b\b\b\b");
243 printf("%06x/%06x |", done, total);
246 for (i = step; i <= total; i += step)
247 printf("%c", done >= i ? '=' : '-');
248 printf("| %3d%%", done * 100 / total);
252 static int read_filename(struct usb_dev_handle *dev, char *dst, int len, u8 which)
258 prepare_cmd(&cmd, CMD_SEC_GET_NAME);
259 cmd.filename.which = which;
260 memset(buff, 0, sizeof(buff));
262 ret = write_cmd(dev, &cmd);
266 ret = read_data(dev, buff, 64);
270 strncpy(dst, buff, len);
276 static int write_filename(struct usb_dev_handle *dev, const char *fname, u8 which)
285 strncpy(buff, fname, len);
288 prepare_cmd(&cmd, CMD_SEC_PUT_NAME);
289 cmd.filename.which = which;
291 ret = write_cmd(dev, &cmd);
295 return write_data(dev, buff, len + 1);
298 static int read_erase_counter(struct usb_dev_handle *dev, u32 *val)
300 dev_info_t dummy_info;
305 /* must perform dummy info read here,
306 * or else device hangs after close (firmware bug?) */
307 ret = read_info(dev, CTL_DATA_BUS, &dummy_info);
311 prepare_cmd(&cmd, CMD_ATM_READY);
312 cmd.write_cnt.cmd = W_COUNTER;
313 cmd.write_cnt.action = W_CNT_READ;
315 ret = write_cmd(dev, &cmd);
319 ret = read_data(dev, buff, sizeof(buff));
327 static int read_flash_rom_id(struct usb_dev_handle *dev, int is_second, u32 *val)
333 prepare_cmd(&cmd, CMD_SEC_DEVID);
334 cmd.rom_id.which = is_second ? 0x10 : 0;
335 cmd.rom_id.dev_id = 0;
337 ret = write_cmd(dev, &cmd);
341 ret = read_data(dev, buff, sizeof(buff));
345 *val = *(u16 *)buff << 16;
347 cmd.rom_id.dev_id = 1;
348 ret = write_cmd(dev, &cmd);
352 ret = read_data(dev, buff, sizeof(buff));
356 *val |= *(u16 *)buff;
360 static const page_table_t *get_page_table(u32 rom_id)
364 return p_AM29LV320DB;
366 return p_AM29LV320DT;
371 fprintf(stderr, "unrecognized ROM id: %08x\n", rom_id);
377 static int get_page_size(const page_table_t *table, u32 addr, u32 *size)
379 const page_table_t *t;
381 for (t = table; t->end_addr != 0; t++) {
382 if (addr >= t->start_addr && addr <= t->end_addr) {
383 *size = t->page_size;
388 if (addr == t[-1].end_addr + 1)
389 return 1; /* no more */
391 fprintf(stderr, "get_page_size: failed on addr %06x\n", addr);
395 static int set_ram_mode(struct usb_dev_handle *dev, u8 mode)
401 prepare_cmd(&cmd, CMD_SEC_COMPAT);
403 cmd.mode.which = mode;
405 ret = write_cmd(dev, &cmd);
409 ret = read_data(dev, buff, sizeof(buff));
413 fprintf(stderr, "warning: failed to set RAM mode\n");
418 * - bytes must be multiple of 64
419 * - bytes must be less than 16k
420 * - must perform even number of reads, or dev hangs on exit (firmware bug?) */
421 static int rw_dev_block(struct usb_dev_handle *dev, u32 addr, void *buffer, int bytes, int mx_cmd)
426 prepare_cmd(&cmd, mx_cmd);
427 if (mx_cmd == CMD_SEC_WRITE || mx_cmd == CMD_SEC_RAM_WRITE)
429 cmd.rom_rw.addrb2 = addr >> (16 + 1);
430 cmd.rom_rw.addrb1 = addr >> (8 + 1);
431 cmd.rom_rw.addrb0 = addr >> 1;
432 cmd.rom_rw.param = bytes / 64;
433 if (mx_cmd == CMD_SEC_WRITE || mx_cmd == CMD_SEC_RAM_WRITE)
434 cmd.rom_rw.param2 = 1; /* ? */
436 ret = write_cmd(dev, &cmd);
442 if (mx_cmd == CMD_SEC_WRITE || mx_cmd == CMD_SEC_RAM_WRITE)
443 ret = write_data(dev, buffer, bytes);
445 ret = read_data(dev, buffer, bytes);
450 fprintf(stderr, "rw_dev_block warning: done only %d/%d bytes\n", ret, bytes);
455 static int read_write_rom(struct usb_dev_handle *dev, u32 addr, void *buffer, int bytes, int is_write)
457 int mx_cmd = is_write ? CMD_SEC_WRITE : CMD_SEC_READ;
458 int total_bytes = bytes;
464 fprintf(stderr, "read_write_rom: can't handle odd address %06x, "
465 "LSb will be ignored\n", addr);
467 fprintf(stderr, "read_write_rom: byte count must be multiple of 64, "
468 "last %d bytes will not be handled\n", bytes & 63);
470 set_ram_mode(dev, C_RAM_TMP_OFF);
472 printf("%s flash ROM...\n", is_write ? "writing to" : "reading");
474 /* do i/o in blocks */
475 for (count = 0; bytes >= IO_BLK_SIZE; count++) {
476 print_progress(buff - (u8 *)buffer, total_bytes);
478 ret = rw_dev_block(dev, addr, buff, IO_BLK_SIZE, mx_cmd);
483 bytes -= IO_BLK_SIZE;
485 print_progress(buff - (u8 *)buffer, total_bytes);
489 ret = rw_dev_block(dev, addr, buff, bytes, mx_cmd);
491 print_progress(total_bytes, total_bytes);
494 if ((count & 1) && !is_write)
495 /* work around rw_dev_block() limitation 3 (works for reads only?) */
496 rw_dev_block(dev, 0, dummy, sizeof(dummy), 0);
502 static int read_write_ram(struct usb_dev_handle *dev, void *buffer, int bytes, int is_write)
504 int mx_cmd = is_write ? CMD_SEC_RAM_WRITE : CMD_SEC_READ;
505 int total_bytes = bytes;
510 if (bytes % IO_RAM_BLK_SIZE)
511 fprintf(stderr, "read_write_ram: byte count must be multiple of %d, "
512 "last %d bytes will not be handled\n", IO_RAM_BLK_SIZE,
513 bytes % IO_RAM_BLK_SIZE);
515 set_ram_mode(dev, C_RAM_TMP_ON);
517 printf("%s RAM...\n", is_write ? "writing to" : "reading");
519 /* do i/o in blocks */
520 while (bytes >= IO_RAM_BLK_SIZE) {
521 print_progress(buff - (u8 *)buffer, total_bytes);
523 ret = rw_dev_block(dev, addr, buff, IO_RAM_BLK_SIZE, mx_cmd);
526 buff += IO_RAM_BLK_SIZE;
527 addr += IO_RAM_BLK_SIZE;
528 bytes -= IO_RAM_BLK_SIZE;
530 print_progress(buff - (u8 *)buffer, total_bytes);
532 /* only D0-D7 connected.. */
533 for (i = 0; i < total_bytes; i += 2)
534 ((u8 *)buffer)[i] = 0;
541 static int increment_erase_cnt(struct usb_dev_handle *dev)
548 ret = read_erase_counter(dev, &cnt);
552 if (cnt == (u32)-1) {
553 fprintf(stderr, "flash erase counter maxed out!\n");
554 fprintf(stderr, "(wow, did you really erase so many times?)\n");
560 prepare_cmd(&cmd, CMD_ATM_READY);
561 cmd.write_cnt.cmd = W_COUNTER;
562 cmd.write_cnt.action = W_CNT_WRITE;
563 cmd.write_cnt.b3 = cnt >> 24;
564 cmd.write_cnt.b2 = cnt >> 16;
565 cmd.write_cnt.b1 = cnt >> 8;
566 cmd.write_cnt.b0 = cnt;
568 ret = write_cmd(dev, &cmd);
572 ret = read_data(dev, buff, sizeof(buff));
579 static int erase_page(struct usb_dev_handle *dev, u32 addr, int whole)
585 prepare_cmd(&cmd, CMD_SEC_ERASE);
587 cmd.rom_rw.addrb2 = addr >> (16 + 1);
588 cmd.rom_rw.addrb1 = addr >> (8 + 1);
589 cmd.rom_rw.addrb0 = addr >> 1;
590 cmd.rom_rw.param = whole ? 0x10 : 0;
592 ret = write_cmd(dev, &cmd);
596 ret = read_data(dev, buff, sizeof(buff));
600 prepare_cmd(&cmd, CMD_SEC_READY);
601 cmd.rom_rw.addrb2 = addr >> (16 + 1);
602 cmd.rom_rw.addrb1 = addr >> (8 + 1);
603 cmd.rom_rw.addrb0 = addr >> 1;
605 for (i = 0; i < 100; i++) {
606 ret = write_cmd(dev, &cmd);
610 ret = read_data(dev, buff, sizeof(buff));
614 if (ret > 4 && buff[4] == 1)
617 usleep((whole ? 600 : 20) * 1000);
621 fprintf(stderr, "\ntimeout waiting for erase to complete\n");
628 static int erase_seq(struct usb_dev_handle *dev, u32 size)
630 const page_table_t *table;
631 u32 addr, page_size = 0;
632 u32 rom0_id, rom1_id;
635 ret = read_flash_rom_id(dev, 0, &rom0_id);
639 ret = read_flash_rom_id(dev, 1, &rom1_id);
643 if (rom0_id != rom1_id)
644 fprintf(stderr, "Warning: flash ROM ids differ: %08x %08x\n",
647 table = get_page_table(rom0_id);
651 ret = increment_erase_cnt(dev);
653 fprintf(stderr, "warning: coun't increase erase counter\n");
655 printf("erasing flash... (erase count=%u)\n", ret);
657 for (addr = 0, count = 0; addr < size; addr += page_size, count++) {
658 print_progress(addr, size);
660 ret = erase_page(dev, addr, 0);
664 ret = get_page_size(table, addr, &page_size);
671 /* must submit even number of erase commands (fw bug?) */
672 erase_page(dev, 0, 0);
674 print_progress(addr, size);
680 static int erase_all(struct usb_dev_handle *dev, u32 size)
684 ret = increment_erase_cnt(dev);
686 fprintf(stderr, "warning: couldn't increase erase counter\n");
688 printf("erasing flash0, count=%u ...", ret);
691 ret = erase_page(dev, 0xaaa, 1);
695 if (size > 0x200000) {
697 printf("erasing flash1...");
700 ret = erase_page(dev, 0x200aaa, 1);
707 static int print_device_info(struct usb_dev_handle *dev)
709 u32 counter, rom0_id, rom1_id;
713 printf("data bus controller:\n");
714 ret = read_info(dev, CTL_DATA_BUS, &info);
719 printf("address bus controller:\n");
720 ret = read_info(dev, CTL_ADDR_BUS, &info);
725 ret = read_erase_counter(dev, &counter);
728 printf("flash erase count: %u\n", counter);
730 ret = read_flash_rom_id(dev, 0, &rom0_id);
733 printf("flash rom0 id: %08x\n", rom0_id);
735 ret = read_flash_rom_id(dev, 1, &rom1_id);
738 printf("flash rom1 id: %08x\n", rom1_id);
743 static int print_game_info(struct usb_dev_handle *dev)
748 ret = read_filename(dev, fname, sizeof(fname), FILENAME_ROM0);
751 printf("ROM filename: %s\n", fname);
753 ret = read_filename(dev, fname, sizeof(fname), FILENAME_RAM);
756 printf("SRAM filename: %s\n", fname);
761 static int read_file(const char *fname, void **buff_out, int *size, int limit)
767 file = fopen(fname, "rb");
769 fprintf(stderr, "can't open file: %s\n", fname);
773 fseek(file, 0, SEEK_END);
774 file_size = ftell(file);
775 fseek(file, 0, SEEK_SET);
776 if (file_size > limit)
777 fprintf(stderr, "warning: input file \"%s\" too large\n", fname);
779 fprintf(stderr, "bad/empty file: %s\n", fname);
783 data = malloc(file_size);
785 fprintf(stderr, "low memory\n");
789 ret = fread(data, 1, file_size, file);
790 if (ret != file_size) {
791 fprintf(stderr, "failed to read file: %s", fname);
806 static int write_file(const char *fname, void *buff, int size)
811 file = fopen(fname, "wb");
813 fprintf(stderr, "can't open for writing: %s\n", fname);
817 ret = fwrite(buff, 1, size, file);
819 fprintf(stderr, "write failed to %s", fname);
822 printf("saved to \"%s\".\n", fname);
828 static usb_dev_handle *get_device(void)
830 struct usb_dev_handle *handle;
831 struct usb_device *dev;
835 ret = usb_find_busses();
837 fprintf(stderr, "Can't find USB busses\n");
841 ret = usb_find_devices();
843 fprintf(stderr, "Can't find USB devices\n");
847 bus = usb_get_busses();
848 for (; bus; bus = bus->next)
850 for (dev = bus->devices; dev; dev = dev->next)
852 for (i = 0; i < array_size(g_devices); i++)
854 if (dev->descriptor.idVendor == g_devices[i].vendor &&
855 dev->descriptor.idProduct == g_devices[i].product)
861 fprintf(stderr, "device not found.\n");
865 printf("found %s.\n", g_devices[i].name);
867 handle = usb_open(dev);
868 if (handle == NULL) {
869 fprintf(stderr, "failed to open device:\n");
870 fprintf(stderr, "%s\n", usb_strerror());
874 ret = usb_set_configuration(handle, 1);
876 fprintf(stderr, "couldn't set configuration for /*/bus/usb/%s/%s:\n",
877 bus->dirname, dev->filename);
878 fprintf(stderr, "%s (%d)\n", usb_strerror(), ret);
882 ret = usb_claim_interface(handle, 0);
884 fprintf(stderr, "couldn't claim /*/bus/usb/%s/%s:\n",
885 bus->dirname, dev->filename);
886 fprintf(stderr, "%s (%d)\n", usb_strerror(), ret);
893 static void release_device(struct usb_dev_handle *device)
895 usb_release_interface(device, 0);
899 static void usage(const char *app_name)
901 printf("Flasher tool for MX game devices\n"
902 "written by Grazvydas \"notaz\" Ignotas\n");
903 printf("v" VERSION " (" __DATE__ ")\n\n");
905 "%s [-i] [-g] [-e] [-r [file]] [-w <file>] ...\n"
906 " -i print some info about connected device\n"
907 " -g print some info about game ROM inside device\n"
908 " -e[1] erase whole flash ROM in device, '1' uses different erase method\n"
909 " -m[1-3] set MX mode: 2M+RAM, 4M no RAM, 4M+RAM\n"
910 " -f skip file check\n"
911 " -r [file] copy game image from device to file; can autodetect filename\n"
912 " -w <file> write file to device; also does erase\n"
913 " -sr [file] read save RAM to file\n"
914 " -sw <file> write save RAM file to device\n"
915 " -sc clear save RAM\n"
916 " -v with -w or -sw: verify written file\n",
920 int main(int argc, char *argv[])
922 char *r_fname = NULL, *w_fname = NULL, *sr_fname = NULL, *sw_fname = NULL;
923 void *r_fdata = NULL, *w_fdata = NULL, *sr_fdata = NULL, *sw_fdata = NULL;
924 int do_read_ram = 0, do_clear_ram = 0, do_verify = 0, do_check = 1;
925 int pr_dev_info = 0, pr_rom_info = 0, do_read = 0, mx_mode = 0;
926 int erase_method = 0, do_erase_size = 0;
927 int w_fsize = 0, sw_fsize = 0;
928 struct usb_dev_handle *device;
932 for (i = 1; i < argc; i++)
934 if (argv[i][0] != '-')
937 switch (argv[i][1]) {
945 do_erase_size = 0x400000;
946 if (argv[i][2] == '1')
956 mx_mode = argv[i][2];
960 if (argv[i+1] && argv[i+1][0] != '-')
964 if (argv[i+1] && argv[i+1][0] != '-')
970 switch (argv[i][2]) {
973 if (argv[i+1] && argv[i+1][0] != '-')
974 sr_fname = argv[++i];
977 if (argv[i+1] && argv[i+1][0] != '-')
978 sw_fname = argv[++i];
995 if (i <= 1 || i < argc) {
1001 if (w_fname != NULL) {
1002 /* check extension */
1003 ret = strlen(w_fname);
1004 if (do_check && (w_fname[ret - 4] == '.' || w_fname[ret - 3] == '.' ||
1005 w_fname[ret - 2] == '.') &&
1006 strcasecmp(&w_fname[ret - 4], ".gen") != 0 &&
1007 strcasecmp(&w_fname[ret - 4], ".bin") != 0 &&
1008 strcasecmp(&w_fname[ret - 4], ".32x") != 0) {
1009 fprintf(stderr, "\"%s\" doesn't look like a game ROM, aborting "
1010 "(use -f to disable this check)\n", w_fname);
1014 ret = read_file(w_fname, &w_fdata, &w_fsize, 0x400000);
1018 /* align size to 64 */
1019 ret = (w_fsize + 63) & ~63;
1020 if (w_fsize != ret) {
1021 printf("ROM image size is %d, padding to %d\n", w_fsize, ret);
1022 w_fdata = realloc(w_fdata, ret);
1023 if (w_fdata == NULL) {
1024 fprintf(stderr, "low mem\n");
1027 memset((char *)w_fdata + w_fsize, 0, ret - w_fsize);
1031 if (do_erase_size < w_fsize)
1032 do_erase_size = w_fsize;
1034 if (sw_fname != NULL) {
1035 ret = read_file(sw_fname, &sw_fdata, &sw_fsize, 0x8000*2);
1039 if (sw_fdata != NULL || do_clear_ram) {
1040 if (sw_fsize < 0x8000*2) {
1041 sw_fdata = realloc(sw_fdata, 0x8000*2);
1042 if (sw_fdata == NULL) {
1043 fprintf(stderr, "low mem\n");
1046 memset((u8 *)sw_fdata + sw_fsize, 0, 0x8000*2 - sw_fsize);
1048 sw_fsize = 0x8000*2;
1050 if (w_fname == NULL && sw_fname == NULL && do_verify) {
1051 fprintf(stderr, "warning: -w or -sw not specified, -v ignored.\n");
1058 device = get_device();
1064 ret = print_device_info(device);
1070 ret = print_game_info(device);
1076 if (do_erase_size != 0) {
1078 ret = erase_all(device, do_erase_size);
1080 ret = erase_seq(device, do_erase_size);
1086 if (w_fdata != NULL) {
1089 ret = read_write_rom(device, 0, w_fdata, w_fsize, 1);
1093 p = strrchr(w_fname, '/');
1094 p = (p == NULL) ? w_fname : p + 1;
1096 ret = write_filename(device, p, FILENAME_ROM0);
1098 fprintf(stderr, "warning: failed to save ROM filename\n");
1102 if (sw_fdata != NULL) {
1105 ret = read_write_ram(device, sw_fdata, sw_fsize, 1);
1109 memset(fname_buff, 0, sizeof(fname_buff));
1111 if (sw_fname != NULL) {
1112 p = strrchr(sw_fname, '/');
1113 p = (p == NULL) ? sw_fname : p + 1;
1114 } else if (w_fname != NULL) {
1115 t = strrchr(w_fname, '/');
1116 t = (t == NULL) ? w_fname : t + 1;
1118 strncpy(fname_buff, t, sizeof(fname_buff));
1119 fname_buff[sizeof(fname_buff) - 1] = 0;
1120 ret = strlen(fname_buff);
1121 if (ret > 4 && fname_buff[ret - 4] == '.')
1122 strcpy(&fname_buff[ret - 4], ".srm");
1125 ret = write_filename(device, p, FILENAME_RAM);
1127 fprintf(stderr, "warning: failed to save RAM filename\n");
1131 if (mx_mode || w_fsize > 0x200000) {
1134 printf("MX mode set to ");
1137 printf("2M with RAM.\n");
1138 mx_mode = C_MODE_2M_RAM;
1141 printf("4M, no RAM.\n");
1142 mx_mode = C_MODE_4M_NORAM;
1145 printf("4M with RAM.\n");
1146 mx_mode = C_MODE_4M_RAM;
1149 set_ram_mode(device, mx_mode);
1153 if (do_read && r_fname == NULL) {
1154 ret = read_filename(device, fname_buff, sizeof(fname_buff), FILENAME_ROM0);
1157 r_fname = fname_buff;
1158 if (r_fname[0] == 0)
1159 r_fname = "rom.gen";
1162 if (r_fname != NULL || do_verify) {
1163 r_fdata = malloc(0x400000);
1164 if (r_fdata == NULL) {
1165 fprintf(stderr, "low mem\n");
1169 ret = read_write_rom(device, 0, r_fdata, 0x400000, 0);
1174 if (r_fname != NULL)
1175 write_file(r_fname, r_fdata, 0x400000);
1178 if (do_read_ram && sr_fname == NULL) {
1179 ret = read_filename(device, fname_buff, sizeof(fname_buff), FILENAME_RAM);
1182 sr_fname = fname_buff;
1183 if (sr_fname[0] == 0)
1184 sr_fname = "rom.srm";
1187 if (sr_fname != NULL || do_verify) {
1188 sr_fdata = malloc(0x8000*2);
1189 if (sr_fdata == NULL) {
1190 fprintf(stderr, "low mem\n");
1194 ret = read_write_ram(device, sr_fdata, 0x8000*2, 0);
1199 if (sr_fname != NULL)
1200 write_file(sr_fname, sr_fdata, 0x8000*2);
1203 if (do_verify && w_fdata != NULL && r_fdata != NULL) {
1204 ret = memcmp(w_fdata, r_fdata, w_fsize);
1206 printf("flash verification passed.\n");
1208 printf("flash verification FAILED!\n");
1211 if (do_verify && sw_fdata != NULL && sr_fdata != NULL) {
1212 ret = memcmp(sw_fdata, sr_fdata, 0x8000*2);
1214 printf("RAM verification passed.\n");
1216 printf("RAM verification FAILED!\n");
1219 printf("all done.\n");
1223 if (w_fdata != NULL)
1225 if (r_fdata != NULL)
1228 release_device(device);