From a4cf1316fa003f73193c3010984a373015051e02 Mon Sep 17 00:00:00 2001 From: hap Date: Sat, 23 Mar 2024 19:03:46 +0100 Subject: added novag tv interface peripheral [hap, Achim] --- scripts/src/bus.lua | 2 + src/devices/bus/rs232/nss_tvinterface.cpp | 246 ++++++++++++++++++++++++++++++ src/devices/bus/rs232/nss_tvinterface.h | 18 +++ src/devices/bus/rs232/rs232.cpp | 2 + src/mame/novag/primo.cpp | 2 + 5 files changed, 270 insertions(+) create mode 100644 src/devices/bus/rs232/nss_tvinterface.cpp create mode 100644 src/devices/bus/rs232/nss_tvinterface.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index b94822a0fa1..4bd51a77699 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -3212,6 +3212,8 @@ if (BUSES["RS232"]~=null) then MAME_DIR .. "src/devices/bus/rs232/loopback.h", MAME_DIR .. "src/devices/bus/rs232/mboardd.cpp", MAME_DIR .. "src/devices/bus/rs232/mboardd.h", + MAME_DIR .. "src/devices/bus/rs232/nss_tvinterface.cpp", + MAME_DIR .. "src/devices/bus/rs232/nss_tvinterface.h", MAME_DIR .. "src/devices/bus/rs232/null_modem.cpp", MAME_DIR .. "src/devices/bus/rs232/null_modem.h", MAME_DIR .. "src/devices/bus/rs232/patchbox.cpp", diff --git a/src/devices/bus/rs232/nss_tvinterface.cpp b/src/devices/bus/rs232/nss_tvinterface.cpp new file mode 100644 index 00000000000..ead4b99b1c4 --- /dev/null +++ b/src/devices/bus/rs232/nss_tvinterface.cpp @@ -0,0 +1,246 @@ +// license:BSD-3-Clause +// copyright-holders:hap +// thanks-to:Achim +/******************************************************************************* + +Novag Super System Peripheral: TV Interface + +It's meant to be connected either like: PC -> Distributor -> TV Interface, or +like: chesscomputer -> Distributor -> TV Interface. But the distributor is only +for converting to/from RS-232/TTL voltage, so MAME can ignore it. + +It expects a baud rate of 9600, 8 data bits, 1 stop bit, no parity. + +Hardware notes: +- PCB label: 100122 REV C +- Hitachi HD63A03RP @ 4.9152MHz +- 8KB ROM (27C64A), 4KB RAM (2*UM6116-3) +- TMT TM6310 CGA chip, 14.318MHz XTAL, 8KB CG ROM (27C64A, only 2KB used) + +TODO: +- dump/add English version +- Currently, MAME only has CGA emulation on ISA cards, but this thing is not an + ISA card, nor compatible with IBM CGA standard. So if MAME ever adds a more + generic CGA device, use that. + +*******************************************************************************/ + +#include "emu.h" +#include "nss_tvinterface.h" + +#include "cpu/m6800/m6801.h" +#include "video/cgapal.h" +#include "video/mc6845.h" + +#include "emupal.h" +#include "screen.h" + +namespace { + +//------------------------------------------------- +// initialization +//------------------------------------------------- + +class nss_tvinterface_device : public device_t, public device_rs232_port_interface +{ +public: + nss_tvinterface_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + virtual void device_start() override; + 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 void input_txd(int state) override { m_rx_state = state ? 1 : 0; } + +private: + required_device m_maincpu; + required_device m_crtc; + required_device m_palette; + required_device m_screen; + required_shared_ptr m_vram; + required_region_ptr m_cg_rom; + + u8 m_rx_state = 0; + + void palette(palette_device &palette) const; + MC6845_UPDATE_ROW(crtc_update_row); + + u8 cga_sync_r(); + void cga_mode_control_w(u8 data); + void cga_color_select_w(u8 data); + void unknown_w(u8 data); + + void main_map(address_map &map); + + u8 p2_r(); + void p2_w(u8 data); +}; + +nss_tvinterface_device::nss_tvinterface_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + device_t(mconfig, NSS_TVINTERFACE, tag, owner, clock), + device_rs232_port_interface(mconfig, *this), + m_maincpu(*this, "maincpu"), + m_crtc(*this, "crtc"), + m_palette(*this, "palette"), + m_screen(*this, "screen"), + m_vram(*this, "vram"), + m_cg_rom(*this, "cg_rom") +{ } + +void nss_tvinterface_device::device_start() +{ + save_item(NAME(m_rx_state)); +} + + +//------------------------------------------------- +// CGA video +//------------------------------------------------- + +void nss_tvinterface_device::palette(palette_device &palette) const +{ + for (int i = 0; i < 16; i++) + palette.set_pen_color(i, cga_palette[i][0], cga_palette[i][1], cga_palette[i][2]); +} + +MC6845_UPDATE_ROW(nss_tvinterface_device::crtc_update_row) +{ + const pen_t *pen = m_palette->pens(); + + for (int x = 0; x < x_count; x++) + { + u16 offset = (ma + x) << 1 & 0x7ff; + + u8 chr = m_vram[offset]; + u8 data = m_cg_rom[((ra << 8 | chr) & 0x7ff) | 0x1000]; + + u8 attr = m_vram[offset | 1]; + u8 fg = attr & 0xf; + u8 bg = attr >> 4 & 0xf; + + for (int xi = 0; xi < 8; xi++) + bitmap.pix(y, x << 3 | xi) = BIT(data, xi ^ 7) ? pen[fg] : pen[bg]; + } +} + +u8 nss_tvinterface_device::cga_sync_r() +{ + return (m_crtc->vsync_r() * 9) | m_crtc->hsync_r(); +} + +void nss_tvinterface_device::cga_mode_control_w(u8 data) +{ + // only uses textmode +} + +void nss_tvinterface_device::cga_color_select_w(u8 data) +{ + // does not use 2bpp palette +} + + +//------------------------------------------------- +// internal i/o +//------------------------------------------------- + +void nss_tvinterface_device::unknown_w(u8 data) +{ +} + +u8 nss_tvinterface_device::p2_r() +{ + // P23: serial in + return m_rx_state << 3; +} + +void nss_tvinterface_device::p2_w(u8 data) +{ + // P24: serial out + output_rxd(BIT(~data, 4)); +} + +void nss_tvinterface_device::main_map(address_map &map) +{ + map(0x8000, 0x87ff).ram().share(m_vram); + + map(0xa3bd, 0xa3bd).portr("IN.0"); + map(0xa3be, 0xa3be).w(FUNC(nss_tvinterface_device::unknown_w)); + + map(0xa3d0, 0xa3d0).mirror(0x0006).w(m_crtc, FUNC(mc6845_device::address_w)); + map(0xa3d1, 0xa3d1).mirror(0x0006).rw(m_crtc, FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w)); + map(0xa3d8, 0xa3d8).w(FUNC(nss_tvinterface_device::cga_mode_control_w)); + map(0xa3d9, 0xa3d9).w(FUNC(nss_tvinterface_device::cga_color_select_w)); + map(0xa3da, 0xa3da).r(FUNC(nss_tvinterface_device::cga_sync_r)); + + map(0xc000, 0xc7ff).ram(); + map(0xe000, 0xffff).rom(); +} + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +static INPUT_PORTS_START( nss_tvinterface ) + PORT_START("IN.0") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Select") + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_NAME("Change") +INPUT_PORTS_END + +ioport_constructor nss_tvinterface_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(nss_tvinterface); +} + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void nss_tvinterface_device::device_add_mconfig(machine_config &config) +{ + // basic machine hardware + HD6303R(config, m_maincpu, 4.9152_MHz_XTAL); + m_maincpu->set_addrmap(AS_PROGRAM, &nss_tvinterface_device::main_map); + m_maincpu->in_p2_cb().set(FUNC(nss_tvinterface_device::p2_r)); + m_maincpu->out_p2_cb().set(FUNC(nss_tvinterface_device::p2_w)); + + // video hardware + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_raw(14.318181_MHz_XTAL/2, 472, 0, 320, 260, 0, 200); + m_screen->set_screen_update(m_crtc, FUNC(mc6845_device::screen_update)); + + MC6845(config, m_crtc, 14.318181_MHz_XTAL/16); + m_crtc->set_screen(m_screen); + m_crtc->set_show_border_area(false); + m_crtc->set_char_width(8); + m_crtc->set_update_row_callback(FUNC(nss_tvinterface_device::crtc_update_row)); + + PALETTE(config, m_palette, FUNC(nss_tvinterface_device::palette), 16); +} + + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +ROM_START(nss_tvinterface) + ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_LOAD("tvgr_011091", 0xe000, 0x2000, CRC(0ff64cec) SHA1(d35881111cdf8e85a843e3b085447d07244d8d70) ) + + ROM_REGION( 0x2000, "cg_rom", 0 ) + ROM_LOAD("cg_930", 0x0000, 0x2000, CRC(98287b9d) SHA1(b20d7856e4739bafcd66434adf9881824f8a611b) ) +ROM_END + +const tiny_rom_entry *nss_tvinterface_device::device_rom_region() const +{ + return ROM_NAME(nss_tvinterface); +} + +} // anonymous namespace + +DEFINE_DEVICE_TYPE_PRIVATE(NSS_TVINTERFACE, device_rs232_port_interface, nss_tvinterface_device, "nss_tvinterface", "Novag Super System TV Interface") diff --git a/src/devices/bus/rs232/nss_tvinterface.h b/src/devices/bus/rs232/nss_tvinterface.h new file mode 100644 index 00000000000..470bd693a5c --- /dev/null +++ b/src/devices/bus/rs232/nss_tvinterface.h @@ -0,0 +1,18 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/******************************************************************************* + + Novag Super System Peripheral: TV Interface + +*******************************************************************************/ + +#ifndef MAME_BUS_RS232_NSS_TVINTERFACE_H +#define MAME_BUS_RS232_NSS_TVINTERFACE_H + +#pragma once + +#include "rs232.h" + +DECLARE_DEVICE_TYPE(NSS_TVINTERFACE, device_rs232_port_interface) + +#endif // MAME_BUS_RS232_NSS_TVINTERFACE_H diff --git a/src/devices/bus/rs232/rs232.cpp b/src/devices/bus/rs232/rs232.cpp index 4fc49cea61b..11a81a54471 100644 --- a/src/devices/bus/rs232/rs232.cpp +++ b/src/devices/bus/rs232/rs232.cpp @@ -158,6 +158,7 @@ device_rs232_port_interface::~device_rs232_port_interface() #include "keyboard.h" #include "loopback.h" #include "mboardd.h" +#include "nss_tvinterface.h" #include "null_modem.h" #include "patchbox.h" #include "printer.h" @@ -178,6 +179,7 @@ void default_rs232_devices(device_slot_interface &device) device.option_add("keyboard", SERIAL_KEYBOARD); device.option_add("loopback", RS232_LOOPBACK); device.option_add("mockingboard", SERIAL_MOCKINGBOARD_D); + device.option_add("nss_tvi", NSS_TVINTERFACE); device.option_add("null_modem", NULL_MODEM); device.option_add("patch", RS232_PATCH_BOX); device.option_add("printer", SERIAL_PRINTER); diff --git a/src/mame/novag/primo.cpp b/src/mame/novag/primo.cpp index 7024beb15fe..ffa38ee4485 100644 --- a/src/mame/novag/primo.cpp +++ b/src/mame/novag/primo.cpp @@ -10,6 +10,8 @@ properly. TODO: - if/when MAME supports an exit callback, hook up power-off switch to that +- nsnova sometimes fails to detect Super System TV Interface when pressing New Game? + It should flash the screen on successful detection. - unmapped reads from 0x3c/0x3d (primo/supremo) or 0x33/0x34 (nsnova) - supremo unmapped writes to 0x2000/0x6000, always 0? - is the 1st version of supremo(black plastic) the same ROM? -- cgit v1.2.3