Previous 199869 Revisions Next

r25470 Monday 30th September, 2013 at 23:16:14 UTC by Michael Zapf
(MESS) Using the split addressing (setaddress ... read/write)
[src/mess/drivers]geneve.c ti99_4x.c ti99_8.c tm990189.c
[src/mess/machine/ti99]datamux.c datamux.h genboard.c genboard.h mapper8.c peribox.c peribox.h spchsyn.c spchsyn.h ti99defs.h

trunk/src/mess/machine/ti99/spchsyn.h
r25469r25470
2323   ti_speech_synthesizer_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
2424   DECLARE_READ8Z_MEMBER(readz);
2525   DECLARE_WRITE8_MEMBER(write);
26   DECLARE_SETADDRESS_DBIN_MEMBER(setaddress_dbin);
2627
2728   void crureadz(offs_t offset, UINT8 *value) { };
2829   void cruwrite(offs_t offset, UINT8 value) { };
r25469r25470
4243
4344private:
4445   cd2501e_device *m_vsp;
46   bool            m_read_mode;
4547};
4648
4749#endif
trunk/src/mess/machine/ti99/ti99defs.h
r25469r25470
4949#define READ8Z_MEMBER(name)             void name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT8 *value, ATTR_UNUSED UINT8 mem_mask)
5050#define DECLARE_READ8Z_MEMBER(name)     void name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT8 *value, ATTR_UNUSED UINT8 mem_mask = 0xff)
5151
52/*
53    For almost all applications of setoffset, we also need the data bus
54    direction. This line is called DBIN on the TI CPUs, but as we do not assume
55    that this is a general rule, we use new macros here which contain the
56    DBIN setting.
57*/
58#define SETADDRESS_DBIN_MEMBER(name)          void  name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED int state)
59#define DECLARE_SETADDRESS_DBIN_MEMBER(name)  void  name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED int state)
60
5261#define GENMOD 0x01
5362
5463/*
r25469r25470
6574   : device_t(mconfig, type, name, tag, owner, clock, shortname, source) { }
6675   virtual DECLARE_READ8Z_MEMBER(readz) =0;
6776   virtual DECLARE_WRITE8_MEMBER(write) =0;
77   virtual DECLARE_SETADDRESS_DBIN_MEMBER( setaddress_dbin ) { };
6878};
6979
7080class bus16z_device : device_t
r25469r25470
7282public:
7383   virtual DECLARE_READ16Z_MEMBER(read16z) =0;
7484   virtual DECLARE_WRITE16_MEMBER(write16) =0;
85   virtual DECLARE_SETADDRESS_DBIN_MEMBER( setaddress_dbin ) { };
7586};
7687
7788/****************************************************************************
trunk/src/mess/machine/ti99/datamux.c
r25469r25470
120120   }
121121}
122122
123void ti99_datamux_device::setaddress_all(address_space& space, UINT16 addr)
124{
125   attached_device *dev = m_devices.first();
126   while (dev != NULL)
127   {
128      if ((addr & dev->m_config->address_mask)==(dev->m_config->select | dev->m_config->write_select))
129      {
130         bus8z_device *devz = static_cast<bus8z_device *>(dev->m_device);
131         devz->setaddress_dbin(space, addr, m_read_mode? ASSERT_LINE : CLEAR_LINE);
132      }
133      dev = dev->m_next;
134   }
135}
136
123137/*
124138    Read access. We are using two loops because the delay between both
125139    accesses must not occur within the loop. So we have one access on the bus,
126140    a delay, and then the second access (each one with possibly many attached
127141    devices)
128
129    TODO: Check two-pass operation
130142*/
131143READ16_MEMBER( ti99_datamux_device::read )
132144{
133   UINT8 hbyte = 0;
134   UINT16 addr = (offset << 1);
135
136145   // Looks ugly, but this is close to the real thing. If the 16bit
137146   // memory expansion is installed in the console, and the access hits its
138147   // space, just respond to the memory access and don't bother the
139148   // datamux in any way. In particular, do not make the datamux insert wait
140149   // states.
141   if (m_use32k)
150   if (m_base32k != 0)
142151   {
143      UINT16 base = 0;
144      if ((addr & 0xe000)==0x2000) base = 0x1000;
145      if (((addr & 0xe000)==0xa000) || ((addr & 0xc000)==0xc000)) base = 0x4000;
152      UINT16 reply = m_ram16b[offset-m_base32k];
153      return reply & mem_mask;
154   }
155   else
156   {
157      // The byte from the odd address has already been read into the latch
158      // Reading the even address now (addr)
159      UINT8 hbyte = 0;
160      read_all(space, m_addr_buf, &hbyte);
161      if (VERBOSE>3) LOG("datamux: read even byte from address %04x -> %02x\n",  m_addr_buf, hbyte);
146162
147      if (base != 0)
148      {
149         UINT16 reply = m_ram16b[offset-base];
150         return reply & mem_mask;
151      }
163      return ((hbyte<<8) | m_latch) & mem_mask;
152164   }
153
154   // Read the odd address into the latch
155   read_all(space, addr+1, &m_latch);
156
157   // Reading the even address now (addr)
158   read_all(space, addr, &hbyte);
159
160   // Insert four wait states and let CPU enter wait state
161   // The counter in the real console is implemented by a shift register
162   // that is triggered on a memory access
163
164   // We cannot split the wait states between the read accesses before we
165   // have a split-phase read access in the core
166   m_waitcount = 6;
167   m_ready(CLEAR_LINE);
168
169   // use the latch and the currently read byte and put it on the 16bit bus
170   return ((hbyte<<8) | m_latch) & mem_mask;
171165}
172166
173167/*
r25469r25470
175169*/
176170WRITE16_MEMBER( ti99_datamux_device::write )
177171{
178   UINT16 addr = (offset << 1);
179
180172   // Although MESS allows for using mem_mask to address parts of the
181173   // data bus, this is not used in the TMS implementation. In fact, all
182174   // accesses are true 16-bit accesses. We check for mem_mask always
183175   // being ffff.
184176
185//  printf("write addr=%04x, value=%04x\n", addr, data);
186
187177   // Handle the internal 32K expansion
188   if (m_use32k)
178   if (m_base32k != 0)
189179   {
190      UINT16 base = 0;
191      if ((addr & 0xe000)==0x2000) base = 0x1000;
192      if (((addr & 0xe000)==0xa000) || ((addr & 0xc000)==0xc000)) base = 0x4000;
180      m_ram16b[offset-m_base32k] = data;
181   }
182   else
183   {
184      // Otherwise the datamux is in normal operation which means it puts
185      // the even value into the latch and outputs the odd value now.
186      m_latch = (data >> 8) & 0xff;
193187
194      if (base != 0)
195      {
196         m_ram16b[offset-base] = data;
197         return;
198      }
188      // write odd byte
189      if (VERBOSE>3) LOG("datamux: write odd byte to address %04x <- %02x\n",  m_addr_buf+1, data & 0xff);
190      write_all(space, m_addr_buf+1, data & 0xff);
199191   }
200
201   // write odd byte
202   write_all(space, addr+1, data & 0xff);
203   // write even byte
204   write_all(space, addr, (data>>8) & 0xff);
205
206   // Insert four wait states and let CPU enter wait state
207   m_waitcount = 6;
208   m_ready(CLEAR_LINE);
209192}
210193
194/*
195    Called when the memory access starts by setting the address bus. From that
196    point on, we suspend the CPU until all operations are done.
197*/
211198SETOFFSET_MEMBER( ti99_datamux_device::setoffset )
212199{
213   if (VERBOSE>6) LOG("set address %04x\n", offset << 1);
200   if (VERBOSE>6) LOG("datamux: set address %04x\n", offset << 1);
201   // Initialize counter
202   // 1 cycle for loading into the datamux
203   // 2 subsequent wait states (LSB)
204   // 2 subsequent wait states (MSB)
205   // clock cycle 6 is the nominal follower of the last wait state
206   m_waitcount = 5;
207   m_addr_buf = offset << 1;
208   m_spacep = &space;
209
210   m_base32k = 0;
211   if (m_use32k)
212   {
213      if ((m_addr_buf & 0xe000)==0x2000) m_base32k = 0x1000;
214      if (((m_addr_buf & 0xe000)==0xa000) || ((m_addr_buf & 0xc000)==0xc000)) m_base32k = 0x4000;
215   }
216
217   // Suspend the CPU if not using the 32K
218   if (m_base32k == 0)
219   {
220      // propagate the setaddress operation
221      // First the odd address
222      setaddress_all(space, m_addr_buf+1);
223      m_ready(CLEAR_LINE);
224   }
225   else m_waitcount = 0;
214226}
215227
216228/*
217229    The datamux is connected to the clock line in order to operate
218    the wait state counter.
230    the wait state counter and to read/write the bytes.
219231*/
220232void ti99_datamux_device::clock_in(int clock)
221233{
222   if (clock==ASSERT_LINE && m_waitcount!=0)
234   // return immediately if the datamux is currently inactive
235   if (m_waitcount>0)
223236   {
224      m_waitcount--;
225      if (m_waitcount==0) m_ready(ASSERT_LINE);
237      if (VERBOSE>6) LOG("datamux: wait count %d\n", m_waitcount);
238      if (m_read_mode)
239      {
240         // Reading
241         if (clock==ASSERT_LINE)
242         {   // raising edge
243            m_waitcount--;
244            if (m_waitcount==0) m_ready(ASSERT_LINE);
245            if (m_waitcount==2)
246            {
247               // read odd byte
248               read_all(*m_spacep, m_addr_buf+1, &m_latch);
249               if (VERBOSE>3) LOG("datamux: read odd byte from address %04x -> %02x\n",  m_addr_buf+1, m_latch);
250               // do the setaddress for the even address
251               setaddress_all(*m_spacep, m_addr_buf);
252            }
253         }
254      }
255      else
256      {
257         if (clock==ASSERT_LINE)
258         {   // raising edge
259            m_waitcount--;
260            if (m_waitcount==0) m_ready(ASSERT_LINE);
261         }
262         else
263         {   // falling edge
264            if (m_waitcount==2)
265            {
266               // do the setaddress for the even address
267               setaddress_all(*m_spacep, m_addr_buf);
268               // write even byte
269               if (VERBOSE>3) LOG("datamux: write even byte to address %04x <- %02x\n",  m_addr_buf, m_latch);
270               write_all(*m_spacep, m_addr_buf, m_latch);
271            }
272         }
273      }
226274   }
227275}
228276
277void ti99_datamux_device::dbin_in(int state)
278{
279   m_read_mode = (state==ASSERT_LINE);
280   if (VERBOSE>6) LOG("datamux: data bus in = %d\n", m_read_mode? 1:0 );
281}
282
229283/***************************************************************************
230284    DEVICE LIFECYCLE FUNCTIONS
231285***************************************************************************/
r25469r25470
308362
309363   m_waitcount = 0;
310364   m_latch = 0;
365
366   m_read_mode = true;
311367}
312368
313369INPUT_PORTS_START( datamux )
trunk/src/mess/machine/ti99/peribox.c
r25469r25470
249249   }
250250}
251251
252SETADDRESS_DBIN_MEMBER(peribox_device::setaddress_dbin)
253{
254   for (int i=2; i <= 8; i++)
255   {
256      if (m_slot[i]!=NULL) m_slot[i]->setaddress_dbin(space, offset | m_address_prefix, state);
257   }
258}
259
252260void peribox_device::crureadz(offs_t offset, UINT8 *value)
253261{
254262   for (int i=2; i <= 8; i++)
r25469r25470
579587   m_card->write(space, offset, data, mem_mask);
580588}
581589
590SETADDRESS_DBIN_MEMBER(peribox_slot_device::setaddress_dbin)
591{
592   m_card->setaddress_dbin(space, offset, state);
593}
594
582595void peribox_slot_device::crureadz(offs_t offset, UINT8 *value)
583596{
584597   m_card->crureadz(offset, value);
trunk/src/mess/machine/ti99/datamux.h
r25469r25470
7373   DECLARE_SETOFFSET_MEMBER( setoffset );
7474
7575   void clock_in(int state);
76   void dbin_in(int state);
7677
7778protected:
7879   /* Constructor */
r25469r25470
8283   virtual ioport_constructor device_input_ports() const;
8384
8485private:
86   // Keeps the address space pointer
87   address_space* m_spacep;
88
8589   // Common read routine
8690   void read_all(address_space& space, UINT16 addr, UINT8 *target);
8791
8892   // Common write routine
8993   void write_all(address_space& space, UINT16 addr, UINT8 value);
9094
95   // Common set address method
96   void setaddress_all(address_space& space, UINT16 addr);
97
9198   // Ready line to the CPU
9299   devcb_resolved_write_line m_ready;
93100
101   /* Address latch (emu). In reality, the address bus remains constant. */
102   UINT16 m_addr_buf;
103
104   /* Stores the state of the DBIN line. */
105   bool    m_read_mode;
106
94107   /* All devices that are attached to the 8-bit bus. */
95108   simple_list<attached_device> m_devices;
96109
r25469r25470
106119   /* Use the memory expansion? */
107120   bool m_use32k;
108121
122   /* Memory base for piggy-back 32K expansion. If 0, expansion is not used. */
123   UINT16  m_base32k;
124
109125   /* Reference to the CPU; avoid lookups. */
110126   device_t *m_cpu;
111127};
trunk/src/mess/machine/ti99/mapper8.c
r25469r25470
5454    CRU access
5555***************************************************************************/
5656
57#define HEXBUS_CRU_BASE 0x1700
5758#define MAPPER_CRU_BASE 0x2700
5859
5960void ti998_mapper_device::crureadz(offs_t offset, UINT8 *value)
r25469r25470
8384         machine().schedule_soft_reset();
8485         break;
8586      }
87      return;
8688   }
89
90   if ((offset & 0xff00)==HEXBUS_CRU_BASE)
91   {
92      if (VERBOSE>5) LOG("mapper8: Set CRU>%04x (Hexbus) to %d\n",offset,data);
93      return;
94   }
95
96   if ((offset & 0xff00)>=0x0100)
97   {
98      if (VERBOSE>5) LOG("mapper8: Set CRU>%04x (unknown) to %d\n",offset,data);
99      return;
100   }
87101}
88102
89103void ti998_mapper_device::CRUS_set(bool state)
r25469r25470
234248            int ptr = (bankindx << 6);
235249            m_pas_offset[i] =   (m_sram[(i<<2) + ptr] << 24) | (m_sram[(i<<2)+ ptr+1] << 16)
236250            | (m_sram[(i<<2) + ptr+2] << 8) | (m_sram[(i<<2) + ptr+3]);
251            if (VERBOSE>7) LOG("mapper8: load %d=%08x\n", i, m_pas_offset[i]);
237252         }
238253      }
239254      else
r25469r25470
247262            m_sram[(i<<2) + ptr +1] =  (m_pas_offset[i] >> 16)& 0xff;
248263            m_sram[(i<<2) + ptr +2] =  (m_pas_offset[i] >> 8)& 0xff;
249264            m_sram[(i<<2) + ptr +3] =  (m_pas_offset[i])& 0xff;
265            if (VERBOSE>7) LOG("mapper8: save %d=%08x\n", i, m_pas_offset[i]);
250266         }
251267      }
252268   }
trunk/src/mess/machine/ti99/peribox.h
r25469r25470
4949   peribox_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
5050   peribox_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
5151
52   // Next six methods are called from the console
52   // Next seven methods are called from the console
5353   DECLARE_READ8Z_MEMBER(readz);
5454   DECLARE_WRITE8_MEMBER(write);
55   DECLARE_SETADDRESS_DBIN_MEMBER(setaddress_dbin);
56
5557   void crureadz(offs_t offset, UINT8 *value);
5658   void cruwrite(offs_t offset, UINT8 value);
5759   DECLARE_WRITE_LINE_MEMBER(senila);
r25469r25470
143145   // Called from the box (direction to card)
144146   DECLARE_READ8Z_MEMBER(readz);
145147   DECLARE_WRITE8_MEMBER(write);
148   DECLARE_SETADDRESS_DBIN_MEMBER(setaddress_dbin);
149
146150   DECLARE_WRITE_LINE_MEMBER(senila);
147151   DECLARE_WRITE_LINE_MEMBER(senilb);
148152
trunk/src/mess/machine/ti99/genboard.c
r25469r25470
264264
265265void geneve_mapper_device::do_wait(int min)
266266{
267   min = min + 1;
267//  min = min + 1;
268268   // Extra waitstates?
269269   if (m_extra_waitstates && min < 4) min = 3;
270270   m_waitcount = min;
271271   if (m_waitcount > 0)
272272   {
273      if (VERBOSE>8) LOG("genboard: Pulling down READY line for %d cycles\n", m_waitcount);
273      if (VERBOSE>7) LOG("genboard: Pulling down READY line for %d cycles\n", m_waitcount);
274274      m_ready(CLEAR_LINE);
275275   }
276276}
r25469r25470
278278/************************************************************************
279279    Called by the address map
280280************************************************************************/
281/*
282    Constants for mapper decoding. Naming scheme:
283    M=mapper
284    L=Logical space; P=Physical space
285    G=Geneve mode;  T=TI mode
286*/
287enum
288{
289   MLGVIDEO=1,
290   MLGMAPPER,
291   MLGKEY,
292   MLGCLOCK,
293   MLGSOUND,
294   MLTMAPPER,
295   MLTKEY,
296   MLTCLOCK,
297   MLTVIDEO,
298   MLTSPEECH,
299   MLTGROM,
300   MLTSOUND,
301   MPGDRAM,
302   MPGEXP,
303   MPGEPROM,
304   MPGSRAM,
305   MPGBOX,
306   MPGMDRAM,
307   MPGMEPROM,
308   MPGMBOX
309};
281310
311/*
312    Read a byte via the data bus. The decoding has already been done in the
313    SETOFFSET method, and we re-use the values stored there to quickly
314    access the appropriate component.
315*/
282316READ8_MEMBER( geneve_mapper_device::readm )
283317{
284318   UINT8 value = 0;
285   int page;
286   UINT32  physaddr;
287319
288320   // Premature access. The CPU reads the start vector before RESET.
289321   if (m_eprom==NULL) return 0;
290322
291   if (m_geneve_mode)
323   switch (m_mapdecode)
292324   {
293      // TODO: shortcut offset & 0xffc0 = 0xf100
294      if ((offset & 0xfff5)==0xf100)
295      {
296         // video
297         // ++++ ++++ ++++ -+-+
298         // 1111 0001 0000 0000
299         // 1111 0001 0000 0010
300         // 1111 0001 0000 1000
301         // 1111 0001 0000 1010
325   case MLGVIDEO:
326      m_video->readz(space, m_offset, &value, mem_mask);
327      if (VERBOSE>7) LOG("genboard: Read video %04x -> %02x\n", m_offset, value);
328      break;
302329
303         // 1 WS is always added; any pending video wait states are canceled
304         m_video_waiting = false;
305         do_wait(1);
330   case MLGMAPPER:
331      // mapper
332      value = m_map[m_offset];
333      if (VERBOSE>7) LOG("genboard: read mapper %04x -> %02x\n", m_offset, value);
334      break;
306335
307         // Initialize wait state timer
308         // Create 16 wait states (2 more than expected, experimenting)
309         if (m_video_waitstates)
310            do_wait(16);
336   case MLGKEY:
337      // key
338      value = m_keyboard->get_recent_key();
339      if (VERBOSE>7) LOG("genboard: Read keyboard -> %02x\n", value);
340      break;
311341
312         m_video->readz(space, offset, &value, mem_mask);
313         if (VERBOSE>7) LOG("genboard: Read video %04x -> %02x\n", offset, value);
314         return value;
315      }
316      if ((offset & 0xfff8)==0xf110)
317      {
318         // mapper
319         value = m_map[offset & 0x0007];
342   case MLGCLOCK:
343      // clock
344      // tests on the real machine showed that
345      // upper nibble is 0xf (probably because of the location at 0xf130?)
346      value = m_clock->read(space, m_offset) | 0xf0;
347      if (VERBOSE>7) LOG("genboard: Read clock %04x -> %02x\n", m_offset, value);
348      break;
320349
321         // Add appropriate number of waitstates
322         // 1 WS is added at least
323         do_wait(1);
324         if (VERBOSE>7) LOG("genboard: read mapper %04x -> %02x\n", offset, value);
325         return value;
326      }
327      if ((offset & 0xfff8) == 0xf118)
328      {
329         // key
330         value = m_keyboard->get_recent_key();
331         do_wait(1);
332         if (VERBOSE>7) LOG("genboard: Read keyboard -> %02x\n", value);
333         return value;
334      }
335      if ((offset & 0xfff0)==0xf130)
336      {
337         // clock
338         // tests on the real machine showed that
339         // upper nibble is 0xf (probably because of the location at 0xf130?)
340         value = m_clock->read(space, offset & 0x000f) | 0xf0;
341         do_wait(1);
342         if (VERBOSE>7) LOG("genboard: Read clock %04x -> %02x\n", offset, value);
343         return value;
344      }
345   }
346   else // TI mode
347   {
348      if ((offset & 0xfff8)==0x8000)
349      {
350         // mapper
351         value = m_map[offset & 0x0007];
352         do_wait(1);
353         if (VERBOSE>7) LOG("genboard: Read mapper %04x -> %02x\n", offset, value);
354         return value;
355      }
356      if ((offset & 0xfff8)== 0x8008)
357      {
358         // key
359         value = m_keyboard->get_recent_key();
360         do_wait(1);
361         if (VERBOSE>7) LOG("genboard: Read keyboard -> %02x\n", value);
362         return value;
363      }
364      if ((offset & 0xfff0)==0x8010)
365      {
366         // clock
367         // upper nibble is 1, only last byte gets a 2
368         // probably because of the location at 8010...8020?
369         // (TI mode used swapped byte order)
370         // unless we use a workspace at >F000, in which case we get 8x values
371         // Obscure, needs more investigation. We might as well ignore this,
372         // as the high nibble is obviously undefined and takes some past
373         // value floating around.
374         value = m_clock->read(space, offset & 0x000f);
375         value |= ((offset & 0x000f)==0x000f)? 0x20 : 0x10;
350   case MLTMAPPER:
351      // mapper
352      value = m_map[m_offset];
353      if (VERBOSE>7) LOG("genboard: Read mapper %04x -> %02x\n", m_offset, value);
354      break;
376355
377         do_wait(1);
378         if (VERBOSE>7) LOG("genboard: Read clock %04x -> %02x\n", offset, value);
379         return value;
380      }
381      if ((offset & 0xfc01)==0x8800)
382      {
383         // video
384         // ++++ ++-- ---- ---+
385         // 1000 1000 0000 00x0
356   case MLTKEY:
357      // key
358      value = m_keyboard->get_recent_key();
359      if (VERBOSE>7) LOG("genboard: Read keyboard -> %02x\n", value);
360      break;
386361
387         // 1 WS is always added; any pending video waitstates are canceled
388         m_video_waiting = false;
389         do_wait(1);
362   case MLTCLOCK:
363      // clock
364      // upper nibble is 1, only last byte gets a 2
365      // probably because of the location at 8010...8020?
366      // (TI mode used swapped byte order)
367      // unless we use a workspace at >F000, in which case we get 8x values
368      // Obscure, needs more investigation. We might as well ignore this,
369      // as the high nibble is obviously undefined and takes some past
370      // value floating around.
371      value = m_clock->read(space, m_offset);
372      value |= (m_offset==0x000f)? 0x20 : 0x10;
373      if (VERBOSE>7) LOG("genboard: Read clock %04x -> %02x\n", m_offset, value);
374      break;
390375
391         // Initialize waitstate timer
392         // Create 14 waitstates (+2, see above)
393         if (m_video_waitstates)
394            do_wait(16);
376   case MLTVIDEO:
377      // video
378      // ++++ ++-- ---- ---+
379      // 1000 1000 0000 00x0
380      m_video->readz(space, m_offset, &value, mem_mask);
381      if (VERBOSE>7) LOG("genboard: Read video %04x -> %02x\n", m_offset, value);
382      break;
395383
396         m_video->readz(space, offset, &value, mem_mask);
397         if (VERBOSE>7) LOG("genboard: Read video %04x -> %02x\n", offset, value);
398         return value;
399      }
400      if ((offset & 0xfc01)==0x9000)
401      {
402         // speech
403         // ++++ ++-- ---- ---+
404         // 1001 0000 0000 0000
405         // We need to add the address prefix bits
406         m_peribox->readz(space, offset | ((m_genmod)? 0x170000 : 0x070000), &value, mem_mask);
384   case MLTSPEECH:
385      // speech
386      // ++++ ++-- ---- ---+
387      // 1001 0000 0000 0000
388      // We need to add the address prefix bits
389      m_peribox->readz(space, m_offset, &value, mem_mask);
390      if (VERBOSE>7) LOG("genboard: Read speech -> %02x\n", value);
391      break;
407392
408         do_wait(1);
409         if (VERBOSE>7) LOG("genboard: Read speech -> %02x\n", value);
410         return value;
411      }
412      if ((offset & 0xfc01)==0x9800)
413      {
414         // grom simulation
415         // ++++ ++-- ---- ---+
416         // 1001 1000 0000 00x0
417         value = read_grom(space, offset, mem_mask);
393   case MLTGROM:
394      // grom simulation
395      // ++++ ++-- ---- ---+
396      // 1001 1000 0000 00x0
397      value = read_grom(space, m_offset, mem_mask);
398      if (VERBOSE>7) LOG("genboard: Read GROM %04x -> %02x\n", m_offset, value);
399      break;
418400
419         do_wait(1);
420         if (VERBOSE>7) LOG("genboard: Read GROM %04x -> %02x\n", offset, value);
421         return value;
422      }
423   }
401   case MLGSOUND:
402   case MLTSOUND:
403      value = 0;
404      break;
424405
425   page = (offset & 0xe000) >> 13;
426406
427   if (m_direct_mode)
428   {
429      physaddr = 0x1e0000; // points to boot eprom
430   }
431   else
432   {
433      if (!m_geneve_mode && page==3)
434      {
435         // Cartridge paging in TI mode
436         // See also cartridge type "paged" in gromport.h
437         // value 0x36 = 0 0110 110x xxxx xxxx xxxx (page 1)
438         // value 0x37 = 0 0110 111x xxxx xxxx xxxx (page 2)
439         // Only use this if there are 2*8 KiB cartridge ROM
440         if (VERBOSE>7) LOG("genboard: Cartridge area\n");
441         if (m_cartridge_size==0x4000 && m_cartridge_secondpage) physaddr = 0x06e000;
442         else physaddr = 0x06c000;
443      }
444      else
445      {
446         physaddr = (m_map[page] << 13);
447      }
448   }
407   case MPGDRAM:
408      // DRAM.
409      value = m_dram[m_physaddr];
410//          printf("dram read physaddr = %06x logaddr = %04x value = %02x\n", m_physaddr, m_offset, value);
411      if (VERBOSE>7) LOG("genboard: Read DRAM %04x (%06x) -> %02x\n", m_offset, m_physaddr, value);
412      break;
449413
450   physaddr |= (offset & 0x1fff);
414   case MPGEXP:
415      // On-board memory expansion for standard Geneve (never used)
416      if (VERBOSE>7) LOG("genboard: Read unmapped area %06x\n", m_physaddr);
417      value = 0;
418      break;
451419
452   if (!m_genmod)
453   {
454      // Standard Geneve
455      if ((physaddr & 0x180000)==0x000000)
456      {
457         // DRAM. One wait state.
458         do_wait(1);
420   case MPGEPROM:
421      // 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K)
422      // mirrored for f0, f2, f4, ...; f1, f3, f5, ...
423      value = m_eprom[m_physaddr];
424      if (VERBOSE>7) LOG("genboard: Read EPROM %04x (%06x) -> %02x\n", m_offset, m_physaddr, value);
425      break;
459426
460         value = m_dram[physaddr & 0x07ffff];
461//          printf("dram read physaddr = %06x logaddr = %04x value = %02x\n", physaddr, offset, value);
462         if (VERBOSE>7) LOG("genboard: Read DRAM %04x (%06x) -> %02x\n", offset, physaddr, value);
463         return value;
464      }
465
466      if ((physaddr & 0x180000)==0x080000)
427   case MPGSRAM:
428      if ((m_physaddr & m_sram_mask)==m_sram_val)
467429      {
468         // On-board memory expansion for standard Geneve (never used)
469         do_wait(1);
470         if (VERBOSE>7) LOG("genboard: Read unmapped area %06x\n", physaddr);
471         return 0;
430         value = m_sram[m_physaddr & ~m_sram_mask];
472431      }
432      else value = 0;
433      // Return in any case
434//          printf("sram read physaddr = %06x logaddr = %04x value = %02x\n", m_physaddr, m_offset, value);
435      if (VERBOSE>7) LOG("genboard: Read SRAM %04x (%06x) -> %02x\n", m_offset, m_physaddr, value);
436      break;
473437
474      if ((physaddr & 0x1e0000)==0x1e0000)
475      {
476         // 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K)
477         // mirrored for f0, f2, f4, ...; f1, f3, f5, ...
478         value = m_eprom[physaddr & 0x003fff];
479         do_wait(0);
480         if (VERBOSE>7) LOG("genboard: Read EPROM %04x (%06x) -> %02x\n", offset, physaddr, value);
481         return value;
482      }
483
484      if ((physaddr & 0x180000)==0x180000)
485      {
486         if ((physaddr & m_sram_mask)==m_sram_val)
487         {
488            value = m_sram[physaddr & ~m_sram_mask];
489         }
490         // Return in any case
491//          printf("sram read physaddr = %06x logaddr = %04x value = %02x\n", physaddr, offset, value);
492         do_wait(0);
493         if (VERBOSE>7) LOG("genboard: Read SRAM %04x (%06x) -> %02x\n", offset, physaddr, value);
494         return value;
495      }
496
438   case MPGBOX:
497439      // Route everything else to the P-Box
498440      //   0x000000-0x07ffff for the stock Geneve (AMC,AMB,AMA,A0 ...,A15)
499441      //   0x000000-0x1fffff for the GenMod.(AME,AMD,AMC,AMB,AMA,A0 ...,A15)
500      // Add a wait state
501      do_wait(1);
502442
503      physaddr = (physaddr & 0x0007ffff);  // 19 bit address (with AMA..AMC)
504      m_peribox->readz(space, physaddr, &value, mem_mask);
505      if (VERBOSE>7) LOG("genboard: Read P-Box %04x (%06x) -> %02x\n", offset, physaddr, value);
506      return value;
443      m_peribox->readz(space, m_physaddr, &value, mem_mask);
444      if (VERBOSE>7) LOG("genboard: Read P-Box %04x (%06x) -> %02x\n", m_offset, m_physaddr, value);
445      break;
446
447   case MPGMDRAM:
448      // DRAM. One wait state.
449      value = m_dram[m_physaddr];
450      break;
451
452   case MPGMEPROM:
453      // 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K)
454      // mirrored for f0, f2, f4, ...; f1, f3, f5, ...
455      value = m_eprom[m_physaddr];
456      break;
457
458   case MPGMBOX:
459      // Route everything else to the P-Box
460      m_peribox->readz(space, m_physaddr, &value, mem_mask);
461      break;
507462   }
508   else
463   return value;
464}
465
466WRITE8_MEMBER( geneve_mapper_device::writem )
467{
468   switch (m_mapdecode)
509469   {
510      // GenMod mode
511      if ((m_timode) && ((physaddr & 0x180000)==0x000000))
512      {
513         // DRAM. One wait state.
514         value = m_dram[physaddr & 0x07ffff];
515         if (!m_turbo) do_wait(1);
516         return value;
517      }
470   case MLGVIDEO:
471      // video
472      // ++++ ++++ ++++ ---+
473      // 1111 0001 0000 .cc0
474      m_video->write(space, m_offset, data, mem_mask);
475      if (VERBOSE>7) LOG("genboard: Write video %04x <- %02x\n", offset, data);
476      break;
518477
519      if ((physaddr & 0x1e0000)==0x1e0000)
478   case MLGMAPPER:
479      // mapper
480      m_map[m_offset] = data;
481      if (VERBOSE>7) LOG("genboard: Write mapper %04x <- %02x\n", offset, data);
482      break;
483
484   case MLGCLOCK:
485      // clock
486      // ++++ ++++ ++++ ----
487      m_clock->write(space, m_offset, data);
488      if (VERBOSE>7) LOG("genboard: Write clock %04x <- %02x\n", offset, data);
489      break;
490
491   case MLGSOUND:
492      // sound
493      // ++++ ++++ ++++ ---+
494      m_sound->write(space, 0, data, mem_mask);
495      if (VERBOSE>7) LOG("genboard: Write sound <- %02x\n", data);
496      break;
497
498   case MLTMAPPER:
499      // mapper
500      m_map[m_offset] = data;
501      if (VERBOSE>7) LOG("genboard: Write mapper %04x <- %02x\n", offset, data);
502      break;
503
504   case MLTCLOCK:
505      // clock
506      m_clock->write(space, m_offset, data);
507      if (VERBOSE>7) LOG("genboard: Write clock %04x <- %02x\n", offset, data);
508      break;
509
510   case MLTVIDEO:
511      // video
512      // ++++ ++-- ---- ---+
513      // 1000 1100 0000 00c0
514      // Initialize waitstate timer
515      m_video->write(space, m_offset, data, mem_mask);
516      if (VERBOSE>7) LOG("genboard: Write video %04x <- %02x\n", offset, data);
517      break;
518
519   case MLTSPEECH:
520      // speech
521      // ++++ ++-- ---- ---+
522      // 1001 0100 0000 0000
523      // We need to add the address prefix bits
524      m_peribox->write(space, m_offset, data, mem_mask);
525      if (VERBOSE>7) LOG("genboard: Write speech <- %02x\n", data);
526      break;
527
528   case MLTGROM:
529      // grom simulation
530      // ++++ ++-- ---- ---+
531      // 1001 1100 0000 00c0
532      write_grom(space, m_offset, data, mem_mask);
533      if (VERBOSE>7) LOG("genboard: Write GROM %04x <- %02x\n", offset, data);
534      break;
535
536   case MLTSOUND:
537      // sound
538      // ++++ ++-- ---- ---+
539      // 1000 0100 0000 0000
540      m_sound->write(space, 0, data, mem_mask);
541      if (VERBOSE>7) LOG("genboard: Write sound <- %02x\n", data);
542      break;
543
544   case MLTKEY:
545   case MLGKEY:
546      break;
547
548   case MPGDRAM:
549      // DRAM write. One wait state. (only for normal Geneve)
550      m_dram[m_physaddr] = data;
551      if (VERBOSE>7) LOG("genboard: Write DRAM %04x (%06x) <- %02x\n", offset, m_physaddr, data);
552      break;
553
554   case MPGEXP:
555      // On-board memory expansion for standard Geneve (never used)
556      if (VERBOSE>7) LOG("genboard: Write unmapped area %06x\n", m_physaddr);
557      break;
558
559   case MPGEPROM:
560      // 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K)
561      // mirrored for f0, f2, f4, ...; f1, f3, f5, ...
562      // Ignore EPROM write
563      if (VERBOSE>7) LOG("genboard: Write EPROM %04x (%06x) <- %02x, ignored\n", offset, m_physaddr, data);
564      break;
565
566   case MPGSRAM:
567      if ((m_physaddr & m_sram_mask)==m_sram_val)
520568      {
521         // 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K)
522         // mirrored for f0, f2, f4, ...; f1, f3, f5, ...
523         value = m_eprom[physaddr & 0x003fff];
524         do_wait(0);
525         return value;
569         m_sram[m_physaddr & ~m_sram_mask] = data;
526570      }
527      // Route everything else to the P-Box
528      physaddr = (physaddr & 0x001fffff);  // 21 bit address for Genmod
571      if (VERBOSE>7) LOG("genboard: Write SRAM %04x (%06x) <- %02x\n", offset, m_physaddr, data);
572      break;
529573
530      if (!m_turbo) do_wait(1);
531      // Check: Are waitstates completely turned off for turbo mode, or
532      // merely the waitstates for DRAM memory access and box access?
574   case MPGBOX:
575      m_physaddr = (m_physaddr & 0x0007ffff);  // 19 bit address
576      if (VERBOSE>7) LOG("genboard: Write P-Box %04x (%06x) <- %02x\n", offset, m_physaddr, data);
577      m_peribox->write(space, m_physaddr, data, mem_mask);
578      break;
533579
534      m_peribox->readz(space, physaddr, &value, mem_mask);
535      return value;
580   case MPGMDRAM:
581      // DRAM. One wait state.
582      m_dram[m_physaddr] = data;
583      break;
584
585   case MPGMEPROM:
586      // 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K)
587      // mirrored for f0, f2, f4, ...; f1, f3, f5, ...
588      // Ignore EPROM write
589      break;
590
591   case MPGMBOX:
592      // Route everything else to the P-Box
593      m_peribox->write(space, m_physaddr, data, mem_mask);
594      break;
536595   }
537596}
538597
539
540598/*
541Geneve mode:
542f100 / fff1: v9938_w
543f110 / fff8: mapper_w
544f120 / fff0: sound_w
545f130 / fff0: clock_w
546
547TI mode:
5488000 / fff8: mapper_w
5498010 / fff0: clock_w
5508400 / fc00: sound_w
5518c00 / fff9: v9938_w
5529400 / fc00: speech_w
5539c00 / fffd: grom_w
554
599    Accept the address passed over the address bus and decode it appropriately.
600    This decoding will later be used in the READ/WRITE member functions. Also,
601    we initiate wait state creation here.
555602*/
556
557WRITE8_MEMBER( geneve_mapper_device::writem )
603SETOFFSET_MEMBER( geneve_mapper_device::setoffset )
558604{
559   UINT32  physaddr;
560605   int page;
561606
562   if (m_peribox==NULL) return;    // see above: prevent premature access
607   m_mapdecode = 0;
608   m_offset = offset;
609   m_physaddr = 0;
563610
564   if (m_geneve_mode)
611   if (VERBOSE>7) LOG("genboard: setoffset = %04x\n", offset);
612
613   // Premature access. The CPU reads the start vector before RESET.
614   if (m_eprom==NULL) return;
615
616   if (m_read_mode)    // got this from DBIN
565617   {
566      if ((offset & 0xfff1)==0xf100)
618      // Logical addresses
619      if (m_geneve_mode)
567620      {
568         // video
569         // ++++ ++++ ++++ ---+
570         // 1111 0001 0000 .cc0
571         m_video->write(space, offset, data, mem_mask);
621         // TODO: shortcut offset & 0xffc0 = 0xf100
622         if ((offset & 0xfff5)==0xf100)
623         {
624            // video
625            // ++++ ++++ ++++ -+-+
626            // 1111 0001 0000 0000
627            // 1111 0001 0000 0010
628            // 1111 0001 0000 1000
629            // 1111 0001 0000 1010
572630
573         // 1 WS is always added; any pending video waitstates are canceled
574         m_video_waiting = false;
575         do_wait(1);
631            // 1 WS is always added; any pending video wait states are canceled
632            m_video_waiting = false;
633            do_wait(1);
576634
577         // Initialize waitstate timer
578         // Create 14 waitstates (+3, experimenting)
579         if (m_video_waitstates)
580            do_wait(17);
635            // Initialize wait state timer
636            // Create 16 wait states (2 more than expected, experimenting)
637            if (m_video_waitstates) do_wait(16);
581638
582         if (VERBOSE>7) LOG("genboard: Write video %04x <- %02x\n", offset, data);
583         return;
639            m_mapdecode = MLGVIDEO;
640            return;
641         }
642         if ((offset & 0xfff8)==0xf110)
643         {
644            // mapper
645            m_mapdecode = MLGMAPPER;
646            m_offset = m_offset & 0x0007;
647            do_wait(1);
648            return;
649         }
650         if ((offset & 0xfff8) == 0xf118)
651         {
652            // key
653            m_mapdecode = MLGKEY;
654            do_wait(1);
655            return;
656         }
657         if ((offset & 0xfff0)==0xf130)
658         {
659            // clock
660            // tests on the real machine showed that
661            // upper nibble is 0xf (probably because of the location at 0xf130?)
662            m_mapdecode = MLGCLOCK;
663            m_offset = m_offset & 0x000f;
664            do_wait(1);
665            return;
666         }
584667      }
585      if ((offset & 0xfff8)==0xf110)
668      else
586669      {
587         // mapper
588         m_map[offset & 0x0007] = data;
589         do_wait(1);
590         if (VERBOSE>7) LOG("genboard: Write mapper %04x <- %02x\n", offset, data);
591         return;
670         if ((offset & 0xfff8)==0x8000)
671         {
672            // mapper
673            m_mapdecode = MLTMAPPER;
674            m_offset = m_offset & 0x0007;
675            do_wait(1);
676            return;
677         }
678         if ((offset & 0xfff8)== 0x8008)
679         {
680            // key
681            m_mapdecode = MLTKEY;
682            do_wait(1);
683            return;
684         }
685         if ((offset & 0xfff0)==0x8010)
686         {
687            // clock
688            m_mapdecode = MLTCLOCK;
689            m_offset = m_offset & 0x000f;
690            do_wait(1);
691            return;
692         }
693         if ((offset & 0xfc01)==0x8800)
694         {
695            // video
696            // ++++ ++-- ---- ---+
697            // 1000 1000 0000 00x0
698            // 1 WS is always added; any pending video waitstates are canceled
699            m_mapdecode = MLTVIDEO;
700            m_video_waiting = false;
701            do_wait(1);
702
703            // Initialize waitstate timer
704            // Create 14 waitstates (+2, see above)
705            if (m_video_waitstates) do_wait(16);
706            return;
707         }
708         if ((offset & 0xfc01)==0x9000)
709         {
710            // speech
711            // ++++ ++-- ---- ---+
712            // 1001 0000 0000 0000
713            // We need to add the address prefix bits
714            m_mapdecode = MLTSPEECH;
715            m_offset = offset | ((m_genmod)? 0x170000 : 0x070000);
716            m_peribox->setaddress_dbin(space, m_offset, m_read_mode);
717            do_wait(1);
718            return;
719         }
720         if ((offset & 0xfc01)==0x9800)
721         {
722            // grom simulation
723            // ++++ ++-- ---- ---+
724            // 1001 1000 0000 00x0
725            m_mapdecode = MLTGROM;
726            do_wait(1);
727            return;
728         }
592729      }
593      if ((offset & 0xfff1)==0xf120)
594      {
595         // sound
596         // ++++ ++++ ++++ ---+
597         m_sound->write(space, 0, data, mem_mask);
730      // still here? Then go via mapping.
731      page = (offset & 0xe000) >> 13;
598732
599         // Add 24 waitstates. This is an average value, as the
600         // waitstate generation seems to depend on an external timer of
601         // the sound chip
602         m_waitcount = 24;
603         m_ready(CLEAR_LINE);
604         if (VERBOSE>7) LOG("genboard: Write sound <- %02x\n", data);
605         return;
606      }
607      if ((offset & 0xfff0)==0xf130)
733      // Determine physical address
734      if (m_direct_mode)
608735      {
609         // clock
610         // ++++ ++++ ++++ ----
611         m_clock->write(space, offset & 0x00f, data);
612         do_wait(1);
613         if (VERBOSE>7) LOG("genboard: Write clock %04x <- %02x\n", offset, data);
614         return;
736         m_physaddr = 0x1e0000; // points to boot eprom
615737      }
616   }
617   else
618   {
619      // TI mode
620      if ((offset & 0xfff8)==0x8000)
738      else
621739      {
622         // mapper
623         m_map[offset & 0x0007] = data;
624         do_wait(1);
625         if (VERBOSE>7) LOG("genboard: Write mapper %04x <- %02x\n", offset, data);
626         return;
740         if (!m_geneve_mode && page==3)
741         {
742            if (m_cartridge_size==0x4000 && m_cartridge_secondpage) m_physaddr = 0x06e000;
743            else m_physaddr = 0x06c000;
744         }
745         else
746         {
747            m_physaddr = (m_map[page] << 13);
748         }
627749      }
628      // No key write at 8008
629      if ((offset & 0xfff0)==0x8010)
750      m_physaddr |= (offset & 0x1fff);
751
752      if (!m_genmod)      // Standard Geneve
630753      {
631         // clock
632         m_clock->write(space, offset & 0x00f, data);
754         if ((m_physaddr & 0x180000)==0x000000)
755         {
756            // DRAM.
757            m_physaddr = m_physaddr & 0x07ffff;
758            m_mapdecode = MPGDRAM;
759            do_wait(1);
760            return;
761         }
762
763         if ((m_physaddr & 0x180000)==0x080000)
764         {
765            // On-board memory expansion for standard Geneve (never used)
766            m_mapdecode = MPGEXP;
767            do_wait(1);
768            return;
769         }
770
771         if ((m_physaddr & 0x1e0000)==0x1e0000)
772         {
773            // 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K)
774            // mirrored for f0, f2, f4, ...; f1, f3, f5, ...
775            m_mapdecode = MPGEPROM;
776            m_physaddr = m_physaddr & 0x003fff;
777            do_wait(0);
778            return;
779         }
780
781         if ((m_physaddr & 0x180000)==0x180000)
782         {
783            m_mapdecode = MPGSRAM;
784            do_wait(0);
785            return;
786         }
787
788         // Route everything else to the P-Box
789         //   0x000000-0x07ffff for the stock Geneve (AMC,AMB,AMA,A0 ...,A15)
790         //   0x000000-0x1fffff for the GenMod.(AME,AMD,AMC,AMB,AMA,A0 ...,A15)
791         // Add a wait state
633792         do_wait(1);
634         if (VERBOSE>7) LOG("genboard: Write clock %04x <- %02x\n", offset, data);
635         return;
636      }
637      if ((offset & 0xfc01)==0x8400)
638      {
639         // sound
640         // ++++ ++-- ---- ---+
641         // 1000 0100 0000 0000
793         m_mapdecode = MPGBOX;
642794
643         m_sound->write(space, 0, data, mem_mask);
644         // Add 24 waitstates. This is an approximation, as the
645         // waitstate generation seems to depend on an external timer of
646         // the sound chip
647         m_waitcount = 24;
648         m_ready(CLEAR_LINE);
649         if (VERBOSE>7) LOG("genboard: Write sound <- %02x\n", data);
795         m_physaddr = (m_physaddr & 0x0007ffff);  // 19 bit address (with AMA..AMC)
796         m_peribox->setaddress_dbin(space, m_physaddr, m_read_mode);
650797         return;
651798      }
652      if ((offset & 0xfc01)==0x8c00)
799      else
653800      {
654         // video
655         // ++++ ++-- ---- ---+
656         // 1000 1100 0000 00c0
657         // Initialize waitstate timer
658         m_video->write(space, offset, data, mem_mask);
801         // GenMod mode
802         if ((m_timode) && ((m_physaddr & 0x180000)==0x000000))
803         {
804            // DRAM. One wait state.
805            m_mapdecode = MPGMDRAM;
806            m_physaddr = m_physaddr & 0x07ffff;
807            if (!m_turbo) do_wait(1);
808            return;
809         }
659810
660         // 1 WS is always added; any pending video waitstates are canceled
661         m_video_waiting = false;
662         do_wait(1);
811         if ((m_physaddr & 0x1e0000)==0x1e0000)
812         {
813            // 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K)
814            // mirrored for f0, f2, f4, ...; f1, f3, f5, ...
815            m_mapdecode = MPGMEPROM;
816            m_physaddr = m_physaddr & 0x003fff;
817            do_wait(0);
818            return;
819         }
663820
664         // Initialize waitstate timer
665         // Create 14 waitstates (+3)
666         if (m_video_waitstates)
667            do_wait(17);
821         // Route everything else to the P-Box
822         m_physaddr = (m_physaddr & 0x001fffff);  // 21 bit address for Genmod
823         m_mapdecode = MPGMBOX;
668824
669         if (VERBOSE>7) LOG("genboard: Write video %04x <- %02x\n", offset, data);
825         if (!m_turbo) do_wait(1);
826         // Check: Are waitstates completely turned off for turbo mode, or
827         // merely the waitstates for DRAM memory access and box access?
828
829         m_peribox->setaddress_dbin(space, m_physaddr, m_read_mode);
670830         return;
671831      }
672      if ((offset & 0xfc01)==0x9400)
673      {
674         // speech
675         // ++++ ++-- ---- ---+
676         // 1001 0100 0000 0000
677         // We need to add the address prefix bits
678         m_peribox->write(space, offset | ((m_genmod)? 0x170000 : 0x070000), data, mem_mask);
679         do_wait(1);
680         if (VERBOSE>7) LOG("genboard: Write speech <- %02x\n", data);
681         return;
682      }
683      if ((offset & 0xfc01)==0x9c00)
684      {
685         // grom simulation
686         // ++++ ++-- ---- ---+
687         // 1001 1100 0000 00c0
688         write_grom(space, offset, data, mem_mask);
689         do_wait(1);
690         if (VERBOSE>7) LOG("genboard: Write GROM %04x <- %02x\n", offset, data);
691         return;
692      }
693832   }
694
695   page = (offset & 0xe000) >> 13;
696   if (m_direct_mode)
697   {
698      physaddr = 0x1e0000; // points to boot eprom
699   }
700833   else
701   {
702      if (!m_geneve_mode && page==3)
834   {   // Write access
835      // Logical addresses
836      if (m_geneve_mode)
703837      {
704         if (m_cartridge_size==0x4000)
838         if ((offset & 0xfff1)==0xf100)
705839         {
706            // Writing to 0x6000 selects page 1,
707            // writing to 0x6002 selects page 2
708            m_cartridge_secondpage = ((offset & 0x0002)!=0);
840            // 1 WS is always added; any pending video waitstates are canceled
841            m_mapdecode = MLGVIDEO;
842            m_video_waiting = false;
709843            do_wait(1);
710            if (VERBOSE>7) LOG("genboard: Set cartridge page %02x\n", m_cartridge_secondpage);
844            // Initialize waitstate timer
845            // Create 14 waitstates (+3, experimenting)
846            if (m_video_waitstates) do_wait(17);
847            return;
848         }
849         if ((offset & 0xfff8)==0xf110)
850         {
851            m_mapdecode = MLGMAPPER;
852            m_offset = m_offset & 0x0007;
853            do_wait(1);
854            return;
855         }
856         if ((offset & 0xfff1)==0xf120)
857         {
858            // Add 24 waitstates. This is an average value, as the
859            // waitstate generation seems to depend on an external timer of
860            // the sound chip
861            // TODO: do it properly with the use of READY
862            m_mapdecode = MLGSOUND;
863            do_wait(24);
864            return;
865         }
866         if ((offset & 0xfff0)==0xf130)
867         {
868            m_mapdecode = MLGCLOCK;
869            m_offset = m_offset & 0x00f;
870            do_wait(1);
871            return;
872         }
873      }
874      else
875      {
876         // TI mode
877         if ((offset & 0xfff8)==0x8000)
878         {
879            m_mapdecode = MLTMAPPER;
880            m_offset = m_offset & 0x0007;
881            do_wait(1);
882            return;
883         }
884         if ((offset & 0xfff0)==0x8010)
885         {
886            m_mapdecode = MLTCLOCK;
887            m_offset = m_offset & 0x00f;
888            do_wait(1);
889            return;
890         }
891         if ((offset & 0xfc01)==0x9c00)
892         {
893            m_mapdecode = MLTGROM;
894            do_wait(1);
895            return;
896         }
897         if ((offset & 0xfc01)==0x8400)
898         {
899            // Add 24 waitstates. This is an approximation, as the
900            // waitstate generation seems to depend on an external timer of
901            // the sound chip
902            // TODO: do it properly with the use of READY-
903            m_mapdecode = MLTSOUND;
904            do_wait(24);
905            return;
906         }
907         if ((offset & 0xfc01)==0x8c00)
908         {
909            // 1 WS is always added; any pending video waitstates are canceled
910            m_mapdecode = MLTVIDEO;
911            m_video_waiting = false;
912            do_wait(1);
711913
914            // Initialize waitstate timer
915            // Create 14 waitstates (+3)
916            if (m_video_waitstates) do_wait(17);
712917            return;
713918         }
714         else
919
920         if ((offset & 0xfc01)==0x9400)
715921         {
716            // writing into cartridge rom space (no bankswitching)
717            if ((((offset & 0x1000)==0x0000) && !m_cartridge6_writable)
718               || (((offset & 0x1000)==0x1000) && !m_cartridge7_writable))
922            m_mapdecode = MLTSPEECH;
923            m_offset = m_offset | ((m_genmod)? 0x170000 : 0x070000);
924            m_peribox->setaddress_dbin(space, m_offset, m_read_mode);
925            do_wait(1);
926            return;
927         }
928      }
929
930      // Determine physical address
931      page = (m_offset & 0xe000) >> 13;
932
933      if (m_direct_mode)
934      {
935         m_physaddr = 0x1e0000; // points to boot eprom
936      }
937      else
938      {
939         if (!m_geneve_mode && page==3)
940         {
941            if (m_cartridge_size==0x4000)
719942            {
720               if (VERBOSE>0) LOG("genboard: Writing to protected cartridge space %04x ignored\n", offset);
943               m_cartridge_secondpage = ((m_offset & 0x0002)!=0);
944               if (VERBOSE>7) LOG("genboard: Set cartridge page %02x\n", m_cartridge_secondpage);
945               do_wait(1);
721946               return;
722947            }
723948            else
724               // TODO: Check whether secondpage is really ignored
725               physaddr = 0x06c000;
949            {
950               // writing into cartridge rom space (no bankswitching)
951               if ((((m_offset & 0x1000)==0x0000) && !m_cartridge6_writable)
952                  || (((m_offset & 0x1000)==0x1000) && !m_cartridge7_writable))
953               {
954                  if (VERBOSE>0) LOG("genboard: Writing to protected cartridge space %04x ignored\n", m_offset);
955                  return;
956               }
957               else
958                  // TODO: Check whether secondpage is really ignored
959               m_physaddr = 0x06c000;
960            }
726961         }
962         else
963            m_physaddr = (m_map[page] << 13);
727964      }
728      else
729         physaddr = (m_map[page] << 13);
730   }
731965
732   physaddr |= offset & 0x1fff;
966      m_physaddr |= m_offset & 0x1fff;
733967
734//  printf("write physaddr = %06x logaddr = %04x value = %02x\n", physaddr, offset, data);
735
736   if (!m_genmod)
737   {
738      if ((physaddr & 0x180000)==0x000000)
968      if (!m_genmod)
739969      {
740         // DRAM write. One wait state. (only for normal Geneve)
741         m_dram[physaddr & 0x07ffff] = data;
742         do_wait(1);
743         if (VERBOSE>7) LOG("genboard: Write DRAM %04x (%06x) <- %02x\n", offset, physaddr, data);
744         return;
745      }
970         if ((m_physaddr & 0x180000)==0x000000)
971         {
972            m_mapdecode = MPGDRAM;
973            m_physaddr = m_physaddr & 0x07ffff;
974            do_wait(1);
975            return;
976         }
977         if ((m_physaddr & 0x180000)==0x080000)
978         {
979            m_mapdecode = MPGEXP;
980            do_wait(1);
981            return;
982         }
746983
747      if ((physaddr & 0x180000)==0x080000)
748      {
749         // On-board memory expansion for standard Geneve (never used)
984         if ((m_physaddr & 0x1e0000)==0x1e0000)
985         {
986            m_mapdecode = MPGEPROM;
987            do_wait(0); // EPROM
988            return;
989         }
990         if ((m_physaddr & 0x180000)==0x180000)
991         {
992            m_mapdecode = MPGSRAM;
993            do_wait(0); // SRAM
994            return;
995         }
996
997         // Route everything else to the P-Box
998         // Add a wait state
999
1000         // only AMA, AMB, AMC are used; AMD and AME are not used
1001         m_mapdecode = MPGBOX;
1002         m_physaddr = (m_physaddr & 0x0007ffff);  // 19 bit address
1003         m_peribox->setaddress_dbin(space, m_physaddr, m_read_mode);
7501004         do_wait(1);
751         if (VERBOSE>7) LOG("genboard: Write unmapped area %06x\n", physaddr);
752         return;
7531005      }
754
755      if ((physaddr & 0x1e0000)==0x1e0000)
1006      else
7561007      {
757         // 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K)
758         // mirrored for f0, f2, f4, ...; f1, f3, f5, ...
759         // Ignore EPROM write
760         do_wait(0);
761         if (VERBOSE>7) LOG("genboard: Write EPROM %04x (%06x) <- %02x, ignored\n", offset, physaddr, data);
762         return;
763      }
1008         // GenMod mode
1009         if ((m_physaddr & 0x1e0000)==0x1e0000)
1010         {   // EPROM, ignore
1011            m_mapdecode = MPGMEPROM;
1012            do_wait(0);
1013            return;
1014         }
7641015
765      if ((physaddr & 0x180000)==0x180000)
766      {
767         if ((physaddr & m_sram_mask)==m_sram_val)
1016         if (m_timode && ((m_physaddr & 0x180000)==0x000000))
7681017         {
769            m_sram[physaddr & ~m_sram_mask] = data;
1018            m_mapdecode = MPGMDRAM;
1019            m_physaddr = m_physaddr & 0x07ffff;
1020            if (!m_turbo) do_wait(1);
1021            return;
7701022         }
771         if (VERBOSE>7) LOG("genboard: Write SRAM %04x (%06x) <- %02x\n", offset, physaddr, data);
772         do_wait(0);
773         // Return in any case
774         return;
775      }
776      // Route everything else to the P-Box
777      // Add a wait state
7781023
779      // only AMA, AMB, AMC are used; AMD and AME are not used
780      physaddr = (physaddr & 0x0007ffff);  // 19 bit address
781      if (VERBOSE>7) LOG("genboard: Write P-Box %04x (%06x) <- %02x\n", offset, physaddr, data);
782      m_peribox->write(space, physaddr, data, mem_mask);
783      do_wait(1);
784   }
785   else
786   {
787      // GenMod mode
788      if ((m_timode) && ((physaddr & 0x180000)==0x000000))
789      {
790         // DRAM. One wait state.
791         m_dram[physaddr & 0x07ffff] = data;
1024         // Route everything else to the P-Box
1025         m_mapdecode = MPGMBOX;
1026         m_physaddr = (m_physaddr & 0x001fffff);  // 21 bit address for Genmod
1027         m_peribox->setaddress_dbin(space, m_physaddr, m_read_mode);
7921028         if (!m_turbo) do_wait(1);
793         return;
7941029      }
795
796      if ((physaddr & 0x1e0000)==0x1e0000)
797      {
798         // 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K)
799         // mirrored for f0, f2, f4, ...; f1, f3, f5, ...
800         // Ignore EPROM write
801         if (!m_turbo) do_wait(1);
802         return;
803      }
804      // Route everything else to the P-Box
805      physaddr = (physaddr & 0x001fffff);  // 21 bit address for Genmod
806      m_peribox->write(space, physaddr, data, mem_mask);
807      if (!m_turbo) do_wait(1);
8081030   }
8091031}
8101032
r25469r25470
8161038{
8171039   if (clock==ASSERT_LINE && m_waitcount!=0)
8181040   {
1041      if (VERBOSE>5) LOG("genboard: clock\n");
8191042      m_waitcount--;
8201043      if (m_waitcount==0) m_ready(ASSERT_LINE);
8211044   }
8221045}
8231046
1047/*
1048    We need the DBIN line for the setoffset operation.
1049*/
1050void geneve_mapper_device::dbin(int state)
1051{
1052   m_read_mode = (state==ASSERT_LINE);
1053   if (VERBOSE>7) LOG("genboard: dbin = %02x\n", m_read_mode? 1:0);
1054}
1055
8241056/***    DEVICE LIFECYCLE FUNCTIONS      ***/
8251057
8261058void geneve_mapper_device::device_start()
r25469r25470
8581090   m_extra_waitstates = false;
8591091   m_video_waitstates = true;
8601092   m_video_waiting = false;
1093   m_read_mode = false;
8611094
8621095   m_geneve_mode =false;
8631096   m_direct_mode = true;
trunk/src/mess/machine/ti99/genboard.h
r25469r25470
135135
136136   DECLARE_READ8_MEMBER( readm );
137137   DECLARE_WRITE8_MEMBER( writem );
138   DECLARE_SETOFFSET_MEMBER( setoffset );
138139
139140   DECLARE_INPUT_CHANGED_MEMBER( gm_changed );
140141
141142   void clock_in(int state);
143   void dbin(int state);
142144
143145protected:
144146   virtual void    device_start();
r25469r25470
157159   bool        m_video_waitstates;
158160   bool        m_extra_waitstates;
159161
162   bool        m_read_mode;
163
160164   // Mapper function
161165   bool    m_geneve_mode;
162166   bool    m_direct_mode;
r25469r25470
166170   bool    m_cartridge7_writable;
167171   int     m_map[8];
168172
173   int     m_mapdecode;
174
175   int     m_offset;
176   int     m_physaddr;
177
169178   // Genmod modifications
170179   bool    m_turbo;
171180   bool    m_genmod;
trunk/src/mess/machine/ti99/spchsyn.c
r25469r25470
2828#define VERBOSE 1
2929#define LOG logerror
3030
31#define REAL_TIMING 0
32
3331/****************************************************************************/
3432
3533ti_speech_synthesizer_device::ti_speech_synthesizer_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
r25469r25470
3836}
3937
4038/*
41    Comments on real timing in the TMS5200 emulation
42
43    Real timing means that the synthesizer clears the /READY line (puts high)
44    whenever a read or write access is in progress. This is done by setting
45    /RS and /WS lines, according to the read or write operation. The /READY line
46    is asserted again after some time. Real timing is used once the tms5220_wsq_w
47    and tms5220_rsq_w are called.
48
49    Within the TI systems, the /RS and /WS lines are controlled directly by the
50    address bus. There is currently no way to insert wait states between
51    the address setting and the data bus sampling, since this is an atomic
52    operation in the emulator (read_byte). It would be necessary to somehow
53    announce the pending read before it actually happens so that devices
54    like this VSP may insert wait states before the read.
55
56    The TMS5220 implementation assumes that wait states are respected and
57    therefore delivers bad values when queried too early. It uses a latch that
58    gets the new value after some time has expired.
59
60    To fix this we have to modify the RS/WS methods in TMS5200 to immediately
61    set the status (after updating the sound status, or the status will be
62    outdated too early).
63
64    Also note that the /RS and /WS lines must be cleared (put to high) when the
65    read is done. Again, this is not possible with the current implementation.
66    So we do this in the ready callback.
67
68    On the bottom line we will stay with the not-REAL_TIMING for now and wait
69    for the core to allow for split read accesses.
70*/
71
72
73/*
7439    Memory read
7540*/
76#if REAL_TIMING
41
7742// ======  This is the version with real timing =======
7843READ8Z_MEMBER( ti_speech_synthesizer_device::readz )
7944{
8045   if ((offset & m_select_mask)==m_select_value)
8146   {
82      m_vsp->wsq_w(TRUE);
83      m_vsp->rsq_w(FALSE);
84      *value = m_vsp->read(offset) & 0xff;
47      *value = m_vsp->status_r(space, offset, 0xff) & 0xff;
8548      if (VERBOSE>4) LOG("spchsyn: read value = %02x\n", *value);
49      // We should clear the lines at this point. The TI-99/4A clears the
50      // lines by setting the address bus to a different value, but the
51      // Geneve may behave differently. This may not 100% reflect the real
52      // situation, but it ensures a safe processing.
53      m_vsp->rsq_w(TRUE);
54      m_vsp->wsq_w(TRUE);
8655   }
8756}
8857
r25469r25470
9362{
9463   if ((offset & m_select_mask)==(m_select_value | 0x0400))
9564   {
96      m_vsp->rsq_w(m_vsp, TRUE);
97      m_vsp->wsq_w(m_vsp, FALSE);
9865      if (VERBOSE>4) LOG("spchsyn: write value = %02x\n", data);
99      m_vsp->write(offset, data);
66      m_vsp->data_w(space, offset, data);
67      // Note that we must NOT clear the lines here. Find the lines in the
68      // READY callback below.
10069   }
10170}
10271
103#else
104// ======  This is the version without real timing =======
105
106READ8Z_MEMBER( ti_speech_synthesizer_device::readz )
72SETADDRESS_DBIN_MEMBER( ti_speech_synthesizer_device::setaddress_dbin )
10773{
108   if ((offset & m_select_mask)==m_select_value)
74   if ((offset & m_select_mask & ~0x0400)==m_select_value)
10975   {
110      machine().device("maincpu")->execute().adjust_icount(-(18+3));      /* this is just a minimum, it can be more */
111      *value = m_vsp->status_r(space, offset, 0xff) & 0xff;
112      if (VERBOSE>4) LOG("spchsyn: read value = %02x\n", *value);
113   }
114}
76      if (VERBOSE>4) LOG("spchsyn: set address = %04x, dbin = %d\n", offset, state);
77      m_read_mode = (state==ASSERT_LINE);
78      bool readop = (offset & 0x0400)==0;
11579
116/*
117    Memory write
118*/
119WRITE8_MEMBER( ti_speech_synthesizer_device::write )
120{
121   if ((offset & m_select_mask)==(m_select_value | 0x0400))
122   {
123      machine().device("maincpu")->execute().adjust_icount(-(54+3));      /* this is just an approx. minimum, it can be much more */
124
125      /* RN: the stupid design of the tms5220 core means that ready is cleared */
126      /* when there are 15 bytes in FIFO.  It should be 16.  Of course, if */
127      /* it were the case, we would need to store the value on the bus, */
128      /* which would be more complex. */
129      if (!m_vsp->readyq_r())
80      if (m_read_mode != readop)
13081      {
131         attotime time_to_ready = attotime::from_double(m_vsp->time_to_ready());
132         int cycles_to_ready = machine().device<cpu_device>("maincpu")->attotime_to_cycles(time_to_ready);
133         if (VERBOSE>8) LOG("spchsyn: time to ready: %f -> %d\n", time_to_ready.as_double(), (int) cycles_to_ready);
134
135         machine().device("maincpu")->execute().adjust_icount(-cycles_to_ready);
136         machine().scheduler().timer_set(attotime::zero, FUNC_NULL);
82         // reset all; this is not a valid access
83         m_vsp->rsq_w(TRUE);
84         m_vsp->wsq_w(TRUE);
13785      }
138      if (VERBOSE>4) LOG("spchsyn: write value = %02x\n", data);
139      m_vsp->data_w(space, offset, data);
86      else
87      {
88         if (readop)
89         {
90            // Caution: We MUST first clear (TRUE) one line to avoid
91            // both RS* and WS* be asserted (otherwise tms5220 will report "illegal")
92            m_vsp->wsq_w(TRUE);
93            m_vsp->rsq_w(FALSE);
94         }
95         else
96         {
97            m_vsp->rsq_w(TRUE);
98            m_vsp->wsq_w(FALSE);
99         }
100      }
140101   }
102   else
103   {
104      // If other address, turn off RS* and WS* (negative logic!)
105      m_vsp->rsq_w(TRUE);
106      m_vsp->wsq_w(TRUE);
107      return;
108   }
141109}
142#endif
143110
144111/****************************************************************************/
145112
r25469r25470
151118   m_slot->set_ready((state==0)? ASSERT_LINE : CLEAR_LINE);
152119   if (VERBOSE>5) LOG("spchsyn: READY = %d\n", (state==0));
153120
154#if REAL_TIMING
155   // Need to do that here (see explanations above)
156   if (state==0)
121   if ((state==0) && !m_read_mode)
157122   {
123      // Clear the lines only when we are done with writing.
158124      m_vsp->rsq_w(TRUE);
159125      m_vsp->wsq_w(TRUE);
160126   }
161#endif
162127}
163128
164129void ti_speech_synthesizer_device::device_start()
r25469r25470
172137
173138void ti_speech_synthesizer_device::device_reset()
174139{
140   if (VERBOSE>5) LOG("spchsyn: reset\n");
175141   if (m_genmod)
176142   {
177143      m_select_mask = 0x1ffc01;
r25469r25470
182148      m_select_mask = 0x7fc01;
183149      m_select_value = 0x79000;
184150   }
151   m_read_mode = false;
185152}
186153
187154MACHINE_CONFIG_FRAGMENT( ti99_speech )
trunk/src/mess/drivers/tm990189.c
r25469r25470
824824   DEVCB_NULL,     // Instruction acquisition
825825   DEVCB_NULL,     // Clock out
826826   DEVCB_NULL,     // wait
827   DEVCB_NULL      // Hold acknowledge
827   DEVCB_NULL,      // Hold acknowledge
828   DEVCB_NULL      // DBIN
828829};
829830
830831static MACHINE_CONFIG_START( tm990_189, tm990189_state )
trunk/src/mess/drivers/ti99_8.c
r25469r25470
215215#include "machine/ti99/gromport.h"
216216#include "machine/ti99/joyport.h"
217217
218#define VERBOSE 0
218#define VERBOSE 1
219219#define LOG logerror
220220
221221class ti99_8_state : public driver_device
r25469r25470
630630WRITE_LINE_MEMBER( ti99_8_state::CRUS )
631631{
632632   m_mapper->CRUS_set(state==ASSERT_LINE);
633   if (state==ASSERT_LINE)
634   {
635      m_gromport->set_grom_base(0x9800, 0xfbf1);
636   }
637   else
638   {
639      m_gromport->set_grom_base(0xf830, 0xfff1);
640   }
633641}
634642
635643/*
r25469r25470
795803   DEVCB_DRIVER_MEMBER(ti99_8_state, external_operation),
796804   DEVCB_NULL,     // Instruction acquisition
797805   DEVCB_DRIVER_LINE_MEMBER(ti99_8_state, clock_out),
798   DEVCB_NULL,     // wait
799806   DEVCB_NULL,     // HOLDA
807   DEVCB_NULL,      // DBIN
800808   NO_INTERNAL_RAM,
801809   NO_OVERFLOW_INT
802810};
r25469r25470
962970
963971   // But we assert the line here so that the system starts running
964972   m_ready_line = m_ready_line1 = ASSERT_LINE;
973   m_gromport->set_grom_base(0x9800, 0xfff1);
965974}
966975
967976static MACHINE_CONFIG_START( ti99_8_60hz, ti99_8_state )
trunk/src/mess/drivers/geneve.c
r25469r25470
240240   DECLARE_WRITE_LINE_MEMBER(video_wait_states);
241241
242242   DECLARE_WRITE_LINE_MEMBER(clock_out);
243   DECLARE_WRITE_LINE_MEMBER(dbin_line);
244
243245   DECLARE_WRITE8_MEMBER(external_operation);
244246
245247   DECLARE_WRITE8_MEMBER(tms9901_interrupt);
r25469r25470
284286*/
285287
286288static ADDRESS_MAP_START(memmap, AS_PROGRAM, 8, geneve_state)
287   AM_RANGE(0x0000, 0xffff) AM_DEVREADWRITE(GMAPPER_TAG, geneve_mapper_device, readm, writem)
289   AM_RANGE(0x0000, 0xffff) AM_DEVREADWRITE(GMAPPER_TAG, geneve_mapper_device, readm, writem) AM_DEVSETOFFSET(GMAPPER_TAG, geneve_mapper_device, setoffset)
288290ADDRESS_MAP_END
289291
290292/*
r25469r25470
604606
605607WRITE_LINE_MEMBER( geneve_state::ext_ready )
606608{
607   if (VERBOSE>6) LOG("ti99_8: READY level (ext) =%02x\n", state);
609   if (VERBOSE>6) LOG("geneve: READY level (ext) = %02x\n", state);
608610   m_ready_line = state;
609611   m_cpu->set_ready((m_ready_line == ASSERT_LINE && m_ready_line1 == ASSERT_LINE)? ASSERT_LINE : CLEAR_LINE);
610612}
r25469r25470
670672   m_mapper->clock_in(state);
671673}
672674
675/*
676    DBIN line from the CPU. Used to control wait state generation.
677*/
678WRITE_LINE_MEMBER( geneve_state::dbin_line )
679{
680   m_mapper->dbin(state);
681}
682
673683static TMS9995_CONFIG( geneve_processor_config )
674684{
675685   DEVCB_DRIVER_MEMBER(geneve_state, external_operation),
676686   DEVCB_NULL,         // Instruction acquisition
677687   DEVCB_DRIVER_LINE_MEMBER(geneve_state, clock_out),
678   DEVCB_NULL,         // wait
679688   DEVCB_NULL,         // HOLDA
689   DEVCB_DRIVER_LINE_MEMBER(geneve_state, dbin_line),      // DBIN
680690   INTERNAL_RAM,       // use internal RAM
681691   NO_OVERFLOW_INT     // The generally available versions of TMS9995 have a deactivated overflow interrupt
682692};
trunk/src/mess/drivers/ti99_4x.c
r25469r25470
8989   DECLARE_READ8_MEMBER( interrupt_level );
9090   DECLARE_READ_LINE_MEMBER( ready_connect );
9191   DECLARE_WRITE_LINE_MEMBER( clock_out );
92   DECLARE_WRITE_LINE_MEMBER( dbin_line );
9293
9394   DECLARE_INPUT_CHANGED_MEMBER( load_interrupt );
9495   TIMER_DEVICE_CALLBACK_MEMBER(ti99_4ev_hblank_interrupt);
r25469r25470
601602   m_datamux->clock_in(state);
602603}
603604
605/*
606   Data bus in (DBIN) line from the CPU.
607*/
608WRITE_LINE_MEMBER( ti99_4x_state::dbin_line )
609{
610   m_datamux->dbin_in(state);
611}
612
604613/*****************************************************************************/
605614
606615/*
r25469r25470
822831   DEVCB_NULL,     // Instruction acquisition
823832   DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, clock_out),
824833   DEVCB_NULL,     // wait
825   DEVCB_NULL      // Hold acknowledge
834   DEVCB_NULL,      // Hold acknowledge
835   DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, dbin_line)      // data bus in
826836};
827837
828838static JOYPORT_CONFIG( joyport4_60 )

Previous 199869 Revisions Next


© 1997-2024 The MAME Team