diff options
Diffstat (limited to '')
| -rwxr-xr-x | asm.rb | 70 |
1 files changed, 0 insertions, 70 deletions
| @@ -1,70 +0,0 @@ | |||
| 1 | #!/usr/bin/ruby -w | ||
| 2 | |||
| 3 | OPCODES = { | ||
| 4 | "i" => 0x080, | ||
| 5 | "acc=" => 0x100, | ||
| 6 | "ladd" => 0x200, | ||
| 7 | "store" => 0x300, | ||
| 8 | "ifeq" => 0x400, | ||
| 9 | "jmp" => 0x500, | ||
| 10 | "ascii" => 0x600, | ||
| 11 | "cla" => 0x001, | ||
| 12 | "++acc" => 0x002, | ||
| 13 | "--acc" => 0x004, | ||
| 14 | "tx" => 0x040, | ||
| 15 | "rx" => 0x080, | ||
| 16 | "halt" => 0x000, | ||
| 17 | } | ||
| 18 | |||
| 19 | Line = Struct.new(:opcode, :refs, :code) | ||
| 20 | |||
| 21 | $labels = {} | ||
| 22 | $code = [] | ||
| 23 | ARGF.each_line() do | line | | ||
| 24 | line.chomp!() | ||
| 25 | line.sub!(/^.*\/\/\s*/, "") | ||
| 26 | next unless line =~ /\S/ | ||
| 27 | op = 0x000 | ||
| 28 | refs = [] | ||
| 29 | line.scan(/\S+/).each() do | word | | ||
| 30 | break if word =~ /^#/ | ||
| 31 | if word =~ /^0(\d+)$/ | ||
| 32 | op |= $1.to_i(8) | ||
| 33 | elsif word =~ /^-0(\d+)$/ | ||
| 34 | op |= 0x100 - $1.to_i(8) | ||
| 35 | elsif word =~ /^(\d+)$/ | ||
| 36 | op |= $1.to_i(10) | ||
| 37 | elsif word =~ /^-(\d+)$/ | ||
| 38 | op |= 0x100 - $1.to_i(10) | ||
| 39 | elsif word =~ /^0x([0-9a-f]+)$/i | ||
| 40 | op |= $1.to_i(16) | ||
| 41 | elsif word =~ /^-0x([0-9a-f]+)$/i | ||
| 42 | op |= 0x100 - $1.to_i(16) | ||
| 43 | elsif OPCODES.key?(word) | ||
| 44 | op |= OPCODES[word] | ||
| 45 | elsif word =~ /^(.+):$/ | ||
| 46 | $labels[$1] = $code.size() | ||
| 47 | else | ||
| 48 | refs << word | ||
| 49 | end | ||
| 50 | end | ||
| 51 | $code << Line.new(op, refs, line) | ||
| 52 | end | ||
| 53 | |||
| 54 | $code.each_with_index() do | line, i | | ||
| 55 | op = line.opcode | ||
| 56 | line.refs.each() do | ref | | ||
| 57 | if ref =~ /^@(.+)$/ and $labels.key?($1) | ||
| 58 | op |= $labels[$1] | ||
| 59 | elsif $labels.key?(ref) | ||
| 60 | target = $labels[ref] - (i + 1) | ||
| 61 | throw "Jump too far forward" if target > 0x7f | ||
| 62 | target += 0x80 if target < 0 | ||
| 63 | throw "Jump too far backward" if target < 0 | ||
| 64 | op |= target | ||
| 65 | else | ||
| 66 | throw "I don't understand #{ref.inspect()}" | ||
| 67 | end | ||
| 68 | end | ||
| 69 | $stdout.write("#{op.to_s(16).rjust(3, "0")} // #{line.code}\n") | ||
| 70 | end | ||
