pc532: add floating-point unit

* ns32381: add new device
* ns32k: refactor slave interface
* ns32k: fix format 9 instruction decoding
This commit is contained in:
Patrick Mackinlay 2024-02-28 17:55:02 +07:00
parent bdda7084bb
commit ca431df745
8 changed files with 757 additions and 559 deletions

View File

@ -32,38 +32,6 @@ namespace ns32000
}; };
} }
class ns32000_state_interface
{
public:
virtual void state_add(device_state_interface &parent, int &index) = 0;
};
class ns32000_fpu_interface
: public device_interface
, public ns32000_state_interface
{
protected:
ns32000_fpu_interface(machine_config const &mconfig, device_t &device)
: device_interface(device, "ns32000_fpu")
{
}
};
class ns32000_mmu_interface
: public device_interface
, public ns32000_state_interface
{
public:
enum translate_result : unsigned { COMPLETE, CANCEL, ABORT };
virtual translate_result translate(address_space &space, unsigned st, u32 &address, bool user, bool write, bool flag = false, bool suppress = false) = 0;
protected:
ns32000_mmu_interface(machine_config const &mconfig, device_t &device)
: device_interface(device, "ns32000_mmu")
{
}
};
class ns32000_slave_interface : public device_interface class ns32000_slave_interface : public device_interface
{ {
public: public:
@ -75,6 +43,14 @@ public:
{ {
} }
enum slave_idbyte : u8
{
FORMAT_9 = 0x3e, // fpu
FORMAT_11 = 0xbe, // fpu
FORMAT_12 = 0xfe, // fpu
FORMAT_14 = 0x1e, // mmu
};
enum slave_status : u16 enum slave_status : u16
{ {
SLAVE_Q = 0x0001, // quit (1=error) SLAVE_Q = 0x0001, // quit (1=error)
@ -87,6 +63,8 @@ public:
SLAVE_OK = 0, SLAVE_OK = 0,
}; };
virtual void state_add(device_state_interface &parent, int &index) = 0;
protected: protected:
ns32000_slave_interface(machine_config const &mconfig, device_t &device, char const *type) ns32000_slave_interface(machine_config const &mconfig, device_t &device, char const *type)
: device_interface(device, type) : device_interface(device, type)
@ -97,31 +75,52 @@ protected:
devcb_write_line m_out_scb; devcb_write_line m_out_scb;
}; };
class ns32000_slow_slave_interface : public ns32000_slave_interface class ns32000_fpu_interface : public ns32000_slave_interface
{ {
public:
virtual void write_id(u16 data) = 0;
virtual void write_op(u16 data) = 0;
virtual u16 read_st(int *icount = nullptr) = 0;
virtual u16 read_op() = 0;
protected: protected:
ns32000_slow_slave_interface(machine_config const &mconfig, device_t &device) ns32000_fpu_interface(machine_config const &mconfig, device_t &device)
: ns32000_slave_interface(mconfig, device) : ns32000_slave_interface(mconfig, device)
{ {
} }
}; };
class ns32000_fast_slave_interface : public ns32000_slave_interface class ns32000_mmu_interface : public ns32000_slave_interface
{ {
public: public:
virtual u32 read_st32(int *icount = nullptr) = 0; enum translate_result : unsigned { COMPLETE, CANCEL, ABORT };
virtual u32 read() = 0; virtual translate_result translate(address_space &space, unsigned st, u32 &address, bool user, bool write, bool flag = false, bool suppress = false) = 0;
virtual void write(u32 data) = 0;
protected:
ns32000_mmu_interface(machine_config const &mconfig, device_t &device)
: ns32000_slave_interface(mconfig, device)
{
}
};
class ns32000_slow_slave_interface : public device_interface
{
public:
virtual u16 slow_status(int *icount = nullptr) = 0;
virtual u16 slow_read() = 0;
virtual void slow_write(u16 data) = 0;
protected:
ns32000_slow_slave_interface(machine_config const &mconfig, device_t &device)
: device_interface(device, "ns32000_slave_slow")
{
}
};
class ns32000_fast_slave_interface : public device_interface
{
public:
virtual u32 fast_status(int *icount = nullptr) = 0;
virtual u32 fast_read() = 0;
virtual void fast_write(u32 data) = 0;
protected: protected:
ns32000_fast_slave_interface(machine_config const &mconfig, device_t &device) ns32000_fast_slave_interface(machine_config const &mconfig, device_t &device)
: ns32000_slave_interface(mconfig, device) : device_interface(device, "ns32000_slave_fast")
{ {
} }
}; };

View File

