1 // license:BSD-3-Clause
2 // copyright-holders:Sandro Ronco
3 /******************************************************************************
4 
5     Sunplus Technology S+core
6     by Sandro Ronco
7 
8     TODO:
9     - unemulated opcodes
10     - irq priority
11     - instruction cycles
12     - cache
13 
14 ******************************************************************************/
15 
16 #include "emu.h"
17 #include "debugger.h"
18 #include "score.h"
19 #include "scoredsm.h"
20 
21 
22 //**************************************************************************
23 //  CONSTANTS
24 //**************************************************************************
25 
26 DEFINE_DEVICE_TYPE(SCORE7, score7_cpu_device, "score7", "Sunplus S+core 7")
27 
28 
29 //**************************************************************************
30 //  MACROS
31 //**************************************************************************
32 
33 #include "scorem.h"
34 
35 
36 //**************************************************************************
37 //  Opcodes Tables
38 //**************************************************************************
39 
40 const score7_cpu_device::op_handler score7_cpu_device::s_opcode32_table[4*8] =
41 {
42 	&score7_cpu_device::op_specialform, &score7_cpu_device::op_iform1, &score7_cpu_device::op_jump , &score7_cpu_device::op_rixform1, &score7_cpu_device::op_branch, &score7_cpu_device::op_iform2, &score7_cpu_device::op_crform, &score7_cpu_device::op_rixform2,
43 	&score7_cpu_device::op_addri      , &score7_cpu_device::op_undef , &score7_cpu_device::op_undef, &score7_cpu_device::op_undef   , &score7_cpu_device::op_andri , &score7_cpu_device::op_orri  , &score7_cpu_device::op_undef , &score7_cpu_device::op_undef   ,
44 	&score7_cpu_device::op_lw         , &score7_cpu_device::op_lh    , &score7_cpu_device::op_lhu  , &score7_cpu_device::op_lb      , &score7_cpu_device::op_sw    , &score7_cpu_device::op_sh    , &score7_cpu_device::op_lbu   , &score7_cpu_device::op_sb      ,
45 	&score7_cpu_device::op_cache      , &score7_cpu_device::op_undef , &score7_cpu_device::op_undef, &score7_cpu_device::op_undef   , &score7_cpu_device::op_cenew , &score7_cpu_device::op_undef , &score7_cpu_device::op_undef , &score7_cpu_device::op_undef
46 };
47 
48 const score7_cpu_device::op_handler score7_cpu_device::s_opcode16_table[8] =
49 {
50 	&score7_cpu_device::op_rform1, &score7_cpu_device::op_undef, &score7_cpu_device::op_rform2, &score7_cpu_device::op_jform, &score7_cpu_device::op_branch16, &score7_cpu_device::op_ldiu, &score7_cpu_device::op_iform1a, &score7_cpu_device::op_iform1b
51 };
52 
53 
54 //**************************************************************************
55 //  LIVE DEVICE
56 //**************************************************************************
57 
58 //-------------------------------------------------
59 //  score7_cpu_device - constructor
60 //-------------------------------------------------
61 
score7_cpu_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)62 score7_cpu_device::score7_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
63 	: cpu_device(mconfig, SCORE7, tag, owner, clock)
64 	, m_program_config("program", ENDIANNESS_LITTLE, 32, 32, 0)
65 	, m_pc(0)
66 	, m_ppc(0)
67 {
68 	memset(m_gpr, 0x00, sizeof(m_gpr));
69 	memset(m_cr, 0x00, sizeof(m_cr));
70 	memset(m_sr, 0x00, sizeof(m_sr));
71 	memset(m_ce, 0x00, sizeof(m_ce));
72 }
73 
74 //-------------------------------------------------
75 //  device_start - start up the device
76 //-------------------------------------------------
77 
device_start()78 void score7_cpu_device::device_start()
79 {
80 	// find address spaces
81 	space(AS_PROGRAM).cache(m_cache);
82 	space(AS_PROGRAM).specific(m_program);
83 
84 	// set our instruction counter
85 	set_icountptr(m_icount);
86 
87 	// register state for debugger
88 	state_add(SCORE_PC  , "PC"  , m_pc).callimport().callexport().formatstr("%08X");
89 
90 	for(int i=0; i<0x20; i++)
91 		state_add(SCORE_GPR + i, string_format("r%d", i).c_str(), m_gpr[i]).callimport().callexport().formatstr("%08X");
92 
93 	for(int i=0; i<0x20; i++)
94 		state_add(SCORE_CR + i, string_format("cr%d", i).c_str(), m_cr[i]).callimport().callexport().formatstr("%08X");
95 
96 	for(int i=0; i<3; i++)
97 		state_add(SCORE_SR + i, string_format("sr%d", i).c_str(), m_sr[i]).callimport().callexport().formatstr("%08X");
98 
99 	state_add(SCORE_CEH, "ceh", REG_CEH).callimport().callexport().formatstr("%08X");
100 	state_add(SCORE_CEL, "cel", REG_CEL).callimport().callexport().formatstr("%08X");
101 
102 	state_add(STATE_GENPC, "GENPC", m_pc).formatstr("%08X").noshow();
103 	state_add(STATE_GENPCBASE, "CURPC", m_ppc).formatstr("%8X").noshow();
104 	state_add(STATE_GENFLAGS, "GENFLAGS", REG_CR).callexport().formatstr("%5s").noshow();
105 
106 	// save state
107 	save_item(NAME(m_pc));
108 	save_item(NAME(m_ppc));
109 	save_item(NAME(m_op));
110 	save_item(NAME(m_gpr));
111 	save_item(NAME(m_cr));
112 	save_item(NAME(m_sr));
113 	save_item(NAME(m_ce));
114 	save_item(NAME(m_pending_interrupt));
115 }
116 
117 
118 //-------------------------------------------------
119 //  device_reset - reset up the device
120 //-------------------------------------------------
121 
device_reset()122 void score7_cpu_device::device_reset()
123 {
124 	// GPR are undefined at reset
125 	memset(m_gpr,0, sizeof(m_gpr));
126 	memset(m_cr, 0, sizeof(m_cr));
127 	memset(m_sr, 0, sizeof(m_sr));
128 	memset(m_ce, 0, sizeof(m_ce));
129 	memset(m_pending_interrupt, 0, sizeof(m_pending_interrupt));
130 
131 	REG_EXCPVEC = m_pc = 0x9f000000;
132 }
133 
134 
135 //-------------------------------------------------
136 //  state_string_export - export state as a string
137 //  for the debugger
138 //-------------------------------------------------
139 
state_string_export(const device_state_entry & entry,std::string & str) const140 void score7_cpu_device::state_string_export(const device_state_entry &entry, std::string &str) const
141 {
142 	switch (entry.index())
143 	{
144 		case STATE_GENFLAGS:
145 			str = string_format("%s%s%s%s%s",
146 				REG_CR & FLAG_V ? "V" : ".",
147 				REG_CR & FLAG_C ? "C" : ".",
148 				REG_CR & FLAG_Z ? "Z" : ".",
149 				REG_CR & FLAG_N ? "N" : ".",
150 				REG_CR & FLAG_T ? "T" : "."
151 			);
152 			break;
153 	}
154 }
155 
156 
157 //-------------------------------------------------
158 //  memory_space_config - return the configuration
159 //  of the specified address space, or nullptr if
160 //  the space doesn't exist
161 //-------------------------------------------------
162 
memory_space_config() const163 device_memory_interface::space_config_vector score7_cpu_device::memory_space_config() const
164 {
165 	return space_config_vector {
166 		std::make_pair(AS_PROGRAM, &m_program_config)
167 	};
168 }
169 
170 
171 //-------------------------------------------------
172 //  execute - execute for the provided number of
173 //  cycles
174 //-------------------------------------------------
175 
execute_run()176 void score7_cpu_device::execute_run()
177 {
178 	do
179 	{
180 		m_ppc = m_pc;
181 		debugger_instruction_hook(m_pc);
182 
183 		check_irq();
184 
185 		uint32_t op = fetch();
186 
187 		switch(((op>>30) & 2) | ((op>>15) & 1))
188 		{
189 			case 0: // 16-bit + 16-bit instruction
190 				m_op = ((m_pc & 0x02) ? (op >> 16) : op) & 0x7fff;
191 				m_pc += 2;
192 				(this->*s_opcode16_table[(m_op >> 12) & 0x07])();
193 				break;
194 			case 1: // undefined parity bit
195 				m_pc += 4;
196 				gen_exception(EXCEPTION_P_EL);
197 				break;
198 			case 2: // parallel conditional execution
199 				m_op = (GET_T ? op: (op >> 16)) & 0x7fff;
200 				m_pc += 4;
201 				(this->*s_opcode16_table[(m_op >> 12) & 0x07])();
202 				break;
203 			case 3: // 32-bit instruction
204 				m_op = (op & 0x7fff) | ((op >> 1) & 0x3fff8000);
205 				m_pc += 4;
206 				(this->*s_opcode32_table[(m_op >> 25) & 0x01f])();
207 				break;
208 		}
209 
210 		m_icount -= 6;  // FIXME: if available use correct cycles per instructions
211 	}
212 	while (m_icount > 0);
213 }
214 
215 
216 //-------------------------------------------------
217 //  execute_set_input
218 //-------------------------------------------------
219 
execute_set_input(int inputnum,int state)220 void score7_cpu_device::execute_set_input(int inputnum, int state)
221 {
222 	if (state)
223 	{
224 		standard_irq_callback(inputnum);
225 		if (inputnum > 0 && inputnum < 64)
226 		{
227 			m_pending_interrupt[inputnum] = true;
228 		}
229 	}
230 }
231 
232 //**************************************************************************
233 //  HELPERS
234 //**************************************************************************
235 
236 
check_condition_branch(uint8_t bc)237 bool score7_cpu_device::check_condition_branch(uint8_t bc)
238 {
239 	if ((bc & 0x0f) == 14)          // CNT>0, CNT--
240 	{
241 		if (REG_CNT > 0)
242 		{
243 			REG_CNT--;
244 			return true;
245 		}
246 		return false;
247 	}
248 	else
249 		return check_condition(bc);
250 }
251 
check_condition(uint8_t bc)252 bool score7_cpu_device::check_condition(uint8_t bc)
253 {
254 	switch(bc & 0x0f)
255 	{
256 		case  0:    return GET_C;                      // carry set
257 		case  1:    return !GET_C;                     // carry clear
258 		case  2:    return GET_C && !GET_Z;            // C & ~Z
259 		case  3:    return !GET_C || GET_Z;            // ~C | Z
260 		case  4:    return GET_Z;                      // Z
261 		case  5:    return !GET_Z;                     // ~Z
262 		case  6:    return !GET_Z && (GET_N == GET_V); // (Z = 0) & (N = V)
263 		case  7:    return GET_Z || (GET_N != GET_V);  // (Z = 1) | (N != V)
264 		case  8:    return (GET_N == GET_V);           // N = V
265 		case  9:    return (GET_N != GET_V);           //  N != V
266 		case 10:    return GET_N;                      // N
267 		case 11:    return !GET_N;                     // ~N
268 		case 12:    return GET_V;                      // overflow V
269 		case 13:    return !GET_V;                     // no overflow ~V
270 		case 14:    return REG_CNT > 0;                // CNT>0
271 		case 15:    return true;                       // always
272 	}
273 
274 	return false;
275 }
276 
sign_extend(uint32_t data,uint8_t len)277 int32_t score7_cpu_device::sign_extend(uint32_t data, uint8_t len)
278 {
279 	data &= (1ULL << len) - 1;
280 	uint32_t sign = 1 << (len - 1);
281 	return (data ^ sign) - sign;
282 }
283 
fetch()284 uint32_t score7_cpu_device::fetch()
285 {
286 	return m_cache.read_dword(m_pc & ~3);
287 }
288 
read_byte(offs_t offset)289 uint8_t score7_cpu_device::read_byte(offs_t offset)
290 {
291 	return m_program.read_byte(offset);
292 }
293 
read_word(offs_t offset)294 uint16_t score7_cpu_device::read_word(offs_t offset)
295 {
296 	return m_program.read_word(offset & ~1);
297 }
298 
read_dword(offs_t offset)299 uint32_t score7_cpu_device::read_dword(offs_t offset)
300 {
301 	return m_program.read_dword(offset & ~3);
302 }
303 
write_byte(offs_t offset,uint8_t data)304 void score7_cpu_device::write_byte(offs_t offset, uint8_t data)
305 {
306 	m_program.write_byte(offset, data);
307 }
308 
write_word(offs_t offset,uint16_t data)309 void score7_cpu_device::write_word(offs_t offset, uint16_t data)
310 {
311 	m_program.write_word(offset & ~1, data);
312 }
313 
write_dword(offs_t offset,uint32_t data)314 void score7_cpu_device::write_dword(offs_t offset, uint32_t data)
315 {
316 	m_program.write_dword(offset & ~3, data);
317 }
318 
check_irq()319 void score7_cpu_device::check_irq()
320 {
321 	if(REG_PSR & 0x01)
322 	{
323 		for (int i=63; i>0; i--)
324 		{
325 			if (m_pending_interrupt[i])
326 			{
327 				m_pending_interrupt[i] = false;
328 				standard_irq_callback(i);
329 				gen_exception(EXCEPTION_INTERRUPT, i);
330 				return;
331 			}
332 		}
333 	}
334 }
335 
gen_exception(int cause,uint32_t param)336 void score7_cpu_device::gen_exception(int cause, uint32_t param)
337 {
338 	debugger_exception_hook(cause);
339 
340 	REG_ECR = (REG_ECR & ~0x0000001f) | (cause & 0x1f);              // set exception cause
341 	REG_PSR = (REG_PSR & ~0x0000000f) | ((REG_PSR << 2) & 0x0c);     // push status bits
342 	REG_CR  = (REG_CR  & ~0x000003ff) | ((REG_CR << 5) & 0x3e0);     // push flag bits
343 	REG_EPC = m_ppc & 0xfffffffe;                                    // set return address
344 
345 	switch(cause)
346 	{
347 		case EXCEPTION_P_EL:
348 			REG_EMA = REG_EPC;
349 			// intentional fallthrough
350 		case EXCEPTION_NMI:
351 		case EXCEPTION_CEE:
352 		case EXCEPTION_SYSCALL:
353 		case EXCEPTION_TRAP:
354 		case EXCEPTION_RI:
355 			m_pc = (REG_EXCPVEC & 0xffff0000) + 0x200;
356 			break;
357 
358 		case EXCEPTION_SWI:
359 		case EXCEPTION_INTERRUPT:
360 			REG_ECR = (REG_ECR & ~0x00fc0000) | ((param & 0x3f) << 18);      // set irq source
361 			m_pc = (REG_EXCPVEC & 0xffff0000) + 0x200 + (param << (REG_EXCPVEC & 1 ? 4 : 2));
362 			break;
363 
364 		case EXCEPTION_ADEL_INSTRUCTION:
365 		case EXCEPTION_BUSEL_INSTRUCTION:
366 		case EXCEPTION_CCU:
367 		case EXCEPTION_ADEL_DATA:
368 		case EXCEPTION_ADES_DATA:
369 		case EXCEPTION_CPE:
370 		case EXCEPTION_BUSEL_DATA:
371 			fatalerror("unhandled exception: %d 0x%08x (PC=0x%08x)\n", cause, param, m_ppc);
372 	}
373 }
374 
375 
376 //**************************************************************************
377 //  32-bit opcodes
378 //**************************************************************************
379 
op_specialform()380 void score7_cpu_device::op_specialform()
381 {
382 	uint8_t ra = GET_S_RA(m_op);
383 	uint8_t rb = GET_S_RB(m_op);
384 	uint8_t rd = GET_S_RD(m_op);
385 	uint8_t cu = GET_S_CU(m_op);
386 	uint32_t r;
387 
388 	switch(GET_S_FUNC6(m_op))
389 	{
390 		case 0x00:  // nop
391 			break;
392 		case 0x01:  // syscall
393 			gen_exception(EXCEPTION_SYSCALL);
394 			break;
395 		case 0x02:  // trap
396 			if (check_condition(rb))
397 				gen_exception(EXCEPTION_TRAP);
398 			break;
399 		case 0x03:  // sdbbp
400 			unemulated_op("sdbbp");
401 			break;
402 		case 0x04:  // br
403 			if (check_condition_branch(rb))
404 			{
405 				if (GET_S_LK(m_op))
406 					REG_LNK = m_pc;
407 
408 				m_pc = m_gpr[ra];
409 			}
410 			break;
411 		case 0x05: // pflush
412 			unemulated_op("pflush");
413 			break;
414 		case 0x08:  // add
415 			r = m_gpr[ra] + m_gpr[rb];
416 			if (cu)
417 			{
418 				CHECK_Z(r);
419 				CHECK_N(r);
420 				CHECK_V_ADD(m_gpr[ra], m_gpr[rb], r);
421 				CHECK_C_ADD(m_gpr[ra], m_gpr[rb]);
422 			}
423 			m_gpr[rd] = r;
424 			break;
425 		case 0x09:  // addc
426 			r = m_gpr[ra] + m_gpr[rb] + GET_C;
427 			if (cu)
428 			{
429 				CHECK_Z(r);
430 				CHECK_N(r);
431 				CHECK_V_ADD(m_gpr[ra] + GET_C, m_gpr[rb], r);
432 				CHECK_C_ADD(m_gpr[ra] + GET_C, m_gpr[rb]);
433 			}
434 			m_gpr[rd] = r;
435 			break;
436 		case 0x0a:  // sub
437 			r = m_gpr[ra] - m_gpr[rb];
438 			if (cu)
439 			{
440 				CHECK_Z(r);
441 				CHECK_N(r);
442 				CHECK_V_SUB(m_gpr[ra], m_gpr[rb], r);
443 				CHECK_C_SUB(m_gpr[ra], m_gpr[rb]);
444 			}
445 			m_gpr[rd] = r;
446 			break;
447 		case 0x0b:  // subc
448 			r = m_gpr[ra] - m_gpr[rb] - (GET_C ^ 1);
449 			if (cu)
450 			{
451 				CHECK_Z(r);
452 				CHECK_N(r);
453 				CHECK_V_SUB(m_gpr[ra] - (GET_C ^ 1), m_gpr[rb], r);
454 				CHECK_C_SUB(m_gpr[ra] - (GET_C ^ 1), m_gpr[rb]);
455 			}
456 			m_gpr[rd] = r;
457 			break;
458 		case 0x0c:  // cmp
459 			if (cu)
460 			{
461 				r = m_gpr[ra] - m_gpr[rb];
462 				CHECK_Z(r);
463 				CHECK_N(r);
464 				CHECK_V_SUB(m_gpr[ra], m_gpr[rb], r);
465 				CHECK_C_SUB(m_gpr[ra], m_gpr[rb]);
466 				switch(rd & 0x03)
467 				{
468 					case 0: SET_T(GET_Z); break;
469 					case 1: SET_T(GET_N); break;
470 				}
471 			}
472 			break;
473 		case 0x0d:  // cmpz
474 			if (cu)
475 			{
476 				r = m_gpr[ra] - 0;
477 				CHECK_Z(r);
478 				CHECK_N(r);
479 				CHECK_V_SUB(m_gpr[ra], 0, r);
480 				CHECK_C_SUB(m_gpr[ra], 0);
481 				switch(rd & 0x03)
482 				{
483 					case 0: SET_T(GET_Z); break;
484 					case 1: SET_T(GET_N); break;
485 				}
486 			}
487 			break;
488 		case 0x0f:  // neg
489 			r = 0 - m_gpr[rb];
490 			if (cu)
491 			{
492 				CHECK_Z(r);
493 				CHECK_N(r);
494 				CHECK_V_SUB(0, m_gpr[rb], r);
495 				CHECK_C_SUB(0, m_gpr[rb]);
496 			}
497 			m_gpr[rd] = r;
498 			break;
499 		case 0x10:  // and
500 			m_gpr[rd] = m_gpr[ra] & m_gpr[rb];
501 			if (cu)
502 			{
503 				CHECK_Z(m_gpr[rd]);
504 				CHECK_N(m_gpr[rd]);
505 			}
506 			break;
507 		case 0x11:  // or
508 			m_gpr[rd] = m_gpr[ra] | m_gpr[rb];
509 			if (cu)
510 			{
511 				CHECK_Z(m_gpr[rd]);
512 				CHECK_N(m_gpr[rd]);
513 			}
514 			break;
515 		case 0x12:  // not
516 			r = ~m_gpr[ra];
517 			if (cu)
518 			{
519 				CHECK_Z(r);
520 				CHECK_N(r);
521 			}
522 			m_gpr[rd] = r;
523 			break;
524 		case 0x13:  // xor
525 			m_gpr[rd] = m_gpr[ra] ^ m_gpr[rb];
526 			if (cu)
527 			{
528 				CHECK_Z(m_gpr[rd]);
529 				CHECK_N(m_gpr[rd]);
530 			}
531 			break;
532 		case 0x14:  // bitclr
533 			m_gpr[rd] = m_gpr[ra] & ~(1 << rb);
534 			if (cu)
535 			{
536 				CHECK_Z(m_gpr[rd]);
537 				CHECK_N(m_gpr[rd]);
538 			}
539 			break;
540 		case 0x15:  // bitset
541 			m_gpr[rd] = m_gpr[ra] | (1 << rb);
542 			if (cu)
543 			{
544 				CHECK_Z(m_gpr[rd]);
545 				CHECK_N(m_gpr[rd]);
546 			}
547 			break;
548 		case 0x16:  // bittst
549 			if (cu)
550 			{
551 				r = m_gpr[ra] & (1 << rb);
552 				CHECK_N(m_gpr[ra]);
553 				CHECK_Z(r);
554 			}
555 			break;
556 		case 0x17:  // bittgl
557 			m_gpr[rd] = m_gpr[ra] ^ (1 << rb);
558 			if (cu)
559 			{
560 				CHECK_Z(m_gpr[rd]);
561 				CHECK_N(m_gpr[rd]);
562 			}
563 			break;
564 		case 0x18:  // sll
565 			m_gpr[rd] = m_gpr[ra] << (m_gpr[rb] & 0x1f);
566 			if (cu)
567 			{
568 				CHECK_Z(m_gpr[rd]);
569 				CHECK_N(m_gpr[rd]);
570 				SET_C(BIT(m_gpr[ra], 32 - (m_gpr[rb] & 0x1f)));
571 			}
572 			break;
573 		case 0x1a:  // srl
574 			m_gpr[rd] = m_gpr[ra] >> (m_gpr[rb] & 0x1f);
575 			if (cu)
576 			{
577 				CHECK_Z(m_gpr[rd]);
578 				CHECK_N(m_gpr[rd]);
579 				SET_C(BIT(m_gpr[ra], (m_gpr[rb] & 0x1f) - 1));
580 			}
581 			break;
582 		case 0x1b:  // sra
583 			m_gpr[rd] = sign_extend(m_gpr[ra] >> (m_gpr[rb] & 0x1f), 32 - (m_gpr[rb] & 0x1f));
584 			if (cu)
585 			{
586 				CHECK_Z(m_gpr[rd]);
587 				CHECK_N(m_gpr[rd]);
588 				SET_C(BIT(m_gpr[ra], (m_gpr[rb] & 0x1f) - 1));
589 			}
590 			break;
591 		case 0x1c:  // ror
592 			unemulated_op("ror");
593 			break;
594 		case 0x1d:  // rorc
595 			unemulated_op("rorc");
596 			break;
597 		case 0x1e:  // rol
598 			unemulated_op("rol");
599 			break;
600 		case 0x1f:  // rolc
601 			unemulated_op("rolc");
602 			break;
603 		case 0x20:  // mul
604 		{
605 			int64_t a = (int32_t)m_gpr[ra];
606 			int64_t b = (int32_t)m_gpr[rb];
607 			uint64_t d = a * b;
608 			REG_CEL = d & 0xffffffff;
609 			REG_CEH = (d >> 32) & 0xffffffff;
610 			break;
611 		}
612 		case 0x21:  // mulu
613 		{
614 			uint64_t a = (uint32_t)m_gpr[ra];
615 			uint64_t b = (uint32_t)m_gpr[rb];
616 			uint64_t d = a * b;
617 			REG_CEL = d & 0xffffffff;
618 			REG_CEH = (d >> 32) & 0xffffffff;
619 			break;
620 		}
621 		case 0x22:  // div
622 			if (m_gpr[rb])
623 			{
624 				int32_t a = (int32_t)m_gpr[ra];
625 				int32_t b = (int32_t)m_gpr[rb];
626 				REG_CEL = a / b;
627 				REG_CEH = a % b;
628 			}
629 			else
630 			{
631 				gen_exception(EXCEPTION_CEE);   // divide by zero exception
632 			}
633 			break;
634 		case 0x23:  // divu
635 			if (m_gpr[rb])
636 			{
637 				uint32_t a = (uint32_t)m_gpr[ra];
638 				uint32_t b = (uint32_t)m_gpr[rb];
639 				REG_CEL = a / b;
640 				REG_CEH = a % b;
641 			}
642 			else
643 			{
644 				gen_exception(EXCEPTION_CEE);   // divide by zero exception
645 			}
646 			break;
647 		case 0x24:  // mfce
648 			switch(rb & 3)
649 			{
650 				case 1: m_gpr[rd] = REG_CEL;                        break;
651 				case 2: m_gpr[rd] = REG_CEH;                        break;
652 				case 3: m_gpr[rd] = REG_CEH; m_gpr[ra] = REG_CEL;   break;
653 			}
654 			break;
655 		case 0x25:  // mtce
656 			switch(rb & 3)
657 			{
658 				case 1: REG_CEL = m_gpr[rd];                        break;
659 				case 2: REG_CEH = m_gpr[rd];                        break;
660 				case 3: REG_CEH = m_gpr[rd]; REG_CEL = m_gpr[ra];   break;
661 			}
662 			break;
663 		case 0x28:  // mfsr
664 			if (rb < 3)
665 				m_gpr[rd] = m_sr[rb];
666 			break;
667 		case 0x29:  // mtsr
668 			if (rb < 3)
669 				m_sr[rb] = m_gpr[ra];
670 			break;
671 		case 0x2a:  // t
672 			SET_T(check_condition(rb));
673 			break;
674 		case 0x2b:  // mv
675 			if ((rb & 0x0f) != 14 && check_condition(rb))
676 				m_gpr[rd] = m_gpr[ra];
677 			break;
678 		case 0x2c:  // extsb
679 		case 0x2d:  // extsh
680 			m_gpr[rd] = sign_extend(m_gpr[ra], (GET_S_FUNC6(m_op) & 1) ? 16 : 8);
681 			if (cu)
682 			{
683 				CHECK_N(m_gpr[rd]);
684 				CHECK_Z(m_gpr[rd]);     // undefined
685 			}
686 			break;
687 		case 0x2e:  // extzb
688 		case 0x2f:  // extzh
689 			m_gpr[rd] = m_gpr[ra] & ((GET_S_FUNC6(m_op) & 1) ? 0xffff : 0x00ff);
690 			if (cu)
691 			{
692 				CHECK_N(m_gpr[rd]);
693 				CHECK_Z(m_gpr[rd]);     // undefined
694 			}
695 			break;
696 		case 0x30:  // lcb
697 			unemulated_op("lcb");
698 			break;
699 		case 0x31:  // lcw
700 			unemulated_op("lcw");
701 			break;
702 		case 0x33:  // lce
703 			unemulated_op("lce");
704 			break;
705 		case 0x34:  // scb
706 			unemulated_op("scb");
707 			break;
708 		case 0x35:  // scw
709 			unemulated_op("scw");
710 			break;
711 		case 0x37:  // sce
712 			unemulated_op("sce");
713 			break;
714 		case 0x38:  // slli
715 			m_gpr[rd] = m_gpr[ra] << rb;
716 			if (cu)
717 			{
718 				CHECK_Z(m_gpr[rd]);
719 				CHECK_N(m_gpr[rd]);
720 				SET_C(BIT(m_gpr[ra], 32 - rb));
721 			}
722 			break;
723 		case 0x3a:  // srli
724 			m_gpr[rd] = m_gpr[ra] >> rb;
725 			if (cu)
726 			{
727 				CHECK_Z(m_gpr[rd]);
728 				CHECK_N(m_gpr[rd]);
729 				SET_C(BIT(m_gpr[ra], rb - 1));
730 			}
731 			break;
732 		case 0x3b:  // srai
733 			m_gpr[rd] = sign_extend(m_gpr[ra] >> rb, 32 - rb);
734 			if (cu)
735 			{
736 				CHECK_Z(m_gpr[rd]);
737 				CHECK_N(m_gpr[rd]);
738 				SET_C(BIT(m_gpr[ra], rb - 1));
739 			}
740 			break;
741 		case 0x3c:  // rori
742 			unemulated_op("rori");
743 			break;
744 		case 0x3d:  // roric
745 			unemulated_op("roric");
746 			break;
747 		case 0x3e:  // roli
748 			unemulated_op("roli");
749 			break;
750 		case 0x3f:  // rolic
751 			unemulated_op("rolic");
752 			break;
753 		default:
754 			op_undef();
755 	}
756 }
757 
op_iform1()758 void score7_cpu_device::op_iform1()
759 {
760 	uint8_t rd = GET_I_RD(m_op);
761 	uint32_t imm16 = GET_I_IMM16(m_op);
762 	int32_t simm16 = sign_extend(imm16, 16);
763 	uint8_t cu = GET_I_CU(m_op);
764 	uint32_t r;
765 
766 	switch(GET_I_FUNC3(m_op))
767 	{
768 		case 0: // addi
769 			r = m_gpr[rd] + simm16;
770 			if (cu)
771 			{
772 				CHECK_Z(r);
773 				CHECK_N(r);
774 				CHECK_V_ADD(m_gpr[rd], (uint32_t)simm16, r);
775 				CHECK_C_ADD(m_gpr[rd], (uint32_t)simm16);
776 			}
777 			m_gpr[rd] = r;
778 			break;
779 		case 2: // cmpi
780 			if (cu)
781 			{
782 				r = m_gpr[rd] - simm16;
783 				CHECK_Z(r);
784 				CHECK_N(r);
785 				CHECK_V_SUB(m_gpr[rd], (uint32_t)simm16, r);
786 				CHECK_C_SUB(m_gpr[rd], (uint32_t)simm16);
787 			}
788 			break;
789 		case 4: // andi
790 			m_gpr[rd] = m_gpr[rd] & imm16;
791 			if (cu)
792 			{
793 				CHECK_Z(m_gpr[rd]);
794 				CHECK_N(m_gpr[rd]);
795 			}
796 			break;
797 		case 5: // ori
798 			m_gpr[rd] = m_gpr[rd] | imm16;
799 			if (cu)
800 			{
801 				CHECK_Z(m_gpr[rd]);
802 				CHECK_N(m_gpr[rd]);
803 			}
804 			break;
805 		case 6: // ldi
806 			m_gpr[rd] = simm16;
807 			break;
808 		default:
809 			op_undef();
810 	}
811 }
812 
op_jump()813 void score7_cpu_device::op_jump()
814 {
815 	if(GET_J_LK(m_op))
816 		REG_LNK = m_pc;
817 
818 	m_pc = (m_ppc & 0xfe000000) | (GET_J_DISP24(m_op) << 1);
819 }
820 
op_rixform1()821 void score7_cpu_device::op_rixform1()
822 {
823 	uint8_t ra = GET_RIX_RA(m_op);
824 	uint8_t rd = GET_RIX_RD(m_op);
825 
826 	// pre-increment
827 	m_gpr[ra] += sign_extend(GET_RIX_IMM12(m_op), 12);
828 
829 	switch(GET_RIX_FUNC3(m_op))
830 	{
831 		case 0: // lw
832 			m_gpr[rd] = read_dword(m_gpr[ra]);
833 			break;
834 		case 1: // lh
835 			m_gpr[rd] = sign_extend(read_word(m_gpr[ra]), 16);
836 			break;
837 		case 2: // lhu
838 			m_gpr[rd] = read_word(m_gpr[ra]);
839 			break;
840 		case 3: // lb
841 			m_gpr[rd] = sign_extend(read_byte(m_gpr[ra]), 8);
842 			break;
843 		case 4: // sw
844 			write_dword(m_gpr[ra], m_gpr[rd]);
845 			break;
846 		case 5: // sh
847 			write_word(m_gpr[ra], m_gpr[rd] & 0xffff);
848 			break;
849 		case 6: // lbu
850 			m_gpr[rd] = read_byte(m_gpr[ra]);
851 			break;
852 		case 7: // sb
853 			write_byte(m_gpr[ra], m_gpr[rd] & 0xff);
854 			break;
855 	}
856 }
857 
op_branch()858 void score7_cpu_device::op_branch()
859 {
860 	if (check_condition_branch(GET_BC_BC(m_op)))
861 	{
862 		int32_t disp = sign_extend(GET_BC_DISP19(m_op), 19) << 1;
863 		if (GET_BC_LK(m_op))
864 			REG_LNK = m_pc;
865 
866 		m_pc = m_ppc + disp;
867 	}
868 }
869 
op_iform2()870 void score7_cpu_device::op_iform2()
871 {
872 	uint8_t rd = GET_I_RD(m_op);
873 	uint32_t imm16 = GET_I_IMM16(m_op) << 16;
874 	int32_t simm16 = (int32_t)imm16;
875 	uint8_t cu = GET_I_CU(m_op);
876 	uint32_t r;
877 
878 	switch(GET_I_FUNC3(m_op))
879 	{
880 		case 0: // addis
881 			r = m_gpr[rd] + simm16;
882 			if (cu)
883 			{
884 				CHECK_Z(r);
885 				CHECK_N(r);
886 				CHECK_V_ADD(m_gpr[rd], imm16, r);
887 				CHECK_C_ADD(m_gpr[rd], imm16);
888 			}
889 			m_gpr[rd] = r;
890 			break;
891 		case 2: // cmpis
892 			if (cu)
893 			{
894 				r = m_gpr[rd] - simm16;
895 				CHECK_Z(r);
896 				CHECK_N(r);
897 				CHECK_V_SUB(m_gpr[rd], imm16, r);
898 				CHECK_C_SUB(m_gpr[rd], imm16);
899 			}
900 			break;
901 		case 4: // andis
902 			m_gpr[rd] = m_gpr[rd] & imm16;
903 			if (cu)
904 			{
905 				CHECK_Z(m_gpr[rd]);
906 				CHECK_N(m_gpr[rd]);
907 			}
908 			break;
909 		case 5: // oris
910 			m_gpr[rd] = m_gpr[rd] | imm16;
911 			if (cu)
912 			{
913 				CHECK_Z(m_gpr[rd]);
914 				CHECK_N(m_gpr[rd]);
915 			}
916 			break;
917 		case 6: // ldis
918 			m_gpr[rd] = imm16;
919 			break;
920 		default:
921 			op_undef();
922 	}
923 
924 }
925 
op_crform()926 void score7_cpu_device::op_crform()
927 {
928 	if ((REG_PSR & 0x08) && !(REG_PSR & 0x10000000))
929 		return;
930 
931 	uint8_t cr = GET_CR_CR(m_op);
932 	uint8_t rd = GET_CR_RD(m_op);
933 
934 	switch(GET_CR_OP(m_op))
935 	{
936 		case 0x00:  // mtcr
937 			m_cr[cr] = m_gpr[rd];
938 			break;
939 		case 0x01:  // mfcr
940 			m_gpr[rd] = m_cr[cr];
941 			break;
942 		case 0x84:  // rte
943 			REG_PSR = (REG_PSR & ~ 0x03) | ((REG_PSR >> 2) & 0x03);
944 			REG_CR = (REG_CR & ~0x1f) | ((REG_CR >> 5) & 0x1f);
945 			m_pc = REG_EPC;
946 			break;
947 		default:
948 			if ((GET_CR_OP(m_op) & 0xc0) == 0)
949 				fatalerror("%s: unemulated Coprocessor 0x%x (PC=0x%08x)\n", tag(), GET_CR_OP(m_op) & 0x07, m_ppc);
950 			else
951 				op_undef();
952 	}
953 }
954 
op_rixform2()955 void score7_cpu_device::op_rixform2()
956 {
957 	uint8_t ra = GET_RIX_RA(m_op);
958 	uint8_t rd = GET_RIX_RD(m_op);
959 
960 	switch(GET_RIX_FUNC3(m_op))
961 	{
962 		case 0: // lw
963 			m_gpr[rd] = read_dword(m_gpr[ra]);
964 			break;
965 		case 1: // lh
966 			m_gpr[rd] = sign_extend(read_word(m_gpr[ra]), 16);
967 			break;
968 		case 2: // lhu
969 			m_gpr[rd] = read_word(m_gpr[ra]);
970 			break;
971 		case 3: // lb
972 			m_gpr[rd] = sign_extend(read_byte(m_gpr[ra]), 8);
973 			break;
974 		case 4: // sw
975 			write_dword(m_gpr[ra], m_gpr[rd]);
976 			break;
977 		case 5: // sh
978 			write_word(m_gpr[ra], m_gpr[rd] & 0xffff);
979 			break;
980 		case 6: // lbu
981 			m_gpr[rd] = read_byte(m_gpr[ra]);
982 			break;
983 		case 7: // sb
984 			write_byte(m_gpr[ra], m_gpr[rd] & 0xff);
985 			break;
986 	}
987 
988 	// post-increment
989 	m_gpr[ra] += sign_extend(GET_RIX_IMM12(m_op), 12);
990 }
991 
op_addri()992 void score7_cpu_device::op_addri()
993 {
994 	uint8_t ra = GET_RI_RA(m_op);
995 	uint8_t rd = GET_RI_RD(m_op);
996 	int32_t simm14 = sign_extend(GET_RI_IMM14(m_op), 14);
997 	uint8_t cu = GET_RI_CU(m_op);
998 
999 	uint32_t r = m_gpr[ra] + simm14;
1000 	if (cu)
1001 	{
1002 		CHECK_Z(r);
1003 		CHECK_N(r);
1004 		CHECK_V_ADD(m_gpr[ra], (uint32_t)simm14, r);
1005 		CHECK_C_ADD(m_gpr[ra], (uint32_t)simm14);
1006 	}
1007 	m_gpr[rd] = r;
1008 }
1009 
op_andri()1010 void score7_cpu_device::op_andri()
1011 {
1012 	uint8_t ra = GET_RI_RA(m_op);
1013 	uint8_t rd = GET_RI_RD(m_op);
1014 	uint32_t imm14 = GET_RI_IMM14(m_op);
1015 
1016 	m_gpr[rd] = m_gpr[ra] & imm14;
1017 
1018 	if (GET_RI_CU(m_op))
1019 	{
1020 		CHECK_Z(m_gpr[rd]);
1021 		CHECK_N(m_gpr[rd]);
1022 	}
1023 }
1024 
op_orri()1025 void score7_cpu_device::op_orri()
1026 {
1027 	uint8_t ra = GET_RI_RA(m_op);
1028 	uint8_t rd = GET_RI_RD(m_op);
1029 	uint32_t imm14 = GET_RI_IMM14(m_op);
1030 
1031 	m_gpr[rd] = m_gpr[ra] | imm14;
1032 
1033 	if (GET_RI_CU(m_op))
1034 	{
1035 		CHECK_Z(m_gpr[rd]);
1036 		CHECK_N(m_gpr[rd]);
1037 	}
1038 }
1039 
op_lw()1040 void score7_cpu_device::op_lw()
1041 {
1042 	uint8_t rd = GET_LS_RD(m_op);
1043 	uint8_t ra = GET_LS_RA(m_op);
1044 	int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15);
1045 
1046 	m_gpr[rd] = read_dword(m_gpr[ra] + simm15);
1047 }
1048 
op_lh()1049 void score7_cpu_device::op_lh()
1050 {
1051 	uint8_t rd = GET_LS_RD(m_op);
1052 	uint8_t ra = GET_LS_RA(m_op);
1053 	int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15);
1054 
1055 	m_gpr[rd] = sign_extend(read_word(m_gpr[ra] + simm15), 16);
1056 }
1057 
op_lhu()1058 void score7_cpu_device::op_lhu()
1059 {
1060 	uint8_t rd = GET_LS_RD(m_op);
1061 	uint8_t ra = GET_LS_RA(m_op);
1062 	int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15);
1063 
1064 	m_gpr[rd] = read_word(m_gpr[ra] + simm15);
1065 }
1066 
op_lb()1067 void score7_cpu_device::op_lb()
1068 {
1069 	uint8_t rd = GET_LS_RD(m_op);
1070 	uint8_t ra = GET_LS_RA(m_op);
1071 	int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15);
1072 
1073 	m_gpr[rd] = sign_extend(read_byte(m_gpr[ra] + simm15), 8);
1074 }
1075 
op_sw()1076 void score7_cpu_device::op_sw()
1077 {
1078 	uint8_t rd = GET_LS_RD(m_op);
1079 	uint8_t ra = GET_LS_RA(m_op);
1080 	int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15);
1081 
1082 	write_dword(m_gpr[ra] + simm15, m_gpr[rd]);
1083 }
1084 
op_sh()1085 void score7_cpu_device::op_sh()
1086 {
1087 	uint8_t rd = GET_LS_RD(m_op);
1088 	uint8_t ra = GET_LS_RA(m_op);
1089 	int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15);
1090 
1091 	write_word(m_gpr[ra] + simm15, m_gpr[rd] & 0xffff);
1092 }
1093 
op_lbu()1094 void score7_cpu_device::op_lbu()
1095 {
1096 	uint8_t rd = GET_LS_RD(m_op);
1097 	uint8_t ra = GET_LS_RA(m_op);
1098 	int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15);
1099 
1100 	m_gpr[rd] = read_byte(m_gpr[ra] + simm15);
1101 }
1102 
op_sb()1103 void score7_cpu_device::op_sb()
1104 {
1105 	uint8_t rd = GET_LS_RD(m_op);
1106 	uint8_t ra = GET_LS_RA(m_op);
1107 	int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15);
1108 
1109 	write_byte(m_gpr[ra] + simm15, m_gpr[rd] & 0xff);
1110 }
1111 
op_cache()1112 void score7_cpu_device::op_cache()
1113 {
1114 	//unemulated_op("CACHE");
1115 }
1116 
op_cenew()1117 void score7_cpu_device::op_cenew()
1118 {
1119 	unemulated_op("CENew");
1120 }
1121 
1122 
1123 //**************************************************************************
1124 //  16-bit opcodes
1125 //**************************************************************************
1126 
op_rform1()1127 void score7_cpu_device::op_rform1()
1128 {
1129 	uint8_t rd = GET_R_RD(m_op);
1130 	uint8_t ra = GET_R_RA(m_op);
1131 
1132 	switch(GET_R_FUNC4(m_op))
1133 	{
1134 		case 0x00:  // nop!
1135 			break;
1136 		case 0x01:  // mlfh!
1137 			m_gpr[rd] = m_gpr[0x10 + ra];
1138 			break;
1139 		case 0x02:  // mhfl!
1140 			m_gpr[0x10 + rd] = m_gpr[ra];
1141 			break;
1142 		case 0x03:  // mv!
1143 			m_gpr[rd] = m_gpr[ra];
1144 			break;
1145 		case 0x04:  // br!
1146 			if (check_condition_branch(rd))
1147 				m_pc = m_gpr[ra];
1148 			break;
1149 		case 0x05:  // t!
1150 			SET_T(check_condition(rd));
1151 			break;
1152 		case 0x08:  // sll!
1153 			m_gpr[rd] = m_gpr[rd] << (m_gpr[ra] & 0x1f);
1154 			break;
1155 		case 0x09:  // addc!
1156 			m_gpr[rd] = m_gpr[rd] + m_gpr[ra] + GET_C;
1157 			break;
1158 		case 0x0a:  // srl!
1159 			m_gpr[rd] = m_gpr[rd] >> (m_gpr[ra] & 0x1f);
1160 			break;
1161 		case 0x0b:  // sra!
1162 			m_gpr[rd] = sign_extend(m_gpr[rd] >> (m_gpr[ra] & 0x1f), 32 - (m_gpr[ra] & 0x1f));
1163 			break;
1164 		case 0x0c:  // brl!
1165 			if (check_condition_branch(rd))
1166 			{
1167 				REG_LNK = m_pc;
1168 				m_pc = m_gpr[ra];
1169 			}
1170 			break;
1171 		default:
1172 			op_undef();
1173 	}
1174 }
1175 
op_rform2()1176 void score7_cpu_device::op_rform2()
1177 {
1178 	uint8_t rd = GET_R_RD(m_op);
1179 	uint8_t ra = GET_R_RA(m_op);
1180 	uint32_t r;
1181 
1182 	switch(GET_R_FUNC4(m_op))
1183 	{
1184 		case 0x00:  // add!
1185 			r = m_gpr[rd] + m_gpr[ra];
1186 			CHECK_Z(r);
1187 			CHECK_N(r);
1188 			CHECK_V_ADD(m_gpr[rd], m_gpr[ra], r);
1189 			CHECK_C_ADD(m_gpr[rd], m_gpr[ra]);
1190 			m_gpr[rd] = r;
1191 			break;
1192 		case 0x01:  // sub!
1193 			r = m_gpr[rd] - m_gpr[ra];
1194 			CHECK_Z(r);
1195 			CHECK_N(r);
1196 			CHECK_V_SUB(m_gpr[rd], m_gpr[ra], r);
1197 			CHECK_C_SUB(m_gpr[rd], m_gpr[ra]);
1198 			m_gpr[rd] = r;
1199 			break;
1200 		case 0x02:  // neg!
1201 			m_gpr[rd] = 0 - m_gpr[ra];
1202 			CHECK_Z(m_gpr[rd]);
1203 			CHECK_N(m_gpr[rd]);
1204 			CHECK_V_SUB(0, m_gpr[ra], m_gpr[rd]);
1205 			CHECK_C_SUB(0, m_gpr[ra]);
1206 			break;
1207 		case 0x03:  // cmp!
1208 			r = m_gpr[rd] - m_gpr[ra];
1209 			CHECK_Z(r);
1210 			CHECK_N(r);
1211 			CHECK_V_SUB(m_gpr[rd], m_gpr[ra], r);
1212 			CHECK_C_SUB(m_gpr[rd], m_gpr[ra]);
1213 			break;
1214 		case 0x04:  // and!
1215 			m_gpr[rd] &= m_gpr[ra];
1216 			CHECK_Z(m_gpr[rd]);
1217 			CHECK_N(m_gpr[rd]);
1218 			break;
1219 		case 0x05:  // or!
1220 			m_gpr[rd] |= m_gpr[ra];
1221 			CHECK_Z(m_gpr[rd]);
1222 			CHECK_N(m_gpr[rd]);
1223 			break;
1224 		case 0x06:  // not!
1225 			m_gpr[rd] = ~m_gpr[ra];
1226 			CHECK_Z(m_gpr[rd]);
1227 			CHECK_N(m_gpr[rd]);
1228 			break;
1229 		case 0x07:  // xor!
1230 			m_gpr[rd] ^= m_gpr[ra];
1231 			CHECK_Z(m_gpr[rd]);
1232 			CHECK_N(m_gpr[rd]);
1233 			break;
1234 		case 0x08:  // lw!
1235 			m_gpr[rd] = read_dword(m_gpr[ra]);
1236 			break;
1237 		case 0x09:  // lh!
1238 			m_gpr[rd] = sign_extend(read_word(m_gpr[ra]), 16);
1239 			break;
1240 		case 0x0a:  // pop!
1241 			m_gpr[GET_P_RDG(m_op)] = read_dword(m_gpr[GET_P_RAG(m_op)]);
1242 			m_gpr[GET_P_RAG(m_op)] += 0x04;
1243 			break;
1244 		case 0x0b:  // lbu!
1245 			m_gpr[rd] = read_byte(m_gpr[ra]);
1246 			break;
1247 		case 0x0c:  // sw!
1248 			write_dword(m_gpr[ra], m_gpr[rd]);
1249 			break;
1250 		case 0x0d:  // sh!
1251 			write_word(m_gpr[ra], m_gpr[rd] & 0xffff);
1252 			break;
1253 		case 0x0e:  // push
1254 			m_gpr[GET_P_RAG(m_op)] -= 0x04;
1255 			write_dword(m_gpr[GET_P_RAG(m_op)], m_gpr[GET_P_RDG(m_op)]);
1256 			break;
1257 		case 0x0f:  // sb!
1258 			write_byte(m_gpr[ra], m_gpr[rd] & 0xff);
1259 			break;
1260 	}
1261 }
1262 
op_jform()1263 void score7_cpu_device::op_jform()
1264 {
1265 	if(GET_J_LK(m_op))
1266 		REG_LNK = m_pc;
1267 
1268 	m_pc = (m_ppc & 0xfffff000) | (GET_J_DISP11(m_op) << 1);
1269 }
1270 
op_branch16()1271 void score7_cpu_device::op_branch16()
1272 {
1273 	if(check_condition_branch(GET_BX_EC(m_op)))
1274 		m_pc = m_ppc + (sign_extend(GET_BX_DISP8(m_op), 8) << 1);
1275 }
1276 
op_ldiu()1277 void score7_cpu_device::op_ldiu()
1278 {
1279 	m_gpr[GET_I2_RD(m_op)] = GET_I2_IMM8(m_op);
1280 }
1281 
op_iform1a()1282 void score7_cpu_device::op_iform1a()
1283 {
1284 	uint8_t rd = GET_I16_RD(m_op);
1285 	uint8_t imm5 = GET_I16_IMM5(m_op);
1286 
1287 	switch(GET_I16_FUNC3(m_op))
1288 	{
1289 		case 0x00:  // addei!
1290 			if (imm5 & 0x10)
1291 				m_gpr[rd] -= 1 << (imm5 & 0xf);
1292 			else
1293 				m_gpr[rd] += 1 << (imm5 & 0xf);
1294 
1295 			// condition flags are invalid after this instruction
1296 			break;
1297 		case 0x01:  // slli!
1298 			m_gpr[rd] <<= imm5;
1299 			CHECK_Z(m_gpr[rd]);
1300 			CHECK_N(m_gpr[rd]);
1301 			break;
1302 		case 0x02:  // sdbbp!
1303 			unemulated_op("sdbbp!");
1304 			break;
1305 		case 0x03:  // srli!
1306 			m_gpr[rd] >>= imm5;
1307 			CHECK_Z(m_gpr[rd]);
1308 			CHECK_N(m_gpr[rd]);
1309 			break;
1310 		case 0x04:  // bitclr!
1311 			m_gpr[rd] &= ~(1 << imm5);
1312 			CHECK_Z(m_gpr[rd]);
1313 			CHECK_N(m_gpr[rd]);
1314 			break;
1315 		case 0x05:  // bitset!
1316 			m_gpr[rd] |= (1 << imm5);
1317 			CHECK_Z(m_gpr[rd]);
1318 			CHECK_N(m_gpr[rd]);
1319 			break;
1320 		case 0x06:  // bittst!
1321 			CHECK_N(m_gpr[rd]);
1322 			CHECK_Z(m_gpr[rd] & (1 << imm5));
1323 			break;
1324 		default:
1325 			op_undef();
1326 	}
1327 }
1328 
op_iform1b()1329 void score7_cpu_device::op_iform1b()
1330 {
1331 	uint8_t rd = GET_I16_RD(m_op);
1332 	uint16_t imm5 = GET_I16_IMM5(m_op);
1333 
1334 	switch(GET_I16_FUNC3(m_op))
1335 	{
1336 		case 0x00:  // lwp!
1337 			m_gpr[rd] = read_dword(REG_BP + (imm5<<2));
1338 			break;
1339 		case 0x01:  // lhp!
1340 			m_gpr[rd] = sign_extend(read_word(REG_BP + (imm5<<1)), 16);
1341 			break;
1342 		case 0x03:  // lbup!
1343 			m_gpr[rd] = read_byte(REG_BP + imm5);
1344 			break;
1345 		case 0x04:  // swp!
1346 			write_dword(REG_BP + (imm5<<2), m_gpr[rd]);
1347 			break;
1348 		case 0x05:  // shp!
1349 			write_word(REG_BP + (imm5<<1), m_gpr[rd] & 0xffff);
1350 			break;
1351 		case 0x07:  // sbp!
1352 			write_byte(REG_BP + imm5, m_gpr[rd] & 0xff);
1353 			break;
1354 		default:
1355 			op_undef();
1356 	}
1357 }
1358 
op_undef()1359 void score7_cpu_device::op_undef()
1360 {
1361 	logerror("%s: undefined instruction 0x%x (PC=0x%08x)\n", tag(), m_op, m_ppc);
1362 	gen_exception(EXCEPTION_RI);
1363 }
1364 
unemulated_op(const char * op)1365 void score7_cpu_device::unemulated_op(const char * op)
1366 {
1367 	fatalerror("%s: unemulated %s (PC=0x%08x)\n", tag(), op, m_ppc);
1368 }
1369 
create_disassembler()1370 std::unique_ptr<util::disasm_interface> score7_cpu_device::create_disassembler()
1371 {
1372 	return std::make_unique<score7_disassembler>();
1373 }
1374