Previous 199869 Revisions Next

r32908 Thursday 23rd October, 2014 at 17:28:06 UTC by smf
renamed psx controller and memory card files, renamed znsec to cat702. (nw)
[src/emu/bus]bus.mak
[src/emu/bus/psx]analogue.c* analogue.h* ctlrport.c* ctlrport.h* memcard.c* memcard.h* multitap.c* multitap.h*
[src/mame]mame.mak
[src/mame/drivers]taitogn.c zn.c
[src/mame/machine]cat702.c* cat702.h* znsec.c znsec.h
[src/mess]mess.mak
[src/mess/drivers]psx.c
[src/mess/machine]psxanalog.c psxanalog.h psxcard.c psxcard.h psxcport.c psxcport.h psxmultitap.c psxmultitap.h

trunk/src/emu/bus/bus.mak
r241419r241420
14631463BUSOBJS += $(BUSOBJ)/wswan/rom.o
14641464endif
14651465
1466#-------------------------------------------------
1467#
1468#@src/emu/bus/psx/ctlrport.h,BUSES += PSX_CONTROLLER
1469#-------------------------------------------------
1470
1471ifneq ($(filter PSX_CONTROLLER,$(BUSES)),)
1472OBJDIRS += $(BUSOBJ)/psx
1473BUSOBJS += $(BUSOBJ)/psx/ctlrport.o
1474BUSOBJS += $(BUSOBJ)/psx/analogue.o
1475BUSOBJS += $(BUSOBJ)/psx/multitap.o
1476BUSOBJS += $(BUSOBJ)/psx/memcard.o
1477endif
trunk/src/emu/bus/psx/analogue.c
r0r241420
1#include "analogue.h"
2
3const device_type PSX_ANALOG_JOYSTICK = &device_creator<psx_analog_joystick_device>;
4const device_type PSX_DUALSHOCK = &device_creator<psx_dualshock_device>;
5
6psx_analog_controller_device::psx_analog_controller_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) :
7      device_t(mconfig, type, name, tag, owner, clock, shortname, source),
8      device_psx_controller_interface(mconfig, *this),
9      m_pad0(*this, "PSXPAD0"),
10      m_pad1(*this, "PSXPAD1"),
11      m_rstickx(*this, "PSXRSTICKX"),
12      m_rsticky(*this, "PSXRSTICKY"),
13      m_lstickx(*this, "PSXLSTICKX"),
14      m_lsticky(*this, "PSXLSTICKY")
15{
16}
17
18psx_dualshock_device::psx_dualshock_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
19      psx_analog_controller_device(mconfig, PSX_DUALSHOCK, "Playstation Dualshock Pad", tag, owner, clock, "psx_dualshock_pad", __FILE__)
20{
21   m_type = DUALSHOCK;
22}
23
24psx_analog_joystick_device::psx_analog_joystick_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
25      psx_analog_controller_device(mconfig, PSX_ANALOG_JOYSTICK, "Playstation Analog Joystick", tag, owner, clock, "psx_analog_joystick", __FILE__)
26{
27   m_type = JOYSTICK;
28}
29
30void psx_analog_controller_device::device_reset()
31{
32   m_confmode = false;
33   m_analogmode = false;
34   m_analoglock = false;
35
36   m_cmd = 0;
37}
38
39UINT8 psx_analog_controller_device::pad_data(int count, bool analog)
40{
41   UINT8 data = 0;
42   switch(count)
43   {
44      case 2:
45         data = m_pad0->read();
46         if(!analog || (m_type == JOYSTICK))
47            data |= 6; // l3/r3
48         break;
49      case 3:
50         data = m_pad1->read();
51         break;
52      case 4:
53         data = m_rstickx->read();
54         break;
55      case 5:
56         data = m_rsticky->read();
57         break;
58      case 6:
59         data = m_lstickx->read();
60         break;
61      case 7:
62         data = m_lsticky->read();
63         break;
64   }
65   return data;
66}
67
68bool psx_analog_controller_device::get_pad(int count, UINT8 *odata, UINT8 idata)
69{
70   if(m_confmode)
71   {
72      switch(count)
73      {
74         case 0:
75            m_temp = 0;
76            *odata = 0xf3;
77            break;
78         case 1:
79            m_cmd = idata;
80            if((m_cmd & 0xf0) != 0x40)
81               return false;
82            *odata = 0x5a;
83            break;
84         default:
85            switch(m_cmd)
86            {
87               default: // 40,41,48,49,4a,4b,4f -- all unknown
88                  *odata = 0x00;
89                  break;
90               case CONFIG_MODE: // 43
91                  if(count == 3)
92                     m_temp = idata;
93                  /* no break */
94               case QUERY_PAD_STATE: // 42
95                  *odata = pad_data(count, true);
96                  break;
97               case 0x44: // set mode and lock ?
98                  switch(count)
99                  {
100                     case 3:
101                        m_analogmode = idata ? true : false; // only 0x01 ?
102                        break;
103                     case 4:
104                        m_analoglock = idata ? true : false; // only 0x03 ?
105                        break;
106                  }
107                  *odata = 0x00;
108                  break;
109               case 0x45: // get mode ?
110               {
111                  const UINT8 val[] = { 1, 2, 0, 2, 1, 0 };
112                  if(count == 4)
113                     *odata = m_analogmode;
114                  else
115                     *odata = val[count-2];
116                  break;
117               }
118               case 0x46: // query act (vibrate) ?
119               {
120                  const UINT8 val[2][6] = {{ 0, 0, 1, 2, 0, 10 },
121                                    { 0, 0, 1, 1, 1, 14 }};
122                  *odata = val[m_temp][count-2];
123                  if(count == 3)
124                     m_temp = idata ? 1 : 0;
125                  break;
126               }
127               case 0x47: // query comb (combination?) ?
128               {
129                  const UINT8 val[] = { 0, 0, 2, 0, 1, 0 };
130                  *odata = val[count-2];
131                  break;
132               }
133               case 0x4c: // query mode ?
134                  switch(count)
135                  {
136                     case 3:
137                        m_temp = idata;
138                        /* no break */
139                     default:
140                        *odata = 0x00;
141                        break;
142                     case 5:
143                        *odata = m_analogmode ? 0x07 : 0x04; // ?
144                        break;
145                  }
146                  break;
147               case 0x4d: // set act (vibrate) ?
148                  *odata = 0xff;
149                  break;
150            }
151            break;
152         case 8:
153            if(m_cmd == CONFIG_MODE)
154               m_confmode = m_temp;
155            return false;
156      }
157   }
158   else if(m_analogmode)
159   {
160      switch(count)
161      {
162         case 0:
163            if(m_type == JOYSTICK)
164               *odata = 0x53;
165            else
166               *odata = 0x73;
167            break;
168         case 1:
169            m_cmd = idata;
170            if((m_cmd & 0xfe) != QUERY_PAD_STATE)
171               return false;
172            *odata = 0x5a;
173            break;
174         case 3:
175            if(m_cmd == CONFIG_MODE)
176               m_temp = idata;
177            /* no break */
178         default:
179            *odata = pad_data(count, true);
180            break;
181         case 8:
182            if(m_cmd == CONFIG_MODE)
183               m_confmode = m_temp;
184            return false;
185      }
186   }
187   else
188   {
189      switch(count)
190      {
191         case 0:
192            *odata = 0x41;
193            break;
194         case 1:
195            m_cmd = idata;
196            if((m_cmd & 0xfe) != QUERY_PAD_STATE)
197               return false;
198            *odata = 0x5a;
199            break;
200         case 3:
201            if(m_cmd == CONFIG_MODE)
202               m_temp = idata;
203            /* no break */
204         default:
205            *odata = pad_data(count, false);
206            break;
207         case 4:
208            if(m_cmd == CONFIG_MODE)
209               m_confmode = m_temp;
210            return false;
211      }
212   }
213   return true;
214}
215
216static INPUT_PORTS_START( psx_analog_controller )
217   PORT_START("PSXPAD0")
218   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
219   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
220   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
221   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP )
222   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START )
223   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON9 ) PORT_NAME("R3")
224   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON10 ) PORT_NAME("L3")
225   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SELECT )
226
227   PORT_START("PSXPAD1")
228   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Square")
229   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Cross")
230   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Circle")
231   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Triangle")
232   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("R1")
233   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("L1")
234   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("R2")
235   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("L2")
236
237   PORT_START("PSXRSTICKX")
238   PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_NAME("Right Analog X") PORT_SENSITIVITY(100)
239
240   PORT_START("PSXRSTICKY")
241   PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_NAME("Right Analog Y") PORT_SENSITIVITY(100)
242
243   PORT_START("PSXLSTICKX")
244   PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Z ) PORT_NAME("Left Analog X") PORT_SENSITIVITY(100)
245
246   PORT_START("PSXLSTICKY")
247   PORT_BIT( 0xff, 0x80, IPT_PADDLE ) PORT_NAME("Left Analog Y") PORT_SENSITIVITY(100)
248
249   PORT_START("PSXMISC")
250   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON11 ) PORT_NAME("Analog") PORT_TOGGLE PORT_CHANGED_MEMBER(DEVICE_SELF, psx_analog_controller_device, change_mode, 0)
251INPUT_PORTS_END
252
253ioport_constructor psx_analog_controller_device::device_input_ports() const
254{
255   return INPUT_PORTS_NAME(psx_analog_controller);
256}
257
258INPUT_CHANGED_MEMBER(psx_analog_controller_device::change_mode)
259{
260   if(!m_analoglock)
261      m_analogmode = newval;
262}
trunk/src/emu/bus/psx/analogue.h
r0r241420
1#ifndef PSXANALOG_H_
2#define PSXANALOG_H_
3
4#include "ctlrport.h"
5
6extern const device_type PSX_DUALSHOCK;
7extern const device_type PSX_ANALOG_JOYSTICK;
8
9class psx_analog_controller_device :    public device_t,
10                              public device_psx_controller_interface
11{
12public:
13   psx_analog_controller_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);
14
15   virtual ioport_constructor device_input_ports() const;
16   DECLARE_INPUT_CHANGED_MEMBER(change_mode);
17protected:
18   virtual void device_reset();
19   virtual void device_start() {}
20   enum {
21      JOYSTICK,
22      DUALSHOCK
23   } m_type;
24private:
25   virtual bool get_pad(int count, UINT8 *odata, UINT8 idata);
26   UINT8 pad_data(int count, bool analog);
27
28   bool m_confmode;
29   bool m_analogmode;
30   bool m_analoglock;
31
32   UINT8 m_temp;
33   UINT8 m_cmd;
34
35   required_ioport m_pad0;
36   required_ioport m_pad1;
37   required_ioport m_rstickx;
38   required_ioport m_rsticky;
39   required_ioport m_lstickx;
40   required_ioport m_lsticky;
41};
42
43class psx_dualshock_device : public psx_analog_controller_device
44{
45public:
46   psx_dualshock_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
47};
48
49class psx_analog_joystick_device : public psx_analog_controller_device
50{
51public:
52   psx_analog_joystick_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
53};
54
55#endif /* PSXANALOG_H_ */
trunk/src/emu/bus/psx/ctlrport.c
r0r241420
1/* PAD emulation */
2
3#include "ctlrport.h"
4#include "analogue.h"
5#include "multitap.h"
6
7const device_type PSX_CONTROLLER_PORT = &device_creator<psx_controller_port_device>;
8
9psx_controller_port_device::psx_controller_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
10      device_t(mconfig, PSX_CONTROLLER_PORT, "Playstation Controller Port", tag, owner, clock, "psx_controller_port", __FILE__),
11      device_slot_interface(mconfig, *this),
12      m_card(*this, "card")
13{
14}
15
16void psx_controller_port_device::device_config_complete()
17{
18   m_dev = dynamic_cast<device_psx_controller_interface *>(get_card_device());
19}
20
21static MACHINE_CONFIG_FRAGMENT( psx_memory_card )
22   MCFG_PSXCARD_ADD("card")
23MACHINE_CONFIG_END
24
25machine_config_constructor psx_controller_port_device::device_mconfig_additions() const
26{
27   return MACHINE_CONFIG_NAME( psx_memory_card );
28}
29
30void psx_controller_port_device::disable_card(bool state)
31{
32   if(state)
33      popmessage("Memory card port %s is disabled\n", m_card->brief_instance_name());
34
35   m_card->disable(state);
36}
37
38const device_type PSXCONTROLLERPORTS = &device_creator<psxcontrollerports_device>;
39
40psxcontrollerports_device::psxcontrollerports_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
41      psxsiodev_device(mconfig, PSXCONTROLLERPORTS, "PSXCONTROLLERPORTS", tag, owner, clock, "psxcontrollerports", __FILE__)
42{
43}
44
45void psxcontrollerports_device::device_start()
46{
47   m_port0 = machine().device<psx_controller_port_device>("port1");
48   m_port1 = machine().device<psx_controller_port_device>("port2");
49   m_port0->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psxcontrollerports_device::ack), this));
50   m_port1->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psxcontrollerports_device::ack), this));
51   psxsiodev_device::device_start();
52}
53
54// add controllers to define so they can be connected to the multitap
55#define PSX_CONTROLLERS \
56      SLOT_INTERFACE("digital_pad", PSX_STANDARD_CONTROLLER) \
57      SLOT_INTERFACE("dualshock_pad", PSX_DUALSHOCK) \
58      SLOT_INTERFACE("analog_joystick", PSX_ANALOG_JOYSTICK)
59
60SLOT_INTERFACE_START(psx_controllers)
61   PSX_CONTROLLERS
62   SLOT_INTERFACE("multitap", PSX_MULTITAP)
63SLOT_INTERFACE_END
64
65SLOT_INTERFACE_START(psx_controllers_nomulti)
66   PSX_CONTROLLERS
67SLOT_INTERFACE_END
68
69void psxcontrollerports_device::data_in( int data, int mask )
70{
71   m_port0->sel_w((data & PSX_SIO_OUT_DTR)?1:0);
72   m_port0->tx_w((data & PSX_SIO_OUT_DATA)?1:0);
73   m_port0->clock_w((data & PSX_SIO_OUT_CLOCK)?1:0); // clock must be last
74
75   m_port1->tx_w((data & PSX_SIO_OUT_DATA)?1:0);
76   m_port1->sel_w((data & PSX_SIO_OUT_DTR)?0:1); // not dtr
77   m_port1->clock_w((data & PSX_SIO_OUT_CLOCK)?1:0);
78
79   data_out(((m_port0->rx_r() && m_port1->rx_r()) * PSX_SIO_IN_DATA), PSX_SIO_IN_DATA);
80}
81
82void psxcontrollerports_device::ack()
83{
84   data_out((!(m_port0->ack_r() && m_port1->ack_r()) * PSX_SIO_IN_DSR), PSX_SIO_IN_DSR);
85}
86
87device_psx_controller_interface::device_psx_controller_interface(const machine_config &mconfig, device_t &device) :
88      device_slot_card_interface(mconfig, device),
89      m_ack(true)
90{
91}
92
93device_psx_controller_interface::~device_psx_controller_interface()
94{
95}
96
97void device_psx_controller_interface::interface_pre_reset()
98{
99   m_bit = 0;
100   m_count = 0;
101   m_idata = 0;
102   m_memcard = false;
103
104   m_clock = true;
105   m_sel = true;
106   m_rx = true;
107   m_ack = true;
108   m_owner->ack();
109}
110
111void device_psx_controller_interface::interface_pre_start()
112{
113   m_owner = dynamic_cast<psx_controller_port_device *>(device().owner());
114   m_ack_timer = device().machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(device_psx_controller_interface::ack_timer), this));
115}
116
117void device_psx_controller_interface::ack_timer(void *ptr, int param)
118{
119   m_ack = param;
120   m_owner->ack();
121
122   if(!param)
123      m_ack_timer->adjust(attotime::from_usec(2), 1);
124}
125
126void device_psx_controller_interface::do_pad()
127{
128   if(!m_bit)
129   {
130      if(!m_count)
131         m_odata = 0xff;
132      m_idata = 0;
133   }
134
135   m_rx = (m_odata & (1 << m_bit)) ? true : false;
136   m_idata |= (m_owner->tx_r()?1:0) << m_bit;
137   m_bit = (m_bit + 1) % 8;
138
139   if(!m_bit)
140   {
141      if((!m_count) && (m_idata & 0xf0))
142      {
143            m_memcard = true;
144            return;
145      }
146
147      if(get_pad(m_count++, &m_odata, m_idata))
148         m_ack_timer->adjust(attotime::from_usec(10), 0);
149      else
150         m_count = 0;
151   }
152}
153
154void device_psx_controller_interface::sel_w(bool state) {
155   if(state && !m_sel)
156      interface_pre_reset(); // don't reset the controller, just the interface
157   m_sel = state;
158}
159
160const device_type PSX_STANDARD_CONTROLLER = &device_creator<psx_standard_controller_device>;
161
162psx_standard_controller_device::psx_standard_controller_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
163      device_t(mconfig, PSX_STANDARD_CONTROLLER, "Playstation Standard Controller", tag, owner, clock, "psx_standard_controller", __FILE__),
164      device_psx_controller_interface(mconfig, *this),
165      m_pad0(*this,"PSXPAD0"),
166      m_pad1(*this,"PSXPAD1")
167{
168}
169
170bool psx_standard_controller_device::get_pad(int count, UINT8 *odata, UINT8 idata)
171{
172   switch(count)
173   {
174      case 0:
175         *odata = 0x41;
176         break;
177      case 1:
178         if(idata != QUERY_PAD_STATE)
179            return false;
180         *odata = 0x5a;
181         break;
182      case 2:
183         *odata = m_pad0->read();
184         break;
185      case 3:
186         *odata = m_pad1->read();
187         break;
188      case 4:
189         return false;
190   }
191   return true;
192}
193
194static INPUT_PORTS_START( psx_standard_controller )
195   PORT_START("PSXPAD0")
196   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
197   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
198   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
199   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP )
200   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START )
201   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
202   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
203   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SELECT )
204
205   PORT_START("PSXPAD1")
206   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Square")
207   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Cross")
208   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Circle")
209   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Triangle")
210   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("R1")
211   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("L1")
212   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("R2")
213   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("L2")
214INPUT_PORTS_END
215
216ioport_constructor psx_standard_controller_device::device_input_ports() const
217{
218   return INPUT_PORTS_NAME(psx_standard_controller);
219}
trunk/src/emu/bus/psx/ctlrport.h
r0r241420
1#pragma once
2
3#ifndef __PSXCPORT_H__
4#define __PSXCPORT_H__
5
6#include "cpu/psx/siodev.h"
7#include "memcard.h"
8
9#define MCFG_PSX_CTRL_PORT_ADD(_tag, _slot_intf, _def_slot) \
10   MCFG_DEVICE_ADD(_tag, PSX_CONTROLLER_PORT, 0) \
11   MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
12
13SLOT_INTERFACE_EXTERN(psx_controllers);
14
15extern const device_type PSXCONTROLLERPORTS;
16extern const device_type PSX_CONTROLLER_PORT;
17extern const device_type PSX_STANDARD_CONTROLLER;
18
19class psx_controller_port_device;
20
21class device_psx_controller_interface : public device_slot_card_interface
22{
23   friend class psx_multitap_device;
24public:
25   device_psx_controller_interface(const machine_config &mconfig, device_t &device);
26   virtual ~device_psx_controller_interface();
27
28   void clock_w(bool state) { if(m_clock && !m_sel && !state && !m_memcard) do_pad(); m_clock = state; }
29   void sel_w(bool state);
30
31   bool rx_r() { return m_rx; }
32   bool ack_r() { return m_ack; }
33
34protected:
35   virtual void interface_pre_reset();
36   virtual void interface_pre_start();
37
38   enum
39   {
40      QUERY_PAD_STATE = 0x42,
41      CONFIG_MODE = 0x43,
42   };
43
44private:
45   virtual bool get_pad(int count, UINT8 *odata, UINT8 idata) = 0;
46   virtual void do_pad();
47   void ack_timer(void *ptr, int param);
48
49   UINT8 m_odata;
50   UINT8 m_idata;
51   int m_bit;
52   int m_count;
53   bool m_memcard;
54
55   bool m_clock;
56   bool m_sel;
57   bool m_ack;
58   bool m_rx;
59
60   emu_timer *m_ack_timer;
61   psx_controller_port_device *m_owner;
62};
63
64class psx_standard_controller_device :  public device_t,
65                              public device_psx_controller_interface
66{
67public:
68   psx_standard_controller_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
69
70   virtual ioport_constructor device_input_ports() const;
71
72protected:
73   virtual void device_start() { }
74private:
75   virtual bool get_pad(int count, UINT8 *odata, UINT8 idata);
76
77   required_ioport m_pad0;
78   required_ioport m_pad1;
79};
80
81class psxcontrollerports_device : public psxsiodev_device
82{
83public:
84   psxcontrollerports_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
85   void ack();
86
87protected:
88   virtual void device_start();
89
90private:
91   virtual void data_in(int data, int mask);
92
93   psx_controller_port_device *m_port0;
94   psx_controller_port_device *m_port1;
95};
96
97class psx_controller_port_device :  public device_t,
98                           public device_slot_interface
99{
100public:
101   psx_controller_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
102   virtual machine_config_constructor device_mconfig_additions() const;
103
104   typedef delegate<void ()> void_cb;
105   void ack() { if(!ack_cb.isnull()) ack_cb(); }
106   void setup_ack_cb(void_cb cb) { ack_cb = cb; }
107
108   DECLARE_WRITE_LINE_MEMBER(tx_w) { m_tx = state; }
109   DECLARE_WRITE_LINE_MEMBER(sel_w) { if(m_dev) m_dev->sel_w(state); m_card->sel_w(state); }
110   DECLARE_WRITE_LINE_MEMBER(clock_w) { if(m_dev) m_dev->clock_w(state); m_card->clock_w(state); }
111
112   DECLARE_READ_LINE_MEMBER(rx_r) { return (m_dev?m_dev->rx_r():true) && m_card->rx_r(); }
113   DECLARE_READ_LINE_MEMBER(ack_r) { return (m_dev?m_dev->ack_r():true) && m_card->ack_r(); }
114   DECLARE_READ_LINE_MEMBER(tx_r) { return m_tx; }
115
116   void disable_card(bool status);
117
118protected:
119   virtual void device_start() {}
120   virtual void device_reset() { m_tx = true; }
121   virtual void device_config_complete();
122
123private:
124   void_cb ack_cb;
125   bool m_tx;
126
127   device_psx_controller_interface *m_dev;
128   required_device<psxcard_device> m_card;
129};
130#endif
trunk/src/emu/bus/psx/memcard.c
r0r241420
1/*
2    psxcard.c - Sony PlayStation memory card device
3
4    by pSXAuthor
5    MESS conversion by R. Belmont
6*/
7
8#include "emu.h"
9#include "memcard.h"
10#include "ctlrport.h"
11
12//
13//
14//
15
16//#define debug_card
17
18//
19//
20//
21
22static const int block_size = 128;
23static const int card_size = block_size * 1024;
24
25const device_type PSXCARD = &device_creator<psxcard_device>;
26
27enum transfer_states
28{
29   state_illegal=0,
30   state_command,
31   state_cmdack,
32   state_wait,
33   state_addr_hi,
34   state_addr_lo,
35   state_read,
36   state_write,
37   state_writeack_2,
38   state_writechk,
39   state_end
40};
41
42psxcard_device::psxcard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
43   : device_t(mconfig, PSXCARD, "Sony PSX Memory Card", tag, owner, clock, "psxcard", __FILE__),
44   device_image_interface(mconfig, *this)
45{
46}
47
48void psxcard_device::device_start()
49{
50   m_owner = dynamic_cast<psx_controller_port_device *>(owner());
51   m_ack_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(psxcard_device::ack_timer), this));
52
53   m_ack = true;
54   m_disabled = false;
55
56   // save state registrations
57   save_item(NAME(pkt));
58   save_item(NAME(pkt_ptr));
59   save_item(NAME(pkt_sz));
60   save_item(NAME(cmd));
61   save_item(NAME(addr));
62   save_item(NAME(state));
63   save_item(NAME(m_disabled));
64   save_item(NAME(m_odata));
65   save_item(NAME(m_idata));
66   save_item(NAME(m_bit));
67   save_item(NAME(m_count));
68   save_item(NAME(m_pad));
69}
70
71void psxcard_device::device_reset()
72{
73   state = state_illegal;
74   addr = 0;
75
76   m_bit = 0;
77   m_count = 0;
78   m_pad = false;
79   m_idata = 0;
80
81   m_clock = true;
82   m_sel = true;
83   m_rx = true;
84   m_ack = true;
85   m_owner->ack();
86}
87
88void psxcard_device::device_config_complete()
89{
90   update_names(PSXCARD, "memcard", "mc");
91}
92
93//
94//
95//
96
97bool psxcard_device::transfer(UINT8 to, UINT8 *from)
98{
99   bool ret=true;
100
101   switch (state)
102   {
103      case state_illegal:
104         if (is_loaded())
105         {
106//              printf("CARD: begin\n");
107            state = state_command;
108            *from = 0x00;
109         }
110         else
111         {
112            ret = false;
113         }
114         break;
115
116      case state_command:
117         cmd=to;
118         *from=0x5a;
119         state=state_cmdack;
120         break;
121
122      case state_cmdack:
123         *from=0x5d;
124         state=state_wait;
125         break;
126
127      case state_wait:
128         *from=0x00;
129         state=state_addr_hi;
130         break;
131
132      case state_addr_hi:
133         addr=(to<<8);
134//          printf("addr_hi: %02x, addr = %x\n", to, addr);
135         *from=to;
136         state=state_addr_lo;
137         break;
138
139      case state_addr_lo:
140         addr|=(to&0xff);
141//          printf("addr_lo: %02x, addr = %x, cmd = %x\n", to, addr, cmd);
142
143         switch (cmd)
144         {
145            case 'R':   // 0x52
146            {
147               pkt[0]=*from=0x5c;
148               pkt[1]=0x5d;
149               pkt[2]=(addr>>8);
150               pkt[3]=(addr&0xff);
151               read_card(addr,&pkt[4]);
152               pkt[4+128]=checksum_data(&pkt[2],128+2);
153               pkt[5+128]=0x47;
154               pkt_sz=6+128;
155               pkt_ptr=1;
156               state=state_read;
157               break;
158            }
159            case 'W':   // 0x57
160            {
161               pkt[0]=addr>>8;
162               pkt[1]=addr&0xff;
163               pkt_sz=129+2;
164               pkt_ptr=2;
165               state=state_write;
166               *from=to;
167               break;
168            }
169            default:
170               state=state_illegal;
171               break;
172         }
173         break;
174
175      case state_read:
176         //assert(to==0);
177//          printf("state_read: pkt_ptr = %d, pkt_sz = %d\n", pkt_ptr, pkt_sz);
178         *from=pkt[pkt_ptr++];
179         if (pkt_ptr==pkt_sz)
180         {
181            #ifdef debug_card
182               printf("card: read finished\n");
183            #endif
184
185            state=state_end;
186         }
187         break;
188
189      case state_write:
190         *from=to;
191         pkt[pkt_ptr++]=to;
192         if (pkt_ptr==pkt_sz)
193         {
194            *from=0x5c;
195            state=state_writeack_2;
196         }
197         break;
198
199      case state_writeack_2:
200         *from=0x5d;
201         state=state_writechk;
202         break;
203
204      case state_writechk:
205      {
206         unsigned char chk=checksum_data(pkt,128+2);
207         if (chk==pkt[128+2])
208         {
209            #ifdef debug_card
210               printf("card: write ok\n");
211            #endif
212
213            write_card(addr,pkt+2);
214
215            *from='G';
216         } else
217         {
218            #ifdef debug_card
219               printf("card: write fail\n");
220            #endif
221
222            *from='N';
223         }
224         state=state_end;
225         break;
226      }
227
228      case state_end:
229         ret = false;
230         state = state_illegal;
231         break;
232
233      default: /*assert(0);*/ ret=false; break;
234   }
235
236   #ifdef debug_card
237//      printf("card: transfer to=%02x from=%02x ret=%c\n",to,*from,ret ? 'T' : 'F');
238   #endif
239
240   return ret;
241}
242
243void psxcard_device::read_card(const unsigned short addr, unsigned char *buf)
244{
245   #ifdef debug_card
246      printf("card: read block %d\n",addr);
247   #endif
248
249   if (addr<(card_size/block_size))
250   {
251      fseek(addr*block_size, SEEK_SET);
252      fread(buf, block_size);
253   } else
254   {
255      memset(buf,0,block_size);
256   }
257}
258
259//
260//
261//
262
263void psxcard_device::write_card(const unsigned short addr, unsigned char *buf)
264{
265   #ifdef debug_card
266      printf("card: write block %d\n",addr);
267   #endif
268
269   if (addr<(card_size/block_size))
270   {
271      fseek(addr*block_size, SEEK_SET);
272      fwrite(buf, block_size);
273   }
274}
275
276unsigned char psxcard_device::checksum_data(const unsigned char *buf, const unsigned int sz)
277{
278   unsigned char chk=*buf++;
279   int left=sz;
280   while (--left) chk^=*buf++;
281   return chk;
282}
283
284bool psxcard_device::call_load()
285{
286   if(m_disabled)
287   {
288      logerror("psxcard: port disabled\n");
289      return IMAGE_INIT_FAIL;
290   }
291
292   if(length() != card_size)
293      return IMAGE_INIT_FAIL;
294   return IMAGE_INIT_PASS;
295}
296
297bool psxcard_device::call_create(int format_type, option_resolution *format_options)
298{
299   UINT8 block[block_size];
300   int i, ret;
301
302   if(m_disabled)
303   {
304      logerror("psxcard: port disabled\n");
305      return IMAGE_INIT_FAIL;
306   }
307
308   memset(block, '\0', block_size);
309   for(i = 0; i < (card_size/block_size); i++)
310   {
311      ret = fwrite(block, block_size);
312      if(ret != block_size)
313         return IMAGE_INIT_FAIL;
314   }
315   return IMAGE_INIT_PASS;
316}
317
318void psxcard_device::do_card()
319{
320   if(!m_bit)
321   {
322      m_idata = 0;
323      if(!m_count)
324         m_odata = 0xff;
325   }
326
327   m_rx = (m_odata & (1 << m_bit)) ? true : false;
328   m_idata |= (m_owner->tx_r()?1:0) << m_bit;
329   m_bit = (m_bit + 1) % 8;
330
331   if(!m_bit)
332   {
333      if((!m_count) && !(m_idata & 0x80))
334      {
335         m_pad = true;
336         return;
337      }
338
339      if(transfer(m_idata, &m_odata))
340      {
341         m_count++;
342         m_ack_timer->adjust(attotime::from_usec(10), 0);
343      }
344      else
345         m_count = 0;
346   }
347}
348
349void psxcard_device::ack_timer(void *ptr, int param)
350{
351   m_ack = param;
352   m_owner->ack();
353
354   if(!param)
355      m_ack_timer->adjust(attotime::from_usec(2), 1);
356}
357
358void psxcard_device::sel_w(bool state)
359{
360   if(state && !m_sel)
361      reset();
362   m_sel = state;
363}
trunk/src/emu/bus/psx/memcard.h
r0r241420
1#pragma once
2
3#ifndef _PSXCARD_
4#define _PSXCARD_
5
6#include "emu.h"
7
8class psx_controller_port_device;
9
10#define MCFG_PSXCARD_ADD(_tag) \
11   MCFG_DEVICE_ADD(_tag, PSXCARD, 0)
12
13class psxcard_device :  public device_t,
14                  public device_image_interface
15{
16public:
17   psxcard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
18
19   virtual iodevice_t image_type() const { return IO_MEMCARD; }
20
21   virtual bool is_readable()  const { return 1; }
22   virtual bool is_writeable() const { return 1; }
23   virtual bool is_creatable() const { return 1; }
24   virtual bool must_be_loaded() const { return 0; }
25   virtual bool is_reset_on_load() const { return 0; }
26   virtual const char *file_extensions() const { return "mc"; }
27   virtual const option_guide *create_option_guide() const { return NULL; }
28
29   virtual bool call_load();
30   virtual bool call_create(int format_type, option_resolution *format_options);
31
32   void disable(bool state) { m_disabled = state; if(state) unload(); }
33
34private:
35   unsigned char pkt[0x8b], pkt_ptr, pkt_sz, cmd;
36   unsigned short addr;
37   int state;
38   bool m_disabled;
39
40   UINT8 m_odata;
41   UINT8 m_idata;
42   int m_bit;
43   int m_count;
44   bool m_pad;
45
46   bool m_clock;
47   bool m_sel;
48   bool m_ack;
49   bool m_rx;
50
51   emu_timer *m_ack_timer;
52   psx_controller_port_device *m_owner;
53
54   void read_card(const unsigned short addr, unsigned char *buf);
55   void write_card(const unsigned short addr, unsigned char *buf);
56   unsigned char checksum_data(const unsigned char *buf, const unsigned int sz);
57   void do_card();
58   bool transfer(UINT8 to, UINT8 *from);
59   void ack_timer(void *ptr, int param);
60
61public:
62   virtual void device_start();
63   virtual void device_reset();
64   virtual void device_config_complete();
65
66   void clock_w(bool state) { if(m_clock && !m_sel && !state && !m_pad) do_card(); m_clock = state; }
67   void sel_w(bool state);
68   bool rx_r() { return m_rx; }
69   bool ack_r() { return m_ack; }
70};
71
72// device type definition
73extern const device_type PSXCARD;
74
75#endif
trunk/src/emu/bus/psx/multitap.c
r0r241420
1// psx multitap emulation
2
3#include "multitap.h"
4
5const device_type PSX_MULTITAP = &device_creator<psx_multitap_device>;
6
7psx_multitap_device::psx_multitap_device(const machine_config& mconfig, const char* tag, device_t* owner, UINT32 clock) :
8   device_t(mconfig, PSX_MULTITAP, "Playstation Multitap", tag, owner, clock, "psx_multitap", __FILE__),
9   device_psx_controller_interface(mconfig, *this),
10   m_porta(*this, "a"),
11   m_portb(*this, "b"),
12   m_portc(*this, "c"),
13   m_portd(*this, "d")
14{
15}
16
17static MACHINE_CONFIG_FRAGMENT( psx_multitap )
18   MCFG_PSX_CTRL_PORT_ADD("a", psx_controllers_nomulti, "digital_pad")
19   MCFG_PSX_CTRL_PORT_ADD("b", psx_controllers_nomulti, NULL)
20   MCFG_PSX_CTRL_PORT_ADD("c", psx_controllers_nomulti, NULL)
21   MCFG_PSX_CTRL_PORT_ADD("d", psx_controllers_nomulti, NULL)
22MACHINE_CONFIG_END
23
24machine_config_constructor psx_multitap_device::device_mconfig_additions() const
25{
26   return MACHINE_CONFIG_NAME( psx_multitap );
27}
28
29void psx_multitap_device::device_start()
30{
31   m_porta->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psx_multitap_device::ack), this));
32   m_portb->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psx_multitap_device::ack), this));
33   m_portc->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psx_multitap_device::ack), this));
34   m_portd->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psx_multitap_device::ack), this));
35   m_nextmode = false;
36
37   save_item(NAME(m_activeport));
38   save_item(NAME(m_cack));
39   save_item(NAME(m_singlemode));
40   save_item(NAME(m_nextmode));
41   save_item(NAME(m_tapmc));
42   save_item(NAME(m_data));
43}
44
45void psx_multitap_device::interface_pre_reset()
46{
47   m_activeport = -1;
48   m_singlemode = m_nextmode;
49   m_tapmc = false;
50   m_cack[0] = m_cack[1] = m_cack[2] = m_cack[3] = true;
51   memset(m_data, 0xff, sizeof(m_data));
52   m_porta->sel_w(false);
53   m_portb->sel_w(false);
54   m_portc->sel_w(false);
55   m_portd->sel_w(false);
56   m_porta->sel_w(true);
57   m_portb->sel_w(true);
58   m_portc->sel_w(true);
59   m_portd->sel_w(true);
60   device_psx_controller_interface::interface_pre_reset();
61}
62
63void psx_multitap_device::set_tx_line(bool tx, int port)
64{
65   psx_controller_port_device *dev;
66   switch(port)
67   {
68      default:
69      case 0:
70         dev = m_porta;
71         break;
72      case 1:
73         dev = m_portb;
74         break;
75      case 2:
76         dev = m_portc;
77         break;
78      case 3:
79         dev = m_portd;
80         break;
81   }
82   dev->clock_w(1);
83   dev->tx_w(tx);
84   dev->clock_w(0);
85}
86
87bool psx_multitap_device::get_rx_line(int port)
88{
89   psx_controller_port_device *dev;
90   switch(port)
91   {
92      default:
93      case 0:
94         dev = m_porta;
95         break;
96      case 1:
97         dev = m_portb;
98         break;
99      case 2:
100         dev = m_portc;
101         break;
102      case 3:
103         dev = m_portd;
104         break;
105   }
106   return dev->rx_r();
107}
108
109void psx_multitap_device::do_pad()
110{
111   bool tx = device_psx_controller_interface::m_owner->tx_r();
112
113   // we don't know which controller until after the first byte
114   if((m_singlemode || m_tapmc) && (m_count >= 1))
115   {
116      if((m_count == 2) && !m_bit && !m_tapmc)
117         m_nextmode = !tx;
118
119      set_tx_line(tx, m_activeport);
120      m_rx = get_rx_line(m_activeport);
121      m_bit = (m_bit + 1) % 8;
122      if(!m_bit)
123         m_count++;
124      return;
125   }
126
127   if(!m_count)
128   {
129      // first send the select byte to all devices until we know whether it's accessing
130      // a controller or memcard
131      if(!m_bit)
132      {
133         m_porta->sel_w(false);
134         m_portb->sel_w(false);
135         m_portc->sel_w(false);
136         m_portd->sel_w(false);
137      }
138      device_psx_controller_interface::do_pad();
139      set_tx_line(tx, 0);
140      set_tx_line(tx, 1);
141      set_tx_line(tx, 2);
142      set_tx_line(tx, 3);
143      if(!m_bit)
144      {
145         m_count = 1;
146         m_tapmc = m_memcard;
147         m_memcard = false; // make sure we still receive clocks
148         if(m_singlemode || m_tapmc)
149         {
150            m_activeport = (m_idata & 0xf) - 1;
151            m_porta->sel_w((m_activeport == 0) ? false : true);
152            m_portb->sel_w((m_activeport == 1) ? false : true);
153            m_portc->sel_w((m_activeport == 2) ? false : true);
154            m_portd->sel_w((m_activeport == 3) ? false : true);
155         }
156      }
157      return;
158   }
159   else if(m_count <= 2)
160      return device_psx_controller_interface::do_pad();
161   else if(m_count < 11)
162   {
163      if((m_count == 3) && !m_bit)
164         m_nextmode = !m_idata;
165
166      if((m_count < 5) && m_cack[0] && m_cack[1] && m_cack[2] && m_cack[3])
167         return; // no acks? hang up.
168
169      // all of the ports are polled here, port a is passed though.  the data
170      // from the other ports is stored and can be retrieved at a much higher clock rate
171      // don't poll a port that is inactive or done
172      if(!m_cack[0])
173      {
174         set_tx_line(tx, 0);
175         m_rx = m_porta->rx_r();
176      }
177      else
178      {
179         m_rx = true;
180         m_porta->sel_w(true);
181      }
182
183      if(!m_cack[1])
184      {
185         set_tx_line(tx, 1);
186         m_data[0][m_count - 3] &= ~(!m_portb->rx_r() << m_bit);
187      }
188      else
189         m_portb->sel_w(true);
190
191      if(!m_cack[2])
192      {
193         set_tx_line(tx, 2);
194         m_data[1][m_count - 3] &= ~(!m_portc->rx_r() << m_bit);
195      }
196      else
197         m_portc->sel_w(true);
198
199      if(!m_cack[3])
200      {
201         set_tx_line(tx, 3);
202         m_data[2][m_count - 3] &= ~(!m_portd->rx_r() << m_bit);
203      }
204      else
205         m_portd->sel_w(true);
206   }
207   else if(m_count < 19)
208      // send stored port b data
209      m_rx = ((m_data[0][m_count - 11] & (1 << m_bit)) ? 1 : 0);
210   else if(m_count < 27)
211      // send stored port c data
212      m_rx = ((m_data[1][m_count - 19] & (1 << m_bit)) ? 1 : 0);
213   else
214      // send stored port d data
215      m_rx = ((m_data[2][m_count - 27] & (1 << m_bit)) ? 1 : 0);
216
217   if(m_bit == 7)
218   {
219      // ports won't ack if they are done
220      m_cack[0] = m_cack[1] = m_cack[2] = m_cack[3] = true;
221      if(m_count < 11)
222         m_ack_timer->adjust(attotime::from_usec(12), 0); // give a bit of time for the ports to ack
223      else if(m_count < 35)
224         m_ack_timer->adjust(attotime::from_usec(10), 0);
225   }
226
227   m_bit = (m_bit + 1) % 8;
228   if(!m_bit)
229      m_count++;
230}
231
232bool psx_multitap_device::get_pad(int count, UINT8 *odata, UINT8 idata)
233{
234   if(!count)
235      *odata = 0x80;
236   else
237      *odata = 0x5a;
238   return true;
239}
240
241void psx_multitap_device::ack()
242{
243   if(m_activeport != -1)
244   {
245      switch(m_activeport)
246      {
247         case 0:
248            m_ack = m_porta->ack_r();
249            break;
250         case 1:
251            m_ack = m_portb->ack_r();
252            break;
253         case 2:
254            m_ack = m_portc->ack_r();
255            break;
256         case 3:
257            m_ack = m_portd->ack_r();
258            break;
259         default:
260            return;
261      }
262      device_psx_controller_interface::m_owner->ack();
263      return;
264   }
265   if(!m_porta->ack_r())
266      m_cack[0] = false;
267   if(!m_portb->ack_r())
268      m_cack[1] = false;
269   if(!m_portc->ack_r())
270      m_cack[2] = false;
271   if(!m_portd->ack_r())
272      m_cack[3] = false;
273}
trunk/src/emu/bus/psx/multitap.h
r0r241420
1#ifndef PSXMULTITAP_H_
2#define PSXMULTITAP_H_
3
4#include "ctlrport.h"
5
6SLOT_INTERFACE_EXTERN(psx_controllers_nomulti);
7
8class psx_multitap_device : public device_t,
9                     public device_psx_controller_interface
10{
11public:
12   psx_multitap_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
13   virtual machine_config_constructor device_mconfig_additions() const;
14
15protected:
16   virtual void device_start();
17   virtual void device_stop() { device_psx_controller_interface::m_owner->disable_card(false); }
18   virtual void device_reset() { device_psx_controller_interface::m_owner->disable_card(true); }
19   virtual void device_config_complete() { m_shortname = "psx_multitap"; }
20   virtual void interface_pre_reset();
21
22private:
23   virtual bool get_pad(int count, UINT8 *odata, UINT8 idata);
24   virtual void do_pad();
25   void ack();
26   void set_tx_line(bool tx, int port);
27   bool get_rx_line(int port);
28
29   int m_activeport;
30   bool m_cack[4];
31   bool m_singlemode, m_nextmode, m_tapmc;
32   UINT8 m_data[3][8]; // port a is passed though
33   required_device<psx_controller_port_device> m_porta;
34   required_device<psx_controller_port_device> m_portb;
35   required_device<psx_controller_port_device> m_portc;
36   required_device<psx_controller_port_device> m_portd;
37};
38
39extern const device_type PSX_MULTITAP;
40
41#endif /* PSXMULTITAP_H_ */
trunk/src/mame/drivers/taitogn.c
r241419r241420
336336#include "machine/intelfsh.h"
337337#include "machine/mb3773.h"
338338#include "machine/rf5c296.h"
339#include "machine/znsec.h"
339#include "machine/cat702.h"
340340#include "machine/zndip.h"
341341#include "sound/spu.h"
342342#include "video/psx.h"
r241419r241420
346346public:
347347   taitogn_state(const machine_config &mconfig, device_type type, const char *tag) :
348348      driver_device(mconfig, type, tag),
349      m_znsec0(*this,"maincpu:sio0:znsec0"),
350      m_znsec1(*this,"maincpu:sio0:znsec1"),
349      m_cat702_1(*this,"maincpu:sio0:cat702_1"),
350      m_cat702_2(*this,"maincpu:sio0:cat702_2"),
351351      m_zndip(*this,"maincpu:sio0:zndip"),
352352      m_maincpu(*this, "maincpu"),
353353      m_mn10200(*this, "mn10200"),
r241419r241420
384384   virtual void machine_reset();
385385
386386private:
387   required_device<znsec_device> m_znsec0;
388   required_device<znsec_device> m_znsec1;
387   required_device<cat702_device> m_cat702_1;
388   required_device<cat702_device> m_cat702_2;
389389   required_device<zndip_device> m_zndip;
390390   required_device<cpu_device> m_maincpu;
391391   required_device<cpu_device> m_mn10200;
r241419r241420
511511
512512WRITE8_MEMBER(taitogn_state::znsecsel_w)
513513{
514   m_znsec0->select( ( data >> 2 ) & 1 );
515   m_znsec1->select( ( data >> 3 ) & 1 );
514   m_cat702_1->select( ( data >> 2 ) & 1 );
515   m_cat702_2->select( ( data >> 3 ) & 1 );
516516   m_zndip->select( ( data & 0x8c ) != 0x8c );
517517
518518   m_n_znsecsel = data;
r241419r241420
579579
580580void taitogn_state::driver_start()
581581{
582   m_znsec0->init(tt10);
583   m_znsec1->init(tt16);
582   m_cat702_1->init(tt10);
583   m_cat702_2->init(tt16);
584584}
585585
586586void taitogn_state::machine_reset()
r241419r241420
657657   MCFG_RAM_MODIFY("maincpu:ram")
658658   MCFG_RAM_DEFAULT_SIZE("4M")
659659
660   MCFG_DEVICE_ADD("maincpu:sio0:znsec0", ZNSEC, 0)
661   MCFG_DEVICE_ADD("maincpu:sio0:znsec1", ZNSEC, 0)
660   MCFG_DEVICE_ADD("maincpu:sio0:cat702_1", CAT702, 0)
661   MCFG_DEVICE_ADD("maincpu:sio0:cat702_2", CAT702, 0)
662662   MCFG_DEVICE_ADD("maincpu:sio0:zndip", ZNDIP, 0)
663663   MCFG_ZNDIP_DATA_HANDLER(IOPORT(":DSW"))
664664
trunk/src/mame/drivers/zn.c
r241419r241420
1717#include "machine/nvram.h"
1818#include "machine/mb3773.h"
1919#include "machine/7200fifo.h"
20#include "machine/znsec.h"
20#include "machine/cat702.h"
2121#include "machine/zndip.h"
2222#include "machine/ataintf.h"
2323#include "machine/vt83c461.h"
r241419r241420
3838      driver_device(mconfig, type, tag),
3939      m_gpu(*this, "gpu"),
4040      m_gpu_screen(*this, "gpu:screen"),
41      m_znsec0(*this,"maincpu:sio0:znsec0"),
42      m_znsec1(*this,"maincpu:sio0:znsec1"),
41      m_cat702_1(*this,"maincpu:sio0:cat702_1"),
42      m_cat702_2(*this,"maincpu:sio0:cat702_2"),
4343      m_zndip(*this,"maincpu:sio0:zndip"),
4444      m_maincpu(*this, "maincpu"),
4545      m_audiocpu(*this, "audiocpu"),
r241419r241420
124124
125125   required_device<psxgpu_device> m_gpu;
126126   required_device<screen_device> m_gpu_screen;
127   required_device<znsec_device> m_znsec0;
128   required_device<znsec_device> m_znsec1;
127   required_device<cat702_device> m_cat702_1;
128   required_device<cat702_device> m_cat702_2;
129129   required_device<zndip_device> m_zndip;
130130   required_device<cpu_device> m_maincpu;
131131   optional_device<cpu_device> m_audiocpu;
r241419r241420
333333{
334334   verboselog(2, "znsecsel_w( %08x, %08x, %08x )\n", offset, data, mem_mask );
335335
336   m_znsec0->select( ( data >> 2 ) & 1 );
337   m_znsec1->select( ( data >> 3 ) & 1 );
336   m_cat702_1->select( ( data >> 2 ) & 1 );
337   m_cat702_2->select( ( data >> 3 ) & 1 );
338338   m_zndip->select( ( data & 0x8c ) != 0x8c );
339339
340340   m_n_znsecsel = data;
r241419r241420
432432   {
433433      if( strcmp( machine().system().name, zn_config_table[ n_game ].s_name ) == 0 )
434434      {
435         m_znsec0->init( zn_config_table[ n_game ].p_n_mainsec );
436         m_znsec1->init( zn_config_table[ n_game ].p_n_gamesec );
435         m_cat702_1->init( zn_config_table[ n_game ].p_n_mainsec );
436         m_cat702_2->init( zn_config_table[ n_game ].p_n_gamesec );
437437         break;
438438      }
439439      n_game++;
r241419r241420
449449   MCFG_RAM_MODIFY("maincpu:ram")
450450   MCFG_RAM_DEFAULT_SIZE("4M")
451451
452   MCFG_DEVICE_ADD("maincpu:sio0:znsec0", ZNSEC, 0)
453   MCFG_DEVICE_ADD("maincpu:sio0:znsec1", ZNSEC, 0)
452   MCFG_DEVICE_ADD("maincpu:sio0:cat702_1", CAT702, 0)
453   MCFG_DEVICE_ADD("maincpu:sio0:cat702_2", CAT702, 0)
454454   MCFG_DEVICE_ADD("maincpu:sio0:zndip", ZNDIP, 0)
455455   MCFG_ZNDIP_DATA_HANDLER(IOPORT(":DSW"))
456456
r241419r241420
483483   MCFG_RAM_MODIFY("maincpu:ram")
484484   MCFG_RAM_DEFAULT_SIZE("4M")
485485
486   MCFG_DEVICE_ADD("maincpu:sio0:znsec0", ZNSEC, 0)
487   MCFG_DEVICE_ADD("maincpu:sio0:znsec1", ZNSEC, 0)
486   MCFG_DEVICE_ADD("maincpu:sio0:cat702_1", CAT702, 0)
487   MCFG_DEVICE_ADD("maincpu:sio0:cat702_2", CAT702, 0)
488488   MCFG_DEVICE_ADD("maincpu:sio0:zndip", ZNDIP, 0)
489489   MCFG_ZNDIP_DATA_HANDLER(IOPORT(":DSW"))
490490
trunk/src/mame/machine/cat702.c
r0r241420
1/*
2
3  CAT702 ZN security chip
4
5  A serial magic latch.
6
7  It's a DIP20 chip with a sticker of the form XXnn, where XX is the
8  company and nn a number:
9    AC = Acclaim
10    AT = Atlus
11    CP = Capcom
12    ET = Raizing
13    KN = Konami
14    MG = Tecmo
15    TT = Taito
16    TW = Atari
17
18  There usually are 2 of them, one on the cpu board and one on the rom
19  board.  The cpu board one is usually numbered 01.
20
21  Pinout:             GND -11  10- GND
22                        ? -12   9- +5V
23                      +5V -13   8- Data in
24                 Data out- 14   7- Clock
25                      +5V -15   6- Select
26                        ? -16   5- Select
27                      +5V -17   4- +5V
28                      +5V -18   3- +5V
29                      +5V -19   2- +5V
30                      +5V -20   1- ?
31
32  The chip works with the '?' lines left unconnected.
33
34  The communication protocol is serial, and in practice the standard
35  psx controller communication protocol minus the ack.  Drive both
36  select to ground to start a communication, send bits and get the
37  results on the raising clock.  Put both select back to +5V when
38  finished.  The bios seems to use two communication clock speeds,
39  ~300KHz (standard psx) and ~2MHz.  Driving it with lower clocks
40  works reasonably, at least at 1KHz.
41
42  The data is divided in bytes but there is no signal for end-of-byte.
43  In all of the following the data will be considered coming and going
44  lower-bit first.
45
46  Internally the chip has a 8-bit state, initialized at communication
47  start to 0xfc.  The structure is simple:
48
49
50                  +---------+         bit number        +--------+
51  Clock   ------->| bit     |-----+-------------------->| bit    |---------> Data out
52                  | counter |     |                     | select |
53                  +---------+     v      +-------+ out  |        |
54                      |        +-----+   | 8bit  |=====>|        |
55  Data in ------------|------->| TF1 |<=>| state |      +--------+
56                      |        +-----+   |       |
57                      |                  |       |
58                      | start  +-----+   |       |
59                      +------->| TF2 |<=>|       |
60                               +-----+   +-------+
61
62  The chip starts by tranforming the state with TF2.  Then, for each
63  input bit from 0 to 7:
64    - the nth bit from the state is sent to the output
65    - the state is transformed by TF1 if the input bit is 0
66
67  TF2 is a fixed linear substitution box (* = and, + = xor):
68    o = ff*s0 + fe*s1 + fc*s2 + f8*s3 + f0*s4 + e0*s5 + c0*s6 + 7f*s7
69
70  TF1 is a chip-dependent set of 8 linear sboxes, one per bit number.
71  In practice, only the sbox for bit 0 is defined for the chip, the 7
72  other are derived from it.  Defining the byte transformation Shift
73  as:
74       Shift(i7..i0) = i6..i0, i7^i6
75
76  and noting the sboxes as:
77       Sbox(n, i7..i0) =    Xor(    c[n, bit]*i[bit])
78                         0<=bit<=7
79  then
80       c[n, bit=0..6] = Shift(c[n-1, (bit-1)&7])
81       c[n, 7]        = Shift(c[n-1, 6])^c[n, 0]
82                      = Shift(c[n-1, 6])^Shift(c[n-1, 7])
83*/
84
85#include "cat702.h"
86
87const device_type CAT702 = &device_creator<cat702_device>;
88
89cat702_device::cat702_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
90   psxsiodev_device(mconfig, CAT702, "CAT702", tag, owner, clock, "cat702", __FILE__)
91{
92}
93
94void cat702_device::device_start()
95{
96   psxsiodev_device::device_start();
97
98   save_item(NAME(m_select));
99   save_item(NAME(m_state));
100   save_item(NAME(m_bit));
101}
102
103// Given the value for x7..x0 and linear transform coefficients a7..a0
104// compute the value of the transform
105#if 0
106static int c_linear(UINT8 x, UINT8 a)
107{
108   int i;
109   UINT8 r;
110   x &= a;
111   r = 0;
112   for(i=0; i<8; i++)
113      if(x & (1<<i))
114         r = !r;
115   return r;
116}
117#endif
118
119// Derive the sbox xor mask for a given input and select bit
120UINT8 cat702_device::compute_sbox_coef(int sel, int bit)
121{
122   if(!sel)
123      return m_transform[bit];
124
125   UINT8 r = compute_sbox_coef((sel-1) & 7, (bit-1) & 7);
126   r = (r << 1)|(((r >> 7)^(r >> 6)) & 1);
127   if(bit != 7)
128      return r;
129
130   return r ^ compute_sbox_coef(sel, 0);
131}
132
133// Apply the sbox for a input 0 bit
134void cat702_device::apply_bit_sbox(int sel)
135{
136   int i;
137   UINT8 r = 0;
138   for(i=0; i<8; i++)
139      if(m_state & (1<<i))
140         r ^= compute_sbox_coef(sel, i);
141
142   m_state = r;
143}
144
145// Apply a sbox
146void cat702_device::apply_sbox(const UINT8 *sbox)
147{
148   int i;
149   UINT8 r = 0;
150   for(i=0; i<8; i++)
151      if(m_state & (1<<i))
152         r ^= sbox[i];
153
154   m_state = r;
155}
156
157void cat702_device::init(const UINT8 *transform)
158{
159   m_transform = transform;
160}
161
162void cat702_device::select(int select)
163{
164   if (m_select != select)
165   {
166      if (!select)
167      {
168         m_state = 0xfc;
169         m_bit = 0;
170      }
171      else
172      {
173         data_out(0, PSX_SIO_IN_DATA);
174      }
175
176      m_select = select;
177   }
178}
179
180void cat702_device::data_in( int data, int mask )
181{
182   static const UINT8 initial_sbox[8] = { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x7f };
183
184   if ( !m_select && (mask & PSX_SIO_OUT_CLOCK) != 0 && (data & PSX_SIO_OUT_CLOCK) == 0)
185   {
186      if (m_bit==0)
187      {
188         // Apply the initial sbox
189         apply_sbox(initial_sbox);
190      }
191
192      // Compute the output and change the state
193      data_out(((m_state >> m_bit) & 1) != 0 ? PSX_SIO_IN_DATA : 0, PSX_SIO_IN_DATA);
194
195      if((data & PSX_SIO_OUT_DATA)==0)
196         apply_bit_sbox(m_bit);
197
198      m_bit++;
199      m_bit&=7;
200   }
201}
trunk/src/mame/machine/cat702.h
r0r241420
1/*  CAT702 ZN security chip */
2
3#pragma once
4
5#ifndef __CAT702_H__
6#define __CAT702_H__
7
8#include "cpu/psx/siodev.h"
9
10extern const device_type CAT702;
11
12class cat702_device : public psxsiodev_device
13{
14public:
15   cat702_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
16
17   void init(const UINT8 *transform);
18   void select(int select);
19
20protected:
21   virtual void device_start();
22
23private:
24   virtual void data_in( int data, int mask );
25
26   UINT8 compute_sbox_coef(int sel, int bit);
27   void apply_bit_sbox(int sel);
28   void apply_sbox(const UINT8 *sbox);
29
30   const UINT8 *m_transform;
31   int m_select;
32   UINT8 m_state;
33   UINT8 m_bit;
34};
35
36#endif
trunk/src/mame/machine/znsec.c
r241419r241420
1/*
2
3  CAT702 ZN security chip
4
5  A serial magic latch.
6
7  It's a DIP20 chip with a sticker of the form XXnn, where XX is the
8  company and nn a number:
9    AC = Acclaim
10    AT = Atlus
11    CP = Capcom
12    ET = Raizing
13    KN = Konami
14    MG = Tecmo
15    TT = Taito
16    TW = Atari
17
18  There usually are 2 of them, one on the cpu board and one on the rom
19  board.  The cpu board one is usually numbered 01.
20
21  Pinout:             GND -11  10- GND
22                        ? -12   9- +5V
23                      +5V -13   8- Data in
24                 Data out- 14   7- Clock
25                      +5V -15   6- Select
26                        ? -16   5- Select
27                      +5V -17   4- +5V
28                      +5V -18   3- +5V
29                      +5V -19   2- +5V
30                      +5V -20   1- ?
31
32  The chip works with the '?' lines left unconnected.
33
34  The communication protocol is serial, and in practice the standard
35  psx controller communication protocol minus the ack.  Drive both
36  select to ground to start a communication, send bits and get the
37  results on the raising clock.  Put both select back to +5V when
38  finished.  The bios seems to use two communication clock speeds,
39  ~300KHz (standard psx) and ~2MHz.  Driving it with lower clocks
40  works reasonably, at least at 1KHz.
41
42  The data is divided in bytes but there is no signal for end-of-byte.
43  In all of the following the data will be considered coming and going
44  lower-bit first.
45
46  Internally the chip has a 8-bit state, initialized at communication
47  start to 0xfc.  The structure is simple:
48
49
50                  +---------+         bit number        +--------+
51  Clock   ------->| bit     |-----+-------------------->| bit    |---------> Data out
52                  | counter |     |                     | select |
53                  +---------+     v      +-------+ out  |        |
54                      |        +-----+   | 8bit  |=====>|        |
55  Data in ------------|------->| TF1 |<=>| state |      +--------+
56                      |        +-----+   |       |
57                      |                  |       |
58                      | start  +-----+   |       |
59                      +------->| TF2 |<=>|       |
60                               +-----+   +-------+
61
62  The chip starts by tranforming the state with TF2.  Then, for each
63  input bit from 0 to 7:
64    - the nth bit from the state is sent to the output
65    - the state is transformed by TF1 if the input bit is 0
66
67  TF2 is a fixed linear substitution box (* = and, + = xor):
68    o = ff*s0 + fe*s1 + fc*s2 + f8*s3 + f0*s4 + e0*s5 + c0*s6 + 7f*s7
69
70  TF1 is a chip-dependent set of 8 linear sboxes, one per bit number.
71  In practice, only the sbox for bit 0 is defined for the chip, the 7
72  other are derived from it.  Defining the byte transformation Shift
73  as:
74       Shift(i7..i0) = i6..i0, i7^i6
75
76  and noting the sboxes as:
77       Sbox(n, i7..i0) =    Xor(    c[n, bit]*i[bit])
78                         0<=bit<=7
79  then
80       c[n, bit=0..6] = Shift(c[n-1, (bit-1)&7])
81       c[n, 7]        = Shift(c[n-1, 6])^c[n, 0]
82                      = Shift(c[n-1, 6])^Shift(c[n-1, 7])
83*/
84
85#include "znsec.h"
86
87const device_type ZNSEC = &device_creator<znsec_device>;
88
89znsec_device::znsec_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
90   psxsiodev_device(mconfig, ZNSEC, "ZNSEC", tag, owner, clock, "znsec", __FILE__)
91{
92}
93
94void znsec_device::device_start()
95{
96   psxsiodev_device::device_start();
97
98   save_item(NAME(m_select));
99   save_item(NAME(m_state));
100   save_item(NAME(m_bit));
101}
102
103// Given the value for x7..x0 and linear transform coefficients a7..a0
104// compute the value of the transform
105#if 0
106static int c_linear(UINT8 x, UINT8 a)
107{
108   int i;
109   UINT8 r;
110   x &= a;
111   r = 0;
112   for(i=0; i<8; i++)
113      if(x & (1<<i))
114         r = !r;
115   return r;
116}
117#endif
118
119// Derive the sbox xor mask for a given input and select bit
120UINT8 znsec_device::compute_sbox_coef(int sel, int bit)
121{
122   if(!sel)
123      return m_transform[bit];
124
125   UINT8 r = compute_sbox_coef((sel-1) & 7, (bit-1) & 7);
126   r = (r << 1)|(((r >> 7)^(r >> 6)) & 1);
127   if(bit != 7)
128      return r;
129
130   return r ^ compute_sbox_coef(sel, 0);
131}
132
133// Apply the sbox for a input 0 bit
134void znsec_device::apply_bit_sbox(int sel)
135{
136   int i;
137   UINT8 r = 0;
138   for(i=0; i<8; i++)
139      if(m_state & (1<<i))
140         r ^= compute_sbox_coef(sel, i);
141
142   m_state = r;
143}
144
145// Apply a sbox
146void znsec_device::apply_sbox(const UINT8 *sbox)
147{
148   int i;
149   UINT8 r = 0;
150   for(i=0; i<8; i++)
151      if(m_state & (1<<i))
152         r ^= sbox[i];
153
154   m_state = r;
155}
156
157void znsec_device::init(const UINT8 *transform)
158{
159   m_transform = transform;
160}
161
162void znsec_device::select(int select)
163{
164   if (m_select != select)
165   {
166      if (!select)
167      {
168         m_state = 0xfc;
169         m_bit = 0;
170      }
171      else
172      {
173         data_out(0, PSX_SIO_IN_DATA);
174      }
175
176      m_select = select;
177   }
178}
179
180void znsec_device::data_in( int data, int mask )
181{
182   static const UINT8 initial_sbox[8] = { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x7f };
183
184   if ( !m_select && (mask & PSX_SIO_OUT_CLOCK) != 0 && (data & PSX_SIO_OUT_CLOCK) == 0)
185   {
186      if (m_bit==0)
187      {
188         // Apply the initial sbox
189         apply_sbox(initial_sbox);
190      }
191
192      // Compute the output and change the state
193      data_out(((m_state >> m_bit) & 1) != 0 ? PSX_SIO_IN_DATA : 0, PSX_SIO_IN_DATA);
194
195      if((data & PSX_SIO_OUT_DATA)==0)
196         apply_bit_sbox(m_bit);
197
198      m_bit++;
199      m_bit&=7;
200   }
201}
trunk/src/mame/machine/znsec.h
r241419r241420
1/*  CAT702 ZN security chip */
2
3#pragma once
4
5#ifndef __ZNSEC_H__
6#define __ZNSEC_H__
7
8#include "cpu/psx/siodev.h"
9
10extern const device_type ZNSEC;
11
12class znsec_device : public psxsiodev_device
13{
14public:
15   znsec_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
16
17   void init(const UINT8 *transform);
18   void select(int select);
19
20protected:
21   virtual void device_start();
22
23private:
24   virtual void data_in( int data, int mask );
25
26   UINT8 compute_sbox_coef(int sel, int bit);
27   void apply_bit_sbox(int sel);
28   void apply_sbox(const UINT8 *sbox);
29
30   const UINT8 *m_transform;
31   int m_select;
32   UINT8 m_state;
33   UINT8 m_bit;
34};
35
36#endif
trunk/src/mame/mame.mak
r241419r241420
18171817   $(DRIVERS)/snk68.o $(VIDEO)/snk68.o \
18181818
18191819$(MAMEOBJ)/sony.a: \
1820   $(DRIVERS)/zn.o $(MACHINE)/zndip.o $(MACHINE)/znsec.o \
1820   $(DRIVERS)/zn.o $(MACHINE)/zndip.o $(MACHINE)/cat702.o \
18211821
18221822$(MAMEOBJ)/stern.a: \
18231823   $(DRIVERS)/astinvad.o \
trunk/src/mess/drivers/psx.c
r241419r241420
1717#include "debugger.h"
1818#include <zlib.h>
1919#include "machine/psxcd.h"
20#include "machine/psxcport.h"
20#include "bus/psx/ctlrport.h"
2121
2222#define PSXCD_TAG   "psxcd"
2323
trunk/src/mess/machine/psxanalog.c
r241419r241420
1#include "machine/psxanalog.h"
2
3const device_type PSX_ANALOG_JOYSTICK = &device_creator<psx_analog_joystick_device>;
4const device_type PSX_DUALSHOCK = &device_creator<psx_dualshock_device>;
5
6psx_analog_controller_device::psx_analog_controller_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) :
7      device_t(mconfig, type, name, tag, owner, clock, shortname, source),
8      device_psx_controller_interface(mconfig, *this),
9      m_pad0(*this, "PSXPAD0"),
10      m_pad1(*this, "PSXPAD1"),
11      m_rstickx(*this, "PSXRSTICKX"),
12      m_rsticky(*this, "PSXRSTICKY"),
13      m_lstickx(*this, "PSXLSTICKX"),
14      m_lsticky(*this, "PSXLSTICKY")
15{
16}
17
18psx_dualshock_device::psx_dualshock_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
19      psx_analog_controller_device(mconfig, PSX_DUALSHOCK, "Playstation Dualshock Pad", tag, owner, clock, "psx_dualshock_pad", __FILE__)
20{
21   m_type = DUALSHOCK;
22}
23
24psx_analog_joystick_device::psx_analog_joystick_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
25      psx_analog_controller_device(mconfig, PSX_ANALOG_JOYSTICK, "Playstation Analog Joystick", tag, owner, clock, "psx_analog_joystick", __FILE__)
26{
27   m_type = JOYSTICK;
28}
29
30void psx_analog_controller_device::device_reset()
31{
32   m_confmode = false;
33   m_analogmode = false;
34   m_analoglock = false;
35
36   m_cmd = 0;
37}
38
39UINT8 psx_analog_controller_device::pad_data(int count, bool analog)
40{
41   UINT8 data = 0;
42   switch(count)
43   {
44      case 2:
45         data = m_pad0->read();
46         if(!analog || (m_type == JOYSTICK))
47            data |= 6; // l3/r3
48         break;
49      case 3:
50         data = m_pad1->read();
51         break;
52      case 4:
53         data = m_rstickx->read();
54         break;
55      case 5:
56         data = m_rsticky->read();
57         break;
58      case 6:
59         data = m_lstickx->read();
60         break;
61      case 7:
62         data = m_lsticky->read();
63         break;
64   }
65   return data;
66}
67
68bool psx_analog_controller_device::get_pad(int count, UINT8 *odata, UINT8 idata)
69{
70   if(m_confmode)
71   {
72      switch(count)
73      {
74         case 0:
75            m_temp = 0;
76            *odata = 0xf3;
77            break;
78         case 1:
79            m_cmd = idata;
80            if((m_cmd & 0xf0) != 0x40)
81               return false;
82            *odata = 0x5a;
83            break;
84         default:
85            switch(m_cmd)
86            {
87               default: // 40,41,48,49,4a,4b,4f -- all unknown
88                  *odata = 0x00;
89                  break;
90               case CONFIG_MODE: // 43
91                  if(count == 3)
92                     m_temp = idata;
93                  /* no break */
94               case QUERY_PAD_STATE: // 42
95                  *odata = pad_data(count, true);
96                  break;
97               case 0x44: // set mode and lock ?
98                  switch(count)
99                  {
100                     case 3:
101                        m_analogmode = idata ? true : false; // only 0x01 ?
102                        break;
103                     case 4:
104                        m_analoglock = idata ? true : false; // only 0x03 ?
105                        break;
106                  }
107                  *odata = 0x00;
108                  break;
109               case 0x45: // get mode ?
110               {
111                  const UINT8 val[] = { 1, 2, 0, 2, 1, 0 };
112                  if(count == 4)
113                     *odata = m_analogmode;
114                  else
115                     *odata = val[count-2];
116                  break;
117               }
118               case 0x46: // query act (vibrate) ?
119               {
120                  const UINT8 val[2][6] = {{ 0, 0, 1, 2, 0, 10 },
121                                    { 0, 0, 1, 1, 1, 14 }};
122                  *odata = val[m_temp][count-2];
123                  if(count == 3)
124                     m_temp = idata ? 1 : 0;
125                  break;
126               }
127               case 0x47: // query comb (combination?) ?
128               {
129                  const UINT8 val[] = { 0, 0, 2, 0, 1, 0 };
130                  *odata = val[count-2];
131                  break;
132               }
133               case 0x4c: // query mode ?
134                  switch(count)
135                  {
136                     case 3:
137                        m_temp = idata;
138                        /* no break */
139                     default:
140                        *odata = 0x00;
141                        break;
142                     case 5:
143                        *odata = m_analogmode ? 0x07 : 0x04; // ?
144                        break;
145                  }
146                  break;
147               case 0x4d: // set act (vibrate) ?
148                  *odata = 0xff;
149                  break;
150            }
151            break;
152         case 8:
153            if(m_cmd == CONFIG_MODE)
154               m_confmode = m_temp;
155            return false;
156      }
157   }
158   else if(m_analogmode)
159   {
160      switch(count)
161      {
162         case 0:
163            if(m_type == JOYSTICK)
164               *odata = 0x53;
165            else
166               *odata = 0x73;
167            break;
168         case 1:
169            m_cmd = idata;
170            if((m_cmd & 0xfe) != QUERY_PAD_STATE)
171               return false;
172            *odata = 0x5a;
173            break;
174         case 3:
175            if(m_cmd == CONFIG_MODE)
176               m_temp = idata;
177            /* no break */
178         default:
179            *odata = pad_data(count, true);
180            break;
181         case 8:
182            if(m_cmd == CONFIG_MODE)
183               m_confmode = m_temp;
184            return false;
185      }
186   }
187   else
188   {
189      switch(count)
190      {
191         case 0:
192            *odata = 0x41;
193            break;
194         case 1:
195            m_cmd = idata;
196            if((m_cmd & 0xfe) != QUERY_PAD_STATE)
197               return false;
198            *odata = 0x5a;
199            break;
200         case 3:
201            if(m_cmd == CONFIG_MODE)
202               m_temp = idata;
203            /* no break */
204         default:
205            *odata = pad_data(count, false);
206            break;
207         case 4:
208            if(m_cmd == CONFIG_MODE)
209               m_confmode = m_temp;
210            return false;
211      }
212   }
213   return true;
214}
215
216static INPUT_PORTS_START( psx_analog_controller )
217   PORT_START("PSXPAD0")
218   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
219   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
220   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
221   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP )
222   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START )
223   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON9 ) PORT_NAME("R3")
224   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON10 ) PORT_NAME("L3")
225   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SELECT )
226
227   PORT_START("PSXPAD1")
228   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Square")
229   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Cross")
230   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Circle")
231   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Triangle")
232   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("R1")
233   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("L1")
234   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("R2")
235   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("L2")
236
237   PORT_START("PSXRSTICKX")
238   PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_NAME("Right Analog X") PORT_SENSITIVITY(100)
239
240   PORT_START("PSXRSTICKY")
241   PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_NAME("Right Analog Y") PORT_SENSITIVITY(100)
242
243   PORT_START("PSXLSTICKX")
244   PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Z ) PORT_NAME("Left Analog X") PORT_SENSITIVITY(100)
245
246   PORT_START("PSXLSTICKY")
247   PORT_BIT( 0xff, 0x80, IPT_PADDLE ) PORT_NAME("Left Analog Y") PORT_SENSITIVITY(100)
248
249   PORT_START("PSXMISC")
250   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON11 ) PORT_NAME("Analog") PORT_TOGGLE PORT_CHANGED_MEMBER(DEVICE_SELF, psx_analog_controller_device, change_mode, 0)
251INPUT_PORTS_END
252
253ioport_constructor psx_analog_controller_device::device_input_ports() const
254{
255   return INPUT_PORTS_NAME(psx_analog_controller);
256}
257
258INPUT_CHANGED_MEMBER(psx_analog_controller_device::change_mode)
259{
260   if(!m_analoglock)
261      m_analogmode = newval;
262}
trunk/src/mess/machine/psxanalog.h
r241419r241420
1#ifndef PSXANALOG_H_
2#define PSXANALOG_H_
3
4#include "machine/psxcport.h"
5
6extern const device_type PSX_DUALSHOCK;
7extern const device_type PSX_ANALOG_JOYSTICK;
8
9class psx_analog_controller_device :    public device_t,
10                              public device_psx_controller_interface
11{
12public:
13   psx_analog_controller_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);
14
15   virtual ioport_constructor device_input_ports() const;
16   DECLARE_INPUT_CHANGED_MEMBER(change_mode);
17protected:
18   virtual void device_reset();
19   virtual void device_start() {}
20   enum {
21      JOYSTICK,
22      DUALSHOCK
23   } m_type;
24private:
25   virtual bool get_pad(int count, UINT8 *odata, UINT8 idata);
26   UINT8 pad_data(int count, bool analog);
27
28   bool m_confmode;
29   bool m_analogmode;
30   bool m_analoglock;
31
32   UINT8 m_temp;
33   UINT8 m_cmd;
34
35   required_ioport m_pad0;
36   required_ioport m_pad1;
37   required_ioport m_rstickx;
38   required_ioport m_rsticky;
39   required_ioport m_lstickx;
40   required_ioport m_lsticky;
41};
42
43class psx_dualshock_device : public psx_analog_controller_device
44{
45public:
46   psx_dualshock_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
47};
48
49class psx_analog_joystick_device : public psx_analog_controller_device
50{
51public:
52   psx_analog_joystick_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
53};
54
55#endif /* PSXANALOG_H_ */
trunk/src/mess/machine/psxcard.c
r241419r241420
1/*
2    psxcard.c - Sony PlayStation memory card device
3
4    by pSXAuthor
5    MESS conversion by R. Belmont
6*/
7
8#include "emu.h"
9#include "psxcard.h"
10#include "machine/psxcport.h"
11
12//
13//
14//
15
16//#define debug_card
17
18//
19//
20//
21
22static const int block_size = 128;
23static const int card_size = block_size * 1024;
24
25const device_type PSXCARD = &device_creator<psxcard_device>;
26
27enum transfer_states
28{
29   state_illegal=0,
30   state_command,
31   state_cmdack,
32   state_wait,
33   state_addr_hi,
34   state_addr_lo,
35   state_read,
36   state_write,
37   state_writeack_2,
38   state_writechk,
39   state_end
40};
41
42psxcard_device::psxcard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
43   : device_t(mconfig, PSXCARD, "Sony PSX Memory Card", tag, owner, clock, "psxcard", __FILE__),
44   device_image_interface(mconfig, *this)
45{
46}
47
48void psxcard_device::device_start()
49{
50   m_owner = dynamic_cast<psx_controller_port_device *>(owner());
51   m_ack_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(psxcard_device::ack_timer), this));
52
53   m_ack = true;
54   m_disabled = false;
55
56   // save state registrations
57   save_item(NAME(pkt));
58   save_item(NAME(pkt_ptr));
59   save_item(NAME(pkt_sz));
60   save_item(NAME(cmd));
61   save_item(NAME(addr));
62   save_item(NAME(state));
63   save_item(NAME(m_disabled));
64   save_item(NAME(m_odata));
65   save_item(NAME(m_idata));
66   save_item(NAME(m_bit));
67   save_item(NAME(m_count));
68   save_item(NAME(m_pad));
69}
70
71void psxcard_device::device_reset()
72{
73   state = state_illegal;
74   addr = 0;
75
76   m_bit = 0;
77   m_count = 0;
78   m_pad = false;
79   m_idata = 0;
80
81   m_clock = true;
82   m_sel = true;
83   m_rx = true;
84   m_ack = true;
85   m_owner->ack();
86}
87
88void psxcard_device::device_config_complete()
89{
90   update_names(PSXCARD, "memcard", "mc");
91}
92
93//
94//
95//
96
97bool psxcard_device::transfer(UINT8 to, UINT8 *from)
98{
99   bool ret=true;
100
101   switch (state)
102   {
103      case state_illegal:
104         if (is_loaded())
105         {
106//              printf("CARD: begin\n");
107            state = state_command;
108            *from = 0x00;
109         }
110         else
111         {
112            ret = false;
113         }
114         break;
115
116      case state_command:
117         cmd=to;
118         *from=0x5a;
119         state=state_cmdack;
120         break;
121
122      case state_cmdack:
123         *from=0x5d;
124         state=state_wait;
125         break;
126
127      case state_wait:
128         *from=0x00;
129         state=state_addr_hi;
130         break;
131
132      case state_addr_hi:
133         addr=(to<<8);
134//          printf("addr_hi: %02x, addr = %x\n", to, addr);
135         *from=to;
136         state=state_addr_lo;
137         break;
138
139      case state_addr_lo:
140         addr|=(to&0xff);
141//          printf("addr_lo: %02x, addr = %x, cmd = %x\n", to, addr, cmd);
142
143         switch (cmd)
144         {
145            case 'R':   // 0x52
146            {
147               pkt[0]=*from=0x5c;
148               pkt[1]=0x5d;
149               pkt[2]=(addr>>8);
150               pkt[3]=(addr&0xff);
151               read_card(addr,&pkt[4]);
152               pkt[4+128]=checksum_data(&pkt[2],128+2);
153               pkt[5+128]=0x47;
154               pkt_sz=6+128;
155               pkt_ptr=1;
156               state=state_read;
157               break;
158            }
159            case 'W':   // 0x57
160            {
161               pkt[0]=addr>>8;
162               pkt[1]=addr&0xff;
163               pkt_sz=129+2;
164               pkt_ptr=2;
165               state=state_write;
166               *from=to;
167               break;
168            }
169            default:
170               state=state_illegal;
171               break;
172         }
173         break;
174
175      case state_read:
176         //assert(to==0);
177//          printf("state_read: pkt_ptr = %d, pkt_sz = %d\n", pkt_ptr, pkt_sz);
178         *from=pkt[pkt_ptr++];
179         if (pkt_ptr==pkt_sz)
180         {
181            #ifdef debug_card
182               printf("card: read finished\n");
183            #endif
184
185            state=state_end;
186         }
187         break;
188
189      case state_write:
190         *from=to;
191         pkt[pkt_ptr++]=to;
192         if (pkt_ptr==pkt_sz)
193         {
194            *from=0x5c;
195            state=state_writeack_2;
196         }
197         break;
198
199      case state_writeack_2:
200         *from=0x5d;
201         state=state_writechk;
202         break;
203
204      case state_writechk:
205      {
206         unsigned char chk=checksum_data(pkt,128+2);
207         if (chk==pkt[128+2])
208         {
209            #ifdef debug_card
210               printf("card: write ok\n");
211            #endif
212
213            write_card(addr,pkt+2);
214
215            *from='G';
216         } else
217         {
218            #ifdef debug_card
219               printf("card: write fail\n");
220            #endif
221
222            *from='N';
223         }
224         state=state_end;
225         break;
226      }
227
228      case state_end:
229         ret = false;
230         state = state_illegal;
231         break;
232
233      default: /*assert(0);*/ ret=false; break;
234   }
235
236   #ifdef debug_card
237//      printf("card: transfer to=%02x from=%02x ret=%c\n",to,*from,ret ? 'T' : 'F');
238   #endif
239
240   return ret;
241}
242
243void psxcard_device::read_card(const unsigned short addr, unsigned char *buf)
244{
245   #ifdef debug_card
246      printf("card: read block %d\n",addr);
247   #endif
248
249   if (addr<(card_size/block_size))
250   {
251      fseek(addr*block_size, SEEK_SET);
252      fread(buf, block_size);
253   } else
254   {
255      memset(buf,0,block_size);
256   }
257}
258
259//
260//
261//
262
263void psxcard_device::write_card(const unsigned short addr, unsigned char *buf)
264{
265   #ifdef debug_card
266      printf("card: write block %d\n",addr);
267   #endif
268
269   if (addr<(card_size/block_size))
270   {
271      fseek(addr*block_size, SEEK_SET);
272      fwrite(buf, block_size);
273   }
274}
275
276unsigned char psxcard_device::checksum_data(const unsigned char *buf, const unsigned int sz)
277{
278   unsigned char chk=*buf++;
279   int left=sz;
280   while (--left) chk^=*buf++;
281   return chk;
282}
283
284bool psxcard_device::call_load()
285{
286   if(m_disabled)
287   {
288      logerror("psxcard: port disabled\n");
289      return IMAGE_INIT_FAIL;
290   }
291
292   if(length() != card_size)
293      return IMAGE_INIT_FAIL;
294   return IMAGE_INIT_PASS;
295}
296
297bool psxcard_device::call_create(int format_type, option_resolution *format_options)
298{
299   UINT8 block[block_size];
300   int i, ret;
301
302   if(m_disabled)
303   {
304      logerror("psxcard: port disabled\n");
305      return IMAGE_INIT_FAIL;
306   }
307
308   memset(block, '\0', block_size);
309   for(i = 0; i < (card_size/block_size); i++)
310   {
311      ret = fwrite(block, block_size);
312      if(ret != block_size)
313         return IMAGE_INIT_FAIL;
314   }
315   return IMAGE_INIT_PASS;
316}
317
318void psxcard_device::do_card()
319{
320   if(!m_bit)
321   {
322      m_idata = 0;
323      if(!m_count)
324         m_odata = 0xff;
325   }
326
327   m_rx = (m_odata & (1 << m_bit)) ? true : false;
328   m_idata |= (m_owner->tx_r()?1:0) << m_bit;
329   m_bit = (m_bit + 1) % 8;
330
331   if(!m_bit)
332   {
333      if((!m_count) && !(m_idata & 0x80))
334      {
335         m_pad = true;
336         return;
337      }
338
339      if(transfer(m_idata, &m_odata))
340      {
341         m_count++;
342         m_ack_timer->adjust(attotime::from_usec(10), 0);
343      }
344      else
345         m_count = 0;
346   }
347}
348
349void psxcard_device::ack_timer(void *ptr, int param)
350{
351   m_ack = param;
352   m_owner->ack();
353
354   if(!param)
355      m_ack_timer->adjust(attotime::from_usec(2), 1);
356}
357
358void psxcard_device::sel_w(bool state)
359{
360   if(state && !m_sel)
361      reset();
362   m_sel = state;
363}
trunk/src/mess/machine/psxcard.h
r241419r241420
1#pragma once
2
3#ifndef _PSXCARD_
4#define _PSXCARD_
5
6#include "emu.h"
7
8class psx_controller_port_device;
9
10#define MCFG_PSXCARD_ADD(_tag) \
11   MCFG_DEVICE_ADD(_tag, PSXCARD, 0)
12
13class psxcard_device :  public device_t,
14                  public device_image_interface
15{
16public:
17   psxcard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
18
19   virtual iodevice_t image_type() const { return IO_MEMCARD; }
20
21   virtual bool is_readable()  const { return 1; }
22   virtual bool is_writeable() const { return 1; }
23   virtual bool is_creatable() const { return 1; }
24   virtual bool must_be_loaded() const { return 0; }
25   virtual bool is_reset_on_load() const { return 0; }
26   virtual const char *file_extensions() const { return "mc"; }
27   virtual const option_guide *create_option_guide() const { return NULL; }
28
29   virtual bool call_load();
30   virtual bool call_create(int format_type, option_resolution *format_options);
31
32   void disable(bool state) { m_disabled = state; if(state) unload(); }
33
34private:
35   unsigned char pkt[0x8b], pkt_ptr, pkt_sz, cmd;
36   unsigned short addr;
37   int state;
38   bool m_disabled;
39
40   UINT8 m_odata;
41   UINT8 m_idata;
42   int m_bit;
43   int m_count;
44   bool m_pad;
45
46   bool m_clock;
47   bool m_sel;
48   bool m_ack;
49   bool m_rx;
50
51   emu_timer *m_ack_timer;
52   psx_controller_port_device *m_owner;
53
54   void read_card(const unsigned short addr, unsigned char *buf);
55   void write_card(const unsigned short addr, unsigned char *buf);
56   unsigned char checksum_data(const unsigned char *buf, const unsigned int sz);
57   void do_card();
58   bool transfer(UINT8 to, UINT8 *from);
59   void ack_timer(void *ptr, int param);
60
61public:
62   virtual void device_start();
63   virtual void device_reset();
64   virtual void device_config_complete();
65
66   void clock_w(bool state) { if(m_clock && !m_sel && !state && !m_pad) do_card(); m_clock = state; }
67   void sel_w(bool state);
68   bool rx_r() { return m_rx; }
69   bool ack_r() { return m_ack; }
70};
71
72// device type definition
73extern const device_type PSXCARD;
74
75#endif
trunk/src/mess/machine/psxcport.c
r241419r241420
1/* PAD emulation */
2
3#include "machine/psxcport.h"
4#include "machine/psxanalog.h"
5#include "machine/psxmultitap.h"
6
7const device_type PSX_CONTROLLER_PORT = &device_creator<psx_controller_port_device>;
8
9psx_controller_port_device::psx_controller_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
10      device_t(mconfig, PSX_CONTROLLER_PORT, "Playstation Controller Port", tag, owner, clock, "psx_controller_port", __FILE__),
11      device_slot_interface(mconfig, *this),
12      m_card(*this, "card")
13{
14}
15
16void psx_controller_port_device::device_config_complete()
17{
18   m_dev = dynamic_cast<device_psx_controller_interface *>(get_card_device());
19}
20
21static MACHINE_CONFIG_FRAGMENT( psx_memory_card )
22   MCFG_PSXCARD_ADD("card")
23MACHINE_CONFIG_END
24
25machine_config_constructor psx_controller_port_device::device_mconfig_additions() const
26{
27   return MACHINE_CONFIG_NAME( psx_memory_card );
28}
29
30void psx_controller_port_device::disable_card(bool state)
31{
32   if(state)
33      popmessage("Memory card port %s is disabled\n", m_card->brief_instance_name());
34
35   m_card->disable(state);
36}
37
38const device_type PSXCONTROLLERPORTS = &device_creator<psxcontrollerports_device>;
39
40psxcontrollerports_device::psxcontrollerports_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
41      psxsiodev_device(mconfig, PSXCONTROLLERPORTS, "PSXCONTROLLERPORTS", tag, owner, clock, "psxcontrollerports", __FILE__)
42{
43}
44
45void psxcontrollerports_device::device_start()
46{
47   m_port0 = machine().device<psx_controller_port_device>("port1");
48   m_port1 = machine().device<psx_controller_port_device>("port2");
49   m_port0->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psxcontrollerports_device::ack), this));
50   m_port1->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psxcontrollerports_device::ack), this));
51   psxsiodev_device::device_start();
52}
53
54// add controllers to define so they can be connected to the multitap
55#define PSX_CONTROLLERS \
56      SLOT_INTERFACE("digital_pad", PSX_STANDARD_CONTROLLER) \
57      SLOT_INTERFACE("dualshock_pad", PSX_DUALSHOCK) \
58      SLOT_INTERFACE("analog_joystick", PSX_ANALOG_JOYSTICK)
59
60SLOT_INTERFACE_START(psx_controllers)
61   PSX_CONTROLLERS
62   SLOT_INTERFACE("multitap", PSX_MULTITAP)
63SLOT_INTERFACE_END
64
65SLOT_INTERFACE_START(psx_controllers_nomulti)
66   PSX_CONTROLLERS
67SLOT_INTERFACE_END
68
69void psxcontrollerports_device::data_in( int data, int mask )
70{
71   m_port0->sel_w((data & PSX_SIO_OUT_DTR)?1:0);
72   m_port0->tx_w((data & PSX_SIO_OUT_DATA)?1:0);
73   m_port0->clock_w((data & PSX_SIO_OUT_CLOCK)?1:0); // clock must be last
74
75   m_port1->tx_w((data & PSX_SIO_OUT_DATA)?1:0);
76   m_port1->sel_w((data & PSX_SIO_OUT_DTR)?0:1); // not dtr
77   m_port1->clock_w((data & PSX_SIO_OUT_CLOCK)?1:0);
78
79   data_out(((m_port0->rx_r() && m_port1->rx_r()) * PSX_SIO_IN_DATA), PSX_SIO_IN_DATA);
80}
81
82void psxcontrollerports_device::ack()
83{
84   data_out((!(m_port0->ack_r() && m_port1->ack_r()) * PSX_SIO_IN_DSR), PSX_SIO_IN_DSR);
85}
86
87device_psx_controller_interface::device_psx_controller_interface(const machine_config &mconfig, device_t &device) :
88      device_slot_card_interface(mconfig, device),
89      m_ack(true)
90{
91}
92
93device_psx_controller_interface::~device_psx_controller_interface()
94{
95}
96
97void device_psx_controller_interface::interface_pre_reset()
98{
99   m_bit = 0;
100   m_count = 0;
101   m_idata = 0;
102   m_memcard = false;
103
104   m_clock = true;
105   m_sel = true;
106   m_rx = true;
107   m_ack = true;
108   m_owner->ack();
109}
110
111void device_psx_controller_interface::interface_pre_start()
112{
113   m_owner = dynamic_cast<psx_controller_port_device *>(device().owner());
114   m_ack_timer = device().machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(device_psx_controller_interface::ack_timer), this));
115}
116
117void device_psx_controller_interface::ack_timer(void *ptr, int param)
118{
119   m_ack = param;
120   m_owner->ack();
121
122   if(!param)
123      m_ack_timer->adjust(attotime::from_usec(2), 1);
124}
125
126void device_psx_controller_interface::do_pad()
127{
128   if(!m_bit)
129   {
130      if(!m_count)
131         m_odata = 0xff;
132      m_idata = 0;
133   }
134
135   m_rx = (m_odata & (1 << m_bit)) ? true : false;
136   m_idata |= (m_owner->tx_r()?1:0) << m_bit;
137   m_bit = (m_bit + 1) % 8;
138
139   if(!m_bit)
140   {
141      if((!m_count) && (m_idata & 0xf0))
142      {
143            m_memcard = true;
144            return;
145      }
146
147      if(get_pad(m_count++, &m_odata, m_idata))
148         m_ack_timer->adjust(attotime::from_usec(10), 0);
149      else
150         m_count = 0;
151   }
152}
153
154void device_psx_controller_interface::sel_w(bool state) {
155   if(state && !m_sel)
156      interface_pre_reset(); // don't reset the controller, just the interface
157   m_sel = state;
158}
159
160const device_type PSX_STANDARD_CONTROLLER = &device_creator<psx_standard_controller_device>;
161
162psx_standard_controller_device::psx_standard_controller_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
163      device_t(mconfig, PSX_STANDARD_CONTROLLER, "Playstation Standard Controller", tag, owner, clock, "psx_standard_controller", __FILE__),
164      device_psx_controller_interface(mconfig, *this),
165      m_pad0(*this,"PSXPAD0"),
166      m_pad1(*this,"PSXPAD1")
167{
168}
169
170bool psx_standard_controller_device::get_pad(int count, UINT8 *odata, UINT8 idata)
171{
172   switch(count)
173   {
174      case 0:
175         *odata = 0x41;
176         break;
177      case 1:
178         if(idata != QUERY_PAD_STATE)
179            return false;
180         *odata = 0x5a;
181         break;
182      case 2:
183         *odata = m_pad0->read();
184         break;
185      case 3:
186         *odata = m_pad1->read();
187         break;
188      case 4:
189         return false;
190   }
191   return true;
192}
193
194static INPUT_PORTS_START( psx_standard_controller )
195   PORT_START("PSXPAD0")
196   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
197   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
198   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
199   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP )
200   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START )
201   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
202   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
203   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SELECT )
204
205   PORT_START("PSXPAD1")
206   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Square")
207   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Cross")
208   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Circle")
209   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Triangle")
210   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("R1")
211   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("L1")
212   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("R2")
213   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("L2")
214INPUT_PORTS_END
215
216ioport_constructor psx_standard_controller_device::device_input_ports() const
217{
218   return INPUT_PORTS_NAME(psx_standard_controller);
219}
trunk/src/mess/machine/psxcport.h
r241419r241420
1#pragma once
2
3#ifndef __PSXCPORT_H__
4#define __PSXCPORT_H__
5
6#include "cpu/psx/siodev.h"
7#include "machine/psxcard.h"
8
9#define MCFG_PSX_CTRL_PORT_ADD(_tag, _slot_intf, _def_slot) \
10   MCFG_DEVICE_ADD(_tag, PSX_CONTROLLER_PORT, 0) \
11   MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
12
13SLOT_INTERFACE_EXTERN(psx_controllers);
14
15extern const device_type PSXCONTROLLERPORTS;
16extern const device_type PSX_CONTROLLER_PORT;
17extern const device_type PSX_STANDARD_CONTROLLER;
18
19class psx_controller_port_device;
20
21class device_psx_controller_interface : public device_slot_card_interface
22{
23   friend class psx_multitap_device;
24public:
25   device_psx_controller_interface(const machine_config &mconfig, device_t &device);
26   virtual ~device_psx_controller_interface();
27
28   void clock_w(bool state) { if(m_clock && !m_sel && !state && !m_memcard) do_pad(); m_clock = state; }
29   void sel_w(bool state);
30
31   bool rx_r() { return m_rx; }
32   bool ack_r() { return m_ack; }
33
34protected:
35   virtual void interface_pre_reset();
36   virtual void interface_pre_start();
37
38   enum
39   {
40      QUERY_PAD_STATE = 0x42,
41      CONFIG_MODE = 0x43,
42   };
43
44private:
45   virtual bool get_pad(int count, UINT8 *odata, UINT8 idata) = 0;
46   virtual void do_pad();
47   void ack_timer(void *ptr, int param);
48
49   UINT8 m_odata;
50   UINT8 m_idata;
51   int m_bit;
52   int m_count;
53   bool m_memcard;
54
55   bool m_clock;
56   bool m_sel;
57   bool m_ack;
58   bool m_rx;
59
60   emu_timer *m_ack_timer;
61   psx_controller_port_device *m_owner;
62};
63
64class psx_standard_controller_device :  public device_t,
65                              public device_psx_controller_interface
66{
67public:
68   psx_standard_controller_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
69
70   virtual ioport_constructor device_input_ports() const;
71
72protected:
73   virtual void device_start() { }
74private:
75   virtual bool get_pad(int count, UINT8 *odata, UINT8 idata);
76
77   required_ioport m_pad0;
78   required_ioport m_pad1;
79};
80
81class psxcontrollerports_device : public psxsiodev_device
82{
83public:
84   psxcontrollerports_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
85   void ack();
86
87protected:
88   virtual void device_start();
89
90private:
91   virtual void data_in(int data, int mask);
92
93   psx_controller_port_device *m_port0;
94   psx_controller_port_device *m_port1;
95};
96
97class psx_controller_port_device :  public device_t,
98                           public device_slot_interface
99{
100public:
101   psx_controller_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
102   virtual machine_config_constructor device_mconfig_additions() const;
103
104   typedef delegate<void ()> void_cb;
105   void ack() { if(!ack_cb.isnull()) ack_cb(); }
106   void setup_ack_cb(void_cb cb) { ack_cb = cb; }
107
108   DECLARE_WRITE_LINE_MEMBER(tx_w) { m_tx = state; }
109   DECLARE_WRITE_LINE_MEMBER(sel_w) { if(m_dev) m_dev->sel_w(state); m_card->sel_w(state); }
110   DECLARE_WRITE_LINE_MEMBER(clock_w) { if(m_dev) m_dev->clock_w(state); m_card->clock_w(state); }
111
112   DECLARE_READ_LINE_MEMBER(rx_r) { return (m_dev?m_dev->rx_r():true) && m_card->rx_r(); }
113   DECLARE_READ_LINE_MEMBER(ack_r) { return (m_dev?m_dev->ack_r():true) && m_card->ack_r(); }
114   DECLARE_READ_LINE_MEMBER(tx_r) { return m_tx; }
115
116   void disable_card(bool status);
117
118protected:
119   virtual void device_start() {}
120   virtual void device_reset() { m_tx = true; }
121   virtual void device_config_complete();
122
123private:
124   void_cb ack_cb;
125   bool m_tx;
126
127   device_psx_controller_interface *m_dev;
128   required_device<psxcard_device> m_card;
129};
130#endif
trunk/src/mess/machine/psxmultitap.c
r241419r241420
1// psx multitap emulation
2
3#include "machine/psxmultitap.h"
4
5const device_type PSX_MULTITAP = &device_creator<psx_multitap_device>;
6
7psx_multitap_device::psx_multitap_device(const machine_config& mconfig, const char* tag, device_t* owner, UINT32 clock) :
8   device_t(mconfig, PSX_MULTITAP, "Playstation Multitap", tag, owner, clock, "psx_multitap", __FILE__),
9   device_psx_controller_interface(mconfig, *this),
10   m_porta(*this, "a"),
11   m_portb(*this, "b"),
12   m_portc(*this, "c"),
13   m_portd(*this, "d")
14{
15}
16
17static MACHINE_CONFIG_FRAGMENT( psx_multitap )
18   MCFG_PSX_CTRL_PORT_ADD("a", psx_controllers_nomulti, "digital_pad")
19   MCFG_PSX_CTRL_PORT_ADD("b", psx_controllers_nomulti, NULL)
20   MCFG_PSX_CTRL_PORT_ADD("c", psx_controllers_nomulti, NULL)
21   MCFG_PSX_CTRL_PORT_ADD("d", psx_controllers_nomulti, NULL)
22MACHINE_CONFIG_END
23
24machine_config_constructor psx_multitap_device::device_mconfig_additions() const
25{
26   return MACHINE_CONFIG_NAME( psx_multitap );
27}
28
29void psx_multitap_device::device_start()
30{
31   m_porta->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psx_multitap_device::ack), this));
32   m_portb->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psx_multitap_device::ack), this));
33   m_portc->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psx_multitap_device::ack), this));
34   m_portd->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psx_multitap_device::ack), this));
35   m_nextmode = false;
36
37   save_item(NAME(m_activeport));
38   save_item(NAME(m_cack));
39   save_item(NAME(m_singlemode));
40   save_item(NAME(m_nextmode));
41   save_item(NAME(m_tapmc));
42   save_item(NAME(m_data));
43}
44
45void psx_multitap_device::interface_pre_reset()
46{
47   m_activeport = -1;
48   m_singlemode = m_nextmode;
49   m_tapmc = false;
50   m_cack[0] = m_cack[1] = m_cack[2] = m_cack[3] = true;
51   memset(m_data, 0xff, sizeof(m_data));
52   m_porta->sel_w(false);
53   m_portb->sel_w(false);
54   m_portc->sel_w(false);
55   m_portd->sel_w(false);
56   m_porta->sel_w(true);
57   m_portb->sel_w(true);
58   m_portc->sel_w(true);
59   m_portd->sel_w(true);
60   device_psx_controller_interface::interface_pre_reset();
61}
62
63void psx_multitap_device::set_tx_line(bool tx, int port)
64{
65   psx_controller_port_device *dev;
66   switch(port)
67   {
68      default:
69      case 0:
70         dev = m_porta;
71         break;
72      case 1:
73         dev = m_portb;
74         break;
75      case 2:
76         dev = m_portc;
77         break;
78      case 3:
79         dev = m_portd;
80         break;
81   }
82   dev->clock_w(1);
83   dev->tx_w(tx);
84   dev->clock_w(0);
85}
86
87bool psx_multitap_device::get_rx_line(int port)
88{
89   psx_controller_port_device *dev;
90   switch(port)
91   {
92      default:
93      case 0:
94         dev = m_porta;
95         break;
96      case 1:
97         dev = m_portb;
98         break;
99      case 2:
100         dev = m_portc;
101         break;
102      case 3:
103         dev = m_portd;
104         break;
105   }
106   return dev->rx_r();
107}
108
109void psx_multitap_device::do_pad()
110{
111   bool tx = device_psx_controller_interface::m_owner->tx_r();
112
113   // we don't know which controller until after the first byte
114   if((m_singlemode || m_tapmc) && (m_count >= 1))
115   {
116      if((m_count == 2) && !m_bit && !m_tapmc)
117         m_nextmode = !tx;
118
119      set_tx_line(tx, m_activeport);
120      m_rx = get_rx_line(m_activeport);
121      m_bit = (m_bit + 1) % 8;
122      if(!m_bit)
123         m_count++;
124      return;
125   }
126
127   if(!m_count)
128   {
129      // first send the select byte to all devices until we know whether it's accessing
130      // a controller or memcard
131      if(!m_bit)
132      {
133         m_porta->sel_w(false);
134         m_portb->sel_w(false);
135         m_portc->sel_w(false);
136         m_portd->sel_w(false);
137      }
138      device_psx_controller_interface::do_pad();
139      set_tx_line(tx, 0);
140      set_tx_line(tx, 1);
141      set_tx_line(tx, 2);
142      set_tx_line(tx, 3);
143      if(!m_bit)
144      {
145         m_count = 1;
146         m_tapmc = m_memcard;
147         m_memcard = false; // make sure we still receive clocks
148         if(m_singlemode || m_tapmc)
149         {
150            m_activeport = (m_idata & 0xf) - 1;
151            m_porta->sel_w((m_activeport == 0) ? false : true);
152            m_portb->sel_w((m_activeport == 1) ? false : true);
153            m_portc->sel_w((m_activeport == 2) ? false : true);
154            m_portd->sel_w((m_activeport == 3) ? false : true);
155         }
156      }
157      return;
158   }
159   else if(m_count <= 2)
160      return device_psx_controller_interface::do_pad();
161   else if(m_count < 11)
162   {
163      if((m_count == 3) && !m_bit)
164         m_nextmode = !m_idata;
165
166      if((m_count < 5) && m_cack[0] && m_cack[1] && m_cack[2] && m_cack[3])
167         return; // no acks? hang up.
168
169      // all of the ports are polled here, port a is passed though.  the data
170      // from the other ports is stored and can be retrieved at a much higher clock rate
171      // don't poll a port that is inactive or done
172      if(!m_cack[0])
173      {
174         set_tx_line(tx, 0);
175         m_rx = m_porta->rx_r();
176      }
177      else
178      {
179         m_rx = true;
180         m_porta->sel_w(true);
181      }
182
183      if(!m_cack[1])
184      {
185         set_tx_line(tx, 1);
186         m_data[0][m_count - 3] &= ~(!m_portb->rx_r() << m_bit);
187      }
188      else
189         m_portb->sel_w(true);
190
191      if(!m_cack[2])
192      {
193         set_tx_line(tx, 2);
194         m_data[1][m_count - 3] &= ~(!m_portc->rx_r() << m_bit);
195      }
196      else
197         m_portc->sel_w(true);
198
199      if(!m_cack[3])
200      {
201         set_tx_line(tx, 3);
202         m_data[2][m_count - 3] &= ~(!m_portd->rx_r() << m_bit);
203      }
204      else
205         m_portd->sel_w(true);
206   }
207   else if(m_count < 19)
208      // send stored port b data
209      m_rx = ((m_data[0][m_count - 11] & (1 << m_bit)) ? 1 : 0);
210   else if(m_count < 27)
211      // send stored port c data
212      m_rx = ((m_data[1][m_count - 19] & (1 << m_bit)) ? 1 : 0);
213   else
214      // send stored port d data
215      m_rx = ((m_data[2][m_count - 27] & (1 << m_bit)) ? 1 : 0);
216
217   if(m_bit == 7)
218   {
219      // ports won't ack if they are done
220      m_cack[0] = m_cack[1] = m_cack[2] = m_cack[3] = true;
221      if(m_count < 11)
222         m_ack_timer->adjust(attotime::from_usec(12), 0); // give a bit of time for the ports to ack
223      else if(m_count < 35)
224         m_ack_timer->adjust(attotime::from_usec(10), 0);
225   }
226
227   m_bit = (m_bit + 1) % 8;
228   if(!m_bit)
229      m_count++;
230}
231
232bool psx_multitap_device::get_pad(int count, UINT8 *odata, UINT8 idata)
233{
234   if(!count)
235      *odata = 0x80;
236   else
237      *odata = 0x5a;
238   return true;
239}
240
241void psx_multitap_device::ack()
242{
243   if(m_activeport != -1)
244   {
245      switch(m_activeport)
246      {
247         case 0:
248            m_ack = m_porta->ack_r();
249            break;
250         case 1:
251            m_ack = m_portb->ack_r();
252            break;
253         case 2:
254            m_ack = m_portc->ack_r();
255            break;
256         case 3:
257            m_ack = m_portd->ack_r();
258            break;
259         default:
260            return;
261      }
262      device_psx_controller_interface::m_owner->ack();
263      return;
264   }
265   if(!m_porta->ack_r())
266      m_cack[0] = false;
267   if(!m_portb->ack_r())
268      m_cack[1] = false;
269   if(!m_portc->ack_r())
270      m_cack[2] = false;
271   if(!m_portd->ack_r())
272      m_cack[3] = false;
273}
trunk/src/mess/machine/psxmultitap.h
r241419r241420
1#ifndef PSXMULTITAP_H_
2#define PSXMULTITAP_H_
3
4#include "machine/psxcport.h"
5
6SLOT_INTERFACE_EXTERN(psx_controllers_nomulti);
7
8class psx_multitap_device : public device_t,
9                     public device_psx_controller_interface
10{
11public:
12   psx_multitap_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
13   virtual machine_config_constructor device_mconfig_additions() const;
14
15protected:
16   virtual void device_start();
17   virtual void device_stop() { device_psx_controller_interface::m_owner->disable_card(false); }
18   virtual void device_reset() { device_psx_controller_interface::m_owner->disable_card(true); }
19   virtual void device_config_complete() { m_shortname = "psx_multitap"; }
20   virtual void interface_pre_reset();
21
22private:
23   virtual bool get_pad(int count, UINT8 *odata, UINT8 idata);
24   virtual void do_pad();
25   void ack();
26   void set_tx_line(bool tx, int port);
27   bool get_rx_line(int port);
28
29   int m_activeport;
30   bool m_cack[4];
31   bool m_singlemode, m_nextmode, m_tapmc;
32   UINT8 m_data[3][8]; // port a is passed though
33   required_device<psx_controller_port_device> m_porta;
34   required_device<psx_controller_port_device> m_portb;
35   required_device<psx_controller_port_device> m_portc;
36   required_device<psx_controller_port_device> m_portd;
37};
38
39extern const device_type PSX_MULTITAP;
40
41#endif /* PSXMULTITAP_H_ */
trunk/src/mess/mess.mak
r241419r241420
613613BUSES += PC_KBD
614614BUSES += PET
615615BUSES += PLUS4
616BUSES += PSX_CONTROLLER
616617BUSES += QL
617618BUSES += RS232
618619BUSES += S100
r241419r241420
16201621   $(MESS_DRIVERS)/ngp.o $(MESS_VIDEO)/k1ge.o \
16211622
16221623$(MESSOBJ)/sony.a:              \
1623   $(MESS_DRIVERS)/pockstat.o $(MESS_DRIVERS)/psx.o $(MESS_MACHINE)/psxanalog.o $(MESS_MACHINE)/psxcard.o $(MESS_MACHINE)/psxcd.o $(MESS_MACHINE)/psxcport.o $(MESS_MACHINE)/psxmultitap.o \
1624   $(MESS_DRIVERS)/pockstat.o $(MESS_DRIVERS)/psx.o $(MESS_MACHINE)/psxcd.o \
16241625   $(MESS_DRIVERS)/pve500.o    \
16251626   $(MESS_DRIVERS)/smc777.o    \
16261627


Previous 199869 Revisions Next


© 1997-2024 The MAME Team