rpicsim 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -1
  3. data/Gemfile +7 -6
  4. data/Introduction.md +3 -1
  5. data/README.md +2 -2
  6. data/docs/ChangeLog.md +6 -0
  7. data/docs/Contributing.md +1 -1
  8. data/docs/DefiningSimulationClass.md +11 -10
  9. data/docs/HowMPLABXIsFound.md +1 -1
  10. data/docs/IntegrationTesting.md +1 -1
  11. data/docs/IntroductionToRSpec.md +8 -5
  12. data/docs/IntroductionToRuby.md +2 -2
  13. data/docs/KnownIssues.md +46 -57
  14. data/docs/Labels.md +5 -4
  15. data/docs/Manual.md +1 -1
  16. data/docs/Memories.md +70 -0
  17. data/docs/PersistentExpectations.md +31 -2
  18. data/docs/Pins.md +5 -7
  19. data/docs/PreventingCallStackOverflow.md +4 -6
  20. data/docs/QuickStartGuide.md +5 -5
  21. data/docs/RSpecIntegration.md +2 -2
  22. data/docs/RamWatcher.md +22 -11
  23. data/docs/Running.md +4 -6
  24. data/docs/Stubbing.md +4 -4
  25. data/docs/SupportedDevices.md +2 -11
  26. data/docs/SupportedMPLABXVersions.md +1 -0
  27. data/docs/SupportedOperatingSystems.md +3 -2
  28. data/docs/UnitTesting.md +1 -1
  29. data/docs/Variables.md +81 -25
  30. data/lib/rpicsim.rb +0 -12
  31. data/lib/rpicsim/call_stack_info.rb +43 -47
  32. data/lib/rpicsim/composite_memory.rb +53 -0
  33. data/lib/rpicsim/flaws.rb +34 -22
  34. data/lib/rpicsim/instruction.rb +204 -48
  35. data/lib/rpicsim/label.rb +4 -4
  36. data/lib/rpicsim/memory.rb +44 -23
  37. data/lib/rpicsim/memory_watcher.rb +14 -22
  38. data/lib/rpicsim/mplab.rb +38 -119
  39. data/lib/rpicsim/mplab/mplab_assembly.rb +23 -18
  40. data/lib/rpicsim/mplab/mplab_device_info.rb +9 -9
  41. data/lib/rpicsim/mplab/mplab_disassembler.rb +5 -6
  42. data/lib/rpicsim/mplab/mplab_instruction.rb +87 -16
  43. data/lib/rpicsim/mplab/mplab_loader.rb +106 -0
  44. data/lib/rpicsim/mplab/mplab_memory.rb +19 -6
  45. data/lib/rpicsim/mplab/mplab_nmmr_info.rb +4 -4
  46. data/lib/rpicsim/mplab/mplab_observer.rb +15 -10
  47. data/lib/rpicsim/mplab/mplab_pin.rb +3 -3
  48. data/lib/rpicsim/mplab/mplab_processor.rb +5 -5
  49. data/lib/rpicsim/mplab/mplab_program_file.rb +29 -17
  50. data/lib/rpicsim/mplab/mplab_register.rb +5 -5
  51. data/lib/rpicsim/mplab/mplab_sfr_info.rb +4 -4
  52. data/lib/rpicsim/mplab/mplab_simulator.rb +27 -30
  53. data/lib/rpicsim/pin.rb +6 -6
  54. data/lib/rpicsim/program_counter.rb +3 -3
  55. data/lib/rpicsim/program_file.rb +39 -81
  56. data/lib/rpicsim/rspec/be_predicate.rb +1 -1
  57. data/lib/rpicsim/rspec/helpers.rb +1 -1
  58. data/lib/rpicsim/rspec/persistent_expectations.rb +17 -2
  59. data/lib/rpicsim/rspec/sim_diagnostics.rb +5 -5
  60. data/lib/rpicsim/search.rb +1 -1
  61. data/lib/rpicsim/sim.rb +153 -228
  62. data/lib/rpicsim/stack_pointer.rb +41 -0
  63. data/lib/rpicsim/stack_trace.rb +1 -1
  64. data/lib/rpicsim/storage/memory_integer.rb +235 -0
  65. data/lib/rpicsim/{register.rb → storage/register.rb} +18 -18
  66. data/lib/rpicsim/variable.rb +25 -211
  67. data/lib/rpicsim/variable_set.rb +93 -0
  68. data/lib/rpicsim/version.rb +2 -2
  69. metadata +9 -4
  70. data/docs/SFRs.md +0 -71
