@@ -42,8 +42,12 @@ public class Dcpu16Computer : PartModule
4242 #region Emulation
4343
4444 private bool _isPowerOn ;
45+ private bool _isHalted ;
4546 private bool _isKeyboardAttached ;
4647
48+ private ushort ? _pcAtHalt ;
49+ private int ? _warpIndexBeforeWake ;
50+
4751 private string _program = String . Empty ;
4852
4953 private readonly List < double > _clockRates = new List < double > ( 60 ) ;
@@ -102,29 +106,57 @@ public override void OnUpdate()
102106 {
103107 if ( _isPowerOn )
104108 {
105- var maxPhysicsWarpIndex = _timeWarp . physicsWarpRates . Length - 1 ;
106-
107- if ( _timeWarp . physicsWarpRates [ maxPhysicsWarpIndex ] < TimeWarp . CurrentRate )
109+ if ( _isHalted )
108110 {
109- TimeWarp . SetRate ( TimeWarp . WarpMode == TimeWarp . Modes . LOW ? maxPhysicsWarpIndex : 0 , true ) ;
110- }
111-
112- var cyclesToExecute = ( int ) Math . Round ( Time . deltaTime * _dcpu . ClockSpeed * TimeWarp . CurrentRate ) ;
113-
114- _dcpu . Execute ( cyclesToExecute ) ;
111+ if ( _dcpu . PC != _pcAtHalt )
112+ {
113+ _warpIndexBeforeWake = TimeWarp . CurrentRateIndex ;
115114
116- var clockRate = _cyclesExecuted / Time . deltaTime ;
117- if ( _clockRates . Count < 60 )
118- {
119- _clockRates . Add ( clockRate ) ;
115+ _pcAtHalt = null ;
116+ _isHalted = false ;
117+ }
120118 }
121119 else
122120 {
123- _clockRates [ _clockRateIndex ] = clockRate ;
124- _clockRateIndex = ( ( _clockRateIndex + 1 ) % 60 ) ;
125- }
121+ if ( _dcpu . IsHalted ( ) )
122+ {
123+ _pcAtHalt = _dcpu . PC ;
124+ _isHalted = true ;
125+
126+ if ( _warpIndexBeforeWake != null )
127+ {
128+ var index = _warpIndexBeforeWake . Value ;
129+ _warpIndexBeforeWake = null ;
130+ TimeWarp . SetRate ( index , true ) ;
131+ }
132+ }
133+ else
134+ {
135+ var maxPhysicsWarpIndex = _timeWarp . physicsWarpRates . Length - 1 ;
136+
137+ if ( _timeWarp . physicsWarpRates [ maxPhysicsWarpIndex ] < TimeWarp . CurrentRate )
138+ {
139+ TimeWarp . SetRate ( TimeWarp . WarpMode == TimeWarp . Modes . LOW ? maxPhysicsWarpIndex : 0 , true ) ;
140+ }
141+
142+ var cyclesToExecute = ( int ) Math . Round ( Time . deltaTime * _dcpu . ClockSpeed * TimeWarp . CurrentRate ) ;
143+
144+ _dcpu . Execute ( cyclesToExecute ) ;
126145
127- _cyclesExecuted = cyclesToExecute ;
146+ var clockRate = _cyclesExecuted / Time . deltaTime ;
147+ if ( _clockRates . Count < 60 )
148+ {
149+ _clockRates . Add ( clockRate ) ;
150+ }
151+ else
152+ {
153+ _clockRates [ _clockRateIndex ] = clockRate ;
154+ _clockRateIndex = ( ( _clockRateIndex + 1 ) % 60 ) ;
155+ }
156+
157+ _cyclesExecuted = cyclesToExecute ;
158+ }
159+ }
128160 }
129161 }
130162
@@ -216,7 +248,21 @@ private void OnWindow(int windowId)
216248 if ( GUILayout . Button ( "4x" , _styleButton ) ) { SetMonitorScale ( 4 ) ; }
217249 GUILayout . EndHorizontal ( ) ;
218250 GUILayout . BeginHorizontal ( ) ;
219- GUILayout . Label ( actualClockSpeedFormatted , _styleLabel ) ;
251+ if ( _isPowerOn )
252+ {
253+ if ( _isHalted )
254+ {
255+ GUILayout . Label ( "Halted" , new GUIStyle ( _styleLabel ) { normal = { textColor = Color . yellow } } ) ;
256+ }
257+ else
258+ {
259+ GUILayout . Label ( actualClockSpeedFormatted , _styleLabel ) ;
260+ }
261+ }
262+ else
263+ {
264+ GUILayout . Label ( "Powered Off" , new GUIStyle ( _styleLabel ) { normal = { textColor = Color . red } } ) ;
265+ }
220266 GUILayout . EndHorizontal ( ) ;
221267
222268 GUI . SetNextControlName ( KeyboardInputName ) ;
@@ -266,6 +312,9 @@ private void OnPowerButtonPressed()
266312 {
267313 _isPowerOn = false ;
268314
315+ _isHalted = false ;
316+ _pcAtHalt = 0 ;
317+
269318 _dcpu . Reset ( ) ;
270319 _dcpu . FlashMemory ( new ushort [ _dcpu . Memory . Length ] ) ;
271320 _clockRates . RemoveAll ( i => true ) ;
0 commit comments