PS2SDK
PS2 Homebrew Libraries
intr.c
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # Copyright 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 
11 #include "accore_internal.h"
12 
13 static acUint8 masks_8[3] = {128u, 2u, 64u};
14 static struct intr_softc Intrc ={0,1};
15 
16 static int intr_intr(void *arg)
17 {
18  struct intr_softc *argt;
19 
20  argt = (struct intr_softc *)arg;
21  if ( argt )
22  {
23  int index;
24  struct intr_handler *v2;
25  int sr;
26 
27  index = 2;
28  v2 = &argt->handlers[1];
29  sr = (*((volatile acUint16 *)0xB241C000) & 0xFF00) >> 8;
30  while ( index >= 0 )
31  {
32  if ( masks_8[index] && masks_8[index] == ((sr & masks_8[index]) & 0xFF) && v2->func )
33  v2->func(v2->arg);
34  --index;
35  --v2;
36  }
37  }
38  return 1;
39 }
40 
41 int acIntrClear(acIntrNum inum)
42 {
43  acUint16 *v2;
44 
45  if ( inum == AC_INTR_NUM_ATA )
46  {
47  v2 = (acUint16 *)0xB3000000;
48  *v2 = 0;
49  }
50  if ( inum == AC_INTR_NUM_UART )
51  {
52  v2 = (acUint16 *)0xB3100000;
53  *v2 = 0;
54  }
55  return 0;
56 }
57 
58 int acIntrEnable(acIntrNum inum)
59 {
60  acUint32 enable;
61 
62  if ( (unsigned int)inum >= (AC_INTR_NUM_LAST | AC_INTR_NUM_JV) )
63  return -22;
64  enable = Intrc.enable;
65  Intrc.enable |= 1 << inum;
66  if ( inum )
67  {
68  if ( inum == AC_INTR_NUM_UART )
69  *((volatile acUint16 *)0xB241511E) = 0;
70  }
71  else
72  {
73  *((volatile acUint16 *)0xB241510C) = 0;
74  *((volatile acUint16 *)0xB3000000) = 0;
75  }
76  if ( !enable )
77  {
78  switch ( EnableIntr(13) )
79  {
80  case 0:
81  return 0;
82  default:
83  return -22;
84  }
85  }
86  return 0;
87 }
88 
89 int acIntrDisable(acIntrNum inum)
90 {
91  int v1;
92  acUint32 enable;
93  int old_status;
94 
95  if ( (unsigned int)inum >= (AC_INTR_NUM_LAST | AC_INTR_NUM_JV) )
96  return -22;
97  if ( inum == AC_INTR_NUM_ATA )
98  {
99  *((volatile acUint16 *)0xB241510C) = 0;
100  }
101  if ( inum == AC_INTR_NUM_UART )
102  {
103  *((volatile acUint16 *)0xB241511C) = 0;
104  }
105  v1 = 1 << inum;
106  Intrc.enable &= ~v1;
107  if ( Intrc.enable )
108  return 0;
109  enable = DisableIntr(13, &old_status);
110  if ( enable != (acUint32)-103 )
111  {
112  if ( !enable )
113  return 0;
114  return -22;
115  }
116  return 1;
117 }
118 
119 int acIntrRegister(acIntrNum inum, acIntrHandler func, void *arg)
120 {
121  char v3;
122  struct intr_handler *handler;
123  acUint32 active;
124  acSpl state;
125 
126  v3 = inum;
127  handler = &Intrc.handlers[inum];
128  if ( (unsigned int)inum >= (AC_INTR_NUM_LAST | AC_INTR_NUM_JV) )
129  return -22;
130  if ( handler->func )
131  return -11;
132  CpuSuspendIntr(&state);
133  active = Intrc.active;
134  handler->func = func;
135  handler->arg = arg;
136  Intrc.active = active | (1 << v3);
137  CpuResumeIntr(state);
138  if ( !active )
139  {
140  switch ( RegisterIntrHandler(13, 1, intr_intr, Intrc.handlers) )
141  {
142  case -104:
143  return -11;
144  case -100:
145  return -4;
146  case 0:
147  return 0;
148  default:
149  return -22;
150  }
151  }
152  return 0;
153 }
154 
155 int acIntrRelease(acIntrNum inum)
156 {
157  char v1;
158  struct intr_handler *handler;
159  acUint32 active;
160  acUint32 active_v5;
161  acSpl state;
162 
163  v1 = inum;
164  handler = &Intrc.handlers[inum];
165  if ( (unsigned int)inum >= (AC_INTR_NUM_LAST | AC_INTR_NUM_JV) )
166  return -22;
167  if ( !handler->func )
168  {
169  return -2;
170  }
171  CpuSuspendIntr(&state);
172  active = Intrc.active;
173  handler->func = 0;
174  handler->arg = 0;
175  active_v5 = active & ~(1 << v1);
176  Intrc.active = active_v5;
177  CpuResumeIntr(state);
178  if ( !active_v5 )
179  {
180  switch ( ReleaseIntrHandler(13) )
181  {
182  case -100:
183  return -4;
184  case -101:
185  return -22;
186  case 0:
187  return 0;
188  default:
189  return -2;
190  }
191  }
192  return 0;
193 }
194 
195 int acIntrModuleStart(int argc, char **argv)
196 {
197  int index;
198  int v4;
199  int state;
200 
201  (void)argc;
202  (void)argv;
203  if ( Intrc.active != 0 || !Intrc.enable )
204  {
205  return -16;
206  }
207  CpuSuspendIntr(&state);
208  index = 2;
209  v4 = 24;
210  while ( index >= 0 )
211  {
212  acUint32 *v5;
213 
214  v5 = (acUint32 *)((char *)&Intrc.active + v4);
215  v4 -= 8;
216  --index;
217  *v5 = 0;
218  v5[1] = 0;
219  }
220  CpuResumeIntr(state);
221  Intrc.enable = 0;
222  Intrc.active = 0;
223  return 0;
224 }
225 
226 int acIntrModuleStop()
227 {
228  int v1;
229 
230  DisableIntr(13, &v1);
231  ReleaseIntrHandler(13);
232  Intrc.enable = 0;
233  Intrc.active = 0;
234  return 0;
235 }
236 
237 int acIntrModuleRestart(int argc, char **argv)
238 {
239  (void)argc;
240  (void)argv;
241 
242  return -88;
243 }
244 
245 int acIntrModuleStatus()
246 {
247  int ret;
248  int state;
249 
250  CpuSuspendIntr(&state);
251  if ( Intrc.enable )
252  ret = 2;
253  else
254  ret = Intrc.active != 0;
255  CpuResumeIntr(state);
256  return ret;
257 }
RegisterIntrHandler
int RegisterIntrHandler(int irq, int mode, int(*handler)(void *arg), void *arg)
Definition: intrman.c:115
ReleaseIntrHandler
int ReleaseIntrHandler(int irq)
Definition: intrman.c:157
DisableIntr
int DisableIntr(int irq, int *res)
Definition: intrman.c:385
CpuSuspendIntr
int CpuSuspendIntr(int *state)
Definition: intrman.c:195
EnableIntr
int EnableIntr(int irq)
Definition: intrman.c:336
intr_handler
Definition: accore_internal.h:26
intr_softc
Definition: accore_internal.h:32
CpuResumeIntr
int CpuResumeIntr(int state)
Definition: intrman.c:217