English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Language

 
 
Thread Tools
Old 23 February 2023, 16:00   #1
8bitsten
Registered User
 
Join Date: Apr 2022
Location: Brno
Posts: 30
VBLANK wait in C

Hi,

Is the below code OK? Or is there something wrong I do not see please?

Thanks
STeN

Code:
Code:
// Actual vertical and horizontal scan line
// High byte (08-15): vertical scanline
// Low byte  (00-07): horizontal scanline
// Note: We need only MSB
volatile UBYTE* REG_VHPOSR_MSB = (UBYTE *) 0xDFF006;

// PAL uses 320x256
// But it is better for games to use the NTSC resolution 320x200 (e.g. scan lines fits a byte)
// which most games of the era used
#define SCANLINE_FIRST_INDEX 0x2C  // (44)
#define SCANLINE_NTSC_LAST_INDEX (SCANLINE_FIRST_INDEX + 199)
#define SCANLINE_PAL_LAST_INDEX (SCANLINE_FIRST_INDEX + 255)

void waitVBLANK()
{
    while ( *REG_VHPOSR_MSB != (UBYTE)( SCANLINE_NTSC_LAST_INDEX + 1 ) )
    {
    }
}
8bitsten is offline  
Old 23 February 2023, 16:59   #2
a/b
Registered User
 
Join Date: Jun 2016
Location: europe
Posts: 1,039
Looks OK to me, as long as you don't change the scanline values drastically. If it compiles to cmp.b #$f4,$dff006, bne.b <back_to_cmp> then it's OK.
a/b is online now  
Old 23 February 2023, 17:32   #3
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
Scanline_pal_last_index

Although the comparison with
SCANLINE_PAL_LAST_INDEX
wouldn't work so well.
phx is offline  
Old 23 February 2023, 18:32   #4
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,233
The easiest way to wait for the vertical blank is to call WaitTOF() of the graphics.library. Unlike your approach it does not even burn CPU cycles. Essentially, it enqueues your task into a wait list which the graphics.library will trigger in its vertical blank interrupt processing, and the CPU is free to do a lot more useful things than idling.
Thomas Richter is offline  
Old 23 February 2023, 18:58   #5
paraj
Registered User
 
paraj's Avatar
 
Join Date: Feb 2017
Location: Denmark
Posts: 1,105
One downside of WaitTOF is that top of frame is later than end of the displayed area (which it looks like OP is actually going for). Then there's WaitBOVP of course, but that burns cycles (or at at least the docs says it does), and also assumes that the game is system friendly. But yes, definitely WaitTOF is the place to go unless there are other considerations.

N.B. If you're using VBCC it (currently at least) generates better code if you use:
Code:
#define REG_VHPOSR_MSB ((volatile UBYTE*)0xDFF006)
rather than a global pointer (it doesn't seem to be able to hoist the load of the pointer value outside the loop otherwise).

And note that any interrupts triggering around that line can cause you to miss the wait and have to wait one (or more) extra frames. I find that's it's usually more robust to use the copper to set a bit in INTREQ (doesn't have to cause an actual interrupt) and use that as a "bottom of frame" marker instead.
paraj is offline  
Old 23 February 2023, 20:48   #6
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,233
WaitTOF() waits for the vertical blank - and that was really the requirements of the original poster as far as I got it. That is, it is triggered by the vertical blank interrupt. WaitBOVP() burns cycles indeed, and it is not recommendable.

Just note that both calls, and the code of the OP would operate under the constraints of the system in total. That is, if there is any other task of the system that requires CPU time, or an interrupt of higher priority, then the CPU will not reach your code until some lower part of the screen.

If the screen is an RTG screen, WaitTOF() may be - depending on hardware - in perfect relation to the actual screen refresh, or in no relation to it whatsoever. The OP code would be in the second class (no relation whatsoever).

Thus, the real question is: What is the reason to wait on the vertical blank? To synchronize some on screen activity to avoid tearing? If so. double buffering and the intuition double-buffering framework ensures that always, also on graphics cards. If, however, the desire is robust timing to ensure consistent game speed, the timer.device is a much better tool for that as it operates independent of the screen mode, and the graphics hardware.
Thomas Richter is offline  
Old 02 March 2023, 12:05   #7
8bitsten
Registered User
 
Join Date: Apr 2022
Location: Brno
Posts: 30
Wow!!

Thanks for the answers. I learned so many new things. Literally EVERY answer to my question was helpful. This is a great community and great forum.

STeN
8bitsten is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Copper wait geldo79 Coders. Asm / Hardware 9 12 November 2019 09:18
Vampire V2+ or wait for V4 Glen M Amiga scene 55 08 May 2018 21:56
Wait() mritter0 Coders. C/C++ 2 17 May 2014 19:14
RTG and chipset vblank rate Mad-Matt support.WinUAE 8 26 July 2011 12:16
Wait a sec - what about Macs? Computolio Amiga scene 10 02 June 2004 07:23

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 14:48.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.07766 seconds with 13 queries