Class: AVR::EEPROM

Inherits:
Memory show all
Extended by:
T::Sig
Defined in:
lib/avr/memory/eeprom.rb

Constant Summary collapse

ERASED_VALUE =
0xff

Instance Attribute Summary collapse

Attributes inherited from Memory

#memory, #name, #size, #watches

Instance Method Summary collapse

Methods inherited from Memory

#inspect, #load_from_intel_hex, #notify, #push_watch, #reset, #set_word, #unshift_watch, #watch, #word

Constructor Details

#initialize(size, cpu) ⇒ EEPROM

Returns a new instance of EEPROM.



14
15
16
17
# File 'lib/avr/memory/eeprom.rb', line 14

def initialize(size, cpu)
  super('EEPROM', size, ERASED_VALUE)
  attach(cpu)
end

Instance Attribute Details

#cpuObject (readonly)

Returns the value of attribute cpu.



11
12
13
# File 'lib/avr/memory/eeprom.rb', line 11

def cpu
  @cpu
end

Instance Method Details

#attach(cpu) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/avr/memory/eeprom.rb', line 20

def attach(cpu)
  @cpu = cpu
  @watched_memory_bytes = {
    cpu.EEARL.memory_byte => :EEARL,
    cpu.EEARH.memory_byte => :EEARH,
    cpu.EECR.memory_byte => :EECR,
    cpu.EEDR.memory_byte => :EEDR,
  }

  @cpu.sram.watch(@watched_memory_bytes.keys.map(&:address)) do |memory_byte, old_value, new_value|
    case @watched_memory_bytes[memory_byte]
    when :EECR
      handle_eecr(old_value, new_value)
    end
  end
end

#handle_eecr(old_value, new_value) ⇒ Object



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
# File 'lib/avr/memory/eeprom.rb', line 38

def handle_eecr(old_value, new_value)
  old_eecr = cpu.EECR.hash_for_value(old_value)
  new_eecr = cpu.EECR.hash_for_value(new_value)

  if !old_eecr[:EEMPE] && new_eecr[:EEMPE]
    cpu.notify_at_tick(cpu.clock.ticks + 4) do
      cpu.EECR.EEMPE = false
    end
  end

  if !old_eecr[:EEPE] && new_eecr[:EEPE] && new_eecr[:EEMPE]
    if (!new_eecr[:EEPM0] && !new_eecr[:EEPM1]) || new_eecr[:EEPM1]
      T.must(memory[(cpu.EEARH.value << 8) | cpu.EEARL.value]).value = cpu.EEDR.value
    elsif new_eecr[:EEPM0]
      T.must(memory[(cpu.EEARH.value << 8) | cpu.EEARL.value]).value = ERASED_VALUE
    end
    cpu.EECR.from_h({ EEMPE: false, EEPE: false })
  end

  if !old_eecr[:EERE] && new_eecr[:EERE]
    cpu.EEDR.value = T.must(memory[(cpu.EEARH.value << 8) | cpu.EEARL.value]).value
    cpu.EECR.EERE = false
  end

  cpu.interrupt(:EE_READY) if cpu.sreg.I && new_eecr[:EERIE]
end