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" |
f53f286a |
10 | |
f8ef8ff7 |
11 | #ifndef UTYPES_DEFINED |
12 | typedef unsigned char u8; |
13 | typedef unsigned short u16; |
14 | typedef unsigned int u32; |
15 | #define UTYPES_DEFINED |
16 | #endif |
17 | |
18 | #define CLEAR_DETECT(pc_start,pc_end,text) \ |
19 | if (d == 0 && SekPc >= pc_start && SekPc < pc_end) \ |
20 | { \ |
21 | if (!clearing_ram) \ |
689fb2c0 |
22 | elprintf(EL_SVP, text); \ |
f8ef8ff7 |
23 | clearing_ram = 1; \ |
24 | return; \ |
25 | } |
26 | |
f53f286a |
27 | unsigned int PicoSVPRead16(unsigned int a, int realsize) |
28 | { |
29 | unsigned int d = 0; |
d26dc685 |
30 | static int a15004_looping = 0; |
f53f286a |
31 | |
d26dc685 |
32 | // dram: 300000-31ffff |
33 | if ((a & 0xfe0000) == 0x300000) |
5de27868 |
34 | d = *(u16 *)(svp->dram + (a&0x1fffe)); |
f8ef8ff7 |
35 | |
d26dc685 |
36 | // "cell arrange" 1: 390000-39ffff |
37 | else if ((a & 0xff0000) == 0x390000) { |
38 | // this is rewritten 68k code |
39 | unsigned int a1 = a >> 1; |
40 | a1 = (a1 & 0x7001) | ((a1 & 0x3e) << 6) | ((a1 & 0xfc0) >> 5); |
41 | d = ((u16 *)svp->dram)[a1]; |
42 | } |
43 | |
44 | // "cell arrange" 2: 3a0000-3affff |
45 | else if ((a & 0xff0000) == 0x3a0000) { |
46 | // this is rewritten 68k code |
47 | unsigned int a1 = a >> 1; |
48 | a1 = (a1 & 0x7801) | ((a1 & 0x1e) << 6) | ((a1 & 0x7e0) >> 4); |
49 | d = ((u16 *)svp->dram)[a1]; |
50 | } |
51 | |
52 | // regs |
53 | else if ((a & 0xfffff0) == 0xa15000) { |
54 | switch (a & 0xf) { |
55 | case 0: |
56 | case 2: |
57 | d = svp->ssp1601.gr[SSP_XST].h; |
58 | break; |
59 | |
60 | case 4: |
61 | d = svp->ssp1601.gr[SSP_PM0].h; |
62 | svp->ssp1601.gr[SSP_PM0].h &= ~1; |
63 | if (d&1) a15004_looping = 0; |
64 | break; |
65 | } |
66 | } |
67 | else |
689fb2c0 |
68 | elprintf(EL_UIO|EL_SVP|EL_ANOMALY, "SVP FIXME: unhandled r%i: [%06x] %04x @%06x", realsize, a&0xffffff, d, SekPc); |
d26dc685 |
69 | |
70 | if (!a15004_looping) |
689fb2c0 |
71 | elprintf(EL_SVP, "SVP r%i: [%06x] %04x @%06x", realsize, a&0xffffff, d, SekPc); |
d26dc685 |
72 | |
73 | if (a == 0xa15004 && !(d&1)) { |
74 | if (!a15004_looping) |
75 | elprintf(EL_SVP, "SVP det TIGHT loop: a15004"); |
76 | a15004_looping = 1; |
77 | } |
78 | else a15004_looping = 0; |
f53f286a |
79 | |
16ebbe9e |
80 | //if (a == 0x30fe02 && d == 0) |
81 | // elprintf(EL_ANOMALY, "SVP lag?"); |
f8ef8ff7 |
82 | |
f53f286a |
83 | return d; |
84 | } |
85 | |
86 | void PicoSVPWrite8(unsigned int a, unsigned int d, int realsize) |
87 | { |
689fb2c0 |
88 | elprintf(EL_UIO|EL_SVP|EL_ANOMALY, "!!! SVP w%i: [%06x], %08x @%06x", realsize, a&0xffffff, d, SekPc); |
f8ef8ff7 |
89 | } |
90 | |
91 | void PicoSVPWrite16(unsigned int a, unsigned int d, int realsize) |
92 | { |
93 | static int clearing_ram = 0; |
94 | |
d26dc685 |
95 | // DRAM |
96 | if ((a & 0xfe0000) == 0x300000) |
5de27868 |
97 | *(u16 *)(svp->dram + (a&0x1fffe)) = d; |
f8ef8ff7 |
98 | |
d26dc685 |
99 | // regs |
100 | else if ((a & 0xfffff0) == 0xa15000) { |
101 | if (a == 0xa15000 || a == 0xa15002) { |
102 | // just guessing here |
103 | svp->ssp1601.gr[SSP_XST].h = d; |
104 | svp->ssp1601.gr[SSP_PM0].h |= 2; |
105 | svp->ssp1601.emu_status &= ~SSP_WAIT_PM0; |
106 | } |
107 | //else if (a == 0xa15006) svp->ssp1601.gr[SSP_PM0].h = d | (d << 1); |
108 | // 0xa15006 probably has 'halt' |
109 | } |
a6fb500b |
110 | else |
111 | elprintf(EL_UIO|EL_SVP|EL_ANOMALY, "SVP FIXME: unhandled w%i: [%06x] %04x @%06x", realsize, a&0xffffff, d, SekPc); |
d26dc685 |
112 | |
113 | |
30752975 |
114 | if (a == 0x30fe06 && d != 0) |
d26dc685 |
115 | svp->ssp1601.emu_status &= ~SSP_WAIT_30FE06; |
30752975 |
116 | |
117 | if (a == 0x30fe08 && d != 0) |
d26dc685 |
118 | svp->ssp1601.emu_status &= ~SSP_WAIT_30FE08; |
30752975 |
119 | |
f8ef8ff7 |
120 | // debug: detect RAM clears.. |
30752975 |
121 | CLEAR_DETECT(0x0221dc, 0x0221f0, "SVP RAM CLEAR (full) @ 0221C2"); |
122 | CLEAR_DETECT(0x02204c, 0x022068, "SVP RAM CLEAR 300000-31ffbf (1) @ 022032"); |
f8ef8ff7 |
123 | CLEAR_DETECT(0x021900, 0x021ff0, "SVP RAM CLEAR 300000-305fff"); |
30752975 |
124 | CLEAR_DETECT(0x0220b0, 0x0220cc, "SVP RAM CLEAR 300000-31ffbf (2) @ 022096"); |
f8ef8ff7 |
125 | clearing_ram = 0; |
126 | |
689fb2c0 |
127 | elprintf(EL_SVP, "SVP w%i: [%06x] %04x @%06x", realsize, a&0xffffff, d, SekPc); |
f53f286a |
128 | } |
129 | |