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; |
451ab91e |
75 | translate_event_queue((unsigned int) rrt & 0xFFFFFFFF); |
76 | Count = (unsigned int) rrt & 0xFFFFFFFF; |
451ab91e |
77 | break; |
78 | case 10: // EntryHi |
79 | EntryHi = (unsigned int) rrt & 0xFFFFE0FF; |
80 | break; |
81 | case 11: // Compare |
82 | update_count(); |
83 | remove_event(COMPARE_INT); |
84 | add_interupt_event_count(COMPARE_INT, (unsigned int)rrt); |
85 | Compare = (unsigned int) rrt; |
86 | Cause = Cause & 0xFFFF7FFF; //Timer interupt is clear |
87 | break; |
88 | case 12: // Status |
89 | if((rrt & 0x04000000) != (Status & 0x04000000)) |
90 | { |
91 | shuffle_fpr_data(Status, (unsigned int) rrt); |
92 | set_fpr_pointers((unsigned int) rrt); |
93 | } |
94 | Status = (unsigned int) rrt; |
95 | update_count(); |
96 | ADD_TO_PC(1); |
97 | check_interupt(); |
98 | interupt_unsafe_state = 1; |
99 | if (next_interupt <= Count) gen_interupt(); |
100 | interupt_unsafe_state = 0; |
101 | ADD_TO_PC(-1); |
102 | break; |
103 | case 13: // Cause |
104 | if (rrt!=0) |
105 | { |
106 | DebugMessage(M64MSG_ERROR, "MTC0 instruction trying to write Cause register with non-0 value"); |
107 | stop = 1; |
108 | } |
109 | else Cause = (unsigned int) rrt; |
110 | break; |
111 | case 14: // EPC |
112 | EPC = (unsigned int) rrt; |
113 | break; |
114 | case 15: // PRevID |
115 | break; |
116 | case 16: // Config |
117 | Config = (unsigned int) rrt; |
118 | break; |
119 | case 18: // WatchLo |
120 | WatchLo = (unsigned int) rrt & 0xFFFFFFFF; |
121 | break; |
122 | case 19: // WatchHi |
123 | WatchHi = (unsigned int) rrt & 0xFFFFFFFF; |
124 | break; |
125 | case 27: // CacheErr |
126 | break; |
127 | case 28: // TagLo |
128 | TagLo = (unsigned int) rrt & 0x0FFFFFC0; |
129 | break; |
130 | case 29: // TagHi |
131 | TagHi =0; |
132 | break; |
133 | default: |
134 | DebugMessage(M64MSG_ERROR, "Unknown MTC0 write: %d", PC->f.r.nrd); |
135 | stop=1; |
136 | } |
137 | ADD_TO_PC(1); |
138 | } |