class AVR::CPU
Constants
- I
Attributes
clock[R]
decoder[R]
device[R]
io_registers[R]
next_pc[RW]
pc[RW]
ports[R]
registers[R]
sp[R]
sram[R]
sreg[R]
tracer[R]
Public Class Methods
new(device)
click to toggle source
# File lib/avr/cpu.rb, line 82 def initialize(device) @device = device @pc = 0 @next_pc = 0 @sram = SRAM.new(device.ram_start + device.sram_size) @registers = RegisterFile.new(self) device.register_count.times do |n| registers.add(MemoryByteRegister.new(self, "r#{n}", @sram.memory[n])) end device.word_register_map.each do |name, map| registers.add(RegisterPair.new(self, @registers[map[:l]], @registers[map[:h]], name)) end @io_registers = RegisterFile.new(self) device.io_registers.each do |name| address = device.data_memory_map[name] next unless address bit_names = device.register_bit_names_map[name] if bit_names io_registers.add(MemoryByteRegisterWithNamedBits.new(self, name.to_s, @sram.memory[address], bit_names)) else io_registers.add(MemoryByteRegister.new(self, name.to_s, @sram.memory[address])) end end @sreg = SREG.new(self) @sp = SP.new( self, @sram.memory[device.data_memory_map[:SPL]], @sram.memory[device.data_memory_map[:SPH]], device.ram_end ) @decoder = OpcodeDecoder.new @ports = {} device.port_map.each do |name, addr| @ports[name] = Port.new(self, name, addr[:pin], addr[:ddr], addr[:port]) end @clock = Clock.new('cpu') @clock.push_sink(Clock::Sink.new('cpu') { step }) @tracer = nil end
Public Instance Methods
X()
click to toggle source
# File lib/avr/cpu.rb, line 44 def X registers.fetch(:X) end
Y()
click to toggle source
# File lib/avr/cpu.rb, line 49 def Y registers.fetch(:Y) end
Z()
click to toggle source
# File lib/avr/cpu.rb, line 54 def Z registers.fetch(:Z) end
decode()
click to toggle source
# File lib/avr/cpu.rb, line 212 def decode offset = next_pc word = fetch decoded_opcode = decoder.decode(word) unless decoded_opcode raise 'Unable to decode 0x%04x at offset 0x%04x words (0x%04x bytes)' % [ word, offset, offset * 2, ] end decoded_opcode.opcode_definition.parse( self, decoded_opcode.opcode_definition, decoded_opcode.prepare_operands(self) ) end
fetch()
click to toggle source
# File lib/avr/cpu.rb, line 187 def fetch word = device.flash.word(next_pc) @next_pc += 1 word end
instruction(mnemonic, *args)
click to toggle source
# File lib/avr/cpu.rb, line 194 def instruction(mnemonic, *args) Instruction.new(self, mnemonic, args) end
interrupt(name_or_vector_number)
click to toggle source
# File lib/avr/cpu.rb, line 199 def interrupt(name_or_vector_number) sreg.I = false case name_or_vector_number when Integer address = name_or_vector_number * 2 when Symbol address = device.interrupt_vector_map[name_or_vector_number] end instruction(:call, Value.new(address)).execute end
notify_at_tick(tick, &block)
click to toggle source
# File lib/avr/cpu.rb, line 133 def notify_at_tick(tick, &block) clock.notify_at_tick(tick, Clock::Sink.new("notify #{block} at #{tick}", block.to_proc)) end
peek()
click to toggle source
# File lib/avr/cpu.rb, line 232 def peek save_pc = pc save_next_pc = next_pc i = decode @pc = save_pc @next_pc = save_next_pc i end
print_status()
click to toggle source
# File lib/avr/cpu.rb, line 144 def print_status puts 'Status:' puts '%8s = %d' % ['Ticks', clock.ticks] puts '%8s = %d opcodes' % ['Cache', decoder.cache.size] puts '%8s = 0x%04x words' % ['PC', pc] puts '%8s = 0x%04x bytes' % ['PC', pc * 2] puts '%8s = 0x%04x (%d bytes used)' % ['SP', sp.value, device.ram_end - sp.value] puts '%8s = 0x%02x [%s]' % ['SREG', sreg.value, sreg.bit_values] puts puts 'Registers:' registers.print_status puts puts 'IO Registers:' io_registers.print_status puts puts 'IO Ports:' puts '%4s %s' % ['', Port::PINS.join(' ')] ports.each do |name, port| puts '%4s: %s' % [name, port.pin_states.join(' ')] end puts puts 'Next instruction:' puts ' ' + peek.to_s puts end
r0()
click to toggle source
# File lib/avr/cpu.rb, line 24 def r0 registers.fetch(:r0) end
r0=(value)
click to toggle source
# File lib/avr/cpu.rb, line 29 def r0=(value) registers.fetch(:r0).value = value end
r1()
click to toggle source
# File lib/avr/cpu.rb, line 34 def r1 registers.fetch(:r1) end
r1=(value)
click to toggle source
# File lib/avr/cpu.rb, line 39 def r1=(value) registers.fetch(:r1).value = value end
reset()
click to toggle source
# File lib/avr/cpu.rb, line 180 def reset @pc = 0 @next_pc = 0 sreg.reset end
reset_to_clean_state()
click to toggle source
# File lib/avr/cpu.rb, line 171 def reset_to_clean_state reset registers.reset io_registers.reset sram.reset sp.value = device.ram_end end
step()
click to toggle source
# File lib/avr/cpu.rb, line 242 def step i = decode @tracer&.call(i) begin i.execute rescue StandardError puts "*** Caught exception while executing #{i}, CPU status:" print_status raise end end
trace(&block)
click to toggle source
# File lib/avr/cpu.rb, line 138 def trace(&block) @tracer = nil @tracer = block.to_proc if block_given? end