@@ -0,0 +1,41 @@
1
+ module RPicSim
2
+ # Instances of this class represent the call stack pointer in a running
3
+ # simulation.
4
+ # A value of 0 means that the stack is empty, regardless of what device
5
+ # architecture you are simulating.
6
+ class StackPointer
7
+ # Initializes the StackPointer object.
8
+ # This be called when the call stack is empty, because this object uses
9
+ # the initial value of stkptr to deduce how it works.
10
+ # @param stkptr The STKPTR register of the simulation.
11
+ def initialize(stkptr)
12
+ @stkptr = stkptr
13
+ @stkptr_initial_value = @stkptr.value
14
+ end
15
+
16
+ def value
17
+ if @stkptr_initial_value > 0
18
+ raw_value = @stkptr.value
19
+ if raw_value == @stkptr_initial_value
20
+ 0
21
+ else
22
+ raw_value + 1
23
+ end
24
+ else
25
+ @stkptr.value
26
+ end
27
+ end
28
+
29
+ def value=(value)
30
+ @stkptr.value = if @stkptr_initial_value > 0
31
+ if value == 0
32
+ @stkptr_initial_value
33
+ else
34
+ value - 1
35
+ end
36
+ else
37
+ value
38
+ end
39
+ end
40
+ end
41
+ end
@@ -29,4 +29,4 @@ module RPicSim
29
29
  description
30
30
  end
31
31
  end
