Improve open bus reads on ARM/MIPS

This commit is contained in:
David Guillen Fandos 2022-01-26 19:03:14 +01:00
parent 8c4196d19e
commit b552d5eb7e
9 changed files with 25 additions and 15 deletions

View File

@ -52,6 +52,7 @@ _##symbol:
#define CPU_MODE (17 * 4)
#define CPU_HALT_STATE (18 * 4)
#define REG_BUS_VALUE (19 * 4)
#define REG_N_FLAG (20 * 4)
#define REG_Z_FLAG (21 * 4)
#define REG_C_FLAG (22 * 4)
@ -324,6 +325,8 @@ defsymbl(execute_swi)
store_registers()
mov w0, #MODE_SUPERVISOR
bl set_cpu_mode // Set supervisor mode
ldr w0, =0xe3a02004
str w0, [reg_base, REG_BUS_VALUE]
ldr lr, [reg_base, #REG_SAVE]
load_registers()
ret

View File

@ -34,6 +34,7 @@ _##symbol:
#define CPU_MODE (17 * 4)
#define CPU_HALT_STATE (18 * 4)
#define REG_BUS_VALUE (19 * 4)
#define REG_N_FLAG (20 * 4)
#define REG_Z_FLAG (21 * 4)
#define REG_C_FLAG (22 * 4)
@ -387,6 +388,8 @@ defsymbl(execute_swi_##mode) ;\
store_registers_##mode() /* store regs for mode */;\
call_c_function(set_cpu_mode) /* set the CPU mode to svsr */;\
load_registers_arm() /* load ARM regs */;\
ldr r0, =0xe3a02004 /* Update open BUS value */;\
str r0, [reg_base, #REG_BUS_VALUE] ;\
;\
restore_flags() ;\
add pc, lr, #4 /* return */;\

16
cpu.c
View File

@ -959,7 +959,7 @@ const u32 psr_masks[16] =
} \
if(((_address >> 24) == 0) && (pc >= 0x4000)) \
{ \
ror(dest, bios_read_protect, (_address & 0x03) << 3); \
ror(dest, reg[REG_BUS_VALUE], (_address & 0x03) << 3); \
} \
else \
\
@ -1577,7 +1577,7 @@ void raise_interrupt(irq_type irq_raised)
((reg[REG_CPSR] & 0x80) == 0))
{
// Value after the FIQ returns, should be improved
bios_read_protect = 0xe55ec002;
reg[REG_BUS_VALUE] = 0xe55ec002;
// Interrupt handler in BIOS
reg_mode[MODE_IRQ][6] = reg[REG_PC] + 4;
@ -3197,7 +3197,7 @@ arm_loop:
/* Jump to BIOS SWI handler */
default:
// After SWI, we read bios[0xE4]
bios_read_protect = 0xe3a02004;
reg[REG_BUS_VALUE] = 0xe3a02004;
reg_mode[MODE_SUPERVISOR][6] = pc + 4;
collapse_flags();
spsr[MODE_SUPERVISOR] = reg[REG_CPSR];
@ -3684,7 +3684,7 @@ thumb_loop:
{
default:
// After SWI, we read bios[0xE4]
bios_read_protect = 0xe3a02004;
reg[REG_BUS_VALUE] = 0xe3a02004;
reg_mode[MODE_SUPERVISOR][6] = pc + 2;
spsr[MODE_SUPERVISOR] = reg[REG_CPSR];
reg[REG_PC] = 0x00000008;
@ -3790,8 +3790,8 @@ void init_cpu(void)
bool cpu_read_savestate(const u8 *src)
{
const u8 *cpudoc = bson_find_key(src, "cpu");
return bson_read_int32(cpudoc, "bus-value", &bios_read_protect) &&
bson_read_int32_array(cpudoc, "regs", reg, REG_IGNORE) &&
return bson_read_int32(cpudoc, "bus-value", &reg[REG_BUS_VALUE]) &&
bson_read_int32_array(cpudoc, "regs", reg, REG_ARCH_COUNT) &&
bson_read_int32_array(cpudoc, "spsr", spsr, 6) &&
bson_read_int32_array(cpudoc, "regmod", (u32*)reg_mode, 7*7);
}
@ -3800,10 +3800,10 @@ unsigned cpu_write_savestate(u8 *dst)
{
u8 *wbptr, *startp = dst;
bson_start_document(dst, "cpu", wbptr);
bson_write_int32array(dst, "regs", reg, REG_IGNORE);
bson_write_int32array(dst, "regs", reg, REG_ARCH_COUNT);
bson_write_int32array(dst, "spsr", spsr, 6);
bson_write_int32array(dst, "regmod", reg_mode, 7*7);
bson_write_int32(dst, "bus-value", bios_read_protect);
bson_write_int32(dst, "bus-value", reg[REG_BUS_VALUE]);
bson_finish_document(dst, wbptr);
return (unsigned int)(dst - startp);

5
cpu.h
View File

@ -74,7 +74,10 @@ typedef enum
REG_CPSR = 16,
CPU_MODE = 17,
CPU_HALT_STATE = 18,
REG_IGNORE = 19,
REG_ARCH_COUNT = 19,
// This is saved separately
REG_BUS_VALUE = 19,
// Dynarec signaling and spilling
// (Not really part of the CPU state)

View File

@ -305,7 +305,6 @@ const u32 gamepak_waitstate_sequential[2][3][3] =
};
u8 bios_rom[1024 * 16];
u32 bios_read_protect;
// Up to 128kb, store SRAM, flash ROM, or EEPROM here.
u8 gamepak_backup[1024 * 128];
@ -569,7 +568,7 @@ u32 function_cc read_eeprom(void)
case 0x00: \
/* BIOS */ \
if(reg[REG_PC] >= 0x4000) \
ror(value, bios_read_protect, (address & 0x03) << 3); \
ror(value, reg[REG_BUS_VALUE], (address & 0x03) << 3); \
else \
value = readaddress##type(bios_rom, address & 0x3FFF); \
break; \
@ -3030,7 +3029,7 @@ void init_memory(void)
rtc_state = RTC_DISABLED;
memset(rtc_registers, 0, sizeof(rtc_registers));
bios_read_protect = 0xe129f000;
reg[REG_BUS_VALUE] = 0xe129f000;
}
void memory_term(void)

View File

@ -209,7 +209,6 @@ extern u32 gbc_sound_wave_update;
extern dma_transfer_type dma[DMA_CHAN_CNT];
extern u8 open_gba_bios_rom[1024*16];
extern u32 bios_read_protect;
extern u16 palette_ram[512];
extern u16 oam_ram[512];
extern u16 palette_ram_converted[512];

View File

@ -99,6 +99,7 @@ symbol:
.equ CPU_MODE, (17 * 4)
.equ CPU_HALT_STATE, (18 * 4)
.equ REG_BUS_VALUE, (19 * 4)
.equ REG_N_FLAG, (20 * 4)
.equ REG_Z_FLAG, (21 * 4)
.equ REG_C_FLAG, (22 * 4)
@ -420,8 +421,9 @@ defsymbl(execute_swi)
cfncall set_cpu_mode, 5 # set the CPU mode to supervisor
lw $ra, REG_SAVE3($16)
restore_registers
la $2, 0xe3a02004 # Update open BUS value
jr $ra # return
nop
sw $2, REG_BUS_VALUE($16)
# $4: pc to restore to
# returns in $4

View File

@ -2134,7 +2134,7 @@ u32 execute_store_cpsr_body()
static void function_cc execute_swi(u32 pc)
{
// Open bus value after SWI
bios_read_protect = 0xe3a02004;
reg[REG_BUS_VALUE] = 0xe3a02004;
reg_mode[MODE_SUPERVISOR][6] = pc;
spsr[MODE_SUPERVISOR] = reg[REG_CPSR];
// Move to ARM mode, supervisor mode, disable IRQs

View File

@ -84,6 +84,7 @@ _##symbol:
.equ CPU_MODE, (17 * 4)
.equ CPU_HALT_STATE, (18 * 4)
.equ REG_BUS_VALUE, (19 * 4)
.equ REG_N_FLAG, (20 * 4)
.equ REG_Z_FLAG, (21 * 4)
.equ REG_C_FLAG, (22 * 4)