diff --git a/lib/parfait/integer.rb b/lib/parfait/integer.rb index 0c380725..595c92c7 100644 --- a/lib/parfait/integer.rb +++ b/lib/parfait/integer.rb @@ -49,6 +49,13 @@ module Parfait # :>, :>=, :<, :<=, :between? end + # Marker class. Same functionality as Integer + # (ie carrying an int, the return address) + # + # But the integer (address) needs to be adjusted by load address. + class ReturnAddress < Integer + end + # adding other base classes in here for now: class FalseClass < Data4 #FIXME: this is "just" for compilation diff --git a/lib/risc/boot.rb b/lib/risc/boot.rb index 7a534843..eae07d36 100644 --- a/lib/risc/boot.rb +++ b/lib/risc/boot.rb @@ -118,8 +118,8 @@ module Risc # superclasses other than default object def super_class_names { Data4: :DataObject , Data8: :DataObject ,Data16: :DataObject , - BinaryCode: :Data16 , Integer: :Data4, Word: :Data8 , - Object: :BasicObject , List: :Data16} + BinaryCode: :Data16 , Integer: :Data4 , Word: :Data8 , + Object: :BasicObject , List: :Data16 , ReturnAddress: :Integer} end # the function really just returns a constant (just avoiding the constant) @@ -132,6 +132,7 @@ module Risc return_address: :Integer, return_value: :Object, caller: :Message , name: :Word , arguments: :NamedList }, Integer: {next_integer: :Integer}, + ReturnAddress: {next_integer: :Integer}, DataObject: {}, Data4: {}, Data8: {}, diff --git a/lib/risc/instructions/label.rb b/lib/risc/instructions/label.rb index 4d76781e..01305c7d 100644 --- a/lib/risc/instructions/label.rb +++ b/lib/risc/instructions/label.rb @@ -66,8 +66,7 @@ module Risc # if none was given def self.label( source , name , position = nil , nekst = nil) unless position - position = Parfait.object_space.get_integer - Risc.machine.add_constant(position) + position = Risc.machine.get_address end Label.new( source , name , position, nekst ) end diff --git a/lib/risc/machine.rb b/lib/risc/machine.rb index a0b62637..6b30c6d1 100644 --- a/lib/risc/machine.rb +++ b/lib/risc/machine.rb @@ -20,6 +20,7 @@ module Risc @booted = false @risc_init = nil @constants = [] + @next_address = nil end attr_reader :constants , :cpu_init attr_reader :booted , :translated @@ -61,6 +62,17 @@ module Risc @constants << const end + # hand out a return address for use as constant the address is added + def get_address + 10.times do # 10 for whole pages + @next_address = Parfait::ReturnAddress.new(0,@next_address) + add_constant( @next_address ) + end unless @next_address + addr = @next_address + @next_address = @next_address.next_integer + addr + end + # To create binaries, objects (and labels) need to have a position # (so objects can be loaded and branches know where to jump) # diff --git a/lib/risc/text_writer.rb b/lib/risc/text_writer.rb index b886e8bb..dd6a6dba 100644 --- a/lib/risc/text_writer.rb +++ b/lib/risc/text_writer.rb @@ -148,8 +148,8 @@ module Risc def write_integer( int ) write_ref_for( int.get_type ) write_ref_for( int.next_integer ) - @stream.write_signed_int_32( int.value ) - @stream.write_signed_int_32( 0 ) + write_ref_for( int.value ) + write_ref_for( 0 ) log.debug "Integer witten stream 0x#{@stream.length.to_s(16)}" end diff --git a/test/parfait/test_integer.rb b/test/parfait/test_integer.rb index 40b69d84..e2a61d12 100644 --- a/test/parfait/test_integer.rb +++ b/test/parfait/test_integer.rb @@ -48,4 +48,18 @@ module Parfait assert_equal 1 , @int.value end end + class AddressTest < ParfaitTest + def test_address + assert ReturnAddress.new(55) + end + def test_value + assert_equal 55 , ReturnAddress.new(55).value + end + def test_value_set + addr = ReturnAddress.new(55) + addr.set_value(33) + assert_equal 33 , addr.value + end + end + end diff --git a/test/risc/interpreter/calling/test_minus.rb b/test/risc/interpreter/calling/test_minus.rb index d695827e..6c91bb3c 100644 --- a/test/risc/interpreter/calling/test_minus.rb +++ b/test/risc/interpreter/calling/test_minus.rb @@ -46,7 +46,7 @@ module Risc ret = main_ticks(63) assert_equal FunctionReturn , ret.class assert_equal :r1 , ret.register.symbol - assert_equal 19460 , @interpreter.get_register(ret.register) + assert_equal 20612 , @interpreter.get_register(ret.register) end def test_sys sys = main_ticks(65) diff --git a/test/risc/test_interpreter.rb b/test/risc/test_interpreter.rb index 53570754..b96c8366 100644 --- a/test/risc/test_interpreter.rb +++ b/test/risc/test_interpreter.rb @@ -52,7 +52,7 @@ module Risc end def test_pc1 @interpreter.tick - assert_equal 19224 , @interpreter.pc + assert_equal 20376 , @interpreter.pc end def test_tick2 @interpreter.tick @@ -66,7 +66,7 @@ module Risc def test_pc2 @interpreter.tick @interpreter.tick - assert_equal 19228 , @interpreter.pc + assert_equal 20380 , @interpreter.pc end def test_tick_14_jump 14.times {@interpreter.tick} diff --git a/test/risc/test_machine.rb b/test/risc/test_machine.rb index a5aa8d6c..7f7e1d44 100644 --- a/test/risc/test_machine.rb +++ b/test/risc/test_machine.rb @@ -17,6 +17,22 @@ module Risc def test_constant assert @machine.add_constant( Parfait::Integer.new(5) ) end + def test_address_get + assert_equal Parfait::ReturnAddress , @machine.get_address.class + end + def test_address_is_constant + addr = @machine.get_address + assert @machine.constants.include?(addr) + end + def test_address_count + addr = @machine.get_address + count = 0 + while(addr) + count += 1 + addr = addr.next_integer + end + assert_equal 5, count + end end class TestMachineInit < MiniTest::Test def setup @@ -29,10 +45,10 @@ module Risc assert_equal 0 , Position.get(@machine.cpu_init).at end def test_cpu_at - assert_equal "0x5a54" , Position.get(@machine.cpu_init.first).to_s + assert_equal "0x5ed4" , Position.get(@machine.cpu_init.first).to_s end def test_cpu_bin - assert_equal "0x5a4c" , Position.get(Position.get(@machine.cpu_init.first).binary).to_s + assert_equal "0x5ecc" , Position.get(Position.get(@machine.cpu_init.first).binary).to_s end def test_cpu_label assert_equal Position::InstructionPosition , Position.get(@machine.cpu_init.first).class