gbx.c 56 KB

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