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 > full screen sprite mux scroller
2011-07-18 14:43
ready.

Registered: Feb 2003
Posts: 441
full screen sprite mux scroller

hello all,
I am coding an upscroller but I'd like to put it in upper and lower border, thus I am using sprites for displaying text, just like +2K end part.

I got the main code to work: I have a stable irq (1-cycle jitter), I move up by one raster line all raster IRQs when I want to move up the text/sprites and that works. I use the $d018 trick to change sprite pointer and that works.

But I am having trouble with bad lines, which still cause flickering when I change $d018 during one of them.

How could I have the $d018 write happen when I want? I tried to move the IRQ entry point earlier in the position of a bad line, but that does not help: then $d018 changes too early and sprites are displayed wrong.

I cheked the +2K code but I could not get out with it.

thanx for help,
Ready.

2011-07-18 14:52
Mr. SID

Registered: Jan 2003
Posts: 424
Do you need the bad lines, i.e. is there gfx behind the scroll?
2011-07-18 16:49
algorithm

Registered: May 2002
Posts: 705
Are you certain that the jitter is removed when you decrease or increase the raster? Maybe at a specific position the jitter occurs.? Try a dec Inc d020.
2011-07-18 18:12
Oswald

Registered: Apr 2002
Posts: 5094
I once made a stable IRQ for this and on badlines with the d018 "trick" I was always either too late or too early, when just changing the timing by 1 cycle!

I guess the solution is to use the RMW trick, in short: using inc/dec d018 at the right horizontal "position" will recover 1-2 cycles back for you from the VIC!

if you make a calculation there's hardly any cycle for the cpu on badline+8 sprites.

GFX data needs 40 bytes read by the VIC
character pointers (badline) = another 40
Sprite pointer 8 bytes
Sprite data 24 bytes

-> 112 bytes to read. VIC runs on 2 mhz thus it has 126 cycles on a line. 126-112=14 -> 7 cpu cycles free. What eats up those 7 cycles is an answer up to someone more qualified than me.
2011-07-18 18:47
algorithm

Registered: May 2002
Posts: 705
Ready mentioned flickering hence why it may seem that when the raster interrupt is starting at a specific area of the screen (in combination of sprites) this may be causing the issue)
2011-07-18 18:51
Oswald

Registered: Apr 2002
Posts: 5094
I might be wrong, but as I said I have done a stable irq, and on a badline+8sprites I couldnt get it right. So if my code was correct 1 cycles jitter will be not enough, and he'll need to use the RMW trick (inc/dec), which recovers a few cycles from the VIC.
2011-07-18 18:57
Wile Coyote
Account closed

Registered: Mar 2004
Posts: 646
(with wishing to hijack this thread in anyway)

On the subject of full screen height scrollers, during:

GFX-Col.1 [logos]
GFX-Col.1 [Logos]

WHW Design attempted (at my request ;) a scroller that scrolls down the screen rather than up the screen. Is scrolling down more difficult than scrolling up, as the scroll is slow, something WHW admits to.
2011-07-18 19:06
algorithm

Registered: May 2002
Posts: 705
It can very well be that the RMW method is required, although i was under the assumption that changing the raster position of an interrupt can interfere somewhat with the stable IRQ timing if the stable IRQ routine is based on the raster position. Ofcourse if this is not the case, then try the RMW method.
2011-07-18 19:08
Mr. SID

Registered: Jan 2003
Posts: 424
Quoting Oswald
GFX data needs 40 bytes read by the VIC
character pointers (badline) = another 40
Sprite pointer 8 bytes
Sprite data 24 bytes

-> 112 bytes to read. VIC runs on 2 mhz thus it has 126 cycles on a line. 126-112=14 -> 7 cpu cycles free. What eats up those 7 cycles is an answer up to someone more qualified than me.


The rest of the cycles are used by the CPU. The VIC only takes over the bus during the non-border part of the screen (where it needs to read the screen data) and when it needs to read a sprite but gives the bus back to the CPU when it doesn't need it. But during most of those cycles the CPU can't read anything, because the VIC has already requested the bus again, so the CPU can only finish the current opcode and store a result.
2011-07-18 19:14
Oswald

Registered: Apr 2002
Posts: 5094
Quote: Quoting Oswald
GFX data needs 40 bytes read by the VIC
character pointers (badline) = another 40
Sprite pointer 8 bytes
Sprite data 24 bytes

-> 112 bytes to read. VIC runs on 2 mhz thus it has 126 cycles on a line. 126-112=14 -> 7 cpu cycles free. What eats up those 7 cycles is an answer up to someone more qualified than me.


The rest of the cycles are used by the CPU. The VIC only takes over the bus during the non-border part of the screen (where it needs to read the screen data) and when it needs to read a sprite but gives the bus back to the CPU when it doesn't need it. But during most of those cycles the CPU can't read anything, because the VIC has already requested the bus again, so the CPU can only finish the current opcode and store a result.


