bugfixes, new config system and messed code for it
[picodrive.git] / Pico / carthw / carthw.c
CommitLineData
a12b1b29 1/*
2 * should better do some pointer stuff here. But as none of these bankswitch
3 * while the game runs, memcpy will suffice.
4 */
5
757f8dae 6#include "../PicoInt.h"
7
a12b1b29 8
9/* 12-in-1 and 4-in-1. Assuming 2MB ROMs here. */
757f8dae 10static unsigned int carthw_12in1_read16(unsigned int a, int realsize)
11{
12 // ??
13 elprintf(EL_UIO, "12-in-1: read [%06x] @ %06x", a, SekPc);
14 return 0;
15}
16
17static void carthw_12in1_write8(unsigned int a, unsigned int d, int realsize)
18{
19 int len;
20
21 if (a < 0xA13000 || a >= 0xA13040) {
a12b1b29 22 /* 4-in-1 has Real Deal Boxing, which uses serial eeprom,
23 * but I really doubt that pirate cart had it */
24 if (a != 0x200001)
25 elprintf(EL_ANOMALY, "12-in-1: unexpected write [%06x] %02x @ %06x", a, d, SekPc);
26 return;
757f8dae 27 }
28
29 a &= 0x3f; a <<= 16;
30 len = Pico.romsize - a;
31 if (len <= 0) {
32 elprintf(EL_ANOMALY, "12-in-1: missing bank @ %06x", a);
33 return;
34 }
35
a12b1b29 36 memcpy(Pico.rom, Pico.rom + Pico.romsize + a, len);
757f8dae 37}
38
39static void carthw_12in1_reset(void)
40{
41 carthw_12in1_write8(0xA13000, 0, 0);
42}
43
44void carthw_12in1_startup(void)
45{
46 void *tmp;
47
48 elprintf(EL_STATUS, "12-in-1 mapper detected");
49
a12b1b29 50 tmp = realloc(Pico.rom, Pico.romsize * 2);
757f8dae 51 if (tmp == NULL)
52 {
53 elprintf(EL_STATUS, "OOM");
54 return;
55 }
a12b1b29 56 Pico.rom = tmp;
57 memcpy(Pico.rom + Pico.romsize, Pico.rom, Pico.romsize);
757f8dae 58
59 PicoRead16Hook = carthw_12in1_read16;
60 PicoWrite8Hook = carthw_12in1_write8;
61 PicoResetHook = carthw_12in1_reset;
62}
63
a12b1b29 64
65/* Realtec, based on TascoDLX doc
66 * http://www.sharemation.com/TascoDLX/REALTEC%20Cart%20Mapper%20-%20description%20v1.txt
67 */
68static int realtec_bank = 0x80000000, realtec_size = 0x80000000;
69static int realtec_romsize = 0;
70
71static void carthw_realtec_write8(unsigned int a, unsigned int d, int realsize)
72{
73 int i, bank_old = realtec_bank, size_old = realtec_size;
74
75 if (a == 0x400000)
76 {
77 realtec_bank &= 0x0e0000;
78 realtec_bank |= 0x300000 & (d << 19);
79 if (realtec_bank != bank_old)
80 elprintf(EL_ANOMALY, "write [%06x] %02x @ %06x", a, d, SekPc);
81 }
82 else if (a == 0x402000)
83 {
84 realtec_size = (d << 17) & 0x3e0000;
85 if (realtec_size != size_old)
86 elprintf(EL_ANOMALY, "write [%06x] %02x @ %06x", a, d, SekPc);
87 }
88 else if (a == 0x404000)
89 {
90 realtec_bank &= 0x300000;
91 realtec_bank |= 0x0e0000 & (d << 17);
92 if (realtec_bank != bank_old)
93 elprintf(EL_ANOMALY, "write [%06x] %02x @ %06x", a, d, SekPc);
94 }
95 else
96 elprintf(EL_ANOMALY, "realtec: unexpected write [%06x] %02x @ %06x", a, d, SekPc);
97
98 if (realtec_bank >= 0 && realtec_size >= 0 &&
99 (realtec_bank != bank_old || realtec_size != size_old))
100 {
101 elprintf(EL_ANOMALY, "realtec: new bank %06x, size %06x", realtec_bank, realtec_size, SekPc);
102 if (realtec_size > realtec_romsize - realtec_bank || realtec_bank >= realtec_romsize)
103 {
104 elprintf(EL_ANOMALY, "realtec: bank too large / out of range?");
105 return;
106 }
107
108 for (i = 0; i < 0x400000; i += realtec_size)
109 memcpy(Pico.rom + i, Pico.rom + 0x400000 + realtec_bank, realtec_size);
110 }
111}
112
113void carthw_realtec_reset(void)
114{
115 int i;
116 /* map boot code */
117 for (i = 0; i < 0x400000; i += 0x2000)
118 memcpy(Pico.rom + i, Pico.rom + 0x400000 + realtec_romsize - 0x2000, 0x2000);
119 realtec_bank = realtec_size = 0x80000000;
120}
121
122void carthw_realtec_startup(void)
123{
124 void *tmp;
125
126 elprintf(EL_STATUS, "Realtec mapper detected");
127
128 realtec_romsize = Pico.romsize;
129 Pico.romsize = 0x400000;
130 tmp = realloc(Pico.rom, 0x400000 + realtec_romsize);
131 if (tmp == NULL)
132 {
133 elprintf(EL_STATUS, "OOM");
134 return;
135 }
136 Pico.rom = tmp;
137 memcpy(Pico.rom + 0x400000, Pico.rom, realtec_romsize);
138
139 PicoWrite8Hook = carthw_realtec_write8;
140 PicoResetHook = carthw_realtec_reset;
141}
142