Proper coding for Vsync or similar functionality

Anything QL Software or Programming Related.
User avatar
grafvonb
ROM Dongle
Posts: 39
Joined: Sat Jan 05, 2019 7:54 am
Location: Frankfurt/Germany

Proper coding for Vsync or similar functionality

Postby grafvonb » Thu Feb 13, 2020 8:27 pm

For my small assembler demo "bouncing lines" I need a Vsync or similar functionality to slow down the loop and get stable redraw of the screen.
I tried the described solution brought by https://www.chibiakumas.com/68000/sinclairql.php:

Code: Select all

waitVBlank
        move.b #%11111111,$18021    ;Clear interrupt bits
waitVBlankAgain
        move.b $18021,d0            ;Read in interrupt state
        tst.b d0                    ;Wait for an interrupt
        beq waitVBlankAgain
        rts

It works with Qemulator (however very notchy).
With a real QL it does not work at all regardless the ROM version (tested with Minerva and MGG).

What is the best way to solve it? How do/did this the guys in the games/demos (as a part of "game/demo loop")?


Loving QL & ZX Spectrum & Amiga...
User avatar
tofro
QL Wafer Drive
Posts: 1880
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Proper coding for Vsync or similar functionality

Postby tofro » Thu Feb 13, 2020 8:52 pm

I dived into that when I worked on the Magnetic Scrolls port and can tell you the following:

