hp80: added HP82900 CP/M module

This commit is contained in:
fulivi 2020-03-03 12:55:35 +01:00
parent c1169e6d2d
commit d469028abc
5 changed files with 258 additions and 13 deletions

View File

@ -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",

View File

@ -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")

View File

@ -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

View File

@ -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);
}

View File

@ -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);