Previous 199869 Revisions Next

r23697 Friday 14th June, 2013 at 07:54:51 UTC by Fabio Priuli
(MESS) NES input cleanup, part 1. nw.
[src/mess/machine]nes.c

trunk/src/mess/machine/nes.c
r23696r23697
211211READ8_MEMBER(nes_state::nes_IN0_r)
212212{
213213   int cfg = m_io_ctrlsel->read();
214   int ret;
215
216   if ((cfg & 0x000f) >= 0x08) // for now we treat the FC keyboard separately from other inputs!
214   /* Some games expect bit 6 to be set because the last entry on the data bus shows up */
215   /* in the unused upper 3 bits, so typically a read from $4016 leaves 0x40 there. */
216   UINT8 ret = 0x40;
217   
218   if ((cfg & 0x000f) >= 0x08)
217219   {
218220      // here we should have the tape input
219      ret = 0;
221      ret |= 0;
220222   }
221   else
222   {
223      /* Some games expect bit 6 to be set because the last entry on the data bus shows up */
224      /* in the unused upper 3 bits, so typically a read from $4016 leaves 0x40 there. */
225      ret = 0x40;
226223
227      ret |= ((m_in_0.i0 >> m_in_0.shift) & 0x01);
224   ret |= ((m_in_0.i0 >> m_in_0.shift) & 0x01);
228225
229      /* zapper */
230      if ((cfg & 0x000f) == 0x0002)
231      {
232         int x = m_in_0.i1;  /* read Zapper x-position */
233         int y = m_in_0.i2;  /* read Zapper y-position */
234         UINT32 pix, color_base;
226   /* zapper */
227   if ((cfg & 0x000f) == 0x0002)
228   {
229      int x = m_in_0.i1;  /* read Zapper x-position */
230      int y = m_in_0.i2;  /* read Zapper y-position */
231      UINT32 pix, color_base;
235232
236         /* get the pixel at the gun position */
237         pix = m_ppu->get_pixel(x, y);
233      /* get the pixel at the gun position */
234      pix = m_ppu->get_pixel(x, y);
238235
239         /* get the color base from the ppu */
240         color_base = m_ppu->get_colorbase();
236      /* get the color base from the ppu */
237      color_base = m_ppu->get_colorbase();
241238
242         /* look at the screen and see if the cursor is over a bright pixel */
243         if ((pix == color_base + 0x20) || (pix == color_base + 0x30) ||
244            (pix == color_base + 0x33) || (pix == color_base + 0x34))
245         {
246            ret &= ~0x08; /* sprite hit */
247         }
248         else
249            ret |= 0x08;  /* no sprite hit */
250
251         /* If button 1 is pressed, indicate the light gun trigger is pressed */
252         ret |= ((m_in_0.i0 & 0x01) << 4);
239      /* look at the screen and see if the cursor is over a bright pixel */
240      if ((pix == color_base + 0x20) || (pix == color_base + 0x30) ||
241         (pix == color_base + 0x33) || (pix == color_base + 0x34))
242      {
243         ret &= ~0x08; /* sprite hit */
253244      }
245      else
246         ret |= 0x08;  /* no sprite hit */
254247
255      if (LOG_JOY)
256         logerror("joy 0 read, val: %02x, pc: %04x, bits read: %d, chan0: %08x\n", ret, space.device().safe_pc(), m_in_0.shift, m_in_0.i0);
257
258      m_in_0.shift++;
248      /* If button 1 is pressed, indicate the light gun trigger is pressed */
249      ret |= ((m_in_0.i0 & 0x01) << 4);
259250   }
260251
252   if (LOG_JOY)
253      logerror("joy 0 read, val: %02x, pc: %04x, bits read: %d, chan0: %08x\n", ret, space.device().safe_pc(), m_in_0.shift, m_in_0.i0);
254
255   m_in_0.shift++;
256
261257   return ret;
262258}
263259
264260READ8_MEMBER(nes_state::nes_IN1_r)
265261{
266262   int cfg = m_io_ctrlsel->read();
267   int ret;
268
263   /* Some games expect bit 6 to be set because the last entry on the data bus shows up */
264   /* in the unused upper 3 bits, so typically a read from $4017 leaves 0x40 there. */
265   UINT8 ret = 0x40;
266   
269267   // row of the keyboard matrix are read 4-bits at time, and gets returned as bit1->bit4
270268   if ((cfg & 0x000f) == 0x08) // for now we treat the FC keyboard separately from other inputs!
271269   {
272270      if (m_fck_scan < 9)
273         ret = ~(((m_io_fckey[m_fck_scan]->read() >> (m_fck_mode * 4)) & 0x0f) << 1) & 0x1e;
271         ret |= ~(((m_io_fckey[m_fck_scan]->read() >> (m_fck_mode * 4)) & 0x0f) << 1) & 0x1e;
274272      else
275         ret = 0x1e;
273         ret |= 0x1e;
276274   }
277   else if ((cfg & 0x000f) == 0x09)    // for now we treat the Subor keyboard separately from other inputs!
275   
276   if ((cfg & 0x000f) == 0x09)    // for now we treat the Subor keyboard separately from other inputs!
278277   {
279278      if (m_fck_scan < 12)
280         ret = ~(((m_io_subkey[m_fck_scan]->read() >> (m_fck_mode * 4)) & 0x0f) << 1) & 0x1e;
279         ret |= ~(((m_io_subkey[m_fck_scan]->read() >> (m_fck_mode * 4)) & 0x0f) << 1) & 0x1e;
281280      else
282         ret = 0x1e;
281         ret |= 0x1e;
283282   }
283
284   /* Handle data line 0's serial output */
285   if ((cfg & 0x00f0) == 0x0070)
286      ret |= (((m_in_1.i0 >> m_in_1.shift) & 0x01) << 1);
284287   else
285   {
286      /* Some games expect bit 6 to be set because the last entry on the data bus shows up */
287      /* in the unused upper 3 bits, so typically a read from $4017 leaves 0x40 there. */
288      ret = 0x40;
288      ret |= ((m_in_1.i0 >> m_in_1.shift) & 0x01);
289289
290      /* Handle data line 0's serial output */
291      if((cfg & 0x00f0) == 0x0070)
292         ret |= (((m_in_1.i0 >> m_in_1.shift) & 0x01) << 1);
293      else
294         ret |= ((m_in_1.i0 >> m_in_1.shift) & 0x01);
295
296      /* zapper */
297      if ((cfg & 0x00f0) == 0x0030)
290   /* zapper */
291   if ((cfg & 0x00f0) == 0x0030)
292   {
293      int x = m_in_1.i1;  /* read Zapper x-position */
294      int y = m_in_1.i2;  /* read Zapper y-position */
295      UINT32 pix, color_base;
296     
297      /* get the pixel at the gun position */
298      pix = m_ppu->get_pixel(x, y);
299     
300      /* get the color base from the ppu */
301      color_base = m_ppu->get_colorbase();
302     
303      /* look at the screen and see if the cursor is over a bright pixel */
304      if ((pix == color_base + 0x20) || (pix == color_base + 0x30) ||
305         (pix == color_base + 0x33) || (pix == color_base + 0x34))
298306      {
299         int x = m_in_1.i1;  /* read Zapper x-position */
300         int y = m_in_1.i2;  /* read Zapper y-position */
301         UINT32 pix, color_base;
302
303         /* get the pixel at the gun position */
304         pix = m_ppu->get_pixel(x, y);
305
306         /* get the color base from the ppu */
307         color_base = m_ppu->get_colorbase();
308
309         /* look at the screen and see if the cursor is over a bright pixel */
310         if ((pix == color_base + 0x20) || (pix == color_base + 0x30) ||
311            (pix == color_base + 0x33) || (pix == color_base + 0x34))
312         {
313            ret &= ~0x08; /* sprite hit */
314         }
315         else
316            ret |= 0x08;  /* no sprite hit */
317
318         /* If button 1 is pressed, indicate the light gun trigger is pressed */
319         ret |= ((m_in_1.i0 & 0x01) << 4);
307         ret &= ~0x08; /* sprite hit */
320308      }
321
322      /* arkanoid dial */
323      else if ((cfg & 0x00f0) == 0x0040)
324      {
325         /* Handle data line 2's serial output */
326         ret |= ((m_in_1.i2 >> m_in_1.shift) & 0x01) << 3;
327
328         /* Handle data line 3's serial output - bits are reversed */
329         /* NPW 27-Nov-2007 - there is no third subscript! commenting out */
330         /* ret |= ((m_in_1[3] >> m_in_1.shift) & 0x01) << 4; */
331         /* ret |= ((m_in_1[3] << m_in_1.shift) & 0x80) >> 3; */
332      }
333
334      if (LOG_JOY)
335         logerror("joy 1 read, val: %02x, pc: %04x, bits read: %d, chan0: %08x\n", ret, space.device().safe_pc(), m_in_1.shift, m_in_1.i0);
336
337      m_in_1.shift++;
309      else
310         ret |= 0x08;  /* no sprite hit */
311     
312      /* If button 1 is pressed, indicate the light gun trigger is pressed */
313      ret |= ((m_in_1.i0 & 0x01) << 4);
338314   }
339315
340   return ret;
341}
342
343
344// FIXME: this is getting messier and messier (no pun intended). inputs reading should be simplified and port_categories cleaned up
345// to also emulate the fact that nothing should be in Port 2 if there is a Crazy Climber pad, etc.
346static void nes_read_input_device( running_machine &machine, int cfg, nes_input *vals, int pad_port, int supports_zapper, int mux_data )
347{
348   nes_state *state = machine.driver_data<nes_state>();
349
350   vals->i0 = 0;
351   vals->i1 = 0;
352   vals->i2 = 0;
353
354   switch (cfg & 0x0f)
316   /* arkanoid dial */
317   if ((cfg & 0x00f0) == 0x0040)
355318   {
356      case 0x01:  /* gamepad */
357         if (pad_port >= 0)
358            vals->i0 = state->m_io_pad[pad_port]->read();
359         break;
319      /* Handle data line 2's serial output */
320      ret |= ((m_in_1.i2 >> m_in_1.shift) & 0x01) << 3;
360321
361      case 0x02:  /* zapper 1 */
362         if (supports_zapper)
363         {
364            vals->i0 = state->m_io_zapper1_t->read();
365            vals->i1 = state->m_io_zapper1_x->read();
366            vals->i2 = state->m_io_zapper1_y->read();
367         }
368         break;
322      /* Handle data line 3's serial output - bits are reversed */
323      /* NPW 27-Nov-2007 - there is no third subscript! commenting out */
324      /* ret |= ((m_in_1[3] >> m_in_1.shift) & 0x01) << 4; */
325      /* ret |= ((m_in_1[3] << m_in_1.shift) & 0x80) >> 3; */
326   }
369327
370      case 0x03:  /* zapper 2 */
371         if (supports_zapper)
372         {
373            vals->i0 = state->m_io_zapper2_t->read();
374            vals->i1 = state->m_io_zapper2_x->read();
375            vals->i2 = state->m_io_zapper2_y->read();
376         }
377         break;
328   if (LOG_JOY)
329      logerror("joy 1 read, val: %02x, pc: %04x, bits read: %d, chan0: %08x\n", ret, space.device().safe_pc(), m_in_1.shift, m_in_1.i0);
378330
379      case 0x04:  /* arkanoid paddle */
380         if (pad_port == 1)
381            vals->i0 = (UINT8) ((UINT8) state->m_io_paddle->read() + (UINT8)0x52) ^ 0xff;
382         break;
331   m_in_1.shift++;
383332
384      case 0x06:  /* crazy climber controller */
385         if (pad_port == 0)
386         {
387            state->m_in_0.i0 = state->m_io_cc_left->read();
388            state->m_in_1.i0 = state->m_io_cc_right->read();
389         }
390         break;
391
392      case 0x07: /* Mahjong Panel */
393         if(mux_data & 0xf8)
394            logerror("Error: Mahjong panel read with mux data %02x\n",mux_data);
395         else
396            vals->i0 = state->m_io_mahjong[mux_data >> 1]->read();
397         break;
398   }
333   return ret;
399334}
400335
401336
r23696r23697
444379   /* Check if lightgun has been chosen as input: if so, enable crosshair */
445380   timer_set(attotime::zero, TIMER_LIGHTGUN_TICK);
446381
447   if ((cfg & 0x000f) >= 0x08) // for now we treat the FC keyboard separately from other inputs!
382   if ((cfg & 0x000f) >= 0x08)
448383   {
449384      // here we should also have the tape output
450385
451386      if (BIT(data, 2))   // keyboard active
452387      {
453         int lines = ((cfg & 0x000f) == 0x04) ? 9 : 12;
388         int lines = ((cfg & 0x000f) == 0x08) ? 9 : 12;
454389         UINT8 out = BIT(data, 1);   // scan
455390
456391         if (m_fck_mode && !out && ++m_fck_scan > lines)
r23696r23697
462397            m_fck_scan = 0;
463398      }
464399   }
465   else
466   {
467      if (data & 0x01)
468         return;
469400
470      if (LOG_JOY)
471         logerror("joy 0 bits read: %d\n", m_in_0.shift);
472
473      /* Toggling bit 0 high then low resets both controllers */
474      m_in_0.shift = 0;
475      m_in_1.shift = 0;
476
477      /* Read the input devices */
478      if ((cfg & 0x000f) != 0x06)
479      {
480         nes_read_input_device(machine(), cfg >>  0, &m_in_0, 0,  TRUE,data & 0xfe);
481         nes_read_input_device(machine(), cfg >>  4, &m_in_1, 1,  TRUE,data & 0xfe);
482         nes_read_input_device(machine(), cfg >>  8, &m_in_2, 2, FALSE,data & 0xfe);
483         nes_read_input_device(machine(), cfg >> 12, &m_in_3, 3, FALSE,data & 0xfe);
484      }
485      else // crazy climber pad
486      {
487         nes_read_input_device(machine(), 0, &m_in_1, 1,  TRUE,data & 0xfe);
488         nes_read_input_device(machine(), 0, &m_in_2, 2, FALSE,data & 0xfe);
489         nes_read_input_device(machine(), 0, &m_in_3, 3, FALSE,data & 0xfe);
490         nes_read_input_device(machine(), cfg >>  0, &m_in_0, 0,  TRUE,data & 0xfe);
491      }
492
493      if (cfg & 0x0f00)
494         m_in_0.i0 |= (m_in_2.i0 << 8) | (0x08 << 16);
495
496      if (cfg & 0xf000)
497         m_in_1.i0 |= (m_in_3.i0 << 8) | (0x04 << 16);
401   // check 'standard' inputs
402   if (data & 0x01)
403      return;
404   
405   if (LOG_JOY)
406      logerror("joy 0 bits read: %d\n", m_in_0.shift);
407   
408   /* Toggling bit 0 high then low resets both controllers */
409   m_in_0.shift = 0;
410   m_in_1.shift = 0;
411   m_in_0.i0 = 0;
412   m_in_0.i1 = 0;
413   m_in_0.i2 = 0;
414   m_in_1.i0 = 0;
415   m_in_1.i1 = 0;
416   m_in_1.i2 = 0;
417   m_in_2.i0 = 0;
418   m_in_2.i1 = 0;
419   m_in_2.i2 = 0;
420   m_in_3.i0 = 0;
421   m_in_3.i1 = 0;
422   m_in_3.i2 = 0;
423   
424   // P1 inputs
425   switch (cfg & 0x000f)
426   {
427      case 0x01:  /* gamepad */
428         m_in_0.i0 = m_io_pad[0]->read();
429         break;
430         
431      case 0x02:  /* zapper 1 */
432         m_in_0.i0 = m_io_zapper1_t->read();
433         m_in_0.i1 = m_io_zapper1_x->read();
434         m_in_0.i2 = m_io_zapper1_y->read();
435         break;
436         
437      case 0x06:  /* crazy climber controller */
438         m_in_0.i0 = m_io_cc_left->read();
439         m_in_1.i0 = m_io_cc_right->read();
440         break;
498441   }
442   
443   // P2 inputs
444   switch ((cfg & 0x00f0) >> 4)
445   {
446      case 0x01:  /* gamepad */
447         m_in_1.i0 = m_io_pad[1]->read();
448         break;
449         
450      case 0x03:  /* zapper 2 */
451         m_in_1.i0 = m_io_zapper2_t->read();
452         m_in_1.i1 = m_io_zapper2_x->read();
453         m_in_1.i2 = m_io_zapper2_y->read();
454         break;
455         
456      case 0x04:  /* arkanoid paddle */
457         m_in_1.i0 = (UINT8) ((UINT8) m_io_paddle->read() + (UINT8)0x52) ^ 0xff;
458         break;
459         
460      case 0x07: /* Mahjong Panel */
461         if (data & 0xf8)
462            logerror("Error: Mahjong panel read with mux data %02x\n", (data & 0xfe));
463         else
464            m_in_1.i0 = m_io_mahjong[(data & 0xfe) >> 1]->read();
465         break;
466   }
467   
468   // P3 inputs
469   if ((cfg & 0x0f00))
470      m_in_2.i0 = m_io_pad[2]->read();
471   
472   // P4 inputs
473   if ((cfg & 0x0f00))
474      m_in_3.i0 = m_io_pad[3]->read();
475   
476   if (cfg & 0x0f00)
477      m_in_0.i0 |= (m_in_2.i0 << 8) | (0x08 << 16);
478   
479   if (cfg & 0xf000)
480      m_in_1.i0 |= (m_in_3.i0 << 8) | (0x04 << 16);
481   
499482}
500483
501484

Previous 199869 Revisions Next


© 1997-2024 The MAME Team