451ab91e |
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 | } |