summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/tm990189.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/tm990189.cpp')
-rw-r--r--src/mame/drivers/tm990189.cpp1086
1 files changed, 0 insertions, 1086 deletions
diff --git a/src/mame/drivers/tm990189.cpp b/src/mame/drivers/tm990189.cpp
deleted file mode 100644
index b27d7907ecc..00000000000
--- a/src/mame/drivers/tm990189.cpp
+++ /dev/null
@@ -1,1086 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Raphael Nabet, Robbbert
-/*
- Experimental tm990/189 ("University Module") driver.
-
- The tm990/189 is a simple board built around a tms9980 at 2.0 MHz.
- The board features:
- * a calculator-like alphanumeric keyboard, a 10-digit 8-segment display,
- a sound buzzer and 4 status LEDs
- * a 4kb ROM socket (0x3000-0x3fff), and a 2kb ROM socket (0x0800-0x0fff)
- * 1kb of RAM expandable to 2kb (0x0000-0x03ff and 0x0400-0x07ff)
- * a tms9901 controlling a custom parallel I/O port (available for
- expansion)
- * an optional on-board serial interface (either TTY or RS232): TI ROMs
- support a terminal connected to this port
- * an optional tape interface
- * an optional bus extension port for adding additional custom devices (TI
- sold a video controller expansion built around a tms9918, which was
- supported by University Basic)
-
- One tms9901 is set up so that it handles tms9980 interrupts. The other
- tms9901, the tms9902, and extension cards can trigger interrupts on the
- interrupt-handling tms9901.
-
- TI sold two ROM sets for this machine: a monitor and assembler ("UNIBUG",
- packaged as one 4kb EPROM) and a Basic interpreter ("University BASIC",
- packaged as a 4kb and a 2kb EPROM). Users could burn and install custom
- ROM sets, too.
-
- This board was sold to universities to learn either assembly language or
- BASIC programming.
-
- A few hobbyists may have bought one of these, too. This board can actually
- be used as a development kit for the tms9980, but it was not supported as
- such (there was no EPROM programmer or mass storage system for the
- tm990/189, though you could definitively design your own and attach them to
- the extension port).
-
- - Raphael Nabet 2003
-
- Bug - The input buffer of character segments isn't fully cleared. If you
- press Shift, then Z enough times, garbage appears. This is because
- the boot process should have set 18C-1CB to FF, but only sets up to 1B3.
-
- Need a dump of the UNIBUG rom.
-
- Demo programs for the 990189v: You can get impressive colour displays (with
- sprites) from the 4 included demos. Press the Enter key after each instruction,
- and wait for the READY prompt before proceeding to the next.
-
- NEW
- LOADx (where x = 0,1,2,3)
- RUN
-
- University BASIC fully supports the tms9918 videocard option. For example, enter
- COLOR x (where x = 1 to 15), to get a coloured background.
-
- - Robbbert 2011
-
-******************************************************************************************/
-
-#include "emu.h"
-
-#include "cpu/tms9900/tms9980a.h"
-#include "imagedev/cassette.h"
-#include "machine/timer.h"
-#include "machine/tms9901.h"
-#include "machine/tms9902.h"
-#include "sound/spkrdev.h"
-#include "video/tms9928a.h"
-
-#include "speaker.h"
-
-#include "tm990189.lh"
-#include "tm990189v.lh"
-
-
-#define TMS9901_0_TAG "tms9901_usr"
-#define TMS9901_1_TAG "tms9901_sys"
-
-class tm990189_state : public driver_device
-{
- friend class tm990_189_rs232_image_device;
-
-public:
- tm990189_state(const machine_config &mconfig, device_type type, const char *tag)
- : driver_device(mconfig, type, tag)
- , m_tms9980a(*this, "maincpu")
- , m_speaker(*this, "speaker")
- , m_cass(*this, "cassette")
- , m_tms9918(*this, "tms9918")
- , m_tms9901_usr(*this, TMS9901_0_TAG)
- , m_tms9901_sys(*this, TMS9901_1_TAG)
- , m_tms9902(*this, "tms9902")
- , m_digits(*this, "digit%u", 0U)
- { }
-
- void tm990_189_v(machine_config &config);
- void tm990_189(machine_config &config);
-
- DECLARE_INPUT_CHANGED_MEMBER( load_interrupt );
-
-private:
- DECLARE_READ8_MEMBER(video_vdp_r);
- DECLARE_WRITE8_MEMBER(video_vdp_w);
- DECLARE_READ8_MEMBER(video_joy_r);
- DECLARE_WRITE8_MEMBER(video_joy_w);
-
- DECLARE_WRITE8_MEMBER( external_operation );
-
- DECLARE_WRITE_LINE_MEMBER(usr9901_led0_w);
- DECLARE_WRITE_LINE_MEMBER(usr9901_led1_w);
- DECLARE_WRITE_LINE_MEMBER(usr9901_led2_w);
- DECLARE_WRITE_LINE_MEMBER(usr9901_led3_w);
- DECLARE_WRITE_LINE_MEMBER(usr9901_interrupt_callback);
-
- DECLARE_WRITE_LINE_MEMBER(sys9901_interrupt_callback);
- DECLARE_READ8_MEMBER(sys9901_r);
- DECLARE_WRITE_LINE_MEMBER(sys9901_digitsel0_w);
- DECLARE_WRITE_LINE_MEMBER(sys9901_digitsel1_w);
- DECLARE_WRITE_LINE_MEMBER(sys9901_digitsel2_w);
- DECLARE_WRITE_LINE_MEMBER(sys9901_digitsel3_w);
-
- DECLARE_WRITE_LINE_MEMBER(sys9901_segment0_w);
- DECLARE_WRITE_LINE_MEMBER(sys9901_segment1_w);
- DECLARE_WRITE_LINE_MEMBER(sys9901_segment2_w);
- DECLARE_WRITE_LINE_MEMBER(sys9901_segment3_w);
- DECLARE_WRITE_LINE_MEMBER(sys9901_segment4_w);
- DECLARE_WRITE_LINE_MEMBER(sys9901_segment5_w);
- DECLARE_WRITE_LINE_MEMBER(sys9901_segment6_w);
- DECLARE_WRITE_LINE_MEMBER(sys9901_segment7_w);
-
- DECLARE_WRITE_LINE_MEMBER(sys9901_dsplytrgr_w);
- DECLARE_WRITE_LINE_MEMBER(sys9901_shiftlight_w);
- DECLARE_WRITE_LINE_MEMBER(sys9901_spkrdrive_w);
- DECLARE_WRITE_LINE_MEMBER(sys9901_tapewdata_w);
-
- DECLARE_WRITE8_MEMBER( xmit_callback );
- DECLARE_MACHINE_START(tm990_189);
- DECLARE_MACHINE_RESET(tm990_189);
- DECLARE_MACHINE_START(tm990_189_v);
- DECLARE_MACHINE_RESET(tm990_189_v);
-
- emu_timer *m_rs232_input_timer;
-
- void tm990_189_cru_map(address_map &map);
- void tm990_189_memmap(address_map &map);
- void tm990_189_v_memmap(address_map &map);
-
- void draw_digit(void);
- void led_set(int number, bool state);
- void segment_set(int offset, bool state);
- void digitsel(int offset, bool state);
-
- TIMER_DEVICE_CALLBACK_MEMBER(display_callback);
- TIMER_CALLBACK_MEMBER(clear_load);
- void hold_load();
-
- required_device<tms9980a_device> m_tms9980a;
- required_device<speaker_sound_device> m_speaker;
- required_device<cassette_image_device> m_cass;
- optional_device<tms9918_device> m_tms9918;
-
- required_device<tms9901_device> m_tms9901_usr;
- required_device<tms9901_device> m_tms9901_sys;
- required_device<tms9902_device> m_tms9902;
- output_finder<10> m_digits;
-
- int m_load_state;
-
- int m_digitsel;
- int m_segment;
- emu_timer *m_displayena_timer;
- uint8_t m_segment_state[10];
- uint8_t m_old_segment_state[10];
- uint8_t m_LED_state;
- emu_timer *m_joy1x_timer;
- emu_timer *m_joy1y_timer;
- emu_timer *m_joy2x_timer;
- emu_timer *m_joy2y_timer;
- device_image_interface *m_rs232_fp;
- //uint8_t m_rs232_rts;
- uint8_t m_bogus_read_save;
-};
-
-
-#define displayena_duration attotime::from_usec(4500) /* Can anyone confirm this? 74LS123 connected to C=0.1uF and R=100kOhm */
-
-MACHINE_RESET_MEMBER(tm990189_state,tm990_189)
-{
- m_tms9980a->set_ready(ASSERT_LINE);
- m_tms9980a->set_hold(CLEAR_LINE);
- hold_load();
-}
-
-MACHINE_START_MEMBER(tm990189_state,tm990_189)
-{
- m_digits.resolve();
- m_displayena_timer = machine().scheduler().timer_alloc(timer_expired_delegate());
-}
-
-MACHINE_START_MEMBER(tm990189_state,tm990_189_v)
-{
- m_digits.resolve();
- m_displayena_timer = machine().scheduler().timer_alloc(timer_expired_delegate());
-
- m_joy1x_timer = machine().scheduler().timer_alloc(timer_expired_delegate());
- m_joy1y_timer = machine().scheduler().timer_alloc(timer_expired_delegate());
- m_joy2x_timer = machine().scheduler().timer_alloc(timer_expired_delegate());
- m_joy2y_timer = machine().scheduler().timer_alloc(timer_expired_delegate());
-}
-
-MACHINE_RESET_MEMBER(tm990189_state,tm990_189_v)
-{
- m_tms9980a->set_ready(ASSERT_LINE);
- m_tms9980a->set_hold(CLEAR_LINE);
- hold_load();
-}
-
-/*
- hold and debounce load line (emulation is inaccurate)
-*/
-
-TIMER_CALLBACK_MEMBER(tm990189_state::clear_load)
-{
- m_load_state = false;
- m_tms9980a->set_input_line(INT_9980A_LOAD, CLEAR_LINE);
-}
-
-void tm990189_state::hold_load()
-{
- m_load_state = true;
- m_tms9980a->set_input_line(INT_9980A_LOAD, ASSERT_LINE);
- machine().scheduler().timer_set(attotime::from_msec(100), timer_expired_delegate(FUNC(tm990189_state::clear_load),this));
-}
-
-/*
- LOAD interrupt switch
-*/
-INPUT_CHANGED_MEMBER( tm990189_state::load_interrupt )
-{
- // When depressed, fire LOAD (neg logic)
- if (newval==CLEAR_LINE) hold_load();
-}
-
-
-/*
- tm990_189 video emulation.
-
- Has an integrated 10 digit 8-segment display.
- Supports EIA and TTY terminals, and an optional 9918 controller.
-*/
-
-void tm990189_state::draw_digit()
-{
- m_segment_state[m_digitsel] |= ~m_segment;
-}
-
-
-TIMER_DEVICE_CALLBACK_MEMBER(tm990189_state::display_callback)
-{
- uint8_t i;
- char ledname[8];
- // since the segment data is cleared after being used, the old_segment is there
- // in case the segment data hasn't been refreshed yet.
- for (i = 0; i < 10; i++)
- {
- m_old_segment_state[i] |= m_segment_state[i];
- m_digits[i] = m_old_segment_state[i];
- m_old_segment_state[i] = m_segment_state[i];
- m_segment_state[i] = 0;
- }
-
- for (i = 0; i < 7; i++)
- {
- sprintf(ledname,"led%d",i);
- output().set_value(ledname, !BIT(m_LED_state, i));
- }
-}
-
-/*
- tms9901 code
-*/
-
-WRITE_LINE_MEMBER( tm990189_state::usr9901_interrupt_callback )
-{
- // Triggered by internal timer (set by ROM to 1.6 ms cycle) on level 3
- // or by keyboard interrupt (level 6)
- if (!m_load_state)
- {
- m_tms9980a->set_input_line(m_tms9901_usr->get_int_level() & 7, ASSERT_LINE);
- }
-}
-
-void tm990189_state::led_set(int offset, bool state)
-{
- if (state)
- m_LED_state |= (1 << offset);
- else
- m_LED_state &= ~(1 << offset);
-}
-
-WRITE_LINE_MEMBER( tm990189_state::usr9901_led0_w )
-{
- led_set(0, state);
-}
-
-WRITE_LINE_MEMBER( tm990189_state::usr9901_led1_w )
-{
- led_set(1, state);
-}
-
-WRITE_LINE_MEMBER( tm990189_state::usr9901_led2_w )
-{
- led_set(2, state);
-}
-
-WRITE_LINE_MEMBER( tm990189_state::usr9901_led3_w )
-{
- led_set(3, state);
-}
-
-WRITE_LINE_MEMBER( tm990189_state::sys9901_interrupt_callback )
-{
- // TODO: Check this
- m_tms9901_usr->set_int_line(5, state);
-}
-
-READ8_MEMBER( tm990189_state::sys9901_r )
-{
- // |-|Cass|K|K|K|K|K|C|
- static const char *const keynames[] = { "LINE0", "LINE1", "LINE2", "LINE3", "LINE4", "LINE5", "LINE6", "LINE7", "LINE8" };
-
- offset &= 0x0F;
- switch (offset)
- {
- case tms9901_device::INT1:
- case tms9901_device::INT2:
- case tms9901_device::INT3:
- case tms9901_device::INT4:
- case tms9901_device::INT5:
- if (m_digitsel < 9)
- return BIT(ioport(keynames[m_digitsel])->read(), offset-tms9901_device::INT1);
- else return 0;
-
- case tms9901_device::INT6:
- return (m_cass->input() > 0);
- default:
- return 0;
- }
-}
-
-/*
- uint8_t data = 0;
- if (offset == tms9901_device::CB_INT7)
- {
- static const char *const keynames[] = { "LINE0", "LINE1", "LINE2", "LINE3", "LINE4", "LINE5", "LINE6", "LINE7", "LINE8" };
- // keyboard read
- if (m_digitsel < 9)
- data |= ioport(keynames[m_digitsel])->read() << 1;
- // tape input
- if (m_cass->input() > 0.0)
- data |= 0x40;
- }
- return data;
-*/
-
-void tm990189_state::digitsel(int offset, bool state)
-{
- if (state)
- m_digitsel |= 1 << offset;
- else
- m_digitsel &= ~ (1 << offset);
-}
-
-WRITE_LINE_MEMBER( tm990189_state::sys9901_digitsel0_w )
-{
- digitsel(0, state);
-}
-WRITE_LINE_MEMBER( tm990189_state::sys9901_digitsel1_w )
-{
- digitsel(1, state);
-}
-WRITE_LINE_MEMBER( tm990189_state::sys9901_digitsel2_w )
-{
- digitsel(2, state);
-}
-WRITE_LINE_MEMBER( tm990189_state::sys9901_digitsel3_w )
-{
- digitsel(3, state);
-}
-
-
-void tm990189_state::segment_set(int offset, bool state)
-{
- if (state)
- m_segment |= 1 << offset;
- else
- {
- m_segment &= ~ (1 << offset);
- if ((m_displayena_timer->remaining() > attotime::zero) && (m_digitsel < 10))
- draw_digit();
- }
-}
-
-WRITE_LINE_MEMBER( tm990189_state::sys9901_segment0_w )
-{
- segment_set(0, state);
-}
-WRITE_LINE_MEMBER( tm990189_state::sys9901_segment1_w )
-{
- segment_set(1, state);
-}
-WRITE_LINE_MEMBER( tm990189_state::sys9901_segment2_w )
-{
- segment_set(2, state);
-}
-WRITE_LINE_MEMBER( tm990189_state::sys9901_segment3_w )
-{
- segment_set(3, state);
-}
-WRITE_LINE_MEMBER( tm990189_state::sys9901_segment4_w )
-{
- segment_set(4, state);
-}
-WRITE_LINE_MEMBER( tm990189_state::sys9901_segment5_w )
-{
- segment_set(5, state);
-}
-WRITE_LINE_MEMBER( tm990189_state::sys9901_segment6_w )
-{
- segment_set(6, state);
-}
-WRITE_LINE_MEMBER( tm990189_state::sys9901_segment7_w )
-{
- segment_set(7, state);
-}
-
-WRITE_LINE_MEMBER( tm990189_state::sys9901_dsplytrgr_w )
-{
- if ((!state) && (m_digitsel < 10))
- {
- m_displayena_timer->reset(displayena_duration);
- draw_digit();
- }
-}
-
-WRITE_LINE_MEMBER( tm990189_state::sys9901_shiftlight_w )
-{
- if (state)
- m_LED_state |= 0x10;
- else
- m_LED_state &= ~0x10;
-}
-
-WRITE_LINE_MEMBER( tm990189_state::sys9901_spkrdrive_w )
-{
- m_speaker->level_w(state);
-}
-
-WRITE_LINE_MEMBER( tm990189_state::sys9901_tapewdata_w )
-{
- m_cass->output(state ? +1.0 : -1.0);
-}
-
-class tm990_189_rs232_image_device : public device_t, public device_image_interface
-{
-public:
- // construction/destruction
- template <typename T> tm990_189_rs232_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&tms_tag)
- : tm990_189_rs232_image_device(mconfig, tag, owner, clock)
- {
- m_tms9902.set_tag(std::forward<T>(tms_tag));
- }
-
- tm990_189_rs232_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
- // image-level overrides
- virtual iodevice_t image_type() const noexcept override { return IO_SERIAL; }
-
- virtual bool is_readable() const noexcept override { return true; }
- virtual bool is_writeable() const noexcept override { return true; }
- virtual bool is_creatable() const noexcept override { return true; }
- virtual bool must_be_loaded() const noexcept override { return false; }
- virtual bool is_reset_on_load() const noexcept override { return false; }
- virtual const char *file_extensions() const noexcept override { return ""; }
-
- virtual image_init_result call_load() override;
- virtual void call_unload() override;
-
-protected:
- // device-level overrides
- virtual void device_start() override;
- virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
-
- required_device<tms9902_device> m_tms9902;
-};
-
-DEFINE_DEVICE_TYPE(TM990_189_RS232, tm990_189_rs232_image_device, "tm990_189_rs232_image", "TM990/189 RS232 port")
-
-tm990_189_rs232_image_device::tm990_189_rs232_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, TM990_189_RS232, tag, owner, clock)
- , device_image_interface(mconfig, *this)
- , m_tms9902(*this, finder_base::DUMMY_TAG)
-{
-}
-
-void tm990_189_rs232_image_device::device_start()
-{
-}
-
-void tm990_189_rs232_image_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
-{
- uint8_t buf;
- if (/*m_rs232_rts &&*/ /*(mame_ftell(m_rs232_fp) < mame_fsize(m_rs232_fp))*/1)
- {
- if (fread(&buf, 1) == 1)
- m_tms9902->rcv_data(buf);
- }
-}
-
-image_init_result tm990_189_rs232_image_device::call_load()
-{
- tm990189_state *state = machine().driver_data<tm990189_state>();
- m_tms9902->rcv_dsr(ASSERT_LINE);
- state->m_rs232_input_timer = timer_alloc();
- state->m_rs232_input_timer->adjust(attotime::zero, 0, attotime::from_msec(10));
- return image_init_result::PASS;
-}
-
-
-void tm990_189_rs232_image_device::call_unload()
-{
- tm990189_state *state = machine().driver_data<tm990189_state>();
- m_tms9902->rcv_dsr(CLEAR_LINE);
-
- state->m_rs232_input_timer->reset(); /* FIXME - timers should only be allocated once */
-}
-
-
-/* static TMS9902_RTS_CALLBACK( rts_callback )
-{
- tm990189 *state = device->machine().driver_data<tm990189>();
- state->m_rs232_rts = RTS;
- tms9902->set_cts(RTS);
-} */
-
-WRITE8_MEMBER( tm990189_state::xmit_callback )
-{
- uint8_t buf = data;
- if (m_rs232_fp) m_rs232_fp->fwrite(&buf, 1);
-}
-
-/*
- External instruction decoding
-*/
-WRITE8_MEMBER( tm990189_state::external_operation )
-{
- switch (offset)
- {
- case 2: // IDLE
- if (data)
- m_LED_state |= 0x40;
- else
- m_LED_state &= ~0x40;
- break;
- case 3: // RSET
- // Not used on the default board
- break;
- case 5: // CKON: set DECKCONTROL
- m_LED_state |= 0x20;
- m_cass->change_state(CASSETTE_MOTOR_ENABLED,CASSETTE_MASK_MOTOR);
- break;
- case 6: // CKOF: clear DECKCONTROL
- m_LED_state &= ~0x20;
- m_cass->change_state(CASSETTE_MOTOR_DISABLED,CASSETTE_MASK_MOTOR);
- break;
- case 7: // LREX: trigger LOAD
- hold_load();
- break;
- default: // undefined
- break;
- }
-}
-
-/*
- Video Board handling
-*/
-
-READ8_MEMBER( tm990189_state::video_vdp_r )
-{
- int reply = 0;
-
- /* When the tms9980 reads @>2000 or @>2001, it actually does a word access:
- it reads @>2000 first, then @>2001. According to schematics, both access
- are decoded to the VDP: read accesses are therefore bogus, all the more so
- since the two reads are too close (1us) for the VDP to be able to reload
- the read buffer: the read address pointer is probably incremented by 2, but
- only the first byte is valid. There is a work around for this problem: all
- you need is reloading the address pointer before each read. However,
- software always uses the second byte, which is very weird, particularly
- for the status port. Presumably, since the read buffer has not been
- reloaded, the second byte read from the memory read port is equal to the
- first; however, this explanation is not very convincing for the status
- port. Still, I do not have any better explanation, so I will stick with
- it. */
-
- if (offset & 2)
- reply = m_tms9918->register_read();
- else
- reply = m_tms9918->vram_read();
-
- if (!(offset & 1))
- m_bogus_read_save = reply;
- else
- reply = m_bogus_read_save;
-
- return reply;
-}
-
-WRITE8_MEMBER( tm990189_state::video_vdp_w )
-{
- if (offset & 1)
- {
- if (offset & 2)
- m_tms9918->register_write(data);
- else
- m_tms9918->vram_write(data);
- }
-}
-
-READ8_MEMBER( tm990189_state::video_joy_r )
-{
- uint8_t data = ioport("BUTTONS")->read();
-
- if (m_joy1x_timer->remaining() < attotime::zero)
- data |= 0x01;
-
- if (m_joy1y_timer->remaining() < attotime::zero)
- data |= 0x02;
-
- if (m_joy2x_timer->remaining() < attotime::zero)
- data |= 0x08;
-
- if (m_joy2y_timer->remaining() < attotime::zero)
- data |= 0x10;
-
- return data;
-}
-
-WRITE8_MEMBER( tm990189_state::video_joy_w )
-{
- m_joy1x_timer->reset(attotime::from_usec(ioport("JOY1_X")->read()*28+28));
- m_joy1y_timer->reset(attotime::from_usec(ioport("JOY1_Y")->read()*28+28));
- m_joy2x_timer->reset(attotime::from_usec(ioport("JOY2_X")->read()*28+28));
- m_joy2y_timer->reset(attotime::from_usec(ioport("JOY2_Y")->read()*28+28));
-}
-
-/*
-// user tms9901 setup
-static const tms9901_interface usr9901reset_param =
-{
- tms9901_device::INT1 | tms9901_device::INT2 | tms9901_device::INT3 | tms9901_device::INT4 | tms9901_device::INT5 | tms9901_device::INT6, // only input pins whose state is always known
-
- // Read handler. Covers all input lines (see tms9901.h)
- DEVCB_NOOP,
-
- // write handlers
- {
- DEVCB_DRIVER_LINE_MEMBER(tm990189_state, usr9901_led0_w),
- DEVCB_DRIVER_LINE_MEMBER(tm990189_state, usr9901_led1_w),
- DEVCB_DRIVER_LINE_MEMBER(tm990189_state, usr9901_led2_w),
- DEVCB_DRIVER_LINE_MEMBER(tm990189_state, usr9901_led3_w),
- DEVCB_NOOP,
- DEVCB_NOOP,
- DEVCB_NOOP,
- DEVCB_NOOP,
- DEVCB_NOOP,
- DEVCB_NOOP,
- DEVCB_NOOP,
- DEVCB_NOOP,
- DEVCB_NOOP,
- DEVCB_NOOP,
- DEVCB_NOOP,
- DEVCB_NOOP
- },
-
- // interrupt handler
- DEVCB_DRIVER_MEMBER(tm990189_state, usr9901_interrupt_callback)
-};
-*/
-
-/*
-// system tms9901 setup
-static const tms9901_interface sys9901reset_param =
-{
- 0, // only input pins whose state is always known
-
- // Read handler. Covers all input lines (see tms9901.h)
- DEVCB_DRIVER_MEMBER(tm990189_state, sys9901_r),
-
- // write handlers
- {
- DEVCB_DRIVER_LINE_MEMBER(tm990189_state, sys9901_digitsel0_w),
- DEVCB_DRIVER_LINE_MEMBER(tm990189_state, sys9901_digitsel1_w),
- DEVCB_DRIVER_LINE_MEMBER(tm990189_state, sys9901_digitsel2_w),
- DEVCB_DRIVER_LINE_MEMBER(tm990189_state, sys9901_digitsel3_w),
- DEVCB_DRIVER_LINE_MEMBER(tm990189_state, sys9901_segment0_w),
- DEVCB_DRIVER_LINE_MEMBER(tm990189_state, sys9901_segment1_w),
- DEVCB_DRIVER_LINE_MEMBER(tm990189_state, sys9901_segment2_w),
- DEVCB_DRIVER_LINE_MEMBER(tm990189_state, sys9901_segment3_w),
- DEVCB_DRIVER_LINE_MEMBER(tm990189_state, sys9901_segment4_w),
- DEVCB_DRIVER_LINE_MEMBER(tm990189_state, sys9901_segment5_w),
- DEVCB_DRIVER_LINE_MEMBER(tm990189_state, sys9901_segment6_w),
- DEVCB_DRIVER_LINE_MEMBER(tm990189_state, sys9901_segment7_w),
- DEVCB_DRIVER_LINE_MEMBER(tm990189_state, sys9901_dsplytrgr_w),
- DEVCB_DRIVER_LINE_MEMBER(tm990189_state, sys9901_shiftlight_w),
- DEVCB_DRIVER_LINE_MEMBER(tm990189_state, sys9901_spkrdrive_w),
- DEVCB_DRIVER_LINE_MEMBER(tm990189_state, sys9901_tapewdata_w)
- },
-
- // interrupt handler
- DEVCB_DRIVER_MEMBER(tm990189_state, sys9901_interrupt_callback)
-};
-
-*/
-
-/*
- Memory map:
-
- 0x0000-0x03ff: 1kb RAM
- 0x0400-0x07ff: 1kb onboard expansion RAM
- 0x0800-0x0bff or 0x0800-0x0fff: 1kb or 2kb onboard expansion ROM
- 0x1000-0x2fff: reserved for offboard expansion
- Only known card: Color Video Board
- 0x1000-0x17ff (R): Video board ROM 1
- 0x1800-0x1fff (R): Video board ROM 2
- 0x2000-0x27ff (R): tms9918 read ports (bogus)
- (address & 2) == 0: data port (bogus)
- (address & 2) == 1: status register (bogus)
- 0x2800-0x2fff (R): joystick read port
- d2: joy 2 switch
- d3: joy 2 Y (length of pulse after retrigger is proportional to axis position)
- d4: joy 2 X (length of pulse after retrigger is proportional to axis position)
- d2: joy 1 switch
- d3: joy 1 Y (length of pulse after retrigger is proportional to axis position)
- d4: joy 1 X (length of pulse after retrigger is proportional to axis position)
- 0x1801-0x1fff ((address & 1) == 1) (W): joystick write port (retrigger)
- 0x2801-0x2fff ((address & 1) == 1) (W): tms9918 write ports
- (address & 2) == 0: data port
- (address & 2) == 1: control register
- 0x3000-0x3fff: 4kb onboard ROM
-*/
-
-void tm990189_state::tm990_189_memmap(address_map &map)
-{
- map(0x0000, 0x07ff).ram(); /* RAM */
- map(0x0800, 0x0fff).rom(); /* extra ROM - application programs with unibug, remaining 2kb of program for university basic */
- map(0x1000, 0x2fff).noprw(); /* reserved for expansion (RAM and/or tms9918 video controller) */
- map(0x3000, 0x3fff).rom(); /* main ROM - unibug or university basic */
-}
-
-void tm990189_state::tm990_189_v_memmap(address_map &map)
-{
- map(0x0000, 0x07ff).ram(); /* RAM */
- map(0x0800, 0x0fff).rom(); /* extra ROM - application programs with unibug, remaining 2kb of program for university basic */
-
- map(0x1000, 0x17ff).rom().nopw(); /* video board ROM 1 */
- map(0x1800, 0x1fff).rom().w(FUNC(tm990189_state::video_joy_w)); /* video board ROM 2 and joystick write port*/
- map(0x2000, 0x27ff).r(FUNC(tm990189_state::video_vdp_r)).nopw(); /* video board tms9918 read ports (bogus) */
- map(0x2800, 0x2fff).rw(FUNC(tm990189_state::video_joy_r), FUNC(tm990189_state::video_vdp_w)); /* video board joystick read port and tms9918 write ports */
-
- map(0x3000, 0x3fff).rom(); /* main ROM - unibug or university basic */
-}
-
-/*
- CRU map
-
- The board features one tms9901 for keyboard and sound I/O, another tms9901
- to drive the parallel port and a few LEDs and handle tms9980 interrupts,
- and one optional tms9902 for serial I/O.
-
- * bits >000->1ff (R12=>000->3fe): first TMS9901: parallel port, a few LEDs,
- interrupts
- - CRU bits 1-5: UINT1* through UINT5* (jumper connectable to parallel
- port or COMINT from tms9902)
- - CRU bit 6: KBINT (interrupt request from second tms9901)
- - CRU bits 7-15: mirrors P15-P7
- - CRU bits 16-31: P0-P15 (parallel port)
- (bits 16, 17, 18 and 19 control LEDs numbered 1, 2, 3 and 4, too)
- * bits >200->3ff (R12=>400->7fe): second TMS9901: display, keyboard and
- sound
- - CRU bits 1-5: KB1*-KB5* (inputs from current keyboard row)
- - CRU bit 6: RDATA (tape in)
- - CRU bits 7-15: mirrors P15-P7
- - CRU bits 16-19: DIGITSELA-DIGITSELD (select current display digit and
- keyboard row)
- - CRU bits 20-27: SEGMENTA*-SEGMENTG* and SEGMENTP* (drives digit
- segments)
- - CRU bit 28: DSPLYTRGR*: used as an alive signal for a watchdog circuit
- which turns off the display when the program hangs and
- LED segments would continuously emit light
-
- - bit 29: SHIFTLIGHT (controls shift light)
- - bit 30: SPKRDRIVE (controls buzzer)
- - bit 31: WDATA (tape out)
- * bits >400->5ff (R12=>800->bfe): optional TMS9902
- * bits >600->7ff (R12=>c00->ffe): reserved for expansion
- * write 0 to bits >1000->17ff: IDLE: flash IDLE LED
- * write 0 to bits >1800->1fff: RSET: not connected, but it is decoded and
- hackers can connect any device they like to this pin
- * write 1 to bits >0800->0fff: CKON: light FWD LED and activates
- DECKCONTROL* signal (part of tape interface)
- * write 1 to bits >1000->17ff: CKOF: light off FWD LED and deactivates
- DECKCONTROL* signal (part of tape interface)
- * write 1 to bits >1800->1fff: LREX: trigger load interrupt
-
- Keyboard map: see input ports
-
- Display segment designation:
- a
- ___
- | |
- f| |b
- |___|
- | g |
- e| |c
- |___| .p
- d
-*/
-
-void tm990189_state::tm990_189_cru_map(address_map &map)
-{
- map(0x0000, 0x03ff).rw(m_tms9901_usr, FUNC(tms9901_device::read), FUNC(tms9901_device::write)); /* user I/O tms9901 */
- map(0x0400, 0x07ff).rw(m_tms9901_sys, FUNC(tms9901_device::read), FUNC(tms9901_device::write)); /* system I/O tms9901 */
- map(0x0800, 0x0bff).rw(m_tms9902, FUNC(tms9902_device::cruread), FUNC(tms9902_device::cruwrite)); /* optional tms9902 */
-}
-
-void tm990189_state::tm990_189(machine_config &config)
-{
- /* basic machine hardware */
- TMS9980A(config, m_tms9980a, 8_MHz_XTAL); // clock divided by 4 internally
- m_tms9980a->set_addrmap(AS_PROGRAM, &tm990189_state::tm990_189_memmap);
- m_tms9980a->set_addrmap(AS_IO, &tm990189_state::tm990_189_cru_map);
- m_tms9980a->extop_cb().set(FUNC(tm990189_state::external_operation));
-
- MCFG_MACHINE_START_OVERRIDE(tm990189_state, tm990_189 )
- MCFG_MACHINE_RESET_OVERRIDE(tm990189_state, tm990_189 )
-
- /* Video hardware */
- config.set_default_layout(layout_tm990189);
-
- /* sound hardware */
- SPEAKER(config, "mono").front_center();
- SPEAKER_SOUND(config, "speaker").add_route(ALL_OUTPUTS, "mono", 0.50);
-
- /* Devices */
- CASSETTE(config, "cassette", 0).add_route(ALL_OUTPUTS, "mono", 0.25);
-
- TMS9901(config, m_tms9901_usr, 8_MHz_XTAL / 4);
- m_tms9901_usr->p_out_cb(0).set(FUNC(tm990189_state::usr9901_led0_w));
- m_tms9901_usr->p_out_cb(1).set(FUNC(tm990189_state::usr9901_led1_w));
- m_tms9901_usr->p_out_cb(2).set(FUNC(tm990189_state::usr9901_led2_w));
- m_tms9901_usr->p_out_cb(3).set(FUNC(tm990189_state::usr9901_led3_w));
- m_tms9901_usr->intreq_cb().set(FUNC(tm990189_state::usr9901_interrupt_callback));
-
- TMS9901(config, m_tms9901_sys, 8_MHz_XTAL / 4);
- m_tms9901_sys->read_cb().set(FUNC(tm990189_state::sys9901_r));
- m_tms9901_sys->p_out_cb(0).set(FUNC(tm990189_state::sys9901_digitsel0_w));
- m_tms9901_sys->p_out_cb(1).set(FUNC(tm990189_state::sys9901_digitsel1_w));
- m_tms9901_sys->p_out_cb(2).set(FUNC(tm990189_state::sys9901_digitsel2_w));
- m_tms9901_sys->p_out_cb(3).set(FUNC(tm990189_state::sys9901_digitsel3_w));
- m_tms9901_sys->p_out_cb(4).set(FUNC(tm990189_state::sys9901_segment0_w));
- m_tms9901_sys->p_out_cb(5).set(FUNC(tm990189_state::sys9901_segment1_w));
- m_tms9901_sys->p_out_cb(6).set(FUNC(tm990189_state::sys9901_segment2_w));
- m_tms9901_sys->p_out_cb(7).set(FUNC(tm990189_state::sys9901_segment3_w));
- m_tms9901_sys->p_out_cb(8).set(FUNC(tm990189_state::sys9901_segment4_w));
- m_tms9901_sys->p_out_cb(9).set(FUNC(tm990189_state::sys9901_segment5_w));
- m_tms9901_sys->p_out_cb(10).set(FUNC(tm990189_state::sys9901_segment6_w));
- m_tms9901_sys->p_out_cb(11).set(FUNC(tm990189_state::sys9901_segment7_w));
- m_tms9901_sys->p_out_cb(12).set(FUNC(tm990189_state::sys9901_dsplytrgr_w));
- m_tms9901_sys->p_out_cb(13).set(FUNC(tm990189_state::sys9901_shiftlight_w));
- m_tms9901_sys->p_out_cb(14).set(FUNC(tm990189_state::sys9901_spkrdrive_w));
- m_tms9901_sys->p_out_cb(15).set(FUNC(tm990189_state::sys9901_tapewdata_w));
- m_tms9901_sys->intreq_cb().set(FUNC(tm990189_state::sys9901_interrupt_callback));
-
- TMS9902(config, m_tms9902, 8_MHz_XTAL / 4);
- m_tms9902->xmit_cb().set(FUNC(tm990189_state::xmit_callback)); // called when a character is transmitted
- TM990_189_RS232(config, "rs232", 0, m_tms9902);
-
- timer_device &display_timer(TIMER(config, "display_timer"));
- display_timer.configure_periodic(FUNC(tm990189_state::display_callback), attotime::from_hz(30));
- // Need to delay the timer, or it will spoil the initial LOAD
- // TODO: Fix this, probably inside CPU
- display_timer.set_start_delay(attotime::from_msec(150));
-}
-
-void tm990189_state::tm990_189_v(machine_config &config)
-{
- /* basic machine hardware */
- TMS9980A(config, m_tms9980a, 8_MHz_XTAL);
- m_tms9980a->set_addrmap(AS_PROGRAM, &tm990189_state::tm990_189_v_memmap);
- m_tms9980a->set_addrmap(AS_IO, &tm990189_state::tm990_189_cru_map);
- m_tms9980a->extop_cb().set(FUNC(tm990189_state::external_operation));
-
- MCFG_MACHINE_START_OVERRIDE(tm990189_state, tm990_189_v )
- MCFG_MACHINE_RESET_OVERRIDE(tm990189_state, tm990_189_v )
-
- /* video hardware */
- tms9918_device &vdp(TMS9918(config, "tms9918", XTAL(10'738'635)));
- vdp.set_screen("screen");
- vdp.set_vram_size(0x4000);
- SCREEN(config, "screen", SCREEN_TYPE_RASTER);
-
- config.set_default_layout(layout_tm990189v);
-
- /* sound hardware */
- SPEAKER(config, "mono").front_center();
- SPEAKER_SOUND(config, "speaker").add_route(ALL_OUTPUTS, "mono", 0.50); /* one two-level buzzer */
-
- /* Devices */
- CASSETTE(config, "cassette", 0).add_route(ALL_OUTPUTS, "mono", 0.25);
-
- TMS9901(config, m_tms9901_usr, 8_MHz_XTAL / 4);
- m_tms9901_usr->p_out_cb(0).set(FUNC(tm990189_state::usr9901_led0_w));
- m_tms9901_usr->p_out_cb(1).set(FUNC(tm990189_state::usr9901_led1_w));
- m_tms9901_usr->p_out_cb(2).set(FUNC(tm990189_state::usr9901_led2_w));
- m_tms9901_usr->p_out_cb(3).set(FUNC(tm990189_state::usr9901_led3_w));
- m_tms9901_usr->intreq_cb().set(FUNC(tm990189_state::usr9901_interrupt_callback));
-
- TMS9901(config, m_tms9901_sys, 8_MHz_XTAL / 4);
- m_tms9901_sys->read_cb().set(FUNC(tm990189_state::sys9901_r));
- m_tms9901_sys->p_out_cb(0).set(FUNC(tm990189_state::sys9901_digitsel0_w));
- m_tms9901_sys->p_out_cb(1).set(FUNC(tm990189_state::sys9901_digitsel1_w));
- m_tms9901_sys->p_out_cb(2).set(FUNC(tm990189_state::sys9901_digitsel2_w));
- m_tms9901_sys->p_out_cb(3).set(FUNC(tm990189_state::sys9901_digitsel3_w));
- m_tms9901_sys->p_out_cb(4).set(FUNC(tm990189_state::sys9901_segment0_w));
- m_tms9901_sys->p_out_cb(5).set(FUNC(tm990189_state::sys9901_segment1_w));
- m_tms9901_sys->p_out_cb(6).set(FUNC(tm990189_state::sys9901_segment2_w));
- m_tms9901_sys->p_out_cb(7).set(FUNC(tm990189_state::sys9901_segment3_w));
- m_tms9901_sys->p_out_cb(8).set(FUNC(tm990189_state::sys9901_segment4_w));
- m_tms9901_sys->p_out_cb(9).set(FUNC(tm990189_state::sys9901_segment5_w));
- m_tms9901_sys->p_out_cb(10).set(FUNC(tm990189_state::sys9901_segment6_w));
- m_tms9901_sys->p_out_cb(11).set(FUNC(tm990189_state::sys9901_segment7_w));
- m_tms9901_sys->p_out_cb(12).set(FUNC(tm990189_state::sys9901_dsplytrgr_w));
- m_tms9901_sys->p_out_cb(13).set(FUNC(tm990189_state::sys9901_shiftlight_w));
- m_tms9901_sys->p_out_cb(14).set(FUNC(tm990189_state::sys9901_spkrdrive_w));
- m_tms9901_sys->p_out_cb(15).set(FUNC(tm990189_state::sys9901_tapewdata_w));
- m_tms9901_sys->intreq_cb().set(FUNC(tm990189_state::sys9901_interrupt_callback));
-
- TMS9902(config, m_tms9902, 8_MHz_XTAL / 4);
- m_tms9902->xmit_cb().set(FUNC(tm990189_state::xmit_callback)); // called when a character is transmitted;
- TM990_189_RS232(config, "rs232", 0, m_tms9902);
-
- timer_device &display_timer(TIMER(config, "display_timer"));
- display_timer.configure_periodic(FUNC(tm990189_state::display_callback), attotime::from_hz(30));
- display_timer.set_start_delay(attotime::from_msec(150));
-}
-
-
-/*
- ROM loading
-*/
-ROM_START(990189)
- /*CPU memory space*/
- ROM_REGION(0x4000, "maincpu", 0 )
-
- /* extra ROM */
- ROM_LOAD("990-469.u32", 0x0800, 0x0800, CRC(08df7edb) SHA1(fa9751fd2e3e5d7ae03819fc9c7099e2ddd9fb53))
-
- /* boot ROM */
- ROM_LOAD("990-469.u33", 0x3000, 0x1000, CRC(e9b4ac1b) SHA1(96e88f4cb7a374033cdf3af0dc26ca5b1d55b9f9))
-ROM_END
-
-ROM_START(990189v)
- /*CPU memory space*/
- ROM_REGION(0x4000, "maincpu", 0 )
-
- /* extra ROM */
- ROM_LOAD("990-469.u32", 0x0800, 0x0800, CRC(08df7edb) SHA1(fa9751fd2e3e5d7ae03819fc9c7099e2ddd9fb53))
-
- /* extension ROM */
- ROM_LOAD_OPTIONAL("demo1000.u13", 0x1000, 0x0800, CRC(c0e16685) SHA1(d0d314134c42fa4682aafbace67f539f67f6ba65))
-
- /* extension ROM */
- ROM_LOAD_OPTIONAL("demo1800.u11", 0x1800, 0x0800, CRC(8737dc4b) SHA1(b87da7aa4d3f909e70f885c4b36999cc1abf5764))
-
- /* boot ROM */
- ROM_LOAD("990-469.u33", 0x3000, 0x1000, CRC(e9b4ac1b) SHA1(96e88f4cb7a374033cdf3af0dc26ca5b1d55b9f9))
- /*ROM_LOAD("unibasic.bin", 0x3000, 0x1000, CRC(de4d9744))*/ /* older, partial dump of university BASIC */
-ROM_END
-
-#define JOYSTICK_DELTA 10
-#define JOYSTICK_SENSITIVITY 100
-
-static INPUT_PORTS_START(tm990_189)
-
- PORT_START( "LOADINT")
- PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Load interrupt") PORT_CODE(KEYCODE_PRTSCR) PORT_CHANGED_MEMBER(DEVICE_SELF, tm990189_state, load_interrupt, 1)
-
- /* 45-key calculator-like alphanumeric keyboard... */
- PORT_START("LINE0") /* row 0 */
- PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
- PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Sp *") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PORT_CHAR('*')
- PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ret '") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PORT_CHAR('\'')
- PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("$ =") PORT_CODE(KEYCODE_STOP) PORT_CHAR('$') PORT_CHAR('=')
- PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(", <") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
-
- PORT_START("LINE1") /* row 1 */
- PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("+ (") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('+') PORT_CHAR('(')
- PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("- )") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('-') PORT_CHAR(')')
- PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("@ /") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('@') PORT_CHAR('/')
- PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("> %") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('>') PORT_CHAR('%')
- PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0 ^") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR('^')
-
- PORT_START("LINE2") /* row 2 */
- PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1 .") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('.')
- PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2 ;") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR(';')
- PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3 :") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR(':')
- PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4 ?") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('?')
- PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5 !") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('!')
-
- PORT_START("LINE3") /* row 3 */
- PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6 _") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('_')
- PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7 \"") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\"')
- PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8 #") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('#')
- PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9 (ESC)") PORT_CODE(KEYCODE_9) PORT_CHAR('9')
- PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A (SOH)") PORT_CODE(KEYCODE_A) PORT_CHAR('A')
-
- PORT_START("LINE4") /* row 4 */
- PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B (STH)") PORT_CODE(KEYCODE_B) PORT_CHAR('B')
- PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C (ETX)") PORT_CODE(KEYCODE_C) PORT_CHAR('C')
- PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D (EOT)") PORT_CODE(KEYCODE_D) PORT_CHAR('D')
- PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E (ENQ)") PORT_CODE(KEYCODE_E) PORT_CHAR('E')
- PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F (ACK)") PORT_CODE(KEYCODE_F) PORT_CHAR('F')
-
- PORT_START("LINE5") /* row 5 */
- PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G (BEL)") PORT_CODE(KEYCODE_G) PORT_CHAR('G')
- PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H (BS)") PORT_CODE(KEYCODE_H) PORT_CHAR('H')
- PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I (HT)") PORT_CODE(KEYCODE_I) PORT_CHAR('I')
- PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J (LF)") PORT_CODE(KEYCODE_J) PORT_CHAR('J')
- PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K (VT)") PORT_CODE(KEYCODE_K) PORT_CHAR('K')
-
- PORT_START("LINE6") /* row 6 */
- PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L (FF)") PORT_CODE(KEYCODE_L) PORT_CHAR('L')
- PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M (DEL)") PORT_CODE(KEYCODE_M) PORT_CHAR('M')
- PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N (SO)") PORT_CODE(KEYCODE_N) PORT_CHAR('N')
- PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O (SI)") PORT_CODE(KEYCODE_O) PORT_CHAR('O')
- PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P (DLE)") PORT_CODE(KEYCODE_P) PORT_CHAR('P')
-
- PORT_START("LINE7") /* row 7 */
- PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q (DC1)") PORT_CODE(KEYCODE_Q) PORT_CHAR('Q')
- PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R (DC2)") PORT_CODE(KEYCODE_R) PORT_CHAR('R')
- PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S (DC3)") PORT_CODE(KEYCODE_S) PORT_CHAR('S')
- PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T (DC4)") PORT_CODE(KEYCODE_T) PORT_CHAR('T')
- PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U (NAK)") PORT_CODE(KEYCODE_U) PORT_CHAR('U')
-
- PORT_START("LINE8") /* row 8 */
- PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V <-D") PORT_CODE(KEYCODE_V) PORT_CHAR('V')
- PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W (ETB)") PORT_CODE(KEYCODE_W) PORT_CHAR('W')
- PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X (CAN)") PORT_CODE(KEYCODE_X) PORT_CHAR('X')
- PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y (EM)") PORT_CODE(KEYCODE_Y) PORT_CHAR('Y')
- PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z ->D") PORT_CODE(KEYCODE_Z) PORT_CHAR('Z')
-
- /* analog joysticks (video board only) */
-
- PORT_START("BUTTONS") /* joystick 1 & 2 buttons */
- PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_PLAYER(1)
- PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_PLAYER(2)
-
- PORT_START("JOY1_X") /* joystick 1, X axis */
- PORT_BIT( 0x3ff, 0x1aa, IPT_AD_STICK_X) PORT_SENSITIVITY(JOYSTICK_SENSITIVITY) PORT_KEYDELTA(JOYSTICK_DELTA) PORT_MINMAX(0xd2,0x282 ) PORT_PLAYER(1)
-
- PORT_START("JOY1_Y") /* joystick 1, Y axis */
- PORT_BIT( 0x3ff, 0x1aa, IPT_AD_STICK_Y) PORT_SENSITIVITY(JOYSTICK_SENSITIVITY) PORT_KEYDELTA(JOYSTICK_DELTA) PORT_MINMAX(0xd2,0x282 ) PORT_PLAYER(1) PORT_REVERSE
-
- PORT_START("JOY2_X") /* joystick 2, X axis */
- PORT_BIT( 0x3ff, 0x180, IPT_AD_STICK_X) PORT_SENSITIVITY(JOYSTICK_SENSITIVITY) PORT_KEYDELTA(JOYSTICK_DELTA) PORT_MINMAX(0xd2,0x180 ) PORT_PLAYER(2)
-
- PORT_START("JOY2_Y") /* joystick 2, Y axis */
- PORT_BIT( 0x3ff, 0x1aa, IPT_AD_STICK_Y) PORT_SENSITIVITY(JOYSTICK_SENSITIVITY) PORT_KEYDELTA(JOYSTICK_DELTA) PORT_MINMAX(0xd2,0x282 ) PORT_PLAYER(2) PORT_REVERSE
-INPUT_PORTS_END
-
-// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
-COMP( 1978, 990189, 0, 0, tm990_189, tm990_189, tm990189_state, empty_init, "Texas Instruments", "TM 990/189 University Board microcomputer", 0 )
-COMP( 1980, 990189v, 990189, 0, tm990_189_v, tm990_189, tm990189_state, empty_init, "Texas Instruments", "TM 990/189 University Board microcomputer with Video Board Interface", 0 )