Fixed cycle delay: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
m (+else)
m (reduce X / Y alternatives length)
Line 146: Line 146:
5 bytes: {14-cycle delay code} + {7-cycle delay code}
5 bytes: {14-cycle delay code} + {7-cycle delay code}


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


Line 161: Line 156:
=== 22 cycles ===
=== 22 cycles ===


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



Revision as of 08:52, 13 March 2016

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