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