f2a.c 47 KB

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