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
|
||||||
end
|
end
|
||||||
|
|
||||||
def start( instruction )
|
def start_machine
|
||||||
initialize
|
initialize
|
||||||
|
init = Risc.machine.cpu_init
|
||||||
set_state(:running)
|
set_state(:running)
|
||||||
set_instruction( instruction )
|
set_pc( Position.get(init).at )
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_state( state )
|
def set_state( state )
|
||||||
@ -44,12 +45,22 @@ module Risc
|
|||||||
trigger(:state_changed , old , state )
|
trigger(:state_changed , old , state )
|
||||||
end
|
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 )
|
def set_instruction( instruction )
|
||||||
raise "set to same instruction #{instruction}:#{instruction.class}" if @instruction == instruction
|
raise "set to same instruction #{instruction}:#{instruction.class}" if @instruction == instruction
|
||||||
|
log.debug "Setting Instruction #{instruction}"
|
||||||
old = @instruction
|
old = @instruction
|
||||||
@instruction = instruction
|
@instruction = instruction
|
||||||
trigger(:instruction_changed, old , instruction)
|
trigger(:instruction_changed, old , instruction)
|
||||||
set_state( :exited) unless instruction
|
set_state( :exited ) unless instruction
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_register( reg )
|
def get_register( reg )
|
||||||
@ -77,29 +88,32 @@ module Risc
|
|||||||
end
|
end
|
||||||
|
|
||||||
def tick
|
def tick
|
||||||
return unless @instruction
|
unless @instruction
|
||||||
@clock += 1
|
log.debug "No Instruction , No Tick"
|
||||||
|
return @clock
|
||||||
|
end
|
||||||
name = @instruction.class.name.split("::").last
|
name = @instruction.class.name.split("::").last
|
||||||
log.debug "#{@clock.to_s}: #{@instruction.to_s}"
|
log.debug "#{@clock.to_s}: #{@instruction.to_s}"
|
||||||
fetch = send "execute_#{name}"
|
fetch = send "execute_#{name}"
|
||||||
log.debug register_dump
|
log.debug register_dump
|
||||||
return unless fetch
|
if fetch
|
||||||
set_instruction @instruction.next
|
clock = @clock + @instruction.byte_length
|
||||||
end
|
set_pc(clock)
|
||||||
|
else
|
||||||
# Label is a noop.
|
log.debug "No Fetch"
|
||||||
def execute_Label
|
end
|
||||||
true
|
@clock
|
||||||
end
|
end
|
||||||
|
|
||||||
# Instruction interpretation starts here
|
# Instruction interpretation starts here
|
||||||
def execute_DynamicJump
|
def execute_DynamicJump
|
||||||
method = get_register(@instruction.register)
|
method = get_register(@instruction.register)
|
||||||
set_instruction( method.risc_instructions )
|
set_instruction( method.risc_instructions )
|
||||||
|
false
|
||||||
end
|
end
|
||||||
def execute_Branch
|
def execute_Branch
|
||||||
label = @instruction.label
|
label = @instruction.label
|
||||||
set_instruction label
|
set_pc Position.get(label).at
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -30,7 +30,10 @@ module Risc
|
|||||||
end
|
end
|
||||||
class IdentityTranslator
|
class IdentityTranslator
|
||||||
def translate(code)
|
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 = code.dup
|
||||||
ret.nil_next
|
ret.nil_next
|
||||||
ret
|
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