diff options
author | 2020-03-03 12:55:35 +0100 | |
---|---|---|
committer | 2020-03-03 12:55:35 +0100 | |
commit | d469028abc5b86b0748c9d2167b91cac2ca0a5ee (patch) | |
tree | 157befea2a007edb3a7d0c3e3544205b13862f0c | |
parent | c1169e6d2dc2d97ffbeed3b660aca7ad7de2397d (diff) |
hp80: added HP82900 CP/M module
-rw-r--r-- | scripts/src/bus.lua | 2 | ||||
-rw-r--r-- | src/devices/bus/hp80_io/82900.cpp | 175 | ||||
-rw-r--r-- | src/devices/bus/hp80_io/82900.h | 67 | ||||
-rw-r--r-- | src/devices/bus/hp80_io/hp80_io.cpp | 6 | ||||
-rw-r--r-- | src/devices/bus/hp80_io/hp80_io.h | 21 |
5 files changed, 258 insertions, 13 deletions
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 87b372b9e50..90aea315fcb 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -3940,6 +3940,8 @@ if (BUSES["HP80_IO"]~=null) then files { MAME_DIR .. "src/devices/bus/hp80_io/hp80_io.cpp", MAME_DIR .. "src/devices/bus/hp80_io/hp80_io.h", + MAME_DIR .. "src/devices/bus/hp80_io/82900.cpp", + MAME_DIR .. "src/devices/bus/hp80_io/82900.h", MAME_DIR .. "src/devices/bus/hp80_io/82937.cpp", MAME_DIR .. "src/devices/bus/hp80_io/82937.h", MAME_DIR .. "src/devices/bus/hp80_io/82939.cpp", diff --git a/src/devices/bus/hp80_io/82900.cpp b/src/devices/bus/hp80_io/82900.cpp new file mode 100644 index 00000000000..008770abb52 --- /dev/null +++ b/src/devices/bus/hp80_io/82900.cpp @@ -0,0 +1,175 @@ +// license:BSD-3-Clause +// copyright-holders: F. Ulivi +/********************************************************************* + + 82900.cpp + + 82900 module (CP/M auxiliary processor) + +*********************************************************************/ + +#include "emu.h" +#include "82900.h" +#include "coreutil.h" + +// Debugging +#define VERBOSE 0 +#include "logmacro.h" + +// Bit manipulation +namespace { + template<typename T> constexpr T BIT_MASK(unsigned n) + { + return (T)1U << n; + } + + template<typename T> void BIT_SET(T& w , unsigned n) + { + w |= BIT_MASK<T>(n); + } +} + +hp82900_io_card_device::hp82900_io_card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig , HP82900_IO_CARD , tag , owner , clock), + device_hp80_io_interface(mconfig, *this), + m_cpu(*this , "cpu"), + m_translator(*this , "xlator"), + m_rom(*this , "rom") +{ +} + +hp82900_io_card_device::~hp82900_io_card_device() +{ +} + +void hp82900_io_card_device::install_read_write_handlers(address_space& space , uint16_t base_addr) +{ + space.install_readwrite_handler(base_addr, base_addr + 1, read8_delegate(*m_translator, FUNC(hp_1mb5_device::cpu_r)), write8_delegate(*m_translator, FUNC(hp_1mb5_device::cpu_w))); +} + +void hp82900_io_card_device::inten() +{ + m_translator->inten(); +} + +void hp82900_io_card_device::clear_service() +{ + m_translator->clear_service(); +} + +static INPUT_PORTS_START(hp82900_port) + PORT_START("SC") + PORT_CONFNAME(0xf , 3 , "Select Code") +INPUT_PORTS_END + +ioport_constructor hp82900_io_card_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(hp82900_port); +} + +void hp82900_io_card_device::device_start() +{ + m_ram = std::make_unique<uint8_t[]>(65536); + + save_pointer(NAME(m_ram) , 65536); + save_item(NAME(m_rom_enabled)); + save_item(NAME(m_addr_latch)); +} + +void hp82900_io_card_device::device_reset() +{ + m_rom_enabled = true; +} + +ROM_START(hp82900) + ROM_REGION(0x800 , "rom" , 0) + ROM_LOAD("82900-60002.bin" , 0 , 0x800 , CRC(48745bbb) SHA1(fb4427f729eedba5ac01809718b841c7bdd85e1f)) +ROM_END + +WRITE_LINE_MEMBER(hp82900_io_card_device::reset_w) +{ + LOG("reset_w %d\n" , state); + m_cpu->set_input_line(INPUT_LINE_RESET , state); + if (state) { + // When reset is asserted, clear state + device_reset(); + } +} + +READ8_MEMBER(hp82900_io_card_device::cpu_mem_r) +{ + if (m_rom_enabled) { + return m_rom[ offset & 0x7ff ]; + } else { + return m_ram[ offset ]; + } +} + +WRITE8_MEMBER(hp82900_io_card_device::cpu_mem_w) +{ + m_ram[ offset ] = data; +} + +READ8_MEMBER(hp82900_io_card_device::cpu_io_r) +{ + m_rom_enabled = false; + + uint8_t res; + if (BIT(offset , 6) && (m_addr_latch & 0x82) == 0) { + res = m_translator->uc_r(space , m_addr_latch & 1 , mem_mask); + } else { + res = ~0; + } + return res; +} + +WRITE8_MEMBER(hp82900_io_card_device::cpu_io_w) +{ + m_rom_enabled = false; + if (BIT(offset , 6) && (m_addr_latch & 0x82) == 0) { + m_translator->uc_w(space , m_addr_latch & 1 , data , mem_mask); + } else if (BIT(offset , 7)) { + m_addr_latch = data; + } +} + +void hp82900_io_card_device::cpu_mem_map(address_map &map) +{ + map.unmap_value_high(); + map(0x0000 , 0xffff).rw(FUNC(hp82900_io_card_device::cpu_mem_r) , FUNC(hp82900_io_card_device::cpu_mem_w)); +} + +void hp82900_io_card_device::cpu_io_map(address_map &map) +{ + map.unmap_value_high(); + map.global_mask(0xff); + map(0x00 , 0xff).rw(FUNC(hp82900_io_card_device::cpu_io_r) , FUNC(hp82900_io_card_device::cpu_io_w)); +} + +WRITE8_MEMBER(hp82900_io_card_device::z80_m1_w) +{ + // 1 wait state on each M1 cycle + m_cpu->adjust_icount(-1); +} + +const tiny_rom_entry *hp82900_io_card_device::device_rom_region() const +{ + return ROM_NAME(hp82900); +} + +void hp82900_io_card_device::device_add_mconfig(machine_config &config) +{ + Z80(config , m_cpu , XTAL(8'000'000) / 2); + m_cpu->set_addrmap(AS_PROGRAM , &hp82900_io_card_device::cpu_mem_map); + m_cpu->set_addrmap(AS_IO , &hp82900_io_card_device::cpu_io_map); + m_cpu->refresh_cb().set(FUNC(hp82900_io_card_device::z80_m1_w)); + + HP_1MB5(config, m_translator, 0); + m_translator->irl_handler().set(FUNC(hp82900_io_card_device::irl_w)); + m_translator->halt_handler().set(FUNC(hp82900_io_card_device::halt_w)); + m_translator->reset_handler().set(FUNC(hp82900_io_card_device::reset_w)); + m_translator->int_handler().set([this](int state) { m_cpu->set_input_line(INPUT_LINE_IRQ0 , !state); }); +} + +// device type definition +DEFINE_DEVICE_TYPE(HP82900_IO_CARD, hp82900_io_card_device, "hp82900", "HP82900 card") diff --git a/src/devices/bus/hp80_io/82900.h b/src/devices/bus/hp80_io/82900.h new file mode 100644 index 00000000000..b562379c8ae --- /dev/null +++ b/src/devices/bus/hp80_io/82900.h @@ -0,0 +1,67 @@ +// license:BSD-3-Clause +// copyright-holders: F. Ulivi +/********************************************************************* + + 82900.h + + 82900 module (CP/M auxiliary processor) + +*********************************************************************/ + +#ifndef MAME_BUS_HP80_IO_82900_H +#define MAME_BUS_HP80_IO_82900_H + +#pragma once + +#include "hp80_io.h" +#include "cpu/z80/z80.h" +#include "machine/1mb5.h" + +class hp82900_io_card_device : public device_t, public device_hp80_io_interface +{ +public: + // construction/destruction + hp82900_io_card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + virtual ~hp82900_io_card_device(); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + // device-level overrides + virtual ioport_constructor device_input_ports() const override; + virtual const tiny_rom_entry *device_rom_region() const override; + virtual void device_add_mconfig(machine_config &config) override; + + virtual void install_read_write_handlers(address_space& space , uint16_t base_addr) override; + + virtual void inten() override; + virtual void clear_service() override; + +private: + required_device<z80_device> m_cpu; + required_device<hp_1mb5_device> m_translator; + + // Boot ROM + required_region_ptr<uint8_t> m_rom; + + // RAM + std::unique_ptr<uint8_t []> m_ram; + + bool m_rom_enabled; + uint8_t m_addr_latch; + + DECLARE_WRITE_LINE_MEMBER(reset_w); + DECLARE_READ8_MEMBER(cpu_mem_r); + DECLARE_WRITE8_MEMBER(cpu_mem_w); + DECLARE_READ8_MEMBER(cpu_io_r); + DECLARE_WRITE8_MEMBER(cpu_io_w); + void cpu_mem_map(address_map &map); + void cpu_io_map(address_map &map); + DECLARE_WRITE8_MEMBER(z80_m1_w); +}; + +// device type definition +DECLARE_DEVICE_TYPE(HP82900_IO_CARD, hp82900_io_card_device) + +#endif // MAME_BUS_HP80_IO_82900_H diff --git a/src/devices/bus/hp80_io/hp80_io.cpp b/src/devices/bus/hp80_io/hp80_io.cpp index 86946007419..591435bafac 100644 --- a/src/devices/bus/hp80_io/hp80_io.cpp +++ b/src/devices/bus/hp80_io/hp80_io.cpp @@ -95,7 +95,7 @@ uint16_t hp80_io_slot_device::get_base_addr() const const device_hp80_io_interface *card = get_card_device(); if (card != nullptr) { - uint16_t addr = ((uint16_t)(card->get_sc() - HP80_IO_FIRST_SC) << 1) | 0xff50; + uint16_t addr = ((uint16_t)(card->get_sc()) << 1) | 0xff40; return addr; } else { return 0; @@ -107,7 +107,7 @@ uint16_t hp80_io_slot_device::get_base_addr() const // +------------------------+ uint8_t device_hp80_io_interface::get_sc() const { - return m_select_code_port->read() + HP80_IO_FIRST_SC; + return m_select_code_port->read(); } void device_hp80_io_interface::inten() @@ -142,11 +142,13 @@ WRITE_LINE_MEMBER(device_hp80_io_interface::halt_w) slot->halt_w(state); } +#include "82900.h" #include "82937.h" #include "82939.h" void hp80_io_slot_devices(device_slot_interface &device) { + device.option_add("82900_cpm" , HP82900_IO_CARD); device.option_add("82937_hpib" , HP82937_IO_CARD); device.option_add("82939_serial" , HP82939_IO_CARD); } diff --git a/src/devices/bus/hp80_io/hp80_io.h b/src/devices/bus/hp80_io/hp80_io.h index 31028d97cdb..3963d56d29e 100644 --- a/src/devices/bus/hp80_io/hp80_io.h +++ b/src/devices/bus/hp80_io/hp80_io.h @@ -13,20 +13,19 @@ #pragma once - -#define HP80_IO_FIRST_SC 3 // Lowest SC used by I/O cards +#define HP80_IO_SC_OFFSET 5 #define PORT_HP80_IO_SC(_default_sc) \ PORT_START("SC") \ - PORT_CONFNAME(0xf , (_default_sc) - HP80_IO_FIRST_SC , "Select Code") \ - PORT_CONFSETTING(0 , "3")\ - PORT_CONFSETTING(1 , "4")\ - PORT_CONFSETTING(2 , "5")\ - PORT_CONFSETTING(3 , "6")\ - PORT_CONFSETTING(4 , "7")\ - PORT_CONFSETTING(5 , "8")\ - PORT_CONFSETTING(6 , "9")\ - PORT_CONFSETTING(7 , "10") + PORT_CONFNAME(0xf , (_default_sc) + HP80_IO_SC_OFFSET , "Select Code") \ + PORT_CONFSETTING(8 , "3")\ + PORT_CONFSETTING(9 , "4")\ + PORT_CONFSETTING(10 , "5")\ + PORT_CONFSETTING(11 , "6")\ + PORT_CONFSETTING(12 , "7")\ + PORT_CONFSETTING(13 , "8")\ + PORT_CONFSETTING(14 , "9")\ + PORT_CONFSETTING(15 , "10") void hp80_io_slot_devices(device_slot_interface &device); |