kfink@jarthur.Claremont.EDU (Kevin Fink) (10/06/89)
My brother is working on smooth scrolling in machine language on the Commodore 64. I don't understand what he's doing, but he sent me this to post. ---------------------------------------------------------------------------- I have a problem with the smooth scrolling on the Commodore 64. I have written a program in machine language that scrolls the screen down one bit at a time in the Y-direction, using the VIC-II chip's automatic scrolling capabilities. It works fine, except for when it scrolls down every eighth bit, it jerks a little. It does this because you have to move the whole screen down one line, then tell the VIC-II to move the whole screen up seven lines. The Commodore 64 Programmer's Reference Manual says, "You can use the raster register to set up timing changes in your display so that you can get rid of screen flicker." I put a raster interrupt routine in my program to move the line down and change the VIC-II chip's setting while the raster is off the visible display area, but either I did it wrong or it didn't work. I am out of ideas and need help badly. ---------------------------------------------------------------------------- He's way out of my league in ML programming, but hopefully some of you can help. Either reply to me here at Harvey Mudd and I'll forward it to him, or if you're feeling really benevolent, mail him directly. His address is: Steve Fink 23000 Grand Ronde Rd. Grand Ronde, OR 97347 (503) 879-5354 Thanks. Kevin Fink kfink@jarthur.claremont.edu -or- kfink@hmcvax.bitnet uunet!jarthur!kfink
jb@cbmtor.UUCP (Jim Butterfield ) (10/08/89)
Question from: kfink@jarthur.Claremont.EDU (Kevin Fink)... > My brother is working on smooth scrolling in machine language ... > [he says...] "It works fine, except for when it scrolls down every > eighth bit, it jerks a little. It does this because you have to move the > whole screen down one line, then tell the VIC-II to move the whole screen > up seven lines." [more details omitted] Even if he's using a character screen, you don't have time to move a thousand characters and their corresponding color pixels within retrace time... and on high resolution, you couldn't even make the attempt. Set up two screen memory areas. While one is displaying, draw the other one (say, with the screen characters pre-moved as desired). When you're ready for that eighth-bit scroll, wait for retrace and then flip to the other screen. --jim -- -- : My boss doesn't understand me... : Jim Butterfield, Toronto : : .. and I'm my own boss! : jb@cbmtor :
bskendig@phoenix.Princeton.EDU (Brian Scott Kendig) (10/09/89)
In article <2317@jarthur.Claremont.EDU> kfink@jarthur.claremont.edu (Kevin Fink) writes: ] I have a problem with the smooth scrolling on the Commodore 64. I ]have written a program in machine language that scrolls the screen down one ]bit at a time in the Y-direction, using the VIC-II chip's automatic ]scrolling capabilities. It works fine, except for when it scrolls down every ]eighth bit, it jerks a little. It does this because you have to move the ]whole screen down one line, then tell the VIC-II to move the whole screen up ]seven lines. The Commodore 64 Programmer's Reference Manual says, "You can ]use the raster register to set up timing changes in your display so that you ]can get rid of screen flicker." I put a raster interrupt routine in my ]program to move the line down and change the VIC-II chip's setting while the ]raster is off the visible display area, but either I did it wrong or it ]didn't work. I am out of ideas and need help badly. ] ... ]help. Either reply to me here at Harvey Mudd and I'll forward it to him, or ]if you're feeling really benevolent, mail him directly. His address is: No, better yet - post replies here to the net, please! I've tried to do smooth ML scrolling on a 128 (*very* similar to doing it on a 64) several times, with no success. I'd like to be able to define a playing-field for a game, and have the field be several times larger than the size of the computer monitor. First of all, how do I represent the playfield in memory (it's a low-res color bitmap), and second of all, how do I scroll through it smoothly? Replies are more than welcome, but code samples would be *heavenly*! Thank you. << Brian >> -- | Brian S. Kendig | I feel more like I | bskendig | | Computer Engineering | did when I got here | @phoenix.Princeton.EDU | | Princeton University | than I do now. | @PUCC.BITNET | | Systems Engineering, NASA Space Station Freedom / General Electric WP3 |
byrd@husc7.HARVARD.EDU (John Byrd) (10/11/89)
There have been a number of messages requesting help on "smooth scrolling" for the 64 mode, and Jim Butterfield posted a very intelligent solution to this problem. However, his solution may have been a little difficult to understand for novice programmers. I hope that I can explain the smooth- scroll idea here in more of lay-programmers' terms. Locations $D011 and $D016 in the 64 contain the smooth-scroll information in the lower 3 bits of each of the registers. All the information on the screen may be slid up to 7 pixels (dots) to the right and 7 pixels down. So how does a programmer achieve the sliding, scrolling effect popular in games? When the screen picture has been slid to its maximum distance, e.g. when a register contains $111 in its lower 3 bits, all the characters on the screen must be moved via a software routine, and new characters must be added on to one side of the screen. At this point the register may be reset to $000. The effect is that of shifting the picture one pixel. This procedure may be reversed and used on the other register to facilitate scrolling in any direction. The programmer must watch for "flicker" when designing and writing this type of sliding routine. If the raster (present line which is being drawn on the television screen) happens to be on the screen when the screen is being moved via the software routine, the screen will flicker. This can be resolved by checking location $D012. The raster is on the screen only when the value of this location is between 51 and 251, AND when the high bit of location $D011 is OFF. Otherwise it is okay to do the software scroll. Jim Butterfield suggested that TWO separate screens should be maintained. In essence, display one screen while preparing the other for viewing; then, when the raster is off the screen, swap the viewed screen and the hidden screen. This swap can generally be done with a few POKES and PEEKS, although the BASIC language is inadvisable for this type of programming due to its lack of speed. Speed of processing is essential for raster techniques; the raster makes a pass of the screen every 1/60th of a second. I hope that this message gives a better understanding of scrolling techniques. ------------------------------------------------------------------------------ John Byrd byrd@husc7.bitnet Q-Link: John Byrd -----------------------------------------------------------------------------
leblanc@eecg.toronto.edu (Marcel LeBlanc) (10/12/89)
In article <2823@husc6.harvard.edu> byrd@husc7.UUCP (John Byrd) writes: [ much deleted ] >The programmer must watch for "flicker" when designing and writing this >type of sliding routine. If the raster (present line which is being drawn on >the television screen) happens to be on the screen when the screen is being ^^^^^^^^^^^^^^^^^^^^^^^^^^^ (difficult to avoid!) >moved via the software routine, the screen will flicker. This can be >resolved by checking location $D012. The raster is on the screen only when >the value of this location is between 51 and 251, AND when the high bit of >location $D011 is OFF. Otherwise it is okay to do the software scroll. Have you ever actually tried this (without double buffering)? As you point out later in your posting, the display is redrawn every 1/60 sec. This is a pretty tough timing problem. Try this loop: CYCLES ldy #0 2 lsrc lda screen+40,y 4/5 (4 on 216/256, 5 on 40/256) ldst sta screen,y 5 iny 2 bne lsrc 3/2 (3 on 255/256, 2 on 1/256) inc lsrc+2 6 inc ldst+2 6 lda lsrc+2 4 cmp #>[screen+$0400] 2 bcc lsrc 3/2 (3 on 3/4, 2 on 1/4) total cycles = 2 + ( (4+40/256+5+2+3)*256-1+6+6+4+2+3)*4-1 = 14577 us (not counting VIC cycles) 1/60 sec is only 16667 us. I suppose you could start a scroll *UP* 8 scan lines behind the raster, such that the scroll wouldn't catch up to the raster and would complete it's job just before the raster reaches the visible part of the screen on the next refresh. But what about a scroll *DOWN*? Starting from the bottom of the screen just after the raster has left the visible area doesn't leave enough time to complete the scroll before the raster starts displaying the top of the visible area on the next refresh! Unless the code I've listed above is *REALLY* bad, I can't think of a way to smooth *DOWN* scroll a screen unless you double buffer it. If I'm missing something obvious, please correct me! >John Byrd Marcel A. LeBlanc | University of Toronto -- Toronto, Canada "leblanc@eecg.toronto.edu" | and: LMS Technologies Ltd, Fredericton, NB, Canada ------------------------------------------------------------------------------- UUCP: uunet!utai!eecg!leblanc BITNET: leblanc@eecg.utoronto[.ca]
byrd@husc7.HARVARD.EDU (John Byrd) (10/20/89)
In article <1989Oct11.151724.18728@jarvis.csri.toronto.edu> leblanc@eecg.toronto.edu (Marcel LeBlanc) writes: >In article <2823@husc6.harvard.edu> byrd@husc7.UUCP (John Byrd) writes: > (much deleted) >>The programmer must watch for "flicker" when designing and writing this >>type of sliding routine. If the raster (present line which is being drawn on >>the television screen) happens to be on the screen when the screen is being > ^^^^^^^^^^^^^^^^^^^^^^^^^^^ (difficult to avoid!) >>moved via the software routine, the screen will flicker. This can be >>resolved by checking location $D012. The raster is on the screen only when >>the value of this location is between 51 and 251, AND when the high bit of >>location $D011 is OFF. Otherwise it is okay to do the software scroll. > >Have you ever actually tried this (without double buffering)? As you point >out later in your posting, the display is redrawn every 1/60 sec. This is a >pretty tough timing problem. Try this loop: > (huge amount of code deleted) >total cycles = 2 + ( (4+40/256+5+2+3)*256-1+6+6+4+2+3)*4-1 > = 14577 us (not counting VIC cycles) (more deletion) >Starting from the bottom of the screen just after the raster has >left the visible area doesn't leave enough time to complete the scroll >before the raster starts displaying the top of the visible area on the next >refresh! (still more deletion) Okay, guys. Marcel has a point (and can you believe how he arrived at it?) When I implemented a scroll for a game, I did it in a way only *similar* to the way listed above. The scroll was left to right, and I didn't have to worry about the down factor. More on that later. Marcel has pointed out that scrolling a screen full of characters in the time it takes the raster (television scanning line) to leave the bottom of the screen and arrive at the top would be a tight timing squeeze, at best. I did indeed use double-buffering when scrolling left and right. Double- buffering refers to drawing a picture on one screen while viewing the other screen (a "screen" being a screen-sized section of memory) and then swapping the viewed screen and the drawing screen. However, if you are willing to put up with a certain amount of flicker (and most games and demos from Europe seem to not mind a little flicker) and are confused by coding a double-buffer, then it is possible to survive with one screen. Regarding scrolling down. This algorithm does it, starting from the top of the screen and working its way down: 1. Copy present character row into buffer B. 2. Copy buffer A into present character row. 3. Copy buffer B into buffer A. 4. Go to next lower character row, if there is one; if not, end. 5. Go to step 1. But the big question: is it fast enough to get to the bottom of the screen before the raster, released at the previous bottom edge, does? I don't think so, after Marcel's analysis. It should take about 3 times as long as Marcel's routine, or about 1/20 of a second. Dang it, not fast enough! However, if it were possible to do this much computation in 1/60 of a second, and your normal down-scroll algorithm wasn't fast enough to beat the raster to the top of the screen, this one would do it. SPECIAL TO LeBlanc: Anyone who counts clock cycles is not completely sane. :) >Marcel A. LeBlanc | University of Toronto -- Toronto, Canada >"leblanc@eecg.toronto.edu"| and: LMS Technologies Ltd, Fredericton, NB, Canada >------------------------------------------------------------------------------ >UUCP: uunet!utai!eecg!leblanc BITNET: leblanc@eecg.utoronto[.ca] John Byrd "byrd@husc7.harvard.edu" I can't think of an intelligent quote....
mccaslan@cetus1a.cs.utk.edu (Donald McCasland) (10/29/89)
>Regarding scrolling down. This algorithm does it, starting from the top of >the screen and working its way down: > >1. Copy present character row into buffer B. >2. Copy buffer A into present character row. >3. Copy buffer B into buffer A. >4. Go to next lower character row, if there is one; if not, end. >5. Go to step 1. > >But the big question: is it fast enough to get to the bottom of the screen >before the raster, released at the previous bottom edge, does? I don't >think so, after Marcel's analysis. It should take about 3 times as long as >Marcel's routine, or about 1/20 of a second. Dang it, not fast enough! >However, if it were possible to do this much computation in 1/60 of a >second, and your normal down-scroll algorithm wasn't fast enough to beat >the raster to the top of the screen, this one would do it. Yes, I am an extremely unpracticed and unknowledgeable c64 user. However, (this may seem stupid) has anyone thought of waiting for the raster to be past the first 8 or so (far enough past so that the information writing wouldn't catch up to the raster) character rows on the screen, and then applying the aforementioned (I bet that's spelled wrong) buffering algorithm. In another words, what I'm trying to say is, would it be possible to draw, smoothly, the screen while the raster is on another part of the screen, rather than off the screen? Sincerely, Don McCasland The Priest at Nemi ____________________________________________________________ |"It has been rumored that the Peano Axioms of propositional| | calculus have been shown to have direct links to the | | peyote plants found in the Southwest of the U.S." | -------------------------------------------------------------
leblanc@eecg.toronto.edu (Marcel LeBlanc) (10/30/89)
In article <1274@utkcs2.cs.utk.edu> mccaslan@cetus1a.cs.utk.edu (Donald McCasland) writes: >>Regarding scrolling down. This algorithm does it, starting from the top of >>the screen and working its way down: >> >>1. Copy present character row into buffer B. >>2. Copy buffer A into present character row. >>3. Copy buffer B into buffer A. >>4. Go to next lower character row, if there is one; if not, end. >>5. Go to step 1. >> >>But the big question: is it fast enough to get to the bottom of the screen >>before the raster, released at the previous bottom edge, does? I don't >>think so, after Marcel's analysis. It should take about 3 times as long as >>Marcel's routine, or about 1/20 of a second. Dang it, not fast enough! >>However, if it were possible to do this much computation in 1/60 of a >>second, and your normal down-scroll algorithm wasn't fast enough to beat >>the raster to the top of the screen, this one would do it. > >Yes, I am an extremely unpracticed and unknowledgeable c64 user. >However, (this may seem stupid) has anyone thought of waiting for the >raster to be past the first 8 or so (far enough past so that the information >writing wouldn't catch up to the raster) character rows on the screen, and >then applying the aforementioned (I bet that's spelled wrong) buffering >algorithm. In another words, what I'm trying to say is, would it be >possible to draw, smoothly, the screen while the raster is on another >part of the screen, rather than off the screen? This is exactly what my original posting on this subject addressed. With the scroll _UP_ algorithm that I presented, I does indeed seem possible to start the scroll at the top of the screen once the raster has reached the 2nd character row, and have it complete before the raster starts the next frame. The problem is that this doesn't work with the scroll _DOWN_ algorithm. The simple algorithm that I presented started from the bottom of the screen, moving up. This doesn't allow enough time to complete the scroll before the raster starts the next frame. The scroll _DOWN_ algorithm quoted at the beginning of this posting starts at the top of the screen and moves down. Because of this, it has more time to complete the scroll. However, it still won't be able to scroll smoothly without double buffering because it performs about 3 times as many byte moves as the simpler algorithm, which requires about 3 times as many CPU cycles. > Don McCasland Marcel A. LeBlanc | University of Toronto -- Toronto, Canada "leblanc@eecg.toronto.edu" | and: LMS Technologies Ltd, Fredericton, NB, Canada ------------------------------------------------------------------------------- UUCP: uunet!utai!eecg!leblanc BITNET: leblanc@eecg.utoronto[.ca]