1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 /***************************************************************************
4 
5     ppccom.c
6 
7     Common PowerPC definitions and functions
8 
9 ***************************************************************************/
10 
11 #include "emu.h"
12 #include "ppccom.h"
13 #include "ppcfe.h"
14 #include "ppc_dasm.h"
15 
16 /***************************************************************************
17     DEBUGGING
18 ***************************************************************************/
19 
20 #define PRINTF_SPU              (0)
21 #define PRINTF_DECREMENTER      (0)
22 
23 
24 
25 /***************************************************************************
26     CONSTANTS
27 ***************************************************************************/
28 
29 #define DOUBLE_SIGN     (0x8000000000000000U)
30 #define DOUBLE_EXP      (0x7ff0000000000000U)
31 #define DOUBLE_FRAC     (0x000fffffffffffffU)
32 #define DOUBLE_ZERO     (0)
33 
34 
35 
36 /***************************************************************************
37     PRIVATE GLOBAL VARIABLES
38 ***************************************************************************/
39 
40 /* lookup table for FP modes */
41 static const uint8_t fpmode_source[4] =
42 {
43 	uml::ROUND_ROUND,
44 	uml::ROUND_TRUNC,
45 	uml::ROUND_CEIL,
46 	uml::ROUND_FLOOR
47 };
48 
49 /* flag lookup table for SZ */
50 static const uint8_t sz_cr_table_source[32] =
51 {
52 	/* ..... */ 0x4,
53 	/* ....C */ 0x4,
54 	/* ...V. */ 0x4,
55 	/* ...VC */ 0x4,
56 	/* ..Z.. */ 0x2,
57 	/* ..Z.C */ 0x2,
58 	/* ..ZV. */ 0x2,
59 	/* ..ZVC */ 0x2,
60 	/* .S... */ 0x8,
61 	/* .S..C */ 0x8,
62 	/* .S.V. */ 0x8,
63 	/* .S.VC */ 0x8,
64 	/* .SZ.. */ 0x2,
65 	/* .SZ.C */ 0x2,
66 	/* .SZV. */ 0x2,
67 	/* .SZVC */ 0x2,
68 	/* U.... */ 0x4,
69 	/* U...C */ 0x4,
70 	/* U..V. */ 0x4,
71 	/* U..VC */ 0x4,
72 	/* U.Z.. */ 0x2,
73 	/* U.Z.C */ 0x2,
74 	/* U.ZV. */ 0x2,
75 	/* U.ZVC */ 0x2,
76 	/* US... */ 0x8,
77 	/* US..C */ 0x8,
78 	/* US.V. */ 0x8,
79 	/* US.VC */ 0x8,
80 	/* USZ.. */ 0x2,
81 	/* USZ.C */ 0x2,
82 	/* USZV. */ 0x2,
83 	/* USZVC */ 0x2
84 };
85 
86 /* flag lookup table for CMP */
87 static const uint8_t cmp_cr_table_source[32] =
88 {
89 	/* ..... */ 0x4,
90 	/* ....C */ 0x4,
91 	/* ...V. */ 0x8,
92 	/* ...VC */ 0x8,
93 	/* ..Z.. */ 0x2,
94 	/* ..Z.C */ 0x2,
95 	/* ..ZV. */ 0x2,
96 	/* ..ZVC */ 0x2,
97 	/* .S... */ 0x8,
98 	/* .S..C */ 0x8,
99 	/* .S.V. */ 0x4,
100 	/* .S.VC */ 0x4,
101 	/* .SZ.. */ 0x2,
102 	/* .SZ.C */ 0x2,
103 	/* .SZV. */ 0x2,
104 	/* .SZVC */ 0x2,
105 	/* U.... */ 0x4,
106 	/* U...C */ 0x4,
107 	/* U..V. */ 0x8,
108 	/* U..VC */ 0x8,
109 	/* U.Z.. */ 0x2,
110 	/* U.Z.C */ 0x2,
111 	/* U.ZV. */ 0x2,
112 	/* U.ZVC */ 0x2,
113 	/* US... */ 0x8,
114 	/* US..C */ 0x8,
115 	/* US.V. */ 0x4,
116 	/* US.VC */ 0x4,
117 	/* USZ.. */ 0x2,
118 	/* USZ.C */ 0x2,
119 	/* USZV. */ 0x2,
120 	/* USZVC */ 0x2
121 };
122 
123 /* flag lookup table for CMPL */
124 static const uint8_t cmpl_cr_table_source[32] =
125 {
126 	/* ..... */ 0x4,
127 	/* ....C */ 0x8,
128 	/* ...V. */ 0x4,
129 	/* ...VC */ 0x8,
130 	/* ..Z.. */ 0x2,
131 	/* ..Z.C */ 0x2,
132 	/* ..ZV. */ 0x2,
133 	/* ..ZVC */ 0x2,
134 	/* .S... */ 0x4,
135 	/* .S..C */ 0x8,
136 	/* .S.V. */ 0x4,
137 	/* .S.VC */ 0x8,
138 	/* .SZ.. */ 0x2,
139 	/* .SZ.C */ 0x2,
140 	/* .SZV. */ 0x2,
141 	/* .SZVC */ 0x2,
142 	/* U.... */ 0x4,
143 	/* U...C */ 0x8,
144 	/* U..V. */ 0x4,
145 	/* U..VC */ 0x8,
146 	/* U.Z.. */ 0x2,
147 	/* U.Z.C */ 0x2,
148 	/* U.ZV. */ 0x2,
149 	/* U.ZVC */ 0x2,
150 	/* US... */ 0x4,
151 	/* US..C */ 0x8,
152 	/* US.V. */ 0x4,
153 	/* US.VC */ 0x8,
154 	/* USZ.. */ 0x2,
155 	/* USZ.C */ 0x2,
156 	/* USZV. */ 0x2,
157 	/* USZVC */ 0x2
158 };
159 
160 /* flag lookup table for FCMP */
161 static const uint8_t fcmp_cr_table_source[32] =
162 {
163 	/* ..... */ 0x4,
164 	/* ....C */ 0x8,
165 	/* ...V. */ 0x4,
166 	/* ...VC */ 0x8,
167 	/* ..Z.. */ 0x2,
168 	/* ..Z.C */ 0xa,
169 	/* ..ZV. */ 0x2,
170 	/* ..ZVC */ 0xa,
171 	/* .S... */ 0x4,
172 	/* .S..C */ 0x8,
173 	/* .S.V. */ 0x4,
174 	/* .S.VC */ 0x8,
175 	/* .SZ.. */ 0x2,
176 	/* .SZ.C */ 0xa,
177 	/* .SZV. */ 0x2,
178 	/* .SZVC */ 0xa,
179 	/* U.... */ 0x5,
180 	/* U...C */ 0x9,
181 	/* U..V. */ 0x5,
182 	/* U..VC */ 0x9,
183 	/* U.Z.. */ 0x3,
184 	/* U.Z.C */ 0xb,
185 	/* U.ZV. */ 0x3,
186 	/* U.ZVC */ 0xb,
187 	/* US... */ 0x5,
188 	/* US..C */ 0x9,
189 	/* US.V. */ 0x5,
190 	/* US.VC */ 0x9,
191 	/* USZ.. */ 0x3,
192 	/* USZ.C */ 0xb,
193 	/* USZV. */ 0x3,
194 	/* USZVC */ 0xb
195 };
196 
197 
198 DEFINE_DEVICE_TYPE(PPC601,    ppc601_device,    "ppc601",     "IBM PowerPC 601")
199 DEFINE_DEVICE_TYPE(PPC602,    ppc602_device,    "ppc602",     "IBM PowerPC 602")
200 DEFINE_DEVICE_TYPE(PPC603,    ppc603_device,    "ppc603",     "IBM PowerPC 603")
201 DEFINE_DEVICE_TYPE(PPC603E,   ppc603e_device,   "ppc603e",    "IBM PowerPC 603E")
202 DEFINE_DEVICE_TYPE(PPC603R,   ppc603r_device,   "ppc603r",    "IBM PowerPC 603R")
203 DEFINE_DEVICE_TYPE(PPC604,    ppc604_device,    "ppc604",     "IBM PowerPC 604")
204 DEFINE_DEVICE_TYPE(MPC8240,   mpc8240_device,   "mpc8240",    "IBM PowerPC MPC8240")
205 DEFINE_DEVICE_TYPE(PPC403GA,  ppc403ga_device,  "ppc403ga",   "IBM PowerPC 403GA")
206 DEFINE_DEVICE_TYPE(PPC403GCX, ppc403gcx_device, "ppc403gcx",  "IBM PowerPC 403GCX")
207 DEFINE_DEVICE_TYPE(PPC405GP,  ppc405gp_device,  "ppc405gp",   "IBM PowerPC 405GP")
208 
209 
ppc_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock,int address_bits,int data_bits,powerpc_flavor flavor,uint32_t cap,uint32_t tb_divisor,address_map_constructor internal_map)210 ppc_device::ppc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int address_bits, int data_bits, powerpc_flavor flavor, uint32_t cap, uint32_t tb_divisor, address_map_constructor internal_map)
211 	: cpu_device(mconfig, type, tag, owner, clock)
212 	, device_vtlb_interface(mconfig, *this, AS_PROGRAM)
213 	, m_program_config("program", ENDIANNESS_BIG, data_bits, address_bits, 0, internal_map)
214 	, c_bus_frequency(0)
215 	, m_core(nullptr)
216 	, m_bus_freq_multiplier(1)
217 	, m_flavor(flavor)
218 	, m_cap(cap)
219 	, m_tb_divisor(tb_divisor)
220 	, m_spu(*this)
221 	, m_dcr_read_func(*this)
222 	, m_dcr_write_func(*this)
223 	, m_dcstore_cb(*this)
224 	, m_ext_dma_read_cb(*this)
225 	, m_ext_dma_write_cb(*this)
226 	, m_cache(CACHE_SIZE + sizeof(internal_ppc_state))
227 	, m_drcuml(nullptr)
228 	, m_drcfe(nullptr)
229 	, m_drcoptions(0)
230 {
231 	m_program_config.m_logaddr_width = 32;
232 	m_program_config.m_page_shift = POWERPC_MIN_PAGE_SHIFT;
233 
234 	// configure the virtual TLB
235 	set_vtlb_dynamic_entries(POWERPC_TLB_ENTRIES);
236 	if (m_cap & PPCCAP_603_MMU)
237 		set_vtlb_fixed_entries(PPC603_FIXED_TLB_ENTRIES);
238 }
239 
~ppc_device()240 ppc_device::~ppc_device()
241 {
242 }
243 
244 //ppc403_device::ppc403_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
245 //  : ppc_device(mconfig, PPC403, "PPC403", tag, owner, clock, "ppc403", 32?, 64?)
246 //{
247 //}
248 //
249 //ppc405_device::ppc405_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
250 //  : ppc_device(mconfig, PPC405, "PPC405", tag, owner, clock, "ppc405", 32?, 64?)
251 //{
252 //}
253 
ppc603_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)254 ppc603_device::ppc603_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
255 	: ppc_device(mconfig, PPC603, tag, owner, clock, 32, 64, PPC_MODEL_603, PPCCAP_OEA | PPCCAP_VEA | PPCCAP_FPU | PPCCAP_MISALIGNED | PPCCAP_603_MMU, 4, address_map_constructor())
256 {
257 }
258 
ppc603e_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)259 ppc603e_device::ppc603e_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
260 	: ppc_device(mconfig, PPC603E, tag, owner, clock, 32, 64, PPC_MODEL_603E, PPCCAP_OEA | PPCCAP_VEA | PPCCAP_FPU | PPCCAP_MISALIGNED | PPCCAP_603_MMU, 4, address_map_constructor())
261 {
262 }
263 
ppc603r_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)264 ppc603r_device::ppc603r_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
265 	: ppc_device(mconfig, PPC603R, tag, owner, clock, 32, 64, PPC_MODEL_603R, PPCCAP_OEA | PPCCAP_VEA | PPCCAP_FPU | PPCCAP_MISALIGNED | PPCCAP_603_MMU, 4, address_map_constructor())
266 {
267 }
268 
ppc602_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)269 ppc602_device::ppc602_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
270 	: ppc_device(mconfig, PPC602, tag, owner, clock, 32, 64, PPC_MODEL_602, PPCCAP_OEA | PPCCAP_VEA | PPCCAP_FPU | PPCCAP_MISALIGNED | PPCCAP_603_MMU, 4, address_map_constructor())
271 {
272 }
273 
mpc8240_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)274 mpc8240_device::mpc8240_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
275 	: ppc_device(mconfig, MPC8240, tag, owner, clock, 32, 64, PPC_MODEL_MPC8240, PPCCAP_OEA | PPCCAP_VEA | PPCCAP_FPU | PPCCAP_MISALIGNED | PPCCAP_603_MMU, 4/* unknown */, address_map_constructor())
276 {
277 }
278 
ppc601_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)279 ppc601_device::ppc601_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
280 	: ppc_device(mconfig, PPC601, tag, owner, clock, 32, 64, PPC_MODEL_601, PPCCAP_OEA | PPCCAP_VEA | PPCCAP_FPU | PPCCAP_MISALIGNED | PPCCAP_MFIOC | PPCCAP_601BAT, 0/* no TB */, address_map_constructor())
281 {
282 }
283 
ppc604_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)284 ppc604_device::ppc604_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
285 	: ppc_device(mconfig, PPC604, tag, owner, clock, 32, 64, PPC_MODEL_604, PPCCAP_OEA | PPCCAP_VEA | PPCCAP_FPU | PPCCAP_MISALIGNED | PPCCAP_604_MMU, 4, address_map_constructor())
286 {
287 }
288 
internal_ppc4xx(address_map & map)289 void ppc4xx_device::internal_ppc4xx(address_map &map)
290 {
291 	map(0x40000000, 0x4000000f).rw(FUNC(ppc4xx_device::ppc4xx_spu_r), FUNC(ppc4xx_device::ppc4xx_spu_w));
292 }
293 
ppc4xx_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock,powerpc_flavor flavor,uint32_t cap,uint32_t tb_divisor)294 ppc4xx_device::ppc4xx_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, powerpc_flavor flavor, uint32_t cap, uint32_t tb_divisor)
295 	: ppc_device(mconfig, type, tag, owner, clock, 31, 32, flavor, cap, tb_divisor, address_map_constructor(FUNC(ppc4xx_device::internal_ppc4xx), this))
296 {
297 }
298 
ppc403ga_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)299 ppc403ga_device::ppc403ga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
300 	: ppc4xx_device(mconfig, PPC403GA, tag, owner, clock, PPC_MODEL_403GA, PPCCAP_4XX, 1)
301 {
302 }
303 
ppc403gcx_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)304 ppc403gcx_device::ppc403gcx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
305 	: ppc4xx_device(mconfig, PPC403GCX, tag, owner, clock, PPC_MODEL_403GCX, PPCCAP_4XX, 1)
306 {
307 }
308 
ppc405gp_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)309 ppc405gp_device::ppc405gp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
310 	: ppc4xx_device(mconfig, PPC405GP, tag, owner, clock, PPC_MODEL_405GP, PPCCAP_4XX | PPCCAP_VEA, 1)
311 {
312 }
313 
memory_space_config() const314 device_memory_interface::space_config_vector ppc_device::memory_space_config() const
315 {
316 	return space_config_vector {
317 		std::make_pair(AS_PROGRAM, &m_program_config)
318 	};
319 }
320 
321 
322 /***************************************************************************
323     INLINE FUNCTIONS
324 ***************************************************************************/
325 
326 /*-------------------------------------------------
327     page_access_allowed - return true if we are
328     allowed to access memory based on the type
329     of access and the protection bits
330 -------------------------------------------------*/
331 
page_access_allowed(int transtype,uint8_t key,uint8_t protbits)332 static inline bool page_access_allowed(int transtype, uint8_t key, uint8_t protbits)
333 {
334 	if (key == 0)
335 		return (transtype == TRANSLATE_WRITE) ? (protbits != 3) : true;
336 	else
337 		return (transtype == TRANSLATE_WRITE) ? (protbits == 2) : (protbits != 0);
338 }
339 
340 
341 /*-------------------------------------------------
342     get_cr - return the current CR value
343 -------------------------------------------------*/
344 
get_cr()345 inline uint32_t ppc_device::get_cr()
346 {
347 	return  ((m_core->cr[0] & 0x0f) << 28) |
348 			((m_core->cr[1] & 0x0f) << 24) |
349 			((m_core->cr[2] & 0x0f) << 20) |
350 			((m_core->cr[3] & 0x0f) << 16) |
351 			((m_core->cr[4] & 0x0f) << 12) |
352 			((m_core->cr[5] & 0x0f) << 8) |
353 			((m_core->cr[6] & 0x0f) << 4) |
354 			((m_core->cr[7] & 0x0f) << 0);
355 }
356 
357 
358 /*-------------------------------------------------
359     set_cr - set the current CR value
360 -------------------------------------------------*/
361 
set_cr(uint32_t value)362 inline void ppc_device::set_cr(uint32_t value)
363 {
364 	m_core->cr[0] = value >> 28;
365 	m_core->cr[1] = value >> 24;
366 	m_core->cr[2] = value >> 20;
367 	m_core->cr[3] = value >> 16;
368 	m_core->cr[4] = value >> 12;
369 	m_core->cr[5] = value >> 8;
370 	m_core->cr[6] = value >> 4;
371 	m_core->cr[7] = value >> 0;
372 }
373 
374 
375 /*-------------------------------------------------
376     get_xer - return the current XER value
377 -------------------------------------------------*/
378 
get_xer()379 inline uint32_t ppc_device::get_xer()
380 {
381 	return m_core->spr[SPR_XER] | (m_core->xerso << 31);
382 }
383 
384 
385 /*-------------------------------------------------
386     set_xer - set the current XER value
387 -------------------------------------------------*/
388 
set_xer(uint32_t value)389 inline void ppc_device::set_xer(uint32_t value)
390 {
391 	m_core->spr[SPR_XER] = value & ~XER_SO;
392 	m_core->xerso = value >> 31;
393 }
394 
395 
396 /*-------------------------------------------------
397     get_timebase - return the current timebase
398     value
399 -------------------------------------------------*/
400 
get_timebase()401 inline uint64_t ppc_device::get_timebase()
402 {
403 	if (!m_tb_divisor)
404 	{
405 		return (total_cycles() - m_tb_zero_cycles);
406 	}
407 
408 	return (total_cycles() - m_tb_zero_cycles) / m_tb_divisor;
409 }
410 
411 
412 /*-------------------------------------------------
413     set_timebase - set the timebase
414 -------------------------------------------------*/
415 
set_timebase(uint64_t newtb)416 inline void ppc_device::set_timebase(uint64_t newtb)
417 {
418 	m_tb_zero_cycles = total_cycles() - newtb * m_tb_divisor;
419 }
420 
421 
422 /*-------------------------------------------------
423     get_decremeter - return the current
424     decrementer value
425 -------------------------------------------------*/
426 
get_decrementer()427 inline uint32_t ppc_device::get_decrementer()
428 {
429 	int64_t cycles_until_zero = m_dec_zero_cycles - total_cycles();
430 	cycles_until_zero = std::max<int64_t>(cycles_until_zero, 0);
431 
432 	if (!m_tb_divisor)
433 	{
434 		return 0;
435 	}
436 
437 	return cycles_until_zero / m_tb_divisor;
438 }
439 
440 
441 /*-------------------------------------------------
442     set_decrementer - set the decremeter
443 -------------------------------------------------*/
444 
set_decrementer(uint32_t newdec)445 inline void ppc_device::set_decrementer(uint32_t newdec)
446 {
447 	uint64_t cycles_until_done = ((uint64_t)newdec + 1) * m_tb_divisor;
448 	uint32_t curdec = get_decrementer();
449 
450 	if (!m_tb_divisor)
451 	{
452 		return;
453 	}
454 
455 	if (PRINTF_DECREMENTER)
456 	{
457 		uint64_t total = total_cycles();
458 		osd_printf_debug("set_decrementer: olddec=%08X newdec=%08X divisor=%d totalcyc=%016X timer=%016X\n",
459 				curdec, newdec, m_tb_divisor,
460 				total, cycles_until_done);
461 	}
462 
463 	m_dec_zero_cycles = total_cycles() + cycles_until_done;
464 	m_decrementer_int_timer->adjust(cycles_to_attotime(cycles_until_done));
465 
466 	if ((int32_t)curdec >= 0 && (int32_t)newdec < 0)
467 		m_core->irq_pending |= 0x02;
468 }
469 
470 
471 #if 0
472 /*-------------------------------------------------
473     is_nan_double - is a double value a NaN
474 -------------------------------------------------*/
475 
476 static inline int is_nan_double(double x)
477 {
478 	uint64_t xi = *(uint64_t*)&x;
479 	return( ((xi & DOUBLE_EXP) == DOUBLE_EXP) &&
480 			((xi & DOUBLE_FRAC) != DOUBLE_ZERO) );
481 }
482 #endif
483 
484 
485 /*-------------------------------------------------
486     is_qnan_double - is a double value a
487     quiet NaN
488 -------------------------------------------------*/
489 
is_qnan_double(double x)490 static inline int is_qnan_double(double x)
491 {
492 	uint64_t xi = *(uint64_t*)&x;
493 	return( ((xi & DOUBLE_EXP) == DOUBLE_EXP) &&
494 			((xi & 0x0007fffffffffffU) == 0x000000000000000U) &&
495 			((xi & 0x000800000000000U) == 0x000800000000000U) );
496 }
497 
498 
499 #if 0
500 /*-------------------------------------------------
501     is_snan_double - is a double value a
502     signaling NaN
503 -------------------------------------------------*/
504 
505 static inline int is_snan_double(double x)
506 {
507 	uint64_t xi = *(uint64_t*)&x;
508 	return( ((xi & DOUBLE_EXP) == DOUBLE_EXP) &&
509 			((xi & DOUBLE_FRAC) != DOUBLE_ZERO) &&
510 			((xi & 0x0008000000000000U) == DOUBLE_ZERO) );
511 }
512 #endif
513 
514 
515 /*-------------------------------------------------
516     is_infinity_double - is a double value
517     infinity
518 -------------------------------------------------*/
519 
is_infinity_double(double x)520 static inline int is_infinity_double(double x)
521 {
522 	uint64_t xi = *(uint64_t*)&x;
523 	return( ((xi & DOUBLE_EXP) == DOUBLE_EXP) &&
524 			((xi & DOUBLE_FRAC) == DOUBLE_ZERO) );
525 }
526 
527 
528 /*-------------------------------------------------
529     is_normalized_double - is a double value
530     normalized
531 -------------------------------------------------*/
532 
is_normalized_double(double x)533 static inline int is_normalized_double(double x)
534 {
535 	uint64_t exp;
536 	uint64_t xi = *(uint64_t*)&x;
537 	exp = (xi & DOUBLE_EXP) >> 52;
538 
539 	return (exp >= 1) && (exp <= 2046);
540 }
541 
542 
543 /*-------------------------------------------------
544     is_denormalized_double - is a double value
545     denormalized
546 -------------------------------------------------*/
547 
is_denormalized_double(double x)548 static inline int is_denormalized_double(double x)
549 {
550 	uint64_t xi = *(uint64_t*)&x;
551 	return( ((xi & DOUBLE_EXP) == 0) &&
552 			((xi & DOUBLE_FRAC) != DOUBLE_ZERO) );
553 }
554 
555 
556 /*-------------------------------------------------
557     sign_double - return sign of a double value
558 -------------------------------------------------*/
559 
sign_double(double x)560 static inline int sign_double(double x)
561 {
562 	uint64_t xi = *(uint64_t*)&x;
563 	return ((xi & DOUBLE_SIGN) != 0);
564 }
565 
566 
567 
568 /***************************************************************************
569     INITIALIZATION AND SHUTDOWN
570 ***************************************************************************/
571 
572 /*-------------------------------------------------
573     device_start - initialize the powerpc_state
574     structure based on the configured type
575 -------------------------------------------------*/
576 
device_start()577 void ppc_device::device_start()
578 {
579 	/* allocate the core from the near cache */
580 	m_core = (internal_ppc_state *)m_cache.alloc_near(sizeof(internal_ppc_state));
581 	memset(m_core, 0, sizeof(internal_ppc_state));
582 
583 	m_entry = nullptr;
584 	m_nocode = nullptr;
585 	m_out_of_cycles = nullptr;
586 	m_tlb_mismatch = nullptr;
587 	m_swap_tgpr = nullptr;
588 	memset(m_lsw, 0, sizeof(m_lsw));
589 	memset(m_stsw, 0, sizeof(m_stsw));
590 	memset(m_read8, 0, sizeof(m_read8));
591 	memset(m_write8, 0, sizeof(m_write8));
592 	memset(m_read16, 0, sizeof(m_read16));
593 	memset(m_read16mask, 0, sizeof(m_read16mask));
594 	memset(m_write16, 0, sizeof(m_write16));
595 	memset(m_write16mask, 0, sizeof(m_write16mask));
596 	memset(m_read32, 0, sizeof(m_read32));
597 	memset(m_read32align, 0, sizeof(m_read32align));
598 	memset(m_read32mask, 0, sizeof(m_read32mask));
599 	memset(m_write32, 0, sizeof(m_write32));
600 	memset(m_write32align, 0, sizeof(m_write32align));
601 	memset(m_write32mask, 0, sizeof(m_write32mask));
602 	memset(m_read64, 0, sizeof(m_read64));
603 	memset(m_read64mask, 0, sizeof(m_read64mask));
604 	memset(m_write64, 0, sizeof(m_write64));
605 	memset(m_write64mask, 0, sizeof(m_write64mask));
606 	memset(m_exception, 0, sizeof(m_exception));
607 	memset(m_exception_norecover, 0, sizeof(m_exception_norecover));
608 
609 	/* initialize the implementation state tables */
610 	memcpy(m_fpmode, fpmode_source, sizeof(fpmode_source));
611 	memcpy(m_sz_cr_table, sz_cr_table_source, sizeof(sz_cr_table_source));
612 	memcpy(m_cmp_cr_table, cmp_cr_table_source, sizeof(cmp_cr_table_source));
613 	memcpy(m_cmpl_cr_table, cmpl_cr_table_source, sizeof(cmpl_cr_table_source));
614 	memcpy(m_fcmp_cr_table, fcmp_cr_table_source, sizeof(fcmp_cr_table_source));
615 
616 	/* initialize based on the config */
617 	m_ppc_tb_base_icount = 0;
618 	m_ppc_dec_base_icount = 0;
619 	m_ppc_dec_trigger_cycle = 0;
620 	m_bus_freq_multiplier = 0;
621 
622 	m_npc = 0;
623 	memset(m_dcr, 0, sizeof(m_dcr));
624 
625 	m_lr = 0;
626 	m_ctr = 0;
627 	m_xer = 0;
628 	m_pvr = 0;
629 	m_srr0 = 0;
630 	m_srr1 = 0;
631 	m_srr2 = 0;
632 	m_srr3 = 0;
633 	m_hid0 = 0;
634 	m_hid1 = 0;
635 	m_hid2 = 0;
636 	m_sdr1 = 0;
637 	memset(m_sprg, 0, sizeof(m_sprg));
638 
639 	m_dsisr = 0;
640 	m_dar = 0;
641 	m_ear = 0;
642 	m_dmiss = 0;
643 	m_dcmp = 0;
644 	m_hash1 = 0;
645 	m_hash2 = 0;
646 	m_imiss = 0;
647 	m_icmp = 0;
648 	m_rpa = 0;
649 
650 	memset(m_ibat, 0, sizeof(m_ibat));
651 	memset(m_dbat, 0, sizeof(m_dbat));
652 
653 	m_evpr = 0;
654 	m_exier = 0;
655 	m_exisr = 0;
656 	m_bear = 0;
657 	m_besr = 0;
658 	m_iocr = 0;
659 	memset(m_br, 0, sizeof(m_br));
660 	m_iabr = 0;
661 	m_esr = 0;
662 	m_iccr = 0;
663 	m_dccr = 0;
664 	m_pit = 0;
665 	m_pit_counter = 0;
666 	m_pit_int_enable = 0;
667 	m_tsr = 0;
668 	m_dbsr = 0;
669 	m_sgr = 0;
670 	m_pid = 0;
671 	m_pbl1 = 0;
672 	m_pbl2 = 0;
673 	m_pbu1 = 0;
674 	m_pbu2 = 0;
675 	m_fit_bit = 0;
676 	m_fit_int_enable = 0;
677 	m_wdt_bit = 0;
678 	m_wdt_int_enable = 0;
679 	m_dac1 = 0;
680 	m_dac2 = 0;
681 	m_iac1 = 0;
682 	m_iac2 = 0;
683 
684 	memset(&m_spu_old, 0, sizeof(m_spu_old));
685 	memset(m_dma, 0, sizeof(m_dma));
686 	m_dmasr = 0;
687 
688 	m_reserved = 0;
689 	m_reserved_address = 0;
690 	m_interrupt_pending = 0;
691 	m_tb = 0;
692 	m_dec = 0;
693 	m_dec_frac = 0;
694 	memset(m_fpr, 0, sizeof(m_fpr));
695 	m_lt = 0;
696 	m_sp = 0;
697 	m_tcr = 0;
698 	m_ibr = 0;
699 	m_esasrr = 0;
700 	m_sebr = 0;
701 	m_ser = 0;
702 
703 	memset(&m_spu, 0, sizeof(m_spu));
704 	m_pit_reload = 0;
705 	m_irqstate = 0;
706 	memset(m_buffered_dma_rate, 0, sizeof(m_buffered_dma_rate));
707 	m_system_clock = 0;
708 	m_cpu_clock = 0;
709 	m_tb_zero_cycles = 0;
710 	m_dec_zero_cycles = 0;
711 
712 	m_arg1 = 0;
713 	m_fastram_select = 0;
714 	memset(m_fastram, 0, sizeof(m_fastram));
715 	m_hotspot_select = 0;
716 	memset(m_hotspot, 0, sizeof(m_hotspot));
717 
718 	m_debugger_temp = 0;
719 
720 	m_cache_line_size = 32;
721 	m_cpu_clock = clock();
722 	m_program = &space(AS_PROGRAM);
723 	if(m_cap & PPCCAP_4XX)
724 	{
725 		m_program->cache(m_cache32);
726 		m_pr32 = [this](offs_t address) -> u32 { return m_cache32.read_dword(address); };
727 		m_prptr = [this](offs_t address) -> const void * { return m_cache32.read_ptr(address); };
728 	}
729 	else
730 	{
731 		m_program->cache(m_cache64);
732 		m_pr32 = [this](offs_t address) -> u32 { return m_cache64.read_dword(address); };
733 		if(space_config()->m_endianness != ENDIANNESS_NATIVE)
734 			m_prptr = [this](offs_t address) -> const void * {
735 				const u32 *ptr = static_cast<u32 *>(m_cache64.read_ptr(address & ~7));
736 				if(!(address & 4))
737 					ptr++;
738 				return ptr;
739 			};
740 		else
741 			m_prptr = [this](offs_t address) -> const void * {
742 				const u32 *ptr = static_cast<u32 *>(m_cache64.read_ptr(address & ~7));
743 				if(address & 4)
744 					ptr++;
745 				return ptr;
746 			};
747 	}
748 	m_system_clock = c_bus_frequency != 0 ? c_bus_frequency : clock();
749 	m_dcr_read_func.set(nullptr);
750 	m_dcr_write_func.set(nullptr);
751 
752 	m_tb_divisor = (m_tb_divisor * clock() + m_system_clock / 2 - 1) / m_system_clock;
753 
754 	/* allocate a timer for the compare interrupt */
755 	if ((m_cap & PPCCAP_OEA) && (m_tb_divisor))
756 		m_decrementer_int_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ppc_device::decrementer_int_callback), this));
757 
758 	/* and for the 4XX interrupts if needed */
759 	if (m_cap & PPCCAP_4XX)
760 	{
761 		m_fit_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ppc_device::ppc4xx_fit_callback), this));
762 		m_pit_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ppc_device::ppc4xx_pit_callback), this));
763 		m_spu.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ppc_device::ppc4xx_spu_callback), this));
764 	}
765 
766 	if (m_cap & PPCCAP_4XX)
767 	{
768 		m_buffered_dma_timer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ppc_device::ppc4xx_buffered_dma_callback), this));
769 		m_buffered_dma_timer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ppc_device::ppc4xx_buffered_dma_callback), this));
770 		m_buffered_dma_timer[2] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ppc_device::ppc4xx_buffered_dma_callback), this));
771 		m_buffered_dma_timer[3] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ppc_device::ppc4xx_buffered_dma_callback), this));
772 
773 		m_buffered_dma_rate[0] = 10000;
774 		m_buffered_dma_rate[1] = 10000;
775 		m_buffered_dma_rate[2] = 10000;
776 		m_buffered_dma_rate[3] = 10000;
777 	}
778 
779 	/* register for save states */
780 	save_item(NAME(m_core->pc));
781 	save_item(NAME(m_core->r));
782 	save_item(NAME(m_core->f));
783 	save_item(NAME(m_core->cr));
784 	save_item(NAME(m_core->xerso));
785 	save_item(NAME(m_core->fpscr));
786 	save_item(NAME(m_core->msr));
787 	save_item(NAME(m_core->sr));
788 	save_item(NAME(m_core->spr));
789 	save_item(NAME(m_dcr));
790 	if (m_cap & PPCCAP_4XX)
791 	{
792 		save_item(NAME(m_spu.regs));
793 		save_item(NAME(m_spu.txbuf));
794 		save_item(NAME(m_spu.rxbuf));
795 		save_item(NAME(m_spu.rxbuffer));
796 		save_item(NAME(m_spu.rxin));
797 		save_item(NAME(m_spu.rxout));
798 		save_item(NAME(m_pit_reload));
799 		save_item(NAME(m_irqstate));
800 	}
801 	if (m_cap & PPCCAP_603_MMU)
802 	{
803 		save_item(NAME(m_core->mmu603_cmp));
804 		save_item(NAME(m_core->mmu603_hash));
805 		save_item(NAME(m_core->mmu603_r));
806 	}
807 	save_item(NAME(m_core->irq_pending));
808 	save_item(NAME(m_tb_zero_cycles));
809 	save_item(NAME(m_dec_zero_cycles));
810 
811 	// Register debugger state
812 	state_add(PPC_PC,    "PC", m_core->pc).formatstr("%08X");
813 	state_add(PPC_MSR,   "MSR", m_core->msr).formatstr("%08X");
814 	state_add(PPC_CR,    "CR", m_debugger_temp).callimport().callexport().formatstr("%08X");
815 	state_add(PPC_LR,    "LR", m_core->spr[SPR_LR]).formatstr("%08X");
816 	state_add(PPC_CTR,   "CTR", m_core->spr[SPR_CTR]).formatstr("%08X");
817 	state_add(PPC_XER,   "XER", m_debugger_temp).callimport().callexport().formatstr("%08X");
818 	state_add(PPC_SRR0,  "SRR0", m_core->spr[SPROEA_SRR0]).formatstr("%08X");
819 	state_add(PPC_SRR1,  "SRR1", m_core->spr[SPROEA_SRR1]).formatstr("%08X");
820 	state_add(PPC_SPRG0, "SPRG0", m_core->spr[SPROEA_SPRG0]).formatstr("%08X");
821 	state_add(PPC_SPRG1, "SPRG1", m_core->spr[SPROEA_SPRG1]).formatstr("%08X");
822 	state_add(PPC_SPRG2, "SPRG2", m_core->spr[SPROEA_SPRG2]).formatstr("%08X");
823 	state_add(PPC_SPRG3, "SPRG3", m_core->spr[SPROEA_SPRG3]).formatstr("%08X");
824 	state_add(PPC_SDR1,  "SDR1", m_core->spr[SPROEA_SDR1]).formatstr("%08X");
825 	state_add(PPC_EXIER, "EXIER", m_dcr[DCR4XX_EXIER]).formatstr("%08X");
826 	state_add(PPC_EXISR, "EXISR", m_dcr[DCR4XX_EXISR]).formatstr("%08X");
827 	state_add(PPC_EVPR,  "EVPR", m_core->spr[SPR4XX_EVPR]).formatstr("%08X");
828 	state_add(PPC_IOCR,  "IOCR", m_dcr[DCR4XX_EXISR]).formatstr("%08X");
829 	state_add(PPC_TBH,   "TBH", m_debugger_temp).callimport().callexport().formatstr("%08X");
830 	state_add(PPC_TBL,   "TBL", m_debugger_temp).callimport().callexport().formatstr("%08X");
831 	state_add(PPC_DEC,   "DEC", m_debugger_temp).callimport().callexport().formatstr("%08X");
832 
833 	for (int regnum = 0; regnum < 16; regnum++)
834 		state_add(PPC_SR0 + regnum, string_format("SR%d", regnum).c_str(), m_core->sr[regnum]).formatstr("%08X");
835 
836 	for (int regnum = 0; regnum < 32; regnum++)
837 		state_add(PPC_R0 + regnum, string_format("R%d", regnum).c_str(), m_core->r[regnum]).formatstr("%08X");
838 
839 	for (int regnum = 0; regnum < 32; regnum++)
840 		state_add(PPC_F0 + regnum, string_format("F%d", regnum).c_str(), m_core->f[regnum]).formatstr("%12s");
841 	state_add(PPC_FPSCR, "FPSCR", m_core->fpscr).formatstr("%08X");
842 
843 	state_add(STATE_GENPC, "GENPC", m_core->pc).noshow();
844 	state_add(STATE_GENPCBASE, "CURPC", m_core->pc).noshow();
845 	state_add(STATE_GENSP, "GENSP", m_core->r[31]).noshow();
846 	state_add(STATE_GENFLAGS, "GENFLAGS", m_debugger_temp).noshow().formatstr("%1s");
847 
848 	set_icountptr(m_core->icount);
849 
850 	uint32_t flags = 0;
851 	/* initialize the UML generator */
852 	m_drcuml = std::make_unique<drcuml_state>(*this, m_cache, flags, 8, 32, 2);
853 
854 	/* add symbols for our stuff */
855 	m_drcuml->symbol_add(&m_core->pc, sizeof(m_core->pc), "pc");
856 	m_drcuml->symbol_add(&m_core->icount, sizeof(m_core->icount), "icount");
857 	for (int regnum = 0; regnum < 32; regnum++)
858 	{
859 		char buf[10];
860 		sprintf(buf, "r%d", regnum);
861 		m_drcuml->symbol_add(&m_core->r[regnum], sizeof(m_core->r[regnum]), buf);
862 		sprintf(buf, "fpr%d", regnum);
863 		m_drcuml->symbol_add(&m_core->f[regnum], sizeof(m_core->f[regnum]), buf);
864 	}
865 	for (int regnum = 0; regnum < 8; regnum++)
866 	{
867 		char buf[10];
868 		sprintf(buf, "cr%d", regnum);
869 		m_drcuml->symbol_add(&m_core->cr[regnum], sizeof(m_core->cr[regnum]), buf);
870 	}
871 	m_drcuml->symbol_add(&m_core->xerso, sizeof(m_core->xerso), "xerso");
872 	m_drcuml->symbol_add(&m_core->fpscr, sizeof(m_core->fpscr), "fpscr");
873 	m_drcuml->symbol_add(&m_core->msr, sizeof(m_core->msr), "msr");
874 	m_drcuml->symbol_add(&m_core->sr, sizeof(m_core->sr), "sr");
875 	m_drcuml->symbol_add(&m_core->spr[SPR_XER], sizeof(m_core->spr[SPR_XER]), "xer");
876 	m_drcuml->symbol_add(&m_core->spr[SPR_LR], sizeof(m_core->spr[SPR_LR]), "lr");
877 	m_drcuml->symbol_add(&m_core->spr[SPR_CTR], sizeof(m_core->spr[SPR_CTR]), "ctr");
878 	m_drcuml->symbol_add(&m_core->spr, sizeof(m_core->spr), "spr");
879 	m_drcuml->symbol_add(&m_dcr, sizeof(m_dcr), "dcr");
880 	m_drcuml->symbol_add(&m_core->param0, sizeof(m_core->param0), "param0");
881 	m_drcuml->symbol_add(&m_core->param1, sizeof(m_core->param1), "param1");
882 	m_drcuml->symbol_add(&m_core->irq_pending, sizeof(m_core->irq_pending), "irq_pending");
883 	m_drcuml->symbol_add(&m_core->mode, sizeof(m_core->mode), "mode");
884 	m_drcuml->symbol_add(&m_core->arg0, sizeof(m_core->arg0), "arg0");
885 	m_drcuml->symbol_add(&m_arg1, sizeof(m_arg1), "arg1");
886 	m_drcuml->symbol_add(&m_core->updateaddr, sizeof(m_core->updateaddr), "updateaddr");
887 	m_drcuml->symbol_add(&m_core->swcount, sizeof(m_core->swcount), "swcount");
888 	m_drcuml->symbol_add(&m_core->tempaddr, sizeof(m_core->tempaddr), "tempaddr");
889 	m_drcuml->symbol_add(&m_core->tempdata, sizeof(m_core->tempdata), "tempdata");
890 	m_drcuml->symbol_add(&m_core->fp0, sizeof(m_core->fp0), "fp0");
891 	m_drcuml->symbol_add(&m_fpmode, sizeof(m_fpmode), "fpmode");
892 	m_drcuml->symbol_add(&m_sz_cr_table, sizeof(m_sz_cr_table), "sz_cr_table");
893 	m_drcuml->symbol_add(&m_cmp_cr_table, sizeof(m_cmp_cr_table), "cmp_cr_table");
894 	m_drcuml->symbol_add(&m_cmpl_cr_table, sizeof(m_cmpl_cr_table), "cmpl_cr_table");
895 	m_drcuml->symbol_add(&m_fcmp_cr_table, sizeof(m_fcmp_cr_table), "fcmp_cr_table");
896 
897 	/* initialize the front-end helper */
898 	m_drcfe = std::make_unique<frontend>(*this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE);
899 
900 	/* compute the register parameters */
901 	for (int regnum = 0; regnum < 32; regnum++)
902 	{
903 		m_regmap[regnum] = uml::mem(&m_core->r[regnum]);
904 		m_fdregmap[regnum] = uml::mem(&m_core->f[regnum]);
905 	}
906 
907 	/* if we have registers to spare, assign r0, r1, r2 to leftovers */
908 	if (!DISABLE_FAST_REGISTERS)
909 	{
910 		drcbe_info beinfo;
911 		m_drcuml->get_backend_info(beinfo);
912 		if (beinfo.direct_iregs > 5)
913 			m_regmap[0] = uml::I5;
914 		if (beinfo.direct_iregs > 6)
915 			m_regmap[1] = uml::I6;
916 		if (beinfo.direct_iregs > 7)
917 			m_regmap[2] = uml::I7;
918 
919 
920 		if (beinfo.direct_fregs > 3)
921 			m_fdregmap[0] = uml::F3;
922 		if (beinfo.direct_fregs > 4)
923 			m_fdregmap[1] = uml::F4;
924 		if (beinfo.direct_fregs > 5)
925 			m_fdregmap[2] = uml::F5;
926 		if (beinfo.direct_fregs > 6)
927 			m_fdregmap[3] = uml::F6;
928 		if (beinfo.direct_fregs > 7)
929 			m_fdregmap[30] = uml::F7;
930 		if (beinfo.direct_fregs > 8)
931 			m_fdregmap[31] = uml::F8;
932 	}
933 
934 	/* mark the cache dirty so it is updated on next execute */
935 	m_cache_dirty = true;
936 }
937 
state_export(const device_state_entry & entry)938 void ppc_device::state_export(const device_state_entry &entry)
939 {
940 	switch (entry.index())
941 	{
942 		case PPC_CR:
943 			m_debugger_temp = get_cr();
944 			break;
945 
946 		case PPC_XER:
947 			m_debugger_temp = get_xer();
948 			break;
949 
950 		case PPC_TBH:
951 			m_debugger_temp = get_timebase() >> 32;
952 			break;
953 
954 		case PPC_TBL:
955 			m_debugger_temp = (uint32_t)get_timebase();
956 			break;
957 
958 		case PPC_DEC:
959 			m_debugger_temp = get_decrementer();
960 			break;
961 	}
962 }
963 
state_import(const device_state_entry & entry)964 void ppc_device::state_import(const device_state_entry &entry)
965 {
966 	switch (entry.index())
967 	{
968 		case PPC_CR:
969 			set_cr(m_debugger_temp);
970 			break;
971 
972 		case PPC_XER:
973 			set_xer(m_debugger_temp);
974 			break;
975 
976 		case PPC_TBL:
977 			set_timebase((get_timebase() & ~u64(0x00ffffff00000000U)) | m_debugger_temp);
978 			break;
979 
980 		case PPC_TBH:
981 			set_timebase((get_timebase() & ~u64(0x00000000ffffffffU)) | ((uint64_t)(m_debugger_temp & 0x00ffffff) << 32));
982 			break;
983 
984 		case PPC_DEC:
985 			set_decrementer(m_debugger_temp);
986 			break;
987 	}
988 }
989 
990 
state_string_export(const device_state_entry & entry,std::string & str) const991 void ppc_device::state_string_export(const device_state_entry &entry, std::string &str) const
992 {
993 	switch (entry.index())
994 	{
995 		case PPC_F0:
996 			str = string_format("%12f", m_core->f[0]);
997 			break;
998 
999 		case PPC_F1:
1000 			str = string_format("%12f", m_core->f[1]);
1001 			break;
1002 
1003 		case PPC_F2:
1004 			str = string_format("%12f", m_core->f[2]);
1005 			break;
1006 
1007 		case PPC_F3:
1008 			str = string_format("%12f", m_core->f[3]);
1009 			break;
1010 
1011 		case PPC_F4:
1012 			str = string_format("%12f", m_core->f[4]);
1013 			break;
1014 
1015 		case PPC_F5:
1016 			str = string_format("%12f", m_core->f[5]);
1017 			break;
1018 
1019 		case PPC_F6:
1020 			str = string_format("%12f", m_core->f[6]);
1021 			break;
1022 
1023 		case PPC_F7:
1024 			str = string_format("%12f", m_core->f[7]);
1025 			break;
1026 
1027 		case PPC_F8:
1028 			str = string_format("%12f", m_core->f[8]);
1029 			break;
1030 
1031 		case PPC_F9:
1032 			str = string_format("%12f", m_core->f[9]);
1033 			break;
1034 
1035 		case PPC_F10:
1036 			str = string_format("%12f", m_core->f[10]);
1037 			break;
1038 
1039 		case PPC_F11:
1040 			str = string_format("%12f", m_core->f[11]);
1041 			break;
1042 
1043 		case PPC_F12:
1044 			str = string_format("%12f", m_core->f[12]);
1045 			break;
1046 
1047 		case PPC_F13:
1048 			str = string_format("%12f", m_core->f[13]);
1049 			break;
1050 
1051 		case PPC_F14:
1052 			str = string_format("%12f", m_core->f[14]);
1053 			break;
1054 
1055 		case PPC_F15:
1056 			str = string_format("%12f", m_core->f[15]);
1057 			break;
1058 
1059 		case PPC_F16:
1060 			str = string_format("%12f", m_core->f[16]);
1061 			break;
1062 
1063 		case PPC_F17:
1064 			str = string_format("%12f", m_core->f[17]);
1065 			break;
1066 
1067 		case PPC_F18:
1068 			str = string_format("%12f", m_core->f[18]);
1069 			break;
1070 
1071 		case PPC_F19:
1072 			str = string_format("%12f", m_core->f[19]);
1073 			break;
1074 
1075 		case PPC_F20:
1076 			str = string_format("%12f", m_core->f[20]);
1077 			break;
1078 
1079 		case PPC_F21:
1080 			str = string_format("%12f", m_core->f[21]);
1081 			break;
1082 
1083 		case PPC_F22:
1084 			str = string_format("%12f", m_core->f[22]);
1085 			break;
1086 
1087 		case PPC_F23:
1088 			str = string_format("%12f", m_core->f[23]);
1089 			break;
1090 
1091 		case PPC_F24:
1092 			str = string_format("%12f", m_core->f[24]);
1093 			break;
1094 
1095 		case PPC_F25:
1096 			str = string_format("%12f", m_core->f[25]);
1097 			break;
1098 
1099 		case PPC_F26:
1100 			str = string_format("%12f", m_core->f[26]);
1101 			break;
1102 
1103 		case PPC_F27:
1104 			str = string_format("%12f", m_core->f[27]);
1105 			break;
1106 
1107 		case PPC_F28:
1108 			str = string_format("%12f", m_core->f[28]);
1109 			break;
1110 
1111 		case PPC_F29:
1112 			str = string_format("%12f", m_core->f[29]);
1113 			break;
1114 
1115 		case PPC_F30:
1116 			str = string_format("%12f", m_core->f[30]);
1117 			break;
1118 
1119 		case PPC_F31:
1120 			str = string_format("%12f", m_core->f[31]);
1121 			break;
1122 	}
1123 }
1124 
1125 
1126 /*-------------------------------------------------
1127     ppccom_exit - common cleanup/exit
1128 -------------------------------------------------*/
1129 
device_stop()1130 void ppc_device::device_stop()
1131 {
1132 }
1133 
1134 
1135 /*-------------------------------------------------
1136     ppccom_reset - reset the state of all the
1137     registers
1138 -------------------------------------------------*/
1139 
device_reset()1140 void ppc_device::device_reset()
1141 {
1142 	/* initialize the OEA state */
1143 	if (m_cap & PPCCAP_OEA)
1144 	{
1145 		/* PC to the reset vector; MSR has IP set to start */
1146 		m_core->pc = 0xfff00100;
1147 		m_core->msr = MSROEA_IP;
1148 
1149 		/* reset the decrementer */
1150 		m_dec_zero_cycles = total_cycles();
1151 		if (m_tb_divisor)
1152 		{
1153 			decrementer_int_callback(nullptr, 0);
1154 		}
1155 	}
1156 
1157 	/* initialize the 4XX state */
1158 	if (m_cap & PPCCAP_4XX)
1159 	{
1160 		/* PC to the last word; MSR to 0 */
1161 		m_core->pc = 0xfffffffc;
1162 		m_core->msr = 0;
1163 
1164 		/* reset the SPU status */
1165 		m_core->spr[SPR4XX_TCR] &= ~PPC4XX_TCR_WRC_MASK;
1166 		m_spu.regs[SPU4XX_LINE_STATUS] = 0x06;
1167 	}
1168 
1169 	/* initialize the 602 HID0 register */
1170 	if (m_flavor == PPC_MODEL_602)
1171 	{
1172 		m_core->spr[SPR602_ESASRR] = 0;
1173 		m_core->spr[SPR603_HID0] = 1;
1174 	}
1175 
1176 	/* time base starts here */
1177 	m_tb_zero_cycles = total_cycles();
1178 
1179 	/* clear interrupts */
1180 	m_core->irq_pending = 0;
1181 
1182 	/* flush the TLB */
1183 	if (m_cap & PPCCAP_603_MMU)
1184 	{
1185 		for (int tlbindex = 0; tlbindex < PPC603_FIXED_TLB_ENTRIES; tlbindex++)
1186 		{
1187 			vtlb_load(tlbindex, 0, 0, 0);
1188 		}
1189 	}
1190 
1191 	/* Mark the cache dirty */
1192 	m_core->mode = 0;
1193 	m_cache_dirty = true;
1194 }
1195 
1196 
1197 /*-------------------------------------------------
1198     ppccom_dasm - handle disassembly for a
1199     CPU
1200 -------------------------------------------------*/
1201 
create_disassembler()1202 std::unique_ptr<util::disasm_interface> ppc_device::create_disassembler()
1203 {
1204 	return std::make_unique<powerpc_disassembler>();
1205 }
1206 
1207 
1208 /*-------------------------------------------------
1209     ppccom_dcstore_callback - call the dcstore
1210     callback if installed
1211 -------------------------------------------------*/
1212 
ppccom_dcstore_callback()1213 void ppc_device::ppccom_dcstore_callback()
1214 {
1215 	if (!m_dcstore_cb.isnull())
1216 	{
1217 		m_dcstore_cb(m_core->param0, 0);
1218 	}
1219 }
1220 
1221 
1222 /***************************************************************************
1223     TLB HANDLING
1224 ***************************************************************************/
1225 
1226 /*-------------------------------------------------
1227     ppccom_translate_address_internal - translate
1228     an address from logical to physical; shared
1229     between external requests and internal TLB
1230     filling
1231 -------------------------------------------------*/
1232 
ppccom_translate_address_internal(int intention,offs_t & address)1233 uint32_t ppc_device::ppccom_translate_address_internal(int intention, offs_t &address)
1234 {
1235 	int transpriv = ((intention & TRANSLATE_USER_MASK) == 0);   // 1 for supervisor, 0 for user
1236 	int transtype = intention & TRANSLATE_TYPE_MASK;
1237 	offs_t hash, hashbase, hashmask;
1238 	int batbase, batnum, hashnum;
1239 	uint32_t segreg;
1240 
1241 	/* 4xx case: "TLB" really just caches writes and checks compare registers */
1242 	if (m_cap & PPCCAP_4XX)
1243 	{
1244 		/* we don't support the MMU of the 403GCX */
1245 		if (m_flavor == PPC_MODEL_403GCX && (m_core->msr & MSROEA_DR))
1246 			fatalerror("MMU enabled but not supported!\n");
1247 
1248 		/* only check if PE is enabled */
1249 		if (transtype == TRANSLATE_WRITE && (m_core->msr & MSR4XX_PE))
1250 		{
1251 			/* are we within one of the protection ranges? */
1252 			int inrange1 = ((address >> 12) >= (m_core->spr[SPR4XX_PBL1] >> 12) && (address >> 12) < (m_core->spr[SPR4XX_PBU1] >> 12));
1253 			int inrange2 = ((address >> 12) >= (m_core->spr[SPR4XX_PBL2] >> 12) && (address >> 12) < (m_core->spr[SPR4XX_PBU2] >> 12));
1254 
1255 			/* if PX == 1, writes are only allowed OUTSIDE of the bounds */
1256 			if (((m_core->msr & MSR4XX_PX) && (inrange1 || inrange2)) || (!(m_core->msr & MSR4XX_PX) && (!inrange1 && !inrange2)))
1257 				return 0x002;
1258 		}
1259 		address &= 0x7fffffff;
1260 		return 0x001;
1261 	}
1262 
1263 	/* only applies if we support the OEA */
1264 	if (!(m_cap & PPCCAP_OEA))
1265 		return 0x001;
1266 
1267 	/* also no translation necessary if translation is disabled */
1268 	if ((transtype == TRANSLATE_FETCH && (m_core->msr & MSROEA_IR) == 0) || (transtype != TRANSLATE_FETCH && (m_core->msr & MSROEA_DR) == 0))
1269 		return 0x001;
1270 
1271 	/* first scan the appropriate BAT */
1272 	if (m_cap & PPCCAP_601BAT)
1273 	{
1274 		for (batnum = 0; batnum < 4; batnum++)
1275 		{
1276 			uint32_t upper = m_core->spr[SPROEA_IBAT0U + 2*batnum + 0];
1277 			uint32_t lower = m_core->spr[SPROEA_IBAT0U + 2*batnum + 1];
1278 			int privbit = ((intention & TRANSLATE_USER_MASK) == 0) ? 3 : 2;
1279 
1280 //            printf("bat %d upper = %08x privbit %d\n", batnum, upper, privbit);
1281 
1282 			// is this pair valid?
1283 			if (lower & 0x40)
1284 			{
1285 				uint32_t mask = ((lower & 0x3f) << 17) ^ 0xfffe0000;
1286 				uint32_t addrout;
1287 				uint32_t key = (upper >> privbit) & 1;
1288 
1289 				/* check for a hit against this bucket */
1290 				if ((address & mask) == (upper & mask))
1291 				{
1292 					/* verify protection; if we fail, return false and indicate a protection violation */
1293 					if (!page_access_allowed(transtype, key, upper & 3))
1294 					{
1295 						return DSISR_PROTECTED | ((transtype == TRANSLATE_WRITE) ? DSISR_STORE : 0);
1296 					}
1297 
1298 					/* otherwise we're good */
1299 					addrout = (lower & mask) | (address & ~mask);
1300 					address = addrout; // top 9 bits from top 9 of PBN
1301 					return 0x001;
1302 				}
1303 			}
1304 		}
1305 	}
1306 	else
1307 	{
1308 		batbase = (transtype == TRANSLATE_FETCH) ? SPROEA_IBAT0U : SPROEA_DBAT0U;
1309 
1310 		for (batnum = 0; batnum < 4; batnum++)
1311 		{
1312 			uint32_t upper = m_core->spr[batbase + 2*batnum + 0];
1313 
1314 			/* check user/supervisor valid bit */
1315 			if ((upper >> transpriv) & 0x01)
1316 			{
1317 				uint32_t mask = (~upper << 15) & 0xfffe0000;
1318 
1319 				/* check for a hit against this bucket */
1320 				if ((address & mask) == (upper & mask))
1321 				{
1322 					uint32_t lower = m_core->spr[batbase + 2*batnum + 1];
1323 
1324 					/* verify protection; if we fail, return false and indicate a protection violation */
1325 					if (!page_access_allowed(transtype, 1, lower & 3))
1326 					{
1327 						return DSISR_PROTECTED | ((transtype == TRANSLATE_WRITE) ? DSISR_STORE : 0);
1328 					}
1329 
1330 					/* otherwise we're good */
1331 					address = (lower & mask) | (address & ~mask);
1332 					return 0x001;
1333 				}
1334 			}
1335 		}
1336 	}
1337 
1338 #if 1
1339 	/* 602-specific Protection-Only mode */
1340 	if (m_flavor == PPC_MODEL_602 && m_core->spr[SPR603_HID0] & 0x00000080)
1341 	{
1342 		// TODO
1343 		return 0x001;
1344 	}
1345 #endif
1346 
1347 	/* look up the segment register */
1348 	segreg = m_core->sr[address >> 28];
1349 	if (transtype == TRANSLATE_FETCH && (segreg & 0x10000000))
1350 		return DSISR_PROTECTED | ((transtype == TRANSLATE_WRITE) ? DSISR_STORE : 0);
1351 
1352 	/* check for memory-forced I/O */
1353 	if (m_cap & PPCCAP_MFIOC)
1354 	{
1355 		if ((transtype != TRANSLATE_FETCH) && ((segreg & 0x87f00000) == 0x87f00000))
1356 		{
1357 			address = ((segreg & 0xf)<<28) | (address & 0x0fffffff);
1358 			return 1;
1359 		}
1360 		else if (segreg & 0x80000000)
1361 		{
1362 			fatalerror("PPC: Unhandled segment register %08x with T=1\n", segreg);
1363 		}
1364 	}
1365 
1366 	/* get hash table information from SD1 */
1367 	hashbase = m_core->spr[SPROEA_SDR1] & 0xffff0000;
1368 	hashmask = ((m_core->spr[SPROEA_SDR1] & 0x1ff) << 16) | 0xffff;
1369 	hash = (segreg & 0x7ffff) ^ ((address >> 12) & 0xffff);
1370 
1371 	/* if we're simulating the 603 MMU, fill in the data and stop here */
1372 	if (m_cap & PPCCAP_603_MMU)
1373 	{
1374 		uint32_t entry = vtlb_table()[address >> 12];
1375 		m_core->mmu603_cmp = 0x80000000 | ((segreg & 0xffffff) << 7) | (0 << 6) | ((address >> 22) & 0x3f);
1376 		m_core->mmu603_hash[0] = hashbase | ((hash << 6) & hashmask);
1377 		m_core->mmu603_hash[1] = hashbase | ((~hash << 6) & hashmask);
1378 		if ((entry & (VTLB_FLAG_FIXED | VTLB_FLAG_VALID)) == (VTLB_FLAG_FIXED | VTLB_FLAG_VALID))
1379 		{
1380 			address = (entry & 0xfffff000) | (address & 0x00000fff);
1381 			return 0x001;
1382 		}
1383 		return DSISR_NOT_FOUND | ((transtype == TRANSLATE_WRITE) ? DSISR_STORE : 0);
1384 	}
1385 
1386 	/* loop twice over hashes */
1387 	for (hashnum = 0; hashnum < 2; hashnum++)
1388 	{
1389 		offs_t ptegaddr = hashbase | ((hash << 6) & hashmask);
1390 		uint32_t *ptegptr = (uint32_t *)m_program->get_read_ptr(ptegaddr);
1391 
1392 		/* should only have valid memory here, but make sure */
1393 		if (ptegptr != nullptr)
1394 		{
1395 			uint32_t targetupper = 0x80000000 | ((segreg & 0xffffff) << 7) | (hashnum << 6) | ((address >> 22) & 0x3f);
1396 			int ptenum;
1397 
1398 			/* scan PTEs */
1399 			for (ptenum = 0; ptenum < 8; ptenum++)
1400 				if (ptegptr[BYTE_XOR_BE(ptenum * 2)] == targetupper)
1401 				{
1402 					uint32_t pteglower = ptegptr[BYTE_XOR_BE(ptenum * 2 + 1)];
1403 
1404 					/* verify protection; if we fail, return false and indicate a protection violation */
1405 					if (!page_access_allowed(transtype, (segreg >> (29 + transpriv)) & 1, pteglower & 3))
1406 						return DSISR_PROTECTED | ((transtype == TRANSLATE_WRITE) ? DSISR_STORE : 0);
1407 
1408 					/* update page table bits */
1409 					if (!(intention & TRANSLATE_DEBUG_MASK))
1410 					{
1411 						pteglower |= 0x100;
1412 						if (transtype == TRANSLATE_WRITE)
1413 							pteglower |= 0x080;
1414 						ptegptr[BYTE_XOR_BE(ptenum * 2 + 1)] = pteglower;
1415 					}
1416 
1417 					/* otherwise we're good */
1418 					address = (pteglower & 0xfffff000) | (address & 0x00000fff);
1419 					return (pteglower >> 7) & 1;
1420 				}
1421 		}
1422 
1423 		/* invert the hash after the first round */
1424 		hash = ~hash;
1425 	}
1426 
1427 	/* we failed to find any match: not found */
1428 	return DSISR_NOT_FOUND | ((transtype == TRANSLATE_WRITE) ? DSISR_STORE : 0);
1429 }
1430 
1431 
1432 /*-------------------------------------------------
1433     ppccom_translate_address - translate an address
1434     from logical to physical
1435 -------------------------------------------------*/
1436 
memory_translate(int spacenum,int intention,offs_t & address)1437 bool ppc_device::memory_translate(int spacenum, int intention, offs_t &address)
1438 {
1439 	/* only applies to the program address space */
1440 	if (spacenum != AS_PROGRAM)
1441 		return true;
1442 
1443 	/* translation is successful if the internal routine returns 0 or 1 */
1444 	return (ppccom_translate_address_internal(intention, address) <= 1);
1445 }
1446 
1447 
1448 /*-------------------------------------------------
1449     ppccom_tlb_fill - handle a missing TLB entry
1450 -------------------------------------------------*/
1451 
ppccom_tlb_fill()1452 void ppc_device::ppccom_tlb_fill()
1453 {
1454 	vtlb_fill(m_core->param0, m_core->param1);
1455 }
1456 
1457 
1458 /*-------------------------------------------------
1459     ppccom_tlb_flush - flush the entire TLB,
1460     including fixed entries
1461 -------------------------------------------------*/
1462 
ppccom_tlb_flush()1463 void ppc_device::ppccom_tlb_flush()
1464 {
1465 	vtlb_flush_dynamic();
1466 }
1467 
1468 
1469 
1470 /***************************************************************************
1471     OPCODE HANDLING
1472 ***************************************************************************/
1473 
1474 /*-------------------------------------------------
1475     ppccom_get_dsisr - gets the DSISR value for a
1476     failing TLB lookup's data access exception.
1477 -------------------------------------------------*/
1478 
ppccom_get_dsisr()1479 void ppc_device::ppccom_get_dsisr()
1480 {
1481 	int intent = 0;
1482 
1483 	if (m_core->param1 & 1)
1484 	{
1485 		intent = TRANSLATE_WRITE;
1486 	}
1487 	else
1488 	{
1489 		intent = TRANSLATE_READ;
1490 	}
1491 
1492 	m_core->param1 = ppccom_translate_address_internal(intent, m_core->param0);
1493 }
1494 
1495 /*-------------------------------------------------
1496     ppccom_execute_tlbie - execute a TLBIE
1497     instruction
1498 -------------------------------------------------*/
1499 
ppccom_execute_tlbie()1500 void ppc_device::ppccom_execute_tlbie()
1501 {
1502 	vtlb_flush_address(m_core->param0);
1503 }
1504 
1505 
1506 /*-------------------------------------------------
1507     ppccom_execute_tlbia - execute a TLBIA
1508     instruction
1509 -------------------------------------------------*/
1510 
ppccom_execute_tlbia()1511 void ppc_device::ppccom_execute_tlbia()
1512 {
1513 	vtlb_flush_dynamic();
1514 }
1515 
1516 
1517 /*-------------------------------------------------
1518     ppccom_execute_tlbl - execute a TLBLD/TLBLI
1519     instruction
1520 -------------------------------------------------*/
1521 
ppccom_execute_tlbl()1522 void ppc_device::ppccom_execute_tlbl()
1523 {
1524 	uint32_t address = m_core->param0;
1525 	int isitlb = m_core->param1;
1526 	vtlb_entry flags;
1527 	int entrynum;
1528 
1529 	if (m_flavor == PPC_MODEL_602) // TODO
1530 		return;
1531 
1532 	/* determine entry number; we use machine().rand() for associativity */
1533 	entrynum = ((address >> 12) & 0x1f) | (machine().rand() & 0x20) | (isitlb ? 0x40 : 0);
1534 
1535 	/* determine the flags */
1536 	flags = VTLB_FLAG_VALID | VTLB_READ_ALLOWED | VTLB_FETCH_ALLOWED;
1537 	if (m_core->spr[SPR603_RPA] & 0x80)
1538 		flags |= VTLB_WRITE_ALLOWED;
1539 	if (isitlb)
1540 		flags |= VTLB_FETCH_ALLOWED;
1541 
1542 	/* load the entry */
1543 	vtlb_load(entrynum, 1, address, (m_core->spr[SPR603_RPA] & 0xfffff000) | flags);
1544 }
1545 
1546 
1547 /*-------------------------------------------------
1548     ppccom_execute_mftb - execute an MFTB
1549     instruction
1550 -------------------------------------------------*/
1551 
ppccom_execute_mftb()1552 void ppc_device::ppccom_execute_mftb()
1553 {
1554 	switch (m_core->param0)
1555 	{
1556 		/* user mode timebase read */
1557 		case SPRVEA_TBL_R:
1558 			m_core->param1 = get_timebase();
1559 			break;
1560 		case SPRVEA_TBU_R:
1561 			m_core->param1 = get_timebase() >> 32;
1562 			break;
1563 	}
1564 }
1565 
1566 
1567 /*-------------------------------------------------
1568     ppccom_execute_mfspr - execute an MFSPR
1569     instruction
1570 -------------------------------------------------*/
1571 
ppccom_execute_mfspr()1572 void ppc_device::ppccom_execute_mfspr()
1573 {
1574 	/* handle OEA SPRs */
1575 	if (m_cap & PPCCAP_OEA)
1576 	{
1577 		switch (m_core->param0)
1578 		{
1579 			/* read-through no-ops */
1580 			case SPROEA_DSISR:
1581 			case SPROEA_DAR:
1582 			case SPROEA_SDR1:
1583 			case SPROEA_SRR0:
1584 			case SPROEA_SRR1:
1585 			case SPROEA_EAR:
1586 			case SPROEA_IBAT0L:
1587 			case SPROEA_IBAT0U:
1588 			case SPROEA_IBAT1L:
1589 			case SPROEA_IBAT1U:
1590 			case SPROEA_IBAT2L:
1591 			case SPROEA_IBAT2U:
1592 			case SPROEA_IBAT3L:
1593 			case SPROEA_IBAT3U:
1594 			case SPROEA_DBAT0L:
1595 			case SPROEA_DBAT0U:
1596 			case SPROEA_DBAT1L:
1597 			case SPROEA_DBAT1U:
1598 			case SPROEA_DBAT2L:
1599 			case SPROEA_DBAT2U:
1600 			case SPROEA_DBAT3L:
1601 			case SPROEA_DBAT3U:
1602 			case SPROEA_DABR:
1603 				m_core->param1 = m_core->spr[m_core->param0];
1604 				return;
1605 
1606 			/* decrementer */
1607 			case SPROEA_DEC:
1608 				m_core->param1 = get_decrementer();
1609 				return;
1610 		}
1611 	}
1612 
1613 	/* handle 602 SPRs */
1614 	if (m_flavor == PPC_MODEL_602)
1615 	{ // TODO: Which are read/write only?
1616 		switch (m_core->param0)
1617 		{
1618 			case SPR602_TCR:
1619 			case SPR602_IBR:
1620 			case SPR602_ESASRR:
1621 			case SPR602_SEBR:
1622 			case SPR602_SER:
1623 			case SPR602_SP:
1624 			case SPR602_LT:
1625 				m_core->param1 = m_core->spr[m_core->param0];
1626 				return;
1627 		}
1628 	}
1629 
1630 	/* handle 603 SPRs */
1631 	if (m_cap & PPCCAP_603_MMU)
1632 	{
1633 		switch (m_core->param0)
1634 		{
1635 			/* read-through no-ops */
1636 			case SPR603_DMISS:
1637 			case SPR603_DCMP:
1638 			case SPR603_HASH1:
1639 			case SPR603_HASH2:
1640 			case SPR603_IMISS:
1641 			case SPR603_ICMP:
1642 			case SPR603_RPA:
1643 			case SPR603_HID0:
1644 			case SPR603_HID1:
1645 			case SPR603_IABR:
1646 			case SPR603_HID2:
1647 				m_core->param1 = m_core->spr[m_core->param0];
1648 				return;
1649 
1650 			/* timebase */
1651 			case SPR603_TBL_R:
1652 				m_core->param1 = get_timebase();
1653 				return;
1654 			case SPR603_TBU_R:
1655 				m_core->param1 = (get_timebase() >> 32) & 0xffffff;
1656 				return;
1657 		}
1658 	}
1659 
1660 	/* handle 4XX SPRs */
1661 	if (m_cap & PPCCAP_4XX)
1662 	{
1663 		switch (m_core->param0)
1664 		{
1665 			/* read-through no-ops */
1666 			case SPR4XX_EVPR:
1667 			case SPR4XX_ESR:
1668 			case SPR4XX_SRR0:
1669 			case SPR4XX_SRR1:
1670 			case SPR4XX_SRR2:
1671 			case SPR4XX_SRR3:
1672 			case SPR4XX_TCR:
1673 			case SPR4XX_TSR:
1674 			case SPR4XX_IAC1:
1675 			case SPR4XX_IAC2:
1676 			case SPR4XX_DAC1:
1677 			case SPR4XX_DAC2:
1678 			case SPR4XX_DCCR:
1679 			case SPR4XX_ICCR:
1680 			case SPR4XX_PBL1:
1681 			case SPR4XX_PBU1:
1682 			case SPR4XX_PBL2:
1683 			case SPR4XX_PBU2:
1684 				m_core->param1 = m_core->spr[m_core->param0];
1685 				return;
1686 
1687 			/* timebase */
1688 			case SPR4XX_TBLO:
1689 			case SPR4XX_TBLU:
1690 				m_core->param1 = get_timebase();
1691 				return;
1692 			case SPR4XX_TBHI:
1693 			case SPR4XX_TBHU:
1694 				m_core->param1 = (get_timebase() >> 32) & 0xffffff;
1695 				return;
1696 		}
1697 	}
1698 
1699 	/* default handling */
1700 	osd_printf_debug("SPR %03X read\n", m_core->param0);
1701 	m_core->param1 = m_core->spr[m_core->param0];
1702 }
1703 
1704 
1705 /*-------------------------------------------------
1706     ppccom_execute_mtspr - execute an MTSPR
1707     instruction
1708 -------------------------------------------------*/
1709 
ppccom_execute_mtspr()1710 void ppc_device::ppccom_execute_mtspr()
1711 {
1712 	/* handle OEA SPRs */
1713 	if (m_cap & PPCCAP_OEA)
1714 	{
1715 		switch (m_core->param0)
1716 		{
1717 			/* write-through no-ops */
1718 			case SPROEA_DSISR:
1719 			case SPROEA_DAR:
1720 			case SPROEA_SRR0:
1721 			case SPROEA_SRR1:
1722 			case SPROEA_EAR:
1723 			case SPROEA_DABR:
1724 				m_core->spr[m_core->param0] = m_core->param1;
1725 				return;
1726 
1727 			/* registers that affect the memory map */
1728 			case SPROEA_SDR1:
1729 			case SPROEA_IBAT0L:
1730 			case SPROEA_IBAT0U:
1731 			case SPROEA_IBAT1L:
1732 			case SPROEA_IBAT1U:
1733 			case SPROEA_IBAT2L:
1734 			case SPROEA_IBAT2U:
1735 			case SPROEA_IBAT3L:
1736 			case SPROEA_IBAT3U:
1737 			case SPROEA_DBAT0L:
1738 			case SPROEA_DBAT0U:
1739 			case SPROEA_DBAT1L:
1740 			case SPROEA_DBAT1U:
1741 			case SPROEA_DBAT2L:
1742 			case SPROEA_DBAT2U:
1743 			case SPROEA_DBAT3L:
1744 			case SPROEA_DBAT3U:
1745 				m_core->spr[m_core->param0] = m_core->param1;
1746 				ppccom_tlb_flush();
1747 				return;
1748 
1749 			/* decrementer */
1750 			case SPROEA_DEC:
1751 				set_decrementer(m_core->param1);
1752 				return;
1753 		}
1754 	}
1755 
1756 	/* handle 602 SPRs */
1757 	if (m_flavor == PPC_MODEL_602)
1758 	{
1759 		switch (m_core->param0)
1760 		{ // TODO: Which are read/write only?
1761 			case SPR602_TCR:
1762 			case SPR602_IBR:
1763 			case SPR602_ESASRR:
1764 			case SPR602_SEBR:
1765 			case SPR602_SER:
1766 			case SPR602_SP:
1767 			case SPR602_LT:
1768 				m_core->spr[m_core->param0] = m_core->param1;
1769 				return;
1770 		}
1771 	}
1772 
1773 	/* handle 603 SPRs */
1774 	if (m_cap & PPCCAP_603_MMU)
1775 	{
1776 		switch (m_core->param0)
1777 		{
1778 			/* read-only */
1779 			case SPR603_DMISS:
1780 			case SPR603_DCMP:
1781 			case SPR603_HASH1:
1782 			case SPR603_HASH2:
1783 			case SPR603_IMISS:
1784 			case SPR603_ICMP:
1785 				return;
1786 
1787 			/* write-through no-ops */
1788 			case SPR603_RPA:
1789 			case SPR603_HID0:
1790 			case SPR603_HID1:
1791 			case SPR603_IABR:
1792 			case SPR603_HID2:
1793 				m_core->spr[m_core->param0] = m_core->param1;
1794 				return;
1795 
1796 			/* timebase */
1797 			case SPR603_TBL_W:
1798 				set_timebase((get_timebase() & ~u64(0xffffffff00000000U)) | m_core->param1);
1799 				return;
1800 			case SPR603_TBU_W:
1801 				set_timebase((get_timebase() & ~u64(0x00000000ffffffffU)) | ((uint64_t)m_core->param1 << 32));
1802 				return;
1803 		}
1804 	}
1805 
1806 	/* handle 4XX SPRs */
1807 	if (m_cap & PPCCAP_4XX)
1808 	{
1809 		uint32_t oldval = m_core->spr[m_core->param0];
1810 		switch (m_core->param0)
1811 		{
1812 			/* write-through no-ops */
1813 			case SPR4XX_EVPR:
1814 			case SPR4XX_ESR:
1815 			case SPR4XX_DCCR:
1816 			case SPR4XX_ICCR:
1817 			case SPR4XX_SRR0:
1818 			case SPR4XX_SRR1:
1819 			case SPR4XX_SRR2:
1820 			case SPR4XX_SRR3:
1821 				m_core->spr[m_core->param0] = m_core->param1;
1822 				return;
1823 
1824 			/* registers that affect the memory map */
1825 			case SPR4XX_PBL1:
1826 			case SPR4XX_PBU1:
1827 			case SPR4XX_PBL2:
1828 			case SPR4XX_PBU2:
1829 				m_core->spr[m_core->param0] = m_core->param1;
1830 				ppccom_tlb_flush();
1831 				return;
1832 
1833 			/* timer control register */
1834 			case SPR4XX_TCR:
1835 				m_core->spr[SPR4XX_TCR] = m_core->param1 | (oldval & PPC4XX_TCR_WRC_MASK);
1836 				if ((oldval ^ m_core->spr[SPR4XX_TCR]) & PPC4XX_TCR_FIE)
1837 					ppc4xx_fit_callback(nullptr, false);
1838 				if ((oldval ^ m_core->spr[SPR4XX_TCR]) & PPC4XX_TCR_PIE)
1839 					ppc4xx_pit_callback(nullptr, false);
1840 				return;
1841 
1842 			/* timer status register */
1843 			case SPR4XX_TSR:
1844 				m_core->spr[SPR4XX_TSR] &= ~m_core->param1;
1845 				ppc4xx_set_irq_line(0, 0);
1846 				return;
1847 
1848 			/* PIT */
1849 			case SPR4XX_PIT:
1850 				m_core->spr[SPR4XX_PIT] = m_core->param1;
1851 				m_pit_reload = m_core->param1;
1852 				ppc4xx_pit_callback(nullptr, false);
1853 				return;
1854 
1855 			/* timebase */
1856 			case SPR4XX_TBLO:
1857 				set_timebase((get_timebase() & ~u64(0x00ffffff00000000U)) | m_core->param1);
1858 				return;
1859 			case SPR4XX_TBHI:
1860 				set_timebase((get_timebase() & ~u64(0x00000000ffffffffU)) | ((uint64_t)(m_core->param1 & 0x00ffffff) << 32));
1861 				return;
1862 		}
1863 	}
1864 
1865 	/* default handling */
1866 	osd_printf_debug("SPR %03X write = %08X\n", m_core->param0, m_core->param1);
1867 	m_core->spr[m_core->param0] = m_core->param1;
1868 }
1869 
1870 
1871 /*-------------------------------------------------
1872     ppccom_execute_mfdcr - execute an MFDCR
1873     instruction
1874 -------------------------------------------------*/
1875 
ppccom_execute_mfdcr()1876 void ppc_device::ppccom_execute_mfdcr()
1877 {
1878 	/* handle various DCRs */
1879 	switch (m_core->param0)
1880 	{
1881 		/* read-through no-ops */
1882 		case DCR4XX_BR0:
1883 		case DCR4XX_BR1:
1884 		case DCR4XX_BR2:
1885 		case DCR4XX_BR3:
1886 		case DCR4XX_BR4:
1887 		case DCR4XX_BR5:
1888 		case DCR4XX_BR6:
1889 		case DCR4XX_BR7:
1890 		case DCR4XX_BESR:
1891 		case DCR4XX_DMASR:
1892 		case DCR4XX_DMACT0:
1893 		case DCR4XX_DMADA0:
1894 		case DCR4XX_DMASA0:
1895 		case DCR4XX_DMACC0:
1896 		case DCR4XX_DMACR0:
1897 		case DCR4XX_DMACT1:
1898 		case DCR4XX_DMADA1:
1899 		case DCR4XX_DMASA1:
1900 		case DCR4XX_DMACC1:
1901 		case DCR4XX_DMACR1:
1902 		case DCR4XX_DMACT2:
1903 		case DCR4XX_DMADA2:
1904 		case DCR4XX_DMASA2:
1905 		case DCR4XX_DMACC2:
1906 		case DCR4XX_DMACR2:
1907 		case DCR4XX_DMACT3:
1908 		case DCR4XX_DMADA3:
1909 		case DCR4XX_DMASA3:
1910 		case DCR4XX_DMACC3:
1911 		case DCR4XX_DMACR3:
1912 		case DCR4XX_EXIER:
1913 		case DCR4XX_EXISR:
1914 		case DCR4XX_IOCR:
1915 			m_core->param1 = m_dcr[m_core->param0];
1916 			return;
1917 	}
1918 
1919 	/* default handling */
1920 	if (m_dcr_read_func.isnull()) {
1921 		osd_printf_debug("DCR %03X read\n", m_core->param0);
1922 		if (m_core->param0 < ARRAY_LENGTH(m_dcr))
1923 			m_core->param1 = m_dcr[m_core->param0];
1924 		else
1925 			m_core->param1 = 0;
1926 	} else {
1927 		m_core->param1 = m_dcr_read_func(m_core->param0);
1928 	}
1929 }
1930 
1931 
1932 /*-------------------------------------------------
1933     ppccom_execute_mtdcr - execute an MTDCR
1934     instruction
1935 -------------------------------------------------*/
1936 
ppccom_execute_mtdcr()1937 void ppc_device::ppccom_execute_mtdcr()
1938 {
1939 	uint8_t oldval;
1940 
1941 	/* handle various DCRs */
1942 	switch (m_core->param0)
1943 	{
1944 		/* write-through no-ops */
1945 		case DCR4XX_BR0:
1946 		case DCR4XX_BR1:
1947 		case DCR4XX_BR2:
1948 		case DCR4XX_BR3:
1949 		case DCR4XX_BR4:
1950 		case DCR4XX_BR5:
1951 		case DCR4XX_BR6:
1952 		case DCR4XX_BR7:
1953 		case DCR4XX_BESR:
1954 		case DCR4XX_DMACT0:
1955 		case DCR4XX_DMADA0:
1956 		case DCR4XX_DMASA0:
1957 		case DCR4XX_DMACC0:
1958 		case DCR4XX_DMACT1:
1959 		case DCR4XX_DMADA1:
1960 		case DCR4XX_DMASA1:
1961 		case DCR4XX_DMACC1:
1962 		case DCR4XX_DMACT2:
1963 		case DCR4XX_DMADA2:
1964 		case DCR4XX_DMASA2:
1965 		case DCR4XX_DMACC2:
1966 		case DCR4XX_DMACT3:
1967 		case DCR4XX_DMADA3:
1968 		case DCR4XX_DMASA3:
1969 		case DCR4XX_DMACC3:
1970 			m_dcr[m_core->param0] = m_core->param1;
1971 			return;
1972 
1973 		/* DMA status */
1974 		case DCR4XX_DMASR:
1975 			m_dcr[DCR4XX_DMASR] &= ~(m_core->param1 & 0xfff80070);
1976 			ppc4xx_dma_update_irq_states();
1977 			return;
1978 
1979 		/* interrupt enables */
1980 		case DCR4XX_EXIER:
1981 			m_dcr[DCR4XX_EXIER] = m_core->param1;
1982 			ppc4xx_set_irq_line(0, 0);
1983 			return;
1984 
1985 		/* interrupt clear */
1986 		case DCR4XX_EXISR:
1987 			m_dcr[m_core->param0] &= ~m_core->param1;
1988 			ppc4xx_set_irq_line(0, 0);
1989 			return;
1990 
1991 		/* DMA controls */
1992 		case DCR4XX_DMACR0:
1993 		case DCR4XX_DMACR1:
1994 		case DCR4XX_DMACR2:
1995 		case DCR4XX_DMACR3:
1996 			m_dcr[m_core->param0] = m_core->param1;
1997 			if (m_core->param1 & PPC4XX_DMACR_CE)
1998 				ppc4xx_dma_exec((m_core->param0 - DCR4XX_DMACR0) / 8);
1999 			ppc4xx_dma_update_irq_states();
2000 			return;
2001 
2002 		/* I/O control */
2003 		case DCR4XX_IOCR:
2004 			oldval = m_dcr[m_core->param0];
2005 			m_dcr[m_core->param0] = m_core->param1;
2006 			if ((oldval ^ m_core->param1) & 0x02)
2007 				ppc4xx_spu_timer_reset();
2008 			return;
2009 	}
2010 
2011 	/* default handling */
2012 	if (m_dcr_write_func.isnull()) {
2013 		osd_printf_debug("DCR %03X write = %08X\n", m_core->param0, m_core->param1);
2014 		if (m_core->param0 < ARRAY_LENGTH(m_dcr))
2015 			m_dcr[m_core->param0] = m_core->param1;
2016 	} else {
2017 		m_dcr_write_func(m_core->param0,m_core->param1);
2018 	}
2019 }
2020 
2021 
2022 
2023 /***************************************************************************
2024     FLOATING POINT STATUS FLAGS HANDLING
2025 ***************************************************************************/
2026 
2027 /*-------------------------------------------------
2028     ppccom_update_fprf - update the FPRF field
2029     of the FPSCR register
2030 -------------------------------------------------*/
2031 
ppccom_update_fprf()2032 void ppc_device::ppccom_update_fprf()
2033 {
2034 	uint32_t fprf;
2035 	double f = m_core->f[m_core->param0];
2036 
2037 	if (is_qnan_double(f))
2038 	{
2039 		fprf = 0x11;
2040 	}
2041 	else if (is_infinity_double(f))
2042 	{
2043 		if (sign_double(f))     /* -Infinity */
2044 			fprf = 0x09;
2045 		else                    /* +Infinity */
2046 			fprf = 0x05;
2047 	}
2048 	else if (is_normalized_double(f))
2049 	{
2050 		if (sign_double(f))     /* -Normalized */
2051 			fprf = 0x08;
2052 		else                    /* +Normalized */
2053 			fprf = 0x04;
2054 	}
2055 	else if (is_denormalized_double(f))
2056 	{
2057 		if (sign_double(f))     /* -Denormalized */
2058 			fprf = 0x18;
2059 		else                    /* +Denormalized */
2060 			fprf = 0x14;
2061 	}
2062 	else
2063 	{
2064 		if (sign_double(f))     /* -Zero */
2065 			fprf = 0x12;
2066 		else                    /* +Zero */
2067 			fprf = 0x02;
2068 	}
2069 
2070 	m_core->fpscr &= ~0x0001f000;
2071 	m_core->fpscr |= fprf << 12;
2072 }
2073 
2074 
2075 /***************************************************************************
2076     OEA HELPERS
2077 ***************************************************************************/
2078 
2079 /*-------------------------------------------------
2080     decrementer_int_callback - callback that fires
2081     whenever a decrementer interrupt is generated
2082 -------------------------------------------------*/
2083 
TIMER_CALLBACK_MEMBER(ppc_device::decrementer_int_callback)2084 TIMER_CALLBACK_MEMBER( ppc_device::decrementer_int_callback )
2085 {
2086 	uint64_t cycles_until_next;
2087 
2088 	/* set the decrementer IRQ state */
2089 	m_core->irq_pending |= 0x02;
2090 
2091 	/* advance by another full rev */
2092 	m_dec_zero_cycles += (uint64_t)m_tb_divisor << 32;
2093 	cycles_until_next = m_dec_zero_cycles - total_cycles();
2094 	m_decrementer_int_timer->adjust(cycles_to_attotime(cycles_until_next));
2095 }
2096 
2097 /*-------------------------------------------------
2098     ppc_set_dcstore_callback - installs a callback
2099     for detecting datacache stores with dcbst
2100 -------------------------------------------------*/
2101 
ppc_set_dcstore_callback(write32sm_delegate callback)2102 void ppc_device::ppc_set_dcstore_callback(write32sm_delegate callback)
2103 {
2104 	m_dcstore_cb = callback;
2105 }
2106 
2107 
execute_set_input(int inputnum,int state)2108 void ppc_device::execute_set_input(int inputnum, int state)
2109 {
2110 	switch (inputnum)
2111 	{
2112 		case PPC_IRQ:
2113 			m_core->irq_pending = (m_core->irq_pending & ~1) | ((state != CLEAR_LINE) ? 1 : 0);
2114 			break;
2115 	}
2116 }
2117 
2118 
execute_set_input(int inputnum,int state)2119 void ppc4xx_device::execute_set_input(int inputnum, int state)
2120 {
2121 	switch (inputnum)
2122 	{
2123 		case PPC_IRQ_LINE_0:
2124 			ppc4xx_set_irq_line(PPC4XX_IRQ_BIT_EXT0, state);
2125 			break;
2126 
2127 		case PPC_IRQ_LINE_1:
2128 			ppc4xx_set_irq_line(PPC4XX_IRQ_BIT_EXT1, state);
2129 			break;
2130 
2131 		case PPC_IRQ_LINE_2:
2132 			ppc4xx_set_irq_line(PPC4XX_IRQ_BIT_EXT2, state);
2133 			break;
2134 
2135 		case PPC_IRQ_LINE_3:
2136 			ppc4xx_set_irq_line(PPC4XX_IRQ_BIT_EXT3, state);
2137 			break;
2138 
2139 		case PPC_IRQ_LINE_4:
2140 			ppc4xx_set_irq_line(PPC4XX_IRQ_BIT_EXT4, state);
2141 			break;
2142 	}
2143 }
2144 
2145 
2146 /***************************************************************************
2147     EMBEDDED 4XX HELPERS
2148 ***************************************************************************/
2149 
2150 /*-------------------------------------------------
2151     ppc4xx_set_irq_line - PowerPC 4XX-specific
2152     IRQ line management
2153 -------------------------------------------------*/
2154 
ppc4xx_set_irq_line(uint32_t bitmask,int state)2155 void ppc_device::ppc4xx_set_irq_line(uint32_t bitmask, int state)
2156 {
2157 	uint32_t oldstate = m_irqstate;
2158 	uint32_t levelmask;
2159 
2160 	/* set or clear the appropriate bit */
2161 	if (state != CLEAR_LINE)
2162 		m_irqstate |= bitmask;
2163 	else
2164 		m_irqstate &= ~bitmask;
2165 
2166 	/* if the state changed to on, edge trigger the interrupt */
2167 	if (((m_irqstate ^ oldstate) & bitmask) && (m_irqstate & bitmask))
2168 		m_dcr[DCR4XX_EXISR] |= bitmask;
2169 
2170 	/* pass through all level-triggered interrupts */
2171 	levelmask = PPC4XX_IRQ_BIT_CRITICAL | PPC4XX_IRQ_BIT_SPUR | PPC4XX_IRQ_BIT_SPUT;
2172 	levelmask |= PPC4XX_IRQ_BIT_JTAGR | PPC4XX_IRQ_BIT_JTAGT;
2173 	levelmask |= PPC4XX_IRQ_BIT_DMA0 | PPC4XX_IRQ_BIT_DMA1 | PPC4XX_IRQ_BIT_DMA2 | PPC4XX_IRQ_BIT_DMA3;
2174 	if (!(m_dcr[DCR4XX_IOCR] & 0x80000000)) levelmask |= PPC4XX_IRQ_BIT_EXT0;
2175 	if (!(m_dcr[DCR4XX_IOCR] & 0x20000000)) levelmask |= PPC4XX_IRQ_BIT_EXT1;
2176 	if (!(m_dcr[DCR4XX_IOCR] & 0x08000000)) levelmask |= PPC4XX_IRQ_BIT_EXT2;
2177 	if (!(m_dcr[DCR4XX_IOCR] & 0x02000000)) levelmask |= PPC4XX_IRQ_BIT_EXT3;
2178 	if (!(m_dcr[DCR4XX_IOCR] & 0x00800000)) levelmask |= PPC4XX_IRQ_BIT_EXT4;
2179 	m_dcr[DCR4XX_EXISR] = (m_dcr[DCR4XX_EXISR] & ~levelmask) | (m_irqstate & levelmask);
2180 
2181 	/* update the IRQ status */
2182 	m_core->irq_pending = ((m_dcr[DCR4XX_EXISR] & m_dcr[DCR4XX_EXIER]) != 0);
2183 	if ((m_core->spr[SPR4XX_TCR] & PPC4XX_TCR_FIE) && (m_core->spr[SPR4XX_TSR] & PPC4XX_TSR_FIS))
2184 		m_core->irq_pending = true;
2185 	if ((m_core->spr[SPR4XX_TCR] & PPC4XX_TCR_PIE) && (m_core->spr[SPR4XX_TSR] & PPC4XX_TSR_PIS))
2186 		m_core->irq_pending = true;
2187 }
2188 
2189 
2190 /*-------------------------------------------------
2191     ppc4xx_get_irq_line - PowerPC 4XX-specific
2192     IRQ line state getter
2193 -------------------------------------------------*/
2194 
ppc4xx_get_irq_line(uint32_t bitmask)2195 int ppc_device::ppc4xx_get_irq_line(uint32_t bitmask)
2196 {
2197 	return (m_irqstate & bitmask) ? ASSERT_LINE : CLEAR_LINE;
2198 }
2199 
2200 
2201 /*-------------------------------------------------
2202     ppc4xx_dma_update_irq_states - update the IRQ
2203     state for each DMA channel
2204 -------------------------------------------------*/
2205 
ppc4xx_dma_update_irq_states()2206 void ppc_device::ppc4xx_dma_update_irq_states()
2207 {
2208 	/* update the IRQ state for each DMA channel */
2209 	for (int dmachan = 0; dmachan < 4; dmachan++)
2210 	{
2211 		bool irq_pending = false;
2212 
2213 		// Channel interrupt enabled?
2214 		if ((m_dcr[DCR4XX_DMACR0 + 8 * dmachan] & PPC4XX_DMACR_CIE))
2215 		{
2216 			// Terminal count and end-of-transfer status bits
2217 			int bitmask = 0x11 << (27 - dmachan);
2218 
2219 			// Chained transfer status bit
2220 			switch (dmachan)
2221 			{
2222 				case 0:
2223 					bitmask |= 0x00080000;
2224 					break;
2225 
2226 				case 1:
2227 				case 2:
2228 				case 3:
2229 					bitmask |= 1 << (7 - dmachan);
2230 					break;
2231 			}
2232 
2233 			irq_pending = (m_dcr[DCR4XX_DMASR] & bitmask) != 0;
2234 		}
2235 
2236 		ppc4xx_set_irq_line(PPC4XX_IRQ_BIT_DMA(dmachan), irq_pending ? ASSERT_LINE : CLEAR_LINE);
2237 	}
2238 }
2239 
2240 
2241 /*-------------------------------------------------
2242     ppc4xx_dma_decrement_count - decrement the
2243     count on a channel and interrupt if configured
2244     to do so
2245 -------------------------------------------------*/
2246 
ppc4xx_dma_decrement_count(int dmachan)2247 bool ppc_device::ppc4xx_dma_decrement_count(int dmachan)
2248 {
2249 	uint32_t *dmaregs = &m_dcr[8 * dmachan];
2250 
2251 	/* decrement the counter */
2252 	dmaregs[DCR4XX_DMACT0]--;
2253 
2254 	/* if non-zero, we keep going */
2255 	if ((dmaregs[DCR4XX_DMACT0] & 0xffff) != 0)
2256 		return false;
2257 
2258 	// if chained mode
2259 	if (dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_CH)
2260 	{
2261 		dmaregs[DCR4XX_DMADA0] = dmaregs[DCR4XX_DMASA0];
2262 		dmaregs[DCR4XX_DMACT0] = dmaregs[DCR4XX_DMACC0];
2263 		dmaregs[DCR4XX_DMACR0] &= ~PPC4XX_DMACR_CH;
2264 
2265 		switch (dmachan)
2266 		{
2267 			case 0:
2268 				m_dcr[DCR4XX_DMASR] |= 0x00080000;
2269 				break;
2270 
2271 			case 1:
2272 			case 2:
2273 			case 3:
2274 				m_dcr[DCR4XX_DMASR] |= 1 << (7 - dmachan);
2275 				break;
2276 		}
2277 
2278 		ppc4xx_dma_update_irq_states();
2279 
2280 		int64_t numdata = dmaregs[DCR4XX_DMACT0];
2281 		if (numdata == 0)
2282 			numdata = 65536;
2283 
2284 		int64_t time = (numdata * 1000000) / m_buffered_dma_rate[dmachan];
2285 
2286 		m_buffered_dma_timer[dmachan]->adjust(attotime::from_usec(time), dmachan);
2287 	}
2288 	else
2289 	{
2290 		/* set the complete bit and handle interrupts */
2291 		m_dcr[DCR4XX_DMASR] |= 1 << (31 - dmachan);
2292 	//  m_dcr[DCR4XX_DMASR] |= 1 << (27 - dmachan);
2293 		ppc4xx_dma_update_irq_states();
2294 
2295 		m_buffered_dma_timer[dmachan]->adjust(attotime::never, false);
2296 	}
2297 	return true;
2298 }
2299 
2300 
2301 /*-------------------------------------------------
2302     buffered_dma_callback - callback that fires
2303     when buffered DMA transfer is ready
2304 -------------------------------------------------*/
2305 
TIMER_CALLBACK_MEMBER(ppc_device::ppc4xx_buffered_dma_callback)2306 TIMER_CALLBACK_MEMBER( ppc_device::ppc4xx_buffered_dma_callback )
2307 {
2308 	int dmachan = param;
2309 
2310 	static const uint8_t dma_transfer_width[4] = { 1, 2, 4, 16 };
2311 	uint32_t *dmaregs = &m_dcr[8 * dmachan];
2312 	int32_t destinc;
2313 	uint8_t width;
2314 
2315 	width = dma_transfer_width[(dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_PW_MASK) >> 26];
2316 	destinc = (dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_DAI) ? width : 0;
2317 
2318 	if (dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_TD)
2319 	{
2320 		/* peripheral to memory */
2321 
2322 		switch (width)
2323 		{
2324 			/* byte transfer */
2325 			case 1:
2326 			do
2327 			{
2328 				uint8_t data = 0;
2329 				if (!m_ext_dma_read_cb[dmachan].isnull())
2330 					data = (m_ext_dma_read_cb[dmachan])(*m_program, 1, 0xffffffff);
2331 				m_program->write_byte(dmaregs[DCR4XX_DMADA0], data);
2332 				dmaregs[DCR4XX_DMADA0] += destinc;
2333 			} while (!ppc4xx_dma_decrement_count(dmachan));
2334 			break;
2335 
2336 			/* word transfer */
2337 			case 2:
2338 			do
2339 			{
2340 				uint16_t data = 0;
2341 				if (!m_ext_dma_read_cb[dmachan].isnull())
2342 					data = (m_ext_dma_read_cb[dmachan])(*m_program, 2, 0xffffffff);
2343 				m_program->write_word(dmaregs[DCR4XX_DMADA0], data);
2344 				dmaregs[DCR4XX_DMADA0] += destinc;
2345 			} while (!ppc4xx_dma_decrement_count(dmachan));
2346 			break;
2347 
2348 			/* dword transfer */
2349 			case 4:
2350 			do
2351 			{
2352 				uint32_t data = 0;
2353 				if (!m_ext_dma_read_cb[dmachan].isnull())
2354 					data = (m_ext_dma_read_cb[dmachan])(*m_program, 4, 0xffffffff);
2355 				m_program->write_dword(dmaregs[DCR4XX_DMADA0], data);
2356 				dmaregs[DCR4XX_DMADA0] += destinc;
2357 			} while (!ppc4xx_dma_decrement_count(dmachan));
2358 			break;
2359 		}
2360 	}
2361 	else
2362 	{
2363 		/* memory to peripheral */
2364 
2365 		// data is read from destination address!
2366 		switch (width)
2367 		{
2368 			/* byte transfer */
2369 			case 1:
2370 			do
2371 			{
2372 				uint8_t data = m_program->read_byte(dmaregs[DCR4XX_DMADA0]);
2373 				if (!m_ext_dma_write_cb[dmachan].isnull())
2374 					(m_ext_dma_write_cb[dmachan])(1, data);
2375 				dmaregs[DCR4XX_DMADA0] += destinc;
2376 			} while (!ppc4xx_dma_decrement_count(dmachan));
2377 			break;
2378 
2379 			/* word transfer */
2380 			case 2:
2381 			do
2382 			{
2383 				uint16_t data = m_program->read_word(dmaregs[DCR4XX_DMADA0]);
2384 				if (!m_ext_dma_write_cb[dmachan].isnull())
2385 					(m_ext_dma_write_cb[dmachan])(2, data);
2386 				dmaregs[DCR4XX_DMADA0] += destinc;
2387 			} while (!ppc4xx_dma_decrement_count(dmachan));
2388 			break;
2389 
2390 			/* dword transfer */
2391 			case 4:
2392 			do
2393 			{
2394 				uint32_t data = m_program->read_dword(dmaregs[DCR4XX_DMADA0]);
2395 				if (!m_ext_dma_write_cb[dmachan].isnull())
2396 					(m_ext_dma_write_cb[dmachan])(4, data);
2397 				dmaregs[DCR4XX_DMADA0] += destinc;
2398 			} while (!ppc4xx_dma_decrement_count(dmachan));
2399 			break;
2400 		}
2401 	}
2402 }
2403 
2404 
2405 /*-------------------------------------------------
2406     ppc4xx_dma_fetch_transmit_byte - fetch a byte
2407     to send to a peripheral
2408 -------------------------------------------------*/
2409 
ppc4xx_dma_fetch_transmit_byte(int dmachan,uint8_t * byte)2410 bool ppc_device::ppc4xx_dma_fetch_transmit_byte(int dmachan, uint8_t *byte)
2411 {
2412 	uint32_t *dmaregs = &m_dcr[8 * dmachan];
2413 
2414 	/* if the channel is not enabled, fail */
2415 	if (!(dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_CE))
2416 		return false;
2417 
2418 	/* if no transfers remaining, fail */
2419 	if ((dmaregs[DCR4XX_DMACT0] & 0xffff) == 0)
2420 		return false;
2421 
2422 	/* fetch the data */
2423 	*byte = m_program->read_byte(dmaregs[DCR4XX_DMADA0]++);
2424 	ppc4xx_dma_decrement_count(dmachan);
2425 	return true;
2426 }
2427 
2428 
2429 /*-------------------------------------------------
2430     ppc4xx_dma_handle_receive_byte - receive a byte
2431     transmitted by a peripheral
2432 -------------------------------------------------*/
2433 
ppc4xx_dma_handle_receive_byte(int dmachan,uint8_t byte)2434 bool ppc_device::ppc4xx_dma_handle_receive_byte(int dmachan, uint8_t byte)
2435 {
2436 	uint32_t *dmaregs = &m_dcr[8 * dmachan];
2437 
2438 	/* if the channel is not enabled, fail */
2439 	if (!(dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_CE))
2440 		return false;
2441 
2442 	/* if no transfers remaining, fail */
2443 	if ((dmaregs[DCR4XX_DMACT0] & 0xffff) == 0)
2444 		return false;
2445 
2446 	/* store the data */
2447 	m_program->write_byte(dmaregs[DCR4XX_DMADA0]++, byte);
2448 	ppc4xx_dma_decrement_count(dmachan);
2449 	return true;
2450 }
2451 
2452 
2453 /*-------------------------------------------------
2454     ppc4xx_dma_execute - execute a DMA operation
2455     if one is pending
2456 -------------------------------------------------*/
2457 
ppc4xx_dma_exec(int dmachan)2458 void ppc_device::ppc4xx_dma_exec(int dmachan)
2459 {
2460 	static const uint8_t dma_transfer_width[4] = { 1, 2, 4, 16 };
2461 	uint32_t *dmaregs = &m_dcr[8 * dmachan];
2462 	int32_t destinc, srcinc;
2463 	uint8_t width;
2464 
2465 	/* skip if not enabled */
2466 	if (!(dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_CE))
2467 		return;
2468 
2469 	/* check for unsupported features */
2470 	if (!(dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_TCE))
2471 		fatalerror("ppc4xx_dma_exec: DMA_TCE == 0\n");
2472 
2473 	/* transfer mode */
2474 	switch ((dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_TM_MASK) >> 21)
2475 	{
2476 		/* buffered mode DMA */
2477 		case 0:
2478 			if (((dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_PL) >> 28) == 0)
2479 			{
2480 				/* buffered DMA with external peripheral */
2481 
2482 				int64_t numdata = dmaregs[DCR4XX_DMACT0];
2483 				if (numdata == 0)
2484 					numdata = 65536;
2485 
2486 				int64_t time;
2487 				if (numdata > 100)
2488 				{
2489 					time = (numdata * 1000000) / m_buffered_dma_rate[dmachan];
2490 				}
2491 				else
2492 				{
2493 					time = 0;       // let very short transfers occur instantly
2494 				}
2495 
2496 				m_buffered_dma_timer[dmachan]->adjust(attotime::from_usec(time), dmachan);
2497 			}
2498 			else        /* buffered DMA with internal peripheral (SPU) */
2499 			{
2500 				/* nothing to do; this happens asynchronously and is driven by the SPU */
2501 			}
2502 			break;
2503 
2504 		/* fly-by mode DMA */
2505 		case 1:
2506 			fatalerror("ppc4xx_dma_exec: fly-by DMA not implemented\n");
2507 
2508 		/* software initiated memory-to-memory mode DMA */
2509 		case 2:
2510 			width = dma_transfer_width[(dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_PW_MASK) >> 26];
2511 			srcinc = (dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_SAI) ? width : 0;
2512 			destinc = (dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_DAI) ? width : 0;
2513 
2514 			switch (width)
2515 			{
2516 				/* byte transfer */
2517 				case 1:
2518 					do
2519 					{
2520 						m_program->write_byte(dmaregs[DCR4XX_DMADA0], m_program->read_byte(dmaregs[DCR4XX_DMASA0]));
2521 						dmaregs[DCR4XX_DMASA0] += srcinc;
2522 						dmaregs[DCR4XX_DMADA0] += destinc;
2523 					} while (!ppc4xx_dma_decrement_count(dmachan));
2524 					break;
2525 
2526 				/* word transfer */
2527 				case 2:
2528 					do
2529 					{
2530 						m_program->write_word(dmaregs[DCR4XX_DMADA0], m_program->read_word(dmaregs[DCR4XX_DMASA0]));
2531 						dmaregs[DCR4XX_DMASA0] += srcinc;
2532 						dmaregs[DCR4XX_DMADA0] += destinc;
2533 					} while (!ppc4xx_dma_decrement_count(dmachan));
2534 					break;
2535 
2536 				/* dword transfer */
2537 				case 4:
2538 					do
2539 					{
2540 						m_program->write_dword(dmaregs[DCR4XX_DMADA0], m_program->read_dword(dmaregs[DCR4XX_DMASA0]));
2541 						dmaregs[DCR4XX_DMASA0] += srcinc;
2542 						dmaregs[DCR4XX_DMADA0] += destinc;
2543 					} while (!ppc4xx_dma_decrement_count(dmachan));
2544 					break;
2545 
2546 				/* 16-byte transfer */
2547 				case 16:
2548 					do
2549 					{
2550 						m_program->write_qword(dmaregs[DCR4XX_DMADA0], m_program->read_qword(dmaregs[DCR4XX_DMASA0]));
2551 						m_program->write_qword(dmaregs[DCR4XX_DMADA0] + 8, m_program->read_qword(dmaregs[DCR4XX_DMASA0] + 8));
2552 						dmaregs[DCR4XX_DMASA0] += srcinc;
2553 						dmaregs[DCR4XX_DMADA0] += destinc;
2554 					} while (!ppc4xx_dma_decrement_count(dmachan));
2555 					break;
2556 			}
2557 			break;
2558 
2559 		/* hardware initiated memory-to-memory mode DMA */
2560 		case 3:
2561 			fatalerror("ppc4xx_dma_exec: HW mem-to-mem DMA not implemented\n");
2562 	}
2563 }
2564 
2565 
2566 /*-------------------------------------------------
2567     ppc4xx_fit_callback - FIT timer callback
2568 -------------------------------------------------*/
2569 
TIMER_CALLBACK_MEMBER(ppc_device::ppc4xx_fit_callback)2570 TIMER_CALLBACK_MEMBER( ppc_device::ppc4xx_fit_callback )
2571 {
2572 	/* if this is a real callback and we are enabled, signal an interrupt */
2573 	if (param)
2574 	{
2575 		m_core->spr[SPR4XX_TSR] |= PPC4XX_TSR_FIS;
2576 		ppc4xx_set_irq_line(0, 0);
2577 	}
2578 
2579 	/* update ourself for the next interval if we are enabled */
2580 	if (m_core->spr[SPR4XX_TCR] & PPC4XX_TCR_FIE)
2581 	{
2582 		uint32_t timebase = get_timebase();
2583 		uint32_t interval = 0x200 << (4 * ((m_core->spr[SPR4XX_TCR] & PPC4XX_TCR_FP_MASK) >> 24));
2584 		uint32_t target = (timebase + interval) & ~(interval - 1);
2585 		m_fit_timer->adjust(cycles_to_attotime((target + 1 - timebase) / m_tb_divisor), true);
2586 	}
2587 
2588 	/* otherwise, turn ourself off */
2589 	else
2590 		m_fit_timer->adjust(attotime::never, false);
2591 }
2592 
2593 
2594 /*-------------------------------------------------
2595     ppc4xx_pit_callback - PIT timer callback
2596 -------------------------------------------------*/
2597 
TIMER_CALLBACK_MEMBER(ppc_device::ppc4xx_pit_callback)2598 TIMER_CALLBACK_MEMBER( ppc_device::ppc4xx_pit_callback )
2599 {
2600 	/* if this is a real callback and we are enabled, signal an interrupt */
2601 	if (param)
2602 	{
2603 		m_core->spr[SPR4XX_TSR] |= PPC4XX_TSR_PIS;
2604 		ppc4xx_set_irq_line(0, 0);
2605 	}
2606 
2607 	/* update ourself for the next interval if we are enabled and we are either being
2608 	   forced to update, or we are in auto-reload mode */
2609 	if ((m_core->spr[SPR4XX_TCR] & PPC4XX_TCR_PIE) && m_pit_reload != 0 && (!param || (m_core->spr[SPR4XX_TCR] & PPC4XX_TCR_ARE)))
2610 	{
2611 		uint32_t timebase = get_timebase();
2612 		uint32_t interval = m_pit_reload;
2613 		uint32_t target = timebase + interval;
2614 		m_pit_timer->adjust(cycles_to_attotime((target + 1 - timebase) / m_tb_divisor), true);
2615 	}
2616 
2617 	/* otherwise, turn ourself off */
2618 	else
2619 		m_pit_timer->adjust(attotime::never, false);
2620 }
2621 
2622 
2623 /*-------------------------------------------------
2624     ppc4xx_spu_update_irq_states - update the IRQ
2625     state for the SPU
2626 -------------------------------------------------*/
2627 
ppc4xx_spu_update_irq_states()2628 void ppc_device::ppc4xx_spu_update_irq_states()
2629 {
2630 	/* check for receive buffer full interrupt */
2631 	if ((m_spu.regs[SPU4XX_RX_COMMAND] & 0x60) == 0x20 && (m_spu.regs[SPU4XX_LINE_STATUS] & 0x80))
2632 		ppc4xx_set_irq_line(PPC4XX_IRQ_BIT_SPUR, ASSERT_LINE);
2633 
2634 	/* check for receive error interrupt */
2635 	else if ((m_spu.regs[SPU4XX_RX_COMMAND] & 0x10) && (m_spu.regs[SPU4XX_LINE_STATUS] & 0x78))
2636 		ppc4xx_set_irq_line(PPC4XX_IRQ_BIT_SPUR, ASSERT_LINE);
2637 
2638 	/* clear otherwise */
2639 	else
2640 		ppc4xx_set_irq_line(PPC4XX_IRQ_BIT_SPUR, CLEAR_LINE);
2641 
2642 	/* check for transmit buffer empty interrupt */
2643 	if ((m_spu.regs[SPU4XX_TX_COMMAND] & 0x60) == 0x20 && (m_spu.regs[SPU4XX_LINE_STATUS] & 0x04))
2644 		ppc4xx_set_irq_line(PPC4XX_IRQ_BIT_SPUT, ASSERT_LINE);
2645 
2646 	/* check for shift register empty interrupt */
2647 	else if ((m_spu.regs[SPU4XX_TX_COMMAND] & 0x10) && (m_spu.regs[SPU4XX_LINE_STATUS] & 0x02))
2648 		ppc4xx_set_irq_line(PPC4XX_IRQ_BIT_SPUT, ASSERT_LINE);
2649 
2650 	/* clear otherwise */
2651 	else
2652 		ppc4xx_set_irq_line(PPC4XX_IRQ_BIT_SPUT, CLEAR_LINE);
2653 }
2654 
2655 
2656 /*-------------------------------------------------
2657     ppc4xx_spu_rx_data - serial port data receive
2658 -------------------------------------------------*/
2659 
ppc4xx_spu_rx_data(uint8_t data)2660 void ppc_device::ppc4xx_spu_rx_data(uint8_t data)
2661 {
2662 	uint32_t new_rxin;
2663 
2664 	/* fail if we are going to overflow */
2665 	new_rxin = (m_spu.rxin + 1) % ARRAY_LENGTH(m_spu.rxbuffer);
2666 	if (new_rxin == m_spu.rxout)
2667 		fatalerror("ppc4xx_spu_rx_data: buffer overrun!\n");
2668 
2669 	/* store the data and accept the new in index */
2670 	m_spu.rxbuffer[m_spu.rxin] = data;
2671 	m_spu.rxin = new_rxin;
2672 }
2673 
2674 
2675 /*-------------------------------------------------
2676     ppc4xx_spu_timer_reset - reset and recompute
2677     the transmit/receive timer
2678 -------------------------------------------------*/
2679 
ppc4xx_spu_timer_reset()2680 void ppc_device::ppc4xx_spu_timer_reset()
2681 {
2682 	uint8_t enabled = (m_spu.regs[SPU4XX_RX_COMMAND] | m_spu.regs[SPU4XX_TX_COMMAND]) & 0x80;
2683 
2684 	/* if we're enabled, reset at the current baud rate */
2685 	if (enabled)
2686 	{
2687 		attotime clockperiod = attotime::from_hz((m_dcr[DCR4XX_IOCR] & 0x02) ? 3686400 : 33333333);
2688 		int divisor = ((m_spu.regs[SPU4XX_BAUD_DIVISOR_H] * 256 + m_spu.regs[SPU4XX_BAUD_DIVISOR_L]) & 0xfff) + 1;
2689 		int bpc = 7 + ((m_spu.regs[SPU4XX_CONTROL] & 8) >> 3) + 1 + (m_spu.regs[SPU4XX_CONTROL] & 1);
2690 		attotime charperiod = clockperiod * (divisor * 16 * bpc);
2691 		m_spu.timer->adjust(charperiod, 0, charperiod);
2692 		if (PRINTF_SPU)
2693 			printf("ppc4xx_spu_timer_reset: baud rate = %.0f\n", charperiod.as_hz() * bpc);
2694 	}
2695 
2696 	/* otherwise, disable the timer */
2697 	else
2698 		m_spu.timer->adjust(attotime::never);
2699 }
2700 
2701 
2702 /*-------------------------------------------------
2703     ppc4xx_spu_callback - serial port send/receive
2704     timer
2705 -------------------------------------------------*/
2706 
TIMER_CALLBACK_MEMBER(ppc_device::ppc4xx_spu_callback)2707 TIMER_CALLBACK_MEMBER( ppc_device::ppc4xx_spu_callback )
2708 {
2709 	/* transmit enabled? */
2710 	if (m_spu.regs[SPU4XX_TX_COMMAND] & 0x80)
2711 	{
2712 		int operation = (m_spu.regs[SPU4XX_TX_COMMAND] >> 5) & 3;
2713 
2714 		/* if we have data to transmit, do it now */
2715 		if (!(m_spu.regs[SPU4XX_LINE_STATUS] & 0x04))
2716 		{
2717 			/* if we have a transmit handler, send it that way */
2718 			if (!m_spu.tx_cb.isnull())
2719 				(m_spu.tx_cb)(m_spu.txbuf);
2720 
2721 			/* indicate that we have moved it to the shift register */
2722 			m_spu.regs[SPU4XX_LINE_STATUS] |= 0x04;
2723 			m_spu.regs[SPU4XX_LINE_STATUS] &= ~0x02;
2724 		}
2725 
2726 		/* otherwise, clear the shift register */
2727 		else if (!(m_spu.regs[SPU4XX_LINE_STATUS] & 0x02))
2728 			m_spu.regs[SPU4XX_LINE_STATUS] |= 0x02;
2729 
2730 		/* handle DMA */
2731 		if (operation >= 2 && ppc4xx_dma_fetch_transmit_byte(operation, &m_spu.txbuf))
2732 			m_spu.regs[SPU4XX_LINE_STATUS] &= ~0x04;
2733 	}
2734 
2735 	/* receive enabled? */
2736 	if (m_spu.regs[SPU4XX_RX_COMMAND] & 0x80)
2737 		if (m_spu.rxout != m_spu.rxin)
2738 		{
2739 			int operation = (m_spu.regs[SPU4XX_RX_COMMAND] >> 5) & 3;
2740 			uint8_t rxbyte;
2741 
2742 			/* consume the byte and advance the out pointer */
2743 			rxbyte = m_spu.rxbuffer[m_spu.rxout];
2744 			m_spu.rxout = (m_spu.rxout + 1) % ARRAY_LENGTH(m_spu.rxbuffer);
2745 
2746 			/* if we're not full, copy data to the buffer and update the line status */
2747 			if (!(m_spu.regs[SPU4XX_LINE_STATUS] & 0x80))
2748 			{
2749 				m_spu.rxbuf = rxbyte;
2750 				m_spu.regs[SPU4XX_LINE_STATUS] |= 0x80;
2751 			}
2752 
2753 			/* otherwise signal an overrun */
2754 			else
2755 			{
2756 				m_spu.regs[SPU4XX_LINE_STATUS] |= 0x20;
2757 				goto updateirq;
2758 			}
2759 
2760 			/* handle DMA */
2761 			if (operation >= 2 && ppc4xx_dma_handle_receive_byte(operation, m_spu.rxbuf))
2762 				m_spu.regs[SPU4XX_LINE_STATUS] &= ~0x80;
2763 		}
2764 
2765 	/* update the final IRQ states */
2766 updateirq:
2767 	ppc4xx_spu_update_irq_states();
2768 }
2769 
2770 
2771 /*-------------------------------------------------
2772     ppc4xx_spu_r - serial port read handler
2773 -------------------------------------------------*/
2774 
ppc4xx_spu_r(offs_t offset)2775 uint8_t ppc4xx_device::ppc4xx_spu_r(offs_t offset)
2776 {
2777 	uint8_t result = 0xff;
2778 
2779 	switch (offset)
2780 	{
2781 		case SPU4XX_BUFFER:
2782 			result = m_spu.rxbuf;
2783 			m_spu.regs[SPU4XX_LINE_STATUS] &= ~0x80;
2784 			break;
2785 
2786 		default:
2787 			if (offset < ARRAY_LENGTH(m_spu.regs))
2788 				result = m_spu.regs[offset];
2789 			break;
2790 	}
2791 	if (PRINTF_SPU)
2792 		printf("spu_r(%d) = %02X\n", offset, result);
2793 	return result;
2794 }
2795 
2796 
2797 /*-------------------------------------------------
2798     ppc4xx_spu_w - serial port write handler
2799 -------------------------------------------------*/
2800 
ppc4xx_spu_w(offs_t offset,uint8_t data)2801 void ppc4xx_device::ppc4xx_spu_w(offs_t offset, uint8_t data)
2802 {
2803 	uint8_t oldstate, newstate;
2804 
2805 	if (PRINTF_SPU)
2806 		printf("spu_w(%d) = %02X\n", offset, data);
2807 	switch (offset)
2808 	{
2809 		/* clear error bits */
2810 		case SPU4XX_LINE_STATUS:
2811 			m_spu.regs[SPU4XX_LINE_STATUS] &= ~(data & 0xf8);
2812 			ppc4xx_spu_update_irq_states();
2813 			break;
2814 
2815 		/* enable/disable the timer if one of these is enabled */
2816 		case SPU4XX_RX_COMMAND:
2817 		case SPU4XX_TX_COMMAND:
2818 			oldstate = m_spu.regs[SPU4XX_RX_COMMAND] | m_spu.regs[SPU4XX_TX_COMMAND];
2819 			m_spu.regs[offset] = data;
2820 			newstate = m_spu.regs[SPU4XX_RX_COMMAND] | m_spu.regs[SPU4XX_TX_COMMAND];
2821 			if ((oldstate ^ newstate) & 0x80)
2822 				ppc4xx_spu_timer_reset();
2823 			ppc4xx_spu_update_irq_states();
2824 			break;
2825 
2826 		/* if the divisor changes, we need to update the timer */
2827 		case SPU4XX_BAUD_DIVISOR_H:
2828 		case SPU4XX_BAUD_DIVISOR_L:
2829 			if (data != m_spu.regs[offset])
2830 			{
2831 				m_spu.regs[offset] = data;
2832 				ppc4xx_spu_timer_reset();
2833 			}
2834 			break;
2835 
2836 		/* if the number of data bits or stop bits changes, we need to update the timer */
2837 		case SPU4XX_CONTROL:
2838 			oldstate = m_spu.regs[offset];
2839 			m_spu.regs[offset] = data;
2840 			if ((oldstate ^ data) & 0x09)
2841 				ppc4xx_spu_timer_reset();
2842 			break;
2843 
2844 		case SPU4XX_BUFFER:
2845 			/* write to the transmit buffer and mark it full */
2846 			m_spu.txbuf = data;
2847 			m_spu.regs[SPU4XX_LINE_STATUS] &= ~0x04;
2848 			break;
2849 
2850 		default:
2851 			if (offset < ARRAY_LENGTH(m_spu.regs))
2852 				m_spu.regs[offset] = data;
2853 			break;
2854 	}
2855 }
2856 
2857 
2858 
2859 /*-------------------------------------------------
2860     ppc4xx_spu_set_tx_handler - PowerPC 4XX-
2861     specific TX handler configuration
2862 -------------------------------------------------*/
2863 
ppc4xx_spu_set_tx_handler(write8smo_delegate callback)2864 void ppc4xx_device::ppc4xx_spu_set_tx_handler(write8smo_delegate callback)
2865 {
2866 	m_spu.tx_cb = callback;
2867 }
2868 
2869 
2870 /*-------------------------------------------------
2871     ppc4xx_spu_receive_byte - PowerPC 4XX-
2872     specific serial byte receive
2873 -------------------------------------------------*/
2874 
ppc4xx_spu_receive_byte(uint8_t byteval)2875 void ppc4xx_device::ppc4xx_spu_receive_byte(uint8_t byteval)
2876 {
2877 	ppc4xx_spu_rx_data(byteval);
2878 }
2879 
2880 /*-------------------------------------------------
2881     ppc4xx_set_dma_read_handler - PowerPC 4XX-
2882     specific external DMA read handler configuration
2883 -------------------------------------------------*/
2884 
ppc4xx_set_dma_read_handler(int channel,read32_delegate callback,int rate)2885 void ppc4xx_device::ppc4xx_set_dma_read_handler(int channel, read32_delegate callback, int rate)
2886 {
2887 	m_ext_dma_read_cb[channel] = callback;
2888 	m_buffered_dma_rate[channel] = rate;
2889 }
2890 
2891 /*-------------------------------------------------
2892     ppc4xx_set_dma_write_handler - PowerPC 4XX-
2893     specific external DMA write handler configuration
2894 -------------------------------------------------*/
2895 
ppc4xx_set_dma_write_handler(int channel,write32sm_delegate callback,int rate)2896 void ppc4xx_device::ppc4xx_set_dma_write_handler(int channel, write32sm_delegate callback, int rate)
2897 {
2898 	m_ext_dma_write_cb[channel] = callback;
2899 	m_buffered_dma_rate[channel] = rate;
2900 }
2901 
2902 /*-------------------------------------------------
2903     ppc4xx_set_dcr_read_handler
2904 -------------------------------------------------*/
2905 
ppc4xx_set_dcr_read_handler(read32sm_delegate dcr_read_func)2906 void ppc4xx_device::ppc4xx_set_dcr_read_handler(read32sm_delegate dcr_read_func)
2907 {
2908 	m_dcr_read_func = dcr_read_func;
2909 
2910 }
2911 
2912 /*-------------------------------------------------
2913     ppc4xx_set_dcr_write_handler
2914 -------------------------------------------------*/
2915 
ppc4xx_set_dcr_write_handler(write32sm_delegate dcr_write_func)2916 void ppc4xx_device::ppc4xx_set_dcr_write_handler(write32sm_delegate dcr_write_func)
2917 {
2918 	m_dcr_write_func = dcr_write_func;
2919 }
2920