summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices
diff options
context:
space:
mode:
author R. Belmont <rb6502@users.noreply.github.com>2020-03-04 10:45:30 -0500
committer GitHub <noreply@github.com>2020-03-04 10:45:30 -0500
commit43a9794c2033f885c85142d94ad038d987021912 (patch)
tree5e8077f25a0da397afd5640f30d1bf4cd5eb566c /src/devices
parent71b0245763509c8b1592171d0e818dff99ac21a3 (diff)
parentd469028abc5b86b0748c9d2167b91cac2ca0a5ee (diff)
Merge pull request #6388 from fulivi/hp80_dev07
HP82900 CP/M module
Diffstat (limited to 'src/devices')
-rw-r--r--src/devices/bus/hp80_io/82900.cpp175
-rw-r--r--src/devices/bus/hp80_io/82900.h67
-rw-r--r--src/devices/bus/hp80_io/hp80_io.cpp6
-rw-r--r--src/devices/bus/hp80_io/hp80_io.h21
4 files changed, 256 insertions, 13 deletions
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);