How to use the gilgamesh.snes.opcodes.Op function in gilgamesh

To help you get started, we’ve selected a few gilgamesh examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github AndreaOrru / gilgamesh / gilgamesh / snes / cpu.py View on Github external
def _check_stack_manipulation(
        i: Instruction, stack_entries: List[StackEntry]
    ) -> Optional[Instruction]:
        # Check whether this return is operating on a manipulated stack.
        call_op = (Op.JSR, Op.RTS) if i.operation == Op.RTS else (Op.JSL, Op.RTL)
        # Non-call instructions which operated on the region of the
        # stack containing the return address from the subroutine.
        stack_manipulators = [
            s.instruction
            for s in stack_entries
            if not s.instruction or s.instruction.operation not in call_op
        ]
        if stack_manipulators:
            return stack_manipulators[-1]
        return None
github AndreaOrru / gilgamesh / gilgamesh / snes / cpu.py View on Github external
targets = self._calculate_targets(i, targets)
        saved_state, saved_state_change = copy(self.state), copy(self.state_change)
        possible_states = set()

        for _, target in targets:
            if target is None or self.rom.is_ram(target):
                # If we can't reliably derive the address of the subroutine
                # being called, we're left in an unknown state.
                return self._unknown_subroutine_state(
                    i, unknown_reason=UnknownReason.INDIRECT_JUMP
                )

            # Run a parallel instance of the CPU to execute
            # the subroutine that is being called.
            cpu = self.copy(new_subroutine=True)
            call_size = 2 if i.operation in (Op.JSR, Op.RTS) else 3
            cpu.stack.push(i, i.pc, call_size)
            cpu.stack_trace.append(self.subroutine_pc)
            cpu.subroutine_pc = target
            cpu.pc = target

            # Emulate the called subroutine.
            self.log.add_reference(i, target)
            self.log.add_subroutine(target, stack_trace=cpu.stack_trace)
            cpu.run()

            # If we univocally know what the return state of the
            # called subroutine is, we can propagate it to the
            # current CPU state. Otherwise, to be on the safe
            # side, we need to stop the execution.
            known, unknown_reason = self._propagate_subroutine_state(i.pc, target)
            if known or self._unknown_subroutine_state(
github AndreaOrru / gilgamesh / gilgamesh / snes / cpu.py View on Github external
def push(self, instruction: Instruction) -> None:
        if instruction.operation == Op.PHP:
            self.stack.push(instruction, (copy(self.state), copy(self.state_change)))
        elif instruction.operation == Op.PHA:
            self.stack.push(instruction, self.registers.a.get(), self.state.a_size)
        elif instruction.operation in (Op.PHX, Op.PHY):
            self.stack.push(instruction, size=self.state.x_size)
        elif instruction.operation in (Op.PHB, Op.PHK):
            self.stack.push(instruction)
        elif instruction.operation in (Op.PHD, Op.PEA, Op.PER):
            self.stack.push(instruction, size=2)
        else:
            assert False
github AndreaOrru / gilgamesh / gilgamesh / snes / cpu.py View on Github external
def pop(self, i: Instruction) -> bool:
        if i.operation == Op.PLP:
            entry = self.stack.pop_one()
            if entry.instruction and entry.instruction.operation == Op.PHP:
                self.state, self.state_change = entry.data
            # We can't trust the disassembly if we don't know
            # which state the PLP instruction is restoring.
            else:
                return self._unknown_subroutine_state(
                    i,
                    unknown_reason=UnknownReason.STACK_MANIPULATION,
                    stack_manipulator=entry.instruction,
                )

        elif i.operation in (Op.PLX, Op.PLY):
            self.stack.pop(self.state.x_size)
        elif i.operation == Op.PLB:
            self.stack.pop_one()
        elif i.operation == Op.PLD:
            self.stack.pop(2)
        else:
            assert False
        return True
github AndreaOrru / gilgamesh / gilgamesh / snes / opcodes.py View on Github external
(Op.TSB, AddressMode.ABSOLUTE),
    (Op.ORA, AddressMode.ABSOLUTE),
    (Op.ASL, AddressMode.ABSOLUTE),
    (Op.ORA, AddressMode.ABSOLUTE_LONG),
    (Op.BPL, AddressMode.RELATIVE),
    (Op.ORA, AddressMode.DIRECT_PAGE_INDIRECT_INDEXED),
    (Op.ORA, AddressMode.DIRECT_PAGE_INDIRECT),
    (Op.ORA, AddressMode.STACK_RELATIVE_INDIRECT_INDEXED),
    (Op.TRB, AddressMode.DIRECT_PAGE),
    (Op.ORA, AddressMode.DIRECT_PAGE_INDEXED_X),
    (Op.ASL, AddressMode.DIRECT_PAGE_INDEXED_X),
    (Op.ORA, AddressMode.DIRECT_PAGE_INDIRECT_INDEXED_LONG),
    (Op.CLC, AddressMode.IMPLIED),
    (Op.ORA, AddressMode.ABSOLUTE_INDEXED_Y),
    (Op.INC, AddressMode.IMPLIED_ACCUMULATOR),
    (Op.TCS, AddressMode.IMPLIED),
    (Op.TRB, AddressMode.ABSOLUTE),
    (Op.ORA, AddressMode.ABSOLUTE_INDEXED_X),
    (Op.ASL, AddressMode.ABSOLUTE_INDEXED_X),
    (Op.ORA, AddressMode.ABSOLUTE_INDEXED_LONG),
    (Op.JSR, AddressMode.ABSOLUTE),
    (Op.AND, AddressMode.DIRECT_PAGE_INDEXED_INDIRECT),
    (Op.JSL, AddressMode.ABSOLUTE_LONG),
    (Op.AND, AddressMode.STACK_RELATIVE),
    (Op.BIT, AddressMode.DIRECT_PAGE),
    (Op.AND, AddressMode.DIRECT_PAGE),
    (Op.ROL, AddressMode.DIRECT_PAGE),
    (Op.AND, AddressMode.DIRECT_PAGE_INDIRECT_LONG),
    (Op.PLP, AddressMode.IMPLIED),
    (Op.AND, AddressMode.IMMEDIATE_M),
    (Op.ROL, AddressMode.IMPLIED_ACCUMULATOR),
    (Op.PLD, AddressMode.IMPLIED),
github AndreaOrru / gilgamesh / gilgamesh / snes / cpu.py View on Github external
def change_a(self, i: Instruction) -> None:
        if i.address_mode == AddressMode.IMMEDIATE_M:
            assert i.argument is not None
            a = self.registers.a.get()

            if i.operation == Op.LDA:
                self.registers.a.set(i.argument)
            elif a is not None:
                if i.operation == Op.ADC:
                    # TODO: handle carry flag.
                    self.registers.a.set(a + i.argument)
                elif i.operation == Op.SBC:
                    # TODO: handle negative flag.
                    self.registers.a.set(a - i.argument)
        elif i.operation == Op.TSC:
            self.registers.a.set_whole(self.stack.pointer)
        elif i.operation == Op.PLA:
            self.stack.pop(self.state.a_size)
        else:
            self.registers.a.set(None)
github AndreaOrru / gilgamesh / gilgamesh / snes / cpu.py View on Github external
def change_stack(self, i: Instruction) -> None:
        if i.operation == Op.TCS:
            a = self.registers.a.get_whole()
            self.stack.set_pointer(i, a)
            if a is not None:
                return
        # We keep the disassembly going if the stack manipulation
        # doesn't otherwise influence the state of the processor.
        i.stack_manipulation = StackManipulation.HARMLESS
github AndreaOrru / gilgamesh / gilgamesh / snes / cpu.py View on Github external
def change_a(self, i: Instruction) -> None:
        if i.address_mode == AddressMode.IMMEDIATE_M:
            assert i.argument is not None
            a = self.registers.a.get()

            if i.operation == Op.LDA:
                self.registers.a.set(i.argument)
            elif a is not None:
                if i.operation == Op.ADC:
                    # TODO: handle carry flag.
                    self.registers.a.set(a + i.argument)
                elif i.operation == Op.SBC:
                    # TODO: handle negative flag.
                    self.registers.a.set(a - i.argument)
        elif i.operation == Op.TSC:
            self.registers.a.set_whole(self.stack.pointer)
        elif i.operation == Op.PLA:
            self.stack.pop(self.state.a_size)
        else:
            self.registers.a.set(None)
github AndreaOrru / gilgamesh / gilgamesh / snes / opcodes.py View on Github external
(Op.JMP, AddressMode.ABSOLUTE),
    (Op.EOR, AddressMode.ABSOLUTE),
    (Op.LSR, AddressMode.ABSOLUTE),
    (Op.EOR, AddressMode.ABSOLUTE_LONG),
    (Op.BVC, AddressMode.RELATIVE),
    (Op.EOR, AddressMode.DIRECT_PAGE_INDIRECT_INDEXED),
    (Op.EOR, AddressMode.DIRECT_PAGE_INDIRECT),
    (Op.EOR, AddressMode.STACK_RELATIVE_INDIRECT_INDEXED),
    (Op.MVN, AddressMode.MOVE),
    (Op.EOR, AddressMode.DIRECT_PAGE_INDEXED_X),
    (Op.LSR, AddressMode.DIRECT_PAGE_INDEXED_X),
    (Op.EOR, AddressMode.DIRECT_PAGE_INDIRECT_INDEXED_LONG),
    (Op.CLI, AddressMode.IMPLIED),
    (Op.EOR, AddressMode.ABSOLUTE_INDEXED_Y),
    (Op.PHY, AddressMode.IMPLIED),
    (Op.TCD, AddressMode.IMPLIED),
    (Op.JML, AddressMode.ABSOLUTE_LONG),
    (Op.EOR, AddressMode.ABSOLUTE_INDEXED_X),
    (Op.LSR, AddressMode.ABSOLUTE_INDEXED_X),
    (Op.EOR, AddressMode.ABSOLUTE_INDEXED_LONG),
    (Op.RTS, AddressMode.IMPLIED),
    (Op.ADC, AddressMode.DIRECT_PAGE_INDEXED_INDIRECT),
    (Op.PER, AddressMode.RELATIVE_LONG),
    (Op.ADC, AddressMode.STACK_RELATIVE),
    (Op.STZ, AddressMode.DIRECT_PAGE),
    (Op.ADC, AddressMode.DIRECT_PAGE),
    (Op.ROR, AddressMode.DIRECT_PAGE),
    (Op.ADC, AddressMode.DIRECT_PAGE_INDIRECT_LONG),
    (Op.PLA, AddressMode.IMPLIED),
    (Op.ADC, AddressMode.IMMEDIATE_M),
    (Op.ROR, AddressMode.IMPLIED_ACCUMULATOR),
    (Op.RTL, AddressMode.IMPLIED),
github AndreaOrru / gilgamesh / gilgamesh / snes / opcodes.py View on Github external
Op.STX: "Store Index Register X to Memory",
    Op.STY: "Store Index Register Y to Memory",
    Op.STZ: "Store Zero to Memory",
    Op.TAX: "Transfer Accumulator to Index Register X",
    Op.TAY: "Transfer Accumulator to Index Register Y",
    Op.TCD: "Transfer 16-bit Accumulator to Direct Page Register",
    Op.TCS: "Transfer 16-bit Accumulator to Stack Pointer",
    Op.TDC: "Transfer Direct Page Register to 16-bit Accumulator",
    Op.TRB: "Test and Reset Memory Bits Against Accumulator",
    Op.TSB: "Test and Set Memory Bits Against Accumulator",
    Op.TSC: "Transfer Stack Pointer to 16-bit Accumulator",
    Op.TSX: "Transfer Stack Pointer to Index Register X",
    Op.TXA: "Transfer Index Register X to Accumulator",
    Op.TXS: "Transfer Index Register X to Stack Pointer",
    Op.TXY: "Transfer Index Register X to Index Register Y",
    Op.TYA: "Transfer Index Register Y to Accumulator",
    Op.TYX: "Transfer Index Register Y to Index Register X",
    Op.WAI: "Wait for Interrupt",
    Op.WDM: "Reserved for Future Expansion",
    Op.XBA: "Exchange B and A 8-bit Accumulators",
    Op.XCE: "Exchange Carry and Emulation Flags",
}