Advertisement
Guest User

loader64.c

a guest
Dec 31st, 2014
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.21 KB | None | 0 0
  1. /* loader64.c
  2.    libftdi Everdrive 64 USB-tool
  3.    by saturnu
  4. */
  5.  
  6. #include <stdio.h>
  7. #include <ftdi.h>
  8. #include <string.h>
  9. #include <sys/stat.h>
  10. #include <unistd.h>
  11. #include <libgen.h>
  12. #include "gopt.h"
  13. #include "loader64.h"
  14.  
  15. int main( int argc, const char **argv )
  16. {
  17.    
  18.     //usb buffer
  19.     char send_buff[512];
  20.     char recv_buff[512];    
  21.    
  22.     int dbg=0;
  23.    
  24.     int arg_fail=1;
  25.    
  26.     //rom filename
  27.     const char *filename;
  28.    
  29.     //verbosity level 0-2
  30.     int verbosity;
  31.     int i,print_help;  
  32.    
  33.     void *options= gopt_sort( & argc, argv, gopt_start(
  34.     gopt_option( 'h', 0, gopt_shorts( 'h' ), gopt_longs( "help" )),
  35.     gopt_option( 'z', 0, gopt_shorts( 'z' ), gopt_longs( "version" )),
  36.     gopt_option( 'v', GOPT_REPEAT, gopt_shorts( 'v' ), gopt_longs( "verbose" )),
  37.     gopt_option( 'r', 0, gopt_shorts( 'r' ), gopt_longs( "read" )),
  38.     gopt_option( 'w', 0, gopt_shorts( 'w' ), gopt_longs( "write" )),
  39.     gopt_option( 't', 0, gopt_shorts( 't' ), gopt_longs( "transfer" )),        
  40.     gopt_option( 'p', 0, gopt_shorts( 'p' ), gopt_longs( "pifboot" )),
  41.     gopt_option( 'f', GOPT_ARG, gopt_shorts( 'f' ), gopt_longs( "file" ))));   
  42.    
  43.    
  44.  
  45.   if( gopt( options, 'h' ) ){
  46.     fprintf( stdout, "Syntax: sudo ./loader64 [options] ...\n\n");
  47.     fprintf( stdout, "loader64 - Everdrive64 USB-tool\n" );
  48.     fprintf( stdout, "by saturnu <tt@anpa.nl>\n\n" );
  49.     fprintf( stdout, " -h, --help\t\tdisplay this help and exit\n" );    
  50.     fprintf( stdout, " -v, --verbose\t\tverbose\n" );
  51.     fprintf( stdout, " -f, --file=rom.z64\trom in z64 format\n" );
  52.     //TODO:
  53.     fprintf( stdout, " -r, --read\t\tread from sdram\n" );
  54.     fprintf( stdout, " -w, --write\t\twrite to sdram\n" );    
  55.     fprintf( stdout, " -t, --name\t\ttransfer file to sdcard\n" );      
  56.     fprintf( stdout, " -p, --pifboot\t\tsimulate pifboot CIC-6102\n" );
  57.     fprintf( stdout, " -z, --version\t\tversion\n" );    
  58.                
  59.     exit( EXIT_SUCCESS );
  60.   }
  61.  
  62.  
  63.   //show info without options
  64.   print_help=1;
  65.  
  66.   if( gopt( options, 'p' ) ||  gopt( options, 't' ) || gopt( options, 'w' ) || gopt( options, 'r') || gopt( options, 'z') || gopt( options, 'h') || gopt( options, 'v') ){ 
  67.  
  68.         print_help = 0;
  69.          if( gopt( options, 'p' ) ||  gopt( options, 't' ) || gopt( options, 'w' ) || gopt( options, 'r' ) )
  70.             arg_fail = 0;
  71.   }
  72.  
  73.  
  74.   if( gopt( options, 'w' ) && gopt( options, 'r' )){
  75.    
  76.     fprintf( stdout, "error: could not read and write at the same time\n" );
  77.     exit( EXIT_SUCCESS );
  78.   }
  79.  
  80.     if( gopt( options, 'w' ) && gopt( options, 'p' )){
  81.    
  82.     fprintf( stdout, "error: use pifboot separately\n" );
  83.     exit( EXIT_SUCCESS );
  84.   }
  85.  
  86.  
  87.   if( gopt( options, 'z' ) ){
  88.    
  89.     fprintf( stdout, "loader64 version v%d.%d\n", MAJOR_VERSION, MINOR_VERSION );
  90.     exit( EXIT_SUCCESS );
  91.   }
  92.  
  93.  
  94.   verbosity = gopt( options, 'v' );
  95.  
  96.  
  97.   if( verbosity > 1 )
  98.     fprintf( stderr, "being really verbose\n" );
  99.  
  100.   else if( verbosity )
  101.     fprintf( stderr, "being verbose\n" );
  102.  
  103.  
  104. //options are ok - init ftdi
  105. if(!arg_fail){
  106.  
  107.     int ret;
  108.     struct ftdi_context *ftdi;
  109.     if ((ftdi = ftdi_new()) == 0)
  110.    {
  111.         fprintf(stderr, "ftdi_new failed\n");
  112.         return EXIT_FAILURE;
  113.     }
  114.  
  115.     if ((ret = ftdi_usb_open(ftdi, USB_VENDOR, USB_DEVICE)) < 0)
  116.     {
  117.         fprintf(stderr, "unable to open ftdi device: %d (%s)\n", ret, ftdi_get_error_string(ftdi));
  118.         ftdi_free(ftdi);
  119.         return EXIT_FAILURE;
  120.     }else{
  121.         //read/write timeout e.g. 500ms
  122.         ftdi->usb_read_timeout = USB_READ_TIMEOUT;
  123.         ftdi->usb_write_timeout = USB_WRITE_TIMEOUT;
  124.     }
  125.  
  126.     if (ftdi->type == TYPE_R)
  127.     {
  128.         unsigned int chipid;
  129.         if(verbosity >= 1){
  130.             printf("ftdi_read_chipid: %d\n", ftdi_read_chipid(ftdi, &chipid));
  131.             printf("FTDI chipid: %X\n", chipid);
  132.         }
  133.     }
  134.    
  135.    
  136.     //init usb transfer buffer
  137.     memset(send_buff, 0, 512);
  138.     memset(recv_buff, 0, 512);    
  139.    
  140.     send_buff[0]='C';
  141.     send_buff[1]='M';
  142.     send_buff[2]='D';
  143.     send_buff[3]='T'; //test        
  144.    
  145.     int ret_s = ftdi_write_data(ftdi, send_buff, 512);
  146.  
  147.    
  148.     if(verbosity >= 1)    
  149.     printf("send: %i bytes\n",ret_s);
  150.    
  151.     sleep(1);
  152.     int ret_r = ftdi_read_data(ftdi, recv_buff, 512);
  153.    
  154.     if(verbosity >= 1)    
  155.     printf("recv: %i bytes\n",ret_r);
  156.    
  157.     if(recv_buff[3]=='k'){
  158.      printf("init test: ok\n");
  159.     }
  160.     else{
  161.         printf("init test: faild - ED64 not running?\n");
  162.         ftdi_free(ftdi);
  163.         exit( EXIT_SUCCESS );
  164.     }
  165.  
  166.  
  167.     memset(send_buff, 0, 512);
  168.     memset(recv_buff, 0, 512);  
  169.     ret_s = 0;
  170.     ret_r = 0;
  171.  
  172.     //pifboot
  173.     if( gopt( options, 'p' ) ){
  174.         send_buff[0]='C';
  175.         send_buff[1]='M';
  176.         send_buff[2]='D';
  177.         send_buff[3]='S'; //pif boot
  178.            
  179.         ret_s = ftdi_write_data(ftdi, send_buff, 512);
  180.        
  181.         if(verbosity >= 1)
  182.         printf("send: %i bytes\n",ret_s);
  183.         printf("pif simulation instructed...\n");
  184.        
  185.     }else //dump
  186.     if( gopt( options, 't' ) ){
  187.        
  188.         if( gopt_arg( options, 'f', & filename ) && strcmp( filename, "-" ) ){ 
  189.         //append romane
  190.             snprintf(send_buff+8, 504, "%s", basename((char *)filename));
  191.         }
  192.        
  193.         FILE *fp;
  194.         fp=fopen(filename, "rb");
  195.         int fsize;
  196.  
  197.         struct stat st;
  198.         stat(filename, &st);
  199.         fsize = st.st_size;
  200.  
  201.         fclose(fp);
  202.  
  203.         if(verbosity >= 1)
  204.         printf("file_size: %d\n",fsize);
  205.  
  206.         send_buff[0]='C';
  207.         send_buff[1]='M';
  208.         send_buff[2]='D';
  209.         send_buff[3]='N'; //name boot
  210.  
  211.  
  212.         //append filesize
  213.         snprintf(send_buff+116, 11, "%d", fsize);
  214.            
  215.         ret_s = ftdi_write_data(ftdi, send_buff, 512);
  216.        
  217.         if(verbosity >= 1)
  218.         printf("send: %i bytes\n",ret_s);
  219.         printf("pname+size send...\n");
  220.        
  221.     }else //write  
  222.     if( gopt( options, 'w' ) ){
  223.        
  224.  
  225.          if( gopt_arg( options, 'f', & filename ) && strcmp( filename, "-" ) ){
  226.              
  227.             FILE *fp;
  228.             fp=fopen(filename, "rb");
  229.             int fsize;
  230.  
  231.             struct stat st;
  232.             stat(filename, &st);
  233.             fsize = st.st_size;
  234.  
  235.             if(verbosity >= 1)
  236.             printf("test_size: %d\n",fsize);
  237.  
  238.  
  239.             int length = (int) fsize;
  240.            
  241.             if(verbosity >= 1)         
  242.             printf("length: %d\n",length);
  243.            
  244.             if (((length / 0x10000) * 0x10000) != fsize) {
  245.                 length = (int) (((fsize / 0x10000) * 0x10000) + 0x10000);
  246.             }
  247.  
  248.  
  249.             if(verbosity >= 2)         
  250.             printf("length_buffer: %d\n",length);
  251.  
  252.             //FILE_CHUNK default 0x8000
  253.             char buffer[FILE_CHUNK];
  254.             memset(buffer, 0, FILE_CHUNK);
  255.            
  256.             if(verbosity >= 2)         
  257.             printf("buffer created\n");
  258.            
  259.            
  260.             //tiny rom fill-mode
  261.              if (length < 0x200000){
  262.                  
  263.                 if(verbosity >= 1)
  264.                 printf("needs filling\n");
  265.                
  266.                 send_buff[0]='C';
  267.                 send_buff[1]='M';
  268.                 send_buff[2]='D';
  269.                 send_buff[3]='F'; //fill
  270.  
  271.                 ret_s = ftdi_write_data(ftdi, send_buff, 512);
  272.  
  273.                 if(verbosity >= 1)
  274.                     printf("send: %i bytes\n",ret_s);
  275.  
  276.                 sleep(1);
  277.                 int ret_r = ftdi_read_data(ftdi, recv_buff, 512);
  278.  
  279.                 if(verbosity >= 1)    
  280.                     printf("recv: %i bytes\n",ret_r);
  281.  
  282.                 if(recv_buff[3]=='k'){
  283.                     printf("fill test: ok\n");
  284.                     memset(send_buff, 0, 512);
  285.                     memset(recv_buff, 0, 512);  
  286.                     ret_s = 0;
  287.                     ret_r = 0;
  288.  
  289.                 }else{
  290.                     printf("fill test: error\n");
  291.                     ftdi_free(ftdi);
  292.                     exit( EXIT_SUCCESS );              
  293.                 }
  294.              }
  295.            
  296.            
  297.             send_buff[0]='C';
  298.             send_buff[1]='M';
  299.             send_buff[2]='D';
  300.             send_buff[3]='W'; //write
  301.             if(!dbg){
  302.                 send_buff[4]=0; //offset
  303.                 send_buff[5]=0; //offset       
  304.             }else{
  305.                 send_buff[4]=0x40; //32mb offset
  306.                 send_buff[5]=0; //offset           
  307.             }
  308.             send_buff[6] = (char) ((( length) / 0x200) >> 8); //length
  309.             send_buff[7] = (char) (length / 0x200); //length
  310.  
  311.             ret_s = ftdi_write_data(ftdi, send_buff, 512);
  312.  
  313.             if(verbosity >= 1)
  314.                 printf("send write cmd: %i bytes\n",ret_s);
  315.  
  316.             //now write in 0x8000 chunks -> 32768
  317.  
  318.             printf("sending...\n");
  319.             int s;
  320.             for(s = 0;s < length; s += 0x8000){
  321.            
  322.                 if (s == 0x2000000 && dbg==0) //step 1024
  323.                 {
  324.                     memset(send_buff, 0, 512);
  325.                     memset(recv_buff, 0, 512);  
  326.                     ret_s = 0;
  327.                     ret_r = 0;
  328.                    
  329.                     send_buff[0]='C';
  330.                     send_buff[1]='M';
  331.                     send_buff[2]='D';
  332.                     send_buff[3]='W'; //write
  333.                     send_buff[4]=0x40; //32mb offset
  334.                     send_buff[5]=0; //offset
  335.                     send_buff[6] = (char) (( ( length - 0x2000000) / 0x200) >> 8); //length
  336.                     send_buff[7] = (char) (( length - 0x2000000) / 0x200); //length
  337.  
  338.                     ret_s = ftdi_write_data(ftdi, send_buff, 512);
  339.  
  340.                     if(verbosity >= 1)
  341.                         printf("send offset cmd: %i bytes\n",ret_s);
  342.                 }
  343.            
  344.             //read parts to memory
  345.             int fret = fread(buffer, sizeof(buffer[0]), sizeof(buffer)/sizeof(buffer[0]), fp);
  346.            
  347.             ret_s = ftdi_write_data(ftdi, buffer,  0x8000);
  348.            
  349.                 if ((s % 0x80000) == 0)
  350.                 {
  351.                     if(verbosity >= 1 && s!=0)
  352.                     printf("part sent: %i\n",s);
  353.                 }
  354.             }
  355.            
  356.             printf("upload done...\n",  argv[0]);
  357.        
  358.         }      
  359.        
  360.        
  361.     }else //TODO: read
  362.     if( gopt( options, 'r' ) ){
  363.        
  364.         if( gopt_arg( options, 'f', & filename ) && strcmp( filename, "-" ) ){ 
  365.              
  366.                 FILE *fp;
  367.                 fp=fopen(filename, "a+b");
  368.                
  369.                 //FILE_CHUNK default 0x8000
  370.                 char buffer[FILE_CHUNK];
  371.                 memset(buffer, 0, FILE_CHUNK);
  372.                
  373.                
  374.                 int length=0x8000*4; //smurfs
  375.                
  376.  
  377.                 send_buff[0]='C';
  378.                 send_buff[1]='M';
  379.                 send_buff[2]='D';
  380.                 send_buff[3]='R'; //read
  381.                 send_buff[4]=0x40; //32mb offset
  382.                 send_buff[5]=0; //offset   
  383.                 send_buff[6] = (char) ((( length) / 0x200) >> 8); //length
  384.                 send_buff[7] = (char) (length / 0x200); //length               
  385.  
  386.                 ret_s = ftdi_write_data(ftdi, send_buff, 512);
  387.  
  388.                 if(verbosity >= 1)
  389.                     printf("send offset cmd: %i bytes\n",ret_s);
  390.  
  391.                 int s;
  392.                 for(s = 0;s < length; s += 0x8000){
  393.                
  394.                 int ret_r;
  395.                     ret_r = ftdi_read_data(ftdi, buffer, 0x8000);
  396.                     fwrite(buffer, sizeof(buffer[0]), sizeof(buffer)/sizeof(buffer[0]), fp);
  397.                
  398.                 }
  399.        
  400.             fclose(fp); /*done!*/
  401.             printf("download done...\n",  argv[0]);
  402.        
  403.         }else{
  404.         printf("where?\n");
  405.         }
  406.  
  407.     }
  408.    
  409.    
  410.    
  411.     if ((ret = ftdi_usb_close(ftdi)) < 0)
  412.     {
  413.         fprintf(stderr, "unable to close ftdi device: %d (%s)\n", ret, ftdi_get_error_string(ftdi));
  414.         ftdi_free(ftdi);
  415.         return EXIT_FAILURE;
  416.     }
  417.    
  418.    
  419.     ftdi_free(ftdi);
  420.    
  421.    
  422. }
  423.    
  424.     if(print_help){
  425.  
  426.         printf("%s: missing operand\n",  argv[0]);
  427.         printf("Try '%s --help' for more information.\n",  argv[0]);
  428.     }
  429.    
  430.    
  431.     gopt_free( options );
  432.     return EXIT_SUCCESS;
  433. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement