summaryrefslogtreecommitdiff
path: root/lib/ultralib/src/io/gbpakcheckconnector.c
blob: 8eb32981a25282a8a0901b15bbf478b6170cd539 (plain)
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include "macros.h"
#include "PR/os_internal.h"
#include "controller.h"

s32 osGbpakCheckConnector(OSPfs* pfs, u8* status) {
    s32 ret;
    s32 bufn = 1;
    s32 oldbufn = 0;
    u16 address = 0;
    u16 oldaddr = 0;
    u16 daddr = 0;
    u16 num;
    u8 buf[3][4][BLOCKSIZE];
    u8 buf_status[3][4];

    ret = osGbpakGetStatus(pfs, status);

    if (ret == PFS_ERR_NEW_GBCART) {
        ret = osGbpakGetStatus(pfs, status);
    }

    if (ret == PFS_ERR_NEW_GBCART) {
        return PFS_ERR_CONTRFAIL;
    } else if (ret == 0) {
        if (!(*status & OS_GBPAK_POWER)) {
            ERRCK(osGbpakPower(pfs, OS_GBPAK_POWER_ON));
        }

        bzero(buf_status, sizeof(buf_status));

        for (address = 0x80; address <= 0x4000; address <<= 1) {
            num = 0;
            daddr = 0;

            do {
                ERRCK(osGbpakReadWrite(pfs, OS_READ, address + daddr, buf[bufn][num], BLOCKSIZE));
                buf_status[bufn][num] = 1;

                if (buf_status[oldbufn][num] == 0) {
                    ret = osGbpakReadWrite(pfs, OS_READ, oldaddr + daddr, buf[oldbufn][num], BLOCKSIZE);

                    if (ret != 0) {
                        return ret;
                    } else {
                        buf_status[oldbufn][num] = 1;
                    }
                }

                if (bcmp(buf[bufn][num], buf[oldbufn][num], BLOCKSIZE) != 0) {
                    num = 0;
                    break;
                }

                daddr += BLOCKSIZE;
            } while (num++ < ARRLEN(buf[0]) - 1);

            if (num != 0) {
                return PFS_ERR_CONTRFAIL;
            }

            if (oldbufn != 0) {
                num = 0;
                daddr = 0;

                do {
                    if (buf_status[bufn][num] == 0) {
                        ERRCK(osGbpakReadWrite(pfs, OS_READ, address + daddr, buf[bufn][num], BLOCKSIZE));
                        buf_status[bufn][num] = 1;
                    }

                    if (buf_status[0][num] == 0) {
                        ret = osGbpakReadWrite(pfs, OS_READ, daddr, buf[0][num], BLOCKSIZE);
                        if (ret != 0) {
                            return ret;
                        } else {
                            buf_status[0][num] = 1;
                        }
                    }

                    if (bcmp(buf[bufn][num], buf[0][num], BLOCKSIZE)) {
                        num = 0;
                        break;
                    }

                    daddr += BLOCKSIZE;
                } while (num++ < ARRLEN(buf_status[0]) - 1);
            }

            if (num != 0) {
                return PFS_ERR_CONTRFAIL;
            }

            if (oldbufn != 0) {
                bzero(buf_status[oldbufn], ARRLEN(buf_status[oldbufn]));
            }

            oldaddr = address;
            oldbufn = bufn;
            bufn ^= 3;
        }

        if ((pfs->dir_size >= 2) || (pfs->version == 2)) {
            num = 0;
            daddr = 0;

            do {
                ERRCK(osGbpakReadWrite(pfs, OS_READ, daddr + 0xA000, buf[bufn][num], BLOCKSIZE));
                ERRCK(osGbpakReadWrite(pfs, OS_READ, daddr + 0x2000, buf[oldbufn][num], BLOCKSIZE));

                if (bcmp(buf[bufn][num], buf[oldbufn][num], BLOCKSIZE)) {
                    num = 0;
                    break;
                }

                daddr += BLOCKSIZE;
            } while (num++ < ARRLEN(buf[0]) - 1);

            if (num != 0) {
                return PFS_ERR_CONTRFAIL;
            }
        }

        ret = osGbpakGetStatus(pfs, status);

        if (ret == PFS_ERR_NEW_GBCART) {
            ret = PFS_ERR_CONTRFAIL;
        }
    }

    return ret;
}