1 /*
2  * cartridge.c - cartridge emulation
3  *
4  * Copyright (C) 2001-2010 Piotr Fusik
5  * Copyright (C) 2001-2010 Atari800 development team (see DOC/CREDITS)
6  *
7  * This file is part of the Atari800 emulator project which emulates
8  * the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers.
9  *
10  * Atari800 is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * Atari800 is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Atari800; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23 */
24 
25 #include "config.h"
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 
30 #include "atari.h"
31 #include "binload.h" /* BINLOAD_loading_basic */
32 #include "cartridge.h"
33 #include "memory.h"
34 #ifdef IDE
35 #  include "ide.h"
36 #endif
37 #include "pia.h"
38 #include "rtime.h"
39 #include "util.h"
40 #ifndef BASIC
41 #include "statesav.h"
42 #endif
43 #ifdef AF80
44 #include "af80.h"
45 #endif
46 #include "log.h"
47 
48 /* #define DEBUG 1 */
49 
50 int const CARTRIDGE_kb[CARTRIDGE_LAST_SUPPORTED + 1] = {
51 	0,
52 	8,        /* CARTRIDGE_STD_8 */
53 	16,       /* CARTRIDGE_STD_16 */
54 	16,       /* CARTRIDGE_OSS_034M_16 */
55 	32,       /* CARTRIDGE_5200_32 */
56 	32,       /* CARTRIDGE_DB_32 */
57 	16,       /* CARTRIDGE_5200_EE_16 */
58 	40,       /* CARTRIDGE_5200_40 */
59 	64,       /* CARTRIDGE_WILL_64 */
60 	64,       /* CARTRIDGE_EXP_64 */
61 	64,       /* CARTRIDGE_DIAMOND_64 */
62 	64,       /* CARTRIDGE_SDX_64 */
63 	32,       /* CARTRIDGE_XEGS_32 */
64 	64,       /* CARTRIDGE_XEGS_64_07 */
65 	128,      /* CARTRIDGE_XEGS_128 */
66 	16,       /* CARTRIDGE_OSS_M091_16 */
67 	16,       /* CARTRIDGE_5200_NS_16 */
68 	128,      /* CARTRIDGE_ATRAX_128 */
69 	40,       /* CARTRIDGE_BBSB_40 */
70 	8,        /* CARTRIDGE_5200_8 */
71 	4,        /* CARTRIDGE_5200_4 */
72 	8,        /* CARTRIDGE_RIGHT_8 */
73 	32,       /* CARTRIDGE_WILL_32 */
74 	256,      /* CARTRIDGE_XEGS_256 */
75 	512,      /* CARTRIDGE_XEGS_512 */
76 	1024,     /* CARTRIDGE_XEGS_1024 */
77 	16,       /* CARTRIDGE_MEGA_16 */
78 	32,       /* CARTRIDGE_MEGA_32 */
79 	64,       /* CARTRIDGE_MEGA_64 */
80 	128,      /* CARTRIDGE_MEGA_128 */
81 	256,      /* CARTRIDGE_MEGA_256 */
82 	512,      /* CARTRIDGE_MEGA_512 */
83 	1024,     /* CARTRIDGE_MEGA_1024 */
84 	32,       /* CARTRIDGE_SWXEGS_32 */
85 	64,       /* CARTRIDGE_SWXEGS_64 */
86 	128,      /* CARTRIDGE_SWXEGS_128 */
87 	256,      /* CARTRIDGE_SWXEGS_256 */
88 	512,      /* CARTRIDGE_SWXEGS_512 */
89 	1024,     /* CARTRIDGE_SWXEGS_1024 */
90 	8,        /* CARTRIDGE_PHOENIX_8 */
91 	16,       /* CARTRIDGE_BLIZZARD_16 */
92 	128,      /* CARTRIDGE_ATMAX_128 */
93 	1024,     /* CARTRIDGE_ATMAX_1024 */
94 	128,      /* CARTRIDGE_SDX_128 */
95 	8,        /* CARTRIDGE_OSS_8 */
96 	16,       /* CARTRIDGE_OSS_043M_16 */
97 	4,        /* CARTRIDGE_BLIZZARD_4 */
98 	32,       /* CARTRIDGE_AST_32 */
99 	64,       /* CARTRIDGE_ATRAX_SDX_64 */
100 	128,      /* CARTRIDGE_ATRAX_SDX_128 */
101 	64,       /* CARTRIDGE_TURBOSOFT_64 */
102 	128,      /* CARTRIDGE_TURBOSOFT_128 */
103 	32,       /* CARTRIDGE_ULTRACART_32 */
104 	8,        /* CARTRIDGE_LOW_BANK_8 */
105 	128,      /* CARTRIDGE_SIC_128 */
106 	256,      /* CARTRIDGE_SIC_256 */
107 	512,      /* CARTRIDGE_SIC_512 */
108 	2,        /* CARTRIDGE_STD_2 */
109 	4,        /* CARTRIDGE_STD_4 */
110 	4,        /* CARTRIDGE_RIGHT_4 */
111 	32,       /* CARTRIDGE_TURBO_HIT_32 */
112 	2048,     /* CARTRIDGE_MEGA_2048 */
113 	128*1024, /* CARTRIDGE_THECART_128M */
114 	4096,     /* CARTRIDGE_MEGA_4096 */
115 	2048,     /* CARTRIDGE_MEGA_2048 */
116 	32*1024,  /* CARTRIDGE_THECART_32M */
117 	64*1024,  /* CARTRIDGE_THECART_64M */
118 	64        /* CARTRIDGE_XEGS_64_8F */
119 };
120 
121 int CARTRIDGE_autoreboot = TRUE;
122 
CartIsFor5200(int type)123 static int CartIsFor5200(int type)
124 {
125 	switch (type) {
126 	case CARTRIDGE_5200_32:
127 	case CARTRIDGE_5200_EE_16:
128 	case CARTRIDGE_5200_40:
129 	case CARTRIDGE_5200_NS_16:
130 	case CARTRIDGE_5200_8:
131 	case CARTRIDGE_5200_4:
132 		return TRUE;
133 	default:
134 		break;
135 	}
136 	return FALSE;
137 }
138 
CartIsPassthrough(int type)139 static int CartIsPassthrough(int type)
140 {
141 	return type == CARTRIDGE_SDX_64 || type == CARTRIDGE_SDX_128 ||
142 	       type == CARTRIDGE_ATRAX_SDX_64 || type == CARTRIDGE_ATRAX_SDX_128;
143 }
144 
145 CARTRIDGE_image_t CARTRIDGE_main = { CARTRIDGE_NONE, 0, 0, NULL, "" }; /* Left/Right cartridge */
146 CARTRIDGE_image_t CARTRIDGE_piggyback = { CARTRIDGE_NONE, 0, 0, NULL, "" }; /* Pass through cartridge for SpartaDOSX */
147 
148 /* The currently active cartridge in the left slot - normally points to
149    CARTRIDGE_main but can be switched to CARTRIDGE_piggyback if the main
150    cartridge is a SpartaDOS X. */
151 static CARTRIDGE_image_t *active_cart = &CARTRIDGE_main;
152 
153 /* DB_32, XEGS_32, XEGS_07_64, XEGS_128, XEGS_256, XEGS_512, XEGS_1024,
154    SWXEGS_32, SWXEGS_64, SWXEGS_128, SWXEGS_256, SWXEGS_512, SWXEGS_1024 */
set_bank_809F(int main,int old_state)155 static void set_bank_809F(int main, int old_state)
156 {
157 	if (active_cart->state & 0x80) {
158 		MEMORY_Cart809fDisable();
159 		MEMORY_CartA0bfDisable();
160 	}
161 	else {
162 		MEMORY_Cart809fEnable();
163 		MEMORY_CartA0bfEnable();
164 		MEMORY_CopyROM(0x8000, 0x9fff, active_cart->image + active_cart->state * 0x2000);
165 		if (old_state & 0x80)
166 			MEMORY_CopyROM(0xa000, 0xbfff, active_cart->image + main);
167 	}
168 }
169 
170 /* XEGS_8F_64 */
set_bank_XEGS_8F_64(void)171 static void set_bank_XEGS_8F_64(void)
172 {
173 	if (active_cart->state & 0x08)
174 		MEMORY_CopyROM(0x8000, 0x9fff, active_cart->image + (active_cart->state & ~0x08) * 0x2000);
175 	else
176 		/* $8000-$9FFF is left unconnected. */
177 		MEMORY_dFillMem(0x8000, 0xff, 0x2000);
178 }
179 
180 /* OSS_034M_16, OSS_043M_16, OSS_M091_16, OSS_8 */
set_bank_A0AF(int main,int old_state)181 static void set_bank_A0AF(int main, int old_state)
182 {
183 	if (active_cart->state < 0)
184 		MEMORY_CartA0bfDisable();
185 	else {
186 		MEMORY_CartA0bfEnable();
187 		if (active_cart->state == 0xff)
188 			/* Fill cart area with 0xFF. */
189 			MEMORY_dFillMem(0xa000, 0xff, 0x1000);
190 		else
191 			MEMORY_CopyROM(0xa000, 0xafff, active_cart->image + active_cart->state * 0x1000);
192 		if (old_state < 0)
193 			MEMORY_CopyROM(0xb000, 0xbfff, active_cart->image + main);
194 	}
195 }
196 
197 /* WILL_64, EXP_64, DIAMOND_64, SDX_64, WILL_32, ATMAX_128, ATMAX_1024,
198    ATRAX_128, ATRAX_SDX_64, TURBOSOFT_64, TURBOSOFT_128, ULTRACART_32,
199    TURBO_HIT_32, THECART_128M, THECART_32M, THECART_64M */
set_bank_A0BF(int disable_mask,int bank_mask)200 static void set_bank_A0BF(int disable_mask, int bank_mask)
201 {
202 	if (active_cart->state & disable_mask)
203 		MEMORY_CartA0bfDisable();
204 	else {
205 		MEMORY_CartA0bfEnable();
206 		MEMORY_CopyROM(0xa000, 0xbfff, active_cart->image + (active_cart->state & bank_mask) * 0x2000);
207 	}
208 }
209 
210 /* MEGA_16, MEGA_32, MEGA_64, MEGA_128, MEGA_256, MEGA_512, MEGA_1024,
211    MEGAMAX_2048, MEGA_2048 */
set_bank_80BF(void)212 static void set_bank_80BF(void)
213 {
214 	if (active_cart->state & 0x80) {
215 		MEMORY_Cart809fDisable();
216 		MEMORY_CartA0bfDisable();
217 	}
218 	else {
219 		MEMORY_Cart809fEnable();
220 		MEMORY_CartA0bfEnable();
221 		MEMORY_CopyROM(0x8000, 0xbfff, active_cart->image + (active_cart->state & 0x7f) * 0x4000);
222 	}
223 }
224 
set_bank_SDX_128(void)225 static void set_bank_SDX_128(void)
226 {
227 	if (active_cart->state & 8)
228 		MEMORY_CartA0bfDisable();
229 	else {
230 		MEMORY_CartA0bfEnable();
231 		MEMORY_CopyROM(0xa000, 0xbfff,
232 			active_cart->image + ((active_cart->state & 7) + ((active_cart->state & 0x10) >> 1)) * 0x2000);
233 	}
234 }
set_bank_SIC(int n)235 static void set_bank_SIC(int n)
236 {
237 	if (!(active_cart->state & 0x20))
238 		MEMORY_Cart809fDisable();
239 	else {
240 		MEMORY_Cart809fEnable();
241 		MEMORY_CopyROM(0x8000, 0x9fff,
242 			active_cart->image + (active_cart->state & n) * 0x4000);
243 	}
244 	if (active_cart->state & 0x40)
245 		MEMORY_CartA0bfDisable();
246 	else {
247 		MEMORY_CartA0bfEnable();
248 		MEMORY_CopyROM(0xa000, 0xbfff,
249 			active_cart->image + (active_cart->state & n) * 0x4000 + 0x2000);
250 	}
251 }
252 
253 /* MEGA_4096 */
set_bank_MEGA_4096(void)254 static void set_bank_MEGA_4096(void)
255 {
256 	if (active_cart->state == 0xff) {
257 		MEMORY_Cart809fDisable();
258 		MEMORY_CartA0bfDisable();
259 	}
260 	else {
261 		MEMORY_Cart809fEnable();
262 		MEMORY_CartA0bfEnable();
263 		MEMORY_CopyROM(0x8000, 0xbfff, active_cart->image + active_cart->state * 0x4000);
264 	}
265 }
266 /* Called on a read or write operation to page $D5. Switches banks or
267    enables/disables the cartridge pointed to by *active_cart. */
SwitchBank(int old_state)268 static void SwitchBank(int old_state)
269 {
270 	/* All bank-switched cartridges besides two BBSB's are included in
271 	   this swithch. The BBSB cartridges are not bank-switched by
272 	   access to page $D5, but in CARTRIDGE_BountyBob1() and
273 	   CARTRIDGE_BountyBob2(), so they need not be processed here. */
274 	switch (active_cart->type) {
275 	case CARTRIDGE_OSS_034M_16:
276 	case CARTRIDGE_OSS_043M_16:
277 		set_bank_A0AF(0x3000, old_state);
278 		break;
279 	case CARTRIDGE_OSS_M091_16:
280 	case CARTRIDGE_OSS_8:
281 		set_bank_A0AF(0x0000, old_state);
282 		break;
283 	case CARTRIDGE_WILL_64:
284 	case CARTRIDGE_EXP_64:
285 	case CARTRIDGE_DIAMOND_64:
286 	case CARTRIDGE_SDX_64:
287 	case CARTRIDGE_WILL_32:
288 	case CARTRIDGE_ATRAX_SDX_64:
289 		set_bank_A0BF(8, 7);
290 		break;
291 	case CARTRIDGE_DB_32:
292 	case CARTRIDGE_XEGS_32:
293 	case CARTRIDGE_SWXEGS_32:
294 		set_bank_809F(0x6000, old_state);
295 		break;
296 	case CARTRIDGE_XEGS_07_64:
297 	case CARTRIDGE_SWXEGS_64:
298 		set_bank_809F(0xe000, old_state);
299 		break;
300 	case CARTRIDGE_XEGS_8F_64:
301 		set_bank_XEGS_8F_64();
302 		break;
303 	case CARTRIDGE_XEGS_128:
304 	case CARTRIDGE_SWXEGS_128:
305 		set_bank_809F(0x1e000, old_state);
306 		break;
307 	case CARTRIDGE_XEGS_256:
308 	case CARTRIDGE_SWXEGS_256:
309 		set_bank_809F(0x3e000, old_state);
310 		break;
311 	case CARTRIDGE_XEGS_512:
312 	case CARTRIDGE_SWXEGS_512:
313 		set_bank_809F(0x7e000, old_state);
314 		break;
315 	case CARTRIDGE_XEGS_1024:
316 	case CARTRIDGE_SWXEGS_1024:
317 		set_bank_809F(0xfe000, old_state);
318 		break;
319 	case CARTRIDGE_ATRAX_128:
320 	case CARTRIDGE_ATMAX_1024:
321 		set_bank_A0BF(0x80, 0x7f);
322 		break;
323 	case CARTRIDGE_ATMAX_128:
324 	case CARTRIDGE_TURBOSOFT_64:
325 	case CARTRIDGE_TURBOSOFT_128:
326 		set_bank_A0BF(0x10, 0x0f);
327 		break;
328 	case CARTRIDGE_MEGA_16:
329 	case CARTRIDGE_MEGA_32:
330 	case CARTRIDGE_MEGA_64:
331 	case CARTRIDGE_MEGA_128:
332 	case CARTRIDGE_MEGA_256:
333 	case CARTRIDGE_MEGA_512:
334 	case CARTRIDGE_MEGA_1024:
335 	case CARTRIDGE_MEGA_2048:
336 	case CARTRIDGE_MEGAMAX_2048:
337 		set_bank_80BF();
338 		break;
339 	case CARTRIDGE_PHOENIX_8:
340 	case CARTRIDGE_BLIZZARD_4:
341 		if (active_cart->state)
342 			MEMORY_CartA0bfDisable();
343 		break;
344 	case CARTRIDGE_BLIZZARD_16:
345 		if (active_cart->state) {
346 			MEMORY_Cart809fDisable();
347 			MEMORY_CartA0bfDisable();
348 		}
349 		break;
350 	case CARTRIDGE_SDX_128:
351 	case CARTRIDGE_ATRAX_SDX_128:
352 		set_bank_SDX_128();
353 		break;
354 	case CARTRIDGE_AST_32:
355 		/* Value 0x10000 indicates cartridge enabled. */
356 		if (active_cart->state < 0x10000)
357 			MEMORY_CartA0bfDisable();
358 		break;
359 	case CARTRIDGE_ULTRACART_32:
360 	case CARTRIDGE_BLIZZARD_32:
361 		set_bank_A0BF(4, 3);
362 		break;
363 	case CARTRIDGE_SIC_128:
364 		set_bank_SIC(0x07);
365 		break;
366 	case CARTRIDGE_SIC_256:
367 		set_bank_SIC(0x0f);
368 		break;
369 	case CARTRIDGE_SIC_512:
370 		set_bank_SIC(0x1f);
371 		break;
372 	case CARTRIDGE_MEGA_4096:
373 		set_bank_MEGA_4096();
374 		break;
375 	case CARTRIDGE_THECART_128M:
376 		set_bank_A0BF(0x4000, 0x3fff);
377 		break;
378 	case CARTRIDGE_THECART_32M:
379 		set_bank_A0BF(0x4000, 0x0fff);
380 		break;
381 	case CARTRIDGE_THECART_64M:
382 		set_bank_A0BF(0x4000, 0x1fff);
383 		break;
384 	}
385 #if DEBUG
386 	if (old_state != active_cart->state)
387 		Log_print("Cart %i state: %02x -> %02x", active_cart == &CARTRIDGE_piggyback, old_state, active_cart->state);
388 #endif
389 }
390 
391 /* Maps *active_cart to memory. If the cartridge is bankswitched,
392    the mapping is performed according to its current state (ie. it doesn't
393    reset to bank 0 or whatever). */
394 /* Note that this function only maps part of a cartridge (if any). Then it
395    calls SwitchBank(), which maps the rest. */
MapActiveCart(void)396 static void MapActiveCart(void)
397 {
398 	if (Atari800_machine_type == Atari800_MACHINE_5200) {
399 		MEMORY_SetROM(0x4ff6, 0x4ff9);		/* disable Bounty Bob bank switching */
400 		MEMORY_SetROM(0x5ff6, 0x5ff9);
401 		switch (active_cart->type) {
402 		case CARTRIDGE_5200_32:
403 			MEMORY_CopyROM(0x4000, 0xbfff, active_cart->image);
404 			break;
405 		case CARTRIDGE_5200_EE_16:
406 			MEMORY_CopyROM(0x4000, 0x5fff, active_cart->image);
407 			MEMORY_CopyROM(0x6000, 0x9fff, active_cart->image);
408 			MEMORY_CopyROM(0xa000, 0xbfff, active_cart->image + 0x2000);
409 			break;
410 		case CARTRIDGE_5200_40:
411 			MEMORY_CopyROM(0x4000, 0x4fff, active_cart->image + (active_cart->state & 0x03) * 0x1000);
412 			MEMORY_CopyROM(0x5000, 0x5fff, active_cart->image + 0x4000 + ((active_cart->state & 0x0c) >> 2) * 0x1000);
413 			MEMORY_CopyROM(0x8000, 0x9fff, active_cart->image + 0x8000);
414 			MEMORY_CopyROM(0xa000, 0xbfff, active_cart->image + 0x8000);
415 #ifndef PAGED_ATTRIB
416 			MEMORY_SetHARDWARE(0x4ff6, 0x4ff9);
417 			MEMORY_SetHARDWARE(0x5ff6, 0x5ff9);
418 #else
419 			MEMORY_readmap[0x4f] = CARTRIDGE_BountyBob1GetByte;
420 			MEMORY_readmap[0x5f] = CARTRIDGE_BountyBob2GetByte;
421 			MEMORY_writemap[0x4f] = CARTRIDGE_BountyBob1PutByte;
422 			MEMORY_writemap[0x5f] = CARTRIDGE_BountyBob2PutByte;
423 #endif
424 			break;
425 		case CARTRIDGE_5200_NS_16:
426 			MEMORY_CopyROM(0x8000, 0xbfff, active_cart->image);
427 			break;
428 		case CARTRIDGE_5200_8:
429 			MEMORY_CopyROM(0x8000, 0x9fff, active_cart->image);
430 			MEMORY_CopyROM(0xa000, 0xbfff, active_cart->image);
431 			break;
432 		case CARTRIDGE_5200_4:
433 			MEMORY_CopyROM(0x8000, 0x8fff, active_cart->image);
434 			MEMORY_CopyROM(0x9000, 0x9fff, active_cart->image);
435 			MEMORY_CopyROM(0xa000, 0xafff, active_cart->image);
436 			MEMORY_CopyROM(0xb000, 0xbfff, active_cart->image);
437 			break;
438 		default:
439 			/* clear cartridge area so the 5200 will crash */
440 			MEMORY_dFillMem(0x4000, 0, 0x8000);
441 			break;
442 		}
443 	}
444 	else {
445 		switch (active_cart->type) {
446 		case CARTRIDGE_STD_2:
447 			MEMORY_Cart809fDisable();
448 			MEMORY_CartA0bfEnable();
449 			MEMORY_dFillMem(0xa000, 0xff, 0x1800);
450 			MEMORY_CopyROM(0xb800, 0xbfff, active_cart->image);
451 			break;
452 		case CARTRIDGE_STD_4:
453 			MEMORY_Cart809fDisable();
454 			MEMORY_CartA0bfEnable();
455 			MEMORY_dFillMem(0xa000, 0xff, 0x1000);
456 			MEMORY_CopyROM(0xb000, 0xbfff, active_cart->image);
457 			break;
458 		case CARTRIDGE_BLIZZARD_4:
459 			MEMORY_Cart809fDisable();
460 			MEMORY_CartA0bfEnable();
461 			MEMORY_CopyROM(0xa000, 0xafff, active_cart->image);
462 			MEMORY_CopyROM(0xb000, 0xbfff, active_cart->image);
463 			break;
464 		case CARTRIDGE_STD_8:
465 		case CARTRIDGE_PHOENIX_8:
466 			MEMORY_Cart809fDisable();
467 			MEMORY_CartA0bfEnable();
468 			MEMORY_CopyROM(0xa000, 0xbfff, active_cart->image);
469 			break;
470 		case CARTRIDGE_LOW_BANK_8:
471 			MEMORY_Cart809fEnable();
472 			MEMORY_CartA0bfDisable();
473 			MEMORY_CopyROM(0x8000, 0x9fff, active_cart->image);
474 			break;
475 		case CARTRIDGE_STD_16:
476 		case CARTRIDGE_BLIZZARD_16:
477 			MEMORY_Cart809fEnable();
478 			MEMORY_CartA0bfEnable();
479 			MEMORY_CopyROM(0x8000, 0xbfff, active_cart->image);
480 			break;
481 		case CARTRIDGE_OSS_034M_16:
482 		case CARTRIDGE_OSS_043M_16:
483 			MEMORY_Cart809fDisable();
484 			if (active_cart->state >= 0) {
485 				MEMORY_CartA0bfEnable();
486 				MEMORY_CopyROM(0xb000, 0xbfff, active_cart->image + 0x3000);
487 			}
488 			break;
489 		case CARTRIDGE_OSS_M091_16:
490 		case CARTRIDGE_OSS_8:
491 			MEMORY_Cart809fDisable();
492 			if (active_cart->state >= 0) {
493 				MEMORY_CartA0bfEnable();
494 				MEMORY_CopyROM(0xb000, 0xbfff, active_cart->image);
495 			}
496 			break;
497 		case CARTRIDGE_WILL_64:
498 		case CARTRIDGE_EXP_64:
499 		case CARTRIDGE_DIAMOND_64:
500 		case CARTRIDGE_SDX_64:
501 		case CARTRIDGE_ATRAX_128:
502 		case CARTRIDGE_WILL_32:
503 		case CARTRIDGE_ATMAX_128:
504 		case CARTRIDGE_ATMAX_1024:
505 		case CARTRIDGE_SDX_128:
506 		case CARTRIDGE_ATRAX_SDX_64:
507 		case CARTRIDGE_ATRAX_SDX_128:
508 		case CARTRIDGE_TURBOSOFT_64:
509 		case CARTRIDGE_TURBOSOFT_128:
510 		case CARTRIDGE_ULTRACART_32:
511 		case CARTRIDGE_BLIZZARD_32:
512 		case CARTRIDGE_THECART_128M:
513 		case CARTRIDGE_THECART_32M:
514 		case CARTRIDGE_THECART_64M:
515 			MEMORY_Cart809fDisable();
516 			break;
517 		case CARTRIDGE_DB_32:
518 		case CARTRIDGE_XEGS_32:
519 		case CARTRIDGE_SWXEGS_32:
520 			if (!(active_cart->state & 0x80)) {
521 				MEMORY_CartA0bfEnable();
522 				MEMORY_CopyROM(0xa000, 0xbfff, active_cart->image + 0x6000);
523 			}
524 			break;
525 		case CARTRIDGE_XEGS_07_64:
526 		case CARTRIDGE_SWXEGS_64:
527 		case CARTRIDGE_XEGS_8F_64:
528 			if (!(active_cart->state & 0x80)) {
529 				MEMORY_CartA0bfEnable();
530 				MEMORY_CopyROM(0xa000, 0xbfff, active_cart->image + 0xe000);
531 			}
532 			break;
533 		case CARTRIDGE_XEGS_128:
534 		case CARTRIDGE_SWXEGS_128:
535 			if (!(active_cart->state & 0x80)) {
536 				MEMORY_CartA0bfEnable();
537 				MEMORY_CopyROM(0xa000, 0xbfff, active_cart->image + 0x1e000);
538 			}
539 			break;
540 		case CARTRIDGE_XEGS_256:
541 		case CARTRIDGE_SWXEGS_256:
542 			if (!(active_cart->state & 0x80)) {
543 				MEMORY_CartA0bfEnable();
544 				MEMORY_CopyROM(0xa000, 0xbfff, active_cart->image + 0x3e000);
545 			}
546 			break;
547 		case CARTRIDGE_XEGS_512:
548 		case CARTRIDGE_SWXEGS_512:
549 			if (!(active_cart->state & 0x80)) {
550 				MEMORY_CartA0bfEnable();
551 				MEMORY_CopyROM(0xa000, 0xbfff, active_cart->image + 0x7e000);
552 			}
553 			break;
554 		case CARTRIDGE_XEGS_1024:
555 		case CARTRIDGE_SWXEGS_1024:
556 			if (!(active_cart->state & 0x80)) {
557 				MEMORY_CartA0bfEnable();
558 				MEMORY_CopyROM(0xa000, 0xbfff, active_cart->image + 0xfe000);
559 			}
560 			break;
561 		case CARTRIDGE_BBSB_40:
562 			MEMORY_Cart809fEnable();
563 			MEMORY_CartA0bfEnable();
564 			MEMORY_CopyROM(0x8000, 0x8fff, active_cart->image + (active_cart->state & 0x03) * 0x1000);
565 			MEMORY_CopyROM(0x9000, 0x9fff, active_cart->image + 0x4000 + ((active_cart->state & 0x0c) >> 2) * 0x1000);
566 			MEMORY_CopyROM(0xa000, 0xbfff, active_cart->image + 0x8000);
567 #ifndef PAGED_ATTRIB
568 			MEMORY_SetHARDWARE(0x8ff6, 0x8ff9);
569 			MEMORY_SetHARDWARE(0x9ff6, 0x9ff9);
570 #else
571 			MEMORY_readmap[0x8f] = CARTRIDGE_BountyBob1GetByte;
572 			MEMORY_readmap[0x9f] = CARTRIDGE_BountyBob2GetByte;
573 			MEMORY_writemap[0x8f] = CARTRIDGE_BountyBob1PutByte;
574 			MEMORY_writemap[0x9f] = CARTRIDGE_BountyBob2PutByte;
575 #endif
576 			/* No need to call SwitchBank(), return. */
577 			return;
578 		case CARTRIDGE_RIGHT_4:
579 			if (Atari800_machine_type == Atari800_MACHINE_800) {
580 				MEMORY_Cart809fEnable();
581 				MEMORY_dFillMem(0x8000, 0xff, 0x1000);
582 				MEMORY_CopyROM(0x9000, 0x9fff, active_cart->image);
583 				if ((!Atari800_disable_basic || BINLOAD_loading_basic) && MEMORY_have_basic) {
584 					MEMORY_CartA0bfEnable();
585 					MEMORY_CopyROM(0xa000, 0xbfff, MEMORY_basic);
586 				}
587 				else
588 					MEMORY_CartA0bfDisable();
589 			} else {
590 				/* there's no right slot in XL/XE */
591 				MEMORY_Cart809fDisable();
592 				MEMORY_CartA0bfDisable();
593 			}
594 			/* No need to call SwitchBank(), return. */
595 			return;
596 		case CARTRIDGE_RIGHT_8:
597 			if (Atari800_machine_type == Atari800_MACHINE_800) {
598 				MEMORY_Cart809fEnable();
599 				MEMORY_CopyROM(0x8000, 0x9fff, active_cart->image);
600 				if (!Atari800_builtin_basic
601 				    && (!Atari800_disable_basic || BINLOAD_loading_basic) && MEMORY_have_basic) {
602 					MEMORY_CartA0bfEnable();
603 					MEMORY_CopyROM(0xa000, 0xbfff, MEMORY_basic);
604 				}
605 				else
606 					MEMORY_CartA0bfDisable();
607 			} else {
608 				/* there's no right slot in XL/XE */
609 				MEMORY_Cart809fDisable();
610 				MEMORY_CartA0bfDisable();
611 			}
612 			/* No need to call SwitchBank(), return. */
613 			return;
614 		case CARTRIDGE_AST_32:
615 			{
616 				int i;
617 				MEMORY_Cart809fDisable();
618 				MEMORY_CartA0bfEnable();
619 				/* Copy the chosen bank 32 times over 0xa000-0xbfff. */
620 				for (i = 0xa000; i < 0xc000; i += 0x100)
621 					MEMORY_CopyROM(i, i + 0xff, active_cart->image + (active_cart->state & 0xffff));
622 			}
623 			break;
624 		case CARTRIDGE_MEGA_16:
625 		case CARTRIDGE_MEGA_32:
626 		case CARTRIDGE_MEGA_64:
627 		case CARTRIDGE_MEGA_128:
628 		case CARTRIDGE_MEGA_256:
629 		case CARTRIDGE_MEGA_512:
630 		case CARTRIDGE_MEGA_1024:
631 		case CARTRIDGE_MEGA_2048:
632 		case CARTRIDGE_MEGA_4096:
633 		case CARTRIDGE_SIC_128:
634 		case CARTRIDGE_SIC_256:
635 		case CARTRIDGE_SIC_512:
636 		case CARTRIDGE_MEGAMAX_2048:
637 			break;
638 		default:
639 			MEMORY_Cart809fDisable();
640 			if (!Atari800_builtin_basic
641 			&& (!Atari800_disable_basic || BINLOAD_loading_basic) && MEMORY_have_basic) {
642 				MEMORY_CartA0bfEnable();
643 				MEMORY_CopyROM(0xa000, 0xbfff, MEMORY_basic);
644 			}
645 			else
646 				MEMORY_CartA0bfDisable();
647 			/* No need to call SwitchBank(), return. */
648 			return;
649 		}
650 		SwitchBank(active_cart->state);
651 	}
652 }
653 
654 /* Called from GetByte() and PutByte(), this function sets cartridge state
655    for a cartridge that is bank-switched by either read or write to
656    page $D5. Returns TRUE if switching a bank is needed. */
access_D5(CARTRIDGE_image_t * cart,UWORD addr,int * state)657 static int access_D5(CARTRIDGE_image_t *cart, UWORD addr, int *state)
658 {
659 	int old_state = cart->state;
660 	int new_state;
661 
662 	switch (cart->type) {
663 	case CARTRIDGE_OSS_034M_16:
664 		/* Reference: http://www.retrobits.net/atari/osscarts.shtml
665 		   Deprecated by CARTRIDGE_OSS_043M_16 - 034M is an incorrect
666 		   bank order (a real cartridge consists of two 8KB chips,
667 		   one containing banks 0 and 4, the other 3 and M). Kept here
668 		   for backward compatibility. */
669 
670 		if (addr & 0x08)
671 			new_state = -1;
672 		else
673 			switch (addr & 0x07) {
674 			case 0x00:
675 				/* B Lo/A Hi */
676 				new_state = 0;
677 				break;
678 			case 0x01:
679 				/* A Lo+B Lo/A Hi */
680 				/* TODO should be binary AND of both banks. For now only fills with 0xFFs. */
681 				new_state = 0xff;
682 				break;
683 			case 0x03:
684 			case 0x07:
685 				/* A Lo/A Hi */
686 				new_state = 1;
687 				break;
688 			case 0x04:
689 				/* B Hi/A Hi */
690 				new_state = 2;
691 				break;
692 			case 0x05:
693 				/* A Lo+B Hi/A Hi */
694 				/* TODO should be binary AND of both banks. For now only fills with 0xFFs. */
695 				new_state = 0xff;
696 				break;
697 			default: /* 0x02, 0x06 */
698 				/* Fill cart area with 0xFFs. */
699 				new_state = 0xff;
700 				break;
701 			}
702 		break;
703 	case CARTRIDGE_OSS_043M_16:
704 		/* Reference: http://www.retrobits.net/atari/osscarts.shtml
705 		   Using the nomenclature of the above article: the emulator
706 		   accepts 16KB images composed of two 8KB EPROM dumps joined
707 		   together in the following order: ROM B, ROM A. Currently
708 		   only three cartridges with this scheme are known:
709 		   Action! 3.5, BASIC XL 1.02 and MAC/65 1.0. */
710 
711 		if (addr & 0x08)
712 			new_state = -1;
713 		else
714 			switch (addr & 0x07) {
715 			case 0x00:
716 				/* B Lo/A Hi */
717 				new_state = 0;
718 				break;
719 			case 0x01:
720 				/* A Lo+B Lo/A Hi */
721 				/* TODO should be binary AND of both banks. For now only fills with 0xFFs. */
722 				new_state = 0xff;
723 				break;
724 			case 0x03:
725 			case 0x07:
726 				/* A Lo/A Hi */
727 				new_state = 2;
728 				break;
729 			case 0x04:
730 				/* B Hi/A Hi */
731 				new_state = 1;
732 				break;
733 			case 0x05:
734 				/* A Lo+B Hi/A Hi */
735 				/* TODO should be binary AND of both banks. For now only fills with 0xFFs. */
736 				new_state = 0xff;
737 				break;
738 			default: /* 0x02, 0x06 */
739 				/* Fill cart area with 0xFFs. */
740 				new_state = 0xff;
741 				break;
742 			}
743 		break;
744 	case CARTRIDGE_DB_32:
745 		new_state = addr & 0x03;
746 		break;
747 	case CARTRIDGE_WILL_64:
748 		new_state = addr & 0x0f;
749 		break;
750 	case CARTRIDGE_WILL_32:
751 		new_state = addr & 0x0b;
752 		break;
753 	case CARTRIDGE_EXP_64:
754 		/* Only react to access to $D57x. */
755 		if ((addr & 0xf0) != 0x70)
756 			return FALSE;
757 		new_state = ((addr ^ 7) & 0x0f);
758 		break;
759 	case CARTRIDGE_DIAMOND_64:
760 		/* Only react to access to $D5Dx. */
761 		if ((addr & 0xf0) != 0xd0)
762 			return FALSE;
763 		new_state = ((addr ^ 7) & 0x0f);
764 		break;
765 	case CARTRIDGE_SDX_64:
766 	case CARTRIDGE_ATRAX_SDX_64:
767 		/* Only react to access to $D5Ex. */
768 		if ((addr & 0xf0) != 0xe0)
769 			return FALSE;
770 		if (addr & 0x08)
771 			new_state = addr & 0x0c;
772 		else
773 			/* Negate bits that encode bank number. */
774 			new_state = ((addr ^ 0x07) & 0x0f);
775 		if (cart == &CARTRIDGE_main) {
776 			/* It's the 1st cartridge, process switching the piggyback on/off. */
777 			if ((old_state & 0x0c) == 0x08) { /* Piggyback cartridge was enabled */
778 				if ((new_state & 0x0c) != 0x08)  { /* Going to disable it */
779 					active_cart = &CARTRIDGE_main;
780 					MapActiveCart();
781 				}
782 			}
783 			else if ((new_state & 0x0c) == 0x08) { /* Going to enable piggyback */
784 				active_cart = &CARTRIDGE_piggyback;
785 				MapActiveCart();
786 			}
787 		}
788 		break;
789 	case CARTRIDGE_SDX_128:
790 	case CARTRIDGE_ATRAX_SDX_128:
791 		/* Only react to access to $D5Ex/$D5Fx. */
792 		if ((addr & 0xe0) != 0xe0)
793 			return FALSE;
794 		if (addr & 0x08)
795 			new_state = addr & 0x0c;
796 		else
797 			/* Negate bits that encode bank number. */
798 			new_state = ((addr ^ 0x17) & 0x1f);
799 		if (cart == &CARTRIDGE_main) {
800 			/* It's the 1st cartridge, process switching the piggyback on/off. */
801 			if ((old_state & 0x0c) == 0x08) { /* Piggyback cartridge was enabled */
802 				if ((new_state & 0x0c) != 0x08)  { /* Going to disable it */
803 					active_cart = &CARTRIDGE_main;
804 					MapActiveCart();
805 				}
806 			}
807 			else if ((new_state & 0x0c) == 0x08) { /* Going to enable piggyback */
808 				active_cart = &CARTRIDGE_piggyback;
809 				MapActiveCart();
810 			}
811 		}
812 		break;
813 	case CARTRIDGE_OSS_M091_16:
814 		switch (addr & 0x09) {
815 		case 0x00:
816 			new_state = 1;
817 			break;
818 		case 0x01:
819 			new_state = 3;
820 			break;
821 		case 0x08:
822 			new_state = -1;
823 			break;
824 		default: /* 0x09 */
825 			new_state = 2;
826 			break;
827 		}
828 		break;
829 	case CARTRIDGE_BLIZZARD_4:
830 	case CARTRIDGE_PHOENIX_8:
831 	case CARTRIDGE_BLIZZARD_16:
832 		/* Disable the cart. */
833 		new_state = 1;
834 		break;
835 	case CARTRIDGE_ATMAX_128:
836 		/* Only react to access to $D50x/$D51x. */
837 		if ((addr & 0xe0) != 0)
838 			return FALSE;
839 		/* fall through */
840 	case CARTRIDGE_TURBOSOFT_128:
841 		new_state = addr & 0x1f;
842 		break;
843 	case CARTRIDGE_TURBOSOFT_64:
844 		new_state = addr & 0x17;
845 		break;
846 	case CARTRIDGE_ATMAX_1024:
847 	case CARTRIDGE_MEGAMAX_2048:
848 		new_state = addr;
849 		break;
850 	case CARTRIDGE_OSS_8:
851 		switch (addr & 0x09) {
852 		case 0x00:
853 		case 0x01:
854 			new_state = 1;
855 			break;
856 		case 0x08:
857 			new_state = -1;
858 			break;
859 		default: /* 0x09 */
860 			new_state = 0;
861 			break;
862 		}
863 		break;
864 	case CARTRIDGE_ULTRACART_32:
865 		new_state = (old_state + 1) % 5;
866 		break;
867 	case CARTRIDGE_BLIZZARD_32:
868 		if (old_state < 4)
869 			new_state = old_state + 1;
870 		break;
871 	default:
872 		/* Other cartridge types don't support enabling/disabling/banking through page D5. */
873 		return FALSE;
874 	}
875 	*state = new_state;
876 	return TRUE;
877 }
878 
879 /* Processes bankswitching of CART when reading from a $D5xx address ADDR. */
GetByte(CARTRIDGE_image_t * cart,UWORD addr,int no_side_effects)880 static UBYTE GetByte(CARTRIDGE_image_t *cart, UWORD addr, int no_side_effects)
881 {
882 	int old_state = cart->state;
883 	int new_state = old_state;
884 
885 #if DEBUG
886 	if (cart->type > CARTRIDGE_NONE)
887 		Log_print("Cart %i read: %04x", cart == &CARTRIDGE_piggyback, addr);
888 #endif
889 	/* Set the cartridge's new state. */
890 	/* Check types switchable by access to page D5. */
891 	if (!no_side_effects && access_D5(cart, addr, &new_state)) {
892 		/* Cartridge supports bankswitching and reacted to the given
893 		   ADDR. If the state changed, we need to do the bankswitch. */
894 		if (new_state != old_state) {
895 			cart->state = new_state;
896 			if (cart == active_cart)
897 				SwitchBank(old_state);
898 		}
899 	}
900 
901 	/* Determine returned byte value. */
902 	switch (cart->type) {
903 	case CARTRIDGE_AST_32:
904 		/* cart->state contains address of current bank, therefore it
905 		   divides by 0x100. */
906 		return cart->image[(cart->state & 0xff00) | (addr & 0xff)];
907 	case CARTRIDGE_SIC_512:
908 	case CARTRIDGE_SIC_256:
909 	case CARTRIDGE_SIC_128:
910 	case CARTRIDGE_MEGA_4096:
911 		/* Only react to access to $D50x/$D51x. */
912 		if ((addr & 0xe0) == 0x00)
913 			return cart->state;
914 		break;
915 	case CARTRIDGE_THECART_128M:
916 	case CARTRIDGE_THECART_32M:
917 	case CARTRIDGE_THECART_64M:
918 		switch (addr) {
919 		case 0xd5a0:
920 			return cart->state & 0x00ff;
921 		case 0xd5a1:
922 			return (cart->state & 0x3f00) >> 8;
923 		case 0xd5a2:
924 			return (~cart->state & 0x4000) >> 14;
925 		}
926 		break;
927 	}
928 	return 0xff;
929 }
930 
931 /* Processes bankswitching of CART when writing to a $D5xx address ADDR. */
PutByte(CARTRIDGE_image_t * cart,UWORD addr,UBYTE byte)932 static void PutByte(CARTRIDGE_image_t *cart, UWORD addr, UBYTE byte)
933 {
934 	int old_state = cart->state;
935 	int new_state = old_state;
936 
937 #if DEBUG
938 	if (cart->type > CARTRIDGE_NONE)
939 		Log_print("Cart %i write: %04x, %02x", cart == &CARTRIDGE_piggyback, addr, byte);
940 #endif
941 	/* Set the cartridge's new state. */
942 	switch (cart->type) {
943 	case CARTRIDGE_XEGS_32:
944 		new_state = byte & 0x03;
945 		break;
946 	case CARTRIDGE_XEGS_07_64:
947 		new_state = byte & 0x07;
948 		break;
949 	case CARTRIDGE_XEGS_128:
950 	case CARTRIDGE_XEGS_8F_64:
951 		new_state = byte & 0x0f;
952 		break;
953 	case CARTRIDGE_XEGS_256:
954 		new_state = byte & 0x1f;
955 		break;
956 	case CARTRIDGE_XEGS_512:
957 		new_state = byte & 0x3f;
958 		break;
959 	case CARTRIDGE_XEGS_1024:
960 		new_state = byte & 0x7f;
961 		break;
962 	case CARTRIDGE_MEGA_16:
963 		new_state = byte & 0x80;
964 		break;
965 	case CARTRIDGE_MEGA_32:
966 		new_state = byte & 0x81;
967 		break;
968 	case CARTRIDGE_MEGA_64:
969 	case CARTRIDGE_SWXEGS_32:
970 		new_state = byte & 0x83;
971 		break;
972 	case CARTRIDGE_MEGA_128:
973 	case CARTRIDGE_SWXEGS_64:
974 		new_state = byte & 0x87;
975 		break;
976 	case CARTRIDGE_MEGA_256:
977 	case CARTRIDGE_SWXEGS_128:
978 	case CARTRIDGE_ATRAX_128:
979 		new_state = byte & 0x8f;
980 		break;
981 	case CARTRIDGE_MEGA_512:
982 	case CARTRIDGE_SWXEGS_256:
983 		new_state = byte & 0x9f;
984 		break;
985 	case CARTRIDGE_MEGA_1024:
986 	case CARTRIDGE_SWXEGS_512:
987 		new_state = byte & 0xbf;
988 		break;
989 	case CARTRIDGE_MEGA_2048:
990 	case CARTRIDGE_SWXEGS_1024:
991 		new_state = byte;
992 		break;
993 	case CARTRIDGE_AST_32:
994 		/* State contains address of current bank. */
995 		new_state = (old_state + 0x100) & 0x7fff;
996 		break;
997 	case CARTRIDGE_SIC_512:
998 	case CARTRIDGE_SIC_256:
999 	case CARTRIDGE_SIC_128:
1000 	case CARTRIDGE_MEGA_4096:
1001 		/* Only react to access to $D50x/$D51x. */
1002 		if ((addr & 0xe0) == 0x00)
1003 			new_state = byte;
1004 		break;
1005 	case CARTRIDGE_THECART_128M:
1006 	case CARTRIDGE_THECART_32M:
1007 	case CARTRIDGE_THECART_64M:
1008 		switch (addr) {
1009 		case 0xd5a0:
1010 			new_state = (old_state & 0x3f00) | byte;
1011 			break;
1012 		case 0xd5a1:
1013 			new_state = (old_state & 0x00ff) | ((byte & 0x3f) << 8);
1014 			break;
1015 		case 0xd5a2:
1016 			new_state = (old_state & 0x3fff) | ((~byte & 0x01) << 14);
1017 			break;
1018 		}
1019 		break;
1020 	default:
1021 		/* Check types switchable by access to page D5. */
1022 		if (!access_D5(cart, addr, &new_state))
1023 			/* Cartridge doesn't support bankswitching, or didn't react to
1024 			   the given ADDR. */
1025 			return;
1026 	}
1027 
1028 	/* If the state changed, we need to do the bankswitch. */
1029 	if (new_state != old_state) {
1030 		cart->state = new_state;
1031 		if (cart == active_cart)
1032 			SwitchBank(old_state);
1033 	}
1034 }
1035 
1036 /* a read from D500-D5FF area */
CARTRIDGE_GetByte(UWORD addr,int no_side_effects)1037 UBYTE CARTRIDGE_GetByte(UWORD addr, int no_side_effects)
1038 {
1039 #ifdef AF80
1040 	if (AF80_enabled) {
1041 		return AF80_D5GetByte(addr, no_side_effects);
1042 	}
1043 #endif
1044 	if (RTIME_enabled && (addr == 0xd5b8 || addr == 0xd5b9))
1045 		return RTIME_GetByte();
1046 #ifdef IDE
1047 	if (IDE_enabled && (addr <= 0xd50f))
1048 		return IDE_GetByte(addr, no_side_effects);
1049 #endif
1050 	/* In case 2 cartridges are inserted, reading a memory location would
1051 	   result in binary AND of both cartridges. */
1052 	return GetByte(&CARTRIDGE_main, addr, no_side_effects) & GetByte(&CARTRIDGE_piggyback, addr, no_side_effects);
1053 }
1054 
1055 /* a write to D500-D5FF area */
CARTRIDGE_PutByte(UWORD addr,UBYTE byte)1056 void CARTRIDGE_PutByte(UWORD addr, UBYTE byte)
1057 {
1058 #ifdef AF80
1059 	if (AF80_enabled) {
1060 		AF80_D5PutByte(addr,byte);
1061 		/* Return, because AF_80_enabled means there's an AF80
1062 		   cartridge in the left slot and no other cartridges are
1063 		   there. */
1064 		return;
1065 	}
1066 #endif
1067 	if (RTIME_enabled && (addr == 0xd5b8 || addr == 0xd5b9)) {
1068 		RTIME_PutByte(byte);
1069 	}
1070 #ifdef IDE
1071 	if (IDE_enabled && (addr <= 0xd50f)) {
1072 		IDE_PutByte(addr,byte);
1073 	}
1074 #endif
1075 	PutByte(&CARTRIDGE_main, addr, byte);
1076 	PutByte(&CARTRIDGE_piggyback, addr, byte);
1077 }
1078 
1079 /* special support of Bounty Bob on Atari5200 */
CARTRIDGE_BountyBob1(UWORD addr)1080 void CARTRIDGE_BountyBob1(UWORD addr)
1081 {
1082 	if (Atari800_machine_type == Atari800_MACHINE_5200) {
1083 		if (addr >= 0x4ff6 && addr <= 0x4ff9) {
1084 			addr -= 0x4ff6;
1085 			MEMORY_CopyROM(0x4000, 0x4fff, active_cart->image + addr * 0x1000);
1086 			active_cart->state = (active_cart->state & 0x0c) | addr;
1087 		}
1088 	} else {
1089 		if (addr >= 0x8ff6 && addr <= 0x8ff9) {
1090 			addr -= 0x8ff6;
1091 			MEMORY_CopyROM(0x8000, 0x8fff, active_cart->image + addr * 0x1000);
1092 			active_cart->state = (active_cart->state & 0x0c) | addr;
1093 		}
1094 	}
1095 }
1096 
CARTRIDGE_BountyBob2(UWORD addr)1097 void CARTRIDGE_BountyBob2(UWORD addr)
1098 {
1099 	if (Atari800_machine_type == Atari800_MACHINE_5200) {
1100 		if (addr >= 0x5ff6 && addr <= 0x5ff9) {
1101 			addr -= 0x5ff6;
1102 			MEMORY_CopyROM(0x5000, 0x5fff, active_cart->image + 0x4000 + addr * 0x1000);
1103 			active_cart->state = (active_cart->state & 0x03) | (addr << 2);
1104 		}
1105 	}
1106 	else {
1107 		if (addr >= 0x9ff6 && addr <= 0x9ff9) {
1108 			addr -= 0x9ff6;
1109 			MEMORY_CopyROM(0x9000, 0x9fff, active_cart->image + 0x4000 + addr * 0x1000);
1110 			active_cart->state = (active_cart->state & 0x03) | (addr << 2);
1111 		}
1112 	}
1113 }
1114 
1115 #ifdef PAGED_ATTRIB
CARTRIDGE_BountyBob1GetByte(UWORD addr,int no_side_effects)1116 UBYTE CARTRIDGE_BountyBob1GetByte(UWORD addr, int no_side_effects)
1117 {
1118 	if (!no_side_effects) {
1119 		if (Atari800_machine_type == Atari800_MACHINE_5200) {
1120 			if (addr >= 0x4ff6 && addr <= 0x4ff9) {
1121 				CARTRIDGE_BountyBob1(addr);
1122 				return 0;
1123 			}
1124 		} else {
1125 			if (addr >= 0x8ff6 && addr <= 0x8ff9) {
1126 				CARTRIDGE_BountyBob1(addr);
1127 				return 0;
1128 			}
1129 		}
1130 	}
1131 	return MEMORY_dGetByte(addr);
1132 }
1133 
CARTRIDGE_BountyBob2GetByte(UWORD addr,int no_side_effects)1134 UBYTE CARTRIDGE_BountyBob2GetByte(UWORD addr, int no_side_effects)
1135 {
1136 	if (!no_side_effects) {
1137 		if (Atari800_machine_type == Atari800_MACHINE_5200) {
1138 			if (addr >= 0x5ff6 && addr <= 0x5ff9) {
1139 				CARTRIDGE_BountyBob2(addr);
1140 				return 0;
1141 			}
1142 		} else {
1143 			if (addr >= 0x9ff6 && addr <= 0x9ff9) {
1144 				CARTRIDGE_BountyBob2(addr);
1145 				return 0;
1146 			}
1147 		}
1148 	}
1149 	return MEMORY_dGetByte(addr);
1150 }
1151 
CARTRIDGE_BountyBob1PutByte(UWORD addr,UBYTE value)1152 void CARTRIDGE_BountyBob1PutByte(UWORD addr, UBYTE value)
1153 {
1154 	if (Atari800_machine_type == Atari800_MACHINE_5200) {
1155 		if (addr >= 0x4ff6 && addr <= 0x4ff9) {
1156 			CARTRIDGE_BountyBob1(addr);
1157 		}
1158 	} else {
1159 		if (addr >= 0x8ff6 && addr <= 0x8ff9) {
1160 			CARTRIDGE_BountyBob1(addr);
1161 		}
1162 	}
1163 }
1164 
CARTRIDGE_BountyBob2PutByte(UWORD addr,UBYTE value)1165 void CARTRIDGE_BountyBob2PutByte(UWORD addr, UBYTE value)
1166 {
1167 	if (Atari800_machine_type == Atari800_MACHINE_5200) {
1168 		if (addr >= 0x5ff6 && addr <= 0x5ff9) {
1169 			CARTRIDGE_BountyBob2(addr);
1170 		}
1171 	} else {
1172 		if (addr >= 0x9ff6 && addr <= 0x9ff9) {
1173 			CARTRIDGE_BountyBob2(addr);
1174 		}
1175 	}
1176 }
1177 #endif
1178 
CARTRIDGE_Checksum(const UBYTE * image,int nbytes)1179 int CARTRIDGE_Checksum(const UBYTE *image, int nbytes)
1180 {
1181 	int checksum = 0;
1182 	while (nbytes > 0) {
1183 		checksum += *image++;
1184 		nbytes--;
1185 	}
1186 	return checksum;
1187 }
1188 
ResetCartState(CARTRIDGE_image_t * cart)1189 static void ResetCartState(CARTRIDGE_image_t *cart)
1190 {
1191 	switch (cart->type) {
1192 	case CARTRIDGE_OSS_034M_16:
1193 		cart->state = 1;
1194 		break;
1195 	case CARTRIDGE_ATMAX_1024:
1196 		cart->state = 0x7f;
1197 		break;
1198 	case CARTRIDGE_AST_32:
1199 		/* A special value of 0x10000 indicates the cartridge is
1200 		   enabled and the current bank is 0. */
1201 		cart->state = 0x10000;
1202 		break;
1203 	case CARTRIDGE_MEGA_4096:
1204 		cart->state = 254;
1205 		break;
1206 	default:
1207 		cart->state = 0;
1208 	}
1209 }
1210 
1211 /* Before first use of the cartridge, preprocess its contents if needed. */
PreprocessCart(CARTRIDGE_image_t * cart)1212 static void PreprocessCart(CARTRIDGE_image_t *cart)
1213 {
1214 	switch (cart->type) {
1215 	case CARTRIDGE_ATRAX_SDX_64:
1216 	case CARTRIDGE_ATRAX_SDX_128: {
1217 		/* The address lines are connected a follows:
1218 		   (left - cartridge port + bank select, right - EPROM)
1219 		    A0 -  A6
1220 		    A1 -  A7
1221 		    A2 - A12
1222 		    A3 - A15
1223 		    A4 - A14
1224 		    A5 - A13
1225 		    A6 -  A8
1226 		    A7 -  A5
1227 		    A8 -  A4
1228 		    A9 -  A3
1229 		   A10 -  A0
1230 		   A11 -  A1
1231 		   A12 -  A2
1232 		   A13 -  A9
1233 		   A14 - A11
1234 		   A15 - A10
1235 		   A16 - A16 (only on ATRAX_SDX_128)
1236 
1237 		    The data lines are connected as follows:
1238 		    (left - cartridge port, right - EPROM)
1239 		    D1 - Q0
1240 		    D3 - Q1
1241 		    D7 - Q2
1242 		    D6 - Q3
1243 		    D0 - Q4
1244 		    D2 - Q5
1245 		    D5 - Q6
1246 		    D4 - Q7
1247 		 */
1248 		unsigned int i;
1249 		unsigned int const size = cart->size << 10;
1250 		UBYTE *new_image = (UBYTE *) Util_malloc(size);
1251 		/* FIXME: Can be optimised by caching the results in a conversion
1252 		   table, but doesn't seem to be worth it. */
1253 		for (i = 0; i < size; i++) {
1254 			unsigned int const rom_addr =
1255 				(i &  0x0001 ?  0x0040 : 0) |
1256 				(i &  0x0002 ?  0x0080 : 0) |
1257 				(i &  0x0004 ?  0x1000 : 0) |
1258 				(i &  0x0008 ?  0x8000 : 0) |
1259 				(i &  0x0010 ?  0x4000 : 0) |
1260 				(i &  0x0020 ?  0x2000 : 0) |
1261 				(i &  0x0040 ?  0x0100 : 0) |
1262 				(i &  0x0080 ?  0x0020 : 0) |
1263 				(i &  0x0100 ?  0x0010 : 0) |
1264 				(i &  0x0200 ?  0x0008 : 0) |
1265 				(i &  0x0400 ?  0x0001 : 0) |
1266 				(i &  0x0800 ?  0x0002 : 0) |
1267 				(i &  0x1000 ?  0x0004 : 0) |
1268 				(i &  0x2000 ?  0x0200 : 0) |
1269 				(i &  0x4000 ?  0x0800 : 0) |
1270 				(i &  0x8000 ?  0x0400 : 0) |
1271 				(i & 0x10000 ? 0x10000 : 0);
1272 
1273 			UBYTE byte = cart->image[rom_addr];
1274 			new_image[i] =
1275 					(byte & 0x01 ? 0x02 : 0) |
1276 					(byte & 0x02 ? 0x08 : 0) |
1277 					(byte & 0x04 ? 0x80 : 0) |
1278 					(byte & 0x08 ? 0x40 : 0) |
1279 					(byte & 0x10 ? 0x01 : 0) |
1280 					(byte & 0x20 ? 0x04 : 0) |
1281 					(byte & 0x40 ? 0x20 : 0) |
1282 					(byte & 0x80 ? 0x10 : 0);
1283 		}
1284 		free(cart->image);
1285 		cart->image = new_image;
1286 		break;
1287 	}
1288 	}
1289 }
1290 
1291 /* Initialises the cartridge CART after mounting. Called by CARTRIDGE_Insert,
1292    or CARTRIDGE_Insert_Second and CARTRIDGE_SetType. */
InitCartridge(CARTRIDGE_image_t * cart)1293 static void InitCartridge(CARTRIDGE_image_t *cart)
1294 {
1295 	PreprocessCart(cart);
1296 	ResetCartState(cart);
1297 	if (cart == &CARTRIDGE_main) {
1298 		/* Check if we should automatically switch between computer/5200. */
1299 		int for5200 = CartIsFor5200(CARTRIDGE_main.type);
1300 		if (for5200 && Atari800_machine_type != Atari800_MACHINE_5200) {
1301 			Atari800_SetMachineType(Atari800_MACHINE_5200);
1302 			MEMORY_ram_size = 16;
1303 			Atari800_InitialiseMachine();
1304 		}
1305 		else if (!for5200 && Atari800_machine_type == Atari800_MACHINE_5200) {
1306 			Atari800_SetMachineType(Atari800_MACHINE_XLXE);
1307 			MEMORY_ram_size = 64;
1308 			Atari800_InitialiseMachine();
1309 		}
1310 	}
1311 	if (cart == active_cart)
1312 		MapActiveCart();
1313 }
1314 
RemoveCart(CARTRIDGE_image_t * cart)1315 static void RemoveCart(CARTRIDGE_image_t *cart)
1316 {
1317 	if (cart->image != NULL) {
1318 		free(cart->image);
1319 		cart->image = NULL;
1320 	}
1321 	if (cart->type != CARTRIDGE_NONE) {
1322 		cart->type = CARTRIDGE_NONE;
1323 		if (cart == active_cart)
1324 			MapActiveCart();
1325 	}
1326 }
1327 
1328 /* Called after inserting/removing a cartridge (but not the piggyback one).
1329    If needed, reboots the machine. */
AutoReboot(void)1330 static void AutoReboot(void)
1331 {
1332 	if (CARTRIDGE_autoreboot)
1333 		Atari800_Coldstart();
1334 }
1335 
CARTRIDGE_SetType(CARTRIDGE_image_t * cart,int type)1336 void CARTRIDGE_SetType(CARTRIDGE_image_t *cart, int type)
1337 {
1338 	cart->type = type;
1339 	if (type == CARTRIDGE_NONE)
1340 		/* User cancelled setting the cartridge's type - the cartridge
1341 		   can be unloaded. */
1342 		RemoveCart(cart);
1343 	InitCartridge(cart);
1344 }
1345 
CARTRIDGE_SetTypeAutoReboot(CARTRIDGE_image_t * cart,int type)1346 void CARTRIDGE_SetTypeAutoReboot(CARTRIDGE_image_t *cart, int type)
1347 {
1348 	CARTRIDGE_SetType(cart, type);
1349 	/* We don't want to autoreboot on inserting the piggyback cartridge. */
1350 	if (cart != &CARTRIDGE_piggyback)
1351 		AutoReboot();
1352 }
1353 
CARTRIDGE_ColdStart(void)1354 void CARTRIDGE_ColdStart(void) {
1355 	active_cart = &CARTRIDGE_main;
1356 	ResetCartState(&CARTRIDGE_main);
1357 	ResetCartState(&CARTRIDGE_piggyback);
1358 	MapActiveCart();
1359 }
1360 
1361 /* Loads a cartridge from FILENAME. Copies FILENAME to CART_FILENAME.
1362    Allocates a buffer with cartridge image data and puts it in *CART_IMAGE.
1363    Sets *CART_TYPE to the cartridge type. */
InsertCartridge(const char * filename,CARTRIDGE_image_t * cart)1364 static int InsertCartridge(const char *filename, CARTRIDGE_image_t *cart)
1365 {
1366 	FILE *fp;
1367 	int len;
1368 	int type;
1369 	UBYTE header[16];
1370 
1371 	/* open file */
1372 	fp = fopen(filename, "rb");
1373 	if (fp == NULL)
1374 		return CARTRIDGE_CANT_OPEN;
1375 	/* check file length */
1376 	len = Util_flen(fp);
1377 	Util_rewind(fp);
1378 
1379 	/* Guard against providing cart->filename as parameter. */
1380 	if (cart->filename != filename)
1381 		/* Save Filename for state save */
1382 		strcpy(cart->filename, filename);
1383 
1384 	/* if full kilobytes, assume it is raw image */
1385 	if ((len & 0x3ff) == 0) {
1386 		/* alloc memory and read data */
1387 		cart->image = (UBYTE *) Util_malloc(len);
1388 		if (fread(cart->image, 1, len, fp) < len) {
1389 			Log_print("Error reading cartridge.\n");
1390 		}
1391 		fclose(fp);
1392 		/* find cart type */
1393 		cart->type = CARTRIDGE_NONE;
1394 		len >>= 10;	/* number of kilobytes */
1395 		cart->size = len;
1396 		for (type = 1; type <= CARTRIDGE_LAST_SUPPORTED; type++)
1397 			if (CARTRIDGE_kb[type] == len) {
1398 				if (cart->type == CARTRIDGE_NONE) {
1399 					cart->type = type;
1400 				} else {
1401 					/* more than one cartridge type of such length - user must select */
1402 					cart->type = CARTRIDGE_UNKNOWN;
1403 					return len;
1404 				}
1405 			}
1406 		if (cart->type != CARTRIDGE_NONE) {
1407 			InitCartridge(cart);
1408 			return 0;	/* ok */
1409 		}
1410 		free(cart->image);
1411 		cart->image = NULL;
1412 		return CARTRIDGE_BAD_FORMAT;
1413 	}
1414 	/* if not full kilobytes, assume it is CART file */
1415 	if (fread(header, 1, 16, fp) < 16) {
1416 		Log_print("Error reading cartridge.\n");
1417 	}
1418 	if ((header[0] == 'C') &&
1419 		(header[1] == 'A') &&
1420 		(header[2] == 'R') &&
1421 		(header[3] == 'T')) {
1422 		type = (header[4] << 24) |
1423 			(header[5] << 16) |
1424 			(header[6] << 8) |
1425 			header[7];
1426 		if (type >= 1 && type <= CARTRIDGE_LAST_SUPPORTED) {
1427 			int checksum;
1428 			int result;
1429 			len = CARTRIDGE_kb[type] << 10;
1430 			cart->size = CARTRIDGE_kb[type];
1431 			/* alloc memory and read data */
1432 			cart->image = (UBYTE *) Util_malloc(len);
1433 			if (fread(cart->image, 1, len, fp) < len) {
1434 				Log_print("Error reading cartridge.\n");
1435 			}
1436 			fclose(fp);
1437 			checksum = (header[8] << 24) |
1438 				(header[9] << 16) |
1439 				(header[10] << 8) |
1440 				header[11];
1441 			cart->type = type;
1442 			result = checksum == CARTRIDGE_Checksum(cart->image, len) ? 0 : CARTRIDGE_BAD_CHECKSUM;
1443 			InitCartridge(cart);
1444 			return result;
1445 		}
1446 	}
1447 	fclose(fp);
1448 	return CARTRIDGE_BAD_FORMAT;
1449 }
1450 
CARTRIDGE_Insert(const char * filename)1451 int CARTRIDGE_Insert(const char *filename)
1452 {
1453 	/* remove currently inserted cart */
1454 	CARTRIDGE_Remove();
1455 	return InsertCartridge(filename, &CARTRIDGE_main);
1456 }
1457 
CARTRIDGE_InsertAutoReboot(const char * filename)1458 int CARTRIDGE_InsertAutoReboot(const char *filename)
1459 {
1460 	int result = CARTRIDGE_Insert(filename);
1461 	AutoReboot();
1462 	return result;
1463 }
1464 
CARTRIDGE_Insert_Second(const char * filename)1465 int CARTRIDGE_Insert_Second(const char *filename)
1466 {
1467 	/* remove currently inserted cart */
1468 	CARTRIDGE_Remove_Second();
1469 	return InsertCartridge(filename, &CARTRIDGE_piggyback);
1470 }
1471 
CARTRIDGE_Remove(void)1472 void CARTRIDGE_Remove(void)
1473 {
1474 	active_cart = &CARTRIDGE_main;
1475 	CARTRIDGE_Remove_Second();
1476 	RemoveCart(&CARTRIDGE_main);
1477 }
1478 
CARTRIDGE_RemoveAutoReboot(void)1479 void CARTRIDGE_RemoveAutoReboot(void)
1480 {
1481 	CARTRIDGE_Remove();
1482 	AutoReboot();
1483 }
1484 
CARTRIDGE_Remove_Second(void)1485 void CARTRIDGE_Remove_Second(void)
1486 {
1487 	RemoveCart(&CARTRIDGE_piggyback);
1488 }
1489 
CARTRIDGE_ReadConfig(char * string,char * ptr)1490 int CARTRIDGE_ReadConfig(char *string, char *ptr)
1491 {
1492 	if (strcmp(string, "CARTRIDGE_FILENAME") == 0) {
1493 		Util_strlcpy(CARTRIDGE_main.filename, ptr, sizeof(CARTRIDGE_main.filename));
1494 		if (CARTRIDGE_main.type == CARTRIDGE_NONE)
1495 			CARTRIDGE_main.type = CARTRIDGE_UNKNOWN;
1496 	}
1497 	else if (strcmp(string, "CARTRIDGE_TYPE") == 0) {
1498 		int value = Util_sscandec(ptr);
1499 		if (value < 0 || value > CARTRIDGE_LAST_SUPPORTED)
1500 			return FALSE;
1501 		CARTRIDGE_main.type = value;
1502 	}
1503 	else if (strcmp(string, "CARTRIDGE_PIGGYBACK_FILENAME") == 0) {
1504 		Util_strlcpy(CARTRIDGE_piggyback.filename, ptr, sizeof(CARTRIDGE_piggyback.filename));
1505 		if (CARTRIDGE_piggyback.type == CARTRIDGE_NONE)
1506 			CARTRIDGE_piggyback.type = CARTRIDGE_UNKNOWN;
1507 	}
1508 	else if (strcmp(string, "CARTRIDGE_PIGGYBACK_TYPE") == 0) {
1509 		int value = Util_sscandec(ptr);
1510 		if (value < 0 || value > CARTRIDGE_LAST_SUPPORTED)
1511 			return FALSE;
1512 		CARTRIDGE_piggyback.type = value;
1513 	}
1514 	else if (strcmp(string, "CARTRIDGE_AUTOREBOOT") == 0) {
1515 		int value = Util_sscanbool(ptr);
1516 		if (value < 0)
1517 			return FALSE;
1518 		CARTRIDGE_autoreboot = value;
1519 	}
1520 	else return FALSE;
1521 	return TRUE;
1522 }
1523 
CARTRIDGE_WriteConfig(FILE * fp)1524 void CARTRIDGE_WriteConfig(FILE *fp)
1525 {
1526 	fprintf(fp, "CARTRIDGE_FILENAME=%s\n", CARTRIDGE_main.filename);
1527 	fprintf(fp, "CARTRIDGE_TYPE=%d\n", CARTRIDGE_main.type);
1528 	fprintf(fp, "CARTRIDGE_PIGGYBACK_FILENAME=%s\n", CARTRIDGE_piggyback.filename);
1529 	fprintf(fp, "CARTRIDGE_PIGGYBACK_TYPE=%d\n", CARTRIDGE_piggyback.type);
1530 	fprintf(fp, "CARTRIDGE_AUTOREBOOT=%d\n", CARTRIDGE_autoreboot);
1531 }
1532 
InitInsert(CARTRIDGE_image_t * cart)1533 static void InitInsert(CARTRIDGE_image_t *cart)
1534 {
1535 	if (cart->type != CARTRIDGE_NONE) {
1536 		int tmp_type = cart->type;
1537 		int res = InsertCartridge(cart->filename, cart);
1538 		if (res < 0) {
1539 			Log_print("Error inserting cartridge \"%s\": %s", cart->filename,
1540 			res == CARTRIDGE_CANT_OPEN ? "Can't open file" :
1541 			res == CARTRIDGE_BAD_FORMAT ? "Bad format" :
1542 			/* Assume r == CARTRIDGE_BAD_CHECKSUM */ "Bad checksum");
1543 			cart->type = CARTRIDGE_NONE;
1544 		}
1545 		if (cart->type == CARTRIDGE_UNKNOWN && CARTRIDGE_kb[tmp_type] == res)
1546 			CARTRIDGE_SetType(cart, tmp_type);
1547 	}
1548 }
1549 
CARTRIDGE_Initialise(int * argc,char * argv[])1550 int CARTRIDGE_Initialise(int *argc, char *argv[])
1551 {
1552 	int i;
1553 	int j;
1554 	int help_only = FALSE;
1555 	/* When filename is given at commandline, we have to reset cartridge type to UNKNOWN,
1556 	   because the cartridge type read earlier from the config file is no longer valid.
1557 	   These two variables indicate that cartridge type is also given at commandline
1558 	   and so it shouldn't be reset. */
1559 	int type_from_commandline = FALSE;
1560 	int type2_from_commandline = FALSE;
1561 
1562 	for (i = j = 1; i < *argc; i++) {
1563 		int i_a = (i + 1 < *argc); /* is argument available? */
1564 		int a_m = FALSE; /* error, argument missing! */
1565 		int a_i = FALSE; /* error, argument invalid! */
1566 
1567 		if (strcmp(argv[i], "-cart") == 0) {
1568 			if (i_a) {
1569 				Util_strlcpy(CARTRIDGE_main.filename, argv[++i], sizeof(CARTRIDGE_main.filename));
1570 				if (!type_from_commandline)
1571 					CARTRIDGE_main.type = CARTRIDGE_UNKNOWN;
1572 			}
1573 			else a_m = TRUE;
1574 		}
1575 		else if (strcmp(argv[i], "-cart-type") == 0) {
1576 			if (i_a) {
1577 				Util_sscansdec(argv[++i], &CARTRIDGE_main.type);
1578 				if (CARTRIDGE_main.type < 0 ||  CARTRIDGE_main.type > CARTRIDGE_LAST_SUPPORTED)
1579 					a_i = TRUE;
1580 				else
1581 					type_from_commandline = TRUE;
1582 			}
1583 			else a_m = TRUE;
1584 		}
1585 		else if (strcmp(argv[i], "-cart2") == 0) {
1586 			if (i_a) {
1587 				Util_strlcpy(CARTRIDGE_piggyback.filename, argv[++i], sizeof(CARTRIDGE_piggyback.filename));
1588 				if (!type2_from_commandline)
1589 					CARTRIDGE_piggyback.type = CARTRIDGE_UNKNOWN;
1590 			}
1591 			else a_m = TRUE;
1592 		}
1593 		else if (strcmp(argv[i], "-cart2-type") == 0) {
1594 			if (i_a) {
1595 				Util_sscansdec(argv[++i], &CARTRIDGE_piggyback.type);
1596 				if (CARTRIDGE_piggyback.type < 0 ||  CARTRIDGE_piggyback.type > CARTRIDGE_LAST_SUPPORTED)
1597 					a_i = TRUE;
1598 				else
1599 					type2_from_commandline = TRUE;
1600 			}
1601 			else a_m = TRUE;
1602 		}
1603 		else if (strcmp(argv[i], "-cart-autoreboot") == 0)
1604 			CARTRIDGE_autoreboot = TRUE;
1605 		else if (strcmp(argv[i], "-no-cart-autoreboot") == 0)
1606 			CARTRIDGE_autoreboot = FALSE;
1607 		else {
1608 			if (strcmp(argv[i], "-help") == 0) {
1609 				help_only = TRUE;
1610 				Log_print("\t-cart <file>         Install cartridge (raw or CART format)");
1611 				Log_print("\t-cart-type <num>     Set cartridge type (0..%i)", CARTRIDGE_LAST_SUPPORTED);
1612 				Log_print("\t-cart2 <file>        Install piggyback cartridge");
1613 				Log_print("\t-cart2-type <num>    Set piggyback cartridge type (0..%i)", CARTRIDGE_LAST_SUPPORTED);
1614 				Log_print("\t-cart-autoreboot     Reboot when cartridge is inserted/removed");
1615 				Log_print("\t-no-cart-autoreboot  Don't reboot after changing cartridge");
1616 			}
1617 			argv[j++] = argv[i];
1618 		}
1619 
1620 		if (a_m) {
1621 			Log_print("Missing argument for '%s'", argv[i]);
1622 			return FALSE;
1623 		} else if (a_i) {
1624 			Log_print("Invalid argument for '%s'", argv[--i]);
1625 			return FALSE;
1626 		}
1627 	}
1628 	*argc = j;
1629 
1630 	if (help_only)
1631 		return TRUE;
1632 
1633 	/* If filename not given, we must reset the cartridge types. */
1634 	if (CARTRIDGE_main.filename[0] == '\0')
1635 		CARTRIDGE_main.type = CARTRIDGE_NONE;
1636 	if (CARTRIDGE_piggyback.filename[0] == '\0')
1637 		CARTRIDGE_piggyback.type = CARTRIDGE_NONE;
1638 
1639 	InitInsert(&CARTRIDGE_main);
1640 	if (CartIsPassthrough(CARTRIDGE_main.type))
1641 		InitInsert(&CARTRIDGE_piggyback);
1642 
1643 	return TRUE;
1644 }
1645 
CARTRIDGE_Exit(void)1646 void CARTRIDGE_Exit(void)
1647 {
1648 	CARTRIDGE_Remove(); /* Removes both cartridges */
1649 }
1650 
1651 #ifndef BASIC
1652 
CARTRIDGE_StateRead(UBYTE version)1653 void CARTRIDGE_StateRead(UBYTE version)
1654 {
1655 	int saved_type = CARTRIDGE_NONE;
1656 	char filename[FILENAME_MAX];
1657 
1658 	/* Read the cart type from the file.  If there is no cart type, becaused we have
1659 	   reached the end of the file, this will just default to CART_NONE */
1660 	StateSav_ReadINT(&saved_type, 1);
1661 	if (saved_type != CARTRIDGE_NONE) {
1662 		StateSav_ReadFNAME(filename);
1663 		if (filename[0]) {
1664 			/* Insert the cartridge... */
1665 			if (CARTRIDGE_Insert(filename) >= 0) {
1666 				/* And set the type to the saved type, in case it was a raw cartridge image */
1667 				CARTRIDGE_main.type = saved_type;
1668 			}
1669 		}
1670 		if (version >= 7)
1671 			/* Read the cartridge's state (current bank etc.). */
1672 			StateSav_ReadINT(&CARTRIDGE_main.state, 1);
1673 	}
1674 	else
1675 		CARTRIDGE_main.type = saved_type;
1676 
1677 	if (saved_type < 0) {
1678 		/* Minus value indicates a piggyback cartridge present. */
1679 		CARTRIDGE_main.type = -saved_type;
1680 
1681 		StateSav_ReadINT(&saved_type, 1);
1682 		StateSav_ReadFNAME(filename);
1683 		if (filename[0]) {
1684 			/* Insert the cartridge... */
1685 			if (CARTRIDGE_Insert_Second(filename) >= 0) {
1686 				/* And set the type to the saved type, in case it was a raw cartridge image */
1687 				CARTRIDGE_piggyback.type = saved_type;
1688 			}
1689 		}
1690 		if (version >= 7)
1691 			/* Read the cartridge's state (current bank etc.). */
1692 			StateSav_ReadINT(&CARTRIDGE_piggyback.state, 1);
1693 		else {
1694 			/* Savestate version 6 explicitely stored information about
1695 			   the active cartridge. */
1696 			int piggyback_active;
1697 			StateSav_ReadINT(&piggyback_active, 1);
1698 			if (piggyback_active)
1699 				active_cart = &CARTRIDGE_piggyback;
1700 			else
1701 				active_cart = &CARTRIDGE_main;
1702 			/* The "Determine active cartridge" code below makes no
1703 			   sense when loading ver.6 savestates, because they
1704 			   did not store the cartridge state. */
1705 			return;
1706 		}
1707 	}
1708 
1709 	/* Determine active cartridge (main or piggyback. */
1710 	if (CartIsPassthrough(CARTRIDGE_main.type) && (CARTRIDGE_main.state & 0x0c) == 0x08)
1711 		active_cart = &CARTRIDGE_piggyback;
1712 	else
1713 		active_cart = &CARTRIDGE_main;
1714 
1715 	MapActiveCart();
1716 }
1717 
CARTRIDGE_StateSave(void)1718 void CARTRIDGE_StateSave(void)
1719 {
1720 	int cart_save = CARTRIDGE_main.type;
1721 
1722 	if (CARTRIDGE_piggyback.type != CARTRIDGE_NONE)
1723 		/* Save the cart type as negative, to indicate to CARTStateRead that there is a
1724 		   second cartridge */
1725 		cart_save = -cart_save;
1726 
1727 	/* Save the cartridge type, or CARTRIDGE_NONE if there isn't one...*/
1728 	StateSav_SaveINT(&cart_save, 1);
1729 	if (CARTRIDGE_main.type != CARTRIDGE_NONE) {
1730 		StateSav_SaveFNAME(CARTRIDGE_main.filename);
1731 		StateSav_SaveINT(&CARTRIDGE_main.state, 1);
1732 	}
1733 
1734 	if (CARTRIDGE_piggyback.type != CARTRIDGE_NONE) {
1735 		/* Save the second cartridge type and name*/
1736 		StateSav_SaveINT(&CARTRIDGE_piggyback.type, 1);
1737 		StateSav_SaveFNAME(CARTRIDGE_piggyback.filename);
1738 		StateSav_SaveINT(&CARTRIDGE_piggyback.state, 1);
1739 	}
1740 }
1741 
1742 #endif
1743 
1744 /*
1745 vim:ts=4:sw=4:
1746 */
1747