summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/e132xs/e132xs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/e132xs/e132xs.cpp')
-rw-r--r--src/devices/cpu/e132xs/e132xs.cpp4294
1 files changed, 537 insertions, 3757 deletions
diff --git a/src/devices/cpu/e132xs/e132xs.cpp b/src/devices/cpu/e132xs/e132xs.cpp
index bfd8de0fc9a..73725ec8a25 100644
--- a/src/devices/cpu/e132xs/e132xs.cpp
+++ b/src/devices/cpu/e132xs/e132xs.cpp
@@ -32,7 +32,7 @@
TODO:
- some wrong cycle counts
-
+ - verify register wrapping with sregf/dregf on hardware
CHANGELOG:
Pierpaolo Prazzoli
@@ -101,10 +101,6 @@
Pierpaolo Prazzoli
- Same fix in get_const
- Ryan Holtz - 02/27/04
- - Fixed delayed branching
- - const_val for CALL should always have bit 0 clear
-
Pierpaolo Prazzoli - 02/25/04
- Fixed some wrong addresses to address local registers instead of memory
- Fixed FRAME and RET instruction
@@ -133,84 +129,16 @@
(From the doc: A Call, Trap or Software instruction increments the FP and sets FL
to 6, thus creating a new stack frame with the length of 6 registers).
- Ryan Holtz - 10/25/03
- - Fixed CALL enough that it at least jumps to the right address, no word
- yet as to whether or not it's working enough to return.
- - Added get_lrconst() to get the const value for the CALL operand, since
- apparently using immediate_value() was wrong. The code is ugly, but it
- works properly. Vampire 1/2 now gets far enough to try to test its RAM.
- - Just from looking at it, CALL apparently doesn't frame properly. I'm not
- sure about FRAME, but perhaps it doesn't work properly - I'm not entirely
- positive. The return address when vamphalf's memory check routine is
- called at FFFFFD7E is stored in register L8, and then the RET instruction
- at the end of the routine uses L1 as the return address, so that might
- provide some clues as to how it works.
- - I'd almost be willing to bet money that there's no framing at all since
- the values in L0 - L15 as displayed by the debugger would change during a
- CALL or FRAME operation. I'll look when I'm in the mood.
- - The mood struck me, and I took a look at SET_L_REG and GET_L_REG.
- Apparently no matter what the current frame pointer is they'll always use
- local_regs[0] through local_regs[15].
-
- Ryan Holtz - 08/20/03
- - Added H flag support for MOV and MOVI
- - Changed init routine to set S flag on boot. Apparently the CPU defaults to
- supervisor mode as opposed to user mode when it powers on, as shown by the
- vamphalf power-on routines. Makes sense, too, since if the machine booted
- in user mode, it would be impossible to get into supervisor mode.
-
Pierpaolo Prazzoli - 08/19/03
- Added check for D_BIT and S_BIT where PC or SR must or must not be denoted.
(movd, divu, divs, ldxx1, ldxx2, stxx1, stxx2, mulu, muls, set, mul
call, chk)
- Ryan Holtz - 08/17/03
- - Working on support for H flag, nothing quite done yet
- - Added trap Range Error for CHK PC, PC
- - Fixed relative jumps, they have to be taken from the opcode following the
- jump instead of the jump opcode itself.
-
Pierpaolo Prazzoli - 08/17/03
- Fixed get_pcrel() when OP & 0x80 is set.
- Decremented PC by 2 also in MOV, ADD, ADDI, SUM, SUB and added the check if
D_BIT is not set. (when pc is changed they are implicit branch)
- Ryan Holtz - 08/17/03
- - Implemented a crude hack to set FL in the SR to 6, since according to the docs
- that's supposed to happen each time a trap occurs, apparently including when
- the processor starts up. The 3rd opcode executed in vamphalf checks to see if
- the FL flag in SR 6, so it's apparently the "correct" behaviour despite the
- docs not saying anything on it. If FL is not 6, the branch falls through and
- encounters a CHK PC, L2, which at that point will always throw a range trap.
- The range trap vector contains 00000000 (CHK PC, PC), which according to the
- docs will always throw a range trap (which would effectively lock the system).
- This revealed a bug: CHK PC, PC apparently does not throw a range trap, which
- needs to be fixed. Now that the "correct" behaviour is hacked in with the FL
- flags, it reveals yet another bug in that the branch is interpreted as being
- +0x8700. This means that the PC then wraps around to 000082B0, give or take
- a few bytes. While it does indeed branch to valid code, I highly doubt that
- this is the desired effect. Check for signed/unsigned relative branch, maybe?
-
- Ryan Holtz - 08/16/03
- - Fixed the debugger at least somewhat so that it displays hex instead of decimal,
- and so that it disassembles opcodes properly.
- - Fixed hyperstone_execute() to increment PC *after* executing the opcode instead of
- before. This is probably why vamphalf was booting to fffffff8, but executing at
- fffffffa instead.
- - Changed execute_trap to decrement PC by 2 so that the next opcode isn't skipped
- after a trap
- - Changed execute_br to decrement PC by 2 so that the next opcode isn't skipped
- after a branch
- - Changed hyperstone_movi to decrement PC by 2 when G0 (PC) is modified so that the
- next opcode isn't skipped after a branch
- - Changed hyperstone_movi to default to a uint32_t being moved into the register
- as opposed to a uint8_t. This is wrong, the bit width is quite likely to be
- dependent on the n field in the Rimm instruction type. However, vamphalf uses
- MOVI G0,[FFFF]FBAC (n=$13) since there's apparently no absolute branch opcode.
- What kind of CPU is this that it doesn't have an absolute jump in its branch
- instructions and you have to use an immediate MOV to do an abs. jump!?
- - Replaced usage of logerror() with smf's verboselog()
-
*********************************************************************/
#include "emu.h"
@@ -219,91 +147,10 @@
#include "debugger.h"
#include "32xsdefs.h"
+#include "32xsdasm.h"
-#ifdef MAME_DEBUG
-#define DEBUG_PRINTF(x) do { osd_printf_debug x; } while (0)
-#else
-#define DEBUG_PRINTF(x) do { } while (0)
-#endif
-
-/* Memory access */
-/* read byte */
-#define READ_B(addr) m_program->read_byte((addr))
-/* read half-word */
-#define READ_HW(addr) m_program->read_word((addr) & ~1)
-/* read word */
-#define READ_W(addr) m_program->read_dword((addr) & ~3)
-
-/* write byte */
-#define WRITE_B(addr, data) m_program->write_byte(addr, data)
-/* write half-word */
-#define WRITE_HW(addr, data) m_program->write_word((addr) & ~1, data)
-/* write word */
-#define WRITE_W(addr, data) m_program->write_dword((addr) & ~3, data)
-
-
-/* I/O access */
-/* read word */
-#define IO_READ_W(addr) m_io->read_dword(((addr) >> 11) & 0x7ffc)
-/* write word */
-#define IO_WRITE_W(addr, data) m_io->write_dword(((addr) >> 11) & 0x7ffc, data)
-
-
-#define READ_OP(addr) m_direct->read_word((addr), m_opcodexor)
-
-// set C in adds/addsi/subs/sums
-#define SETCARRYS 0
-#define MISSIONCRAFT_FLAGS 1
-
-/* Registers */
-
-/* Internal registers */
-
-#define SREG (decode)->src_value
-#define SREGF (decode)->next_src_value
-#define DREG (decode)->dst_value
-#define DREGF (decode)->next_dst_value
-#define EXTRA_U (decode)->extra.u
-#define EXTRA_S (decode)->extra.s
-
-#define SET_SREG( _data_ ) ((decode)->src_is_local ? set_local_register((decode)->src, (uint32_t)_data_) : set_global_register((decode)->src, (uint32_t)_data_))
-#define SET_SREGF( _data_ ) ((decode)->src_is_local ? set_local_register((decode)->src + 1, (uint32_t)_data_) : set_global_register((decode)->src + 1, (uint32_t)_data_))
-#define SET_DREG( _data_ ) ((decode)->dst_is_local ? set_local_register((decode)->dst, (uint32_t)_data_) : set_global_register((decode)->dst, (uint32_t)_data_))
-#define SET_DREGF( _data_ ) ((decode)->dst_is_local ? set_local_register((decode)->dst + 1, (uint32_t)_data_) : set_global_register((decode)->dst + 1, (uint32_t)_data_))
-
-#define SRC_IS_PC (!(decode)->src_is_local && (decode)->src == PC_REGISTER)
-#define DST_IS_PC (!(decode)->dst_is_local && (decode)->dst == PC_REGISTER)
-#define SRC_IS_SR (!(decode)->src_is_local && (decode)->src == SR_REGISTER)
-#define DST_IS_SR (!(decode)->dst_is_local && (decode)->dst == SR_REGISTER)
-#define SAME_SRC_DST (decode)->same_src_dst
-#define SAME_SRC_DSTF (decode)->same_src_dstf
-#define SAME_SRCF_DST (decode)->same_srcf_dst
-
-
-/* Memory access */
-/* read byte */
-#define READ_B(addr) m_program->read_byte((addr))
-/* read half-word */
-#define READ_HW(addr) m_program->read_word((addr) & ~1)
-/* read word */
-#define READ_W(addr) m_program->read_dword((addr) & ~3)
-
-/* write byte */
-#define WRITE_B(addr, data) m_program->write_byte(addr, data)
-/* write half-word */
-#define WRITE_HW(addr, data) m_program->write_word((addr) & ~1, data)
-/* write word */
-#define WRITE_W(addr, data) m_program->write_dword((addr) & ~3, data)
-
-
-/* I/O access */
-/* read word */
-#define IO_READ_W(addr) m_io->read_dword(((addr) >> 11) & 0x7ffc)
-/* write word */
-#define IO_WRITE_W(addr, data) m_io->write_dword(((addr) >> 11) & 0x7ffc, data)
-
-
-#define READ_OP(addr) m_direct->read_word((addr), m_opcodexor)
+//#define VERBOSE 1
+#include "logmacro.h"
//**************************************************************************
// INTERNAL ADDRESS MAP
@@ -353,9 +200,6 @@ hyperstone_device::hyperstone_device(const machine_config &mconfig, const char *
m_io_config("io", ENDIANNESS_BIG, io_data_width, 15),
m_icount(0)
{
- // build the opcode table
- for (int op = 0; op < 256; op++)
- m_opcode[op] = s_opcodetable[op];
}
@@ -555,87 +399,11 @@ void hyperstone_device::hyperstone_set_trap_entry(int which)
break;
default:
- DEBUG_PRINTF(("Set entry point to a reserved value: %d\n", which));
+ LOG("Set entry point to a reserved value: %d\n", which);
break;
}
}
-#define OP m_op
-#define PPC m_ppc //previous pc
-#define PC m_global_regs[0] //Program Counter
-#define SR m_global_regs[1] //Status Register
-#define FER m_global_regs[2] //Floating-Point Exception Register
-// 03 - 15 General Purpose Registers
-// 16 - 17 Reserved
-#define SP m_global_regs[18] //Stack Pointer
-#define UB m_global_regs[19] //Upper Stack Bound
-#define BCR m_global_regs[20] //Bus Control Register
-#define TPR m_global_regs[21] //Timer Prescaler Register
-#define TCR m_global_regs[22] //Timer Compare Register
-#define TR compute_tr() //Timer Register
-#define WCR m_global_regs[24] //Watchdog Compare Register
-#define ISR m_global_regs[25] //Input Status Register
-#define FCR m_global_regs[26] //Function Control Register
-#define MCR m_global_regs[27] //Memory Control Register
-// 28 - 31 Reserved
-
-/* SR flags */
-#define GET_C ( SR & 0x00000001) // bit 0 //CARRY
-#define GET_Z ((SR & 0x00000002)>>1) // bit 1 //ZERO
-#define GET_N ((SR & 0x00000004)>>2) // bit 2 //NEGATIVE
-#define GET_V ((SR & 0x00000008)>>3) // bit 3 //OVERFLOW
-#define GET_M ((SR & 0x00000010)>>4) // bit 4 //CACHE-MODE
-#define GET_H ((SR & 0x00000020)>>5) // bit 5 //HIGHGLOBAL
-// bit 6 RESERVED (always 0)
-#define GET_I ((SR & 0x00000080)>>7) // bit 7 //INTERRUPT-MODE
-#define GET_FTE ((SR & 0x00001f00)>>8) // bits 12 - 8 //Floating-Point Trap Enable
-#define GET_FRM ((SR & 0x00006000)>>13) // bits 14 - 13 //Floating-Point Rounding Mode
-#define GET_L ((SR & 0x00008000)>>15) // bit 15 //INTERRUPT-LOCK
-#define GET_T ((SR & 0x00010000)>>16) // bit 16 //TRACE-MODE
-#define GET_P ((SR & 0x00020000)>>17) // bit 17 //TRACE PENDING
-#define GET_S ((SR & 0x00040000)>>18) // bit 18 //SUPERVISOR STATE
-#define GET_ILC ((SR & 0x00180000)>>19) // bits 20 - 19 //INSTRUCTION-LENGTH
-/* if FL is zero it is always interpreted as 16 */
-#define GET_FL ((SR & 0x01e00000) ? ((SR & 0x01e00000)>>21) : 16) // bits 24 - 21 //FRAME LENGTH
-#define GET_FP ((SR & 0xfe000000)>>25) // bits 31 - 25 //FRAME POINTER
-
-#define SET_C(val) (SR = (SR & ~0x00000001) | (val))
-#define SET_Z(val) (SR = (SR & ~0x00000002) | ((val) << 1))
-#define SET_N(val) (SR = (SR & ~0x00000004) | ((val) << 2))
-#define SET_V(val) (SR = (SR & ~0x00000008) | ((val) << 3))
-#define SET_M(val) (SR = (SR & ~0x00000010) | ((val) << 4))
-#define SET_H(val) (SR = (SR & ~0x00000020) | ((val) << 5))
-#define SET_I(val) (SR = (SR & ~0x00000080) | ((val) << 7))
-#define SET_FTE(val) (SR = (SR & ~0x00001f00) | ((val) << 8))
-#define SET_FRM(val) (SR = (SR & ~0x00006000) | ((val) << 13))
-#define SET_L(val) (SR = (SR & ~0x00008000) | ((val) << 15))
-#define SET_T(val) (SR = (SR & ~0x00010000) | ((val) << 16))
-#define SET_P(val) (SR = (SR & ~0x00020000) | ((val) << 17))
-#define SET_S(val) (SR = (SR & ~0x00040000) | ((val) << 18))
-#define SET_ILC(val) (SR = (SR & ~0x00180000) | ((val) << 19))
-#define SET_FL(val) (SR = (SR & ~0x01e00000) | ((val) << 21))
-#define SET_FP(val) (SR = (SR & ~0xfe000000) | ((val) << 25))
-
-#define SET_PC(val) PC = ((val) & 0xfffffffe) //PC(0) = 0
-#define SET_SP(val) SP = ((val) & 0xfffffffc) //SP(0) = SP(1) = 0
-#define SET_UB(val) UB = ((val) & 0xfffffffc) //UB(0) = UB(1) = 0
-
-#define SET_LOW_SR(val) (SR = (SR & 0xffff0000) | ((val) & 0x0000ffff)) // when SR is addressed, only low 16 bits can be changed
-
-
-#define CHECK_C(x) (SR = (SR & ~0x00000001) | (((x) & (((uint64_t)1) << 32)) ? 1 : 0 ))
-#define CHECK_VADD(x,y,z) (SR = (SR & ~0x00000008) | ((((x) ^ (z)) & ((y) ^ (z)) & 0x80000000) ? 8: 0))
-#define CHECK_VADD3(x,y,w,z) (SR = (SR & ~0x00000008) | ((((x) ^ (z)) & ((y) ^ (z)) & ((w) ^ (z)) & 0x80000000) ? 8: 0))
-#define CHECK_VSUB(x,y,z) (SR = (SR & ~0x00000008) | ((((z) ^ (y)) & ((y) ^ (x)) & 0x80000000) ? 8: 0))
-
-
-/* FER flags */
-#define GET_ACCRUED (FER & 0x0000001f) //bits 4 - 0 //Floating-Point Accrued Exceptions
-#define GET_ACTUAL (FER & 0x00001f00) //bits 12 - 8 //Floating-Point Actual Exceptions
-//other bits are reversed, in particular 7 - 5 for the operating system.
-//the user program can only changes the above 2 flags
-
-
uint32_t hyperstone_device::compute_tr()
{
uint64_t cycles_since_base = total_cycles() - m_tr_base_cycles;
@@ -650,6 +418,7 @@ void hyperstone_device::update_timer_prescale()
m_clck_scale = (TPR >> 26) & m_clock_scale_mask;
m_clock_cycles_1 = 1 << m_clck_scale;
m_clock_cycles_2 = 2 << m_clck_scale;
+ m_clock_cycles_3 = 3 << m_clck_scale;
m_clock_cycles_4 = 4 << m_clck_scale;
m_clock_cycles_6 = 6 << m_clck_scale;
m_tr_clocks_per_tick = ((TPR >> 16) & 0xff) + 2;
@@ -730,23 +499,23 @@ uint32_t hyperstone_device::get_global_register(uint8_t code)
case 29:
case 30:
case 31:
- DEBUG_PRINTF(("read _Reserved_ Global Register %d @ %08X\n",code,PC));
+ LOG("read _Reserved_ Global Register %d @ %08X\n",code,PC);
break;
case BCR_REGISTER:
- DEBUG_PRINTF(("read write-only BCR register @ %08X\n",PC));
+ LOG("read write-only BCR register @ %08X\n",PC);
return 0;
case TPR_REGISTER:
- DEBUG_PRINTF(("read write-only TPR register @ %08X\n",PC));
+ LOG("read write-only TPR register @ %08X\n",PC);
return 0;
case FCR_REGISTER:
- DEBUG_PRINTF(("read write-only FCR register @ %08X\n",PC));
+ LOG("read write-only FCR register @ %08X\n",PC);
return 0;
case MCR_REGISTER:
- DEBUG_PRINTF(("read write-only MCR register @ %08X\n",PC));
+ LOG("read write-only MCR register @ %08X\n",PC);
return 0;
}
}
@@ -758,585 +527,253 @@ uint32_t hyperstone_device::get_global_register(uint8_t code)
m_icount -= m_tr_clocks_per_tick / 2;
return compute_tr();
}
- return m_global_regs[code];
+ return m_global_regs[code & 0x1f];
}
void hyperstone_device::set_local_register(uint8_t code, uint32_t val)
{
- uint8_t new_code = (code + GET_FP) % 64;
-
- m_local_regs[new_code] = val;
+ m_local_regs[(code + GET_FP) & 0x3f] = val;
}
void hyperstone_device::set_global_register(uint8_t code, uint32_t val)
{
//TODO: add correct FER set instruction
-
- if( code == PC_REGISTER )
- {
- SET_PC(val);
- }
- else if( code == SR_REGISTER )
- {
- SET_LOW_SR(val); // only a RET instruction can change the full content of SR
- SR &= ~0x40; //reserved bit 6 always zero
- if (m_intblock < 1)
- m_intblock = 1;
- }
- else
- {
- uint32_t oldval = m_global_regs[code];
- if( code != ISR_REGISTER )
+ code &= 0x1f;
+ switch (code)
+ {
+ case PC_REGISTER:
+ SET_PC(val);
+ return;
+ case SR_REGISTER:
+ SET_LOW_SR(val); // only a RET instruction can change the full content of SR
+ SR &= ~0x40; //reserved bit 6 always zero
+ if (m_intblock < 1)
+ m_intblock = 1;
+ return;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+ // are the below ones set only when privilege bit is set?
+ case 17:
m_global_regs[code] = val;
- else
- DEBUG_PRINTF(("Written to ISR register. PC = %08X\n", PC));
-
- //are these set only when privilege bit is set?
- if( code >= 16 )
- {
- switch( code )
+ return;
+ case SP_REGISTER:
+ case UB_REGISTER:
+ m_global_regs[code] = val & ~3;
+ return;
+ case BCR_REGISTER:
+ m_global_regs[code] = val;
+ return;
+ case TPR_REGISTER:
+ m_global_regs[code] = val;
+ if (!(val & 0x80000000)) /* change immediately */
+ update_timer_prescale();
+ adjust_timer_interrupt();
+ return;
+ case TCR_REGISTER:
+ if (m_global_regs[code] != val)
{
- case 18:
- SET_SP(val);
- break;
-
- case 19:
- SET_UB(val);
- break;
-/*
- case ISR_REGISTER:
- DEBUG_PRINTF(("written %08X to read-only ISR register\n",val));
- break;
-
- case TCR_REGISTER:
-// DEBUG_PRINTF(("written %08X to TCR register\n",val));
- break;
-
- case 23:
-// DEBUG_PRINTF(("written %08X to TR register\n",val));
- break;
-
- case 24:
-// DEBUG_PRINTF(("written %08X to WCR register\n",val));
- break;
-
- case 16:
- case 17:
- case 28:
- case 29:
- case 30:
- case 31:
- DEBUG_PRINTF(("written %08X to _Reserved_ Global Register %d\n",val,code));
- break;
-
- case BCR_REGISTER:
- break;
-*/
- case TR_REGISTER:
- m_tr_base_value = val;
- m_tr_base_cycles = total_cycles();
- adjust_timer_interrupt();
- break;
-
- case TPR_REGISTER:
- if (!(val & 0x80000000)) /* change immediately */
- update_timer_prescale();
+ m_global_regs[code] = val;
adjust_timer_interrupt();
- break;
-
- case TCR_REGISTER:
- if (oldval != val)
- {
- adjust_timer_interrupt();
- if (m_intblock < 1)
- m_intblock = 1;
- }
- break;
-
- case FCR_REGISTER:
- if ((oldval ^ val) & 0x00800000)
- adjust_timer_interrupt();
if (m_intblock < 1)
m_intblock = 1;
- break;
-
- case MCR_REGISTER:
- // bits 14..12 EntryTableMap
- hyperstone_set_trap_entry((val & 0x7000) >> 12);
- break;
}
- }
+ return;
+ case TR_REGISTER:
+ m_global_regs[code] = val;
+ m_tr_base_value = val;
+ m_tr_base_cycles = total_cycles();
+ adjust_timer_interrupt();
+ return;
+ case WCR_REGISTER:
+ m_global_regs[code] = val;
+ return;
+ case ISR_REGISTER:
+ return;
+ case FCR_REGISTER:
+ if ((m_global_regs[code] ^ val) & 0x00800000)
+ adjust_timer_interrupt();
+ m_global_regs[code] = val;
+ if (m_intblock < 1)
+ m_intblock = 1;
+ return;
+ case MCR_REGISTER:
+ // bits 14..12 EntryTableMap
+ hyperstone_set_trap_entry((val & 0x7000) >> 12);
+ m_global_regs[code] = val;
+ return;
+ case 28:
+ case 29:
+ case 30:
+ case 31:
+ m_global_regs[code] = val;
+ return;
}
}
-#define GET_ABS_L_REG(code) m_local_regs[code]
-#define SET_L_REG(code, val) set_local_register(code, val)
-#define SET_ABS_L_REG(code, val) m_local_regs[code] = val
-#define GET_G_REG(code) get_global_register(code)
-#define SET_G_REG(code, val) set_global_register(code, val)
-
#define S_BIT ((OP & 0x100) >> 8)
-#define N_BIT S_BIT
#define D_BIT ((OP & 0x200) >> 9)
-#define N_VALUE ((N_BIT << 4) | (OP & 0x0f))
+#define N_VALUE (((OP & 0x100) >> 4) | (OP & 0x0f))
+#define HI_N_VALUE (0x10 | (OP & 0x0f))
+#define LO_N_VALUE (OP & 0x0f)
+#define N_OP_MASK (m_op & 0x10f)
#define DST_CODE ((OP & 0xf0) >> 4)
#define SRC_CODE (OP & 0x0f)
#define SIGN_BIT(val) ((val & 0x80000000) >> 31)
+#define SIGN_TO_N(val) ((val & 0x80000000) >> 29)
-#define LOCAL 1
-
-static const int32_t immediate_values[32] =
+static constexpr int32_t immediate_values[32] =
{
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
- 16, 0, 0, 0, 32, 64, 128, static_cast<int32_t>(0x80000000),
+ 16, 0, 0, 0, 32, 64, 128, int32_t(0x80000000),
-8, -7, -6, -5, -4, -3, -2, -1
};
-#define WRITE_ONLY_REGMASK ((1 << BCR_REGISTER) | (1 << TPR_REGISTER) | (1 << FCR_REGISTER) | (1 << MCR_REGISTER))
-
-#define decode_source(decode, local, hflag) \
-do \
-{ \
- if(local) \
- { \
- uint8_t code = (decode)->src; \
- (decode)->src_is_local = 1; \
- code = ((decode)->src + GET_FP) % 64; /* registers offset by frame pointer */\
- SREG = m_local_regs[code]; \
- code = ((decode)->src + 1 + GET_FP) % 64; \
- SREGF = m_local_regs[code]; \
- } \
- else \
- { \
- (decode)->src_is_local = 0; \
- \
- if (!hflag) \
- { \
- SREG = get_global_register((decode)->src); \
- \
- /* bound safe */ \
- if ((decode)->src != 15) \
- SREGF = get_global_register((decode)->src + 1); \
- } \
- else \
- { \
- (decode)->src += 16; \
- \
- SREG = get_global_register((decode)->src); \
- if ((WRITE_ONLY_REGMASK >> (decode)->src) & 1) \
- SREG = 0; /* write-only registers */ \
- else if ((decode)->src == ISR_REGISTER) \
- DEBUG_PRINTF(("read src ISR. PC = %08X\n",PPC)); \
- \
- /* bound safe */ \
- if ((decode)->src != 31) \
- SREGF = get_global_register((decode)->src + 1); \
- } \
- } \
-} while (0)
-
-#define decode_dest(decode, local, hflag) \
-do \
-{ \
- if(local) \
- { \
- uint8_t code = (decode)->dst; \
- (decode)->dst_is_local = 1; \
- code = ((decode)->dst + GET_FP) % 64; /* registers offset by frame pointer */\
- DREG = m_local_regs[code]; \
- code = ((decode)->dst + 1 + GET_FP) % 64; \
- DREGF = m_local_regs[code]; \
- } \
- else \
- { \
- (decode)->dst_is_local = 0; \
- \
- if (!hflag) \
- { \
- DREG = get_global_register((decode)->dst); \
- \
- /* bound safe */ \
- if ((decode)->dst != 15) \
- DREGF = get_global_register((decode)->dst + 1); \
- } \
- else \
- { \
- (decode)->dst += 16; \
- \
- DREG = get_global_register((decode)->dst); \
- if( (decode)->dst == ISR_REGISTER ) \
- DEBUG_PRINTF(("read dst ISR. PC = %08X\n",PPC)); \
- \
- /* bound safe */ \
- if ((decode)->dst != 31) \
- DREGF = get_global_register((decode)->dst + 1); \
- } \
- } \
-} while (0)
-
-#define decode_RR(decode, dlocal, slocal) \
-do \
-{ \
- (decode)->src = SRC_CODE; \
- (decode)->dst = DST_CODE; \
- decode_source(decode, slocal, 0); \
- decode_dest(decode, dlocal, 0); \
- \
- if( (slocal) == (dlocal) && SRC_CODE == DST_CODE ) \
- SAME_SRC_DST = 1; \
- \
- if( (slocal) == LOCAL && (dlocal) == LOCAL ) \
- { \
- if( SRC_CODE == ((DST_CODE + 1) % 64) ) \
- SAME_SRC_DSTF = 1; \
- \
- if( ((SRC_CODE + 1) % 64) == DST_CODE ) \
- SAME_SRCF_DST = 1; \
- } \
- else if( (slocal) == 0 && (dlocal) == 0 ) \
- { \
- if( SRC_CODE == (DST_CODE + 1) ) \
- SAME_SRC_DSTF = 1; \
- \
- if( (SRC_CODE + 1) == DST_CODE ) \
- SAME_SRCF_DST = 1; \
- } \
-} while (0)
-
-#define decode_LL(decode) \
-do \
-{ \
- (decode)->src = SRC_CODE; \
- (decode)->dst = DST_CODE; \
- decode_source(decode, LOCAL, 0); \
- decode_dest(decode, LOCAL, 0); \
- \
- if( SRC_CODE == DST_CODE ) \
- SAME_SRC_DST = 1; \
- \
- if( SRC_CODE == ((DST_CODE + 1) % 64) ) \
- SAME_SRC_DSTF = 1; \
-} while (0)
-
-#define decode_LR(decode, slocal) \
-do \
-{ \
- (decode)->src = SRC_CODE; \
- (decode)->dst = DST_CODE; \
- decode_source(decode, slocal, 0); \
- decode_dest(decode, LOCAL, 0); \
- \
- if( ((SRC_CODE + 1) % 64) == DST_CODE && slocal == LOCAL ) \
- SAME_SRCF_DST = 1; \
-} while (0)
+constexpr uint32_t WRITE_ONLY_REGMASK = (1 << BCR_REGISTER) | (1 << TPR_REGISTER) | (1 << FCR_REGISTER) | (1 << MCR_REGISTER);
#define check_delay_PC() \
do \
{ \
/* if PC is used in a delay instruction, the delayed PC should be used */ \
- if( m_delay.delay_cmd == DELAY_EXECUTE ) \
+ if (m_delay_slot) \
{ \
- PC = m_delay.delay_pc; \
- m_delay.delay_cmd = NO_DELAY; \
+ PC = m_delay_pc; \
+ m_delay_slot = false; \
} \
} while (0)
-#define decode_immediate(decode, nbit) \
-do \
-{ \
- if (!nbit) \
- EXTRA_U = immediate_values[OP & 0x0f]; \
- else \
- switch( OP & 0x0f ) \
- { \
- default: \
- EXTRA_U = immediate_values[0x10 + (OP & 0x0f)]; \
- break; \
- \
- case 1: \
- m_instruction_length = 3; \
- EXTRA_U = (READ_OP(PC) << 16) | READ_OP(PC + 2); \
- PC += 4; \
- break; \
- \
- case 2: \
- m_instruction_length = 2; \
- EXTRA_U = READ_OP(PC); \
- PC += 2; \
- break; \
- \
- case 3: \
- m_instruction_length = 2; \
- EXTRA_U = 0xffff0000 | READ_OP(PC); \
- PC += 2; \
- break; \
- } \
-} while (0)
-
-#define decode_const(decode) \
-do \
-{ \
- uint16_t imm_1 = READ_OP(PC); \
- \
- PC += 2; \
- m_instruction_length = 2; \
- \
- if( E_BIT(imm_1) ) \
- { \
- uint16_t imm_2 = READ_OP(PC); \
- \
- PC += 2; \
- m_instruction_length = 3; \
- \
- EXTRA_S = imm_2; \
- EXTRA_S |= ((imm_1 & 0x3fff) << 16); \
- \
- if( S_BIT_CONST(imm_1) ) \
- { \
- EXTRA_S |= 0xc0000000; \
- } \
- } \
- else \
- { \
- EXTRA_S = imm_1 & 0x3fff; \
- \
- if( S_BIT_CONST(imm_1) ) \
- { \
- EXTRA_S |= 0xffffc000; \
- } \
- } \
-} while (0)
-
-#define decode_pcrel(decode) \
-do \
-{ \
- if( OP & 0x80 ) \
- { \
- uint16_t next = READ_OP(PC); \
- \
- PC += 2; \
- m_instruction_length = 2; \
- \
- EXTRA_S = (OP & 0x7f) << 16; \
- EXTRA_S |= (next & 0xfffe); \
- \
- if( next & 1 ) \
- EXTRA_S |= 0xff800000; \
- } \
- else \
- { \
- EXTRA_S = OP & 0x7e; \
- \
- if( OP & 1 ) \
- EXTRA_S |= 0xffffff80; \
- } \
-} while (0)
-
-#define decode_dis(decode) \
-do \
-{ \
- uint16_t next_1 = READ_OP(PC); \
- \
- PC += 2; \
- m_instruction_length = 2; \
- \
- (decode)->sub_type = DD(next_1); \
- \
- if( E_BIT(next_1) ) \
- { \
- uint16_t next_2 = READ_OP(PC); \
- \
- PC += 2; \
- m_instruction_length = 3; \
- \
- EXTRA_S = next_2; \
- EXTRA_S |= ((next_1 & 0xfff) << 16); \
- \
- if( S_BIT_CONST(next_1) ) \
- { \
- EXTRA_S |= 0xf0000000; \
- } \
- } \
- else \
- { \
- EXTRA_S = next_1 & 0xfff; \
- \
- if( S_BIT_CONST(next_1) ) \
- { \
- EXTRA_S |= 0xfffff000; \
- } \
- } \
-} while (0)
-
-#define decode_lim(decode) \
-do \
-{ \
- uint32_t next = READ_OP(PC); \
- PC += 2; \
- m_instruction_length = 2; \
- \
- (decode)->sub_type = X_CODE(next); \
- \
- if( E_BIT(next) ) \
- { \
- EXTRA_U = ((next & 0xfff) << 16) | READ_OP(PC); \
- PC += 2; \
- m_instruction_length = 3; \
- } \
- else \
- { \
- EXTRA_U = next & 0xfff; \
- } \
-} while (0)
-
-#define RRdecode(decode, dlocal, slocal) \
-do \
-{ \
- check_delay_PC(); \
- decode_RR(decode, dlocal, slocal); \
-} while (0)
-
-#define RRlimdecode(decode, dlocal, slocal) \
-do \
-{ \
- decode_lim(decode); \
- check_delay_PC(); \
- decode_RR(decode, dlocal, slocal); \
-} while (0)
+void hyperstone_device::ignore_immediate_s()
+{
+ static const uint32_t lengths[16] = { 1<<19, 3<<19, 2<<19, 2<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19 };
+ static const uint32_t offsets[16] = { 0, 4, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ const uint8_t nybble = m_op & 0x0f;
+ m_instruction_length = lengths[nybble];
+ PC += offsets[nybble];
+}
-#define RRconstdecode(decode, dlocal, slocal) \
-do \
-{ \
- decode_const(decode); \
- check_delay_PC(); \
- decode_RR(decode, dlocal, slocal); \
-} while (0)
+uint32_t hyperstone_device::decode_immediate_s()
+{
+ const uint8_t nybble = m_op & 0x0f;
+ switch (nybble)
+ {
+ case 0:
+ default:
+ return immediate_values[0x10 + nybble];
+ case 1:
+ {
+ m_instruction_length = (3<<19);
+ uint32_t extra_u = (READ_OP(PC) << 16) | READ_OP(PC + 2);
+ PC += 4;
+ return extra_u;
+ }
+ case 2:
+ {
+ m_instruction_length = (2<<19);
+ uint32_t extra_u = READ_OP(PC);
+ PC += 2;
+ return extra_u;
+ }
+ case 3:
+ {
+ m_instruction_length = (2<<19);
+ uint32_t extra_u = 0xffff0000 | READ_OP(PC);
+ PC += 2;
+ return extra_u;
+ }
+ }
+}
-#define RRdisdecode(decode, dlocal, slocal) \
-do \
-{ \
- decode_dis(decode); \
- check_delay_PC(); \
- decode_RR(decode, dlocal, slocal); \
-} while (0)
+uint32_t hyperstone_device::decode_const()
+{
+ const uint16_t imm_1 = READ_OP(PC);
-#define RRdecodewithHflag(decode, dlocal, slocal) \
-do \
-{ \
- check_delay_PC(); \
- (decode)->src = SRC_CODE; \
- (decode)->dst = DST_CODE; \
- decode_source(decode, slocal, GET_H); \
- decode_dest(decode, dlocal, GET_H); \
- \
- if(GET_H) \
- if(slocal == 0 && dlocal == 0) \
- DEBUG_PRINTF(("MOV with hflag and 2 GRegs! PC = %08X\n",PPC)); \
-} while (0)
+ PC += 2;
+ m_instruction_length = (2<<19);
-#define Rimmdecode(decode, dlocal, nbit) \
-do \
-{ \
- decode_immediate(decode, nbit); \
- check_delay_PC(); \
- (decode)->dst = DST_CODE; \
- decode_dest(decode, dlocal, 0); \
-} while (0)
+ if (imm_1 & 0x8000)
+ {
+ const uint16_t imm_2 = READ_OP(PC);
-#define Rndecode(decode, dlocal) \
-do \
-{ \
- check_delay_PC(); \
- (decode)->dst = DST_CODE; \
- decode_dest(decode, dlocal, 0); \
-} while (0)
+ PC += 2;
+ m_instruction_length = (3<<19);
-#define RimmdecodewithHflag(decode, dlocal, nbit) \
-do \
-{ \
- decode_immediate(decode, nbit); \
- check_delay_PC(); \
- (decode)->dst = DST_CODE; \
- decode_dest(decode, dlocal, GET_H); \
-} while (0)
+ uint32_t imm = imm_2;
+ imm |= ((imm_1 & 0x3fff) << 16);
-#define Lndecode(decode) \
-do \
-{ \
- check_delay_PC(); \
- (decode)->dst = DST_CODE; \
- decode_dest(decode, LOCAL, 0); \
-} while (0)
+ if (imm_1 & 0x4000)
+ imm |= 0xc0000000;
+ return imm;
+ }
+ else
+ {
+ uint32_t imm = imm_1 & 0x3fff;
-#define LLdecode(decode) \
-do \
-{ \
- check_delay_PC(); \
- decode_LL(decode); \
-} while (0)
+ if (imm_1 & 0x4000)
+ imm |= 0xffffc000;
+ return imm;
+ }
+}
-#define LLextdecode(decode) \
-do \
-{ \
- m_instruction_length = 2; \
- EXTRA_U = READ_OP(PC); \
- PC += 2; \
- check_delay_PC(); \
- decode_LL(decode); \
-} while (0)
+int32_t hyperstone_device::decode_pcrel()
+{
+ if (OP & 0x80)
+ {
+ uint16_t next = READ_OP(PC);
-#define LRdecode(decode, slocal) \
-do \
-{ \
- check_delay_PC(); \
- decode_LR(decode, slocal); \
-} while (0)
+ PC += 2;
+ m_instruction_length = (2<<19);
-#define LRconstdecode(decode, slocal) \
-do \
-{ \
- decode_const(decode); \
- check_delay_PC(); \
- decode_LR(decode, slocal); \
-} while (0)
+ int32_t offset = (OP & 0x7f) << 16;
+ offset |= (next & 0xfffe);
-#define PCreldecode(decode) \
-do \
-{ \
- decode_pcrel(decode); \
- check_delay_PC(); \
-} while (0)
+ if (next & 1)
+ offset |= 0xff800000;
-#define PCadrdecode(decode) \
-do \
-{ \
- check_delay_PC(); \
-} while (0)
+ return offset;
+ }
+ else
+ {
+ int32_t offset = OP & 0x7e;
-#define no_decode(decode) \
-do \
-{ \
-} while (0)
+ if (OP & 1)
+ offset |= 0xffffff80;
+ return offset;
+ }
+}
-void hyperstone_device::execute_br(struct hyperstone_device::regs_decode *decode)
+void hyperstone_device::ignore_pcrel()
{
- PPC = PC;
- PC += EXTRA_S;
- SET_M(0);
-
- m_icount -= m_clock_cycles_2;
+ if (m_op & 0x80)
+ {
+ PC += 2;
+ m_instruction_length = (2<<19);
+ }
}
-void hyperstone_device::execute_dbr(struct hyperstone_device::regs_decode *decode)
+void hyperstone_device::execute_br()
{
- m_delay.delay_cmd = DELAY_EXECUTE;
- m_delay.delay_pc = PC + EXTRA_S;
+ const int32_t offset = decode_pcrel();
+ check_delay_PC();
- m_intblock = 3;
-}
+ PC += offset;
+ SR &= ~M_MASK;
+ m_icount -= m_clock_cycles_2;
+}
void hyperstone_device::execute_trap(uint32_t addr)
{
@@ -1344,22 +781,21 @@ void hyperstone_device::execute_trap(uint32_t addr)
uint32_t oldSR;
reg = GET_FP + GET_FL;
- SET_ILC(m_instruction_length & 3);
+ SET_ILC(m_instruction_length);
oldSR = SR;
SET_FL(6);
SET_FP(reg);
- SET_L_REG(0, (PC & 0xfffffffe) | GET_S);
- SET_L_REG(1, oldSR);
+ set_local_register(0, (PC & 0xfffffffe) | GET_S);
+ set_local_register(1, oldSR);
SET_M(0);
SET_T(0);
SET_L(1);
SET_S(1);
- PPC = PC;
PC = addr;
m_icount -= m_clock_cycles_2;
@@ -1368,27 +804,19 @@ void hyperstone_device::execute_trap(uint32_t addr)
void hyperstone_device::execute_int(uint32_t addr)
{
- uint8_t reg;
- uint32_t oldSR;
- reg = GET_FP + GET_FL;
-
- SET_ILC(m_instruction_length & 3);
-
- oldSR = SR;
+ const uint8_t reg = GET_FP + GET_FL;
+ SET_ILC(m_instruction_length);
+ const uint32_t oldSR = SR;
SET_FL(2);
SET_FP(reg);
- SET_L_REG(0, (PC & 0xfffffffe) | GET_S);
- SET_L_REG(1, oldSR);
+ m_local_regs[(0 + reg) & 0x3f] = (PC & ~1) | GET_S;
+ m_local_regs[(1 + reg) & 0x3f] = oldSR;
- SET_M(0);
- SET_T(0);
- SET_L(1);
- SET_S(1);
- SET_I(1);
+ SR &= ~(M_MASK | T_MASK);
+ SR |= (L_MASK | S_MASK | I_MASK);
- PPC = PC;
PC = addr;
m_icount -= m_clock_cycles_2;
@@ -1397,66 +825,60 @@ void hyperstone_device::execute_int(uint32_t addr)
/* TODO: mask Parity Error and Extended Overflow exceptions */
void hyperstone_device::execute_exception(uint32_t addr)
{
- uint8_t reg;
- uint32_t oldSR;
- reg = GET_FP + GET_FL;
-
- SET_ILC(m_instruction_length & 3);
-
- oldSR = SR;
+ const uint8_t reg = GET_FP + GET_FL;
+ SET_ILC(m_instruction_length);
+ const uint32_t oldSR = SR;
SET_FP(reg);
SET_FL(2);
- SET_L_REG(0, (PC & 0xfffffffe) | GET_S);
- SET_L_REG(1, oldSR);
+ m_local_regs[(0 + reg) & 0x3f] = (PC & ~1) | GET_S;
+ m_local_regs[(1 + reg) & 0x3f] = oldSR;
- SET_M(0);
- SET_T(0);
- SET_L(1);
- SET_S(1);
+ SR &= ~(M_MASK | T_MASK);
+ SR |= (L_MASK | S_MASK);
- PPC = PC;
PC = addr;
- DEBUG_PRINTF(("EXCEPTION! PPC = %08X PC = %08X\n",PPC-2,PC-2));
m_icount -= m_clock_cycles_2;
}
-void hyperstone_device::execute_software(struct hyperstone_device::regs_decode *decode)
+void hyperstone_device::execute_software()
{
- uint8_t reg;
- uint32_t oldSR;
- uint32_t addr;
- uint32_t stack_of_dst;
+ check_delay_PC();
- SET_ILC(1);
+ const uint32_t fp = GET_FP;
+ const uint32_t src_code = SRC_CODE;
+ const uint32_t sreg = m_local_regs[(src_code + fp) & 0x3f];
+ const uint32_t sregf = m_local_regs[(src_code + 1 + fp) & 0x3f];
- addr = get_emu_code_addr((OP & 0xff00) >> 8);
- reg = GET_FP + GET_FL;
+ SET_ILC(1<<19);
+
+ const uint32_t addr = get_emu_code_addr((m_op & 0xff00) >> 8);
+ const uint8_t reg = fp + GET_FL;
//since it's sure the register is in the register part of the stack,
//set the stack address to a value above the highest address
//that can be set by a following frame instruction
- stack_of_dst = (SP & ~0xff) + 64*4 + (((GET_FP + decode->dst) % 64) * 4); //converted to 32bits offset
+ const uint32_t stack_of_dst = (SP & ~0xff) + 64*4 + (((fp + DST_CODE) % 64) * 4); //converted to 32bits offset
- oldSR = SR;
+ const uint32_t oldSR = SR;
SET_FL(6);
SET_FP(reg);
- SET_L_REG(0, stack_of_dst);
- SET_L_REG(1, SREG);
- SET_L_REG(2, SREGF);
- SET_L_REG(3, (PC & 0xfffffffe) | GET_S);
- SET_L_REG(4, oldSR);
+ m_local_regs[(reg + 0) & 0x3f] = stack_of_dst;
+ m_local_regs[(reg + 1) & 0x3f] = sreg;
+ m_local_regs[(reg + 2) & 0x3f] = sregf;
+ m_local_regs[(reg + 3) & 0x3f] = (PC & ~1) | GET_S;
+ m_local_regs[(reg + 4) & 0x3f] = oldSR;
- SET_M(0);
- SET_T(0);
- SET_L(1);
+ SR &= ~(M_MASK | T_MASK);
+ SR |= L_MASK;
- PPC = PC;
PC = addr;
+
+ m_icount -= m_clock_cycles_6;
}
@@ -1588,7 +1010,6 @@ void hyperstone_device::init(int scale_mask)
{
memset(m_global_regs, 0, sizeof(uint32_t) * 32);
memset(m_local_regs, 0, sizeof(uint32_t) * 64);
- m_ppc = 0;
m_op = 0;
m_trap_entry = 0;
m_clock_scale_mask = 0;
@@ -1609,12 +1030,17 @@ void hyperstone_device::init(int scale_mask)
m_icount = 0;
m_program = &space(AS_PROGRAM);
- m_direct = &m_program->direct();
+ m_direct = m_program->direct<0>();
m_io = &space(AS_IO);
m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(hyperstone_device::timer_callback), this));
m_clock_scale_mask = scale_mask;
+ for (uint8_t i = 0; i < 16; i++)
+ {
+ m_fl_lut[i] = (i ? i : 16);
+ }
+
// register our state for the debugger
state_add(STATE_GENPC, "GENPC", m_global_regs[0]).noshow();
state_add(STATE_GENPCBASE, "CURPC", m_global_regs[0]).noshow();
@@ -1734,12 +1160,11 @@ void hyperstone_device::init(int scale_mask)
save_item(NAME(m_global_regs));
save_item(NAME(m_local_regs));
- save_item(NAME(m_ppc));
save_item(NAME(m_trap_entry));
- save_item(NAME(m_delay.delay_pc));
+ save_item(NAME(m_delay_pc));
save_item(NAME(m_instruction_length));
save_item(NAME(m_intblock));
- save_item(NAME(m_delay.delay_cmd));
+ save_item(NAME(m_delay_slot));
save_item(NAME(m_tr_clocks_per_tick));
save_item(NAME(m_tr_base_value));
save_item(NAME(m_tr_base_cycles));
@@ -1844,7 +1269,7 @@ void hyperstone_device::device_reset()
//TODO: Add different reset initializations for BCR, MCR, FCR, TPR
m_program = &space(AS_PROGRAM);
- m_direct = &m_program->direct();
+ m_direct = m_program->direct<0>();
m_io = &space(AS_IO);
m_tr_clocks_per_tick = 2;
@@ -1866,15 +1291,14 @@ void hyperstone_device::device_reset()
SET_L(1);
SET_S(1);
- SET_L_REG(0, (PC & 0xfffffffe) | GET_S);
- SET_L_REG(1, SR);
+ set_local_register(0, (PC & 0xfffffffe) | GET_S);
+ set_local_register(1, SR);
m_icount -= m_clock_cycles_2;
}
void hyperstone_device::device_stop()
{
- // nothing to do
}
@@ -1926,2993 +1350,84 @@ void hyperstone_device::state_string_export(const device_state_entry &entry, std
//-------------------------------------------------
-// disasm_min_opcode_bytes - return the length
-// of the shortest instruction, in bytes
-//-------------------------------------------------
-
-uint32_t hyperstone_device::disasm_min_opcode_bytes() const
-{
- return 2;
-}
-
-
-//-------------------------------------------------
-// disasm_max_opcode_bytes - return the length
-// of the longest instruction, in bytes
-//-------------------------------------------------
-
-uint32_t hyperstone_device::disasm_max_opcode_bytes() const
-{
- return 6;
-}
-
-
-//-------------------------------------------------
-// disasm_disassemble - call the disassembly
+// disassemble - call the disassembly
// helper function
//-------------------------------------------------
-offs_t hyperstone_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options)
+util::disasm_interface *hyperstone_device::create_disassembler()
{
- extern CPU_DISASSEMBLE( hyperstone );
- return dasm_hyperstone(stream, pc, oprom, GET_H, GET_FP);
+ return new hyperstone_disassembler;
}
/* Opcodes */
-void hyperstone_device::hyperstone_chk(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR);
-
- if( SRC_IS_SR )
- {
- if( DREG == 0 )
- execute_exception(addr);
- }
- else
- {
- if( SRC_IS_PC )
- {
- if( DREG >= SREG )
- execute_exception(addr);
- }
- else
- {
- if( DREG > SREG )
- execute_exception(addr);
- }
- }
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_movd(struct hyperstone_device::regs_decode *decode)
-{
- if( DST_IS_PC ) // Rd denotes PC
- {
- // RET instruction
-
- uint8_t old_s, old_l;
- int8_t difference; // really it's 7 bits
-
- if( SRC_IS_PC || SRC_IS_SR )
- {
- DEBUG_PRINTF(("Denoted PC or SR in RET instruction. PC = %08X\n", PC));
- }
- else
- {
- old_s = GET_S;
- old_l = GET_L;
- PPC = PC;
-
- SET_PC(SREG);
- SR = (SREGF & 0xffe00000) | ((SREG & 0x01) << 18 ) | (SREGF & 0x3ffff);
- if (m_intblock < 1)
- m_intblock = 1;
-
- m_instruction_length = 0; // undefined
-
- if( (!old_s && GET_S) || (!GET_S && !old_l && GET_L))
- {
- uint32_t addr = get_trap_addr(TRAPNO_PRIVILEGE_ERROR);
- execute_exception(addr);
- }
-
- difference = GET_FP - ((SP & 0x1fc) >> 2);
-
- /* convert to 8 bits */
- if(difference > 63)
- difference = (int8_t)(difference|0x80);
- else if( difference < -64 )
- difference = difference & 0x7f;
-
- if( difference < 0 ) //else it's finished
- {
- do
- {
- SP -= 4;
- SET_ABS_L_REG(((SP & 0xfc) >> 2), READ_W(SP));
- difference++;
-
- } while(difference != 0);
- }
- }
-
- //TODO: no 1!
- m_icount -= m_clock_cycles_1;
- }
- else if( SRC_IS_SR ) // Rd doesn't denote PC and Rs denotes SR
- {
- SET_DREG(0);
- SET_DREGF(0);
- SET_Z(1);
- SET_N(0);
-
- m_icount -= m_clock_cycles_2;
- }
- else // Rd doesn't denote PC and Rs doesn't denote SR
- {
- uint64_t tmp;
-
- SET_DREG(SREG);
- SET_DREGF(SREGF);
-
- tmp = concat_64(SREG, SREGF);
- SET_Z( tmp == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(SREG) );
-
- m_icount -= m_clock_cycles_2;
- }
-}
-
-void hyperstone_device::hyperstone_divu(struct hyperstone_device::regs_decode *decode)
-{
- if( SAME_SRC_DST || SAME_SRC_DSTF )
- {
- DEBUG_PRINTF(("Denoted the same register code in hyperstone_divu instruction. PC = %08X\n", PC));
- }
- else
- {
- if( SRC_IS_PC || SRC_IS_SR )
- {
- DEBUG_PRINTF(("Denoted PC or SR as source register in hyperstone_divu instruction. PC = %08X\n", PC));
- }
- else
- {
- uint64_t dividend;
-
- dividend = concat_64(DREG, DREGF);
-
- if( SREG == 0 )
- {
- //Rd//Rdf -> undefined
- //Z -> undefined
- //N -> undefined
- uint32_t addr;
- SET_V(1);
- addr = get_trap_addr(TRAPNO_RANGE_ERROR);
- execute_exception(addr);
- }
- else
- {
- uint32_t quotient, remainder;
-
- /* TODO: add quotient overflow */
- quotient = dividend / SREG;
- remainder = dividend % SREG;
-
- SET_DREG(remainder);
- SET_DREGF(quotient);
-
- SET_Z( quotient == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(quotient) );
- SET_V(0);
- }
- }
- }
-
- m_icount -= 36 << m_clck_scale;
-}
-
-void hyperstone_device::hyperstone_divs(struct hyperstone_device::regs_decode *decode)
-{
- if( SAME_SRC_DST || SAME_SRC_DSTF )
- {
- DEBUG_PRINTF(("Denoted the same register code in hyperstone_divs instruction. PC = %08X\n", PC));
- }
- else
- {
- if( SRC_IS_PC || SRC_IS_SR )
- {
- DEBUG_PRINTF(("Denoted PC or SR as source register in hyperstone_divs instruction. PC = %08X\n", PC));
- }
- else
- {
- int64_t dividend;
-
- dividend = (int64_t) concat_64(DREG, DREGF);
-
- if( SREG == 0 || (DREG & 0x80000000) )
- {
- //Rd//Rdf -> undefined
- //Z -> undefined
- //N -> undefined
- uint32_t addr;
- SET_V(1);
- addr = get_trap_addr(TRAPNO_RANGE_ERROR);
- execute_exception(addr);
- }
- else
- {
- int32_t quotient, remainder;
-
- /* TODO: add quotient overflow */
- quotient = dividend / ((int32_t)(SREG));
- remainder = dividend % ((int32_t)(SREG));
-
- SET_DREG(remainder);
- SET_DREGF(quotient);
-
- SET_Z( quotient == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(quotient) );
- SET_V(0);
- }
- }
- }
-
- m_icount -= 36 << m_clck_scale;
-}
-
-void hyperstone_device::hyperstone_xm(struct hyperstone_device::regs_decode *decode)
-{
- if( SRC_IS_SR || DST_IS_SR || DST_IS_PC )
- {
- DEBUG_PRINTF(("Denoted PC or SR in hyperstone_xm. PC = %08X\n", PC));
- }
- else
- {
- switch( decode->sub_type ) // x_code
- {
- case 0:
- case 1:
- case 2:
- case 3:
- if( !SRC_IS_PC && (SREG > EXTRA_U) )
- {
- uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR);
- execute_exception(addr);
- }
- else if( SRC_IS_PC && (SREG >= EXTRA_U) )
- {
- uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR);
- execute_exception(addr);
- }
- else
- {
- SREG <<= decode->sub_type;
- }
-
- break;
-
- case 4:
- case 5:
- case 6:
- case 7:
- decode->sub_type -= 4;
- SREG <<= decode->sub_type;
-
- break;
- }
-
- SET_DREG(SREG);
- }
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_mask(struct hyperstone_device::regs_decode *decode)
-{
- DREG = SREG & EXTRA_U;
-
- SET_DREG(DREG);
- SET_Z( DREG == 0 ? 1 : 0 );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_sum(struct hyperstone_device::regs_decode *decode)
-{
- uint64_t tmp;
-
- if( SRC_IS_SR )
- SREG = GET_C;
-
- tmp = (uint64_t)(SREG) + (uint64_t)(EXTRA_U);
- CHECK_C(tmp);
- CHECK_VADD(SREG,EXTRA_U,tmp);
-
- DREG = SREG + EXTRA_U;
-
- SET_DREG(DREG);
-
- if( DST_IS_PC )
- SET_M(0);
-
- SET_Z( DREG == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(DREG) );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_sums(struct hyperstone_device::regs_decode *decode)
-{
- int32_t res;
- int64_t tmp;
-
- if( SRC_IS_SR )
- SREG = GET_C;
-
- tmp = (int64_t)((int32_t)(SREG)) + (int64_t)(EXTRA_S);
- CHECK_VADD(SREG,EXTRA_S,tmp);
-
-//#if SETCARRYS
-// CHECK_C(tmp);
-//#endif
-
- res = (int32_t)(SREG) + EXTRA_S;
-
- SET_DREG(res);
-
- SET_Z( res == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(res) );
-
- m_icount -= m_clock_cycles_1;
-
- if( GET_V && !SRC_IS_SR )
- {
- uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR);
- execute_exception(addr);
- }
-}
-
-void hyperstone_device::hyperstone_cmp(struct hyperstone_device::regs_decode *decode)
-{
- uint64_t tmp;
-
- if( SRC_IS_SR )
- SREG = GET_C;
-
- if( DREG == SREG )
- SET_Z(1);
- else
- SET_Z(0);
-
- if( (int32_t) DREG < (int32_t) SREG )
- SET_N(1);
- else
- SET_N(0);
-
- tmp = (uint64_t)(DREG) - (uint64_t)(SREG);
- CHECK_VSUB(SREG,DREG,tmp);
-
- if( DREG < SREG )
- SET_C(1);
- else
- SET_C(0);
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_mov(struct hyperstone_device::regs_decode *decode)
-{
- if( !GET_S && decode->dst >= 16 )
- {
- uint32_t addr = get_trap_addr(TRAPNO_PRIVILEGE_ERROR);
- execute_exception(addr);
- }
-
- SET_DREG(SREG);
-
- if( DST_IS_PC )
- SET_M(0);
-
- SET_Z( SREG == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(SREG) );
-
- m_icount -= m_clock_cycles_1;
-}
-
-
-void hyperstone_device::hyperstone_add(struct hyperstone_device::regs_decode *decode)
-{
- uint64_t tmp;
-
- if( SRC_IS_SR )
- SREG = GET_C;
-
- tmp = (uint64_t)(SREG) + (uint64_t)(DREG);
- CHECK_C(tmp);
- CHECK_VADD(SREG,DREG,tmp);
-
- DREG = SREG + DREG;
- SET_DREG(DREG);
-
- if( DST_IS_PC )
- SET_M(0);
-
- SET_Z( DREG == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(DREG) );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_adds(struct hyperstone_device::regs_decode *decode)
+void hyperstone_device::hyperstone_trap()
{
- int32_t res;
- int64_t tmp;
-
- if( SRC_IS_SR )
- SREG = GET_C;
-
- tmp = (int64_t)((int32_t)(SREG)) + (int64_t)((int32_t)(DREG));
-
- CHECK_VADD(SREG,DREG,tmp);
-
-//#if SETCARRYS
-// CHECK_C(tmp);
-//#endif
+ check_delay_PC();
- res = (int32_t)(SREG) + (int32_t)(DREG);
+ const uint8_t trapno = (m_op & 0xfc) >> 2;
+ const uint32_t addr = get_trap_addr(trapno);
+ const uint8_t code = ((m_op & 0x300) >> 6) | (m_op & 0x03);
- SET_DREG(res);
- SET_Z( res == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(res) );
-
- m_icount -= m_clock_cycles_1;
-
- if( GET_V )
- {
- uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR);
- execute_exception(addr);
- }
-}
-
-void hyperstone_device::hyperstone_cmpb(struct hyperstone_device::regs_decode *decode)
-{
- SET_Z( (DREG & SREG) == 0 ? 1 : 0 );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_andn(struct hyperstone_device::regs_decode *decode)
-{
- DREG = DREG & ~SREG;
-
- SET_DREG(DREG);
- SET_Z( DREG == 0 ? 1 : 0 );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_or(struct hyperstone_device::regs_decode *decode)
-{
- DREG = DREG | SREG;
-
- SET_DREG(DREG);
- SET_Z( DREG == 0 ? 1 : 0 );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_xor(struct hyperstone_device::regs_decode *decode)
-{
- DREG = DREG ^ SREG;
-
- SET_DREG(DREG);
- SET_Z( DREG == 0 ? 1 : 0 );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_subc(struct hyperstone_device::regs_decode *decode)
-{
- uint64_t tmp;
-
- if( SRC_IS_SR )
- {
- tmp = (uint64_t)(DREG) - (uint64_t)(GET_C);
- CHECK_VSUB(GET_C,DREG,tmp);
- }
- else
- {
- tmp = (uint64_t)(DREG) - ((uint64_t)(SREG) + (uint64_t)(GET_C));
- //CHECK!
- CHECK_VSUB(SREG + GET_C,DREG,tmp);
- }
-
-
- if( SRC_IS_SR )
- {
- DREG = DREG - GET_C;
- }
- else
- {
- DREG = DREG - (SREG + GET_C);
- }
-
- CHECK_C(tmp);
-
- SET_DREG(DREG);
-
- SET_Z( GET_Z & (DREG == 0 ? 1 : 0) );
- SET_N( SIGN_BIT(DREG) );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_not(struct hyperstone_device::regs_decode *decode)
-{
- SET_DREG(~SREG);
- SET_Z( ~SREG == 0 ? 1 : 0 );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_sub(struct hyperstone_device::regs_decode *decode)
-{
- uint64_t tmp;
-
- if( SRC_IS_SR )
- SREG = GET_C;
-
- tmp = (uint64_t)(DREG) - (uint64_t)(SREG);
- CHECK_C(tmp);
- CHECK_VSUB(SREG,DREG,tmp);
-
- DREG = DREG - SREG;
- SET_DREG(DREG);
-
- if( DST_IS_PC )
- SET_M(0);
-
- SET_Z( DREG == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(DREG) );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_subs(struct hyperstone_device::regs_decode *decode)
-{
- int32_t res;
- int64_t tmp;
-
- if( SRC_IS_SR )
- SREG = GET_C;
-
- tmp = (int64_t)((int32_t)(DREG)) - (int64_t)((int32_t)(SREG));
-
-//#ifdef SETCARRYS
-// CHECK_C(tmp);
-//#endif
-
- CHECK_VSUB(SREG,DREG,tmp);
-
- res = (int32_t)(DREG) - (int32_t)(SREG);
-
- SET_DREG(res);
-
- SET_Z( res == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(res) );
-
- m_icount -= m_clock_cycles_1;
-
- if( GET_V )
- {
- uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR);
- execute_exception(addr);
- }
-}
-
-void hyperstone_device::hyperstone_addc(struct hyperstone_device::regs_decode *decode)
-{
- uint64_t tmp;
-
- if( SRC_IS_SR )
- {
- tmp = (uint64_t)(DREG) + (uint64_t)(GET_C);
- CHECK_VADD(DREG,GET_C,tmp);
- }
- else
- {
- tmp = (uint64_t)(SREG) + (uint64_t)(DREG) + (uint64_t)(GET_C);
-
- //CHECK!
- //CHECK_VADD1: V = (DREG == 0x7FFF) && (C == 1);
- //OVERFLOW = CHECK_VADD1(DREG, C, DREG+C) | CHECK_VADD(SREG, DREG+C, SREG+DREG+C)
- /* check if DREG + GET_C overflows */
-// if( (DREG == 0x7FFFFFFF) && (GET_C == 1) )
-// SET_V(1);
-// else
-// CHECK_VADD(SREG,DREG + GET_C,tmp);
-
- CHECK_VADD3(SREG,DREG,GET_C,tmp);
- }
-
-
-
- if( SRC_IS_SR )
- DREG = DREG + GET_C;
- else
- DREG = SREG + DREG + GET_C;
-
- CHECK_C(tmp);
-
- SET_DREG(DREG);
- SET_Z( GET_Z & (DREG == 0 ? 1 : 0) );
- SET_N( SIGN_BIT(DREG) );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_and(struct hyperstone_device::regs_decode *decode)
-{
- DREG = DREG & SREG;
-
- SET_DREG(DREG);
- SET_Z( DREG == 0 ? 1 : 0 );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_neg(struct hyperstone_device::regs_decode *decode)
-{
- uint64_t tmp;
-
- if( SRC_IS_SR )
- SREG = GET_C;
-
- tmp = -(uint64_t)(SREG);
- CHECK_C(tmp);
- CHECK_VSUB(SREG,0,tmp);
-
- DREG = -SREG;
-
- SET_DREG(DREG);
-
- SET_Z( DREG == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(DREG) );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_negs(struct hyperstone_device::regs_decode *decode)
-{
- int32_t res;
- int64_t tmp;
-
- if( SRC_IS_SR )
- SREG = GET_C;
-
- tmp = -(int64_t)((int32_t)(SREG));
- CHECK_VSUB(SREG,0,tmp);
-
-//#if SETCARRYS
-// CHECK_C(tmp);
-//#endif
-
- res = -(int32_t)(SREG);
-
- SET_DREG(res);
-
- SET_Z( res == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(res) );
-
-
- m_icount -= m_clock_cycles_1;
-
- if( GET_V && !SRC_IS_SR ) //trap doesn't occur when source is SR
- {
- uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR);
- execute_exception(addr);
- }
-}
-
-void hyperstone_device::hyperstone_cmpi(struct hyperstone_device::regs_decode *decode)
-{
- uint64_t tmp;
-
- tmp = (uint64_t)(DREG) - (uint64_t)(EXTRA_U);
- CHECK_VSUB(EXTRA_U,DREG,tmp);
-
- if( DREG == EXTRA_U )
- SET_Z(1);
- else
- SET_Z(0);
-
- if( (int32_t) DREG < (int32_t) EXTRA_U )
- SET_N(1);
- else
- SET_N(0);
-
- if( DREG < EXTRA_U )
- SET_C(1);
- else
- SET_C(0);
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_movi(struct hyperstone_device::regs_decode *decode)
-{
- if( !GET_S && decode->dst >= 16 )
- {
- uint32_t addr = get_trap_addr(TRAPNO_PRIVILEGE_ERROR);
- execute_exception(addr);
- }
-
- SET_DREG(EXTRA_U);
-
- if( DST_IS_PC )
- SET_M(0);
-
- SET_Z( EXTRA_U == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(EXTRA_U) );
-
-#if MISSIONCRAFT_FLAGS
- SET_V(0); // or V undefined ?
-#endif
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_addi(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t imm;
- uint64_t tmp;
-
- if( N_VALUE )
- imm = EXTRA_U;
- else
- imm = GET_C & ((GET_Z == 0 ? 1 : 0) | (DREG & 0x01));
-
-
- tmp = (uint64_t)(imm) + (uint64_t)(DREG);
- CHECK_C(tmp);
- CHECK_VADD(imm,DREG,tmp);
-
- DREG = imm + DREG;
- SET_DREG(DREG);
-
- if( DST_IS_PC )
- SET_M(0);
-
- SET_Z( DREG == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(DREG) );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_addsi(struct hyperstone_device::regs_decode *decode)
-{
- int32_t imm, res;
- int64_t tmp;
-
- if( N_VALUE )
- imm = EXTRA_S;
- else
- imm = GET_C & ((GET_Z == 0 ? 1 : 0) | (DREG & 0x01));
-
- tmp = (int64_t)(imm) + (int64_t)((int32_t)(DREG));
- CHECK_VADD(imm,DREG,tmp);
-
-//#if SETCARRYS
-// CHECK_C(tmp);
-//#endif
-
- res = imm + (int32_t)(DREG);
-
- SET_DREG(res);
-
- SET_Z( res == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(res) );
-
- m_icount -= m_clock_cycles_1;
-
- if( GET_V )
- {
- uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR);
- execute_exception(addr);
- }
-}
-
-void hyperstone_device::hyperstone_cmpbi(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t imm;
-
- if( N_VALUE )
- {
- if( N_VALUE == 31 )
- {
- imm = 0x7fffffff; // bit 31 = 0, others = 1
- }
- else
- {
- imm = EXTRA_U;
- }
-
- SET_Z( (DREG & imm) == 0 ? 1 : 0 );
- }
- else
- {
- if( (DREG & 0xff000000) == 0 || (DREG & 0x00ff0000) == 0 ||
- (DREG & 0x0000ff00) == 0 || (DREG & 0x000000ff) == 0 )
- SET_Z(1);
- else
- SET_Z(0);
- }
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_andni(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t imm;
-
- if( N_VALUE == 31 )
- imm = 0x7fffffff; // bit 31 = 0, others = 1
- else
- imm = EXTRA_U;
-
- DREG = DREG & ~imm;
-
- SET_DREG(DREG);
- SET_Z( DREG == 0 ? 1 : 0 );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_ori(struct hyperstone_device::regs_decode *decode)
-{
- DREG = DREG | EXTRA_U;
-
- SET_DREG(DREG);
- SET_Z( DREG == 0 ? 1 : 0 );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_xori(struct hyperstone_device::regs_decode *decode)
-{
- DREG = DREG ^ EXTRA_U;
-
- SET_DREG(DREG);
- SET_Z( DREG == 0 ? 1 : 0 );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_shrdi(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t low_order, high_order;
- uint64_t val;
-
- high_order = DREG;
- low_order = DREGF;
-
- val = concat_64(high_order, low_order);
-
- if( N_VALUE )
- SET_C((val >> (N_VALUE - 1)) & 1);
- else
- SET_C(0);
-
- val >>= N_VALUE;
-
- high_order = extract_64hi(val);
- low_order = extract_64lo(val);
-
- SET_DREG(high_order);
- SET_DREGF(low_order);
- SET_Z( val == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(high_order) );
-
- m_icount -= m_clock_cycles_2;
-}
-
-void hyperstone_device::hyperstone_shrd(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t low_order, high_order;
- uint64_t val;
- uint8_t n = SREG & 0x1f;
-
- // result undefined if Ls denotes the same register as Ld or Ldf
- if( SAME_SRC_DST || SAME_SRC_DSTF )
- {
- DEBUG_PRINTF(("Denoted same registers in hyperstone_shrd. PC = %08X\n", PC));
- }
- else
- {
- high_order = DREG;
- low_order = DREGF;
-
- val = concat_64(high_order, low_order);
-
- if( n )
- SET_C((val >> (n - 1)) & 1);
- else
- SET_C(0);
-
- val >>= n;
-
- high_order = extract_64hi(val);
- low_order = extract_64lo(val);
-
- SET_DREG(high_order);
- SET_DREGF(low_order);
-
- SET_Z( val == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(high_order) );
- }
-
- m_icount -= m_clock_cycles_2;
-}
-
-void hyperstone_device::hyperstone_shr(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t ret;
- uint8_t n;
-
- n = SREG & 0x1f;
- ret = DREG;
-
- if( n )
- SET_C((ret >> (n - 1)) & 1);
- else
- SET_C(0);
-
- ret >>= n;
-
- SET_DREG(ret);
- SET_Z( ret == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(ret) );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_sardi(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t low_order, high_order;
- uint64_t val;
- uint8_t sign_bit;
-
- high_order = DREG;
- low_order = DREGF;
-
- val = concat_64(high_order, low_order);
-
- if( N_VALUE )
- SET_C((val >> (N_VALUE - 1)) & 1);
- else
- SET_C(0);
-
- sign_bit = val >> 63;
- val >>= N_VALUE;
-
- if( sign_bit )
- {
- int i;
- for( i = 0; i < N_VALUE; i++ )
- {
- val |= (0x8000000000000000U >> i);
- }
- }
-
- high_order = val >> 32;
- low_order = val & 0xffffffff;
-
- SET_DREG(high_order);
- SET_DREGF(low_order);
-
- SET_Z( val == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(high_order) );
-
- m_icount -= m_clock_cycles_2;
-}
-
-void hyperstone_device::hyperstone_sard(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t low_order, high_order;
- uint64_t val;
- uint8_t n, sign_bit;
-
- n = SREG & 0x1f;
-
- // result undefined if Ls denotes the same register as Ld or Ldf
- if( SAME_SRC_DST || SAME_SRC_DSTF )
- {
- DEBUG_PRINTF(("Denoted same registers in hyperstone_sard. PC = %08X\n", PC));
- }
- else
- {
- high_order = DREG;
- low_order = DREGF;
-
- val = concat_64(high_order, low_order);
-
- if( n )
- SET_C((val >> (n - 1)) & 1);
- else
- SET_C(0);
-
- sign_bit = val >> 63;
-
- val >>= n;
-
- if( sign_bit )
- {
- int i;
- for( i = 0; i < n; i++ )
- {
- val |= (0x8000000000000000U >> i);
- }
- }
-
- high_order = val >> 32;
- low_order = val & 0xffffffff;
-
- SET_DREG(high_order);
- SET_DREGF(low_order);
- SET_Z( val == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(high_order) );
- }
-
- m_icount -= m_clock_cycles_2;
-}
-
-void hyperstone_device::hyperstone_sar(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t ret;
- uint8_t n, sign_bit;
-
- n = SREG & 0x1f;
- ret = DREG;
- sign_bit = (ret & 0x80000000) >> 31;
-
- if( n )
- SET_C((ret >> (n - 1)) & 1);
- else
- SET_C(0);
-
- ret >>= n;
-
- if( sign_bit )
- {
- int i;
- for( i = 0; i < n; i++ )
- {
- ret |= (0x80000000 >> i);
- }
- }
-
- SET_DREG(ret);
- SET_Z( ret == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(ret) );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_shldi(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t low_order, high_order, tmp;
- uint64_t val, mask;
-
- high_order = DREG;
- low_order = DREGF;
-
- val = concat_64(high_order, low_order);
- SET_C( (N_VALUE)?(((val<<(N_VALUE-1))&0x8000000000000000U)?1:0):0);
- mask = ((((uint64_t)1) << (32 - N_VALUE)) - 1) ^ 0xffffffff;
- tmp = high_order << N_VALUE;
-
- if( ((high_order & mask) && (!(tmp & 0x80000000))) ||
- (((high_order & mask) ^ mask) && (tmp & 0x80000000)) )
- SET_V(1);
- else
- SET_V(0);
-
- val <<= N_VALUE;
-
- high_order = extract_64hi(val);
- low_order = extract_64lo(val);
-
- SET_DREG(high_order);
- SET_DREGF(low_order);
-
- SET_Z( val == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(high_order) );
-
- m_icount -= m_clock_cycles_2;
-}
-
-void hyperstone_device::hyperstone_shld(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t low_order, high_order, tmp, n;
- uint64_t val, mask;
-
- n = SREG & 0x1f;
-
- // result undefined if Ls denotes the same register as Ld or Ldf
- if( SAME_SRC_DST || SAME_SRC_DSTF )
- {
- DEBUG_PRINTF(("Denoted same registers in hyperstone_shld. PC = %08X\n", PC));
- }
- else
- {
- high_order = DREG;
- low_order = DREGF;
-
- mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff;
-
- val = concat_64(high_order, low_order);
- SET_C( (n)?(((val<<(n-1))&0x8000000000000000U)?1:0):0);
- tmp = high_order << n;
-
- if( ((high_order & mask) && (!(tmp & 0x80000000))) ||
- (((high_order & mask) ^ mask) && (tmp & 0x80000000)) )
- SET_V(1);
- else
- SET_V(0);
-
- val <<= n;
-
- high_order = extract_64hi(val);
- low_order = extract_64lo(val);
-
- SET_DREG(high_order);
- SET_DREGF(low_order);
-
- SET_Z( val == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(high_order) );
- }
-
- m_icount -= m_clock_cycles_2;
-}
-
-void hyperstone_device::hyperstone_shl(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t base, ret, n;
- uint64_t mask;
-
- n = SREG & 0x1f;
- base = DREG;
- mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff;
- SET_C( (n)?(((base<<(n-1))&0x80000000)?1:0):0);
- ret = base << n;
-
- if( ((base & mask) && (!(ret & 0x80000000))) ||
- (((base & mask) ^ mask) && (ret & 0x80000000)) )
- SET_V(1);
- else
- SET_V(0);
-
- SET_DREG(ret);
- SET_Z( ret == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(ret) );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::reserved(struct hyperstone_device::regs_decode *decode)
-{
- DEBUG_PRINTF(("Executed Reserved opcode. PC = %08X OP = %04X\n", PC, OP));
-}
-
-void hyperstone_device::hyperstone_testlz(struct hyperstone_device::regs_decode *decode)
-{
- uint8_t zeros = 0;
- uint32_t mask;
-
- for( mask = 0x80000000; ; mask >>= 1 )
- {
- if( SREG & mask )
- break;
- else
- zeros++;
-
- if( zeros == 32 )
- break;
- }
-
- SET_DREG(zeros);
-
- m_icount -= m_clock_cycles_2;
-}
-
-void hyperstone_device::hyperstone_rol(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t val, base;
- uint8_t n;
- uint64_t mask;
-
- n = SREG & 0x1f;
-
- val = base = DREG;
-
- mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff;
-
- while( n > 0 )
- {
- val = (val << 1) | ((val & 0x80000000) >> 31);
- n--;
- }
-
-#ifdef MISSIONCRAFT_FLAGS
-
- if( ((base & mask) && (!(val & 0x80000000))) ||
- (((base & mask) ^ mask) && (val & 0x80000000)) )
- SET_V(1);
- else
- SET_V(0);
-
-#endif
-
- SET_DREG(val);
-
- SET_Z( val == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(val) );
-
- m_icount -= m_clock_cycles_1;
-}
-
-//TODO: add trap error
-void hyperstone_device::hyperstone_ldxx1(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t load;
-
- if( DST_IS_SR )
- {
- switch( decode->sub_type )
- {
- case 0: // LDBS.A
-
- load = READ_B(EXTRA_S);
- load |= (load & 0x80) ? 0xffffff00 : 0;
- SET_SREG(load);
-
- break;
-
- case 1: // LDBU.A
-
- load = READ_B(EXTRA_S);
- SET_SREG(load);
-
- break;
-
- case 2:
-
- load = READ_HW(EXTRA_S);
-
- if( EXTRA_S & 1 ) // LDHS.A
- {
- load |= (load & 0x8000) ? 0xffff0000 : 0;
- }
- /*
- else // LDHU.A
- {
- // nothing more
- }
- */
-
- SET_SREG(load);
-
- break;
-
- case 3:
-
- if( (EXTRA_S & 3) == 3 ) // LDD.IOA
- {
- load = IO_READ_W(EXTRA_S & ~3);
- SET_SREG(load);
-
- load = IO_READ_W((EXTRA_S & ~3) + 4);
- SET_SREGF(load);
-
- m_icount -= m_clock_cycles_1; // extra cycle
- }
- else if( (EXTRA_S & 3) == 2 ) // LDW.IOA
- {
- load = IO_READ_W(EXTRA_S & ~3);
- SET_SREG(load);
- }
- else if( (EXTRA_S & 3) == 1 ) // LDD.A
- {
- load = READ_W(EXTRA_S & ~1);
- SET_SREG(load);
-
- load = READ_W((EXTRA_S & ~1) + 4);
- SET_SREGF(load);
-
- m_icount -= m_clock_cycles_1; // extra cycle
- }
- else // LDW.A
- {
- load = READ_W(EXTRA_S & ~1);
- SET_SREG(load);
- }
-
- break;
- }
- }
- else
- {
- switch( decode->sub_type )
- {
- case 0: // LDBS.D
-
- load = READ_B(DREG + EXTRA_S);
- load |= (load & 0x80) ? 0xffffff00 : 0;
- SET_SREG(load);
-
- break;
-
- case 1: // LDBU.D
-
- load = READ_B(DREG + EXTRA_S);
- SET_SREG(load);
-
- break;
-
- case 2:
-
- load = READ_HW(DREG + (EXTRA_S & ~1));
-
- if( EXTRA_S & 1 ) // LDHS.D
- {
- load |= (load & 0x8000) ? 0xffff0000 : 0;
- }
- /*
- else // LDHU.D
- {
- // nothing more
- }
- */
-
- SET_SREG(load);
-
- break;
-
- case 3:
-
- if( (EXTRA_S & 3) == 3 ) // LDD.IOD
- {
- load = IO_READ_W(DREG + (EXTRA_S & ~3));
- SET_SREG(load);
-
- load = IO_READ_W(DREG + (EXTRA_S & ~3) + 4);
- SET_SREGF(load);
-
- m_icount -= m_clock_cycles_1; // extra cycle
- }
- else if( (EXTRA_S & 3) == 2 ) // LDW.IOD
- {
- load = IO_READ_W(DREG + (EXTRA_S & ~3));
- SET_SREG(load);
- }
- else if( (EXTRA_S & 3) == 1 ) // LDD.D
- {
- load = READ_W(DREG + (EXTRA_S & ~1));
- SET_SREG(load);
-
- load = READ_W(DREG + (EXTRA_S & ~1) + 4);
- SET_SREGF(load);
-
- m_icount -= m_clock_cycles_1; // extra cycle
- }
- else // LDW.D
- {
- load = READ_W(DREG + (EXTRA_S & ~1));
- SET_SREG(load);
- }
-
- break;
- }
- }
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_ldxx2(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t load;
-
- if( DST_IS_PC || DST_IS_SR )
- {
- DEBUG_PRINTF(("Denoted PC or SR in hyperstone_ldxx2. PC = %08X\n", PC));
- }
- else
- {
- switch( decode->sub_type )
- {
- case 0: // LDBS.N
-
- if(SAME_SRC_DST)
- DEBUG_PRINTF(("LDBS.N denoted same regs @ %08X",PPC));
-
- load = READ_B(DREG);
- load |= (load & 0x80) ? 0xffffff00 : 0;
- SET_SREG(load);
-
- if(!SAME_SRC_DST)
- SET_DREG(DREG + EXTRA_S);
-
- break;
-
- case 1: // LDBU.N
-
- if(SAME_SRC_DST)
- DEBUG_PRINTF(("LDBU.N denoted same regs @ %08X",PPC));
-
- load = READ_B(DREG);
- SET_SREG(load);
-
- if(!SAME_SRC_DST)
- SET_DREG(DREG + EXTRA_S);
-
- break;
-
- case 2:
-
- load = READ_HW(DREG);
-
- if( EXTRA_S & 1 ) // LDHS.N
- {
- load |= (load & 0x8000) ? 0xffff0000 : 0;
-
- if(SAME_SRC_DST)
- DEBUG_PRINTF(("LDHS.N denoted same regs @ %08X",PPC));
- }
- /*
- else // LDHU.N
- {
- // nothing more
- }
- */
-
- SET_SREG(load);
-
- if(!SAME_SRC_DST)
- SET_DREG(DREG + (EXTRA_S & ~1));
-
- break;
-
- case 3:
-
- if( (EXTRA_S & 3) == 3 ) // LDW.S
- {
- if(SAME_SRC_DST)
- DEBUG_PRINTF(("LDW.S denoted same regs @ %08X",PPC));
-
- if(DREG < SP)
- SET_SREG(READ_W(DREG));
- else
- SET_SREG(GET_ABS_L_REG((DREG & 0xfc) >> 2));
-
- if(!SAME_SRC_DST)
- SET_DREG(DREG + (EXTRA_S & ~3));
-
- m_icount -= m_clock_cycles_2; // extra cycles
- }
- else if( (EXTRA_S & 3) == 2 ) // Reserved
- {
- DEBUG_PRINTF(("Executed Reserved instruction in hyperstone_ldxx2. PC = %08X\n", PC));
- }
- else if( (EXTRA_S & 3) == 1 ) // LDD.N
- {
- if(SAME_SRC_DST || SAME_SRCF_DST)
- DEBUG_PRINTF(("LDD.N denoted same regs @ %08X",PPC));
-
- load = READ_W(DREG);
- SET_SREG(load);
-
- load = READ_W(DREG + 4);
- SET_SREGF(load);
-
- if(!SAME_SRC_DST && !SAME_SRCF_DST)
- SET_DREG(DREG + (EXTRA_S & ~1));
-
- m_icount -= m_clock_cycles_1; // extra cycle
- }
- else // LDW.N
- {
- if(SAME_SRC_DST)
- DEBUG_PRINTF(("LDW.N denoted same regs @ %08X",PPC));
-
- load = READ_W(DREG);
- SET_SREG(load);
-
- if(!SAME_SRC_DST)
- SET_DREG(DREG + (EXTRA_S & ~1));
- }
-
- break;
- }
- }
-
- m_icount -= m_clock_cycles_1;
-}
-
-//TODO: add trap error
-void hyperstone_device::hyperstone_stxx1(struct hyperstone_device::regs_decode *decode)
-{
- if( SRC_IS_SR )
- SREG = SREGF = 0;
-
- if( DST_IS_SR )
- {
- switch( decode->sub_type )
- {
- case 0: // STBS.A
-
- /* TODO: missing trap on range error */
- WRITE_B(EXTRA_S, SREG & 0xff);
-
- break;
-
- case 1: // STBU.A
-
- WRITE_B(EXTRA_S, SREG & 0xff);
-
- break;
-
- case 2:
-
- WRITE_HW(EXTRA_S, SREG & 0xffff);
-
- /*
- if( EXTRA_S & 1 ) // STHS.A
- {
- // TODO: missing trap on range error
- }
- else // STHU.A
- {
- // nothing more
- }
- */
-
- break;
-
- case 3:
-
- if( (EXTRA_S & 3) == 3 ) // STD.IOA
- {
- IO_WRITE_W(EXTRA_S & ~3, SREG);
- IO_WRITE_W((EXTRA_S & ~3) + 4, SREGF);
-
- m_icount -= m_clock_cycles_1; // extra cycle
- }
- else if( (EXTRA_S & 3) == 2 ) // STW.IOA
- {
- IO_WRITE_W(EXTRA_S & ~3, SREG);
- }
- else if( (EXTRA_S & 3) == 1 ) // STD.A
- {
- WRITE_W(EXTRA_S & ~1, SREG);
- WRITE_W((EXTRA_S & ~1) + 4, SREGF);
-
- m_icount -= m_clock_cycles_1; // extra cycle
- }
- else // STW.A
- {
- WRITE_W(EXTRA_S & ~1, SREG);
- }
-
- break;
- }
- }
- else
- {
- switch( decode->sub_type )
- {
- case 0: // STBS.D
-
- /* TODO: missing trap on range error */
- WRITE_B(DREG + EXTRA_S, SREG & 0xff);
-
- break;
-
- case 1: // STBU.D
-
- WRITE_B(DREG + EXTRA_S, SREG & 0xff);
-
- break;
-
- case 2:
-
- WRITE_HW(DREG + (EXTRA_S & ~1), SREG & 0xffff);
-
- /*
- if( EXTRA_S & 1 ) // STHS.D
- {
- // TODO: missing trap on range error
- }
- else // STHU.D
- {
- // nothing more
- }
- */
-
- break;
-
- case 3:
-
- if( (EXTRA_S & 3) == 3 ) // STD.IOD
- {
- IO_WRITE_W(DREG + (EXTRA_S & ~3), SREG);
- IO_WRITE_W(DREG + (EXTRA_S & ~3) + 4, SREGF);
-
- m_icount -= m_clock_cycles_1; // extra cycle
- }
- else if( (EXTRA_S & 3) == 2 ) // STW.IOD
- {
- IO_WRITE_W(DREG + (EXTRA_S & ~3), SREG);
- }
- else if( (EXTRA_S & 3) == 1 ) // STD.D
- {
- WRITE_W(DREG + (EXTRA_S & ~1), SREG);
- WRITE_W(DREG + (EXTRA_S & ~1) + 4, SREGF);
-
- m_icount -= m_clock_cycles_1; // extra cycle
- }
- else // STW.D
- {
- WRITE_W(DREG + (EXTRA_S & ~1), SREG);
- }
-
- break;
- }
- }
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_stxx2(struct hyperstone_device::regs_decode *decode)
-{
- if( SRC_IS_SR )
- SREG = SREGF = 0;
-
- if( DST_IS_PC || DST_IS_SR )
- {
- DEBUG_PRINTF(("Denoted PC or SR in hyperstone_stxx2. PC = %08X\n", PC));
- }
- else
- {
- switch( decode->sub_type )
- {
- case 0: // STBS.N
-
- /* TODO: missing trap on range error */
- WRITE_B(DREG, SREG & 0xff);
- SET_DREG(DREG + EXTRA_S);
-
- break;
-
- case 1: // STBU.N
-
- WRITE_B(DREG, SREG & 0xff);
- SET_DREG(DREG + EXTRA_S);
-
- break;
-
- case 2:
-
- WRITE_HW(DREG, SREG & 0xffff);
- SET_DREG(DREG + (EXTRA_S & ~1));
-
- /*
- if( EXTRA_S & 1 ) // STHS.N
- {
- // TODO: missing trap on range error
- }
- else // STHU.N
- {
- // nothing more
- }
- */
-
- break;
-
- case 3:
-
- if( (EXTRA_S & 3) == 3 ) // STW.S
- {
- if(DREG < SP)
- WRITE_W(DREG, SREG);
- else
- {
- if(((DREG & 0xfc) >> 2) == ((decode->src + GET_FP) % 64) && S_BIT == LOCAL)
- DEBUG_PRINTF(("STW.S denoted the same local register @ %08X\n",PPC));
-
- SET_ABS_L_REG((DREG & 0xfc) >> 2,SREG);
- }
-
- SET_DREG(DREG + (EXTRA_S & ~3));
-
- m_icount -= m_clock_cycles_2; // extra cycles
-
- }
- else if( (EXTRA_S & 3) == 2 ) // Reserved
- {
- DEBUG_PRINTF(("Executed Reserved instruction in hyperstone_stxx2. PC = %08X\n", PC));
- }
- else if( (EXTRA_S & 3) == 1 ) // STD.N
- {
- WRITE_W(DREG, SREG);
- SET_DREG(DREG + (EXTRA_S & ~1));
-
- if( SAME_SRCF_DST )
- WRITE_W(DREG + 4, SREGF + (EXTRA_S & ~1)); // because DREG == SREGF and DREG has been incremented
- else
- WRITE_W(DREG + 4, SREGF);
-
- m_icount -= m_clock_cycles_1; // extra cycle
- }
- else // STW.N
- {
- WRITE_W(DREG, SREG);
- SET_DREG(DREG + (EXTRA_S & ~1));
- }
-
- break;
- }
- }
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_shri(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t val;
-
- val = DREG;
-
- if( N_VALUE )
- SET_C((val >> (N_VALUE - 1)) & 1);
- else
- SET_C(0);
-
- val >>= N_VALUE;
-
- SET_DREG(val);
- SET_Z( val == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(val) );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_sari(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t val;
- uint8_t sign_bit;
-
- val = DREG;
- sign_bit = (val & 0x80000000) >> 31;
-
- if( N_VALUE )
- SET_C((val >> (N_VALUE - 1)) & 1);
- else
- SET_C(0);
-
- val >>= N_VALUE;
-
- if( sign_bit )
- {
- int i;
- for( i = 0; i < N_VALUE; i++ )
- {
- val |= (0x80000000 >> i);
- }
- }
-
- SET_DREG(val);
- SET_Z( val == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(val) );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_shli(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t val, val2;
- uint64_t mask;
-
- val = DREG;
- SET_C( (N_VALUE)?(((val<<(N_VALUE-1))&0x80000000)?1:0):0);
- mask = ((((uint64_t)1) << (32 - N_VALUE)) - 1) ^ 0xffffffff;
- val2 = val << N_VALUE;
-
- if( ((val & mask) && (!(val2 & 0x80000000))) ||
- (((val & mask) ^ mask) && (val2 & 0x80000000)) )
- SET_V(1);
- else
- SET_V(0);
-
- SET_DREG(val2);
- SET_Z( val2 == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(val2) );
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_mulu(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t low_order, high_order;
- uint64_t double_word;
-
- // PC or SR aren't denoted, else result is undefined
- if( SRC_IS_PC || SRC_IS_SR || DST_IS_PC || DST_IS_SR )
- {
- DEBUG_PRINTF(("Denoted PC or SR in hyperstone_mulu instruction. PC = %08X\n", PC));
- }
- else
- {
- double_word = (uint64_t)SREG *(uint64_t)DREG;
-
- low_order = double_word & 0xffffffff;
- high_order = double_word >> 32;
-
- SET_DREG(high_order);
- SET_DREGF(low_order);
-
- SET_Z( double_word == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(high_order) );
- }
-
- if(SREG <= 0xffff && DREG <= 0xffff)
- m_icount -= m_clock_cycles_4;
- else
- m_icount -= m_clock_cycles_6;
-}
-
-void hyperstone_device::hyperstone_muls(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t low_order, high_order;
- int64_t double_word;
-
- // PC or SR aren't denoted, else result is undefined
- if( SRC_IS_PC || SRC_IS_SR || DST_IS_PC || DST_IS_SR )
- {
- DEBUG_PRINTF(("Denoted PC or SR in hyperstone_muls instruction. PC = %08X\n", PC));
- }
- else
- {
- double_word = (int64_t)(int32_t)(SREG) * (int64_t)(int32_t)(DREG);
- low_order = double_word & 0xffffffff;
- high_order = double_word >> 32;
-
- SET_DREG(high_order);
- SET_DREGF(low_order);
-
- SET_Z( double_word == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(high_order) );
- }
-
- if((SREG >= 0xffff8000 && SREG <= 0x7fff) && (DREG >= 0xffff8000 && DREG <= 0x7fff))
- m_icount -= m_clock_cycles_4;
- else
- m_icount -= m_clock_cycles_6;
-}
-
-void hyperstone_device::hyperstone_set(struct hyperstone_device::regs_decode *decode)
-{
- int n = N_VALUE;
-
- if( DST_IS_PC )
- {
- DEBUG_PRINTF(("Denoted PC in hyperstone_set. PC = %08X\n", PC));
- }
- else if( DST_IS_SR )
- {
- //TODO: add fetch opcode when there's the pipeline
-
- //TODO: no 1!
- m_icount -= m_clock_cycles_1;
- }
- else
- {
- switch( n )
- {
- // SETADR
- case 0:
- {
- uint32_t val;
- val = (SP & 0xfffffe00) | (GET_FP << 2);
-
- //plus carry into bit 9
- val += (( (SP & 0x100) && (SIGN_BIT(SR) == 0) ) ? 1 : 0);
-
- SET_DREG(val);
-
- break;
- }
- // Reserved
- case 1:
- case 16:
- case 17:
- case 19:
- DEBUG_PRINTF(("Used reserved N value (%d) in hyperstone_set. PC = %08X\n", n, PC));
- break;
-
- // SETxx
- case 2:
- SET_DREG(1);
- break;
-
- case 3:
- SET_DREG(0);
- break;
-
- case 4:
- if( GET_N || GET_Z )
- {
- SET_DREG(1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 5:
- if( !GET_N && !GET_Z )
- {
- SET_DREG(1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 6:
- if( GET_N )
- {
- SET_DREG(1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 7:
- if( !GET_N )
- {
- SET_DREG(1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 8:
- if( GET_C || GET_Z )
- {
- SET_DREG(1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 9:
- if( !GET_C && !GET_Z )
- {
- SET_DREG(1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 10:
- if( GET_C )
- {
- SET_DREG(1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 11:
- if( !GET_C )
- {
- SET_DREG(1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 12:
- if( GET_Z )
- {
- SET_DREG(1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 13:
- if( !GET_Z )
- {
- SET_DREG(1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 14:
- if( GET_V )
- {
- SET_DREG(1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 15:
- if( !GET_V )
- {
- SET_DREG(1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 18:
- SET_DREG(-1);
- break;
-
- case 20:
- if( GET_N || GET_Z )
- {
- SET_DREG(-1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 21:
- if( !GET_N && !GET_Z )
- {
- SET_DREG(-1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 22:
- if( GET_N )
- {
- SET_DREG(-1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 23:
- if( !GET_N )
- {
- SET_DREG(-1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 24:
- if( GET_C || GET_Z )
- {
- SET_DREG(-1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 25:
- if( !GET_C && !GET_Z )
- {
- SET_DREG(-1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 26:
- if( GET_C )
- {
- SET_DREG(-1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 27:
- if( !GET_C )
- {
- SET_DREG(-1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 28:
- if( GET_Z )
- {
- SET_DREG(-1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 29:
- if( !GET_Z )
- {
- SET_DREG(-1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 30:
- if( GET_V )
- {
- SET_DREG(-1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
-
- case 31:
- if( !GET_V )
- {
- SET_DREG(-1);
- }
- else
- {
- SET_DREG(0);
- }
-
- break;
- }
-
- m_icount -= m_clock_cycles_1;
- }
-}
-
-void hyperstone_device::hyperstone_mul(struct hyperstone_device::regs_decode *decode)
-{
- uint32_t single_word;
-
- // PC or SR aren't denoted, else result is undefined
- if( SRC_IS_PC || SRC_IS_SR || DST_IS_PC || DST_IS_SR )
- {
- DEBUG_PRINTF(("Denoted PC or SR in hyperstone_mul instruction. PC = %08X\n", PC));
- }
- else
- {
- single_word = (SREG * DREG);// & 0xffffffff; // only the low-order word is taken
-
- SET_DREG(single_word);
-
- SET_Z( single_word == 0 ? 1 : 0 );
- SET_N( SIGN_BIT(single_word) );
- }
-
- if((SREG >= 0xffff8000 && SREG <= 0x7fff) && (DREG >= 0xffff8000 && DREG <= 0x7fff))
- m_icount -= 3 << m_clck_scale;
- else
- m_icount -= 5 << m_clck_scale;
-}
-
-void hyperstone_device::hyperstone_fadd(struct hyperstone_device::regs_decode *decode)
-{
- execute_software(decode);
- m_icount -= m_clock_cycles_6;
-}
-
-void hyperstone_device::hyperstone_faddd(struct hyperstone_device::regs_decode *decode)
-{
- execute_software(decode);
- m_icount -= m_clock_cycles_6;
-}
-
-void hyperstone_device::hyperstone_fsub(struct hyperstone_device::regs_decode *decode)
-{
- execute_software(decode);
- m_icount -= m_clock_cycles_6;
-}
-
-void hyperstone_device::hyperstone_fsubd(struct hyperstone_device::regs_decode *decode)
-{
- execute_software(decode);
- m_icount -= m_clock_cycles_6;
-}
-
-void hyperstone_device::hyperstone_fmul(struct hyperstone_device::regs_decode *decode)
-{
- execute_software(decode);
- m_icount -= m_clock_cycles_6;
-}
-
-void hyperstone_device::hyperstone_fmuld(struct hyperstone_device::regs_decode *decode)
-{
- execute_software(decode);
- m_icount -= m_clock_cycles_6;
-}
-
-void hyperstone_device::hyperstone_fdiv(struct hyperstone_device::regs_decode *decode)
-{
- execute_software(decode);
- m_icount -= m_clock_cycles_6;
-}
-
-void hyperstone_device::hyperstone_fdivd(struct hyperstone_device::regs_decode *decode)
-{
- execute_software(decode);
- m_icount -= m_clock_cycles_6;
-}
-
-void hyperstone_device::hyperstone_fcmp(struct hyperstone_device::regs_decode *decode)
-{
- execute_software(decode);
- m_icount -= m_clock_cycles_6;
-}
-
-void hyperstone_device::hyperstone_fcmpd(struct hyperstone_device::regs_decode *decode)
-{
- execute_software(decode);
- m_icount -= m_clock_cycles_6;
-}
-
-void hyperstone_device::hyperstone_fcmpu(struct hyperstone_device::regs_decode *decode)
-{
- execute_software(decode);
- m_icount -= m_clock_cycles_6;
-}
-
-void hyperstone_device::hyperstone_fcmpud(struct hyperstone_device::regs_decode *decode)
-{
- execute_software(decode);
- m_icount -= m_clock_cycles_6;
-}
-
-void hyperstone_device::hyperstone_fcvt(struct hyperstone_device::regs_decode *decode)
-{
- execute_software(decode);
- m_icount -= m_clock_cycles_6;
-}
-
-void hyperstone_device::hyperstone_fcvtd(struct hyperstone_device::regs_decode *decode)
-{
- execute_software(decode);
- m_icount -= m_clock_cycles_6;
-}
-
-void hyperstone_device::hyperstone_extend(struct hyperstone_device::regs_decode *decode)
-{
- //TODO: add locks, overflow error and other things
- uint32_t vals, vald;
-
- vals = SREG;
- vald = DREG;
-
- switch( EXTRA_U ) // extended opcode
- {
- // signed or unsigned multiplication, single word product
- case EMUL:
- case 0x100: // used in "N" type cpu
- {
- uint32_t result;
-
- result = vals * vald;
- SET_G_REG(15, result);
-
- break;
- }
- // unsigned multiplication, double word product
- case EMULU:
- {
- uint64_t result;
-
- result = (uint64_t)vals * (uint64_t)vald;
- vals = result >> 32;
- vald = result & 0xffffffff;
- SET_G_REG(14, vals);
- SET_G_REG(15, vald);
-
- break;
- }
- // signed multiplication, double word product
- case EMULS:
- {
- int64_t result;
-
- result = (int64_t)(int32_t)(vals) * (int64_t)(int32_t)(vald);
- vals = result >> 32;
- vald = result & 0xffffffff;
- SET_G_REG(14, vals);
- SET_G_REG(15, vald);
-
- break;
- }
- // signed multiply/add, single word product sum
- case EMAC:
- {
- int32_t result;
-
- result = (int32_t)GET_G_REG(15) + ((int32_t)(vals) * (int32_t)(vald));
- SET_G_REG(15, result);
-
- break;
- }
- // signed multiply/add, double word product sum
- case EMACD:
- {
- int64_t result;
-
- result = (int64_t)concat_64(GET_G_REG(14), GET_G_REG(15)) + (int64_t)((int64_t)(int32_t)(vals) * (int64_t)(int32_t)(vald));
-
- vals = result >> 32;
- vald = result & 0xffffffff;
- SET_G_REG(14, vals);
- SET_G_REG(15, vald);
-
- break;
- }
- // signed multiply/substract, single word product difference
- case EMSUB:
- {
- int32_t result;
-
- result = (int32_t)GET_G_REG(15) - ((int32_t)(vals) * (int32_t)(vald));
- SET_G_REG(15, result);
-
- break;
- }
- // signed multiply/substract, double word product difference
- case EMSUBD:
- {
- int64_t result;
-
- result = (int64_t)concat_64(GET_G_REG(14), GET_G_REG(15)) - (int64_t)((int64_t)(int32_t)(vals) * (int64_t)(int32_t)(vald));
-
- vals = result >> 32;
- vald = result & 0xffffffff;
- SET_G_REG(14, vals);
- SET_G_REG(15, vald);
-
- break;
- }
- // signed half-word multiply/add, single word product sum
- case EHMAC:
- {
- int32_t result;
-
- result = (int32_t)GET_G_REG(15) + ((int32_t)((vald & 0xffff0000) >> 16) * (int32_t)((vals & 0xffff0000) >> 16)) + ((int32_t)(vald & 0xffff) * (int32_t)(vals & 0xffff));
- SET_G_REG(15, result);
-
- break;
- }
- // signed half-word multiply/add, double word product sum
- case EHMACD:
- {
- int64_t result;
-
- result = (int64_t)concat_64(GET_G_REG(14), GET_G_REG(15)) + (int64_t)((int64_t)(int32_t)((vald & 0xffff0000) >> 16) * (int64_t)(int32_t)((vals & 0xffff0000) >> 16)) + ((int64_t)(int32_t)(vald & 0xffff) * (int64_t)(int32_t)(vals & 0xffff));
-
- vals = result >> 32;
- vald = result & 0xffffffff;
- SET_G_REG(14, vals);
- SET_G_REG(15, vald);
-
- break;
- }
- // half-word complex multiply
- case EHCMULD:
- {
- uint32_t result;
-
- result = (((vald & 0xffff0000) >> 16) * ((vals & 0xffff0000) >> 16)) - ((vald & 0xffff) * (vals & 0xffff));
- SET_G_REG(14, result);
-
- result = (((vald & 0xffff0000) >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * ((vals & 0xffff0000) >> 16));
- SET_G_REG(15, result);
-
- break;
- }
- // half-word complex multiply/add
- case EHCMACD:
- {
- uint32_t result;
-
- result = GET_G_REG(14) + (((vald & 0xffff0000) >> 16) * ((vals & 0xffff0000) >> 16)) - ((vald & 0xffff) * (vals & 0xffff));
- SET_G_REG(14, result);
-
- result = GET_G_REG(15) + (((vald & 0xffff0000) >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * ((vals & 0xffff0000) >> 16));
- SET_G_REG(15, result);
-
- break;
- }
- // half-word (complex) add/substract
- // Ls is not used and should denote the same register as Ld
- case EHCSUMD:
- {
- uint32_t result;
-
- result = ((((vals & 0xffff0000) >> 16) + GET_G_REG(14)) << 16) & 0xffff0000;
- result |= ((vals & 0xffff) + GET_G_REG(15)) & 0xffff;
- SET_G_REG(14, result);
-
- result = ((((vals & 0xffff0000) >> 16) - GET_G_REG(14)) << 16) & 0xffff0000;
- result |= ((vals & 0xffff) - GET_G_REG(15)) & 0xffff;
- SET_G_REG(15, result);
-
- break;
- }
- // half-word (complex) add/substract with fixed point adjustment
- // Ls is not used and should denote the same register as Ld
- case EHCFFTD:
- {
- uint32_t result;
-
- result = ((((vals & 0xffff0000) >> 16) + (GET_G_REG(14) >> 15)) << 16) & 0xffff0000;
- result |= ((vals & 0xffff) + (GET_G_REG(15) >> 15)) & 0xffff;
- SET_G_REG(14, result);
-
- result = ((((vals & 0xffff0000) >> 16) - (GET_G_REG(14) >> 15)) << 16) & 0xffff0000;
- result |= ((vals & 0xffff) - (GET_G_REG(15) >> 15)) & 0xffff;
- SET_G_REG(15, result);
-
- break;
- }
- // half-word (complex) add/substract with fixed point adjustment and shift
- // Ls is not used and should denote the same register as Ld
- case EHCFFTSD:
- {
- uint32_t result;
-
- result = (((((vals & 0xffff0000) >> 16) + (GET_G_REG(14) >> 15)) >> 1) << 16) & 0xffff0000;
- result |= ((((vals & 0xffff) + (GET_G_REG(15) >> 15)) >> 1) & 0xffff);
- SET_G_REG(14, result);
-
- result = (((((vals & 0xffff0000) >> 16) - (GET_G_REG(14) >> 15)) >> 1) << 16) & 0xffff0000;
- result |= ((((vals & 0xffff) - (GET_G_REG(15) >> 15)) >> 1) & 0xffff);
- SET_G_REG(15, result);
-
- break;
- }
- default:
- DEBUG_PRINTF(("Executed Illegal extended opcode (%X). PC = %08X\n", EXTRA_U, PC));
- break;
- }
-
- m_icount -= m_clock_cycles_1; //TODO: with the latency it can change
-}
-
-void hyperstone_device::hyperstone_do(struct hyperstone_device::regs_decode *decode)
-{
- fatalerror("Executed hyperstone_do instruction. PC = %08X\n", PPC);
-}
-
-void hyperstone_device::hyperstone_ldwr(struct hyperstone_device::regs_decode *decode)
-{
- SET_SREG(READ_W(DREG));
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_lddr(struct hyperstone_device::regs_decode *decode)
-{
- SET_SREG(READ_W(DREG));
- SET_SREGF(READ_W(DREG + 4));
-
- m_icount -= m_clock_cycles_2;
-}
-
-void hyperstone_device::hyperstone_ldwp(struct hyperstone_device::regs_decode *decode)
-{
- SET_SREG(READ_W(DREG));
-
- // post increment the destination register if it's different from the source one
- // (needed by Hidden Catch)
- if(!(decode->src == decode->dst && S_BIT == LOCAL))
- SET_DREG(DREG + 4);
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_lddp(struct hyperstone_device::regs_decode *decode)
-{
- SET_SREG(READ_W(DREG));
- SET_SREGF(READ_W(DREG + 4));
-
- // post increment the destination register if it's different from the source one
- // and from the "next source" one
- if(!(decode->src == decode->dst && S_BIT == LOCAL) && !SAME_SRCF_DST )
- {
- SET_DREG(DREG + 8);
- }
- else
- {
- DEBUG_PRINTF(("LDD.P denoted same regs @ %08X",PPC));
- }
-
- m_icount -= m_clock_cycles_2;
-}
-
-void hyperstone_device::hyperstone_stwr(struct hyperstone_device::regs_decode *decode)
-{
- if( SRC_IS_SR )
- SREG = 0;
-
- WRITE_W(DREG, SREG);
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_stdr(struct hyperstone_device::regs_decode *decode)
-{
- if( SRC_IS_SR )
- SREG = SREGF = 0;
-
- WRITE_W(DREG, SREG);
- WRITE_W(DREG + 4, SREGF);
-
- m_icount -= m_clock_cycles_2;
-}
-
-void hyperstone_device::hyperstone_stwp(struct hyperstone_device::regs_decode *decode)
-{
- if( SRC_IS_SR )
- SREG = 0;
-
- WRITE_W(DREG, SREG);
- SET_DREG(DREG + 4);
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_stdp(struct hyperstone_device::regs_decode *decode)
-{
- if( SRC_IS_SR )
- SREG = SREGF = 0;
-
- WRITE_W(DREG, SREG);
- SET_DREG(DREG + 8);
-
- if( SAME_SRCF_DST )
- WRITE_W(DREG + 4, SREGF + 8); // because DREG == SREGF and DREG has been incremented
- else
- WRITE_W(DREG + 4, SREGF);
-
- m_icount -= m_clock_cycles_2;
-}
-
-void hyperstone_device::hyperstone_dbv(struct hyperstone_device::regs_decode *decode)
-{
- if( GET_V )
- execute_dbr(decode);
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_dbnv(struct hyperstone_device::regs_decode *decode)
-{
- if( !GET_V )
- execute_dbr(decode);
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_dbe(struct hyperstone_device::regs_decode *decode) //or DBZ
-{
- if( GET_Z )
- execute_dbr(decode);
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_dbne(struct hyperstone_device::regs_decode *decode) //or DBNZ
-{
- if( !GET_Z )
- execute_dbr(decode);
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_dbc(struct hyperstone_device::regs_decode *decode) //or DBST
-{
- if( GET_C )
- execute_dbr(decode);
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_dbnc(struct hyperstone_device::regs_decode *decode) //or DBHE
-{
- if( !GET_C )
- execute_dbr(decode);
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_dbse(struct hyperstone_device::regs_decode *decode)
-{
- if( GET_C || GET_Z )
- execute_dbr(decode);
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_dbht(struct hyperstone_device::regs_decode *decode)
-{
- if( !GET_C && !GET_Z )
- execute_dbr(decode);
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_dbn(struct hyperstone_device::regs_decode *decode) //or DBLT
-{
- if( GET_N )
- execute_dbr(decode);
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_dbnn(struct hyperstone_device::regs_decode *decode) //or DBGE
-{
- if( !GET_N )
- execute_dbr(decode);
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_dble(struct hyperstone_device::regs_decode *decode)
-{
- if( GET_N || GET_Z )
- execute_dbr(decode);
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_dbgt(struct hyperstone_device::regs_decode *decode)
-{
- if( !GET_N && !GET_Z )
- execute_dbr(decode);
-
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_dbr(struct hyperstone_device::regs_decode *decode)
-{
- execute_dbr(decode);
-}
-
-void hyperstone_device::hyperstone_frame(struct hyperstone_device::regs_decode *decode)
-{
- int8_t difference; // really it's 7 bits
- uint8_t realfp = GET_FP - SRC_CODE;
-
- SET_FP(realfp);
- SET_FL(DST_CODE);
- SET_M(0);
-
- difference = ((SP & 0x1fc) >> 2) + (64 - 10) - (realfp + GET_FL);
-
- /* convert to 8 bits */
- if(difference > 63)
- difference = (int8_t)(difference|0x80);
- else if( difference < -64 )
- difference = difference & 0x7f;
-
- if( difference < 0 ) // else it's finished
- {
- uint8_t tmp_flag;
-
- tmp_flag = ( SP >= UB ? 1 : 0 );
-
- do
- {
- WRITE_W(SP, GET_ABS_L_REG((SP & 0xfc) >> 2));
- SP += 4;
- difference++;
-
- } while(difference != 0);
-
- if( tmp_flag )
- {
- uint32_t addr = get_trap_addr(TRAPNO_FRAME_ERROR);
- execute_exception(addr);
- }
- }
-
- //TODO: no 1!
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_call(struct hyperstone_device::regs_decode *decode)
-{
- if( SRC_IS_SR )
- SREG = 0;
-
- if( !DST_CODE )
- decode->dst = 16;
-
- EXTRA_S = (EXTRA_S & ~1) + SREG;
-
- SET_ILC(m_instruction_length & 3);
-
- SET_DREG((PC & 0xfffffffe) | GET_S);
- SET_DREGF(SR);
-
- SET_FP(GET_FP + decode->dst);
-
- SET_FL(6); //default value for call
- SET_M(0);
-
- PPC = PC;
- PC = EXTRA_S; // const value
-
- m_intblock = 2;
-
- //TODO: add interrupt locks, errors, ....
-
- //TODO: no 1!
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_bv(struct hyperstone_device::regs_decode *decode)
-{
- if( GET_V )
- execute_br(decode);
- else
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_bnv(struct hyperstone_device::regs_decode *decode)
-{
- if( !GET_V )
- execute_br(decode);
- else
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_be(struct hyperstone_device::regs_decode *decode) //or BZ
-{
- if( GET_Z )
- execute_br(decode);
- else
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_bne(struct hyperstone_device::regs_decode *decode) //or BNZ
-{
- if( !GET_Z )
- execute_br(decode);
- else
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_bc(struct hyperstone_device::regs_decode *decode) //or BST
-{
- if( GET_C )
- execute_br(decode);
- else
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_bnc(struct hyperstone_device::regs_decode *decode) //or BHE
-{
- if( !GET_C )
- execute_br(decode);
- else
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_bse(struct hyperstone_device::regs_decode *decode)
-{
- if( GET_C || GET_Z )
- execute_br(decode);
- else
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_bht(struct hyperstone_device::regs_decode *decode)
-{
- if( !GET_C && !GET_Z )
- execute_br(decode);
- else
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_bn(struct hyperstone_device::regs_decode *decode) //or BLT
-{
- if( GET_N )
- execute_br(decode);
- else
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_bnn(struct hyperstone_device::regs_decode *decode) //or BGE
-{
- if( !GET_N )
- execute_br(decode);
- else
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_ble(struct hyperstone_device::regs_decode *decode)
-{
- if( GET_N || GET_Z )
- execute_br(decode);
- else
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_bgt(struct hyperstone_device::regs_decode *decode)
-{
- if( !GET_N && !GET_Z )
- execute_br(decode);
- else
- m_icount -= m_clock_cycles_1;
-}
-
-void hyperstone_device::hyperstone_br(struct hyperstone_device::regs_decode *decode)
-{
- execute_br(decode);
-}
-
-void hyperstone_device::hyperstone_trap(struct hyperstone_device::regs_decode *decode)
-{
- uint8_t code, trapno;
- uint32_t addr;
-
- trapno = (OP & 0xfc) >> 2;
-
- addr = get_trap_addr(trapno);
- code = ((OP & 0x300) >> 6) | (OP & 0x03);
-
- switch( code )
+ switch (code)
{
case TRAPLE:
- if( GET_N || GET_Z )
+ if (SR & (N_MASK | Z_MASK))
execute_trap(addr);
-
break;
case TRAPGT:
- if( !GET_N && !GET_Z )
+ if(!(SR & (N_MASK | Z_MASK)))
execute_trap(addr);
-
break;
case TRAPLT:
- if( GET_N )
+ if (SR & N_MASK)
execute_trap(addr);
-
break;
case TRAPGE:
- if( !GET_N )
+ if (!(SR & N_MASK))
execute_trap(addr);
-
break;
case TRAPSE:
- if( GET_C || GET_Z )
+ if (SR & (C_MASK | Z_MASK))
execute_trap(addr);
-
break;
case TRAPHT:
- if( !GET_C && !GET_Z )
+ if (!(SR & (C_MASK | Z_MASK)))
execute_trap(addr);
-
break;
case TRAPST:
- if( GET_C )
+ if (SR & C_MASK)
execute_trap(addr);
-
break;
case TRAPHE:
- if( !GET_C )
+ if (!(SR & C_MASK))
execute_trap(addr);
-
break;
case TRAPE:
- if( GET_Z )
+ if (SR & Z_MASK)
execute_trap(addr);
-
break;
case TRAPNE:
- if( !GET_Z )
+ if (!(SR & Z_MASK))
execute_trap(addr);
-
break;
case TRAPV:
- if( GET_V )
+ if (SR & V_MASK)
execute_trap(addr);
-
break;
case TRAP:
execute_trap(addr);
-
break;
}
@@ -4967,6 +1482,15 @@ void hyperstone_device::execute_set_input(int inputnum, int state)
ISR &= ~(1 << inputnum);
}
+void hyperstone_device::hyperstone_reserved()
+{
+ LOG("Executed Reserved opcode. PC = %08X OP = %04X\n", PC, OP);
+}
+
+void hyperstone_device::hyperstone_do()
+{
+ fatalerror("Executed hyperstone_do instruction. PC = %08X\n", PC-4);
+}
//-------------------------------------------------
// execute_run - execute a timeslice's worth of
@@ -4984,23 +1508,279 @@ void hyperstone_device::execute_run()
{
uint32_t oldh = SR & 0x00000020;
- PPC = PC; /* copy PC to previous PC */
debugger_instruction_hook(this, PC);
OP = READ_OP(PC);
PC += 2;
- m_instruction_length = 1;
+ m_instruction_length = (1<<19);
- /* execute opcode */
- (this->*m_opcode[(OP & 0xff00) >> 8])();
+ switch ((OP >> 8) & 0x00ff)
+ {
+ case 0x00: hyperstone_chk<GLOBAL, GLOBAL>(); break;
+ case 0x01: hyperstone_chk<GLOBAL, LOCAL>(); break;
+ case 0x02: hyperstone_chk<LOCAL, GLOBAL>(); break;
+ case 0x03: hyperstone_chk<LOCAL, LOCAL>(); break;
+ case 0x04: hyperstone_movd<GLOBAL, GLOBAL>(); break;
+ case 0x05: hyperstone_movd<GLOBAL, LOCAL>(); break;
+ case 0x06: hyperstone_movd<LOCAL, GLOBAL>(); break;
+ case 0x07: hyperstone_movd<LOCAL, LOCAL>(); break;
+ case 0x08: hyperstone_divsu<GLOBAL, GLOBAL, IS_UNSIGNED>(); break;
+ case 0x09: hyperstone_divsu<GLOBAL, LOCAL, IS_UNSIGNED>(); break;
+ case 0x0a: hyperstone_divsu<LOCAL, GLOBAL, IS_UNSIGNED>(); break;
+ case 0x0b: hyperstone_divsu<LOCAL, LOCAL, IS_UNSIGNED>(); break;
+ case 0x0c: hyperstone_divsu<GLOBAL, GLOBAL, IS_SIGNED>(); break;
+ case 0x0d: hyperstone_divsu<GLOBAL, LOCAL, IS_SIGNED>(); break;
+ case 0x0e: hyperstone_divsu<LOCAL, GLOBAL, IS_SIGNED>(); break;
+ case 0x0f: hyperstone_divsu<LOCAL, LOCAL, IS_SIGNED>(); break;
+ case 0x10: hyperstone_xm<GLOBAL, GLOBAL>(); break;
+ case 0x11: hyperstone_xm<GLOBAL, LOCAL>(); break;
+ case 0x12: hyperstone_xm<LOCAL, GLOBAL>(); break;
+ case 0x13: hyperstone_xm<LOCAL, LOCAL>(); break;
+ case 0x14: hyperstone_mask<GLOBAL, GLOBAL>(); break;
+ case 0x15: hyperstone_mask<GLOBAL, LOCAL>(); break;
+ case 0x16: hyperstone_mask<LOCAL, GLOBAL>(); break;
+ case 0x17: hyperstone_mask<LOCAL, LOCAL>(); break;
+ case 0x18: hyperstone_sum<GLOBAL, GLOBAL>(); break;
+ case 0x19: hyperstone_sum<GLOBAL, LOCAL>(); break;
+ case 0x1a: hyperstone_sum<LOCAL, GLOBAL>(); break;
+ case 0x1b: hyperstone_sum<LOCAL, LOCAL>(); break;
+ case 0x1c: hyperstone_sums<GLOBAL, GLOBAL>(); break;
+ case 0x1d: hyperstone_sums<GLOBAL, LOCAL>(); break;
+ case 0x1e: hyperstone_sums<LOCAL, GLOBAL>(); break;
+ case 0x1f: hyperstone_sums<LOCAL, LOCAL>(); break;
+ case 0x20: hyperstone_cmp<GLOBAL, GLOBAL>(); break;
+ case 0x21: hyperstone_cmp<GLOBAL, LOCAL>(); break;
+ case 0x22: hyperstone_cmp<LOCAL, GLOBAL>(); break;
+ case 0x23: hyperstone_cmp<LOCAL, LOCAL>(); break;
+ case 0x24: hyperstone_mov<GLOBAL, GLOBAL>(); break;
+ case 0x25: hyperstone_mov<GLOBAL, LOCAL>(); break;
+ case 0x26: hyperstone_mov<LOCAL, GLOBAL>(); break;
+ case 0x27: hyperstone_mov<LOCAL, LOCAL>(); break;
+ case 0x28: hyperstone_add<GLOBAL, GLOBAL>(); break;
+ case 0x29: hyperstone_add<GLOBAL, LOCAL>(); break;
+ case 0x2a: hyperstone_add<LOCAL, GLOBAL>(); break;
+ case 0x2b: hyperstone_add<LOCAL, LOCAL>(); break;
+ case 0x2c: hyperstone_adds<GLOBAL, GLOBAL>(); break;
+ case 0x2d: hyperstone_adds<GLOBAL, LOCAL>(); break;
+ case 0x2e: hyperstone_adds<LOCAL, GLOBAL>(); break;
+ case 0x2f: hyperstone_adds<LOCAL, LOCAL>(); break;
+ case 0x30: hyperstone_cmpb<GLOBAL, GLOBAL>(); break;
+ case 0x31: hyperstone_cmpb<GLOBAL, LOCAL>(); break;
+ case 0x32: hyperstone_cmpb<LOCAL, GLOBAL>(); break;
+ case 0x33: hyperstone_cmpb<LOCAL, LOCAL>(); break;
+ case 0x34: hyperstone_andn<GLOBAL, GLOBAL>(); break;
+ case 0x35: hyperstone_andn<GLOBAL, LOCAL>(); break;
+ case 0x36: hyperstone_andn<LOCAL, GLOBAL>(); break;
+ case 0x37: hyperstone_andn<LOCAL, LOCAL>(); break;
+ case 0x38: hyperstone_or<GLOBAL, GLOBAL>(); break;
+ case 0x39: hyperstone_or<GLOBAL, LOCAL>(); break;
+ case 0x3a: hyperstone_or<LOCAL, GLOBAL>(); break;
+ case 0x3b: hyperstone_or<LOCAL, LOCAL>(); break;
+ case 0x3c: hyperstone_xor<GLOBAL, GLOBAL>(); break;
+ case 0x3d: hyperstone_xor<GLOBAL, LOCAL>(); break;
+ case 0x3e: hyperstone_xor<LOCAL, GLOBAL>(); break;
+ case 0x3f: hyperstone_xor<LOCAL, LOCAL>(); break;
+ case 0x40: hyperstone_subc<GLOBAL, GLOBAL>(); break;
+ case 0x41: hyperstone_subc<GLOBAL, LOCAL>(); break;
+ case 0x42: hyperstone_subc<LOCAL, GLOBAL>(); break;
+ case 0x43: hyperstone_subc<LOCAL, LOCAL>(); break;
+ case 0x44: hyperstone_not<GLOBAL, GLOBAL>(); break;
+ case 0x45: hyperstone_not<GLOBAL, LOCAL>(); break;
+ case 0x46: hyperstone_not<LOCAL, GLOBAL>(); break;
+ case 0x47: hyperstone_not<LOCAL, LOCAL>(); break;
+ case 0x48: hyperstone_sub<GLOBAL, GLOBAL>(); break;
+ case 0x49: hyperstone_sub<GLOBAL, LOCAL>(); break;
+ case 0x4a: hyperstone_sub<LOCAL, GLOBAL>(); break;
+ case 0x4b: hyperstone_sub<LOCAL, LOCAL>(); break;
+ case 0x4c: hyperstone_subs<GLOBAL, GLOBAL>(); break;
+ case 0x4d: hyperstone_subs<GLOBAL, LOCAL>(); break;
+ case 0x4e: hyperstone_subs<LOCAL, GLOBAL>(); break;
+ case 0x4f: hyperstone_subs<LOCAL, LOCAL>(); break;
+ case 0x50: hyperstone_addc<GLOBAL, GLOBAL>(); break;
+ case 0x51: hyperstone_addc<GLOBAL, LOCAL>(); break;
+ case 0x52: hyperstone_addc<LOCAL, GLOBAL>(); break;
+ case 0x53: hyperstone_addc<LOCAL, LOCAL>(); break;
+ case 0x54: hyperstone_and<GLOBAL, GLOBAL>(); break;
+ case 0x55: hyperstone_and<GLOBAL, LOCAL>(); break;
+ case 0x56: hyperstone_and<LOCAL, GLOBAL>(); break;
+ case 0x57: hyperstone_and<LOCAL, LOCAL>(); break;
+ case 0x58: hyperstone_neg<GLOBAL, GLOBAL>(); break;
+ case 0x59: hyperstone_neg<GLOBAL, LOCAL>(); break;
+ case 0x5a: hyperstone_neg<LOCAL, GLOBAL>(); break;
+ case 0x5b: hyperstone_neg<LOCAL, LOCAL>(); break;
+ case 0x5c: hyperstone_negs<GLOBAL, GLOBAL>(); break;
+ case 0x5d: hyperstone_negs<GLOBAL, LOCAL>(); break;
+ case 0x5e: hyperstone_negs<LOCAL, GLOBAL>(); break;
+ case 0x5f: hyperstone_negs<LOCAL, LOCAL>(); break;
+ case 0x60: hyperstone_cmpi<GLOBAL, SIMM>(); break;
+ case 0x61: hyperstone_cmpi<GLOBAL, LIMM>(); break;
+ case 0x62: hyperstone_cmpi<LOCAL, SIMM>(); break;
+ case 0x63: hyperstone_cmpi<LOCAL, LIMM>(); break;
+ case 0x64: hyperstone_movi<GLOBAL, SIMM>(); break;
+ case 0x65: hyperstone_movi<GLOBAL, LIMM>(); break;
+ case 0x66: hyperstone_movi<LOCAL, SIMM>(); break;
+ case 0x67: hyperstone_movi<LOCAL, LIMM>(); break;
+ case 0x68: hyperstone_addi<GLOBAL, SIMM>(); break;
+ case 0x69: hyperstone_addi<GLOBAL, LIMM>(); break;
+ case 0x6a: hyperstone_addi<LOCAL, SIMM>(); break;
+ case 0x6b: hyperstone_addi<LOCAL, LIMM>(); break;
+ case 0x6c: hyperstone_addsi<GLOBAL, SIMM>(); break;
+ case 0x6d: hyperstone_addsi<GLOBAL, LIMM>(); break;
+ case 0x6e: hyperstone_addsi<LOCAL, SIMM>(); break;
+ case 0x6f: hyperstone_addsi<LOCAL, LIMM>(); break;
+ case 0x70: hyperstone_cmpbi<GLOBAL, SIMM>(); break;
+ case 0x71: hyperstone_cmpbi<GLOBAL, LIMM>(); break;
+ case 0x72: hyperstone_cmpbi<LOCAL, SIMM>(); break;
+ case 0x73: hyperstone_cmpbi<LOCAL, LIMM>(); break;
+ case 0x74: hyperstone_andni<GLOBAL, SIMM>(); break;
+ case 0x75: hyperstone_andni<GLOBAL, LIMM>(); break;
+ case 0x76: hyperstone_andni<LOCAL, SIMM>(); break;
+ case 0x77: hyperstone_andni<LOCAL, LIMM>(); break;
+ case 0x78: hyperstone_ori<GLOBAL, SIMM>(); break;
+ case 0x79: hyperstone_ori<GLOBAL, LIMM>(); break;
+ case 0x7a: hyperstone_ori<LOCAL, SIMM>(); break;
+ case 0x7b: hyperstone_ori<LOCAL, LIMM>(); break;
+ case 0x7c: hyperstone_xori<GLOBAL, SIMM>(); break;
+ case 0x7d: hyperstone_xori<GLOBAL, LIMM>(); break;
+ case 0x7e: hyperstone_xori<LOCAL, SIMM>(); break;
+ case 0x7f: hyperstone_xori<LOCAL, LIMM>(); break;
+ case 0x80: hyperstone_shrdi<N_LO>(); break;
+ case 0x81: hyperstone_shrdi<N_HI>(); break;
+ case 0x82: hyperstone_shrd(); break;
+ case 0x83: hyperstone_shr(); break;
+ case 0x84: hyperstone_sardi<N_LO>(); break;
+ case 0x85: hyperstone_sardi<N_HI>(); break;
+ case 0x86: hyperstone_sard(); break;
+ case 0x87: hyperstone_sar(); break;
+ case 0x88: hyperstone_shldi<N_LO>(); break;
+ case 0x89: hyperstone_shldi<N_HI>(); break;
+ case 0x8a: hyperstone_shld(); break;
+ case 0x8b: hyperstone_shl(); break;
+ case 0x8c: hyperstone_reserved(); break;
+ case 0x8d: hyperstone_reserved(); break;
+ case 0x8e: hyperstone_testlz(); break;
+ case 0x8f: hyperstone_rol(); break;
+ case 0x90: hyperstone_ldxx1<GLOBAL, GLOBAL>(); break;
+ case 0x91: hyperstone_ldxx1<GLOBAL, LOCAL>(); break;
+ case 0x92: hyperstone_ldxx1<LOCAL, GLOBAL>(); break;
+ case 0x93: hyperstone_ldxx1<LOCAL, LOCAL>(); break;
+ case 0x94: hyperstone_ldxx2<GLOBAL, GLOBAL>(); break;
+ case 0x95: hyperstone_ldxx2<GLOBAL, LOCAL>(); break;
+ case 0x96: hyperstone_ldxx2<LOCAL, GLOBAL>(); break;
+ case 0x97: hyperstone_ldxx2<LOCAL, LOCAL>(); break;
+ case 0x98: hyperstone_stxx1<GLOBAL, GLOBAL>(); break;
+ case 0x99: hyperstone_stxx1<GLOBAL, LOCAL>(); break;
+ case 0x9a: hyperstone_stxx1<LOCAL, GLOBAL>(); break;
+ case 0x9b: hyperstone_stxx1<LOCAL, LOCAL>(); break;
+ case 0x9c: hyperstone_stxx2<GLOBAL, GLOBAL>(); break;
+ case 0x9d: hyperstone_stxx2<GLOBAL, LOCAL>(); break;
+ case 0x9e: hyperstone_stxx2<LOCAL, GLOBAL>(); break;
+ case 0x9f: hyperstone_stxx2<LOCAL, LOCAL>(); break;
+ case 0xa0: hyperstone_shri<N_LO, GLOBAL>(); break;
+ case 0xa1: hyperstone_shri<N_HI, GLOBAL>(); break;
+ case 0xa2: hyperstone_shri<N_LO, LOCAL>(); break;
+ case 0xa3: hyperstone_shri<N_HI, LOCAL>(); break;
+ case 0xa4: hyperstone_sari<N_LO, GLOBAL>(); break;
+ case 0xa5: hyperstone_sari<N_HI, GLOBAL>(); break;
+ case 0xa6: hyperstone_sari<N_LO, LOCAL>(); break;
+ case 0xa7: hyperstone_sari<N_HI, LOCAL>(); break;
+ case 0xa8: hyperstone_shli<N_LO, GLOBAL>(); break;
+ case 0xa9: hyperstone_shli<N_HI, GLOBAL>(); break;
+ case 0xaa: hyperstone_shli<N_LO, LOCAL>(); break;
+ case 0xab: hyperstone_shli<N_HI, LOCAL>(); break;
+ case 0xac: hyperstone_reserved(); break;
+ case 0xad: hyperstone_reserved(); break;
+ case 0xae: hyperstone_reserved(); break;
+ case 0xaf: hyperstone_reserved(); break;
+ case 0xb0: hyperstone_mulsu<GLOBAL, GLOBAL, IS_UNSIGNED>(); break;
+ case 0xb1: hyperstone_mulsu<GLOBAL, LOCAL, IS_UNSIGNED>(); break;
+ case 0xb2: hyperstone_mulsu<LOCAL, GLOBAL, IS_UNSIGNED>(); break;
+ case 0xb3: hyperstone_mulsu<LOCAL, LOCAL, IS_UNSIGNED>(); break;
+ case 0xb4: hyperstone_mulsu<GLOBAL, GLOBAL, IS_SIGNED>(); break;
+ case 0xb5: hyperstone_mulsu<GLOBAL, LOCAL, IS_SIGNED>(); break;
+ case 0xb6: hyperstone_mulsu<LOCAL, GLOBAL, IS_SIGNED>(); break;
+ case 0xb7: hyperstone_mulsu<LOCAL, LOCAL, IS_SIGNED>(); break;
+ case 0xb8: hyperstone_set<N_LO, GLOBAL>(); break;
+ case 0xb9: hyperstone_set<N_HI, GLOBAL>(); break;
+ case 0xba: hyperstone_set<N_LO, LOCAL>(); break;
+ case 0xbb: hyperstone_set<N_HI, LOCAL>(); break;
+ case 0xbc: hyperstone_mul<GLOBAL, GLOBAL>(); break;
+ case 0xbd: hyperstone_mul<GLOBAL, LOCAL>(); break;
+ case 0xbe: hyperstone_mul<LOCAL, GLOBAL>(); break;
+ case 0xbf: hyperstone_mul<LOCAL, LOCAL>(); break;
+ case 0xc0: execute_software(); break; // fadd
+ case 0xc1: execute_software(); break; // faddd
+ case 0xc2: execute_software(); break; // fsub
+ case 0xc3: execute_software(); break; // fsubd
+ case 0xc4: execute_software(); break; // fmul
+ case 0xc5: execute_software(); break; // fmuld
+ case 0xc6: execute_software(); break; // fdiv
+ case 0xc7: execute_software(); break; // fdivd
+ case 0xc8: execute_software(); break; // fcmp
+ case 0xc9: execute_software(); break; // fcmpd
+ case 0xca: execute_software(); break; // fcmpu
+ case 0xcb: execute_software(); break; // fcmpud
+ case 0xcc: execute_software(); break; // fcvt
+ case 0xcd: execute_software(); break; // fcvtd
+ case 0xce: hyperstone_extend(); break;
+ case 0xcf: hyperstone_do(); break;
+ case 0xd0: hyperstone_ldwr<GLOBAL>(); break;
+ case 0xd1: hyperstone_ldwr<LOCAL>(); break;
+ case 0xd2: hyperstone_lddr<GLOBAL>(); break;
+ case 0xd3: hyperstone_lddr<LOCAL>(); break;
+ case 0xd4: hypesrtone_ldwp<GLOBAL>(); break;
+ case 0xd5: hypesrtone_ldwp<LOCAL>(); break;
+ case 0xd6: hyperstone_lddp<GLOBAL>(); break;
+ case 0xd7: hyperstone_lddp<LOCAL>(); break;
+ case 0xd8: hyperstone_stwr<GLOBAL>(); break;
+ case 0xd9: hyperstone_stwr<LOCAL>(); break;
+ case 0xda: hyperstone_stdr<GLOBAL>(); break;
+ case 0xdb: hyperstone_stdr<LOCAL>(); break;
+ case 0xdc: hyperstone_stwp<GLOBAL>(); break;
+ case 0xdd: hyperstone_stwp<LOCAL>(); break;
+ case 0xde: hyperstone_stdp<GLOBAL>(); break;
+ case 0xdf: hyperstone_stdp<LOCAL>(); break;
+ case 0xe0: hyperstone_dbv(); break;
+ case 0xe1: hyperstone_dbnv(); break;
+ case 0xe2: hyperstone_dbe(); break;
+ case 0xe3: hyperstone_dbne(); break;
+ case 0xe4: hyperstone_dbc(); break;
+ case 0xe5: hyperstone_dbnc(); break;
+ case 0xe6: hyperstone_dbse(); break;
+ case 0xe7: hyperstone_dbht(); break;
+ case 0xe8: hyperstone_dbn(); break;
+ case 0xe9: hyperstone_dbnn(); break;
+ case 0xea: hyperstone_dble(); break;
+ case 0xeb: hyperstone_dbgt(); break;
+ case 0xec: hyperstone_dbr(); break;
+ case 0xed: hyperstone_frame(); break;
+ case 0xee: hyperstone_call_global(); break;
+ case 0xef: hyperstone_call_local(); break;
+ case 0xf0: hyperstone_bv(); break;
+ case 0xf1: hyperstone_bnv(); break;
+ case 0xf2: hyperstone_be(); break;
+ case 0xf3: hyperstone_bne(); break;
+ case 0xf4: hyperstone_bc(); break;
+ case 0xf5: hyperstone_bnc(); break;
+ case 0xf6: hyperstone_bse(); break;
+ case 0xf7: hyperstone_bht(); break;
+ case 0xf8: hyperstone_bn(); break;
+ case 0xf9: hyperstone_bnn(); break;
+ case 0xfa: hyperstone_ble(); break;
+ case 0xfb: hyperstone_bgt(); break;
+ case 0xfc: execute_br(); break;
+ case 0xfd: hyperstone_trap(); break;
+ case 0xfe: hyperstone_trap(); break;
+ case 0xff: hyperstone_trap(); break;
+ }
/* clear the H state if it was previously set */
SR ^= oldh;
- SET_ILC(m_instruction_length & 3);
+ SET_ILC(m_instruction_length);
- if( GET_T && GET_P && m_delay.delay_cmd == NO_DELAY ) /* Not in a Delayed Branch instructions */
+ if (GET_T && GET_P && !m_delay_slot) /* Not in a Delayed Branch instructions */
{
uint32_t addr = get_trap_addr(TRAPNO_TRACE_EXCEPTION);
execute_exception(addr);