mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +03:00
(MESS) devcb2 migration. (nw)
This commit is contained in:
parent
4b03839955
commit
57a3ca60e9
@ -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<const tms9901_interface *>(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;
|
||||
}
|
||||
|
@ -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<class _Object> static devcb2_base &static_set_readblock_callback(device_t &device, _Object object) { return downcast<tms9901_device &>(device).m_read_block.set_callback(object); }
|
||||
|
||||
template<class _Object> static devcb2_base &static_set_p0_callback(device_t &device, _Object object) { return downcast<tms9901_device &>(device).m_write_p0.set_callback(object); }
|
||||
template<class _Object> static devcb2_base &static_set_p1_callback(device_t &device, _Object object) { return downcast<tms9901_device &>(device).m_write_p1.set_callback(object); }
|
||||
template<class _Object> static devcb2_base &static_set_p2_callback(device_t &device, _Object object) { return downcast<tms9901_device &>(device).m_write_p2.set_callback(object); }
|
||||
template<class _Object> static devcb2_base &static_set_p3_callback(device_t &device, _Object object) { return downcast<tms9901_device &>(device).m_write_p3.set_callback(object); }
|
||||
template<class _Object> static devcb2_base &static_set_p4_callback(device_t &device, _Object object) { return downcast<tms9901_device &>(device).m_write_p4.set_callback(object); }
|
||||
template<class _Object> static devcb2_base &static_set_p5_callback(device_t &device, _Object object) { return downcast<tms9901_device &>(device).m_write_p5.set_callback(object); }
|
||||
template<class _Object> static devcb2_base &static_set_p6_callback(device_t &device, _Object object) { return downcast<tms9901_device &>(device).m_write_p6.set_callback(object); }
|
||||
template<class _Object> static devcb2_base &static_set_p7_callback(device_t &device, _Object object) { return downcast<tms9901_device &>(device).m_write_p7.set_callback(object); }
|
||||
template<class _Object> static devcb2_base &static_set_p8_callback(device_t &device, _Object object) { return downcast<tms9901_device &>(device).m_write_p8.set_callback(object); }
|
||||
template<class _Object> static devcb2_base &static_set_p9_callback(device_t &device, _Object object) { return downcast<tms9901_device &>(device).m_write_p9.set_callback(object); }
|
||||
template<class _Object> static devcb2_base &static_set_p10_callback(device_t &device, _Object object) { return downcast<tms9901_device &>(device).m_write_p10.set_callback(object); }
|
||||
template<class _Object> static devcb2_base &static_set_p11_callback(device_t &device, _Object object) { return downcast<tms9901_device &>(device).m_write_p11.set_callback(object); }
|
||||
template<class _Object> static devcb2_base &static_set_p12_callback(device_t &device, _Object object) { return downcast<tms9901_device &>(device).m_write_p12.set_callback(object); }
|
||||
template<class _Object> static devcb2_base &static_set_p13_callback(device_t &device, _Object object) { return downcast<tms9901_device &>(device).m_write_p13.set_callback(object); }
|
||||
template<class _Object> static devcb2_base &static_set_p14_callback(device_t &device, _Object object) { return downcast<tms9901_device &>(device).m_write_p14.set_callback(object); }
|
||||
template<class _Object> static devcb2_base &static_set_p15_callback(device_t &device, _Object object) { return downcast<tms9901_device &>(device).m_write_p15.set_callback(object); }
|
||||
|
||||
template<class _Object> static devcb2_base &static_set_intlevel_callback(device_t &device, _Object object) { return downcast<tms9901_device &>(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__ */
|
||||
|
@ -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)
|
||||
|
@ -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<<line);
|
||||
else m_9901_int &= ~(1<<line);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( ti99_4p_state::extint )
|
||||
{
|
||||
if (VERBOSE>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)
|
||||
|
@ -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<tms9900_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<<line);
|
||||
else m_9901_int &= ~(1<<line);
|
||||
}
|
||||
|
||||
/*
|
||||
set the state of TMS9901's INT2 (called by the tms9928 core)
|
||||
*/
|
||||
WRITE_LINE_MEMBER( ti99_4x_state::set_tms9901_INT2 )
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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 )
|
||||
|
@ -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<tms9995_device> m_cpu;
|
||||
required_device<tms9901_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<<line);
|
||||
else m_9901_int &= ~(1<<line);
|
||||
}
|
||||
|
||||
/*
|
||||
set the state of TMS9901's INT2 (called by the tms9928 core)
|
||||
*/
|
||||
WRITE_LINE_MEMBER( ti99_8_state::set_tms9901_INT2 )
|
||||
{
|
||||
if (TRACE_INTERRUPTS) LOG("ti99_8: VDP int 2 on tms9901, level=%02x\n", state);
|
||||
m_tms9901->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) )
|
||||
|
@ -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<tms9980a_device> m_tms9980a;
|
||||
required_device<speaker_sound_device> m_speaker;
|
||||
@ -158,6 +162,8 @@ private:
|
||||
void digitsel(int offset, bool state);
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<cassette_image_device> m_cassette;
|
||||
required_device<tms9901_device> m_tms9901_usr;
|
||||
required_device<tms9901_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_device>("tms9901_0")->set_single_int(5, (data!=0)? ASSERT_LINE:CLEAR_LINE);
|
||||
// machine().device<tms9901_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))
|
||||
|
Loading…
Reference in New Issue
Block a user