Working or not working has obviously nothing to do with the ROM version (you're not using the ROM at all in the loop).

To get a 100% stable sync with the display, you need to enter supervisor mode and switch off interrupts - otherwise, the toggling of the timer interrupt bit in the interrupt register will cause QDOS to enter the scheduler before it even runs the loop, with all sorts of things happening that could or could not affect your timing (but very probably will).

Next, your loop doesn't test for blanking, but rather any interrupt - You should test only bit #3 instead of all bits, otherwise you'll catch various possible disturbances on expanded machines.

My code looks like that:

Code: Select all

        bset    #3,PC_INTR
intLp   move.b  PC_INTR,d1              ; wait for (any) interrupt
        btst    #3,d1
        beq     intLp                   ; no, busy wait

       


and syncs pretty well with the display.

Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
User avatar
grafvonb
ROM Dongle
Posts: 39
Joined: Sat Jan 05, 2019 7:54 am
Location: Frankfurt/Germany

Re: Proper coding for Vsync or similar functionality

Postby grafvonb » Thu Feb 13, 2020 9:12 pm

Hi Tobias, many thanks for your fast and great response!

However my problem still remains. In Qemulator my code works, using a real QL the sync does not (it flickers as it would be without the sync).

Here my code example:

Code: Select all

SCREEN  equ     $20000
PC_INTR equ     $18021

repeat  lea     sinus,a5
        lea     SCREEN,a6
loop    move.l  a6,a0
        move.l  blue,d0
        bsr     draw_ln
        lea     SCREEN,a6
        clr.w   d2
        move.b  (a5)+,d2
        cmpi    #$ff,d2
        beq     repeat       
        mulu    #$80,d2
        adda.l  d2,a6
        move.l  a6,a0
        move.l  white,d0
        bsr     draw_ln

        bset    #3,PC_INTR
intLp   move.b  PC_INTR,d1              ; wait for (any) interrupt
        btst    #3,d1
        beq     intLp                   ; no, busy wait

        jmp     loop

draw_ln
        move.l  a0,a1
        moveq   #$1f,d1
draw_ln_loop   
        move.l  d0,(a1)+
        dbeq    d1,draw_ln_loop
        rts

waitVBlank
        move.b #%11111111,$18021    ;Clear interrupt bits
waitVBlankAgain
        move.b $18021,d0            ;Read in interrupt state
        tst.b d0                    ;Wait for an interrupt
        beq waitVBlankAgain
        rts

black:  dc.l    %00000000000000000000000000000000   ;line of 8-points black
blue:   dc.l    %00000000010101010000000001010101   ;line of 8-points blue
white:  dc.l    %10101010111111111010101011111111   ;line of 8-points white

sinus:  dc.b    $32,$34,$35,$37,$39,$3b,$3c,$3e
        dc.b    $40,$41,$43,$45,$46,$48,$49,$4b
        dc.b    $4c,$4e,$4f,$51,$52,$53,$55,$56
        dc.b    $57,$58,$59,$5a,$5b,$5c,$5d,$5e
        dc.b    $5f,$60,$60,$61,$62,$62,$63,$63
        dc.b    $63,$64,$64,$64,$64,$64,$64,$64
        dc.b    $64,$64,$63,$63,$63,$62,$62,$61
        dc.b    $60,$60,$5f,$5e,$5d,$5c,$5b,$5a
        dc.b    $59,$58,$57,$56,$55,$53,$52,$51
        dc.b    $4f,$4e,$4c,$4b,$49,$48,$46,$45
        dc.b    $43,$41,$40,$3e,$3c,$3b,$39,$37
        dc.b    $35,$34,$32,$30,$2f,$2d,$2b,$29
        dc.b    $28,$26,$24,$23,$21,$1f,$1e,$1c
        dc.b    $1b,$19,$18,$16,$15,$13,$12,$11
        dc.b    $f,$e,$d,$c,$b,$a,$9,$8
        dc.b    $7,$6,$5,$4,$4,$3,$2,$2
        dc.b    $1,$1,$1,$0,$0,$0,$0,$0
        dc.b    $0,$0,$0,$0,$1,$1,$1,$2
        dc.b    $2,$3,$4,$4,$5,$6,$7,$8
        dc.b    $9,$a,$b,$c,$d,$e,$f,$11
        dc.b    $12,$13,$15,$16,$18,$19,$1b,$1c
        dc.b    $1e,$1f,$21,$23,$24,$26,$28,$29
        dc.b    $2b,$2d,$2f,$30,$32
        dc.b    $ff
Last edited by grafvonb on Fri Feb 14, 2020 5:40 am, edited 1 time in total.


Loving QL & ZX Spectrum & Amiga...
User avatar
grafvonb
ROM Dongle
Posts: 39
Joined: Sat Jan 05, 2019 7:54 am
Location: Frankfurt/Germany

Re: Proper coding for Vsync or similar functionality

Postby grafvonb » Thu Feb 13, 2020 9:17 pm

To get a 100% stable sync with the display, you need to enter supervisor mode and switch off interrupts - otherwise, the toggling of the timer interrupt bit in the interrupt register will cause QDOS to enter the scheduler before it even runs the loop, with all sorts of things happening that could or could not affect your timing (but very probably will).


Ah, this is probably the reason, isn't it?


Loving QL & ZX Spectrum & Amiga...
User avatar
tofro
QL Wafer Drive
Posts: 1880
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Proper coding for Vsync or similar functionality

Postby tofro » Thu Feb 13, 2020 9:44 pm

grafvonb wrote:
To get a 100% stable sync with the display, you need to enter supervisor mode and switch off interrupts - otherwise, the toggling of the timer interrupt bit in the interrupt register will cause QDOS to enter the scheduler before it even runs the loop, with all sorts of things happening that could or could not affect your timing (but very probably will).


Ah, this is probably the reason, isn't it?



Of course. QDOS being a multi-tasking OS will do all sorts of things in the timer interrupt that disturb your timing if you allow it to.

Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
User avatar
grafvonb
ROM Dongle
Posts: 39
Joined: Sat Jan 05, 2019 7:54 am
Location: Frankfurt/Germany

Re: Proper coding for Vsync or similar functionality

Postby grafvonb » Thu Feb 13, 2020 9:54 pm

Entering super mode with trap #0, as I understand. But I cannot find a code snippet to switch off interrupts. Can you help me?


Loving QL & ZX Spectrum & Amiga...
User avatar
NormanDunbar
Aurora
Posts: 986
Joined: Tue Dec 14, 2010 9:04 am
Location: Leeds, West Yorkshire, UK
Contact:

Re: Proper coding for Vsync or similar functionality

Postby NormanDunbar » Thu Feb 13, 2020 10:19 pm

grafvonb wrote:Entering super mode with trap #0, as I understand. But I cannot find a code snippet to switch off interrupts. Can you help me?


http://qdosmsq.dunbar-it.co.uk/doku.php ... ap_0:start might help. ;)

Cheers,
Norm.


Why do they put lightning conductors on churches?
Author of Arduino Software Internals - https://www.amazon.co.uk/Arduino-Softwa ... 1484257898, https://www.apress.com/gb/book/9781484257890
User avatar
grafvonb
ROM Dongle
Posts: 39
Joined: Sat Jan 05, 2019 7:54 am
Location: Frankfurt/Germany

Re: Proper coding for Vsync or similar functionality

Postby grafvonb » Thu Feb 13, 2020 10:33 pm

Thanks, I have found this great side too. Surprisingly the following code:

Code: Select all

        trap    #0
        ori     #%0000011100000000,sr

helped to run the code above smoothly using Qemulator, however my problem with the real QL remains as it was (the sync does not work).


Loving QL & ZX Spectrum & Amiga...
User avatar
M68008
Bent Pin Expansion Port
Posts: 97
Joined: Sat Jan 29, 2011 1:55 am
Contact:

Re: Proper coding for Vsync or similar functionality

Postby M68008 » Fri Feb 14, 2020 4:58 am

grafvonb wrote:Thanks, I have found this great side too. Surprisingly the following code:

Code: Select all

        trap    #0
        ori     #%0000011100000000,sr

helped to run the code above smoothly using Qemulator, however my problem with the real QL remains as it was (the sync does not work).


Yes, this disables the interrupts. It's a good way to get all the processor time for your program.
With your vsync mechanism, this also prevents the OS from intercepting and clearing the interrupt before you detect it.

Avoid Minerva and use the MGG you have. It doesn't matter for now since you disable the OS, but it can cause problems if later you decide to call the OS for sound or reading the keyboard. See https://qemulator.blogspot.com/2013/04/minerva-and-games.html.


User avatar
M68008
Bent Pin Expansion Port
Posts: 97
Joined: Sat Jan 29, 2011 1:55 am
Contact:

Re: Proper coding for Vsync or similar functionality

Postby M68008 » Fri Feb 14, 2020 5:00 am

grafvonb wrote:however my problem with the real QL remains as it was (the sync does not work).


The code you posted should work fine, just make sure you add the instructions to disable the interrupts at the beginning.



Who is online

Users browsing this forum: No registered users and 9 guests