diff options
Diffstat (limited to 'source/link.c')
-rw-r--r-- | source/link.c | 157 |
1 files changed, 149 insertions, 8 deletions
diff --git a/source/link.c b/source/link.c index 4178293..1091576 100644 --- a/source/link.c +++ b/source/link.c | |||
@@ -5,18 +5,159 @@ | |||
5 | * of the MIT license. See the LICENSE file for details. | 5 | * of the MIT license. See the LICENSE file for details. |
6 | */ | 6 | */ |
7 | #include "link.h" | 7 | #include "link.h" |
8 | #include <unistd.h> | ||
9 | #include <stdio.h> | ||
10 | #include <string.h> | ||
11 | #include <malloc.h> | ||
8 | 12 | ||
9 | u32 waitForButtons(u32 mask) | 13 | //from my tests 50us seems to be the lowest |
14 | //safe si transfer delay in between calls | ||
15 | #define SI_TRANS_DELAY 50 | ||
16 | |||
17 | static u8* resbuf; | ||
18 | static u8* cmdbuf; | ||
19 | |||
20 | void initLink() | ||
21 | { | ||
22 | cmdbuf = memalign(32,32); | ||
23 | resbuf = memalign(32,32); | ||
24 | } | ||
25 | |||
26 | static volatile u32 transval = 0; | ||
27 | void transcb(s32 chan, u32 ret) | ||
28 | { | ||
29 | transval = 1; | ||
30 | } | ||
31 | |||
32 | static volatile u32 resval = 0; | ||
33 | void acb(s32 res, u32 val) | ||
34 | { | ||
35 | resval = val; | ||
36 | } | ||
37 | |||
38 | void doreset() | ||
39 | { | ||
40 | cmdbuf[0] = 0xFF; //reset | ||
41 | transval = 0; | ||
42 | SI_Transfer(1, cmdbuf, 1, resbuf, 3, transcb, SI_TRANS_DELAY); | ||
43 | |||
44 | while (transval == 0); | ||
45 | } | ||
46 | |||
47 | void getstatus() | ||
10 | { | 48 | { |
11 | for (;;) | 49 | cmdbuf[0] = 0; //status |
50 | transval = 0; | ||
51 | SI_Transfer(1, cmdbuf, 1, resbuf, 3, transcb, SI_TRANS_DELAY); | ||
52 | |||
53 | while (transval == 0); | ||
54 | } | ||
55 | |||
56 | u32 recv() | ||
57 | { | ||
58 | memset(resbuf,0,32); | ||
59 | cmdbuf[0]=0x14; //read | ||
60 | transval = 0; | ||
61 | SI_Transfer(1, cmdbuf, 1, resbuf, 5, transcb, SI_TRANS_DELAY); | ||
62 | |||
63 | while (transval == 0); | ||
64 | printf("%08lx\n", *(vu32*)resbuf); | ||
65 | return *(vu32*)resbuf; | ||
66 | } | ||
67 | |||
68 | void send(u32 msg) | ||
69 | { | ||
70 | cmdbuf[0] = 0x15; | ||
71 | cmdbuf[1] = (msg >> 0) & 0xFF; | ||
72 | cmdbuf[2] = (msg >> 8) & 0xFF; | ||
73 | cmdbuf[3] = (msg >> 16) & 0xFF; | ||
74 | cmdbuf[4] = (msg >> 24) & 0xFF; | ||
75 | |||
76 | transval = 0; | ||
77 | resbuf[0] = 0; | ||
78 | SI_Transfer(1, cmdbuf, 5, resbuf, 1, transcb, SI_TRANS_DELAY); | ||
79 | |||
80 | while (transval == 0); | ||
81 | } | ||
82 | |||
83 | u32 getMsg() | ||
84 | { | ||
85 | u32 val = 0; | ||
86 | while (val == 0) | ||
12 | { | 87 | { |
13 | PAD_ScanPads(); | 88 | val = __builtin_bswap32(recv()); |
14 | VIDEO_WaitVSync(); | 89 | sleep(1); |
90 | } | ||
15 | 91 | ||
16 | u32 btns = PAD_ButtonsDown(0); | 92 | send(0); |
17 | if (btns & mask) | 93 | while (recv()!=0) {sleep(1);} |
94 | send(0); | ||
95 | |||
96 | return val; | ||
97 | } | ||
98 | |||
99 | void getMsgArr(u32* arr, int len) | ||
100 | { | ||
101 | for (int i=0; i<len; i++) | ||
102 | { | ||
103 | *(vu32*)(arr+i) = __builtin_bswap32(recv()); | ||
104 | usleep(500000); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | void sendMsg(u32 msg) | ||
109 | { | ||
110 | while (recv()==0) {sleep(1);} | ||
111 | send(msg); | ||
112 | while (recv()!=0) {sleep(1);} | ||
113 | send(0); | ||
114 | } | ||
115 | |||
116 | void waitForGBA() | ||
117 | { | ||
118 | resval = 0; | ||
119 | |||
120 | do | ||
121 | { | ||
122 | SI_GetTypeAsync(1, acb); | ||
123 | |||
124 | for (;;) | ||
18 | { | 125 | { |
19 | return btns; | 126 | if (resval) |
127 | { | ||
128 | if (resval == 0x80 || resval & 8) | ||
129 | { | ||
130 | resval = 0; | ||
131 | SI_GetTypeAsync(1, acb); | ||
132 | } else if (resval) | ||
133 | { | ||
134 | break; | ||
135 | } | ||
136 | } | ||
20 | } | 137 | } |
21 | } | 138 | } while (!(resval & SI_GBA)); |
139 | } | ||
140 | |||
141 | void waitForBIOS() | ||
142 | { | ||
143 | resbuf[2]=0; | ||
144 | |||
145 | do | ||
146 | { | ||
147 | doreset(); | ||
148 | } while (!(resbuf[1] > 4)); | ||
149 | } | ||
150 | |||
151 | void waitForGame() | ||
152 | { | ||
153 | do | ||
154 | { | ||
155 | doreset(); | ||
156 | } while ((resbuf[0] != 0) || !(resbuf[2] & 0x10)); | ||
157 | } | ||
158 | |||
159 | void waitForAck() | ||
160 | { | ||
161 | while (recv() != 0) {sleep(1);}; | ||
162 | send(0); | ||
22 | } | 163 | } |