diff --git a/README b/README
index ae7d12e..d6c19e5 100644
--- a/README
+++ b/README
@@ -28,4 +28,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
\ No newline at end of file
+THE SOFTWARE.
diff --git a/doc/c64-1.oph b/doc/c64-1.oph
index 04166dd..0a30520 100644
--- a/doc/c64-1.oph
+++ b/doc/c64-1.oph
@@ -9,4 +9,4 @@ _next: .word 0 ; End of program
.advance 2064
-.require "kernal.oph"
\ No newline at end of file
+.require "kernal.oph"
diff --git a/doc/c64-2.oph b/doc/c64-2.oph
index 720ef21..e694c12 100644
--- a/doc/c64-2.oph
+++ b/doc/c64-2.oph
@@ -37,4 +37,4 @@ _next: .word 0 ; End of program
_main:
; Program follows...
-.scend
\ No newline at end of file
+.scend
diff --git a/doc/docbook/cmdref.sgm b/doc/docbook/cmdref.sgm
index 6dbfb30..e7b4a5a 100644
--- a/doc/docbook/cmdref.sgm
+++ b/doc/docbook/cmdref.sgm
@@ -249,7 +249,7 @@
.checkpc $100
-
+
Macros
@@ -400,7 +400,7 @@
code in and of itself, nor does it overwrite anything that
previously existed. If you wish to jump ahead in memory,
use .advance.
- .require filename: Includes the entirety
+ .require filename: Includes the entirety
of the file specified at that point in the program. Unlike .include,
however, code included with .require will only be inserted once.
The .require directive is useful for ensuring that certain code libraries
@@ -447,5 +447,5 @@
macro definition intends to read. A shorthand for .invoke
is the name of the macro to invoke, backquoted.
-
+
diff --git a/doc/docbook/samplecode.sgm b/doc/docbook/samplecode.sgm
index 6d65b07..24d2344 100644
--- a/doc/docbook/samplecode.sgm
+++ b/doc/docbook/samplecode.sgm
@@ -333,7 +333,7 @@ delay: tax
iny
bne -
dex
- bne -
+ bne -
rts
diff --git a/doc/docbook/tutor1.sgm b/doc/docbook/tutor1.sgm
index 6a754b9..861d1a3 100644
--- a/doc/docbook/tutor1.sgm
+++ b/doc/docbook/tutor1.sgm
@@ -153,19 +153,19 @@ next: .word 0 ; End of program
Labels are defined by putting their name, then a colon, as
seen in the definition of next.
-
+
Instead of putting in the hex codes for the string part of
the BASIC code, we included the string directly. Each
character in the string becomes one byte.
-
+
Instead of adding the buffer ourselves, we
used .advance, which outputs zeros until
the specified address is reached. Attempting
to .advance backwards produces an
assemble-time error.
-
+
It has comments that explain what the data are for. The
semicolon is the comment marker; everything from a semicolon
to the end of the line is ignored.
@@ -263,9 +263,9 @@ hello: .byte "HELLO, WORLD!", 0
Option
Effect
-
+
-
+
Allows the 6510 undocumented opcodes as listed in the VICE documentation.
Allows opcodes and addressing modes added by the 65C02.
Quiet operation. Only reports errors.
diff --git a/doc/kernal.oph b/doc/kernal.oph
index ea13fad..ec777a8 100644
--- a/doc/kernal.oph
+++ b/doc/kernal.oph
@@ -64,4 +64,4 @@
; ...and character set
.alias upper'case 142
-.alias lower'case 14
\ No newline at end of file
+.alias lower'case 14
diff --git a/doc/tutor1.oph b/doc/tutor1.oph
index 6789ce7..e5b6a9d 100644
--- a/doc/tutor1.oph
+++ b/doc/tutor1.oph
@@ -15,4 +15,4 @@ loop: lda hello, x
bne loop
done: rts
-hello: .byte "HELLO, WORLD!", 0
\ No newline at end of file
+hello: .byte "HELLO, WORLD!", 0
diff --git a/doc/tutor2.oph b/doc/tutor2.oph
index 27c6682..7a4f436 100644
--- a/doc/tutor2.oph
+++ b/doc/tutor2.oph
@@ -19,4 +19,4 @@ _next: .word 0 ; End of program
bne -
* rts
-hello: .byte "HELLO, WORLD!", 0
\ No newline at end of file
+hello: .byte "HELLO, WORLD!", 0
diff --git a/doc/tutor3.oph b/doc/tutor3.oph
index 112e2bf..ead6014 100644
--- a/doc/tutor3.oph
+++ b/doc/tutor3.oph
@@ -42,4 +42,4 @@ target6: .byte "NATION", 0
target7: .byte "WORLD", 0
target8: .byte "SOLAR SYSTEM", 0
target9: .byte "GALAXY", 0
-target10: .byte "UNIVERSE", 0
\ No newline at end of file
+target10: .byte "UNIVERSE", 0
diff --git a/doc/tutor4a.oph b/doc/tutor4a.oph
index d218a5f..906cfe6 100644
--- a/doc/tutor4a.oph
+++ b/doc/tutor4a.oph
@@ -63,7 +63,7 @@ delay: tax
bne -
dex
bne -
-
-
+
+
rts
diff --git a/doc/tutor4b.oph b/doc/tutor4b.oph
index 3926965..ab93ead 100644
--- a/doc/tutor4b.oph
+++ b/doc/tutor4b.oph
@@ -65,7 +65,7 @@ delay: tax
bne -
dex
bne -
-
-
+
+
rts
diff --git a/doc/tutor4c.oph b/doc/tutor4c.oph
index f05d023..a84d04a 100644
--- a/doc/tutor4c.oph
+++ b/doc/tutor4c.oph
@@ -68,6 +68,6 @@ delay: tax
bne -
dex
bne -
-
-
- rts
\ No newline at end of file
+
+
+ rts
diff --git a/doc/tutor5.oph b/doc/tutor5.oph
index 8caf839..6e21c57 100644
--- a/doc/tutor5.oph
+++ b/doc/tutor5.oph
@@ -72,4 +72,4 @@ delay: sta _tmp ; save argument (rdtim destroys it)
.checkpc $A000
.data
-.checkpc $D000
\ No newline at end of file
+.checkpc $D000
diff --git a/doc/tutor6.oph b/doc/tutor6.oph
index 60ad8e9..eea3a3c 100644
--- a/doc/tutor6.oph
+++ b/doc/tutor6.oph
@@ -99,4 +99,4 @@ _done: rts
.checkpc $A000
.data
-.checkpc $D000
\ No newline at end of file
+.checkpc $D000
diff --git a/doc/tutor7.oph b/doc/tutor7.oph
index 88ba5bf..f01506a 100644
--- a/doc/tutor7.oph
+++ b/doc/tutor7.oph
@@ -93,4 +93,4 @@ _done: rts
.checkpc $D000
.data zp
-.checkpc $80
\ No newline at end of file
+.checkpc $80
diff --git a/src/Ophis/CmdLine.py b/src/Ophis/CmdLine.py
index aa73170..6beb174 100644
--- a/src/Ophis/CmdLine.py
+++ b/src/Ophis/CmdLine.py
@@ -6,44 +6,59 @@ import optparse
# You may use, modify, and distribute this file under the MIT
# license: See README for details.
-enable_collapse = True
-enable_branch_extend = True
-enable_undoc_ops = False
-enable_65c02_exts = False
+enable_collapse = True
+enable_branch_extend = True
+enable_undoc_ops = False
+enable_65c02_exts = False
warn_on_branch_extend = True
-print_summary = True
-print_loaded_files = False
-print_pass = False
-print_ir = False
-print_labels = False
+print_summary = True
+print_loaded_files = False
+print_pass = False
+print_ir = False
+print_labels = False
+
+infile = None
+outfile = None
-infile = None
-outfile = None
def parse_args(raw_args):
"Populate the module's globals based on the command-line options given."
- global enable_collapse, enable_branch_extend, enable_undoc_ops, enable_65c02_exts
+ global enable_collapse, enable_branch_extend
+ global enable_undoc_ops, enable_65c02_exts
global warn_on_branch_extend
- global print_summary, print_loaded_files, print_pass, print_ir, print_labels
+ global print_summary, print_loaded_files
+ global print_pass, print_ir, print_labels
global infile, outfile
- parser = optparse.OptionParser(usage= "Usage: %prog [options] srcfile outfile", version="Ophis 6502 cross-assembler, version 2.0")
+ parser = optparse.OptionParser(
+ usage="Usage: %prog [options] srcfile outfile",
+ version="Ophis 6502 cross-assembler, version 2.0")
ingrp = optparse.OptionGroup(parser, "Input options")
- ingrp.add_option("-u", "--undoc", action="store_true", default=False, help="Enable 6502 undocumented opcodes")
- ingrp.add_option("-c", "--65c02", action="store_true", default=False, dest="c02", help="Enable 65c02 extended instruction set")
+ ingrp.add_option("-u", "--undoc", action="store_true", default=False,
+ help="Enable 6502 undocumented opcodes")
+ ingrp.add_option("-c", "--65c02", action="store_true", default=False,
+ dest="c02", help="Enable 65c02 extended instruction set")
outgrp = optparse.OptionGroup(parser, "Console output options")
- outgrp.add_option("-v", "--verbose", action="store_const", const=2, help="Verbose mode", default=1)
- outgrp.add_option("-q", "--quiet", action="store_const", help="Quiet mode", dest="verbose", const=0)
- outgrp.add_option("-d", "--debug", action="count", dest="verbose", help=optparse.SUPPRESS_HELP)
- outgrp.add_option("--no-warn", action="store_false", dest="warn", default=True, help="Do not print warnings")
+ outgrp.add_option("-v", "--verbose", action="store_const", const=2,
+ help="Verbose mode", default=1)
+ outgrp.add_option("-q", "--quiet", action="store_const", help="Quiet mode",
+ dest="verbose", const=0)
+ outgrp.add_option("-d", "--debug", action="count", dest="verbose",
+ help=optparse.SUPPRESS_HELP)
+ outgrp.add_option("--no-warn", action="store_false", dest="warn",
+ default=True, help="Do not print warnings")
- bingrp = optparse.OptionGroup(parser, "Binary output options")
- bingrp.add_option("--no-collapse", action="store_false", dest="enable_collapse", default="True", help="Disable zero-page collapse pass")
- bingrp.add_option("--no-branch-extend", action="store_false", dest="enable_branch_extend", default="True", help="Disable branch-extension pass")
+ bingrp = optparse.OptionGroup(parser, "Compilation options")
+ bingrp.add_option("--no-collapse", action="store_false",
+ dest="enable_collapse", default="True",
+ help="Disable zero-page collapse pass")
+ bingrp.add_option("--no-branch-extend", action="store_false",
+ dest="enable_branch_extend", default="True",
+ help="Disable branch-extension pass")
parser.add_option_group(ingrp)
parser.add_option_group(outgrp)
@@ -60,15 +75,15 @@ def parse_args(raw_args):
if options.c02 and options.undoc:
parser.error("--undoc and --65c02 are mutually exclusive")
- infile = args[0]
- outfile = args[1]
- enable_collapse = options.enable_collapse
- enable_branch_extend = options.enable_branch_extend
- enable_undoc_ops = options.undoc
- enable_65c02_exts = options.c02
+ infile = args[0]
+ outfile = args[1]
+ enable_collapse = options.enable_collapse
+ enable_branch_extend = options.enable_branch_extend
+ enable_undoc_ops = options.undoc
+ enable_65c02_exts = options.c02
warn_on_branch_extend = options.warn
- print_summary = options.verbose > 0 # no options set
- print_loaded_files = options.verbose > 1 # v
- print_pass = options.verbose > 2 # dd
- print_ir = options.verbose > 3 # ddd
- print_labels = options.verbose > 4 # dddd
+ print_summary = options.verbose > 0 # no options set
+ print_loaded_files = options.verbose > 1 # v
+ print_pass = options.verbose > 2 # dd
+ print_ir = options.verbose > 3 # ddd
+ print_labels = options.verbose > 4 # dddd
diff --git a/src/Ophis/CorePragmas.py b/src/Ophis/CorePragmas.py
index 176222c..7087785 100644
--- a/src/Ophis/CorePragmas.py
+++ b/src/Ophis/CorePragmas.py
@@ -10,46 +10,52 @@ import Ophis.IR as IR
import Ophis.Frontend as FE
import Ophis.Errors as Err
-loadedfiles={}
+loadedfiles = {}
basecharmap = "".join([chr(x) for x in range(256)])
currentcharmap = basecharmap
+
def reset():
global loadedfiles, currentcharmap, basecharmap
- loadedfiles={}
+ loadedfiles = {}
currentcharmap = basecharmap
+
def pragmaInclude(ppt, line, result):
"Includes a source file"
filename = line.expect("STRING").value
line.expect("EOL")
- if type(filename)==str: result.append(FE.parse_file(ppt, filename))
+ if type(filename) == str:
+ result.append(FE.parse_file(ppt, filename))
+
def pragmaRequire(ppt, line, result):
"Includes a source file at most one time"
filename = line.expect("STRING").value
line.expect("EOL")
- if type(filename)==str:
+ if type(filename) == str:
global loadedfiles
if filename not in loadedfiles:
- loadedfiles[filename]=1
+ loadedfiles[filename] = True
result.append(FE.parse_file(ppt, filename))
+
def pragmaIncbin(ppt, line, result):
"Includes a binary file"
filename = line.expect("STRING").value
line.expect("EOL")
- if type(filename)==str:
+ if type(filename) == str:
try:
f = file(filename, "rb")
bytes = f.read()
f.close()
except IOError:
- Err.log ("Could not read "+filename)
+ Err.log("Could not read " + filename)
return
bytes = [IR.ConstantExpr(ord(x)) for x in bytes]
result.append(IR.Node(ppt, "Byte", *bytes))
+
def pragmaCharmap(ppt, line, result):
"Modify the character map."
global currentcharmap, basecharmap
@@ -60,30 +66,33 @@ def pragmaCharmap(ppt, line, result):
try:
base = bytes[0].data
newsubstr = "".join([chr(x.data) for x in bytes[1:]])
- currentcharmap = currentcharmap[:base] + newsubstr + currentcharmap[base+len(newsubstr):]
+ currentcharmap = currentcharmap[:base] + newsubstr + \
+ currentcharmap[base + len(newsubstr):]
if len(currentcharmap) != 256 or base < 0 or base > 255:
Err.log("Charmap replacement out of range")
currentcharmap = currentcharmap[:256]
except ValueError:
Err.log("Illegal character in .charmap directive")
+
def pragmaCharmapbin(ppt, line, result):
"Load a new character map from a file"
global currentcharmap
filename = line.expect("STRING").value
line.expect("EOL")
- if type(filename)==str:
+ if type(filename) == str:
try:
f = file(filename, "rb")
bytes = f.read()
f.close()
except IOError:
- Err.log ("Could not read "+filename)
+ Err.log("Could not read " + filename)
return
- if len(bytes)==256:
+ if len(bytes) == 256:
currentcharmap = bytes
else:
- Err.log("Character map "+filename+" not 256 bytes long")
+ Err.log("Character map " + filename + " not 256 bytes long")
+
def pragmaOrg(ppt, line, result):
"Relocates the PC with no output"
@@ -91,6 +100,7 @@ def pragmaOrg(ppt, line, result):
line.expect("EOL")
result.append(IR.Node(ppt, "SetPC", newPC))
+
def pragmaAdvance(ppt, line, result):
"Outputs filler until reaching the target PC"
newPC = FE.parse_expr(line)
@@ -102,25 +112,31 @@ def pragmaAdvance(ppt, line, result):
line.expect("EOL")
result.append(IR.Node(ppt, "Advance", newPC, fillexpr))
+
def pragmaCheckpc(ppt, line, result):
"Enforces that the PC has not exceeded a certain point"
target = FE.parse_expr(line)
line.expect("EOL")
result.append(IR.Node(ppt, "CheckPC", target))
+
def pragmaAlias(ppt, line, result):
"Assigns an arbitrary label"
lbl = line.expect("LABEL").value
target = FE.parse_expr(line)
result.append(IR.Node(ppt, "Label", lbl, target))
+
def pragmaSpace(ppt, line, result):
"Reserves space in a data segment for a variable"
lbl = line.expect("LABEL").value
size = line.expect("NUM").value
line.expect("EOL")
result.append(IR.Node(ppt, "Label", lbl, IR.PCExpr()))
- result.append(IR.Node(ppt, "SetPC", IR.SequenceExpr([IR.PCExpr(), "+", IR.ConstantExpr(size)])))
+ result.append(IR.Node(ppt, "SetPC",
+ IR.SequenceExpr([IR.PCExpr(), "+",
+ IR.ConstantExpr(size)])))
+
def pragmaText(ppt, line, result):
"Switches to a text segment"
@@ -132,6 +148,7 @@ def pragmaText(ppt, line, result):
segment = "*text-default*"
result.append(IR.Node(ppt, "TextSegment", segment))
+
def pragmaData(ppt, line, result):
"Switches to a data segment (no output allowed)"
next = line.expect("LABEL", "EOL")
@@ -142,67 +159,80 @@ def pragmaData(ppt, line, result):
segment = "*data-default*"
result.append(IR.Node(ppt, "DataSegment", segment))
+
def readData(line):
"Read raw data from a comma-separated list"
if line.lookahead(0).type == "STRING":
- data = [IR.ConstantExpr(ord(x)) for x in line.expect("STRING").value.translate(currentcharmap)]
+ data = [IR.ConstantExpr(ord(x))
+ for x in line.expect("STRING").value.translate(currentcharmap)]
else:
data = [FE.parse_expr(line)]
next = line.expect(',', 'EOL').type
while next == ',':
if line.lookahead(0).type == "STRING":
- data.extend([IR.ConstantExpr(ord(x)) for x in line.expect("STRING").value])
+ data.extend([IR.ConstantExpr(ord(x))
+ for x in line.expect("STRING").value])
else:
data.append(FE.parse_expr(line))
next = line.expect(',', 'EOL').type
return data
+
def pragmaByte(ppt, line, result):
"Raw data, a byte at a time"
bytes = readData(line)
result.append(IR.Node(ppt, "Byte", *bytes))
+
def pragmaWord(ppt, line, result):
"Raw data, a word at a time, little-endian"
words = readData(line)
result.append(IR.Node(ppt, "Word", *words))
+
def pragmaDword(ppt, line, result):
"Raw data, a double-word at a time, little-endian"
dwords = readData(line)
result.append(IR.Node(ppt, "Dword", *dwords))
+
def pragmaWordbe(ppt, line, result):
"Raw data, a word at a time, big-endian"
words = readData(line)
result.append(IR.Node(ppt, "WordBE", *words))
+
def pragmaDwordbe(ppt, line, result):
"Raw data, a dword at a time, big-endian"
dwords = readData(line)
result.append(IR.Node(ppt, "DwordBE", *dwords))
+
def pragmaScope(ppt, line, result):
"Create a new lexical scoping block"
line.expect("EOL")
result.append(IR.Node(ppt, "ScopeBegin"))
+
def pragmaScend(ppt, line, result):
"End the innermost lexical scoping block"
line.expect("EOL")
result.append(IR.Node(ppt, "ScopeEnd"))
+
def pragmaMacro(ppt, line, result):
"Begin a macro definition"
lbl = line.expect("LABEL").value
line.expect("EOL")
result.append(IR.Node(ppt, "MacroBegin", lbl))
+
def pragmaMacend(ppt, line, result):
"End a macro definition"
line.expect("EOL")
result.append(IR.Node(ppt, "MacroEnd"))
+
def pragmaInvoke(ppt, line, result):
macro = line.expect("LABEL").value
if line.lookahead(0).type == "EOL":
diff --git a/src/Ophis/Environment.py b/src/Ophis/Environment.py
index 0450262..ec4e201 100644
--- a/src/Ophis/Environment.py
+++ b/src/Ophis/Environment.py
@@ -9,6 +9,7 @@
import Ophis.Errors as Err
+
class Environment(object):
"""Environment class.
Controls the various scopes and global abstract execution variables."""
@@ -19,39 +20,52 @@ class Environment(object):
self.segmentdict = {}
self.segment = "*text-default*"
self.scopecount = 0
+
def __contains__(self, item):
if item[0] == '_':
for dict in [self.dicts[i] for i in self.stack]:
- if item in dict: return 1
- return 0
+ if item in dict:
+ return True
+ return False
return item in self.dicts[0]
+
def __getitem__(self, item):
if item[0] == '_':
for dict in [self.dicts[i] for i in self.stack]:
- if item in dict: return dict[item]
+ if item in dict:
+ return dict[item]
else:
- if item in self.dicts[0]: return self.dicts[0][item]
+ if item in self.dicts[0]:
+ return self.dicts[0][item]
Err.log("Unknown label '%s'" % item)
return 0
+
def __setitem__(self, item, value):
if item[0] == '_':
self.dicts[self.stack[0]][item] = value
else:
self.dicts[0][item] = value
+
def __str__(self):
return str(self.dicts)
+
def getPC(self):
return self.pc
+
def setPC(self, value):
self.pc = value
+
def incPC(self, amount):
self.pc += amount
+
def getsegment(self):
return self.segment
+
def setsegment(self, segment):
self.segmentdict[self.segment] = self.pc
self.segment = segment
self.pc = self.segmentdict.get(segment, 0)
+
def reset(self):
"Clears out program counter, segment, and scoping information"
self.pc = 0
@@ -61,14 +75,16 @@ class Environment(object):
if len(self.stack) > 1:
Err.log("Unmatched .scope")
self.stack = [0]
+
def newscope(self):
"Enters a new scope for temporary labels."
self.scopecount += 1
self.stack.insert(0, self.scopecount)
- if len(self.dicts) <= self.scopecount: self.dicts.append({})
+ if len(self.dicts) <= self.scopecount:
+ self.dicts.append({})
+
def endscope(self):
"Leaves a scope."
if len(self.stack) == 1:
Err.log("Unmatched .scend")
self.stack.pop(0)
-
diff --git a/src/Ophis/Errors.py b/src/Ophis/Errors.py
index bdc9d65..88f37e0 100644
--- a/src/Ophis/Errors.py
+++ b/src/Ophis/Errors.py
@@ -12,15 +12,20 @@ import sys
count = 0
currentpoint = ""
+
def log(err):
"""Reports an error at the current program point, and increases
the global error count."""
global count
- count = count+1
- print>>sys.stderr, currentpoint+": "+err
+ count = count + 1
+ print>>sys.stderr, currentpoint + ": " + err
+
def report():
"Print out the number of errors."
- if count == 0: print>>sys.stderr, "No errors"
- elif count == 1: print>>sys.stderr, "1 error"
- else: print>>sys.stderr, str(count)+" errors"
+ if count == 0:
+ print>>sys.stderr, "No errors"
+ elif count == 1:
+ print>>sys.stderr, "1 error"
+ else:
+ print>>sys.stderr, str(count) + " errors"
diff --git a/src/Ophis/Frontend.py b/src/Ophis/Frontend.py
index 38c03a9..f8176ce 100644
--- a/src/Ophis/Frontend.py
+++ b/src/Ophis/Frontend.py
@@ -13,35 +13,44 @@ import os
# You may use, modify, and distribute this file under the MIT
# license: See README for details.
+
class Lexeme(object):
"Class for lexer tokens. Used by lexer and parser."
def __init__(self, type="UNKNOWN", value=None):
self.type = type.upper()
self.value = value
+
def __str__(self):
- if self.value == None:
+ if self.value is None:
return self.type
else:
- return self.type+":"+str(self.value)
+ return self.type + ":" + str(self.value)
+
def __repr__(self):
- return "Lexeme("+`self.type`+", "+`self.value`+")"
+ return "Lexeme(" + repr(self.type) + ", " + repr(self.value) + ")"
+
def matches(self, other):
"1 if Lexemes a and b have the same type."
return self.type == other.type
-bases = {"$":("hexadecimal", 16),
- "%":("binary", 2),
- "0":("octal", 8)}
+
+bases = {"$": ("hexadecimal", 16),
+ "%": ("binary", 2),
+ "0": ("octal", 8)}
+
punctuation = "#,`<>():.+-*/&|^[]"
+
def lex(point, line):
"""Turns a line of source into a sequence of lexemes."""
Err.currentpoint = point
result = []
+
def is_opcode(op):
"Tests whether a string is an opcode or an identifier"
return op in Ops.opcodes
+
def add_token(token):
"Converts a substring into a single lexeme"
if token == "":
@@ -59,7 +68,8 @@ def lex(point, line):
result.append(Lexeme("NUM", long(rest, bases[firstchar][1])))
return
except ValueError:
- Err.log('Invalid '+bases[firstchar][0]+' constant: '+rest)
+ Err.log('Invalid ' + bases[firstchar][0] + ' constant: ' +
+ rest)
result.append(Lexeme("NUM", 0))
return
elif firstchar.isdigit():
@@ -73,12 +83,12 @@ def lex(point, line):
if len(rest) == 1:
result.append(Lexeme("NUM", ord(rest)))
else:
- Err.log("Invalid character constant '"+rest+"'")
+ Err.log("Invalid character constant '" + rest + "'")
result.append(Lexeme("NUM", 0))
return
elif firstchar in punctuation:
if rest != "":
- Err.log("Internal lexer error! '"+token+"' can't happen!")
+ Err.log("Internal lexer error! '" + token + "' can't happen!")
result.append(Lexeme(firstchar))
return
else: # Label, opcode, or index register
@@ -94,22 +104,24 @@ def lex(point, line):
return
# should never reach here
Err.log("Internal lexer error: add_token fall-through")
+
def add_EOL():
"Adds an end-of-line lexeme"
result.append(Lexeme("EOL"))
+
# Actual routine begins here
value = ""
- quotemode = 0
- backslashmode = 0
+ quotemode = False
+ backslashmode = False
for c in line.strip():
if backslashmode:
- backslashmode = 0
+ backslashmode = False
value = value + c
elif c == "\\":
- backslashmode = 1
+ backslashmode = True
elif quotemode:
if c == '"':
- quotemode = 0
+ quotemode = False
else:
value = value + c
elif c == ';':
@@ -126,7 +138,7 @@ def lex(point, line):
elif c == '"':
add_token(value)
value = '"'
- quotemode = 1
+ quotemode = True
else:
value = value + c
if backslashmode:
@@ -137,35 +149,45 @@ def lex(point, line):
add_EOL()
return result
+
class ParseLine(object):
- "Maintains the parse state of a line of code. Enables arbitrary lookahead."
+ "Maintains the parse state of a line of code. Enables arbitrary lookahead."
+
def __init__(self, lexemes):
self.lexemes = lexemes
self.location = 0
+
def lookahead(self, i):
- """Returns the token i units ahead in the parse.
- lookahead(0) returns the next token; trying to read off the end of
+ """Returns the token i units ahead in the parse.
+ lookahead(0) returns the next token; trying to read off the end of
the sequence returns the last token in the sequence (usually EOL)."""
- target = self.location+i
- if target >= len(self.lexemes): target = -1
+ target = self.location + i
+ if target >= len(self.lexemes):
+ target = -1
return self.lexemes[target]
+
def pop(self):
"Returns and removes the next element in the line."
old = self.location
- if self.location < len(self.lexemes)-1: self.location += 1
+ if self.location < len(self.lexemes) - 1:
+ self.location += 1
return self.lexemes[old]
+
def expect(self, *tokens):
- """Reads a token from the ParseLine line and returns it if it's of a type
- in the sequence tokens. Otherwise, it logs an error."""
+ """Reads a token from the ParseLine line and returns it if it's of a
+ type in the sequence tokens. Otherwise, it logs an error."""
token = self.pop()
- if token.type not in tokens:
- Err.log('Expected: "'+'", "'.join(tokens)+'"')
+ if token.type not in tokens:
+ Err.log('Expected: "' + '", "'.join(tokens) + '"')
return token
+
pragma_modules = []
+
def parse_expr(line):
"Parses an Ophis arithmetic expression."
+
def atom():
"Parses lowest-priority expression components."
next = line.lookahead(0).type
@@ -187,14 +209,14 @@ def parse_expr(line):
offset += 1
line.expect("+")
next = line.lookahead(0).type
- return IR.LabelExpr("*"+str(templabelcount+offset))
+ return IR.LabelExpr("*" + str(templabelcount + offset))
elif next == "-":
offset = 1
while next == "-":
offset -= 1
line.expect("-")
next = line.lookahead(0).type
- return IR.LabelExpr("*"+str(templabelcount+offset))
+ return IR.LabelExpr("*" + str(templabelcount + offset))
elif next == ">":
line.expect(">")
return IR.HighByteExpr(atom())
@@ -203,6 +225,7 @@ def parse_expr(line):
return IR.LowByteExpr(atom())
else:
Err.log('Expected: expression')
+
def precedence_read(constructor, reader, separators):
"""Handles precedence. The reader argument is a function that returns
expressions that bind more tightly than these; separators is a list
@@ -218,51 +241,60 @@ def parse_expr(line):
result.append(nextop)
result.append(reader())
nextop = line.lookahead(0).type
- if len(result) == 1: return result[0]
+ if len(result) == 1:
+ return result[0]
return constructor(result)
+
def term():
"Parses * and /"
return precedence_read(IR.SequenceExpr, atom, ["*", "/"])
+
def arith():
"Parses + and -"
return precedence_read(IR.SequenceExpr, term, ["+", "-"])
+
def bits():
"Parses &, |, and ^"
return precedence_read(IR.SequenceExpr, arith, ["&", "|", "^"])
+
return bits()
+
def parse_line(ppt, lexemelist):
"Turn a line of source into an IR Node."
Err.currentpoint = ppt
result = []
line = ParseLine(lexemelist)
+
def aux():
"Accumulates all IR nodes defined by this line."
if line.lookahead(0).type == "EOL":
pass
elif line.lookahead(1).type == ":":
- newlabel=line.expect("LABEL").value
+ newlabel = line.expect("LABEL").value
line.expect(":")
result.append(IR.Node(ppt, "Label", newlabel, IR.PCExpr()))
aux()
elif line.lookahead(0).type == "*":
global templabelcount
templabelcount = templabelcount + 1
- result.append(IR.Node(ppt, "Label", "*"+str(templabelcount), IR.PCExpr()))
+ result.append(IR.Node(ppt, "Label", "*" + str(templabelcount),
+ IR.PCExpr()))
line.expect("*")
aux()
elif line.lookahead(0).type == "." or line.lookahead(0).type == "`":
which = line.expect(".", "`").type
- if (which == "."): pragma = line.expect("LABEL").value
- else: pragma = "invoke"
- pragmaFunction = "pragma"+pragma.title()
+ if (which == "."):
+ pragma = line.expect("LABEL").value
+ else:
+ pragma = "invoke"
+ pragmaFunction = "pragma" + pragma.title()
for mod in pragma_modules:
if hasattr(mod, pragmaFunction):
getattr(mod, pragmaFunction)(ppt, line, result)
break
else:
- Err.log("Unknown pragma "+pragma)
-
+ Err.log("Unknown pragma " + pragma)
else: # Instruction
opcode = line.expect("OPCODE").value
if line.lookahead(0).type == "#":
@@ -296,23 +328,30 @@ def parse_line(ppt, lexemelist):
tok = line.expect("EOL", ",").type
if tok == ",":
tok = line.expect("X", "Y").type
- if tok == "X": mode = "MemoryX"
- else: mode = "MemoryY"
+ if tok == "X":
+ mode = "MemoryX"
+ else:
+ mode = "MemoryY"
line.expect("EOL")
- else: mode = "Memory"
+ else:
+ mode = "Memory"
result.append(IR.Node(ppt, mode, opcode, arg))
+
aux()
result = [node for node in result if node is not IR.NullNode]
- if len(result) == 0: return IR.NullNode
- if len(result) == 1: return result[0]
+ if len(result) == 0:
+ return IR.NullNode
+ if len(result) == 1:
+ return result[0]
return IR.SequenceNode(ppt, result)
+
def parse_file(ppt, filename):
"Loads an Ophis source file, and returns an IR list."
Err.currentpoint = ppt
if Cmd.print_loaded_files:
if filename != '-':
- print>>sys.stderr, "Loading "+filename
+ print>>sys.stderr, "Loading " + filename
else:
print>>sys.stderr, "Loading from standard input"
try:
@@ -322,18 +361,19 @@ def parse_file(ppt, filename):
f.close()
else:
linelist = sys.stdin.readlines()
- pptlist = ["%s:%d" % (filename, i+1) for i in range(len(linelist))]
+ pptlist = ["%s:%d" % (filename, i + 1) for i in range(len(linelist))]
lexlist = map(lex, pptlist, linelist)
IRlist = map(parse_line, pptlist, lexlist)
IRlist = [node for node in IRlist if node is not IR.NullNode]
return IR.SequenceNode(ppt, IRlist)
except IOError:
- Err.log ("Could not read "+filename)
+ Err.log("Could not read " + filename)
return IR.NullNode
+
def parse(filename):
- "Top level parsing routine, taking a source file name and returning an IR list."
+ """Top level parsing routine, taking a source file name
+ and returning an IR list."""
global templabelcount
templabelcount = 0
return parse_file("", filename)
-
diff --git a/src/Ophis/IR.py b/src/Ophis/IR.py
index 40fe818..2250541 100644
--- a/src/Ophis/IR.py
+++ b/src/Ophis/IR.py
@@ -9,6 +9,7 @@
import Ophis.Errors as Err
+
class Node(object):
"""The default IR Node
Instances of Node always have the three fields ppt(Program Point),
@@ -17,27 +18,35 @@ class Node(object):
self.ppt = ppt
self.nodetype = nodetype
self.data = list(data)
+
def accept(self, asmpass, env=None):
"""Implements the Visitor pattern for an assembler pass.
- Calls the routine 'asmpass.visitTYPE(self, env)' where
+ Calls the routine 'asmpass.visitTYPE(self, env)' where
TYPE is the value of self.nodetype."""
Err.currentpoint = self.ppt
- routine = getattr(asmpass, "visit"+self.nodetype, asmpass.visitUnknown)
+ routine = getattr(asmpass, "visit" + self.nodetype,
+ asmpass.visitUnknown)
routine(self, env)
+
def __str__(self):
if self.nodetype != "SEQUENCE":
- return str(self.ppt)+": "+self.nodetype+" - "+" ".join(map(str, self.data))
+ return str(self.ppt) + ": " + self.nodetype + " - " + \
+ " ".join(map(str, self.data))
else:
return "\n".join(map(str, self.data))
+
def __repr__(self):
args = [self.ppt, self.nodetype] + self.data
return "Node(" + ", ".join(map(repr, args)) + ")"
+
NullNode = Node("", "None")
+
def SequenceNode(ppt, nodelist):
return Node(ppt, "SEQUENCE", *nodelist)
+
class Expr(object):
"""Base class for Ophis expressions
All expressions have a field called "data" and a boolean field
@@ -45,78 +54,102 @@ class Expr(object):
symbolic values in it."""
def __init__(self, data):
self.data = data
- self.hardcoded = 0
+ self.hardcoded = False
+
def __str__(self):
- return ""
- def valid(self, env=None, PCvalid=0):
+ return ""
+
+ def valid(self, env=None, PCvalid=False):
"""Returns true if the the expression can be successfully
evaluated in the specified environment."""
- return 0
+ return False
+
def value(self, env=None):
"Evaluates this expression in the given environment."
return None
+
class ConstantExpr(Expr):
"Represents a numeric constant"
def __init__(self, data):
self.data = data
- self.hardcoded = 1
+ self.hardcoded = True
+
def __str__(self):
return str(self.data)
- def valid(self, env=None, PCvalid=0):
- return 1
+
+ def valid(self, env=None, PCvalid=False):
+ return True
+
def value(self, env=None):
return self.data
+
class LabelExpr(Expr):
"Represents a symbolic constant"
def __init__(self, data):
self.data = data
- self.hardcoded = 0
+ self.hardcoded = False
+
def __str__(self):
return self.data
- def valid(self, env=None, PCvalid=0):
+
+ def valid(self, env=None, PCvalid=False):
return (env is not None) and self.data in env
+
def value(self, env=None):
return env[self.data]
+
class PCExpr(Expr):
"Represents the current program counter: ^"
def __init__(self):
- self.hardcoded = 0
+ self.hardcoded = False
+
def __str__(self):
return "^"
- def valid(self, env=None, PCvalid=0):
+
+ def valid(self, env=None, PCvalid=False):
return env is not None and PCvalid
+
def value(self, env=None):
return env.getPC()
+
class HighByteExpr(Expr):
"Represents the expression >{data}"
def __init__(self, data):
self.data = data
self.hardcoded = data.hardcoded
+
def __str__(self):
- return ">"+str(self.data)
- def valid(self, env=None, PCvalid=0):
+ return ">" + str(self.data)
+
+ def valid(self, env=None, PCvalid=False):
return self.data.valid(env, PCvalid)
+
def value(self, env=None):
val = self.data.value(env)
return (val >> 8) & 0xff
-
+
+
class LowByteExpr(Expr):
"Represents the expression <{data}"
def __init__(self, data):
self.data = data
self.hardcoded = data.hardcoded
+
def __str__(self):
- return "<"+str(self.data)
- def valid(self, env=None, PCvalid=0):
+ return "<" + str(self.data)
+
+ def valid(self, env=None, PCvalid=False):
return self.data.valid(env, PCvalid)
+
def value(self, env=None):
val = self.data.value(env)
return val & 0xff
+
class SequenceExpr(Expr):
"""Represents an interleaving of operands (of type Expr) and
operators (of type String). Subclasses must provide a routine
@@ -128,20 +161,23 @@ class SequenceExpr(Expr):
[Expr, str, Expr, str, Expr, str, ... Expr, str, Expr]."""
self.data = data
self.operands = [x for x in data if isinstance(x, Expr)]
- self.operators = [x for x in data if type(x)==str]
+ self.operators = [x for x in data if type(x) == str]
for i in self.operands:
if not i.hardcoded:
- self.hardcoded = 0
+ self.hardcoded = False
break
else:
- self.hardcoded = 1
+ self.hardcoded = True
+
def __str__(self):
- return "["+" ".join(map(str, self.data))+"]"
- def valid(self, env=None, PCvalid=0):
+ return "[" + " ".join(map(str, self.data)) + "]"
+
+ def valid(self, env=None, PCvalid=False):
for i in self.operands:
if not i.valid(env, PCvalid):
- return 0
- return 1
+ return False
+ return True
+
def value(self, env=None):
subs = map((lambda x: x.value(env)), self.operands)
result = subs[0]
@@ -150,11 +186,19 @@ class SequenceExpr(Expr):
result = self.operate(result, op, subs[index])
index += 1
return result
+
def operate(self, start, op, other):
- if op=="*": return start * other
- if op=="/": return start // other
- if op=="+": return start + other
- if op=="-": return start - other
- if op=="&": return start & other
- if op=="|": return start | other
- if op=="^": return start ^ other
+ if op == "*":
+ return start * other
+ if op == "/":
+ return start // other
+ if op == "+":
+ return start + other
+ if op == "-":
+ return start - other
+ if op == "&":
+ return start & other
+ if op == "|":
+ return start | other
+ if op == "^":
+ return start ^ other
diff --git a/src/Ophis/Macro.py b/src/Ophis/Macro.py
index ee3a68f..65b0017 100644
--- a/src/Ophis/Macro.py
+++ b/src/Ophis/Macro.py
@@ -18,6 +18,7 @@ macros = {}
currentname = None
currentbody = None
+
def newMacro(name):
"Start creating a new macro with the specified name."
global currentname
@@ -31,10 +32,12 @@ def newMacro(name):
currentname = name
currentbody = []
+
def registerNode(node):
global currentbody
currentbody.append(IR.Node(node.ppt, node.nodetype, *node.data))
+
def endMacro():
global currentname
global currentbody
@@ -46,21 +49,29 @@ def endMacro():
currentname = None
currentbody = None
+
def expandMacro(ppt, name, arglist):
global macros
if name not in macros:
Err.log("Undefined macro '%s'" % name)
return IR.NullNode
- argexprs = [IR.Node(ppt, "Label", "_*%d" % i, arg) for (i, arg) in zip(xrange(1, sys.maxint), arglist)]
- bindexprs = [IR.Node(ppt, "Label", "_%d" % i, IR.LabelExpr("_*%d" % i)) for i in range(1, len(arglist)+1)]
- body = [IR.Node("%s->%s" % (ppt, node.ppt), node.nodetype, *node.data) for node in macros[name]]
- invocation = [IR.Node(ppt, "ScopeBegin")] + argexprs + [IR.Node(ppt, "ScopeBegin")] + bindexprs + body + [IR.Node(ppt, "ScopeEnd"), IR.Node(ppt, "ScopeEnd")]
+ argexprs = [IR.Node(ppt, "Label", "_*%d" % i, arg)
+ for (i, arg) in zip(xrange(1, sys.maxint), arglist)]
+ bindexprs = [IR.Node(ppt, "Label", "_%d" % i, IR.LabelExpr("_*%d" % i))
+ for i in range(1, len(arglist) + 1)]
+ body = [IR.Node("%s->%s" % (ppt, node.ppt), node.nodetype, *node.data)
+ for node in macros[name]]
+ invocation = [IR.Node(ppt, "ScopeBegin")] + argexprs + \
+ [IR.Node(ppt, "ScopeBegin")] + bindexprs + body + \
+ [IR.Node(ppt, "ScopeEnd"), IR.Node(ppt, "ScopeEnd")]
return IR.SequenceNode(ppt, invocation)
+
def dump():
global macros
for mac in macros:
body = macros[mac]
- print>>sys.stderr, "Macro: "+mac
- for node in body: print>>sys.stderr, node
+ print>>sys.stderr, "Macro: " + mac
+ for node in body:
+ print>>sys.stderr, node
print>>sys.stderr, ""
diff --git a/src/Ophis/Main.py b/src/Ophis/Main.py
index c439f32..f66bf08 100644
--- a/src/Ophis/Main.py
+++ b/src/Ophis/Main.py
@@ -17,6 +17,7 @@ import Ophis.Environment
import Ophis.CmdLine
import Ophis.Opcodes
+
def run_all(infile, outfile):
"Transforms the source infile to a binary outfile."
Err.count = 0
@@ -26,21 +27,31 @@ def run_all(infile, outfile):
m = Ophis.Passes.ExpandMacros()
i = Ophis.Passes.InitLabels()
l_basic = Ophis.Passes.UpdateLabels()
- l = Ophis.Passes.FixPoint("label update", [l_basic], lambda: l_basic.changed == 0)
+ l = Ophis.Passes.FixPoint("label update", [l_basic],
+ lambda: not l_basic.changed)
c_basic = Ophis.Passes.Collapse()
- c = Ophis.Passes.FixPoint("instruction selection 1", [l, c_basic], lambda: c_basic.collapsed == 0)
+ c = Ophis.Passes.FixPoint("instruction selection 1", [l, c_basic],
+ lambda: not c_basic.changed)
b = Ophis.Passes.ExtendBranches()
a = Ophis.Passes.Assembler()
passes = []
passes.append(Ophis.Passes.DefineMacros())
- passes.append(Ophis.Passes.FixPoint("macro expansion", [m], lambda: m.changed == 0))
- passes.append(Ophis.Passes.FixPoint("label initialization", [i], lambda: i.changed == 0))
- passes.extend([Ophis.Passes.CircularityCheck(), Ophis.Passes.CheckExprs(), Ophis.Passes.EasyModes()])
- passes.append(Ophis.Passes.FixPoint("instruction selection 2", [c, b], lambda: b.expanded == 0))
- passes.extend([Ophis.Passes.NormalizeModes(), Ophis.Passes.UpdateLabels(), a])
+ passes.append(Ophis.Passes.FixPoint("macro expansion", [m],
+ lambda: not m.changed))
+ passes.append(Ophis.Passes.FixPoint("label initialization", [i],
+ lambda: not i.changed))
+ passes.extend([Ophis.Passes.CircularityCheck(),
+ Ophis.Passes.CheckExprs(),
+ Ophis.Passes.EasyModes()])
+ passes.append(Ophis.Passes.FixPoint("instruction selection 2", [c, b],
+ lambda: not b.changed))
+ passes.extend([Ophis.Passes.NormalizeModes(),
+ Ophis.Passes.UpdateLabels(),
+ a])
- for p in passes: p.go(z, env)
+ for p in passes:
+ p.go(z, env)
if Err.count == 0:
try:
@@ -53,10 +64,11 @@ def run_all(infile, outfile):
if outfile != '-':
output.close()
except IOError:
- print>>sys.stderr, "Could not write to "+outfile
+ print>>sys.stderr, "Could not write to " + outfile
else:
Err.report()
+
def run_ophis(args):
Ophis.CmdLine.parse_args(args)
Ophis.Frontend.pragma_modules.append(Ophis.CorePragmas)
@@ -69,5 +81,6 @@ def run_ophis(args):
Ophis.CorePragmas.reset()
run_all(Ophis.CmdLine.infile, Ophis.CmdLine.outfile)
+
if __name__ == '__main__':
run_ophis(sys.argv[1:])
diff --git a/src/Ophis/Opcodes.py b/src/Ophis/Opcodes.py
index 4ff55af..0be2676 100644
--- a/src/Ophis/Opcodes.py
+++ b/src/Ophis/Opcodes.py
@@ -12,162 +12,291 @@
# the tables in tools/opcodes. Edit those tables, not these.
# Names of addressing modes
-modes = ["Implied", # 0
- "Immediate", # 1
- "Zero Page", # 2
- "Zero Page, X", # 3
- "Zero Page, Y", # 4
- "Absolute", # 5
- "Absolute, X", # 6
- "Absolute, Y", # 7
- "(Absolute)", # 8
- "(Absolute, X)", # 9
+modes = ["Implied", # 0
+ "Immediate", # 1
+ "Zero Page", # 2
+ "Zero Page, X", # 3
+ "Zero Page, Y", # 4
+ "Absolute", # 5
+ "Absolute, X", # 6
+ "Absolute, Y", # 7
+ "(Absolute)", # 8
+ "(Absolute, X)", # 9
"(Absolute), Y", # 10
"(Zero Page)", # 11
"(Zero Page, X)", # 12
"(Zero Page), Y", # 13
"Relative"] # 14
+
# Lengths of the argument
lengths = [0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1]
opcodes = {
- 'adc': [None, 0x69, 0x65, 0x75, None, 0x6D, 0x7D, 0x79, None, None, None, None, 0x61, 0x71, None],
- 'and': [None, 0x29, 0x25, 0x35, None, 0x2D, 0x3D, 0x39, None, None, None, None, 0x21, 0x31, None],
- 'asl': [0x0A, None, 0x06, 0x16, None, 0x0E, 0x1E, None, None, None, None, None, None, None, None],
- 'bcc': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0x90],
- 'bcs': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0xB0],
- 'beq': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0xF0],
- 'bit': [None, None, 0x24, None, None, 0x2C, None, None, None, None, None, None, None, None, None],
- 'bmi': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0x30],
- 'bne': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0xD0],
- 'bpl': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0x10],
- 'brk': [0x00, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'bvc': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0x50],
- 'bvs': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0x70],
- 'clc': [0x18, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'cld': [0xD8, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'cli': [0x58, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'clv': [0xB8, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'cmp': [None, 0xC9, 0xC5, 0xD5, None, 0xCD, 0xDD, 0xD9, None, None, None, None, 0xC1, 0xD1, None],
- 'cpx': [None, 0xE0, 0xE4, None, None, 0xEC, None, None, None, None, None, None, None, None, None],
- 'cpy': [None, 0xC0, 0xC4, None, None, 0xCC, None, None, None, None, None, None, None, None, None],
- 'dec': [None, None, 0xC6, 0xD6, None, 0xCE, 0xDE, None, None, None, None, None, None, None, None],
- 'dex': [0xCA, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'dey': [0x88, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'eor': [None, 0x49, 0x45, 0x55, None, 0x4D, 0x5D, 0x59, None, None, None, None, 0x41, 0x51, None],
- 'inc': [None, None, 0xE6, 0xF6, None, 0xEE, 0xFE, None, None, None, None, None, None, None, None],
- 'inx': [0xE8, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'iny': [0xC8, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'jmp': [None, None, None, None, None, 0x4C, None, None, 0x6C, None, None, None, None, None, None],
- 'jsr': [None, None, None, None, None, 0x20, None, None, None, None, None, None, None, None, None],
- 'lda': [None, 0xA9, 0xA5, 0xB5, None, 0xAD, 0xBD, 0xB9, None, None, None, None, 0xA1, 0xB1, None],
- 'ldx': [None, 0xA2, 0xA6, None, 0xB6, 0xAE, None, 0xBE, None, None, None, None, None, None, None],
- 'ldy': [None, 0xA0, 0xA4, 0xB4, None, 0xAC, 0xBC, None, None, None, None, None, None, None, None],
- 'lsr': [0x4A, None, 0x46, 0x56, None, 0x4E, 0x5E, None, None, None, None, None, None, None, None],
- 'nop': [0xEA, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'ora': [None, 0x09, 0x05, 0x15, None, 0x0D, 0x1D, 0x19, None, None, None, None, 0x01, 0x11, None],
- 'pha': [0x48, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'php': [0x08, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'pla': [0x68, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'plp': [0x28, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'rol': [0x2A, None, 0x26, 0x36, None, 0x2E, 0x3E, None, None, None, None, None, None, None, None],
- 'ror': [0x6A, None, 0x66, 0x76, None, 0x6E, 0x7E, None, None, None, None, None, None, None, None],
- 'rti': [0x40, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'rts': [0x60, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'sbc': [None, 0xE9, 0xE5, 0xF5, None, 0xED, 0xFD, 0xF9, None, None, None, None, 0xE1, 0xF1, None],
- 'sec': [0x38, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'sed': [0xF8, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'sei': [0x78, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'sta': [None, None, 0x85, 0x95, None, 0x8D, 0x9D, 0x99, None, None, None, None, 0x81, 0x91, None],
- 'stx': [None, None, 0x86, None, 0x96, 0x8E, None, None, None, None, None, None, None, None, None],
- 'sty': [None, None, 0x84, 0x94, None, 0x8C, None, None, None, None, None, None, None, None, None],
- 'tax': [0xAA, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'tay': [0xA8, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'tsx': [0xBA, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'txa': [0x8A, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'txs': [0x9A, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'tya': [0x98, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
+ 'adc': [None, 0x69, 0x65, 0x75, None, 0x6D, 0x7D, 0x79,
+ None, None, None, None, 0x61, 0x71, None],
+ 'and': [None, 0x29, 0x25, 0x35, None, 0x2D, 0x3D, 0x39,
+ None, None, None, None, 0x21, 0x31, None],
+ 'asl': [0x0A, None, 0x06, 0x16, None, 0x0E, 0x1E, None,
+ None, None, None, None, None, None, None],
+ 'bcc': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0x90],
+ 'bcs': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0xB0],
+ 'beq': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0xF0],
+ 'bit': [None, None, 0x24, None, None, 0x2C, None, None,
+ None, None, None, None, None, None, None],
+ 'bmi': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0x30],
+ 'bne': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0xD0],
+ 'bpl': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0x10],
+ 'brk': [0x00, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'bvc': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0x50],
+ 'bvs': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0x70],
+ 'clc': [0x18, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'cld': [0xD8, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'cli': [0x58, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'clv': [0xB8, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'cmp': [None, 0xC9, 0xC5, 0xD5, None, 0xCD, 0xDD, 0xD9,
+ None, None, None, None, 0xC1, 0xD1, None],
+ 'cpx': [None, 0xE0, 0xE4, None, None, 0xEC, None, None,
+ None, None, None, None, None, None, None],
+ 'cpy': [None, 0xC0, 0xC4, None, None, 0xCC, None, None,
+ None, None, None, None, None, None, None],
+ 'dec': [None, None, 0xC6, 0xD6, None, 0xCE, 0xDE, None,
+ None, None, None, None, None, None, None],
+ 'dex': [0xCA, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'dey': [0x88, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'eor': [None, 0x49, 0x45, 0x55, None, 0x4D, 0x5D, 0x59,
+ None, None, None, None, 0x41, 0x51, None],
+ 'inc': [None, None, 0xE6, 0xF6, None, 0xEE, 0xFE, None,
+ None, None, None, None, None, None, None],
+ 'inx': [0xE8, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'iny': [0xC8, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'jmp': [None, None, None, None, None, 0x4C, None, None,
+ 0x6C, None, None, None, None, None, None],
+ 'jsr': [None, None, None, None, None, 0x20, None, None,
+ None, None, None, None, None, None, None],
+ 'lda': [None, 0xA9, 0xA5, 0xB5, None, 0xAD, 0xBD, 0xB9,
+ None, None, None, None, 0xA1, 0xB1, None],
+ 'ldx': [None, 0xA2, 0xA6, None, 0xB6, 0xAE, None, 0xBE,
+ None, None, None, None, None, None, None],
+ 'ldy': [None, 0xA0, 0xA4, 0xB4, None, 0xAC, 0xBC, None,
+ None, None, None, None, None, None, None],
+ 'lsr': [0x4A, None, 0x46, 0x56, None, 0x4E, 0x5E, None,
+ None, None, None, None, None, None, None],
+ 'nop': [0xEA, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'ora': [None, 0x09, 0x05, 0x15, None, 0x0D, 0x1D, 0x19,
+ None, None, None, None, 0x01, 0x11, None],
+ 'pha': [0x48, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'php': [0x08, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'pla': [0x68, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'plp': [0x28, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'rol': [0x2A, None, 0x26, 0x36, None, 0x2E, 0x3E, None,
+ None, None, None, None, None, None, None],
+ 'ror': [0x6A, None, 0x66, 0x76, None, 0x6E, 0x7E, None,
+ None, None, None, None, None, None, None],
+ 'rti': [0x40, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'rts': [0x60, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'sbc': [None, 0xE9, 0xE5, 0xF5, None, 0xED, 0xFD, 0xF9,
+ None, None, None, None, 0xE1, 0xF1, None],
+ 'sec': [0x38, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'sed': [0xF8, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'sei': [0x78, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'sta': [None, None, 0x85, 0x95, None, 0x8D, 0x9D, 0x99,
+ None, None, None, None, 0x81, 0x91, None],
+ 'stx': [None, None, 0x86, None, 0x96, 0x8E, None, None,
+ None, None, None, None, None, None, None],
+ 'sty': [None, None, 0x84, 0x94, None, 0x8C, None, None,
+ None, None, None, None, None, None, None],
+ 'tax': [0xAA, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'tay': [0xA8, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'tsx': [0xBA, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'txa': [0x8A, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'txs': [0x9A, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'tya': [0x98, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
}
-
undocops = {
- 'anc': [None, 0x0B, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'ane': [None, 0x8B, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'arr': [None, 0x6B, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'asr': [None, 0x4B, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'dcp': [None, None, 0xC7, 0xD7, None, 0xCF, 0xDF, 0xDB, None, None, None, None, 0xC3, 0xD3, None],
- 'isb': [None, None, 0xE7, 0xF7, None, 0xEF, 0xFF, 0xFB, None, None, None, None, 0xE3, 0xF3, None],
- 'las': [None, None, None, None, None, None, None, 0xBB, None, None, None, None, None, None, None],
- 'lax': [None, None, 0xA7, None, 0xB7, 0xAF, None, 0xBF, None, None, None, None, 0xA3, 0xB3, None],
- 'lxa': [None, 0xAB, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'nop': [0xEA, None, 0x04, None, None, None, None, None, None, None, None, None, None, None, None],
- 'rla': [None, None, 0x27, 0x37, None, 0x2F, 0x3F, 0x3B, None, None, None, None, 0x23, 0x33, None],
- 'rra': [None, None, 0x67, 0x77, None, 0x6F, 0x7F, 0x7B, None, None, None, None, 0x63, 0x73, None],
- 'sax': [None, None, 0x87, None, 0x97, 0x8F, None, None, None, None, None, None, 0x83, None, None],
- 'sbx': [None, 0xCB, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'sha': [None, None, None, None, None, None, None, 0x9F, None, None, None, None, None, 0x93, None],
- 'shs': [None, None, None, None, None, None, None, 0x9B, None, None, None, None, None, None, None],
- 'shx': [None, None, None, None, None, None, None, 0x9E, None, None, None, None, None, None, None],
- 'slo': [None, None, 0x07, 0x17, None, 0x0F, 0x1F, 0x1B, None, None, None, None, 0x03, 0x13, None],
- 'sre': [None, None, 0x47, 0x57, None, 0x4F, 0x5F, 0x5B, None, None, None, None, 0x43, 0x53, None],
+ 'anc': [None, 0x0B, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'ane': [None, 0x8B, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'arr': [None, 0x6B, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'asr': [None, 0x4B, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'dcp': [None, None, 0xC7, 0xD7, None, 0xCF, 0xDF, 0xDB,
+ None, None, None, None, 0xC3, 0xD3, None],
+ 'isb': [None, None, 0xE7, 0xF7, None, 0xEF, 0xFF, 0xFB,
+ None, None, None, None, 0xE3, 0xF3, None],
+ 'las': [None, None, None, None, None, None, None, 0xBB,
+ None, None, None, None, None, None, None],
+ 'lax': [None, None, 0xA7, None, 0xB7, 0xAF, None, 0xBF,
+ None, None, None, None, 0xA3, 0xB3, None],
+ 'lxa': [None, 0xAB, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'nop': [0xEA, None, 0x04, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'rla': [None, None, 0x27, 0x37, None, 0x2F, 0x3F, 0x3B,
+ None, None, None, None, 0x23, 0x33, None],
+ 'rra': [None, None, 0x67, 0x77, None, 0x6F, 0x7F, 0x7B,
+ None, None, None, None, 0x63, 0x73, None],
+ 'sax': [None, None, 0x87, None, 0x97, 0x8F, None, None,
+ None, None, None, None, 0x83, None, None],
+ 'sbx': [None, 0xCB, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'sha': [None, None, None, None, None, None, None, 0x9F,
+ None, None, None, None, None, 0x93, None],
+ 'shs': [None, None, None, None, None, None, None, 0x9B,
+ None, None, None, None, None, None, None],
+ 'shx': [None, None, None, None, None, None, None, 0x9E,
+ None, None, None, None, None, None, None],
+ 'slo': [None, None, 0x07, 0x17, None, 0x0F, 0x1F, 0x1B,
+ None, None, None, None, 0x03, 0x13, None],
+ 'sre': [None, None, 0x47, 0x57, None, 0x4F, 0x5F, 0x5B,
+ None, None, None, None, 0x43, 0x53, None],
}
-
c02extensions = {
- 'adc': [None, 0x69, 0x65, 0x75, None, 0x6D, 0x7D, 0x79, None, None, None, 0x72, 0x61, 0x71, None],
- 'and': [None, 0x29, 0x25, 0x35, None, 0x2D, 0x3D, 0x39, None, None, None, 0x32, 0x21, 0x31, None],
- 'bbr0': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0x0F],
- 'bbr1': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0x1F],
- 'bbr2': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0x2F],
- 'bbr3': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0x3F],
- 'bbr4': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0x4F],
- 'bbr5': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0x5F],
- 'bbr6': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0x6F],
- 'bbr7': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0x7F],
- 'bbs0': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0x8F],
- 'bbs1': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0x9F],
- 'bbs2': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0xAF],
- 'bbs3': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0xBF],
- 'bbs4': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0xCF],
- 'bbs5': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0xDF],
- 'bbs6': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0xEF],
- 'bbs7': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0xFF],
- 'bit': [None, 0x89, 0x24, 0x34, None, 0x2C, 0x3C, None, None, None, None, None, None, None, None],
- 'bra': [None, None, None, None, None, None, None, None, None, None, None, None, None, None, 0x80],
- 'cmp': [None, 0xC9, 0xC5, 0xD5, None, 0xCD, 0xDD, 0xD9, None, None, None, 0xD2, 0xC1, 0xD1, None],
- 'dea': [0x3A, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'dec': [0x3A, None, 0xC6, 0xD6, None, 0xCE, 0xDE, None, None, None, None, None, None, None, None],
- 'eor': [None, 0x49, 0x45, 0x55, None, 0x4D, 0x5D, 0x59, None, None, None, 0x52, 0x41, 0x51, None],
- 'ina': [0x1A, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'inc': [0x1A, None, 0xE6, 0xF6, None, 0xEE, 0xFE, None, None, None, None, None, None, None, None],
- 'jmp': [None, None, None, None, None, 0x4C, None, None, 0x6C, 0x7C, None, None, None, None, None],
- 'lda': [None, 0xA9, 0xA5, 0xB5, None, 0xAD, 0xBD, 0xB9, None, None, None, 0xB2, 0xA1, 0xB1, None],
- 'ora': [None, 0x09, 0x05, 0x15, None, 0x0D, 0x1D, 0x19, None, None, None, 0x12, 0x01, 0x11, None],
- 'phx': [0xDA, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'phy': [0x5A, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'plx': [0xFA, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'ply': [0x7A, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'rmb0': [None, None, 0x07, None, None, None, None, None, None, None, None, None, None, None, None],
- 'rmb1': [None, None, 0x17, None, None, None, None, None, None, None, None, None, None, None, None],
- 'rmb2': [None, None, 0x27, None, None, None, None, None, None, None, None, None, None, None, None],
- 'rmb3': [None, None, 0x37, None, None, None, None, None, None, None, None, None, None, None, None],
- 'rmb4': [None, None, 0x47, None, None, None, None, None, None, None, None, None, None, None, None],
- 'rmb5': [None, None, 0x57, None, None, None, None, None, None, None, None, None, None, None, None],
- 'rmb6': [None, None, 0x67, None, None, None, None, None, None, None, None, None, None, None, None],
- 'rmb7': [None, None, 0x77, None, None, None, None, None, None, None, None, None, None, None, None],
- 'sbc': [None, 0xE9, 0xE5, 0xF5, None, 0xED, 0xFD, 0xF9, None, None, None, 0xF2, 0xE1, 0xF1, None],
- 'smb0': [None, None, 0x87, None, None, None, None, None, None, None, None, None, None, None, None],
- 'smb1': [None, None, 0x97, None, None, None, None, None, None, None, None, None, None, None, None],
- 'smb2': [None, None, 0xA7, None, None, None, None, None, None, None, None, None, None, None, None],
- 'smb3': [None, None, 0xB7, None, None, None, None, None, None, None, None, None, None, None, None],
- 'smb4': [None, None, 0xC7, None, None, None, None, None, None, None, None, None, None, None, None],
- 'smb5': [None, None, 0xD7, None, None, None, None, None, None, None, None, None, None, None, None],
- 'smb6': [None, None, 0xE7, None, None, None, None, None, None, None, None, None, None, None, None],
- 'smb7': [None, None, 0xF7, None, None, None, None, None, None, None, None, None, None, None, None],
- 'sta': [None, None, 0x85, 0x95, None, 0x8D, 0x9D, 0x99, None, None, None, 0x92, 0x81, 0x91, None],
- 'stp': [0xDB, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
- 'stz': [None, None, 0x64, 0x74, None, 0x9C, 0x9E, None, None, None, None, None, None, None, None],
- 'trb': [None, None, 0x14, None, None, 0x1C, None, None, None, None, None, None, None, None, None],
- 'tsb': [None, None, 0x04, None, None, 0x0C, None, None, None, None, None, None, None, None, None],
- 'wai': [0xCB, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
+ 'adc': [None, 0x69, 0x65, 0x75, None, 0x6D, 0x7D, 0x79,
+ None, None, None, 0x72, 0x61, 0x71, None],
+ 'and': [None, 0x29, 0x25, 0x35, None, 0x2D, 0x3D, 0x39,
+ None, None, None, 0x32, 0x21, 0x31, None],
+ 'bbr0': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0x0F],
+ 'bbr1': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0x1F],
+ 'bbr2': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0x2F],
+ 'bbr3': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0x3F],
+ 'bbr4': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0x4F],
+ 'bbr5': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0x5F],
+ 'bbr6': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0x6F],
+ 'bbr7': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0x7F],
+ 'bbs0': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0x8F],
+ 'bbs1': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0x9F],
+ 'bbs2': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0xAF],
+ 'bbs3': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0xBF],
+ 'bbs4': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0xCF],
+ 'bbs5': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0xDF],
+ 'bbs6': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0xEF],
+ 'bbs7': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0xFF],
+ 'bit': [None, 0x89, 0x24, 0x34, None, 0x2C, 0x3C, None,
+ None, None, None, None, None, None, None],
+ 'bra': [None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, 0x80],
+ 'cmp': [None, 0xC9, 0xC5, 0xD5, None, 0xCD, 0xDD, 0xD9,
+ None, None, None, 0xD2, 0xC1, 0xD1, None],
+ 'dea': [0x3A, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'dec': [0x3A, None, 0xC6, 0xD6, None, 0xCE, 0xDE, None,
+ None, None, None, None, None, None, None],
+ 'eor': [None, 0x49, 0x45, 0x55, None, 0x4D, 0x5D, 0x59,
+ None, None, None, 0x52, 0x41, 0x51, None],
+ 'ina': [0x1A, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'inc': [0x1A, None, 0xE6, 0xF6, None, 0xEE, 0xFE, None,
+ None, None, None, None, None, None, None],
+ 'jmp': [None, None, None, None, None, 0x4C, None, None,
+ 0x6C, 0x7C, None, None, None, None, None],
+ 'lda': [None, 0xA9, 0xA5, 0xB5, None, 0xAD, 0xBD, 0xB9,
+ None, None, None, 0xB2, 0xA1, 0xB1, None],
+ 'ora': [None, 0x09, 0x05, 0x15, None, 0x0D, 0x1D, 0x19,
+ None, None, None, 0x12, 0x01, 0x11, None],
+ 'phx': [0xDA, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'phy': [0x5A, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'plx': [0xFA, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'ply': [0x7A, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'rmb0': [None, None, 0x07, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'rmb1': [None, None, 0x17, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'rmb2': [None, None, 0x27, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'rmb3': [None, None, 0x37, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'rmb4': [None, None, 0x47, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'rmb5': [None, None, 0x57, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'rmb6': [None, None, 0x67, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'rmb7': [None, None, 0x77, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'sbc': [None, 0xE9, 0xE5, 0xF5, None, 0xED, 0xFD, 0xF9,
+ None, None, None, 0xF2, 0xE1, 0xF1, None],
+ 'smb0': [None, None, 0x87, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'smb1': [None, None, 0x97, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'smb2': [None, None, 0xA7, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'smb3': [None, None, 0xB7, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'smb4': [None, None, 0xC7, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'smb5': [None, None, 0xD7, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'smb6': [None, None, 0xE7, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'smb7': [None, None, 0xF7, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'sta': [None, None, 0x85, 0x95, None, 0x8D, 0x9D, 0x99,
+ None, None, None, 0x92, 0x81, 0x91, None],
+ 'stp': [0xDB, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
+ 'stz': [None, None, 0x64, 0x74, None, 0x9C, 0x9E, None,
+ None, None, None, None, None, None, None],
+ 'trb': [None, None, 0x14, None, None, 0x1C, None, None,
+ None, None, None, None, None, None, None],
+ 'tsb': [None, None, 0x04, None, None, 0x0C, None, None,
+ None, None, None, None, None, None, None],
+ 'wai': [0xCB, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None],
}
-
diff --git a/src/Ophis/Passes.py b/src/Ophis/Passes.py
index 497f37e..ae8139e 100644
--- a/src/Ophis/Passes.py
+++ b/src/Ophis/Passes.py
@@ -6,7 +6,7 @@
translation occurs. This structure also makes the assembler
very extensible; additional analyses or optimizations may be
added as new subclasses of Pass."""
-
+
# Copyright 2002-2012 Michael C. Martin and additional contributors.
# You may use, modify, and distribute this file under the MIT
# license: See README for details.
@@ -20,41 +20,55 @@ import Ophis.Macro as Macro
# The passes themselves
+
class Pass(object):
"""Superclass for all assembler passes. Automatically handles IR
types that modify the environent's structure, and by default
raises an error on anything else. Override visitUnknown in your
extension pass to produce a pass that accepts everything."""
name = "Default Pass"
+
def __init__(self):
- self.writeOK = 1
+ self.writeOK = True
+
def visitNone(self, node, env):
pass
+
def visitSEQUENCE(self, node, env):
Err.currentpoint = node.ppt
for n in node.data:
n.accept(self, env)
+
def visitDataSegment(self, node, env):
- self.writeOK = 0
+ self.writeOK = False
env.setsegment(node.data[0])
+
def visitTextSegment(self, node, env):
- self.writeOK = 1
+ self.writeOK = True
env.setsegment(node.data[0])
+
def visitScopeBegin(self, node, env):
env.newscope()
+
def visitScopeEnd(self, node, env):
env.endscope()
+
def visitUnknown(self, node, env):
- Err.log("Internal error! "+self.name+" cannot understand node type "+node.nodetype)
+ Err.log("Internal error! " + self.name +
+ " cannot understand node type " + node.nodetype)
+
def prePass(self):
pass
+
def postPass(self):
pass
+
def go(self, node, env):
- """Prepares the environment and runs this pass, possibly
+ """Prepares the environment and runs this pass, possibly
printing debugging information."""
if Err.count == 0:
- if Cmd.print_pass: print>>sys.stderr, "Running: "+self.name
+ if Cmd.print_pass:
+ print>>sys.stderr, "Running: " + self.name
env.reset()
self.prePass()
node.accept(self, env)
@@ -67,6 +81,7 @@ class Pass(object):
print>>sys.stderr, "Current IR:"
print>>sys.stderr, node
+
class FixPoint(object):
"""A specialized class that is not a pass but can be run like one.
This class takes a list of passes and a "fixpoint" function."""
@@ -74,48 +89,60 @@ class FixPoint(object):
self.name = name
self.passes = passes
self.fixpoint = fixpoint
+
def go(self, node, env):
"""Runs this FixPoint's passes, in order, until the fixpoint
is true. Always runs the passes at least once."""
for i in xrange(100):
- if Err.count != 0: break
+ if Err.count != 0:
+ break
for p in self.passes:
p.go(node, env)
- if Err.count != 0: break
- if self.fixpoint(): break
- if Cmd.print_pass: print>>sys.stderr, "Fixpoint failed, looping back"
+ if Err.count != 0:
+ break
+ if self.fixpoint():
+ break
+ if Cmd.print_pass:
+ print>>sys.stderr, "Fixpoint failed, looping back"
else:
- Err.log("Can't make %s converge! Maybe there's a recursive dependency somewhere?" % self.name)
+ Err.log("Can't make %s converge! Maybe there's a recursive "
+ "dependency somewhere?" % self.name)
+
class DefineMacros(Pass):
"Extract macro definitions and remove them from the IR"
name = "Macro definition pass"
+
def prePass(self):
- self.inDef = 0
- self.nestedError = 0
+ self.inDef = False
+ self.nestedError = False
+
def postPass(self):
if self.inDef:
Err.log("Unmatched .macro")
elif Cmd.print_ir:
print>>sys.stderr, "Macro definitions:"
Macro.dump()
+
def visitMacroBegin(self, node, env):
if self.inDef:
Err.log("Nested macro definition")
- self.nestedError = 1
+ self.nestedError = True
else:
Macro.newMacro(node.data[0])
node.nodetype = "None"
node.data = []
- self.inDef = 1
+ self.inDef = True
+
def visitMacroEnd(self, node, env):
if self.inDef:
Macro.endMacro()
node.nodetype = "None"
node.data = []
- self.inDef = 0
+ self.inDef = False
elif not self.nestedError:
Err.log("Unmatched .macend")
+
def visitUnknown(self, node, env):
if self.inDef:
Macro.registerNode(node)
@@ -126,305 +153,438 @@ class DefineMacros(Pass):
class ExpandMacros(Pass):
"Replace macro invocations with the appropriate text"
name = "Macro expansion pass"
+
def prePass(self):
- self.changed = 0
+ self.changed = False
+
def visitMacroInvoke(self, node, env):
replacement = Macro.expandMacro(node.ppt, node.data[0], node.data[1:])
node.nodetype = replacement.nodetype
node.data = replacement.data
- self.changed = 1
+ self.changed = True
+
def visitUnknown(self, node, env):
pass
+
class InitLabels(Pass):
"Finds all reachable labels"
name = "Label initialization pass"
+
def __init__(self):
Pass.__init__(self)
self.labelmap = {}
+
def prePass(self):
- self.changed = 0
- self.PCvalid = 1
+ self.changed = False
+ self.PCvalid = True
+
def visitAdvance(self, node, env):
- self.PCvalid=node.data[0].valid(env, self.PCvalid)
+ self.PCvalid = node.data[0].valid(env, self.PCvalid)
+
def visitSetPC(self, node, env):
- self.PCvalid=node.data[0].valid(env, self.PCvalid)
+ self.PCvalid = node.data[0].valid(env, self.PCvalid)
+
def visitLabel(self, node, env):
(label, val) = node.data
fulllabel = "%d:%s" % (env.stack[0], label)
- if fulllabel in self.labelmap and self.labelmap[fulllabel] is not node:
+ if fulllabel in self.labelmap and self.labelmap[fulllabel] is not node:
Err.log("Duplicate label definition '%s'" % label)
if fulllabel not in self.labelmap:
self.labelmap[fulllabel] = node
if val.valid(env, self.PCvalid) and label not in env:
- env[label]=0
- self.changed=1
+ env[label] = 0
+ self.changed = True
+
def visitUnknown(self, node, env):
pass
+
class CircularityCheck(Pass):
"Checks for circular label dependencies"
name = "Circularity check pass"
+
def prePass(self):
- self.changed=0
- self.PCvalid=1
+ self.changed = False
+ self.PCvalid = True
+
def visitAdvance(self, node, env):
PCvalid = self.PCvalid
- self.PCvalid=node.data[0].valid(env, self.PCvalid)
+ self.PCvalid = node.data[0].valid(env, self.PCvalid)
if not node.data[0].valid(env, PCvalid):
Err.log("Undefined or circular reference on .advance")
+
def visitSetPC(self, node, env):
PCvalid = self.PCvalid
- self.PCvalid=node.data[0].valid(env, self.PCvalid)
+ self.PCvalid = node.data[0].valid(env, self.PCvalid)
if not node.data[0].valid(env, PCvalid):
Err.log("Undefined or circular reference on program counter set")
+
def visitCheckPC(self, node, env):
if not node.data[0].valid(env, self.PCvalid):
Err.log("Undefined or circular reference on program counter check")
+
def visitLabel(self, node, env):
(label, val) = node.data
- if not val.valid(env, self.PCvalid):
+ if not val.valid(env, self.PCvalid):
Err.log("Undefined or circular dependency for label '%s'" % label)
+
def visitUnknown(self, node, env):
pass
+
class CheckExprs(Pass):
"Ensures all expressions can resolve"
name = "Expression checking pass"
+
def visitUnknown(self, node, env):
+ # Throw away result, just confirm validity of all expressions
for i in [x for x in node.data if isinstance(x, IR.Expr)]:
- i.value(env) # Throw away result, just confirm validity of all expressions
+ i.value(env)
+
class EasyModes(Pass):
"Assigns address modes to hardcoded and branch instructions"
name = "Easy addressing modes pass"
+
def visitMemory(self, node, env):
if Ops.opcodes[node.data[0]][14] is not None:
node.nodetype = "Relative"
return
- if node.data[1].hardcoded:
+ if node.data[1].hardcoded:
if not collapse_no_index(node, env):
node.nodetype = "Absolute"
- def visitMemoryX(self, node, env):
- if node.data[1].hardcoded:
+
+ def visitMemoryX(self, node, env):
+ if node.data[1].hardcoded:
if not collapse_x(node, env):
node.nodetype = "AbsoluteX"
- def visitMemoryY(self, node, env):
- if node.data[1].hardcoded:
+
+ def visitMemoryY(self, node, env):
+ if node.data[1].hardcoded:
if not collapse_y(node, env):
node.nodetype = "AbsoluteY"
+
def visitPointer(self, node, env):
if node.data[1].hardcoded:
if not collapse_no_index_ind(node, env):
node.nodetype = "Indirect"
+
def visitPointerX(self, node, env):
if node.data[1].hardcoded:
if not collapse_x_ind(node, env):
node.nodetype = "AbsIndX"
+
def visitPointerY(self, node, env):
if node.data[1].hardcoded:
if not collapse_y_ind(node, env):
node.nodetype = "AbsIndY"
+
def visitUnknown(self, node, env):
pass
+
class PCTracker(Pass):
"Superclass for passes that need an accurate program counter."
name = "**BUG** PC Tracker Superpass used directly"
- def visitSetPC(self, node, env): env.setPC(node.data[0].value(env))
- def visitAdvance(self, node, env): env.setPC(node.data[0].value(env))
- def visitImplied(self, node, env): env.incPC(1)
- def visitImmediate(self, node, env): env.incPC(2)
- def visitIndirectX(self, node, env): env.incPC(2)
- def visitIndirectY(self, node, env): env.incPC(2)
- def visitZPIndirect(self, node, env): env.incPC(2)
- def visitZeroPage(self, node, env): env.incPC(2)
- def visitZeroPageX(self, node, env): env.incPC(2)
- def visitZeroPageY(self, node, env): env.incPC(2)
- def visitRelative(self, node, env): env.incPC(2)
- def visitIndirect(self, node, env): env.incPC(3)
- def visitAbsolute(self, node, env): env.incPC(3)
- def visitAbsoluteX(self, node, env): env.incPC(3)
- def visitAbsoluteY(self, node, env): env.incPC(3)
- def visitAbsIndX(self, node, env): env.incPC(3)
- def visitAbsIndY(self, node, env): env.incPC(3)
- def visitMemory(self, node, env): env.incPC(3)
- def visitMemoryX(self, node, env): env.incPC(3)
- def visitMemoryY(self, node, env): env.incPC(3)
- def visitPointer(self, node, env): env.incPC(3)
- def visitPointerX(self, node, env): env.incPC(3)
- def visitPointerY(self, node, env): env.incPC(3)
- def visitCheckPC(self, node, env): pass
- def visitLabel(self, node, env): pass
- def visitByte(self, node, env): env.incPC(len(node.data))
- def visitWord(self, node, env): env.incPC(len(node.data)*2)
- def visitDword(self, node, env): env.incPC(len(node.data)*4)
- def visitWordBE(self, node, env): env.incPC(len(node.data)*2)
- def visitDwordBE(self, node, env): env.incPC(len(node.data)*4)
+
+ def visitSetPC(self, node, env):
+ env.setPC(node.data[0].value(env))
+
+ def visitAdvance(self, node, env):
+ env.setPC(node.data[0].value(env))
+
+ def visitImplied(self, node, env):
+ env.incPC(1)
+
+ def visitImmediate(self, node, env):
+ env.incPC(2)
+
+ def visitIndirectX(self, node, env):
+ env.incPC(2)
+
+ def visitIndirectY(self, node, env):
+ env.incPC(2)
+
+ def visitZPIndirect(self, node, env):
+ env.incPC(2)
+
+ def visitZeroPage(self, node, env):
+ env.incPC(2)
+
+ def visitZeroPageX(self, node, env):
+ env.incPC(2)
+
+ def visitZeroPageY(self, node, env):
+ env.incPC(2)
+
+ def visitRelative(self, node, env):
+ env.incPC(2)
+
+ def visitIndirect(self, node, env):
+ env.incPC(3)
+
+ def visitAbsolute(self, node, env):
+ env.incPC(3)
+
+ def visitAbsoluteX(self, node, env):
+ env.incPC(3)
+
+ def visitAbsoluteY(self, node, env):
+ env.incPC(3)
+
+ def visitAbsIndX(self, node, env):
+ env.incPC(3)
+
+ def visitAbsIndY(self, node, env):
+ env.incPC(3)
+
+ def visitMemory(self, node, env):
+ env.incPC(3)
+
+ def visitMemoryX(self, node, env):
+ env.incPC(3)
+
+ def visitMemoryY(self, node, env):
+ env.incPC(3)
+
+ def visitPointer(self, node, env):
+ env.incPC(3)
+
+ def visitPointerX(self, node, env):
+ env.incPC(3)
+
+ def visitPointerY(self, node, env):
+ env.incPC(3)
+
+ def visitCheckPC(self, node, env):
+ pass
+
+ def visitLabel(self, node, env):
+ pass
+
+ def visitByte(self, node, env):
+ env.incPC(len(node.data))
+
+ def visitWord(self, node, env):
+ env.incPC(len(node.data) * 2)
+
+ def visitDword(self, node, env):
+ env.incPC(len(node.data) * 4)
+
+ def visitWordBE(self, node, env):
+ env.incPC(len(node.data) * 2)
+
+ def visitDwordBE(self, node, env):
+ env.incPC(len(node.data) * 4)
+
class UpdateLabels(PCTracker):
"Computes the new values for all entries in the symbol table"
name = "Label Update Pass"
+
def prePass(self):
- self.changed = 0
+ self.changed = False
+
def visitLabel(self, node, env):
(label, val) = node.data
old = env[label]
env[label] = val.value(env)
if old != env[label]:
- self.changed = 1
+ self.changed = True
+
class Collapse(Pass):
- """Selects as many zero-page instructions to convert as
- possible, and tracks how many instructions have been
- converted this pass."""
+ "Selects as many zero-page instructions to convert as possible."
name = "Instruction Collapse Pass"
+
def prePass(self):
- self.collapsed = 0
+ self.changed = False
+
def visitMemory(self, node, env):
- if collapse_no_index(node, env): self.collapsed += 1
+ self.changed |= collapse_no_index(node, env)
+
def visitMemoryX(self, node, env):
- if collapse_x(node, env): self.collapsed += 1
+ self.changed |= collapse_x(node, env)
+
def visitMemoryY(self, node, env):
- if collapse_y(node, env): self.collapsed += 1
+ self.changed |= collapse_y(node, env)
+
def visitPointer(self, node, env):
- if collapse_no_index_ind(node, env): self.collapsed += 1
+ self.changed |= collapse_no_index_ind(node, env)
+
def visitPointerX(self, node, env):
- if collapse_x_ind(node, env): self.collapsed += 1
+ self.changed |= collapse_x_ind(node, env)
+
def visitPointerY(self, node, env):
- if collapse_y_ind(node, env): self.collapsed += 1
+ self.changed |= collapse_y_ind(node, env)
+
def visitUnknown(self, node, env):
pass
+
def collapse_no_index(node, env):
"""Transforms a Memory node into a ZeroPage one if possible.
- Returns 1 if it made the collapse, false otherwise."""
- if node.data[1].value(env) < 0x100 and Ops.opcodes[node.data[0]][2] is not None:
- node.nodetype = "ZeroPage"
- return 1
- else:
- return 0
+ Returns boolean indicating whether or not it made the collapse."""
+ if node.data[1].value(env) < 0x100:
+ if Ops.opcodes[node.data[0]][2] is not None:
+ node.nodetype = "ZeroPage"
+ return True
+ return False
+
def collapse_x(node, env):
"""Transforms a MemoryX node into a ZeroPageX one if possible.
- Returns 1 if it made the collapse, false otherwise."""
- if node.data[1].value(env) < 0x100 and Ops.opcodes[node.data[0]][3] is not None:
- node.nodetype = "ZeroPageX"
- return 1
- else:
- return 0
+ Returns boolean indicating whether or not it made the collapse."""
+ if node.data[1].value(env) < 0x100:
+ if Ops.opcodes[node.data[0]][3] is not None:
+ node.nodetype = "ZeroPageX"
+ return True
+ return False
+
def collapse_y(node, env):
"""Transforms a MemoryY node into a ZeroPageY one if possible.
- Returns 1 if it made the collapse, false otherwise."""
- if node.data[1].value(env) < 0x100 and Ops.opcodes[node.data[0]][4] is not None:
- node.nodetype = "ZeroPageY"
- return 1
- else:
- return 0
+ Returns boolean indicating whether or not it made the collapse."""
+ if node.data[1].value(env) < 0x100:
+ if Ops.opcodes[node.data[0]][4] is not None:
+ node.nodetype = "ZeroPageY"
+ return True
+ return False
+
def collapse_no_index_ind(node, env):
"""Transforms a Pointer node into a ZPIndirect one if possible.
- Returns 1 if it made the collapse, false otherwise."""
- if node.data[1].value(env) < 0x100 and Ops.opcodes[node.data[0]][11] is not None:
- node.nodetype = "ZPIndirect"
- return 1
- else:
- return 0
+ Returns boolean indicating whether or not it made the collapse."""
+ if node.data[1].value(env) < 0x100:
+ if Ops.opcodes[node.data[0]][11] is not None:
+ node.nodetype = "ZPIndirect"
+ return True
+ return False
+
def collapse_x_ind(node, env):
"""Transforms a PointerX node into an IndirectX one if possible.
- Returns 1 if it made the collapse, false otherwise."""
- if node.data[1].value(env) < 0x100 and Ops.opcodes[node.data[0]][12] is not None:
- node.nodetype = "IndirectX"
- return 1
- else:
- return 0
+ Returns boolean indicating whether or not it made the collapse."""
+ if node.data[1].value(env) < 0x100:
+ if Ops.opcodes[node.data[0]][12] is not None:
+ node.nodetype = "IndirectX"
+ return True
+ return False
+
def collapse_y_ind(node, env):
"""Transforms a PointerY node into an IndirectY one if possible.
- Returns 1 if it made the collapse, false otherwise."""
- if node.data[1].value(env) < 0x100 and Ops.opcodes[node.data[0]][13] is not None:
- node.nodetype = "IndirectY"
- return 1
- else:
- return 0
+ Returns boolean indicating whether or not it made the collapse."""
+ if node.data[1].value(env) < 0x100:
+ if Ops.opcodes[node.data[0]][13] is not None:
+ node.nodetype = "IndirectY"
+ return True
+ return False
+
class ExtendBranches(PCTracker):
"""Eliminates any branch instructions that would end up going past
- the 128-byte range, and replaces them with a branch-jump
- pair. Also tracks how many elements where changed this pass."""
+ the 128-byte range, and replaces them with a branch-jump pair."""
name = "Branch Expansion Pass"
- reversed = { 'bcc': 'bcs',
- 'bcs': 'bcc',
- 'beq': 'bne',
- 'bmi': 'bpl',
- 'bne': 'beq',
- 'bpl': 'bmi',
- 'bvc': 'bvs',
- 'bvs': 'bvc',
- # 65c02 ones. 'bra' is special, though, having no inverse
- 'bbr0': 'bbs0',
- 'bbs0': 'bbr0',
- 'bbr1': 'bbs1',
- 'bbs1': 'bbr1',
- 'bbr2': 'bbs2',
- 'bbs2': 'bbr2',
- 'bbr3': 'bbs3',
- 'bbs3': 'bbr3',
- 'bbr4': 'bbs4',
- 'bbs4': 'bbr4',
- 'bbr5': 'bbs5',
- 'bbs5': 'bbr5',
- 'bbr6': 'bbs6',
- 'bbs6': 'bbr6',
- 'bbr7': 'bbs7',
- 'bbs7': 'bbr7'
- }
+ reversed = {'bcc': 'bcs',
+ 'bcs': 'bcc',
+ 'beq': 'bne',
+ 'bmi': 'bpl',
+ 'bne': 'beq',
+ 'bpl': 'bmi',
+ 'bvc': 'bvs',
+ 'bvs': 'bvc',
+ # 65c02 ones. 'bra' is special, though, having no inverse
+ 'bbr0': 'bbs0',
+ 'bbs0': 'bbr0',
+ 'bbr1': 'bbs1',
+ 'bbs1': 'bbr1',
+ 'bbr2': 'bbs2',
+ 'bbs2': 'bbr2',
+ 'bbr3': 'bbs3',
+ 'bbs3': 'bbr3',
+ 'bbr4': 'bbs4',
+ 'bbs4': 'bbr4',
+ 'bbr5': 'bbs5',
+ 'bbs5': 'bbr5',
+ 'bbr6': 'bbs6',
+ 'bbs6': 'bbr6',
+ 'bbr7': 'bbs7',
+ 'bbs7': 'bbr7'
+ }
+
def prePass(self):
- self.expanded = 0
+ self.changed = False
+
def visitRelative(self, node, env):
(opcode, expr) = node.data
arg = expr.value(env)
- arg = arg-(env.getPC()+2)
+ arg = arg - (env.getPC() + 2)
if arg < -128 or arg > 127:
if opcode == 'bra':
# If BRA - BRanch Always - is out of range, it's a JMP.
node.data = ('jmp', expr)
node.nodetype = "Absolute"
if Cmd.warn_on_branch_extend:
- print>>sys.stderr, str(node.ppt) + ": WARNING: bra out of range, replacing with jmp"
+ print>>sys.stderr, str(node.ppt) + ": WARNING: " \
+ "bra out of range, replacing with jmp"
else:
# Otherwise, we replace it with a 'macro' of sorts by hand:
# $branch LOC -> $reversed_branch ^+5; JMP LOC
- # We don't use temp labels here because labels need to have been fixed
- # in place by this point, and JMP is always 3 bytes long.
- expansion = [IR.Node(node.ppt, "Relative", ExtendBranches.reversed[opcode], IR.SequenceExpr([IR.PCExpr(), "+", IR.ConstantExpr(5)])),
+ # We don't use temp labels here because labels need to have
+ # been fixed in place by this point, and JMP is always 3
+ # bytes long.
+ expansion = [IR.Node(node.ppt, "Relative",
+ ExtendBranches.reversed[opcode],
+ IR.SequenceExpr([IR.PCExpr(), "+",
+ IR.ConstantExpr(5)])),
IR.Node(node.ppt, "Absolute", 'jmp', expr)]
- node.nodetype='SEQUENCE'
+ node.nodetype = 'SEQUENCE'
node.data = expansion
if Cmd.warn_on_branch_extend:
- print>>sys.stderr, str(node.ppt) + ": WARNING: "+opcode+" out of range, replacing with "+ExtendBranches.reversed[opcode] +"/jmp combo"
- self.expanded += 1
+ print>>sys.stderr, str(node.ppt) + ": WARNING: " + \
+ opcode + " out of range, " \
+ "replacing with " + \
+ ExtendBranches.reversed[opcode] + \
+ "/jmp combo"
+ self.changed = True
node.accept(self, env)
else:
env.incPC(2)
+
class NormalizeModes(Pass):
"""Eliminates the intermediate "Memory" and "Pointer" nodes,
converting them to "Absolute"."""
name = "Mode Normalization pass"
- def visitMemory(self, node, env): node.nodetype = "Absolute"
- def visitMemoryX(self, node, env): node.nodetype = "AbsoluteX"
- def visitMemoryY(self, node, env): node.nodetype = "AbsoluteY"
- def visitPointer(self, node, env): node.nodetype = "Indirect"
- def visitPointerX(self, node, env): node.nodetype = "AbsIndX"
+
+ def visitMemory(self, node, env):
+ node.nodetype = "Absolute"
+
+ def visitMemoryX(self, node, env):
+ node.nodetype = "AbsoluteX"
+
+ def visitMemoryY(self, node, env):
+ node.nodetype = "AbsoluteY"
+
+ def visitPointer(self, node, env):
+ node.nodetype = "Indirect"
+
+ def visitPointerX(self, node, env):
+ node.nodetype = "AbsIndX"
+
# If we ever hit a PointerY by this point, we have a bug.
- def visitPointerY(self, node, env): node.nodetype = "AbsIndY"
- def visitUnknown(self, node, env): pass
+
+ def visitPointerY(self, node, env):
+ node.nodetype = "AbsIndY"
+
+ def visitUnknown(self, node, env):
+ pass
+
class Assembler(Pass):
- """Converts the IR into a list of bytes, suitable for writing to
+ """Converts the IR into a list of bytes, suitable for writing to
a file."""
name = "Assembler"
@@ -436,36 +596,40 @@ class Assembler(Pass):
def postPass(self):
if Cmd.print_summary and Err.count == 0:
- print>>sys.stderr, "Assembly complete: %s bytes output (%s code, %s data, %s filler)" \
- % (len(self.output), self.code, self.data, self.filler)
+ print>>sys.stderr, "Assembly complete: %s bytes output " \
+ "(%s code, %s data, %s filler)" \
+ % (len(self.output),
+ self.code, self.data, self.filler)
def outputbyte(self, expr, env):
'Outputs a byte, with range checking'
if self.writeOK:
val = expr.value(env)
if val < 0x00 or val > 0xff:
- Err.log("Byte constant "+str(expr)+" out of range")
+ Err.log("Byte constant " + str(expr) + " out of range")
val = 0
self.output.append(int(val))
else:
Err.log("Attempt to write to data segment")
+
def outputword(self, expr, env):
'Outputs a little-endian word, with range checking'
if self.writeOK:
val = expr.value(env)
if val < 0x0000 or val > 0xFFFF:
- Err.log("Word constant "+str(expr)+" out of range")
+ Err.log("Word constant " + str(expr) + " out of range")
val = 0
self.output.append(int(val & 0xFF))
self.output.append(int((val >> 8) & 0xFF))
else:
Err.log("Attempt to write to data segment")
+
def outputdword(self, expr, env):
'Outputs a little-endian dword, with range checking'
if self.writeOK:
val = expr.value(env)
if val < 0x00000000 or val > 0xFFFFFFFFL:
- Err.log("DWord constant "+str(expr)+" out of range")
+ Err.log("DWord constant " + str(expr) + " out of range")
val = 0
self.output.append(int(val & 0xFF))
self.output.append(int((val >> 8) & 0xFF))
@@ -479,18 +643,19 @@ class Assembler(Pass):
if self.writeOK:
val = expr.value(env)
if val < 0x0000 or val > 0xFFFF:
- Err.log("Word constant "+str(expr)+" out of range")
+ Err.log("Word constant " + str(expr) + " out of range")
val = 0
self.output.append(int((val >> 8) & 0xFF))
self.output.append(int(val & 0xFF))
else:
Err.log("Attempt to write to data segment")
+
def outputdword_be(self, expr, env):
'Outputs a big-endian dword, with range checking'
if self.writeOK:
val = expr.value(env)
if val < 0x00000000 or val > 0xFFFFFFFFL:
- Err.log("DWord constant "+str(expr)+" out of range")
+ Err.log("DWord constant " + str(expr) + " out of range")
val = 0
self.output.append(int((val >> 24) & 0xFF))
self.output.append(int((val >> 16) & 0xFF))
@@ -504,77 +669,122 @@ class Assembler(Pass):
(opcode, expr) = node.data
bin_op = Ops.opcodes[opcode][mode]
if bin_op is None:
- Err.log('%s does not have mode "%s"' % (opcode.upper(), Ops.modes[mode]))
+ Err.log('%s does not have mode "%s"' % (opcode.upper(),
+ Ops.modes[mode]))
return
self.outputbyte(IR.ConstantExpr(bin_op), env)
arglen = Ops.lengths[mode]
if mode == 14: # Special handling for relative mode
arg = expr.value(env)
- arg = arg-(env.getPC()+2)
+ arg = arg - (env.getPC() + 2)
if arg < -128 or arg > 127:
Err.log("Branch target out of bounds")
arg = 0
- if arg < 0: arg += 256
+ if arg < 0:
+ arg += 256
expr = IR.ConstantExpr(arg)
- if arglen == 1: self.outputbyte(expr, env)
- if arglen == 2: self.outputword(expr, env)
- env.incPC(1+arglen)
- self.code += 1+arglen
+ if arglen == 1:
+ self.outputbyte(expr, env)
+ if arglen == 2:
+ self.outputword(expr, env)
+ env.incPC(1 + arglen)
+ self.code += 1 + arglen
+
+ def visitImplied(self, node, env):
+ self.assemble(node, 0, env)
+
+ def visitImmediate(self, node, env):
+ self.assemble(node, 1, env)
+
+ def visitZeroPage(self, node, env):
+ self.assemble(node, 2, env)
+
+ def visitZeroPageX(self, node, env):
+ self.assemble(node, 3, env)
+
+ def visitZeroPageY(self, node, env):
+ self.assemble(node, 4, env)
+
+ def visitAbsolute(self, node, env):
+ self.assemble(node, 5, env)
+
+ def visitAbsoluteX(self, node, env):
+ self.assemble(node, 6, env)
+
+ def visitAbsoluteY(self, node, env):
+ self.assemble(node, 7, env)
+
+ def visitIndirect(self, node, env):
+ self.assemble(node, 8, env)
+
+ def visitAbsIndX(self, node, env):
+ self.assemble(node, 9, env)
+
+ def visitAbsIndY(self, node, env):
+ self.assemble(node, 10, env)
+
+ def visitZPIndirect(self, node, env):
+ self.assemble(node, 11, env)
+
+ def visitIndirectX(self, node, env):
+ self.assemble(node, 12, env)
+
+ def visitIndirectY(self, node, env):
+ self.assemble(node, 13, env)
+
+ def visitRelative(self, node, env):
+ self.assemble(node, 14, env)
+
+ def visitLabel(self, node, env):
+ pass
- def visitImplied(self, node, env): self.assemble(node, 0, env)
- def visitImmediate(self, node, env): self.assemble(node, 1, env)
- def visitZeroPage(self, node, env): self.assemble(node, 2, env)
- def visitZeroPageX(self, node, env): self.assemble(node, 3, env)
- def visitZeroPageY(self, node, env): self.assemble(node, 4, env)
- def visitAbsolute(self, node, env): self.assemble(node, 5, env)
- def visitAbsoluteX(self, node, env): self.assemble(node, 6, env)
- def visitAbsoluteY(self, node, env): self.assemble(node, 7, env)
- def visitIndirect(self, node, env): self.assemble(node, 8, env)
- def visitAbsIndX(self, node, env): self.assemble(node, 9, env)
- def visitAbsIndY(self, node, env): self.assemble(node, 10, env)
- def visitZPIndirect(self, node, env): self.assemble(node, 11, env)
- def visitIndirectX(self, node, env): self.assemble(node, 12, env)
- def visitIndirectY(self, node, env): self.assemble(node, 13, env)
- def visitRelative(self, node, env): self.assemble(node, 14, env)
- def visitLabel(self, node, env): pass
def visitByte(self, node, env):
for expr in node.data:
self.outputbyte(expr, env)
env.incPC(len(node.data))
self.data += len(node.data)
+
def visitWord(self, node, env):
for expr in node.data:
self.outputword(expr, env)
- env.incPC(len(node.data)*2)
- self.data += len(node.data)*2
+ env.incPC(len(node.data) * 2)
+ self.data += len(node.data) * 2
+
def visitDword(self, node, env):
for expr in node.data:
self.outputdword(expr, env)
- env.incPC(len(node.data)*4)
- self.data += len(node.data)*4
+ env.incPC(len(node.data) * 4)
+ self.data += len(node.data) * 4
+
def visitWordBE(self, node, env):
for expr in node.data:
self.outputword_be(expr, env)
- env.incPC(len(node.data)*2)
- self.data += len(node.data)*2
+ env.incPC(len(node.data) * 2)
+ self.data += len(node.data) * 2
+
def visitDwordBE(self, node, env):
for expr in node.data:
self.outputdword_be(expr, env)
- env.incPC(len(node.data)*4)
- self.data += len(node.data)*4
- def visitSetPC(self, node, env):
+ env.incPC(len(node.data) * 4)
+ self.data += len(node.data) * 4
+
+ def visitSetPC(self, node, env):
env.setPC(node.data[0].value(env))
+
def visitCheckPC(self, node, env):
pc = env.getPC()
target = node.data[0].value(env)
if (pc > target):
Err.log(".checkpc assertion failed: $%x > $%x" % (pc, target))
- def visitAdvance(self, node, env):
+
+ def visitAdvance(self, node, env):
pc = env.getPC()
target = node.data[0].value(env)
if (pc > target):
- Err.log("Attempted to .advance backwards: $%x to $%x" % (pc, target))
+ Err.log("Attempted to .advance backwards: $%x to $%x" %
+ (pc, target))
else:
- for i in xrange(target-pc): self.outputbyte(node.data[1], env)
- self.filler += target-pc
+ for i in xrange(target - pc):
+ self.outputbyte(node.data[1], env)
+ self.filler += target - pc
env.setPC(target)
diff --git a/src/scripts/ophis.nsi b/src/scripts/ophis.nsi
index 5382375..5964ff8 100644
--- a/src/scripts/ophis.nsi
+++ b/src/scripts/ophis.nsi
@@ -155,4 +155,4 @@ Section Uninstall
DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"
SetAutoClose true
-SectionEnd
\ No newline at end of file
+SectionEnd
diff --git a/src/setup.py b/src/setup.py
index b60c09f..c602381 100644
--- a/src/setup.py
+++ b/src/setup.py
@@ -6,6 +6,11 @@ setup(name='Ophis',
author="Michael Martin",
author_email="mcmartin@gmail.com",
license="MIT",
- long_description="Ophis is a cross-assembler for the 65xx series of chips. It supports the stock 6502 opcodes, the 65c02 extensions, and syntax for the \"undocumented opcodes\" in the 6510 chip used on the Commodore 64. (Syntax for these opcodes matches those given in the VICE team's documentation.)",
+ long_description="Ophis is a cross-assembler for the 65xx series of "
+ "chips. It supports the stock 6502 opcodes, the 65c02 "
+ "extensions, and syntax for the \"undocumented "
+ "opcodes\" in the 6510 chip used on the Commodore 64. "
+ "(Syntax for these opcodes matches those given in the "
+ "VICE team's documentation.)",
packages=['Ophis'],
scripts=['scripts/ophis'])
diff --git a/src/win_setup.py b/src/win_setup.py
index d5c682c..6e5322b 100644
--- a/src/win_setup.py
+++ b/src/win_setup.py
@@ -1,9 +1,10 @@
from distutils.core import setup
-import py2exe, sys
+import py2exe
+import sys
sys.argv.append('py2exe')
-setup(options = {'py2exe': {'bundle_files': 1}},
- packages = ['Ophis'],
- zipfile = None,
- console = [{'script': "scripts/ophis"}])
+setup(options={'py2exe': {'bundle_files': 1}},
+ packages=['Ophis'],
+ zipfile=None,
+ console=[{'script': "scripts/ophis"}])
diff --git a/tests/longbranch_ref.oph b/tests/longbranch_ref.oph
index 72f585d..1cf5778 100644
--- a/tests/longbranch_ref.oph
+++ b/tests/longbranch_ref.oph
@@ -51,4 +51,4 @@ late:
jmp early
* bne +
jmp early
-*
\ No newline at end of file
+*
diff --git a/tests/test6510.oph b/tests/test6510.oph
index 8b0a707..e5cbda3 100644
--- a/tests/test6510.oph
+++ b/tests/test6510.oph
@@ -76,4 +76,4 @@
ISB $F7, X
ISB $FBFB, Y
ISB $FFFF, X
-
+
diff --git a/tests/test65c02.oph b/tests/test65c02.oph
index ebaba8d..ab027cf 100644
--- a/tests/test65c02.oph
+++ b/tests/test65c02.oph
@@ -25,7 +25,7 @@
AND ($32) ; 32: AND - (Zero Page)
BIT $34, X ; 34: BIT - Zero Page, X
RMB3 $37 ; 37: RMB3 - Zero Page
- DEA ; 3A: DEA - Implied
+ DEA ; 3A: DEA - Implied
DEC ; 3A: DEC - Implied
BIT $3C3C,X ; 3C: BIT - Absolute, X
BBR3 ^+$41 ; 3F: BBR3 - Relative
diff --git a/tests/testbase.oph b/tests/testbase.oph
index 44b636d..96c8f64 100644
--- a/tests/testbase.oph
+++ b/tests/testbase.oph
@@ -1,157 +1,157 @@
-; Test file for base 6502 opcode compliance
-; This odd little source file uses every addressing mode
-; of every opcode, and uses the opcode itself as the argument
-; to each instruction that takes one. The resulting binary's
-; bytes are thus in strictly increasing numerical order.
-
- BRK
- ORA ($01, X)
- ORA $05
- ASL $06
- PHP
- ORA #$09
- ASL
- ORA $0D0D
- ASL $0E0E
- BPL ^+$12
- ORA ($11), Y
- ORA $15, X
- ASL $16, X
- CLC
- ORA $1919, Y
- ORA $1D1D, X
- ASL $1E1E, X
- JSR $2020
- AND ($21, X)
- BIT $24
- AND $25
- ROL $26
- PLP
- AND #$29
- ROL
- BIT $2C2C
- AND $2D2D
- ROL $2E2E
- BMI ^+$32
- AND ($31), Y
- AND $35, X
- ROL $36, X
- SEC
- AND $3939, Y
- AND $3D3D, X
- ROL $3E3E, X
- RTI
- EOR ($41, X)
- EOR $45
- LSR $46
- PHA
- EOR #$49
- LSR
- JMP $4C4C
- EOR $4D4D
- LSR $4E4E
- BVC ^+$52
- EOR ($51), Y
- EOR $55, X
- LSR $56, X
- CLI
- EOR $5959, Y
- EOR $5D5D, X
- LSR $5E5E, X
- RTS
- ADC ($61, X)
- ADC $65
- ROR $66
- PLA
- ADC #$69
- ROR
- JMP ($6C6C)
- ADC $6D6D
- ROR $6E6E
- BVS ^+$72
- ADC ($71), Y
- ADC $75, X
- ROR $76, X
- SEI
- ADC $7979, Y
- ADC $7D7D, X
- ROR $7E7E, X
- STA ($81, X)
- STY $84
- STA $85
- STX $86
- DEY
- TXA
- STY $8C8C
- STA $8D8D
- STX $8E8E
- BCC ^-$6E
- STA ($91), Y
- STY $94, X
- STA $95, X
- STX $96, Y
- TYA
- STA $9999, Y
- TXS
- STA $9D9D, X
- LDY #$A0
- LDA ($A1, X)
- LDX #$A2
- LDY $A4
- LDA $A5
- LDX $A6
- TAY
- LDA #$A9
- TAX
- LDY $ACAC
- LDA $ADAD
- LDX $AEAE
- BCS ^-$4e
- LDA ($B1), Y
- LDY $B4, X
- LDA $B5, X
- LDX $B6, Y
- CLV
- LDA $B9B9,Y
- TSX
- LDY $BCBC, X
- LDA $BDBD, X
- LDX $BEBE, Y
- CPY #$C0
- CMP ($C1, X)
- CPY $C4
- CMP $C5
- DEC $C6
- INY
- CMP #$C9
- DEX
- CPY $CCCC
- CMP $CDCD
- DEC $CECE
- BNE ^-$2E
- CMP ($D1), Y
- CMP $D5, X
- DEC $D6, X
- CLD
- CMP $D9D9, Y
- CMP $DDDD, X
- DEC $DEDE, X
- CPX #$E0
- SBC ($E1, X)
- CPX $E4
- SBC $E5
- INC $E6
- INX
- SBC #$E9
- NOP
- CPX $ECEC
- SBC $EDED
- INC $EEEE
- BEQ ^-$0E
- SBC ($F1), Y
- SBC $F5, X
- INC $F6, X
- SED
- SBC $F9F9, Y
- SBC $FDFD, X
- INC $FEFE, X
+; Test file for base 6502 opcode compliance
+; This odd little source file uses every addressing mode
+; of every opcode, and uses the opcode itself as the argument
+; to each instruction that takes one. The resulting binary's
+; bytes are thus in strictly increasing numerical order.
+
+ BRK
+ ORA ($01, X)
+ ORA $05
+ ASL $06
+ PHP
+ ORA #$09
+ ASL
+ ORA $0D0D
+ ASL $0E0E
+ BPL ^+$12
+ ORA ($11), Y
+ ORA $15, X
+ ASL $16, X
+ CLC
+ ORA $1919, Y
+ ORA $1D1D, X
+ ASL $1E1E, X
+ JSR $2020
+ AND ($21, X)
+ BIT $24
+ AND $25
+ ROL $26
+ PLP
+ AND #$29
+ ROL
+ BIT $2C2C
+ AND $2D2D
+ ROL $2E2E
+ BMI ^+$32
+ AND ($31), Y
+ AND $35, X
+ ROL $36, X
+ SEC
+ AND $3939, Y
+ AND $3D3D, X
+ ROL $3E3E, X
+ RTI
+ EOR ($41, X)
+ EOR $45
+ LSR $46
+ PHA
+ EOR #$49
+ LSR
+ JMP $4C4C
+ EOR $4D4D
+ LSR $4E4E
+ BVC ^+$52
+ EOR ($51), Y
+ EOR $55, X
+ LSR $56, X
+ CLI
+ EOR $5959, Y
+ EOR $5D5D, X
+ LSR $5E5E, X
+ RTS
+ ADC ($61, X)
+ ADC $65
+ ROR $66
+ PLA
+ ADC #$69
+ ROR
+ JMP ($6C6C)
+ ADC $6D6D
+ ROR $6E6E
+ BVS ^+$72
+ ADC ($71), Y
+ ADC $75, X
+ ROR $76, X
+ SEI
+ ADC $7979, Y
+ ADC $7D7D, X
+ ROR $7E7E, X
+ STA ($81, X)
+ STY $84
+ STA $85
+ STX $86
+ DEY
+ TXA
+ STY $8C8C
+ STA $8D8D
+ STX $8E8E
+ BCC ^-$6E
+ STA ($91), Y
+ STY $94, X
+ STA $95, X
+ STX $96, Y
+ TYA
+ STA $9999, Y
+ TXS
+ STA $9D9D, X
+ LDY #$A0
+ LDA ($A1, X)
+ LDX #$A2
+ LDY $A4
+ LDA $A5
+ LDX $A6
+ TAY
+ LDA #$A9
+ TAX
+ LDY $ACAC
+ LDA $ADAD
+ LDX $AEAE
+ BCS ^-$4e
+ LDA ($B1), Y
+ LDY $B4, X
+ LDA $B5, X
+ LDX $B6, Y
+ CLV
+ LDA $B9B9,Y
+ TSX
+ LDY $BCBC, X
+ LDA $BDBD, X
+ LDX $BEBE, Y
+ CPY #$C0
+ CMP ($C1, X)
+ CPY $C4
+ CMP $C5
+ DEC $C6
+ INY
+ CMP #$C9
+ DEX
+ CPY $CCCC
+ CMP $CDCD
+ DEC $CECE
+ BNE ^-$2E
+ CMP ($D1), Y
+ CMP $D5, X
+ DEC $D6, X
+ CLD
+ CMP $D9D9, Y
+ CMP $DDDD, X
+ DEC $DEDE, X
+ CPX #$E0
+ SBC ($E1, X)
+ CPX $E4
+ SBC $E5
+ INC $E6
+ INX
+ SBC #$E9
+ NOP
+ CPX $ECEC
+ SBC $EDED
+ INC $EEEE
+ BEQ ^-$0E
+ SBC ($F1), Y
+ SBC $F5, X
+ INC $F6, X
+ SED
+ SBC $F9F9, Y
+ SBC $FDFD, X
+ INC $FEFE, X
diff --git a/tools/charmaps/makea2maps.py b/tools/charmaps/makea2maps.py
index 40dac91..a95f692 100644
--- a/tools/charmaps/makea2maps.py
+++ b/tools/charmaps/makea2maps.py
@@ -10,11 +10,13 @@ normmap = ''.join([bits[x] for x in norm])
ivrsmap = ''.join([bits[x] for x in ivrs])
blnkmap = ''.join([bits[x] for x in blnk])
+
def dumpfile(n, m):
f = file(n, 'wb')
f.write(m)
f.close()
+
dumpfile('a2normal.map', normmap)
dumpfile('a2inverse.map', ivrsmap)
dumpfile('a2blink.map', blnkmap)
diff --git a/tools/opcodes/gensets.py b/tools/opcodes/gensets.py
index 64f791a..84a5991 100644
--- a/tools/opcodes/gensets.py
+++ b/tools/opcodes/gensets.py
@@ -3,7 +3,7 @@ import sys
verbose = 0
-prologue = '"""' +"""Opcodes file.
+prologue = '"""' + """Opcodes file.
Tables for the assembly of 6502-family instructions, mapping
opcodes and addressing modes to binary instructions.""" + '"""' + """
@@ -17,37 +17,38 @@ prologue = '"""' +"""Opcodes file.
# the tables in tools/opcodes. Edit those tables, not these.
# Names of addressing modes
-modes = ["Implied", # 0
- "Immediate", # 1
- "Zero Page", # 2
- "Zero Page, X", # 3
- "Zero Page, Y", # 4
- "Absolute", # 5
- "Absolute, X", # 6
- "Absolute, Y", # 7
- "(Absolute)", # 8
- "(Absolute, X)", # 9
+modes = ["Implied", # 0
+ "Immediate", # 1
+ "Zero Page", # 2
+ "Zero Page, X", # 3
+ "Zero Page, Y", # 4
+ "Absolute", # 5
+ "Absolute, X", # 6
+ "Absolute, Y", # 7
+ "(Absolute)", # 8
+ "(Absolute, X)", # 9
"(Absolute), Y", # 10
"(Zero Page)", # 11
"(Zero Page, X)", # 12
"(Zero Page), Y", # 13
"Relative"] # 14
+
# Lengths of the argument
lengths = [0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1]
"""
# These values should match the ones in the prologue string.
-modes = ["Implied", # 0
- "Immediate", # 1
- "Zero Page", # 2
- "Zero Page, X", # 3
- "Zero Page, Y", # 4
- "Absolute", # 5
- "Absolute, X", # 6
- "Absolute, Y", # 7
- "(Absolute)", # 8
- "(Absolute, X)", # 9
+modes = ["Implied", # 0
+ "Immediate", # 1
+ "Zero Page", # 2
+ "Zero Page, X", # 3
+ "Zero Page, Y", # 4
+ "Absolute", # 5
+ "Absolute, X", # 6
+ "Absolute, Y", # 7
+ "(Absolute)", # 8
+ "(Absolute, X)", # 9
"(Absolute), Y", # 10
"(Zero Page)", # 11
"(Zero Page, X)", # 12
@@ -56,24 +57,28 @@ modes = ["Implied", # 0
flatmodes = [x.lower() for x in modes]
+
# WARNING: This decommenter assumes that # never appears anywhere else
# in a line.
-def decomment (l):
+def decomment(l):
if '#' in l:
l = l[:l.index('#')]
return l.strip()
-def decomment_readlines (fname):
- result = [decomment(x) for x in file(fname).readlines()]
- return [x for x in result if len(x) > 0]
-def parse_chipset_file (fname):
+def decomment_readlines(fname):
+ result = [decomment(x) for x in file(fname).readlines()]
+ return [x for x in result if len(x) > 0]
+
+
+def parse_chipset_file(fname):
result = [None] * 256
- ls = [[x.strip() for x in y] for y in [z.split(':', 1) for z in decomment_readlines (fname)]]
+ ls = [[x.strip() for x in y]
+ for y in [z.split(':', 1) for z in decomment_readlines(fname)]]
for l in ls:
if len(l) == 2:
try:
- op = int (l[0], 16)
+ op = int(l[0], 16)
syns = l[1].split(';')
for s in syns:
s_p = s.split('-')
@@ -81,19 +86,20 @@ def parse_chipset_file (fname):
mnem = s_p[0].lower().strip()
mode = s_p[1].lower().strip()
if mode in flatmodes:
- if result[op] == None:
+ if result[op] is None:
result[op] = []
result[op].append((mnem, flatmodes.index(mode)))
else:
print "Unknown mode '%s'" % s_p[1]
except ValueError:
print "Illegal opcode '%s'" % l[0]
- return result
+ return result
-def collate_chipset_map (cs_list, base):
+
+def collate_chipset_map(cs_list, base):
result = {}
- for (opcode, insts) in zip (range(256), cs_list):
- if insts != None:
+ for (opcode, insts) in zip(range(256), cs_list):
+ if insts is not None:
for inst in insts:
(mnem, mode) = inst
if mnem not in result:
@@ -115,19 +121,26 @@ def collate_chipset_map (cs_list, base):
del result[x]
return result
+
def mapval(x):
if x is None:
return "None"
else:
return "0x%02X" % x
-def dump_map (m, prologue = ''):
+
+def dump_map(m, prologue=''):
mnems = m.keys()
mnems.sort()
for mnem in mnems:
- print "%s'%s': [%s]," % (prologue, mnem, ', '.join([mapval(x) for x in m[mnem]]))
+ codes = [mapval(x) for x in m[mnem]]
+ print "%s'%s': [%s,\n%s %s]," % (prologue, mnem,
+ ', '.join(codes[:8]),
+ prologue + " " * len(mnem),
+ ', '.join(codes[8:]))
-if __name__=='__main__':
+
+if __name__ == '__main__':
if len(sys.argv) > 1:
chipsets = argv[1:]
else:
@@ -135,7 +148,8 @@ if __name__=='__main__':
archs = []
for x in chipsets:
try:
- ls = [[x.strip() for x in y] for y in [z.split(':', 1) for z in decomment_readlines (x)]]
+ ls = [[x.strip() for x in y]
+ for y in [z.split(':', 1) for z in decomment_readlines(x)]]
for l in ls:
if len(l) != 2:
print "Could not parse the chipset line '%s'" % ":".join(l)
@@ -147,10 +161,9 @@ if __name__=='__main__':
baseset = None
for (field, fname) in archs:
chipset_list = parse_chipset_file(fname)
- instruction_map = collate_chipset_map (chipset_list, baseset)
- if baseset == None:
+ instruction_map = collate_chipset_map(chipset_list, baseset)
+ if baseset is None:
baseset = instruction_map
print "%s = {" % field
- dump_map (instruction_map, ' ' * (len(field) + 4))
+ dump_map(instruction_map, ' ' * (len(field) + 4))
print "%s}" % (' ' * (len(field) + 3))
- print ""
diff --git a/tools/opcodes/op6502.txt b/tools/opcodes/op6502.txt
index 9e3e8c5..524698a 100644
--- a/tools/opcodes/op6502.txt
+++ b/tools/opcodes/op6502.txt
@@ -1,256 +1,256 @@
00: BRK - Implied
01: ORA - (Zero Page, X)
- 02:
- 03:
- 04:
+ 02:
+ 03:
+ 04:
05: ORA - Zero Page
06: ASL - Zero Page
- 07:
+ 07:
08: PHP - Implied
09: ORA - Immediate
0A: ASL - Implied
- 0B:
- 0C:
+ 0B:
+ 0C:
0D: ORA - Absolute
0E: ASL - Absolute
- 0F:
+ 0F:
10: BPL - Relative
11: ORA - (Zero Page), Y
- 12:
- 13:
- 14:
+ 12:
+ 13:
+ 14:
15: ORA - Zero Page, X
16: ASL - Zero Page, X
- 17:
+ 17:
18: CLC - Implied
19: ORA - Absolute, Y
- 1A:
- 1B:
- 1C:
+ 1A:
+ 1B:
+ 1C:
1D: ORA - Absolute, X
1E: ASL - Absolute, X
- 1F:
+ 1F:
20: JSR - Absolute
21: AND - (Zero Page, X)
- 22:
- 23:
+ 22:
+ 23:
24: BIT - Zero Page
25: AND - Zero Page
26: ROL - Zero Page
- 27:
+ 27:
28: PLP - Implied
29: AND - Immediate
2A: ROL - Implied
- 2B:
+ 2B:
2C: BIT - Absolute
2D: AND - Absolute
2E: ROL - Absolute
- 2F:
+ 2F:
30: BMI - Relative
31: AND - (Zero Page), Y
- 32:
- 33:
- 34:
+ 32:
+ 33:
+ 34:
35: AND - Zero Page, X
36: ROL - Zero Page, X
- 37:
+ 37:
38: SEC - Implied
39: AND - Absolute, Y
- 3A:
- 3B:
- 3C:
+ 3A:
+ 3B:
+ 3C:
3D: AND - Absolute, X
3E: ROL - Absolute, X
- 3F:
+ 3F:
40: RTI - Implied
41: EOR - (Zero Page, X)
- 42:
- 43:
- 44:
+ 42:
+ 43:
+ 44:
45: EOR - Zero Page
46: LSR - Zero Page
- 47:
+ 47:
48: PHA - Implied
49: EOR - Immediate
4A: LSR - Implied
- 4B:
+ 4B:
4C: JMP - Absolute
4D: EOR - Absolute
4E: LSR - Absolute
- 4F:
+ 4F:
50: BVC - Relative
51: EOR - (Zero Page), Y
- 52:
- 53:
- 54:
+ 52:
+ 53:
+ 54:
55: EOR - Zero Page, X
56: LSR - Zero Page, X
- 57:
+ 57:
58: CLI - Implied
59: EOR - Absolute, Y
- 5A:
- 5B:
- 5C:
+ 5A:
+ 5B:
+ 5C:
5D: EOR - Absolute, X
5E: LSR - Absolute, X
- 5F:
+ 5F:
60: RTS - Implied
61: ADC - (Zero Page, X)
- 62:
- 63:
- 64:
+ 62:
+ 63:
+ 64:
65: ADC - Zero Page
66: ROR - Zero Page
- 67:
+ 67:
68: PLA - Implied
69: ADC - Immediate
6A: ROR - Implied
- 6B:
+ 6B:
6C: JMP - (Absolute)
6D: ADC - Absolute
6E: ROR - Absolute
- 6F:
+ 6F:
70: BVS - Relative
71: ADC - (Zero Page), Y
- 72:
- 73:
- 74:
+ 72:
+ 73:
+ 74:
75: ADC - Zero Page, X
76: ROR - Zero Page, X
- 77:
+ 77:
78: SEI - Implied
79: ADC - Absolute, Y
- 7A:
- 7B:
- 7C:
+ 7A:
+ 7B:
+ 7C:
7D: ADC - Absolute, X
7E: ROR - Absolute, X
- 7F:
- 80:
+ 7F:
+ 80:
81: STA - (Zero Page, X)
- 82:
- 83:
+ 82:
+ 83:
84: STY - Zero Page
85: STA - Zero Page
86: STX - Zero Page
- 87:
+ 87:
88: DEY - Implied
- 89:
+ 89:
8A: TXA - Implied
- 8B:
+ 8B:
8C: STY - Absolute
8D: STA - Absolute
8E: STX - Absolute
- 8F:
+ 8F:
90: BCC - Relative
91: STA - (Zero Page), Y
- 92:
- 93:
+ 92:
+ 93:
94: STY - Zero Page, X
95: STA - Zero Page, X
96: STX - Zero Page, Y
- 97:
+ 97:
98: TYA - Implied
99: STA - Absolute, Y
9A: TXS - Implied
- 9B:
- 9C:
+ 9B:
+ 9C:
9D: STA - Absolute, X
- 9E:
- 9F:
+ 9E:
+ 9F:
A0: LDY - Immediate
A1: LDA - (Zero Page, X)
A2: LDX - Immediate
- A3:
+ A3:
A4: LDY - Zero Page
A5: LDA - Zero Page
A6: LDX - Zero Page
- A7:
+ A7:
A8: TAY - Implied
A9: LDA - Immediate
AA: TAX - Implied
- AB:
+ AB:
AC: LDY - Absolute
AD: LDA - Absolute
AE: LDX - Absolute
- AF:
+ AF:
B0: BCS - Relative
B1: LDA - (Zero Page), Y
- B2:
- B3:
+ B2:
+ B3:
B4: LDY - Zero Page, X
B5: LDA - Zero Page, X
B6: LDX - Zero Page, Y
- B7:
+ B7:
B8: CLV - Implied
B9: LDA - Absolute, Y
BA: TSX - Implied
- BB:
+ BB:
BC: LDY - Absolute, X
BD: LDA - Absolute, X
BE: LDX - Absolute, Y
- BF:
+ BF:
C0: CPY - Immediate
C1: CMP - (Zero Page, X)
- C2:
- C3:
+ C2:
+ C3:
C4: CPY - Zero Page
C5: CMP - Zero Page
C6: DEC - Zero Page
- C7:
+ C7:
C8: INY - Implied
C9: CMP - Immediate
CA: DEX - Implied
- CB:
+ CB:
CC: CPY - Absolute
CD: CMP - Absolute
CE: DEC - Absolute
- CF:
+ CF:
D0: BNE - Relative
D1: CMP - (Zero Page), Y
- D2:
- D3:
- D4:
+ D2:
+ D3:
+ D4:
D5: CMP - Zero Page, X
D6: DEC - Zero Page, X
- D7:
+ D7:
D8: CLD - Implied
D9: CMP - Absolute, Y
- DA:
- DB:
- DC:
+ DA:
+ DB:
+ DC:
DD: CMP - Absolute, X
DE: DEC - Absolute, X
- DF:
+ DF:
E0: CPX - Immediate
E1: SBC - (Zero Page, X)
- E2:
- E3:
+ E2:
+ E3:
E4: CPX - Zero Page
E5: SBC - Zero Page
E6: INC - Zero Page
- E7:
+ E7:
E8: INX - Implied
E9: SBC - Immediate
EA: NOP - Implied
- EB:
+ EB:
EC: CPX - Absolute
ED: SBC - Absolute
EE: INC - Absolute
- EF:
+ EF:
F0: BEQ - Relative
F1: SBC - (Zero Page), Y
- F2:
- F3:
- F4:
+ F2:
+ F3:
+ F4:
F5: SBC - Zero Page, X
F6: INC - Zero Page, X
- F7:
+ F7:
F8: SED - Implied
F9: SBC - Absolute, Y
- FA:
- FB:
- FC:
+ FA:
+ FB:
+ FC:
FD: SBC - Absolute, X
FE: INC - Absolute, X
- FF:
+ FF:
diff --git a/tools/opcodes/op6510.txt b/tools/opcodes/op6510.txt
index 2de216e..43b4f29 100644
--- a/tools/opcodes/op6510.txt
+++ b/tools/opcodes/op6510.txt
@@ -1,8 +1,8 @@
00: BRK - Implied
01: ORA - (Zero Page, X)
- 02:
+ 02:
03: SLO - (Zero Page, X)
- 04: NOP - Zero Page
+ 04: NOP - Zero Page
05: ORA - Zero Page
06: ASL - Zero Page
07: SLO - Zero Page
@@ -10,29 +10,29 @@
09: ORA - Immediate
0A: ASL - Implied
0B: ANC - Immediate
- 0C:
+ 0C:
0D: ORA - Absolute
0E: ASL - Absolute
0F: SLO - Absolute
10: BPL - Relative
11: ORA - (Zero Page), Y
- 12:
+ 12:
13: SLO - (Zero Page), Y
- 14:
+ 14:
15: ORA - Zero Page, X
16: ASL - Zero Page, X
17: SLO - Zero Page, X
18: CLC - Implied
19: ORA - Absolute, Y
- 1A:
+ 1A:
1B: SLO - Absolute, Y
- 1C:
+ 1C:
1D: ORA - Absolute, X
1E: ASL - Absolute, X
1F: SLO - Absolute, X
20: JSR - Absolute
21: AND - (Zero Page, X)
- 22:
+ 22:
23: RLA - (Zero Page, X)
24: BIT - Zero Page
25: AND - Zero Page
@@ -41,32 +41,32 @@
28: PLP - Implied
29: AND - Immediate
2A: ROL - Implied
- 2B:
+ 2B:
2C: BIT - Absolute
2D: AND - Absolute
2E: ROL - Absolute
2F: RLA - Absolute
30: BMI - Relative
31: AND - (Zero Page), Y
- 32:
+ 32:
33: RLA - (Zero Page), Y
- 34:
+ 34:
35: AND - Zero Page, X
36: ROL - Zero Page, X
37: RLA - Zero Page, X
38: SEC - Implied
39: AND - Absolute, Y
- 3A:
+ 3A:
3B: RLA - Absolute, Y
- 3C:
+ 3C:
3D: AND - Absolute, X
3E: ROL - Absolute, X
3F: RLA - Absolute, X
40: RTI - Implied
41: EOR - (Zero Page, X)
- 42:
+ 42:
43: SRE - (Zero Page, X)
- 44:
+ 44:
45: EOR - Zero Page
46: LSR - Zero Page
47: SRE - Zero Page
@@ -80,25 +80,25 @@
4F: SRE - Absolute
50: BVC - Relative
51: EOR - (Zero Page), Y
- 52:
+ 52:
53: SRE - (Zero Page), Y
- 54:
+ 54:
55: EOR - Zero Page, X
56: LSR - Zero Page, X
57: SRE - Zero Page, X
58: CLI - Implied
59: EOR - Absolute, Y
- 5A:
+ 5A:
5B: SRE - Absolute, Y
- 5C:
+ 5C:
5D: EOR - Absolute, X
5E: LSR - Absolute, X
5F: SRE - Absolute, X
60: RTS - Implied
61: ADC - (Zero Page, X)
- 62:
+ 62:
63: RRA - (Zero Page, X)
- 64:
+ 64:
65: ADC - Zero Page
66: ROR - Zero Page
67: RRA - Zero Page
@@ -112,30 +112,30 @@
6F: RRA - Absolute
70: BVS - Relative
71: ADC - (Zero Page), Y
- 72:
+ 72:
73: RRA - (Zero Page), Y
- 74:
+ 74:
75: ADC - Zero Page, X
76: ROR - Zero Page, X
77: RRA - Zero Page, X
78: SEI - Implied
79: ADC - Absolute, Y
- 7A:
+ 7A:
7B: RRA - Absolute, Y
- 7C:
+ 7C:
7D: ADC - Absolute, X
7E: ROR - Absolute, X
7F: RRA - Absolute, X
- 80:
+ 80:
81: STA - (Zero Page, X)
- 82:
+ 82:
83: SAX - (Zero Page, X)
84: STY - Zero Page
85: STA - Zero Page
86: STX - Zero Page
87: SAX - Zero Page
88: DEY - Implied
- 89:
+ 89:
8A: TXA - Implied
8B: ANE - Immediate
8C: STY - Absolute
@@ -144,7 +144,7 @@
8F: SAX - Absolute
90: BCC - Relative
91: STA - (Zero Page), Y
- 92:
+ 92:
93: SHA - (Zero Page), Y
94: STY - Zero Page, X
95: STA - Zero Page, X
@@ -154,7 +154,7 @@
99: STA - Absolute, Y
9A: TXS - Implied
9B: SHS - Absolute, Y
- 9C:
+ 9C:
9D: STA - Absolute, X
9E: SHX - Absolute, Y
9F: SHA - Absolute, Y
@@ -176,7 +176,7 @@
AF: LAX - Absolute
B0: BCS - Relative
B1: LDA - (Zero Page), Y
- B2:
+ B2:
B3: LAX - (Zero Page), Y
B4: LDY - Zero Page, X
B5: LDA - Zero Page, X
@@ -192,7 +192,7 @@
BF: LAX - Absolute, Y
C0: CPY - Immediate
C1: CMP - (Zero Page, X)
- C2:
+ C2:
C3: DCP - (Zero Page, X)
C4: CPY - Zero Page
C5: CMP - Zero Page
@@ -208,23 +208,23 @@
CF: DCP - Absolute
D0: BNE - Relative
D1: CMP - (Zero Page), Y
- D2:
+ D2:
D3: DCP - (Zero Page), Y
- D4:
+ D4:
D5: CMP - Zero Page, X
D6: DEC - Zero Page, X
D7: DCP - Zero Page, X
D8: CLD - Implied
D9: CMP - Absolute, Y
- DA:
+ DA:
DB: DCP - Absolute, Y
- DC:
+ DC:
DD: CMP - Absolute, X
DE: DEC - Absolute, X
DF: DCP - Absolute, X
E0: CPX - Immediate
E1: SBC - (Zero Page, X)
- E2:
+ E2:
E3: ISB - (Zero Page, X)
E4: CPX - Zero Page
E5: SBC - Zero Page
@@ -233,24 +233,24 @@
E8: INX - Implied
E9: SBC - Immediate
EA: NOP - Implied
- EB:
+ EB:
EC: CPX - Absolute
ED: SBC - Absolute
EE: INC - Absolute
EF: ISB - Absolute
F0: BEQ - Relative
F1: SBC - (Zero Page), Y
- F2:
+ F2:
F3: ISB - (Zero Page), Y
- F4:
+ F4:
F5: SBC - Zero Page, X
F6: INC - Zero Page, X
F7: ISB - Zero Page, X
F8: SED - Implied
F9: SBC - Absolute, Y
- FA:
+ FA:
FB: ISB - Absolute, Y
- FC:
+ FC:
FD: SBC - Absolute, X
FE: INC - Absolute, X
FF: ISB - Absolute, X
diff --git a/tools/opcodes/op65c02.txt b/tools/opcodes/op65c02.txt
index ebe8c94..9072f27 100644
--- a/tools/opcodes/op65c02.txt
+++ b/tools/opcodes/op65c02.txt
@@ -1,7 +1,7 @@
00: BRK - Implied
01: ORA - (Zero Page, X)
- 02:
- 03:
+ 02:
+ 03:
04: TSB - Zero Page
05: ORA - Zero Page
06: ASL - Zero Page
@@ -9,7 +9,7 @@
08: PHP - Implied
09: ORA - Immediate
0A: ASL - Implied
- 0B:
+ 0B:
0C: TSB - Absolute
0D: ORA - Absolute
0E: ASL - Absolute
@@ -17,7 +17,7 @@
10: BPL - Relative
11: ORA - (Zero Page), Y
12: ORA - (Zero Page)
- 13:
+ 13:
14: TRB - Zero Page
15: ORA - Zero Page, X
16: ASL - Zero Page, X
@@ -25,15 +25,15 @@
18: CLC - Implied
19: ORA - Absolute, Y
1A: INA - Implied; INC - Implied
- 1B:
+ 1B:
1C: TRB - Absolute
1D: ORA - Absolute, X
1E: ASL - Absolute, X
1F: BBR1 - Relative
20: JSR - Absolute
21: AND - (Zero Page, X)
- 22:
- 23:
+ 22:
+ 23:
24: BIT - Zero Page
25: AND - Zero Page
26: ROL - Zero Page
@@ -41,7 +41,7 @@
28: PLP - Implied
29: AND - Immediate
2A: ROL - Implied
- 2B:
+ 2B:
2C: BIT - Absolute
2D: AND - Absolute
2E: ROL - Absolute
@@ -49,7 +49,7 @@
30: BMI - Relative
31: AND - (Zero Page), Y
32: AND - (Zero Page)
- 33:
+ 33:
34: BIT - Zero Page, X
35: AND - Zero Page, X
36: ROL - Zero Page, X
@@ -57,23 +57,23 @@
38: SEC - Implied
39: AND - Absolute, Y
3A: DEA - Implied; DEC - Implied
- 3B:
+ 3B:
3C: BIT - Absolute, X
3D: AND - Absolute, X
3E: ROL - Absolute, X
3F: BBR3 - Relative
40: RTI - Implied
41: EOR - (Zero Page, X)
- 42:
- 43:
- 44:
+ 42:
+ 43:
+ 44:
45: EOR - Zero Page
46: LSR - Zero Page
47: RMB4 - Zero Page
48: PHA - Implied
49: EOR - Immediate
4A: LSR - Implied
- 4B:
+ 4B:
4C: JMP - Absolute
4D: EOR - Absolute
4E: LSR - Absolute
@@ -81,23 +81,23 @@
50: BVC - Relative
51: EOR - (Zero Page), Y
52: EOR - (Zero Page)
- 53:
- 54:
+ 53:
+ 54:
55: EOR - Zero Page, X
56: LSR - Zero Page, X
57: RMB5 - Zero Page
58: CLI - Implied
59: EOR - Absolute, Y
5A: PHY - Implied
- 5B:
- 5C:
+ 5B:
+ 5C:
5D: EOR - Absolute, X
5E: LSR - Absolute, X
5F: BBR5 - Relative
60: RTS - Implied
61: ADC - (Zero Page, X)
- 62:
- 63:
+ 62:
+ 63:
64: STZ - Zero Page
65: ADC - Zero Page
66: ROR - Zero Page
@@ -105,7 +105,7 @@
68: PLA - Implied
69: ADC - Immediate
6A: ROR - Implied
- 6B:
+ 6B:
6C: JMP - (Absolute)
6D: ADC - Absolute
6E: ROR - Absolute
@@ -113,7 +113,7 @@
70: BVS - Relative
71: ADC - (Zero Page), Y
72: ADC - (Zero Page)
- 73:
+ 73:
74: STZ - Zero Page, X
75: ADC - Zero Page, X
76: ROR - Zero Page, X
@@ -121,15 +121,15 @@
78: SEI - Implied
79: ADC - Absolute, Y
7A: PLY - Implied
- 7B:
+ 7B:
7C: JMP - (Absolute, X)
7D: ADC - Absolute, X
7E: ROR - Absolute, X
7F: BBR7 - Relative
80: BRA - Relative
81: STA - (Zero Page, X)
- 82:
- 83:
+ 82:
+ 83:
84: STY - Zero Page
85: STA - Zero Page
86: STX - Zero Page
@@ -137,7 +137,7 @@
88: DEY - Implied
89: BIT - Immediate
8A: TXA - Implied
- 8B:
+ 8B:
8C: STY - Absolute
8D: STA - Absolute
8E: STX - Absolute
@@ -145,7 +145,7 @@
90: BCC - Relative
91: STA - (Zero Page), Y
92: STA - (Zero Page)
- 93:
+ 93:
94: STY - Zero Page, X
95: STA - Zero Page, X
96: STX - Zero Page, Y
@@ -153,7 +153,7 @@
98: TYA - Implied
99: STA - Absolute, Y
9A: TXS - Implied
- 9B:
+ 9B:
9C: STZ - Absolute
9D: STA - Absolute, X
9E: STZ - Absolute, X
@@ -161,7 +161,7 @@
A0: LDY - Immediate
A1: LDA - (Zero Page, X)
A2: LDX - Immediate
- A3:
+ A3:
A4: LDY - Zero Page
A5: LDA - Zero Page
A6: LDX - Zero Page
@@ -169,7 +169,7 @@
A8: TAY - Implied
A9: LDA - Immediate
AA: TAX - Implied
- AB:
+ AB:
AC: LDY - Absolute
AD: LDA - Absolute
AE: LDX - Absolute
@@ -177,7 +177,7 @@
B0: BCS - Relative
B1: LDA - (Zero Page), Y
B2: LDA - (Zero Page)
- B3:
+ B3:
B4: LDY - Zero Page, X
B5: LDA - Zero Page, X
B6: LDX - Zero Page, Y
@@ -185,15 +185,15 @@
B8: CLV - Implied
B9: LDA - Absolute, Y
BA: TSX - Implied
- BB:
+ BB:
BC: LDY - Absolute, X
BD: LDA - Absolute, X
BE: LDX - Absolute, Y
BF: BBS3 - Relative
C0: CPY - Immediate
C1: CMP - (Zero Page, X)
- C2:
- C3:
+ C2:
+ C3:
C4: CPY - Zero Page
C5: CMP - Zero Page
C6: DEC - Zero Page
@@ -209,8 +209,8 @@
D0: BNE - Relative
D1: CMP - (Zero Page), Y
D2: CMP - (Zero Page)
- D3:
- D4:
+ D3:
+ D4:
D5: CMP - Zero Page, X
D6: DEC - Zero Page, X
D7: SMB5 - Zero Page
@@ -218,14 +218,14 @@
D9: CMP - Absolute, Y
DA: PHX - Implied
DB: STP - Implied
- DC:
+ DC:
DD: CMP - Absolute, X
DE: DEC - Absolute, X
DF: BBS5 - Relative
E0: CPX - Immediate
E1: SBC - (Zero Page, X)
- E2:
- E3:
+ E2:
+ E3:
E4: CPX - Zero Page
E5: SBC - Zero Page
E6: INC - Zero Page
@@ -233,7 +233,7 @@
E8: INX - Implied
E9: SBC - Immediate
EA: NOP - Implied
- EB:
+ EB:
EC: CPX - Absolute
ED: SBC - Absolute
EE: INC - Absolute
@@ -241,16 +241,16 @@
F0: BEQ - Relative
F1: SBC - (Zero Page), Y
F2: SBC - (Zero Page)
- F3:
- F4:
+ F3:
+ F4:
F5: SBC - Zero Page, X
F6: INC - Zero Page, X
F7: SMB7 - Zero Page
F8: SED - Implied
F9: SBC - Absolute, Y
FA: PLX - Implied
- FB:
- FC:
+ FB:
+ FC:
FD: SBC - Absolute, X
FE: INC - Absolute, X
FF: BBS7 - Relative