summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author angelosa <salese_corp_ltd@email.it>2018-03-20 17:20:52 +0100
committer angelosa <salese_corp_ltd@email.it>2018-03-20 17:23:46 +0100
commit3344b2f6ac451adc8df63440a8c7dd098c40cb14 (patch)
tree92695cafb877a9f7254aa788ced4425bf945a35a
parentde5a35530b92aba4bdaa04547a9d2ef3c687f2d2 (diff)
Wrote a preliminary TGPx4 interpreter core [Angelo Salese]
i960.cpp: support burst stall on writes [Angelo Salese]
-rw-r--r--src/devices/cpu/i960/i960.cpp31
-rw-r--r--src/devices/cpu/i960/i960.h3
-rw-r--r--src/devices/cpu/mb86235/mb86235.cpp91
-rw-r--r--src/devices/cpu/mb86235/mb86235.h67
-rw-r--r--src/devices/cpu/mb86235/mb86235d.cpp11
-rw-r--r--src/devices/cpu/mb86235/mb86235d.h2
-rw-r--r--src/devices/cpu/mb86235/mb86235ops.cpp1284
-rw-r--r--src/mame/drivers/model2.cpp87
-rw-r--r--src/mame/includes/model2.h9
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 ; i<m_stall_state.size ;i++)
{
- // count down 1 icount for every read
+ // count down 1 icount for every op
m_icount--;
- m_r[m_stall_state.t2+i] = i960_read_dword_unaligned(m_stall_state.t1);
+ if(m_stall_state.iswriteop == true)
+ i960_write_dword_unaligned(m_stall_state.t1, m_r[m_stall_state.t2+i]);
+ else
+ m_r[m_stall_state.t2+i] = i960_read_dword_unaligned(m_stall_state.t1);
// if the host returned stall just save the index and try again on a later moment
if(m_stalled == true)
@@ -1952,7 +1956,7 @@ void i960_cpu_device::execute_op(uint32_t opcode)
m_r[t2+i] = i960_read_dword_unaligned(t1);
if(m_stalled)
{
- burst_stall_save(t1,t2,i,2);
+ burst_stall_save(t1,t2,i,2,false);
return;
}
if(m_bursting)
@@ -1969,6 +1973,11 @@ void i960_cpu_device::execute_op(uint32_t opcode)
m_bursting = 1;
for(i=0; i<2; i++) {
i960_write_dword_unaligned(t1, m_r[t2+i]);
+ if(m_stalled)
+ {
+ burst_stall_save(t1,t2,i,2,true);
+ return;
+ }
if(m_bursting)
t1 += 4;
}
@@ -1985,7 +1994,7 @@ void i960_cpu_device::execute_op(uint32_t opcode)
m_r[t2+i] = i960_read_dword_unaligned(t1);
if(m_stalled)
{
- burst_stall_save(t1,t2,i,3);
+ burst_stall_save(t1,t2,i,3,false);
return;
}
if(m_bursting)
@@ -2002,6 +2011,11 @@ void i960_cpu_device::execute_op(uint32_t opcode)
m_bursting = 1;
for(i=0; i<3; i++) {
i960_write_dword_unaligned(t1, m_r[t2+i]);
+ if(m_stalled)
+ {
+ burst_stall_save(t1,t2,i,3,true);
+ return;
+ }
if(m_bursting)
t1 += 4;
}
@@ -2018,7 +2032,7 @@ void i960_cpu_device::execute_op(uint32_t opcode)
m_r[t2+i] = i960_read_dword_unaligned(t1);
if(m_stalled)
{
- burst_stall_save(t1,t2,i,4);
+ burst_stall_save(t1,t2,i,4,false);
return;
}
if(m_bursting)
@@ -2035,6 +2049,11 @@ void i960_cpu_device::execute_op(uint32_t opcode)
m_bursting = 1;
for(i=0; i<4; i++) {
i960_write_dword_unaligned(t1, m_r[t2+i]);
+ if(m_stalled)
+ {
+ burst_stall_save(t1,t2,i,4,true);
+ return;
+ }
if(m_bursting)
t1 += 4;
}
diff --git a/src/devices/cpu/i960/i960.h b/src/devices/cpu/i960/i960.h
index 0fa99b1498e..a76998d2747 100644
--- a/src/devices/cpu/i960/i960.h
+++ b/src/devices/cpu/i960/i960.h
@@ -104,12 +104,13 @@ protected:
virtual util::disasm_interface *create_disassembler() override;
private:
- void burst_stall_save(uint32_t t1, uint32_t t2, int index, int size);
+ void burst_stall_save(uint32_t t1, uint32_t t2, int index, int size, bool iswriteop);
struct {
uint32_t t1,t2;
int index,size;
bool burst_mode;
+ bool iswriteop;
}m_stall_state;
bool m_stalled;
diff --git a/src/devices/cpu/mb86235/mb86235.cpp b/src/devices/cpu/mb86235/mb86235.cpp
index f26536f4a44..363a071e586 100644
--- a/src/devices/cpu/mb86235/mb86235.cpp
+++ b/src/devices/cpu/mb86235/mb86235.cpp
@@ -7,7 +7,14 @@
* Written by Angelo Salese & ElSemi
*
* TODO:
- * - Everything!
+ * - 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;
+ * - externalize PDR / DDR (error LED flags on Model 2);
+ * - instruction cycles;
+ * - pipeline (four instruction executed per cycle!)
*
*****************************************************************************/
@@ -49,8 +56,31 @@ void mb86235_device::execute_run()
#if ENABLE_DRC
run_drc();
#else
- debugger_instruction_hook(this, m_core->pc);
- 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<drcuml_state>(*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<i960_cpu_device &>(*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);
};
/*****************************