1  /**************************************************************************\
2  *				  Texas Instruments TMS320x25 DSP Emulator					*
3  *																			*
4  *				   Copyright (C) 2001-2002+ Tony La Porta					*
5  *						Written for the MAME project.						*
6  *																			*
7  *																			*
8  *	Three versions of the chip are available, and they are: 				*
9  *	TMS320C25   Internal ROM one time programmed at TI  					*
10  *	TMS320E25   Internal ROM programmable as a normal EPROM 				*
11  *	TMS320P25   Internal ROM programmable once as a normal EPROM only		*
12  *	These devices can also be used as a MicroController with external ROM	*
13  *																			*
14  *																			*
15  *		Notes : The term 'DMA' within this document, is in reference		*
16  *					to Direct Memory Addressing, and NOT the usual term		*
17  *					of Direct Memory Access.								*
18  *				This is a word based microcontroller, with addressing		*
19  *					architecture based on the Harvard addressing scheme.	*
20  *																			*
21  *																			*
22  *																			*
23  *	**** Change Log ****													*
24  *																			*
25  *	TLP (2x-May-2001)														*
26  *	 - Work began on this emulator  										*
27  *	TLP (12-Jul-2001)														*
28  *	 - First private release												*
29  *	TLP (xx-Dec-2001) Ver 0.11  											*
30  *	 - Various undocumented fixes											*
31  *	TLP (13-Jul-2002) Ver 0.12  											*
32  *	 - Corrected IRQ2 vector pointer										*
33  *	 - Fixed the signedness in many equation based instructions				*
34  *	 - Adjusted the level sensing for the Signal inputs 					*
35  *	 - Added the ability to view the CPU in the debugger when it's halted	*
36  *	TLP (16-Nov-2002)														*
37  *	 - First public release after nearly 1.5 years! 						*
38  *	 - Adjusted more signedness instructions (ADDH, SUBC, SUBH, etc)		*
39  *	TLP (21-Dec-2002)														*
40  *	 - Added memory banking for the CNFD, CNFP and CONF instructions		*
41  *	 - Corrected IRQ masking checks 										*
42  *	TLP (25-Dec-2002) Ver 1.10  											*
43  *	 - Added internal timer													*
44  *																			*
45  \**************************************************************************/
46 
47 /*****************************************************************************
48  To fix, or currently lacking from this emulator are:
49 
50  Fix the levels for S_IN and S_OUT - use assert/release line
51 
52  #	Support for the built in Timer/Counter Page 91
53   	When idling, Counter must still be activly counting down. When counter
54   	reaches 0 it should issue a TINT (if it's not masked), then come out of
55   	IDLE mode.
56   	If TINT is masked, the Timer still needs to count down.
57 
58  #	Support for the built in Serial Port
59  #	Support for the Global memory register
60  #	Support for the switch for RAM block 0 banking between RAM and ROM space
61  #	Correct the mulit-cycle instruction cycle counts
62  #	Add support to set ROM & RAM as Internal/External in order to correctly
63   	compute cycle timings
64  #	Possibly add internal memory into here (instead of having it in the driver)
65  #	Check (read) Hold signal level during execution loop ?
66  #	Fix bugs
67  #	Fix more bugs :-)
68  #	Add/fix other things I forgot
69 *****************************************************************************/
70 
71 /*
72      TMS32025 CONF Mode Decoding Table
73 |=======================================|
74 | Status bit |           Blocks         |
75 |     CNF    |   B0    |   B1    |  B2  |
76 |------------+---------+---------+------|
77 |     0  0   |  data   |  data   | data |
78 |     1  1   | program |  data   | data |
79 |=======================================|
80 
81 
82      TMS32026 CONF Mode Decoding Table
83 |==================================================|
84 | Status bits |               Blocks               |
85 | CNF1 | CNF0 |   B0    |   B1    |  B2  |   B3    |
86 |------+------+---------+---------+------+---------|
87 |  0   |  0   |  data   |  data   | data |  data   |
88 |  0   |  1   | program |  data   | data |  data   |
89 |  1   |  0   | program | program | data |  data   |
90 |  1   |  1   | program | program | data | program |
91 |==================================================|
92 
93 
94 
95 Table 3-2.  TMS32025/26 Memory Blocks
96 |=========================================================|
97 |             Configured As Data Memory                   |
98 |-------+-------TMS320C25--------+-------TMS320C26--------|
99 |       |         | Hexadecimal  |         | Hexadecimal  |
100 | Block |  Pages  |   Address    |  Pages  |   Address    |
101 |-------+---------+--------------+---------+--------------|
102 |   B2  |    0    | 0060h-007Fh  |    0    | 0060h-007Fh  |
103 |   B0  |   4-5   | 0200h-02FFh  |   4-7   | 0200h-03FFh  |
104 |   B1  |   6-7   | 0300h-03FFh  |   8-11  | 0400h-05FFh  |
105 |   B3  |   B3 does not exist    |  12-15  | 0600h-07FFh  |
106 |=========================================================|
107 |             Configured As Program Memory                |
108 |-------+-------TMS320C25--------+-------TMS320C26--------|
109 |       |         | Hexadecimal  |         | Hexadecimal  |
110 | Block |  Pages  |   Address    |  Pages  |   Address    |
111 |-------+---------+--------------+---------+--------------|
112 |   B2  | B2 is not configurable | B2 is not configurable |
113 |   B0  | 510-511 | FF00h-FFFFh  | 500-503 | FA00h-FBFFh  |
114 |   B1  | B1 is not configurable | 504-507 | FC00h-FDFFh  |
115 |   B3  | B3 does not exist      | 508-511 | FE00h-FFFFh  |
116 |=========================================================|
117 */
118 
119 
120 
121 #include <stdio.h>
122 #include <string.h>
123 #include <stdlib.h>
124 
125 #include <retro_inline.h>
126 
127 #include "driver.h"
128 #include "cpuintrf.h"
129 #include "mamedbg.h"
130 #include "state.h"
131 #include "tms32025.h"
132 
133 
134 #define CLK 4	/* 1 cycle equals 4 clock ticks */		/* PE/DI */
135 
136 
137 #define M_RDROM(A)		TMS32025_ROM_RDMEM(A)
138 #define M_WRTROM(A,V)	TMS32025_ROM_WRMEM(A,V)
139 #define M_RDRAM(A)		TMS32025_RAM_RDMEM(A)
140 #define M_WRTRAM(A,V)	TMS32025_RAM_WRMEM(A,V)
141 #define M_RDOP(A)		TMS32025_RDOP(A)
142 #define M_RDOP_ARG(A)	TMS32025_RDOP_ARG(A)
143 #define P_IN(A)			TMS32025_In(A)
144 #define P_OUT(A,V)		TMS32025_Out(A,V)
145 #define S_IN(A)			TMS32025_Signal_In(A)
146 #define S_OUT(A,V)		TMS32025_Signal_Out(A,V)
147 
148 
149 
150 static UINT8 tms32025_reg_layout[] = {
151 	TMS32025_PC,  TMS32025_STR0,TMS32025_STR1,TMS32025_IFR, TMS32025_STK7,TMS32025_STK6,-1,
152 	TMS32025_STK5,TMS32025_STK4,TMS32025_STK3,TMS32025_STK2,TMS32025_STK1,TMS32025_STK0,-1,
153 	TMS32025_ACC, TMS32025_PREG,TMS32025_TREG,TMS32025_RPTC,TMS32025_AR0, TMS32025_AR1, -1,
154 	TMS32025_AR2, TMS32025_AR3, TMS32025_AR4, TMS32025_AR5, TMS32025_AR6, TMS32025_AR7, -1,
155 	TMS32025_DRR, TMS32025_DXR, TMS32025_TIM, TMS32025_PRD, TMS32025_IMR, TMS32025_GREG, 0
156 };
157 
158 static UINT8 tms32025_win_layout[] = {
159 	 0, 0,80, 5,	/* register window (top rows) */
160 	 0, 6,29,16,	/* disassembler window (left colums) */
161 	30, 6,50, 7,	/* memory #1 window (right, upper middle) */
162 	30,14,50, 8,	/* memory #2 window (right, lower middle) */
163 	 0,23,80, 1,	/* command line window (bottom rows) */
164 };
165 
166 
167 
168 
169 typedef struct			/* Page 3-6 (45) shows all registers */
170 {
171 	/******************** CPU Internal Registers *******************/
172 	UINT16	PREVPC;		/* previous program counter */
173 	UINT16	PC;
174 	UINT16	PFC;
175 	UINT16	STR0, STR1;
176 	UINT8	IFR;
177 	UINT8	RPTC;
178 	PAIR	ACC;		/* PAIR defined in os/osd_cpu.h */
179 	PAIR	Preg;
180 	UINT16	Treg;
181 	UINT16	AR[8];
182 	UINT16	STACK[8];
183 	PAIR	ALU;
184 	UINT16	*intRAM;
185 
186 	/********************** Status data ****************************/
187 	PAIR	opcode;
188 	int		idle;
189 	int		hold;
190 	int		external_mem_access;	/** required for hold mode. Implement it ! */
191 	int		init_load_addr;			/* 0=No, 1=Yes, 2=Once for repeat mode */
192 	int		tms32025_irq_cycles;
193 	int		tms32025_dec_cycles;
194 	int		(*irq_callback)(int irqline);
195 } tms32025_Regs;
196 
197 static tms32025_Regs R;
198 static PAIR  oldacc;
199 static UINT32 memaccess;
200 int    tms32025_icount;
201 offs_t TMS32025_DATA_BANK[0x10];
202 offs_t TMS32025_PRGM_BANK[0x10];
203 typedef void (*opcode_fn) (void);
204 
205 
206 /************************** Memory mapped registers ****************/
207 #define DRR 	R.intRAM[0]
208 #define DXR 	R.intRAM[1]
209 #define TIM 	R.intRAM[2]
210 #define PRD 	R.intRAM[3]
211 #define IMR 	R.intRAM[4]
212 #define GREG	R.intRAM[5]
213 
214 
215 
216 /****************************************************************************
217  *******  The following is the Status (Flag) register 0 definition.  ********
218 | 15 | 14 | 13 | 12 |  11 | 10 |   9  | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
219 | <----ARP---> | OV | OVM |  1 | INTM | <--------------DP---------------> | */
220 
221 #define ARP_REG		0xe000	/* ARP	(Auxiliary Register Pointer) */
222 #define OV_FLAG		0x1000	/* OV	(Overflow flag) 1 indicates an overflow */
223 #define OVM_FLAG	0x0800	/* OVM	(Overflow Mode bit) 1 forces ACC overflow to greatest positive or negative saturation value */
224 #define INTM_FLAG	0x0200	/* INTM	(Interrupt Mask flag) 0 enables maskable interrupts */
225 #define DP_REG		0x01ff	/* DP	(Data bank memory Pointer) */
226 
227 
228 /***********************************************************************************
229  *** The following is the Status (Flag) register 1 definition for TMS32025. ********
230 | 15 | 14 | 13 |  12  | 11 |  10 | 9 | 8 | 7 |  6 |  5  |  4 |  3 |  2  | 1 | 0  |
231 | <----ARB---> | CNF0 | TC | SXM | C | 1 | 1 | HM | FSM | XF | FO | TXM | <-PM-> | */
232 
233 /*** The following is the Status (Flag) register 1 definition for TMS32026. ***********
234 | 15 | 14 | 13 |  12  | 11 |  10 | 9 | 8 |   7  |  6 |  5  |  4 |  3 |  2  | 1 | 0  |
235 | <----ARB---> | CNF0 | TC | SXM | C | 1 | CNF1 | HM | FSM | XF | FO | TXM | <-PM-> | */
236 
237 #define ARB_REG		0xe000	/* ARB	(Auxiliary Register pointer Backup) */
238 #define CNF0_REG	0x1000	/* CNF0	(Onchip RAM CoNFiguration) 0 means B0=data memory, 1means B0=program memory */
239 #define CNF1_REG	0x0080	/* CNF1	(Onchip RAM CoNFiguration) 0 means B0=data memory, 1means B0=program memory */
240 #define TC_FLAG		0x0800	/* TC	(Test Control flag) */
241 #define SXM_FLAG	0x0400	/* SXM	(Sign eXtension Mode) */
242 #define C_FLAG		0x0200	/* C	(Carry flag) */
243 #define HM_FLAG		0x0040	/* HM	(Processor Hold Mode) */
244 #define FSM_FLAG	0x0020	/* FSM	(Frame Synchronization Mode - for serial port) */
245 #define XF_FLAG		0x0010	/* XF	(XF output pin status) */
246 #define FO_FLAG		0x0008	/* FO	(Serial port Format In/Out mode) */
247 #define TXM_FLAG	0x0004	/* TXM	(Transmit Mode - for serial port) */
248 #define PM_REG		0x0003	/* PM	(Product shift Mode) */
249 
250 
251 #define OV		( R.STR0 & OV_FLAG)			/* OV	(Overflow flag) */
252 #define OVM		( R.STR0 & OVM_FLAG)		/* OVM	(Overflow Mode bit) 1 indicates an overflow */
253 #define INTM	( R.STR0 & INTM_FLAG)		/* INTM	(Interrupt enable flag) 0 enables maskable interrupts */
254 #define ARP		((R.STR0 & ARP_REG) >> 13)	/* ARP	(Auxiliary Register Pointer) */
255 #define DP		((R.STR0 & DP_REG) << 7)	/* DP	(Data memory Pointer bit) */
256 #define ARB		( R.STR1 & ARB_REG)			/* ARB	(Backup Auxiliary Register pointer) */
257 #define CNF0	( R.STR1 & CNF0_REG)		/* CNF0	(Onchip Ram Config register) */
258 #define TC		( R.STR1 & TC_FLAG)			/* TC	(Test Control Flag) */
259 #define SXM		( R.STR1 & SXM_FLAG)		/* SXM	(Sign Extension Mode) */
260 #define CARRY	( R.STR1 & C_FLAG)			/* C	(Carry Flag for accumulator) */
261 #define HM		( R.STR1 & HM_FLAG)			/* HM	(Processor Hold Mode) */
262 #define FSM		( R.STR1 & FSM_FLAG)		/* FSM	(Frame Synchronization Mode - for serial port) */
263 #define XF		( R.STR1 & FSM_FLAG)		/* XF	(XF output pin status) */
264 #define FO		( R.STR1 & FO_FLAG)			/* FO	(Serial port Format In/Out mode) */
265 #define TXM		( R.STR1 & TXM_FLAG)		/* TXM	(Transmit Mode - for serial port) */
266 #define PM		( R.STR1 & PM_REG)			/* PM	(P register shift Mode. See SHIFT_Preg_TO_ALU below )*/
267 
268 #define DMA		(DP | (R.opcode.b.l & 0x7f))	/* address used in direct memory access operations */
269 #define DMApg0	(R.opcode.b.l & 0x7f)			/* address used in direct memory access operations for sst instruction */
270 #define IND		R.AR[ARP]						/* address used in indirect memory access operations */
271 
272 
273 
CLR0(UINT16 flag)274 static INLINE void CLR0(UINT16 flag) { R.STR0 &= ~flag; R.STR0 |= 0x0400; }
SET0(UINT16 flag)275 static INLINE void SET0(UINT16 flag) { R.STR0 |=  flag; R.STR0 |= 0x0400; }
CLR1(UINT16 flag)276 static INLINE void CLR1(UINT16 flag) { R.STR1 &= ~flag; R.STR1 |= 0x0180; }
SET1(UINT16 flag)277 static INLINE void SET1(UINT16 flag) { R.STR1 |=  flag; R.STR1 |= 0x0180; }
MODIFY_DP(int data)278 static INLINE void MODIFY_DP (int data) { R.STR0 &= ~DP_REG;  R.STR0 |= (data & DP_REG); R.STR0 |= 0x0400; }
MODIFY_PM(int data)279 static INLINE void MODIFY_PM (int data) { R.STR1 &= ~PM_REG;  R.STR1 |= (data & PM_REG); R.STR1 |= 0x0180; }
MODIFY_ARP(int data)280 static INLINE void MODIFY_ARP(int data) { R.STR1 &= ~ARB_REG; R.STR1 |= (R.STR0 & ARP_REG); R.STR1 |= 0x0180; \
281 								   R.STR0 &= ~ARP_REG; R.STR0 |= ((data << 13) & ARP_REG); R.STR0 |= 0x0400; }
MODIFY_ARB(int data)282 static INLINE void MODIFY_ARB(int data) { R.STR1 &= ~ARB_REG; R.STR1 |= ((data << 13) & ARB_REG); R.STR1 |= 0x0180; }
283 
MODIFY_AR_ARP(void)284 static INLINE void MODIFY_AR_ARP(void)
285 {
286 	switch (R.opcode.b.l & 0x70)		/* Cases ordered by predicted useage */
287 	{
288 		case 0x00:		break;
289 		case 0x10:		R.AR[ARP] -- ; break;
290 		case 0x20:		R.AR[ARP] ++ ; break;
291 		case 0x50:		R.AR[ARP] -= R.AR[0]; break;
292 		case 0x60:		R.AR[ARP] += R.AR[0]; break;
293 		case 0x40:		R.AR[ARP] -= (R.AR[0]>>1); break;	/* reverse carry propogation */
294 		case 0x70:		R.AR[ARP] += (R.AR[0]>>1); break;	/* reverse carry propogation */
295 		case 0x30:		break;	/* Reserved. Lets use it for LAR instruction */
296 		default:		break;
297 	}
298 	if (R.opcode.b.l & 8)
299 	{
300 /*		MODIFY_ARB(ARP);*/
301 		MODIFY_ARP(R.opcode.b.l & 7);
302 	}
303 }
304 
CALCULATE_ADD_CARRY(void)305 static INLINE void CALCULATE_ADD_CARRY(void)
306 {
307 	if ( ((INT32)(oldacc.d) < 0) && ((INT32)(R.ACC.d) >= 0) ) {
308 		SET1(C_FLAG);
309 	}
310 	else {
311 		CLR1(C_FLAG);
312 	}
313 }
314 
CALCULATE_SUB_CARRY(void)315 static INLINE void CALCULATE_SUB_CARRY(void)
316 {
317 	if ( ((INT32)(oldacc.d) >= 0) && ((INT32)(R.ACC.d) < 0) ) {
318 		CLR1(C_FLAG);
319 	}
320 	else {
321 		SET1(C_FLAG);
322 	}
323 }
324 
CALCULATE_ADD_OVERFLOW(INT32 addval)325 static INLINE void CALCULATE_ADD_OVERFLOW(INT32 addval)
326 {
327 	if ((INT32)(~(oldacc.d ^ addval) & (oldacc.d ^ R.ACC.d)) < 0) {
328 		SET0(OV_FLAG);
329 		if (OVM)
330 			R.ACC.d = ((INT32)oldacc.d < 0) ? 0x80000000 : 0x7fffffff;
331 	}
332 }
CALCULATE_SUB_OVERFLOW(INT32 subval)333 static INLINE void CALCULATE_SUB_OVERFLOW(INT32 subval)
334 {
335 	if ((INT32)((oldacc.d ^ subval) & (oldacc.d ^ R.ACC.d)) < 0) {
336 		SET0(OV_FLAG);
337 		if (OVM)
338 			R.ACC.d = ((INT32)oldacc.d < 0) ? 0x80000000 : 0x7fffffff;
339 	}
340 }
341 
POP_STACK(void)342 static INLINE UINT16 POP_STACK(void)
343 {
344 	UINT16 data = R.STACK[7];
345 	R.STACK[7] = R.STACK[6];
346 	R.STACK[6] = R.STACK[5];
347 	R.STACK[5] = R.STACK[4];
348 	R.STACK[4] = R.STACK[3];
349 	R.STACK[3] = R.STACK[2];
350 	R.STACK[2] = R.STACK[1];
351 	R.STACK[1] = R.STACK[0];
352 	return data;
353 }
PUSH_STACK(UINT16 data)354 static INLINE void PUSH_STACK(UINT16 data)
355 {
356 	R.STACK[0] = R.STACK[1];
357 	R.STACK[1] = R.STACK[2];
358 	R.STACK[2] = R.STACK[3];
359 	R.STACK[3] = R.STACK[4];
360 	R.STACK[4] = R.STACK[5];
361 	R.STACK[5] = R.STACK[6];
362 	R.STACK[6] = R.STACK[7];
363 	R.STACK[7] = data;
364 }
365 
SHIFT_Preg_TO_ALU(void)366 static INLINE void SHIFT_Preg_TO_ALU(void)
367 {
368 	switch(PM)		/* PM (in STR1) is the shift mode for Preg */
369 	{
370 		case 0:		R.ALU.d = R.Preg.d; break;
371 		case 1:		R.ALU.d = (R.Preg.d << 1); break;
372 		case 2:		R.ALU.d = (R.Preg.d << 4); break;
373 		case 3:		R.ALU.d = (R.Preg.d >> 6); if (R.Preg.d & 0x80000000) R.ALU.d |= 0xfc000000; break;
374 		default:	break;
375 	}
376 }
377 
378 
379 
380 
GETDATA(int shift,int signext)381 static INLINE void GETDATA(int shift,int signext)
382 {
383 	if (R.opcode.b.l & 0x80) memaccess = IND;
384 	else memaccess = DMA;
385 
386 	if (memaccess >= 0x800) R.external_mem_access = 1;	/* Pause if hold pin is active */
387 	else R.external_mem_access = 0;
388 
389 	R.ALU.d = (UINT16)M_RDRAM(memaccess);
390 	if (signext) R.ALU.d = (INT16)R.ALU.d;
391 	R.ALU.d <<= shift;
392 
393 	if (R.opcode.b.l & 0x80) MODIFY_AR_ARP();
394 }
PUTDATA(UINT16 data)395 static INLINE void PUTDATA(UINT16 data)
396 {
397 	if (R.opcode.b.l & 0x80) {
398 		if (memaccess >= 0x800) R.external_mem_access = 1;	/* Pause if hold pin is active */
399 		else R.external_mem_access = 0;
400 
401 		M_WRTRAM(IND,data);
402 		MODIFY_AR_ARP();
403 	}
404 	else {
405 		if (memaccess >= 0x800) R.external_mem_access = 1;	/* Pause if hold pin is active */
406 		else R.external_mem_access = 0;
407 
408 		M_WRTRAM(DMA,data);
409 	}
410 }
PUTDATA_SST(UINT16 data)411 static INLINE void PUTDATA_SST(UINT16 data)
412 {
413 	if (R.opcode.b.l & 0x80) memaccess = IND;
414 	else memaccess = DMApg0;
415 
416 	if (memaccess >= 0x800) R.external_mem_access = 1;		/* Pause if hold pin is active */
417 	else R.external_mem_access = 0;
418 
419 	if (R.opcode.b.l & 0x80) {
420 		R.opcode.b.l &= 0xf7;					/* Stop ARP changes */
421 		MODIFY_AR_ARP();
422 	}
423 	M_WRTRAM(memaccess,data);
424 }
425 
426 
427 
428 
429 /* The following functions are here to fill the void for the */
430 /* opcode call functions. These functions are never actually called. */
opcodes_CE(void)431 static void opcodes_CE(void) { }
opcodes_DX(void)432 static void opcodes_DX(void) { }
433 
illegal(void)434 static void illegal(void)
435 {
436 		log_cb(RETRO_LOG_DEBUG, LOGPRE "TMS32025:  PC = %04x,  Illegal opcode = %04x\n", (R.PC-1), R.opcode.w.l);
437 }
438 
abst(void)439 static void abst(void)
440 {
441 		if ( (INT32)(R.ACC.d) < 0 ) {
442 			R.ACC.d = -R.ACC.d;
443 			if (OVM) {
444 				SET0(OV_FLAG);
445 				if (R.ACC.d == 0x80000000) R.ACC.d-- ;
446 			}
447 		}
448 		CLR1(C_FLAG);
449 }
add(void)450 static void add(void)		/* #### add carry support - see page 3-31 (70) #### */
451 {							/* page 10-13 (348) spru031d */
452 		oldacc.d = R.ACC.d;
453 		GETDATA((R.opcode.b.h & 0xf),SXM);
454 		R.ACC.d += R.ALU.d;
455 		CALCULATE_ADD_OVERFLOW(R.ALU.d);
456 		CALCULATE_ADD_CARRY();
457 }
addc(void)458 static void addc(void)
459 {
460 		oldacc.d = R.ACC.d;
461 		GETDATA(0,0);
462 		if (CARRY) R.ALU.d++;
463 		R.ACC.d += R.ALU.d;
464 		CALCULATE_ADD_OVERFLOW(R.ALU.d);
465 		CALCULATE_ADD_CARRY();
466 }
addh(void)467 static void addh(void)
468 {
469 		oldacc.d = R.ACC.d;
470 		GETDATA(0,0);
471 		R.ACC.w.h += R.ALU.w.l;
472 		if ((INT16)(~(oldacc.w.h ^ R.ALU.w.l) & (oldacc.w.h ^ R.ACC.w.h)) < 0) {
473 			SET0(OV_FLAG);
474 			if (OVM)
475 				R.ACC.w.h = ((INT16)oldacc.w.h < 0) ? 0x8000 : 0x7fff;
476 		}
477 		if ( ((INT16)(oldacc.w.h) < 0) && ((INT16)(R.ACC.w.h) >= 0) ) {
478 			SET1(C_FLAG);
479 		}
480 		/* Carry flag is not cleared, if no carry occured */
481 }
addk(void)482 static void addk(void)
483 {
484 		oldacc.d = R.ACC.d;
485 		R.ALU.d = (UINT8)R.opcode.b.l;
486 		R.ACC.d += R.ALU.d;
487 		CALCULATE_ADD_OVERFLOW(R.ALU.d);
488 		CALCULATE_ADD_CARRY();
489 }
adds(void)490 static void adds(void)
491 {
492 		oldacc.d = R.ACC.d;
493 		GETDATA(0,0);
494 		R.ACC.d += R.ALU.d;
495 		CALCULATE_ADD_OVERFLOW(R.ALU.d);
496 		CALCULATE_ADD_CARRY();
497 }
addt(void)498 static void addt(void)
499 {
500 		oldacc.d = R.ACC.d;
501 		GETDATA((R.Treg & 0xf),SXM);
502 		R.ACC.d += R.ALU.d;
503 		CALCULATE_ADD_OVERFLOW(R.ALU.d);
504 		CALCULATE_ADD_CARRY();
505 }
adlk(void)506 static void adlk(void)
507 {
508 		oldacc.d = R.ACC.d;
509 		if (SXM) R.ALU.d =  (INT16)M_RDOP_ARG(R.PC);
510 		else     R.ALU.d = (UINT16)M_RDOP_ARG(R.PC);
511 		R.PC++;
512 		R.ALU.d <<= (R.opcode.b.h & 0xf);
513 		R.ACC.d += R.ALU.d;
514 		CALCULATE_ADD_OVERFLOW(R.ALU.d);
515 		CALCULATE_ADD_CARRY();
516 }
adrk(void)517 static void adrk(void)
518 {
519 		R.AR[ARP] += R.opcode.b.l;
520 }
and(void)521 static void and(void)
522 {
523 		GETDATA(0,0);
524 		R.ACC.d &= R.ALU.d;
525 }
andk(void)526 static void andk(void)
527 {
528 		oldacc.d = R.ACC.d;
529 		R.ALU.d = (UINT16)M_RDOP_ARG(R.PC);
530 		R.PC++;
531 		R.ALU.d <<= (R.opcode.b.h & 0xf);
532 		R.ACC.d &= R.ALU.d;
533 		R.ACC.d &= 0x7fffffff;
534 }
apac(void)535 static void apac(void)
536 {
537 		oldacc.d = R.ACC.d;
538 		SHIFT_Preg_TO_ALU();
539 		R.ACC.d += R.ALU.d;
540 		CALCULATE_ADD_OVERFLOW(R.ALU.d);
541 		CALCULATE_ADD_CARRY();
542 }
br(void)543 static void br(void)
544 {
545 		R.PC = M_RDOP_ARG(R.PC);
546 		MODIFY_AR_ARP();
547 }
bacc(void)548 static void bacc(void)
549 {
550 		R.PC = R.ACC.w.l;
551 }
banz(void)552 static void banz(void)
553 {
554 		if (R.AR[ARP]) R.PC = M_RDOP_ARG(R.PC);
555 		else R.PC++ ;
556 		MODIFY_AR_ARP();
557 }
bbnz(void)558 static void bbnz(void)
559 {
560 		if (TC) R.PC = M_RDOP_ARG(R.PC);
561 		else R.PC++ ;
562 		MODIFY_AR_ARP();
563 }
bbz(void)564 static void bbz(void)
565 {
566 		if (TC == 0) R.PC = M_RDOP_ARG(R.PC);
567 		else R.PC++ ;
568 		MODIFY_AR_ARP();
569 }
bc(void)570 static void bc(void)
571 {
572 		if (CARRY) R.PC = M_RDOP_ARG(R.PC);
573 		else R.PC++ ;
574 		MODIFY_AR_ARP();
575 }
bgez(void)576 static void bgez(void)
577 {
578 		if ( (INT32)(R.ACC.d) >= 0 ) R.PC = M_RDOP_ARG(R.PC);
579 		else R.PC++ ;
580 		MODIFY_AR_ARP();
581 }
bgz(void)582 static void bgz(void)
583 {
584 		if ( (INT32)(R.ACC.d) > 0 ) R.PC = M_RDOP_ARG(R.PC);
585 		else R.PC++ ;
586 		MODIFY_AR_ARP();
587 }
bioz(void)588 static void bioz(void)
589 {
590 		if (S_IN(TMS32025_BIO) != CLEAR_LINE) R.PC = M_RDOP_ARG(R.PC);
591 		else R.PC++ ;
592 		MODIFY_AR_ARP();
593 }
bit(void)594 static void bit(void)
595 {
596 		GETDATA(0,0);
597 		if (R.ALU.d & (0x8000 >> (R.opcode.b.h & 0xf))) SET1(TC_FLAG);
598 		else CLR1(TC_FLAG);
599 }
bitt(void)600 static void bitt(void)
601 {
602 		GETDATA(0,0);
603 		if (R.ALU.d & (0x8000 >> (R.Treg & 0xf))) SET1(TC_FLAG);
604 		else CLR1(TC_FLAG);
605 }
blez(void)606 static void blez(void)
607 {
608 		if ( (INT32)(R.ACC.d) <= 0 ) R.PC = M_RDOP_ARG(R.PC);
609 		else R.PC++ ;
610 		MODIFY_AR_ARP();
611 }
blkd(void)612 static void blkd(void)
613 {										/** Fix cycle timing **/
614 		if (R.init_load_addr) {
615 			R.PFC = M_RDOP_ARG(R.PC);
616 			R.PC++;
617 		}
618 		R.ALU.d = M_RDRAM(R.PFC);
619 		PUTDATA(R.ALU.d);
620 		R.PFC++;
621 		tms32025_icount -= (1*CLK);
622 }
blkp(void)623 static void blkp(void)
624 {										/** Fix cycle timing **/
625 		if (R.init_load_addr) {
626 			R.PFC = M_RDOP_ARG(R.PC);
627 			R.PC++;
628 		}
629 		R.ALU.d = M_RDROM(R.PFC);
630 		PUTDATA(R.ALU.d);
631 		R.PFC++;
632 		tms32025_icount -= (2*CLK);
633 }
blz(void)634 static void blz(void)
635 {
636 		if ( (INT32)(R.ACC.d) <  0 ) R.PC = M_RDOP_ARG(R.PC);
637 		else R.PC++ ;
638 		MODIFY_AR_ARP();
639 }
bnc(void)640 static void bnc(void)
641 {
642 		if (CARRY == 0) R.PC = M_RDOP_ARG(R.PC);
643 		else R.PC++ ;
644 		MODIFY_AR_ARP();
645 }
bnv(void)646 static void bnv(void)
647 {
648 		if (OV == 0) R.PC = M_RDOP_ARG(R.PC);
649 		else {
650 			R.PC++ ;
651 			CLR0(OV_FLAG);
652 		}
653 		MODIFY_AR_ARP();
654 }
bnz(void)655 static void bnz(void)
656 {
657 		if (R.ACC.d != 0) R.PC = M_RDOP_ARG(R.PC);
658 		else R.PC++ ;
659 		MODIFY_AR_ARP();
660 }
bv(void)661 static void bv(void)
662 {
663 		if (OV) {
664 			R.PC = M_RDOP_ARG(R.PC);
665 			CLR0(OV_FLAG);
666 		}
667 		else R.PC++ ;
668 		MODIFY_AR_ARP();
669 }
bz(void)670 static void bz(void)
671 {
672 		if (R.ACC.d == 0) R.PC = M_RDOP_ARG(R.PC);
673 		else R.PC++ ;
674 		MODIFY_AR_ARP();
675 }
cala(void)676 static void cala(void)
677 {
678 		PUSH_STACK(R.PC);
679 		R.PC = R.ACC.w.l;
680 }
call(void)681 static void call(void)
682 {
683 		R.PC++ ;
684 		PUSH_STACK(R.PC);
685 		R.PC = M_RDOP_ARG((R.PC - 1));
686 		MODIFY_AR_ARP();
687 }
cmpl(void)688 static void cmpl(void)
689 {
690 		R.ACC.d = (~R.ACC.d);
691 }
cmpr(void)692 static void cmpr(void)
693 {
694 		switch (R.opcode.b.l & 3)
695 		{
696 			case 00:	if ( (UINT16)(R.AR[ARP]) == (UINT16)(R.AR[0]) ) SET1(TC_FLAG); else CLR1(TC_FLAG); break;
697 			case 01:	if ( (UINT16)(R.AR[ARP]) <  (UINT16)(R.AR[0]) ) SET1(TC_FLAG); else CLR1(TC_FLAG); break;
698 			case 02:	if ( (UINT16)(R.AR[ARP])  > (UINT16)(R.AR[0]) ) SET1(TC_FLAG); else CLR1(TC_FLAG); break;
699 			case 03:	if ( (UINT16)(R.AR[ARP]) != (UINT16)(R.AR[0]) ) SET1(TC_FLAG); else CLR1(TC_FLAG); break;
700 			default:	break;
701 		}
702 }
cnfd(void)703 static void cnfd(void)	/** next two fetches need to use previous CNF value ! **/
704 {
705 		CLR1(CNF0_REG);
706 		TMS32025_DATA_BANK[0x2] = TMS32025_DATA_OFFSET + 0x0200;
707 		TMS32025_PRGM_BANK[0xf] = TMS32025_PGM_OFFSET + 0x0f00;
708 }
cnfp(void)709 static void cnfp(void)	/** next two fetches need to use previous CNF value ! **/
710 {
711 		SET1(CNF0_REG);
712 		TMS32025_DATA_BANK[0x2] = TMS32025_DATA_OFFSET + 0xff00;
713 		TMS32025_PRGM_BANK[0xf] = TMS32025_PGM_OFFSET + 0x0200;
714 }
conf(void)715 static void conf(void)	/** Need to reconfigure the memory blocks */
716 {
717 		switch (R.opcode.b.l & 3)
718 		{
719 			case 00:	CLR1(CNF1_REG); CLR1(CNF0_REG);
720 						TMS32025_DATA_BANK[0x2] = TMS32025_DATA_OFFSET + 0x0200;
721 						TMS32025_DATA_BANK[0x3] = TMS32025_DATA_OFFSET + 0x0300;
722 						TMS32025_DATA_BANK[0x4] = TMS32025_DATA_OFFSET + 0x0400;
723 						TMS32025_DATA_BANK[0x5] = TMS32025_DATA_OFFSET + 0x0500;
724 						TMS32025_DATA_BANK[0x6] = TMS32025_DATA_OFFSET + 0x0600;
725 						TMS32025_DATA_BANK[0x7] = TMS32025_DATA_OFFSET + 0x0700;
726 						TMS32025_PRGM_BANK[0xa] = TMS32025_PGM_OFFSET + 0x0a00;
727 						TMS32025_PRGM_BANK[0xb] = TMS32025_PGM_OFFSET + 0x0b00;
728 						TMS32025_PRGM_BANK[0xc] = TMS32025_PGM_OFFSET + 0x0c00;
729 						TMS32025_PRGM_BANK[0xd] = TMS32025_PGM_OFFSET + 0x0d00;
730 						TMS32025_PRGM_BANK[0xe] = TMS32025_PGM_OFFSET + 0x0e00;
731 						TMS32025_PRGM_BANK[0xf] = TMS32025_PGM_OFFSET + 0x0f00;
732 						break;
733 			case 01:	CLR1(CNF1_REG); SET1(CNF0_REG);
734 						TMS32025_DATA_BANK[0x2] = TMS32025_PGM_OFFSET + 0xfa00;
735 						TMS32025_DATA_BANK[0x3] = TMS32025_PGM_OFFSET + 0xfb00;
736 						TMS32025_DATA_BANK[0x4] = TMS32025_PGM_OFFSET + 0x0400;
737 						TMS32025_DATA_BANK[0x5] = TMS32025_PGM_OFFSET + 0x0500;
738 						TMS32025_DATA_BANK[0x6] = TMS32025_DATA_OFFSET + 0x0600;
739 						TMS32025_DATA_BANK[0x7] = TMS32025_DATA_OFFSET + 0x0700;
740 						TMS32025_PRGM_BANK[0xa] = TMS32025_DATA_OFFSET + 0x0200;
741 						TMS32025_PRGM_BANK[0xb] = TMS32025_DATA_OFFSET + 0x0300;
742 						TMS32025_PRGM_BANK[0xc] = TMS32025_DATA_OFFSET + 0x0c00;
743 						TMS32025_PRGM_BANK[0xd] = TMS32025_DATA_OFFSET + 0x0d00;
744 						TMS32025_PRGM_BANK[0xe] = TMS32025_PGM_OFFSET + 0x0e00;
745 						TMS32025_PRGM_BANK[0xf] = TMS32025_PGM_OFFSET + 0x0f00;
746 						break;
747 			case 02:	SET1(CNF1_REG); CLR1(CNF0_REG);
748 						TMS32025_DATA_BANK[0x2] = TMS32025_PGM_OFFSET + 0xfa00;
749 						TMS32025_DATA_BANK[0x3] = TMS32025_PGM_OFFSET + 0xfb00;
750 						TMS32025_DATA_BANK[0x4] = TMS32025_PGM_OFFSET + 0xfc00;
751 						TMS32025_DATA_BANK[0x5] = TMS32025_PGM_OFFSET + 0xfd00;
752 						TMS32025_DATA_BANK[0x6] = TMS32025_DATA_OFFSET + 0x0600;
753 						TMS32025_DATA_BANK[0x7] = TMS32025_DATA_OFFSET + 0x0700;
754 						TMS32025_PRGM_BANK[0xa] = TMS32025_DATA_OFFSET + 0x0200;
755 						TMS32025_PRGM_BANK[0xb] = TMS32025_DATA_OFFSET + 0x0300;
756 						TMS32025_PRGM_BANK[0xc] = TMS32025_DATA_OFFSET + 0x0400;
757 						TMS32025_PRGM_BANK[0xd] = TMS32025_DATA_OFFSET + 0x0500;
758 						TMS32025_PRGM_BANK[0xe] = TMS32025_PGM_OFFSET + 0x0e00;
759 						TMS32025_PRGM_BANK[0xf] = TMS32025_PGM_OFFSET + 0x0f00;
760 						break;
761 			case 03:	SET1(CNF1_REG); SET1(CNF0_REG);
762 						TMS32025_DATA_BANK[0x2] = TMS32025_PGM_OFFSET + 0xfa00;
763 						TMS32025_DATA_BANK[0x3] = TMS32025_PGM_OFFSET + 0xfb00;
764 						TMS32025_DATA_BANK[0x4] = TMS32025_PGM_OFFSET + 0xfc00;
765 						TMS32025_DATA_BANK[0x5] = TMS32025_PGM_OFFSET + 0xfd00;
766 						TMS32025_DATA_BANK[0x6] = TMS32025_DATA_OFFSET + 0xfe00;
767 						TMS32025_DATA_BANK[0x7] = TMS32025_DATA_OFFSET + 0xff00;
768 						TMS32025_PRGM_BANK[0xa] = TMS32025_DATA_OFFSET + 0x0200;
769 						TMS32025_PRGM_BANK[0xb] = TMS32025_DATA_OFFSET + 0x0300;
770 						TMS32025_PRGM_BANK[0xc] = TMS32025_DATA_OFFSET + 0x0400;
771 						TMS32025_PRGM_BANK[0xd] = TMS32025_DATA_OFFSET + 0x0500;
772 						TMS32025_PRGM_BANK[0xe] = TMS32025_PGM_OFFSET + 0x0600;
773 						TMS32025_PRGM_BANK[0xf] = TMS32025_PGM_OFFSET + 0x0700;
774 						break;
775 			default:	break;
776 		}
777 }
dint(void)778 static void dint(void)
779 {
780 		SET0(INTM_FLAG);
781 }
dmov(void)782 static void dmov(void)	/** Careful with how memory is configured !! */
783 {
784 		GETDATA(0,0);
785 		M_WRTRAM((memaccess + 1),R.ALU.w.l);
786 }
eint(void)787 static void eint(void)
788 {
789 		CLR0(INTM_FLAG);
790 }
fort(void)791 static void fort(void)
792 {
793 		if (R.opcode.b.l & 1) SET1(FO_FLAG);
794 		else CLR1(FO_FLAG);
795 }
idle(void)796 static void idle(void)
797 {
798 		CLR0(INTM_FLAG);
799 		R.idle = 1;
800 }
in(void)801 static void in(void)
802 {
803 		R.ALU.w.l = P_IN( (R.opcode.b.h & 0xf) );
804 		PUTDATA(R.ALU.w.l);
805 }
lac(void)806 static void lac(void)
807 {
808 		GETDATA( (R.opcode.b.h & 0xf),SXM );
809 		R.ACC.d = R.ALU.d;
810 }
lack(void)811 static void lack(void)		/* ZAC is a subset of this instruction */
812 {
813 		R.ACC.d = (UINT8)R.opcode.b.l;
814 }
lact(void)815 static void lact(void)
816 {
817 		GETDATA( (R.Treg & 0xf),SXM );
818 		R.ACC.d = R.ALU.d;
819 }
lalk(void)820 static void lalk(void)
821 {
822 		if (SXM) {
823 			R.ALU.d = (INT16)M_RDOP_ARG(R.PC);
824 			R.ACC.d = R.ALU.d << (R.opcode.b.h & 0xf);
825 		}
826 		else {
827 			R.ALU.d = (UINT16)M_RDOP_ARG(R.PC);
828 			R.ACC.d = R.ALU.d << (R.opcode.b.h & 0xf);
829 			R.ACC.d &= 0x7fffffff;
830 		}
831 		R.PC++;
832 }
lar_ar0(void)833 static void lar_ar0(void)	{ GETDATA(0,0); R.AR[0] = R.ALU.w.l; }
lar_ar1(void)834 static void lar_ar1(void)	{ GETDATA(0,0); R.AR[1] = R.ALU.w.l; }
lar_ar2(void)835 static void lar_ar2(void)	{ GETDATA(0,0); R.AR[2] = R.ALU.w.l; }
lar_ar3(void)836 static void lar_ar3(void)	{ GETDATA(0,0); R.AR[3] = R.ALU.w.l; }
lar_ar4(void)837 static void lar_ar4(void)	{ GETDATA(0,0); R.AR[4] = R.ALU.w.l; }
lar_ar5(void)838 static void lar_ar5(void)	{ GETDATA(0,0); R.AR[5] = R.ALU.w.l; }
lar_ar6(void)839 static void lar_ar6(void)	{ GETDATA(0,0); R.AR[6] = R.ALU.w.l; }
lar_ar7(void)840 static void lar_ar7(void)	{ GETDATA(0,0); R.AR[7] = R.ALU.w.l; }
lark_ar0(void)841 static void lark_ar0(void)	{ R.AR[0] = R.opcode.b.l; }
lark_ar1(void)842 static void lark_ar1(void)	{ R.AR[1] = R.opcode.b.l; }
lark_ar2(void)843 static void lark_ar2(void)	{ R.AR[2] = R.opcode.b.l; }
lark_ar3(void)844 static void lark_ar3(void)	{ R.AR[3] = R.opcode.b.l; }
lark_ar4(void)845 static void lark_ar4(void)	{ R.AR[4] = R.opcode.b.l; }
lark_ar5(void)846 static void lark_ar5(void)	{ R.AR[5] = R.opcode.b.l; }
lark_ar6(void)847 static void lark_ar6(void)	{ R.AR[6] = R.opcode.b.l; }
lark_ar7(void)848 static void lark_ar7(void)	{ R.AR[7] = R.opcode.b.l; }
ldp(void)849 static void ldp(void)
850 {
851 		GETDATA(0,0);
852 		MODIFY_DP(R.ALU.d & 0x1ff);
853 }
ldpk(void)854 static void ldpk(void)
855 {
856 		MODIFY_DP(R.opcode.b.l & 0x1ff);
857 }
lph(void)858 static void lph(void)
859 {
860 		GETDATA(0,0);
861 		R.Preg.w.h = R.ALU.w.l;
862 }
lrlk(void)863 static void lrlk(void)
864 {
865 		R.ALU.d = (UINT16)M_RDOP_ARG(R.PC);
866 		R.PC++;
867 		R.AR[R.opcode.b.h & 7] = R.ALU.w.l;
868 }
lst(void)869 static void lst(void)
870 {
871 		R.opcode.b.l &= 0xf7;		/* Must ignore next ARP */
872 		GETDATA(0,0);
873 		R.ALU.w.l &= (~INTM_FLAG);
874 		R.STR0 &= INTM_FLAG;
875 		R.STR0 |= R.ALU.w.l;		/* Must not affect INTM */
876 		R.STR0 |= 0x0400;
877 }
lst1(void)878 static void lst1(void)
879 {
880 		R.opcode.b.l &= 0xf7;		/* Must ignore next ARP */
881 		GETDATA(0,0);
882 		R.STR1 = R.ALU.w.l;
883 		R.STR1 |= 0x0180;
884 		R.STR0 &= (~ARP_REG);		/* ARB also gets copied to ARP */
885 		R.STR0 |= (R.STR1 & ARB_REG);
886 }
lt(void)887 static void lt(void)
888 {
889 		GETDATA(0,0);
890 		R.Treg = R.ALU.w.l;
891 }
lta(void)892 static void lta(void)
893 {
894 		oldacc.d = R.ACC.d;
895 		GETDATA(0,0);
896 		R.Treg = R.ALU.w.l;
897 		SHIFT_Preg_TO_ALU();
898 		R.ACC.d += R.ALU.d;
899 		CALCULATE_ADD_OVERFLOW(R.ALU.d);
900 		CALCULATE_ADD_CARRY();
901 }
ltd(void)902 static void ltd(void)	/** Careful with how memory is configured !! */
903 {
904 		oldacc.d = R.ACC.d;
905 		GETDATA(0,0);
906 		R.Treg = R.ALU.w.l;
907 		M_WRTRAM((memaccess+1),R.ALU.w.l);
908 		SHIFT_Preg_TO_ALU();
909 		R.ACC.d += R.ALU.d;
910 		CALCULATE_ADD_OVERFLOW(R.ALU.d);
911 		CALCULATE_ADD_CARRY();
912 }
ltp(void)913 static void ltp(void)
914 {
915 		oldacc.d = R.ACC.d;
916 		GETDATA(0,0);
917 		R.Treg = R.ALU.w.l;
918 		SHIFT_Preg_TO_ALU();
919 		R.ACC.d = R.ALU.d;
920 }
lts(void)921 static void lts(void)
922 {
923 		oldacc.d = R.ACC.d;
924 		GETDATA(0,0);
925 		R.Treg = R.ALU.w.l;
926 		SHIFT_Preg_TO_ALU();
927 		R.ACC.d -= R.ALU.d;
928 		CALCULATE_SUB_OVERFLOW(R.ALU.d);
929 		CALCULATE_SUB_CARRY();
930 }
mac(void)931 static void mac(void)			/** RAM blocks B0,B1,B2 may be important ! */
932 {								/** Fix cycle timing **/
933 		oldacc.d = R.ACC.d;
934 		if (R.init_load_addr) {
935 			R.PFC = M_RDOP_ARG(R.PC);
936 			R.PC++;
937 		}
938 		SHIFT_Preg_TO_ALU();
939 		R.ACC.d += R.ALU.d;
940 		CALCULATE_ADD_OVERFLOW(R.ALU.d);
941 		CALCULATE_ADD_CARRY();
942 		GETDATA(0,0);
943 		R.Treg = R.ALU.w.l;
944 		R.Preg.d = ( R.ALU.w.l * M_RDROM(R.PFC) );
945 		R.PFC++;
946 		tms32025_icount -= (2*CLK);
947 }
macd(void)948 static void macd(void)			/** RAM blocks B0,B1,B2 may be important ! */
949 {								/** Fix cycle timing **/
950 		oldacc.d = R.ACC.d;
951 		if (R.init_load_addr) {
952 			R.PFC = M_RDOP_ARG(R.PC);
953 			R.PC++;
954 		}
955 		SHIFT_Preg_TO_ALU();
956 		R.ACC.d += R.ALU.d;
957 		CALCULATE_ADD_OVERFLOW(R.ALU.d);
958 		CALCULATE_ADD_CARRY();
959 		GETDATA(0,0);
960 		if ( (R.opcode.b.l & 0x80) || R.init_load_addr ) {	/* No writing during repitition, or DMA mode */
961 			M_WRTRAM((memaccess+1),R.ALU.w.l);
962 		}
963 		R.Treg = R.ALU.w.l;
964 		R.Preg.d = ( R.ALU.w.l * M_RDROM(R.PFC) );
965 		R.PFC++;
966 		tms32025_icount -= (2*CLK);
967 }
mar(void)968 static void mar(void)		/* LARP and NOP are a subset of this instruction */
969 {
970 		if (R.opcode.b.l & 0x80) MODIFY_AR_ARP();
971 }
mpy(void)972 static void mpy(void)
973 {
974 		GETDATA(0,0);
975 		R.Preg.d = (INT16)(R.ALU.w.l) * (INT16)(R.Treg);
976 }
mpya(void)977 static void mpya(void)
978 {
979 		oldacc.d = R.ACC.d;
980 		SHIFT_Preg_TO_ALU();
981 		R.ACC.d += R.ALU.d;
982 		CALCULATE_ADD_OVERFLOW(R.ALU.d);
983 		CALCULATE_ADD_CARRY();
984 		GETDATA(0,0);
985 		R.Preg.d = (INT16)(R.ALU.w.l) * (INT16)(R.Treg);
986 }
mpyk(void)987 static void mpyk(void)
988 {
989 		R.Preg.d = (INT16)R.Treg * ((INT16)(R.opcode.w.l << 3) >> 3);
990 
991 }
mpys(void)992 static void mpys(void)
993 {
994 		oldacc.d = R.ACC.d;
995 		SHIFT_Preg_TO_ALU();
996 		R.ACC.d -= R.ALU.d;
997 		CALCULATE_SUB_OVERFLOW(R.ALU.d);
998 		CALCULATE_SUB_CARRY();
999 		GETDATA(0,0);
1000 		R.Preg.d = (INT16)(R.ALU.w.l) * (INT16)(R.Treg);
1001 }
mpyu(void)1002 static void mpyu(void)
1003 {
1004 		GETDATA(0,0); R.Preg.d = (UINT16)(R.ALU.w.l) * (UINT16)(R.Treg);
1005 }
neg(void)1006 static void neg(void)
1007 {
1008 		if (R.ACC.d == 0x80000000) {
1009 			SET0(OV_FLAG);
1010 			if (OVM) R.ACC.d = 0x7fffffff;
1011 		}
1012 		else R.ACC.d = -R.ACC.d;
1013 		if (R.ACC.d) CLR0(C_FLAG);
1014 		else SET0(C_FLAG);
1015 }
1016 /*
1017 static void nop(void) { }	// NOP is a subset of the MAR instruction
1018 */
norm(void)1019 static void norm(void)
1020 {
1021 		if (R.ACC.d == 0) {
1022 			SET1(TC_FLAG);
1023 		}
1024 		else {
1025 			if ( ((R.ACC.d & 0x80000000) ^ (R.ACC.d & 0x40000000)) ) {
1026 				SET1(TC_FLAG);
1027 			}
1028 			else {
1029 				CLR1(TC_FLAG);
1030 				R.ACC.d <<= 1;
1031 				MODIFY_AR_ARP();	/* ARP not changed in this instruction */
1032 			}
1033 		}
1034 }
or(void)1035 static void or(void)
1036 {
1037 		GETDATA(0,0);
1038 		R.ACC.w.l |= R.ALU.w.l;
1039 }
ork(void)1040 static void ork(void)
1041 {
1042 		R.ALU.d = (UINT16)M_RDOP_ARG(R.PC);
1043 		R.PC++;
1044 		R.ALU.d <<= (R.opcode.b.h & 0xf);
1045 		R.ACC.d |=  (R.ALU.d & 0x7fffffff);
1046 }
out(void)1047 static void out(void)
1048 {
1049 		GETDATA(0,0);
1050 		P_OUT( (R.opcode.b.h & 0xf), R.ALU.w.l );
1051 }
pac(void)1052 static void pac(void)
1053 {
1054 		SHIFT_Preg_TO_ALU();
1055 		R.ACC.d = R.ALU.d;
1056 }
pop(void)1057 static void pop(void)
1058 {
1059 		R.ACC.d = (UINT16)POP_STACK();
1060 }
popd(void)1061 static void popd(void)
1062 {
1063 		R.ALU.d = (UINT16)POP_STACK();
1064 		PUTDATA(R.ALU.w.l);
1065 }
pshd(void)1066 static void pshd(void)
1067 {
1068 		GETDATA(0,0);
1069 		PUSH_STACK(R.ALU.w.l);
1070 }
push(void)1071 static void push(void)
1072 {
1073 		PUSH_STACK(R.ACC.w.l);
1074 }
rc(void)1075 static void rc(void)
1076 {
1077 		CLR1(C_FLAG);
1078 }
ret(void)1079 static void ret(void)
1080 {
1081 		R.PC = POP_STACK();
1082 }
rfsm(void)1083 static void rfsm(void)				/** serial port mode */
1084 {
1085 		CLR1(FSM_FLAG);
1086 }
rhm(void)1087 static void rhm(void)
1088 {
1089 		CLR1(HM_FLAG);
1090 }
rol(void)1091 static void rol(void)
1092 {
1093 		R.ALU.d = R.ACC.d;
1094 		R.ACC.d <<= 1;
1095 		if (CARRY) R.ACC.d |= 1;
1096 		if (R.ALU.d & 0x80000000) SET1(C_FLAG);
1097 		else CLR1(C_FLAG);
1098 }
ror(void)1099 static void ror(void)
1100 {
1101 		R.ALU.d = R.ACC.d;
1102 		R.ACC.d >>= 1;
1103 		if (CARRY) R.ACC.d |= 0x80000000;
1104 		if (R.ALU.d & 1) SET1(C_FLAG);
1105 		else CLR1(C_FLAG);
1106 }
rovm(void)1107 static void rovm(void)
1108 {
1109 		CLR0(OVM_FLAG);
1110 }
rpt(void)1111 static void rpt(void)
1112 {
1113 		GETDATA(0,0);
1114 		R.RPTC = R.ALU.b.l;
1115 		R.init_load_addr = 2;		/* Initiate repeat mode */
1116 }
rptk(void)1117 static void rptk(void)
1118 {
1119 		R.RPTC = R.opcode.b.l;
1120 		R.init_load_addr = 2;		/* Initiate repeat mode */
1121 }
rsxm(void)1122 static void rsxm(void)
1123 {
1124 		CLR1(SXM_FLAG);
1125 }
rtc(void)1126 static void rtc(void)
1127 {
1128 		CLR1(TC_FLAG);
1129 }
rtxm(void)1130 static void rtxm(void)				/** serial port stuff */
1131 {
1132 		CLR1(TXM_FLAG);
1133 }
rxf(void)1134 static void rxf(void)
1135 {
1136 		CLR1(XF_FLAG);
1137 		S_OUT(TMS32025_XF,CLEAR_LINE);
1138 }
sach(void)1139 static void sach(void)
1140 {
1141 		R.ALU.d = (R.ACC.d << (R.opcode.b.h & 7));
1142 		PUTDATA(R.ALU.w.h);
1143 }
sacl(void)1144 static void sacl(void)
1145 {
1146 		R.ALU.d = (R.ACC.d << (R.opcode.b.h & 7));
1147 		PUTDATA(R.ALU.w.l);
1148 }
sar_ar0(void)1149 static void sar_ar0(void)	{ PUTDATA(R.AR[0]); }
sar_ar1(void)1150 static void sar_ar1(void)	{ PUTDATA(R.AR[1]); }
sar_ar2(void)1151 static void sar_ar2(void)	{ PUTDATA(R.AR[2]); }
sar_ar3(void)1152 static void sar_ar3(void)	{ PUTDATA(R.AR[3]); }
sar_ar4(void)1153 static void sar_ar4(void)	{ PUTDATA(R.AR[4]); }
sar_ar5(void)1154 static void sar_ar5(void)	{ PUTDATA(R.AR[5]); }
sar_ar6(void)1155 static void sar_ar6(void)	{ PUTDATA(R.AR[6]); }
sar_ar7(void)1156 static void sar_ar7(void)	{ PUTDATA(R.AR[7]); }
sblk(void)1157 static void sblk(void)
1158 {
1159 		oldacc.d = R.ACC.d;
1160 		R.ALU.d = (M_RDOP_ARG(R.PC) << (R.opcode.b.h & 0xf));
1161 		R.PC++;
1162 		if (SXM && (R.ALU.d & 0x8000)) R.ALU.d = -R.ALU.d;
1163 		R.ACC.d -= R.ALU.d;
1164 		CALCULATE_SUB_OVERFLOW(R.ALU.d);
1165 		CALCULATE_SUB_CARRY();
1166 }
sbrk(void)1167 static void sbrk(void)
1168 {
1169 		R.AR[ARP] -= R.opcode.b.l;
1170 }
sc(void)1171 static void sc(void)
1172 {
1173 		SET1(C_FLAG);
1174 }
sfl(void)1175 static void sfl(void)
1176 {
1177 		R.ALU.d = R.ACC.d;
1178 		R.ACC.d <<= 1;
1179 		if (R.ALU.d & 0x80000000) SET1(C_FLAG);
1180 		else CLR1(C_FLAG);
1181 }
sfr(void)1182 static void sfr(void)
1183 {
1184 		R.ALU.d = R.ACC.d;
1185 		R.ACC.d >>= 1;
1186 		if (SXM) {
1187 			if (R.ALU.d & 0x80000000) R.ACC.d |= 0x80000000;
1188 		}
1189 		if (R.ALU.d & 1) SET1(C_FLAG);
1190 		else CLR1(C_FLAG);
1191 }
sfsm(void)1192 static void sfsm(void)				/** serial port mode */
1193 {
1194 		SET1(FSM_FLAG);
1195 }
shm(void)1196 static void shm(void)
1197 {
1198 		SET1(HM_FLAG);
1199 }
sovm(void)1200 static void sovm(void)
1201 {
1202 		SET0(OVM_FLAG);
1203 }
spac(void)1204 static void spac(void)
1205 {
1206 		oldacc.d = R.ACC.d;
1207 		SHIFT_Preg_TO_ALU();
1208 		R.ACC.d -= R.ALU.d;
1209 		CALCULATE_SUB_OVERFLOW(R.ALU.d);
1210 		CALCULATE_SUB_CARRY();
1211 }
sph(void)1212 static void sph(void)
1213 {
1214 		SHIFT_Preg_TO_ALU();
1215 		PUTDATA(R.ALU.w.h);
1216 }
spl(void)1217 static void spl(void)
1218 {
1219 		SHIFT_Preg_TO_ALU();
1220 		PUTDATA(R.ALU.w.l);
1221 }
spm(void)1222 static void spm(void)
1223 {
1224 		MODIFY_PM( (R.opcode.b.l & 3) );
1225 }
sqra(void)1226 static void sqra(void)
1227 {
1228 		oldacc.d = R.ACC.d;
1229 		SHIFT_Preg_TO_ALU();
1230 		R.ACC.d += R.ALU.d;
1231 		CALCULATE_ADD_OVERFLOW(R.ALU.d);
1232 		CALCULATE_ADD_CARRY();
1233 		GETDATA(0,0);
1234 		R.Treg = R.ALU.w.l;
1235 		R.Preg.d = (R.ALU.w.l * R.ALU.w.l);
1236 }
sqrs(void)1237 static void sqrs(void)
1238 {
1239 		oldacc.d = R.ACC.d;
1240 		SHIFT_Preg_TO_ALU();
1241 		R.ACC.d -= R.ALU.d;
1242 		CALCULATE_SUB_OVERFLOW(R.ALU.d);
1243 		CALCULATE_SUB_CARRY();
1244 		GETDATA(0,0);
1245 		R.Treg = R.ALU.w.l;
1246 		R.Preg.d = (R.ALU.w.l * R.ALU.w.l);
1247 }
sst(void)1248 static void sst(void)
1249 {
1250 		PUTDATA_SST(R.STR0);
1251 }
sst1(void)1252 static void sst1(void)
1253 {
1254 		PUTDATA_SST(R.STR1);
1255 }
ssxm(void)1256 static void ssxm(void)
1257 {		/** Check instruction description, and make sure right instructions use SXM */
1258 		SET1(SXM_FLAG);
1259 }
stc(void)1260 static void stc(void)
1261 {
1262 		SET1(TC_FLAG);
1263 }
stxm(void)1264 static void stxm(void)				/** serial port stuff */
1265 {
1266 		SET1(TXM_FLAG);
1267 }
sub(void)1268 static void sub(void)
1269 {
1270 		oldacc.d = R.ACC.d;
1271 		GETDATA((R.opcode.b.h & 0xf),SXM);
1272 		R.ACC.d -= R.ALU.d;
1273 		CALCULATE_SUB_OVERFLOW(R.ALU.d);
1274 		CALCULATE_SUB_CARRY();
1275 }
subb(void)1276 static void subb(void)
1277 {
1278 		oldacc.d = R.ACC.d;
1279 		GETDATA(0,0);
1280 		if (CARRY == 0) R.ALU.d--;
1281 		R.ACC.d -= R.ALU.d;
1282 		CALCULATE_SUB_OVERFLOW(R.ALU.d);
1283 		CALCULATE_SUB_CARRY();
1284 }
subc(void)1285 static void subc(void)
1286 {
1287 		oldacc.d = R.ACC.d;
1288 		GETDATA(15,0);
1289 		R.ALU.d = R.ACC.d - R.ALU.d;
1290 		if ((INT32)((oldacc.d ^ R.ALU.d) & (oldacc.d ^ R.ACC.d)) < 0) {
1291 			SET0(OV_FLAG);			/* Not affected by OVM */
1292 		}
1293 		CALCULATE_SUB_CARRY();
1294 		if ( (INT32)(R.ALU.d) >= 0 ) {
1295 			R.ACC.d = ((R.ALU.d << 1) + 1);
1296 		}
1297 		else {
1298 			R.ACC.d = (R.ACC.d << 1);
1299 		}
1300 }
subh(void)1301 static void subh(void)
1302 {
1303 		oldacc.d = R.ACC.d;
1304 		GETDATA(0,0);
1305 		R.ACC.w.h -= R.ALU.w.l;
1306 		if ((INT16)((oldacc.w.h ^ R.ALU.w.l) & (oldacc.w.h ^ R.ACC.w.h)) < 0) {
1307 			SET0(OV_FLAG);
1308 			if (OVM)
1309 				R.ACC.w.h = ((INT16)oldacc.w.h < 0) ? 0x8000 : 0x7fff;
1310 		}
1311 		if ( ((INT16)(oldacc.w.h) >= 0) && ((INT16)(R.ACC.w.h) < 0) ) {
1312 			CLR1(C_FLAG);
1313 		}
1314 		/* Carry flag is not affected, if no borrow occured */
1315 }
subk(void)1316 static void subk(void)
1317 {
1318 		oldacc.d = R.ACC.d;
1319 		R.ALU.d = (UINT8)R.opcode.b.l;
1320 		R.ACC.d -= R.ALU.b.l;
1321 		CALCULATE_SUB_OVERFLOW(R.ALU.d);
1322 		CALCULATE_SUB_CARRY();
1323 }
subs(void)1324 static void subs(void)
1325 {
1326 		oldacc.d = R.ACC.d;
1327 		GETDATA(0,0);
1328 		R.ACC.d -= R.ALU.w.l;
1329 		CALCULATE_SUB_OVERFLOW(R.ALU.d);
1330 		CALCULATE_SUB_CARRY();
1331 }
subt(void)1332 static void subt(void)
1333 {
1334 		oldacc.d = R.ACC.d;
1335 		GETDATA((R.Treg & 0xf),SXM);
1336 		R.ACC.d -= R.ALU.d;
1337 		CALCULATE_SUB_OVERFLOW(R.ALU.d);
1338 		CALCULATE_SUB_CARRY();
1339 }
sxf(void)1340 static void sxf(void)
1341 {
1342 		SET1(XF_FLAG);
1343 		S_OUT(TMS32025_XF,ASSERT_LINE);
1344 }
tblr(void)1345 static void tblr(void)
1346 {
1347 		if (R.init_load_addr) R.PFC = R.ACC.w.l;
1348 		R.ALU.w.l = M_RDROM(R.PFC);
1349 		if ( (CNF0) && ( (UINT16)(R.PFC) >= 0xff00 ) ) {}	/** TMS32025 only */
1350 		else tms32025_icount -= (1*CLK);
1351 		PUTDATA(R.ALU.w.l);
1352 		R.PFC++;
1353 }
tblw(void)1354 static void tblw(void)
1355 {
1356 		if (R.init_load_addr) R.PFC = R.ACC.w.l;
1357 		tms32025_icount -= (1*CLK);
1358 		GETDATA(0,0);
1359 		if (R.external_mem_access) tms32025_icount -= (1*CLK);
1360 		M_WRTROM(R.PFC, R.ALU.w.l);
1361 		R.PFC++;
1362 }
trap(void)1363 static void trap(void)
1364 {
1365 		PUSH_STACK(R.PC);
1366 		R.PC = 0x001E;		/* Trap vector */
1367 }
xor(void)1368 static void xor(void)
1369 {
1370 		GETDATA(0,0);
1371 		R.ACC.w.l ^= R.ALU.w.l;
1372 }
xork(void)1373 static void xork(void)
1374 {
1375 		oldacc.d = R.ACC.d;
1376 		R.ALU.d = M_RDOP_ARG(R.PC);
1377 		R.PC++;
1378 		R.ALU.d <<= (R.opcode.b.h & 0xf);
1379 		R.ACC.d ^= R.ALU.d;
1380 		R.ACC.d |= (oldacc.d & 0x80000000);
1381 }
zalh(void)1382 static void zalh(void)
1383 {
1384 		GETDATA(0,0);
1385 		R.ACC.w.h = R.ALU.w.l;
1386 		R.ACC.w.l = 0x0000;
1387 }
zalr(void)1388 static void zalr(void)
1389 {
1390 		GETDATA(0,0);
1391 		R.ACC.w.h = R.ALU.w.l;
1392 		R.ACC.w.l = 0x8000;
1393 }
zals(void)1394 static void zals(void)
1395 {
1396 		GETDATA(0,0);
1397 		R.ACC.w.l = R.ALU.w.l;
1398 		R.ACC.w.h = 0x0000;
1399 }
1400 
1401 
1402 /***********************************************************************
1403  *	Cycle Timings
1404  ***********************************************************************/
1405 
1406 static unsigned cycles_main[256]=
1407 {
1408 /*00*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1409 /*08*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1410 /*10*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1411 /*18*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1412 /*20*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1413 /*28*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1414 /*30*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1415 /*38*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1416 /*40*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1417 /*48*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1418 /*50*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1419 /*58*/		3*CLK, 2*CLK, 1*CLK, 1*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK,
1420 /*60*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1421 /*68*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1422 /*70*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1423 /*78*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1424 /*80*/		2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK,
1425 /*88*/		2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK,
1426 /*90*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1427 /*98*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1428 /*A0*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1429 /*A8*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1430 /*B0*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1431 /*B8*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1432 /*C0*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1433 /*C8*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1434 /*D0*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 0*CLK,
1435 /*D8*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1436 /*E0*/		2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK,
1437 /*E8*/		2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK,
1438 /*F0*/		2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK,
1439 /*F8*/		2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK
1440 };
1441 
1442 static unsigned cycles_DX_subset[8]=
1443 {
1444 /*00*/		2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK, 2*CLK, 0
1445 };
1446 
1447 static unsigned cycles_CE_subset[256]=
1448 {
1449 /*00*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1450 /*08*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1451 /*10*/		0*CLK, 0*CLK, 0*CLK, 0*CLK, 1*CLK, 1*CLK, 1*CLK, 0*CLK,
1452 /*18*/		1*CLK, 1*CLK, 0*CLK, 1*CLK, 1*CLK, 1*CLK, 2*CLK, 3*CLK,
1453 /*20*/		1*CLK, 1*CLK, 0*CLK, 1*CLK, 2*CLK, 2*CLK, 2*CLK, 1*CLK,
1454 /*28*/		0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1455 /*30*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1456 /*38*/		1*CLK, 1*CLK, 0*CLK, 0*CLK, 1*CLK, 1*CLK, 1*CLK, 1*CLK,
1457 /*40*/		0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1458 /*48*/		0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1459 /*50*/		1*CLK, 1*CLK, 1*CLK, 1*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1460 /*58*/		0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1461 /*60*/		0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1462 /*68*/		0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1463 /*70*/		0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1464 /*78*/		0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1465 /*80*/		0*CLK, 0*CLK, 1*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1466 /*88*/		0*CLK, 0*CLK, 1*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1467 /*90*/		0*CLK, 0*CLK, 1*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1468 /*98*/		0*CLK, 0*CLK, 1*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1469 /*A0*/		0*CLK, 0*CLK, 1*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1470 /*A8*/		0*CLK, 0*CLK, 1*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1471 /*B0*/		0*CLK, 0*CLK, 1*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1472 /*B8*/		0*CLK, 0*CLK, 1*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1473 /*C0*/		0*CLK, 0*CLK, 1*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1474 /*C8*/		0*CLK, 0*CLK, 1*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1475 /*D0*/		0*CLK, 0*CLK, 1*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1476 /*D8*/		0*CLK, 0*CLK, 1*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1477 /*E0*/		0*CLK, 0*CLK, 1*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1478 /*E8*/		0*CLK, 0*CLK, 1*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1479 /*F0*/		0*CLK, 0*CLK, 1*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK,
1480 /*F8*/		0*CLK, 0*CLK, 1*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK, 0*CLK
1481 };
1482 
1483 
1484 /***********************************************************************
1485  *	Opcode Table
1486  ***********************************************************************/
1487 
1488 static opcode_fn opcode_main[256]=
1489 {
1490 /*00*/ add,			add,		add,		add,		add,		add,		add,		add,
1491 /*08*/ add,			add,		add,		add,		add,		add,		add,		add,
1492 /*10*/ sub,			sub,		sub,		sub,		sub,		sub,		sub,		sub,
1493 /*18*/ sub,			sub,		sub,		sub,		sub,		sub,		sub,		sub,
1494 /*20*/ lac,			lac,		lac,		lac,		lac,		lac,		lac,		lac,
1495 /*28*/ lac,			lac,		lac,		lac,		lac,		lac,		lac,		lac,
1496 /*30*/ lar_ar0,		lar_ar1,	lar_ar2,	lar_ar3,	lar_ar4,	lar_ar5,	lar_ar6,	lar_ar7,
1497 /*38*/ mpy,			sqra,		mpya,		mpys,		lt,			lta,		ltp,		ltd,
1498 /*40*/ zalh,		zals,		lact,		addc,		subh,		subs,		subt,		subc,
1499 /*48*/ addh,		adds,		addt,		rpt,		xor,		or,			and,		subb,
1500 /*50*/ lst,			lst1,		ldp,		lph,		pshd,		mar,		dmov,		bitt,
1501 /*58*/ tblr,		tblw,		sqrs,		lts,		macd,		mac,		bc,			bnc,
1502 /*60*/ sacl,		sacl,		sacl,		sacl,		sacl,		sacl,		sacl,		sacl,
1503 /*68*/ sach,		sach,		sach,		sach,		sach,		sach,		sach,		sach,
1504 /*70*/ sar_ar0,		sar_ar1,	sar_ar2,	sar_ar3,	sar_ar4,	sar_ar5,	sar_ar6,	sar_ar7,
1505 /*78*/ sst,			sst1,		popd,		zalr,		spl,		sph,		adrk,		sbrk,
1506 /*80*/ in,			in,			in,			in,			in,			in,			in,			in,
1507 /*88*/ in,			in,			in,			in,			in,			in,			in,			in,
1508 /*90*/ bit,			bit,		bit,		bit,		bit,		bit,		bit,		bit,
1509 /*98*/ bit,			bit,		bit,		bit,		bit,		bit,		bit,		bit,
1510 /*A0*/ mpyk,		mpyk,		mpyk,		mpyk,		mpyk,		mpyk,		mpyk,		mpyk,
1511 /*A8*/ mpyk,		mpyk,		mpyk,		mpyk,		mpyk,		mpyk,		mpyk,		mpyk,
1512 /*B0*/ mpyk,		mpyk,		mpyk,		mpyk,		mpyk,		mpyk,		mpyk,		mpyk,
1513 /*B8*/ mpyk,		mpyk,		mpyk,		mpyk,		mpyk,		mpyk,		mpyk,		mpyk,
1514 /*C0*/ lark_ar0,	lark_ar1,	lark_ar2,	lark_ar3,	lark_ar4,	lark_ar5,	lark_ar6,	lark_ar7,
1515 /*C8*/ ldpk,		ldpk,		lack,		rptk,		addk,		subk,		opcodes_CE,	mpyu,
1516 /*D0*/ opcodes_DX,	opcodes_DX,	opcodes_DX,	opcodes_DX,	opcodes_DX,	opcodes_DX,	opcodes_DX,	opcodes_DX,
1517 /*D8*/ opcodes_DX,	opcodes_DX,	opcodes_DX,	opcodes_DX,	opcodes_DX,	opcodes_DX,	opcodes_DX,	opcodes_DX,
1518 /*E0*/ out,			out,		out,		out,		out,		out,		out,		out,
1519 /*E8*/ out,			out,		out,		out,		out,		out,		out,		out,
1520 /*F0*/ bv,			bgz,		blez,		blz,		bgez,		bnz,		bz,			bnv,
1521 /*F8*/ bbz,			bbnz,		bioz,		banz,		blkp,		blkd,		call,		br
1522 };
1523 
1524 static opcode_fn opcode_DX_subset[8]=	/* Instructions living under the Dxxx opcode */
1525 {
1526 /*00*/ lrlk,		lalk,		adlk,		sblk,		andk,		ork,		xork,		illegal
1527 };
1528 
1529 static opcode_fn opcode_CE_subset[256]=
1530 {
1531 /*00*/ eint,		dint,		rovm,		sovm,		cnfd,		cnfp,		rsxm,		ssxm,
1532 /*08*/ spm,			spm,		spm,		spm,		rxf,		sxf,		fort,		fort,
1533 /*10*/ illegal,		illegal,	illegal,	illegal,	pac,		apac,		spac,		illegal,
1534 /*18*/ sfl,			sfr,		illegal,	abst,		push,		pop,		trap,		idle,
1535 /*20*/ rtxm,		stxm,		illegal,	neg,		cala,		bacc,		ret,		cmpl,
1536 /*28*/ illegal,		illegal,	illegal,	illegal,	illegal,	illegal,	illegal,	illegal,
1537 /*30*/ rc,			sc,			rtc,		stc,		rol,		ror,		rfsm,		sfsm,
1538 /*38*/ rhm,			shm,		illegal,	illegal,	conf,		conf,		conf,		conf,
1539 /*40*/ illegal,		illegal,	illegal,	illegal,	illegal,	illegal,	illegal,	illegal,
1540 /*48*/ illegal,		illegal,	illegal,	illegal,	illegal,	illegal,	illegal,	illegal,
1541 /*50*/ cmpr,		cmpr,		cmpr,		cmpr,		illegal,	illegal,	illegal,	illegal,
1542 /*58*/ illegal,		illegal,	illegal,	illegal,	illegal,	illegal,	illegal,	illegal,
1543 /*60*/ illegal,		illegal,	illegal,	illegal,	illegal,	illegal,	illegal,	illegal,
1544 /*68*/ illegal,		illegal,	illegal,	illegal,	illegal,	illegal,	illegal,	illegal,
1545 /*70*/ illegal,		illegal,	illegal,	illegal,	illegal,	illegal,	illegal,	illegal,
1546 /*78*/ illegal,		illegal,	illegal,	illegal,	illegal,	illegal,	illegal,	illegal,
1547 /*80*/ illegal,		illegal,	norm,		illegal,	illegal,	illegal,	illegal,	illegal,
1548 /*88*/ illegal,		illegal,	illegal,	illegal,	illegal,	illegal,	illegal,	illegal,
1549 /*90*/ illegal,		illegal,	norm,		illegal,	illegal,	illegal,	illegal,	illegal,
1550 /*98*/ illegal,		illegal,	illegal,	illegal,	illegal,	illegal,	illegal,	illegal,
1551 /*A0*/ illegal,		illegal,	norm,		illegal,	illegal,	illegal,	illegal,	illegal,
1552 /*A8*/ illegal,		illegal,	illegal,	illegal,	illegal,	illegal,	illegal,	illegal,
1553 /*B0*/ illegal,		illegal,	norm,		illegal,	illegal,	illegal,	illegal,	illegal,
1554 /*B8*/ illegal,		illegal,	illegal,	illegal,	illegal,	illegal,	illegal,	illegal,
1555 /*C0*/ illegal,		illegal,	norm,		illegal,	illegal,	illegal,	illegal,	illegal,
1556 /*C8*/ illegal,		illegal,	illegal,	illegal,	illegal,	illegal,	illegal,	illegal,
1557 /*D0*/ illegal,		illegal,	norm,		illegal,	illegal,	illegal,	illegal,	illegal,
1558 /*D8*/ illegal,		illegal,	illegal,	illegal,	illegal,	illegal,	illegal,	illegal,
1559 /*E0*/ illegal,		illegal,	norm,		illegal,	illegal,	illegal,	illegal,	illegal,
1560 /*E8*/ illegal,		illegal,	illegal,	illegal,	illegal,	illegal,	illegal,	illegal,
1561 /*F0*/ illegal,		illegal,	norm,		illegal,	illegal,	illegal,	illegal,	illegal,
1562 /*F8*/ illegal,		illegal,	illegal,	illegal,	illegal,	illegal,	illegal,	illegal
1563 };
1564 
1565 
1566 
1567 /****************************************************************************
1568  *	Inits CPU emulation
1569  ****************************************************************************/
tms32025_init(void)1570 void tms32025_init (void)
1571 {
1572 	int cpu = cpu_getactivecpu();
1573 
1574 	state_save_register_UINT16("tms32025", cpu, "PC", &R.PC, 1);
1575 	state_save_register_UINT16("tms32025", cpu, "STR0", &R.STR0, 1);
1576 	state_save_register_UINT16("tms32025", cpu, "STR1", &R.STR1, 1);
1577 	state_save_register_UINT16("tms32025", cpu, "PFC", &R.PFC, 1);
1578 	state_save_register_UINT8("tms32025", cpu, "IFR", &R.IFR, 1);
1579 	state_save_register_UINT8("tms32025", cpu, "RPTC", &R.RPTC, 1);
1580 	state_save_register_UINT32("tms32025", cpu, "ACC", &R.ACC.d, 1);
1581 	state_save_register_UINT32("tms32025", cpu, "ALU", &R.ALU.d, 1);
1582 	state_save_register_UINT32("tms32025", cpu, "Preg", &R.Preg.d, 1);
1583 	state_save_register_UINT16("tms32025", cpu, "Treg", &R.Treg, 1);
1584 	state_save_register_UINT16("tms32025", cpu, "AR0", &R.AR[0], 1);
1585 	state_save_register_UINT16("tms32025", cpu, "AR1", &R.AR[1], 1);
1586 	state_save_register_UINT16("tms32025", cpu, "AR2", &R.AR[2], 1);
1587 	state_save_register_UINT16("tms32025", cpu, "AR3", &R.AR[3], 1);
1588 	state_save_register_UINT16("tms32025", cpu, "AR4", &R.AR[4], 1);
1589 	state_save_register_UINT16("tms32025", cpu, "AR5", &R.AR[5], 1);
1590 	state_save_register_UINT16("tms32025", cpu, "AR6", &R.AR[6], 1);
1591 	state_save_register_UINT16("tms32025", cpu, "AR7", &R.AR[7], 1);
1592 	state_save_register_UINT16("tms32025", cpu, "Stack0", &R.STACK[0], 1);
1593 	state_save_register_UINT16("tms32025", cpu, "Stack1", &R.STACK[1], 1);
1594 	state_save_register_UINT16("tms32025", cpu, "Stack2", &R.STACK[2], 1);
1595 	state_save_register_UINT16("tms32025", cpu, "Stack3", &R.STACK[3], 1);
1596 	state_save_register_UINT16("tms32025", cpu, "Stack4", &R.STACK[4], 1);
1597 	state_save_register_UINT16("tms32025", cpu, "Stack5", &R.STACK[5], 1);
1598 	state_save_register_UINT16("tms32025", cpu, "Stack6", &R.STACK[6], 1);
1599 	state_save_register_UINT16("tms32025", cpu, "Stack7", &R.STACK[7], 1);
1600 
1601 	state_save_register_INT32("tms32025", cpu, "idle", &R.idle, 1);
1602 	state_save_register_INT32("tms32025", cpu, "hold", &R.hold, 1);
1603 	state_save_register_INT32("tms32025", cpu, "external_mem_access", &R.external_mem_access, 1);
1604 	state_save_register_INT32("tms32025", cpu, "init_load_addr", &R.init_load_addr, 1);
1605 	state_save_register_UINT16("tms32025", cpu, "prevpc", &R.PREVPC, 1);
1606 
1607 	state_save_register_UINT32("tms32025", cpu, "D_bank0", &TMS32025_DATA_BANK[0x0], 1);
1608 	state_save_register_UINT32("tms32025", cpu, "D_bank1", &TMS32025_DATA_BANK[0x1], 1);
1609 	state_save_register_UINT32("tms32025", cpu, "D_bank2", &TMS32025_DATA_BANK[0x2], 1);
1610 	state_save_register_UINT32("tms32025", cpu, "D_bank3", &TMS32025_DATA_BANK[0x3], 1);
1611 	state_save_register_UINT32("tms32025", cpu, "D_bank4", &TMS32025_DATA_BANK[0x4], 1);
1612 	state_save_register_UINT32("tms32025", cpu, "D_bank5", &TMS32025_DATA_BANK[0x5], 1);
1613 	state_save_register_UINT32("tms32025", cpu, "D_bank6", &TMS32025_DATA_BANK[0x6], 1);
1614 	state_save_register_UINT32("tms32025", cpu, "D_bank7", &TMS32025_DATA_BANK[0x7], 1);
1615 	state_save_register_UINT32("tms32025", cpu, "D_bank8", &TMS32025_DATA_BANK[0x8], 1);
1616 	state_save_register_UINT32("tms32025", cpu, "D_bank9", &TMS32025_DATA_BANK[0x9], 1);
1617 	state_save_register_UINT32("tms32025", cpu, "D_bankA", &TMS32025_DATA_BANK[0xa], 1);
1618 	state_save_register_UINT32("tms32025", cpu, "D_bankB", &TMS32025_DATA_BANK[0xb], 1);
1619 	state_save_register_UINT32("tms32025", cpu, "D_bankC", &TMS32025_DATA_BANK[0xc], 1);
1620 	state_save_register_UINT32("tms32025", cpu, "D_bankD", &TMS32025_DATA_BANK[0xd], 1);
1621 	state_save_register_UINT32("tms32025", cpu, "D_bankE", &TMS32025_DATA_BANK[0xe], 1);
1622 	state_save_register_UINT32("tms32025", cpu, "D_bankF", &TMS32025_DATA_BANK[0xf], 1);
1623 	state_save_register_UINT32("tms32025", cpu, "P_bank0", &TMS32025_PRGM_BANK[0x0], 1);
1624 	state_save_register_UINT32("tms32025", cpu, "P_bank1", &TMS32025_PRGM_BANK[0x1], 1);
1625 	state_save_register_UINT32("tms32025", cpu, "P_bank2", &TMS32025_PRGM_BANK[0x2], 1);
1626 	state_save_register_UINT32("tms32025", cpu, "P_bank3", &TMS32025_PRGM_BANK[0x3], 1);
1627 	state_save_register_UINT32("tms32025", cpu, "P_bank4", &TMS32025_PRGM_BANK[0x4], 1);
1628 	state_save_register_UINT32("tms32025", cpu, "P_bank5", &TMS32025_PRGM_BANK[0x5], 1);
1629 	state_save_register_UINT32("tms32025", cpu, "P_bank6", &TMS32025_PRGM_BANK[0x6], 1);
1630 	state_save_register_UINT32("tms32025", cpu, "P_bank7", &TMS32025_PRGM_BANK[0x7], 1);
1631 	state_save_register_UINT32("tms32025", cpu, "P_bank8", &TMS32025_PRGM_BANK[0x8], 1);
1632 	state_save_register_UINT32("tms32025", cpu, "P_bank9", &TMS32025_PRGM_BANK[0x9], 1);
1633 	state_save_register_UINT32("tms32025", cpu, "P_bankA", &TMS32025_PRGM_BANK[0xa], 1);
1634 	state_save_register_UINT32("tms32025", cpu, "P_bankB", &TMS32025_PRGM_BANK[0xb], 1);
1635 	state_save_register_UINT32("tms32025", cpu, "P_bankC", &TMS32025_PRGM_BANK[0xc], 1);
1636 	state_save_register_UINT32("tms32025", cpu, "P_bankD", &TMS32025_PRGM_BANK[0xd], 1);
1637 	state_save_register_UINT32("tms32025", cpu, "P_bankE", &TMS32025_PRGM_BANK[0xe], 1);
1638 	state_save_register_UINT32("tms32025", cpu, "P_bankF", &TMS32025_PRGM_BANK[0xf], 1);
1639 }
1640 
1641 /****************************************************************************
1642  *	Reset registers to their initial values
1643  ****************************************************************************/
tms32025_reset(void * param)1644 void tms32025_reset (void *param)
1645 {
1646 	R.PC = 0;			/* Starting address on a reset */
1647 	R.STR0 |= 0x0600;	/* INTM and unused bit set to 1 */
1648 	R.STR0 &= 0xefff;	/* OV cleared to 0. Remaining bits undefined */
1649 	R.STR1 |= 0x07f0;	/* SXM, C, HM, FSM, XF and unused bits set to 1 */
1650 	R.STR1 &= 0xeff0;	/* CNF, FO, TXM, PM bits cleared to 0. Remaining bits undefined */
1651 	R.RPTC = 0;			/* Reset repeat counter to 0 */
1652 	R.IFR = 0;			/* IRQ pending flags */
1653 
1654 	S_OUT(TMS32025_XF,ASSERT_LINE);	/* XF flag is high. Must set the pin */
1655 
1656 	/* ugly hack.. */
1657 	R.intRAM = (UINT16 *)memory_region(REGION_CPU1 + cpu_getactivecpu());
1658 	/* Set the internal memory mapped registers */
1659 	GREG = 0;
1660 	TIM  = 0xffff;
1661 	PRD  = 0xffff;
1662 	IMR  = 0xffc0;
1663 
1664 	R.idle = 0;
1665 	R.hold = 0;
1666 	R.init_load_addr = 1;
1667 
1668 	/* Reset the Data/Program address banks */
1669 	TMS32025_DATA_BANK[0x0] = TMS32025_DATA_OFFSET + 0x0000;
1670 	TMS32025_DATA_BANK[0x1] = TMS32025_DATA_OFFSET + 0x0100;
1671 	TMS32025_DATA_BANK[0x2] = TMS32025_DATA_OFFSET + 0x0200;
1672 	TMS32025_DATA_BANK[0x3] = TMS32025_DATA_OFFSET + 0x0300;
1673 	TMS32025_DATA_BANK[0x4] = TMS32025_DATA_OFFSET + 0x0400;
1674 	TMS32025_DATA_BANK[0x5] = TMS32025_DATA_OFFSET + 0x0500;
1675 	TMS32025_DATA_BANK[0x6] = TMS32025_DATA_OFFSET + 0x0600;
1676 	TMS32025_DATA_BANK[0x7] = TMS32025_DATA_OFFSET + 0x0700;
1677 	TMS32025_DATA_BANK[0x8] = TMS32025_DATA_OFFSET + 0x0800;
1678 	TMS32025_DATA_BANK[0x9] = TMS32025_DATA_OFFSET + 0x0900;
1679 	TMS32025_DATA_BANK[0xa] = TMS32025_DATA_OFFSET + 0x0a00;
1680 	TMS32025_DATA_BANK[0xb] = TMS32025_DATA_OFFSET + 0x0b00;
1681 	TMS32025_DATA_BANK[0xc] = TMS32025_DATA_OFFSET + 0x0c00;
1682 	TMS32025_DATA_BANK[0xd] = TMS32025_DATA_OFFSET + 0x0d00;
1683 	TMS32025_DATA_BANK[0xe] = TMS32025_DATA_OFFSET + 0x0e00;
1684 	TMS32025_DATA_BANK[0xf] = TMS32025_DATA_OFFSET + 0x0f00;
1685 
1686 	TMS32025_PRGM_BANK[0x0] = TMS32025_PGM_OFFSET + 0x0000;
1687 	TMS32025_PRGM_BANK[0x1] = TMS32025_PGM_OFFSET + 0x0100;
1688 	TMS32025_PRGM_BANK[0x2] = TMS32025_PGM_OFFSET + 0x0200;
1689 	TMS32025_PRGM_BANK[0x3] = TMS32025_PGM_OFFSET + 0x0300;
1690 	TMS32025_PRGM_BANK[0x4] = TMS32025_PGM_OFFSET + 0x0400;
1691 	TMS32025_PRGM_BANK[0x5] = TMS32025_PGM_OFFSET + 0x0500;
1692 	TMS32025_PRGM_BANK[0x6] = TMS32025_PGM_OFFSET + 0x0600;
1693 	TMS32025_PRGM_BANK[0x7] = TMS32025_PGM_OFFSET + 0x0700;
1694 	TMS32025_PRGM_BANK[0x8] = TMS32025_PGM_OFFSET + 0x0800;
1695 	TMS32025_PRGM_BANK[0x9] = TMS32025_PGM_OFFSET + 0x0900;
1696 	TMS32025_PRGM_BANK[0xa] = TMS32025_PGM_OFFSET + 0x0a00;
1697 	TMS32025_PRGM_BANK[0xb] = TMS32025_PGM_OFFSET + 0x0b00;
1698 	TMS32025_PRGM_BANK[0xc] = TMS32025_PGM_OFFSET + 0x0c00;
1699 	TMS32025_PRGM_BANK[0xd] = TMS32025_PGM_OFFSET + 0x0d00;
1700 	TMS32025_PRGM_BANK[0xe] = TMS32025_PGM_OFFSET + 0x0e00;
1701 	TMS32025_PRGM_BANK[0xf] = TMS32025_PGM_OFFSET + 0x0f00;
1702 }
1703 
1704 
1705 /****************************************************************************
1706  *	Shut down CPU emulation
1707  ****************************************************************************/
tms32025_exit(void)1708 void tms32025_exit (void)
1709 {
1710 	/* nothing to do ? */
1711 }
1712 
1713 
1714 /****************************************************************************
1715  *	Issue an interrupt if necessary
1716  ****************************************************************************/
process_IRQs(void)1717 static int process_IRQs(void)
1718 {
1719 	/********** Interrupt Flag Register (IFR) **********
1720 		|  5  |  4  |  3  |  2  |  1  |  0  |
1721 		| XINT| RINT| TINT| INT2| INT1| INT0|
1722 	*/
1723 
1724 	R.tms32025_irq_cycles = 0;
1725 
1726 	/* Dont service Interrupts if masked, or prev instruction was EINT ! */
1727 
1728 	if ( (INTM == 0) && (R.opcode.w.l != 0xce00) && (R.IFR & IMR) )
1729 	{
1730 		R.tms32025_irq_cycles = (3*CLK);	/* 3 clock cycles used due to PUSH and DINT operation ? */
1731 		PUSH_STACK(R.PC);
1732 
1733 		if ((R.IFR & 0x01) && (IMR & 0x01)) {		/* IRQ line 0 */
1734 			log_cb(RETRO_LOG_DEBUG, LOGPRE "TMS32025:  Active INT0\n");
1735 			R.PC = 0x0002;
1736 			(*R.irq_callback)(0);
1737 			R.idle = 0;
1738 			R.IFR &= (~0x01);
1739 			SET0(INTM_FLAG);
1740 			return R.tms32025_irq_cycles;
1741 		}
1742 		if ((R.IFR & 0x02) && (IMR & 0x02)) {		/* IRQ line 1 */
1743 			log_cb(RETRO_LOG_DEBUG, LOGPRE "TMS32025:  Active INT1\n");
1744 			R.PC = 0x0004;
1745 			(*R.irq_callback)(1);
1746 			R.idle = 0;
1747 			R.IFR &= (~0x02);
1748 			SET0(INTM_FLAG);
1749 			return R.tms32025_irq_cycles;
1750 		}
1751 		if ((R.IFR & 0x04) && (IMR & 0x04)) {		/* IRQ line 2 */
1752 			log_cb(RETRO_LOG_DEBUG, LOGPRE "TMS32025:  Active INT2\n");
1753 			R.PC = 0x0006;
1754 			(*R.irq_callback)(2);
1755 			R.idle = 0;
1756 			R.IFR &= (~0x04);
1757 			SET0(INTM_FLAG);
1758 			return R.tms32025_irq_cycles;
1759 		}
1760 		if ((R.IFR & 0x08) && (IMR & 0x08)) {		/* Timer IRQ (internal) */
1761 			log_cb(RETRO_LOG_DEBUG, LOGPRE "TMS32025:  Active TINT (Timer)\n");
1762 			R.PC = 0x0018;
1763 			R.idle = 0;
1764 			R.IFR &= (~0x08);
1765 			SET0(INTM_FLAG);
1766 			return R.tms32025_irq_cycles;
1767 		}
1768 		if ((R.IFR & 0x10) && (IMR & 0x10)) {		/* Serial port receive IRQ (internal) */
1769 			log_cb(RETRO_LOG_DEBUG, LOGPRE "TMS32025:  Active RINT (Serial recieve)\n");
1770 			R.PC = 0x001A;
1771 			R.idle = 0;
1772 			R.IFR &= (~0x10);
1773 			SET0(INTM_FLAG);
1774 			return R.tms32025_irq_cycles;
1775 		}
1776 		if ((R.IFR & 0x20) && (IMR & 0x20)) {		/* Serial port transmit IRQ (internal) */
1777 			log_cb(RETRO_LOG_DEBUG, LOGPRE "TMS32025:  Active XINT (Serial transmit)\n");
1778 			R.PC = 0x001C;
1779 			R.idle = 0;
1780 			R.IFR &= (~0x20);
1781 			SET0(INTM_FLAG);
1782 			return R.tms32025_irq_cycles;
1783 		}
1784 	}
1785 	return R.tms32025_irq_cycles;
1786 }
1787 
process_timer(int counts)1788 static INLINE void process_timer(int counts)
1789 {
1790 	if (counts > TIM) {				/* Overflow timer counts ? */
1791 		if (counts > PRD) {
1792 			counts %= (PRD + 1);
1793 		}
1794 		if (counts > TIM) {
1795 			TIM = (PRD + 1) - (counts - TIM);
1796 		}
1797 		else {
1798 			TIM -= counts;
1799 		}
1800 
1801 		R.IFR |= 0x08;
1802 		tms32025_icount -= process_IRQs();		/* Handle Timer IRQ */
1803 	}
1804 	else {
1805 		TIM -= counts;
1806 	}
1807 }
1808 
1809 /****************************************************************************
1810  *	Execute ICount cycles. Exit when 0 or less
1811  ****************************************************************************/
tms32025_execute(int cycles)1812 int tms32025_execute(int cycles)
1813 {
1814 	tms32025_icount = cycles;
1815 
1816 
1817 	/**** Respond to external hold signal */
1818 	if (S_IN(TMS32025_HOLD) == ASSERT_LINE) {
1819 		if (R.hold == 0) {
1820 			S_OUT(TMS32025_HOLDA,ASSERT_LINE);	/* Hold-Ack (active low) */
1821 		}
1822 		R.hold = 1;
1823 		if (HM) {
1824 			tms32025_icount = 0;		/* Exit */
1825 		}
1826 		else {
1827 			if (R.external_mem_access) {
1828 				tms32025_icount = 0;	/* Exit */
1829 			}
1830 		}
1831 	}
1832 	else {
1833 		if (R.hold == 1) {
1834 			S_OUT(TMS32025_HOLDA,CLEAR_LINE);	/* Hold-Ack (active low) */
1835 			tms32025_icount -= 3;
1836 		}
1837 		R.hold = 0;
1838 	}
1839 
1840 	/**** If idling, update timer and/or exit execution */
1841 	if (R.idle) {
1842 		if ((R.hold == 0) && (IMR & 0x08) && (INTM == 0)){
1843 			process_timer(TIM + 1);
1844 			tms32025_icount -= ((TIM + 1) * CLK);
1845 		}
1846 		else {
1847 			process_timer(((tms32025_icount + CLK) / CLK));
1848 			tms32025_icount = (tms32025_icount % CLK) - CLK;	/* Exit */
1849 		}
1850 	}
1851 
1852 	if (tms32025_icount <= 0) CALL_MAME_DEBUG;
1853 
1854 
1855 	while (tms32025_icount > 0)
1856 	{
1857 		R.tms32025_dec_cycles = (1*CLK);
1858 
1859 		if (R.IFR) {	/* Check IRQ Flag Register for pending IRQs */
1860 			R.tms32025_dec_cycles += process_IRQs();
1861 		}
1862 
1863 		R.PREVPC = R.PC;
1864 
1865 		CALL_MAME_DEBUG;
1866 
1867 		R.opcode.d = M_RDOP(R.PC);
1868 		R.PC++;
1869 
1870 		if (R.opcode.b.h == 0xCE)	/* Opcode 0xCExx has many opcodes in its minor byte */
1871 		{
1872 			R.tms32025_dec_cycles = cycles_CE_subset[R.opcode.b.l];
1873 			(*(opcode_CE_subset[R.opcode.b.l]))();
1874 		}
1875 		else if ((R.opcode.w.l & 0xf0f8) == 0xd000)	/* Opcode 0xDxxx has many opcodes in its minor byte */
1876 		{
1877 			R.tms32025_dec_cycles = cycles_DX_subset[R.opcode.b.l];
1878 			(*(opcode_DX_subset[R.opcode.b.l]))();
1879 		}
1880 		else			/* Do all opcodes except the CExx and Dxxx ones */
1881 		{
1882 			R.tms32025_dec_cycles = cycles_main[R.opcode.b.h];
1883 			(*(opcode_main[R.opcode.b.h]))();
1884 		}
1885 
1886 
1887 		if (R.init_load_addr == 2) {		/* Repeat next instruction */
1888 			R.PREVPC = R.PC;
1889 
1890 			CALL_MAME_DEBUG;
1891 
1892 			R.opcode.d = M_RDOP(R.PC);
1893 			R.PC++;
1894 			R.tms32025_dec_cycles += (1*CLK);
1895 
1896 			do {
1897 				if (R.opcode.b.h == 0xCE)
1898 				{							/* Do all 0xCExx Opcodes */
1899 					if (R.init_load_addr) {
1900 						R.tms32025_dec_cycles += (1*CLK);
1901 					}
1902 					else {
1903 						R.tms32025_dec_cycles += (1*CLK);
1904 					}
1905 					(*(opcode_CE_subset[R.opcode.b.l]))();
1906 				}
1907 				if ((R.opcode.w.l & 0xf0f8) == 0xd000)
1908 				{							/* Do all valid 0xDxxx Opcodes */
1909 					if (R.init_load_addr) {
1910 						R.tms32025_dec_cycles += (1*CLK);
1911 					}
1912 					else {
1913 						R.tms32025_dec_cycles += (1*CLK);
1914 					}
1915 					(*(opcode_DX_subset[R.opcode.b.l]))();
1916 				}
1917 				else
1918 				{							/* Do all other opcodes */
1919 					if (R.init_load_addr) {
1920 						R.tms32025_dec_cycles += (1*CLK);
1921 					}
1922 					else {
1923 						R.tms32025_dec_cycles += (1*CLK);
1924 					}
1925 					(*(opcode_main[R.opcode.b.h]))();
1926 				}
1927 				R.init_load_addr = 0;
1928 				R.RPTC-- ;
1929 			} while ((INT8)(R.RPTC) != -1);
1930 			R.RPTC = 0;
1931 			R.PFC = R.PC;
1932 			R.init_load_addr = 1;
1933 		}
1934 
1935 		tms32025_icount -= R.tms32025_dec_cycles;
1936 
1937 		/**** If device is put into idle mode, exit and wait for an interrupt */
1938 		if (R.idle) {
1939 			if ((R.hold == 0) && (IMR & 0x08) && (INTM == 0)) {
1940 				if (R.tms32025_dec_cycles < (TIM * CLK)) {
1941 					int burn_cycles;
1942 					burn_cycles = ((TIM * CLK) <= tms32025_icount) ? (TIM * CLK) : tms32025_icount;
1943 					R.tms32025_dec_cycles += burn_cycles;
1944 					tms32025_icount -= burn_cycles;
1945 				}
1946 			}
1947 			else {
1948 				R.tms32025_dec_cycles += (tms32025_icount + CLK);
1949 				tms32025_icount = (tms32025_icount % CLK) - CLK;	/* Exit */
1950 			}
1951 		}
1952 
1953 		process_timer((R.tms32025_dec_cycles / CLK));
1954 
1955 		/**** If hold pin is active, exit if accessing external memory or if HM is set */
1956 		if (R.hold) {
1957 			if (R.external_mem_access || (HM)) {
1958 				if (tms32025_icount > 0) {
1959 					tms32025_icount = 0;
1960 				}
1961 			}
1962 		}
1963 	}
1964 
1965 	return (cycles - tms32025_icount);
1966 }
1967 
1968 /****************************************************************************
1969  *	Get all registers in given buffer
1970  ****************************************************************************/
tms32025_get_context(void * dst)1971 unsigned tms32025_get_context (void *dst)
1972 {
1973 	if (dst)
1974 		*(tms32025_Regs*)dst = R;
1975 	return sizeof(tms32025_Regs);
1976 }
1977 
1978 /****************************************************************************
1979  *	Set all registers to given values
1980  ****************************************************************************/
tms32025_set_context(void * src)1981 void tms32025_set_context (void *src)
1982 {
1983 	if (src)
1984 		R = *(tms32025_Regs*)src;
1985 }
1986 
1987 
1988 /****************************************************************************
1989  *	Return a specific register
1990  ****************************************************************************/
tms32025_get_reg(int regnum)1991 unsigned tms32025_get_reg(int regnum)
1992 {
1993 	switch (regnum)
1994 	{
1995 		case REG_PC:
1996 		case TMS32025_PC: return R.PC;
1997 		/* This is actually not a stack pointer, but the stack contents */
1998 		case REG_SP:
1999 		case TMS32025_STK7:  return R.STACK[7];
2000 		case TMS32025_STK6:  return R.STACK[6];
2001 		case TMS32025_STK5:  return R.STACK[5];
2002 		case TMS32025_STK4:  return R.STACK[4];
2003 		case TMS32025_STK3:  return R.STACK[3];
2004 		case TMS32025_STK2:  return R.STACK[2];
2005 		case TMS32025_STK1:  return R.STACK[1];
2006 		case TMS32025_STK0:  return R.STACK[0];
2007 		case TMS32025_STR0:  return R.STR0;
2008 		case TMS32025_STR1:  return R.STR1;
2009 		case TMS32025_IFR:   return R.IFR;
2010 		case TMS32025_RPTC:  return R.RPTC;
2011 		case TMS32025_ACC:   return R.ACC.d;
2012 		case TMS32025_PREG:  return R.Preg.d;
2013 		case TMS32025_TREG:  return R.Treg;
2014 		case TMS32025_AR0:   return R.AR[0];
2015 		case TMS32025_AR1:   return R.AR[1];
2016 		case TMS32025_AR2:   return R.AR[2];
2017 		case TMS32025_AR3:   return R.AR[3];
2018 		case TMS32025_AR4:   return R.AR[4];
2019 		case TMS32025_AR5:   return R.AR[5];
2020 		case TMS32025_AR6:   return R.AR[6];
2021 		case TMS32025_AR7:   return R.AR[7];
2022 		case TMS32025_DRR:   return M_RDRAM(0);
2023 		case TMS32025_DXR:   return M_RDRAM(1);
2024 		case TMS32025_TIM:   return M_RDRAM(2);
2025 		case TMS32025_PRD:   return M_RDRAM(3);
2026 		case TMS32025_IMR:   return M_RDRAM(4);
2027 		case TMS32025_GREG:  return M_RDRAM(5);
2028 		case REG_PREVIOUSPC: return R.PREVPC;
2029 		default:
2030 			if (regnum <= REG_SP_CONTENTS)
2031 			{
2032 				unsigned offset = (REG_SP_CONTENTS - regnum);
2033 				if (offset < 8)
2034 					return R.STACK[offset];
2035 			}
2036 	}
2037 	return 0;
2038 }
2039 
2040 
2041 /****************************************************************************
2042  *	Set a specific register
2043  ****************************************************************************/
tms32025_set_reg(int regnum,unsigned val)2044 void tms32025_set_reg(int regnum, unsigned val)
2045 {
2046 	switch (regnum)
2047 	{
2048 		case REG_PC:
2049 		case TMS32025_PC: R.PC = val; break;
2050 		/* This is actually not a stack pointer, but the stack contents */
2051 		case REG_SP:
2052 		case TMS32025_STK7: R.STACK[7] = val; break;
2053 		case TMS32025_STK6: R.STACK[6] = val; break;
2054 		case TMS32025_STK5: R.STACK[5] = val; break;
2055 		case TMS32025_STK4: R.STACK[4] = val; break;
2056 		case TMS32025_STK3: R.STACK[3] = val; break;
2057 		case TMS32025_STK2: R.STACK[2] = val; break;
2058 		case TMS32025_STK1: R.STACK[1] = val; break;
2059 		case TMS32025_STK0: R.STACK[0] = val; break;
2060 		case TMS32025_STR0: R.STR0 = val; break;
2061 		case TMS32025_STR1: R.STR1 = val; break;
2062 		case TMS32025_IFR:  R.IFR = val; break;
2063 		case TMS32025_RPTC: R.RPTC = val; break;
2064 		case TMS32025_ACC:  R.ACC.d = val; break;
2065 		case TMS32025_PREG: R.Preg.d = val; break;
2066 		case TMS32025_TREG: R.Treg = val; break;
2067 		case TMS32025_AR0:  R.AR[0] = val; break;
2068 		case TMS32025_AR1:  R.AR[1] = val; break;
2069 		case TMS32025_AR2:  R.AR[2] = val; break;
2070 		case TMS32025_AR3:  R.AR[3] = val; break;
2071 		case TMS32025_AR4:  R.AR[4] = val; break;
2072 		case TMS32025_AR5:  R.AR[5] = val; break;
2073 		case TMS32025_AR6:  R.AR[6] = val; break;
2074 		case TMS32025_AR7:  R.AR[7] = val; break;
2075 		case TMS32025_DRR:  M_WRTRAM(0,val); break;
2076 		case TMS32025_DXR:  M_WRTRAM(1,val); break;
2077 		case TMS32025_TIM:  M_WRTRAM(2,val); break;
2078 		case TMS32025_PRD:  M_WRTRAM(3,val); break;
2079 		case TMS32025_IMR:  M_WRTRAM(4,val); break;
2080 		case TMS32025_GREG: M_WRTRAM(5,val); break;
2081 		default:
2082 			if (regnum <= REG_SP_CONTENTS)
2083 			{
2084 				unsigned offset = (REG_SP_CONTENTS - regnum);
2085 				if (offset < 8)
2086 					R.STACK[offset] = val;
2087 			}
2088 	}
2089 }
2090 
2091 
2092 /****************************************************************************
2093  *	Set IRQ line state
2094  ****************************************************************************/
tms32025_set_irq_line(int irqline,int state)2095 void tms32025_set_irq_line(int irqline, int state)
2096 {
2097 	/* Pending IRQs cannot be cleared */
2098 
2099 	if (state != CLEAR_LINE)
2100 	{
2101 		R.IFR |= (1 << irqline);
2102 		R.IFR &= 0x07;
2103 	}
2104 }
2105 
tms32025_set_irq_callback(int (* callback)(int irqline))2106 void tms32025_set_irq_callback(int (*callback)(int irqline))
2107 {
2108 	/* IACK is only a general IRQ Ack - no vector related stuff */
2109 
2110 	R.irq_callback = callback;
2111 }
2112 
2113 /****************************************************************************
2114  *	Return a formatted string for a register
2115  ****************************************************************************/
tms32025_info(void * context,int regnum)2116 const char *tms32025_info(void *context, int regnum)
2117 {
2118 	static char buffer[32][63+1];
2119 	static int which = 0;
2120 	tms32025_Regs *r = context;
2121 
2122 	which = (which+1) % 32;
2123 	buffer[which][0] = '\0';
2124 	if (!context)
2125 		r = &R;
2126 
2127 	switch (regnum)
2128 	{
2129 		case CPU_INFO_REG+TMS32025_PC: sprintf(buffer[which], "PC:%04X",  r->PC); break;
2130 		case CPU_INFO_REG+TMS32025_STR0: sprintf(buffer[which], "STR0:%04X", r->STR0); break;
2131 		case CPU_INFO_REG+TMS32025_STR1: sprintf(buffer[which], "STR1:%04X", r->STR1); break;
2132 		case CPU_INFO_REG+TMS32025_IFR: sprintf(buffer[which], "IFR:%04X", r->IFR); break;
2133 		case CPU_INFO_REG+TMS32025_RPTC: sprintf(buffer[which], "RPTC:%02X", r->RPTC); break;
2134 		case CPU_INFO_REG+TMS32025_STK7: sprintf(buffer[which], "STK7:%04X", r->STACK[7]); break;
2135 		case CPU_INFO_REG+TMS32025_STK6: sprintf(buffer[which], "STK6:%04X", r->STACK[6]); break;
2136 		case CPU_INFO_REG+TMS32025_STK5: sprintf(buffer[which], "STK5:%04X", r->STACK[5]); break;
2137 		case CPU_INFO_REG+TMS32025_STK4: sprintf(buffer[which], "STK4:%04X", r->STACK[4]); break;
2138 		case CPU_INFO_REG+TMS32025_STK3: sprintf(buffer[which], "STK3:%04X", r->STACK[3]); break;
2139 		case CPU_INFO_REG+TMS32025_STK2: sprintf(buffer[which], "STK2:%04X", r->STACK[2]); break;
2140 		case CPU_INFO_REG+TMS32025_STK1: sprintf(buffer[which], "STK1:%04X", r->STACK[1]); break;
2141 		case CPU_INFO_REG+TMS32025_STK0: sprintf(buffer[which], "STK0:%04X", r->STACK[0]); break;
2142 		case CPU_INFO_REG+TMS32025_ACC: sprintf(buffer[which], "ACC:%08X", r->ACC.d); break;
2143 		case CPU_INFO_REG+TMS32025_PREG: sprintf(buffer[which], "P:%08X", r->Preg.d); break;
2144 		case CPU_INFO_REG+TMS32025_TREG: sprintf(buffer[which], "T:%04X", r->Treg); break;
2145 		case CPU_INFO_REG+TMS32025_AR0: sprintf(buffer[which], "AR0:%04X", r->AR[0]); break;
2146 		case CPU_INFO_REG+TMS32025_AR1: sprintf(buffer[which], "AR1:%04X", r->AR[1]); break;
2147 		case CPU_INFO_REG+TMS32025_AR2: sprintf(buffer[which], "AR2:%04X", r->AR[2]); break;
2148 		case CPU_INFO_REG+TMS32025_AR3: sprintf(buffer[which], "AR3:%04X", r->AR[3]); break;
2149 		case CPU_INFO_REG+TMS32025_AR4: sprintf(buffer[which], "AR4:%04X", r->AR[4]); break;
2150 		case CPU_INFO_REG+TMS32025_AR5: sprintf(buffer[which], "AR5:%04X", r->AR[5]); break;
2151 		case CPU_INFO_REG+TMS32025_AR6: sprintf(buffer[which], "AR6:%04X", r->AR[6]); break;
2152 		case CPU_INFO_REG+TMS32025_AR7: sprintf(buffer[which], "AR7:%04X", r->AR[7]); break;
2153 		case CPU_INFO_REG+TMS32025_DRR: sprintf(buffer[which], "DRR:%04X", M_RDRAM(0)); break;
2154 		case CPU_INFO_REG+TMS32025_DXR: sprintf(buffer[which], "DXR:%04X", M_RDRAM(1)); break;
2155 		case CPU_INFO_REG+TMS32025_TIM: sprintf(buffer[which], "TIM:%04X", M_RDRAM(2)); break;
2156 		case CPU_INFO_REG+TMS32025_PRD: sprintf(buffer[which], "PRD:%04X", M_RDRAM(3)); break;
2157 		case CPU_INFO_REG+TMS32025_IMR: sprintf(buffer[which], "IMR:%04X", M_RDRAM(4)); break;
2158 		case CPU_INFO_REG+TMS32025_GREG: sprintf(buffer[which], "GREG:%04X", M_RDRAM(5)); break;
2159 		case CPU_INFO_FLAGS:
2160 			sprintf(buffer[which], "arp%d%c%c%c%cdp%03x  arb%d%c%c%c%c%c%c%c%c%c%c%cpm%d",
2161 				(r->STR0 & 0xe000) >> 13,
2162 				r->STR0 & 0x1000 ? 'O':'.',
2163 				r->STR0 & 0x0800 ? 'M':'.',
2164 				r->STR0 & 0x0400 ? '.':'?',
2165 				r->STR0 & 0x0200 ? 'I':'.',
2166 				(r->STR0 & 0x01ff),
2167 
2168 				(r->STR1 & 0xe000) >> 13,
2169 				r->STR1 & 0x1000 ? 'P':'D',
2170 				r->STR1 & 0x0800 ? 'T':'.',
2171 				r->STR1 & 0x0400 ? 'S':'.',
2172 				r->STR1 & 0x0200 ? 'C':'?',
2173 				r->STR0 & 0x0100 ? '.':'?',
2174 				r->STR1 & 0x0080 ? '.':'?',
2175 				r->STR1 & 0x0040 ? 'H':'.',
2176 				r->STR1 & 0x0020 ? 'F':'.',
2177 				r->STR1 & 0x0010 ? 'X':'.',
2178 				r->STR1 & 0x0008 ? 'f':'.',
2179 				r->STR1 & 0x0004 ? 'o':'i',
2180 				(r->STR1 & 0x0003) );
2181 			break;
2182 		case CPU_INFO_NAME: return "TMS32025";
2183 		case CPU_INFO_FAMILY: return "Texas Instruments TMS320x25";
2184 		case CPU_INFO_VERSION: return "1.10";
2185 		case CPU_INFO_FILE: return __FILE__;
2186 		case CPU_INFO_CREDITS: return "Copyright (C) 2001 by Tony La Porta";
2187 		case CPU_INFO_REG_LAYOUT: return (const char*)tms32025_reg_layout;
2188 		case CPU_INFO_WIN_LAYOUT: return (const char*)tms32025_win_layout;
2189 		default: return "";
2190 	}
2191 	return buffer[which];
2192 }
2193 
tms32025_dasm(char * buffer,unsigned pc)2194 unsigned tms32025_dasm(char *buffer, unsigned pc)
2195 {
2196 #ifdef MAME_DEBUG
2197 	return Dasm32025( buffer, pc );
2198 #else
2199 	sprintf( buffer, "$%04X", TMS32025_RDOP(pc) );
2200 	return 2;
2201 #endif
2202 }
2203