Jump to content
IGNORED

When can VBLANK be cleared?


ZackAttack

Recommended Posts

So you are saying when you want to start drawing a picture? As far as I know, it can technically be done at any point in the scan line, but if it is during the visible part you will get a partial line at the top. Same goes for the bottom. There are probably some examples of this in the released games... Lots of times you hit WSYNC first just so you know where you're at. If you know for sure it will be cycle 74 - 76 every time, you should have no trouble.

Link to comment
Share on other sites

VBLANK is not that critical. If you enable blanking after the display has been drawn and disable at the beginning of vertical sync, that should be more than long enough. You can keep it enabled during vertical sync or even until the next display starts.

Link to comment
Share on other sites

VBLANK is not that critical. If you enable blanking after the display has been drawn and disable at the beginning of vertical sync, that should be more than long enough. You can keep it enabled during vertical sync or even until the next display starts.

 

I thought blanking was required for 37 scanlines after vertical sync to prevent the electron beam from producing artifacts on the screen while it retraced from the bottom of the screen to the top. Isn't turning it on during overscan just a convenient way of drawing black during overscan?

 

So you are saying when you want to start drawing a picture? As far as I know, it can technically be done at any point in the scan line, but if it is during the visible part you will get a partial line at the top. Same goes for the bottom. There are probably some examples of this in the released games... Lots of times you hit WSYNC first just so you know where you're at. If you know for sure it will be cycle 74 - 76 every time, you should have no trouble.

 

I'll go with this for now until I get my Encore to test with. Maybe in addition to the Harmony Encore, I should buy a CRT TV to test on too. It would suck to spend all this effort on making an 8way scrolling game engine if it doesn't work properly on the original hardware.

Link to comment
Share on other sites

 

I thought blanking was required for 37 scanlines after vertical sync to prevent the electron beam from producing artifacts on the screen while it retraced from the bottom of the screen to the top. Isn't turning it on during overscan just a convenient way of drawing black during overscan?

The blanking is mainly required for TVs to sync to the frequency. Depending on the brightness of your TV, it may roll even if you use the Atari's (only almost!) black instead of VBLANK. The artifacts do not happen on a bit more modern TVs anymore.

 

And of course it is also convenient for drawing black. :)

Link to comment
Share on other sites

Yes, you can. E.g. Stay Frosty 2 does that on the title screen.

 

It used to do that. I also used the same routine for the multicolor menu in other games. It looked OK if the brightness was correctly set:

post-3056-0-45237600-1421332067_thumb.jpg post-3056-0-15730100-1421332072_thumb.jpg

 

but if brightness was too high, you'd see the mid-screen use of VBLANK:

post-3056-0-53583400-1421332078_thumb.jpg post-3056-0-38328500-1421332083_thumb.jpg

 

All four of those are photos from my actual 2600. With some inspiration from Omegamatrix, I rewrote the routine to not use VBLANK.

 

I'll be covering the development of those routines in an upcoming entry of The Story of Stay Frosty 2. The routines were done in early December 2010, the blog entries are currently up to the midpoint of October 2010.

Edited by SpiceWare
Link to comment
Share on other sites

Thanks ill have a read of that.

 

I would like to blank the screen on the far left and right of the screen. I have a mirrored playfield and don't draw anything in the PF0 region. But I am having trouble with sprites straying over this region when they are half on and half off the playfield on either end.

Link to comment
Share on other sites

Thanks ill have a read of that.

 

I would like to blank the screen on the far left and right of the screen. I have a mirrored playfield and don't draw anything in the PF0 region. But I am having trouble with sprites straying over this region when they are half on and half off the playfield on either end.

 

That would require some amazingly timed code in every kernel. Did you try changing the object priorities? Here's an excerpt from the stella guide:

 

To make the players and missiles move behind the playfield, a "1" must be written to D2 of the CTRLPF register.

 

 

 

Link to comment
Share on other sites

Thanks ill have a read of that.

 

I would like to blank the screen on the far left and right of the screen. I have a mirrored playfield and don't draw anything in the PF0 region. But I am having trouble with sprites straying over this region when they are half on and half off the playfield on either end.

 

 

 

Don't think that'll work well as you can't set VBLANK with pixel perfect precision. It's the same issue with positioning the players, the 6507 isn't fast enough to strobe at a specific pixel location so you must use course positioning with fine-tuning adjustments via HMOVE.

 

In the menu the players are black, the color comes from the background and playfield. I used 8x wide missiles (also black) positioned on the left and right side of the multicolor image to hide the fact that VBLANK couldn't be set at exactly the right time.

Link to comment
Share on other sites

Thanks ill have a read of that.

 

I would like to blank the screen on the far left and right of the screen. I have a mirrored playfield and don't draw anything in the PF0 region. But I am having trouble with sprites straying over this region when they are half on and half off the playfield on either end.

The most common solution usually is to use 1 byte of ram to AND the bits of the sprite you don't want displayed. It costs just 3 cycles where as turning VBLANK on and off will cost you at least 6 cycles (if you can make use of an existing value in A, X, or Y), and more likely 10 cycles. Since you have a sharp vertical divide you can figure the AND value before you write the kernel.

 

 

Here is an example of a kernel that uses VBLANK to mask portions of both the left and right sides. We were making a picture of a parrot for Wiki or something, but everyone lost interest.

Link to comment
Share on other sites

I have a slightly strange sprite to hide here is an example of it being displayed

 

post-34963-0-80841700-1421356019_thumb.png

 

As you can see I am looking to hide the parts that are being shown on either side and display only the portion that is overlapping the playfield.

 

