gbx.c 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996
  1. /*
  2. gbx.c - Game Boy Xchanger/GBDoctor support for uCON64
  3. Copyright (c) 1999 - 2001 NoisyB
  4. Copyright (c) 2001 - 2004 dbjh
  5. Based on gbt15.c - Copyright (c) Bung Enterprises
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. /********************************************************************
  19. * use parallel EPP/SPP port to r/w game boy cartridge *
  20. * *
  21. * ai[]=0 w a[7..0] *
  22. * ai[]=1 w a[15..8] *
  23. * ai[]=2 w control d7=rs,d6=spp,d1=xwe_en,d0=cs_en *
  24. * ai[]=3 r/w data *
  25. * *
  26. * MBC1 *
  27. * R/W A000~BFFF RAM SWITCHING BANK(256Kbit) 4 BANKS OF 8Kbyte *
  28. * R 4000~7FFF ROM SWITCHING BANK(4Mbit) 32 BANKS OF 128Kbit *
  29. * W 2000~3FFF SET ROM BANK (5 BIT) *
  30. * R 0000~3FFF FIX ROM BANK 0 *
  31. * W 4000~5FFF SET RAM BANK (2 BIT) *
  32. * W 0000~1FFF SET 0A ENABLE RAM BANK *
  33. * *
  34. * MBC2 *
  35. * R/W A000~BFFF 512 X 4 BIT RAM *
  36. * R 4000~7FFF ROM SWITCHING BANK(2Mbit) 16 BANKS OF 128Kbit *
  37. * W 2100 SET ROM BANK (4 BIT) *
  38. * R 0000~3FFF FIX ROM BANK 0 *
  39. * W 0000 SET 0A ENABLE RAM BANK *
  40. * *
  41. * MBC5 *
  42. * R/W A000~BFFF RAM SWITCHING BANK(1Mbit) 16 BANKS OF 64 Kbit *
  43. * R 4000~7FFF ROM SWITCHING BANK(64Mbit) 512 BANKS OF 128Kbit *
  44. * W 3000~3FFF SET ROM BANK1(BANK Q8) TOTAL 9 BIT *
  45. * W 2000~2FFF SET ROM BANK0(BANK Q7~Q0) *
  46. * R 0000~3FFF FIX ROM BANK 0 *
  47. * W 4000~7FFF SET RAM BANK (4 BIT) *
  48. * W 0000~1FFF SET 0A ENABLE RAM BANK *
  49. * *
  50. ********************************************************************/
  51. #ifdef HAVE_CONFIG_H
  52. #include "config.h"
  53. #endif
  54. #include <ctype.h>
  55. #include <stdlib.h>
  56. #include "misc/archive.h"
  57. #include "misc/file.h"
  58. #include "misc/misc.h"
  59. #include "misc/parallel.h"
  60. #include "misc/term.h"
  61. #include "ucon64_misc.h"
  62. #include "console/gb.h" // GB_NAME_LEN, gb_logodata,
  63. #include "backup/gbx.h" // rocket_logodata
  64. #ifdef USE_PARALLEL
  65. static st_ucon64_obj_t gbx_obj[] =
  66. {
  67. {UCON64_GB, WF_DEFAULT | WF_STOP | WF_NO_ROM},
  68. {UCON64_GB, WF_STOP | WF_NO_ROM},
  69. {UCON64_GB, WF_SWITCH}
  70. };
  71. #endif
  72. const st_getopt2_t gbx_usage[] =
  73. {
  74. {
  75. NULL, 0, 0, 0,
  76. NULL, "Game Boy Xchanger/GBDoctor"/*"19XX Bung Enterprises Ltd http://www.bung.com.hk"*/,
  77. NULL
  78. },
  79. #ifdef USE_PARALLEL
  80. {
  81. "xgbx", 0, 0, UCON64_XGBX,
  82. NULL, "send/receive ROM to/from GB Xchanger; " OPTION_LONG_S "port=PORT\n"
  83. "receives automatically when ROM does not exist",
  84. &gbx_obj[0]
  85. },
  86. {
  87. "xgbxs", 0, 0, UCON64_XGBXS,
  88. NULL, "send/receive SRAM to/from GB Xchanger; " OPTION_LONG_S "port=PORT\n"
  89. "receives automatically when SRAM does not exist",
  90. &gbx_obj[1]
  91. },
  92. {
  93. "xgbxb", 1, 0, UCON64_XGBXB,
  94. "BANK", "send/receive 64 kbits SRAM to/from GB Xchanger BANK\n"
  95. "BANK can be a number from 0 to 15; " OPTION_LONG_S "port=PORT\n"
  96. "receives automatically when ROM does not exist",
  97. &gbx_obj[1]
  98. },
  99. {
  100. "xgbxm", 0, 0, UCON64_XGBXM,
  101. NULL, "try to enable EPP mode, default is SPP mode",
  102. &gbx_obj[2]
  103. },
  104. #endif
  105. {NULL, 0, 0, 0, NULL, NULL, NULL}
  106. };
  107. #ifdef USE_PARALLEL
  108. //#define set_ai_write outportb (port_a, 5); // ninit=1, nwrite=0
  109. #define set_data_read outportb (port_a, 0); // ninit=0, nastb=1, nib_sel=0, ndstb=1, nwrite=1
  110. #define set_data_write outportb (port_a, 1); // ninit=0, nastb=1, nib_sel=0, ndstb=1, nwrite=0
  111. //#define set_normal outportb (port_a, 4); // ninit=1, nwrite=1
  112. typedef enum { UNKNOWN_MBC, BUNG, ROM, MBC1, MBC2, MBC3, MBC5, CAMERA, ROCKET } mbc_t;
  113. typedef enum { UNKNOWN_EEPROM, WINBOND, MX, INTEL } eeprom_t;
  114. static unsigned short port_8, port_9, port_a, port_b, port_c, rocket_game_no;
  115. static unsigned char buffer[32768];
  116. static mbc_t mbc_type;
  117. static eeprom_t eeprom_type;
  118. static parport_mode_t port_mode;
  119. static void
  120. delay_us (int n_us)
  121. // Hmmm, usleep() can be used on UNIX, but default on DOS is delay() which waits
  122. // for a number of milliseconds... Better use the same code on all platforms.
  123. {
  124. volatile int n;
  125. int n_max;
  126. // it's probably best to use the original strange loop values
  127. if (n_us == 10)
  128. n_max = 0x2000;
  129. else if (n_us == 100)
  130. n_max = 0x10000;
  131. else if (n_us == 20000)
  132. n_max = 0xfffff;
  133. else
  134. n_max = n_us * 1000;
  135. for (n = 0; n < n_max; n++)
  136. ;
  137. }
  138. static void
  139. spp_set_ai (unsigned char ai)
  140. {
  141. set_data_write
  142. // outportb (port_a, 1); // nastb=1,nib_sel=0,ndstb=1,nwrite=0
  143. outportb (port_8, ai); // put ai at data bus
  144. outportb (port_a, 9); // nastb=0,nib_sel=0,ndstb=1,nwrite=0
  145. outportb (port_a, 1); // nastb=1,nib_sel=0,ndstb=1,nwrite=0
  146. // nastb ~~~~|___|~~~~
  147. }
  148. static void
  149. spp_write_data (unsigned char data)
  150. {
  151. // outportb (port_a, 1); // nastb=1,nib_sel=0,ndstb=1,nwrite=0
  152. outportb (port_8, data); // put data at data bus
  153. outportb (port_a, 3); // nastb=1,nib_sel=0,ndstb=0,nwrite=0
  154. outportb (port_a, 1); // nastb=1,nib_sel=0,ndstb=1,nwrite=0
  155. // ndstb ~~~~|___|~~~~
  156. }
  157. static void
  158. spp_set_ai_data (unsigned char ai, unsigned char data)
  159. {
  160. spp_set_ai (ai);
  161. spp_write_data (data);
  162. }
  163. static unsigned char
  164. spp_read_data (void)
  165. {
  166. unsigned char byte;
  167. set_data_read
  168. outportb (port_a, 2); // nastb=1,nib_sel=0,ndstb=0,nwrite=1
  169. byte = (inportb (port_9) >> 3) & 0x0f;
  170. outportb (port_a, 6); // nastb=1,nib_sel=1,ndstb=0,nwrite=1
  171. byte |= (inportb (port_9) << 1) & 0xf0;
  172. outportb (port_a, 0); // nastb=1,nib_sel=0,ndstb=1,nwrite=1
  173. // nibble_sel ___|~~~ and ndstb ~~~~|___|~~~~
  174. return byte;
  175. }
  176. static void
  177. epp_set_ai (unsigned char ai)
  178. {
  179. set_data_write
  180. outportb (port_b, ai);
  181. }
  182. static void
  183. epp_set_ai_data (unsigned char ai, unsigned char data)
  184. {
  185. epp_set_ai (ai);
  186. set_data_write
  187. outportb (port_c, data);
  188. }
  189. static void
  190. set_ai (unsigned char ai)
  191. {
  192. set_data_write
  193. if (port_mode == UCON64_SPP)
  194. spp_set_ai (ai);
  195. else
  196. epp_set_ai (ai);
  197. }
  198. static void
  199. set_ai_data (unsigned char ai, unsigned char data)
  200. {
  201. if (port_mode == UCON64_SPP)
  202. spp_set_ai_data (ai, data); // SPP mode
  203. else
  204. epp_set_ai_data (ai, data); // EPP mode
  205. }
  206. static void
  207. write_data (unsigned char data)
  208. {
  209. if (port_mode == UCON64_SPP)
  210. spp_write_data (data); // SPP write data
  211. else
  212. outportb (port_c, data); // EPP write data
  213. }
  214. static unsigned char
  215. read_data (void)
  216. {
  217. if (port_mode == UCON64_SPP)
  218. return spp_read_data (); // SPP read data
  219. else
  220. return inportb (port_c); // EPP read data
  221. }
  222. static void
  223. init_port (void)
  224. {
  225. #ifndef USE_PPDEV
  226. outportb (port_9, 1); // clear EPP time flag
  227. #endif
  228. set_ai_data ((unsigned char) 2, 0); // rst=0, wei=0(dis.), rdi=0(dis.)
  229. set_ai_data ((unsigned char) 2, 0x80); // rst=1, wei=0(dis.), rdi=0(dis.)
  230. }
  231. static void
  232. end_port (void)
  233. {
  234. set_ai_data ((unsigned char) 2, 0); // rst=0, wei=0(dis.), rdi=0(dis.)
  235. outportb (port_a, 4); // ninit=1, nwrite=1
  236. }
  237. static void
  238. set_adr (unsigned int adr)
  239. {
  240. set_ai_data ((unsigned char) 0, (unsigned char) adr); // a[7..0]
  241. set_ai_data ((unsigned char) 1, (unsigned char) (adr >> 8)); // a[15..8]
  242. set_ai (3);
  243. set_data_read // ninit=0, nwrite=1
  244. }
  245. static void
  246. set_adr_long (unsigned int adr, int ignore_xh) // real address
  247. {
  248. unsigned char xh, h, m, l;
  249. set_ai_data ((unsigned char) 2, 0x80); // disable wr/rd inc.
  250. l = (unsigned char) adr; // a7-a0
  251. m = (unsigned char) (adr >> 8) & 0x3f; // a13-a8
  252. h = (unsigned char) (adr >> 14) & 0xff; // a21-a13
  253. if (h)
  254. m |= 0x40; // > bank 0
  255. if (!ignore_xh)
  256. {
  257. xh = (unsigned char) (adr >> 22) & 0x7; // max. 256Mbit
  258. if (xh)
  259. m |= 0x40; // > bank 0
  260. set_adr (0x3000); // write 3000:xh
  261. set_data_write
  262. write_data (xh); // set ROM bank extend value
  263. }
  264. set_adr (0x2000); // write 2000:h
  265. set_data_write
  266. write_data (h); // set ROM bank value
  267. set_ai_data ((unsigned char) 1, m); // a[15..8]
  268. set_ai_data ((unsigned char) 0, l); // a[7..0]
  269. }
  270. static void
  271. set_bank (unsigned int adr, unsigned char bank)
  272. {
  273. set_ai_data ((unsigned char) 2, 0x80); // disable inc
  274. set_ai_data ((unsigned char) 0, (unsigned char) adr); // a[7..0]
  275. set_ai_data ((unsigned char) 1, (unsigned char) ((adr >> 8) & 0x7f)); // a[15..8]
  276. set_ai_data ((unsigned char) 3, bank); // write bank no
  277. set_data_read // ninit=0, nwrite=1
  278. }
  279. static void
  280. out_byte_eeprom (unsigned char data)
  281. {
  282. set_ai_data ((unsigned char) 2, 0x82); // wei enable
  283. set_ai (3); // default write mode
  284. // set_data_read // ninit=0, nwrite=1
  285. set_data_write
  286. write_data (data); // out data
  287. set_ai_data ((unsigned char) 2, 0x80); // wei disable
  288. set_ai (3); // default write mode
  289. }
  290. static void
  291. out_byte (unsigned char data)
  292. {
  293. set_ai (3);
  294. // set_data_read // ninit=0, nwrite=1
  295. set_data_write
  296. write_data (data); // out data
  297. }
  298. static void
  299. out_data (unsigned char h, unsigned char m, unsigned char l, unsigned char data)
  300. {
  301. // ai[]=2 w control d7=rs,d1=xwe_en,d0=cs_en
  302. h = ((h << 2) | (m >> 6)) & 0x1f; // maximum bank is 1f
  303. if (h)
  304. m = (m & 0x3f) | 0x40; // > bank 0
  305. else
  306. m = m & 0x3f; // bank 0
  307. set_adr (0x2000); // write 2000:h
  308. set_data_write
  309. write_data (h); // set ROM bank value
  310. set_ai_data ((unsigned char) 1, m); // a[15..8]
  311. set_ai_data ((unsigned char) 0, l); // a[7..0]
  312. out_byte_eeprom (data); // write data to EEPROM
  313. }
  314. static void
  315. out_adr2_data (unsigned int adr, unsigned char data) // address shift 1 bit
  316. {
  317. set_adr_long (adr << 1, 1); // adr x 2
  318. out_byte_eeprom (data); // write data to EEPROM
  319. }
  320. static void
  321. out_adr_data (unsigned int adr, unsigned char data) // real address
  322. {
  323. set_adr_long (adr, 0);
  324. out_byte_eeprom (data); // write data to EEPROM
  325. }
  326. static void
  327. out_adr_data_32k (unsigned int adr, unsigned char data)
  328. {
  329. set_adr (adr);
  330. out_byte_eeprom (data); // write data to EEPROM
  331. }
  332. static unsigned char
  333. read_byte (void)
  334. {
  335. set_ai (3); // default write mode
  336. set_data_read // ninit=0, nwrite=1
  337. return read_data ();
  338. }
  339. static void
  340. enable_protection (void)
  341. {
  342. // set_bank (0x2000,0); // set bank 0
  343. out_data (0, 0x55, 0x55, 0xaa); // adr2,adr1,adr0,data 05555:aa
  344. out_data (0, 0x2a, 0xaa, 0x55);
  345. out_data (0, 0x55, 0x55, 0xa0);
  346. }
  347. /*
  348. static void
  349. disable_protection (void)
  350. {
  351. out_data (0, 0x55, 0x55, 0xaa); // adr2,adr1,adr0,data 05555:aa
  352. out_data (0, 0x2a, 0xaa, 0x55);
  353. out_data (0, 0x55, 0x55, 0x80);
  354. out_data (0, 0x55, 0x55, 0xaa);
  355. out_data (0, 0x2a, 0xaa, 0x55);
  356. out_data (0, 0x55, 0x55, 0x20);
  357. delay_us (20000);
  358. }
  359. */
  360. #if 0
  361. static int
  362. data_polling_data (unsigned char last_data)
  363. {
  364. unsigned int timeout = 0;
  365. while (timeout++ < 0x07ffffff)
  366. if (((read_byte () ^ last_data) & 0x80) == 0)
  367. return 0;
  368. return 1; // ready to exit the while loop
  369. }
  370. #endif
  371. static int
  372. data_polling (void)
  373. {
  374. unsigned char predata, currdata;
  375. unsigned int timeout = 0;
  376. predata = read_byte () & 0x40;
  377. while (timeout++ < 0x07ffffff)
  378. {
  379. currdata = read_byte () & 0x40;
  380. if (predata == currdata)
  381. return 0;
  382. predata = currdata;
  383. }
  384. return 1;
  385. }
  386. static void
  387. reset_to_read (void) // return to read mode
  388. {
  389. out_adr2_data (0x5555, 0xaa); // 5555:aa adr2,adr1,adr0,data
  390. out_adr2_data (0x2aaa, 0x55); // 2aaa:55
  391. out_adr2_data (0x5555, 0xf0); // 5555:f0
  392. }
  393. /*
  394. static void
  395. read_status_reg_cmd (void)
  396. {
  397. out_adr2_data (0x5555, 0xaa); // 5555:aa adr2,adr1,adr0,data
  398. out_adr2_data (0x2aaa, 0x55); // 2aaa:55
  399. out_adr2_data (0x5555, 0x70); // 5555:70
  400. }
  401. */
  402. static int
  403. wait_status (void)
  404. {
  405. unsigned temp = read_byte (); // read first status byte
  406. while ((temp & 0xfc) != 0x80)
  407. {
  408. if ((temp & 0x20) == 0x20 && port_mode == UCON64_SPP)
  409. {
  410. fputs ("\nERROR: Erase failed\n", stderr);
  411. return -1;
  412. }
  413. if ((temp & 0x10) == 0x10)
  414. {
  415. fputs ("\nERROR: Programming failed\n", stderr);
  416. return -2;
  417. }
  418. temp = read_data ();
  419. }
  420. // reset_to_read ();
  421. return 0;
  422. }
  423. static int
  424. mx_erase (void)
  425. {
  426. int retval;
  427. out_adr2_data (0x5555, 0xaa); // 5555:aa adr2,adr1,adr0,data
  428. out_adr2_data (0x2aaa, 0x55); // 2aaa:55
  429. out_adr2_data (0x5555, 0x80); // 5555:80
  430. out_adr2_data (0x5555, 0xaa); // 5555:aa
  431. out_adr2_data (0x2aaa, 0x55); // 2aaa:55
  432. out_adr2_data (0x5555, 0x10); // 5555:10
  433. delay_us (100);
  434. // read_status_reg_cmd (); // send read status reg. cmd
  435. retval = wait_status () ? -1 : 0;
  436. reset_to_read ();
  437. return retval;
  438. }
  439. /*
  440. static int
  441. win_erase (void)
  442. {
  443. out_data (0, 0x55, 0x55, 0xaa); // adr2,adr1,adr0,data 05555:aa
  444. out_data (0, 0x2a, 0xaa, 0x55);
  445. out_data (0, 0x55, 0x55, 0x80);
  446. out_data (0, 0x55, 0x55, 0xaa);
  447. out_data (0, 0x2a, 0xaa, 0x55);
  448. out_data (0, 0x55, 0x55, 0x10);
  449. delay_us (20000);
  450. if (data_polling ())
  451. {
  452. fputs ("ERROR: Erase failed\n", stderr);
  453. return -1;
  454. }
  455. else
  456. return 0;
  457. }
  458. */
  459. static unsigned char
  460. intel_read_status (void)
  461. {
  462. out_adr_data (0, 0x70); // read status command
  463. return read_byte ();
  464. }
  465. static int
  466. intel_check_status (void)
  467. {
  468. unsigned int time_out = 0x8000;
  469. while (!(intel_read_status () & 0x80))
  470. {
  471. time_out--;
  472. if (time_out == 0)
  473. {
  474. fprintf (stderr, "\nERROR: Intel read status time out\n"
  475. " Status = 0x%02x\n", intel_read_status ());
  476. out_adr_data (0, 0x50); // clear status register
  477. return -1;
  478. }
  479. }
  480. return 0;
  481. }
  482. static int
  483. intel_block_erase (unsigned int block)
  484. {
  485. unsigned int time_out = 0x8000;
  486. while ((intel_read_status ()) != 0x80)
  487. {
  488. time_out--;
  489. if (time_out == 0)
  490. {
  491. fprintf (stderr, "\nERROR: Intel block erase time out\n"
  492. " Status = 0x%02x\n", intel_read_status ());
  493. return -1;
  494. }
  495. }
  496. out_adr_data (block, 0x20); // block erase
  497. out_adr_data (block, 0xd0); // write confirm
  498. time_out = 0x8000;
  499. while (!(intel_read_status () & 0x80))
  500. {
  501. time_out--;
  502. if (time_out == 0)
  503. {
  504. fprintf (stderr, "\nERROR: Intel block erase time out at 0x%x\n"
  505. " Status = 0x%02x\n", block, intel_read_status ());
  506. out_adr_data (block, 0x50); // clear status register
  507. fprintf (stderr, " Status = 0x%02x\n", intel_read_status ());
  508. return -1;
  509. }
  510. }
  511. if ((intel_read_status ()) == 0x80)
  512. return 0;
  513. else
  514. {
  515. fprintf (stderr, "\nERROR: Intel block erase error at 0x%x\n"
  516. " Status = 0x%02x\n", block, intel_read_status ());
  517. out_adr_data (block, 0x50); // clear status register
  518. fprintf (stderr, " Status = 0x%02x\n", intel_read_status ());
  519. out_adr_data (0x0000, 0xff); // read array
  520. return -1;
  521. }
  522. }
  523. /*
  524. static int
  525. intel_erase (void)
  526. {
  527. unsigned int block;
  528. for (block = 0; block < 64; block++)
  529. if (intel_block_erase (block * 0x20000))
  530. return -1;
  531. return 0;
  532. }
  533. static int
  534. erase (void)
  535. {
  536. if (eeprom_type == WINBOND)
  537. return win_erase ();
  538. else if (eeprom_type == MX)
  539. return mx_erase ();
  540. else if (eeprom_type == INTEL)
  541. return intel_erase ();
  542. fputs ("ERROR: Unknown EEPROM type\n", stderr);
  543. return -1;
  544. }
  545. */
  546. static int
  547. check_eeprom (void)
  548. {
  549. int i;
  550. // check 4M flash
  551. out_adr_data_32k (0x5555, 0xaa); // software product ID entry
  552. out_adr_data_32k (0x2aaa, 0x55);
  553. out_adr_data_32k (0x5555, 0x80);
  554. out_adr_data_32k (0x5555, 0xaa);
  555. out_adr_data_32k (0x2aaa, 0x55);
  556. out_adr_data_32k (0x5555, 0x60);
  557. delay_us (10);
  558. set_adr (0); // adr2,adr1,adr0
  559. if (read_byte () == 0xda) // manufacturer code
  560. {
  561. set_adr (1); // adr2,adr1,adr0
  562. if (read_byte () == 0x46) // device code
  563. {
  564. out_adr_data_32k (0x5555, 0xaa); // software product ID exit
  565. out_adr_data_32k (0x2aaa, 0x55); // adr2,adr1,adr0,data
  566. out_adr_data_32k (0x5555, 0xf0); // adr2,adr1,adr0,data
  567. eeprom_type = WINBOND; // Winbond 4 Mbit flash
  568. return 0;
  569. }
  570. }
  571. // check 16M flash
  572. out_adr2_data (0x5555, 0xaa); // 5555:aa software product ID entry
  573. out_adr2_data (0x2aaa, 0x55); // 2aaa:55 adr2,adr1,adr0,data
  574. out_adr2_data (0x5555, 0x90); // 5555:90 adr2,adr1,adr0,data
  575. set_adr (0); // adr2,adr1,adr0
  576. if (read_byte () == 0xc2) // manufacturer code
  577. {
  578. set_adr (2); // adr2,adr1,adr0
  579. if (read_byte () == 0xf1) // device code
  580. {
  581. reset_to_read (); // reset to read mode
  582. eeprom_type = MX; // MX 16 Mbit flash
  583. return 0;
  584. }
  585. }
  586. // check 64M flash
  587. reset_to_read ();
  588. init_port ();
  589. out_adr_data (0x0000, 0x98); // read query
  590. for (i = 0; i < 128; i += 2)
  591. {
  592. set_adr (i); // adr2,adr1,adr0
  593. buffer[i / 2] = read_byte ();
  594. }
  595. // dumper (stdout, buffer, 64, 0, DUMPER_HEX);
  596. if (buffer[0] == 0x89 && buffer[1] == 0x15
  597. && buffer[0x10] == 'Q' && buffer[0x11] == 'R' && buffer[0x12] == 'Y')
  598. {
  599. out_adr_data (0x0000, 0xff); // read array
  600. eeprom_type = INTEL; // Intel 64 Mbit flash
  601. return 0;
  602. }
  603. // eeprom_type = UNKNOWN_EEPROM;
  604. return 1;
  605. }
  606. static void
  607. check_mbc (void)
  608. // determine memory bank controller type
  609. {
  610. if (eeprom_type != UNKNOWN_EEPROM)
  611. mbc_type = BUNG;
  612. else
  613. {
  614. unsigned char rom_type = buffer[0x47];
  615. if (memcmp (buffer + 4, rocket_logodata, GB_LOGODATA_LEN) == 0)
  616. mbc_type = ROCKET; // rom_type == 0x97 || rom_type == 0x99
  617. else if (rom_type == 0)
  618. mbc_type = ROM;
  619. else if ((rom_type >= 1 && rom_type <= 3) || rom_type == 0xff)
  620. mbc_type = MBC1;
  621. else if (rom_type == 5 || rom_type == 6)
  622. mbc_type = MBC2;
  623. else if (rom_type >= 0x0f && rom_type <= 0x13)
  624. mbc_type = MBC3;
  625. else if (rom_type >= 0x19 && rom_type <= 0x1e)
  626. mbc_type = MBC5;
  627. else if (rom_type == 0x1f)
  628. mbc_type = CAMERA;
  629. else
  630. mbc_type = UNKNOWN_MBC;
  631. }
  632. }
  633. static int
  634. check_card (void)
  635. /*
  636. 16 kB ROM = 1 bank
  637. 8 kB RAM = 1 bank
  638. */
  639. {
  640. unsigned char sum = 0;
  641. char game_name[GB_NAME_LEN + 2];
  642. int gb_name_len, i;
  643. puts ("Checking ROM data...");
  644. if (mbc_type == ROCKET)
  645. puts ("NOTE: Rocket Games cartridge detected");
  646. else if (memcmp (buffer + 4, gb_logodata, GB_LOGODATA_LEN) != 0)
  647. {
  648. puts ("WARNING: Cartridge does not contain official Nintendo logo data");
  649. dumper (stdout, buffer, 0x50, 0x100, DUMPER_HEX);
  650. }
  651. gb_name_len = (buffer[0x43] == 0x80 || buffer[0x43] == 0xc0) ?
  652. GB_NAME_LEN : GB_NAME_LEN + 1;
  653. memcpy (game_name, buffer + 0x34, gb_name_len);
  654. game_name[gb_name_len] = 0;
  655. for (i = 0; i < gb_name_len; i++)
  656. if (!isprint ((int) game_name[i]) && game_name[i] != 0)
  657. game_name[i] = '.';
  658. printf ("Game name: \"%s\"\n", game_name);
  659. if (buffer[0x48] > 8) // ROM size
  660. printf ("NOTE: Strange ROM size byte value in header (0x%02x)\n", buffer[0x48]);
  661. if (buffer[0x49] > 5) // SRAM size
  662. printf ("NOTE: Strange RAM size byte value in header (0x%02x)\n", buffer[0x49]);
  663. /*
  664. // [47] = ROM type
  665. if (buffer[0x47] > 0 && buffer[0x47] < 4 && buffer[0x48] > 4)
  666. mbc1_exp = 1; // MBC1 8 Mbit/16 Mbit
  667. */
  668. for (i = 0x34; i < 0x4d; i++)
  669. sum += ~buffer[i];
  670. if (buffer[0x4d] != sum)
  671. printf ("NOTE: Incorrect header checksum (0x%02x), should be 0x%02x\n",
  672. buffer[0x4d], sum);
  673. return (1 << (buffer[0x48] > 8 ? 9 : buffer[0x48])) * 32 * 1024;
  674. }
  675. static void
  676. set_sram_bank (unsigned char bank)
  677. // original code only did "set_adr (0x4000); out_byte (bank);"
  678. {
  679. if (eeprom_type != UNKNOWN_EEPROM)
  680. { // flash card
  681. set_adr (0x4000); // set SRAM adr
  682. out_byte (bank); // SRAM bank 0
  683. // this should be equivalent to the code above: set_bank (0x4000, bank)
  684. }
  685. else
  686. { // game cartridge
  687. switch (mbc_type)
  688. {
  689. case MBC1:
  690. set_bank (0x6000, 1);
  691. set_bank (0x4000, (unsigned char) (bank & 3));
  692. break;
  693. case MBC3:
  694. case MBC5:
  695. set_bank (0x4000, bank);
  696. break;
  697. default:
  698. break;
  699. }
  700. }
  701. }
  702. static void
  703. set_bank2 (unsigned int bank)
  704. {
  705. switch (mbc_type)
  706. {
  707. case BUNG:
  708. case UNKNOWN_MBC:
  709. case MBC5:
  710. set_bank (0x2000, (unsigned char) bank);
  711. if (eeprom_type != WINBOND)
  712. set_bank (0x3000, (unsigned char) (bank >> 8));
  713. break;
  714. case MBC1:
  715. set_bank (0x6000, 0);
  716. set_bank (0x2000, (unsigned char) (bank & 0x1f));
  717. set_bank (0x4000, (unsigned char) ((bank >> 5) & 3)); // (bank & 0x60) >> 5
  718. break;
  719. case MBC2:
  720. set_bank (0x2100, (unsigned char) (bank & 0x0f));
  721. break;
  722. case MBC3:
  723. set_bank (0x2000, (unsigned char) bank);
  724. break;
  725. case CAMERA:
  726. set_bank (0x4000, (unsigned char) bank);
  727. break;
  728. case ROCKET:
  729. set_bank (0x3f00, (unsigned char) bank);
  730. break;
  731. default:
  732. break;
  733. }
  734. }
  735. static void
  736. read_rom_16k (unsigned int bank) // ROM or EEPROM
  737. {
  738. int idx = 0, i, j;
  739. char game_name[GB_NAME_LEN + 2];
  740. set_bank2 (bank);
  741. for (j = 0; j < 64; j++)
  742. { // 16k bytes = 64 x 256 bytes
  743. if (bank)
  744. set_ai_data ((unsigned char) 1, (unsigned char) (j | 0x40)); // set adr[15..8]
  745. else
  746. set_ai_data ((unsigned char) 1, (unsigned char) j); // a[15..0]
  747. set_ai_data ((unsigned char) 0, 0); // a[7..0]
  748. set_ai_data ((unsigned char) 2, 0x81); // enable read inc.
  749. set_ai (3); // read/write data
  750. set_data_read
  751. for (i = 0; i < 256; i++) // page = 256
  752. buffer[idx + i] = read_data ();
  753. idx += 256;
  754. /*
  755. One can select the game in 2-in-1 cartridges by writing the game number
  756. to 0x3fc0. This has been verified for 2 cartridges with ROM type byte
  757. value 0x99. Maybe there exist other Rocket Games n-in-1 games with a
  758. different ROM type byte value. That's why we don't check for that
  759. specific ROM type byte value.
  760. */
  761. if (mbc_type == ROCKET && j == 1)
  762. if (memcmp (buffer + 0x104, rocket_logodata, GB_LOGODATA_LEN) == 0)
  763. {
  764. set_adr (0x3fc0);
  765. out_byte ((unsigned char) rocket_game_no++);
  766. if (bank)
  767. {
  768. // Reread the last two pages, because the data came from the
  769. // previously selected game (data is "mirrored"). This does not
  770. // apply to the first game.
  771. int k, gb_name_len;
  772. idx = 0;
  773. for (k = 0; k < 2; k++)
  774. {
  775. set_ai_data ((unsigned char) 1, (unsigned char) (k | 0x40));
  776. set_ai_data ((unsigned char) 0, 0);
  777. set_ai_data ((unsigned char) 2, 0x81);
  778. set_ai (3);
  779. set_data_read
  780. for (i = 0; i < 256; i++)
  781. buffer[idx + i] = read_data ();
  782. idx += 256;
  783. }
  784. clear_line (); // remove last gauge
  785. gb_name_len = (buffer[0x143] == 0x80 || buffer[0x143] == 0xc0) ?
  786. GB_NAME_LEN : GB_NAME_LEN + 1;
  787. memcpy (game_name, buffer + 0x134, gb_name_len);
  788. game_name[gb_name_len] = 0;
  789. for (i = 0; i < gb_name_len; i++)
  790. if (!isprint ((int) game_name[i]) && game_name[i] != 0)
  791. game_name[i] = '.';
  792. printf ("Found another game: \"%s\"\n\n", game_name);
  793. }
  794. }
  795. }
  796. }
  797. static int
  798. verify_rom_16k (unsigned int bank) // ROM or EEPROM
  799. {
  800. int idx = 0, i, j;
  801. set_bank2 (bank);
  802. for (j = 0; j < 64; j++)
  803. { // 16k bytes = 64 x 256 bytes
  804. if (bank)
  805. set_ai_data ((unsigned char) 1, (unsigned char) (j | 0x40)); // set adr[15..8]
  806. else
  807. set_ai_data ((unsigned char) 1, (unsigned char) j);
  808. set_ai_data ((unsigned char) 0, 0); // a[7..0]
  809. set_ai_data ((unsigned char) 2, 0x81); // enable read inc.
  810. set_ai (3); // read/write data
  811. set_data_read
  812. for (i = 0; i < 256; i++)
  813. if (read_data () != buffer[idx + i])
  814. {
  815. printf ("\nWARNING: Verify error at 0x%x\n",
  816. (bank * 16384) + (j * 256) + i);
  817. return -1;
  818. }
  819. idx += 256;
  820. }
  821. return 0;
  822. }
  823. static int
  824. win_write_eeprom_16k (unsigned int bank)
  825. {
  826. int wr_done, err_cnt, idx = 0, i, j;
  827. // disable_protection ();
  828. for (j = 0; j < 64; j++)
  829. { // 16k bytes = 64 x 256 bytes
  830. err_cnt = 16; // retry write counter
  831. wr_done = 1;
  832. while (wr_done)
  833. {
  834. enable_protection ();
  835. // write 256 bytes
  836. set_bank (0x2000, (unsigned char) bank); // for MCB1 16k bank
  837. if (bank)
  838. set_ai_data ((unsigned char) 1, (unsigned char) (j | 0x40)); // set adr[15..8]
  839. else
  840. set_ai_data ((unsigned char) 1, (unsigned char) j);
  841. set_ai_data ((unsigned char) 0, 0); // a[7..0]
  842. // set_ai_data ((unsigned char) 2, 0x82); // enable flash write
  843. set_ai_data ((unsigned char) 2, 0x83); // enable flash write inc.
  844. set_ai (3); // read/write data
  845. // set_ai_data ((unsigned char) 2, 0x80);
  846. for (i = 0; i < 256; i++)
  847. write_data (buffer[idx + i]); // write data to EEPROM
  848. set_ai_data ((unsigned char) 2, 0x80); // disable wr/rd inc.
  849. set_ai_data ((unsigned char) 0, 0xff); // point to xxff
  850. if (data_polling ())
  851. puts ("\nWARNING: Write error"); // was: "Write error check (d6)"
  852. wr_done = 0;
  853. // verify 256 bytes
  854. set_ai_data ((unsigned char) 0, 0); // a[7..0]
  855. set_ai_data ((unsigned char) 2, 0x81); // enable read inc.
  856. set_ai (3); // read/write data
  857. set_data_read
  858. for (i = 0; i < 256; i++)
  859. if (read_data () != buffer[idx + i])
  860. {
  861. err_cnt--;
  862. wr_done = 1;
  863. break;
  864. }
  865. if (err_cnt == 0)
  866. {
  867. fputs ("\nERROR: Programming failed after retry\n", stderr);
  868. return -1;
  869. }
  870. }
  871. idx += 256;
  872. }
  873. /*
  874. enable_protection();
  875. disable_protection();
  876. delay_us (20000);
  877. */
  878. return verify_rom_16k (bank);
  879. }
  880. static void
  881. set_page_write (void) // start page write command
  882. {
  883. out_adr2_data (0x5555, 0xaa); // 5555:aa adr2,adr1,adr0,data
  884. out_adr2_data (0x2aaa, 0x55); // 2aaa:55
  885. out_adr2_data (0x5555, 0xa0); // 5555:a0
  886. }
  887. static int
  888. page_write_128 (unsigned int bank, unsigned char hi_lo, int j, int idx)
  889. {
  890. int retry = 3, verify_ok, i;
  891. while (retry)
  892. {
  893. set_page_write (); // each page is 128 bytes
  894. set_bank (0x2000, (unsigned char) bank); // for MCB1 16k bank
  895. if (bank)
  896. set_ai_data ((unsigned char) 1, (unsigned char) (j | 0x40)); // set adr[15..8]
  897. else
  898. set_ai_data ((unsigned char) 1, (unsigned char) j);
  899. set_ai_data ((unsigned char) 0, hi_lo); // a[7..0]
  900. set_ai_data ((unsigned char) 2, 0x83); // enable flash write inc.
  901. set_ai (3); // read/write data
  902. for (i = 0; i < 128; i++)
  903. write_data (buffer[idx + i]); // write data to EEPROM
  904. set_ai_data ((unsigned char) 2, 0x80); // disable wr/rd inc.
  905. delay_us (10); // delay is large enough? - dbjh
  906. if (wait_status ())
  907. return -1; // wait_status() prints error message
  908. // verify data
  909. reset_to_read (); // return to read mode
  910. verify_ok = 1; // verify OK
  911. set_bank (0x2000, (unsigned char) bank); // for MCB1 16k bank
  912. if (bank)
  913. set_ai_data ((unsigned char) 1, (unsigned char) (j | 0x40)); // set adr[15..8]
  914. else
  915. set_ai_data ((unsigned char) 1, (unsigned char) j);
  916. set_ai_data ((unsigned char) 0, hi_lo); // a[7..0]
  917. set_ai_data ((unsigned char) 2, 0x81); // enable inc.
  918. set_ai (3); // read/write data
  919. set_data_read
  920. for (i = 0; i < 128; i++) // page = 128
  921. if (read_data () != buffer[idx + i])
  922. {
  923. verify_ok = 0; // verify error
  924. break;
  925. }
  926. if (verify_ok)
  927. break;
  928. else
  929. {
  930. retry--;
  931. if (retry == 0)
  932. {
  933. fputs ("\nERROR: Programming failed after retry\n", stderr);
  934. return -1;
  935. }
  936. }
  937. }
  938. return 0;
  939. }
  940. static int
  941. mx_write_eeprom_16k (unsigned int bank)
  942. {
  943. int idx = 0, j;
  944. for (j = 0; j < 64; j++)
  945. { // 16k bytes = 64 x 256 bytes
  946. if (page_write_128 (bank, 0, j, idx)) // write first 128 bytes
  947. return -1;
  948. idx += 128;
  949. if (page_write_128 (bank, 0x80, j, idx)) // write second 128 bytes
  950. return -1;
  951. idx += 128;
  952. }
  953. reset_to_read (); // return to read mode
  954. return verify_rom_16k (bank);
  955. }
  956. /*
  957. static void
  958. dump_intel_data (void)
  959. {
  960. int i;
  961. out_adr_data (0, 0xff); // read array command
  962. for (i = 0; i < 64; i++)
  963. { // read 0x100-0x150 to buffer
  964. set_adr (i);
  965. buffer[i] = read_data ();
  966. }
  967. dumper (stdout, buffer, 64, 0, DUMPER_HEX);
  968. }
  969. static int
  970. intel_byte_write_32 (unsigned int block_adr, int idx)
  971. {
  972. int time_out, i;
  973. for (i = 0; i < 32; i++)
  974. {
  975. out_adr_data (block_adr + idx + i, 0x40); // Write byte command
  976. out_adr_data (block_adr + idx + i, buffer[idx + i]); // Write data
  977. time_out = 0x8000;
  978. if (intel_check_status ())
  979. {
  980. fprintf (stderr, "\nERROR: Intel byte write command time out\n"
  981. " Status = 0x%02x\n", intel_read_status ());
  982. // dump_intel_data ();
  983. return -1;
  984. }
  985. }
  986. if (intel_read_status () == 0x80)
  987. return 0;
  988. else
  989. return -1; // error
  990. }
  991. */
  992. static int
  993. intel_buffer_write_32 (unsigned int block_adr, int idx)
  994. {
  995. int time_out = 0x80000, i;
  996. out_adr_data (block_adr + idx, 0xe8); // Write buffer command
  997. set_ai_data ((unsigned char) 2, 0x82); // wei enable
  998. set_ai (3); // default write mode
  999. // write_data (0xe8); // Write buffer command
  1000. set_data_read // ninit=0, nwrite=1
  1001. while (!(read_data () & 0x80))
  1002. {
  1003. time_out--;
  1004. if (time_out == 0)
  1005. {
  1006. fprintf (stderr, "\nERROR: Intel buffer write command time out\n"
  1007. " Status = 0x%02x\n", intel_read_status ());
  1008. // dump_intel_data ();
  1009. return -1;
  1010. }
  1011. set_data_write
  1012. write_data (0xe8); // out data
  1013. set_data_read
  1014. // out_byte_eeprom (0xe8); // write buffer command
  1015. }
  1016. // out_byte_eeprom (0x1f); // set write byte count command
  1017. write_data (0x1f); // out data
  1018. set_ai_data ((unsigned char) 2, 0x83); // enable flash write inc.
  1019. set_ai (3);
  1020. for (i = 0; i < 32; i++)
  1021. write_data (buffer[idx + i]); // write data to EEPROM
  1022. write_data (0xd0); // write confirm command
  1023. return 0;
  1024. }
  1025. static int
  1026. intel_write_eeprom_16k (unsigned int bank)
  1027. {
  1028. unsigned int block_adr = bank << 14; // convert to real address
  1029. int idx, j;
  1030. if ((bank & 0x07) == 0)
  1031. if (intel_block_erase (block_adr))
  1032. return -1;
  1033. // set_adr_long (block_adr, 0); // set real address
  1034. for (j = 0; j < 512; j++)
  1035. { // 16k bytes = 512 x 32 bytes
  1036. idx = j * 32;
  1037. // if (intel_byte_write_32 (block_adr, idx)) return -1;
  1038. if (intel_buffer_write_32 (block_adr, idx))
  1039. {
  1040. fprintf (stderr, "\nERROR: Write error\n"
  1041. " Status = 0x%02x\n", intel_read_status ());
  1042. return -1;
  1043. }
  1044. }
  1045. if (intel_check_status ())
  1046. {
  1047. fprintf (stderr, "\nERROR: Intel buffer write command error\n"
  1048. " Status = 0x%02x\n", intel_read_status ());
  1049. // dump_intel_data();
  1050. return -1;
  1051. }
  1052. if (intel_read_status () != 0x80)
  1053. return -1; // error
  1054. out_adr_data (0, 0xff); // read array
  1055. set_data_read
  1056. return verify_rom_16k (bank);
  1057. }
  1058. static int
  1059. write_eeprom_16k (unsigned int bank)
  1060. {
  1061. if (eeprom_type == WINBOND) // Winbond 4 Mbits EEPROM
  1062. return win_write_eeprom_16k (bank);
  1063. if (eeprom_type == MX) // MX 16 Mbits EEPROM
  1064. return mx_write_eeprom_16k (bank);
  1065. if (eeprom_type == INTEL) // Intel 64 Mbits EEPROM
  1066. return intel_write_eeprom_16k (bank);
  1067. return -1;
  1068. }
  1069. static void
  1070. enable_sram_bank (void)
  1071. {
  1072. init_port ();
  1073. set_adr (0x0000); // write 0x0000:0x0a default read mode
  1074. out_byte (0x0a); // enable SRAM
  1075. out_byte (0xc0); // disable SRAM
  1076. set_adr (0xa000);
  1077. out_byte (0xa0); // ctr index
  1078. set_adr (0xa100);
  1079. // out_byte(0x00); // ram_off,ram_bank_disable,MBC1
  1080. out_byte (0xc0); // ram_on,ram_bank_enable,MBC1
  1081. set_adr (0x0000); // write 0x0000:0x0a
  1082. out_byte (0x0a); // enable SRAM
  1083. }
  1084. /*
  1085. static void
  1086. usage (char *progname)
  1087. {
  1088. fprintf (stderr, "Usage: %s [-option] <Filename>\n", progname);
  1089. fprintf (stderr, "-l : load ROM file to GB Card.\n");
  1090. fprintf (stderr, "-lsa : load 256k/1Mbits sram from PC to GB Card.\n");
  1091. fprintf (stderr,
  1092. "-lsn : load 64kbits sram file from PC to specific sram bank(-n) in GB card.\n");
  1093. fprintf (stderr, "-lsc : load 1Mbits sram file from PC to Pocket Camera.\n");
  1094. fprintf (stderr, "-b : auto-detect size and backup entire GB Card to PC.\n");
  1095. fprintf (stderr, "-ba : backup full 4Mbits/16Mbits GB Card to PC.\n");
  1096. fprintf (stderr, "-bsa : retrieve all sram data (256k/1Mbits) from GB Card to PC.\n");
  1097. fprintf (stderr,
  1098. "-bsn : retrieve specific bank(-n) sram data(64kbits) from GB Card to PC.\n");
  1099. fprintf (stderr, "-bsc : retrieve 1Mbits sram from Pocket Camera to PC.\n");
  1100. fprintf (stderr, "-v : verify file in PC with GB Card.\n");
  1101. fprintf (stderr, "-e : erase Flash rom.\n");
  1102. fprintf (stderr, "-c : check ROM file header.\n");
  1103. exit (2);
  1104. }
  1105. */
  1106. static int
  1107. check_port_mode (void)
  1108. {
  1109. init_port ();
  1110. set_ai_data ((unsigned char) 1, 0x12);
  1111. set_ai_data ((unsigned char) 0, 0x34);
  1112. set_ai (1);
  1113. set_data_read // ninit=0, nwrite=1
  1114. if (read_data () != 0x12)
  1115. return 1;
  1116. set_ai (0);
  1117. set_data_read // ninit=0, nwrite=1
  1118. if (read_data () != 0x34)
  1119. return 1;
  1120. end_port ();
  1121. return 0;
  1122. }
  1123. static int
  1124. check_port (void)
  1125. {
  1126. if (ucon64.parport_mode == UCON64_EPP && port_8 != 0x3bc)
  1127. port_mode = UCON64_EPP; // if port == 0x3bc => no EPP available
  1128. else
  1129. port_mode = UCON64_SPP;
  1130. if (check_port_mode ())
  1131. {
  1132. port_mode = UCON64_SPP;
  1133. if (check_port_mode ())
  1134. return 1;
  1135. else
  1136. end_port ();
  1137. }
  1138. // If we get here, a GBX was detected
  1139. if (port_mode == UCON64_EPP)
  1140. puts ("GBX found. EPP found");
  1141. else
  1142. puts ("GBX found. EPP not found or not enabled - SPP used");
  1143. return 0;
  1144. }
  1145. #if 0 // not used
  1146. static void
  1147. win_id (void)
  1148. {
  1149. out_data (0, 0x55, 0x55, 0xaa); // software product ID entry
  1150. out_data (0, 0x2a, 0xaa, 0x55); // adr2,adr1,adr0,data
  1151. out_data (0, 0x55, 0x55, 0x80); // adr2,adr1,adr0,data
  1152. out_data (0, 0x55, 0x55, 0xaa); // adr2,adr1,adr0,data
  1153. out_data (0, 0x2a, 0xaa, 0x55); // adr2,adr1,adr0,data
  1154. out_data (0, 0x55, 0x55, 0x60); // adr2,adr1,adr0,data
  1155. delay_us (10);
  1156. set_adr (0); // adr2,adr1,adr0
  1157. printf ("Manufacturer code: 0x%02x\n", read_byte ());
  1158. set_adr (1); // adr2,adr1,adr0
  1159. printf ("Device code: 0x%02x\n", read_byte ());
  1160. /*
  1161. set_adr (2); // adr2,adr1,adr0
  1162. printf ("First 16 k protection code: 0x%02x\n", read_byte ());
  1163. set_bank (0x2000, 0x1f);
  1164. set_adr (0x7ff2); // adr2,adr1,adr0=0x7fff2
  1165. printf("Last 16 k protection code: 0x%02x\n", read_byte ());
  1166. */
  1167. out_data (0, 0x55, 0x55, 0xaa); // software product ID exit
  1168. out_data (0, 0x2a, 0xaa, 0x55); // adr2,adr1,adr0,data
  1169. out_data (0, 0x55, 0x55, 0xf0); // adr2,adr1,adr0,data
  1170. }
  1171. static void
  1172. mx_id (void)
  1173. {
  1174. out_adr2_data (0x5555, 0xaa); // software product ID entry
  1175. out_adr2_data (0x2aaa, 0x55); // adr2,adr1,adr0,data
  1176. out_adr2_data (0x5555, 0x90); // adr2,adr1,adr0,data
  1177. set_adr (0); // adr2,adr1,adr0
  1178. printf ("Manufacturer code: 0x%02x\n", read_byte ());
  1179. set_adr (2); // adr2,adr1,adr0
  1180. printf ("Device code: 0x%02x\n", read_byte ());
  1181. set_adr (4); // adr2,adr1,adr0
  1182. printf ("First 16 k protection code: 0x%02x\n", read_byte ());
  1183. reset_to_read (); // reset to read mode
  1184. }
  1185. static void
  1186. intel_id (void)
  1187. {
  1188. int i;
  1189. out_adr_data (0, 0x98); // read query
  1190. for (i = 0; i < 128; i += 2)
  1191. {
  1192. set_adr (i); // adr2,adr1,adr0
  1193. buffer[i / 2] = read_byte ();
  1194. }
  1195. // dumper (stdout, buffer, 64, 0, DUMPER_HEX);
  1196. printf ("Manufacture code = 0x%02x\n", buffer[0]);
  1197. printf ("Device code = 0x%02x\n", buffer[1]);
  1198. }
  1199. static void
  1200. disp_id (void)
  1201. {
  1202. if (eeprom_type == WINBOND)
  1203. win_id ();
  1204. if (eeprom_type == MX)
  1205. mx_id ();
  1206. if (eeprom_type == INTEL)
  1207. intel_id ();
  1208. }
  1209. static void
  1210. gen_pat (unsigned int offset)
  1211. {
  1212. int i;
  1213. for (i = 0; i < 0x2000; i++) // 8 k words = 16 k bytes
  1214. ((unsigned short int *) buffer)[i] = i + offset;
  1215. }
  1216. static int
  1217. test_sram_v (int n_banks)
  1218. {
  1219. int idx, i, j, bank;
  1220. enable_sram_bank ();
  1221. for (bank = 0; bank < n_banks; bank++)
  1222. {
  1223. idx = 0;
  1224. set_sram_bank (bank);
  1225. gen_pat (bank);
  1226. for (j = 0; j < 0x20; j++)
  1227. { // 32 x 256 = 8192 (8 kbytes)
  1228. set_ai_data ((unsigned char) 1, (unsigned char) (0xa0 + j)); // SRAM at 0xa000-0xbfff
  1229. set_ai_data ((unsigned char) 0, 0); // a[7..0]=0
  1230. set_ai_data ((unsigned char) 2, 0x81); // enable inc
  1231. set_ai (3); // point to data r/w port
  1232. set_data_read
  1233. for (i = 0; i < 256; i++)
  1234. if (read_data () != buffer[i + idx])
  1235. {
  1236. fputs ("ERROR: SRAM verify error\n", stderr);
  1237. return -1;
  1238. }
  1239. set_ai_data ((unsigned char) 2, 0x80); // disable inc
  1240. idx += 256;
  1241. }
  1242. }
  1243. return 0;
  1244. }
  1245. static int
  1246. test_sram_wv (int n_banks)
  1247. {
  1248. int idx, i, j, bank;
  1249. enable_sram_bank ();
  1250. for (bank = 0; bank < n_banks; bank++)
  1251. {
  1252. idx = 0;
  1253. set_sram_bank (bank);
  1254. gen_pat (bank);
  1255. // dumper (stdout, buffer, 0x10, 0, DUMPER_HEX);
  1256. for (j = 0; j < 0x20; j++)
  1257. { // 32 x 256 = 8192(8kbytes)
  1258. set_ai_data ((unsigned char) 1, (unsigned char) (0xa0 + j)); // SRAM at 0xa000-0xbfff
  1259. set_ai_data ((unsigned char) 0, 0); // a[7..0]=0
  1260. set_ai_data ((unsigned char) 2, 0x81); // enable inc
  1261. set_ai (3); // point to data r/w port
  1262. set_data_write
  1263. for (i = 0; i < 256; i++)
  1264. write_data (buffer[i + idx]);
  1265. set_ai_data ((unsigned char) 2, 0x80); // disable inc
  1266. idx += 256;
  1267. }
  1268. }
  1269. return test_sram_v (n_banks);
  1270. }
  1271. int cart_type = 0; // should be set to value of ROM[0x147]
  1272. static void
  1273. set_rom_bank (unsigned char bank)
  1274. {
  1275. // cart_type < 4 is MCB1, other is MCB2
  1276. if (cart_type < 4)
  1277. set_bank (0x2000, bank); // for MCB1
  1278. else
  1279. set_bank (0x2100, bank); // for MCB2
  1280. }
  1281. static void
  1282. try_read (void)
  1283. {
  1284. int i;
  1285. set_ai_data ((unsigned char) 0, 0); // a[7..0]=0
  1286. set_ai_data ((unsigned char) 1, 0x40);
  1287. set_ai_data ((unsigned char) 2, 0x81); // enable inc
  1288. set_ai (3); // point to data r/w port
  1289. for (i = 0; i < 16; i++)
  1290. buffer[i] = read_data ();
  1291. dumper (stdout, buffer, 16, 0, DUMPER_HEX);
  1292. }
  1293. static void
  1294. try_read0 (void)
  1295. {
  1296. int j;
  1297. set_rom_bank (1);
  1298. for (j = 0; j < 4; j++)
  1299. {
  1300. set_sram_bank ((unsigned char) j);
  1301. try_read ();
  1302. }
  1303. set_bank (0x6000, (unsigned char) 1);
  1304. puts ("6000:1");
  1305. for (j = 0; j < 4; j++)
  1306. {
  1307. set_sram_bank ((unsigned char) j);
  1308. try_read ();
  1309. }
  1310. set_bank (0x6000, (unsigned char) 0);
  1311. puts ("6000:0");
  1312. for (j = 0; j < 4; j++)
  1313. {
  1314. set_sram_bank ((unsigned char) j);
  1315. try_read ();
  1316. }
  1317. }
  1318. static void
  1319. test_intel (void)
  1320. {
  1321. int i;
  1322. out_adr2_data (0x0000, 0x90); // software product ID entry
  1323. for (i = 0; i < 128; i += 2)
  1324. {
  1325. set_adr (i); // adr2,adr1,adr0
  1326. buffer[i / 2] = read_byte ();
  1327. }
  1328. dumper (stdout, buffer, 64, 0, DUMPER_HEX);
  1329. out_adr2_data (0x0000, 0x70); // read status register
  1330. printf ("Status register = 0x%02x\n", read_byte ());
  1331. }
  1332. static void gbx_init (unsigned short parport, int read_header);
  1333. static int
  1334. verify_card_from_file (const char *filename, unsigned int parport)
  1335. {
  1336. unsigned int bank, n_banks, filesize;
  1337. FILE *file;
  1338. time_t starttime;
  1339. gbx_init (parport, 1);
  1340. filesize = fsizeof (filename);
  1341. if ((filesize < 0x8000) || (filesize & 0x7fff) || (filesize > 64 * MBIT))
  1342. {
  1343. fputs ("ERROR: File size error\n", stderr);
  1344. exit (1);
  1345. }
  1346. if ((file = fopen (filename, "rb")) == NULL)
  1347. {
  1348. fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
  1349. exit (1);
  1350. }
  1351. n_banks = (filesize / 0x8000) * 2; // how many 16k banks (rounded
  1352. starttime = time (NULL); // down to 32k boundary)
  1353. for (bank = 0; bank < n_banks; bank++)
  1354. {
  1355. if (fread (buffer, 1, 0x4000, file) != 0x4000)
  1356. {
  1357. fprintf (stderr, ucon64_msg[READ_ERROR], filename);
  1358. fclose (file);
  1359. exit (1);
  1360. }
  1361. /*
  1362. if (bank == 0)
  1363. {
  1364. // [0x147] = ROM type; [0x148] = ROM size
  1365. if (buffer[0x147] > 0 && buffer[0x147] < 4 && buffer[0x148] > 4)
  1366. mbc1_exp = 1; // MBC1 8 Mbit/16 Mbit
  1367. }
  1368. */
  1369. if (verify_eeprom_16k (bank))
  1370. {
  1371. printf ("Verify card error at bank 0x%x\n", bank);
  1372. fclose (file);
  1373. exit (1);
  1374. }
  1375. ucon64_gauge (starttime, (bank + 1) * 0x4000, filesize);
  1376. }
  1377. fclose (file);
  1378. puts ("\nVerify card OK");
  1379. return 0;
  1380. }
  1381. #endif
  1382. static void
  1383. gbx_init (unsigned short parport, int read_header)
  1384. {
  1385. int i;
  1386. eeprom_type = UNKNOWN_EEPROM;
  1387. rocket_game_no = 0;
  1388. port_8 = parport;
  1389. port_9 = parport + 1;
  1390. port_a = parport + 2;
  1391. port_b = parport + 3;
  1392. port_c = parport + 4;
  1393. parport_print_info ();
  1394. if (check_port () != 0)
  1395. {
  1396. fputs ("ERROR: GBX not found or not turned on\n", stderr);
  1397. exit (1);
  1398. }
  1399. init_port ();
  1400. check_eeprom ();
  1401. if (read_header)
  1402. for (i = 0x100; i < 0x150; i++)
  1403. { // read 0x100-0x150 to buffer
  1404. set_adr (i);
  1405. buffer[i - 0x100] = read_data ();
  1406. }
  1407. /*
  1408. buffer is undefined if read_header == 0. This is not a problem as
  1409. read_header is only 0 if a flash card should be programmed
  1410. (gbx_write_rom()). In that case check_mbc() won't use buffer.
  1411. */
  1412. check_mbc ();
  1413. }
  1414. int
  1415. gbx_read_rom (const char *filename, unsigned short parport)
  1416. {
  1417. unsigned int bank, n_banks, rom_size, n_bytes = 0, totalbytes;
  1418. time_t starttime;
  1419. FILE *file;
  1420. gbx_init (parport, 1);
  1421. rom_size = check_card ();
  1422. if ((file = fopen (filename, "wb")) == NULL)
  1423. {
  1424. fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
  1425. end_port ();
  1426. exit (1);
  1427. }
  1428. /*
  1429. 0 256 kbit = 32 kB = 2 banks
  1430. 1 512 kbit = 64 kB = 4 banks
  1431. 2 1 Mbit = 128 kB = 8 banks
  1432. 3 2 Mbit = 256 kB = 16 banks
  1433. 4 4 Mbit = 512 kB = 32 banks
  1434. 5 8 Mbit = 1 MB = 64 banks
  1435. 6 16 Mbit = 2 MB = 128 banks
  1436. */
  1437. n_banks = rom_size / (16 * 1024);
  1438. if (eeprom_type == WINBOND)
  1439. n_banks = 32; // backup 4 Mbit
  1440. if (eeprom_type == MX)
  1441. n_banks = 128; // backup 16 Mbit
  1442. if (eeprom_type == INTEL)
  1443. n_banks = 512; // backup 64 Mbit
  1444. totalbytes = n_banks * 16 * 1024;
  1445. printf ("Receive: %d Bytes (%.4f Mb)\n\n", totalbytes, (float) totalbytes / MBIT);
  1446. starttime = time (NULL);
  1447. for (bank = 0; bank < n_banks; bank++)
  1448. {
  1449. read_rom_16k (bank);
  1450. if (verify_rom_16k (bank))
  1451. printf ("Verify card error at bank 0x%x\n", bank);
  1452. fwrite (buffer, 1, 0x4000, file);
  1453. n_bytes += 16 * 1024;
  1454. ucon64_gauge (starttime, n_bytes, totalbytes);
  1455. }
  1456. fclose (file);
  1457. end_port ();
  1458. return 0;
  1459. }
  1460. int
  1461. gbx_write_rom (const char *filename, unsigned short parport)
  1462. {
  1463. int bank, n_banks, n_bytes = 0;
  1464. time_t starttime;
  1465. FILE *file;
  1466. gbx_init (parport, 0);
  1467. if (eeprom_type == UNKNOWN_EEPROM)
  1468. {
  1469. fputs ("ERROR: Unknown EEPROM type\n", stderr);
  1470. end_port ();
  1471. exit (1);
  1472. }
  1473. if ((ucon64.file_size < 0x8000) || (ucon64.file_size & 0x7fff) ||
  1474. (ucon64.file_size > 64 * MBIT))
  1475. {
  1476. fputs ("ERROR: File size error\n", stderr);
  1477. exit (1);
  1478. }
  1479. n_banks = (ucon64.file_size / 0x8000) * 2; // how many 16k banks (rounded
  1480. // down to 32k boundary)
  1481. if (eeprom_type == MX)
  1482. if (mx_erase ()) // erase 16M flash
  1483. {
  1484. // wait_status() prints error message
  1485. end_port ();
  1486. exit (1);
  1487. }
  1488. if ((file = fopen (filename, "rb")) == NULL)
  1489. {
  1490. fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
  1491. end_port ();
  1492. exit (1);
  1493. }
  1494. printf ("Send: %d Bytes (%.4f Mb)\n\n",
  1495. n_banks * 0x4000, (float) (n_banks * 0x4000) / MBIT);
  1496. starttime = time (NULL);
  1497. for (bank = 0; bank < n_banks; bank++)
  1498. {
  1499. if (fread (buffer, 1, 0x4000, file) != 0x4000)
  1500. {
  1501. fprintf (stderr, ucon64_msg[READ_ERROR], filename);
  1502. fclose (file);
  1503. end_port ();
  1504. exit (1);
  1505. }
  1506. if (write_eeprom_16k (bank))
  1507. {
  1508. fprintf (stderr, "ERROR: Write card error at bank 0x%x\n", bank);
  1509. fclose (file);
  1510. end_port ();
  1511. exit (1);
  1512. }
  1513. n_bytes += 0x4000;
  1514. ucon64_gauge (starttime, n_bytes, ucon64.file_size);
  1515. }
  1516. #if 0 // write_eeprom_16k() already calls verify_rom_16k() (indirectly)...
  1517. clear_line (); // remove last gauge
  1518. puts ("Verifying card...\n");
  1519. fseek (file, 0, SEEK_SET);
  1520. n_bytes = 0;
  1521. starttime = time (NULL);
  1522. for (bank = 0; bank < n_banks; bank++)
  1523. {
  1524. if (fread (buffer, 1, 0x4000, file) != 0x4000)
  1525. {
  1526. fprintf (stderr, ucon64_msg[READ_ERROR], filename);
  1527. fclose (file);
  1528. end_port ();
  1529. exit (1);
  1530. }
  1531. if (verify_rom_16k (bank))
  1532. {
  1533. fprintf (stderr, "ERROR: Verify card error at bank 0x%x\n", bank);
  1534. fclose (file);
  1535. end_port ();
  1536. exit (1);
  1537. }
  1538. n_bytes += 0x4000;
  1539. ucon64_gauge (starttime, n_bytes, ucon64.file_size);
  1540. }
  1541. #endif
  1542. fclose (file);
  1543. end_port ();
  1544. return 0;
  1545. }
  1546. static int
  1547. sram_size_banks (int pocket_camera, unsigned char sram_size_byte)
  1548. {
  1549. int n_banks;
  1550. if (eeprom_type == UNKNOWN_EEPROM)
  1551. {
  1552. // it seems reasonable that eeprom_type == UNKNOWN_EEPROM when a pocket
  1553. // camera (1 Mbit SRAM) is plugged in the GBX
  1554. if (pocket_camera)
  1555. n_banks = 16;
  1556. else // no flash card, must be game cartridge
  1557. {
  1558. int x = (sram_size_byte & 7) << 1;
  1559. if (x > 5)
  1560. x = 6;
  1561. if (x)
  1562. x = 1 << (x - 1); // SRAM size in kB
  1563. n_banks = (x + 8192 - 1) / 8192; // round up to 1 bank if it's 2 kB
  1564. }
  1565. }
  1566. else
  1567. {
  1568. // if eeprom_type != UNKNOWN_EEPROM, it has to be WINBOND, MX or INTEL (no
  1569. // need to set n_banks to a default value)
  1570. if (eeprom_type == WINBOND)
  1571. n_banks = 4; // 4 x 8 kB = 32 kB
  1572. else // if (eeprom_type == MX || eeprom_type == INTEL)
  1573. n_banks = 16; // 16 x 8 kB = 128 kB
  1574. }
  1575. return n_banks;
  1576. }
  1577. int
  1578. gbx_read_sram (const char *filename, unsigned short parport, int start_bank)
  1579. {
  1580. int bank, n_banks, n_bytes = 0, totalbytes, idx, i, j;
  1581. time_t starttime;
  1582. FILE *file;
  1583. gbx_init (parport, 1);
  1584. n_banks = sram_size_banks (buffer[0x47] == 0x1f, buffer[0x49]);
  1585. if (!n_banks)
  1586. {
  1587. fputs ("ERROR: No SRAM available\n", stderr);
  1588. end_port ();
  1589. exit (1);
  1590. }
  1591. if (start_bank == -1)
  1592. start_bank = 0;
  1593. else
  1594. {
  1595. if (start_bank >= n_banks)
  1596. {
  1597. fprintf (stderr, "ERROR: Bank must be a value 0 - %d (for this card)\n",
  1598. n_banks - 1);
  1599. end_port ();
  1600. exit (1);
  1601. }
  1602. n_banks = 1;
  1603. }
  1604. if ((file = fopen (filename, "wb")) == NULL)
  1605. {
  1606. fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
  1607. end_port ();
  1608. exit (1);
  1609. }
  1610. memset (buffer, 0, 8192);
  1611. totalbytes = n_banks * 8192;
  1612. printf ("Receive: %d Bytes (%.4f Mb)\n\n", totalbytes, (float) totalbytes / MBIT);
  1613. enable_sram_bank ();
  1614. starttime = time (NULL);
  1615. for (bank = start_bank; bank < start_bank + n_banks; bank++)
  1616. {
  1617. idx = 0;
  1618. set_sram_bank ((unsigned char) bank);
  1619. for (j = 0; j < 32; j++)
  1620. { // 32 x 256 = 8192 (8 kbytes)
  1621. set_ai_data ((unsigned char) 1, (unsigned char) (0xa0 + j)); // SRAM at 0xa000-0xbfff
  1622. set_ai_data ((unsigned char) 0, 0); // a[7..0]=0
  1623. set_ai_data ((unsigned char) 2, 0x81); // enable inc
  1624. set_ai (3); // point to data r/w port
  1625. set_data_read
  1626. for (i = 0; i < 256; i++)
  1627. buffer[idx + i] = read_data ();
  1628. set_ai_data ((unsigned char) 2, 0x80); // disable inc
  1629. idx += 256;
  1630. }
  1631. fwrite (buffer, 1, 8192, file);
  1632. n_bytes += 8192;
  1633. ucon64_gauge (starttime, n_bytes, totalbytes);
  1634. }
  1635. fclose (file);
  1636. end_port ();
  1637. return 0;
  1638. }
  1639. int
  1640. gbx_write_sram (const char *filename, unsigned short parport, int start_bank)
  1641. {
  1642. int bank, n_banks, n_bytes = 0, totalbytes, idx, i, j;
  1643. time_t starttime;
  1644. FILE *file;
  1645. gbx_init (parport, 1);
  1646. n_banks = sram_size_banks (buffer[0x47] == 0x1f, buffer[0x49]);
  1647. if (!n_banks)
  1648. {
  1649. fputs ("ERROR: No SRAM to write to\n", stderr);
  1650. end_port ();
  1651. exit (1);
  1652. }
  1653. if (start_bank == -1)
  1654. {
  1655. start_bank = 0;
  1656. n_banks = MIN (n_banks, (ucon64.file_size + 8192 - 1) / 8192); // "+ 8192 - 1" to round up
  1657. }
  1658. else
  1659. {
  1660. if (start_bank >= n_banks)
  1661. {
  1662. fprintf (stderr, "ERROR: Bank must be a value 0 - %d (for this card)\n",
  1663. n_banks - 1);
  1664. end_port ();
  1665. exit (1);
  1666. }
  1667. n_banks = 1;
  1668. }
  1669. if ((file = fopen (filename, "rb")) == NULL)
  1670. {
  1671. fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
  1672. end_port ();
  1673. exit (1);
  1674. }
  1675. memset (buffer, 0, 8192);
  1676. totalbytes = n_banks * 8192; // yes, we _send_ totalbytes bytes
  1677. printf ("Send: %d Bytes (%.4f Mb)\n\n", totalbytes, (float) totalbytes / MBIT);
  1678. enable_sram_bank ();
  1679. starttime = time (NULL);
  1680. for (bank = start_bank; bank < start_bank + n_banks; bank++)
  1681. {
  1682. idx = 0;
  1683. if (!fread (buffer, 1, 8192, file))
  1684. { // handle/allow files that are not an exact multiple of 8 kB
  1685. fprintf (stderr, ucon64_msg[READ_ERROR], filename);
  1686. fclose (file);
  1687. end_port ();
  1688. exit (1);
  1689. }
  1690. set_sram_bank ((unsigned char) bank);
  1691. for (j = 0; j < 32; j++)
  1692. { // 32 x 256 = 8192 (8 kbytes)
  1693. set_ai_data ((unsigned char) 1, (unsigned char) (0xa0 + j)); // SRAM at 0xa000-0xbfff
  1694. set_ai_data ((unsigned char) 0, 0); // a[7..0]=0
  1695. set_ai_data ((unsigned char) 2, 0x81); // enable inc
  1696. set_ai (3); // point to data r/w port
  1697. set_data_write
  1698. for (i = 0; i < 256; i++)
  1699. write_data (buffer[idx + i]);
  1700. set_ai_data ((unsigned char) 2, 0x80); // disable inc
  1701. idx += 256;
  1702. }
  1703. n_bytes += 8192;
  1704. ucon64_gauge (starttime, n_bytes, totalbytes);
  1705. }
  1706. fclose (file);
  1707. end_port ();
  1708. return 0;
  1709. }
  1710. #endif // USE_PARALLEL