Browse code

update for C++17 compliance, update to latest 2sf, add WINE cross-compile makefiles

Adam Higerd authored on 2021/02/11 15:36:17
Showing 1 changed files
... ...
@@ -24,7 +24,7 @@ armcp15_t cp15;
24 24
 
25 25
 bool armcp15_t::reset(armcpu_t *c)
26 26
 {
27
-	//printf("CP15 Reset\n");
27
+	//fprintf(stderr, "CP15 Reset\n");
28 28
 	this->cpu = c;
29 29
 	this->IDCode = 0x41059461;
30 30
 	this->cacheType = 0x0F0D2112;
... ...
@@ -225,7 +225,7 @@ bool armcp15_t::moveCP2ARM(uint32_t *R, uint8_t CRn, uint8_t CRm, uint8_t opcode
225 225
 {
226 226
 	if (!this->cpu)
227 227
 	{
228
-		printf("ERROR: cp15 don\'t allocated\n");
228
+		fprintf(stderr, "ERROR: cp15 don\'t allocated\n");
229 229
 		return false;
230 230
 	}
231 231
 	if (this->cpu->CPSR.bits.mode == USR)
... ...
@@ -371,7 +371,7 @@ bool armcp15_t::moveARM2CP(uint32_t val, uint8_t CRn, uint8_t CRm, uint8_t opcod
371 371
 {
372 372
 	if (!this->cpu)
373 373
 	{
374
-		printf("ERROR: cp15 don\'t allocated\n");
374
+		fprintf(stderr, "ERROR: cp15 don\'t allocated\n");
375 375
 		return false;
376 376
 	}
377 377
 	if (this->cpu->CPSR.bits.mode == USR)
Browse code

* Fixes for gcc and clang (while they can compile the code, the DLLs made aren't functional, but oh well).

* [2SF] Used more up-to-date asmjit, despite the ugly looking code.

Naram Qashat authored on 2014/09/17 19:51:45
Showing 1 changed files
... ...
@@ -274,7 +274,7 @@ bool armcp15_t::moveCP2ARM(uint32_t *R, uint8_t CRn, uint8_t CRm, uint8_t opcode
274 274
 			}
275 275
 			return false;
276 276
 		case 3:
277
-			if (!opcode1 && ~opcode2 && !CRm)
277
+			if (!opcode1 && ~static_cast<int8_t>(opcode2) && !CRm)
278 278
 			{
279 279
 				*R = this->writeBuffCtrl;
280 280
 				return true;
Browse code

Removed a bunch of casts, they seem to be fine without them in most cases.

Naram Qashat authored on 2013/04/18 23:22:54
Showing 1 changed files
... ...
@@ -384,7 +384,7 @@ bool armcp15_t::moveARM2CP(uint32_t val, uint8_t CRn, uint8_t CRm, uint8_t opcod
384 384
 			{
385 385
 				// On the NDS bit0,2,7,12..19 are R/W, Bit3..6 are always set, all other bits are always zero.
386 386
 				this->ctrl = (val & 0x000FF085) | 0x00000078;
387
-				MMU.ARM9_RW_MODE = static_cast<uint8_t>(BIT7(val));
387
+				MMU.ARM9_RW_MODE = BIT7(val);
388 388
 				// zero 31-jan-2010: change from 0x0FFF0000 to 0xFFFF0000 per gbatek
389 389
 				this->cpu->intVector = 0xFFFF0000 * BIT13(val);
390 390
 				this->cpu->LDTBit = !BIT15(val); // TBit
Browse code

Updating in_2sf to use a newish version of DeSmuME, 0.9.9 from SVN. Somewhat cleaned up as well, but not everything because it's a pain in the ass.

Naram Qashat authored on 2013/04/18 17:22:55
Showing 1 changed files
... ...
@@ -17,81 +17,75 @@
17 17
 */
18 18
 
19 19
 #include <cstdlib>
20
-
21 20
 #include "cp15.h"
22
-//#include "debug.h"
23 21
 #include "MMU.h"
24 22
 
25
-armcp15_t *armcp15_new(armcpu_t * c)
26
-{
27
-	int i;
28
-	armcp15_t *armcp15 = (armcp15_t*)malloc(sizeof(armcp15_t));
29
-	if(!armcp15) return NULL;
30
-
23
+armcp15_t cp15;
31 24
 
32
-	armcp15->cpu = c;
33
-	armcp15->IDCode = 0x41059461;
34
-	armcp15->cacheType = 0x0F0D2112;
35
-	armcp15->TCMSize = 0x00140180;
36
-	armcp15->ctrl = 0x00012078;
37
-	armcp15->DCConfig = 0x0;
38
-	armcp15->ICConfig = 0x0;
39
-	armcp15->writeBuffCtrl = 0x0;
40
-	armcp15->und = 0x0;
41
-	armcp15->DaccessPerm = 0x22222222;
42
-	armcp15->IaccessPerm = 0x22222222;
43
-	armcp15->protectBaseSize0 = 0x0;
44
-	armcp15->protectBaseSize1 = 0x0;
45
-	armcp15->protectBaseSize2 = 0x0;
46
-	armcp15->protectBaseSize3 = 0x0;
47
-	armcp15->protectBaseSize4 = 0x0;
48
-	armcp15->protectBaseSize5 = 0x0;
49
-	armcp15->protectBaseSize6 = 0x0;
50
-	armcp15->protectBaseSize7 = 0x0;
51
-	armcp15->cacheOp = 0x0;
52
-	armcp15->DcacheLock = 0x0;
53
-	armcp15->IcacheLock = 0x0;
54
-	armcp15->ITCMRegion = 0x0C;
55
-	armcp15->DTCMRegion = 0x0080000A;
56
-	armcp15->processID = 0;
25
+bool armcp15_t::reset(armcpu_t *c)
26
+{
27
+	//printf("CP15 Reset\n");
28
+	this->cpu = c;
29
+	this->IDCode = 0x41059461;
30
+	this->cacheType = 0x0F0D2112;
31
+	this->TCMSize = 0x00140180;
32
+	this->ctrl = 0x00012078;
33
+	this->DCConfig = 0x0;
34
+	this->ICConfig = 0x0;
35
+	this->writeBuffCtrl = 0x0;
36
+	this->und = 0x0;
37
+	this->DaccessPerm = 0x22222222;
38
+	this->IaccessPerm = 0x22222222;
39
+	this->protectBaseSize0 = 0x0;
40
+	this->protectBaseSize1 = 0x0;
41
+	this->protectBaseSize2 = 0x0;
42
+	this->protectBaseSize3 = 0x0;
43
+	this->protectBaseSize4 = 0x0;
44
+	this->protectBaseSize5 = 0x0;
45
+	this->protectBaseSize6 = 0x0;
46
+	this->protectBaseSize7 = 0x0;
47
+	this->cacheOp = 0x0;
48
+	this->DcacheLock = 0x0;
49
+	this->IcacheLock = 0x0;
50
+	this->ITCMRegion = 0x0C;
51
+	this->DTCMRegion = 0x0080000A;
52
+	this->processID = 0;
57 53
 
58
-	MMU.ARM9_RW_MODE = static_cast<uint8_t>(BIT7(armcp15->ctrl));
59
-	armcp15->cpu->intVector = 0xFFFF0000 * (BIT13(armcp15->ctrl));
60
-	armcp15->cpu->LDTBit = !BIT15(armcp15->ctrl); //TBit
54
+	MMU.ARM9_RW_MODE = BIT7(this->ctrl);
55
+	this->cpu->intVector = 0xFFFF0000 * BIT13(this->ctrl);
56
+	this->cpu->LDTBit = !BIT15(this->ctrl); // TBit
61 57
 
62 58
 	/* preset calculated regionmasks */
63
-	for (i=0;i<8;i++) {
64
-		armcp15->regionWriteMask_USR[i] = 0 ;
65
-		armcp15->regionWriteMask_SYS[i] = 0 ;
66
-		armcp15->regionReadMask_USR[i] = 0 ;
67
-		armcp15->regionReadMask_SYS[i] = 0 ;
68
-		armcp15->regionExecuteMask_USR[i] = 0 ;
69
-		armcp15->regionExecuteMask_SYS[i] = 0 ;
70
-		armcp15->regionWriteSet_USR[i] = 0 ;
71
-		armcp15->regionWriteSet_SYS[i] = 0 ;
72
-		armcp15->regionReadSet_USR[i] = 0 ;
73
-		armcp15->regionReadSet_SYS[i] = 0 ;
74
-		armcp15->regionExecuteSet_USR[i] = 0 ;
75
-		armcp15->regionExecuteSet_SYS[i] = 0 ;
76
-	} ;
59
+	for (uint8_t i = 0; i < 8; ++i)
60
+	{
61
+		this->regionWriteMask_USR[i] = 0;
62
+		this->regionWriteMask_SYS[i] = 0;
63
+		this->regionReadMask_USR[i] = 0;
64
+		this->regionReadMask_SYS[i] = 0;
65
+		this->regionExecuteMask_USR[i] = 0;
66
+		this->regionExecuteMask_SYS[i] = 0;
67
+		this->regionWriteSet_USR[i] = 0;
68
+		this->regionWriteSet_SYS[i] = 0;
69
+		this->regionReadSet_USR[i] = 0;
70
+		this->regionReadSet_SYS[i] = 0;
71
+		this->regionExecuteSet_USR[i] = 0;
72
+		this->regionExecuteSet_SYS[i] = 0;
73
+	}
77 74
 
78
-	return armcp15;
75
+	return true;
79 76
 }
80 77
 
81
-//#define ACCESSTYPE(val,n)   (((val) >> (4*n)) & 0x0F)
82 78
 static inline uint32_t ACCESSTYPE(uint32_t val, unsigned char n) { return (val >> (4 * n)) & 0x0F; }
83
-//#define SIZEIDENTIFIER(val) ((((val) >> 1) & 0x1F))
84 79
 static inline uint32_t SIZEIDENTIFIER(uint32_t val) { return (val >> 1) & 0x1F; }
85
-//#define SIZEBINARY(val)     (1 << (SIZEIDENTIFIER(val)+1))
86 80
 static inline uint32_t SIZEBINARY(uint32_t val) { return 1 << (SIZEIDENTIFIER(val) + 1); }
87
-//#define MASKFROMREG(val)    (~((SIZEBINARY(val)-1) | 0x3F))
88 81
 static inline uint32_t MASKFROMREG(uint32_t val) { return ~((SIZEBINARY(val) - 1) | 0x3F); }
89
-//#define SETFROMREG(val)     ((val) & MASKFROMREG(val))
90 82
 static inline uint32_t SETFROMREG(uint32_t val) { return val & MASKFROMREG(val); }
91 83
 /* sets the precalculated regions to mask,set for the affected accesstypes */
92
-static void armcp15_setSingleRegionAccess(armcp15_t *armcp15,uint32_t dAccess,uint32_t iAccess,unsigned char num, uint32_t mask,uint32_t set) {
84
+void armcp15_t::setSingleRegionAccess(uint32_t dAccess, uint32_t iAccess, unsigned char num, uint32_t mask, uint32_t set)
85
+{
93 86
 
94
-	switch (ACCESSTYPE(dAccess,num)) {
87
+	switch (ACCESSTYPE(dAccess, num))
88
+	{
95 89
 		case 4: /* UNP */
96 90
 		case 7: /* UNP */
97 91
 		case 8: /* UNP */
... ...
@@ -103,67 +97,67 @@ static void armcp15_setSingleRegionAccess(armcp15_t *armcp15,uint32_t dAccess,ui
103 97
 		case 14: /* UNP */
104 98
 		case 15: /* UNP */
105 99
 		case 0: /* no access at all */
106
-			armcp15->regionWriteMask_USR[num] = 0 ;
107
-			armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
108
-			armcp15->regionReadMask_USR[num] = 0 ;
109
-			armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ;
110
-			armcp15->regionWriteMask_SYS[num] = 0 ;
111
-			armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ;
112
-			armcp15->regionReadMask_SYS[num] = 0 ;
113
-			armcp15->regionReadSet_SYS[num] = 0xFFFFFFFF ;
114
-			break ;
100
+			this->regionWriteMask_USR[num] = 0;
101
+			this->regionWriteSet_USR[num] = 0xFFFFFFFF;
102
+			this->regionReadMask_USR[num] = 0;
103
+			this->regionReadSet_USR[num] = 0xFFFFFFFF;
104
+			this->regionWriteMask_SYS[num] = 0;
105
+			this->regionWriteSet_SYS[num] = 0xFFFFFFFF;
106
+			this->regionReadMask_SYS[num] = 0;
107
+			this->regionReadSet_SYS[num] = 0xFFFFFFFF;
108
+			break;
115 109
 		case 1: /* no access at USR, all to sys */
116
-			armcp15->regionWriteMask_USR[num] = 0 ;
117
-			armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
118
-			armcp15->regionReadMask_USR[num] = 0 ;
119
-			armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ;
120
-			armcp15->regionWriteMask_SYS[num] = mask ;
121
-			armcp15->regionWriteSet_SYS[num] = set ;
122
-			armcp15->regionReadMask_SYS[num] = mask ;
123
-			armcp15->regionReadSet_SYS[num] = set ;
124
-			break ;
110
+			this->regionWriteMask_USR[num] = 0;
111
+			this->regionWriteSet_USR[num] = 0xFFFFFFFF;
112
+			this->regionReadMask_USR[num] = 0;
113
+			this->regionReadSet_USR[num] = 0xFFFFFFFF;
114
+			this->regionWriteMask_SYS[num] = mask;
115
+			this->regionWriteSet_SYS[num] = set;
116
+			this->regionReadMask_SYS[num] = mask;
117
+			this->regionReadSet_SYS[num] = set;
118
+			break;
125 119
 		case 2: /* read at USR, all to sys */
126
-			armcp15->regionWriteMask_USR[num] = 0 ;
127
-			armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
128
-			armcp15->regionReadMask_USR[num] = mask ;
129
-			armcp15->regionReadSet_USR[num] = set ;
130
-			armcp15->regionWriteMask_SYS[num] = mask ;
131
-			armcp15->regionWriteSet_SYS[num] = set ;
132
-			armcp15->regionReadMask_SYS[num] = mask ;
133
-			armcp15->regionReadSet_SYS[num] = set ;
134
-			break ;
120
+			this->regionWriteMask_USR[num] = 0;
121
+			this->regionWriteSet_USR[num] = 0xFFFFFFFF;
122
+			this->regionReadMask_USR[num] = mask;
123
+			this->regionReadSet_USR[num] = set;
124
+			this->regionWriteMask_SYS[num] = mask;
125
+			this->regionWriteSet_SYS[num] = set;
126
+			this->regionReadMask_SYS[num] = mask;
127
+			this->regionReadSet_SYS[num] = set;
128
+			break;
135 129
 		case 3: /* all to USR, all to sys */
136
-			armcp15->regionWriteMask_USR[num] = mask ;
137
-			armcp15->regionWriteSet_USR[num] = set ;
138
-			armcp15->regionReadMask_USR[num] = mask ;
139
-			armcp15->regionReadSet_USR[num] = set ;
140
-			armcp15->regionWriteMask_SYS[num] = mask ;
141
-			armcp15->regionWriteSet_SYS[num] = set ;
142
-			armcp15->regionReadMask_SYS[num] = mask ;
143
-			armcp15->regionReadSet_SYS[num] = set ;
144
-			break ;
130
+			this->regionWriteMask_USR[num] = mask;
131
+			this->regionWriteSet_USR[num] = set;
132
+			this->regionReadMask_USR[num] = mask;
133
+			this->regionReadSet_USR[num] = set;
134
+			this->regionWriteMask_SYS[num] = mask;
135
+			this->regionWriteSet_SYS[num] = set;
136
+			this->regionReadMask_SYS[num] = mask;
137
+			this->regionReadSet_SYS[num] = set;
138
+			break;
145 139
 		case 5: /* no access at USR, read to sys */
146
-			armcp15->regionWriteMask_USR[num] = 0 ;
147
-			armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
148
-			armcp15->regionReadMask_USR[num] = 0 ;
149
-			armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ;
150
-			armcp15->regionWriteMask_SYS[num] = 0 ;
151
-			armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ;
152
-			armcp15->regionReadMask_SYS[num] = mask ;
153
-			armcp15->regionReadSet_SYS[num] = set ;
154
-			break ;
140
+			this->regionWriteMask_USR[num] = 0;
141
+			this->regionWriteSet_USR[num] = 0xFFFFFFFF;
142
+			this->regionReadMask_USR[num] = 0;
143
+			this->regionReadSet_USR[num] = 0xFFFFFFFF;
144
+			this->regionWriteMask_SYS[num] = 0;
145
+			this->regionWriteSet_SYS[num] = 0xFFFFFFFF;
146
+			this->regionReadMask_SYS[num] = mask;
147
+			this->regionReadSet_SYS[num] = set;
148
+			break;
155 149
 		case 6: /* read at USR, read to sys */
156
-			armcp15->regionWriteMask_USR[num] = 0 ;
157
-			armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
158
-			armcp15->regionReadMask_USR[num] = mask ;
159
-			armcp15->regionReadSet_USR[num] = set ;
160
-			armcp15->regionWriteMask_SYS[num] = 0 ;
161
-			armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ;
162
-			armcp15->regionReadMask_SYS[num] = mask ;
163
-			armcp15->regionReadSet_SYS[num] = set ;
164
-			break ;
150
+			this->regionWriteMask_USR[num] = 0;
151
+			this->regionWriteSet_USR[num] = 0xFFFFFFFF;
152
+			this->regionReadMask_USR[num] = mask;
153
+			this->regionReadSet_USR[num] = set;
154
+			this->regionWriteMask_SYS[num] = 0;
155
+			this->regionWriteSet_SYS[num] = 0xFFFFFFFF;
156
+			this->regionReadMask_SYS[num] = mask;
157
+			this->regionReadSet_SYS[num] = set;
165 158
 	}
166
-	switch (ACCESSTYPE(iAccess,num)) {
159
+	switch (ACCESSTYPE(iAccess, num))
160
+	{
167 161
 		case 4: /* UNP */
168 162
 		case 7: /* UNP */
169 163
 		case 8: /* UNP */
... ...
@@ -175,400 +169,386 @@ static void armcp15_setSingleRegionAccess(armcp15_t *armcp15,uint32_t dAccess,ui
175 169
 		case 14: /* UNP */
176 170
 		case 15: /* UNP */
177 171
 		case 0: /* no access at all */
178
-			armcp15->regionExecuteMask_USR[num] = 0 ;
179
-			armcp15->regionExecuteSet_USR[num] = 0xFFFFFFFF ;
180
-			armcp15->regionExecuteMask_SYS[num] = 0 ;
181
-			armcp15->regionExecuteSet_SYS[num] = 0xFFFFFFFF ;
182
-			break ;
172
+			this->regionExecuteMask_USR[num] = 0;
173
+			this->regionExecuteSet_USR[num] = 0xFFFFFFFF;
174
+			this->regionExecuteMask_SYS[num] = 0;
175
+			this->regionExecuteSet_SYS[num] = 0xFFFFFFFF;
176
+			break;
183 177
 		case 1:
184
-			armcp15->regionExecuteMask_USR[num] = 0 ;
185
-			armcp15->regionExecuteSet_USR[num] = 0xFFFFFFFF ;
186
-			armcp15->regionExecuteMask_SYS[num] = mask ;
187
-			armcp15->regionExecuteSet_SYS[num] = set ;
188
-			break ;
178
+			this->regionExecuteMask_USR[num] = 0;
179
+			this->regionExecuteSet_USR[num] = 0xFFFFFFFF;
180
+			this->regionExecuteMask_SYS[num] = mask;
181
+			this->regionExecuteSet_SYS[num] = set;
182
+			break;
189 183
 		case 2:
190 184
 		case 3:
191 185
 		case 6:
192
-			armcp15->regionExecuteMask_USR[num] = mask ;
193
-			armcp15->regionExecuteSet_USR[num] = set ;
194
-			armcp15->regionExecuteMask_SYS[num] = mask ;
195
-			armcp15->regionExecuteSet_SYS[num] = set ;
196
-			break ;
186
+			this->regionExecuteMask_USR[num] = mask;
187
+			this->regionExecuteSet_USR[num] = set;
188
+			this->regionExecuteMask_SYS[num] = mask;
189
+			this->regionExecuteSet_SYS[num] = set;
197 190
 	}
198 191
 }
199 192
 
200 193
 /* precalculate region masks/sets from cp15 register */
201
-static void armcp15_maskPrecalc(armcp15_t *armcp15)
194
+void armcp15_t::maskPrecalc()
202 195
 {
203
-#define precalc(num) {  \
204
-	uint32_t mask = 0, set = 0xFFFFFFFF ; /* (x & 0) == 0xFF..FF is allways false (disabled) */  \
205
-	if (BIT_N(armcp15->protectBaseSize##num,0)) /* if region is enabled */ \
206
-	{    /* reason for this define: naming includes var */  \
207
-	mask = MASKFROMREG(armcp15->protectBaseSize##num) ;   \
208
-	set = SETFROMREG(armcp15->protectBaseSize##num) ; \
209
-	if (SIZEIDENTIFIER(armcp15->protectBaseSize##num)==0x1F)  \
210
-	{   /* for the 4GB region, uint32_t suffers wraparound */   \
211
-	mask = 0 ; set = 0 ;   /* (x & 0) == 0  is allways true (enabled) */  \
212
-} \
213
-}  \
214
-	armcp15_setSingleRegionAccess(armcp15,armcp15->DaccessPerm,armcp15->IaccessPerm,num,mask,set) ;  \
196
+#define precalc(num) \
197
+{ \
198
+	uint32_t mask = 0, set = 0xFFFFFFFF; /* (x & 0) == 0xFF..FF is allways false (disabled) */ \
199
+	if (BIT_N(this->protectBaseSize##num, 0)) /* if region is enabled */ \
200
+	{ \
201
+		/* reason for this define: naming includes var */ \
202
+		mask = MASKFROMREG(this->protectBaseSize##num); \
203
+		set = SETFROMREG(this->protectBaseSize##num); \
204
+		if (SIZEIDENTIFIER(this->protectBaseSize##num) == 0x1F) \
205
+		{ \
206
+			/* for the 4GB region, u32 suffers wraparound */ \
207
+			mask = 0; \
208
+			set = 0; /* (x & 0) == 0  is allways true (enabled) */ \
209
+		} \
210
+	} \
211
+	this->setSingleRegionAccess(this->DaccessPerm, this->IaccessPerm, num, mask, set); \
215 212
 }
216
-	precalc(0) ;
217
-	precalc(1) ;
218
-	precalc(2) ;
219
-	precalc(3) ;
220
-	precalc(4) ;
221
-	precalc(5) ;
222
-	precalc(6) ;
223
-	precalc(7) ;
213
+	precalc(0);
214
+	precalc(1);
215
+	precalc(2);
216
+	precalc(3);
217
+	precalc(4);
218
+	precalc(5);
219
+	precalc(6);
220
+	precalc(7);
221
+#undef precalc
224 222
 }
225 223
 
226
-/*bool armcp15_isAccessAllowed(armcp15_t *armcp15,uint32_t address,uint32_t access)
227
-{
228
-	int i ;
229
-	if (!(armcp15->ctrl & 1)) return true ;*/        /* protection checking is not enabled */
230
-	/*for (i=0;i<8;i++) {
231
-		switch (access) {
232
-		case CP15_ACCESS_WRITEUSR:
233
-			if ((address & armcp15->regionWriteMask_USR[i]) == armcp15->regionWriteSet_USR[i]) return true ;
234
-			break ;
235
-		case CP15_ACCESS_WRITESYS:
236
-			if ((address & armcp15->regionWriteMask_SYS[i]) == armcp15->regionWriteSet_SYS[i]) return true ;
237
-			break ;
238
-		case CP15_ACCESS_READUSR:
239
-			if ((address & armcp15->regionReadMask_USR[i]) == armcp15->regionReadSet_USR[i]) return true ;
240
-			break ;
241
-		case CP15_ACCESS_READSYS:
242
-			if ((address & armcp15->regionReadMask_SYS[i]) == armcp15->regionReadSet_SYS[i]) return true ;
243
-			break ;
244
-		case CP15_ACCESS_EXECUSR:
245
-			if ((address & armcp15->regionExecuteMask_USR[i]) == armcp15->regionExecuteSet_USR[i]) return true ;
246
-			break ;
247
-		case CP15_ACCESS_EXECSYS:
248
-			if ((address & armcp15->regionExecuteMask_SYS[i]) == armcp15->regionExecuteSet_SYS[i]) return true ;
249
-			break ;
250
-		}
251
-	}*/
252
-	/* when protections are enabled, but no region allows access, deny access */
253
-	/*return false ;
254
-}*/
255
-
256
-/*bool armcp15_dataProcess(armcp15_t *, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t)
257
-{
258
-	//LOG("Unsupported CP15 operation : DataProcess\n");
259
-	return false;
260
-}*/
261
-
262
-/*bool armcp15_load(armcp15_t *, uint8_t, uint8_t)
224
+bool armcp15_t::moveCP2ARM(uint32_t *R, uint8_t CRn, uint8_t CRm, uint8_t opcode1, uint8_t opcode2)
263 225
 {
264
-	//LOG("Unsupported CP15 operation : Load\n");
265
-	return false;
266
-}*/
267
-
268
-/*bool armcp15_store(armcp15_t *, uint8_t, uint8_t)
269
-{
270
-	//LOG("Unsupported CP15 operation : Store\n");
271
-	return false;
272
-}*/
273
-
274
-bool armcp15_moveCP2ARM(armcp15_t *armcp15, uint32_t * R, uint8_t CRn, uint8_t CRm, uint8_t opcode1, uint8_t opcode2)
275
-{
276
-	if(armcp15->cpu->CPSR.bits.mode == USR) return false;
277
-
278
-	switch(CRn)
226
+	if (!this->cpu)
279 227
 	{
280
-	case 0:
281
-		if((opcode1 == 0)&&(CRm==0))
282
-		{
283
-			switch(opcode2)
284
-			{
285
-			case 1:
286
-				*R = armcp15->cacheType;
287
-				return true;
288
-			case 2:
289
-				*R = armcp15->TCMSize;
290
-				return true;
291
-			default:
292
-				*R = armcp15->IDCode;
293
-				return true;
294
-			}
295
-		}
228
+		printf("ERROR: cp15 don\'t allocated\n");
296 229
 		return false;
297
-	case 1:
298
-		if((opcode1==0) && (opcode2==0) && (CRm==0))
299
-		{
300
-			*R = armcp15->ctrl;
301
-			//LOG("CP15: CPtoARM ctrl %08X\n", armcp15->ctrl);
302
-			return true;
303
-		}
230
+	}
231
+	if (this->cpu->CPSR.bits.mode == USR)
304 232
 		return false;
305 233
 
306
-	case 2:
307
-		if((opcode1==0) && (CRm==0))
308
-		{
309
-			switch(opcode2)
234
+	switch (CRn)
235
+	{
236
+		case 0:
237
+			if (!opcode1 && !CRm)
310 238
 			{
311
-			case 0:
312
-				*R = armcp15->DCConfig;
313
-				return true;
314
-			case 1:
315
-				*R = armcp15->ICConfig;
316
-				return true;
317
-			default:
318
-				return false;
239
+				switch (opcode2)
240
+				{
241
+					case 1:
242
+						*R = this->cacheType;
243
+						return true;
244
+					case 2:
245
+						*R = this->TCMSize;
246
+						return true;
247
+					default:
248
+						*R = this->IDCode;
249
+						return true;
250
+				}
319 251
 			}
320
-		}
321
-		return false;
322
-	case 3:
323
-		if((opcode1==0) && (opcode2==0) && (CRm==0))
324
-		{
325
-			*R = armcp15->writeBuffCtrl;
326
-			//LOG("CP15: CPtoARM writeBuffer ctrl %08X\n", armcp15->writeBuffCtrl);
327
-			return true;
328
-		}
329
-		return false;
330
-	case 5:
331
-		if((opcode1==0) && (CRm==0))
332
-		{
333
-			switch(opcode2)
252
+			return false;
253
+		case 1:
254
+			if (!opcode1 && !opcode2 && !CRm)
334 255
 			{
335
-			case 2:
336
-				*R = armcp15->DaccessPerm;
337
-				return true;
338
-			case 3:
339
-				*R = armcp15->IaccessPerm;
256
+				*R = this->ctrl;
340 257
 				return true;
341
-			default:
342
-				return false;
343 258
 			}
344
-		}
345
-		return false;
346
-	case 6:
347
-		if((opcode1==0) && (opcode2==0))
348
-		{
349
-			switch(CRm)
259
+			return false;
260
+		case 2:
261
+			if (!opcode1 && !CRm)
350 262
 			{
351
-			case 0:
352
-				*R = armcp15->protectBaseSize0;
353
-				return true;
354
-			case 1:
355
-				*R = armcp15->protectBaseSize1;
356
-				return true;
357
-			case 2:
358
-				*R = armcp15->protectBaseSize2;
359
-				return true;
360
-			case 3:
361
-				*R = armcp15->protectBaseSize3;
362
-				return true;
363
-			case 4:
364
-				*R = armcp15->protectBaseSize4;
365
-				return true;
366
-			case 5:
367
-				*R = armcp15->protectBaseSize5;
368
-				return true;
369
-			case 6:
370
-				*R = armcp15->protectBaseSize6;
371
-				return true;
372
-			case 7:
373
-				*R = armcp15->protectBaseSize7;
263
+				switch (opcode2)
264
+				{
265
+					case 0:
266
+						*R = this->DCConfig;
267
+						return true;
268
+					case 1:
269
+						*R = this->ICConfig;
270
+						return true;
271
+					default:
272
+						return false;
273
+				}
274
+			}
275
+			return false;
276
+		case 3:
277
+			if (!opcode1 && ~opcode2 && !CRm)
278
+			{
279
+				*R = this->writeBuffCtrl;
374 280
 				return true;
375
-			default:
376
-				return false;
377 281
 			}
378
-		}
379
-		return false;
380
-	case 9:
381
-		if((opcode1==0))
382
-		{
383
-			switch(CRm)
282
+			return false;
283
+		case 5:
284
+			if (!opcode1 && !CRm)
285
+			{
286
+				switch (opcode2)
287
+				{
288
+					case 2:
289
+						*R = this->DaccessPerm;
290
+						return true;
291
+					case 3:
292
+						*R = this->IaccessPerm;
293
+						return true;
294
+					default:
295
+						return false;
296
+				}
297
+			}
298
+			return false;
299
+		case 6:
300
+			if (!opcode1 && !opcode2)
384 301
 			{
385
-			case 0:
386
-				switch(opcode2)
302
+				switch (CRm)
387 303
 				{
388
-				case 0:
389
-					*R = armcp15->DcacheLock;
390
-					return true;
391
-				case 1:
392
-					*R = armcp15->IcacheLock;
393
-					return true;
394
-				default:
395
-					return false;
304
+					case 0:
305
+						*R = this->protectBaseSize0;
306
+						return true;
307
+					case 1:
308
+						*R = this->protectBaseSize1;
309
+						return true;
310
+					case 2:
311
+						*R = this->protectBaseSize2;
312
+						return true;
313
+					case 3:
314
+						*R = this->protectBaseSize3;
315
+						return true;
316
+					case 4:
317
+						*R = this->protectBaseSize4;
318
+						return true;
319
+					case 5:
320
+						*R = this->protectBaseSize5;
321
+						return true;
322
+					case 6:
323
+						*R = this->protectBaseSize6;
324
+						return true;
325
+					case 7:
326
+						*R = this->protectBaseSize7;
327
+						return true;
328
+					default:
329
+						return false;
396 330
 				}
397
-			case 1:
398
-				switch(opcode2)
331
+			}
332
+			return false;
333
+		case 9:
334
+			if (!opcode1)
335
+			{
336
+				switch (CRm)
399 337
 				{
400
-				case 0:
401
-					*R = armcp15->DTCMRegion;
402
-					return true;
403
-				case 1:
404
-					*R = armcp15->ITCMRegion;
405
-					return true;
406
-				default:
407
-					return false;
338
+					case 0:
339
+						switch (opcode2)
340
+						{
341
+							case 0:
342
+								*R = this->DcacheLock;
343
+								return true;
344
+							case 1:
345
+								*R = this->IcacheLock;
346
+								return true;
347
+							default:
348
+								return false;
349
+						}
350
+					case 1:
351
+						switch (opcode2)
352
+						{
353
+							case 0:
354
+								*R = this->DTCMRegion;
355
+								return true;
356
+							case 1:
357
+								*R = this->ITCMRegion;
358
+								return true;
359
+							default:
360
+								return false;
361
+						}
408 362
 				}
409 363
 			}
410
-		}
411
-		return false;
412
-	default:
413
-		//LOG("Unsupported CP15 operation : MRC\n");
414
-		return false;
364
+			return false;
365
+		default:
366
+			return false;
415 367
 	}
416 368
 }
417 369
 
418
-static uint32_t CP15wait4IRQ(armcpu_t *cpu)
370
+bool armcp15_t::moveARM2CP(uint32_t val, uint8_t CRn, uint8_t CRm, uint8_t opcode1, uint8_t opcode2)
419 371
 {
420
-	cpu->waitIRQ = true;
421
-	cpu->halt_IE_and_IF = true;
422
-	//IME set deliberately omitted: only SWI sets IME to 1
423
-	return 1;
424
-}
425
-
426
-bool armcp15_moveARM2CP(armcp15_t *armcp15, uint32_t val, uint8_t CRn, uint8_t CRm, uint8_t opcode1, uint8_t opcode2)
427
-{
428
-	if(armcp15->cpu->CPSR.bits.mode == USR) return false;
429
-
430
-	switch(CRn)
372
+	if (!this->cpu)
431 373
 	{
432
-	case 1:
433
-		if((opcode1==0) && (opcode2==0) && (CRm==0))
434
-		{
435
-
436
-			//On the NDS bit0,2,7,12..19 are R/W, Bit3..6 are always set, all other bits are always zero.
437
-			armcp15->ctrl = (val & 0x000FF085) | 0x00000078;
438
-			MMU.ARM9_RW_MODE = static_cast<uint8_t>(BIT7(val));
439
-			//zero 31-jan-2010: change from 0x0FFF0000 to 0xFFFF0000 per gbatek
440
-			armcp15->cpu->intVector = 0xFFFF0000 * (BIT13(val));
441
-			armcp15->cpu->LDTBit = !BIT15(val); //TBit
442
-			//LOG("CP15: ARMtoCP ctrl %08X (val %08X)\n", armcp15->ctrl, val);
443
-			return true;
444
-		}
374
+		printf("ERROR: cp15 don\'t allocated\n");
375
+		return false;
376
+	}
377
+	if (this->cpu->CPSR.bits.mode == USR)
445 378
 		return false;
446
-	case 2:
447
-		if((opcode1==0) && (CRm==0))
448
-		{
449
-			switch(opcode2)
379
+
380
+	switch (CRn)
381
+	{
382
+		case 1:
383
+			if (!opcode1 && !opcode2 && !CRm)
450 384
 			{
451
-			case 0:
452
-				armcp15->DCConfig = val;
453
-				return true;
454
-			case 1:
455
-				armcp15->ICConfig = val;
385
+				// On the NDS bit0,2,7,12..19 are R/W, Bit3..6 are always set, all other bits are always zero.
386
+				this->ctrl = (val & 0x000FF085) | 0x00000078;
387
+				MMU.ARM9_RW_MODE = static_cast<uint8_t>(BIT7(val));
388
+				// zero 31-jan-2010: change from 0x0FFF0000 to 0xFFFF0000 per gbatek
389
+				this->cpu->intVector = 0xFFFF0000 * BIT13(val);
390
+				this->cpu->LDTBit = !BIT15(val); // TBit
456 391
 				return true;
457
-			default:
458
-				return false;
459 392
 			}
460
-		}
461
-		return false;
462
-	case 3:
463
-		if((opcode1==0) && (opcode2==0) && (CRm==0))
464
-		{
465
-			armcp15->writeBuffCtrl = val;
466
-			//LOG("CP15: ARMtoCP writeBuffer ctrl %08X\n", armcp15->writeBuffCtrl);
467
-			return true;
468
-		}
469
-		return false;
470
-	case 5:
471
-		if((opcode1==0) && (CRm==0))
472
-		{
473
-			switch(opcode2)
393
+			return false;
394
+		case 2:
395
+			if (!opcode1 && !CRm)
474 396
 			{
475
-			case 2:
476
-				armcp15->DaccessPerm = val;
477
-				armcp15_maskPrecalc(armcp15);
478
-				return true;
479
-			case 3:
480
-				armcp15->IaccessPerm = val;
481
-				armcp15_maskPrecalc(armcp15);
482
-				return true;
483
-			default:
484
-				return false;
397
+				switch (opcode2)
398
+				{
399
+					case 0:
400
+						this->DCConfig = val;
401
+						return true;
402
+					case 1:
403
+						this->ICConfig = val;
404
+						return true;
405
+					default:
406
+						return false;
407
+				}
485 408
 			}
486
-		}
487
-		return false;
488
-	case 6:
489
-		if((opcode1==0) && (opcode2==0))
490
-		{
491
-			switch(CRm)
409
+			return false;
410
+		case 3:
411
+			if (!opcode1 && !opcode2 && !CRm)
492 412
 			{
493
-			case 0:
494
-				armcp15->protectBaseSize0 = val;
495
-				armcp15_maskPrecalc(armcp15) ;
413
+				this->writeBuffCtrl = val;
496 414
 				return true;
497
-			case 1:
498
-				armcp15->protectBaseSize1 = val;
499
-				armcp15_maskPrecalc(armcp15) ;
500
-				return true;
501
-			case 2:
502
-				armcp15->protectBaseSize2 = val;
503
-				armcp15_maskPrecalc(armcp15) ;
504
-				return true;
505
-			case 3:
506
-				armcp15->protectBaseSize3 = val;
507
-				armcp15_maskPrecalc(armcp15) ;
508
-				return true;
509
-			case 4:
510
-				armcp15->protectBaseSize4 = val;
511
-				armcp15_maskPrecalc(armcp15) ;
512
-				return true;
513
-			case 5:
514
-				armcp15->protectBaseSize5 = val;
515
-				armcp15_maskPrecalc(armcp15) ;
516
-				return true;
517
-			case 6:
518
-				armcp15->protectBaseSize6 = val;
519
-				armcp15_maskPrecalc(armcp15) ;
520
-				return true;
521
-			case 7:
522
-				armcp15->protectBaseSize7 = val;
523
-				armcp15_maskPrecalc(armcp15) ;
524
-				return true;
525
-			default:
526
-				return false;
527 415
 			}
528
-		}
529
-		return false;
530
-	case 7:
531
-		if((CRm==0)&&(opcode1==0)&&((opcode2==4)))
532
-		{
533
-			CP15wait4IRQ(armcp15->cpu);
534
-			return true;
535
-		}
536
-		return false;
537
-	case 9:
538
-		if((opcode1==0))
539
-		{
540
-			switch(CRm)
416
+			return false;
417
+		case 5:
418
+			if (!opcode1 && !CRm)
541 419
 			{
542
-			case 0:
543
-				switch(opcode2)
420
+				switch (opcode2)
544 421
 				{
545
-				case 0:
546
-					armcp15->DcacheLock = val;
547
-					return true;
548
-				case 1:
549
-					armcp15->IcacheLock = val;
550
-					return true;
551
-				default:
552
-					return false;
422
+					case 2:
423
+						this->DaccessPerm = val;
424
+						this->maskPrecalc();
425
+						return true;
426
+					case 3:
427
+						this->IaccessPerm = val;
428
+						this->maskPrecalc();
429
+						return true;
430
+					default:
431
+						return false;
553 432
 				}
554
-			case 1:
555
-				switch(opcode2)
433
+			}
434
+			return false;
435
+		case 6:
436
+			if (!opcode1 && !opcode2)
437
+			{
438
+				switch (CRm)
556 439
 				{
557
-				case 0:
558
-					MMU.DTCMRegion = armcp15->DTCMRegion = val & 0x0FFFF000;
559
-					return true;
560
-				case 1:
561
-					armcp15->ITCMRegion = val;
562
-					//ITCM base is not writeable!
563
-					MMU.ITCMRegion = 0;
564
-					return true;
565
-				default:
566
-					return false;
440
+					case 0:
441
+						this->protectBaseSize0 = val;
442
+						this->maskPrecalc();
443
+						return true;
444
+					case 1:
445
+						this->protectBaseSize1 = val;
446
+						this->maskPrecalc();
447
+						return true;
448
+					case 2:
449
+						this->protectBaseSize2 = val;
450
+						this->maskPrecalc();
451
+						return true;
452
+					case 3:
453
+						this->protectBaseSize3 = val;
454
+						this->maskPrecalc();
455
+						return true;
456
+					case 4:
457
+						this->protectBaseSize4 = val;
458
+						this->maskPrecalc();
459
+						return true;
460
+					case 5:
461
+						this->protectBaseSize5 = val;
462
+						this->maskPrecalc();
463
+						return true;
464
+					case 6:
465
+						this->protectBaseSize6 = val;
466
+						this->maskPrecalc();
467
+						return true;
468
+					case 7:
469
+						this->protectBaseSize7 = val;
470
+						this->maskPrecalc();
471
+						return true;
472
+					default:
473
+						return false;
567 474
 				}
568 475
 			}
569
-		}
570
-		return false;
571
-	default:
572
-		return false;
476
+			return false;
477
+		case 7:
478
+			if (!CRm && !opcode1 && opcode2 == 4)
479
+			{
480
+				this->cpu->waitIRQ = true;
481
+				this->cpu->halt_IE_and_IF = true;
482
+				// IME set deliberately omitted: only SWI sets IME to 1
483
+				return true;
484
+			}
485
+			return false;
486
+		case 9:
487
+			if (!opcode1)
488
+			{
489
+				switch (CRm)
490
+				{
491
+					case 0:
492
+						switch (opcode2)
493
+						{
494
+							case 0:
495
+								this->DcacheLock = val;
496
+								return true;
497
+							case 1:
498
+								this->IcacheLock = val;
499
+								return true;
500
+							default:
501
+								return false;
502
+						}
503
+					case 1:
504
+						switch (opcode2)
505
+						{
506
+							case 0:
507
+								MMU.DTCMRegion = this->DTCMRegion = val & 0x0FFFF000;
508
+								return true;
509
+							case 1:
510
+								this->ITCMRegion = val;
511
+								// ITCM base is not writeable!
512
+								MMU.ITCMRegion = 0;
513
+								return true;
514
+							default:
515
+								return false;
516
+						}
517
+				}
518
+			}
519
+			return false;
520
+		default:
521
+			return false;
573 522
 	}
574 523
 }
524
+
525
+/* precalculate region masks/sets from cp15 register ----- JIT */
526
+void maskPrecalc()
527
+{
528
+#define precalc(num) \
529
+{ \
530
+	uint32_t mask = 0, set = 0xFFFFFFFF; /* (x & 0) == 0xFF..FF is allways false (disabled) */ \
531
+	if (BIT_N(cp15.protectBaseSize##num, 0)) /* if region is enabled */ \
532
+	{ \
533
+		/* reason for this define: naming includes var */ \
534
+		mask = MASKFROMREG(cp15.protectBaseSize##num); \
535
+		set = SETFROMREG(cp15.protectBaseSize##num); \
536
+		if (SIZEIDENTIFIER(cp15.protectBaseSize##num) == 0x1F) \
537
+		{ \
538
+			/* for the 4GB region, u32 suffers wraparound */ \
539
+			mask = 0; \
540
+			set = 0; /* (x & 0) == 0  is allways true (enabled) */ \
541
+		} \
542
+	} \
543
+	cp15.setSingleRegionAccess(cp15.DaccessPerm, cp15.IaccessPerm, num, mask, set); \
544
+}
545
+	precalc(0);
546
+	precalc(1);
547
+	precalc(2);
548
+	precalc(3);
549
+	precalc(4);
550
+	precalc(5);
551
+	precalc(6);
552
+	precalc(7);
553
+#undef precalc
554
+}
Browse code

Import actual code.

Naram Qashat authored on 2013/03/26 02:41:19
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,574 @@
1
+/*
2
+	Copyright (C) 2006 yopyop
3
+	Copyright (C) 2006-2011 DeSmuME team
4
+
5
+	This file is free software: you can redistribute it and/or modify
6
+	it under the terms of the GNU General Public License as published by
7
+	the Free Software Foundation, either version 2 of the License, or
8
+	(at your option) any later version.
9
+
10
+	This file is distributed in the hope that it will be useful,
11
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+	GNU General Public License for more details.
14
+
15
+	You should have received a copy of the GNU General Public License
16
+	along with the this software.  If not, see <http://www.gnu.org/licenses/>.
17
+*/
18
+
19
+#include <cstdlib>
20
+
21
+#include "cp15.h"
22
+//#include "debug.h"
23
+#include "MMU.h"
24
+
25
+armcp15_t *armcp15_new(armcpu_t * c)
26
+{
27
+	int i;
28
+	armcp15_t *armcp15 = (armcp15_t*)malloc(sizeof(armcp15_t));
29
+	if(!armcp15) return NULL;
30
+
31
+
32
+	armcp15->cpu = c;
33
+	armcp15->IDCode = 0x41059461;
34
+	armcp15->cacheType = 0x0F0D2112;
35
+	armcp15->TCMSize = 0x00140180;
36
+	armcp15->ctrl = 0x00012078;
37
+	armcp15->DCConfig = 0x0;
38
+	armcp15->ICConfig = 0x0;
39
+	armcp15->writeBuffCtrl = 0x0;
40
+	armcp15->und = 0x0;
41
+	armcp15->DaccessPerm = 0x22222222;
42
+	armcp15->IaccessPerm = 0x22222222;
43
+	armcp15->protectBaseSize0 = 0x0;
44
+	armcp15->protectBaseSize1 = 0x0;
45
+	armcp15->protectBaseSize2 = 0x0;
46
+	armcp15->protectBaseSize3 = 0x0;
47
+	armcp15->protectBaseSize4 = 0x0;
48
+	armcp15->protectBaseSize5 = 0x0;
49
+	armcp15->protectBaseSize6 = 0x0;
50
+	armcp15->protectBaseSize7 = 0x0;
51
+	armcp15->cacheOp = 0x0;
52
+	armcp15->DcacheLock = 0x0;
53
+	armcp15->IcacheLock = 0x0;
54
+	armcp15->ITCMRegion = 0x0C;
55
+	armcp15->DTCMRegion = 0x0080000A;
56
+	armcp15->processID = 0;
57
+
58
+	MMU.ARM9_RW_MODE = static_cast<uint8_t>(BIT7(armcp15->ctrl));
59
+	armcp15->cpu->intVector = 0xFFFF0000 * (BIT13(armcp15->ctrl));
60
+	armcp15->cpu->LDTBit = !BIT15(armcp15->ctrl); //TBit
61
+
62
+	/* preset calculated regionmasks */
63
+	for (i=0;i<8;i++) {
64
+		armcp15->regionWriteMask_USR[i] = 0 ;
65
+		armcp15->regionWriteMask_SYS[i] = 0 ;
66
+		armcp15->regionReadMask_USR[i] = 0 ;
67
+		armcp15->regionReadMask_SYS[i] = 0 ;
68
+		armcp15->regionExecuteMask_USR[i] = 0 ;
69
+		armcp15->regionExecuteMask_SYS[i] = 0 ;
70
+		armcp15->regionWriteSet_USR[i] = 0 ;
71
+		armcp15->regionWriteSet_SYS[i] = 0 ;
72
+		armcp15->regionReadSet_USR[i] = 0 ;
73
+		armcp15->regionReadSet_SYS[i] = 0 ;
74
+		armcp15->regionExecuteSet_USR[i] = 0 ;
75
+		armcp15->regionExecuteSet_SYS[i] = 0 ;
76
+	} ;
77
+
78
+	return armcp15;
79
+}
80
+
81
+//#define ACCESSTYPE(val,n)   (((val) >> (4*n)) & 0x0F)
82
+static inline uint32_t ACCESSTYPE(uint32_t val, unsigned char n) { return (val >> (4 * n)) & 0x0F; }
83
+//#define SIZEIDENTIFIER(val) ((((val) >> 1) & 0x1F))
84
+static inline uint32_t SIZEIDENTIFIER(uint32_t val) { return (val >> 1) & 0x1F; }
85
+//#define SIZEBINARY(val)     (1 << (SIZEIDENTIFIER(val)+1))
86
+static inline uint32_t SIZEBINARY(uint32_t val) { return 1 << (SIZEIDENTIFIER(val) + 1); }
87
+//#define MASKFROMREG(val)    (~((SIZEBINARY(val)-1) | 0x3F))
88
+static inline uint32_t MASKFROMREG(uint32_t val) { return ~((SIZEBINARY(val) - 1) | 0x3F); }
89
+//#define SETFROMREG(val)     ((val) & MASKFROMREG(val))
90
+static inline uint32_t SETFROMREG(uint32_t val) { return val & MASKFROMREG(val); }
91
+/* sets the precalculated regions to mask,set for the affected accesstypes */
92
+static void armcp15_setSingleRegionAccess(armcp15_t *armcp15,uint32_t dAccess,uint32_t iAccess,unsigned char num, uint32_t mask,uint32_t set) {
93
+
94
+	switch (ACCESSTYPE(dAccess,num)) {
95
+		case 4: /* UNP */
96
+		case 7: /* UNP */
97
+		case 8: /* UNP */
98
+		case 9: /* UNP */
99
+		case 10: /* UNP */
100
+		case 11: /* UNP */
101
+		case 12: /* UNP */
102
+		case 13: /* UNP */
103
+		case 14: /* UNP */
104
+		case 15: /* UNP */
105
+		case 0: /* no access at all */
106
+			armcp15->regionWriteMask_USR[num] = 0 ;
107
+			armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
108
+			armcp15->regionReadMask_USR[num] = 0 ;
109
+			armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ;
110
+			armcp15->regionWriteMask_SYS[num] = 0 ;
111
+			armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ;
112
+			armcp15->regionReadMask_SYS[num] = 0 ;
113
+			armcp15->regionReadSet_SYS[num] = 0xFFFFFFFF ;
114
+			break ;
115
+		case 1: /* no access at USR, all to sys */
116
+			armcp15->regionWriteMask_USR[num] = 0 ;
117
+			armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
118
+			armcp15->regionReadMask_USR[num] = 0 ;
119
+			armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ;
120
+			armcp15->regionWriteMask_SYS[num] = mask ;
121
+			armcp15->regionWriteSet_SYS[num] = set ;
122
+			armcp15->regionReadMask_SYS[num] = mask ;
123
+			armcp15->regionReadSet_SYS[num] = set ;
124
+			break ;
125
+		case 2: /* read at USR, all to sys */
126
+			armcp15->regionWriteMask_USR[num] = 0 ;
127
+			armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
128
+			armcp15->regionReadMask_USR[num] = mask ;
129
+			armcp15->regionReadSet_USR[num] = set ;
130
+			armcp15->regionWriteMask_SYS[num] = mask ;
131
+			armcp15->regionWriteSet_SYS[num] = set ;
132
+			armcp15->regionReadMask_SYS[num] = mask ;
133
+			armcp15->regionReadSet_SYS[num] = set ;
134
+			break ;
135
+		case 3: /* all to USR, all to sys */
136
+			armcp15->regionWriteMask_USR[num] = mask ;
137
+			armcp15->regionWriteSet_USR[num] = set ;
138
+			armcp15->regionReadMask_USR[num] = mask ;
139
+			armcp15->regionReadSet_USR[num] = set ;
140
+			armcp15->regionWriteMask_SYS[num] = mask ;
141
+			armcp15->regionWriteSet_SYS[num] = set ;
142
+			armcp15->regionReadMask_SYS[num] = mask ;
143
+			armcp15->regionReadSet_SYS[num] = set ;
144
+			break ;
145
+		case 5: /* no access at USR, read to sys */
146
+			armcp15->regionWriteMask_USR[num] = 0 ;
147
+			armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
148
+			armcp15->regionReadMask_USR[num] = 0 ;
149
+			armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ;
150
+			armcp15->regionWriteMask_SYS[num] = 0 ;
151
+			armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ;
152
+			armcp15->regionReadMask_SYS[num] = mask ;
153
+			armcp15->regionReadSet_SYS[num] = set ;
154
+			break ;
155
+		case 6: /* read at USR, read to sys */
156
+			armcp15->regionWriteMask_USR[num] = 0 ;
157
+			armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
158
+			armcp15->regionReadMask_USR[num] = mask ;
159
+			armcp15->regionReadSet_USR[num] = set ;
160
+			armcp15->regionWriteMask_SYS[num] = 0 ;
161
+			armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ;
162
+			armcp15->regionReadMask_SYS[num] = mask ;
163
+			armcp15->regionReadSet_SYS[num] = set ;
164
+			break ;
165
+	}
166
+	switch (ACCESSTYPE(iAccess,num)) {
167
+		case 4: /* UNP */
168
+		case 7: /* UNP */
169
+		case 8: /* UNP */
170
+		case 9: /* UNP */
171
+		case 10: /* UNP */
172
+		case 11: /* UNP */
173
+		case 12: /* UNP */
174
+		case 13: /* UNP */
175
+		case 14: /* UNP */
176
+		case 15: /* UNP */
177
+		case 0: /* no access at all */
178
+			armcp15->regionExecuteMask_USR[num] = 0 ;
179
+			armcp15->regionExecuteSet_USR[num] = 0xFFFFFFFF ;
180
+			armcp15->regionExecuteMask_SYS[num] = 0 ;
181
+			armcp15->regionExecuteSet_SYS[num] = 0xFFFFFFFF ;
182
+			break ;
183
+		case 1:
184
+			armcp15->regionExecuteMask_USR[num] = 0 ;
185
+			armcp15->regionExecuteSet_USR[num] = 0xFFFFFFFF ;
186
+			armcp15->regionExecuteMask_SYS[num] = mask ;
187
+			armcp15->regionExecuteSet_SYS[num] = set ;
188
+			break ;
189
+		case 2:
190
+		case 3:
191
+		case 6:
192
+			armcp15->regionExecuteMask_USR[num] = mask ;
193
+			armcp15->regionExecuteSet_USR[num] = set ;
194
+			armcp15->regionExecuteMask_SYS[num] = mask ;
195
+			armcp15->regionExecuteSet_SYS[num] = set ;
196
+			break ;
197
+	}
198
+}
199
+
200
+/* precalculate region masks/sets from cp15 register */
201
+static void armcp15_maskPrecalc(armcp15_t *armcp15)
202
+{
203
+#define precalc(num) {  \
204
+	uint32_t mask = 0, set = 0xFFFFFFFF ; /* (x & 0) == 0xFF..FF is allways false (disabled) */  \
205
+	if (BIT_N(armcp15->protectBaseSize##num,0)) /* if region is enabled */ \
206
+	{    /* reason for this define: naming includes var */  \
207
+	mask = MASKFROMREG(armcp15->protectBaseSize##num) ;   \
208
+	set = SETFROMREG(armcp15->protectBaseSize##num) ; \
209
+	if (SIZEIDENTIFIER(armcp15->protectBaseSize##num)==0x1F)  \
210
+	{   /* for the 4GB region, uint32_t suffers wraparound */   \
211
+	mask = 0 ; set = 0 ;   /* (x & 0) == 0  is allways true (enabled) */  \
212
+} \
213
+}  \
214
+	armcp15_setSingleRegionAccess(armcp15,armcp15->DaccessPerm,armcp15->IaccessPerm,num,mask,set) ;  \
215
+}
216
+	precalc(0) ;
217
+	precalc(1) ;
218
+	precalc(2) ;
219
+	precalc(3) ;
220
+	precalc(4) ;
221
+	precalc(5) ;
222
+	precalc(6) ;
223
+	precalc(7) ;
224
+}
225
+
226
+/*bool armcp15_isAccessAllowed(armcp15_t *armcp15,uint32_t address,uint32_t access)
227
+{
228
+	int i ;
229
+	if (!(armcp15->ctrl & 1)) return true ;*/        /* protection checking is not enabled */
230
+	/*for (i=0;i<8;i++) {
231
+		switch (access) {
232
+		case CP15_ACCESS_WRITEUSR:
233
+			if ((address & armcp15->regionWriteMask_USR[i]) == armcp15->regionWriteSet_USR[i]) return true ;
234
+			break ;
235
+		case CP15_ACCESS_WRITESYS:
236
+			if ((address & armcp15->regionWriteMask_SYS[i]) == armcp15->regionWriteSet_SYS[i]) return true ;
237
+			break ;
238
+		case CP15_ACCESS_READUSR:
239
+			if ((address & armcp15->regionReadMask_USR[i]) == armcp15->regionReadSet_USR[i]) return true ;
240
+			break ;
241
+		case CP15_ACCESS_READSYS:
242
+			if ((address & armcp15->regionReadMask_SYS[i]) == armcp15->regionReadSet_SYS[i]) return true ;
243
+			break ;
244
+		case CP15_ACCESS_EXECUSR:
245
+			if ((address & armcp15->regionExecuteMask_USR[i]) == armcp15->regionExecuteSet_USR[i]) return true ;
246
+			break ;
247
+		case CP15_ACCESS_EXECSYS:
248
+			if ((address & armcp15->regionExecuteMask_SYS[i]) == armcp15->regionExecuteSet_SYS[i]) return true ;
249
+			break ;
250
+		}
251
+	}*/
252
+	/* when protections are enabled, but no region allows access, deny access */
253
+	/*return false ;
254
+}*/
255
+
256
+/*bool armcp15_dataProcess(armcp15_t *, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t)
257
+{
258
+	//LOG("Unsupported CP15 operation : DataProcess\n");
259
+	return false;
260
+}*/
261
+
262
+/*bool armcp15_load(armcp15_t *, uint8_t, uint8_t)
263
+{
264
+	//LOG("Unsupported CP15 operation : Load\n");
265
+	return false;
266
+}*/
267
+
268
+/*bool armcp15_store(armcp15_t *, uint8_t, uint8_t)
269
+{
270
+	//LOG("Unsupported CP15 operation : Store\n");
271
+	return false;
272
+}*/
273
+
274
+bool armcp15_moveCP2ARM(armcp15_t *armcp15, uint32_t * R, uint8_t CRn, uint8_t CRm, uint8_t opcode1, uint8_t opcode2)
275
+{
276
+	if(armcp15->cpu->CPSR.bits.mode == USR) return false;
277
+
278
+	switch(CRn)
279
+	{
280
+	case 0:
281
+		if((opcode1 == 0)&&(CRm==0))
282
+		{
283
+			switch(opcode2)
284
+			{
285
+			case 1:
286
+				*R = armcp15->cacheType;
287
+				return true;
288
+			case 2:
289
+				*R = armcp15->TCMSize;
290
+				return true;
291
+			default:
292
+				*R = armcp15->IDCode;
293
+				return true;
294
+			}
295
+		}
296
+		return false;
297
+	case 1:
298
+		if((opcode1==0) && (opcode2==0) && (CRm==0))
299
+		{
300
+			*R = armcp15->ctrl;
301
+			//LOG("CP15: CPtoARM ctrl %08X\n", armcp15->ctrl);
302
+			return true;
303
+		}
304
+		return false;
305
+
306
+	case 2:
307
+		if((opcode1==0) && (CRm==0))
308
+		{
309
+			switch(opcode2)
310
+			{
311
+			case 0:
312
+				*R = armcp15->DCConfig;
313
+				return true;
314
+			case 1:
315
+				*R = armcp15->ICConfig;
316
+				return true;
317
+			default:
318
+				return false;
319
+			}
320
+		}
321
+		return false;
322
+	case 3:
323
+		if((opcode1==0) && (opcode2==0) && (CRm==0))
324
+		{
325
+			*R = armcp15->writeBuffCtrl;
326
+			//LOG("CP15: CPtoARM writeBuffer ctrl %08X\n", armcp15->writeBuffCtrl);
327
+			return true;
328
+		}
329
+		return false;
330
+	case 5:
331
+		if((opcode1==0) && (CRm==0))
332
+		{
333
+			switch(opcode2)
334
+			{
335
+			case 2:
336
+				*R = armcp15->DaccessPerm;
337
+				return true;
338
+			case 3:
339
+				*R = armcp15->IaccessPerm;
340
+				return true;
341
+			default:
342
+				return false;
343
+			}
344
+		}
345
+		return false;
346
+	case 6:
347
+		if((opcode1==0) && (opcode2==0))
348
+		{
349
+			switch(CRm)
350
+			{
351
+			case 0:
352
+				*R = armcp15->protectBaseSize0;
353
+				return true;
354
+			case 1:
355
+				*R = armcp15->protectBaseSize1;
356
+				return true;
357
+			case 2:
358
+				*R = armcp15->protectBaseSize2;
359
+				return true;
360
+			case 3:
361
+				*R = armcp15->protectBaseSize3;
362
+				return true;
363
+			case 4:
364
+				*R = armcp15->protectBaseSize4;
365
+				return true;
366
+			case 5:
367
+				*R = armcp15->protectBaseSize5;
368
+				return true;
369
+			case 6:
370
+				*R = armcp15->protectBaseSize6;
371
+				return true;
372
+			case 7:
373
+				*R = armcp15->protectBaseSize7;
374
+				return true;
375
+			default:
376
+				return false;
377
+			}
378
+		}
379
+		return false;
380
+	case 9:
381
+		if((opcode1==0))
382
+		{
383
+			switch(CRm)
384
+			{
385
+			case 0:
386
+				switch(opcode2)
387
+				{
388
+				case 0:
389
+					*R = armcp15->DcacheLock;
390
+					return true;
391
+				case 1:
392
+					*R = armcp15->IcacheLock;
393
+					return true;
394
+				default:
395
+					return false;
396
+				}
397
+			case 1:
398
+				switch(opcode2)
399
+				{
400
+				case 0:
401
+					*R = armcp15->DTCMRegion;
402
+					return true;
403
+				case 1:
404
+					*R = armcp15->ITCMRegion;
405
+					return true;
406
+				default:
407
+					return false;
408
+				}
409
+			}
410
+		}
411
+		return false;
412
+	default:
413
+		//LOG("Unsupported CP15 operation : MRC\n");
414
+		return false;
415
+	}
416
+}
417
+
418
+static uint32_t CP15wait4IRQ(armcpu_t *cpu)
419
+{
420
+	cpu->waitIRQ = true;
421
+	cpu->halt_IE_and_IF = true;
422
+	//IME set deliberately omitted: only SWI sets IME to 1
423
+	return 1;
424
+}
425
+
426
+bool armcp15_moveARM2CP(armcp15_t *armcp15, uint32_t val, uint8_t CRn, uint8_t CRm, uint8_t opcode1, uint8_t opcode2)
427
+{
428
+	if(armcp15->cpu->CPSR.bits.mode == USR) return false;
429
+
430
+	switch(CRn)
431
+	{
432
+	case 1:
433
+		if((opcode1==0) && (opcode2==0) && (CRm==0))
434
+		{
435
+
436
+			//On the NDS bit0,2,7,12..19 are R/W, Bit3..6 are always set, all other bits are always zero.
437
+			armcp15->ctrl = (val & 0x000FF085) | 0x00000078;
438
+			MMU.ARM9_RW_MODE = static_cast<uint8_t>(BIT7(val));
439
+			//zero 31-jan-2010: change from 0x0FFF0000 to 0xFFFF0000 per gbatek
440
+			armcp15->cpu->intVector = 0xFFFF0000 * (BIT13(val));
441
+			armcp15->cpu->LDTBit = !BIT15(val); //TBit
442
+			//LOG("CP15: ARMtoCP ctrl %08X (val %08X)\n", armcp15->ctrl, val);
443
+			return true;
444
+		}
445
+		return false;
446
+	case 2:
447
+		if((opcode1==0) && (CRm==0))
448
+		{
449
+			switch(opcode2)
450
+			{
451
+			case 0:
452
+				armcp15->DCConfig = val;
453
+				return true;
454
+			case 1:
455
+				armcp15->ICConfig = val;
456
+				return true;
457
+			default:
458
+				return false;
459
+			}
460
+		}
461
+		return false;
462
+	case 3:
463
+		if((opcode1==0) && (opcode2==0) && (CRm==0))
464
+		{
465
+			armcp15->writeBuffCtrl = val;
466
+			//LOG("CP15: ARMtoCP writeBuffer ctrl %08X\n", armcp15->writeBuffCtrl);
467
+			return true;
468
+		}
469
+		return false;
470
+	case 5:
471
+		if((opcode1==0) && (CRm==0))
472
+		{
473
+			switch(opcode2)
474
+			{
475
+			case 2:
476
+				armcp15->DaccessPerm = val;
477
+				armcp15_maskPrecalc(armcp15);
478
+				return true;
479
+			case 3:
480
+				armcp15->IaccessPerm = val;
481
+				armcp15_maskPrecalc(armcp15);
482
+				return true;
483
+			default:
484
+				return false;
485
+			}
486
+		}
487
+		return false;
488
+	case 6:
489
+		if((opcode1==0) && (opcode2==0))
490
+		{
491
+			switch(CRm)
492
+			{
493
+			case 0:
494
+				armcp15->protectBaseSize0 = val;
495
+				armcp15_maskPrecalc(armcp15) ;
496
+				return true;
497
+			case 1:
498
+				armcp15->protectBaseSize1 = val;
499
+				armcp15_maskPrecalc(armcp15) ;
500
+				return true;
501
+			case 2:
502
+				armcp15->protectBaseSize2 = val;
503
+				armcp15_maskPrecalc(armcp15) ;
504
+				return true;
505
+			case 3:
506
+				armcp15->protectBaseSize3 = val;
507
+				armcp15_maskPrecalc(armcp15) ;
508
+				return true;
509
+			case 4:
510
+				armcp15->protectBaseSize4 = val;
511
+				armcp15_maskPrecalc(armcp15) ;
512
+				return true;
513
+			case 5:
514
+				armcp15->protectBaseSize5 = val;
515
+				armcp15_maskPrecalc(armcp15) ;
516
+				return true;
517
+			case 6:
518
+				armcp15->protectBaseSize6 = val;
519
+				armcp15_maskPrecalc(armcp15) ;
520
+				return true;
521
+			case 7:
522
+				armcp15->protectBaseSize7 = val;
523
+				armcp15_maskPrecalc(armcp15) ;
524
+				return true;
525
+			default:
526
+				return false;
527
+			}
528
+		}
529
+		return false;
530
+	case 7:
531
+		if((CRm==0)&&(opcode1==0)&&((opcode2==4)))
532
+		{
533
+			CP15wait4IRQ(armcp15->cpu);
534
+			return true;
535
+		}
536
+		return false;
537
+	case 9:
538
+		if((opcode1==0))
539
+		{
540
+			switch(CRm)
541
+			{
542
+			case 0:
543
+				switch(opcode2)
544
+				{
545
+				case 0:
546
+					armcp15->DcacheLock = val;
547
+					return true;
548
+				case 1:
549
+					armcp15->IcacheLock = val;
550
+					return true;
551
+				default:
552
+					return false;
553
+				}
554
+			case 1:
555
+				switch(opcode2)
556
+				{
557
+				case 0:
558
+					MMU.DTCMRegion = armcp15->DTCMRegion = val & 0x0FFFF000;
559
+					return true;
560
+				case 1:
561
+					armcp15->ITCMRegion = val;
562
+					//ITCM base is not writeable!
563
+					MMU.ITCMRegion = 0;
564
+					return true;
565
+				default:
566
+					return false;
567
+				}
568
+			}
569
+		}
570
+		return false;
571
+	default:
572
+		return false;
573
+	}
574
+}