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