gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > VCOUNT interrupt.

#110183 - Dark Knight ez - Sun Nov 26, 2006 3:11 pm

Hey guys.

About time I posted another question.
This one concerns the use of VCOUNT interrupt.
As far as I understand, you can trigger an interrupt on a certain hblank (vertical scanline) with this. I checked gbatek, bugged LiraNuna about it, but I could not get it to work.

I created a small tech demo of me trying to get it to work without all the other code of my project possibly interfering. Still no luck though. Could someone point out what's wrong in my little techdemo?
(All commented out code in there was also tested enabled, to no avail.)
As you might be able to tell, the goal of this techdemo is to show black on the upper half of the screen, and another colour on the bottom half.

Thanks in advance.


Code:
/* YTrigger Tech-Demo *
 *********************/

#include <nds.h>
#include <stdio.h>
#include <string>
#include <sstream>
#include <malloc.h>
#include <nds/memory.h>
#include <nds/ARM9/console.h>

#include <nds/registers_alt.h>


static inline void setYTrigger(int YValue) {
    REG_DISPSTAT = (REG_DISPSTAT & 0xFF ) | (YValue << 8);
    //REG_DISPSTAT = (REG_DISPSTAT & 0xFF ) | (YValue << 8) | (( YValue & 0x100 ) >> 2);
}


void handleVBlankInterrupt() {
    BG_PALETTE[0] = 0;
}

void handleYTriggerInterrupt() {
    BG_PALETTE[0] = 0x1F;
}



int main() {
    powerON(POWER_ALL_2D);
   
    //vramSetBankA(VRAM_A_MAIN_BG);
    DISPLAY_CR = MODE_0_2D; // | DISPLAY_BG0_ACTIVE;
    //BG0_CR = BG_PRIORITY_0 | BG_TILE_BASE(0) | BG_256_COLOR | BG_MAP_BASE(28) | BG_32x32;
   
    irqInit();

    irqSet(IRQ_VBLANK, handleVBlankInterrupt);
    irqEnable(IRQ_VBLANK);
   
    setYTrigger(96);
    irqSet(IRQ_VCOUNT, handleYTriggerInterrupt);
    irqEnable(IRQ_VCOUNT);
   
   
    while (1)    {
        swiWaitForVBlank();
    }
    return 0;
}



edited to represent the current version (which still does not work).
_________________
AmplituDS website


Last edited by Dark Knight ez on Mon Nov 27, 2006 12:58 pm; edited 1 time in total

#110186 - ProblemBaby - Sun Nov 26, 2006 3:22 pm

Hey

Code:

    irqSet(IRQ_VCOUNT, handleVBlankInterrupt); // IRQ_VBLANK
    irqEnable(IRQ_VBLANK);
   
    setYTrigger(96);
    irqSet(IRQ_VCOUNT, handleYTriggerInterrupt);
    irqEnable(IRQ_VCOUNT);


First it seems like your first irqSet is wrong. Second Iam unsure if NDSLib set the stat-bits automatically for you as it does for hbl and vbl.

#110187 - Mighty Max - Sun Nov 26, 2006 3:23 pm

You got to enable vcount irq in dispstat too. (Bit 5)
_________________
GBAMP Multiboot

#110192 - Dark Knight ez - Sun Nov 26, 2006 4:13 pm

Quote:
First it seems like your first irqSet is wrong

Yeah... fixed that one now. Didn't solve the problem though.

Quote:
Second Iam unsure if NDSLib set the stat-bits automatically for you as it does for hbl and vbl.

Quote:
You got to enable vcount irq in dispstat too. (Bit 5)

I looked it up, and that is indeed done by irqEnable. (I also did it manually first to make sure that wasn't the problem.)

Code:
if (irq & IRQ_VCOUNT)
    REG_DISPSTAT |= DISP_YTRIGGER_IRQ;

Where DISP_YTRIGGER_IRQ is BIT(5).
_________________
AmplituDS website

#110194 - ProblemBaby - Sun Nov 26, 2006 5:10 pm

iam not familiar with ndslib but musnt you initialize the irq-system somehow?

#110199 - Dark Knight ez - Sun Nov 26, 2006 6:09 pm

Quite right. Yet another line I forgot to add to my tech demo.
"irqInit();" line added now.

However, it still fails to work.
_________________
AmplituDS website

#110344 - Dark Knight ez - Mon Nov 27, 2006 11:44 pm

Surely someone got this interrupt to work. Anyone?
_________________
AmplituDS website

#110353 - bsder - Tue Nov 28, 2006 12:59 am

Isn't there a bit in DISPSTAT you have to set as well?

Quote:

4000004h - DISPSTAT - General LCD Status (Read/Write)
Display status and Interrupt control. The H-Blank conditions are generated once per scanline, including for the 'hidden' scanlines during V-Blank.

Bit Expl.
0 V-Blank flag (Read only) (1=VBlank)
1 H-Blank flag (Read only) (1=HBlank)
2 V-Counter flag (Read only) (1=Match)
3 V-Blank IRQ Enable (1=Enable)
4 H-Blank IRQ Enable (1=Enable)
5 V-Counter IRQ Enable (1=Enable)
6-7 Not used
8-15 V-Count Setting (0-227)


I don't see where you set Bit 5. Also, you might want to check bit 2 as it should trigger during the expected scanline even without an interrupt.

-a

#110363 - gmiller - Tue Nov 28, 2006 1:55 am

Maybe a dumb question but are you compiling this code in ARM mode? On the GBA the interrupt handler needs to be ARM mode. The interrupt handler dispatcher I ASSUME can do ARM/THUMB calls but I don't know. I don't do and DS development yet so I could be completely off.

Also does the irqEnable mess with the vcount part of DISPSTAT?

#110405 - Dark Knight ez - Tue Nov 28, 2006 9:11 am

Notice one of my previous replies.
"irqEnable(IRQ_VCOUNT);" actually sets BIT(5) of REG_DISPSTAT.

Quote:
Also, you might want to check bit 2 as it should trigger during the expected scanline even without an interrupt.

You want me to check with HBlank interrupts if that flag has been set at (a certain) scanline at all? Sure, but if that's not set, then something's very wrong with documentation or how I interpret it.

@gmiller:
I'm using regular ARM code. I've been using VBlank and HBlank interrupts without a problem. Just this VCOUNT interrupt won't work with me.
_________________
AmplituDS website

#110408 - Ted - Tue Nov 28, 2006 11:11 am

I copied the code in the first post and compiled it, and as far as i can tell it works as intended.
The bottom half turns red on my hardware, except that the first two pixels that should be red are still black. I assume that's because the hardware keeps drawing while we're changing the palette.

#110458 - Dark Knight ez - Tue Nov 28, 2006 7:30 pm

Unfortunately, that code does not work with either my EZ-Flash 2 or my EZ-Flash 4.

The VBlank function is executed, I can verify that.
The VCount function, however, is not.

Odd that you got it to work, Ted.
Might I ask what version of devkitpro you are using?
Could you upload the (.ds.gba) binary for me, so I can check if it has to do with my compiling setup or my DS setup?

edit:
DevilSpawn compiled it for me and that version works on my DS.
Must be due to my old (v18?) devkitpro. I'll upgrade to the latest, hoping it doesn't break any of my (old) projects. Thanks, Ted.
_________________
AmplituDS website