X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=megadrive.git;a=blobdiff_plain;f=hexed%2Fpc_transfer.c;h=ef1f58b4bd8310d466c8566551d5b39b7b276ef0;hp=569acfc9129c22d55406e74b645b2a21505f08fb;hb=4e6ba16d44cf7d8f4c84712c1dc59738f0a2048d;hpb=93c5aa8a4e294c0736b3ddd02b57b3b4f353e539 diff --git a/hexed/pc_transfer.c b/hexed/pc_transfer.c index 569acfc..ef1f58b 100644 --- a/hexed/pc_transfer.c +++ b/hexed/pc_transfer.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "transfer.h" @@ -190,7 +191,9 @@ static void usage(const char *argv0) fprintf(stderr, "usage:\n%s [args]\n" "\tsend [size]\n" "\trecv \n" - "\tjump \n", argv0); + "\tjump \n" + "\tio {r{8,16,32} ,w{8,16,32} }*\n" + "\tloadstate \n", argv0); exit(1); } @@ -208,6 +211,16 @@ static unsigned int atoi_or_die(const char *a) return i; } +static void checked_gzread(gzFile f, void *data, size_t size) +{ + unsigned int ret; + ret = gzread(f, data, size); + if (ret != size) { + fprintf(stderr, "gzread returned %d/%zu\n", ret, size); + exit(1); + } +} + int main(int argc, char *argv[]) { unsigned int addr = 0, size = 0; @@ -322,6 +335,75 @@ int main(int argc, char *argv[]) count++; } } + else if (strcmp(argv[1], "loadstate") == 0) + { + unsigned char chunk; + char header[12]; + gzFile f; + int len; + + if (argc != 3) + usage(argv[0]); + + f = gzopen(argv[2], "rb"); + if (f == NULL) { + perror("gzopen"); + return 1; + } + + checked_gzread(f, header, sizeof(header)); + if (strncmp(header, "PicoSEXT", 8) != 0) { + fprintf(stderr, "bad header\n"); + return 1; + } + + while (!gzeof(file)) + { + ret = gzread(f, &chunk, 1); + if (ret == 0) + break; + checked_gzread(f, &len, 4); + //printf("%2d %x\n", chunk, len); + switch (chunk) { + case 3: // VRAM + checked_gzread(f, data, len); + size += len; + break; + case 5: // CRAM + checked_gzread(f, data + 0x10000, len); + size += len; + break; + case 6: // VSRAM + checked_gzread(f, data + 0x10080, len); + size += len; + break; + case 8: // video + checked_gzread(f, data + 0x10100, len); + data[size+0] &= ~1; // no display disable + data[size+1] |= 0x40; // no blanking + size += 0x20; + break; + default: + if (chunk > 64+8) { + fprintf(stderr, "bad chunk: %d\n", chunk); + return 1; + } + gzseek(f, len, SEEK_CUR); + break; + } + } + gzclose(f); + if (size != 0x10120) { + fprintf(stderr, "bad final size: %x\n", size); + return 1; + } + // unbyteswap *RAMs (stored byteswapped) + for (i = 0; i < 0x10100; i += 2) { + int tmp = data[i]; + data[i] = data[i + 1]; + data[i + 1] = tmp; + } + } else usage(argv[0]); @@ -448,12 +530,28 @@ int main(int argc, char *argv[]) } } } + else if (strcmp(argv[1], "loadstate") == 0) + { + send_cmd(CMD_LOADSTATE); + + for (i = 0; i < size; i++) + { + if ((i & 0x1f) == 0) { + printf("\b\b\b\b\b\b\b\b\b\b\b\b\b"); + printf("%06x/%06x", i, size); + fflush(stdout); + } + + send_byte(data[i]); + } + } - if (file != NULL) { + if (size != 0) { printf("\b\b\b\b\b\b\b\b\b\b\b\b\b"); printf("%06x/%06x\n", i, size); - fclose(file); } + if (file != NULL) + fclose(file); /* switch TL back to high, disable outputs */ outb(0xe0, PORT_CONTROL);