Core commit. Compile and run on the OpenPandora
[mupen64plus-pandora.git] / source / mupen64plus-core / src / r4300 / interpreter_tlb.def
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
24 DECLARE_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
39 static 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
200 DECLARE_INSTRUCTION(TLBWI)
201 {
202    TLBWrite(Index&0x3F);
203    ADD_TO_PC(1);
204 }
205
206 DECLARE_INSTRUCTION(TLBWR)
207 {
208    update_count();
209    Random = (Count/2 % (32 - Wired)) + Wired;
210    TLBWrite(Random);
211    ADD_TO_PC(1);
212 }
213
214 DECLARE_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
232 DECLARE_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 }