Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
 Welcome to our latest new user maak ! (Registered 2024-04-18) You are not logged in - nap
CSDb User Forums


Forums > C64 Coding > Stablising raster IRQ with DMA
2012-01-08 19:49
ChristopherJam

Registered: Aug 2004
Posts: 1370
Stablising raster IRQ with DMA

I was a little surprised not to see this method on codebase64, as it's really quite old. It's most useful at the top of the screen, where you can do the DMA forcing in the border, but for that very reason I find it a useful prelude to (e.g.) line crunch and other HW scrolling techniques.

The concept's fairly simple; you start a character row above the visible area, set an interrupt for a subsequent non-badline, and force a DMA to absorb the unknown number of cycles between then and end-of-row. Set $d011 back to $1b, and the screen appears as normal!

A simple example:

#define poke(addr,val)	.(:lda #val:sta addr:.)
#define doke(addr,val)	.(:lda #<val:sta addr:lda #>val:sta addr+1:.)
#define endIRQ pla:tay:pla:tax:pla:rti
#define ackIRQ pha:lda $d019:sta $d019:txa:pha:tya:pha

	*= $0801-2
	.word *+2	; load address
	.byt $0b,$08,$0a,$00,$9e,$32,$30,$36,$31,0,0,0 ; 10 sys2061
main:
	poke($d021,$04)
	sta 646
	lda#147
	jsr $ffd2
	poke($d021,0)
	poke($0400,1)  ;something to see
	poke($0428,2)

	jsr IRQstart
loop:
	inc $7e7  ; a nice untidy main loop to ensure instability!
	bpl loop
	jmp loop

IRQstart
	poke($dc0d,$7f)	; kill CIA irq
	sei
	poke($01,  $35)	; disable ROM
	poke($d01a,$01) ; enable VIC irq
	poke($d011,$1b) ; clear high bit of irq rasterline
	poke($d012,$32) ; last invisible line
	doke($fffe,irq1 ) ; set irq vector
	cli
	rts
	
irq1:
	ackIRQ
	poke($d020,$0f)   ; this is unstable!
	poke($d011,$1a)   ; force partial badline before screen starts
	poke($d020,$0b)   ; this is stable ^_^
	poke($d011,$1b)   ; trigger normal re-fetch of first row of chars
	poke($d012,$ff)   ; set end-of-screen irq
	doke($fffe,irq2 )
	endIRQ

irq2:
	ackIRQ
	;ensure first row of chars is already being displayed when badline forced by irq1
	poke($d011,$18)
	poke($d012,$32	)
	doke($fffe,irq1 )
	endIRQ


(build with Fachat's xa)


Does anyone know why this technique is so rarely mentioned?

 
... 37 posts hidden. Click here to view all posts....
 
2014-01-15 14:45
Oswald

Registered: Apr 2002
Posts: 5017
innovative method, but using a CIA timer is much less trouble. You dont have to waste so much resources, and are free to use sprites, calculating cycles to waste is simpler aswell.
2014-01-15 15:21
Rastah Bar

Registered: Oct 2012
Posts: 336
Not sure I understand you. I use $d01f only once to find the exact beam position, then I set a CIA timer that is used from then on to keep track of where the beam is.
2014-01-15 17:36
enthusi

Registered: May 2004
Posts: 674
Nice, once you know xpos exactly you can even busy loop to the next start of the line anyway
2014-01-15 23:08
Mace

Registered: May 2002
Posts: 1799
"You can even busy loop to..." WHATYAMEAN?! :-)
2014-01-15 23:22
chatGPZ

Registered: Dec 2001
Posts: 11100
Quote:
using a CIA timer is much less trouble.

actually if you consider the setup it requires, the CIA timer stuff is the most involved method of them all. and it really only makes sense when you need to sync more than once per frame. in pretty much all other cases some other method is nicer (i usually use double irq, and occasional dma forcing)
2014-01-16 07:14
Oswald

Registered: Apr 2002
Posts: 5017
my bad, I didnt read it fully, so I thought this would use merely the sprites for stabilization without timer.

gpz: if you make a demo, you can just copy paste the timer setup, and run it at the start, then you are set. Now for going like this imho it doesnt really matter how you init the timer. I use a routine by Ninja which does it in about 100 lines including irq setup

clever innovative method still, tho. easyer to code from scratch, than waiting for $d012 change and then add cycles accordingly.
2014-01-16 08:02
MagerValp

