#include "screenmode.h"
#include "commun.h"

#define ROM_BANKSWITCH                        (volatile u16 *) (0x096B592E)
#define WRITE_LOC_1                                (volatile u16 *) (0x987654 * 2 + 0x8000000)
#define WRITE_LOC_2                                (volatile u16 *) (0x012345 * 2 + 0x8000000)
#define WRITE_LOC_3                                (volatile u16 *) (0x007654 * 2 + 0x8000000)
#define WRITE_LOC_4                                (volatile u16 *) (0x765400 * 2 + 0x8000000)
#define WRITE_LOC_5                                (volatile u16 *) (0x013450 * 2 + 0x8000000)
#define SLEEP_TIMER_LENGTH                180000        //milliseconds
#define TIME_FREQUENCY_SYSTEM        0x0
#define TIME_FREQUENCY_64                0x1
#define TIME_FREQUENCY_256                0x2
#define TIME_FREQUENCY_1024                0x3
#define TIME_OVERFLOW                        0x4
#define TIME_ENABLE                                0x80
#define TIME_IRQ_ENABLE                        0x40

void initInterrupt()
{
	irqInit();
	irqEnable(IRQ_VBLANK);
	irqEnable(IRQ_VCOUNT);
	irqSet(IRQ_VBLANK, vblHandlerGame);
	irqSet(IRQ_VCOUNT, vcountHandlerGame);

/*	REG_IME = 0;
	REG_IE = IRQ_VBLANK;

	REG_DISPSTAT = 1 << 3;
	INT_VECTOR = (void*)interruptHandler;

	REG_IME = 1;                //enable interrupt*/
}

void DesactiveInterruptions()
{
	REG_DISPSTAT = 0;
	REG_IME = 0;
	REG_DMA1CNT = 0;
	REG_SOUNDCNT_X = 0; //turn sound chip off
}

void softReset()
{
	REG_DMA1CNT = 0;        //stop DMA
	REG_SOUNDCNT_X = 0; //turn sound chip off
	REG_TM0CNT_H = 0;        //disable timer 0
	REG_TM1CNT_H = 0;        //disable timer 1
	asm volatile("swi 0x00000");        // 0x00 Soft Reset
	// asm volatile("mov r0,#0x8c; bx r0" ::: "r0", "r1", "r2", "r3");
}

// From Herg's Solitaire
void exit_to_pogoshell(void)
{
	unsigned int i;

	REG_IME = 0;

	/* reset cart bankswitching */
	for (i = 0; i < 1; i++)
		*WRITE_LOC_1 = 0x5354;
	for (i = 0; i < 500; i++)
		*WRITE_LOC_2 = 0x1234;
	for (i = 0; i < 1; i++)
		*WRITE_LOC_2 = 0x5354;
	for (i = 0; i < 500; i++)
		*WRITE_LOC_2 = 0x5678;
	for (i = 0; i < 1; i++)
		*WRITE_LOC_1 = 0x5354;
	for (i = 0; i < 1; i++)
		*WRITE_LOC_2 = 0x5354;
	for (i = 0; i < 1; i++)
		*WRITE_LOC_4 = 0x5678;
	for (i = 0; i < 1; i++)
		*WRITE_LOC_5 = 0x1234;
	for (i = 0; i < 500; i++)
		*WRITE_LOC_2 = 0xabcd;
	for (i = 0; i < 1; i++)
		*WRITE_LOC_1 = 0x5354;
	*ROM_BANKSWITCH = 0;

	/* reset GBA */
	*(u16 *) 0x03007ffa = 0;        /* reset to ROM (= 0) rather than RAM (= 1) */
	asm volatile
		(
		"mov r0, #0xfc  \n" /* clear everything other than RAM */ "swi 0x01       \n""swi 0x00       \n":: : "r0",
		"r1",
		"r2",
		"r3"
		);
}

#undef RGB
#define RGB(r, g, b)        ((r) + ((g) << 5) + ((b) << 10))


int nImages = 0, nLigne = 0, bgmap_scrlX = 0, bgmap_scrlY = 0;
int niveau_eau = 9000;

int jeuEnCours = 0;

u32 _ihScrlX, _ihScrlY;
volatile int vblSet;

//Possible de l'enlever d'IWRAM sans problème de vitesse (0.2% de CPU)
void vblHandlerGame()
{
	u32 cacheJeu = jeuEnCours;

	vblSet++;
	if (cacheJeu)
	{

		//ENLEVER L'INT_HBLANK!
		REG_DISPSTAT = (1 << 3) | (1 << 5) | (224 << 8);
		REG_IE = IRQ_VCOUNT | IRQ_VBLANK;
	}

	//Le son :)
	directSound();
	nImages++;
	if (cacheJeu)
	{
		nLigne = -1;
		niveau_eau = niveau_reel;
		if (niveau_eau < 0)
		{
			CopieDMA0(PaletteEau, BG_PALETTE, 512, DMA_16im);
			niveau_eau = 9000;
		}
		else
		{
			if (niveau_eau >= 156)
				niveau_eau = 9000;
			CopieDMA0(PaletteNormale, BG_PALETTE, 512, DMA_16im);
		}

		//7.5% CPU
		CopieMapBG(scrlX, scrlY);
		REG_BG1VOFS = modulo8(bgmap_scrlY);
	}
}

//Possible de l'enlever d'IWRAM sans problème de vitesse (0.2% de CPU)
/*void SSInterruptHandler(void)
{
	u32 IF;
	REG_IME = 0x00;
	IF = REG_IF;

	if (REG_IF & IRQ_VBLANK)
	{

		//#ifdef SON
		Exec(directSound);
		CopieDMA0(PaletteNormale, BG_PALETTE, 512, DMA_16im);

		//#endif
		nImages++;
	}

	REG_IF = IF;
	REG_IME = 0x01;
}*/

/*void InterruptHandler(void)
{
	u32 Int_Flag;
	REG_IME = 0x00;
	Int_Flag = REG_IF;
	if(REG_IF & INT_HBLANK)     {
		(*(volatile unsigned short*)MEM_PAL_BG_COL_256(0))=RGB((R_VCNT>>3)+4,0,24);
	}
	REG_IF = Int_Flag;
	REG_IME = 0x01;
}*/
