Explorar el Código

added a more userfriendly commandline interface to qdinc

Jannis (jix) Harder hace 14 años
padre
commit
243658c0d3
Se han modificado 2 ficheros con 154 adiciones y 17 borrados
  1. 153 16
      tools/qdinc/qdinc.c
  2. 1 1
      tools/qdinc/qdinc.h

+ 153 - 16
tools/qdinc/qdinc.c

@@ -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(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, "Could not open file %s for writing\n", outfile);
+        exit(1);
+    }
+    
+    
+    FILE * upd = fopen(filename, "rb");
     
     if(upd == 0)
     {
-        fprintf(stderr, "couldn't open file %s\n", argv[3]);
+        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");
 }

+ 1 - 1
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