Skip to content

Instantly share code, notes, and snippets.

@Cheaterman
Created October 12, 2021 19:07
Show Gist options
  • Save Cheaterman/1c982fce6e5f1a8cb53f86f359fd605c to your computer and use it in GitHub Desktop.
Save Cheaterman/1c982fce6e5f1a8cb53f86f359fd605c to your computer and use it in GitHub Desktop.
cpu.pyx
# cython: language_level=3, boundscheck=False, wraparound=False, cdivision=True
cimport cython
from libc.string cimport strncmp, strncpy
from bus cimport Bus
from cpu_instructions cimport cpu_function_from_name
cdef class CPU:
def __cinit__(self, Bus bus):
cdef unsigned char opcode = 0
self.bus = bus
self.status = CPUStatus(value=0)
self.opcode = 0
self.address_absolute = 0
self.address_relative = 0
self.fetched = 0
self.cycles_to_wait = 0
for operation_name, addressing_mode_name, cycles in (
('BRK', 'imp', 7), ('ORA', 'inx', 6), ('ill', 'imp', 1), ('ill', 'imp', 1),
('ill', 'imp', 1), ('ORA', 'zp0', 3), ('ASL', 'zp0', 5), ('ill', 'imp', 1),
('PHP', 'imp', 3), ('ORA', 'imm', 2), ('ASL', 'imp', 2), ('ill', 'imp', 1),
('ill', 'imp', 1), ('ORA', 'abs', 4), ('ASL', 'abs', 6), ('ill', 'imp', 1),
('BPL', 'rel', 2), ('ORA', 'iny', 5), ('ill', 'imp', 1), ('ill', 'imp', 1),
('ill', 'imp', 1), ('ORA', 'zpx', 4), ('ASL', 'zpx', 6), ('ill', 'imp', 1),
('CLC', 'imp', 2), ('ORA', 'aby', 4), ('ill', 'imp', 1), ('ill', 'imp', 1),
('ill', 'imp', 1), ('ORA', 'abx', 4), ('ASL', 'abx', 7), ('ill', 'imp', 1),
('JSR', 'abs', 6), ('AND', 'inx', 6), ('ill', 'imp', 1), ('ill', 'imp', 1),
('BIT', 'zp0', 3), ('AND', 'zp0', 3), ('ROL', 'zp0', 5), ('ill', 'imp', 1),
('PLP', 'imp', 4), ('AND', 'imm', 2), ('ROL', 'imp', 2), ('ill', 'imp', 1),
('BIT', 'abs', 4), ('AND', 'abs', 4), ('ROL', 'abs', 6), ('ill', 'imp', 1),
('BMI', 'rel', 2), ('AND', 'iny', 5), ('ill', 'imp', 1), ('ill', 'imp', 1),
('ill', 'imp', 1), ('AND', 'zpx', 4), ('ROL', 'zpx', 6), ('ill', 'imp', 1),
('SEC', 'imp', 2), ('AND', 'aby', 4), ('ill', 'imp', 1), ('ill', 'imp', 1),
('ill', 'imp', 1), ('AND', 'abx', 4), ('ROL', 'abx', 7), ('ill', 'imp', 1),
# Fifth row
('RTI', 'imp', 6), ('EOR', 'inx', 6), ('ill', 'imp', 1), ('ill', 'imp', 1),
('ill', 'imp', 1), ('EOR', 'zp0', 3), ('LSR', 'zp0', 5), ('ill', 'imp', 1),
('PHA', 'imp', 3), ('EOR', 'imm', 2), ('LSR', 'imp', 2), ('ill', 'imp', 1),
('JMP', 'abs', 3), ('EOR', 'abs', 4), ('LSR', 'abs', 6), ('ill', 'imp', 1),
('BVC', 'rel', 2), ('EOR', 'iny', 5), ('ill', 'imp', 1), ('ill', 'imp', 1),
('ill', 'imp', 1), ('EOR', 'zpx', 4), ('LSR', 'zpx', 6), ('ill', 'imp', 1),
('CLI', 'imp', 2), ('EOR', 'aby', 4), ('ill', 'imp', 1), ('ill', 'imp', 1),
('ill', 'imp', 1), ('EOR', 'abx', 4), ('LSR', 'abx', 7), ('ill', 'imp', 1),
('RTS', 'imp', 6), ('ADC', 'inx', 6), ('ill', 'imp', 1), ('ill', 'imp', 1),
('ill', 'imp', 1), ('ADC', 'zp0', 3), ('ROR', 'zp0', 5), ('ill', 'imp', 1),
('PLA', 'imp', 4), ('ADC', 'imm', 2), ('ROR', 'imp', 2), ('ill', 'imp', 1),
('JMP', 'ind', 5), ('ADC', 'abs', 4), ('ROR', 'abs', 6), ('ill', 'imp', 1),
('BVS', 'rel', 2), ('ADC', 'iny', 5), ('ill', 'imp', 1), ('ill', 'imp', 1),
('ill', 'imp', 1), ('ADC', 'zpx', 4), ('ROR', 'zpx', 6), ('ill', 'imp', 1),
('SEI', 'imp', 2), ('ADC', 'aby', 4), ('ill', 'imp', 1), ('ill', 'imp', 1),
('ill', 'imp', 1), ('ADC', 'abx', 4), ('ROR', 'abx', 7), ('ill', 'imp', 1),
# Ninth row
('ill', 'imp', 1), ('STA', 'inx', 6), ('ill', 'imp', 1), ('ill', 'imp', 1),
('STY', 'zp0', 3), ('STA', 'zp0', 3), ('STX', 'zp0', 3), ('ill', 'imp', 1),
('DEY', 'imp', 2), ('ill', 'imp', 1), ('TXA', 'imp', 2), ('ill', 'imp', 1),
('STY', 'abs', 4), ('STA', 'abs', 4), ('STX', 'abs', 4), ('ill', 'imp', 1),
('BCC', 'rel', 2), ('STA', 'iny', 6), ('ill', 'imp', 1), ('ill', 'imp', 1),
('STY', 'zpx', 4), ('STA', 'zpx', 4), ('STX', 'zpy', 4), ('ill', 'imp', 1),
('TYA', 'imp', 2), ('STA', 'aby', 5), ('TXS', 'imp', 2), ('ill', 'imp', 1),
('ill', 'imp', 1), ('STA', 'abx', 5), ('ill', 'imp', 1), ('ill', 'imp', 1),
('LDY', 'imm', 2), ('LDA', 'inx', 6), ('LDX', 'imm', 2), ('ill', 'imp', 1),
('LDY', 'zp0', 3), ('LDA', 'zp0', 3), ('LDX', 'zp0', 3), ('ill', 'imp', 1),
('TAY', 'imp', 2), ('LDA', 'imm', 2), ('TAX', 'imp', 2), ('ill', 'imp', 1),
('LDY', 'abs', 4), ('LDA', 'abs', 4), ('LDX', 'abs', 4), ('ill', 'imp', 1),
('BCS', 'rel', 2), ('LDA', 'iny', 5), ('ill', 'imp', 1), ('ill', 'imp', 1),
('LDY', 'zpx', 4), ('LDA', 'zpx', 4), ('LDX', 'zpy', 4), ('ill', 'imp', 1),
('CLV', 'imp', 2), ('LDA', 'aby', 4), ('TSX', 'imp', 2), ('ill', 'imp', 1),
('LDY', 'abx', 4), ('LDA', 'abx', 4), ('LDX', 'aby', 4), ('ill', 'imp', 1),
# Thirteenth row
('CPY', 'imm', 2), ('CMP', 'inx', 6), ('ill', 'imp', 1), ('ill', 'imp', 1),
('CPY', 'zp0', 3), ('CMP', 'zp0', 3), ('DEC', 'zp0', 5), ('ill', 'imp', 1),
('INY', 'imp', 2), ('CMP', 'imm', 2), ('DEX', 'imp', 2), ('ill', 'imp', 1),
('CPY', 'abs', 4), ('CMP', 'abs', 4), ('DEC', 'abs', 6), ('ill', 'imp', 1),
('BNE', 'rel', 2), ('CMP', 'iny', 5), ('ill', 'imp', 1), ('ill', 'imp', 1),
('ill', 'imp', 1), ('CMP', 'zpx', 4), ('DEC', 'zpx', 6), ('ill', 'imp', 1),
('CLD', 'imp', 2), ('CMP', 'aby', 4), ('ill', 'imp', 1), ('ill', 'imp', 1),
('ill', 'imp', 1), ('CMP', 'abx', 4), ('DEC', 'abx', 7), ('ill', 'imp', 1),
('CPX', 'imm', 2), ('SBC', 'inx', 6), ('ill', 'imp', 1), ('ill', 'imp', 1),
('CPX', 'zp0', 3), ('SBC', 'zp0', 3), ('INC', 'zp0', 5), ('ill', 'imp', 1),
('INX', 'imp', 2), ('SBC', 'imm', 2), ('NOP', 'imp', 2), ('ill', 'imp', 1),
('CPX', 'abs', 4), ('SBC', 'abs', 4), ('INC', 'abs', 6), ('ill', 'imp', 1),
('BEQ', 'rel', 2), ('SBC', 'iny', 5), ('ill', 'imp', 1), ('ill', 'imp', 1),
('ill', 'imp', 1), ('SBC', 'zpx', 4), ('INC', 'zpx', 6), ('ill', 'imp', 1),
('SED', 'imp', 2), ('SBC', 'aby', 4), ('ill', 'imp', 1), ('ill', 'imp', 1),
('ill', 'imp', 1), ('SBC', 'abx', 4), ('INC', 'abx', 7), ('ill', 'imp', 1),
):
self.instructions[opcode] = Instruction(
operation=cpu_function_from_name(operation_name),
addressing_mode=cpu_function_from_name(addressing_mode_name),
cycles=cycles,
)
operation_name_bytes = (
operation_name.encode()
if operation_name != 'ill'
else b'???'
)
strncpy(
self.instructions[opcode].name,
operation_name_bytes,
4
)
strncpy(
self.instructions[opcode].addressing_mode_name,
addressing_mode_name.encode(),
4
)
opcode += 1
cdef inline void clock(self) nogil:
cdef unsigned char opcode
cdef bint requires_extra_cycle
if self.cycles_to_wait == 0:
self.opcode = opcode = self.read(self.pc)
self.pc += 1
self.instruction = self.instructions[opcode]
self.cycles_to_wait = self.instruction.cycles
requires_extra_cycle = self.instruction.addressing_mode(self)
if(
self.instruction.operation(self)
and requires_extra_cycle
):
self.cycles_to_wait += 1
self.cycles_to_wait -= 1
cdef void reset(self) nogil:
self.a = self.x = self.y = 0
self.sp = 0xFD
self.pc = self.read(0xFFFD) << 8 | self.read(0xFFFC)
self.status.value = 0
self.status.flags._ = 1
self.address_absolute = 0
self.address_relative = 0
self.fetched = 0
self.cycles_to_wait = 6
cdef void irq(self) nogil:
if not self.status.flags.I:
self.write(0x100 + self.sp, (self.pc & 0xFF00) >> 8)
self.sp -= 1
self.write(0x100 + self.sp, self.pc & 0xFF)
self.sp -= 1
self.status.flags.I = 1
self.status.flags.B = 0
self.write(0x100 + self.sp, self.status.value)
self.sp -= 1
self.pc = self.read(0xFFFF) << 8 | self.read(0xFFFE)
self.cycles_to_wait = 7
cdef void nmi(self) nogil:
self.write(0x100 + self.sp, (self.pc & 0xFF00) >> 8)
self.sp -= 1
self.write(0x100 + self.sp, self.pc & 0xFF)
self.sp -= 1
self.status.flags.I = 1
self.status.flags.B = 0
self.write(0x100 + self.sp, self.status.value)
self.sp -= 1
self.pc = self.read(0xFFFB) << 8 | self.read(0xFFFA)
self.cycles_to_wait = 7
cdef inline unsigned char fetch(self) nogil:
if strncmp(self.instruction.addressing_mode_name, b'imp', 4):
self.fetched = self.read(self.address_absolute)
return self.fetched
cdef inline unsigned char read(self, unsigned short address) nogil:
return self.bus.read(address)
cdef inline void write(self, unsigned short address, unsigned char value) nogil:
self.bus.write(address, value)
# Addressing modes
cdef inline bint implied(self) nogil:
self.fetched = self.a
cdef inline bint imm(self) nogil:
self.address_absolute = self.pc
self.pc += 1
cdef inline bint relative(self) nogil:
self.address_relative = self.read(self.pc)
self.pc += 1
if self.address_relative & 0x80:
self.address_relative |= 0xFF00
return True
cdef inline bint abs(self) nogil:
self.address_absolute = self.read(self.pc)
self.pc += 1
self.address_absolute |= self.read(self.pc) << 8
self.pc += 1
cdef inline bint abx(self) nogil:
cdef unsigned short high_byte
self.address_absolute = self.read(self.pc)
self.pc += 1
high_byte = self.read(self.pc) << 8
self.address_absolute |= high_byte
self.pc += 1
self.address_absolute += self.x
if self.address_absolute & 0xFF00 != high_byte:
return True
cdef inline bint aby(self) nogil:
cdef unsigned short high_byte
self.address_absolute = self.read(self.pc)
self.pc += 1
high_byte = self.read(self.pc) << 8
self.address_absolute |= high_byte
self.pc += 1
self.address_absolute += self.y
if self.address_absolute & 0xFF00 != high_byte:
return True
cdef inline bint zp0(self) nogil:
self.address_absolute = self.read(self.pc)
self.address_absolute &= 0xFF
self.pc += 1
cdef inline bint zpx(self) nogil:
self.address_absolute = self.read(self.pc) + self.x
self.address_absolute &= 0xFF
self.pc += 1
cdef inline bint zpy(self) nogil:
self.address_absolute = self.read(self.pc) + self.y
self.address_absolute &= 0xFF
self.pc += 1
cdef inline bint indirect(self) nogil:
cdef unsigned short address
address = self.read(self.pc)
self.pc += 1
address |= self.read(self.pc) << 8
self.pc += 1
self.address_absolute = self.read(address)
self.address_absolute |= self.read(
address & 0xFF00 | (address + 1 & 0xFF)
) << 8
cdef inline bint indx(self) nogil:
cdef unsigned short address
address = self.read(self.pc) + self.x
address &= 0xFF
self.pc += 1
self.address_absolute = self.read(address)
self.address_absolute |= self.read(
address & 0xFF00 | (address + 1 & 0xFF)
) << 8
cdef inline bint indy(self) nogil:
cdef unsigned short address, high_byte
address = self.read(self.pc)
self.pc += 1
self.address_absolute = self.read(address)
high_byte = self.read(address + 1) << 8
self.address_absolute |= high_byte
self.address_absolute += self.y
if self.address_absolute & 0xFF00 != high_byte:
return True
# Operations
cdef inline bint illegal(self) nogil:
#print('Illegal opcode: 0x%02X' % self.opcode)
pass
cdef inline bint add(self, unsigned char value) nogil:
# Probably wrong - result should be a short?
cdef unsigned char a_value, result
a_value = self.a
result = a_value + value + self.status.flags.C
self.status.flags.C = <bint>(result > 0xFF)
self.status.flags.Z = <bint>(result & 0xFF == 0)
self.status.flags.V = <bint>((a_value ^ result) & ~(a_value ^ value) & 0x80)
self.status.flags.N = <bint>(result & 0x80)
self.a = result & 0xFF
return True
cdef inline bint branch(self) nogil:
self.cycles_to_wait += 1
old_pc = self.pc
self.pc += <char>self.address_relative
if self.pc & 0xFF00 != old_pc & 0xFF00:
return True
cdef inline bint ADC(self) nogil:
return self.add(self.fetch())
cdef inline bint AND(self) nogil:
self.a &= self.fetch()
self.status.flags.Z = <bint>(self.a == 0)
self.status.flags.N = <bint>(self.a & 0x80)
return True
cdef inline bint ASL(self) nogil:
cdef unsigned char result
result = self.fetch() << 1
self.status.flags.C = <bint>(result > 0xFF)
self.status.flags.Z = <bint>(result & 0xFF == 0)
self.status.flags.N = <bint>(result & 0x80)
if not strncmp(self.instruction.addressing_mode_name, b'imp', 4):
self.a = result & 0xFF
else:
self.write(self.address_absolute, result)
cdef inline bint BCC(self) nogil:
if not self.status.flags.C:
return self.branch()
cdef inline bint BCS(self) nogil:
if self.status.flags.C:
return self.branch()
cdef inline bint BEQ(self) nogil:
if self.status.flags.Z:
return self.branch()
cdef inline bint BIT(self) nogil:
cdef unsigned char result
result = self.fetch() & self.a
self.status.flags.Z = <bint>(result & 0xFF == 0)
self.status.flags.V = <bint>(self.fetched & (1 << 6))
self.status.flags.N = <bint>(self.fetched & (1 << 7))
cdef inline bint BMI(self) nogil:
if self.status.flags.N:
return self.branch()
cdef inline bint BNE(self) nogil:
if not self.status.flags.Z:
return self.branch()
cdef inline bint BPL(self) nogil:
if not self.status.flags.N:
return self.branch()
cdef inline bint BRK(self) nogil:
self.pc += 1
self.write(0x100 + self.sp, (self.pc & 0xFF00) >> 8)
self.sp -= 1
self.write(0x100 + self.sp, self.pc & 0xFF)
self.sp -= 1
self.status.flags.I = 1
self.status.flags.B = 1
self.write(0x100 + self.sp, self.status.value)
self.sp -= 1
self.status.flags.B = 0
self.pc = self.read(0xFFFF) << 8 | self.read(0xFFFE)
cdef inline bint BVC(self) nogil:
if not self.status.flags.V:
return self.branch()
cdef inline bint BVS(self) nogil:
if self.status.flags.V:
return self.branch()
cdef inline bint CLC(self) nogil:
self.status.flags.C = 0
cdef inline bint CLD(self) nogil:
self.status.flags.D = 0
cdef inline bint CLI(self) nogil:
self.status.flags.I = 0
cdef inline bint CLV(self) nogil:
self.status.flags.V = 0
cdef inline bint CMP(self) nogil:
cdef unsigned char result
result = self.a - self.fetch()
self.status.flags.C = <bint>(result >= 0)
self.status.flags.Z = <bint>(result & 0xFF == 0)
self.status.flags.N = <bint>(result & 0x80)
return True
cdef inline bint CPX(self) nogil:
cdef unsigned char result
result = self.x - self.fetch()
self.status.flags.C = <bint>(result >= 0)
self.status.flags.Z = <bint>(result & 0xFF == 0)
self.status.flags.N = <bint>(result & 0x80)
return True
cdef inline bint CPY(self) nogil:
cdef unsigned char result
result = self.y - self.fetch()
self.status.flags.C = <bint>(result >= 0)
self.status.flags.Z = <bint>(result & 0xFF == 0)
self.status.flags.N = <bint>(result & 0x80)
return True
cdef inline bint DEC(self) nogil:
cdef unsigned char result
result = self.fetch() - 1
self.status.flags.Z = <bint>(result & 0xFF == 0)
self.status.flags.N = <bint>(result & 0x80)
self.write(self.address_absolute, result)
cdef inline bint DEX(self) nogil:
cdef unsigned char result
result = self.x - 1
self.status.flags.Z = <bint>(result & 0xFF == 0)
self.status.flags.N = <bint>(result & 0x80)
self.x = result
cdef inline bint DEY(self) nogil:
cdef unsigned char result
result = self.y - 1
self.status.flags.Z = <bint>(result & 0xFF == 0)
self.status.flags.N = <bint>(result & 0x80)
self.y = result
cdef inline bint EOR(self) nogil:
cdef unsigned char result
result = self.a ^ self.fetch()
self.status.flags.Z = <bint>(result & 0xFF == 0)
self.status.flags.N = <bint>(result & 0x80)
self.a = result
return True
cdef inline bint INC(self) nogil:
cdef unsigned char result
result = self.fetch() + 1
self.status.flags.Z = <bint>(result & 0xFF == 0)
self.status.flags.N = <bint>(result & 0x80)
self.write(self.address_absolute, result)
cdef inline bint INX(self) nogil:
cdef unsigned char result
result = self.x + 1
self.status.flags.Z = <bint>(result & 0xFF == 0)
self.status.flags.N = <bint>(result & 0x80)
self.x = result
cdef inline bint INY(self) nogil:
cdef unsigned char result
result = self.y + 1
self.status.flags.Z = <bint>(result & 0xFF == 0)
self.status.flags.N = <bint>(result & 0x80)
self.y = result
cdef inline bint JMP(self) nogil:
self.pc = self.address_absolute
cdef inline bint JSR(self) nogil:
self.write(0x100 + self.sp, (self.pc & 0xFF00) >> 8)
self.sp -= 1
self.write(0x100 + self.sp, self.pc & 0xFF)
self.sp -= 1
self.pc = self.address_absolute
cdef inline bint LDA(self) nogil:
cdef unsigned char result
result = self.fetch()
self.status.flags.Z = <bint>(result & 0xFF == 0)
self.status.flags.N = <bint>(result & 0x80)
self.a = result
return True
cdef inline bint LDX(self) nogil:
cdef unsigned char result
result = self.fetch()
self.status.flags.Z = <bint>(result & 0xFF == 0)
self.status.flags.N = <bint>(result & 0x80)
self.x = result
return True
cdef inline bint LDY(self) nogil:
cdef unsigned char result
result = self.fetch()
self.status.flags.Z = <bint>(result & 0xFF == 0)
self.status.flags.N = <bint>(result & 0x80)
self.y = result
return True
cdef inline bint LSR(self) nogil:
cdef unsigned char result
result = self.fetch() >> 1
self.status.flags.C = <bint>(self.fetched & 1)
self.status.flags.Z = <bint>(result & 0xFF == 0)
self.status.flags.N = 0
if not strncmp(self.instruction.addressing_mode_name, b'imp', 4):
self.a = result
else:
self.write(self.address_absolute, result)
cdef inline bint NOP(self) nogil:
# There will probably be some unofficial variants here
pass
cdef inline bint ORA(self) nogil:
cdef unsigned char result
result = self.a | self.fetch()
self.status.flags.Z = <bint>(result & 0xFF == 0)
self.status.flags.N = <bint>(result & 0x80)
self.a = result
cdef inline bint PHA(self) nogil:
self.write(0x100 + self.sp, self.a)
self.sp -= 1
cdef inline bint PHP(self) nogil:
self.write(0x100 + self.sp, self.status.value)
self.sp -= 1
cdef inline bint PLA(self) nogil:
cdef unsigned char result
self.sp += 1
result = self.read(0x100 + self.sp)
self.status.flags.Z = <bint>(result & 0xFF == 0)
self.status.flags.N = <bint>(result & 0x80)
self.a = result
cdef inline bint PLP(self) nogil:
self.sp += 1
self.status.value = self.read(0x100 + self.sp)
cdef inline bint ROL(self) nogil:
cdef unsigned char result
result = (self.fetch() << 1) | ((self.fetched & (1 << 7)) >> 7)
self.status.flags.C = <bint>(result > 0xFF)
self.status.flags.Z = <bint>(result & 0xFF == 0)
self.status.flags.N = <bint>(result & 0x80)
if not strncmp(self.instruction.addressing_mode_name, b'imp', 4):
self.a = result
else:
self.write(self.address_absolute, result)
cdef inline bint ROR(self) nogil:
cdef unsigned char result
result = ((self.fetch() & 1) << 7) | (self.fetched >> 1)
self.status.flags.C = <bint>(self.fetched & 1)
self.status.flags.Z = <bint>(result & 0xFF == 0)
self.status.flags.N = <bint>(result & 0x80)
if not strncmp(self.instruction.addressing_mode_name, b'imp', 4):
self.a = result
else:
self.write(self.address_absolute, result)
cdef inline bint RTI(self) nogil:
self.sp += 1
self.status.value = self.read(0x100 + self.sp)
self.status.flags.B = 0
self.sp += 1
self.pc = self.read(0x100 + self.sp)
self.sp += 1
self.pc |= self.read(0x100 + self.sp) << 8
cdef inline bint RTS(self) nogil:
self.sp += 1
self.pc = self.read(0x100 + self.sp)
self.sp += 1
self.pc |= self.read(0x100 + self.sp) << 8
cdef inline bint SBC(self) nogil:
return self.add(self.fetch() ^ 0xFF)
cdef inline bint SEC(self) nogil:
self.status.flags.C = 1
cdef inline bint SED(self) nogil:
self.status.flags.D = 1
cdef inline bint SEI(self) nogil:
self.status.flags.I = 1
cdef inline bint STA(self) nogil:
self.write(self.address_absolute, self.a)
cdef inline bint STX(self) nogil:
self.write(self.address_absolute, self.x)
cdef inline bint STY(self) nogil:
self.write(self.address_absolute, self.y)
cdef inline bint TAX(self) nogil:
self.x = self.a
cdef inline bint TAY(self) nogil:
self.y = self.a
cdef inline bint TSX(self) nogil:
self.x = self.sp
cdef inline bint TXA(self) nogil:
self.a = self.x
cdef inline bint TXS(self) nogil:
self.sp = self.x
cdef inline bint TYA(self) nogil:
self.a = self.y
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment