Created
October 12, 2021 19:07
-
-
Save Cheaterman/1c982fce6e5f1a8cb53f86f359fd605c to your computer and use it in GitHub Desktop.
cpu.pyx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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