From a494a3f00ee3bd35ee9ab76f8cd4f164da080113 Mon Sep 17 00:00:00 2001 From: David Guillen Fandos Date: Thu, 25 Mar 2021 21:02:06 +0100 Subject: Move OAM update flag to a register Fix a small bug in MIPS dynarec that affects non -G0 targets --- arm/arm_stub.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arm/arm_stub.S') diff --git a/arm/arm_stub.S b/arm/arm_stub.S index f0b7f52..8e6cc9b 100644 --- a/arm/arm_stub.S +++ b/arm/arm_stub.S @@ -43,8 +43,8 @@ _##symbol: #define CPU_HALT_STATE (30 * 4) #define CHANGED_PC_STATUS (31 * 4) #define COMPLETED_FRAME (32 * 4) - -#define MAIN_THREAD_SP (33 * 4) +#define OAM_UPDATED (33 * 4) +#define MAIN_THREAD_SP (34 * 4) #define reg_a0 r0 #define reg_a1 r1 -- cgit v1.2.3 From 7ea6c5e247a742af6f7acfbf215c23264410451f Mon Sep 17 00:00:00 2001 From: David Guillen Fandos Date: Thu, 25 Mar 2021 23:01:20 +0100 Subject: Move OAM RAM to stubs also Makes accesses more efficient for MIPS. Make accesses also fast for palette reads. --- arm/arm_stub.S | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arm/arm_stub.S') diff --git a/arm/arm_stub.S b/arm/arm_stub.S index 8e6cc9b..374daba 100644 --- a/arm/arm_stub.S +++ b/arm/arm_stub.S @@ -820,6 +820,8 @@ defsymbl(palette_ram) .space 0x400 defsymbl(palette_ram_converted) .space 0x400 +defsymbl(oam_ram) + .space 0x400 defsymbl(spsr) .space 24 defsymbl(reg_mode) -- cgit v1.2.3 From d284c868e9e23fb210b8c448cdace39f394cb895 Mon Sep 17 00:00:00 2001 From: David Guillen Fandos Date: Fri, 26 Mar 2021 13:00:08 +0100 Subject: Improve ARM store accesses --- arm/arm_stub.S | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'arm/arm_stub.S') diff --git a/arm/arm_stub.S b/arm/arm_stub.S index 374daba..1db913e 100644 --- a/arm/arm_stub.S +++ b/arm/arm_stub.S @@ -559,7 +559,7 @@ ptr_tbl_##store_type: ;\ .word ext_store_u##store_type /* 0x04: I/O regs */;\ .word ext_store_u##store_type /* 0x05: palette RAM */;\ .word ext_store_vram_u##store_type /* 0x06: vram */;\ - .word ext_store_u##store_type /* 0x07: oam ram */;\ + .word ext_store_oam_ram_u##store_type /* 0x07: oam ram */;\ .word ext_store_u##store_type /* 0x08: gamepak: ignore */;\ .word ext_store_u##store_type /* 0x09: gamepak: ignore */;\ .word ext_store_u##store_type /* 0x0A: gamepak: ignore */;\ @@ -624,6 +624,15 @@ ext_store_vram_u##store_type: ;\ restore_flags() ;\ add pc, lr, #4 /* return */;\ ;\ +ext_store_oam_ram_u##store_type: ;\ + mask_addr_bus16_##store_type(10) /* Mask to mirror memory (+align)*/;\ + add r2, reg_base, #256 /* r2 = oam ram base */;\ + store_op r1, [r0, r2] /* store data */;\ + str r2, [reg_base, #OAM_UPDATED] /* write non zero to signal */;\ + ldr lr, [reg_base, #REG_SAVE3] /* pop lr off of stack */;\ + restore_flags() ;\ + add pc, lr, #4 /* return */;\ + ;\ 3: ;\ ldr lr, [reg_base, #REG_SAVE3] /* restore lr */;\ ldr r0, [lr] /* load PC */;\ @@ -671,6 +680,14 @@ ext_store_vram_u32_safe: restore_flags() ldr pc, [reg_base, #REG_SAVE3] @ return +ext_store_oam_ram_u32_safe: + mask_addr_8(10) @ Mask to mirror memory (no need to align!) + add r2, reg_base, #256 @ r2 = oam ram base + str r1, [r0, r2] @ store data + str r2, [reg_base, #OAM_UPDATED] @ store anything non zero here + restore_flags() + ldr pc, [reg_base, #REG_SAVE3] @ return + write_epilogue: cmp r0, #0 @ check if the write rose an alert beq 4f @ if not we can exit @@ -820,8 +837,6 @@ defsymbl(palette_ram) .space 0x400 defsymbl(palette_ram_converted) .space 0x400 -defsymbl(oam_ram) - .space 0x400 defsymbl(spsr) .space 24 defsymbl(reg_mode) @@ -829,6 +844,8 @@ defsymbl(reg_mode) defsymbl(reg) .space 0x100, 0 +defsymbl(oam_ram) + .space 0x400 @ Vita and 3DS (and of course mmap) map their own cache sections through some @ platform-speficic mechanisms. -- cgit v1.2.3 From 452ba76ba898c5fc6d176ae8f8e2d77cf15f64a2 Mon Sep 17 00:00:00 2001 From: David Guillen Fandos Date: Fri, 26 Mar 2021 13:25:50 +0100 Subject: Fix 16 bit RAM stores (VRAM and OAM) in ARM --- arm/arm_stub.S | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'arm/arm_stub.S') diff --git a/arm/arm_stub.S b/arm/arm_stub.S index 1db913e..5917e82 100644 --- a/arm/arm_stub.S +++ b/arm/arm_stub.S @@ -538,7 +538,7 @@ return_to_main: @ The instruction at LR is not an inst but a u32 data that contains the PC @ Used for SMC. That's why return is essentially `pc = lr + 4` -#define execute_store_body(store_type, store_op) ;\ +#define execute_store_body(store_type) ;\ save_flags() ;\ str lr, [reg_base, #REG_SAVE3] /* save lr */;\ str r4, [reg_base, #REG_SAVE2] /* save r4 */;\ @@ -576,11 +576,11 @@ ext_store_ignore: add pc, lr, #4 @ return -#define execute_store_builder(store_type, store_op, load_op) ;\ +#define execute_store_builder(store_type, store_op, store_op16, load_op) ;\ ;\ .align 2 ;\ defsymbl(execute_store_u##store_type) ;\ - execute_store_body(store_type, store_op) ;\ + execute_store_body(store_type) ;\ ;\ ext_store_u##store_type: ;\ ldr lr, [reg_base, #REG_SAVE3] /* pop lr off of stack */;\ @@ -619,7 +619,7 @@ ext_store_vram_u##store_type: ;\ cmp r0, #0x18000 /* Check if exceeds 96KB */;\ subcs r0, r0, #0x8000 /* Mirror to the last bank */;\ ldr r2, =(vram) /* r2 = vram base */;\ - store_op r1, [r0, r2] /* store data */;\ + store_op16 r1, [r0, r2] /* store data */;\ ldr lr, [reg_base, #REG_SAVE3] /* pop lr off of stack */;\ restore_flags() ;\ add pc, lr, #4 /* return */;\ @@ -627,7 +627,7 @@ ext_store_vram_u##store_type: ;\ ext_store_oam_ram_u##store_type: ;\ mask_addr_bus16_##store_type(10) /* Mask to mirror memory (+align)*/;\ add r2, reg_base, #256 /* r2 = oam ram base */;\ - store_op r1, [r0, r2] /* store data */;\ + store_op16 r1, [r0, r2] /* store data */;\ str r2, [reg_base, #OAM_UPDATED] /* write non zero to signal */;\ ldr lr, [reg_base, #REG_SAVE3] /* pop lr off of stack */;\ restore_flags() ;\ @@ -640,14 +640,14 @@ ext_store_oam_ram_u##store_type: ;\ b smc_write /* perform smc write */;\ -execute_store_builder(8, strb, ldrb) -execute_store_builder(16, strh, ldrh) -execute_store_builder(32, str, ldr) +execute_store_builder(8, strb, strh, ldrb) +execute_store_builder(16, strh, strh, ldrh) +execute_store_builder(32, str, str, ldr) @ This is a store that is executed in a strm case (so no SMC checks in-between) defsymbl(execute_store_u32_safe) - execute_store_body(32_safe, str) + execute_store_body(32_safe) restore_flags() ldr pc, [reg_base, #REG_SAVE3] @ return -- cgit v1.2.3