mame/src/mame/drivers/vt240.cpp
cracyc a1e832cd32 vt240: WIP (nw)
t11: add reset output line (nw)
mc68681: op tx/rx status lines (nw)
2016-07-11 19:32:25 -05:00

680 lines
21 KiB
C++

// license:BSD-3-Clause
// copyright-holders:Miodrag Milanovic, Jonathan Gevaryahu
/***************************************************************************
DEC VT240
****************************************************************************/
#include "emu.h"
#include "bus/rs232/rs232.h"
#include "cpu/i8085/i8085.h"
#include "cpu/t11/t11.h"
#include "machine/clock.h"
#include "machine/dec_lk201.h"
#include "machine/i8251.h"
#include "machine/mc68681.h"
#include "machine/ms7004.h"
#include "machine/bankdev.h"
#include "machine/x2212.h"
#include "video/upd7220.h"
#define VERBOSE_DBG 1 /* general debug messages */
#define DBG_LOG(N,M,A) \
do { \
if(VERBOSE_DBG>=N) \
{ \
logerror("%11.6f at %s: ",machine().time().as_double(),machine().describe_context()); \
logerror A; \
} \
} while (0)
class vt240_state : public driver_device
{
public:
vt240_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_i8085(*this, "charcpu"),
m_i8251(*this, "i8251"),
m_duart(*this, "duart"),
m_host(*this, "host"),
m_hgdc(*this, "upd7220"),
m_bank(*this, "bank"),
m_nvram(*this, "x2212"),
m_palette(*this, "palette"),
m_rom(*this, "maincpu"),
m_video_ram(*this, "vram"),
m_monitor(*this, "monitor"),
m_lk201(*this, "lk201"){ }
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_i8085;
required_device<i8251_device> m_i8251;
required_device<mc68681_device> m_duart;
required_device<rs232_port_device> m_host;
required_device<upd7220_device> m_hgdc;
required_device<address_map_bank_device> m_bank;
required_device<x2212_device> m_nvram;
required_device<palette_device> m_palette;
required_region_ptr<UINT16> m_rom;
required_shared_ptr<UINT16> m_video_ram;
required_ioport m_monitor;
optional_device<lk201_device> m_lk201;
DECLARE_WRITE_LINE_MEMBER(write_keyboard_clock);
DECLARE_WRITE_LINE_MEMBER(i8085_rdy_w);
DECLARE_WRITE_LINE_MEMBER(lben_w);
DECLARE_WRITE_LINE_MEMBER(tx_w);
DECLARE_WRITE_LINE_MEMBER(t11_reset_w);
DECLARE_READ_LINE_MEMBER(i8085_sid_r);
DECLARE_READ8_MEMBER(i8085_comm_r);
DECLARE_WRITE8_MEMBER(i8085_comm_w);
DECLARE_READ8_MEMBER(t11_comm_r);
DECLARE_WRITE8_MEMBER(t11_comm_w);
DECLARE_READ8_MEMBER(duart_r);
DECLARE_WRITE8_MEMBER(duart_w);
DECLARE_WRITE8_MEMBER(duartout_w);
DECLARE_READ8_MEMBER(mem_map_cs_r);
DECLARE_WRITE8_MEMBER(mem_map_cs_w);
DECLARE_READ8_MEMBER(ctrl_r);
DECLARE_WRITE8_MEMBER(mem_map_sel_w);
DECLARE_READ8_MEMBER(char_buf_r);
DECLARE_WRITE8_MEMBER(char_buf_w);
DECLARE_WRITE8_MEMBER(patmult_w);
DECLARE_WRITE8_MEMBER(vpat_w);
DECLARE_READ16_MEMBER(vram_r);
DECLARE_WRITE16_MEMBER(vram_w);
DECLARE_READ8_MEMBER(vom_r);
DECLARE_WRITE8_MEMBER(vom_w);
DECLARE_WRITE8_MEMBER(nvr_store_w);
DECLARE_WRITE8_MEMBER(mask_w);
DECLARE_WRITE8_MEMBER(reg0_w);
DECLARE_WRITE8_MEMBER(reg1_w);
DECLARE_WRITE8_MEMBER(lu_w);
DECLARE_READ16_MEMBER(mem_r);
DECLARE_WRITE16_MEMBER(mem_w);
DECLARE_DRIVER_INIT(vt240);
virtual void machine_reset() override;
UPD7220_DISPLAY_PIXELS_MEMBER(hgdc_draw);
UINT8 m_i8085_out, m_t11_out, m_i8085_rdy, m_t11;
UINT8 m_mem_map[16];
UINT8 m_mem_map_sel;
UINT8 m_char_buf[16];
UINT8 m_char_idx, m_mask, m_reg0, m_reg1, m_lu;
UINT8 m_vom[16];
UINT8 m_vpat, m_patmult, m_patcnt, m_patidx;
bool m_lb;
};
WRITE_LINE_MEMBER(vt240_state::write_keyboard_clock)
{
m_i8251->write_txc(state);
m_i8251->write_rxc(state);
}
WRITE_LINE_MEMBER(vt240_state::lben_w)
{
m_lb = state ? false : true;
}
WRITE_LINE_MEMBER(vt240_state::t11_reset_w)
{
if(state == ASSERT_LINE)
{
m_duart->reset();
m_i8251->reset();
m_nvram->recall(ASSERT_LINE);
m_nvram->recall(CLEAR_LINE);
}
}
WRITE_LINE_MEMBER(vt240_state::tx_w)
{
if(m_lb)
m_i8251->write_rxd(state);
else
m_lk201->rx_w(state);
}
WRITE_LINE_MEMBER(vt240_state::i8085_rdy_w)
{
m_maincpu->set_input_line(3, state ? CLEAR_LINE : ASSERT_LINE);
m_i8085_rdy = state;
}
READ_LINE_MEMBER(vt240_state::i8085_sid_r)
{
return m_t11 ? CLEAR_LINE : ASSERT_LINE;
}
UPD7220_DISPLAY_PIXELS_MEMBER( vt240_state::hgdc_draw )
{
const rgb_t *palette = m_palette->palette()->entry_list_raw();
int xi, gfx1, gfx2;
UINT8 vom;
if(!BIT(m_reg0, 7))
{
vram_w(generic_space(), address >> 1, 0);
vram_w(generic_space(), (0x20000 + address) >> 1, 0);
}
gfx1 = m_video_ram[(address & 0x7fff) >> 1];
gfx2 = m_video_ram[((address & 0x7fff) + 0x8000) >> 1];
bool color = m_monitor->read() ? true : false;
for(xi=0;xi<16;xi++)
{
vom = BIT(gfx1, xi) | (BIT(gfx2, xi) << 1) | ((m_reg0 & 3) << 2);
bitmap.pix32(y, x + xi) = palette[color ? (vom + 16) : vom];
}
}
READ8_MEMBER(vt240_state::t11_comm_r)
{
m_t11 = 1;
m_i8085->set_input_line(I8085_RST65_LINE, CLEAR_LINE);
return m_t11_out;
}
WRITE8_MEMBER(vt240_state::t11_comm_w)
{
m_i8085_out = data;
}
READ8_MEMBER(vt240_state::i8085_comm_r)
{
switch(offset)
{
case 0:
return m_i8085_out;
case 2:
m_i8085->set_input_line(I8085_RST65_LINE, CLEAR_LINE);
m_i8085->set_input_line(INPUT_LINE_RESET, PULSE_LINE);
m_t11 = 1;
break;
}
return 0xff;
}
WRITE8_MEMBER(vt240_state::i8085_comm_w)
{
switch(offset)
{
case 1:
m_t11_out = data;
m_t11 = 0;
m_i8085->set_input_line(I8085_RST65_LINE, ASSERT_LINE);
break;
case 2:
m_i8085->set_input_line(I8085_RST65_LINE, CLEAR_LINE);
m_i8085->set_input_line(INPUT_LINE_RESET, PULSE_LINE);
m_t11 = 1;
break;
}
}
READ8_MEMBER(vt240_state::duart_r)
{
if(!(offset & 1))
return m_duart->read(space, offset >> 1);
return 0;
}
WRITE8_MEMBER(vt240_state::duart_w)
{
if(offset & 1)
m_duart->write(space, offset >> 1, data);
}
WRITE8_MEMBER(vt240_state::duartout_w)
{
m_host->write_rts(BIT(data, 0) ? CLEAR_LINE : ASSERT_LINE);
m_host->write_dtr(BIT(data, 2) ? CLEAR_LINE : ASSERT_LINE);
m_maincpu->set_input_line(15, BIT(data, 4) ? CLEAR_LINE : ASSERT_LINE);
m_maincpu->set_input_line(14, BIT(data, 5) ? CLEAR_LINE : ASSERT_LINE);
m_maincpu->set_input_line(11, BIT(data, 6) ? CLEAR_LINE : ASSERT_LINE);
m_maincpu->set_input_line(10, BIT(data, 7) ? CLEAR_LINE : ASSERT_LINE);
}
READ8_MEMBER(vt240_state::mem_map_cs_r)
{
return ~m_mem_map[offset];
}
WRITE8_MEMBER(vt240_state::mem_map_cs_w)
{
m_mem_map[offset] = ~data;
}
READ8_MEMBER(vt240_state::ctrl_r)
{
return m_mem_map_sel | ((m_lb ? 0 : 1) << 3) | (m_i8085_rdy << 6) | (m_t11 << 7) | (1<<5); // no modem
}
WRITE8_MEMBER(vt240_state::mem_map_sel_w)
{
m_mem_map_sel = data & 1;
}
READ16_MEMBER(vt240_state::mem_r)
{
if(m_mem_map_sel)
{
m_bank->set_bank(m_mem_map[(offset >> 11) & 0xf]);
return m_bank->read16(space, offset & 0x7ff, mem_mask);
}
else
return m_rom[offset];
}
WRITE16_MEMBER(vt240_state::mem_w)
{
if(m_mem_map_sel)
{
m_bank->set_bank(m_mem_map[(offset >> 11) & 0xf]);
m_bank->write16(space, offset & 0x7ff, data, mem_mask);
}
}
READ8_MEMBER(vt240_state::char_buf_r)
{
m_char_idx = 0;
return 0xff;
}
WRITE8_MEMBER(vt240_state::char_buf_w)
{
m_char_buf[m_char_idx++] = BITSWAP8(data, 0, 1, 2, 3, 4, 5, 6, 7);
m_char_idx &= 0xf;
}
WRITE8_MEMBER(vt240_state::patmult_w)
{
m_patmult = data & 0xf;
}
WRITE8_MEMBER(vt240_state::vpat_w)
{
m_vpat = data;
m_patcnt = m_patmult;
m_patidx = 7;
}
READ8_MEMBER(vt240_state::vom_r)
{
if(!BIT(m_reg0, 2))
return m_vom[offset];
// this hack passes a self test, is not a useful value normally
// when vom read mode is disabled, the read latch is set to whatever map is
// enabled and color is currently drawn, the self test fills the screen with 0xff
// and reads it
return m_vom[((m_reg0 & 3) << 2) + 3];
}
WRITE8_MEMBER(vt240_state::vom_w)
{
if(!BIT(m_reg0, 2))
{
m_vom[offset] = data;
data = ~BITSWAP8(data, 0, 1, 2, 3, 4, 5, 6, 7);
m_palette->set_pen_color(offset, pal2bit(data >> 6), pal2bit(data >> 6), pal2bit(data >> 6));
m_palette->set_pen_color((offset + 16), pal2bit(data >> 0), pal2bit(data >> 2), pal2bit(data >> 4));
}
}
READ16_MEMBER(vt240_state::vram_r)
{
if(!BIT(m_reg0, 3) || space.debugger_access())
{
offset = ((offset & 0x18000) >> 1) | (offset & 0x3fff);
return m_video_ram[offset & 0x7fff];
}
return 0;
}
WRITE16_MEMBER(vt240_state::vram_w)
{
UINT8 *video_ram = (UINT8 *)(&m_video_ram[0]);
offset <<= 1;
offset = ((offset & 0x30000) >> 1) | (offset & 0x7fff);
if(!BIT(m_reg0, 3))
offset |= BIT(offset, 16);
else
{
if(data & 0xff00)
{
data >>= 8;
offset += 1;
}
else
data &= 0xff;
}
offset &= 0xffff;
UINT8 chr = data;
if(BIT(m_reg1, 2))
chr = video_ram[offset];
else if(BIT(m_reg0, 4))
{
if(BIT(m_reg0, 6))
{
chr = BITSWAP8(m_vpat, m_patidx, m_patidx, m_patidx, m_patidx, m_patidx, m_patidx, m_patidx, m_patidx);
if(m_patcnt-- == 0)
{
m_patcnt = m_patmult;
if(m_patidx-- == 0)
m_patidx = 7;
}
}
else
{
chr = m_char_buf[m_char_idx++];
m_char_idx &= 0xf;
}
int ps = ~m_lu & 3;
for(int i = 0; i <= (ps >> 1); i++)
{
if(ps == 0)
i++;
UINT8 mem = video_ram[(offset & 0x7fff) + (0x8000 * i)];
switch(m_lu >> 6)
{
case 0:
break;
case 1:
chr |= mem;
break;
case 2:
logerror("invalid logic unit mode 2\n");
break;
case 3:
chr ^= mem;
break;
}
UINT8 out = 0, ifore = BIT(m_lu, (i ? 5 : 4)), iback = BIT(m_lu, (i ? 3 : 2));
for(int j = 0; j < 8; j++)
out |= BIT(chr, j) ? (ifore << j) : (iback << j);
if(!BIT(m_reg0, 3))
out = (out & ~m_mask) | (mem & m_mask);
else
out = (out & data) | (mem & ~data);
video_ram[(offset & 0x7fff) + (0x8000 * i)] = out;
}
return;
}
if(!BIT(m_reg0, 3))
data = (chr & ~m_mask) | (video_ram[offset] & m_mask);
else
data = (chr & data) | (video_ram[offset] & ~data);
video_ram[offset] = data;
}
WRITE8_MEMBER(vt240_state::mask_w)
{
m_mask = BITSWAP8(data, 0, 1, 2, 3, 4, 5, 6, 7);
}
WRITE8_MEMBER(vt240_state::nvr_store_w)
{
m_nvram->store(ASSERT_LINE);
m_nvram->store(CLEAR_LINE);
}
WRITE8_MEMBER(vt240_state::reg0_w)
{
m_reg0 = data;
}
WRITE8_MEMBER(vt240_state::reg1_w)
{
m_reg1 = data;
}
WRITE8_MEMBER(vt240_state::lu_w)
{
m_lu = data;
}
static ADDRESS_MAP_START(bank_map, AS_PROGRAM, 16, vt240_state)
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x00000, 0x1ffff) AM_ROM AM_REGION("maincpu", 0)
AM_RANGE(0x80000, 0x87fff) AM_RAM
ADDRESS_MAP_END
// PDF page 78 (4-25)
static ADDRESS_MAP_START( vt240_mem, AS_PROGRAM, 16, vt240_state )
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE (0000000, 0167777) AM_READWRITE(mem_r, mem_w)
AM_RANGE (0170000, 0170037) AM_READWRITE8(mem_map_cs_r, mem_map_cs_w, 0x00ff)
AM_RANGE (0170040, 0170041) AM_WRITE8(mem_map_sel_w, 0x00ff)
AM_RANGE (0170100, 0170101) AM_READ8(ctrl_r, 0x00ff)
AM_RANGE (0170140, 0170141) AM_WRITE8(nvr_store_w, 0x00ff)
AM_RANGE (0171000, 0171003) AM_DEVREADWRITE8("i8251", i8251_device, data_r, data_w, 0x00ff)
AM_RANGE (0171004, 0171007) AM_DEVREADWRITE8("i8251", i8251_device, status_r, control_w, 0x00ff)
AM_RANGE (0172000, 0172077) AM_READWRITE8(duart_r, duart_w, 0x00ff)
AM_RANGE (0173000, 0173003) AM_DEVREAD8("upd7220", upd7220_device, read, 0x00ff)
AM_RANGE (0173040, 0173077) AM_READ8(vom_r, 0x00ff)
AM_RANGE (0173140, 0173141) AM_READ8(char_buf_r, 0x00ff)
AM_RANGE (0174000, 0174003) AM_DEVWRITE8("upd7220", upd7220_device, write, 0x00ff)
AM_RANGE (0174040, 0174077) AM_WRITE8(vom_w, 0x00ff)
AM_RANGE (0174140, 0174141) AM_WRITE8(char_buf_w, 0x00ff)
AM_RANGE (0174400, 0174401) AM_WRITE8(patmult_w, 0x00ff)
AM_RANGE (0174440, 0174441) AM_WRITE8(mask_w, 0x00ff)
AM_RANGE (0174500, 0174501) AM_WRITE8(vpat_w, 0x00ff)
AM_RANGE (0174540, 0174541) AM_WRITE8(lu_w, 0x00ff)
AM_RANGE (0174600, 0174601) AM_WRITE8(reg0_w, 0x00ff)
AM_RANGE (0174640, 0174641) AM_WRITE8(reg1_w, 0x00ff)
AM_RANGE (0175000, 0175005) AM_READWRITE8(i8085_comm_r, i8085_comm_w, 0x00ff)
AM_RANGE (0176000, 0176777) AM_DEVREADWRITE8("x2212", x2212_device, read, write, 0x00ff)
// 017700x System comm logic
ADDRESS_MAP_END
// PDF page 134 (6-9)
static ADDRESS_MAP_START(vt240_char_mem, AS_PROGRAM, 8, vt240_state)
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x0000, 0x3fff) AM_ROM AM_REGION("charcpu", 0)
AM_RANGE(0x4000, 0x5fff) AM_ROM AM_REGION("charcpu", 0x8000)
AM_RANGE(0x8000, 0x87ff) AM_RAM
ADDRESS_MAP_END
static ADDRESS_MAP_START(vt240_char_io, AS_IO, 8, vt240_state)
ADDRESS_MAP_UNMAP_HIGH
ADDRESS_MAP_GLOBAL_MASK(0xff)
AM_RANGE(0x00, 0x01) AM_DEVREADWRITE("upd7220", upd7220_device, read, write)
AM_RANGE(0x10, 0x1f) AM_READWRITE(vom_r, vom_w)
AM_RANGE(0x20, 0x20) AM_READWRITE(t11_comm_r, t11_comm_w)
AM_RANGE(0x30, 0x30) AM_READWRITE(char_buf_r, char_buf_w)
AM_RANGE(0x80, 0x80) AM_WRITE(patmult_w)
AM_RANGE(0x90, 0x90) AM_WRITE(mask_w)
AM_RANGE(0xa0, 0xa0) AM_WRITE(vpat_w)
AM_RANGE(0xb0, 0xb0) AM_WRITE(lu_w)
AM_RANGE(0xc0, 0xc0) AM_WRITE(reg0_w)
AM_RANGE(0xd0, 0xd0) AM_WRITE(reg1_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( upd7220_map, AS_0, 16, vt240_state)
AM_RANGE(0x00000, 0x3ffff) AM_READWRITE(vram_r, vram_w) AM_SHARE("vram")
ADDRESS_MAP_END
void vt240_state::machine_reset()
{
m_i8251->write_cts(0);
m_nvram->recall(ASSERT_LINE);
m_nvram->recall(CLEAR_LINE);
m_mem_map_sel = 0;
m_t11 = 1;
m_i8085_rdy = 1;
m_char_idx = 0;
m_patcnt = 0;
m_patidx = 0;
m_reg0 = 0x80;
}
static const gfx_layout vt240_chars_8x10 =
{
8,10,
0x240,
1,
{ 0 },
{ STEP8(0,1) },
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8 },
8*10
};
static GFXDECODE_START( vt240 )
GFXDECODE_ENTRY( "charcpu", 0x338*10-3, vt240_chars_8x10, 0, 8 )
GFXDECODE_END
static INPUT_PORTS_START( vt240 )
PORT_START("monitor")
PORT_CONFNAME(0x01, 0x01, "Monitor Type")
PORT_CONFSETTING(0x00, "Monochrome")
PORT_CONFSETTING(0x01, "Color")
INPUT_PORTS_END
static MACHINE_CONFIG_START( vt240, vt240_state )
MCFG_CPU_ADD("maincpu", T11, XTAL_7_3728MHz) // confirm
MCFG_CPU_PROGRAM_MAP(vt240_mem)
MCFG_T11_INITIAL_MODE(5 << 13)
MCFG_T11_RESET(WRITELINE(vt240_state, t11_reset_w))
MCFG_CPU_ADD("charcpu", I8085A, XTAL_16MHz / 4)
MCFG_CPU_PROGRAM_MAP(vt240_char_mem)
MCFG_CPU_IO_MAP(vt240_char_io)
MCFG_I8085A_SOD(WRITELINE(vt240_state, i8085_rdy_w))
MCFG_I8085A_SID(READLINE(vt240_state, i8085_sid_r))
MCFG_DEVICE_ADD("bank", ADDRESS_MAP_BANK, 0)
MCFG_DEVICE_PROGRAM_MAP(bank_map)
MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE)
MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(20)
MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16)
MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000)
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(50)
MCFG_SCREEN_SIZE(640, 480)
MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 480-1)
MCFG_SCREEN_UPDATE_DEVICE("upd7220", upd7220_device, screen_update)
MCFG_PALETTE_ADD("palette", 32)
MCFG_GFXDECODE_ADD("gfxdecode", "palette", vt240)
MCFG_DEVICE_ADD("upd7220", UPD7220, XTAL_4MHz / 4)
MCFG_DEVICE_ADDRESS_MAP(AS_0, upd7220_map)
MCFG_UPD7220_DISPLAY_PIXELS_CALLBACK_OWNER(vt240_state, hgdc_draw)
MCFG_UPD7220_VSYNC_CALLBACK(INPUTLINE("charcpu", I8085_RST75_LINE))
MCFG_UPD7220_BLANK_CALLBACK(INPUTLINE("charcpu", I8085_RST55_LINE))
MCFG_VIDEO_SET_SCREEN("screen")
MCFG_MC68681_ADD("duart", XTAL_3_6864MHz) /* 2681 duart (not 68681!) */
MCFG_MC68681_IRQ_CALLBACK(INPUTLINE("maincpu", 13))
MCFG_MC68681_A_TX_CALLBACK(DEVWRITELINE("host", rs232_port_device, write_txd))
MCFG_MC68681_B_TX_CALLBACK(DEVWRITELINE("printer", rs232_port_device, write_txd))
MCFG_MC68681_OUTPORT_CALLBACK(WRITE8(vt240_state, duartout_w))
MCFG_DEVICE_ADD("i8251", I8251, 0)
MCFG_I8251_TXD_HANDLER(WRITELINE(vt240_state, tx_w))
MCFG_I8251_DTR_HANDLER(WRITELINE(vt240_state, lben_w))
MCFG_I8251_RXRDY_HANDLER(INPUTLINE("maincpu", 9))
MCFG_I8251_TXRDY_HANDLER(INPUTLINE("maincpu", 7))
MCFG_DEVICE_ADD("lk201", LK201, 0)
MCFG_LK201_TX_HANDLER(DEVWRITELINE("i8251", i8251_device, write_rxd))
MCFG_DEVICE_ADD("keyboard_clock", CLOCK, 4800 * 64) // 8251 is set to /64 on the clock input
MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(vt240_state, write_keyboard_clock))
MCFG_RS232_PORT_ADD("host", default_rs232_devices, "null_modem")
MCFG_RS232_RXD_HANDLER(DEVWRITELINE("duart", mc68681_device, rx_a_w))
MCFG_RS232_DSR_HANDLER(DEVWRITELINE("duart", mc68681_device, ip5_w))
MCFG_RS232_CTS_HANDLER(DEVWRITELINE("duart", mc68681_device, ip0_w))
MCFG_RS232_PORT_ADD("printer", default_rs232_devices, nullptr)
MCFG_RS232_RXD_HANDLER(DEVWRITELINE("duart", mc68681_device, rx_b_w))
MCFG_RS232_DSR_HANDLER(DEVWRITELINE("duart", mc68681_device, ip1_w))
MCFG_X2212_ADD("x2212")
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( mc7105, vt240 )
MCFG_DEVICE_REMOVE("lk201")
MCFG_DEVICE_ADD("ms7004", MS7004, 0)
MCFG_MS7004_TX_HANDLER(DEVWRITELINE("i8251", i8251_device, write_rxd))
MCFG_DEVICE_MODIFY("i8251")
MCFG_I8251_TXD_HANDLER(NOOP)
//MCFG_I8251_TXD_HANDLER(DEVWRITELINE("ms7004", ms7004_device, rx_w))
// baud rate is supposed to be 4800 but keyboard is slightly faster
MCFG_DEVICE_REMOVE("keyboard_clock")
MCFG_DEVICE_ADD("keyboard_clock", CLOCK, 4960*16)
MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(vt240_state, write_keyboard_clock))
MACHINE_CONFIG_END
/* ROM definition */
ROM_START( mc7105 )
ROM_REGION( 0x10000, "charcpu", ROMREGION_ERASEFF )
ROM_LOAD( "027.bin", 0x8000, 0x8000, CRC(a159b412) SHA1(956097ccc2652d494258b3682498cfd3096d7d4f))
ROM_LOAD( "028.bin", 0x0000, 0x8000, CRC(b253151f) SHA1(22ffeef8eb5df3c38bfe91266f26d1e7822cdb53))
ROM_REGION( 0x20000, "maincpu", ROMREGION_ERASEFF )
ROM_LOAD16_BYTE( "029.bin", 0x00000, 0x8000, CRC(4a6db217) SHA1(47637325609ea19ffab61fe31e2700d72fa50729))
ROM_LOAD16_BYTE( "031.bin", 0x00001, 0x8000, CRC(47129579) SHA1(39de9e2e26f90c5da5e72a09ff361c1a94b9008a))
ROM_LOAD16_BYTE( "030.bin", 0x10000, 0x8000, CRC(05fd7b75) SHA1(2ad8c14e76accfa1b9b8748c58e9ebbc28844a47))
ROM_LOAD16_BYTE( "032.bin", 0x10001, 0x8000, CRC(e81d93c4) SHA1(982412a7a6e65d6f6b4f66bd093e54ee16f31384))
ROM_END
/* ROM definition */
ROM_START( vt240 )
ROM_REGION( 0x10000, "charcpu", ROMREGION_ERASEFF )
ROM_LOAD( "23-008e6-00.e100", 0x0000, 0x4000, CRC(ebc8a2fe) SHA1(70838175f8302fdc0dee79b2403fa95e6d989206))
ROM_CONTINUE(0x8000, 0x4000)
ROM_REGION( 0x20000, "maincpu", ROMREGION_ERASEFF )
ROM_DEFAULT_BIOS( "vt240" )
// according to the schematics an even older set exists, variation 'E1' with roms:
// e100/8085: 23-003e6
// e20: 23-001e6
// e22: 23-002e6
// e19: 23-048e5
// e21: 23-049e5
// but according to the Field Change Order below, the initial release is V2.1, so the above must be a prototype.
// DOL for v2.1 to v2.2 change: http://web.archive.org/web/20060905145200/http://cmcnabb.cc.vt.edu/dec94mds/vt240dol.txt
ROM_SYSTEM_BIOS( 0, "vt240v21", "VT240 V2.1" ) // initial factory release, FCO says this was 8 Feburary 1985
ROMX_LOAD( "23-006e6-00.e20", 0x00000, 0x8000, CRC(79c11d82) SHA1(5a6fe5b75b6504a161f2c9b148c0fe9f19770837), ROM_SKIP(1) | ROM_BIOS(1))
ROMX_LOAD( "23-004e6-00.e22", 0x00001, 0x8000, CRC(eba10fef) SHA1(c0ee4d8e4eeb70066f03f3d17a7e2f2bd0b5f8ad), ROM_SKIP(1) | ROM_BIOS(1))
ROMX_LOAD( "23-007e6-00.e19", 0x10000, 0x8000, CRC(d18a2ab8) SHA1(37f448a332fc50298007ed39c8bf1ab1eb6d4cae), ROM_SKIP(1) | ROM_BIOS(1))
ROMX_LOAD( "23-005e6-00.e21", 0x10001, 0x8000, CRC(558d0285) SHA1(e96a49bf9d55d8ab879d9b39aa380368c5c9ade0), ROM_SKIP(1) | ROM_BIOS(1))
ROM_SYSTEM_BIOS( 1, "vt240", "VT240 V2.2" ) // Revised version, December 1985
ROMX_LOAD( "23-058e6.e20", 0x00000, 0x8000, CRC(d2a56b90) SHA1(39cbb26134d7d8ba308df3a93228918a5945b45f), ROM_SKIP(1) | ROM_BIOS(2))
ROMX_LOAD( "23-056e6.e22", 0x00001, 0x8000, CRC(c46e13c3) SHA1(0f2801fa7483d1f97708143cd81ae0816bf9a435), ROM_SKIP(1) | ROM_BIOS(2))
ROMX_LOAD( "23-059e6.e19", 0x10000, 0x8000, CRC(f8393346) SHA1(1e28daf1b7f2bdabc47ce2f6fa99ef038b275a29), ROM_SKIP(1) | ROM_BIOS(2))
ROMX_LOAD( "23-057e6.e21", 0x10001, 0x8000, CRC(7ce9dce9) SHA1(5a105e5bdca13910b3b79cc23567ce2dc36b844d), ROM_SKIP(1) | ROM_BIOS(2))
// E39, E85, E131 are empty.
ROM_REGION( 0x1000, "proms", ROMREGION_ERASEFF )
ROM_LOAD( "23-351a1.e149", 0x0000, 0x0020, NO_DUMP) // 82s123; DRAM RAS/CAS Timing PROM
ROM_LOAD( "23-352a1.e187", 0x0020, 0x0020, NO_DUMP) // 82s123; "CT0" Timing PROM
ROM_LOAD( "23-369a1.e53", 0x0040, 0x0020, NO_DUMP) // 82s123; ROM and RAM mapping PROM
ROM_LOAD( "23-370a1.e188", 0x0060, 0x0020, NO_DUMP) // 82s123; "CT1" Timing PROM
ROM_LOAD( "23-994a9.e74", 0x0100, 0x0200, NO_DUMP) // 82s131; T11 Interrupt Encoder PROM
ROM_REGION( 0x1000, "pals", 0 )
ROM_LOAD( "23-087j5.e182.e183.jed", 0x0000, 0x1000, NO_DUMP ) // PAL16L8ACN; "Logic Unit" Character Pattern Related
ROM_END
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
COMP( 1983, vt240, 0, 0, vt240, vt240, driver_device, 0, "Digital Equipment Corporation", "VT240", MACHINE_NOT_WORKING )
//COMP( 1983, vt241, 0, 0, vt220, vt220, driver_device, 0, "Digital Equipment Corporation", "VT241", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
// NOTE: the only difference between VT240 and VT241 is the latter comes with a VR241 Color monitor, while the former comes with a mono display; the ROMs and operation are identical.
COMP( 1983, mc7105, 0, 0, mc7105, vt240, driver_device, 0, "Elektronika", "MC7105", MACHINE_NOT_WORKING )