gorgh Posted September 4, 2021 Share Posted September 4, 2021 (edited) Hi there folks, yesterday I started learning how to code on VCS and I'm having trouble understanding how VBLANK and VSYNC work. On Atari 8 bit computers VBLANK is is generated by the hardware and it's simply an interrupt. On VCS we need to keep track of the screen lines by either counting them or setting timer. My question is... how can I tell in which scanline am I currently in? For example at the start of the program how do I know that I should do this: lda #0 sta VBLANK lda #2 sta VSYNC sta WSYNC sta WSYNC sta WSYNC ; 3 scanlines of VSYNC signal lda #0 sta VSYNC If I understand correctly the code must have exactly the number of cycles that the frame has (including WSYNC waiting) otherwise it will make the screen to flip... or won't? Or maybe writing to VBLANK stops the processor so it can start execution at the start of the VBLANK period? I'm quite confused here, any help will be appreciated, thanks! EDIT: What I am missing is understanding how to synchronise my program with the current frame, how to tell that Overscan or Vblank are taking place right now Edited September 4, 2021 by gorgh Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted September 4, 2021 Share Posted September 4, 2021 You are not syncing your code to a frame, your code is creating the frame. The number of cycles your code needs, defines where you are and how many scanlines a frame has. To create a valid frame (e.g. 262 scanlines), you have to make sure your code requires the correct number scanlines for execution. Usually that means that the VBlank and Overscan areas above and below the kernel use a timer (so that the code is does not need to sync to scanlines), while the display kernel itself counts scanlines. 2 Quote Link to comment Share on other sites More sharing options...
+Andrew Davie Posted September 5, 2021 Share Posted September 5, 2021 As Thomas says, YOU are effectively the graphics hardware that creates the correct signals that tell the TV what a frame is. The VBLANK tells the TV to reset the electron beam to the top of the screen and begin scanning. The actual timing and generation of the rest of the frame is what your code does. The simplest way is to start a timer (look at TIM64T) and wait for it to expire. Then you send the appropriate "end of frame" stuff (overscan). You can/should replace the "wait for stuff" with your code that sets the registers for playfield/sprites on each and every scanline. By adjusting the timer, you can adjust the total number of scanlines the "wait" encompasses. By adjusting the number of scanlines, you adjust the frame frequency. PAL uses 312 scanlines and is 50Hz. NTSC uses 262 scanlines and is close to 60Hz. So a typical frame you generate might be... do VBLANK, set TIM64T, do some blank scanlines, do about 200 scanlines of content, wait for timer to expire, do the overscan stuff, repeat. Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted September 5, 2021 Share Posted September 5, 2021 13 hours ago, gorgh said: On Atari 8 bit computers VBLANK is is generated by the hardware and it's simply an interrupt. On VCS we need to keep track of the screen lines by either counting them or setting timer. 13 hours ago, gorgh said: What I am missing is understanding how to synchronise my program with the current frame, how to tell that Overscan or Vblank are taking place right now The Atari 8 bit computers have an extra graphics chip, ANTIC, allowing frame synchronization and DLI's. You may find Flashback or SuperCharger BASIC a more familiar environment because it includes a soft ANTIC that can drive the TIA independently allowing you to synchronize your BASIC or Assembly program with the current frame and create display list interrupts that scroll sections of the screen in different directions and modes like the Atari 8 bit computers. Here is a recent example from SillyVenture2020+1. 1 Quote Link to comment Share on other sites More sharing options...
gorgh Posted September 5, 2021 Author Share Posted September 5, 2021 thanks for the answers. My question was about something else, though. I spoke with my friend and he told me that setting D1 of VSYNC for 3 scanlines force TV display to wait for vertical synchronisation, which means that it synchronises with a frame, could you confirm that? What about the situation where my program has let's say 260 or 258 scanlines? Quote Link to comment Share on other sites More sharing options...
gorgh Posted September 5, 2021 Author Share Posted September 5, 2021 (edited) I've got another question... I try to animate the sprites but sometimes when I run the file on Stella emolator the it works good and sometimes horizontal positioning of the sprites seem to be wrong. Here's my code: SEG ORG $F000 fineAdjustBegin .byte %01110000; Left 7 .byte %01100000; Left 6 .byte %01010000; Left 5 .byte %01000000; Left 4 .byte %00110000; Left 3 .byte %00100000; Left 2 .byte %00010000; Left 1 .byte %00000000; No movement. .byte %11110000; Right 1 .byte %11100000; Right 2 .byte %11010000; Right 3 .byte %11000000; Right 4 .byte %10110000; Right 5 .byte %10100000; Right 6 .byte %10010000; Right 7 fineAdjustTable EQU fineAdjustBegin - %11110001 PosObject sta WSYNC ; 00 Sync to start of scanline. sec ; 02 Set the carry flag so no ; borrow will be applied ; during the division. divideby15 sbc #15 ; 04 Waste the necessary amount ; of time dividing X-pos by 15! bcs divideby15 ; 06/07 ; 11/16/21/26/31/36/41/46/51/56/61/66 tay lda fineAdjustTable,y ; 13 -> Consume 5 cycles by ; guaranteeing we cross a ; page boundary sta HMP0,x sta RESP0,x ; 21/ 26/31/36/41/46/51/56/61/66/71 ; Set the rough position. rts I invoke the horizontal positioning procedure after the kernel, and it goes like this: lda #%00000010 sta VBLANK sta WSYNC lda $91 bmi decr1 incr1 inc $8c lda $8c cmp #150 bcc fine1 pha lda $91 eor #$ff sta $91 pla jmp fine1 decr1 lda $8c dec $8c cmp #2 bcs fine1 pha lda $91 eor #$ff sta $91 pla fine1 sta GRP0 ldx #0 ;player 0 jsr PosObject lda $92 bmi decr2 incr2 inc $8d lda $8d cmp #150 bcc fine2 pha lda $92 eor #$ff sta $92 pla jmp fine2 decr2 lda $8d dec $8d cmp #2 bcs fine2 pha lda $92 eor #$ff sta $92 pla fine2 sta GRP1 ldx #1 ;player 1 jsr PosObject sta WSYNC sta HMOVE ldx #0 Overscan sta WSYNC inx cpx 25 bne Overscan spr.asm spr.bin Edited September 5, 2021 by gorgh Quote Link to comment Share on other sites More sharing options...
+Andrew Davie Posted September 5, 2021 Share Posted September 5, 2021 4 hours ago, gorgh said: thanks for the answers. My question was about something else, though. I spoke with my friend and he told me that setting D1 of VSYNC for 3 scanlines force TV display to wait for vertical synchronisation, which means that it synchronises with a frame, could you confirm that? What about the situation where my program has let's say 260 or 258 scanlines? Well, you're still not quite getting it. The TV has no internal concept of "a frame". It simply responds to electrical signals of the TV signal. When you write VSYNC, you effectively adjust the signal that the TV sees, which causes an *immediate* start of new frame. There's no "waiting" by the TV, because the TV doesn't have some sort of "state" or concept of how long a frame it. It just response, as I mentioned, to the signal that it is fed. You can, therefore, send all sorts of weird stuff to it. So "what about ...260/258" -- well, most TVs will display this happily. At a higher frame rate because you are sending less scanlines per second, so your frame rate increases proportionally. The TV doesn't *know*... it is simply responding to the signal that you effectively send it by writing registers on the '2600. Again, there is no concept of the TV "waiting" for vertical synchronisation. Quote Link to comment Share on other sites More sharing options...
gorgh Posted September 5, 2021 Author Share Posted September 5, 2021 (edited) thank you for your answer, if I may I have some more questions... If there's immediate start of a new frame after the VSYNC change then what happens with the electron beam gun of the TV display? As far as I know it takes some time for the beam to return to its original start position. Edited September 5, 2021 by gorgh Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted September 5, 2021 Share Posted September 5, 2021 That exactly what's happening during VSYNC. 1 Quote Link to comment Share on other sites More sharing options...
gorgh Posted September 5, 2021 Author Share Posted September 5, 2021 thanks, all is clear to me now Quote Link to comment Share on other sites More sharing options...
+Andrew Davie Posted September 5, 2021 Share Posted September 5, 2021 41 minutes ago, gorgh said: thank you for your answer, if I may I have some more questions... If there's immediate start of a new frame after the VSYNC change then what happens with the electron beam gun of the TV display? As far as I know it takes some time for the beam to return to its original start position. Have a look at some sample kernel code for the exact process on the '2600. At the bottom of the screen, after you've drawn your scanlines (say, 200 of them), then the electron beam is turned off (via VBLANK) and you have a fairly hefty delay (the vertical blank). When that delay is done, then you toggle VSYNC (it's a 3 scanline-long toggle) that starts the new frame. You'll need to verify this next bit; but as I understand it, at that point you are at the top of the screen and effectively drawing stuff. From the Stella Programming Manual... "All horizontal timing is taken care of by hardware, but the microprocessor must “manually” control vertical timing to signal the start of the next frame. When the last line of the previous frame is detected, the microprocessor must generate 3 lines of VSYNC, 37 lines of VBLANK, 192 lines of actual TV picture, and 30 lines of overscan. " I'd say the vertical retrace of the beam happens at the start of the VSYNC, but someone may very well correct me on this one. Quote Link to comment Share on other sites More sharing options...
gorgh Posted September 5, 2021 Author Share Posted September 5, 2021 Thanks for the answer Andrew, Im passionate about vcs coding and all the help is appreciated. Now I have a problem with sprites as I mentioned above. Even when I do not change the position of the sprite it tends to change it's HMPx position..all I do is to rewrite the same position to the RESPx and HMPx but still at some runs of Stella emulator it works differently - sometimes it moves and sometimes it stays still. It's bothering me because I can't find a solution to this... all I know is that writing to HMPx couple times may alone change the position of the sprite. spr.bin Quote Link to comment Share on other sites More sharing options...
gorgh Posted September 5, 2021 Author Share Posted September 5, 2021 hehe, after examination in debugger it turned out that the decimal mode in 6507 was somehow triggered, CLD at the beginning of program helped Quote Link to comment Share on other sites More sharing options...
+Andrew Davie Posted September 6, 2021 Share Posted September 6, 2021 15 hours ago, gorgh said: hehe, after examination in debugger it turned out that the decimal mode in 6507 was somehow triggered, CLD at the beginning of program helped An easy mistake to make. A good reason to use the standard "CLEAN_START" macro for system startup. 1 Quote Link to comment Share on other sites More sharing options...
ZylonBane Posted September 11, 2021 Share Posted September 11, 2021 On 9/5/2021 at 9:19 AM, Andrew Davie said: When you write VSYNC, you effectively adjust the signal that the TV sees, which causes an *immediate* start of new frame. There's no "waiting" by the TV, because the TV doesn't have some sort of "state" or concept of how long a frame it. It just response, as I mentioned, to the signal that it is fed. You can, therefore, send all sorts of weird stuff to it. So "what about ...260/258" -- well, most TVs will display this happily. At a higher frame rate because you are sending less scanlines per second, so your frame rate increases proportionally. What you're saying sounds like you could write a 2600 game that generates a 120 FPS display (on a CRT) by only outputting, say, 100 lines per field. This seems... unlikely. Quote Link to comment Share on other sites More sharing options...
+Karl G Posted September 11, 2021 Share Posted September 11, 2021 3 minutes ago, ZylonBane said: What you're saying sounds like you could write a 2600 game that generates a 120 FPS display (on a CRT) by only outputting, say, 100 lines per field. This seems... unlikely. The frame rate varies by the number of total lines, but as you get farther from spec, less TVs will display it properly. No TV is going to display a 120 FPS display this way, I'm pretty sure. Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted September 11, 2021 Share Posted September 11, 2021 2 hours ago, ZylonBane said: What you're saying sounds like you could write a 2600 game that generates a 120 FPS display (on a CRT) by only outputting, say, 100 lines per field. This seems... unlikely. Pretty interesting idea I'll have to try that 2 hours ago, Karl G said: The frame rate varies by the number of total lines, but as you get farther from spec, less TVs will display it properly. No TV is going to display a 120 FPS display this way, I'm pretty sure. To generate a full screen NTSC display we are limited to a maximum of 60 FPS which is double the framerate of classic CRT Television, the nonstandard Atari video signal not offsetting the encapsulated 30 Hz fields in the subcarrier so they become full frames. It is possible to subdivide the frame rate from this spec. STARBLITZ plays at 60,30,20,15,12,10,8.57 and 7.5 Hz sequencing for the video and audio with the frame rate matching the Hz on all but the 60 Hz mode. When it doesn't match we get another type of flicker called motion blur, there's a thread here on the BlurBusters forum with a parallel researcher taking 120,240 and 480 Hz experiments into the stratosphere with more powerful CRT kit. Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted September 11, 2021 Share Posted September 11, 2021 14 hours ago, Karl G said: The frame rate varies by the number of total lines, but as you get farther from spec, less TVs will display it properly. No TV is going to display a 120 FPS display this way, I'm pretty sure. I created a test program when I added jitter support to Stella, it lets you interactively control the number of scanlines. The default output of 128 rainbow lines creates a total of 262 scanlines @ 60 Hz. Use your joystick to adjust the count, then hold FIRE for it to be active. Example counts and HZ: 1 = 135 total scanlines @ 116.4 Hz 64 = 198 @ 79.4 Hz 128 = 262 @ 60 Hz (NTSC) 178 = 312 @ 50 Hz (PAL, Stella needs to be in PAL mode for a stable image) 192 = 326 @ 47.9 Hz (Stella in PAL mode) 225 = 359 @ 43.5 Hz (Stella in PAL mode, largest image that's stable in Stella) 0 = 390 @ 40 Hz (0 outputs 256 rainbow scanlines) I posted some tests here with my Commodore 1084S monitor and found that 51 was stable (185 scanlines @ 85.0 Hz): You can see the VSYNC at the top of the screen, this could be hidden by adjusting the monitor to expand the image vertically. 50 and 49 were unstable on the 1084S, while from 48 down to 1 it was stable but would generate 2 images: Different displays will support a different range of total scanlines. 1 Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted September 13, 2021 Share Posted September 13, 2021 Looks like 85 Hz is working and the electron gun isn't getting reset early in the double image. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.