pub struct Cpu {Show 24 fields
pub cycle: u64,
pub pc: u16,
pub bus: Bus,
pub read_cycles: Cycle,
pub write_cycles: Cycle,
pub master_clock: u64,
pub instr: Instr,
pub fetched_data: u8,
pub status: Status,
pub acc: u8,
pub x: u8,
pub y: u8,
pub sp: u8,
pub abs_addr: u16,
pub rel_addr: u16,
pub run_irq: bool,
pub prev_run_irq: bool,
pub nmi: bool,
pub prev_nmi: bool,
pub prev_nmi_pending: bool,
pub corrupted: bool,
pub region: NesRegion,
pub cycle_accurate: bool,
pub disasm: String,
}Expand description
The Central Processing Unit status and registers
Fields§
§cycle: u64§pc: u16§bus: Bus§read_cycles: Cycle§write_cycles: Cycle§master_clock: u64§instr: Instr§fetched_data: u8§status: Status§acc: u8§x: u8§y: u8§sp: u8§abs_addr: u16§rel_addr: u16§run_irq: bool§prev_run_irq: bool§nmi: bool§prev_nmi: bool§prev_nmi_pending: bool§corrupted: bool§region: NesRegion§cycle_accurate: bool§disasm: StringImplementations§
Source§impl Cpu
CPU Addressing Modes
impl Cpu
CPU Addressing Modes
The 6502 can address 64KB from 0x0000 - 0xFFFF. The high byte is usually the page and the low byte the offset into the page. There are 256 total pages of 256 bytes.
Sourcepub const INSTRUCTIONS: [Instr; 256]
pub const INSTRUCTIONS: [Instr; 256]
16x16 grid of 6502 opcodes. Matches datasheet matrix for easy lookup
Sourcepub fn acc(&mut self)
pub fn acc(&mut self)
Accumulator Addressing.
No additional data is required, but the default target will be the accumulator.
§Instructions
ASL, ROL, LSR, ROR
# address R/W description
--- ------- --- -----------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R read next instruction byte (and throw it away)Sourcepub fn imp(&mut self)
pub fn imp(&mut self)
Implied Addressing.
No additional data is required, but the default target will be the accumulator.
# address R/W description
--- ------- --- -----------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R read next instruction byte (and throw it away)Sourcepub const fn imm(&mut self)
pub const fn imm(&mut self)
Immediate Addressing.
Uses the next byte as the value, so we’ll update the abs_addr to the next byte.
# address R/W description
--- ------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch value, increment PCSourcepub fn zp0(&mut self)
pub fn zp0(&mut self)
Zero Page Addressing.
Accesses the first 0xFF bytes of the address range, so this only requires one extra byte instead of the usual two.
§Read instructions
LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT, LAX, NOP
# address R/W description
--- ------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch address, increment PC
3 address R read from effective address§Read-Modify-Write instructions
ASL, LSR, ROL, ROR, INC, DEC, SLO, SRE, RLA, RRA, ISB, DCP
# address R/W description
--- ------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch address, increment PC
3 address R read from effective address
4 address W write the value back to effective address,
and do the operation on it
5 address W write the new value to effective address§Write instructions
STA, STX, STY, SAX
# address R/W description
--- ------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch address, increment PC
3 address W write register to effective addressSourcepub fn zpx(&mut self)
pub fn zpx(&mut self)
Zero Page Addressing w/ X offset.
Same as Zero Page, but is offset by adding the x register.
§Read instructions
LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT, LAX, NOP
# address R/W description
--- --------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch address, increment PC
3 address R read from address, add index register to it
4 address+X* R read from effective address
* The high byte of the effective address is always zero,
i.e. page boundary crossings are not handled.§Read-Modify-Write instructions
ASL, LSR, ROL, ROR, INC, DEC, SLO, SRE, RLA, RRA, ISB, DCP
# address R/W description
--- --------- --- ---------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch address, increment PC
3 address R read from address, add index register X to it
4 address+X* R read from effective address
5 address+X* W write the value back to effective address,
and do the operation on it
6 address+X* W write the new value to effective address
* The high byte of the effective address is always zero,
i.e. page boundary crossings are not handled.§Write instructions
STA, STX, STY, SAX
# address R/W description
--- --------- --- -------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch address, increment PC
3 address R read from address, add index register to it
4 address+X* W write to effective address
* The high byte of the effective address is always zero,
i.e. page boundary crossings are not handled.Sourcepub fn zpy(&mut self)
pub fn zpy(&mut self)
Zero Page Addressing w/ Y offset.
Same as Zero Page, but is offset by adding the y register.
§Read instructions
LDX, LAX
# address R/W description
--- --------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch address, increment PC
3 address R read from address, add index register to it
4 address+Y* R read from effective address
* The high byte of the effective address is always zero,
i.e. page boundary crossings are not handled.§Write instructions
STX, SAX
# address R/W description
--- --------- --- -------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch address, increment PC
3 address R read from address, add index register to it
4 address+Y* W write to effective address
* The high byte of the effective address is always zero,
i.e. page boundary crossings are not handled.Sourcepub fn rel(&mut self)
pub fn rel(&mut self)
Relative Addressing.
This mode is only used by branching instructions. The address must be between -128 and +127, allowing the branching instruction to move backward or forward relative to the current program counter.
§Notes
The opcode fetch of the next instruction is included to this diagram for illustration purposes. When determining real execution times, remember to subtract the last cycle.
# address R/W description
--- --------- --- ---------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch fetched_data, increment PC
3 PC R Fetch opcode of next instruction,
If branch is taken, add fetched_data to PCL.
Otherwise increment PC.
4+ PC* R Fetch opcode of next instruction.
Fix PCH. If it did not change, increment PC.
5! PC R Fetch opcode of next instruction,
increment PC.
* The high byte of Program Counter (PCH) may be invalid
at this time, i.e. it may be smaller or bigger by $100.
+ If branch is taken, this cycle will be executed.
! If branch occurs to different page, this cycle will be
executed.Sourcepub fn abs(&mut self)
pub fn abs(&mut self)
Absolute Addressing.
Uses a full 16-bit address as the next value.
§Read instructions
LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT, LAX, NOP
# address R/W description
--- ------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch low byte of address, increment PC
3 PC R fetch high byte of address, increment PC
4 address R read from effective address§Read-Modify-Write instructions
ASL, LSR, ROL, ROR, INC, DEC, SLO, SRE, RLA, RRA, ISB, DCP
# address R/W description
--- ------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch low byte of address, increment PC
3 PC R fetch high byte of address, increment PC
4 address R read from effective address
5 address W write the value back to effective address,
and do the operation on it
6 address W write the new value to effective address§Write instructions
STA, STX, STY, SAX
# address R/W description
--- ------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch low byte of address, increment PC
3 PC R fetch high byte of address, increment PC
4 address W write register to effective addressSourcepub fn abx(&mut self)
pub fn abx(&mut self)
Absolute Address w/ X offset.
Same as Absolute, but is offset by adding the x register. If a page boundary is crossed, an additional clock is required.
§Read instructions
LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT, LAX, LAE, SHS, NOP
# address R/W description
--- --------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch low byte of address, increment PC
3 PC R fetch high byte of address,
add index register to low address byte,
increment PC
4 address+X* R read from effective address,
fix the high byte of effective address
5+ address+X R re-read from effective address
* The high byte of the effective address may be invalid
at this time, i.e. it may be smaller by $100.
+ This cycle will be executed only if the effective address
was invalid during cycle #4, i.e. page boundary was crossed.§Read-Modify-Write instructions
ASL, LSR, ROL, ROR, INC, DEC, SLO, SRE, RLA, RRA, ISB, DCP
# address R/W description
-- --------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch low byte of address, increment PC
3 PC R fetch high byte of address,
add index register X to low address byte,
increment PC
4 address+X* R read from effective address,
fix the high byte of effective address
5 address+X R re-read from effective address
6 address+X W write the value back to effective address,
and do the operation on it
7 address+X W write the new value to effective address
* The high byte of the effective address may be invalid
at this time, i.e. it may be smaller by $100.§Write instructions
STA, STX, STY, SHA, SHX, SHY
# address R/W description
-- --------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch low byte of address, increment PC
3 PC R fetch high byte of address,
add index register to low address byte,
increment PC
4 address+X* R read from effective address,
fix the high byte of effective address
5 address+X W write to effective address
* The high byte of the effective address may be invalid
at this time, i.e. it may be smaller by $100. Because
the processor cannot undo a write to an invalid
address, it always reads from the address first.Sourcepub fn aby(&mut self)
pub fn aby(&mut self)
Absolute Address w/ Y offset.
Same as Absolute, but is offset by adding the y register. If a page boundary is crossed, an additional clock is required.
§Read instructions
LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT, LAX, LAE, SHS, NOP
# address R/W description
--- --------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch low byte of address, increment PC
3 PC R fetch high byte of address,
add index register to low address byte,
increment PC
4 address+Y* R read from effective address,
fix the high byte of effective address
5+ address+Y R re-read from effective address
* The high byte of the effective address may be invalid
at this time, i.e. it may be smaller by $100.
+ This cycle will be executed only if the effective address
was invalid during cycle #4, i.e. page boundary was crossed.§Read-Modify-Write instructions
ASL, LSR, ROL, ROR, INC, DEC, SLO, SRE, RLA, RRA, ISB, DCP
# address R/W description
--- --------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch low byte of address, increment PC
3 PC R fetch high byte of address,
add index register Y to low address byte,
increment PC
4 address+Y* R read from effective address,
fix the high byte of effective address
5 address+Y R re-read from effective address
6 address+Y W write the value back to effective address,
and do the operation on it
7 address+Y W write the new value to effective address
* The high byte of the effective address may be invalid
at this time, i.e. it may be smaller by $100.§Write instructions
STA, STX, STY, SHA, SHX, SHY
# address R/W description
--- --------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch low byte of address, increment PC
3 PC R fetch high byte of address,
add index register to low address byte,
increment PC
4 address+Y* R read from effective address,
fix the high byte of effective address
5 address+Y W write to effective address
* The high byte of the effective address may be invalid
at this time, i.e. it may be smaller by $100. Because
the processor cannot undo a write to an invalid
address, it always reads from the address first.Sourcepub fn ind(&mut self)
pub fn ind(&mut self)
Indirect Addressing.
The next 16-bit address is used to get the actual 16-bit address. This instruction has a bug in the original hardware. If the lo byte is 0xFF, the hi byte would cross a page boundary. However, this doesn’t work correctly on the original hardware and instead wraps back around to 0.
§Instructions
JMP
# address R/W description
--- --------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch pointer address low, increment PC
3 PC R fetch pointer address high, increment PC
4 pointer R fetch low address to latch
5 pointer+1* R fetch PCH, copy latch to PCL
* The PCH will always be fetched from the same page
than PCL, i.e. page boundary crossing is not handled.Sourcepub fn idx(&mut self)
pub fn idx(&mut self)
Indirect X Addressing.
The next 8-bit address is offset by the X register to get the actual 16-bit address from page 0x00.
§Read instructions
LDA, ORA, EOR, AND, ADC, CMP, SBC, LAX
# address R/W description
--- ----------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch pointer address, increment PC
3 pointer R read from the address, add X to it
4 pointer+X* R fetch effective address low
5 pointer+X+1* R fetch effective address high
6 address R read from effective address
* The effective address is always fetched from zero page,
i.e. the zero page boundary crossing is not handled.§Read-Modify-Write instructions
SLO, SRE, RLA, RRA, ISB, DCP
# address R/W description
--- ----------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch pointer address, increment PC
3 pointer R read from the address, add X to it
4 pointer+X* R fetch effective address low
5 pointer+X+1* R fetch effective address high
6 address R read from effective address
7 address W write the value back to effective address,
and do the operation on it
8 address W write the new value to effective address
* The effective address is always fetched from zero page,
i.e. the zero page boundary crossing is not handled.§Write instructions
STA, SAX
# address R/W description
--- ----------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch pointer address, increment PC
3 pointer R read from the address, add X to it
4 pointer+X* R fetch effective address low
5 pointer+X+1* R fetch effective address high
6 address W write to effective address
* The effective address is always fetched from zero page,
i.e. the zero page boundary crossing is not handled.Sourcepub fn idy(&mut self)
pub fn idy(&mut self)
Indirect Y Addressing.
The next 8-bit address is read to get a 16-bit address from page 0x00, which is then offset by the Y register. If a page boundary is crossed, add a clock cycle.
§Read instructions
LDA, EOR, AND, ORA, ADC, SBC, CMP
# address R/W description
--- ----------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch pointer address, increment PC
3 pointer R fetch effective address low
4 pointer+1* R fetch effective address high,
add Y to low byte of effective address
5 address+Y+ R read from effective address,
fix high byte of effective address
6! address+Y R read from effective address
* The effective address is always fetched from zero page,
i.e. the zero page boundary crossing is not handled.
+ The high byte of the effective address may be invalid
at this time, i.e. it may be smaller by $100.
! This cycle will be executed only if the effective address
was invalid during cycle #5, i.e. page boundary was crossed.§Read-Modify-Write instructions
SLO, SRE, RLA, RRA, ISB, DCP
# address R/W description
--- ----------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch pointer address, increment PC
3 pointer R fetch effective address low
4 pointer+1* R fetch effective address high,
add Y to low byte of effective address
5 address+Y+ R read from effective address,
fix high byte of effective address
6 address+Y R re-read from effective address
7 address+Y W write the value back to effective address,
and do the operation on it
8 address+Y W write the new value to effective address
* The effective address is always fetched from zero page,
i.e. the zero page boundary crossing is not handled.
+ The high byte of the effective address may be invalid
at this time, i.e. it may be smaller by $100.§Write instructions
STA, SHA
# address R/W description
--- ----------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch pointer address, increment PC
3 pointer R fetch effective address low
4 pointer+1* R fetch effective address high,
add Y to low byte of effective address
5 address+Y+ R read from effective address,
fix high byte of effective address
6 address+Y W write to effective address
* The effective address is always fetched from zero page,
i.e. the zero page boundary crossing is not handled.
+ The high byte of the effective address may be invalid
at this time, i.e. it may be smaller by $100.Source§impl Cpu
CPU instructions
impl Cpu
CPU instructions
Sourcepub const fn jmp(&mut self)
pub const fn jmp(&mut self)
JMP: Jump to Location
# address R/W description
--- ------- --- -------------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch low address byte, increment PC
3 PC R copy low address byte to PCL, fetch high address
byte to PCHSourcepub fn jsr(&mut self)
pub fn jsr(&mut self)
JSR: Jump to Location Save Return addr
# address R/W description
--- ------- --- -------------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch low address byte, increment PC
3 $0100,S R internal operation (predecrement S?)
4 $0100,S W push PCH on stack, decrement S
5 $0100,S W push PCL on stack, decrement S
6 PC R copy low address byte to PCL, fetch high address
byte to PCHSourcepub fn rti(&mut self)
pub fn rti(&mut self)
RTI: Return from Interrupt
# address R/W description
--- ------- --- -----------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R read next instruction byte (and throw it away)
3 $0100,S R increment S
4 $0100,S R pull P from stack, increment S
5 $0100,S R pull PCL from stack, increment S
6 $0100,S R pull PCH from stackSourcepub fn rts(&mut self)
pub fn rts(&mut self)
RTS: Return from Subroutine
# address R/W description
--- ------- --- -----------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R read next instruction byte (and throw it away)
3 $0100,S R increment S
4 $0100,S R pull PCL from stack, increment S
5 $0100,S R pull PCH from stack
6 PC R increment PCSourcepub fn php(&mut self)
pub fn php(&mut self)
PHP: Push Processor Status on Stack
# address R/W description
--- ------- --- -----------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R read next instruction byte (and throw it away)
3 $0100,S W push register on stack, decrement SSourcepub fn plp(&mut self)
pub fn plp(&mut self)
PLP: Pull Processor Status from Stack
# address R/W description
--- ------- --- -----------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R read next instruction byte (and throw it away)
3 $0100,S R increment S
4 $0100,S R pull register from stackSourcepub fn pha(&mut self)
pub fn pha(&mut self)
PHA: Push A on Stack
# address R/W description
--- ------- --- -----------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R read next instruction byte (and throw it away)
3 $0100,S W push register on stack, decrement SSourcepub fn pla(&mut self)
pub fn pla(&mut self)
PLA: Pull A from Stack
# address R/W description
--- ------- --- -----------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R read next instruction byte (and throw it away)
3 $0100,S R increment S
4 $0100,S R pull register from stackSourcepub fn brk(&mut self)
pub fn brk(&mut self)
BRK: Force Break Interrupt
# address R/W description
--- ------- --- -----------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R read next instruction byte (and throw it away),
increment PC
3 $0100,S W push PCH on stack (with B flag set), decrement S
4 $0100,S W push PCL on stack, decrement S
5 $0100,S W push P on stack, decrement S
6 $FFFE R fetch PCL
7 $FFFF R fetch PCHSource§impl Cpu
impl Cpu
Sourcepub const fn region_clock_rate(region: NesRegion) -> f32
pub const fn region_clock_rate(region: NesRegion) -> f32
Returns the CPU clock rate based on NesRegion.
Sourcepub const fn clock_rate(&self) -> f32
pub const fn clock_rate(&self) -> f32
Clock rate based on currently configured NES region.
Sourcepub fn next_instr(&self) -> Instr
pub fn next_instr(&self) -> Instr
Peek at the next instruction.
pub fn nmi_pending() -> bool
pub fn set_nmi()
pub fn clear_nmi()
pub fn irqs() -> Irq
pub fn has_irq(irq: Irq) -> bool
pub fn set_irq(irq: Irq)
pub fn clear_irq(irq: Irq)
pub fn start_dmc_dma()
pub fn start_oam_dma(addr: u16)
pub fn halt_for_dma() -> bool
pub fn dma_oam_addr() -> u16
pub fn dmas_running() -> Option<(bool, bool)>
pub fn clear_dma(dma: Dma)
pub fn clear_dma_halt()
pub fn dma_dummy_read() -> bool
pub fn clear_dma_dummy_read()
Sourcepub fn irq(&mut self)
pub fn irq(&mut self)
Process an interrupted request.
https://wiki.nesdev.org/w/index.php/IRQ
§address R/W description
1 PC R fetch PCH 2 PC R fetch PCL 3 $0100,S W push PCH to stack, decrement S 4 $0100,S W push PCL to stack, decrement S 5 $0100,S W push P to stack, decrement S 6 PC R fetch low byte of interrupt vector 7 PC R fetch high byte of interrupt vector
Sourcepub fn peek_stack(&self) -> u8
pub fn peek_stack(&self) -> u8
Peek byte at the top of the stack.
Sourcepub fn peek_stack_u16(&self) -> u16
pub fn peek_stack_u16(&self) -> u16
Peek at the top of the stack.
Sourcepub fn disassemble(&mut self, pc: &mut u16) -> &str
pub fn disassemble(&mut self, pc: &mut u16) -> &str
Disassemble the instruction at the given program counter.
Sourcepub fn trace_instr(&mut self)
pub fn trace_instr(&mut self)
Logs the disassembled instruction being executed.