Core commit. Compile and run on the OpenPandora
[mupen64plus-pandora.git] / source / mupen64plus-core / src / r4300 / interpreter_tlb.def
CommitLineData
451ab91e 1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - interpreter_tlb.def *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2002 Hacktarux *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
20 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21
22#include <zlib.h> // For adler32()
23
24DECLARE_INSTRUCTION(TLBR)
25{
26 int index;
27 index = Index & 0x1F;
28 PageMask = tlb_e[index].mask << 13;
29 EntryHi = ((tlb_e[index].vpn2 << 13) | tlb_e[index].asid);
30 EntryLo0 = (tlb_e[index].pfn_even << 6) | (tlb_e[index].c_even << 3)
31 | (tlb_e[index].d_even << 2) | (tlb_e[index].v_even << 1)
32 | tlb_e[index].g;
33 EntryLo1 = (tlb_e[index].pfn_odd << 6) | (tlb_e[index].c_odd << 3)
34 | (tlb_e[index].d_odd << 2) | (tlb_e[index].v_odd << 1)
35 | tlb_e[index].g;
36 ADD_TO_PC(1);
37}
38
39static void TLBWrite(unsigned int idx)
40{
41 if (r4300emu != CORE_PURE_INTERPRETER)
42 {
43 unsigned int i;
44 if (tlb_e[idx].v_even)
45 {
46 for (i=tlb_e[idx].start_even>>12; i<=tlb_e[idx].end_even>>12; i++)
47 {
48 if(!invalid_code[i] &&(invalid_code[tlb_LUT_r[i]>>12] ||
49 invalid_code[(tlb_LUT_r[i]>>12)+0x20000]))
50 invalid_code[i] = 1;
51 if (!invalid_code[i])
52 {
53 /*int j;
54 md5_state_t state;
55 md5_byte_t digest[16];
56 md5_init(&state);
57 md5_append(&state,
58 (const md5_byte_t*)&rdram[(tlb_LUT_r[i]&0x7FF000)/4],
59 0x1000);
60 md5_finish(&state, digest);
61 for (j=0; j<16; j++) blocks[i]->md5[j] = digest[j];*/
62
63 blocks[i]->adler32 = adler32(0, (const unsigned char *)&rdram[(tlb_LUT_r[i]&0x7FF000)/4], 0x1000);
64
65 invalid_code[i] = 1;
66 }
67 else if (blocks[i])
68 {
69 /*int j;
70 for (j=0; j<16; j++) blocks[i]->md5[j] = 0;*/
71 blocks[i]->adler32 = 0;
72 }
73 }
74 }
75 if (tlb_e[idx].v_odd)
76 {
77 for (i=tlb_e[idx].start_odd>>12; i<=tlb_e[idx].end_odd>>12; i++)
78 {
79 if(!invalid_code[i] &&(invalid_code[tlb_LUT_r[i]>>12] ||
80 invalid_code[(tlb_LUT_r[i]>>12)+0x20000]))
81 invalid_code[i] = 1;
82 if (!invalid_code[i])
83 {
84 /*int j;
85 md5_state_t state;
86 md5_byte_t digest[16];
87 md5_init(&state);
88 md5_append(&state,
89 (const md5_byte_t*)&rdram[(tlb_LUT_r[i]&0x7FF000)/4],
90 0x1000);
91 md5_finish(&state, digest);
92 for (j=0; j<16; j++) blocks[i]->md5[j] = digest[j];*/
93
94 blocks[i]->adler32 = adler32(0, (const unsigned char *)&rdram[(tlb_LUT_r[i]&0x7FF000)/4], 0x1000);
95
96 invalid_code[i] = 1;
97 }
98 else if (blocks[i])
99 {
100 /*int j;
101 for (j=0; j<16; j++) blocks[i]->md5[j] = 0;*/
102 blocks[i]->adler32 = 0;
103 }
104 }
105 }
106 }
107
108 tlb_unmap(&tlb_e[idx]);
109
110 tlb_e[idx].g = (EntryLo0 & EntryLo1 & 1);
111 tlb_e[idx].pfn_even = (EntryLo0 & 0x3FFFFFC0) >> 6;
112 tlb_e[idx].pfn_odd = (EntryLo1 & 0x3FFFFFC0) >> 6;
113 tlb_e[idx].c_even = (EntryLo0 & 0x38) >> 3;
114 tlb_e[idx].c_odd = (EntryLo1 & 0x38) >> 3;
115 tlb_e[idx].d_even = (EntryLo0 & 0x4) >> 2;
116 tlb_e[idx].d_odd = (EntryLo1 & 0x4) >> 2;
117 tlb_e[idx].v_even = (EntryLo0 & 0x2) >> 1;
118 tlb_e[idx].v_odd = (EntryLo1 & 0x2) >> 1;
119 tlb_e[idx].asid = (EntryHi & 0xFF);
120 tlb_e[idx].vpn2 = (EntryHi & 0xFFFFE000) >> 13;
121 //tlb_e[idx].r = (EntryHi & 0xC000000000000000LL) >> 62;
122 tlb_e[idx].mask = (PageMask & 0x1FFE000) >> 13;
123
124 tlb_e[idx].start_even = tlb_e[idx].vpn2 << 13;
125 tlb_e[idx].end_even = tlb_e[idx].start_even+
126 (tlb_e[idx].mask << 12) + 0xFFF;
127 tlb_e[idx].phys_even = tlb_e[idx].pfn_even << 12;
128
129
130 tlb_e[idx].start_odd = tlb_e[idx].end_even+1;
131 tlb_e[idx].end_odd = tlb_e[idx].start_odd+
132 (tlb_e[idx].mask << 12) + 0xFFF;
133 tlb_e[idx].phys_odd = tlb_e[idx].pfn_odd << 12;
134
135 tlb_map(&tlb_e[idx]);
136
137 if (r4300emu != CORE_PURE_INTERPRETER)
138 {
139 unsigned int i;
140 if (tlb_e[idx].v_even)
141 {
142 for (i=tlb_e[idx].start_even>>12; i<=tlb_e[idx].end_even>>12; i++)
143 {
144 /*if (blocks[i] && (blocks[i]->md5[0] || blocks[i]->md5[1] ||
145 blocks[i]->md5[2] || blocks[i]->md5[3]))
146 {
147 int j;
148 int equal = 1;
149 md5_state_t state;
150 md5_byte_t digest[16];
151 md5_init(&state);
152 md5_append(&state,
153 (const md5_byte_t*)&rdram[(tlb_LUT_r[i]&0x7FF000)/4],
154 0x1000);
155 md5_finish(&state, digest);
156 for (j=0; j<16; j++)
157 if (digest[j] != blocks[i]->md5[j])
158 equal = 0;
159 if (equal) invalid_code[i] = 0;
160 }*/
161 if(blocks[i] && blocks[i]->adler32)
162 {
163 if(blocks[i]->adler32 == adler32(0,(const unsigned char *)&rdram[(tlb_LUT_r[i]&0x7FF000)/4],0x1000))
164 invalid_code[i] = 0;
165 }
166 }
167 }
168
169 if (tlb_e[idx].v_odd)
170 {
171 for (i=tlb_e[idx].start_odd>>12; i<=tlb_e[idx].end_odd>>12; i++)
172 {
173 /*if (blocks[i] && (blocks[i]->md5[0] || blocks[i]->md5[1] ||
174 blocks[i]->md5[2] || blocks[i]->md5[3]))
175 {
176 int j;
177 int equal = 1;
178 md5_state_t state;
179 md5_byte_t digest[16];
180 md5_init(&state);
181 md5_append(&state,
182 (const md5_byte_t*)&rdram[(tlb_LUT_r[i]&0x7FF000)/4],
183 0x1000);
184 md5_finish(&state, digest);
185 for (j=0; j<16; j++)
186 if (digest[j] != blocks[i]->md5[j])
187 equal = 0;
188 if (equal) invalid_code[i] = 0;
189 }*/
190 if(blocks[i] && blocks[i]->adler32)
191 {
192 if(blocks[i]->adler32 == adler32(0,(const unsigned char *)&rdram[(tlb_LUT_r[i]&0x7FF000)/4],0x1000))
193 invalid_code[i] = 0;
194 }
195 }
196 }
197 }
198}
199
200DECLARE_INSTRUCTION(TLBWI)
201{
202 TLBWrite(Index&0x3F);
203 ADD_TO_PC(1);
204}
205
206DECLARE_INSTRUCTION(TLBWR)
207{
208 update_count();
209 Random = (Count/2 % (32 - Wired)) + Wired;
210 TLBWrite(Random);
211 ADD_TO_PC(1);
212}
213
214DECLARE_INSTRUCTION(TLBP)
215{
216 int i;
217 Index |= 0x80000000;
218 for (i=0; i<32; i++)
219 {
220 if (((tlb_e[i].vpn2 & (~tlb_e[i].mask)) ==
221 (((EntryHi & 0xFFFFE000) >> 13) & (~tlb_e[i].mask))) &&
222 ((tlb_e[i].g) ||
223 (tlb_e[i].asid == (EntryHi & 0xFF))))
224 {
225 Index = i;
226 break;
227 }
228 }
229 ADD_TO_PC(1);
230}
231
232DECLARE_INSTRUCTION(ERET)
233{
234 update_count();
235 if (Status & 0x4)
236 {
237 DebugMessage(M64MSG_ERROR, "error in ERET");
238 stop=1;
239 }
240 else
241 {
242 Status &= ~0x2;
243 generic_jump_to(EPC);
244 }
245 llbit = 0;
246 check_interupt();
247 last_addr = PCADDR;
248 if (next_interupt <= Count) gen_interupt();
249}