From 7e988f9563d837a523c238917760e5d801046fe6 Mon Sep 17 00:00:00 2001 From: Nigel Barnes Date: Thu, 25 Jul 2019 17:05:31 +0100 Subject: microtan.cpp: The Microtan driver overhaul! - Renamed driver microtan->mt65 - Added alternative monitor ROMs: TANBUG V3.1, TANBUG V.3B, TUGBUG V1.1, TANBUG V1. - Replaced XBug with original 0.75MHz version, fixes cassette loading. - New machine Micron, consisting of MT65 and Tanex boards only. - Implemented the Microtan motherboard backplane and moved Tanex to slot device. - Additional boards implemented: Bulldog Sound Generator Board, Mousepacket Designs Colour VDU Card, Tangerine Tandos Board (not working), Tangerine High Resolution Graphics Card (monochrome), Tangerine High Resolution Graphics Card (colour), Tangerine Tanram Board, TUG 64K RAM Card, TUG Programmable Graphic Module Card, Microtanic Video 80/82 (not working), Ralph Allen 32K EPROM-RAM Card (incomplete), Ralph Allen Disc Controller Card (not working), Ralph Allen Colour VDU card - Added Microtan 6809 System, not yet working. - Added Space Invasion (ETI), the DIY project from Electronics Today based on the Microtan. --- scripts/src/bus.lua | 36 +++ scripts/target/mame/mess.lua | 1 + src/devices/bus/tanbus/bullsnd.cpp | 103 +++++++++ src/devices/bus/tanbus/bullsnd.h | 49 +++++ src/devices/bus/tanbus/mpvdu.cpp | 182 ++++++++++++++++ src/devices/bus/tanbus/mpvdu.h | 62 ++++++ src/devices/bus/tanbus/ra32k.cpp | 257 ++++++++++++++++++++++ src/devices/bus/tanbus/ra32k.h | 59 +++++ src/devices/bus/tanbus/radisc.cpp | 213 ++++++++++++++++++ src/devices/bus/tanbus/radisc.h | 76 +++++++ src/devices/bus/tanbus/ravdu.cpp | 195 +++++++++++++++++ src/devices/bus/tanbus/ravdu.h | 63 ++++++ src/devices/bus/tanbus/tanbus.cpp | 254 +++++++++++++++++++++ src/devices/bus/tanbus/tanbus.h | 150 +++++++++++++ src/devices/bus/tanbus/tandos.cpp | 254 +++++++++++++++++++++ src/devices/bus/tanbus/tandos.h | 72 ++++++ src/devices/bus/tanbus/tanex.cpp | 436 +++++++++++++++++++++++++++++++++++++ src/devices/bus/tanbus/tanex.h | 86 ++++++++ src/devices/bus/tanbus/tanhrg.cpp | 368 +++++++++++++++++++++++++++++++ src/devices/bus/tanbus/tanhrg.h | 90 ++++++++ src/devices/bus/tanbus/tanram.cpp | 93 ++++++++ src/devices/bus/tanbus/tanram.h | 45 ++++ src/devices/bus/tanbus/tug64k.cpp | 188 ++++++++++++++++ src/devices/bus/tanbus/tug64k.h | 51 +++++ src/devices/bus/tanbus/tug8082.cpp | 263 ++++++++++++++++++++++ src/devices/bus/tanbus/tug8082.h | 70 ++++++ src/devices/bus/tanbus/tugpgm.cpp | 113 ++++++++++ src/devices/bus/tanbus/tugpgm.h | 52 +++++ src/mame/drivers/microtan.cpp | 404 ++++++++++++++++++++++++---------- src/mame/includes/microtan.h | 105 +++++---- src/mame/machine/microtan.cpp | 197 ++++++----------- src/mame/mame.lst | 5 +- src/mame/video/microtan.cpp | 4 + 33 files changed, 4307 insertions(+), 289 deletions(-) create mode 100644 src/devices/bus/tanbus/bullsnd.cpp create mode 100644 src/devices/bus/tanbus/bullsnd.h create mode 100644 src/devices/bus/tanbus/mpvdu.cpp create mode 100644 src/devices/bus/tanbus/mpvdu.h create mode 100644 src/devices/bus/tanbus/ra32k.cpp create mode 100644 src/devices/bus/tanbus/ra32k.h create mode 100644 src/devices/bus/tanbus/radisc.cpp create mode 100644 src/devices/bus/tanbus/radisc.h create mode 100644 src/devices/bus/tanbus/ravdu.cpp create mode 100644 src/devices/bus/tanbus/ravdu.h create mode 100644 src/devices/bus/tanbus/tanbus.cpp create mode 100644 src/devices/bus/tanbus/tanbus.h create mode 100644 src/devices/bus/tanbus/tandos.cpp create mode 100644 src/devices/bus/tanbus/tandos.h create mode 100644 src/devices/bus/tanbus/tanex.cpp create mode 100644 src/devices/bus/tanbus/tanex.h create mode 100644 src/devices/bus/tanbus/tanhrg.cpp create mode 100644 src/devices/bus/tanbus/tanhrg.h create mode 100644 src/devices/bus/tanbus/tanram.cpp create mode 100644 src/devices/bus/tanbus/tanram.h create mode 100644 src/devices/bus/tanbus/tug64k.cpp create mode 100644 src/devices/bus/tanbus/tug64k.h create mode 100644 src/devices/bus/tanbus/tug8082.cpp create mode 100644 src/devices/bus/tanbus/tug8082.h create mode 100644 src/devices/bus/tanbus/tugpgm.cpp create mode 100644 src/devices/bus/tanbus/tugpgm.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 69af8c860ee..2ca74db3c79 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -2825,6 +2825,42 @@ if (BUSES["SMS_EXP"]~=null) then } end +--------------------------------------------------- +-- +--@src/devices/bus/tanbus/tanbus.h,BUSES["TANBUS"] = true +--------------------------------------------------- + +if (BUSES["TANBUS"]~=null) then + files { + MAME_DIR .. "src/devices/bus/tanbus/bullsnd.cpp", + MAME_DIR .. "src/devices/bus/tanbus/bullsnd.h", + MAME_DIR .. "src/devices/bus/tanbus/tanbus.cpp", + MAME_DIR .. "src/devices/bus/tanbus/tanbus.h", + MAME_DIR .. "src/devices/bus/tanbus/tanex.cpp", + MAME_DIR .. "src/devices/bus/tanbus/tanex.h", + MAME_DIR .. "src/devices/bus/tanbus/tandos.cpp", + MAME_DIR .. "src/devices/bus/tanbus/tandos.h", + MAME_DIR .. "src/devices/bus/tanbus/tanhrg.cpp", + MAME_DIR .. "src/devices/bus/tanbus/tanhrg.h", + MAME_DIR .. "src/devices/bus/tanbus/tanram.cpp", + MAME_DIR .. "src/devices/bus/tanbus/tanram.h", + MAME_DIR .. "src/devices/bus/tanbus/mpvdu.cpp", + MAME_DIR .. "src/devices/bus/tanbus/mpvdu.h", + MAME_DIR .. "src/devices/bus/tanbus/ra32k.cpp", + MAME_DIR .. "src/devices/bus/tanbus/ra32k.h", + MAME_DIR .. "src/devices/bus/tanbus/radisc.cpp", + MAME_DIR .. "src/devices/bus/tanbus/radisc.h", + MAME_DIR .. "src/devices/bus/tanbus/ravdu.cpp", + MAME_DIR .. "src/devices/bus/tanbus/ravdu.h", + MAME_DIR .. "src/devices/bus/tanbus/tug64k.cpp", + MAME_DIR .. "src/devices/bus/tanbus/tug64k.h", + MAME_DIR .. "src/devices/bus/tanbus/tug8082.cpp", + MAME_DIR .. "src/devices/bus/tanbus/tug8082.h", + MAME_DIR .. "src/devices/bus/tanbus/tugpgm.cpp", + MAME_DIR .. "src/devices/bus/tanbus/tugpgm.h", + } +end + --------------------------------------------------- -- --@src/devices/bus/ti8x/ti8x.h,BUSES["TI8X"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 325283f6f92..cbcc19c2c2b 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -844,6 +844,7 @@ BUSES["SUNKBD"] = true BUSES["SUNMOUSE"] = true BUSES["SVI_EXPANDER"] = true BUSES["SVI_SLOT"] = true +BUSES["TANBUS"] = true BUSES["TATUNG_PIPE"] = true BUSES["TMC600"] = true BUSES["TI8X"] = true diff --git a/src/devices/bus/tanbus/bullsnd.cpp b/src/devices/bus/tanbus/bullsnd.cpp new file mode 100644 index 00000000000..3dcd7a9897b --- /dev/null +++ b/src/devices/bus/tanbus/bullsnd.cpp @@ -0,0 +1,103 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Microtan Bulldog Sound Generator Board + + http://www.microtan.ukpc.net/pageProducts.html#SOUND + +**********************************************************************/ + + +#include "emu.h" +#include "bullsnd.h" +#include "speaker.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(TANBUS_BULLSND, tanbus_bullsnd_device, "tanbus_bullsnd", "Microtan Bulldog Sound Generator Board") + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void tanbus_bullsnd_device::device_add_mconfig(machine_config &config) +{ + SPEAKER(config, "speaker").front_center(); + AY8910(config, m_ay8910[0], DERIVED_CLOCK(1, 8)).add_route(ALL_OUTPUTS, "speaker", 0.5); + AY8910(config, m_ay8910[1], DERIVED_CLOCK(1, 8)).add_route(ALL_OUTPUTS, "speaker", 0.5); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// tanbus_bullsnd_device - constructor +//------------------------------------------------- + +tanbus_bullsnd_device::tanbus_bullsnd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, TANBUS_BULLSND, tag, owner, clock) + , device_tanbus_interface(mconfig, *this) + , m_ay8910(*this, "ay8910%u", 0) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void tanbus_bullsnd_device::device_start() +{ +} + + +//------------------------------------------------- +// read - card read +//------------------------------------------------- + +uint8_t tanbus_bullsnd_device::read(offs_t offset, int inhrom, int inhram, int be) +{ + uint8_t data = 0xff; + + switch (offset) + { + case 0xbc01: + data = m_ay8910[0]->data_r(); + break; + case 0xbc03: + data = m_ay8910[1]->data_r(); + break; + } + + return data; +} + + +//------------------------------------------------- +// write - card write +//------------------------------------------------- + +void tanbus_bullsnd_device::write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) +{ + switch (offset) + { + case 0xbc00: + m_ay8910[0]->address_w(data); + break; + case 0xbc01: + m_ay8910[0]->data_w(data); + break; + case 0xbc02: + m_ay8910[1]->address_w(data); + break; + case 0xbc03: + m_ay8910[1]->data_w(data); + break; + } +} diff --git a/src/devices/bus/tanbus/bullsnd.h b/src/devices/bus/tanbus/bullsnd.h new file mode 100644 index 00000000000..1573eab6351 --- /dev/null +++ b/src/devices/bus/tanbus/bullsnd.h @@ -0,0 +1,49 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Microtan Bulldog Sound Generator Board + +**********************************************************************/ + + +#ifndef MAME_BUS_TANBUS_BULLSND_H +#define MAME_BUS_TANBUS_BULLSND_H + +#pragma once + +#include "bus/tanbus/tanbus.h" +#include "sound/ay8910.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class tanbus_bullsnd_device : + public device_t, + public device_tanbus_interface +{ +public: + // construction/destruction + tanbus_bullsnd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + + virtual uint8_t read(offs_t offset, int inhrom, int inhram, int be) override; + virtual void write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) override; + +private: + required_device_array m_ay8910; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(TANBUS_BULLSND, tanbus_bullsnd_device) + + +#endif // MAME_BUS_TANBUS_BULLSND_H diff --git a/src/devices/bus/tanbus/mpvdu.cpp b/src/devices/bus/tanbus/mpvdu.cpp new file mode 100644 index 00000000000..8463d90b6c5 --- /dev/null +++ b/src/devices/bus/tanbus/mpvdu.cpp @@ -0,0 +1,182 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Microtan Mousepacket Designs Colour VDU Card + + http://www.microtan.ukpc.net/pageProducts.html#VIDEO + + TODO: + - use MC6845 screen_update to implement cursor, requires interlace + +**********************************************************************/ + + +#include "emu.h" +#include "mpvdu.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(TANBUS_MPVDU, tanbus_mpvdu_device, "tanbus_mpvdu", "Mousepacket Designs Colour VDU Card") + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void tanbus_mpvdu_device::device_add_mconfig(machine_config &config) +{ + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_refresh_hz(50); + m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); + m_screen->set_size(1152, 625); + m_screen->set_visarea(0, 768 - 1, 0, 500 - 1); + //m_screen->set_screen_update("mc6845", FUNC(mc6845_device::screen_update)); // TODO: implement interlace in mc6845 + m_screen->set_screen_update("saa5050", FUNC(saa5050_device::screen_update)); + + MC6845(config, m_crtc, DERIVED_CLOCK(1, 3)); + m_crtc->set_screen(nullptr); + m_crtc->set_show_border_area(false); + m_crtc->set_char_width(12); + m_crtc->out_vsync_callback().set(FUNC(tanbus_mpvdu_device::vsync_changed)); + m_crtc->set_update_row_callback(FUNC(tanbus_mpvdu_device::crtc_update_row), this); + + SAA5050(config, m_trom, DERIVED_CLOCK(1, 1)); + m_trom->d_cb().set(FUNC(tanbus_mpvdu_device::videoram_r)); + m_trom->set_screen_size(64, 25, 64); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// tanbus_mpvdu_device - constructor +//------------------------------------------------- + +tanbus_mpvdu_device::tanbus_mpvdu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, TANBUS_MPVDU, tag, owner, clock) + , device_tanbus_interface(mconfig, *this) + , m_screen(*this, "screen") + , m_crtc(*this, "mc6845") + , m_trom(*this, "saa5050") +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void tanbus_mpvdu_device::device_start() +{ + m_videoram = std::make_unique(0x800); + + save_pointer(NAME(m_videoram), 0x800); +} + +//------------------------------------------------- +// read - card read +//------------------------------------------------- + +uint8_t tanbus_mpvdu_device::read(offs_t offset, int inhrom, int inhram, int be) +{ + uint8_t data = 0xff; + + if ((offset & 0xf800) == 0xa000) + { + data = m_videoram[offset & 0x7ff]; + } + + switch (offset & 0xfff1) + { + case 0xa7f0: + data = m_crtc->status_r(); + break; + case 0xa7f1: + data = m_crtc->register_r(); + break; + } + + return data; +} + +//------------------------------------------------- +// write - card write +//------------------------------------------------- + +void tanbus_mpvdu_device::write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) +{ + if ((offset & 0xf800) == 0xa000) + { + m_videoram[offset & 0x7ff] = data; + } + + switch (offset & 0xfff1) + { + case 0xa7f0: + m_crtc->address_w(data); + break; + case 0xa7f1: + m_crtc->register_w(data); + break; + } +} + +//------------------------------------------------- +// set_inhibit_lines +//------------------------------------------------- + +void tanbus_mpvdu_device::set_inhibit_lines(offs_t offset, int &inhram, int &inhrom) +{ + if ((offset & 0xf800) == 0xa000) + { + inhram = 1; + } +}; + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +READ8_MEMBER(tanbus_mpvdu_device::videoram_r) +{ + return m_videoram[offset]; +} + +MC6845_UPDATE_ROW(tanbus_mpvdu_device::crtc_update_row) +{ + uint32_t *p = &bitmap.pix32(y); + + m_trom->lose_w(1); + m_trom->lose_w(0); + for (int column = 0; column < x_count; column++) + { + m_trom->write(m_videoram[(ma + column) & 0x7ff]); + + m_trom->f1_w(1); + m_trom->f1_w(0); + + for (int bit = 0; bit < 12; bit++) + { + m_trom->tr6_w(1); + m_trom->tr6_w(0); + + int col = m_trom->get_rgb() ^ ((column == cursor_x) ? 7 : 0); + + int r = BIT(col, 0) * 0xff; + int g = BIT(col, 1) * 0xff; + int b = BIT(col, 2) * 0xff; + + *p++ = rgb_t(r, g, b); + } + } +} + +WRITE_LINE_MEMBER(tanbus_mpvdu_device::vsync_changed) +{ + m_trom->dew_w(state); +} diff --git a/src/devices/bus/tanbus/mpvdu.h b/src/devices/bus/tanbus/mpvdu.h new file mode 100644 index 00000000000..c4c48b96199 --- /dev/null +++ b/src/devices/bus/tanbus/mpvdu.h @@ -0,0 +1,62 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Microtan Mousepacket Designs Colour VDU Card + +**********************************************************************/ + + +#ifndef MAME_BUS_TANBUS_MPVDU_H +#define MAME_BUS_TANBUS_MPVDU_H + +#pragma once + +#include "bus/tanbus/tanbus.h" +#include "video/saa5050.h" +#include "video/mc6845.h" +#include "screen.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class tanbus_mpvdu_device : + public device_t, + public device_tanbus_interface +{ +public: + static constexpr feature_type imperfect_features() { return feature::GRAPHICS; } + + // construction/destruction + tanbus_mpvdu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + + virtual uint8_t read(offs_t offset, int inhrom, int inhram, int be) override; + virtual void write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) override; + virtual void set_inhibit_lines(offs_t offset, int &inhram, int &inhrom) override; + +private: + DECLARE_READ8_MEMBER(videoram_r); + MC6845_UPDATE_ROW(crtc_update_row); + DECLARE_WRITE_LINE_MEMBER(vsync_changed); + + required_device m_screen; + required_device m_crtc; + required_device m_trom; + + std::unique_ptr m_videoram; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(TANBUS_MPVDU, tanbus_mpvdu_device) + + +#endif // MAME_BUS_TANBUS_MPVDU_H diff --git a/src/devices/bus/tanbus/ra32k.cpp b/src/devices/bus/tanbus/ra32k.cpp new file mode 100644 index 00000000000..9b83afc96f0 --- /dev/null +++ b/src/devices/bus/tanbus/ra32k.cpp @@ -0,0 +1,257 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Ralph Allen 32K EPROM-RAM Card + + http://www.microtan.ukpc.net/6809/32RAM.pdf + +**********************************************************************/ + + +#include "emu.h" +#include "ra32k.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(TANBUS_RA32K, tanbus_ra32k_device, "tanbus_ra32k", "Ralph Allen 32K EPROM-RAM Card") + + +//------------------------------------------------- +// INPUT_PORTS( ra32k ) +//------------------------------------------------- + +INPUT_PORTS_START( ra32k ) + PORT_START("DSW1") + PORT_DIPNAME(0x01, 0x01, "2K block $0800") PORT_DIPLOCATION("SW1:1") + PORT_DIPSETTING(0x00, "Disable") + PORT_DIPSETTING(0x01, "Enable") + PORT_DIPNAME(0x02, 0x02, "2K block $1800") PORT_DIPLOCATION("SW1:2") + PORT_DIPSETTING(0x00, "Disable") + PORT_DIPSETTING(0x02, "Enable") + PORT_DIPNAME(0x04, 0x04, "2K block $2800") PORT_DIPLOCATION("SW1:3") + PORT_DIPSETTING(0x00, "Disable") + PORT_DIPSETTING(0x04, "Enable") + PORT_DIPNAME(0x08, 0x08, "2K block $3800") PORT_DIPLOCATION("SW1:4") + PORT_DIPSETTING(0x00, "Disable") + PORT_DIPSETTING(0x08, "Enable") + PORT_DIPNAME(0x10, 0x10, "2K block $4800") PORT_DIPLOCATION("SW1:5") + PORT_DIPSETTING(0x00, "Disable") + PORT_DIPSETTING(0x10, "Enable") + PORT_DIPNAME(0x20, 0x20, "2K block $5800") PORT_DIPLOCATION("SW1:6") + PORT_DIPSETTING(0x00, "Disable") + PORT_DIPSETTING(0x20, "Enable") + PORT_DIPNAME(0x40, 0x40, "2K block $6800") PORT_DIPLOCATION("SW1:7") + PORT_DIPSETTING(0x00, "Disable") + PORT_DIPSETTING(0x40, "Enable") + PORT_DIPNAME(0x80, 0x80, "2K block $7800") PORT_DIPLOCATION("SW1:8") + PORT_DIPSETTING(0x00, "Disable") + PORT_DIPSETTING(0x80, "Enable") + + PORT_START("DSW2") + PORT_DIPNAME(0x01, 0x01, "2K block $0000") PORT_DIPLOCATION("SW2:1") + PORT_DIPSETTING(0x00, "Disable") + PORT_DIPSETTING(0x01, "Enable") + PORT_DIPNAME(0x02, 0x02, "2K block $1000") PORT_DIPLOCATION("SW2:2") + PORT_DIPSETTING(0x00, "Disable") + PORT_DIPSETTING(0x02, "Enable") + PORT_DIPNAME(0x04, 0x04, "2K block $2000") PORT_DIPLOCATION("SW2:3") + PORT_DIPSETTING(0x00, "Disable") + PORT_DIPSETTING(0x04, "Enable") + PORT_DIPNAME(0x08, 0x08, "2K block $3000") PORT_DIPLOCATION("SW2:4") + PORT_DIPSETTING(0x00, "Disable") + PORT_DIPSETTING(0x08, "Enable") + PORT_DIPNAME(0x10, 0x10, "2K block $4000") PORT_DIPLOCATION("SW2:5") + PORT_DIPSETTING(0x00, "Disable") + PORT_DIPSETTING(0x10, "Enable") + PORT_DIPNAME(0x20, 0x20, "2K block $5000") PORT_DIPLOCATION("SW2:6") + PORT_DIPSETTING(0x00, "Disable") + PORT_DIPSETTING(0x20, "Enable") + PORT_DIPNAME(0x40, 0x40, "2K block $6000") PORT_DIPLOCATION("SW2:7") + PORT_DIPSETTING(0x00, "Disable") + PORT_DIPSETTING(0x40, "Enable") + PORT_DIPNAME(0x80, 0x80, "2K block $7000") PORT_DIPLOCATION("SW2:8") + PORT_DIPSETTING(0x00, "Disable") + PORT_DIPSETTING(0x80, "Enable") + + PORT_START("DSW3") + PORT_DIPNAME(0x0f, 0x0f, "Address Selection") PORT_DIPLOCATION("SW3:1,2,3,4") + PORT_DIPSETTING(0x0f, "$0000-$7FFF") + PORT_DIPSETTING(0x00, "$1000-$8FFF") + PORT_DIPSETTING(0x04, "$2000-$9FFF") + PORT_DIPSETTING(0x08, "$3000-$AFFF") + PORT_DIPSETTING(0x0c, "$4000-$BFFF") + PORT_DIPSETTING(0x01, "$5000-$CFFF") + PORT_DIPSETTING(0x05, "$6000-$DFFF") + PORT_DIPSETTING(0x09, "$7000-$EFFF") + PORT_DIPSETTING(0x0d, "$8000-$FFFF") + PORT_DIPSETTING(0x02, "$9000-$0FFF") + PORT_DIPSETTING(0x06, "$A000-$1FFF") + PORT_DIPSETTING(0x0a, "$B000-$2FFF") + PORT_DIPSETTING(0x0e, "$C000-$3FFF") + PORT_DIPSETTING(0x03, "$D000-$4FFF") + PORT_DIPSETTING(0x07, "$E000-$5FFF") + PORT_DIPSETTING(0x0b, "$F000-$6FFF") + + PORT_START("LNK1") + PORT_CONFNAME(0x03, 0x00, "Block Enable") + PORT_CONFSETTING(0x00, "RAM (permanent)") + PORT_CONFSETTING(0x01, "RAM (page selectable)") + PORT_CONFSETTING(0x02, "EPROM (page selectable)") +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor tanbus_ra32k_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( ra32k ); +} + +//------------------------------------------------- +// ROM( ra32k ) +//------------------------------------------------- + +ROM_START(ra32k) + ROM_REGION(0x8000, "rom", 0) + ROM_LOAD("data_v1.4.rom", 0x0000, 0x0800, CRC(de61f11d) SHA1(3e6ddc5dba47d9136f58abc9475c3e73fc8cc0c2)) + ROM_LOAD("syntax_v1.4.rom", 0x0800, 0x0800, CRC(17438c4c) SHA1(46bf4e33544c19e142b380095736c5c3eb885ba0)) + ROM_LOAD("ascii_v1.4.rom", 0x1000, 0x0800, CRC(93244a81) SHA1(6149eec9904438a0d23529d2c2428a594d5b1fb9)) + ROM_LOAD("graph_v1.4.rom", 0x1800, 0x0800, CRC(159eb1f6) SHA1(5e49edda4b550506aca70d1f7e7de7a352f0359f)) +ROM_END + +const tiny_rom_entry *tanbus_ra32k_device::device_rom_region() const +{ + return ROM_NAME(ra32k); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// tanbus_ra32k_device - constructor +//------------------------------------------------- + +tanbus_ra32k_device::tanbus_ra32k_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, TANBUS_RA32K, tag, owner, clock) + , device_tanbus_interface(mconfig, *this) + , m_rom(*this, "rom") + , m_dsw(*this, "DSW%u", 1) + , m_link(*this, "LNK1") +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void tanbus_ra32k_device::device_start() +{ + m_ram = std::make_unique(0x8000); + + save_pointer(NAME(m_ram), 0x8000); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void tanbus_ra32k_device::device_reset() +{ +} + +//------------------------------------------------- +// read - card read +//------------------------------------------------- + +uint8_t tanbus_ra32k_device::read(offs_t offset, int inhrom, int inhram, int be) +{ + uint8_t data = 0xff; + + switch (m_link->read() & 0x02) + { + case 0x00: + /* 32K dynamic RAM */ + if (block_enabled(offset, inhrom, inhram, be)) + { + //logerror("ram read %04x\n", offset); + data = m_ram[offset & 0x7fff]; + } + break; + case 0x02: + /* ROM selected */ + if (block_enabled(offset, inhrom, inhram, be)) + { + //logerror("rom read %04x\n", offset); + data = m_rom->base()[(offset - m_addr_start) & 0x7fff]; + } + break; + } + + return data; +} + +//------------------------------------------------- +// write - card write +//------------------------------------------------- + +void tanbus_ra32k_device::write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) +{ + switch (m_link->read() & 0x02) + { + case 0x00: + /* 32K dynamic RAM */ + if (block_enabled(offset, inhrom, inhram, be)) + { + //logerror("ram write %04x %02x\n", offset, data); + m_ram[offset & 0x7fff] = data; + } + break; + case 0x02: + /* ROM selected */ + break; + } +} + +bool tanbus_ra32k_device::block_enabled(offs_t offset, int inhrom, int inhram, int be) +{ + m_addr_start = ((bitswap<4>(m_dsw[2]->read(), 1, 0, 3, 2) << 12) + 0x1000) & 0xffff; + m_addr_end = (m_addr_start + 0x7fff) & 0xffff; + + //uint8_t block_start = (bitswap<4>(m_dsw[2]->read(), 1, 0, 3, 2) + 1) & 0x0f; + uint8_t block = offset >> 12; + //logerror("%04x start %04x current %04x\n", offset, block_start, block); + + if (offset & 0x0800) + { + /* switch SW1 */ + if (!BIT(m_dsw[0]->read(), block)) + return false; + } + else + { + /* switch SW2 */ + if (!BIT(m_dsw[1]->read(), block)) + return false; + } + + /* recognise INHRAM signal */ + if (inhram) + return false; + + /* recognise I/O signal (should be a Tanex output) */ + if ((offset & 0xfc00) == 0xbc00) + return false; + + /* recognise Block Enable */ + if ((m_link->read() & 0x01) && !be) + return false; + + return true; +} diff --git a/src/devices/bus/tanbus/ra32k.h b/src/devices/bus/tanbus/ra32k.h new file mode 100644 index 00000000000..a67e9c859bb --- /dev/null +++ b/src/devices/bus/tanbus/ra32k.h @@ -0,0 +1,59 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Ralph Allen 32K Dynamic RAM Board + +**********************************************************************/ + + +#ifndef MAME_BUS_TANBUS_RA32K_H +#define MAME_BUS_TANBUS_RA32K_H + +#pragma once + +#include "bus/tanbus/tanbus.h" +#include "bus/tanbus/ra32k.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class tanbus_ra32k_device : + public device_t, + public device_tanbus_interface +{ +public: + // construction/destruction + tanbus_ra32k_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual const tiny_rom_entry *device_rom_region() const override; + virtual ioport_constructor device_input_ports() const override; + + virtual uint8_t read(offs_t offset, int inhrom, int inhram, int be) override; + virtual void write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) override; + +private: + required_memory_region m_rom; + required_ioport_array<3> m_dsw; + required_ioport m_link; + + offs_t m_addr_start; + offs_t m_addr_end; + std::unique_ptr m_ram; + + bool block_enabled(offs_t offset, int inhrom, int inhram, int be); +}; + + +// device type definition +DECLARE_DEVICE_TYPE(TANBUS_RA32K, tanbus_ra32k_device) + + +#endif // MAME_BUS_TANBUS_RA32K_H diff --git a/src/devices/bus/tanbus/radisc.cpp b/src/devices/bus/tanbus/radisc.cpp new file mode 100644 index 00000000000..383a8b0d1bb --- /dev/null +++ b/src/devices/bus/tanbus/radisc.cpp @@ -0,0 +1,213 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Ralph Allen Disc Controller Card + + http://www.microtan.ukpc.net/6809/DOS_RTC.pdf + +**********************************************************************/ + + +#include "emu.h" +#include "radisc.h" +#include "speaker.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(TANBUS_RADISC, tanbus_radisc_device, "tanbus_radisc", "Ralph Allen Disc Controller Card") + +//------------------------------------------------- +// MACHINE_DRIVER( radisc ) +//------------------------------------------------- + +static void tandos_floppies(device_slot_interface &device) +{ + device.option_add("525sssd", FLOPPY_525_SSSD); + device.option_add("525sd", FLOPPY_525_SD); + device.option_add("525qd", FLOPPY_525_QD); +} + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void tanbus_radisc_device::device_add_mconfig(machine_config &config) +{ + INPUT_MERGER_ANY_HIGH(config, m_irq_line).output_handler().set(FUNC(tanbus_radisc_device::fdc_irq_w)); + + FD1793(config, m_fdc, 4_MHz_XTAL / 4); + m_fdc->intrq_wr_callback().set(m_irq_line, FUNC(input_merger_device::in_w)); + m_fdc->drq_wr_callback().set(FUNC(tanbus_radisc_device::fdc_drq_w)); + m_fdc->hld_wr_callback().set(FUNC(tanbus_radisc_device::fdc_hld_w)); + m_fdc->set_force_ready(true); + + FLOPPY_CONNECTOR(config, m_floppies[0], tandos_floppies, "525qd", floppy_image_device::default_floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppies[1], tandos_floppies, "525qd", floppy_image_device::default_floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppies[2], tandos_floppies, nullptr, floppy_image_device::default_floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppies[3], tandos_floppies, nullptr, floppy_image_device::default_floppy_formats).enable_sound(true); + + MC146818(config, m_rtc, 32.768_kHz_XTAL); + m_rtc->irq().set(m_irq_line, FUNC(input_merger_device::in_w)); + + VIA6522(config, m_via, 4_MHz_XTAL / 4); + m_via->irq_handler().set(m_irq_line, FUNC(input_merger_device::in_w)); + + /* audio hardware */ + SPEAKER(config, "mono").front_center(); + BEEP(config, m_beeper, 1000); // TODO: unknown frequency + m_beeper->add_route(ALL_OUTPUTS, "mono", 1.0); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// tanbus_radisc_device - constructor +//------------------------------------------------- + +tanbus_radisc_device::tanbus_radisc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, TANBUS_RADISC, tag, owner, clock) + , device_tanbus_interface(mconfig, *this) + , m_fdc(*this, "fdc") + , m_floppies(*this, "fdc:%u", 0) + , m_floppy(nullptr) + , m_rtc(*this, "rtc") + , m_via(*this, "via") + , m_irq_line(*this, "irq_line") + , m_beeper(*this, "beeper") + , m_beeper_state(0) + , m_drive_control(0) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void tanbus_radisc_device::device_start() +{ +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void tanbus_radisc_device::device_reset() +{ +} + +//------------------------------------------------- +// read - card read +//------------------------------------------------- + +uint8_t tanbus_radisc_device::read(offs_t offset, int inhrom, int inhram, int be) +{ + uint8_t data = 0xff; + + switch (offset) + { + case 0xbf80: case 0xbf81: case 0xbf82: case 0xbf83: case 0xbf84: case 0xbf85: case 0xbf86: case 0xbf87: case 0xbf88: case 0xbf89: case 0xbf8a: case 0xbf8b: case 0xbf8c: case 0xbf8d: case 0xbf8e: case 0xbf8f: + data = m_via->read(offset & 0x0f); + break; + case 0xbf90: case 0xbf91: case 0xbf92: case 0xbf93: + data = m_fdc->read(offset & 0x03); + break; + case 0xbf94: + data = control_r(); + break; + case 0xbf98: case 0xbf99: + data = m_rtc->read(offset & 0x01); + break; + } + + return data; +} + +//------------------------------------------------- +// write - card write +//------------------------------------------------- + +void tanbus_radisc_device::write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) +{ + switch (offset) + { + case 0xbf80: case 0xbf81: case 0xbf82: case 0xbf83: case 0xbf84: case 0xbf85: case 0xbf86: case 0xbf87: case 0xbf88: case 0xbf89: case 0xbf8a: case 0xbf8b: case 0xbf8c: case 0xbf8d: case 0xbf8e: case 0xbf8f: + m_via->write(offset & 0x0f, data); + break; + case 0xbf90: case 0xbf91: case 0xbf92: case 0xbf93: + m_fdc->write(offset & 0x03, data); + break; + case 0xbf94: + control_w(data); + break; + case 0xbf95: + m_beeper_state ^= 1; + m_beeper->set_state(m_beeper_state); + break; + case 0xbf98: case 0xbf99: + m_rtc->write(offset & 0x01, data); + break; + } +} + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +void tanbus_radisc_device::control_w(uint8_t val) +{ + logerror("control_w %02x\n", val); + m_drive_control = val; + + // bit 0: irq enable + m_irq_enable = BIT(val, 0); + + // bit 1: data select (data stream controller) + + // bit 2, 3: drive select + m_floppy = m_floppies[(val >> 2) & 0x03]->get_device(); + m_fdc->set_floppy(m_floppy); + + // bit 4: side select + if (m_floppy) + m_floppy->ss_w(BIT(val, 4)); + + // bit 5: density + m_fdc->dden_w(BIT(val, 5)); + + // bit 6: head load + if (m_floppy) + m_floppy->mon_w(BIT(val, 6)); + + // bit 7: drq enable + m_drq_enable = BIT(val, 7); +} + +uint8_t tanbus_radisc_device::control_r() +{ + logerror("control_r %02x\n", m_drive_control); + return m_drive_control; +} + +WRITE_LINE_MEMBER(tanbus_radisc_device::fdc_drq_w) +{ + m_tanbus->so_w((m_drq_enable && state) ? ASSERT_LINE : CLEAR_LINE); +} + +WRITE_LINE_MEMBER(tanbus_radisc_device::fdc_irq_w) +{ + m_tanbus->irq_w((m_irq_enable && state) ? ASSERT_LINE : CLEAR_LINE); +} + +WRITE_LINE_MEMBER(tanbus_radisc_device::fdc_hld_w) +{ + logerror("fdc_hld_w %d\n", state); + if (m_floppy) + m_floppy->mon_w(state); +} diff --git a/src/devices/bus/tanbus/radisc.h b/src/devices/bus/tanbus/radisc.h new file mode 100644 index 00000000000..a4eddf8d0f5 --- /dev/null +++ b/src/devices/bus/tanbus/radisc.h @@ -0,0 +1,76 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Ralph Allen Disc Controller Card + +**********************************************************************/ + + +#ifndef MAME_BUS_TANBUS_RADISC_H +#define MAME_BUS_TANBUS_RADISC_H + +#pragma once + +#include "bus/tanbus/tanbus.h" +#include "imagedev/floppy.h" +#include "machine/wd_fdc.h" +#include "machine/mc146818.h" +#include "machine/6522via.h" +#include "machine/input_merger.h" +#include "sound/beep.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class tanbus_radisc_device : + public device_t, + public device_tanbus_interface +{ +public: + // construction/destruction + tanbus_radisc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_FLOPPY_FORMATS(floppy_formats); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + + virtual uint8_t read(offs_t offset, int inhrom, int inhram, int be) override; + virtual void write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) override; + +private: + enum { IRQ_FDC, IRQ_VIA, IRQ_RTC }; + + void control_w(uint8_t val); + uint8_t control_r(); + DECLARE_WRITE_LINE_MEMBER(fdc_irq_w); + DECLARE_WRITE_LINE_MEMBER(fdc_drq_w); + DECLARE_WRITE_LINE_MEMBER(fdc_hld_w); + + required_device m_fdc; + required_device_array m_floppies; + floppy_image_device *m_floppy; + required_device m_rtc; + required_device m_via; + required_device m_irq_line; + required_device m_beeper; + + int m_beeper_state; + uint8_t m_drive_control; + int m_irq_enable; + int m_drq_enable; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(TANBUS_RADISC, tanbus_radisc_device) + + +#endif // MAME_BUS_TANBUS_RADISC_H diff --git a/src/devices/bus/tanbus/ravdu.cpp b/src/devices/bus/tanbus/ravdu.cpp new file mode 100644 index 00000000000..a68a609c18e --- /dev/null +++ b/src/devices/bus/tanbus/ravdu.cpp @@ -0,0 +1,195 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Ralph Allen Colour VDU Card + + http://www.microtan.ukpc.net/6809/Video.pdf + + TODO: + - use MC6845 screen_update to implement cursor, requires interlace + - verify whether INHRAM and BE lines are used + +**********************************************************************/ + + +#include "emu.h" +#include "ravdu.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(TANBUS_RAVDU, tanbus_ravdu_device, "tanbus_ravdu", "Ralph Allen Colour VDU Card") + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void tanbus_ravdu_device::device_add_mconfig(machine_config &config) +{ + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_refresh_hz(50); + m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); + m_screen->set_size(1536, 624); + m_screen->set_visarea(0, 972 - 1, 0, 500 - 1); + //m_screen->set_screen_update("mc6845", FUNC(mc6845_device::screen_update)); // TODO: implement interlace in mc6845 + m_screen->set_screen_update("saa5055", FUNC(saa5055_device::screen_update)); + + MC6845(config, m_crtc, DERIVED_CLOCK(1, 4)); + m_crtc->set_screen(nullptr); + m_crtc->set_show_border_area(false); + m_crtc->set_char_width(12); + m_crtc->out_vsync_callback().set(FUNC(tanbus_ravdu_device::vsync_changed)); + m_crtc->set_update_row_callback(FUNC(tanbus_ravdu_device::crtc_update_row), this); + + SAA5055(config, m_trom, DERIVED_CLOCK(1, 1)); + m_trom->d_cb().set(FUNC(tanbus_ravdu_device::videoram_r)); + m_trom->set_screen_size(81, 25, 81); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// tanbus_ravdu_device - constructor +//------------------------------------------------- + +tanbus_ravdu_device::tanbus_ravdu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, TANBUS_RAVDU, tag, owner, clock) + , device_tanbus_interface(mconfig, *this) + , m_screen(*this, "screen") + , m_crtc(*this, "mc6845") + , m_trom(*this, "saa5055") +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void tanbus_ravdu_device::device_start() +{ + set_clock(m_tanbus->clock()); + m_videoram = std::make_unique(0x800); + memset(m_videoram.get(), 0xff, sizeof(uint8_t) * 0x800); + + save_pointer(NAME(m_videoram), 0x800); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void tanbus_ravdu_device::device_reset() +{ +} + +//------------------------------------------------- +// read - card read +//------------------------------------------------- + +uint8_t tanbus_ravdu_device::read(offs_t offset, int inhrom, int inhram, int be) +{ + uint8_t data = 0xff; + + if ((offset & 0xf800) == 0xe000) + { + data = m_videoram[offset & 0x7ff]; + } + + switch (offset) + { + case 0xe7fe: + data = m_crtc->status_r(); + break; + case 0xe7ff: + data = m_crtc->register_r(); + break; + } + + return data; +} + +//------------------------------------------------- +// write - card write +//------------------------------------------------- + +void tanbus_ravdu_device::write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) +{ + if ((offset & 0xf800) == 0xe000) + { + m_videoram[offset & 0x7ff] = data; + } + + switch (offset) + { + case 0xe7fe: + m_crtc->address_w(data); + break; + case 0xe7ff: + m_crtc->register_w(data); + break; + } +} + +//------------------------------------------------- +// set_inhibit_lines +//------------------------------------------------- + +void tanbus_ravdu_device::set_inhibit_lines(offs_t offset, int &inhram, int &inhrom) +{ + if ((offset & 0xf800) == 0xe000) + { + inhram = 1; + } +}; + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +READ8_MEMBER(tanbus_ravdu_device::videoram_r) +{ + return m_videoram[offset & 0x7ff]; +} + +MC6845_UPDATE_ROW(tanbus_ravdu_device::crtc_update_row) +{ + uint32_t *p = &bitmap.pix32(y); + + m_trom->lose_w(1); + m_trom->lose_w(0); + + for (int column = 0; column < x_count; column++) + { + m_trom->write(m_videoram[(ma + column) & 0x7ff]); + + m_trom->f1_w(1); + m_trom->f1_w(0); + + for (int bit = 0; bit < 12; bit++) + { + m_trom->tr6_w(1); + m_trom->tr6_w(0); + + int col = m_trom->get_rgb() ^ ((column == cursor_x) ? 7 : 0); + + int r = BIT(col, 0) * 0xff; + int g = BIT(col, 1) * 0xff; + int b = BIT(col, 2) * 0xff; + + *p++ = rgb_t(r, g, b); + } + } +} + +WRITE_LINE_MEMBER(tanbus_ravdu_device::vsync_changed) +{ + m_trom->dew_w(state); +} diff --git a/src/devices/bus/tanbus/ravdu.h b/src/devices/bus/tanbus/ravdu.h new file mode 100644 index 00000000000..4817abb78f4 --- /dev/null +++ b/src/devices/bus/tanbus/ravdu.h @@ -0,0 +1,63 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Ralph Allen Colour VDU Card + +**********************************************************************/ + + +#ifndef MAME_BUS_TANBUS_RAVDU_H +#define MAME_BUS_TANBUS_RAVDU_H + +#pragma once + +#include "bus/tanbus/tanbus.h" +#include "video/saa5050.h" +#include "video/mc6845.h" +#include "screen.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class tanbus_ravdu_device : + public device_t, + public device_tanbus_interface +{ +public: + static constexpr feature_type imperfect_features() { return feature::GRAPHICS; } + + // construction/destruction + tanbus_ravdu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + + virtual uint8_t read(offs_t offset, int inhrom, int inhram, int be) override; + virtual void write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) override; + virtual void set_inhibit_lines(offs_t offset, int &inhram, int &inhrom) override; + +private: + DECLARE_READ8_MEMBER(videoram_r); + MC6845_UPDATE_ROW(crtc_update_row); + DECLARE_WRITE_LINE_MEMBER(vsync_changed); + + required_device m_screen; + required_device m_crtc; + required_device m_trom; + + std::unique_ptr m_videoram; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(TANBUS_RAVDU, tanbus_ravdu_device) + + +#endif // MAME_BUS_TANBUS_RAVDU_H diff --git a/src/devices/bus/tanbus/tanbus.cpp b/src/devices/bus/tanbus/tanbus.cpp new file mode 100644 index 00000000000..c7d36a1a578 --- /dev/null +++ b/src/devices/bus/tanbus/tanbus.cpp @@ -0,0 +1,254 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Microtan Bus emulation + + http://www.microtan.ukpc.net/pageProducts.html#MOTHERBOARDS + +**********************************************************************/ + +#include "emu.h" +#include "tanbus.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(TANBUS_SLOT, tanbus_slot_device, "tanbus_slot", "Microtan Bus slot") + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// tanbus_slot_device - constructor +//------------------------------------------------- +tanbus_slot_device::tanbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, TANBUS_SLOT, tag, owner, clock) + , device_slot_interface(mconfig, *this) + , m_tanbus(*this, DEVICE_SELF_OWNER) +{ +} + +//------------------------------------------------- +// device_validity_check - device-specific checks +//------------------------------------------------- + +void tanbus_slot_device::device_validity_check(validity_checker &valid) const +{ + device_t *const card(get_card_device()); + if (card && !dynamic_cast(card)) + osd_printf_error("tanbus_slot_device: card device %s (%s) does not implement device_tanbus_interface\n", card->tag(), card->name()); +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void tanbus_slot_device::device_start() +{ + device_tanbus_interface *dev = dynamic_cast(get_card_device()); + if (dev) m_tanbus->add_card(dev, m_bus_num); +} + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE(TANBUS, tanbus_device, "tanbus", "Microtan Bus") + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// tanbus_device - constructor +//------------------------------------------------- + +tanbus_device::tanbus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, TANBUS, tag, owner, clock) + , m_out_irq_cb(*this) + , m_out_nmi_cb(*this) + , m_out_so_cb(*this) + , m_out_pgm_cb(*this) +{ +} + +void tanbus_device::add_card(device_tanbus_interface *card, int num) +{ + card->m_tanbus = this; + card->m_page = num; + m_device_list.append(*card); +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void tanbus_device::device_start() +{ + // resolve callbacks + m_out_irq_cb.resolve_safe(); + m_out_nmi_cb.resolve_safe(); + m_out_so_cb.resolve_safe(); + m_out_pgm_cb.resolve_safe(); + + save_item(NAME(m_block_register)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void tanbus_device::device_reset() +{ + m_block_register = 0x00; +} + +//------------------------------------------------- +// fetch - tanbus data read +//------------------------------------------------- + +void tanbus_device::set_inhibit_lines(offs_t offset) +{ + // prevent debugger from changing inhibit lines + if (machine().side_effects_disabled()) return; + + // reset inhibit lines + m_inhram = m_inhrom = 0; + + device_tanbus_interface *card = m_device_list.first(); + + while (card) + { + card->set_inhibit_lines(offset, m_inhram, m_inhrom); + card = card->next(); + } +} + +//------------------------------------------------- +// read - tanbus data read +//------------------------------------------------- + +uint8_t tanbus_device::read(offs_t offset) +{ + uint8_t data = 0xff; + + set_inhibit_lines(offset); + + device_tanbus_interface *card = m_device_list.first(); + + while (card) + { + // set block enable line for current card + if ((card->m_page == 0) || ((m_block_register >> 4) & 7) == card->m_page) + m_block_enable = 1; + else + m_block_enable = 0; + + data &= card->read(offset, m_inhrom, m_inhram, m_block_enable); + card = card->next(); + + } + + return data; +} + +//------------------------------------------------- +// write - tanbus data write +//------------------------------------------------- + +void tanbus_device::write(offs_t offset, uint8_t data) +{ + if (offset == 0xffff) + { + logerror("write: Memory management control (read %d, write %d)\n", (data >> 4) & 7, data & 7); + m_block_register = data; + } + else if (offset >= 0xf800) + { + logerror("write: Unhandled write %02x to %04x\n", data, offset); + } + + set_inhibit_lines(offset); + + device_tanbus_interface *card = m_device_list.first(); + + while (card) + { + // set block enable line for current card + if ((card->m_page == 0) || (m_block_register & 7) == card->m_page) + m_block_enable = 1; + else + m_block_enable = 0; + + card->write(offset, data, m_inhrom, m_inhram, m_block_enable); + card = card->next(); + } +} + +//************************************************************************** +// DEVICE TANBUS INTERFACE +//************************************************************************** + +//------------------------------------------------- +// device_tanbus_interface - constructor +//------------------------------------------------- + +device_tanbus_interface::device_tanbus_interface(const machine_config &mconfig, device_t &device) + : device_slot_card_interface(mconfig, device) + , m_tanbus(nullptr) + , m_page(0) + , m_next(nullptr) +{ +} + + +//------------------------------------------------- +// SLOT_INTERFACE( tanbus_devices ) +//------------------------------------------------- + + +// slot devices +#include "bullsnd.h" +#include "mpvdu.h" +#include "ra32k.h" +#include "radisc.h" +#include "ravdu.h" +#include "tanram.h" +#include "tandos.h" +#include "tanex.h" +#include "tanhrg.h" +#include "tug64k.h" +#include "tug8082.h" +#include "tugpgm.h" + +void tanex_devices(device_slot_interface &device) +{ + device.option_add("tanex", TANBUS_TANEX); +} + +void tanbus_devices(device_slot_interface &device) +{ + device.option_add("bullsnd", TANBUS_BULLSND); + device.option_add("mpvdu", TANBUS_MPVDU); + device.option_add("tanram", TANBUS_TANRAM); + device.option_add("tandos", TANBUS_TANDOS); + device.option_add("tanhrg", TANBUS_TANHRG); + device.option_add("tanhrgc", TANBUS_TANHRGC); + device.option_add("tug64k", TANBUS_TUG64K); + device.option_add("tug8082", TANBUS_TUG8082); + device.option_add("tugpgm", TANBUS_TUGPGM); +} + +void tanbus6809_devices(device_slot_interface &device) +{ + device.option_add("ra32k", TANBUS_RA32K); + device.option_add("radisc", TANBUS_RADISC); + device.option_add("ravdu", TANBUS_RAVDU); + device.option_add("tanram", TANBUS_TANRAM); +} diff --git a/src/devices/bus/tanbus/tanbus.h b/src/devices/bus/tanbus/tanbus.h new file mode 100644 index 00000000000..315f2d1b1d8 --- /dev/null +++ b/src/devices/bus/tanbus/tanbus.h @@ -0,0 +1,150 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Microtan Bus emulation + +**********************************************************************/ + +#ifndef MAME_BUS_TANBUS_TANBUS_H +#define MAME_BUS_TANBUS_TANBUS_H + +#pragma once + + + +//************************************************************************** +// FORWARD DECLARATIONS +//************************************************************************** + +class tanbus_device; +class device_tanbus_interface; + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class tanbus_slot_device : public device_t, public device_slot_interface +{ +public: + // construction/destruction + template + tanbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, int num, T &&opts, const char *dflt) + : tanbus_slot_device(mconfig, tag, owner, DERIVED_CLOCK(1, 1)) + { + option_reset(); + opts(*this); + set_default_option(dflt); + set_fixed(false); + set_tanbus_slot(tag, num); + } + tanbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // inline configuration + void set_tanbus_slot(const char *tag, int num) { m_bus_num = num; } + +protected: + // device-level overrides + virtual void device_validity_check(validity_checker &valid) const override; + virtual void device_start() override; + +private: + required_device m_tanbus; + + int m_bus_num; +}; + +// device type definition +DECLARE_DEVICE_TYPE(TANBUS_SLOT, tanbus_slot_device) + + + +// ======================> tanbus_device + +class tanbus_device : public device_t +{ +public: + // construction/destruction + tanbus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + ~tanbus_device() { m_device_list.detach_all(); } + + // inline configuration + auto out_irq_callback() { return m_out_irq_cb.bind(); } + auto out_nmi_callback() { return m_out_nmi_cb.bind(); } + auto out_so_callback() { return m_out_so_cb.bind(); } + auto out_pgm_callback() { return m_out_pgm_cb.bind(); } + + void add_card(device_tanbus_interface *card, int num); + + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); + + void set_inhibit_lines(offs_t offset); + + DECLARE_WRITE_LINE_MEMBER(irq_w) { m_out_irq_cb(state); } + DECLARE_WRITE_LINE_MEMBER(nmi_w) { m_out_nmi_cb(state); } + DECLARE_WRITE_LINE_MEMBER(so_w) { m_out_so_cb(state); } + + // pgm board has additional cable to fully decode the character generator + void pgm_w(offs_t offset, uint8_t data) { m_out_pgm_cb(offset, data); } + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + +private: + // internal state + devcb_write_line m_out_irq_cb; + devcb_write_line m_out_nmi_cb; + devcb_write_line m_out_so_cb; + devcb_write8 m_out_pgm_cb; + + uint8_t m_block_register; + + int m_inhrom; + int m_inhram; + int m_block_enable; + + simple_list m_device_list; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(TANBUS, tanbus_device) + +// ======================> device_tanbus_interface + +class device_tanbus_interface : public device_slot_card_interface +{ + friend class tanbus_device; + template friend class simple_list; + +public: + device_tanbus_interface *next() const { return m_next; } + + // bus access + virtual uint8_t read(offs_t offset, int inhrom, int inhram, int be) { return 0xff; } + virtual void write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) { } + virtual void set_inhibit_lines(offs_t offset, int &inhram, int &inhrom) { }; + +protected: + device_tanbus_interface(const machine_config &mconfig, device_t &device); + + tanbus_device *m_tanbus; + int m_page; + +private: + device_tanbus_interface *m_next; +}; + + +void tanex_devices(device_slot_interface &device); +void tanbus_devices(device_slot_interface &device); +void tanbus6809_devices(device_slot_interface &device); + + +typedef device_type_iterator tanbus_slot_device_iterator; + +#endif // MAME_BUS_TANBUS_TANBUS_H diff --git a/src/devices/bus/tanbus/tandos.cpp b/src/devices/bus/tanbus/tandos.cpp new file mode 100644 index 00000000000..c4cbdab00ae --- /dev/null +++ b/src/devices/bus/tanbus/tandos.cpp @@ -0,0 +1,254 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Tangerine TANDOS (MT0078) + + http://www.microtan.ukpc.net/pageProducts.html#DOS + +**********************************************************************/ + + +#include "emu.h" +#include "tandos.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(TANBUS_TANDOS, tanbus_tandos_device, "tanbus_tandos", "Tangerine Tandos Board") + +//------------------------------------------------- +// SLOT_INTERFACE( tandos_floppies ) +//------------------------------------------------- + +static void tandos_floppies(device_slot_interface &device) +{ + device.option_add("525sssd", FLOPPY_525_SSSD); + device.option_add("525sd", FLOPPY_525_SD); + device.option_add("525qd", FLOPPY_525_QD); +} + +//------------------------------------------------- +// ROM( tandos ) +//------------------------------------------------- + +ROM_START(tandos) + ROM_REGION(0x1000, "dos_rom", 0) + ROM_DEFAULT_BIOS("step30") + ROM_SYSTEM_BIOS(0, "step30", "30ms Stepping Rate") + ROMX_LOAD("tandos_sr30.f2", 0x0000, 0x1000, CRC(54f55771) SHA1(5a801039fa8c05cd9227e9138469959524516c9e), ROM_BIOS(0)) + ROM_SYSTEM_BIOS(1, "step6", "6ms Stepping Rate") + ROMX_LOAD("tandos_sr6.f2", 0x0000, 0x1000, CRC(10ef90fa) SHA1(b1e42cbf7197e693073d2578561803ea4c8efa8c), ROM_BIOS(1)) +ROM_END + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void tanbus_tandos_device::device_add_mconfig(machine_config &config) +{ + FD1793(config, m_fdc, 8_MHz_XTAL / 8); + m_fdc->intrq_wr_callback().set(FUNC(tanbus_tandos_device::fdc_irq_w)); + m_fdc->drq_wr_callback().set(FUNC(tanbus_tandos_device::fdc_drq_w)); + m_fdc->hld_wr_callback().set(FUNC(tanbus_tandos_device::fdc_hld_w)); + m_fdc->set_force_ready(true); + + FLOPPY_CONNECTOR(config, m_floppies[0], tandos_floppies, "525qd", floppy_image_device::default_floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppies[1], tandos_floppies, "525qd", floppy_image_device::default_floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppies[2], tandos_floppies, nullptr, floppy_image_device::default_floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppies[3], tandos_floppies, nullptr, floppy_image_device::default_floppy_formats).enable_sound(true); +} + +const tiny_rom_entry *tanbus_tandos_device::device_rom_region() const +{ + return ROM_NAME(tandos); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// tanbus_tandos_device - constructor +//------------------------------------------------- + +tanbus_tandos_device::tanbus_tandos_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, TANBUS_TANDOS, tag, owner, clock) + , device_tanbus_interface(mconfig, *this) + , m_dos_rom(*this, "dos_rom") + , m_fdc(*this, "fdc") + , m_floppies(*this, "fdc:%u", 0) + , m_floppy(nullptr) + , m_drive_control(0) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void tanbus_tandos_device::device_start() +{ + m_ram = std::make_unique(0x0400); + + save_pointer(NAME(m_ram), 0x0400); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void tanbus_tandos_device::device_reset() +{ + // reset floppy control register + control_w(0); +} + +//------------------------------------------------- +// read - card read +//------------------------------------------------- + +uint8_t tanbus_tandos_device::read(offs_t offset, int inhrom, int inhram, int be) +{ + uint8_t data = 0xff; + + switch (offset & 0xfc00) + { + case 0xa800: case 0xac00: case 0xb000: case 0xb400: + data = m_dos_rom->base()[offset & 0x0fff]; + break; + + case 0xb800: + data = m_ram[offset & 0x03ff]; + break; + + default: + switch (offset) + { + case 0xbf90: case 0xbf91: case 0xbf92: case 0xbf93: + data = m_fdc->read(offset & 0x03); + break; + case 0xbf94: case 0xbf96: + data = status_r(); + break; + case 0xbf95: case 0xbf97: + // GPIB PCB Switches + break; + case 0xbf98: case 0xbf99: case 0xbf9a: case 0xbf9b: case 0xbf9c: case 0xbf9d: case 0xbf9e: case 0xbf9f: + // GPIB (9914) + break; + } + break; + } + + return data; +} + +//------------------------------------------------- +// write - card write +//------------------------------------------------- + +void tanbus_tandos_device::write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) +{ + switch (offset & 0xfc00) + { + case 0xb800: + m_ram[offset & 0x03ff] = data; + break; + + default: + switch (offset) + { + case 0xbf90: case 0xbf91: case 0xbf92: case 0xbf93: + m_fdc->write(offset & 0x03, data); + break; + case 0xbf94: case 0xbf96: + control_w(data); + break; + case 0xbf98: case 0xbf99: case 0xbf9a: case 0xbf9b: case 0xbf9c: case 0xbf9d: case 0xbf9e: case 0xbf9f: + // GPIB (9914) + break; + } + break; + } +} + +//------------------------------------------------- +// set_inhibit_lines +//------------------------------------------------- + +void tanbus_tandos_device::set_inhibit_lines(offs_t offset, int &inhram, int &inhrom) +{ + if (offset >= 0xa800 && offset < 0xbc00) + { + inhram = 1; + inhrom = 1; + } +}; + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +void tanbus_tandos_device::control_w(uint8_t data) +{ + logerror("control_w %02x\n", data); + m_drive_control = data; + + // bit 0: irq enable + m_irq_enable = BIT(data, 0); + + // bit 1: data select (data stream controller) + + // bit 2, 3: drive select + m_floppy = m_floppies[(data >> 2) & 0x03]->get_device(); + m_fdc->set_floppy(m_floppy); + + // bit 4: side select + if (m_floppy) + m_floppy->ss_w(BIT(data, 4)); + + // bit 5: density + m_fdc->dden_w(BIT(data, 5)); + + // bit 6: head load timing + m_fdc->hlt_w(BIT(data, 6)); + if (m_floppy) + m_floppy->mon_w(!BIT(data, 6)); + + // bit 7: drq enable + m_drq_enable = BIT(data, 7); +} + +uint8_t tanbus_tandos_device::status_r() +{ + uint8_t data = 0x00; + + data |= m_drive_control & 0x3c; + data |= m_fdc->intrq_r() << 0; + data |= m_fdc->hld_r() << 6; + data |= m_fdc->drq_r() << 7; + + return data; +} + + +WRITE_LINE_MEMBER(tanbus_tandos_device::fdc_drq_w) +{ + m_tanbus->so_w((m_drq_enable && state) ? ASSERT_LINE : CLEAR_LINE); +} + +WRITE_LINE_MEMBER(tanbus_tandos_device::fdc_irq_w) +{ + m_tanbus->irq_w((m_irq_enable && state) ? ASSERT_LINE : CLEAR_LINE); +} + +WRITE_LINE_MEMBER(tanbus_tandos_device::fdc_hld_w) +{ + logerror("fdc_hld_w %d\n", state); + if (m_floppy) + m_floppy->mon_w(state); +} diff --git a/src/devices/bus/tanbus/tandos.h b/src/devices/bus/tanbus/tandos.h new file mode 100644 index 00000000000..f47cb585ec7 --- /dev/null +++ b/src/devices/bus/tanbus/tandos.h @@ -0,0 +1,72 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Tangerine TANDOS (MT0078) + +**********************************************************************/ + + +#ifndef MAME_BUS_TANBUS_TANDOS_H +#define MAME_BUS_TANBUS_TANDOS_H + +#pragma once + +#include "bus/tanbus/tanbus.h" +#include "imagedev/floppy.h" +#include "machine/wd_fdc.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class tanbus_tandos_device : + public device_t, + public device_tanbus_interface +{ +public: + static constexpr feature_type imperfect_features() { return feature::DISK; } + + // construction/destruction + tanbus_tandos_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_FLOPPY_FORMATS(floppy_formats); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + + virtual uint8_t read(offs_t offset, int inhrom, int inhram, int be) override; + virtual void write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) override; + virtual void set_inhibit_lines(offs_t offset, int &inhram, int &inhrom) override; + +private: + void control_w(uint8_t val); + uint8_t status_r(); + DECLARE_WRITE_LINE_MEMBER(fdc_irq_w); + DECLARE_WRITE_LINE_MEMBER(fdc_drq_w); + DECLARE_WRITE_LINE_MEMBER(fdc_hld_w); + + required_memory_region m_dos_rom; + required_device m_fdc; + required_device_array m_floppies; + floppy_image_device *m_floppy; + + uint8_t m_drive_control; + int m_irq_enable; + int m_drq_enable; + + std::unique_ptr m_ram; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(TANBUS_TANDOS, tanbus_tandos_device) + + +#endif // MAME_BUS_TANBUS_TANDOS_H diff --git a/src/devices/bus/tanbus/tanex.cpp b/src/devices/bus/tanbus/tanex.cpp new file mode 100644 index 00000000000..1670040da1b --- /dev/null +++ b/src/devices/bus/tanbus/tanex.cpp @@ -0,0 +1,436 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Tangerine TANEX (MT002 Iss2) + + http://www.microtan.ukpc.net/pageProducts.html#TANEX + + This emulates the Tanex board with additional H2 and E2 expansion + boards. The expansion boards are pre-populated with commonly used + language and toolkit ROMs that can be selected in Machine + Configuration. + Alternatively, the expansion boards can be overridden and any + selection of ROMs can be inserted into five ROM sockets + +**********************************************************************/ + + +#include "emu.h" +#include "tanex.h" +#include "speaker.h" + +//#define VERBOSE 1 +#include "logmacro.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(TANBUS_TANEX, tanbus_tanex_device, "tanbus_tanex", "Tangerine Tanex Board") + +//------------------------------------------------- +// INPUT_PORTS( tanex ) +//------------------------------------------------- + +static INPUT_PORTS_START(tanex) + PORT_START("CONFIG") + PORT_CONFNAME(0x0f, 0x00, "H2 Extension Eprom Board") + PORT_CONFSETTING(0x00, "Microsoft BASIC [GE2ED]") + PORT_CONFSETTING(0x01, "Microtanic FORTH [GC000]") + PORT_CONFSETTING(0x02, "2-Pass Assembler [GC000]") + PORT_CONFNAME(0xf0, 0x00, "E2 Extension Eprom Board") + PORT_CONFSETTING(0x00, "Toolkit") + PORT_CONFSETTING(0x10, "HRG Toolkit (TANHRG)") + PORT_CONFSETTING(0x20, "Video 80/82 Toolkit (VID8082)") + PORT_CONFSETTING(0x30, "PGM Toolkit (TUGPGM)") + + PORT_START("JOY") // VIA #1 PORT A + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON1) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_BUTTON2) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_4WAY + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_4WAY + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_4WAY + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_4WAY +INPUT_PORTS_END + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor tanbus_tanex_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(tanex); +} + +//------------------------------------------------- +// ROM( tanex ) +//------------------------------------------------- + +ROM_START(tanex) + ROM_REGION(0x3800, "rom_tanex", 0) + /* tanex - default configuration */ + ROM_LOAD("basl.j2", 0x0000, 0x1000, CRC(3e09d384) SHA1(15a98941a672ff16242cc73f1dcf1d81fccd8910)) + ROM_LOAD("basm.h2", 0x1000, 0x1000, CRC(75105113) SHA1(c6fea4d65b7c52f43aa1589cace9467349a0f290)) + ROM_LOAD("bash.d3", 0x2000, 0x0800, CRC(ee6e8412) SHA1(7e1bca84bab79d94a4ab8554d23e2bc28ccd0384)) + ROM_LOAD("toolkit.e2", 0x2800, 0x0800, CRC(bd87fd34) SHA1(f41895df4a733dddfaf1c89ecff5040addcab804)) + ROM_LOAD("xbug.g2", 0x3000, 0x0800, CRC(4a875dda) SHA1(9f2626e09e7604ae6e8aa55c4f3a8ace3667348b)) + + /* eprom extension board - h2 */ + ROM_REGION(0x5000, "rom_h2", 0) + ROM_LOAD("basl.j2", 0x0000, 0x1000, CRC(3e09d384) SHA1(15a98941a672ff16242cc73f1dcf1d81fccd8910)) + ROM_LOAD("basm.h2", 0x1000, 0x1000, CRC(75105113) SHA1(c6fea4d65b7c52f43aa1589cace9467349a0f290)) + ROM_LOAD("fforth.j2", 0x2000, 0x1000, CRC(18c8e389) SHA1(3201c90d8183e49b8ca683dcc383278b31683297)) + ROM_LOAD("fforth.h2", 0x3000, 0x1000, CRC(b1869543) SHA1(b82900f40de52beb5a4ea12abb8eaaf55665cf01)) + ROM_LOAD("assem12.j2", 0x4000, 0x1000, CRC(5d0cf5ec) SHA1(8832964eb647b5bf3fe954e52218ed27cf885667)) + + /* eprom extension board - e2 */ + ROM_REGION(0x2000, "rom_e2", 0) + ROM_LOAD("toolkit.e2", 0x0000, 0x0800, CRC(bd87fd34) SHA1(f41895df4a733dddfaf1c89ecff5040addcab804)) + ROM_LOAD("hrgtkt.e2", 0x0800, 0x0800, CRC(592c13de) SHA1(544c2a3d58f07dfaa90f022f059129d6b8b659d6)) + ROM_LOAD("vdutkt.e2", 0x1000, 0x0800, CRC(068cbb9e) SHA1(38d99c23966b69440c8498c342a1486741f4d817)) + ROM_LOAD("pgmtkt.e2", 0x1800, 0x0800, CRC(340f6ddd) SHA1(93d205ffb07a339f801b9aa9469e069de321c41c)) +ROM_END + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void tanbus_tanex_device::device_add_mconfig(machine_config &config) +{ + INPUT_MERGER_ANY_HIGH(config, m_irq_line).output_handler().set(FUNC(tanbus_tanex_device::bus_irq_w)); + + /* acia */ + MOS6551(config, m_acia, 0); + m_acia->set_xtal(1.8432_MHz_XTAL); + m_acia->txd_handler().set(m_rs232, FUNC(rs232_port_device::write_txd)); + m_acia->rts_handler().set(m_rs232, FUNC(rs232_port_device::write_rts)); + m_acia->dtr_handler().set(m_rs232, FUNC(rs232_port_device::write_dtr)); + m_acia->irq_handler().set(m_irq_line, FUNC(input_merger_device::in_w)); + + RS232_PORT(config, m_rs232, default_rs232_devices, nullptr); + m_rs232->rxd_handler().set(m_acia, FUNC(mos6551_device::write_rxd)); + m_rs232->dcd_handler().set(m_acia, FUNC(mos6551_device::write_dcd)); + m_rs232->dsr_handler().set(m_acia, FUNC(mos6551_device::write_dsr)); + m_rs232->cts_handler().set(m_acia, FUNC(mos6551_device::write_cts)); + + /* via */ + VIA6522(config, m_via6522[0], DERIVED_CLOCK(1, 8)); + m_via6522[0]->readpa_handler().set(FUNC(tanbus_tanex_device::via_0_in_a)); + m_via6522[0]->writepa_handler().set(FUNC(tanbus_tanex_device::via_0_out_a)); + m_via6522[0]->writepb_handler().set(FUNC(tanbus_tanex_device::via_0_out_b)); + m_via6522[0]->ca2_handler().set(FUNC(tanbus_tanex_device::via_0_out_ca2)); + m_via6522[0]->cb2_handler().set(FUNC(tanbus_tanex_device::via_0_out_cb2)); + m_via6522[0]->irq_handler().set(m_irq_line, FUNC(input_merger_device::in_w)); + + VIA6522(config, m_via6522[1], DERIVED_CLOCK(1, 8)); + m_via6522[1]->writepa_handler().set(FUNC(tanbus_tanex_device::via_1_out_a)); + m_via6522[1]->writepb_handler().set(FUNC(tanbus_tanex_device::via_1_out_b)); + m_via6522[1]->ca2_handler().set(FUNC(tanbus_tanex_device::via_1_out_ca2)); + m_via6522[1]->cb2_handler().set(FUNC(tanbus_tanex_device::via_1_out_cb2)); + m_via6522[1]->irq_handler().set(m_irq_line, FUNC(input_merger_device::in_w)); + + /* sound hardware */ + SPEAKER(config, "speaker").front_center(); + + /* cassette */ + CASSETTE(config, m_cassette); + m_cassette->add_route(ALL_OUTPUTS, "speaker", 0.05); + m_cassette->set_default_state(CASSETTE_STOPPED); + m_cassette->set_interface("mt65_cass"); + TIMER(config, "read_cassette").configure_periodic(FUNC(tanbus_tanex_device::read_cassette), attotime::from_hz(20000)); + + /* 4K sockets */ + GENERIC_SOCKET(config, m_rom[0], generic_linear_slot, "rom_c000", "bin,rom"); + GENERIC_SOCKET(config, m_rom[1], generic_linear_slot, "rom_d000", "bin,rom"); + + /* 2K sockets */ + GENERIC_SOCKET(config, m_rom[2], generic_linear_slot, "rom_e000", "bin,rom"); + GENERIC_SOCKET(config, m_rom[3], generic_linear_slot, "rom_e800", "bin,rom"); + GENERIC_SOCKET(config, m_rom[4], generic_linear_slot, "rom_f000", "bin,rom"); +} + +const tiny_rom_entry *tanbus_tanex_device::device_rom_region() const +{ + return ROM_NAME(tanex); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// tanbus_tanex_device - constructor +//------------------------------------------------- + +tanbus_tanex_device::tanbus_tanex_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, TANBUS_TANEX, tag, owner, clock) + , device_tanbus_interface(mconfig, *this) + , m_rom_tanex(*this, "rom_tanex") + , m_rom_h2(*this, "rom_h2") + , m_rom_e2(*this, "rom_e2") + , m_rom(*this, "rom%u", 0) + , m_cassette(*this, "cassette") + , m_acia(*this, "acia") + , m_rs232(*this, "rs232") + , m_via6522(*this, "via6522%u", 0) + , m_irq_line(*this, "irq_line") + , m_config(*this, "CONFIG") +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void tanbus_tanex_device::device_start() +{ + m_ram = std::make_unique(0x1c00); + + save_pointer(NAME(m_ram), 0x1c00); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void tanbus_tanex_device::device_reset() +{ + m_via6522[0]->write_ca1(1); + m_via6522[0]->write_ca2(1); + + m_via6522[0]->write_pb(0xff); + m_via6522[0]->write_cb1(1); + m_via6522[0]->write_cb2(1); + + m_via6522[1]->write_pa(0xff); + m_via6522[1]->write_ca1(1); + m_via6522[1]->write_ca2(1); + + m_via6522[1]->write_pb(0xff); + m_via6522[1]->write_cb1(1); + m_via6522[1]->write_cb2(1); +} + +//------------------------------------------------- +// read - card read +//------------------------------------------------- + +uint8_t tanbus_tanex_device::read(offs_t offset, int inhrom, int inhram, int be) +{ + uint8_t data = 0xff; + + /* 7K static ram */ + if ((offset >= 0x0400) && (offset < 0x2000)) + { + data = m_ram[offset - 0x0400]; + } + + /* IO */ + switch (offset & 0xfff0) + { + case 0xbfc0: + data = m_via6522[0]->read(offset & 0x0f); + break; + case 0xbfd0: + data = m_acia->read(offset & 0x03); + break; + case 0xbfe0: + data = m_via6522[1]->read(offset & 0x0f); + break; + } + + /* tanex default rom 0xc000-0xf7ff */ + if ((offset >= 0xc000) && (offset < 0xf800)) + { + data = m_rom_tanex->base()[offset & 0x3fff]; + } + + /* H2 extension eprom board 0xc000-0xdfff */ + if ((offset & 0xe000) == 0xc000) + { + if (m_rom[0]->exists() || m_rom[1]->exists()) + { + if ((offset & 0xf000) == 0xc000) + data = m_rom[0]->read_rom(offset & 0x0fff); + else + data = m_rom[1]->read_rom(offset & 0x0fff); + } + else + { + switch (m_config->read() & 0x0f) + { + case 0x00: + data = m_rom_h2->base()[offset & 0x1fff]; + break; + case 0x01: + data = m_rom_h2->base()[(offset & 0x1fff) + 0x2000]; + break; + case 0x02: + data = m_rom_h2->base()[(offset & 0x0fff) + 0x4000]; + break; + } + } + } + + /* D3 0xe000-0e7ff */ + if ((offset & 0xf800) == 0xe000) + { + if (m_rom[2]->exists()) + { + data = m_rom[2]->read_rom(offset & 0x07ff); + } + } + + /* E2 extension eprom board 0xe800-0efff */ + if ((offset & 0xf800) == 0xe800) + { + if (m_rom[3]->exists()) + { + data = m_rom[3]->read_rom(offset & 0x07ff); + } + else + { + switch (m_config->read() & 0xf0) + { + case 0x00: + data = m_rom_e2->base()[offset & 0x07ff]; + break; + case 0x10: + data = m_rom_e2->base()[(offset & 0x07ff) + 0x0800]; + break; + case 0x20: + data = m_rom_e2->base()[(offset & 0x07ff) + 0x1000]; + break; + case 0x30: + data = m_rom_e2->base()[(offset & 0x07ff) + 0x1800]; + break; + } + } + } + + /* G2 0xf000-0f7ff */ + if ((offset & 0xf800) == 0xf000) + { + if (m_rom[4]->exists()) + { + data = m_rom[4]->read_rom(offset & 0x07ff); + } + } + + return data; +} + +//------------------------------------------------- +// write - card write +//------------------------------------------------- + +void tanbus_tanex_device::write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) +{ + /* 7K static ram */ + if ((offset >= 0x0400) && (offset < 0x2000)) + { + m_ram[offset - 0x0400] = data; + } + + /* IO */ + switch (offset & 0xfff0) + { + case 0xbfc0: + m_via6522[0]->write(offset & 0x0f, data); + break; + case 0xbfd0: + m_acia->write(offset & 0x03, data); + break; + case 0xbfe0: + m_via6522[1]->write(offset & 0x0f, data); + break; + } +} + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +TIMER_DEVICE_CALLBACK_MEMBER(tanbus_tanex_device::read_cassette) +{ + double level = m_cassette->input(); + + LOG("read_cassette: %g\n", level); + if (level < -0.07) + m_via6522[0]->write_cb2(0); + else if (level > +0.07) + m_via6522[0]->write_cb2(1); +} + +WRITE_LINE_MEMBER(tanbus_tanex_device::bus_so_w) +{ + m_tanbus->so_w(state); +} + +WRITE_LINE_MEMBER(tanbus_tanex_device::bus_irq_w) +{ + m_tanbus->irq_w(state); +} + +//************************************************************** +// VIA callback functions for VIA #0 +//************************************************************** + +READ8_MEMBER(tanbus_tanex_device::via_0_in_a) +{ + int data = ioport("JOY")->read(); + LOG("via_0_in_a %02X\n", data); + return data; +} + +WRITE8_MEMBER(tanbus_tanex_device::via_0_out_a) +{ + LOG("via_0_out_a %02X\n", data); +} + +WRITE8_MEMBER(tanbus_tanex_device::via_0_out_b) +{ + LOG("via_0_out_b %02X\n", data); + /* bit #5 is the replay cassette drive */ + /* bit #6 is the record cassette drive */ + /* bit #7 is the cassette output signal */ + m_cassette->output(data & 0x80 ? +1.0 : -1.0); +} + +WRITE_LINE_MEMBER(tanbus_tanex_device::via_0_out_ca2) +{ + LOG("via_0_out_ca2 %d\n", state); +} + +WRITE_LINE_MEMBER(tanbus_tanex_device::via_0_out_cb2) +{ + LOG("via_0_out_cb2 %d\n", state); +} + +//************************************************************** +// VIA callback functions for VIA #1 +//************************************************************** + +WRITE8_MEMBER(tanbus_tanex_device::via_1_out_a) +{ + LOG("via_1_out_a %02X\n", data); +} + +WRITE8_MEMBER(tanbus_tanex_device::via_1_out_b) +{ + LOG("via_1_out_b %02X\n", data); +} + +WRITE_LINE_MEMBER(tanbus_tanex_device::via_1_out_ca2) +{ + LOG("via_1_out_ca2 %d\n", state); +} + +WRITE_LINE_MEMBER(tanbus_tanex_device::via_1_out_cb2) +{ + LOG("via_1_out_cb2 %d\n", state); +} diff --git a/src/devices/bus/tanbus/tanex.h b/src/devices/bus/tanbus/tanex.h new file mode 100644 index 00000000000..12f59d567ee --- /dev/null +++ b/src/devices/bus/tanbus/tanex.h @@ -0,0 +1,86 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Tangerine TANEX (MT002 Iss2) + +**********************************************************************/ + + +#ifndef MAME_BUS_TANBUS_TANEX_H +#define MAME_BUS_TANBUS_TANEX_H + +#pragma once + +#include "bus/tanbus/tanbus.h" +#include "bus/generic/slot.h" +#include "bus/generic/carts.h" +#include "bus/rs232/rs232.h" +#include "machine/6522via.h" +#include "machine/mos6551.h" +#include "machine/input_merger.h" +#include "machine/timer.h" +#include "imagedev/cassette.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class tanbus_tanex_device : + public device_t, + public device_tanbus_interface +{ +public: + // construction/destruction + tanbus_tanex_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + virtual ioport_constructor device_input_ports() const override; + + virtual uint8_t read(offs_t offset, int inhrom, int inhram, int be) override; + virtual void write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) override; + +private: + enum { IRQ_VIA_0, IRQ_VIA_1, IRQ_ACIA }; + + DECLARE_WRITE_LINE_MEMBER(bus_irq_w); + DECLARE_WRITE_LINE_MEMBER(bus_so_w); + TIMER_DEVICE_CALLBACK_MEMBER(read_cassette); + DECLARE_READ8_MEMBER(via_0_in_a); + DECLARE_WRITE8_MEMBER(via_0_out_a); + DECLARE_WRITE8_MEMBER(via_0_out_b); + DECLARE_WRITE_LINE_MEMBER(via_0_out_ca2); + DECLARE_WRITE_LINE_MEMBER(via_0_out_cb2); + DECLARE_WRITE8_MEMBER(via_1_out_a); + DECLARE_WRITE8_MEMBER(via_1_out_b); + DECLARE_WRITE_LINE_MEMBER(via_1_out_ca2); + DECLARE_WRITE_LINE_MEMBER(via_1_out_cb2); + + required_memory_region m_rom_tanex; + required_memory_region m_rom_h2; + required_memory_region m_rom_e2; + required_device_array m_rom; + required_device m_cassette; + required_device m_acia; + required_device m_rs232; + required_device_array m_via6522; + required_device m_irq_line; + required_ioport m_config; + + std::unique_ptr m_ram; + emu_timer *m_read_cassette_timer; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(TANBUS_TANEX, tanbus_tanex_device) + + +#endif // MAME_BUS_TANBUS_TANEX_H diff --git a/src/devices/bus/tanbus/tanhrg.cpp b/src/devices/bus/tanbus/tanhrg.cpp new file mode 100644 index 00000000000..1c8ffc87ab5 --- /dev/null +++ b/src/devices/bus/tanbus/tanhrg.cpp @@ -0,0 +1,368 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Tangerine High Resolution Graphics Card (MT0055 Iss2) + + http://www.microtan.ukpc.net/pageProducts.html#VIDEO + + TODO: + - option to merge MT65 chunky and HRG screens + +**********************************************************************/ + + +#include "emu.h" +#include "tanhrg.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(TANBUS_TANHRG, tanbus_tanhrg_device, "tanbus_tanhrg", "Tangerine High Resolution Graphics Card (monochrome)") +DEFINE_DEVICE_TYPE(TANBUS_TANHRGC, tanbus_tanhrgc_device, "tanbus_tanhrgc", "Tangerine High Resolution Graphics Card (colour)") + +//------------------------------------------------- +// INPUT_PORTS( tanhrg ) +//------------------------------------------------- + +INPUT_PORTS_START(tanhrg) + PORT_START("DSW") + PORT_DIPNAME(0x07, 0x04, "Address Space") PORT_DIPLOCATION("DSW:1,2,3") + PORT_DIPSETTING(0x00, "&0000-&1FFF (Invalid - Do Not Use)") + PORT_DIPSETTING(0x01, "&2000-&3FFF") + PORT_DIPSETTING(0x02, "&4000-&5FFF") + PORT_DIPSETTING(0x03, "&6000-&7FFF") + PORT_DIPSETTING(0x04, "&8000-&9FFF") + PORT_DIPSETTING(0x05, "&A000-&BFFF (Invalid - Do Not Use)") + PORT_DIPSETTING(0x06, "&C000-&DFFF") + PORT_DIPSETTING(0x07, "&E000-&FFFF") + PORT_DIPNAME(0x08, 0x00, "Video") PORT_DIPLOCATION("DSW:4") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x08, DEF_STR(On)) + PORT_DIPNAME(0x10, 0x10, "Inhibit RAM (INHRAM)") PORT_DIPLOCATION("DSW:5") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x10, DEF_STR(On)) + PORT_DIPNAME(0x20, 0x20, "Block Enable (BE)") PORT_DIPLOCATION("DSW:6") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x20, DEF_STR(On)) +INPUT_PORTS_END + + +INPUT_PORTS_START(tanhrgc) + PORT_START("DSW_1") + PORT_DIPNAME(0x07, 0x02, "Address Space - Red") PORT_DIPLOCATION("DSW_R:1,2,3") + PORT_DIPSETTING(0x00, "&0000-&1FFF (Invalid - Do Not Use)") + PORT_DIPSETTING(0x01, "&2000-&3FFF") + PORT_DIPSETTING(0x02, "&4000-&5FFF") + PORT_DIPSETTING(0x03, "&6000-&7FFF") + PORT_DIPSETTING(0x04, "&8000-&9FFF") + PORT_DIPSETTING(0x05, "&A000-&BFFF (Invalid - Do Not Use)") + PORT_DIPSETTING(0x06, "&C000-&DFFF") + PORT_DIPSETTING(0x07, "&E000-&FFFF") + PORT_DIPNAME(0x08, 0x00, "Video") PORT_DIPLOCATION("DSW_R:4") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x08, DEF_STR(On)) + PORT_DIPNAME(0x10, 0x10, "Inhibit RAM (INHRAM)") PORT_DIPLOCATION("DSW_R:5") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x10, DEF_STR(On)) + PORT_DIPNAME(0x20, 0x20, "Block Enable (BE)") PORT_DIPLOCATION("DSW_R:6") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x20, DEF_STR(On)) + + PORT_START("DSW_2") + PORT_DIPNAME(0x07, 0x04, "Address Space - Green") PORT_DIPLOCATION("DSW_G:1,2,3") + PORT_DIPSETTING(0x00, "&0000-&1FFF (Invalid - Do Not Use)") + PORT_DIPSETTING(0x01, "&2000-&3FFF") + PORT_DIPSETTING(0x02, "&4000-&5FFF") + PORT_DIPSETTING(0x03, "&6000-&7FFF") + PORT_DIPSETTING(0x04, "&8000-&9FFF") + PORT_DIPSETTING(0x05, "&A000-&BFFF (Invalid - Do Not Use)") + PORT_DIPSETTING(0x06, "&C000-&DFFF") + PORT_DIPSETTING(0x07, "&E000-&FFFF") + PORT_DIPNAME(0x08, 0x00, "Video") PORT_DIPLOCATION("DSW_G:4") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x08, DEF_STR(On)) + PORT_DIPNAME(0x10, 0x10, "Inhibit RAM (INHRAM)") PORT_DIPLOCATION("DSW_G:5") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x10, DEF_STR(On)) + PORT_DIPNAME(0x20, 0x20, "Block Enable (BE)") PORT_DIPLOCATION("DSW_G:6") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x20, DEF_STR(On)) + + PORT_START("DSW_3") + PORT_DIPNAME(0x07, 0x03, "Address Space - Blue") PORT_DIPLOCATION("DSW_B:1,2,3") + PORT_DIPSETTING(0x00, "&0000-&1FFF (Invalid - Do Not Use)") + PORT_DIPSETTING(0x01, "&2000-&3FFF") + PORT_DIPSETTING(0x02, "&4000-&5FFF") + PORT_DIPSETTING(0x03, "&6000-&7FFF") + PORT_DIPSETTING(0x04, "&8000-&9FFF") + PORT_DIPSETTING(0x05, "&A000-&BFFF (Invalid - Do Not Use)") + PORT_DIPSETTING(0x06, "&C000-&DFFF") + PORT_DIPSETTING(0x07, "&E000-&FFFF") + PORT_DIPNAME(0x08, 0x00, "Video") PORT_DIPLOCATION("DSW_B:4") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x08, DEF_STR(On)) + PORT_DIPNAME(0x10, 0x10, "Inhibit RAM (INHRAM)") PORT_DIPLOCATION("DSW_B:5") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x10, DEF_STR(On)) + PORT_DIPNAME(0x20, 0x20, "Block Enable (BE)") PORT_DIPLOCATION("DSW_B:6") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x20, DEF_STR(On)) +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor tanbus_tanhrg_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(tanhrg); +} + + +ioport_constructor tanbus_tanhrgc_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(tanhrgc); +} + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void tanbus_tanhrg_device::device_add_mconfig(machine_config &config) +{ + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_raw(6_MHz_XTAL, 384, 0, 256, 312, 0, 256); + m_screen->set_screen_update(FUNC(tanbus_tanhrg_device::screen_update)); + + PALETTE(config, m_palette, palette_device::MONOCHROME); +} + + +void tanbus_tanhrgc_device::device_add_mconfig(machine_config &config) +{ + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_raw(6_MHz_XTAL, 384, 0, 256, 312, 0, 256); + m_screen->set_screen_update(FUNC(tanbus_tanhrgc_device::screen_update)); + + PALETTE(config, m_palette, palette_device::RGB_3BIT); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// tanbus_tanhrg_device - constructor +//------------------------------------------------- + +tanbus_tanhrg_device::tanbus_tanhrg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, TANBUS_TANHRG, tag, owner, clock) + , device_tanbus_interface(mconfig, *this) + , m_dsw(*this, "DSW") + , m_screen(*this, "screen") + , m_palette(*this, "palette") +{ +} + + +tanbus_tanhrgc_device::tanbus_tanhrgc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, TANBUS_TANHRGC, tag, owner, clock) + , device_tanbus_interface(mconfig, *this) + , m_dsw(*this, "DSW_%u", 1) + , m_screen(*this, "screen") + , m_palette(*this, "palette") +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void tanbus_tanhrg_device::device_start() +{ + m_videoram = std::make_unique(0x2000); + + /* randomize video memory contents */ + for (uint16_t addr = 0; addr < 0x2000; addr++) + m_videoram[addr] = machine().rand() & 0xff; + + save_pointer(NAME(m_videoram), 0x2000); +} + + +void tanbus_tanhrgc_device::device_start() +{ + m_videoram = std::make_unique(0x6000); + + /* randomize video memory contents */ + for (uint16_t addr = 0; addr < 0x6000; addr++) + m_videoram[addr] = machine().rand() & 0xff; + + save_pointer(NAME(m_videoram), 0x6000); +} + + +//------------------------------------------------- +// read - card read +//------------------------------------------------- + +uint8_t tanbus_tanhrg_device::read(offs_t offset, int inhrom, int inhram, int be) +{ + uint8_t data = 0xff; + + offs_t addr = (m_dsw->read() & 7) << 13; + + if ((!BIT(m_dsw->read(), 5) || be) && (offset & 0xe000) == addr) + { + data = m_videoram[offset & 0x1fff]; + } + + return data; +} + + +uint8_t tanbus_tanhrgc_device::read(offs_t offset, int inhrom, int inhram, int be) +{ + uint8_t data = 0xff; + + offs_t addr_r = (m_dsw[0]->read() & 7) << 13; + offs_t addr_g = (m_dsw[1]->read() & 7) << 13; + offs_t addr_b = (m_dsw[2]->read() & 7) << 13; + + if ((!BIT(m_dsw[0]->read(), 5) || be) && (offset & 0xe000) == addr_r) + { + data = m_videoram[0x0000 | (offset & 0x1fff)]; + } + else if ((!BIT(m_dsw[1]->read(), 5) || be) && (offset & 0xe000) == addr_g) + { + data = m_videoram[0x2000 | (offset & 0x1fff)]; + } + else if ((!BIT(m_dsw[2]->read(), 5) || be) && (offset & 0xe000) == addr_b) + { + data = m_videoram[0x4000 | (offset & 0x1fff)]; + } + + return data; +} + + +//------------------------------------------------- +// write - card write +//------------------------------------------------- + +void tanbus_tanhrg_device::write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) +{ + offs_t addr = (m_dsw->read() & 7) << 13; + + if ((!BIT(m_dsw->read(), 5) || be) && (offset & 0xe000) == addr) + { + m_videoram[offset & 0x1fff] = data; + } +} + + +void tanbus_tanhrgc_device::write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) +{ + offs_t addr_r = (m_dsw[0]->read() & 7) << 13; + offs_t addr_g = (m_dsw[1]->read() & 7) << 13; + offs_t addr_b = (m_dsw[2]->read() & 7) << 13; + + if ((!BIT(m_dsw[0]->read(), 5) || be) && (offset & 0xe000) == addr_r) + { + m_videoram[0x0000 | (offset & 0x1fff)] = data; + } + else if ((!BIT(m_dsw[1]->read(), 5) || be) && (offset & 0xe000) == addr_g) + { + m_videoram[0x2000 | (offset & 0x1fff)] = data; + } + else if ((!BIT(m_dsw[2]->read(), 5) || be) && (offset & 0xe000) == addr_b) + { + m_videoram[0x4000 | (offset & 0x1fff)] = data; + } +} + + +//------------------------------------------------- +// set_inhibit_lines +//------------------------------------------------- + +void tanbus_tanhrg_device::set_inhibit_lines(offs_t offset, int &inhram, int &inhrom) +{ + offs_t addr = (m_dsw->read() & 7) << 13; + + if (BIT(m_dsw->read(), 4) && (offset & 0xe000) == addr) + { + inhram = 1; + } +}; + + +void tanbus_tanhrgc_device::set_inhibit_lines(offs_t offset, int &inhram, int &inhrom) +{ + offs_t addr_r = (m_dsw[0]->read() & 7) << 13; + offs_t addr_g = (m_dsw[1]->read() & 7) << 13; + offs_t addr_b = (m_dsw[2]->read() & 7) << 13; + + if ((BIT(m_dsw[0]->read(), 4) && (offset & 0xe000) == addr_r) || (BIT(m_dsw[1]->read(), 4) && (offset & 0xe000) == addr_g) || (BIT(m_dsw[2]->read(), 4) && (offset & 0xe000) == addr_b)) + { + inhram = 1; + } +}; + + +//------------------------------------------------- +// screen_update +//------------------------------------------------- + +uint32_t tanbus_tanhrg_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + uint16_t offset; + uint32_t *p; + + for (int y = 0; y < 256; y++) + { + p = &bitmap.pix32(y); + + for (int x = 0; x < 256; x++) + { + offset = (y * 32) + (x / 8); + + *p++ = m_palette->pen_color(BIT(m_videoram[offset], x & 7)); + } + } + + return 0; +} + + +uint32_t tanbus_tanhrgc_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + uint8_t r, g, b; + uint16_t offset; + uint32_t *p; + + for (int y = 0; y < 256; y++) + { + p = &bitmap.pix32(y); + + for (int x = 0; x < 256; x++) + { + offset = (y * 32) + (x / 8); + + r = m_videoram[0x0000 | offset]; + b = m_videoram[0x2000 | offset]; + g = m_videoram[0x4000 | offset]; + + *p++ = m_palette->pen_color(BIT(b, x & 7) << 2 | BIT(g, x & 7) << 1 | BIT(r, x & 7)); + } + } + + return 0; +} diff --git a/src/devices/bus/tanbus/tanhrg.h b/src/devices/bus/tanbus/tanhrg.h new file mode 100644 index 00000000000..bce2c68bd78 --- /dev/null +++ b/src/devices/bus/tanbus/tanhrg.h @@ -0,0 +1,90 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Tangerine High Resolution Graphics Card (MT0055 Iss2) + +**********************************************************************/ + + +#ifndef MAME_BUS_TANBUS_TANHRG_H +#define MAME_BUS_TANBUS_TANHRG_H + +#pragma once + +#include "bus/tanbus/tanbus.h" +#include "emupal.h" +#include "screen.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class tanbus_tanhrg_device : + public device_t, + public device_tanbus_interface +{ +public: + // construction/destruction + tanbus_tanhrg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual ioport_constructor device_input_ports() const override; + + virtual uint8_t read(offs_t offset, int inhrom, int inhram, int be) override; + virtual void write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) override; + virtual void set_inhibit_lines(offs_t offset, int &inhram, int &inhrom) override; + +private: + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + + required_ioport m_dsw; + required_device m_screen; + required_device m_palette; + + std::unique_ptr m_videoram; +}; + + +class tanbus_tanhrgc_device : + public device_t, + public device_tanbus_interface +{ +public: + // construction/destruction + tanbus_tanhrgc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual ioport_constructor device_input_ports() const override; + + virtual uint8_t read(offs_t offset, int inhrom, int inhram, int be) override; + virtual void write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) override; + virtual void set_inhibit_lines(offs_t offset, int &inhram, int &inhrom) override; + +private: + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + + required_ioport_array<3> m_dsw; + required_device m_screen; + required_device m_palette; + + std::unique_ptr m_videoram; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(TANBUS_TANHRG, tanbus_tanhrg_device) +DECLARE_DEVICE_TYPE(TANBUS_TANHRGC, tanbus_tanhrgc_device) + + +#endif // MAME_BUS_TANBUS_TANHRG_H diff --git a/src/devices/bus/tanbus/tanram.cpp b/src/devices/bus/tanbus/tanram.cpp new file mode 100644 index 00000000000..0e3dadf9d15 --- /dev/null +++ b/src/devices/bus/tanbus/tanram.cpp @@ -0,0 +1,93 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Tangerine TANRAM (MT013 Iss2) + + http://www.microtan.ukpc.net/pageProducts.html#RAM + +**********************************************************************/ + + +#include "emu.h" +#include "tanram.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(TANBUS_TANRAM, tanbus_tanram_device, "tanbus_tanram", "Tangerine Tanram Board") + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// tanbus_tanram_device - constructor +//------------------------------------------------- + +tanbus_tanram_device::tanbus_tanram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, TANBUS_TANRAM, tag, owner, clock) + , device_tanbus_interface(mconfig, *this) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void tanbus_tanram_device::device_start() +{ + m_ram = std::make_unique(0x9c00); + + save_pointer(NAME(m_ram), 0x9c00); +} + +//------------------------------------------------- +// read - card read +//------------------------------------------------- + +uint8_t tanbus_tanram_device::read(offs_t offset, int inhrom, int inhram, int be) +{ + uint8_t data = 0xff; + + if (be && !inhram) + { + /* 32K dynamic ram */ + if ((offset >= 0x2000) && (offset < 0xa000)) + { + data = m_ram[offset - 0x2000]; + } + + /* 7K static ram */ + if ((offset >= 0xa000) && (offset < 0xbc00)) + { + data = m_ram[offset - 0xa000]; + } + } + return data; +} + +//------------------------------------------------- +// write - card write +//------------------------------------------------- + +void tanbus_tanram_device::write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) +{ + if (be && !inhram) + { + /* 32K dynamic ram */ + if ((offset >= 0x2000) && (offset < 0xa000)) + { + m_ram[offset - 0x2000] = data; + } + + /* 7K static ram */ + if ((offset >= 0xa000) && (offset < 0xbc00)) + { + m_ram[offset - 0xa000] = data; + } + } +} diff --git a/src/devices/bus/tanbus/tanram.h b/src/devices/bus/tanbus/tanram.h new file mode 100644 index 00000000000..9cdf7970c77 --- /dev/null +++ b/src/devices/bus/tanbus/tanram.h @@ -0,0 +1,45 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Tangerine TANRAM (MT013 Iss2) + +**********************************************************************/ + + +#ifndef MAME_BUS_TANBUS_TANRAM_H +#define MAME_BUS_TANBUS_TANRAM_H + +#pragma once + +#include "bus/tanbus/tanbus.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class tanbus_tanram_device : + public device_t, + public device_tanbus_interface +{ +public: + // construction/destruction + tanbus_tanram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + + virtual uint8_t read(offs_t offset, int inhrom, int inhram, int be) override; + virtual void write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) override; + +private: + std::unique_ptr m_ram; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(TANBUS_TANRAM, tanbus_tanram_device) + + +#endif // MAME_BUS_TANBUS_TANRAM_H diff --git a/src/devices/bus/tanbus/tug64k.cpp b/src/devices/bus/tanbus/tug64k.cpp new file mode 100644 index 00000000000..3f5d834cd92 --- /dev/null +++ b/src/devices/bus/tanbus/tug64k.cpp @@ -0,0 +1,188 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + TUG 64K Dynamic RAM Board + + http://www.microtan.ukpc.net/pageProducts.html#RAM + +**********************************************************************/ + + +#include "emu.h" +#include "tug64k.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(TANBUS_TUG64K, tanbus_tug64k_device, "tanbus_tug64k", "TUG 64K Dynamic RAM Board") + + +//------------------------------------------------- +// INPUT_PORTS( tug64k ) +//------------------------------------------------- + +INPUT_PORTS_START(tug64k) + PORT_START("SW1") + PORT_DIPNAME(0x01, 0x01, "Overlay Tanex RAM") PORT_DIPLOCATION("SW1:1") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x01, DEF_STR(On)) + PORT_DIPNAME(0x02, 0x02, "Recognise INHRAM Signal") PORT_DIPLOCATION("SW1:2") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x02, DEF_STR(On)) + PORT_DIPNAME(0x04, 0x04, "Recognise I/O Signal") PORT_DIPLOCATION("SW1:3") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x04, DEF_STR(On)) + PORT_DIPNAME(0x08, 0x08, "Recognise Block Enable") PORT_DIPLOCATION("SW1:4") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x08, DEF_STR(On)) + + PORT_START("SW2") + PORT_DIPNAME(0x01, 0x00, "Disable RAM &C000-&C7FF") PORT_DIPLOCATION("SW2:1") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x01, DEF_STR(On)) + PORT_DIPNAME(0x02, 0x00, "Disable RAM &C800-&CFFF") PORT_DIPLOCATION("SW2:2") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x02, DEF_STR(On)) + PORT_DIPNAME(0x04, 0x00, "Disable RAM &D000-&D7FF") PORT_DIPLOCATION("SW2:3") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x04, DEF_STR(On)) + PORT_DIPNAME(0x08, 0x00, "Disable RAM &D800-&DFFF") PORT_DIPLOCATION("SW2:4") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x08, DEF_STR(On)) + PORT_DIPNAME(0x10, 0x00, "Disable RAM &E000-&E7FF") PORT_DIPLOCATION("SW2:5") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x10, DEF_STR(On)) + PORT_DIPNAME(0x20, 0x00, "Disable RAM &E800-&EFFF") PORT_DIPLOCATION("SW2:6") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x20, DEF_STR(On)) + PORT_DIPNAME(0x40, 0x00, "Disable RAM &F000-&F7FF") PORT_DIPLOCATION("SW2:7") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x40, DEF_STR(On)) + PORT_DIPNAME(0x80, 0x00, "Not Used") PORT_DIPLOCATION("SW2:8") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x80, DEF_STR(On)) +INPUT_PORTS_END + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor tanbus_tug64k_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(tug64k); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// tanbus_tug64k_device - constructor +//------------------------------------------------- + +tanbus_tug64k_device::tanbus_tug64k_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, TANBUS_TUG64K, tag, owner, clock) + , device_tanbus_interface(mconfig, *this) + , m_dsw(*this, "SW%u", 1) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void tanbus_tug64k_device::device_start() +{ + m_ram = std::make_unique(0x10000); + + save_pointer(NAME(m_ram), 0x10000); +} + +//------------------------------------------------- +// read - card read +//------------------------------------------------- + +uint8_t tanbus_tug64k_device::read(offs_t offset, int inhrom, int inhram, int be) +{ + uint8_t data = 0xff; + + if (ram_enabled(offset, inhrom, inhram, be)) + { + data = m_ram[offset]; + } + + return data; +} + +//------------------------------------------------- +// write - card write +//------------------------------------------------- + +void tanbus_tug64k_device::write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) +{ + if (ram_enabled(offset, inhrom, inhram, be)) + { + m_ram[offset] = data; + } +} + + +bool tanbus_tug64k_device::ram_enabled(offs_t offset, int inhrom, int inhram, int be) +{ + /* overlay Tanex RAM */ + if (!BIT(m_dsw[0]->read(), 0) && (offset >= 0x0400) && (offset < 0x2000)) + return false; + + /* recognise INHRAM signal */ + if (BIT(m_dsw[0]->read(), 1) && inhram) + return false; + + /* recognise I/O signal (should be a Tanex output) */ + if (BIT(m_dsw[0]->read(), 2) && (offset & 0xfc00) == 0xbc00) + return false; + + /* recognise Block Enable */ + if (BIT(m_dsw[0]->read(), 3) && !be) + return false; + + /* disable RAM locations */ + switch (offset & 0xf800) + { + case 0xc000: + if (BIT(m_dsw[1]->read(), 0)) + return false; + break; + case 0xc800: + if (BIT(m_dsw[1]->read(), 1)) + return false; + break; + case 0xd000: + if (BIT(m_dsw[1]->read(), 2)) + return false; + break; + case 0xd800: + if (BIT(m_dsw[1]->read(), 3)) + return false; + break; + case 0xe000: + if (BIT(m_dsw[1]->read(), 4)) + return false; + break; + case 0xe800: + if (BIT(m_dsw[1]->read(), 5)) + return false; + break; + case 0xf000: + if (BIT(m_dsw[1]->read(), 6)) + return false; + break; + case 0xf800: + return false; + break; + } + + return true; +} diff --git a/src/devices/bus/tanbus/tug64k.h b/src/devices/bus/tanbus/tug64k.h new file mode 100644 index 00000000000..e6163d7a187 --- /dev/null +++ b/src/devices/bus/tanbus/tug64k.h @@ -0,0 +1,51 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + TUG 64K Dynamic RAM Board + +**********************************************************************/ + + +#ifndef MAME_BUS_TANBUS_TUG64K_H +#define MAME_BUS_TANBUS_TUG64K_H + +#pragma once + +#include "bus/tanbus/tanbus.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class tanbus_tug64k_device : + public device_t, + public device_tanbus_interface +{ +public: + // construction/destruction + tanbus_tug64k_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + + // optional information overrides + virtual ioport_constructor device_input_ports() const override; + + virtual uint8_t read(offs_t offset, int inhrom, int inhram, int be) override; + virtual void write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) override; + +private: + required_ioport_array<2> m_dsw; + std::unique_ptr m_ram; + + bool ram_enabled(offs_t offset, int inhrom, int inhram, int be); +}; + + +// device type definition +DECLARE_DEVICE_TYPE(TANBUS_TUG64K, tanbus_tug64k_device) + + +#endif // MAME_BUS_TANBUS_TUG64K_H diff --git a/src/devices/bus/tanbus/tug8082.cpp b/src/devices/bus/tanbus/tug8082.cpp new file mode 100644 index 00000000000..8fb596cb5d6 --- /dev/null +++ b/src/devices/bus/tanbus/tug8082.cpp @@ -0,0 +1,263 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Microtanic Video 80/82 Board + + http://www.microtan.ukpc.net/pageProducts.html#VIDEO + + TODO: + - implement the communication between the 8212's + +**********************************************************************/ + + +#include "emu.h" +#include "tug8082.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(TANBUS_TUG8082, tanbus_tug8082_device, "tanbus_vid8082", "Microtanic Video 80/82 Board") + +//------------------------------------------------- +// ADDRESS_MAP( vid8082_map ) +//------------------------------------------------- + +void tanbus_tug8082_device::vid8082_map(address_map &map) +{ + map(0x0000, 0x07ff).ram(); + map(0x4000, 0x7fff).ram().share(m_videoram); + map(0x8000, 0x8000).w(m_iop[0], FUNC(i8212_device::write)); + map(0x8001, 0x8001).r(m_iop[1], FUNC(i8212_device::read)); + map(0xe000, 0xffff).rom().region("rom", 0); +} + +//------------------------------------------------- +// ROM( tug8082 ) +//------------------------------------------------- + +ROM_START(tug8082) + ROM_REGION(0x2000, "rom", 0) + ROM_LOAD("vdu80.ic28", 0x0000, 0x2000, CRC(e9df89c3) SHA1(1db8b055306067eb62940c0e9e63d97a2fab20f9)) +ROM_END + +//------------------------------------------------- +// INPUT_PORTS( tug8082 ) +//------------------------------------------------- + +INPUT_PORTS_START(tug8082) + PORT_START("DSW0") + PORT_DIPNAME(0x01, 0x01, "VDU Interrupt Request") PORT_DIPLOCATION("DSWA:1") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x01, DEF_STR(On)) + PORT_DIPNAME(0x02, 0x00, "VDU Non Maskable Interrupt") PORT_DIPLOCATION("DSWA:2") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x02, DEF_STR(On)) + PORT_DIPNAME(0x04, 0x00, "Not used") PORT_DIPLOCATION("DSWA:3") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x04, DEF_STR(On)) + PORT_DIPNAME(0x08, 0x00, "Not used") PORT_DIPLOCATION("DSWA:4") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x08, DEF_STR(On)) + PORT_DIPNAME(0xf0, 0x00, "I/O Address") PORT_DIPLOCATION("DSWA:5,6,7,8") + PORT_DIPSETTING(0x60, "$BE60 - $BE61") + PORT_DIPSETTING(0x40, "$BE40 - $BE41") + PORT_DIPSETTING(0x20, "$BE20 - $BE21") + PORT_DIPSETTING(0x00, "$BE00 - $BE01") + + PORT_START("DSW1") + PORT_DIPNAME(0x01, 0x00, "Not used") PORT_DIPLOCATION("DSWB:1") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x01, DEF_STR(On)) + PORT_DIPNAME(0x02, 0x00, "Not used") PORT_DIPLOCATION("DSWB:2") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x02, DEF_STR(On)) + PORT_DIPNAME(0x04, 0x04, "80 Column Mode 16K Ram") PORT_DIPLOCATION("DSWB:3") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x04, DEF_STR(On)) + PORT_DIPNAME(0x08, 0x00, "Not used") PORT_DIPLOCATION("DSWB:4") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x08, DEF_STR(On)) + PORT_DIPNAME(0x10, 0x00, "Not used") PORT_DIPLOCATION("DSWB:5") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x10, DEF_STR(On)) + PORT_DIPNAME(0x20, 0x20, "Write Protect") PORT_DIPLOCATION("DSWB:6") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x20, DEF_STR(On)) + PORT_DIPNAME(0x40, 0x00, "40 Column Mode 8K Ram") PORT_DIPLOCATION("DSWB:7") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x40, DEF_STR(On)) + PORT_DIPNAME(0x80, 0x80, "Video Select Disable") PORT_DIPLOCATION("DSWB:8") + PORT_DIPSETTING(0x00, DEF_STR(Off)) + PORT_DIPSETTING(0x80, DEF_STR(On)) +INPUT_PORTS_END + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor tanbus_tug8082_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(tug8082); +} + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void tanbus_tug8082_device::device_add_mconfig(machine_config &config) +{ + M6502(config, m_maincpu, DERIVED_CLOCK(1, 4)); + m_maincpu->set_addrmap(AS_PROGRAM, &tanbus_tug8082_device::vid8082_map); + + I8212(config, m_iop[0], 0); + //m_iop[0]->md_rd_callback().set(CONSTANT(0)); + m_iop[0]->int_wr_callback().set(FUNC(tanbus_tug8082_device::bus_irq_w)); + //m_iop->do_wr_callback().set(FUNC(tanbus_tug8082_device::write)); + + I8212(config, m_iop[1], 0); + //m_iop[1]->md_rd_callback().set(CONSTANT(0)); + m_iop[1]->int_wr_callback().set(FUNC(tanbus_tug8082_device::vdu_irq_w)); + //m_iop->di_rd_callback().set(FUNC(tanbus_tug8082_device::read)); + + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_refresh_hz(50); + m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); + m_screen->set_size(512, 256); + m_screen->set_visarea(0, 512 - 1, 0, 256 - 1); + m_screen->set_screen_update(FUNC(tanbus_tug8082_device::screen_update)); + + PALETTE(config, "palette", palette_device::MONOCHROME); +} + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const tiny_rom_entry *tanbus_tug8082_device::device_rom_region() const +{ + return ROM_NAME(tug8082); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// tanbus_tug8082_device - constructor +//------------------------------------------------- + +tanbus_tug8082_device::tanbus_tug8082_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, TANBUS_TUG8082, tag, owner, clock) + , device_tanbus_interface(mconfig, *this) + , m_maincpu(*this, "maincpu") + , m_iop(*this, "iop%u", 0) + , m_dips(*this, "DSW%u", 0) + , m_rom(*this, "rom") + , m_screen(*this, "screen") + , m_palette(*this, "palette") + , m_videoram(*this, "videoram") +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void tanbus_tug8082_device::device_start() +{ +} + +//------------------------------------------------- +// read - card read +//------------------------------------------------- + +uint8_t tanbus_tug8082_device::read(offs_t offset, int inhrom, int inhram, int be) +{ + uint8_t data = 0xff; + + offs_t addr = 0xbe00 | (m_dips[0]->read() & 0xf0); + + if (offset == addr) + { + data = m_iop[0]->read(); + } + + return data; +} + +//------------------------------------------------- +// write - card write +//------------------------------------------------- + +void tanbus_tug8082_device::write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) +{ + offs_t addr = 0xbe01 | (m_dips[0]->read() & 0xf0); + + if (offset == addr) + { + m_iop[1]->write(data); + } +} + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +WRITE_LINE_MEMBER(tanbus_tug8082_device::bus_irq_w) +{ + /* Manual says these DIPs are not used but schematic suggests they are */ + //switch (m_dips[0]->read() >> 2) + //{ + //case 0x01: + m_tanbus->irq_w(state); + // break; + //case 0x02: + // m_tanbus->nmi_w(state); + // break; + //} +} + +WRITE_LINE_MEMBER(tanbus_tug8082_device::vdu_irq_w) +{ + switch (m_dips[0]->read() & 0x03) + { + case 0x01: + m_maincpu->set_input_line(M6502_IRQ_LINE, state); + break; + case 0x02: + m_maincpu->set_input_line(M6502_NMI_LINE, state); + break; + case 0x03: + m_maincpu->set_input_line(M6502_IRQ_LINE, state); + m_maincpu->set_input_line(M6502_NMI_LINE, state); + break; + } +} + +uint32_t tanbus_tug8082_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + uint32_t *scanline; + int x, y; + uint8_t pixels; + + const pen_t *pen = m_palette->pens(); + + for (y = 0; y < 256; y++) + { + scanline = &bitmap.pix32(y); + for (x = 0; x < 64; x++) + { + pixels = m_videoram[(y * 64) + x]; + + for (int i = 0; i < 8; ++i) + *scanline++ = pen[BIT(pixels, 7 - i)]; + } + } + + return 0; +} diff --git a/src/devices/bus/tanbus/tug8082.h b/src/devices/bus/tanbus/tug8082.h new file mode 100644 index 00000000000..979e47180e5 --- /dev/null +++ b/src/devices/bus/tanbus/tug8082.h @@ -0,0 +1,70 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Microtanic Video 80/82 Board + +**********************************************************************/ + + +#ifndef MAME_BUS_TANBUS_TUG8082_H +#define MAME_BUS_TANBUS_TUG8082_H + +#pragma once + +#include "bus/tanbus/tanbus.h" +#include "cpu/m6502/m6502.h" +#include "machine/i8212.h" + +#include "emupal.h" +#include "screen.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class tanbus_tug8082_device : + public device_t, + public device_tanbus_interface +{ +public: + static constexpr feature_type imperfect_features() { return feature::GRAPHICS; } + + // construction/destruction + tanbus_tug8082_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + virtual ioport_constructor device_input_ports() const override; + + virtual uint8_t read(offs_t offset, int inhrom, int inhram, int be) override; + virtual void write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) override; + +private: + DECLARE_WRITE_LINE_MEMBER(bus_irq_w); + DECLARE_WRITE_LINE_MEMBER(vdu_irq_w); + + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + + required_device m_maincpu; + required_device_array m_iop; + required_ioport_array<2> m_dips; + required_memory_region m_rom; + required_device m_screen; + required_device m_palette; + required_shared_ptr m_videoram; + + void vid8082_map(address_map &map); +}; + + +// device type definition +DECLARE_DEVICE_TYPE(TANBUS_TUG8082, tanbus_tug8082_device) + + +#endif // MAME_BUS_TANBUS_TUG8082_H diff --git a/src/devices/bus/tanbus/tugpgm.cpp b/src/devices/bus/tanbus/tugpgm.cpp new file mode 100644 index 00000000000..e97b0853f64 --- /dev/null +++ b/src/devices/bus/tanbus/tugpgm.cpp @@ -0,0 +1,113 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + TUG Programmable Graphic Module + + http://www.microtan.ukpc.net/pageProducts.html#VIDEO + +**********************************************************************/ + + +#include "emu.h" +#include "tugpgm.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(TANBUS_TUGPGM, tanbus_tugpgm_device, "tanbus_tugpgm", "TUG Programmable Graphic Module") + + +//------------------------------------------------- +// INPUT_PORTS( tugpgm ) +//------------------------------------------------- + +INPUT_PORTS_START(tugpgm) + PORT_START("LINKS") + PORT_DIPNAME(0x07, 0x04, "Address Select") + PORT_DIPSETTING(0x00, "$0400 - $07FF (Not Recommended)") + PORT_DIPSETTING(0x01, "$2400 - $27FF") + PORT_DIPSETTING(0x02, "$4400 - $47FF") + PORT_DIPSETTING(0x03, "$6400 - $67FF") + PORT_DIPSETTING(0x04, "$8400 - $87FF") + PORT_DIPSETTING(0x05, "$A400 - $A7FF") + PORT_DIPSETTING(0x06, "$C400 - $C7FF") + PORT_DIPSETTING(0x07, "$E400 - $E7FF") +INPUT_PORTS_END + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor tanbus_tugpgm_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(tugpgm); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// tanbus_tugpgm_device - constructor +//------------------------------------------------- + +tanbus_tugpgm_device::tanbus_tugpgm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, TANBUS_TUGPGM, tag, owner, clock) + , device_tanbus_interface(mconfig, *this) + , m_links(*this, "LINKS") +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void tanbus_tugpgm_device::device_start() +{ + m_ram = std::make_unique(0x0400); + + /* randomize video memory contents */ + for (uint16_t addr = 0; addr < 0x0400; addr++) + { + m_ram[addr] = machine().rand() & 0xff; + m_tanbus->pgm_w(addr, m_ram[addr]); + } + + save_pointer(NAME(m_ram), 0x0400); +} + +//------------------------------------------------- +// read - card read +//------------------------------------------------- + +uint8_t tanbus_tugpgm_device::read(offs_t offset, int inhrom, int inhram, int be) +{ + uint8_t data = 0xff; + + if ((offset & 0xfc00) == ((m_links->read() << 13) | 0x0400)) + { + data = m_ram[offset & 0x3ff]; + } + + return data; +} + +//------------------------------------------------- +// write - card write +//------------------------------------------------- + +void tanbus_tugpgm_device::write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) +{ + if ((offset & 0xfc00) == ((m_links->read() << 13) | 0x0400)) + { + m_ram[offset & 0x3ff] = data; + + /* update the chargen on the CPU board */ + m_tanbus->pgm_w(offset & 0x3ff, data); + } +} diff --git a/src/devices/bus/tanbus/tugpgm.h b/src/devices/bus/tanbus/tugpgm.h new file mode 100644 index 00000000000..215f66a397c --- /dev/null +++ b/src/devices/bus/tanbus/tugpgm.h @@ -0,0 +1,52 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + TUG Programmable Graphic Module + +**********************************************************************/ + + +#ifndef MAME_BUS_TANBUS_TUGPGM_H +#define MAME_BUS_TANBUS_TUGPGM_H + +#pragma once + +#include "bus/tanbus/tanbus.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class tanbus_tugpgm_device : + public device_t, + public device_tanbus_interface +{ +public: + static constexpr feature_type imperfect_features() { return feature::GRAPHICS; } + + // construction/destruction + tanbus_tugpgm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + + // optional information overrides + virtual ioport_constructor device_input_ports() const override; + + virtual uint8_t read(offs_t offset, int inhrom, int inhram, int be) override; + virtual void write(offs_t offset, uint8_t data, int inhrom, int inhram, int be) override; + +private: + required_ioport m_links; + + std::unique_ptr m_ram; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(TANBUS_TUGPGM, tanbus_tugpgm_device) + + +#endif // MAME_BUS_TANBUS_TUGPGM_H diff --git a/src/mame/drivers/microtan.cpp b/src/mame/drivers/microtan.cpp index abe2cf58402..3871fb88f8f 100644 --- a/src/mame/drivers/microtan.cpp +++ b/src/mame/drivers/microtan.cpp @@ -1,5 +1,5 @@ // license:GPL-2.0+ -// copyright-holders:Juergen Buchmueller +// copyright-holders:Juergen Buchmueller,Nigel Barnes /****************************************************************************** * Microtan 65 * @@ -51,46 +51,58 @@ * *****************************************************************************/ -/* Core includes */ #include "emu.h" #include "includes/microtan.h" - -/* Components */ -#include "cpu/m6502/m6502.h" -#include "machine/mos6551.h" - - #include "emupal.h" #include "screen.h" -#include "speaker.h" #include "softlist.h" -void microtan_state::main_map(address_map &map) +void microtan_state::mt65_map(address_map &map) +{ + map(0x0000, 0xffff).rw(m_tanbus, FUNC(tanbus_device::read), FUNC(tanbus_device::write)); + map(0x0000, 0x01ff).ram(); + map(0x0200, 0x03ff).ram().w(FUNC(microtan_state::videoram_w)).share(m_videoram); + map(0xbff0, 0xbfff).rw(FUNC(microtan_state::bffx_r), FUNC(microtan_state::bffx_w)); + map(0xf800, 0xffff).rom(); +} + +void microtan_state::spinv_map(address_map &map) { + map.unmap_value_high(); map(0x0000, 0x01ff).ram(); map(0x0200, 0x03ff).ram().w(FUNC(microtan_state::videoram_w)).share(m_videoram); - map(0xbc00, 0xbc00).w(m_ay8910[0], FUNC(ay8910_device::address_w)); - map(0xbc01, 0xbc01).rw(m_ay8910[0], FUNC(ay8910_device::data_r), FUNC(ay8910_device::data_w)); - map(0xbc02, 0xbc02).w(m_ay8910[1], FUNC(ay8910_device::address_w)); - map(0xbc03, 0xbc03).rw(m_ay8910[1], FUNC(ay8910_device::data_r), FUNC(ay8910_device::data_w)); - map(0xbfc0, 0xbfcf).m(m_via6522[0], FUNC(via6522_device::map)); - map(0xbfd0, 0xbfd3).rw("acia", FUNC(mos6551_device::read), FUNC(mos6551_device::write)); - map(0xbfe0, 0xbfef).m(m_via6522[1], FUNC(via6522_device::map)); + map(0xbc04, 0xbc04).rw(FUNC(microtan_state::sound_r), FUNC(microtan_state::sound_w)); map(0xbff0, 0xbfff).rw(FUNC(microtan_state::bffx_r), FUNC(microtan_state::bffx_w)); - map(0xc000, 0xe7ff).rom(); - map(0xf000, 0xffff).rom(); + map(0xe800, 0xefff).rom().mirror(0x1000); +} + +void mt6809_state::mt6809_map(address_map &map) +{ + map(0x0000, 0xffff).rw(m_tanbus, FUNC(tanbus_device::read), FUNC(tanbus_device::write)); + map(0xdc00, 0xdfff).ram(); + map(0xdfd8, 0xdfd8).r(FUNC(mt6809_state::keyboard_r)); + map(0xf800, 0xffff).rom(); +} + + +INPUT_CHANGED_MEMBER(microtan_state::trigger_reset) +{ + m_maincpu->set_input_line(INPUT_LINE_RESET, newval ? ASSERT_LINE : CLEAR_LINE); + + if (newval) + { + machine().schedule_soft_reset(); + } } static INPUT_PORTS_START( microtan ) - PORT_START("DSW") - PORT_DIPNAME( 0x03, 0x00, "Memory size" ) - PORT_DIPSETTING( 0x00, "1K" ) - PORT_DIPSETTING( 0x01, "1K + 7K TANEX" ) - PORT_DIPSETTING( 0x02, "1K + 7K TANEX + 40K TANRAM" ) - PORT_BIT( 0xfc, 0xfc, IPT_UNUSED ) - - PORT_START("ROW0") + PORT_START("CONFIG") + PORT_CONFNAME(0x03, 0x00, "Input") + PORT_CONFSETTING(0x00, "ASCII Keyboard") + PORT_CONFSETTING(0x01, "Hex Keypad") + + PORT_START("KBD0") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("2 \"") PORT_CODE(KEYCODE_2) @@ -100,7 +112,7 @@ static INPUT_PORTS_START( microtan ) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("6 &") PORT_CODE(KEYCODE_6) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("7 '") PORT_CODE(KEYCODE_7) - PORT_START("ROW1") + PORT_START("KBD1") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("8 *") PORT_CODE(KEYCODE_8) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("9 (") PORT_CODE(KEYCODE_9) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("0 )") PORT_CODE(KEYCODE_0) @@ -110,7 +122,7 @@ static INPUT_PORTS_START( microtan ) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("BACK SPACE") PORT_CODE(KEYCODE_BACKSPACE) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) - PORT_START("ROW2") + PORT_START("KBD2") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') @@ -120,7 +132,7 @@ static INPUT_PORTS_START( microtan ) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CHAR('u') PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CHAR('i') - PORT_START("ROW3") + PORT_START("KBD3") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHAR('o') PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHAR('p') PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("[ {") PORT_CODE(KEYCODE_OPENBRACE) @@ -130,7 +142,7 @@ static INPUT_PORTS_START( microtan ) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CAPS LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE - PORT_START("ROW4") + PORT_START("KBD4") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHAR('a') PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CHAR('s') PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHAR('d') @@ -140,7 +152,7 @@ static INPUT_PORTS_START( microtan ) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHAR('j') PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHAR('k') - PORT_START("ROW5") + PORT_START("KBD5") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHAR('l') PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("; :") PORT_CODE(KEYCODE_COLON) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("' \"") PORT_CODE(KEYCODE_QUOTE) @@ -150,7 +162,7 @@ static INPUT_PORTS_START( microtan ) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHAR('x') PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHAR('c') - PORT_START("ROW6") + PORT_START("KBD6") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CHAR('v') PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHAR('b') PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CHAR('n') @@ -160,7 +172,7 @@ static INPUT_PORTS_START( microtan ) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("SHIFT (R)") PORT_CODE(KEYCODE_RSHIFT) - PORT_START("ROW7") + PORT_START("KBD7") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("LINE FEED") PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("- (KP)") PORT_CODE(KEYCODE_MINUS_PAD) @@ -170,7 +182,7 @@ static INPUT_PORTS_START( microtan ) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("0 (KP)") PORT_CODE(KEYCODE_0_PAD) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("1 (KP)") PORT_CODE(KEYCODE_1_PAD) - PORT_START("ROW8") + PORT_START("KBD8") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("2 (KP)") PORT_CODE(KEYCODE_2_PAD) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("3 (KP)") PORT_CODE(KEYCODE_3_PAD) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("4 (KP)") PORT_CODE(KEYCODE_4_PAD) @@ -180,63 +192,92 @@ static INPUT_PORTS_START( microtan ) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("8 (KP)") PORT_CODE(KEYCODE_8_PAD) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("9 (KP)") PORT_CODE(KEYCODE_9_PAD) - PORT_START("JOY") // VIA #1 PORT A - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(1) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(2) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_4WAY - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_4WAY + PORT_START("KPAD0") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("0") PORT_CODE(KEYCODE_0_PAD) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("4") PORT_CODE(KEYCODE_4_PAD) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("8 P") PORT_CODE(KEYCODE_8_PAD) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("C M") PORT_CODE(KEYCODE_LCONTROL) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) + PORT_BIT(0xe0, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("KPAD1") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("1") PORT_CODE(KEYCODE_1_PAD) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("5 O") PORT_CODE(KEYCODE_5_PAD) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("9 ESC") PORT_CODE(KEYCODE_9_PAD) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("D G") PORT_CODE(KEYCODE_LCONTROL) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("LF DEL") PORT_CODE(KEYCODE_DEL_PAD) + PORT_BIT(0xe0, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("KPAD2") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("2") PORT_CODE(KEYCODE_2_PAD) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("6 C") PORT_CODE(KEYCODE_6_PAD) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("A") PORT_CODE(KEYCODE_LEFT) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("E S") PORT_CODE(KEYCODE_LCONTROL) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("CR SP") PORT_CODE(KEYCODE_ENTER_PAD) + PORT_BIT(0xe0, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("KPAD3") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("3 '") PORT_CODE(KEYCODE_3_PAD) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("7 R") PORT_CODE(KEYCODE_7_PAD) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("B L") PORT_CODE(KEYCODE_LEFT) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("F N") PORT_CODE(KEYCODE_LCONTROL) + PORT_BIT(0xf0, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("BRK") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("RESET") PORT_CODE(KEYCODE_F12) PORT_CHAR(UCHAR_MAMEKEY(F12)) PORT_CHANGED_MEMBER(DEVICE_SELF, microtan_state, trigger_reset, 0) INPUT_PORTS_END -static const gfx_layout char_layout = -{ - 8, 16, /* 8 x 16 graphics */ - 128, /* 128 codes */ - 1, /* 1 bit per pixel */ - { 0 }, /* no bitplanes */ - { 0, 1, 2, 3, 4, 5, 6, 7 }, - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, - 8*8, 9*8,10*8,11*8,12*8,13*8,14*8,15*8 }, - 8 * 16 /* code takes 8 times 16 bits */ -}; +static INPUT_PORTS_START( spinveti ) + PORT_START("CONFIG") + PORT_CONFNAME(0x03, 0x02, "Input") + PORT_CONFSETTING(0x02, "ETI Keypad") + PORT_CONFNAME(0x60, 0x20, "Difficulty") + PORT_CONFSETTING(0x00, "Easy") + PORT_CONFSETTING(0x20, "Normal") + PORT_CONFSETTING(0x40, "Hard") + PORT_CONFSETTING(0x60, "Hardest") + + PORT_START("KEYPAD") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Play") PORT_CODE(KEYCODE_P) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Right") PORT_CODE(KEYCODE_RIGHT) + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Left") PORT_CODE(KEYCODE_LEFT) + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Fire") PORT_CODE(KEYCODE_LCONTROL) + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Hold") PORT_CODE(KEYCODE_H) + + PORT_START("BRK") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Reset") PORT_CODE(KEYCODE_R) PORT_CHANGED_MEMBER(DEVICE_SELF, microtan_state, trigger_reset, 0) +INPUT_PORTS_END -static const gfx_layout chunky_layout = +static const gfx_layout char_layout = { 8, 16, /* 8 x 16 graphics */ 256, /* 256 codes */ 1, /* 1 bit per pixel */ { 0 }, /* no bitplanes */ { 0, 1, 2, 3, 4, 5, 6, 7 }, - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, - 8*8, 9*8,10*8,11*8,12*8,13*8,14*8,15*8 }, + { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 }, 8 * 16 /* code takes 8 times 16 bits */ }; static GFXDECODE_START( gfx_microtan ) GFXDECODE_ENTRY( "gfx1", 0, char_layout, 0, 1 ) - GFXDECODE_ENTRY( "gfx2", 0, chunky_layout, 0, 1 ) + GFXDECODE_ENTRY( "gfx2", 0, char_layout, 0, 1 ) GFXDECODE_END -void microtan_state::microtan(machine_config &config) +void microtan_state::mt65(machine_config &config) { - /* basic machine hardware */ - M6502(config, m_maincpu, 6_MHz_XTAL / 8); // 750 kHz - m_maincpu->set_addrmap(AS_PROGRAM, µtan_state::main_map); - m_maincpu->set_vblank_int("screen", FUNC(microtan_state::interrupt)); + /* Microtan 65 CPU board */ + M6502(config, m_maincpu, 6_MHz_XTAL / 8); + m_maincpu->set_addrmap(AS_PROGRAM, µtan_state::mt65_map); + + TIMER(config, "kbd_timer").configure_periodic(FUNC(microtan_state::kbd_scan), attotime::from_hz(45)); - // The 6502 IRQ line is active low and probably driven by open collector outputs (guess). - INPUT_MERGER_ANY_HIGH(config, m_irq_line).output_handler().set_inputline(m_maincpu, 0); + INPUT_MERGER_ANY_HIGH(config, m_irq_line).output_handler().set_inputline(m_maincpu, M6502_IRQ_LINE); /* video hardware - include overscan */ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_refresh_hz(60); - screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */ - screen.set_size(32*8, 16*16); - screen.set_visarea(0*8, 32*8-1, 0*16, 16*16-1); + screen.set_raw(6_MHz_XTAL, 384, 0, 32*8, 312, 0, 16*16); screen.set_screen_update(FUNC(microtan_state::screen_update)); screen.set_palette("palette"); @@ -244,10 +285,23 @@ void microtan_state::microtan(machine_config &config) PALETTE(config, "palette", palette_device::MONOCHROME); - /* sound hardware */ - SPEAKER(config, "speaker").front_center(); - AY8910(config, m_ay8910[0], 1000000).add_route(ALL_OUTPUTS, "speaker", 0.5); - AY8910(config, m_ay8910[1], 1000000).add_route(ALL_OUTPUTS, "speaker", 0.5); + /* Microtan Motherboard */ + TANBUS(config, m_tanbus, 6_MHz_XTAL); + m_tanbus->out_irq_callback().set(m_irq_line, FUNC(input_merger_device::in_w)); + m_tanbus->out_so_callback().set_inputline(m_maincpu, M6502_SET_OVERFLOW); + m_tanbus->out_nmi_callback().set_inputline(m_maincpu, M6502_NMI_LINE); + m_tanbus->out_pgm_callback().set(FUNC(microtan_state::pgm_chargen_w)); + + TANBUS_SLOT(config, "tanbus:tanex", -1, tanex_devices, "tanex"); + TANBUS_SLOT(config, "tanbus:0", 0, tanbus_devices, "tanram"); + TANBUS_SLOT(config, "tanbus:1", 1, tanbus_devices, nullptr); + TANBUS_SLOT(config, "tanbus:2", 2, tanbus_devices, "bullsnd"); + TANBUS_SLOT(config, "tanbus:3", 3, tanbus_devices, nullptr); + TANBUS_SLOT(config, "tanbus:4", 4, tanbus_devices, nullptr); + TANBUS_SLOT(config, "tanbus:5", 5, tanbus_devices, nullptr); + TANBUS_SLOT(config, "tanbus:6", 6, tanbus_devices, nullptr); + TANBUS_SLOT(config, "tanbus:7", 7, tanbus_devices, nullptr); + TANBUS_SLOT(config, "tanbus:exp", 8, tanbus_devices, nullptr); /* snapshot/quickload */ snapshot_image_device &snapshot(SNAPSHOT(config, "snapshot", "dmp,m65")); @@ -255,52 +309,170 @@ void microtan_state::microtan(machine_config &config) snapshot.set_interface("mt65_snap"); QUICKLOAD(config, "quickload", "hex").set_load_callback(FUNC(microtan_state::quickload_cb), this); - /* cassette */ - CASSETTE(config, m_cassette); - m_cassette->add_route(ALL_OUTPUTS, "speaker", 0.05); - TIMER(config, "read_cassette").configure_periodic(FUNC(microtan_state::read_cassette), attotime::from_hz(20000)); // cass read - - /* acia */ - mos6551_device &acia(MOS6551(config, "acia", 0)); - acia.set_xtal(1.8432_MHz_XTAL); - - /* via */ - VIA6522(config, m_via6522[0], 6_MHz_XTAL / 8); - m_via6522[0]->readpa_handler().set(FUNC(microtan_state::via_0_in_a)); - m_via6522[0]->writepa_handler().set(FUNC(microtan_state::via_0_out_a)); - m_via6522[0]->writepb_handler().set(FUNC(microtan_state::via_0_out_b)); - m_via6522[0]->ca2_handler().set(FUNC(microtan_state::via_0_out_ca2)); - m_via6522[0]->cb2_handler().set(FUNC(microtan_state::via_0_out_cb2)); - m_via6522[0]->irq_handler().set(m_irq_line, FUNC(input_merger_device::in_w)); - - VIA6522(config, m_via6522[1], 6_MHz_XTAL / 8); - m_via6522[1]->writepa_handler().set(FUNC(microtan_state::via_1_out_a)); - m_via6522[1]->writepb_handler().set(FUNC(microtan_state::via_1_out_b)); - m_via6522[1]->ca2_handler().set(FUNC(microtan_state::via_1_out_ca2)); - m_via6522[1]->cb2_handler().set(FUNC(microtan_state::via_1_out_cb2)); - m_via6522[1]->irq_handler().set(m_irq_line, FUNC(input_merger_device::in_w)); - /* software lists */ + SOFTWARE_LIST(config, "rom_list").set_original("mt65_rom"); + SOFTWARE_LIST(config, "cass_list").set_original("mt65_cass"); + //SOFTWARE_LIST(config, "flop_list").set_original("mt65_flop").set_filter("6502"); SOFTWARE_LIST(config, "snap_list").set_original("mt65_snap"); } -ROM_START( microtan ) - ROM_REGION( 0x10000, "maincpu", 0 ) - ROM_LOAD( "tanex_j2.rom", 0xc000, 0x1000, CRC(3e09d384) SHA1(15a98941a672ff16242cc73f1dcf1d81fccd8910) ) - ROM_LOAD( "tanex_h2.rom", 0xd000, 0x1000, CRC(75105113) SHA1(c6fea4d65b7c52f43aa1589cace9467349a0f290) ) - ROM_LOAD( "tanex_d3.rom", 0xe000, 0x0800, CRC(ee6e8412) SHA1(7e1bca84bab79d94a4ab8554d23e2bc28ccd0384) ) - ROM_LOAD( "tanex_e2.rom", 0xe800, 0x0800, CRC(bd87fd34) SHA1(f41895df4a733dddfaf1c89ecff5040addcab804) ) - ROM_LOAD( "tanex_g2.rom", 0xf000, 0x0800, CRC(9fd233ee) SHA1(7b0be2d0402229ec80b062f7a0bed793686bcbf9) ) - ROM_LOAD( "tanbug_2.rom", 0xf800, 0x0400, CRC(7e215313) SHA1(c8fb3d33ce2beaf624dc75ec57d34c216b086274) ) - ROM_LOAD( "tanbug.rom", 0xfc00, 0x0400, CRC(c8221d9e) SHA1(c7fe4c174523aaaab30be7a8c9baf2bc08b33968) ) - - ROM_REGION( 0x00800, "gfx1", 0 ) - ROM_LOAD( "charset.rom", 0x0000, 0x0800, CRC(3b3c5360) SHA1(a3a2f74149107f8b8f35b15069c71f3aa843d12f) ) - - ROM_REGION( 0x01000, "gfx2", ROMREGION_ERASEFF ) - // initialized in init_microtan +void microtan_state::micron(machine_config &config) +{ + mt65(config); + + /* Microtan Mini-Motherboard connects MT65 CPU card and TANEX, no extra slots */ + config.device_remove("tanbus:0"); + config.device_remove("tanbus:1"); + config.device_remove("tanbus:2"); + config.device_remove("tanbus:3"); + config.device_remove("tanbus:4"); + config.device_remove("tanbus:5"); + config.device_remove("tanbus:6"); + config.device_remove("tanbus:7"); + config.device_remove("tanbus:exp"); +} + +void microtan_state::spinveti(machine_config &config) +{ + /* basic machine hardware */ + M6502(config, m_maincpu, 6_MHz_XTAL / 8); + m_maincpu->set_addrmap(AS_PROGRAM, µtan_state::spinv_map); + + INPUT_MERGER_ANY_HIGH(config, m_irq_line).output_handler().set_inputline(m_maincpu, M6502_IRQ_LINE); + + /* video hardware - include overscan */ + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_raw(6_MHz_XTAL, 384, 0, 32*8, 312, 0, 16*16); + screen.set_screen_update(FUNC(microtan_state::screen_update)); + screen.set_palette("palette"); + + GFXDECODE(config, m_gfxdecode, "palette", gfx_microtan); + + PALETTE(config, "palette", palette_device::MONOCHROME); + + /* TODO: Sound hardware */ +} + + +static DEVICE_INPUT_DEFAULTS_START(ra32k_def_ram0000) + /* 32K RAM configured 0x0000-0x7fff */ + DEVICE_INPUT_DEFAULTS("SW1", 0xff, 0xff) // all blocks enabled + DEVICE_INPUT_DEFAULTS("SW2", 0xff, 0xff) // all blocks enabled + DEVICE_INPUT_DEFAULTS("SW3", 0x0f, 0x0f) // start address $0000 + DEVICE_INPUT_DEFAULTS("LNK1", 0x03, 0x01) +DEVICE_INPUT_DEFAULTS_END + +static DEVICE_INPUT_DEFAULTS_START(ra32k_def_ram8000) + /* 32K RAM configured 0x8000-0xffff */ + DEVICE_INPUT_DEFAULTS("SW1", 0xff, 0x7f) // disable block $F800 + DEVICE_INPUT_DEFAULTS("SW2", 0xff, 0xff) // all blocks enabled + DEVICE_INPUT_DEFAULTS("SW3", 0x0f, 0x0d) // start address $8000 + DEVICE_INPUT_DEFAULTS("LNK1", 0x03, 0x00) +DEVICE_INPUT_DEFAULTS_END + +static DEVICE_INPUT_DEFAULTS_START(ra32k_def_rom2000) + /* 8K EPROM configured 0x2000-0x3fff */ + DEVICE_INPUT_DEFAULTS("SW1", 0xff, 0xff) // all blocks enabled + DEVICE_INPUT_DEFAULTS("SW2", 0xff, 0xff) // all blocks enabled + DEVICE_INPUT_DEFAULTS("SW3", 0x0f, 0x04) // start address $2000 + DEVICE_INPUT_DEFAULTS("LNK1", 0x03, 0x02) +DEVICE_INPUT_DEFAULTS_END + +void mt6809_state::mt6809(machine_config &config) +{ + /* Ralph Allen 6809 CPU Board */ + MC6809(config, m_maincpu, 6_MHz_XTAL / 4); // TODO: verify divider + m_maincpu->set_addrmap(AS_PROGRAM, &mt6809_state::mt6809_map); + + TIMER(config, "kbd_timer").configure_periodic(FUNC(microtan_state::kbd_scan), attotime::from_hz(45)); + + INPUT_MERGER_ANY_HIGH(config, m_irq_line).output_handler().set_inputline(m_maincpu, M6809_IRQ_LINE); + + /* Microtan Motherboard */ + TANBUS(config, m_tanbus, 6_MHz_XTAL); + m_tanbus->out_irq_callback().set(m_irq_line, FUNC(input_merger_device::in_w)); + m_tanbus->out_nmi_callback().set_inputline(m_maincpu, M6809_FIRQ_LINE); + + TANBUS_SLOT(config, "tanbus:tanex", -1, tanex_devices, nullptr); + TANBUS_SLOT(config, "tanbus:0", 0, tanbus6809_devices, "ra32k").set_option_device_input_defaults("ra32k", DEVICE_INPUT_DEFAULTS_NAME(ra32k_def_ram0000)); + TANBUS_SLOT(config, "tanbus:1", 1, tanbus6809_devices, "ra32k").set_option_device_input_defaults("ra32k", DEVICE_INPUT_DEFAULTS_NAME(ra32k_def_ram8000)); + TANBUS_SLOT(config, "tanbus:2", 2, tanbus6809_devices, "ravdu"); + TANBUS_SLOT(config, "tanbus:3", 3, tanbus6809_devices, "radisc"); + TANBUS_SLOT(config, "tanbus:4", 4, tanbus6809_devices, nullptr); + TANBUS_SLOT(config, "tanbus:5", 5, tanbus6809_devices, nullptr); + TANBUS_SLOT(config, "tanbus:6", 6, tanbus6809_devices, nullptr); + TANBUS_SLOT(config, "tanbus:7", 7, tanbus6809_devices, "ra32k").set_option_device_input_defaults("ra32k", DEVICE_INPUT_DEFAULTS_NAME(ra32k_def_rom2000)); + TANBUS_SLOT(config, "tanbus:exp", 8, tanbus6809_devices, nullptr); + + /* software lists */ + //SOFTWARE_LIST(config, "flop_list").set_original("mt65_flop").set_filter("6809"); +} + + +ROM_START( mt65 ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_DEFAULT_BIOS("tanbug23") + /* Microtan 65 (MT0016 Iss 1) */ + ROM_SYSTEM_BIOS(0, "tanbug23", "TANBUG V2.3") + ROMX_LOAD("tanbug23.k3", 0xf800, 0x0800, CRC(7f29845d) SHA1(de277e942eefa11a9a6defe3d7d03071d5100b68), ROM_BIOS(0)) + ROM_SYSTEM_BIOS(1, "tanbug23p", "TANBUG V2.3 (patched)") + ROMX_LOAD("tanbug_2.rom", 0xf800, 0x0400, CRC(7e215313) SHA1(c8fb3d33ce2beaf624dc75ec57d34c216b086274), ROM_BIOS(1)) + ROMX_LOAD("tanbug.rom", 0xfc00, 0x0400, CRC(c8221d9e) SHA1(c7fe4c174523aaaab30be7a8c9baf2bc08b33968), ROM_BIOS(1)) + ROM_SYSTEM_BIOS(2, "tanbug31", "TANBUG V3.1 (TANDOS)") + ROMX_LOAD("tanbug31.k3", 0xf800, 0x0800, CRC(5943e427) SHA1(55fe645363cd5f2015a537be6f7a00de33d1bea5), ROM_BIOS(2)) + ROM_SYSTEM_BIOS(3, "tanbug3b", "TANBUG V.3B (MPVDU)") + ROMX_LOAD("tanbug3b.k3", 0xf800, 0x0800, CRC(5b49f861) SHA1(b37cddf97b6324ab0647479b5b013a9b3d47ddda), ROM_BIOS(3)) + ROM_SYSTEM_BIOS(4, "tugbug11", "TUGBUG V1.1 (VID8082)") + ROMX_LOAD("tugbug11.k3", 0xf800, 0x0800, CRC(23b02439) SHA1(9e56fbd6c07b1dc5c10e7b574a5ea26405781a3d), ROM_BIOS(4)) + + ROM_REGION(0x1000, "gfx1", 0) + ROM_LOAD("charset.rom", 0x0000, 0x0800, CRC(3b3c5360) SHA1(a3a2f74149107f8b8f35b15069c71f3aa843d12f)) + ROM_RELOAD(0x0800, 0x0800) + + ROM_REGION(0x1000, "gfx2", ROMREGION_ERASEFF) + // initialized in init_gfx2 +ROM_END + +ROM_START( micron ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_DEFAULT_BIOS("tanbug1") + /* MT65 (Iss 0) */ + ROM_SYSTEM_BIOS(0, "tanbug1", "TANBUG V1") + ROMX_LOAD("tanbug1.g2", 0xf800, 0x0400, CRC(6f45aaca) SHA1(c1a020d86830ee475ee75c847e98f7a02d467659), ROM_BIOS(0) | ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO) + ROM_RELOAD(0xfc00, 0x0400) + ROMX_LOAD("tanbug1.h2", 0xf800, 0x0400, CRC(1ccd6b8f) SHA1(49784749599255458ba5513d8c2fc58c4df39515), ROM_BIOS(0) | ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI) + ROM_RELOAD(0xfc00, 0x0400) + + ROM_REGION(0x1000, "gfx1", 0) + ROM_LOAD("charset.rom", 0x0000, 0x0800, CRC(3b3c5360) SHA1(a3a2f74149107f8b8f35b15069c71f3aa843d12f)) + ROM_RELOAD(0x0800, 0x0800) + + ROM_REGION(0x1000, "gfx2", ROMREGION_ERASEFF) + // initialized in init_gfx2 +ROM_END + +ROM_START( spinveti ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_LOAD("spaceinv.ic20", 0xe800, 0x0800, CRC(3e235077) SHA1(ae7d2788125d01a3c5d57ab0d992bd708abd6ade)) + + ROM_REGION(0x1000, "gfx1", 0) + ROM_LOAD("charset.rom", 0x0000, 0x0800, CRC(3b3c5360) SHA1(a3a2f74149107f8b8f35b15069c71f3aa843d12f)) + ROM_RELOAD(0x0800, 0x0800) + + ROM_REGION(0x1000, "gfx2", ROMREGION_ERASEFF) + // initialized in init_gfx2 +ROM_END + +ROM_START( mt6809 ) + /* 6809 CPU Card (Ralph Allen Engineering) */ + ROM_REGION(0x10000, "maincpu", 0) + ROM_SYSTEM_BIOS(0, "ralbug14", "RALBUG V1.4") + ROMX_LOAD("ralbug14.rom", 0xf800, 0x0800, CRC(8bbc87d8) SHA1(3d53a6ffd4a8d7c8edf4f2e23946011ed29146ce), ROM_BIOS(0)) ROM_END -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1979, microtan, 0, 0, microtan, microtan, microtan_state, init_microtan, "Tangerine", "Microtan 65" , 0 ) +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1979, mt65, 0, 0, mt65, microtan, microtan_state, init_microtan, "Tangerine", "Microtan 65", MACHINE_NO_SOUND_HW ) +COMP( 1980, micron, mt65, 0, micron, microtan, microtan_state, init_microtan, "Tangerine", "Micron", MACHINE_NO_SOUND_HW ) +COMP( 1980, spinveti, mt65, 0, spinveti, spinveti, microtan_state, init_gfx2, "Tangerine/ETI", "Space Invasion (ETI)", MACHINE_NO_SOUND ) +COMP( 1984, mt6809, mt65, 0, mt6809, microtan, mt6809_state, empty_init, "Tangerine", "Microtan 6809 System", MACHINE_NO_SOUND_HW | MACHINE_NOT_WORKING ) diff --git a/src/mame/includes/microtan.h b/src/mame/includes/microtan.h index 83cab523b76..133278b8a42 100644 --- a/src/mame/includes/microtan.h +++ b/src/mame/includes/microtan.h @@ -19,62 +19,60 @@ #pragma once -#include "imagedev/snapquik.h" -#include "machine/6522via.h" -#include "machine/timer.h" +#include "cpu/m6502/m6502.h" +#include "cpu/m6809/m6809.h" #include "machine/input_merger.h" -#include "sound/ay8910.h" -#include "imagedev/cassette.h" +#include "machine/timer.h" +#include "bus/tanbus/tanbus.h" +#include "imagedev/snapquik.h" class microtan_state : public driver_device { public: microtan_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) - , m_videoram(*this, "videoram") , m_maincpu(*this, "maincpu") , m_irq_line(*this, "irq_line") - , m_cassette(*this, "cassette") - , m_via6522(*this, "via6522%u", 0) - , m_ay8910(*this, "ay8910%u", 0) - , m_io_keyboard(*this, "ROW%u", 0) + , m_config(*this, "CONFIG") + , m_io_keyboard(*this, "KBD%u", 0) + , m_io_keypad(*this, "KPAD%u", 0) + , m_keypad(*this, "KEYPAD") + , m_tanbus(*this, "tanbus") + , m_videoram(*this, "videoram") , m_gfxdecode(*this, "gfxdecode") + , m_gfx1(*this, "gfx1") , m_led(*this, "led1") { } - void microtan(machine_config &config); + void mt65(machine_config &config); + void micron(machine_config &config); + void spinveti(machine_config &config); + void init_gfx2(); void init_microtan(); + TIMER_DEVICE_CALLBACK_MEMBER(kbd_scan); + DECLARE_READ8_MEMBER(bffx_r); + DECLARE_WRITE8_MEMBER(bffx_w); + DECLARE_INPUT_CHANGED_MEMBER(trigger_reset); + protected: - enum - { - TIMER_PULSE_NMI - }; + enum { IRQ_KBD, IRQ_TANBUS }; virtual void machine_start() override; virtual void machine_reset() override; virtual void video_start() override; - virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; -private: - enum { IRQ_VIA_0, IRQ_VIA_1, IRQ_KBD }; - - required_shared_ptr m_videoram; required_device m_maincpu; required_device m_irq_line; - required_device m_cassette; - required_device_array m_via6522; - required_device_array m_ay8910; - required_ioport_array<9> m_io_keyboard; - required_device m_gfxdecode; - output_finder<> m_led; + required_ioport m_config; + optional_ioport_array<9> m_io_keyboard; + optional_ioport_array<4> m_io_keypad; + optional_ioport m_keypad; + optional_device m_tanbus; - uint8_t m_chunky_graphics; - std::unique_ptr m_chunky_buffer; uint8_t m_keypad_column; uint8_t m_keyboard_ascii; - emu_timer *m_read_cassette_timer; emu_timer *m_pulse_nmi_timer; uint8_t m_keyrows[10]; int m_lastrow; @@ -82,28 +80,27 @@ private: int m_key; int m_repeat; int m_repeater; + + virtual void store_key(int key); + +private: + optional_shared_ptr m_videoram; + optional_device m_gfxdecode; + optional_memory_region m_gfx1; + output_finder<> m_led; + + uint8_t m_chunky_graphics; + std::unique_ptr m_chunky_buffer; tilemap_t *m_bg_tilemap; DECLARE_READ8_MEMBER(sound_r); DECLARE_WRITE8_MEMBER(sound_w); - DECLARE_READ8_MEMBER(bffx_r); - DECLARE_WRITE8_MEMBER(bffx_w); DECLARE_WRITE8_MEMBER(videoram_w); TILE_GET_INFO_MEMBER(get_bg_tile_info); + DECLARE_WRITE8_MEMBER(pgm_chargen_w); uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - INTERRUPT_GEN_MEMBER(interrupt); - TIMER_DEVICE_CALLBACK_MEMBER(read_cassette); TIMER_CALLBACK_MEMBER(pulse_nmi); - DECLARE_READ8_MEMBER(via_0_in_a); - DECLARE_WRITE8_MEMBER(via_0_out_a); - DECLARE_WRITE8_MEMBER(via_0_out_b); - DECLARE_WRITE_LINE_MEMBER(via_0_out_ca2); - DECLARE_WRITE_LINE_MEMBER(via_0_out_cb2); - DECLARE_WRITE8_MEMBER(via_1_out_a); - DECLARE_WRITE8_MEMBER(via_1_out_b); - DECLARE_WRITE_LINE_MEMBER(via_1_out_ca2); - DECLARE_WRITE_LINE_MEMBER(via_1_out_cb2); - void store_key(int key); + image_verify_result verify_snapshot(uint8_t *data, int size); image_init_result parse_intel_hex(uint8_t *snapshot_buff, char *src); image_init_result parse_zillion_hex(uint8_t *snapshot_buff, char *src); @@ -112,7 +109,27 @@ private: DECLARE_SNAPSHOT_LOAD_MEMBER(snapshot_cb); DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb); - void main_map(address_map &map); + void mt65_map(address_map &map); + void spinv_map(address_map &map); +}; + + +class mt6809_state : public microtan_state +{ +public: + using microtan_state::microtan_state; + + void mt6809(machine_config &config); + +protected: + virtual void video_start() override; + + virtual void store_key(int key) override; + +private: + DECLARE_READ8_MEMBER(keyboard_r); + + void mt6809_map(address_map &map); }; #endif // MAME_INCLUDES_MICROTAN_H diff --git a/src/mame/machine/microtan.cpp b/src/mame/machine/microtan.cpp index 4b17f844d87..72e610cb6fa 100644 --- a/src/mame/machine/microtan.cpp +++ b/src/mame/machine/microtan.cpp @@ -14,16 +14,9 @@ * *****************************************************************************/ -/* Core includes */ #include "emu.h" #include "includes/microtan.h" -/* Components */ -#include "cpu/m6502/m6502.h" -#include "machine/mos6551.h" - -//#include "imagedev/snapquik.h" - //#define VERBOSE 1 #include "logmacro.h" @@ -120,86 +113,6 @@ static const char keyboard[8][9][8] = { }; -/************************************************************** - * VIA callback functions for VIA #0 - **************************************************************/ -READ8_MEMBER(microtan_state::via_0_in_a) -{ - int data = ioport("JOY")->read(); - LOG("via_0_in_a %02X\n", data); - return data; -} - -WRITE8_MEMBER(microtan_state::via_0_out_a) -{ - LOG("via_0_out_a %02X\n", data); -} - -WRITE8_MEMBER(microtan_state::via_0_out_b) -{ - LOG("via_0_out_b %02X\n", data); - /* bit #7 is the cassette output signal */ - m_cassette->output(data & 0x80 ? +1.0 : -1.0); -} - -WRITE_LINE_MEMBER(microtan_state::via_0_out_ca2) -{ - LOG("via_0_out_ca2 %d\n", state); -} - -WRITE_LINE_MEMBER(microtan_state::via_0_out_cb2) -{ - LOG("via_0_out_cb2 %d\n", state); -} - -/************************************************************** - * VIA callback functions for VIA #1 - **************************************************************/ - -WRITE8_MEMBER(microtan_state::via_1_out_a) -{ - LOG("via_1_out_a %02X\n", data); -} - -WRITE8_MEMBER(microtan_state::via_1_out_b) -{ - LOG("via_1_out_b %02X\n", data); -} - -WRITE_LINE_MEMBER(microtan_state::via_1_out_ca2) -{ - LOG("via_1_out_ca2 %d\n", state); -} - -WRITE_LINE_MEMBER(microtan_state::via_1_out_cb2) -{ - LOG("via_1_out_cb2 %d\n", state); -} - -void microtan_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) -{ - switch (id) - { - case TIMER_PULSE_NMI: - pulse_nmi(ptr, param); - break; - default: - assert_always(false, "Unknown id in microtan_state::device_timer"); - } -} - - -TIMER_DEVICE_CALLBACK_MEMBER(microtan_state::read_cassette) -{ - double level = m_cassette->input(); - - LOG("read_cassette: %g\n", level); - if (level < -0.07) - m_via6522[0]->write_cb2(0); - else if (level > +0.07) - m_via6522[0]->write_cb2(1); -} - READ8_MEMBER(microtan_state::sound_r) { int data = 0xff; @@ -228,9 +141,26 @@ READ8_MEMBER(microtan_state::bffx_r) case 2: /* BFF2: read undefined (?) */ LOG("bff2_r: -> %02x\n", data); break; - default: /* BFF3: read keyboard ASCII value */ - data = m_keyboard_ascii; + case 3: /* BFF3: read keyboard/keypad */ + switch (m_config->read() & 3) + { + case 0: /* ASCII Keyboard */ + data = m_keyboard_ascii; + break; + case 1: /* Hex Keypad */ + data = 0x00; + for (int i = 0; i < 4; i++) + { + if (m_keypad_column & (1 << i)) + data |= m_io_keypad[i]->read(); + } + break; + case 2: /* ETI Keypad */ + data = (m_keypad->read() & 0x1f) | (m_config->read() & 0x60); + break; + } LOG("bff3_r: -> %02x (keyboard ASCII)\n", data); + break; } return data; } @@ -256,25 +186,43 @@ WRITE8_MEMBER(microtan_state::bffx_w) LOG("bff1_w: %d <- %02x (delayed NMI)\n", offset, data); m_pulse_nmi_timer->adjust(m_maincpu->cycles_to_attotime(8)); break; - case 2: /* BFF2: write keypad column write (what is this meant for?) */ - LOG("bff2_w: %d <- %02x (keypad column)\n", offset, data); - m_keypad_column = data; + case 2: /* BFF2: write keypad */ + LOG("bff2_w: %d <- %02x (keypad column)\n", offset, data); // 1, 2, 4, 7, f + m_keypad_column = data & 0x0f; break; - default: /* BFF3: write disable chunky graphics */ + case 3: /* BFF3: write disable chunky graphics */ LOG("bff3_w: %d <- %02x (chunky graphics off)\n", offset, data); m_chunky_graphics = 0; + break; + } +} + +READ8_MEMBER(mt6809_state::keyboard_r) +{ + uint8_t data = m_keyboard_ascii; + + m_keyboard_ascii = 0x00; + + return data; } + +void mt6809_state::store_key(int key) +{ + m_keyboard_ascii = key | 0x80; } void microtan_state::store_key(int key) { - LOG("microtan: store key '%c'\n", key); m_keyboard_ascii = key | 0x80; m_irq_line->in_w(1); } -INTERRUPT_GEN_MEMBER(microtan_state::interrupt) +TIMER_DEVICE_CALLBACK_MEMBER(microtan_state::kbd_scan) { + /* ASCII Keyboard only */ + if ((m_config->read() & 3) != 0) + return; + int mod, row, col, chg, newvar; if( m_repeat ) @@ -360,7 +308,25 @@ INTERRUPT_GEN_MEMBER(microtan_state::interrupt) } } -void microtan_state::init_microtan() + +WRITE8_MEMBER(microtan_state::pgm_chargen_w) +{ + switch (offset & 0x200) + { + case 0x000: + /* update char &80-&1F */ + m_gfx1->base()[offset | 0x800] = data; + m_gfxdecode->gfx(0)->mark_dirty(0x80 | (offset >> 4)); + break; + case 0x200: + /* update char &E0-&FF */ + m_gfx1->base()[offset | 0xc00] = data; + m_gfxdecode->gfx(0)->mark_dirty(0xc0 | (offset >> 4)); + break; + } +} + +void microtan_state::init_gfx2() { uint8_t *dst = memregion("gfx2")->base(); @@ -399,24 +365,13 @@ void microtan_state::init_microtan() } dst += 4; } +} +void microtan_state::init_microtan() +{ + init_gfx2(); - m_pulse_nmi_timer = timer_alloc(TIMER_PULSE_NMI); - - m_via6522[0]->write_ca1(1); - m_via6522[0]->write_ca2(1); - - m_via6522[0]->write_pb(0xff); - m_via6522[0]->write_cb1(1); - m_via6522[0]->write_cb2(1); - - m_via6522[1]->write_pa(0xff); - m_via6522[1]->write_ca1(1); - m_via6522[1]->write_ca2(1); - - m_via6522[1]->write_pb(0xff); - m_via6522[1]->write_cb1(1); - m_via6522[1]->write_cb2(1); + m_pulse_nmi_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(microtan_state::pulse_nmi), this)); } void microtan_state::machine_start() @@ -435,24 +390,10 @@ void microtan_state::machine_start() void microtan_state::machine_reset() { - address_space &space = m_maincpu->space(AS_PROGRAM); - switch (ioport("DSW")->read() & 3) + for (int i = 1; i < 10; i++) { - case 0: // 1K only :) - space.nop_readwrite(0x0400, 0xbbff); - break; - case 1: // +7K TANEX - space.install_ram(0x0400, 0x1fff,nullptr); - space.nop_readwrite(0x2000, 0xbbff); - break; - default: // +7K TANEX + 40K TANRAM - space.install_ram(0x0400, 0xbbff, nullptr); - break; + m_keyrows[i] = m_io_keyboard[i-1].read_safe(0); } - - for (int i = 1; i < 10; i++) - m_keyrows[i] = m_io_keyboard[i-1]->read(); - m_led = BIT(~m_keyrows[3], 7); } diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 0be5c85017f..e0ba5072e6e 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -21685,7 +21685,10 @@ pentacup // pentacup2 // @source:microtan.cpp -microtan // 1979 Microtan 65 +mt65 // 1979 Microtan 65 +micron // 1980 Micron +spinveti // 1980 Space Invasion (ETI) +mt6809 // 1984 Microtan 65 (6809 CPU) @source:microterm.cpp mt420 // diff --git a/src/mame/video/microtan.cpp b/src/mame/video/microtan.cpp index 4d5aed84be5..3a43600b312 100644 --- a/src/mame/video/microtan.cpp +++ b/src/mame/video/microtan.cpp @@ -60,3 +60,7 @@ uint32_t microtan_state::screen_update(screen_device &screen, bitmap_ind16 &bitm m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); return 0; } + +void mt6809_state::video_start() +{ +} -- cgit v1.2.3