1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  *   Mupen64plus - cp0.h                                                   *
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 #ifndef M64P_R4300_CP0_H
23 #define M64P_R4300_CP0_H
24 
25 #include <stdint.h>
26 
27 enum
28 {
29     CP0_STATUS_IE   = 0x00000001,
30     CP0_STATUS_EXL  = 0x00000002,
31     CP0_STATUS_ERL  = 0x00000004,
32     /* Execution modes */
33     CP0_STATUS_MODE_K    = 0   << 3,
34     CP0_STATUS_MODE_S    = 1   << 3,
35     CP0_STATUS_MODE_U    = 2   << 3,
36     CP0_STATUS_MODE_MASK = 0x3 << 3,
37 
38     CP0_STATUS_UX   = 0x00000020,
39     CP0_STATUS_SX   = 0x00000040,
40     CP0_STATUS_KX   = 0x00000080,
41     CP0_STATUS_IM0  = 0x00000100,
42     CP0_STATUS_IM1  = 0x00000200,
43     CP0_STATUS_IM2  = 0x00000400,
44     CP0_STATUS_IM3  = 0x00000800,
45     CP0_STATUS_IM4  = 0x00001000,
46     CP0_STATUS_IM5  = 0x00002000,
47     CP0_STATUS_IM6  = 0x00004000,
48     CP0_STATUS_IM7  = 0x00008000,
49     /* bit 16 and 17 are left for compatibility */
50     CP0_STATUS_CH   = 0x00040000,
51     /* bit 19 is zero */
52     CP0_STATUS_SR   = 0x00100000,
53     CP0_STATUS_TS   = 0x00200000,
54     CP0_STATUS_BEV  = 0x00400000,
55     CP0_STATUS_RSVD = 0x00800000,
56     CP0_STATUS_ITS  = 0x01000000,
57     CP0_STATUS_RE   = 0x02000000,
58     CP0_STATUS_FR   = 0x04000000,
59     CP0_STATUS_RP   = 0x08000000,
60     CP0_STATUS_CU0  = 0x10000000,
61     CP0_STATUS_CU1  = 0x20000000,
62     CP0_STATUS_CU2  = 0x40000000,
63     CP0_STATUS_CU3  = 0x80000000,
64 };
65 
66 enum
67 {
68     /* Execution Codes */
69     CP0_CAUSE_EXCCODE_INT   = 0    << 2,
70     CP0_CAUSE_EXCCODE_MOD   = 1    << 2,
71     CP0_CAUSE_EXCCODE_TLBL  = 2    << 2,
72     CP0_CAUSE_EXCCODE_TLBS  = 3    << 2,
73     CP0_CAUSE_EXCCODE_ADEL  = 4    << 2,
74     CP0_CAUSE_EXCCODE_ADES  = 5    << 2,
75     CP0_CAUSE_EXCCODE_IBE   = 6    << 2,
76     CP0_CAUSE_EXCCODE_DBE   = 7    << 2,
77     CP0_CAUSE_EXCCODE_SYS   = 8    << 2,
78     CP0_CAUSE_EXCCODE_BP    = 9    << 2,
79     CP0_CAUSE_EXCCODE_RI    = 10   << 2,
80     CP0_CAUSE_EXCCODE_CPU   = 11   << 2,
81     CP0_CAUSE_EXCCODE_OV    = 12   << 2,
82     CP0_CAUSE_EXCCODE_TR    = 13   << 2,
83     /* 14 is reserved */
84     CP0_CAUSE_EXCCODE_FPE   = 15   << 2,
85     /* 16-22 are reserved */
86     CP0_CAUSE_EXCCODE_WATCH = 23   << 2,
87     /* 24-31 are reserved */
88     CP0_CAUSE_EXCCODE_MASK  = 0x1f << 2,
89 
90     /* Interrupt Pending */
91     CP0_CAUSE_IP0  = 0x00000100,
92     CP0_CAUSE_IP1  = 0x00000200,
93     CP0_CAUSE_IP2  = 0x00000400,
94     CP0_CAUSE_IP3  = 0x00000800,
95     CP0_CAUSE_IP4  = 0x00001000,
96     CP0_CAUSE_IP5  = 0x00002000,
97     CP0_CAUSE_IP6  = 0x00004000,
98     CP0_CAUSE_IP7  = 0x00008000,
99 
100     CP0_CAUSE_CE1 = 0x10000000,
101     CP0_CAUSE_BD  = 0x80000000,
102 };
103 
104 enum r4300_cp0_registers
105 {
106     CP0_INDEX_REG,
107     CP0_RANDOM_REG,
108     CP0_ENTRYLO0_REG,
109     CP0_ENTRYLO1_REG,
110     CP0_CONTEXT_REG,
111     CP0_PAGEMASK_REG,
112     CP0_WIRED_REG,
113     /* 7 is unused */
114     CP0_BADVADDR_REG = 8,
115     CP0_COUNT_REG,
116     CP0_ENTRYHI_REG,
117     CP0_COMPARE_REG,
118     CP0_STATUS_REG,
119     CP0_CAUSE_REG,
120     CP0_EPC_REG,
121     CP0_PREVID_REG,
122     CP0_CONFIG_REG,
123     CP0_LLADDR_REG,
124     CP0_WATCHLO_REG,
125     CP0_WATCHHI_REG,
126     CP0_XCONTEXT_REG,
127     /* 21 - 27 are unused */
128     CP0_TAGLO_REG = 28,
129     CP0_TAGHI_REG,
130     CP0_ERROREPC_REG,
131     /* 31 is unused */
132     CP0_REGS_COUNT = 32
133 };
134 
135 void init_cp0(unsigned int _count_per_op);
136 
137 void poweron_cp0(void);
138 
139 uint32_t* r4300_cp0_regs(void);
140 
141 void cp0_update_count(void);
142 
143 #endif /* M64P_R4300_CP0_H */
144 
145