Skip to content

Commit

Permalink
Improve bin/rcpu:
Browse files Browse the repository at this point in the history
* Can now run binaries
* Can now compile to binaries
  • Loading branch information
judofyr committed Apr 9, 2012
1 parent 47049f8 commit 0e841d1
Show file tree
Hide file tree
Showing 9 changed files with 849 additions and 96 deletions.
47 changes: 35 additions & 12 deletions bin/rcpu
Original file line number Diff line number Diff line change
@@ -1,23 +1,46 @@
#!/usr/bin/env ruby
$LOAD_PATH.unshift(File.expand_path("../../lib", __FILE__))

if ARGV.empty?
puts "usage: rcpu examples/from_spec.rpcu"
exit 1
require 'rcpu'
require 'rcpu/trollop'
T = RCPU::Trollop

p = T::Parser.new do
version "RCPU #{RCPU::VERSION}"
banner <<-EOS
DCPU-16 assembler, emulator, debugger
Usage:
bin/rcpu examples/hello.rcpu
bin/rcpu examples/hello.bin
bin/rcpu -f bin examples/hello
Available options:
EOS
opt :format, "File format (bin or rcpu). Guessed from filename if not present.",
:type => String
end

require 'rcpu'
formats = %w[bin rcpu]

begin
require 'pry'
rescue LoadError
opts = nil
T.with_standard_exception_handling(p) do
opts = p.parse(ARGV)
raise T::HelpNeeded unless opts[:filename] = ARGV.shift
opts[:format] ||= File.extname(opts[:filename]).sub('.','')
p.die :format, "can only be 'bin' or 'rcpu'" unless formats.include?(opts[:format])
end

linker = RCPU::Linker.new
lib = linker.find(ARGV[0], Dir.pwd)
linker.compile(lib)
emu = RCPU::Emulator.new(linker.finalize)
emu.memory.add_extensions(linker.extensions)

RCPU::Debugger.new(emu, linker).start
case opts[:format]
when 'rpcu'
lib = linker.find(opts[:filename], Dir.pwd)
linker.compile_library(lib)
when 'bin'
linker.extensions << [0x8000, RCPU::ScreenExtension, []]
linker.compile_binary(File.binread(opts[:filename]))
end

linker.debugger.start

55 changes: 0 additions & 55 deletions bin/rcpu-as

This file was deleted.

20 changes: 0 additions & 20 deletions bin/rcpu-bin

This file was deleted.

Binary file added examples/hello
Binary file not shown.
2 changes: 2 additions & 0 deletions lib/rcpu.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
module RCPU
VERSION = "0.1.0"

class AssemblerError < StandardError; end

class BasicInstruction < Struct.new(:name, :a, :b)
Expand Down
15 changes: 9 additions & 6 deletions lib/rcpu/assembler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,11 @@ def load_file(file)
@libraries[file] = l
end

def compile(library, name = :main)
def compile_binary(str)
@memory.concat(str.unpack('v*'))
end

def compile_library(library, name = :main)
gather(library)
block = @blocks[name] or raise AssemblerError, "no block: #{name}"
compile_block(name, block)
Expand Down Expand Up @@ -220,11 +224,10 @@ def finalize
end
end

def dump
finalize.each_slice(8).each_with_index do |r, i|
print "#{(i*8).to_s(16).rjust(4, '0')}: "
puts r.map { |x| x.to_s(16).rjust(4, '0') }.join(" ")
end
def debugger
emu = Emulator.new(finalize)
emu.memory.add_extensions(extensions)
Debugger.new(emu, self)
end
end
end
Expand Down
22 changes: 19 additions & 3 deletions lib/rcpu/debugger.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
begin
require 'pry'
rescue LoadError
end

module RCPU
class Debugger
def initialize(emulator, linker = Linker.new)
Expand All @@ -14,9 +19,10 @@ def pry?
def help
puts "(^C) stop execution"
puts "(b) add breakpoint"
puts "(d) dump state"
puts "(c) compile to binary"
puts "(d) dump memory and registrers"
puts "(e) evaluate ruby"
puts "(h) help"
puts "(h) help (this message)"
puts "(p) ruby shell" if pry?
puts "(r) run"
puts "(s) step"
Expand All @@ -35,8 +41,11 @@ def start
@running = false
end

puts "Welcome to RCPU:"
puts "Welcome to RCPU #{VERSION}:"
help
puts
puts "You probably want to type 'r' for run or 'c' for compile"
puts

while true
begin
Expand All @@ -55,6 +64,13 @@ def start
bp = @linker.symbols[input] || Integer(input)
@breakpoints << bp
puts "Added breakpoint #{@breakpoints.size} at 0x#{bp.to_s(16)}"
when "c"
print "Enter filename: "
filename = gets.strip
File.open(filename, 'w') do |f|
f << @emulator.memory.to_s
end
puts ">> Saved as #{filename}"
when "d"
@emulator.dump
when "e"
Expand Down
2 changes: 2 additions & 0 deletions lib/rcpu/emulator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ def initialize(source)
@extensions = []
end

def to_s; @array.pack('v*') end

def add_extensions(list)
list.each do |(location, klass, args, blk)|
ext = klass.new(@array, location, *args, &blk)
Expand Down
Loading

2 comments on commit 0e841d1

@rlane
Copy link
Collaborator

@rlane rlane commented on 0e841d1 Apr 10, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't remove the standalone assembler. It's very useful for automation, such as in a Makefile.

@judofyr
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revived in 60e375e.

Please sign in to comment.