fix various bugs with 4502 assembly.

This commit is contained in:
gardners 2014-02-07 20:52:11 +10:30
parent 5c4b23cbee
commit 6856da1bbf
5 changed files with 68 additions and 16 deletions

View File

@ -104,6 +104,10 @@ def lex(point, line):
result.append(Lexeme("X"))
elif id == "y":
result.append(Lexeme("Y"))
elif id == "z":
result.append(Lexeme("Z"))
elif id == "sp":
result.append(Lexeme("SP"))
else:
result.append(Lexeme("LABEL", id))
return
@ -187,7 +191,7 @@ class ParseLine(object):
if token.type in tokens:
return token
if 'LABEL' in tokens:
if token.type in ['X', 'Y']:
if token.type in ['X', 'Y', 'Z', 'SP']:
token.value = token.type.lower()
token.type = 'LABEL'
return token
@ -210,7 +214,7 @@ def parse_expr(line):
next = line.lookahead(0).type
if next == "NUM":
return IR.ConstantExpr(line.expect("NUM").value)
elif next in ["LABEL", "X", "Y", "OPCODE"]:
elif next in ["LABEL", "X", "Y", "Z", "SP", "OPCODE"]:
return IR.LabelExpr(line.expect("LABEL").value)
elif next == "^":
line.expect("^")
@ -324,20 +328,33 @@ def parse_line(ppt, lexemelist):
line.expect("(")
arg = parse_expr(line)
if line.lookahead(0).type == ",":
mode = "PointerX"
line.expect(",")
line.expect("X")
line.expect(")")
line.expect("EOL")
if line.lookahead(0).type == "X":
mode = "PointerX"
line.expect("X")
line.expect(")")
line.expect("EOL")
else:
mode = "PointerSPY"
line.expect("SP")
line.expect(")")
line.expect(",")
line.expect("Y")
line.expect("EOL")
else:
line.expect(")")
tok = line.expect(",", "EOL").type
if tok == "EOL":
mode = "Pointer"
else:
mode = "PointerY"
line.expect("Y")
line.expect("EOL")
if line.lookahead(0).type == "Y":
mode = "PointerY"
line.expect("Y")
line.expect("EOL")
else:
mode = "PointerZ"
line.expect("Z")
line.expect("EOL")
elif line.lookahead(0).type == "EOL":
mode = "Implied"
arg = None
@ -351,11 +368,13 @@ def parse_line(ppt, lexemelist):
arg2 = parse_expr(line)
mode = "Memory2"
else:
tok = line.expect("X", "Y").type
tok = line.expect("X", "Y", "Z").type
if tok == "X":
mode = "MemoryX"
else:
elif tok == "Y":
mode = "MemoryY"
else:
mode = "MemoryZ"
line.expect("EOL")
else:
mode = "Memory"

View File

@ -35,7 +35,7 @@ modes = ["Implied", # 0
# Lengths of the argument
lengths = [0, 1, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 1, 1, 2, 2]
lengths = [0, 1, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2]
opcodes = {
'adc': [None, 0x69, None, 0x65, 0x75, None, 0x6D, 0x7D,
@ -445,7 +445,7 @@ csg4502extensions = {
'jsr': [None, None, None, None, None, None, 0x20, None,
None, 0x22, 0x23, None, None, None, None, None, None, None, None, None],
'lda': [None, 0xA9, None, 0xA5, 0xB5, None, 0xAD, 0xBD,
0xB9, None, None, None, 0xB2, 0xA1, 0xB1, 0xE2, None, None, None, None],
0xB9, None, None, None, None, 0xA1, 0xB1, 0xE2, 0xB2, None, None, None],
'ldz': [None, 0xA3, None, None, None, None, 0xAB, 0xBB,
None, None, None, None, None, None, None, None, None, None, None, None],
'map': [0x5C, None, None, None, None, None, None, None,

View File

@ -293,6 +293,16 @@ class EasyModes(Pass):
if not collapse_y_ind(node, env):
node.nodetype = "AbsIndY"
def visitPointerSPY(self, node, env):
if node.data[1].hardcoded:
if not collapse_spy_ind(node, env):
node.nodetype = "AbsIndSPY"
def visitPointerZ(self, node, env):
if node.data[1].hardcoded:
if not collapse_z_ind(node, env):
node.nodetype = "AbsIndZ"
def visitUnknown(self, node, env):
pass
@ -373,6 +383,9 @@ class PCTracker(Pass):
def visitMemoryY(self, node, env):
env.incPC(3)
def visitMemoryZ(self, node, env):
env.incPC(3)
def visitPointer(self, node, env):
env.incPC(3)
@ -442,6 +455,9 @@ class Collapse(PCTracker):
self.changed |= collapse_y(node, env)
PCTracker.visitMemoryY(self, node, env)
def visitMemoryZ(self, node, env):
PCTracker.visitMemoryZ(self, node, env)
def visitPointer(self, node, env):
self.changed |= collapse_no_index_ind(node, env)
PCTracker.visitPointer(self, node, env)
@ -515,7 +531,6 @@ def collapse_y(node, env):
return True
return False
def collapse_no_index_ind(node, env):
"""Transforms a Pointer node into a ZPIndirect one if possible.
Returns boolean indicating whether or not it made the collapse."""
@ -545,6 +560,24 @@ def collapse_y_ind(node, env):
return True
return False
def collapse_spy_ind(node, env):
"""Transforms a PointerSPY node into an IndirectY one if possible.
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 = "IndirectSPY"
return True
return False
def collapse_z_ind(node, env):
"""Transforms a PointerZ node into an IndirectZ one if possible.
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 = "IndirectZ"
return True
return False
class ExtendBranches(PCTracker):
"""Eliminates any branch instructions that would end up going past

View File

@ -40,7 +40,7 @@ modes = ["Implied", # 0
# Lengths of the argument
lengths = [0, 1, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2,2]
lengths = [0, 1, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2]
"""
# These values should match the ones in the prologue string.

View File

@ -176,7 +176,7 @@
AF: BBS2 - Zero Page, Relative
B0: BCS - Relative
B1: LDA - (Zero Page), Y
B2: LDA - (Zero Page)
B2: LDA - (Zero Page), Z
B3: BCS - RelativeLong
B4: LDY - Zero Page, X
B5: LDA - Zero Page, X