32
- end
32
+ end
@@ -0,0 +1,235 @@
1
+ module RPicSim::Storage
2
+ # This class and its subclasses represent integers stored in RAM.
3
+ class MemoryInteger
4
+ attr_reader :name, :address
5
+ attr_writer :memory
6
+
7
+ # Creates a new MemoryInteger object not bound to any memory yet.
8
+ # @param name [Symbol] The name of the variable.
9
+ # @param address [Integer] should be the address of the variable
10
+ def initialize(name, address)
11
+ @name = name
12
+ @address = address
13
+ end
14
+
15
+ # Creates a new Variable that is bound to the specified memory.
16
+ # @param memory [RPicSim::Memory]
17
+ def bind(memory)
18
+ bound_var = dup
19
+ bound_var.memory = memory
20
+ bound_var
21
+ end
22
+
23
+ # @return [Range] The addresses of each byte that is part of this variable.
24
+ def addresses
25
+ address ... (address + size)
26
+ end
27
+
28
+ # Reads the value of the variable from memory.
29
+ # @return [Integer]
30
+ def value
31
+ raise NoMethodError, 'value not implemented'
32
+ end
33
+
34
+ # Writes to the value to the variable's memory.
35
+ # @return [Integer]
36
+ def value=(val)
37
+ raise NoMethodError, 'value= not implemented'
38
+ end
39
+
40
+ def memory_value=(val)
41
+ self.value = val
42
+ end
43
+
44
+ def memory_value(val)
45
+ value
46
+ end
47
+
48
+ def to_s
49
+ name.to_s
50
+ end
51
+
52
+ def inspect
53
+ '<%s %s 0x%x>' % [self.class, name, address]
54
+ end
55
+
56
+ private
57
+ def check_value(value, allowed_values)
58
+ if !allowed_values.include?(value)
59
+ raise ArgumentError, "Invalid value #{value} written to #{name}."
60
+ end
61
+ end
62
+ end
63
+
64
+ # Represents an unsigned 8-bit variable.
65
+ class MemoryUInt8 < MemoryInteger
66
+ def size
67
+ 1
68
+ end
69
+
70
+ def value
71
+ @memory.read_byte(@address)
72
+ end
73
+
74
+ def value=(val)
75
+ check_value val, 0..255
76
+ @memory.write_byte(@address, val)
77
+ end
78
+
79
+ end
80
+
81
+ # Represents a signed 8-bit variable.
82
+ class MemoryInt8 < MemoryInteger
83
+ def size
84
+ 1
85
+ end
86
+
87
+ def value
88
+ val = @memory.read_byte(@address)
89
+ val -= 0x100 if val >= 0x80
90
+ val
91
+ end
92
+
93
+ def value=(val)
94
+ check_value val, -0x80...0x80
95
+ @memory.write_byte(@address, val & 0xFF)
96
+ @memory.write_byte(@address + 1, (val >> 8) & 0xFF)
97
+ end
98
+ end
99
+
100
+ # Represents an unsigned 16-bit variable.
101
+ class MemoryUInt16 < MemoryInteger
102
+ def size
103
+ 2
104
+ end
105
+
106
+ def value
107
+ @memory.read_byte(@address) + 256 * @memory.read_byte(@address + 1)
108
+ end
109
+
110
+ def value=(val)
111
+ check_value val, 0...0x10000
112
+ @memory.write_byte(@address, val & 0xFF)
113
+ @memory.write_byte(@address + 1, (val >> 8) & 0xFF)
114
+ end
115
+ end
116
+
117
+ # Represents a signed 16-bit variable.
118
+ class MemoryInt16 < MemoryInteger
119
+ def size
120
+ 2
121
+ end
122
+
123
+ def value
124
+ val = @memory.read_byte(@address) + 256 * @memory.read_byte(@address + 1)
125
+ val -= 0x10000 if val >= 0x8000
126
+ val
127
+ end
128
+
129
+ def value=(val)
130
+ check_value val, -0x8000...0x8000
131
+ @memory.write_byte(@address, val & 0xFF)
132
+ @memory.write_byte(@address + 1, (val >> 8) & 0xFF)
133
+ end
134
+ end
135
+
136
+ # Represents an unsigned 24-bit variable.
137
+ class MemoryUInt24 < MemoryInteger
138
+ def size
139
+ 3
140
+ end
141
+
142
+ def value
143
+ @memory.read_byte(@address) + 0x100 * @memory.read_byte(@address + 1) +
144
+ 0x10000 * @memory.read_byte(@address + 2)
145
+ end
146
+
147
+ def value=(val)
148
+ check_value val, 0...0x1000000
149
+ @memory.write_byte(@address, val & 0xFF)
150
+ @memory.write_byte(@address + 1, (val >> 8) & 0xFF)
151
+ @memory.write_byte(@address + 2, (val >> 16) & 0xFF)
152
+ end
153
+ end
154
+
155
+ # Represents a signed 24-bit variable.
156
+ class MemoryInt24 < MemoryInteger
157
+ def size
158
+ 3
159
+ end
160
+
161
+ def value
162
+ val = @memory.read_byte(@address) + 0x100 * @memory.read_byte(@address + 1) +
163
+ 0x10000 * @memory.read_byte(@address + 2)
164
+ val -= 0x1000000 if val >= 0x800000
165
+ val
166
+ end
167
+
168
+ def value=(val)
169
+ check_value val, -0x800000..0x800000
170
+ @memory.write_byte(@address, val & 0xFF)
171
+ @memory.write_byte(@address + 1, (val >> 8) & 0xFF)
172
+ @memory.write_byte(@address + 2, (val >> 16) & 0xFF)
173
+ end
174
+ end
175
+
176
+ # Represents an unsigned 32-bit variable.
177
+ class MemoryUInt32 < MemoryInteger
178
+ def size
179
+ 4
180
+ end
181
+
182
+ def value
183
+ @memory.read_byte(@address) + 0x100 * @memory.read_byte(@address + 1) +
184
+ 0x10000 * @memory.read_byte(@address + 2) +
185
+ 0x1000000 * @memory.read_byte(@address + 3)
186
+ end
187
+
188
+ def value=(val)
189
+ check_value val, 0...0x100000000
190
+ @memory.write_byte(@address, val & 0xFF)
191
+ @memory.write_byte(@address + 1, (val >> 8) & 0xFF)
192
+ @memory.write_byte(@address + 2, (val >> 16) & 0xFF)
193
+ @memory.write_byte(@address + 3, (val >> 24) & 0xFF)
194
+ end
195
+ end
196
+
197
+ # Represents a signed 32-bit variable.
198
+ class MemoryInt32 < MemoryInteger
199
+ def size
200
+ 4
201
+ end
202
+
203
+ def value
204
+ val = @memory.read_byte(@address) + 0x100 * @memory.read_byte(@address + 1) +
205
+ 0x10000 * @memory.read_byte(@address + 2) +
206
+ 0x1000000 * @memory.read_byte(@address + 3) +
207
+ 0x100000000 * @memory.read_byte(@address + 4)
208
+ val -= 0x100000000 if val >= 0x80000000
209
+ val
210
+ end
211
+
212
+ def value=(val)
213
+ check_value val, -0x80000000..0x80000000
214
+ @memory.write_byte(@address, val & 0xFF)
215
+ @memory.write_byte(@address + 1, (val >> 8) & 0xFF)
216
+ @memory.write_byte(@address + 2, (val >> 16) & 0xFF)
217
+ @memory.write_byte(@address + 3, (val >> 24) & 0xFF)
218
+ end
219
+ end
220
+
221
+ # Represents a word-sized variable.
222
+ # The size of the word will depend on the memory the variable lives in.
223
+ class MemoryWord < MemoryInteger
224
+ attr_accessor :size
225
+
226
+ def value
227
+ @memory.read_word(@address)
228
+ end
229
+
230
+ def value=(val)
231
+ @memory.write_word(@address, val)
232
+ end
233
+ end
234
+
235
+ end
@@ -1,16 +1,16 @@
1
- module RPicSim
1
+ module RPicSim::Storage
2
2
  class Register
