Previous 15994 Revisions Next

r15496 Sunday 24th June, 2012 at 15:35:12 UTC by Michael Zapf
ti99: Changes in logging; spchsyn prepared for real timing (nw)
[src/mess/drivers]ti99_4x.c
[src/mess/machine/ti99]spchsyn.c

src/mess/machine/ti99/spchsyn.c
r15495r15496
2828
2929#define SPEECHROM_TAG "speechrom"
3030
31#define REAL_TIMING 0
32
3133/****************************************************************************/
3234
3335ti_speech_synthesizer_device::ti_speech_synthesizer_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
r15495r15496
3739}
3840
3941/*
42    Comments on real timing in the TMS5200 emulation
43
44    Real timing means that the synthesizer clears the /READY line (puts high)
45    whenever a read or write access is in progress. This is done by setting
46    /RS and /WS lines, according to the read or write operation. The /READY line
47    is asserted again after some time. Real timing is used once the tms5220_wsq_w
48    and tms5220_rsq_w are called.
49
50    Within the TI systems, the /RS and /WS lines are controlled directly by the
51    address bus. There is currently no way to insert wait states between
52    the address setting and the data bus sampling, since this is an atomic
53    operation in the emulator (read_byte). It would be necessary to somehow
54    announce the pending read before it actually happens so that devices
55    like this VSP may insert wait states before the read.
56
57    The TMS5220 implementation assumes that wait states are respected and
58    therefore delivers bad values when queried too early. It uses a latch that
59    gets the new value after some time has expired.
60
61    To fix this we have to modify the RS/WS methods in TMS5200 to immediately
62    set the status (after updating the sound status, or the status will be
63    outdated too early).
64
65    Also note that the /RS and /WS lines must be cleared (put to high) when the
66    read is done. Again, this is not possible with the current implementation.
67    So we do this in the ready callback.
68
69    On the bottom line we will stay with the not-REAL_TIMING for now and wait
70    for the core to allow for split read accesses.
71*/
72
73
74/*
4075    Memory read
4176*/
77#if REAL_TIMING
78// ======  This is the version with real timing =======
4279READ8Z_MEMBER( ti_speech_synthesizer_device::readz )
4380{
4481   if ((offset & m_select_mask)==m_select_value)
4582   {
83      tms5220_wsq_w(m_vsp, TRUE);
84      tms5220_rsq_w(m_vsp, FALSE);
85      *value = tms5220_status_r(m_vsp, offset) & 0xff;
86      if (VERBOSE>4) LOG("spchsyn: read value = %02x\n", *value);
87   }
88}
89
90/*
91    Memory write
92*/
93WRITE8_MEMBER( ti_speech_synthesizer_device::write )
94{
95   if ((offset & m_select_mask)==(m_select_value | 0x0400))
96   {
97      tms5220_rsq_w(m_vsp, TRUE);
98      tms5220_wsq_w(m_vsp, FALSE);
99      if (VERBOSE>4) LOG("spchsyn: write value = %02x\n", data);
100      tms5220_data_w(m_vsp, offset, data);
101   }
102}
103
104#else
105// ======  This is the version without real timing =======
106
107READ8Z_MEMBER( ti_speech_synthesizer_device::readz )
108{
109   if ((offset & m_select_mask)==m_select_value)
110   {
46111      device_adjust_icount(machine().device("maincpu"),-(18+3));      /* this is just a minimum, it can be more */
47112      *value = tms5220_status_r(m_vsp, offset) & 0xff;
113      if (VERBOSE>4) LOG("spchsyn: read value = %02x\n", *value);
48114   }
49115}
50116
r15495r15496
70136         device_adjust_icount(machine().device("maincpu"),-cycles_to_ready);
71137         machine().scheduler().timer_set(attotime::zero, FUNC_NULL);
72138      }
139      if (VERBOSE>4) LOG("spchsyn: write value = %02x\n", data);
73140      tms5220_data_w(m_vsp, offset, data);
74141   }
75142}
143#endif
76144
77145/****************************************************************************
78146    Callbacks from TMS5220
r15495r15496
175243
176244WRITE_LINE_MEMBER( ti_speech_synthesizer_device::speech_ready )
177245{
178   // TODO: Fix this in TMS5220
246   // The TMS5200 implementation uses TRUE/FALSE, not ASSERT/CLEAR semantics
247   // and we have to adapt a /READY to a READY line.
248   // The real synthesizer board uses a transistor for that purpose.
179249   m_slot->set_ready((state==0)? ASSERT_LINE : CLEAR_LINE);
250   if (VERBOSE>5) LOG("spchsyn: READY = %d\n", (state==0));
251
252#if REAL_TIMING
253   // Need to do that here (see explanations above)
254   if (state==0)
255   {
256      tms5220_rsq_w(m_vsp, TRUE);
257      tms5220_wsq_w(m_vsp, TRUE);
258   }
259#endif
180260}
181261
182262void ti_speech_synthesizer_device::device_start()
r15495r15496
210290
211291MACHINE_CONFIG_FRAGMENT( ti99_speech )
212292   MCFG_SPEAKER_STANDARD_MONO("mono")
213   MCFG_SOUND_ADD("speechsyn", TMC0285, 680000L)
293   MCFG_SOUND_ADD("speechsyn", TMC0285, 640000L)
214294   MCFG_SOUND_CONFIG(ti99_4x_tms5200interface)
215295   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
216296MACHINE_CONFIG_END
src/mess/drivers/ti99_4x.c
r15495r15496
5656#include "machine/ti99/peribox.h"
5757
5858#define LOG logerror
59#define VERBOSE
59#define VERBOSE 1
6060
6161/*
6262    The console.
r15495r15496
9696   ti99_handset_device* m_handset;
9797   ti99_datamux_device* m_datamux;
9898
99   int      m_ready_line, m_ready_line1;
99   int      m_ready_line, m_ready_line_dmux;
100100
101101   // Connections with the system interface TMS9901
102102   DECLARE_READ8_MEMBER(read_by_9901);
r15495r15496
115115   void   set_key(int number, int data);
116116   int      m_keyboard_column;
117117   int      m_alphalock_line;
118   int      m_ready_prev;      // for debugging purposes only
118119};
119120
120121/*
r15495r15496
379380
380381WRITE8_MEMBER( ti99_4x::cruwrite )
381382{
382   if (VERBOSE>6) LOG("write access to CRU address %04x\n", offset << 1);
383   if (VERBOSE>6) LOG("ti99_4x: write access to CRU address %04x\n", offset << 1);
383384   m_gromport->cruwrite(offset<<1, data);
384385   m_peribox->cruwrite(offset<<1, data);
385386}
r15495r15496
387388WRITE8_MEMBER( ti99_4x::external_operation )
388389{
389390   static const char* extop[8] = { "inv1", "inv2", "IDLE", "RSET", "inv3", "CKON", "CKOF", "LREX" };
390   if (VERBOSE>1) LOG("External operation %s not implemented on TI-99 board\n", extop[offset]);
391   // Some games (e.g. Slymoids) actually use IDLE for synchronization
392   if (offset == IDLE_OP) return;
393   else
394   {
395      if (VERBOSE>1) LOG("ti99_4x: External operation %s not implemented on TI-99 board\n", extop[offset]);
396   }
391397}
392398
393399/***************************************************************************
r15495r15496
626632*/
627633WRITE_LINE_MEMBER( ti99_4x::set_tms9901_INT2 )
628634{
629   if (VERBOSE>6) LOG("ti99_4x: VDP int 2 on tms9901, level=%02x\n", state);
635   if (VERBOSE>6) LOG("ti99_4x: VDP int 2 on tms9901, level=%d\n", state);
630636   m_tms9901->set_single_int(2, state);
631637}
632638
r15495r15496
655661*/
656662WRITE_LINE_MEMBER( ti99_4x::console_ready )
657663{
658   if (VERBOSE>6) LOG("ti99_4x: READY level = %02x\n", state);
659664   m_ready_line = state;
665   int combined = (m_ready_line == ASSERT_LINE && m_ready_line_dmux == ASSERT_LINE)? ASSERT_LINE : CLEAR_LINE;
660666
661   m_cpu->set_ready((m_ready_line == ASSERT_LINE && m_ready_line1 == ASSERT_LINE)? ASSERT_LINE : CLEAR_LINE);
667   if (VERBOSE>6)
668   {
669      if (m_ready_prev != combined) LOG("ti99_4x: READY level = %d\n", combined);
670   }
671   m_ready_prev = combined;
672   m_cpu->set_ready(combined);
662673}
663674
664675/*
r15495r15496
668679*/
669680WRITE_LINE_MEMBER( ti99_4x::console_ready_dmux )
670681{
671   if (VERBOSE>6) LOG("ti99_4x: READY dmux level = %02x\n", state);
672   m_ready_line1 = state;
673   m_cpu->set_ready((m_ready_line == ASSERT_LINE && m_ready_line1 == ASSERT_LINE)? ASSERT_LINE : CLEAR_LINE);
682   m_ready_line_dmux = state;
683   int combined = (m_ready_line == ASSERT_LINE && m_ready_line_dmux == ASSERT_LINE)? ASSERT_LINE : CLEAR_LINE;
684
685   if (VERBOSE>7)
686   {
687      if (m_ready_prev != combined) LOG("ti99_4x: READY dmux level = %d\n", state);
688   }
689   m_ready_prev = combined;
690   m_cpu->set_ready(combined);
674691}
675692
676693WRITE_LINE_MEMBER( ti99_4x::extint )
r15495r15496
837854   driver->m_peribox->senila(CLEAR_LINE);
838855   driver->m_peribox->senilb(CLEAR_LINE);
839856
840   driver->m_ready_line = driver->m_ready_line1 = ASSERT_LINE;
857   driver->m_ready_line = driver->m_ready_line_dmux = ASSERT_LINE;
841858}
842859
843860MACHINE_RESET( ti99_4 )
r15495r15496
867884   MCFG_MACHINE_START( ti99_4 )
868885   MCFG_MACHINE_RESET( ti99_4 )
869886
870   MCFG_TI_TMS991x_ADD_NTSC(VIDEO_SYSTEM_TAG, TMS9118, ti99_4_tms9928a_interface)
887   MCFG_TI_TMS991x_ADD_NTSC(VIDEO_SYSTEM_TAG, TMS9918, ti99_4_tms9928a_interface)
871888
872889   /* Main board */
873890   MCFG_TMS9901_ADD(TMS9901_TAG, tms9901_wiring_ti99_4, 3000000)
r15495r15496
969986
970987   driver->m_peribox->senila(CLEAR_LINE);
971988   driver->m_peribox->senilb(CLEAR_LINE);
972   driver->m_ready_line = driver->m_ready_line1 = ASSERT_LINE;
989   driver->m_ready_line = driver->m_ready_line_dmux = ASSERT_LINE;
973990}
974991
975992MACHINE_RESET( ti99_4a )

Previous 15994 Revisions Next


© 1998-2018 The MESS Team