class TestScript

An enclosure for the ca65 assembler.

An enclosure for the cc65 compiler.

An enclosure for the ld65 linker.

An enclosure for the sim65 simulator.

Utility methods

Public Class Methods

new(options={}) click to toggle source

Create a test script object and set up its default options.

# File lib/test65/perform_test.rb, line 12
def initialize(options={})
  @options = options.full_dup
  @phase   = :create

  @options[:objs] = []
  @options[:temps] = []

  cc65_initialize
  ca65_initialize
  ld65_initialize
  sim65_initialize

  @quiet = @options[:quiet].to_s
end

Public Instance Methods

adjust(files) click to toggle source

Adjust a list of files to include the path to the test file.

# File lib/test65/enclosures/utils.rb, line 22
def adjust(files)
  files.map { |file| @options[:path] + "/" + file }
end
append_option(key, *value) click to toggle source

Append to an option.

# File lib/test65/enclosures/utils.rb, line 17
def append_option(key, *value)
  @options[key] = ((@options[key] || []) + [value]).flatten
end
build_args(prefix = nil, args) click to toggle source

Construct a series of arguments.

# File lib/test65/enclosures/utils.rb, line 11
def build_args(prefix = nil, args)
  pre = prefix ? prefix + " " : ""
  args.inject("") {|str, arg| str << pre + arg + " "}
end
ca65(file, options="") click to toggle source

Assemble some files.

# File lib/test65/enclosures/ca65.rb, line 17
def ca65(file, options="")
  fail "Sequence error: ca65" unless @phase == :create
  source  = File.absolute_path(@options[:path] + "/" + file)
  target  = "--target #{@options[:ca65_target]} "
  paths   = build_args("-I", @options[:ca65_inc_paths])

  # Convert source assembler files into object files.
  object = change_type(source, ".o")
  list   = @options[:list] ? "-l " + change_type(source, ".lst") : ""
  command = "ca65 #{target}#{paths}#{list} #{options} -o #{object} #{source} #{@quiet}\n"
  puts command if @options[:debug]
  system(command)
  fail "Error assembling #{source.localize_path}" unless $?.exitstatus == 0

  @options[:objs] << object
end
ca65_inc_paths(*more_paths) click to toggle source

Add some include paths for the assembler.

# File lib/test65/enclosures/ca65.rb, line 11
def ca65_inc_paths(*more_paths)
  fail "Sequence error: ca65_inc_paths" unless @phase == :create
  append_option(:ca65_inc_paths, more_paths)
end
ca65_initialize() click to toggle source

Setup ca65

# File lib/test65/enclosures/ca65.rb, line 5
def ca65_initialize
  @options[:ca65_target] = "sim65c02"
  @options[:ca65_inc_paths] = ["#{@options[:gem_root]}/asminc"]
end
cc65(file, options="") click to toggle source

Compile some files.

# File lib/test65/enclosures/cc65.rb, line 17
def cc65(file, options="")
  fail "Sequence error: cc65" unless @phase == :create
  source = File.absolute_path(@options[:path] + "/" + file)
  target = "--target #{@options[:cc65_target]} "
  paths = build_args("--include-dir", @options[:cc65_inc_paths])

  # Convert source C files into assembler files.
  list = @options[:list] ? "--add-source " : " "
  command = "cc65 #{target}#{list}#{paths}#{options} #{source} #{@quiet}\n"
  puts command if @options[:debug]
  system(command)
  fail "Error compiling #{source.localize_path}" unless $?.exitstatus == 0

  # Convert intermediate assembler files into object files.
  temp = change_type(source, ".s")
  object = change_type(source, ".o")
  list   = @options[:list] ? "-l " + change_type(source, ".lst") : ""
  command = "ca65 #{target}#{list} -o #{object} #{temp} #{@quiet}\n"
  puts command if @options[:debug]
  system(command)
  fail "Error assembling #{source.localize_path}" unless $?.exitstatus == 0

  @options[:temps] << temp
  @options[:objs] << object
end
cc65_inc_paths(*more_paths) click to toggle source

Add some include paths for the compiler.

