diff options
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 |
commit | 8364758817f5a287f07a2f710fc9f5a52f299661 (patch) | |
tree | b6db73c79349637f142ba5690eadb765f74f95eb | |
parent | 4d22ad601e5d6ffe5fb2949fad1c2c6ae9238f3e (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.cpp | 17 | ||||
-rw-r--r-- | src/devices/cpu/mb86235/mb86235.h | 3 | ||||
-rw-r--r-- | src/devices/cpu/mb86235/mb86235ops.cpp | 115 |
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; } |