Get rid of Musashi separate writes

The separate writes functionality of Musashi was severely getting in the way of any kind of caching of bus longwords, and I found that the negatvie performance impact of disabling separate writes could be negated by creatively applying the address translation cache to the FC reads/writes instead.
This commit requires a `make clean` before rebuilding the emulator with `make`.
This commit is contained in:
beeanyew
2021-06-28 15:08:28 +02:00
parent 9b1031c859
commit 208ba3d79d
4 changed files with 69 additions and 9 deletions

View File

@@ -673,9 +673,9 @@ void cpu_pulse_reset(void) {
m68k_pulse_reset(state);
}
int cpu_irq_ack(int level) {
printf("cpu irq ack\n");
return level;
unsigned int cpu_irq_ack(int level) {
//printf("cpu irq ack\n");
return 24 + level;
}
static unsigned int target = 0;

View File

@@ -21,10 +21,10 @@ uint16_t read8(uint32_t address);
void cpu_pulse_reset(void);
void m68ki_int_ack(uint8_t int_level);
int cpu_irq_ack(int level);
unsigned int m68k_read_memory_8(unsigned int address);
unsigned int m68k_read_memory_16(unsigned int address);
unsigned int m68k_read_memory_32(unsigned int address);
unsigned int cpu_irq_ack(int level);
unsigned int m68k_read_memory_8(unsigned int address);
unsigned int m68k_read_memory_16(unsigned int address);
unsigned int m68k_read_memory_32(unsigned int address);
void m68k_write_memory_8(unsigned int address, unsigned int value);
void m68k_write_memory_16(unsigned int address, unsigned int value);
void m68k_write_memory_32(unsigned int address, unsigned int value);

View File

@@ -32,6 +32,7 @@
#ifndef M68KCONF__HEADER
#define M68KCONF__HEADER
#include "emulator.h"
/* Configuration switches.
* Use OPT_SPECIFY_HANDLER for configuration options that allow callbacks.
@@ -75,7 +76,7 @@
* and m68k_read_pcrelative_xx() for PC-relative addressing.
* If off, all read requests from the CPU will be redirected to m68k_read_xx()
*/
#define M68K_SEPARATE_READS OPT_ON
#define M68K_SEPARATE_READS OPT_OFF
/* If ON, the CPU will call m68k_write_32_pd() when it executes move.l with a
* predecrement destination EA mode instead of m68k_write_32().

View File

@@ -1062,8 +1062,10 @@ typedef struct m68ki_cpu_core
unsigned int write_upper[8];
unsigned char *write_data[8];
address_translation_cache code_translation_cache;
address_translation_cache fc_read_translation_cache;
address_translation_cache fc_write_translation_cache;
volatile unsigned int *gpio;
} m68ki_cpu_core;
@@ -1245,6 +1247,12 @@ static inline uint m68ki_read_imm_32(m68ki_cpu_core *state)
* code if they are enabled in m68kconf.h.
*/
#define SET_FC_TRANSLATION_CACHE_VALUES \
cache->lower = state->read_addr[i]; \
cache->upper = state->read_upper[i]; \
cache->offset = state->read_data[i];
// M68KI_READ_8_FC
static inline uint m68ki_read_8_fc(m68ki_cpu_core *state, uint address, uint fc)
{
(void)fc;
@@ -1258,14 +1266,23 @@ static inline uint m68ki_read_8_fc(m68ki_cpu_core *state, uint address, uint fc)
address = pmmu_translate_addr(state,address,1);
#endif
address_translation_cache *cache = &state->fc_read_translation_cache;
if(cache->offset && address >= cache->lower && address < cache->upper)
{
return cache->offset[address - cache->lower];
}
for (int i = 0; i < state->read_ranges; i++) {
if(address >= state->read_addr[i] && address < state->read_upper[i]) {
SET_FC_TRANSLATION_CACHE_VALUES
return state->read_data[i][address - state->read_addr[i]];
}
}
return m68k_read_memory_8(ADDRESS_68K(address));
}
// M68KI_READ_16_FC
static inline uint m68ki_read_16_fc(m68ki_cpu_core *state, uint address, uint fc)
{
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
@@ -1279,14 +1296,23 @@ static inline uint m68ki_read_16_fc(m68ki_cpu_core *state, uint address, uint fc
address = pmmu_translate_addr(state,address,1);
#endif
address_translation_cache *cache = &state->fc_read_translation_cache;
if(cache->offset && address >= cache->lower && address < cache->upper)
{
return be16toh(((unsigned short *)(cache->offset + (address - cache->lower)))[0]);
}
for (int i = 0; i < state->read_ranges; i++) {
if(address >= state->read_addr[i] && address < state->read_upper[i]) {
SET_FC_TRANSLATION_CACHE_VALUES
return be16toh(((unsigned short *)(state->read_data[i] + (address - state->read_addr[i])))[0]);
}
}
return m68k_read_memory_16(ADDRESS_68K(address));
}
// M68KI_READ_32_FC
static inline uint m68ki_read_32_fc(m68ki_cpu_core *state, uint address, uint fc)
{
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
@@ -1300,8 +1326,15 @@ static inline uint m68ki_read_32_fc(m68ki_cpu_core *state, uint address, uint fc
address = pmmu_translate_addr(state,address,1);
#endif
address_translation_cache *cache = &state->fc_read_translation_cache;
if(cache->offset && address >= cache->lower && address < cache->upper)
{
return be32toh(((unsigned int *)(cache->offset + (address - cache->lower)))[0]);
}
for (int i = 0; i < state->read_ranges; i++) {
if(address >= state->read_addr[i] && address < state->read_upper[i]) {
SET_FC_TRANSLATION_CACHE_VALUES
return be32toh(((unsigned int *)(state->read_data[i] + (address - state->read_addr[i])))[0]);
}
}
@@ -1309,6 +1342,7 @@ static inline uint m68ki_read_32_fc(m68ki_cpu_core *state, uint address, uint fc
return m68k_read_memory_32(ADDRESS_68K(address));
}
// M68KI_WRITE_8_FC
static inline void m68ki_write_8_fc(m68ki_cpu_core *state, uint address, uint fc, uint value)
{
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
@@ -1321,8 +1355,15 @@ static inline void m68ki_write_8_fc(m68ki_cpu_core *state, uint address, uint fc
address = pmmu_translate_addr(state,address,0);
#endif
address_translation_cache *cache = &state->fc_write_translation_cache;
if(cache->offset && address >= cache->lower && address < cache->upper)
{
cache->offset[address - cache->lower] = value;
}
for (int i = 0; i < state->write_ranges; i++) {
if(address >= state->write_addr[i] && address < state->write_upper[i]) {
SET_FC_TRANSLATION_CACHE_VALUES
state->write_data[i][address - state->write_addr[i]] = (unsigned char)value;
return;
}
@@ -1330,6 +1371,8 @@ static inline void m68ki_write_8_fc(m68ki_cpu_core *state, uint address, uint fc
m68k_write_memory_8(ADDRESS_68K(address), value);
}
// M68KI_WRITE_16_FC
static inline void m68ki_write_16_fc(m68ki_cpu_core *state, uint address, uint fc, uint value)
{
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
@@ -1343,8 +1386,15 @@ static inline void m68ki_write_16_fc(m68ki_cpu_core *state, uint address, uint f
address = pmmu_translate_addr(state,address,0);
#endif
address_translation_cache *cache = &state->fc_write_translation_cache;
if(cache->offset && address >= cache->lower && address < cache->upper)
{
((short *)(cache->offset + (address - cache->lower)))[0] = value;
}
for (int i = 0; i < state->write_ranges; i++) {
if(address >= state->write_addr[i] && address < state->write_upper[i]) {
SET_FC_TRANSLATION_CACHE_VALUES
((short *)(state->write_data[i] + (address - state->write_addr[i])))[0] = htobe16(value);
return;
}
@@ -1352,6 +1402,8 @@ static inline void m68ki_write_16_fc(m68ki_cpu_core *state, uint address, uint f
m68k_write_memory_16(ADDRESS_68K(address), value);
}
// M68KI_WRITE_32_FC
static inline void m68ki_write_32_fc(m68ki_cpu_core *state, uint address, uint fc, uint value)
{
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
@@ -1365,8 +1417,15 @@ static inline void m68ki_write_32_fc(m68ki_cpu_core *state, uint address, uint f
address = pmmu_translate_addr(state,address,0);
#endif
address_translation_cache *cache = &state->fc_write_translation_cache;
if(cache->offset && address >= cache->lower && address < cache->upper)
{
((int *)(cache->offset + (address - cache->lower)))[0] = value;
}
for (int i = 0; i < state->write_ranges; i++) {
if(address >= state->write_addr[i] && address < state->write_upper[i]) {
SET_FC_TRANSLATION_CACHE_VALUES
((int *)(state->write_data[i] + (address - state->write_addr[i])))[0] = htobe32(value);
return;
}