X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=mx%2Flinux%2Fmain.c;h=9f9fdbe23304e2bcd27afa77dbe083684c795d98;hb=95122097e24114e884b48d432aa9e96d7c83fd28;hp=fd948547c017d407c375b8ef3605b5da7ac6b6b2;hpb=c9d375d5cc92c170b985a5874ef168aef877e398;p=megadrive.git diff --git a/mx/linux/main.c b/mx/linux/main.c index fd94854..9f9fdbe 100644 --- a/mx/linux/main.c +++ b/mx/linux/main.c @@ -1,3 +1,4 @@ +/* FIXME: RAM odd */ #include #include #include @@ -32,8 +33,9 @@ static const struct { #define CMD_SEC_READY 'C' /* is flash ready? */ #define CMD_SEC_READ 'R' #define CMD_SEC_WRITE 'W' -#define CMD_SEC_RAM_READ 'D' +#define CMD_SEC_RAM_READ 'D' /* not implemented? */ #define CMD_SEC_RAM_WRITE 'U' +#define CMD_SEC_COMPAT '$' /* set RAM mode */ /* bus controllers */ #define CTL_DATA_BUS 0x55 @@ -47,6 +49,16 @@ static const struct { #define FILENAME_ROM1 1 #define FILENAME_RAM 2 +/* windows app sets to 0x80 on init + * checkboxes use 0x41 0x42 0x43 (?) + * r,w Ram/ROM uses 0x23/0x21 + */ +#define C_MODE_4M_NORAM 0x41 /* RAM always off */ +#define C_MODE_4M_RAM 0x42 /* RAM switched by game */ +#define C_MODE_2M_RAM 0x43 +#define C_RAM_TMP_OFF 0x21 +#define C_RAM_TMP_ON 0x23 + typedef struct { u8 magic[4]; u8 reserved[8]; @@ -67,7 +79,7 @@ typedef struct { } rom_rw; struct { u8 which; - } filename; + } filename, mode; struct { u8 cmd; u8 action; @@ -354,6 +366,28 @@ static int get_page_size(const page_table_t *table, u32 addr, u32 *size) return -1; } +static int set_ram_mode(struct usb_dev_handle *dev, u8 mode) +{ + dev_cmd_t cmd; + u8 buff[2]; + int ret; + + prepare_cmd(&cmd, CMD_SEC_COMPAT); + cmd.write_flag = 1; + cmd.mode.which = mode; + + ret = write_cmd(dev, &cmd); + if (ret < 0) + goto end; + + ret = read_data(dev, buff, sizeof(buff)); + +end: + if (ret < 0) + fprintf(stderr, "warning: failed to set RAM mode\n"); + return ret; +} + /* limitations: * - bytes must be multiple of 64 * - bytes must be less than 16k @@ -407,6 +441,8 @@ static int read_write_rom(struct usb_dev_handle *dev, u32 addr, void *buffer, in fprintf(stderr, "read_write_rom: byte count must be multiple of 64, " "last %d bytes will not be handled\n", bytes & 63); + set_ram_mode(dev, C_RAM_TMP_OFF); + printf("%s flash ROM...\n", is_write ? "writing to" : "reading"); /* do i/o in blocks */ @@ -439,17 +475,19 @@ static int read_write_rom(struct usb_dev_handle *dev, u32 addr, void *buffer, in static int read_write_ram(struct usb_dev_handle *dev, void *buffer, int bytes, int is_write) { - int mx_cmd = is_write ? CMD_SEC_RAM_WRITE : CMD_SEC_RAM_READ; + int mx_cmd = is_write ? CMD_SEC_RAM_WRITE : CMD_SEC_READ; int total_bytes = bytes; u8 *buff = buffer; u32 addr = 0x200000; - int ret = 0; + int i, ret = 0; if (bytes % IO_RAM_BLK_SIZE) fprintf(stderr, "read_write_ram: byte count must be multiple of %d, " "last %d bytes will not be handled\n", IO_RAM_BLK_SIZE, bytes % IO_RAM_BLK_SIZE); + set_ram_mode(dev, C_RAM_TMP_ON); + printf("%s RAM...\n", is_write ? "writing to" : "reading"); /* do i/o in blocks */ @@ -465,6 +503,10 @@ static int read_write_ram(struct usb_dev_handle *dev, void *buffer, int bytes, i } print_progress(buff - (u8 *)buffer, total_bytes); + /* only D0-D7 connected.. */ + for (i = 0; i < total_bytes; i += 2) + ((u8 *)buffer)[i] = 0; + printf("\n"); return ret; @@ -505,7 +547,7 @@ static int increment_erase_cnt(struct usb_dev_handle *dev) if (ret < 0) return ret; - return 0; + return cnt; } static int erase_page(struct usb_dev_handle *dev, u32 addr, int whole) @@ -580,12 +622,12 @@ static int erase_seq(struct usb_dev_handle *dev, u32 size) if (table == NULL) return -1; - printf("erasing flash...\n"); - ret = increment_erase_cnt(dev); - if (ret != 0) + if (ret < 0) fprintf(stderr, "warning: coun't increase erase counter\n"); + printf("erasing flash... (erase count=%u)\n", ret); + for (addr = 0, count = 0; addr < size; addr += page_size, count++) { print_progress(addr, size); @@ -613,13 +655,13 @@ static int erase_all(struct usb_dev_handle *dev, u32 size) { int ret; - printf("erasing flash0..."); - fflush(stdout); - ret = increment_erase_cnt(dev); - if (ret != 0) + if (ret < 0) fprintf(stderr, "warning: couldn't increase erase counter\n"); + printf("erasing flash0, count=%u ...", ret); + fflush(stdout); + ret = erase_page(dev, 0xaaa, 1); if (ret != 0) return ret; @@ -720,7 +762,8 @@ static int read_file(const char *fname, void **buff_out, int *size, int limit) ret = fread(data, 1, file_size, file); if (ret != file_size) { - fprintf(stderr, "failed to read file: %s\n", fname); + fprintf(stderr, "failed to read file: %s", fname); + perror(""); goto fail; } @@ -745,12 +788,13 @@ static int write_file(const char *fname, void *buff, int size) return -1; } - ret = fwrite(fname, 1, size, file); + ret = fwrite(buff, 1, size, file); + if (ret != size) { + fprintf(stderr, "write failed to %s", fname); + perror(""); + } else + printf("saved to \"%s\".\n", fname); fclose(file); - if (ret != size) - fprintf(stderr, "write failed to %s\n", fname); - else - printf("saved to %s.\n", fname); return 0; } @@ -836,6 +880,7 @@ static void usage(const char *app_name) " -i print some info about connected device\n" " -g print some info about game ROM inside device\n" " -e[1] erase whole flash ROM in device, '1' uses different erase method\n" + " -m[1-3] set MX mode: 2M+RAM, 4M no RAM, 4M+RAM\n" " -f skip file check\n" " -r [file] copy game image from device to file; can autodetect filename\n" " -w write file to device; also does erase\n" @@ -851,7 +896,7 @@ int main(int argc, char *argv[]) char *r_fname = NULL, *w_fname = NULL, *sr_fname = NULL, *sw_fname = NULL; void *r_fdata = NULL, *w_fdata = NULL, *sr_fdata = NULL, *sw_fdata = NULL; int do_read_ram = 0, do_clear_ram = 0, do_verify = 0, do_check = 1; - int pr_dev_info = 0, pr_rom_info = 0, do_read = 0; + int pr_dev_info = 0, pr_rom_info = 0, do_read = 0, mx_mode = 0; int erase_method = 0, do_erase_size = 0; int w_fsize = 0, sw_fsize = 0; struct usb_dev_handle *device; @@ -881,6 +926,9 @@ int main(int argc, char *argv[]) case 'v': do_verify = 1; break; + case 'm': + mx_mode = argv[i][2]; + break; case 'r': do_read = 1; if (argv[i+1] && argv[i+1][0] != '-') @@ -909,8 +957,9 @@ int main(int argc, char *argv[]) do_clear_ram = 1; break; default: - /* fall though */; + goto breakloop; } + break; default: goto breakloop; } @@ -943,20 +992,20 @@ breakloop: do_erase_size = w_fsize; } if (sw_fname != NULL) { - ret = read_file(sw_fname, &sw_fdata, &sw_fsize, 0x8000); + ret = read_file(sw_fname, &sw_fdata, &sw_fsize, 0x8000*2); if (ret < 0) return 1; } if (sw_fdata != NULL || do_clear_ram) { - if (sw_fsize < 0x8000) { - sw_fdata = realloc(sw_fdata, 0x8000); + if (sw_fsize < 0x8000*2) { + sw_fdata = realloc(sw_fdata, 0x8000*2); if (sw_fdata == NULL) { fprintf(stderr, "low mem\n"); return 1; } - memset((u8 *)sw_fdata + sw_fsize, 0, 0x8000 - sw_fsize); + memset((u8 *)sw_fdata + sw_fsize, 0, 0x8000*2 - sw_fsize); } - sw_fsize = 0x8000; + sw_fsize = 0x8000*2; } if (w_fname == NULL && sw_fname == NULL && do_verify) { fprintf(stderr, "warning: -w or -sw not specified, -v ignored.\n"); @@ -983,6 +1032,28 @@ breakloop: goto end; } + /* set mode */ + if (mx_mode || w_fsize > 0x200000) { + if (mx_mode == 0) + mx_mode = '3'; + printf("MX mode set to "); + switch (mx_mode) { + case '1': + printf("2M with RAM.\n"); + mx_mode = C_MODE_2M_RAM; + break; + case '2': + printf("4M, no RAM.\n"); + mx_mode = C_MODE_4M_NORAM; + break; + default: + printf("4M with RAM.\n"); + mx_mode = C_MODE_4M_RAM; + break; + } + set_ram_mode(device, mx_mode); + } + /* erase */ if (do_erase_size != 0) { if (erase_method) @@ -1074,19 +1145,19 @@ breakloop: } if (sr_fname != NULL || do_verify) { - sr_fdata = malloc(0x8000); + sr_fdata = malloc(0x8000*2); if (sr_fdata == NULL) { fprintf(stderr, "low mem\n"); goto end; } - ret = read_write_ram(device, sr_fdata, 0x400000, 0); + ret = read_write_ram(device, sr_fdata, 0x8000*2, 0); if (ret < 0) goto end; } if (sr_fname != NULL) - write_file(sr_fname, sr_fdata, 0x400000); + write_file(sr_fname, sr_fdata, 0x8000*2); /* verify */ if (do_verify && w_fdata != NULL && r_fdata != NULL) { @@ -1098,7 +1169,7 @@ breakloop: } if (do_verify && sw_fdata != NULL && sr_fdata != NULL) { - ret = memcmp(sw_fdata, sr_fdata, 0x8000); + ret = memcmp(sw_fdata, sr_fdata, 0x8000*2); if (ret == 0) printf("RAM verification passed.\n"); else