1
// Copyright 2013 Dolphin Emulator Project
2
// Licensed under GPLv2
3
// Refer to the license.txt file included.
9
#include "ConfigManager.h"
11
CUCode_GBA::CUCode_GBA(DSPHLE *dsp_hle, u32 crc)
12
: IUCode(dsp_hle, crc)
14
m_rMailHandler.PushMail(DSP_INIT);
17
CUCode_GBA::~CUCode_GBA()
19
m_rMailHandler.Clear();
22
void CUCode_GBA::Update(int cycles)
24
// check if we have to send something
25
if (!m_rMailHandler.IsEmpty())
27
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
31
u32 CUCode_GBA::GetUpdateMs()
33
return SConfig::GetInstance().m_LocalCoreStartupParameter.bWii ? 3 : 5;
36
void CUCode_GBA::HandleMail(u32 _uMail)
38
static bool nextmail_is_mramaddr = false;
39
static bool calc_done = false;
41
if (m_UploadSetupInProgress)
43
PrepareBootUCode(_uMail);
45
else if ((_uMail >> 16 == 0xabba) && !nextmail_is_mramaddr)
47
nextmail_is_mramaddr = true;
49
else if (nextmail_is_mramaddr)
51
nextmail_is_mramaddr = false;
52
u32 mramaddr = _uMail;
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);
68
// This is the main decrypt routine
70
x20 = 0, x21 = 0, x22 = 0, x23 = 0;
72
x20 = Common::swap16(sec_params.key[0]) ^ 0x6f64;
73
x21 = Common::swap16(sec_params.key[1]) ^ 0x6573;
75
s16 unk2 = (s8)sec_params.unk2[0];
78
x11 = ((~unk2 + 3) << 1) | (sec_params.unk1[0] << 4);
82
x11 = (sec_params.unk1[0] << 1) | 0x70;
86
x11 = ((unk2 - 1) << 1) | (sec_params.unk1[0] << 4);
89
s32 rounded_sub = ((sec_params.length + 7) & ~7) - 0x200;
90
u16 size = (rounded_sub < 0) ? 0 : rounded_sub >> 3;
92
u32 t = (((size << 16) | 0x3f80) & 0x3f80ffff) << 1;
93
s16 t_low = (s8)(t >> 8);
94
t += (t_low & size) << 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);
99
u16 final11 = 0, final12 = 0;
100
final11 = x11 | ((t >> 8) & 0xff00) | 0x8080;
101
final12 = x12 | 0x8080;
103
if ((final12 & 0x200) != 0)
105
x22 = final11 ^ 0x6f64;
106
x23 = final12 ^ 0x6573;
110
x22 = final11 ^ 0x6177;
111
x23 = final12 ^ 0x614b;
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);
119
DEBUG_LOG(DSPHLE, "\n%08x -> key: %08x, len: %08x, dest_addr: %08x, unk1: %08x, unk2: %08x"
120
" 22: %04x, 23: %04x",
122
*(u32*)sec_params.key, sec_params.length, sec_params.dest_addr,
123
*(u32*)sec_params.unk1, *(u32*)sec_params.unk2,
127
m_rMailHandler.PushMail(DSP_DONE);
129
else if ((_uMail >> 16 == 0xcdd1) && calc_done)
131
switch (_uMail & 0xffff)
134
m_UploadSetupInProgress = true;
137
m_DSPHLE->SetUCode(UCODE_ROM);
140
DEBUG_LOG(DSPHLE, "CUCode_GBA - unknown 0xcdd1 command: %08x", _uMail);
146
DEBUG_LOG(DSPHLE, "CUCode_GBA - unknown command: %08x", _uMail);