added a more userfriendly commandline interface to qdinc

This commit is contained in:
Jannis (jix) Harder 2009-09-23 02:16:06 +02:00
parent 080598cb97
commit 243658c0d3
2 changed files with 155 additions and 18 deletions

View File

@ -1,5 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <usb.h>
@ -7,32 +8,118 @@
#include "qdinc.h"
static const char * default_tempfile = "/tmp/quickdev";
void usage(void)
{
fprintf(stderr, "usage: qdinc [-hsi] <romfile>\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] <update> [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");
}

View File

@ -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