diff options
Diffstat (limited to 'src/devices/cpu/mb86235')
-rw-r--r-- | src/devices/cpu/mb86235/mb86235.cpp | 55 | ||||
-rw-r--r-- | src/devices/cpu/mb86235/mb86235.h | 61 | ||||
-rw-r--r-- | src/devices/cpu/mb86235/mb86235drc.cpp | 192 | ||||
-rw-r--r-- | src/devices/cpu/mb86235/mb86235ops.cpp | 58 |
4 files changed, 142 insertions, 224 deletions
diff --git a/src/devices/cpu/mb86235/mb86235.cpp b/src/devices/cpu/mb86235/mb86235.cpp index 0987b1e1b20..670571e6fce 100644 --- a/src/devices/cpu/mb86235/mb86235.cpp +++ b/src/devices/cpu/mb86235/mb86235.cpp @@ -263,6 +263,9 @@ mb86235_device::mb86235_device(const machine_config &mconfig, const char *tag, d , m_program_config("program", ENDIANNESS_LITTLE, 64, 32, -3) , m_dataa_config("data_a", ENDIANNESS_LITTLE, 32, 24, -2, address_map_constructor(FUNC(mb86235_device::internal_abus), this)) , m_datab_config("data_b", ENDIANNESS_LITTLE, 32, 10, -2, address_map_constructor(FUNC(mb86235_device::internal_bbus), this)) + , m_fifoin(*this, finder_base::DUMMY_TAG) + , m_fifoout0(*this, finder_base::DUMMY_TAG) + , m_fifoout1(*this, finder_base::DUMMY_TAG) , m_cache(CACHE_SIZE + sizeof(mb86235_internal_state)) , m_drcuml(nullptr) , m_drcfe(nullptr) @@ -292,55 +295,3 @@ std::unique_ptr<util::disasm_interface> mb86235_device::create_disassembler() { return std::make_unique<mb86235_disassembler>(); } - - -void mb86235_device::fifoin_w(uint32_t data) -{ - if (m_core->fifoin.num >= FIFOIN_SIZE) - { - fatalerror("fifoin_w: pushing to full fifo"); - } - - //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++; -} - -bool mb86235_device::is_fifoin_empty() -{ - return m_core->fifoin.num == 0; -} - -bool mb86235_device::is_fifoin_full() -{ - return m_core->fifoin.num >= FIFOIN_SIZE; -} - -uint32_t mb86235_device::fifoout0_r() -{ - if (m_core->fifoout0.num == 0) - { - fatalerror("fifoout0_r: reading from empty fifo"); - } - - 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; -} - -bool mb86235_device::is_fifoout0_full() -{ - return m_core->fifoout0.num >= FIFOOUT0_SIZE; -} - -bool mb86235_device::is_fifoout0_empty() -{ - return m_core->fifoout0.num == 0; -} diff --git a/src/devices/cpu/mb86235/mb86235.h b/src/devices/cpu/mb86235/mb86235.h index 73ee7fcb07f..dc583dd9b84 100644 --- a/src/devices/cpu/mb86235/mb86235.h +++ b/src/devices/cpu/mb86235/mb86235.h @@ -13,10 +13,21 @@ #include "cpu/drcfe.h" #include "cpu/drcuml.h" +#include "machine/gen_fifo.h" + +#define MCFG_MB86235_FIFOIN(tag) \ + downcast<mb86235_device &>(*device).set_fifoin_tag(tag); + +#define MCFG_MB86235_FIFOOUT0(tag) \ + downcast<mb86235_device &>(*device).set_fifoout0_tag(tag); + +#define MCFG_MB86235_FIFOOUT1(tag) \ + downcast<mb86235_device &>(*device).set_fifoout1_tag(tag); class mb86235_frontend; + class mb86235_device : public cpu_device { friend class mb86235_frontend; @@ -25,6 +36,10 @@ public: // construction/destruction mb86235_device(const machine_config &mconfig, const char *_tag, device_t *_owner, uint32_t clock); + void set_fifoin_tag(const char *tag) { m_fifoin.set_tag(tag); } + void set_fifoout0_tag(const char *tag) { m_fifoout0.set_tag(tag); } + void set_fifoout1_tag(const char *tag) { m_fifoout1.set_tag(tag); } + void unimplemented_op(); void unimplemented_alu(); void unimplemented_control(); @@ -33,13 +48,6 @@ public: void pcs_overflow(); void pcs_underflow(); - void fifoin_w(uint32_t data); - bool is_fifoin_full(); - bool is_fifoin_empty(); - uint32_t fifoout0_r(); - bool is_fifoout0_empty(); - bool is_fifoout0_full(); - enum { MB86235_PC = 1, @@ -53,10 +61,6 @@ public: MB86235_ST }; - static constexpr int FIFOIN_SIZE = 16; - static constexpr int FIFOOUT0_SIZE = 16; - static constexpr int FIFOOUT1_SIZE = 16; - void internal_abus(address_map &map); void internal_bbus(address_map &map); protected: @@ -102,14 +106,6 @@ private: uint32_t md; }; - struct fifo - { - int rpos; - int wpos; - int num; - uint32_t data[16]; - }; - struct fifo_state { uint32_t pc; @@ -164,9 +160,6 @@ private: float fp0; bool delay_slot; - fifo fifoin; - fifo fifoout0; - fifo fifoout1; fifo_state cur_fifo_state; }; @@ -177,18 +170,16 @@ private: uml::code_handle *m_entry; /* entry point */ uml::code_handle *m_nocode; /* nocode exception handler */ uml::code_handle *m_out_of_cycles; /* out of cycles exception handler */ - uml::code_handle *m_clear_fifo_in; - uml::code_handle *m_clear_fifo_out0; - uml::code_handle *m_clear_fifo_out1; - uml::code_handle *m_read_fifo_in; - uml::code_handle *m_write_fifo_out0; - uml::code_handle *m_write_fifo_out1; uml::code_handle *m_read_abus; uml::code_handle *m_write_abus; address_space_config m_program_config; address_space_config m_dataa_config; address_space_config m_datab_config; + optional_device<generic_fifo_u32_device> m_fifoin; + optional_device<generic_fifo_u32_device> m_fifoout0; + optional_device<generic_fifo_u32_device> m_fifoout1; + drc_cache m_cache; std::unique_ptr<drcuml_state> m_drcuml; std::unique_ptr<mb86235_frontend> m_drcfe; @@ -216,7 +207,6 @@ private: void static_generate_entry_point(); void static_generate_nocode_handler(); void static_generate_out_of_cycles(); - void static_generate_fifo(); void static_generate_memory_accessors(); void generate_sequence_instruction(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); void generate_update_cycles(drcuml_block &block, compiler_state &compiler, uml::parameter param, bool allow_exception); @@ -244,6 +234,19 @@ private: bool aluop_has_result(int aluop); bool check_previous_op_stall(); + // UML is sad... + u32 m_cur_value; + + static void clear_fifoin(void *param); + static void clear_fifoout0(void *param); + static void clear_fifoout1(void *param); + static void read_fifoin(void *param); + static void write_fifoout0(void *param); + static void write_fifoout1(void *param); + static void empty_fifoin(void *param); + static void full_fifoout0(void *param); + static void full_fifoout1(void *param); + // interpreter void execute_op(uint32_t h, uint32_t l); void do_alu1(uint32_t h, uint32_t l); diff --git a/src/devices/cpu/mb86235/mb86235drc.cpp b/src/devices/cpu/mb86235/mb86235drc.cpp index d1682d0e024..12e0ab60650 100644 --- a/src/devices/cpu/mb86235/mb86235drc.cpp +++ b/src/devices/cpu/mb86235/mb86235drc.cpp @@ -78,17 +78,6 @@ #define MU_CALC_REQUIRED ((desc->regreq[1] & 0x1000) || desc->flags & OPFLAG_IN_DELAY_SLOT) #define MD_CALC_REQUIRED ((desc->regreq[1] & 0x2000) || desc->flags & OPFLAG_IN_DELAY_SLOT) -#define FIFOIN_RPOS uml::mem(&m_core->fifoin.rpos) -#define FIFOIN_WPOS uml::mem(&m_core->fifoin.wpos) -#define FIFOIN_NUM uml::mem(&m_core->fifoin.num) -#define FIFOOUT0_RPOS uml::mem(&m_core->fifoout0.rpos) -#define FIFOOUT0_WPOS uml::mem(&m_core->fifoout0.wpos) -#define FIFOOUT0_NUM uml::mem(&m_core->fifoout0.num) -#define FIFOOUT1_RPOS uml::mem(&m_core->fifoout1.rpos) -#define FIFOOUT1_WPOS uml::mem(&m_core->fifoout1.wpos) -#define FIFOOUT1_NUM uml::mem(&m_core->fifoout1.num) - - inline void mb86235_device::alloc_handle(uml::code_handle *&handleptr, const char *name) { if (!handleptr) @@ -390,89 +379,58 @@ void mb86235_device::static_generate_out_of_cycles() block.end(); } -void mb86235_device::static_generate_fifo() +void mb86235_device::clear_fifoin(void *param) { - { - // clear fifo in - drcuml_block &block(m_drcuml->begin_block(20)); - - alloc_handle(m_clear_fifo_in, "clear_fifo_in"); - UML_HANDLE(block, *m_clear_fifo_in); - UML_MOV(block, FIFOIN_NUM, 0); - UML_MOV(block, FIFOIN_RPOS, 0); - UML_MOV(block, FIFOIN_WPOS, 0); - UML_RET(block); + mb86235_device *cpu = (mb86235_device *)param; + cpu->m_fifoin->clear(); +} - block.end(); - } - { - // clear fifo out0 - drcuml_block &block(m_drcuml->begin_block(20)); - - alloc_handle(m_clear_fifo_out0, "clear_fifo_out0"); - UML_HANDLE(block, *m_clear_fifo_out0); - UML_MOV(block, FIFOOUT0_NUM, 0); - UML_MOV(block, FIFOOUT0_RPOS, 0); - UML_MOV(block, FIFOOUT0_WPOS, 0); - UML_RET(block); +void mb86235_device::clear_fifoout0(void *param) +{ + mb86235_device *cpu = (mb86235_device *)param; + cpu->m_fifoout0->clear(); +} - block.end(); - } - { - // clear fifo out1 - drcuml_block &block(m_drcuml->begin_block(20)); - - alloc_handle(m_clear_fifo_out1, "clear_fifo_out1"); - UML_HANDLE(block, *m_clear_fifo_out1); - UML_MOV(block, FIFOOUT1_NUM, 0); - UML_MOV(block, FIFOOUT1_RPOS, 0); - UML_MOV(block, FIFOOUT1_WPOS, 0); - UML_RET(block); +void mb86235_device::clear_fifoout1(void *param) +{ + mb86235_device *cpu = (mb86235_device *)param; + cpu->m_fifoout1->clear(); +} - block.end(); - } - { - // read fifo in - // I0 = return value - drcuml_block &block(m_drcuml->begin_block(32)); - alloc_handle(m_read_fifo_in, "read_fifo_in"); - UML_HANDLE(block, *m_read_fifo_in); - UML_MOV(block, I1, FIFOIN_RPOS); - UML_LOAD(block, I0, m_core->fifoin.data, I1, SIZE_QWORD, SCALE_x8); - UML_ADD(block, I1, I1, 1); - UML_AND(block, I1, I1, FIFOIN_SIZE-1); - UML_MOV(block, FIFOIN_RPOS, I1); - UML_SUB(block, FIFOIN_NUM, FIFOIN_NUM, 1); - UML_RET(block); +void mb86235_device::read_fifoin(void *param) +{ + mb86235_device *cpu = (mb86235_device *)param; + cpu->m_cur_value = cpu->m_fifoin->pop(); +} - block.end(); - } - { - // write fifo out0 - // I0 = input value - drcuml_block &block(m_drcuml->begin_block(32)); - alloc_handle(m_write_fifo_out0, "write_fifo_out0"); - UML_HANDLE(block, *m_write_fifo_out0); - UML_MOV(block, I1, FIFOOUT0_WPOS); - UML_STORE(block, m_core->fifoout0.data, I1, I0, SIZE_QWORD, SCALE_x8); - UML_ADD(block, I1, I1, 1); - UML_AND(block, I1, I1, FIFOOUT0_SIZE - 1); - UML_MOV(block, FIFOOUT0_WPOS, I1); - UML_ADD(block, FIFOOUT0_NUM, FIFOOUT0_NUM, 1); - UML_RET(block); +void mb86235_device::write_fifoout0(void *param) +{ + mb86235_device *cpu = (mb86235_device *)param; + cpu->m_fifoout0->push(u32(cpu->m_cur_value)); +} - block.end(); - } - { - // write fifo out1 - drcuml_block &block(m_drcuml->begin_block(32)); - alloc_handle(m_write_fifo_out1, "write_fifo_out1"); - UML_HANDLE(block, *m_write_fifo_out1); - // TODO - UML_RET(block); +void mb86235_device::write_fifoout1(void *param) +{ + mb86235_device *cpu = (mb86235_device *)param; + cpu->m_fifoout1->push(u32(cpu->m_cur_value)); +} - block.end(); - } +void mb86235_device::empty_fifoin(void *param) +{ + mb86235_device *cpu = (mb86235_device *)param; + cpu->m_cur_value = cpu->m_fifoin->is_empty(); +} + +void mb86235_device::full_fifoout0(void *param) +{ + mb86235_device *cpu = (mb86235_device *)param; + cpu->m_cur_value = cpu->m_fifoout0->is_full(); +} + +void mb86235_device::full_fifoout1(void *param) +{ + mb86235_device *cpu = (mb86235_device *)param; + cpu->m_cur_value = cpu->m_fifoout1->is_full(); } void mb86235_device::static_generate_memory_accessors() @@ -542,9 +500,6 @@ void mb86235_device::flush_cache() static_generate_nocode_handler(); static_generate_out_of_cycles(); - // generate utility functions - static_generate_fifo(); - // generate exception handlers // generate memory accessors @@ -690,8 +645,13 @@ void mb86235_device::generate_reg_read(drcuml_block &block, compiler_state &comp break; case 0x31: // FI - UML_CALLH(block, *m_read_fifo_in); - UML_MOV(block, dst, I0); + if (m_fifoin) + { + UML_CALLC(block, read_fifoin, this); + UML_MOV(block, dst, mem(&m_cur_value)); + } + else + UML_MOV(block, dst, 0); break; default: @@ -747,8 +707,11 @@ void mb86235_device::generate_reg_write(drcuml_block &block, compiler_state &com break; case 0x32: // FO0 - UML_MOV(block, I0, src); - UML_CALLH(block, *m_write_fifo_out0); + if (m_fifoout0) + { + UML_MOV(block, mem(&m_cur_value), src); + UML_CALLC(block, write_fifoout0, this); + } break; case 0x34: // PDR @@ -850,11 +813,12 @@ bool mb86235_device::generate_opcode(drcuml_block &block, compiler_state &compil } // insert FIFO IN check if needed - if (fifoin_check) + if (fifoin_check && m_fifoin) { uml::code_label const not_empty = compiler.labelnum++; - UML_CMP(block, FIFOIN_NUM, 0); - UML_JMPc(block, COND_G, not_empty); + UML_CALLC(block, empty_fifoin, this); + UML_CMP(block, mem(&m_cur_value), 1); + UML_JMPc(block, COND_NE, not_empty); UML_MOV(block, mem(&m_core->icount), 0); UML_EXH(block, *m_out_of_cycles, desc->pc); @@ -863,11 +827,12 @@ bool mb86235_device::generate_opcode(drcuml_block &block, compiler_state &compil } // insert FIFO OUT0 check if needed - if (fifoout0_check) + if (fifoout0_check && m_fifoout0) { uml::code_label const not_full = compiler.labelnum++; - UML_CMP(block, FIFOOUT0_NUM, FIFOOUT0_SIZE - 1); - UML_JMPc(block, COND_L, not_full); + UML_CALLC(block, full_fifoout0, this); + UML_CMP(block, mem(&m_cur_value), 1); + UML_JMPc(block, COND_NE, not_full); UML_MOV(block, mem(&m_core->icount), 0); UML_EXH(block, *m_out_of_cycles, desc->pc); @@ -876,11 +841,12 @@ bool mb86235_device::generate_opcode(drcuml_block &block, compiler_state &compil } // insert FIFO OUT1 check if needed - if (fifoout1_check) + if (fifoout1_check && m_fifoout1) { uml::code_label const not_full = compiler.labelnum++; - UML_CMP(block, FIFOOUT1_NUM, FIFOOUT1_SIZE - 1); - UML_JMPc(block, COND_L, not_full); + UML_CALLC(block, full_fifoout1, this); + UML_CMP(block, mem(&m_cur_value), 1); + UML_JMPc(block, COND_NE, not_full); UML_MOV(block, mem(&m_core->icount), 0); UML_EXH(block, *m_out_of_cycles, desc->pc); @@ -1573,17 +1539,25 @@ void mb86235_device::generate_control(drcuml_block &block, compiler_state &compi case 0x03: // if (ef1 == 1) // CLRFI - UML_CALLH(block, *m_clear_fifo_in); + { + if (m_fifoin) + UML_CALLC(block, clear_fifoin, this); + } else if (ef1 == 2) // CLRFO { - UML_CALLH(block, *m_clear_fifo_out0); - UML_CALLH(block, *m_clear_fifo_out1); + if (m_fifoout0) + UML_CALLC(block, clear_fifoout0, this); + if (m_fifoout1) + UML_CALLC(block, clear_fifoout1, this); } else if (ef1 == 3) // CLRF { - UML_CALLH(block, *m_clear_fifo_in); - UML_CALLH(block, *m_clear_fifo_out0); - UML_CALLH(block, *m_clear_fifo_out1); + if (m_fifoin) + UML_CALLC(block, clear_fifoin, this); + if (m_fifoout0) + UML_CALLC(block, clear_fifoout0, this); + if (m_fifoout1) + UML_CALLC(block, clear_fifoout1, this); } break; diff --git a/src/devices/cpu/mb86235/mb86235ops.cpp b/src/devices/cpu/mb86235/mb86235ops.cpp index 024437c506a..fc8d667fc35 100644 --- a/src/devices/cpu/mb86235/mb86235ops.cpp +++ b/src/devices/cpu/mb86235/mb86235ops.cpp @@ -752,7 +752,7 @@ inline uint32_t mb86235_device::get_transfer_reg(uint8_t which) case 1: // FI { FCLR(IFE); - if(is_fifoin_empty() == true) + if(m_fifoin->is_empty()) { FSET(IFE); m_core->cur_fifo_state.has_stalled = true; @@ -765,13 +765,7 @@ inline uint32_t mb86235_device::get_transfer_reg(uint8_t which) } 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; + return m_fifoin->pop(); } } } @@ -827,24 +821,23 @@ inline void mb86235_device::set_transfer_reg(uint8_t which, uint32_t value) break; case 2: // FO0 FCLR(OFF); - if(is_fifoout0_full() == true) + if(m_fifoout0) { - 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++; + if(m_fifoout0->is_full()) + { + 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_fifoout0->push(u32(value)); + } break; case 4: m_core->pdr = value; break; case 5: m_core->ddr = value; break; @@ -1193,21 +1186,18 @@ void mb86235_device::do_control(uint32_t h, uint32_t l) 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; + if(m_fifoin) + m_fifoin->clear(); FSET(IFE); FCLR(IFF); m_core->cur_fifo_state.has_stalled = false; } 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; + if(m_fifoout0) + m_fifoout0->clear(); + if(m_fifoout1) + m_fifoout1->clear(); FSET(OFE); FCLR(OFF); m_core->cur_fifo_state.has_stalled = false; |