3
3
  attr_reader :name
4
-
4
+
5
5
  # The size of the register in bytes.
6
6
  attr_reader :size
7
-
7
+
8
8
  # @param mplab_register [Mplab::MplabRegister]
9
9
  # @param memory An optional parameter that enables memory_value.
10
10
  def initialize(mplab_register, memory, width)
11
11
  @mplab_register = mplab_register
12
12
  @name = mplab_register.name.to_sym
13
-
13
+
14
14
  @size = case width
15
15
  when 8 then 1
16
16
  when 16 then 2
@@ -18,14 +18,14 @@ module RPicSim
18
18
  when 32 then 4
19
19
  else raise "Unsupported register width: #{name} is #{width}-bit."
20
20
  end
21
-
21
+
22
22
  var_type = case size
23
- when 1 then VariableU8
24
- when 2 then VariableU16
25
- when 3 then VariableU24
26
- when 4 then VariableU32
23
+ when 1 then MemoryUInt8
24
+ when 2 then MemoryUInt16
25
+ when 3 then MemoryUInt24
26
+ when 4 then MemoryUInt32
27
27
  end
28
-
28
+
29
29
  @var = var_type.new(name, address).bind(memory)
30
30
  end
31
31
 
@@ -34,13 +34,13 @@ module RPicSim
34
34
  def value=(val)
35
35
  @mplab_register.write val
36
36
  end
37
-
37
+
38
38
  # Reads the value of the register.
39
39
  # @return [Integer]
40
40
  def value
41
41
  @mplab_register.read
42
42
  end
43
-
43
+
44
44
  # For some registers, like STATUS, you cannot read and write the full
45
45
  # range of possible values using {#value=} because some bits are not
46
46
  # writable by the CPU.
@@ -49,7 +49,7 @@ module RPicSim
49
49
  def memory_value=(value)
50
50
  @var.value = value
51
51
  end
52
-
52
+
53
53
  # Reads the value directly from the memory object backing the register.
54
54
  def memory_value
55
55
  @var.value
@@ -60,19 +60,19 @@ module RPicSim
60
60
  def address
61
61
  @mplab_register.address
62
62
  end
63
-
63
+
64
64
  # Gets the range of addresses occupied.
65
65
  # @return [Range] A range of integers.
66
66
  def addresses
67
67
  address...(address + size)
68
68
  end
69
-
69
+
70
70
  def to_s
71
71
  name.to_s
72
72
  end
73
-
73
+
74
74
  def inspect
75
- "<%s %s 0x%x>" % [self.class, name, address]
75
+ '<%s %s 0x%x>' % [self.class, name, address]
76
76
  end
77
77
  end
78
- end
78
+ end
@@ -1,236 +1,50 @@
1
1
  module RPicSim
2
- # This class and its subclasses represent firmware-defined variables
3
- # in RAM or flash.
4
- #
5
- # Instances of this class come in two varieties:
6
- # - Unbound variables are just a name and an address.
7
- # - Bound variables have a name and an address and they are attached to
8
- # a memory object so you can actually read and write values from them.
9
2
  class Variable
