summaryrefslogtreecommitdiff
path: root/lib/simulator/engine/engine_backward_stepping.tcl
blob: af5e7d9cf7aa37757956b03189b5c1ed8f178908 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/tclsh
# Part of MCU 8051 IDE ( http://http://www.moravia-microsystems.com/mcu8051ide )

############################################################################
#    Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin OŇ°mera     #
#    martin.osmera@gmail.com                                               #
#                                                                          #
#    Copyright (C) 2014 by Moravia Microsystems, s.r.o.                    #
#    martin.osmera@moravia-microsystems.com                                #
#                                                                          #
#    This program is free software; you can redistribute it and#or modify  #
#    it under the terms of the GNU General Public License as published by  #
#    the Free Software Foundation; either version 2 of the License, or     #
#    (at your option) any later version.                                   #
#                                                                          #
#    This program is distributed in the hope that it will be useful,       #
#    but WITHOUT ANY WARRANTY; without even the implied warranty of        #
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         #
#    GNU General Public License for more details.                          #
#                                                                          #
#    You should have received a copy of the GNU General Public License     #
#    along with this program; if not, write to the                         #
#    Free Software Foundation, Inc.,                                       #
#    59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             #
############################################################################

# >>> File inclusion guard
if { ! [ info exists _ENGINE_BACKWARD_STEPPING_TCL ] } {
set _ENGINE_BACKWARD_STEPPING_TCL _
# <<< File inclusion guard

# --------------------------------------------------------------------------
# DESCRIPTION
# Part of simulator engine functionality.
#
# --------------------------------------------------------------------------
# BACKWARD STEPPING RELATED PROCEDURES
# --------------------------------------------------------------------------

## Save current value of the given register for purpose of stepback operation
 # This function does not check for address validity !
 # @parm Char mem	- Memory type (one of {I E X S P})
 # @parm Int addr	- Register address
 # @return void
private method stepback_reg_change {mem addr} {
	if {!$stepback_ena} {return}
	if {[lsearch $stepback_local_regs $addr] != -1} {
		return
	}
	lappend stepback_local_regs $addr

	switch -- $mem {
		{I} {set val $ram($addr)	}
		{E} {set val $eram($addr)	}
		{X} {set val $xram($addr)	}
		{S} {set val $sfr($addr)	}
		{P} {set val $eeprom($addr)	}
	}
	lappend stepback_local [list $mem $addr $val]
}

## Save local stepback stack to global stepback stack
 # This function should be called after each instrucion
 # @return void
private method stepback_save_norm {} {
	if {!$stepback_ena} {return}
	lappend stepback_normal $stepback_local
	set stepback_local_regs {}
	set stepback_local {}
}

## Save special engine configuration variables for purpose of stepback operation
 # This function should be called before each instrucion
 # @return void
private method stepback_save_spec {} {
	if {!$stepback_ena} {return}
	incr stepback_length
	set discard [expr {$stepback_length - ${::Simulator::reverse_run_steps}}]
	if {$discard > 0} {
		incr stepback_length -$discard
		set stepback_spec	[lreplace $stepback_spec 0 0]
		set stepback_normal	[lreplace $stepback_normal 0 0]
	}

	lappend stepback_spec [simulator_get_special]
}

## Set the last list element in stepback to current time
 # @return void
private method stepback_save_spec_time {} {
	lset stepback_spec {end end} $time
}

## Set "subprog" value for stepback function.
 # This is important for list of subprograms and stack monitor
 # @parm Int action -
 #	6 - Instruction POP peformed
 #	5 - Instruction PUSH performed
 #	4 - Return from subprogram
 #	3 - Return from interrupt routine
 #	2 - Invocaton of subprogram
 #	1 - Invocaton of interrupt
 #	0 - Nothing mentioned above
 # @return void
private method stepback_save_spec_subprog {action} {
	lset stepback_spec {end 0} $action
}

## Discard stack for stepback functions
 # @return void
public method stepback_discard_stack {} {
	set stepback_local_regs	{}
	set stepback_normal	{}
	set stepback_spec	{}
	set stepback_local	{}
	set stepback_length	0
}

## Get stepback stack length
 # @return Int - stack length
public method simulator_get_SBS_len {} {
	if {${::Simulator::reverse_run_steps}} {
		return $stepback_length
	} else {
		return 0
	}
}

## Set stepback stack length
 # @parm Int value - stack length
 # @return void
public method simulator_set_SBS_len {value} {
	set stepback_length $value
}

# >>> File inclusion guard
}
# <<< File inclusion guard