changeset 1508:2e57910fd641 mame_interp

More efficient memory access when using MAME interpreters
author Michael Pavone <pavone@retrodev.com>
date Sun, 31 Dec 2017 10:03:25 -0800
parents 2455662378ed
children 36732f5c2281
files mame_z80/z80.c mame_z80/z80.h musashi/m68kcpu.c musashi/m68kcpu.h
diffstat 4 files changed, 78 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/mame_z80/z80.c	Sat Dec 30 18:27:06 2017 -0800
+++ b/mame_z80/z80.c	Sun Dec 31 10:03:25 2017 -0800
@@ -450,6 +450,10 @@
  ***************************************************************/
 static inline uint8_t rm(z80_device *z80, uint16_t addr)
 {
+	uint16_t index = addr >> 13;
+	if (z80->read_pointers[index]) {
+		return z80->read_pointers[index][addr & 0x1FFF];
+	}
 	return read_byte(addr, (void **)z80->mem_pointers, &z80->options->gen, z80);
 }
 
@@ -467,6 +471,11 @@
  ***************************************************************/
 static inline void wm(z80_device *z80, uint16_t addr, uint8_t value)
 {
+	uint16_t index = addr >> 13;
+	if (z80->write_pointers[index]) {
+		z80->write_pointers[index][addr & 0x1FFF] = value;
+		return;
+	}
 	write_byte(addr, value, (void **)z80->mem_pointers, &z80->options->gen, z80);
 }
 
@@ -3439,6 +3448,26 @@
 	z80->m_cc_xycb = cc_xycb;
 	z80->m_cc_ex = cc_ex;
 	
+	for (uint32_t address = 0; address < (64*1024); address += 8*1024)
+	{
+		z80->read_pointers[address >> 13] = NULL;
+		z80->write_pointers[address >> 13] = NULL;
+		memmap_chunk const *chunk = find_map_chunk(address, &z80->options->gen, 0, NULL);
+		if (!chunk || chunk->end < (address + 8*1024) || (chunk->flags & MMAP_PTR_IDX) || !chunk->buffer) {
+			continue;
+		}
+		void *ptr = get_native_pointer(address, (void **)z80->mem_pointers, &z80->options->gen);
+		if (!ptr) {
+			continue;
+		}
+		if (chunk->flags & MMAP_READ) {
+			z80->read_pointers[address >> 13] = ptr;
+		}
+		if (chunk->flags & MMAP_WRITE) {
+			z80->write_pointers[address >> 13] = ptr;
+		}
+	}
+	
 	return z80;
 }
 
--- a/mame_z80/z80.h	Sat Dec 30 18:27:06 2017 -0800
+++ b/mame_z80/z80.h	Sun Dec 31 10:03:25 2017 -0800
@@ -94,6 +94,8 @@
 	const uint8_t *   m_cc_xy;
 	const uint8_t *   m_cc_xycb;
 	const uint8_t *   m_cc_ex;
+	uint8_t           *read_pointers[64/8];
+	uint8_t           *write_pointers[64/8];
 };
 
 #define z80_invalidate_code_range(Z, S, E) 
--- a/musashi/m68kcpu.c	Sat Dec 30 18:27:06 2017 -0800
+++ b/musashi/m68kcpu.c	Sun Dec 31 10:03:25 2017 -0800
@@ -773,11 +773,24 @@
 
 uint8_t m68ki_read_8(m68000_base_device *m68k, uint32_t address)
 {
+	address &= 0xFFFFFF;
+	uint32_t base = address >> 16;
+	if (m68k->read_pointers[base]) {
+		uint8_t *chunk = m68k->read_pointers[base];
+		return chunk[(address ^ 1) & 0xFFFF];
+	}
 	return read_byte(address, (void **)m68k->c.mem_pointers, &m68k->c.options->gen, &m68k->c);
 }
 
 void m68ki_write_8(m68000_base_device *m68k, uint32_t address, uint8_t value)
 {
+	address &= 0xFFFFFF;
+	uint32_t base = address >> 16;
+	if (m68k->read_pointers[base]) {
+		uint8_t *chunk = m68k->read_pointers[base];
+		chunk[(address ^ 1) & 0xFFFF] = value;
+		return;
+	}
 	write_byte(address, value, (void **)m68k->c.mem_pointers, &m68k->c.options->gen, &m68k->c);
 }
 
@@ -787,11 +800,24 @@
  
 uint16_t m68ki_read_16(m68000_base_device *m68k, uint32_t address)
 {
+	address &= 0xFFFFFF;
+	uint32_t base = address >> 16;
+	if (m68k->read_pointers[base]) {
+		uint16_t *chunk = m68k->read_pointers[base];
+		return chunk[address >> 1 & 0x7FFF];
+	}
 	return read_word(address, (void **)m68k->c.mem_pointers, &m68k->c.options->gen, &m68k->c);
 }
 
 void m68ki_write_16(m68000_base_device *m68k, uint32_t address, uint16_t value)
 {
+	address &= 0xFFFFFF;
+	uint32_t base = address >> 16;
+	if (m68k->write_pointers[base]) {
+		uint16_t *chunk = m68k->read_pointers[base];
+		chunk[address >> 1 & 0x7FFF] = value;
+		return;
+	}
 	write_word(address, value, (void **)m68k->c.mem_pointers, &m68k->c.options->gen, &m68k->c);
 }
 
@@ -833,6 +859,25 @@
 	this->cyc_reset        = 132 * this->c.options->gen.clock_divider;
 	this->int_mask = 7 << 8;
 	this->c.status = m68ki_get_sr(this) >> 8;
+	for (uint32_t address = 0; address < (24*1024*1024); address += 64*1024)
+	{
+		this->read_pointers[address >> 16] = NULL;
+		this->write_pointers[address >> 16] = NULL;
+		memmap_chunk const *chunk = find_map_chunk(address, &this->c.options->gen, 0, NULL);
+		if (!chunk || chunk->end < (address + 64*1024) || (chunk->flags & (MMAP_ONLY_ODD | MMAP_ONLY_EVEN | MMAP_PTR_IDX)) || !chunk->buffer) {
+			continue;
+		}
+		void *ptr = get_native_pointer(address, (void **)this->c.mem_pointers, &this->c.options->gen);
+		if (!ptr) {
+			continue;
+		}
+		if (chunk->flags & MMAP_READ) {
+			this->read_pointers[address >> 16] = ptr;
+		}
+		if (chunk->flags & MMAP_WRITE) {
+			this->write_pointers[address >> 16] = ptr;
+		}
+	}
 }
 
 /* Service an interrupt request and start exception processing */
--- a/musashi/m68kcpu.h	Sat Dec 30 18:27:06 2017 -0800
+++ b/musashi/m68kcpu.h	Sun Dec 31 10:03:25 2017 -0800
@@ -55,6 +55,8 @@
 	void (**jump_table)(m68000_base_device *m68k);
 	const uint8_t* cyc_instruction;
 	const uint8_t* cyc_exception;
+	void *read_pointers[24*1024/64];
+	void *write_pointers[24*1024/64];
 };
 
 /* Special interrupt acknowledge values.