diff options
Diffstat (limited to 'src/mame/drivers/tabe22.cpp')
-rw-r--r-- | src/mame/drivers/tabe22.cpp | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/src/mame/drivers/tabe22.cpp b/src/mame/drivers/tabe22.cpp new file mode 100644 index 00000000000..35524d15c9e --- /dev/null +++ b/src/mame/drivers/tabe22.cpp @@ -0,0 +1,326 @@ +// license: BSD-3-Clause +// copyright-holders: AJR, Dirk Best +/*************************************************************************** + + Tab Products "E22" Terminal + + VT52/VT100/VT220 + + Hardware: + - P8085AH + - SCN2674B with SCB2675T + - SCN2681 + - P8251A + - 3x HM6264LP-12 (8k) + - 3x HM6116LP-2 (2k) + - XTAL: 3.6864 MHz, 10.0000 MHz, 21.7566 MHz, 35.8344 MHz + + TODO: + - Dump keyboard controller and emulate it (currently HLE'd) + - NVRAM / memory layout + - Needs a hack to send out data on the RS232 port: + Set $f7a3 = 0 after startup + + Notes: + - The hardware has some similarities to cit220.cpp + - Everything here is guessed (including the system name), no docs available + +***************************************************************************/ + +#include "emu.h" +#include "cpu/i8085/i8085.h" +#include "machine/bankdev.h" +#include "machine/e22_kbd.h" +#include "machine/i8251.h" +#include "machine/mc68681.h" +#include "machine/nvram.h" +#include "video/scn2674.h" +#include "bus/rs232/rs232.h" +#include "bus/rs232/printer.h" +#include "emupal.h" +#include "screen.h" + + +namespace { + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class tabe22_state : public driver_device +{ +public: + tabe22_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_screen(*this, "screen"), + m_palette(*this, "palette"), + m_avdc(*this, "avdc"), + m_chargen(*this, "chargen"), + m_vram_bank(*this, "vrambank") + { } + + void tabe22(machine_config &config); + +protected: + virtual void machine_start() override; + +private: + void mem_map(address_map &map); + void io_map(address_map &map); + void vram_map(address_map &map); + + void char_map(address_map &map); + void attr_map(address_map &map); + + required_device<i8085a_cpu_device> m_maincpu; + required_device<screen_device> m_screen; + required_device<palette_device> m_palette; + required_device<scn2674_device> m_avdc; + required_region_ptr<uint8_t> m_chargen; + optional_device<address_map_bank_device> m_vram_bank; + + void video_ctrl_w(uint8_t data); + void crt_brightness_w(uint8_t data); + SCN2674_DRAW_CHARACTER_MEMBER(draw_character); + void palette(palette_device &palette) const; + + bool m_screen_light; +}; + + +//************************************************************************** +// ADDRESS MAPS +//************************************************************************** + +void tabe22_state::mem_map(address_map &map) +{ + map(0x0000, 0xbfff).rom().region("maincpu", 0); + map(0xc000, 0xcfff).rw(m_vram_bank, FUNC(address_map_bank_device::read8), FUNC(address_map_bank_device::write8)); + map(0xd000, 0xdfff).ram(); + map(0xe000, 0xffff).ram(); +} + +void tabe22_state::vram_map(address_map &map) +{ + map(0x0000, 0x0fff).ram().share("charram"); + map(0x1000, 0x1fff).ram().share("attrram"); +} + +void tabe22_state::io_map(address_map &map) +{ + map(0x00, 0x0f).rw("duart", FUNC(scn2681_device::read), FUNC(scn2681_device::write)); + map(0x20, 0x27).rw(m_avdc, FUNC(scn2674_device::read), FUNC(scn2674_device::write)); + map(0x40, 0x41).rw("usart", FUNC(i8251_device::read), FUNC(i8251_device::write)); + map(0x60, 0x60).w(FUNC(tabe22_state::video_ctrl_w)); + map(0x61, 0x61).w(FUNC(tabe22_state::crt_brightness_w)); +} + + +//************************************************************************** +// VIDEO EMULATION +//************************************************************************** + +void tabe22_state::char_map(address_map &map) +{ + map(0x0000, 0x0fff).ram().share("charram"); +} + +void tabe22_state::attr_map(address_map &map) +{ + map(0x0000, 0x0fff).ram().share("attrram"); +} + +void tabe22_state::video_ctrl_w(uint8_t data) +{ + // 7------- unknown + // -6------ screen light/dark + // --5----- char ram/attribute ram switch + // ---4---- unknown + // ----3--- 80/132 col switch + // -----210 unknown + + m_screen_light = bool(BIT(data, 6)); + m_vram_bank->set_bank(BIT(data, 5)); + m_avdc->set_unscaled_clock(BIT(data, 3) ? 35.8344_MHz_XTAL / 9 : 21.7566_MHz_XTAL / 9); +} + +void tabe22_state::crt_brightness_w(uint8_t data) +{ + // unknown algorithm for the brightness + // default value is 7, range is 15 (off) to 0 (brightest) + m_screen->set_brightness(0xff - ((data & 0x0f) * 6)); +} + +SCN2674_DRAW_CHARACTER_MEMBER( tabe22_state::draw_character ) +{ + uint16_t data = m_chargen[charcode << 4 | linecount] << 2; + const pen_t *const pen = m_palette->pens(); + + // 76------ unknown + // --5----- shaded + // ---4---- unknown + // ----3--- bold + // -----2-- blink + // ------1- underline + // -------0 reverse + + if (ul && (BIT(attrcode, 1))) + data = 0x1ff; + + if (blink && (BIT(attrcode, 2))) + data = 0x000; + + if (BIT(attrcode, 0)) + data = ~data; + + if (cursor) + data = ~data; + + // foreground/background colors + rgb_t fg = BIT(attrcode, 5) ? pen[1] : BIT(attrcode, 3) ? pen[3] : pen[2]; + rgb_t bg = m_screen_light ? pen[1] : pen[0]; + + // draw 9 pixels of the character + for (int i = 0; i < 9; i++) + bitmap.pix(y, x + i) = BIT(data, 8 - i) ? fg : bg; +} + +static const gfx_layout char_layout = +{ + 8,16, + RGN_FRAC(1,1), + 1, + { 0 }, + { STEP8(0,1) }, + { STEP16(0,8) }, + 8*16 +}; + +static GFXDECODE_START(chars) + GFXDECODE_ENTRY("chargen", 0, char_layout, 0, 1) +GFXDECODE_END + +void tabe22_state::palette(palette_device &palette) const +{ + static constexpr rgb_t pens[4] = + { + { 0x00, 0x00, 0x00 }, // black + { 0x7f, 0x7f, 0x7f }, // gray + { 0xcf, 0xcf, 0xcf }, // white + { 0xff, 0xff, 0xff }, // highlight + }; + + palette.set_pen_colors(0, pens); +} + + +//************************************************************************** +// MACHINE EMULATION +//************************************************************************** + +void tabe22_state::machine_start() +{ + // register for save states + save_item(NAME(m_screen_light)); +} + + +//************************************************************************** +// MACHINE DEFINTIONS +//************************************************************************** + +void printer_devices(device_slot_interface &device) +{ + device.option_add("printer", SERIAL_PRINTER); +} + +static DEVICE_INPUT_DEFAULTS_START( printer_defaults ) + DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_4800 ) + DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_4800 ) + DEVICE_INPUT_DEFAULTS( "RS232_STARTBITS", 0xff, RS232_STARTBITS_1 ) + DEVICE_INPUT_DEFAULTS( "RS232_DATABITS", 0xff, RS232_DATABITS_7 ) + DEVICE_INPUT_DEFAULTS( "RS232_PARITY", 0xff, RS232_PARITY_ODD ) + DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_1 ) +DEVICE_INPUT_DEFAULTS_END + +void tabe22_state::tabe22(machine_config &config) +{ + I8085A(config, m_maincpu, 10_MHz_XTAL); + m_maincpu->set_addrmap(AS_PROGRAM, &tabe22_state::mem_map); + m_maincpu->set_addrmap(AS_IO, &tabe22_state::io_map); + + ADDRESS_MAP_BANK(config, m_vram_bank, 0); + m_vram_bank->set_map(&tabe22_state::vram_map); + m_vram_bank->set_addr_width(13); + m_vram_bank->set_data_width(8); + m_vram_bank->set_stride(0x1000); + +// NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); + + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_color(rgb_t::amber()); + m_screen->set_raw(21.7566_MHz_XTAL, 918, 0, 720, 395, 0, 378); // 80 column mode +// m_screen->set_raw(35.8344_MHz_XTAL, 1494, 0, 1188, 395, 0, 378); // 132 column mode + m_screen->set_screen_update(m_avdc, FUNC(scn2674_device::screen_update)); + + PALETTE(config, m_palette, FUNC(tabe22_state::palette), 4); + + GFXDECODE(config, "gfxdecode", m_palette, chars); + + SCN2674(config, m_avdc, 21.7566_MHz_XTAL / 9); + m_avdc->intr_callback().set_inputline(m_maincpu, I8085_RST75_LINE); + m_avdc->set_character_width(9); + m_avdc->set_display_callback(FUNC(tabe22_state::draw_character)); + m_avdc->set_addrmap(0, &tabe22_state::char_map); + m_avdc->set_addrmap(1, &tabe22_state::attr_map); + m_avdc->set_screen("screen"); + + scn2681_device &duart(SCN2681(config, "duart", 3.6864_MHz_XTAL)); + duart.irq_cb().set_inputline(m_maincpu, I8085_RST65_LINE); + duart.a_tx_cb().set("printer", FUNC(rs232_port_device::write_txd)); + duart.b_tx_cb().set("host", FUNC(rs232_port_device::write_txd)); + duart.outport_cb().set("usart", FUNC(i8251_device::write_txc)).bit(3); + duart.outport_cb().append("usart", FUNC(i8251_device::write_rxc)).bit(3); + + rs232_port_device &rs232_host(RS232_PORT(config, "host", default_rs232_devices, nullptr)); + rs232_host.rxd_handler().set("duart", FUNC(scn2681_device::rx_b_w)); + rs232_host.cts_handler().set("duart", FUNC(scn2681_device::ip1_w)); + + rs232_port_device &rs232_printer(RS232_PORT(config, "printer", printer_devices, nullptr)); + rs232_printer.set_option_device_input_defaults("printer", DEVICE_INPUT_DEFAULTS_NAME(printer_defaults)); + + i8251_device &usart(I8251(config, "usart", 10_MHz_XTAL / 4)); // divider guessed + usart.rxrdy_handler().set_inputline(m_maincpu, I8085_RST55_LINE); + usart.txd_handler().set("kbd", FUNC(e22_kbd_hle_device::rx_w)); + + e22_kbd_hle_device &kbd(E22_KBD_HLE(config, "kbd")); + kbd.tx_handler().set("usart", FUNC(i8251_device::write_rxd)); + kbd.cts_handler().set("usart", FUNC(i8251_device::write_cts)); +} + + +//************************************************************************** +// ROM DEFINITIONS +//************************************************************************** + +ROM_START(tabe22) + ROM_REGION(0xc000, "maincpu", 0) + ROM_LOAD("e22_u3__2.17.86__v2.00.bin", 0x0000, 0x8000, CRC(fd931bc5) SHA1(013d5a5ed759bb9684bff18a3e848fa6d1167e10)) + ROM_LOAD("e22_u2__2.17.86__v2.00.bin", 0x8000, 0x4000, CRC(45d5e895) SHA1(a2b4e04dbc881230462a38de98ed843d5683c1b9)) + + ROM_REGION(0x2000, "chargen", 0) + ROM_LOAD("e22_u43__char_gen.bin", 0x0000, 0x2000, CRC(33880908) SHA1(7f26dede2feaf3591312d67e3dabfc1ad8bb3181)) +ROM_END + + +} // anonymous namespace + + +//************************************************************************** +// SYSTEM DRIVERS +//************************************************************************** + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1986, tabe22, 0, 0, tabe22, 0, tabe22_state, empty_init, "Tab Products", "E-22 Display Terminal", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) |