Switched to getopt, fixed minor issues and some cleanups.

This commit is contained in:
Tobias Pflug 2009-10-21 20:28:33 +02:00 committed by optixx
parent d471173fcc
commit e0dd846013
3 changed files with 92 additions and 113 deletions

View File

@ -27,7 +27,7 @@ NAME = qdinc
OBJECTS = opendevice.o $(NAME).o OBJECTS = opendevice.o $(NAME).o
CC = gcc CC = gcc
CFLAGS = $(CPPFLAGS) $(USBFLAGS) -O -g -Wall CFLAGS = $(CPPFLAGS) $(USBFLAGS) -O -g -Wall -D_GNU_SOURCE
LIBS = $(USBLIBS) LIBS = $(USBLIBS)
PROGRAM = $(NAME)$(EXE_SUFFIX) PROGRAM = $(NAME)$(EXE_SUFFIX)

View File

@ -1,19 +1,31 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <usb.h> #include <usb.h>
#include <unistd.h>
#include <getopt.h>
#include "opendevice.h" #include "opendevice.h"
#include "qdinc.h" #include "qdinc.h"
#define _16MBIT 0x200000
#define HIROM_BANK_SIZE_SHIFT 16
#define LOROM_BANK_SIZE_SHIFT 15
#define HIROM_BANK_COUNT_SHIFT 32
#define LOROM_BANK_COUNT_SHIFT 64
static const char * default_tempfile = "/tmp/quickdev"; static const char * default_tempfile = "/tmp/quickdev";
void usage(void) void usage(void)
{ {
fprintf(stderr, "usage: qdinc [-hsi] <romfile>\n"); fprintf(stderr, "Usage: qdinc [option] <romfile>\n\n\
Options:\n\
-i\tInitial ROM upload\n\
-s\tSkip ROM header\n\
-q\tBe quiet\n\
-h\tForce HiROM mode\n\n");
exit(1); exit(1);
} }
@ -24,81 +36,67 @@ int main(int argc, char * argv[])
int hirom = 0; int hirom = 0;
int header = 0; int header = 0;
int init = 0; int init = 0;
int i,j,j2; int quiet = 0;
for(i = 1; i < argc; i++) int opt = 0;
{
if(argv[i][0] == '-') if (argc==1)
{ usage();
if(strcmp(argv[i], "--") == 0)
{ while ((opt = getopt(argc,argv,"qish")) != -1){
if(i != argc - 2 || filename) switch (opt) {
usage(); case 'i':
else init = 1;
{ break;
filename = argv[i+1]; case 's':
break; header = 1;
} break;
} case 'h':
unsigned int len = strlen(argv[i]); hirom = 1;
if(len == 1) break;
case 'q':
quiet = 1;
break;
default:
usage(); 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];
} }
} }
unsigned int pos = 0;
int ref_complete, upd_complete = 0;
const char * tempfile = getenv("QDINC_FILE"); if (optind >= argc) {
usage();
}
if(tempfile == 0) filename = argv[optind];
tempfile = default_tempfile;
char * outfile = malloc(strlen(tempfile) + sizeof(".out")); int j,j2;
char * ext = stpcpy(outfile, tempfile); int ref_complete, upload_complete = 0;
const char * tempfile_name = getenv("QDINC_FILE");
if(tempfile_name == 0)
tempfile_name = default_tempfile;
char * outfile = malloc(strlen(tempfile_name) + sizeof(".out"));
char * ext = stpcpy(outfile, tempfile_name);
strcpy(ext, ".out"); strcpy(ext, ".out");
FILE * temp_file = fopen(outfile, "wb");
FILE * out = fopen(outfile, "wb"); if(temp_file == 0)
if(out == 0)
{ {
fprintf(stderr, "Could not open file %s for writing\n", outfile); fprintf(stderr, "Could not open file %s for writing\n", outfile);
exit(1); exit(1);
} }
FILE * upd = fopen(filename, "rb"); FILE * new_rom = fopen(filename, "rb");
if(upd == 0) if(new_rom == 0)
{ {
fprintf(stderr, "Could not open file %s\n", argv[3]); fprintf(stderr, "Could not open file %s\n", argv[3]);
exit(1); exit(1);
} }
fseek(upd, 0, SEEK_END); fseek(new_rom, 0, SEEK_END);
unsigned int size = ftell(upd); unsigned int size = ftell(new_rom);
if(header) if(header)
{ {
@ -106,12 +104,12 @@ int main(int argc, char * argv[])
size = 0; size = 0;
else else
size -= 512; size -= 512;
fseek(upd, 512, SEEK_SET); fseek(new_rom, 512, SEEK_SET);
} }
else else
rewind(upd); rewind(new_rom);
if(size > 0x200000) if(size > _16MBIT)
{ {
fprintf(stderr, "Input file is larger than supported by Quickdev16\n"); fprintf(stderr, "Input file is larger than supported by Quickdev16\n");
exit(1); exit(1);
@ -119,7 +117,7 @@ int main(int argc, char * argv[])
FILE * ref = 0; FILE * ref = 0;
if(!init) if(!init)
ref = fopen(tempfile, "rb"); ref = fopen(tempfile_name, "rb");
ref_complete = (ref == 0); ref_complete = (ref == 0);
@ -138,27 +136,23 @@ int main(int argc, char * argv[])
exit(1); exit(1);
} }
#ifndef QDINC_OLD_FIRMWARE
cnt = usb_control_msg(handle, cnt = usb_control_msg(handle,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_TYPE_VENDOR | USB_RECIP_DEVICE |
USB_ENDPOINT_OUT, USB_SET_LAODER, 0, 0, NULL, USB_ENDPOINT_OUT, USB_SET_LOADER, 0, 0, NULL,
0, 5000); 0, 5000);
#endif
cnt = usb_control_msg(handle, cnt = usb_control_msg(handle,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_TYPE_VENDOR | USB_RECIP_DEVICE |
USB_ENDPOINT_OUT, USB_MODE_AVR, 0, 0, NULL, USB_ENDPOINT_OUT, USB_MODE_AVR, 0, 0, NULL,
0, 5000); 0, 5000);
#ifdef QDINC_OLD_FIRMWARE
/* wait for the loader to depack */
usleep(500000);
#else
usleep(50000); usleep(50000);
#endif
cnt = usb_control_msg(handle, cnt = usb_control_msg(handle,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
USB_BULK_UPLOAD_INIT, (hirom ? 16 : 15) , (hirom ? 32 : 64) /* << this is wrong, but only used for progress display */, NULL, 0, 5000); USB_BULK_UPLOAD_INIT,
(hirom ? HIROM_BANK_SIZE_SHIFT : LOROM_BANK_SIZE_SHIFT) ,
(hirom ? HIROM_BANK_COUNT_SHIFT : LOROM_BANK_COUNT_SHIFT) /* << this is wrong, but only used for progress display */,
NULL, 0, 5000);
unsigned char diffblock[256]; unsigned char diffblock[256];
unsigned int blocklen = 0; unsigned int blocklen = 0;
@ -166,31 +160,31 @@ int main(int argc, char * argv[])
unsigned int position = 0; unsigned int position = 0;
unsigned int last_position = (unsigned int)(-1); unsigned int last_position = (unsigned int)(-1);
unsigned char lastchar; unsigned char lastchar = 0;
unsigned int transmitted = 0; unsigned int transmitted = 0;
char progress[21]; char progress[21];
memset(progress,' ',19);
for(i = 0; i < 20; i++)
progress[i] = ' ';
progress[20] = 0; progress[20] = 0;
j = 0; j = 0;
j2 = 0; j2 = 0;
while(!upd_complete) while(!upload_complete)
{ {
int msg = 0; int msg = 0;
unsigned char updchar = fgetc(upd); unsigned char updchar = fgetc(new_rom);
unsigned char refchar; unsigned char refchar=0;
if(feof(upd))
if(feof(new_rom))
{ {
msg = 1; msg = 1;
upd_complete = 1; upload_complete = 1;
} }
else else
fputc(updchar, out); fputc(updchar, temp_file);
if(!ref_complete && !upd_complete)
if(!ref_complete && !upload_complete)
{ {
refchar = fgetc(ref); refchar = fgetc(ref);
if(feof(ref)) if(feof(ref))
@ -198,21 +192,11 @@ int main(int argc, char * argv[])
} }
int match = (ref_complete || updchar != refchar); int match = (ref_complete || updchar != refchar);
#ifdef QDINC_OLD_FIRMWARE if(upload_complete)
if(position < 64 * 1024)
match = 1;
#endif
if(upd_complete)
match = 0; match = 0;
if(match) if(match)
{ {
#ifdef QDINC_OLD_FIRMWARE
if(blocklen == 0 && (position & (hirom ? 0xFFFF : 0x7FFF)) == 0 && position != 0 && position != last_position)
{
diffblock[0] = lastchar;
blocklen++;
}
#endif
diffblock[blocklen] = updchar; diffblock[blocklen] = updchar;
blocklen++; blocklen++;
reallen = blocklen; reallen = blocklen;
@ -224,7 +208,7 @@ int main(int argc, char * argv[])
} }
position++; position++;
if((reallen > 0 && upd_complete) || ((!upd_complete) && (( (blocklen - reallen) >= QDINC_RANGE && !match) || blocklen == QDINC_SIZE)) ) if((reallen > 0 && upload_complete) || ((!upload_complete) && (( (blocklen - reallen) >= QDINC_RANGE && !match) || blocklen == QDINC_SIZE)) )
{ {
int consecutive = (last_position == position - blocklen); int consecutive = (last_position == position - blocklen);
unsigned int begin = position - blocklen; unsigned int begin = position - blocklen;
@ -243,7 +227,7 @@ int main(int argc, char * argv[])
msg = 1; msg = 1;
} }
if(msg) if(!quiet && msg)
{ {
for(; j < (position - 1) * 20 / size; j++) for(; j < (position - 1) * 20 / size; j++)
progress[j] = '='; progress[j] = '=';
@ -267,16 +251,17 @@ int main(int argc, char * argv[])
if(feof(ref)) if(feof(ref))
ref_complete = 1; ref_complete = 1;
else else
fputc(refchar, out); fputc(refchar, temp_file);
} }
fclose(out); fclose(temp_file);
fclose(upd); fclose(new_rom);
fclose(ref); if (!init)
fclose(ref);
if(rename(outfile, tempfile)) if(rename(outfile, tempfile_name))
{ {
fprintf(stderr, "Could not replace tempfile %s\n", tempfile); fprintf(stderr, "Could not replace tempfile %s\n", tempfile_name);
exit(1); exit(1);
} }
@ -285,18 +270,15 @@ int main(int argc, char * argv[])
USB_ENDPOINT_OUT, USB_BULK_UPLOAD_END, 0, 0, NULL, USB_ENDPOINT_OUT, USB_BULK_UPLOAD_END, 0, 0, NULL,
0, 5000); 0, 5000);
#ifndef QDINC_OLD_FIRMWARE
cnt = usb_control_msg(handle, cnt = usb_control_msg(handle,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_TYPE_VENDOR | USB_RECIP_DEVICE |
USB_ENDPOINT_OUT, USB_SET_LAODER, 1, 1, NULL, USB_ENDPOINT_OUT, USB_SET_LOADER, 1, 1, NULL,
0, 5000); 0, 5000);
#endif
cnt = usb_control_msg(handle, cnt = usb_control_msg(handle,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_TYPE_VENDOR | USB_RECIP_DEVICE |
USB_ENDPOINT_OUT, USB_MODE_SNES, 0, 0, NULL, USB_ENDPOINT_OUT, USB_MODE_SNES, 0, 0, NULL,
0, 5000); 0, 5000);
return 0;
printf("Done"); return 0;
} }

View File

@ -4,9 +4,6 @@
#define QDINC_RANGE 96 #define QDINC_RANGE 96
#define QDINC_SIZE 254 #define QDINC_SIZE 254
// makes this compatible with a bug in older quickdev firmware revisions
//#define QDINC_OLD_FIRMWARE
/* quickdev protocol defines */ /* quickdev protocol defines */
#define USB_UPLOAD_INIT 0 #define USB_UPLOAD_INIT 0
@ -25,7 +22,7 @@
#define USB_MODE_SNES 10 #define USB_MODE_SNES 10
#define USB_MODE_AVR 11 #define USB_MODE_AVR 11
#define USB_AVR_RESET 12 #define USB_AVR_RESET 12
#define USB_SET_LAODER 13 #define USB_SET_LOADER 13
/* -------------------------- Device Description --------------------------- */ /* -------------------------- Device Description --------------------------- */