Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
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: 1409
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 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: 11386
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: 5094
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: 1078
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: 1409
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
Account closed

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?
2014-01-16 15:48
Rastah Bar
Account closed

Registered: Oct 2012
Posts: 336
Correct me if I'm wrong: If you set it to 8, the counter will go like this: 8,7,6,5,4,3,2,1,8,8,7,6,...

So instead of 0 it will take on the value 8.
2014-01-16 16:11
robo

Registered: Nov 2012
Posts: 9
I already thought about something like that.
But with #8 the eor #7 will result in branch-offset = #0f.
That would be wrong, since there are only 7 adresses to branch to, so the Offset has to be 0..6.
2014-01-16 17:04
robo

Registered: Nov 2012
Posts: 9
Color Bar, its exactly like you wrote.
I did a short test in vice by setting up a timer and watching the values in the monitor.

So, is it a bug or what is going on?
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
JEZ
slimeysmine
Freeze/Blazon
Paulko64
Nordischsound/Hokuto..
Mr. Mouse/XeNTaX/G*P
Guests online: 123
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Mojo  (9.7)
4 Coma Light 13  (9.6)
5 Edge of Disgrace  (9.6)
6 What Is The Matrix 2  (9.6)
7 The Demo Coder  (9.6)
8 Uncensored  (9.6)
9 Comaland 100%  (9.6)
10 Wonderland XIV  (9.6)
Top onefile Demos
1 No Listen  (9.6)
2 Layers  (9.6)
3 Cubic Dream  (9.6)
4 Party Elk 2  (9.6)
5 Copper Booze  (9.6)
6 Dawnfall V1.1  (9.5)
7 Rainbow Connection  (9.5)
8 Onscreen 5k  (9.5)
9 Morph  (9.5)
10 Libertongo  (9.5)
Top Groups
1 Performers  (9.3)
2 Booze Design  (9.3)
3 Oxyron  (9.3)
4 Censor Design  (9.3)
5 Triad  (9.3)
Top Original Suppliers
1 Derbyshire Ram  (9.7)
2 Fungus  (9.3)
3 Black Beard  (9.2)
4 Baracuda  (9.2)
5 hedning  (9.1)

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