1 /*###################################################################################################
2 **
3 **
4 **		jaguar.c
5 **		Core implementation for the portable Jaguar DSP emulator.
6 **		Written by Aaron Giles
7 **
8 **
9 **#################################################################################################*/
10 
11 #include <stdio.h>
12 #include <stddef.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include "driver.h"
16 #include "mamedbg.h"
17 #include "state.h"
18 #include "jaguar.h"
19 
20 
21 /*###################################################################################################
22 **	CONSTANTS
23 **#################################################################################################*/
24 
25 #define ZFLAG				0x00001
26 #define CFLAG				0x00002
27 #define NFLAG				0x00004
28 #define IFLAG				0x00008
29 #define EINT0FLAG			0x00010
30 #define EINT1FLAG			0x00020
31 #define EINT2FLAG			0x00040
32 #define EINT3FLAG			0x00080
33 #define EINT4FLAG			0x00100
34 #define EINT04FLAGS			(EINT0FLAG | EINT1FLAG | EINT2FLAG | EINT3FLAG | EINT4FLAG)
35 #define CINT0FLAG			0x00200
36 #define CINT1FLAG			0x00400
37 #define CINT2FLAG			0x00800
38 #define CINT3FLAG			0x01000
39 #define CINT4FLAG			0x02000
40 #define CINT04FLAGS			(CINT0FLAG | CINT1FLAG | CINT2FLAG | CINT3FLAG | CINT4FLAG)
41 #define RPAGEFLAG			0x04000
42 #define DMAFLAG				0x08000
43 #define EINT5FLAG			0x10000		/* DSP only */
44 #define CINT5FLAG			0x20000		/* DSP only */
45 
46 #define CLR_Z				(jaguar.FLAGS &= ~ZFLAG)
47 #define CLR_ZN				(jaguar.FLAGS &= ~(ZFLAG | NFLAG))
48 #define CLR_ZNC				(jaguar.FLAGS &= ~(CFLAG | ZFLAG | NFLAG))
49 #define SET_Z(r)			(jaguar.FLAGS |= ((r) == 0))
50 #define SET_C_ADD(a,b)		(jaguar.FLAGS |= ((UINT32)(b) > (UINT32)(~(a))) << 1)
51 #define SET_C_SUB(a,b)		(jaguar.FLAGS |= ((UINT32)(b) > (UINT32)(a)) << 1)
52 #define SET_N(r)			(jaguar.FLAGS |= (((UINT32)(r) >> 29) & 4))
53 #define SET_ZN(r)			SET_N(r); SET_Z(r)
54 #define SET_ZNC_ADD(a,b,r)	SET_N(r); SET_Z(r); SET_C_ADD(a,b)
55 #define SET_ZNC_SUB(a,b,r)	SET_N(r); SET_Z(r); SET_C_SUB(a,b)
56 
57 
58 
59 /*###################################################################################################
60 **	MACROS
61 **#################################################################################################*/
62 
63 #define PC				ctrl[G_PC]
64 #define FLAGS			ctrl[G_FLAGS]
65 
66 #define CONDITION(x)	condition_table[(x) + ((jaguar.FLAGS & 7) << 5)]
67 
68 #define READBYTE(a)		cpu_readmem24bedw(a)
69 #define READWORD(a)		cpu_readmem24bedw_word(a)
70 #define READLONG(a)		cpu_readmem24bedw_dword(a)
71 
72 #define WRITEBYTE(a,v)	cpu_writemem24bedw(a,v)
73 #define WRITEWORD(a,v)	cpu_writemem24bedw_word(a,v)
74 #define WRITELONG(a,v)	cpu_writemem24bedw_dword(a,v)
75 
76 
77 
78 /*###################################################################################################
79 **	STRUCTURES & TYPEDEFS
80 **#################################################################################################*/
81 
82 /* Jaguar Registers */
83 typedef struct
84 {
85 	/* core registers */
86 	UINT32		r[32];
87 	UINT32		a[32];
88 	UINT32 *	b0;
89 	UINT32 *	b1;
90 
91 	/* control registers */
92 	UINT32		ctrl[G_CTRLMAX];
93 	UINT32		ppc;
94 	UINT64		accum;
95 
96 	/* internal stuff */
97 	int			isdsp;
98 	int			op;
99 	int			interrupt_cycles;
100 	void 		(**table)(void);
101 	int 		(*irq_callback)(int irqline);
102 	void		(*cpu_interrupt)(void);
103 } jaguar_regs;
104 
105 
106 
107 /*###################################################################################################
108 **	PUBLIC GLOBAL VARIABLES
109 **#################################################################################################*/
110 
111 int	jaguar_icount;
112 static int bankswitch_icount;
113 
114 
115 
116 /*###################################################################################################
117 **	PRIVATE GLOBAL VARIABLES
118 **#################################################################################################*/
119 
120 static jaguar_regs	jaguar;
121 static UINT16 *		mirror_table;
122 static UINT8 *		condition_table;
123 static int			executing_cpu = -1;
124 
125 static const UINT32 convert_zero[32] =
126 { 32,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 };
127 
128 
129 
130 /*###################################################################################################
131 **	FUNCTION TABLES
132 **#################################################################################################*/
133 
134 static void abs_rn(void);
135 static void add_rn_rn(void);
136 static void addc_rn_rn(void);
137 static void addq_n_rn(void);
138 static void addqmod_n_rn(void);	/* DSP only */
139 static void addqt_n_rn(void);
140 static void and_rn_rn(void);
141 static void bclr_n_rn(void);
142 static void bset_n_rn(void);
143 static void btst_n_rn(void);
144 static void cmp_rn_rn(void);
145 static void cmpq_n_rn(void);
146 static void div_rn_rn(void);
147 static void illegal(void);
148 static void imacn_rn_rn(void);
149 static void imult_rn_rn(void);
150 static void imultn_rn_rn(void);
151 static void jr_cc_n(void);
152 static void jump_cc_rn(void);
153 static void load_rn_rn(void);
154 static void load_r14n_rn(void);
155 static void load_r15n_rn(void);
156 static void load_r14rn_rn(void);
157 static void load_r15rn_rn(void);
158 static void loadb_rn_rn(void);
159 static void loadw_rn_rn(void);
160 static void loadp_rn_rn(void);	/* GPU only */
161 static void mirror_rn(void);	/* DSP only */
162 static void mmult_rn_rn(void);
163 static void move_rn_rn(void);
164 static void move_pc_rn(void);
165 static void movefa_rn_rn(void);
166 static void movei_n_rn(void);
167 static void moveq_n_rn(void);
168 static void moveta_rn_rn(void);
169 static void mtoi_rn_rn(void);
170 static void mult_rn_rn(void);
171 static void neg_rn(void);
172 static void nop(void);
173 static void normi_rn_rn(void);
174 static void not_rn(void);
175 static void or_rn_rn(void);
176 static void pack_rn(void);		/* GPU only */
177 static void resmac_rn(void);
178 static void ror_rn_rn(void);
179 static void rorq_n_rn(void);
180 static void sat8_rn(void);		/* GPU only */
181 static void sat16_rn(void);		/* GPU only */
182 static void sat16s_rn(void);		/* DSP only */
183 static void sat24_rn(void);			/* GPU only */
184 static void sat32s_rn(void);		/* DSP only */
185 static void sh_rn_rn(void);
186 static void sha_rn_rn(void);
187 static void sharq_n_rn(void);
188 static void shlq_n_rn(void);
189 static void shrq_n_rn(void);
190 static void store_rn_rn(void);
191 static void store_rn_r14n(void);
192 static void store_rn_r15n(void);
193 static void store_rn_r14rn(void);
194 static void store_rn_r15rn(void);
195 static void storeb_rn_rn(void);
196 static void storew_rn_rn(void);
197 static void storep_rn_rn(void);	/* GPU only */
198 static void sub_rn_rn(void);
199 static void subc_rn_rn(void);
200 static void subq_n_rn(void);
201 static void subqmod_n_rn(void);	/* DSP only */
202 static void subqt_n_rn(void);
203 static void xor_rn_rn(void);
204 
205 static void (*gpu_op_table[64])(void) =
206 {
207 	/* 00-03 */	add_rn_rn,		addc_rn_rn,		addq_n_rn,		addqt_n_rn,
208 	/* 04-07 */	sub_rn_rn,		subc_rn_rn,		subq_n_rn,		subqt_n_rn,
209 	/* 08-11 */	neg_rn,			and_rn_rn,		or_rn_rn,		xor_rn_rn,
210 	/* 12-15 */	not_rn,			btst_n_rn,		bset_n_rn,		bclr_n_rn,
211 	/* 16-19 */	mult_rn_rn,		imult_rn_rn,	imultn_rn_rn,	resmac_rn,
212 	/* 20-23 */	imacn_rn_rn,	div_rn_rn,		abs_rn,			sh_rn_rn,
213 	/* 24-27 */	shlq_n_rn,		shrq_n_rn,		sha_rn_rn,		sharq_n_rn,
214 	/* 28-31 */	ror_rn_rn,		rorq_n_rn,		cmp_rn_rn,		cmpq_n_rn,
215 	/* 32-35 */	sat8_rn,		sat16_rn,		move_rn_rn,		moveq_n_rn,
216 	/* 36-39 */	moveta_rn_rn,	movefa_rn_rn,	movei_n_rn,		loadb_rn_rn,
217 	/* 40-43 */	loadw_rn_rn,	load_rn_rn,		loadp_rn_rn,	load_r14n_rn,
218 	/* 44-47 */	load_r15n_rn,	storeb_rn_rn,	storew_rn_rn,	store_rn_rn,
219 	/* 48-51 */	storep_rn_rn,	store_rn_r14n,	store_rn_r15n,	move_pc_rn,
220 	/* 52-55 */	jump_cc_rn,		jr_cc_n,		mmult_rn_rn,	mtoi_rn_rn,
221 	/* 56-59 */	normi_rn_rn,	nop,			load_r14rn_rn,	load_r15rn_rn,
222 	/* 60-63 */	store_rn_r14rn,	store_rn_r15rn,	sat24_rn,		pack_rn
223 };
224 
225 static void (*dsp_op_table[64])(void) =
226 {
227 	/* 00-03 */	add_rn_rn,		addc_rn_rn,		addq_n_rn,		addqt_n_rn,
228 	/* 04-07 */	sub_rn_rn,		subc_rn_rn,		subq_n_rn,		subqt_n_rn,
229 	/* 08-11 */	neg_rn,			and_rn_rn,		or_rn_rn,		xor_rn_rn,
230 	/* 12-15 */	not_rn,			btst_n_rn,		bset_n_rn,		bclr_n_rn,
231 	/* 16-19 */	mult_rn_rn,		imult_rn_rn,	imultn_rn_rn,	resmac_rn,
232 	/* 20-23 */	imacn_rn_rn,	div_rn_rn,		abs_rn,			sh_rn_rn,
233 	/* 24-27 */	shlq_n_rn,		shrq_n_rn,		sha_rn_rn,		sharq_n_rn,
234 	/* 28-31 */	ror_rn_rn,		rorq_n_rn,		cmp_rn_rn,		cmpq_n_rn,
235 	/* 32-35 */	subqmod_n_rn,	sat16s_rn,		move_rn_rn,		moveq_n_rn,
236 	/* 36-39 */	moveta_rn_rn,	movefa_rn_rn,	movei_n_rn,		loadb_rn_rn,
237 	/* 40-43 */	loadw_rn_rn,	load_rn_rn,		sat32s_rn,		load_r14n_rn,
238 	/* 44-47 */	load_r15n_rn,	storeb_rn_rn,	storew_rn_rn,	store_rn_rn,
239 	/* 48-51 */	mirror_rn,		store_rn_r14n,	store_rn_r15n,	move_pc_rn,
240 	/* 52-55 */	jump_cc_rn,		jr_cc_n,		mmult_rn_rn,	mtoi_rn_rn,
241 	/* 56-59 */	normi_rn_rn,	nop,			load_r14rn_rn,	load_r15rn_rn,
242 	/* 60-63 */	store_rn_r14rn,	store_rn_r15rn,	illegal,		addqmod_n_rn
243 };
244 
245 
246 
247 /*###################################################################################################
248 **	MEMORY ACCESSORS
249 **#################################################################################################*/
250 
251 #ifdef MSB_FIRST
252 #define ROPCODE(pc)		(*(UINT16 *)&OP_ROM[(UINT32)(pc)])
253 #else
254 #define ROPCODE(pc)		(*(UINT16 *)&OP_ROM[(UINT32)(pc) ^ 2])
255 #endif
256 
257 
258 
259 /*###################################################################################################
260 **	INLINES
261 **#################################################################################################*/
262 
update_register_banks(void)263 static INLINE void update_register_banks(void)
264 {
265 	UINT32 temp;
266 	int i, bank;
267 
268 	/* pick the bank */
269 	bank = jaguar.FLAGS & RPAGEFLAG;
270 	if (jaguar.FLAGS & IFLAG) bank = 0;
271 
272 	/* do we need to swap? */
273 	if ((!bank && jaguar.b0 != jaguar.r) || (bank && jaguar.b1 != jaguar.r))
274 	{
275 		/* remember the icount of the instruction after we swap */
276 		bankswitch_icount = jaguar_icount - 1;
277 
278 		/* exchange the contents */
279 		for (i = 0; i < 32; i++)
280 			temp = jaguar.r[i], jaguar.r[i] = jaguar.a[i], jaguar.a[i] = temp;
281 
282 		/* swap the bank pointers */
283 		if (!bank)
284 		{
285 			jaguar.b0 = jaguar.r;
286 			jaguar.b1 = jaguar.a;
287 		}
288 		else
289 		{
290 			jaguar.b0 = jaguar.a;
291 			jaguar.b1 = jaguar.r;
292 		}
293 	}
294 }
295 
296 
297 
298 /*###################################################################################################
299 **	IRQ HANDLING
300 **#################################################################################################*/
301 
check_irqs(void)302 static void check_irqs(void)
303 {
304 	int bits, mask, which = 0;
305 
306 	/* if the IMASK is set, bail */
307 	if (jaguar.FLAGS & IFLAG)
308 		return;
309 
310 	/* get the active interrupt bits */
311 	bits = (jaguar.ctrl[G_CTRL] >> 6) & 0x1f;
312 	bits |= (jaguar.ctrl[G_CTRL] >> 10) & 0x20;
313 
314 	/* get the interrupt mask */
315 	mask = (jaguar.FLAGS >> 4) & 0x1f;
316 	mask |= (jaguar.FLAGS >> 11) & 0x20;
317 
318 	/* bail if nothing is available */
319 	bits &= mask;
320 	if (!bits)
321 		return;
322 
323 	/* determine which interrupt */
324 	if (bits & 0x01) which = 0;
325 	if (bits & 0x02) which = 1;
326 	if (bits & 0x04) which = 2;
327 	if (bits & 0x08) which = 3;
328 	if (bits & 0x10) which = 4;
329 	if (bits & 0x20) which = 5;
330 
331 	/* set the interrupt flag */
332 	jaguar.FLAGS |= IFLAG;
333 	update_register_banks();
334 
335 	/* push the PC-2 on the stack */
336 	jaguar.r[31] -= 4;
337 	WRITELONG(jaguar.r[31], jaguar.PC - 2);
338 
339 	/* dispatch */
340 	jaguar.PC = (jaguar.isdsp) ? 0xf1b000 : 0xf03000;
341 	jaguar.PC += which * 0x10;
342 	change_pc24bedw(jaguar.PC);
343 }
344 
345 
jaguargpu_set_irq_line(int irqline,int state)346 void jaguargpu_set_irq_line(int irqline, int state)
347 {
348 	int mask = 0x40 << irqline;
349 	jaguar.ctrl[G_CTRL] &= ~mask;
350 	if (state != CLEAR_LINE)
351 	{
352 		jaguar.ctrl[G_CTRL] |= mask;
353 		check_irqs();
354 	}
355 }
356 
jaguardsp_set_irq_line(int irqline,int state)357 void jaguardsp_set_irq_line(int irqline, int state)
358 {
359 	int mask = (irqline < 5) ? (0x40 << irqline) : 0x10000;
360 	jaguar.ctrl[G_CTRL] &= ~mask;
361 	if (state != CLEAR_LINE)
362 	{
363 		jaguar.ctrl[G_CTRL] |= mask;
364 		check_irqs();
365 	}
366 }
367 
368 
jaguargpu_set_irq_callback(int (* callback)(int irqline))369 void jaguargpu_set_irq_callback(int (*callback)(int irqline))
370 {
371 	jaguar.irq_callback = callback;
372 }
373 
jaguardsp_set_irq_callback(int (* callback)(int irqline))374 void jaguardsp_set_irq_callback(int (*callback)(int irqline))
375 {
376 	jaguar.irq_callback = callback;
377 }
378 
379 
380 
381 /*###################################################################################################
382 **	CONTEXT SWITCHING
383 **#################################################################################################*/
384 
jaguargpu_get_context(void * dst)385 unsigned jaguargpu_get_context(void *dst)
386 {
387 	/* copy the context */
388 	if (dst)
389 		*(jaguar_regs *)dst = jaguar;
390 
391 	/* return the context size */
392 	return sizeof(jaguar_regs);
393 }
394 
jaguardsp_get_context(void * dst)395 unsigned jaguardsp_get_context(void *dst)
396 {
397 	/* copy the context */
398 	if (dst)
399 		*(jaguar_regs *)dst = jaguar;
400 
401 	/* return the context size */
402 	return sizeof(jaguar_regs);
403 }
404 
405 
jaguargpu_set_context(void * src)406 void jaguargpu_set_context(void *src)
407 {
408 	/* copy the context */
409 	if (src)
410 		jaguar = *(jaguar_regs *)src;
411 
412 	/* check for IRQs */
413 	check_irqs();
414 }
415 
jaguardsp_set_context(void * src)416 void jaguardsp_set_context(void *src)
417 {
418 	/* copy the context */
419 	if (src)
420 		jaguar = *(jaguar_regs *)src;
421 
422 	/* check for IRQs */
423 	check_irqs();
424 }
425 
426 
427 /*###################################################################################################
428 **	INITIALIZATION AND SHUTDOWN
429 **#################################################################################################*/
430 
init_tables(void)431 static void init_tables(void)
432 {
433 	int i, j;
434 
435 	/* allocate the mirror table */
436 	if (!mirror_table)
437 		mirror_table = malloc(65536 * sizeof(mirror_table[0]));
438 
439 	/* fill in the mirror table */
440 	if (mirror_table)
441 		for (i = 0; i < 65536; i++)
442 			mirror_table[i] = ((i >> 15) & 0x0001) | ((i >> 13) & 0x0002) |
443 			                  ((i >> 11) & 0x0004) | ((i >> 9)  & 0x0008) |
444 			                  ((i >> 7)  & 0x0010) | ((i >> 5)  & 0x0020) |
445 			                  ((i >> 3)  & 0x0040) | ((i >> 1)  & 0x0080) |
446 			                  ((i << 1)  & 0x0100) | ((i << 3)  & 0x0200) |
447 			                  ((i << 5)  & 0x0400) | ((i << 7)  & 0x0800) |
448 			                  ((i << 9)  & 0x1000) | ((i << 11) & 0x2000) |
449 			                  ((i << 13) & 0x4000) | ((i << 15) & 0x8000);
450 
451 	/* allocate the condition table */
452 	if (!condition_table)
453 		condition_table = malloc(32 * 8 * sizeof(condition_table[0]));
454 
455 	/* fill in the condition table */
456 	if (condition_table)
457 		for (i = 0; i < 8; i++)
458 			for (j = 0; j < 32; j++)
459 			{
460 				int result = 1;
461 				if (j & 1)
462 					if (i & ZFLAG) result = 0;
463 				if (j & 2)
464 					if (!(i & ZFLAG)) result = 0;
465 				if (j & 4)
466 					if (i & (CFLAG << (j >> 4))) result = 0;
467 				if (j & 8)
468 					if (!(i & (CFLAG << (j >> 4)))) result = 0;
469 				condition_table[i * 32 + j] = result;
470 			}
471 }
472 
jaguar_state_register(const char * type)473 static void jaguar_state_register(const char *type)
474 {
475 	int cpu = cpu_getactivecpu();
476 	state_save_register_UINT32(type, cpu, "R",    jaguar.r, 32);
477 	state_save_register_UINT32(type, cpu, "A",    jaguar.a, 32);
478 	state_save_register_UINT32(type, cpu, "CTRL", jaguar.ctrl, G_CTRLMAX);
479 	state_save_register_UINT32(type, cpu, "PPC",  &jaguar.ppc, 1);
480 	state_save_register_func_postload(update_register_banks);
481 	state_save_register_func_postload(check_irqs);
482 }
483 
jaguargpu_init(void)484 void jaguargpu_init(void)
485 {
486 	jaguar_state_register("jaguargpu");
487 }
488 
jaguardsp_init(void)489 void jaguardsp_init(void)
490 {
491 	jaguar_state_register("jaguardsp");
492 }
493 
common_reset(struct jaguar_config * config)494 static INLINE void common_reset(struct jaguar_config *config)
495 {
496 	init_tables();
497 
498 	if (config)
499 		jaguar.cpu_interrupt = config->cpu_int_callback;
500 
501 	jaguar.b0 = jaguar.r;
502 	jaguar.b1 = jaguar.a;
503 
504 	change_pc24bedw(jaguar.PC);
505 }
506 
jaguargpu_reset(void * param)507 void jaguargpu_reset(void *param)
508 {
509 	common_reset(param);
510 	jaguar.table = gpu_op_table;
511 	jaguar.isdsp = 0;
512 }
513 
jaguardsp_reset(void * param)514 void jaguardsp_reset(void *param)
515 {
516 	common_reset(param);
517 	jaguar.table = dsp_op_table;
518 	jaguar.isdsp = 1;
519 }
520 
common_exit(void)521 static INLINE void common_exit(void)
522 {
523 	if (mirror_table)
524 		free(mirror_table);
525 	mirror_table = NULL;
526 
527 	if (condition_table)
528 		free(condition_table);
529 	condition_table = NULL;
530 }
531 
jaguargpu_exit(void)532 void jaguargpu_exit(void)
533 {
534 	common_exit();
535 }
536 
jaguardsp_exit(void)537 void jaguardsp_exit(void)
538 {
539 	common_exit();
540 }
541 
542 
543 
544 /*###################################################################################################
545 **	CORE EXECUTION LOOP
546 **#################################################################################################*/
547 
jaguargpu_execute(int cycles)548 int jaguargpu_execute(int cycles)
549 {
550 	/* if we're halted, we shouldn't be here */
551 	if (!(jaguar.ctrl[G_CTRL] & 1))
552 	{
553 		cpu_set_halt_line(cpu_getactivecpu(), ASSERT_LINE);
554 		return cycles;
555 	}
556 
557 	/* count cycles and interrupt cycles */
558 	bankswitch_icount = -1000;
559 	jaguar_icount = cycles;
560 	jaguar_icount -= jaguar.interrupt_cycles;
561 	jaguar.interrupt_cycles = 0;
562 	change_pc24bedw(jaguar.PC);
563 
564 	/* remember that we're executing */
565 	executing_cpu = cpu_getactivecpu();
566 
567 	/* core execution loop */
568 	do
569 	{
570 		/* debugging */
571 		/*if (jaguar.PC < 0xf03000 || jaguar.PC > 0xf04000) { fprintf(stderr, "GPU: jaguar.PC = %06X (ppc = %06X)\n", jaguar.PC, jaguar.ppc); exit(1); }*/
572 		jaguar.ppc = jaguar.PC;
573 		CALL_MAME_DEBUG;
574 
575 		/* instruction fetch */
576 		jaguar.op = ROPCODE(jaguar.PC);
577 		jaguar.PC += 2;
578 
579 		/* parse the instruction */
580 		(*gpu_op_table[jaguar.op >> 10])();
581 		jaguar_icount--;
582 
583 	} while (jaguar_icount > 0 || jaguar_icount == bankswitch_icount);
584 
585 	/* no longer executing */
586 	executing_cpu = -1;
587 
588 	/* adjust cycles for interrupts */
589 	jaguar_icount -= jaguar.interrupt_cycles;
590 	jaguar.interrupt_cycles = 0;
591 	return cycles - jaguar_icount;
592 }
593 
jaguardsp_execute(int cycles)594 int jaguardsp_execute(int cycles)
595 {
596 	/* if we're halted, we shouldn't be here */
597 	if (!(jaguar.ctrl[G_CTRL] & 1))
598 	{
599 		cpu_set_halt_line(cpu_getactivecpu(), ASSERT_LINE);
600 		return cycles;
601 	}
602 
603 	/* count cycles and interrupt cycles */
604 	bankswitch_icount = -1000;
605 	jaguar_icount = cycles;
606 	jaguar_icount -= jaguar.interrupt_cycles;
607 	jaguar.interrupt_cycles = 0;
608 	change_pc24bedw(jaguar.PC);
609 
610 	/* remember that we're executing */
611 	executing_cpu = cpu_getactivecpu();
612 
613 	/* core execution loop */
614 	do
615 	{
616 		/* debugging */
617 		/*if (jaguar.PC < 0xf1b000 || jaguar.PC > 0xf1d000) { fprintf(stderr, "DSP: jaguar.PC = %06X\n", jaguar.PC); exit(1); }*/
618 		jaguar.ppc = jaguar.PC;
619 		CALL_MAME_DEBUG;
620 
621 		/* instruction fetch */
622 		jaguar.op = ROPCODE(jaguar.PC);
623 		jaguar.PC += 2;
624 
625 		/* parse the instruction */
626 		(*dsp_op_table[jaguar.op >> 10])();
627 		jaguar_icount--;
628 
629 	} while (jaguar_icount > 0 || jaguar_icount == bankswitch_icount);
630 
631 	/* no longer executing */
632 	executing_cpu = -1;
633 
634 	/* adjust cycles for interrupts */
635 	jaguar_icount -= jaguar.interrupt_cycles;
636 	jaguar.interrupt_cycles = 0;
637 	return cycles - jaguar_icount;
638 }
639 
640 
641 
642 /*###################################################################################################
643 **	REGISTER SNOOP
644 **#################################################################################################*/
645 
common_get_reg(int regnum)646 static INLINE unsigned common_get_reg(int regnum)
647 {
648 	switch (regnum)
649 	{
650 		case REG_PC:
651 		case JAGUAR_PC:		return jaguar.PC;
652 		case JAGUAR_FLAGS:	return jaguar.FLAGS;
653 
654 		case JAGUAR_R0:		return jaguar.r[0];
655 		case JAGUAR_R1:		return jaguar.r[1];
656 		case JAGUAR_R2:		return jaguar.r[2];
657 		case JAGUAR_R3:		return jaguar.r[3];
658 		case JAGUAR_R4:		return jaguar.r[4];
659 		case JAGUAR_R5:		return jaguar.r[5];
660 		case JAGUAR_R6:		return jaguar.r[6];
661 		case JAGUAR_R7:		return jaguar.r[7];
662 		case JAGUAR_R8:		return jaguar.r[8];
663 		case JAGUAR_R9:		return jaguar.r[9];
664 		case JAGUAR_R10:	return jaguar.r[10];
665 		case JAGUAR_R11:	return jaguar.r[11];
666 		case JAGUAR_R12:	return jaguar.r[12];
667 		case JAGUAR_R13:	return jaguar.r[13];
668 		case JAGUAR_R14:	return jaguar.r[14];
669 		case JAGUAR_R15:	return jaguar.r[15];
670 		case JAGUAR_R16:	return jaguar.r[16];
671 		case JAGUAR_R17:	return jaguar.r[17];
672 		case JAGUAR_R18:	return jaguar.r[18];
673 		case JAGUAR_R19:	return jaguar.r[19];
674 		case JAGUAR_R20:	return jaguar.r[20];
675 		case JAGUAR_R21:	return jaguar.r[21];
676 		case JAGUAR_R22:	return jaguar.r[22];
677 		case JAGUAR_R23:	return jaguar.r[23];
678 		case JAGUAR_R24:	return jaguar.r[24];
679 		case JAGUAR_R25:	return jaguar.r[25];
680 		case JAGUAR_R26:	return jaguar.r[26];
681 		case JAGUAR_R27:	return jaguar.r[27];
682 		case JAGUAR_R28:	return jaguar.r[28];
683 		case JAGUAR_R29:	return jaguar.r[29];
684 		case JAGUAR_R30:	return jaguar.r[30];
685 		case JAGUAR_R31:	return jaguar.r[31];
686 		case REG_SP:		return jaguar.b0[31];
687 
688 		case REG_PREVIOUSPC: return jaguar.ppc;
689 
690 		default:
691 			if (regnum <= REG_SP_CONTENTS)
692 			{
693 /*				unsigned offset = REG_SP_CONTENTS - regnum;*/
694 /*				if (offset < PC_STACK_DEPTH)*/
695 /*					return jaguar.pc_stack[offset];*/
696 			}
697 	}
698 	return 0;
699 }
700 
jaguargpu_get_reg(int regnum)701 unsigned jaguargpu_get_reg(int regnum)
702 {
703 	return common_get_reg(regnum);
704 }
705 
jaguardsp_get_reg(int regnum)706 unsigned jaguardsp_get_reg(int regnum)
707 {
708 	return common_get_reg(regnum);
709 }
710 
711 
712 
713 /*###################################################################################################
714 **	REGISTER MODIFY
715 **#################################################################################################*/
716 
common_set_reg(int regnum,unsigned val)717 static INLINE void common_set_reg(int regnum, unsigned val)
718 {
719 	switch (regnum)
720 	{
721 		case REG_PC:
722 		case JAGUAR_PC:		jaguar.PC = val;	break;
723 		case JAGUAR_FLAGS:	jaguar.FLAGS = val;	break;
724 
725 		case JAGUAR_R0:		jaguar.r[0] = val;	break;
726 		case JAGUAR_R1:		jaguar.r[1] = val;	break;
727 		case JAGUAR_R2:		jaguar.r[2] = val;	break;
728 		case JAGUAR_R3:		jaguar.r[3] = val;	break;
729 		case JAGUAR_R4:		jaguar.r[4] = val;	break;
730 		case JAGUAR_R5:		jaguar.r[5] = val;	break;
731 		case JAGUAR_R6:		jaguar.r[6] = val;	break;
732 		case JAGUAR_R7:		jaguar.r[7] = val;	break;
733 		case JAGUAR_R8:		jaguar.r[8] = val;	break;
734 		case JAGUAR_R9:		jaguar.r[9] = val;	break;
735 		case JAGUAR_R10:	jaguar.r[10] = val;	break;
736 		case JAGUAR_R11:	jaguar.r[11] = val;	break;
737 		case JAGUAR_R12:	jaguar.r[12] = val;	break;
738 		case JAGUAR_R13:	jaguar.r[13] = val;	break;
739 		case JAGUAR_R14:	jaguar.r[14] = val;	break;
740 		case JAGUAR_R15:	jaguar.r[15] = val;	break;
741 		case JAGUAR_R16:	jaguar.r[16] = val;	break;
742 		case JAGUAR_R17:	jaguar.r[17] = val;	break;
743 		case JAGUAR_R18:	jaguar.r[18] = val;	break;
744 		case JAGUAR_R19:	jaguar.r[19] = val;	break;
745 		case JAGUAR_R20:	jaguar.r[20] = val;	break;
746 		case JAGUAR_R21:	jaguar.r[21] = val;	break;
747 		case JAGUAR_R22:	jaguar.r[22] = val;	break;
748 		case JAGUAR_R23:	jaguar.r[23] = val;	break;
749 		case JAGUAR_R24:	jaguar.r[24] = val;	break;
750 		case JAGUAR_R25:	jaguar.r[25] = val;	break;
751 		case JAGUAR_R26:	jaguar.r[26] = val;	break;
752 		case JAGUAR_R27:	jaguar.r[27] = val;	break;
753 		case JAGUAR_R28:	jaguar.r[28] = val;	break;
754 		case JAGUAR_R29:	jaguar.r[29] = val;	break;
755 		case JAGUAR_R30:	jaguar.r[30] = val;	break;
756 		case JAGUAR_R31:	jaguar.r[31] = val;	break;
757 		case REG_SP:		jaguar.b0[31] = val; break;
758 
759 		default:
760 			if (regnum <= REG_SP_CONTENTS)
761 			{
762 /*				unsigned offset = REG_SP_CONTENTS - regnum;*/
763 /*				if (offset < PC_STACK_DEPTH)*/
764 /*					jaguar.pc_stack[offset] = val;*/
765 			}
766     }
767 }
768 
jaguargpu_set_reg(int regnum,unsigned val)769 void jaguargpu_set_reg(int regnum, unsigned val)
770 {
771 	common_set_reg(regnum, val);
772 }
773 
jaguardsp_set_reg(int regnum,unsigned val)774 void jaguardsp_set_reg(int regnum, unsigned val)
775 {
776 	common_set_reg(regnum, val);
777 }
778 
779 
780 
781 /*###################################################################################################
782 **	DEBUGGER DEFINITIONS
783 **#################################################################################################*/
784 
785 static UINT8 jaguar_reg_layout[] =
786 {
787 	JAGUAR_PC,		JAGUAR_FLAGS,	-1,
788 	JAGUAR_R0,	 	JAGUAR_R16,		-1,
789 	JAGUAR_R1, 		JAGUAR_R17,		-1,
790 	JAGUAR_R2, 		JAGUAR_R18,		-1,
791 	JAGUAR_R3, 		JAGUAR_R19,		-1,
792 	JAGUAR_R4, 		JAGUAR_R20,		-1,
793 	JAGUAR_R5, 		JAGUAR_R21,		-1,
794 	JAGUAR_R6, 		JAGUAR_R22,		-1,
795 	JAGUAR_R7, 		JAGUAR_R23,		-1,
796 	JAGUAR_R8,		JAGUAR_R24,		-1,
797 	JAGUAR_R9,		JAGUAR_R25,		-1,
798 	JAGUAR_R10,		JAGUAR_R26,		-1,
799 	JAGUAR_R11,		JAGUAR_R27,		-1,
800 	JAGUAR_R12,		JAGUAR_R28,		-1,
801 	JAGUAR_R13,		JAGUAR_R29,		-1,
802 	JAGUAR_R14,		JAGUAR_R30,		-1,
803 	JAGUAR_R15,		JAGUAR_R31,		0
804 };
805 
806 static UINT8 jaguar_win_layout[] =
807 {
808 	 0, 0,30,20,	/* register window (top rows) */
809 	31, 0,48,14,	/* disassembler window (left colums) */
810 	 0,21,30, 1,	/* memory #1 window (right, upper middle) */
811 	31,15,48, 7,	/* memory #2 window (right, lower middle) */
812 	 0,23,80, 1,	/* command line window (bottom rows) */
813 };
814 
815 
816 
817 /*###################################################################################################
818 **	DEBUGGER STRINGS
819 **#################################################################################################*/
820 
common_info(void * context,int regnum)821 static const char *common_info(void *context, int regnum)
822 {
823 	static char buffer[16][47+1];
824 	static int which = 0;
825 	jaguar_regs *r = context;
826 
827 	which = (which+1) % 16;
828     buffer[which][0] = '\0';
829 
830 	if (!context)
831 		r = &jaguar;
832 
833     switch( regnum )
834 	{
835 		case CPU_INFO_REG+JAGUAR_PC:  	sprintf(buffer[which], "PC: %08X", r->PC); break;
836 
837 		case CPU_INFO_REG+JAGUAR_R0:	sprintf(buffer[which], "R0: %08X", r->r[0]); break;
838 		case CPU_INFO_REG+JAGUAR_R1:	sprintf(buffer[which], "R1: %08X", r->r[1]); break;
839 		case CPU_INFO_REG+JAGUAR_R2:	sprintf(buffer[which], "R2: %08X", r->r[2]); break;
840 		case CPU_INFO_REG+JAGUAR_R3:	sprintf(buffer[which], "R3: %08X", r->r[3]); break;
841 		case CPU_INFO_REG+JAGUAR_R4:	sprintf(buffer[which], "R4: %08X", r->r[4]); break;
842 		case CPU_INFO_REG+JAGUAR_R5:	sprintf(buffer[which], "R5: %08X", r->r[5]); break;
843 		case CPU_INFO_REG+JAGUAR_R6:	sprintf(buffer[which], "R6: %08X", r->r[6]); break;
844 		case CPU_INFO_REG+JAGUAR_R7:	sprintf(buffer[which], "R7: %08X", r->r[7]); break;
845 		case CPU_INFO_REG+JAGUAR_R8:	sprintf(buffer[which], "R8: %08X", r->r[8]); break;
846 		case CPU_INFO_REG+JAGUAR_R9:	sprintf(buffer[which], "R9: %08X", r->r[9]); break;
847 		case CPU_INFO_REG+JAGUAR_R10:	sprintf(buffer[which], "R10:%08X", r->r[10]); break;
848 		case CPU_INFO_REG+JAGUAR_R11:	sprintf(buffer[which], "R11:%08X", r->r[11]); break;
849 		case CPU_INFO_REG+JAGUAR_R12:	sprintf(buffer[which], "R12:%08X", r->r[12]); break;
850 		case CPU_INFO_REG+JAGUAR_R13:	sprintf(buffer[which], "R13:%08X", r->r[13]); break;
851 		case CPU_INFO_REG+JAGUAR_R14:	sprintf(buffer[which], "R14:%08X", r->r[14]); break;
852 		case CPU_INFO_REG+JAGUAR_R15:	sprintf(buffer[which], "R15:%08X", r->r[15]); break;
853 		case CPU_INFO_REG+JAGUAR_R16:	sprintf(buffer[which], "R16:%08X", r->r[16]); break;
854 		case CPU_INFO_REG+JAGUAR_R17:	sprintf(buffer[which], "R17:%08X", r->r[17]); break;
855 		case CPU_INFO_REG+JAGUAR_R18:	sprintf(buffer[which], "R18:%08X", r->r[18]); break;
856 		case CPU_INFO_REG+JAGUAR_R19:	sprintf(buffer[which], "R19:%08X", r->r[19]); break;
857 		case CPU_INFO_REG+JAGUAR_R20:	sprintf(buffer[which], "R20:%08X", r->r[20]); break;
858 		case CPU_INFO_REG+JAGUAR_R21:	sprintf(buffer[which], "R21:%08X", r->r[21]); break;
859 		case CPU_INFO_REG+JAGUAR_R22:	sprintf(buffer[which], "R22:%08X", r->r[22]); break;
860 		case CPU_INFO_REG+JAGUAR_R23:	sprintf(buffer[which], "R23:%08X", r->r[23]); break;
861 		case CPU_INFO_REG+JAGUAR_R24:	sprintf(buffer[which], "R24:%08X", r->r[24]); break;
862 		case CPU_INFO_REG+JAGUAR_R25:	sprintf(buffer[which], "R25:%08X", r->r[25]); break;
863 		case CPU_INFO_REG+JAGUAR_R26:	sprintf(buffer[which], "R26:%08X", r->r[26]); break;
864 		case CPU_INFO_REG+JAGUAR_R27:	sprintf(buffer[which], "R27:%08X", r->r[27]); break;
865 		case CPU_INFO_REG+JAGUAR_R28:	sprintf(buffer[which], "R28:%08X", r->r[28]); break;
866 		case CPU_INFO_REG+JAGUAR_R29:	sprintf(buffer[which], "R29:%08X", r->r[29]); break;
867 		case CPU_INFO_REG+JAGUAR_R30:	sprintf(buffer[which], "R30:%08X", r->r[30]); break;
868 		case CPU_INFO_REG+JAGUAR_R31:	sprintf(buffer[which], "R31:%08X", r->r[31]); break;
869 
870 		case CPU_INFO_REG+JAGUAR_FLAGS:	sprintf(buffer[which], "%c%c%c%c%c%c%c%c%c%c%c",
871 												r->FLAGS & 0x8000 ? 'D':'.',
872 												r->FLAGS & 0x4000 ? 'A':'.',
873 												r->FLAGS & 0x0100 ? '4':'.',
874 												r->FLAGS & 0x0080 ? '3':'.',
875 												r->FLAGS & 0x0040 ? '2':'.',
876 												r->FLAGS & 0x0020 ? '1':'.',
877 												r->FLAGS & 0x0010 ? '0':'.',
878 												r->FLAGS & 0x0008 ? 'I':'.',
879 												r->FLAGS & 0x0004 ? 'N':'.',
880 												r->FLAGS & 0x0002 ? 'C':'.',
881 												r->FLAGS & 0x0001 ? 'Z':'.'); break;
882 
883 		case CPU_INFO_FAMILY: return "Jaguar";
884 		case CPU_INFO_VERSION: return "1.0";
885 		case CPU_INFO_FILE: return __FILE__;
886 		case CPU_INFO_CREDITS: return "Copyright (C) Aaron Giles 2000-2002";
887 		case CPU_INFO_REG_LAYOUT: return (const char *)jaguar_reg_layout;
888 		case CPU_INFO_WIN_LAYOUT: return (const char *)jaguar_win_layout;
889 		case CPU_INFO_REG+10000: return "         ";
890     }
891 	return buffer[which];
892 }
893 
jaguargpu_info(void * context,int regnum)894 const char *jaguargpu_info(void *context, int regnum)
895 {
896 	switch (regnum)
897 	{
898 		case CPU_INFO_NAME: return "Jaguar GPU";
899 		default:			return common_info(context, regnum);
900 	}
901 }
902 
jaguardsp_info(void * context,int regnum)903 const char *jaguardsp_info(void *context, int regnum)
904 {
905 	switch (regnum)
906 	{
907 		case CPU_INFO_NAME: return "Jaguar DSP";
908 		default:			return common_info(context, regnum);
909 	}
910 }
911 
912 
913 
914 /*###################################################################################################
915 **	DISASSEMBLY HOOK
916 **#################################################################################################*/
917 
jaguargpu_dasm(char * buffer,unsigned pc)918 unsigned jaguargpu_dasm(char *buffer, unsigned pc)
919 {
920 #ifdef MAME_DEBUG
921 	extern unsigned dasmjag(int, char *, unsigned);
922     return dasmjag(JAGUAR_VARIANT_GPU, buffer, pc);
923 #else
924 	sprintf(buffer, "$%04X", ROPCODE(pc));
925 	return 2;
926 #endif
927 }
928 
jaguardsp_dasm(char * buffer,unsigned pc)929 unsigned jaguardsp_dasm(char *buffer, unsigned pc)
930 {
931 #ifdef MAME_DEBUG
932 	extern unsigned dasmjag(int, char *, unsigned);
933     return dasmjag(JAGUAR_VARIANT_DSP, buffer, pc);
934 #else
935 	sprintf(buffer, "$%04X", ROPCODE(pc));
936 	return 2;
937 #endif
938 }
939 
940 
941 
942 /*###################################################################################################
943 **	OPCODES
944 **#################################################################################################*/
945 
abs_rn(void)946 void abs_rn(void)
947 {
948 	int dreg = jaguar.op & 31;
949 	UINT32 res = jaguar.r[dreg];
950 	CLR_ZNC;
951 	if (res & 0x80000000)
952 	{
953 		jaguar.r[dreg] = res = -res;
954 		jaguar.FLAGS |= CFLAG;
955 	}
956 	SET_Z(res);
957 }
958 
add_rn_rn(void)959 void add_rn_rn(void)
960 {
961 	int dreg = jaguar.op & 31;
962 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
963 	UINT32 r2 = jaguar.r[dreg];
964 	UINT32 res = r2 + r1;
965 	jaguar.r[dreg] = res;
966 	CLR_ZNC; SET_ZNC_ADD(r2,r1,res);
967 }
968 
addc_rn_rn(void)969 void addc_rn_rn(void)
970 {
971 	int dreg = jaguar.op & 31;
972 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
973 	UINT32 r2 = jaguar.r[dreg];
974 	UINT32 res = r2 + r1 + ((jaguar.FLAGS >> 1) & 1);
975 	jaguar.r[dreg] = res;
976 	CLR_ZNC; SET_ZNC_ADD(r2,r1,res);
977 }
978 
addq_n_rn(void)979 void addq_n_rn(void)
980 {
981 	int dreg = jaguar.op & 31;
982 	UINT32 r1 = convert_zero[(jaguar.op >> 5) & 31];
983 	UINT32 r2 = jaguar.r[dreg];
984 	UINT32 res = r2 + r1;
985 	jaguar.r[dreg] = res;
986 	CLR_ZNC; SET_ZNC_ADD(r2,r1,res);
987 }
988 
addqmod_n_rn(void)989 void addqmod_n_rn(void)	/* DSP only */
990 {
991 	int dreg = jaguar.op & 31;
992 	UINT32 r1 = convert_zero[(jaguar.op >> 5) & 31];
993 	UINT32 r2 = jaguar.r[dreg];
994 	UINT32 res = r2 + r1;
995 	res = (res & ~jaguar.ctrl[D_MOD]) | (r2 & ~jaguar.ctrl[D_MOD]);
996 	jaguar.r[dreg] = res;
997 	CLR_ZNC; SET_ZNC_ADD(r2,r1,res);
998 }
999 
addqt_n_rn(void)1000 void addqt_n_rn(void)
1001 {
1002 	int dreg = jaguar.op & 31;
1003 	UINT32 r1 = convert_zero[(jaguar.op >> 5) & 31];
1004 	UINT32 r2 = jaguar.r[dreg];
1005 	UINT32 res = r2 + r1;
1006 	jaguar.r[dreg] = res;
1007 }
1008 
and_rn_rn(void)1009 void and_rn_rn(void)
1010 {
1011 	int dreg = jaguar.op & 31;
1012 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1013 	UINT32 r2 = jaguar.r[dreg];
1014 	UINT32 res = r2 & r1;
1015 	jaguar.r[dreg] = res;
1016 	CLR_ZN; SET_ZN(res);
1017 }
1018 
bclr_n_rn(void)1019 void bclr_n_rn(void)
1020 {
1021 	int dreg = jaguar.op & 31;
1022 	UINT32 r1 = (jaguar.op >> 5) & 31;
1023 	UINT32 r2 = jaguar.r[dreg];
1024 	UINT32 res = r2 & ~(1 << r1);
1025 	jaguar.r[dreg] = res;
1026 	CLR_ZN; SET_ZN(res);
1027 }
1028 
bset_n_rn(void)1029 void bset_n_rn(void)
1030 {
1031 	int dreg = jaguar.op & 31;
1032 	UINT32 r1 = (jaguar.op >> 5) & 31;
1033 	UINT32 r2 = jaguar.r[dreg];
1034 	UINT32 res = r2 | (1 << r1);
1035 	jaguar.r[dreg] = res;
1036 	CLR_ZN; SET_ZN(res);
1037 }
1038 
btst_n_rn(void)1039 void btst_n_rn(void)
1040 {
1041 	UINT32 r1 = (jaguar.op >> 5) & 31;
1042 	UINT32 r2 = jaguar.r[jaguar.op & 31];
1043 	CLR_Z; jaguar.FLAGS |= (~r2 >> r1) & 1;
1044 }
1045 
cmp_rn_rn(void)1046 void cmp_rn_rn(void)
1047 {
1048 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1049 	UINT32 r2 = jaguar.r[jaguar.op & 31];
1050 	UINT32 res = r2 - r1;
1051 	CLR_ZNC; SET_ZNC_SUB(r2,r1,res);
1052 }
1053 
cmpq_n_rn(void)1054 void cmpq_n_rn(void)
1055 {
1056 	UINT32 r1 = (INT8)(jaguar.op >> 2) >> 3;
1057 	UINT32 r2 = jaguar.r[jaguar.op & 31];
1058 	UINT32 res = r2 - r1;
1059 	CLR_ZNC; SET_ZNC_SUB(r2,r1,res);
1060 }
1061 
div_rn_rn(void)1062 void div_rn_rn(void)
1063 {
1064 	int dreg = jaguar.op & 31;
1065 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1066 	UINT32 r2 = jaguar.r[dreg];
1067 	if (r1)
1068 	{
1069 		if (jaguar.ctrl[D_DIVCTRL] & 1)
1070 		{
1071 			jaguar.r[dreg] = ((UINT64)r2 << 16) / r1;
1072 			jaguar.ctrl[D_REMAINDER] = ((UINT64)r2 << 16) % r1;
1073 		}
1074 		else
1075 		{
1076 			jaguar.r[dreg] = r2 / r1;
1077 			jaguar.ctrl[D_REMAINDER] = r2 % r1;
1078 		}
1079 	}
1080 	else
1081 		jaguar.r[dreg] = 0xffffffff;
1082 }
1083 
illegal(void)1084 void illegal(void)
1085 {
1086 }
1087 
imacn_rn_rn(void)1088 void imacn_rn_rn(void)
1089 {
1090 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1091 	UINT32 r2 = jaguar.r[jaguar.op & 31];
1092 	jaguar.accum += (INT64)((INT16)r1 * (INT16)r2);
1093 	log_cb(RETRO_LOG_DEBUG, LOGPRE "Unexpected IMACN instruction!\n");
1094 }
1095 
imult_rn_rn(void)1096 void imult_rn_rn(void)
1097 {
1098 	int dreg = jaguar.op & 31;
1099 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1100 	UINT32 r2 = jaguar.r[dreg];
1101 	UINT32 res = (INT16)r1 * (INT16)r2;
1102 	jaguar.r[dreg] = res;
1103 	CLR_ZN; SET_ZN(res);
1104 }
1105 
imultn_rn_rn(void)1106 void imultn_rn_rn(void)
1107 {
1108 	int dreg = jaguar.op & 31;
1109 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1110 	UINT32 r2 = jaguar.r[dreg];
1111 	UINT32 res = (INT16)r1 * (INT16)r2;
1112 	jaguar.accum = (INT32)res;
1113 	CLR_ZN; SET_ZN(res);
1114 
1115 	jaguar.op = ROPCODE(jaguar.PC);
1116 	while ((jaguar.op >> 10) == 20)
1117 	{
1118 		r1 = jaguar.r[(jaguar.op >> 5) & 31];
1119 		r2 = jaguar.r[jaguar.op & 31];
1120 		jaguar.accum += (INT64)((INT16)r1 * (INT16)r2);
1121 		jaguar.PC += 2;
1122 		jaguar.op = ROPCODE(jaguar.PC);
1123 	}
1124 	if ((jaguar.op >> 10) == 19)
1125 	{
1126 		jaguar.PC += 2;
1127 		jaguar.r[jaguar.op & 31] = (UINT32)jaguar.accum;
1128 	}
1129 }
1130 
jr_cc_n(void)1131 void jr_cc_n(void)
1132 {
1133 	if (CONDITION(jaguar.op & 31))
1134 	{
1135 		INT32 r1 = (INT8)((jaguar.op >> 2) & 0xf8) >> 2;
1136 		UINT32 newpc = jaguar.PC + r1;
1137 		CALL_MAME_DEBUG;
1138 		jaguar.op = ROPCODE(jaguar.PC);
1139 		jaguar.PC = newpc;
1140 		(*jaguar.table[jaguar.op >> 10])();
1141 
1142 		jaguar_icount -= 3;	/* 3 wait states guaranteed */
1143 	}
1144 }
1145 
jump_cc_rn(void)1146 void jump_cc_rn(void)
1147 {
1148 	if (CONDITION(jaguar.op & 31))
1149 	{
1150 		UINT8 reg = (jaguar.op >> 5) & 31;
1151 
1152 		/* special kludge for risky code in the cojag DSP interrupt handlers */
1153 		UINT32 newpc = (jaguar_icount == bankswitch_icount) ? jaguar.a[reg] : jaguar.r[reg];
1154 		CALL_MAME_DEBUG;
1155 		jaguar.op = ROPCODE(jaguar.PC);
1156 		jaguar.PC = newpc;
1157 		(*jaguar.table[jaguar.op >> 10])();
1158 
1159 		jaguar_icount -= 3;	/* 3 wait states guaranteed */
1160 	}
1161 }
1162 
load_rn_rn(void)1163 void load_rn_rn(void)
1164 {
1165 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1166 	jaguar.r[jaguar.op & 31] = READLONG(r1);
1167 }
1168 
load_r14n_rn(void)1169 void load_r14n_rn(void)
1170 {
1171 	UINT32 r1 = convert_zero[(jaguar.op >> 5) & 31];
1172 	jaguar.r[jaguar.op & 31] = READLONG(jaguar.r[14] + 4 * r1);
1173 }
1174 
load_r15n_rn(void)1175 void load_r15n_rn(void)
1176 {
1177 	UINT32 r1 = convert_zero[(jaguar.op >> 5) & 31];
1178 	jaguar.r[jaguar.op & 31] = READLONG(jaguar.r[15] + 4 * r1);
1179 }
1180 
load_r14rn_rn(void)1181 void load_r14rn_rn(void)
1182 {
1183 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1184 	jaguar.r[jaguar.op & 31] = READLONG(jaguar.r[14] + r1);
1185 }
1186 
load_r15rn_rn(void)1187 void load_r15rn_rn(void)
1188 {
1189 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1190 	jaguar.r[jaguar.op & 31] = READLONG(jaguar.r[15] + r1);
1191 }
1192 
loadb_rn_rn(void)1193 void loadb_rn_rn(void)
1194 {
1195 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1196 	jaguar.r[jaguar.op & 31] = READBYTE(r1);
1197 }
1198 
loadw_rn_rn(void)1199 void loadw_rn_rn(void)
1200 {
1201 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1202 	jaguar.r[jaguar.op & 31] = READWORD(r1);
1203 }
1204 
loadp_rn_rn(void)1205 void loadp_rn_rn(void)	/* GPU only */
1206 {
1207 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1208 	jaguar.ctrl[G_HIDATA] = READWORD(r1);
1209 	jaguar.r[jaguar.op & 31] = READWORD(r1+4);
1210 }
1211 
mirror_rn(void)1212 void mirror_rn(void)	/* DSP only */
1213 {
1214 	int dreg = jaguar.op & 31;
1215 	UINT32 r1 = jaguar.r[dreg];
1216 	UINT32 res = (mirror_table[r1 & 0xffff] << 16) | mirror_table[r1 >> 16];
1217 	jaguar.r[dreg] = res;
1218 	CLR_ZN; SET_ZN(res);
1219 }
1220 
mmult_rn_rn(void)1221 void mmult_rn_rn(void)
1222 {
1223 	int count = jaguar.ctrl[G_MTXC] & 15, i;
1224 	int sreg = (jaguar.op >> 5) & 31;
1225 	int dreg = jaguar.op & 31;
1226 	UINT32 addr = jaguar.ctrl[G_MTXA];
1227 	INT64 accum = 0;
1228 	UINT32 res;
1229 
1230 	if (!(jaguar.ctrl[G_MTXC] & 0x10))
1231 	{
1232 		for (i = 0; i < count; i++)
1233 		{
1234 			accum += (INT16)(jaguar.b1[sreg + i/2] >> (16 * ((i & 1) ^ 1))) * (INT16)READWORD(addr);
1235 			addr += 2;
1236 		}
1237 	}
1238 	else
1239 	{
1240 		for (i = 0; i < count; i++)
1241 		{
1242 			accum += (INT16)(jaguar.b1[sreg + i/2] >> (16 * ((i & 1) ^ 1))) * (INT16)READWORD(addr);
1243 			addr += 2 * count;
1244 		}
1245 	}
1246 	jaguar.r[dreg] = res = (UINT32)accum;
1247 	CLR_ZN; SET_ZN(res);
1248 }
1249 
move_rn_rn(void)1250 void move_rn_rn(void)
1251 {
1252 	jaguar.r[jaguar.op & 31] = jaguar.r[(jaguar.op >> 5) & 31];
1253 }
1254 
move_pc_rn(void)1255 void move_pc_rn(void)
1256 {
1257 	jaguar.r[jaguar.op & 31] = jaguar.ppc;
1258 }
1259 
movefa_rn_rn(void)1260 void movefa_rn_rn(void)
1261 {
1262 	jaguar.r[jaguar.op & 31] = jaguar.a[(jaguar.op >> 5) & 31];
1263 }
1264 
movei_n_rn(void)1265 void movei_n_rn(void)
1266 {
1267 	UINT32 res = ROPCODE(jaguar.PC) | (ROPCODE(jaguar.PC + 2) << 16);
1268 	jaguar.PC += 4;
1269 	jaguar.r[jaguar.op & 31] = res;
1270 }
1271 
moveq_n_rn(void)1272 void moveq_n_rn(void)
1273 {
1274 	jaguar.r[jaguar.op & 31] = (jaguar.op >> 5) & 31;
1275 }
1276 
moveta_rn_rn(void)1277 void moveta_rn_rn(void)
1278 {
1279 	jaguar.a[jaguar.op & 31] = jaguar.r[(jaguar.op >> 5) & 31];
1280 }
1281 
mtoi_rn_rn(void)1282 void mtoi_rn_rn(void)
1283 {
1284 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1285 	jaguar.r[jaguar.op & 31] = (((INT32)r1 >> 8) & 0xff800000) | (r1 & 0x007fffff);
1286 }
1287 
mult_rn_rn(void)1288 void mult_rn_rn(void)
1289 {
1290 	int dreg = jaguar.op & 31;
1291 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1292 	UINT32 r2 = jaguar.r[dreg];
1293 	UINT32 res = (UINT16)r1 * (UINT16)r2;
1294 	jaguar.r[dreg] = res;
1295 	CLR_ZN; SET_ZN(res);
1296 }
1297 
neg_rn(void)1298 void neg_rn(void)
1299 {
1300 	int dreg = jaguar.op & 31;
1301 	UINT32 r2 = jaguar.r[dreg];
1302 	UINT32 res = -r2;
1303 	jaguar.r[dreg] = res;
1304 	CLR_ZNC; SET_ZNC_SUB(0,r2,res);
1305 }
1306 
nop(void)1307 void nop(void)
1308 {
1309 }
1310 
normi_rn_rn(void)1311 void normi_rn_rn(void)
1312 {
1313 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1314 	UINT32 res = 0;
1315 	if (r1 != 0)
1316 	{
1317 		while ((r1 & 0xffc00000) == 0)
1318 		{
1319 			r1 <<= 1;
1320 			res--;
1321 		}
1322 		while ((r1 & 0xff800000) != 0)
1323 		{
1324 			r1 >>= 1;
1325 			res++;
1326 		}
1327 	}
1328 	jaguar.r[jaguar.op & 31] = res;
1329 	CLR_ZN; SET_ZN(res);
1330 }
1331 
not_rn(void)1332 void not_rn(void)
1333 {
1334 	int dreg = jaguar.op & 31;
1335 	UINT32 res = ~jaguar.r[dreg];
1336 	jaguar.r[dreg] = res;
1337 	CLR_ZN; SET_ZN(res);
1338 }
1339 
or_rn_rn(void)1340 void or_rn_rn(void)
1341 {
1342 	int dreg = jaguar.op & 31;
1343 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1344 	UINT32 r2 = jaguar.r[dreg];
1345 	UINT32 res = r1 | r2;
1346 	jaguar.r[dreg] = res;
1347 	CLR_ZN; SET_ZN(res);
1348 }
1349 
pack_rn(void)1350 void pack_rn(void)		/* GPU only */
1351 {
1352 	int dreg = jaguar.op & 31;
1353 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1354 	UINT32 r2 = jaguar.r[dreg];
1355 	UINT32 res;
1356 	if (r1 == 0)	/* PACK */
1357 		res = ((r2 >> 10) & 0xf000) | ((r2 >> 5) & 0x0f00) | (r2 & 0xff);
1358 	else			/* UNPACK */
1359 		res = ((r2 & 0xf000) << 10) | ((r2 & 0x0f00) << 5) | (r2 & 0xff);
1360 	jaguar.r[dreg] = res;
1361 	CLR_ZN; SET_ZN(res);
1362 }
1363 
resmac_rn(void)1364 void resmac_rn(void)
1365 {
1366 	jaguar.r[jaguar.op & 31] = (UINT32)jaguar.accum;
1367 }
1368 
ror_rn_rn(void)1369 void ror_rn_rn(void)
1370 {
1371 	int dreg = jaguar.op & 31;
1372 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31] & 31;
1373 	UINT32 r2 = jaguar.r[dreg];
1374 	UINT32 res = (r2 >> r1) | (r2 << (32 - r1));
1375 	jaguar.r[dreg] = res;
1376 	CLR_ZNC; SET_ZN(res); jaguar.FLAGS |= (r2 >> 30) & 2;
1377 }
1378 
rorq_n_rn(void)1379 void rorq_n_rn(void)
1380 {
1381 	int dreg = jaguar.op & 31;
1382 	UINT32 r1 = convert_zero[(jaguar.op >> 5) & 31];
1383 	UINT32 r2 = jaguar.r[dreg];
1384 	UINT32 res = (r2 >> r1) | (r2 << (32 - r1));
1385 	jaguar.r[dreg] = res;
1386 	CLR_ZNC; SET_ZN(res); jaguar.FLAGS |= (r2 >> 30) & 2;
1387 }
1388 
sat8_rn(void)1389 void sat8_rn(void)		/* GPU only */
1390 {
1391 	int dreg = jaguar.op & 31;
1392 	INT32 r2 = jaguar.r[dreg];
1393 	UINT32 res = (r2 < 0) ? 0 : (r2 > 255) ? 255 : r2;
1394 	jaguar.r[dreg] = res;
1395 	CLR_ZN; SET_ZN(res);
1396 }
1397 
sat16_rn(void)1398 void sat16_rn(void)		/* GPU only */
1399 {
1400 	int dreg = jaguar.op & 31;
1401 	INT32 r2 = jaguar.r[dreg];
1402 	UINT32 res = (r2 < 0) ? 0 : (r2 > 65535) ? 65535 : r2;
1403 	jaguar.r[dreg] = res;
1404 	CLR_ZN; SET_ZN(res);
1405 }
1406 
sat16s_rn(void)1407 void sat16s_rn(void)		/* DSP only */
1408 {
1409     UINT32 res;
1410 	int dreg = jaguar.op & 31;
1411 	INT32 r2 = jaguar.r[dreg];
1412    MAME_CLAMP_SAMPLE(r2);
1413    res = r2;
1414 	jaguar.r[dreg] = res;
1415 	CLR_ZN; SET_ZN(res);
1416 }
1417 
sat24_rn(void)1418 void sat24_rn(void)			/* GPU only */
1419 {
1420 	int dreg = jaguar.op & 31;
1421 	INT32 r2 = jaguar.r[dreg];
1422 	UINT32 res = (r2 < 0) ? 0 : (r2 > 16777215) ? 16777215 : r2;
1423 	jaguar.r[dreg] = res;
1424 	CLR_ZN; SET_ZN(res);
1425 }
1426 
sat32s_rn(void)1427 void sat32s_rn(void)		/* DSP only */
1428 {
1429 	int dreg = jaguar.op & 31;
1430 	INT32 r2 = (UINT32)jaguar.r[dreg];
1431 	INT32 temp = jaguar.accum >> 32;
1432 	UINT32 res = (temp < -1) ? (INT32)0x80000000 : (temp > 0) ? (INT32)0x7fffffff : r2;
1433 	jaguar.r[dreg] = res;
1434 	CLR_ZN; SET_ZN(res);
1435 }
1436 
sh_rn_rn(void)1437 void sh_rn_rn(void)
1438 {
1439 	int dreg = jaguar.op & 31;
1440 	INT32 r1 = (INT32)jaguar.r[(jaguar.op >> 5) & 31];
1441 	UINT32 r2 = jaguar.r[dreg];
1442 	UINT32 res;
1443 
1444 	CLR_ZNC;
1445 	if (r1 < 0)
1446 	{
1447 		res = (r1 <= -32) ? 0 : (r2 << -r1);
1448 		jaguar.FLAGS |= (r2 >> 30) & 2;
1449 	}
1450 	else
1451 	{
1452 		res = (r1 >= 32) ? 0 : (r2 >> r1);
1453 		jaguar.FLAGS |= (r2 << 1) & 2;
1454 	}
1455 	jaguar.r[dreg] = res;
1456 	SET_ZN(res);
1457 }
1458 
sha_rn_rn(void)1459 void sha_rn_rn(void)
1460 {
1461 	int dreg = jaguar.op & 31;
1462 	INT32 r1 = (INT32)jaguar.r[(jaguar.op >> 5) & 31];
1463 	UINT32 r2 = jaguar.r[dreg];
1464 	UINT32 res;
1465 
1466 	CLR_ZNC;
1467 	if (r1 < 0)
1468 	{
1469 		res = (r1 <= -32) ? 0 : (r2 << -r1);
1470 		jaguar.FLAGS |= (r2 >> 30) & 2;
1471 	}
1472 	else
1473 	{
1474 		res = (r1 >= 32) ? ((INT32)r2 >> 31) : ((INT32)r2 >> r1);
1475 		jaguar.FLAGS |= (r2 << 1) & 2;
1476 	}
1477 	jaguar.r[dreg] = res;
1478 	SET_ZN(res);
1479 }
1480 
sharq_n_rn(void)1481 void sharq_n_rn(void)
1482 {
1483 	int dreg = jaguar.op & 31;
1484 	INT32 r1 = convert_zero[(jaguar.op >> 5) & 31];
1485 	UINT32 r2 = jaguar.r[dreg];
1486 	UINT32 res = (INT32)r2 >> r1;
1487 	jaguar.r[dreg] = res;
1488 	CLR_ZNC; SET_ZN(res); jaguar.FLAGS |= (r2 << 1) & 2;
1489 }
1490 
shlq_n_rn(void)1491 void shlq_n_rn(void)
1492 {
1493 	int dreg = jaguar.op & 31;
1494 	INT32 r1 = convert_zero[(jaguar.op >> 5) & 31];
1495 	UINT32 r2 = jaguar.r[dreg];
1496 	UINT32 res = r2 << (32 - r1);
1497 	jaguar.r[dreg] = res;
1498 	CLR_ZNC; SET_ZN(res); jaguar.FLAGS |= (r2 >> 30) & 2;
1499 }
1500 
shrq_n_rn(void)1501 void shrq_n_rn(void)
1502 {
1503 	int dreg = jaguar.op & 31;
1504 	INT32 r1 = convert_zero[(jaguar.op >> 5) & 31];
1505 	UINT32 r2 = jaguar.r[dreg];
1506 	UINT32 res = r2 >> r1;
1507 	jaguar.r[dreg] = res;
1508 	CLR_ZNC; SET_ZN(res); jaguar.FLAGS |= (r2 << 1) & 2;
1509 }
1510 
store_rn_rn(void)1511 void store_rn_rn(void)
1512 {
1513 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1514 	WRITELONG(r1, jaguar.r[jaguar.op & 31]);
1515 }
1516 
store_rn_r14n(void)1517 void store_rn_r14n(void)
1518 {
1519 	UINT32 r1 = convert_zero[(jaguar.op >> 5) & 31];
1520 	WRITELONG(jaguar.r[14] + r1 * 4, jaguar.r[jaguar.op & 31]);
1521 }
1522 
store_rn_r15n(void)1523 void store_rn_r15n(void)
1524 {
1525 	UINT32 r1 = convert_zero[(jaguar.op >> 5) & 31];
1526 	WRITELONG(jaguar.r[15] + r1 * 4, jaguar.r[jaguar.op & 31]);
1527 }
1528 
store_rn_r14rn(void)1529 void store_rn_r14rn(void)
1530 {
1531 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1532 	WRITELONG(jaguar.r[14] + r1, jaguar.r[jaguar.op & 31]);
1533 }
1534 
store_rn_r15rn(void)1535 void store_rn_r15rn(void)
1536 {
1537 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1538 	WRITELONG(jaguar.r[15] + r1, jaguar.r[jaguar.op & 31]);
1539 }
1540 
storeb_rn_rn(void)1541 void storeb_rn_rn(void)
1542 {
1543 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1544 	WRITEBYTE(r1, jaguar.r[jaguar.op & 31]);
1545 }
1546 
storew_rn_rn(void)1547 void storew_rn_rn(void)
1548 {
1549 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1550 	WRITEWORD(r1, jaguar.r[jaguar.op & 31]);
1551 }
1552 
storep_rn_rn(void)1553 void storep_rn_rn(void)	/* GPU only */
1554 {
1555 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1556 	WRITELONG(r1, jaguar.ctrl[G_HIDATA]);
1557 	WRITELONG(r1+4, jaguar.r[jaguar.op & 31]);
1558 }
1559 
sub_rn_rn(void)1560 void sub_rn_rn(void)
1561 {
1562 	int dreg = jaguar.op & 31;
1563 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1564 	UINT32 r2 = jaguar.r[dreg];
1565 	UINT32 res = r2 - r1;
1566 	jaguar.r[dreg] = res;
1567 	CLR_ZNC; SET_ZNC_SUB(r2,r1,res);
1568 }
1569 
subc_rn_rn(void)1570 void subc_rn_rn(void)
1571 {
1572 	int dreg = jaguar.op & 31;
1573 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1574 	UINT32 r2 = jaguar.r[dreg];
1575 	UINT32 res = r2 - r1 - ((jaguar.FLAGS >> 1) & 1);
1576 	jaguar.r[dreg] = res;
1577 	CLR_ZNC; SET_ZNC_SUB(r2,r1,res);
1578 }
1579 
subq_n_rn(void)1580 void subq_n_rn(void)
1581 {
1582 	int dreg = jaguar.op & 31;
1583 	UINT32 r1 = convert_zero[(jaguar.op >> 5) & 31];
1584 	UINT32 r2 = jaguar.r[dreg];
1585 	UINT32 res = r2 - r1;
1586 	jaguar.r[dreg] = res;
1587 	CLR_ZNC; SET_ZNC_SUB(r2,r1,res);
1588 }
1589 
subqmod_n_rn(void)1590 void subqmod_n_rn(void)	/* DSP only */
1591 {
1592 	int dreg = jaguar.op & 31;
1593 	UINT32 r1 = convert_zero[(jaguar.op >> 5) & 31];
1594 	UINT32 r2 = jaguar.r[dreg];
1595 	UINT32 res = r2 - r1;
1596 	res = (res & ~jaguar.ctrl[D_MOD]) | (r2 & ~jaguar.ctrl[D_MOD]);
1597 	jaguar.r[dreg] = res;
1598 	CLR_ZNC; SET_ZNC_SUB(r2,r1,res);
1599 }
1600 
subqt_n_rn(void)1601 void subqt_n_rn(void)
1602 {
1603 	int dreg = jaguar.op & 31;
1604 	UINT32 r1 = convert_zero[(jaguar.op >> 5) & 31];
1605 	UINT32 r2 = jaguar.r[dreg];
1606 	UINT32 res = r2 - r1;
1607 	jaguar.r[dreg] = res;
1608 }
1609 
xor_rn_rn(void)1610 void xor_rn_rn(void)
1611 {
1612 	int dreg = jaguar.op & 31;
1613 	UINT32 r1 = jaguar.r[(jaguar.op >> 5) & 31];
1614 	UINT32 r2 = jaguar.r[dreg];
1615 	UINT32 res = r1 ^ r2;
1616 	jaguar.r[dreg] = res;
1617 	CLR_ZN; SET_ZN(res);
1618 }
1619 
1620 
1621 
1622 /*###################################################################################################
1623 **	I/O HANDLING
1624 **#################################################################################################*/
1625 
jaguargpu_ctrl_r(int cpunum,offs_t offset)1626 data32_t jaguargpu_ctrl_r(int cpunum, offs_t offset)
1627 {
1628 	data32_t result;
1629 
1630 	log_cb(RETRO_LOG_DEBUG, LOGPRE "%08X/%d:GPU read register @ F021%02X\n", activecpu_get_previouspc(), cpu_getactivecpu(), offset * 4);
1631 
1632 	/* switch to the target context */
1633 	cpuintrf_push_context(cpunum);
1634 	result = jaguar.ctrl[offset];
1635 	cpuintrf_pop_context();
1636 
1637 	return result;
1638 }
1639 
1640 
jaguargpu_ctrl_w(int cpunum,offs_t offset,data32_t data,data32_t mem_mask)1641 void jaguargpu_ctrl_w(int cpunum, offs_t offset, data32_t data, data32_t mem_mask)
1642 {
1643 	UINT32 			oldval, newval;
1644 
1645 	if (offset != G_HIDATA)
1646 		log_cb(RETRO_LOG_DEBUG, LOGPRE "%08X/%d:GPU write register @ F021%02X = %08X\n", activecpu_get_previouspc(), cpu_getactivecpu(), offset * 4, data);
1647 
1648 	/* switch to the target context */
1649 	cpuintrf_push_context(cpunum);
1650 
1651 	/* remember the old and set the new */
1652 	oldval = jaguar.ctrl[offset];
1653 	newval = oldval;
1654 	COMBINE_DATA(&newval);
1655 
1656 	/* handle the various registers */
1657 	switch (offset)
1658 	{
1659 		case G_FLAGS:
1660 
1661 			/* combine the data properly */
1662 			jaguar.ctrl[offset] = newval & (ZFLAG | CFLAG | NFLAG | EINT04FLAGS | RPAGEFLAG);
1663 			if (newval & IFLAG)
1664 				jaguar.ctrl[offset] |= oldval & IFLAG;
1665 
1666 			/* clear interrupts */
1667 			jaguar.ctrl[G_CTRL] &= ~((newval & CINT04FLAGS) >> 3);
1668 
1669 			/* determine which register bank should be active */
1670 			update_register_banks();
1671 
1672 			/* update IRQs */
1673 			check_irqs();
1674 			break;
1675 
1676 		case G_MTXC:
1677 		case G_MTXA:
1678 			jaguar.ctrl[offset] = newval;
1679 			break;
1680 
1681 		case G_END:
1682 			jaguar.ctrl[offset] = newval;
1683 			if ((newval & 7) != 7)
1684 				log_cb(RETRO_LOG_DEBUG, LOGPRE "GPU to set to little-endian!\n");
1685 			break;
1686 
1687 		case G_PC:
1688 			jaguar.PC = newval & 0xffffff;
1689 			if (executing_cpu == cpunum)
1690 				change_pc24bedw(jaguar.PC);
1691 			break;
1692 
1693 		case G_CTRL:
1694 			jaguar.ctrl[offset] = newval;
1695 			if ((oldval ^ newval) & 0x01)
1696 			{
1697 				cpu_set_halt_line(cpunum, (newval & 1) ? CLEAR_LINE : ASSERT_LINE);
1698 				cpu_yield();
1699 			}
1700 			if (newval & 0x02)
1701 			{
1702 				if (jaguar.cpu_interrupt)
1703 					(*jaguar.cpu_interrupt)();
1704 				jaguar.ctrl[offset] &= ~0x02;
1705 			}
1706 			if (newval & 0x04)
1707 			{
1708 				jaguar.ctrl[G_CTRL] |= 1 << 6;
1709 				jaguar.ctrl[offset] &= ~0x04;
1710 				check_irqs();
1711 			}
1712 			if (newval & 0x18)
1713 			{
1714 				log_cb(RETRO_LOG_DEBUG, LOGPRE "GPU single stepping was enabled!\n");
1715 			}
1716 			break;
1717 
1718 		case G_HIDATA:
1719 		case G_DIVCTRL:
1720 			jaguar.ctrl[offset] = newval;
1721 			break;
1722 	}
1723 
1724 	/* restore old context */
1725 	cpuintrf_pop_context();
1726 }
1727 
1728 
1729 
1730 /*###################################################################################################
1731 **	I/O HANDLING
1732 **#################################################################################################*/
1733 
jaguardsp_ctrl_r(int cpunum,offs_t offset)1734 data32_t jaguardsp_ctrl_r(int cpunum, offs_t offset)
1735 {
1736 	data32_t result;
1737 
1738 	if (offset != D_FLAGS)
1739 		log_cb(RETRO_LOG_DEBUG, LOGPRE "%08X/%d:DSP read register @ F1A1%02X\n", activecpu_get_previouspc(), cpu_getactivecpu(), offset * 4);
1740 
1741 	/* switch to the target context */
1742 	cpuintrf_push_context(cpunum);
1743 	result = jaguar.ctrl[offset];
1744 	cpuintrf_pop_context();
1745 
1746 	return result;
1747 }
1748 
1749 
jaguardsp_ctrl_w(int cpunum,offs_t offset,data32_t data,data32_t mem_mask)1750 void jaguardsp_ctrl_w(int cpunum, offs_t offset, data32_t data, data32_t mem_mask)
1751 {
1752 	UINT32 			oldval, newval;
1753 
1754 	if (offset != D_FLAGS)
1755 		log_cb(RETRO_LOG_DEBUG, LOGPRE "%08X/%d:DSP write register @ F1A1%02X = %08X\n", activecpu_get_previouspc(), cpu_getactivecpu(), offset * 4, data);
1756 
1757 	/* switch to the target context */
1758 	cpuintrf_push_context(cpunum);
1759 
1760 	/* remember the old and set the new */
1761 	oldval = jaguar.ctrl[offset];
1762 	newval = oldval;
1763 	COMBINE_DATA(&newval);
1764 
1765 	/* handle the various registers */
1766 	switch (offset)
1767 	{
1768 		case D_FLAGS:
1769 
1770 			/* combine the data properly */
1771 			jaguar.ctrl[offset] = newval & (ZFLAG | CFLAG | NFLAG | EINT04FLAGS | EINT5FLAG | RPAGEFLAG);
1772 			if (newval & IFLAG)
1773 				jaguar.ctrl[offset] |= oldval & IFLAG;
1774 
1775 			/* clear interrupts */
1776 			jaguar.ctrl[D_CTRL] &= ~((newval & CINT04FLAGS) >> 3);
1777 			jaguar.ctrl[D_CTRL] &= ~((newval & CINT5FLAG) >> 1);
1778 
1779 			/* determine which register bank should be active */
1780 			update_register_banks();
1781 
1782 			/* update IRQs */
1783 			check_irqs();
1784 			break;
1785 
1786 		case D_MTXC:
1787 		case D_MTXA:
1788 			jaguar.ctrl[offset] = newval;
1789 			break;
1790 
1791 		case D_END:
1792 			jaguar.ctrl[offset] = newval;
1793 			if ((newval & 7) != 7)
1794 				log_cb(RETRO_LOG_DEBUG, LOGPRE "DSP to set to little-endian!\n");
1795 			break;
1796 
1797 		case D_PC:
1798 			jaguar.PC = newval & 0xffffff;
1799 			if (executing_cpu == cpunum)
1800 				change_pc24bedw(jaguar.PC);
1801 			break;
1802 
1803 		case D_CTRL:
1804 			jaguar.ctrl[offset] = newval;
1805 			if ((oldval ^ newval) & 0x01)
1806 			{
1807 				cpu_set_halt_line(cpunum, (newval & 1) ? CLEAR_LINE : ASSERT_LINE);
1808 				cpu_yield();
1809 			}
1810 			if (newval & 0x02)
1811 			{
1812 				if (jaguar.cpu_interrupt)
1813 					(*jaguar.cpu_interrupt)();
1814 				jaguar.ctrl[offset] &= ~0x02;
1815 			}
1816 			if (newval & 0x04)
1817 			{
1818 				jaguar.ctrl[D_CTRL] |= 1 << 6;
1819 				jaguar.ctrl[offset] &= ~0x04;
1820 				check_irqs();
1821 			}
1822 			if (newval & 0x18)
1823 			{
1824 				log_cb(RETRO_LOG_DEBUG, LOGPRE "DSP single stepping was enabled!\n");
1825 			}
1826 			break;
1827 
1828 		case D_MOD:
1829 		case D_DIVCTRL:
1830 			jaguar.ctrl[offset] = newval;
1831 			break;
1832 	}
1833 
1834 	/* restore old context */
1835 	cpuintrf_pop_context();
1836 }
1837