From 57a3ca60e968a0f0dd51b2bc48270402bc523a75 Mon Sep 17 00:00:00 2001 From: Michael Zapf Date: Wed, 19 Mar 2014 23:53:59 +0000 Subject: [PATCH] (MESS) devcb2 migration. (nw) --- src/emu/machine/tms9901.c | 412 ++++++++++++++++++++++-------------- src/emu/machine/tms9901.h | 136 +++++++++--- src/mess/drivers/geneve.c | 65 +++--- src/mess/drivers/ti99_4p.c | 86 +++++--- src/mess/drivers/ti99_4x.c | 222 +++++++++++++------ src/mess/drivers/ti99_8.c | 102 ++++++--- src/mess/drivers/tm990189.c | 184 ++++++++++------ 7 files changed, 798 insertions(+), 409 deletions(-) diff --git a/src/emu/machine/tms9901.c b/src/emu/machine/tms9901.c index 367a9e58e27..8ca2f4b2bf7 100644 --- a/src/emu/machine/tms9901.c +++ b/src/emu/machine/tms9901.c @@ -4,6 +4,29 @@ TMS9901 Programmable System Interface + +--------------+ + RST1*| 1 | | 40| Vcc + CRUOUT | 2 +--+ 39| S0 + CRUCLK | 3 38| P0 + CRUIN | 4 37| P1 + CE*| 5 36| S1 + INT6*| 6 35| S2 + INT5*| 7 34| INT7* / P15 + INT4*| 8 33| INT8* / P14 + INT3*| 9 32| INT9* / P13 + Phi*|10 31| INT10* / P12 + INTREQ*|11 30| INT11* / P11 + IC3 |12 29| INT12* / P10 + IC2 |13 28| INT13* / P9 + IC1 |14 27| INT14* / P8 + IC0 |15 26| P2 + Vss |16 25| S3 + INT1*|17 24| S4 + INT2*|18 23| INT15* / P7 + P6 |19 22| P3 + P5 |20 21| P4 + +--------------+ + Overview: TMS9901 is a support chip for TMS9900. It handles interrupts, provides several I/O pins, and a timer (a.k.a. clock: it is merely a register which @@ -101,14 +124,36 @@ TODO: Tests on a real machine #include "tms9901.h" -#define VERBOSE 1 -#define LOG logerror +/* + Debugging flags. +*/ +#define TRACE_PINS 0 +#define TRACE_CLOCK 0 +#define TRACE_MODE 0 /* Constructor */ tms9901_device::tms9901_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) -: device_t(mconfig, TMS9901, "TMS9901 Programmable System Interface", tag, owner, clock, "tms9901", __FILE__) +: device_t(mconfig, TMS9901, "TMS9901 Programmable System Interface", tag, owner, clock, "tms9901", __FILE__), + m_read_block(*this), + m_write_p0(*this), + m_write_p1(*this), + m_write_p2(*this), + m_write_p3(*this), + m_write_p4(*this), + m_write_p5(*this), + m_write_p6(*this), + m_write_p7(*this), + m_write_p8(*this), + m_write_p9(*this), + m_write_p10(*this), + m_write_p11(*this), + m_write_p12(*this), + m_write_p13(*this), + m_write_p14(*this), + m_write_p15(*this), + m_interrupt(*this) { } @@ -119,24 +164,25 @@ void tms9901_device::field_interrupts(void) { int current_ints; - /* int_state: state of lines int1-int15 */ + // m_int_state: inverted state of lines INT1*-INT15*. Bits are set by set_single_int only. current_ints = m_int_state; if (m_clock_register != 0) - { /* if timer is enabled, INT3 pin is overriden by timer */ + { + // if timer is enabled, INT3 pin is overridden by timer if (m_timer_int_pending) { - if (VERBOSE>8) LOG("tms9901: timer fires\n"); + if (TRACE_CLOCK) logerror("%s: timer fires\n", tag()); current_ints |= TMS9901_INT3; } else { - if (VERBOSE>8) LOG("tms9901: timer clear\n"); + if (TRACE_CLOCK) logerror("%s: timer clear\n", tag()); current_ints &= ~TMS9901_INT3; } } - /* enabled_ints: enabled interrupts */ - /* mask out all int pins currently set as output */ + // enabled_ints: enabled interrupts + // Remove all settings from pins that are set as outputs (INT7*-INT15* share the same pins as P15-P7) current_ints &= m_enabled_ints & (~m_pio_direction_mirror); // Check whether we have a new state. For systems that use level-triggered @@ -147,12 +193,12 @@ void tms9901_device::field_interrupts(void) m_old_int_state = current_ints; - if (current_ints) + if (current_ints != 0) { // find which interrupt tripped us: // the number of the first (i.e. least significant) non-zero bit among // the 16 first bits - // we simply look for the first bit set to 1 in current_ints... */ + // we simply look for the first bit set to 1 in current_ints... int level = 0; while ((current_ints & 1)==0) @@ -162,13 +208,13 @@ void tms9901_device::field_interrupts(void) } m_int_pending = true; if (!m_interrupt.isnull()) - m_interrupt(level, 1); // the offset carries the IC0-3 level + m_interrupt(level, 1, 0xff); // the offset carries the IC0-3 level } else { m_int_pending = false; if (!m_interrupt.isnull()) - m_interrupt(0xf, 0); //Spec: INTREQ*=1 <=> IC0,1,2,3 = 1111 + m_interrupt(0xf, 0, 0xff); //Spec: INTREQ*=1 <=> IC0,1,2,3 = 1111 } } @@ -176,8 +222,8 @@ void tms9901_device::field_interrupts(void) function which should be called by the driver when the state of an INTn* pin changes (only required if the pin is set up as an interrupt pin) - state == 0: INTn* is inactive (high) - state != 0: INTn* is active (low) + state == CLEAR_LINE: INTn* is inactive (high) + state == ASSERT_LINE: INTn* is active (low) 0<=pin_number<=15 */ @@ -189,7 +235,6 @@ void tms9901_device::set_single_int(int pin_number, int state) else m_int_state &= ~(1 << pin_number); - /* we do not need to always call this function - time for an optimization */ field_interrupts(); } @@ -236,42 +281,50 @@ READ8_MEMBER( tms9901_device::read ) { case 0: if (m_clock_mode) - { /* clock mode */ + { + // Clock mode. The LSB reflects the CB bit which is set to 1 for clock mode. answer = ((m_clock_read_register & 0x7F) << 1) | 0x01; } else - { /* interrupt mode */ - // m_int_state stores the INTx values, which are inverted to the pin levels (INTx*) - answer = ((~m_int_state) & m_supported_int_mask) & 0xFF; - + { + // Interrupt mode + // Note that we rely on the read function to deliver the same + // INTx levels that have been signaled via the set_single_int method. + // This may mean that those levels must be latched by the callee. if (!m_read_block.isnull()) answer |= m_read_block(TMS9901_CB_INT7); - answer &= ~ m_pio_direction_mirror; + // Remove the bits that are set as outputs (can only be INT7*) + answer &= ~m_pio_direction_mirror; + + // Set those bits here answer |= (m_pio_output_mirror & m_pio_direction_mirror) & 0xFF; } + if (TRACE_PINS) logerror("%s: input on lines INT7..CB = %02x\n", tag(), answer); break; case 1: if (m_clock_mode) - { /* clock mode */ + { + // clock mode answer = (m_clock_read_register & 0x3F80) >> 7; if (!m_int_pending) answer |= 0x80; } else - { /* interrupt mode */ - answer = ((~m_int_state) & m_supported_int_mask) >> 8; - + { + // See above concerning the INT levels. if (!m_read_block.isnull()) answer |= m_read_block(TMS9901_INT8_INT15); - answer &= ~ (m_pio_direction_mirror >> 8); + // Remove the bits that are set as outputs (can be any line) + answer &= ~(m_pio_direction_mirror >> 8); answer |= (m_pio_output_mirror & m_pio_direction_mirror) >> 8; } + if (TRACE_PINS) logerror("%s: input on lines INT15..INT8 = %02x\n", tag(), answer); break; case 2: /* exit timer mode */ - // MZ: See comments at the beginning. I'm pretty sure this is not correct. + // MZ: See comments at the beginning. I'm sure that we do not quit clock mode. // m_clock_mode = false; if (!m_read_block.isnull()) @@ -279,20 +332,22 @@ READ8_MEMBER( tms9901_device::read ) else answer = 0; - answer &= ~ m_pio_direction; + answer &= ~m_pio_direction; answer |= (m_pio_output & m_pio_direction) & 0xFF; + if (TRACE_PINS) logerror("%s: input on lines P7..P0 = %02x\n", tag(), answer); break; case 3: // MZ: see above - // m_clock_mode = false; // exit timer mode + // m_clock_mode = false; if (!m_read_block.isnull()) answer = m_read_block(TMS9901_P8_P15); else answer = 0; - answer &= ~ (m_pio_direction >> 8); + answer &= ~(m_pio_direction >> 8); answer |= (m_pio_output & m_pio_direction) >> 8; + if (TRACE_PINS) logerror("%s: input on lines P15..P8 = %02x\n", tag(), answer); break; } @@ -317,19 +372,94 @@ WRITE8_MEMBER ( tms9901_device::write ) { data &= 1; /* clear extra bits */ offset &= 0x01F; - switch (offset) + + if (offset >= 0x10) { - case 0x00: /* write to mode bit */ + int pin = offset & 0x0F; + if (TRACE_PINS) logerror("%s: output on P%d = %d\n", tag(), pin, data); + + int bit = (1 << pin); + + // MZ: see above - I think this is wrong + // m_clock_mode = false; // exit timer mode + + // Once a value is written to a pin, the pin remains in output mode + // until the chip is reset + m_pio_direction |= bit; + + // Latch the value + if (data) + m_pio_output |= bit; + else + m_pio_output &= ~bit; + + if (pin >= 7) + { + // pins P7-P15 are mirrored as INT15*-INT7*, + // also using the same pins in the package + int mirror_bit = (1 << (22 - pin)); + + // See above + m_pio_direction_mirror |= mirror_bit; + + if (data) + m_pio_output_mirror |= mirror_bit; + else + m_pio_output_mirror &= ~mirror_bit; + } + + switch (offset) + { + case 0x10: + if (!m_write_p0.isnull()) m_write_p0(data); break; + case 0x11: + if (!m_write_p1.isnull()) m_write_p1(data); break; + case 0x12: + if (!m_write_p2.isnull()) m_write_p2(data); break; + case 0x13: + if (!m_write_p3.isnull()) m_write_p3(data); break; + case 0x14: + if (!m_write_p4.isnull()) m_write_p4(data); break; + case 0x15: + if (!m_write_p5.isnull()) m_write_p5(data); break; + case 0x16: + if (!m_write_p6.isnull()) m_write_p6(data); break; + case 0x17: + if (!m_write_p7.isnull()) m_write_p7(data); break; + case 0x18: + if (!m_write_p8.isnull()) m_write_p8(data); break; + case 0x19: + if (!m_write_p9.isnull()) m_write_p9(data); break; + case 0x1A: + if (!m_write_p10.isnull()) m_write_p10(data); break; + case 0x1B: + if (!m_write_p11.isnull()) m_write_p11(data); break; + case 0x1C: + if (!m_write_p12.isnull()) m_write_p12(data); break; + case 0x1D: + if (!m_write_p13.isnull()) m_write_p13(data); break; + case 0x1E: + if (!m_write_p14.isnull()) m_write_p14(data); break; + case 0x1F: + if (!m_write_p15.isnull()) m_write_p15(data); break; + + } + return; + } + + if (offset == 0) + { + // Write to control bit (CB) if (data == 0) { - /* we are quitting clock mode */ + // Switch to interrupt mode; quit clock mode m_clock_mode = false; - if (VERBOSE>5) LOG("tms9901: int mode\n"); + if (TRACE_MODE) logerror("%s: int mode\n", tag()); } else { m_clock_mode = true; - if (VERBOSE>5) LOG("tms9901: clock mode\n"); + if (TRACE_MODE) logerror("%s: clock mode\n", tag()); // we are switching to clock mode: latch the current value of // the decrementer register if (m_clock_register != 0) @@ -337,131 +467,75 @@ WRITE8_MEMBER ( tms9901_device::write ) else m_clock_read_register = 0; /* timer inactive... */ } - break; - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x06: - case 0x07: - case 0x08: - case 0x09: - case 0x0A: - case 0x0B: - case 0x0C: - case 0x0D: - case 0x0E: - // write one bit to 9901 (bits 1-14) - // - // m_clock_mode==false ? Disable/Enable an interrupt - // : Bit in clock interval - // - // offset is the index of the modified bit of register (-> interrupt number -1) - if (m_clock_mode) - { /* modify clock interval */ - int mask = 1 << ((offset & 0x0F) - 1); /* corresponding mask */ + } + else + { + if (offset == 0x0f) + { + if (m_clock_mode) + { /* in clock mode this is the soft reset bit */ + if (!data) + { // TMS9901 soft reset (RST2*) + // Spec: "Writing a 0 to bit 15 while in the clock mode executes a soft reset on the I/O pins. + // [...] RST2* will program all ports to the input mode" + m_pio_direction = 0; + m_pio_direction_mirror = 0; - if (data) - m_clock_register |= mask; /* set bit */ + // "RST1* (power-up reset) will reset all mask bits low." + // Spec is not clear on whether the mask bits are also reset by RST2* + // TODO: Check on a real machine. (I'd guess from the text they are not touched) + m_enabled_ints = 0; + if (TRACE_MODE) logerror("%s: Soft reset (RST2*)\n", tag()); + } + } else - m_clock_register &= ~mask; /* clear bit */ + { /* modify interrupt enable mask */ + if (data) + m_enabled_ints |= 0x4000; /* set bit */ + else + m_enabled_ints &= ~0x4000; /* unset bit */ - /* reset clock timer (page 8) */ - if (VERBOSE>6) LOG("tms9901: clock register = %04x\n", m_clock_register); - timer_reload(); - } - else - { /* modify interrupt enable mask */ - int mask = 1 << (offset & 0x0F); /* corresponding mask */ - - if (data) - m_enabled_ints |= mask; /* set bit */ - else - m_enabled_ints &= ~mask; /* unset bit */ - - if (offset == 3) - m_timer_int_pending = false; /* SBO 3 clears pending timer interrupt (??) */ - - if (VERBOSE>6) LOG("tms9901: interrupts = %04x\n", m_enabled_ints); - field_interrupts(); /* changed interrupt state */ - } - break; - case 0x0F: - if (m_clock_mode) - { /* in clock mode this is the soft reset bit */ - if (!data) - { // TMS9901 soft reset (RST2*) - // Spec: "Writing a 0 to bit 15 while in the clock mode executes a soft reset on the I/O pins. - // [...] RST2* will program all ports to the input mode" - m_pio_direction = 0; - m_pio_direction_mirror = 0; - - // "RST1* (power-up reset) will reset all mask bits low." - // Spec is not clear on whether the mask bits are also reset by RST2* - // TODO: Check on a real machine. (I'd guess from the text they are not touched) - m_enabled_ints = 0; - if (VERBOSE>5) LOG("tms9901: Soft reset (RST2*)\n"); + if (TRACE_PINS) logerror("%s: interrupts = %04x\n", tag(), m_enabled_ints); + field_interrupts(); /* changed interrupt state */ } } else - { /* modify interrupt enable mask */ - if (data) - m_enabled_ints |= 0x4000; /* set bit */ + { + // write one bit to 9901 (bits 1-14) + // + // m_clock_mode==false ? Disable/Enable an interrupt + // : Bit in clock interval + // + // offset is the index of the modified bit of register (-> interrupt number -1) + if (m_clock_mode) + { /* modify clock interval */ + int bit = 1 << ((offset & 0x0F) - 1); /* corresponding mask */ + + if (data) + m_clock_register |= bit; /* set bit */ + else + m_clock_register &= ~bit; /* clear bit */ + + /* reset clock timer (page 8) */ + if (TRACE_CLOCK) logerror("%s: clock register = %04x\n", tag(), m_clock_register); + timer_reload(); + } else - m_enabled_ints &= ~0x4000; /* unset bit */ + { /* modify interrupt enable mask */ + int bit = 1 << (offset & 0x0F); /* corresponding mask */ - if (VERBOSE>6) LOG("tms9901: interrupts = %04x\n", m_enabled_ints); - field_interrupts(); /* changed interrupt state */ + if (data) + m_enabled_ints |= bit; /* set bit */ + else + m_enabled_ints &= ~bit; /* unset bit */ + + if (offset == 3) + m_timer_int_pending = false; /* SBO 3 clears pending timer interrupt (??) */ + + if (TRACE_MODE) logerror("%s: enabled interrupts = %04x\n", tag(), m_enabled_ints); + field_interrupts(); /* changed interrupt state */ + } } - break; - case 0x10: - case 0x11: - case 0x12: - case 0x13: - case 0x14: - case 0x15: - case 0x16: - case 0x17: - case 0x18: - case 0x19: - case 0x1A: - case 0x1B: - case 0x1C: - case 0x1D: - case 0x1E: - case 0x1F: - int pin = offset & 0x0F; - if (VERBOSE>6) LOG("tms9901: output on P%d = %d\n", pin, data); - int mask = (1 << pin); - - // MZ: see above - I think this is wrong - // m_clock_mode = false; // exit timer mode - - m_pio_direction |= mask; /* set up as output pin */ - - if (data) - m_pio_output |= mask; - else - m_pio_output &= ~mask; - - if (pin >= 7) - { /* pins P7-P15 are mirrored as INT15*-INT7* */ - int pin2 = 22 - pin; - int mask2 = (1 << pin2); - - m_pio_direction_mirror |= mask2; /* set up as output pin */ - - if (data) - m_pio_output_mirror |= mask2; - else - m_pio_output_mirror &= ~ mask2; - } - - if (!m_write_line[pin].isnull()) - (m_write_line[pin])(data); - - break; } } @@ -476,7 +550,7 @@ void tms9901_device::device_timer(emu_timer &timer, device_timer_id id, int para if (id==DECREMENTER) // we have only that one { m_decrementer_value--; - if (VERBOSE>6) LOG("tms9901: decrementer = %d\n", m_decrementer_value); + if (TRACE_CLOCK) logerror("%s: decrementer = %d\n", tag(), m_decrementer_value); if (m_decrementer_value<=0) { m_timer_int_pending = true; // decrementer interrupt requested @@ -507,7 +581,10 @@ void tms9901_device::device_reset(void) m_pio_direction_mirror = 0; m_pio_output = m_pio_output_mirror = 0; + // This is an interrupt level latch, positive logic (bit 0 = no int) + // The inputs are negative logic (INTx*) m_int_state = 0; + m_old_int_state = -1; field_interrupts(); @@ -524,21 +601,28 @@ void tms9901_device::device_reset(void) void tms9901_device::device_start(void) { - const tms9901_interface *intf = reinterpret_cast(static_config()); - m_supported_int_mask = intf->interrupt_mask; - m_decrementer = timer_alloc(DECREMENTER); m_decrementer->adjust(attotime::from_hz(clock() / 64.), 0, attotime::from_hz(clock() / 64.)); m_decrementer->enable(false); - m_read_block.resolve(intf->read_handler, *this); - - for (int i=0; i < 16; i++) - { - m_write_line[i].resolve(intf->write_handler[i], *this); - } - - m_interrupt.resolve(intf->interrupt_callback, *this); + m_read_block.resolve(); + m_write_p0.resolve(); + m_write_p1.resolve(); + m_write_p2.resolve(); + m_write_p3.resolve(); + m_write_p4.resolve(); + m_write_p5.resolve(); + m_write_p6.resolve(); + m_write_p7.resolve(); + m_write_p8.resolve(); + m_write_p9.resolve(); + m_write_p10.resolve(); + m_write_p11.resolve(); + m_write_p12.resolve(); + m_write_p13.resolve(); + m_write_p14.resolve(); + m_write_p15.resolve(); + m_interrupt.resolve(); m_clock_register = 0; } diff --git a/src/emu/machine/tms9901.h b/src/emu/machine/tms9901.h index a1f610f4072..096a654046a 100644 --- a/src/emu/machine/tms9901.h +++ b/src/emu/machine/tms9901.h @@ -23,10 +23,11 @@ extern const device_type TMS9901; MACROS ***************************************************************************/ -/* Masks for the interrupts levels available on TMS9901 */ +// Masks for the interrupts levels available on TMS9901 + #define TMS9901_INT1 0x0002 #define TMS9901_INT2 0x0004 -#define TMS9901_INT3 0x0008 // overriden by the timer interrupt +#define TMS9901_INT3 0x0008 // overridden by the timer interrupt #define TMS9901_INT4 0x0010 #define TMS9901_INT5 0x0020 #define TMS9901_INT6 0x0040 @@ -52,14 +53,6 @@ enum CLASS DEFINITION ***************************************************************************/ -struct tms9901_interface -{ - int interrupt_mask; // a bit for each input pin whose state is always notified to the TMS9901 core - devcb_read8 read_handler; // 4*8 bits, to be selected using the offset (0-3) - devcb_write_line write_handler[16]; // 16 Pn outputs - devcb_write8 interrupt_callback; // called when interrupt bus state changes -}; - class tms9901_device : public device_t { public: @@ -70,6 +63,27 @@ public: DECLARE_READ8_MEMBER( read ); DECLARE_WRITE8_MEMBER( write ); + template static devcb2_base &static_set_readblock_callback(device_t &device, _Object object) { return downcast(device).m_read_block.set_callback(object); } + + template static devcb2_base &static_set_p0_callback(device_t &device, _Object object) { return downcast(device).m_write_p0.set_callback(object); } + template static devcb2_base &static_set_p1_callback(device_t &device, _Object object) { return downcast(device).m_write_p1.set_callback(object); } + template static devcb2_base &static_set_p2_callback(device_t &device, _Object object) { return downcast(device).m_write_p2.set_callback(object); } + template static devcb2_base &static_set_p3_callback(device_t &device, _Object object) { return downcast(device).m_write_p3.set_callback(object); } + template static devcb2_base &static_set_p4_callback(device_t &device, _Object object) { return downcast(device).m_write_p4.set_callback(object); } + template static devcb2_base &static_set_p5_callback(device_t &device, _Object object) { return downcast(device).m_write_p5.set_callback(object); } + template static devcb2_base &static_set_p6_callback(device_t &device, _Object object) { return downcast(device).m_write_p6.set_callback(object); } + template static devcb2_base &static_set_p7_callback(device_t &device, _Object object) { return downcast(device).m_write_p7.set_callback(object); } + template static devcb2_base &static_set_p8_callback(device_t &device, _Object object) { return downcast(device).m_write_p8.set_callback(object); } + template static devcb2_base &static_set_p9_callback(device_t &device, _Object object) { return downcast(device).m_write_p9.set_callback(object); } + template static devcb2_base &static_set_p10_callback(device_t &device, _Object object) { return downcast(device).m_write_p10.set_callback(object); } + template static devcb2_base &static_set_p11_callback(device_t &device, _Object object) { return downcast(device).m_write_p11.set_callback(object); } + template static devcb2_base &static_set_p12_callback(device_t &device, _Object object) { return downcast(device).m_write_p12.set_callback(object); } + template static devcb2_base &static_set_p13_callback(device_t &device, _Object object) { return downcast(device).m_write_p13.set_callback(object); } + template static devcb2_base &static_set_p14_callback(device_t &device, _Object object) { return downcast(device).m_write_p14.set_callback(object); } + template static devcb2_base &static_set_p15_callback(device_t &device, _Object object) { return downcast(device).m_write_p15.set_callback(object); } + + template static devcb2_base &static_set_intlevel_callback(device_t &device, _Object object) { return downcast(device).m_interrupt.set_callback(object); } + private: static const device_timer_id DECREMENTER = 0; @@ -77,18 +91,14 @@ private: void timer_reload(void); void field_interrupts(void); - virtual void device_start(void); - virtual void device_stop(void); - virtual void device_reset(void); + void device_start(void); + void device_stop(void); + void device_reset(void); - /* interrupt registers */ - // mask: bit #n is set if pin #n is supported as an interrupt pin, - // i.e. the driver sends a notification whenever the pin state changes - // setting these bits is not required, but it saves you the trouble of - // saving the state of interrupt pins and feeding it to the port read - // handlers again - int m_supported_int_mask; - int m_int_state; // state of the int1-int15 lines (must be inverted when queried) + // State of the INT1-INT15 lines (must be inverted when queried) + // Note that the levels must also be delivered when reading the pins, which + // may require to latch the int levels. + int m_int_state; int m_old_int_state; // stores the previous value to avoid useless INT line assertions int m_enabled_ints; // interrupt enable mask @@ -127,18 +137,88 @@ private: // ======================================================================= - // Callbacks - devcb_resolved_read8 m_read_block; - devcb_resolved_write_line m_write_line[16]; - devcb_resolved_write8 m_interrupt; // also delivers the interrupt level + // Read callback. + devcb2_read8 m_read_block; + + // I/O lines, used for output. When used as inputs, the levels are delivered via the m_read_block + devcb2_write_line m_write_p0; + devcb2_write_line m_write_p1; + devcb2_write_line m_write_p2; + devcb2_write_line m_write_p3; + devcb2_write_line m_write_p4; + devcb2_write_line m_write_p5; + devcb2_write_line m_write_p6; + devcb2_write_line m_write_p7; + devcb2_write_line m_write_p8; + devcb2_write_line m_write_p9; + devcb2_write_line m_write_p10; + devcb2_write_line m_write_p11; + devcb2_write_line m_write_p12; + devcb2_write_line m_write_p13; + devcb2_write_line m_write_p14; + devcb2_write_line m_write_p15; + + // The invocation corresponds to the INTREQ signal (with the level passed as data) + // and the address delivers the interrupt level (0-15) + devcb2_write8 m_interrupt; }; /*************************************************************************** DEVICE CONFIGURATION MACROS ***************************************************************************/ -#define MCFG_TMS9901_ADD(_tag, _intrf, _rate) \ - MCFG_DEVICE_ADD(_tag, TMS9901, _rate) \ - MCFG_DEVICE_CONFIG(_intrf) +#define MCFG_TMS9901_READBLOCK_HANDLER( _read ) \ + devcb = &tms9901_device::static_set_readblock_callback( *device, DEVCB2_##_read ); + +#define MCFG_TMS9901_P0_HANDLER( _write ) \ + devcb = &tms9901_device::static_set_p0_callback( *device, DEVCB2_##_write ); + +#define MCFG_TMS9901_P1_HANDLER( _write ) \ + devcb = &tms9901_device::static_set_p1_callback( *device, DEVCB2_##_write ); + +#define MCFG_TMS9901_P2_HANDLER( _write ) \ + devcb = &tms9901_device::static_set_p2_callback( *device, DEVCB2_##_write ); + +#define MCFG_TMS9901_P3_HANDLER( _write ) \ + devcb = &tms9901_device::static_set_p3_callback( *device, DEVCB2_##_write ); + +#define MCFG_TMS9901_P4_HANDLER( _write ) \ + devcb = &tms9901_device::static_set_p4_callback( *device, DEVCB2_##_write ); + +#define MCFG_TMS9901_P5_HANDLER( _write ) \ + devcb = &tms9901_device::static_set_p5_callback( *device, DEVCB2_##_write ); + +#define MCFG_TMS9901_P6_HANDLER( _write ) \ + devcb = &tms9901_device::static_set_p6_callback( *device, DEVCB2_##_write ); + +#define MCFG_TMS9901_P7_HANDLER( _write ) \ + devcb = &tms9901_device::static_set_p7_callback( *device, DEVCB2_##_write ); + +#define MCFG_TMS9901_P8_HANDLER( _write ) \ + devcb = &tms9901_device::static_set_p8_callback( *device, DEVCB2_##_write ); + +#define MCFG_TMS9901_P9_HANDLER( _write ) \ + devcb = &tms9901_device::static_set_p9_callback( *device, DEVCB2_##_write ); + +#define MCFG_TMS9901_P10_HANDLER( _write ) \ + devcb = &tms9901_device::static_set_p10_callback( *device, DEVCB2_##_write ); + +#define MCFG_TMS9901_P11_HANDLER( _write ) \ + devcb = &tms9901_device::static_set_p11_callback( *device, DEVCB2_##_write ); + +#define MCFG_TMS9901_P12_HANDLER( _write ) \ + devcb = &tms9901_device::static_set_p12_callback( *device, DEVCB2_##_write ); + +#define MCFG_TMS9901_P13_HANDLER( _write ) \ + devcb = &tms9901_device::static_set_p13_callback( *device, DEVCB2_##_write ); + +#define MCFG_TMS9901_P14_HANDLER( _write ) \ + devcb = &tms9901_device::static_set_p14_callback( *device, DEVCB2_##_write ); + +#define MCFG_TMS9901_P15_HANDLER( _write ) \ + devcb = &tms9901_device::static_set_p15_callback( *device, DEVCB2_##_write ); + +#define MCFG_TMS9901_INTLEVEL_HANDLER( _intlevel ) \ + devcb = &tms9901_device::static_set_intlevel_callback( *device, DEVCB2_##_intlevel ); #endif /* __TMS9901_H__ */ diff --git a/src/mess/drivers/geneve.c b/src/mess/drivers/geneve.c index f9569be16cc..61d947e7ea0 100644 --- a/src/mess/drivers/geneve.c +++ b/src/mess/drivers/geneve.c @@ -275,10 +275,6 @@ public: line_state m_video_wait; // reflects the line to the mapper for CRU query int m_ready_line, m_ready_line1; - -private: - //int m_joystick_select; - // Some values to keep. Rest is on the geneve_mapper. }; /* @@ -551,40 +547,43 @@ WRITE8_MEMBER( geneve_state::tms9901_interrupt ) m_cpu->set_input_line(INT_9995_INT1, data); } -/* tms9901 setup */ +/* +// tms9901 setup const tms9901_interface tms9901_wiring_geneve = { - TMS9901_INT1 | TMS9901_INT2 | TMS9901_INT8 | TMS9901_INTB | TMS9901_INTC, /* only input pins whose state is always known */ + TMS9901_INT1 | TMS9901_INT2 | TMS9901_INT8 | TMS9901_INTB | TMS9901_INTC, - // read handler - DEVCB_DRIVER_MEMBER(geneve_state, read_by_9901), + // read handler + DEVCB_DRIVER_MEMBER(geneve_state, read_by_9901), - { /* write handlers */ - DEVCB_DRIVER_LINE_MEMBER(geneve_state, peripheral_bus_reset), - DEVCB_DRIVER_LINE_MEMBER(geneve_state, VDP_reset), - DEVCB_DRIVER_LINE_MEMBER(geneve_state, joystick_select), - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_DEVICE_LINE_MEMBER(GKEYBOARD_TAG, geneve_keyboard_device, reset_line), - DEVCB_DRIVER_LINE_MEMBER(geneve_state, extbus_wait_states), - DEVCB_NULL, - DEVCB_DRIVER_LINE_MEMBER(geneve_state, video_wait_states), - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL - }, + { // write handlers + DEVCB_DRIVER_LINE_MEMBER(geneve_state, peripheral_bus_reset), + DEVCB_DRIVER_LINE_MEMBER(geneve_state, VDP_reset), + DEVCB_DRIVER_LINE_MEMBER(geneve_state, joystick_select), + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_DEVICE_LINE_MEMBER(GKEYBOARD_TAG, geneve_keyboard_device, reset_line), + DEVCB_DRIVER_LINE_MEMBER(geneve_state, extbus_wait_states), + DEVCB_NULL, + DEVCB_DRIVER_LINE_MEMBER(geneve_state, video_wait_states), + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL + }, - /* interrupt handler */ - DEVCB_DRIVER_MEMBER(geneve_state, tms9901_interrupt) + // interrupt handler + DEVCB_DRIVER_MEMBER(geneve_state, tms9901_interrupt) }; +*/ /******************************************************************* Signal lines *******************************************************************/ + /* inta is connected to both tms9901 IRQ1 line and to tms9995 INT4/EC line. */ @@ -748,7 +747,15 @@ static MACHINE_CONFIG_START( geneve_60hz, geneve_state ) MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", geneve_state, geneve_hblank_interrupt, SCREEN_TAG, 0, 1) /* 262.5 in 60Hz, 312.5 in 50Hz */ // Main board components - MCFG_TMS9901_ADD(TMS9901_TAG, tms9901_wiring_geneve, 3000000) + MCFG_DEVICE_ADD(TMS9901_TAG, TMS9901, 3000000) + MCFG_TMS9901_READBLOCK_HANDLER( READ8(geneve_state, read_by_9901) ) + MCFG_TMS9901_P0_HANDLER( WRITELINE( geneve_state, peripheral_bus_reset) ) + MCFG_TMS9901_P1_HANDLER( WRITELINE( geneve_state, VDP_reset) ) + MCFG_TMS9901_P2_HANDLER( WRITELINE( geneve_state, joystick_select) ) + MCFG_TMS9901_P6_HANDLER( DEVWRITELINE( GKEYBOARD_TAG, geneve_keyboard_device, reset_line) ) + MCFG_TMS9901_P7_HANDLER( WRITELINE( geneve_state, extbus_wait_states) ) + MCFG_TMS9901_P9_HANDLER( WRITELINE( geneve_state, video_wait_states) ) + MCFG_TMS9901_INTLEVEL_HANDLER( WRITE8( geneve_state, tms9901_interrupt) ) // Mapper MCFG_DEVICE_ADD(GMAPPER_TAG, GENEVE_MAPPER, 0) diff --git a/src/mess/drivers/ti99_4p.c b/src/mess/drivers/ti99_4p.c index 769861fe721..237878ed354 100644 --- a/src/mess/drivers/ti99_4p.c +++ b/src/mess/drivers/ti99_4p.c @@ -167,6 +167,10 @@ private: // Mapper registers UINT8 m_mapper[16]; + // Latch for 9901 INT2, INT1 lines + int m_9901_int; + void set_9901_int(int line, line_state state); + int m_ready_prev; // for debugging purposes only }; @@ -566,8 +570,8 @@ READ8_MEMBER( ti99_4p_state::read_by_9901 ) { case TMS9901_CB_INT7: // Read pins INT3*-INT7* of TI99's 9901. - // bit 1: INT1 status (interrupt; not set at this place) - // bit 2: INT2 status (interrupt; not set at this place) + // bit 1: INT1 status + // bit 2: INT2 status // bit 3-7: keyboard status bits 0 to 4 // // |K|K|K|K|K|I2|I1|C| @@ -584,7 +588,7 @@ READ8_MEMBER( ti99_4p_state::read_by_9901 ) { answer &= ~(ioport("ALPHA")->read()); } - answer = (answer << 3) & 0xf8; + answer = (answer << 3) | m_9901_int; break; case TMS9901_INT8_INT15: @@ -679,37 +683,40 @@ WRITE_LINE_MEMBER( ti99_4p_state::cassette_output ) m_cassette->output((state!=0)? +1 : -1); } -/* TMS9901 setup. The callback functions pass a reference to the TMS9901 as device. */ +/* +// TMS9901 setup. The callback functions pass a reference to the TMS9901 as device. const tms9901_interface tms9901_wiring_sgcpu = { - TMS9901_INT1 | TMS9901_INT2 | TMS9901_INTC, /* only input pins whose state is always known */ + TMS9901_INT1 | TMS9901_INT2 | TMS9901_INTC, // only input pins whose state is always known - // read handler - DEVCB_DRIVER_MEMBER(ti99_4p_state, read_by_9901), + // read handler + DEVCB_DRIVER_MEMBER(ti99_4p_state, read_by_9901), - { // write handlers - DEVCB_NULL, - DEVCB_NULL, - DEVCB_DRIVER_LINE_MEMBER(ti99_4p_state, keyC0), - DEVCB_DRIVER_LINE_MEMBER(ti99_4p_state, keyC1), - DEVCB_DRIVER_LINE_MEMBER(ti99_4p_state, keyC2), - DEVCB_DRIVER_LINE_MEMBER(ti99_4p_state, alphaW), - DEVCB_DRIVER_LINE_MEMBER(ti99_4p_state, cs_motor), - DEVCB_NULL, - DEVCB_DRIVER_LINE_MEMBER(ti99_4p_state, audio_gate), - DEVCB_DRIVER_LINE_MEMBER(ti99_4p_state, cassette_output), - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL - }, + { // write handlers + DEVCB_NULL, + DEVCB_NULL, + DEVCB_DRIVER_LINE_MEMBER(ti99_4p_state, keyC0), + DEVCB_DRIVER_LINE_MEMBER(ti99_4p_state, keyC1), + DEVCB_DRIVER_LINE_MEMBER(ti99_4p_state, keyC2), + DEVCB_DRIVER_LINE_MEMBER(ti99_4p_state, alphaW), + DEVCB_DRIVER_LINE_MEMBER(ti99_4p_state, cs_motor), + DEVCB_NULL, + DEVCB_DRIVER_LINE_MEMBER(ti99_4p_state, audio_gate), + DEVCB_DRIVER_LINE_MEMBER(ti99_4p_state, cassette_output), + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL + }, - /* interrupt handler */ - DEVCB_DRIVER_MEMBER(ti99_4p_state, tms9901_interrupt) + // interrupt handler + DEVCB_DRIVER_MEMBER(ti99_4p_state, tms9901_interrupt) }; +*/ + /*************************************************************************** Control lines ****************************************************************************/ @@ -751,12 +758,18 @@ WRITE_LINE_MEMBER( ti99_4p_state::console_ready_dmux ) m_cpu->set_ready(combined); } +void ti99_4p_state::set_9901_int( int line, line_state state) +{ + m_tms9901->set_single_int(line, state); + // We latch the value for the read operation. Mind the negative logic. + if (state==CLEAR_LINE) m_9901_int |= (1<6) LOG("ti99_4p: EXTINT level = %02x\n", state); - if (m_tms9901 != NULL) - m_tms9901->set_single_int(1, state); + set_9901_int(1, (line_state)state); } WRITE_LINE_MEMBER( ti99_4p_state::notconnected ) @@ -836,7 +849,7 @@ void ti99_4p_state::machine_start() */ WRITE_LINE_MEMBER(ti99_4p_state::set_tms9901_INT2_from_v9938) { - m_tms9901->set_single_int(2, state); + set_9901_int(2, (line_state)state); } /* @@ -844,10 +857,11 @@ WRITE_LINE_MEMBER(ti99_4p_state::set_tms9901_INT2_from_v9938) */ MACHINE_RESET_MEMBER(ti99_4p_state,ti99_4p) { - m_tms9901->set_single_int(12, 0); + set_9901_int(12, CLEAR_LINE); m_cpu->set_ready(ASSERT_LINE); m_cpu->set_hold(CLEAR_LINE); + m_9901_int = 0x03; // INT2* and INT1* set to 1, i.e. inactive } TIMER_DEVICE_CALLBACK_MEMBER(ti99_4p_state::sgcpu_hblank_interrupt) @@ -873,7 +887,15 @@ static MACHINE_CONFIG_START( ti99_4p_60hz, ti99_4p_state ) MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", ti99_4p_state, sgcpu_hblank_interrupt, SCREEN_TAG, 0, 1) // tms9901 - MCFG_TMS9901_ADD(TMS9901_TAG, tms9901_wiring_sgcpu, 3000000) + MCFG_DEVICE_ADD(TMS9901_TAG, TMS9901, 3000000) + MCFG_TMS9901_READBLOCK_HANDLER( READ8(ti99_4p_state, read_by_9901) ) + MCFG_TMS9901_P2_HANDLER( WRITELINE( ti99_4p_state, keyC0) ) + MCFG_TMS9901_P3_HANDLER( WRITELINE( ti99_4p_state, keyC1) ) + MCFG_TMS9901_P4_HANDLER( WRITELINE( ti99_4p_state, keyC2) ) + MCFG_TMS9901_P6_HANDLER( WRITELINE( ti99_4p_state, cs_motor) ) + MCFG_TMS9901_P8_HANDLER( WRITELINE( ti99_4p_state, audio_gate) ) + MCFG_TMS9901_P9_HANDLER( WRITELINE( ti99_4p_state, cassette_output) ) + MCFG_TMS9901_INTLEVEL_HANDLER( WRITE8( ti99_4p_state, tms9901_interrupt) ) // Peripheral expansion box (SGCPU composition) MCFG_DEVICE_ADD( PERIBOX_TAG, PERIBOX_SG, 0) diff --git a/src/mess/drivers/ti99_4x.c b/src/mess/drivers/ti99_4x.c index bac2995ec3b..235e0adc45f 100644 --- a/src/mess/drivers/ti99_4x.c +++ b/src/mess/drivers/ti99_4x.c @@ -137,7 +137,11 @@ private: void console_ready_join(int id, int state); // Console type - int m_console; + int m_console; + + // Latch for 9901 INT2, INT1 lines + int m_9901_int; + void set_9901_int(int line, line_state state); // Connected devices required_device m_cpu; @@ -443,8 +447,8 @@ READ8_MEMBER( ti99_4x_state::read_by_9901 ) case TMS9901_CB_INT7: // // Read pins INT3*-INT7* of TI99's 9901. - // bit 1: INT1 status (interrupt; not set at this place) - // bit 2: INT2 status (interrupt; not set at this place) + // bit 1: INT1 status + // bit 2: INT2 status // bit 3-7: keyboard status bits 0 to 4 // // |K|K|K|K|K|I2|I1|C| @@ -470,7 +474,7 @@ READ8_MEMBER( ti99_4x_state::read_by_9901 ) { answer &= ~(ioport("ALPHA")->read()); } - answer = (answer << 3) & 0xf8; + answer = (answer << 3) | m_9901_int; break; @@ -631,19 +635,27 @@ WRITE_LINE_MEMBER( ti99_4x_state::dbin_line ) /*****************************************************************************/ +void ti99_4x_state::set_9901_int( int line, line_state state) +{ + m_tms9901->set_single_int(line, state); + // We latch the value for the read operation. Mind the negative logic. + if (state==CLEAR_LINE) m_9901_int |= (1<set_single_int(2, state); + set_9901_int(2, (line_state)state); } WRITE_LINE_MEMBER(ti99_4x_state::set_tms9901_INT2_from_v9938) { if (TRACE_INTERRUPTS) LOG("ti99_4x: VDP int 2 on tms9901, level=%d\n", state); - m_tms9901->set_single_int(2, state); + set_9901_int(2, (line_state)state); } /* @@ -652,7 +664,7 @@ WRITE_LINE_MEMBER(ti99_4x_state::set_tms9901_INT2_from_v9938) WRITE_LINE_MEMBER( ti99_4x_state::set_tms9901_INT12) { if (TRACE_INTERRUPTS) LOG("ti99_4x: joyport INT 12 on tms9901, level=%d\n", state); - m_tms9901->set_single_int(12, state); + set_9901_int(12, (line_state)state); } /* @@ -736,8 +748,7 @@ WRITE_LINE_MEMBER( ti99_4x_state::console_reset ) WRITE_LINE_MEMBER( ti99_4x_state::extint ) { if (TRACE_INTERRUPTS) LOG("ti99_4x: EXTINT level = %02x\n", state); - if (m_tms9901 != NULL) - m_tms9901->set_single_int(1, state); + set_9901_int(1, (line_state)state); } WRITE_LINE_MEMBER( ti99_4x_state::notconnected ) @@ -753,67 +764,70 @@ static TMS9928A_INTERFACE(ti99_4_tms9928a_interface) DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, set_tms9901_INT2) }; -/* TMS9901 setup. */ +/* TMS9901 setup. const tms9901_interface tms9901_wiring_ti99_4 = { - TMS9901_INT1 | TMS9901_INT2 | TMS9901_INTC, /* only input pins whose state is always known */ + TMS9901_INT1 | TMS9901_INT2 | TMS9901_INTC, // only input pins whose state is always known - // read handler - DEVCB_DRIVER_MEMBER(ti99_4x_state, read_by_9901), + // read handler + DEVCB_DRIVER_MEMBER(ti99_4x_state, read_by_9901), - // write handlers - { - DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, handset_ack), - DEVCB_NULL, - DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, keyC0), - DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, keyC1), - DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, keyC2), - DEVCB_NULL, - DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, cs1_motor), - DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, cs2_motor), - DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, audio_gate), - DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, cassette_output), - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL - }, + // write handlers + { + DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, handset_ack), + DEVCB_NULL, + DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, keyC0), + DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, keyC1), + DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, keyC2), + DEVCB_NULL, + DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, cs1_motor), + DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, cs2_motor), + DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, audio_gate), + DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, cassette_output), + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL + }, - // interrupt handler - DEVCB_DRIVER_MEMBER(ti99_4x_state, tms9901_interrupt) + // interrupt handler + DEVCB_DRIVER_MEMBER(ti99_4x_state, tms9901_interrupt) }; +*/ +/* const tms9901_interface tms9901_wiring_ti99_4a = { - TMS9901_INT1 | TMS9901_INT2 | TMS9901_INTC, + TMS9901_INT1 | TMS9901_INT2 | TMS9901_INTC, - // read handler - DEVCB_DRIVER_MEMBER(ti99_4x_state, read_by_9901), + // read handler + DEVCB_DRIVER_MEMBER(ti99_4x_state, read_by_9901), - // write handlers - { - DEVCB_NULL, - DEVCB_NULL, - DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, keyC0), - DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, keyC1), - DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, keyC2), - DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, alphaW), - DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, cs1_motor), - DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, cs2_motor), - DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, audio_gate), - DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, cassette_output), - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL - }, + // write handlers + { + DEVCB_NULL, + DEVCB_NULL, + DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, keyC0), + DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, keyC1), + DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, keyC2), + DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, alphaW), + DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, cs1_motor), + DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, cs2_motor), + DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, audio_gate), + DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, cassette_output), + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL + }, - DEVCB_DRIVER_MEMBER(ti99_4x_state, tms9901_interrupt) + DEVCB_DRIVER_MEMBER(ti99_4x_state, tms9901_interrupt) }; +*/ /* Devices attached to the databus multiplexer. We cannot solve this with @@ -886,6 +900,7 @@ MACHINE_RESET_MEMBER(ti99_4x_state,ti99_4) { m_cpu->set_ready(ASSERT_LINE); m_cpu->set_hold(CLEAR_LINE); + m_9901_int = 0x03; // INT2* and INT1* set to 1, i.e. inactive } /* @@ -901,7 +916,18 @@ static MACHINE_CONFIG_START( ti99_4_60hz, ti99_4x_state ) MCFG_TI_TMS991x_ADD_NTSC(VIDEO_SYSTEM_TAG, TMS9918, ti99_4_tms9928a_interface) /* Main board */ - MCFG_TMS9901_ADD(TMS9901_TAG, tms9901_wiring_ti99_4, 3000000) + MCFG_DEVICE_ADD(TMS9901_TAG, TMS9901, 3000000) + MCFG_TMS9901_READBLOCK_HANDLER( READ8(ti99_4x_state, read_by_9901) ) + MCFG_TMS9901_P0_HANDLER( WRITELINE( ti99_4x_state, handset_ack) ) + MCFG_TMS9901_P2_HANDLER( WRITELINE( ti99_4x_state, keyC0) ) + MCFG_TMS9901_P3_HANDLER( WRITELINE( ti99_4x_state, keyC1) ) + MCFG_TMS9901_P4_HANDLER( WRITELINE( ti99_4x_state, keyC2) ) + MCFG_TMS9901_P6_HANDLER( WRITELINE( ti99_4x_state, cs1_motor) ) + MCFG_TMS9901_P7_HANDLER( WRITELINE( ti99_4x_state, cs2_motor) ) + MCFG_TMS9901_P8_HANDLER( WRITELINE( ti99_4x_state, audio_gate) ) + MCFG_TMS9901_P9_HANDLER( WRITELINE( ti99_4x_state, cassette_output) ) + MCFG_TMS9901_INTLEVEL_HANDLER( WRITE8( ti99_4x_state, tms9901_interrupt) ) + MCFG_DMUX_ADD( DATAMUX_TAG, datamux_conf ) MCFG_DMUX_READY_HANDLER( WRITELINE(ti99_4x_state, console_ready_dmux) ) MCFG_TI99_GROMPORT_ADD( GROMPORT_TAG ) @@ -953,8 +979,19 @@ static MACHINE_CONFIG_START( ti99_4_50hz, ti99_4x_state ) /* video hardware */ MCFG_TI_TMS991x_ADD_PAL(VIDEO_SYSTEM_TAG, TMS9929, ti99_4_tms9928a_interface) - /* main board */ - MCFG_TMS9901_ADD(TMS9901_TAG, tms9901_wiring_ti99_4, 3000000) + /* Main board */ + MCFG_DEVICE_ADD(TMS9901_TAG, TMS9901, 3000000) + MCFG_TMS9901_READBLOCK_HANDLER( READ8(ti99_4x_state, read_by_9901) ) + MCFG_TMS9901_P0_HANDLER( WRITELINE( ti99_4x_state, handset_ack) ) + MCFG_TMS9901_P2_HANDLER( WRITELINE( ti99_4x_state, keyC0) ) + MCFG_TMS9901_P3_HANDLER( WRITELINE( ti99_4x_state, keyC1) ) + MCFG_TMS9901_P4_HANDLER( WRITELINE( ti99_4x_state, keyC2) ) + MCFG_TMS9901_P6_HANDLER( WRITELINE( ti99_4x_state, cs1_motor) ) + MCFG_TMS9901_P7_HANDLER( WRITELINE( ti99_4x_state, cs2_motor) ) + MCFG_TMS9901_P8_HANDLER( WRITELINE( ti99_4x_state, audio_gate) ) + MCFG_TMS9901_P9_HANDLER( WRITELINE( ti99_4x_state, cassette_output) ) + MCFG_TMS9901_INTLEVEL_HANDLER( WRITE8( ti99_4x_state, tms9901_interrupt) ) + MCFG_DMUX_ADD( DATAMUX_TAG, datamux_conf ) MCFG_DMUX_READY_HANDLER( WRITELINE(ti99_4x_state, console_ready_dmux) ) @@ -1026,7 +1063,18 @@ static MACHINE_CONFIG_START( ti99_4a_60hz, ti99_4x_state ) MCFG_TI_TMS991x_ADD_NTSC(VIDEO_SYSTEM_TAG, TMS9918A, ti99_4_tms9928a_interface) /* Main board */ - MCFG_TMS9901_ADD(TMS9901_TAG, tms9901_wiring_ti99_4a, 3000000) + MCFG_DEVICE_ADD(TMS9901_TAG, TMS9901, 3000000) + MCFG_TMS9901_READBLOCK_HANDLER( READ8(ti99_4x_state, read_by_9901) ) + MCFG_TMS9901_P2_HANDLER( WRITELINE( ti99_4x_state, keyC0) ) + MCFG_TMS9901_P3_HANDLER( WRITELINE( ti99_4x_state, keyC1) ) + MCFG_TMS9901_P4_HANDLER( WRITELINE( ti99_4x_state, keyC2) ) + MCFG_TMS9901_P5_HANDLER( WRITELINE( ti99_4x_state, alphaW) ) + MCFG_TMS9901_P6_HANDLER( WRITELINE( ti99_4x_state, cs1_motor) ) + MCFG_TMS9901_P7_HANDLER( WRITELINE( ti99_4x_state, cs2_motor) ) + MCFG_TMS9901_P8_HANDLER( WRITELINE( ti99_4x_state, audio_gate) ) + MCFG_TMS9901_P9_HANDLER( WRITELINE( ti99_4x_state, cassette_output) ) + MCFG_TMS9901_INTLEVEL_HANDLER( WRITE8( ti99_4x_state, tms9901_interrupt) ) + MCFG_DMUX_ADD( DATAMUX_TAG, datamux_conf ) MCFG_DMUX_READY_HANDLER( WRITELINE(ti99_4x_state, console_ready_dmux) ) MCFG_TI99_GROMPORT_ADD( GROMPORT_TAG ) @@ -1078,7 +1126,18 @@ static MACHINE_CONFIG_START( ti99_4a_50hz, ti99_4x_state ) MCFG_TI_TMS991x_ADD_PAL(VIDEO_SYSTEM_TAG, TMS9929A, ti99_4_tms9928a_interface) /* Main board */ - MCFG_TMS9901_ADD(TMS9901_TAG, tms9901_wiring_ti99_4a, 3000000) + MCFG_DEVICE_ADD(TMS9901_TAG, TMS9901, 3000000) + MCFG_TMS9901_READBLOCK_HANDLER( READ8(ti99_4x_state, read_by_9901) ) + MCFG_TMS9901_P2_HANDLER( WRITELINE( ti99_4x_state, keyC0) ) + MCFG_TMS9901_P3_HANDLER( WRITELINE( ti99_4x_state, keyC1) ) + MCFG_TMS9901_P4_HANDLER( WRITELINE( ti99_4x_state, keyC2) ) + MCFG_TMS9901_P5_HANDLER( WRITELINE( ti99_4x_state, alphaW) ) + MCFG_TMS9901_P6_HANDLER( WRITELINE( ti99_4x_state, cs1_motor) ) + MCFG_TMS9901_P7_HANDLER( WRITELINE( ti99_4x_state, cs2_motor) ) + MCFG_TMS9901_P8_HANDLER( WRITELINE( ti99_4x_state, audio_gate) ) + MCFG_TMS9901_P9_HANDLER( WRITELINE( ti99_4x_state, cassette_output) ) + MCFG_TMS9901_INTLEVEL_HANDLER( WRITE8( ti99_4x_state, tms9901_interrupt) ) + MCFG_DMUX_ADD( DATAMUX_TAG, datamux_conf ) MCFG_DMUX_READY_HANDLER( WRITELINE(ti99_4x_state, console_ready_dmux) ) MCFG_TI99_GROMPORT_ADD( GROMPORT_TAG ) @@ -1147,7 +1206,18 @@ static MACHINE_CONFIG_START( ti99_4qi_60hz, ti99_4x_state ) MCFG_TI_TMS991x_ADD_NTSC(VIDEO_SYSTEM_TAG, TMS9918A, ti99_4_tms9928a_interface) /* Main board */ - MCFG_TMS9901_ADD(TMS9901_TAG, tms9901_wiring_ti99_4a, 3000000) + MCFG_DEVICE_ADD(TMS9901_TAG, TMS9901, 3000000) + MCFG_TMS9901_READBLOCK_HANDLER( READ8(ti99_4x_state, read_by_9901) ) + MCFG_TMS9901_P2_HANDLER( WRITELINE( ti99_4x_state, keyC0) ) + MCFG_TMS9901_P3_HANDLER( WRITELINE( ti99_4x_state, keyC1) ) + MCFG_TMS9901_P4_HANDLER( WRITELINE( ti99_4x_state, keyC2) ) + MCFG_TMS9901_P5_HANDLER( WRITELINE( ti99_4x_state, alphaW) ) + MCFG_TMS9901_P6_HANDLER( WRITELINE( ti99_4x_state, cs1_motor) ) + MCFG_TMS9901_P7_HANDLER( WRITELINE( ti99_4x_state, cs2_motor) ) + MCFG_TMS9901_P8_HANDLER( WRITELINE( ti99_4x_state, audio_gate) ) + MCFG_TMS9901_P9_HANDLER( WRITELINE( ti99_4x_state, cassette_output) ) + MCFG_TMS9901_INTLEVEL_HANDLER( WRITE8( ti99_4x_state, tms9901_interrupt) ) + MCFG_DMUX_ADD( DATAMUX_TAG, datamux_conf ) MCFG_DMUX_READY_HANDLER( WRITELINE(ti99_4x_state, console_ready_dmux) ) MCFG_TI99_GROMPORT_ADD( GROMPORT_TAG ) @@ -1199,7 +1269,18 @@ static MACHINE_CONFIG_START( ti99_4qi_50hz, ti99_4x_state ) MCFG_TI_TMS991x_ADD_PAL(VIDEO_SYSTEM_TAG, TMS9929A, ti99_4_tms9928a_interface) /* Main board */ - MCFG_TMS9901_ADD(TMS9901_TAG, tms9901_wiring_ti99_4a, 3000000) + MCFG_DEVICE_ADD(TMS9901_TAG, TMS9901, 3000000) + MCFG_TMS9901_READBLOCK_HANDLER( READ8(ti99_4x_state, read_by_9901) ) + MCFG_TMS9901_P2_HANDLER( WRITELINE( ti99_4x_state, keyC0) ) + MCFG_TMS9901_P3_HANDLER( WRITELINE( ti99_4x_state, keyC1) ) + MCFG_TMS9901_P4_HANDLER( WRITELINE( ti99_4x_state, keyC2) ) + MCFG_TMS9901_P5_HANDLER( WRITELINE( ti99_4x_state, alphaW) ) + MCFG_TMS9901_P6_HANDLER( WRITELINE( ti99_4x_state, cs1_motor) ) + MCFG_TMS9901_P7_HANDLER( WRITELINE( ti99_4x_state, cs2_motor) ) + MCFG_TMS9901_P8_HANDLER( WRITELINE( ti99_4x_state, audio_gate) ) + MCFG_TMS9901_P9_HANDLER( WRITELINE( ti99_4x_state, cassette_output) ) + MCFG_TMS9901_INTLEVEL_HANDLER( WRITE8( ti99_4x_state, tms9901_interrupt) ) + MCFG_DMUX_ADD( DATAMUX_TAG, datamux_conf ) MCFG_DMUX_READY_HANDLER( WRITELINE(ti99_4x_state, console_ready_dmux) ) MCFG_TI99_GROMPORT_ADD( GROMPORT_TAG ) @@ -1267,7 +1348,18 @@ static MACHINE_CONFIG_START( ti99_4ev_60hz, ti99_4x_state ) MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", ti99_4x_state, ti99_4ev_hblank_interrupt, SCREEN_TAG, 0, 1) /* Main board */ - MCFG_TMS9901_ADD(TMS9901_TAG, tms9901_wiring_ti99_4a, 3000000) + MCFG_DEVICE_ADD(TMS9901_TAG, TMS9901, 3000000) + MCFG_TMS9901_READBLOCK_HANDLER( READ8(ti99_4x_state, read_by_9901) ) + MCFG_TMS9901_P2_HANDLER( WRITELINE( ti99_4x_state, keyC0) ) + MCFG_TMS9901_P3_HANDLER( WRITELINE( ti99_4x_state, keyC1) ) + MCFG_TMS9901_P4_HANDLER( WRITELINE( ti99_4x_state, keyC2) ) + MCFG_TMS9901_P5_HANDLER( WRITELINE( ti99_4x_state, alphaW) ) + MCFG_TMS9901_P6_HANDLER( WRITELINE( ti99_4x_state, cs1_motor) ) + MCFG_TMS9901_P7_HANDLER( WRITELINE( ti99_4x_state, cs2_motor) ) + MCFG_TMS9901_P8_HANDLER( WRITELINE( ti99_4x_state, audio_gate) ) + MCFG_TMS9901_P9_HANDLER( WRITELINE( ti99_4x_state, cassette_output) ) + MCFG_TMS9901_INTLEVEL_HANDLER( WRITE8( ti99_4x_state, tms9901_interrupt) ) + MCFG_DMUX_ADD( DATAMUX_TAG, datamux_conf_ev ) MCFG_DMUX_READY_HANDLER( WRITELINE(ti99_4x_state, console_ready_dmux) ) MCFG_TI99_GROMPORT_ADD( GROMPORT_TAG ) diff --git a/src/mess/drivers/ti99_8.c b/src/mess/drivers/ti99_8.c index b10b0d3e2db..67377777c68 100644 --- a/src/mess/drivers/ti99_8.c +++ b/src/mess/drivers/ti99_8.c @@ -297,6 +297,10 @@ private: int m_nready_prev; void console_ready_join(int id, int state); + // Latch for 9901 INT2, INT1 lines + int m_9901_int; + void set_9901_int(int line, line_state state); + // Connected devices required_device m_cpu; required_device m_tms9901; @@ -563,8 +567,8 @@ READ8_MEMBER( ti99_8_state::read_by_9901 ) case TMS9901_CB_INT7: // Read pins INT3*-INT7* of TI99's 9901. // - // (bit 1: INT1 status) - // (bit 2: INT2 status) + // bit 1: INT1 status + // bit 2: INT2 status // bits 3-4: unused? // bit 5: ??? // bit 6-7: keyboard status bits 0 through 1 @@ -580,7 +584,7 @@ READ8_MEMBER( ti99_8_state::read_by_9901 ) { answer = ioport(column[m_keyboard_column])->read(); } - answer = (answer << 6) & 0xc0; + answer = (answer << 6) | m_9901_int; break; @@ -714,45 +718,55 @@ WRITE8_MEMBER( ti99_8_state::tms9901_interrupt ) m_cpu->set_input_line(INT_9995_INT1, data); } +/* const tms9901_interface tms9901_wiring_ti99_8 = { - TMS9901_INT1 | TMS9901_INT2 | TMS9901_INTC, + TMS9901_INT1 | TMS9901_INT2 | TMS9901_INTC, - // read handler - DEVCB_DRIVER_MEMBER(ti99_8_state, read_by_9901), + // read handler + DEVCB_DRIVER_MEMBER(ti99_8_state, read_by_9901), - // write handlers - { - DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, keyC0), - DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, keyC1), - DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, keyC2), - DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, keyC3), - DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, CRUS), - DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, PTGEN), - DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, cassette_motor), - DEVCB_NULL, - DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, audio_gate), - DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, cassette_output), - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL - }, + // write handlers + { + DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, keyC0), + DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, keyC1), + DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, keyC2), + DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, keyC3), + DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, CRUS), + DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, PTGEN), + DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, cassette_motor), + DEVCB_NULL, + DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, audio_gate), + DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, cassette_output), + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL + }, - DEVCB_DRIVER_MEMBER(ti99_8_state, tms9901_interrupt) + DEVCB_DRIVER_MEMBER(ti99_8_state, tms9901_interrupt) }; +*/ /*****************************************************************************/ +void ti99_8_state::set_9901_int( int line, line_state state) +{ + m_tms9901->set_single_int(line, state); + // We latch the value for the read operation. Mind the negative logic. + if (state==CLEAR_LINE) m_9901_int |= (1<set_single_int(2, state); + set_9901_int(2, (line_state)state); } /*********************************************************** @@ -829,8 +843,7 @@ WRITE_LINE_MEMBER( ti99_8_state::console_reset ) WRITE_LINE_MEMBER( ti99_8_state::extint ) { if (TRACE_READY) LOG("ti99_8: EXTINT level = %02x\n", state); - if (m_tms9901 != NULL) - m_tms9901->set_single_int(1, state); + set_9901_int(1, (line_state)state); } WRITE_LINE_MEMBER( ti99_8_state::notconnected ) @@ -1004,6 +1017,9 @@ MACHINE_RESET_MEMBER(ti99_8_state, ti99_8) // But we assert the line here so that the system starts running m_nready_combined = 0; m_gromport->set_grom_base(0x9800, 0xfff1); + + // Clear INT1 and INT2 latch (negative logic) + m_9901_int = 0x03; } static MACHINE_CONFIG_START( ti99_8_60hz, ti99_8_state ) @@ -1017,7 +1033,19 @@ static MACHINE_CONFIG_START( ti99_8_60hz, ti99_8_state ) MCFG_TI998_ADD_NTSC(VIDEO_SYSTEM_TAG, TMS9118, ti99_8_tms9118a_interface) /* Main board */ - MCFG_TMS9901_ADD( TMS9901_TAG, tms9901_wiring_ti99_8, XTAL_10_738635MHz/4.0) + MCFG_DEVICE_ADD(TMS9901_TAG, TMS9901, XTAL_10_738635MHz/4.0) + MCFG_TMS9901_READBLOCK_HANDLER( READ8(ti99_8_state, read_by_9901) ) + MCFG_TMS9901_P0_HANDLER( WRITELINE( ti99_8_state, keyC0) ) + MCFG_TMS9901_P1_HANDLER( WRITELINE( ti99_8_state, keyC1) ) + MCFG_TMS9901_P2_HANDLER( WRITELINE( ti99_8_state, keyC2) ) + MCFG_TMS9901_P3_HANDLER( WRITELINE( ti99_8_state, keyC3) ) + MCFG_TMS9901_P4_HANDLER( WRITELINE( ti99_8_state, CRUS) ) + MCFG_TMS9901_P5_HANDLER( WRITELINE( ti99_8_state, PTGEN) ) + MCFG_TMS9901_P6_HANDLER( WRITELINE( ti99_8_state, cassette_motor) ) + MCFG_TMS9901_P8_HANDLER( WRITELINE( ti99_8_state, audio_gate) ) + MCFG_TMS9901_P9_HANDLER( WRITELINE( ti99_8_state, cassette_output) ) + MCFG_TMS9901_INTLEVEL_HANDLER( WRITE8( ti99_8_state, tms9901_interrupt) ) + MCFG_MAINBOARD8_ADD( MAINBOARD8_TAG, mapper_conf ) MCFG_MAINBOARD8_READY_CALLBACK(WRITELINE(ti99_8_state, console_ready_mapper)) MCFG_TI99_GROMPORT_ADD( GROMPORT_TAG ) @@ -1073,7 +1101,19 @@ static MACHINE_CONFIG_START( ti99_8_50hz, ti99_8_state ) MCFG_TI998_ADD_PAL(VIDEO_SYSTEM_TAG, TMS9129, ti99_8_tms9118a_interface) /* Main board */ - MCFG_TMS9901_ADD( TMS9901_TAG, tms9901_wiring_ti99_8, XTAL_10_738635MHz/4.0 ) + MCFG_DEVICE_ADD(TMS9901_TAG, TMS9901, XTAL_10_738635MHz/4.0) + MCFG_TMS9901_READBLOCK_HANDLER( READ8(ti99_8_state, read_by_9901) ) + MCFG_TMS9901_P0_HANDLER( WRITELINE( ti99_8_state, keyC0) ) + MCFG_TMS9901_P1_HANDLER( WRITELINE( ti99_8_state, keyC1) ) + MCFG_TMS9901_P2_HANDLER( WRITELINE( ti99_8_state, keyC2) ) + MCFG_TMS9901_P3_HANDLER( WRITELINE( ti99_8_state, keyC3) ) + MCFG_TMS9901_P4_HANDLER( WRITELINE( ti99_8_state, CRUS) ) + MCFG_TMS9901_P5_HANDLER( WRITELINE( ti99_8_state, PTGEN) ) + MCFG_TMS9901_P6_HANDLER( WRITELINE( ti99_8_state, cassette_motor) ) + MCFG_TMS9901_P8_HANDLER( WRITELINE( ti99_8_state, audio_gate) ) + MCFG_TMS9901_P9_HANDLER( WRITELINE( ti99_8_state, cassette_output) ) + MCFG_TMS9901_INTLEVEL_HANDLER( WRITE8( ti99_8_state, tms9901_interrupt) ) + MCFG_MAINBOARD8_ADD( MAINBOARD8_TAG, mapper_conf ) MCFG_TI99_GROMPORT_ADD( GROMPORT_TAG ) MCFG_GROMPORT_READY_HANDLER( WRITELINE(ti99_8_state, console_ready_cart) ) diff --git a/src/mess/drivers/tm990189.c b/src/mess/drivers/tm990189.c index 3fee2d7d99e..749b03ea6b9 100644 --- a/src/mess/drivers/tm990189.c +++ b/src/mess/drivers/tm990189.c @@ -70,6 +70,8 @@ #include "tm990189.lh" #include "tm990189v.lh" +#define TMS9901_0_TAG "tms9901_usr" +#define TMS9901_1_TAG "tms9901_sys" class tm990189_state : public driver_device { @@ -81,7 +83,9 @@ public: m_cass(*this, "cassette"), m_tms9918(*this, "tms9918" ), m_maincpu(*this, "maincpu"), - m_cassette(*this, "cassette") { } + m_cassette(*this, "cassette"), + m_tms9901_usr(*this, TMS9901_0_TAG), + m_tms9901_sys(*this, TMS9901_1_TAG) { } required_device m_tms9980a; required_device m_speaker; @@ -158,6 +162,8 @@ private: void digitsel(int offset, bool state); required_device m_maincpu; required_device m_cassette; + required_device m_tms9901_usr; + required_device m_tms9901_sys; }; @@ -304,7 +310,9 @@ WRITE_LINE_MEMBER( tm990189_state::usr9901_led3_w ) WRITE8_MEMBER( tm990189_state::sys9901_interrupt_callback ) { - machine().device("tms9901_0")->set_single_int(5, (data!=0)? ASSERT_LINE:CLEAR_LINE); + // machine().device("tms9901_0")->set_single_int(5, (data!=0)? ASSERT_LINE:CLEAR_LINE); + // TODO: Check this + m_tms9901_usr->set_single_int(5, (data!=0)? ASSERT_LINE:CLEAR_LINE); } READ8_MEMBER( tm990189_state::sys9901_r ) @@ -624,70 +632,75 @@ WRITE8_MEMBER( tm990189_state::video_joy_w ) m_joy2y_timer->reset(attotime::from_usec(ioport("JOY2_Y")->read()*28+28)); } -/* user tms9901 setup */ +/* +// user tms9901 setup static const tms9901_interface usr9901reset_param = { - TMS9901_INT1 | TMS9901_INT2 | TMS9901_INT3 | TMS9901_INT4 | TMS9901_INT5 | TMS9901_INT6, /* only input pins whose state is always known */ + TMS9901_INT1 | TMS9901_INT2 | TMS9901_INT3 | TMS9901_INT4 | TMS9901_INT5 | TMS9901_INT6, // only input pins whose state is always known - /* Read handler. Covers all input lines (see tms9901.h) */ - DEVCB_NULL, + // Read handler. Covers all input lines (see tms9901.h) + DEVCB_NULL, - /* 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_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL - }, + // 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_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL + }, - /* interrupt handler */ - DEVCB_DRIVER_MEMBER(tm990189_state, usr9901_interrupt_callback) + // interrupt handler + DEVCB_DRIVER_MEMBER(tm990189_state, usr9901_interrupt_callback) }; +*/ -/* system tms9901 setup */ +/* +// system tms9901 setup static const tms9901_interface sys9901reset_param = { - 0, /* only input pins whose state is always known */ + 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), + // 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) - }, + // 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) + // interrupt handler + DEVCB_DRIVER_MEMBER(tm990189_state, sys9901_interrupt_callback) }; +*/ + /* Memory map: @@ -800,12 +813,12 @@ ADDRESS_MAP_END */ static ADDRESS_MAP_START( tm990_189_cru_map, AS_IO, 8, tm990189_state ) - AM_RANGE(0x0000, 0x003f) AM_DEVREAD("tms9901_0", tms9901_device, read) /* user I/O tms9901 */ - AM_RANGE(0x0040, 0x006f) AM_DEVREAD("tms9901_1", tms9901_device, read) /* system I/O tms9901 */ + AM_RANGE(0x0000, 0x003f) AM_DEVREAD(TMS9901_0_TAG, tms9901_device, read) /* user I/O tms9901 */ + AM_RANGE(0x0040, 0x006f) AM_DEVREAD(TMS9901_1_TAG, tms9901_device, read) /* system I/O tms9901 */ AM_RANGE(0x0080, 0x00cf) AM_DEVREAD("tms9902", tms9902_device, cruread) /* optional tms9902 */ - AM_RANGE(0x0000, 0x01ff) AM_DEVWRITE("tms9901_0", tms9901_device, write) /* user I/O tms9901 */ - AM_RANGE(0x0200, 0x03ff) AM_DEVWRITE("tms9901_1", tms9901_device, write) /* system I/O tms9901 */ + AM_RANGE(0x0000, 0x01ff) AM_DEVWRITE(TMS9901_0_TAG, tms9901_device, write) /* user I/O tms9901 */ + AM_RANGE(0x0200, 0x03ff) AM_DEVWRITE(TMS9901_1_TAG, tms9901_device, write) /* system I/O tms9901 */ AM_RANGE(0x0400, 0x05ff) AM_DEVWRITE("tms9902", tms9902_device, cruwrite) /* optional tms9902 */ ADDRESS_MAP_END @@ -837,8 +850,34 @@ static MACHINE_CONFIG_START( tm990_189, tm990189_state ) /* Devices */ MCFG_CASSETTE_ADD( "cassette", default_cassette_interface ) - MCFG_TMS9901_ADD("tms9901_0", usr9901reset_param, 2000000) - MCFG_TMS9901_ADD("tms9901_1", sys9901reset_param, 2000000) + + MCFG_DEVICE_ADD(TMS9901_0_TAG, TMS9901, 2000000) + MCFG_TMS9901_P0_HANDLER( WRITELINE( tm990189_state, usr9901_led0_w) ) + MCFG_TMS9901_P1_HANDLER( WRITELINE( tm990189_state, usr9901_led1_w) ) + MCFG_TMS9901_P2_HANDLER( WRITELINE( tm990189_state, usr9901_led2_w) ) + MCFG_TMS9901_P3_HANDLER( WRITELINE( tm990189_state, usr9901_led3_w) ) + MCFG_TMS9901_INTLEVEL_HANDLER( WRITE8( tm990189_state, usr9901_interrupt_callback) ) + + MCFG_DEVICE_ADD(TMS9901_1_TAG, TMS9901, 2000000) + MCFG_TMS9901_READBLOCK_HANDLER( READ8(tm990189_state, sys9901_r) ) + MCFG_TMS9901_P0_HANDLER( WRITELINE( tm990189_state, sys9901_digitsel0_w) ) + MCFG_TMS9901_P1_HANDLER( WRITELINE( tm990189_state, sys9901_digitsel1_w) ) + MCFG_TMS9901_P2_HANDLER( WRITELINE( tm990189_state, sys9901_digitsel2_w) ) + MCFG_TMS9901_P3_HANDLER( WRITELINE( tm990189_state, sys9901_digitsel3_w) ) + MCFG_TMS9901_P4_HANDLER( WRITELINE( tm990189_state, sys9901_segment0_w) ) + MCFG_TMS9901_P5_HANDLER( WRITELINE( tm990189_state, sys9901_segment1_w) ) + MCFG_TMS9901_P6_HANDLER( WRITELINE( tm990189_state, sys9901_segment2_w) ) + MCFG_TMS9901_P7_HANDLER( WRITELINE( tm990189_state, sys9901_segment3_w) ) + MCFG_TMS9901_P8_HANDLER( WRITELINE( tm990189_state, sys9901_segment4_w) ) + MCFG_TMS9901_P9_HANDLER( WRITELINE( tm990189_state, sys9901_segment5_w) ) + MCFG_TMS9901_P10_HANDLER( WRITELINE( tm990189_state, sys9901_segment6_w) ) + MCFG_TMS9901_P11_HANDLER( WRITELINE( tm990189_state, sys9901_segment7_w) ) + MCFG_TMS9901_P12_HANDLER( WRITELINE( tm990189_state, sys9901_dsplytrgr_w) ) + MCFG_TMS9901_P13_HANDLER( WRITELINE( tm990189_state, sys9901_shiftlight_w) ) + MCFG_TMS9901_P14_HANDLER( WRITELINE( tm990189_state, sys9901_spkrdrive_w) ) + MCFG_TMS9901_P15_HANDLER( WRITELINE( tm990189_state, sys9901_tapewdata_w) ) + MCFG_TMS9901_INTLEVEL_HANDLER( WRITE8( tm990189_state, sys9901_interrupt_callback) ) + MCFG_TMS9902_ADD("tms9902", tms9902_params, 2000000) MCFG_TM990_189_RS232_ADD("rs232") MCFG_TIMER_DRIVER_ADD_PERIODIC("display_timer", tm990189_state, display_callback, attotime::from_hz(30)) @@ -869,8 +908,33 @@ static MACHINE_CONFIG_START( tm990_189_v, tm990189_state ) /* Devices */ MCFG_CASSETTE_ADD( "cassette", default_cassette_interface ) - MCFG_TMS9901_ADD("tms9901_0", usr9901reset_param, 2000000) - MCFG_TMS9901_ADD("tms9901_1", sys9901reset_param, 2000000) + MCFG_DEVICE_ADD(TMS9901_0_TAG, TMS9901, 2000000) + MCFG_TMS9901_P0_HANDLER( WRITELINE( tm990189_state, usr9901_led0_w) ) + MCFG_TMS9901_P1_HANDLER( WRITELINE( tm990189_state, usr9901_led1_w) ) + MCFG_TMS9901_P2_HANDLER( WRITELINE( tm990189_state, usr9901_led2_w) ) + MCFG_TMS9901_P3_HANDLER( WRITELINE( tm990189_state, usr9901_led3_w) ) + MCFG_TMS9901_INTLEVEL_HANDLER( WRITE8( tm990189_state, usr9901_interrupt_callback) ) + + MCFG_DEVICE_ADD(TMS9901_1_TAG, TMS9901, 2000000) + MCFG_TMS9901_READBLOCK_HANDLER( READ8(tm990189_state, sys9901_r) ) + MCFG_TMS9901_P0_HANDLER( WRITELINE( tm990189_state, sys9901_digitsel0_w) ) + MCFG_TMS9901_P1_HANDLER( WRITELINE( tm990189_state, sys9901_digitsel1_w) ) + MCFG_TMS9901_P2_HANDLER( WRITELINE( tm990189_state, sys9901_digitsel2_w) ) + MCFG_TMS9901_P3_HANDLER( WRITELINE( tm990189_state, sys9901_digitsel3_w) ) + MCFG_TMS9901_P4_HANDLER( WRITELINE( tm990189_state, sys9901_segment0_w) ) + MCFG_TMS9901_P5_HANDLER( WRITELINE( tm990189_state, sys9901_segment1_w) ) + MCFG_TMS9901_P6_HANDLER( WRITELINE( tm990189_state, sys9901_segment2_w) ) + MCFG_TMS9901_P7_HANDLER( WRITELINE( tm990189_state, sys9901_segment3_w) ) + MCFG_TMS9901_P8_HANDLER( WRITELINE( tm990189_state, sys9901_segment4_w) ) + MCFG_TMS9901_P9_HANDLER( WRITELINE( tm990189_state, sys9901_segment5_w) ) + MCFG_TMS9901_P10_HANDLER( WRITELINE( tm990189_state, sys9901_segment6_w) ) + MCFG_TMS9901_P11_HANDLER( WRITELINE( tm990189_state, sys9901_segment7_w) ) + MCFG_TMS9901_P12_HANDLER( WRITELINE( tm990189_state, sys9901_dsplytrgr_w) ) + MCFG_TMS9901_P13_HANDLER( WRITELINE( tm990189_state, sys9901_shiftlight_w) ) + MCFG_TMS9901_P14_HANDLER( WRITELINE( tm990189_state, sys9901_spkrdrive_w) ) + MCFG_TMS9901_P15_HANDLER( WRITELINE( tm990189_state, sys9901_tapewdata_w) ) + MCFG_TMS9901_INTLEVEL_HANDLER( WRITE8( tm990189_state, sys9901_interrupt_callback) ) + MCFG_TMS9902_ADD("tms9902", tms9902_params, 2000000) MCFG_TM990_189_RS232_ADD("rs232") MCFG_TIMER_DRIVER_ADD_PERIODIC("display_timer", tm990189_state, display_callback, attotime::from_hz(30))