sounds correct, questin is how many cycles b4 the vic really needs the bus does this special state happen
2011-07-18 19:20
Mr. SID

Registered: Jan 2003
Posts: 424
The bus takeover takes three cycles, during which the CPU just finishes the current instruction and will halt on the first read (the one that would fetch the next opcode).
2011-07-18 19:29
Oswald

Registered: Apr 2002
Posts: 5094
that means there should be 4 cycles free for a d018 write on a badline + 8 sprites. Maybe I was doing something wrong :)
2011-07-18 20:25
ready.

Registered: Feb 2003
Posts: 441
wow, a full bunch of replies! Thanx.
Actually I experienced exaclty what Oswald said:

Quoting name
I once made a stable IRQ for this and on badlines with the d018 "trick" I was always either too late or too early, when just changing the timing by 1 cycle!


just adding one more NOP after the IRQ stabilizing code (double IRQ method) would either get rid or mantain the flickering. And the flickering flickers between correct sprite data and wrong sprite data, so it is the $d018 which seems to be "locked" if written at the wrong moment.

Since I was getting stable results by just adding 1 NOP after the stabilizing code, I thought about adding or not adding that NOP depending on the need (thus on the vertical position of the scroll). In fact the NOP sometimes is good, sometimes is bad. Adding a lookup table for the NOPs to add might do the trick.

Still I didn't quite get the RMW trick, any coding reference for it? Any demo using it? I will give it a try anyhow.

2011-07-18 20:55
algorithm

Registered: May 2002
Posts: 705
It should not flicker if the irq is stable. you may need to change the timing in the stable irq routine. dynamically adjusting when the raster IRQ takes place would require adjustments to the stable routine depending on the line/whether it matches with the same line as sprites etc. once solid, If one nop is too less and two nops is too much have you tried removing a nop and including something such as a bit $ea (3 cycles)?
2011-07-18 21:00
Skate

Registered: Jul 2003
Posts: 494
I had a similar problem using 4 sprites + sideborders. I still don't know what to do at the 168th line. 168th line is the killer for me. It comes from sprite height (21*8). even if you start from a badline (setting everything earlier), at the 168th line relative to your starting point... there you go, a badline which you need to change sprite pointers and open sideborders at the same time. tadaa.... :) Maybe answer to your question also solves my problem. I know there is a dirty trick for that but couldn't figure out myself. Since I don't examine other coders' demo codes, I was helpless. :)
2011-07-18 21:03
algorithm

Registered: May 2002
Posts: 705
@Skate: Could you not use the partial sprite method so that the sprites below have part of the bottom few data (same as the data at the bottom of the current sprites) this way you can change sprite pointers earlier rather than at a badline?
2011-07-18 21:16
algorithm

Registered: May 2002
Posts: 705
@ready. I should read properly. hehe. I had a similar issue with the multiplexer (the interference sprite underlay) in Algodancer 2 in regards to what oswald had mentioned. $d018 was either too early or too late. This was padded with i believe an inc/dec or something similar along the lines which latched $d018 to the correct area.
2011-07-19 06:24
ready.

Registered: Feb 2003
Posts: 441
@Algorithm: I could also use the trick you suggested to Skate of partial sprites, but then I'd have almost no RAM left for the VIC, since I have to double the sprites and I want to use some chars/bitmap too (@Mr.SID first post).

The sprite multiplexer is quite feasible with $d018 if you want it static, all you have to make sure is that you don't change $d018 on badlines.

I have to think more about how to solve this issue.
2011-07-19 06:33
JackAsser

Registered: Jun 2002
Posts: 2014
@Ready: For a sprite upscroller the extremly simple solution is not to pack the sprites back 2 back, nobody will notice nor care anyway. Have a gap of 2 raster lines or something and get on with it.
2011-07-19 07:17
algorithm

Registered: May 2002
Posts: 705
@ready. You dont need to double the amount of sprites. The duplication would only be around two lines of sprites.
2011-07-19 07:25
ready.

Registered: Feb 2003
Posts: 441
@algorithm: yes if I used a static screen with fixed y-sprite positions, but since sprites are moving up, a bad line can happen at any sprite line.
2011-07-19 07:29
algorithm

Registered: May 2002
Posts: 705
@ready. you can try what jackasser suggested. or if $d018 switching on badline with 8 sprites is an issue, perhaps use 7 sprites and use the $d018 method
2011-07-19 15:19
Oswald

Registered: Apr 2002
Posts: 5094
Quote: @Ready: For a sprite upscroller the extremly simple solution is not to pack the sprites back 2 back, nobody will notice nor care anyway. Have a gap of 2 raster lines or something and get on with it.

