Screensplit: Line not detected. I'm puzzled.

Por Bengalack

Master (133)

imagem de Bengalack

24-04-2020, 10:57

Scratching my head atm. Can't get the program to let me know when I have reached line 150. More or less using Grauw's example directly from this page: http://map.grauw.nl/articles/split_guide.php, but it just "falls through". That means that the in-value which supposedly have the FH-flag set, always has this flag set. --Strange.

I was expecting to see the border being colored green until line 150 in this example. Anyone cares to have a look?

void sceneRun()
{
    SetBorderColor( COLOR_RED ); 

    g_tick++;

    // Just create a delay to see border color effect
    int i;
    char c = 0;
    for( i=0;i<256;i++ )
    {
        c++;
    }

    sceneHandleInput(); // joystick and keyboard

    SetBorderColor( COLOR_GREEN );
__asm
    di

    ; Set S#1 for reading ("in"), to be used further down
    ld a, #1
    out ( #99 ), a
    ld a, #15 + #128
    out ( #99 ), a

    ; Set the line for the interrupt in reg #19
    ld a, #150
    out ( #99 ), a
    ld a, #19 + #128
    out ( #99 ), a

    nop             ; don’t access too fast

Poll:
    in a, ( #99 )      ; poll until line reached, also clears FH bit
    rra
    jp nc, Poll

    ; Re-set the value / status register to S#0 again, as the rule is
    xor a
    out ( #99 ), a
    ld a, #15 + #128
    out ( #99 ), a

    ei

__endasm;
    
    SetBorderColor( COLOR_BLACK );
}
Entrar ou registrar-se para comentar

Por Bengalack

Master (133)

imagem de Bengalack

24-04-2020, 13:03

Move along. It works now. If I could delete this post, I would. As embarrassing it is, the fault is that all those port 99's should be prefixed with 0x... :-O

Por Grauw

Ascended (9055)

imagem de Grauw

24-04-2020, 13:10

Hey Bengalack, please test this on a real machine and not only on an emulator. You may notice that polling F and FH is not reliable. When the bit is set by the VDP at exactly the same time as you read it, the read can clear it without the Z80 receiving the bit, so it will read 0. In practice this means that the flag is missed every so often. Instead you have to always reads these bits from an ISR.

The other bits which are not automatically cleared on read (e.g. VR, HR) can be polled without issue.

Por Bengalack

Master (133)

imagem de Bengalack

24-04-2020, 14:57

Thanks for the info, Grauw.

I plan to make it kick of an interrupt in the R#0/E1-flag. So I'm probably off the hook, as long as that one works, I guess Smile

Por Grauw

Ascended (9055)

imagem de Grauw

24-04-2020, 15:08

Yes that should be fine! Smile

Por PingPong

Prophet (3521)

imagem de PingPong

25-04-2020, 01:39

Grauw wrote:

Hey Bengalack, please test this on a real machine and not only on an emulator. You may notice that polling F and FH is not reliable. When the bit is set by the VDP at exactly the same time as you read it, the read can clear it without the Z80 receiving the bit, so it will read 0. In practice this means that the flag is missed every so often. Instead you have to always reads these bits from an ISR.

The other bits which are not automatically cleared on read (e.g. VR, HR) can be polled without issue.

But does this behaviour only apply to tms vdp msx1 chip? I ve always thought that the race condition was solved on v99x8

Por pgimeno

Master (170)

imagem de pgimeno

25-04-2020, 02:32

I've verified it for the vertical interrupt in the V9938 (details). In the V9938 the window where you reset the vertical interrupt bit and get a 0 instead of a 1 can be up to 4 cycles. I didn't know it affects the horizontal interrupt too.

Por Sandy Brand

Master (172)

imagem de Sandy Brand

25-04-2020, 11:36

I think what Grauw means to say is that it is about how you structure the code.

If you apply polling like is done here outside of interrupt handling routines, you run the risk of resetting the FH bit without seeing it being raised at some point.

With an interrupt handling routine you will not have this issue because the raising of the FH bit and the raising of the interrupt signal coming from the VDP are done at the same time.

Por pgimeno

Master (170)

imagem de pgimeno

25-04-2020, 16:18

Sandy Brand wrote:

With an interrupt handling routine you will not have this issue because the raising of the FH bit and the raising of the interrupt signal coming from the VDP are done at the same time.

Actually, my tests show that the bit is raised 2 to 3 cycles before the interrupt occurs (but they also show that you clear it if the port is read up to 6 cycles before the interrupt occurs, which leaves a small window in which you will clear the bit and not see it set).

Por Sandy Brand

Master (172)

imagem de Sandy Brand

09-05-2020, 15:32

An interesting find for sure Smile

But it doesn't invalidate the argument that if you want to make this 100% safe then you should just use interrupt handlers.

Normally, the non-interrupt related code has no business polling VDP status registers S0 and S1.

The only thing I can image that might cause issues is if you want to poll sprite collision information from status register S0 by non-interrupt code.

I am not sure how this was supposed to work, but I can image that it still only makes sense to poll that register in the V-blank interrupt handler and pass it on to code that would care about? I never fully understood the addition of this feature anyways; like, what happens with collision detection while I am writing my sprite data into VRAM? I guess the collision data was only computed will drawing the current scan-line, so it sort of assumes that the sprite data is 'ready' by the time the VDP starts scan converting the top line on the screen again? This would indeed only make it safe to modify sprite tables in VRAM during the V-blank and then process collisions events there as well?

Por pgimeno

Master (170)

imagem de pgimeno

10-05-2020, 01:12

Sandy Brand wrote:

An interesting find for sure Smile
But it doesn't invalidate the argument that if you want to make this 100% safe then you should just use interrupt handlers.

No, not in the least. I was just clarifying the details.

Note that, with a bit of bad luck, if another device causes an interrupt that makes the ISR poll the status register at the wrong time, the VDP interrupt will be completely missed. That's a design flaw of the VDP interrupt system.