f2a.c 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689
  1. /*
  2. f2a.c - Flash 2 Advance support for uCON64
  3. Copyright (c) 2003 Ulrich Hecht <uli@emulinks.de>
  4. Copyright (c) 2003 - 2004 David Voswinkel <d.voswinkel@netcologne.de>
  5. Copyright (c) 2004 NoisyB
  6. Copyright (c) 2004 - 2005, 2015 dbjh
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. #ifdef HAVE_CONFIG_H
  20. #include "config.h"
  21. #endif
  22. #include <errno.h>
  23. #include <fcntl.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #ifdef _MSC_VER
  27. #pragma warning(push)
  28. #pragma warning(disable: 4820) // 'bytes' bytes padding added after construct 'member_name'
  29. #endif
  30. #include <sys/stat.h>
  31. #ifdef _MSC_VER
  32. #pragma warning(pop)
  33. #endif
  34. #if defined _WIN32 || defined __MSDOS__
  35. #ifdef _MSC_VER
  36. #pragma warning(push)
  37. #pragma warning(disable: 4820) // 'bytes' bytes padding added after construct 'member_name'
  38. #endif
  39. #include <sys/timeb.h>
  40. #ifdef _MSC_VER
  41. #pragma warning(pop)
  42. #endif
  43. #else
  44. #include <sys/time.h>
  45. #endif
  46. #ifdef USE_USB
  47. #include <stdarg.h>
  48. #ifdef __unix__
  49. #include <sys/utsname.h>
  50. #include <sys/wait.h>
  51. #endif
  52. #include "misc/usb.h"
  53. #endif // USE_USB
  54. #include "misc/archive.h"
  55. #include "misc/bswap.h"
  56. #include "misc/file.h"
  57. #include "misc/misc.h"
  58. #include "misc/parallel.h"
  59. #include "misc/property.h"
  60. #include "ucon64_misc.h"
  61. #include "console/gba.h"
  62. #include "backup/f2a.h"
  63. #if defined USE_PARALLEL || defined USE_USB
  64. static st_ucon64_obj_t f2a_obj[] =
  65. {
  66. {UCON64_GBA, WF_DEFAULT | WF_STOP | WF_NO_ROM},
  67. {UCON64_GBA, WF_DEFAULT | WF_STOP},
  68. {UCON64_GBA, WF_STOP | WF_NO_ROM}
  69. };
  70. #endif
  71. const st_getopt2_t f2a_usage[] =
  72. {
  73. {
  74. NULL, 0, 0, 0,
  75. NULL, "Flash 2 Advance (Ultra)"/*"2003 Flash2Advance http://www.flash2advance.com"*/,
  76. NULL
  77. },
  78. #if defined USE_PARALLEL || defined USE_USB
  79. {
  80. "xf2a", 0, 0, UCON64_XF2A,
  81. NULL, "send/receive ROM to/from Flash 2 Advance (Ultra); " OPTION_LONG_S "port=PORT\n"
  82. "receives automatically (32 Mbits) when ROM does not exist",
  83. &f2a_obj[0]
  84. },
  85. {
  86. "xf2amulti", 1, 0, UCON64_XF2AMULTI, // send only
  87. "SIZE", "send multiple ROMs to Flash 2 Advance (Ultra); specify a\n"
  88. "loader in the configuration file; " OPTION_LONG_S "port=PORT",
  89. &f2a_obj[1]
  90. },
  91. {
  92. "xf2ac", 1, 0, UCON64_XF2AC,
  93. "N", "receive N Mbits of ROM from Flash 2 Advance (Ultra);\n" OPTION_LONG_S "port=PORT",
  94. &f2a_obj[2]
  95. },
  96. {
  97. "xf2as", 0, 0, UCON64_XF2AS,
  98. NULL, "send/receive SRAM to/from Flash 2 Advance (Ultra); " OPTION_LONG_S "port=PORT\n"
  99. "receives automatically when SRAM does not exist",
  100. &f2a_obj[2]
  101. },
  102. {
  103. "xf2ab", 1, 0, UCON64_XF2AB,
  104. "BANK", "send/receive SRAM to/from Flash 2 Advance (Ultra) BANK\n"
  105. "BANK should be a number >= 1; " OPTION_LONG_S "port=PORT\n"
  106. "receives automatically when SRAM does not exist",
  107. &f2a_obj[2]
  108. },
  109. #endif
  110. {NULL, 0, 0, 0, NULL, NULL, NULL}
  111. };
  112. #ifdef USE_USB
  113. #define EZDEV "/proc/ezusb/dev0"
  114. #define F2A_FIRM_SIZE 23053
  115. #define CMD_GETINF 0x05 // get info on the system status
  116. #define CMD_MULTIBOOT1 0xff // boot up the GBA stage 1, no parameters
  117. #define CMD_MULTIBOOT2 0 // boot up the GBA stage 2, f2a_sendmsg_t.size has to be set
  118. #define SENDMSG_SIZE 63 // (sizeof (f2a_sendmsg_t) - 1)
  119. typedef struct
  120. {
  121. unsigned int command; // command to execute, see below
  122. unsigned int size; // size of data block to read/write
  123. unsigned int pad1[2];
  124. unsigned int magic; // magic number, see below
  125. unsigned int pad2[3];
  126. unsigned int unknown; // no idea what this is for, seems to have to be 0xa for write, 0x7 for read
  127. unsigned int address; // base address for read/write
  128. unsigned int sizekb; // size of data block to read/write in kB
  129. unsigned char pad3[5 * 4 /*-1*/];
  130. /*
  131. For some reason the original software uses a 63 bytes structure for outgoing
  132. messages, not 64 as it does for incoming messages, hence the "-1". It all
  133. seems to work fine with 64 bytes, too, and I therefore suspect this to be a
  134. bug in the original software.
  135. */
  136. // we use SENDMSG_SIZE to solve the problem - dbjh
  137. } /*__attribute__ ((packed))*/ f2a_sendmsg_t;
  138. typedef struct
  139. {
  140. unsigned char data[64];
  141. } f2a_recvmsg_t;
  142. static int f2a_init_usb (void);
  143. static int f2a_connect_usb (void);
  144. static int f2a_info (f2a_recvmsg_t *rm);
  145. static int f2a_boot_usb (const char *ilclient_fname);
  146. static int f2a_read_usb (int address, int size, const char *filename);
  147. static int f2a_write_usb (int n_files, char **files, int address);
  148. static usb_dev_handle *f2a_handle;
  149. #endif // USE_USB
  150. #ifdef USE_PARALLEL
  151. #define LOGO_ADDR 0x06000000
  152. #define EXEC_STUB 0x03002000
  153. #define ERASE_STUB 0x03000c00
  154. #define LOGO_SIZE 76800
  155. #define BOOT_SIZE 18432
  156. #define FLIP 1
  157. #define HEAD 1
  158. #define EXEC 1
  159. #define PP_CMD_WRITEROM 0x0a
  160. #define PP_CMD_ERASE 0x0b
  161. #define PP_HEAD_BOOT 0x01
  162. typedef struct
  163. {
  164. unsigned int pad1[3];
  165. unsigned int magic;
  166. unsigned int command;
  167. unsigned int address;
  168. unsigned int sizekb;
  169. unsigned int pad2;
  170. unsigned int exec;
  171. unsigned int exec_stub;
  172. unsigned char pad3[984];
  173. } /*__attribute__ ((packed))*/ f2a_msg_cmd_t; // packed attribute is not necessary
  174. static int f2a_boot_par (const char *ilclient2_fname, const char *illogo_fname);
  175. static int f2a_write_par (int n_files, char **files, unsigned int address);
  176. static int f2a_read_par (unsigned int start, unsigned int size,
  177. const char *filename);
  178. //static int f2a_erase_par (unsigned int start, unsigned int size);
  179. static int f2a_send_buffer_par (int cmd, int address,
  180. int size, const unsigned char *resource, int head,
  181. int flip, unsigned int exec, int mode);
  182. //static int f2a_send_cmd_par (int cmd, int address, int size);
  183. static int f2a_exec_cmd_par (int cmd, int address, int size);
  184. static int f2a_receive_data_par (int cmd, int address, int size,
  185. const char *filename, int flip);
  186. static int f2a_send_head_par (int cmd, int size);
  187. static int f2a_send_raw_par (unsigned char *buffer, int len);
  188. static int f2a_receive_raw_par (unsigned char *buffer, int len);
  189. static int f2a_wait_par (void);
  190. static int parport_init (unsigned short port, int target_delay);
  191. static int parport_init_delay (int target);
  192. static void parport_out31 (unsigned char val);
  193. static void parport_out91 (unsigned char val);
  194. static void parport_nop (void);
  195. static unsigned short f2a_pport;
  196. #ifdef DEBUG
  197. static int parport_debug = 1;
  198. #else
  199. static int parport_debug = 0;
  200. #endif
  201. static int parport_nop_cntr;
  202. #endif // USE_PARALLEL
  203. #if defined USE_PARALLEL || defined USE_USB
  204. #define LOADER_SIZE 32768
  205. #define CMD_WRITEDATA 0x06 // write data to RAM/ROM(USB)/SRAM
  206. #define CMD_READDATA 0x07 // read data from RAM/ROM(USB)/SRAM
  207. #define MAGIC_NUMBER 0xa46e5b91 // needs to be properly set for almost all commands
  208. enum
  209. {
  210. UPLOAD_FAILED = 0,
  211. CANNOT_GET_FILE_SIZE,
  212. UPLOAD_FILE
  213. };
  214. static time_t starttime = 0;
  215. static const char *f2a_msg[] = {
  216. "ERROR: Upload failed\n",
  217. "ERROR: Cannot determine size of file \"%s\"\n",
  218. "Uploading %s, %d kB, padded to %d kB\n",
  219. NULL
  220. };
  221. #endif
  222. #ifdef USE_USB
  223. #if defined __unix__ && !defined __CYGWIN__
  224. static int
  225. exec (const char *program, int argc, ...)
  226. /*
  227. This function is needed in order to execute a program with the same
  228. permissions as we have. In this way a suid root uCON64 executable can execute
  229. programs that require root privileges. We cannot use system(), because it
  230. might drop privileges.
  231. argc should be the number of _arguments_ (excluding the program name itself).
  232. DON'T move this function to misc.c. It's only necessary on Linux 2.5 (and
  233. later) for the USB version of the F2A. It's hard to be more system dependent
  234. than that. - dbjh
  235. */
  236. {
  237. va_list argptr;
  238. int status;
  239. argc++;
  240. va_start (argptr, argc);
  241. if (fork () == 0)
  242. {
  243. int n;
  244. char *argv[argc + 1], *arg;
  245. if ((argv[0] = strdup (program)) == NULL)
  246. {
  247. fprintf (stderr, ucon64_msg[BUFFER_ERROR], strlen (program) + 1);
  248. exit (1);
  249. }
  250. for (n = 1; n < argc; n++)
  251. {
  252. arg = (char *) va_arg (argptr, char *); // get next argument
  253. if ((argv[n] = strdup (arg)) == NULL)
  254. {
  255. fprintf (stderr, ucon64_msg[BUFFER_ERROR], strlen (arg) + 1);
  256. exit (1);
  257. }
  258. }
  259. argv[n] = 0;
  260. setuid (geteuid ());
  261. setgid (getegid ());
  262. if (execv (argv[0], (char **) argv))
  263. { // error in info page: return value can be != 1
  264. // fprintf (stderr, "ERROR: %s\n", strerror (errno));
  265. exit (1);
  266. }
  267. }
  268. wait (&status);
  269. va_end (argptr);
  270. return status;
  271. }
  272. #endif // __unix__ && !__CYGWIN__
  273. static int
  274. f2a_init_usb (void)
  275. {
  276. f2a_recvmsg_t rm;
  277. char iclientu_fname[FILENAME_MAX];
  278. #ifdef _MSC_VER
  279. #pragma warning(push)
  280. #pragma warning(disable: 4127) // conditional expression is constant
  281. #endif
  282. if (sizeof (f2a_recvmsg_t) != 64)
  283. {
  284. fprintf (stderr, "ERROR: The size of f2a_recvmsg_t is not 64 bytes.\n"
  285. " Please correct the source code or send a bug report\n");
  286. exit (1);
  287. }
  288. if (sizeof (f2a_sendmsg_t) != 64)
  289. {
  290. fprintf (stderr, "ERROR: The size of f2a_sendmsg_t is not 64 bytes.\n"
  291. " Please correct the source code or send a bug report\n");
  292. exit (1);
  293. }
  294. #ifdef _MSC_VER
  295. #pragma warning(pop)
  296. #endif
  297. memset (&rm, 0, sizeof (rm));
  298. if (f2a_connect_usb ())
  299. {
  300. fprintf (stderr, "ERROR: Could not connect to F2A USB linker\n");
  301. exit (1); // fatal
  302. }
  303. f2a_info (&rm);
  304. if (rm.data[0] == 0)
  305. {
  306. const char *p = NULL;
  307. p = get_property (ucon64.configfile, "iclientu", PROPERTY_MODE_FILENAME);
  308. strncpy (iclientu_fname, p ? p : "iclientu.bin", FILENAME_MAX)[FILENAME_MAX - 1] = 0;
  309. if (f2a_boot_usb (iclientu_fname))
  310. {
  311. fprintf (stderr, "ERROR: Booting GBA client binary was not successful\n");
  312. exit (1); // fatal
  313. }
  314. f2a_info (&rm);
  315. }
  316. return 0;
  317. }
  318. static int
  319. f2a_connect_usb (void)
  320. {
  321. int result;
  322. struct usb_bus *bus;
  323. struct usb_device *dev, *f2adev = NULL;
  324. #ifdef __linux__
  325. int fp, firmware_loaded = 0;
  326. unsigned char f2afirmware[F2A_FIRM_SIZE];
  327. char f2afirmware_fname[FILENAME_MAX];
  328. const char *p = NULL;
  329. p = get_property (ucon64.configfile, "f2afirmware", PROPERTY_MODE_FILENAME);
  330. strncpy (f2afirmware_fname, p ? p : "f2afirm.hex", FILENAME_MAX)[FILENAME_MAX - 1] = 0;
  331. if (ucon64_fread (f2afirmware, 0, F2A_FIRM_SIZE, f2afirmware_fname) <= 0)
  332. {
  333. fprintf (stderr, "ERROR: Could not load F2A firmware (%s)\n", f2afirmware_fname);
  334. exit (1); // fatal
  335. }
  336. #endif
  337. usb_init ();
  338. usb_find_busses ();
  339. #ifdef __linux__
  340. usb_find_devices ();
  341. for (bus = usb_busses; bus; bus = bus->next) // usb_busses is present in libusb
  342. {
  343. for (dev = bus->devices; dev; dev = dev->next)
  344. {
  345. if (dev->descriptor.idVendor == 0x547 && dev->descriptor.idProduct == 0x2131)
  346. {
  347. struct utsname info;
  348. int version;
  349. if (uname (&info) == -1)
  350. {
  351. fputs ("ERROR: Could not determine version of the running kernel\n", stderr);
  352. return -1;
  353. }
  354. version = strtol (&info.release[0], NULL, 10) * 10 +
  355. strtol (&info.release[2], NULL, 10);
  356. // example contents of info.release: "2.4.18-14custom"
  357. if (version >= 25) // Linux kernel 2.5 or later
  358. {
  359. // use fxload to upload the F2A firmware
  360. char device_path[160];
  361. int exitstatus;
  362. snprintf (device_path, 160, "/proc/bus/usb/%s/%s",
  363. bus->dirname, dev->filename);
  364. device_path[160 - 1] = 0;
  365. exitstatus = exec ("/sbin/fxload", 7, "-D", device_path, "-I",
  366. f2afirmware_fname, "-t", "an21",
  367. ucon64.quiet < 0 ? "-vv" : "-v");
  368. if (WEXITSTATUS (exitstatus))
  369. {
  370. char cmd[10 * 80];
  371. snprintf (cmd, 10 * 80, ucon64.quiet < 0 ?
  372. "/sbin/fxload -D %s -I %s -t an21 -vv" :
  373. "/sbin/fxload -D %s -I %s -t an21 -v",
  374. device_path, f2afirmware_fname);
  375. cmd[10 * 80 - 1] = 0;
  376. fprintf (stderr, "ERROR: Could not upload EZUSB firmware using fxload. Command:\n"
  377. " %s\n", cmd);
  378. return -1;
  379. }
  380. }
  381. else
  382. {
  383. int wrote, w;
  384. // Linux kernel version 2.4 or older (2.2.16 is supported by
  385. // the EZUSB2131 driver). It is possible to use fxload on
  386. // (later versions of?) Linux 2.4...
  387. if ((fp = open (EZDEV, O_WRONLY)) == -1)
  388. {
  389. fprintf (stderr, "ERROR: Could not upload EZUSB firmware (opening "
  390. EZDEV": %s)\n", strerror (errno));
  391. return -1;
  392. }
  393. // The EZUSB2131 driver (version 1.0) only accepts one line of
  394. // an Intel hex record file at a time...
  395. for (wrote = 0; wrote < F2A_FIRM_SIZE; wrote += w)
  396. {
  397. if ((w = write (fp, f2afirmware + wrote, F2A_FIRM_SIZE - wrote)) == -1)
  398. {
  399. fprintf (stderr, "ERROR: Could not upload EZUSB firmware (writing "
  400. EZDEV": %s)\n", strerror (errno));
  401. return -1;
  402. }
  403. if (ucon64.quiet < 0)
  404. printf ("Wrote %d bytes (%d-%d of %d) to "EZDEV"\n",
  405. w, wrote, wrote + w, F2A_FIRM_SIZE);
  406. }
  407. close (fp);
  408. }
  409. firmware_loaded = 1;
  410. wait2 (2000); // give the EZUSB some time to renumerate
  411. break;
  412. }
  413. }
  414. if (firmware_loaded)
  415. break;
  416. }
  417. #endif // __linux__
  418. usb_find_devices ();
  419. for (bus = usb_busses; bus; bus = bus->next)
  420. {
  421. for (dev = bus->devices; dev; dev = dev->next)
  422. {
  423. if (dev->descriptor.idVendor == 0x547 && dev->descriptor.idProduct == 0x1002)
  424. {
  425. f2adev = dev;
  426. break;
  427. }
  428. }
  429. if (f2adev)
  430. break;
  431. }
  432. if (f2adev == NULL)
  433. {
  434. fprintf (stderr, "ERROR: Could not find F2A attached to USB\n");
  435. return -1;
  436. }
  437. f2a_handle = usb_open (f2adev);
  438. result = usb_claim_interface (f2a_handle, 0x4);
  439. if (result == -1)
  440. {
  441. fprintf (stderr, "ERROR: Could not claim USB interface\n"
  442. " %s\n", usb_strerror ());
  443. return -1;
  444. }
  445. result = usb_claim_interface (f2a_handle, 0x83);
  446. if (result == -1)
  447. {
  448. fprintf (stderr, "ERROR: Could not claim USB interface\n"
  449. " %s\n", usb_strerror ());
  450. return -1;
  451. }
  452. return 0;
  453. }
  454. static int
  455. f2a_info (f2a_recvmsg_t *rm)
  456. {
  457. f2a_sendmsg_t sm;
  458. memset (&sm, 0, sizeof (f2a_sendmsg_t));
  459. memset (rm, 0, sizeof (f2a_recvmsg_t));
  460. sm.command = me2le_32 (CMD_GETINF);
  461. if (usbport_write (f2a_handle, (char *) &sm, SENDMSG_SIZE) == -1)
  462. {
  463. fprintf (stderr, "ERROR: Could not send info request\n");
  464. exit (1);
  465. }
  466. if (usbport_read (f2a_handle, (char *) rm, sizeof (f2a_recvmsg_t)) == -1)
  467. {
  468. fprintf (stderr, "ERROR: Did not receive info request\n");
  469. exit (1);
  470. }
  471. #if 0
  472. {
  473. unsigned int i;
  474. for (i = 0; i < (sizeof (f2a_sendmsg_t) / 4); i++)
  475. printf ("%-2x %08X\n", i, *(((unsigned int *) (&sm)) + i));
  476. if (ucon64.quiet < 0)
  477. {
  478. printf ("info:");
  479. for (i = 0; i < (sizeof (f2a_sendmsg_t) / 4); i++)
  480. printf (" %08X", *(((unsigned int *) (rm)) + i));
  481. fputc ('\n', stdout);
  482. }
  483. }
  484. #endif
  485. return 0;
  486. }
  487. static int
  488. f2a_boot_usb (const char *ilclient_fname)
  489. {
  490. f2a_sendmsg_t sm;
  491. unsigned int ack[16], i;
  492. char ilclient[16 * 1024];
  493. printf ("Booting GBA\n"
  494. "Uploading iLinker client\n"
  495. "Please turn OFF, then ON your GBA with SELECT and START held down\n");
  496. if (ucon64_fread (ilclient, 0, 16 * 1024, ilclient_fname) <= 0)
  497. {
  498. fprintf (stderr, "ERROR: Could not load GBA client binary (%s)\n", ilclient_fname);
  499. return -1;
  500. }
  501. // boot the GBA
  502. memset (&sm, 0, sizeof (f2a_sendmsg_t));
  503. sm.command = me2le_32 (CMD_MULTIBOOT1);
  504. usbport_write (f2a_handle, (char *) &sm, SENDMSG_SIZE);
  505. sm.command = me2le_32 (CMD_MULTIBOOT2);
  506. sm.size = me2le_32 (16 * 1024);
  507. usbport_write (f2a_handle, (char *) &sm, SENDMSG_SIZE);
  508. // send the multiboot image
  509. if (usbport_write (f2a_handle, ilclient, 16 * 1024) == -1)
  510. {
  511. fprintf (stderr, f2a_msg[UPLOAD_FAILED]);
  512. return -1;
  513. }
  514. if (usbport_read (f2a_handle, (char *) ack, 16 * 4) == -1)
  515. return -1;
  516. if (ucon64.quiet < 0)
  517. {
  518. printf ("post-boot:");
  519. for (i = 0; i < 16; i++)
  520. printf (" %08X", ack[i]);
  521. fputc ('\n', stdout);
  522. }
  523. return 0;
  524. }
  525. static int
  526. f2a_read_usb (int address, int size, const char *filename)
  527. {
  528. FILE *file;
  529. int i;
  530. f2a_sendmsg_t sm;
  531. char buffer[1024];
  532. memset (&sm, 0, sizeof (f2a_sendmsg_t));
  533. if ((file = fopen (filename, "wb")) == NULL)
  534. {
  535. fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
  536. // exit (1); for now, return, although registering usbport_close() is better
  537. return -1;
  538. }
  539. sm.command = me2le_32 (CMD_READDATA);
  540. sm.magic = me2le_32 (MAGIC_NUMBER);
  541. sm.unknown = me2le_32 (7);
  542. sm.address = me2le_32 (address);
  543. sm.size = me2le_32 (size);
  544. sm.sizekb = me2le_32 (size / 1024);
  545. if (usbport_write (f2a_handle, (char *) &sm, SENDMSG_SIZE) == -1)
  546. return -1;
  547. for (i = 0; i < size; i += 1024)
  548. {
  549. if (usbport_read (f2a_handle, buffer, 1024) == -1)
  550. {
  551. fclose (file);
  552. return -1;
  553. }
  554. if (!fwrite (buffer, 1024, 1, file)) // note order of arguments
  555. {
  556. fprintf (stderr, ucon64_msg[WRITE_ERROR], filename);
  557. fclose (file);
  558. return -1; // see comment for fopen() call
  559. }
  560. ucon64_gauge (starttime, i + 1024, size);
  561. }
  562. fclose (file);
  563. return 0;
  564. }
  565. static int
  566. f2a_write_usb (int n_files, char **files, int address)
  567. {
  568. f2a_sendmsg_t sm;
  569. int i, j, fsize, size, n, is_sram_data = address >= 0xe000000 ? 1 : 0;
  570. char buffer[1024], loader_fname[FILENAME_MAX];
  571. unsigned char loader[LOADER_SIZE];
  572. const char *p = NULL;
  573. FILE *file;
  574. // initialize command buffer
  575. memset (&sm, 0, sizeof (f2a_sendmsg_t));
  576. sm.command = me2le_32 (CMD_WRITEDATA);
  577. sm.magic = me2le_32 (MAGIC_NUMBER);
  578. sm.unknown = me2le_32 (is_sram_data ? 0x06 : 0x0a); // SRAM => 0x06, ROM => 0x0a
  579. if (n_files > 1 && !is_sram_data)
  580. {
  581. printf ("Uploading multiloader\n");
  582. p = get_property (ucon64.configfile, "gbaloader", PROPERTY_MODE_FILENAME);
  583. strncpy (loader_fname, p ? p : "loader.bin", FILENAME_MAX)[FILENAME_MAX - 1] = 0;
  584. if (ucon64_fread (loader, 0, LOADER_SIZE, loader_fname) <= 0)
  585. {
  586. fprintf (stderr, "ERROR: Could not load loader binary (%s)\n", loader_fname);
  587. return -1;
  588. }
  589. #if 0 // just use a correct loader file - dbjh
  590. ((int *) loader)[0] = me2be_32 (0x2e0000ea); // start address
  591. #endif
  592. memcpy (loader + 4, gba_logodata, GBA_LOGODATA_LEN); // + 4 for start address
  593. sm.size = me2le_32 (LOADER_SIZE);
  594. sm.address = me2le_32 (address);
  595. sm.sizekb = me2le_32 (LOADER_SIZE / 1024);
  596. if (usbport_write (f2a_handle, (char *) &sm, SENDMSG_SIZE) == -1)
  597. return -1;
  598. if (usbport_write (f2a_handle, (char *) loader, LOADER_SIZE) == -1)
  599. {
  600. fprintf (stderr, f2a_msg[UPLOAD_FAILED]);
  601. return -1;
  602. }
  603. address += LOADER_SIZE;
  604. }
  605. for (j = 0; j < n_files; j++)
  606. {
  607. if ((fsize = fsizeof (files[j])) == -1)
  608. {
  609. fprintf (stderr, f2a_msg[CANNOT_GET_FILE_SIZE], files[j]);
  610. return -1;
  611. }
  612. // Round up to 32 kB. FIXME: This has to be 128 kB for Turbo carts
  613. size = fsize;
  614. if (size & (32768 - 1))
  615. size += 32768;
  616. size &= ~(32768 - 1);
  617. printf (f2a_msg[UPLOAD_FILE], files[j], fsize / 1024, size / 1024);
  618. if ((file = fopen (files[j], "rb")) == NULL)
  619. {
  620. fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], files[j]);
  621. // exit (1); for now, return, although registering usbport_close() is better
  622. return -1;
  623. }
  624. clearerr (file);
  625. sm.size = me2le_32 (size);
  626. sm.address = me2le_32 (address);
  627. sm.sizekb = me2le_32 (size / 1024);
  628. if (usbport_write (f2a_handle, (char *) &sm, SENDMSG_SIZE) == -1)
  629. return -1;
  630. for (i = 0; i < size; i += 1024)
  631. {
  632. // printf ("writing chunk %d\n", i);
  633. n = fread (buffer, 1, 1024, file);
  634. memset (buffer + n, 0, 1024 - n);
  635. if (ferror (file))
  636. {
  637. fputc ('\n', stderr);
  638. fprintf (stderr, ucon64_msg[READ_ERROR], files[j]);
  639. fclose (file);
  640. return -1; // see comment for fopen() call
  641. }
  642. if (usbport_write (f2a_handle, buffer, 1024) == -1)
  643. return -1;
  644. ucon64_gauge (starttime, i + 1024, size);
  645. }
  646. fputc ('\n', stdout); // start new gauge on new line
  647. fclose (file);
  648. address += fsize;
  649. }
  650. return 0;
  651. }
  652. #endif // USE_USB
  653. #ifdef USE_PARALLEL
  654. static int
  655. f2a_init_par (unsigned short parport, int parport_delay)
  656. {
  657. char iclientp_fname[FILENAME_MAX], ilogo_fname[FILENAME_MAX];
  658. const char *p = NULL;
  659. if (parport_init (parport, parport_delay))
  660. {
  661. fprintf (stderr, "ERROR: Could not connect to F2A parport linker\n");
  662. exit (1); // fatal
  663. }
  664. p = get_property (ucon64.configfile, "iclientp", PROPERTY_MODE_FILENAME);
  665. strncpy (iclientp_fname, p ? p : "iclientp.bin", FILENAME_MAX)[FILENAME_MAX - 1] = 0;
  666. p = get_property (ucon64.configfile, "ilogo", PROPERTY_MODE_FILENAME);
  667. if (p)
  668. strncpy (ilogo_fname, p, FILENAME_MAX)[FILENAME_MAX - 1] = 0;
  669. else
  670. *ilogo_fname = 0;
  671. if (f2a_boot_par (iclientp_fname, ilogo_fname))
  672. {
  673. fprintf (stderr, "ERROR: Booting GBA client binary was not successful\n");
  674. exit (1); // fatal
  675. }
  676. return 0;
  677. }
  678. static int
  679. parport_init (unsigned short port, int target_delay)
  680. {
  681. f2a_pport = port;
  682. parport_nop_cntr = parport_init_delay (target_delay);
  683. parport_print_info ();
  684. #ifndef USE_PPDEV
  685. outportb (f2a_pport + PARPORT_STATUS, 0x01); // clear EPP time flag
  686. #endif
  687. outportb (f2a_pport + PARPORT_CONTROL, 0x04);
  688. outportb (f2a_pport + PARPORT_CONTROL, 0x01);
  689. outportb (f2a_pport + PARPORT_DATA, 0x04);
  690. parport_out91 (0x47);
  691. parport_out31 (0x02);
  692. parport_out91 (0x12);
  693. parport_out31 (0x01);
  694. parport_out91 (0x34);
  695. parport_out31 (0x00);
  696. parport_out91 (0x56);
  697. // not parport_out31 (0x02), because extra write to control register
  698. outportb (f2a_pport + PARPORT_CONTROL, 0x03);
  699. outportb (f2a_pport + PARPORT_CONTROL, 0x01);
  700. outportb (f2a_pport + PARPORT_CONTROL, 0x01);
  701. outportb (f2a_pport + PARPORT_CONTROL, 0x01);
  702. outportb (f2a_pport + PARPORT_DATA, 0x02);
  703. // not parport_out91 (0x00), because no write to data register
  704. outportb (f2a_pport + PARPORT_CONTROL, 0x09);
  705. outportb (f2a_pport + PARPORT_CONTROL, 0x01);
  706. outportb (f2a_pport + PARPORT_CONTROL, 0x00);
  707. outportb (f2a_pport + PARPORT_CONTROL, 0x00);
  708. outportb (f2a_pport + PARPORT_CONTROL, 0x02);
  709. inportb (f2a_pport + PARPORT_STATUS);
  710. outportb (f2a_pport + PARPORT_CONTROL, 0x06);
  711. inportb (f2a_pport + PARPORT_STATUS);
  712. outportb (f2a_pport + PARPORT_CONTROL, 0x00);
  713. outportb (f2a_pport + PARPORT_CONTROL, 0x01);
  714. outportb (f2a_pport + PARPORT_EADDRESS, 0x04);
  715. outportb (f2a_pport + PARPORT_EDATA, 0x07);
  716. outportb (f2a_pport + PARPORT_CONTROL, 0x01);
  717. outportb (f2a_pport + PARPORT_EADDRESS, 0x02);
  718. outportb (f2a_pport + PARPORT_EDATA, 0x12);
  719. outportb (f2a_pport + PARPORT_CONTROL, 0x01);
  720. outportb (f2a_pport + PARPORT_EADDRESS, 0x01);
  721. outportb (f2a_pport + PARPORT_EDATA, 0x34);
  722. outportb (f2a_pport + PARPORT_CONTROL, 0x01);
  723. outportb (f2a_pport + PARPORT_EADDRESS, 0x00);
  724. outportb (f2a_pport + PARPORT_EDATA, 0x56);
  725. outportb (f2a_pport + PARPORT_CONTROL, 0x01);
  726. outportb (f2a_pport + PARPORT_CONTROL, 0x01);
  727. outportb (f2a_pport + PARPORT_EADDRESS, 0x02);
  728. outportb (f2a_pport + PARPORT_CONTROL, 0x00);
  729. inportb (f2a_pport + PARPORT_EDATA);
  730. return 0;
  731. }
  732. static int
  733. parport_init_delay (int n_micros)
  734. /*
  735. We only have millisecond accuracy on DOS, while we have to determine the
  736. correct initial loop counter value for a number of microseconds. Luckily, the
  737. function of time against the initial loop counter value is linear (provided
  738. that the initial counter value is large enough), so we can just divide the
  739. found loop value by 1000. Of course, in reality we don't get millisecond
  740. accuracy...
  741. TODO: Find the equivalent of gettimeofday() for MinGW and Visual C++
  742. */
  743. {
  744. #define N_CHECKS 10
  745. #define N_HITSMAX 10
  746. #if defined _WIN32 || defined __MSDOS__
  747. struct timeb t0, t1;
  748. #else
  749. struct timeval t0, t1;
  750. #endif
  751. int n_ticks = 0, n, n_hits = 0, loop = 10000, loop_sum = 0;
  752. volatile int m; // volatile is necessary for Visual C++...
  753. printf ("Determining delay loop value for %d microseconds...", n_micros);
  754. fflush (stdout);
  755. while (n_hits < N_HITSMAX)
  756. {
  757. n_ticks = 0;
  758. for (n = 0; n < N_CHECKS; n++)
  759. {
  760. m = loop;
  761. #if defined _WIN32 || defined __MSDOS__
  762. ftime (&t0);
  763. #else
  764. gettimeofday (&t0, NULL);
  765. #endif
  766. while (m--)
  767. ;
  768. #if defined _WIN32 || defined __MSDOS__
  769. ftime (&t1);
  770. n_ticks += ((int) t1.time * 1000 + t1.millitm) - ((int) t0.time * 1000 + t0.millitm);
  771. #else
  772. gettimeofday (&t1, NULL);
  773. n_ticks += (t1.tv_sec * 1000000 + t1.tv_usec) - (t0.tv_sec * 1000000 + t0.tv_usec);
  774. #endif
  775. }
  776. n_ticks /= N_CHECKS;
  777. #ifndef DJGPP
  778. if (n_ticks - n_micros == 0) // we are aiming at microsecond accuracy...
  779. #else // DJGPP's run-time system is quite inaccurate on Windows XP
  780. n = n_ticks - n_micros;
  781. if (n < 0)
  782. n = -n;
  783. if (n <= 1) // allow a deviation of 1 ms?
  784. #endif
  785. {
  786. n_hits++;
  787. loop_sum += loop;
  788. loop -= loop >> 3; // force "variation" in hope of better accuracy
  789. continue;
  790. }
  791. if (n_ticks == 0)
  792. loop <<= 1;
  793. else
  794. loop = (int) (n_micros / ((float) n_ticks / loop));
  795. }
  796. #if defined _WIN32 || defined __MSDOS__
  797. n = loop_sum / (1000 * N_HITSMAX); // divide by 1000
  798. #else
  799. n = loop_sum / N_HITSMAX; // we summed N_HITSMAX loop values
  800. #endif
  801. printf ("done (%d)\n", n);
  802. return n;
  803. }
  804. static void
  805. parport_nop (void)
  806. {
  807. volatile int i = parport_nop_cntr; // volatile is necessary for Visual C++...
  808. while (i--)
  809. ;
  810. }
  811. static void
  812. parport_out31 (unsigned char val)
  813. {
  814. outportb (f2a_pport + PARPORT_CONTROL, 0x03);
  815. outportb (f2a_pport + PARPORT_CONTROL, 0x01);
  816. outportb (f2a_pport + PARPORT_CONTROL, 0x01);
  817. outportb (f2a_pport + PARPORT_DATA, val);
  818. }
  819. static void
  820. parport_out91 (unsigned char val)
  821. {
  822. outportb (f2a_pport + PARPORT_CONTROL, 0x09);
  823. outportb (f2a_pport + PARPORT_CONTROL, 0x01);
  824. outportb (f2a_pport + PARPORT_DATA, val);
  825. }
  826. static int
  827. f2a_boot_par (const char *iclientp_fname, const char *ilogo_fname)
  828. {
  829. unsigned char recv[4], iclientp[BOOT_SIZE];
  830. printf ("Booting GBA\n"
  831. "Please turn OFF, then ON your GBA with SELECT and START held down\n");
  832. if (f2a_send_head_par (PP_HEAD_BOOT, 1))
  833. return -1;
  834. if (f2a_receive_raw_par (recv, 4))
  835. return -1;
  836. if (ilogo_fname[0] != 0)
  837. {
  838. unsigned char ilogo[LOGO_SIZE];
  839. printf ("Uploading iLinker logo\n");
  840. if (ucon64_fread (ilogo, 0, LOGO_SIZE, ilogo_fname) <= 0)
  841. {
  842. fprintf (stderr, "ERROR: Could not load logo file (%s)\n", ilogo_fname);
  843. return -1;
  844. }
  845. if (f2a_send_buffer_par (CMD_WRITEDATA, LOGO_ADDR, LOGO_SIZE, ilogo,
  846. 0, 0, 0, 0))
  847. {
  848. fprintf (stderr, f2a_msg[UPLOAD_FAILED]);
  849. return -1;
  850. }
  851. }
  852. printf ("Uploading iLinker client\n");
  853. if (ucon64_fread (iclientp, 0, BOOT_SIZE, iclientp_fname) <= 0)
  854. {
  855. fprintf (stderr, "ERROR: Could not load GBA client binary (%s)\n", iclientp_fname);
  856. return -1;
  857. }
  858. if (f2a_send_buffer_par (CMD_WRITEDATA, EXEC_STUB, BOOT_SIZE, iclientp,
  859. HEAD, FLIP, EXEC, 0))
  860. {
  861. fprintf (stderr, f2a_msg[UPLOAD_FAILED]);
  862. return -1;
  863. }
  864. return 0;
  865. }
  866. static int
  867. f2a_write_par (int n_files, char **files, unsigned int address)
  868. {
  869. int j, fsize, size, is_sram_data = address >= 0xe000000 ? 1 : 0;
  870. char loader_fname[FILENAME_MAX];
  871. unsigned char loader[LOADER_SIZE];
  872. const char *p = NULL;
  873. if (n_files > 1 && !is_sram_data)
  874. {
  875. printf ("Uploading multiloader\n");
  876. p = get_property (ucon64.configfile, "gbaloader", PROPERTY_MODE_FILENAME);
  877. strncpy (loader_fname, p ? p : "loader.bin", FILENAME_MAX)[FILENAME_MAX - 1] = 0;
  878. if (ucon64_fread (loader, 0, LOADER_SIZE, loader_fname) <= 0)
  879. {
  880. fprintf (stderr, "ERROR: Could not load loader binary (%s)\n", loader_fname);
  881. return -1;
  882. }
  883. #if 0 // just use a correct loader file - dbjh
  884. ((int *) loader)[0] = me2le_32 (0x2e0000ea); // start address
  885. #endif
  886. if (f2a_send_buffer_par (PP_CMD_WRITEROM, address, LOADER_SIZE, loader,
  887. HEAD, FLIP, 0, 0))
  888. {
  889. fprintf (stderr, f2a_msg[UPLOAD_FAILED]);
  890. return -1;
  891. }
  892. address += LOADER_SIZE;
  893. }
  894. for (j = 0; j < n_files; j++)
  895. {
  896. if ((fsize = fsizeof (files[j])) == -1)
  897. {
  898. fprintf (stderr, f2a_msg[CANNOT_GET_FILE_SIZE], files[j]);
  899. return -1;
  900. }
  901. size = fsize;
  902. if (size & (32768 - 1))
  903. size += 32768;
  904. size &= ~(32768 - 1);
  905. printf (f2a_msg[UPLOAD_FILE], files[j], fsize / 1024, size / 1024);
  906. if (f2a_send_buffer_par (PP_CMD_WRITEROM, address, size,
  907. (unsigned char *) files[j], HEAD, FLIP, 0, 1))
  908. {
  909. fprintf (stderr, f2a_msg[UPLOAD_FAILED]);
  910. return -1;
  911. }
  912. address += size;
  913. }
  914. return 0;
  915. }
  916. #if 0
  917. static int
  918. f2a_erase_par (unsigned int start, unsigned int size)
  919. {
  920. int end, address;
  921. f2a_exec_cmd_par (CMD_READDATA, ERASE_STUB, 1024);
  922. end = start + (size);
  923. printf ("Erase cart start=0x%08x end=0x%08x\n", start, end);
  924. for (address = start; address < end; address += 0x40000)
  925. f2a_send_cmd_par (PP_CMD_ERASE, address, 1024);
  926. return 0;
  927. }
  928. #endif
  929. static int
  930. f2a_read_par (unsigned int start, unsigned int size, const char *filename)
  931. {
  932. f2a_exec_cmd_par (CMD_READDATA, ERASE_STUB, 1024);
  933. printf ("Reading from cart start=0x%08x size=0x%08x\n", start, size);
  934. f2a_receive_data_par (CMD_READDATA, start, size, filename, FLIP);
  935. return 0;
  936. }
  937. #if 0
  938. typedef struct
  939. {
  940. unsigned char header[16];
  941. unsigned char command;
  942. unsigned char unknown;
  943. unsigned int size;
  944. unsigned char pad[58];
  945. } __attribute__ ((packed)) f2a_msg_head_t;
  946. #endif
  947. static int
  948. f2a_send_head_par (int cmd, int size)
  949. {
  950. unsigned char trans[] = { 0xa, 0x8, 0xe, 0xc, 0x2, 0x0, 0x6, 0x4 },
  951. msg_header[80] = { 0x49, 0x2d, 0x4c, 0x69, 0x6e, 0x6b, 0x65, 0x72,
  952. 0x2e, 0x31, 0x30, 0x30, 0x00, 0x00, 0x01, 0xe8 };
  953. // f2a_msg_head_t msg_header; // Don't use structs with misaligned
  954. unsigned short int s; // members for data streams (we don't
  955. // want compiler-specific stuff)
  956. // memcpy (&msg_head, header, 16); // .head
  957. msg_header[16] = (unsigned char) cmd; // .command
  958. s = (unsigned short) (size / 1024);
  959. msg_header[17] = // .unknown
  960. (trans[((s & 255) / 32)] << 4) | (((1023 - (s & 1023)) / 256) & 0x0f);
  961. // msg_header.unknown = 0x82;
  962. msg_header[18] = (unsigned char) s; // .size
  963. msg_header[19] = (unsigned char) (s >> 8);
  964. memset (&msg_header[20], 0, 80 - 20);
  965. if (f2a_send_raw_par (msg_header, 80))
  966. return -1;
  967. return 0;
  968. }
  969. static int
  970. f2a_exec_cmd_par (int cmd, int address, int size)
  971. {
  972. unsigned char *buffer;
  973. f2a_msg_cmd_t msg_cmd;
  974. memset (&msg_cmd, 0, sizeof (f2a_msg_cmd_t));
  975. msg_cmd.magic = me2be_32 (MAGIC_NUMBER);
  976. msg_cmd.command = me2be_32 (cmd);
  977. msg_cmd.address = me2be_32 (address);
  978. msg_cmd.sizekb = me2be_32 (size / 1024);
  979. msg_cmd.exec_stub = me2be_32 (EXEC_STUB);
  980. msg_cmd.exec = me2be_32 (0x08);
  981. f2a_send_head_par (CMD_READDATA, size);
  982. f2a_wait_par ();
  983. if (parport_debug)
  984. fprintf (stderr,
  985. "sending msg_cmd cmd='0x%08x' address='0x%08x' size='0x%08x' %d bytes\n",
  986. msg_cmd.command, msg_cmd.address, msg_cmd.sizekb,
  987. (int) sizeof (f2a_msg_cmd_t));
  988. f2a_send_raw_par ((unsigned char *) &msg_cmd, sizeof (f2a_msg_cmd_t));
  989. // f2a_wait_par ();
  990. if ((buffer = (unsigned char *) malloc (size)) == NULL)
  991. {
  992. fprintf (stderr, ucon64_msg[BUFFER_ERROR], size);
  993. exit (1); // not return, caller doesn't handle it
  994. }
  995. f2a_receive_raw_par (buffer, size);
  996. free (buffer);
  997. return 0;
  998. }
  999. static int
  1000. f2a_receive_data_par (int cmd, int address, int size, const char *filename, int flip)
  1001. {
  1002. unsigned char buffer[1024], recv[4]; //, *mbuffer;
  1003. int i, j;
  1004. f2a_msg_cmd_t msg_cmd;
  1005. FILE *file;
  1006. memset (&msg_cmd, 0, sizeof (f2a_msg_cmd_t));
  1007. msg_cmd.magic = me2be_32 (MAGIC_NUMBER);
  1008. msg_cmd.command = me2be_32 (cmd);
  1009. msg_cmd.address = me2be_32 (address);
  1010. msg_cmd.sizekb = me2be_32 (size / 1024);
  1011. if (f2a_send_head_par (CMD_READDATA, size))
  1012. return -1;
  1013. if (f2a_receive_raw_par (recv, 4))
  1014. return -1;
  1015. if (parport_debug)
  1016. fprintf (stderr,
  1017. "sending msg_cmd cmd='0x%08x' address='0x%08x' size='0x%08x' %d bytes\n",
  1018. msg_cmd.command, msg_cmd.address, msg_cmd.sizekb,
  1019. (int) sizeof (f2a_msg_cmd_t));
  1020. f2a_send_raw_par ((unsigned char *) &msg_cmd, sizeof (f2a_msg_cmd_t));
  1021. if ((file = fopen (filename, "wb")) == NULL)
  1022. {
  1023. fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
  1024. // exit (1); return, because the other code does it too...
  1025. return -1;
  1026. }
  1027. #if 0
  1028. if ((mbuffer = (unsigned char *) malloc (size)) == NULL)
  1029. {
  1030. fprintf (stderr, ucon64_msg[BUFFER_ERROR], size);
  1031. // exit (1); see comment for fopen() call
  1032. return -1;
  1033. }
  1034. f2a_receive_raw_par (mbuffer, size);
  1035. if (flip)
  1036. for (j = 0; j < size / 4; j++)
  1037. ((int *) mbuffer)[j] = bswap_32 (((int *) mbuffer)[j]);
  1038. if (!fwrite (mbuffer, size, 1, file)) // note order of arguments
  1039. {
  1040. fprintf (stderr, ucon64_msg[WRITE_ERROR], filename);
  1041. fclose (file);
  1042. free (mbuffer);
  1043. return -1; // see comment for fopen() call
  1044. }
  1045. free (mbuffer);
  1046. #else
  1047. for (i = 0; i < size; i += 1024)
  1048. {
  1049. f2a_receive_raw_par (buffer, 1024);
  1050. if (flip)
  1051. for (j = 0; j < 256; j++)
  1052. ((int *) buffer)[j] = bswap_32 (((int *) buffer)[j]);
  1053. if (!fwrite (buffer, 1024, 1, file)) // note order of arguments
  1054. {
  1055. fprintf (stderr, ucon64_msg[WRITE_ERROR], filename);
  1056. fclose (file);
  1057. return -1; // see comment for fopen() call
  1058. }
  1059. if (parport_debug)
  1060. fprintf (stderr, "reading chunk %d of %d\n", (int) (i / 1024) + 1,
  1061. (int) (size / 1024));
  1062. else
  1063. ucon64_gauge (starttime, i + 1024, size);
  1064. }
  1065. if (!parport_debug)
  1066. fputc ('\n', stdout);
  1067. fclose (file);
  1068. #endif
  1069. return 0;
  1070. }
  1071. #if 0
  1072. static int
  1073. f2a_send_cmd_par (int cmd, int address, int size)
  1074. {
  1075. unsigned char recv[4];
  1076. f2a_msg_cmd_t msg_cmd;
  1077. memset (&msg_cmd, 0, sizeof (f2a_msg_cmd_t));
  1078. msg_cmd.magic = me2be_32 (MAGIC_NUMBER);
  1079. msg_cmd.command = me2be_32 (cmd);
  1080. msg_cmd.address = me2be_32 (address);
  1081. msg_cmd.sizekb = me2be_32 (size / 1024);
  1082. if (f2a_send_head_par (CMD_WRITEDATA, size))
  1083. return -1;
  1084. if (f2a_receive_raw_par (recv, 4))
  1085. return -1;
  1086. if (parport_debug)
  1087. fprintf (stderr,
  1088. "parport_send_cmd cmd='0x%08x' address='0x%08x' size='0x%08x' %d bytes\n",
  1089. msg_cmd.command, msg_cmd.address, msg_cmd.sizekb,
  1090. (int) sizeof (f2a_msg_cmd_t));
  1091. if (f2a_send_raw_par ((unsigned char *) &msg_cmd, sizeof (f2a_msg_cmd_t)))
  1092. return -1;
  1093. return 0;
  1094. }
  1095. #endif
  1096. static int
  1097. f2a_send_buffer_par (int cmd, int address, int size, const unsigned char *resource,
  1098. int head, int flip, unsigned int exec, int mode)
  1099. {
  1100. unsigned char recv[4], buffer[1024];
  1101. int i, j;
  1102. f2a_msg_cmd_t msg_cmd;
  1103. FILE *file = NULL;
  1104. memset (&msg_cmd, 0, sizeof (f2a_msg_cmd_t));
  1105. msg_cmd.magic = me2be_32 (MAGIC_NUMBER);
  1106. msg_cmd.command = me2be_32 (cmd);
  1107. msg_cmd.address = me2be_32 (address);
  1108. msg_cmd.sizekb = me2be_32 (size / 1024);
  1109. if (exec)
  1110. {
  1111. msg_cmd.exec_stub = me2be_32 (EXEC_STUB);
  1112. msg_cmd.exec = me2be_32 (0x08);
  1113. }
  1114. if (f2a_send_head_par (CMD_WRITEDATA, size))
  1115. return -1;
  1116. if (f2a_receive_raw_par (recv, 4))
  1117. return -1;
  1118. if (parport_debug)
  1119. fprintf (stderr,
  1120. "parport_send_buffer cmd='0x%08x' address='0x%08x' size='0x%08x' %d bytes\n",
  1121. msg_cmd.command, msg_cmd.address, msg_cmd.sizekb,
  1122. (int) sizeof (f2a_msg_cmd_t));
  1123. if (f2a_send_raw_par ((unsigned char *) &msg_cmd, sizeof (f2a_msg_cmd_t)))
  1124. return -1;
  1125. if (mode == 1)
  1126. {
  1127. if ((file = fopen ((char *) resource, "rb")) == NULL)
  1128. {
  1129. fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], (char *) resource);
  1130. // exit (1); return, because the other code does it too...
  1131. return -1;
  1132. }
  1133. clearerr (file);
  1134. }
  1135. for (i = 0; i < size; i += 1024)
  1136. {
  1137. if (mode == 1)
  1138. {
  1139. j = fread (buffer, 1, 1024, file);
  1140. memset (buffer + j, 0, 1024 - j);
  1141. if (ferror (file))
  1142. {
  1143. fputc ('\n', stderr);
  1144. fprintf (stderr, ucon64_msg[READ_ERROR], (char *) resource);
  1145. fclose (file);
  1146. return -1;
  1147. }
  1148. }
  1149. else
  1150. memcpy (buffer, resource, 1024);
  1151. if (flip)
  1152. for (j = 0; j < 256; j++)
  1153. ((int *) buffer)[j] = bswap_32 (((int *) buffer)[j]);
  1154. if (!i && head)
  1155. for (j = 1; j < GBA_LOGODATA_LEN / 4 + 1; j++) // + 1 for start address
  1156. ((int *) buffer)[j] = bswap_32 (((int *) gba_logodata)[j - 1]);
  1157. if (parport_debug)
  1158. fprintf (stderr, "sending chunk %d of %d\n", (int) (i / 1024) + 1,
  1159. (int) (size / 1024));
  1160. else
  1161. ucon64_gauge (starttime, i + 1024, size);
  1162. f2a_send_raw_par (buffer, 1024);
  1163. if (mode == 0)
  1164. resource += 1024;
  1165. }
  1166. if (!parport_debug)
  1167. fputc ('\n', stdout); // start new gauge on new line
  1168. if (mode == 1)
  1169. fclose (file);
  1170. return 0;
  1171. }
  1172. #ifdef DEBUG
  1173. static void
  1174. parport_dump_byte (unsigned char byte)
  1175. {
  1176. char i;
  1177. for (i = 7; i >= 0; i--)
  1178. {
  1179. if ((byte >> i) & 1)
  1180. fprintf (stderr, "1");
  1181. else
  1182. fprintf (stderr, "0");
  1183. }
  1184. fputc ('\n', stderr);
  1185. }
  1186. #endif
  1187. static int
  1188. f2a_receive_raw_par (unsigned char *buffer, int len)
  1189. {
  1190. int err, i;
  1191. unsigned char *ptr, nibble;
  1192. ptr = buffer;
  1193. if (parport_debug)
  1194. fprintf (stderr, "\nreceive:\n%04x: ", 0);
  1195. *ptr = 0;
  1196. for (err = 0, i = 0; i < len * 2; i++)
  1197. {
  1198. nibble = 0;
  1199. outportb (f2a_pport + PARPORT_CONTROL, 0x04);
  1200. parport_nop ();
  1201. while (inportb (f2a_pport + PARPORT_STATUS) & PARPORT_IBUSY)
  1202. ;
  1203. outportb (f2a_pport + PARPORT_CONTROL, 0x05);
  1204. nibble = inportb (f2a_pport + PARPORT_STATUS);
  1205. while (!(inportb (f2a_pport + PARPORT_STATUS) & PARPORT_IBUSY))
  1206. ;
  1207. if (i % 2)
  1208. {
  1209. *ptr |= (nibble >> 3) & 0x0f;
  1210. if (parport_debug)
  1211. {
  1212. fprintf (stderr, "%02x ", (unsigned char) *ptr);
  1213. if (!(((i / 2) + 1) % 32) && i && (i / 2) < len - 1)
  1214. fprintf (stderr, "\n%04x: ", (i / 2) + 1);
  1215. }
  1216. *ptr = 0;
  1217. ptr++;
  1218. }
  1219. else
  1220. *ptr |= ((nibble >> 3) & 0xf) << 4;
  1221. }
  1222. if (parport_debug)
  1223. fputc ('\n', stderr);
  1224. return err;
  1225. }
  1226. static int
  1227. f2a_send_raw_par (unsigned char *buffer, int len)
  1228. {
  1229. int timeout, i;
  1230. unsigned char *pc;
  1231. pc = buffer;
  1232. if (parport_debug)
  1233. fprintf (stderr, "\nsend:\n%04x: ", 0);
  1234. for (i = 0; i < len; i++)
  1235. {
  1236. timeout = 2000;
  1237. if (parport_debug)
  1238. {
  1239. fprintf (stderr, "%02x ", (unsigned char) *pc);
  1240. if (!((i + 1) % 32) && i && i < len - 1)
  1241. fprintf (stderr, "\n%04x: ", i + 1);
  1242. }
  1243. outportb (f2a_pport + PARPORT_CONTROL, 0x04);
  1244. parport_nop ();
  1245. while ((inportb (f2a_pport + PARPORT_STATUS) & PARPORT_IBUSY) &&
  1246. (timeout--) > 0)
  1247. wait2 (1);
  1248. outportb (f2a_pport + PARPORT_DATA, *pc);
  1249. parport_nop ();
  1250. while ((inportb (f2a_pport + PARPORT_STATUS) & PARPORT_IBUSY) &&
  1251. (timeout--) > 0)
  1252. wait2 (1);
  1253. outportb (f2a_pport + PARPORT_CONTROL, 0x05);
  1254. parport_nop ();
  1255. while ((!(inportb (f2a_pport + PARPORT_STATUS) & PARPORT_IBUSY)) &&
  1256. (timeout--) > 0)
  1257. wait2 (1);
  1258. pc++;
  1259. if (timeout < 0)
  1260. {
  1261. fprintf (stderr, "\nERROR: Time-out\n");
  1262. return -1;
  1263. }
  1264. }
  1265. if (parport_debug)
  1266. fputc ('\n', stderr);
  1267. return 0;
  1268. }
  1269. static int
  1270. f2a_wait_par (void)
  1271. {
  1272. int stat;
  1273. for (;;)
  1274. {
  1275. outportb (f2a_pport + PARPORT_CONTROL, 0x04);
  1276. parport_nop ();
  1277. stat = inportb (f2a_pport + PARPORT_STATUS);
  1278. if (stat & PARPORT_IBUSY)
  1279. break;
  1280. outportb (f2a_pport + PARPORT_CONTROL, 0x05);
  1281. parport_nop ();
  1282. inportb (f2a_pport + PARPORT_STATUS);
  1283. }
  1284. return 0;
  1285. }
  1286. #endif // USE_PARALLEL
  1287. #if defined USE_PARALLEL || defined USE_USB
  1288. int
  1289. f2a_read_rom (const char *filename, int size)
  1290. {
  1291. int offset = 0;
  1292. starttime = time (NULL);
  1293. #ifdef USE_USB
  1294. if (ucon64.usbport)
  1295. {
  1296. f2a_init_usb ();
  1297. f2a_read_usb (0x8000000 + offset * MBIT, size * MBIT, filename);
  1298. usbport_close (f2a_handle);
  1299. }
  1300. #endif
  1301. #if defined USE_PARALLEL && defined USE_USB
  1302. else
  1303. #endif
  1304. #ifdef USE_PARALLEL
  1305. {
  1306. f2a_init_par (ucon64.parport, 10);
  1307. f2a_read_par (0x08000000 + offset * MBIT, size * MBIT, filename);
  1308. }
  1309. #endif
  1310. return 0;
  1311. }
  1312. int
  1313. f2a_write_rom (const char *filename, int size)
  1314. {
  1315. int offset = 0, n, n_files, n_files_max = 0, fsize, totalsize = LOADER_SIZE;
  1316. char **files = NULL, *file_mem[1];
  1317. struct stat fstate;
  1318. if (filename) // -xf2a
  1319. {
  1320. files = file_mem;
  1321. files[0] = (char *) filename;
  1322. n_files = 1;
  1323. }
  1324. else // -xf2amulti=SIZE
  1325. {
  1326. n_files = 0;
  1327. for (n = 1; n < ucon64.argc; n++)
  1328. {
  1329. if (access (ucon64.argv[n], F_OK))
  1330. continue; // "file" does not exist (option)
  1331. stat (ucon64.argv[n], &fstate);
  1332. if (!S_ISREG (fstate.st_mode))
  1333. continue;
  1334. if (n_files == n_files_max)
  1335. {
  1336. n_files_max += 20; // allocate mem for 20 extra pointers
  1337. if ((files = (char **) realloc (files, n_files_max * 4)) == NULL)
  1338. {
  1339. fprintf (stderr, ucon64_msg[BUFFER_ERROR], n_files_max * 4);
  1340. exit (1);
  1341. }
  1342. }
  1343. fsize = fsizeof (ucon64.argv[n]);
  1344. if (totalsize + fsize > size)
  1345. {
  1346. printf ("WARNING: The sum of the sizes of the files is larger than the specified flash\n"
  1347. " card size (%d Mbit). Skipping files, starting with\n"
  1348. " %s\n",
  1349. size / MBIT, ucon64.argv[n]);
  1350. break;
  1351. }
  1352. totalsize += fsize;
  1353. files[n_files] = ucon64.argv[n];
  1354. n_files++;
  1355. }
  1356. if (n_files == 0)
  1357. return -1;
  1358. }
  1359. starttime = time (NULL);
  1360. #ifdef USE_USB
  1361. if (ucon64.usbport)
  1362. {
  1363. f2a_init_usb ();
  1364. f2a_write_usb (n_files, files, 0x8000000 + offset * MBIT);
  1365. usbport_close (f2a_handle);
  1366. }
  1367. #endif
  1368. #if defined USE_PARALLEL && defined USE_USB
  1369. else
  1370. #endif
  1371. #ifdef USE_PARALLEL
  1372. {
  1373. f2a_init_par (ucon64.parport, 10);
  1374. // f2a_erase_par (0x08000000, size * MBIT);
  1375. f2a_write_par (n_files, files, 0x8000000 + offset * MBIT);
  1376. }
  1377. #endif
  1378. if (!filename)
  1379. free (files);
  1380. return 0;
  1381. }
  1382. int
  1383. f2a_read_sram (const char *filename, int bank)
  1384. {
  1385. int size;
  1386. if (bank == UCON64_UNKNOWN)
  1387. {
  1388. bank = 1;
  1389. size = 256 * 1024;
  1390. }
  1391. else
  1392. {
  1393. if (bank < 1)
  1394. {
  1395. fprintf (stderr, "ERROR: Bank must be a number larger than or equal to 1\n");
  1396. exit (1);
  1397. }
  1398. size = 64 * 1024;
  1399. }
  1400. bank--;
  1401. starttime = time (NULL);
  1402. #ifdef USE_USB
  1403. if (ucon64.usbport)
  1404. {
  1405. f2a_init_usb ();
  1406. f2a_read_usb (0xe000000 + bank * 64 * 1024, size, filename);
  1407. usbport_close (f2a_handle);
  1408. }
  1409. #endif
  1410. #if defined USE_PARALLEL && defined USE_USB
  1411. else
  1412. #endif
  1413. #ifdef USE_PARALLEL
  1414. {
  1415. f2a_init_par (ucon64.parport, 10);
  1416. f2a_read_par (0xe000000 + bank * 64 * 1024, size, filename);
  1417. }
  1418. #endif
  1419. return 0;
  1420. }
  1421. int
  1422. f2a_write_sram (const char *filename, int bank)
  1423. {
  1424. char *files[1];
  1425. files[0] = (char *) filename;
  1426. // define one bank as a 64 kilobyte unit
  1427. if (bank == UCON64_UNKNOWN)
  1428. bank = 1;
  1429. else
  1430. if (bank < 1)
  1431. {
  1432. fprintf (stderr, "ERROR: Bank must be a number larger than or equal to 1\n");
  1433. exit (1);
  1434. }
  1435. bank--;
  1436. starttime = time (NULL);
  1437. #ifdef USE_USB
  1438. if (ucon64.usbport)
  1439. {
  1440. f2a_init_usb ();
  1441. f2a_write_usb (1, files, 0xe000000 + bank * 64 * 1024);
  1442. usbport_close (f2a_handle);
  1443. }
  1444. #endif
  1445. #if defined USE_PARALLEL && defined USE_USB
  1446. else
  1447. #endif
  1448. #ifdef USE_PARALLEL
  1449. {
  1450. f2a_init_par (ucon64.parport, 10);
  1451. // f2a_erase_par (0xe000000, size * MBIT);
  1452. f2a_write_par (1, files, 0xe000000 + bank * 64 * 1024);
  1453. }
  1454. #endif
  1455. return 0;
  1456. }
  1457. #endif // defined USE_PARALLEL || defined USE_USB