mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
tgpx4: misc fixing (floating point conversions, broken REP opcode, support for rascot2 MOV2 int->ext opcode) (nw)
This commit is contained in:
parent
4d22ad601e
commit
8364758817
@ -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()
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user