f2a.c 47 KB

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