PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
sbusintr.c
Go to the documentation of this file.
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright (c) 2003 Marcus R. Brown <mrbrown@0xd6.org>
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
16#include "types.h"
17#include "defs.h"
18#include "irx.h"
19
20#include "loadcore.h"
21#include "intrman.h"
22#include "sifman.h"
23#include "sbusintr.h"
24
25IRX_ID("sbusintr", 1, 1);
26
27static struct {
28 sbus_intr_handler_t handler;
29 void *arg;
30} sbus_handler_table[32];
31
32extern struct irx_export_table _exp_sbusintr;
33
34int _start(int argc, char *argv[])
35{
36 (void)argc;
37 (void)argv;
38
39 if (RegisterLibraryEntries(&_exp_sbusintr) != 0)
40 return MODULE_NO_RESIDENT_END;
41
42 return MODULE_RESIDENT_END;
43}
44
45static int sbus_dispatch(void *arg)
46{
47 u32 msflag, irq;
48
49 (void)arg;
50
51 if (!(msflag = sceSifGetMSFlag()))
52 return 1;
53
54 for (irq = 0; msflag != 0 && irq < 32; irq++, msflag >>= 1) {
55 if (!(msflag & 1))
56 continue;
57
58 /* "Acknowledge" the interrupt */
59 sceSifSetMSFlag(1 << irq);
60
61 if (sbus_handler_table[irq].handler)
62 sbus_handler_table[irq].handler(irq,
63 sbus_handler_table[irq].arg);
64 }
65
66 return 1;
67}
68
69int sbus_intr_handler_add(u32 irq, sbus_intr_handler_t handler, void *arg)
70{
71 int res = irq, state = 0;
72
73 /* I hope this correct... */
74 CpuSuspendIntr(&state);
75
76 if (irq > 31) {
77 res = -SBUS_E_ARG;
78 goto out;
79 }
80
81 if (sbus_handler_table[irq].handler) {
82 res = -SBUS_E_IRQ;
83 goto out;
84 }
85
86 sbus_handler_table[irq].handler = handler;
87 sbus_handler_table[irq].arg = arg;
88out:
89 CpuResumeIntr(state);
90 return res;
91}
92
93int sbus_intr_handler_del(u32 irq)
94{
95 if (irq > 31)
96 return -SBUS_E_ARG;
97
98 sbus_handler_table[irq].handler = NULL;
99 sbus_handler_table[irq].arg = NULL;
100
101 return irq;
102}
103
104void sbus_intr_main_interrupt(u32 irq)
105{
106 u32 flag = 1 << irq;
107
108 if (irq > 31 || (sceSifGetSMFlag() & flag))
109 return;
110
111 sceSifSetSMFlag(flag);
112 sceSifIntrMain();
113}
114
115static int initialized = 0;
116
117/*
118 * - Register SBUS handler
119 * - Clear handler table
120 */
121int sbus_intr_init()
122{
123 int i, state, res = 0;
124
125 if (initialized)
126 return res;
127
128 CpuSuspendIntr(&state);
129
130 for (i = 0; i < 32; ++i) {
131 sbus_handler_table[i].handler = NULL;
132 sbus_handler_table[i].arg = NULL;
133 }
134
135 if (RegisterIntrHandler(IOP_IRQ_SBUS, 1, sbus_dispatch, NULL) < 0) {
136 res = -SBUS_E_INIT;
137 goto out;
138 }
139 EnableIntr(IOP_IRQ_SBUS);
140 initialized = 1;
141out:
142 CpuResumeIntr(state);
143 return res;
144}
145
146void sbus_intr_exit()
147{
148 DisableIntr(IOP_IRQ_SBUS, NULL);
149 ReleaseIntrHandler(IOP_IRQ_SBUS);
150 initialized = 0;
151}
int CpuResumeIntr(int state)
Definition intrman.c:227
int RegisterIntrHandler(int irq, int mode, int(*handler)(void *), void *arg)
Definition intrman.c:125
int ReleaseIntrHandler(int irq)
Definition intrman.c:167
int DisableIntr(int irq, int *res)
Definition intrman.c:395
int CpuSuspendIntr(int *state)
Definition intrman.c:205
int EnableIntr(int irq)
Definition intrman.c:346
@ SBUS_E_INIT
Definition sbusintr.h:27
@ SBUS_E_ARG
Definition sbusintr.h:29
@ SBUS_E_IRQ
Definition sbusintr.h:31