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:
Torsten Ruger 2018-05-17 20:14:59 +03:00
parent 8966a50a8a
commit 15e4533a2f
3 changed files with 85 additions and 14 deletions

View File

@ -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

View File

@ -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

View 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