mirror of
https://github.com/holub/mame
synced 2025-04-19 15:11:37 +03:00
vme/enp10: add new device [CJ, System Source Computer Museum]
This commit is contained in:
parent
f83830751a
commit
b877d9c15e
@ -2641,6 +2641,8 @@ end
|
||||
|
||||
if (BUSES["VME"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/bus/vme/enp10.cpp",
|
||||
MAME_DIR .. "src/devices/bus/vme/enp10.h",
|
||||
MAME_DIR .. "src/devices/bus/vme/mvme187.cpp",
|
||||
MAME_DIR .. "src/devices/bus/vme/mvme187.h",
|
||||
MAME_DIR .. "src/devices/bus/vme/tp881v.cpp",
|
||||
|
166
src/devices/bus/vme/enp10.cpp
Normal file
166
src/devices/bus/vme/enp10.cpp
Normal file
@ -0,0 +1,166 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Patrick Mackinlay
|
||||
|
||||
/*
|
||||
* Communication Machinery Corporation Ethernet Node Processor (ENP-10)
|
||||
*
|
||||
* Sources:
|
||||
* - Ethernet Node Processor ENP-30 Reference Guide (6213000-05B), Communication Machinery Corporation, November 15, 1988
|
||||
*
|
||||
* TODO:
|
||||
* - vme interface
|
||||
* - address/interrupt configuration
|
||||
* - verify registers
|
||||
* - uart?
|
||||
*/
|
||||
|
||||
/*
|
||||
* WIP
|
||||
* ---
|
||||
* - 0xef'8010-0xef'802f appears to be a uart, but doesn't match scn2681 per ENP-30 documentation?
|
||||
* - following text is output to 0xef'008025 at startup:
|
||||
* CMC ENP/10 CMOS - 112708 Bytes Free
|
||||
* Ethernet Address: 02CF1F123456
|
||||
* Allocating 30 receive buffers
|
||||
* Allocating 30 transmit buffers
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "enp10.h"
|
||||
|
||||
#define VERBOSE 0
|
||||
#include "logmacro.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(CMC_ENP10, cmc_enp10_device, "cmc_enp10", "CMC ENP-10")
|
||||
|
||||
cmc_enp10_device::cmc_enp10_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, CMC_ENP10, tag, owner, clock)
|
||||
, device_vme_card_interface(mconfig, *this)
|
||||
, m_cpu(*this, "cpu")
|
||||
, m_net(*this, "net")
|
||||
, m_led(*this, "led%u", 0U)
|
||||
, m_boot(*this, "boot")
|
||||
{
|
||||
}
|
||||
|
||||
ROM_START(enp10)
|
||||
ROM_REGION16_BE(0x4000, "eprom", 0)
|
||||
ROM_SYSTEM_BIOS(0, "enp10", "CMC ENP/10 CMOS")
|
||||
ROMX_LOAD("link_10_2.0_nh_rev.4.1h.u4", 0x0000, 0x2000, CRC(7532f2b1) SHA1(bdef6c525f451fbc67f3d4625c9db18975e7e1e4), ROM_SKIP(1) | ROM_BIOS(0)) // AM2764A
|
||||
ROMX_LOAD("link_10_2.0_nh_rev.k4.1l.u3", 0x0001, 0x2000, CRC(f2decb78) SHA1(795623274bfff6273790c30445e4dca4064859ed), ROM_SKIP(1) | ROM_BIOS(0)) // AM2764A
|
||||
|
||||
// hand-crafted prom containing address 02:cf:1f:12:34:56
|
||||
ROM_REGION16_BE(0x20, "mac", 0)
|
||||
ROM_LOAD("mac.bin", 0x00, 0x20, CRC(99ac9577) SHA1(b4d6bba88dd376cc492738d57742628f42e9265e))
|
||||
ROM_END
|
||||
|
||||
static INPUT_PORTS_START(enp10)
|
||||
INPUT_PORTS_END
|
||||
|
||||
const tiny_rom_entry *cmc_enp10_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME(enp10);
|
||||
}
|
||||
|
||||
ioport_constructor cmc_enp10_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(enp10);
|
||||
}
|
||||
|
||||
void cmc_enp10_device::device_start()
|
||||
{
|
||||
m_led.resolve();
|
||||
|
||||
save_item(NAME(m_ier));
|
||||
save_item(NAME(m_tir));
|
||||
save_item(NAME(m_rir));
|
||||
save_item(NAME(m_uir));
|
||||
save_item(NAME(m_exr));
|
||||
save_item(NAME(m_csr));
|
||||
save_item(NAME(m_rer));
|
||||
save_item(NAME(m_hir));
|
||||
}
|
||||
|
||||
void cmc_enp10_device::device_reset()
|
||||
{
|
||||
m_boot.select(0);
|
||||
|
||||
m_ier = 0;
|
||||
m_tir = 0;
|
||||
m_rir = 0;
|
||||
m_uir = 0;
|
||||
m_exr = 0;
|
||||
m_csr = 0;
|
||||
m_rer = 0;
|
||||
m_hir = 0;
|
||||
}
|
||||
|
||||
void cmc_enp10_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
M68000(config, m_cpu, 10_MHz_XTAL / 2);
|
||||
m_cpu->set_addrmap(AS_PROGRAM, &cmc_enp10_device::cpu_mem);
|
||||
|
||||
AM7990(config, m_net, 20_MHz_XTAL / 2);
|
||||
m_net->intr_out().set_inputline(m_cpu, INPUT_LINE_IRQ6).invert();
|
||||
m_net->dma_in().set([this](offs_t offset) { return m_cpu->space(0).read_word(offset); });
|
||||
m_net->dma_out().set([this](offs_t offset, u16 data, u16 mem_mask) { m_cpu->space(0).write_word(offset, data, mem_mask); });
|
||||
}
|
||||
|
||||
void cmc_enp10_device::cpu_mem(address_map &map)
|
||||
{
|
||||
map(0xf8'0000, 0xf8'3fff).rom().region("eprom", 0).mirror(0x02'0000);
|
||||
|
||||
map(0x00'0000, 0xf1'ffff).view(m_boot);
|
||||
// map 1k of eprom at 0x00'0000
|
||||
m_boot[0](0x00'0000, 0x00'0fff).rom().region("eprom", 0);
|
||||
m_boot[0](0xf0'0000, 0xf1'ffff).ram().share("ram");
|
||||
|
||||
// map 1k of ram at 0x00'0000, unmap at 0xf0'0000
|
||||
m_boot[1](0x00'0000, 0x01'ffff).ram().share("ram");
|
||||
m_boot[1](0x00'1000, 0x01'ffff).unmaprw();
|
||||
m_boot[1](0xf0'0000, 0xf1'ffff).ram().share("ram");
|
||||
m_boot[1](0xf0'0000, 0xf0'0fff).unmaprw();
|
||||
|
||||
// uart: 16 byte registers 10-2f?
|
||||
map(0xef'8010, 0xef'802f).noprw();
|
||||
|
||||
// fe'0080 vector? w:host vectored interrupt, r:slave address msb
|
||||
|
||||
map(0xfe'00a0, 0xfe'00a1).umask16(0x00ff).lrw8(
|
||||
[this]() { return m_csr; }, "csr_r",
|
||||
[this](u8 data)
|
||||
{
|
||||
LOG("csr_w 0x%02x\n", data);
|
||||
|
||||
m_led[0] = BIT(data, 6); // fail?
|
||||
m_led[1] = BIT(data, 5); // run?
|
||||
|
||||
m_csr = data;
|
||||
}, "csr_w");
|
||||
|
||||
map(0xfe'00c0, 0xfe'00c1).umask16(0x00ff).lrw8(NAME([this]() { return m_ier; }), NAME([this](u8 data) { m_ier = data; interrupt(); }));
|
||||
map(0xfe'00c2, 0xfe'00c3).umask16(0x00ff).lrw8(NAME([this]() { return m_tir; }), NAME([this](u8 data) { m_tir = data; interrupt(); }));
|
||||
map(0xfe'00c4, 0xfe'00c5).umask16(0x00ff).lrw8(NAME([this]() { return m_rir; }), NAME([this](u8 data) { m_rir = data; interrupt(); }));
|
||||
map(0xfe'00c6, 0xfe'00c7).umask16(0x00ff).lrw8(NAME([this]() { return m_uir; }), NAME([this](u8 data) { m_uir = data; interrupt(); }));
|
||||
map(0xfe'00ce, 0xfe'00cf).umask16(0x00ff).lrw8(NAME([this]() { return m_rer; }), NAME([this](u8 data) { m_rer = data; m_boot.select(BIT(data, 7)); }));
|
||||
|
||||
map(0xfe'00e0, 0xfe'00e1).umask16(0x00ff).lrw8(NAME([this]() { return m_exr; }), NAME([this](u8 data) { m_exr = data; })); // TODO: bit 1 parity error?
|
||||
map(0xfe'00ee, 0xfe'00ef).umask16(0x00ff).lr8(NAME([]() { return 0; })); // TODO: bit 1 enables additional ram test?
|
||||
|
||||
map(0xfe'0200, 0xfe'0203).rw(m_net, FUNC(am7990_device::regs_r), FUNC(am7990_device::regs_w));
|
||||
map(0xfe'0400, 0xfe'041f).rom().region("mac", 0);
|
||||
|
||||
// TODO: verify the next two registers
|
||||
map(0xfe'0e00, 0xfe'0e01).umask16(0x00ff).lrw8(NAME([this]() { return m_hir; }), NAME([this](u8 data) { m_hir = data; interrupt(); }));
|
||||
map(0xfe'0f00, 0xfe'0f01).umask16(0x00ff).lrw8(NAME([this]() { reset(); return 0; }), NAME([this](u8 data) { reset(); }));
|
||||
}
|
||||
|
||||
void cmc_enp10_device::interrupt()
|
||||
{
|
||||
bool const enable = BIT(m_ier, 7);
|
||||
|
||||
m_cpu->set_input_line(INPUT_LINE_IRQ2, enable && BIT(m_uir, 7));
|
||||
m_cpu->set_input_line(INPUT_LINE_IRQ3, enable && BIT(m_hir, 7));
|
||||
m_cpu->set_input_line(INPUT_LINE_IRQ4, enable && BIT(m_tir, 7));
|
||||
m_cpu->set_input_line(INPUT_LINE_IRQ5, enable && BIT(m_rir, 7));
|
||||
}
|
51
src/devices/bus/vme/enp10.h
Normal file
51
src/devices/bus/vme/enp10.h
Normal file
@ -0,0 +1,51 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Patrick Mackinlay
|
||||
|
||||
#ifndef MAME_BUS_VME_ENP10_H
|
||||
#define MAME_BUS_VME_ENP10_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cpu/m68000/m68000.h"
|
||||
#include "machine/am79c90.h"
|
||||
#include "bus/vme/vme.h"
|
||||
|
||||
class cmc_enp10_device
|
||||
: public device_t
|
||||
, public device_vme_card_interface
|
||||
{
|
||||
public:
|
||||
cmc_enp10_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||
|
||||
protected:
|
||||
virtual const tiny_rom_entry *device_rom_region() const override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
virtual ioport_constructor device_input_ports() const override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
private:
|
||||
void cpu_mem(address_map &map);
|
||||
|
||||
void interrupt();
|
||||
|
||||
required_device<m68000_device> m_cpu;
|
||||
required_device<am7990_device> m_net;
|
||||
|
||||
output_finder<2> m_led;
|
||||
|
||||
u8 m_ier; // interrupt enable register
|
||||
u8 m_tir; // transmit interrupt register
|
||||
u8 m_rir; // receive interrupt register
|
||||
u8 m_uir; // utility interrupt register
|
||||
u8 m_exr; // exception register
|
||||
u8 m_csr; // control/status register
|
||||
u8 m_rer; // ram/rom enable register
|
||||
u8 m_hir; // host interrupt register
|
||||
|
||||
memory_view m_boot;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(CMC_ENP10, cmc_enp10_device)
|
||||
|
||||
#endif // MAME_BUS_VME_ENP10_H
|
Loading…
Reference in New Issue
Block a user