1 #include "../pico_int.h"
4 static const char str_mars[] = "MARS";
8 u8 dram[0x40000]; // AKA fb
9 u8 m68k_rom[M68K_BANK_SIZE]; // 0x100
12 static struct Pico32xMem *Pico32xMem;
14 static u32 p32x_reg_read16(u32 a)
18 return Pico32x.regs[a / 2];
21 static void p32x_reg_write16(u32 a, u32 d)
25 if (a == 0 && !(Pico32x.regs[0] & 1)) {
32 static void p32x_reg_write8(u32 a, u32 d)
36 if (a == 1 && !(Pico32x.regs[0] & 1)) {
44 static u32 p32x_vdp_read16(u32 a)
48 return Pico32x.vdp_regs[a / 2];
51 static void p32x_vdp_write16(u32 a, u32 d)
57 Pico32x.pending_fb = d & 1;
58 if (Pico.video.status & 8) {
59 Pico32x.vdp_regs[0x0a/2] &= ~1;
60 Pico32x.vdp_regs[0x0a/2] |= d & 1;
66 static void p32x_vdp_write8(u32 a, u32 d)
72 Pico32x.pending_fb = d & 1;
73 if (Pico.video.status & 8) {
74 Pico32x.vdp_regs[0x0a/2] &= ~1;
75 Pico32x.vdp_regs[0x0a/2] |= d & 1;
81 // default 32x handlers
82 u32 PicoRead8_32x(u32 a)
85 if ((a & 0xffc0) == 0x5100) { // a15100
86 d = p32x_reg_read16(a);
90 if ((a & 0xfff0) == 0x5180 && (Pico32x.regs[0] & 1)) {
91 d = p32x_vdp_read16(a);
95 if ((a & 0xfffc) == 0x30ec) { // a130ec
100 elprintf(EL_UIO, "m68k unmapped r8 [%06x] @%06x", a, SekPc);
110 elprintf(EL_32X, "m68k 32x r8 [%06x] %02x @%06x", a, d, SekPc);
114 u32 PicoRead16_32x(u32 a)
117 if ((a & 0xffc0) == 0x5100) { // a15100
118 d = p32x_reg_read16(a);
122 if ((a & 0xfff0) == 0x5180 && (Pico32x.regs[0] & 1)) { // a15180
123 d = p32x_vdp_read16(a);
127 if ((a & 0xfffc) == 0x30ec) { // a130ec
128 d = !(a & 2) ? ('M'<<8)|'A' : ('R'<<8)|'S';
132 elprintf(EL_UIO, "m68k unmapped r16 [%06x] @%06x", a, SekPc);
136 elprintf(EL_32X, "m68k 32x r16 [%06x] %04x @%06x", a, d, SekPc);
140 void PicoWrite8_32x(u32 a, u32 d)
142 if ((a & 0xfc00) == 0x5000)
143 elprintf(EL_32X, "m68k 32x w8 [%06x] %02x @%06x", a, d & 0xff, SekPc);
145 if ((a & 0xffc0) == 0x5100) { // a15100
146 p32x_reg_write8(a, d);
150 if ((a & 0xfff0) == 0x5180 && (Pico32x.regs[0] & 1)) { // a15180
151 p32x_vdp_write8(a, d);
155 elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x", a, d & 0xff, SekPc);
158 void PicoWrite16_32x(u32 a, u32 d)
160 if ((a & 0xfc00) == 0x5000)
161 elprintf(EL_UIO, "m68k 32x w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);
163 if ((a & 0xffc0) == 0x5100) { // a15100
164 p32x_reg_write16(a, d);
168 if ((a & 0xfff0) == 0x5180 && (Pico32x.regs[0] & 1)) { // a15180
169 p32x_vdp_write16(a, d);
173 elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);
176 // hint vector is writeable
177 static void PicoWrite8_hint(u32 a, u32 d)
179 if ((a & 0xfffc) == 0x0070) {
180 Pico32xMem->m68k_rom[a ^ 1] = d;
184 elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x", a, d & 0xff, SekPc);
187 static void PicoWrite16_hint(u32 a, u32 d)
189 if ((a & 0xfffc) == 0x0070) {
190 ((u16 *)Pico32xMem->m68k_rom)[a/2] = d;
194 elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);
197 #define HWSWAP(x) (((x) << 16) | ((x) >> 16))
198 void PicoMemSetup32x(void)
202 unsigned int rs, rs1;
205 Pico32xMem = calloc(1, sizeof(*Pico32xMem));
206 if (Pico32xMem == NULL) {
207 elprintf(EL_STATUS, "OOM");
212 ps = (unsigned short *)Pico32xMem->m68k_rom;
213 pl = (unsigned int *)Pico32xMem->m68k_rom;
214 for (i = 1; i < 0xc0/4; i++)
215 pl[i] = HWSWAP(0x880200 + i * 6);
218 for (i = 0xc0/2; i < 0x100/2; i++)
222 ps[0xc2/2] = 0x2700; // move #0x2700,sr
223 ps[0xfe/2] = 0x60fe; // jump to self
225 // fill remaining mem with ROM
226 memcpy(Pico32xMem->m68k_rom + 0x100, Pico.rom + 0x100, M68K_BANK_SIZE - 0x100);
228 // cartridge area becomes unmapped
229 // XXX: we take the easy way and don't unmap ROM,
230 // so that we can avoid handling the RV bit.
231 // m68k_map_unmap(0x000000, 0x3fffff);
234 cpu68k_map_set(m68k_read8_map, 0x000000, M68K_BANK_SIZE - 1, Pico32xMem->m68k_rom, 0);
235 cpu68k_map_set(m68k_read16_map, 0x000000, M68K_BANK_SIZE - 1, Pico32xMem->m68k_rom, 0);
236 cpu68k_map_set(m68k_write8_map, 0x000000, M68K_BANK_SIZE - 1, PicoWrite8_hint, 1); // TODO verify
237 cpu68k_map_set(m68k_write16_map, 0x000000, M68K_BANK_SIZE - 1, PicoWrite16_hint, 1);
239 // 32X ROM (unbanked, XXX: consider mirroring?)
240 rs1 = rs = (Pico.romsize + M68K_BANK_MASK) & ~M68K_BANK_MASK;
243 cpu68k_map_set(m68k_read8_map, 0x880000, 0x880000 + rs1 - 1, Pico.rom, 0);
244 cpu68k_map_set(m68k_read16_map, 0x880000, 0x880000 + rs1 - 1, Pico.rom, 0);
249 cpu68k_map_set(m68k_read8_map, 0x900000, 0x900000 + rs - 1, Pico.rom, 0);
250 cpu68k_map_set(m68k_read16_map, 0x900000, 0x900000 + rs - 1, Pico.rom, 0);