summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author angelosa <salese_corp_ltd@email.it>2018-03-22 01:47:55 +0100
committer angelosa <salese_corp_ltd@email.it>2018-03-22 01:50:34 +0100
commit8364758817f5a287f07a2f710fc9f5a52f299661 (patch)
treeb6db73c79349637f142ba5690eadb765f74f95eb
parent4d22ad601e5d6ffe5fb2949fad1c2c6ae9238f3e (diff)
tgpx4: misc fixing (floating point conversions, broken REP opcode, support for rascot2 MOV2 int->ext opcode) (nw)
-rw-r--r--src/devices/cpu/mb86235/mb86235.cpp17
-rw-r--r--src/devices/cpu/mb86235/mb86235.h3
-rw-r--r--src/devices/cpu/mb86235/mb86235ops.cpp115
3 files changed, 84 insertions, 51 deletions
diff --git a/src/devices/cpu/mb86235/mb86235.cpp b/src/devices/cpu/mb86235/mb86235.cpp
index 363a071e586..17ce8f0fb42 100644
--- a/src/devices/cpu/mb86235/mb86235.cpp
+++ b/src/devices/cpu/mb86235/mb86235.cpp
@@ -1,6 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Angelo Salese, ElSemi, Ville Linde
-/*****************************************************************************
+/********************************************************************************
*
* MB86235 "TGPx4" (c) Fujitsu
*
@@ -9,14 +9,16 @@
* TODO:
* - rewrite ALU integer/floating point functions, use templates etc;
* - move post-opcodes outside of the execute_op() function, like increment_prp()
- * (needed if opcode uses fifo in/out);
- * - fifo stall shouldn't make the alu opcode to repeat;
- * - illegal delay slot on REP unsupported;
+ * (needed if opcode uses fifo in/out);
+ * - rewrite fifo hookups, remove them from the actual opcodes.
+ * - use a phase system for the execution, like do_alu() being separated
+ * from control();
+ * - illegal delay slots unsupported, and no idea about what is supposed to happen;
* - externalize PDR / DDR (error LED flags on Model 2);
* - instruction cycles;
* - pipeline (four instruction executed per cycle!)
*
- *****************************************************************************/
+ ********************************************************************************/
#include "emu.h"
#include "mb86235.h"
@@ -61,8 +63,8 @@ void mb86235_device::execute_run()
{
uint32_t curpc;
- curpc = m_core->cur_fifo_state.has_stalled ? m_core->cur_fifo_state.pc : m_core->pc;
-
+ curpc = check_previous_op_stall() ? m_core->cur_fifo_state.pc : m_core->pc;
+
debugger_instruction_hook(this, curpc);
opcode = m_direct->read_qword(curpc);
@@ -218,6 +220,7 @@ void mb86235_device::device_start()
m_icountptr = &m_core->icount;
m_core->fp0 = 0.0f;
+ save_pointer(NAME(m_core->pr), 24);
}
void mb86235_device::device_reset()
diff --git a/src/devices/cpu/mb86235/mb86235.h b/src/devices/cpu/mb86235/mb86235.h
index 1d367d511ab..58e8f645dda 100644
--- a/src/devices/cpu/mb86235/mb86235.h
+++ b/src/devices/cpu/mb86235/mb86235.h
@@ -240,6 +240,7 @@ private:
void generate_branch_target(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int type, int ef2);
bool has_register_clash(const opcode_desc *desc, int outreg);
bool aluop_has_result(int aluop);
+ bool check_previous_op_stall();
// interpreter
void execute_op(uint32_t h, uint32_t l);
@@ -274,7 +275,7 @@ private:
inline void decrement_prp();
inline void zero_prp();
inline void set_alu_flagsd(uint32_t val);
- inline void set_alu_flagsf(float val);
+ inline void set_alu_flagsf(double val);
inline void set_alu_flagsi(int val);
inline bool get_alu_second_src(uint8_t which);
void handle_single_step_execution();
diff --git a/src/devices/cpu/mb86235/mb86235ops.cpp b/src/devices/cpu/mb86235/mb86235ops.cpp
index 2be53e6224b..c667d745d90 100644
--- a/src/devices/cpu/mb86235/mb86235ops.cpp
+++ b/src/devices/cpu/mb86235/mb86235ops.cpp
@@ -10,6 +10,7 @@
#include "emu.h"
#include "mb86235.h"
+#include "debugger.h"
/*********************
*
@@ -60,6 +61,11 @@ void mb86235_device::handle_single_step_execution()
m_core->pc ++;
}
+bool mb86235_device::check_previous_op_stall()
+{
+ return (m_core->cur_fifo_state.has_stalled == true) && ((m_core->st & RP) == 0);
+}
+
inline void mb86235_device::increment_pwp()
{
m_core->pwp++;
@@ -97,11 +103,15 @@ inline uint32_t mb86235_device::decode_ea(uint8_t mode, uint8_t rx, uint8_t ry,
return m_core->ar[rx];
case 0x01: // ARx ++
res = m_core->ar[rx];
+ if(m_core->cur_fifo_state.has_stalled == true)
+ return res;
m_core->ar[rx]++;
m_core->ar[rx]&=0x3fff;
return res;
case 0x03: // ARx + disp12
res = m_core->ar[rx];
+ if(m_core->cur_fifo_state.has_stalled == true)
+ return res;
m_core->ar[rx]+=disp;
m_core->ar[rx]&=0x3fff;
return res;
@@ -109,11 +119,15 @@ inline uint32_t mb86235_device::decode_ea(uint8_t mode, uint8_t rx, uint8_t ry,
return m_core->ar[rx]+m_core->ar[ry];
case 0x05: // ARx + ARy++
res = m_core->ar[ry];
+ if(m_core->cur_fifo_state.has_stalled == true)
+ return res;
m_core->ar[ry]++;
m_core->ar[ry]&=0x3fff;
return m_core->ar[rx]+res;
case 0x07: // ARx + (ARy + disp12)
res = m_core->ar[ry];
+ if(m_core->cur_fifo_state.has_stalled == true)
+ return res;
m_core->ar[ry]+=disp;
m_core->ar[ry]&=0x3fff;
return m_core->ar[rx]+res;
@@ -197,7 +211,7 @@ inline void mb86235_device::set_alu_flagsd(uint32_t val)
if(val==0) FSET(AZ);
}
-inline void mb86235_device::set_alu_flagsf(float val)
+inline void mb86235_device::set_alu_flagsf(double val)
{
FCLR(AN|AZ);
if(val<0.0) FSET(AN);
@@ -228,8 +242,8 @@ inline uint32_t mb86235_device::get_prx(uint8_t which)
inline uint32_t mb86235_device::get_constfloat(uint8_t which)
{
- const float float_table[8] = { -1.0, 0.0, 0.5, 1.0, 1.5, 2.0, 3.0, 5.0 };
- return (uint32_t)float_table[which & 7];
+ const double float_table[8] = { -1.0, 0.0, 0.5, 1.0, 1.5, 2.0, 3.0, 5.0 };
+ return f2u(float_table[which & 7]);
}
inline uint32_t mb86235_device::get_constint(uint8_t which)
@@ -313,9 +327,9 @@ inline void mb86235_device::decode_aluop(uint8_t opcode, uint32_t src1, uint32_t
case 0x02: // FSUB
case 0x03: // FSUBZ
{
- float f1 = (float)src1;
- float f2 = (float)src2;
- float d;
+ double f1 = u2f(src1);
+ double f2 = u2f(src2);
+ double d;
if(opcode & 2)
d = f2-f1;
@@ -328,34 +342,37 @@ inline void mb86235_device::decode_aluop(uint8_t opcode, uint32_t src1, uint32_t
if(d < 0.0)
{
FSET(ZC);
- d = 0.0f;
+ d = 0.0;
}
}
+
set_alu_flagsf(d);
- set_alureg(dst_which,d);
+ set_alureg(dst_which,f2u(d));
break;
}
case 0x04: // FCMP
case 0x06: // FABC
{
- float f1 = (float)src1;
- float f2 = (float)src2;
- float d;
+ double f1 = u2f(src1);
+ double f2 = u2f(src2);
+ double d;
+
if(opcode & 2)
d = fabs(f2)-fabs(f1);
else
d = f2-f1;
+
set_alu_flagsf(d);
break;
}
case 0x05: // FABS
{
- float d = (float)src1;
+ double d = u2f(src1);
d = fabs(d);
set_alu_flagsf(d);
- set_alureg(dst_which,d);
+ set_alureg(dst_which,f2u(d));
break;
}
@@ -380,64 +397,64 @@ inline void mb86235_device::decode_aluop(uint8_t opcode, uint32_t src1, uint32_t
case 0x0a: // FRCP
{
- float f = (float)src1;
+ double f = u2f(src1);
FCLR(ZD);
if(f == 0.0f)
FSET(ZD);
f = 1.0/f;
set_alu_flagsf(f);
- set_alureg(dst_which,f);
+ set_alureg(dst_which,f2u(f));
break;
}
case 0x0b: // FRSQ
{
- float f = (float)src1;
+ double f = u2f(src1);
FCLR(NR);
if(f <= 0.0f)
FSET(NR);
f = 1.0/sqrtf(f);
set_alu_flagsf(f);
- set_alureg(dst_which,f);
+ set_alureg(dst_which,f2u(f));
break;
}
case 0x0c: // FLOG
{
- float f = (float)src1;
+ double f = u2f(src1);
FCLR(IL);
if(f <= 0.0f)
FSET(IL);
- f = log(f)/0.301030f; // log2
+ f = log(f)/0.301030; // log2
set_alu_flagsf(f);
- set_alureg(dst_which,f);
+ set_alureg(dst_which,f2u(f));
break;
}
case 0x0d: // CIF
{
- int v = (((int)src1) << 0) >> 0;
- float f = (float)v;
+ int v = (int)src1;
+ double f = u2f(v);
set_alu_flagsf(f);
- set_alureg(dst_which,f);
+ set_alureg(dst_which,f2u(f));
break;
}
case 0x0e: // CFI
{
- float f = (float)src1;
+ double f = u2f(src1);
int v = (int)f;
set_alu_flagsi(v);
- set_alureg(dst_which,v);
+ set_alureg(dst_which,f2u(v));
break;
}
case 0x0f: // CFIB
{
- float f = (float)src1;
+ double f = u2f(src1);
uint32_t res;
FCLR(AU);
- res = (uint32_t)f;
+ res = f2u(f);
if(f<0)
{
FSET(AU);
@@ -592,15 +609,15 @@ void mb86235_device::decode_mulop(bool isfmul, uint32_t src1, uint32_t src2, uin
{
if(isfmul == true) // FMUL
{
- float f1 = (float)src1;
- float f2 = (float)src2;
- float res = f1*f2;
+ double f1 = u2f(src1);
+ double f2 = u2f(src2);
+ double res = f1*f2;
FCLR(MD|MU|MV);
// TODO: MD MU MV flags
FCLR(MN|MZ);
if(res<0.0) FSET(MN);
if(res==0.0) FSET(MZ);
- set_alureg(dst_which,(uint32_t)res);
+ set_alureg(dst_which,f2u(res));
}
else // MUL
{
@@ -694,8 +711,6 @@ void mb86235_device::do_alu2(uint32_t h, uint32_t l)
*
********************/
-#include "debugger.h"
-
inline uint32_t mb86235_device::get_transfer_reg(uint8_t which)
{
switch(which >> 3)
@@ -741,7 +756,7 @@ inline uint32_t mb86235_device::get_transfer_reg(uint8_t which)
{
FSET(IFE);
m_core->cur_fifo_state.has_stalled = true;
- //if((m_core->st & RP) == 0)
+ if((m_core->st & RP) == 0)
m_core->cur_fifo_state.pc = m_core->ppc;
//else
// fatalerror("check me %08x\n",m_core->ppc);
@@ -816,8 +831,9 @@ inline void mb86235_device::set_transfer_reg(uint8_t which, uint32_t value)
{
FSET(OFF);
m_core->cur_fifo_state.has_stalled = true;
- //if((m_core->st & RP) == 0)
+ if((m_core->st & RP) == 0)
m_core->cur_fifo_state.pc = m_core->ppc;
+
//else
// fatalerror("check me (writes)");
return;
@@ -958,7 +974,7 @@ void mb86235_device::do_trans2_2(uint32_t h, uint32_t l)
switch(sdb)
{
// reg -> reg
- case 0: //reg->reg
+ case 0:
{
uint8_t bs = (l >> 13) & 0x1f;
uint8_t bd = (l >> 8) & 0xf;
@@ -1013,7 +1029,16 @@ void mb86235_device::do_trans1_2(uint32_t h, uint32_t l)
disp_offs |= 1;
if(sr & 0x40)
- fatalerror("TGPx4: unimplemented int->ext sr %02x at pc=%08x\n",sr,m_core->ppc);
+ {
+ if(sr == 0x58)
+ res = l & 0xffffff;
+ else
+ {
+ bool isbbus = (sr & 0x20) == 0x20;
+ uint32_t addr = decode_ea(l & 0xf,sr & 7,(l >> 4) & 7, (l >> 7) & 0x3fff,isbbus);
+ res = read_bus(isbbus,addr);
+ }
+ }
else
res = get_transfer_reg(sr);
@@ -1085,17 +1110,17 @@ void mb86235_device::do_trans1_3(uint32_t h, uint32_t l)
inline void mb86235_device::push_pc(uint32_t pcval)
{
m_core->pcs[m_core->pcp++] = pcval;
-// m_core->pcp &= 3;
- if(m_core->pcp & ~3)
- fatalerror("TGPx4: push_pc overflow PCP=%08x PC=%08x\n",m_core->pcp,m_core->ppc);
+ m_core->pcp &= 3;
+// if(m_core->pcp & ~3)
+// fatalerror("TGPx4: push_pc overflow PCP=%08x PC=%08x\n",m_core->pcp,m_core->ppc);
}
inline uint32_t mb86235_device::pop_pc()
{
m_core->pcp--;
-// m_core->pcp &= 3;
- if(m_core->pcp & ~3)
- fatalerror("TGPx4: pop_pc underflow PCP=%08x PC=%08x\n",m_core->pcp,m_core->ppc);
+ m_core->pcp &= 3;
+// if(m_core->pcp & ~3)
+// fatalerror("TGPx4: pop_pc underflow PCP=%08x PC=%08x\n",m_core->pcp,m_core->ppc);
return m_core->pcs[m_core->pcp];
}
@@ -1173,6 +1198,7 @@ void mb86235_device::do_control(uint32_t h, uint32_t l)
m_core->fifoin.num = 0;
FSET(IFE);
FCLR(IFF);
+ m_core->cur_fifo_state.has_stalled = false;
}
if(ef1 & 2) // clear fifo0/1 out (CLRFO)
{
@@ -1184,6 +1210,7 @@ void mb86235_device::do_control(uint32_t h, uint32_t l)
m_core->fifoout1.num = 0;
FSET(OFE);
FCLR(OFF);
+ m_core->cur_fifo_state.has_stalled = false;
}
break;
case 0x04: // PUSH
@@ -1223,6 +1250,7 @@ void mb86235_device::do_control(uint32_t h, uint32_t l)
{
m_core->delay_slot = true;
m_core->delay_pc = do_control_dst(l);
+ m_core->icount--;
}
break;
}
@@ -1233,6 +1261,7 @@ void mb86235_device::do_control(uint32_t h, uint32_t l)
{
m_core->delay_slot = true;
m_core->delay_pc = do_control_dst(l);
+ m_core->icount--;
}
break;
}