Jump to content
IGNORED

Somehow I end up in RAM


Recommended Posts

I think you are still not quite getting it. Consider the diagram above. In the section marked "HORIZONTAL BLANK", there is NOTHING being displayed on the TV. It's when the TV beam is starting "off the left edge of the visible screen" so to speak. When you write to WSYNC, you are synchronising the CPU with the TIA, so as soon as you do that write, the very next thing is that the TIA is at colour clock 0 and you're ready to setup the scanline - and you do the first PF0, PF1, PF2 writes before the TIA starts displaying them.

Now, the PF0 is not displayed until TIA colour clock 68. That's about 22 CPU cycles later. (68/3).
So, for those 22 CPU cycles you can start to get busy writing to PF0, PF1 and PF2. You want to write PF0 before it starts displaying (cycle 22 ish). You want to write PF1 before it starts displaying (about cycle 28), and PF2 before it starts displaying (about cycle 39). You don't need ANY sleeps in there, you just bang bang bang write PF0 PF1 and PF2.

Once you've done that, the scanline is probably approaching half-done. You need to WAIT until PF0 is finished drawing before you write the new PF0 data for the right-hand side of the screen. So, PF0 right-side starts displaying around cycle 49.  But PF0 left-side doesn't finish until cycle 28-ish.  So, you need to SLEEP until the cycle is after 28, and then BANG you write PF0 so the right-side is setup and register has the data for when the TIA gets to the right-half and starts displaying PF0. Meanwhile, you are ready to write PF1. You can't do it while the left PF1 is being displayed - and that ends on cycle 38-ish. So, make sure you SLEEP at least until cycle 38... PF1 now finished drawing on left side... and BANG you write PF1 for the right side. Note that PF1 doesn't start displaying until cycle 55-ish. But you've written to the register well before that, hopefully, so it's all setup.  And it's the same with right-side PF2. Wait until left-side PF2 has finished drawing... and... BANG.  Once you've done the three writes for the right-side... you're basically done. You are just effectively waiting for the end of the line. So at that point, you do your line count decrement, and branch back to the start of the loop.

And at the start of the loop... a WSYNC... which will halt the CPU until the very start of the NEXT scanline.

 

Edited by Andrew Davie
Link to comment
Share on other sites

On 8/27/2019 at 12:28 AM, Andrew Davie said:

I think you are still not quite getting it. Consider the diagram above. In the section marked "HORIZONTAL BLANK", there is NOTHING being displayed on the TV. It's when the TV beam is starting "off the left edge of the visible screen" so to speak. When you write to WSYNC, you are synchronising the CPU with the TIA, so as soon as you do that write, the very next thing is that the TIA is at colour clock 0 and you're ready to setup the scanline - and you do the first PF0, PF1, PF2 writes before the TIA starts displaying them.

Now, the PF0 is not displayed until TIA colour clock 68. That's about 22 CPU cycles later. (68/3).
So, for those 22 CPU cycles you can start to get busy writing to PF0, PF1 and PF2. You want to write PF0 before it starts displaying (cycle 22 ish). You want to write PF1 before it starts displaying (about cycle 28), and PF2 before it starts displaying (about cycle 39). You don't need ANY sleeps in there, you just bang bang bang write PF0 PF1 and PF2.

Once you've done that, the scanline is probably approaching half-done. You need to WAIT until PF0 is finished drawing before you write the new PF0 data for the right-hand side of the screen. So, PF0 right-side starts displaying around cycle 49.  But PF0 left-side doesn't finish until cycle 28-ish.  So, you need to SLEEP until the cycle is after 28, and then BANG you write PF0 so the right-side is setup and register has the data for when the TIA gets to the right-half and starts displaying PF0. Meanwhile, you are ready to write PF1. You can't do it while the left PF1 is being displayed - and that ends on cycle 38-ish. So, make sure you SLEEP at least until cycle 38... PF1 now finished drawing on left side... and BANG you write PF1 for the right side. Note that PF1 doesn't start displaying until cycle 55-ish. But you've written to the register well before that, hopefully, so it's all setup.  And it's the same with right-side PF2. Wait until left-side PF2 has finished drawing... and... BANG.  Once you've done the three writes for the right-side... you're basically done. You are just effectively waiting for the end of the line. So at that point, you do your line count decrement, and branch back to the start of the loop.

And at the start of the loop... a WSYNC... which will halt the CPU until the very start of the NEXT scanline.

 

