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