summaryrefslogtreecommitdiff
path: root/psp
diff options
context:
space:
mode:
authorneonloop2021-03-31 16:26:36 +0000
committerneonloop2021-03-31 16:26:36 +0000
commit295b35c2f32887a1b73b1509668bf278c52929e1 (patch)
treefb6e5905f2daa864cc6cd1c61b7b32610ed94eae /psp
parent3ef78ae250b5460bf1b69c4d1f05e27985fa9d1b (diff)
parentfd2079354572372f4516fcc13c51992ef4b4c715 (diff)
downloadpicogpsp-295b35c2f32887a1b73b1509668bf278c52929e1.tar.gz
picogpsp-295b35c2f32887a1b73b1509668bf278c52929e1.tar.bz2
picogpsp-295b35c2f32887a1b73b1509668bf278c52929e1.zip
Merge remote-tracking branch 'libretro/master' into pico-fe
Diffstat (limited to 'psp')
-rw-r--r--psp/mips_emit.h139
-rw-r--r--psp/mips_stub.S39
2 files changed, 83 insertions, 95 deletions
diff --git a/psp/mips_emit.h b/psp/mips_emit.h
index 8d1d8d8..818b724 100644
--- a/psp/mips_emit.h
+++ b/psp/mips_emit.h
@@ -1010,47 +1010,10 @@ u32 generate_load_rm_sh_##flags_op(u32 rm) \
{ \
u32 _address = (u32)(address); \
u32 _address_hi = (_address + 0x8000) >> 16; \
- generate_load_imm(ireg, address); \
mips_emit_lui(ireg, _address_hi >> 16) \
generate_load_memory_##type(ireg, _address - (_address_hi << 16)); \
} \
-#define generate_known_address_load_builder(type) \
- u32 generate_known_address_load_##type(u32 rd, u32 address) \
- { \
- switch(address >> 24) \
- { \
- /* Read from the BIOS ROM, can be converted to an immediate load. \
- Only really possible to do this from the BIOS but should be okay \
- to allow it everywhere */ \
- case 0x00: \
- u32 imm = read_memory_constant_##type(address); \
- generate_load_imm(arm_to_mips_reg[rd], imm); \
- return 1; \
- \
- /* Read from RAM, can be converted to a load */ \
- case 0x02: \
- generate_load_memory(type, arm_to_mips_reg[rd], (u8 *)ewram + \
- (address & 0x7FFF) + ((address & 0x38000) * 2) + 0x8000); \
- return 1; \
- \
- case 0x03: \
- generate_load_memory(type, arm_to_mips_reg[rd], (u8 *)iwram + \
- (address & 0x7FFF) + 0x8000); \
- return 1; \
- \
- /* Read from gamepak ROM, this has to be an immediate load because \
- it might not actually be in memory anymore when we get to it. */ \
- case 0x08: \
- u32 imm = read_memory_constant_##type(address); \
- generate_load_imm(arm_to_mips_reg[rd], imm); \
- return 1; \
- \
- default: \
- return 0; \
- } \
- } \
-
#define generate_block_extra_vars() \
u32 stored_pc = pc; \
u8 *update_trampoline \
@@ -1060,12 +1023,6 @@ u32 generate_load_rm_sh_##flags_op(u32 rm) \
generate_load_rm_sh_builder(flags); \
generate_load_rm_sh_builder(no_flags); \
\
-/* generate_known_address_load_builder(u8); \
- generate_known_address_load_builder(u16); \
- generate_known_address_load_builder(u32); \
- generate_known_address_load_builder(s8); \
- generate_known_address_load_builder(s16); */ \
- \
u32 generate_load_offset_sh(u32 rm) \
{ \
switch((opcode >> 5) & 0x03) \
@@ -2555,7 +2512,8 @@ u8 swi_hle_handle[256] =
#define ReOff_SaveR1 (21*4) // 3 save scratch regs
#define ReOff_SaveR2 (22*4)
#define ReOff_SaveR3 (23*4)
-#define ReOff_GP_Save (32*4) // GP_SAVE
+#define ReOff_OamUpd (33*4) // OAM_UPDATED
+#define ReOff_GP_Save (34*4) // GP_SAVE
// Saves all regs to their right slot and loads gp
#define emit_save_regs(save_a2) { \
@@ -2661,11 +2619,7 @@ static void emit_mem_access_loadop(
#define genccall(fn) mips_emit_jal(((u32)fn) >> 2);
#endif
-// Stub memory map:
-// 0 .. 63 First patch handler [#0]
-// 448 .. 511 Last patch handler [#7]
-// 512+ smc_write handler
-#define SMC_WRITE_OFF32 160
+#define SMC_WRITE_OFF32 (10*16) /* 10 handlers (16 insts) */
// Describes a "plain" memory are, that is, an area that is just accessed
// as normal memory (with some caveats tho).
@@ -2676,6 +2630,7 @@ typedef struct {
bool check_smc; // Whether the memory can contain code
bool bus16; // Whether it can only be accessed at 16bit
u32 baseptr; // Memory base address.
+ u32 baseoff; // Offset from base_reg
} t_stub_meminfo;
// Generates the stub to access memory for a given region, access type,
@@ -2784,15 +2739,20 @@ static void emit_pmemld_stub(
} else {
// Generate upper bits of the addr and do addr mirroring
// (The address hi16 is rounded up since load uses signed offset)
- mips_emit_lui(reg_rv, ((base_addr + 0x8000) >> 16));
+ if (!meminfo->baseoff) {
+ mips_emit_lui(reg_rv, ((base_addr + 0x8000) >> 16));
+ } else {
+ base_addr = meminfo->baseoff;
+ }
if (region == 2) {
- // EWRAM is a bit special
+ // Can't do EWRAM with an `andi` instruction (18 bits mask)
+ mips_emit_ext(reg_a0, reg_a0, 0, 18); // &= 0x3ffff
+ if (!aligned && alignment != 0) {
+ mips_emit_ins(reg_a0, reg_zero, 0, size);// addr & ~1/2 (align to size)
+ }
// Need to insert a zero in the addr (due to how it's mapped)
- mips_emit_andi(reg_temp, reg_a0, memmask); // Clears all but 15 bits (LSB)
- mips_emit_ext(reg_a0, reg_a0, 15, 3); // Gets the 3 higher bits (from the 18)
- mips_emit_ins(reg_temp, reg_a0, 16, 3); // Puts the 3 bits into bits 18..16
- mips_emit_addu(reg_rv, reg_rv, reg_temp); // Adds to the base addr
+ mips_emit_addu(reg_rv, reg_rv, reg_a0); // Adds to the base addr
} else if (region == 6) {
// VRAM is mirrored every 128KB but the last 32KB is mapped to the previous
mips_emit_ext(reg_temp, reg_a0, 15, 2); // Extract bits 15 and 16
@@ -2806,8 +2766,9 @@ static void emit_pmemld_stub(
mips_emit_addu(reg_rv, reg_rv, reg_a0); // addr = base + adjusted offset
} else {
// Generate regular (<=32KB) mirroring
- mips_emit_andi(reg_a0, reg_a0, memmask); // Clear upper bits (mirroring)
- mips_emit_addu(reg_rv, reg_rv, reg_a0); // Adds to base addr
+ mips_reg_number breg = (meminfo->baseoff ? reg_base : reg_rv);
+ mips_emit_andi(reg_temp, reg_a0, memmask); // Clear upper bits (mirroring)
+ mips_emit_addu(reg_rv, breg, reg_temp); // Adds to base addr
}
}
@@ -2862,12 +2823,13 @@ static void emit_pmemst_stub(
}
if (region == 2) {
- // EWRAM is a bit special
+ // Can't do EWRAM with an `andi` instruction (18 bits mask)
+ mips_emit_ext(reg_a0, reg_a0, 0, 18); // &= 0x3ffff
+ if (!aligned && realsize != 0) {
+ mips_emit_ins(reg_a0, reg_zero, 0, size);// addr & ~1/2 (align to size)
+ }
// Need to insert a zero in the addr (due to how it's mapped)
- mips_emit_andi(reg_temp, reg_a0, memmask); // Clears all but 15 bits (LSB)
- mips_emit_ext(reg_a0, reg_a0, 15, 3); // Gets the 3 higher bits (from the 18)
- mips_emit_ins(reg_temp, reg_a0, 16, 3); // Puts the 3 bits into bits 18..16
- mips_emit_addu(reg_rv, reg_rv, reg_temp); // Adds to the base addr
+ mips_emit_addu(reg_rv, reg_rv, reg_a0); // Adds to the base addr
} else if (region == 6) {
// VRAM is mirrored every 128KB but the last 32KB is mapped to the previous
mips_emit_ext(reg_temp, reg_a0, 15, 2); // Extract bits 15 and 16
@@ -2888,7 +2850,12 @@ static void emit_pmemst_stub(
// Generate SMC write and tracking
// TODO: Should we have SMC checks here also for aligned?
if (meminfo->check_smc && !aligned) {
- mips_emit_addiu(reg_temp, reg_rv, 0x8000); // -32KB is the addr of the SMC buffer
+ if (region == 2) {
+ mips_emit_lui(reg_temp, 0x40000 >> 16);
+ mips_emit_addu(reg_temp, reg_rv, reg_temp); // SMC lives after the ewram
+ } else {
+ mips_emit_addiu(reg_temp, reg_rv, 0x8000); // -32KB is the addr of the SMC buffer
+ }
if (realsize == 2) {
mips_emit_lw(reg_temp, reg_temp, base_addr);
} else if (realsize == 1) {
@@ -2898,8 +2865,7 @@ static void emit_pmemst_stub(
}
// If the data is non zero, we just wrote over code
// Local-jump to the smc_write (which lives at offset:0)
- unsigned instoffset = (&stub_arena[SMC_WRITE_OFF32] - (((u32*)translation_ptr) + 1));
- mips_emit_b(bne, reg_zero, reg_temp, instoffset);
+ mips_emit_b(bne, reg_zero, reg_temp, branch_offset(&stub_arena[SMC_WRITE_OFF32]));
}
// Store the data (delay slot from the SMC branch)
@@ -2914,9 +2880,8 @@ static void emit_pmemst_stub(
// Post processing store:
// Signal that OAM was updated
if (region == 7) {
- u32 palcaddr = (u32)&oam_update;
- mips_emit_lui(reg_temp, ((palcaddr + 0x8000) >> 16));
- mips_emit_sw(reg_base, reg_temp, palcaddr & 0xffff); // Write any nonzero data
+ // Write any nonzero data
+ mips_emit_sw(reg_base, reg_base, ReOff_OamUpd);
generate_function_return_swap_delay();
}
else {
@@ -3195,7 +3160,7 @@ static void emit_phand(
mips_emit_ins(reg_temp, reg_a0, 6, size); // Alignment bits (1 or 2, to bits 6 (and 7)
}
- unsigned tbloff = 256 + 2048 + 220 + 4 * toff; // Skip regs and palettes
+ unsigned tbloff = 256 + 3*1024 + 220 + 4 * toff; // Skip regs and RAMs
mips_emit_addu(reg_rv, reg_temp, reg_base); // Add to the base_reg the table offset
mips_emit_lw(reg_rv, reg_rv, tbloff); // Read addr from table
mips_emit_sll(reg_temp, reg_rv, 4); // 26 bit immediate to the MSB
@@ -3270,21 +3235,21 @@ void init_emitter() {
// Generate memory handlers
const t_stub_meminfo ldinfo [] = {
- { emit_pmemld_stub, 0, 0x4000, false, false, (u32)bios_rom },
+ { emit_pmemld_stub, 0, 0x4000, false, false, (u32)bios_rom, 0},
// 1 Open load / Ignore store
- { emit_pmemld_stub, 2, 0x8000, true, false, (u32)&ewram[0x8000] },
- { emit_pmemld_stub, 3, 0x8000, true, false, (u32)&iwram[0x8000] }, // memsize wrong on purpose, see above
- { emit_pmemld_stub, 4, 0x400, false, false, (u32)io_registers },
- { emit_pmemld_stub, 5, 0x400, false, true, (u32)palette_ram },
- { emit_pmemld_stub, 6, 0x0, false, true, (u32)vram }, // same, vram is a special case
- { emit_pmemld_stub, 7, 0x400, false, true, (u32)oam_ram },
- { emit_pmemld_stub, 8, 0x8000, false, false, 0 },
- { emit_pmemld_stub, 9, 0x8000, false, false, 0 },
- { emit_pmemld_stub, 10, 0x8000, false, false, 0 },
- { emit_pmemld_stub, 11, 0x8000, false, false, 0 },
- { emit_pmemld_stub, 12, 0x8000, false, false, 0 },
+ { emit_pmemld_stub, 2, 0x8000, true, false, (u32)ewram, 0 }, // memsize wrong on purpose
+ { emit_pmemld_stub, 3, 0x8000, true, false, (u32)&iwram[0x8000], 0 },
+ { emit_pmemld_stub, 4, 0x400, false, false, (u32)io_registers, 0 },
+ { emit_pmemld_stub, 5, 0x400, false, true, (u32)palette_ram, 0x100 },
+ { emit_pmemld_stub, 6, 0x0, false, true, (u32)vram, 0 }, // same, vram is a special case
+ { emit_pmemld_stub, 7, 0x400, false, true, (u32)oam_ram, 0x900 },
+ { emit_pmemld_stub, 8, 0x8000, false, false, 0, 0 },
+ { emit_pmemld_stub, 9, 0x8000, false, false, 0, 0 },
+ { emit_pmemld_stub, 10, 0x8000, false, false, 0, 0 },
+ { emit_pmemld_stub, 11, 0x8000, false, false, 0, 0 },
+ { emit_pmemld_stub, 12, 0x8000, false, false, 0, 0 },
// 13 is EEPROM mapped already (a bit special)
- { emit_pmemld_stub, 14, 0, false, false, 0 }, // Mapped via function call
+ { emit_pmemld_stub, 14, 0, false, false, 0, 0 }, // Mapped via function call
// 15 Open load / Ignore store
};
@@ -3308,12 +3273,12 @@ void init_emitter() {
}
const t_stub_meminfo stinfo [] = {
- { emit_pmemst_stub, 2, 0x8000, true, false, (u32)&ewram[0x8000] },
- { emit_pmemst_stub, 3, 0x8000, true, false, (u32)&iwram[0x8000] }, // memsize wrong on purpose, see above
+ { emit_pmemst_stub, 2, 0x8000, true, false, (u32)ewram, 0 },
+ { emit_pmemst_stub, 3, 0x8000, true, false, (u32)&iwram[0x8000], 0 },
// I/O is special and mapped with a function call
- { emit_palette_hdl, 5, 0x400, false, true, (u32)palette_ram },
- { emit_pmemst_stub, 6, 0x0, false, true, (u32)vram }, // same, vram is a special case
- { emit_pmemst_stub, 7, 0x400, false, true, (u32)oam_ram },
+ { emit_palette_hdl, 5, 0x400, false, true, (u32)palette_ram, 0x100 },
+ { emit_pmemst_stub, 6, 0x0, false, true, (u32)vram, 0 }, // same, vram is a special case
+ { emit_pmemst_stub, 7, 0x400, false, true, (u32)oam_ram, 0x900 },
};
// Store only for "regular"-ish mem regions
diff --git a/psp/mips_stub.S b/psp/mips_stub.S
index 2d40bf8..1c4ad4b 100644
--- a/psp/mips_stub.S
+++ b/psp/mips_stub.S
@@ -16,6 +16,8 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#include "../gpsp_config.h"
+
.set mips32r2
.align 4
@@ -38,19 +40,20 @@
.global reg_check
.global palette_ram
.global palette_ram_converted
+.global oam_ram
.global init_emitter
.global mips_lookup_pc
.global smc_write
.global write_io_epilogue
.global memory_map_read
-.global memory_map_write
.global tmemld
.global tmemst
.global tmemst
.global reg
.global spsr
.global reg_mode
+.global oam_update
# MIPS register layout:
@@ -115,13 +118,15 @@
.equ CPU_HALT_STATE, (30 * 4)
.equ CHANGED_PC_STATUS, (31 * 4)
.equ COMPLETED_FRAME, (32 * 4)
-.equ GP_SAVE, (33 * 4)
+.equ OAM_UPDATED, (33 * 4)
+.equ GP_SAVE, (34 * 4)
-.equ SPSR_BASE, (0x900)
-.equ REGMODE_BASE, (0x900 + 24)
+.equ SPSR_BASE, (0x100 + 0x400 * 3)
+.equ REGMODE_BASE, (SPSR_BASE + 24)
.equ SUPERVISOR_SPSR, (3 * 4 + SPSR_BASE)
.equ SUPERVISOR_LR, ((3 * (7 * 4)) + (6 * 4) + REGMODE_BASE)
-.equ FNPTRS_BASE, (0x900 + 220 + 960)
+.equ FNPTRS_MEMOPS, (REGMODE_BASE + 196)
+.equ FNPTRS_BASE, (FNPTRS_MEMOPS + 960)
.set noat
.set noreorder
@@ -609,9 +614,6 @@ execute_arm_translate_internal:
.data
.align 6
-memory_map_write:
- .space 0x8000
-
memory_map_read:
.space 0x8000
@@ -625,6 +627,8 @@ palette_ram:
.space 0x400
palette_ram_converted:
.space 0x400
+oam_ram:
+ .space 0x400
spsr:
.space 24 # u32[6]
reg_mode:
@@ -649,3 +653,22 @@ fnptrs:
.long execute_spsr_restore_body # 6
.long execute_store_cpsr_body # 7
+#if !defined(HAVE_MMAP)
+
+# Make this section executable!
+.text
+.section .jit,"awx",%nobits
+.align 2
+.global stub_arena
+.global rom_translation_cache
+.global ram_translation_cache
+
+stub_arena:
+ .space STUB_ARENA_SIZE
+rom_translation_cache:
+ .space ROM_TRANSLATION_CACHE_SIZE
+ram_translation_cache:
+ .space RAM_TRANSLATION_CACHE_SIZE
+
+#endif
+