313ec9db440b7c367dfbe95ce81e2bc0635ac1d4
[mupen64plus-pandora.git] / source / mupen64plus-core / src / r4300 / interpreter_cop0.def
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  *   Mupen64plus - interpreter_cop0.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 DECLARE_INSTRUCTION(MFC0)
23 {
24    switch(PC->f.r.nrd)
25    {
26       case 1:
27         DebugMessage(M64MSG_ERROR, "MFC0 instruction reading un-implemented Random register");
28         stop=1;
29       case 9:    // Count
30         update_count();
31       default:
32         rrt32 = reg_cop0[PC->f.r.nrd];
33         sign_extended(rrt);
34    }
35    ADD_TO_PC(1);
36 }
37
38 DECLARE_INSTRUCTION(MTC0)
39 {
40   switch(PC->f.r.nrd)
41   {
42     case 0:    // Index
43       Index = (unsigned int) rrt & 0x8000003F;
44       if ((Index & 0x3F) > 31) 
45       {
46         DebugMessage(M64MSG_ERROR, "MTC0 instruction writing Index register with TLB index > 31");
47         stop=1;
48       }
49       break;
50     case 1:    // Random
51       break;
52     case 2:    // EntryLo0
53       EntryLo0 = (unsigned int) rrt & 0x3FFFFFFF;
54       break;
55     case 3:    // EntryLo1
56       EntryLo1 = (unsigned int) rrt & 0x3FFFFFFF;
57       break;
58     case 4:    // Context
59       Context = ((unsigned int) rrt & 0xFF800000) | (Context & 0x007FFFF0);
60       break;
61     case 5:    // PageMask
62       PageMask = (unsigned int) rrt & 0x01FFE000;
63       break;
64     case 6:    // Wired
65       Wired = (unsigned int) rrt;
66       Random = 31;
67       break;
68     case 8:    // BadVAddr
69       break;
70     case 9:    // Count
71       update_count();
72       interupt_unsafe_state = 1;
73       if (next_interupt <= Count) gen_interupt();
74       interupt_unsafe_state = 0;
75       debug_count += Count;
76       translate_event_queue((unsigned int) rrt & 0xFFFFFFFF);
77       Count = (unsigned int) rrt & 0xFFFFFFFF;
78       debug_count -= Count;
79       break;
80     case 10:   // EntryHi
81       EntryHi = (unsigned int) rrt & 0xFFFFE0FF;
82       break;
83     case 11:   // Compare
84       update_count();
85       remove_event(COMPARE_INT);
86       add_interupt_event_count(COMPARE_INT, (unsigned int)rrt);
87       Compare = (unsigned int) rrt;
88       Cause = Cause & 0xFFFF7FFF; //Timer interupt is clear
89       break;
90     case 12:   // Status
91       if((rrt & 0x04000000) != (Status & 0x04000000))
92       {
93           shuffle_fpr_data(Status, (unsigned int) rrt);
94           set_fpr_pointers((unsigned int) rrt);
95       }
96       Status = (unsigned int) rrt;
97       update_count();
98       ADD_TO_PC(1);
99       check_interupt();
100       interupt_unsafe_state = 1;
101       if (next_interupt <= Count) gen_interupt();
102       interupt_unsafe_state = 0;
103       ADD_TO_PC(-1);
104       break;
105     case 13:   // Cause
106       if (rrt!=0)
107       {
108          DebugMessage(M64MSG_ERROR, "MTC0 instruction trying to write Cause register with non-0 value");
109          stop = 1;
110       }
111       else Cause = (unsigned int) rrt;
112       break;
113     case 14:   // EPC
114       EPC = (unsigned int) rrt;
115       break;
116     case 15:  // PRevID
117       break;
118     case 16:  // Config
119       Config = (unsigned int) rrt;
120       break;
121     case 18:  // WatchLo
122       WatchLo = (unsigned int) rrt & 0xFFFFFFFF;
123       break;
124     case 19:  // WatchHi
125       WatchHi = (unsigned int) rrt & 0xFFFFFFFF;
126       break;
127     case 27:  // CacheErr
128       break;
129     case 28:  // TagLo
130       TagLo = (unsigned int) rrt & 0x0FFFFFC0;
131       break;
132     case 29: // TagHi
133       TagHi =0;
134       break;
135     default:
136       DebugMessage(M64MSG_ERROR, "Unknown MTC0 write: %d", PC->f.r.nrd);
137       stop=1;
138   }
139   ADD_TO_PC(1);
140 }