Advertisement
Guest User

Untitled

a guest
Mar 20th, 2013
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.40 KB | None | 0 0
  1. /*
  2. *
  3. * PSX Peripheral Bus Library v1.4 17/01/00 Richard Davies
  4. * <mailto:richard@debaser.force9.co.uk>
  5. *
  6. * Revision History:
  7. * v1.4 - 17/01/00 Win32 / Win32 DLL support, rewrite and bug fixes
  8. * v1.3 - 21/12/99 Linux support and bug fixes
  9. * v1.1 - 26/09/99 Minor Controller detection improvements.
  10. * v1.0 - 17/07/99 Initial release (based on PSXTest v1.1 by me).
  11. *
  12. * see psxpblib.h for details.
  13. *
  14. */
  15.  
  16.  
  17.  
  18. #include"psxpblib.h"
  19.  
  20.  
  21.  
  22. /*
  23. *
  24. * sets clock for conport connected to parallel port base
  25. *
  26. */
  27. void psx_clk(int base, int conport, int on)
  28. {
  29. if (conport == 8)
  30. {
  31. if (on)
  32. {
  33. /* set controller clock high */
  34. psx_parallel_out_2 |= LPT_STR;
  35. }
  36. else
  37. {
  38. /* set controller clock low */
  39. psx_parallel_out_2 &= ~LPT_STR;
  40. }
  41.  
  42. psx_outportb(base + 2, psx_parallel_out_2);
  43. }
  44. else
  45. {
  46. if (on)
  47. {
  48. /* set controller clock high */
  49. psx_parallel_out_0 |= LPT_D2;
  50. }
  51. else
  52. {
  53. /* set controller clock low */
  54. psx_parallel_out_0 &= ~LPT_D2;
  55. }
  56.  
  57. psx_outportb(base + 0, psx_parallel_out_0);
  58. }
  59. }
  60.  
  61. /*
  62. *
  63. * sets att for conport connected to parallel port base
  64. *
  65. */
  66. void psx_att(int base, int conport, int on)
  67. {
  68. /* bits 3-7 base + 0 (pins 5 to 9 parallel port) */
  69. const int power = LPT_D3 | LPT_D4 | LPT_D5 | LPT_D6 | LPT_D7;
  70. /* bits 1-6 base + 0 (pins 3, 5, 6, 7 and 8 parallel port) */
  71. unsigned char att_array[] = { LPT_D1, LPT_D1, LPT_D3, LPT_D4, LPT_D5, LPT_D6, LPT_D7 };
  72. unsigned char att;
  73.  
  74. if (conport == 8)
  75. {
  76. if (on)
  77. {
  78. /* set controller att high */
  79. psx_parallel_out_2 |= LPT_INI;
  80. }
  81. else
  82. {
  83. /* set controller att low */
  84. psx_parallel_out_2 &= ~LPT_INI;
  85. }
  86.  
  87. psx_outportb(base + 2, psx_parallel_out_2);
  88. }
  89. else
  90. {
  91. /* powers up all parallel port driven conports */
  92. psx_parallel_out_0 |= power;
  93.  
  94. att = att_array[conport - 1];
  95.  
  96. if (on)
  97. {
  98. /* set controller att high */
  99. psx_parallel_out_0 |= att;
  100. }
  101. else
  102. {
  103. /* set controller att low */
  104. psx_parallel_out_0 &= ~att;
  105. }
  106.  
  107. psx_outportb(base + 0, psx_parallel_out_0);
  108. }
  109. }
  110.  
  111. /*
  112. *
  113. * sets command for conport connected to parallel port base
  114. *
  115. */
  116. void psx_cmd(int base, int conport, int on)
  117. {
  118. if (conport == 8)
  119. {
  120. if (on)
  121. {
  122. /* set controller cmd high */
  123. psx_parallel_out_2 |= LPT_AUT;
  124. }
  125. else
  126. {
  127. /* set controller cmd low */
  128. psx_parallel_out_2 &= ~LPT_AUT;
  129. }
  130.  
  131. psx_outportb(base + 2, psx_parallel_out_2);
  132. }
  133. else
  134. {
  135. if (on)
  136. {
  137. /* set controller cmd high */
  138. psx_parallel_out_0 |= LPT_D0;
  139. }
  140. else
  141. {
  142. /* set controller cmd low */
  143. psx_parallel_out_0 &= ~LPT_D0;
  144. }
  145.  
  146. psx_outportb(base + 0, psx_parallel_out_0);
  147. }
  148. }
  149.  
  150. /*
  151. *
  152. * tests data for conport connected to parallel port base, returns 1 if high
  153. *
  154. */
  155. int psx_dat(int base, int conport)
  156. {
  157. if (conport == 2)
  158. {
  159. if (psx_inportb(base + 1) & LPT_SEL)
  160. {
  161. return 1;
  162. }
  163. else
  164. {
  165. return 0;
  166. }
  167. }
  168. else
  169. {
  170. if (psx_inportb(base + 1) & LPT_ACK)
  171. {
  172. return 1;
  173. }
  174. else
  175. {
  176. return 0;
  177. }
  178. }
  179. }
  180.  
  181. /*
  182. *
  183. * tests ack for conport connected to parallel port base, returns 1 if high
  184. *
  185. */
  186. int psx_ack(int base, int conport)
  187. {
  188. if (conport == 2)
  189. {
  190. if (psx_inportb(base + 2) & LPT_ERR)
  191. {
  192. return 1;
  193. }
  194. else
  195. {
  196. return 0;
  197. }
  198. }
  199. else if (conport == 8)
  200. {
  201. if (psx_inportb(base + 1) & LPT_SEL)
  202. {
  203. return 1;
  204. }
  205. else
  206. {
  207. return 0;
  208. }
  209. }
  210. else
  211. {
  212. if (psx_inportb(base + 1) & LPT_PAP)
  213. {
  214. return 1;
  215. }
  216. else
  217. {
  218. return 0;
  219. }
  220. }
  221. }
  222.  
  223. /*
  224. *
  225. * wait for delay * (psx_outportb() execution time)
  226. *
  227. */
  228. void psx_delay(int base, int delay)
  229. {
  230. int i;
  231.  
  232. for (i = 0; i < delay; i++)
  233. {
  234. psx_outportb(base + 0, psx_parallel_out_0);
  235. }
  236. }
  237.  
  238. /*
  239. *
  240. * send byte as a command to conport connected to parallel port base
  241. * assumes clock high and the attention for conport
  242. *
  243. */
  244. unsigned char psx_sendbyte(int base, int conport, int delay, unsigned char byte, int wait)
  245. {
  246. int i;
  247. unsigned char data;
  248.  
  249. data = 0;
  250.  
  251. /* for each bit in byte */
  252. for (i = 0; i < 8; i++)
  253. {
  254. psx_delay(base, delay);
  255. psx_cmd(base, conport, byte & (1<<i)); /* send the (i+1)th bit of byte to any listening controller */
  256. psx_clk(base, conport, 0); /* clock low */
  257. psx_delay(base, delay);
  258. data |= (psx_dat(base, conport) ? (1<<i) : 0); /* read the (i+1)th bit of data from conport */
  259. psx_clk(base, conport, 1); /* clock high */
  260. }
  261.  
  262. /* wait for controller ack */
  263. for(i = 0; wait && i < 10240 && psx_ack(base, conport); i++);
  264.  
  265. return data;
  266. }
  267.  
  268. int psx_obtain_io_permission(int base)
  269. {
  270. static int already=0;
  271. if (already==1) { return 1; }
  272. // return 1 if successful, otherwise, 0
  273. #ifdef _PSX_LINUX_
  274. if (ioperm(base,3,1)) { return 0; }
  275. #endif
  276. already=1;
  277. return 1;
  278. }
  279.  
  280. /*
  281. *
  282. * sets clock high and gets the attention of conport, use before psx_sendbyte()
  283. *
  284. */
  285. void psx_sendinit(int base, int conport, int delay)
  286. {
  287. psx_obtain_io_permission(base);
  288. psx_att(base, conport, 1); /* set att on for conport */
  289. psx_clk(base, conport, 1); /* clock high */
  290. psx_cmd(base, conport, 1); /* set command on for conport */
  291. psx_delay(base, delay);
  292. psx_delay(base, delay);
  293. psx_delay(base, delay);
  294. psx_delay(base, delay);
  295. psx_delay(base, delay);
  296. psx_att(base, conport, 0); /* set att off for conport */
  297. psx_delay(base, delay);
  298. psx_delay(base, delay);
  299. psx_delay(base, delay);
  300. psx_delay(base, delay);
  301. }
  302.  
  303. /*
  304. *
  305. * use after psx_sendbyte()
  306. *
  307. */
  308. void psx_sendclose(int base, int conport, int delay)
  309. {
  310. psx_delay(base, delay);
  311. psx_delay(base, delay);
  312. psx_att(base, conport, 1); /* set att on for conport */
  313. psx_cmd(base, conport, 1); /* set command on for conport */
  314. psx_clk(base, conport, 1); /* clock high */
  315. psx_delay(base, delay);
  316. }
  317.  
  318. /*
  319. *
  320. * send string as a series of commands to conport connected to parallel port base
  321. *
  322. */
  323. void psx_sendstring(int base, int conport, int delay, int string[])
  324. {
  325. int i;
  326.  
  327. psx_sendinit(base, conport, delay);
  328.  
  329. /* for each byte in string */
  330. for (i = 0; string[i + 1] != -1; i++)
  331. {
  332. /* send byte i and wait for conport ack */
  333. psx_sendbyte(base, conport, delay, (unsigned char)string[i], 0);
  334. psx_delay(base, delay);
  335. }
  336.  
  337. /* send the last byte in string and don't wait for ack */
  338. psx_sendbyte(base, conport, delay, (unsigned char)string[i], 0);
  339.  
  340. psx_sendclose(base, conport, delay);
  341. }
  342.  
  343. /*
  344. *
  345. * tests for the presence of a controller on conport:tap connected to base
  346. * returns the type if present, otherwise -1
  347. *
  348. */
  349. int psx_controller_detect(int base, int conport, int tap, int delay)
  350. {
  351. unsigned char ack;
  352. int type, length;
  353.  
  354. psx_sendinit(base, conport, delay);
  355.  
  356. psx_sendbyte(base, conport, delay, (unsigned char) tap, 0);
  357. psx_delay(base, delay);
  358. psx_delay(base, delay);
  359. psx_delay(base, delay);
  360. psx_delay(base, delay);
  361. ack = psx_sendbyte(base, conport, delay, 0x42, 0);
  362. psx_delay(base, delay);
  363.  
  364. psx_sendclose(base, conport, delay);
  365.  
  366. type = (ack & 0xf0) >> 4;
  367. length = 2 * (ack & 0x0f);
  368.  
  369. /* check the controller has a legal packet length */
  370. if (!((length > 0) && (length < PSX_MAX_DATA)))
  371. return -1;
  372.  
  373. /* check the controller has a legal id */
  374. if (!((type > 0) && (type < 0x0f) && (type != 0x08)))
  375. return -1;
  376.  
  377. return type;
  378. }
  379.  
  380. /*
  381. *
  382. * reads a controller on conport:tap connected to base returns the data
  383. * if present, otherwise -1
  384. *
  385. */
  386. PSX_CON_BUF* psx_controller_read(int base, int conport, int tap, int delay)
  387. {
  388. unsigned char ack;
  389. int i;
  390. static PSX_CON_BUF psx_con_buf;
  391.  
  392. psx_sendinit(base, conport, delay);
  393.  
  394. psx_sendbyte(base, conport, delay, (unsigned char)tap, 0);
  395. psx_delay(base, delay);
  396. psx_delay(base, delay);
  397. psx_delay(base, delay);
  398. psx_delay(base, delay);
  399. ack = psx_sendbyte(base, conport, delay, 0x42, 0);
  400. psx_delay(base, delay);
  401.  
  402. psx_con_buf.type = (ack & 0xf0) >> 4;
  403. psx_con_buf.length = 2 * (ack & 0x0f);
  404.  
  405. /* check the controller has a legal packet length */
  406. if (!((psx_con_buf.length > 0) && (psx_con_buf.length < PSX_MAX_DATA)))
  407. {
  408. psx_sendclose(base, conport, delay);
  409. return NULL;
  410. }
  411.  
  412. /* check the controller has a legal id */
  413. if (!((psx_con_buf.type > 0) && (psx_con_buf.type < 0x0f) && (psx_con_buf.type != 0x08)))
  414. {
  415. psx_sendclose(base, conport, delay);
  416. return NULL;
  417. }
  418.  
  419. psx_sendbyte(base, conport, delay, 0x00, 0);
  420. psx_delay(base, delay);
  421. for (i = 0; i < psx_con_buf.length; i++)
  422. {
  423. psx_con_buf.data[i] = psx_sendbyte(base, conport, delay, 0x00, 0);
  424. psx_delay(base, delay);
  425. }
  426. psx_sendclose(base, conport, delay);
  427.  
  428. return &psx_con_buf;
  429. }
  430.  
  431. /*
  432. *
  433. * sends force feedback/shock init command sequence to conport:tap on port base
  434. * (also initialises crash protection for some controllers)
  435. *
  436. */
  437. void psx_controller_vinit(int base, int conport, int tap, int delay)
  438. {
  439. int i;
  440. int vibrate_init_string[3][11] =
  441. {
  442. {tap, 0x43, 0x00, 0x01, 0x00, 0x01, -1},
  443. {tap, 0x4d, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, -1},
  444. {tap, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -1},
  445. };
  446.  
  447. for (i = 0; i < 3; i++)
  448. {
  449. psx_delay(base, delay);
  450. psx_delay(base, delay);
  451. psx_delay(base, delay);
  452. psx_sendstring(base, conport, delay, vibrate_init_string[i]);
  453. }
  454. }
  455.  
  456. /*
  457. *
  458. * sends the dual shock command sequence to conport:tap on port base
  459. *
  460. */
  461. void psx_controller_vshock(int base, int conport, int tap, int delay, int shock, int rumble)
  462. {
  463. int dualshock_string[7] = {tap, 0x42, 0x00, shock, rumble, 0x01, -1 };
  464.  
  465. psx_controller_vinit(base, conport, tap, delay);
  466.  
  467. psx_delay(base, delay);
  468. psx_delay(base, delay);
  469. psx_delay(base, delay);
  470. psx_sendstring(base, conport, delay, dualshock_string);
  471. }
  472.  
  473. /*
  474. *
  475. * Reads a single frame (128 bytes) from Memory Card on conport base:tap
  476. *
  477. */
  478. char* psx_memcard_read_frame(int base, int conport, int tap, int delay, int frame)
  479. {
  480. int i, xor;
  481. static unsigned char data[128], c_data;
  482.  
  483. unsigned char cmd_rstring_hdr[4] = {(0x80 + (unsigned char)tap), 0x52, 0x00, 0x00};
  484. unsigned char chk_rstring_hdr[2] = {0x5a, 0x5d};
  485.  
  486. unsigned char cmd_rstring_adr[2] = {(frame >> 8) & 0xff, frame & 0xff};
  487.  
  488. unsigned char chk_rstring_ack[1] = {0x5c};
  489.  
  490. unsigned char chk_rstring_sfl[1] = {0x5d};
  491.  
  492. unsigned char chk_rstring_efl[1] = {0x47};
  493.  
  494. psx_sendinit(base, conport, delay);
  495.  
  496. /* send header */
  497. for (i = 0; i < 2; i++)
  498. {
  499. psx_sendbyte(base, conport, delay, cmd_rstring_hdr[i], 0);
  500. psx_delay(base, delay);
  501. psx_delay(base, delay);
  502. }
  503.  
  504. for (;i < 4; i++)
  505. {
  506. c_data = psx_sendbyte(base, conport, delay, cmd_rstring_hdr[i], 0);
  507. psx_delay(base, delay);
  508. psx_delay(base, delay);
  509.  
  510. if (c_data != chk_rstring_hdr[i-2])
  511. {
  512. psx_sendclose(base, conport, delay);
  513. return NULL;
  514. }
  515. }
  516.  
  517. /* send read address */
  518. for (i = 0; i < 2; i++)
  519. {
  520. psx_sendbyte(base, conport, delay, cmd_rstring_adr[i], 0);
  521. psx_delay(base, delay);
  522. }
  523.  
  524. /* receive command ack (have to wait for this) */
  525. c_data = psx_sendbyte(base, conport, delay, 0x00, 1);
  526.  
  527. if (c_data != chk_rstring_ack[0])
  528. {
  529. psx_sendclose(base, conport, delay);
  530. return NULL;
  531. }
  532.  
  533. /* receive start of data flag */
  534. i = 0;
  535.  
  536. while (c_data != chk_rstring_sfl[0])
  537. {
  538. c_data = psx_sendbyte(base, conport, delay, 0x00, 0);
  539. psx_delay(base, delay);
  540.  
  541. i++;
  542.  
  543. if (i > 255)
  544. {
  545. psx_sendclose(base, conport, delay);
  546. return NULL;
  547. }
  548. }
  549.  
  550. /* receive read address */
  551. for (i = 0; i < 2; i++)
  552. {
  553. c_data = psx_sendbyte(base, conport, delay, 0x00, 0);
  554. psx_delay(base, delay);
  555.  
  556. if (c_data != cmd_rstring_adr[i])
  557. {
  558. psx_sendclose(base, conport, delay);
  559. return NULL;
  560. }
  561. }
  562.  
  563. /* receive data */
  564. for (i = 0; i < 128; i++)
  565. {
  566. data[i] = psx_sendbyte(base, conport, delay, 0x00, 0);
  567. psx_delay(base, delay);
  568. }
  569.  
  570. /* receive xor */
  571. c_data = psx_sendbyte(base, conport, delay, 0x00, 0);
  572. psx_delay(base, delay);
  573.  
  574. /* test xor */
  575. xor = 0;
  576.  
  577. xor ^= cmd_rstring_adr[0];
  578. xor ^= cmd_rstring_adr[1];
  579.  
  580. for (i = 0; i < 128; i++)
  581. xor ^= data[i];
  582.  
  583. if (xor != c_data)
  584. {
  585. psx_sendclose(base, conport, delay);
  586. return NULL;
  587. }
  588.  
  589. /* receive end of data flag */
  590. c_data = psx_sendbyte(base, conport, delay, 0x00, 0);
  591. psx_delay(base, delay);
  592.  
  593. if (c_data != chk_rstring_efl[0])
  594. {
  595. psx_sendclose(base, conport, delay);
  596. return NULL;
  597. }
  598.  
  599. psx_sendclose(base, conport, delay);
  600.  
  601. return data;
  602. }
  603.  
  604. /*
  605. *
  606. * Writes a single frame (128 bytes) to Memory Card on conport base:tap
  607. *
  608. */
  609. int psx_memcard_write_frame(int base, int conport, int tap, int delay, int frame, char* data_f)
  610. {
  611. int i, xor;
  612. unsigned char c_data;
  613.  
  614. unsigned char cmd_wstring_hdr[4] = {(0x80 + (unsigned char)tap), 0x57, 0x00, 0x00};
  615. unsigned char chk_wstring_hdr[2] = {0x5a, 0x5d};
  616.  
  617. unsigned char cmd_wstring_adr[2] = {(frame >> 8) & 0xff, frame & 0xff};
  618.  
  619. unsigned char chk_wstring_emk[2] = {0x5c, 0x5d};
  620.  
  621. unsigned char chk_wstring_efl[1] = {0x47};
  622.  
  623. psx_sendinit(base, conport, delay);
  624.  
  625. /* send header (have to wait for this) */
  626. for (i = 0; i < 2; i++)
  627. {
  628. psx_sendbyte(base, conport, delay, cmd_wstring_hdr[i], 1);
  629. }
  630.  
  631. for (;i < 4; i++)
  632. {
  633. c_data = psx_sendbyte(base, conport, delay, cmd_wstring_hdr[i], 1);
  634.  
  635. if (c_data != chk_wstring_hdr[i-2])
  636. {
  637. psx_sendclose(base, conport, delay);
  638. return -1;
  639. }
  640. }
  641.  
  642. /* send write address */
  643. for (i = 0; i < 2; i++)
  644. {
  645. psx_sendbyte(base, conport, delay, cmd_wstring_adr[i], 0);
  646. psx_delay(base, delay);
  647. }
  648. /* send data */
  649. for (i = 0; i < 128; i++)
  650. {
  651. psx_sendbyte(base, conport, delay, data_f[i], 0);
  652. psx_delay(base, delay);
  653. }
  654.  
  655. /* calculate xor */
  656. xor = 0;
  657.  
  658. xor ^= cmd_wstring_adr[0];
  659. xor ^= cmd_wstring_adr[1];
  660.  
  661. for (i = 0; i < 128; i++)
  662. xor ^= data_f[i];
  663.  
  664. /* send xor */
  665. psx_sendbyte(base, conport, delay, (unsigned char) xor, 0);
  666. psx_delay(base, delay);
  667.  
  668. /* receive end mark */
  669. for (i = 0; i < 2; i++)
  670. {
  671. c_data = psx_sendbyte(base, conport, delay, 0x00, 1);
  672.  
  673. if (c_data != chk_wstring_emk[i])
  674. {
  675. psx_sendclose(base, conport, delay);
  676. return -1;
  677. }
  678. }
  679.  
  680. /* receive end of data flag */
  681. c_data = psx_sendbyte(base, conport, delay, 0x00, 1);
  682.  
  683. if (c_data != chk_wstring_efl[0])
  684. {
  685. psx_sendclose(base, conport, delay);
  686. return -1;
  687. }
  688.  
  689. psx_sendclose(base, conport, delay);
  690.  
  691. return (int)((unsigned char)xor);
  692. }
  693.  
  694. /*
  695. *
  696. * Reads a single block (64 frames) from Memory Card on conport base:tap
  697. *
  698. */
  699. char* psx_memcard_read_block(int base, int conport, int tap, int delay, int block)
  700. {
  701. int i, j;
  702. static unsigned char data_b[8192], *data_f;
  703.  
  704. for (i = 0; i < 64; i++)
  705. {
  706. data_f = psx_memcard_read_frame(base, conport, tap, delay, (block*64)+i);
  707.  
  708. if (data_f != NULL)
  709. {
  710. for (j = 0; j < 128; j++)
  711. data_b[(i*128)+j] = data_f[j];
  712. }
  713. else
  714. {
  715. return NULL;
  716. }
  717. }
  718.  
  719. return data_b;
  720. }
  721.  
  722. /*
  723. *
  724. * Writes a single block (64 frames) to Memory Card on conport base:tap
  725. *
  726. */
  727. int psx_memcard_write_block(int base, int conport, int tap, int delay, int block, char* data_b)
  728. {
  729. int i, xor;
  730.  
  731. for (i = 0; i < 64; i++)
  732. {
  733. xor = psx_memcard_write_frame(base, conport, tap, delay, (block*64)+i, &(data_b[128*i]));
  734.  
  735. if (xor == -1)
  736. {
  737. return -1;
  738. }
  739. }
  740.  
  741. return 1;
  742. }
  743.  
  744. /*
  745. *
  746. * Reads the info associated with block from the directory
  747. *
  748. */
  749. PSX_MCB_INFO_DIR* psx_mcb_read_dir(int base, int conport, int tap, int delay, int block)
  750. {
  751. int i, xor;
  752. unsigned char *data_f;
  753. static PSX_MCB_INFO_DIR mcb_info_dir;
  754.  
  755. mcb_info_dir.read = 1;
  756.  
  757. /* check memory card state */
  758. data_f = psx_memcard_read_frame(base, conport, tap, delay, 0);
  759.  
  760. if (data_f == NULL)
  761. {
  762. mcb_info_dir.read = 0;
  763. return &mcb_info_dir;
  764. }
  765.  
  766. if ((data_f[0] != 'M') && (data_f[1] != 'C'))
  767. {
  768. mcb_info_dir.read = 0;
  769. return &mcb_info_dir;
  770. }
  771.  
  772. for (i = 2; i < 127; i++)
  773. {
  774. if (data_f[i] != 0x00)
  775. {
  776. mcb_info_dir.read = 0;
  777. return &mcb_info_dir;
  778. }
  779. }
  780.  
  781. if (data_f[127] != 0x0e)
  782. {
  783. mcb_info_dir.read = 0;
  784. return &mcb_info_dir;
  785. }
  786.  
  787. /* read block's directory */
  788. data_f = psx_memcard_read_frame(base, conport, tap, delay, block);
  789.  
  790. if (data_f == NULL)
  791. {
  792. mcb_info_dir.read = 0;
  793. return &mcb_info_dir;
  794. }
  795.  
  796. xor = 0;
  797.  
  798. for (i = 0; i < 127; i++)
  799. xor ^= data_f[i];
  800.  
  801. if (xor != data_f[127])
  802. {
  803. mcb_info_dir.read = 0;
  804. return &mcb_info_dir;
  805. }
  806.  
  807. mcb_info_dir.linktype = data_f[0] & 0x0f;
  808.  
  809. /* Only test if first link */
  810. if (mcb_info_dir.linktype == PSX_MCB_LTYPE_FIRST)
  811. {
  812. if (data_f[10] != 'B')
  813. {
  814. mcb_info_dir.read = 0;
  815. return &mcb_info_dir;
  816. }
  817. }
  818.  
  819. mcb_info_dir.state = (data_f[0] >> 4) & 0x0f;
  820.  
  821. mcb_info_dir.bytes = (data_f[4] << 16) + (data_f[5] << 8) + data_f[6];
  822.  
  823. mcb_info_dir.next = data_f[8]; /* 0 to 14 */
  824.  
  825. mcb_info_dir.territory = data_f[11]; /* E, A or I */
  826.  
  827. for (i = 0; i < 10; i++)
  828. mcb_info_dir.code[i] = (char)data_f[12+i];
  829.  
  830. mcb_info_dir.code[i] = '\0';
  831.  
  832. for (i = 0; i < 8; i++)
  833. mcb_info_dir.filename[i] = data_f[22+i];
  834.  
  835. mcb_info_dir.filename[i] = '\0';
  836.  
  837. return &mcb_info_dir;
  838. }
  839.  
  840. /*
  841. *
  842. * Reads the info associated with block from it's data
  843. *
  844. */
  845. PSX_MCB_INFO_DAT* psx_mcb_read_dat(int base, int conport, int tap, int delay, int block)
  846. {
  847. int i, j;
  848. unsigned char *data_f;
  849. static PSX_MCB_INFO_DAT mcb_info_dat;
  850.  
  851. mcb_info_dat.read = 1;
  852.  
  853. if ((block < 1) || (block > 15))
  854. {
  855. mcb_info_dat.read = 0;
  856. return &mcb_info_dat;
  857. }
  858.  
  859. data_f = psx_memcard_read_frame(base, conport, tap, delay, (block*64)+0);
  860.  
  861. if (!data_f)
  862. {
  863. mcb_info_dat.read = 0;
  864. return &mcb_info_dat;
  865. }
  866.  
  867. if ((data_f[0] != 'S') || (data_f[1] != 'C'))
  868. {
  869. mcb_info_dat.read = 0;
  870. return &mcb_info_dat;
  871. }
  872.  
  873. mcb_info_dat.icon_valid = (data_f[2] >> 4) & 0x0f;
  874. mcb_info_dat.icon_frames = data_f[2] & 0x0f;
  875. mcb_info_dat.blocks = data_f[3];
  876.  
  877. /* bodged character set conversion */
  878. j = 0;
  879. for (i = 0; i < 91; i+=2)
  880. {
  881. if (data_f[4+i] != 0x00)
  882. {
  883. if (data_f[4+i] == 0x81)
  884. {
  885. if (data_f[5+i] == 0x7c)
  886. mcb_info_dat.name[j] = '-';
  887. else if (data_f[5+i] == 0x40)
  888. mcb_info_dat.name[j] = ' ';
  889. else if (data_f[5+i] == 0x46)
  890. mcb_info_dat.name[j] = ':';
  891. else if (data_f[5+i] == 0x5e)
  892. mcb_info_dat.name[j] = '/';
  893. else if (data_f[5+i] == 0x49)
  894. mcb_info_dat.name[j] = '!';
  895. else if (data_f[5+i] == 0x93)
  896. mcb_info_dat.name[j] = '%';
  897. else if (data_f[5+i] == 0x68)
  898. mcb_info_dat.name[j] = '\"';
  899. else if (data_f[5+i] == 0x44)
  900. mcb_info_dat.name[j] = '.';
  901. else if (data_f[5+i] == 0x6d)
  902. mcb_info_dat.name[j] = '[';
  903. else if (data_f[5+i] == 0x6e)
  904. mcb_info_dat.name[j] = ']';
  905. else if (data_f[5+i] == 0x69)
  906. mcb_info_dat.name[j] = '(';
  907. else if (data_f[5+i] == 0x6a)
  908. mcb_info_dat.name[j] = ')';
  909. else
  910. mcb_info_dat.name[j] = '?';
  911. }
  912. else if (data_f[4+i] == 0x82)
  913. {
  914. if ((data_f[5+i] > 0x4e) && (data_f[5+i] < 0x80))
  915. mcb_info_dat.name[j] = data_f[5+i] - 0x1f;
  916. else if ((data_f[4+i] > 0x80) && (data_f[5+i] < 0x9a))
  917. mcb_info_dat.name[j] = data_f[5+i] - 0x20;
  918. else
  919. mcb_info_dat.name[j] = '?';
  920. }
  921. else
  922. {
  923. mcb_info_dat.name[j] = data_f[4+i];
  924.  
  925. j++;
  926. if (data_f[5+i] != 0x00)
  927. mcb_info_dat.name[j] = data_f[5+i];
  928. else
  929. {
  930. mcb_info_dat.name[j] = '\0';
  931. i = 91;
  932. }
  933. }
  934. }
  935. else
  936. {
  937. mcb_info_dat.name[j] = '\0';
  938. i = 91;
  939. }
  940. j++;
  941. }
  942.  
  943. return &mcb_info_dat;
  944. }
  945.  
  946. /*
  947. *
  948. * Merges the info associated with block from the directory and it's data
  949. *
  950. */
  951. PSX_MCB_INFO* psx_mcb_info_merge(PSX_MCB_INFO_DIR mcb_info_dir, PSX_MCB_INFO_DAT mcb_info_dat, PSX_MCB_INFO *mcb_info)
  952. {
  953. mcb_info->read = 1;
  954.  
  955. if (!mcb_info_dir.read)
  956. {
  957. mcb_info->read = 0;
  958. return mcb_info;
  959. }
  960.  
  961. if ((mcb_info_dir.linktype == PSX_MCB_LTYPE_FIRST) && (!mcb_info_dat.read))
  962. {
  963. mcb_info->read = 0;
  964. return mcb_info;
  965. }
  966.  
  967. strcpy(mcb_info->filename, mcb_info_dir.filename);
  968. strcpy(mcb_info->code, mcb_info_dir.code);
  969. mcb_info->territory = mcb_info_dir.territory;
  970. mcb_info->bytes = mcb_info_dir.bytes;
  971. mcb_info->state = mcb_info_dir.state;
  972. mcb_info->linktype = mcb_info_dir.linktype;
  973. mcb_info->next = mcb_info_dir.next;
  974. if (mcb_info_dir.linktype == PSX_MCB_LTYPE_FIRST)
  975. {
  976. strcpy(mcb_info->name, mcb_info_dat.name);
  977. mcb_info->blocks = mcb_info_dat.blocks;
  978. mcb_info->icon_valid = mcb_info_dat.icon_valid;
  979. mcb_info->icon_frames = mcb_info_dat.icon_frames;
  980. }
  981. else
  982. {
  983. mcb_info->name[0] = '\0';
  984. mcb_info->blocks = 0;
  985. mcb_info->icon_valid = 0;
  986. mcb_info->icon_frames = 0;
  987. }
  988.  
  989. return mcb_info;
  990. }
  991.  
  992. /*
  993. *
  994. * Reads the info associated with block from the directory and it's data
  995. *
  996. */
  997. PSX_MCB_INFO* psx_mcb_read_info(int base, int conport, int tap, int delay, int block)
  998. {
  999. PSX_MCB_INFO_DIR *mcb_info_dir;
  1000. PSX_MCB_INFO_DAT *mcb_info_dat;
  1001. static PSX_MCB_INFO mcb_info;
  1002.  
  1003. mcb_info_dir = psx_mcb_read_dir(base, conport, tap, delay, block);
  1004. mcb_info_dat = psx_mcb_read_dat(base, conport, tap, delay, block);
  1005. return psx_mcb_info_merge(*mcb_info_dir, *mcb_info_dat, &mcb_info);
  1006. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement