From 3344b2f6ac451adc8df63440a8c7dd098c40cb14 Mon Sep 17 00:00:00 2001 From: angelosa Date: Tue, 20 Mar 2018 17:20:52 +0100 Subject: Wrote a preliminary TGPx4 interpreter core [Angelo Salese] i960.cpp: support burst stall on writes [Angelo Salese] --- src/devices/cpu/i960/i960.cpp | 31 +- src/devices/cpu/i960/i960.h | 3 +- src/devices/cpu/mb86235/mb86235.cpp | 91 ++- src/devices/cpu/mb86235/mb86235.h | 67 +- src/devices/cpu/mb86235/mb86235d.cpp | 11 +- src/devices/cpu/mb86235/mb86235d.h | 2 +- src/devices/cpu/mb86235/mb86235ops.cpp | 1284 ++++++++++++++++++++++++++++++++ src/mame/drivers/model2.cpp | 87 ++- src/mame/includes/model2.h | 9 +- 9 files changed, 1512 insertions(+), 73 deletions(-) diff --git a/src/devices/cpu/i960/i960.cpp b/src/devices/cpu/i960/i960.cpp index b6d76e9788f..049d0a54043 100644 --- a/src/devices/cpu/i960/i960.cpp +++ b/src/devices/cpu/i960/i960.cpp @@ -601,12 +601,13 @@ void i960_cpu_device::do_ret() // if last opcode was a multi dword burst read opcode save the data here // i.e. Model 2 FIFO reads with ldl, ldt, ldq -void i960_cpu_device::burst_stall_save(uint32_t t1, uint32_t t2, int index, int size) +void i960_cpu_device::burst_stall_save(uint32_t t1, uint32_t t2, int index, int size, bool iswriteop) { m_stall_state.t1 = t1; m_stall_state.t2 = t2; m_stall_state.index = index; m_stall_state.size = size; + m_stall_state.iswriteop = iswriteop; m_stall_state.burst_mode = true; } @@ -620,9 +621,12 @@ void i960_cpu_device::execute_burst_stall_op(uint32_t opcode) // check if our data is ready for(i=m_stall_state.index ; ipc); - m_core->icount = 0; + uint64_t opcode; + while(m_core->icount > 0) + { + uint32_t curpc; + + curpc = m_core->cur_fifo_state.has_stalled ? m_core->cur_fifo_state.pc : m_core->pc; + + debugger_instruction_hook(this, curpc); + opcode = m_direct->read_qword(curpc); + + m_core->ppc = curpc; + + if(m_core->delay_slot == true) + { + m_core->pc = m_core->delay_pc; + m_core->delay_slot = false; + } + else + handle_single_step_execution(); + + execute_op(opcode >> 32, opcode & 0xffffffff); + + m_core->icount--; + } + #endif } @@ -66,7 +96,9 @@ void mb86235_device::device_start() memset(m_core, 0, sizeof(mb86235_internal_state)); +#if ENABLE_DRC // init UML generator + uint32_t umlflags = 0; m_drcuml = std::make_unique(*this, m_cache, umlflags, 1, 24, 0); @@ -124,7 +156,7 @@ void mb86235_device::device_start() m_regmap[i + 16] = uml::mem(&m_core->ma[i]); m_regmap[i + 24] = uml::mem(&m_core->mb[i]); } - +#endif // Register state for debugger state_add(MB86235_PC, "PC", m_core->pc).formatstr("%08X"); @@ -168,6 +200,18 @@ void mb86235_device::device_start() state_add(MB86235_MB5, "MB5", m_core->mb[5]).formatstr("%08X"); state_add(MB86235_MB6, "MB6", m_core->mb[6]).formatstr("%08X"); state_add(MB86235_MB7, "MB7", m_core->mb[7]).formatstr("%08X"); + state_add(MB86235_ST, "ST", m_core->st).formatstr("%08X"); + + state_add(MB86235_EB, "EB", m_core->eb).formatstr("%08X"); + state_add(MB86235_EO, "EO", m_core->eo).formatstr("%08X"); + state_add(MB86235_SP, "SP", m_core->sp).formatstr("%08X"); + state_add(MB86235_RPC, "RPC", m_core->rpc).formatstr("%08X"); + state_add(MB86235_LPC, "LPC", m_core->lpc).formatstr("%08X"); + state_add(MB86235_PDR, "PDR", m_core->pdr).formatstr("%08X"); + state_add(MB86235_DDR, "DDR", m_core->ddr).formatstr("%08X"); + state_add(MB86235_MOD, "MOD", m_core->mod).formatstr("%04X"); + state_add(MB86235_PRP, "PRP", m_core->prp).formatstr("%02X"); + state_add(MB86235_PWP, "PWP", m_core->pwp).formatstr("%02X"); state_add(STATE_GENPC, "GENPC", m_core->pc ).noshow(); state_add(STATE_GENPCBASE, "CURPC", m_core->pc).noshow(); @@ -178,9 +222,14 @@ void mb86235_device::device_start() void mb86235_device::device_reset() { +#if ENABLE_DRC flush_cache(); - +#endif + m_core->pc = 0; + m_core->delay_pc = 0; + m_core->ppc = 0; + m_core->delay_slot = false; } #if 0 @@ -242,57 +291,53 @@ util::disasm_interface *mb86235_device::create_disassembler() } -void mb86235_device::fifoin_w(uint64_t data) +void mb86235_device::fifoin_w(uint32_t data) { -#if ENABLE_DRC if (m_core->fifoin.num >= FIFOIN_SIZE) { fatalerror("fifoin_w: pushing to full fifo"); } - //printf("FIFOIN push %08X%08X\n", (uint32_t)(data >> 32), (uint32_t)(data)); + //printf("FIFOIN push %08X\n", data); m_core->fifoin.data[m_core->fifoin.wpos] = data; m_core->fifoin.wpos++; m_core->fifoin.wpos &= FIFOIN_SIZE-1; m_core->fifoin.num++; -#endif +} + +bool mb86235_device::is_fifoin_empty() +{ + return m_core->fifoin.num == 0; } bool mb86235_device::is_fifoin_full() { -#if ENABLE_DRC return m_core->fifoin.num >= FIFOIN_SIZE; -#else - return false; -#endif } -uint64_t mb86235_device::fifoout0_r() +uint32_t mb86235_device::fifoout0_r() { -#if ENABLE_DRC if (m_core->fifoout0.num == 0) { fatalerror("fifoout0_r: reading from empty fifo"); } - uint64_t data = m_core->fifoout0.data[m_core->fifoout0.rpos]; + uint32_t data = m_core->fifoout0.data[m_core->fifoout0.rpos]; m_core->fifoout0.rpos++; m_core->fifoout0.rpos &= FIFOOUT0_SIZE - 1; m_core->fifoout0.num--; return data; -#else - return 0; -#endif +} + +bool mb86235_device::is_fifoout0_full() +{ + return m_core->fifoout0.num >= FIFOOUT0_SIZE; } bool mb86235_device::is_fifoout0_empty() { -#if ENABLE_DRC return m_core->fifoout0.num == 0; -#else - return false; -#endif } diff --git a/src/devices/cpu/mb86235/mb86235.h b/src/devices/cpu/mb86235/mb86235.h index 8f3c9ddb848..1d367d511ab 100644 --- a/src/devices/cpu/mb86235/mb86235.h +++ b/src/devices/cpu/mb86235/mb86235.h @@ -33,10 +33,12 @@ public: void pcs_overflow(); void pcs_underflow(); - void fifoin_w(uint64_t data); + void fifoin_w(uint32_t data); bool is_fifoin_full(); - uint64_t fifoout0_r(); + bool is_fifoin_empty(); + uint32_t fifoout0_r(); bool is_fifoout0_empty(); + bool is_fifoout0_full(); enum { @@ -46,6 +48,9 @@ public: MB86235_MA0, MB86235_MA1, MB86235_MA2, MB86235_MA3, MB86235_MA4, MB86235_MA5, MB86235_MA6, MB86235_MA7, MB86235_MB0, MB86235_MB1, MB86235_MB2, MB86235_MB3, MB86235_MB4, MB86235_MB5, MB86235_MB6, MB86235_MB7, MB86235_AR0, MB86235_AR1, MB86235_AR2, MB86235_AR3, MB86235_AR4, MB86235_AR5, MB86235_AR6, MB86235_AR7, + MB86235_MOD, MB86235_EB, MB86235_EO, MB86235_SP, MB86235_PDR, MB86235_DDR, MB86235_RPC, MB86235_LPC, + MB86235_PRP, MB86235_PWP, + MB86235_ST }; static constexpr int FIFOIN_SIZE = 16; @@ -102,12 +107,20 @@ private: int rpos; int wpos; int num; - uint64_t data[16]; + uint32_t data[16]; }; - + + struct fifo_state + { + uint32_t pc; + bool has_stalled; + }; + struct mb86235_internal_state { uint32_t pc; + uint32_t delay_pc; + uint32_t ppc; uint32_t aa[8]; uint32_t ab[8]; uint32_t ma[8]; @@ -125,8 +138,10 @@ private: uint32_t pr[24]; uint32_t mod; + // TODO: remove this, use ST instead mb86235_flags flags; - + uint32_t st; + int icount; uint32_t arg0; @@ -147,10 +162,12 @@ private: uint32_t ddr; float fp0; - + bool delay_slot; + fifo fifoin; fifo fifoout0; fifo fifoout1; + fifo_state cur_fifo_state; }; mb86235_internal_state *m_core; @@ -223,6 +240,44 @@ 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); + +// interpreter + void execute_op(uint32_t h, uint32_t l); + void do_alu1(uint32_t h, uint32_t l); + void do_alu2(uint32_t h, uint32_t l); + void do_trans2_1(uint32_t h, uint32_t l); + void do_trans1_1(uint32_t h, uint32_t l); + void do_trans2_2(uint32_t h, uint32_t l); + void do_trans1_2(uint32_t h, uint32_t l); + void do_trans1_3(uint32_t h, uint32_t l); + void do_control(uint32_t h, uint32_t l); + inline uint32_t get_prx(uint8_t which); + inline uint32_t get_constfloat(uint8_t which); + inline uint32_t get_constint(uint8_t which); + inline uint32_t get_alureg(uint8_t which, bool isfloatop); + inline uint32_t get_mulreg(uint8_t which, bool isfloatop); + inline void set_alureg(uint8_t which, uint32_t value); + inline void decode_aluop(uint8_t opcode, uint32_t src1, uint32_t src2, uint8_t imm, uint8_t dst_which); + inline void decode_mulop(bool isfmul, uint32_t src1, uint32_t src2, uint8_t dst_which); + inline bool decode_branch_jump(uint8_t which); + inline uint32_t do_control_dst(uint32_t l); + inline void push_pc(uint32_t pcval); + inline uint32_t pop_pc(); + inline void set_mod(uint16_t mod1, uint16_t mod2); + inline uint32_t get_transfer_reg(uint8_t which); + inline void set_transfer_reg(uint8_t which, uint32_t value); + inline uint32_t decode_ea(uint8_t mode, uint8_t rx, uint8_t ry, uint16_t disp, bool isbbus); + inline uint32_t read_bus(bool isbbus, uint32_t addr); + inline void write_bus(bool isbbus, uint32_t addr, uint32_t data); + inline void increment_pwp(); + inline void increment_prp(); + 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_flagsi(int val); + inline bool get_alu_second_src(uint8_t which); + void handle_single_step_execution(); }; diff --git a/src/devices/cpu/mb86235/mb86235d.cpp b/src/devices/cpu/mb86235/mb86235d.cpp index e705500f1cd..ca31dbca720 100644 --- a/src/devices/cpu/mb86235/mb86235d.cpp +++ b/src/devices/cpu/mb86235/mb86235d.cpp @@ -468,7 +468,7 @@ void mb86235_disassembler::dasm_xfer1(std::ostream &stream, uint64_t opcode) } } -void mb86235_disassembler::dasm_double_xfer2_field(std::ostream &stream, int sd, uint32_t field) +void mb86235_disassembler::dasm_double_xfer2_field(std::ostream &stream, int sd, bool isbbus, uint32_t field) { switch (sd) { @@ -476,6 +476,11 @@ void mb86235_disassembler::dasm_double_xfer2_field(std::ostream &stream, int sd, { int s = (field >> 13) & 0x1f; int d = (field >> 8) & 0x1f; + if(isbbus == true) + { + s |= 0x20; + d |= 0x20; + } util::stream_format(stream, "%s, %s", regname[s], regname[d]); break; } @@ -576,9 +581,9 @@ void mb86235_disassembler::dasm_double_xfer2(std::ostream &stream, uint64_t opco else { stream << "MVD2 "; - dasm_double_xfer2_field(stream, asd, (opcode >> 20) & 0x3ffff); + dasm_double_xfer2_field(stream, asd, false, (opcode >> 20) & 0x3ffff); stream << ", "; - dasm_double_xfer2_field(stream, bsd, opcode & 0x3ffff); + dasm_double_xfer2_field(stream, bsd, true, opcode & 0x3ffff); } } diff --git a/src/devices/cpu/mb86235/mb86235d.h b/src/devices/cpu/mb86235/mb86235d.h index a29fe41f064..4f9a3c1ed2d 100644 --- a/src/devices/cpu/mb86235/mb86235d.h +++ b/src/devices/cpu/mb86235/mb86235d.h @@ -32,7 +32,7 @@ private: void dasm_control(std::ostream &stream, uint32_t pc, uint64_t opcode); void dasm_double_xfer1(std::ostream &stream, uint64_t opcode); void dasm_xfer1(std::ostream &stream, uint64_t opcode); - void dasm_double_xfer2_field(std::ostream &stream, int sd, uint32_t field); + void dasm_double_xfer2_field(std::ostream &stream, int sd, bool isbbus, uint32_t field); void dasm_double_xfer2(std::ostream &stream, uint64_t opcode); void dasm_xfer2(std::ostream &stream, uint64_t opcode); void dasm_xfer3(std::ostream &stream, uint64_t opcode); diff --git a/src/devices/cpu/mb86235/mb86235ops.cpp b/src/devices/cpu/mb86235/mb86235ops.cpp index 136f0fddaa1..2be53e6224b 100644 --- a/src/devices/cpu/mb86235/mb86235ops.cpp +++ b/src/devices/cpu/mb86235/mb86235ops.cpp @@ -10,3 +10,1287 @@ #include "emu.h" #include "mb86235.h" + +/********************* + * + * Misc helpers + * + ********************/ + +#define AD 0x00000001 +#define AU 0x00000002 +#define AV 0x00000004 +#define AZ 0x00000008 +#define AN 0x00000010 +#define ZC 0x00000100 +#define IL 0x00000200 +#define NR 0x00000400 +#define ZD 0x00000800 +#define RP 0x00004000 +#define LP 0x00008000 +#define MD 0x00010000 +#define MU 0x00020000 +#define MV 0x00040000 +#define MZ 0x00080000 +#define MN 0x00100000 +#define OFF 0x01000000 +#define OFE 0x02000000 +#define IFF 0x04000000 +#define IFE 0x08000000 +#define F0 0x10000000 +#define F1 0x20000000 +#define F2 0x40000000 + +#define FSET(f) m_core->st|=(f) +#define FCLR(f) m_core->st&=~(f) + +void mb86235_device::handle_single_step_execution() +{ + if(m_core->cur_fifo_state.has_stalled == true) + return; + + // repeat opcode + if(m_core->st & RP) + { + --m_core->rpc; + if(m_core->rpc == 1) + FCLR(RP); + } + else // normal operation + m_core->pc ++; +} + +inline void mb86235_device::increment_pwp() +{ + m_core->pwp++; + if(m_core->pwp >= 24) + m_core->pwp = 0; +} + +void mb86235_device::increment_prp() +{ + m_core->prp ++; + if(m_core->prp >= 24) + m_core->prp = 0; +} + +void mb86235_device::decrement_prp() +{ + if(m_core->prp == 0) + m_core->prp = 24; + + m_core->prp --; +} + +void mb86235_device::zero_prp() +{ + m_core->prp = 0; +} + +inline uint32_t mb86235_device::decode_ea(uint8_t mode, uint8_t rx, uint8_t ry, uint16_t disp, bool isbbus) +{ + uint32_t res; + + switch(mode) + { + case 0x00: // ARx + return m_core->ar[rx]; + case 0x01: // ARx ++ + res = m_core->ar[rx]; + m_core->ar[rx]++; + m_core->ar[rx]&=0x3fff; + return res; + case 0x03: // ARx + disp12 + res = m_core->ar[rx]; + m_core->ar[rx]+=disp; + m_core->ar[rx]&=0x3fff; + return res; + case 0x04: // ARx + ARy + return m_core->ar[rx]+m_core->ar[ry]; + case 0x05: // ARx + ARy++ + res = m_core->ar[ry]; + 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]; + m_core->ar[ry]+=disp; + m_core->ar[ry]&=0x3fff; + return m_core->ar[rx]+res; + case 0x0a: // ARx + disp12 + return m_core->ar[rx]+disp; + case 0x0b: // ARx + ARy + disp12 + return m_core->ar[rx]+m_core->ar[ry]+disp; + } + + + fatalerror("TGPx4: unemulated decode_ea type %02x executed at pc=%08x\n",mode,m_core->ppc); + return 0; +} + +inline uint32_t mb86235_device::read_bus(bool isbbus, uint32_t addr) +{ + return isbbus == true ? m_datab->read_dword(addr & 0x3ff) : m_dataa->read_dword(addr & 0x3ff); +} + +inline void mb86235_device::write_bus(bool isbbus, uint32_t addr, uint32_t data) +{ + if(isbbus == true) + m_datab->write_dword(addr & 0x3ff,data); + else + m_dataa->write_dword(addr & 0x3ff,data); +} + + +/********************* + * + * Instruction fetch + * + ********************/ + +void mb86235_device::execute_op(uint32_t h, uint32_t l) +{ + switch((h >> 29) & 7) + { + case 0: + do_alu2(h,l); + do_trans2_1(h,l); + break; + case 1: + do_alu2(h,l); + do_trans1_1(h,l); + break; + case 2: + do_alu2(h,l); + do_control(h,l); + break; + case 4: + do_alu1(h,l); + do_trans2_2(h,l); + break; + case 5: + do_alu1(h,l); + do_trans1_2(h,l); + break; + case 6: + do_alu1(h,l); + do_control(h,l); + break; + case 7: + do_trans1_3(h,l); + break; + default: + fatalerror("TGPx4: illegal opcode type %02x executed at pc=%08x\n",(h >> 29) & 7,m_core->ppc); + } +} + +/********************* + * + * ALU + * + ********************/ + +inline void mb86235_device::set_alu_flagsd(uint32_t val) +{ + FCLR(AN|AZ); + if(val&0x80000000) FSET(AN); + if(val==0) FSET(AZ); +} + +inline void mb86235_device::set_alu_flagsf(float val) +{ + FCLR(AN|AZ); + if(val<0.0) FSET(AN); + if(val==0.0) FSET(AZ); +} + +inline void mb86235_device::set_alu_flagsi(int val) +{ + FCLR(AN|AZ); + if(val<0) FSET(AN); + if(val==0) FSET(AZ); +} + +inline uint32_t mb86235_device::get_prx(uint8_t which) +{ + uint32_t res = m_core->pr[m_core->prp]; + switch(which & 7) + { + case 0: break; + case 1: increment_prp(); break; + case 2: decrement_prp(); break; + case 3: zero_prp(); break; + default: fatalerror("TGPx4: unimplemented get_prx %02x at pc=%08x\n",which & 7,m_core->ppc); break; + } + + return res; +} + +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]; +} + +inline uint32_t mb86235_device::get_constint(uint8_t which) +{ + switch(which & 7) + { + case 0: // A0 + return 0; + case 1: // A1 + return 1; + case 2: // A2 + return 0xffffffff; // -1 + } + + fatalerror("TGPx4: illegal get_constint %02x at pc=%08x\n",which,m_core->ppc); + return 0; +} + +inline uint32_t mb86235_device::get_alureg(uint8_t which, bool isfloatop) +{ + switch(which >> 3) + { + case 0: // AAx + return m_core->aa[which & 7]; + case 1: // ABx + return m_core->ab[which & 7]; + case 2: // PRx + return get_prx(which & 7); + case 3: // constants + return (isfloatop == true) ? get_constfloat(which & 7) : get_constint(which & 7); + } + + fatalerror("TGPx4: unimplemented get_alureg %02x at pc=%08x\n",which,m_core->ppc); + return 0; +} + +inline uint32_t mb86235_device::get_mulreg(uint8_t which, bool isfloatop) +{ + switch(which >> 3) + { + case 0: // MAx + return m_core->ma[which & 7]; + case 1: // MBx + return m_core->mb[which & 7]; + case 2: // PRx + return get_prx(which & 7); + case 3: // constants + return (isfloatop == true) ? get_constfloat(which & 7) : get_constint(which & 7); + } + + fatalerror("TGPx4: unimplemented get_mulreg %02x at pc=%08x\n",which,m_core->ppc); + return 0; +} + +inline void mb86235_device::set_alureg(uint8_t which, uint32_t value) +{ + switch(which >> 3) + { + case 0: // MAx + m_core->ma[which & 7] = value; + break; + case 1: // MBx + m_core->mb[which & 7] = value; + break; + case 2: // AAx + m_core->aa[which & 7] = value; + break; + case 3: // ABx + m_core->ab[which & 7] = value; + break; + } +} + +inline void mb86235_device::decode_aluop(uint8_t opcode, uint32_t src1, uint32_t src2, uint8_t imm, uint8_t dst_which) +{ + switch(opcode) + { + // floating point ops + case 0x00: // FADD + case 0x01: // FADDZ + case 0x02: // FSUB + case 0x03: // FSUBZ + { + float f1 = (float)src1; + float f2 = (float)src2; + float d; + + if(opcode & 2) + d = f2-f1; + else + d = f1+f2; + + if(opcode & 1) + { + FCLR(ZC); + if(d < 0.0) + { + FSET(ZC); + d = 0.0f; + } + } + set_alu_flagsf(d); + set_alureg(dst_which,d); + break; + } + + case 0x04: // FCMP + case 0x06: // FABC + { + float f1 = (float)src1; + float f2 = (float)src2; + float 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; + d = fabs(d); + set_alu_flagsf(d); + set_alureg(dst_which,d); + break; + } + + case 0x07: // NOP + break; + + case 0x08: // FEA + case 0x09: // FES + { + uint32_t exp = (src1>>23)&0xff; + src1 &= 0x7f800000; + if(opcode & 1) + exp -= imm; + else + exp += imm; + exp &= 0xff; + src1 |= exp<<23; + set_alu_flagsd(src1); + set_alureg(dst_which,src1); + break; + } + + case 0x0a: // FRCP + { + float f = (float)src1; + FCLR(ZD); + if(f == 0.0f) + FSET(ZD); + f = 1.0/f; + set_alu_flagsf(f); + set_alureg(dst_which,f); + break; + } + + case 0x0b: // FRSQ + { + float f = (float)src1; + FCLR(NR); + if(f <= 0.0f) + FSET(NR); + f = 1.0/sqrtf(f); + set_alu_flagsf(f); + set_alureg(dst_which,f); + break; + } + + case 0x0c: // FLOG + { + float f = (float)src1; + FCLR(IL); + if(f <= 0.0f) + FSET(IL); + f = log(f)/0.301030f; // log2 + set_alu_flagsf(f); + set_alureg(dst_which,f); + break; + } + + case 0x0d: // CIF + { + int v = (((int)src1) << 0) >> 0; + float f = (float)v; + set_alu_flagsf(f); + set_alureg(dst_which,f); + break; + } + + case 0x0e: // CFI + { + float f = (float)src1; + int v = (int)f; + set_alu_flagsi(v); + set_alureg(dst_which,v); + break; + } + + case 0x0f: // CFIB + { + float f = (float)src1; + uint32_t res; + FCLR(AU); + res = (uint32_t)f; + if(f<0) + { + FSET(AU); + res=0; + }; + FCLR(AZ); + if(res==0) + FSET(AZ); + FCLR(AV); + if(res>0xff) + { + FSET(AV); + res=0xff; + } + set_alureg(dst_which,res); + break; + } + + // integer ops + case 0x10: // ADD + case 0x11: // ADDZ + case 0x12: // SUB + case 0x13: // SUBZ + { + int v1 = (((int)src1) << 0) >> 0; + int v2 = (((int)src2) << 0) >> 0; + int res; + + if(opcode & 2) + res = v2-v1; + else + res = v1+v2; + + if(opcode & 1) + { + FCLR(ZC); + if(res < 0) + { + FSET(ZC); + res = 0; + } + } + set_alu_flagsi(res); + set_alureg(dst_which,(uint32_t)res); + break; + } + + case 0x14: // CMP + { + int v1 = (((int)src1) << 0) >> 0; + int v2 = (((int)src2) << 0) >> 0; + int res = v2-v1; + set_alu_flagsi(res); + break; + } + + case 0x15: // ABS + { + src1 &= 0x7fffffff; + set_alu_flagsd(src1); + set_alureg(dst_which,src1); + break; + } + + case 0x16: // ATR + case 0x17: // ATRZ + { + if(opcode & 1) + { + FCLR(ZC); + if(src1&0x80000000) + { + FSET(ZC); + src1=0; + } + } + set_alureg(dst_which,src1); + break; + } + + // logical ops + case 0x18: // AND + { + uint32_t res = src1 & src2; + set_alu_flagsd(res); + set_alureg(dst_which,res); + break; + } + + case 0x19: // OR + { + uint32_t res = src1 | src2; + set_alu_flagsd(res); + set_alureg(dst_which,res); + break; + } + + case 0x1a: // XOR + { + uint32_t res = src1 ^ src2; + set_alu_flagsd(res); + set_alureg(dst_which,res); + break; + } + + case 0x1b: // NOT + { + uint32_t res = ~src1; + set_alu_flagsd(res); + set_alureg(dst_which,res); + break; + } + + case 0x1c: // LSR + { + uint32_t res = src1 >> imm; + set_alu_flagsd(res); + set_alureg(dst_which,res); + break; + } + + case 0x1d: // LSL + { + uint32_t res = src1 << imm; + set_alu_flagsd(res); + set_alureg(dst_which,res); + break; + } + + case 0x1e: // ASR + { + int res = ((((int)src1) << 0) >> 0) >> imm; + set_alu_flagsi(res); + set_alureg(dst_which,(uint32_t)res); + break; + } + + case 0x1f: // ASL + { + int res = ((((int)src1) << 0) >> 0) << imm; + set_alu_flagsd(res); + set_alureg(dst_which,(uint32_t)res); + break; + } + + default: + fatalerror("TGPx4: unimplemented decode_aluop %02x at pc=%08x\n",opcode,m_core->ppc); + } +} + +void mb86235_device::decode_mulop(bool isfmul, uint32_t src1, uint32_t src2, uint8_t dst_which) +{ + if(isfmul == true) // FMUL + { + float f1 = (float)src1; + float f2 = (float)src2; + float 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); + } + else // MUL + { + int v1 = (int)src1; + int v2 = (int)src2; + int res = v1*v2; + FCLR(MN|MZ); + if(res<0) FSET(MN); + if(res==0) FSET(MZ); + set_alureg(dst_which,(uint32_t)res); + } +} + +#define GETAOP(x) ((x>>24)&0x1f) +#define GETAI1(x) ((x>>20)&0xf) +#define GETAI2(x) ((x>>15)&0x1f) +#define GETAO(x) ((x>>10)&0x1f) + +#define GETMOP(x) ((x>>9)&0x1) +#define GETMI1(x) ((x>>5)&0x0f) +#define GETMI2(x) ((x>>0)&0x1f) +#define GETMO(x) ((x>>27)&0x1f) + +inline bool mb86235_device::get_alu_second_src(uint8_t which) +{ + if((which & 0x1c) == 0x1c) // logical ops + return false; + + if((which & 0x1e) == 0x16) // ATRx + return false; + + if((which & 0x0f) == 0x05) // ABS/FABS + return false; + + if((which & 0x18) == 0x08) // floating point ops + return false; + + return true; +} + +void mb86235_device::do_alu1(uint32_t h, uint32_t l) +{ + if(m_core->cur_fifo_state.has_stalled == true) + return; + + if(h&(1<<9)) // ALU + { + uint8_t opcode = GETAOP(h); + uint32_t alusrc1 = get_alureg(GETAI1(h),false); + uint32_t alusrc2; + if(get_alu_second_src(opcode) == true) + alusrc2 = get_alureg(GETAI2(h),(opcode & 0x10) == 0); + else + alusrc2 = 0; + decode_aluop(opcode, alusrc1, alusrc2, GETAI2(h), GETAO(h)); + } + else // MUL + { + bool opcode = GETAOP(h) != 0; + uint32_t mulsrc1 = get_mulreg(GETAI1(h),false); + uint32_t mulsrc2 = get_mulreg(GETAI2(h),opcode); + decode_mulop(opcode, mulsrc1, mulsrc2, GETAO(h)); + } +} + +void mb86235_device::do_alu2(uint32_t h, uint32_t l) +{ + if(m_core->cur_fifo_state.has_stalled == true) + return; + + // ALU + uint8_t opcode = GETAOP(h); + uint32_t alusrc1 = get_alureg(GETAI1(h),false); + uint32_t alusrc2; + if(get_alu_second_src(opcode) == true) + alusrc2 = get_alureg(GETAI2(h),(opcode & 0x10) == 0); + else + alusrc2 = 0; + decode_aluop(opcode, alusrc1, alusrc2, GETAI2(h), GETAO(h)); + + // MUL + opcode = GETMOP(h); + alusrc1 = get_mulreg(GETMI1(h),false); + alusrc2 = get_mulreg(GETMI2(h),opcode != 0); + decode_mulop(opcode != 0, alusrc1, alusrc2, GETMO(l)); +} + +/********************* + * + * Transfer types + * + ********************/ + +#include "debugger.h" + +inline uint32_t mb86235_device::get_transfer_reg(uint8_t which) +{ + switch(which >> 3) + { + case 0: // MAx + return m_core->ma[which & 7]; + case 1: // AAx + return m_core->aa[which & 7]; + case 2: + switch(which & 7) + { + case 0: return m_core->eb; + //case 1: m_core->ebu = value; break; + //case 2: m_core->ebl = value; break; + case 3: return m_core->eo; + case 4: return m_core->sp; + case 5: return m_core->st; + case 6: return m_core->mod; + case 7: return m_core->lpc; + default: + fatalerror("TGPx4: unimplemented set_transfer_reg %02x at pc=%08x\n",which,m_core->ppc); + break; + } + + break; + case 3: // ARx + return m_core->ar[which & 7]; + case 4: // MBx + return m_core->mb[which & 7]; + case 5: // ABx + return m_core->ab[which & 7]; + case 6: + { + switch(which & 7) + { + case 0: // PRx + return m_core->pr[m_core->prp]; + + case 1: // FI + { + FCLR(IFE); + if(is_fifoin_empty() == true) + { + FSET(IFE); + m_core->cur_fifo_state.has_stalled = true; + //if((m_core->st & RP) == 0) + m_core->cur_fifo_state.pc = m_core->ppc; + //else + // fatalerror("check me %08x\n",m_core->ppc); + + return 0; + } + + m_core->cur_fifo_state.has_stalled = false; + uint32_t res = (uint32_t)m_core->fifoin.data[m_core->fifoin.rpos]; + + m_core->fifoin.rpos++; + m_core->fifoin.rpos &= FIFOIN_SIZE-1; + m_core->fifoin.num--; + + return res; + } + } + } + } + + fatalerror("TGPx4: unimplemented get_transfer_reg %02x at pc=%08x\n",which,m_core->ppc); + return 0; +} + +inline void mb86235_device::set_transfer_reg(uint8_t which, uint32_t value) +{ + switch(which >> 3) + { + case 0: // MAx + m_core->ma[which & 7] = value; + break; + case 1: // AAx + m_core->aa[which & 7] = value; + break; + case 2: + switch(which & 7) + { + case 0: m_core->eb = value; break; + //case 1: m_core->ebu = value; break; + //case 2: m_core->ebl = value; break; + case 3: m_core->eo = value; break; + case 4: m_core->sp = value; break; + case 5: m_core->st = value; break; + case 6: m_core->mod = value; break; + case 7: m_core->lpc = value; break; + default: + fatalerror("TGPx4: unimplemented set_transfer_reg %02x at pc=%08x\n",which,m_core->ppc); + break; + } + + break; + case 3: // ARx + m_core->ar[which & 7] = value & 0x3fff; + break; + case 4: // MBx + m_core->mb[which & 7] = value; + break; + case 5: // ABx + m_core->ab[which & 7] = value; + break; + case 6: + switch(which & 7) + { + case 0: + m_core->pr[m_core->pwp] = value; + if(m_core->cur_fifo_state.has_stalled == false) + increment_pwp(); + break; + case 2: // FO0 + FCLR(OFF); + if(is_fifoout0_full() == true) + { + FSET(OFF); + m_core->cur_fifo_state.has_stalled = true; + //if((m_core->st & RP) == 0) + m_core->cur_fifo_state.pc = m_core->ppc; + //else + // fatalerror("check me (writes)"); + return; + } + + m_core->cur_fifo_state.has_stalled = false; + m_core->fifoout0.data[m_core->fifoin.wpos] = value; + + m_core->fifoout0.wpos++; + m_core->fifoout0.wpos &= FIFOIN_SIZE-1; + m_core->fifoout0.num++; + break; + case 4: m_core->pdr = value; break; + case 5: m_core->ddr = value; break; + case 6: + if(value >= 24) + fatalerror("TGPx4: attempting to set prp with a %02x at pc=%08x\n",value,m_core->ppc); + + m_core->prp = value; + break; + case 7: + if(value >= 24) + fatalerror("TGPx4: attempting to set pwp with a %02x at pc=%08x\n",value,m_core->ppc); + + m_core->pwp = value; + break; + default: + fatalerror("TGPx4: unimplemented set_transfer_reg %02x at pc=%08x\n",which,m_core->ppc); + break; + } + + break; + default: + fatalerror("TGPx4: unimplemented set_transfer_reg dst %02x at pc=%08x\n",which,m_core->ppc); + break; + } +} + +// double transfer type 1 +void mb86235_device::do_trans2_1(uint32_t h, uint32_t l) +{ + fatalerror("TGPx4: unimplemented trans2_1 op %08x %08x at pc=%08x\n",h,l,m_core->ppc); +} + +// transfer type 1 +void mb86235_device::do_trans1_1(uint32_t h, uint32_t l) +{ + uint8_t sr,dr; + uint32_t res; + + if(l & (1<<26)) //External transfer + { + if(l & (1<<25)) // ext -> int + { + dr = (l >> 12) & 0x7f; + uint32_t addr = m_core->eb+m_core->eo; + uint8_t disp_offs = (l >> 19) & 0x3f; + + res = m_dataa->read_dword(addr); + if(dr & 0x40) + { + bool isbbus = (dr & 0x20) == 0x20; + addr = decode_ea(l & 0xf,dr & 7,(l >> 4) & 7, (l >> 7) & 0x1f,isbbus); + write_bus(isbbus,addr,res); + } + else + set_transfer_reg(dr,res); + + if(disp_offs & 0x20) + m_core->eo -= disp_offs & 0x1f; + else + m_core->eo += disp_offs & 0x1f; + } + else // int -> ext + { + fatalerror("TGPx4: unimplemented trans1_1 int->ext %08x %08x at pc=%08x\n",h,l,m_core->ppc); + } + } + else + { + sr = (l>>19) & 0x7f; + dr = (l>>12) & 0x7f; + + if(sr & 0x40) + { + if(sr == 0x58) + fatalerror("TGPx4: unimplemented trans1_1 sr %08x dr %08x at pc=%08x\n",sr,dr,m_core->ppc); + else + { + bool isbbus = (sr & 0x20) == 0x20; + uint32_t addr = decode_ea(l & 0xf,sr & 7,(l >> 4) & 7, (l >> 7) & 0x1f,isbbus); + res = read_bus(isbbus,addr); + } + } + else + res = get_transfer_reg(sr); + + if(dr & 0x40) + { + if(dr == 0x58) + fatalerror("TGPx4: illegal do_trans1_1 dr == 0x58 at pc=%08x\n",m_core->ppc); + + bool isbbus = (dr & 0x20) == 0x20; + uint32_t addr = decode_ea(l & 0xf,dr & 7,(l >> 4) & 7, (l >> 7) & 0x1f,isbbus); + write_bus(isbbus,addr,res); + } + else + set_transfer_reg(dr,res); + } +} + +// double transfer type 2 +void mb86235_device::do_trans2_2(uint32_t h, uint32_t l) +{ + uint8_t sda = (h >> 6) & 3; + uint8_t sdb = (l >> 18) & 3; + + // A bus + switch(sda) + { + // reg -> reg + case 0: + { + uint8_t as = (h >> 1) & 0x1f; + uint8_t ada= (l >> 28) & 0xf; + if(h&1) + ada|=0x10; + + set_transfer_reg(ada,get_transfer_reg(as)); + break; + } + default: + fatalerror("TGPx4: unimplemented trans2_2 SDA %08x at pc=%08x\n",sda,m_core->ppc); + break; + } + + // B bus + switch(sdb) + { + // reg -> reg + case 0: //reg->reg + { + uint8_t bs = (l >> 13) & 0x1f; + uint8_t bd = (l >> 8) & 0xf; + set_transfer_reg(bd|0x20,get_transfer_reg(bs|0x20)); + break; + } + + default: + fatalerror("TGPx4: unimplemented trans2_2 SDB %08x at pc=%08x\n",sdb,m_core->ppc); + break; + } +} + +// transfer type 2 +void mb86235_device::do_trans1_2(uint32_t h, uint32_t l) +{ + uint8_t sr, dr; + uint32_t res; + + if(h & 1<<6) // external transfer + { + if(h & 1<<5) // ext->int + { + dr = (l >> 24) & 0x7f; + uint32_t addr = m_core->eb+m_core->eo; + uint8_t disp_offs = (h << 1) & 0x3e; + uint32_t res; + if(l&0x80000000) + disp_offs |= 1; + + res = m_dataa->read_dword(addr); + if(dr & 0x40) + { + bool isbbus = (dr & 0x20) == 0x20; + addr = decode_ea(l & 0xf,dr & 7,(l >> 4) & 7, (l >> 7) & 0xfff,isbbus); + write_bus(isbbus,addr,res); + } + else + set_transfer_reg(dr,res); + + if(disp_offs & 0x20) + m_core->eo -= disp_offs & 0x1f; + else + m_core->eo += disp_offs & 0x1f; + } + else // int->ext + { + sr = (l >> 24) & 0x7f; + uint32_t addr = m_core->eb+m_core->eo; + uint8_t disp_offs = (h << 1) & 0x3e; + if(l&0x80000000) + disp_offs |= 1; + + if(sr & 0x40) + fatalerror("TGPx4: unimplemented int->ext sr %02x at pc=%08x\n",sr,m_core->ppc); + else + res = get_transfer_reg(sr); + + m_dataa->write_dword(addr,res); + if(disp_offs & 0x20) + m_core->eo -= disp_offs & 0x1f; + else + m_core->eo += disp_offs & 0x1f; + } + } + else + { + sr = (h << 1) &0x7e; + dr = (l >> 24) &0x7f; + if(l & 0x80000000) + sr|=1; + + if(sr & 0x40) + { + 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); + + if(dr & 0x40) + { + if(dr == 0x58) + fatalerror("TGPx4: illegal do_trans1_2 dr == 0x58 at pc=%08x\n",m_core->ppc); + + bool isbbus = (dr & 0x20) == 0x20; + uint32_t addr = decode_ea(l & 0xf,dr & 7,(l >> 4) & 7, (l >> 7) & 0x3fff,isbbus); + write_bus(isbbus,addr,res); + } + else + set_transfer_reg(dr,res); + } +} + +// transfer type 3 +void mb86235_device::do_trans1_3(uint32_t h, uint32_t l) +{ + uint8_t dr = (l >> 19) & 0x7f; + uint32_t imm = (l >> 27) & 0x1f; + imm|= (h & 0x7ffffff)<<5; + + if(dr & 0x40) + { + bool isbbus = (dr & 0x20) == 0x20; + uint32_t addr = decode_ea(l & 0xf,dr & 7,(l >> 4) & 7, (l >> 7) & 0xfff,isbbus); + write_bus(isbbus,addr,imm); + } + else // direct imm reg + set_transfer_reg(dr,imm); +} + +/********************* + * + * Control + * + ********************/ + +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); +} + +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); + + return m_core->pcs[m_core->pcp]; +} + +inline uint32_t mb86235_device::do_control_dst(uint32_t l) +{ + switch((l>>12)&0xf) + { + case 0: // absolute immediate + return l & 0xfff; + case 2: // absolute register AR + return m_core->ar[(l >> 6) & 7]; + case 4: // absolute register AAx / ABx + return (l & 1 << 11) ? m_core->ab[(l >> 6) & 7] : m_core->aa[(l >> 6) & 7]; + default: + fatalerror("TGPx4: unimplemented do_control_dst op mode %08x at pc=%08x\n",(l>>12) & 0xf,m_core->ppc); + } + + return 0; +} + +inline void mb86235_device::set_mod(uint16_t mod1, uint16_t mod2) +{ + m_core->mod &= ~mod1; + m_core->mod |= mod2; +} + +inline bool mb86235_device::decode_branch_jump(uint8_t which) +{ + // test, should be 22 + if(which < 14) + { + const uint32_t condition_table[22] = {MN, MZ, MV, MU, ZD, NR, IL, ZC, + AN, AZ, AV, AU, MD, AD, F0, F1, + F2,IFF,IFE,OFF,OFE, 0}; + + return (m_core->st & condition_table[which]) != 0; + } + + fatalerror("TGPx4: unimplemented decode_branch_jump mode %08x at pc=%08x\n",which,m_core->ppc); + return false; +} + +void mb86235_device::do_control(uint32_t h, uint32_t l) +{ + uint32_t cop = (l >> 22) & 0x1f; + uint32_t ef1 = (l >> 16) & 0x3f; + uint16_t ef2 = l & 0xffff; + + switch(cop) + { + case 0x00: // NOP + break; + case 0x01: // REP + if(ef1 == 0x3f) + m_core->rpc = m_core->ar[(ef2 >> 13) & 7]; + else + m_core->rpc = ef2; + + FSET(RP); // set repeat flag + break; + case 0x02: // SETL + if(ef1 == 0x3f) + m_core->lpc = m_core->ar[(ef2 >> 13) & 7]; + else + m_core->lpc = ef2; + + FSET(LP); // set repeat flag + break; + case 0x03: // CLRF + if(ef1 & 1) // clear fifo in (CLRFI) + { + m_core->fifoin.wpos = 0; + m_core->fifoin.rpos = 0; + m_core->fifoin.num = 0; + FSET(IFE); + FCLR(IFF); + } + if(ef1 & 2) // clear fifo0/1 out (CLRFO) + { + m_core->fifoout0.wpos = 0; + m_core->fifoout0.rpos = 0; + m_core->fifoout0.num = 0; + m_core->fifoout1.wpos = 0; + m_core->fifoout1.rpos = 0; + m_core->fifoout1.num = 0; + FSET(OFE); + FCLR(OFF); + } + break; + case 0x04: // PUSH + m_core->sp --; + m_core->sp &= 0x3ff; + m_datab->write_dword(m_core->sp,get_transfer_reg((ef2>>6) & 0x3f)); + break; + case 0x05: // POP + set_transfer_reg((ef2>>6) & 0x3f, m_datab->read_dword(m_core->sp)); + m_core->sp ++; + m_core->sp &= 0x3ff; + break; + case 0x08: // SETM + set_mod(0xffff,ef2); + break; + case 0x09: // SETMCBSA + set_mod(0x7000,ef2); + break; + case 0x0a: // SETMCBSB + set_mod(0x0e00,ef2); + break; + case 0x0b: // SETMRF + set_mod(0x0080,ef2); + break; + case 0x0c: // SETMRDY + set_mod(0x0010,ef2); + break; + case 0x0d: // SETMWAIT + set_mod(0x0007,ef2); + break; + + // control flow + case 0x10: // DBcc + { + bool result = decode_branch_jump(ef1); + if(result == true) + { + m_core->delay_slot = true; + m_core->delay_pc = do_control_dst(l); + } + break; + } + case 0x11: // DBNcc + { + bool result = decode_branch_jump(ef1); + if(result == false) + { + m_core->delay_slot = true; + m_core->delay_pc = do_control_dst(l); + } + break; + } + case 0x12: // DJMP + { + m_core->delay_slot = true; + m_core->delay_pc = do_control_dst(l); + break; + } + case 0x13: // DBLP + { + if(m_core->st & LP) + { + m_core->delay_slot = true; + // relative addressing only + m_core->delay_pc = m_core->pc + (l & 0xfff); + m_core->delay_pc&= 0xfff; + } + + --m_core->lpc; + if(m_core->lpc == 1) + FCLR(LP); + break; + } + case 0x18: // DCcc + { + bool result = decode_branch_jump(ef1); + if(result == true) + { + m_core->delay_slot = true; + m_core->delay_pc = do_control_dst(l); + push_pc(m_core->pc+1); + } + break; + } + case 0x19: // DCNcc + { + bool result = decode_branch_jump(ef1); + if(result == false) + { + m_core->delay_slot = true; + m_core->delay_pc = do_control_dst(l); + push_pc(m_core->pc+1); + } + break; + } + case 0x1a: // DCALL + m_core->delay_slot = true; + m_core->delay_pc = do_control_dst(l); + push_pc(m_core->pc+1); + break; + case 0x1b: // DRET + m_core->delay_slot = true; + m_core->delay_pc = pop_pc(); + break; + default: + fatalerror("TGPx4: unimplemented control op %08x at pc=%08x\n",cop,m_core->ppc); + } +} + + \ No newline at end of file diff --git a/src/mame/drivers/model2.cpp b/src/mame/drivers/model2.cpp index 3c13696f637..a0dd627ba87 100644 --- a/src/mame/drivers/model2.cpp +++ b/src/mame/drivers/model2.cpp @@ -553,7 +553,7 @@ WRITE32_MEMBER(model2_state::analog_2b_w) } -READ32_MEMBER(model2_state::fifoctl_r) +READ32_MEMBER(model2_state::fifo_control_2a_r) { uint32_t r = 0; @@ -563,7 +563,7 @@ READ32_MEMBER(model2_state::fifoctl_r) } // #### 1 if fifo empty, zerogun needs | 0x04 set - // TODO: 0x04 is probably fifo full, zeroguna stalls with a fresh nvram with that enabled! + // TODO: 0x04 is probably fifo full, zeroguna stalls with a fresh nvram with that enabled? return r; // return r | 0x04; } @@ -865,9 +865,18 @@ WRITE32_MEMBER(model2_state::copro_function_port_w) copro_fifoin_push(machine().device("tgp"), d,offset,mem_mask); else if (m_dsp_type == DSP_TYPE_TGPX4) { - if (m_tgpx4->is_fifoin_full()) - printf("trying to push to full fifo! (function port)\n"); + m_maincpu->i960_noburst(); + if (m_tgpx4->is_fifoin_full()) + { + //fatalerror("model2.cpp: unsupported i960->tgpx4 fifo full"); + /* Writing to full FIFO causes the i960 to enter wait state */ + m_maincpu->i960_stall(); + /* spin the main cpu and let the TGP catch up */ + m_maincpu->spin_until_time(attotime::from_usec(1)); + return; + } + m_tgpx4->fifoin_w(d); } } @@ -888,8 +897,9 @@ READ32_MEMBER(model2_state::copro_fifo_r) /* Reading from empty FIFO causes the i960 to enter wait state */ downcast(*m_maincpu).i960_stall(); /* spin the main cpu and let the TGP catch up */ - m_maincpu->spin_until_time(attotime::from_usec(100)); - printf("stalled\n"); + m_maincpu->spin_until_time(attotime::from_usec(1)); + + return 0x00884000+offset*4; } else { @@ -899,6 +909,11 @@ READ32_MEMBER(model2_state::copro_fifo_r) return 0; } +READ32_MEMBER(model2c_state::fifo_control_2c_r) +{ + return (m_tgpx4->is_fifoout0_empty() == true) ? 1 : 0; +} + WRITE32_MEMBER(model2_state::copro_fifo_w) { if (m_coproctl & 0x80000000) @@ -939,13 +954,15 @@ WRITE32_MEMBER(model2_state::copro_fifo_w) copro_fifoin_push(machine().device("tgp"), data,offset,mem_mask); else if (m_dsp_type == DSP_TYPE_TGPX4) { + m_maincpu->i960_noburst(); + if (m_tgpx4->is_fifoin_full()) { + //fatalerror("model2.cpp: unsupported i960->tgpx4 fifo full"); /* Writing to full FIFO causes the i960 to enter wait state */ m_maincpu->i960_stall(); /* spin the main cpu and let the TGP catch up */ - m_maincpu->spin_until_time(attotime::from_usec(100)); - printf("write stalled\n"); + m_maincpu->spin_until_time(attotime::from_usec(1)); } else { @@ -1393,7 +1410,7 @@ void model2_state::model2_base_mem(address_map &map) map(0x00900000, 0x0091ffff).mirror(0x60000).ram().share("bufferram"); - map(0x00980004, 0x00980007).r(this, FUNC(model2_state::fifoctl_r)); + map(0x00980004, 0x00980007).r(this, FUNC(model2_state::fifo_control_2a_r)); map(0x0098000c, 0x0098000f).rw(this, FUNC(model2_state::videoctl_r), FUNC(model2_state::videoctl_w)); map(0x00980030, 0x0098003f).r(this, FUNC(model2_state::tgpid_r)); @@ -1475,7 +1492,7 @@ READ8_MEMBER(model2_state::virtuacop_lightgun_offscreen_r) } /* Apparently original Model 2 doesn't have fifo control? */ -READ32_MEMBER(model2o_state::fifoctrl_r) +READ32_MEMBER(model2o_state::fifo_control_2o_r) { return 0xffffffff; } @@ -1509,7 +1526,7 @@ void model2o_state::model2o_mem(address_map &map) map(0x00884000, 0x00887fff).rw(this, FUNC(model2o_state::copro_fifo_r), FUNC(model2o_state::copro_fifo_w)); map(0x00980000, 0x00980003).rw(this, FUNC(model2o_state::copro_ctl1_r), FUNC(model2o_state::copro_ctl1_w)); - map(0x00980004, 0x00980007).r(this, FUNC(model2o_state::fifoctrl_r)); + map(0x00980004, 0x00980007).r(this, FUNC(model2o_state::fifo_control_2o_r)); map(0x00980008, 0x0098000b).w(this, FUNC(model2o_state::geo_ctl1_w)); map(0x009c0000, 0x009cffff).rw(this, FUNC(model2o_state::model2_serial_r), FUNC(model2o_state::model2_serial_w)); @@ -1692,6 +1709,7 @@ void model2c_state::model2c_crx_mem(address_map &map) map(0x00884000, 0x00887fff).rw(this, FUNC(model2c_state::copro_fifo_r), FUNC(model2c_state::copro_fifo_w)); map(0x00980000, 0x00980003).rw(this, FUNC(model2c_state::copro_ctl1_r), FUNC(model2c_state::copro_ctl1_w)); + map(0x00980004, 0x00980007).r(this, FUNC(model2c_state::fifo_control_2c_r)); map(0x00980008, 0x0098000b).w(this, FUNC(model2c_state::geo_ctl1_w)); map(0x00980014, 0x00980017).r(this, FUNC(model2c_state::copro_status_r)); map(0x009c0000, 0x009cffff).rw(this, FUNC(model2c_state::model2_serial_r), FUNC(model2c_state::model2_serial_w)); @@ -1703,6 +1721,8 @@ void model2c_state::model2c_crx_mem(address_map &map) map(0x01c00000, 0x01c0001f).r(this, FUNC(model2c_state::model2_crx_in_r)).umask32(0x00ff00ff); map(0x01c00000, 0x01c00003).w(this, FUNC(model2c_state::ctrl0_w)); + map(0x01c00008, 0x01c0000b).nopw(); + map(0x01c00010, 0x01c00013).nopw(); map(0x01c00014, 0x01c00017).w(this, FUNC(model2c_state::hotd_lightgun_w)); map(0x01c0001c, 0x01c0001f).w(this, FUNC(model2c_state::analog_2b_w)); map(0x01c80000, 0x01c80003).rw(this, FUNC(model2c_state::model2_serial_r), FUNC(model2c_state::model2_serial_w)); @@ -2745,11 +2765,17 @@ MACHINE_CONFIG_START(model2b_state::rchase2) MACHINE_CONFIG_END -ADDRESS_MAP_START(model2_state::copro_tgpx4_map) - AM_RANGE(0x00000000, 0x00007fff) AM_RAM AM_SHARE("tgpx4_program") -// AM_RANGE(0x00400000, 0x007fffff) // bufferram -// AM_RANGE(0x00800000, 0x00ffffff) // ROM data -ADDRESS_MAP_END +void model2c_state::copro_tgpx4_map(address_map &map) +{ + map(0x00000000, 0x00007fff).ram().share("tgpx4_program"); +} + +void model2c_state::copro_tgpx4_data_map(address_map &map) +{ +// map(0x00000000, 0x000003ff) internal RAM + map(0x00400000, 0x007fffff).rw(this, FUNC(model2_state::copro_tgp_buffer_r),FUNC(model2_state::copro_tgp_buffer_w)); // bufferram + map(0x00800000, 0x008fffff).rom().region("copro_data",0); // ROM data +} /* 2C-CRX */ MACHINE_CONFIG_START(model2c_state::model2c) @@ -2759,6 +2785,7 @@ MACHINE_CONFIG_START(model2c_state::model2c) MCFG_CPU_ADD("tgpx4", MB86235, 40000000) MCFG_CPU_PROGRAM_MAP(copro_tgpx4_map) + MCFG_CPU_DATA_MAP(copro_tgpx4_data_map) MCFG_MACHINE_START_OVERRIDE(model2_state,model2) MCFG_MACHINE_RESET_OVERRIDE(model2_state,model2c) @@ -3980,7 +4007,7 @@ ROM_START( dynamcopc ) /* Dynamite Cop (USA), Model 2C */ ROM_LOAD32_WORD("mpr-20791.4", 0x1800000, 0x400000, CRC(4883d0df) SHA1(b98af63e81f6c1b2766d7e96acbd1821bba000d4) ) /* Located at position 5 on 2C-CRX rom board */ ROM_LOAD32_WORD("mpr-20792.5", 0x1800002, 0x400000, CRC(47becfa2) SHA1(a333885872a64b322f3cb464a70352d73654b1b3) ) /* Located at position 6 on 2C-CRX rom board */ - ROM_REGION( 0x800000, "cpu2", ROMREGION_ERASE00 ) // TGPx4 program (COPRO sockets) + ROM_REGION( 0x800000, "copro_data", ROMREGION_ERASE00 ) // TGPx4 program (COPRO sockets) ROM_REGION( 0x2000000, "polygons", 0 ) // Models ROM_LOAD32_WORD("mpr-20799.16", 0x0000000, 0x400000, CRC(424571bf) SHA1(18a4e8d0e968fff3b645b59a0023b0ef38d51924) ) /* Located at position 17 on 2C-CRX rom board */ @@ -4137,7 +4164,7 @@ ROM_START( stcc ) /* Sega Touring Car Championship, Model 2C - Defaults to Japan ROM_COPY("main_data", 0x800000, 0xe00000, 0x100000) ROM_COPY("main_data", 0x800000, 0xf00000, 0x100000) - ROM_REGION( 0x800000, "cpu2", 0 ) // TGPx4 program + ROM_REGION( 0x800000, "copro_data", 0 ) // TGPx4 program ROM_LOAD32_WORD("mpr-19255.29", 0x000000, 0x200000, CRC(d78bf030) SHA1(e6b3d8422613d22db50cf6c251f9a21356d96653) ) ROM_LOAD32_WORD("mpr-19256.30", 0x000002, 0x200000, CRC(cb2b2d9e) SHA1(86b2b8bb6074352f72eb81e616093a1ba6f5163f) ) @@ -4202,7 +4229,7 @@ ROM_START( stccb ) /* Sega Touring Car Championship Revision B, Model 2C - Defau ROM_COPY("main_data", 0x800000, 0xe00000, 0x100000) ROM_COPY("main_data", 0x800000, 0xf00000, 0x100000) - ROM_REGION( 0x800000, "cpu2", 0 ) // TGPx4 program + ROM_REGION( 0x800000, "copro_data", 0 ) // TGPx4 program ROM_LOAD32_WORD("mpr-19255.29", 0x000000, 0x200000, CRC(d78bf030) SHA1(e6b3d8422613d22db50cf6c251f9a21356d96653) ) ROM_LOAD32_WORD("mpr-19256.30", 0x000002, 0x200000, CRC(cb2b2d9e) SHA1(86b2b8bb6074352f72eb81e616093a1ba6f5163f) ) @@ -4267,7 +4294,7 @@ ROM_START( stcca ) /* Sega Touring Car Championship Revision A, Model 2C - Defau ROM_COPY("main_data", 0x800000, 0xe00000, 0x100000) ROM_COPY("main_data", 0x800000, 0xf00000, 0x100000) - ROM_REGION( 0x800000, "cpu2", 0 ) // TGPx4 program + ROM_REGION( 0x800000, "copro_data", 0 ) // TGPx4 program ROM_LOAD32_WORD("mpr-19255.29", 0x000000, 0x200000, CRC(d78bf030) SHA1(e6b3d8422613d22db50cf6c251f9a21356d96653) ) ROM_LOAD32_WORD("mpr-19256.30", 0x000002, 0x200000, CRC(cb2b2d9e) SHA1(86b2b8bb6074352f72eb81e616093a1ba6f5163f) ) @@ -4327,7 +4354,7 @@ ROM_START( skisuprg ) /* Sega Ski Super G, Model 2C, Sega Game ID# 833-12861, RO ROM_LOAD32_WORD( "mpr-19492.9", 0x800000, 0x400000, CRC(4805318f) SHA1(dbd1359817933313c6d74d3a1450682e8ce5857a) ) ROM_LOAD32_WORD( "mpr-19493.10", 0x800002, 0x400000, CRC(39daa909) SHA1(e29e50c7fc39bd4945f993ceaa100358054efc5a) ) - ROM_REGION( 0x800000, "cpu2", 0 ) // TGPx4 program + ROM_REGION( 0x800000, "copro_data", 0 ) // TGPx4 program ROM_LOAD32_WORD( "mpr-19502.29", 0x000000, 0x400000, CRC(2212d8d6) SHA1(3b8a4da2dc00a1eac41b48cbdc322ea1c31b8b29) ) ROM_LOAD32_WORD( "mpr-19503.30", 0x000002, 0x400000, CRC(3c9cfc73) SHA1(2213485a00cef0bcef11b67f00027c4159c5e2f5) ) @@ -4372,7 +4399,7 @@ ROM_START( segawski ) /* Sega Water Ski Revision A, Model 2C, Sega Game ID# 833- ROM_COPY( "main_data", 0x1800000, 0x1e00000, 0x100000 ) ROM_COPY( "main_data", 0x1800000, 0x1f00000, 0x100000 ) - ROM_REGION( 0x800000, "cpu2", 0 ) // TGPx4 program + ROM_REGION( 0x800000, "copro_data", 0 ) // TGPx4 program ROM_LOAD32_WORD("mpr-19986.29", 0x0000000, 0x400000, CRC(4b8e26f8) SHA1(859e3788c75599295a8b57ed7852f2cbb6a2a738) ) ROM_LOAD32_WORD("mpr-19987.30", 0x0000002, 0x400000, CRC(8d5b9d38) SHA1(35f41c474af3754152aecefe81e912120823e0ff) ) @@ -4425,7 +4452,7 @@ ROM_START( hotd ) /* House of the Dead, Model 2C, Sega Game ID# 610-0396-13054, ROM_COPY( "main_data", 0x1800000, 0x1f00000, 0x100000 ) - ROM_REGION( 0x800000, "cpu2", 0 ) // TGPx4 program + ROM_REGION( 0x800000, "copro_data", 0 ) // TGPx4 program ROM_LOAD32_WORD("epr-19707.29", 0x000000, 0x080000, CRC(384fd133) SHA1(6d060378d0f801b04d12e7ee874f2fa0572992d9) ) ROM_LOAD32_WORD("epr-19706.30", 0x000002, 0x080000, CRC(1277531c) SHA1(08d3e733ba9989fcd32290634171c73f26ab6e2b) ) @@ -4974,7 +5001,7 @@ ROM_START( bel ) /* Behind Enemy Lines, Model 2C */ ROM_LOAD32_WORD("mpr-20227.5", 0xc00000, 0x200000, CRC(1277686e) SHA1(fff27006659458300001425261b944e690f1d494) ) ROM_LOAD32_WORD("mpr-20228.6", 0xc00002, 0x200000, CRC(49cb5568) SHA1(ee3273302830f3499c7d4e548b629c51e0369e8a) ) - ROM_REGION( 0x800000, "cpu2", 0 ) // TGPx4 program + ROM_REGION( 0x800000, "copro_data", 0 ) // TGPx4 program ROM_LOAD32_WORD("mpr-20236.29", 0x000000, 0x200000, CRC(8de9a3c2) SHA1(e7fde1fd509531e1002ff813163067dc0d134536) ) ROM_LOAD32_WORD("mpr-20235.30", 0x000002, 0x200000, CRC(78fa11ef) SHA1(a60deabb662e9c09f5d6342dc1a1c6045744d93f) ) @@ -5015,7 +5042,7 @@ ROM_START( overrev ) /* Over Rev Revision A, Model 2C */ ROM_LOAD32_WORD( "mpr-19994.9", 0x800000, 0x400000, CRC(e691fbd5) SHA1(b99c2f3f2a682966d792917dfcb8ed8e53bc0b7a) ) ROM_LOAD32_WORD( "mpr-19995.10", 0x800002, 0x400000, CRC(82a7828e) SHA1(4336a12a07a67f94091b4a9b491bab02c375dd15) ) - ROM_REGION( 0x800000, "cpu2", ROMREGION_ERASE00 ) // TGPx4 program (COPRO sockets) + ROM_REGION( 0x800000, "copro_data", ROMREGION_ERASE00 ) // TGPx4 program (COPRO sockets) ROM_REGION( 0x800000, "polygons", 0 ) // Models (TGP sockets) ROM_LOAD32_WORD( "mpr-19998.17", 0x000000, 0x200000, CRC(6a834574) SHA1(8be19bf42dbb157d6acde62a2018ef4c0d41aab4) ) @@ -5075,7 +5102,7 @@ ROM_START( rascot2 ) /* Royal Ascot 2, Model 2C, Rom Board : 837-12485 Com Board ROM_LOAD32_WORD("mpr-20169.9", 0x800000, 0x400000, CRC(b5be4d6b) SHA1(cfb4696506efa0e93fab35bbeb87decd83aec040) ) ROM_LOAD32_WORD("mpr-20170.10", 0x800002, 0x400000, CRC(7b05cf33) SHA1(9e392ea0c7a9f4cef76d46ad92a7cf814022c133) ) - ROM_REGION( 0x800000, "cpu2", ROMREGION_ERASE00) // TGPx4 program + ROM_REGION( 0x800000, "copro_data", ROMREGION_ERASE00) // TGPx4 program ROM_REGION( 0x2000000, "polygons", 0 ) // Models ROM_LOAD32_WORD("mpr-20173.17", 0x0000000, 0x400000, CRC(60bd684e) SHA1(893985808adb88fb54f0ca85ca23995d65360360) ) @@ -5111,7 +5138,7 @@ ROM_START( topskatr ) /* Top Skater Revision A (Export), Model 2C, Sega Game ID# ROM_LOAD32_WORD("mpr-19737.9", 0x800000, 0x400000, CRC(281a7dde) SHA1(71d5ba434328a81969bfdc71ac1160c5ff3ae9d3) ) ROM_LOAD32_WORD("mpr-19738.10", 0x800002, 0x400000, CRC(f688327e) SHA1(68c9db242ef7e8f98979e968a09e4b093bc5d470) ) - ROM_REGION( 0x800000, "cpu2", 0 ) // TGPx4 program + ROM_REGION( 0x800000, "copro_data", 0 ) // TGPx4 program ROM_LOAD32_WORD("mpr-19743.29", 0x000000, 0x200000, CRC(d41a41bf) SHA1(a5f6b24e6526d0d2ef9c526c273c018d1e0fed59) ) ROM_LOAD32_WORD("mpr-19744.30", 0x000002, 0x200000, CRC(84f203bf) SHA1(4952b764e6bf6cd735018738c5eff08781ee2315) ) @@ -5151,7 +5178,7 @@ ROM_START( topskatruo ) /* Top Skater (USA), Model 2C, Sega Game ID# 833-13080-0 ROM_LOAD32_WORD("mpr-19737.9", 0x800000, 0x400000, CRC(281a7dde) SHA1(71d5ba434328a81969bfdc71ac1160c5ff3ae9d3) ) ROM_LOAD32_WORD("mpr-19738.10", 0x800002, 0x400000, CRC(f688327e) SHA1(68c9db242ef7e8f98979e968a09e4b093bc5d470) ) - ROM_REGION( 0x800000, "cpu2", 0 ) // TGPx4 program + ROM_REGION( 0x800000, "copro_data", 0 ) // TGPx4 program ROM_LOAD32_WORD("mpr-19743.29", 0x000000, 0x200000, CRC(d41a41bf) SHA1(a5f6b24e6526d0d2ef9c526c273c018d1e0fed59) ) ROM_LOAD32_WORD("mpr-19744.30", 0x000002, 0x200000, CRC(84f203bf) SHA1(4952b764e6bf6cd735018738c5eff08781ee2315) ) @@ -5191,7 +5218,7 @@ ROM_START( topskatru ) /* Top Skater Revision A (USA), Model 2C, Sega Game ID# 8 ROM_LOAD32_WORD("mpr-19737.9", 0x800000, 0x400000, CRC(281a7dde) SHA1(71d5ba434328a81969bfdc71ac1160c5ff3ae9d3) ) ROM_LOAD32_WORD("mpr-19738.10", 0x800002, 0x400000, CRC(f688327e) SHA1(68c9db242ef7e8f98979e968a09e4b093bc5d470) ) - ROM_REGION( 0x800000, "cpu2", 0 ) // TGPx4 program + ROM_REGION( 0x800000, "copro_data", 0 ) // TGPx4 program ROM_LOAD32_WORD("mpr-19743.29", 0x000000, 0x200000, CRC(d41a41bf) SHA1(a5f6b24e6526d0d2ef9c526c273c018d1e0fed59) ) ROM_LOAD32_WORD("mpr-19744.30", 0x000002, 0x200000, CRC(84f203bf) SHA1(4952b764e6bf6cd735018738c5eff08781ee2315) ) @@ -5231,7 +5258,7 @@ ROM_START( topskatrj ) /* Top Skater (Japan), Model 2C, Sega Game ID# 833-13080- ROM_LOAD32_WORD("mpr-19737.9", 0x800000, 0x400000, CRC(281a7dde) SHA1(71d5ba434328a81969bfdc71ac1160c5ff3ae9d3) ) ROM_LOAD32_WORD("mpr-19738.10", 0x800002, 0x400000, CRC(f688327e) SHA1(68c9db242ef7e8f98979e968a09e4b093bc5d470) ) - ROM_REGION( 0x800000, "cpu2", 0 ) // TGPx4 program + ROM_REGION( 0x800000, "copro_data", 0 ) // TGPx4 program ROM_LOAD32_WORD("mpr-19743.29", 0x000000, 0x200000, CRC(d41a41bf) SHA1(a5f6b24e6526d0d2ef9c526c273c018d1e0fed59) ) ROM_LOAD32_WORD("mpr-19744.30", 0x000002, 0x200000, CRC(84f203bf) SHA1(4952b764e6bf6cd735018738c5eff08781ee2315) ) diff --git a/src/mame/includes/model2.h b/src/mame/includes/model2.h index 6e859eb8227..df714ea5e66 100644 --- a/src/mame/includes/model2.h +++ b/src/mame/includes/model2.h @@ -141,7 +141,7 @@ public: DECLARE_WRITE16_MEMBER(colorxlat_w); DECLARE_WRITE32_MEMBER(ctrl0_w); DECLARE_WRITE32_MEMBER(analog_2b_w); - DECLARE_READ32_MEMBER(fifoctl_r); + DECLARE_READ32_MEMBER(fifo_control_2a_r); DECLARE_READ32_MEMBER(videoctl_r); DECLARE_WRITE32_MEMBER(videoctl_w); DECLARE_WRITE32_MEMBER(rchase2_devices_w); @@ -248,7 +248,6 @@ public: void sj25_0207_01(machine_config &config); void copro_sharc_map(address_map &map); void copro_tgp_map(address_map &map); - void copro_tgpx4_map(address_map &map); void drive_io_map(address_map &map); void drive_map(address_map &map); void geo_sharc_map(address_map &map); @@ -345,7 +344,7 @@ public: DECLARE_READ32_MEMBER(daytona_unk_r); DECLARE_READ8_MEMBER(model2o_in_r); - DECLARE_READ32_MEMBER(fifoctrl_r); + DECLARE_READ32_MEMBER(fifo_control_2o_r); void daytona(machine_config &config); void model2o(machine_config &config); @@ -455,12 +454,16 @@ public: : model2_state(mconfig, type, tag) {} + DECLARE_READ32_MEMBER(fifo_control_2c_r); + void model2c(machine_config &config); void model2c_5881(machine_config &config); void overrev2c(machine_config &config); void stcc(machine_config &config); void model2c_crx_mem(address_map &map); void model2c_5881_mem(address_map &map); + void copro_tgpx4_map(address_map &map); + void copro_tgpx4_data_map(address_map &map); }; /***************************** -- cgit v1.2.3