base:6510_instruction_timing
no way to compare when less than two revisions
Differences
This shows you the differences between two versions of the page.
— | base:6510_instruction_timing [2015-04-17 04:30] (current) – created - external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== 6510 Instruction Timing ====== | ||
+ | |||
+ | The NMOS 6500 series processors always perform at least two reads for each instruction. In addition to the operation code (opcode), they fetch the next byte. This is quite efficient, as most instructions are two or three bytes long. | ||
+ | |||
+ | The processors also use a sort of pipelining. If an instruction does not store data in memory on its last cycle, the processor can fetch the opcode of the next instruction while executing the last cycle. For instance, the instruction EOR #$FF truly takes three cycles. On the first cycle, the opcode $49 will be fetched. During the second cycle the processor decodes the opcode and fetches the parameter #$FF. On the third cycle, the processor will perform the operation and store the result to accumulator, | ||
+ | |||
+ | The following tables show what happens on the bus while executing different kinds of instructions. | ||
+ | |||
+ | |||
+ | ===== Interrupts ===== | ||
+ | |||
+ | NMI and IRQ both take 7 cycles. Their timing diagram is much like BRK's (see below). IRQ will be executed only when the I flag is clear. IRQ and BRK both set the I flag, whereas the NMI does not affect its state. | ||
+ | |||
+ | The processor will usually wait for the current instruction to complete before executing the interrupt sequence. To process the interrupt before the next instruction, | ||
+ | |||
+ | There is one exception to this rule: the BRK instruction. If a hardware interrupt (NMI or IRQ) occurs before the fourth (flags saving) cycle of BRK, the BRK instruction will be skipped, and the processor will jump to the hardware interrupt vector. This sequence will always take 7 cycles. | ||
+ | |||
+ | You do not completely lose the BRK interrupt, the B flag will be set in the pushed status register if a BRK instruction gets interrupted. When BRK and IRQ occur at the same time, this does not cause any problems, as your program will consider it as a BRK, and the IRQ would occur again after the processor returned from your BRK routine, unless you cleared the interrupt source in your BRK handler. But the simultaneous occurrence of NMI and BRK is far more fatal. If you do not check the B flag in the NMI routine and subtract two from the return address when needed, the BRK instruction will be skipped. | ||
+ | |||
+ | If the NMI and IRQ interrupts overlap each other (one interrupt occurs before fetching the interrupt vector for the other interrupt), the processor will most probably jump to the NMI vector in every case, and then jump to the IRQ vector after processing the first instruction of the NMI handler. This has not been measured yet, but the IRQ is very similar to BRK, and many sources state that the NMI has higher priority than IRQ. However, it might be that the processor takes the interrupt that comes later, i.e. you could lose an NMI interrupt if an IRQ occurred in four cycles after it. | ||
+ | |||
+ | After finishing the interrupt sequence, the processor will start to execute the first instruction of the interrupt routine. This proves that the processor uses a sort of pipelining: it finishes the current instruction (or interrupt sequence) while reading the opcode of the next instruction. | ||
+ | |||
+ | RESET does not push program counter on stack, and it lasts probably 6 cycles after deactivating the signal. Like NMI, RESET preserves all registers except PC. | ||
+ | |||
+ | |||
+ | ===== Instructions accessing the stack ===== | ||
+ | |||
+ | < | ||
+ | BRK | ||
+ | |||
+ | # address R/W description | ||
+ | --- ------- --- ----------------------------------------------- | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | | ||
+ | 3 $0100, | ||
+ | 4 $0100, | ||
+ | 5 $0100, | ||
+ | 6 | ||
+ | 7 | ||
+ | |||
+ | |||
+ | RTI | ||
+ | |||
+ | # address R/W description | ||
+ | --- ------- --- ----------------------------------------------- | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | 3 $0100, | ||
+ | 4 $0100, | ||
+ | 5 $0100, | ||
+ | 6 $0100, | ||
+ | |||
+ | |||
+ | RTS | ||
+ | |||
+ | # address R/W description | ||
+ | --- ------- --- ----------------------------------------------- | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | 3 $0100, | ||
+ | 4 $0100, | ||
+ | 5 $0100, | ||
+ | 6 PC | ||
+ | |||
+ | |||
+ | PHA, PHP | ||
+ | |||
+ | # address R/W description | ||
+ | --- ------- --- ----------------------------------------------- | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | 3 $0100, | ||
+ | |||
+ | |||
+ | PLA, PLP | ||
+ | |||
+ | # address R/W description | ||
+ | --- ------- --- ----------------------------------------------- | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | 3 $0100, | ||
+ | 4 $0100, | ||
+ | |||
+ | |||
+ | JSR | ||
+ | |||
+ | # address R/W description | ||
+ | --- ------- --- ------------------------------------------------- | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | 3 $0100, | ||
+ | 4 $0100, | ||
+ | 5 $0100, | ||
+ | 6 PC | ||
+ | byte to PCH | ||
+ | </ | ||
+ | |||
+ | ===== Accumulator or implied addressing ===== | ||
+ | |||
+ | < | ||
+ | # address R/W description | ||
+ | --- ------- --- ----------------------------------------------- | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | |||
+ | </ | ||
+ | |||
+ | ===== Immediate addressing ===== | ||
+ | |||
+ | < | ||
+ | # address R/W description | ||
+ | --- ------- --- ------------------------------------------ | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | </ | ||
+ | |||
+ | ===== Absolute addressing ===== | ||
+ | |||
+ | < | ||
+ | JMP | ||
+ | |||
+ | # address R/W description | ||
+ | --- ------- --- ------------------------------------------------- | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | 3 PC | ||
+ | byte to PCH | ||
+ | |||
+ | |||
+ | Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT, | ||
+ | LAX, NOP) | ||
+ | |||
+ | # address R/W description | ||
+ | --- ------- --- ------------------------------------------ | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | 3 PC | ||
+ | 4 address | ||
+ | |||
+ | |||
+ | | ||
+ | SLO, SRE, RLA, RRA, ISB, DCP) | ||
+ | |||
+ | # address R/W description | ||
+ | --- ------- --- ------------------------------------------ | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | 3 PC | ||
+ | 4 address | ||
+ | 5 address | ||
+ | and do the operation on it | ||
+ | 6 address | ||
+ | |||
+ | |||
+ | Write instructions (STA, STX, STY, SAX) | ||
+ | |||
+ | # address R/W description | ||
+ | --- ------- --- ------------------------------------------ | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | 3 PC | ||
+ | 4 address | ||
+ | </ | ||
+ | |||
+ | ===== Zero page addressing ===== | ||
+ | |||
+ | < | ||
+ | |||
+ | Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT, | ||
+ | LAX, NOP) | ||
+ | |||
+ | # address R/W description | ||
+ | --- ------- --- ------------------------------------------ | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | 3 address | ||
+ | |||
+ | |||
+ | | ||
+ | SLO, SRE, RLA, RRA, ISB, DCP) | ||
+ | |||
+ | # address R/W description | ||
+ | --- ------- --- ------------------------------------------ | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | 3 address | ||
+ | 4 address | ||
+ | and do the operation on it | ||
+ | 5 address | ||
+ | |||
+ | |||
+ | Write instructions (STA, STX, STY, SAX) | ||
+ | |||
+ | # address R/W description | ||
+ | --- ------- --- ------------------------------------------ | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | 3 address | ||
+ | </ | ||
+ | |||
+ | ===== Zero page indexed addressing ===== | ||
+ | |||
+ | < | ||
+ | Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT, | ||
+ | LAX, NOP) | ||
+ | |||
+ | # | ||
+ | --- --------- --- ------------------------------------------ | ||
+ | 1 | ||
+ | 2 | ||
+ | 3 | ||
+ | 4 address+I* R read from effective address | ||
+ | |||
+ | | ||
+ | |||
+ | * The high byte of the effective address is always zero, | ||
+ | i.e. page boundary crossings are not handled. | ||
+ | |||
+ | |||
+ | | ||
+ | SLO, SRE, RLA, RRA, ISB, DCP) | ||
+ | |||
+ | # | ||
+ | --- --------- --- --------------------------------------------- | ||
+ | 1 | ||
+ | 2 | ||
+ | 3 | ||
+ | 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 | ||
+ | |||
+ | Note: * The high byte of the effective address is always zero, | ||
+ | i.e. page boundary crossings are not handled. | ||
+ | |||
+ | |||
+ | Write instructions (STA, STX, STY, SAX) | ||
+ | |||
+ | # | ||
+ | --- --------- --- ------------------------------------------- | ||
+ | 1 | ||
+ | 2 | ||
+ | 3 | ||
+ | 4 address+I* W write to effective address | ||
+ | |||
+ | | ||
+ | |||
+ | * The high byte of the effective address is always zero, | ||
+ | i.e. page boundary crossings are not handled. | ||
+ | </ | ||
+ | |||
+ | ===== Absolute indexed addressing ===== | ||
+ | |||
+ | < | ||
+ | |||
+ | Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT, | ||
+ | LAX, LAE, SHS, NOP) | ||
+ | |||
+ | # | ||
+ | --- --------- --- ------------------------------------------ | ||
+ | 1 | ||
+ | 2 | ||
+ | 3 | ||
+ | add index register to low address byte, | ||
+ | | ||
+ | 4 address+I* R read from effective address, | ||
+ | fix the high byte of effective address | ||
+ | 5+ address+I | ||
+ | |||
+ | | ||
+ | |||
+ | * 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. | ||
+ | |||
+ | |||
+ | | ||
+ | SLO, SRE, RLA, RRA, ISB, DCP) | ||
+ | |||
+ | # | ||
+ | --- --------- --- ------------------------------------------ | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | 3 PC | ||
+ | add index register X to low address byte, | ||
+ | | ||
+ | 4 address+X* R read from effective address, | ||
+ | fix the high byte of effective address | ||
+ | 5 address+X | ||
+ | 6 address+X | ||
+ | and do the operation on it | ||
+ | 7 address+X | ||
+ | |||
+ | | ||
+ | at this time, i.e. it may be smaller by $100. | ||
+ | |||
+ | |||
+ | Write instructions (STA, STX, STY, SHA, SHX, SHY) | ||
+ | |||
+ | # | ||
+ | --- --------- --- ------------------------------------------ | ||
+ | 1 | ||
+ | 2 | ||
+ | 3 | ||
+ | add index register to low address byte, | ||
+ | | ||
+ | 4 address+I* R read from effective address, | ||
+ | fix the high byte of effective address | ||
+ | 5 address+I | ||
+ | |||
+ | | ||
+ | |||
+ | * 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. | ||
+ | </ | ||
+ | |||
+ | ===== Relative addressing ===== | ||
+ | |||
+ | (BCC, BCS, BNE, BEQ, BPL, BMI, BVC, BVS) | ||
+ | |||
+ | < | ||
+ | |||
+ | # | ||
+ | --- --------- --- --------------------------------------------- | ||
+ | 1 | ||
+ | 2 | ||
+ | 3 | ||
+ | If branch is taken, add operand to PCL. | ||
+ | | ||
+ | 4+ PC* | ||
+ | Fix PCH. If it did not change, increment PC. | ||
+ | 5! PC R Fetch opcode of next instruction, | ||
+ | | ||
+ | |||
+ | | ||
+ | this diagram for illustration purposes. When determining | ||
+ | real execution times, remember to subtract the last | ||
+ | cycle. | ||
+ | |||
+ | * 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. | ||
+ | </ | ||
+ | |||
+ | ===== Indexed indirect addressing ===== | ||
+ | |||
+ | < | ||
+ | Read instructions (LDA, ORA, EOR, AND, ADC, CMP, SBC, LAX) | ||
+ | |||
+ | # address | ||
+ | --- ----------- --- ------------------------------------------ | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | 3 pointer | ||
+ | 4 | ||
+ | 5 pointer+X+1 | ||
+ | 6 address | ||
+ | |||
+ | Note: The effective address is always fetched from zero page, | ||
+ | i.e. the zero page boundary crossing is not handled. | ||
+ | |||
+ | | ||
+ | |||
+ | # address | ||
+ | --- ----------- --- ------------------------------------------ | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | 3 pointer | ||
+ | 4 | ||
+ | 5 pointer+X+1 | ||
+ | 6 address | ||
+ | 7 address | ||
+ | and do the operation on it | ||
+ | 8 address | ||
+ | |||
+ | Note: The effective address is always fetched from zero page, | ||
+ | i.e. the zero page boundary crossing is not handled. | ||
+ | |||
+ | Write instructions (STA, SAX) | ||
+ | |||
+ | # address | ||
+ | --- ----------- --- ------------------------------------------ | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | 3 pointer | ||
+ | 4 | ||
+ | 5 pointer+X+1 | ||
+ | 6 address | ||
+ | |||
+ | Note: The effective address is always fetched from zero page, | ||
+ | i.e. the zero page boundary crossing is not handled. | ||
+ | </ | ||
+ | |||
+ | ===== Indirect indexed addressing ===== | ||
+ | |||
+ | < | ||
+ | Read instructions (LDA, EOR, AND, ORA, ADC, SBC, CMP) | ||
+ | |||
+ | # address | ||
+ | --- ----------- --- ------------------------------------------ | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | 3 pointer | ||
+ | 4 | ||
+ | add Y to low byte of effective address | ||
+ | 5 | ||
+ | fix high byte of effective address | ||
+ | 6+ address+Y | ||
+ | |||
+ | | ||
+ | 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. | ||
+ | |||
+ | |||
+ | | ||
+ | |||
+ | # address | ||
+ | --- ----------- --- ------------------------------------------ | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | 3 pointer | ||
+ | 4 | ||
+ | add Y to low byte of effective address | ||
+ | 5 | ||
+ | fix high byte of effective address | ||
+ | 6 | ||
+ | 7 | ||
+ | and do the operation on it | ||
+ | 8 | ||
+ | |||
+ | | ||
+ | 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 | ||
+ | --- ----------- --- ------------------------------------------ | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | 3 pointer | ||
+ | 4 | ||
+ | add Y to low byte of effective address | ||
+ | 5 | ||
+ | fix high byte of effective address | ||
+ | 6 | ||
+ | |||
+ | | ||
+ | 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. | ||
+ | </ | ||
+ | |||
+ | ===== Absolute indirect addressing ===== | ||
+ | |||
+ | (JMP) | ||
+ | |||
+ | < | ||
+ | # | ||
+ | --- --------- --- ------------------------------------------ | ||
+ | 1 | ||
+ | 2 | ||
+ | 3 | ||
+ | 4 | ||
+ | 5 pointer+1* R fetch PCH, copy latch to PCL | ||
+ | |||
+ | Note: * The PCH will always be fetched from the same page | ||
+ | than PCL, i.e. page boundary crossing is not handled. | ||
+ | </ | ||
base/6510_instruction_timing.txt · Last modified: 2015-04-17 04:30 by 127.0.0.1