// 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, const XTAL &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, const XTAL &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) { for (int y = 0; y < 256; y++) { uint32_t *p = &bitmap.pix(y); for (int x = 0; x < 256; x++) { uint16_t const 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) { for (int y = 0; y < 256; y++) { uint32_t *p = &bitmap.pix(y); for (int x = 0; x < 256; x++) { uint16_t const offset = (y * 32) + (x / 8); uint8_t const r = m_videoram[0x0000 | offset]; uint8_t const b = m_videoram[0x2000 | offset]; uint8_t const 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; }