~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Source/Core/Core/Src/HW/CPU.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 "Common.h"
 
6
#include "Thread.h"
 
7
 
 
8
#include "../DSPEmulator.h"
 
9
#include "../PowerPC/PowerPC.h"
 
10
#include "../Host.h"
 
11
#include "../Core.h"
 
12
#include "CPU.h"
 
13
#include "DSP.h"
 
14
#include "Movie.h"
 
15
 
 
16
#include "VideoBackendBase.h"
 
17
 
 
18
namespace
 
19
{
 
20
        static Common::Event m_StepEvent;
 
21
        static Common::Event *m_SyncEvent = NULL;
 
22
        static std::mutex m_csCpuOccupied;
 
23
}
 
24
 
 
25
void CCPU::Init(int cpu_core)
 
26
{
 
27
        PowerPC::Init(cpu_core);
 
28
        m_SyncEvent = NULL;
 
29
}
 
30
 
 
31
void CCPU::Shutdown()
 
32
{
 
33
        PowerPC::Shutdown();
 
34
        m_SyncEvent = NULL;
 
35
}
 
36
 
 
37
void CCPU::Run()
 
38
{
 
39
        std::lock_guard<std::mutex> lk(m_csCpuOccupied);
 
40
        Host_UpdateDisasmDialog();
 
41
 
 
42
        while (true)
 
43
        {
 
44
reswitch:
 
45
                switch (PowerPC::GetState())
 
46
                {
 
47
                case PowerPC::CPU_RUNNING:
 
48
                        //1: enter a fast runloop
 
49
                        PowerPC::RunLoop();
 
50
                        break;
 
51
 
 
52
                case PowerPC::CPU_STEPPING:
 
53
                        m_csCpuOccupied.unlock();
 
54
 
 
55
                        //1: wait for step command..
 
56
                        m_StepEvent.Wait();
 
57
 
 
58
                        m_csCpuOccupied.lock();
 
59
                        if (PowerPC::GetState() == PowerPC::CPU_POWERDOWN)
 
60
                                return;
 
61
                        if (PowerPC::GetState() != PowerPC::CPU_STEPPING)
 
62
                                goto reswitch;
 
63
 
 
64
                        //3: do a step
 
65
                        PowerPC::SingleStep();
 
66
 
 
67
                        //4: update disasm dialog
 
68
                        if (m_SyncEvent)
 
69
                        {
 
70
                                m_SyncEvent->Set();
 
71
                                m_SyncEvent = NULL;
 
72
                        }
 
73
                        Host_UpdateDisasmDialog();
 
74
                        break;
 
75
 
 
76
                case PowerPC::CPU_POWERDOWN:
 
77
                        //1: Exit loop!!
 
78
                        return; 
 
79
                }
 
80
        }
 
81
}
 
82
 
 
83
void CCPU::Stop()
 
84
{
 
85
        PowerPC::Stop();
 
86
        m_StepEvent.Set();
 
87
}
 
88
 
 
89
bool CCPU::IsStepping()
 
90
{
 
91
        return PowerPC::GetState() == PowerPC::CPU_STEPPING;
 
92
}
 
93
 
 
94
void CCPU::Reset()
 
95
{
 
96
 
 
97
}
 
98
 
 
99
void CCPU::StepOpcode(Common::Event *event) 
 
100
{
 
101
        m_StepEvent.Set();
 
102
        if (PowerPC::GetState() == PowerPC::CPU_STEPPING)
 
103
        {
 
104
                m_SyncEvent = event;
 
105
        }
 
106
}
 
107
 
 
108
void CCPU::EnableStepping(const bool _bStepping)
 
109
{       
 
110
        if (_bStepping)
 
111
        {
 
112
                PowerPC::Pause();
 
113
                m_StepEvent.Reset();
 
114
                g_video_backend->EmuStateChange(EMUSTATE_CHANGE_PAUSE);
 
115
                DSP::GetDSPEmulator()->DSP_ClearAudioBuffer(true);
 
116
        }
 
117
        else
 
118
        {
 
119
                PowerPC::Start();
 
120
                m_StepEvent.Set();
 
121
                g_video_backend->EmuStateChange(EMUSTATE_CHANGE_PLAY);
 
122
                DSP::GetDSPEmulator()->DSP_ClearAudioBuffer(false);
 
123
        }
 
124
}
 
125
 
 
126
void CCPU::Break() 
 
127
{
 
128
        EnableStepping(true);
 
129
}
 
130
 
 
131
bool CCPU::PauseAndLock(bool doLock, bool unpauseOnUnlock)
 
132
{
 
133
        bool wasUnpaused = !IsStepping();
 
134
        if (doLock)
 
135
        {
 
136
                // we can't use EnableStepping, that would causes deadlocks with both audio and video
 
137
                PowerPC::Pause();
 
138
                if (!Core::IsCPUThread())
 
139
                        m_csCpuOccupied.lock();
 
140
        }
 
141
        else
 
142
        {
 
143
                if (unpauseOnUnlock)
 
144
                {
 
145
                        PowerPC::Start();
 
146
                        m_StepEvent.Set();
 
147
                }
 
148
 
 
149
                if (!Core::IsCPUThread())
 
150
                        m_csCpuOccupied.unlock();
 
151
        }
 
152
        return wasUnpaused;
 
153
}