rx01_cpu: Add sector data space in place of scratchpad space (nw)

This commit is contained in:
AJR 2020-04-15 19:26:06 -04:00
parent 5c90a13cee
commit 0709c3fe27
4 changed files with 62 additions and 23 deletions

View File

@ -8,7 +8,8 @@
the rather brisk rate of 200 ns per machine cycle. However, it has no the rather brisk rate of 200 ns per machine cycle. However, it has no
ALU or general-purpose data bus, so most of its operations amount to ALU or general-purpose data bus, so most of its operations amount to
simple manipulations of an assortment of synchronous up counters, shift simple manipulations of an assortment of synchronous up counters, shift
registers and flip-flops. registers and flip-flops, plus a 16-location scratchpad made up of two
7489 16x4 register files.
The instruction memory is organized as a series of 256-byte "fields" The instruction memory is organized as a series of 256-byte "fields"
which limit the extent of conditional branches. The architecture allows which limit the extent of conditional branches. The architecture allows
@ -37,9 +38,9 @@ DEFINE_DEVICE_TYPE(RX01_CPU, rx01_cpu_device, "rx01_cpu", "DEC RX01 CPU")
rx01_cpu_device::rx01_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) rx01_cpu_device::rx01_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: cpu_device(mconfig, RX01_CPU, tag, owner, clock) : cpu_device(mconfig, RX01_CPU, tag, owner, clock)
, m_inst_config("program", ENDIANNESS_LITTLE, 8, 12, 0) , m_inst_config("program", ENDIANNESS_LITTLE, 8, 12, 0)
, m_sp_config("scratchpad", ENDIANNESS_LITTLE, 8, 4, 0, address_map_constructor(FUNC(rx01_cpu_device::scratchpad_map), this)) , m_data_config("sector data", ENDIANNESS_LITTLE, 8, 10, 0) // actually 1 bit wide
, m_inst_cache(nullptr) , m_inst_cache(nullptr)
, m_sp_cache(nullptr) , m_data_cache(nullptr)
, m_pc(0) , m_pc(0)
, m_ppc(0) , m_ppc(0)
, m_mb(0) , m_mb(0)
@ -56,8 +57,8 @@ rx01_cpu_device::rx01_cpu_device(const machine_config &mconfig, const char *tag,
, m_load_head(false) , m_load_head(false)
, m_icount(0) , m_icount(0)
{ {
std::fill(std::begin(m_sp), std::end(m_sp), 0);
m_inst_config.m_is_octal = true; m_inst_config.m_is_octal = true;
m_sp_config.m_is_octal = true;
} }
std::unique_ptr<util::disasm_interface> rx01_cpu_device::create_disassembler() std::unique_ptr<util::disasm_interface> rx01_cpu_device::create_disassembler()
@ -65,23 +66,18 @@ std::unique_ptr<util::disasm_interface> rx01_cpu_device::create_disassembler()
return std::make_unique<rx01_disassembler>(); return std::make_unique<rx01_disassembler>();
} }
void rx01_cpu_device::scratchpad_map(address_map &map)
{
map(0, 15).ram().share("scratchpad"); // two 7489 16x4 register files
}
device_memory_interface::space_config_vector rx01_cpu_device::memory_space_config() const device_memory_interface::space_config_vector rx01_cpu_device::memory_space_config() const
{ {
return space_config_vector { return space_config_vector {
std::make_pair(AS_PROGRAM, &m_inst_config), std::make_pair(AS_PROGRAM, &m_inst_config),
std::make_pair(AS_DATA, &m_sp_config) std::make_pair(AS_DATA, &m_data_config)
}; };
} }
void rx01_cpu_device::device_start() void rx01_cpu_device::device_start()
{ {
m_inst_cache = space(AS_PROGRAM).cache<0, 0, ENDIANNESS_LITTLE>(); m_inst_cache = space(AS_PROGRAM).cache<0, 0, ENDIANNESS_LITTLE>();
m_sp_cache = space(AS_DATA).cache<0, 0, ENDIANNESS_LITTLE>(); m_data_cache = space(AS_DATA).cache<0, 0, ENDIANNESS_LITTLE>();
set_icountptr(m_icount); set_icountptr(m_icount);
@ -93,9 +89,8 @@ void rx01_cpu_device::device_start()
state_add(RX01_CNTR, "CNTR", m_cntr).formatstr("%03O"); state_add(RX01_CNTR, "CNTR", m_cntr).formatstr("%03O");
state_add(RX01_SR, "SR", m_sr).formatstr("%03O"); state_add(RX01_SR, "SR", m_sr).formatstr("%03O");
state_add(RX01_SPAR, "SPAR", m_spar).mask(15).formatstr("%3s"); state_add(RX01_SPAR, "SPAR", m_spar).mask(15).formatstr("%3s");
u8 *sp = static_cast<u8 *>(memshare("scratchpad")->ptr());
for (int r = 0; r < 16; r++) for (int r = 0; r < 16; r++)
state_add(RX01_R0 + r, string_format("R%d", r).c_str(), sp[r]).formatstr("%03O"); state_add(RX01_R0 + r, string_format("R%d", r).c_str(), m_sp[r]).formatstr("%03O");
state_add(RX01_BAR, "BAR", m_bar).mask(07777).formatstr("%04O"); state_add(RX01_BAR, "BAR", m_bar).mask(07777).formatstr("%04O");
state_add(RX01_CRC, "CRC", m_crc).formatstr("%06O"); state_add(RX01_CRC, "CRC", m_crc).formatstr("%06O");
state_add(RX01_UNIT, "UNIT", m_unit); state_add(RX01_UNIT, "UNIT", m_unit);
@ -125,7 +120,7 @@ void rx01_cpu_device::device_reset()
m_mb = 0; m_mb = 0;
m_inst_disable = false; m_inst_disable = false;
m_inst_repeat = false; m_inst_repeat = false;
m_bar = 0; set_bar(0);
m_cntr = 0; m_cntr = 0;
m_sr = 0; m_sr = 0;
m_spar = 0; m_spar = 0;
@ -137,11 +132,17 @@ void rx01_cpu_device::device_reset()
u8 rx01_cpu_device::mux_out() u8 rx01_cpu_device::mux_out()
{ {
if (BIT(m_mb, 0)) if (BIT(m_mb, 0))
return m_sp_cache->read_byte(m_spar); return m_sp[m_spar];
else else
return m_inst_cache->read_byte(m_pc); return m_inst_cache->read_byte(m_pc);
} }
bool rx01_cpu_device::data_in()
{
// TODO
return false;
}
bool rx01_cpu_device::sep_data() bool rx01_cpu_device::sep_data()
{ {
// TODO // TODO
@ -160,6 +161,14 @@ bool rx01_cpu_device::drv_sel_trk0()
return false; return false;
} }
bool rx01_cpu_device::sec_buf_in()
{
if (m_flags & FF_IOB0)
return sep_data();
else
return data_in();
}
bool rx01_cpu_device::test_condition() bool rx01_cpu_device::test_condition()
{ {
switch (m_mb & 074) switch (m_mb & 074)
@ -172,6 +181,10 @@ bool rx01_cpu_device::test_condition()
// Output buffer bit 3 // Output buffer bit 3
return (m_flags & FF_IOB3) != 0; return (m_flags & FF_IOB3) != 0;
case 010:
// Serial data from interface
return data_in();
case 020: case 020:
// MSB of shift register // MSB of shift register
return BIT(m_sr, 7); return BIT(m_sr, 7);
@ -200,6 +213,13 @@ bool rx01_cpu_device::test_condition()
// Missing clock equals shift register MSB // Missing clock equals shift register MSB
return BIT(m_sr, 7) == missing_clk(); return BIT(m_sr, 7) == missing_clk();
case 070:
// Sector buffer output
if (m_flags & FF_WRTBUF)
return sec_buf_in();
else
return m_data_cache->read_byte(m_bar) & 1;
case 074: case 074:
// Flag state equals one // Flag state equals one
return (m_flags & FF_FLAG) != 0; return (m_flags & FF_FLAG) != 0;
@ -210,6 +230,13 @@ bool rx01_cpu_device::test_condition()
} }
} }
void rx01_cpu_device::set_bar(u16 bar)
{
if (m_bar != bar && (m_flags & FF_WRTBUF))
m_data_cache->write_byte(m_bar, sec_buf_in());
m_bar = bar;
}
void rx01_cpu_device::shift_crc(bool data) void rx01_cpu_device::shift_crc(bool data)
{ {
// TODO: double-check algorithm // TODO: double-check algorithm
@ -334,16 +361,19 @@ void rx01_cpu_device::execute_run()
case 044: case 044:
if (BIT(m_mb, 1)) if (BIT(m_mb, 1))
m_bar = (m_bar + 1) & 07777; set_bar((m_bar + 1) & 07777);
else else
m_bar = BIT(m_mb, 0) ? 0 : 06000; set_bar(BIT(m_mb, 0) ? 0 : 06000);
break; break;
case 050: case 050:
if (BIT(m_mb, 0)) if (BIT(m_mb, 0))
m_flags |= FF_WRTBUF; m_flags |= FF_WRTBUF;
else else if (m_flags & FF_WRTBUF)
{
m_data_cache->write_byte(m_bar, sec_buf_in());
m_flags &= ~FF_WRTBUF; m_flags &= ~FF_WRTBUF;
}
break; break;
case 054: case 054:
@ -360,7 +390,7 @@ void rx01_cpu_device::execute_run()
break; break;
case 064: case 064:
m_sp_cache->write_byte(m_spar, m_sr); m_sp[m_spar] = m_sr;
break; break;
case 070: case 070:

View File

@ -54,22 +54,23 @@ protected:
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
private: private:
void scratchpad_map(address_map &map);
// internal helpers // internal helpers
u8 mux_out(); u8 mux_out();
bool data_in();
bool sep_data(); bool sep_data();
bool missing_clk(); bool missing_clk();
bool drv_sel_trk0(); bool drv_sel_trk0();
bool sec_buf_in();
bool test_condition(); bool test_condition();
void set_bar(u16 bar);
void shift_crc(bool data); void shift_crc(bool data);
void set_flag(bool j, bool k); void set_flag(bool j, bool k);
// address spaces // address spaces
address_space_config m_inst_config; address_space_config m_inst_config;
address_space_config m_sp_config; address_space_config m_data_config;
memory_access_cache<0, 0, ENDIANNESS_LITTLE> *m_inst_cache; memory_access_cache<0, 0, ENDIANNESS_LITTLE> *m_inst_cache;
memory_access_cache<0, 0, ENDIANNESS_LITTLE> *m_sp_cache; memory_access_cache<0, 0, ENDIANNESS_LITTLE> *m_data_cache;
// internal state // internal state
u16 m_pc; u16 m_pc;
@ -81,6 +82,7 @@ private:
u8 m_cntr; u8 m_cntr;
u8 m_sr; u8 m_sr;
u8 m_spar; u8 m_spar;
u8 m_sp[16];
u16 m_bar; u16 m_bar;
u16 m_crc; u16 m_crc;
u16 m_flags; u16 m_flags;

View File

@ -56,6 +56,11 @@ void rx01_device::firmware_map(address_map &map)
map(00000, 02777).rom().region("firmware", 0); map(00000, 02777).rom().region("firmware", 0);
} }
void rx01_device::secbuf_map(address_map &map)
{
map(00000, 01777).ram(); // FIXME: 1-bit
}
//------------------------------------------------- //-------------------------------------------------
// device_add_mconfig - add device configuration // device_add_mconfig - add device configuration
//------------------------------------------------- //-------------------------------------------------
@ -64,6 +69,7 @@ void rx01_device::device_add_mconfig(machine_config &config)
{ {
rx01_cpu_device &cpu(RX01_CPU(config, "rx01cpu", 20_MHz_XTAL)); rx01_cpu_device &cpu(RX01_CPU(config, "rx01cpu", 20_MHz_XTAL));
cpu.set_addrmap(AS_PROGRAM, &rx01_device::firmware_map); cpu.set_addrmap(AS_PROGRAM, &rx01_device::firmware_map);
cpu.set_addrmap(AS_DATA, &rx01_device::secbuf_map);
for (auto &floppy : m_image) for (auto &floppy : m_image)
LEGACY_FLOPPY(config, floppy, 0, &rx01_floppy_interface); LEGACY_FLOPPY(config, floppy, 0, &rx01_floppy_interface);

View File

@ -51,6 +51,7 @@ protected:
private: private:
void firmware_map(address_map &map); void firmware_map(address_map &map);
void secbuf_map(address_map &map);
enum rx01_state { enum rx01_state {
RX01_FILL, RX01_FILL,