--- /dev/null
+#pragma once
+
+// Functions for allocating/deallocating mappable memory
+void* mappableAlloc(size_t size); // returns a page-aligned address
+void mappableFree(void* mem);
+u32 mappableSpaceFree(); // get free mappable space in bytes
#include <3ds/types.h>
#define CSND_NUM_CHANNELS 32
-#define CSND_SHAREDMEM_DEFAULT 0x10004000
#define CSND_TIMER(n) (0x3FEC3FC / ((u32)(n)))
//See also: http://3dbrew.org/wiki/HID_Services http://3dbrew.org/wiki/HID_Shared_Memory
-#define HID_SHAREDMEM_DEFAULT (0x10000000)
-
typedef enum
{
KEY_A = BIT(0),
extern Handle hidMemHandle;
extern vu32* hidSharedMem;
-Result hidInit(u32* sharedMem);
+Result hidInit();
void hidExit();
void hidScanInput();
#include "3ds/services/hid.h" // for circlePosition definition
-#define IRRST_SHAREDMEM_DEFAULT (0x1000A000)
-
extern Handle irrstMemHandle;
extern vu32* irrstSharedMem;
-Result irrstInit(u32* sharedMem);
+Result irrstInit();
void irrstExit();
void irrstScanInput();
--- /dev/null
+extern "C"
+{
+ #include <3ds/types.h>
+ #include <3ds/mappable.h>
+ #include <3ds/util/rbtree.h>
+}
+
+#include "mem_pool.h"
+#include "addrmap.h"
+
+static MemPool sMappablePool;
+
+static bool mappableInit()
+{
+ auto blk = MemBlock::Create((u8*)0x10000000, 0x04000000);
+ if (blk)
+ {
+ sMappablePool.AddBlock(blk);
+ rbtree_init(&sAddrMap, addrMapNodeComparator);
+ return true;
+ }
+ return false;
+}
+
+void* mappableAlloc(size_t size)
+{
+ // Initialize the pool if it is not ready
+ if (!sMappablePool.Ready() && !mappableInit())
+ return nullptr;
+
+ // Allocate the chunk
+ MemChunk chunk;
+ if (!sMappablePool.Allocate(chunk, size, 12))
+ return nullptr;
+
+ auto node = newNode(chunk);
+ if (!node)
+ {
+ sMappablePool.Deallocate(chunk);
+ return nullptr;
+ }
+ if (rbtree_insert(&sAddrMap, &node->node));
+ return chunk.addr;
+}
+
+void mappableFree(void* mem)
+{
+ auto node = getNode(mem);
+ if (!node) return;
+
+ // Free the chunk
+ sMappablePool.Deallocate(node->chunk);
+
+ // Free the node
+ delNode(node);
+}
+
+u32 mappableSpaceFree()
+{
+ return sMappablePool.GetFreeSpace();
+}
#include <3ds/gfx.h>
#include <3ds/svc.h>
#include <3ds/linear.h>
+#include <3ds/mappable.h>
#include <3ds/vram.h>
GSP_FramebufferInfo topFramebufferInfo, bottomFramebufferInfo;
gspInit();
- gfxSharedMemory=(u8*)0x10002000;
+ gfxSharedMemory=(u8*)mappableAlloc(0x1000);
GSPGPU_AcquireRight(NULL, 0x0);
GSPGPU_UnregisterInterruptRelayQueue(NULL);
svcCloseHandle(gspSharedMemHandle);
+ if(gfxSharedMemory != NULL)
+ {
+ mappableFree(gfxSharedMemory);
+ gfxSharedMemory = NULL;
+ }
+
svcCloseHandle(gspEvent);
GSPGPU_ReleaseRight(NULL);
#include <3ds/types.h>
#include <3ds/svc.h>
#include <3ds/srv.h>
+#include <3ds/mappable.h>
#include <3ds/os.h>
#include <3ds/services/csnd.h>
Result csndInit(void)
{
Result ret=0;
- csndSharedMem = (vu32*)CSND_SHAREDMEM_DEFAULT;
// TODO: proper error handling!
csndSharedMemSize = csndOffsets[3] + 0x3C; // Total size of the CSND shared memory
ret = CSND_Initialize();
- if (ret != 0) return ret;
+ if (ret != 0) goto cleanup1;
+
+ csndSharedMem = (vu32*)mappableAlloc(csndSharedMemSize);
+ if(!csndSharedMem)
+ {
+ ret = -1;
+ goto cleanup1;
+ }
ret = svcMapMemoryBlock(csndSharedMemBlock, (u32)csndSharedMem, 3, 0x10000000);
- if (ret != 0) return ret;
+ if (ret != 0) goto cleanup2;
memset((void*)csndSharedMem, 0, csndSharedMemSize);
ret = CSND_AcquireSoundChannels(&csndChannels);
- if (ret != 0) return ret;
+ if (!ret) return 0;
- return 0;
+cleanup2:
+ svcCloseHandle(csndSharedMemBlock);
+ if(csndSharedMem != NULL)
+ {
+ mappableFree((void*) csndSharedMem);
+ csndSharedMem = NULL;
+ }
+cleanup1:
+ svcCloseHandle(csndHandle);
+ return ret;
}
Result csndExit(void)
ret = CSND_Shutdown();
svcCloseHandle(csndHandle);
+
+ if(csndSharedMem != NULL)
+ {
+ mappableFree((void*) csndSharedMem);
+ csndSharedMem = NULL;
+ }
+
return ret;
}
#include <3ds/types.h>
#include <3ds/svc.h>
#include <3ds/srv.h>
+#include <3ds/mappable.h>
#include <3ds/services/apt.h>
#include <3ds/services/hid.h>
#include <3ds/services/irrst.h>
static bool hidInitialised;
-Result hidInit(u32* sharedMem)
+Result hidInit()
{
u8 val=0;
Result ret=0;
if(hidInitialised) return ret;
- if(!sharedMem)sharedMem=(u32*)HID_SHAREDMEM_DEFAULT;
-
// Request service.
if((ret=srvGetServiceHandle(&hidHandle, "hid:USER")) && (ret=srvGetServiceHandle(&hidHandle, "hid:SPVR")))return ret;
// Get sharedmem handle.
if((ret=HIDUSER_GetHandles(&hidMemHandle, &hidEvents[HIDEVENT_PAD0], &hidEvents[HIDEVENT_PAD1], &hidEvents[HIDEVENT_Accel], &hidEvents[HIDEVENT_Gyro], &hidEvents[HIDEVENT_DebugPad]))) goto cleanup1;
- // Map HID shared memory at addr "sharedMem".
- hidSharedMem=sharedMem;
+ // Map HID shared memory.
+ hidSharedMem=(vu32*)mappableAlloc(0x2b0);
+ if(!hidSharedMem)
+ {
+ ret = -1;
+ goto cleanup1;
+ }
+
if((ret=svcMapMemoryBlock(hidMemHandle, (u32)hidSharedMem, MEMPERM_READ, 0x10000000)))goto cleanup2;
APT_CheckNew3DS(NULL, &val);
if(val)
{
- ret = irrstInit(NULL);
+ ret = irrstInit();
}
// Reset internal state.
cleanup2:
svcCloseHandle(hidMemHandle);
+ if(hidSharedMem != NULL)
+ {
+ mappableFree((void*) hidSharedMem);
+ hidSharedMem = NULL;
+ }
cleanup1:
svcCloseHandle(hidHandle);
return ret;
{
irrstExit();
}
+
+ if(hidSharedMem != NULL)
+ {
+ mappableFree((void*) hidSharedMem);
+ hidSharedMem = NULL;
+ }
hidInitialised = false;
}
#include <3ds/types.h>
#include <3ds/svc.h>
#include <3ds/srv.h>
+#include <3ds/mappable.h>
#include <3ds/services/irrst.h>
// used to determine whether or not we should do IRRST_Initialize
static circlePosition csPos;
static bool irrstUsed = false;
-Result irrstInit(u32* sharedMem)
+Result irrstInit()
{
if(irrstUsed)return 0;
- if(!sharedMem)sharedMem=(u32*)IRRST_SHAREDMEM_DEFAULT;
Result ret=0;
// Request service.
// Initialize ir:rst
if(__get_handle_from_list("ir:rst")==0)ret=IRRST_Initialize(10, 0);
- // Map ir:rst shared memory at addr "sharedMem".
- irrstSharedMem=sharedMem;
+ // Map ir:rst shared memory.
+ irrstSharedMem=(vu32*)mappableAlloc(0x98);
+ if(!irrstSharedMem)
+ {
+ ret = -1;
+ goto cleanup1;
+ }
+
if((ret=svcMapMemoryBlock(irrstMemHandle, (u32)irrstSharedMem, MEMPERM_READ, 0x10000000)))goto cleanup2;
// Reset internal state.
cleanup2:
svcCloseHandle(irrstMemHandle);
+ if(irrstSharedMem != NULL)
+ {
+ mappableFree((void*) irrstSharedMem);
+ irrstSharedMem = NULL;
+ }
cleanup1:
svcCloseHandle(irrstHandle);
return ret;
if(__get_handle_from_list("ir:rst")==0) IRRST_Shutdown();
svcCloseHandle(irrstMemHandle);
svcCloseHandle(irrstHandle);
+
+ if(irrstSharedMem != NULL)
+ {
+ mappableFree((void*) irrstSharedMem);
+ irrstSharedMem = NULL;
+ }
}
void irrstWaitForEvent(bool nextEvent)
// Initialize services
srvInit();
aptInit();
- hidInit(NULL);
+ hidInit();
fsInit();
sdmcInit();