10
- module ClassMethods
11
- # @return (Integer) The size of this type of variable in memory words.
12
- attr_reader :size
13
-
14
- # Specifies the size of this class of variables in memory words.
15
- # The units for this are usually bytes for RAM and more than a byte
16
- # for flash. This should be called inside the definition of a subclass of
17
- # {Variable}, not from anywhere else.
18
- def size_is(size)
19
- @size = size
20
- end
21
- end
22
-
23
- extend ClassMethods
24
-
25
- attr_reader :name, :address
26
- attr_writer :memory
27
-
28
- # Creates a new Variable object not bound to any memory yet.
29
- # @param name [Symbol] The name of the variable.
30
- # @param address [Integer] should be the address of the variable
31
- def initialize(name, address)
32
- @name = name
33
- @address = address
34
- end
35
-
36
- # Creates a new Variable that is bound to the specified memory.
37
- # @param memory [RPicSim::Memory]
38
- def bind(memory)
39
- bound_var = dup
40
- bound_var.memory = memory
41
- bound_var
42
- end
43
-
44
- # @return [Range] The addresses of each byte that is part of this variable.
45
- def addresses
46
- address ... (address + self.class.size)
3
+ # Creates a new Variable object.
4
+ # @param storage The internal storage for the variable.
5
+ def initialize(storage)
6
+ @storage = storage
47
7
  end
48
8
 
49
- # Reads the value of the variable from memory.
9
+ # Reads the value of the variable.
50
10
  # @return [Integer]
51
11
  def value
52
- raise NoMethodError, "value not implemented"
12
+ @storage.value
53
13
  end
54
14
 
55
- # Writes to the value to the variable's memory.
15
+ # Writes the value to the variable.
56
16
  # @return [Integer]
57
17
  def value=(val)
58
- raise NoMethodError, "value= not implemented"
59
- end
60
-
61
- def to_s
62
- name.to_s
63
- end
64
-
65
- def inspect
66
- "<%s %s 0x%x>" % [self.class, name, address]
67
- end
68
-
69
- private
70
- def check_value(value, allowed_values)
71
- if !allowed_values.include?(value)
72
- raise ArgumentError, "Invalid value #{value} written to #{name}."
73
- end
74
- end
75
- end
76
-
77
- # Represents an unsigned 8-bit variable.
78
- class VariableU8 < Variable
79
- size_is 1
80
-
81
- def value
82
- @memory.read_word(@address)
83
- end
84
-
85
- def value=(val)
86
- check_value val, 0..255
87
- @memory.write_word(@address, val)
88
- end
89
-
90
- end
91
-
92
- # Represents a signed 8-bit variable.
93
- class VariableS8 < Variable
94
- size_is 1
95
-
96
- def value
97
- val = @memory.read_word(@address)
98
- val -= 0x100 if val >= 0x80
99
- val
100
- end
101
-
102
- def value=(val)
103
- check_value val, -0x80...0x80
104
- @memory.write_word(@address, val & 0xFF)
105
- @memory.write_word(@address + 1, (val >> 8) & 0xFF)
106
- end
107
- end
108
-
109
- # Represents an unsigned 16-bit variable.
110
- class VariableU16 < Variable
111
- size_is 2
112
-
113
- def value
114
- @memory.read_word(@address) + 256 * @memory.read_word(@address + 1)
115
- end
116
-
117
- def value=(val)
118
- check_value val, 0...0x10000
119
- @memory.write_word(@address, val & 0xFF)
120
- @memory.write_word(@address + 1, (val >> 8) & 0xFF)
121
- end
122
- end
123
-
124
- # Represents a signed 16-bit variable.
125
- class VariableS16 < Variable
126
- size_is 2
127
-
128
- def value
129
- val = @memory.read_word(@address) + 256 * @memory.read_word(@address + 1)
130
- val -= 0x10000 if val >= 0x8000
131
- val
132
- end
133
-
134
- def value=(val)
135
- check_value val, -0x8000...0x8000
136
- @memory.write_word(@address, val & 0xFF)
137
- @memory.write_word(@address + 1, (val >> 8) & 0xFF)
138
- end
139
- end
140
-
141
- # Represents an unsigned 24-bit variable.
142
- class VariableU24 < Variable
143
- size_is 3
144
-
145
- def value
146
- @memory.read_word(@address) + 0x100 * @memory.read_word(@address + 1) +
147
- 0x10000 * @memory.read_word(@address + 2)
148
- end
149
-
150
- def value=(val)
151
- check_value val, 0...0x1000000
152
- @memory.write_word(@address, val & 0xFF)
153
- @memory.write_word(@address + 1, (val >> 8) & 0xFF)
154
- @memory.write_word(@address + 2, (val >> 16) & 0xFF)
155
- end
156
- end
157
-
158
- # Represents a signed 24-bit variable.
159
- class VariableS24 < Variable
160
- size_is 3
161
-
162
- def value
163
- val = @memory.read_word(@address) + 0x100 * @memory.read_word(@address + 1) +
164
- 0x10000 * @memory.read_word(@address + 2)
165
- val -= 0x1000000 if val >= 0x800000
166
- val
167
- end
168
-
169
- def value=(val)
170
- check_value val, -0x800000..0x800000
171
- @memory.write_word(@address, val & 0xFF)
172
- @memory.write_word(@address + 1, (val >> 8) & 0xFF)
173
- @memory.write_word(@address + 2, (val >> 16) & 0xFF)
18
+ @storage.value = val
174
19
  end
