diff options
Diffstat (limited to 'src/mame/drivers/tv990.cpp')
-rw-r--r-- | src/mame/drivers/tv990.cpp | 445 |
1 files changed, 0 insertions, 445 deletions
diff --git a/src/mame/drivers/tv990.cpp b/src/mame/drivers/tv990.cpp deleted file mode 100644 index 6544df8851d..00000000000 --- a/src/mame/drivers/tv990.cpp +++ /dev/null @@ -1,445 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:R. Belmont, Carl -/*************************************************************************** - - TeleVideo 990/995 terminal - - Driver by Carl and R. Belmont - Thanks to Al Kossow. - - H/W: - 68000-P16 CPU (clock unknown, above 10 MHz it outruns the AT keyboard controller) - 16C452 dual 16450 (PC/AT standard) UART + PC-compatible Centronics (integrated into - ASIC on 995) - AMI MEGA-KBD-H-Q PS/2 keyboard interface on 990, PS/2 8042 on 995 - Televideo ASIC marked "134446-00 TVI1111-0 427" - 3x AS7C256 (32K x 8 SRAM) - - IRQs: - 2 = PS/2 keyboard - 3 = Centronics - 4 = UART 1 - 5 = UART 0 - 6 = VBL (9003b is status, write 3 to 9003b to reset - - Video modes include 80 or 132 wide by 24, 25, 42, 43, 48, or 49 lines high plus an - optional status bar - Modes include TeleVideo 990, 950, and 955, Wyse WY-60, WY-150/120/50+/50, ANSI, - DEC VT320/220, VT100/52, SCO Console, and PC TERM. - -****************************************************************************/ - -#include "emu.h" -#include "bus/rs232/rs232.h" -#include "cpu/m68000/m68000.h" -#include "machine/8042kbdc.h" -#include "machine/ins8250.h" -#include "machine/nvram.h" -#include "machine/pc_lpt.h" -#include "sound/beep.h" -#include "emupal.h" -#include "screen.h" -#include "speaker.h" - - -#define RS232A_TAG "rs232a" -#define RS232B_TAG "rs232b" -#define LPT_TAG "lpt" - -class tv990_state : public driver_device -{ -public: - tv990_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_vram(*this, "vram"), - m_fontram(*this, "fontram"), - m_uart(*this, "ns16450_%u", 0U), - m_screen(*this, "screen"), - m_kbdc(*this, "pc_kbdc"), - m_palette(*this, "palette"), - m_beep(*this, "beep") - { - } - - void tv990(machine_config &config); - - DECLARE_INPUT_CHANGED_MEMBER(color); - -private: - required_device<m68000_device> m_maincpu; - required_shared_ptr<uint16_t> m_vram; - required_shared_ptr<uint16_t> m_fontram; - required_device_array<ns16450_device, 2> m_uart; - required_device<screen_device> m_screen; - required_device<kbdc8042_device> m_kbdc; - required_device<palette_device> m_palette; - required_device<beep_device> m_beep; - - virtual void machine_reset() override; - virtual void machine_start() override; - virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - virtual void device_post_load() override; - - uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - - DECLARE_READ16_MEMBER(tvi1111_r); - DECLARE_WRITE16_MEMBER(tvi1111_w); - DECLARE_READ8_MEMBER(kbdc_r); - DECLARE_WRITE8_MEMBER(kbdc_w); - - DECLARE_WRITE_LINE_MEMBER(uart0_irq); - DECLARE_WRITE_LINE_MEMBER(uart1_irq); - DECLARE_WRITE_LINE_MEMBER(lpt_irq); - DECLARE_WRITE_LINE_MEMBER(vblank_irq); - - void tv990_mem(address_map &map); - - uint16_t tvi1111_regs[(0x100/2)+2]; - emu_timer *m_rowtimer; - int m_rowh, m_width, m_height; -}; - -WRITE_LINE_MEMBER(tv990_state::vblank_irq) -{ - if (state) - { - m_rowtimer->adjust(m_screen->time_until_pos(m_rowh)); - m_maincpu->set_input_line(M68K_IRQ_6, ASSERT_LINE); - tvi1111_regs[0x1d] |= 4; - } -} - -void tv990_state::machine_start() -{ - m_rowtimer = timer_alloc(); - - save_item(NAME(tvi1111_regs)); - save_item(NAME(m_rowh)); - save_item(NAME(m_width)); - save_item(NAME(m_height)); -} - -void tv990_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) -{ - m_rowtimer->adjust(m_screen->time_until_pos(m_screen->vpos() + m_rowh)); - m_maincpu->set_input_line(M68K_IRQ_6, ASSERT_LINE); - m_screen->update_now(); -} - -WRITE_LINE_MEMBER(tv990_state::uart0_irq) -{ - m_maincpu->set_input_line(M68K_IRQ_5, state); -} - -WRITE_LINE_MEMBER(tv990_state::uart1_irq) -{ - m_maincpu->set_input_line(M68K_IRQ_4, state); -} - -WRITE_LINE_MEMBER(tv990_state::lpt_irq) -{ - m_maincpu->set_input_line(M68K_IRQ_3, state); -} - -READ16_MEMBER(tv990_state::tvi1111_r) -{ - if (offset == (0x32/2)) - { - tvi1111_regs[offset] |= 8; // loop at 109ca wants this set - } - else if(offset == 0x1d) - { - m_maincpu->set_input_line(M68K_IRQ_6, CLEAR_LINE); - } - - return tvi1111_regs[offset]; -} - -WRITE16_MEMBER(tv990_state::tvi1111_w) -{ -#if 0 - //if ((offset != 0x50) && (offset != 0x68) && (offset != 0x1d) && (offset != 0x1e) && (offset != 0x17) && (offset != 0x1c)) - { - if (mem_mask == 0x00ff) - { - printf("%x (%d) to ASIC @ %x (mask %04x)\n", data & 0xff, data & 0xff, offset, mem_mask); - } - else if (mem_mask == 0xff00) - { - printf("%x (%d) to ASIC @ %x (mask %04x)\n", data & 0xff, data & 0xff, offset, mem_mask); - } - else - { - printf("%x (%d) to ASIC @ %x (mask %04x)\n", data, data, offset, mem_mask); - } - } -#endif - COMBINE_DATA(&tvi1111_regs[offset]); - if((offset == 0x1c) || (offset == 0x10) || (offset == 0x9) || (offset == 0xa)) - { - m_width = BIT(tvi1111_regs[0x1c], 11) ? 132 : 80; - m_rowh = (tvi1111_regs[0x10] & 0xff) + 1; - if(!m_rowh) - m_rowh = 16; - m_height = (tvi1111_regs[0xa] - tvi1111_regs[0x9]) / m_rowh; - // m_height can be 0 or -1 while machine is starting, leading to a crash on a debug build, so we sanitise it. - if(m_height < 8 || m_height > 99) - m_height = 0x1a; - m_screen->set_visible_area(0, m_width * 16 - 1, 0, m_height * m_rowh - 1); - } - if(offset == 0x17) - m_beep->set_state(tvi1111_regs[0x17] & 4 ? ASSERT_LINE : CLEAR_LINE); -} - -uint32_t tv990_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - uint32_t *scanline; - int x, y; - uint8_t pixels, pixels2; - uint16_t *vram = (uint16_t *)m_vram.target(); - uint8_t *fontram = (uint8_t *)m_fontram.target(); - uint16_t *curchar; - uint8_t *fontptr; - int miny = cliprect.min_y / m_rowh; - int maxy = cliprect.max_y / m_rowh; - - bitmap.fill(0, cliprect); - - for (y = miny; y <= maxy; y++) - { - int i; - for(i = 7; i >= 0; i--) - { - if(!BIT(tvi1111_regs[0x1f], i)) - continue; - - int starty = tvi1111_regs[i + 0x40] >> 8; - int endy = tvi1111_regs[i + 0x40] & 0xff; - if((y < starty) || (y >= endy)) - continue; - - uint16_t row_offset = tvi1111_regs[i + 0x50]; - curchar = &vram[row_offset]; - int minx = tvi1111_regs[i + 0x30] >> 8; - int maxx = tvi1111_regs[i + 0x30] & 0xff; - - if(maxx > m_width) - maxx = m_width; - - uint16_t cursor_x = tvi1111_regs[0x16] - row_offset; - - for (x = minx; x < maxx; x++) - { - uint8_t chr = curchar[x - minx] >> 8; - uint8_t attr = curchar[x - minx] & 0xff; - if((attr & 2) && (m_screen->frame_number() & 32)) // blink rate? - continue; - - fontptr = (uint8_t *)&fontram[(chr + (attr & 0x40 ? 256 : 0)) * 64]; - - uint32_t palette[2]; - - if (BIT(tvi1111_regs[0x1b], 0) && x == cursor_x) - { - uint8_t attrchg; - if(tvi1111_regs[0x15] & 0xff00) // what does this really mean? it looks like a mask but that doesn't work in 8line char mode - attrchg = 8; - else - attrchg = 4; - if(!BIT(tvi1111_regs[0x1b], 1)) - attr ^= attrchg; - else if(m_screen->frame_number() & 32) - attr ^= attrchg; - } - - if (attr & 0x4) // inverse video? - { - palette[1] = m_palette->pen(0); - palette[0] = (attr & 0x10) ? m_palette->pen(1) : m_palette->pen(2); - } - else - { - palette[0] = m_palette->pen(0); - palette[1] = (attr & 0x10) ? m_palette->pen(1) : m_palette->pen(2); - } - - for (int chary = 0; chary < m_rowh; chary++) - { - scanline = &bitmap.pix32((y*m_rowh)+chary, (x*16)); - - pixels = *fontptr++; - pixels2 = *fontptr++; - if((attr & 0x8) && (chary == m_rowh - 1)) - { - pixels = 0xff; - pixels2 = 0xff; - } - - *scanline++ = palette[(pixels>>7)&1]; - *scanline++ = palette[(pixels2>>7)&1]; - *scanline++ = palette[(pixels>>6)&1]; - *scanline++ = palette[(pixels2>>6)&1]; - *scanline++ = palette[(pixels>>5)&1]; - *scanline++ = palette[(pixels2>>5)&1]; - *scanline++ = palette[(pixels>>4)&1]; - *scanline++ = palette[(pixels2>>4)&1]; - *scanline++ = palette[(pixels>>3)&1]; - *scanline++ = palette[(pixels2>>3)&1]; - *scanline++ = palette[(pixels>>2)&1]; - *scanline++ = palette[(pixels2>>2)&1]; - *scanline++ = palette[(pixels>>1)&1]; - *scanline++ = palette[(pixels2>>1)&1]; - *scanline++ = palette[(pixels&1)]; - *scanline++ = palette[(pixels2&1)]; - } - } - } - } - - return 0; -} - -READ8_MEMBER(tv990_state::kbdc_r) -{ - if(offset) - return m_kbdc->data_r(space, 4); - else - return m_kbdc->data_r(space, 0); -} - -WRITE8_MEMBER(tv990_state::kbdc_w) -{ - if(offset) - m_kbdc->data_w(space, 4, data); - else - m_kbdc->data_w(space, 0, data); -} - -void tv990_state::tv990_mem(address_map &map) -{ - map(0x000000, 0x03ffff).rom().region("maincpu", 0); - map(0x060000, 0x06ffff).ram().share("vram"); // character/attribute RAM - map(0x080000, 0x087fff).ram().share("fontram"); // font RAM - map(0x090000, 0x0900ff).rw(FUNC(tv990_state::tvi1111_r), FUNC(tv990_state::tvi1111_w)); - map(0x0a0000, 0x0a000f).rw(m_uart[0], FUNC(ns16450_device::ins8250_r), FUNC(ns16450_device::ins8250_w)).umask16(0x00ff); - map(0x0a0010, 0x0a001f).rw(m_uart[1], FUNC(ns16450_device::ins8250_r), FUNC(ns16450_device::ins8250_w)).umask16(0x00ff); - map(0x0a0028, 0x0a002d).rw(LPT_TAG, FUNC(pc_lpt_device::read), FUNC(pc_lpt_device::write)).umask16(0x00ff); - map(0x0b0000, 0x0b0003).rw(FUNC(tv990_state::kbdc_r), FUNC(tv990_state::kbdc_w)).umask16(0x00ff); - map(0x0c0000, 0x0c7fff).ram().share("nvram");// work RAM -} - -/* Input ports */ -static INPUT_PORTS_START( tv990 ) - PORT_INCLUDE( at_keyboard ) - PORT_START("Screen") - PORT_CONFNAME( 0x30, 0x00, "Color") PORT_CHANGED_MEMBER(DEVICE_SELF, tv990_state, color, 0) - PORT_CONFSETTING( 0x00, "Green") - PORT_CONFSETTING( 0x10, "Amber") - PORT_CONFSETTING( 0x20, "White") -INPUT_PORTS_END - -INPUT_CHANGED_MEMBER(tv990_state::color) -{ - rgb_t color; - if(newval == oldval) - return; - - switch(newval) - { - case 0: - default: - color = rgb_t::green(); - break; - case 1: - color = rgb_t::amber(); - break; - case 2: - color = rgb_t::white(); - break; - } - m_screen->set_color(color); -} - -void tv990_state::machine_reset() -{ - m_rowtimer->adjust(m_screen->time_until_pos(0)); - - memset(tvi1111_regs, 0, sizeof(tvi1111_regs)); - m_rowh = 16; - m_width = 80; - m_height = 50; -} - -void tv990_state::device_post_load() -{ - m_screen->set_visible_area(0, m_width * 16 - 1, 0, m_height * m_rowh - 1); -} - -void tv990_state::tv990(machine_config &config) -{ - /* basic machine hardware */ - M68000(config, m_maincpu, 14967500); // verified (59.86992/4) - m_maincpu->set_addrmap(AS_PROGRAM, &tv990_state::tv990_mem); - - SCREEN(config, m_screen, SCREEN_TYPE_RASTER); - m_screen->set_color(rgb_t::green()); - m_screen->set_screen_update(FUNC(tv990_state::screen_update)); - m_screen->set_size(132*16, 50*16); - m_screen->set_visarea(0, (80*16)-1, 0, (50*16)-1); - m_screen->set_refresh_hz(60); - m_screen->screen_vblank().set(FUNC(tv990_state::vblank_irq)); - - PALETTE(config, m_palette, palette_device::MONOCHROME_HIGHLIGHT); - - NS16450(config, m_uart[0], 3.6864_MHz_XTAL); - m_uart[0]->out_dtr_callback().set(RS232A_TAG, FUNC(rs232_port_device::write_dtr)); - m_uart[0]->out_rts_callback().set(RS232A_TAG, FUNC(rs232_port_device::write_rts)); - m_uart[0]->out_tx_callback().set(RS232A_TAG, FUNC(rs232_port_device::write_txd)); - m_uart[0]->out_int_callback().set(FUNC(tv990_state::uart0_irq)); - - NS16450(config, m_uart[1], 3.6864_MHz_XTAL); - m_uart[1]->out_dtr_callback().set(RS232B_TAG, FUNC(rs232_port_device::write_dtr)); - m_uart[1]->out_rts_callback().set(RS232B_TAG, FUNC(rs232_port_device::write_rts)); - m_uart[1]->out_tx_callback().set(RS232B_TAG, FUNC(rs232_port_device::write_txd)); - m_uart[1]->out_int_callback().set(FUNC(tv990_state::uart1_irq)); - - pc_lpt_device &lpt(PC_LPT(config, LPT_TAG)); - lpt.irq_handler().set(FUNC(tv990_state::lpt_irq)); - - rs232_port_device &rs232a(RS232_PORT(config, RS232A_TAG, default_rs232_devices, nullptr)); - rs232a.rxd_handler().set(m_uart[0], FUNC(ns16450_device::rx_w)); - rs232a.dcd_handler().set(m_uart[0], FUNC(ns16450_device::dcd_w)); - rs232a.cts_handler().set(m_uart[0], FUNC(ns16450_device::cts_w)); - - rs232_port_device &rs232b(RS232_PORT(config, RS232B_TAG, default_rs232_devices, nullptr)); - rs232b.rxd_handler().set(m_uart[1], FUNC(ns16450_device::rx_w)); - rs232b.dcd_handler().set(m_uart[1], FUNC(ns16450_device::dcd_w)); - rs232b.cts_handler().set(m_uart[1], FUNC(ns16450_device::cts_w)); - - KBDC8042(config, m_kbdc); - m_kbdc->set_keyboard_type(kbdc8042_device::KBDC8042_STANDARD); - m_kbdc->input_buffer_full_callback().set_inputline("maincpu", M68K_IRQ_2); - - NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); - - SPEAKER(config, "mono").front_center(); - BEEP(config, "beep", 1000).add_route(ALL_OUTPUTS, "mono", 1.0); //whats the freq? -} - -/* ROM definition */ -ROM_START( tv990 ) - ROM_REGION( 0x40000, "maincpu", 0 ) - ROM_LOAD16_BYTE( "180003-89_u3.bin", 0x000000, 0x010000, CRC(0465fc55) SHA1(b8874ce54bf2bf4f77664194d2f23c0e4e6ccbe9) ) - ROM_LOAD16_BYTE( "180003-90_u4.bin", 0x000001, 0x010000, CRC(fad7d77d) SHA1(f1114a4a07c8b4ffa0323a2e7ce03d82a386f7d3) ) -ROM_END - -ROM_START( tv995 ) - ROM_REGION( 0x40000, "maincpu", 0 ) - ROM_LOAD16_BYTE( "995-65_u3.bin", 0x000000, 0x020000, CRC(2d71b6fe) SHA1(a2a3406c19308eb9232db319ea8f151949b2ac74) ) - ROM_LOAD16_BYTE( "995-65_u4.bin", 0x000001, 0x020000, CRC(dc002af2) SHA1(9608e7a729c5ac0fc58f673eaf441d2f4f591ec6) ) -ROM_END - -/* Driver */ -COMP( 1992, tv990, 0, 0, tv990, tv990, tv990_state, empty_init, "TeleVideo", "TeleVideo 990", MACHINE_SUPPORTS_SAVE ) -COMP( 1994, tv995, 0, 0, tv990, tv990, tv990_state, empty_init, "TeleVideo", "TeleVideo 995-65", MACHINE_SUPPORTS_SAVE ) |