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