n65 0.5.0 → 1.0.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.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data/.github/workflows/ci.yml +28 -0
- data/.gitignore +1 -1
- data/.rubocop.yml +125 -0
- data/Gemfile +3 -1
- data/README.md +3 -20
- data/Rakefile +15 -1
- data/bin/n65 +2 -0
- data/data/opcodes.yaml +39 -39
- data/everdrive_transfer/everdrive.rb +175 -0
- data/examples/pulse_chord.asm +1 -1
- data/examples/scales.asm +182 -0
- data/lib/n65/directives/ascii.rb +4 -19
- data/lib/n65/directives/bytes.rb +20 -35
- data/lib/n65/directives/dw.rb +22 -36
- data/lib/n65/directives/enter_scope.rb +14 -30
- data/lib/n65/directives/exit_scope.rb +7 -17
- data/lib/n65/directives/inc.rb +14 -30
- data/lib/n65/directives/incbin.rb +6 -24
- data/lib/n65/directives/ines_header.rb +66 -27
- data/lib/n65/directives/label.rb +8 -21
- data/lib/n65/directives/org.rb +9 -19
- data/lib/n65/directives/segment.rb +5 -19
- data/lib/n65/directives/space.rb +6 -18
- data/lib/n65/front_end.rb +36 -39
- data/lib/n65/instruction.rb +123 -159
- data/lib/n65/instruction_base.rb +6 -18
- data/lib/n65/memory_space.rb +51 -71
- data/lib/n65/opcodes.rb +3 -5
- data/lib/n65/parser.rb +20 -38
- data/lib/n65/regexes.rb +20 -21
- data/lib/n65/symbol_table.rb +58 -89
- data/lib/n65/version.rb +3 -1
- data/lib/n65.rb +120 -121
- data/n65.gemspec +17 -12
- data/nes_lib/nes.sym +2 -2
- data/spec/.rubocop.yml +4 -0
- data/spec/assembler_spec.rb +84 -0
- data/spec/lib/n65/memory_space_spec.rb +147 -0
- data/spec/lib/n65/symbol_table_spec.rb +291 -0
- data/utils/opcode_table_to_yaml.rb +65 -67
- data.tar.gz.sig +0 -0
- metadata +84 -41
- metadata.gz.sig +0 -0
- data/examples/music_driver.asm +0 -202
- data/test/test_memory_space.rb +0 -82
- data/test/test_symbol_table.rb +0 -238
- data/utils/midi/Makefile +0 -3
- data/utils/midi/c_scale.mid +0 -0
- data/utils/midi/convert +0 -0
- data/utils/midi/guitar.mid +0 -0
- data/utils/midi/include/event.h +0 -93
- data/utils/midi/include/file.h +0 -57
- data/utils/midi/include/helpers.h +0 -14
- data/utils/midi/include/track.h +0 -45
- data/utils/midi/lil_melody.mid +0 -0
- data/utils/midi/mi_feabhra.mid +0 -0
- data/utils/midi/midi_to_nes.rb +0 -204
- data/utils/midi/source/convert.cpp +0 -16
- data/utils/midi/source/event.cpp +0 -96
- data/utils/midi/source/file.cpp +0 -37
- data/utils/midi/source/helpers.cpp +0 -46
- data/utils/midi/source/track.cpp +0 -37
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../../lib/n65'
|
|
4
|
+
require_relative '../../../lib/n65/symbol_table'
|
|
5
|
+
|
|
6
|
+
RSpec.describe(N65::SymbolTable) do
|
|
7
|
+
subject { described_class.new }
|
|
8
|
+
|
|
9
|
+
context 'when defining a global symbol' do
|
|
10
|
+
before { subject.define_symbol('dog', 'woof') }
|
|
11
|
+
|
|
12
|
+
it 'can resolve the value' do
|
|
13
|
+
expect(subject.resolve_symbol('dog')).to eq('woof')
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
context 'when entering a sub-scope' do
|
|
18
|
+
before do
|
|
19
|
+
subject.enter_scope('animals')
|
|
20
|
+
subject.define_symbol('dog', 'woof')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'can resolve the value' do
|
|
24
|
+
expect(subject.resolve_symbol('dog')).to eq('woof')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'can resolve the value with full dot syntax' do
|
|
28
|
+
expect(subject.resolve_symbol('animals.dog')).to eq('woof')
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context 'when accessing a symbol at higher scope' do
|
|
33
|
+
before do
|
|
34
|
+
subject.enter_scope('outer')
|
|
35
|
+
subject.define_symbol('dog', 'woof')
|
|
36
|
+
subject.enter_scope('inner')
|
|
37
|
+
subject.define_symbol('pig', 'oink')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'can resolve the outer value without dot syntax' do
|
|
41
|
+
expect(subject.resolve_symbol('dog')).to eq('woof')
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'can resolve the value in current scope' do
|
|
45
|
+
expect(subject.resolve_symbol('pig')).to eq('oink')
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
context 'when a symbol from an outer scope is shadowed' do
|
|
50
|
+
before do
|
|
51
|
+
subject.enter_scope('outer')
|
|
52
|
+
subject.define_symbol('dog', 'woof')
|
|
53
|
+
subject.enter_scope('inner')
|
|
54
|
+
subject.define_symbol('dog', 'bark')
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'the inner scope shadows the outer' do
|
|
58
|
+
expect(subject.resolve_symbol('dog')).to eq('bark')
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'does not shadow it when we leave the inner scope' do
|
|
62
|
+
subject.exit_scope
|
|
63
|
+
expect(subject.resolve_symbol('dog')).to eq('woof')
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'can access inner via dot syntax if we exit both scopes' do
|
|
67
|
+
subject.exit_scope
|
|
68
|
+
subject.exit_scope
|
|
69
|
+
expect(subject.resolve_symbol('outer.inner.dog')).to eq('bark')
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
context 'when trying to access a symbol not in scope' do
|
|
74
|
+
before do
|
|
75
|
+
subject.enter_scope('animals')
|
|
76
|
+
subject.define_symbol('dog', 'woof')
|
|
77
|
+
subject.exit_scope
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it 'is undefined' do
|
|
81
|
+
expect { subject.resolve_symbol('dog') }.to raise_error(described_class::UndefinedSymbol)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
context 'when trying to access a symbol not in scope' do
|
|
86
|
+
before do
|
|
87
|
+
subject.enter_scope('animals')
|
|
88
|
+
subject.define_symbol('dog', 'woof')
|
|
89
|
+
subject.exit_scope
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it 'can be accessed by full path' do
|
|
93
|
+
expect(subject.resolve_symbol('animals.dog')).to eq('woof')
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
context 'when we have two symbols with the same name in different scopes' do
|
|
98
|
+
before do
|
|
99
|
+
subject.define_symbol('dog', 'woof')
|
|
100
|
+
subject.enter_scope('animals')
|
|
101
|
+
subject.define_symbol('dog', 'woof woof')
|
|
102
|
+
subject.exit_scope
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it 'can access each by full path' do
|
|
106
|
+
expect(subject.resolve_symbol('dog')).to eq('woof')
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it 'can access each by full path' do
|
|
110
|
+
expect(subject.resolve_symbol('animals.dog')).to eq('woof woof')
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
context 'when trying to access symbols at top scope' do
|
|
115
|
+
before do
|
|
116
|
+
subject.define_symbol('dog', 'woof')
|
|
117
|
+
subject.enter_scope('animals')
|
|
118
|
+
subject.define_symbol('dog', 'woof woof')
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it 'can use the global prefix' do
|
|
122
|
+
expect(subject.resolve_symbol('global.dog')).to eq('woof')
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
context 'when creating an anonymous scope' do
|
|
127
|
+
before do
|
|
128
|
+
subject.define_symbol('dog', 'woof')
|
|
129
|
+
subject.enter_scope
|
|
130
|
+
subject.define_symbol('dog', 'woof woof')
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it 'gets the value in the current anonymous scope' do
|
|
134
|
+
expect(subject.resolve_symbol('dog')).to eq('woof woof')
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it 'can get the outer dog by dot syntax' do
|
|
138
|
+
expect(subject.resolve_symbol('global.dog')).to eq('woof')
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it 'can get the outer dog by exiting anonymous scope and resolving' do
|
|
142
|
+
subject.exit_scope
|
|
143
|
+
expect(subject.resolve_symbol('dog')).to eq('woof')
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
context 'when trying to exit the top most scope' do
|
|
148
|
+
it 'raises an error' do
|
|
149
|
+
expect { subject.exit_scope }.to raise_error(described_class::CantExitScope)
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
context 'when checking the address value of a scope' do
|
|
154
|
+
let(:assembler) { N65::Assembler.new }
|
|
155
|
+
let(:program) do
|
|
156
|
+
<<~'ASM'
|
|
157
|
+
.ines {"prog": 1, "char": 0, "mapper": 0, "mirror": 0}
|
|
158
|
+
.org $8000
|
|
159
|
+
.segment prog 0
|
|
160
|
+
.scope main
|
|
161
|
+
sei
|
|
162
|
+
cld
|
|
163
|
+
lda #$00
|
|
164
|
+
jmp main
|
|
165
|
+
.
|
|
166
|
+
jmp main
|
|
167
|
+
jmp global.main
|
|
168
|
+
ASM
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
before { assembler.assemble_string(program) }
|
|
172
|
+
|
|
173
|
+
it 'assigns the value of the scope main to the program counter value' do
|
|
174
|
+
expect(assembler.symbol_table.resolve_symbol('global.main')).to eq(0x8000)
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
context 'when we try to jump to a forward declared symbol' do
|
|
179
|
+
let(:assembler) { N65::Assembler.new }
|
|
180
|
+
let(:program) do
|
|
181
|
+
<<~'ASM'
|
|
182
|
+
.ines {"prog": 1, "char": 0, "mapper": 0, "mirror": 0}
|
|
183
|
+
.org $8000
|
|
184
|
+
.scope main
|
|
185
|
+
sei
|
|
186
|
+
cld
|
|
187
|
+
lda #$00
|
|
188
|
+
bne forward_symbol
|
|
189
|
+
nop
|
|
190
|
+
nop
|
|
191
|
+
nop
|
|
192
|
+
forward_symbol:
|
|
193
|
+
rts
|
|
194
|
+
.
|
|
195
|
+
ASM
|
|
196
|
+
end
|
|
197
|
+
let(:correct_binary) do
|
|
198
|
+
[
|
|
199
|
+
0x78, # SEI
|
|
200
|
+
0xd8, # CLD
|
|
201
|
+
0xa9, 0x0, # LDA immediate 0
|
|
202
|
+
0xd0, 0x3, # BNE +3
|
|
203
|
+
0xea, # NOP
|
|
204
|
+
0xea, # NOP
|
|
205
|
+
0xea, # NOP
|
|
206
|
+
0x60 # RTS
|
|
207
|
+
]
|
|
208
|
+
end
|
|
209
|
+
let(:emitted_rom) { assembler.emit_binary_rom.bytes[16...26] }
|
|
210
|
+
|
|
211
|
+
before { assembler.assemble_string(program) }
|
|
212
|
+
|
|
213
|
+
it 'assembles the branch to forward_symbol correctly' do
|
|
214
|
+
expect(emitted_rom).to eq(correct_binary)
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
context 'when setting a symbols value' do
|
|
219
|
+
before do
|
|
220
|
+
subject.define_symbol('variable', 0xff)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
it 'can resolve to that value' do
|
|
224
|
+
expect(subject.resolve_symbol('variable')).to eq(0xff)
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
context 'when performing artithmetic on a symbol' do
|
|
229
|
+
before do
|
|
230
|
+
subject.define_symbol('variable', 0x20)
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
it 'can perform addition on the symbol' do
|
|
234
|
+
expect(subject.resolve_symbol('variable+1')).to eq(0x21)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
it 'can perform subtraction on the symbol' do
|
|
238
|
+
expect(subject.resolve_symbol('variable-16')).to eq(0x10)
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
it 'can perform multiplication on the symbol' do
|
|
242
|
+
expect(subject.resolve_symbol('variable*2')).to eq(0x40)
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
it 'can perform division on the symbol' do
|
|
246
|
+
expect(subject.resolve_symbol('variable/2')).to eq(0x10)
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
context 'when performing arithmetic on a scope struct' do
|
|
251
|
+
let(:assembler) { N65::Assembler.new }
|
|
252
|
+
let(:program) do
|
|
253
|
+
<<~'ASM'
|
|
254
|
+
.ines {"prog": 1, "char": 0, "mapper": 0, "mirror": 0}
|
|
255
|
+
|
|
256
|
+
.org $0020
|
|
257
|
+
.scope struct
|
|
258
|
+
.space a 1
|
|
259
|
+
.space b 1
|
|
260
|
+
.
|
|
261
|
+
|
|
262
|
+
.org $8000
|
|
263
|
+
.scope main
|
|
264
|
+
sei
|
|
265
|
+
cld
|
|
266
|
+
lda struct+1 zp
|
|
267
|
+
lda struct*2 zp
|
|
268
|
+
rts
|
|
269
|
+
.
|
|
270
|
+
ASM
|
|
271
|
+
end
|
|
272
|
+
let(:emitted_rom) { assembler.emit_binary_rom.bytes[16...23] }
|
|
273
|
+
let(:correct_binary) do
|
|
274
|
+
[
|
|
275
|
+
0x78, # sei
|
|
276
|
+
0xd8, # cld
|
|
277
|
+
0xa5, # lda
|
|
278
|
+
0x21, # $20 + 1
|
|
279
|
+
0xa5, # lda
|
|
280
|
+
0x40, # $20 * 2
|
|
281
|
+
0x60 # rts
|
|
282
|
+
]
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
before { assembler.assemble_string(program) }
|
|
286
|
+
|
|
287
|
+
it 'assembles the symbol arithmetic correctly' do
|
|
288
|
+
expect(emitted_rom).to eq(correct_binary)
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
end
|
|
@@ -1,91 +1,89 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
4
|
+
##############################################################################
|
|
5
|
+
# From http://www.6502.org/tutorials/6502opcodes.html
|
|
6
|
+
# This web page has information about each and every 6502 instruction
|
|
7
|
+
# Specifically:
|
|
8
|
+
#
|
|
9
|
+
# - Description of what each of the instructions do
|
|
10
|
+
# - Which modes are supported by which instructions, immediate, zero page
|
|
11
|
+
# zero page x, and y, absolute, indirect, relative etc.
|
|
12
|
+
# - The hex codes each instruction assembles to, in each mode.
|
|
13
|
+
# - The lengths in bytes of each instruction, by mode
|
|
14
|
+
# - The possibly variable number of cycles each instruction takes.
|
|
15
|
+
#
|
|
16
|
+
# There are 56 of them, and in my programmer laziness I just wrote this
|
|
17
|
+
# script to parse the page into the data structure that you see in
|
|
18
|
+
# opcodes.yaml. This really helped in creating the assembler, and
|
|
19
|
+
# it had basically everything I needed to know, and sped up writing
|
|
20
|
+
# this by huge factor. So, yay to this page, and this script!
|
|
20
21
|
|
|
21
22
|
require 'yaml'
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
# Instruction name, and output structure to fill in.
|
|
24
25
|
name = :adc
|
|
25
|
-
output = {name
|
|
26
|
+
output = { name: {} }
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
text
|
|
29
|
-
Immediate ADC #$44 $69 2 2
|
|
30
|
-
Zero Page ADC $44 $65 2 3
|
|
31
|
-
Zero Page,X ADC $44,X $75 2 4
|
|
32
|
-
Absolute ADC $4400 $6D 3 4
|
|
33
|
-
Absolute,X ADC $4400,X $7D 3 4+
|
|
34
|
-
Absolute,Y ADC $4400,Y $79 3 4+
|
|
35
|
-
Indirect,X ADC ($44,X) $61 2 6
|
|
36
|
-
Indirect,Y ADC ($44),Y $71 2 5+
|
|
28
|
+
# Copy paste the tables from that website into this heredoc:
|
|
29
|
+
text = <<~'TEXT'
|
|
30
|
+
Immediate ADC #$44 $69 2 2
|
|
31
|
+
Zero Page ADC $44 $65 2 3
|
|
32
|
+
Zero Page,X ADC $44,X $75 2 4
|
|
33
|
+
Absolute ADC $4400 $6D 3 4
|
|
34
|
+
Absolute,X ADC $4400,X $7D 3 4+
|
|
35
|
+
Absolute,Y ADC $4400,Y $79 3 4+
|
|
36
|
+
Indirect,X ADC ($44,X) $61 2 6
|
|
37
|
+
Indirect,Y ADC ($44),Y $71 2 5+
|
|
37
38
|
TEXT
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
## And now iterate over each line to extract the info
|
|
40
|
+
# And now iterate over each line to extract the info
|
|
41
41
|
lines = text.split(/\n/)
|
|
42
42
|
lines.each do |line|
|
|
43
|
-
|
|
44
|
-
## Grab out the values we care about
|
|
43
|
+
# Grab out the values we care about
|
|
45
44
|
parts = line.split
|
|
46
45
|
cycles, len, hex = parts[-1], parts[-2], parts[-3]
|
|
47
|
-
hex =
|
|
46
|
+
hex = format('0x%X', hex.gsub('$', '').to_i(16))
|
|
48
47
|
|
|
49
48
|
match_data = cycles.match(/([0-9]+)(\+?)/)
|
|
50
49
|
cycles = match_data[1]
|
|
51
50
|
boundary = match_data[2]
|
|
52
|
-
hash = {:
|
|
51
|
+
hash = { hex: hex, len: len, cycles: cycles, boundry_add: boundary != '' }
|
|
53
52
|
|
|
54
|
-
|
|
53
|
+
# And now decide which mode the line belongs to, collecting each listed mode
|
|
55
54
|
hash = case line
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
55
|
+
when /^Accumulator/
|
|
56
|
+
{ accumulator: hash }
|
|
57
|
+
when /^Immediate/
|
|
58
|
+
{ immediate: hash }
|
|
59
|
+
when /^Zero Page,X/
|
|
60
|
+
{ zero_page_x: hash }
|
|
61
|
+
when /^Zero Page,Y/
|
|
62
|
+
{ zero_page_y: hash }
|
|
63
|
+
when /^Zero Page/
|
|
64
|
+
{ zero_page: hash }
|
|
65
|
+
when /^Absolute,X/
|
|
66
|
+
{ absolute_x: hash }
|
|
67
|
+
when /^Absolute,Y/
|
|
68
|
+
{ absolute_y: hash }
|
|
69
|
+
when /^Absolute/
|
|
70
|
+
{ absolute: hash }
|
|
71
|
+
when /^Indirect,X/
|
|
72
|
+
{ indirect_x: hash }
|
|
73
|
+
when /^Indirect,Y/
|
|
74
|
+
{ indirect_y: hash }
|
|
75
|
+
when /^Indirect/
|
|
76
|
+
{ indirect: hash }
|
|
77
|
+
when /^Implied/
|
|
78
|
+
{ implied: hash }
|
|
79
|
+
else
|
|
80
|
+
{}
|
|
81
|
+
end
|
|
83
82
|
output[name].merge!(hash)
|
|
84
83
|
end
|
|
85
84
|
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
# Now output some yaml, and I only had to do this about 45 times
|
|
86
|
+
# instead of laboriously and mistak-pronely doing it by hand.
|
|
88
87
|
puts YAML.dump(output).gsub("'", '')
|
|
89
88
|
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
# See opcodes.yaml
|
data.tar.gz.sig
ADDED
|
Binary file
|
metadata
CHANGED
|
@@ -1,44 +1,99 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: n65
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Safiire
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
|
-
cert_chain:
|
|
11
|
-
|
|
9
|
+
cert_chain:
|
|
10
|
+
- |
|
|
11
|
+
-----BEGIN CERTIFICATE-----
|
|
12
|
+
MIIEijCCAvKgAwIBAgIBATANBgkqhkiG9w0BAQsFADBFMRAwDgYDVQQDDAdzYWZp
|
|
13
|
+
aXJlMRwwGgYKCZImiZPyLGQBGRYMaXJrZW5raXR0aWVzMRMwEQYKCZImiZPyLGQB
|
|
14
|
+
GRYDY29tMB4XDTI2MDczMTIyMzIyN1oXDTI3MDczMTIyMzIyN1owRTEQMA4GA1UE
|
|
15
|
+
AwwHc2FmaWlyZTEcMBoGCgmSJomT8ixkARkWDGlya2Vua2l0dGllczETMBEGCgmS
|
|
16
|
+
JomT8ixkARkWA2NvbTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAM0L
|
|
17
|
+
DaMnUQ6jVoPfLrU3xznh53NKFHxK7fuCzn8T4fe8NysBpTaDpMVdDGMjUyMZ7dIH
|
|
18
|
+
ufJwC2twDfcX1i95U8xy8g9Pymec9l6huwcu8gZjCwwv4sGejsJBh3w/mrfIAG0d
|
|
19
|
+
iORSnGl9dU+JfFC8fKdMnVNhS4DoXhwpvtwTyZz8S83b3A85nd4ArcLIRu87jt3R
|
|
20
|
+
PSg3VChmr19RQemPq9tMOrVRaaV1dCF48pcchFTh4nSuTZorAWI1LMmbod3X0L4c
|
|
21
|
+
NLKhSy8409BuC8MzQW/Poi5AGju9nhu7wXSpyCjzc/iOKR4OBsxwWc1OSTAhEN+P
|
|
22
|
+
CbImbFyqnyOi170ZqJsAxIkIRRJ7gHcbjCTtLzlLBhM4EMi1IDXrg+d1Wo8HCOPU
|
|
23
|
+
FGye9mJ6hYDN99+ei6ODhBnVmmPW1KhqoRuhaZIakXn0v2k+/MLFPDdhSyDe4ina
|
|
24
|
+
QwnB2xtzzhDsQhGZkqYtwq1CtCtZLb9jxbkcb2FZxwZU1Fga+ft0RaU209syGQID
|
|
25
|
+
AQABo4GEMIGBMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBTLktC6
|
|
26
|
+
gboWK+oVAacBV/TuMNhc6TAjBgNVHREEHDAagRhzYWZpaXJlQGlya2Vua2l0dGll
|
|
27
|
+
cy5jb20wIwYDVR0SBBwwGoEYc2FmaWlyZUBpcmtlbmtpdHRpZXMuY29tMA0GCSqG
|
|
28
|
+
SIb3DQEBCwUAA4IBgQC5ZnrbrUIMVIeq2Xpn1MrhmZlD0Bl6BTTb4tjO8AMod8AY
|
|
29
|
+
9bmBCfzXBNwF0prPvrwaZ6eTnLgPeByNHhXO7HcaQTZhyTOZdhUJ4YQjFO+emf5B
|
|
30
|
+
0WSsB1nU+vc0P+T0vdCxhpFfze0pXuAfef/hnLaFsTWvSZv0CBNSirtGSfdvGEYZ
|
|
31
|
+
YLA4bSs/HxL1NGlPaS/gSQic5BQapTH+Dy2iV0o45WXpdtSdJS9c9wPe3N1wi99U
|
|
32
|
+
rOl0/s70mlMRZZK4C06ioiWpOxANxZZQZ9AgaCh04NkVvx9iCoNrXktMlwBQBsUm
|
|
33
|
+
25TerYzsddkZm0rETJy9WebcdzbPHyr3EvXBbEsEa4yAKIrgndfo5lJmf4rFhZK3
|
|
34
|
+
lewUuIe+L/6Z/OHQO6v9yZ0i2ZZrGm/F/l/gDNWyPoWjmYhCb2SeL8je3QKkbv0V
|
|
35
|
+
yXnUU4CUd3nGqZ+O+K5FDHxyhZ+bVXB8KWm7VLsPEC1kPdYIOj3gNhjY0FNuwpex
|
|
36
|
+
cOU2xo9QjOzgxd3rzy4=
|
|
37
|
+
-----END CERTIFICATE-----
|
|
38
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
39
|
dependencies:
|
|
13
40
|
- !ruby/object:Gem::Dependency
|
|
14
41
|
name: bundler
|
|
15
42
|
requirement: !ruby/object:Gem::Requirement
|
|
16
43
|
requirements:
|
|
17
|
-
- - "
|
|
44
|
+
- - ">="
|
|
18
45
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
46
|
+
version: '0'
|
|
20
47
|
type: :development
|
|
21
48
|
prerelease: false
|
|
22
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
50
|
requirements:
|
|
24
|
-
- - "
|
|
51
|
+
- - ">="
|
|
25
52
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
53
|
+
version: '0'
|
|
27
54
|
- !ruby/object:Gem::Dependency
|
|
28
55
|
name: rake
|
|
29
56
|
requirement: !ruby/object:Gem::Requirement
|
|
30
57
|
requirements:
|
|
31
|
-
- - "
|
|
58
|
+
- - ">="
|
|
32
59
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
60
|
+
version: '0'
|
|
34
61
|
type: :development
|
|
35
62
|
prerelease: false
|
|
36
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
64
|
requirements:
|
|
38
|
-
- - "
|
|
65
|
+
- - ">="
|
|
39
66
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
41
|
-
|
|
67
|
+
version: '0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: rspec
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0'
|
|
75
|
+
type: :development
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '0'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: rubocop
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '0'
|
|
89
|
+
type: :development
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - ">="
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '0'
|
|
96
|
+
description: An NES assembler for the 6502 microprocessor in pure Ruby
|
|
42
97
|
email:
|
|
43
98
|
- safiire@irkenkitties.com
|
|
44
99
|
executables:
|
|
@@ -46,20 +101,23 @@ executables:
|
|
|
46
101
|
extensions: []
|
|
47
102
|
extra_rdoc_files: []
|
|
48
103
|
files:
|
|
104
|
+
- ".github/workflows/ci.yml"
|
|
49
105
|
- ".gitignore"
|
|
106
|
+
- ".rubocop.yml"
|
|
50
107
|
- Gemfile
|
|
51
108
|
- LICENSE
|
|
52
109
|
- README.md
|
|
53
110
|
- Rakefile
|
|
54
111
|
- bin/n65
|
|
55
112
|
- data/opcodes.yaml
|
|
113
|
+
- everdrive_transfer/everdrive.rb
|
|
56
114
|
- examples/beep.asm
|
|
57
115
|
- examples/demo.asm
|
|
58
116
|
- examples/mario2.asm
|
|
59
117
|
- examples/mario2.char
|
|
60
|
-
- examples/music_driver.asm
|
|
61
118
|
- examples/noise.asm
|
|
62
119
|
- examples/pulse_chord.asm
|
|
120
|
+
- examples/scales.asm
|
|
63
121
|
- images/assembler_demo.png
|
|
64
122
|
- lib/n65.rb
|
|
65
123
|
- lib/n65/directives/ascii.rb
|
|
@@ -85,30 +143,15 @@ files:
|
|
|
85
143
|
- lib/n65/version.rb
|
|
86
144
|
- n65.gemspec
|
|
87
145
|
- nes_lib/nes.sym
|
|
88
|
-
-
|
|
89
|
-
-
|
|
90
|
-
-
|
|
91
|
-
-
|
|
92
|
-
- utils/midi/convert
|
|
93
|
-
- utils/midi/guitar.mid
|
|
94
|
-
- utils/midi/include/event.h
|
|
95
|
-
- utils/midi/include/file.h
|
|
96
|
-
- utils/midi/include/helpers.h
|
|
97
|
-
- utils/midi/include/track.h
|
|
98
|
-
- utils/midi/lil_melody.mid
|
|
99
|
-
- utils/midi/mi_feabhra.mid
|
|
100
|
-
- utils/midi/midi_to_nes.rb
|
|
101
|
-
- utils/midi/source/convert.cpp
|
|
102
|
-
- utils/midi/source/event.cpp
|
|
103
|
-
- utils/midi/source/file.cpp
|
|
104
|
-
- utils/midi/source/helpers.cpp
|
|
105
|
-
- utils/midi/source/track.cpp
|
|
146
|
+
- spec/.rubocop.yml
|
|
147
|
+
- spec/assembler_spec.rb
|
|
148
|
+
- spec/lib/n65/memory_space_spec.rb
|
|
149
|
+
- spec/lib/n65/symbol_table_spec.rb
|
|
106
150
|
- utils/opcode_table_to_yaml.rb
|
|
107
151
|
homepage: http://github.com/safiire/n65
|
|
108
152
|
licenses:
|
|
109
|
-
-
|
|
153
|
+
- GPL-2.0-or-later
|
|
110
154
|
metadata: {}
|
|
111
|
-
post_install_message:
|
|
112
155
|
rdoc_options: []
|
|
113
156
|
require_paths:
|
|
114
157
|
- lib
|
|
@@ -116,18 +159,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
116
159
|
requirements:
|
|
117
160
|
- - ">="
|
|
118
161
|
- !ruby/object:Gem::Version
|
|
119
|
-
version:
|
|
162
|
+
version: 3.2.0
|
|
120
163
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
121
164
|
requirements:
|
|
122
165
|
- - ">="
|
|
123
166
|
- !ruby/object:Gem::Version
|
|
124
167
|
version: '0'
|
|
125
168
|
requirements: []
|
|
126
|
-
|
|
127
|
-
rubygems_version: 2.4.5
|
|
128
|
-
signing_key:
|
|
169
|
+
rubygems_version: 4.0.4
|
|
129
170
|
specification_version: 4
|
|
130
|
-
summary: An NES assembler for the 6502 microprocessor
|
|
171
|
+
summary: An NES assembler for the 6502 microprocessor
|
|
131
172
|
test_files:
|
|
132
|
-
-
|
|
133
|
-
-
|
|
173
|
+
- spec/.rubocop.yml
|
|
174
|
+
- spec/assembler_spec.rb
|
|
175
|
+
- spec/lib/n65/memory_space_spec.rb
|
|
176
|
+
- spec/lib/n65/symbol_table_spec.rb
|
metadata.gz.sig
ADDED
|
Binary file
|