Finally managed to get the titlescreen working with 1 very minor issue, my scanline count went back down to 229.? Other then the sleep's to push everything into place, nothing else had changed in the kernel. ?

 

Source: https://www.dropbox.com/sh/z6wn1u7hmrnflli/AACXSWLGETd7zEjWnhWELg4oa?dl=0

Link to comment
Share on other sites

Do you understand how to adjust the scan line count with WSYNC loops on either side of your visible content when you make changes that affect the scanline count? It should be as simple as just adjusting one or two counters every time you make changes like that.

Link to comment
Share on other sites

Also, it looks like your cycle count is off by 3 (after WSYNC).  The right PF2 data must be written after cycle 50, not 58 (which you do in your loop, but the cycle count is wrong in comments, as is your comment about when to write PF2):

 

	sta WSYNC								; (3 0) Wait for the previous line to finish
	lda pf0dataleft,y						; (4 7) load left pf0 data into the acumulator
	sta PF0									; (3 10) and store it
	lda pf1dataleft,y						; (4 14) load left pf1 data into the acumulator
	sta PF1									; (3 17) and store it
	lda pf2dataleft,y						; (4 21) load left pf2 data into the acumulator
	sta PF2									; (3 24) and store it
	lda pf0dataright,y						; (4 28) load right pf0 data into the acumulator
	sta PF0									; (3 31) and store it *MUST OCCUR AFTER CYCLE 28*
	SLEEP 2									; (2 33) sleep for 2 cycles
	lda pf1dataright,y						; (4 37) load right pf1 data into the acumulator
	sta PF1									; (3 40) and store it *MUST OCCUR AFTER CYCLE 38*
	SLEEP 12								; (12 52) sleep for 12 cycles
	lda pf2dataright,y						; (4 56) load right pf2 data into the acumulator
	sta PF2									; (3 59) and store it *MUST OCCUR AFTER CYCLE 58*
	dex										; (2 61) decrement x
	bne ScanLoop_TitleScreen				; (2/3 63/64) and repeat if we're not finished with all the scanlines.
	ldx #02									; (2 65/66) load 2 into x register
	dey										; (2 67/68) subtract one off the line counter thingy
	bne ScanLoop_TitleScreen				; (2/3 69/70 70/71) and repeat if we're not finished with all the scanlines.
	ldy #16									; (2 72/73 73/74) 16 scanlines of padding on the bottom

 

What is the remaining minor issue?

Link to comment
Share on other sites

12 hours ago, Karl G said:

Also, it looks like your cycle count is off by 3 (after WSYNC).  The right PF2 data must be written after cycle 50, not 58 (which you do in your loop, but the cycle count is wrong in comments, as is your comment about when to write PF2):

 


	sta WSYNC								; (3 0) Wait for the previous line to finish
	lda pf0dataleft,y						; (4 7) load left pf0 data into the acumulator
	sta PF0									; (3 10) and store it
	lda pf1dataleft,y						; (4 14) load left pf1 data into the acumulator
	sta PF1									; (3 17) and store it
	lda pf2dataleft,y						; (4 21) load left pf2 data into the acumulator
	sta PF2									; (3 24) and store it
	lda pf0dataright,y						; (4 28) load right pf0 data into the acumulator
	sta PF0									; (3 31) and store it *MUST OCCUR AFTER CYCLE 28*
	SLEEP 2									; (2 33) sleep for 2 cycles
	lda pf1dataright,y						; (4 37) load right pf1 data into the acumulator
	sta PF1									; (3 40) and store it *MUST OCCUR AFTER CYCLE 38*
	SLEEP 12								; (12 52) sleep for 12 cycles
	lda pf2dataright,y						; (4 56) load right pf2 data into the acumulator
	sta PF2									; (3 59) and store it *MUST OCCUR AFTER CYCLE 58*
	dex										; (2 61) decrement x
	bne ScanLoop_TitleScreen				; (2/3 63/64) and repeat if we're not finished with all the scanlines.
	ldx #02									; (2 65/66) load 2 into x register
	dey										; (2 67/68) subtract one off the line counter thingy
	bne ScanLoop_TitleScreen				; (2/3 69/70 70/71) and repeat if we're not finished with all the scanlines.
	ldy #16									; (2 72/73 73/74) 16 scanlines of padding on the bottom

 

What is the remaining minor issue?

