1 /*
2 Copyright (C) 2006 T. Scott Dattalo
3
4 This file is part of the libgpsim library of gpsim
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, see
18 <http://www.gnu.org/licenses/lgpl-2.1.html>.
19 */
20
21
22 #include "clock_phase.h"
23
24 #include "processor.h"
25 #include "gpsim_time.h"
26
27 //========================================================================
ClockPhase()28 ClockPhase::ClockPhase()
29 : m_pNextPhase(this)
30 {
31 }
32
~ClockPhase()33 ClockPhase::~ClockPhase()
34 {
35 }
36
37
38 //========================================================================
39
ProcessorPhase(Processor * pcpu)40 ProcessorPhase::ProcessorPhase(Processor *pcpu)
41 : ClockPhase(),
42 m_pcpu(pcpu)
43 {
44 }
~ProcessorPhase()45 ProcessorPhase::~ProcessorPhase()
46 {
47 }
48
49 //========================================================================
50
phaseExecute1Cycle(Processor * pcpu)51 phaseExecute1Cycle::phaseExecute1Cycle(Processor *pcpu)
52 : ProcessorPhase(pcpu)
53 {
54 }
~phaseExecute1Cycle()55 phaseExecute1Cycle::~phaseExecute1Cycle()
56 {
57 }
58
59 /*
60 phaseExecute1Cycle::advance() - advances a processor's time one clock cycle.
61
62 */
63
advance()64 ClockPhase *phaseExecute1Cycle::advance()
65 {
66 setNextPhase(this);
67 m_pcpu->step_one(false);
68 if (bp.global_break & GLOBAL_LOG)
69 {
70 if (GetTraceLog().log_file)
71 {
72 trace.cycle_counter(get_cycles().get());
73 trace.dump(1, GetTraceLog().log_file);
74 GetTraceLog().items_logged++;
75 }
76 bp.global_break &= ~GLOBAL_LOG;
77 }
78 if (!bp.global_break)
79 get_cycles().increment();
80 return m_pNextPhase;
81 }
82
83 //========================================================================
84
phaseIdle(Processor * pcpu)85 phaseIdle::phaseIdle(Processor *pcpu)
86 : ProcessorPhase(pcpu)
87 {
88 }
~phaseIdle()89 phaseIdle::~phaseIdle()
90 {
91 }
92
93 /*
94 phaseIdle::advance() - advances a processor's time one clock cycle,
95 but does not execute code.
96 */
97
advance()98 ClockPhase *phaseIdle::advance()
99 {
100 setNextPhase(this);
101 get_cycles().increment();
102 return m_pNextPhase;
103 }
104 #if 0
105 const char* phaseDesc(ClockPhase *pPhase)
106 {
107 if (pPhase == mIdle)
108 return ("mIdle");
109 if (pPhase == mExecute1Cycle)
110 return ("mExecute1Cycle");
111 if (pPhase == mExecute2ndHalf)
112 return ("mExecute2ndHalf");
113 if (pPhase == mCaptureInterrupt)
114 return ("mCaptureInterrupt");
115 return "unknown phase";
116 }
117 #endif
118
119
phaseCaptureInterrupt(Processor * pcpu)120 phaseCaptureInterrupt::phaseCaptureInterrupt(Processor *pcpu)
121 : ProcessorPhase(pcpu), m_pCurrentPhase(0),m_pNextNextPhase(0)
122 {
123 }
~phaseCaptureInterrupt()124 phaseCaptureInterrupt::~phaseCaptureInterrupt()
125 {}
126 #define Rprintf(arg) {printf("0x%06X %s() ",cycles.get(),__FUNCTION__); printf arg; }
advance()127 ClockPhase *phaseCaptureInterrupt::advance()
128 {
129
130 //Rprintf (("phaseCaptureInterrupt\n"));
131 if (m_pNextPhase == m_pcpu->mExecute2ndHalf)
132 m_pNextPhase->advance();
133
134 if (m_pCurrentPhase == m_pcpu->mIdle) { // Interrupted sleep
135
136 // complete sleeping phase
137 m_pNextPhase = m_pNextNextPhase->advance();
138
139 if (m_pNextPhase == m_pcpu->mIdle)
140 {
141 m_pNextPhase = m_pcpu->mExecute1Cycle;
142 do
143 {
144 m_pNextPhase = m_pcpu->mExecute1Cycle->advance();
145 }while (m_pNextPhase != m_pcpu->mExecute1Cycle);
146 }
147 m_pcpu->mCurrentPhase = this;
148 if (bp.global_break)
149 m_pNextNextPhase = m_pNextPhase;
150 else
151 m_pCurrentPhase = NULL;
152
153 m_pcpu->exit_sleep();
154 return this;
155 }
156
157 m_pcpu->interrupt();
158
159 return m_pNextPhase;
160 }
161
firstHalf()162 void phaseCaptureInterrupt::firstHalf()
163 {
164 m_pCurrentPhase = m_pcpu->mCurrentPhase;
165
166 m_pNextPhase = this;
167 m_pNextNextPhase = m_pcpu->mCurrentPhase->getNextPhase();
168 m_pcpu->mCurrentPhase->setNextPhase(this);
169 m_pcpu->mCurrentPhase = this;
170 }
171
172
173
174