mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
Added preliminary MB86235 recompiler [Ville Linde]
This commit is contained in:
parent
3cb2a973fd
commit
dbcf903c78
@ -13,7 +13,7 @@
|
||||
-- Dynamic recompiler objects
|
||||
--------------------------------------------------
|
||||
|
||||
if (CPUS["SH2"]~=null or CPUS["MIPS"]~=null or CPUS["POWERPC"]~=null or CPUS["RSP"]~=null or CPUS["ARM7"]~=null or CPUS["ADSP21062"]~=null) then
|
||||
if (CPUS["SH2"]~=null or CPUS["MIPS"]~=null or CPUS["POWERPC"]~=null or CPUS["RSP"]~=null or CPUS["ARM7"]~=null or CPUS["ADSP21062"]~=null or CPUS["MB86235"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/cpu/drcbec.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/drcbec.h",
|
||||
@ -1064,6 +1064,9 @@ if (CPUS["MB86235"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/cpu/mb86235/mb86235.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/mb86235/mb86235.h",
|
||||
MAME_DIR .. "src/devices/cpu/mb86235/mb86235drc.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/mb86235/mb86235fe.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/mb86235/mb86235fe.h",
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Angelo Salese, ElSemi
|
||||
// copyright-holders:Angelo Salese, ElSemi, Ville Linde
|
||||
/*****************************************************************************
|
||||
*
|
||||
* MB86235 "TGPx4" (c) Fujitsu
|
||||
@ -14,69 +14,163 @@
|
||||
#include "emu.h"
|
||||
#include "debugger.h"
|
||||
#include "mb86235.h"
|
||||
|
||||
|
||||
const device_type MB86235 = &device_creator<mb86235_cpu_device>;
|
||||
#include "mb86235fe.h"
|
||||
|
||||
|
||||
|
||||
#define CACHE_SIZE (1 * 1024 * 1024)
|
||||
#define COMPILE_BACKWARDS_BYTES 128
|
||||
#define COMPILE_FORWARDS_BYTES 512
|
||||
#define COMPILE_MAX_INSTRUCTIONS ((COMPILE_BACKWARDS_BYTES/4) + (COMPILE_FORWARDS_BYTES/4))
|
||||
#define COMPILE_MAX_SEQUENCE 64
|
||||
|
||||
|
||||
#define mb86235_readop(A) m_program->read_dword(A)
|
||||
#define mb86235_readmem(A) m_program->read_dword(A)
|
||||
#define mb86235_writemem(A,B) m_program->write_dword((A),B)
|
||||
|
||||
const device_type MB86235 = &device_creator<mb86235_device>;
|
||||
|
||||
|
||||
static ADDRESS_MAP_START(internal_abus, AS_DATA, 32, mb86235_device)
|
||||
AM_RANGE(0x000000, 0x0003ff) AM_RAM
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START(internal_bbus, AS_IO, 32, mb86235_device)
|
||||
AM_RANGE(0x000000, 0x0003ff) AM_RAM
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
/***********************************
|
||||
* illegal opcodes
|
||||
***********************************/
|
||||
void mb86235_cpu_device::mb86235_illegal()
|
||||
{
|
||||
//logerror("mb86235 illegal opcode at 0x%04x\n", m_pc);
|
||||
m_icount -= 1;
|
||||
}
|
||||
|
||||
/* Execute cycles */
|
||||
void mb86235_cpu_device::execute_run()
|
||||
void mb86235_device::execute_run()
|
||||
{
|
||||
uint32_t opcode;
|
||||
|
||||
do
|
||||
{
|
||||
debugger_instruction_hook(this, m_pc);
|
||||
|
||||
opcode = mb86235_readop(m_pc);
|
||||
//m_pc++;
|
||||
|
||||
switch( opcode )
|
||||
{
|
||||
default:
|
||||
mb86235_illegal();
|
||||
break;
|
||||
}
|
||||
|
||||
} while( m_icount > 0 );
|
||||
run_drc();
|
||||
}
|
||||
|
||||
|
||||
void mb86235_cpu_device::device_start()
|
||||
void mb86235_device::device_start()
|
||||
{
|
||||
m_program = &space(AS_PROGRAM);
|
||||
m_direct = &m_program->direct();
|
||||
m_dataa = &space(AS_DATA);
|
||||
m_datab = &space(AS_IO);
|
||||
|
||||
m_core = (mb86235_internal_state *)m_cache.alloc_near(sizeof(mb86235_internal_state));
|
||||
memset(m_core, 0, sizeof(mb86235_internal_state));
|
||||
|
||||
|
||||
// init UML generator
|
||||
uint32_t umlflags = 0;
|
||||
m_drcuml = std::make_unique<drcuml_state>(*this, m_cache, umlflags, 1, 24, 0);
|
||||
|
||||
// add UML symbols
|
||||
m_drcuml->symbol_add(&m_core->pc, sizeof(m_core->pc), "pc");
|
||||
m_drcuml->symbol_add(&m_core->icount, sizeof(m_core->icount), "icount");
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
char buf[10];
|
||||
sprintf(buf, "aa%d", i);
|
||||
m_drcuml->symbol_add(&m_core->aa[i], sizeof(m_core->aa[i]), buf);
|
||||
sprintf(buf, "ab%d", i);
|
||||
m_drcuml->symbol_add(&m_core->ab[i], sizeof(m_core->ab[i]), buf);
|
||||
sprintf(buf, "ma%d", i);
|
||||
m_drcuml->symbol_add(&m_core->ma[i], sizeof(m_core->ma[i]), buf);
|
||||
sprintf(buf, "mb%d", i);
|
||||
m_drcuml->symbol_add(&m_core->mb[i], sizeof(m_core->mb[i]), buf);
|
||||
sprintf(buf, "ar%d", i);
|
||||
m_drcuml->symbol_add(&m_core->ar[i], sizeof(m_core->ar[i]), buf);
|
||||
}
|
||||
|
||||
m_drcuml->symbol_add(&m_core->flags.az, sizeof(m_core->flags.az), "flags_az");
|
||||
m_drcuml->symbol_add(&m_core->flags.an, sizeof(m_core->flags.an), "flags_an");
|
||||
m_drcuml->symbol_add(&m_core->flags.av, sizeof(m_core->flags.av), "flags_av");
|
||||
m_drcuml->symbol_add(&m_core->flags.au, sizeof(m_core->flags.au), "flags_au");
|
||||
m_drcuml->symbol_add(&m_core->flags.ad, sizeof(m_core->flags.ad), "flags_ad");
|
||||
m_drcuml->symbol_add(&m_core->flags.zc, sizeof(m_core->flags.zc), "flags_zc");
|
||||
m_drcuml->symbol_add(&m_core->flags.il, sizeof(m_core->flags.il), "flags_il");
|
||||
m_drcuml->symbol_add(&m_core->flags.nr, sizeof(m_core->flags.nr), "flags_nr");
|
||||
m_drcuml->symbol_add(&m_core->flags.zd, sizeof(m_core->flags.zd), "flags_zd");
|
||||
m_drcuml->symbol_add(&m_core->flags.mn, sizeof(m_core->flags.mn), "flags_mn");
|
||||
m_drcuml->symbol_add(&m_core->flags.mz, sizeof(m_core->flags.mz), "flags_mz");
|
||||
m_drcuml->symbol_add(&m_core->flags.mv, sizeof(m_core->flags.mv), "flags_mv");
|
||||
m_drcuml->symbol_add(&m_core->flags.mu, sizeof(m_core->flags.mu), "flags_mu");
|
||||
m_drcuml->symbol_add(&m_core->flags.md, sizeof(m_core->flags.md), "flags_md");
|
||||
|
||||
|
||||
m_drcuml->symbol_add(&m_core->arg0, sizeof(m_core->arg0), "arg0");
|
||||
m_drcuml->symbol_add(&m_core->arg1, sizeof(m_core->arg1), "arg1");
|
||||
m_drcuml->symbol_add(&m_core->arg2, sizeof(m_core->arg2), "arg2");
|
||||
m_drcuml->symbol_add(&m_core->arg3, sizeof(m_core->arg3), "arg3");
|
||||
m_drcuml->symbol_add(&m_core->alutemp, sizeof(m_core->alutemp), "alutemp");
|
||||
m_drcuml->symbol_add(&m_core->multemp, sizeof(m_core->multemp), "multemp");
|
||||
|
||||
m_drcuml->symbol_add(&m_core->pcs_ptr, sizeof(m_core->pcs_ptr), "pcs_ptr");
|
||||
|
||||
|
||||
m_drcfe = std::make_unique<mb86235_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, COMPILE_MAX_SEQUENCE);
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
m_regmap[i] = uml::mem(&m_core->aa[i]);
|
||||
m_regmap[i + 8] = uml::mem(&m_core->ab[i]);
|
||||
m_regmap[i + 16] = uml::mem(&m_core->ma[i]);
|
||||
m_regmap[i + 24] = uml::mem(&m_core->mb[i]);
|
||||
}
|
||||
|
||||
save_item(NAME(m_pc));
|
||||
save_item(NAME(m_flags));
|
||||
|
||||
// Register state for debugger
|
||||
//state_add( CP1610_R0, "PC", m_pc ).formatstr("%02X");
|
||||
state_add( STATE_GENPC, "GENPC", m_pc ).noshow();
|
||||
state_add( STATE_GENPCBASE, "CURPC", m_pc ).noshow();
|
||||
state_add( STATE_GENFLAGS, "GENFLAGS", m_flags ).noshow();
|
||||
state_add(MB86235_PC, "PC", m_core->pc).formatstr("%08X");
|
||||
state_add(MB86235_AR0, "AR0", m_core->ar[0]).formatstr("%08X");
|
||||
state_add(MB86235_AR1, "AR1", m_core->ar[1]).formatstr("%08X");
|
||||
state_add(MB86235_AR2, "AR2", m_core->ar[2]).formatstr("%08X");
|
||||
state_add(MB86235_AR3, "AR3", m_core->ar[3]).formatstr("%08X");
|
||||
state_add(MB86235_AR4, "AR4", m_core->ar[4]).formatstr("%08X");
|
||||
state_add(MB86235_AR5, "AR5", m_core->ar[5]).formatstr("%08X");
|
||||
state_add(MB86235_AR6, "AR6", m_core->ar[6]).formatstr("%08X");
|
||||
state_add(MB86235_AR7, "AR7", m_core->ar[7]).formatstr("%08X");
|
||||
state_add(MB86235_AA0, "AA0", m_core->aa[0]).formatstr("%08X");
|
||||
state_add(MB86235_AA1, "AA1", m_core->aa[1]).formatstr("%08X");
|
||||
state_add(MB86235_AA2, "AA2", m_core->aa[2]).formatstr("%08X");
|
||||
state_add(MB86235_AA3, "AA3", m_core->aa[3]).formatstr("%08X");
|
||||
state_add(MB86235_AA4, "AA4", m_core->aa[4]).formatstr("%08X");
|
||||
state_add(MB86235_AA5, "AA5", m_core->aa[5]).formatstr("%08X");
|
||||
state_add(MB86235_AA6, "AA6", m_core->aa[6]).formatstr("%08X");
|
||||
state_add(MB86235_AA7, "AA7", m_core->aa[7]).formatstr("%08X");
|
||||
state_add(MB86235_AB0, "AB0", m_core->ab[0]).formatstr("%08X");
|
||||
state_add(MB86235_AB1, "AB1", m_core->ab[1]).formatstr("%08X");
|
||||
state_add(MB86235_AB2, "AB2", m_core->ab[2]).formatstr("%08X");
|
||||
state_add(MB86235_AB3, "AB3", m_core->ab[3]).formatstr("%08X");
|
||||
state_add(MB86235_AB4, "AB4", m_core->ab[4]).formatstr("%08X");
|
||||
state_add(MB86235_AB5, "AB5", m_core->ab[5]).formatstr("%08X");
|
||||
state_add(MB86235_AB6, "AB6", m_core->ab[6]).formatstr("%08X");
|
||||
state_add(MB86235_AB7, "AB7", m_core->ab[7]).formatstr("%08X");
|
||||
state_add(MB86235_MA0, "MA0", m_core->ma[0]).formatstr("%08X");
|
||||
state_add(MB86235_MA1, "MA1", m_core->ma[1]).formatstr("%08X");
|
||||
state_add(MB86235_MA2, "MA2", m_core->ma[2]).formatstr("%08X");
|
||||
state_add(MB86235_MA3, "MA3", m_core->ma[3]).formatstr("%08X");
|
||||
state_add(MB86235_MA4, "MA4", m_core->ma[4]).formatstr("%08X");
|
||||
state_add(MB86235_MA5, "MA5", m_core->ma[5]).formatstr("%08X");
|
||||
state_add(MB86235_MA6, "MA6", m_core->ma[6]).formatstr("%08X");
|
||||
state_add(MB86235_MA7, "MA7", m_core->ma[7]).formatstr("%08X");
|
||||
state_add(MB86235_MB0, "MB0", m_core->mb[0]).formatstr("%08X");
|
||||
state_add(MB86235_MB1, "MB1", m_core->mb[1]).formatstr("%08X");
|
||||
state_add(MB86235_MB2, "MB2", m_core->mb[2]).formatstr("%08X");
|
||||
state_add(MB86235_MB3, "MB3", m_core->mb[3]).formatstr("%08X");
|
||||
state_add(MB86235_MB4, "MB4", m_core->mb[4]).formatstr("%08X");
|
||||
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(STATE_GENPC, "GENPC", m_core->pc ).noshow();
|
||||
|
||||
m_icountptr = &m_icount;
|
||||
m_icountptr = &m_core->icount;
|
||||
|
||||
m_core->fp0 = 0.0f;
|
||||
}
|
||||
|
||||
void mb86235_cpu_device::device_reset()
|
||||
void mb86235_device::device_reset()
|
||||
{
|
||||
flush_cache();
|
||||
|
||||
m_core->pc = 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -102,29 +196,62 @@ void mb86235_cpu_device::execute_set_input(int irqline, int state)
|
||||
}
|
||||
#endif
|
||||
|
||||
mb86235_cpu_device::mb86235_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
mb86235_device::mb86235_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: cpu_device(mconfig, MB86235, "MB86235", tag, owner, clock, "mb86235", __FILE__)
|
||||
, m_program_config("program", ENDIANNESS_LITTLE, 64, 32, -3)
|
||||
, m_dataa_config("data_a", ENDIANNESS_LITTLE, 32, 24, -2, ADDRESS_MAP_NAME(internal_abus))
|
||||
, m_datab_config("data_b", ENDIANNESS_LITTLE, 32, 10, -2, ADDRESS_MAP_NAME(internal_bbus))
|
||||
, m_cache(CACHE_SIZE + sizeof(mb86235_internal_state))
|
||||
, m_drcuml(nullptr)
|
||||
, m_drcfe(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void mb86235_cpu_device::state_string_export(const device_state_entry &entry, std::string &str) const
|
||||
void mb86235_device::state_string_export(const device_state_entry &entry, std::string &str) const
|
||||
{
|
||||
switch (entry.index())
|
||||
{
|
||||
case STATE_GENFLAGS:
|
||||
str = string_format("%c%c%c%c",
|
||||
m_flags & 0x80 ? 'S':'.',
|
||||
m_flags & 0x40 ? 'Z':'.',
|
||||
m_flags & 0x20 ? 'V':'.',
|
||||
m_flags & 0x10 ? 'C':'.');
|
||||
str = string_format("?");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
offs_t mb86235_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options)
|
||||
offs_t mb86235_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options)
|
||||
{
|
||||
extern CPU_DISASSEMBLE( mb86235 );
|
||||
return CPU_DISASSEMBLE_NAME(mb86235)(this, stream, pc, oprom, opram, options);
|
||||
}
|
||||
|
||||
|
||||
void mb86235_device::fifoin_w(uint64_t data)
|
||||
{
|
||||
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));
|
||||
|
||||
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_full()
|
||||
{
|
||||
return m_core->fifoin.num >= FIFOIN_SIZE;
|
||||
}
|
||||
|
||||
uint64_t mb86235_device::fifoout0_r()
|
||||
{
|
||||
fatalerror("fifoout0_r");
|
||||
}
|
||||
|
||||
bool mb86235_device::is_fifoout0_empty()
|
||||
{
|
||||
return m_core->fifoout0.num == 0;
|
||||
}
|
@ -11,20 +11,62 @@
|
||||
#ifndef __MB86235_H__
|
||||
#define __MB86235_H__
|
||||
|
||||
#if 0
|
||||
enum
|
||||
{
|
||||
MB86235_R0=1, MB86235_R1, MB86235_R2, MB86235_R3,
|
||||
MB86235_R4, MB86235_R5, MB86235_R6, MB86235_R7
|
||||
};
|
||||
#endif
|
||||
#include "cpu/drcfe.h"
|
||||
#include "cpu/drcuml.h"
|
||||
|
||||
class mb86235_frontend;
|
||||
|
||||
|
||||
class mb86235_cpu_device : public cpu_device
|
||||
|
||||
|
||||
#define OP_USERFLAG_FIFOIN 0x1
|
||||
#define OP_USERFLAG_FIFOOUT0 0x2
|
||||
#define OP_USERFLAG_FIFOOUT1 0x4
|
||||
#define OP_USERFLAG_REPEAT 0x8
|
||||
#define OP_USERFLAG_REPEATED_OP 0x10
|
||||
#define OP_USERFLAG_ALU_PRP_UPDATE 0x100
|
||||
#define OP_USERFLAG_MUL_PRP_UPDATE 0x200
|
||||
#define OP_USERFLAG_XFER_PRP_UPDATE 0x400
|
||||
#define OP_USERFLAG_ALU_PWP_UPDATE 0x800
|
||||
#define OP_USERFLAG_MUL_PWP_UPDATE 0x1000
|
||||
#define OP_USERFLAG_XFER_PWP_UPDATE 0x2000
|
||||
|
||||
|
||||
class mb86235_device : public cpu_device
|
||||
{
|
||||
friend class mb86235_frontend;
|
||||
|
||||
public:
|
||||
// construction/destruction
|
||||
mb86235_cpu_device(const machine_config &mconfig, const char *_tag, device_t *_owner, uint32_t _clock);
|
||||
mb86235_device(const machine_config &mconfig, const char *_tag, device_t *_owner, uint32_t clock);
|
||||
|
||||
void unimplemented_op();
|
||||
void unimplemented_alu();
|
||||
void unimplemented_control();
|
||||
void unimplemented_xfer1();
|
||||
void unimplemented_double_xfer1();
|
||||
void unimplemented_double_xfer2();
|
||||
void pcs_overflow();
|
||||
void pcs_underflow();
|
||||
|
||||
void fifoin_w(uint64_t data);
|
||||
bool is_fifoin_full();
|
||||
uint64_t fifoout0_r();
|
||||
bool is_fifoout0_empty();
|
||||
|
||||
enum
|
||||
{
|
||||
MB86235_PC = 1,
|
||||
MB86235_AA0, MB86235_AA1, MB86235_AA2, MB86235_AA3, MB86235_AA4, MB86235_AA5, MB86235_AA6, MB86235_AA7,
|
||||
MB86235_AB0, MB86235_AB1, MB86235_AB2, MB86235_AB3, MB86235_AB4, MB86235_AB5, MB86235_AB6, MB86235_AB7,
|
||||
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,
|
||||
};
|
||||
|
||||
const int FIFOIN_SIZE = 16;
|
||||
const int FIFOOUT0_SIZE = 16;
|
||||
const int FIFOOUT1_SIZE = 16;
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
@ -39,7 +81,7 @@ protected:
|
||||
//virtual void execute_set_input(int inputnum, int state);
|
||||
|
||||
// device_memory_interface overrides
|
||||
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const override { return (spacenum == AS_PROGRAM) ? &m_program_config : nullptr; }
|
||||
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const override { return (spacenum == AS_PROGRAM) ? &m_program_config : ((spacenum == AS_DATA) ? &m_dataa_config : (spacenum == AS_IO) ? &m_datab_config : nullptr); }
|
||||
|
||||
// device_state_interface overrides
|
||||
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
|
||||
@ -49,16 +91,154 @@ protected:
|
||||
virtual uint32_t disasm_max_opcode_bytes() const override { return 8; }
|
||||
virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override;
|
||||
|
||||
direct_read_data *m_direct;
|
||||
|
||||
private:
|
||||
|
||||
struct mb86235_flags
|
||||
{
|
||||
uint32_t az;
|
||||
uint32_t an;
|
||||
uint32_t av;
|
||||
uint32_t au;
|
||||
uint32_t ad;
|
||||
uint32_t zc;
|
||||
uint32_t il;
|
||||
uint32_t nr;
|
||||
uint32_t zd;
|
||||
uint32_t mn;
|
||||
uint32_t mz;
|
||||
uint32_t mv;
|
||||
uint32_t mu;
|
||||
uint32_t md;
|
||||
};
|
||||
|
||||
struct fifo
|
||||
{
|
||||
int rpos;
|
||||
int wpos;
|
||||
int num;
|
||||
uint64_t data[16];
|
||||
};
|
||||
|
||||
struct mb86235_internal_state
|
||||
{
|
||||
uint32_t pc;
|
||||
uint32_t aa[8];
|
||||
uint32_t ab[8];
|
||||
uint32_t ma[8];
|
||||
uint32_t mb[8];
|
||||
uint32_t ar[8];
|
||||
|
||||
uint32_t sp;
|
||||
uint32_t eb;
|
||||
uint32_t eo;
|
||||
uint32_t rpc;
|
||||
uint32_t lpc;
|
||||
|
||||
uint32_t prp;
|
||||
uint32_t pwp;
|
||||
uint32_t pr[24];
|
||||
|
||||
uint32_t mod;
|
||||
mb86235_flags flags;
|
||||
|
||||
int icount;
|
||||
|
||||
uint32_t arg0;
|
||||
uint32_t arg1;
|
||||
uint32_t arg2;
|
||||
uint32_t arg3;
|
||||
uint64_t arg64;
|
||||
|
||||
uint32_t pcs[4];
|
||||
int pcs_ptr;
|
||||
|
||||
uint32_t jmpdest;
|
||||
uint32_t alutemp;
|
||||
uint32_t multemp;
|
||||
uint32_t condtemp;
|
||||
|
||||
uint32_t pdr;
|
||||
uint32_t ddr;
|
||||
|
||||
float fp0;
|
||||
|
||||
fifo fifoin;
|
||||
fifo fifoout0;
|
||||
fifo fifoout1;
|
||||
};
|
||||
|
||||
mb86235_internal_state *m_core;
|
||||
|
||||
drc_cache m_cache;
|
||||
std::unique_ptr<drcuml_state> m_drcuml;
|
||||
std::unique_ptr<mb86235_frontend> m_drcfe;
|
||||
uml::parameter m_regmap[32];
|
||||
|
||||
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;
|
||||
|
||||
uint8_t m_pc; /* registers */
|
||||
uint8_t m_flags; /* flags */
|
||||
address_space *m_program;
|
||||
int m_icount;
|
||||
address_space *m_dataa;
|
||||
address_space *m_datab;
|
||||
|
||||
void mb86235_illegal();
|
||||
/* internal compiler state */
|
||||
struct compiler_state
|
||||
{
|
||||
uint32_t cycles; /* accumulated cycles */
|
||||
uint8_t checkints; /* need to check interrupts before next instruction */
|
||||
uml::code_label labelnum; /* index for local labels */
|
||||
};
|
||||
|
||||
void run_drc();
|
||||
void flush_cache();
|
||||
void alloc_handle(drcuml_state *drcuml, uml::code_handle **handleptr, const char *name);
|
||||
void compile_block(offs_t pc);
|
||||
void load_fast_iregs(drcuml_block *block);
|
||||
void save_fast_iregs(drcuml_block *block);
|
||||
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);
|
||||
bool generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_alu(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int aluop, bool alu_temp);
|
||||
void generate_mul(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int mulop, bool mul_temp);
|
||||
void generate_pre_control(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_control(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_xfer1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_double_xfer1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_xfer2(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_double_xfer2(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_xfer3(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_branch(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_ea(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int md, int arx, int ary, int disp);
|
||||
void generate_reg_read(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int reg, uml::parameter dst);
|
||||
void generate_reg_write(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int reg, uml::parameter src);
|
||||
void generate_alumul_input(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int reg, uml::parameter dst, bool fp, bool mul);
|
||||
uml::parameter get_alu1_input(int reg);
|
||||
uml::parameter get_alu_output(int reg);
|
||||
uml::parameter get_mul1_input(int reg);
|
||||
void generate_condition(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int cc, bool not, uml::code_label skip_label, bool condtemp);
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
|
1775
src/devices/cpu/mb86235/mb86235drc.cpp
Normal file
1775
src/devices/cpu/mb86235/mb86235drc.cpp
Normal file
File diff suppressed because it is too large
Load Diff
845
src/devices/cpu/mb86235/mb86235fe.cpp
Normal file
845
src/devices/cpu/mb86235/mb86235fe.cpp
Normal file
@ -0,0 +1,845 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ville Linde
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
Front-end for MB86235 recompiler
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "mb86235fe.h"
|
||||
|
||||
|
||||
#define AA_USED(desc,x) do { (desc).regin[0] |= 1 << (x); } while(0)
|
||||
#define AA_MODIFIED(desc,x) do { (desc).regout[0] |= 1 << (x); } while(0)
|
||||
#define AB_USED(desc,x) do { (desc).regin[0] |= 1 << (8+x); } while(0)
|
||||
#define AB_MODIFIED(desc,x) do { (desc).regout[0] |= 1 << (8+x); } while(0)
|
||||
#define MA_USED(desc,x) do { (desc).regin[0] |= 1 << (16+x); } while(0)
|
||||
#define MA_MODIFIED(desc,x) do { (desc).regout[0] |= 1 << (16+x); } while(0)
|
||||
#define MB_USED(desc,x) do { (desc).regin[0] |= 1 << (24+x); } while(0)
|
||||
#define MB_MODIFIED(desc,x) do { (desc).regout[0] |= 1 << (24+x); } while(0)
|
||||
#define AR_USED(desc,x) do { (desc).regin[1] |= 1 << (24+x); } while(0)
|
||||
#define AR_MODIFIED(desc,x) do { (desc).regout[1] |= 1 << (24+x); } while(0)
|
||||
|
||||
#define AZ_USED(desc) do { (desc).regin[1] |= 1 << 0; } while (0)
|
||||
#define AZ_MODIFIED(desc) do { (desc).regout[1] |= 1 << 0; } while (0)
|
||||
#define AN_USED(desc) do { (desc).regin[1] |= 1 << 1; } while (0)
|
||||
#define AN_MODIFIED(desc) do { (desc).regout[1] |= 1 << 1; } while (0)
|
||||
#define AV_USED(desc) do { (desc).regin[1] |= 1 << 2; } while (0)
|
||||
#define AV_MODIFIED(desc) do { (desc).regout[1] |= 1 << 2; } while (0)
|
||||
#define AU_USED(desc) do { (desc).regin[1] |= 1 << 3; } while (0)
|
||||
#define AU_MODIFIED(desc) do { (desc).regout[1] |= 1 << 3; } while (0)
|
||||
#define AD_USED(desc) do { (desc).regin[1] |= 1 << 4; } while (0)
|
||||
#define AD_MODIFIED(desc) do { (desc).regout[1] |= 1 << 4; } while (0)
|
||||
#define ZC_USED(desc) do { (desc).regin[1] |= 1 << 5; } while (0)
|
||||
#define ZC_MODIFIED(desc) do { (desc).regout[1] |= 1 << 5; } while (0)
|
||||
#define IL_USED(desc) do { (desc).regin[1] |= 1 << 6; } while (0)
|
||||
#define IL_MODIFIED(desc) do { (desc).regout[1] |= 1 << 6; } while (0)
|
||||
#define NR_USED(desc) do { (desc).regin[1] |= 1 << 7; } while (0)
|
||||
#define NR_MODIFIED(desc) do { (desc).regout[1] |= 1 << 7; } while (0)
|
||||
#define ZD_USED(desc) do { (desc).regin[1] |= 1 << 8; } while (0)
|
||||
#define ZD_MODIFIED(desc) do { (desc).regout[1] |= 1 << 8; } while (0)
|
||||
#define MN_USED(desc) do { (desc).regin[1] |= 1 << 9; } while (0)
|
||||
#define MN_MODIFIED(desc) do { (desc).regout[1] |= 1 << 9; } while (0)
|
||||
#define MZ_USED(desc) do { (desc).regin[1] |= 1 << 10; } while (0)
|
||||
#define MZ_MODIFIED(desc) do { (desc).regout[1] |= 1 << 10; } while (0)
|
||||
#define MV_USED(desc) do { (desc).regin[1] |= 1 << 11; } while (0)
|
||||
#define MV_MODIFIED(desc) do { (desc).regout[1] |= 1 << 11; } while (0)
|
||||
#define MU_USED(desc) do { (desc).regin[1] |= 1 << 12; } while (0)
|
||||
#define MU_MODIFIED(desc) do { (desc).regout[1] |= 1 << 12; } while (0)
|
||||
#define MD_USED(desc) do { (desc).regin[1] |= 1 << 13; } while (0)
|
||||
#define MD_MODIFIED(desc) do { (desc).regout[1] |= 1 << 13; } while (0)
|
||||
|
||||
|
||||
mb86235_frontend::mb86235_frontend(mb86235_device *core, uint32_t window_start, uint32_t window_end, uint32_t max_sequence)
|
||||
: drc_frontend(*core, window_start, window_end, max_sequence),
|
||||
m_core(core)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool mb86235_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
|
||||
{
|
||||
uint64_t opcode = desc.opptr.q[0] = m_core->m_direct->read_qword(desc.pc * 8, 0);
|
||||
|
||||
desc.length = 1;
|
||||
desc.cycles = 1;
|
||||
|
||||
// repeatable instruction needs an entry point
|
||||
if (prev != nullptr)
|
||||
{
|
||||
if (prev->userflags & OP_USERFLAG_REPEAT)
|
||||
{
|
||||
desc.flags |= OPFLAG_IS_BRANCH_TARGET;
|
||||
desc.userflags |= OP_USERFLAG_REPEATED_OP;
|
||||
}
|
||||
}
|
||||
|
||||
switch ((opcode >> 61) & 7)
|
||||
{
|
||||
case 0: // ALU / MUL / double transfer (type 1)
|
||||
describe_alu(desc, (opcode >> 42) & 0x7ffff);
|
||||
describe_mul(desc, (opcode >> 27) & 0x7fff);
|
||||
describe_double_xfer1(desc);
|
||||
break;
|
||||
case 1: // ALU / MUL / transfer (type 1)
|
||||
describe_alu(desc, (opcode >> 42) & 0x7ffff);
|
||||
describe_mul(desc, (opcode >> 27) & 0x7fff);
|
||||
describe_xfer1(desc);
|
||||
break;
|
||||
case 2: // ALU / MUL / control
|
||||
describe_alu(desc, (opcode >> 42) & 0x7ffff);
|
||||
describe_mul(desc, (opcode >> 27) & 0x7fff);
|
||||
describe_control(desc);
|
||||
break;
|
||||
case 4: // ALU or MUL / double transfer (type 2)
|
||||
if (opcode & ((uint64_t)(1) << 41))
|
||||
describe_alu(desc, (opcode >> 42) & 0x7ffff);
|
||||
else
|
||||
describe_mul(desc, (opcode >> 42) & 0x7fff);
|
||||
describe_double_xfer2(desc);
|
||||
break;
|
||||
case 5: // ALU or MUL / transfer (type 2)
|
||||
if (opcode & ((uint64_t)(1) << 41))
|
||||
describe_alu(desc, (opcode >> 42) & 0x7ffff);
|
||||
else
|
||||
describe_mul(desc, (opcode >> 42) & 0x7fff);
|
||||
describe_xfer2(desc);
|
||||
break;
|
||||
case 6: // ALU or MUL / control
|
||||
if (opcode & ((uint64_t)(1) << 41))
|
||||
describe_alu(desc, (opcode >> 42) & 0x7ffff);
|
||||
else
|
||||
describe_mul(desc, (opcode >> 42) & 0x7fff);
|
||||
describe_control(desc);
|
||||
break;
|
||||
case 7: // transfer (type 3)
|
||||
describe_xfer3(desc);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void mb86235_frontend::describe_alu_input(opcode_desc &desc, int reg)
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
|
||||
AA_USED(desc, reg & 7);
|
||||
break;
|
||||
|
||||
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
|
||||
AB_USED(desc, reg & 7);
|
||||
break;
|
||||
|
||||
case 0x10: // PR
|
||||
case 0x11: // PR++
|
||||
case 0x12: // PR--
|
||||
case 0x13: // PR#0
|
||||
desc.userflags |= OP_USERFLAG_ALU_PRP_UPDATE;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void mb86235_frontend::describe_mul_input(opcode_desc &desc, int reg)
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
|
||||
MA_USED(desc, reg & 7);
|
||||
break;
|
||||
|
||||
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
|
||||
MB_USED(desc, reg & 7);
|
||||
break;
|
||||
|
||||
case 0x10: // PR
|
||||
case 0x11: // PR++
|
||||
case 0x12: // PR--
|
||||
case 0x13: // PR#0
|
||||
desc.userflags |= OP_USERFLAG_MUL_PRP_UPDATE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void mb86235_frontend::describe_alumul_output(opcode_desc &desc, int reg)
|
||||
{
|
||||
switch (reg >> 3)
|
||||
{
|
||||
case 0:
|
||||
MA_MODIFIED(desc, reg & 7);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
MB_MODIFIED(desc, reg & 7);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
AA_MODIFIED(desc, reg & 7);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
AB_MODIFIED(desc, reg & 7);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void mb86235_frontend::describe_reg_read(opcode_desc &desc, int reg)
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
|
||||
// MA0-7
|
||||
MA_USED(desc, reg & 7);
|
||||
break;
|
||||
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
|
||||
// AA0-7
|
||||
AA_USED(desc, reg & 7);
|
||||
break;
|
||||
case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
|
||||
// AR0-7
|
||||
AR_USED(desc, reg & 7);
|
||||
break;
|
||||
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
|
||||
// MB0-7
|
||||
MB_USED(desc, reg & 7);
|
||||
break;
|
||||
case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
|
||||
// AB0-7
|
||||
AB_USED(desc, reg & 7);
|
||||
break;
|
||||
|
||||
case 0x31: // FI
|
||||
desc.userflags |= OP_USERFLAG_FIFOIN;
|
||||
desc.flags |= OPFLAG_IS_BRANCH_TARGET; // fifo check makes this a branch target
|
||||
break;
|
||||
|
||||
case 0x32: // FO0
|
||||
break;
|
||||
case 0x33: // FO1
|
||||
break;
|
||||
|
||||
case 0x10: // EB
|
||||
case 0x11: // EBU
|
||||
case 0x12: // EBL
|
||||
case 0x13: // EO
|
||||
case 0x15: // ST
|
||||
case 0x16: // MOD
|
||||
case 0x17: // LRPC
|
||||
case 0x34: // PDR
|
||||
case 0x35: // DDR
|
||||
case 0x36: // PRP
|
||||
case 0x37: // PWP
|
||||
break;
|
||||
|
||||
case 0x30: // PR
|
||||
desc.userflags |= OP_USERFLAG_XFER_PRP_UPDATE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void mb86235_frontend::describe_reg_write(opcode_desc &desc, int reg)
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
|
||||
// MA0-7
|
||||
MA_MODIFIED(desc, reg & 7);
|
||||
break;
|
||||
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
|
||||
// AA0-7
|
||||
AA_MODIFIED(desc, reg & 7);
|
||||
break;
|
||||
case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
|
||||
// AR0-7
|
||||
AR_MODIFIED(desc, reg & 7);
|
||||
break;
|
||||
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
|
||||
// MB0-7
|
||||
MB_MODIFIED(desc, reg & 7);
|
||||
break;
|
||||
case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
|
||||
// AB0-7
|
||||
AB_MODIFIED(desc, reg & 7);
|
||||
break;
|
||||
|
||||
case 0x31: // FI
|
||||
break;
|
||||
|
||||
case 0x32: // FO0
|
||||
desc.userflags |= OP_USERFLAG_FIFOOUT0;
|
||||
desc.flags |= OPFLAG_IS_BRANCH_TARGET; // fifo check makes this a branch target
|
||||
break;
|
||||
case 0x33: // FO1
|
||||
desc.userflags |= OP_USERFLAG_FIFOOUT1;
|
||||
desc.flags |= OPFLAG_IS_BRANCH_TARGET; // fifo check makes this a branch target
|
||||
break;
|
||||
|
||||
case 0x10: // EB
|
||||
case 0x11: // EBU
|
||||
case 0x12: // EBL
|
||||
case 0x13: // EO
|
||||
case 0x15: // ST
|
||||
case 0x16: // MOD
|
||||
case 0x17: // LRPC
|
||||
case 0x34: // PDR
|
||||
case 0x35: // DDR
|
||||
case 0x36: // PRP
|
||||
case 0x37: // PWP
|
||||
break;
|
||||
|
||||
case 0x30: // PR
|
||||
desc.userflags |= OP_USERFLAG_XFER_PWP_UPDATE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mb86235_frontend::describe_alu(opcode_desc &desc, uint32_t aluop)
|
||||
{
|
||||
int i1 = (aluop >> 10) & 0xf;
|
||||
int i2 = (aluop >> 5) & 0x1f;
|
||||
int io = aluop & 0x1f;
|
||||
int op = (aluop >> 14) & 0x1f;
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case 0x00: // FADD
|
||||
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AV_MODIFIED(desc);
|
||||
AU_MODIFIED(desc);
|
||||
break;
|
||||
case 0x01: // FADDZ
|
||||
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
|
||||
ZC_MODIFIED(desc);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AV_MODIFIED(desc);
|
||||
AU_MODIFIED(desc);
|
||||
AD_MODIFIED(desc);
|
||||
break;
|
||||
case 0x02: // FSUB
|
||||
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AV_MODIFIED(desc);
|
||||
AU_MODIFIED(desc);
|
||||
AD_MODIFIED(desc);
|
||||
break;
|
||||
case 0x03: // FSUBZ
|
||||
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
|
||||
ZC_MODIFIED(desc);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AV_MODIFIED(desc);
|
||||
AU_MODIFIED(desc);
|
||||
AD_MODIFIED(desc);
|
||||
break;
|
||||
case 0x04: // FCMP
|
||||
describe_alu_input(desc, i1); describe_alu_input(desc, i2);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AV_MODIFIED(desc);
|
||||
AU_MODIFIED(desc);
|
||||
AD_MODIFIED(desc);
|
||||
break;
|
||||
case 0x05: // FABS
|
||||
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AD_MODIFIED(desc);
|
||||
break;
|
||||
case 0x06: // FABC
|
||||
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AU_MODIFIED(desc);
|
||||
AD_MODIFIED(desc);
|
||||
break;
|
||||
case 0x07: // NOP
|
||||
break;
|
||||
case 0x08: // FEA
|
||||
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AV_MODIFIED(desc);
|
||||
AD_MODIFIED(desc);
|
||||
break;
|
||||
case 0x09: // FES
|
||||
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AU_MODIFIED(desc);
|
||||
AD_MODIFIED(desc);
|
||||
break;
|
||||
case 0x0a: // FRCP
|
||||
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
|
||||
ZD_MODIFIED(desc);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AU_MODIFIED(desc);
|
||||
AD_MODIFIED(desc);
|
||||
break;
|
||||
case 0x0b: // FRSQ
|
||||
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
|
||||
NR_MODIFIED(desc);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AU_MODIFIED(desc);
|
||||
AD_MODIFIED(desc);
|
||||
break;
|
||||
case 0x0c: // FLOG
|
||||
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
|
||||
IL_MODIFIED(desc);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AD_MODIFIED(desc);
|
||||
break;
|
||||
case 0x0d: // CIF
|
||||
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
break;
|
||||
case 0x0e: // CFI
|
||||
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AV_MODIFIED(desc);
|
||||
AD_MODIFIED(desc);
|
||||
break;
|
||||
case 0x0f: // CFIB
|
||||
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AV_MODIFIED(desc);
|
||||
AD_MODIFIED(desc);
|
||||
AU_MODIFIED(desc);
|
||||
break;
|
||||
case 0x10: // ADD
|
||||
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AV_MODIFIED(desc);
|
||||
break;
|
||||
case 0x11: // ADDZ
|
||||
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
|
||||
ZC_MODIFIED(desc);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AV_MODIFIED(desc);
|
||||
break;
|
||||
case 0x12: // SUB
|
||||
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AV_MODIFIED(desc);
|
||||
break;
|
||||
case 0x13: // SUBZ
|
||||
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
|
||||
ZC_MODIFIED(desc);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AV_MODIFIED(desc);
|
||||
break;
|
||||
case 0x14: // CMP
|
||||
describe_alu_input(desc, i1); describe_alu_input(desc, i2);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AV_MODIFIED(desc);
|
||||
break;
|
||||
case 0x15: // ABS
|
||||
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AV_MODIFIED(desc);
|
||||
break;
|
||||
case 0x16: // ATR
|
||||
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
|
||||
break;
|
||||
case 0x17: // ATRZ
|
||||
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
|
||||
ZC_MODIFIED(desc);
|
||||
break;
|
||||
case 0x18: // AND
|
||||
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AV_MODIFIED(desc);
|
||||
AU_MODIFIED(desc);
|
||||
break;
|
||||
case 0x19: // OR
|
||||
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AV_MODIFIED(desc);
|
||||
AU_MODIFIED(desc);
|
||||
break;
|
||||
case 0x1a: // XOR
|
||||
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AV_MODIFIED(desc);
|
||||
AU_MODIFIED(desc);
|
||||
break;
|
||||
case 0x1b: // NOT
|
||||
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AV_MODIFIED(desc);
|
||||
AU_MODIFIED(desc);
|
||||
break;
|
||||
case 0x1c: // LSR
|
||||
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AV_MODIFIED(desc);
|
||||
AU_MODIFIED(desc);
|
||||
break;
|
||||
case 0x1d: // LSL
|
||||
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
AV_MODIFIED(desc);
|
||||
AU_MODIFIED(desc);
|
||||
break;
|
||||
case 0x1e: // ASR
|
||||
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
break;
|
||||
case 0x1f: // ASL
|
||||
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
|
||||
AN_MODIFIED(desc);
|
||||
AZ_MODIFIED(desc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void mb86235_frontend::describe_mul(opcode_desc &desc, uint32_t mulop)
|
||||
{
|
||||
int i1 = (mulop >> 10) & 0xf;
|
||||
int i2 = (mulop >> 5) & 0x1f;
|
||||
int io = mulop & 0x1f;
|
||||
int m = mulop & 0x4000;
|
||||
|
||||
describe_mul_input(desc, i1);
|
||||
describe_mul_input(desc, i2);
|
||||
describe_alumul_output(desc, io);
|
||||
|
||||
if (m)
|
||||
{
|
||||
// FMUL
|
||||
MN_MODIFIED(desc);
|
||||
MZ_MODIFIED(desc);
|
||||
MV_MODIFIED(desc);
|
||||
MU_MODIFIED(desc);
|
||||
MD_MODIFIED(desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// MUL
|
||||
MN_MODIFIED(desc);
|
||||
MZ_MODIFIED(desc);
|
||||
MV_MODIFIED(desc);
|
||||
}
|
||||
}
|
||||
|
||||
void mb86235_frontend::describe_ea(opcode_desc &desc, int md, int arx, int ary, int disp)
|
||||
{
|
||||
switch (md)
|
||||
{
|
||||
case 0x0: // @ARx
|
||||
AR_USED(desc, arx);
|
||||
break;
|
||||
case 0x1: // @ARx++
|
||||
AR_USED(desc, arx); AR_MODIFIED(desc, arx);
|
||||
break;
|
||||
case 0x2: // @ARx--
|
||||
AR_USED(desc, arx); AR_MODIFIED(desc, arx);
|
||||
break;
|
||||
case 0x3: // @ARx++disp
|
||||
AR_USED(desc, arx); AR_MODIFIED(desc, arx);
|
||||
break;
|
||||
case 0x4: // @ARx+ARy
|
||||
AR_USED(desc, arx); AR_USED(desc, ary);
|
||||
break;
|
||||
case 0x5: // @ARx+ARy++
|
||||
AR_USED(desc, arx); AR_USED(desc, ary); AR_MODIFIED(desc, ary);
|
||||
break;
|
||||
case 0x6: // @ARx+ARy--
|
||||
AR_USED(desc, arx); AR_USED(desc, ary); AR_MODIFIED(desc, ary);
|
||||
break;
|
||||
case 0x7: // @ARx+ARy++disp
|
||||
AR_USED(desc, arx); AR_USED(desc, ary); AR_MODIFIED(desc, ary);
|
||||
break;
|
||||
case 0x8: // @ARx+ARyU
|
||||
AR_USED(desc, arx); AR_USED(desc, ary);
|
||||
break;
|
||||
case 0x9: // @ARx+ARyL
|
||||
AR_USED(desc, arx); AR_USED(desc, ary);
|
||||
break;
|
||||
case 0xa: // @ARx+disp
|
||||
AR_USED(desc, arx);
|
||||
break;
|
||||
case 0xb: // @ARx+ARy+disp
|
||||
AR_USED(desc, arx); AR_USED(desc, ary);
|
||||
break;
|
||||
case 0xc: // @disp
|
||||
break;
|
||||
case 0xd: // @ARx+[ARy++]
|
||||
AR_USED(desc, arx); AR_USED(desc, ary); AR_MODIFIED(desc, ary);
|
||||
break;
|
||||
case 0xe: // @ARx+[ARy--]
|
||||
AR_USED(desc, arx); AR_USED(desc, ary); AR_MODIFIED(desc, ary);
|
||||
break;
|
||||
case 0xf: // @ARx+[ARy++disp]
|
||||
AR_USED(desc, arx); AR_USED(desc, ary); AR_MODIFIED(desc, ary);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void mb86235_frontend::describe_xfer1(opcode_desc &desc)
|
||||
{
|
||||
uint64_t opcode = desc.opptr.q[0];
|
||||
fatalerror("mb86235_frontend: describe_xfer1 at %08X (%08X%08X)", desc.pc, (uint32_t)(opcode >> 32), (uint32_t)(opcode));
|
||||
}
|
||||
|
||||
void mb86235_frontend::describe_double_xfer1(opcode_desc &desc)
|
||||
{
|
||||
uint64_t opcode = desc.opptr.q[0];
|
||||
fatalerror("mb86235_frontend: describe_double_xfer1 at %08X (%08X%08X)", desc.pc, (uint32_t)(opcode >> 32), (uint32_t)(opcode));
|
||||
}
|
||||
|
||||
void mb86235_frontend::describe_xfer2(opcode_desc &desc)
|
||||
{
|
||||
uint64_t opcode = desc.opptr.q[0];
|
||||
|
||||
int op = (opcode >> 39) & 3;
|
||||
int trm = (opcode >> 38) & 1;
|
||||
int dir = (opcode >> 37) & 1;
|
||||
int sr = (opcode >> 31) & 0x7f;
|
||||
int dr = (opcode >> 24) & 0x7f;
|
||||
int ary = (opcode >> 4) & 7;
|
||||
int md = opcode & 0xf;
|
||||
int disp14 = (opcode >> 7) & 0x3fff;
|
||||
|
||||
if (op == 0) // MOV2
|
||||
{
|
||||
if (trm == 0)
|
||||
{
|
||||
if ((sr & 0x40) == 0)
|
||||
{
|
||||
describe_reg_read(desc, sr & 0x3f);
|
||||
}
|
||||
else if (sr == 0x58)
|
||||
{
|
||||
// MOV2 #imm24, DR
|
||||
}
|
||||
else
|
||||
{
|
||||
describe_ea(desc, md, sr & 7, ary, disp14);
|
||||
desc.flags |= OPFLAG_READS_MEMORY;
|
||||
}
|
||||
|
||||
if ((dr & 0x40) == 0)
|
||||
{
|
||||
describe_reg_write(desc, dr & 0x3f);
|
||||
}
|
||||
else
|
||||
{
|
||||
describe_ea(desc, md, dr & 7, ary, disp14);
|
||||
desc.flags |= OPFLAG_WRITES_MEMORY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// external transfer
|
||||
if (dir == 0)
|
||||
{
|
||||
describe_reg_read(desc, dr & 0x3f);
|
||||
desc.flags |= OPFLAG_WRITES_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
describe_reg_write(desc, dr & 0x3f);
|
||||
desc.flags |= OPFLAG_READS_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (op == 2) // MOV4
|
||||
{
|
||||
fatalerror("mb86235_frontend: describe_xfer2 MOV4 at %08X (%08X%08X)", desc.pc, (uint32_t)(opcode >> 32), (uint32_t)(opcode));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void mb86235_frontend::describe_double_xfer2(opcode_desc &desc)
|
||||
{
|
||||
uint64_t opcode = desc.opptr.q[0];
|
||||
fatalerror("mb86235_frontend: describe_double_xfer2 at %08X (%08X%08X)", desc.pc, (uint32_t)(opcode >> 32), (uint32_t)(opcode));
|
||||
}
|
||||
|
||||
void mb86235_frontend::describe_xfer3(opcode_desc &desc)
|
||||
{
|
||||
uint64_t opcode = desc.opptr.q[0];
|
||||
|
||||
int dr = (opcode >> 19) & 0x7f;
|
||||
int disp = (opcode >> 7) & 0xfff;
|
||||
int ary = (opcode >> 4) & 7;
|
||||
int md = opcode & 0xf;
|
||||
|
||||
switch (dr >> 4)
|
||||
{
|
||||
case 0:
|
||||
case 1: // reg
|
||||
describe_reg_write(desc, dr & 0x3f);
|
||||
break;
|
||||
|
||||
case 2: // RAM-A
|
||||
case 3: // RAM-B
|
||||
desc.flags |= OPFLAG_WRITES_MEMORY;
|
||||
describe_ea(desc, md, dr & 7, ary, disp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void mb86235_frontend::describe_control(opcode_desc &desc)
|
||||
{
|
||||
int ef1 = (desc.opptr.q[0] >> 16) & 0x3f;
|
||||
int ef2 = desc.opptr.q[0] & 0xffff;
|
||||
int cop = (desc.opptr.q[0] >> 22) & 0x1f;
|
||||
int rel12 = (desc.opptr.q[0] & 0x800) ? (0xfffff000 | (desc.opptr.q[0] & 0xfff)) : (desc.opptr.q[0] & 0xfff);
|
||||
|
||||
switch (cop)
|
||||
{
|
||||
case 0x00: // NOP
|
||||
break;
|
||||
case 0x01: // REP
|
||||
if (ef1 != 0) // ARx
|
||||
AR_USED(desc, (ef2 >> 12) & 7);
|
||||
|
||||
desc.userflags |= OP_USERFLAG_REPEAT;
|
||||
break;
|
||||
case 0x02: // SETL
|
||||
if (ef1 != 0) // ARx
|
||||
AR_USED(desc, (ef2 >> 12) & 7);
|
||||
break;
|
||||
case 0x03: // CLRFI/CLRFO/CLRF
|
||||
break;
|
||||
case 0x04: // PUSH
|
||||
describe_reg_read(desc, (ef2 >> 6) & 0x3f);
|
||||
break;
|
||||
case 0x05: // POP
|
||||
describe_reg_write(desc, (ef2 >> 6) & 0x3f);
|
||||
break;
|
||||
case 0x08: // SETM #imm16
|
||||
break;
|
||||
case 0x09: // SETM #imm3, CBSA
|
||||
break;
|
||||
case 0x0a: // SETM #imm3, CBSB
|
||||
break;
|
||||
case 0x0b: // SETM #imm1, RF
|
||||
break;
|
||||
case 0x0c: // SETM #imm1, RDY
|
||||
break;
|
||||
case 0x0d: // SETM #imm1, WAIT
|
||||
break;
|
||||
case 0x13: // DBLP rel12
|
||||
desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
|
||||
desc.targetpc = desc.pc + rel12;
|
||||
desc.delayslots = 1;
|
||||
break;
|
||||
case 0x14: // DBBC ARx:y, rel12
|
||||
desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
|
||||
desc.targetpc = desc.pc + rel12;
|
||||
desc.delayslots = 1;
|
||||
AR_USED(desc, ((desc.opptr.q[0] >> 13) & 7));
|
||||
break;
|
||||
case 0x15: // DBBS ARx:y, rel12
|
||||
desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
|
||||
desc.targetpc = desc.pc + rel12;
|
||||
desc.delayslots = 1;
|
||||
AR_USED(desc, ((desc.opptr.q[0] >> 13) & 7));
|
||||
break;
|
||||
case 0x1b: // DRET
|
||||
desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
|
||||
desc.targetpc = BRANCH_TARGET_DYNAMIC;
|
||||
desc.delayslots = 1;
|
||||
break;
|
||||
|
||||
case 0x10: // DBcc
|
||||
case 0x11: // DBNcc
|
||||
case 0x18: // DCcc
|
||||
case 0x19: // DCNcc
|
||||
{
|
||||
switch ((desc.opptr.q[0] >> 12) & 0xf)
|
||||
{
|
||||
case 0x0: desc.targetpc = ef2 & 0xfff; break;
|
||||
case 0x1: desc.targetpc = desc.pc + rel12; break;
|
||||
case 0x2: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
|
||||
case 0x3: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
|
||||
case 0x4: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
|
||||
case 0x5: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
|
||||
case 0x6: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
|
||||
case 0x7: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
|
||||
case 0x8: desc.targetpc = BRANCH_TARGET_DYNAMIC; break;
|
||||
case 0x9: desc.targetpc = BRANCH_TARGET_DYNAMIC; break;
|
||||
case 0xa: desc.targetpc = BRANCH_TARGET_DYNAMIC; break;
|
||||
case 0xb: desc.targetpc = BRANCH_TARGET_DYNAMIC; break;
|
||||
case 0xc: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
|
||||
case 0xd: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
|
||||
case 0xe: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
|
||||
case 0xf: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
|
||||
}
|
||||
|
||||
desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
|
||||
desc.delayslots = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x1a: // DCALL
|
||||
case 0x12: // DJMP
|
||||
{
|
||||
switch ((desc.opptr.q[0] >> 12) & 0xf)
|
||||
{
|
||||
case 0x0: desc.targetpc = ef2 & 0xfff; break;
|
||||
case 0x1: desc.targetpc = desc.pc + rel12; break;
|
||||
case 0x2: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
|
||||
case 0x3: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
|
||||
case 0x4: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
|
||||
case 0x5: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
|
||||
case 0x6: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
|
||||
case 0x7: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
|
||||
case 0x8: desc.targetpc = BRANCH_TARGET_DYNAMIC; break;
|
||||
case 0x9: desc.targetpc = BRANCH_TARGET_DYNAMIC; break;
|
||||
case 0xa: desc.targetpc = BRANCH_TARGET_DYNAMIC; break;
|
||||
case 0xb: desc.targetpc = BRANCH_TARGET_DYNAMIC; break;
|
||||
case 0xc: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
|
||||
case 0xd: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
|
||||
case 0xe: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
|
||||
case 0xf: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
|
||||
}
|
||||
|
||||
desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
|
||||
desc.delayslots = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
47
src/devices/cpu/mb86235/mb86235fe.h
Normal file
47
src/devices/cpu/mb86235/mb86235fe.h
Normal file
@ -0,0 +1,47 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ville Linde
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
Front-end for MB86235 recompiler
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mb86235.h"
|
||||
#include "cpu/drcfe.h"
|
||||
|
||||
#ifndef __MB86235FE_H__
|
||||
#define __MB86235FE_H__
|
||||
|
||||
class mb86235_frontend : public drc_frontend
|
||||
{
|
||||
public:
|
||||
mb86235_frontend(mb86235_device *core, uint32_t window_start, uint32_t window_end, uint32_t max_sequence);
|
||||
|
||||
protected:
|
||||
// required overrides
|
||||
virtual bool describe(opcode_desc &desc, const opcode_desc *prev) override;
|
||||
|
||||
private:
|
||||
|
||||
mb86235_device *m_core;
|
||||
|
||||
void describe_alu(opcode_desc &desc, uint32_t aluop);
|
||||
void describe_mul(opcode_desc &desc, uint32_t mulop);
|
||||
void describe_xfer1(opcode_desc &desc);
|
||||
void describe_double_xfer1(opcode_desc &desc);
|
||||
void describe_xfer2(opcode_desc &desc);
|
||||
void describe_double_xfer2(opcode_desc &desc);
|
||||
void describe_xfer3(opcode_desc &desc);
|
||||
void describe_control(opcode_desc &desc);
|
||||
void describe_alu_input(opcode_desc &desc, int reg);
|
||||
void describe_mul_input(opcode_desc &desc, int reg);
|
||||
void describe_alumul_output(opcode_desc &desc, int reg);
|
||||
void describe_reg_read(opcode_desc &desc, int reg);
|
||||
void describe_reg_write(opcode_desc &desc, int reg);
|
||||
void describe_ea(opcode_desc &desc, int md, int arx, int ary, int disp);
|
||||
};
|
||||
|
||||
#endif /* __MB86235FE_H__ */
|
@ -752,14 +752,42 @@ WRITE32_MEMBER(model2_state::copro_function_port_w)
|
||||
//logerror("copro_function_port_w: %08X, %08X, %08X\n", data, offset, mem_mask);
|
||||
if (m_dsp_type == DSP_TYPE_SHARC)
|
||||
copro_fifoin_push(machine().device("dsp"), d,offset,mem_mask);
|
||||
else
|
||||
else if (m_dsp_type == DSP_TYPE_TGP)
|
||||
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_tgpx4->fifoin_w(d);
|
||||
}
|
||||
}
|
||||
|
||||
READ32_MEMBER(model2_state::copro_fifo_r)
|
||||
{
|
||||
//logerror("copro_fifo_r: %08X, %08X\n", offset, mem_mask);
|
||||
return copro_fifoout_pop(space,offset,mem_mask);
|
||||
if (m_dsp_type == DSP_TYPE_SHARC || m_dsp_type == DSP_TYPE_TGP)
|
||||
{
|
||||
return copro_fifoout_pop(space, offset, mem_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO
|
||||
printf("FIFO OUT read\n");
|
||||
if (m_tgpx4->is_fifoout0_empty())
|
||||
{
|
||||
/* Reading from empty FIFO causes the i960 to enter wait state */
|
||||
downcast<i960_cpu_device &>(space.device()).i960_stall();
|
||||
/* spin the main cpu and let the TGP catch up */
|
||||
space.device().execute().spin_until_time(attotime::from_usec(100));
|
||||
printf("stalled\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
return (uint32_t)(m_tgpx4->fifoout0_r());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(model2_state::copro_fifo_w)
|
||||
@ -774,6 +802,19 @@ WRITE32_MEMBER(model2_state::copro_fifo_w)
|
||||
{
|
||||
m_tgp_program[m_coprocnt] = data;
|
||||
}
|
||||
else if (m_dsp_type == DSP_TYPE_TGPX4)
|
||||
{
|
||||
if (m_coprocnt & 1)
|
||||
{
|
||||
m_tgpx4_program[m_coprocnt / 2] &= 0xffffffffU;
|
||||
m_tgpx4_program[m_coprocnt / 2] |= u64(data) << 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tgpx4_program[m_coprocnt / 2] &= 0xffffffff00000000U;
|
||||
m_tgpx4_program[m_coprocnt / 2] |= data;
|
||||
}
|
||||
}
|
||||
|
||||
m_coprocnt++;
|
||||
}
|
||||
@ -785,8 +826,16 @@ WRITE32_MEMBER(model2_state::copro_fifo_w)
|
||||
//osd_printf_debug("copro_fifo_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, space.device().safe_pc());
|
||||
if (m_dsp_type == DSP_TYPE_SHARC)
|
||||
copro_fifoin_push(machine().device("dsp"), data,offset,mem_mask);
|
||||
else
|
||||
else if (m_dsp_type == DSP_TYPE_TGP)
|
||||
copro_fifoin_push(machine().device("tgp"), data,offset,mem_mask);
|
||||
else if (m_dsp_type == DSP_TYPE_TGPX4)
|
||||
{
|
||||
if (m_tgpx4->is_fifoin_full())
|
||||
printf("trying to push to full fifo!\n");
|
||||
|
||||
printf("push %08X at %08X\n", data, space.device().safe_pc());
|
||||
m_tgpx4->fifoin_w(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1624,7 +1673,8 @@ static ADDRESS_MAP_START( model2c_crx_mem, AS_PROGRAM, 32, model2_state )
|
||||
AM_RANGE(0x00200000, 0x0023ffff) AM_RAM
|
||||
|
||||
AM_RANGE(0x00804000, 0x00807fff) AM_READWRITE(geo_prg_r, geo_prg_w)
|
||||
AM_RANGE(0x00884000, 0x00887fff) AM_READWRITE(copro_prg_r, copro_prg_w)
|
||||
AM_RANGE(0x00880000, 0x00883fff) AM_WRITE(copro_function_port_w)
|
||||
AM_RANGE(0x00884000, 0x00887fff) AM_READWRITE(copro_fifo_r, copro_fifo_w)
|
||||
|
||||
AM_RANGE(0x00980000, 0x00980003) AM_READWRITE(copro_ctl1_r,copro_ctl1_w)
|
||||
AM_RANGE(0x00980008, 0x0098000b) AM_WRITE(geo_ctl1_w )
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "audio/segam1audio.h"
|
||||
#include "machine/eepromser.h"
|
||||
#include "cpu/i960/i960.h"
|
||||
#include "cpu/mb86235/mb86235.h"
|
||||
#include "sound/scsp.h"
|
||||
#include "machine/315-5881_crypt.h"
|
||||
#include "machine/315-5838_317-0229_comp.h"
|
||||
@ -67,7 +68,7 @@ public:
|
||||
optional_device<cpu_device> m_audiocpu;
|
||||
optional_device<cpu_device> m_tgp;
|
||||
optional_device<cpu_device> m_dsp;
|
||||
optional_device<cpu_device> m_tgpx4;
|
||||
optional_device<mb86235_device> m_tgpx4;
|
||||
optional_device<cpu_device> m_drivecpu;
|
||||
required_device<eeprom_serial_93cxx_device> m_eeprom;
|
||||
required_device<screen_device> m_screen;
|
||||
|
Loading…
Reference in New Issue
Block a user