Page 1 of 2

Proper coding for Vsync or similar functionality

Posted: Thu Feb 13, 2020 8:27 pm
by grafvonb
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")?

Re: Proper coding for Vsync or similar functionality

Posted: Thu Feb 13, 2020 8:52 pm
by tofro
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

Re: Proper coding for Vsync or similar functionality

Posted: Thu Feb 13, 2020 9:12 pm
by grafvonb
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

Re: Proper coding for Vsync or similar functionality

Posted: Thu Feb 13, 2020 9:17 pm
by grafvonb
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?

Re: Proper coding for Vsync or similar functionality

Posted: Thu Feb 13, 2020 9:44 pm
by tofro
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

Re: Proper coding for Vsync or similar functionality

Posted: Thu Feb 13, 2020 9:54 pm
by grafvonb
Entering super mode with trap #0, as I understand. But I cannot find a code snippet to switch off interrupts. Can you help me?

Re: Proper coding for Vsync or similar functionality

Posted: Thu Feb 13, 2020 10:19 pm
by NormanDunbar
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.

Re: Proper coding for Vsync or similar functionality

Posted: Thu Feb 13, 2020 10:33 pm
by grafvonb
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).

Re: Proper coding for Vsync or similar functionality

Posted: Fri Feb 14, 2020 4:58 am
by M68008
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/ ... games.html.

Re: Proper coding for Vsync or similar functionality

Posted: Fri Feb 14, 2020 5:00 am
by M68008
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.