65ca3034 |
1 | // The SVP chip emulator, mem I/O stuff |
d4ca252d |
2 | |
3 | // (c) Copyright 2008, Grazvydas "notaz" Ignotas |
4 | // Free for non-commercial use. |
5 | |
6 | // For commercial use, separate licencing terms must be obtained. |
7 | |
8 | |
efcba75f |
9 | #include "../../pico_int.h" |
45f2f245 |
10 | #include "../../memory.h" |
f53f286a |
11 | |
72f63cf0 |
12 | // for wait loop det |
13 | static void PicoWrite16_dram(u32 a, u32 d) |
14 | { |
15 | a &= ~0xfe0000; |
d26dc685 |
16 | |
72f63cf0 |
17 | if (d != 0) { |
18 | if (a == 0xfe06) // 30fe06 |
19 | svp->ssp1601.emu_status &= ~SSP_WAIT_30FE06; |
20 | else if (a == 0xfe08) |
21 | svp->ssp1601.emu_status &= ~SSP_WAIT_30FE08; |
d26dc685 |
22 | } |
72f63cf0 |
23 | |
24 | ((u16 *)svp->dram)[a / 2] = d; |
25 | } |
26 | |
27 | // "cell arrange" 1: 390000-39ffff |
28 | static u32 PicoRead16_svpca1(u32 a) |
29 | { |
30 | // this is 68k code rewritten |
31 | u32 a1 = a >> 1; |
32 | a1 = (a1 & 0x7001) | ((a1 & 0x3e) << 6) | ((a1 & 0xfc0) >> 5); |
33 | return ((u16 *)svp->dram)[a1]; |
34 | } |
35 | |
36 | // "cell arrange" 2: 3a0000-3affff |
37 | static u32 PicoRead16_svpca2(u32 a) |
38 | { |
39 | u32 a1 = a >> 1; |
40 | a1 = (a1 & 0x7801) | ((a1 & 0x1e) << 6) | ((a1 & 0x7e0) >> 4); |
41 | return ((u16 *)svp->dram)[a1]; |
42 | } |
45f2f245 |
43 | |
44 | // IO/control area (0xa10000 - 0xa1ffff) |
45 | static u32 PicoRead16_svpr(u32 a) |
46 | { |
47 | u32 d = 0; |
d26dc685 |
48 | |
49 | // regs |
72f63cf0 |
50 | if ((a & ~0x0f) == 0xa15000) { |
d26dc685 |
51 | switch (a & 0xf) { |
52 | case 0: |
53 | case 2: |
54 | d = svp->ssp1601.gr[SSP_XST].h; |
55 | break; |
56 | |
57 | case 4: |
58 | d = svp->ssp1601.gr[SSP_PM0].h; |
59 | svp->ssp1601.gr[SSP_PM0].h &= ~1; |
d26dc685 |
60 | break; |
61 | } |
d26dc685 |
62 | |
45f2f245 |
63 | #if EL_LOGMASK & EL_SVP |
64 | { |
65 | static int a15004_looping = 0; |
66 | if (a == 0xa15004 && (d & 1)) |
67 | a15004_looping = 0; |
68 | |
69 | if (!a15004_looping) |
70 | elprintf(EL_SVP, "SVP r%i: [%06x] %04x @%06x", realsize, a, d, SekPc); |
71 | |
72 | if (a == 0xa15004 && !(d&1)) { |
73 | if (!a15004_looping) |
74 | elprintf(EL_SVP, "SVP det TIGHT loop: a15004"); |
75 | a15004_looping = 1; |
76 | } |
77 | else |
78 | a15004_looping = 0; |
79 | } |
80 | #endif |
81 | return d; |
d26dc685 |
82 | } |
f53f286a |
83 | |
16ebbe9e |
84 | //if (a == 0x30fe02 && d == 0) |
85 | // elprintf(EL_ANOMALY, "SVP lag?"); |
f8ef8ff7 |
86 | |
45f2f245 |
87 | return PicoRead16_io(a); |
f53f286a |
88 | } |
89 | |
72f63cf0 |
90 | // used in VR test mode |
91 | static u32 PicoRead8_svpr(u32 a) |
92 | { |
93 | u32 d; |
94 | |
95 | if ((a & ~0x0f) != 0xa15000) |
96 | return PicoRead8_io(a); |
97 | |
98 | d = PicoRead16_svpr(a & ~1); |
99 | if (!(a & 1)) |
100 | d >>= 8; |
101 | return d; |
102 | } |
103 | |
45f2f245 |
104 | static void PicoWrite16_svpr(u32 a, u32 d) |
f53f286a |
105 | { |
45f2f245 |
106 | elprintf(EL_SVP, "SVP w16: [%06x] %04x @%06x", a, d, SekPc); |
f8ef8ff7 |
107 | |
72f63cf0 |
108 | if ((a & ~0x0f) == 0xa15000) { |
d26dc685 |
109 | if (a == 0xa15000 || a == 0xa15002) { |
110 | // just guessing here |
111 | svp->ssp1601.gr[SSP_XST].h = d; |
112 | svp->ssp1601.gr[SSP_PM0].h |= 2; |
113 | svp->ssp1601.emu_status &= ~SSP_WAIT_PM0; |
114 | } |
115 | //else if (a == 0xa15006) svp->ssp1601.gr[SSP_PM0].h = d | (d << 1); |
116 | // 0xa15006 probably has 'halt' |
45f2f245 |
117 | return; |
d26dc685 |
118 | } |
d26dc685 |
119 | |
45f2f245 |
120 | PicoWrite16_io(a, d); |
45f2f245 |
121 | } |
122 | |
123 | void PicoSVPMemSetup(void) |
124 | { |
125 | // 68k memmap: |
126 | // DRAM |
127 | cpu68k_map_set(m68k_read8_map, 0x300000, 0x31ffff, svp->dram, 0); |
128 | cpu68k_map_set(m68k_read16_map, 0x300000, 0x31ffff, svp->dram, 0); |
129 | cpu68k_map_set(m68k_write8_map, 0x300000, 0x31ffff, svp->dram, 0); |
130 | cpu68k_map_set(m68k_write16_map, 0x300000, 0x31ffff, svp->dram, 0); |
72f63cf0 |
131 | cpu68k_map_set(m68k_write16_map, 0x300000, 0x30ffff, PicoWrite16_dram, 1); |
30752975 |
132 | |
72f63cf0 |
133 | // DRAM (cell arrange) |
134 | cpu68k_map_set(m68k_read16_map, 0x390000, 0x39ffff, PicoRead16_svpca1, 1); |
135 | cpu68k_map_set(m68k_read16_map, 0x3a0000, 0x3affff, PicoRead16_svpca2, 1); |
f8ef8ff7 |
136 | |
45f2f245 |
137 | // regs |
72f63cf0 |
138 | cpu68k_map_set(m68k_read8_map, 0xa10000, 0xa1ffff, PicoRead8_svpr, 1); |
45f2f245 |
139 | cpu68k_map_set(m68k_read16_map, 0xa10000, 0xa1ffff, PicoRead16_svpr, 1); |
140 | cpu68k_map_set(m68k_write8_map, 0xa10000, 0xa1ffff, PicoWrite8_io, 1); // PicoWrite8_svpr |
141 | cpu68k_map_set(m68k_write16_map, 0xa10000, 0xa1ffff, PicoWrite16_svpr, 1); |
f53f286a |
142 | } |
143 | |