mirror of
https://github.com/libretro/RetroArch
synced 2025-03-30 07:20:36 +00:00
(CTR) Style nits
This commit is contained in:
parent
98b847cad9
commit
41ffca2b6f
@ -37,25 +37,32 @@ void ctr_linear_free_pages(u32 pages);
|
||||
|
||||
void ctr_free_pages(u32 pages)
|
||||
{
|
||||
u32 linear_free_pages;
|
||||
u32 stack_free, stack_usage, stack_free_pages;
|
||||
|
||||
if(!pages)
|
||||
return;
|
||||
|
||||
u32 linear_free_pages = ctr_get_linear_free() >> 12;
|
||||
linear_free_pages = ctr_get_linear_free() >> 12;
|
||||
|
||||
if((ctr_get_linear_unused() >> 12) > pages + 0x100)
|
||||
if ((ctr_get_linear_unused() >> 12) > pages + 0x100)
|
||||
return ctr_linear_free_pages(pages);
|
||||
|
||||
#if 0
|
||||
if(linear_free_pages > pages + 0x400)
|
||||
if (linear_free_pages > pages + 0x400)
|
||||
return ctr_linear_free_pages(pages);
|
||||
#endif
|
||||
|
||||
u32 stack_free = ctr_get_stack_free();
|
||||
u32 stack_usage = __stacksize__ > stack_free? __stacksize__ - stack_free: 0;
|
||||
stack_free = ctr_get_stack_free();
|
||||
stack_usage = __stacksize__ > stack_free
|
||||
? __stacksize__ - stack_free
|
||||
: 0;
|
||||
|
||||
stack_free = stack_free > __stack_size_extra ? __stack_size_extra : stack_free;
|
||||
stack_free = stack_free > __stack_size_extra
|
||||
? __stack_size_extra
|
||||
: stack_free;
|
||||
|
||||
u32 stack_free_pages = stack_free >> 12;
|
||||
stack_free_pages = stack_free >> 12;
|
||||
|
||||
if(linear_free_pages + (stack_free_pages - (stack_usage >> 12)) > pages)
|
||||
{
|
||||
@ -83,7 +90,8 @@ void ctr_free_pages(u32 pages)
|
||||
__stacksize__ -= stack_free_pages << 12;
|
||||
#if 0
|
||||
printf("s:0x%08X-->0x%08X(-0x%08X) \n", stack_free,
|
||||
stack_free - (stack_free_pages << 12), stack_free_pages << 12);
|
||||
stack_free - (stack_free_pages << 12),
|
||||
stack_free_pages << 12);
|
||||
DEBUG_HOLD();
|
||||
#endif
|
||||
}
|
||||
@ -111,11 +119,12 @@ void* _sbrk_r(struct _reent *ptr, ptrdiff_t incr)
|
||||
{
|
||||
static u32 sbrk_top = 0;
|
||||
u32 tmp;
|
||||
int diff;
|
||||
|
||||
if (!sbrk_top)
|
||||
sbrk_top = __heapBase;
|
||||
|
||||
int diff = ((sbrk_top + incr + 0xFFF) & ~0xFFF)
|
||||
diff = ((sbrk_top + incr + 0xFFF) & ~0xFFF)
|
||||
- (__heapBase + __heap_size);
|
||||
|
||||
if (diff > 0)
|
||||
|
265
ctr/ctr_svchax.c
265
ctr/ctr_svchax.c
@ -15,13 +15,53 @@
|
||||
#define SVC_ACL_MASK(svc_id) (0x1 << ((svc_id) & 0x1F))
|
||||
#define THREAD_PAGE_ACL_OFFSET 0xF38
|
||||
|
||||
u32 __ctr_svchax = 0;
|
||||
u32 __ctr_svchax = 0;
|
||||
u32 __ctr_svchax_srv = 0;
|
||||
|
||||
extern void* __service_ptr;
|
||||
|
||||
typedef u32(*backdoor_fn)(u32 arg0, u32 arg1);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Handle started_event;
|
||||
Handle lock;
|
||||
volatile u32 target_kaddr;
|
||||
volatile u32 target_val;
|
||||
} mch2_thread_args_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32* stack_top;
|
||||
Handle handle;
|
||||
bool keep;
|
||||
mch2_thread_args_t args;
|
||||
} mch2_thread_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 old_cpu_time_limit;
|
||||
bool isNew3DS;
|
||||
u32 kernel_fcram_mapping_offset;
|
||||
|
||||
Handle arbiter;
|
||||
volatile u32 alloc_address;
|
||||
volatile u32 alloc_size;
|
||||
u8* flush_buffer;
|
||||
|
||||
Handle dummy_threads_lock;
|
||||
Handle target_threads_lock;
|
||||
Handle main_thread_lock;
|
||||
u32* thread_page_va;
|
||||
u32 thread_page_kva;
|
||||
|
||||
u32 threads_limit;
|
||||
Handle alloc_thread;
|
||||
Handle poll_thread;
|
||||
mch2_thread_t threads[MCH2_THREAD_COUNT_MAX];
|
||||
} mch2_vars_t;
|
||||
|
||||
|
||||
__attribute((naked))
|
||||
static u32 svc_7b(backdoor_fn entry_fn, ...) /* can pass up to two arguments to entry_fn(...) */
|
||||
{
|
||||
@ -46,7 +86,7 @@ static u32 svc_7b(backdoor_fn entry_fn, ...) /* can pass up to two arguments to
|
||||
|
||||
static void k_enable_all_svcs(u32 isNew3DS)
|
||||
{
|
||||
u32* thread_ACL = *(*(u32***)CURRENT_KTHREAD + 0x22) - 0x6;
|
||||
u32* thread_ACL = *(*(u32***)CURRENT_KTHREAD + 0x22) - 0x6;
|
||||
u32* process_ACL = *(u32**)CURRENT_KPROCESS + (isNew3DS ? 0x24 : 0x22);
|
||||
|
||||
memset(thread_ACL, 0xFF, 0x10);
|
||||
@ -88,45 +128,6 @@ static u32 get_thread_page(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Handle started_event;
|
||||
Handle lock;
|
||||
volatile u32 target_kaddr;
|
||||
volatile u32 target_val;
|
||||
} mch2_thread_args_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32* stack_top;
|
||||
Handle handle;
|
||||
bool keep;
|
||||
mch2_thread_args_t args;
|
||||
} mch2_thread_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 old_cpu_time_limit;
|
||||
bool isNew3DS;
|
||||
u32 kernel_fcram_mapping_offset;
|
||||
|
||||
Handle arbiter;
|
||||
volatile u32 alloc_address;
|
||||
volatile u32 alloc_size;
|
||||
u8* flush_buffer;
|
||||
|
||||
Handle dummy_threads_lock;
|
||||
Handle target_threads_lock;
|
||||
Handle main_thread_lock;
|
||||
u32* thread_page_va;
|
||||
u32 thread_page_kva;
|
||||
|
||||
u32 threads_limit;
|
||||
Handle alloc_thread;
|
||||
Handle poll_thread;
|
||||
mch2_thread_t threads[MCH2_THREAD_COUNT_MAX];
|
||||
} mch2_vars_t;
|
||||
|
||||
static void alloc_thread_entry(mch2_vars_t* mch2)
|
||||
{
|
||||
u32 tmp;
|
||||
@ -162,7 +163,7 @@ static u32 get_first_free_basemem_page(bool isNew3DS)
|
||||
{
|
||||
s64 v1;
|
||||
int memused_base_linear; /* guessed */
|
||||
int memused_base = osGetMemRegionUsed(MEMREGION_BASE);
|
||||
int memused_base = osGetMemRegionUsed(MEMREGION_BASE);
|
||||
|
||||
svcGetSystemInfo(&v1, 2, 0);
|
||||
memused_base_linear = 0x6C000 + v1 +
|
||||
@ -197,13 +198,25 @@ static void do_memchunkhax2(void)
|
||||
{
|
||||
static u8 flush_buffer[0x8000];
|
||||
static u8 thread_stacks[MCH2_THREAD_STACKS_SIZE];
|
||||
|
||||
extern u32 __heapBase;
|
||||
extern u32 __heap_size;
|
||||
int i;
|
||||
u32 tmp;
|
||||
mch2_vars_t mch2 = {0};
|
||||
u32 linear_buffer;
|
||||
u32 linear_address;
|
||||
u32 dst_memchunk;
|
||||
u32 mem_free;
|
||||
u32 fragmented_size;
|
||||
u32* mapped_page;
|
||||
volatile u32 *thread_ACL;
|
||||
u32 alloc_address_kaddr;
|
||||
u32 fragmented_address = 0;
|
||||
u32 linear_size = 0xF000;
|
||||
u32 skip_pages = 2;
|
||||
mch2_vars_t mch2 = {0};
|
||||
|
||||
mch2.flush_buffer = flush_buffer;
|
||||
mch2.threads_limit = get_threads_limit();
|
||||
mch2.flush_buffer = flush_buffer;
|
||||
mch2.threads_limit = get_threads_limit();
|
||||
mch2.kernel_fcram_mapping_offset = (osGetKernelVersion() > SYSTEM_VERSION(2, 40, 0)) ? 0xC0000000 : 0xD0000000;
|
||||
|
||||
for (i = 0; i < MCH2_THREAD_COUNT_MAX; i++)
|
||||
@ -215,8 +228,10 @@ static void do_memchunkhax2(void)
|
||||
|
||||
for (i = 0; i < mch2.threads_limit; i++)
|
||||
{
|
||||
svcCreateThread(&mch2.threads[i].handle, (ThreadFunc)check_tls_thread_entry, (u32)&mch2.threads[i].keep,
|
||||
mch2.threads[i].stack_top, 0x18, 0);
|
||||
svcCreateThread(&mch2.threads[i].handle,
|
||||
(ThreadFunc)check_tls_thread_entry,
|
||||
(u32)&mch2.threads[i].keep,
|
||||
mch2.threads[i].stack_top, 0x18, 0);
|
||||
svcWaitSynchronization(mch2.threads[i].handle, U64_MAX);
|
||||
}
|
||||
|
||||
@ -229,61 +244,70 @@ static void do_memchunkhax2(void)
|
||||
|
||||
for (i = 0; i < mch2.threads_limit; i++)
|
||||
if (!mch2.threads[i].keep)
|
||||
svcCreateThread(&mch2.threads[i].handle, (ThreadFunc)dummy_thread_entry, mch2.dummy_threads_lock,
|
||||
mch2.threads[i].stack_top, 0x3F - i, 0);
|
||||
svcCreateThread(&mch2.threads[i].handle,
|
||||
(ThreadFunc)dummy_thread_entry,
|
||||
mch2.dummy_threads_lock,
|
||||
mch2.threads[i].stack_top, 0x3F - i, 0);
|
||||
|
||||
svcSignalEvent(mch2.dummy_threads_lock);
|
||||
|
||||
for (i = mch2.threads_limit - 1; i >= 0; i--)
|
||||
{
|
||||
if (!mch2.threads[i].keep)
|
||||
{
|
||||
svcWaitSynchronization(mch2.threads[i].handle, U64_MAX);
|
||||
svcCloseHandle(mch2.threads[i].handle);
|
||||
mch2.threads[i].handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
svcCloseHandle(mch2.dummy_threads_lock);
|
||||
|
||||
u32 fragmented_address = 0;
|
||||
mch2.arbiter = __sync_get_arbiter();
|
||||
|
||||
mch2.arbiter = __sync_get_arbiter();
|
||||
svcControlMemory(&linear_buffer, 0, 0, 0x1000,
|
||||
MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE);
|
||||
|
||||
u32 linear_buffer;
|
||||
svcControlMemory(&linear_buffer, 0, 0, 0x1000, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE);
|
||||
mch2.alloc_size = ((((linear_size - (skip_pages << 12))
|
||||
+ 0x1000) >> 13) << 12);
|
||||
|
||||
u32 linear_size = 0xF000;
|
||||
u32 skip_pages = 2;
|
||||
mch2.alloc_size = ((((linear_size - (skip_pages << 12)) + 0x1000) >> 13) << 12);
|
||||
u32 mem_free = osGetMemRegionFree(MEMREGION_APPLICATION);
|
||||
mem_free = osGetMemRegionFree(MEMREGION_APPLICATION);
|
||||
fragmented_size = mem_free - linear_size;
|
||||
|
||||
u32 fragmented_size = mem_free - linear_size;
|
||||
extern u32 __heapBase;
|
||||
extern u32 __heap_size;
|
||||
fragmented_address = __heapBase + __heap_size;
|
||||
u32 linear_address;
|
||||
mch2.alloc_address = fragmented_address + fragmented_size;
|
||||
fragmented_address = __heapBase + __heap_size;
|
||||
mch2.alloc_address = fragmented_address + fragmented_size;
|
||||
|
||||
svcControlMemory(&linear_address, 0x0, 0x0, linear_size, MEMOP_ALLOC_LINEAR,
|
||||
MEMPERM_READ | MEMPERM_WRITE);
|
||||
svcControlMemory(&linear_address,
|
||||
0x0, 0x0, linear_size, MEMOP_ALLOC_LINEAR,
|
||||
MEMPERM_READ | MEMPERM_WRITE);
|
||||
|
||||
if (fragmented_size)
|
||||
svcControlMemory(&tmp, (u32)fragmented_address, 0x0, fragmented_size, MEMOP_ALLOC,
|
||||
MEMPERM_READ | MEMPERM_WRITE);
|
||||
svcControlMemory(&tmp,
|
||||
(u32)fragmented_address, 0x0, fragmented_size, MEMOP_ALLOC,
|
||||
MEMPERM_READ | MEMPERM_WRITE);
|
||||
|
||||
if (skip_pages)
|
||||
svcControlMemory(&tmp, (u32)linear_address, 0x0, (skip_pages << 12), MEMOP_FREE, MEMPERM_DONTCARE);
|
||||
svcControlMemory(&tmp,
|
||||
(u32)linear_address, 0x0, (skip_pages << 12), MEMOP_FREE,
|
||||
MEMPERM_DONTCARE);
|
||||
|
||||
for (i = skip_pages; i < (linear_size >> 12) ; i += 2)
|
||||
svcControlMemory(&tmp, (u32)linear_address + (i << 12), 0x0, 0x1000, MEMOP_FREE, MEMPERM_DONTCARE);
|
||||
svcControlMemory(&tmp,
|
||||
(u32)linear_address + (i << 12), 0x0, 0x1000,
|
||||
MEMOP_FREE, MEMPERM_DONTCARE);
|
||||
|
||||
u32 alloc_address_kaddr = osConvertVirtToPhys((void*)linear_address) + mch2.kernel_fcram_mapping_offset;
|
||||
alloc_address_kaddr = osConvertVirtToPhys(
|
||||
(void*)linear_address) + mch2.kernel_fcram_mapping_offset;
|
||||
|
||||
mch2.thread_page_kva = get_first_free_basemem_page(mch2.isNew3DS) - 0x10000; /* skip down 16 pages */
|
||||
mch2.thread_page_kva = get_first_free_basemem_page(mch2.isNew3DS)
|
||||
- 0x10000; /* skip down 16 pages */
|
||||
((u32*)linear_buffer)[0] = 1;
|
||||
((u32*)linear_buffer)[1] = mch2.thread_page_kva;
|
||||
((u32*)linear_buffer)[2] = alloc_address_kaddr + (((mch2.alloc_size >> 12) - 3) << 13) + (skip_pages << 12);
|
||||
|
||||
u32 dst_memchunk = linear_address + (((mch2.alloc_size >> 12) - 2) << 13) + (skip_pages << 12);
|
||||
dst_memchunk = linear_address
|
||||
+ (((mch2.alloc_size >> 12) - 2) << 13)
|
||||
+ (skip_pages << 12);
|
||||
|
||||
memcpy(flush_buffer, flush_buffer + 0x4000, 0x4000);
|
||||
|
||||
@ -291,18 +315,21 @@ static void do_memchunkhax2(void)
|
||||
GSPGPU_FlushDataCache((void*)linear_buffer, 16);
|
||||
memcpy(flush_buffer, flush_buffer + 0x4000, 0x4000);
|
||||
|
||||
/* can't clear gspEvents[GSPGPU_EVENT_PPF]), directly so execute a dummy copy
|
||||
* and use gspWaitForEvent to clear it. */
|
||||
/* can't clear gspEvents[GSPGPU_EVENT_PPF]),
|
||||
* directly so execute a dummy copy
|
||||
* and use gspWaitForEvent to clear it. */
|
||||
|
||||
/* LightEvent_Clear(&gspEvents[GSPGPU_EVENT_PPF]); */
|
||||
/* LightEvent_Clear(&gspEvents[GSPGPU_EVENT_PPF]); */
|
||||
GX_TextureCopy((void*)linear_buffer, 0, (void*)dst_memchunk, 0, 16, 8);
|
||||
gspWaitForEvent(GSPGPU_EVENT_PPF, false);
|
||||
|
||||
svcCreateThread(&mch2.alloc_thread, (ThreadFunc)alloc_thread_entry, (u32)&mch2,
|
||||
mch2.threads[MCH2_THREAD_COUNT_MAX - 1].stack_top, 0x3F, 1);
|
||||
svcCreateThread(&mch2.alloc_thread,
|
||||
(ThreadFunc)alloc_thread_entry, (u32)&mch2,
|
||||
mch2.threads[MCH2_THREAD_COUNT_MAX - 1].stack_top, 0x3F, 1);
|
||||
|
||||
while ((u32) svcArbitrateAddress(mch2.arbiter, mch2.alloc_address, ARBITRATION_WAIT_IF_LESS_THAN_TIMEOUT, 0,
|
||||
0) == 0xD9001814);
|
||||
while ((u32) svcArbitrateAddress(mch2.arbiter, mch2.alloc_address,
|
||||
ARBITRATION_WAIT_IF_LESS_THAN_TIMEOUT, 0,
|
||||
0) == 0xD9001814);
|
||||
|
||||
GX_TextureCopy((void*)linear_buffer, 0, (void*)dst_memchunk, 0, 16, 8);
|
||||
memcpy(flush_buffer, flush_buffer + 0x4000, 0x4000);
|
||||
@ -311,9 +338,9 @@ static void do_memchunkhax2(void)
|
||||
svcWaitSynchronization(mch2.alloc_thread, U64_MAX);
|
||||
svcCloseHandle(mch2.alloc_thread);
|
||||
|
||||
u32* mapped_page = (u32*)(mch2.alloc_address + mch2.alloc_size - 0x1000);
|
||||
|
||||
volatile u32* thread_ACL = &mapped_page[THREAD_PAGE_ACL_OFFSET >> 2];
|
||||
mapped_page = (u32*)
|
||||
(mch2.alloc_address + mch2.alloc_size - 0x1000);
|
||||
thread_ACL = &mapped_page[THREAD_PAGE_ACL_OFFSET >> 2];
|
||||
|
||||
svcCreateEvent(&mch2.main_thread_lock, 0);
|
||||
svcCreateEvent(&mch2.target_threads_lock, 1);
|
||||
@ -325,16 +352,18 @@ static void do_memchunkhax2(void)
|
||||
continue;
|
||||
|
||||
mch2.threads[i].args.started_event = mch2.main_thread_lock;
|
||||
mch2.threads[i].args.lock = mch2.target_threads_lock;
|
||||
mch2.threads[i].args.target_kaddr = 0;
|
||||
mch2.threads[i].args.lock = mch2.target_threads_lock;
|
||||
mch2.threads[i].args.target_kaddr = 0;
|
||||
|
||||
thread_ACL[0] = 0;
|
||||
thread_ACL[0] = 0;
|
||||
GSPGPU_FlushDataCache((void*)thread_ACL, 16);
|
||||
GSPGPU_InvalidateDataCache((void*)thread_ACL, 16);
|
||||
|
||||
svcClearEvent(mch2.main_thread_lock);
|
||||
svcCreateThread(&mch2.threads[i].handle, (ThreadFunc)target_thread_entry, (u32)&mch2.threads[i].args,
|
||||
mch2.threads[i].stack_top, 0x18, 0);
|
||||
svcCreateThread(&mch2.threads[i].handle,
|
||||
(ThreadFunc)target_thread_entry,
|
||||
(u32)&mch2.threads[i].args,
|
||||
mch2.threads[i].stack_top, 0x18, 0);
|
||||
svcWaitSynchronization(mch2.main_thread_lock, U64_MAX);
|
||||
|
||||
if (thread_ACL[0])
|
||||
@ -342,8 +371,10 @@ static void do_memchunkhax2(void)
|
||||
thread_ACL[SVC_ACL_OFFSET(0x7B) >> 2] = SVC_ACL_MASK(0x7B);
|
||||
GSPGPU_FlushDataCache((void*)thread_ACL, 16);
|
||||
GSPGPU_InvalidateDataCache((void*)thread_ACL, 16);
|
||||
mch2.threads[i].args.target_kaddr = get_thread_page() + THREAD_PAGE_ACL_OFFSET + SVC_ACL_OFFSET(0x7B);
|
||||
mch2.threads[i].args.target_val = SVC_ACL_MASK(0x7B);
|
||||
mch2.threads[i].args.target_kaddr = get_thread_page()
|
||||
+ THREAD_PAGE_ACL_OFFSET
|
||||
+ SVC_ACL_OFFSET(0x7B);
|
||||
mch2.threads[i].args.target_val = SVC_ACL_MASK(0x7B);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -365,14 +396,18 @@ static void do_memchunkhax2(void)
|
||||
svcCloseHandle(mch2.target_threads_lock);
|
||||
svcCloseHandle(mch2.main_thread_lock);
|
||||
|
||||
svcControlMemory(&tmp, mch2.alloc_address, 0, mch2.alloc_size, MEMOP_FREE, MEMPERM_DONTCARE);
|
||||
svcControlMemory(&tmp, mch2.alloc_address, 0, mch2.alloc_size,
|
||||
MEMOP_FREE, MEMPERM_DONTCARE);
|
||||
write_kaddr(alloc_address_kaddr + linear_size - 0x3000 + 0x4, alloc_address_kaddr + linear_size - 0x1000);
|
||||
svcControlMemory(&tmp, (u32)fragmented_address, 0x0, fragmented_size, MEMOP_FREE, MEMPERM_DONTCARE);
|
||||
svcControlMemory(&tmp, (u32)fragmented_address, 0x0, fragmented_size,
|
||||
MEMOP_FREE, MEMPERM_DONTCARE);
|
||||
|
||||
for (i = 1 + skip_pages; i < (linear_size >> 12) ; i += 2)
|
||||
svcControlMemory(&tmp, (u32)linear_address + (i << 12), 0x0, 0x1000, MEMOP_FREE, MEMPERM_DONTCARE);
|
||||
svcControlMemory(&tmp, (u32)linear_address + (i << 12), 0x0, 0x1000,
|
||||
MEMOP_FREE, MEMPERM_DONTCARE);
|
||||
|
||||
svcControlMemory(&tmp, linear_buffer, 0, 0x1000, MEMOP_FREE, MEMPERM_DONTCARE);
|
||||
svcControlMemory(&tmp, linear_buffer, 0, 0x1000, MEMOP_FREE,
|
||||
MEMPERM_DONTCARE);
|
||||
|
||||
APT_SetAppCpuTimeLimit(mch2.old_cpu_time_limit);
|
||||
}
|
||||
@ -418,7 +453,8 @@ static void memchunkhax1_write_pair(u32 val1, u32 val2)
|
||||
u32* next_ptr1;
|
||||
u32* prev_ptr6;
|
||||
|
||||
svcControlMemory(&linear_buffer, 0, 0, 0x10000, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE);
|
||||
svcControlMemory(&linear_buffer, 0, 0, 0x10000,
|
||||
MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE);
|
||||
|
||||
flush_buffer = (u8*)(linear_buffer + 0x8000);
|
||||
|
||||
@ -426,23 +462,24 @@ static void memchunkhax1_write_pair(u32 val1, u32 val2)
|
||||
svcControlMemory(&tmp, linear_buffer + 0x3000, 0, 0x2000, MEMOP_FREE, 0);
|
||||
svcControlMemory(&tmp, linear_buffer + 0x6000, 0, 0x1000, MEMOP_FREE, 0);
|
||||
|
||||
next_ptr1 = (u32*)(linear_buffer + 0x0004);
|
||||
next_ptr1 = (u32*)(linear_buffer + 0x0004);
|
||||
gspwn(linear_buffer + 0x0000, linear_buffer + 0x1000, 16, flush_buffer);
|
||||
|
||||
next_ptr3 = (u32*)(linear_buffer + 0x2004);
|
||||
prev_ptr3 = (u32*)(linear_buffer + 0x2008);
|
||||
next_ptr3 = (u32*)(linear_buffer + 0x2004);
|
||||
prev_ptr3 = (u32*)(linear_buffer + 0x2008);
|
||||
gspwn(linear_buffer + 0x2000, linear_buffer + 0x3000, 16, flush_buffer);
|
||||
|
||||
prev_ptr6 = (u32*)(linear_buffer + 0x5008);
|
||||
prev_ptr6 = (u32*)(linear_buffer + 0x5008);
|
||||
gspwn(linear_buffer + 0x5000, linear_buffer + 0x6000, 16, flush_buffer);
|
||||
|
||||
*next_ptr1 = *next_ptr3;
|
||||
*prev_ptr6 = *prev_ptr3;
|
||||
*next_ptr1 = *next_ptr3;
|
||||
*prev_ptr6 = *prev_ptr3;
|
||||
|
||||
*prev_ptr3 = val1 - 4;
|
||||
*next_ptr3 = val2;
|
||||
*prev_ptr3 = val1 - 4;
|
||||
*next_ptr3 = val2;
|
||||
gspwn(linear_buffer + 0x3000, linear_buffer + 0x2000, 16, flush_buffer);
|
||||
svcControlMemory(&tmp, 0, 0, 0x2000, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE);
|
||||
svcControlMemory(&tmp, 0, 0, 0x2000,
|
||||
MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE);
|
||||
|
||||
gspwn(linear_buffer + 0x1000, linear_buffer + 0x0000, 16, flush_buffer);
|
||||
gspwn(linear_buffer + 0x6000, linear_buffer + 0x5000, 16, flush_buffer);
|
||||
@ -450,7 +487,6 @@ static void memchunkhax1_write_pair(u32 val1, u32 val2)
|
||||
svcControlMemory(&tmp, linear_buffer + 0x0000, 0, 0x1000, MEMOP_FREE, 0);
|
||||
svcControlMemory(&tmp, linear_buffer + 0x2000, 0, 0x4000, MEMOP_FREE, 0);
|
||||
svcControlMemory(&tmp, linear_buffer + 0x7000, 0, 0x9000, MEMOP_FREE, 0);
|
||||
|
||||
}
|
||||
|
||||
static void do_memchunkhax1(void)
|
||||
@ -458,7 +494,9 @@ static void do_memchunkhax1(void)
|
||||
u32 saved_vram_value = *(u32*)0x1F000008;
|
||||
|
||||
/* 0x1F000000 contains the enable bit for svc 0x7B */
|
||||
memchunkhax1_write_pair(get_thread_page() + THREAD_PAGE_ACL_OFFSET + SVC_ACL_OFFSET(0x7B), 0x1F000000);
|
||||
memchunkhax1_write_pair(get_thread_page()
|
||||
+ THREAD_PAGE_ACL_OFFSET
|
||||
+ SVC_ACL_OFFSET(0x7B), 0x1F000000);
|
||||
|
||||
write_kaddr(0x1F000008, saved_vram_value);
|
||||
}
|
||||
@ -480,9 +518,11 @@ Result get_luma_version(u32 *major, u32 *minor)
|
||||
Result svchax_init(bool patch_srv)
|
||||
{
|
||||
bool isNew3DS;
|
||||
u32 kver;
|
||||
|
||||
APT_CheckNew3DS(&isNew3DS);
|
||||
|
||||
u32 kver = osGetKernelVersion();
|
||||
kver = osGetKernelVersion();
|
||||
|
||||
if (!__ctr_svchax)
|
||||
{
|
||||
@ -491,9 +531,11 @@ Result svchax_init(bool patch_srv)
|
||||
u32 luma_major, luma_minor;
|
||||
|
||||
if (kver > SYSTEM_VERSION(2, 50, 11) &&
|
||||
(R_FAILED(get_luma_version(&luma_major, &luma_minor) || luma_major < 8)))
|
||||
(R_FAILED(get_luma_version(&luma_major, &luma_minor)
|
||||
|| luma_major < 8)))
|
||||
return -1;
|
||||
else if (kver > SYSTEM_VERSION(2, 46, 0) && kver <= SYSTEM_VERSION(2, 50, 11))
|
||||
else if (kver > SYSTEM_VERSION(2, 46, 0)
|
||||
&& kver <= SYSTEM_VERSION(2, 50, 11))
|
||||
do_memchunkhax2();
|
||||
else if (kver <= SYSTEM_VERSION(2, 46, 0))
|
||||
do_memchunkhax1();
|
||||
@ -506,8 +548,9 @@ Result svchax_init(bool patch_srv)
|
||||
|
||||
if (patch_srv && !__ctr_svchax_srv)
|
||||
{
|
||||
u32 PID_kaddr = read_kaddr(CURRENT_KPROCESS) + (isNew3DS ? 0xBC : (kver > SYSTEM_VERSION(2, 40, 0)) ? 0xB4 : 0xAC);
|
||||
u32 old_PID = read_kaddr(PID_kaddr);
|
||||
u32 PID_kaddr = read_kaddr(CURRENT_KPROCESS)
|
||||
+ (isNew3DS ? 0xBC : (kver > SYSTEM_VERSION(2, 40, 0)) ? 0xB4 : 0xAC);
|
||||
u32 old_PID = read_kaddr(PID_kaddr);
|
||||
write_kaddr(PID_kaddr, 0);
|
||||
srvExit();
|
||||
srvInit();
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#define CTR_APPMEMALLOC_PTR ((u32*)0x1FF80040)
|
||||
|
||||
/* Global variables */
|
||||
u32 __stacksize__ = 0x00400000;
|
||||
u32 __linear_heap_size = 0x01000000;
|
||||
|
||||
@ -22,22 +23,24 @@ u32 __stack_size_extra;
|
||||
|
||||
extern u32 __linear_heap_size_hbl;
|
||||
extern u32 __heap_size_hbl;
|
||||
extern void* __service_ptr;
|
||||
|
||||
extern void (*__system_retAddr)(void);
|
||||
|
||||
/* Forward declarations */
|
||||
void envDestroyHandles(void);
|
||||
void __appExit();
|
||||
void __appExit(void);
|
||||
void __libc_fini_array(void);
|
||||
|
||||
void __appInit();
|
||||
void __appInit(void);
|
||||
void __libc_init_array(void);
|
||||
void __system_initSyscalls(void);
|
||||
void __system_initArgv();
|
||||
void __system_initArgv(void);
|
||||
|
||||
void __ctru_exit(int rc);
|
||||
int __libctru_gtod(struct _reent* ptr, struct timeval* tp, struct timezone* tz);
|
||||
int __libctru_gtod(struct _reent* ptr,
|
||||
struct timeval* tp, struct timezone* tz);
|
||||
void (*__system_retAddr)(void);
|
||||
extern void* __service_ptr;
|
||||
|
||||
Result __sync_init(void) __attribute__((weak));
|
||||
|
||||
@ -140,37 +143,41 @@ extern const char* __system_arglist;
|
||||
char __argv_hmac[0x20] = {0x1d, 0x78, 0xff, 0xb9, 0xc5, 0xbc, 0x78, 0xb7, 0xac, 0x29, 0x1d, 0x3e, 0x16, 0xd0, 0xcf, 0x53,
|
||||
0xef, 0x12, 0x58, 0x83, 0xb6, 0x9e, 0x2f, 0x79, 0x47, 0xf9, 0x35, 0x61, 0xeb, 0x50, 0xd7, 0x67};
|
||||
|
||||
Result APT_ReceiveDeliverArg_(void* param, size_t param_size, void* hmac, size_t hmac_size, u64* source_pid, bool* received)
|
||||
Result APT_ReceiveDeliverArg_(void* param, size_t param_size,
|
||||
void* hmac, size_t hmac_size, u64* source_pid, bool* received)
|
||||
{
|
||||
u32 cmdbuf[16];
|
||||
cmdbuf[0]=IPC_MakeHeader(0x35,2,0);
|
||||
cmdbuf[1]=param_size;
|
||||
cmdbuf[2]=hmac_size;
|
||||
|
||||
u32 saved_threadstorage[4];
|
||||
u32* staticbufs = getThreadStaticBuffers();
|
||||
saved_threadstorage[0]=staticbufs[0];
|
||||
saved_threadstorage[1]=staticbufs[1];
|
||||
saved_threadstorage[2]=staticbufs[2];
|
||||
saved_threadstorage[3]=staticbufs[3];
|
||||
staticbufs[0]=IPC_Desc_StaticBuffer(param_size, 0);
|
||||
staticbufs[1]=(u32)param;
|
||||
staticbufs[2]=IPC_Desc_StaticBuffer(hmac_size, 2);
|
||||
staticbufs[3]=(u32)hmac;
|
||||
u32 *staticbufs;
|
||||
Result ret;
|
||||
|
||||
Result ret = aptSendCommand(cmdbuf);
|
||||
staticbufs[0]=saved_threadstorage[0];
|
||||
staticbufs[1]=saved_threadstorage[1];
|
||||
staticbufs[2]=saved_threadstorage[2];
|
||||
staticbufs[3]=saved_threadstorage[3];
|
||||
cmdbuf[0] = IPC_MakeHeader(0x35,2,0);
|
||||
cmdbuf[1] = param_size;
|
||||
cmdbuf[2] = hmac_size;
|
||||
|
||||
staticbufs = getThreadStaticBuffers();
|
||||
saved_threadstorage[0] = staticbufs[0];
|
||||
saved_threadstorage[1] = staticbufs[1];
|
||||
saved_threadstorage[2] = staticbufs[2];
|
||||
saved_threadstorage[3] = staticbufs[3];
|
||||
staticbufs[0] = IPC_Desc_StaticBuffer(param_size, 0);
|
||||
staticbufs[1] = (u32)param;
|
||||
staticbufs[2] = IPC_Desc_StaticBuffer(hmac_size, 2);
|
||||
staticbufs[3] = (u32)hmac;
|
||||
|
||||
ret = aptSendCommand(cmdbuf);
|
||||
staticbufs[0] = saved_threadstorage[0];
|
||||
staticbufs[1] = saved_threadstorage[1];
|
||||
staticbufs[2] = saved_threadstorage[2];
|
||||
staticbufs[3] = saved_threadstorage[3];
|
||||
|
||||
if(R_FAILED(ret))
|
||||
return ret;
|
||||
|
||||
if(source_pid)
|
||||
*source_pid = ((u64*)cmdbuf)[1];
|
||||
*source_pid = ((u64*)cmdbuf)[1];
|
||||
if(received)
|
||||
*received = ((bool*)cmdbuf)[16];
|
||||
*received = ((bool*)cmdbuf)[16];
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
@ -202,13 +209,15 @@ void __system_initArgv(void)
|
||||
|
||||
if (__system_argc)
|
||||
{
|
||||
__system_argv = (char**) malloc((__system_argc + 1) * sizeof(char**));
|
||||
__system_argv[0] = arg_struct->args;
|
||||
__system_argv = (char**)malloc(
|
||||
(__system_argc + 1) * sizeof(char**));
|
||||
__system_argv[0] = arg_struct->args;
|
||||
for (i = 1; i < __system_argc; i++)
|
||||
__system_argv[i] = __system_argv[i - 1] + strlen(__system_argv[i - 1]) + 1;
|
||||
|
||||
i = __system_argc - 1;
|
||||
i = __system_argc - 1;
|
||||
__system_argc = 1;
|
||||
|
||||
while (i)
|
||||
{
|
||||
if(__system_argv[i] && isalnum(__system_argv[i][0])
|
||||
@ -223,8 +232,8 @@ void __system_initArgv(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
__system_argc = 1;
|
||||
__system_argv = (char**) malloc(sizeof(char**) * 2);
|
||||
__system_argc = 1;
|
||||
__system_argv = (char**) malloc(sizeof(char**) * 2);
|
||||
__system_argv[0] = "sdmc:/retroarch/retroarch";
|
||||
}
|
||||
__system_argv[__system_argc] = NULL;
|
||||
@ -269,8 +278,6 @@ void dump_result_value(Result val)
|
||||
printf("level : %u\n", res.level);
|
||||
}
|
||||
|
||||
bool select_pressed = false;
|
||||
|
||||
void wait_for_input(void)
|
||||
{
|
||||
printf("\n\nPress Start.\n\n");
|
||||
@ -290,10 +297,6 @@ void wait_for_input(void)
|
||||
if (kDown & KEY_SELECT)
|
||||
exit(0);
|
||||
|
||||
#if 0
|
||||
select_pressed = true;
|
||||
#endif
|
||||
|
||||
svcSleepThread(1000000);
|
||||
}
|
||||
}
|
||||
|
@ -15,12 +15,12 @@ static void (*launch_3dsx)(const char* path,
|
||||
static int exec_3dsx_actual(const char* path,
|
||||
const char** args, bool appendPath)
|
||||
{
|
||||
bool inited;
|
||||
bool fileExists;
|
||||
struct stat sBuff;
|
||||
argData_s newProgramArgs;
|
||||
unsigned int argChars = 0;
|
||||
unsigned int argNum = 0;
|
||||
bool fileExists;
|
||||
bool inited;
|
||||
unsigned int argNum = 0;
|
||||
|
||||
if (!path || path[0] == '\0')
|
||||
{
|
||||
@ -51,7 +51,8 @@ static int exec_3dsx_actual(const char* path,
|
||||
newProgramArgs.dst += strlen(path) + 1;
|
||||
newProgramArgs.buf[0]++;
|
||||
}
|
||||
while(args[argNum] != NULL)
|
||||
|
||||
while(args[argNum])
|
||||
{
|
||||
strcpy(newProgramArgs.dst, args[argNum]);
|
||||
newProgramArgs.dst += strlen(args[argNum]) + 1;
|
||||
@ -59,18 +60,18 @@ static int exec_3dsx_actual(const char* path,
|
||||
argNum++;
|
||||
}
|
||||
|
||||
inited = loader_Rosalina.init();
|
||||
launch_3dsx = loader_Rosalina.launchFile;
|
||||
inited = loader_Rosalina.init();
|
||||
launch_3dsx = loader_Rosalina.launchFile;
|
||||
|
||||
if (!inited)
|
||||
{
|
||||
inited = loader_Ninjhax2.init();
|
||||
inited = loader_Ninjhax2.init();
|
||||
launch_3dsx = loader_Ninjhax2.launchFile;
|
||||
}
|
||||
|
||||
if (!inited)
|
||||
{
|
||||
inited = loader_Ninjhax1.init();
|
||||
inited = loader_Ninjhax1.init();
|
||||
launch_3dsx = loader_Ninjhax1.launchFile;
|
||||
}
|
||||
|
||||
|
@ -6,9 +6,10 @@
|
||||
|
||||
#define FILE_CHUNK_SIZE 4096
|
||||
|
||||
typedef struct{
|
||||
u32 argc;
|
||||
char args[0x300 - 0x4];
|
||||
typedef struct
|
||||
{
|
||||
u32 argc;
|
||||
char args[0x300 - 0x4];
|
||||
}ciaParam;
|
||||
|
||||
char argvHmac[0x20] = {0x1d, 0x78, 0xff, 0xb9, 0xc5, 0xbc, 0x78, 0xb7, 0xac, 0x29, 0x1d, 0x3e, 0x16, 0xd0, 0xcf, 0x53, 0xef, 0x12, 0x58, 0x83, 0xb6, 0x9e, 0x2f, 0x79, 0x47, 0xf9, 0x35, 0x61, 0xeb, 0x50, 0xd7, 0x67};
|
||||
@ -28,11 +29,10 @@ static int isCiaInstalled(u64 titleId, u16 version)
|
||||
u32 titlesToRetrieve;
|
||||
u32 titlesRetrieved;
|
||||
u64* titleIds;
|
||||
bool titleExists = false;
|
||||
u32 titlesToCheck;
|
||||
AM_TitleEntry titleInfo;
|
||||
Result failed;
|
||||
|
||||
failed = AM_GetTitleCount(MEDIATYPE_SD, &titlesToRetrieve);
|
||||
bool titleExists = false;
|
||||
Result failed = AM_GetTitleCount(MEDIATYPE_SD, &titlesToRetrieve);
|
||||
if (R_FAILED(failed))
|
||||
return -1;
|
||||
|
||||
@ -44,7 +44,7 @@ static int isCiaInstalled(u64 titleId, u16 version)
|
||||
if (R_FAILED(failed))
|
||||
return -1;
|
||||
|
||||
for(u32 titlesToCheck = 0; titlesToCheck < titlesRetrieved; titlesToCheck++)
|
||||
for(titlesToCheck = 0; titlesToCheck < titlesRetrieved; titlesToCheck++)
|
||||
{
|
||||
if (titleIds[titlesToCheck] == titleId)
|
||||
{
|
||||
@ -57,7 +57,8 @@ static int isCiaInstalled(u64 titleId, u16 version)
|
||||
|
||||
if (titleExists)
|
||||
{
|
||||
failed = AM_GetTitleInfo(MEDIATYPE_SD, 1 /*titleCount*/, &titleId, &titleInfo);
|
||||
failed = AM_GetTitleInfo(MEDIATYPE_SD,
|
||||
1 /*titleCount*/, &titleId, &titleInfo);
|
||||
if (R_FAILED(failed))
|
||||
return -1;
|
||||
|
||||
@ -70,15 +71,13 @@ static int isCiaInstalled(u64 titleId, u16 version)
|
||||
|
||||
static int installCia(Handle ciaFile)
|
||||
{
|
||||
Result failed;
|
||||
Handle outputHandle;
|
||||
u64 fileSize;
|
||||
u64 fileOffset = 0;
|
||||
u32 bytesRead;
|
||||
u32 bytesWritten;
|
||||
u8 transferBuffer[FILE_CHUNK_SIZE];
|
||||
|
||||
failed = AM_StartCiaInstall(MEDIATYPE_SD, &outputHandle);
|
||||
u64 fileOffset = 0;
|
||||
Result failed = AM_StartCiaInstall(MEDIATYPE_SD, &outputHandle);
|
||||
if (R_FAILED(failed))
|
||||
return -1;
|
||||
|
||||
@ -89,14 +88,19 @@ static int installCia(Handle ciaFile)
|
||||
while(fileOffset < fileSize)
|
||||
{
|
||||
u64 bytesRemaining = fileSize - fileOffset;
|
||||
failed = FSFILE_Read(ciaFile, &bytesRead, fileOffset, transferBuffer, bytesRemaining < FILE_CHUNK_SIZE ? bytesRemaining : FILE_CHUNK_SIZE);
|
||||
failed = FSFILE_Read(ciaFile, &bytesRead,
|
||||
fileOffset, transferBuffer,
|
||||
bytesRemaining < FILE_CHUNK_SIZE
|
||||
? bytesRemaining
|
||||
: FILE_CHUNK_SIZE);
|
||||
if (R_FAILED(failed))
|
||||
{
|
||||
AM_CancelCIAInstall(outputHandle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
failed = FSFILE_Write(outputHandle, &bytesWritten, fileOffset, transferBuffer, bytesRead, 0);
|
||||
failed = FSFILE_Write(outputHandle, &bytesWritten,
|
||||
fileOffset, transferBuffer, bytesRead, 0);
|
||||
if (R_FAILED(failed))
|
||||
{
|
||||
AM_CancelCIAInstall(outputHandle);
|
||||
@ -146,6 +150,7 @@ int exec_cia(const char* path, const char** args)
|
||||
}
|
||||
|
||||
inited = R_SUCCEEDED(amInit()) && R_SUCCEEDED(fsInit());
|
||||
|
||||
if (inited)
|
||||
{
|
||||
AM_TitleEntry ciaInfo;
|
||||
@ -155,12 +160,15 @@ int exec_cia(const char* path, const char** args)
|
||||
ciaParam param;
|
||||
int argsLength;
|
||||
/* open CIA file */
|
||||
Result res = FSUSER_OpenArchive(&ciaArchive, ARCHIVE_SDMC, fsMakePath(PATH_EMPTY, ""));
|
||||
Result res = FSUSER_OpenArchive(&ciaArchive,
|
||||
ARCHIVE_SDMC, fsMakePath(PATH_EMPTY, ""));
|
||||
|
||||
if (R_FAILED(res))
|
||||
errorAndQuit("Cant open SD FS archive.");
|
||||
|
||||
res = FSUSER_OpenFile(&ciaFile, ciaArchive, fsMakePath(PATH_ASCII, path + 5/*skip "sdmc:"*/), FS_OPEN_READ, 0);
|
||||
res = FSUSER_OpenFile(&ciaFile,
|
||||
ciaArchive, fsMakePath(PATH_ASCII, path + 5/*skip "sdmc:"*/),
|
||||
FS_OPEN_READ, 0);
|
||||
if (R_FAILED(res))
|
||||
errorAndQuit("Cant open CIA file.");
|
||||
|
||||
@ -185,10 +193,11 @@ int exec_cia(const char* path, const char** args)
|
||||
FSFILE_Close(ciaFile);
|
||||
FSUSER_CloseArchive(ciaArchive);
|
||||
|
||||
param.argc = 0;
|
||||
argsLength = 0;
|
||||
char* argLocation = param.args;
|
||||
while(args[param.argc] != NULL)
|
||||
param.argc = 0;
|
||||
argsLength = 0;
|
||||
char *argLocation = param.args;
|
||||
|
||||
while(args[param.argc])
|
||||
{
|
||||
strcpy(argLocation, args[param.argc]);
|
||||
argLocation += strlen(args[param.argc]) + 1;
|
||||
@ -200,7 +209,8 @@ int exec_cia(const char* path, const char** args)
|
||||
if (R_FAILED(res))
|
||||
errorAndQuit("CIA cant run, cant prepare.");
|
||||
|
||||
res = APT_DoApplicationJump(¶m, sizeof(param.argc) + argsLength, argvHmac);
|
||||
res = APT_DoApplicationJump(¶m, sizeof(param.argc)
|
||||
+ argsLength, argvHmac);
|
||||
if (R_FAILED(res))
|
||||
errorAndQuit("CIA cant run, cant jump.");
|
||||
|
||||
|
@ -3,20 +3,24 @@
|
||||
Handle launchOpenFile(const char* path)
|
||||
{
|
||||
Handle file;
|
||||
Result res;
|
||||
ssize_t units;
|
||||
static uint16_t __utf16path[PATH_MAX+1];
|
||||
|
||||
if (strncmp(path, "sdmc:/", 6) == 0)
|
||||
path += 5;
|
||||
else if (*path != '/')
|
||||
return 0;
|
||||
|
||||
/* Convert the executable path to UTF-16 */
|
||||
static uint16_t __utf16path[PATH_MAX+1];
|
||||
ssize_t units = utf8_to_utf16(__utf16path, (const uint8_t*)path, PATH_MAX);
|
||||
units = utf8_to_utf16(__utf16path, (const uint8_t*)path, PATH_MAX);
|
||||
if (units < 0 || units >= PATH_MAX) return 0;
|
||||
__utf16path[units] = 0;
|
||||
|
||||
/* Open the file directly */
|
||||
FS_Path apath = { PATH_EMPTY, 1, (u8*)"" };
|
||||
FS_Path fpath = { PATH_UTF16, (units+1)*2, (u8*)__utf16path };
|
||||
Result res = FSUSER_OpenFileDirectly(&file, ARCHIVE_SDMC, apath, fpath, FS_OPEN_READ, 0);
|
||||
res = FSUSER_OpenFileDirectly(&file, ARCHIVE_SDMC,
|
||||
apath, fpath, FS_OPEN_READ, 0);
|
||||
return R_SUCCEEDED(res) ? file : 0;
|
||||
}
|
||||
|
@ -9,28 +9,32 @@ static bool init(void)
|
||||
|
||||
static Result HBLDR_SetTarget(const char* path)
|
||||
{
|
||||
Result rc;
|
||||
u32 pathLen = strlen(path) + 1;
|
||||
u32* cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(2, 0, 2); /* 0x20002 */
|
||||
cmdbuf[1] = IPC_Desc_StaticBuffer(pathLen, 0);
|
||||
cmdbuf[2] = (u32)path;
|
||||
cmdbuf[0] = IPC_MakeHeader(2, 0, 2); /* 0x20002 */
|
||||
cmdbuf[1] = IPC_Desc_StaticBuffer(pathLen, 0);
|
||||
cmdbuf[2] = (u32)path;
|
||||
|
||||
Result rc = svcSendSyncRequest(hbldrHandle);
|
||||
if (R_SUCCEEDED(rc)) rc = cmdbuf[1];
|
||||
rc = svcSendSyncRequest(hbldrHandle);
|
||||
if (R_SUCCEEDED(rc))
|
||||
rc = cmdbuf[1];
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result HBLDR_SetArgv(const void* buffer, u32 size)
|
||||
{
|
||||
Result rc;
|
||||
u32* cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(3, 0, 2); /* 0x30002 */
|
||||
cmdbuf[1] = IPC_Desc_StaticBuffer(size, 1);
|
||||
cmdbuf[2] = (u32)buffer;
|
||||
cmdbuf[0] = IPC_MakeHeader(3, 0, 2); /* 0x30002 */
|
||||
cmdbuf[1] = IPC_Desc_StaticBuffer(size, 1);
|
||||
cmdbuf[2] = (u32)buffer;
|
||||
|
||||
Result rc = svcSendSyncRequest(hbldrHandle);
|
||||
if (R_SUCCEEDED(rc)) rc = cmdbuf[1];
|
||||
rc = svcSendSyncRequest(hbldrHandle);
|
||||
if (R_SUCCEEDED(rc))
|
||||
rc = cmdbuf[1];
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -39,7 +43,8 @@ static void deinit(void)
|
||||
svcCloseHandle(hbldrHandle);
|
||||
}
|
||||
|
||||
static void launchFile(const char* path, argData_s* args, executableMetadata_s* em)
|
||||
static void launchFile(const char* path,
|
||||
argData_s* args, executableMetadata_s* em)
|
||||
{
|
||||
if (strncmp(path, "sdmc:/",6) == 0)
|
||||
path += 5;
|
||||
|
173
ctr/gpu_old.c
173
ctr/gpu_old.c
@ -25,14 +25,17 @@ void GPU_Reset(u32* gxbuf, u32* gpuBuf, u32 gpuBufSize)
|
||||
GPUCMD_SetBuffer(gpuBuf, gpuBufSize, 0);
|
||||
}
|
||||
|
||||
void GPU_SetFloatUniform(GPU_SHADER_TYPE type, u32 startreg, u32* data, u32 numreg)
|
||||
void GPU_SetFloatUniform(GPU_SHADER_TYPE type,
|
||||
u32 startreg, u32* data, u32 numreg)
|
||||
{
|
||||
int regOffset;
|
||||
if(!data)
|
||||
return;
|
||||
|
||||
int regOffset = (type == GPU_GEOMETRY_SHADER) ? (-0x30) : (0x0);
|
||||
regOffset = (type == GPU_GEOMETRY_SHADER) ? (-0x30) : (0x0);
|
||||
|
||||
GPUCMD_AddWrite(GPUREG_VSH_FLOATUNIFORM_CONFIG+regOffset, 0x80000000|startreg);
|
||||
GPUCMD_AddWrite(GPUREG_VSH_FLOATUNIFORM_CONFIG+regOffset,
|
||||
0x80000000 | startreg);
|
||||
GPUCMD_AddWrites(GPUREG_VSH_FLOATUNIFORM_DATA+regOffset, data, numreg*4);
|
||||
}
|
||||
|
||||
@ -40,43 +43,46 @@ void GPU_SetFloatUniform(GPU_SHADER_TYPE type, u32 startreg, u32* data, u32 numr
|
||||
void GPU_SetViewport(u32* depthBuffer, u32* colorBuffer,
|
||||
u32 x, u32 y, u32 w, u32 h)
|
||||
{
|
||||
u32 f116e;
|
||||
u32 param[0x4];
|
||||
float fw=(float)w;
|
||||
float fh=(float)h;
|
||||
float fw = (float)w;
|
||||
float fh = (float)h;
|
||||
|
||||
GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_FLUSH, 0x00000001);
|
||||
GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_INVALIDATE, 0x00000001);
|
||||
|
||||
u32 f116e=0x01000000|(((h-1)&0xFFF)<<12)|(w&0xFFF);
|
||||
f116e = 0x01000000 | (((h-1) & 0xFFF) << 12) | (w & 0xFFF);
|
||||
|
||||
param[0x0]=((u32)depthBuffer)>>3;
|
||||
param[0x1]=((u32)colorBuffer)>>3;
|
||||
param[0x2]=f116e;
|
||||
param[0x0] = ((u32)depthBuffer) >> 3;
|
||||
param[0x1] = ((u32)colorBuffer) >> 3;
|
||||
param[0x2] = f116e;
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_DEPTHBUFFER_LOC, param, 0x00000003);
|
||||
|
||||
GPUCMD_AddWrite(GPUREG_RENDERBUF_DIM, f116e);
|
||||
GPUCMD_AddWrite(GPUREG_DEPTHBUFFER_FORMAT, 0x00000003); /* depth buffer format */
|
||||
GPUCMD_AddWrite(GPUREG_COLORBUFFER_FORMAT, 0x00000002); /* color buffer format */
|
||||
/* depth buffer format */
|
||||
GPUCMD_AddWrite(GPUREG_DEPTHBUFFER_FORMAT, 0x00000003);
|
||||
/* color buffer format */
|
||||
GPUCMD_AddWrite(GPUREG_COLORBUFFER_FORMAT, 0x00000002);
|
||||
GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_BLOCK32, 0x00000000); /* ? */
|
||||
|
||||
param[0x0]=f32tof24(fw/2);
|
||||
param[0x1]=f32tof31(2.0f / fw) << 1;
|
||||
param[0x2]=f32tof24(fh/2);
|
||||
param[0x3]=f32tof31(2.0f / fh) << 1;
|
||||
param[0x0] = f32tof24(fw/2);
|
||||
param[0x1] = f32tof31(2.0f / fw) << 1;
|
||||
param[0x2] = f32tof24(fh/2);
|
||||
param[0x3] = f32tof31(2.0f / fh) << 1;
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_VIEWPORT_WIDTH, param, 0x00000004);
|
||||
|
||||
GPUCMD_AddWrite(GPUREG_VIEWPORT_XY, (y<<16)|(x&0xFFFF));
|
||||
GPUCMD_AddWrite(GPUREG_VIEWPORT_XY, (y << 16)|(x & 0xFFFF));
|
||||
|
||||
param[0x0]=0x00000000;
|
||||
param[0x1]=0x00000000;
|
||||
param[0x2]=((h-1)<<16)|((w-1)&0xFFFF);
|
||||
param[0x0] = 0x00000000;
|
||||
param[0x1] = 0x00000000;
|
||||
param[0x2] = ((h-1) << 16)|((w-1) & 0xFFFF);
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_SCISSORTEST_MODE, param, 0x00000003);
|
||||
|
||||
/* enable depth buffer */
|
||||
param[0x0]=0x0000000F;
|
||||
param[0x1]=0x0000000F;
|
||||
param[0x2]=0x00000002;
|
||||
param[0x3]=0x00000002;
|
||||
param[0x0] = 0x0000000F;
|
||||
param[0x1] = 0x0000000F;
|
||||
param[0x2] = 0x00000002;
|
||||
param[0x3] = 0x00000002;
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_COLORBUFFER_READ, param, 0x00000004);
|
||||
}
|
||||
|
||||
@ -85,8 +91,8 @@ void GPU_SetScissorTest(GPU_SCISSORMODE mode, u32 left, u32 bottom, u32 right, u
|
||||
u32 param[3];
|
||||
|
||||
param[0x0] = mode;
|
||||
param[0x1] = (bottom<<16)|(left&0xFFFF);
|
||||
param[0x2] = ((top-1)<<16)|((right-1)&0xFFFF);
|
||||
param[0x1] = (bottom << 16) | (left & 0xFFFF);
|
||||
param[0x2] = ((top-1) << 16) | ((right-1) & 0xFFFF);
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_SCISSORTEST_MODE, param, 0x00000003);
|
||||
}
|
||||
|
||||
@ -99,12 +105,14 @@ void GPU_DepthMap(float zScale, float zOffset)
|
||||
|
||||
void GPU_SetAlphaTest(bool enable, GPU_TESTFUNC function, u8 ref)
|
||||
{
|
||||
GPUCMD_AddWrite(GPUREG_FRAGOP_ALPHA_TEST, (enable&1)|((function&7)<<4)|(ref<<8));
|
||||
GPUCMD_AddWrite(GPUREG_FRAGOP_ALPHA_TEST,
|
||||
(enable&1)|((function&7) << 4)|(ref << 8));
|
||||
}
|
||||
|
||||
void GPU_SetStencilTest(bool enable, GPU_TESTFUNC function, u8 ref, u8 input_mask, u8 write_mask)
|
||||
{
|
||||
GPUCMD_AddWrite(GPUREG_STENCIL_TEST, (enable&1)|((function&7)<<4)|(write_mask<<8)|(ref<<16)|(input_mask<<24));
|
||||
GPUCMD_AddWrite(GPUREG_STENCIL_TEST,
|
||||
(enable&1)|((function&7) << 4)|(write_mask << 8)|(ref << 16)|(input_mask << 24));
|
||||
}
|
||||
|
||||
void GPU_SetStencilOp(GPU_STENCILOP sfail, GPU_STENCILOP dfail, GPU_STENCILOP pass)
|
||||
@ -114,14 +122,14 @@ void GPU_SetStencilOp(GPU_STENCILOP sfail, GPU_STENCILOP dfail, GPU_STENCILOP pa
|
||||
|
||||
void GPU_SetDepthTestAndWriteMask(bool enable, GPU_TESTFUNC function, GPU_WRITEMASK writemask)
|
||||
{
|
||||
GPUCMD_AddWrite(GPUREG_DEPTH_COLOR_MASK, (enable&1)|((function&7)<<4)|(writemask<<8));
|
||||
GPUCMD_AddWrite(GPUREG_DEPTH_COLOR_MASK, (enable&1)|((function&7) << 4)|(writemask << 8));
|
||||
}
|
||||
|
||||
void GPU_SetAlphaBlending(GPU_BLENDEQUATION colorEquation, GPU_BLENDEQUATION alphaEquation,
|
||||
GPU_BLENDFACTOR colorSrc, GPU_BLENDFACTOR colorDst,
|
||||
GPU_BLENDFACTOR alphaSrc, GPU_BLENDFACTOR alphaDst)
|
||||
{
|
||||
GPUCMD_AddWrite(GPUREG_BLEND_FUNC, colorEquation | (alphaEquation<<8) | (colorSrc<<16) | (colorDst<<20) | (alphaSrc<<24) | (alphaDst<<28));
|
||||
GPUCMD_AddWrite(GPUREG_BLEND_FUNC, colorEquation | (alphaEquation << 8) | (colorSrc << 16) | (colorDst << 20) | (alphaSrc << 24) | (alphaDst << 28));
|
||||
GPUCMD_AddMaskedWrite(GPUREG_COLOR_OPERATION, 0x2, 0x00000100);
|
||||
}
|
||||
|
||||
@ -138,7 +146,7 @@ void GPU_SetBlendingColor(u8 r, u8 g, u8 b, u8 a)
|
||||
|
||||
void GPU_SetTextureEnable(GPU_TEXUNIT units)
|
||||
{
|
||||
GPUCMD_AddMaskedWrite(GPUREG_SH_OUTATTR_CLOCK, 0x2, units<<8); /* enables texcoord outputs */
|
||||
GPUCMD_AddMaskedWrite(GPUREG_SH_OUTATTR_CLOCK, 0x2, units << 8); /* enables texcoord outputs */
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT_CONFIG, 0x00011000|units); /* enables texture units */
|
||||
}
|
||||
|
||||
@ -148,22 +156,22 @@ void GPU_SetTexture(GPU_TEXUNIT unit, u32* data, u16 width, u16 height, u32 para
|
||||
{
|
||||
case GPU_TEXUNIT0:
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT0_TYPE, colorType);
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT0_ADDR1, ((u32)data)>>3);
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT0_DIM, (width<<16)|height);
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT0_ADDR1, ((u32)data) >> 3);
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT0_DIM, (width << 16)|height);
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT0_PARAM, param);
|
||||
break;
|
||||
|
||||
case GPU_TEXUNIT1:
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT1_TYPE, colorType);
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT1_ADDR, ((u32)data)>>3);
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT1_DIM, (width<<16)|height);
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT1_ADDR, ((u32)data) >> 3);
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT1_DIM, (width << 16)|height);
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT1_PARAM, param);
|
||||
break;
|
||||
|
||||
case GPU_TEXUNIT2:
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT2_TYPE, colorType);
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT2_ADDR, ((u32)data)>>3);
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT2_DIM, (width<<16)|height);
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT2_ADDR, ((u32)data) >> 3);
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT2_DIM, (width << 16)|height);
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT2_PARAM, param);
|
||||
break;
|
||||
}
|
||||
@ -172,49 +180,60 @@ void GPU_SetTexture(GPU_TEXUNIT unit, u32* data, u16 width, u16 height, u32 para
|
||||
void GPU_SetTextureBorderColor(GPU_TEXUNIT unit,u32 borderColor)
|
||||
{
|
||||
switch (unit)
|
||||
{
|
||||
case GPU_TEXUNIT0:
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT0_BORDER_COLOR, borderColor);
|
||||
break;
|
||||
{
|
||||
case GPU_TEXUNIT0:
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT0_BORDER_COLOR, borderColor);
|
||||
break;
|
||||
|
||||
case GPU_TEXUNIT1:
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT1_BORDER_COLOR, borderColor);
|
||||
break;
|
||||
case GPU_TEXUNIT1:
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT1_BORDER_COLOR, borderColor);
|
||||
break;
|
||||
|
||||
case GPU_TEXUNIT2:
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT2_BORDER_COLOR, borderColor);
|
||||
break;
|
||||
}
|
||||
case GPU_TEXUNIT2:
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT2_BORDER_COLOR, borderColor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const u8 GPU_FORMATSIZE[4]={1,1,2,4};
|
||||
|
||||
void GPU_SetAttributeBuffers(u8 totalAttributes, u32* baseAddress, u64 attributeFormats, u16 attributeMask, u64 attributePermutation, u8 numBuffers, u32 bufferOffsets[], u64 bufferPermutations[], u8 bufferNumAttributes[])
|
||||
void GPU_SetAttributeBuffers(
|
||||
u8 totalAttributes,
|
||||
u32* baseAddress,
|
||||
u64 attributeFormats,
|
||||
u16 attributeMask,
|
||||
u64 attributePermutation,
|
||||
u8 numBuffers,
|
||||
u32 bufferOffsets[],
|
||||
u64 bufferPermutations[],
|
||||
u8 bufferNumAttributes[])
|
||||
{
|
||||
int i, j;
|
||||
u32 param[0x28];
|
||||
u8 sizeTable[0xC];
|
||||
|
||||
memset(param, 0x00, 0x28*4);
|
||||
|
||||
param[0x0]=((u32)baseAddress)>>3;
|
||||
param[0x1]=attributeFormats&0xFFFFFFFF;
|
||||
param[0x2]=((totalAttributes-1)<<28)|((attributeMask&0xFFF)<<16)|((attributeFormats>>32)&0xFFFF);
|
||||
param[0x0] = ((u32)baseAddress) >> 3;
|
||||
param[0x1] = attributeFormats & 0xFFFFFFFF;
|
||||
param[0x2] = ((totalAttributes-1) << 28) | ((attributeMask & 0xFFF) << 16) | ((attributeFormats >> 32) & 0xFFFF);
|
||||
|
||||
int i, j;
|
||||
u8 sizeTable[0xC];
|
||||
for(i=0;i<totalAttributes;i++)
|
||||
for(i = 0; i < totalAttributes; i++)
|
||||
{
|
||||
u8 v=attributeFormats&0xF;
|
||||
sizeTable[i]=GPU_FORMATSIZE[v&3]*((v>>2)+1);
|
||||
attributeFormats>>=4;
|
||||
u8 v = attributeFormats & 0xF;
|
||||
sizeTable[i] = GPU_FORMATSIZE[v & 3]*((v>>2)+1);
|
||||
attributeFormats >>= 4;
|
||||
}
|
||||
|
||||
for(i=0;i<numBuffers;i++)
|
||||
{
|
||||
u16 stride=0;
|
||||
param[3*(i+1)+0]=bufferOffsets[i];
|
||||
param[3*(i+1)+1]=bufferPermutations[i]&0xFFFFFFFF;
|
||||
for(j=0;j<bufferNumAttributes[i];j++)stride+=sizeTable[(bufferPermutations[i]>>(4*j))&0xF];
|
||||
param[3*(i+1)+2]=(bufferNumAttributes[i]<<28)|((stride&0xFFF)<<16)|((bufferPermutations[i]>>32)&0xFFFF);
|
||||
u16 stride = 0;
|
||||
param[3*(i+1)+0] = bufferOffsets[i];
|
||||
param[3*(i+1)+1] = bufferPermutations[i] & 0xFFFFFFFF;
|
||||
for(j = 0; j < bufferNumAttributes[i]; j++)
|
||||
stride += sizeTable[(bufferPermutations[i]>>(4*j)) & 0xF];
|
||||
|
||||
param[3*(i+1)+2] = (bufferNumAttributes[i] << 28) | ((stride & 0xFFF)<< 16) | ((bufferPermutations[i] >> 32) & 0xFFFF);
|
||||
}
|
||||
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_ATTRIBBUFFERS_LOC, param, 0x00000027);
|
||||
@ -222,17 +241,17 @@ void GPU_SetAttributeBuffers(u8 totalAttributes, u32* baseAddress, u64 attribute
|
||||
GPUCMD_AddMaskedWrite(GPUREG_VSH_INPUTBUFFER_CONFIG, 0xB, 0xA0000000|(totalAttributes-1));
|
||||
GPUCMD_AddWrite(GPUREG_VSH_NUM_ATTR, (totalAttributes-1));
|
||||
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_VSH_ATTRIBUTES_PERMUTATION_LOW, ((u32[]){attributePermutation&0xFFFFFFFF, (attributePermutation>>32)&0xFFFF}), 2);
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_VSH_ATTRIBUTES_PERMUTATION_LOW, ((u32[]){attributePermutation & 0xFFFFFFFF, (attributePermutation >> 32) & 0xFFFF}), 2);
|
||||
}
|
||||
|
||||
void GPU_SetAttributeBuffersAddress(u32* baseAddress)
|
||||
{
|
||||
GPUCMD_AddWrite(GPUREG_ATTRIBBUFFERS_LOC, ((u32)baseAddress)>>3);
|
||||
GPUCMD_AddWrite(GPUREG_ATTRIBBUFFERS_LOC, ((u32)baseAddress) >> 3);
|
||||
}
|
||||
|
||||
void GPU_SetFaceCulling(GPU_CULLMODE mode)
|
||||
{
|
||||
GPUCMD_AddWrite(GPUREG_FACECULLING_CONFIG, mode&0x3);
|
||||
GPUCMD_AddWrite(GPUREG_FACECULLING_CONFIG, mode & 0x3);
|
||||
}
|
||||
|
||||
void GPU_SetCombinerBufferWrite(u8 rgb_config, u8 alpha_config)
|
||||
@ -244,15 +263,16 @@ const u8 GPU_TEVID[]={0xC0,0xC8,0xD0,0xD8,0xF0,0xF8};
|
||||
|
||||
void GPU_SetTexEnv(u8 id, u16 rgbSources, u16 alphaSources, u16 rgbOperands, u16 alphaOperands, GPU_COMBINEFUNC rgbCombine, GPU_COMBINEFUNC alphaCombine, u32 constantColor)
|
||||
{
|
||||
if(id>6)return;
|
||||
u32 param[0x5];
|
||||
if(id > 6)
|
||||
return;
|
||||
memset(param, 0x00, 5*4);
|
||||
|
||||
param[0x0]=(alphaSources<<16)|(rgbSources);
|
||||
param[0x1]=(alphaOperands<<12)|(rgbOperands);
|
||||
param[0x2]=(alphaCombine<<16)|(rgbCombine);
|
||||
param[0x3]=constantColor;
|
||||
param[0x4]=0x00000000; /* ? */
|
||||
param[0x0] = (alphaSources << 16) | (rgbSources);
|
||||
param[0x1] = (alphaOperands << 12) | (rgbOperands);
|
||||
param[0x2] = (alphaCombine << 16) | (rgbCombine);
|
||||
param[0x3] = constantColor;
|
||||
param[0x4] = 0x00000000; /* ? */
|
||||
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_0000|GPU_TEVID[id], param, 0x00000005);
|
||||
}
|
||||
@ -262,7 +282,8 @@ void GPU_DrawArray(GPU_Primitive_t primitive, u32 first, u32 count)
|
||||
/* set primitive type */
|
||||
GPUCMD_AddMaskedWrite(GPUREG_PRIMITIVE_CONFIG, 0x2, primitive);
|
||||
GPUCMD_AddMaskedWrite(GPUREG_RESTART_PRIMITIVE, 0x2, 0x00000001);
|
||||
/* index buffer address register should be cleared (except bit 31) before drawing */
|
||||
/* index buffer address register should be cleared
|
||||
* (except bit 31) before drawing */
|
||||
GPUCMD_AddWrite(GPUREG_INDEXBUFFER_CONFIG, 0x80000000);
|
||||
/* pass number of vertices */
|
||||
GPUCMD_AddWrite(GPUREG_NUMVERTICES, count);
|
||||
@ -298,10 +319,11 @@ void GPU_DrawElements(GPU_Primitive_t primitive, u32* indexArray, u32 n)
|
||||
GPUCMD_AddMaskedWrite(GPUREG_START_DRAW_FUNC0, 0x1, 0x00000001);
|
||||
GPUCMD_AddWrite(GPUREG_VTX_FUNC, 0x00000001);
|
||||
|
||||
/* CHECKME: does this one also require GPUREG_FRAMEBUFFER_FLUSH at the end? */
|
||||
/* CHECKME: does this one also require
|
||||
* GPUREG_FRAMEBUFFER_FLUSH at the end? */
|
||||
}
|
||||
|
||||
void GPU_FinishDrawing()
|
||||
void GPU_FinishDrawing(void)
|
||||
{
|
||||
GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_FLUSH, 0x00000001);
|
||||
GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_INVALIDATE, 0x00000001);
|
||||
@ -317,7 +339,8 @@ void GPU_Finalize(void)
|
||||
GPUCMD_Split(NULL, NULL);
|
||||
#else
|
||||
GPUCMD_AddWrite(GPUREG_FINALIZE, 0x12345678);
|
||||
/* not the cleanest way of guaranteeing 0x10-byte size but whatever good enough for now */
|
||||
/* not the cleanest way of guaranteeing 0x10-byte size
|
||||
* but whatever good enough for now */
|
||||
GPUCMD_AddWrite(GPUREG_FINALIZE,0x12345678);
|
||||
#endif
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user