diff --git a/arm/arm64_stub.S b/arm/arm64_stub.S index 3f28d1d..8b67296 100644 --- a/arm/arm64_stub.S +++ b/arm/arm64_stub.S @@ -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 diff --git a/arm/arm_stub.S b/arm/arm_stub.S index db7035b..03ff9f4 100644 --- a/arm/arm_stub.S +++ b/arm/arm_stub.S @@ -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 */;\ diff --git a/cpu.c b/cpu.c index 7f37580..8b77fad 100644 --- a/cpu.c +++ b/cpu.c @@ -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_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); diff --git a/cpu.h b/cpu.h index ae4b92d..0911ed4 100644 --- a/cpu.h +++ b/cpu.h @@ -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) diff --git a/gba_memory.c b/gba_memory.c index 8130aff..e8e9bda 100644 --- a/gba_memory.c +++ b/gba_memory.c @@ -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) diff --git a/gba_memory.h b/gba_memory.h index d3d664f..8e5cf7e 100644 --- a/gba_memory.h +++ b/gba_memory.h @@ -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]; diff --git a/mips/mips_stub.S b/mips/mips_stub.S index 6966e92..b949276 100644 --- a/mips/mips_stub.S +++ b/mips/mips_stub.S @@ -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 diff --git a/x86/x86_emit.h b/x86/x86_emit.h index 1e51f64..afff8c8 100644 --- a/x86/x86_emit.h +++ b/x86/x86_emit.h @@ -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 diff --git a/x86/x86_stub.S b/x86/x86_stub.S index 2280cce..410ef6d 100644 --- a/x86/x86_stub.S +++ b/x86/x86_stub.S @@ -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)