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