diff options
Diffstat (limited to 'src/devices/bus/acorn/system/vdu80.cpp')
-rw-r--r-- | src/devices/bus/acorn/system/vdu80.cpp | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/src/devices/bus/acorn/system/vdu80.cpp b/src/devices/bus/acorn/system/vdu80.cpp new file mode 100644 index 00000000000..77fd4d7a629 --- /dev/null +++ b/src/devices/bus/acorn/system/vdu80.cpp @@ -0,0 +1,195 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Acorn 80x25 VDU Interface + + Part No. 400,019 + + http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Acorn_80x25VDUIF.html + +**********************************************************************/ + + +#include "emu.h" +#include "vdu80.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(ACORN_VDU80, acorn_vdu80_device, "acorn_vdu80", "Acorn 80x25 VDU Interface") + + +//------------------------------------------------- +// INPUT_PORTS( vdu80 ) +//------------------------------------------------- + +INPUT_PORTS_START( vdu80 ) + PORT_START("LINKS") + PORT_CONFNAME(0x01, 0x00, "Address Selection (RAM/CRTC)") + PORT_CONFSETTING(0x00, "A: &1000-&17FF/&1840-&1841") + PORT_CONFSETTING(0x01, "B: &F000-&F7FF/&E840-&E841") + PORT_CONFNAME(0x02, 0x00, "LK2: Display Inversion") + PORT_CONFSETTING(0x00, DEF_STR(No)) + PORT_CONFSETTING(0x02, DEF_STR(Yes)) +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor acorn_vdu80_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( vdu80 ); +} + + +//------------------------------------------------- +// MACHINE_DRIVER( vdu80 ) +//------------------------------------------------- + +ROM_START( vdu80 ) + ROM_REGION(0x0800, "chargen", 0) + ROM_LOAD("80chvdu.ic13", 0x0000, 0x0800, CRC(a943f01b) SHA1(04c326a745ba6a78185ebc2adeecb53a166a6ab3)) +ROM_END + + +//------------------------------------------------- +// gfx_layout acorn_vdu80_charlayout +//------------------------------------------------- + +static const gfx_layout acorn_vdu80_charlayout = +{ + 6, 10, /* 6 x 10 characters */ + 128, /* 128 characters */ + 1, /* 1 bits per pixel */ + { 0 }, /* no bitplanes */ + /* x offsets */ + { 0, 1, 2, 3, 4, 5 }, + /* y offsets */ + { 0 * 8, 1 * 8, 2 * 8, 3 * 8, 4 * 8, 5 * 8, 6 * 8, 7 * 8, 8 * 8, 9 * 8 }, + 8 * 16 /* every char takes 16 bytes */ +}; + +//------------------------------------------------- +// GFXDECODE( gfx_acorn_vdu80 ) +//------------------------------------------------- + +static GFXDECODE_START(gfx_acorn_vdu80) + GFXDECODE_ENTRY("chargen", 0, acorn_vdu80_charlayout, 0, 1) +GFXDECODE_END + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +MACHINE_CONFIG_START(acorn_vdu80_device::device_add_mconfig) + device = &SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_color(rgb_t::white()); + m_screen->set_raw(12_MHz_XTAL, 768, 132, 612, 312, 20, 270); + MCFG_SCREEN_UPDATE_DEVICE("mc6845", mc6845_device, screen_update) + + MCFG_DEVICE_ADD("gfxdecode", GFXDECODE, "palette", gfx_acorn_vdu80) + MCFG_PALETTE_ADD_MONOCHROME("palette") + + H46505(config, m_crtc, 2_MHz_XTAL); + m_crtc->set_screen("screen"); + m_crtc->set_show_border_area(false); + m_crtc->set_char_width(6); + m_crtc->set_update_row_callback(FUNC(acorn_vdu80_device::crtc_update_row), this); +MACHINE_CONFIG_END + + +const tiny_rom_entry *acorn_vdu80_device::device_rom_region() const +{ + return ROM_NAME( vdu80 ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// acorn_vdu80_device - constructor +//------------------------------------------------- + +acorn_vdu80_device::acorn_vdu80_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, ACORN_VDU80, tag, owner, clock) + , device_acorn_bus_interface(mconfig, *this) + , m_chargen(*this, "chargen") + , m_screen(*this, "screen") + , m_crtc(*this, "mc6845") + , m_palette(*this, "palette") + , m_links(*this, "LINKS") +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void acorn_vdu80_device::device_start() +{ + /* allocate m_videoram */ + m_videoram = std::make_unique<uint8_t[]>(0x0800); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void acorn_vdu80_device::device_reset() +{ + set_acorn_bus_device(); + address_space &space = m_bus->memspace(); + + if (m_links->read() & 0x01) + { + space.install_ram(0xf000, 0x0f7ff, m_videoram.get()); + + space.install_readwrite_handler(0xe840, 0xe840, 0, 0x3f, 0, read8_delegate(FUNC(mc6845_device::status_r), m_crtc.target()), write8_delegate(FUNC(mc6845_device::address_w), m_crtc.target())); + space.install_readwrite_handler(0xe841, 0xe841, 0, 0x3e, 0, read8_delegate(FUNC(mc6845_device::register_r), m_crtc.target()), write8_delegate(FUNC(mc6845_device::register_w), m_crtc.target())); + } + else + { + space.install_ram(0x1000, 0x017ff, m_videoram.get()); + + space.install_readwrite_handler(0x1840, 0x1840, 0, 0x3f, 0, read8_delegate(FUNC(mc6845_device::status_r), m_crtc.target()), write8_delegate(FUNC(mc6845_device::address_w), m_crtc.target())); + space.install_readwrite_handler(0x1841, 0x1841, 0, 0x3e, 0, read8_delegate(FUNC(mc6845_device::register_r), m_crtc.target()), write8_delegate(FUNC(mc6845_device::register_w), m_crtc.target())); + } +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +MC6845_UPDATE_ROW(acorn_vdu80_device::crtc_update_row) +{ + uint8_t invert = BIT(m_links->read(), 1); + uint32_t *p = &bitmap.pix32(y); + + for (int column = 0; column < x_count; column++) + { + uint8_t code = m_videoram[(ma + column) & 0x7ff]; + uint16_t addr = (code << 4) | (ra & 0x0f); + uint8_t data = m_chargen->base()[addr & 0x7ff]; + + if (column == cursor_x) + { + data = 0xff; + } + + for (int bit = 0; bit < 6; bit++) + { + *p++ = m_palette->pen(BIT(data, 7) ^ invert); + + data <<= 1; + } + } +} |