fix interpreter to use positions
tick from one (simulated memory) position to the next (not from one instruction to the next)
This commit is contained in:
parent
8966a50a8a
commit
15e4533a2f
@ -31,10 +31,11 @@ module Risc
|
||||
end
|
||||
end
|
||||
|
||||
def start( instruction )
|
||||
def start_machine
|
||||
initialize
|
||||
init = Risc.machine.cpu_init
|
||||
set_state(:running)
|
||||
set_instruction( instruction )
|
||||
set_pc( Position.get(init).at )
|
||||
end
|
||||
|
||||
def set_state( state )
|
||||
@ -44,12 +45,22 @@ module Risc
|
||||
trigger(:state_changed , old , state )
|
||||
end
|
||||
|
||||
def set_pc( pos )
|
||||
raise "Not int #{pos}" unless pos.is_a? Numeric
|
||||
position = Position.at(pos)
|
||||
log.debug "Setting Position #{pos}"
|
||||
raise "not instruction position #{position}-#{position.class}-#{position.object.class}" unless position.is_a?(Position::InstructionPosition)
|
||||
set_instruction( position.instruction)
|
||||
@clock = position.at
|
||||
end
|
||||
|
||||
def set_instruction( instruction )
|
||||
raise "set to same instruction #{instruction}:#{instruction.class}" if @instruction == instruction
|
||||
log.debug "Setting Instruction #{instruction}"
|
||||
old = @instruction
|
||||
@instruction = instruction
|
||||
trigger(:instruction_changed, old , instruction)
|
||||
set_state( :exited) unless instruction
|
||||
set_state( :exited ) unless instruction
|
||||
end
|
||||
|
||||
def get_register( reg )
|
||||
@ -77,29 +88,32 @@ module Risc
|
||||
end
|
||||
|
||||
def tick
|
||||
return unless @instruction
|
||||
@clock += 1
|
||||
unless @instruction
|
||||
log.debug "No Instruction , No Tick"
|
||||
return @clock
|
||||
end
|
||||
name = @instruction.class.name.split("::").last
|
||||
log.debug "#{@clock.to_s}: #{@instruction.to_s}"
|
||||
fetch = send "execute_#{name}"
|
||||
log.debug register_dump
|
||||
return unless fetch
|
||||
set_instruction @instruction.next
|
||||
end
|
||||
|
||||
# Label is a noop.
|
||||
def execute_Label
|
||||
true
|
||||
if fetch
|
||||
clock = @clock + @instruction.byte_length
|
||||
set_pc(clock)
|
||||
else
|
||||
log.debug "No Fetch"
|
||||
end
|
||||
@clock
|
||||
end
|
||||
|
||||
# Instruction interpretation starts here
|
||||
def execute_DynamicJump
|
||||
method = get_register(@instruction.register)
|
||||
set_instruction( method.risc_instructions )
|
||||
false
|
||||
end
|
||||
def execute_Branch
|
||||
label = @instruction.label
|
||||
set_instruction label
|
||||
set_pc Position.get(label).at
|
||||
false
|
||||
end
|
||||
|
||||
|
@ -30,7 +30,10 @@ module Risc
|
||||
end
|
||||
class IdentityTranslator
|
||||
def translate(code)
|
||||
return Label.new( code.source , code.name ) if code.is_a?(Label)
|
||||
#return Label.new( code.source , code.name ) if code.is_a?(Label)
|
||||
if( code.is_a?(Branch))
|
||||
return code.class.new(code.source , code.label.to_cpu(self))
|
||||
end
|
||||
ret = code.dup
|
||||
ret.nil_next
|
||||
ret
|
||||
|
54
test/risc/test_interpreter.rb
Normal file
54
test/risc/test_interpreter.rb
Normal file
@ -0,0 +1,54 @@
|
||||
require_relative "helper"
|
||||
|
||||
module Risc
|
||||
class TestInterpreterBasics < MiniTest::Test
|
||||
|
||||
def test_class
|
||||
assert_equal Risc::Interpreter , Interpreter.new.class
|
||||
end
|
||||
def test_starts_stopped
|
||||
assert_equal :stopped , Interpreter.new.state
|
||||
end
|
||||
def test_has_regs
|
||||
assert_equal 12 , Interpreter.new.registers.length
|
||||
end
|
||||
def test_has_r0
|
||||
assert_equal :r0 , Interpreter.new.registers.keys.first
|
||||
end
|
||||
end
|
||||
class TestInterpreterStarts < MiniTest::Test
|
||||
def setup
|
||||
@machine = Risc.machine.boot
|
||||
@machine.translate(:interpreter)
|
||||
@machine.position_all
|
||||
@interpreter = Interpreter.new
|
||||
end
|
||||
def test_starts
|
||||
assert_equal 0 , @interpreter.start_machine
|
||||
end
|
||||
def test_started
|
||||
@interpreter.start_machine
|
||||
assert_equal :running , @interpreter.state
|
||||
end
|
||||
def test_pos
|
||||
@interpreter.start_machine
|
||||
assert_equal 0 , @interpreter.clock
|
||||
end
|
||||
end
|
||||
class TestInterpreterTicks < MiniTest::Test
|
||||
def setup
|
||||
@machine = Risc.machine.boot
|
||||
@machine.translate(:interpreter)
|
||||
@machine.position_all
|
||||
@interpreter = Interpreter.new
|
||||
@interpreter.start_machine
|
||||
end
|
||||
def test_tick
|
||||
assert_equal 19484 , @interpreter.tick
|
||||
end
|
||||
def test_tick
|
||||
assert_equal 19484 , @interpreter.tick
|
||||
assert_equal 19488 , @interpreter.tick
|
||||
end
|
||||
end
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user