1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - interpreter_tlb.def *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2002 Hacktarux *
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. *
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. *
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 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
22 #include <zlib.h> // For adler32()
24 DECLARE_INSTRUCTION(TLBR)
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)
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)
39 static void TLBWrite(unsigned int idx)
41 if (r4300emu != CORE_PURE_INTERPRETER)
44 if (tlb_e[idx].v_even)
46 for (i=tlb_e[idx].start_even>>12; i<=tlb_e[idx].end_even>>12; i++)
48 if(!invalid_code[i] &&(invalid_code[tlb_LUT_r[i]>>12] ||
49 invalid_code[(tlb_LUT_r[i]>>12)+0x20000]))
55 md5_byte_t digest[16];
58 (const md5_byte_t*)&rdram[(tlb_LUT_r[i]&0x7FF000)/4],
60 md5_finish(&state, digest);
61 for (j=0; j<16; j++) blocks[i]->md5[j] = digest[j];*/
63 blocks[i]->adler32 = adler32(0, (const unsigned char *)&rdram[(tlb_LUT_r[i]&0x7FF000)/4], 0x1000);
70 for (j=0; j<16; j++) blocks[i]->md5[j] = 0;*/
71 blocks[i]->adler32 = 0;
77 for (i=tlb_e[idx].start_odd>>12; i<=tlb_e[idx].end_odd>>12; i++)
79 if(!invalid_code[i] &&(invalid_code[tlb_LUT_r[i]>>12] ||
80 invalid_code[(tlb_LUT_r[i]>>12)+0x20000]))
86 md5_byte_t digest[16];
89 (const md5_byte_t*)&rdram[(tlb_LUT_r[i]&0x7FF000)/4],
91 md5_finish(&state, digest);
92 for (j=0; j<16; j++) blocks[i]->md5[j] = digest[j];*/
94 blocks[i]->adler32 = adler32(0, (const unsigned char *)&rdram[(tlb_LUT_r[i]&0x7FF000)/4], 0x1000);
101 for (j=0; j<16; j++) blocks[i]->md5[j] = 0;*/
102 blocks[i]->adler32 = 0;
108 tlb_unmap(&tlb_e[idx]);
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;
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;
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;
135 tlb_map(&tlb_e[idx]);
137 if (r4300emu != CORE_PURE_INTERPRETER)
140 if (tlb_e[idx].v_even)
142 for (i=tlb_e[idx].start_even>>12; i<=tlb_e[idx].end_even>>12; i++)
144 /*if (blocks[i] && (blocks[i]->md5[0] || blocks[i]->md5[1] ||
145 blocks[i]->md5[2] || blocks[i]->md5[3]))
150 md5_byte_t digest[16];
153 (const md5_byte_t*)&rdram[(tlb_LUT_r[i]&0x7FF000)/4],
155 md5_finish(&state, digest);
157 if (digest[j] != blocks[i]->md5[j])
159 if (equal) invalid_code[i] = 0;
161 if(blocks[i] && blocks[i]->adler32)
163 if(blocks[i]->adler32 == adler32(0,(const unsigned char *)&rdram[(tlb_LUT_r[i]&0x7FF000)/4],0x1000))
169 if (tlb_e[idx].v_odd)
171 for (i=tlb_e[idx].start_odd>>12; i<=tlb_e[idx].end_odd>>12; i++)
173 /*if (blocks[i] && (blocks[i]->md5[0] || blocks[i]->md5[1] ||
174 blocks[i]->md5[2] || blocks[i]->md5[3]))
179 md5_byte_t digest[16];
182 (const md5_byte_t*)&rdram[(tlb_LUT_r[i]&0x7FF000)/4],
184 md5_finish(&state, digest);
186 if (digest[j] != blocks[i]->md5[j])
188 if (equal) invalid_code[i] = 0;
190 if(blocks[i] && blocks[i]->adler32)
192 if(blocks[i]->adler32 == adler32(0,(const unsigned char *)&rdram[(tlb_LUT_r[i]&0x7FF000)/4],0x1000))
200 DECLARE_INSTRUCTION(TLBWI)
202 TLBWrite(Index&0x3F);
206 DECLARE_INSTRUCTION(TLBWR)
209 Random = (Count/2 % (32 - Wired)) + Wired;
214 DECLARE_INSTRUCTION(TLBP)
220 if (((tlb_e[i].vpn2 & (~tlb_e[i].mask)) ==
221 (((EntryHi & 0xFFFFE000) >> 13) & (~tlb_e[i].mask))) &&
223 (tlb_e[i].asid == (EntryHi & 0xFF))))
232 DECLARE_INSTRUCTION(ERET)
237 DebugMessage(M64MSG_ERROR, "error in ERET");
243 generic_jump_to(EPC);
248 if (next_interupt <= Count) gen_interupt();