| |
lft
Registered: Jul 2007 Posts: 369 |
Useless coding riddle: Stable raster without I/O
Hi!
I came up with a technique to synchronise code to the raster position without accessing any I/O registers. It is not very efficient, and hence not very useful, but it was a nice intellectual exercise.
This is the premise: Provide a small piece of code (less than a page) that may start executing at any time. When execution reaches the end of the code, the current rasterline and cycle will be known. You may assume that sprites and interrupts are off, and that d011 has its default value (9b).
See if you can figure out how it's done! |
|
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
extra points for using LAS and TAS! :o) |
| |
Pex Mahoney Tufvesson
Registered: Sep 2003 Posts: 52 |
I think I can, but I'm not coding anything this time... Stop reading if you're not interested in my guesses... where's ROT13 when you need it? Ah, here it is! :)
Zl thrff vf gung lbh'er hfvat gur snpg gung n onqyvar jvyy unyg gur PCH qvssreragyl qrcraqvat ba jung nfz vafgehpgvba lbh'er pheeragyl qbvat. Fb, jevgr n ybbcrq pbqr jvgu gur rknpg nzbhag bs plpyrf ninvynoyr va n senzr - naq jevgr vg va fhpu jnl gung vg jvyy fybjyl "qevsg" gbjneqf gur "fgnoyr" cbfvgvba.
Correct?
---
Have a noise night!
http://mahoney.c64.org |
| |
lft
Registered: Jul 2007 Posts: 369 |
@Pex: Yep, that's the gist of it. |
| |
Flavioweb
Registered: Nov 2011 Posts: 463 |
;-------------------------------------------------------------------------------
; Main stable raster routine
; (C) 2014 by FlavioWeb/Asura
;-------------------------------------------------------------------------------
*= $0801
.WORD END_OF_PROGRAM
.WORD 2014
.BYTE $9E
.TEXT "2061"
.BYTE $00
END_OF_PROGRAM
.WORD $0000
;-------------------
SEI
WVB_01
LDA $D011
BMI WVB_01
WVB_02
LDA $D011
BPL WVB_02
;---------------------------------------
; Start raster IRQ alignment
;-------------------
LDX $D012
IRQ_ALIGN_01
CPX $D012
BEQ IRQ_ALIGN_01
;-------------------
IRQ_ALIGN_02
INX
LDY #$0A
IRQ_ALIGN_03
DEY
BNE IRQ_ALIGN_03
IRQ_ALIGN_04
CMP #$00
CPX $D012
BNE IRQ_ALIGN_02
LDY #$0B
IRQ_ALIGN_05
DEY
BNE IRQ_ALIGN_05
INC $D020 ; Here we are at cycle 58
CLI
RTS
Works on PAL.
(Sorry i'm hurry...)
=P |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
err, did you understand what the point of lfts post was? o_O |
| |
Zyron
Registered: Jan 2002 Posts: 2381 |
Obviously not. ;) |
| |
Flavioweb
Registered: Nov 2011 Posts: 463 |
Ok.
Forgot my previous post.
'Without access I/O regs'. |
| |
Slammer
Registered: Feb 2004 Posts: 416 |
Seams like the solution is combining Pexs hint with actual code and some kind of induction proof that ensures it always ends in the desired end state instead of an endless drift. |
| |
algorithm
Registered: May 2002 Posts: 705 |
I assume its probably using rmw instructions near/on badlines perhaps to remove jitter in stages? |
| |
Danzig
Registered: Jun 2002 Posts: 440 |
cli jsr *
worx ;) proof: One Year Crest |
| |
Slammer
Registered: Feb 2004 Posts: 416 |
My guess is that you could do it like this. Haven't tried it out, so there might be flaws...
Jevgr n ybbc jvgu rknpgyl bar ezj bcrengvba gung gnxrf gur rknpg nzbhag bs gvzr bs n senzr jura gur ezj bcrengvba fgrnyf na rkgen plpyr. Eha vg sbe rabhtu ahzore bs gvzrf gvy vg fgbcf va n fgnoyr pbaqvgvba. Jr abj xabj gur cbfvgvba bs gur ezj bcrengvba gb or bar bs 25 cbffvoyr cbfvgvbaf. Yrgf pnyy guvf cebprqher sbe 'Pnyvoengr'.
Abj nqq n qrynl sbe gur jubyr senzr zvahf 9 yvarf naq ercrng pnyvoengr ntnva. Jr ner abj ba bar bs gur svefg 24 cbffvoyr cbfvgvbaf. Ercrng guvf 25 gvzrf gb or fher gb or va cbfvgvba 1. Ceboyrz fbyirq.
Gb bcgvzvmr gur nobir lbh pbhyq bspnhfr fhogenpg zber guna avar yvarf. |
| |
Peiselulli
Registered: Oct 2006 Posts: 81 |
I think it can be done like Algorithm said before: Make a loop the fullfills the 19656 Cycles (PAL) for a frame with 25 stores to memory in it.
Program it in that way that this is only the case if these stores are just before of the bad lines. If this loop does not hit all 25 stores at right position, then is will last longer and will run over again until it is in sync.
But I'm too lazy to program it, because it is useless, sorry ... |
| |
Slammer
Registered: Feb 2004 Posts: 416 |
Peiselulli: Oh yeah and it will reach the stable condition faster. Didn't read Algos post like that though and you have to convince yourself that the possibly 25 extra cycles taken doesn't makes you miss the stable point, but I think you are right. |
| |
Fresh
Registered: Jan 2005 Posts: 101 |
Well, looks like I'm a bit late... anyway:
http://pastebin.com/PeP4BfU1
64 bytes long, probably shrinkable. |
| |
lft
Registered: Jul 2007 Posts: 369 |
@Freshness79:
It's great to see some actual code! This looks rather similar to my own solution (which happens to be 63 bytes). And the I/O registers d020 and d021 in your code can obviously be changed to addresses in RAM, for strict compliance.
I'm curious about one thing: In the large waiting loop (>7000 cycles) there's a write cycle. Did you make sure that it won't interfere with the synchronisation? |
| |
Fresh
Registered: Jan 2005 Posts: 101 |
Yes, of course I've put $d020 and $d021 just to show it works. But, now that I'm thinking about it, with a longer code I may be able to show it without touching I/O.
You're way smarter than me so I'm sure you know how, or maybe that's the way you've already implemented it. :)
About the write cycle (stx $d021), it shouldn't cause any trouble as it's misadligned compared to the INCs. |
| |
ruk
Registered: Jan 2012 Posts: 43 |
Boo! I thought that looping about $100 times would suffice, but no... 62 bytes though :)
https://gist.github.com/p-a/38abcb0091019743d55a |
| |
Fresh
Registered: Jan 2005 Posts: 101 |
Ok, this one does its job by using only two W cycles per frame. I think that's the minimum number, I doubt you can sync with one.
http://pastebin.com/HTuu4KPP
(48 bytes)
Beware, this is S*L*O*W!!! Use warp!
@ruk: hope you won't mind, I've borrowed something from your routine.
@lft: thanks for this nice challenge. And I'm still waiting a code that shows stability w/o I/O (ie no $d020 or such). |
| |
ruk
Registered: Jan 2012 Posts: 43 |
@Freshness, np, sharing is caring =)
Impressed by the size of your code! |
| |
lft
Registered: Jul 2007 Posts: 369 |
Here's my solution. I've squeezed it down a bit to 59 bytes, and it doesn't clobber S.
The code reaches "done" at the last rasterline, cycle 62, so one extra nop would bring you to the top of the screen.
I have verified that 385 iterations are enough through simulation. This gives a total execution time of about 7.7 seconds.
sei
lda #0
ldy #129 ; 385 = 256 + 129
loop0
ldx #169 ; 2
loop3
cmp (0,x) ; \_ 3210
cmp (0,x)
nop
dex
bne loop3 ; /
beq *+2 ; 3
and #1 ; 2
ora #48 ; 2
sec ; 2
loop1
jsr sub ; rrrwwr
sbc #2 ; 2
bcs loop1 ; 3/2
ldx #166 ; 2
loop4
cmp (0,x) ; \_ 3817
cmp (0,x)
cmp (0,x)
dex
bne loop4 ; /
cmp (0,x) ; 6
dey ; 2 \_ 11 (9 when leaving)
bne not0 ; 2/3
lsr ; 2
bcs done ; 2/3
back
jmp loop0 ; 3
not0
bne back ; 3 /
sub
ldx #89 ; 2
loop2
dex ; 2 \_ 444
bne loop2 ; 3/2 /
rts ; 6
done
|
| |
Fresh
Registered: Jan 2005 Posts: 101 |
This is my last one, I don't want to flood the thread. :)
It uses brk and converges a bit faster: 262 frames, about 5.2s.
Too bad that I couldn't bring it down to 256 or less...
One more thought: adding other misaligned write cycles, even though it doesn't ruin the sync process, has the side effect of slowing it down because those writes get "randomly" absorbed by the badlines.
http://pastebin.com/rLNaayPz
(63 bytes) |
| |
ruk
Registered: Jan 2012 Posts: 43 |
@lft: Brilliant as always :) I would never have thought of using JSR in favour of a plain old INC. 10/10 |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
For the record, Quiss's method with Copyfault's refinements solves the problem in 8 bytes, so it does have useful properties for sizecoding. =) |
| |
Copyfault
Registered: Dec 2001 Posts: 478 |
Quoting KrillFor the record, Quiss's method with Copyfault's refinements solves the problem in 8 bytes, so it does have useful properties for sizecoding. =) Oh nice, thanks Krill for the mention. This brought the whole thread here to my notice for the first time, so I really *do* wonder how this could have slipped through my radar for coding riddles.
Nice approaches in here, so thanks also for the pointer! |