Fixed cycle delay

From NESdev Wiki
Revision as of 08:55, 13 March 2016 by Bisqwit (talk | contribs) (formatting)
Jump to navigationJump to search

Delay code

Shortest possible CPU code that creates N cycles of delay, depending on constraints.

All branch instructions assume that no page wrap occurs.

0 cycles

0 bytes

1 cycle

Impossible

2 cycles

1 byte: NOP

3 cycles

If you can clobber S:
1 byte: PHA

If you have a zeropage address that you can write random data into:
2 bytes: STA @zp_temp

If you can clobber Z, N and V:
2 bytes: BIT $00

If you can use unofficial opcodes:
2 bytes: NOP $00 (04 00)

Else:
3 bytes: JMP * + 3

4 cycles

If you can clobber S and A:
1 byte: PLA

If you can use unofficial opcodes:
2 bytes, 1 instruction: NOP $00,X (14 00)

Else:
2 bytes, 2 instructions: 2 × NOP

5 cycles

3―4 bytes: NOP + {3-cycle delay code}

6 cycles

3 bytes: 3 × NOP

7 cycles

2 bytes: PHP
PLP

8 cycles

If you can clobber S and A:
2 bytes: 2 × PLA

If you can clobber Z, N and X:
3 bytes: TSX
PLA
TXS

Else:
4 bytes: 4 × NOP

9 cycles

3 bytes: {7-cycle delay code} + {2-cycle delay code}

10 cycles

If you can clobber Z and N (note that this does not change C or memory):
4 bytes: ROL $00
ROR $00

If the 3-cycle delay code is 2 bytes long:
4 bytes: {7-cycle delay code} + {3-cycle delay code}

Else:
5 bytes: 5 × NOP

11 cycles

3―4 bytes: {7-cycle delay code} + {4-cycle delay code}

12 cycles

If you know a memory address that contains byte $60 (RTS):
3 bytes: JSR location

If you can clobber S and A:
3 bytes: 3 × PLA

If you can clobber Z and N (note that this does not change C or memory, and that it does not depend on value of X):
4 bytes: ROL $00,X
ROR $00,X

Else:
5―6 bytes: {7-cycle delay code} + {5-cycle delay code}

13 cycles

5 bytes: {7-cycle delay code} + {6-cycle delay code}

14 cycles

If you know a memory address that contains a harmless 2-cycle instruction that fits your constraints (such as CLC, LDA #0, or NOP), followed by RTS:
3 bytes: JSR location

Else:
4 bytes: 2 × {7-cycle delay code}

15 cycles

If you know a memory address that contains a JMP that jumps to another location that contains RTS:
3 bytes: JSR location

If you know a memory address that contains a harmless 3-cycle instruction that fits your constraints (such as LDA $00), followed by RTS:
3 bytes: JSR location

Else:
4―6 bytes: {8-cycle delay code} + {7-cycle delay code}

16 cycles

If your 8-cycle delay code is 2 bytes:
4 bytes: 2 × {8-cycle delay code}

Else:
4―5 bytes: {14-cycle delay code} + {2-cycle delay code}

17 cycles

If your 15-cycle delay code is 3 bytes long:
4 bytes: {15-cycle delay code} + {2-cycle delay code}

Else:
5―7 bytes: {10-cycle delay code} + {7-cycle delay code}

18 cycles

5―6 bytes: {16-cycle delay code} + {2-cycle delay code}

19 cycles

5―8 bytes: {12-cycle delay code} + {7-cycle delay code}

20 cycles

If your 18-cycle delay code is 5 bytes long:
6 bytes: {18-cycle delay code} + {2-cycle delay code}

Else:
7 bytes: {13-cycle delay code} + {7-cycle delay code}

21 cycles

If your 14-cycle delay code is 5 bytes long:
5 bytes: {14-cycle delay code} + {7-cycle delay code}

If you can clobber Z, N and <index register> (here, assumes X):
5 bytes: LDX #4
loop: DEX
BNE loop

Else:
6 bytes: {14-cycle delay code} + {7-cycle delay code}

22 cycles

If you can clobber Z, N and <index register> (here, assumes X):
6 bytes: LDX #3
loop: NOP
DEX
BNE loop

Else: 6―8 bytes: {15-cycle delay code} + {7-cycle delay code}

23 cycles

If your 16-cycle delay code is 4 bytes long:
6 bytes: {16-cycle delay code} + {7-cycle delay code}

If your 21-cycle delay code is 5 bytes long:
6 bytes: {21-cycle delay code} + {2-cycle delay code}

Else: 6―7 bytes: {15-cycle delay code} + {7-cycle delay code}

24 cycles

If your 8-cycle delay code is 2 bytes long:
6 bytes: 3 × {8-cycle delay code}

If your 17-cycle delay code is 4 bytes long:
6 bytes: {17-cycle delay code} + {7-cycle delay code}

Option:
7―9 bytes: {22-cycle delay code} + {2-cycle delay code}

Option:
7―9 bytes: {17-cycle delay code} + {7-cycle delay code}


More

Bisqwit's 6502 delay_n macro set for ca65: http://bisqwit.iki.fi/src/6502-inline_delay.7z