class AVR::EEPROM

Constants

EEMPE
EERE
ERASED_VALUE

Attributes

cpu[R]

Public Class Methods

new(size, cpu) click to toggle source
Calls superclass method AVR::Memory::new
# File lib/avr/memory/eeprom.rb, line 14
def initialize(size, cpu)
  super('EEPROM', size, ERASED_VALUE)
  attach(cpu)
end

Public Instance Methods

attach(cpu) click to toggle source
# 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) click to toggle source
# 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