pl.c 16 KB

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