I use a masking kernel and my first thought was moving the mask up and down to draw to hide portions that are not needed.

 

Then when I saw this i though it could also prove useful in this case.

Link to comment
Share on other sites

I have a slightly strange sprite to hide here is an example of it being displayed

 

attachicon.gifDemo_000dd0dd.png

 

As you can see I am looking to hide the parts that are being shown on either side and display only the portion that is overlapping the playfield.

 

I use a masking kernel and my first thought was moving the mask up and down to draw to hide portions that are not needed.

 

Then when I saw this i though it could also prove useful in this case.

Have you tried out setting PF0 to $FF on reset and leaving it at that to see what it looks like?

Link to comment
Share on other sites

There's a few things you can do:

 

1) You are currently using 1 color for everything. If you keep it that way you could draw the skater with P1, and the railing with M1 and the Ball. To cover up the rail wraparound position P0 at pixel 143. Make COLUP0 black, and use Quad Size for NUSIZ0. P0 will be large enough to cover up the railing if you make its length a few pixels shorter.

 

This works because P0 always has priority over P1 and M1. Also before I forget I seem to recall the positioning gets delay 1 or 2 pixels in quad size so you will have to look in the debugger at what pixel position it actually is and adjust. This is a solution, although a crappy one because you lose P0 an probably M0, and restrict the color. But it is easy to implement.

 

 

2) Start splitting you kernel into vertical segments. Before you enter drawing the screen look at the position of your railing and determine if it is wrapping around the left side. If it does then you will jump into a kernel that delays enabling the railing until a third or halfway through the scanline. Specifically delay whatever object you use to draw the railing and right hand post. That takes care of the left side of the screen pretty easily. The right side is a little uglier. If you are delay an enable on the left side then you also need a few cycles on the right side or in HBLANK to disable it. Ideally you can get it to turn off the railing right at the beginning of PF0 on the right side or a couple of pixels after. I don't think it will look bad if the rail extends a few pixels further then the rest of the playfield. Kind of gives you a preview of the railing which isn't bad.

 

 

3) Split the kernel into stacked horizontal kernels.... at least two kernels. One includes the handrail, and the other is everything above or below the rail. A lot of games split the screen up into several horizontal kernels. So in a game like this it wouldn't be uncommon to have a kernel drawing the skater (or no skater), and then a second kernel to draw the handrail and or skater. The advantage is you could make your AND mask a lot shorter. The idea is you only use the AND mask inside the railing kernel. When you run into the beginning of wrap around then it kind of looks like this:

   |\
   | \
   |  \
   |   \
pppp
pppp
pppp


'p' stands for PF1 playfield

So at this point you still have some of the railing hanging off. You just build some more railing graphics that don't have the railing portion. They don't even have to be full height as the AND mask will take care of most of it. The crappy part is you'll probably need a quite a few to scroll along.

 

 

 

 

Anyhow those are some ideas off the top of my head. You might come up with something even better by combining some of these methods. I'm sure some other programmers will chime in with some ideas too. There are usually a few different ways to do it. :)

Link to comment
Share on other sites

Thanks Omega.

 

One of my first thoughts was just to shift the mask so it only draws as many rows as need displaying.However that alone would not work for the top portion of the rail where the vertical and kinked portion of the rail are drawn together.

 

For that I need a form of blanking or a custom kernel like the ones you mentioned.

Link to comment
Share on other sites

I decided to go ahead and give VBLANK a go as I have only just discovered this concept. I have managed to incorporate it into my existing kernel with a bit of rejigging to get the timings correct. For my needs I had to enable VBLANK at cycle 25 and disable it again at cycle 67 this hides my rails on both the left and right hand side of the screen when they wrap.

 

I will be trying this out on real hardware just to see if stella emulates this properly. I know if your TV brightness is set incorrectly you can see the VBLANK regions are a different colour.

 

post-34963-0-23794800-1421575603_thumb.png

 

Here is a demo binary if anyones interested. The rail and playfield are not in synch but it dosent matter for the purpose of the demo.

 

Demo.bin

 

And here is the drawing kernel code.

;===========================
.drawLoop
	sta HMOVE				; 3 - *first scanline
	
	lda pfBuffer,x 			; 4
	sta PF1 				; 3
	lda pfBuffer+1,x 		; 4
	sta PF2 				; 3 - 14

	Sleep 6
	lda #0
	sta VBLANK 				; cycle 25

	dey						; 2
	lda (playerGfxPtr),y	;5
	and (playerMaskPtr),y	;5
	sta GRP0				;3 - 13

	lda pfBuffer+2,x		; 4
	sta PF2 				; 3 - 14
	lda pfBuffer+3,x 		; 4
	sta PF1 				; 3 

	Sleep 5
	lda (railDataPtr),y		; 5
	sta VBLANK 				; cycle 67

	and (railMaskPtr),y		; 5
	sta ENAM1				; 3
	sta HMM1				; 3
	rol 					; 2
	sta ENAM0				; 3
	rol						; 2
	and #%00110000			; 2
	sta NUSIZ1				; 3 - 28

	Sleep 3
	lda #0
	sta PF1
	sta VBLANK 				; cycle 25
	sta PF2					; 3 - 8

	dey 					; 2
	beq Endframe			; 2

	lda (playerGfxPtr),y	;5
	and (playerMaskPtr),y	;5
	sta GRP0				;3 - 13
	ldx XTable,y			; 4

	Sleep 13
	lda #%00000010
	sta VBLANK 				; cycle 67
	Sleep 3 
	jmp .drawLoop			; 3 - 13
Edited by Mikes360
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...