Switched to getopt, fixed minor issues and some cleanups.
This commit is contained in:
parent
d471173fcc
commit
e0dd846013
@ -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)
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 --------------------------- */
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user