Interrupts during VDP access?

SGDK only sub forum

Moderator: Stef

Post Reply
matteus
Very interested
Posts: 336
Joined: Mon Feb 04, 2008 1:41 pm

Interrupts during VDP access?

Post by matteus » Thu Sep 17, 2015 1:37 pm

Should I be disabling the interrupts for every VDP call? If I don't what will happen?

I'm really a newbie when it comes to this stuff :) Does this include calls to the SPR engine also?

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: Interrupts during VDP access?

Post by Stef » Thu Sep 17, 2015 8:03 pm

SGDK will handle some internals stuff during the V-Int and may access the VDP (to update the sprites for instance) so yes, if you access the VDP outside the V-Int callback then you really need to disable interrupts before accessing it (and restore them after) to avoid conflict accesses.

Imagine your code is doing VDP accesses, then V-Int happen during the VDP accesses, the SGDK internals works will completely mess the VDP state and your resuming VDP operations will be corrupted. That is why you have to disable interrupts during VDP access outside V-Int callback.
Generally speaking it's better to centralize all VDP accesses in the V-Int callback (as VDP accesses are faster during VBlank), if it's too complicated to do that then at least, protect your VDP accesses by disabling interrupts :)

matteus
Very interested
Posts: 336
Joined: Mon Feb 04, 2008 1:41 pm

Re: Interrupts during VDP access?

Post by matteus » Thu Sep 17, 2015 9:32 pm

This is my structure

Code: Select all

    
int main {    
    << DO INITIAL STUFF >>
    
    while(TRUE)
    {
     
     	<< DO STUFF >>

        VDP_waitVSync();
 
    }
    
}

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: Interrupts during VDP access?

Post by Stef » Thu Sep 17, 2015 9:46 pm

Yeah, that is what I call the "main thread" or "main loop" code. In this part you should handle the game logic for the current/next frame depending how you see it and the waitVSync() call allow to synchronize the game speed. Normally in this "thread" you should not access the VDP directly but instead use the vint callback for that :

Code: Select all

  // init stuff
  ...
  SYS_setVIntCallback(vint);

  while(true)
  {
    VDP_waitVSync();
    // prepare next frame
    ...
    frameDone = TRUE;
  }
}

void vint()
{
  if (frameDone)
  {
    // do VDP stuff
    VDP_setTileMap(..);
    VDP_drawText(...);
    ...
    
    frameDone = FALSE;
  }
}
But sometime isolating the VDP stuff in the VInt handler can be overkilling / overcomplicated so you can just do in your main loop :

Code: Select all

  while(true)
  {
    VDP_waitVSync();
    // prepare next frame
    ...
    // disable ints
    SYS_disableInterrupts();
    // do VDP stuff
    VDP_drawText(..);
    // re-enable ints
    SYS_enableInterrupts();
    ...
    frameDone = TRUE;
  }
Oh and by the way, you can of course use the SPR_xxx methods in your main loop without disabling interrupts. SPR_xx methods take care of not accessing VDP immediately, all accesses are centralized in the internal SGDK VInt callback.

matteus
Very interested
Posts: 336
Joined: Mon Feb 04, 2008 1:41 pm

Re: Interrupts during VDP access?

Post by matteus » Mon Sep 21, 2015 8:48 am

It all makes sense to me now! I could rewrite things to work like this but I think I'll leave it for now. If it looks like it's not going to run well on real hardware I'll move to using vint rather than switching off interrupts. I guess I'm lucky that my code never actively updates the screen during calculations and input anyway!

matteus
Very interested
Posts: 336
Joined: Mon Feb 04, 2008 1:41 pm

Re: Interrupts during VDP access?

Post by matteus » Mon Oct 05, 2015 7:56 am

Is there much of a performance different between the two methods? I can understand this would probably be the case if I was continously updating the screen in a game with lots of movement and A.I?
Last edited by matteus on Mon Oct 05, 2015 9:01 am, edited 1 time in total.

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: Interrupts during VDP access?

Post by Stef » Mon Oct 05, 2015 8:24 am

Generally updating the screen during the active period is slow (because VDP accesses are very slow during active period).
It's why it's better to move all your VDP update code in the VInt callback and doing the game logic in the main loop :)

matteus
Very interested
Posts: 336
Joined: Mon Feb 04, 2008 1:41 pm

Re: Interrupts during VDP access?

Post by matteus » Mon Oct 05, 2015 9:00 am

So for instance I have a function to type text. Do I need a function to allocate the letter and another to print the letter in vint? where would I control the text print speed? Vint?

Code: Select all

u16 writeOnScreenMessage(char * Message, u16 MessageRow) {
    u16 completeOnScreenMessage = FALSE;
    u16 static increment = 0;
    u16 static TextTimer = 0;
    char static character[1];
    if (TextTimer == 0) {
        u16 stringLength = strlen(Message) - 1;
        if (increment <= stringLength) {
            character[0] = Message[increment];
            SYS_disableInts();
            VDP_drawText(character, 2+increment, MessageRow);
            SYS_enableInts();
            strclr(character);
            TextTimer = TIMERSECONDS;
            increment++;
        } else {
            TextTimer = 0;
            increment = 0;
            completeOnScreenMessage = TRUE;
        }
    } else if (TextTimer > 0) {
        TextTimer--;
    }
    return completeOnScreenMessage;
}

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: Interrupts during VDP access?

Post by Stef » Mon Oct 05, 2015 11:44 am

Given the method you can keep it in the main loop (with V-Int protection). This is easier to handle the whole and here you don't need it to be blazing fast :)

Post Reply