diff options
Diffstat (limited to 'src/devices/bus/einstein/pipe/tk02.cpp')
-rw-r--r-- | src/devices/bus/einstein/pipe/tk02.cpp | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/src/devices/bus/einstein/pipe/tk02.cpp b/src/devices/bus/einstein/pipe/tk02.cpp new file mode 100644 index 00000000000..9af704c2f2b --- /dev/null +++ b/src/devices/bus/einstein/pipe/tk02.cpp @@ -0,0 +1,231 @@ +// license: GPL-2.0+ +// copyright-holders: Dirk Best, Phill Harvey-Smith +/*************************************************************************** + + TK02 80 Column Monochrome Unit + +***************************************************************************/ + +#include "emu.h" +#include "tk02.h" +#include "screen.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(TK02_80COL, tk02_device, "tk02", "TK02 80 Column Monochrome Unit") + +//------------------------------------------------- +// device_address_map +//------------------------------------------------- + +DEVICE_ADDRESS_MAP_START(map, 8, tk02_device) +// AM_RANGE(0x00, 0x07) AM_SELECT(0xff00) AM_READWRITE(ram_r, ram_w) // no AM_SELECT (or AM_MASK) support here + AM_RANGE(0x08, 0x08) AM_MIRROR(0xff00) AM_DEVWRITE("crtc", mc6845_device, address_w) + AM_RANGE(0x09, 0x09) AM_MIRROR(0xff00) AM_DEVWRITE("crtc", mc6845_device, register_w) + AM_RANGE(0x0c, 0x0c) AM_MIRROR(0xff00) AM_READ(status_r) +ADDRESS_MAP_END + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +ROM_START( tk02 ) + ROM_REGION(0x2000, "gfx", 0) + ROM_LOAD("tk02-v100.bin", 0x0000, 0x2000, CRC(ad3c4346) SHA1(cd57e630371b4d0314e3f15693753fb195c7257d)) +ROM_END + +const tiny_rom_entry *tk02_device::device_rom_region() const +{ + return ROM_NAME( tk02 ); +} + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +static INPUT_PORTS_START( tk02_links ) + PORT_START("M001") + PORT_DIPUNUSED_DIPLOC(0x01, 0x01, "M001:1") + + PORT_START("M002") + PORT_DIPNAME(0x01, 0x00, "TV Standard") PORT_DIPLOCATION("M002:1") + PORT_DIPSETTING(0x00, "625 lines/50 Hz") + PORT_DIPSETTING(0x01, "525 lines/60 Hz") + + PORT_START("M003") + PORT_DIPNAME(0x01, 0x00, "Startup Mode") PORT_DIPLOCATION("M003:1") + PORT_DIPSETTING(0x00, "Normal") + PORT_DIPSETTING(0x01, "Automatic 80 Column") + + PORT_START("M004") + PORT_DIPNAME(0x01, 0x00, "Character Set") PORT_DIPLOCATION("M004:1") + PORT_DIPSETTING(0x00, "Modified") + PORT_DIPSETTING(0x01, "Normal") +INPUT_PORTS_END + +ioport_constructor tk02_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( tk02_links ); +} + +//------------------------------------------------- +// gfx_layout - only for the char viewer +//------------------------------------------------- + +static const gfx_layout tk02_charlayout = +{ + 8, 10, + 256, + 1, + { 0 }, + { 0, 1, 2, 3, 4, 5, 6, 7 }, + { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 0x800*8, 0x801*8 }, + 8*8 +}; + +static GFXDECODE_START( tk02 ) + GFXDECODE_ENTRY("gfx", 0x0000, tk02_charlayout, 0, 1) + GFXDECODE_ENTRY("gfx", 0x1000, tk02_charlayout, 0, 1) +GFXDECODE_END + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +MACHINE_CONFIG_MEMBER( tk02_device::device_add_mconfig ) + MCFG_SCREEN_ADD_MONOCHROME("mono", RASTER, rgb_t::green()) + MCFG_SCREEN_RAW_PARAMS(XTAL_8MHz * 2, 1024, 0, 640, 312, 0, 250) + MCFG_SCREEN_UPDATE_DEVICE("crtc", mc6845_device, screen_update) + + MCFG_PALETTE_ADD_MONOCHROME("palette") + + MCFG_GFXDECODE_ADD("gfxdecode", "palette", tk02) + + MCFG_MC6845_ADD("crtc", MC6845, "mono", XTAL_8MHz / 4) + MCFG_MC6845_SHOW_BORDER_AREA(false) + MCFG_MC6845_CHAR_WIDTH(8) + MCFG_MC6845_UPDATE_ROW_CB(tk02_device, crtc_update_row) + MCFG_MC6845_OUT_DE_CB(WRITELINE(tk02_device, de_w)) + + MCFG_TATUNG_PIPE_ADD("pipe") +MACHINE_CONFIG_END + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// tk02_device - constructor +//------------------------------------------------- + +tk02_device::tk02_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, TK02_80COL, tag, owner, clock), + device_tatung_pipe_interface(mconfig, *this), + m_pipe(*this, "pipe"), + m_crtc(*this, "crtc"), + m_palette(*this, "palette"), + m_gfx(*this, "gfx"), + m_links(*this, "M00%u", 1), + m_de(0) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void tk02_device::device_start() +{ + // setup ram + m_ram = std::make_unique<uint8_t[]>(0x800); + memset(m_ram.get(), 0xff, 0x800); + + // register for save states + save_pointer(NAME(m_ram.get()), 0x800); + save_item(NAME(m_de)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void tk02_device::device_reset() +{ + m_pipe->set_io_space(&io_space()); + m_pipe->set_program_space(&program_space()); + + io_space().install_device(0x40, 0x4f, *this, &tk02_device::map); + io_space().install_readwrite_handler(0x40, 0x47, 0, 0, 0xff00, read8_delegate(FUNC(tk02_device::ram_r), this), write8_delegate(FUNC(tk02_device::ram_w), this)); +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +MC6845_UPDATE_ROW( tk02_device::crtc_update_row ) +{ + const pen_t *pen = m_palette->pens(); + + for (int i = 0; i < x_count; i++) + { + uint8_t code = m_ram[(ma + i) & 0x07ff]; + + // 12-------------- link M004 + // --11------------ ra3 + // ----109876543--- data from ram + // -------------210 ra0..2 + uint8_t data = m_gfx->as_u8((m_links[3]->read() << 12) | ((ra & 0x08) << 8) | (code << 3) | (ra & 0x07)); + + if (i == cursor_x) + data ^= 0xff; + + bitmap.pix32(y, i * 8 + 0) = pen[BIT(data, 7)]; + bitmap.pix32(y, i * 8 + 1) = pen[BIT(data, 6)]; + bitmap.pix32(y, i * 8 + 2) = pen[BIT(data, 5)]; + bitmap.pix32(y, i * 8 + 3) = pen[BIT(data, 4)]; + bitmap.pix32(y, i * 8 + 4) = pen[BIT(data, 3)]; + bitmap.pix32(y, i * 8 + 5) = pen[BIT(data, 2)]; + bitmap.pix32(y, i * 8 + 6) = pen[BIT(data, 1)]; + bitmap.pix32(y, i * 8 + 7) = pen[BIT(data, 0)]; + } +} + +WRITE_LINE_MEMBER( tk02_device::de_w ) +{ + m_de = state; +} + +// lower 3 bits of address define a 256-byte "row" +// upper 8 bits define the offset in the row +READ8_MEMBER( tk02_device::ram_r ) +{ + return m_ram[((offset & 0x07) << 8) | ((offset >> 8) & 0xff)]; +} + +WRITE8_MEMBER( tk02_device::ram_w ) +{ + m_ram[((offset & 0x07) << 8) | ((offset >> 8) & 0xff)] = data; +} + +READ8_MEMBER( tk02_device::status_r ) +{ + // 7654---- unused + // ----3--- link M001 + // -----2-- link M002 + // ------1- link M003 + // -------0 mc6845 display enabled + + uint8_t data = 0xf0; + + data |= m_links[0]->read() << 3; + data |= m_links[1]->read() << 2; + data |= m_links[2]->read() << 1; + data |= m_de << 0; + + return data; +} |