if I were going for this (I was) I'd use 5 pixel high chars, that gives you 2 rasterlines between char rows (3 char rows per sprite each 7 pixel high), and sprites can still be back 2 back. only the sprite pointer changing can be inaccurate.
2011-07-19 17:27
ready.

Registered: Feb 2003
Posts: 441
@Oswald and Jackasser: I might have to face reality and surrender to a compromise. Actually I wanted to implement something that can be "recycled", use it this time for displaying text and maybe in the future a picture or something continuos, unlike char rows. But still leave the possibility to use char displaying behind/over sprites.

I had in mind the Pearl For Pigs big sprite picture moving around the screen (borders included), but there's no char mode behind and I guess (have not checked the code) there's no bad line happening there.

I might try a few more tricks using stable raster before surrendering :)

I'd like to try the $d018 change one the line right before a bad line but after all the sprites on that line have been displayed.
2011-07-19 19:15
Oswald

Registered: Apr 2002
Posts: 5094
you may also want to try to dec/inc d018 as suggested, but make your raster stable first. then try to find the sweet spot :)
2011-07-20 13:27
ready.

Registered: Feb 2003
Posts: 441
ok, I am getting the first decent results.
First I implemetned a 100% stable raster. Used double irq method for first synch in order to start CIA1 timer A at the beginning of a raster line (loaded $dc04 with value #62).
Then my $d012 irq code looks like this:
[/code]
pha


lda $dc04
eor #63
lsr
sta *+4
bpl *+2
.fill 30, $ea
bcc *+2
bit $ea
irq_badline_patch
nop #$ff ;nop #$ff = 2 cycles, op code $80
;nop $ff = 3 cycles, op code $04

nop
bit $ea

irq_d018
lda #00 ;$d018
sta $d018
inc $d021
dec $d021

2011-07-20 13:42
ready.

Registered: Feb 2003
Posts: 441
hello again. I am getting the first good results.
I implemented a stable irq via CIA timer. I used a double irq synching routine to start CIA1 timer A at the beginning of a raster line in the upper border (to avoid bad lines). I loaded $dc04 with #62.

Then my $d012 irq looks like this (unoptimized):
irq
	pha	
	lda $dc04
	eor #63
	lsr
	sta *+4
	bpl *+2
	.fill 30, $ea
	bcc *+2
	bit $ea
irq_badline_patch
	nop #$ff ;nop #$ff = 2 cycles, op code $80
			 ;nop $ff  = 3 cycles, op code $04		
	nop
	bit $ea
irq_d018
	lda #00 
	sta $d018
	inc $d021
	dec $d021
	
	;rest of irq code: set sprite y position, new sprite pointers, badline patch for next irq.......
	


In this way $d018 is set right after the beginning of a raster line.
Bad lines are handled using a lookup table that can add (irq_badline_patch = $04) or not add (irq_badline_patch = $80) 1 cycle delay.
When bad lines cause wrong sprite pointer to display, the corresponding irq has to be anticipated by 1 raster line and eventually patched with irq_badline_patch = $04.
The tuning process is tedious as there are 21 y positions, so 21 frames to tune and for each frame there can be some bad line to fix.
Furthermore, entry irq raster line anticipation and irq_badline_patch can be fine tuned also to solve the conflict with the nmi routine I use for opening the upper/lower border.
I'll get back with results after tuning is done.
So far no need for inc/dec $d018.

Sorry for double posting, can't delete the previous one.
2011-07-21 10:17
WVL

Registered: Mar 2002
Posts: 902
Quoting ready.
I had in mind the Pearl For Pigs big sprite picture moving around the screen (borders included), but there's no char mode behind and I guess (have not checked the code) there's no bad line happening there.

No badlines there :) (if there would be, you can be 100% sure I would have shown that by displaying a nice picture ofcourse! ;))
2011-07-21 11:04
Mr. SID

Registered: Jan 2003
Posts: 424
Maybe this can give you some ideas? It has graphics behind the big sprite head.

Einstein IV
2011-07-22 04:53
ready.

Registered: Feb 2003
Posts: 441
@Mr.SID: yeah I remember that demo, amazing stuff for 1989.

Anyhow, I finally managed to get the scroller right without glitches.
Sooner or later I will put some char stuff behind. Ok, enough for today, gotta rush, as I am becoming father again :)
2011-07-22 10:01
WVL

Registered: Mar 2002
Posts: 902
Good that you got it working!

Btw, you can forget to have 8 sprites, open sideborders and a picture in the background (well, a picture with badlines at least..).

There's no multiplexer in PfP at all btw, the zoomer in the borders only has 7 sprites on the screen...
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
MWR/Visdom
SplAtterpunk
Acidchild/Padua
Tom-Cat/Nostalgia
Mike
Jammer
Guests online: 128
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 Graphicians
1 Mirage  (9.8)
2 Archmage  (9.7)
3 Pal  (9.6)
4 Carrion  (9.6)
5 Sulevi  (9.6)

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