diff --git a/tools/qdinc/qdinc.c b/tools/qdinc/qdinc.c index ac7a408..0f721d4 100644 --- a/tools/qdinc/qdinc.c +++ b/tools/qdinc/qdinc.c @@ -1,5 +1,6 @@ #include #include +#include #include @@ -7,32 +8,118 @@ #include "qdinc.h" +static const char * default_tempfile = "/tmp/quickdev"; + + +void usage(void) +{ + fprintf(stderr, "usage: qdinc [-hsi] \n"); + exit(1); +} int main(int argc, char * argv[]) { - if(argc != 4 && argc != 3) + char * filename = 0; + + int hirom = 0; + int header = 0; + int init = 0; + int i,j,j2; + for(i = 1; i < argc; i++) { - fprintf(stderr, "usage: qdinc [hl] [reference]\n"); - exit(1); + if(argv[i][0] == '-') + { + if(strcmp(argv[i], "--") == 0) + { + if(i != argc - 2 || filename) + usage(); + else + { + filename = argv[i+1]; + break; + } + } + unsigned int len = strlen(argv[i]); + if(len == 1) + usage(); + for(j = 1; j < len; j++) + { + switch(argv[i][j]) + { + case 'h': + hirom = 1; + break; + case 's': + header = 1; + break; + case 'i': + init = 1; + break; + default: + usage(); + } + } + } + else + { + if(filename != 0) + usage(); + filename = argv[i]; + } } - int hirom = (argv[1][0] == 'h' || argv[1][0] == 'H'); - - unsigned int pos = 0; int ref_complete, upd_complete = 0; - FILE * upd = fopen(argv[2], "rb"); + const char * tempfile = getenv("QDINC_FILE"); - if(upd == 0) + if(tempfile == 0) + tempfile = default_tempfile; + + char * outfile = malloc(strlen(tempfile) + sizeof(".out")); + char * ext = stpcpy(outfile, tempfile); + strcpy(ext, ".out"); + + FILE * out = fopen(outfile, "wb"); + + if(out == 0) { - fprintf(stderr, "couldn't open file %s\n", argv[3]); + fprintf(stderr, "Could not open file %s for writing\n", outfile); + exit(1); } + FILE * upd = fopen(filename, "rb"); + + if(upd == 0) + { + fprintf(stderr, "Could not open file %s\n", argv[3]); + exit(1); + } + + fseek(upd, 0, SEEK_END); + unsigned int size = ftell(upd); + + if(header) + { + if(size < 512) + size = 0; + else + size -= 512; + fseek(upd, 512, SEEK_SET); + } + else + rewind(upd); + + if(size > 0x200000) + { + fprintf(stderr, "Input file is larger than supported by Quickdev16\n"); + exit(1); + } + FILE * ref = 0; - if(argc == 4) - ref = fopen(argv[3], "rb"); + if(!init) + ref = fopen(tempfile, "rb"); ref_complete = (ref == 0); @@ -65,6 +152,8 @@ int main(int argc, char * argv[]) #ifdef QDINC_OLD_FIRMWARE /* wait for the loader to depack */ usleep(500000); +#else + usleep(50000); #endif cnt = usb_control_msg(handle, @@ -79,14 +168,29 @@ int main(int argc, char * argv[]) unsigned char lastchar; unsigned int transmitted = 0; + + + char progress[21]; + + for(i = 0; i < 20; i++) + progress[i] = ' '; + progress[20] = 0; + j = 0; + j2 = 0; while(!upd_complete) { + int msg = 0; unsigned char updchar = fgetc(upd); unsigned char refchar; if(feof(upd)) + { + msg = 1; upd_complete = 1; - if(!ref_complete) + } + else + fputc(updchar, out); + if(!ref_complete && !upd_complete) { refchar = fgetc(ref); if(feof(ref)) @@ -125,9 +229,6 @@ int main(int argc, char * argv[]) int consecutive = (last_position == position - blocklen); unsigned int begin = position - blocklen; - printf("updating %sblock from 0x%06x to 0x%06x of size 0x%03x\n", (consecutive ? "consecutive " : ""), begin, begin + reallen - 1, reallen); - - cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, consecutive ? USB_BULK_UPLOAD_NEXT : USB_BULK_UPLOAD_ADDR, begin >> 16, @@ -138,11 +239,47 @@ int main(int argc, char * argv[]) transmitted += reallen; blocklen = 0; reallen = 0; + + msg = 1; + + } + if(msg) + { + for(; j < (position - 1) * 20 / size; j++) + progress[j] = '='; + for(; j2 < transmitted * 20 / size; j2++) + progress[j2] = '#'; + printf("At 0x%06x/0x%06x %6.2f%% [%10s] Tx 0x%06x/0x%06x %6.2f%%\r", + position - 1, size, (position - 1) * 100.0 / size, + progress, + transmitted, size, transmitted * 100.0 / size); + fflush(stdout); } - lastchar = updchar; } position--; + + printf("\n"); + + while(!ref_complete) + { + unsigned char refchar = fgetc(ref); + if(feof(ref)) + ref_complete = 1; + else + fputc(refchar, out); + } + + fclose(out); + fclose(upd); + fclose(ref); + + if(rename(outfile, tempfile)) + { + fprintf(stderr, "Could not replace tempfile %s\n", tempfile); + exit(1); + } + cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, USB_BULK_UPLOAD_END, 0, 0, NULL, @@ -155,11 +292,11 @@ int main(int argc, char * argv[]) 0, 5000); #endif - printf("Transmitted %i of %i bytes (%3.2f)\n", transmitted, position, transmitted * 100.0 / position); cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, USB_MODE_SNES, 0, 0, NULL, 0, 5000); return 0; + printf("Done"); } \ No newline at end of file diff --git a/tools/qdinc/qdinc.h b/tools/qdinc/qdinc.h index 1284536..162ab53 100644 --- a/tools/qdinc/qdinc.h +++ b/tools/qdinc/qdinc.h @@ -1,7 +1,7 @@ #ifndef __QDINC_H__ #define __QDINC_H__ -#define QDINC_RANGE 32 +#define QDINC_RANGE 96 #define QDINC_SIZE 254 // makes this compatible with a bug in older quickdev firmware revisions