English Amiga Board

English Amiga Board (https://eab.abime.net/index.php)
-   Coders. Tutorials (https://eab.abime.net/forumdisplay.php?f=73)
-   -   ASM: Wait for Vertical Blank (https://eab.abime.net/showthread.php?t=51928)

Asman 31 March 2010 10:49

ASM: Wait for Vertical Blank
 
I'm looking for best/accurate wait vb routine. Any examples are welcome :)

StingRay 31 March 2010 11:08

I do it like this:
Code:

.loop        move.l        $dff004,d0
        and.l        #$1ff00,d0
        cmp.l        #303<<8,d0
        bne.b        .loop


Doc Mindie 31 March 2010 12:07

what does the << in the cmp.l line do?

copperkid 31 March 2010 12:27

#303<<8 should be a shift 8 bits to the left

303 == $12f, so #$12f<<8 becomes #$12f00

given the initial
and.l #$1ff00,d0
basically the comparison is only for bits 33-16 of the value initially read in d0

why this works is a mystery to me, but I assume StingRay knows what he's doing :D


By the way, just this morning I was playing around with the exec routines to add my handler to the vertical blank interrupt, is there a lot of difference in performance?
I took and modified the code from the HRM, something on the lines of

Code:

   
    move.l  _GfxBase,a6
    jsr    _LVOOwnBlitter(a6)
    move.l  $4.w,a6
    jsr    _LVOForbid(a6)
    moveq.l #INTB_VERTB,d0
    lea    VBlankServer(pc),a1
    jsr    _LVOAddIntServer(a6)


Toni Wilen 31 March 2010 12:56

Quote:

Originally Posted by StingRay (Post 657152)
I do it like this:
Code:

.loop        move.l        $dff004,d0
        and.l        #$1ff00,d0
        cmp.l        #303<<8,d0
        bne.b        .loop


This is 100% acceptable and reliable :)

Worst you can do is to poll INTREQR VBLANK bit when VBLANK interrupt is enabled. Very unreliable.

StingRay 31 March 2010 13:51

Quote:

Originally Posted by copperkid (Post 657172)
given the initial
and.l #$1ff00,d0
basically the comparison is only for bits 33-16 of the value initially read in d0

why this works is a mystery to me, but I assume StingRay knows what he's doing :D

Bits 8-16 rather (VPOS). See VPOSR and VHPOSR documentation and you'll understand how and why it works. :)


Quote:

Originally Posted by copperkid (Post 657172)
By the way, just this morning I was playing around with the exec routines to add my handler to the vertical blank interrupt, is there a lot of difference in performance?
I took and modified the code from the HRM, something on the lines of

Code:

   
    move.l  _GfxBase,a6
    jsr    _LVOOwnBlitter(a6)
    move.l  $4.w,a6
    jsr    _LVOForbid(a6)
    moveq.l #INTB_VERTB,d0
    lea    VBlankServer(pc),a1
    jsr    _LVOAddIntServer(a6)


Nothing wrong with that, one advantage is that you don't have to care about acknowledging the IRQ (and thus you don't have to deal with interrupt related bugs that can occur on A4000's f.e.) because the OS does that for you.

Asman 31 March 2010 14:06

I find

Code:

wait_vb
.1        btst        #0,(_custom+vposr+1)
        beq        .1
.2        btst        #0,(_custom+vposr+1)
        bne        .2\@
        rts

but I'm not sure if above code is 100% acceptable and reliable. :)

Leffmann 31 March 2010 15:15

Looks perfectly fine to me, and it's both safe for all displays up to 512 scanlines and guaranteed to only run once per frame, as opposed to a single wait that might run several times if the other code in the loop finishes in less than 1 scanline.

I use this, works with any operand like WaitLine D3, #$FF, (A0)+ etc.

Code:

WaitLine  macro
.\@      move.l    vposr(a6), d0
          lsr.l    #1, d0
          lsr.w    #7, d0
          cmp.w    \1, d0
          bne      .\@
          endm


StingRay 31 March 2010 15:20

Quote:

Originally Posted by Leffmann (Post 657222)
Looks perfectly fine to me, and it's both safe for all displays up to 512 scanlines and guaranteed to only run once per frame, as opposed to a single wait that might run several times if the other code in the loop finishes in less than 1 scanline.

Which can be easily fixed:
Code:

.loop        move.l        $dff004,d0
        and.l        #$1ff00,d0
        cmp.l        #303<<8,d0
        bne.b        .loop

.loop2        move.l        $dff004,d0
        and.l        #$1ff00,d0
        cmp.l        #303<<8,d0
        beq.b        .loop2

And the likelihood that a routine needs less than 1 rasterline is not very high anyway.

Leffmann 31 March 2010 15:33

No there's not a whole lot of code that will run in less than 1 scanline, BUT there are a few very good examples that will, and many more things run under WinUAE with JIT and immediate blitter or on a faster system might as well.

Try something like a simple fade to black of a 16 color screen in 12-bit RGB on an 060 and you'll be looking at 1 scanline or less.

I'm just saying the check for the MSB switch from 1 to 0 is safe, short, and works for all programmed displays. If people wrote solid code to begin with they wouldn't have to sit in sorry hindsight when their code freaks out on faster systems, and people like you wouldn't have to sit and WHD-fix poor games that won't run on A1200 :)

StingRay 31 March 2010 15:38

Quote:

Originally Posted by Leffmann (Post 657224)
No there's not a whole lot of code that will run in less than 1 scanline, BUT there are a few very good examples that will, and many more things run under WinUAE with JIT and immediate blitter or on a faster system might as well.

I know that they exist, I wrote that the likelihood is "not very high" after all (WinUAE and JIT do not count for me!). In 99% of all cases a standard "wait for line xxx" routine does the job without wasting cycles.

Asman 08 April 2010 14:00

@Leffmann, StingRay - thanks a lot.

Is there any difference between

Code:

wait_vb_1
.1        btst        #0,(_custom+vposr+1)
        beq        .1
.2        btst        #0,(_custom+vposr+1)
        bne        .2
        rts

and

Code:

wait_vb_2
.1        btst        #0,(_custom+vposr+1)
        bne        .1
.2        btst        #0,(_custom+vposr+1)
        beq        .2
        rts

?

And second ( stupid :) ) question. Is legal to do btst on odd address _custom+vposr+1 ?

