| |
TWW
Registered: Jul 2009 Posts: 545 |
Timing Challenge
Hello everyone. Figured I'd give you a small challenge before the weekend in terms of making a timing delay routine with the least amount of bytes and without destroying any registers for the following amounts of cycles:
26 cycles delay:
pha // 3
pha // 3
pha // 3
nop // 2
bit $00 // 3
pla // 4
pla // 4
pla // 4 <- 26 cycles | 9 bytes
27 cycles delay:
pha // 3
pha // 3
pha // 3
nop // 2
nop // 2
nop // 2
pla // 4
pla // 4
pla // 4 <- 27 cycles | 9 bytes
31 cycles delay:
pha // 3
lda #%00001000 // 2
lsr // 2 2 2 2
bcc *-1 // 3 3 3 2
bit $00 // 3
pla // 4 <- 31 cycles | 9 bytes
32 cycles delay:
pha // 3
lda #%00001000 // 2
lsr // 2 2 2 2
bcc *-1 // 3 3 3 2
nop // 2
nop // 2
pla // 4 <- 32 cycles | 9 bytes
31 cycles delay:
pha // 3
lda #%00001000 // 2
lsr // 2 2 2 2
bcc *-1 // 3 3 3 2
nop // 2
nop // 2
nop // 2
pla // 4 <- 34 cycles | 10 bytes
I have posted my solutions for reference and hope to see creative (hehe got it?) solutions ;-) Have a nice weekend^^ |
|
... 20 posts hidden. Click here to view all posts.... |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Quote: You can replace three nops with cmp ($00,x) and save a byte.
Oh, good point. For some reason I was only considering BIT, which doesn't have anywhere near as many addressing modes. |
| |
Kruthers
Registered: Jul 2016 Posts: 21 |
Slight tangent, but this thread reminds me of the timing hell I was in working on Sidistic. I had to constantly adjust timing all over the place, which would cause code to adjust and cross pages, changing timing.... it was driving me nuts.
So I wrote a macro that would always use 8 bytes to burn any amount of cycles (except 2 or 4, grrr!) Always wondered if that would be useful to anyone else, though it needs to trash a register and/or a ZP location for some amounts of delay.
But what still nags me: is there some way to burn 4 cycles in 8 bytes that I missed? Obviously, without using page crossing... |
| |
Frantic
Registered: Mar 2003 Posts: 1648 |
Quote: Slight tangent, but this thread reminds me of the timing hell I was in working on Sidistic. I had to constantly adjust timing all over the place, which would cause code to adjust and cross pages, changing timing.... it was driving me nuts.
So I wrote a macro that would always use 8 bytes to burn any amount of cycles (except 2 or 4, grrr!) Always wondered if that would be useful to anyone else, though it needs to trash a register and/or a ZP location for some amounts of delay.
But what still nags me: is there some way to burn 4 cycles in 8 bytes that I missed? Obviously, without using page crossing...
The only solution (to burn 4 cycles in 8 bytes) I can think of is one of the bxx branch instructions precisely when the branch is always taken due to some known register/flag state AND crossing a page boundary, since you could then skip some bytes in 4 cycles. ....so this clearly does not adhere to your specification, but my point is just that this is the only way I can think of. |
| |
Kruthers
Registered: Jul 2016 Posts: 21 |
Quote: The only solution (to burn 4 cycles in 8 bytes) I can think of is one of the bxx branch instructions precisely when the branch is always taken due to some known register/flag state AND crossing a page boundary, since you could then skip some bytes in 4 cycles. ....so this clearly does not adhere to your specification, but my point is just that this is the only way I can think of.
Yeah, pretty much what I figured. At first I held out hope that some illegal instruction would help, but after reading groepaz' doc was surprised that there are no weird branches out of all those unused opcodes. I guess a "branch slowly" was wishful thinking. ;) |
Previous - 1 | 2 | 3 - Next |