Merge pull request #120 from davidgfnet/master
Fixes and improvements for MIPS and ARM
This commit is contained in:
commit
08d2fa1ebe
9
Makefile
9
Makefile
|
@ -362,6 +362,15 @@ else ifneq (,$(findstring armv,$(platform)))
|
||||||
endif
|
endif
|
||||||
LDFLAGS := -Wl,--no-undefined
|
LDFLAGS := -Wl,--no-undefined
|
||||||
|
|
||||||
|
# MIPS
|
||||||
|
else ifeq ($(platform), mips32)
|
||||||
|
TARGET := $(TARGET_NAME)_libretro.so
|
||||||
|
SHARED := -shared -nostdlib -Wl,--version-script=link.T
|
||||||
|
fpic := -fPIC -DPIC
|
||||||
|
CFLAGS += -fomit-frame-pointer -ffast-math -march=mips32 -mtune=mips32r2 -mhard-float
|
||||||
|
HAVE_DYNAREC := 1
|
||||||
|
CPU_ARCH := mips
|
||||||
|
|
||||||
# emscripten
|
# emscripten
|
||||||
else ifeq ($(platform), emscripten)
|
else ifeq ($(platform), emscripten)
|
||||||
TARGET := $(TARGET_NAME)_libretro_$(platform).bc
|
TARGET := $(TARGET_NAME)_libretro_$(platform).bc
|
||||||
|
|
|
@ -43,8 +43,8 @@ _##symbol:
|
||||||
#define CPU_HALT_STATE (30 * 4)
|
#define CPU_HALT_STATE (30 * 4)
|
||||||
#define CHANGED_PC_STATUS (31 * 4)
|
#define CHANGED_PC_STATUS (31 * 4)
|
||||||
#define COMPLETED_FRAME (32 * 4)
|
#define COMPLETED_FRAME (32 * 4)
|
||||||
|
#define OAM_UPDATED (33 * 4)
|
||||||
#define MAIN_THREAD_SP (33 * 4)
|
#define MAIN_THREAD_SP (34 * 4)
|
||||||
|
|
||||||
#define reg_a0 r0
|
#define reg_a0 r0
|
||||||
#define reg_a1 r1
|
#define reg_a1 r1
|
||||||
|
@ -538,7 +538,7 @@ return_to_main:
|
||||||
@ The instruction at LR is not an inst but a u32 data that contains the PC
|
@ 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`
|
@ 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() ;\
|
save_flags() ;\
|
||||||
str lr, [reg_base, #REG_SAVE3] /* save lr */;\
|
str lr, [reg_base, #REG_SAVE3] /* save lr */;\
|
||||||
str r4, [reg_base, #REG_SAVE2] /* save r4 */;\
|
str r4, [reg_base, #REG_SAVE2] /* save r4 */;\
|
||||||
|
@ -559,7 +559,7 @@ ptr_tbl_##store_type: ;\
|
||||||
.word ext_store_u##store_type /* 0x04: I/O regs */;\
|
.word ext_store_u##store_type /* 0x04: I/O regs */;\
|
||||||
.word ext_store_u##store_type /* 0x05: palette RAM */;\
|
.word ext_store_u##store_type /* 0x05: palette RAM */;\
|
||||||
.word ext_store_vram_u##store_type /* 0x06: vram */;\
|
.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 /* 0x08: gamepak: ignore */;\
|
||||||
.word ext_store_u##store_type /* 0x09: gamepak: ignore */;\
|
.word ext_store_u##store_type /* 0x09: gamepak: ignore */;\
|
||||||
.word ext_store_u##store_type /* 0x0A: gamepak: ignore */;\
|
.word ext_store_u##store_type /* 0x0A: gamepak: ignore */;\
|
||||||
|
@ -576,11 +576,11 @@ ext_store_ignore:
|
||||||
add pc, lr, #4 @ return
|
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 ;\
|
.align 2 ;\
|
||||||
defsymbl(execute_store_u##store_type) ;\
|
defsymbl(execute_store_u##store_type) ;\
|
||||||
execute_store_body(store_type, store_op) ;\
|
execute_store_body(store_type) ;\
|
||||||
;\
|
;\
|
||||||
ext_store_u##store_type: ;\
|
ext_store_u##store_type: ;\
|
||||||
ldr lr, [reg_base, #REG_SAVE3] /* pop lr off of stack */;\
|
ldr lr, [reg_base, #REG_SAVE3] /* pop lr off of stack */;\
|
||||||
|
@ -619,7 +619,16 @@ ext_store_vram_u##store_type: ;\
|
||||||
cmp r0, #0x18000 /* Check if exceeds 96KB */;\
|
cmp r0, #0x18000 /* Check if exceeds 96KB */;\
|
||||||
subcs r0, r0, #0x8000 /* Mirror to the last bank */;\
|
subcs r0, r0, #0x8000 /* Mirror to the last bank */;\
|
||||||
ldr r2, =(vram) /* r2 = vram base */;\
|
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 */;\
|
||||||
|
;\
|
||||||
|
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_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 */;\
|
ldr lr, [reg_base, #REG_SAVE3] /* pop lr off of stack */;\
|
||||||
restore_flags() ;\
|
restore_flags() ;\
|
||||||
add pc, lr, #4 /* return */;\
|
add pc, lr, #4 /* return */;\
|
||||||
|
@ -631,14 +640,14 @@ ext_store_vram_u##store_type: ;\
|
||||||
b smc_write /* perform smc write */;\
|
b smc_write /* perform smc write */;\
|
||||||
|
|
||||||
|
|
||||||
execute_store_builder(8, strb, ldrb)
|
execute_store_builder(8, strb, strh, ldrb)
|
||||||
execute_store_builder(16, strh, ldrh)
|
execute_store_builder(16, strh, strh, ldrh)
|
||||||
execute_store_builder(32, str, ldr)
|
execute_store_builder(32, str, str, ldr)
|
||||||
|
|
||||||
@ This is a store that is executed in a strm case (so no SMC checks in-between)
|
@ This is a store that is executed in a strm case (so no SMC checks in-between)
|
||||||
|
|
||||||
defsymbl(execute_store_u32_safe)
|
defsymbl(execute_store_u32_safe)
|
||||||
execute_store_body(32_safe, str)
|
execute_store_body(32_safe)
|
||||||
restore_flags()
|
restore_flags()
|
||||||
ldr pc, [reg_base, #REG_SAVE3] @ return
|
ldr pc, [reg_base, #REG_SAVE3] @ return
|
||||||
|
|
||||||
|
@ -671,6 +680,14 @@ ext_store_vram_u32_safe:
|
||||||
restore_flags()
|
restore_flags()
|
||||||
ldr pc, [reg_base, #REG_SAVE3] @ return
|
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:
|
write_epilogue:
|
||||||
cmp r0, #0 @ check if the write rose an alert
|
cmp r0, #0 @ check if the write rose an alert
|
||||||
beq 4f @ if not we can exit
|
beq 4f @ if not we can exit
|
||||||
|
@ -827,6 +844,8 @@ defsymbl(reg_mode)
|
||||||
|
|
||||||
defsymbl(reg)
|
defsymbl(reg)
|
||||||
.space 0x100, 0
|
.space 0x100, 0
|
||||||
|
defsymbl(oam_ram)
|
||||||
|
.space 0x400
|
||||||
|
|
||||||
@ Vita and 3DS (and of course mmap) map their own cache sections through some
|
@ Vita and 3DS (and of course mmap) map their own cache sections through some
|
||||||
@ platform-speficic mechanisms.
|
@ platform-speficic mechanisms.
|
||||||
|
|
1
cpu.c
1
cpu.c
|
@ -1630,6 +1630,7 @@ void raise_interrupt(irq_type irq_raised)
|
||||||
|
|
||||||
#ifndef HAVE_DYNAREC
|
#ifndef HAVE_DYNAREC
|
||||||
u8 *memory_map_read [8 * 1024];
|
u8 *memory_map_read [8 * 1024];
|
||||||
|
u16 oam_ram[512];
|
||||||
u16 palette_ram[512];
|
u16 palette_ram[512];
|
||||||
u16 palette_ram_converted[512];
|
u16 palette_ram_converted[512];
|
||||||
#endif
|
#endif
|
||||||
|
|
4
cpu.h
4
cpu.h
|
@ -85,7 +85,8 @@ typedef enum
|
||||||
CPU_MODE = 29,
|
CPU_MODE = 29,
|
||||||
CPU_HALT_STATE = 30,
|
CPU_HALT_STATE = 30,
|
||||||
CHANGED_PC_STATUS = 31,
|
CHANGED_PC_STATUS = 31,
|
||||||
COMPLETED_FRAME = 32
|
COMPLETED_FRAME = 32,
|
||||||
|
OAM_UPDATED = 33
|
||||||
} ext_reg_numbers;
|
} ext_reg_numbers;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
@ -146,7 +147,6 @@ extern u8 *ram_translation_ptr;
|
||||||
|
|
||||||
extern u32 idle_loop_target_pc;
|
extern u32 idle_loop_target_pc;
|
||||||
extern u32 iwram_stack_optimize;
|
extern u32 iwram_stack_optimize;
|
||||||
extern u32 direct_map_vram;
|
|
||||||
extern u32 translation_gate_targets;
|
extern u32 translation_gate_targets;
|
||||||
extern u32 translation_gate_target_pc[MAX_TRANSLATION_GATES];
|
extern u32 translation_gate_target_pc[MAX_TRANSLATION_GATES];
|
||||||
|
|
||||||
|
|
16
gba_memory.c
16
gba_memory.c
|
@ -305,7 +305,6 @@ u32 gamepak_waitstate_sequential[2][3][3] =
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
u16 oam_ram[512];
|
|
||||||
u16 io_registers[1024 * 16];
|
u16 io_registers[1024 * 16];
|
||||||
u8 ewram[1024 * 256 * 2];
|
u8 ewram[1024 * 256 * 2];
|
||||||
u8 iwram[1024 * 32 * 2];
|
u8 iwram[1024 * 32 * 2];
|
||||||
|
@ -342,14 +341,9 @@ gamepak_swap_entry_type *gamepak_memory_map;
|
||||||
// a lot.
|
// a lot.
|
||||||
FILE *gamepak_file_large = NULL;
|
FILE *gamepak_file_large = NULL;
|
||||||
|
|
||||||
u32 direct_map_vram = 0;
|
|
||||||
|
|
||||||
// Writes to these respective locations should trigger an update
|
// Writes to these respective locations should trigger an update
|
||||||
// so the related subsystem may react to it.
|
// so the related subsystem may react to it.
|
||||||
|
|
||||||
// If OAM is written to:
|
|
||||||
u32 oam_update = 1;
|
|
||||||
|
|
||||||
// If GBC audio is written to:
|
// If GBC audio is written to:
|
||||||
u32 gbc_sound_update = 0;
|
u32 gbc_sound_update = 0;
|
||||||
|
|
||||||
|
@ -755,7 +749,7 @@ cpu_alert_type function_cc write_io_register8(u32 address, u32 value)
|
||||||
u32 dispcnt = io_registers[REG_DISPCNT];
|
u32 dispcnt = io_registers[REG_DISPCNT];
|
||||||
|
|
||||||
if((value & 0x07) != (dispcnt & 0x07))
|
if((value & 0x07) != (dispcnt & 0x07))
|
||||||
oam_update = 1;
|
reg[OAM_UPDATED] = 1;
|
||||||
|
|
||||||
address8(io_registers, 0x00) = value;
|
address8(io_registers, 0x00) = value;
|
||||||
break;
|
break;
|
||||||
|
@ -1171,7 +1165,7 @@ cpu_alert_type function_cc write_io_register16(u32 address, u32 value)
|
||||||
{
|
{
|
||||||
u32 dispcnt = io_registers[REG_DISPCNT];
|
u32 dispcnt = io_registers[REG_DISPCNT];
|
||||||
if((value & 0x07) != (dispcnt & 0x07))
|
if((value & 0x07) != (dispcnt & 0x07))
|
||||||
oam_update = 1;
|
reg[OAM_UPDATED] = 1;
|
||||||
|
|
||||||
address16(io_registers, 0x00) = value;
|
address16(io_registers, 0x00) = value;
|
||||||
break;
|
break;
|
||||||
|
@ -1934,7 +1928,7 @@ void function_cc write_rtc(u32 address, u32 value)
|
||||||
\
|
\
|
||||||
case 0x07: \
|
case 0x07: \
|
||||||
/* OAM RAM */ \
|
/* OAM RAM */ \
|
||||||
oam_update = 1; \
|
reg[OAM_UPDATED] = 1; \
|
||||||
address##type(oam_ram, address & 0x3FF) = value; \
|
address##type(oam_ram, address & 0x3FF) = value; \
|
||||||
break; \
|
break; \
|
||||||
\
|
\
|
||||||
|
@ -2529,7 +2523,7 @@ dma_region_type dma_region_map[16] =
|
||||||
dma_smc_vars_##type()
|
dma_smc_vars_##type()
|
||||||
|
|
||||||
#define dma_oam_ram_dest() \
|
#define dma_oam_ram_dest() \
|
||||||
oam_update = 1 \
|
reg[OAM_UPDATED] = 1 \
|
||||||
|
|
||||||
#define dma_vars_oam_ram(type) \
|
#define dma_vars_oam_ram(type) \
|
||||||
dma_oam_ram_##type() \
|
dma_oam_ram_##type() \
|
||||||
|
@ -3331,7 +3325,7 @@ void gba_load_state(const void* src)
|
||||||
wipe_caches();
|
wipe_caches();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
oam_update = 1;
|
reg[OAM_UPDATED] = 1;
|
||||||
gbc_sound_update = 1;
|
gbc_sound_update = 1;
|
||||||
|
|
||||||
for(i = 0; i < 512; i++)
|
for(i = 0; i < 512; i++)
|
||||||
|
|
2
main.c
2
main.c
|
@ -158,7 +158,7 @@ u32 update_gba(void)
|
||||||
if((dispstat & 0x01) == 0)
|
if((dispstat & 0x01) == 0)
|
||||||
{
|
{
|
||||||
u32 i;
|
u32 i;
|
||||||
if(oam_update)
|
if(reg[OAM_UPDATED])
|
||||||
oam_update_count++;
|
oam_update_count++;
|
||||||
|
|
||||||
if(no_alpha)
|
if(no_alpha)
|
||||||
|
|
|
@ -2512,7 +2512,8 @@ u8 swi_hle_handle[256] =
|
||||||
#define ReOff_SaveR1 (21*4) // 3 save scratch regs
|
#define ReOff_SaveR1 (21*4) // 3 save scratch regs
|
||||||
#define ReOff_SaveR2 (22*4)
|
#define ReOff_SaveR2 (22*4)
|
||||||
#define ReOff_SaveR3 (23*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
|
// Saves all regs to their right slot and loads gp
|
||||||
#define emit_save_regs(save_a2) { \
|
#define emit_save_regs(save_a2) { \
|
||||||
|
@ -2629,6 +2630,7 @@ typedef struct {
|
||||||
bool check_smc; // Whether the memory can contain code
|
bool check_smc; // Whether the memory can contain code
|
||||||
bool bus16; // Whether it can only be accessed at 16bit
|
bool bus16; // Whether it can only be accessed at 16bit
|
||||||
u32 baseptr; // Memory base address.
|
u32 baseptr; // Memory base address.
|
||||||
|
u32 baseoff; // Offset from base_reg
|
||||||
} t_stub_meminfo;
|
} t_stub_meminfo;
|
||||||
|
|
||||||
// Generates the stub to access memory for a given region, access type,
|
// Generates the stub to access memory for a given region, access type,
|
||||||
|
@ -2737,7 +2739,11 @@ static void emit_pmemld_stub(
|
||||||
} else {
|
} else {
|
||||||
// Generate upper bits of the addr and do addr mirroring
|
// Generate upper bits of the addr and do addr mirroring
|
||||||
// (The address hi16 is rounded up since load uses signed offset)
|
// (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) {
|
if (region == 2) {
|
||||||
// Can't do EWRAM with an `andi` instruction (18 bits mask)
|
// Can't do EWRAM with an `andi` instruction (18 bits mask)
|
||||||
|
@ -2760,8 +2766,9 @@ static void emit_pmemld_stub(
|
||||||
mips_emit_addu(reg_rv, reg_rv, reg_a0); // addr = base + adjusted offset
|
mips_emit_addu(reg_rv, reg_rv, reg_a0); // addr = base + adjusted offset
|
||||||
} else {
|
} else {
|
||||||
// Generate regular (<=32KB) mirroring
|
// Generate regular (<=32KB) mirroring
|
||||||
mips_emit_andi(reg_a0, reg_a0, memmask); // Clear upper bits (mirroring)
|
mips_reg_number breg = (meminfo->baseoff ? reg_base : reg_rv);
|
||||||
mips_emit_addu(reg_rv, reg_rv, reg_a0); // Adds to base addr
|
mips_emit_andi(reg_temp, reg_a0, memmask); // Clear upper bits (mirroring)
|
||||||
|
mips_emit_addu(reg_rv, breg, reg_temp); // Adds to base addr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2873,9 +2880,8 @@ static void emit_pmemst_stub(
|
||||||
// Post processing store:
|
// Post processing store:
|
||||||
// Signal that OAM was updated
|
// Signal that OAM was updated
|
||||||
if (region == 7) {
|
if (region == 7) {
|
||||||
u32 palcaddr = (u32)&oam_update;
|
// Write any nonzero data
|
||||||
mips_emit_lui(reg_temp, ((palcaddr + 0x8000) >> 16));
|
mips_emit_sw(reg_base, reg_base, ReOff_OamUpd);
|
||||||
mips_emit_sw(reg_base, reg_temp, palcaddr & 0xffff); // Write any nonzero data
|
|
||||||
generate_function_return_swap_delay();
|
generate_function_return_swap_delay();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -3154,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)
|
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_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_lw(reg_rv, reg_rv, tbloff); // Read addr from table
|
||||||
mips_emit_sll(reg_temp, reg_rv, 4); // 26 bit immediate to the MSB
|
mips_emit_sll(reg_temp, reg_rv, 4); // 26 bit immediate to the MSB
|
||||||
|
@ -3229,21 +3235,21 @@ void init_emitter() {
|
||||||
|
|
||||||
// Generate memory handlers
|
// Generate memory handlers
|
||||||
const t_stub_meminfo ldinfo [] = {
|
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
|
// 1 Open load / Ignore store
|
||||||
{ emit_pmemld_stub, 2, 0x8000, true, false, (u32)ewram }, // memsize wrong on purpose
|
{ emit_pmemld_stub, 2, 0x8000, true, false, (u32)ewram, 0 }, // memsize wrong on purpose
|
||||||
{ emit_pmemld_stub, 3, 0x8000, true, false, (u32)&iwram[0x8000] },
|
{ emit_pmemld_stub, 3, 0x8000, true, false, (u32)&iwram[0x8000], 0 },
|
||||||
{ emit_pmemld_stub, 4, 0x400, false, false, (u32)io_registers },
|
{ emit_pmemld_stub, 4, 0x400, false, false, (u32)io_registers, 0 },
|
||||||
{ emit_pmemld_stub, 5, 0x400, false, true, (u32)palette_ram },
|
{ emit_pmemld_stub, 5, 0x400, false, true, (u32)palette_ram, 0x100 },
|
||||||
{ emit_pmemld_stub, 6, 0x0, false, true, (u32)vram }, // same, vram is a special case
|
{ 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 },
|
{ emit_pmemld_stub, 7, 0x400, false, true, (u32)oam_ram, 0x900 },
|
||||||
{ emit_pmemld_stub, 8, 0x8000, false, false, 0 },
|
{ emit_pmemld_stub, 8, 0x8000, false, false, 0, 0 },
|
||||||
{ emit_pmemld_stub, 9, 0x8000, false, false, 0 },
|
{ emit_pmemld_stub, 9, 0x8000, false, false, 0, 0 },
|
||||||
{ emit_pmemld_stub, 10, 0x8000, false, false, 0 },
|
{ emit_pmemld_stub, 10, 0x8000, false, false, 0, 0 },
|
||||||
{ emit_pmemld_stub, 11, 0x8000, false, false, 0 },
|
{ emit_pmemld_stub, 11, 0x8000, false, false, 0, 0 },
|
||||||
{ emit_pmemld_stub, 12, 0x8000, false, false, 0 },
|
{ emit_pmemld_stub, 12, 0x8000, false, false, 0, 0 },
|
||||||
// 13 is EEPROM mapped already (a bit special)
|
// 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
|
// 15 Open load / Ignore store
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3267,12 +3273,12 @@ void init_emitter() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const t_stub_meminfo stinfo [] = {
|
const t_stub_meminfo stinfo [] = {
|
||||||
{ emit_pmemst_stub, 2, 0x8000, true, false, (u32)ewram },
|
{ emit_pmemst_stub, 2, 0x8000, true, false, (u32)ewram, 0 },
|
||||||
{ emit_pmemst_stub, 3, 0x8000, true, false, (u32)&iwram[0x8000] },
|
{ emit_pmemst_stub, 3, 0x8000, true, false, (u32)&iwram[0x8000], 0 },
|
||||||
// I/O is special and mapped with a function call
|
// I/O is special and mapped with a function call
|
||||||
{ emit_palette_hdl, 5, 0x400, false, true, (u32)palette_ram },
|
{ emit_palette_hdl, 5, 0x400, false, true, (u32)palette_ram, 0x100 },
|
||||||
{ emit_pmemst_stub, 6, 0x0, false, true, (u32)vram }, // same, vram is a special case
|
{ 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 },
|
{ emit_pmemst_stub, 7, 0x400, false, true, (u32)oam_ram, 0x900 },
|
||||||
};
|
};
|
||||||
|
|
||||||
// Store only for "regular"-ish mem regions
|
// Store only for "regular"-ish mem regions
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
.global reg_check
|
.global reg_check
|
||||||
.global palette_ram
|
.global palette_ram
|
||||||
.global palette_ram_converted
|
.global palette_ram_converted
|
||||||
|
.global oam_ram
|
||||||
.global init_emitter
|
.global init_emitter
|
||||||
.global mips_lookup_pc
|
.global mips_lookup_pc
|
||||||
.global smc_write
|
.global smc_write
|
||||||
|
@ -52,6 +53,7 @@
|
||||||
.global reg
|
.global reg
|
||||||
.global spsr
|
.global spsr
|
||||||
.global reg_mode
|
.global reg_mode
|
||||||
|
.global oam_update
|
||||||
|
|
||||||
# MIPS register layout:
|
# MIPS register layout:
|
||||||
|
|
||||||
|
@ -116,13 +118,15 @@
|
||||||
.equ CPU_HALT_STATE, (30 * 4)
|
.equ CPU_HALT_STATE, (30 * 4)
|
||||||
.equ CHANGED_PC_STATUS, (31 * 4)
|
.equ CHANGED_PC_STATUS, (31 * 4)
|
||||||
.equ COMPLETED_FRAME, (32 * 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 SPSR_BASE, (0x100 + 0x400 * 3)
|
||||||
.equ REGMODE_BASE, (0x900 + 24)
|
.equ REGMODE_BASE, (SPSR_BASE + 24)
|
||||||
.equ SUPERVISOR_SPSR, (3 * 4 + SPSR_BASE)
|
.equ SUPERVISOR_SPSR, (3 * 4 + SPSR_BASE)
|
||||||
.equ SUPERVISOR_LR, ((3 * (7 * 4)) + (6 * 4) + REGMODE_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 noat
|
||||||
.set noreorder
|
.set noreorder
|
||||||
|
@ -623,6 +627,8 @@ palette_ram:
|
||||||
.space 0x400
|
.space 0x400
|
||||||
palette_ram_converted:
|
palette_ram_converted:
|
||||||
.space 0x400
|
.space 0x400
|
||||||
|
oam_ram:
|
||||||
|
.space 0x400
|
||||||
spsr:
|
spsr:
|
||||||
.space 24 # u32[6]
|
.space 24 # u32[6]
|
||||||
reg_mode:
|
reg_mode:
|
||||||
|
|
4
video.c
4
video.c
|
@ -4429,10 +4429,10 @@ void update_scanline(void)
|
||||||
|
|
||||||
// If OAM has been modified since the last scanline has been updated then
|
// If OAM has been modified since the last scanline has been updated then
|
||||||
// reorder and reprofile the OBJ lists.
|
// reorder and reprofile the OBJ lists.
|
||||||
if(oam_update)
|
if(reg[OAM_UPDATED])
|
||||||
{
|
{
|
||||||
order_obj(video_mode);
|
order_obj(video_mode);
|
||||||
oam_update = 0;
|
reg[OAM_UPDATED] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
order_layers((dispcnt >> 8) & active_layers[video_mode]);
|
order_layers((dispcnt >> 8) & active_layers[video_mode]);
|
||||||
|
|
|
@ -28,7 +28,6 @@ _##symbol:
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
# External symbols (data + functions)
|
# External symbols (data + functions)
|
||||||
#define _oam_update oam_update
|
|
||||||
#define _iwram iwram
|
#define _iwram iwram
|
||||||
#define _ewram ewram
|
#define _ewram ewram
|
||||||
#define _vram vram
|
#define _vram vram
|
||||||
|
@ -50,7 +49,6 @@ _##symbol:
|
||||||
#define _execute_store_cpsr_body execute_store_cpsr_body
|
#define _execute_store_cpsr_body execute_store_cpsr_body
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
.global _oam_update
|
|
||||||
.global _iwram
|
.global _iwram
|
||||||
.global _ewram
|
.global _ewram
|
||||||
.global _vram
|
.global _vram
|
||||||
|
@ -75,6 +73,7 @@ _##symbol:
|
||||||
.equ CPU_HALT_STATE, (30 * 4)
|
.equ CPU_HALT_STATE, (30 * 4)
|
||||||
.equ CHANGED_PC_STATUS, (31 * 4)
|
.equ CHANGED_PC_STATUS, (31 * 4)
|
||||||
.equ COMPLETED_FRAME, (32 * 4)
|
.equ COMPLETED_FRAME, (32 * 4)
|
||||||
|
.equ OAM_UPDATED, (33 * 4)
|
||||||
|
|
||||||
# destroys ecx and edx
|
# destroys ecx and edx
|
||||||
|
|
||||||
|
@ -241,7 +240,7 @@ ext_store_vram8b:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ext_store_oam8:
|
ext_store_oam8:
|
||||||
movl $1, _oam_update # flag OAM update
|
movl $1, OAM_UPDATED(%ebx) # flag OAM update
|
||||||
and $0x3FE, %eax # wrap around address and align to 16bits
|
and $0x3FE, %eax # wrap around address and align to 16bits
|
||||||
mov %dl, %dh # copy lower 8bits of value into full 16bits
|
mov %dl, %dh # copy lower 8bits of value into full 16bits
|
||||||
mov %dx, _oam_ram(%eax) # perform 16bit store
|
mov %dx, _oam_ram(%eax) # perform 16bit store
|
||||||
|
@ -332,7 +331,7 @@ ext_store_vram16b:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ext_store_oam16:
|
ext_store_oam16:
|
||||||
movl $1, _oam_update # flag OAM update
|
movl $1, OAM_UPDATED(%ebx) # flag OAM update
|
||||||
and $0x3FF, %eax # wrap around address
|
and $0x3FF, %eax # wrap around address
|
||||||
mov %dx, _oam_ram(%eax) # perform 16bit store
|
mov %dx, _oam_ram(%eax) # perform 16bit store
|
||||||
ret
|
ret
|
||||||
|
@ -410,7 +409,7 @@ ext_store_vram32b:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ext_store_oam32:
|
ext_store_oam32:
|
||||||
movl $1, _oam_update # flag OAM update
|
movl $1, OAM_UPDATED(%ebx) # flag OAM update
|
||||||
and $0x3FF, %eax # wrap around address
|
and $0x3FF, %eax # wrap around address
|
||||||
mov %edx, _oam_ram(%eax) # perform 32bit store
|
mov %edx, _oam_ram(%eax) # perform 32bit store
|
||||||
ret
|
ret
|
||||||
|
@ -539,6 +538,8 @@ defsymbl(palette_ram)
|
||||||
.space 0x400
|
.space 0x400
|
||||||
defsymbl(palette_ram_converted)
|
defsymbl(palette_ram_converted)
|
||||||
.space 0x400
|
.space 0x400
|
||||||
|
defsymbl(oam_ram)
|
||||||
|
.space 0x400
|
||||||
defsymbl(spsr)
|
defsymbl(spsr)
|
||||||
.space 24
|
.space 24
|
||||||
defsymbl(reg_mode)
|
defsymbl(reg_mode)
|
||||||
|
|
Loading…
Reference in New Issue