diff options
author | neonloop | 2021-03-31 16:26:36 +0000 |
---|---|---|
committer | neonloop | 2021-03-31 16:26:36 +0000 |
commit | 295b35c2f32887a1b73b1509668bf278c52929e1 (patch) | |
tree | fb6e5905f2daa864cc6cd1c61b7b32610ed94eae /psp | |
parent | 3ef78ae250b5460bf1b69c4d1f05e27985fa9d1b (diff) | |
parent | fd2079354572372f4516fcc13c51992ef4b4c715 (diff) | |
download | picogpsp-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.h | 139 | ||||
-rw-r--r-- | psp/mips_stub.S | 39 |
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 + |