Nothing the scanline count is the remaining issue. The thing is if you look at the number of bytes for the titlescreen and game playfield you will notice they are almost exactly the same minus the padding on the top and bottom of the titlescreen to save some space. While it's true that I could easily fix it by increasing the padding, my main concern is if both modes use the same number of scanline, why am i coming up short for the titlescreen? The

	sta WSYNC						; (3 0) Wait for the previous line to finish

resets the cycle count to 0, but additionally take 3 cycles to complete which I add to the next instruction. 

Edited by Mallard Games
Link to comment
Share on other sites

11 minutes ago, Mallard Games said:

 


	sta WSYNC

resets the cycle count to 0, but additionally take 3 cycles to complete which I add to the next instruction. 

 

No. You are not understanding what is happening.

The write to WSYNC halts the CPU. Dead. As soon as you execute that 3 cycle instruction, and the write actually happens, the CPU is halted.

It is only then re-enabled when the TIA gets to clock cycle #0 on the next line. And then the CPU starts 'working' again. And it is precisely in synch with the TIA insofar as the first instruction the CPU executes... starts with the TIA clock at zero. That's why you DO NOT count the WSYNC cycle times as part of the scanline about to be drawn.  However, it DOES count for the previous scanline - those 3 cycles are a part of that previous line, and can push the line cycle count over 76 if you are not careful!  So, again, count it as part of the previous scanline, not the current one.

  • Like 1
Link to comment
Share on other sites

12 minutes ago, Andrew Davie said:

 

No. You are not understanding what is happening.

The write to WSYNC halts the CPU. Dead. As soon as you execute that 3 cycle instruction, and the write actually happens, the CPU is halted.

It is only then re-enabled when the TIA gets to clock cycle #0 on the next line. And then the CPU starts 'working' again. And it is precisely in synch with the TIA insofar as the first instruction the CPU executes... starts with the TIA clock at zero. That's why you DO NOT count the WSYNC cycle times as part of the scanline about to be drawn.  However, it DOES count for the previous scanline - those 3 cycles are a part of that previous line, and can push the line cycle count over 76 if you are not careful!  So, again, count it as part of the previous scanline, not the current one.

Dead, as in completely stopped in it's tracks after the write happens until we're ready to start a new scanline???

on a dime horse GIF

You mean like the visual above. ^^^

 

Ok, then if that is the case then now i understand, but how exactly do you tag previous line counts or you just don't?

Link to comment
Share on other sites

3 minutes ago, Mallard Games said:

Dead, as in completely stopped in it's tracks after the write happens until we're ready to start a new scanline???

on a dime horse GIF

You mean like the visual above. ^^^

 

Ok, then if that is the case then now i understand, but how exactly do you tag previous line counts or you just don't?

 

Yep. Dead stopped.

You just have to make sure that CURRENT line (just drawn) uses no more than 73 cycles IF you are using WSYNC to wait for the start of the next line. Don't think of WSYNC as "start this line" so much as "end this line and stop until the start of the NEXT line".

Of course, you don't need to use WSYNC at all, provided your cycle count on a line is EXACTLY 76. Sometimes you need those extra 3 cycles, and so you time everything, the whole screen, to the exact cycle, using 76 cycles on each and every line. And no WSYNCs. You can do it that way if you wish, but of course it's MUCH easier to include WSYNCS and just make sure you use no more than 73 cycles/line.

Edited by Andrew Davie
clarified WSYNC
Link to comment
Share on other sites

19 hours ago, Mallard Games said:

Nothing the scanline count is the remaining issue. The thing is if you look at the number of bytes for the titlescreen and game playfield you will notice they are almost exactly the same minus the padding on the top and bottom of the titlescreen to save some space. While it's true that I could easily fix it by increasing the padding, my main concern is if both modes use the same number of scanline, why am i coming up short for the titlescreen?

Still haven't figured out why if both kernels use the same number of scanline, why one comes out short while the other is over 262.

Link to comment
Share on other sites

1 hour ago, Mallard Games said:

Still haven't figured out why if both kernels use the same number of scanline, why one comes out short while the other is over 262.

 

Branches or data crossing pages add +1 to cycle counts. If this pushes the scanline over 76 cycles (including 3 for WSYNC at end of line), then the TIA will have already started drawing the next line. The WSYNC will push it to the line after that. That's one possibility.

 

Another is that you have different values in your wait lines at beginning and/or end of the screen draws. The ones that "pad" the screens.

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...