rasl 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|