mirror of
https://github.com/michaelcmartin/Ophis.git
synced 2025-01-02 14:29:35 +00:00
fix various bugs with 4502 assembly.
This commit is contained in:
parent
5c4b23cbee
commit
6856da1bbf
@ -104,6 +104,10 @@ def lex(point, line):
|
|||||||
result.append(Lexeme("X"))
|
result.append(Lexeme("X"))
|
||||||
elif id == "y":
|
elif id == "y":
|
||||||
result.append(Lexeme("Y"))
|
result.append(Lexeme("Y"))
|
||||||
|
elif id == "z":
|
||||||
|
result.append(Lexeme("Z"))
|
||||||
|
elif id == "sp":
|
||||||
|
result.append(Lexeme("SP"))
|
||||||
else:
|
else:
|
||||||
result.append(Lexeme("LABEL", id))
|
result.append(Lexeme("LABEL", id))
|
||||||
return
|
return
|
||||||
@ -187,7 +191,7 @@ class ParseLine(object):
|
|||||||
if token.type in tokens:
|
if token.type in tokens:
|
||||||
return token
|
return token
|
||||||
if 'LABEL' in tokens:
|
if 'LABEL' in tokens:
|
||||||
if token.type in ['X', 'Y']:
|
if token.type in ['X', 'Y', 'Z', 'SP']:
|
||||||
token.value = token.type.lower()
|
token.value = token.type.lower()
|
||||||
token.type = 'LABEL'
|
token.type = 'LABEL'
|
||||||
return token
|
return token
|
||||||
@ -210,7 +214,7 @@ def parse_expr(line):
|
|||||||
next = line.lookahead(0).type
|
next = line.lookahead(0).type
|
||||||
if next == "NUM":
|
if next == "NUM":
|
||||||
return IR.ConstantExpr(line.expect("NUM").value)
|
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)
|
return IR.LabelExpr(line.expect("LABEL").value)
|
||||||
elif next == "^":
|
elif next == "^":
|
||||||
line.expect("^")
|
line.expect("^")
|
||||||
@ -324,20 +328,33 @@ def parse_line(ppt, lexemelist):
|
|||||||
line.expect("(")
|
line.expect("(")
|
||||||
arg = parse_expr(line)
|
arg = parse_expr(line)
|
||||||
if line.lookahead(0).type == ",":
|
if line.lookahead(0).type == ",":
|
||||||
mode = "PointerX"
|
|
||||||
line.expect(",")
|
line.expect(",")
|
||||||
|
if line.lookahead(0).type == "X":
|
||||||
|
mode = "PointerX"
|
||||||
line.expect("X")
|
line.expect("X")
|
||||||
line.expect(")")
|
line.expect(")")
|
||||||
line.expect("EOL")
|
line.expect("EOL")
|
||||||
|
else:
|
||||||
|
mode = "PointerSPY"
|
||||||
|
line.expect("SP")
|
||||||
|
line.expect(")")
|
||||||
|
line.expect(",")
|
||||||
|
line.expect("Y")
|
||||||
|
line.expect("EOL")
|
||||||
else:
|
else:
|
||||||
line.expect(")")
|
line.expect(")")
|
||||||
tok = line.expect(",", "EOL").type
|
tok = line.expect(",", "EOL").type
|
||||||
if tok == "EOL":
|
if tok == "EOL":
|
||||||
mode = "Pointer"
|
mode = "Pointer"
|
||||||
else:
|
else:
|
||||||
|
if line.lookahead(0).type == "Y":
|
||||||
mode = "PointerY"
|
mode = "PointerY"
|
||||||
line.expect("Y")
|
line.expect("Y")
|
||||||
line.expect("EOL")
|
line.expect("EOL")
|
||||||
|
else:
|
||||||
|
mode = "PointerZ"
|
||||||
|
line.expect("Z")
|
||||||
|
line.expect("EOL")
|
||||||
elif line.lookahead(0).type == "EOL":
|
elif line.lookahead(0).type == "EOL":
|
||||||
mode = "Implied"
|
mode = "Implied"
|
||||||
arg = None
|
arg = None
|
||||||
@ -351,11 +368,13 @@ def parse_line(ppt, lexemelist):
|
|||||||
arg2 = parse_expr(line)
|
arg2 = parse_expr(line)
|
||||||
mode = "Memory2"
|
mode = "Memory2"
|
||||||
else:
|
else:
|
||||||
tok = line.expect("X", "Y").type
|
tok = line.expect("X", "Y", "Z").type
|
||||||
if tok == "X":
|
if tok == "X":
|
||||||
mode = "MemoryX"
|
mode = "MemoryX"
|
||||||
else:
|
elif tok == "Y":
|
||||||
mode = "MemoryY"
|
mode = "MemoryY"
|
||||||
|
else:
|
||||||
|
mode = "MemoryZ"
|
||||||
line.expect("EOL")
|
line.expect("EOL")
|
||||||
else:
|
else:
|
||||||
mode = "Memory"
|
mode = "Memory"
|
||||||
|
@ -35,7 +35,7 @@ modes = ["Implied", # 0
|
|||||||
|
|
||||||
|
|
||||||
# Lengths of the argument
|
# 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 = {
|
opcodes = {
|
||||||
'adc': [None, 0x69, None, 0x65, 0x75, None, 0x6D, 0x7D,
|
'adc': [None, 0x69, None, 0x65, 0x75, None, 0x6D, 0x7D,
|
||||||
@ -445,7 +445,7 @@ csg4502extensions = {
|
|||||||
'jsr': [None, None, None, None, None, None, 0x20, None,
|
'jsr': [None, None, None, None, None, None, 0x20, None,
|
||||||
None, 0x22, 0x23, None, None, None, None, None, None, None, None, None],
|
None, 0x22, 0x23, None, None, None, None, None, None, None, None, None],
|
||||||
'lda': [None, 0xA9, None, 0xA5, 0xB5, None, 0xAD, 0xBD,
|
'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,
|
'ldz': [None, 0xA3, None, None, None, None, 0xAB, 0xBB,
|
||||||
None, None, None, None, None, None, None, None, None, None, None, None],
|
None, None, None, None, None, None, None, None, None, None, None, None],
|
||||||
'map': [0x5C, None, None, None, None, None, None, None,
|
'map': [0x5C, None, None, None, None, None, None, None,
|
||||||
|
@ -293,6 +293,16 @@ class EasyModes(Pass):
|
|||||||
if not collapse_y_ind(node, env):
|
if not collapse_y_ind(node, env):
|
||||||
node.nodetype = "AbsIndY"
|
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):
|
def visitUnknown(self, node, env):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -373,6 +383,9 @@ class PCTracker(Pass):
|
|||||||
def visitMemoryY(self, node, env):
|
def visitMemoryY(self, node, env):
|
||||||
env.incPC(3)
|
env.incPC(3)
|
||||||
|
|
||||||
|
def visitMemoryZ(self, node, env):
|
||||||
|
env.incPC(3)
|
||||||
|
|
||||||
def visitPointer(self, node, env):
|
def visitPointer(self, node, env):
|
||||||
env.incPC(3)
|
env.incPC(3)
|
||||||
|
|
||||||
@ -442,6 +455,9 @@ class Collapse(PCTracker):
|
|||||||
self.changed |= collapse_y(node, env)
|
self.changed |= collapse_y(node, env)
|
||||||
PCTracker.visitMemoryY(self, node, env)
|
PCTracker.visitMemoryY(self, node, env)
|
||||||
|
|
||||||
|
def visitMemoryZ(self, node, env):
|
||||||
|
PCTracker.visitMemoryZ(self, node, env)
|
||||||
|
|
||||||
def visitPointer(self, node, env):
|
def visitPointer(self, node, env):
|
||||||
self.changed |= collapse_no_index_ind(node, env)
|
self.changed |= collapse_no_index_ind(node, env)
|
||||||
PCTracker.visitPointer(self, node, env)
|
PCTracker.visitPointer(self, node, env)
|
||||||
@ -515,7 +531,6 @@ def collapse_y(node, env):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def collapse_no_index_ind(node, env):
|
def collapse_no_index_ind(node, env):
|
||||||
"""Transforms a Pointer node into a ZPIndirect one if possible.
|
"""Transforms a Pointer node into a ZPIndirect one if possible.
|
||||||
Returns boolean indicating whether or not it made the collapse."""
|
Returns boolean indicating whether or not it made the collapse."""
|
||||||
@ -545,6 +560,24 @@ def collapse_y_ind(node, env):
|
|||||||
return True
|
return True
|
||||||
return False
|
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):
|
class ExtendBranches(PCTracker):
|
||||||
"""Eliminates any branch instructions that would end up going past
|
"""Eliminates any branch instructions that would end up going past
|
||||||
|
@ -40,7 +40,7 @@ modes = ["Implied", # 0
|
|||||||
|
|
||||||
|
|
||||||
# Lengths of the argument
|
# 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.
|
# These values should match the ones in the prologue string.
|
||||||
|
@ -176,7 +176,7 @@
|
|||||||
AF: BBS2 - Zero Page, Relative
|
AF: BBS2 - Zero Page, Relative
|
||||||
B0: BCS - Relative
|
B0: BCS - Relative
|
||||||
B1: LDA - (Zero Page), Y
|
B1: LDA - (Zero Page), Y
|
||||||
B2: LDA - (Zero Page)
|
B2: LDA - (Zero Page), Z
|
||||||
B3: BCS - RelativeLong
|
B3: BCS - RelativeLong
|
||||||
B4: LDY - Zero Page, X
|
B4: LDY - Zero Page, X
|
||||||
B5: LDA - Zero Page, X
|
B5: LDA - Zero Page, X
|
||||||
|
Loading…
Reference in New Issue
Block a user