~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_GBA.cpp

  • Committer: Sérgio Benjamim
  • Date: 2015-02-13 05:54:40 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20150213055440-ey2rt3sjpy27km78
Dolphin Triforce branch from code.google, commit b957980 (4.0-315).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2013 Dolphin Emulator Project
 
2
// Licensed under GPLv2
 
3
// Refer to the license.txt file included.
 
4
 
 
5
#include "UCodes.h"
 
6
#include "UCode_GBA.h"
 
7
 
 
8
#include "../../DSP.h"
 
9
#include "ConfigManager.h"
 
10
 
 
11
CUCode_GBA::CUCode_GBA(DSPHLE *dsp_hle, u32 crc)
 
12
: IUCode(dsp_hle, crc)
 
13
{
 
14
        m_rMailHandler.PushMail(DSP_INIT);
 
15
}
 
16
 
 
17
CUCode_GBA::~CUCode_GBA()
 
18
{
 
19
        m_rMailHandler.Clear();
 
20
}
 
21
 
 
22
void CUCode_GBA::Update(int cycles)
 
23
{
 
24
        // check if we have to send something
 
25
        if (!m_rMailHandler.IsEmpty())
 
26
        {
 
27
                DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
 
28
        }
 
29
}
 
30
 
 
31
u32 CUCode_GBA::GetUpdateMs()
 
32
{
 
33
        return SConfig::GetInstance().m_LocalCoreStartupParameter.bWii ? 3 : 5;
 
34
}
 
35
 
 
36
void CUCode_GBA::HandleMail(u32 _uMail)
 
37
{
 
38
        static bool nextmail_is_mramaddr = false;
 
39
        static bool calc_done = false;
 
40
 
 
41
        if (m_UploadSetupInProgress)
 
42
        {
 
43
                PrepareBootUCode(_uMail);
 
44
        }
 
45
        else if ((_uMail >> 16 == 0xabba) && !nextmail_is_mramaddr)
 
46
        {
 
47
                nextmail_is_mramaddr = true;
 
48
        }
 
49
        else if (nextmail_is_mramaddr)
 
50
        {
 
51
                nextmail_is_mramaddr = false;
 
52
                u32 mramaddr = _uMail;
 
53
 
 
54
                struct sec_params_t
 
55
                {
 
56
                        u16 key[2];
 
57
                        u16 unk1[2];
 
58
                        u16 unk2[2];
 
59
                        u32 length;
 
60
                        u32 dest_addr;
 
61
                        u32 pad[3];
 
62
                } sec_params;
 
63
 
 
64
                // 32 bytes from mram addr to dram @ 0
 
65
                for (int i = 0; i < 8; i++, mramaddr += 4)
 
66
                        ((u32*)&sec_params)[i] = HLEMemory_Read_U32(mramaddr);
 
67
 
 
68
                // This is the main decrypt routine
 
69
                u16 x11 = 0, x12 = 0,
 
70
                        x20 = 0, x21 = 0, x22 = 0, x23 = 0;
 
71
 
 
72
                x20 = Common::swap16(sec_params.key[0]) ^ 0x6f64;
 
73
                x21 = Common::swap16(sec_params.key[1]) ^ 0x6573;
 
74
 
 
75
                s16 unk2 = (s8)sec_params.unk2[0];
 
76
                if (unk2 < 0)
 
77
                {
 
78
                        x11 = ((~unk2 + 3) << 1) | (sec_params.unk1[0] << 4);
 
79
                }
 
80
                else if (unk2 == 0)
 
81
                {
 
82
                        x11 = (sec_params.unk1[0] << 1) | 0x70;
 
83
                }
 
84
                else // unk2 > 0
 
85
                {
 
86
                        x11 = ((unk2 - 1) << 1) | (sec_params.unk1[0] << 4);
 
87
                }
 
88
 
 
89
                s32 rounded_sub = ((sec_params.length + 7) & ~7) - 0x200;
 
90
                u16 size = (rounded_sub < 0) ? 0 : rounded_sub >> 3;
 
91
 
 
92
                u32 t = (((size << 16) | 0x3f80) & 0x3f80ffff) << 1;
 
93
                s16 t_low = (s8)(t >> 8);
 
94
                t += (t_low & size) << 16;
 
95
                x12 = t >> 16;
 
96
                x11 |= (size & 0x4000) >> 14; // this would be stored in ac0.h if we weren't constrained to 32bit :)
 
97
                t = ((x11 & 0xff) << 16) + ((x12 & 0xff) << 16) + (x12 << 8);
 
98
 
 
99
                u16 final11 = 0, final12 = 0;
 
100
                final11 = x11 | ((t >> 8) & 0xff00) | 0x8080;
 
101
                final12 = x12 | 0x8080;
 
102
 
 
103
                if ((final12 & 0x200) != 0)
 
104
                {
 
105
                        x22 = final11 ^ 0x6f64;
 
106
                        x23 = final12 ^ 0x6573;
 
107
                }
 
108
                else
 
109
                {
 
110
                        x22 = final11 ^ 0x6177;
 
111
                        x23 = final12 ^ 0x614b;
 
112
                }
 
113
 
 
114
                // Send the result back to mram
 
115
                *(u32*)HLEMemory_Get_Pointer(sec_params.dest_addr) = Common::swap32((x20 << 16) | x21);
 
116
                *(u32*)HLEMemory_Get_Pointer(sec_params.dest_addr+4) = Common::swap32((x22 << 16) | x23);
 
117
 
 
118
                // Done!
 
119
                DEBUG_LOG(DSPHLE, "\n%08x -> key: %08x, len: %08x, dest_addr: %08x, unk1: %08x, unk2: %08x"
 
120
                        " 22: %04x, 23: %04x",
 
121
                        mramaddr,
 
122
                        *(u32*)sec_params.key, sec_params.length, sec_params.dest_addr,
 
123
                        *(u32*)sec_params.unk1, *(u32*)sec_params.unk2,
 
124
                        x22, x23);
 
125
 
 
126
                calc_done = true;
 
127
                m_rMailHandler.PushMail(DSP_DONE);
 
128
        }
 
129
        else if ((_uMail >> 16 == 0xcdd1) && calc_done)
 
130
        {
 
131
                switch (_uMail & 0xffff)
 
132
                {
 
133
                case 1:
 
134
                        m_UploadSetupInProgress = true;
 
135
                        break;
 
136
                case 2:
 
137
                        m_DSPHLE->SetUCode(UCODE_ROM);
 
138
                        break;
 
139
                default:
 
140
                        DEBUG_LOG(DSPHLE, "CUCode_GBA - unknown 0xcdd1 command: %08x", _uMail);
 
141
                        break;
 
142
                }
 
143
        }
 
144
        else
 
145
        {
 
146
                DEBUG_LOG(DSPHLE, "CUCode_GBA - unknown command: %08x", _uMail);
 
147
        }
 
148
}