1 // license:BSD-3-Clause
2 // copyright-holders:Ville Linde
3 #define SIGN_EXTEND6(x) (((x) & 0x20) ? (0xffffffc0 | (x)) : (x))
4 #define SIGN_EXTEND24(x) (((x) & 0x800000) ? (0xff000000 | (x)) : (x))
5
6 #define PM_REG_I(x) (m_core->dag2.i[x])
7 #define PM_REG_M(x) (m_core->dag2.m[x])
8 #define PM_REG_B(x) (m_core->dag2.b[x])
9 #define PM_REG_L(x) (m_core->dag2.l[x])
10 #define DM_REG_I(x) (m_core->dag1.i[x])
11 #define DM_REG_M(x) (m_core->dag1.m[x])
12 #define DM_REG_B(x) (m_core->dag1.b[x])
13 #define DM_REG_L(x) (m_core->dag1.l[x])
14
15 // ASTAT flags
16 #define AZ 0x1 /* ALU result zero */
17 #define AV 0x2 /* ALU overflow */
18 #define AN 0x4 /* ALU result negative */
19 #define AC 0x8 /* ALU fixed-point carry */
20 #define AS 0x10 /* ALU X input sign */
21 #define AI 0x20 /* ALU floating-point invalid operation */
22 #define MN 0x40 /* Multiplier result negative */
23 #define MV 0x80 /* Multiplier overflow */
24 #define MU 0x100 /* Multiplier underflow */
25 #define MI 0x200 /* Multiplier floating-point invalid operation */
26 #define AF 0x400
27 #define SV 0x800 /* Shifter overflow */
28 #define SZ 0x1000 /* Shifter result zero */
29 #define SS 0x2000 /* Shifter input sign */
30 #define BTF 0x40000 /* Bit Test Flag */
31 #define FLG0 0x80000 /* FLAG0 */
32 #define FLG1 0x100000 /* FLAG1 */
33 #define FLG2 0x200000 /* FLAG2 */
34 #define FLG3 0x400000 /* FLAG3 */
35
36 #define REG_PC 0x63
37 #define REG_PCSTK 0x64
38 #define REG_PCSTKP 0x65
39 #define REG_LADDR 0x66
40 #define REG_CURLCNTR 0x67
41 #define REG_LCNTR 0x68
42 #define REG_USTAT1 0x70
43 #define REG_USTAT2 0x71
44 #define REG_IRPTL 0x79
45 #define REG_MODE2 0x7a
46 #define REG_MODE1 0x7b
47 #define REG_ASTAT 0x7c
48 #define REG_IMASK 0x7d
49 #define REG_STKY 0x7e
50 #define REG_IMASKP 0x7f
51
52
53
54 #define REG(x) (m_core->r[x].r)
55 #define FREG(x) (m_core->r[x].f)
56
57 #define UPDATE_CIRCULAR_BUFFER_PM(x) \
58 { \
59 if (PM_REG_L(x) != 0) \
60 { \
61 if (PM_REG_I(x) > PM_REG_B(x)+PM_REG_L(x)) \
62 { \
63 PM_REG_I(x) -= PM_REG_L(x); \
64 } \
65 else if (PM_REG_I(x) < PM_REG_B(x)) \
66 { \
67 PM_REG_I(x) += PM_REG_L(x); \
68 } \
69 } \
70 }
71
72 #define UPDATE_CIRCULAR_BUFFER_DM(x) \
73 { \
74 if (DM_REG_L(x) != 0) \
75 { \
76 if (DM_REG_I(x) > DM_REG_B(x)+DM_REG_L(x)) \
77 { \
78 DM_REG_I(x) -= DM_REG_L(x); \
79 } \
80 else if (DM_REG_I(x) < DM_REG_B(x)) \
81 { \
82 DM_REG_I(x) += DM_REG_L(x); \
83 } \
84 } \
85 }
86
87
88 /*****************************************************************************/
89
add_systemreg_write_latency_effect(int sysreg,uint32_t data,uint32_t prev_data)90 void adsp21062_device::add_systemreg_write_latency_effect(int sysreg, uint32_t data, uint32_t prev_data)
91 {
92 if (m_core->systemreg_latency_cycles > 0)
93 {
94 //fatalerror("SHARC: add_systemreg_write_latency_effect: already scheduled! (reg: %02X, data: %08X, PC: %08X)\n", systemreg_latency_reg, systemreg_latency_data, m_core->pc);
95 systemreg_write_latency_effect();
96 }
97
98 m_core->systemreg_latency_cycles = 2;
99 m_core->systemreg_latency_reg = sysreg;
100 m_core->systemreg_latency_data = data;
101 m_core->systemreg_previous_data = prev_data;
102 }
103
swap_register(uint32_t * a,uint32_t * b)104 void adsp21062_device::swap_register(uint32_t *a, uint32_t *b)
105 {
106 uint32_t temp = *a;
107 *a = *b;
108 *b = temp;
109 }
110
systemreg_write_latency_effect()111 void adsp21062_device::systemreg_write_latency_effect()
112 {
113 int i;
114 uint32_t data = m_core->systemreg_latency_data;
115 uint32_t old_data = m_core->systemreg_previous_data;
116
117 switch(m_core->systemreg_latency_reg)
118 {
119 case 0xb: /* MODE1 */
120 {
121 uint32_t oldreg = old_data;
122 m_core->mode1 = data;
123
124 if ((data & 0x1) != (oldreg & 0x1))
125 {
126 fatalerror("SHARC: systemreg_latency_op: enable I8 bit-reversing\n");
127 }
128 if ((data & 0x2) != (oldreg & 0x2))
129 {
130 fatalerror("SHARC: systemreg_latency_op: enable I0 bit-reversing\n");
131 }
132 if ((data & 0x4) != (oldreg & 0x4))
133 {
134 fatalerror("SHARC: systemreg_latency_op: enable MR alternate\n");
135 }
136
137 if ((data & 0x8) != (oldreg & 0x8)) /* Switch DAG1 7-4 */
138 {
139 swap_register(&m_core->dag1.i[4], &m_core->dag1_alt.i[4]);
140 swap_register(&m_core->dag1.i[5], &m_core->dag1_alt.i[5]);
141 swap_register(&m_core->dag1.i[6], &m_core->dag1_alt.i[6]);
142 swap_register(&m_core->dag1.i[7], &m_core->dag1_alt.i[7]);
143 swap_register(&m_core->dag1.m[4], &m_core->dag1_alt.m[4]);
144 swap_register(&m_core->dag1.m[5], &m_core->dag1_alt.m[5]);
145 swap_register(&m_core->dag1.m[6], &m_core->dag1_alt.m[6]);
146 swap_register(&m_core->dag1.m[7], &m_core->dag1_alt.m[7]);
147 swap_register(&m_core->dag1.l[4], &m_core->dag1_alt.l[4]);
148 swap_register(&m_core->dag1.l[5], &m_core->dag1_alt.l[5]);
149 swap_register(&m_core->dag1.l[6], &m_core->dag1_alt.l[6]);
150 swap_register(&m_core->dag1.l[7], &m_core->dag1_alt.l[7]);
151 swap_register(&m_core->dag1.b[4], &m_core->dag1_alt.b[4]);
152 swap_register(&m_core->dag1.b[5], &m_core->dag1_alt.b[5]);
153 swap_register(&m_core->dag1.b[6], &m_core->dag1_alt.b[6]);
154 swap_register(&m_core->dag1.b[7], &m_core->dag1_alt.b[7]);
155 }
156 if ((data & 0x10) != (oldreg & 0x10)) /* Switch DAG1 3-0 */
157 {
158 swap_register(&m_core->dag1.i[0], &m_core->dag1_alt.i[0]);
159 swap_register(&m_core->dag1.i[1], &m_core->dag1_alt.i[1]);
160 swap_register(&m_core->dag1.i[2], &m_core->dag1_alt.i[2]);
161 swap_register(&m_core->dag1.i[3], &m_core->dag1_alt.i[3]);
162 swap_register(&m_core->dag1.m[0], &m_core->dag1_alt.m[0]);
163 swap_register(&m_core->dag1.m[1], &m_core->dag1_alt.m[1]);
164 swap_register(&m_core->dag1.m[2], &m_core->dag1_alt.m[2]);
165 swap_register(&m_core->dag1.m[3], &m_core->dag1_alt.m[3]);
166 swap_register(&m_core->dag1.l[0], &m_core->dag1_alt.l[0]);
167 swap_register(&m_core->dag1.l[1], &m_core->dag1_alt.l[1]);
168 swap_register(&m_core->dag1.l[2], &m_core->dag1_alt.l[2]);
169 swap_register(&m_core->dag1.l[3], &m_core->dag1_alt.l[3]);
170 swap_register(&m_core->dag1.b[0], &m_core->dag1_alt.b[0]);
171 swap_register(&m_core->dag1.b[1], &m_core->dag1_alt.b[1]);
172 swap_register(&m_core->dag1.b[2], &m_core->dag1_alt.b[2]);
173 swap_register(&m_core->dag1.b[3], &m_core->dag1_alt.b[3]);
174 }
175 if ((data & 0x20) != (oldreg & 0x20)) /* Switch DAG2 15-12 */
176 {
177 swap_register(&m_core->dag2.i[4], &m_core->dag2_alt.i[4]);
178 swap_register(&m_core->dag2.i[5], &m_core->dag2_alt.i[5]);
179 swap_register(&m_core->dag2.i[6], &m_core->dag2_alt.i[6]);
180 swap_register(&m_core->dag2.i[7], &m_core->dag2_alt.i[7]);
181 swap_register(&m_core->dag2.m[4], &m_core->dag2_alt.m[4]);
182 swap_register(&m_core->dag2.m[5], &m_core->dag2_alt.m[5]);
183 swap_register(&m_core->dag2.m[6], &m_core->dag2_alt.m[6]);
184 swap_register(&m_core->dag2.m[7], &m_core->dag2_alt.m[7]);
185 swap_register(&m_core->dag2.l[4], &m_core->dag2_alt.l[4]);
186 swap_register(&m_core->dag2.l[5], &m_core->dag2_alt.l[5]);
187 swap_register(&m_core->dag2.l[6], &m_core->dag2_alt.l[6]);
188 swap_register(&m_core->dag2.l[7], &m_core->dag2_alt.l[7]);
189 swap_register(&m_core->dag2.b[4], &m_core->dag2_alt.b[4]);
190 swap_register(&m_core->dag2.b[5], &m_core->dag2_alt.b[5]);
191 swap_register(&m_core->dag2.b[6], &m_core->dag2_alt.b[6]);
192 swap_register(&m_core->dag2.b[7], &m_core->dag2_alt.b[7]);
193 }
194 if ((data & 0x40) != (oldreg & 0x40)) /* Switch DAG2 11-8 */
195 {
196 swap_register(&m_core->dag2.i[0], &m_core->dag2_alt.i[0]);
197 swap_register(&m_core->dag2.i[1], &m_core->dag2_alt.i[1]);
198 swap_register(&m_core->dag2.i[2], &m_core->dag2_alt.i[2]);
199 swap_register(&m_core->dag2.i[3], &m_core->dag2_alt.i[3]);
200 swap_register(&m_core->dag2.m[0], &m_core->dag2_alt.m[0]);
201 swap_register(&m_core->dag2.m[1], &m_core->dag2_alt.m[1]);
202 swap_register(&m_core->dag2.m[2], &m_core->dag2_alt.m[2]);
203 swap_register(&m_core->dag2.m[3], &m_core->dag2_alt.m[3]);
204 swap_register(&m_core->dag2.l[0], &m_core->dag2_alt.l[0]);
205 swap_register(&m_core->dag2.l[1], &m_core->dag2_alt.l[1]);
206 swap_register(&m_core->dag2.l[2], &m_core->dag2_alt.l[2]);
207 swap_register(&m_core->dag2.l[3], &m_core->dag2_alt.l[3]);
208 swap_register(&m_core->dag2.b[0], &m_core->dag2_alt.b[0]);
209 swap_register(&m_core->dag2.b[1], &m_core->dag2_alt.b[1]);
210 swap_register(&m_core->dag2.b[2], &m_core->dag2_alt.b[2]);
211 swap_register(&m_core->dag2.b[3], &m_core->dag2_alt.b[3]);
212 }
213 if ((data & 0x80) != (oldreg & 0x80))
214 {
215 for (i=8; i<16; i++)
216 swap_register((uint32_t*)&m_core->r[i].r, (uint32_t*)&m_core->reg_alt[i].r);
217 }
218 if ((data & 0x400) != (oldreg & 0x400))
219 {
220 for (i=0; i<8; i++)
221 swap_register((uint32_t*)&m_core->r[i].r, (uint32_t*)&m_core->reg_alt[i].r);
222 }
223 break;
224 }
225 default: fatalerror("SHARC: systemreg_latency_op: unknown register %02X at %08X\n", m_core->systemreg_latency_reg, m_core->pc);
226 }
227
228 m_core->systemreg_latency_reg = -1;
229 }
230
GET_UREG(int ureg)231 uint32_t adsp21062_device::GET_UREG(int ureg)
232 {
233 int reg = ureg & 0xf;
234 switch((ureg >> 4) & 0xf)
235 {
236 case 0x0: /* R0 - R15 */
237 {
238 return m_core->r[reg].r;
239 }
240
241 case 0x1:
242 {
243 if (reg & 0x8) /* I8 - I15 */
244 {
245 return m_core->dag2.i[reg & 0x7];
246 }
247 else /* I0 - I7 */
248 {
249 return m_core->dag1.i[reg & 0x7];
250 }
251 }
252
253 case 0x2:
254 {
255 if (reg & 0x8) /* M8 - M15 */
256 {
257 int32_t r = m_core->dag2.m[reg & 0x7];
258 if (r & 0x800000) r |= 0xff000000;
259
260 return r;
261 }
262 else /* M0 - M7 */
263 {
264 return m_core->dag1.m[reg & 0x7];
265 }
266 }
267
268 case 0x3:
269 {
270 if (reg & 0x8) /* L8 - L15 */
271 {
272 return m_core->dag2.l[reg & 0x7];
273 }
274 else /* L0 - L7 */
275 {
276 return m_core->dag1.l[reg & 0x7];
277 }
278 }
279
280 case 0x4:
281 {
282 if (reg & 0x8) /* B8 - B15 */
283 {
284 return m_core->dag2.b[reg & 0x7];
285 }
286 else /* B0 - B7 */
287 {
288 return m_core->dag1.b[reg & 0x7];
289 }
290 }
291
292 case 0x6:
293 {
294 switch(reg)
295 {
296 case 0x4: return m_core->pcstack[m_core->pcstkp]; /* PCSTK */
297 default: fatalerror("SHARC: GET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc);
298 }
299 break;
300 }
301
302 case 0x7:
303 {
304 switch(reg)
305 {
306 case 0x0: return m_core->ustat1; /* USTAT1 */
307 case 0x1: return m_core->ustat2; /* USTAT2 */
308 case 0x9: return m_core->irptl; /* IRPTL */
309 case 0xa: return m_core->mode2; /* MODE2 */
310 case 0xb: return m_core->mode1; /* MODE1 */
311 case 0xc: /* ASTAT */
312 {
313 uint32_t r = m_core->astat;
314 r &= ~0x00780000;
315 r |= (m_core->flag[0] << 19);
316 r |= (m_core->flag[1] << 20);
317 r |= (m_core->flag[2] << 21);
318 r |= (m_core->flag[3] << 22);
319 return r;
320 }
321 case 0xd: return m_core->imask; /* IMASK */
322 case 0xe: return m_core->stky; /* STKY */
323 default: fatalerror("SHARC: GET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc);
324 }
325 break;
326 }
327
328 case 0xd:
329 {
330 switch(reg)
331 {
332 /* PX needs to be handled separately if the whole 48 bits are needed */
333 case 0xb: return (uint32_t)(m_core->px); /* PX */
334 case 0xc: return (uint16_t)(m_core->px); /* PX1 */
335 case 0xd: return (uint32_t)(m_core->px >> 16); /* PX2 */
336 default: fatalerror("SHARC: GET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc);
337 }
338 break;
339 }
340
341 default: fatalerror("SHARC: GET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc);
342 }
343 }
344
SET_UREG(int ureg,uint32_t data)345 void adsp21062_device::SET_UREG(int ureg, uint32_t data)
346 {
347 int reg = ureg & 0xf;
348 switch((ureg >> 4) & 0xf)
349 {
350 case 0x0: /* R0 - R15 */
351 m_core->r[reg].r = data;
352 break;
353
354 case 0x1:
355 if (reg & 0x8) /* I8 - I15 */
356 {
357 m_core->dag2.i[reg & 0x7] = data;
358 }
359 else /* I0 - I7 */
360 {
361 m_core->dag1.i[reg & 0x7] = data;
362 }
363 break;
364
365 case 0x2:
366 if (reg & 0x8) /* M8 - M15 */
367 {
368 m_core->dag2.m[reg & 0x7] = data;
369 }
370 else /* M0 - M7 */
371 {
372 m_core->dag1.m[reg & 0x7] = data;
373 }
374 break;
375
376 case 0x3:
377 if (reg & 0x8) /* L8 - L15 */
378 {
379 m_core->dag2.l[reg & 0x7] = data;
380 }
381 else /* L0 - L7 */
382 {
383 m_core->dag1.l[reg & 0x7] = data;
384 }
385 break;
386
387 case 0x4:
388 // Note: loading B also loads the same value in I
389 if (reg & 0x8) /* B8 - B15 */
390 {
391 m_core->dag2.b[reg & 0x7] = data;
392 m_core->dag2.i[reg & 0x7] = data;
393 }
394 else /* B0 - B7 */
395 {
396 m_core->dag1.b[reg & 0x7] = data;
397 m_core->dag1.i[reg & 0x7] = data;
398 }
399 break;
400
401 case 0x6:
402 switch (reg)
403 {
404 case 0x5: m_core->pcstkp = data; break; /* PCSTKP */
405 case 0x7: m_core->curlcntr = data; break; /* CURLCNTR (Zero Gunner 2B) */
406 case 0x8: m_core->lcntr = data; break; /* LCNTR */
407 default: fatalerror("SHARC: SET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc);
408 }
409 break;
410
411 case 0x7: /* system regs */
412 switch(reg)
413 {
414 case 0x0: m_core->ustat1 = data; break; /* USTAT1 */
415 case 0x1: m_core->ustat2 = data; break; /* USTAT2 */
416
417 case 0x9: m_core->irptl = data; break; /* IRPTL */
418 case 0xa: m_core->mode2 = data; break; /* MODE2 */
419
420 case 0xb: /* MODE1 */
421 {
422 add_systemreg_write_latency_effect(reg, data, m_core->mode1);
423 m_core->mode1 = data;
424 break;
425 }
426
427 case 0xc: m_core->astat = data; break; /* ASTAT */
428
429 case 0xd: /* IMASK */
430 {
431 check_interrupts();
432 m_core->imask = data;
433 break;
434 }
435
436 case 0xe: m_core->stky = data; break; /* STKY */
437 default: fatalerror("SHARC: SET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc);
438 }
439 break;
440
441 case 0xd:
442 switch(reg)
443 {
444 case 0xc: m_core->px &= 0xffffffffffff0000U; m_core->px |= (data & 0xffff); break; /* PX1 */
445 case 0xd: m_core->px &= 0x000000000000ffffU; m_core->px |= (uint64_t)data << 16; break; /* PX2 */
446 default: fatalerror("SHARC: SET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc);
447 }
448 break;
449
450 default: fatalerror("SHARC: SET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc);
451 }
452 }
453
454 /*****************************************************************************/
455 #define SET_FLAG_SV_LSHIFT(x, shift) if((x) & ((uint32_t)0xffffffff << shift)) m_core->astat |= SV
456 #define SET_FLAG_SV_RSHIFT(x, shift) if((x) & ((uint32_t)0xffffffff >> shift)) m_core->astat |= SV
457
458 #define SET_FLAG_SZ(x) if((x) == 0) m_core->astat |= SZ
459
460 #define MAKE_EXTRACT_MASK(start_bit, length) ((0xffffffff << start_bit) & (((uint32_t)0xffffffff) >> (32 - (start_bit + length))))
461
SHIFT_OPERATION_IMM(int shiftop,int data,int rn,int rx)462 void adsp21062_device::SHIFT_OPERATION_IMM(int shiftop, int data, int rn, int rx)
463 {
464 int8_t shift = data & 0xff;
465 int bit = data & 0x3f;
466 int len = (data >> 6) & 0x3f;
467
468 m_core->astat &= ~(SZ|SV|SS);
469
470 switch(shiftop)
471 {
472 case 0x00: /* LSHIFT Rx BY <data8>*/
473 {
474 if(shift < 0) {
475 REG(rn) = (shift > -32 ) ? ((uint32_t)REG(rx) >> -shift) : 0;
476 } else {
477 REG(rn) = (shift < 32) ? ((uint32_t)REG(rx) << shift) : 0;
478 if (shift > 0)
479 {
480 m_core->astat |= SV;
481 }
482 }
483 SET_FLAG_SZ(REG(rn));
484 break;
485 }
486
487 case 0x01: /* ASHIFT Rx BY <data8> */
488 {
489 if (shift < 0)
490 {
491 REG(rn) = (shift > -32) ? ((int32_t)REG(rx) >> -shift) : ((REG(rx) & 0x80000000) ? 0xffffffff : 0);
492 }
493 else
494 {
495 REG(rn) = (shift < 32) ? ((int32_t)REG(rx) << shift) : 0;
496 if (shift > 0)
497 {
498 m_core->astat |= SV;
499 }
500 }
501 SET_FLAG_SZ(REG(rn));
502 break;
503 }
504
505 case 0x02: /* ROT Rx BY <data8> */
506 {
507 if (shift < 0)
508 {
509 int s = (-shift) & 0x1f;
510 REG(rn) = (((uint32_t)REG(rx) >> s) & ((uint32_t)(0xffffffff) >> s)) |
511 (((uint32_t)REG(rx) << (32-s)) & ((uint32_t)(0xffffffff) << (32-s)));
512 }
513 else
514 {
515 int s = shift & 0x1f;
516 REG(rn) = (((uint32_t)REG(rx) << s) & ((uint32_t)(0xffffffff) << s)) |
517 (((uint32_t)REG(rx) >> (32-s)) & ((uint32_t)(0xffffffff) >> (32-s)));
518 }
519 SET_FLAG_SZ(REG(rn));
520 break;
521 }
522
523 case 0x08: /* Rn = Rn OR LSHIFT Rx BY <data8> */
524 {
525 uint32_t r = 0;
526 if(shift < 0) {
527 r = (shift > -32 ) ? ((uint32_t)REG(rx) >> -shift) : 0;
528 } else {
529 r = (shift < 32) ? ((uint32_t)REG(rx) << shift) : 0;
530 if (shift > 0)
531 {
532 m_core->astat |= SV;
533 }
534 }
535
536 SET_FLAG_SZ(r);
537
538 REG(rn) = REG(rn) | r;
539 break;
540 }
541
542 case 0x10: /* FEXT Rx BY <bit6>:<len6> */
543 {
544 uint32_t ext = REG(rx) & MAKE_EXTRACT_MASK(bit, len);
545 REG(rn) = ext >> bit;
546
547 SET_FLAG_SZ(REG(rn));
548 if (bit+len > 32)
549 {
550 m_core->astat |= SV;
551 }
552 break;
553 }
554
555 case 0x11: /* Rn = Rn FDEP Rx BY <bit6>:<len6> */
556 {
557 uint32_t ext = REG(rx) & MAKE_EXTRACT_MASK(0, len);
558
559 REG(rn) = ext << bit;
560
561 SET_FLAG_SZ(REG(rn));
562 if (bit+len > 32)
563 {
564 m_core->astat |= SV;
565 }
566 break;
567 }
568
569 case 0x12: /* FEXT Rx BY <bit6>:<len6> (Sign Extended) */
570 {
571 uint32_t ext = (REG(rx) & MAKE_EXTRACT_MASK(bit, len)) >> bit;
572 if (ext & (1 << (len-1))) {
573 ext |= (uint32_t)0xffffffff << (len-1);
574 }
575 REG(rn) = ext;
576
577 SET_FLAG_SZ(REG(rn));
578 if (bit+len > 32)
579 {
580 m_core->astat |= SV;
581 }
582 break;
583 }
584
585 case 0x13: /* FDEP Rx BY Ry <bit6>:<len6> (Sign Extended) */
586 {
587 uint32_t ext = REG(rx) & MAKE_EXTRACT_MASK(0, len);
588 if (ext & (1 << (len-1))) {
589 ext |= (uint32_t)0xffffffff << (len-1);
590 }
591 REG(rn) = ext << bit;
592
593 SET_FLAG_SZ(REG(rn));
594 if (bit+len > 32)
595 {
596 m_core->astat |= SV;
597 }
598 break;
599 }
600
601 case 0x19: /* Rn = Rn OR FDEP Rx BY <bit6>:<len6> */
602 {
603 uint32_t ext = REG(rx) & MAKE_EXTRACT_MASK(0, len);
604
605 REG(rn) |= ext << bit;
606
607 SET_FLAG_SZ(REG(rn));
608 if (bit+len > 32)
609 {
610 m_core->astat |= SV;
611 }
612 break;
613 }
614
615 case 0x30: /* BSET Rx BY <data8> */
616 {
617 REG(rn) = REG(rx);
618 if (data >= 0 && data < 32)
619 {
620 REG(rn) |= (1 << data);
621 }
622 else
623 {
624 m_core->astat |= SV;
625 }
626 SET_FLAG_SZ(REG(rn));
627 break;
628 }
629
630 case 0x31: /* BCLR Rx BY <data8> */
631 {
632 REG(rn) = REG(rx);
633 if (data >= 0 && data < 32)
634 {
635 REG(rn) &= ~(1 << data);
636 }
637 else
638 {
639 m_core->astat |= SV;
640 }
641 SET_FLAG_SZ(REG(rn));
642 break;
643 }
644
645 case 0x32: /* BTGL Rx BY <data8> */
646 {
647 REG(rn) = REG(rx);
648 if (data >= 0 && data < 32)
649 {
650 REG(rn) ^= (1 << data);
651 }
652 else
653 {
654 m_core->astat |= SV;
655 }
656 SET_FLAG_SZ(REG(rn));
657 break;
658 }
659
660 case 0x33: /* BTST Rx BY <data8> */
661 {
662 if (data < 32)
663 {
664 uint32_t r = REG(rx) & (1 << data);
665
666 SET_FLAG_SZ(r);
667 }
668 else
669 {
670 m_core->astat |= SZ | SV;
671 }
672 break;
673 }
674
675 default: fatalerror("SHARC: unimplemented shift operation %02X at %08X\n", shiftop, m_core->pc);
676 }
677 }
678
679 #include "compute.hxx"
680
COMPUTE(uint32_t opcode)681 void adsp21062_device::COMPUTE(uint32_t opcode)
682 {
683 int multiop;
684 int op = (opcode >> 12) & 0xff;
685 int cu = (opcode >> 20) & 0x3;
686 int rn = (opcode >> 8) & 0xf;
687 int rx = (opcode >> 4) & 0xf;
688 int ry = (opcode >> 0) & 0xf;
689 //int rs = (opcode >> 12) & 0xf;
690 //int ra = rn;
691 //int rm = rs;
692
693 if(opcode & 0x400000) /* Multi-function opcode */
694 {
695 int fm = (opcode >> 12) & 0xf;
696 int fa = (opcode >> 8) & 0xf;
697 int fxm = (opcode >> 6) & 0x3; // registers 0 - 3
698 int fym = ((opcode >> 4) & 0x3) + 4; // registers 4 - 7
699 int fxa = ((opcode >> 2) & 0x3) + 8; // registers 8 - 11
700 int fya = (opcode & 0x3) + 12; // registers 12 - 15
701
702 multiop = (opcode >> 16) & 0x3f;
703 switch(multiop)
704 {
705 case 0x00: compute_multi_mr_to_reg(op & 0xf, rn); break;
706 case 0x01: compute_multi_reg_to_mr(op & 0xf, rn); break;
707
708 case 0x04: /* Rm = Rxm * Rym (SSFR), Ra = Rxa + Rya */
709 {
710 compute_mul_ssfr_add(fm, fxm, fym, fa, fxa, fya);
711 break;
712 }
713
714 case 0x05: /* Rm = Rxm * Rym (SSFR), Ra = Rxa - Rya */
715 {
716 compute_mul_ssfr_sub(fm, fxm, fym, fa, fxa, fya);
717 break;
718 }
719
720 case 0x18: /* Fm = Fxm * Fym, Fa = Fxa + Fya */
721 {
722 compute_fmul_fadd(fm, fxm, fym, fa, fxa, fya);
723 break;
724 }
725
726 case 0x19: /* Fm = Fxm * Fym, Fa = Fxa - Fya */
727 {
728 compute_fmul_fsub(fm, fxm, fym, fa, fxa, fya);
729 break;
730 }
731
732 case 0x1a: /* Fm = Fxm * Fym, Fa = FLOAT Fxa BY Fya */
733 {
734 compute_fmul_float_scaled(fm, fxm, fym, fa, fxa, fya);
735 break;
736 }
737
738 case 0x1b: /* Fm = Fxm * Fym, Fa = FIX Fxa BY Fya */
739 {
740 compute_fmul_fix_scaled(fm, fxm, fym, fa, fxa, fya);
741 break;
742 }
743
744 // TODO: verify this (last bronx)
745 case 0x1c:
746 {
747 compute_fmul_avg(fm, fxm, fym, fa, fxa, fya);
748 break;
749 }
750
751 // TODO: verify this (Gunblade NY Score Attack Remix mode)
752 case 0x1d:
753 {
754 compute_fmul_abs(fm, fxm, fym, fa, fxa, fya);
755 break;
756 }
757
758 case 0x1e: /* Fm = Fxm * Fym, Fa = MAX(Fxa, Fya) */
759 {
760 compute_fmul_fmax(fm, fxm, fym, fa, fxa, fya);
761 break;
762 }
763
764 case 0x1f: /* Fm = Fxm * Fym, Fa = MIN(Fxa, Fya) */
765 {
766 compute_fmul_fmin(fm, fxm, fym, fa, fxa, fya);
767 break;
768 }
769
770 case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
771 case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
772 {
773 /* Parallel Multiplier & Dual Add/Subtract */
774 /* Floating-point */
775 int fs = (opcode >> 16) & 0xf;
776 compute_fmul_dual_fadd_fsub(fm, fxm, fym, fa, fs, fxa, fya);
777 break;
778 }
779
780 default:
781 fatalerror("SHARC: compute: multi-function opcode %02X not implemented ! (%08X, %08X)\n", multiop, m_core->pc, opcode);
782 break;
783 }
784 }
785 else /* Single-function opcode */
786 {
787 switch(cu)
788 {
789 /* ALU operations */
790 case 0:
791 {
792 switch(op)
793 {
794 case 0x01: compute_add(rn, rx, ry); break;
795 case 0x02: compute_sub(rn, rx, ry); break;
796 case 0x05: compute_add_ci(rn, rx, ry); break;
797 case 0x06: compute_sub_ci(rn, rx, ry); break;
798 case 0x0a: compute_comp(rx, ry); break;
799 case 0x21: compute_pass(rn, rx); break;
800 case 0x22: compute_neg(rn, rx); break;
801 case 0x29: compute_inc(rn, rx); break;
802 case 0x2a: compute_dec(rn, rx); break;
803 case 0x40: compute_and(rn, rx, ry); break;
804 case 0x41: compute_or(rn, rx, ry); break;
805 case 0x42: compute_xor(rn, rx, ry); break;
806 case 0x43: compute_not(rn, rx); break;
807 case 0x61: compute_min(rn, rx, ry); break;
808 case 0x62: compute_max(rn, rx, ry); break;
809 case 0x81: compute_fadd(rn, rx, ry); break;
810 case 0x82: compute_fsub(rn, rx, ry); break;
811 case 0x89: compute_favg(rn, rx, ry); break;
812 case 0x8a: compute_fcomp(rx, ry); break;
813 case 0x91: compute_fabs_plus(rn, rx, ry); break;
814 case 0xa1: compute_fpass(rn, rx); break;
815 case 0xa2: compute_fneg(rn, rx); break;
816 case 0xb0: compute_fabs(rn, rx); break;
817 case 0xbd: compute_scalb(rn, rx, ry); break;
818 case 0xc1: compute_logb(rn, rx); break;
819 case 0xc4: compute_recips(rn, rx); break;
820 case 0xc5: compute_rsqrts(rn, rx); break;
821 case 0xc9: compute_fix(rn, rx); break;
822 case 0xca: compute_float(rn, rx); break;
823 case 0xd9: compute_fix_scaled(rn, rx, ry); break;
824 case 0xda: compute_float_scaled(rn, rx, ry); break;
825 case 0xe0: compute_fcopysign(rn, rx, ry); break;
826 case 0xe1: compute_fmin(rn, rx, ry); break;
827 case 0xe2: compute_fmax(rn, rx, ry); break;
828 case 0xe3: compute_fclip(rn, rx, ry); break;
829
830 case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
831 case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
832 {
833 /* Fixed-point Dual Add/Subtract */
834 int rs = (opcode >> 12) & 0xf;
835 int ra = (opcode >> 8) & 0xf;
836 compute_dual_add_sub(ra, rs, rx, ry);
837 break;
838 }
839
840 case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7:
841 case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff:
842 {
843 /* Floating-point Dual Add/Subtract */
844 int rs = (opcode >> 12) & 0xf;
845 int ra = (opcode >> 8) & 0xf;
846 compute_dual_fadd_fsub(ra, rs, rx, ry);
847 break;
848 }
849
850 default: fatalerror("SHARC: compute: unimplemented ALU operation %02X (%08X, %08X)\n", op, m_core->pc, opcode);
851 }
852 break;
853 }
854
855
856 /* Multiplier operations */
857 case 1:
858 {
859 switch(op)
860 {
861 case 0x14: m_core->mrf = 0; break;
862 case 0x16: m_core->mrb = 0; break;
863
864 case 0x30: compute_fmul(rn, rx, ry); break;
865 case 0x40: compute_mul_uuin(rn, rx, ry); break;
866 case 0x70: compute_mul_ssin(rn, rx, ry); break;
867
868 case 0xb0: REG(rn) = compute_mrf_plus_mul_ssin(rx, ry); break;
869 case 0xb2: REG(rn) = compute_mrb_plus_mul_ssin(rx, ry); break;
870
871 default:
872 fatalerror("SHARC: compute: multiplier operation %02X not implemented ! (%08X, %08X)\n", op, m_core->pc, opcode);
873 break;
874 }
875 break;
876 }
877
878
879 /* Shifter operations */
880 case 2:
881 {
882 m_core->astat &= ~(SZ|SV|SS);
883
884 op >>= 2;
885 switch(op)
886 {
887 case 0x00: /* LSHIFT Rx BY Ry*/
888 {
889 int shift = REG(ry);
890 if(shift < 0)
891 {
892 REG(rn) = (shift > -32 ) ? ((uint32_t)REG(rx) >> -shift) : 0;
893 }
894 else
895 {
896 REG(rn) = (shift < 32) ? ((uint32_t)REG(rx) << shift) : 0;
897 if (shift > 0)
898 {
899 m_core->astat |= SV;
900 }
901 }
902 SET_FLAG_SZ(REG(rn));
903 break;
904 }
905
906 case 0x02: /* ROT Rx BY Ry */
907 {
908 int shift = REG(ry);
909 if (shift < 0)
910 {
911 int s = (-shift) & 0x1f;
912 REG(rn) = (((uint32_t)REG(rx) >> s) & ((uint32_t)(0xffffffff) >> s)) |
913 (((uint32_t)REG(rx) << (32-s)) & ((uint32_t)(0xffffffff) << (32-s)));
914 }
915 else
916 {
917 int s = shift & 0x1f;
918 REG(rn) = (((uint32_t)REG(rx) << s) & ((uint32_t)(0xffffffff) << s)) |
919 (((uint32_t)REG(rx) >> (32-s)) & ((uint32_t)(0xffffffff) >> (32-s)));
920 if (shift > 0)
921 {
922 m_core->astat |= SV;
923 }
924 }
925 SET_FLAG_SZ(REG(rn));
926 break;
927 }
928
929 case 0x08: /* Rn = Rn OR LSHIFT Rx BY Ry*/
930 {
931 int8_t shift = REG(ry);
932 if(shift < 0) {
933 REG(rn) = REG(rn) | ((shift > -32 ) ? (REG(rx) >> -shift) : 0);
934 } else {
935 REG(rn) = REG(rn) | ((shift < 32) ? (REG(rx) << shift) : 0);
936 if (shift > 0)
937 {
938 m_core->astat |= SV;
939 }
940 }
941 SET_FLAG_SZ(REG(rn));
942 break;
943 }
944
945 case 0x10: /* FEXT Rx BY Ry */
946 {
947 int bit = REG(ry) & 0x3f;
948 int len = (REG(ry) >> 6) & 0x3f;
949 uint32_t ext = REG(rx) & MAKE_EXTRACT_MASK(bit, len);
950 REG(rn) = ext >> bit;
951
952 SET_FLAG_SZ(REG(rn));
953 if (bit+len > 32)
954 {
955 m_core->astat |= SV;
956 }
957 break;
958 }
959
960 case 0x12: /* FEXT Rx BY Ry (Sign Extended) */
961 {
962 int bit = REG(ry) & 0x3f;
963 int len = (REG(ry) >> 6) & 0x3f;
964 uint32_t ext = (REG(rx) & MAKE_EXTRACT_MASK(bit, len)) >> bit;
965 if (ext & (1 << (len-1))) {
966 ext |= (uint32_t)0xffffffff << (len-1);
967 }
968 REG(rn) = ext;
969
970 SET_FLAG_SZ(REG(rn));
971 if (bit+len > 32)
972 {
973 m_core->astat |= SV;
974 }
975 break;
976 }
977
978 case 0x19: /* Rn = Rn OR FDEP Rx BY Ry */
979 {
980 int bit = REG(ry) & 0x3f;
981 int len = (REG(ry) >> 6) & 0x3f;
982 uint32_t ext = REG(rx) & MAKE_EXTRACT_MASK(0, len);
983
984 REG(rn) |= ext << bit;
985
986 SET_FLAG_SZ(REG(rn));
987 if (bit+len > 32)
988 {
989 m_core->astat |= SV;
990 }
991 break;
992 }
993
994 case 0x30: /* BSET Rx BY Ry */
995 {
996 uint32_t shift = REG(ry);
997 REG(rn) = REG(rx);
998 if (shift < 32)
999 {
1000 REG(rn) |= (1 << shift);
1001 }
1002 else
1003 {
1004 m_core->astat |= SV;
1005 }
1006 SET_FLAG_SZ(REG(rn));
1007 break;
1008 }
1009
1010 case 0x31: /* BCLR Rx BY Ry */
1011 {
1012 uint32_t shift = REG(ry);
1013 REG(rn) = REG(rx);
1014 if (shift < 32)
1015 {
1016 REG(rn) &= ~(1 << shift);
1017 }
1018 else
1019 {
1020 m_core->astat |= SV;
1021 }
1022 SET_FLAG_SZ(REG(rn));
1023 break;
1024 }
1025
1026 case 0x33: /* BTST Rx BY Ry */
1027 {
1028 uint32_t shift = REG(ry);
1029 if (shift < 32)
1030 {
1031 uint32_t r = REG(rx) & (1 << shift);
1032
1033 SET_FLAG_SZ(r);
1034 }
1035 else
1036 {
1037 m_core->astat |= SZ | SV;
1038 }
1039 break;
1040 }
1041
1042 default:
1043 fatalerror("SHARC: compute: shift operation %02X not implemented ! (%08X, %08X)\n", op, m_core->pc, opcode);
1044 }
1045 break;
1046 }
1047
1048 default:
1049 fatalerror("SHARC: compute: invalid single-function operation %02X\n", cu);
1050 }
1051 }
1052 }
1053
PUSH_PC(uint32_t pc)1054 void adsp21062_device::PUSH_PC(uint32_t pc)
1055 {
1056 m_core->pcstkp++;
1057 if(m_core->pcstkp >= 32)
1058 {
1059 fatalerror("SHARC: PC Stack overflow!\n");
1060 }
1061
1062 if (m_core->pcstkp == 0)
1063 {
1064 m_core->stky |= 0x400000;
1065 }
1066 else
1067 {
1068 m_core->stky &= ~0x400000;
1069 }
1070
1071 m_core->pcstk = pc;
1072 m_core->pcstack[m_core->pcstkp] = pc;
1073 }
1074
POP_PC()1075 uint32_t adsp21062_device::POP_PC()
1076 {
1077 m_core->pcstk = m_core->pcstack[m_core->pcstkp];
1078
1079 if(m_core->pcstkp == 0)
1080 {
1081 fatalerror("SHARC: PC Stack underflow!\n");
1082 }
1083
1084 m_core->pcstkp--;
1085
1086 if (m_core->pcstkp == 0)
1087 {
1088 m_core->stky |= 0x400000;
1089 }
1090 else
1091 {
1092 m_core->stky &= ~0x400000;
1093 }
1094
1095 return m_core->pcstk;
1096 }
1097
TOP_PC()1098 uint32_t adsp21062_device::TOP_PC()
1099 {
1100 return m_core->pcstack[m_core->pcstkp];
1101 }
1102
PUSH_LOOP(uint32_t addr,uint32_t code,uint32_t type,uint32_t count)1103 void adsp21062_device::PUSH_LOOP(uint32_t addr, uint32_t code, uint32_t type, uint32_t count)
1104 {
1105 m_core->lstkp++;
1106 if(m_core->lstkp >= 6)
1107 {
1108 fatalerror("SHARC: Loop Stack overflow!\n");
1109 }
1110
1111 if (m_core->lstkp == 0)
1112 {
1113 m_core->stky |= 0x4000000;
1114 }
1115 else
1116 {
1117 m_core->stky &= ~0x4000000;
1118 }
1119
1120 m_core->lcstack[m_core->lstkp] = count;
1121 m_core->lastack[m_core->lstkp] = (type << 30) | (code << 24) | addr;
1122 m_core->curlcntr = count;
1123
1124 m_core->laddr.addr = addr;
1125 m_core->laddr.code = code;
1126 m_core->laddr.loop_type = type;
1127 }
1128
POP_LOOP()1129 void adsp21062_device::POP_LOOP()
1130 {
1131 if(m_core->lstkp == 0)
1132 {
1133 fatalerror("SHARC: Loop Stack underflow!\n");
1134 }
1135
1136 m_core->lstkp--;
1137
1138 if (m_core->lstkp == 0)
1139 {
1140 m_core->stky |= 0x4000000;
1141 }
1142 else
1143 {
1144 m_core->stky &= ~0x4000000;
1145 }
1146
1147 m_core->curlcntr = m_core->lcstack[m_core->lstkp];
1148
1149 m_core->laddr.addr = m_core->lastack[m_core->lstkp] & 0xffffff;
1150 m_core->laddr.code = (m_core->lastack[m_core->lstkp] >> 24) & 0x1f;
1151 m_core->laddr.loop_type = (m_core->lastack[m_core->lstkp] >> 30) & 0x3;
1152 }
1153
PUSH_STATUS_STACK()1154 void adsp21062_device::PUSH_STATUS_STACK()
1155 {
1156 m_core->status_stkp++;
1157 if (m_core->status_stkp >= 5)
1158 {
1159 fatalerror("SHARC: Status stack overflow!\n");
1160 }
1161
1162 if (m_core->status_stkp == 0)
1163 {
1164 m_core->stky |= 0x1000000;
1165 }
1166 else
1167 {
1168 m_core->stky &= ~0x1000000;
1169 }
1170
1171 m_core->status_stack[m_core->status_stkp].mode1 = GET_UREG(REG_MODE1);
1172 m_core->status_stack[m_core->status_stkp].astat = GET_UREG(REG_ASTAT);
1173 }
1174
POP_STATUS_STACK()1175 void adsp21062_device::POP_STATUS_STACK()
1176 {
1177 SET_UREG(REG_MODE1, m_core->status_stack[m_core->status_stkp].mode1);
1178 SET_UREG(REG_ASTAT, m_core->status_stack[m_core->status_stkp].astat);
1179
1180 m_core->status_stkp--;
1181 if (m_core->status_stkp < 0)
1182 {
1183 fatalerror("SHARC: Status stack underflow!\n");
1184 }
1185
1186 if (m_core->status_stkp == 0)
1187 {
1188 m_core->stky |= 0x1000000;
1189 }
1190 else
1191 {
1192 m_core->stky &= ~0x1000000;
1193 }
1194 }
1195
IF_CONDITION_CODE(int cond)1196 int adsp21062_device::IF_CONDITION_CODE(int cond)
1197 {
1198 switch(cond)
1199 {
1200 case 0x00: return m_core->astat & AZ; /* EQ */
1201 case 0x01: return !(m_core->astat & AZ) && (m_core->astat & AN); /* LT */
1202 case 0x02: return (m_core->astat & AZ) || (m_core->astat & AN); /* LE */
1203 case 0x03: return (m_core->astat & AC); /* AC */
1204 case 0x04: return (m_core->astat & AV); /* AV */
1205 case 0x05: return (m_core->astat & MV); /* MV */
1206 case 0x06: return (m_core->astat & MN); /* MS */
1207 case 0x07: return (m_core->astat & SV); /* SV */
1208 case 0x08: return (m_core->astat & SZ); /* SZ */
1209 case 0x09: return (m_core->flag[0] != 0); /* FLAG0 */
1210 case 0x0a: return (m_core->flag[1] != 0); /* FLAG1 */
1211 case 0x0b: return (m_core->flag[2] != 0); /* FLAG2 */
1212 case 0x0c: return (m_core->flag[3] != 0); /* FLAG3 */
1213 case 0x0d: return (m_core->astat & BTF); /* TF */
1214 case 0x0e: return 0; /* BM */
1215 case 0x0f: return (m_core->curlcntr!=1); /* NOT LCE */
1216 case 0x10: return !(m_core->astat & AZ); /* NOT EQUAL */
1217 case 0x11: return (m_core->astat & AZ) || !(m_core->astat & AN); /* GE */
1218 case 0x12: return !(m_core->astat & AZ) && !(m_core->astat & AN); /* GT */
1219 case 0x13: return !(m_core->astat & AC); /* NOT AC */
1220 case 0x14: return !(m_core->astat & AV); /* NOT AV */
1221 case 0x15: return !(m_core->astat & MV); /* NOT MV */
1222 case 0x16: return !(m_core->astat & MN); /* NOT MS */
1223 case 0x17: return !(m_core->astat & SV); /* NOT SV */
1224 case 0x18: return !(m_core->astat & SZ); /* NOT SZ */
1225 case 0x19: return (m_core->flag[0] == 0); /* NOT FLAG0 */
1226 case 0x1a: return (m_core->flag[1] == 0); /* NOT FLAG1 */
1227 case 0x1b: return (m_core->flag[2] == 0); /* NOT FLAG2 */
1228 case 0x1c: return (m_core->flag[3] == 0); /* NOT FLAG3 */
1229 case 0x1d: return !(m_core->astat & BTF); /* NOT TF */
1230 case 0x1e: return 1; /* NOT BM */
1231 case 0x1f: return 1; /* TRUE */
1232 }
1233 return 1;
1234 }
1235
DO_CONDITION_CODE(int cond)1236 int adsp21062_device::DO_CONDITION_CODE(int cond)
1237 {
1238 switch(cond)
1239 {
1240 case 0x00: return m_core->astat & AZ; /* EQ */
1241 case 0x01: return !(m_core->astat & AZ) && (m_core->astat & AN); /* LT */
1242 case 0x02: return (m_core->astat & AZ) || (m_core->astat & AN); /* LE */
1243 case 0x03: return (m_core->astat & AC); /* AC */
1244 case 0x04: return (m_core->astat & AV); /* AV */
1245 case 0x05: return (m_core->astat & MV); /* MV */
1246 case 0x06: return (m_core->astat & MN); /* MS */
1247 case 0x07: return (m_core->astat & SV); /* SV */
1248 case 0x08: return (m_core->astat & SZ); /* SZ */
1249 case 0x09: return (m_core->flag[0] != 0); /* FLAG0 */
1250 case 0x0a: return (m_core->flag[1] != 0); /* FLAG1 */
1251 case 0x0b: return (m_core->flag[2] != 0); /* FLAG2 */
1252 case 0x0c: return (m_core->flag[3] != 0); /* FLAG3 */
1253 case 0x0d: return (m_core->astat & BTF); /* TF */
1254 case 0x0e: return 0; /* BM */
1255 case 0x0f: return (m_core->curlcntr==1); /* LCE */
1256 case 0x10: return !(m_core->astat & AZ); /* NOT EQUAL */
1257 case 0x11: return (m_core->astat & AZ) || !(m_core->astat & AN); /* GE */
1258 case 0x12: return !(m_core->astat & AZ) && !(m_core->astat & AN); /* GT */
1259 case 0x13: return !(m_core->astat & AC); /* NOT AC */
1260 case 0x14: return !(m_core->astat & AV); /* NOT AV */
1261 case 0x15: return !(m_core->astat & MV); /* NOT MV */
1262 case 0x16: return !(m_core->astat & MN); /* NOT MS */
1263 case 0x17: return !(m_core->astat & SV); /* NOT SV */
1264 case 0x18: return !(m_core->astat & SZ); /* NOT SZ */
1265 case 0x19: return (m_core->flag[0] == 0); /* NOT FLAG0 */
1266 case 0x1a: return (m_core->flag[1] == 0); /* NOT FLAG1 */
1267 case 0x1b: return (m_core->flag[2] == 0); /* NOT FLAG2 */
1268 case 0x1c: return (m_core->flag[3] == 0); /* NOT FLAG3 */
1269 case 0x1d: return !(m_core->astat & BTF); /* NOT TF */
1270 case 0x1e: return 1; /* NOT BM */
1271 case 0x1f: return 0; /* FALSE (FOREVER) */
1272 }
1273 return 1;
1274 }
1275
1276 /*****************************************************************************/
1277 /* | 001xxxxxx | */
1278
1279 /* compute / dreg <-> DM / dreg <-> PM */
sharcop_compute_dreg_dm_dreg_pm()1280 void adsp21062_device::sharcop_compute_dreg_dm_dreg_pm()
1281 {
1282 int pm_dreg = (m_core->opcode >> 23) & 0xf;
1283 int pmm = (m_core->opcode >> 27) & 0x7;
1284 int pmi = (m_core->opcode >> 30) & 0x7;
1285 int dm_dreg = (m_core->opcode >> 33) & 0xf;
1286 int dmm = (m_core->opcode >> 38) & 0x7;
1287 int dmi = (m_core->opcode >> 41) & 0x7;
1288 int pmd = (m_core->opcode >> 37) & 0x1;
1289 int dmd = (m_core->opcode >> 44) & 0x1;
1290 int compute = m_core->opcode & 0x7fffff;
1291
1292 /* due to parallelity issues, source DREGs must be saved */
1293 /* because the compute operation may change them */
1294 uint32_t parallel_pm_dreg = REG(pm_dreg);
1295 uint32_t parallel_dm_dreg = REG(dm_dreg);
1296
1297 if (compute)
1298 {
1299 COMPUTE(compute);
1300 }
1301
1302 if (pmd) // dreg -> PM
1303 {
1304 pm_write32(PM_REG_I(pmi), parallel_pm_dreg);
1305 PM_REG_I(pmi) += PM_REG_M(pmm);
1306 UPDATE_CIRCULAR_BUFFER_PM(pmi);
1307 }
1308 else // PM -> dreg
1309 {
1310 REG(pm_dreg) = pm_read32(PM_REG_I(pmi));
1311 PM_REG_I(pmi) += PM_REG_M(pmm);
1312 UPDATE_CIRCULAR_BUFFER_PM(pmi);
1313 }
1314
1315 if (dmd) // dreg -> DM
1316 {
1317 dm_write32(DM_REG_I(dmi), parallel_dm_dreg);
1318 DM_REG_I(dmi) += DM_REG_M(dmm);
1319 UPDATE_CIRCULAR_BUFFER_DM(dmi);
1320 }
1321 else // DM -> dreg
1322 {
1323 REG(dm_dreg) = dm_read32(DM_REG_I(dmi));
1324 DM_REG_I(dmi) += DM_REG_M(dmm);
1325 UPDATE_CIRCULAR_BUFFER_DM(dmi);
1326 }
1327 }
1328
1329 /*****************************************************************************/
1330 /* | 00000001x | */
1331
1332 /* compute */
sharcop_compute()1333 void adsp21062_device::sharcop_compute()
1334 {
1335 int cond = (m_core->opcode >> 33) & 0x1f;
1336 int compute = m_core->opcode & 0x7fffff;
1337
1338 if (IF_CONDITION_CODE(cond) && compute != 0)
1339 {
1340 COMPUTE(compute);
1341 }
1342 }
1343
1344 /*****************************************************************************/
1345 /* | 010xxxxxx | */
1346
1347 /* compute / ureg <-> DM|PM, pre-modify */
sharcop_compute_ureg_dmpm_premod()1348 void adsp21062_device::sharcop_compute_ureg_dmpm_premod()
1349 {
1350 int i = (m_core->opcode >> 41) & 0x7;
1351 int m = (m_core->opcode >> 38) & 0x7;
1352 int cond = (m_core->opcode >> 33) & 0x1f;
1353 int g = (m_core->opcode >> 32) & 0x1;
1354 int d = (m_core->opcode >> 31) & 0x1;
1355 int ureg = (m_core->opcode >> 23) & 0xff;
1356 int compute = m_core->opcode & 0x7fffff;
1357
1358 if (IF_CONDITION_CODE(cond))
1359 {
1360 /* due to parallelity issues, source UREG must be saved */
1361 /* because the compute operation may change it */
1362 uint32_t parallel_ureg = GET_UREG(ureg);
1363
1364 if (compute)
1365 {
1366 COMPUTE(compute);
1367 }
1368
1369 if (g) /* PM */
1370 {
1371 if (d) /* ureg -> PM */
1372 {
1373 if (ureg == 0xdb) /* PX register access is always 48-bit */
1374 {
1375 pm_write48(PM_REG_I(i)+PM_REG_M(m), m_core->px);
1376 }
1377 else
1378 {
1379 pm_write32(PM_REG_I(i)+PM_REG_M(m), parallel_ureg);
1380 }
1381 }
1382 else /* PM <- ureg */
1383 {
1384 if (ureg == 0xdb) /* PX register access is always 48-bit */
1385 {
1386 m_core->px = pm_read48(PM_REG_I(i)+PM_REG_M(m));
1387 }
1388 else
1389 {
1390 SET_UREG(ureg, pm_read32(PM_REG_I(i)+PM_REG_M(m)));
1391 }
1392 }
1393 }
1394 else /* DM */
1395 {
1396 if (d) /* ureg -> DM */
1397 {
1398 dm_write32(DM_REG_I(i)+DM_REG_M(m), parallel_ureg);
1399 }
1400 else /* DM <- ureg */
1401 {
1402 SET_UREG(ureg, dm_read32(DM_REG_I(i)+DM_REG_M(m)));
1403 }
1404 }
1405 }
1406 }
1407
1408 /* compute / ureg <-> DM|PM, post-modify */
sharcop_compute_ureg_dmpm_postmod()1409 void adsp21062_device::sharcop_compute_ureg_dmpm_postmod()
1410 {
1411 int i = (m_core->opcode >> 41) & 0x7;
1412 int m = (m_core->opcode >> 38) & 0x7;
1413 int cond = (m_core->opcode >> 33) & 0x1f;
1414 int g = (m_core->opcode >> 32) & 0x1;
1415 int d = (m_core->opcode >> 31) & 0x1;
1416 int ureg = (m_core->opcode >> 23) & 0xff;
1417 int compute = m_core->opcode & 0x7fffff;
1418
1419 if(IF_CONDITION_CODE(cond))
1420 {
1421 /* due to parallelity issues, source UREG must be saved */
1422 /* because the compute operation may change it */
1423 uint32_t parallel_ureg = GET_UREG(ureg);
1424
1425 if (compute)
1426 {
1427 COMPUTE(compute);
1428 }
1429
1430 if (g) /* PM */
1431 {
1432 if (d) /* ureg -> PM */
1433 {
1434 if (ureg == 0xdb) /* PX register access is always 48-bit */
1435 {
1436 pm_write48(PM_REG_I(i), m_core->px);
1437 }
1438 else
1439 {
1440 pm_write32(PM_REG_I(i), parallel_ureg);
1441 }
1442 PM_REG_I(i) += PM_REG_M(m);
1443 UPDATE_CIRCULAR_BUFFER_PM(i);
1444 }
1445 else /* PM <- ureg */
1446 {
1447 if (ureg == 0xdb) /* PX register access is always 48-bit */
1448 {
1449 m_core->px = pm_read48(PM_REG_I(i));
1450 }
1451 else
1452 {
1453 SET_UREG(ureg, pm_read32(PM_REG_I(i)));
1454 }
1455 PM_REG_I(i) += PM_REG_M(m);
1456 UPDATE_CIRCULAR_BUFFER_PM(i);
1457 }
1458 }
1459 else /* DM */
1460 {
1461 if (d) /* ureg -> DM */
1462 {
1463 dm_write32(DM_REG_I(i), parallel_ureg);
1464 DM_REG_I(i) += DM_REG_M(m);
1465 UPDATE_CIRCULAR_BUFFER_DM(i);
1466 }
1467 else /* DM <- ureg */
1468 {
1469 SET_UREG(ureg, dm_read32(DM_REG_I(i)));
1470 DM_REG_I(i) += DM_REG_M(m);
1471 UPDATE_CIRCULAR_BUFFER_DM(i);
1472 }
1473 }
1474 }
1475 }
1476
1477 /*****************************************************************************/
1478 /* | 0110xxxxx | */
1479
1480 /* compute / dreg <- DM, immediate modify */
sharcop_compute_dm_to_dreg_immmod()1481 void adsp21062_device::sharcop_compute_dm_to_dreg_immmod()
1482 {
1483 int cond = (m_core->opcode >> 33) & 0x1f;
1484 int u = (m_core->opcode >> 38) & 0x1;
1485 int dreg = (m_core->opcode >> 23) & 0xf;
1486 int i = (m_core->opcode >> 41) & 0x7;
1487 int mod = SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f);
1488 int compute = m_core->opcode & 0x7fffff;
1489
1490 if (IF_CONDITION_CODE(cond))
1491 {
1492 if (compute != 0)
1493 {
1494 COMPUTE(compute);
1495 }
1496
1497 if (u) /* post-modify with update */
1498 {
1499 REG(dreg) = dm_read32(DM_REG_I(i));
1500 DM_REG_I(i) += mod;
1501 UPDATE_CIRCULAR_BUFFER_DM(i);
1502 }
1503 else /* pre-modify, no update */
1504 {
1505 REG(dreg) = dm_read32(DM_REG_I(i) + mod);
1506 }
1507 }
1508 }
1509
1510 /* compute / dreg -> DM, immediate modify */
sharcop_compute_dreg_to_dm_immmod()1511 void adsp21062_device::sharcop_compute_dreg_to_dm_immmod()
1512 {
1513 int cond = (m_core->opcode >> 33) & 0x1f;
1514 int u = (m_core->opcode >> 38) & 0x1;
1515 int dreg = (m_core->opcode >> 23) & 0xf;
1516 int i = (m_core->opcode >> 41) & 0x7;
1517 int mod = SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f);
1518 int compute = m_core->opcode & 0x7fffff;
1519
1520 /* due to parallelity issues, source REG must be saved */
1521 /* because the shift operation may change it */
1522 uint32_t parallel_dreg = REG(dreg);
1523
1524 if (IF_CONDITION_CODE(cond))
1525 {
1526 if (compute != 0)
1527 {
1528 COMPUTE(compute);
1529 }
1530
1531 if (u) /* post-modify with update */
1532 {
1533 dm_write32(DM_REG_I(i), parallel_dreg);
1534 DM_REG_I(i) += mod;
1535 UPDATE_CIRCULAR_BUFFER_DM(i);
1536 }
1537 else /* pre-modify, no update */
1538 {
1539 dm_write32(DM_REG_I(i) + mod, parallel_dreg);
1540 }
1541 }
1542 }
1543
1544 /* compute / dreg <- PM, immediate modify */
sharcop_compute_pm_to_dreg_immmod()1545 void adsp21062_device::sharcop_compute_pm_to_dreg_immmod()
1546 {
1547 int cond = (m_core->opcode >> 33) & 0x1f;
1548 int u = (m_core->opcode >> 38) & 0x1;
1549 int dreg = (m_core->opcode >> 23) & 0xf;
1550 int i = (m_core->opcode >> 41) & 0x7;
1551 int mod = SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f);
1552 int compute = m_core->opcode & 0x7fffff;
1553
1554 if (IF_CONDITION_CODE(cond))
1555 {
1556 if (compute != 0)
1557 {
1558 COMPUTE(compute);
1559 }
1560
1561 if (u) /* post-modify with update */
1562 {
1563 REG(dreg) = pm_read32(PM_REG_I(i));
1564 PM_REG_I(i) += mod;
1565 UPDATE_CIRCULAR_BUFFER_PM(i);
1566 }
1567 else /* pre-modify, no update */
1568 {
1569 REG(dreg) = pm_read32(PM_REG_I(i) + mod);
1570 }
1571 }
1572 }
1573
1574 /* compute / dreg -> PM, immediate modify */
sharcop_compute_dreg_to_pm_immmod()1575 void adsp21062_device::sharcop_compute_dreg_to_pm_immmod()
1576 {
1577 int cond = (m_core->opcode >> 33) & 0x1f;
1578 int u = (m_core->opcode >> 38) & 0x1;
1579 int dreg = (m_core->opcode >> 23) & 0xf;
1580 int i = (m_core->opcode >> 41) & 0x7;
1581 int mod = SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f);
1582 int compute = m_core->opcode & 0x7fffff;
1583
1584 /* due to parallelity issues, source REG must be saved */
1585 /* because the compute operation may change it */
1586 uint32_t parallel_dreg = REG(dreg);
1587
1588 if (IF_CONDITION_CODE(cond))
1589 {
1590 if (compute != 0)
1591 {
1592 COMPUTE(compute);
1593 }
1594
1595 if (u) /* post-modify with update */
1596 {
1597 pm_write32(PM_REG_I(i), parallel_dreg);
1598 PM_REG_I(i) += mod;
1599 UPDATE_CIRCULAR_BUFFER_PM(i);
1600 }
1601 else /* pre-modify, no update */
1602 {
1603 pm_write32(PM_REG_I(i) + mod, parallel_dreg);
1604 }
1605 }
1606 }
1607
1608 /*****************************************************************************/
1609 /* | 0111xxxxx | */
1610
1611 /* compute / ureg <-> ureg */
sharcop_compute_ureg_to_ureg()1612 void adsp21062_device::sharcop_compute_ureg_to_ureg()
1613 {
1614 int src_ureg = (m_core->opcode >> 36) & 0xff;
1615 int dst_ureg = (m_core->opcode >> 23) & 0xff;
1616 int cond = (m_core->opcode >> 31) & 0x1f;
1617 int compute = m_core->opcode & 0x7fffff;
1618
1619 if (IF_CONDITION_CODE(cond))
1620 {
1621 /* due to parallelity issues, source UREG must be saved */
1622 /* because the compute operation may change it */
1623 uint32_t parallel_ureg = GET_UREG(src_ureg);
1624
1625 if (compute != 0)
1626 {
1627 COMPUTE(compute);
1628 }
1629
1630 SET_UREG(dst_ureg, parallel_ureg);
1631 }
1632 }
1633
1634 /*****************************************************************************/
1635 /* | 1000xxxxx | */
1636
1637 /* immediate shift / dreg <-> DM|PM */
sharcop_imm_shift_dreg_dmpm()1638 void adsp21062_device::sharcop_imm_shift_dreg_dmpm()
1639 {
1640 int i = (m_core->opcode >> 41) & 0x7;
1641 int m = (m_core->opcode >> 38) & 0x7;
1642 int g = (m_core->opcode >> 32) & 0x1;
1643 int d = (m_core->opcode >> 31) & 0x1;
1644 int dreg = (m_core->opcode >> 23) & 0xf;
1645 int cond = (m_core->opcode >> 33) & 0x1f;
1646 int data = ((m_core->opcode >> 8) & 0xff) | ((m_core->opcode >> 19) & 0xf00);
1647 int shiftop = (m_core->opcode >> 16) & 0x3f;
1648 int rn = (m_core->opcode >> 4) & 0xf;
1649 int rx = (m_core->opcode & 0xf);
1650
1651 if (IF_CONDITION_CODE(cond))
1652 {
1653 /* due to parallelity issues, source REG must be saved */
1654 /* because the shift operation may change it */
1655 uint32_t parallel_dreg = REG(dreg);
1656
1657 SHIFT_OPERATION_IMM(shiftop, data, rn, rx);
1658
1659 if (g) /* PM */
1660 {
1661 if (d) /* dreg -> PM */
1662 {
1663 pm_write32(PM_REG_I(i), parallel_dreg);
1664 PM_REG_I(i) += PM_REG_M(m);
1665 UPDATE_CIRCULAR_BUFFER_PM(i);
1666 }
1667 else /* PM <- dreg */
1668 {
1669 REG(dreg) = pm_read32(PM_REG_I(i));
1670 PM_REG_I(i) += PM_REG_M(m);
1671 UPDATE_CIRCULAR_BUFFER_PM(i);
1672 }
1673 }
1674 else /* DM */
1675 {
1676 if (d) /* dreg -> DM */
1677 {
1678 dm_write32(DM_REG_I(i), parallel_dreg);
1679 DM_REG_I(i) += DM_REG_M(m);
1680 UPDATE_CIRCULAR_BUFFER_DM(i);
1681 }
1682 else /* DM <- dreg */
1683 {
1684 REG(dreg) = dm_read32(DM_REG_I(i));
1685 DM_REG_I(i) += DM_REG_M(m);
1686 UPDATE_CIRCULAR_BUFFER_DM(i);
1687 }
1688 }
1689 }
1690 }
1691
1692 /*****************************************************************************/
1693 /* | 00000010x | */
1694
1695 /* immediate shift */
sharcop_imm_shift()1696 void adsp21062_device::sharcop_imm_shift()
1697 {
1698 int cond = (m_core->opcode >> 33) & 0x1f;
1699 int data = ((m_core->opcode >> 8) & 0xff) | ((m_core->opcode >> 19) & 0xf00);
1700 int shiftop = (m_core->opcode >> 16) & 0x3f;
1701 int rn = (m_core->opcode >> 4) & 0xf;
1702 int rx = (m_core->opcode & 0xf);
1703
1704 if (IF_CONDITION_CODE(cond))
1705 {
1706 SHIFT_OPERATION_IMM(shiftop, data, rn, rx);
1707 }
1708 }
1709
1710 /*****************************************************************************/
1711 /* | 00000100x | */
1712
1713 /* compute / modify */
sharcop_compute_modify()1714 void adsp21062_device::sharcop_compute_modify()
1715 {
1716 int cond = (m_core->opcode >> 33) & 0x1f;
1717 int compute = m_core->opcode & 0x7fffff;
1718 int g = (m_core->opcode >> 38) & 0x1;
1719 int m = (m_core->opcode >> 27) & 0x7;
1720 int i = (m_core->opcode >> 30) & 0x7;
1721
1722 if (IF_CONDITION_CODE(cond))
1723 {
1724 if (compute != 0)
1725 {
1726 COMPUTE(compute);
1727 }
1728
1729 if (g) /* Modify PM */
1730 {
1731 PM_REG_I(i) += PM_REG_M(m);
1732 UPDATE_CIRCULAR_BUFFER_PM(i);
1733 }
1734 else /* Modify DM */
1735 {
1736 DM_REG_I(i) += DM_REG_M(m);
1737 UPDATE_CIRCULAR_BUFFER_DM(i);
1738 }
1739 }
1740 }
1741
1742 /*****************************************************************************/
1743 /* | 00000110x | */
1744
1745 /* direct call to absolute address */
sharcop_direct_call()1746 void adsp21062_device::sharcop_direct_call()
1747 {
1748 int j = (m_core->opcode >> 26) & 0x1;
1749 int cond = (m_core->opcode >> 33) & 0x1f;
1750 uint32_t address = m_core->opcode & 0xffffff;
1751
1752 if (IF_CONDITION_CODE(cond))
1753 {
1754 if (j)
1755 {
1756 //PUSH_PC(m_core->pc+3); /* 1 instruction + 2 delayed instructions */
1757 PUSH_PC(m_core->nfaddr); /* 1 instruction + 2 delayed instructions */
1758 CHANGE_PC_DELAYED(address);
1759 }
1760 else
1761 {
1762 //PUSH_PC(m_core->pc+1);
1763 PUSH_PC(m_core->daddr);
1764 CHANGE_PC(address);
1765 }
1766 }
1767 }
1768
1769 /* direct jump to absolute address */
sharcop_direct_jump()1770 void adsp21062_device::sharcop_direct_jump()
1771 {
1772 int la = (m_core->opcode >> 38) & 0x1;
1773 int ci = (m_core->opcode >> 24) & 0x1;
1774 int j = (m_core->opcode >> 26) & 0x1;
1775 int cond = (m_core->opcode >> 33) & 0x1f;
1776 uint32_t address = m_core->opcode & 0xffffff;
1777
1778 if(IF_CONDITION_CODE(cond))
1779 {
1780 // Clear Interrupt
1781 if (ci)
1782 {
1783 // TODO: anything else?
1784 if (m_core->status_stkp > 0)
1785 {
1786 POP_STATUS_STACK();
1787 }
1788
1789 m_core->interrupt_active = 0;
1790 m_core->irptl &= ~(1 << m_core->active_irq_num);
1791 }
1792
1793 if (la)
1794 {
1795 POP_PC();
1796 POP_LOOP();
1797 }
1798
1799 if (j)
1800 {
1801 CHANGE_PC_DELAYED(address);
1802 }
1803 else
1804 {
1805 CHANGE_PC(address);
1806 }
1807 }
1808 }
1809
1810 /*****************************************************************************/
1811 /* | 00000111x | */
1812
1813 /* direct call to relative address */
sharcop_relative_call()1814 void adsp21062_device::sharcop_relative_call()
1815 {
1816 int j = (m_core->opcode >> 26) & 0x1;
1817 int cond = (m_core->opcode >> 33) & 0x1f;
1818 uint32_t address = m_core->opcode & 0xffffff;
1819
1820 if (IF_CONDITION_CODE(cond))
1821 {
1822 if (j)
1823 {
1824 PUSH_PC(m_core->pc+3); /* 1 instruction + 2 delayed instructions */
1825 CHANGE_PC_DELAYED(m_core->pc + SIGN_EXTEND24(address));
1826 }
1827 else
1828 {
1829 PUSH_PC(m_core->pc+1);
1830 CHANGE_PC(m_core->pc + SIGN_EXTEND24(address));
1831 }
1832 }
1833 }
1834
1835 /* direct jump to relative address */
sharcop_relative_jump()1836 void adsp21062_device::sharcop_relative_jump()
1837 {
1838 int la = (m_core->opcode >> 38) & 0x1;
1839 int ci = (m_core->opcode >> 24) & 0x1;
1840 int j = (m_core->opcode >> 26) & 0x1;
1841 int cond = (m_core->opcode >> 33) & 0x1f;
1842 uint32_t address = m_core->opcode & 0xffffff;
1843
1844 if (IF_CONDITION_CODE(cond))
1845 {
1846 // Clear Interrupt
1847 if (ci)
1848 {
1849 // TODO: anything else?
1850 if (m_core->status_stkp > 0)
1851 {
1852 POP_STATUS_STACK();
1853 }
1854
1855 m_core->interrupt_active = 0;
1856 m_core->irptl &= ~(1 << m_core->active_irq_num);
1857 }
1858
1859 if (la)
1860 {
1861 POP_PC();
1862 POP_LOOP();
1863 }
1864
1865 if (j)
1866 {
1867 CHANGE_PC_DELAYED(m_core->pc + SIGN_EXTEND24(address));
1868 }
1869 else
1870 {
1871 CHANGE_PC(m_core->pc + SIGN_EXTEND24(address));
1872 }
1873 }
1874 }
1875
1876 /*****************************************************************************/
1877 /* | 00001000x | */
1878
1879 /* indirect jump */
sharcop_indirect_jump()1880 void adsp21062_device::sharcop_indirect_jump()
1881 {
1882 int la = (m_core->opcode >> 38) & 0x1;
1883 int ci = (m_core->opcode >> 24) & 0x1;
1884 int j = (m_core->opcode >> 26) & 0x1;
1885 int e = (m_core->opcode >> 25) & 0x1;
1886 int pmi = (m_core->opcode >> 30) & 0x7;
1887 int pmm = (m_core->opcode >> 27) & 0x7;
1888 int cond = (m_core->opcode >> 33) & 0x1f;
1889 int compute = m_core->opcode & 0x7fffff;
1890
1891 // Clear Interrupt
1892 if (ci)
1893 {
1894 // TODO: anything else?
1895 if (m_core->status_stkp > 0)
1896 {
1897 POP_STATUS_STACK();
1898 }
1899
1900 m_core->interrupt_active = 0;
1901 m_core->irptl &= ~(1 << m_core->active_irq_num);
1902 }
1903
1904 if (e) /* IF...ELSE */
1905 {
1906 if (IF_CONDITION_CODE(cond))
1907 {
1908 if (la)
1909 {
1910 POP_PC();
1911 POP_LOOP();
1912 }
1913
1914 if(j)
1915 {
1916 CHANGE_PC_DELAYED(PM_REG_I(pmi) + PM_REG_M(pmm));
1917 }
1918 else
1919 {
1920 CHANGE_PC(PM_REG_I(pmi) + PM_REG_M(pmm));
1921 }
1922 }
1923 else
1924 {
1925 if (compute)
1926 {
1927 COMPUTE(compute);
1928 }
1929 }
1930 }
1931 else /* IF */
1932 {
1933 if (IF_CONDITION_CODE(cond))
1934 {
1935 if (compute)
1936 {
1937 COMPUTE(compute);
1938 }
1939
1940 if (la)
1941 {
1942 POP_PC();
1943 POP_LOOP();
1944 }
1945
1946 if(j)
1947 {
1948 CHANGE_PC_DELAYED(PM_REG_I(pmi) + PM_REG_M(pmm));
1949 }
1950 else
1951 {
1952 CHANGE_PC(PM_REG_I(pmi) + PM_REG_M(pmm));
1953 }
1954 }
1955 }
1956 }
1957
1958 /* indirect call */
sharcop_indirect_call()1959 void adsp21062_device::sharcop_indirect_call()
1960 {
1961 int j = (m_core->opcode >> 26) & 0x1;
1962 int e = (m_core->opcode >> 25) & 0x1;
1963 int pmi = (m_core->opcode >> 30) & 0x7;
1964 int pmm = (m_core->opcode >> 27) & 0x7;
1965 int cond = (m_core->opcode >> 33) & 0x1f;
1966 int compute = m_core->opcode & 0x7fffff;
1967
1968 if (e) /* IF...ELSE */
1969 {
1970 if (IF_CONDITION_CODE(cond))
1971 {
1972 if (j)
1973 {
1974 //PUSH_PC(m_core->pc+3); /* 1 instruction + 2 delayed instructions */
1975 PUSH_PC(m_core->nfaddr); /* 1 instruction + 2 delayed instructions */
1976 CHANGE_PC_DELAYED(PM_REG_I(pmi) + PM_REG_M(pmm));
1977 }
1978 else
1979 {
1980 //PUSH_PC(m_core->pc+1);
1981 PUSH_PC(m_core->daddr);
1982 CHANGE_PC(PM_REG_I(pmi) + PM_REG_M(pmm));
1983 }
1984 }
1985 else
1986 {
1987 if (compute)
1988 {
1989 COMPUTE(compute);
1990 }
1991 }
1992 }
1993 else /* IF */
1994 {
1995 if (IF_CONDITION_CODE(cond))
1996 {
1997 if (compute)
1998 {
1999 COMPUTE(compute);
2000 }
2001
2002 if (j)
2003 {
2004 //PUSH_PC(m_core->pc+3); /* 1 instruction + 2 delayed instructions */
2005 PUSH_PC(m_core->nfaddr); /* 1 instruction + 2 delayed instructions */
2006 CHANGE_PC_DELAYED(PM_REG_I(pmi) + PM_REG_M(pmm));
2007 }
2008 else
2009 {
2010 //PUSH_PC(m_core->pc+1);
2011 PUSH_PC(m_core->daddr);
2012 CHANGE_PC(PM_REG_I(pmi) + PM_REG_M(pmm));
2013 }
2014 }
2015 }
2016 }
2017
2018 /*****************************************************************************/
2019 /* | 00001001x | */
2020
2021 /* indirect jump to relative address */
sharcop_relative_jump_compute()2022 void adsp21062_device::sharcop_relative_jump_compute()
2023 {
2024 int la = (m_core->opcode >> 38) & 0x1;
2025 int ci = (m_core->opcode >> 24) & 0x1;
2026 int j = (m_core->opcode >> 26) & 0x1;
2027 int e = (m_core->opcode >> 25) & 0x1;
2028 int cond = (m_core->opcode >> 33) & 0x1f;
2029 int compute = m_core->opcode & 0x7fffff;
2030
2031 // Clear Interrupt
2032 if (ci)
2033 {
2034 // TODO: anything else?
2035 if (m_core->status_stkp > 0)
2036 {
2037 POP_STATUS_STACK();
2038 }
2039
2040 m_core->interrupt_active = 0;
2041 m_core->irptl &= ~(1 << m_core->active_irq_num);
2042 }
2043
2044 if (e) /* IF...ELSE */
2045 {
2046 if (IF_CONDITION_CODE(cond))
2047 {
2048 if (la)
2049 {
2050 POP_PC();
2051 POP_LOOP();
2052 }
2053
2054 if (j)
2055 {
2056 CHANGE_PC_DELAYED(m_core->pc + SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f));
2057 }
2058 else
2059 {
2060 CHANGE_PC(m_core->pc + SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f));
2061 }
2062 }
2063 else
2064 {
2065 if (compute)
2066 {
2067 COMPUTE(compute);
2068 }
2069 }
2070 }
2071 else /* IF */
2072 {
2073 if (IF_CONDITION_CODE(cond))
2074 {
2075 if (compute)
2076 {
2077 COMPUTE(compute);
2078 }
2079
2080 if (la)
2081 {
2082 POP_PC();
2083 POP_LOOP();
2084 }
2085
2086 if (j)
2087 {
2088 CHANGE_PC_DELAYED(m_core->pc + SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f));
2089 }
2090 else
2091 {
2092 CHANGE_PC(m_core->pc + SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f));
2093 }
2094 }
2095 }
2096 }
2097
2098 /* indirect call to relative address */
sharcop_relative_call_compute()2099 void adsp21062_device::sharcop_relative_call_compute()
2100 {
2101 int j = (m_core->opcode >> 26) & 0x1;
2102 int e = (m_core->opcode >> 25) & 0x1;
2103 int cond = (m_core->opcode >> 33) & 0x1f;
2104 int compute = m_core->opcode & 0x7fffff;
2105
2106 if (e) /* IF...ELSE */
2107 {
2108 if (IF_CONDITION_CODE(cond))
2109 {
2110 if (j)
2111 {
2112 //PUSH_PC(m_core->pc+3); /* 1 instruction + 2 delayed instructions */
2113 PUSH_PC(m_core->nfaddr); /* 1 instruction + 2 delayed instructions */
2114 CHANGE_PC_DELAYED(m_core->pc + SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f));
2115 }
2116 else
2117 {
2118 //PUSH_PC(m_core->pc+1);
2119 PUSH_PC(m_core->daddr);
2120 CHANGE_PC(m_core->pc + SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f));
2121 }
2122 }
2123 else
2124 {
2125 if (compute)
2126 {
2127 COMPUTE(compute);
2128 }
2129 }
2130 }
2131 else /* IF */
2132 {
2133 if (IF_CONDITION_CODE(cond))
2134 {
2135 if (compute)
2136 {
2137 COMPUTE(compute);
2138 }
2139
2140 if (j)
2141 {
2142 //PUSH_PC(m_core->pc+3); /* 1 instruction + 2 delayed instructions */
2143 PUSH_PC(m_core->nfaddr); /* 1 instruction + 2 delayed instructions */
2144 CHANGE_PC_DELAYED(m_core->pc + SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f));
2145 }
2146 else
2147 {
2148 //PUSH_PC(m_core->pc+1);
2149 PUSH_PC(m_core->daddr);
2150 CHANGE_PC(m_core->pc + SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f));
2151 }
2152 }
2153 }
2154 }
2155
2156 /*****************************************************************************/
2157 /* | 110xxxxxx | */
2158
2159 /* indirect jump / compute / dreg <-> DM */
sharcop_indirect_jump_compute_dreg_dm()2160 void adsp21062_device::sharcop_indirect_jump_compute_dreg_dm()
2161 {
2162 int d = (m_core->opcode >> 44) & 0x1;
2163 int dmi = (m_core->opcode >> 41) & 0x7;
2164 int dmm = (m_core->opcode >> 38) & 0x7;
2165 int pmi = (m_core->opcode >> 30) & 0x7;
2166 int pmm = (m_core->opcode >> 27) & 0x7;
2167 int cond = (m_core->opcode >> 33) & 0x1f;
2168 int dreg = (m_core->opcode >> 23) & 0xf;
2169
2170 if (IF_CONDITION_CODE(cond))
2171 {
2172 CHANGE_PC(PM_REG_I(pmi) + PM_REG_M(pmm));
2173 }
2174 else
2175 {
2176 uint32_t compute = m_core->opcode & 0x7fffff;
2177 /* due to parallelity issues, source REG must be saved */
2178 /* because the compute operation may change it */
2179 uint32_t parallel_dreg = REG(dreg);
2180
2181 if (compute)
2182 {
2183 COMPUTE(compute);
2184 }
2185
2186 if (d) /* dreg -> DM */
2187 {
2188 dm_write32(DM_REG_I(dmi), parallel_dreg);
2189 DM_REG_I(dmi) += DM_REG_M(dmm);
2190 UPDATE_CIRCULAR_BUFFER_DM(dmi);
2191 }
2192 else /* DM <- dreg */
2193 {
2194 REG(dreg) = dm_read32(DM_REG_I(dmi));
2195 DM_REG_I(dmi) += DM_REG_M(dmm);
2196 UPDATE_CIRCULAR_BUFFER_DM(dmi);
2197 }
2198 }
2199 }
2200
2201 /*****************************************************************************/
2202 /* | 111xxxxxx | */
2203
2204 /* relative jump / compute / dreg <-> DM */
sharcop_relative_jump_compute_dreg_dm()2205 void adsp21062_device::sharcop_relative_jump_compute_dreg_dm()
2206 {
2207 int d = (m_core->opcode >> 44) & 0x1;
2208 int dmi = (m_core->opcode >> 41) & 0x7;
2209 int dmm = (m_core->opcode >> 38) & 0x7;
2210 int cond = (m_core->opcode >> 33) & 0x1f;
2211 int dreg = (m_core->opcode >> 23) & 0xf;
2212
2213 if (IF_CONDITION_CODE(cond))
2214 {
2215 CHANGE_PC(m_core->pc + SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f));
2216 }
2217 else
2218 {
2219 uint32_t compute = m_core->opcode & 0x7fffff;
2220 /* due to parallelity issues, source REG must be saved */
2221 /* because the compute operation may change it */
2222 uint32_t parallel_dreg = REG(dreg);
2223
2224 if (compute)
2225 {
2226 COMPUTE(compute);
2227 }
2228
2229 if (d) /* dreg -> DM */
2230 {
2231 dm_write32(DM_REG_I(dmi), parallel_dreg);
2232 DM_REG_I(dmi) += DM_REG_M(dmm);
2233 UPDATE_CIRCULAR_BUFFER_DM(dmi);
2234 }
2235 else /* DM <- dreg */
2236 {
2237 REG(dreg) = dm_read32(DM_REG_I(dmi));
2238 DM_REG_I(dmi) += DM_REG_M(dmm);
2239 UPDATE_CIRCULAR_BUFFER_DM(dmi);
2240 }
2241 }
2242 }
2243
2244 /*****************************************************************************/
2245 /* | 00001010x | */
2246
2247 /* return from subroutine / compute */
sharcop_rts()2248 void adsp21062_device::sharcop_rts()
2249 {
2250 int cond = (m_core->opcode >> 33) & 0x1f;
2251 int j = (m_core->opcode >> 26) & 0x1;
2252 int e = (m_core->opcode >> 25) & 0x1;
2253 //int lr = (m_core->opcode >> 24) & 0x1;
2254 int compute = m_core->opcode & 0x7fffff;
2255
2256 //if(lr)
2257 // fatalerror("SHARC: rts: loop reentry not implemented!\n");
2258
2259 if (e) /* IF...ELSE */
2260 {
2261 if(IF_CONDITION_CODE(cond))
2262 {
2263 if (j)
2264 {
2265 CHANGE_PC_DELAYED(POP_PC());
2266 }
2267 else
2268 {
2269 CHANGE_PC(POP_PC());
2270 }
2271 }
2272 else
2273 {
2274 if (compute)
2275 {
2276 COMPUTE(compute);
2277 }
2278 }
2279 }
2280 else /* IF */
2281 {
2282 if (IF_CONDITION_CODE(cond))
2283 {
2284 if (compute)
2285 {
2286 COMPUTE(compute);
2287 }
2288
2289 if (j)
2290 {
2291 CHANGE_PC_DELAYED(POP_PC());
2292 }
2293 else
2294 {
2295 CHANGE_PC(POP_PC());
2296 }
2297 }
2298 }
2299 }
2300
2301 /*****************************************************************************/
2302 /* | 00001011x | */
2303
2304 /* return from interrupt / compute */
sharcop_rti()2305 void adsp21062_device::sharcop_rti()
2306 {
2307 int cond = (m_core->opcode >> 33) & 0x1f;
2308 int j = (m_core->opcode >> 26) & 0x1;
2309 int e = (m_core->opcode >> 25) & 0x1;
2310 int compute = m_core->opcode & 0x7fffff;
2311
2312 m_core->irptl &= ~(1 << m_core->active_irq_num);
2313
2314 if(e) /* IF...ELSE */
2315 {
2316 if (IF_CONDITION_CODE(cond))
2317 {
2318 if (j)
2319 {
2320 CHANGE_PC_DELAYED(POP_PC());
2321 }
2322 else
2323 {
2324 CHANGE_PC(POP_PC());
2325 }
2326 }
2327 else
2328 {
2329 if (compute)
2330 {
2331 COMPUTE(compute);
2332 }
2333 }
2334 }
2335 else /* IF */
2336 {
2337 if (IF_CONDITION_CODE(cond))
2338 {
2339 if (compute)
2340 {
2341 COMPUTE(compute);
2342 }
2343
2344 if (j)
2345 {
2346 CHANGE_PC_DELAYED(POP_PC());
2347 }
2348 else
2349 {
2350 CHANGE_PC(POP_PC());
2351 }
2352 }
2353 }
2354
2355 if (m_core->status_stkp > 0)
2356 {
2357 POP_STATUS_STACK();
2358 }
2359
2360 m_core->interrupt_active = 0;
2361 check_interrupts();
2362 }
2363
2364 /*****************************************************************************/
2365 /* | 00001100x | */
2366
2367 /* do until counter expired, LCNTR immediate */
sharcop_do_until_counter_imm()2368 void adsp21062_device::sharcop_do_until_counter_imm()
2369 {
2370 uint16_t data = (uint16_t)(m_core->opcode >> 24);
2371 int offset = SIGN_EXTEND24(m_core->opcode & 0xffffff);
2372 uint32_t address = m_core->pc + offset;
2373 int type;
2374 int cond = 0xf; /* until LCE (loop counter expired */
2375 int distance = abs(offset);
2376
2377 if (distance == 1)
2378 {
2379 type = 1;
2380 }
2381 else if (distance == 2)
2382 {
2383 type = 2;
2384 }
2385 else
2386 {
2387 type = 3;
2388 }
2389
2390 m_core->lcntr = data;
2391 if (m_core->lcntr > 0)
2392 {
2393 PUSH_PC(m_core->pc+1);
2394 PUSH_LOOP(address, cond, type, m_core->lcntr);
2395 }
2396 }
2397
2398 /*****************************************************************************/
2399 /* | 00001101x | */
2400
2401 /* do until counter expired, LCNTR from UREG */
sharcop_do_until_counter_ureg()2402 void adsp21062_device::sharcop_do_until_counter_ureg()
2403 {
2404 int ureg = (m_core->opcode >> 32) & 0xff;
2405 int offset = SIGN_EXTEND24(m_core->opcode & 0xffffff);
2406 uint32_t address = m_core->pc + offset;
2407 int type;
2408 int cond = 0xf; /* until LCE (loop counter expired */
2409 int distance = abs(offset);
2410
2411 if (distance == 1)
2412 {
2413 type = 1;
2414 }
2415 else if (distance == 2)
2416 {
2417 type = 2;
2418 }
2419 else
2420 {
2421 type = 3;
2422 }
2423
2424 m_core->lcntr = GET_UREG(ureg);
2425 if (m_core->lcntr > 0)
2426 {
2427 PUSH_PC(m_core->pc+1);
2428 PUSH_LOOP(address, cond, type, m_core->lcntr);
2429 }
2430 }
2431
2432 /*****************************************************************************/
2433 /* | 00001110x | */
2434
2435 /* do until */
sharcop_do_until()2436 void adsp21062_device::sharcop_do_until()
2437 {
2438 int cond = (m_core->opcode >> 33) & 0x1f;
2439 int offset = SIGN_EXTEND24(m_core->opcode & 0xffffff);
2440 uint32_t address = (m_core->pc + offset);
2441
2442 PUSH_PC(m_core->pc+1);
2443 PUSH_LOOP(address, cond, 0, 0);
2444 }
2445
2446 /*****************************************************************************/
2447 /* | 000100 | G | D | */
2448
2449 /* ureg <- DM (direct addressing) */
sharcop_dm_to_ureg_direct()2450 void adsp21062_device::sharcop_dm_to_ureg_direct()
2451 {
2452 int ureg = (m_core->opcode >> 32) & 0xff;
2453 uint32_t address = (uint32_t)(m_core->opcode);
2454
2455 SET_UREG(ureg, dm_read32(address));
2456 }
2457
2458 /* ureg -> DM (direct addressing) */
sharcop_ureg_to_dm_direct()2459 void adsp21062_device::sharcop_ureg_to_dm_direct()
2460 {
2461 int ureg = (m_core->opcode >> 32) & 0xff;
2462 uint32_t address = (uint32_t)(m_core->opcode);
2463
2464 dm_write32(address, GET_UREG(ureg));
2465 }
2466
2467 /* ureg <- PM (direct addressing) */
sharcop_pm_to_ureg_direct()2468 void adsp21062_device::sharcop_pm_to_ureg_direct()
2469 {
2470 int ureg = (m_core->opcode >> 32) & 0xff;
2471 uint32_t address = (uint32_t)(m_core->opcode);
2472
2473 if (ureg == 0xdb) // PX is 48-bit
2474 {
2475 m_core->px = pm_read48(address);
2476 }
2477 else
2478 {
2479 SET_UREG(ureg, pm_read32(address));
2480 }
2481 }
2482
2483 /* ureg -> PM (direct addressing) */
sharcop_ureg_to_pm_direct()2484 void adsp21062_device::sharcop_ureg_to_pm_direct()
2485 {
2486 int ureg = (m_core->opcode >> 32) & 0xff;
2487 uint32_t address = (uint32_t)(m_core->opcode);
2488
2489 if (ureg == 0xdb) // PX is 48-bit
2490 {
2491 pm_write48(address, m_core->px);
2492 }
2493 else
2494 {
2495 pm_write32(address, GET_UREG(ureg));
2496 }
2497 }
2498
2499 /*****************************************************************************/
2500 /* | 101 | G | III | D | */
2501
2502 /* ureg <- DM (indirect addressing) */
sharcop_dm_to_ureg_indirect()2503 void adsp21062_device::sharcop_dm_to_ureg_indirect()
2504 {
2505 int ureg = (m_core->opcode >> 32) & 0xff;
2506 uint32_t offset = (uint32_t)m_core->opcode;
2507 int i = (m_core->opcode >> 41) & 0x7;
2508
2509 SET_UREG(ureg, dm_read32(DM_REG_I(i) + offset));
2510 }
2511
2512 /* ureg -> DM (indirect addressing) */
sharcop_ureg_to_dm_indirect()2513 void adsp21062_device::sharcop_ureg_to_dm_indirect()
2514 {
2515 int ureg = (m_core->opcode >> 32) & 0xff;
2516 uint32_t offset = (uint32_t)m_core->opcode;
2517 int i = (m_core->opcode >> 41) & 0x7;
2518
2519 dm_write32(DM_REG_I(i) + offset, GET_UREG(ureg));
2520 }
2521
2522 /* ureg <- PM (indirect addressing) */
sharcop_pm_to_ureg_indirect()2523 void adsp21062_device::sharcop_pm_to_ureg_indirect()
2524 {
2525 int ureg = (m_core->opcode >> 32) & 0xff;
2526 uint32_t offset = m_core->opcode & 0xffffff;
2527 int i = (m_core->opcode >> 41) & 0x7;
2528
2529 if (ureg == 0xdb) /* PX is 48-bit */
2530 {
2531 m_core->px = pm_read48(PM_REG_I(i) + offset);
2532 }
2533 else
2534 {
2535 SET_UREG(ureg, pm_read32(PM_REG_I(i) + offset));
2536 }
2537 }
2538
2539 /* ureg -> PM (indirect addressing) */
sharcop_ureg_to_pm_indirect()2540 void adsp21062_device::sharcop_ureg_to_pm_indirect()
2541 {
2542 int ureg = (m_core->opcode >> 32) & 0xff;
2543 uint32_t offset = (uint32_t)m_core->opcode;
2544 int i = (m_core->opcode >> 41) & 0x7;
2545
2546 if (ureg == 0xdb) /* PX is 48-bit */
2547 {
2548 pm_write48(PM_REG_I(i) + offset, m_core->px);
2549 }
2550 else
2551 {
2552 pm_write32(PM_REG_I(i) + offset, GET_UREG(ureg));
2553 }
2554 }
2555
2556 /*****************************************************************************/
2557 /* | 1001xxxxx | */
2558
2559 /* immediate data -> DM|PM */
sharcop_imm_to_dmpm()2560 void adsp21062_device::sharcop_imm_to_dmpm()
2561 {
2562 int i = (m_core->opcode >> 41) & 0x7;
2563 int m = (m_core->opcode >> 38) & 0x7;
2564 int g = (m_core->opcode >> 37) & 0x1;
2565 uint32_t data = (uint32_t)m_core->opcode;
2566
2567 if (g)
2568 {
2569 /* program memory (PM) */
2570 pm_write32(PM_REG_I(i), data);
2571 PM_REG_I(i) += PM_REG_M(m);
2572 UPDATE_CIRCULAR_BUFFER_PM(i);
2573 }
2574 else
2575 {
2576 /* data memory (DM) */
2577 dm_write32(DM_REG_I(i), data);
2578 DM_REG_I(i) += DM_REG_M(m);
2579 UPDATE_CIRCULAR_BUFFER_DM(i);
2580 }
2581 }
2582
2583 /*****************************************************************************/
2584 /* | 00001111x | */
2585
2586 /* immediate data -> ureg */
sharcop_imm_to_ureg()2587 void adsp21062_device::sharcop_imm_to_ureg()
2588 {
2589 int ureg = (m_core->opcode >> 32) & 0xff;
2590 uint32_t data = (uint32_t)m_core->opcode;
2591
2592 SET_UREG(ureg, data);
2593 }
2594
2595 /*****************************************************************************/
2596 /* | 00010100x | */
2597
2598 /* system register bit manipulation */
sharcop_sysreg_bitop()2599 void adsp21062_device::sharcop_sysreg_bitop()
2600 {
2601 int bop = (m_core->opcode >> 37) & 0x7;
2602 int sreg = (m_core->opcode >> 32) & 0xf;
2603 uint32_t data = (uint32_t)m_core->opcode;
2604
2605 uint32_t src = GET_UREG(0x70 | sreg);
2606
2607 switch(bop)
2608 {
2609 case 0: /* SET */
2610 {
2611 src |= data;
2612 break;
2613 }
2614 case 1: /* CLEAR */
2615 {
2616 src &= ~data;
2617 break;
2618 }
2619 case 2: /* TOGGLE */
2620 {
2621 src ^= data;
2622 break;
2623 }
2624 case 4: /* TEST */
2625 {
2626 if ((src & data) == data)
2627 {
2628 m_core->astat |= BTF;
2629 }
2630 else
2631 {
2632 m_core->astat &= ~BTF;
2633 }
2634 break;
2635 }
2636 case 5: /* XOR */
2637 {
2638 if (src == data)
2639 {
2640 m_core->astat |= BTF;
2641 }
2642 else
2643 {
2644 m_core->astat &= ~BTF;
2645 }
2646 break;
2647 }
2648 default:
2649 fatalerror("SHARC: sysreg_bitop: invalid bitop %d\n", bop);
2650 break;
2651 }
2652
2653 SET_UREG(0x70 | sreg, src);
2654 }
2655
2656 /*****************************************************************************/
2657 /* | 000101100 | */
2658
2659 /* I register modify */
sharcop_modify()2660 void adsp21062_device::sharcop_modify()
2661 {
2662 int g = (m_core->opcode >> 38) & 0x1;
2663 int i = (m_core->opcode >> 32) & 0x7;
2664 int32_t data = (m_core->opcode);
2665
2666 if (g) // PM
2667 {
2668 PM_REG_I(i) += data;
2669 UPDATE_CIRCULAR_BUFFER_PM(i);
2670 }
2671 else // DM
2672 {
2673 DM_REG_I(i) += data;
2674 UPDATE_CIRCULAR_BUFFER_DM(i);
2675 }
2676 }
2677
2678 /*****************************************************************************/
2679 /* | 000101101 | */
2680
2681 /* I register bit-reverse */
sharcop_bit_reverse()2682 void adsp21062_device::sharcop_bit_reverse()
2683 {
2684 fatalerror("SHARC: sharcop_bit_reverse unimplemented\n");
2685 }
2686
2687 /*****************************************************************************/
2688 /* | 00010111x | */
2689
2690 /* push/pop stacks / flush cache */
sharcop_push_pop_stacks()2691 void adsp21062_device::sharcop_push_pop_stacks()
2692 {
2693 if (m_core->opcode & 0x008000000000U)
2694 {
2695 fatalerror("sharcop_push_pop_stacks: push loop not implemented\n");
2696 }
2697 if (m_core->opcode & 0x004000000000U)
2698 {
2699 fatalerror("sharcop_push_pop_stacks: pop loop not implemented\n");
2700 }
2701 if (m_core->opcode & 0x002000000000U)
2702 {
2703 //fatalerror("sharcop_push_pop_stacks: push sts not implemented\n");
2704 PUSH_STATUS_STACK();
2705 }
2706 if (m_core->opcode & 0x001000000000U)
2707 {
2708 //fatalerror("sharcop_push_pop_stacks: pop sts not implemented\n");
2709 POP_STATUS_STACK();
2710 }
2711 if (m_core->opcode & 0x000800000000U)
2712 {
2713 PUSH_PC(m_core->pcstk);
2714 }
2715 if (m_core->opcode & 0x000400000000U)
2716 {
2717 POP_PC();
2718 }
2719 }
2720
2721 /*****************************************************************************/
2722 /* | 000000000 | */
2723
sharcop_nop()2724 void adsp21062_device::sharcop_nop()
2725 {
2726 }
2727
2728 /*****************************************************************************/
2729 /* | 000000001 | */
2730
sharcop_idle()2731 void adsp21062_device::sharcop_idle()
2732 {
2733 //CHANGE_PC(m_core->pc);
2734
2735 m_core->daddr = m_core->pc;
2736 m_core->faddr = m_core->pc+1;
2737 m_core->nfaddr = m_core->pc+2;
2738
2739 m_core->idle = 1;
2740 }
2741
2742 /*****************************************************************************/
2743
sharcop_unimplemented()2744 void adsp21062_device::sharcop_unimplemented()
2745 {
2746 fatalerror("SHARC: Unimplemented opcode %04X%08X at %08X\n", (uint16_t)(m_core->opcode >> 32), (uint32_t)(m_core->opcode), m_core->pc);
2747 }
2748