diff --git a/src/Ophis/Frontend.py b/src/Ophis/Frontend.py index 6c76dc4..51bcde9 100644 --- a/src/Ophis/Frontend.py +++ b/src/Ophis/Frontend.py @@ -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" diff --git a/src/Ophis/Opcodes.py b/src/Ophis/Opcodes.py index d571235..5808719 100644 --- a/src/Ophis/Opcodes.py +++ b/src/Ophis/Opcodes.py @@ -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, diff --git a/src/Ophis/Passes.py b/src/Ophis/Passes.py index a2b316d..a909e67 100644 --- a/src/Ophis/Passes.py +++ b/src/Ophis/Passes.py @@ -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 diff --git a/src/tools/opcodes/gensets.py b/src/tools/opcodes/gensets.py index 9e79e48..6ca3450 100755 --- a/src/tools/opcodes/gensets.py +++ b/src/tools/opcodes/gensets.py @@ -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. diff --git a/src/tools/opcodes/op4502.txt b/src/tools/opcodes/op4502.txt index d1e73fe..0b1e386 100644 --- a/src/tools/opcodes/op4502.txt +++ b/src/tools/opcodes/op4502.txt @@ -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