PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
ee_sbus.c
1/*
2
3EE-specific code for PS2 SBUS library.
4
5This file contains the glue, etc needed for an SBUS library on EE.
6
7*/
8
9#include <ps2_reg_defs.h>
10#include <tamtypes.h>
11#include <kernel.h>
12#include "ps2_sbus.h"
13#include "sbus_priv.h"
14
15extern int __local_sbus_irq_handler(void);
16
17void SBUS_check_intr(void)
18{
19 if (*R_EE_I_STAT & EE_I_STAT_SBUS) {
20 __local_sbus_irq_handler();
21 *R_EE_I_STAT |= EE_I_STAT_SBUS;
22 }
23}
24
25#if 0
26
27int SBUS_interrupt_remote(int irq)
28{
29 int oldi;
30
31 M_SuspendIntr(&oldi);
32
33 // wait for remote to clear "irq" bit
34 while (SBUS_get_reg(PS2_SBUS_LR_FLAG) & (1 << irq))
35 ;
36
37 // if clk is high, bring it low
38 if (SBUS_get_reg(PS2_SBUS_REG4) & 0x00000100) {
39 SBUS_set_reg(PS2_SBUS_REG4, 0x00000100);
40 }
41
42 // set the "irq" bit for the SBUS interrupt.
43 SBUS_set_reg(PS2_SBUS_LR_FLAG, (1 << irq));
44
45 // cause the actual SBUS interrupt on remote CPU
46
47 // clk high
48 *R_EE_SBUS(4) = 0x00000100;
49 // clk low
50 *R_EE_SBUS(4) = 0x00000100;
51 // clk high
52 *R_EE_SBUS(4) = 0x00000100;
53 // clk low
54 *R_EE_SBUS(4) = 0x00000100;
55 // clk high
56 *R_EE_SBUS(4) = 0x00000100;
57 // clk low
58 *R_EE_SBUS(4) = 0x00000100;
59 // clk high
60 *R_EE_SBUS(4) = 0x00000100;
61 // clk low
62 *R_EE_SBUS(4) = 0x00000100;
63 // clk high
64 *R_EE_SBUS(4) = 0x00000100;
65 // clk low, intr high
66 *R_EE_SBUS(4) = 0x00040100;
67
68 M_ResumeIntr(oldi);
69
70 return (irq);
71}
72#else
73int SBUS_interrupt_remote(int irq)
74{
75 int oldi;
76
77 if (irq >= 32) {
78 return (-1);
79 }
80
81 M_SuspendIntr(&oldi);
82
83 // wait for remote to clear irq bit
84 while (SBUS_get_reg(PS2_SBUS_MS_FLAG) & (((u32)1) << irq))
85 ;
86
87 // set the "irq" bit for the SBUS interrupt.
88 SBUS_set_reg(PS2_SBUS_MS_FLAG, (((u32)1) << irq));
89
90 SBUS_set_reg(PS2_SBUS_REG4, 0x00040100);
91 SBUS_set_reg(PS2_SBUS_REG4, 0x00000100);
92
93 M_ResumeIntr(oldi);
94
95 return (irq);
96}
97#endif
98
99// this is a hack but the address of the function that sets the actual low-level interrupt handler pointer.
100void _SetIntcHandler(int irq, void *handler)
101{
102 int i_state, u_state;
103
104 i_state = DI();
105 u_state = (ee_kmode_enter() >> 3) & 3;
106
107 ((void (*)(int, void *))(0x80000700))(irq, handler);
108
109 if (u_state) {
110 ee_kmode_exit();
111 }
112 if (i_state) {
113 EI();
114 }
115}
#define R_EE_I_STAT
Definition ee_regs.h:462