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