@ -3128,14 +3128,14 @@ template <int HighBits, int Width> void ns32000_device<HighBits, Width>::execute
} }
} }
break; break;
case 0x3e: case ns32000_slave_interface::FORMAT_9:
// format 9: xxxx xyyy yyoo ofii 0011 1110 // format 9: xxxx xyyy yyoo ofii 0011 1110
if (m_cfg & CFG_F) if (m_cfg & CFG_F)
{ {
u16 const opword = fetch<u16>(bytes); u16 const opword = fetch<u16>(bytes);
addr_mode mode[] = { addr_mode(BIT(opword, 11, 5)), addr_mode(BIT(opword, 6, 5)) }; addr_mode mode[] = { addr_mode(BIT(opword, 11, 5)), addr_mode(BIT(opword, 6, 5)) };
size_code const size_f = BIT(opword, 0) ? SIZE_D : SIZE_Q; size_code const size_f = BIT(opword, 2) ? SIZE_D : SIZE_Q;
size_code const size = size_code(opword & 3); size_code const size = size_code(opword & 3);
switch (BIT(opword, 3, 3)) switch (BIT(opword, 3, 3))
@ -3234,7 +3234,7 @@ template <int HighBits, int Width> void ns32000_device<HighBits, Width>::execute
case 0x7e: // format 10 case 0x7e: // format 10
interrupt(UND); interrupt(UND);
break; break;
case 0xbe: case ns32000_slave_interface::FORMAT_11:
// format 11: xxxx xyyy yyoo oo0f 1011 1110 // format 11: xxxx xyyy yyoo oo0f 1011 1110
if (m_cfg & CFG_F) if (m_cfg & CFG_F)
{ {
@ -3366,7 +3366,7 @@ template <int HighBits, int Width> void ns32000_device<HighBits, Width>::execute
else else
interrupt(UND); interrupt(UND);
break; break;
case 0xfe: case ns32000_slave_interface::FORMAT_12:
// format 12: xxxx xyyy yyoo oo0f 1111 1110 // format 12: xxxx xyyy yyoo oo0f 1111 1110
if ((m_cfg & CFG_F) && type() == NS32332) if ((m_cfg & CFG_F) && type() == NS32332)
{ {
@ -3459,7 +3459,7 @@ template <int HighBits, int Width> void ns32000_device<HighBits, Width>::execute
case 0x9e: // format 13 case 0x9e: // format 13
interrupt(UND); interrupt(UND);
break; break;
case 0x1e: case ns32000_slave_interface::FORMAT_14:
// format 14: xxxx xsss s0oo ooii 0001 1110 // format 14: xxxx xsss s0oo ooii 0001 1110
if (!(m_psr & PSR_U)) if (!(m_psr & PSR_U))
{ {
@ -3671,7 +3671,7 @@ template <int HighBits, int Width> u16 ns32000_device<HighBits, Width>::slave(u8
{ {
switch (opbyte) switch (opbyte)
{ {
case 0x1e: case ns32000_slave_interface::FORMAT_14:
if (!m_mmu) if (!m_mmu)
fatalerror("slave mmu coprocessor not configured (%s)\n", machine().describe_context()); fatalerror("slave mmu coprocessor not configured (%s)\n", machine().describe_context());
@ -3681,9 +3681,9 @@ template <int HighBits, int Width> u16 ns32000_device<HighBits, Width>::slave(u8
return slave_slow(dynamic_cast<ns32000_slow_slave_interface &>(*m_mmu), opbyte, opword, op1, op2); return slave_slow(dynamic_cast<ns32000_slow_slave_interface &>(*m_mmu), opbyte, opword, op1, op2);
break; break;
case 0x3e: case ns32000_slave_interface::FORMAT_9:
case 0xbe: case ns32000_slave_interface::FORMAT_11:
case 0xfe: case ns32000_slave_interface::FORMAT_12:
if (!m_fpu) if (!m_fpu)
fatalerror("slave fpu coprocessor not configured (%s)\n", machine().describe_context()); fatalerror("slave fpu coprocessor not configured (%s)\n", machine().describe_context());
@ -3701,8 +3701,8 @@ template <int HighBits, int Width> u16 ns32000_device<HighBits, Width>::slave(u8
template <int HighBits, int Width> u16 ns32000_device<HighBits, Width>::slave_slow(ns32000_slow_slave_interface &slave, u8 opbyte, u16 opword, addr_mode op1, addr_mode op2) template <int HighBits, int Width> u16 ns32000_device<HighBits, Width>::slave_slow(ns32000_slow_slave_interface &slave, u8 opbyte, u16 opword, addr_mode op1, addr_mode op2)
{ {
slave.write_id(opbyte); slave.slow_write(opbyte);
slave.write_op(swapendian_int16(opword)); slave.slow_write(swapendian_int16(opword));
if ((op1.access == READ || op1.access == RMW) && !(op1.type == REG && op1.slave)) if ((op1.access == READ || op1.access == RMW) && !(op1.type == REG && op1.slave))
{ {
@ -3711,20 +3711,20 @@ template <int HighBits, int Width> u16 ns32000_device<HighBits, Width>::slave_sl
switch (op1.size) switch (op1.size)
{ {
case SIZE_B: case SIZE_B:
slave.write_op(u8(data)); slave.slow_write(u8(data));
break; break;
case SIZE_W: case SIZE_W:
slave.write_op(u16(data)); slave.slow_write(u16(data));
break; break;
case SIZE_D: case SIZE_D:
slave.write_op(u16(data >> 0)); slave.slow_write(u16(data >> 0));
slave.write_op(u16(data >> 16)); slave.slow_write(u16(data >> 16));
break; break;
case SIZE_Q: case SIZE_Q:
slave.write_op(u16(data >> 0)); slave.slow_write(u16(data >> 0));
slave.write_op(u16(data >> 16)); slave.slow_write(u16(data >> 16));
slave.write_op(u16(data >> 32)); slave.slow_write(u16(data >> 32));
slave.write_op(u16(data >> 48)); slave.slow_write(u16(data >> 48));
break; break;
} }
} }
@ -3732,8 +3732,8 @@ template <int HighBits, int Width> u16 ns32000_device<HighBits, Width>::slave_sl
{ {
u32 const data = ea(op1); u32 const data = ea(op1);
slave.write_op(u16(data >> 0)); slave.slow_write(u16(data >> 0));
slave.write_op(u16(data >> 16)); slave.slow_write(u16(data >> 16));
// single-byte memory read cycle // single-byte memory read cycle
mem_read<u8>(ns32000::ST_ODT, data, true); mem_read<u8>(ns32000::ST_ODT, data, true);
@ -3746,41 +3746,41 @@ template <int HighBits, int Width> u16 ns32000_device<HighBits, Width>::slave_sl
switch (op2.size) switch (op2.size)
{ {
case SIZE_B: case SIZE_B:
slave.write_op(u8(data)); slave.slow_write(u8(data));
break; break;
case SIZE_W: case SIZE_W:
slave.write_op(u16(data)); slave.slow_write(u16(data));
break; break;
case SIZE_D: case SIZE_D:
slave.write_op(u16(data >> 0)); slave.slow_write(u16(data >> 0));
slave.write_op(u16(data >> 16)); slave.slow_write(u16(data >> 16));
break; break;
case SIZE_Q: case SIZE_Q:
slave.write_op(u16(data >> 0)); slave.slow_write(u16(data >> 0));
slave.write_op(u16(data >> 16)); slave.slow_write(u16(data >> 16));
slave.write_op(u16(data >> 32)); slave.slow_write(u16(data >> 32));
slave.write_op(u16(data >> 48)); slave.slow_write(u16(data >> 48));
break; break;
} }
} }
u16 const status = slave.read_st(&m_icount); u16 const status = slave.slow_status(&m_icount);
if (!(status & ns32000_slave_interface::SLAVE_Q)) if (!(status & ns32000_slave_interface::SLAVE_Q))
{ {
if ((op2.access == WRITE || op2.access == RMW) && !(op2.type == REG && op2.slave)) if ((op2.access == WRITE || op2.access == RMW) && !(op2.type == REG && op2.slave))
{ {
u64 data = slave.read_op(); u64 data = slave.slow_read();
switch (op2.size) switch (op2.size)
{ {
case SIZE_D: case SIZE_D:
data |= u64(slave.read_op()) << 16; data |= u64(slave.slow_read()) << 16;
break; break;
case SIZE_Q: case SIZE_Q:
data |= u64(slave.read_op()) << 16; data |= u64(slave.slow_read()) << 16;
data |= u64(slave.read_op()) << 32; data |= u64(slave.slow_read()) << 32;
data |= u64(slave.read_op()) << 48; data |= u64(slave.slow_read()) << 48;
break; break;
default: default:
break; break;
@ -3795,7 +3795,7 @@ template <int HighBits, int Width> u16 ns32000_device<HighBits, Width>::slave_sl
template <int HighBits, int Width> u16 ns32000_device<HighBits, Width>::slave_fast(ns32000_fast_slave_interface &slave, u8 opbyte, u16 opword, addr_mode op1, addr_mode op2) template <int HighBits, int Width> u16 ns32000_device<HighBits, Width>::slave_fast(ns32000_fast_slave_interface &slave, u8 opbyte, u16 opword, addr_mode op1, addr_mode op2)
{ {
slave.write(u32(opbyte) << 24 | u32(swapendian_int16(opword)) << 8); slave.fast_write(u32(opbyte) << 24 | u32(swapendian_int16(opword)) << 8);
if ((op1.access == READ || op1.access == RMW) && !(op1.type == REG && op1.slave)) if ((op1.access == READ || op1.access == RMW) && !(op1.type == REG && op1.slave))
{ {
@ -3804,17 +3804,17 @@ template <int HighBits, int Width> u16 ns32000_device<HighBits, Width>::slave_fa
switch (op1.size) switch (op1.size)
{ {
case SIZE_B: case SIZE_B:
slave.write(u8(data)); slave.fast_write(u8(data));
break; break;
case SIZE_W: case SIZE_W:
slave.write(u16(data)); slave.fast_write(u16(data));
break; break;
case SIZE_D: case SIZE_D:
slave.write(u32(data)); slave.fast_write(u32(data));
break; break;
case SIZE_Q: case SIZE_Q:
slave.write(u32(data >> 0)); slave.fast_write(u32(data >> 0));
slave.write(u32(data >> 32)); slave.fast_write(u32(data >> 32));
break; break;
} }
} }
@ -3822,7 +3822,7 @@ template <int HighBits, int Width> u16 ns32000_device<HighBits, Width>::slave_fa
{ {
u32 const data = ea(op1); u32 const data = ea(op1);
slave.write(u32(data)); slave.fast_write(u32(data));
// single-byte memory read cycle // single-byte memory read cycle
mem_read<u8>(ns32000::ST_ODT, data, true); mem_read<u8>(ns32000::ST_ODT, data, true);
@ -3835,32 +3835,32 @@ template <int HighBits, int Width> u16 ns32000_device<HighBits, Width>::slave_fa
switch (op2.size) switch (op2.size)
{ {
case SIZE_B: case SIZE_B:
slave.write(u8(data)); slave.fast_write(u8(data));
break; break;
case SIZE_W: case SIZE_W:
slave.write(u16(data)); slave.fast_write(u16(data));
break; break;
case SIZE_D: case SIZE_D:
slave.write(u32(data)); slave.fast_write(u32(data));
break; break;
case SIZE_Q: case SIZE_Q:
slave.write(u32(data >> 0)); slave.fast_write(u32(data >> 0));
slave.write(u32(data >> 32)); slave.fast_write(u32(data >> 32));
break; break;
} }
} }
// TODO: status is optional in fast protocol // TODO: status is optional in fast protocol
u32 const status = slave.read_st32(&m_icount); u32 const status = slave.fast_status(&m_icount);
if (!(status & ns32000_slave_interface::SLAVE_Q)) if (!(status & ns32000_slave_interface::SLAVE_Q))
{ {
if ((op2.access == WRITE || op2.access == RMW) && !(op2.type == REG && op2.slave)) if ((op2.access == WRITE || op2.access == RMW) && !(op2.type == REG && op2.slave))
{ {
u64 data = slave.read(); u64 data = slave.fast_read();
if (op2.size == SIZE_Q) if (op2.size == SIZE_Q)
data |= u64(slave.read()) << 32; data |= u64(slave.fast_read()) << 32;
gen_write(op2, data); gen_write(op2, data);
} }
@ -4162,7 +4162,7 @@ void ns32532_device::spr(unsigned reg, addr_mode const mode, bool user, unsigned
u16 ns32532_device::slave(u8 opbyte, u16 opword, addr_mode op1, addr_mode op2) u16 ns32532_device::slave(u8 opbyte, u16 opword, addr_mode op1, addr_mode op2)
{ {
if (opbyte == 0x1e) if (opbyte == FORMAT_14)
{ {
switch (BIT(opword, 2, 4)) switch (BIT(opword, 2, 4))
{ {

View File

@ -461,7 +461,7 @@ offs_t ns32000_disassembler::disassemble(std::ostream &stream, offs_t pc, data_b
u16 const opword = opcodes.r16(pc + bytes); bytes += 2; u16 const opword = opcodes.r16(pc + bytes); bytes += 2;
addr_mode mode[] = { addr_mode(BIT(opword, 11, 5)), addr_mode(BIT(opword, 6, 5)) }; addr_mode mode[] = { addr_mode(BIT(opword, 11, 5)), addr_mode(BIT(opword, 6, 5)) };
size_code const size_f = BIT(opword, 0) ? SIZE_D : SIZE_Q; size_code const size_f = BIT(opword, 2) ? SIZE_D : SIZE_Q;
size_code const size = size_code(opword & 3); size_code const size = size_code(opword & 3);
switch (BIT(opword, 3, 3)) switch (BIT(opword, 3, 3))
@ -473,7 +473,7 @@ offs_t ns32000_disassembler::disassemble(std::ostream &stream, offs_t pc, data_b
mode[0].size_i(size); mode[0].size_i(size);
mode[1].size_f(size_f); mode[1].size_f(size_f);
decode(mode, pc, opcodes, bytes); decode(mode, pc, opcodes, bytes);
util::stream_format(stream, "MOV%c%c %s, %s", size_char[size], BIT(opword, 0) ? 'F' : 'L', mode[0].mode, mode[1].mode); util::stream_format(stream, "MOV%c%c %s, %s", size_char[size], BIT(opword, 2) ? 'F' : 'L', mode[0].mode, mode[1].mode);
break; break;
case 1: case 1:
// LFSR src // LFSR src
@ -508,7 +508,7 @@ offs_t ns32000_disassembler::disassemble(std::ostream &stream, offs_t pc, data_b
mode[0].size_f(size_f); mode[0].size_f(size_f);
mode[1].size_i(size); mode[1].size_i(size);
decode(mode, pc, opcodes, bytes); decode(mode, pc, opcodes, bytes);
util::stream_format(stream, "ROUND%c%c %s, %s", BIT(opword, 0) ? 'F' : 'L', size_char[size], mode[0].mode, mode[1].mode); util::stream_format(stream, "ROUND%c%c %s, %s", BIT(opword, 2) ? 'F' : 'L', size_char[size], mode[0].mode, mode[1].mode);
break; break;
case 5: case 5:
// TRUNCfi src,dst // TRUNCfi src,dst
@ -517,7 +517,7 @@ offs_t ns32000_disassembler::disassemble(std::ostream &stream, offs_t pc, data_b
mode[0].size_f(size_f); mode[0].size_f(size_f);
mode[1].size_i(size); mode[1].size_i(size);
decode(mode, pc, opcodes, bytes); decode(mode, pc, opcodes, bytes);
util::stream_format(stream, "TRUNC%c%c %s, %s", BIT(opword, 0) ? 'F' : 'L', size_char[size], mode[0].mode, mode[1].mode); util::stream_format(stream, "TRUNC%c%c %s, %s", BIT(opword, 2) ? 'F' : 'L', size_char[size], mode[0].mode, mode[1].mode);
break; break;
case 6: case 6:
// SFSR dst // SFSR dst
@ -534,7 +534,7 @@ offs_t ns32000_disassembler::disassemble(std::ostream &stream, offs_t pc, data_b
mode[0].size_f(size_f); mode[0].size_f(size_f);
mode[1].size_i(size); mode[1].size_i(size);
decode(mode, pc, opcodes, bytes); decode(mode, pc, opcodes, bytes);
util::stream_format(stream, "FLOOR%c%c %s, %s", BIT(opword, 0) ? 'F' : 'L', size_char[size], mode[0].mode, mode[1].mode); util::stream_format(stream, "FLOOR%c%c %s, %s", BIT(opword, 2) ? 'F' : 'L', size_char[size], mode[0].mode, mode[1].mode);
break; break;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -8,54 +8,119 @@
#include "cpu/ns32000/common.h" #include "cpu/ns32000/common.h"
class ns32081_device class ns32081_device_base
: public device_t : public device_t
, public ns32000_slow_slave_interface
, public ns32000_fpu_interface , public ns32000_fpu_interface
{ {
protected:
ns32081_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock);
// device_t implementation
virtual void device_start() override;
virtual void device_reset() override;
// ns32000_slave_interface implementation
virtual void state_add(device_state_interface &parent, int &index) override;
// slave interface handlers
template <typename T> T read();
template <typename T> void write(T data);
// execution helpers
bool decode(u8 const idbyte, u16 const opword);
void execute();
u16 status(int *icount);
void complete(s32 param);
// register helpers
virtual void reg_get(unsigned const op_size, u64 &op_value, unsigned const reg) const = 0;
virtual void reg_set(unsigned const reg, unsigned const op_size, u64 const op_value) = 0;
private:
emu_timer *m_complete;
u32 m_fsr; // floating-point status register
// operating state
u32 m_state;
u8 m_idbyte;
u16 m_opword;
struct operand
{
u32 expected;
u32 issued;
u64 value;
}
m_op[3];
u16 m_status;
u32 m_tcy;
};
class ns32081_device
: public ns32081_device_base
, public ns32000_slow_slave_interface
{
public: public:
ns32081_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); ns32081_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
// ns32000_slave_interface implementation
virtual void state_add(device_state_interface &parent, int &index) override; virtual void state_add(device_state_interface &parent, int &index) override;
virtual u16 read_st(int *icount = nullptr) override; // ns32000_slow_slave_interface implementation
virtual u16 read_op() override; virtual u16 slow_status(int *icount = nullptr) override { return status(icount); }
virtual u16 slow_read() override { return read<u16>(); }
virtual void write_id(u16 data) override; virtual void slow_write(u16 data) override { write<u16>(data); }
virtual void write_op(u16 data) override;
protected: protected:
// device_t implementation // device_t implementation
virtual void device_start() override; virtual void device_start() override;
virtual void device_reset() override; virtual void device_reset() override;
void execute(); // register helpers
void complete(s32 param); virtual void reg_get(unsigned const op_size, u64 &op_value, unsigned const reg) const override;
virtual void reg_set(unsigned const reg, unsigned const op_size, u64 const op_value) override;
private: private:
emu_timer *m_complete;
// registers // registers
u32 m_fsr;
u32 m_f[8]; u32 m_f[8];
};
// operating state class ns32381_device
u8 m_idbyte; : public ns32081_device_base
u16 m_opword; , public ns32000_slow_slave_interface
struct operand , public ns32000_fast_slave_interface
{ {
unsigned expected; public:
unsigned issued; ns32381_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
u64 value;
}
m_op[3];
u16 m_status;
// implementation state // ns32000_slave_interface implementation
unsigned m_state; virtual void state_add(device_state_interface &parent, int &index) override;
unsigned m_tcy;
// ns32000_slow_slave_interface implementation
virtual u16 slow_status(int *icount = nullptr) override { return status(icount); }
virtual u16 slow_read() override { return read<u16>(); }
virtual void slow_write(u16 data) override { write<u16>(data); }
// ns32000_fast_slave_interface implementation
virtual u32 fast_status(int *icount = nullptr) override { return status(icount); }
virtual u32 fast_read() override { return read<u32>(); }
virtual void fast_write(u32 data) override { write<u32>(data); }
protected:
// device_t implementation
virtual void device_start() override;
virtual void device_reset() override;
// register helpers
virtual void reg_get(unsigned const op_size, u64 &op_value, unsigned const reg) const override;
virtual void reg_set(unsigned const reg, unsigned const op_size, u64 const op_value) override;
private:
// registers
u64 m_l[8];
}; };
DECLARE_DEVICE_TYPE(NS32081, ns32081_device) DECLARE_DEVICE_TYPE(NS32081, ns32081_device)
DECLARE_DEVICE_TYPE(NS32381, ns32381_device)
#endif // MAME_MACHINE_NS32081_H #endif // MAME_MACHINE_NS32081_H

View File

@ -34,11 +34,6 @@ enum state : unsigned
RESULT = 6, // result word available RESULT = 6, // result word available
}; };
enum idbyte : u8
{
FORMAT_14 = 0x1e,
};
enum reg_mask : unsigned enum reg_mask : unsigned
{ {
BPR0 = 0x0, // breakpoint register 0 BPR0 = 0x0, // breakpoint register 0
@ -127,8 +122,8 @@ enum eia_mask : u32
ns32082_device::ns32082_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) ns32082_device::ns32082_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
: device_t(mconfig, NS32082, tag, owner, clock) : device_t(mconfig, NS32082, tag, owner, clock)
, ns32000_slow_slave_interface(mconfig, *this)
, ns32000_mmu_interface(mconfig, *this) , ns32000_mmu_interface(mconfig, *this)
, ns32000_slow_slave_interface(mconfig, *this)
, m_bpr{} , m_bpr{}
, m_pf{} , m_pf{}
, m_sc(0) , m_sc(0)
@ -172,7 +167,7 @@ void ns32082_device::state_add(device_state_interface &parent, int &index)
parent.state_add(index++, "MSR", m_msr).formatstr("%08X"); parent.state_add(index++, "MSR", m_msr).formatstr("%08X");
} }
u16 ns32082_device::read_st(int *icount) u16 ns32082_device::slow_status(int *icount)
{ {
if (m_state == STATUS) if (m_state == STATUS)
{ {
@ -181,63 +176,54 @@ u16 ns32082_device::read_st(int *icount)
if (icount) if (icount)
*icount -= m_tcy; *icount -= m_tcy;
LOG("read_st status 0x%04x tcy %d %s (%s)\n", m_status, m_tcy, LOG("status 0x%04x tcy %d %s (%s)\n", m_status, m_tcy,
(m_state == RESULT ? "results pending" : "complete"), machine().describe_context()); (m_state == RESULT ? "results pending" : "complete"), machine().describe_context());
return m_status; return m_status;
} }
logerror("read_st protocol error reading status word (%s)\n", machine().describe_context()); logerror("status protocol error (%s)\n", machine().describe_context());
return 0; return 0;
} }
u16 ns32082_device::read_op() u16 ns32082_device::slow_read()
{ {
if (m_state == RESULT && m_op[2].issued < m_op[2].expected) if (m_state == RESULT && m_op[2].issued < m_op[2].expected)
{ {
u16 const data = u16(m_op[2].value >> (m_op[2].issued * 8)); u16 const data = u16(m_op[2].value >> (m_op[2].issued * 8));
LOG("read_op word %d data 0x%04x (%s)\n", m_op[2].issued >> 1, data, machine().describe_context()); LOG("read %d data 0x%04x (%s)\n", m_op[2].issued >> 1, data, machine().describe_context());
m_op[2].issued += 2; m_op[2].issued += 2;
if (m_op[2].issued == m_op[2].expected) if (m_op[2].issued == m_op[2].expected)
{ {
LOG("read_op last result word issued\n"); LOG("read complete\n");
m_state = IDLE; m_state = IDLE;
} }
return data; return data;
} }
logerror("read_op protocol error reading result word (%s)\n", machine().describe_context()); logerror("read protocol error (%s)\n", machine().describe_context());
return 0; return 0;
} }
void ns32082_device::write_id(u16 data) void ns32082_device::slow_write(u16 data)
{
bool const match = (data == FORMAT_14);
if (match)
{
LOG("write_id match 0x%04x (%s)\n", data, machine().describe_context());
m_state = OPERATION;
}
else
{
LOG("write_id ignore 0x%04x (%s)\n", data, machine().describe_context());
m_state = IDLE;
}
m_idbyte = u8(data);
}
void ns32082_device::write_op(u16 data)
{ {
switch (m_state) switch (m_state)
{ {
case IDLE:
LOG("write idbyte 0x%04x (%s)\n", data, machine().describe_context());
if (data == FORMAT_14)
{
m_idbyte = u8(data);
m_state = OPERATION;
}
break;
case OPERATION: case OPERATION:
m_opword = swapendian_int16(data); m_opword = swapendian_int16(data);
LOG("write_op opword 0x%04x (%s)\n", m_opword, machine().describe_context()); LOG("write opword 0x%04x (%s)\n", m_opword, machine().describe_context());
m_tcy = 0; m_tcy = 0;
@ -282,14 +268,16 @@ void ns32082_device::write_op(u16 data)
unsigned const n = (m_op[0].issued < m_op[0].expected) ? 0 : 1; unsigned const n = (m_op[0].issued < m_op[0].expected) ? 0 : 1;
operand &op = m_op[n]; operand &op = m_op[n];
LOG("write_op op%d data 0x%04x (%s)\n", n, data, machine().describe_context()); LOG("write operand %d data 0x%04x (%s)\n",
n, data, machine().describe_context());
// insert word into operand value // insert word into operand value
op.value |= u64(data) << (op.issued * 8); op.value |= u64(data) << (op.issued * 8);
op.issued += 2; op.issued += 2;
} }
else else
logerror("write_op protocol error unexpected operand word 0x%04x (%s)\n", data, machine().describe_context()); logerror("write protocol error unexpected operand data 0x%04x (%s)\n",
data, machine().describe_context());
break; break;
} }

View File

@ -10,24 +10,25 @@
class ns32082_device class ns32082_device
: public device_t : public device_t
, public ns32000_slow_slave_interface
, public ns32000_mmu_interface , public ns32000_mmu_interface
, public ns32000_slow_slave_interface
{ {
public: public:
ns32082_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); ns32082_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
// ns32000_slave_interface implementation
virtual void state_add(device_state_interface &parent, int &index) override; virtual void state_add(device_state_interface &parent, int &index) override;
virtual u16 read_st(int *icount = nullptr) override; // ns32000_slow_slave_interface implementation
virtual u16 read_op() override; virtual u16 slow_status(int *icount = nullptr) override;
virtual u16 slow_read() override;
virtual void write_id(u16 data) override; virtual void slow_write(u16 data) override;
virtual void write_op(u16 data) override;
// ns32000_mmu_interface implementation
virtual translate_result translate(address_space &space, unsigned st, u32 &address, bool user, bool write, bool pfs = false, bool suppress = false) override; virtual translate_result translate(address_space &space, unsigned st, u32 &address, bool user, bool write, bool pfs = false, bool suppress = false) override;
protected: protected:
// device_t overrides // device_t implementation
virtual void device_start() override; virtual void device_start() override;
virtual void device_reset() override; virtual void device_reset() override;
@ -51,16 +52,16 @@ private:
u16 m_opword; u16 m_opword;
struct operand struct operand
{ {
unsigned expected; u32 expected;
unsigned issued; u32 issued;
u64 value; u64 value;
} }
m_op[3]; m_op[3];
u16 m_status; u16 m_status;
// implementation state // implementation state
unsigned m_state; u32 m_state;
unsigned m_tcy; u32 m_tcy;
}; };
DECLARE_DEVICE_TYPE(NS32082, ns32082_device) DECLARE_DEVICE_TYPE(NS32082, ns32082_device)

View File

@ -10,7 +10,6 @@
* - https://www.nic.funet.fi/pub/misc/pc532/ * - https://www.nic.funet.fi/pub/misc/pc532/
* *
* TODO: * TODO:
* - ns32381
* - et532 * - et532
* *
* WIP: * WIP:
@ -47,7 +46,7 @@ public:
pc532_state(machine_config const &mconfig, device_type type, char const *tag) pc532_state(machine_config const &mconfig, device_type type, char const *tag)
: driver_device(mconfig, type, tag) : driver_device(mconfig, type, tag)
, m_cpu(*this, "cpu") , m_cpu(*this, "cpu")
//, m_fpu(*this, "fpu") , m_fpu(*this, "fpu")
, m_icu(*this, "icu") , m_icu(*this, "icu")
, m_rtc(*this, "rtc") , m_rtc(*this, "rtc")
, m_ncr5380(*this, "slot:7:ncr5380") , m_ncr5380(*this, "slot:7:ncr5380")
@ -61,7 +60,6 @@ public:
{ {
} }
void init();
void pc532(machine_config &config); void pc532(machine_config &config);
protected: protected:
@ -71,7 +69,7 @@ protected:
template <unsigned ST> void cpu_map(address_map &map); template <unsigned ST> void cpu_map(address_map &map);
required_device<ns32532_device> m_cpu; required_device<ns32532_device> m_cpu;
//required_device<ns32381_device> m_fpu; required_device<ns32381_device> m_fpu;
required_device<ns32202_device> m_icu; required_device<ns32202_device> m_icu;
required_device<ds1315_device> m_rtc; required_device<ds1315_device> m_rtc;
@ -113,12 +111,6 @@ private:
m_state; m_state;
}; };
void pc532_state::init()
{
// HACK: disable unemulated FPU
m_eprom[0x7c00 >> 2] &= ~0x02;
}
void pc532_state::machine_start() void pc532_state::machine_start()
{ {
// install phantom rtc using memory taps // install phantom rtc using memory taps
@ -312,8 +304,8 @@ void pc532_state::pc532(machine_config &config)
// ODT required because system software uses explicit MOV instead of RETI instructions // ODT required because system software uses explicit MOV instead of RETI instructions
m_cpu->set_addrmap(ns32000::ST_ODT, &pc532_state::cpu_map<ns32000::ST_ODT>); m_cpu->set_addrmap(ns32000::ST_ODT, &pc532_state::cpu_map<ns32000::ST_ODT>);
//NS32381(config, m_fpu, 50_MHz_XTAL / 2); NS32381(config, m_fpu, 50_MHz_XTAL / 2);
//m_cpu->set_fpu(m_fpu); m_cpu->set_fpu(m_fpu);
NS32202(config, m_icu, 3.6864_MHz_XTAL); NS32202(config, m_icu, 3.6864_MHz_XTAL);
m_icu->out_int().set_inputline(m_cpu, INPUT_LINE_IRQ0).invert(); m_icu->out_int().set_inputline(m_cpu, INPUT_LINE_IRQ0).invert();
@ -327,7 +319,7 @@ void pc532_state::pc532(machine_config &config)
NSCSI_CONNECTOR(config, "slot:1", scsi_devices, nullptr, false); NSCSI_CONNECTOR(config, "slot:1", scsi_devices, nullptr, false);
NSCSI_CONNECTOR(config, "slot:2", scsi_devices, nullptr, false); NSCSI_CONNECTOR(config, "slot:2", scsi_devices, nullptr, false);
NSCSI_CONNECTOR(config, "slot:3", scsi_devices, nullptr, false); NSCSI_CONNECTOR(config, "slot:3", scsi_devices, nullptr, false);
NSCSI_CONNECTOR(config, "slot:7").option_set("ncr5380", NCR5380).machine_config( NSCSI_CONNECTOR(config, "slot:7").option_set("ncr5380", NCR5380).machine_config( // DP8490
[this](device_t *device) [this](device_t *device)
{ {
ncr5380_device &ncr5380(downcast<ncr5380_device &>(*device)); ncr5380_device &ncr5380(downcast<ncr5380_device &>(*device));
@ -412,5 +404,5 @@ ROM_END
} // anonymous namespace } // anonymous namespace
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ /* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
COMP(1989, pc532, 0, 0, pc532, 0, pc532_state, init, "George Scolaro", "pc532", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW) COMP(1989, pc532, 0, 0, pc532, 0, pc532_state, empty_init, "George Scolaro", "pc532", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW)