1.40a fixes, pt2
[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. */
bdec53c9 10static unsigned int carthw_12in1_baddr = 0;
11
12static carthw_state_chunk carthw_12in1_state[] =
13{
14 { CHUNK_CARTHW, sizeof(carthw_12in1_baddr), &carthw_12in1_baddr },
15 { 0, 0, NULL }
16};
17
757f8dae 18static unsigned int carthw_12in1_read16(unsigned int a, int realsize)
19{
20 // ??
21 elprintf(EL_UIO, "12-in-1: read [%06x] @ %06x", a, SekPc);
22 return 0;
23}
24
25static void carthw_12in1_write8(unsigned int a, unsigned int d, int realsize)
26{
27 int len;
28
29 if (a < 0xA13000 || a >= 0xA13040) {
a12b1b29 30 /* 4-in-1 has Real Deal Boxing, which uses serial eeprom,
31 * but I really doubt that pirate cart had it */
32 if (a != 0x200001)
33 elprintf(EL_ANOMALY, "12-in-1: unexpected write [%06x] %02x @ %06x", a, d, SekPc);
34 return;
757f8dae 35 }
36
bdec53c9 37 carthw_12in1_baddr = a;
757f8dae 38 a &= 0x3f; a <<= 16;
39 len = Pico.romsize - a;
40 if (len <= 0) {
41 elprintf(EL_ANOMALY, "12-in-1: missing bank @ %06x", a);
42 return;
43 }
44
a12b1b29 45 memcpy(Pico.rom, Pico.rom + Pico.romsize + a, len);
757f8dae 46}
47
48static void carthw_12in1_reset(void)
49{
50 carthw_12in1_write8(0xA13000, 0, 0);
51}
52
bdec53c9 53static void carthw_12in1_statef(void)
54{
55 carthw_12in1_write8(carthw_12in1_baddr, 0, 0);
56}
57
757f8dae 58void carthw_12in1_startup(void)
59{
60 void *tmp;
61
62 elprintf(EL_STATUS, "12-in-1 mapper detected");
63
a12b1b29 64 tmp = realloc(Pico.rom, Pico.romsize * 2);
757f8dae 65 if (tmp == NULL)
66 {
67 elprintf(EL_STATUS, "OOM");
68 return;
69 }
a12b1b29 70 Pico.rom = tmp;
71 memcpy(Pico.rom + Pico.romsize, Pico.rom, Pico.romsize);
757f8dae 72
73 PicoRead16Hook = carthw_12in1_read16;
74 PicoWrite8Hook = carthw_12in1_write8;
75 PicoResetHook = carthw_12in1_reset;
bdec53c9 76 PicoLoadStateHook = carthw_12in1_statef;
77 carthw_chunks = carthw_12in1_state;
757f8dae 78}
79
a12b1b29 80
81/* Realtec, based on TascoDLX doc
82 * http://www.sharemation.com/TascoDLX/REALTEC%20Cart%20Mapper%20-%20description%20v1.txt
83 */
84static int realtec_bank = 0x80000000, realtec_size = 0x80000000;
85static int realtec_romsize = 0;
86
87static void carthw_realtec_write8(unsigned int a, unsigned int d, int realsize)
88{
89 int i, bank_old = realtec_bank, size_old = realtec_size;
90
91 if (a == 0x400000)
92 {
93 realtec_bank &= 0x0e0000;
94 realtec_bank |= 0x300000 & (d << 19);
95 if (realtec_bank != bank_old)
96 elprintf(EL_ANOMALY, "write [%06x] %02x @ %06x", a, d, SekPc);
97 }
98 else if (a == 0x402000)
99 {
100 realtec_size = (d << 17) & 0x3e0000;
101 if (realtec_size != size_old)
102 elprintf(EL_ANOMALY, "write [%06x] %02x @ %06x", a, d, SekPc);
103 }
104 else if (a == 0x404000)
105 {
106 realtec_bank &= 0x300000;
107 realtec_bank |= 0x0e0000 & (d << 17);
108 if (realtec_bank != bank_old)
109 elprintf(EL_ANOMALY, "write [%06x] %02x @ %06x", a, d, SekPc);
110 }
111 else
112 elprintf(EL_ANOMALY, "realtec: unexpected write [%06x] %02x @ %06x", a, d, SekPc);
113
114 if (realtec_bank >= 0 && realtec_size >= 0 &&
115 (realtec_bank != bank_old || realtec_size != size_old))
116 {
117 elprintf(EL_ANOMALY, "realtec: new bank %06x, size %06x", realtec_bank, realtec_size, SekPc);
118 if (realtec_size > realtec_romsize - realtec_bank || realtec_bank >= realtec_romsize)
119 {
120 elprintf(EL_ANOMALY, "realtec: bank too large / out of range?");
121 return;
122 }
123
124 for (i = 0; i < 0x400000; i += realtec_size)
125 memcpy(Pico.rom + i, Pico.rom + 0x400000 + realtec_bank, realtec_size);
126 }
127}
128
129void carthw_realtec_reset(void)
130{
131 int i;
132 /* map boot code */
133 for (i = 0; i < 0x400000; i += 0x2000)
134 memcpy(Pico.rom + i, Pico.rom + 0x400000 + realtec_romsize - 0x2000, 0x2000);
135 realtec_bank = realtec_size = 0x80000000;
136}
137
138void carthw_realtec_startup(void)
139{
140 void *tmp;
141
142 elprintf(EL_STATUS, "Realtec mapper detected");
143
144 realtec_romsize = Pico.romsize;
145 Pico.romsize = 0x400000;
146 tmp = realloc(Pico.rom, 0x400000 + realtec_romsize);
147 if (tmp == NULL)
148 {
149 elprintf(EL_STATUS, "OOM");
150 return;
151 }
152 Pico.rom = tmp;
153 memcpy(Pico.rom + 0x400000, Pico.rom, realtec_romsize);
154
155 PicoWrite8Hook = carthw_realtec_write8;
156 PicoResetHook = carthw_realtec_reset;
157}
158