1 /*
2 	This file is part of FreeIntv.
3 
4 	FreeIntv is free software: you can redistribute it and/or modify
5 	it under the terms of the GNU General Public License as published by
6 	the Free Software Foundation, either version 3 of the License, or
7 	(at your option) any later version.
8 
9 	FreeIntv is distributed in the hope that it will be useful,
10 	but WITHOUT ANY WARRANTY; without even the implied warranty of
11 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 	GNU General Public License for more details.
13 
14 	You should have received a copy of the GNU General Public License
15 	along with FreeIntv.  If not, see http://www.gnu.org/licenses/
16 */
17 
18 #include <stdio.h>
19 #include "memory.h"
20 #include "cart.h"
21 #include "osd.h"
22 
23 int isIntellicart(void);
24 int loadIntellicart(void);
25 int isROM(void);
26 int loadROM(void);
27 int getLoadMethod(void);
28 void load0(void);
29 void load1(void);
30 void load2(void);
31 void load3(void);
32 void load4(void);
33 void load5(void);
34 void load6(void);
35 void load7(void);
36 void load8(void);
37 void load9(void);
38 
39 int data[0x20000]; // rom data loaded from file
40 
41 int size = 0; // size of file read
42 
43 int pos = 0; // current position in data
44 
LoadCart(const char * path)45 int LoadCart(const char *path)
46 {
47 	unsigned char word[1];
48 	FILE *fp;
49 
50     printf("[INFO] [FREEINTV] Attempting to load cartridge ROM from: %s\n", path);
51 
52 	size = 0;
53 
54 	if((fp = fopen(path,"rb"))!=NULL)
55 	{
56 		while(fread(word,sizeof(word),1,fp) && size<0x20000)
57 		{
58 			data[size] = word[0];
59 			size++;
60 		}
61         fclose(fp);
62         if (feof(fp))
63         {
64             printf("[INFO] [FREEINTV] Successful cartridge load: EOF indicator set\n");
65         }
66         if (ferror(fp))
67         {
68             printf("[ERROR] [FREEINTV] Cartridge load error indicator set\n");
69         }
70 
71 		OSD_drawText(8, 7, "SIZE:");
72 		OSD_drawInt(14, 7, size, 10);
73 
74         if(isIntellicart()) // intellicart format
75         {
76 			OSD_drawText(8, 8, "INTELLICART");
77             printf("[INFO] [FREEINTV] Intellicart cartridge format detected\n");
78             return loadIntellicart();
79         }
80         else
81         {
82 			if(isROM())
83 			{
84 				OSD_drawText(8, 8, "INTELLICART");
85 				OSD_drawText(8, 9, "MISSING A8!");
86 				printf("[INFO] [FREEINTV] Possible Intellicart cartridge format detected\n");
87 				return loadROM();
88 			}
89 			else
90 			{
91 				// check cartinfo database for load method
92 				printf("[INFO] [FREEINTV] Raw ROM image. Determining load method via database.\n");
93 				switch(getLoadMethod())
94 				{
95 						case 0: load0(); break;
96 						case 1: load1(); break;
97 						case 2: load2(); break;
98 						case 3: load3(); break;
99 						case 4: load4(); break;
100 						case 5: load5(); break;
101 						case 6: load6(); break;
102 						case 7: load7(); break;
103 						case 8: load8(); break;
104 						case 9: load9(); break;
105 						default: printf("[INFO] [FREEINTV] No database match. Using default cartridge memory map.\n"); load0();
106 				}
107 			}
108         }
109         return 1; // loaded okay
110 	}
111     else
112     {
113         printf("[ERROR] [FREEINTV] Failed to load cartridge ROM file.\n");
114         return 0;
115     }
116 }
117 
readWord(void)118 int readWord(void)
119 {
120    int val;
121 
122 	pos = pos * (pos<size);
123 	val = (data[pos]<<8) | data[pos+1];
124 	pos+=2;
125 	return val;
126 }
127 
loadRange(int start,int stop)128 void loadRange(int start, int stop)
129 {
130 	while(start<=stop && pos<size) // load segment
131 	{
132 		Memory[start] = readWord();
133 		start++;
134 	}
135 }
136 
137 // http://spatula-city.org/~im14u2c/intv/jzintv-1.0-beta3/doc/rom_fmt/IntellicartManual.booklet.pdf
isIntellicart()138 int isIntellicart() // check for intellicart format rom
139 {
140 	// check magic number (used for intellicart baud rate detection)
141 	return (data[0]==0xA8);
142 }
143 
isROM()144 int isROM() // some Intellicart roms don't start with A8 for no apparent reason
145 {
146 	// the third byte should be the 1's compliment of the second byte
147 	return data[1] == (data[2]^0xFF);
148 }
149 
loadIntellicart()150 int loadIntellicart() // load intellicart format rom
151 {
152 	int start;
153 	int stop;
154 	int i, t;
155 	int segments;
156 
157 	pos = 0;
158 	segments = readWord() & 0xFF; // number of non-contiguous rom segments (drop magic number)
159 	pos++; // 1's compliment of segments (ignore)
160 
161 	for(i=0; i<segments; i++)
162 	{
163 		t = readWord(); // high bytes of segment start and stop addresses
164 		start = t & 0xFF00;
165 		stop = ((t<<8) & 0xFF00) | 0xFF;
166 		loadRange(start, stop);
167 		t = readWord(); // CRC for segment (ignored)
168 	}
169 	// Enable tables (ignored)
170 	return 1;
171 }
172 
loadROM()173 int loadROM() // load ROM formatted cart
174 {
175 	return loadIntellicart();
176 }
177 
178 // http://atariage.com/forums/topic/203179-config-files-to-use-with-various-intellivision-titles/
179 
load0()180 void load0() // default - handles majority of carts
181 {
182 	loadRange(0x5000, 0x6FFF);
183 	loadRange(0xD000, 0xDFFF);
184 	loadRange(0xF000, 0xFFFF);
185 }
186 
load1()187 void load1()
188 {
189 	loadRange(0x5000, 0x6FFF);
190 	loadRange(0xD000, 0xFFFF);
191 }
192 
load2()193 void load2()
194 {
195 	loadRange(0x5000, 0x6FFF);
196 	loadRange(0x9000, 0xBFFF);
197 	loadRange(0xD000, 0xDFFF);
198 }
199 
load3()200 void load3()
201 {
202 	loadRange(0x5000, 0x6FFF);
203 	loadRange(0x9000, 0xAFFF);
204 	loadRange(0xD000, 0xDFFF);
205 	loadRange(0xF000, 0xFFFF);
206 }
207 
load4()208 void load4()
209 {
210 	loadRange(0x5000, 0x6FFF);
211 	// [memattr] $D000 - $D3FF = RAM 8 // automatic
212 }
213 
load5()214 void load5()
215 {
216 	loadRange(0x5000, 0x7FFF);
217 	loadRange(0x9000, 0xBFFF);
218 }
219 
load6()220 void load6()
221 {
222 	loadRange(0x6000, 0x7FFF);
223 }
224 
load7()225 void load7()
226 {
227 	loadRange(0x4800, 0x67FF);
228 }
229 
load8()230 void load8()
231 {
232 	loadRange(0x5000, 0x5FFF);
233 	loadRange(0x7000, 0x7FFF);
234 }
235 
load9()236 void load9()
237 {
238 	loadRange(0x5000, 0x6FFF);
239 	loadRange(0x9000, 0xAFFF);
240 	loadRange(0xD000, 0xDFFF);
241 	loadRange(0xF000, 0xFFFF);
242 	// [memattr] $8800 - $8FFF = RAM 8 // is this automatic too???
243 }
244 
245 int fingerprints[] =
246 {
247 15702, 0, // 4-TRIS (2001) (Joseph Zbiciak)
248 11072, 0, // SDK-1600 Movable Object Demo (2002) (Joseph Zbiciak)
249 10253, 0, // ABPA Backgammon (1978) (Mattel)
250 9049,  0, // Advanced D&D - Tower of Mystery (1983) (Mattel)
251 9709,  0, // Advanced D&D - Treasure of Tarmin (1982) (Mattel)
252 11212, 0, // Advanced Dungeons and Dragons (1982) (Mattel)
253 11087, 0, // Adventure (AD&D - Cloudy Mountain) (1982) (Mattel)
254 11426, 0, // Air Strike (1982) (Mattel)
255 9766,  0, // All-Star Major League Baseball (1983) (Mattel)
256 10847, 0, // Armor Battle (1978) (Mattel)
257 9371,  0, // Astrosmash (1981) (Mattel)
258 9764,  0, // Astrosmash Competition (1981) (Mattel)
259 10908, 7, // Atlantis (1981) (Imagic)
260 10218, 0, // Auto Racing (1979) (Mattel)
261 10894, 0, // B-17 Bomber (1981) (Mattel)
262 11349, 0, // Baseball (1978) (Mattel)
263 // (missing Baseball II proto, method 3)
264 9904,  0, // BeamRider (1983) (Activision)
265 10538, 7, // Beauty and the Beast (1982) (Imagic)
266 9337,  0, // Blockade Runner (1983) (Interphase)
267 10735, 1, // Blowout (1983) (Mattel)
268 9654,  2, // Body Slam - Super Pro Wrestling (1988) (Intv Corp)
269 10921, 0, // Bomb Squad (1982) (Mattel)
270 11614, 0, // Bouncing Pixels (1999) (JRMZ Electronics)
271 9978,  0, // Boxing (1980) (Mattel)
272 9379,  0, // Brickout! (1981) (Mattel)
273 8612,  0, // Bump 'N' Jump (1982-83) (Mattel)
274 11137, 0, // BurgerTime! (1982) (Mattel)
275 11765, 0, // Buzz Bombers (1982) (Mattel)
276 8689,  0, // Carnival (1982) (Coleco-CBS)
277 11007, 0, // Castle Trailer (2003) (Arnauld Chevallier)
278 11666, 6, // Centipede (1983) (Atarisoft)
279 11477, 1, // Championship Tennis (1985) (Mattel)
280 7102,  0, // Checkers (1979) (Mattel)
281 // missing Choplifter method 5
282 // missing Choplifter method 1
283 9602,  2, // Chip Shot - Super Pro Golf (1987) (Intv Corp)
284 8402,  2, // Commando (1987) (Mattel)
285 12615, 5, // Congo Bongo (1983) (Sega)
286 10329, 0, // Crazy Clones (1981) (PD)
287 10496, 2, // Deep Pockets-Super Pro Pool and Billiards (1990) (Realtime)
288 12619, 5, // Defender (1983) (Atarisoft)
289 10665, 7, // Demon Attack (1982) (Imagic)
290 12174, 5, // Dig Dug (1987) (Intv Corp)
291 10444, 2, // Diner (1987) (Intv Corp)
292 18826, 3, // DK Arcade (1982) (IntelligentVision)
293 9395,  0, // Donkey Kong (1982) (Coleco)
294 10004, 0, // Donkey Kong Jr (1982) (Coleco)
295 14879, 0, // Doom (2002) (Joseph Zbiciak)
296 10144, 0, // Dracula (1982) (Imagic)
297 10083, 0, // Dragonfire (1982) (Imagic)
298 6406,  0, // Dreadnaught Factor, The (1983) (Activision)
299 6474,  0, // Dreadnaught Factor, The (1983) (Activision)
300 12407, 0, // Duncan's Thin Ice (1983) (Mattel)
301 11910, 0, // Easter Eggs (1981) (Mattel)
302 9499,  0, // Eggs 'n' Eyes by Scott Nudds (1996) (PD)
303 9775,  0, // Electric Company - Math Fun (1978) (CTW)
304 9066,  0, // Electric Company - Word Fun (1980) (CTW)
305 10109, 0, // Fathom (1983) (Imagic)
306 13433, 0, // Frog Bog (1982) (Mattel)
307 9676,  0, // Frogger (1983) (Parker Bros)
308 11101, 0, // GROM, The (1978) (General Instruments)
309 12756, 9, // Game Factory (Prototype) (1983) (Mattel)
310 11614, 0, // Go For the Gold (1981) (Mattel)
311 9926,  0, // Grid Shock (1982) (Mattel)
312 10621, 0, // Groovy! (1999) (JRMZ Electronics)
313 6362,  0, // Happy Trails (1983) (Activision) [o1]
314 6362,  0, // Happy Trails (1983) (Activision)
315 10224, 0, // Hard Hat (1979) (Mattel)
316 10009, 0, // Horse Racing (1980) (Mattel)
317 10552, 2, // Hover Force (1986) (Intv Corp)
318 10186, 2, // Hover Force 3D (Prototype) (1984) (Mattel)
319 9109,  0, // Hypnotic Lights (1981) (Mattel)
320 10266, 0, // Ice Trek (1983) (Imagic)
321 9533,  0, // Illusions (1983) (Mattel)
322 10266, 0, // Istar (1983) (Imagic)
323 11042, 0, // Jetsons, The - Ways With Words (1983) (Mattel)
324 9273,  1, // King of the Mountain (1982) (Mattel)
325 8809,  0, // Kool-Aid Man (1983) (Mattel)
326 9378,  0, // Lady Bug (1983) (Coleco)
327 11981, 4, // Land Battle (1982) (Mattel)
328 8281,  0, // Las Vegas Blackjack and Poker (1979) (Mattel)
329 11001, 0, // Las Vegas Roulette (1979) (Mattel)
330 6185,  0, // League of Light (Prototype) (1983) (Activision)
331 15735, 2, // Learning Fun I - Math Master Factor Fun (1987) (Intv Corp)
332 14363, 2, // Learning Fun II - Word Wizard Memory Fun (1987) (Intv Corp)
333 10644, 0, // Lock 'N' Chase (1982) (Mattel)
334 10090, 0, // Lock 'N' Chase (Improved) (1982) (Mattel)
335 10842, 0, // Loco-Motion (1982) (Mattel)
336 10304, 0, // Magic Carousel (Prototype) (1983) (Intv Corp)
337 12439, 0, // Masters of the Universe-The Power of He-Man! (1983) (Mattel)
338 9802,  0, // Maze Demo #1 (2000) (JRMZ Electronics)
339 11067, 0, // Maze Demo #2 (2000) (JRMZ Electronics)
340 10242, 0, // Melody Blaster (1983) (Mattel)
341 11108, 7, // Microsurgeon (1982) (Imagic)
342 10643, 0, // Mind Strike! (1982) (Mattel)
343 11207, 0, // Mine Hunter (2004) (Ryan Kinnen)
344 11576, 0, // Minotaur (1981) (Mattel)
345 6217,  0, // Minotaur V1.1 (1981) (Mattel)
346 6217,  0, // Minotaur (Treasure of Tarmin Hack) (1982) (Mattel)
347 6498,  0, // Minotaur V2 (1981) (Mattel)
348 9244,  0, // Mission X (1982) (Mattel)
349 10085, 0, // MOB Collision Test (2002) (Arnauld Chevallier)
350 11500, 0, // Motocross (1982) (Mattel)
351 10251, 0, // Mountain Madness - Super Pro Skiing (1987) (Intv Corp)
352 9275,  0, // Mouse Trap (1982) (Coleco)
353 10506, 0, // Mr. Basic Meets Bits 'N Bytes (1983) (Mattel)
354 11349, 8, // MTE201 Intellivision Test Cartridge (1978) (Mattel)
355 10637, 0, // NASL Soccer (1979) (Mattel)
356 9563,  0, // NBA Basketball (1978) (Mattel)
357 10626, 0, // NFL Football (1978) (Mattel)
358 9318,  0, // NHL Hockey (1979) (Mattel)
359 9301,  0, // Night Stalker (1982) (Mattel)
360 10884, 0, // Nova Blast (1983) (Imagic)
361 12646, 0, // Number Jumble (1983) (Mattel)
362 8088,  0, // PBA Bowling (1980) (Mattel)
363 10071, 0, // PGA Golf (1979) (Mattel)
364 5049,  5, // Pac-Man (1983) (Atarisoft)
365 5049,  5, // Pac-Man (1983) (Intv Corp)
366 11430, 0, // Pinball (1981) (Mattel)
367 6302,  0, // Pitfall! (1982) (Activision)
368 10490, 2, // Pole Position (1986) (Intv Corp)
369 10523, 0, // Pong (1999) (Joseph Zbiciak)
370 10115, 0, // Popeye (1983) (Parker Bros)
371 6902,  0, // Q-bert (1983) (Parker Bros)
372 8238,  0, // Reversi (1984) (Mattel)
373 10980, 0, // River Raid (1982-83) (Activision)
374 13155, 0, // Robot Rubble (1983) (Activision)
375 10270, 0, // Rockey & Bullwinckle (1983) (Mattel)
376 10090, 0, // Royal Dealer (1981) (Mattel)
377 9836,  0, // Safecracker (1983) (Imagic)
378 9923,  0, // Santa's Helper (1983) (Mattel)
379 // missing Scarfinger method 2
380 //10547, ?, // Scar Finger (Unfinished) (1983) (Mattel)
381 10420, 0, // Scooby Doo's Maze Chase (1983) (Mattel)
382 11292, 0, // Sea Battle (1980) (Mattel)
383 10760, 0, // Sears Super Video Arcade BIOS (1978) (Sears)
384 11784, 0, // Sewer Sam (1983) (Interphase)
385 10336, 0, // Shark! Shark! (1982) (Mattel) [a1]
386 10335, 0, // Shark! Shark! (1982) (Mattel)
387 10738, 0, // Sharp Shot (1982) (Mattel)
388 9888,  2, // Slam Dunk - Super Pro Basketball (1987) (Intv Corp)
389 11858, 0, // Slap Shot - Super Pro Hockey (1987) (Intv Corp)
390 11002, 0, // Snafu (1981) (Mattel)
391 10692, 0, // Soccer (Prototype) (1979) (Mattel)
392 10566, 0, // Space Armada (1981) (Mattel)
393 10018, 0, // Space Battle (1979) (Mattel)
394 10656, 0, // Space Cadet (1982) (Mattel)
395 9487,  0, // Space Hawk (1981) (Mattel)
396 // missing Spaceshuttle method 1
397 //12490, ?, // Space Shuttle (1981) (Mattel)
398 10228, 0, // Space Spartans (1981) (Mattel)
399 11692, 2, // Spiker! - Super Pro Volleyball (1988) (Intv Corp)
400 11879, 0, // Spirit V1.0 (2003) (Arnauld Chevallier)
401 10447, 2, // Stadium Mud Buggies (1988) (Intv Corp)
402 5776,  0, // Stampede (1982) (Activision)
403 10470, 0, // Star Strike (1981) (Mattel)
404 9680,  0, // Star Wars - The Empire Strikes Back (1983) (Parker Bros)
405 8789,  0, // Street (1981) (Mattel)
406 11675, 0, // Stonix Beta1.1 (2003) (Arnauld Chevallier)
407 11406, 0, // Stonix Beta1.2 (2003) (Arnauld Chevallier)
408 10230, 0, // Stonix (2004) (Arnauld Chevallier)
409 11615, 0, // Sub Hunt (1981) (Mattel)
410 11402, 0, // Super Cobra (1983) (Konami)
411 10849, 0, // Super Masters! (1982) (Mattel)
412 12534, 2, // Super Pro Decathlon (1988) (Intv Corp)
413 11689, 2, // Super Pro Football (1986) (Intv Corp)
414 10973, 0, // Super Soccer (1983) (Mattel)
415 10000, 0, // Swords and Serpents (1982) (Imagic)
416 10000, 0, // Tag-Along Todd (Ver. 3.13 Beta) (2002) (Joseph Zbiciak)
417 10575, 0, // TRON - Deadly Discs (1981) (Mattel)
418 10970, 0, // TRON - Deadly Discs - Deadly Dogs (1987) (Intv Corp)
419 11495, 0, // TRON - Maze-A-Tron (1981) (Mattel)
420 11094, 0, // TRON - Solar Sailer (1982) (Mattel)
421 11888, 0, // Takeover (1982) (Mattel)
422 9825,  0, // Tennis (1980) (Mattel)
423 11267, 0, // Tetris (2000) (Joseph Zbiciak)
424 11832, 0, // Thin Ice (Prototype) (1983) (Intv Corp)
425 13276, 0, // Thunder Castle (1982) (Mattel)
426 9992,  3, // Tower of Doom (1986) (Intv Corp)
427 8777,  0, // Triple Action (1981) (Mattel)
428 9893,  9, // Triple Challenge (1986) (Intv Corp)
429 10422, 0, // Tropical Trouble (1982) (Imagic)
430 10249, 0, // Truckin' (1983) (Imagic)
431 11365, 0, // Turbo (1983) (Coleco)
432 9949,  0, // Tutankham (1983) (Parker Bros)
433 10084, 0, // U.S. Ski Team Skiing (1980) (Mattel)
434 9871,  4, // USCF Chess (1981) (Mattel)
435 9784,  0, // Utopia (1981) (Mattel)
436 10602, 0, // Vectron (1982) (Mattel)
437 9894,  0, // Venture (1982) (Coleco)
438 10015, 0, // White Water! (1983) (Imagic)
439 11411, 0, // World Cup Football (1985) (Nice Ideas)
440 15043, 1, // World Series Major League Baseball (1983) (Mattel)
441 10887, 0, // Worm Whomper (1983) (Activision)
442 11187, 0, // Yogi's Frustration (1983) (Mattel) (unreleased)
443 11566, 0  // Zaxxon (1982) (Coleco)
444 };
445 
getLoadMethod()446 int getLoadMethod() // lazy, but it works
447 {
448 	int i;
449 	int fingerprint = 0;
450 	// find fingerprint
451 	for(i=0; i<256; i++)
452 	{
453 		fingerprint = fingerprint + data[i];
454 	}
455 	printf("[INFO] [FREEINTV] Cartridge fingerprint code: %i\n", fingerprint);
456 
457 	// find load method
458 	for (i=0; i<380; i+=2)
459 	{
460 		if(fingerprint==fingerprints[i])
461 		{
462 			printf("[INFO] [FREEINTV] Cartridge database match: memory map %i\n", fingerprints[i+1]);
463 			if(fingerprint==11349)
464 			{
465 				// Baseball or MTE Test Cart?
466 				if(size>8192) { return 8; } // load method 8 for MTE Test Cart
467 				return 0; // default method for BaseBall
468 			}
469 			return fingerprints[i+1];
470 		}
471 	}
472 	return -1;
473 }
474