pl.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782
  1. /*
  2. pl.c - Pocket Linker support for uCON64
  3. Copyright (c) 2004 Walter van Niftrik <w.f.b.w.v.niftrik@stud.tue.nl>
  4. Partly based on PokeLink - Copyright (c) Dark Fader / BlackThunder
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. #ifdef HAVE_CONFIG_H
  18. #include "config.h"
  19. #endif
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <time.h>
  23. #include "misc/itypes.h"
  24. #ifdef USE_ZLIB
  25. #include "misc/archive.h"
  26. #endif
  27. #include "misc/getopt2.h" // st_getopt2_t
  28. #include "misc/misc.h"
  29. #include "misc/parallel.h"
  30. #include "misc/file.h"
  31. #include "ucon64.h"
  32. #include "ucon64_misc.h"
  33. #include "pl.h"
  34. const st_getopt2_t pl_usage[] =
  35. {
  36. {
  37. NULL, 0, 0, 0,
  38. NULL, "Pocket Linker"/*"19XX Bung Enterprises Ltd"*/,
  39. NULL
  40. },
  41. #ifdef USE_PARALLEL
  42. {
  43. "xpl", 0, 0, UCON64_XPL,
  44. NULL, "send/receive ROM to/from Pocket Linker; " OPTION_LONG_S "port=PORT\n"
  45. "receives automatically when ROM does not exist",
  46. &ucon64_wf[WF_OBJ_NGP_DEFAULT_STOP_NO_ROM]
  47. },
  48. {
  49. "xpli", 0, 0, UCON64_XPLI,
  50. NULL, "show information about inserted cartridge; " OPTION_LONG_S "port=PORT",
  51. &ucon64_wf[WF_OBJ_NGP_STOP_NO_ROM]
  52. },
  53. {
  54. "xplm", 0, 0, UCON64_XPLM,
  55. NULL, "try to enable EPP mode, default is SPP mode",
  56. &ucon64_wf[WF_OBJ_NGP_SWITCH]
  57. },
  58. #endif // USE_PARALLEL
  59. {NULL, 0, 0, 0, NULL, NULL, NULL}
  60. };
  61. #ifdef USE_PARALLEL
  62. // flash unlock addresses with chip select
  63. #define fx0002aa(A) (((A) & 0x200000) | 0x0002aa)
  64. #define fx000555(A) (((A) & 0x200000) | 0x000555)
  65. #define fx000aaa(A) (((A) & 0x200000) | 0x000aaa)
  66. #define fx002aaa(A) (((A) & 0x200000) | 0x002aaa)
  67. #define fx005555(A) (((A) & 0x200000) | 0x005555)
  68. #define set_data_read outportb (port_a, 0);
  69. #define set_data_write outportb (port_a, 1);
  70. #define reset_port outportb (port_a, 4);
  71. #define clear_timeout outportb (port_9, 1);
  72. #define CMD_READ 0xf0
  73. #define CMD_INFO 0x90
  74. #define CMD_ERASE 0x80
  75. #define TYPE_BW 0x00
  76. #define TYPE_COLOR 0x01
  77. #define TYPE_MULTI 0x02
  78. static short int port_8, port_9, port_a, port_b, port_c;
  79. static parport_mode_t port_mode;
  80. static int current_ai;
  81. static unsigned char ai_value[4];
  82. static void
  83. epp_write_data (unsigned char data)
  84. {
  85. outportb (port_c, data);
  86. }
  87. static void
  88. spp_write_data (unsigned char data)
  89. {
  90. outportb (port_8, data);
  91. outportb (port_a, 3);
  92. outportb (port_a, 1);
  93. }
  94. static void
  95. write_data (unsigned char data)
  96. {
  97. ai_value[current_ai] = data;
  98. if (port_mode == UCON64_SPP)
  99. spp_write_data (data);
  100. else
  101. epp_write_data (data);
  102. }
  103. static unsigned char
  104. epp_read_data (void)
  105. {
  106. return inportb (port_c);
  107. }
  108. static unsigned char
  109. spp_read_data (void)
  110. {
  111. unsigned char byte;
  112. outportb (port_a, 2);
  113. byte = (inportb (port_9) >> 3) & 0x0f;
  114. outportb (port_a, 6);
  115. byte |= (inportb (port_9) << 1) & 0xf0;
  116. outportb (port_a, 0);
  117. return byte;
  118. }
  119. static unsigned char
  120. read_data (void)
  121. {
  122. if (port_mode == UCON64_SPP)
  123. return spp_read_data ();
  124. else
  125. return epp_read_data ();
  126. }
  127. static void
  128. epp_set_ai (unsigned char ai)
  129. {
  130. current_ai = ai;
  131. outportb (port_b, ai);
  132. }
  133. static void
  134. spp_set_ai (unsigned char ai)
  135. {
  136. current_ai = ai;
  137. outportb (port_8, ai);
  138. outportb (port_a, 9);
  139. outportb (port_a, 1);
  140. }
  141. static void
  142. set_ai (unsigned char ai)
  143. {
  144. if (port_mode == UCON64_SPP)
  145. spp_set_ai (ai);
  146. else
  147. epp_set_ai (ai);
  148. }
  149. static void
  150. epp_set_ai_data (unsigned char ai, unsigned char data)
  151. {
  152. epp_set_ai (ai);
  153. epp_write_data (data);
  154. }
  155. static void
  156. spp_set_ai_data (unsigned char ai, unsigned char data)
  157. {
  158. spp_set_ai (ai);
  159. spp_write_data (data);
  160. }
  161. static void
  162. set_ai_data (unsigned char ai, unsigned char data)
  163. {
  164. if (port_mode == UCON64_SPP)
  165. spp_set_ai_data (ai, data);
  166. else
  167. epp_set_ai_data (ai, data);
  168. }
  169. static void
  170. init_port (void)
  171. {
  172. #ifndef USE_PPDEV
  173. clear_timeout
  174. #endif
  175. set_data_write
  176. set_ai_data (2, 0);
  177. }
  178. static void
  179. end_port (void)
  180. {
  181. set_data_write
  182. set_ai_data (2, 0);
  183. reset_port
  184. }
  185. static int
  186. detect_linker (void)
  187. {
  188. init_port ();
  189. set_data_write
  190. set_ai_data (1, 0x12);
  191. set_ai_data (0, 0x34);
  192. set_ai (1);
  193. set_data_read
  194. if (read_data () != 0x12)
  195. return 0;
  196. set_data_write
  197. set_ai (0);
  198. set_data_read
  199. if (read_data () != 0x34)
  200. return 0;
  201. end_port ();
  202. return 1;
  203. }
  204. static void
  205. select_address (unsigned int addr, int inc)
  206. {
  207. unsigned char data = (((addr >> 14) & 0x3c) | ((addr >> 13) & 0x80) |
  208. (inc ? 0x01 : 0x00)); // a[20..16], auto-increment
  209. if (data != ai_value[2])
  210. set_ai_data (2, data);
  211. set_ai_data (1, (unsigned char) ((addr >> 8) & 0xff)); // a[15..8]
  212. set_ai_data (0, (unsigned char) (addr & 0xff)); // a[7..0]
  213. }
  214. static void
  215. write_address_data (unsigned int addr, unsigned char data)
  216. {
  217. select_address (addr, 0);
  218. set_ai_data (3, data);
  219. }
  220. static void
  221. send_command (unsigned char cmd)
  222. {
  223. set_data_write
  224. write_address_data (0x5555, 0xaa);
  225. write_address_data (0x2aaa, 0x55);
  226. write_address_data (0x5555, cmd);
  227. }
  228. static void
  229. reset_read (void)
  230. {
  231. send_command (CMD_READ);
  232. }
  233. static unsigned char
  234. read_ai3_data (void)
  235. {
  236. set_ai (3);
  237. set_data_read
  238. return read_data ();
  239. }
  240. static int
  241. detect_chip (void)
  242. {
  243. int ai;
  244. unsigned char info[4];
  245. reset_read ();
  246. reset_read ();
  247. reset_read ();
  248. send_command (CMD_INFO);
  249. for (ai = 0; ai < 4; ai++)
  250. {
  251. set_data_write
  252. select_address (ai, 0);
  253. info[ai] = read_ai3_data ();
  254. }
  255. reset_read ();
  256. if (((info[0] & 0x90) == 0x90) && (info[2] == 0x01) && (info[3] & 0x80))
  257. return 1;
  258. else
  259. return 0;
  260. }
  261. static void
  262. select_chip (unsigned int addr)
  263. {
  264. set_data_write
  265. set_ai_data (2, 2);
  266. set_ai_data (3, (unsigned char) ((addr & 0x200000) ? 1 : 2));
  267. set_ai_data (2, 0);
  268. }
  269. static unsigned int
  270. cart_size (void)
  271. {
  272. select_chip (0x000000);
  273. if (!detect_chip ())
  274. return 0; // no cartridge found
  275. select_chip (0x200000);
  276. if (!detect_chip ())
  277. return 0x200000; // 16 megabit
  278. return 0x400000; // 32 megabit
  279. }
  280. static void
  281. read_blocks (unsigned int addr, unsigned char *buf, int blocks)
  282. {
  283. int block, i, offset = 0;
  284. select_chip (addr);
  285. for (block = 0; block < blocks; block++)
  286. {
  287. set_data_write
  288. select_address (addr | (block << 8), 1);
  289. set_ai (3);
  290. set_data_read
  291. for (i = 0; i < 0x100; i++)
  292. buf[offset++] = read_data ();
  293. }
  294. }
  295. static int
  296. is_erased (unsigned char *buf, unsigned int len)
  297. {
  298. unsigned int i;
  299. for (i = 0; i < len; i++)
  300. if (buf[i] != 0xff)
  301. return 0;
  302. return 1;
  303. }
  304. static int
  305. is_header (unsigned char *buf)
  306. {
  307. char msg[0x1d];
  308. strncpy (msg, (char *) buf, 0x1c);
  309. msg[0x1c] = '\0';
  310. if (strstr (msg, "COPYRIGHT") || strstr (msg, "SNK") ||
  311. strstr (msg, "LICENSED") || strstr (msg, "CORPORATION"))
  312. return 1; // header found
  313. return 0; // other data found
  314. }
  315. static int
  316. same_header (unsigned char *header, unsigned char *buf)
  317. {
  318. return (!memcmp (header, buf, 0x100));
  319. }
  320. static unsigned int
  321. game_info (unsigned int cart_size, char name[13], int *type)
  322. {
  323. unsigned char header[0x100];
  324. unsigned char buf[0x8000];
  325. select_chip (0x000000);
  326. read_blocks (0x000000, header, 1);
  327. if (!is_header (header))
  328. return 0; // no game found
  329. if (name)
  330. {
  331. strncpy (name, (char *) (header + 0x24), 12);
  332. name[12] = '\0';
  333. }
  334. if (type)
  335. {
  336. if (strstr (name, "Multi"))
  337. *type = TYPE_MULTI;
  338. else if (header[0x23] == 0x10)
  339. *type = TYPE_COLOR;
  340. else
  341. *type = TYPE_BW;
  342. }
  343. read_blocks (0x080000, buf, 128);
  344. if ((same_header (buf, header)) || is_erased (buf, 0x8000))
  345. return 0x080000; // 4 megabit
  346. read_blocks (0x100000, buf, 128);
  347. if ((same_header (buf, header)) || is_erased (buf, 0x8000))
  348. return 0x100000; // 8 megabit
  349. if (cart_size == 0x400000)
  350. {
  351. read_blocks (0x200000, buf, 128);
  352. if (is_erased (buf, 0x8000))
  353. return 0x200000; // 16 megabit
  354. return 0x400000; // 32 megabit
  355. }
  356. return 0x200000; // 16 megabit
  357. }
  358. static void
  359. deinit_io (void)
  360. {
  361. end_port ();
  362. }
  363. static void
  364. init_io (unsigned int port)
  365. {
  366. #ifndef USE_PPDEV
  367. outportb ((unsigned short) (port_8 + 0x402), 0); // Set EPP mode for ECP chipsets
  368. #endif
  369. port_8 = port;
  370. port_9 = port + 1;
  371. port_a = port + 2;
  372. port_b = port + 3;
  373. port_c = port + 4;
  374. parport_print_info ();
  375. if (ucon64.parport_mode == UCON64_EPP && port_8 != 0x3bc)
  376. port_mode = UCON64_EPP; // if port == 0x3bc => no EPP available
  377. else
  378. port_mode = UCON64_SPP;
  379. if (!detect_linker ())
  380. {
  381. port_mode = UCON64_SPP;
  382. if (!detect_linker ())
  383. {
  384. fputs ("ERROR: Pocket Linker not found or not turned on\n", stderr);
  385. deinit_io ();
  386. exit (1);
  387. }
  388. }
  389. // If we get here, a Pocket Linker was detected
  390. if (port_mode == UCON64_EPP)
  391. puts ("Pocket Linker found. EPP found");
  392. else
  393. puts ("Pocket Linker found. EPP not found or not enabled - SPP used");
  394. }
  395. static void
  396. set_address (unsigned int addr, int inc)
  397. {
  398. set_ai_data (0, (unsigned char) (addr & 0xff)); // a[7..0]
  399. set_ai_data (1, (unsigned char) ((addr >> 8) & 0xff)); // a[15..8]
  400. set_ai_data (2, 0x02); // latch chip select
  401. set_ai_data (3, (unsigned char) ~(1 << (addr >> 21))); // a[23..21]
  402. set_ai_data (2, (unsigned char) ((((addr >> 16) & 0x0f) << 2) | // a[20..16], auto-increment
  403. (((addr >> 20) & 0x01) << 7) |
  404. (inc ? 0x01 : 0x00)));
  405. set_ai (3);
  406. }
  407. static int
  408. program (unsigned int addr, unsigned char data, int retries)
  409. {
  410. int to = 10000;
  411. set_data_write
  412. set_address (fx005555 (addr), 0); // program byte
  413. write_data (0xaa);
  414. set_address (fx002aaa (addr), 0);
  415. write_data (0x55);
  416. set_address (fx005555 (addr), 0);
  417. write_data (0xa0);
  418. set_address (addr, 0);
  419. write_data (data);
  420. set_data_read
  421. while (to--)
  422. {
  423. unsigned char s = read_data ();
  424. if ((s & 128) == 0)
  425. return 0; // ok
  426. if (s & 32)
  427. {
  428. int s = read_data ();
  429. if ((s & 128) == 0)
  430. return 0; // ok
  431. if (data == read_data ())
  432. return 0; // ok
  433. }
  434. }
  435. set_data_write
  436. set_address (addr, 0);
  437. set_data_read
  438. if (data == read_data ())
  439. return 0; // ok
  440. if (retries == 0)
  441. return 1; // error
  442. return program (addr, data, retries - 1);
  443. }
  444. static int
  445. write_block (unsigned int addr, unsigned char *buf)
  446. {
  447. int count;
  448. select_address (addr, 1);
  449. for (count = 0; count < 0x100; count++)
  450. {
  451. if (buf[count] == 0xff)
  452. continue; // nothing to write
  453. if (program (addr + count, buf[count], 3))
  454. {
  455. select_address (addr + count, 0);
  456. set_data_read
  457. fprintf (stderr, "\nERROR: Programming failed at 0x%06x (w:0x%02x, "
  458. "r:0x%02x)\n", addr + count, buf[count], read_data ());
  459. return 1;
  460. }
  461. }
  462. return 0;
  463. }
  464. #if 0
  465. static int
  466. wait_erased (void)
  467. {
  468. int i = 0;
  469. unsigned char cur_byte, prev_byte;
  470. prev_byte = read_ai3_data () & 0x40;
  471. while (++i < 0x7ffffff)
  472. {
  473. cur_byte = read_data () & 0x40;
  474. if (cur_byte == prev_byte)
  475. return 0; // ok
  476. prev_byte = cur_byte;
  477. }
  478. return 1; // erase error
  479. }
  480. static int
  481. erase_chip (void)
  482. {
  483. reset_read ();
  484. send_command (CMD_ERASE);
  485. write_address_data (0x5555, 0xaa);
  486. write_address_data (0x2aaa, 0x55);
  487. write_address_data (0x5555, 0x10);
  488. return wait_erased ();
  489. }
  490. static int
  491. erase_cart (unsigned int size)
  492. {
  493. unsigned int addr;
  494. unsigned char buf[0x8000];
  495. for (addr = 0x000000; addr < size; addr += 0x200000)
  496. {
  497. select_chip (addr);
  498. if (erase_chip ())
  499. {
  500. fprintf (stderr, "ERROR: Erase chip %d failed\n", addr >> 21);
  501. return 1;
  502. }
  503. read_blocks (0x000000, buf, 128);
  504. if (!is_erased (buf, 0x8000))
  505. {
  506. fprintf (stderr, "ERROR: Erase chip %d verify failed\n", addr >> 21);
  507. return 1;
  508. }
  509. }
  510. }
  511. #endif
  512. static int
  513. erase (void)
  514. {
  515. unsigned int addr;
  516. for (addr = 0; addr < 0x400000; addr += 0x200000)
  517. {
  518. set_data_write
  519. set_address (fx005555 (addr), 0);
  520. write_data (0xaa);
  521. set_address (fx002aaa (addr), 0);
  522. write_data (0x55);
  523. set_address (fx005555 (addr), 0);
  524. write_data (0x80);
  525. set_address (fx005555 (addr), 0);
  526. write_data (0xaa);
  527. set_address (fx002aaa (addr), 0);
  528. write_data (0x55);
  529. set_address (fx005555 (addr), 0);
  530. write_data (0x10);
  531. set_data_read
  532. while (~read_data () & 0x80) // wait for completion
  533. ;
  534. }
  535. return 0;
  536. }
  537. int
  538. pl_read_rom (const char *filename, unsigned int parport)
  539. {
  540. FILE *file;
  541. unsigned int blocksleft, c_size, size, address = 0;
  542. unsigned char buffer[0x8000];
  543. time_t starttime;
  544. if ((file = fopen (filename, "wb")) == NULL)
  545. {
  546. fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
  547. exit (1);
  548. }
  549. init_io (parport);
  550. c_size = cart_size ();
  551. if (c_size == 0x00) // Check for cartridge
  552. {
  553. fputs ("ERROR: No cartridge detected\n", stderr);
  554. deinit_io ();
  555. exit (1);
  556. }
  557. size = game_info (c_size, NULL, NULL);
  558. if (size == 0x00)
  559. {
  560. fputs ("ERROR: No game detected\n", stderr);
  561. deinit_io ();
  562. exit (1);
  563. }
  564. reset_read ();
  565. printf ("Receive: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
  566. blocksleft = size >> 15;
  567. starttime = time (NULL);
  568. while (blocksleft-- > 0)
  569. {
  570. read_blocks (address, buffer, 128);
  571. fwrite (buffer, 1, 0x8000, file);
  572. address += 0x8000;
  573. ucon64_gauge (starttime, address, size);
  574. }
  575. fclose (file);
  576. deinit_io ();
  577. return 0;
  578. }
  579. int
  580. pl_write_rom (const char *filename, unsigned int parport)
  581. {
  582. FILE *file;
  583. unsigned int size, bytesread, bytessent = 0, address = 0;
  584. unsigned char buffer[0x100];
  585. time_t starttime;
  586. if ((file = fopen (filename, "rb")) == NULL)
  587. {
  588. fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
  589. exit (1);
  590. }
  591. init_io (parport);
  592. size = fsizeof (filename);
  593. erase ();
  594. reset_read ();
  595. printf ("Send: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
  596. starttime = time (NULL);
  597. while ((bytesread = fread (buffer, 1, 0x100, file)))
  598. {
  599. if (write_block (address, buffer))
  600. break; // write failed
  601. bytessent += bytesread;
  602. address += 0x100;
  603. ucon64_gauge (starttime, bytessent, size);
  604. }
  605. fclose (file);
  606. deinit_io ();
  607. return 0;
  608. }
  609. int
  610. pl_info (unsigned int parport)
  611. {
  612. unsigned int c_size, g_size;
  613. int g_type;
  614. char g_name[13];
  615. init_io (parport);
  616. c_size = cart_size ();
  617. if (c_size == 0)
  618. {
  619. printf ("No cartridge found\n");
  620. deinit_io ();
  621. return 0;
  622. }
  623. g_size = game_info (c_size, g_name, &g_type);
  624. if (g_size == 0)
  625. printf ("No game found\n");
  626. else
  627. {
  628. printf ("Game name: \"%s\"\n", g_name);
  629. printf ("Game type: %s\n", (g_type == TYPE_COLOR) ? "Color" : "B&W");
  630. printf ("Game size: %d Bytes (%.4f Mb)\n", g_size, (float) g_size / MBIT);
  631. }
  632. deinit_io ();
  633. return 0;
  634. }
  635. #endif // USE_PARALLEL