pmc 08 April 2010 14:26

@ Asman - btst when used with mem locations is btst.b so yes, testing bytes at odd mem locations is legal.

I used a btst to an odd mem address (intreqr+1) in my trackloader.

Toni Wilen 08 April 2010 19:54

Quote:

Originally Posted by Asman (Post 659253)
@Leffmann, StingRay - thanks a lot.

Is there any difference between

Code:

wait_vb_1
.1        btst        #0,(_custom+vposr+1)
        beq        .1
.2        btst        #0,(_custom+vposr+1)
        bne        .2
        rts

and

Code:

wait_vb_2
.1        btst        #0,(_custom+vposr+1)
        bne        .1
.2        btst        #0,(_custom+vposr+1)
        beq        .2
        rts

?

First waits for line 0, second waits for line 256. (it can also wait for line 512, 1024 and so on but I think this was about standard video modes :D)

Quote:

And second ( stupid :) ) question. Is legal to do btst on odd address _custom+vposr+1 ?
Technically byte read from custom register is "illegal" but has always worked perfectly fine. Everyone did that :)

Byte writes to custom registers may not work properly with all accelerator models (Blizzard 1260 for example, only to odd or even bytes, if I remember correctly)

Wepl 10 April 2010 16:24

I would avoid waiting for a fixed raster line number. Because if there are interrupts like sound via cia interrupt or also a keyboard handler which uses direct wait for ack, it may tigger not in the following frame or several frames later.

Toni Wilen 10 April 2010 17:07

Quote:

Originally Posted by Wepl (Post 659808)
I would avoid waiting for a fixed raster line number. Because if there are interrupts like sound via cia interrupt or also a keyboard handler which uses direct wait for ack, it may tigger not in the following frame or several frames later.

In worst case you get near-impossible to debug very rare display corruption if your "vblank wait" ends in the middle of display :)

There is no 100% safe way to wait for vblank if "random" interrupts are enabled.

Wepl 10 April 2010 17:24

Quote:

Originally Posted by Toni Wilen (Post 659813)
In worst case you get near-impossible to debug very rare display corruption if your "vblank wait" ends in the middle of display :)

yes, that may happen (if the code is not well synchronized and does not work properly on 68000-68060)

Quote:

Originally Posted by Toni Wilen (Post 659813)
There is no 100% safe way to wait for vblank if "random" interrupts are enabled.

yes, but it's possible to wait for the next free slot after the vblank as long as the interrupts are not eating half of the frame :)

Wepl 10 April 2010 17:29

Quote:

Originally Posted by StingRay (Post 657152)
I do it like this:
Code:

.loop        move.l        $dff004,d0
        and.l        #$1ff00,d0
        cmp.l        #303<<8,d0
        bne.b        .loop


is it guaranteed that line 303 is reached on every display mode (PAL/NTSC)?

Toni Wilen 10 April 2010 18:13

Quote:

Originally Posted by Wepl (Post 659821)
is it guaranteed that line 303 is reached on every display mode (PAL/NTSC)?

No. NTSC has 262/263 lines.

StingRay 10 April 2010 20:19

Quote:

Originally Posted by Wepl (Post 659808)
I would avoid waiting for a fixed raster line number. Because if there are interrupts like sound via cia interrupt or also a keyboard handler which uses direct wait for ack, it may tigger not in the following frame or several frames later.

I've been using this approach in countless demos which had CIA/keyboard interrupts enabled and never experienced any problem.

Quote:

Originally Posted by Wepl (Post 659821)
is it guaranteed that line 303 is reached on every display mode (PAL/NTSC)?

This is PAL only as Toni already said. TBH, I never cared about NTSC compatibility at all. ;)

Maybe a better way would be to set a flag in the VBI and poll that flag in the mainloop? Disadvantage is that you need a vertical blank interrupt though.


All times are GMT +2. The time now is 00:08.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.

Page generated in 0.05621 seconds with 11 queries