PS2SDK
PS2 Homebrew Libraries
librm.c
Go to the documentation of this file.
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # Copyright 2001-2004, ps2dev - http://www.ps2dev.org
7 # Licenced under Academic Free License version 2.0
8 # Review ps2sdk README & LICENSE files for further details.
9 */
10 
16 #include <stdio.h>
17 #include <tamtypes.h>
18 #include <sifrpc.h>
19 #include <kernel.h>
20 #include <string.h>
21 #include <iopcontrol.h>
22 #include "librm.h"
23 
24 static SifRpcClientData_t rmmanif __attribute__((aligned(64)));
25 static struct rmRpcPacket buffer __attribute__((aligned(64)));
26 static int rmman_type;
27 
28 struct port_state
29 {
30  int opened;
31  struct rmEEData *rmData;
32 };
33 
34 static struct port_state ports[2];
35 
36 static struct rmEEData *rmGetDmaStr(int port, int slot)
37 {
38  struct rmEEData *pdata;
39 
40  (void)slot;
41 
42  pdata = ports[port].rmData;
43  SyncDCache(pdata, (u8 *)pdata + 256);
44 
45  if (pdata[0].frame < pdata[1].frame)
46  {
47  return &pdata[1];
48  }
49  else
50  {
51  return &pdata[0];
52  }
53 }
54 
55 static void RMMan_Cleanup(void)
56 {
57  memset(&rmmanif, 0, sizeof(rmmanif));
58  rmman_type = 0;
59 }
60 
61 int RMMan_Init(void)
62 {
63  int i;
65  RMMan_Cleanup();
66 
67  if (rmmanif.server)
68  {
69  printf("RMMan Library already initialised\n");
70  return 0;
71  }
72 
73  {
74  SifRpcClientData_t rpciftmp[3] __attribute__((aligned(64)));
75  int rpc_ids[3] = {
76  RMMANX_RPC_ID,
77  RMMAN2_RPC_ID,
78  RMMAN_RPC_ID,
79  };
80 
81  rmmanif.server = NULL;
82  for (i = 0; i < (int)(sizeof(rpc_ids)/sizeof(rpc_ids[0])); i += 1)
83  {
84  rpciftmp[i].server = NULL;
85  }
86 
87  for (;;)
88  {
89  for (i = 0; i < (int)(sizeof(rpc_ids)/sizeof(rpc_ids[0])); i += 1)
90  {
91  if ((sceSifBindRpc(&rpciftmp[i], rpc_ids[i], 0) < 0))
92  {
93  return -1;
94  }
95  if (rpciftmp[i].server != NULL)
96  {
97  switch (rpc_ids[i])
98  {
99  case RMMANX_RPC_ID:
100  case RMMAN2_RPC_ID:
101  {
102  rmman_type = 2;
103  break;
104  }
105  case RMMAN_RPC_ID:
106  {
107  rmman_type = 1;
108  break;
109  }
110  default:
111  {
112  break;
113  }
114  }
115  memcpy(&rmmanif, &rpciftmp[i], sizeof(rmmanif));
116  break;
117  }
118  }
119  if (rmmanif.server != NULL)
120  {
121  break;
122  }
123  nopdelay();
124  }
125  }
126 
127  if (rmman_type == 0)
128  {
129  return -1;
130  }
131 
132  buffer.cmd.command = (rmman_type == 2) ? RMMAN2_RPCFUNC_INIT : RMMAN_RPCFUNC_INIT;
133 
134  if (sceSifCallRpc(&rmmanif, 0, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
135  {
136  rmman_type = 0;
137  return -1;
138  }
139 
140  for (i = 0; i < (int)(sizeof(ports)/sizeof(ports[0])); i += 1)
141  {
142  ports[i].opened = 0;
143  ports[i].rmData = NULL;
144  }
145 
146  switch (rmman_type)
147  {
148  case 1:
149  return buffer.cmd.u.cmd1.result;
150  case 2:
151  return buffer.cmd.u.cmd2.result;
152  default:
153  return 0;
154  }
155 }
156 
158 {
159  buffer.cmd.command = (rmman_type == 2) ? RMMAN2_RPCFUNC_VERSION : RMMAN_RPCFUNC_VERSION;
160 
161  if (sceSifCallRpc(&rmmanif, 0, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
162  {
163  return 0;
164  }
165 
166  switch (rmman_type)
167  {
168  case 1:
169  return buffer.cmd.u.cmd1.result;
170  case 2:
171  return buffer.cmd.u.cmd2.result;
172  default:
173  return 0;
174  }
175 }
176 
177 int RMMan_Open(int port, int slot, void *pData)
178 {
179  if ((port < 0) || (port > 1) || (slot != 0))
180  {
181  printf("Error, port must be 0 or 1 and slot set to 0\n");
182  return 0;
183  }
184 
185  if ((u32)pData & 0x3F)
186  {
187  printf("Error, pData not aligned to 64byte boundary");
188  return 0;
189  }
190 
191  if (rmman_type != 1 && port != 0)
192  {
193  port = 0;
194  }
195 
196  buffer.cmd.command = (rmman_type == 2) ? RMMAN2_RPCFUNC_OPEN : RMMAN_RPCFUNC_OPEN;
197  switch (rmman_type)
198  {
199  case 1:
200  {
201  buffer.cmd.u.cmd1.port = port;
202  buffer.cmd.u.cmd1.slot = slot;
203  buffer.cmd.u.cmd1.data = pData;
204  break;
205  }
206  case 2:
207  {
208  buffer.cmd.u.cmd2.data = pData;
209  break;
210  }
211  default:
212  {
213  break;
214  }
215  }
216 
217  if (sceSifCallRpc(&rmmanif, 0, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
218  {
219  return 0;
220  }
221 
222  ports[port].opened = 1;
223  ports[port].rmData = pData;
224 
225  switch (rmman_type)
226  {
227  case 1:
228  return buffer.cmd.u.cmd1.result;
229  case 2:
230  return buffer.cmd.u.cmd2.result;
231  default:
232  return 0;
233  }
234 }
235 
236 int RMMan_End(void)
237 {
238  buffer.cmd.command = (rmman_type == 2) ? RMMAN2_RPCFUNC_END : RMMAN_RPCFUNC_END;
239 
240  if (sceSifCallRpc(&rmmanif, 0, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
241  {
242  return 0;
243  }
244 
245  switch (rmman_type)
246  {
247  case 1:
248  return buffer.cmd.u.cmd1.result;
249  case 2:
250  return buffer.cmd.u.cmd2.result;
251  default:
252  return 0;
253  }
254 }
255 
256 int RMMan_Close(int port, int slot)
257 {
258  if ((port < 0) || (port > 1) || (slot != 0))
259  {
260  printf("Error, port must be 0 or 1 and slot set to 0\n");
261  return 0;
262  }
263 
264  if (rmman_type != 1 && port != 0)
265  {
266  port = 0;
267  }
268 
269  if (!ports[port].opened)
270  {
271  return 0;
272  }
273 
274  buffer.cmd.command = (rmman_type == 2) ? RMMAN2_RPCFUNC_CLOSE : RMMAN_RPCFUNC_CLOSE;
275  switch (rmman_type)
276  {
277  case 1:
278  {
279  buffer.cmd.u.cmd1.port = port;
280  buffer.cmd.u.cmd1.slot = slot;
281  break;
282  }
283  default:
284  {
285  break;
286  }
287  }
288 
289  if (sceSifCallRpc(&rmmanif, 0, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
290  {
291  return 0;
292  }
293 
294  switch (rmman_type)
295  {
296  case 1:
297  return buffer.cmd.u.cmd1.result;
298  case 2:
299  return buffer.cmd.u.cmd2.result;
300  default:
301  return 0;
302  }
303 }
304 
305 void RMMan_Read(int port, int slot, struct remote_data *data)
306 {
307  const struct rmEEData *pdata;
308 
309  if ((port < 0) || (port > 1) || (slot != 0))
310  {
311  printf("Error, port must be 0 or 1 and slot set to 0\n");
312  return;
313  }
314 
315  if (rmman_type != 1 && port != 0)
316  {
317  port = 0;
318  }
319 
320  pdata = rmGetDmaStr(port, slot);
321 
322  if (rmman_type == 2)
323  {
324  int status;
325  int button;
326  status = RM_READY;
327  button = 0;
328  if (pdata->data[0] == 0x14)
329  {
330  status = RM_KEYPRESSED;
331  button = pdata->data[1] | (pdata->data[2] << 8) | (pdata->data[3] << 16);
332  }
333  data->status = status;
334  data->button = button;
335  }
336  else
337  {
338  memcpy(data, pdata->data, 8);
339  }
340 }
kernel.h
RMMan_Open
int RMMan_Open(int port, int slot, void *pData)
Definition: librm.c:177
port_state
Definition: librm.c:28
rmRpcPacket
Definition: librm-common.h:21
RMMan_End
int RMMan_End(void)
Ends all remote communication.
Definition: librm.c:236
RMMan_Init
int RMMan_Init(void)
Initialise librm.
Definition: librm.c:61
remote_data
Definition: librm.h:21
rmEEData
Definition: librm-common.h:47
iopcontrol.h
librm.h
RPC Interface for PS2 Remote Control Driver (RMMAN)
RMMan_Close
int RMMan_Close(int port, int slot)
Closes an opened port.
Definition: librm.c:256
tamtypes.h
HasIopRebootedSinceLastCall
static int HasIopRebootedSinceLastCall(void)
Definition: iopcontrol.h:47
stdio.h
t_SifRpcClientData
Definition: sifrpc-common.h:134
RMMan_Read
void RMMan_Read(int port, int slot, struct remote_data *data)
Read remote data.
Definition: librm.c:305
__attribute__
Definition: gif_registers.h:38
RMMan_GetModuleVersion
u32 RMMan_GetModuleVersion(void)
Returns the rmman.irx version.
Definition: librm.c:157