1 /********************************************************************
2 Hyperstone cpu emulator
3 written by Pierpaolo Prazzoli
4
5 All the types are compatible, but they have different IRAM size and cycles
6
7 Hyperstone models:
8
9 16 bits
10 - E1-16T
11 - E1-16XT
12 - E1-16XS
13 - E1-16XSR
14
15 32bits
16 - E1-32N or E1-32T
17 - E1-32XN or E1-32XT
18 - E1-32XS
19 - E1-32XSR
20
21 Hynix models:
22
23 16 bits
24 - GMS30C2116
25 - GMS30C2216
26
27 32bits
28 - GMS30C2132
29 - GMS30C2232
30
31 TODO:
32 - some wrong cycle counts
33
34 CHANGELOG:
35
36 Pierpaolo Prazzoli
37 - Fixed LDxx.N/P/S opcodes not to increment the destination register when
38 it's the same as the source or "next source" one.
39
40 Pierpaolo Prazzoli
41 - Removed nested delays
42 - Added better delay branch support
43 - Fixed PC seen by a delay instruction, because a delay instruction
44 should use the delayed PC (thus allowing the execution of software
45 opcodes too)
46
47 Tomasz Slanina
48 - Fixed delayed branching for delay instructions longer than 2 bytes
49
50 Pierpaolo Prazzoli
51 - Added and fixed Timer without hack
52
53 Tomasz Slanina
54 - Fixed MULU/MULS
55 - Fixed Carry in ADDC/SUBC
56
57 Pierpaolo Prazzoli
58 - Fixed software opcodes used as delay instructions
59 - Added nested delays
60
61 Tomasz Slanina
62 - Added "undefined" C flag to shift left instructions
63
64 Pierpaolo Prazzoli
65 - Added interrupts-block for delay instructions
66 - Fixed get_emu_code_addr
67 - Added LDW.S and STW.S instructions
68 - Fixed floating point opcodes
69
70 Tomasz Slanina
71 - interrputs after call and before frame are prohibited now
72 - emulation of FCR register
73 - Floating point opcodes (preliminary)
74 - Fixed stack addressing in RET/FRAME opcodes
75 - Fixed bug in SET_RS macro
76 - Fixed bug in return opcode (S flag)
77 - Added C/N flags calculation in add/adc/addi/adds/addsi and some shift opcodes
78 - Added writeback to ROL
79 - Fixed ROL/SAR/SARD/SHR/SHRD/SHL/SHLD opcode decoding (Local/Global regs)
80 - Fixed I and T flag in RET opcode
81 - Fixed XX/XM opcodes
82 - Fixed MOV opcode, when RD = PC
83 - Fixed execute_trap()
84 - Fixed ST opcodes, when when RS = SR
85 - Added interrupts
86 - Fixed I/O addressing
87
88 Pierpaolo Prazzoli
89 - Fixed fetch
90 - Fixed decode of hyperstone_xm opcode
91 - Fixed 7 bits difference number in FRAME / RET instructions
92 - Some debbugger fixes
93 - Added generic registers decode function
94 - Some other little fixes.
95
96 MooglyGuy 29/03/2004
97 - Changed MOVI to use unsigned values instead of signed, correcting
98 an ugly glitch when loading 32-bit immediates.
99 Pierpaolo Prazzoli
100 - Same fix in get_const
101
102 MooglyGuy - 02/27/04
103 - Fixed delayed branching
104 - const_val for CALL should always have bit 0 clear
105
106 Pierpaolo Prazzoli - 02/25/04
107 - Fixed some wrong addresses to address local registers instead of memory
108 - Fixed FRAME and RET instruction
109 - Added preliminary I/O space
110 - Fixed some load / store instructions
111
112 Pierpaolo Prazzoli - 02/20/04
113 - Added execute_exception function
114 - Added FL == 0 always interpreted as 16
115
116 Pierpaolo Prazzoli - 02/19/04
117 - Changed the reset to use the execute_trap(reset) which should be right to set
118 the initiale state of the cpu
119 - Added Trace exception
120 - Set of T flag in RET instruction
121 - Set I flag in interrupts entries and resetted by a RET instruction
122 - Added correct set instruction for SR
123
124 Pierpaolo Prazzoli - 10/26/03
125 - Changed get_lrconst to get_const and changed it to use the removed GET_CONST_RR
126 macro.
127 - Removed the High flag used in some opcodes, it should be used only in
128 MOV and MOVI instruction.
129 - Fixed MOV and MOVI instruction.
130 - Set to 1 FP is SR register at reset.
131 (From the doc: A Call, Trap or Software instruction increments the FP and sets FL
132 to 6, thus creating a new stack frame with the length of 6 registers).
133
134 MooglyGuy - 10/25/03
135 - Fixed CALL enough that it at least jumps to the right address, no word
136 yet as to whether or not it's working enough to return.
137 - Added get_lrconst() to get the const value for the CALL operand, since
138 apparently using immediate_value() was wrong. The code is ugly, but it
139 works properly. Vampire 1/2 now gets far enough to try to test its RAM.
140 - Just from looking at it, CALL apparently doesn't frame properly. I'm not
141 sure about FRAME, but perhaps it doesn't work properly - I'm not entirely
142 positive. The return address when vamphalf's memory check routine is
143 called at FFFFFD7E is stored in register L8, and then the RET instruction
144 at the end of the routine uses L1 as the return address, so that might
145 provide some clues as to how it works.
146 - I'd almost be willing to bet money that there's no framing at all since
147 the values in L0 - L15 as displayed by the debugger would change during a
148 CALL or FRAME operation. I'll look when I'm in the mood.
149 - The mood struck me, and I took a look at SET_L_REG and GET_L_REG.
150 Apparently no matter what the current frame pointer is they'll always use
151 local_regs[0] through local_regs[15].
152
153 MooglyGuy - 08/20/03
154 - Added H flag support for MOV and MOVI
155 - Changed init routine to set S flag on boot. Apparently the CPU defaults to
156 supervisor mode as opposed to user mode when it powers on, as shown by the
157 vamphalf power-on routines. Makes sense, too, since if the machine booted
158 in user mode, it would be impossible to get into supervisor mode.
159
160 Pierpaolo Prazzoli - 08/19/03
161 - Added check for D_BIT and S_BIT where PC or SR must or must not be denoted.
162 (movd, divu, divs, ldxx1, ldxx2, stxx1, stxx2, mulu, muls, set, mul
163 call, chk)
164
165 MooglyGuy - 08/17/03
166 - Working on support for H flag, nothing quite done yet
167 - Added trap Range Error for CHK PC, PC
168 - Fixed relative jumps, they have to be taken from the opcode following the
169 jump minstead of the jump opcode itself.
170
171 Pierpaolo Prazzoli - 08/17/03
172 - Fixed get_pcrel() when OP & 0x80 is set.
173 - Decremented PC by 2 also in MOV, ADD, ADDI, SUM, SUB and added the check if
174 D_BIT is not set. (when pc is changed they are implicit branch)
175
176 MooglyGuy - 08/17/03
177 - Implemented a crude hack to set FL in the SR to 6, since according to the docs
178 that's supposed to happen each time a trap occurs, apparently including when
179 the processor starts up. The 3rd opcode executed in vamphalf checks to see if
180 the FL flag in SR 6, so it's apparently the "correct" behaviour despite the
181 docs not saying anything on it. If FL is not 6, the branch falls through and
182 encounters a CHK PC, L2, which at that point will always throw a range trap.
183 The range trap vector contains 00000000 (CHK PC, PC), which according to the
184 docs will always throw a range trap (which would effectively lock the system).
185 This revealed a bug: CHK PC, PC apparently does not throw a range trap, which
186 needs to be fixed. Now that the "correct" behaviour is hacked in with the FL
187 flags, it reveals yet another bug in that the branch is interpreted as being
188 +0x8700. This means that the PC then wraps around to 000082B0, give or take
189 a few bytes. While it does indeed branch to valid code, I highly doubt that
190 this is the desired effect. Check for signed/unsigned relative branch, maybe?
191
192 MooglyGuy - 08/16/03
193 - Fixed the debugger at least somewhat so that it displays hex instead of decimal,
194 and so that it disassembles opcodes properly.
195 - Fixed hyperstone_execute() to increment PC *after* executing the opcode instead of
196 before. This is probably why vamphalf was booting to fffffff8, but executing at
197 fffffffa instead.
198 - Changed execute_trap to decrement PC by 2 so that the next opcode isn't skipped
199 after a trap
200 - Changed execute_br to decrement PC by 2 so that the next opcode isn't skipped
201 after a branch
202 - Changed hyperstone_movi to decrement PC by 2 when G0 (PC) is modified so that the
203 next opcode isn't skipped after a branch
204 - Changed hyperstone_movi to default to a UINT32 being moved into the register
205 as opposed to a UINT8. This is wrong, the bit width is quite likely to be
206 dependent on the n field in the Rimm instruction type. However, vamphalf uses
207 MOVI G0,[FFFF]FBAC (n=$13) since there's apparently no absolute branch opcode.
208 What kind of CPU is this that it doesn't have an absolute jump in its branch
209 instructions and you have to use an immediate MOV to do an abs. jump!?
210 - Replaced usage of logerror() with smf's verboselog()
211
212 *********************************************************************/
213
214 #include "burnint.h"
215 #include "e132xs.h"
216 #include "e132xs_intf.h"
217
218 static UINT8 *mem[2][0x100000];
219
220 static void (*write_byte_handler)(UINT32,UINT8);
221 static void (*write_word_handler)(UINT32,UINT16);
222 static void (*write_dword_handler)(UINT32,UINT32);
223 static UINT8 (*read_byte_handler)(UINT32);
224 static UINT16 (*read_word_handler)(UINT32);
225 static UINT32 (*read_dword_handler)(UINT32);
226
227 static void (*io_write_dword_handler)(UINT32,UINT32);
228 static UINT32 (*io_read_dword_handler)(UINT32);
229
E132XSSetWriteByteHandler(void (* handler)(UINT32,UINT8))230 void E132XSSetWriteByteHandler(void (*handler)(UINT32,UINT8))
231 {
232 write_byte_handler = handler;
233 }
234
E132XSSetWriteWordHandler(void (* handler)(UINT32,UINT16))235 void E132XSSetWriteWordHandler(void (*handler)(UINT32,UINT16))
236 {
237 write_word_handler = handler;
238 }
239
E132XSSetWriteLongHandler(void (* handler)(UINT32,UINT32))240 void E132XSSetWriteLongHandler(void (*handler)(UINT32,UINT32))
241 {
242 write_dword_handler = handler;
243 }
244
E132XSSetReadByteHandler(UINT8 (* handler)(UINT32))245 void E132XSSetReadByteHandler(UINT8 (*handler)(UINT32))
246 {
247 read_byte_handler = handler;
248 }
249
E132XSSetReadWordHandler(UINT16 (* handler)(UINT32))250 void E132XSSetReadWordHandler(UINT16 (*handler)(UINT32))
251 {
252 read_word_handler = handler;
253 }
254
E132XSSetReadLongHandler(UINT32 (* handler)(UINT32))255 void E132XSSetReadLongHandler(UINT32 (*handler)(UINT32))
256 {
257 read_dword_handler = handler;
258 }
259
E132XSSetIOWriteHandler(void (* handler)(UINT32,UINT32))260 void E132XSSetIOWriteHandler(void (*handler)(UINT32,UINT32))
261 {
262 io_write_dword_handler = handler;
263 }
264
E132XSSetIOReadHandler(UINT32 (* handler)(UINT32))265 void E132XSSetIOReadHandler(UINT32 (*handler)(UINT32))
266 {
267 io_read_dword_handler = handler;
268 }
269
E132XSMapMemory(UINT8 * ptr,UINT32 start,UINT32 end,INT32 flags)270 void E132XSMapMemory(UINT8 *ptr, UINT32 start, UINT32 end, INT32 flags)
271 {
272 start >>= 12;
273 end >>= 12;
274
275 for (UINT32 i = 0; i < (end - start) + 1; i++)
276 {
277 if (flags & MAP_READ) mem[0][start + i] = (ptr == NULL) ? NULL : (ptr + (i << 12));
278 if (flags & MAP_WRITE) mem[1][start + i] = (ptr == NULL) ? NULL : (ptr + (i << 12));
279 }
280 }
281
program_read_byte_16be(UINT32 address)282 static UINT8 program_read_byte_16be(UINT32 address)
283 {
284 // bprintf (0, _T("RB: %8.8x\n"), address);
285
286 UINT8 *ptr = mem[0][address >> 12];
287
288 if (ptr) {
289 return ptr[(address & 0xfff)^1];
290 }
291
292 if (read_byte_handler) {
293 return read_byte_handler(address);
294 }
295
296 return 0;
297 }
298
program_read_word_16be(UINT32 address)299 static UINT16 program_read_word_16be(UINT32 address)
300 {
301 // bprintf (0, _T("RW: %8.8x\n"), address);
302
303 UINT8 *ptr = mem[0][address >> 12];
304
305 if (ptr) {
306 return BURN_ENDIAN_SWAP_INT16(*((UINT16*)(ptr + (address & 0xffe))));
307 }
308
309 if (read_word_handler) {
310 return read_word_handler(address);
311 }
312
313 return 0;
314 }
315
program_read_dword_32be(UINT32 address)316 static UINT32 program_read_dword_32be(UINT32 address)
317 {
318 // bprintf (0, _T("RL: %8.8x\n"), address);
319
320 UINT8 *ptr = mem[0][address >> 12];
321
322 if (ptr) {
323 UINT32 ret = *((UINT32*)(ptr + (address & 0xffe))); // word aligned
324 return BURN_ENDIAN_SWAP_INT32((ret << 16) | (ret >> 16));
325 }
326
327 if (read_dword_handler) {
328 return read_dword_handler(address);
329 }
330
331 return 0;
332 }
333
cpu_readop16(UINT32 address)334 static UINT16 cpu_readop16(UINT32 address)
335 {
336 // bprintf (0, _T("RO: %8.8x\n"), address);
337
338 UINT8 *ptr = mem[0][address >> 12];
339
340 if (ptr) {
341 return BURN_ENDIAN_SWAP_INT16(*((UINT16*)(ptr + (address & 0xffe))));
342 }
343
344 if (read_word_handler) {
345 return read_word_handler(address);
346 }
347
348 return 0;
349 }
350
program_write_byte_16be(UINT32 address,UINT8 data)351 static void program_write_byte_16be(UINT32 address, UINT8 data)
352 {
353 // bprintf (0, _T("WB: %8.8x, %2.2x\n"), address, data);
354
355 UINT8 *ptr = mem[1][address >> 12];
356
357 if (ptr) {
358 ptr[(address & 0xfff)^1] = data;
359 return;
360 }
361
362 if (write_byte_handler) {
363 write_byte_handler(address, data);
364 }
365 }
366
program_write_word_16be(UINT32 address,UINT16 data)367 static void program_write_word_16be(UINT32 address, UINT16 data)
368 {
369 // bprintf (0, _T("WW: %8.8x, %4.4x\n"), address, data);
370
371 UINT8 *ptr = mem[1][address >> 12];
372
373 if (ptr) {
374 *((UINT16*)(ptr + (address & 0xffe))) = BURN_ENDIAN_SWAP_INT16(data);
375 return;
376 }
377
378 if (write_word_handler) {
379 write_word_handler(address, data);
380 }
381 }
382
program_write_dword_32be(UINT32 address,UINT32 data)383 static void program_write_dword_32be(UINT32 address, UINT32 data)
384 {
385 // bprintf (0, _T("WL: %8.8x, %8.8x\n"), address, data);
386
387 UINT8 *ptr = mem[1][address >> 12];
388
389 if (ptr) {
390 data = (data << 16) | (data >> 16);
391 *((UINT32*)(ptr + (address & 0xffe))) = BURN_ENDIAN_SWAP_INT32(data); // word aligned!
392 return;
393 }
394
395 if (write_dword_handler) {
396 write_dword_handler(address, data);
397 }
398 }
399
io_write_dword_32be(UINT32 address,UINT32 data)400 static void io_write_dword_32be(UINT32 address, UINT32 data)
401 {
402 // bprintf (0, _T("IOL32: %8.8x %8.8x\n"), address,data);
403
404 if (io_write_dword_handler) {
405 io_write_dword_handler(address, data);
406 return;
407 }
408 }
409
io_read_dword_32be(UINT32 address)410 static UINT32 io_read_dword_32be(UINT32 address)
411 {
412 // bprintf (0, _T("IORL32: %8.8x\n"), address);
413
414 if (io_read_dword_handler) {
415 return io_read_dword_handler(address);
416 }
417
418 return 0;
419 }
420
421 #define CONCAT_64(A, B) ((((UINT64)(A))<<32) | (UINT32)(B))
422 #define EXTRACT_64HI(A) (((UINT64)(A)) >> 32)
423 #define EXTRACT_64LO(A) ((A) & 0xffffffff)
424
mulu_32x32(UINT32 a,UINT32 b)425 static UINT64 mulu_32x32(UINT32 a, UINT32 b)
426 {
427 return (UINT64)(((UINT64)a) * ((UINT64)b));
428 }
429
430 #ifdef MAME_DEBUG
431 #define DEBUG_PRINTF(x) do { osd_printf_debug x; } while (0)
432 #else
433 #define DEBUG_PRINTF(x) do { } while (0)
434 #endif
435
436 // set C in adds/addsi/subs/sums
437 #define SETCARRYS 0
438 #define MISSIONCRAFT_FLAGS 1
439
440 /* Registers */
441
442 /* Internal registers */
443
444 #define SREG (decode)->src_value
445 #define SREGF (decode)->next_src_value
446 #define DREG (decode)->dst_value
447 #define DREGF (decode)->next_dst_value
448 #define EXTRA_U (decode)->extra.u
449 #define EXTRA_S (decode)->extra.s
450
451 #define SET_SREG( _data_ ) ((decode)->src_is_local ? set_local_register((decode)->src, (UINT32)_data_) : set_global_register((decode)->src, (UINT32)_data_))
452 #define SET_SREGF( _data_ ) ((decode)->src_is_local ? set_local_register((decode)->src + 1, (UINT32)_data_) : set_global_register((decode)->src + 1, (UINT32)_data_))
453 #define SET_DREG( _data_ ) ((decode)->dst_is_local ? set_local_register((decode)->dst, (UINT32)_data_) : set_global_register((decode)->dst, (UINT32)_data_))
454 #define SET_DREGF( _data_ ) ((decode)->dst_is_local ? set_local_register((decode)->dst + 1, (UINT32)_data_) : set_global_register((decode)->dst + 1, (UINT32)_data_))
455
456 #define SRC_IS_PC (!(decode)->src_is_local && (decode)->src == PC_REGISTER)
457 #define DST_IS_PC (!(decode)->dst_is_local && (decode)->dst == PC_REGISTER)
458 #define SRC_IS_SR (!(decode)->src_is_local && (decode)->src == SR_REGISTER)
459 #define DST_IS_SR (!(decode)->dst_is_local && (decode)->dst == SR_REGISTER)
460 #define SAME_SRC_DST (decode)->same_src_dst
461 #define SAME_SRC_DSTF (decode)->same_src_dstf
462 #define SAME_SRCF_DST (decode)->same_srcf_dst
463
464 /* Delay information */
465 struct delay_info
466 {
467 INT32 delay_cmd;
468 UINT32 delay_pc;
469 };
470
471 // CPU registers
472 static UINT32 m_global_regs[32];
473 static UINT32 m_local_regs[64];
474
475 static UINT8 internal_ram[0x4000];
476
477 /* internal stuff */
478 static UINT32 m_ppc; // previous pc
479 static UINT16 m_op; // opcode
480 static UINT32 m_trap_entry; // entry point to get trap address
481
482 static UINT8 m_clock_scale_mask;
483 static UINT8 m_clock_scale;
484 static UINT8 m_clock_cycles_1;
485 static UINT8 m_clock_cycles_2;
486 static UINT8 m_clock_cycles_4;
487 static UINT8 m_clock_cycles_6;
488
489 static UINT64 m_tr_base_cycles;
490 static UINT32 m_tr_base_value;
491 static UINT32 m_tr_clocks_per_tick;
492 static UINT8 m_timer_int_pending;
493
494 static INT32 timer_time;
495 static INT32 timer_param;
496 static INT32 m_hold_irq;
497
498 static delay_info m_delay;
499
500 static INT32 m_instruction_length;
501 static INT32 m_intblock;
502
503 // other internal state
504 static int m_icount;
505 static UINT64 itotal_cycles; // internal total cycles (timers etc)
506 static UINT64 utotal_cycles; // user-total cycles (E132XSTotalCycles() / E132XSNewFrame() etc..)
507 static INT32 n_cycles;
508 static INT32 sleep_until_int;
509
510 struct regs_decode
511 {
512 UINT8 src, dst; // destination and source register code
513 UINT32 src_value; // current source register value
514 UINT32 next_src_value; // current next source register value
515 UINT32 dst_value; // current destination register value
516 UINT32 next_dst_value; // current next destination register value
517 UINT8 sub_type; // sub type opcode (for DD and X_CODE bits)
518 union
519 {
520 UINT32 u;
521 INT32 s;
522 } extra; // extra value such as immediate value, const, pcrel, ...
523 UINT8 src_is_local;
524 UINT8 dst_is_local;
525 UINT8 same_src_dst;
526 UINT8 same_src_dstf;
527 UINT8 same_srcf_dst;
528 };
529
530 /* Return the entry point for a determinated trap */
get_trap_addr(UINT8 trapno)531 static UINT32 get_trap_addr(UINT8 trapno)
532 {
533 UINT32 addr;
534 if( m_trap_entry == 0xffffff00 ) /* @ MEM3 */
535 {
536 addr = trapno * 4;
537 }
538 else
539 {
540 addr = (63 - trapno) * 4;
541 }
542 addr |= m_trap_entry;
543
544 return addr;
545 }
546
547 /* Return the entry point for a determinated emulated code (the one for "extend" opcode is reserved) */
get_emu_code_addr(UINT8 num)548 static UINT32 get_emu_code_addr(UINT8 num) /* num is OP */
549 {
550 UINT32 addr;
551 if( m_trap_entry == 0xffffff00 ) /* @ MEM3 */
552 {
553 addr = (m_trap_entry - 0x100) | ((num & 0xf) << 4);
554 }
555 else
556 {
557 addr = m_trap_entry | (0x10c | ((0xcf - num) << 4));
558 }
559 return addr;
560 }
561
hyperstone_set_trap_entry(int which)562 static void hyperstone_set_trap_entry(int which)
563 {
564 switch( which )
565 {
566 case E132XS_ENTRY_MEM0:
567 m_trap_entry = 0x00000000;
568 break;
569
570 case E132XS_ENTRY_MEM1:
571 m_trap_entry = 0x40000000;
572 break;
573
574 case E132XS_ENTRY_MEM2:
575 m_trap_entry = 0x80000000;
576 break;
577
578 case E132XS_ENTRY_MEM3:
579 m_trap_entry = 0xffffff00;
580 break;
581
582 case E132XS_ENTRY_IRAM:
583 m_trap_entry = 0xc0000000;
584 break;
585
586 default:
587 DEBUG_PRINTF(("Set entry point to a reserved value: %d\n", which));
588 break;
589 }
590 }
591
592 #define OP m_op
593 #define PPC m_ppc //previous pc
594 #define PC m_global_regs[0] //Program Counter
595 #define SR m_global_regs[1] //Status Register
596 #define FER m_global_regs[2] //Floating-Point Exception Register
597 // 03 - 15 General Purpose Registers
598 // 16 - 17 Reserved
599 #define SP m_global_regs[18] //Stack Pointer
600 #define UB m_global_regs[19] //Upper Stack Bound
601 #define BCR m_global_regs[20] //Bus Control Register
602 #define TPR m_global_regs[21] //Timer Prescaler Register
603 #define TCR m_global_regs[22] //Timer Compare Register
604 #define TR compute_tr() //Timer Register
605 #define WCR m_global_regs[24] //Watchdog Compare Register
606 #define ISR m_global_regs[25] //Input Status Register
607 #define FCR m_global_regs[26] //Function Control Register
608 #define MCR m_global_regs[27] //Memory Control Register
609 // 28 - 31 Reserved
610
611 /* SR flags */
612 #define GET_C ( SR & 0x00000001) // bit 0 //CARRY
613 #define GET_Z ((SR & 0x00000002)>>1) // bit 1 //ZERO
614 #define GET_N ((SR & 0x00000004)>>2) // bit 2 //NEGATIVE
615 #define GET_V ((SR & 0x00000008)>>3) // bit 3 //OVERFLOW
616 #define GET_M ((SR & 0x00000010)>>4) // bit 4 //CACHE-MODE
617 #define GET_H ((SR & 0x00000020)>>5) // bit 5 //HIGHGLOBAL
618 // bit 6 RESERVED (always 0)
619 #define GET_I ((SR & 0x00000080)>>7) // bit 7 //INTERRUPT-MODE
620 #define GET_FTE ((SR & 0x00001f00)>>8) // bits 12 - 8 //Floating-Point Trap Enable
621 #define GET_FRM ((SR & 0x00006000)>>13) // bits 14 - 13 //Floating-Point Rounding Mode
622 #define GET_L ((SR & 0x00008000)>>15) // bit 15 //INTERRUPT-LOCK
623 #define GET_T ((SR & 0x00010000)>>16) // bit 16 //TRACE-MODE
624 #define GET_P ((SR & 0x00020000)>>17) // bit 17 //TRACE PENDING
625 #define GET_S ((SR & 0x00040000)>>18) // bit 18 //SUPERVISOR STATE
626 #define GET_ILC ((SR & 0x00180000)>>19) // bits 20 - 19 //INSTRUCTION-LENGTH
627 /* if FL is zero it is always interpreted as 16 */
628 #define GET_FL ((SR & 0x01e00000) ? ((SR & 0x01e00000)>>21) : 16) // bits 24 - 21 //FRAME LENGTH
629 #define GET_FP ((SR & 0xfe000000)>>25) // bits 31 - 25 //FRAME POINTER
630
631 #define SET_C(val) (SR = (SR & ~0x00000001) | (val))
632 #define SET_Z(val) (SR = (SR & ~0x00000002) | ((val) << 1))
633 #define SET_N(val) (SR = (SR & ~0x00000004) | ((val) << 2))
634 #define SET_V(val) (SR = (SR & ~0x00000008) | ((val) << 3))
635 #define SET_M(val) (SR = (SR & ~0x00000010) | ((val) << 4))
636 #define SET_H(val) (SR = (SR & ~0x00000020) | ((val) << 5))
637 #define SET_I(val) (SR = (SR & ~0x00000080) | ((val) << 7))
638 #define SET_FTE(val) (SR = (SR & ~0x00001f00) | ((val) << 8))
639 #define SET_FRM(val) (SR = (SR & ~0x00006000) | ((val) << 13))
640 #define SET_L(val) (SR = (SR & ~0x00008000) | ((val) << 15))
641 #define SET_T(val) (SR = (SR & ~0x00010000) | ((val) << 16))
642 #define SET_P(val) (SR = (SR & ~0x00020000) | ((val) << 17))
643 #define SET_S(val) (SR = (SR & ~0x00040000) | ((val) << 18))
644 #define SET_ILC(val) (SR = (SR & ~0x00180000) | ((val) << 19))
645 #define SET_FL(val) (SR = (SR & ~0x01e00000) | ((val) << 21))
646 #define SET_FP(val) (SR = (SR & ~0xfe000000) | ((val) << 25))
647
648 #define SET_PC(val) PC = ((val) & 0xfffffffe) //PC(0) = 0
649 #define SET_SP(val) SP = ((val) & 0xfffffffc) //SP(0) = SP(1) = 0
650 #define SET_UB(val) UB = ((val) & 0xfffffffc) //UB(0) = UB(1) = 0
651
652 #define SET_LOW_SR(val) (SR = (SR & 0xffff0000) | ((val) & 0x0000ffff)) // when SR is addressed, only low 16 bits can be changed
653
654
655 #define CHECK_C(x) (SR = (SR & ~0x00000001) | (((x) & (((UINT64)1) << 32)) ? 1 : 0 ))
656 #define CHECK_VADD(x,y,z) (SR = (SR & ~0x00000008) | ((((x) ^ (z)) & ((y) ^ (z)) & 0x80000000) ? 8: 0))
657 #define CHECK_VADD3(x,y,w,z) (SR = (SR & ~0x00000008) | ((((x) ^ (z)) & ((y) ^ (z)) & ((w) ^ (z)) & 0x80000000) ? 8: 0))
658 #define CHECK_VSUB(x,y,z) (SR = (SR & ~0x00000008) | ((((z) ^ (y)) & ((y) ^ (x)) & 0x80000000) ? 8: 0))
659
660
661 /* FER flags */
662 #define GET_ACCRUED (FER & 0x0000001f) //bits 4 - 0 //Floating-Point Accrued Exceptions
663 #define GET_ACTUAL (FER & 0x00001f00) //bits 12 - 8 //Floating-Point Actual Exceptions
664 //other bits are reversed, in particular 7 - 5 for the operating system.
665 //the user program can only changes the above 2 flags
666
667
total_cycles()668 static UINT64 total_cycles() // for internal use only!! (timers, etc)
669 {
670 return itotal_cycles;
671 }
672
compute_tr()673 static UINT32 compute_tr()
674 {
675 UINT64 cycles_since_base = total_cycles() - m_tr_base_cycles;
676 UINT64 clocks_since_base = cycles_since_base >> m_clock_scale;
677 return m_tr_base_value + (clocks_since_base / m_tr_clocks_per_tick);
678 }
679
update_timer_prescale()680 static void update_timer_prescale()
681 {
682 UINT32 prevtr = compute_tr();
683 TPR &= ~0x80000000;
684 m_clock_scale = (TPR >> 26) & m_clock_scale_mask;
685 m_clock_cycles_1 = 1 << m_clock_scale;
686 m_clock_cycles_2 = 2 << m_clock_scale;
687 m_clock_cycles_4 = 4 << m_clock_scale;
688 m_clock_cycles_6 = 6 << m_clock_scale;
689 m_tr_clocks_per_tick = ((TPR >> 16) & 0xff) + 2;
690 m_tr_base_value = prevtr;
691 m_tr_base_cycles = total_cycles();
692 }
693
694 static void timer_callback(INT32 param);
695
set_timer(INT32 cyc,INT32 param)696 static void set_timer(INT32 cyc, INT32 param)
697 {
698 timer_time = cyc;
699 timer_param = param;
700 }
701
adjust_timer_interrupt()702 static void adjust_timer_interrupt()
703 {
704 UINT64 cycles_since_base = total_cycles() - m_tr_base_cycles;
705 UINT64 clocks_since_base = cycles_since_base >> m_clock_scale;
706 UINT64 cycles_until_next_clock = cycles_since_base - (clocks_since_base << m_clock_scale);
707
708 if (cycles_until_next_clock == 0)
709 cycles_until_next_clock = (UINT64)(1 << m_clock_scale);
710
711 /* special case: if we have a change pending, set a timer to fire then */
712 if (TPR & 0x80000000)
713 {
714 UINT64 clocks_until_int = m_tr_clocks_per_tick - (clocks_since_base % m_tr_clocks_per_tick);
715 UINT64 cycles_until_int = (clocks_until_int << m_clock_scale) + cycles_until_next_clock;
716 set_timer(cycles_until_int + 1, 1);
717 // m_timer->adjust(cycles_to_attotime(cycles_until_int + 1), 1); // iq_132
718 }
719
720 /* else if the timer interrupt is enabled, configure it to fire at the appropriate time */
721 else if (!(FCR & 0x00800000))
722 {
723 UINT32 curtr = m_tr_base_value + (clocks_since_base / m_tr_clocks_per_tick);
724 UINT32 delta = TCR - curtr;
725 if (delta > 0x80000000)
726 {
727 if (!m_timer_int_pending) {
728 set_timer(1, 0);
729 //timer_callback(0);
730 }
731 }
732 else
733 {
734 UINT64 clocks_until_int = mulu_32x32(delta, m_tr_clocks_per_tick);
735 UINT64 cycles_until_int = (clocks_until_int << m_clock_scale) + cycles_until_next_clock;
736 set_timer(cycles_until_int, 0);
737 // m_timer->adjust(cycles_to_attotime(cycles_until_int)); // iq_132
738 }
739 }
740
741 /* otherwise, disable the timer */
742 else
743 {
744 set_timer(-1, 0);
745 }
746 }
747
timer_callback(INT32 param)748 static void timer_callback(INT32 param)
749 {
750 int update = param;
751 //bprintf(0, _T("--->timer(%d) @ %d\n"), param, itotal_cycles);
752 /* update the values if necessary */
753 if (update)
754 update_timer_prescale();
755
756 /* see if the timer is right for firing */
757 if (!((compute_tr() - TCR) & 0x80000000))
758 m_timer_int_pending = 1;
759
760 /* adjust ourselves for the next time */
761 else
762 adjust_timer_interrupt();
763 }
764
765
766
767
get_global_register(UINT8 code)768 static UINT32 get_global_register(UINT8 code)
769 {
770 /*
771 if( code >= 16 )
772 {
773 switch( code )
774 {
775 case 16:
776 case 17:
777 case 28:
778 case 29:
779 case 30:
780 case 31:
781 DEBUG_PRINTF(("read _Reserved_ Global Register %d @ %08X\n",code,PC));
782 break;
783
784 case BCR_REGISTER:
785 DEBUG_PRINTF(("read write-only BCR register @ %08X\n",PC));
786 return 0;
787
788 case TPR_REGISTER:
789 DEBUG_PRINTF(("read write-only TPR register @ %08X\n",PC));
790 return 0;
791
792 case FCR_REGISTER:
793 DEBUG_PRINTF(("read write-only FCR register @ %08X\n",PC));
794 return 0;
795
796 case MCR_REGISTER:
797 DEBUG_PRINTF(("read write-only MCR register @ %08X\n",PC));
798 return 0;
799 }
800 }
801 */
802 if (code == TR_REGISTER)
803 {
804 /* it is common to poll this in a loop */
805 if (m_icount > m_tr_clocks_per_tick / 2)
806 m_icount -= m_tr_clocks_per_tick / 2;
807 return compute_tr();
808 }
809 return m_global_regs[code];
810 }
811
set_local_register(UINT8 code,UINT32 val)812 static void set_local_register(UINT8 code, UINT32 val)
813 {
814 UINT8 new_code = (code + GET_FP) % 64;
815
816 m_local_regs[new_code] = val;
817 }
818
set_global_register(UINT8 code,UINT32 val)819 static void set_global_register(UINT8 code, UINT32 val)
820 {
821 //TODO: add correct FER set instruction
822
823 if( code == PC_REGISTER )
824 {
825 SET_PC(val);
826 }
827 else if( (INT32)code == SR_REGISTER )
828 {
829 SET_LOW_SR(val); // only a RET instruction can change the full content of SR
830 SR &= ~0x40; //reserved bit 6 always zero
831 if (m_intblock < 1)
832 m_intblock = 1;
833 }
834 else
835 {
836 UINT32 oldval = m_global_regs[code];
837 if( code != ISR_REGISTER )
838 m_global_regs[code] = val;
839 else
840 DEBUG_PRINTF(("Written to ISR register. PC = %08X\n", PC));
841
842 //are these set only when privilege bit is set?
843 if( code >= 16 )
844 {
845 switch( code )
846 {
847 case 18:
848 SET_SP(val);
849 break;
850
851 case 19:
852 SET_UB(val);
853 break;
854 /*
855 case ISR_REGISTER:
856 DEBUG_PRINTF(("written %08X to read-only ISR register\n",val));
857 break;
858
859 case TCR_REGISTER:
860 // DEBUG_PRINTF(("written %08X to TCR register\n",val));
861 break;
862
863 case 23:
864 // DEBUG_PRINTF(("written %08X to TR register\n",val));
865 break;
866
867 case 24:
868 // DEBUG_PRINTF(("written %08X to WCR register\n",val));
869 break;
870
871 case 16:
872 case 17:
873 case 28:
874 case 29:
875 case 30:
876 case 31:
877 DEBUG_PRINTF(("written %08X to _Reserved_ Global Register %d\n",val,code));
878 break;
879
880 case BCR_REGISTER:
881 break;
882 */
883 case TR_REGISTER:
884 m_tr_base_value = val;
885 m_tr_base_cycles = total_cycles();
886 adjust_timer_interrupt();
887 break;
888
889 case TPR_REGISTER:
890 if (!(val & 0x80000000)) /* change immediately */
891 update_timer_prescale();
892 adjust_timer_interrupt();
893 break;
894
895 case TCR_REGISTER:
896 if (oldval != val)
897 {
898 adjust_timer_interrupt();
899 if (m_intblock < 1)
900 m_intblock = 1;
901 }
902 break;
903
904 case FCR_REGISTER:
905 if ((oldval ^ val) & 0x00800000)
906 adjust_timer_interrupt();
907 if (m_intblock < 1)
908 m_intblock = 1;
909 break;
910
911 case MCR_REGISTER:
912 // bits 14..12 EntryTableMap
913 hyperstone_set_trap_entry((val & 0x7000) >> 12);
914 break;
915 }
916 }
917 }
918 }
919
920 #define GET_ABS_L_REG(code) m_local_regs[code]
921 #define SET_L_REG(code, val) set_local_register(code, val)
922 #define SET_ABS_L_REG(code, val) m_local_regs[code] = val
923 #define GET_G_REG(code) get_global_register(code)
924 #define SET_G_REG(code, val) set_global_register(code, val)
925
926 #define S_BIT ((OP & 0x100) >> 8)
927 #define N_BIT S_BIT
928 #define D_BIT ((OP & 0x200) >> 9)
929 #define N_VALUE ((N_BIT << 4) | (OP & 0x0f))
930 #define DST_CODE ((OP & 0xf0) >> 4)
931 #define SRC_CODE (OP & 0x0f)
932 #define SIGN_BIT(val) ((val & 0x80000000) >> 31)
933
934 #define LOCAL 1
935
936 static const INT32 immediate_values[32] =
937 {
938 0, 1, 2, 3, 4, 5, 6, 7,
939 8, 9, 10, 11, 12, 13, 14, 15,
940 16, 0, 0, 0, 32, 64, 128, (INT32)0x80000000,
941 -8, -7, -6, -5, -4, -3, -2, -1
942 };
943
944 #define WRITE_ONLY_REGMASK ((1 << BCR_REGISTER) | (1 << TPR_REGISTER) | (1 << FCR_REGISTER) | (1 << MCR_REGISTER))
945
946 #define decode_source(decode, local, hflag) \
947 do \
948 { \
949 if(local) \
950 { \
951 UINT8 code = (decode)->src; \
952 (decode)->src_is_local = 1; \
953 code = ((decode)->src + GET_FP) % 64; /* registers offset by frame pointer */\
954 SREG = m_local_regs[code]; \
955 code = ((decode)->src + 1 + GET_FP) % 64; \
956 SREGF = m_local_regs[code]; \
957 } \
958 else \
959 { \
960 (decode)->src_is_local = 0; \
961 \
962 if (!hflag) \
963 { \
964 SREG = get_global_register((decode)->src); \
965 \
966 /* bound safe */ \
967 if ((decode)->src != 15) \
968 SREGF = get_global_register((decode)->src + 1); \
969 } \
970 else \
971 { \
972 (decode)->src += 16; \
973 \
974 SREG = get_global_register((decode)->src); \
975 if ((WRITE_ONLY_REGMASK >> (decode)->src) & 1) \
976 SREG = 0; /* write-only registers */ \
977 else if ((decode)->src == ISR_REGISTER) \
978 DEBUG_PRINTF(("read src ISR. PC = %08X\n",PPC)); \
979 \
980 /* bound safe */ \
981 if ((decode)->src != 31) \
982 SREGF = get_global_register((decode)->src + 1); \
983 } \
984 } \
985 } while (0)
986
987 #define decode_dest(decode, local, hflag) \
988 do \
989 { \
990 if(local) \
991 { \
992 UINT8 code = (decode)->dst; \
993 (decode)->dst_is_local = 1; \
994 code = ((decode)->dst + GET_FP) % 64; /* registers offset by frame pointer */\
995 DREG = m_local_regs[code]; \
996 code = ((decode)->dst + 1 + GET_FP) % 64; \
997 DREGF = m_local_regs[code]; \
998 } \
999 else \
1000 { \
1001 (decode)->dst_is_local = 0; \
1002 \
1003 if (!hflag) \
1004 { \
1005 DREG = get_global_register((decode)->dst); \
1006 \
1007 /* bound safe */ \
1008 if ((decode)->dst != 15) \
1009 DREGF = get_global_register((decode)->dst + 1); \
1010 } \
1011 else \
1012 { \
1013 (decode)->dst += 16; \
1014 \
1015 DREG = get_global_register((decode)->dst); \
1016 if( (decode)->dst == ISR_REGISTER ) \
1017 DEBUG_PRINTF(("read dst ISR. PC = %08X\n",PPC)); \
1018 \
1019 /* bound safe */ \
1020 if ((decode)->dst != 31) \
1021 DREGF = get_global_register((decode)->dst + 1); \
1022 } \
1023 } \
1024 } while (0)
1025
1026 #define decode_RR(decode, dlocal, slocal) \
1027 do \
1028 { \
1029 (decode)->src = SRC_CODE; \
1030 (decode)->dst = DST_CODE; \
1031 decode_source(decode, slocal, 0); \
1032 decode_dest(decode, dlocal, 0); \
1033 \
1034 if( (slocal) == (dlocal) && SRC_CODE == DST_CODE ) \
1035 SAME_SRC_DST = 1; \
1036 \
1037 if( (slocal) == LOCAL && (dlocal) == LOCAL ) \
1038 { \
1039 if( SRC_CODE == ((DST_CODE + 1) % 64) ) \
1040 SAME_SRC_DSTF = 1; \
1041 \
1042 if( ((SRC_CODE + 1) % 64) == DST_CODE ) \
1043 SAME_SRCF_DST = 1; \
1044 } \
1045 else if( (slocal) == 0 && (dlocal) == 0 ) \
1046 { \
1047 if( SRC_CODE == (DST_CODE + 1) ) \
1048 SAME_SRC_DSTF = 1; \
1049 \
1050 if( (SRC_CODE + 1) == DST_CODE ) \
1051 SAME_SRCF_DST = 1; \
1052 } \
1053 } while (0)
1054
1055 #define decode_LL(decode) \
1056 do \
1057 { \
1058 (decode)->src = SRC_CODE; \
1059 (decode)->dst = DST_CODE; \
1060 decode_source(decode, LOCAL, 0); \
1061 decode_dest(decode, LOCAL, 0); \
1062 \
1063 if( SRC_CODE == DST_CODE ) \
1064 SAME_SRC_DST = 1; \
1065 \
1066 if( SRC_CODE == ((DST_CODE + 1) % 64) ) \
1067 SAME_SRC_DSTF = 1; \
1068 } while (0)
1069
1070 #define decode_LR(decode, slocal) \
1071 do \
1072 { \
1073 (decode)->src = SRC_CODE; \
1074 (decode)->dst = DST_CODE; \
1075 decode_source(decode, slocal, 0); \
1076 decode_dest(decode, LOCAL, 0); \
1077 \
1078 if( ((SRC_CODE + 1) % 64) == DST_CODE && slocal == LOCAL ) \
1079 SAME_SRCF_DST = 1; \
1080 } while (0)
1081
1082 #define check_delay_PC() \
1083 do \
1084 { \
1085 /* if PC is used in a delay instruction, the delayed PC should be used */ \
1086 if( m_delay.delay_cmd == DELAY_EXECUTE ) \
1087 { \
1088 PC = m_delay.delay_pc; \
1089 m_delay.delay_cmd = NO_DELAY; \
1090 } \
1091 } while (0)
1092
1093 #define decode_immediate(decode, nbit) \
1094 do \
1095 { \
1096 if (!nbit) \
1097 EXTRA_U = immediate_values[OP & 0x0f]; \
1098 else \
1099 switch( OP & 0x0f ) \
1100 { \
1101 default: \
1102 EXTRA_U = immediate_values[0x10 + (OP & 0x0f)]; \
1103 break; \
1104 \
1105 case 1: \
1106 m_instruction_length = 3; \
1107 EXTRA_U = (READ_OP(PC) << 16) | READ_OP(PC + 2); \
1108 PC += 4; \
1109 break; \
1110 \
1111 case 2: \
1112 m_instruction_length = 2; \
1113 EXTRA_U = READ_OP(PC); \
1114 PC += 2; \
1115 break; \
1116 \
1117 case 3: \
1118 m_instruction_length = 2; \
1119 EXTRA_U = 0xffff0000 | READ_OP(PC); \
1120 PC += 2; \
1121 break; \
1122 } \
1123 } while (0)
1124
1125 #define decode_const(decode) \
1126 do \
1127 { \
1128 UINT16 imm_1 = READ_OP(PC); \
1129 \
1130 PC += 2; \
1131 m_instruction_length = 2; \
1132 \
1133 if( E_BIT(imm_1) ) \
1134 { \
1135 UINT16 imm_2 = READ_OP(PC); \
1136 \
1137 PC += 2; \
1138 m_instruction_length = 3; \
1139 \
1140 EXTRA_S = imm_2; \
1141 EXTRA_S |= ((imm_1 & 0x3fff) << 16); \
1142 \
1143 if( S_BIT_CONST(imm_1) ) \
1144 { \
1145 EXTRA_S |= 0xc0000000; \
1146 } \
1147 } \
1148 else \
1149 { \
1150 EXTRA_S = imm_1 & 0x3fff; \
1151 \
1152 if( S_BIT_CONST(imm_1) ) \
1153 { \
1154 EXTRA_S |= 0xffffc000; \
1155 } \
1156 } \
1157 } while (0)
1158
1159 #define decode_pcrel(decode) \
1160 do \
1161 { \
1162 if( OP & 0x80 ) \
1163 { \
1164 UINT16 next = READ_OP(PC); \
1165 \
1166 PC += 2; \
1167 m_instruction_length = 2; \
1168 \
1169 EXTRA_S = (OP & 0x7f) << 16; \
1170 EXTRA_S |= (next & 0xfffe); \
1171 \
1172 if( next & 1 ) \
1173 EXTRA_S |= 0xff800000; \
1174 } \
1175 else \
1176 { \
1177 EXTRA_S = OP & 0x7e; \
1178 \
1179 if( OP & 1 ) \
1180 EXTRA_S |= 0xffffff80; \
1181 } \
1182 } while (0)
1183
1184 #define decode_dis(decode) \
1185 do \
1186 { \
1187 UINT16 next_1 = READ_OP(PC); \
1188 \
1189 PC += 2; \
1190 m_instruction_length = 2; \
1191 \
1192 (decode)->sub_type = DD(next_1); \
1193 \
1194 if( E_BIT(next_1) ) \
1195 { \
1196 UINT16 next_2 = READ_OP(PC); \
1197 \
1198 PC += 2; \
1199 m_instruction_length = 3; \
1200 \
1201 EXTRA_S = next_2; \
1202 EXTRA_S |= ((next_1 & 0xfff) << 16); \
1203 \
1204 if( S_BIT_CONST(next_1) ) \
1205 { \
1206 EXTRA_S |= 0xf0000000; \
1207 } \
1208 } \
1209 else \
1210 { \
1211 EXTRA_S = next_1 & 0xfff; \
1212 \
1213 if( S_BIT_CONST(next_1) ) \
1214 { \
1215 EXTRA_S |= 0xfffff000; \
1216 } \
1217 } \
1218 } while (0)
1219
1220 #define decode_lim(decode) \
1221 do \
1222 { \
1223 UINT32 next = READ_OP(PC); \
1224 PC += 2; \
1225 m_instruction_length = 2; \
1226 \
1227 (decode)->sub_type = X_CODE(next); \
1228 \
1229 if( E_BIT(next) ) \
1230 { \
1231 EXTRA_U = ((next & 0xfff) << 16) | READ_OP(PC); \
1232 PC += 2; \
1233 m_instruction_length = 3; \
1234 } \
1235 else \
1236 { \
1237 EXTRA_U = next & 0xfff; \
1238 } \
1239 } while (0)
1240
1241 #define RRdecode(decode, dlocal, slocal) \
1242 do \
1243 { \
1244 check_delay_PC(); \
1245 decode_RR(decode, dlocal, slocal); \
1246 } while (0)
1247
1248 #define RRlimdecode(decode, dlocal, slocal) \
1249 do \
1250 { \
1251 decode_lim(decode); \
1252 check_delay_PC(); \
1253 decode_RR(decode, dlocal, slocal); \
1254 } while (0)
1255
1256 #define RRconstdecode(decode, dlocal, slocal) \
1257 do \
1258 { \
1259 decode_const(decode); \
1260 check_delay_PC(); \
1261 decode_RR(decode, dlocal, slocal); \
1262 } while (0)
1263
1264 #define RRdisdecode(decode, dlocal, slocal) \
1265 do \
1266 { \
1267 decode_dis(decode); \
1268 check_delay_PC(); \
1269 decode_RR(decode, dlocal, slocal); \
1270 } while (0)
1271
1272 #define RRdecodewithHflag(decode, dlocal, slocal) \
1273 do \
1274 { \
1275 check_delay_PC(); \
1276 (decode)->src = SRC_CODE; \
1277 (decode)->dst = DST_CODE; \
1278 decode_source(decode, slocal, GET_H); \
1279 decode_dest(decode, dlocal, GET_H); \
1280 \
1281 if(GET_H) \
1282 if(slocal == 0 && dlocal == 0) \
1283 DEBUG_PRINTF(("MOV with hflag and 2 GRegs! PC = %08X\n",PPC)); \
1284 } while (0)
1285
1286 #define Rimmdecode(decode, dlocal, nbit) \
1287 do \
1288 { \
1289 decode_immediate(decode, nbit); \
1290 check_delay_PC(); \
1291 (decode)->dst = DST_CODE; \
1292 decode_dest(decode, dlocal, 0); \
1293 } while (0)
1294
1295 #define Rndecode(decode, dlocal) \
1296 do \
1297 { \
1298 check_delay_PC(); \
1299 (decode)->dst = DST_CODE; \
1300 decode_dest(decode, dlocal, 0); \
1301 } while (0)
1302
1303 #define RimmdecodewithHflag(decode, dlocal, nbit) \
1304 do \
1305 { \
1306 decode_immediate(decode, nbit); \
1307 check_delay_PC(); \
1308 (decode)->dst = DST_CODE; \
1309 decode_dest(decode, dlocal, GET_H); \
1310 } while (0)
1311
1312 #define Lndecode(decode) \
1313 do \
1314 { \
1315 check_delay_PC(); \
1316 (decode)->dst = DST_CODE; \
1317 decode_dest(decode, LOCAL, 0); \
1318 } while (0)
1319
1320 #define LLdecode(decode) \
1321 do \
1322 { \
1323 check_delay_PC(); \
1324 decode_LL(decode); \
1325 } while (0)
1326
1327 #define LLextdecode(decode) \
1328 do \
1329 { \
1330 m_instruction_length = 2; \
1331 EXTRA_U = READ_OP(PC); \
1332 PC += 2; \
1333 check_delay_PC(); \
1334 decode_LL(decode); \
1335 } while (0)
1336
1337 #define LRdecode(decode, slocal) \
1338 do \
1339 { \
1340 check_delay_PC(); \
1341 decode_LR(decode, slocal); \
1342 } while (0)
1343
1344 #define LRconstdecode(decode, slocal) \
1345 do \
1346 { \
1347 decode_const(decode); \
1348 check_delay_PC(); \
1349 decode_LR(decode, slocal); \
1350 } while (0)
1351
1352 #define PCreldecode(decode) \
1353 do \
1354 { \
1355 decode_pcrel(decode); \
1356 check_delay_PC(); \
1357 } while (0)
1358
1359 #define PCadrdecode(decode) \
1360 do \
1361 { \
1362 check_delay_PC(); \
1363 } while (0)
1364
1365 #define no_decode(decode) \
1366 do \
1367 { \
1368 } while (0)
1369
1370
execute_br(struct regs_decode * decode)1371 static void execute_br(struct regs_decode *decode)
1372 {
1373 PPC = PC;
1374 PC += EXTRA_S;
1375 SET_M(0);
1376
1377 m_icount -= m_clock_cycles_2;
1378 }
1379
execute_dbr(struct regs_decode * decode)1380 static void execute_dbr(struct regs_decode *decode)
1381 {
1382 m_delay.delay_cmd = DELAY_EXECUTE;
1383 m_delay.delay_pc = PC + EXTRA_S;
1384
1385 m_intblock = 3;
1386 }
1387
1388
execute_trap(UINT32 addr)1389 static void execute_trap(UINT32 addr)
1390 {
1391 UINT8 reg;
1392 UINT32 oldSR;
1393 reg = GET_FP + GET_FL;
1394
1395 SET_ILC(m_instruction_length & 3);
1396
1397 oldSR = SR;
1398
1399 SET_FL(6);
1400 SET_FP(reg);
1401
1402 SET_L_REG(0, (PC & 0xfffffffe) | GET_S);
1403 SET_L_REG(1, oldSR);
1404
1405 SET_M(0);
1406 SET_T(0);
1407 SET_L(1);
1408 SET_S(1);
1409
1410 PPC = PC;
1411 PC = addr;
1412
1413 m_icount -= m_clock_cycles_2;
1414 }
1415
1416
execute_int(UINT32 addr)1417 static void execute_int(UINT32 addr)
1418 {
1419 UINT8 reg;
1420 UINT32 oldSR;
1421 reg = GET_FP + GET_FL;
1422
1423 SET_ILC(m_instruction_length & 3);
1424
1425 oldSR = SR;
1426
1427 SET_FL(2);
1428 SET_FP(reg);
1429
1430 SET_L_REG(0, (PC & 0xfffffffe) | GET_S);
1431 SET_L_REG(1, oldSR);
1432
1433 SET_M(0);
1434 SET_T(0);
1435 SET_L(1);
1436 SET_S(1);
1437 SET_I(1);
1438
1439 PPC = PC;
1440 PC = addr;
1441
1442 m_icount -= m_clock_cycles_2;
1443 }
1444
1445 /* TODO: mask Parity Error and Extended Overflow exceptions */
execute_exception(UINT32 addr)1446 static void execute_exception(UINT32 addr)
1447 {
1448 UINT8 reg;
1449 UINT32 oldSR;
1450 reg = GET_FP + GET_FL;
1451
1452 SET_ILC(m_instruction_length & 3);
1453
1454 oldSR = SR;
1455
1456 SET_FP(reg);
1457 SET_FL(2);
1458
1459 SET_L_REG(0, (PC & 0xfffffffe) | GET_S);
1460 SET_L_REG(1, oldSR);
1461
1462 SET_M(0);
1463 SET_T(0);
1464 SET_L(1);
1465 SET_S(1);
1466
1467 PPC = PC;
1468 PC = addr;
1469
1470 DEBUG_PRINTF(("EXCEPTION! PPC = %08X PC = %08X\n",PPC-2,PC-2));
1471 m_icount -= m_clock_cycles_2;
1472 }
1473
execute_software(struct regs_decode * decode)1474 static void execute_software(struct regs_decode *decode)
1475 {
1476 UINT8 reg;
1477 UINT32 oldSR;
1478 UINT32 addr;
1479 UINT32 stack_of_dst;
1480
1481 SET_ILC(1);
1482
1483 addr = get_emu_code_addr((OP & 0xff00) >> 8);
1484 reg = GET_FP + GET_FL;
1485
1486 //since it's sure the register is in the register part of the stack,
1487 //set the stack address to a value above the highest address
1488 //that can be set by a following frame instruction
1489 stack_of_dst = (SP & ~0xff) + 64*4 + (((GET_FP + decode->dst) % 64) * 4); //converted to 32bits offset
1490
1491 oldSR = SR;
1492
1493 SET_FL(6);
1494 SET_FP(reg);
1495
1496 SET_L_REG(0, stack_of_dst);
1497 SET_L_REG(1, SREG);
1498 SET_L_REG(2, SREGF);
1499 SET_L_REG(3, (PC & 0xfffffffe) | GET_S);
1500 SET_L_REG(4, oldSR);
1501
1502 SET_M(0);
1503 SET_T(0);
1504 SET_L(1);
1505
1506 PPC = PC;
1507 PC = addr;
1508 }
1509
1510
1511 /*
1512 IRQ lines :
1513 0 - IO2 (trap 48)
1514 1 - IO1 (trap 49)
1515 2 - INT4 (trap 50)
1516 3 - INT3 (trap 51)
1517 4 - INT2 (trap 52)
1518 5 - INT1 (trap 53)
1519 6 - IO3 (trap 54)
1520 7 - TIMER (trap 55)
1521 */
1522
1523 #define INT1_LINE_STATE ((ISR >> 0) & 1)
1524 #define INT2_LINE_STATE ((ISR >> 1) & 1)
1525 #define INT3_LINE_STATE ((ISR >> 2) & 1)
1526 #define INT4_LINE_STATE ((ISR >> 3) & 1)
1527 #define IO1_LINE_STATE ((ISR >> 4) & 1)
1528 #define IO2_LINE_STATE ((ISR >> 5) & 1)
1529 #define IO3_LINE_STATE ((ISR >> 6) & 1)
1530
execute_set_input(int inputnum,int state)1531 static void execute_set_input(int inputnum, int state)
1532 {
1533 if (state) {
1534 m_hold_irq = (state & 2) ? (0x1000 | inputnum) : 0;
1535 ISR |= 1 << inputnum;
1536 } else {
1537 ISR &= ~(1 << inputnum);
1538 }
1539 }
1540
standard_irq_callback(INT32 line)1541 static void standard_irq_callback(INT32 line)
1542 {
1543 if (m_hold_irq && (m_hold_irq & 0xff) == line) {
1544 m_hold_irq = 0;
1545 execute_set_input(line, 0);
1546 }
1547 }
1548
E132XSInterruptActive()1549 INT32 E132XSInterruptActive()
1550 {
1551 if ((FCR & (1 << 29)) == 0) return 1;
1552 return 0;
1553 }
1554
E132XSGetPC(INT32)1555 UINT32 E132XSGetPC(INT32)
1556 {
1557 return PC;
1558 }
1559
check_interrupts()1560 static void check_interrupts()
1561 {
1562 /* Interrupt-Lock flag isn't set */
1563 if (GET_L || m_intblock > 0)
1564 return;
1565
1566 /* quick exit if nothing */
1567 if (!m_timer_int_pending && (ISR & 0x7f) == 0)
1568 return;
1569
1570 /* IO3 is priority 5; state is in bit 6 of ISR; FCR bit 10 enables input and FCR bit 8 inhibits interrupt */
1571 if (IO3_LINE_STATE && (FCR & 0x00000500) == 0x00000400)
1572 {
1573 execute_int(get_trap_addr(TRAPNO_IO3));
1574 standard_irq_callback(IRQ_IO3);
1575 return;
1576 }
1577
1578 /* timer int might be priority 6 if FCR bits 20-21 == 3; FCR bit 23 inhibits interrupt */
1579 if (m_timer_int_pending && (FCR & 0x00b00000) == 0x00300000)
1580 {
1581 m_timer_int_pending = 0;
1582 execute_int(get_trap_addr(TRAPNO_TIMER));
1583 return;
1584 }
1585
1586 /* INT1 is priority 7; state is in bit 0 of ISR; FCR bit 28 inhibits interrupt */
1587 if (INT1_LINE_STATE && (FCR & 0x10000000) == 0x00000000)
1588 {
1589 execute_int(get_trap_addr(TRAPNO_INT1));
1590 standard_irq_callback(IRQ_INT1);
1591 return;
1592 }
1593
1594 /* timer int might be priority 8 if FCR bits 20-21 == 2; FCR bit 23 inhibits interrupt */
1595 if (m_timer_int_pending && (FCR & 0x00b00000) == 0x00200000)
1596 {
1597 m_timer_int_pending = 0;
1598 execute_int(get_trap_addr(TRAPNO_TIMER));
1599 return;
1600 }
1601
1602 /* INT2 is priority 9; state is in bit 1 of ISR; FCR bit 29 inhibits interrupt */
1603 if (INT2_LINE_STATE && (FCR & 0x20000000) == 0x00000000)
1604 {
1605 execute_int(get_trap_addr(TRAPNO_INT2));
1606 standard_irq_callback(IRQ_INT2);
1607 return;
1608 }
1609
1610 /* timer int might be priority 10 if FCR bits 20-21 == 1; FCR bit 23 inhibits interrupt */
1611 if (m_timer_int_pending && (FCR & 0x00b00000) == 0x00100000)
1612 {
1613 m_timer_int_pending = 0;
1614 execute_int(get_trap_addr(TRAPNO_TIMER));
1615 return;
1616 }
1617
1618 /* INT3 is priority 11; state is in bit 2 of ISR; FCR bit 30 inhibits interrupt */
1619 if (INT3_LINE_STATE && (FCR & 0x40000000) == 0x00000000)
1620 {
1621 execute_int(get_trap_addr(TRAPNO_INT3));
1622 standard_irq_callback(IRQ_INT3);
1623 return;
1624 }
1625
1626 /* timer int might be priority 12 if FCR bits 20-21 == 0; FCR bit 23 inhibits interrupt */
1627 if (m_timer_int_pending && (FCR & 0x00b00000) == 0x00000000)
1628 {
1629 m_timer_int_pending = 0;
1630 execute_int(get_trap_addr(TRAPNO_TIMER));
1631 return;
1632 }
1633
1634 /* INT4 is priority 13; state is in bit 3 of ISR; FCR bit 31 inhibits interrupt */
1635 if (INT4_LINE_STATE && (FCR & 0x80000000) == 0x00000000)
1636 {
1637 execute_int(get_trap_addr(TRAPNO_INT4));
1638 standard_irq_callback(IRQ_INT4);
1639 return;
1640 }
1641
1642 /* IO1 is priority 14; state is in bit 4 of ISR; FCR bit 2 enables input and FCR bit 0 inhibits interrupt */
1643 if (IO1_LINE_STATE && (FCR & 0x00000005) == 0x00000004)
1644 {
1645 execute_int(get_trap_addr(TRAPNO_IO1));
1646 standard_irq_callback(IRQ_IO1);
1647 return;
1648 }
1649
1650 /* IO2 is priority 15; state is in bit 5 of ISR; FCR bit 6 enables input and FCR bit 4 inhibits interrupt */
1651 if (IO2_LINE_STATE && (FCR & 0x00000050) == 0x00000040)
1652 {
1653 execute_int(get_trap_addr(TRAPNO_IO2));
1654 standard_irq_callback(IRQ_IO2);
1655 return;
1656 }
1657 }
1658
1659
1660 //-------------------------------------------------
1661 // memory_space_config - return the configuration
1662 // of the specified address space, or NULL if
1663 // the space doesn't exist
1664 //-------------------------------------------------
1665
hyperstone_chk(struct regs_decode * decode)1666 static void hyperstone_chk(struct regs_decode *decode)
1667 {
1668 UINT32 addr = get_trap_addr(TRAPNO_RANGE_ERROR);
1669
1670 if( SRC_IS_SR )
1671 {
1672 if( DREG == 0 )
1673 execute_exception(addr);
1674 }
1675 else
1676 {
1677 if( SRC_IS_PC )
1678 {
1679 if( DREG >= SREG )
1680 execute_exception(addr);
1681 }
1682 else
1683 {
1684 if( DREG > SREG )
1685 execute_exception(addr);
1686 }
1687 }
1688
1689 m_icount -= m_clock_cycles_1;
1690 }
1691
hyperstone_movd(struct regs_decode * decode)1692 static void hyperstone_movd(struct regs_decode *decode)
1693 {
1694 if( DST_IS_PC ) // Rd denotes PC
1695 {
1696 // RET instruction
1697
1698 UINT8 old_s, old_l;
1699 INT8 difference; // really it's 7 bits
1700
1701 if( SRC_IS_PC || SRC_IS_SR )
1702 {
1703 DEBUG_PRINTF(("Denoted PC or SR in RET instruction. PC = %08X\n", PC));
1704 }
1705 else
1706 {
1707 old_s = GET_S;
1708 old_l = GET_L;
1709 PPC = PC;
1710
1711 SET_PC(SREG);
1712 SR = (SREGF & 0xffe00000) | ((SREG & 0x01) << 18 ) | (SREGF & 0x3ffff);
1713 if (m_intblock < 1)
1714 m_intblock = 1;
1715
1716 m_instruction_length = 0; // undefined
1717
1718 if( (!old_s && GET_S) || (!GET_S && !old_l && GET_L))
1719 {
1720 UINT32 addr = get_trap_addr(TRAPNO_PRIVILEGE_ERROR);
1721 execute_exception(addr);
1722 }
1723
1724 difference = GET_FP - ((SP & 0x1fc) >> 2);
1725
1726 /* convert to 8 bits */
1727 if(difference > 63)
1728 difference = (INT8)(difference|0x80);
1729 else if( difference < -64 )
1730 difference = difference & 0x7f;
1731
1732 if( difference < 0 ) //else it's finished
1733 {
1734 do
1735 {
1736 SP -= 4;
1737 SET_ABS_L_REG(((SP & 0xfc) >> 2), READ_W(SP));
1738 difference++;
1739
1740 } while(difference != 0);
1741 }
1742 }
1743
1744 //TODO: no 1!
1745 m_icount -= m_clock_cycles_1;
1746 }
1747 else if( SRC_IS_SR ) // Rd doesn't denote PC and Rs denotes SR
1748 {
1749 SET_DREG(0);
1750 SET_DREGF(0);
1751 SET_Z(1);
1752 SET_N(0);
1753
1754 m_icount -= m_clock_cycles_2;
1755 }
1756 else // Rd doesn't denote PC and Rs doesn't denote SR
1757 {
1758 UINT64 tmp;
1759
1760 SET_DREG(SREG);
1761 SET_DREGF(SREGF);
1762
1763 tmp = CONCAT_64(SREG, SREGF);
1764 SET_Z( tmp == 0 ? 1 : 0 );
1765 SET_N( SIGN_BIT(SREG) );
1766
1767 m_icount -= m_clock_cycles_2;
1768 }
1769 }
1770
hyperstone_divu(struct regs_decode * decode)1771 static void hyperstone_divu(struct regs_decode *decode)
1772 {
1773 if( SAME_SRC_DST || SAME_SRC_DSTF )
1774 {
1775 DEBUG_PRINTF(("Denoted the same register code in hyperstone_divu instruction. PC = %08X\n", PC));
1776 }
1777 else
1778 {
1779 if( SRC_IS_PC || SRC_IS_SR )
1780 {
1781 DEBUG_PRINTF(("Denoted PC or SR as source register in hyperstone_divu instruction. PC = %08X\n", PC));
1782 }
1783 else
1784 {
1785 UINT64 dividend;
1786
1787 dividend = CONCAT_64(DREG, DREGF);
1788
1789 if( SREG == 0 )
1790 {
1791 //Rd//Rdf -> undefined
1792 //Z -> undefined
1793 //N -> undefined
1794 UINT32 addr;
1795 SET_V(1);
1796 addr = get_trap_addr(TRAPNO_RANGE_ERROR);
1797 execute_exception(addr);
1798 }
1799 else
1800 {
1801 UINT32 quotient, remainder;
1802
1803 /* TODO: add quotient overflow */
1804 quotient = dividend / SREG;
1805 remainder = dividend % SREG;
1806
1807 SET_DREG(remainder);
1808 SET_DREGF(quotient);
1809
1810 SET_Z( quotient == 0 ? 1 : 0 );
1811 SET_N( SIGN_BIT(quotient) );
1812 SET_V(0);
1813 }
1814 }
1815 }
1816
1817 m_icount -= 36 << m_clock_scale;
1818 }
1819
hyperstone_divs(struct regs_decode * decode)1820 static void hyperstone_divs(struct regs_decode *decode)
1821 {
1822 if( SAME_SRC_DST || SAME_SRC_DSTF )
1823 {
1824 DEBUG_PRINTF(("Denoted the same register code in hyperstone_divs instruction. PC = %08X\n", PC));
1825 }
1826 else
1827 {
1828 if( SRC_IS_PC || SRC_IS_SR )
1829 {
1830 DEBUG_PRINTF(("Denoted PC or SR as source register in hyperstone_divs instruction. PC = %08X\n", PC));
1831 }
1832 else
1833 {
1834 INT64 dividend;
1835
1836 dividend = (INT64) CONCAT_64(DREG, DREGF);
1837
1838 if( SREG == 0 || (DREG & 0x80000000) )
1839 {
1840 //Rd//Rdf -> undefined
1841 //Z -> undefined
1842 //N -> undefined
1843 UINT32 addr;
1844 SET_V(1);
1845 addr = get_trap_addr(TRAPNO_RANGE_ERROR);
1846 execute_exception(addr);
1847 }
1848 else
1849 {
1850 INT32 quotient, remainder;
1851
1852 /* TODO: add quotient overflow */
1853 quotient = dividend / ((INT32)(SREG));
1854 remainder = dividend % ((INT32)(SREG));
1855
1856 SET_DREG(remainder);
1857 SET_DREGF(quotient);
1858
1859 SET_Z( quotient == 0 ? 1 : 0 );
1860 SET_N( SIGN_BIT(quotient) );
1861 SET_V(0);
1862 }
1863 }
1864 }
1865
1866 m_icount -= 36 << m_clock_scale;
1867 }
1868
hyperstone_xm(struct regs_decode * decode)1869 static void hyperstone_xm(struct regs_decode *decode)
1870 {
1871 if( SRC_IS_SR || DST_IS_SR || DST_IS_PC )
1872 {
1873 DEBUG_PRINTF(("Denoted PC or SR in hyperstone_xm. PC = %08X\n", PC));
1874 }
1875 else
1876 {
1877 switch( decode->sub_type ) // x_code
1878 {
1879 case 0:
1880 case 1:
1881 case 2:
1882 case 3:
1883 if( !SRC_IS_PC && (SREG > EXTRA_U) )
1884 {
1885 UINT32 addr = get_trap_addr(TRAPNO_RANGE_ERROR);
1886 execute_exception(addr);
1887 }
1888 else if( SRC_IS_PC && (SREG >= EXTRA_U) )
1889 {
1890 UINT32 addr = get_trap_addr(TRAPNO_RANGE_ERROR);
1891 execute_exception(addr);
1892 }
1893 else
1894 {
1895 SREG <<= decode->sub_type;
1896 }
1897
1898 break;
1899
1900 case 4:
1901 case 5:
1902 case 6:
1903 case 7:
1904 decode->sub_type -= 4;
1905 SREG <<= decode->sub_type;
1906
1907 break;
1908 }
1909
1910 SET_DREG(SREG);
1911 }
1912
1913 m_icount -= m_clock_cycles_1;
1914 }
1915
hyperstone_mask(struct regs_decode * decode)1916 static void hyperstone_mask(struct regs_decode *decode)
1917 {
1918 DREG = SREG & EXTRA_U;
1919
1920 SET_DREG(DREG);
1921 SET_Z( DREG == 0 ? 1 : 0 );
1922
1923 m_icount -= m_clock_cycles_1;
1924 }
1925
hyperstone_sum(struct regs_decode * decode)1926 static void hyperstone_sum(struct regs_decode *decode)
1927 {
1928 UINT64 tmp;
1929
1930 if( SRC_IS_SR )
1931 SREG = GET_C;
1932
1933 tmp = (UINT64)(SREG) + (UINT64)(EXTRA_U);
1934 CHECK_C(tmp);
1935 CHECK_VADD(SREG,EXTRA_U,tmp);
1936
1937 DREG = SREG + EXTRA_U;
1938
1939 SET_DREG(DREG);
1940
1941 if( DST_IS_PC )
1942 SET_M(0);
1943
1944 SET_Z( DREG == 0 ? 1 : 0 );
1945 SET_N( SIGN_BIT(DREG) );
1946
1947 m_icount -= m_clock_cycles_1;
1948 }
1949
hyperstone_sums(struct regs_decode * decode)1950 static void hyperstone_sums(struct regs_decode *decode)
1951 {
1952 INT32 res;
1953 INT64 tmp;
1954
1955 if( SRC_IS_SR )
1956 SREG = GET_C;
1957
1958 tmp = (INT64)((INT32)(SREG)) + (INT64)(EXTRA_S);
1959 CHECK_VADD(SREG,EXTRA_S,tmp);
1960
1961 //#if SETCARRYS
1962 // CHECK_C(tmp);
1963 //#endif
1964
1965 res = (INT32)(SREG) + EXTRA_S;
1966
1967 SET_DREG(res);
1968
1969 SET_Z( res == 0 ? 1 : 0 );
1970 SET_N( SIGN_BIT(res) );
1971
1972 m_icount -= m_clock_cycles_1;
1973
1974 if( GET_V && !SRC_IS_SR )
1975 {
1976 UINT32 addr = get_trap_addr(TRAPNO_RANGE_ERROR);
1977 execute_exception(addr);
1978 }
1979 }
1980
hyperstone_cmp(struct regs_decode * decode)1981 static void hyperstone_cmp(struct regs_decode *decode)
1982 {
1983 UINT64 tmp;
1984
1985 if( SRC_IS_SR )
1986 SREG = GET_C;
1987
1988 if( DREG == SREG )
1989 SET_Z(1);
1990 else
1991 SET_Z(0);
1992
1993 if( (INT32) DREG < (INT32) SREG )
1994 SET_N(1);
1995 else
1996 SET_N(0);
1997
1998 tmp = (UINT64)(DREG) - (UINT64)(SREG);
1999 CHECK_VSUB(SREG,DREG,tmp);
2000
2001 if( DREG < SREG )
2002 SET_C(1);
2003 else
2004 SET_C(0);
2005
2006 m_icount -= m_clock_cycles_1;
2007 }
2008
hyperstone_mov(struct regs_decode * decode)2009 static void hyperstone_mov(struct regs_decode *decode)
2010 {
2011 if( !GET_S && decode->dst >= 16 )
2012 {
2013 UINT32 addr = get_trap_addr(TRAPNO_PRIVILEGE_ERROR);
2014 execute_exception(addr);
2015 }
2016
2017 SET_DREG(SREG);
2018
2019 if( DST_IS_PC )
2020 SET_M(0);
2021
2022 SET_Z( SREG == 0 ? 1 : 0 );
2023 SET_N( SIGN_BIT(SREG) );
2024
2025 m_icount -= m_clock_cycles_1;
2026 }
2027
2028
hyperstone_add(struct regs_decode * decode)2029 static void hyperstone_add(struct regs_decode *decode)
2030 {
2031 UINT64 tmp;
2032
2033 if( SRC_IS_SR )
2034 SREG = GET_C;
2035
2036 tmp = (UINT64)(SREG) + (UINT64)(DREG);
2037 CHECK_C(tmp);
2038 CHECK_VADD(SREG,DREG,tmp);
2039
2040 DREG = SREG + DREG;
2041 SET_DREG(DREG);
2042
2043 if( DST_IS_PC )
2044 SET_M(0);
2045
2046 SET_Z( DREG == 0 ? 1 : 0 );
2047 SET_N( SIGN_BIT(DREG) );
2048
2049 m_icount -= m_clock_cycles_1;
2050 }
2051
hyperstone_adds(struct regs_decode * decode)2052 static void hyperstone_adds(struct regs_decode *decode)
2053 {
2054 INT32 res;
2055 INT64 tmp;
2056
2057 if( SRC_IS_SR )
2058 SREG = GET_C;
2059
2060 tmp = (INT64)((INT32)(SREG)) + (INT64)((INT32)(DREG));
2061
2062 CHECK_VADD(SREG,DREG,tmp);
2063
2064 //#if SETCARRYS
2065 // CHECK_C(tmp);
2066 //#endif
2067
2068 res = (INT32)(SREG) + (INT32)(DREG);
2069
2070 SET_DREG(res);
2071 SET_Z( res == 0 ? 1 : 0 );
2072 SET_N( SIGN_BIT(res) );
2073
2074 m_icount -= m_clock_cycles_1;
2075
2076 if( GET_V )
2077 {
2078 UINT32 addr = get_trap_addr(TRAPNO_RANGE_ERROR);
2079 execute_exception(addr);
2080 }
2081 }
2082
hyperstone_cmpb(struct regs_decode * decode)2083 static void hyperstone_cmpb(struct regs_decode *decode)
2084 {
2085 SET_Z( (DREG & SREG) == 0 ? 1 : 0 );
2086
2087 m_icount -= m_clock_cycles_1;
2088 }
2089
hyperstone_andn(struct regs_decode * decode)2090 static void hyperstone_andn(struct regs_decode *decode)
2091 {
2092 DREG = DREG & ~SREG;
2093
2094 SET_DREG(DREG);
2095 SET_Z( DREG == 0 ? 1 : 0 );
2096
2097 m_icount -= m_clock_cycles_1;
2098 }
2099
hyperstone_or(struct regs_decode * decode)2100 static void hyperstone_or(struct regs_decode *decode)
2101 {
2102 DREG = DREG | SREG;
2103
2104 SET_DREG(DREG);
2105 SET_Z( DREG == 0 ? 1 : 0 );
2106
2107 m_icount -= m_clock_cycles_1;
2108 }
2109
hyperstone_xor(struct regs_decode * decode)2110 static void hyperstone_xor(struct regs_decode *decode)
2111 {
2112 DREG = DREG ^ SREG;
2113
2114 SET_DREG(DREG);
2115 SET_Z( DREG == 0 ? 1 : 0 );
2116
2117 m_icount -= m_clock_cycles_1;
2118 }
2119
hyperstone_subc(struct regs_decode * decode)2120 static void hyperstone_subc(struct regs_decode *decode)
2121 {
2122 UINT64 tmp;
2123
2124 if( SRC_IS_SR )
2125 {
2126 tmp = (UINT64)(DREG) - (UINT64)(GET_C);
2127 CHECK_VSUB(GET_C,DREG,tmp);
2128 }
2129 else
2130 {
2131 tmp = (UINT64)(DREG) - ((UINT64)(SREG) + (UINT64)(GET_C));
2132 //CHECK!
2133 CHECK_VSUB(SREG + GET_C,DREG,tmp);
2134 }
2135
2136
2137 if( SRC_IS_SR )
2138 {
2139 DREG = DREG - GET_C;
2140 }
2141 else
2142 {
2143 DREG = DREG - (SREG + GET_C);
2144 }
2145
2146 CHECK_C(tmp);
2147
2148 SET_DREG(DREG);
2149
2150 SET_Z( GET_Z & (DREG == 0 ? 1 : 0) );
2151 SET_N( SIGN_BIT(DREG) );
2152
2153 m_icount -= m_clock_cycles_1;
2154 }
2155
hyperstone_not(struct regs_decode * decode)2156 static void hyperstone_not(struct regs_decode *decode)
2157 {
2158 SET_DREG(~SREG);
2159 SET_Z( ~SREG == 0 ? 1 : 0 );
2160
2161 m_icount -= m_clock_cycles_1;
2162 }
2163
hyperstone_sub(struct regs_decode * decode)2164 static void hyperstone_sub(struct regs_decode *decode)
2165 {
2166 UINT64 tmp;
2167
2168 if( SRC_IS_SR )
2169 SREG = GET_C;
2170
2171 tmp = (UINT64)(DREG) - (UINT64)(SREG);
2172 CHECK_C(tmp);
2173 CHECK_VSUB(SREG,DREG,tmp);
2174
2175 DREG = DREG - SREG;
2176 SET_DREG(DREG);
2177
2178 if( DST_IS_PC )
2179 SET_M(0);
2180
2181 SET_Z( DREG == 0 ? 1 : 0 );
2182 SET_N( SIGN_BIT(DREG) );
2183
2184 m_icount -= m_clock_cycles_1;
2185 }
2186
hyperstone_subs(struct regs_decode * decode)2187 static void hyperstone_subs(struct regs_decode *decode)
2188 {
2189 INT32 res;
2190 INT64 tmp;
2191
2192 if( SRC_IS_SR )
2193 SREG = GET_C;
2194
2195 tmp = (INT64)((INT32)(DREG)) - (INT64)((INT32)(SREG));
2196
2197 //#ifdef SETCARRYS
2198 // CHECK_C(tmp);
2199 //#endif
2200
2201 CHECK_VSUB(SREG,DREG,tmp);
2202
2203 res = (INT32)(DREG) - (INT32)(SREG);
2204
2205 SET_DREG(res);
2206
2207 SET_Z( res == 0 ? 1 : 0 );
2208 SET_N( SIGN_BIT(res) );
2209
2210 m_icount -= m_clock_cycles_1;
2211
2212 if( GET_V )
2213 {
2214 UINT32 addr = get_trap_addr(TRAPNO_RANGE_ERROR);
2215 execute_exception(addr);
2216 }
2217 }
2218
hyperstone_addc(struct regs_decode * decode)2219 static void hyperstone_addc(struct regs_decode *decode)
2220 {
2221 UINT64 tmp;
2222
2223 if( SRC_IS_SR )
2224 {
2225 tmp = (UINT64)(DREG) + (UINT64)(GET_C);
2226 CHECK_VADD(DREG,GET_C,tmp);
2227 }
2228 else
2229 {
2230 tmp = (UINT64)(SREG) + (UINT64)(DREG) + (UINT64)(GET_C);
2231
2232 //CHECK!
2233 //CHECK_VADD1: V = (DREG == 0x7FFF) && (C == 1);
2234 //OVERFLOW = CHECK_VADD1(DREG, C, DREG+C) | CHECK_VADD(SREG, DREG+C, SREG+DREG+C)
2235 /* check if DREG + GET_C overflows */
2236 // if( (DREG == 0x7FFFFFFF) && (GET_C == 1) )
2237 // SET_V(1);
2238 // else
2239 // CHECK_VADD(SREG,DREG + GET_C,tmp);
2240
2241 CHECK_VADD3(SREG,DREG,GET_C,tmp);
2242 }
2243
2244
2245
2246 if( SRC_IS_SR )
2247 DREG = DREG + GET_C;
2248 else
2249 DREG = SREG + DREG + GET_C;
2250
2251 CHECK_C(tmp);
2252
2253 SET_DREG(DREG);
2254 SET_Z( GET_Z & (DREG == 0 ? 1 : 0) );
2255 SET_N( SIGN_BIT(DREG) );
2256
2257 m_icount -= m_clock_cycles_1;
2258 }
2259
hyperstone_and(struct regs_decode * decode)2260 static void hyperstone_and(struct regs_decode *decode)
2261 {
2262 DREG = DREG & SREG;
2263
2264 SET_DREG(DREG);
2265 SET_Z( DREG == 0 ? 1 : 0 );
2266
2267 m_icount -= m_clock_cycles_1;
2268 }
2269
hyperstone_neg(struct regs_decode * decode)2270 static void hyperstone_neg(struct regs_decode *decode)
2271 {
2272 UINT64 tmp;
2273
2274 if( SRC_IS_SR )
2275 SREG = GET_C;
2276
2277 tmp = -(UINT64)(SREG);
2278 CHECK_C(tmp);
2279 CHECK_VSUB(SREG,0,tmp);
2280
2281 DREG = -SREG;
2282
2283 SET_DREG(DREG);
2284
2285 SET_Z( DREG == 0 ? 1 : 0 );
2286 SET_N( SIGN_BIT(DREG) );
2287
2288 m_icount -= m_clock_cycles_1;
2289 }
2290
hyperstone_negs(struct regs_decode * decode)2291 static void hyperstone_negs(struct regs_decode *decode)
2292 {
2293 INT32 res;
2294 INT64 tmp;
2295
2296 if( SRC_IS_SR )
2297 SREG = GET_C;
2298
2299 tmp = -(INT64)((INT32)(SREG));
2300 CHECK_VSUB(SREG,0,tmp);
2301
2302 //#if SETCARRYS
2303 // CHECK_C(tmp);
2304 //#endif
2305
2306 res = -(INT32)(SREG);
2307
2308 SET_DREG(res);
2309
2310 SET_Z( res == 0 ? 1 : 0 );
2311 SET_N( SIGN_BIT(res) );
2312
2313
2314 m_icount -= m_clock_cycles_1;
2315
2316 if( GET_V && !SRC_IS_SR ) //trap doesn't occur when source is SR
2317 {
2318 UINT32 addr = get_trap_addr(TRAPNO_RANGE_ERROR);
2319 execute_exception(addr);
2320 }
2321 }
2322
hyperstone_cmpi(struct regs_decode * decode)2323 static void hyperstone_cmpi(struct regs_decode *decode)
2324 {
2325 UINT64 tmp;
2326
2327 tmp = (UINT64)(DREG) - (UINT64)(EXTRA_U);
2328 CHECK_VSUB(EXTRA_U,DREG,tmp);
2329
2330 if( DREG == EXTRA_U )
2331 SET_Z(1);
2332 else
2333 SET_Z(0);
2334
2335 if( (INT32) DREG < (INT32) EXTRA_U )
2336 SET_N(1);
2337 else
2338 SET_N(0);
2339
2340 if( DREG < EXTRA_U )
2341 SET_C(1);
2342 else
2343 SET_C(0);
2344
2345 m_icount -= m_clock_cycles_1;
2346 }
2347
hyperstone_movi(struct regs_decode * decode)2348 static void hyperstone_movi(struct regs_decode *decode)
2349 {
2350 if( !GET_S && decode->dst >= 16 )
2351 {
2352 UINT32 addr = get_trap_addr(TRAPNO_PRIVILEGE_ERROR);
2353 execute_exception(addr);
2354 }
2355
2356 SET_DREG(EXTRA_U);
2357
2358 if( DST_IS_PC )
2359 SET_M(0);
2360
2361 SET_Z( EXTRA_U == 0 ? 1 : 0 );
2362 SET_N( SIGN_BIT(EXTRA_U) );
2363
2364 #if MISSIONCRAFT_FLAGS
2365 SET_V(0); // or V undefined ?
2366 #endif
2367
2368 m_icount -= m_clock_cycles_1;
2369 }
2370
hyperstone_addi(struct regs_decode * decode)2371 static void hyperstone_addi(struct regs_decode *decode)
2372 {
2373 UINT32 imm;
2374 UINT64 tmp;
2375
2376 if( N_VALUE )
2377 imm = EXTRA_U;
2378 else
2379 imm = GET_C & ((GET_Z == 0 ? 1 : 0) | (DREG & 0x01));
2380
2381
2382 tmp = (UINT64)(imm) + (UINT64)(DREG);
2383 CHECK_C(tmp);
2384 CHECK_VADD(imm,DREG,tmp);
2385
2386 DREG = imm + DREG;
2387 SET_DREG(DREG);
2388
2389 if( DST_IS_PC )
2390 SET_M(0);
2391
2392 SET_Z( DREG == 0 ? 1 : 0 );
2393 SET_N( SIGN_BIT(DREG) );
2394
2395 m_icount -= m_clock_cycles_1;
2396 }
2397
hyperstone_addsi(struct regs_decode * decode)2398 static void hyperstone_addsi(struct regs_decode *decode)
2399 {
2400 INT32 imm, res;
2401 INT64 tmp;
2402
2403 if( N_VALUE )
2404 imm = EXTRA_S;
2405 else
2406 imm = GET_C & ((GET_Z == 0 ? 1 : 0) | (DREG & 0x01));
2407
2408 tmp = (INT64)(imm) + (INT64)((INT32)(DREG));
2409 CHECK_VADD(imm,DREG,tmp);
2410
2411 //#if SETCARRYS
2412 // CHECK_C(tmp);
2413 //#endif
2414
2415 res = imm + (INT32)(DREG);
2416
2417 SET_DREG(res);
2418
2419 SET_Z( res == 0 ? 1 : 0 );
2420 SET_N( SIGN_BIT(res) );
2421
2422 m_icount -= m_clock_cycles_1;
2423
2424 if( GET_V )
2425 {
2426 UINT32 addr = get_trap_addr(TRAPNO_RANGE_ERROR);
2427 execute_exception(addr);
2428 }
2429 }
2430
hyperstone_cmpbi(struct regs_decode * decode)2431 static void hyperstone_cmpbi(struct regs_decode *decode)
2432 {
2433 UINT32 imm;
2434
2435 if( N_VALUE )
2436 {
2437 if( N_VALUE == 31 )
2438 {
2439 imm = 0x7fffffff; // bit 31 = 0, others = 1
2440 }
2441 else
2442 {
2443 imm = EXTRA_U;
2444 }
2445
2446 SET_Z( (DREG & imm) == 0 ? 1 : 0 );
2447 }
2448 else
2449 {
2450 if( (DREG & 0xff000000) == 0 || (DREG & 0x00ff0000) == 0 ||
2451 (DREG & 0x0000ff00) == 0 || (DREG & 0x000000ff) == 0 )
2452 SET_Z(1);
2453 else
2454 SET_Z(0);
2455 }
2456
2457 m_icount -= m_clock_cycles_1;
2458 }
2459
hyperstone_andni(struct regs_decode * decode)2460 static void hyperstone_andni(struct regs_decode *decode)
2461 {
2462 UINT32 imm;
2463
2464 if( N_VALUE == 31 )
2465 imm = 0x7fffffff; // bit 31 = 0, others = 1
2466 else
2467 imm = EXTRA_U;
2468
2469 DREG = DREG & ~imm;
2470
2471 SET_DREG(DREG);
2472 SET_Z( DREG == 0 ? 1 : 0 );
2473
2474 m_icount -= m_clock_cycles_1;
2475 }
2476
hyperstone_ori(struct regs_decode * decode)2477 static void hyperstone_ori(struct regs_decode *decode)
2478 {
2479 DREG = DREG | EXTRA_U;
2480
2481 SET_DREG(DREG);
2482 SET_Z( DREG == 0 ? 1 : 0 );
2483
2484 m_icount -= m_clock_cycles_1;
2485 }
2486
hyperstone_xori(struct regs_decode * decode)2487 static void hyperstone_xori(struct regs_decode *decode)
2488 {
2489 DREG = DREG ^ EXTRA_U;
2490
2491 SET_DREG(DREG);
2492 SET_Z( DREG == 0 ? 1 : 0 );
2493
2494 m_icount -= m_clock_cycles_1;
2495 }
2496
hyperstone_shrdi(struct regs_decode * decode)2497 static void hyperstone_shrdi(struct regs_decode *decode)
2498 {
2499 UINT32 low_order, high_order;
2500 UINT64 val;
2501
2502 high_order = DREG;
2503 low_order = DREGF;
2504
2505 val = CONCAT_64(high_order, low_order);
2506
2507 if( N_VALUE )
2508 SET_C((val >> (N_VALUE - 1)) & 1);
2509 else
2510 SET_C(0);
2511
2512 val >>= N_VALUE;
2513
2514 high_order = EXTRACT_64HI(val);
2515 low_order = EXTRACT_64LO(val);
2516
2517 SET_DREG(high_order);
2518 SET_DREGF(low_order);
2519 SET_Z( val == 0 ? 1 : 0 );
2520 SET_N( SIGN_BIT(high_order) );
2521
2522 m_icount -= m_clock_cycles_2;
2523 }
2524
hyperstone_shrd(struct regs_decode * decode)2525 static void hyperstone_shrd(struct regs_decode *decode)
2526 {
2527 UINT32 low_order, high_order;
2528 UINT64 val;
2529 UINT8 n = SREG & 0x1f;
2530
2531 // result undefined if Ls denotes the same register as Ld or Ldf
2532 if( SAME_SRC_DST || SAME_SRC_DSTF )
2533 {
2534 DEBUG_PRINTF(("Denoted same registers in hyperstone_shrd. PC = %08X\n", PC));
2535 }
2536 else
2537 {
2538 high_order = DREG;
2539 low_order = DREGF;
2540
2541 val = CONCAT_64(high_order, low_order);
2542
2543 if( n )
2544 SET_C((val >> (n - 1)) & 1);
2545 else
2546 SET_C(0);
2547
2548 val >>= n;
2549
2550 high_order = EXTRACT_64HI(val);
2551 low_order = EXTRACT_64LO(val);
2552
2553 SET_DREG(high_order);
2554 SET_DREGF(low_order);
2555
2556 SET_Z( val == 0 ? 1 : 0 );
2557 SET_N( SIGN_BIT(high_order) );
2558 }
2559
2560 m_icount -= m_clock_cycles_2;
2561 }
2562
hyperstone_shr(struct regs_decode * decode)2563 static void hyperstone_shr(struct regs_decode *decode)
2564 {
2565 UINT32 ret;
2566 UINT8 n;
2567
2568 n = SREG & 0x1f;
2569 ret = DREG;
2570
2571 if( n )
2572 SET_C((ret >> (n - 1)) & 1);
2573 else
2574 SET_C(0);
2575
2576 ret >>= n;
2577
2578 SET_DREG(ret);
2579 SET_Z( ret == 0 ? 1 : 0 );
2580 SET_N( SIGN_BIT(ret) );
2581
2582 m_icount -= m_clock_cycles_1;
2583 }
2584
hyperstone_sardi(struct regs_decode * decode)2585 static void hyperstone_sardi(struct regs_decode *decode)
2586 {
2587 UINT32 low_order, high_order;
2588 UINT64 val;
2589 UINT8 sign_bit;
2590
2591 high_order = DREG;
2592 low_order = DREGF;
2593
2594 val = CONCAT_64(high_order, low_order);
2595
2596 if( N_VALUE )
2597 SET_C((val >> (N_VALUE - 1)) & 1);
2598 else
2599 SET_C(0);
2600
2601 sign_bit = val >> 63;
2602 val >>= N_VALUE;
2603
2604 if( sign_bit )
2605 {
2606 int i;
2607 for( i = 0; i < N_VALUE; i++ )
2608 {
2609 val |= ((UINT64)(0x8000000000000000ULL) >> i);
2610 }
2611 }
2612
2613 high_order = val >> 32;
2614 low_order = val & 0xffffffff;
2615
2616 SET_DREG(high_order);
2617 SET_DREGF(low_order);
2618
2619 SET_Z( val == 0 ? 1 : 0 );
2620 SET_N( SIGN_BIT(high_order) );
2621
2622 m_icount -= m_clock_cycles_2;
2623 }
2624
hyperstone_sard(struct regs_decode * decode)2625 static void hyperstone_sard(struct regs_decode *decode)
2626 {
2627 UINT32 low_order, high_order;
2628 UINT64 val;
2629 UINT8 n, sign_bit;
2630
2631 n = SREG & 0x1f;
2632
2633 // result undefined if Ls denotes the same register as Ld or Ldf
2634 if( SAME_SRC_DST || SAME_SRC_DSTF )
2635 {
2636 DEBUG_PRINTF(("Denoted same registers in hyperstone_sard. PC = %08X\n", PC));
2637 }
2638 else
2639 {
2640 high_order = DREG;
2641 low_order = DREGF;
2642
2643 val = CONCAT_64(high_order, low_order);
2644
2645 if( n )
2646 SET_C((val >> (n - 1)) & 1);
2647 else
2648 SET_C(0);
2649
2650 sign_bit = val >> 63;
2651
2652 val >>= n;
2653
2654 if( sign_bit )
2655 {
2656 int i;
2657 for( i = 0; i < n; i++ )
2658 {
2659 val |= ((UINT64)(0x8000000000000000ULL) >> i);
2660 }
2661 }
2662
2663 high_order = val >> 32;
2664 low_order = val & 0xffffffff;
2665
2666 SET_DREG(high_order);
2667 SET_DREGF(low_order);
2668 SET_Z( val == 0 ? 1 : 0 );
2669 SET_N( SIGN_BIT(high_order) );
2670 }
2671
2672 m_icount -= m_clock_cycles_2;
2673 }
2674
hyperstone_sar(struct regs_decode * decode)2675 static void hyperstone_sar(struct regs_decode *decode)
2676 {
2677 UINT32 ret;
2678 UINT8 n, sign_bit;
2679
2680 n = SREG & 0x1f;
2681 ret = DREG;
2682 sign_bit = (ret & 0x80000000) >> 31;
2683
2684 if( n )
2685 SET_C((ret >> (n - 1)) & 1);
2686 else
2687 SET_C(0);
2688
2689 ret >>= n;
2690
2691 if( sign_bit )
2692 {
2693 int i;
2694 for( i = 0; i < n; i++ )
2695 {
2696 ret |= (0x80000000 >> i);
2697 }
2698 }
2699
2700 SET_DREG(ret);
2701 SET_Z( ret == 0 ? 1 : 0 );
2702 SET_N( SIGN_BIT(ret) );
2703
2704 m_icount -= m_clock_cycles_1;
2705 }
2706
hyperstone_shldi(struct regs_decode * decode)2707 static void hyperstone_shldi(struct regs_decode *decode)
2708 {
2709 UINT32 low_order, high_order, tmp;
2710 UINT64 val, mask;
2711
2712 high_order = DREG;
2713 low_order = DREGF;
2714
2715 val = CONCAT_64(high_order, low_order);
2716 SET_C( (N_VALUE)?(((val<<(N_VALUE-1))&((UINT64)(0x8000000000000000ULL)))?1:0):0);
2717 mask = ((((UINT64)1) << (32 - N_VALUE)) - 1) ^ 0xffffffff;
2718 tmp = high_order << N_VALUE;
2719
2720 if( ((high_order & mask) && (!(tmp & 0x80000000))) ||
2721 (((high_order & mask) ^ mask) && (tmp & 0x80000000)) )
2722 SET_V(1);
2723 else
2724 SET_V(0);
2725
2726 val <<= N_VALUE;
2727
2728 high_order = EXTRACT_64HI(val);
2729 low_order = EXTRACT_64LO(val);
2730
2731 SET_DREG(high_order);
2732 SET_DREGF(low_order);
2733
2734 SET_Z( val == 0 ? 1 : 0 );
2735 SET_N( SIGN_BIT(high_order) );
2736
2737 m_icount -= m_clock_cycles_2;
2738 }
2739
hyperstone_shld(struct regs_decode * decode)2740 static void hyperstone_shld(struct regs_decode *decode)
2741 {
2742 UINT32 low_order, high_order, tmp, n;
2743 UINT64 val, mask;
2744
2745 n = SREG & 0x1f;
2746
2747 // result undefined if Ls denotes the same register as Ld or Ldf
2748 if( SAME_SRC_DST || SAME_SRC_DSTF )
2749 {
2750 DEBUG_PRINTF(("Denoted same registers in hyperstone_shld. PC = %08X\n", PC));
2751 }
2752 else
2753 {
2754 high_order = DREG;
2755 low_order = DREGF;
2756
2757 mask = ((((UINT64)1) << (32 - n)) - 1) ^ 0xffffffff;
2758
2759 val = CONCAT_64(high_order, low_order);
2760 SET_C( (n)?(((val<<(n-1))&((UINT64)(0x8000000000000000ULL)))?1:0):0);
2761 tmp = high_order << n;
2762
2763 if( ((high_order & mask) && (!(tmp & 0x80000000))) ||
2764 (((high_order & mask) ^ mask) && (tmp & 0x80000000)) )
2765 SET_V(1);
2766 else
2767 SET_V(0);
2768
2769 val <<= n;
2770
2771 high_order = EXTRACT_64HI(val);
2772 low_order = EXTRACT_64LO(val);
2773
2774 SET_DREG(high_order);
2775 SET_DREGF(low_order);
2776
2777 SET_Z( val == 0 ? 1 : 0 );
2778 SET_N( SIGN_BIT(high_order) );
2779 }
2780
2781 m_icount -= m_clock_cycles_2;
2782 }
2783
hyperstone_shl(struct regs_decode * decode)2784 static void hyperstone_shl(struct regs_decode *decode)
2785 {
2786 UINT32 base, ret, n;
2787 UINT64 mask;
2788
2789 n = SREG & 0x1f;
2790 base = DREG;
2791 mask = ((((UINT64)1) << (32 - n)) - 1) ^ 0xffffffff;
2792 SET_C( (n)?(((base<<(n-1))&0x80000000)?1:0):0);
2793 ret = base << n;
2794
2795 if( ((base & mask) && (!(ret & 0x80000000))) ||
2796 (((base & mask) ^ mask) && (ret & 0x80000000)) )
2797 SET_V(1);
2798 else
2799 SET_V(0);
2800
2801 SET_DREG(ret);
2802 SET_Z( ret == 0 ? 1 : 0 );
2803 SET_N( SIGN_BIT(ret) );
2804
2805 m_icount -= m_clock_cycles_1;
2806 }
2807
reserved(struct regs_decode * decode)2808 static void reserved(struct regs_decode *decode)
2809 {
2810 DEBUG_PRINTF(("Executed Reserved opcode. PC = %08X OP = %04X\n", PC, OP));
2811 }
2812
hyperstone_testlz(struct regs_decode * decode)2813 static void hyperstone_testlz(struct regs_decode *decode)
2814 {
2815 UINT8 zeros = 0;
2816 UINT32 mask;
2817
2818 for( mask = 0x80000000; ; mask >>= 1 )
2819 {
2820 if( SREG & mask )
2821 break;
2822 else
2823 zeros++;
2824
2825 if( zeros == 32 )
2826 break;
2827 }
2828
2829 SET_DREG(zeros);
2830
2831 m_icount -= m_clock_cycles_2;
2832 }
2833
hyperstone_rol(struct regs_decode * decode)2834 static void hyperstone_rol(struct regs_decode *decode)
2835 {
2836 UINT32 val, base;
2837 UINT8 n;
2838 UINT64 mask;
2839
2840 n = SREG & 0x1f;
2841
2842 val = base = DREG;
2843
2844 mask = ((((UINT64)1) << (32 - n)) - 1) ^ 0xffffffff;
2845
2846 while( n > 0 )
2847 {
2848 val = (val << 1) | ((val & 0x80000000) >> 31);
2849 n--;
2850 }
2851
2852 #ifdef MISSIONCRAFT_FLAGS
2853
2854 if( ((base & mask) && (!(val & 0x80000000))) ||
2855 (((base & mask) ^ mask) && (val & 0x80000000)) )
2856 SET_V(1);
2857 else
2858 SET_V(0);
2859
2860 #endif
2861
2862 SET_DREG(val);
2863
2864 SET_Z( val == 0 ? 1 : 0 );
2865 SET_N( SIGN_BIT(val) );
2866
2867 m_icount -= m_clock_cycles_1;
2868 }
2869
2870 //TODO: add trap error
hyperstone_ldxx1(struct regs_decode * decode)2871 static void hyperstone_ldxx1(struct regs_decode *decode)
2872 {
2873 UINT32 load;
2874
2875 if( DST_IS_SR )
2876 {
2877 switch( decode->sub_type )
2878 {
2879 case 0: // LDBS.A
2880
2881 load = READ_B(EXTRA_S);
2882 load |= (load & 0x80) ? 0xffffff00 : 0;
2883 SET_SREG(load);
2884
2885 break;
2886
2887 case 1: // LDBU.A
2888
2889 load = READ_B(EXTRA_S);
2890 SET_SREG(load);
2891
2892 break;
2893
2894 case 2:
2895
2896 load = READ_HW(EXTRA_S & ~1);
2897
2898 if( EXTRA_S & 1 ) // LDHS.A
2899 {
2900 load |= (load & 0x8000) ? 0xffff0000 : 0;
2901 }
2902 /*
2903 else // LDHU.A
2904 {
2905 // nothing more
2906 }
2907 */
2908
2909 SET_SREG(load);
2910
2911 break;
2912
2913 case 3:
2914
2915 if( (EXTRA_S & 3) == 3 ) // LDD.IOA
2916 {
2917 load = IO_READ_W(EXTRA_S & ~3);
2918 SET_SREG(load);
2919
2920 load = IO_READ_W((EXTRA_S & ~3) + 4);
2921 SET_SREGF(load);
2922
2923 m_icount -= m_clock_cycles_1; // extra cycle
2924 }
2925 else if( (EXTRA_S & 3) == 2 ) // LDW.IOA
2926 {
2927 load = IO_READ_W(EXTRA_S & ~3);
2928 SET_SREG(load);
2929 }
2930 else if( (EXTRA_S & 3) == 1 ) // LDD.A
2931 {
2932 load = READ_W(EXTRA_S & ~1);
2933 SET_SREG(load);
2934
2935 load = READ_W((EXTRA_S & ~1) + 4);
2936 SET_SREGF(load);
2937
2938 m_icount -= m_clock_cycles_1; // extra cycle
2939 }
2940 else // LDW.A
2941 {
2942 load = READ_W(EXTRA_S & ~1);
2943 SET_SREG(load);
2944 }
2945
2946 break;
2947 }
2948 }
2949 else
2950 {
2951 switch( decode->sub_type )
2952 {
2953 case 0: // LDBS.D
2954
2955 load = READ_B(DREG + EXTRA_S);
2956 load |= (load & 0x80) ? 0xffffff00 : 0;
2957 SET_SREG(load);
2958
2959 break;
2960
2961 case 1: // LDBU.D
2962
2963 load = READ_B(DREG + EXTRA_S);
2964 SET_SREG(load);
2965
2966 break;
2967
2968 case 2:
2969
2970 load = READ_HW(DREG + (EXTRA_S & ~1));
2971
2972 if( EXTRA_S & 1 ) // LDHS.D
2973 {
2974 load |= (load & 0x8000) ? 0xffff0000 : 0;
2975 }
2976 /*
2977 else // LDHU.D
2978 {
2979 // nothing more
2980 }
2981 */
2982
2983 SET_SREG(load);
2984
2985 break;
2986
2987 case 3:
2988
2989 if( (EXTRA_S & 3) == 3 ) // LDD.IOD
2990 {
2991 load = IO_READ_W(DREG + (EXTRA_S & ~3));
2992 SET_SREG(load);
2993
2994 load = IO_READ_W(DREG + (EXTRA_S & ~3) + 4);
2995 SET_SREGF(load);
2996
2997 m_icount -= m_clock_cycles_1; // extra cycle
2998 }
2999 else if( (EXTRA_S & 3) == 2 ) // LDW.IOD
3000 {
3001 load = IO_READ_W(DREG + (EXTRA_S & ~3));
3002 SET_SREG(load);
3003 }
3004 else if( (EXTRA_S & 3) == 1 ) // LDD.D
3005 {
3006 load = READ_W(DREG + (EXTRA_S & ~1));
3007 SET_SREG(load);
3008
3009 load = READ_W(DREG + (EXTRA_S & ~1) + 4);
3010 SET_SREGF(load);
3011
3012 m_icount -= m_clock_cycles_1; // extra cycle
3013 }
3014 else // LDW.D
3015 {
3016 load = READ_W(DREG + (EXTRA_S & ~1));
3017 SET_SREG(load);
3018 }
3019
3020 break;
3021 }
3022 }
3023
3024 m_icount -= m_clock_cycles_1;
3025 }
3026
hyperstone_ldxx2(struct regs_decode * decode)3027 static void hyperstone_ldxx2(struct regs_decode *decode)
3028 {
3029 UINT32 load;
3030
3031 if( DST_IS_PC || DST_IS_SR )
3032 {
3033 DEBUG_PRINTF(("Denoted PC or SR in hyperstone_ldxx2. PC = %08X\n", PC));
3034 }
3035 else
3036 {
3037 switch( decode->sub_type )
3038 {
3039 case 0: // LDBS.N
3040
3041 if(SAME_SRC_DST)
3042 DEBUG_PRINTF(("LDBS.N denoted same regs @ %08X",PPC));
3043
3044 load = READ_B(DREG);
3045 load |= (load & 0x80) ? 0xffffff00 : 0;
3046 SET_SREG(load);
3047
3048 if(!SAME_SRC_DST)
3049 SET_DREG(DREG + EXTRA_S);
3050
3051 break;
3052
3053 case 1: // LDBU.N
3054
3055 if(SAME_SRC_DST)
3056 DEBUG_PRINTF(("LDBU.N denoted same regs @ %08X",PPC));
3057
3058 load = READ_B(DREG);
3059 SET_SREG(load);
3060
3061 if(!SAME_SRC_DST)
3062 SET_DREG(DREG + EXTRA_S);
3063
3064 break;
3065
3066 case 2:
3067
3068 load = READ_HW(DREG);
3069
3070 if( EXTRA_S & 1 ) // LDHS.N
3071 {
3072 load |= (load & 0x8000) ? 0xffff0000 : 0;
3073
3074 if(SAME_SRC_DST)
3075 DEBUG_PRINTF(("LDHS.N denoted same regs @ %08X",PPC));
3076 }
3077 /*
3078 else // LDHU.N
3079 {
3080 // nothing more
3081 }
3082 */
3083
3084 SET_SREG(load);
3085
3086 if(!SAME_SRC_DST)
3087 SET_DREG(DREG + (EXTRA_S & ~1));
3088
3089 break;
3090
3091 case 3:
3092
3093 if( (EXTRA_S & 3) == 3 ) // LDW.S
3094 {
3095 if(SAME_SRC_DST)
3096 DEBUG_PRINTF(("LDW.S denoted same regs @ %08X",PPC));
3097
3098 if(DREG < SP)
3099 SET_SREG(READ_W(DREG));
3100 else
3101 SET_SREG(GET_ABS_L_REG((DREG & 0xfc) >> 2));
3102
3103 if(!SAME_SRC_DST)
3104 SET_DREG(DREG + (EXTRA_S & ~3));
3105
3106 m_icount -= m_clock_cycles_2; // extra cycles
3107 }
3108 else if( (EXTRA_S & 3) == 2 ) // Reserved
3109 {
3110 DEBUG_PRINTF(("Executed Reserved instruction in hyperstone_ldxx2. PC = %08X\n", PC));
3111 }
3112 else if( (EXTRA_S & 3) == 1 ) // LDD.N
3113 {
3114 if(SAME_SRC_DST || SAME_SRCF_DST)
3115 DEBUG_PRINTF(("LDD.N denoted same regs @ %08X",PPC));
3116
3117 load = READ_W(DREG);
3118 SET_SREG(load);
3119
3120 load = READ_W(DREG + 4);
3121 SET_SREGF(load);
3122
3123 if(!SAME_SRC_DST && !SAME_SRCF_DST)
3124 SET_DREG(DREG + (EXTRA_S & ~1));
3125
3126 m_icount -= m_clock_cycles_1; // extra cycle
3127 }
3128 else // LDW.N
3129 {
3130 if(SAME_SRC_DST)
3131 DEBUG_PRINTF(("LDW.N denoted same regs @ %08X",PPC));
3132
3133 load = READ_W(DREG);
3134 SET_SREG(load);
3135
3136 if(!SAME_SRC_DST)
3137 SET_DREG(DREG + (EXTRA_S & ~1));
3138 }
3139
3140 break;
3141 }
3142 }
3143
3144 m_icount -= m_clock_cycles_1;
3145 }
3146
3147 //TODO: add trap error
hyperstone_stxx1(struct regs_decode * decode)3148 static void hyperstone_stxx1(struct regs_decode *decode)
3149 {
3150 if( SRC_IS_SR )
3151 SREG = SREGF = 0;
3152
3153 if( DST_IS_SR )
3154 {
3155 switch( decode->sub_type )
3156 {
3157 case 0: // STBS.A
3158
3159 /* TODO: missing trap on range error */
3160 WRITE_B(EXTRA_S, SREG & 0xff);
3161
3162 break;
3163
3164 case 1: // STBU.A
3165
3166 WRITE_B(EXTRA_S, SREG & 0xff);
3167
3168 break;
3169
3170 case 2:
3171
3172 WRITE_HW(EXTRA_S & ~1, SREG & 0xffff);
3173
3174 /*
3175 if( EXTRA_S & 1 ) // STHS.A
3176 {
3177 // TODO: missing trap on range error
3178 }
3179 else // STHU.A
3180 {
3181 // nothing more
3182 }
3183 */
3184
3185 break;
3186
3187 case 3:
3188
3189 if( (EXTRA_S & 3) == 3 ) // STD.IOA
3190 {
3191 IO_WRITE_W(EXTRA_S & ~3, SREG);
3192 IO_WRITE_W((EXTRA_S & ~3) + 4, SREGF);
3193
3194 m_icount -= m_clock_cycles_1; // extra cycle
3195 }
3196 else if( (EXTRA_S & 3) == 2 ) // STW.IOA
3197 {
3198 IO_WRITE_W(EXTRA_S & ~3, SREG);
3199 }
3200 else if( (EXTRA_S & 3) == 1 ) // STD.A
3201 {
3202 WRITE_W(EXTRA_S & ~1, SREG);
3203 WRITE_W((EXTRA_S & ~1) + 4, SREGF);
3204
3205 m_icount -= m_clock_cycles_1; // extra cycle
3206 }
3207 else // STW.A
3208 {
3209 WRITE_W(EXTRA_S & ~1, SREG);
3210 }
3211
3212 break;
3213 }
3214 }
3215 else
3216 {
3217 switch( decode->sub_type )
3218 {
3219 case 0: // STBS.D
3220
3221 /* TODO: missing trap on range error */
3222 WRITE_B(DREG + EXTRA_S, SREG & 0xff);
3223
3224 break;
3225
3226 case 1: // STBU.D
3227
3228 WRITE_B(DREG + EXTRA_S, SREG & 0xff);
3229
3230 break;
3231
3232 case 2:
3233
3234 WRITE_HW(DREG + (EXTRA_S & ~1), SREG & 0xffff);
3235
3236 /*
3237 if( EXTRA_S & 1 ) // STHS.D
3238 {
3239 // TODO: missing trap on range error
3240 }
3241 else // STHU.D
3242 {
3243 // nothing more
3244 }
3245 */
3246
3247 break;
3248
3249 case 3:
3250
3251 if( (EXTRA_S & 3) == 3 ) // STD.IOD
3252 {
3253 IO_WRITE_W(DREG + (EXTRA_S & ~3), SREG);
3254 IO_WRITE_W(DREG + (EXTRA_S & ~3) + 4, SREGF);
3255
3256 m_icount -= m_clock_cycles_1; // extra cycle
3257 }
3258 else if( (EXTRA_S & 3) == 2 ) // STW.IOD
3259 {
3260 IO_WRITE_W(DREG + (EXTRA_S & ~3), SREG);
3261 }
3262 else if( (EXTRA_S & 3) == 1 ) // STD.D
3263 {
3264 WRITE_W(DREG + (EXTRA_S & ~1), SREG);
3265 WRITE_W(DREG + (EXTRA_S & ~1) + 4, SREGF);
3266
3267 m_icount -= m_clock_cycles_1; // extra cycle
3268 }
3269 else // STW.D
3270 {
3271 WRITE_W(DREG + (EXTRA_S & ~1), SREG);
3272 }
3273
3274 break;
3275 }
3276 }
3277
3278 m_icount -= m_clock_cycles_1;
3279 }
3280
hyperstone_stxx2(struct regs_decode * decode)3281 static void hyperstone_stxx2(struct regs_decode *decode)
3282 {
3283 if( SRC_IS_SR )
3284 SREG = SREGF = 0;
3285
3286 if( DST_IS_PC || DST_IS_SR )
3287 {
3288 DEBUG_PRINTF(("Denoted PC or SR in hyperstone_stxx2. PC = %08X\n", PC));
3289 }
3290 else
3291 {
3292 switch( decode->sub_type )
3293 {
3294 case 0: // STBS.N
3295
3296 /* TODO: missing trap on range error */
3297 WRITE_B(DREG, SREG & 0xff);
3298 SET_DREG(DREG + EXTRA_S);
3299
3300 break;
3301
3302 case 1: // STBU.N
3303
3304 WRITE_B(DREG, SREG & 0xff);
3305 SET_DREG(DREG + EXTRA_S);
3306
3307 break;
3308
3309 case 2:
3310
3311 WRITE_HW(DREG, SREG & 0xffff);
3312 SET_DREG(DREG + (EXTRA_S & ~1));
3313
3314 /*
3315 if( EXTRA_S & 1 ) // STHS.N
3316 {
3317 // TODO: missing trap on range error
3318 }
3319 else // STHU.N
3320 {
3321 // nothing more
3322 }
3323 */
3324
3325 break;
3326
3327 case 3:
3328
3329 if( (EXTRA_S & 3) == 3 ) // STW.S
3330 {
3331 if(DREG < SP)
3332 WRITE_W(DREG, SREG);
3333 else
3334 {
3335 if(((DREG & 0xfc) >> 2) == ((decode->src + GET_FP) % 64) && S_BIT == LOCAL)
3336 DEBUG_PRINTF(("STW.S denoted the same local register @ %08X\n",PPC));
3337
3338 SET_ABS_L_REG((DREG & 0xfc) >> 2,SREG);
3339 }
3340
3341 SET_DREG(DREG + (EXTRA_S & ~3));
3342
3343 m_icount -= m_clock_cycles_2; // extra cycles
3344
3345 }
3346 else if( (EXTRA_S & 3) == 2 ) // Reserved
3347 {
3348 DEBUG_PRINTF(("Executed Reserved instruction in hyperstone_stxx2. PC = %08X\n", PC));
3349 }
3350 else if( (EXTRA_S & 3) == 1 ) // STD.N
3351 {
3352 WRITE_W(DREG, SREG);
3353 SET_DREG(DREG + (EXTRA_S & ~1));
3354
3355 if( SAME_SRCF_DST )
3356 WRITE_W(DREG + 4, SREGF + (EXTRA_S & ~1)); // because DREG == SREGF and DREG has been incremented
3357 else
3358 WRITE_W(DREG + 4, SREGF);
3359
3360 m_icount -= m_clock_cycles_1; // extra cycle
3361 }
3362 else // STW.N
3363 {
3364 WRITE_W(DREG, SREG);
3365 SET_DREG(DREG + (EXTRA_S & ~1));
3366 }
3367
3368 break;
3369 }
3370 }
3371
3372 m_icount -= m_clock_cycles_1;
3373 }
3374
hyperstone_shri(struct regs_decode * decode)3375 static void hyperstone_shri(struct regs_decode *decode)
3376 {
3377 UINT32 val;
3378
3379 val = DREG;
3380
3381 if( N_VALUE )
3382 SET_C((val >> (N_VALUE - 1)) & 1);
3383 else
3384 SET_C(0);
3385
3386 val >>= N_VALUE;
3387
3388 SET_DREG(val);
3389 SET_Z( val == 0 ? 1 : 0 );
3390 SET_N( SIGN_BIT(val) );
3391
3392 m_icount -= m_clock_cycles_1;
3393 }
3394
hyperstone_sari(struct regs_decode * decode)3395 static void hyperstone_sari(struct regs_decode *decode)
3396 {
3397 UINT32 val;
3398 UINT8 sign_bit;
3399
3400 val = DREG;
3401 sign_bit = (val & 0x80000000) >> 31;
3402
3403 if( N_VALUE )
3404 SET_C((val >> (N_VALUE - 1)) & 1);
3405 else
3406 SET_C(0);
3407
3408 val >>= N_VALUE;
3409
3410 if( sign_bit )
3411 {
3412 int i;
3413 for( i = 0; i < N_VALUE; i++ )
3414 {
3415 val |= (0x80000000 >> i);
3416 }
3417 }
3418
3419 SET_DREG(val);
3420 SET_Z( val == 0 ? 1 : 0 );
3421 SET_N( SIGN_BIT(val) );
3422
3423 m_icount -= m_clock_cycles_1;
3424 }
3425
hyperstone_shli(struct regs_decode * decode)3426 static void hyperstone_shli(struct regs_decode *decode)
3427 {
3428 UINT32 val, val2;
3429 UINT64 mask;
3430
3431 val = DREG;
3432 SET_C( (N_VALUE)?(((val<<(N_VALUE-1))&0x80000000)?1:0):0);
3433 mask = ((((UINT64)1) << (32 - N_VALUE)) - 1) ^ 0xffffffff;
3434 val2 = val << N_VALUE;
3435
3436 if( ((val & mask) && (!(val2 & 0x80000000))) ||
3437 (((val & mask) ^ mask) && (val2 & 0x80000000)) )
3438 SET_V(1);
3439 else
3440 SET_V(0);
3441
3442 SET_DREG(val2);
3443 SET_Z( val2 == 0 ? 1 : 0 );
3444 SET_N( SIGN_BIT(val2) );
3445
3446 m_icount -= m_clock_cycles_1;
3447 }
3448
hyperstone_mulu(struct regs_decode * decode)3449 static void hyperstone_mulu(struct regs_decode *decode)
3450 {
3451 UINT32 low_order, high_order;
3452 UINT64 double_word;
3453
3454 // PC or SR aren't denoted, else result is undefined
3455 if( SRC_IS_PC || SRC_IS_SR || DST_IS_PC || DST_IS_SR )
3456 {
3457 DEBUG_PRINTF(("Denoted PC or SR in hyperstone_mulu instruction. PC = %08X\n", PC));
3458 }
3459 else
3460 {
3461 double_word = (UINT64)SREG *(UINT64)DREG;
3462
3463 low_order = double_word & 0xffffffff;
3464 high_order = double_word >> 32;
3465
3466 SET_DREG(high_order);
3467 SET_DREGF(low_order);
3468
3469 SET_Z( double_word == 0 ? 1 : 0 );
3470 SET_N( SIGN_BIT(high_order) );
3471 }
3472
3473 if(SREG <= 0xffff && DREG <= 0xffff)
3474 m_icount -= m_clock_cycles_4;
3475 else
3476 m_icount -= m_clock_cycles_6;
3477 }
3478
hyperstone_muls(struct regs_decode * decode)3479 static void hyperstone_muls(struct regs_decode *decode)
3480 {
3481 UINT32 low_order, high_order;
3482 INT64 double_word;
3483
3484 // PC or SR aren't denoted, else result is undefined
3485 if( SRC_IS_PC || SRC_IS_SR || DST_IS_PC || DST_IS_SR )
3486 {
3487 DEBUG_PRINTF(("Denoted PC or SR in hyperstone_muls instruction. PC = %08X\n", PC));
3488 }
3489 else
3490 {
3491 double_word = (INT64)(INT32)(SREG) * (INT64)(INT32)(DREG);
3492 low_order = double_word & 0xffffffff;
3493 high_order = double_word >> 32;
3494
3495 SET_DREG(high_order);
3496 SET_DREGF(low_order);
3497
3498 SET_Z( double_word == 0 ? 1 : 0 );
3499 SET_N( SIGN_BIT(high_order) );
3500 }
3501
3502 if((SREG >= 0xffff8000 && SREG <= 0x7fff) && (DREG >= 0xffff8000 && DREG <= 0x7fff))
3503 m_icount -= m_clock_cycles_4;
3504 else
3505 m_icount -= m_clock_cycles_6;
3506 }
3507
hyperstone_set(struct regs_decode * decode)3508 static void hyperstone_set(struct regs_decode *decode)
3509 {
3510 int n = N_VALUE;
3511
3512 if( DST_IS_PC )
3513 {
3514 DEBUG_PRINTF(("Denoted PC in hyperstone_set. PC = %08X\n", PC));
3515 }
3516 else if( DST_IS_SR )
3517 {
3518 //TODO: add fetch opcode when there's the pipeline
3519
3520 //TODO: no 1!
3521 m_icount -= m_clock_cycles_1;
3522 }
3523 else
3524 {
3525 switch( n )
3526 {
3527 // SETADR
3528 case 0:
3529 {
3530 UINT32 val;
3531 val = (SP & 0xfffffe00) | (GET_FP << 2);
3532
3533 //plus carry into bit 9
3534 val += (( (SP & 0x100) && (SIGN_BIT(SR) == 0) ) ? 1 : 0);
3535
3536 SET_DREG(val);
3537
3538 break;
3539 }
3540 // Reserved
3541 case 1:
3542 case 16:
3543 case 17:
3544 case 19:
3545 DEBUG_PRINTF(("Used reserved N value (%d) in hyperstone_set. PC = %08X\n", n, PC));
3546 break;
3547
3548 // SETxx
3549 case 2:
3550 SET_DREG(1);
3551 break;
3552
3553 case 3:
3554 SET_DREG(0);
3555 break;
3556
3557 case 4:
3558 if( GET_N || GET_Z )
3559 {
3560 SET_DREG(1);
3561 }
3562 else
3563 {
3564 SET_DREG(0);
3565 }
3566
3567 break;
3568
3569 case 5:
3570 if( !GET_N && !GET_Z )
3571 {
3572 SET_DREG(1);
3573 }
3574 else
3575 {
3576 SET_DREG(0);
3577 }
3578
3579 break;
3580
3581 case 6:
3582 if( GET_N )
3583 {
3584 SET_DREG(1);
3585 }
3586 else
3587 {
3588 SET_DREG(0);
3589 }
3590
3591 break;
3592
3593 case 7:
3594 if( !GET_N )
3595 {
3596 SET_DREG(1);
3597 }
3598 else
3599 {
3600 SET_DREG(0);
3601 }
3602
3603 break;
3604
3605 case 8:
3606 if( GET_C || GET_Z )
3607 {
3608 SET_DREG(1);
3609 }
3610 else
3611 {
3612 SET_DREG(0);
3613 }
3614
3615 break;
3616
3617 case 9:
3618 if( !GET_C && !GET_Z )
3619 {
3620 SET_DREG(1);
3621 }
3622 else
3623 {
3624 SET_DREG(0);
3625 }
3626
3627 break;
3628
3629 case 10:
3630 if( GET_C )
3631 {
3632 SET_DREG(1);
3633 }
3634 else
3635 {
3636 SET_DREG(0);
3637 }
3638
3639 break;
3640
3641 case 11:
3642 if( !GET_C )
3643 {
3644 SET_DREG(1);
3645 }
3646 else
3647 {
3648 SET_DREG(0);
3649 }
3650
3651 break;
3652
3653 case 12:
3654 if( GET_Z )
3655 {
3656 SET_DREG(1);
3657 }
3658 else
3659 {
3660 SET_DREG(0);
3661 }
3662
3663 break;
3664
3665 case 13:
3666 if( !GET_Z )
3667 {
3668 SET_DREG(1);
3669 }
3670 else
3671 {
3672 SET_DREG(0);
3673 }
3674
3675 break;
3676
3677 case 14:
3678 if( GET_V )
3679 {
3680 SET_DREG(1);
3681 }
3682 else
3683 {
3684 SET_DREG(0);
3685 }
3686
3687 break;
3688
3689 case 15:
3690 if( !GET_V )
3691 {
3692 SET_DREG(1);
3693 }
3694 else
3695 {
3696 SET_DREG(0);
3697 }
3698
3699 break;
3700
3701 case 18:
3702 SET_DREG(-1);
3703 break;
3704
3705 case 20:
3706 if( GET_N || GET_Z )
3707 {
3708 SET_DREG(-1);
3709 }
3710 else
3711 {
3712 SET_DREG(0);
3713 }
3714
3715 break;
3716
3717 case 21:
3718 if( !GET_N && !GET_Z )
3719 {
3720 SET_DREG(-1);
3721 }
3722 else
3723 {
3724 SET_DREG(0);
3725 }
3726
3727 break;
3728
3729 case 22:
3730 if( GET_N )
3731 {
3732 SET_DREG(-1);
3733 }
3734 else
3735 {
3736 SET_DREG(0);
3737 }
3738
3739 break;
3740
3741 case 23:
3742 if( !GET_N )
3743 {
3744 SET_DREG(-1);
3745 }
3746 else
3747 {
3748 SET_DREG(0);
3749 }
3750
3751 break;
3752
3753 case 24:
3754 if( GET_C || GET_Z )
3755 {
3756 SET_DREG(-1);
3757 }
3758 else
3759 {
3760 SET_DREG(0);
3761 }
3762
3763 break;
3764
3765 case 25:
3766 if( !GET_C && !GET_Z )
3767 {
3768 SET_DREG(-1);
3769 }
3770 else
3771 {
3772 SET_DREG(0);
3773 }
3774
3775 break;
3776
3777 case 26:
3778 if( GET_C )
3779 {
3780 SET_DREG(-1);
3781 }
3782 else
3783 {
3784 SET_DREG(0);
3785 }
3786
3787 break;
3788
3789 case 27:
3790 if( !GET_C )
3791 {
3792 SET_DREG(-1);
3793 }
3794 else
3795 {
3796 SET_DREG(0);
3797 }
3798
3799 break;
3800
3801 case 28:
3802 if( GET_Z )
3803 {
3804 SET_DREG(-1);
3805 }
3806 else
3807 {
3808 SET_DREG(0);
3809 }
3810
3811 break;
3812
3813 case 29:
3814 if( !GET_Z )
3815 {
3816 SET_DREG(-1);
3817 }
3818 else
3819 {
3820 SET_DREG(0);
3821 }
3822
3823 break;
3824
3825 case 30:
3826 if( GET_V )
3827 {
3828 SET_DREG(-1);
3829 }
3830 else
3831 {
3832 SET_DREG(0);
3833 }
3834
3835 break;
3836
3837 case 31:
3838 if( !GET_V )
3839 {
3840 SET_DREG(-1);
3841 }
3842 else
3843 {
3844 SET_DREG(0);
3845 }
3846
3847 break;
3848 }
3849
3850 m_icount -= m_clock_cycles_1;
3851 }
3852 }
3853
hyperstone_mul(struct regs_decode * decode)3854 static void hyperstone_mul(struct regs_decode *decode)
3855 {
3856 UINT32 single_word;
3857
3858 // PC or SR aren't denoted, else result is undefined
3859 if( SRC_IS_PC || SRC_IS_SR || DST_IS_PC || DST_IS_SR )
3860 {
3861 DEBUG_PRINTF(("Denoted PC or SR in hyperstone_mul instruction. PC = %08X\n", PC));
3862 }
3863 else
3864 {
3865 single_word = (SREG * DREG);// & 0xffffffff; // only the low-order word is taken
3866
3867 SET_DREG(single_word);
3868
3869 SET_Z( single_word == 0 ? 1 : 0 );
3870 SET_N( SIGN_BIT(single_word) );
3871 }
3872
3873 if((SREG >= 0xffff8000 && SREG <= 0x7fff) && (DREG >= 0xffff8000 && DREG <= 0x7fff))
3874 m_icount -= 3 << m_clock_scale;
3875 else
3876 m_icount -= 5 << m_clock_scale;
3877 }
3878
hyperstone_fadd(struct regs_decode * decode)3879 static void hyperstone_fadd(struct regs_decode *decode)
3880 {
3881 execute_software(decode);
3882 m_icount -= m_clock_cycles_6;
3883 }
3884
hyperstone_faddd(struct regs_decode * decode)3885 static void hyperstone_faddd(struct regs_decode *decode)
3886 {
3887 execute_software(decode);
3888 m_icount -= m_clock_cycles_6;
3889 }
3890
hyperstone_fsub(struct regs_decode * decode)3891 static void hyperstone_fsub(struct regs_decode *decode)
3892 {
3893 execute_software(decode);
3894 m_icount -= m_clock_cycles_6;
3895 }
3896
hyperstone_fsubd(struct regs_decode * decode)3897 static void hyperstone_fsubd(struct regs_decode *decode)
3898 {
3899 execute_software(decode);
3900 m_icount -= m_clock_cycles_6;
3901 }
3902
hyperstone_fmul(struct regs_decode * decode)3903 static void hyperstone_fmul(struct regs_decode *decode)
3904 {
3905 execute_software(decode);
3906 m_icount -= m_clock_cycles_6;
3907 }
3908
hyperstone_fmuld(struct regs_decode * decode)3909 static void hyperstone_fmuld(struct regs_decode *decode)
3910 {
3911 execute_software(decode);
3912 m_icount -= m_clock_cycles_6;
3913 }
3914
hyperstone_fdiv(struct regs_decode * decode)3915 static void hyperstone_fdiv(struct regs_decode *decode)
3916 {
3917 execute_software(decode);
3918 m_icount -= m_clock_cycles_6;
3919 }
3920
hyperstone_fdivd(struct regs_decode * decode)3921 static void hyperstone_fdivd(struct regs_decode *decode)
3922 {
3923 execute_software(decode);
3924 m_icount -= m_clock_cycles_6;
3925 }
3926
hyperstone_fcmp(struct regs_decode * decode)3927 static void hyperstone_fcmp(struct regs_decode *decode)
3928 {
3929 execute_software(decode);
3930 m_icount -= m_clock_cycles_6;
3931 }
3932
hyperstone_fcmpd(struct regs_decode * decode)3933 static void hyperstone_fcmpd(struct regs_decode *decode)
3934 {
3935 execute_software(decode);
3936 m_icount -= m_clock_cycles_6;
3937 }
3938
hyperstone_fcmpu(struct regs_decode * decode)3939 static void hyperstone_fcmpu(struct regs_decode *decode)
3940 {
3941 execute_software(decode);
3942 m_icount -= m_clock_cycles_6;
3943 }
3944
hyperstone_fcmpud(struct regs_decode * decode)3945 static void hyperstone_fcmpud(struct regs_decode *decode)
3946 {
3947 execute_software(decode);
3948 m_icount -= m_clock_cycles_6;
3949 }
3950
hyperstone_fcvt(struct regs_decode * decode)3951 static void hyperstone_fcvt(struct regs_decode *decode)
3952 {
3953 execute_software(decode);
3954 m_icount -= m_clock_cycles_6;
3955 }
3956
hyperstone_fcvtd(struct regs_decode * decode)3957 static void hyperstone_fcvtd(struct regs_decode *decode)
3958 {
3959 execute_software(decode);
3960 m_icount -= m_clock_cycles_6;
3961 }
3962
hyperstone_extend(struct regs_decode * decode)3963 static void hyperstone_extend(struct regs_decode *decode)
3964 {
3965 //TODO: add locks, overflow error and other things
3966 UINT32 vals, vald;
3967
3968 vals = SREG;
3969 vald = DREG;
3970
3971 switch( EXTRA_U ) // extended opcode
3972 {
3973 // signed or unsigned multiplication, single word product
3974 case EMUL:
3975 case 0x100: // used in "N" type cpu
3976 {
3977 UINT32 result;
3978
3979 result = vals * vald;
3980 SET_G_REG(15, result);
3981
3982 break;
3983 }
3984 // unsigned multiplication, double word product
3985 case EMULU:
3986 {
3987 UINT64 result;
3988
3989 result = (UINT64)vals * (UINT64)vald;
3990 vals = result >> 32;
3991 vald = result & 0xffffffff;
3992 SET_G_REG(14, vals);
3993 SET_G_REG(15, vald);
3994
3995 break;
3996 }
3997 // signed multiplication, double word product
3998 case EMULS:
3999 {
4000 INT64 result;
4001
4002 result = (INT64)(INT32)(vals) * (INT64)(INT32)(vald);
4003 vals = result >> 32;
4004 vald = result & 0xffffffff;
4005 SET_G_REG(14, vals);
4006 SET_G_REG(15, vald);
4007
4008 break;
4009 }
4010 // signed multiply/add, single word product sum
4011 case EMAC:
4012 {
4013 INT32 result;
4014
4015 result = (INT32)GET_G_REG(15) + ((INT32)(vals) * (INT32)(vald));
4016 SET_G_REG(15, result);
4017
4018 break;
4019 }
4020 // signed multiply/add, double word product sum
4021 case EMACD:
4022 {
4023 INT64 result;
4024
4025 result = (INT64)CONCAT_64(GET_G_REG(14), GET_G_REG(15)) + (INT64)((INT64)(INT32)(vals) * (INT64)(INT32)(vald));
4026
4027 vals = result >> 32;
4028 vald = result & 0xffffffff;
4029 SET_G_REG(14, vals);
4030 SET_G_REG(15, vald);
4031
4032 break;
4033 }
4034 // signed multiply/substract, single word product difference
4035 case EMSUB:
4036 {
4037 INT32 result;
4038
4039 result = (INT32)GET_G_REG(15) - ((INT32)(vals) * (INT32)(vald));
4040 SET_G_REG(15, result);
4041
4042 break;
4043 }
4044 // signed multiply/substract, double word product difference
4045 case EMSUBD:
4046 {
4047 INT64 result;
4048
4049 result = (INT64)CONCAT_64(GET_G_REG(14), GET_G_REG(15)) - (INT64)((INT64)(INT32)(vals) * (INT64)(INT32)(vald));
4050
4051 vals = result >> 32;
4052 vald = result & 0xffffffff;
4053 SET_G_REG(14, vals);
4054 SET_G_REG(15, vald);
4055
4056 break;
4057 }
4058 // signed half-word multiply/add, single word product sum
4059 case EHMAC:
4060 {
4061 INT32 result;
4062
4063 result = (INT32)GET_G_REG(15) + ((INT32)((vald & 0xffff0000) >> 16) * (INT32)((vals & 0xffff0000) >> 16)) + ((INT32)(vald & 0xffff) * (INT32)(vals & 0xffff));
4064 SET_G_REG(15, result);
4065
4066 break;
4067 }
4068 // signed half-word multiply/add, double word product sum
4069 case EHMACD:
4070 {
4071 INT64 result;
4072
4073 result = (INT64)CONCAT_64(GET_G_REG(14), GET_G_REG(15)) + (INT64)((INT64)(INT32)((vald & 0xffff0000) >> 16) * (INT64)(INT32)((vals & 0xffff0000) >> 16)) + ((INT64)(INT32)(vald & 0xffff) * (INT64)(INT32)(vals & 0xffff));
4074
4075 vals = result >> 32;
4076 vald = result & 0xffffffff;
4077 SET_G_REG(14, vals);
4078 SET_G_REG(15, vald);
4079
4080 break;
4081 }
4082 // half-word complex multiply
4083 case EHCMULD:
4084 {
4085 UINT32 result;
4086
4087 result = (((vald & 0xffff0000) >> 16) * ((vals & 0xffff0000) >> 16)) - ((vald & 0xffff) * (vals & 0xffff));
4088 SET_G_REG(14, result);
4089
4090 result = (((vald & 0xffff0000) >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * ((vals & 0xffff0000) >> 16));
4091 SET_G_REG(15, result);
4092
4093 break;
4094 }
4095 // half-word complex multiply/add
4096 case EHCMACD:
4097 {
4098 UINT32 result;
4099
4100 result = GET_G_REG(14) + (((vald & 0xffff0000) >> 16) * ((vals & 0xffff0000) >> 16)) - ((vald & 0xffff) * (vals & 0xffff));
4101 SET_G_REG(14, result);
4102
4103 result = GET_G_REG(15) + (((vald & 0xffff0000) >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * ((vals & 0xffff0000) >> 16));
4104 SET_G_REG(15, result);
4105
4106 break;
4107 }
4108 // half-word (complex) add/substract
4109 // Ls is not used and should denote the same register as Ld
4110 case EHCSUMD:
4111 {
4112 UINT32 result;
4113
4114 result = ((((vals & 0xffff0000) >> 16) + GET_G_REG(14)) << 16) & 0xffff0000;
4115 result |= ((vals & 0xffff) + GET_G_REG(15)) & 0xffff;
4116 SET_G_REG(14, result);
4117
4118 result = ((((vals & 0xffff0000) >> 16) - GET_G_REG(14)) << 16) & 0xffff0000;
4119 result |= ((vals & 0xffff) - GET_G_REG(15)) & 0xffff;
4120 SET_G_REG(15, result);
4121
4122 break;
4123 }
4124 // half-word (complex) add/substract with fixed point adjustment
4125 // Ls is not used and should denote the same register as Ld
4126 case EHCFFTD:
4127 {
4128 UINT32 result;
4129
4130 result = ((((vals & 0xffff0000) >> 16) + (GET_G_REG(14) >> 15)) << 16) & 0xffff0000;
4131 result |= ((vals & 0xffff) + (GET_G_REG(15) >> 15)) & 0xffff;
4132 SET_G_REG(14, result);
4133
4134 result = ((((vals & 0xffff0000) >> 16) - (GET_G_REG(14) >> 15)) << 16) & 0xffff0000;
4135 result |= ((vals & 0xffff) - (GET_G_REG(15) >> 15)) & 0xffff;
4136 SET_G_REG(15, result);
4137
4138 break;
4139 }
4140 // half-word (complex) add/substract with fixed point adjustment and shift
4141 // Ls is not used and should denote the same register as Ld
4142 case EHCFFTSD:
4143 {
4144 UINT32 result;
4145
4146 result = (((((vals & 0xffff0000) >> 16) + (GET_G_REG(14) >> 15)) >> 1) << 16) & 0xffff0000;
4147 result |= ((((vals & 0xffff) + (GET_G_REG(15) >> 15)) >> 1) & 0xffff);
4148 SET_G_REG(14, result);
4149
4150 result = (((((vals & 0xffff0000) >> 16) - (GET_G_REG(14) >> 15)) >> 1) << 16) & 0xffff0000;
4151 result |= ((((vals & 0xffff) - (GET_G_REG(15) >> 15)) >> 1) & 0xffff);
4152 SET_G_REG(15, result);
4153
4154 break;
4155 }
4156 default:
4157 DEBUG_PRINTF(("Executed Illegal extended opcode (%X). PC = %08X\n", EXTRA_U, PC));
4158 break;
4159 }
4160
4161 m_icount -= m_clock_cycles_1; //TODO: with the latency it can change
4162 }
4163
hyperstone_do(struct regs_decode *)4164 static void hyperstone_do(struct regs_decode *)
4165 {
4166 // fatalerror("Executed hyperstone_do instruction. PC = %08X\n", PPC);
4167 }
4168
hyperstone_ldwr(struct regs_decode * decode)4169 static void hyperstone_ldwr(struct regs_decode *decode)
4170 {
4171 SET_SREG(READ_W(DREG));
4172
4173 m_icount -= m_clock_cycles_1;
4174 }
4175
hyperstone_lddr(struct regs_decode * decode)4176 static void hyperstone_lddr(struct regs_decode *decode)
4177 {
4178 SET_SREG(READ_W(DREG));
4179 SET_SREGF(READ_W(DREG + 4));
4180
4181 m_icount -= m_clock_cycles_2;
4182 }
4183
hyperstone_ldwp(struct regs_decode * decode)4184 static void hyperstone_ldwp(struct regs_decode *decode)
4185 {
4186 SET_SREG(READ_W(DREG));
4187
4188 // post increment the destination register if it's different from the source one
4189 // (needed by Hidden Catch)
4190 if(!(decode->src == decode->dst && S_BIT == LOCAL))
4191 SET_DREG(DREG + 4);
4192
4193 m_icount -= m_clock_cycles_1;
4194 }
4195
hyperstone_lddp(struct regs_decode * decode)4196 static void hyperstone_lddp(struct regs_decode *decode)
4197 {
4198 SET_SREG(READ_W(DREG));
4199 SET_SREGF(READ_W(DREG + 4));
4200
4201 // post increment the destination register if it's different from the source one
4202 // and from the "next source" one
4203 if(!(decode->src == decode->dst && S_BIT == LOCAL) && !SAME_SRCF_DST )
4204 {
4205 SET_DREG(DREG + 8);
4206 }
4207 else
4208 {
4209 DEBUG_PRINTF(("LDD.P denoted same regs @ %08X",PPC));
4210 }
4211
4212 m_icount -= m_clock_cycles_2;
4213 }
4214
hyperstone_stwr(struct regs_decode * decode)4215 static void hyperstone_stwr(struct regs_decode *decode)
4216 {
4217 if( SRC_IS_SR )
4218 SREG = 0;
4219
4220 WRITE_W(DREG, SREG);
4221
4222 m_icount -= m_clock_cycles_1;
4223 }
4224
hyperstone_stdr(struct regs_decode * decode)4225 static void hyperstone_stdr(struct regs_decode *decode)
4226 {
4227 if( SRC_IS_SR )
4228 SREG = SREGF = 0;
4229
4230 WRITE_W(DREG, SREG);
4231 WRITE_W(DREG + 4, SREGF);
4232
4233 m_icount -= m_clock_cycles_2;
4234 }
4235
hyperstone_stwp(struct regs_decode * decode)4236 static void hyperstone_stwp(struct regs_decode *decode)
4237 {
4238 if( SRC_IS_SR )
4239 SREG = 0;
4240
4241 WRITE_W(DREG, SREG);
4242 SET_DREG(DREG + 4);
4243
4244 m_icount -= m_clock_cycles_1;
4245 }
4246
hyperstone_stdp(struct regs_decode * decode)4247 static void hyperstone_stdp(struct regs_decode *decode)
4248 {
4249 if( SRC_IS_SR )
4250 SREG = SREGF = 0;
4251
4252 WRITE_W(DREG, SREG);
4253 SET_DREG(DREG + 8);
4254
4255 if( SAME_SRCF_DST )
4256 WRITE_W(DREG + 4, SREGF + 8); // because DREG == SREGF and DREG has been incremented
4257 else
4258 WRITE_W(DREG + 4, SREGF);
4259
4260 m_icount -= m_clock_cycles_2;
4261 }
4262
hyperstone_dbv(struct regs_decode * decode)4263 static void hyperstone_dbv(struct regs_decode *decode)
4264 {
4265 if( GET_V )
4266 execute_dbr(decode);
4267
4268 m_icount -= m_clock_cycles_1;
4269 }
4270
hyperstone_dbnv(struct regs_decode * decode)4271 static void hyperstone_dbnv(struct regs_decode *decode)
4272 {
4273 if( !GET_V )
4274 execute_dbr(decode);
4275
4276 m_icount -= m_clock_cycles_1;
4277 }
4278
hyperstone_dbe(struct regs_decode * decode)4279 static void hyperstone_dbe(struct regs_decode *decode) //or DBZ
4280 {
4281 if( GET_Z )
4282 execute_dbr(decode);
4283
4284 m_icount -= m_clock_cycles_1;
4285 }
4286
hyperstone_dbne(struct regs_decode * decode)4287 static void hyperstone_dbne(struct regs_decode *decode) //or DBNZ
4288 {
4289 if( !GET_Z )
4290 execute_dbr(decode);
4291
4292 m_icount -= m_clock_cycles_1;
4293 }
4294
hyperstone_dbc(struct regs_decode * decode)4295 static void hyperstone_dbc(struct regs_decode *decode) //or DBST
4296 {
4297 if( GET_C )
4298 execute_dbr(decode);
4299
4300 m_icount -= m_clock_cycles_1;
4301 }
4302
hyperstone_dbnc(struct regs_decode * decode)4303 static void hyperstone_dbnc(struct regs_decode *decode) //or DBHE
4304 {
4305 if( !GET_C )
4306 execute_dbr(decode);
4307
4308 m_icount -= m_clock_cycles_1;
4309 }
4310
hyperstone_dbse(struct regs_decode * decode)4311 static void hyperstone_dbse(struct regs_decode *decode)
4312 {
4313 if( GET_C || GET_Z )
4314 execute_dbr(decode);
4315
4316 m_icount -= m_clock_cycles_1;
4317 }
4318
hyperstone_dbht(struct regs_decode * decode)4319 static void hyperstone_dbht(struct regs_decode *decode)
4320 {
4321 if( !GET_C && !GET_Z )
4322 execute_dbr(decode);
4323
4324 m_icount -= m_clock_cycles_1;
4325 }
4326
hyperstone_dbn(struct regs_decode * decode)4327 static void hyperstone_dbn(struct regs_decode *decode) //or DBLT
4328 {
4329 if( GET_N )
4330 execute_dbr(decode);
4331
4332 m_icount -= m_clock_cycles_1;
4333 }
4334
hyperstone_dbnn(struct regs_decode * decode)4335 static void hyperstone_dbnn(struct regs_decode *decode) //or DBGE
4336 {
4337 if( !GET_N )
4338 execute_dbr(decode);
4339
4340 m_icount -= m_clock_cycles_1;
4341 }
4342
hyperstone_dble(struct regs_decode * decode)4343 static void hyperstone_dble(struct regs_decode *decode)
4344 {
4345 if( GET_N || GET_Z )
4346 execute_dbr(decode);
4347
4348 m_icount -= m_clock_cycles_1;
4349 }
4350
hyperstone_dbgt(struct regs_decode * decode)4351 static void hyperstone_dbgt(struct regs_decode *decode)
4352 {
4353 if( !GET_N && !GET_Z )
4354 execute_dbr(decode);
4355
4356 m_icount -= m_clock_cycles_1;
4357 }
4358
hyperstone_dbr(struct regs_decode * decode)4359 static void hyperstone_dbr(struct regs_decode *decode)
4360 {
4361 execute_dbr(decode);
4362 }
4363
hyperstone_frame(struct regs_decode *)4364 static void hyperstone_frame(struct regs_decode *)
4365 {
4366 INT8 difference; // really it's 7 bits
4367 UINT8 realfp = GET_FP - SRC_CODE;
4368
4369 SET_FP(realfp);
4370 SET_FL(DST_CODE);
4371 SET_M(0);
4372
4373 difference = ((SP & 0x1fc) >> 2) + (64 - 10) - (realfp + GET_FL);
4374
4375 /* convert to 8 bits */
4376 if(difference > 63)
4377 difference = (INT8)(difference|0x80);
4378 else if( difference < -64 )
4379 difference = difference & 0x7f;
4380
4381 if( difference < 0 ) // else it's finished
4382 {
4383 UINT8 tmp_flag;
4384
4385 tmp_flag = ( SP >= UB ? 1 : 0 );
4386
4387 do
4388 {
4389 WRITE_W(SP, GET_ABS_L_REG((SP & 0xfc) >> 2));
4390 SP += 4;
4391 difference++;
4392
4393 } while(difference != 0);
4394
4395 if( tmp_flag )
4396 {
4397 UINT32 addr = get_trap_addr(TRAPNO_FRAME_ERROR);
4398 execute_exception(addr);
4399 }
4400 }
4401
4402 //TODO: no 1!
4403 m_icount -= m_clock_cycles_1;
4404 }
4405
hyperstone_call(struct regs_decode * decode)4406 static void hyperstone_call(struct regs_decode *decode)
4407 {
4408 if( SRC_IS_SR )
4409 SREG = 0;
4410
4411 if( !DST_CODE )
4412 decode->dst = 16;
4413
4414 EXTRA_S = (EXTRA_S & ~1) + SREG;
4415
4416 SET_ILC(m_instruction_length & 3);
4417
4418 SET_DREG((PC & 0xfffffffe) | GET_S);
4419 SET_DREGF(SR);
4420
4421 SET_FP(GET_FP + decode->dst);
4422
4423 SET_FL(6); //default value for call
4424 SET_M(0);
4425
4426 PPC = PC;
4427 PC = EXTRA_S; // const value
4428
4429 m_intblock = 2;
4430
4431 //TODO: add interrupt locks, errors, ....
4432
4433 //TODO: no 1!
4434 m_icount -= m_clock_cycles_1;
4435 }
4436
hyperstone_bv(struct regs_decode * decode)4437 static void hyperstone_bv(struct regs_decode *decode)
4438 {
4439 if( GET_V )
4440 execute_br(decode);
4441 else
4442 m_icount -= m_clock_cycles_1;
4443 }
4444
hyperstone_bnv(struct regs_decode * decode)4445 static void hyperstone_bnv(struct regs_decode *decode)
4446 {
4447 if( !GET_V )
4448 execute_br(decode);
4449 else
4450 m_icount -= m_clock_cycles_1;
4451 }
4452
hyperstone_be(struct regs_decode * decode)4453 static void hyperstone_be(struct regs_decode *decode) //or BZ
4454 {
4455 if( GET_Z )
4456 execute_br(decode);
4457 else
4458 m_icount -= m_clock_cycles_1;
4459 }
4460
hyperstone_bne(struct regs_decode * decode)4461 static void hyperstone_bne(struct regs_decode *decode) //or BNZ
4462 {
4463 if( !GET_Z )
4464 execute_br(decode);
4465 else
4466 m_icount -= m_clock_cycles_1;
4467 }
4468
hyperstone_bc(struct regs_decode * decode)4469 static void hyperstone_bc(struct regs_decode *decode) //or BST
4470 {
4471 if( GET_C )
4472 execute_br(decode);
4473 else
4474 m_icount -= m_clock_cycles_1;
4475 }
4476
hyperstone_bnc(struct regs_decode * decode)4477 static void hyperstone_bnc(struct regs_decode *decode) //or BHE
4478 {
4479 if( !GET_C )
4480 execute_br(decode);
4481 else
4482 m_icount -= m_clock_cycles_1;
4483 }
4484
hyperstone_bse(struct regs_decode * decode)4485 static void hyperstone_bse(struct regs_decode *decode)
4486 {
4487 if( GET_C || GET_Z )
4488 execute_br(decode);
4489 else
4490 m_icount -= m_clock_cycles_1;
4491 }
4492
hyperstone_bht(struct regs_decode * decode)4493 static void hyperstone_bht(struct regs_decode *decode)
4494 {
4495 if( !GET_C && !GET_Z )
4496 execute_br(decode);
4497 else
4498 m_icount -= m_clock_cycles_1;
4499 }
4500
hyperstone_bn(struct regs_decode * decode)4501 static void hyperstone_bn(struct regs_decode *decode) //or BLT
4502 {
4503 if( GET_N )
4504 execute_br(decode);
4505 else
4506 m_icount -= m_clock_cycles_1;
4507 }
4508
hyperstone_bnn(struct regs_decode * decode)4509 static void hyperstone_bnn(struct regs_decode *decode) //or BGE
4510 {
4511 if( !GET_N )
4512 execute_br(decode);
4513 else
4514 m_icount -= m_clock_cycles_1;
4515 }
4516
hyperstone_ble(struct regs_decode * decode)4517 static void hyperstone_ble(struct regs_decode *decode)
4518 {
4519 if( GET_N || GET_Z )
4520 execute_br(decode);
4521 else
4522 m_icount -= m_clock_cycles_1;
4523 }
4524
hyperstone_bgt(struct regs_decode * decode)4525 static void hyperstone_bgt(struct regs_decode *decode)
4526 {
4527 if( !GET_N && !GET_Z )
4528 execute_br(decode);
4529 else
4530 m_icount -= m_clock_cycles_1;
4531 }
4532
hyperstone_br(struct regs_decode * decode)4533 static void hyperstone_br(struct regs_decode *decode)
4534 {
4535 execute_br(decode);
4536 }
4537
hyperstone_trap(struct regs_decode *)4538 static void hyperstone_trap(struct regs_decode *)
4539 {
4540 UINT8 code, trapno;
4541 UINT32 addr;
4542
4543 trapno = (OP & 0xfc) >> 2;
4544
4545 addr = get_trap_addr(trapno);
4546 code = ((OP & 0x300) >> 6) | (OP & 0x03);
4547
4548 switch( code )
4549 {
4550 case TRAPLE:
4551 if( GET_N || GET_Z )
4552 execute_trap(addr);
4553
4554 break;
4555
4556 case TRAPGT:
4557 if( !GET_N && !GET_Z )
4558 execute_trap(addr);
4559
4560 break;
4561
4562 case TRAPLT:
4563 if( GET_N )
4564 execute_trap(addr);
4565
4566 break;
4567
4568 case TRAPGE:
4569 if( !GET_N )
4570 execute_trap(addr);
4571
4572 break;
4573
4574 case TRAPSE:
4575 if( GET_C || GET_Z )
4576 execute_trap(addr);
4577
4578 break;
4579
4580 case TRAPHT:
4581 if( !GET_C && !GET_Z )
4582 execute_trap(addr);
4583
4584 break;
4585
4586 case TRAPST:
4587 if( GET_C )
4588 execute_trap(addr);
4589
4590 break;
4591
4592 case TRAPHE:
4593 if( !GET_C )
4594 execute_trap(addr);
4595
4596 break;
4597
4598 case TRAPE:
4599 if( GET_Z )
4600 execute_trap(addr);
4601
4602 break;
4603
4604 case TRAPNE:
4605 if( !GET_Z )
4606 execute_trap(addr);
4607
4608 break;
4609
4610 case TRAPV:
4611 if( GET_V )
4612 execute_trap(addr);
4613
4614 break;
4615
4616 case TRAP:
4617 execute_trap(addr);
4618
4619 break;
4620 }
4621
4622 m_icount -= m_clock_cycles_1;
4623 }
4624
4625
4626 #include "e132xsop.inc"
4627
core_set_irq_line(INT32,INT32 line,INT32 state)4628 static void core_set_irq_line(INT32, INT32 line, INT32 state)
4629 {
4630 E132XSSetIRQLine(line, state);
4631 }
4632
4633 cpu_core_config E132XSConfig =
4634 {
4635 "e132xs",
4636 E132XSOpen,
4637 E132XSClose,
4638 program_read_byte_16be,
4639 program_write_byte_16be,
4640 E132XSGetActive,
4641 E132XSTotalCycles32,
4642 E132XSNewFrame,
4643 E132XSIdle,
4644 core_set_irq_line,
4645 E132XSRun,
4646 E132XSRunEnd,
4647 E132XSReset,
4648 0xffffffff,
4649 1
4650 };
4651
map_internal_ram(UINT32 size)4652 static void map_internal_ram(UINT32 size)
4653 {
4654 for (INT32 i = 0; i < 0x20000000; i += size)
4655 {
4656 E132XSMapMemory(internal_ram, 0xc0000000 + i, 0xc0000000 + i + (size - 1), MAP_RAM);
4657 }
4658 }
4659
core_init(int scale_mask)4660 static void core_init(int scale_mask)
4661 {
4662 memset(m_global_regs, 0, sizeof(UINT32) * 32);
4663 memset(m_local_regs, 0, sizeof(UINT32) * 64);
4664 m_ppc = 0;
4665 m_op = 0;
4666 m_trap_entry = 0;
4667 m_clock_scale_mask = 0;
4668 m_clock_scale = 0;
4669 m_clock_cycles_1 = 0;
4670 m_clock_cycles_2 = 0;
4671 m_clock_cycles_4 = 0;
4672 m_clock_cycles_6 = 0;
4673
4674 m_tr_base_cycles = 0;
4675 m_tr_base_value = 0;
4676 m_tr_clocks_per_tick = 0;
4677 m_timer_int_pending = 0;
4678
4679 m_instruction_length = 0;
4680 m_intblock = 0;
4681
4682 m_icount = 0;
4683
4684 timer_time = -1;
4685 timer_param = 0;
4686 m_clock_scale_mask = scale_mask;
4687 }
4688
E132XSInit(INT32,INT32 type,INT32)4689 void E132XSInit(INT32 , INT32 type, INT32 )
4690 {
4691 memset (mem, 0, sizeof(mem));
4692
4693 write_byte_handler = NULL;
4694 write_word_handler = NULL;
4695 write_dword_handler = NULL;
4696 read_byte_handler = NULL;
4697 read_word_handler = NULL;
4698 read_dword_handler = NULL;
4699 io_write_dword_handler = NULL;
4700 io_read_dword_handler = NULL;
4701
4702 CpuCheatRegister(0, &E132XSConfig);
4703
4704 switch (type)
4705 {
4706 case TYPE_E116T:
4707 core_init(0);
4708 map_internal_ram(0x1000);
4709 break;
4710
4711 case TYPE_E116XT:
4712 core_init(3);
4713 map_internal_ram(0x2000);
4714 break;
4715
4716 case TYPE_E116XS:
4717 core_init(7);
4718 map_internal_ram(0x4000);
4719 break;
4720
4721 case TYPE_E116XSR:
4722 core_init(7);
4723 map_internal_ram(0x4000);
4724 break;
4725
4726 case TYPE_E132N:
4727 core_init(0);
4728 map_internal_ram(0x1000);
4729 break;
4730
4731 case TYPE_E132T:
4732 core_init(0);
4733 map_internal_ram(0x1000);
4734 break;
4735
4736 case TYPE_E132XN:
4737 core_init(3);
4738 map_internal_ram(0x2000);
4739 break;
4740
4741 case TYPE_E132XT:
4742 core_init(3);
4743 map_internal_ram(0x2000);
4744 break;
4745
4746 case TYPE_E132XS:
4747 core_init(7);
4748 map_internal_ram(0x4000);
4749 break;
4750
4751 case TYPE_E132XSR:
4752 core_init(7);
4753 map_internal_ram(0x4000);
4754 break;
4755
4756 case TYPE_GMS30C2116:
4757 core_init(0);
4758 map_internal_ram(0x1000);
4759 break;
4760
4761 case TYPE_GMS30C2132:
4762 core_init(0);
4763 map_internal_ram(0x1000);
4764 break;
4765
4766 case TYPE_GMS30C2216:
4767 core_init(0);
4768 map_internal_ram(0x2000);
4769 break;
4770
4771 case TYPE_GMS30C2232:
4772 core_init(0);
4773 map_internal_ram(0x2000);
4774 break;
4775 }
4776 }
4777
E132XSReset()4778 void E132XSReset()
4779 {
4780 //TODO: Add different reset initializations for BCR, MCR, FCR, TPR
4781
4782 m_tr_clocks_per_tick = 2;
4783
4784 hyperstone_set_trap_entry(E132XS_ENTRY_MEM3); /* default entry point @ MEM3 */
4785
4786 set_global_register(BCR_REGISTER, ~0);
4787 set_global_register(MCR_REGISTER, ~0);
4788 set_global_register(FCR_REGISTER, ~0);
4789 set_global_register(TPR_REGISTER, 0xc000000);
4790
4791 PC = get_trap_addr(TRAPNO_RESET);
4792
4793 SET_FP(0);
4794 SET_FL(2);
4795
4796 SET_M(0);
4797 SET_T(0);
4798 SET_L(1);
4799 SET_S(1);
4800
4801 SET_L_REG(0, (PC & 0xfffffffe) | GET_S);
4802 SET_L_REG(1, SR);
4803
4804 m_icount = 0;
4805 m_icount -= m_clock_cycles_2;
4806 itotal_cycles = 0;
4807 utotal_cycles = 0;
4808 n_cycles = 0;
4809
4810 m_hold_irq = 0;
4811 sleep_until_int = 0;
4812 }
4813
E132XSGetActive()4814 INT32 E132XSGetActive()
4815 {
4816 return 0;
4817 }
4818
E132XSOpen(INT32 nCpu)4819 void E132XSOpen(INT32 nCpu)
4820 {
4821 if (nCpu){}
4822 }
4823
E132XSClose()4824 void E132XSClose()
4825 {
4826 }
4827
E132XSExit()4828 void E132XSExit()
4829 {
4830
4831 }
4832
E132XSTotalCycles()4833 INT64 E132XSTotalCycles()
4834 {
4835 return utotal_cycles + (n_cycles - m_icount);
4836 }
4837
E132XSTotalCycles32()4838 INT32 E132XSTotalCycles32()
4839 {
4840 return E132XSTotalCycles();
4841 }
4842
E132XSNewFrame()4843 void E132XSNewFrame()
4844 {
4845 utotal_cycles = 0;
4846 }
4847
E132XSScan(INT32 nAction)4848 void E132XSScan(INT32 nAction)
4849 {
4850 SCAN_VAR(m_global_regs);
4851 SCAN_VAR(m_local_regs);
4852
4853 SCAN_VAR(internal_ram);
4854
4855 SCAN_VAR(m_ppc); // previous pc
4856 SCAN_VAR(m_op); // opcode
4857 SCAN_VAR(m_trap_entry); // entry point to get trap address
4858
4859 SCAN_VAR(m_clock_scale_mask);
4860 SCAN_VAR(m_clock_scale);
4861 SCAN_VAR(m_clock_cycles_1);
4862 SCAN_VAR(m_clock_cycles_2);
4863 SCAN_VAR(m_clock_cycles_4);
4864 SCAN_VAR(m_clock_cycles_6);
4865
4866 SCAN_VAR(m_tr_base_cycles);
4867 SCAN_VAR(m_tr_base_value);
4868 SCAN_VAR(m_tr_clocks_per_tick);
4869 SCAN_VAR(m_timer_int_pending);
4870
4871 SCAN_VAR(timer_time);
4872 SCAN_VAR(timer_param);
4873 SCAN_VAR(m_hold_irq);
4874
4875 SCAN_VAR(m_delay);
4876
4877 SCAN_VAR(m_instruction_length);
4878 SCAN_VAR(m_intblock);
4879
4880 SCAN_VAR(m_icount);
4881 SCAN_VAR(itotal_cycles); // internal total cycles (timers etc)
4882 SCAN_VAR(utotal_cycles); // user-total cycles (E132XSTotalCycles() / E132XSNewFrame() etc..)
4883 SCAN_VAR(n_cycles);
4884 }
4885
E132XSSetIRQLine(INT32 line,INT32 state)4886 void E132XSSetIRQLine(INT32 line, INT32 state)
4887 {
4888 if (state) sleep_until_int = 0;
4889
4890 switch (state) {
4891 case CPU_IRQSTATUS_HOLD:
4892 execute_set_input(line, 2);
4893 break;
4894 case CPU_IRQSTATUS_AUTO:
4895 execute_set_input(line, 1);
4896 E132XSRun(10);
4897 execute_set_input(line, 0);
4898 break;
4899 default:
4900 execute_set_input(line, state ? 1 : 0);
4901 E132XSRun(10);
4902 break;
4903 }
4904 }
4905
E132XSBurnUntilInt()4906 void E132XSBurnUntilInt()
4907 {
4908 sleep_until_int = 1;
4909 }
4910
E132XSIdle(INT32 cycles)4911 INT32 E132XSIdle(INT32 cycles)
4912 {
4913 utotal_cycles += cycles;
4914
4915 return cycles;
4916 }
4917
4918 static INT32 end_run = 0;
4919
E132XSRun(INT32 cycles)4920 INT32 E132XSRun(INT32 cycles)
4921 {
4922 if (sleep_until_int) {
4923 return E132XSIdle(cycles);
4924 }
4925
4926 m_icount = cycles;
4927 n_cycles = m_icount;
4928
4929 if (m_intblock < 0)
4930 m_intblock = 0;
4931
4932 check_interrupts();
4933
4934 INT32 t_icount;
4935
4936 end_run = 0;
4937
4938 do
4939 {
4940 t_icount = m_icount;
4941
4942 UINT32 oldh = SR & 0x00000020;
4943
4944 PPC = PC; /* copy PC to previous PC */
4945
4946 OP = READ_OP(PC);
4947 PC += 2;
4948
4949 m_instruction_length = 1;
4950
4951 switch (OP >> 8)
4952 {
4953 case 0x00: op00(); break;
4954 case 0x01: op01(); break;
4955 case 0x02: op02(); break;
4956 case 0x03: op03(); break;
4957 case 0x04: op04(); break;
4958 case 0x05: op05(); break;
4959 case 0x06: op06(); break;
4960 case 0x07: op07(); break;
4961 case 0x08: op08(); break;
4962 case 0x09: op09(); break;
4963 case 0x0a: op0a(); break;
4964 case 0x0b: op0b(); break;
4965 case 0x0c: op0c(); break;
4966 case 0x0d: op0d(); break;
4967 case 0x0e: op0e(); break;
4968 case 0x0f: op0f(); break;
4969 case 0x10: op10(); break;
4970 case 0x11: op11(); break;
4971 case 0x12: op12(); break;
4972 case 0x13: op13(); break;
4973 case 0x14: op14(); break;
4974 case 0x15: op15(); break;
4975 case 0x16: op16(); break;
4976 case 0x17: op17(); break;
4977 case 0x18: op18(); break;
4978 case 0x19: op19(); break;
4979 case 0x1a: op1a(); break;
4980 case 0x1b: op1b(); break;
4981 case 0x1c: op1c(); break;
4982 case 0x1d: op1d(); break;
4983 case 0x1e: op1e(); break;
4984 case 0x1f: op1f(); break;
4985 case 0x20: op20(); break;
4986 case 0x21: op21(); break;
4987 case 0x22: op22(); break;
4988 case 0x23: op23(); break;
4989 case 0x24: op24(); break;
4990 case 0x25: op25(); break;
4991 case 0x26: op26(); break;
4992 case 0x27: op27(); break;
4993 case 0x28: op28(); break;
4994 case 0x29: op29(); break;
4995 case 0x2a: op2a(); break;
4996 case 0x2b: op2b(); break;
4997 case 0x2c: op2c(); break;
4998 case 0x2d: op2d(); break;
4999 case 0x2e: op2e(); break;
5000 case 0x2f: op2f(); break;
5001 case 0x30: op30(); break;
5002 case 0x31: op31(); break;
5003 case 0x32: op32(); break;
5004 case 0x33: op33(); break;
5005 case 0x34: op34(); break;
5006 case 0x35: op35(); break;
5007 case 0x36: op36(); break;
5008 case 0x37: op37(); break;
5009 case 0x38: op38(); break;
5010 case 0x39: op39(); break;
5011 case 0x3a: op3a(); break;
5012 case 0x3b: op3b(); break;
5013 case 0x3c: op3c(); break;
5014 case 0x3d: op3d(); break;
5015 case 0x3e: op3e(); break;
5016 case 0x3f: op3f(); break;
5017 case 0x40: op40(); break;
5018 case 0x41: op41(); break;
5019 case 0x42: op42(); break;
5020 case 0x43: op43(); break;
5021 case 0x44: op44(); break;
5022 case 0x45: op45(); break;
5023 case 0x46: op46(); break;
5024 case 0x47: op47(); break;
5025 case 0x48: op48(); break;
5026 case 0x49: op49(); break;
5027 case 0x4a: op4a(); break;
5028 case 0x4b: op4b(); break;
5029 case 0x4c: op4c(); break;
5030 case 0x4d: op4d(); break;
5031 case 0x4e: op4e(); break;
5032 case 0x4f: op4f(); break;
5033 case 0x50: op50(); break;
5034 case 0x51: op51(); break;
5035 case 0x52: op52(); break;
5036 case 0x53: op53(); break;
5037 case 0x54: op54(); break;
5038 case 0x55: op55(); break;
5039 case 0x56: op56(); break;
5040 case 0x57: op57(); break;
5041 case 0x58: op58(); break;
5042 case 0x59: op59(); break;
5043 case 0x5a: op5a(); break;
5044 case 0x5b: op5b(); break;
5045 case 0x5c: op5c(); break;
5046 case 0x5d: op5d(); break;
5047 case 0x5e: op5e(); break;
5048 case 0x5f: op5f(); break;
5049 case 0x60: op60(); break;
5050 case 0x61: op61(); break;
5051 case 0x62: op62(); break;
5052 case 0x63: op63(); break;
5053 case 0x64: op64(); break;
5054 case 0x65: op65(); break;
5055 case 0x66: op66(); break;
5056 case 0x67: op67(); break;
5057 case 0x68: op68(); break;
5058 case 0x69: op69(); break;
5059 case 0x6a: op6a(); break;
5060 case 0x6b: op6b(); break;
5061 case 0x6c: op6c(); break;
5062 case 0x6d: op6d(); break;
5063 case 0x6e: op6e(); break;
5064 case 0x6f: op6f(); break;
5065 case 0x70: op70(); break;
5066 case 0x71: op71(); break;
5067 case 0x72: op72(); break;
5068 case 0x73: op73(); break;
5069 case 0x74: op74(); break;
5070 case 0x75: op75(); break;
5071 case 0x76: op76(); break;
5072 case 0x77: op77(); break;
5073 case 0x78: op78(); break;
5074 case 0x79: op79(); break;
5075 case 0x7a: op7a(); break;
5076 case 0x7b: op7b(); break;
5077 case 0x7c: op7c(); break;
5078 case 0x7d: op7d(); break;
5079 case 0x7e: op7e(); break;
5080 case 0x7f: op7f(); break;
5081 case 0x80: op80(); break;
5082 case 0x81: op81(); break;
5083 case 0x82: op82(); break;
5084 case 0x83: op83(); break;
5085 case 0x84: op84(); break;
5086 case 0x85: op85(); break;
5087 case 0x86: op86(); break;
5088 case 0x87: op87(); break;
5089 case 0x88: op88(); break;
5090 case 0x89: op89(); break;
5091 case 0x8a: op8a(); break;
5092 case 0x8b: op8b(); break;
5093 case 0x8c: op8c(); break;
5094 case 0x8d: op8d(); break;
5095 case 0x8e: op8e(); break;
5096 case 0x8f: op8f(); break;
5097 case 0x90: op90(); break;
5098 case 0x91: op91(); break;
5099 case 0x92: op92(); break;
5100 case 0x93: op93(); break;
5101 case 0x94: op94(); break;
5102 case 0x95: op95(); break;
5103 case 0x96: op96(); break;
5104 case 0x97: op97(); break;
5105 case 0x98: op98(); break;
5106 case 0x99: op99(); break;
5107 case 0x9a: op9a(); break;
5108 case 0x9b: op9b(); break;
5109 case 0x9c: op9c(); break;
5110 case 0x9d: op9d(); break;
5111 case 0x9e: op9e(); break;
5112 case 0x9f: op9f(); break;
5113 case 0xa0: opa0(); break;
5114 case 0xa1: opa1(); break;
5115 case 0xa2: opa2(); break;
5116 case 0xa3: opa3(); break;
5117 case 0xa4: opa4(); break;
5118 case 0xa5: opa5(); break;
5119 case 0xa6: opa6(); break;
5120 case 0xa7: opa7(); break;
5121 case 0xa8: opa8(); break;
5122 case 0xa9: opa9(); break;
5123 case 0xaa: opaa(); break;
5124 case 0xab: opab(); break;
5125 case 0xac: opac(); break;
5126 case 0xad: opad(); break;
5127 case 0xae: opae(); break;
5128 case 0xaf: opaf(); break;
5129 case 0xb0: opb0(); break;
5130 case 0xb1: opb1(); break;
5131 case 0xb2: opb2(); break;
5132 case 0xb3: opb3(); break;
5133 case 0xb4: opb4(); break;
5134 case 0xb5: opb5(); break;
5135 case 0xb6: opb6(); break;
5136 case 0xb7: opb7(); break;
5137 case 0xb8: opb8(); break;
5138 case 0xb9: opb9(); break;
5139 case 0xba: opba(); break;
5140 case 0xbb: opbb(); break;
5141 case 0xbc: opbc(); break;
5142 case 0xbd: opbd(); break;
5143 case 0xbe: opbe(); break;
5144 case 0xbf: opbf(); break;
5145 case 0xc0: opc0(); break;
5146 case 0xc1: opc1(); break;
5147 case 0xc2: opc2(); break;
5148 case 0xc3: opc3(); break;
5149 case 0xc4: opc4(); break;
5150 case 0xc5: opc5(); break;
5151 case 0xc6: opc6(); break;
5152 case 0xc7: opc7(); break;
5153 case 0xc8: opc8(); break;
5154 case 0xc9: opc9(); break;
5155 case 0xca: opca(); break;
5156 case 0xcb: opcb(); break;
5157 case 0xcc: opcc(); break;
5158 case 0xcd: opcd(); break;
5159 case 0xce: opce(); break;
5160 case 0xcf: opcf(); break;
5161 case 0xd0: opd0(); break;
5162 case 0xd1: opd1(); break;
5163 case 0xd2: opd2(); break;
5164 case 0xd3: opd3(); break;
5165 case 0xd4: opd4(); break;
5166 case 0xd5: opd5(); break;
5167 case 0xd6: opd6(); break;
5168 case 0xd7: opd7(); break;
5169 case 0xd8: opd8(); break;
5170 case 0xd9: opd9(); break;
5171 case 0xda: opda(); break;
5172 case 0xdb: opdb(); break;
5173 case 0xdc: opdc(); break;
5174 case 0xdd: opdd(); break;
5175 case 0xde: opde(); break;
5176 case 0xdf: opdf(); break;
5177 case 0xe0: ope0(); break;
5178 case 0xe1: ope1(); break;
5179 case 0xe2: ope2(); break;
5180 case 0xe3: ope3(); break;
5181 case 0xe4: ope4(); break;
5182 case 0xe5: ope5(); break;
5183 case 0xe6: ope6(); break;
5184 case 0xe7: ope7(); break;
5185 case 0xe8: ope8(); break;
5186 case 0xe9: ope9(); break;
5187 case 0xea: opea(); break;
5188 case 0xeb: opeb(); break;
5189 case 0xec: opec(); break;
5190 case 0xed: oped(); break;
5191 case 0xee: opee(); break;
5192 case 0xef: opef(); break;
5193 case 0xf0: opf0(); break;
5194 case 0xf1: opf1(); break;
5195 case 0xf2: opf2(); break;
5196 case 0xf3: opf3(); break;
5197 case 0xf4: opf4(); break;
5198 case 0xf5: opf5(); break;
5199 case 0xf6: opf6(); break;
5200 case 0xf7: opf7(); break;
5201 case 0xf8: opf8(); break;
5202 case 0xf9: opf9(); break;
5203 case 0xfa: opfa(); break;
5204 case 0xfb: opfb(); break;
5205 case 0xfc: opfc(); break;
5206 case 0xfd: opfd(); break;
5207 case 0xfe: opfe(); break;
5208 case 0xff: opff(); break;
5209 }
5210
5211 /* clear the H state if it was previously set */
5212 SR ^= oldh;
5213
5214 SET_ILC(m_instruction_length & 3);
5215
5216 if( GET_T && GET_P && m_delay.delay_cmd == NO_DELAY ) /* Not in a Delayed Branch instructions */
5217 {
5218 UINT32 addr = get_trap_addr(TRAPNO_TRACE_EXCEPTION);
5219 execute_exception(addr);
5220 }
5221
5222 if (--m_intblock == 0)
5223 check_interrupts();
5224
5225 // here??
5226 if (timer_time > 0) {
5227 timer_time -= t_icount - m_icount;
5228 if (timer_time <= 0) {
5229 timer_callback(timer_param);
5230 }
5231 }
5232
5233 itotal_cycles += t_icount - m_icount;
5234
5235 } while( m_icount > 0 && !end_run );
5236
5237 cycles = n_cycles - m_icount;
5238 utotal_cycles += cycles;
5239
5240 n_cycles = m_icount = 0;
5241
5242 return cycles;
5243 }
5244
E132XSRunEnd()5245 void E132XSRunEnd()
5246 {
5247 end_run = 1;
5248 }
5249
E132XSRunEndBurnAllCycles()5250 void E132XSRunEndBurnAllCycles()
5251 {
5252 m_icount = 0;
5253 }
5254
E132XSBurnCycles(INT32 cycles)5255 INT32 E132XSBurnCycles(INT32 cycles)
5256 {
5257 m_icount -= cycles;
5258 return cycles;
5259 }
5260
5261
5262