| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | /*====================================================================
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 16:15:52 +00:00
										 |  |  |    filename:     gdsp_opcodes_helper.h | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  |    project:      GameCube DSP Tool (gcdsp) | 
					
						
							|  |  |  |    created:      2005.03.04 | 
					
						
							|  |  |  |    mail:		  duddie@walla.com | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Copyright (c) 2005 Duddie | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |    modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |    as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |    of the License, or (at your option) any later version. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |    GNU General Public License for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |    along with this program; if not, write to the Free Software | 
					
						
							|  |  |  |    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    ====================================================================*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-28 10:00:25 +00:00
										 |  |  | #ifndef _DSP_INT_UTIL_H
 | 
					
						
							|  |  |  | #define _DSP_INT_UTIL_H
 | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-12 10:21:40 +00:00
										 |  |  | #include "Common.h"
 | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-01 20:22:43 +00:00
										 |  |  | #include "DSPInterpreter.h"
 | 
					
						
							| 
									
										
										
										
											2009-05-01 20:06:24 +00:00
										 |  |  | #include "DSPCore.h"
 | 
					
						
							| 
									
										
										
										
											2009-06-28 10:00:25 +00:00
										 |  |  | #include "DSPMemoryMap.h"
 | 
					
						
							| 
									
										
										
										
											2009-06-28 10:24:44 +00:00
										 |  |  | #include "DSPStacks.h"
 | 
					
						
							| 
									
										
										
										
											2009-05-01 20:06:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-06 19:19:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | // ---------------------------------------------------------------------------------------
 | 
					
						
							|  |  |  | // --- SR
 | 
					
						
							|  |  |  | // ---------------------------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2010-03-08 21:25:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-05 16:58:15 +00:00
										 |  |  | inline void dsp_SR_set_flag(int flag) | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 	g_dsp.r.sr |= flag; | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-05 16:58:15 +00:00
										 |  |  | inline bool dsp_SR_is_flag_set(int flag) | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 	return (g_dsp.r.sr & flag) != 0; | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-08 21:25:35 +00:00
										 |  |  | // ---------------------------------------------------------------------------------------
 | 
					
						
							|  |  |  | // --- AR increments, decrements
 | 
					
						
							|  |  |  | // ---------------------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-30 15:36:28 +00:00
										 |  |  | inline u16 dsp_increase_addr_reg(u16 reg, s16 _ix) | 
					
						
							| 
									
										
										
										
											2009-05-01 22:17:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-30 15:36:28 +00:00
										 |  |  | 	u32 ar = g_dsp.r.ar[reg]; | 
					
						
							|  |  |  | 	u32 wr = g_dsp.r.wr[reg]; | 
					
						
							|  |  |  | 	s32 ix = _ix; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	u32 mx = (wr | 1) << 1; | 
					
						
							|  |  |  | 	u32 nar = ar + ix; | 
					
						
							|  |  |  | 	u32 dar = (nar ^ ar ^ ix) & mx; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (ix >= 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (dar > wr) //overflow
 | 
					
						
							|  |  |  | 			nar -= wr + 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if ((((nar + wr + 1) ^ nar) & dar) <= wr) //underflow or below min for mask
 | 
					
						
							|  |  |  | 			nar += wr + 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nar; | 
					
						
							| 
									
										
										
										
											2009-05-01 22:17:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-30 15:36:28 +00:00
										 |  |  | inline u16 dsp_decrease_addr_reg(u16 reg, s16 _ix)  | 
					
						
							| 
									
										
										
										
											2010-04-15 20:01:44 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-30 15:36:28 +00:00
										 |  |  | 	u32 ar = g_dsp.r.ar[reg]; | 
					
						
							|  |  |  | 	u32 wr = g_dsp.r.wr[reg]; | 
					
						
							|  |  |  | 	s32 ix = _ix; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	u32 mx = (wr | 1) << 1; | 
					
						
							|  |  |  | 	u32 nar = ar - ix; | 
					
						
							|  |  |  | 	u32 dar = (nar ^ ar ^ ~ix) & mx; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((u32)ix > 0xFFFF8000) //(ix < 0 && ix != -0x8000)
 | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (dar > wr) //overflow
 | 
					
						
							|  |  |  | 			nar -= wr + 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if ((((nar + wr + 1) ^ nar) & dar) <= wr) //underflow or below min for mask
 | 
					
						
							|  |  |  | 			nar += wr + 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nar; | 
					
						
							| 
									
										
										
										
											2009-06-28 10:00:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 17:09:40 +00:00
										 |  |  | inline u16 dsp_increment_addr_reg(u16 reg)  | 
					
						
							| 
									
										
										
										
											2009-06-21 06:56:44 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-30 15:36:28 +00:00
										 |  |  | 	u32 ar = g_dsp.r.ar[reg]; | 
					
						
							|  |  |  | 	u32 wr = g_dsp.r.wr[reg]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	u32 nar = ar + 1; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2011-01-01 13:19:07 +00:00
										 |  |  | 	if ((nar ^ ar) > ((wr | 1) << 1)) | 
					
						
							| 
									
										
										
										
											2010-12-30 15:36:28 +00:00
										 |  |  | 		nar -= wr + 1; | 
					
						
							|  |  |  | 	return nar; | 
					
						
							| 
									
										
										
										
											2009-06-21 06:56:44 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 17:09:40 +00:00
										 |  |  | inline u16 dsp_decrement_addr_reg(u16 reg)  | 
					
						
							| 
									
										
										
										
											2010-03-08 21:25:35 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-30 15:36:28 +00:00
										 |  |  | 	u32 ar = g_dsp.r.ar[reg]; | 
					
						
							|  |  |  | 	u32 wr = g_dsp.r.wr[reg]; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	u32 nar = ar + wr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (((nar ^ ar) & ((wr | 1) << 1)) > wr) | 
					
						
							|  |  |  | 		nar -= wr + 1; | 
					
						
							|  |  |  | 	return nar; | 
					
						
							| 
									
										
										
										
											2010-03-08 21:25:35 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-05-01 22:17:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 17:09:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | // ---------------------------------------------------------------------------------------
 | 
					
						
							|  |  |  | // --- reg
 | 
					
						
							|  |  |  | // ---------------------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-18 17:53:15 +00:00
										 |  |  | inline u16 dsp_op_read_reg(int reg) | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-04-21 08:53:36 +00:00
										 |  |  | 	switch (reg & 0x1f) { | 
					
						
							| 
									
										
										
										
											2009-05-02 16:15:52 +00:00
										 |  |  | 	case DSP_REG_ST0: | 
					
						
							|  |  |  | 	case DSP_REG_ST1: | 
					
						
							|  |  |  | 	case DSP_REG_ST2: | 
					
						
							|  |  |  | 	case DSP_REG_ST3: | 
					
						
							| 
									
										
										
										
											2010-12-29 02:12:06 +00:00
										 |  |  | 		return dsp_reg_load_stack(reg - DSP_REG_ST0); | 
					
						
							|  |  |  | 	case DSP_REG_AR0: | 
					
						
							|  |  |  | 	case DSP_REG_AR1: | 
					
						
							|  |  |  | 	case DSP_REG_AR2: | 
					
						
							|  |  |  | 	case DSP_REG_AR3: | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 		return g_dsp.r.ar[reg - DSP_REG_AR0]; | 
					
						
							| 
									
										
										
										
											2010-12-29 02:12:06 +00:00
										 |  |  | 	case DSP_REG_IX0: | 
					
						
							|  |  |  | 	case DSP_REG_IX1: | 
					
						
							|  |  |  | 	case DSP_REG_IX2: | 
					
						
							|  |  |  | 	case DSP_REG_IX3: | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 		return g_dsp.r.ix[reg - DSP_REG_IX0]; | 
					
						
							| 
									
										
										
										
											2010-12-29 02:12:06 +00:00
										 |  |  | 	case DSP_REG_WR0: | 
					
						
							|  |  |  | 	case DSP_REG_WR1: | 
					
						
							|  |  |  | 	case DSP_REG_WR2: | 
					
						
							|  |  |  | 	case DSP_REG_WR3: | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 		return g_dsp.r.wr[reg - DSP_REG_WR0]; | 
					
						
							| 
									
										
										
										
											2010-12-29 02:12:06 +00:00
										 |  |  | 	case DSP_REG_ACH0: | 
					
						
							|  |  |  | 	case DSP_REG_ACH1: | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 		return g_dsp.r.ac[reg - DSP_REG_ACH0].h; | 
					
						
							|  |  |  | 	case DSP_REG_CR:     return g_dsp.r.cr; | 
					
						
							|  |  |  | 	case DSP_REG_SR:     return g_dsp.r.sr; | 
					
						
							|  |  |  | 	case DSP_REG_PRODL:  return g_dsp.r.prod.l; | 
					
						
							|  |  |  | 	case DSP_REG_PRODM:  return g_dsp.r.prod.m; | 
					
						
							|  |  |  | 	case DSP_REG_PRODH:  return g_dsp.r.prod.h; | 
					
						
							|  |  |  | 	case DSP_REG_PRODM2: return g_dsp.r.prod.m2; | 
					
						
							| 
									
										
										
										
											2010-12-29 02:12:06 +00:00
										 |  |  | 	case DSP_REG_AXL0: | 
					
						
							|  |  |  | 	case DSP_REG_AXL1: | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 		return g_dsp.r.ax[reg - DSP_REG_AXL0].l; | 
					
						
							| 
									
										
										
										
											2010-12-29 02:12:06 +00:00
										 |  |  | 	case DSP_REG_AXH0: | 
					
						
							|  |  |  | 	case DSP_REG_AXH1: | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 		return g_dsp.r.ax[reg - DSP_REG_AXH0].h; | 
					
						
							| 
									
										
										
										
											2010-12-29 02:12:06 +00:00
										 |  |  | 	case DSP_REG_ACL0: | 
					
						
							|  |  |  | 	case DSP_REG_ACL1: | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 		return g_dsp.r.ac[reg - DSP_REG_ACL0].l; | 
					
						
							| 
									
										
										
										
											2010-12-29 02:12:06 +00:00
										 |  |  | 	case DSP_REG_ACM0: | 
					
						
							|  |  |  | 	case DSP_REG_ACM1: | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 		return g_dsp.r.ac[reg - DSP_REG_ACM0].m; | 
					
						
							| 
									
										
										
										
											2009-04-21 08:53:36 +00:00
										 |  |  | 	default: | 
					
						
							| 
									
										
										
										
											2010-12-29 02:12:06 +00:00
										 |  |  | 		_assert_msg_(DSP_INT, 0, "cannot happen"); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-18 17:53:15 +00:00
										 |  |  | inline void dsp_op_write_reg(int reg, u16 val) | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-04-21 08:53:36 +00:00
										 |  |  | 	switch (reg & 0x1f) { | 
					
						
							| 
									
										
										
										
											2009-05-01 20:06:24 +00:00
										 |  |  | 	// 8-bit sign extended registers. Should look at prod.h too...
 | 
					
						
							| 
									
										
										
										
											2009-05-01 19:07:29 +00:00
										 |  |  | 	case DSP_REG_ACH0: | 
					
						
							|  |  |  | 	case DSP_REG_ACH1: | 
					
						
							|  |  |  | 		// sign extend from the bottom 8 bits.
 | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 		g_dsp.r.ac[reg-DSP_REG_ACH0].h = (u16)(s16)(s8)(u8)val; | 
					
						
							| 
									
										
										
										
											2009-05-01 19:07:29 +00:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2009-05-01 20:06:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Stack registers.
 | 
					
						
							| 
									
										
										
										
											2009-05-02 16:15:52 +00:00
										 |  |  | 	case DSP_REG_ST0: | 
					
						
							|  |  |  | 	case DSP_REG_ST1: | 
					
						
							|  |  |  | 	case DSP_REG_ST2: | 
					
						
							|  |  |  | 	case DSP_REG_ST3: | 
					
						
							| 
									
										
										
										
											2010-12-29 02:12:06 +00:00
										 |  |  | 		dsp_reg_store_stack(reg - DSP_REG_ST0, val); | 
					
						
							| 
									
										
										
										
											2009-04-21 08:53:36 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-29 02:12:06 +00:00
										 |  |  | 	case DSP_REG_AR0: | 
					
						
							|  |  |  | 	case DSP_REG_AR1: | 
					
						
							|  |  |  | 	case DSP_REG_AR2: | 
					
						
							|  |  |  | 	case DSP_REG_AR3: | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 		g_dsp.r.ar[reg - DSP_REG_AR0] = val; | 
					
						
							| 
									
										
										
										
											2010-12-29 02:12:06 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case DSP_REG_IX0: | 
					
						
							|  |  |  | 	case DSP_REG_IX1: | 
					
						
							|  |  |  | 	case DSP_REG_IX2: | 
					
						
							|  |  |  | 	case DSP_REG_IX3: | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 		g_dsp.r.ix[reg - DSP_REG_IX0] = val; | 
					
						
							| 
									
										
										
										
											2010-12-29 02:12:06 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case DSP_REG_WR0: | 
					
						
							|  |  |  | 	case DSP_REG_WR1: | 
					
						
							|  |  |  | 	case DSP_REG_WR2: | 
					
						
							|  |  |  | 	case DSP_REG_WR3: | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 		g_dsp.r.wr[reg - DSP_REG_WR0] = val; | 
					
						
							| 
									
										
										
										
											2010-12-29 02:12:06 +00:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 	case DSP_REG_CR:     g_dsp.r.cr = val; break; | 
					
						
							|  |  |  | 	case DSP_REG_SR:     g_dsp.r.sr = val; break; | 
					
						
							|  |  |  | 	case DSP_REG_PRODL:  g_dsp.r.prod.l = val; break; | 
					
						
							|  |  |  | 	case DSP_REG_PRODM:  g_dsp.r.prod.m = val; break; | 
					
						
							|  |  |  | 	case DSP_REG_PRODH:  g_dsp.r.prod.h = val; break; | 
					
						
							|  |  |  | 	case DSP_REG_PRODM2: g_dsp.r.prod.m2 = val; break; | 
					
						
							| 
									
										
										
										
											2010-12-29 02:12:06 +00:00
										 |  |  | 	case DSP_REG_AXL0: | 
					
						
							|  |  |  | 	case DSP_REG_AXL1: | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 		g_dsp.r.ax[reg - DSP_REG_AXL0].l = val; | 
					
						
							| 
									
										
										
										
											2010-12-29 02:12:06 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case DSP_REG_AXH0: | 
					
						
							|  |  |  | 	case DSP_REG_AXH1: | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 		g_dsp.r.ax[reg - DSP_REG_AXH0].h = val; | 
					
						
							| 
									
										
										
										
											2010-12-29 02:12:06 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case DSP_REG_ACL0: | 
					
						
							|  |  |  | 	case DSP_REG_ACL1: | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 		g_dsp.r.ac[reg - DSP_REG_ACL0].l = val; | 
					
						
							| 
									
										
										
										
											2010-12-29 02:12:06 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case DSP_REG_ACM0: | 
					
						
							|  |  |  | 	case DSP_REG_ACM1: | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 		g_dsp.r.ac[reg - DSP_REG_ACM0].m = val; | 
					
						
							| 
									
										
										
										
											2009-04-21 08:53:36 +00:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2009-05-01 19:07:29 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-04-21 08:53:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-18 17:53:15 +00:00
										 |  |  | inline void dsp_conditional_extend_accum(int reg)  | 
					
						
							| 
									
										
										
										
											2009-05-01 19:07:29 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	switch (reg)  | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	case DSP_REG_ACM0: | 
					
						
							|  |  |  | 	case DSP_REG_ACM1: | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 		if (g_dsp.r.sr & SR_40_MODE_BIT) | 
					
						
							| 
									
										
										
										
											2009-05-01 19:07:29 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			// Sign extend into whole accum.
 | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 			u16 val = g_dsp.r.ac[reg-DSP_REG_ACM0].m; | 
					
						
							|  |  |  | 			g_dsp.r.ac[reg - DSP_REG_ACM0].h = (val & 0x8000) ? 0xFFFF : 0x0000; | 
					
						
							|  |  |  | 			g_dsp.r.ac[reg - DSP_REG_ACM0].l = 0; | 
					
						
							| 
									
										
										
										
											2009-04-21 08:53:36 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // ---------------------------------------------------------------------------------------
 | 
					
						
							|  |  |  | // --- prod
 | 
					
						
							|  |  |  | // ---------------------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-30 03:27:31 +00:00
										 |  |  | inline s64 dsp_get_long_prod() | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | { | 
					
						
							|  |  |  | #if PROFILE
 | 
					
						
							|  |  |  | 	ProfilerAddDelta(g_dsp.err_pc, 1); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 	s64 val   = (s8)(u8)g_dsp.r.prod.h; | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | 	val <<= 32; | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 	s64 low_prod  = g_dsp.r.prod.m; | 
					
						
							|  |  |  | 	low_prod += g_dsp.r.prod.m2; | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | 	low_prod <<= 16; | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 	low_prod |= g_dsp.r.prod.l; | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | 	val += low_prod; | 
					
						
							| 
									
										
										
										
											2009-04-05 21:04:46 +00:00
										 |  |  | 	return val; | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-19 21:53:41 +00:00
										 |  |  | inline s64 dsp_get_long_prod_round_prodl() | 
					
						
							| 
									
										
										
										
											2010-03-18 00:18:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-08-08 16:35:10 +00:00
										 |  |  | 	s64 prod = dsp_get_long_prod(); | 
					
						
							| 
									
										
										
										
											2010-12-29 02:12:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-14 09:07:28 +00:00
										 |  |  | 	if (prod & 0x10000) | 
					
						
							| 
									
										
										
										
											2010-08-08 16:35:10 +00:00
										 |  |  | 		prod = (prod + 0x8000) & ~0xffff; | 
					
						
							| 
									
										
										
										
											2010-08-14 09:07:28 +00:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		prod = (prod + 0x7fff) & ~0xffff; | 
					
						
							| 
									
										
										
										
											2010-08-08 16:35:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return prod; | 
					
						
							| 
									
										
										
										
											2010-03-18 00:18:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 16:15:52 +00:00
										 |  |  | // For accurate emulation, this is wrong - but the real prod registers behave
 | 
					
						
							| 
									
										
										
										
											2010-12-12 17:09:40 +00:00
										 |  |  | // in completely bizarre ways. Not needed to emulate them correctly for game ucodes.
 | 
					
						
							| 
									
										
										
										
											2009-03-30 03:27:31 +00:00
										 |  |  | inline void dsp_set_long_prod(s64 val) | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | { | 
					
						
							|  |  |  | #if PROFILE
 | 
					
						
							|  |  |  | 	ProfilerAddDelta(g_dsp.err_pc, 1); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 	g_dsp.r.prod.l = (u16)val; | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | 	val >>= 16; | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 	g_dsp.r.prod.m = (u16)val; | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | 	val >>= 16; | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 	g_dsp.r.prod.h = /*(s16)(s8)*/(u8)val;//todo: check expansion
 | 
					
						
							|  |  |  | 	g_dsp.r.prod.m2 = 0; | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // ---------------------------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2009-05-01 20:06:24 +00:00
										 |  |  | // --- ACC - main accumulators (40-bit)
 | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | // ---------------------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-05 16:58:15 +00:00
										 |  |  | inline s64 dsp_get_long_acc(int reg) | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | { | 
					
						
							|  |  |  | #if PROFILE
 | 
					
						
							|  |  |  | 	ProfilerAddDelta(g_dsp.err_pc, 1); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 	s64 high = (s64)(s8)g_dsp.r.ac[reg].h << 32; | 
					
						
							|  |  |  | 	u32 mid_low = ((u32)g_dsp.r.ac[reg].m << 16) | g_dsp.r.ac[reg].l; | 
					
						
							| 
									
										
										
										
											2009-04-05 21:04:46 +00:00
										 |  |  | 	return high | mid_low; | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-05 16:58:15 +00:00
										 |  |  | inline void dsp_set_long_acc(int _reg, s64 val) | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | { | 
					
						
							|  |  |  | #if PROFILE
 | 
					
						
							|  |  |  | 	ProfilerAddDelta(g_dsp.err_pc, 1); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 	g_dsp.r.ac[_reg].l = (u16)val; | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | 	val >>= 16; | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 	g_dsp.r.ac[_reg].m = (u16)val; | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | 	val >>= 16; | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 	g_dsp.r.ac[_reg].h = (u16)(s16)(s8)(u8)val; | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-21 10:35:28 +00:00
										 |  |  | inline s64 dsp_convert_long_acc(s64 val) // s64 -> s40
 | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return ((s64)(s8)(val >> 32))<<32 | (u32)val; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-08 16:35:10 +00:00
										 |  |  | inline s64 dsp_round_long_acc(s64 val) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-08-14 09:07:28 +00:00
										 |  |  | 	if (val & 0x10000) | 
					
						
							| 
									
										
										
										
											2010-08-08 16:35:10 +00:00
										 |  |  | 		val = (val + 0x8000) & ~0xffff; | 
					
						
							| 
									
										
										
										
											2010-08-14 09:07:28 +00:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		val = (val + 0x7fff) & ~0xffff; | 
					
						
							| 
									
										
										
										
											2010-08-08 16:35:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return val; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-05 16:58:15 +00:00
										 |  |  | inline s16 dsp_get_acc_l(int _reg) | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 	return g_dsp.r.ac[_reg].l; | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-05 16:58:15 +00:00
										 |  |  | inline s16 dsp_get_acc_m(int _reg) | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 	return g_dsp.r.ac[_reg].m; | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-05 16:58:15 +00:00
										 |  |  | inline s16 dsp_get_acc_h(int _reg) | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 	return g_dsp.r.ac[_reg].h; | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // ---------------------------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2009-05-01 20:06:24 +00:00
										 |  |  | // --- AX - extra accumulators (32-bit)
 | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | // ---------------------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 16:15:52 +00:00
										 |  |  | inline s32 dsp_get_long_acx(int _reg) | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | { | 
					
						
							|  |  |  | #if PROFILE
 | 
					
						
							|  |  |  | 	ProfilerAddDelta(g_dsp.err_pc, 1); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 	return ((u32)g_dsp.r.ax[_reg].h << 16) | g_dsp.r.ax[_reg].l; | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-05 16:58:15 +00:00
										 |  |  | inline s16 dsp_get_ax_l(int _reg) | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 	return (s16)g_dsp.r.ax[_reg].l; | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-05 16:58:15 +00:00
										 |  |  | inline s16 dsp_get_ax_h(int _reg) | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-29 20:20:52 +00:00
										 |  |  | 	return (s16)g_dsp.r.ax[_reg].h; | 
					
						
							| 
									
										
										
										
											2009-03-23 09:10:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 |