/
tipi_msg.c
69 lines (56 loc) · 1.48 KB
/
tipi_msg.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include "tipi_msg.h"
#define GPLWS_R0 *((volatile unsigned int*)0x83E0)
#define GPLWS_R1 *((volatile unsigned int*)0x83E2)
void tipi_lib_init();
int tipi_crubase = 0;
inline void enableTipi() {
__asm__("mov %0,r12\n\tsbo 0" : : "r"(tipi_crubase) : "r12");
}
inline void disableTipi() {
__asm__("mov %0,r12\n\tsbz 0" : : "r"(tipi_crubase) : "r12");
}
void tipi_on()
{
if (tipi_crubase == 0) {
tipi_lib_init();
}
enableTipi();
}
void tipi_off()
{
disableTipi();
}
void tipi_lib_init()
{
tipi_crubase = 0x1000;
while(tipi_crubase < 0x2000) {
enableTipi();
unsigned int* dsrrom = (unsigned int*) 0x4000;
dsrrom += 4; // 4 words, not bytes
if (*dsrrom != 0) {
dsrrom = ((unsigned int*) *dsrrom) + 2;
unsigned char* dsrname = (unsigned char*) dsrrom;
// TIPI will always have device TIPI first in dsrlnk list.
if (dsrname[0] == 4 && dsrname[1] == 'T' && dsrname[2] == 'I' && dsrname[3] == 'P' && dsrname[4] == 'I') {
disableTipi();
return;
}
}
disableTipi();
tipi_crubase += 0x0100;
}
tipi_crubase = 0x0000;
}
void tipi_recvmsg(unsigned int* len, unsigned char* buf)
{
GPLWS_R0 = (unsigned int)*len;
GPLWS_R1 = (unsigned int)buf;
__asm__("lwpi >83E0\n\tmov @>4010,r4\n\tbl *r4\n\tlwpi >8300");
*len = GPLWS_R0;
}
void tipi_sendmsg(unsigned int len, const unsigned char* buf)
{
GPLWS_R0 = len;
GPLWS_R1 = (unsigned int)buf;
__asm__("lwpi >83E0\n\tmov @>4012,r4\n\tbl *r4\n\tlwpi >8300");
}