mirror of
https://github.com/holub/mame
synced 2025-10-05 08:41:31 +03:00
MIPS: initial support for VR5500 and TX4925 CPUs. [R. Belmont]
This commit is contained in:
parent
43eeb96ee3
commit
8ce5aa566f
@ -108,8 +108,12 @@ const device_type R4650BE = device_creator<r4650be_device>;
|
||||
const device_type R4650LE = device_creator<r4650le_device>;
|
||||
const device_type R4700BE = device_creator<r4700be_device>;
|
||||
const device_type R4700LE = device_creator<r4700le_device>;
|
||||
const device_type TX4925BE = device_creator<tx4925be_device>;
|
||||
const device_type TX4925LE = device_creator<tx4925le_device>;
|
||||
const device_type R5000BE = device_creator<r5000be_device>;
|
||||
const device_type R5000LE = device_creator<r5000le_device>;
|
||||
const device_type VR5500BE = device_creator<vr5500be_device>;
|
||||
const device_type VR5500LE = device_creator<vr5500le_device>;
|
||||
const device_type QED5271BE = device_creator<qed5271be_device>;
|
||||
const device_type QED5271LE = device_creator<qed5271le_device>;
|
||||
const device_type RM7000BE = device_creator<rm7000be_device>;
|
||||
@ -974,6 +978,12 @@ offs_t mips3_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u
|
||||
|
||||
inline bool mips3_device::RBYTE(offs_t address, uint32_t *result)
|
||||
{
|
||||
if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000))
|
||||
{
|
||||
*result = (*m_memory.read_byte)(*m_program, address);
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & VTLB_READ_ALLOWED)
|
||||
{
|
||||
@ -1007,6 +1017,12 @@ inline bool mips3_device::RBYTE(offs_t address, uint32_t *result)
|
||||
|
||||
inline bool mips3_device::RHALF(offs_t address, uint32_t *result)
|
||||
{
|
||||
if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000))
|
||||
{
|
||||
*result = (*m_memory.read_word)(*m_program, address);
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & VTLB_READ_ALLOWED)
|
||||
{
|
||||
@ -1040,6 +1056,12 @@ inline bool mips3_device::RHALF(offs_t address, uint32_t *result)
|
||||
|
||||
inline bool mips3_device::RWORD(offs_t address, uint32_t *result)
|
||||
{
|
||||
if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000))
|
||||
{
|
||||
*result = (*m_memory.read_dword)(*m_program, address);
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & VTLB_READ_ALLOWED)
|
||||
{
|
||||
@ -1073,6 +1095,12 @@ inline bool mips3_device::RWORD(offs_t address, uint32_t *result)
|
||||
|
||||
inline bool mips3_device::RWORD_MASKED(offs_t address, uint32_t *result, uint32_t mem_mask)
|
||||
{
|
||||
if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000))
|
||||
{
|
||||
*result = (*m_memory.read_dword_masked)(*m_program, address, mem_mask);
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & VTLB_READ_ALLOWED)
|
||||
{
|
||||
@ -1096,6 +1124,11 @@ inline bool mips3_device::RWORD_MASKED(offs_t address, uint32_t *result, uint32_
|
||||
|
||||
inline bool mips3_device::RDOUBLE(offs_t address, uint64_t *result)
|
||||
{
|
||||
if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000))
|
||||
{
|
||||
*result = (*m_memory.read_qword)(*m_program, address);
|
||||
return true;
|
||||
}
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & VTLB_READ_ALLOWED)
|
||||
{
|
||||
@ -1119,6 +1152,12 @@ inline bool mips3_device::RDOUBLE(offs_t address, uint64_t *result)
|
||||
|
||||
inline bool mips3_device::RDOUBLE_MASKED(offs_t address, uint64_t *result, uint64_t mem_mask)
|
||||
{
|
||||
if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000))
|
||||
{
|
||||
*result = (*m_memory.read_qword_masked)(*m_program, address, mem_mask);
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & VTLB_READ_ALLOWED)
|
||||
{
|
||||
@ -1142,6 +1181,12 @@ inline bool mips3_device::RDOUBLE_MASKED(offs_t address, uint64_t *result, uint6
|
||||
|
||||
inline void mips3_device::WBYTE(offs_t address, uint8_t data)
|
||||
{
|
||||
if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000))
|
||||
{
|
||||
(*m_memory.write_byte)(*m_program, address, data);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & VTLB_WRITE_ALLOWED)
|
||||
{
|
||||
@ -1176,6 +1221,11 @@ inline void mips3_device::WBYTE(offs_t address, uint8_t data)
|
||||
|
||||
inline void mips3_device::WHALF(offs_t address, uint16_t data)
|
||||
{
|
||||
if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000))
|
||||
{
|
||||
(*m_memory.write_word)(*m_program, address, data);
|
||||
return;
|
||||
}
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & VTLB_WRITE_ALLOWED)
|
||||
{
|
||||
@ -1210,6 +1260,12 @@ inline void mips3_device::WHALF(offs_t address, uint16_t data)
|
||||
|
||||
inline void mips3_device::WWORD(offs_t address, uint32_t data)
|
||||
{
|
||||
if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000))
|
||||
{
|
||||
(*m_memory.write_dword)(*m_program, address, data);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & VTLB_WRITE_ALLOWED)
|
||||
{
|
||||
@ -1244,6 +1300,12 @@ inline void mips3_device::WWORD(offs_t address, uint32_t data)
|
||||
|
||||
inline void mips3_device::WWORD_MASKED(offs_t address, uint32_t data, uint32_t mem_mask)
|
||||
{
|
||||
if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000))
|
||||
{
|
||||
(*m_memory.write_dword_masked)(*m_program, address, data, mem_mask);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & VTLB_WRITE_ALLOWED)
|
||||
{
|
||||
@ -1268,6 +1330,12 @@ inline void mips3_device::WWORD_MASKED(offs_t address, uint32_t data, uint32_t m
|
||||
|
||||
inline void mips3_device::WDOUBLE(offs_t address, uint64_t data)
|
||||
{
|
||||
if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000))
|
||||
{
|
||||
(*m_memory.write_qword)(*m_program, address, data);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & VTLB_WRITE_ALLOWED)
|
||||
{
|
||||
@ -1292,6 +1360,12 @@ inline void mips3_device::WDOUBLE(offs_t address, uint64_t data)
|
||||
|
||||
inline void mips3_device::WDOUBLE_MASKED(offs_t address, uint64_t data, uint64_t mem_mask)
|
||||
{
|
||||
if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000))
|
||||
{
|
||||
(*m_memory.write_qword_masked)(*m_program, address, data, mem_mask);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & VTLB_WRITE_ALLOWED)
|
||||
{
|
||||
|
@ -33,8 +33,12 @@ extern const device_type R4650BE;
|
||||
extern const device_type R4650LE;
|
||||
extern const device_type R4700BE;
|
||||
extern const device_type R4700LE;
|
||||
extern const device_type TX4925BE;
|
||||
extern const device_type TX4925LE;
|
||||
extern const device_type R5000BE;
|
||||
extern const device_type R5000LE;
|
||||
extern const device_type VR5500BE;
|
||||
extern const device_type VR5500LE;
|
||||
extern const device_type QED5271BE;
|
||||
extern const device_type QED5271LE;
|
||||
extern const device_type RM7000BE;
|
||||
@ -259,10 +263,12 @@ protected:
|
||||
MIPS3_TYPE_R4600,
|
||||
MIPS3_TYPE_R4650,
|
||||
MIPS3_TYPE_R4700,
|
||||
MIPS3_TYPE_TX4925,
|
||||
|
||||
/* MIPS IV variants */
|
||||
MIPS3_TYPE_MIPS_IV,
|
||||
MIPS3_TYPE_R5000,
|
||||
MIPS3_TYPE_VR5500,
|
||||
MIPS3_TYPE_QED5271,
|
||||
MIPS3_TYPE_RM7000
|
||||
};
|
||||
@ -662,6 +668,24 @@ public:
|
||||
{ }
|
||||
};
|
||||
|
||||
class tx4925be_device : public mips3_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
tx4925be_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: mips3_device(mconfig, TX4925BE, "TX4925 (big)", tag, owner, clock, "tx4925be", MIPS3_TYPE_TX4925, ENDIANNESS_BIG)
|
||||
{ }
|
||||
};
|
||||
|
||||
class tx4925le_device : public mips3_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
tx4925le_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: mips3_device(mconfig, TX4925LE, "TX4925 (little)", tag, owner, clock, "tx4925le", MIPS3_TYPE_TX4925, ENDIANNESS_LITTLE)
|
||||
{ }
|
||||
};
|
||||
|
||||
class r5000be_device : public mips3_device
|
||||
{
|
||||
public:
|
||||
@ -680,6 +704,24 @@ public:
|
||||
{ }
|
||||
};
|
||||
|
||||
class vr5500be_device : public mips3_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
vr5500be_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: mips3_device(mconfig, VR5500BE, "VR5500 (big)", tag, owner, clock, "vr5500be", MIPS3_TYPE_R5000, ENDIANNESS_BIG)
|
||||
{ }
|
||||
};
|
||||
|
||||
class vr5500le_device : public mips3_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
vr5500le_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: mips3_device(mconfig, VR5500LE, "VR5500 (little)", tag, owner, clock, "r5500le", MIPS3_TYPE_R5000, ENDIANNESS_LITTLE)
|
||||
{ }
|
||||
};
|
||||
|
||||
class qed5271be_device : public mips3_device
|
||||
{
|
||||
public:
|
||||
|
@ -230,6 +230,24 @@ uint32_t mips3_device::compute_config_register()
|
||||
|
||||
configreg = 0x6460;
|
||||
}
|
||||
else if (m_flavor == MIPS3_TYPE_VR5500)
|
||||
{
|
||||
/*
|
||||
For VR55xx, Config is as follows:
|
||||
bit 31 = always 0
|
||||
bits 28-30 = EC
|
||||
bits 24-27 = EP
|
||||
bits 23-22 = EM
|
||||
bits 21-20 = always b11
|
||||
bits 19-18 = EW
|
||||
bits 17-16 = always b10
|
||||
bit 15 = endian indicator as standard MIPS III
|
||||
bits 3-14 = always b110011011110
|
||||
bits 0-2 = K0 ("Coherency algorithm of kseg0")
|
||||
*/
|
||||
|
||||
configreg = 0x6460;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* set the data cache size */
|
||||
@ -287,6 +305,9 @@ uint32_t mips3_device::compute_prid_register()
|
||||
case MIPS3_TYPE_VR4300:
|
||||
return 0x0b00;
|
||||
|
||||
case MIPS3_TYPE_VR5500:
|
||||
return 0x5500;
|
||||
|
||||
case MIPS3_TYPE_R4600:
|
||||
case MIPS3_TYPE_R4650:
|
||||
return 0x2000;
|
||||
@ -294,6 +315,9 @@ uint32_t mips3_device::compute_prid_register()
|
||||
case MIPS3_TYPE_R4700:
|
||||
return 0x2100;
|
||||
|
||||
case MIPS3_TYPE_TX4925:
|
||||
return 0x2d23;
|
||||
|
||||
case MIPS3_TYPE_R5000:
|
||||
case MIPS3_TYPE_QED5271:
|
||||
return 0x2300;
|
||||
|
@ -840,6 +840,69 @@ void mips3_device::static_generate_memory_accessor(int mode, int size, int iswri
|
||||
UML_LABEL(block, addrok); // addrok:
|
||||
}
|
||||
|
||||
/* TX4925 on-board peripherals pass-through */
|
||||
if (m_flavor == MIPS3_TYPE_TX4925)
|
||||
{
|
||||
int addrok;
|
||||
UML_AND(block, I3, I0, 0xffff0000); // and i3, i0, 0xffff0000
|
||||
UML_CMP(block, I3, 0xff1f0000); // cmp i3, 0xff1f0000
|
||||
UML_JMPc(block, COND_NZ, addrok = label++);
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
if (iswrite)
|
||||
UML_WRITE(block, I0, I1, SIZE_BYTE, SPACE_PROGRAM); // write i0,i1,program_byte
|
||||
else
|
||||
UML_READ(block, I0, I0, SIZE_BYTE, SPACE_PROGRAM); // read i0,i0,program_byte
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (iswrite)
|
||||
UML_WRITE(block, I0, I1, SIZE_WORD, SPACE_PROGRAM); // write i0,i1,program_word
|
||||
else
|
||||
UML_READ(block, I0, I0, SIZE_WORD, SPACE_PROGRAM); // read i0,i0,program_word
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (iswrite)
|
||||
{
|
||||
if (!ismasked)
|
||||
UML_WRITE(block, I0, I1, SIZE_DWORD, SPACE_PROGRAM); // write i0,i1,program_dword
|
||||
else
|
||||
UML_WRITEM(block, I0, I1, I2, SIZE_DWORD, SPACE_PROGRAM); // writem i0,i1,i2,program_dword
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ismasked)
|
||||
UML_READ(block, I0, I0, SIZE_DWORD, SPACE_PROGRAM); // read i0,i0,program_dword
|
||||
else
|
||||
UML_READM(block, I0, I0, I2, SIZE_DWORD, SPACE_PROGRAM); // readm i0,i0,i2,program_dword
|
||||
}
|
||||
break;
|
||||
|
||||
case 8:
|
||||
if (iswrite)
|
||||
{
|
||||
if (!ismasked)
|
||||
UML_DWRITE(block, I0, I1, SIZE_QWORD, SPACE_PROGRAM); // dwrite i0,i1,program_qword
|
||||
else
|
||||
UML_DWRITEM(block, I0, I1, I2, SIZE_QWORD, SPACE_PROGRAM); // dwritem i0,i1,i2,program_qword
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ismasked)
|
||||
UML_DREAD(block, I0, I0, SIZE_QWORD, SPACE_PROGRAM); // dread i0,i0,program_qword
|
||||
else
|
||||
UML_DREADM(block, I0, I0, I2, SIZE_QWORD, SPACE_PROGRAM); // dreadm i0,i0,i2,program_qword
|
||||
}
|
||||
break;
|
||||
}
|
||||
UML_RET(block);
|
||||
|
||||
UML_LABEL(block, addrok);
|
||||
}
|
||||
|
||||
/* general case: assume paging and perform a translation */
|
||||
UML_SHR(block, I3, I0, 12); // shr i3,i0,12
|
||||
UML_LOAD(block, I3, (void *)vtlb_table(), I3, SIZE_DWORD, SCALE_x4);// load i3,[vtlb_table],i3,dword
|
||||
|
Loading…
Reference in New Issue
Block a user