hd647180x: Eliminate data space and instead map internal RAM into program space using memory view

This commit is contained in:
AJR 2021-03-17 16:53:38 -04:00
parent a928d3c40c
commit 0049b39696
4 changed files with 16 additions and 58 deletions

View File

@ -18,8 +18,7 @@
TODO: the current emulation is incomplete, implementing mostly
the internal memory and parallel ports. Timer 2 (which is very
similar to the additional timer of the HD6301) is not emulated at
all. Programs trying to execute from internal RAM will also fail,
though this likely capability is merely theoretical so far.
all.
**********************************************************************/
@ -33,47 +32,22 @@
DEFINE_DEVICE_TYPE(HD647180X, hd647180x_device, "hd647180x", "Hitachi HD647180X MCU")
hd647180x_device::hd647180x_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: z180_device(mconfig, HD647180X, tag, owner, clock, true, address_map_constructor(FUNC(hd647180x_device::prom_map), this))
: z180_device(mconfig, HD647180X, tag, owner, clock, true, address_map_constructor(FUNC(hd647180x_device::internal_map), this))
, m_port_input_cb(*this)
, m_port_output_cb(*this)
, m_data_config("data", ENDIANNESS_LITTLE, 8, 9, 0, address_map_constructor(FUNC(hd647180x_device::ram_map), this))
, m_ram_view(*this, "ram_view")
{
// arbitrary initial states
m_ccsr = 0;
std::fill(std::begin(m_odr), std::end(m_odr), 0);
}
void hd647180x_device::prom_map(address_map &map)
void hd647180x_device::internal_map(address_map &map)
{
map(0x00000, 0x03fff).rom().region(DEVICE_SELF, 0); // 16 KB internal PROM (not used in mode 1)
}
void hd647180x_device::ram_map(address_map &map)
{
map(0x000, 0x1ff).ram(); // 512 bytes remappable internal RAM (available in all modes)
}
device_memory_interface::space_config_vector hd647180x_device::memory_space_config() const
{
auto spaces = z180_device::memory_space_config();
spaces.emplace_back(AS_DATA, &m_data_config);
return spaces;
}
uint8_t hd647180x_device::z180_read_memory(offs_t addr)
{
if ((addr & 0xffe00) == (offs_t(m_rmcr) << 12 | 0x0fe00))
return m_data->read_byte(addr & 0x1ff);
else
return z180_device::z180_read_memory(addr);
}
void hd647180x_device::z180_write_memory(offs_t addr, uint8_t data)
{
if ((addr & 0xffe00) == (offs_t(m_rmcr) << 12 | 0x0fe00))
m_data->write_byte(addr & 0x1ff, data);
else
z180_device::z180_write_memory(addr, data);
map(0x00000, 0xfffff).view(m_ram_view);
for (unsigned pos = 0; pos < 16; pos++)
m_ram_view[pos](offs_t(pos) << 16 | 0xfe00, offs_t(pos) << 16 | 0xffff).ram().share("ram");
}
uint8_t hd647180x_device::z180_internal_port_read(uint8_t port)
@ -236,6 +210,7 @@ void hd647180x_device::z180_internal_port_write(uint8_t port, uint8_t data)
case 0x51:
LOG("HD647180X RMCR wr $%02x\n", data);
m_rmcr = data & 0xf0;
m_ram_view.select(m_rmcr >> 4);
break;
case 0x53:
@ -285,8 +260,6 @@ void hd647180x_device::device_start()
{
z180_device::device_start();
m_data = &space(AS_DATA);
state_add(HD647180X_T2FRC, "T2FRC", m_t2frc.w);
state_add(HD647180X_T2OCR1, "T2OCR1", m_t2ocr[0].w);
state_add(HD647180X_T2OCR2, "T2OCR2", m_t2ocr[1].w);
@ -294,7 +267,7 @@ void hd647180x_device::device_start()
state_add(HD647180X_T2CSR1, "T2CSR1", m_t2csr[0]);
state_add(HD647180X_T2CSR2, "T2CSR2", m_t2csr[1]).mask(0xef);
state_add(HD647180X_CCSR, "CCSR", m_ccsr).mask(0xbf);
state_add(HD647180X_RMCR, "RMCR", m_rmcr).mask(0xf0);
state_add(HD647180X_RMCR, "RMCR", m_rmcr, [this](u8 data) { m_rmcr = data; m_ram_view.select(data >> 4); }).mask(0xf0);
state_add(HD647180X_DERA, "DERA", m_dera);
for (int i = 0; i < 6; i++)
{
@ -325,6 +298,7 @@ void hd647180x_device::device_reset()
m_t2csr[1] = 0x00;
m_ccsr = (m_ccsr & 0x80) | 0x2c;
m_rmcr = 0;
m_ram_view.select(0);
m_dera = 0;
std::fill(std::begin(m_ddr), std::end(m_ddr), 0);
}

View File

@ -47,27 +47,20 @@ protected:
virtual void device_start() override;
virtual void device_reset() override;
// device_memory_interface overrides
virtual space_config_vector memory_space_config() const override;
// z180_device overrides
virtual uint8_t z180_read_memory(offs_t addr) override;
virtual void z180_write_memory(offs_t addr, uint8_t data) override;
virtual uint8_t z180_internal_port_read(uint8_t port) override;
virtual void z180_internal_port_write(uint8_t port, uint8_t data) override;
private:
// internal memory maps
void prom_map(address_map &map);
void ram_map(address_map &map);
// internal memory map
void internal_map(address_map &map);
// port callbacks
devcb_read8::array<7> m_port_input_cb;
devcb_write8::array<6> m_port_output_cb;
// internal RAM space
address_space_config m_data_config;
address_space *m_data;
memory_view m_ram_view;
// internal registers
PAIR16 m_t2frc;

View File

@ -482,16 +482,6 @@ device_memory_interface::space_config_vector z180_device::memory_space_config()
};
}
uint8_t z180_device::z180_read_memory(offs_t addr)
{
return m_program.read_byte(addr);
}
void z180_device::z180_write_memory(offs_t addr, uint8_t data)
{
m_program.write_byte(addr, data);
}
uint8_t z180_device::z180_readcontrol(offs_t port)
{
// normal external readport (ignore the data)

View File

@ -140,8 +140,6 @@ protected:
// device_disasm_interface overrides
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
virtual uint8_t z180_read_memory(offs_t addr);
virtual void z180_write_memory(offs_t addr, uint8_t data);
virtual uint8_t z180_internal_port_read(uint8_t port);
virtual void z180_internal_port_write(uint8_t port, uint8_t data);
@ -152,6 +150,9 @@ protected:
void set_address_width(int bits);
private:
uint8_t z180_read_memory(offs_t addr) { return m_program.read_byte(addr); }
void z180_write_memory(offs_t addr, uint8_t data) { m_program.write_byte(addr, data); }
int memory_wait_states() const { return (m_dcntl & 0xc0) >> 6; }
int io_wait_states() const { return (m_dcntl & 0x30) == 0 ? 0 : ((m_dcntl & 0x30) >> 4) + 1; }
bool is_internal_io_address(uint16_t port) const { return ((port ^ m_iocr) & (m_extended_io ? 0xff80 : 0xffc0)) == 0; }