scasm 0.0.1 → 0.1.0
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.
- data/README.md +53 -4
- data/lib/scasm/assembler.rb +14 -0
- data/lib/scasm/statement.rb +11 -0
- data/lib/scasm/version.rb +1 -1
- data/test/test_assembler.rb +26 -0
- metadata +3 -3
data/README.md
CHANGED
@@ -18,10 +18,14 @@ Installation
|
|
18
18
|
Example
|
19
19
|
-------
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
````ruby
|
22
|
+
foo = A
|
23
|
+
bar = B
|
24
|
+
offset = 42
|
25
|
+
label "loop"
|
26
|
+
add [foo, offset], bar
|
27
|
+
set pc, "loop"
|
28
|
+
````
|
25
29
|
|
26
30
|
See the examples directory for more sample code.
|
27
31
|
|
@@ -32,6 +36,32 @@ SCASM input is Ruby code, but you won't need a deep understanding of Ruby to
|
|
32
36
|
get started. Simple statements like `add A, 1` work just like you expect. This
|
33
37
|
section will cover the SCASM-specific syntax.
|
34
38
|
|
39
|
+
### Instructions
|
40
|
+
|
41
|
+
To emit an instruction just write its lower-case name followed by the values:
|
42
|
+
|
43
|
+
````ruby
|
44
|
+
add A, 1
|
45
|
+
jsr X
|
46
|
+
````
|
47
|
+
|
48
|
+
The one exception is the `and` instruction, which must be written as `and_`
|
49
|
+
because `and` is a reserved word in Ruby.
|
50
|
+
|
51
|
+
### Pseudoinstructions
|
52
|
+
|
53
|
+
* `jmp label` - Equivalent to `set pc, label`.
|
54
|
+
* `ret` - Equivalent to `set pc, pop`.
|
55
|
+
|
56
|
+
To make your own pseudoinstructions/macros just define a Ruby method. For
|
57
|
+
example, here's how `jmp` is implemented:
|
58
|
+
|
59
|
+
````ruby
|
60
|
+
def jmp label
|
61
|
+
set pc, label
|
62
|
+
end
|
63
|
+
````
|
64
|
+
|
35
65
|
### Registers
|
36
66
|
|
37
67
|
Ruby variables named `A`, `B`, `C`, `X`, `Y`, `Z`, `I`, and `J` are provided to refer to the
|
@@ -52,6 +82,25 @@ Examples:
|
|
52
82
|
|
53
83
|
Literal values are just given as integers. Example: `42` or `0x200`.
|
54
84
|
|
85
|
+
### Labels
|
86
|
+
|
87
|
+
Labels are defined by the `label` statement. To refer to a label, just use its name. For example:
|
88
|
+
|
89
|
+
````ruby
|
90
|
+
label "loop"
|
91
|
+
add A, 1
|
92
|
+
set pc, "loop"
|
93
|
+
````
|
94
|
+
|
95
|
+
### Data
|
96
|
+
|
97
|
+
Use the `data` statement to put arbitrary words into the binary.
|
98
|
+
|
99
|
+
````ruby
|
100
|
+
label "sin_lookup_table"
|
101
|
+
data 0, 0x38f6, 0x6f12, 0x9f9c, 0xc825, 0xe6a4, 0xf993, 0xffff
|
102
|
+
````
|
103
|
+
|
55
104
|
### Miscellaneous
|
56
105
|
|
57
106
|
These values have the same meaning as in the spec:
|
data/lib/scasm/assembler.rb
CHANGED
@@ -82,6 +82,10 @@ class Assembler < BasicObject
|
|
82
82
|
ImmediateLabel.new(name).tap { |x| @relocations << x }
|
83
83
|
end
|
84
84
|
|
85
|
+
def data *words
|
86
|
+
@stmts << Data.new(words)
|
87
|
+
end
|
88
|
+
|
85
89
|
# Add a method for each instruction
|
86
90
|
BASIC_OPCODES.each do |opsym,opcode|
|
87
91
|
define_method(opsym) { |a,b| inst opsym, a, b }
|
@@ -96,6 +100,16 @@ class Assembler < BasicObject
|
|
96
100
|
const_set regsym, regsym
|
97
101
|
end
|
98
102
|
|
103
|
+
## Pseudoinstructions
|
104
|
+
|
105
|
+
def jmp label
|
106
|
+
set pc, label
|
107
|
+
end
|
108
|
+
|
109
|
+
def ret
|
110
|
+
set pc, pop
|
111
|
+
end
|
112
|
+
|
99
113
|
private
|
100
114
|
|
101
115
|
def resolve_labels
|
data/lib/scasm/statement.rb
CHANGED
@@ -53,6 +53,17 @@ class Instruction < Statement
|
|
53
53
|
end
|
54
54
|
|
55
55
|
class Data < Statement
|
56
|
+
def initialize words
|
57
|
+
@words = words
|
58
|
+
end
|
59
|
+
|
60
|
+
def assemble io
|
61
|
+
io.write @words.pack('v*')
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_s
|
65
|
+
"data #{@words * ', '}"
|
66
|
+
end
|
56
67
|
end
|
57
68
|
|
58
69
|
class Label < Statement
|
data/lib/scasm/version.rb
CHANGED
data/test/test_assembler.rb
CHANGED
@@ -130,4 +130,30 @@ class AssemblerTest < Test::Unit::TestCase
|
|
130
130
|
expect [0x7c10, 0x0020]
|
131
131
|
check 'jsr 32'
|
132
132
|
end
|
133
|
+
|
134
|
+
def test_data
|
135
|
+
expect [1, 2, 3, 4, 65535]
|
136
|
+
check 'data 1, 2, 3, 4, 65535'
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_jmp
|
140
|
+
expect [
|
141
|
+
0x7dc1, 0x0000,
|
142
|
+
]
|
143
|
+
|
144
|
+
check <<-EOS
|
145
|
+
label 'loop'
|
146
|
+
jmp 'loop'
|
147
|
+
EOS
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_ret
|
151
|
+
expect [
|
152
|
+
0x61c1
|
153
|
+
]
|
154
|
+
|
155
|
+
check <<-EOS
|
156
|
+
ret
|
157
|
+
EOS
|
158
|
+
end
|
133
159
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scasm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-04-05 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: trollop
|
16
|
-
requirement: &
|
16
|
+
requirement: &8467060 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *8467060
|
25
25
|
description: ''
|
26
26
|
email:
|
27
27
|
- rlane@club.cc.cmu.edu
|