Jump to content



0

Can you run non-cycle-predictable code in the VBL and/or overscan?


2 replies to this topic

#1 Sdw OFFLINE  

Sdw

    Space Invader

  • 48 posts
  • Location:Sweden

Posted Mon Jan 12, 2009 8:49 AM

I'm a newbie when it comes to 2600-coding, but I've got some 6502 experience from C64 coding and after spending a few hours glancing through the Andrew Davie tutorials (very good btw!), I have a general grasp of things and have got some code up and running.
However, I was wondering - is there no way to be able to run segments of code that you don't have cycle-exact predictions for? During the drawing of the screen I guess you need to be in cycle-exact mode, however in the overscan and VBL areas, I'd like to be able to do something like start a timer or set an IRQ (but the 2600 doesn't have any IRQs...?), then run some code that I know will take less than 30 rasterlines (but not EXACTLY how much) and then somehow use the timer/IRQ to get back in sync for the three lines of vertical vertical synchro or start of screen, depending on if you are in VBL or overscan.
Can this be somehow done? Or is the only solution to split your code into segments that are less one scanline of cycles and use a series of STA WSYNC and keep the line-count intact?

-edit-

Well, what do you know, I might have been onto something after all. I found this quote in the "main" 2600 programming forum:

Quote

But for the most part, the timer is usually only used to time the overscan and vertical blank periods. Set a timer, do a whole lot of stuff involving branches, then eat up the remaining time...each frame will reach the end of the loop at exactly the same time.

That is pretty much exactly how I wanted it to work. Now I need to learn how to set up the timer, what values are appropriate for a full VBL/full overscan (I'm programming for PAL)?

Edited by Sdw, Mon Jan 12, 2009 9:43 AM.


#2 supercat OFFLINE  

supercat

    Quadrunner

  • 6,367 posts

Posted Mon Jan 12, 2009 9:12 PM

View PostSdw, on Mon Jan 12, 2009 8:49 AM, said:

That is pretty much exactly how I wanted it to work. Now I need to learn how to set up the timer, what values are appropriate for a full VBL/full overscan (I'm programming for PAL)?

I would suggest using TIM64 and experimenting with values. To make it easy to detect upcoming or entry, I would suggest that instead of having INTIM count down to zero, you have it count to a value like 125 (tripping at 124). Thus, the code would be something like:
  lda #125+40 ; Experiment with this value
  sta TIM64T
...
  lda #125
 ; Next three lines are optional
  sta WSYNC
  cmp INTIM
  bcc INTIM_Wait
 ; Set 'oops' flag if desired
INTIM_Wait:
  sta WSYNC
  cmp INTIM
  bcc INTIM_Wait
Rather than calculating the TIM64T values to use, it's often easier in the age of emulation to simply experiment. Make a guess and then adjust up or down as needed.

To see if INTIM is 127 or less, you may use the instruction BIT INTIM without disturbing other registers. If the N flag is clear, that means that you have 256 or fewer cycles remaining before you should be at your VBLANK routine (180 or fewer with optional code included). Using such an approach makes it practical to have loops that run at variable speeds and which will take multiple frames to complete (Strat-O-Gems uses that technique heavily, btw).

#3 Sdw OFFLINE  

Sdw

    Space Invader

  • 48 posts
  • Location:Sweden

Posted Fri Jan 16, 2009 12:34 PM

I think I got things working:

frameloop:
   // Start of vertical blank processing
   lda #0
   sta VBLANK
   lda #2
   sta VSYNC

   // 3 scanlines of VSYNCH signal...
   sta WSYNC
   sta WSYNC
   sta WSYNC

   lda #0
   sta VSYNC		  

   // 37 scanlines of vertical blank...
   lda #127+44
   sta TIM64T
   
   // DO VARIABLE TIME STUFF HERE!!!
   
!wait:   
   lda INTIM
   and #$80
   bne !wait-
   sta WSYNC
   
   // 242 scanlines of picture here (not included)...   
   
   // end of screen - enter blanking
   lda #%01000010
   sta VBLANK		
   
   // 30 scanlines of overscan...
   lda #127+35
   sta TIM64T
   
   // DO VARIABLE TIME STUFF HERE!!!
   
!wait:   
   lda INTIM
   and #$80
   bne !wait-
   sta WSYNC

   jmp frameloop

At least in STELLA it seems to display a stable 23712 cycles/frame, which I guess means things should be OK.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users