175
- end
176
-
177
- # Represents an unsigned 32-bit variable.
178
- class VariableU32 < Variable
179
- size_is 4
180
20
 
181
- def value
182
- @memory.read_word(@address) + 0x100 * @memory.read_word(@address + 1) +
183
- 0x10000 * @memory.read_word(@address + 2) +
184
- 0x1000000 * @memory.read_word(@address + 3)
21
+ # Writes the value to the variable in a lower-level way that
22
+ # overrides any read-only bits.
23
+ # For some types of variables, this is the same as {#value=}.
24
+ def memory_value=(val)
25
+ @storage.memory_value = val
185
26
  end
186
27
 
187
- def value=(val)
188
- check_value val, 0...0x100000000
189
- @memory.write_word(@address, val & 0xFF)
190
- @memory.write_word(@address + 1, (val >> 8) & 0xFF)
191
- @memory.write_word(@address + 2, (val >> 16) & 0xFF)
192
- @memory.write_word(@address + 3, (val >> 24) & 0xFF)
28
+ # Reads the value directly from the memory object backing the register.
29
+ # For some types of variables, this is the same as {#value}.
30
+ def memory_value
31
+ @storage.memory_value
193
32
  end
194
- end
195
33
 
196
- # Represents a signed 32-bit variable.
197
- class VariableS32 < Variable
198
- size_is 4
199
-
200
- def value
201
- val = @memory.read_word(@address) + 0x100 * @memory.read_word(@address + 1) +
202
- 0x10000 * @memory.read_word(@address + 2) +
203
- 0x1000000 * @memory.read_word(@address + 3) +
204
- 0x100000000 * @memory.read_word(@address + 4)
205
- val -= 0x100000000 if val >= 0x80000000
206
- val
34
+ def to_s
35
+ @storage.to_s
207
36
  end
208
37
 
209
- def value=(val)
210
- check_value val, -0x80000000..0x80000000
211
- @memory.write_word(@address, val & 0xFF)
212
- @memory.write_word(@address + 1, (val >> 8) & 0xFF)
213
- @memory.write_word(@address + 2, (val >> 16) & 0xFF)
214
- @memory.write_word(@address + 3, (val >> 24) & 0xFF)
38
+ def addresses
39
+ @storage.addresses
215
40
  end
216
- end
217
-
218
- # Represents a word-sized variable.
219
- # The size of the word will depend on the memory the variable lives in.
220
- class VariableWord < Variable
221
- size_is 1
222
-
223
- attr_writer :max_value
224
41
 
225
- def value
226
- @memory.read_word(@address)
42
+ def address
43
+ @storage.address
227
44
  end
228
45
 
229
- def value=(val)
230
- if @max_value
231
- check_value val, 0..@max_value
232
- end
233
- @memory.write_word(@address, val)
46
+ def name
47
+ @storage.name
234
48
  end
235
49
  end
236
50
  end