# File lib/test65/enclosures/cc65.rb, line 11
def cc65_inc_paths(*more_paths)
  fail "Sequence error: cc65_inc_paths" unless @phase == :create
  append_option(:cc65_inc_paths, more_paths)
end
cc65_initialize() click to toggle source

Setup cc65

# File lib/test65/enclosures/cc65.rb, line 5
def cc65_initialize
  @options[:cc65_target] = "sim65c02"
  @options[:cc65_inc_paths] = ["#{@options[:gem_root]}/include"]
end
change_type(file, new_ext) click to toggle source

Create a file name with a new extension.

# File lib/test65/enclosures/utils.rb, line 6
def change_type(file, new_ext)
  file.gsub(/\...?.?\z/, new_ext)
end
clean_up() click to toggle source

Cleanup after ourselves

# File lib/test65/perform_test.rb, line 28
def clean_up
  # Remove objects and executable unless told to keep them.
  unless @options[:keep]
    File.delete(@output) if File.exists?(@output)

    @options[:temps].each do |file|
      File.delete(file) if File.exists?(file)
    end

    @options[:objs].each do |file|
      File.delete(file) if File.exists?(file)
    end
  end

  # Remove listing files unless they were requested.
  unless @options[:list]
    @options[:objs].each do |file|
      file = change_type(file, ".lst")
      File.delete(file) if File.exists?(file)
    end
  end

  # Remove the map file if needed.
  File.delete(@map_file) if !@options[:map] && File.exists?(@map_file)
end
ld65(options="") click to toggle source
# File lib/test65/enclosures/ld65.rb, line 27
def ld65(options="")
  fail "Sequence error: ld65" unless [:create, :link].include?(@phase)
  @phase = :simulate

  @output   = change_type(@options[:objs][0], ".out")
  @map_file = change_type(@options[:objs][0], ".map")
  lib_paths = build_args("--lib-path", @options[:lib_paths])
  objs      = build_args(@options[:objs])
  libs      = build_args("--lib", @options[:libraries])
  map       = @options[:map] ? "-m #{@map_file}" : ""
  cfg       = "-C " + @options[:config] + " "

  # Build the command and run it.
  command = "ld65 #{lib_paths}#{libs}#{cfg}#{options} #{objs}#{map} -o #{@output} #{@quiet}\n"
  puts command if @options[:debug]
  system(command)
  fail "Error linking #{@output.localize_path}." unless $?.exitstatus == 0
end
ld65_initialize() click to toggle source

Setup ld65

# File lib/test65/enclosures/ld65.rb, line 6
def ld65_initialize
  @options[:lib_paths] = []
  @options[:libraries] = ["sim65c02.lib"]
  @options[:ld65_options] = []
  @options[:config] = "#{@options[:gem_root]}/cfg/test65.cfg"
end
ld65_lib_paths(*more_paths) click to toggle source

Add some library paths for the linker.

# File lib/test65/enclosures/ld65.rb, line 14
def ld65_lib_paths(*more_paths)
  fail "Sequence error: ld65_lib_paths" unless [:create, :link].include?(@phase)
  append_option(:lib_paths, more_paths)
  @phase = :link
end
ld65_libraries(*more_libs) click to toggle source

Add some library paths for the linker.

# File lib/test65/enclosures/ld65.rb, line 21
def ld65_libraries(*more_libs)
  fail "Sequence error: ld65_libraries" unless [:create, :link].include?(@phase)
  append_option(:libraries, more_libs)
  @phase = :link
end
sim65(options="") click to toggle source

Run the simulator to get the actual test results.

# File lib/test65/enclosures/sim65.rb, line 11
def sim65(options="")
  fail "Sequence error: sim65" unless @phase == :simulate
  @phase = :done

  # Build the command and run it.
  command = "sim65 #{options} #{@output} #{@quiet}\n"
  puts command if @options[:debug]
  system(command)
  status = $?.exitstatus
  fail "Test #{@output.localize_path} failed with error code: #{status}" unless status == 0
end
sim65_initialize() click to toggle source

Setup sim65

# File lib/test65/enclosures/sim65.rb, line 6
def sim65_initialize
  @options[:sim65_options] = []
end