rasl 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.travis.yml +4 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +22 -0
- data/README.org +221 -0
- data/Rakefile +6 -0
- data/bin/rasl +3 -0
- data/examples/fnumb.casl +22 -0
- data/examples/fnumb.map +20 -0
- data/examples/hanoi.casl +48 -0
- data/examples/hanoi.map +61 -0
- data/examples/hanoi.rb +124 -0
- data/examples/hello.casl +6 -0
- data/examples/hello.map +14 -0
- data/examples/hello.rb +41 -0
- data/examples/in_out.casl +17 -0
- data/examples/in_out.map +62 -0
- data/examples/run_all.sh +2 -0
- data/examples/sum.casl +7 -0
- data/examples/sum.map +7 -0
- data/examples/sum.rb +27 -0
- data/examples/swap.casl +8 -0
- data/examples/swap.map +6 -0
- data/examples/utf8.casl +2 -0
- data/examples/utf8.map +4 -0
- data/lib/rasl.rb +1657 -0
- data/lib/rasl/version.rb +3 -0
- data/rasl.gemspec +29 -0
- data/spec/rasl_spec.rb +700 -0
- data/spec/spec_helper.rb +11 -0
- metadata +163 -0
data/lib/rasl/version.rb
ADDED
data/rasl.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rasl/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'rasl'
|
8
|
+
spec.version = Rasl::VERSION
|
9
|
+
spec.author = 'akicho8'
|
10
|
+
spec.email = 'akicho8@gmail.com'
|
11
|
+
spec.homepage = 'https://github.com/akicho8/rasl'
|
12
|
+
spec.summary = 'CASL Assembler / Simulator'
|
13
|
+
spec.description = 'CASL Assembler / Simulator'
|
14
|
+
spec.platform = Gem::Platform::RUBY
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
spec.rdoc_options = ['--line-numbers', '--inline-source', '--charset=UTF-8', '--diagram', '--image-format=jpg']
|
21
|
+
|
22
|
+
spec.add_dependency 'activesupport'
|
23
|
+
spec.add_dependency 'activemodel'
|
24
|
+
|
25
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
26
|
+
spec.add_development_dependency 'rake'
|
27
|
+
spec.add_development_dependency 'rspec'
|
28
|
+
spec.add_development_dependency 'byebug'
|
29
|
+
end
|
data/spec/rasl_spec.rb
ADDED
@@ -0,0 +1,700 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Rasl do
|
6
|
+
before do
|
7
|
+
Rasl.configure do |config|
|
8
|
+
config.memory_size = 65536
|
9
|
+
config.bol_order = true
|
10
|
+
config.ds_init_value = -1
|
11
|
+
end
|
12
|
+
|
13
|
+
@p = Processor.new
|
14
|
+
end
|
15
|
+
|
16
|
+
it "regs_info" do
|
17
|
+
@p.regs_info.should == "GR0=0000 GR1=0000 GR2=0000 GR3=0000 GR4=0000 GR5=0000 GR6=0000 GR7=0000 PC=0000 SP=0000 FR=___(+)"
|
18
|
+
end
|
19
|
+
|
20
|
+
describe Value do
|
21
|
+
it "符号の有無はアクセサによって決まる" do
|
22
|
+
r = Value.new(-1)
|
23
|
+
[r.value, r.s_value, r.u_value].should == [65535, -1, 65535]
|
24
|
+
r = Value.new(65535)
|
25
|
+
[r.value, r.s_value, r.u_value].should == [65535, -1, 65535]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe Register do
|
30
|
+
it do
|
31
|
+
r = Register.new(:ax, :pos => 0)
|
32
|
+
r.key.should == :ax
|
33
|
+
r.name.should == "AX"
|
34
|
+
r.pos.should == 0
|
35
|
+
r.to_s.should == "AX=0000"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe Environment do
|
40
|
+
it "new" do
|
41
|
+
@p.code_size.should == 0
|
42
|
+
@p.boot_pc.should == 0
|
43
|
+
@p.gr[:sp].value == @p.memory.size
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe OperandPresets1 do
|
48
|
+
describe "基本命令" do
|
49
|
+
it "nop" do
|
50
|
+
asm " nop"
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "ld" do
|
54
|
+
it "r_imm" do
|
55
|
+
asm "ld gr0, a", :dc => {:a => -77}
|
56
|
+
reg_is :gr0, -77
|
57
|
+
fire :sf
|
58
|
+
end
|
59
|
+
it "rix" do
|
60
|
+
asm "ld gr0, a, gr1", :dc => {:a => [-444, -77]}, :regs => {:gr1 => 1}
|
61
|
+
reg_is :gr0, -77
|
62
|
+
fire :sf
|
63
|
+
end
|
64
|
+
it "r1_r2" do
|
65
|
+
asm "ld gr1, gr0", :regs => {:gr0 => -77}
|
66
|
+
reg_is :gr1, -77
|
67
|
+
fire :sf
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "st" do
|
72
|
+
it "r_imm" do
|
73
|
+
asm "st gr0, a", :dc => {:a => 0}, :regs => {:gr0 => -77}
|
74
|
+
var_check :a, -77
|
75
|
+
fr_blank
|
76
|
+
end
|
77
|
+
it "rix" do
|
78
|
+
asm "st gr0, a, gr1", :dc => {:a => 0, :b => 0}, :regs => {:gr0 => -77, :gr1 => 1}
|
79
|
+
var_check :b, -77
|
80
|
+
fr_blank
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "lea" do
|
85
|
+
it "r_imm" do
|
86
|
+
asm "lea gr0, -77"
|
87
|
+
reg_is :gr0, -77
|
88
|
+
fire :sf
|
89
|
+
end
|
90
|
+
it "rix" do
|
91
|
+
asm "lea gr0, 1, gr1", :regs => {:gr1 => -77 - 1}
|
92
|
+
reg_is :gr0, -77
|
93
|
+
fire :sf
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "adda" do
|
98
|
+
describe "r1_r2" do
|
99
|
+
describe "上限" do
|
100
|
+
it "of_true" do
|
101
|
+
asm "adda gr0, gr1", :regs => {:gr0 => 1, :gr1 => 32767}
|
102
|
+
reg_is :gr0, -32768
|
103
|
+
fire :of, :sf
|
104
|
+
end
|
105
|
+
it "of_false" do
|
106
|
+
asm "adda gr0, gr1", :regs => {:gr0 => 0, :gr1 => 32767}
|
107
|
+
reg_is :gr0, 32767
|
108
|
+
fire
|
109
|
+
end
|
110
|
+
end
|
111
|
+
describe "下限" do
|
112
|
+
it "of_true" do
|
113
|
+
asm "adda gr0, gr1", :regs => {:gr0 => -1, :gr1 => -32768}
|
114
|
+
reg_is :gr0, 32767
|
115
|
+
fire :of
|
116
|
+
end
|
117
|
+
it "of_false" do
|
118
|
+
asm "adda gr0, gr1", :regs => {:gr0 => 0, :gr1 => -32768}
|
119
|
+
reg_is :gr0, -32768
|
120
|
+
fire :sf
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
it "rix" do
|
125
|
+
asm "adda gr0, a, gr1", :dc => {:a => 0, :b => -66}, :regs => {:gr0 => -11, :gr1 => 1}
|
126
|
+
reg_is :gr0, -77
|
127
|
+
fire :sf
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "addl" do
|
132
|
+
describe "r1_r2" do
|
133
|
+
describe "上限" do
|
134
|
+
it "of_true" do
|
135
|
+
asm "addl gr0, gr1", :regs => {:gr0 => 1, :gr1 => 65535}
|
136
|
+
reg_is :gr0, 0
|
137
|
+
fire :of, :zf
|
138
|
+
end
|
139
|
+
it "of_false" do
|
140
|
+
asm "addl gr0, gr1", :regs => {:gr0 => 0, :gr1 => 65535}
|
141
|
+
reg_is :gr0, -1
|
142
|
+
fire :sf
|
143
|
+
end
|
144
|
+
end
|
145
|
+
describe "下限" do
|
146
|
+
it "of_false" do
|
147
|
+
asm "addl gr0, gr1", :regs => {:gr0 => -1, :gr1 => 0}
|
148
|
+
reg_is :gr0, -1
|
149
|
+
fire :sf
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe "alias" do
|
156
|
+
it "add" do
|
157
|
+
asm "add gr0, a, gr1", :dc => {:a => 0, :b => -66}, :regs => {:gr0 => -11, :gr1 => 1}
|
158
|
+
reg_is :gr0, -77
|
159
|
+
fire :sf
|
160
|
+
end
|
161
|
+
it "sub" do
|
162
|
+
asm "sub gr0, a, gr1", :dc => {:a => 0, :b => 88}, :regs => {:gr0 => 11, :gr1 => 1}
|
163
|
+
reg_is :gr0, -77
|
164
|
+
fire :sf
|
165
|
+
end
|
166
|
+
it "eor" do
|
167
|
+
asm "eor gr0, a, gr1", :dc => {:a => 0, :b => 0x5500}, :regs => {:gr0 => 0xf0f0, :gr1 => 1}
|
168
|
+
@p.gr[:gr0].value.should == 0xa5f0
|
169
|
+
fire :sf
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe "論理演算" do
|
174
|
+
describe "r1_r2" do
|
175
|
+
it do
|
176
|
+
logic_check(:and, 0x5000)
|
177
|
+
logic_check(:or, 0xf5f0)
|
178
|
+
logic_check(:xor, 0xa5f0)
|
179
|
+
end
|
180
|
+
|
181
|
+
def logic_check(order, result)
|
182
|
+
asm "#{order} gr0, gr1", :regs => {:gr0 => 0xf0f0, :gr1 => 0x5500}
|
183
|
+
@p.gr[:gr0].value.should == result
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
describe "rix" do
|
188
|
+
it "xor" do
|
189
|
+
asm "xor gr0, a, gr1", :dc => {:a => 0, :b => 0x5500}, :regs => {:gr0 => 0xf0f0, :gr1 => 1}
|
190
|
+
@p.gr[:gr0].value.should == 0xa5f0
|
191
|
+
fire :sf
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
it "比較" do
|
197
|
+
compare_check(:cpa, 1, -1, [])
|
198
|
+
compare_check(:cpl, 1, -1, [:sf])
|
199
|
+
compare_check(:cpa, -1, 1, [:sf])
|
200
|
+
compare_check(:cpl, -1, 1, [])
|
201
|
+
end
|
202
|
+
|
203
|
+
def compare_check(order, a, b, flags)
|
204
|
+
@p.init_env
|
205
|
+
asm ["lea gr0, #{a}", "#{order} gr0, a"], :dc => {:a => b}
|
206
|
+
fire *flags
|
207
|
+
end
|
208
|
+
|
209
|
+
describe "シフト" do
|
210
|
+
it do
|
211
|
+
shift_check :sla, -1, 0b1000000000000000, [:of, :sf]
|
212
|
+
shift_check :sla, 0, 0b1010000000000001, [:sf]
|
213
|
+
shift_check :sla, 1, 0b1100000000000010, [:of, :sf]
|
214
|
+
shift_check :sla, 2, 0b1000000000000100, [:of, :sf]
|
215
|
+
shift_check :sla, 15, 0b1000000000000000, [:of, :sf]
|
216
|
+
shift_check :sla, 16, 0b1000000000000000, [:of, :sf]
|
217
|
+
shift_check :sla, 17, 0b1000000000000000, [:of, :sf]
|
218
|
+
shift_check :sla, 64, 0b1000000000000000, [:of, :sf]
|
219
|
+
shift_check :sra, -1, 0b1111111111111111, [:of, :sf]
|
220
|
+
shift_check :sra, 0, 0b1010000000000001, [:sf]
|
221
|
+
shift_check :sra, 1, 0b1101000000000000, [:of, :sf]
|
222
|
+
shift_check :sra, 2, 0b1110100000000000, [:sf]
|
223
|
+
shift_check :sra, 15, 0b1111111111111111, [:sf]
|
224
|
+
shift_check :sra, 16, 0b1111111111111111, [:of, :sf]
|
225
|
+
shift_check :sra, 17, 0b1111111111111111, [:of, :sf]
|
226
|
+
shift_check :sra, 64, 0b1111111111111111, [:of, :sf]
|
227
|
+
shift_check :sll, -1, 0b0000000000000000, [:of, :zf]
|
228
|
+
shift_check :sll, 0, 0b1010000000000001, [:sf]
|
229
|
+
shift_check :sll, 1, 0b0100000000000010, [:of]
|
230
|
+
shift_check :sll, 2, 0b1000000000000100, [:sf]
|
231
|
+
shift_check :sll, 15, 0b1000000000000000, [:sf]
|
232
|
+
shift_check :sll, 16, 0b0000000000000000, [:of, :zf]
|
233
|
+
shift_check :sll, 17, 0b0000000000000000, [:of, :zf]
|
234
|
+
shift_check :sll, 64, 0b0000000000000000, [:of, :zf]
|
235
|
+
shift_check :srl, -1, 0b0000000000000000, [:of, :zf]
|
236
|
+
shift_check :srl, 0, 0b1010000000000001, [:sf]
|
237
|
+
shift_check :srl, 1, 0b0101000000000000, [:of]
|
238
|
+
shift_check :srl, 2, 0b0010100000000000, []
|
239
|
+
shift_check :srl, 15, 0b0000000000000001, []
|
240
|
+
shift_check :srl, 16, 0b0000000000000000, [:of, :zf]
|
241
|
+
shift_check :srl, 17, 0b0000000000000000, [:of, :zf]
|
242
|
+
shift_check :srl, 64, 0b0000000000000000, [:of, :zf]
|
243
|
+
end
|
244
|
+
|
245
|
+
def shift_check(order, count, result_value, result_flgs)
|
246
|
+
@p.init_env
|
247
|
+
asm "#{order} gr0, count", :dc => {:count => count}, :regs => {:gr0 => 0b1010000000000001}
|
248
|
+
# p(["%016b" % @p.gr[:gr0].value, @p.gr[:fr].available_flags])
|
249
|
+
# [@p.gr[:gr0].value, @p.gr[:fr].available_flags]
|
250
|
+
@p.gr[:gr0].value.should == result_value
|
251
|
+
fire *result_flgs
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
describe "jmp" do
|
256
|
+
it do
|
257
|
+
jmp_check :jmp, [1, 1, 1]
|
258
|
+
jmp_check :jump, [1, 1, 1]
|
259
|
+
jmp_check :jpl, [0, 0, 1]
|
260
|
+
jmp_check :jpz, [0, 1, 1]
|
261
|
+
jmp_check :jmi, [1, 0, 0]
|
262
|
+
jmp_check :jnz, [1, 0, 1]
|
263
|
+
jmp_check :jze, [0, 1, 0]
|
264
|
+
end
|
265
|
+
|
266
|
+
def jmp_check(order, result)
|
267
|
+
[].tap do |gr0|
|
268
|
+
@p.init_env; asm ["lea gr0, -1", "#{order} a", "lea gr0, 0", "jmp b", "a lea gr0, 1", "b nop"]; gr0 << @p.gr[:gr0].s_value
|
269
|
+
@p.init_env; asm ["lea gr0, 0", "#{order} a", "lea gr0, 0", "jmp b", "a lea gr0, 1", "b nop"]; gr0 << @p.gr[:gr0].s_value
|
270
|
+
@p.init_env; asm ["lea gr0, 1", "#{order} a", "lea gr0, 0", "jmp b", "a lea gr0, 1", "b nop"]; gr0 << @p.gr[:gr0].s_value
|
271
|
+
end.should == result
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
describe "jov" do
|
276
|
+
it "of_true" do
|
277
|
+
asm ["jov a", "jmp e", "a lea gr0, 77", "e nop"], :flags => {:of => true}
|
278
|
+
reg_is :gr0, 77
|
279
|
+
end
|
280
|
+
it "of_false" do
|
281
|
+
asm ["jov a", "jmp e", "a lea gr0, 77", "e nop"], :flags => {:of => false}
|
282
|
+
reg_is :gr0, 0
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
it "push_pop" do
|
287
|
+
asm ["push 77", "pop gr0"]
|
288
|
+
reg_is :gr0, 77
|
289
|
+
end
|
290
|
+
|
291
|
+
it "call" do
|
292
|
+
asm ["call a", "a nop"]
|
293
|
+
@p.memory[@p.gr[:sp].value].should == 2
|
294
|
+
end
|
295
|
+
|
296
|
+
describe "ret" do
|
297
|
+
it do
|
298
|
+
asm ["call a", "lea gr1,77", "jmp e", "a lea gr0,77", "ret", "e nop"]
|
299
|
+
reg_is :gr0, 77
|
300
|
+
reg_is :gr1, 77
|
301
|
+
end
|
302
|
+
|
303
|
+
it "ret で正常に戻ったかどうかは exit_key でわかる" do
|
304
|
+
asm "RET"
|
305
|
+
@p.exit_key.should == :ret
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
describe "擬似命令" do
|
311
|
+
it "start" do
|
312
|
+
asm [" start a", " lea gr0, 444", " jmp e", "a lea gr0, 77", "e nop"]
|
313
|
+
reg_is :gr0, 77
|
314
|
+
end
|
315
|
+
|
316
|
+
# it "end" do
|
317
|
+
# @p.assemble(["start", "ld gr0,=77", " dc 0", "end"].join("\n"))
|
318
|
+
# @p.memory[@p.code_size - 1].should == 77
|
319
|
+
# end
|
320
|
+
#
|
321
|
+
# it "ds" do
|
322
|
+
# @p.assemble [" nop", "a ds a"].join("\n") # 個数がラベル
|
323
|
+
# @p.code_size.should == 2
|
324
|
+
#
|
325
|
+
# @p.assemble " ds 7"
|
326
|
+
# @p.code_size.should == 7
|
327
|
+
#
|
328
|
+
# @p.assemble " ds 0"
|
329
|
+
# @p.code_size.should == 0
|
330
|
+
# end
|
331
|
+
#
|
332
|
+
# describe "dc" do
|
333
|
+
# it do
|
334
|
+
# dc_check %{''}, ""
|
335
|
+
# dc_check %{'\;'}, ";"
|
336
|
+
# dc_check %{'a'}, "a"
|
337
|
+
# dc_check %{"a"}, "a"
|
338
|
+
# dc_check %{10}, "\x0a"
|
339
|
+
# dc_check %{'a', 'b', 0, 'c', 'd'}, "ab\x00cd"
|
340
|
+
# dc_check %{'a''b''c',0,'d''e''f'}, "a'b'c\x00d'e'f"
|
341
|
+
# dc_check %{"a""b""c",0,'d''e''f'}, %{a"b"c\x00d'e'f}
|
342
|
+
# end
|
343
|
+
#
|
344
|
+
# it "ラベルはアドレスに展開" do
|
345
|
+
# asm ["nop", "a nop"], :dc => {:b => :a}
|
346
|
+
# var_check :b, @p.labels[:a]
|
347
|
+
# end
|
348
|
+
#
|
349
|
+
# def dc_check(code, result)
|
350
|
+
# @p.assemble " dc #{code}"
|
351
|
+
# @p.memory[0...@p.code_size].pack("C*").should == result
|
352
|
+
# end
|
353
|
+
# end
|
354
|
+
end
|
355
|
+
|
356
|
+
describe "マクロ" do
|
357
|
+
describe "in" do
|
358
|
+
shared_examples_for "test" do
|
359
|
+
it do
|
360
|
+
asm "in buf,len", :ds => {:buf => 4}, :dc => {:len => 0}
|
361
|
+
@p.memory[@p.labels[:__global__]["buf"] + 0].should == "a".ord
|
362
|
+
@p.memory[@p.labels[:__global__]["buf"] + 1].should == "b".ord
|
363
|
+
var_check :len, 2
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
describe "@dataから" do
|
368
|
+
before { @p.data = ["ab"] }
|
369
|
+
it_behaves_like "test"
|
370
|
+
end
|
371
|
+
|
372
|
+
describe "標準入力" do
|
373
|
+
before do
|
374
|
+
@save_stdin = $stdin
|
375
|
+
$stdin = double("stdin", :gets => "ab")
|
376
|
+
end
|
377
|
+
after do
|
378
|
+
$stdin = @save_stdin
|
379
|
+
end
|
380
|
+
it_behaves_like "test"
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
it "out" do
|
385
|
+
# capture(:stdout) {
|
386
|
+
# asm ["out str,len", "out str,len"], :dc => {:str => "'abcd'", :len => 2}
|
387
|
+
# }.should == "ab\nab\n"
|
388
|
+
expect {
|
389
|
+
asm ["out str,len", "out str,len"], :dc => {:str => "'abcd'", :len => 2}
|
390
|
+
}.to output("ab\nab\n").to_stdout
|
391
|
+
end
|
392
|
+
|
393
|
+
it "exit" do
|
394
|
+
asm
|
395
|
+
end
|
396
|
+
|
397
|
+
it "rpush rpop" do
|
398
|
+
asm ["lea gr1, 77", "rpush", "lea gr1, 444", "rpop"]
|
399
|
+
reg_is :gr1, 77
|
400
|
+
end
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
describe Parser do
|
405
|
+
it "ラベル表記" do
|
406
|
+
@p.assemble("foo").labels.should == {:__global__ => {"foo" => 0}}
|
407
|
+
@p.assemble("foo:").labels.should == {:__global__ => {"foo" => 0}}
|
408
|
+
@p.assemble("Foo:").labels.should == {:__global__ => {"Foo" => 0}}
|
409
|
+
@p.assemble("lad:").labels.should == {:__global__ => {"lad" => 0}}
|
410
|
+
@p.assemble("@xx").labels.should == {:__global__ => {"@xx" => 0}}
|
411
|
+
@p.assemble("$xx").labels.should == {:__global__ => {"$xx" => 0}}
|
412
|
+
end
|
413
|
+
|
414
|
+
it "ローカルラベルとグローバルラベル" do
|
415
|
+
asm [
|
416
|
+
"a START", # global
|
417
|
+
"a NOP", # local
|
418
|
+
" RET",
|
419
|
+
" END",
|
420
|
+
"",
|
421
|
+
"b START", # global
|
422
|
+
"a NOP", # local
|
423
|
+
"$x NOP", # global
|
424
|
+
" RET",
|
425
|
+
" END",
|
426
|
+
]
|
427
|
+
@p.labels.should == {
|
428
|
+
:__global__ => {"a" => 0, "b" => 2, "$x" => 3},
|
429
|
+
"a" => {"a" => 0},
|
430
|
+
"b" => {"a" => 2},
|
431
|
+
}
|
432
|
+
end
|
433
|
+
|
434
|
+
it "コメント" do
|
435
|
+
@p.assemble(" DC #77 ; comment").disassemble.should match "77"
|
436
|
+
@p.assemble("#DC #77").code_size.should == 0
|
437
|
+
@p.assemble(";DC #77").code_size.should == 0
|
438
|
+
end
|
439
|
+
|
440
|
+
it "インラインデータ" do
|
441
|
+
@p.assemble([" ld gr1, =1", " nop"].join("\n"))
|
442
|
+
@p.disassemble.should == <<-EOT
|
443
|
+
0000 1010 0003 LD GR1, #0003
|
444
|
+
0002 0900 NOP
|
445
|
+
0003 0001 DC 1
|
446
|
+
EOT
|
447
|
+
@p.assemble([" dc ='abcd'", " nop"].join("\n"))
|
448
|
+
@p.disassemble.should == <<-EOT
|
449
|
+
0000 0002 DC 2
|
450
|
+
0001 0900 NOP
|
451
|
+
0002 0061 DC 97 ; 'a'
|
452
|
+
0003 0062 DC 98 ; 'b'
|
453
|
+
0004 0063 DC 99 ; 'c'
|
454
|
+
0005 0064 DC 100 ; 'd'
|
455
|
+
EOT
|
456
|
+
end
|
457
|
+
|
458
|
+
it "即値" do
|
459
|
+
value_format_check "010", 8
|
460
|
+
value_format_check "10", 10
|
461
|
+
value_format_check "#10", 0x10
|
462
|
+
value_format_check "0x10", 0x10
|
463
|
+
value_format_check "0b10", 2
|
464
|
+
end
|
465
|
+
|
466
|
+
def value_format_check(str, result)
|
467
|
+
@p.assemble(" DC #{str}")
|
468
|
+
@p.memory.first.should == result
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
describe RaslError do
|
473
|
+
before do
|
474
|
+
@bol_order = Rasl.config.bol_order
|
475
|
+
end
|
476
|
+
after do
|
477
|
+
Rasl.config.bol_order = @bol_order
|
478
|
+
end
|
479
|
+
|
480
|
+
it do
|
481
|
+
Rasl.config.bol_order = false; expect { @p.assemble "JPZ GR1, 1, GR2" }.to raise_error(InvalidOrder)
|
482
|
+
Rasl.config.bol_order = true; expect { @p.assemble "JPZ GR1, 1, GR2" }.to raise_error(LabelNotFound)
|
483
|
+
end
|
484
|
+
|
485
|
+
it do
|
486
|
+
expect { asm "JPZ GR1, 1, GR2" }.to raise_error(LabelNotFound)
|
487
|
+
end
|
488
|
+
end
|
489
|
+
|
490
|
+
describe Simulator do
|
491
|
+
describe "r" do
|
492
|
+
it "r" do
|
493
|
+
@p.command_init
|
494
|
+
expect { @p.post_command("r") }.to output(<<-EOT).to_stdout
|
495
|
+
GR0=0000 GR1=0000 GR2=0000 GR3=0000 GR4=0000 GR5=0000 GR6=0000 GR7=0000 PC=0000 SP=FFFF FR=___(+)
|
496
|
+
0000 0000 DC 0
|
497
|
+
EOT
|
498
|
+
end
|
499
|
+
|
500
|
+
it "rGR=77" do
|
501
|
+
@p.command_init
|
502
|
+
@p.post_command("rGR0=77")
|
503
|
+
@p.gr[:gr0].value.should == 77
|
504
|
+
end
|
505
|
+
|
506
|
+
it "asm => r" do
|
507
|
+
asm "lea GR0,1"
|
508
|
+
expect { @p.post_command("r") }.to output(<<-EOT).to_stdout
|
509
|
+
GR0=0001 GR1=0000 GR2=0000 GR3=0000 GR4=0000 GR5=0000 GR6=0000 GR7=0000 PC=0004 SP=FFFF FR=___(+) [exit]
|
510
|
+
0004 0000 DC 0
|
511
|
+
EOT
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
515
|
+
it "#disassemble" do
|
516
|
+
@p.assemble("ld gr0, 1").disassemble.should == "0000 1000 0001 LD GR0, #0001\n"
|
517
|
+
end
|
518
|
+
end
|
519
|
+
|
520
|
+
it "disassemble" do
|
521
|
+
@p.assemble <<-SOURCE
|
522
|
+
NOP
|
523
|
+
LD GR1, 1, GR2
|
524
|
+
ST GR1, 1, GR2
|
525
|
+
LAD GR1, 1, GR2
|
526
|
+
LD GR1, GR2
|
527
|
+
ADDA GR1, 1, GR2
|
528
|
+
SUBA GR1, 1, GR2
|
529
|
+
ADDA GR3, GR4
|
530
|
+
SUBA GR3, GR4
|
531
|
+
AND GR1, 1, GR2
|
532
|
+
OR GR1, 1, GR2
|
533
|
+
XOR GR1, 1, GR2
|
534
|
+
AND GR1, GR2
|
535
|
+
OR GR1, GR2
|
536
|
+
XOR GR1, GR2
|
537
|
+
|
538
|
+
CPA GR1, 1, GR2
|
539
|
+
CPL GR1, 1, GR2
|
540
|
+
CPA GR1, GR2
|
541
|
+
CPL GR1, GR2
|
542
|
+
|
543
|
+
SLA GR1, 1, GR2
|
544
|
+
SRA GR1, 1, GR2
|
545
|
+
SLL GR1, 1, GR2
|
546
|
+
SRL GR1, 1, GR2
|
547
|
+
|
548
|
+
JPZ 1, GR2
|
549
|
+
JMI 1, GR2
|
550
|
+
JNZ 1, GR2
|
551
|
+
JZE 1, GR2
|
552
|
+
JUMP 1, GR2
|
553
|
+
JPL 1, GR2
|
554
|
+
JOV 1, GR2
|
555
|
+
|
556
|
+
PUSH #0077, GR2
|
557
|
+
POP GR0
|
558
|
+
CALL #0077, GR2
|
559
|
+
RET
|
560
|
+
|
561
|
+
RPUSH
|
562
|
+
RPOP
|
563
|
+
|
564
|
+
IN 1, 2
|
565
|
+
OUT 3, 4
|
566
|
+
SVC 0, GR2
|
567
|
+
EXIT
|
568
|
+
|
569
|
+
JMP A
|
570
|
+
EOR GR0, A
|
571
|
+
ADD GR1, 1, GR2
|
572
|
+
SUB GR1, 1, GR2
|
573
|
+
|
574
|
+
A DC 'a''b','c'
|
575
|
+
B DS 0
|
576
|
+
C DS 3
|
577
|
+
SOURCE
|
578
|
+
@p.disassemble.should == <<-MAP
|
579
|
+
0000 0900 NOP
|
580
|
+
0001 1012 0001 LD GR1, #0001, GR2
|
581
|
+
0003 1112 0001 ST GR1, #0001, GR2
|
582
|
+
0005 1212 0001 LAD GR1, #0001, GR2
|
583
|
+
0007 1412 LD GR1, GR2
|
584
|
+
0008 2012 0001 ADDA GR1, #0001, GR2
|
585
|
+
000A 2112 0001 SUBA GR1, #0001, GR2
|
586
|
+
000C 2434 ADDA GR3, GR4
|
587
|
+
000D 2534 SUBA GR3, GR4
|
588
|
+
000E 3012 0001 AND GR1, #0001, GR2
|
589
|
+
0010 3112 0001 OR GR1, #0001, GR2
|
590
|
+
0012 3212 0001 XOR GR1, #0001, GR2
|
591
|
+
0014 3412 AND GR1, GR2
|
592
|
+
0015 3512 OR GR1, GR2
|
593
|
+
0016 3612 XOR GR1, GR2
|
594
|
+
0017 4012 0001 CPA GR1, #0001, GR2
|
595
|
+
0019 4112 0001 CPL GR1, #0001, GR2
|
596
|
+
001B 4412 CPA GR1, GR2
|
597
|
+
001C 4512 CPL GR1, GR2
|
598
|
+
001D 5012 0001 SLA GR1, #0001, GR2
|
599
|
+
001F 5112 0001 SRA GR1, #0001, GR2
|
600
|
+
0021 5212 0001 SLL GR1, #0001, GR2
|
601
|
+
0023 5312 0001 SRL GR1, #0001, GR2
|
602
|
+
0025 6002 0001 JPZ #0001, GR2
|
603
|
+
0027 6102 0001 JMI #0001, GR2
|
604
|
+
0029 6202 0001 JNZ #0001, GR2
|
605
|
+
002B 6302 0001 JZE #0001, GR2
|
606
|
+
002D 6402 0001 JUMP #0001, GR2
|
607
|
+
002F 6502 0001 JPL #0001, GR2
|
608
|
+
0031 6602 0001 JOV #0001, GR2
|
609
|
+
0033 7002 0077 PUSH #0077, GR2
|
610
|
+
0035 7100 POP GR0
|
611
|
+
0036 8002 0077 CALL #0077, GR2
|
612
|
+
0038 8100 RET
|
613
|
+
0039 7001 0000 PUSH #0000, GR1
|
614
|
+
003B 7002 0000 PUSH #0000, GR2
|
615
|
+
003D 7003 0000 PUSH #0000, GR3
|
616
|
+
003F 7004 0000 PUSH #0000, GR4
|
617
|
+
0041 7005 0000 PUSH #0000, GR5
|
618
|
+
0043 7006 0000 PUSH #0000, GR6
|
619
|
+
0045 7007 0000 PUSH #0000, GR7
|
620
|
+
0047 7170 POP GR7
|
621
|
+
0048 7160 POP GR6
|
622
|
+
0049 7150 POP GR5
|
623
|
+
004A 7140 POP GR4
|
624
|
+
004B 7130 POP GR3
|
625
|
+
004C 7120 POP GR2
|
626
|
+
004D 7110 POP GR1
|
627
|
+
004E 7001 0000 PUSH #0000, GR1
|
628
|
+
0050 7002 0000 PUSH #0000, GR2
|
629
|
+
0052 1210 0001 LAD GR1, #0001
|
630
|
+
0054 1220 0002 LAD GR2, #0002
|
631
|
+
0056 F000 0000 SVC #0000
|
632
|
+
0058 7120 POP GR2
|
633
|
+
0059 7110 POP GR1
|
634
|
+
005A 7001 0000 PUSH #0000, GR1
|
635
|
+
005C 7002 0000 PUSH #0000, GR2
|
636
|
+
005E 1210 0003 LAD GR1, #0003
|
637
|
+
0060 1220 0004 LAD GR2, #0004
|
638
|
+
0062 F000 0001 SVC #0001
|
639
|
+
0064 7120 POP GR2
|
640
|
+
0065 7110 POP GR1
|
641
|
+
0066 F002 0000 SVC #0000, GR2
|
642
|
+
0068 F000 0002 SVC #0002
|
643
|
+
006A 6400 0072 JUMP #0072
|
644
|
+
006C 3200 0072 XOR GR0, #0072
|
645
|
+
006E 2012 0001 ADDA GR1, #0001, GR2
|
646
|
+
0070 2112 0001 SUBA GR1, #0001, GR2
|
647
|
+
0072 0061 DC 97 ; 'a'
|
648
|
+
0073 0027 DC 39 ; '''
|
649
|
+
0074 0062 DC 98 ; 'b'
|
650
|
+
0075 0063 DC 99 ; 'c'
|
651
|
+
0076 FFFF DC -1
|
652
|
+
0077 FFFF DC -1
|
653
|
+
0078 FFFF DC -1
|
654
|
+
MAP
|
655
|
+
end
|
656
|
+
|
657
|
+
private
|
658
|
+
|
659
|
+
def asm(order = nil, options = {})
|
660
|
+
options = {
|
661
|
+
:regs => {},
|
662
|
+
:flags => {},
|
663
|
+
:dc => {},
|
664
|
+
:ds => {},
|
665
|
+
}.merge(options)
|
666
|
+
|
667
|
+
options[:flags].each{|k, v|@p.gr[:fr].send("#{k}=", v)}
|
668
|
+
options[:regs].each{|k, v|@p.gr[k].value = v}
|
669
|
+
|
670
|
+
source = Array(order) + [" exit"]
|
671
|
+
source += options[:dc].collect{|k, v|"#{k} dc #{Array(v).join(',')}"}
|
672
|
+
source += options[:ds].collect{|k, v|"#{k} ds #{Array(v).join(',')}"}
|
673
|
+
source = source.join("\n")
|
674
|
+
|
675
|
+
@p.assemble_without_init_env(source)
|
676
|
+
@p.before_go
|
677
|
+
@p.command_go
|
678
|
+
@p
|
679
|
+
end
|
680
|
+
|
681
|
+
def var_check(name, value)
|
682
|
+
var(name).should == value
|
683
|
+
end
|
684
|
+
|
685
|
+
def var(name)
|
686
|
+
Value.new(@p.memory[@p.labels[:__global__].fetch(name.to_s)]).s_value
|
687
|
+
end
|
688
|
+
|
689
|
+
def reg_is(name, value)
|
690
|
+
@p.gr[name].s_value.should == value
|
691
|
+
end
|
692
|
+
|
693
|
+
def fire(*args)
|
694
|
+
@p.gr[:fr].available_flags.should == args
|
695
|
+
end
|
696
|
+
|
697
|
+
def fr_blank
|
698
|
+
fire
|
699
|
+
end
|
700
|
+
end
|