diff --git a/config/sly1.yaml b/config/sly1.yaml index ff19d4fe..4411dba7 100644 --- a/config/sly1.yaml +++ b/config/sly1.yaml @@ -130,8 +130,8 @@ segments: - [0x529e0, c, P2/difficulty] - [0x53438, c, P2/dl] - - [0x53810, asm, P2/dmas] - #- [0x, asm, P2/dsp] + - [0x53810, c, P2/dmas] + - [0x53E28, asm, P2/dsp] #- [0x, asm, P2/dysh] #- [0x, asm, P2/dzg] @@ -334,6 +334,8 @@ segments: - [0x14A2F0, .rodata, P2/splice/ref] - [0x14A3A0, .rodata, P2/splice/serialize] - [0x14A428, rodata] + - [0x14B0E0, .rodata, P2/dmas] + - [0x14B0F8, rodata] #-------------------------------------------------------- # Data diff --git a/config/symbol_addrs.txt b/config/symbol_addrs.txt index c20f9f16..57f3e759 100644 --- a/config/symbol_addrs.txt +++ b/config/symbol_addrs.txt @@ -671,6 +671,32 @@ FIsDlEmpty__FP2DL = 0x152720; // type:func MergeDl__FP2DLT0 = 0x152730; // type:func CPvDl__FP2DL = 0x1527D8; // type:func + +//////////////////////////////////////////////////////////////// +// P2/dmas.c +//////////////////////////////////////////////////////////////// +StartupDma__Fv = 0x152810; // type:func +__4DMAS = 0x152888; // type:func +Clear__4DMAS = 0x1528C8; // type:func +Reset__4DMAS = 0x1528E0; // type:func +AllocGlobal__4DMASi = 0x1528F0; // type:func +AllocSw__4DMASii = 0x152938; // type:func +AllocStack__4DMASi = 0x152980; // type:func +AllocStatic__4DMASiP2QW = 0x1529C8; // type:func +Detach__4DMASPiPP2QW = 0x1529E0; // type:func +DetachCopySw__4DMASPiPP2QWT2i = 0x152A50; // type:func +Send__4DMASP10sceDmaChan = 0x152AE0; // type:func +AddDmaCnt__4DMAS = 0x152B38; // type:func +AddDmaRefs__4DMASiP2QW = 0x152B80; // type:func +AddDmaCall__4DMASP2QW = 0x152C18; // type:func +AddDmaRet__4DMAS = 0x152CA0; // type:func +AddDmaBulk__4DMASiP2QW = 0x152CE0; // type:func +AddDmaEnd__4DMAS = 0x152D30; // type:func +EndDmaCnt__4DMAS = 0x152D70; // type:func +EndPrim__4DMASi = 0x152E18; // type:func + +_vt$4DMAS = 0x24A0E0; // size:0x10 + //////////////////////////////////////////////////////////////// // P2/find.c //////////////////////////////////////////////////////////////// @@ -1238,6 +1264,14 @@ atan2f = 0x205778; // type:func fmodf = 0x2058a0; // type:func +//////////////////////////////////////////////////////////////// +// sce/dma.c +//////////////////////////////////////////////////////////////// +sceDmaGetChan = 0x2027A0; // type:func +sceDmaReset = 0x2027C8; // type:func +sceDmaSend = 0x202A80; // type:func + + //////////////////////////////////////////////////////////////// // sce/eecdvd.c //////////////////////////////////////////////////////////////// @@ -1259,6 +1293,7 @@ GetThreadId = 0x1F6A90; // type:func CreateSema = 0x1F6B20; // type:func SignalSema = 0x1F6B40; // type:func WaitSema = 0x1F6B60; // type:func +FlushCache = 0x1F6C20; // type:func //////////////////////////////////////////////////////////////// diff --git a/include/dmas.h b/include/dmas.h index 0f54ac7d..4dc4d200 100644 --- a/include/dmas.h +++ b/include/dmas.h @@ -5,7 +5,40 @@ #define DMAS_H #include "common.h" +#include +#include -// ... +class DMAS +{ + uchar* m_pbMax; + uchar* m_ab; + QW* m_pqwCnt; + uchar* m_pb; + int m_fPad; + int m_fEndPrim; + + DMAS(); + + void Clear(); + void Reset(); + void AllocGlobal(int); + void AllocSw(int, int); + void AllocStack(int); + void AllocStatic(int, QW*); + void Detach(int*, QW**); + void DetachCopySw(int*, QW**, QW*, int); + void Send(sceDmaChan* chan); + void AddDmaCnt(); + void AddDmaRefs(int, QW*); + void AddDmaCall(QW*); + void AddDmaRet(); + void AddDmaBulk(int, QW*); + void AddDmaEnd(); + void EndDmaCnt(); + + virtual void EndPrim(); +}; + +static void StartupDma(); #endif // DMAS_H diff --git a/include/sce/dma.h b/include/sce/dma.h new file mode 100644 index 00000000..97383d60 --- /dev/null +++ b/include/sce/dma.h @@ -0,0 +1,82 @@ +/** + * @file dma.h + * + * @brief Direct Memory Access (DMA) module. + */ +#ifndef SCE_DMA_H +#define SCE_DMA_H + +#include "common.h" + +extern "C" +{ + struct tD_CHCR + { + unsigned DIR : 1; /* Direction */ + unsigned pad0: 1; + unsigned MOD : 2; /* Mode */ + unsigned ASP : 2; /* Address stack pointer */ + unsigned TTE : 1; /* Tag trasfer enable */ + unsigned TIE : 1; /* Tag interrupt enable */ + unsigned STR : 1; /* start */ + unsigned pad1: 7; + unsigned TAG :16; /* DMAtag */ + }; + + struct sceDmaTag + { + ushort qwc; /* transfer count */ + uchar mark; /* mark */ + uchar id; /* tag */ + sceDmaTag *next; /* next tag */ + uint p[2]; /* padding */ + } __attribute__ ((aligned(16))); + + struct sceDmaChan + { + tD_CHCR chcr; // Channel control Dn_CHCR + uint p0[3]; + volatile void *madr; // Transfer memory address Dn_MADR + uint p1[3]; + volatile uint qwc; // Transfer size Dn_QWC + uint p2[3]; + volatile sceDmaTag *tadr; // Transfer tag address Dn_TADR + uint p3[3]; + volatile void *as0; // Address stack 0 Dn_ASR0 + uint p4[3]; + volatile void *as1; // Address stack Dn_ASR1 + uint p5[3]; + uint p6[4]; + uint p7[4]; + void* sadr; // SPR address Dn_SADR + uint p8[3]; + }; + + void FlushCache(int); + + /** + * @brief Reset the DMA controller + * + * @param mode 0 = disable, 1 = enable + * @return Previous mode before reset + */ + int sceDmaReset(int mode); + + /** + * @brief Start DMA transfer from memory to a device using Source Chain Mode. + * + * @param chan DMA channel for performing the transfer + * @param tag Starting address of the transfer list + */ + void sceDmaSend(sceDmaChan *chan, void *tag); + + /** + * @brief Get a DMA channel structure by ID + * + * @param id Channel number + * @return sceDmaChan* + */ + sceDmaChan *sceDmaGetChan(int id); +} + +#endif // SCE_DMA_H diff --git a/src/P2/dmas.c b/src/P2/dmas.c new file mode 100644 index 00000000..9d47316b --- /dev/null +++ b/src/P2/dmas.c @@ -0,0 +1,80 @@ +#include "common.h" +#include + +INCLUDE_ASM(const s32, "P2/dmas", StartupDma__Fv); + +DMAS::DMAS() +{ + m_fPad = 0; + m_fEndPrim = 0; + Clear(); +} + +void DMAS::Clear() +{ + m_pbMax = (uchar*)nullptr; + m_ab = (uchar*)nullptr; + m_pqwCnt = (QW*)nullptr; + m_pb = (uchar*)nullptr; +} + +void DMAS::Reset() +{ + m_pqwCnt = (QW*)nullptr; + m_pb = m_ab; +} + +INCLUDE_ASM(const s32, "P2/dmas", AllocGlobal__4DMASi); + +INCLUDE_ASM(const s32, "P2/dmas", AllocSw__4DMASii); + +INCLUDE_ASM(const s32, "P2/dmas", AllocStack__4DMASi); + +INCLUDE_ASM(const s32, "P2/dmas", AllocStatic__4DMASiP2QW); + +void DMAS::Detach(int* arg0, QW** arg1) +{ + EndDmaCnt(); + if (arg0 != nullptr) + { + *arg0 = (uint)(m_pb - m_ab) >> 4; + } + if (arg1 != nullptr) + { + *arg1 = (QW*)m_ab; + } + Clear(); +} + +INCLUDE_ASM(const s32, "P2/dmas", DetachCopySw__4DMASPiPP2QWT2i); + +void DMAS::Send(sceDmaChan* chan) +{ + EndDmaCnt(); + FlushCache(0); + sceDmaSend(chan, m_ab); + m_pb = m_ab; +} + +INCLUDE_ASM(const s32, "P2/dmas", func_00152B30); + +INCLUDE_ASM(const s32, "P2/dmas", AddDmaCnt__4DMAS); + +INCLUDE_ASM(const s32, "P2/dmas", AddDmaRefs__4DMASiP2QW); + +INCLUDE_ASM(const s32, "P2/dmas", AddDmaCall__4DMASP2QW); + +INCLUDE_ASM(const s32, "P2/dmas", AddDmaRet__4DMAS); + +INCLUDE_ASM(const s32, "P2/dmas", AddDmaBulk__4DMASiP2QW); + +INCLUDE_ASM(const s32, "P2/dmas", AddDmaEnd__4DMAS); + +INCLUDE_ASM(const s32, "P2/dmas", EndDmaCnt__4DMAS); + +void DMAS::EndPrim(void) +{ + return; +} + +INCLUDE_ASM(const s32, "P2/dmas", func_00152E20);