From acdfb30a412061c700dc5df0e70b5b7a23f3e4b6 Mon Sep 17 00:00:00 2001 From: cracyc Date: Thu, 29 Mar 2018 21:52:24 -0500 Subject: i186: handle program space mapping for io block same as io space (nw) --- src/devices/cpu/i86/i186.cpp | 65 +++++++++++++++++++++++++++++++++++--------- src/devices/cpu/i86/i186.h | 4 +++ 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/src/devices/cpu/i86/i186.cpp b/src/devices/cpu/i86/i186.cpp index 9aeb4759bbb..e1edfedaebd 100644 --- a/src/devices/cpu/i86/i186.cpp +++ b/src/devices/cpu/i86/i186.cpp @@ -691,7 +691,7 @@ uint8_t i80186_cpu_device::read_port_byte(uint16_t port) { if(!(m_reloc & 0x1000) && (port >> 8) == (m_reloc & 0xff)) { - uint16_t ret = internal_port_r(*m_io, (port >> 1) - ((m_reloc & 0xff) << 7), (port & 1) ? 0xff00 : 0x00ff); + uint16_t ret = internal_port_r(*m_io, (port >> 1) & 0x7f, (port & 1) ? 0xff00 : 0x00ff); return (port & 1) ? (ret >> 8) : (ret & 0xff); } return m_io->read_byte(port); @@ -706,7 +706,7 @@ uint16_t i80186_cpu_device::read_port_word(uint16_t port) uint8_t low = read_port_byte(port); return read_port_byte(port + 1) << 8 | low; } - return internal_port_r(*m_io, (port >> 1) - ((m_reloc & 0xff) << 7)); + return internal_port_r(*m_io, (port >> 1) & 0x7f); } return m_io->read_word_unaligned(port); } @@ -714,7 +714,7 @@ uint16_t i80186_cpu_device::read_port_word(uint16_t port) void i80186_cpu_device::write_port_byte(uint16_t port, uint8_t data) { if(!(m_reloc & 0x1000) && (port >> 8) == (m_reloc & 0xff)) - internal_port_w(*m_io, (port >> 1) - ((m_reloc & 0xff) << 7), (port & 1) ? (data << 8) : data, (port & 1) ? 0xff00 : 0x00ff); + internal_port_w(*m_io, (port >> 1) & 0x7f, (port & 1) ? (data << 8) : data, (port & 1) ? 0xff00 : 0x00ff); else m_io->write_byte(port, data); } @@ -729,12 +729,60 @@ void i80186_cpu_device::write_port_word(uint16_t port, uint16_t data) write_port_byte(port + 1, data >> 8); } else - internal_port_w(*m_io, (port >> 1) - ((m_reloc & 0xff) << 7), data); + internal_port_w(*m_io, (port >> 1) & 0x7f, data); } else m_io->write_word_unaligned(port, data); } +uint8_t i80186_cpu_device::read_byte(uint32_t addr) +{ + if((m_reloc & 0x1000) && (addr >> 8) == (m_reloc & 0xfff)) + { + uint16_t ret = internal_port_r(*m_program, (addr >> 1) & 0x7f, (addr & 1) ? 0xff00 : 0x00ff); + return (addr & 1) ? (ret >> 8) : (ret & 0xff); + } + return m_program->read_byte(addr); +} + +uint16_t i80186_cpu_device::read_word(uint32_t addr) +{ + if((m_reloc & 0x1000) && (addr >> 8) == (m_reloc & 0xfff)) + { + if(addr & 1) + { + uint8_t low = read_byte(addr); + return read_byte(addr + 1) << 8 | low; + } + return internal_port_r(*m_program, (addr >> 1) & 0x7f); + } + return m_program->read_word_unaligned(addr); +} + +void i80186_cpu_device::write_byte(uint32_t addr, uint8_t data) +{ + if((m_reloc & 0x1000) && (addr >> 8) == (m_reloc & 0xfff)) + internal_port_w(*m_program, (addr >> 1) & 0x7f, (addr & 1) ? (data << 8) : data, (addr & 1) ? 0xff00 : 0x00ff); + else + m_program->write_byte(addr, data); +} + +void i80186_cpu_device::write_word(uint32_t addr, uint16_t data) +{ + if((m_reloc & 0x1000) && (addr >> 8) == (m_reloc & 0xfff)) + { + if(addr & 1) + { + write_byte(addr, data & 0xff); + write_byte(addr + 1, data >> 8); + } + else + internal_port_w(*m_program, (addr >> 1) & 0x7f, data); + } + else + m_program->write_word_unaligned(addr, data); +} + /************************************* * * 80186 interrupt controller @@ -1735,15 +1783,6 @@ WRITE16_MEMBER(i80186_cpu_device::internal_port_w) case 0x7f: if (LOG_PORTS) logerror("%05X:80186 relocation register = %04X\n", m_pc, data); - if ((data & 0x1fff) != (m_reloc & 0x1fff)) - { - uint32_t newmap = (data & 0xfff) << 8; - uint32_t oldmap = (m_reloc & 0xfff) << 8; - if (m_reloc & 0x1000) - m_program->unmap_readwrite(oldmap, oldmap + 0xff); - if (data & 0x1000) // TODO: make work with 80188 if needed - m_program->install_readwrite_handler(newmap, newmap + 0xff, read16_delegate(FUNC(i80186_cpu_device::internal_port_r), this), write16_delegate(FUNC(i80186_cpu_device::internal_port_w), this)); - } m_reloc = data; break; diff --git a/src/devices/cpu/i86/i186.h b/src/devices/cpu/i86/i186.h index 7ebb6e1bc4b..ca281a58604 100644 --- a/src/devices/cpu/i86/i186.h +++ b/src/devices/cpu/i86/i186.h @@ -66,6 +66,10 @@ protected: virtual uint16_t read_port_word(uint16_t port) override; virtual void write_port_byte(uint16_t port, uint8_t data) override; virtual void write_port_word(uint16_t port, uint16_t data) override; + virtual uint8_t read_byte(uint32_t addr) override; + virtual uint16_t read_word(uint32_t addr) override; + virtual void write_byte(uint32_t addr, uint8_t data) override; + virtual void write_word(uint32_t addr, uint16_t data) override; static const uint8_t m_i80186_timing[200]; -- cgit v1.2.3