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