Registered: Dec 2001
Posts: 1055
Quote: Quote:
using a CIA timer is much less trouble.

actually if you consider the setup it requires, the CIA timer stuff is the most involved method of them all. and it really only makes sense when you need to sync more than once per frame. in pretty much all other cases some other method is nicer (i usually use double irq, and occasional dma forcing)


If you only stabilize once per frame and speedcode or busywait from thereon, then yes, double IRQ is all you need. It costs about 80 cycles though, so when you need to stabilize every N raster lines, there's a huge gain from using CIA timers since you can stabilize anywhere on a line. Hermit's init code on codebase64 is nice and compact and can be generalized to give you a 63 or 65 cycle counter, and it's smooth sailing after that. Conceptually I don't think it's much more complicated than the double IRQ, and not as crazy as putting a jmp instruction at $dc02-$dc04.
2014-01-16 09:03
ChristopherJam

Registered: Aug 2004
Posts: 1370
Mace wrote:
Quote:
I tried the DMA method, but results vary.
How come that it sometimes jitters while with a different timing, it's stable?
And the single cycle I change, is at a point where I'd expect it to have no effect on the stabilization.


I just had a look, and the issue is you're not writing to $d011 until you're in the right hand border - too late to force DMA.

Try replacing
	and #$07
	ora #$18
	sta $d011

with
	and #$07
	ora #$18
	sta $d021
	sta $d011
	dec $d021

and you'll see where your d011 write is occurring. Drop timeloop1's iterations by two (ie ldx#$06) and it should be fine.
2014-01-16 11:26
Rastah Bar

Registered: Oct 2012
Posts: 336
Quote: Quote:
using a CIA timer is much less trouble.

actually if you consider the setup it requires, the CIA timer stuff is the most involved method of them all. and it really only makes sense when you need to sync more than once per frame. in pretty much all other cases some other method is nicer (i usually use double irq, and occasional dma forcing)


When I was learning to make a stable raster routine, I had some difficulty understanding some of the other methods (DMA forcing in particular). So I thought about a way to directly observe/measure the beam position.

For inexperienced coders (like me) this method could be a bit easier to visualize then some of the others, even though some of these other methods are more efficient, nicer, faster, etc. Once you understand one simple method, it becomes way easier to understand more complicated ones too.

Personally, I find it always interesting to learn about different methods to achieve the same thing. That is why I started my post with "For the sake of completeness".
2014-01-16 15:22
robo

Registered: Nov 2012
Posts: 9
I have a question regarding the cia-timer method:

When setting $dc04 to #8, will the timer really count only from 7..1?
Because otherwise, hermit's Routine would fail (but I guess it does not...)

In the opposite, the Manual http://archive.6502.org/datasheets/mos_6526_cia.pdf
says, that CIA counts from the latched value (#8) to Zero. That would be 9 values, and so this setup not usable to correct a 7 cycle-jitter..

What am I missing?
Previous - 1 | 2 | 3 | 4 | 5 - Next
RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Advanced
Users Online
Soren/Camelot, MoN, ..
Guests online: 102
Top Demos
1 Next Level  (9.8)
2 Mojo  (9.7)
3 Coma Light 13  (9.7)
4 Edge of Disgrace  (9.6)
5 Comaland 100%  (9.6)
6 No Bounds  (9.6)
7 Uncensored  (9.6)
8 Wonderland XIV  (9.6)
9 The Ghost  (9.6)
10 Bromance  (9.6)
Top onefile Demos
1 It's More Fun to Com..  (9.9)
2 Party Elk 2  (9.7)
3 Cubic Dream  (9.6)
4 Copper Booze  (9.5)
5 Rainbow Connection  (9.5)
6 TRSAC, Gabber & Pebe..  (9.5)
7 Onscreen 5k  (9.5)
8 Dawnfall V1.1  (9.5)
9 Quadrants  (9.5)
10 Daah, Those Acid Pil..  (9.5)
Top Groups
1 Oxyron  (9.3)
2 Nostalgia  (9.3)
3 Booze Design  (9.3)
4 Censor Design  (9.3)
5 Crest  (9.3)
Top Fullscreen Graphicians
1 Carrion  (9.8)
2 Joe  (9.8)
3 Duce  (9.8)
4 Mirage  (9.7)
5 Facet  (9.7)

Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.047 sec.