diff --git a/src/3ds.h b/src/3ds.h index 721b525..fa0fc5e 100644 --- a/src/3ds.h +++ b/src/3ds.h @@ -43,7 +43,6 @@ typedef struct _3DS { } HLE3DS; #define R(n) s->cpu.r[n] -#define RR(n) (s->cpu.rr[n >> 1]) #define PTR(addr) ((void*) &s->virtmem[addr]) #define PAGE_SIZE BIT(12) diff --git a/src/arm/arm_core.h b/src/arm/arm_core.h index 5c6b096..6e65e0f 100644 --- a/src/arm/arm_core.h +++ b/src/arm/arm_core.h @@ -38,7 +38,6 @@ typedef struct _ArmCore { u32 lr; u32 pc; }; - u64 rr[8]; }; union { diff --git a/src/pica/gpu.c b/src/pica/gpu.c index 2d2051e..6b3ed78 100644 --- a/src/pica/gpu.c +++ b/src/pica/gpu.c @@ -903,6 +903,11 @@ void load_tex_image(void* rawdata, int w, int h, int level, int fmt) { } void gpu_load_texture(GPU* gpu, int id, TexUnitRegs* regs, u32 fmt) { + if ((regs->addr << 3) < VRAM_PBASE) { + // games setup textures with NULL sometimes + return; + } + FBInfo* fb = fbcache_find(gpu, regs->addr << 3); glActiveTexture(GL_TEXTURE0 + id); if (fb) { @@ -1091,8 +1096,8 @@ void gpu_update_gl_state(GPU* gpu) { glDepthMask(false); } - // we need to always enable the depth test, since the pica can still write - // the depth buffer even if depth testing is disabled + // we need to always enable the depth test, since the pica can still + // write the depth buffer even if depth testing is disabled glEnable(GL_DEPTH_TEST); if (gpu->io.fb.color_mask.depthtest) { glDepthFunc(compare_func[gpu->io.fb.color_mask.depthfunc & 7]); diff --git a/src/pica/shader.c b/src/pica/shader.c index 9e17c5b..739fb4c 100644 --- a/src/pica/shader.c +++ b/src/pica/shader.c @@ -152,6 +152,17 @@ void shader_run(ShaderUnit* shu) { DEST(res, 1); break; } + case PICA_DPH: { + fvec a, b; + SRC1(a, 1); + SRC2(b, 1); + fvec res; + res[0] = + MUL(a[0], b[0]) + MUL(a[1], b[1]) + MUL(a[2], b[2]) + b[3]; + res[1] = res[2] = res[3] = res[0]; + DEST(res, 1); + break; + } case PICA_DST: case PICA_DSTI: { fvec a, b; diff --git a/src/pica/shader.h b/src/pica/shader.h index 5176da5..24f4766 100644 --- a/src/pica/shader.h +++ b/src/pica/shader.h @@ -12,6 +12,7 @@ enum { PICA_ADD = 0x00, PICA_DP3 = 0x01, PICA_DP4 = 0x02, + PICA_DPH = 0x03, PICA_DST = 0x04, PICA_EX2 = 0x05, PICA_LG2 = 0x06, diff --git a/src/pica/shaderjit/shaderjit_x86.cpp b/src/pica/shaderjit/shaderjit_x86.cpp index 4ce1128..24b83fc 100644 --- a/src/pica/shaderjit/shaderjit_x86.cpp +++ b/src/pica/shaderjit/shaderjit_x86.cpp @@ -284,6 +284,15 @@ void ShaderCode::compileBlock(ShaderUnit* shu, u32 start, u32 len) { DEST(xmm0, 1); break; } + case PICA_DPH: { + SRC1(xmm0, 1); + SRC2(xmm1, 1); + insertps(xmm0, ones, 0 << 6 | 3 << 4); // src1[3] = 1 + setupMul(); + dpps(xmm0, xmm1, 0xff); + DEST(xmm0, 1); + break; + } case PICA_MUL: { SRC1(xmm0, 1); SRC2(xmm1, 1); diff --git a/src/services.h b/src/services.h index 94bef05..cfe91ee 100644 --- a/src/services.h +++ b/src/services.h @@ -2,6 +2,7 @@ #define SERVICE_DATA_H #include "services/ac.h" +#include "services/act.h" #include "services/am.h" #include "services/apt.h" #include "services/boss.h" diff --git a/src/services/act.c b/src/services/act.c new file mode 100644 index 0000000..bde7138 --- /dev/null +++ b/src/services/act.c @@ -0,0 +1,15 @@ +#include "act.h" + +#include "../3ds.h" + +DECL_PORT(act) { + u32* cmdbuf = PTR(cmd_addr); + switch (cmd.command) { + default: + lwarn("unknown command 0x%04x (%x,%x,%x,%x,%x)", cmd.command, + cmdbuf[1], cmdbuf[2], cmdbuf[3], cmdbuf[4], cmdbuf[5]); + cmdbuf[0] = IPCHDR(1, 0); + cmdbuf[1] = 0; + break; + } +} \ No newline at end of file diff --git a/src/services/act.h b/src/services/act.h new file mode 100644 index 0000000..4ededb0 --- /dev/null +++ b/src/services/act.h @@ -0,0 +1,8 @@ +#ifndef ACT_H +#define ACT_H + +#include "../srv.h" + +DECL_PORT(act); + +#endif diff --git a/src/services/apt.c b/src/services/apt.c index d25592c..3712ed4 100644 --- a/src/services/apt.c +++ b/src/services/apt.c @@ -158,6 +158,13 @@ DECL_PORT(apt) { cmdbuf[2] = s->services.apt.application_cpu_time_limit; break; } + case 0x0101: { + linfo("GetTargetPlatform"); + cmdbuf[0] = IPCHDR(2, 0); + cmdbuf[1] = 0; + cmdbuf[2] = 0; // 0 for old 3ds + break; + } default: lwarn("unknown command 0x%04x (%x,%x,%x,%x,%x)", cmd.command, cmdbuf[1], cmdbuf[2], cmdbuf[3], cmdbuf[4], cmdbuf[5]); diff --git a/src/srv.c b/src/srv.c index ee80139..4e31f46 100644 --- a/src/srv.c +++ b/src/srv.c @@ -132,6 +132,8 @@ DECL_PORT(srv) { handler = port_handle_cam; } else if (IS("ir:USER")) { handler = port_handle_ir; + } else if (IS("act:u")) { + handler = port_handle_act; } else { lerror("unknown service '%s'", name); cmdbuf[1] = -1; diff --git a/src/svc.c b/src/svc.c index 4b27077..2de09a3 100644 --- a/src/svc.c +++ b/src/svc.c @@ -106,7 +106,7 @@ DECL_SVC(ExitThread) { } DECL_SVC(SleepThread) { - s64 timeout = RR(0); + s64 timeout = R(0) | (u64) R(1) << 32; R(0) = 0; thread_sleep(s, CUR_THREAD, timeout); @@ -284,7 +284,7 @@ DECL_SVC(ArbitrateAddress) { u32 addr = R(1); u32 type = R(2); s32 value = R(3); - s64 time = RR(4); + s64 time = R(4) | (u64) R(5) << 32; KArbiter* arbiter = HANDLE_GET_TYPED(h, KOT_ARBITER); if (!arbiter) { @@ -371,7 +371,7 @@ DECL_SVC(CloseHandle) { DECL_SVC(WaitSynchronization1) { u32 handle = R(0); - s64 timeout = RR(2); + s64 timeout = R(2) | (u64) R(3) << 32; KObject* obj = HANDLE_GET(handle); if (!obj) { @@ -395,7 +395,7 @@ DECL_SVC(WaitSynchronizationN) { u32* handles = PTR(R(1)); int count = R(2); bool waitAll = R(3); - s64 timeout = (u64) R(0) | (u64) R(4) << 32; + s64 timeout = R(0) | (u64) R(4) << 32; bool wokeup = false; int wokeupi = 0; @@ -451,8 +451,25 @@ DECL_SVC(DuplicateHandle) { } DECL_SVC(GetSystemTick) { - RR(0) = s->sched.now; - s->sched.now += 200; + R(0) = s->sched.now; + R(1) = s->sched.now >> 32; + s->sched.now += 200; // make time advance so the next read happens later +} + +DECL_SVC(GetProcessInfo) { + u32 type = R(2); + + R(0) = 0; + switch (type) { + case 0x14: // linear memory address conversion + R(1) = FCRAM_PBASE - LINEAR_HEAP_BASE; + R(2) = 0; + break; + default: + R(0) = -1; + lerror("unknown process info"); + break; + } } DECL_SVC(ConnectToPort) { diff --git a/src/svcs.inc b/src/svcs.inc index 193bb4c..8d726fc 100644 --- a/src/svcs.inc +++ b/src/svcs.inc @@ -19,6 +19,7 @@ SVC(0x24, WaitSynchronization1) SVC(0x25, WaitSynchronizationN) SVC(0x27, DuplicateHandle) SVC(0x28, GetSystemTick) +SVC(0x2b, GetProcessInfo) SVC(0x2d, ConnectToPort) SVC(0x32, SendSyncRequest) SVC(0x35, GetProcessId)