-
Notifications
You must be signed in to change notification settings - Fork 4
/
norcpu.rb
executable file
·77 lines (58 loc) · 1.39 KB
/
norcpu.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#!/usr/bin/ruby
class NorCpu
@@REGS = [:ip, :shift_reg, :sp, :reg0, :reg1, :reg2, :reg3]
@mem = []
attr_reader :mem
def self.nor(a, b)
~(a | b) & 0xFFFF
end
def self.reg_index(name)
@@REGS.index(name)
end
def reg(name)
@mem[NorCpu.reg_index(name)]
end
def reg_set(name,value)
@mem[NorCpu.reg_index(name)] = value
end
def load(obj_file)
File.open(obj_file) do |f|
@mem = f.read.unpack("S*")
end
puts "program @mem size: %d" % @mem.size
1000.times {|x| @mem << 0} #stack area
end
def run
ip = NorCpu.reg_index(:ip)
shift_reg = NorCpu.reg_index(:shift_reg)
sp = NorCpu.reg_index(:sp)
reg0 = NorCpu.reg_index(:reg0)
@mem[ip] = @@REGS.size
sp_low = @mem[sp]
while true do
i = @mem[ip]
#raise "not code area!" if i>=sp_low || i<@@REGS.size
raise "stack overflow!" if @mem[sp]<sp_low || @mem[sp]>[email protected]
a = @mem[i + 0]
b = @mem[i + 1]
r = @mem[i + 2]
@mem[ip] = i + 3
f = NorCpu.nor(@mem[a], @mem[b])
@mem[r] = f
@mem[shift_reg] = ((f >> 15) & 1) | ((f & 0x7FFF) << 1)
break if @mem[ip] == 0xFFFF
end
puts "return value: #{@mem[reg0]}"
end
def load_run(obj_file="a.out")
load(obj_file)
run
end
end
unless $embedded
if ARGV.size==0
NorCpu.new.load_run
else
NorCpu.new.load_run(ARGV[0])
end
end