Previous 199869 Revisions Next

r23717 Saturday 15th June, 2013 at 11:53:20 UTC by Fabio Priuli
(MESS) NES input cleanup, part 4 (Simplified NES input reads and fixed Arkanoid paddle
emulation which has been broken for long time, probably more than 6 years). nw.
[src/mess/drivers]nes.c
[src/mess/includes]nes.h
[src/mess/machine]nes.c

trunk/src/mess/machine/nes.c
r23716r23717
4848   m_in_1.shift = 0;
4949
5050   m_maincpu->reset();
51
52   memset(m_pad_latch, 0, sizeof(m_pad_latch));
53   memset(m_zapper_latch, 0, sizeof(m_zapper_latch));
54   m_paddle_latch = 0;
55   m_paddle_btn_latch = 0;
5156}
5257
5358static void nes_state_register( running_machine &machine )
r23716r23717
7176
7277   if (state->m_disk_expansion)
7378      state->save_pointer(NAME(state->m_vram), 0x800);
79
80   state->save_item(NAME(state->m_pad_latch));
81   state->save_item(NAME(state->m_zapper_latch));
82   state->save_item(NAME(state->m_paddle_latch));
83   state->save_item(NAME(state->m_paddle_btn_latch));
7484}
7585
7686
r23716r23717
104114   m_io_ctrlsel        = ioport("CTRLSEL");
105115   m_io_exp            = ioport("EXP");
106116   m_io_paddle         = ioport("PADDLE");
117   m_io_paddle_btn     = ioport("PADDLE_BUTTON");
107118   m_io_cc_left        = ioport("CC_LEFT");
108119   m_io_cc_right       = ioport("CC_RIGHT");
109120   m_io_zapper1_t      = ioport("ZAPPER1_T");
r23716r23717
200211READ8_MEMBER(nes_state::nes_in0_r)
201212{
202213   int cfg = m_io_ctrlsel->read();
203   /* Some games expect bit 6 to be set because the last entry on the data bus shows up */
204   /* in the unused upper 3 bits, so typically a read from $4016 leaves 0x40 there. */
205   UINT8 ret = 0x40;
206   ret |= ((m_in_0.i0 >> m_in_0.shift) & 0x01);
207214
208   /* zapper */
215   // Some games expect bit 6 to be set because the last entry on the data bus shows up
216   // in the unused upper 3 bits, so typically a read from $4016 leaves 0x40 there.
217   UINT8 ret = 0x40;
218   ret |= (m_pad_latch[0] & 0x01);
219   
220   // shift
221   m_pad_latch[0] >>= 1;
222   
223   // zapper
209224   if ((cfg & 0x000f) == 0x0002)
210225   {
211      int x = m_in_0.i1;  /* read Zapper x-position */
212      int y = m_in_0.i2;  /* read Zapper y-position */
226      int x = m_zapper_latch[0][1];  // x-position
227      int y = m_zapper_latch[0][2];  // y-position
213228      UINT32 pix, color_base;
214229
215      /* get the pixel at the gun position */
230      // get the pixel at the gun position
216231      pix = m_ppu->get_pixel(x, y);
217232
218      /* get the color base from the ppu */
233      // get the color base from the ppu
219234      color_base = m_ppu->get_colorbase();
220235
221      /* look at the screen and see if the cursor is over a bright pixel */
236      // check if the cursor is over a bright pixel
222237      if ((pix == color_base + 0x20) || (pix == color_base + 0x30) ||
223238         (pix == color_base + 0x33) || (pix == color_base + 0x34))
224      {
225         ret &= ~0x08; /* sprite hit */
226      }
239         ret &= ~0x08; // sprite hit
227240      else
228         ret |= 0x08;  /* no sprite hit */
241         ret |= 0x08;  // no sprite hit
229242
230      /* If button 1 is pressed, indicate the light gun trigger is pressed */
231      ret |= ((m_in_0.i0 & 0x01) << 4);
243      // light gun trigger
244      ret |= (m_zapper_latch[0][0] << 4);
232245   }
233246
234247   if (LOG_JOY)
235248      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);
236249
237   m_in_0.shift++;
238
239250   return ret;
240251}
241252
242253READ8_MEMBER(nes_state::nes_in1_r)
243254{
244255   int cfg = m_io_ctrlsel->read();
245   /* Some games expect bit 6 to be set because the last entry on the data bus shows up */
246   /* in the unused upper 3 bits, so typically a read from $4017 leaves 0x40 there. */
256
257   // Some games expect bit 6 to be set because the last entry on the data bus shows up
258   // in the unused upper 3 bits, so typically a read from $4017 leaves 0x40 there.
247259   UINT8 ret = 0x40;
248   ret |= ((m_in_1.i0 >> m_in_1.shift) & 0x01);
260   ret |= (m_pad_latch[1] & 0x01);
249261
250   /* zapper */
262   // shift
263   m_pad_latch[1] >>= 1;
264   
265   // zapper
251266   if ((cfg & 0x00f0) == 0x0020)
252267   {
253      int x = m_in_1.i1;  /* read Zapper x-position */
254      int y = m_in_1.i2;  /* read Zapper y-position */
268      int x = m_zapper_latch[1][1];  // x-position
269      int y = m_zapper_latch[1][2];  // y-position
255270      UINT32 pix, color_base;
256271     
257      /* get the pixel at the gun position */
272      // get the pixel at the gun position
258273      pix = m_ppu->get_pixel(x, y);
259274     
260      /* get the color base from the ppu */
275      // get the color base from the ppu
261276      color_base = m_ppu->get_colorbase();
262277     
263      /* look at the screen and see if the cursor is over a bright pixel */
278      // check if the cursor is over a bright pixel
264279      if ((pix == color_base + 0x20) || (pix == color_base + 0x30) ||
265280         (pix == color_base + 0x33) || (pix == color_base + 0x34))
266      {
267         ret &= ~0x08; /* sprite hit */
268      }
281         ret &= ~0x08; // sprite hit
269282      else
270         ret |= 0x08;  /* no sprite hit */
283         ret |= 0x08;  // no sprite hit
271284     
272      /* If button 1 is pressed, indicate the light gun trigger is pressed */
273      ret |= ((m_in_1.i0 & 0x01) << 4);
285      // light gun trigger
286      ret |= (m_zapper_latch[1][0] << 4);
274287   }
275288
276   /* arkanoid dial */
289   // arkanoid paddle
277290   if ((cfg & 0x00f0) == 0x0040)
278291   {
279      /* Handle data line 2's serial output */
280      ret |= ((m_in_1.i2 >> m_in_1.shift) & 0x01) << 3;
281
282      /* Handle data line 3's serial output - bits are reversed */
283      /* NPW 27-Nov-2007 - there is no third subscript! commenting out */
284      /* ret |= ((m_in_1[3] >> m_in_1.shift) & 0x01) << 4; */
285      /* ret |= ((m_in_1[3] << m_in_1.shift) & 0x80) >> 3; */
292      ret |= (m_paddle_btn_latch << 3);   // button
293      ret |= ((m_paddle_latch & 0x80) >> 3);      // paddle data
294      m_paddle_latch <<= 1;
295      m_paddle_latch &= 0xff;
286296   }
287297
288298   if (LOG_JOY)
289299      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);
290300
291   m_in_1.shift++;
292
293301   return ret;
294302}
295303
r23716r23717
297305{
298306   int cfg = m_io_ctrlsel->read();
299307
300   /* Check if lightgun has been chosen as input: if so, enable crosshair */
308   // Check if lightgun has been chosen as input: if so, enable crosshair
301309   timer_set(attotime::zero, TIMER_ZAPPER_TICK);
302310
303   // check 'standard' inputs
304311   if (data & 0x01)
305312      return;
313
314   // Toggling bit 0 high then low resets controllers
315   m_pad_latch[0] = 0;
316   m_pad_latch[1] = 0;
317   m_zapper_latch[0][0] = 0;   
318   m_zapper_latch[0][1] = 0;   
319   m_zapper_latch[0][2] = 0;   
320   m_zapper_latch[1][0] = 0;   
321   m_zapper_latch[1][1] = 0;   
322   m_zapper_latch[1][2] = 0;   
323   m_paddle_latch = 0;
306324   
307   if (LOG_JOY)
308      logerror("joy 0 bits read: %d\n", m_in_0.shift);
309   
310   /* Toggling bit 0 high then low resets both controllers */
311   m_in_0.shift = 0;
312   m_in_1.shift = 0;
313   m_in_0.i0 = 0;
314   m_in_0.i1 = 0;
315   m_in_0.i2 = 0;
316   m_in_1.i0 = 0;
317   m_in_1.i1 = 0;
318   m_in_1.i2 = 0;
319   m_in_2.i0 = 0;
320   m_in_2.i1 = 0;
321   m_in_2.i2 = 0;
322   m_in_3.i0 = 0;
323   m_in_3.i1 = 0;
324   m_in_3.i2 = 0;
325   
326325   // P1 inputs
327326   switch (cfg & 0x000f)
328327   {
329      case 0x01:  /* gamepad */
330         m_in_0.i0 = m_io_pad[0]->read();
328      case 0x01:  // pad 1
329         m_pad_latch[0] = m_io_pad[0]->read();
331330         break;
332331         
333      case 0x02:  /* zapper 1 */
334         m_in_0.i0 = m_io_zapper1_t->read();
335         m_in_0.i1 = m_io_zapper1_x->read();
336         m_in_0.i2 = m_io_zapper1_y->read();
332      case 0x02:  // zapper (secondary)
333         m_zapper_latch[0][0] = m_io_zapper1_t->read();
334         m_zapper_latch[0][1] = m_io_zapper1_x->read();
335         m_zapper_latch[0][2] = m_io_zapper1_y->read();
337336         break;
338337   }
339338   
340339   // P2 inputs
341340   switch ((cfg & 0x00f0) >> 4)
342341   {
343      case 0x01:  /* gamepad */
344         m_in_1.i0 = m_io_pad[1]->read();
342      case 0x01:  // pad 2
343         m_pad_latch[1] = m_io_pad[1]->read();
345344         break;
346345         
347      case 0x02:  /* zapper 2 */
348         m_in_1.i0 = m_io_zapper2_t->read();
349         m_in_1.i1 = m_io_zapper2_x->read();
350         m_in_1.i2 = m_io_zapper2_y->read();
346      case 0x02:  // zapper (primary) - most games expect pad in port1 & zapper in port2
347         m_zapper_latch[1][0] = m_io_zapper2_t->read();
348         m_zapper_latch[1][1] = m_io_zapper2_x->read();
349         m_zapper_latch[1][2] = m_io_zapper2_y->read();
351350         break;
352351         
353      case 0x04:  /* arkanoid paddle */
354         m_in_1.i0 = (UINT8) ((UINT8) m_io_paddle->read() + (UINT8)0x52) ^ 0xff;
352      case 0x04:  // arkanoid paddle
353         m_paddle_btn_latch = m_io_paddle_btn->read();
354         m_paddle_latch = (UINT8) (m_io_paddle->read() ^ 0xff);
355355         break;
356356   }
357357   
358358   // P3 inputs
359359   if ((cfg & 0x0f00))
360      m_in_2.i0 = m_io_pad[2]->read();
360      m_pad_latch[0] |= ((m_io_pad[2]->read() << 8) | (0x08 << 16));     // pad 3 + signature
361361   
362362   // P4 inputs
363   if ((cfg & 0x0f00))
364      m_in_3.i0 = m_io_pad[3]->read();
365   
366   if (cfg & 0x0f00)
367      m_in_0.i0 |= (m_in_2.i0 << 8) | (0x08 << 16);
368   
369   if (cfg & 0xf000)
370      m_in_1.i0 |= (m_in_3.i0 << 8) | (0x04 << 16);
371   
363   if ((cfg & 0xf000))
364      m_pad_latch[1] |= ((m_io_pad[3]->read() << 8) | (0x04 << 16));     // pad 4 + signature   
372365}
373366
374367
trunk/src/mess/includes/nes.h
r23716r23717
484484   ioport_port       *m_io_zapper2_x;
485485   ioport_port       *m_io_zapper2_y;
486486   ioport_port       *m_io_paddle;
487   ioport_port       *m_io_paddle_btn;
487488   ioport_port       *m_io_exp;
488489
489490   UINT8      *m_vram;
r23716r23717
553554   DECLARE_DEVICE_IMAGE_UNLOAD_MEMBER(nes_disk);
554555
555556   void fds_irq(int scanline, int vblank, int blanked);
557   
558   UINT8 m_pad_latch[4];
559   UINT8 m_zapper_latch[2][3];
560   UINT8 m_paddle_latch, m_paddle_btn_latch;
556561
557562protected:
558563   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
trunk/src/mess/drivers/nes.c
r23716r23717
110110   PORT_START("ZAPPER1_Y")  /* P1 zapper */
111111   PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(30) PORT_MINMAX(0,255) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0002)
112112   PORT_START("ZAPPER1_T")  /* P1 zapper trigger */
113   PORT_BIT( 0x03, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("P1 Lightgun Trigger") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0002)
113   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("P1 Lightgun Trigger") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0002)
114114INPUT_PORTS_END
115115
116116static INPUT_PORTS_START( nes_zapper2 )
r23716r23717
119119   PORT_START("ZAPPER2_Y")  /* P2 zapper */
120120   PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(30) PORT_MINMAX(0,255 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0020)
121121   PORT_START("ZAPPER2_T")  /* P2 zapper trigger */
122   PORT_BIT( 0x03, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("P2 Lightgun Trigger") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0020)
122   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("P2 Lightgun Trigger") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0020)
123123INPUT_PORTS_END
124124
125125static INPUT_PORTS_START( nes_paddle )
126126   PORT_START("PADDLE")  /* Arkanoid paddle */
127   PORT_BIT( 0xff, 0x7f, IPT_PADDLE) PORT_SENSITIVITY(25) PORT_KEYDELTA(3) PORT_MINMAX(0x62,0xf2) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0040)
127   PORT_BIT( 0xff, 0x7f, IPT_PADDLE) PORT_SENSITIVITY(25) PORT_KEYDELTA(25) PORT_CENTERDELTA(0) PORT_MINMAX(0x62,0xf2) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0040)
128   PORT_START("PADDLE_BUTTON")  /* Arkanoid paddle button */
129   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Paddle button") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0040)
128130INPUT_PORTS_END
129131
130132static INPUT_PORTS_START( nes )

Previous 199869 Revisions Next


© 1997-2024 The MAME Team