Ejemplo n.º 1
0
void GBA_DMASoundRequestData(int A, int B)
{
    //this should check if another dma is running and return without copying

    if(DMA[1].starttime == START_SPECIAL)
    {
        if( (A && (DMA[1].dstaddr==FIFO_A)) || (B && (DMA[1].dstaddr==FIFO_B)) )
        {
            //copy words
            int i; for(i = 0; i < 4; i++)
            {
            //    if(GBA_MemoryRead32(DMA[1].srcaddr)!=0) //Debug_DebugMsgArg("%08X",DMA[1].srcaddr);
            //    //Debug_DebugMsgArg("[%08x]= %08X",DMA[1].srcaddr,GBA_MemoryRead32(DMA[1].srcaddr));
            //    Debug_DebugMsgArg("%08X",GBA_MemoryRead32(DMA[1].srcaddr));
                GBA_MemoryWrite32(DMA[1].dstaddr,GBA_MemoryRead32(DMA[1].srcaddr));
                DMA[1].srcaddr += DMA[1].srcadd;
            }
            if(REG_DMA2CNT_H & BIT(14)) GBA_CallInterrupt(BIT(9));
        }
    }

    if(DMA[2].starttime == START_SPECIAL)
    {
        if( (A && (DMA[2].dstaddr==FIFO_A)) || (B && (DMA[2].dstaddr==FIFO_B)) )
        {
            //copy words
            int i; for(i = 0; i < 4; i++)
            {
                GBA_MemoryWrite32(DMA[2].dstaddr,GBA_MemoryRead32(DMA[2].srcaddr));
                DMA[2].srcaddr += DMA[2].srcadd;
            }
            if(REG_DMA2CNT_H & BIT(14)) GBA_CallInterrupt(BIT(10));
        }
    }
}
Ejemplo n.º 2
0
inline void GBA_CheckKeypadInterrupt(void)
{
    u16 keys = REG_KEYCNT & 0x03FF;
    u16 keyspressed = (~REG_KEYINPUT) & 0x03FF;

    if(REG_KEYCNT&BIT(15)) //AND
    {
        if((keys&keyspressed) == keys)
        {
            if(REG_KEYCNT&BIT(14)) GBA_CallInterrupt(BIT(12)); //IRQ Enable Flag
            if(GBA_CPUGetHalted()==2) GBA_CPUClearHalted();
        }
    }
    else //OR
    {
        if(keys&keyspressed)
        {
            if(REG_KEYCNT&BIT(14)) GBA_CallInterrupt(BIT(12)); //IRQ Enable Flag
            if(GBA_CPUGetHalted()==2) GBA_CPUClearHalted();
        }
    }
}
Ejemplo n.º 3
0
static inline s32 GBA_DMA3Update(s32 clocks) //return clocks to finish transfer
{
    if(DMA[3].enabled == 0) return 0x7FFFFFFF;

    if(DMA[3].starttime == START_SPECIAL)
    {
        Debug_DebugMsgArg("DMA3, MODE: START_SPECIAL -- NOT EMULATED");
        GBA_ExecutionBreak();
        DMA[3].enabled = 0;
        return 0x7FFFFFFF;
    }

    if(DMA[3].clocksremaining == DMA[3].clockstotal)
    {
        u32 copy = 0;

        switch(DMA[3].starttime)
        {
            case START_NOW:
            {
                copy = 1;
                break;
            }
            case START_VBL:
            {
                if(screenmode != SCR_VBL) return 0x7FFFFFFF;
                if(GBA_ScreenJustChangedMode() == 0) return 0x7FFFFFFF;
                copy = 1;
                break;
            }
            case START_HBL:
            {
                if(screenmode != SCR_HBL) return 0x7FFFFFFF;
                if(GBA_ScreenJustChangedMode() == 0) return 0x7FFFFFFF;
                copy = 1;
                break;
            }
            case START_SPECIAL: return 0x7FFFFFFF; // TODO: NOT EMULATED *****************************
            default: break;
        }

        if(copy)
        {
            //MessageBox(NULL, "DMA 3 copy", "EMULATION", MB_OK);
            //GBA_ExecutionBreak();

            //char text[64]; snprintf(text,sizeof(text),"DMA3\nSRC: %08X\nDST: %08X\nCHUNCKS: %08X",
            //    DMA[3].srcaddr,DMA[3].dstaddr,DMA[3].num_chunks);
            //MessageBox(NULL, text, "EMULATION", MB_OK);
            //GBA_ExecutionBreak();

            if(DMA[3].copywords) //copy words
            {
                int i;
                for(i = 0; i < DMA[3].num_chunks; i++)
                {
                    GBA_MemoryWrite32(DMA[3].dstaddr,GBA_MemoryRead32(DMA[3].srcaddr));
                    DMA[3].srcaddr += DMA[3].srcadd; DMA[3].dstaddr += DMA[3].dstadd;
                }
            }
            else //copy halfwords
            {
                int i;
                for(i = 0; i < DMA[3].num_chunks; i++)
                {
                    GBA_MemoryWrite16(DMA[3].dstaddr,GBA_MemoryRead16(DMA[3].srcaddr));
                    DMA[3].srcaddr += DMA[3].srcadd; DMA[3].dstaddr += DMA[3].dstadd;
                }
            }
        }
    }

    DMA[3].clocksremaining -= clocks;

    if(DMA[3].clocksremaining <= 0)
    {
        gba_dma_extra_clocks_elapsed = -DMA[3].clocksremaining;

        if(DMA[3].dst_reload) DMA[3].dstaddr = REG_DMA3DAD & (DMA[3].copywords ? ~3 : ~1);

        if(REG_DMA3CNT_H & BIT(14)) GBA_CallInterrupt(BIT(11)); //interrupt

        if(DMA[3].repeat == 0)
        {
            REG_DMA3CNT_H &= ~BIT(15);
            DMA[3].enabled = 0;
            //MessageBox(NULL, "DMA 3 clear", "EMULATION", MB_OK);
            //GBA_ExecutionBreak();
        }
        else
        {
            DMA[3].clocksremaining = DMA[3].clockstotal;

            if(DMA[3].starttime == START_NOW)
            {
                //Debug_DebugMsgArg("WARNING: DMA 3, immediate mode with repeat bit set.");
                //GBA_ExecutionBreak();
                REG_DMA3CNT_H &= ~BIT(15);
                DMA[3].enabled = 0;
                return 0x7FFFFFFF;
            }
        }

        return 0x7FFFFFFF;
    }

    gba_dmaworking = 1;
    return DMA[3].clocksremaining;
}
Ejemplo n.º 4
0
static inline s32 GBA_DMA0Update(s32 clocks) //return clocks to finish transfer
{
    if(DMA[0].enabled == 0) return 0x7FFFFFFF;

    if(DMA[0].starttime == START_SPECIAL)
    {
        Debug_DebugMsgArg("DMA0, MODE: START_SPECIAL (?)");
        GBA_ExecutionBreak();
        DMA[0].enabled = 0;
        return 0x7FFFFFFF;
    }

    if(DMA[0].clocksremaining == DMA[0].clockstotal)
    {
        u32 copy = 0;

        switch(DMA[0].starttime)
        {
            case START_NOW:
            {
                copy = 1;
                break;
            }
            case START_VBL:
            {
                if(screenmode != SCR_VBL) return 0x7FFFFFFF;
                if(GBA_ScreenJustChangedMode() == 0) return 0x7FFFFFFF;
                copy = 1;
                break;
            }
            case START_HBL:
            {
                if(screenmode != SCR_HBL) return 0x7FFFFFFF;
                if(GBA_ScreenJustChangedMode() == 0) return 0x7FFFFFFF;
                copy = 1;
                break;
            }
            case START_SPECIAL: return 0x7FFFFFFF; //NOT EMULATED *****************************
            default: break;
        }

        if(copy)
        {
            if(DMA[0].copywords) //copy words
            {
                int i;
                for(i = 0; i < DMA[0].num_chunks; i++)
                {
                    GBA_MemoryWrite32(DMA[0].dstaddr,GBA_MemoryRead32(DMA[0].srcaddr));
                    DMA[0].srcaddr += DMA[0].srcadd; DMA[0].dstaddr += DMA[0].dstadd;
                }
            }
            else //copy halfwords
            {
                int i;
                for(i = 0; i < DMA[0].num_chunks; i++)
                {
                    GBA_MemoryWrite16(DMA[0].dstaddr,GBA_MemoryRead16(DMA[0].srcaddr));
                    DMA[0].srcaddr += DMA[0].srcadd; DMA[0].dstaddr += DMA[0].dstadd;
                }
            }
        }
    }

    DMA[0].clocksremaining -= clocks;

    if(DMA[0].clocksremaining <= 0)
    {
        gba_dma_extra_clocks_elapsed = -DMA[0].clocksremaining;

        if(DMA[0].dst_reload) DMA[0].dstaddr = REG_DMA0DAD & (DMA[0].copywords ? ~3 : ~1);

        if(REG_DMA0CNT_H & BIT(14)) GBA_CallInterrupt(BIT(8)); //interrupt

        if(DMA[0].repeat == 0)
        {
            REG_DMA0CNT_H &= ~BIT(15);
            DMA[0].enabled = 0;
        }
        else
        {
            DMA[0].clocksremaining = DMA[0].clockstotal;

            if(DMA[0].starttime == START_NOW)
            {
                //Debug_DebugMsgArg("DMA 0 immediate mode with repeat bit set.");
                //GBA_ExecutionBreak();
                REG_DMA0CNT_H &= ~BIT(15);
                DMA[0].enabled = 0;
                return 0x7FFFFFFF;
            }
        }

        return 0x7FFFFFFF;
    }

    gba_dmaworking = 1;
    return DMA[0].clocksremaining;
}