c64asm 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,132 @@
1
+ # encoding: utf-8
2
+ # See LICENSE.txt for licensing information.
3
+
4
+ require 'c64asm/asm'
5
+ require 'c64asm/data'
6
+
7
+ module C64Asm
8
+ class Error < Exception; end
9
+
10
+ # C64 Basic error
11
+ class BasicError < Error; end
12
+
13
+ # C64 Basic block
14
+ class Basic
15
+ attr_reader :basic, :code
16
+
17
+ # Create a new C64 basic block
18
+ def initialize(program, origin = 0x801, align = true)
19
+ raise BasicError, 'Program has to be a string' unless program.instance_of? String
20
+ raise BasicError, 'Origin has to be a fixnum' unless origin.instance_of? Fixnum
21
+ raise BasicError, 'Origin out of range' unless (origin >= 0 and origin <= 65535)
22
+
23
+ @basic = program
24
+ @code = Block.new
25
+
26
+ @code.push(Align.new(origin)) if align
27
+ @code.push(Data.new(parse(origin)))
28
+ end
29
+
30
+ # Return a pretty string representation
31
+ def to_s; "<Basic: #{@basic.lines.to_a.length}>"; end
32
+
33
+ private
34
+ # Parse basic code string given the origin address
35
+ def parse(addr)
36
+ state = :nextline
37
+ bytes = []
38
+ line = []
39
+ token = ''
40
+
41
+ @basic.upcase.each_char do |c|
42
+ if c == "\n"
43
+ state = :nextline
44
+ next
45
+ end
46
+
47
+ if state == :nextline
48
+ unless token.empty?
49
+ token.codepoints.each{|p| bytes += [PETSCII[p]]}
50
+ token = ''
51
+ end
52
+
53
+ unless bytes.empty?
54
+ bytes += [0]
55
+ addr += 1
56
+ end
57
+
58
+ addr += 2
59
+ bytes += [addr.ls_byte, addr.ms_byte]
60
+ state = :linenum
61
+ end
62
+
63
+ if state == :linenum
64
+ if c.match(/\d/)
65
+ token += c
66
+ addr += 1
67
+ else
68
+ raise BasicError, 'Each line has to start with a line number' if token.empty?
69
+
70
+ lineno = token.to_i
71
+ raise BasicError, 'Line number out of range' unless (lineno >= 0 and lineno <= 65535)
72
+
73
+ bytes += [lineno.ls_byte, lineno.ms_byte]
74
+ addr += 2
75
+ state = :out
76
+ token = ''
77
+
78
+ next if c == ' '
79
+ end
80
+ end
81
+
82
+ if state == :out
83
+ if c == '"'
84
+ bytes += [PETSCII['"'.ord]]
85
+ addr += 1
86
+ state = :in
87
+
88
+ next
89
+ elsif c == ' '
90
+ unless token.empty?
91
+ token.codepoints.each{|p| bytes += [PETSCII[p]]}
92
+ token = ''
93
+ end
94
+
95
+ bytes += [PETSCII[' '.ord]]
96
+ addr += 1
97
+ elsif BASIC.has_key? c
98
+ token.codepoints.each{|p| bytes += [PETSCII[p]]} unless token.empty?
99
+ bytes += [BASIC[c]]
100
+ addr += 1
101
+ token = ''
102
+ else
103
+ raise BasicError, 'Unknown character' unless PETSCII.has_key? c.codepoints.to_a.first
104
+
105
+ token += c
106
+ addr += 1
107
+
108
+ if BASIC.has_key? token
109
+ bytes += [BASIC[token]]
110
+ token = ''
111
+ end
112
+ end
113
+ end
114
+
115
+ if state == :in
116
+ raise BasicError, 'Unknown character' unless PETSCII.has_key? c.codepoints.to_a.first
117
+
118
+ token += c
119
+ addr += 1
120
+ state = :out if c == '"'
121
+ end
122
+ end
123
+
124
+ unless token.empty?
125
+ token.codepoints.each{|p| bytes += [PETSCII[p]]}
126
+ bytes += [0]
127
+ end
128
+
129
+ bytes += [0, 0]
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,221 @@
1
+ # encoding: utf-8
2
+ # See LICENSE.txt for licensing information.
3
+
4
+ module C64Asm
5
+ # Known addressing modes
6
+ ADDR_MODES = {
7
+ :n => { :src => '', :len => 0 },
8
+ :d => { :src => ' #%s', :len => 1},
9
+ :z => { :src => ' %s', :len => 1},
10
+ :zx => { :src => ' %s,x', :len => 1},
11
+ :zy => { :src => ' %s,y', :len => 1},
12
+ :zxr => { :src => ' (%s,z)', :len => 1},
13
+ :zyr => { :src => ' (%s),y', :len => 1},
14
+ :a => { :src => ' %s', :len => 2},
15
+ :ax => { :src => ' %s,x', :len => 2},
16
+ :ay => { :src => ' %s,y', :len => 2},
17
+ :ar => { :src => ' (%s)', :len => 2},
18
+ :r => { :src => ' %s', :len => 1},
19
+ :e => { :src => '', :len => 1}
20
+ }
21
+
22
+ # Known operands
23
+ OP_CODES = {
24
+ :adc=>{:d=>{:byte=>105, :cycles=>2},
25
+ :z=>{:byte=>101, :cycles=>3},
26
+ :zx=>{:byte=>117, :cycles=>4},
27
+ :zxr=>{:byte=>97, :cycles=>6},
28
+ :zyr=>{:byte=>113, :cycles=>5, :page=>true},
29
+ :a=>{:byte=>109, :cycles=>4},
30
+ :ax=>{:byte=>125, :cycles=>4, :page=>true},
31
+ :ay=>{:byte=>121, :cycles=>4, :page=>true}},
32
+ :and=>{:d=>{:byte=>41, :cycles=>2},
33
+ :z=>{:byte=>37, :cycles=>3},
34
+ :zx=>{:byte=>53, :cycles=>4},
35
+ :zxr=>{:byte=>33, :cycles=>6},
36
+ :zyr=>{:byte=>49, :cycles=>5, :page=>true},
37
+ :a=>{:byte=>45, :cycles=>4},
38
+ :ax=>{:byte=>61, :cycles=>4, :page=>true},
39
+ :ay=>{:byte=>41, :cycles=>4, :page=>true},
40
+ :e=>{:cycles=>2}},
41
+ :asl=>{:z=>{:byte=>6, :cycles=>5},
42
+ :zx=>{:byte=>22, :cycles=>6},
43
+ :a=>{:byte=>14, :cycles=>6},
44
+ :ax=>{:byte=>30, :cycles=>7},
45
+ :e=>{:byte=>10}},
46
+ :bcc=>{:r=>{:byte=>144, :cycles=>2, :page=>true, :branch=>true}},
47
+ :bcs=>{:r=>{:byte=>176, :cycles=>2, :page=>true, :branch=>true}},
48
+ :beq=>{:r=>{:byte=>240, :cycles=>2, :page=>true, :branch=>true}},
49
+ :bit=>{:d=>{:byte=>36, :cycles=>3}, :zyr=>{:byte=>44, :cycles=>4}},
50
+ :bmi=>{:r=>{:byte=>48, :cycles=>2, :page=>true, :branch=>true}},
51
+ :bne=>{:r=>{:byte=>208, :cycles=>2, :page=>true, :branch=>true}},
52
+ :bpl=>{:r=>{:byte=>16, :cycles=>2, :page=>true, :branch=>true}},
53
+ :brk=>{:n=>{:byte=>0, :cycles=>7}},
54
+ :bvc=>{:r=>{:byte=>80, :cycles=>2, :page=>true, :branch=>true}},
55
+ :bvs=>{:r=>{:byte=>112, :cycles=>2, :page=>true, :branch=>true}},
56
+ :clc=>{:n=>{:byte=>24, :cycles=>2}},
57
+ :cld=>{:n=>{:byte=>216, :cycles=>2}},
58
+ :cli=>{:n=>{:byte=>88, :cycles=>2}},
59
+ :clv=>{:n=>{:byte=>184, :cycles=>2}},
60
+ :cmp=>{:d=>{:byte=>201, :cycles=>2},
61
+ :z=>{:byte=>197, :cycles=>3},
62
+ :zx=>{:byte=>213, :cycles=>4},
63
+ :zxr=>{:byte=>193, :cycles=>6},
64
+ :zyr=>{:byte=>209, :cycles=>5, :page=>true},
65
+ :a=>{:byte=>205, :cycles=>4},
66
+ :ax=>{:byte=>221, :cycles=>4, :page=>true},
67
+ :ay=>{:byte=>217, :cycles=>4, :page=>true}},
68
+ :cpx=>{:d=>{:byte=>224, :cycles=>2},
69
+ :z=>{:byte=>228, :cycles=>3},
70
+ :a=>{:byte=>236, :cycles=>4}},
71
+ :cpy=>{:d=>{:byte=>192, :cycles=>2},
72
+ :z=>{:byte=>196, :cycles=>3},
73
+ :a=>{:byte=>204, :cycles=>4}},
74
+ :dec=>{:z=>{:byte=>198, :cycles=>5},
75
+ :zx=>{:byte=>214, :cycles=>6},
76
+ :a=>{:byte=>206, :cycles=>6},
77
+ :ax=>{:byte=>222, :cycles=>7}},
78
+ :dex=>{:n=>{:byte=>202, :cycles=>2}},
79
+ :dey=>{:n=>{:byte=>136, :cycles=>2}},
80
+ :eor=>{:d=>{:byte=>73, :cycles=>2},
81
+ :z=>{:byte=>69, :cycles=>3},
82
+ :zx=>{:byte=>85, :cycles=>4},
83
+ :zxr=>{:byte=>65, :cycles=>6},
84
+ :zyr=>{:byte=>81, :cycles=>5, :page=>true},
85
+ :a=>{:byte=>77, :cycles=>4},
86
+ :ax=>{:byte=>93, :cycles=>4, :page=>true},
87
+ :ay=>{:byte=>89, :cycles=>4, :page=>true}},
88
+ :inc=>{:z=>{:byte=>230, :cycles=>5},
89
+ :zx=>{:byte=>246, :cycles=>6},
90
+ :a=>{:byte=>238, :cycles=>6},
91
+ :ax=>{:byte=>254, :cycles=>7}},
92
+ :inx=>{:n=>{:byte=>232, :cycles=>2}},
93
+ :iny=>{:n=>{:byte=>200, :cycles=>2}},
94
+ :jmp=>{:a=>{:byte=>76, :cycles=>3}, :ar=>{:byte=>108, :cycles=>5}},
95
+ :jsr=>{:a=>{:byte=>32, :cycles=>6}},
96
+ :lda=>{:d=>{:byte=>169, :cycles=>2},
97
+ :z=>{:byte=>165, :cycles=>3},
98
+ :zx=>{:byte=>181, :cycles=>4},
99
+ :zxr=>{:byte=>161, :cycles=>6},
100
+ :zyr=>{:byte=>177, :cycles=>5, :page=>true},
101
+ :a=>{:byte=>173, :cycles=>4},
102
+ :ax=>{:byte=>189, :cycles=>4, :page=>true},
103
+ :ay=>{:byte=>185, :cycles=>4, :page=>true}},
104
+ :ldx=>{:d=>{:byte=>162, :cycles=>2},
105
+ :z=>{:byte=>166, :cycles=>3},
106
+ :zy=>{:byte=>182, :cycles=>4},
107
+ :a=>{:byte=>174, :cycles=>4},
108
+ :ay=>{:byte=>190, :cycles=>4, :page=>true}},
109
+ :ldy=>{:d=>{:byte=>160, :cycles=>2},
110
+ :z=>{:byte=>164, :cycles=>3},
111
+ :zx=>{:byte=>180, :cycles=>4},
112
+ :a=>{:byte=>172, :cycles=>4},
113
+ :ax=>{:byte=>188, :cycles=>4, :page=>true}},
114
+ :lsr=>{:z=>{:byte=>70, :cycles=>5},
115
+ :zx=>{:byte=>86, :cycles=>6},
116
+ :a=>{:byte=>78, :cycles=>6},
117
+ :ax=>{:byte=>94, :cycles=>7},
118
+ :e=>{:byte=>74, :cycles=>2}},
119
+ :nop=>{:n=>{:byte=>234, :cycles=>2}},
120
+ :ora=>{:d=>{:byte=>9, :cycles=>2},
121
+ :z=>{:byte=>5, :cycles=>3},
122
+ :zx=>{:byte=>21, :cycles=>4},
123
+ :zxr=>{:byte=>1, :cycles=>6},
124
+ :zyr=>{:byte=>17, :cycles=>5, :page=>true},
125
+ :a=>{:byte=>13, :cycles=>4},
126
+ :ax=>{:byte=>29, :cycles=>4, :page=>true},
127
+ :ay=>{:byte=>25, :cycles=>4, :page=>true}},
128
+ :pha=>{:n=>{:byte=>72, :cycles=>3}},
129
+ :php=>{:n=>{:byte=>8, :cycles=>3}},
130
+ :pla=>{:n=>{:byte=>104, :cycles=>4}},
131
+ :plp=>{:n=>{:byte=>40, :cycles=>4}},
132
+ :rol=>{:z=>{:byte=>38, :cycles=>5},
133
+ :zx=>{:byte=>54, :cycles=>6},
134
+ :a=>{:byte=>46, :cycles=>6},
135
+ :ax=>{:byte=>62, :cycles=>7},
136
+ :e=>{:byte=>42, :cycles=>2}},
137
+ :ror=>{:z=>{:byte=>102, :cycles=>5},
138
+ :zx=>{:byte=>118, :cycles=>6},
139
+ :a=>{:byte=>110, :cycles=>6},
140
+ :ax=>{:byte=>126, :cycles=>7},
141
+ :e=>{:byte=>106, :cycles=>2}},
142
+ :rti=>{:n=>{:byte=>64, :cycles=>6}},
143
+ :rts=>{:n=>{:byte=>96, :cycles=>6}},
144
+ :sbc=>{:d=>{:byte=>233, :cycles=>2},
145
+ :z=>{:byte=>229, :cycles=>3},
146
+ :zx=>{:byte=>245, :cycles=>4},
147
+ :zxr=>{:byte=>225, :cycles=>6},
148
+ :zyr=>{:byte=>241, :cycles=>5, :page=>true},
149
+ :a=>{:byte=>237, :cycles=>4},
150
+ :ax=>{:byte=>253, :cycles=>4, :page=>true},
151
+ :ay=>{:byte=>233, :cycles=>4, :page=>true}},
152
+ :sec=>{:n=>{:byte=>56, :cycles=>2}},
153
+ :sed=>{:n=>{:byte=>248, :cycles=>2}},
154
+ :sei=>{:n=>{:byte=>120, :cycles=>2}},
155
+ :sta=>{:z=>{:byte=>133, :cycles=>3},
156
+ :zx=>{:byte=>149, :cycles=>4},
157
+ :zxr=>{:byte=>129, :cycles=>6},
158
+ :zyr=>{:byte=>145, :cycles=>6},
159
+ :a=>{:byte=>141, :cycles=>4},
160
+ :ax=>{:byte=>157, :cycles=>5},
161
+ :ay=>{:byte=>153, :cycles=>5}},
162
+ :stx=>{:z=>{:byte=>134, :cycles=>3},
163
+ :zy=>{:byte=>150, :cycles=>4},
164
+ :a=>{:byte=>142, :cycles=>4}},
165
+ :sty=>{:z=>{:byte=>132, :cycles=>3},
166
+ :zx=>{:byte=>148, :cycles=>4},
167
+ :a=>{:byte=>140, :cycles=>4}},
168
+ :tax=>{:n=>{:byte=>170, :cycles=>2}},
169
+ :tay=>{:n=>{:byte=>168, :cycles=>2}},
170
+ :tsx=>{:n=>{:byte=>186, :cycles=>2}},
171
+ :txa=>{:n=>{:byte=>138, :cycles=>2}},
172
+ :txs=>{:n=>{:byte=>154, :cycles=>2}},
173
+ :tya=>{:n=>{:byte=>152, :cycles=>2}}}
174
+
175
+ # Character map
176
+ CHAR_MAP = {
177
+ 64=>0, 65=>1, 66=>2, 67=>3, 68=>4, 69=>5, 70=>6, 71=>7, 72=>8, 73=>9, 74=>10, 75=>11, 76=>12,
178
+ 77=>13, 78=>14, 79=>15, 80=>16, 81=>17, 82=>18, 83=>19, 84=>20, 85=>21, 86=>22, 87=>23, 88=>24,
179
+ 89=>25, 90=>26, 91=>27, 163=>28, 93=>29, 8593=>30, 8592=>31, 32=>32, 33=>33, 34=>34, 35=>35,
180
+ 36=>36, 37=>37, 38=>38, 39=>39, 40=>40, 41=>41, 42=>42, 43=>43, 44=>44, 45=>45, 46=>46, 47=>47,
181
+ 48=>48, 49=>49, 50=>50, 51=>51, 52=>52, 53=>53, 54=>54, 55=>55, 56=>56, 57=>57, 58=>58, 59=>59,
182
+ 60=>60, 61=>61, 62=>62, 63=>63
183
+ }
184
+
185
+ # PETSCII map
186
+ PETSCII = {
187
+ 32=>32, 160=>224, 38=>38, 33=>33, 34=>34, 35=>35, 36=>36, 37=>37, 39=>39, 40=>40, 41=>41, 42=>42,
188
+ 43=>43, 44=>44, 45=>45, 46=>46, 47=>47, 48=>48, 49=>49, 50=>50, 51=>51, 52=>52, 53=>53, 54=>54,
189
+ 55=>55, 56=>56, 57=>57, 58=>58, 59=>59, 61=>61, 62=>62, 63=>63, 64=>64, 65=>65, 66=>66, 67=>67,
190
+ 68=>68, 69=>69, 70=>70, 71=>71, 72=>72, 73=>73, 74=>74, 75=>75, 76=>76, 77=>77, 78=>78, 79=>79,
191
+ 80=>80, 81=>81, 82=>82, 83=>83, 84=>84, 85=>85, 86=>86, 87=>87, 88=>88, 89=>89, 90=>90, 91=>91,
192
+ 92=>92, 93=>93, 94=>94, 95=>95, 96=>96, 97=>97, 98=>98, 99=>99, 100=>100, 101=>101, 102=>102,
193
+ 103=>103, 104=>104, 105=>105, 106=>106, 107=>107, 108=>108, 109=>109, 110=>110, 111=>111, 112=>112,
194
+ 113=>113, 114=>114, 115=>115, 116=>116, 117=>117, 118=>118, 119=>119, 120=>120, 121=>121, 122=>122,
195
+ 123=>123, 124=>124, 125=>125, 126=>126, 127=>127, 61700=>129, 61712=>133, 61714=>134, 61716=>135,
196
+ 61718=>136, 61713=>137, 61715=>138, 61717=>139, 61719=>140, 10=>141, 61701=>144, 61726=>145, 61723=>146,
197
+ 61729=>148, 61702=>149, 61703=>150, 61704=>151, 61705=>152, 61706=>153, 61707=>154, 61708=>155, 61709=>156,
198
+ 61725=>157, 61710=>158, 61711=>159, 9612=>225, 9604=>226, 9620=>227, 9601=>228, 9615=>229, 9618=>230,
199
+ 9621=>231, 61743=>232, 9700=>233, 61744=>234, 9500=>235, 61748=>236, 9492=>237, 9488=>238, 9602=>239,
200
+ 9484=>240, 9524=>241, 9516=>242, 9508=>243, 9614=>244, 9613=>245, 61745=>246, 61746=>247, 61747=>248,
201
+ 9603=>249, 61741=>250, 61749=>251, 61750=>252, 9496=>253, 61751=>254, 61752=>191, 9473=>195, 9824=>193,
202
+ 9474=>221, 61730=>196, 61731=>197, 61732=>198, 61734=>199, 61736=>200, 9582=>201, 9584=>202, 9583=>203,
203
+ 61738=>204, 9586=>205, 9585=>206, 61739=>207, 61740=>208, 9679=>209, 61733=>210, 9829=>211, 61735=>212,
204
+ 9581=>213, 9587=>214, 9675=>215, 9827=>216, 61737=>217, 9830=>218, 9532=>219, 61742=>220, 960=>255,
205
+ 9701=>223
206
+ }
207
+
208
+ # Basic commands
209
+ BASIC = {
210
+ "END"=>128, "FOR"=>129, "NEXT"=>130, "DATA"=>131, "INPUT#"=>132, "INPUT"=>133, "DIM"=>134, "READ"=>135,
211
+ "LET"=>136, "GOTO"=>137, "RUN"=>138, "IF"=>139, "RESTORE"=>140, "GOSUB"=>141, "RETURN"=>142, "REM"=>143,
212
+ "STOP"=>144, "ON"=>145, "WAIT"=>146, "LOAD"=>147, "SAVE"=>148, "VERIFY"=>149, "DEF"=>150, "POKE"=>151,
213
+ "PRINT#"=>152, "PRINT"=>153, "CONT"=>154, "LIST"=>155, "CLR"=>156, "CMD"=>157, "SYS"=>158, "OPEN"=>159,
214
+ "CLOSE"=>160, "GET"=>161, "NEW"=>162, "TAB("=>163, "TO"=>164, "FN"=>165, "SPC("=>166, "THEN"=>167,
215
+ "NOT"=>168, "STEP"=>169, "+"=>170, "-"=>171, "*"=>172, "/"=>173, "^"=>174, "AND"=>175, "OR"=>176,
216
+ ">"=>177, "="=>178, "<"=>179, "SGN"=>180, "INT"=>181, "ABS"=>182, "USR"=>183, "FRE"=>184, "POS"=>185,
217
+ "SQR"=>186, "RND"=>187, "LOG"=>188, "EXP"=>189, "COS"=>190, "SIN"=>191, "TAN"=>192, "ATN"=>193,
218
+ "PEEK"=>194, "LEN"=>195, "STR$"=>196, "VAL"=>197, "ASC"=>198, "CHR$"=>199, "LEFT$"=>200, "RIGHT$"=>201,
219
+ "MID$"=>202, "GO"=>203
220
+ }
221
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+ # See LICENSE.txt for licensing information.
3
+
4
+ module C64Asm
5
+ # Reported version
6
+ VERSION = '0.4.1'
7
+ end
data/lib/c64asm.rb ADDED
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+ # See LICENSE.txt for licensing information.
3
+
4
+ require 'c64asm/asm'
5
+ require 'c64asm/version'
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+ # coding: utf-8
3
+ # See LICENSE.txt for licensing information.
4
+
5
+ # I assume I've used this to get the contents of what is now lib/data.rb.
6
+ # Data-driven assembly ftw!
7
+ #
8
+ # Honestly, I leave it as close to as it were two years ago as I can.
9
+ # Perlish stuff.
10
+
11
+ %w{ pp open-uri nokogiri }.each{|g| require g}
12
+
13
+ MODES = %w{ n d z zx zy zxr zyr a ax ay ar r e }
14
+
15
+ puts "MODES = [ #{MODES.collect{|m| ":#{m}"}.join(', ')} ]\n"
16
+
17
+ opcodes = Hash.new
18
+ page = Nokogiri::HTML.parse(open('http://sta.c64.org/cbm64mcinst2.html'))
19
+ page.xpath('//tr').each do |row|
20
+ data = row.xpath('td').collect{|c| c.content}
21
+ next unless data.length == 14
22
+ inst = data.shift.downcase.to_sym
23
+ opcodes[inst] = Hash.new
24
+ data.each_with_index do |code, i|
25
+ next if code[0] != '$'
26
+ mode = MODES[i].to_sym
27
+ op = code.gsub(/\$/, '').to_i(16)
28
+ opcodes[inst][mode] = Hash.new
29
+ opcodes[inst][mode][:byte] = op
30
+ end
31
+ end
32
+
33
+ page = Nokogiri::HTML.parse(open('http://sta.c64.org/cbm64mctime.html'))
34
+ page.xpath('//tr').each do |row|
35
+ data = row.xpath('td').collect{|c| c.content}
36
+ next unless data.length == 14
37
+ inst = data.shift.downcase.to_sym
38
+ data.each_with_index do |code, i|
39
+ next unless m = code.match(/(\d)(\+)?(\*)?/)
40
+ cycles = m[1].to_i
41
+ boundary = m[2] ? true : false
42
+ branch = m[3] ? true : false
43
+ mode = MODES[i].to_sym
44
+ #puts "#{inst} #{mode} #{cycles} #{boundary} #{branch}"
45
+ opcodes[inst][mode] ||= Hash.new
46
+ opcodes[inst][mode][:cycles] = cycles
47
+ opcodes[inst][mode][:page] = true if boundary
48
+ opcodes[inst][mode][:branch] = true if branch
49
+ end
50
+ end
51
+
52
+ puts 'OPCODES = '
53
+ pp(opcodes, width = 120)
54
+
55
+ petscii = Hash.new
56
+ page = Nokogiri::HTML.parse(open('http://www.andrijar.com/tables/petsci.htm'))
57
+ page.xpath('//tr').each do |row|
58
+ data = row.xpath('td').collect{|c| c.content}
59
+ 0.step(11, 3).each do |i|
60
+ byte = data[i].to_i
61
+ symbol = data[i+2]
62
+ next if (symbol == 'NOC' or symbol == '')
63
+ point = symbol.unpack('U*').first
64
+ petscii[point] = byte
65
+ end
66
+ end
67
+
68
+ puts 'PETSCII = '
69
+ pp(petscii, width = 120)
70
+
71
+ # for basic tokens
72
+ #tokens = {}
73
+ #STDIN.each_line do |l|
74
+ # code, *rest = l.split(' ')
75
+ # byte = code.split('/').first
76
+ # name = rest.first.split(' ').first
77
+ # tokens[name] = byte.to_i
78
+ #end
79
+ #
80
+ #pp(tokens, width=120)
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: c64asm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.1
5
+ platform: ruby
6
+ authors:
7
+ - Piotr S. Staszewski
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-04 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Already two-year-old project inspirated by the NES assembler written
14
+ in Lisp. The assembly DSL lets you easily unroll loops, create screen maps on the
15
+ fly and just hack the thing. As you write a plain .prg file you may also dump the
16
+ code to a very verbose format to ponder the machine code.
17
+ email: p.staszewski@gmail.com
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - ".gitignore"
23
+ - ".yardopts"
24
+ - LICENSE.txt
25
+ - README.md
26
+ - Rakefile
27
+ - c64asm.gemspec
28
+ - examples/04.png
29
+ - examples/04.prg
30
+ - examples/hello_world.png
31
+ - examples/hello_world.rb
32
+ - lib/c64asm.rb
33
+ - lib/c64asm/asm.rb
34
+ - lib/c64asm/basic.rb
35
+ - lib/c64asm/data.rb
36
+ - lib/c64asm/version.rb
37
+ - tools/make-data.rb
38
+ homepage: https://github.com/drbig/c64asm
39
+ licenses:
40
+ - BSD
41
+ metadata: {}
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 1.8.7
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements: []
57
+ rubyforge_project:
58
+ rubygems_version: 2.2.2
59
+ signing_key:
60
+ specification_version: 4
61
+ summary: Data-driven verbose DSL (almost dis-)assembler for MOS6502 with focus on
62
+ Commoder 64
63
+ test_files: []
64
+ has_rdoc: