dimemory: Add the target address space to translate, wrap the constants

divtlb: Wrap the constants
This commit is contained in:
Olivier Galibert 2023-03-18 21:25:40 +01:00
parent 02fe685a83
commit e2d60b0acb
68 changed files with 643 additions and 591 deletions

View File

@ -152,14 +152,17 @@ Indicates whether a given space actually exists.
.. code-block:: C++ .. code-block:: C++
bool translate(int spacenum, int intention, offs_t &address); bool translate(int spacenum, int intention, offs_t &address, address_space *&target_space);
Does a logical to physical address translation through the device's Does a logical to physical address translation through the device's
MMU. spacenum gives the space number, intention for the type of the MMU. spacenum gives the space number, intention for the type of the
future access (``TRANSLATE_(READ\|WRITE\|FETCH)(\|_USER\|_DEBUG)``) future access (``TR_(READ\|WRITE\|FETCH)``), address is an in/out
and address is an in/out parameter holding the address to translate on parameter holding the address to translate on entry and the translated
entry and the translated version on return. Should return ``true`` if version on return, and finally target_space is the actual space the
the translation went correctly, or ``false`` if the address is unmapped. access would end up in, which may be in a different device. Should
return ``true`` if the translation went correctly, or ``false`` if the
address is unmapped. The call must not change the state of the
device.
Note that for some historical reason, the device itself must override Note that for some historical reason, the device itself must override
the virtual method ``memory_translate`` with the same signature. the virtual method ``memory_translate`` with the same signature.

View File

@ -145,8 +145,9 @@ device_memory_interface::space_config_vector alpha_device::memory_space_config()
}; };
} }
bool alpha_device::memory_translate(int spacenum, int intention, offs_t &address) bool alpha_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{ {
target_space = &space(spacenum);
u64 placeholder = s64(s32(address)); u64 placeholder = s64(s32(address));
if (cpu_translate(placeholder, intention)) if (cpu_translate(placeholder, intention))
@ -626,7 +627,7 @@ bool alpha_ev4_device::cpu_translate(u64 &address, int intention)
// trim virtual address to 43 bits // trim virtual address to 43 bits
address &= 0x7ff'ffffffff; address &= 0x7ff'ffffffff;
if (intention & TRANSLATE_FETCH) if (intention == device_memory_interface::TR_FETCH)
{ {
// instruction superpage mapping // instruction superpage mapping
if ((m_ibx[IBX_ICCSR] & IBX_ICCSR_R_MAP) && !(m_ibx[IBX_PS] & IBX_PS_R_CM) && (address >> 41) == 2) if ((m_ibx[IBX_ICCSR] & IBX_ICCSR_R_MAP) && !(m_ibx[IBX_PS] & IBX_PS_R_CM) && (address >> 41) == 2)
@ -660,7 +661,7 @@ bool alpha_ev4_device::cpu_translate(u64 &address, int intention)
template <typename T, typename U> std::enable_if_t<std::is_convertible<U, std::function<void(T)>>::value, void> alpha_device::load(u64 address, U &&apply) template <typename T, typename U> std::enable_if_t<std::is_convertible<U, std::function<void(T)>>::value, void> alpha_device::load(u64 address, U &&apply)
{ {
cpu_translate(address, TRANSLATE_READ); cpu_translate(address, device_memory_interface::TR_READ);
unsigned const s = (address >> 31) & 6; unsigned const s = (address >> 31) & 6;
@ -675,7 +676,7 @@ template <typename T, typename U> std::enable_if_t<std::is_convertible<U, std::f
template <typename T, typename U> std::enable_if_t<std::is_convertible<U, std::function<void(address_space &, u64, T)>>::value, void> alpha_device::load_l(u64 address, U &&apply) template <typename T, typename U> std::enable_if_t<std::is_convertible<U, std::function<void(address_space &, u64, T)>>::value, void> alpha_device::load_l(u64 address, U &&apply)
{ {
cpu_translate(address, TRANSLATE_READ); cpu_translate(address, device_memory_interface::TR_READ);
unsigned const s = (address >> 31) & 6; unsigned const s = (address >> 31) & 6;
@ -688,7 +689,7 @@ template <typename T, typename U> std::enable_if_t<std::is_convertible<U, std::f
template <typename T, typename U> std::enable_if_t<std::is_convertible<U, T>::value, void> alpha_device::store(u64 address, U data, T mem_mask) template <typename T, typename U> std::enable_if_t<std::is_convertible<U, T>::value, void> alpha_device::store(u64 address, U data, T mem_mask)
{ {
cpu_translate(address, TRANSLATE_WRITE); cpu_translate(address, device_memory_interface::TR_WRITE);
unsigned const s = (address >> 31) & 6; unsigned const s = (address >> 31) & 6;
@ -703,7 +704,7 @@ template <typename T, typename U> std::enable_if_t<std::is_convertible<U, T>::va
void alpha_device::fetch(u64 address, std::function<void(u32)> &&apply) void alpha_device::fetch(u64 address, std::function<void(u32)> &&apply)
{ {
cpu_translate(address, TRANSLATE_FETCH); cpu_translate(address, device_memory_interface::TR_FETCH);
apply(icache_fetch(address)); apply(icache_fetch(address));
} }

View File

@ -32,7 +32,7 @@ protected:
// device_memory_interface overrides // device_memory_interface overrides
virtual space_config_vector memory_space_config() const override; virtual space_config_vector memory_space_config() const override;
virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
// device_disasm_interface overrides // device_disasm_interface overrides
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;

View File

@ -863,12 +863,12 @@ bool arm7_cpu_device::translate_vaddr_to_paddr(offs_t &vaddr, const int flags)
void arm7_cpu_device::translate_insn_command(const std::vector<std::string_view> &params) void arm7_cpu_device::translate_insn_command(const std::vector<std::string_view> &params)
{ {
translate_command(params, TRANSLATE_FETCH); translate_command(params, TR_FETCH);
} }
void arm7_cpu_device::translate_data_command(const std::vector<std::string_view> &params) void arm7_cpu_device::translate_data_command(const std::vector<std::string_view> &params)
{ {
translate_command(params, TRANSLATE_READ); translate_command(params, TR_READ);
} }
void arm7_cpu_device::translate_command(const std::vector<std::string_view> &params, int intention) void arm7_cpu_device::translate_command(const std::vector<std::string_view> &params, int intention)
@ -880,21 +880,21 @@ void arm7_cpu_device::translate_command(const std::vector<std::string_view> &par
vaddr &= 0xffffffff; vaddr &= 0xffffffff;
offs_t paddr = (offs_t)vaddr; offs_t paddr = (offs_t)vaddr;
bool can_translate = memory_translate(AS_PROGRAM, intention, paddr); address_space *space = nullptr;
bool can_translate = memory_translate(AS_PROGRAM, intention, paddr, space);
if (can_translate) if (can_translate)
machine().debugger().console().printf("%s vaddr %08x => phys %08x\n", intention == TRANSLATE_FETCH ? "instruction" : "data", (uint32_t)vaddr, paddr); machine().debugger().console().printf("%s vaddr %08x => phys %08x\n", intention == TR_FETCH ? "instruction" : "data", (uint32_t)vaddr, paddr);
else else
machine().debugger().console().printf("%s vaddr %08x => unmapped\n", intention == TRANSLATE_FETCH ? "instruction" : "data"); machine().debugger().console().printf("%s vaddr %08x => unmapped\n", intention == TR_FETCH ? "instruction" : "data");
} }
bool arm7_cpu_device::memory_translate(int spacenum, int intention, offs_t &address) bool arm7_cpu_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{ {
target_space = &space(spacenum);
/* only applies to the program address space and only does something if the MMU's enabled */ /* only applies to the program address space and only does something if the MMU's enabled */
if (spacenum == AS_PROGRAM && (m_control & COPRO_CTRL_MMU_EN)) if (spacenum == AS_PROGRAM && (m_control & COPRO_CTRL_MMU_EN))
{ {
int intention_type = intention & TRANSLATE_TYPE_MASK; const int flags = intention == TR_FETCH ? ARM7_TLB_ABORT_P : ARM7_TLB_ABORT_D;
const int flags = (intention_type & TRANSLATE_FETCH) ? ARM7_TLB_ABORT_P : ARM7_TLB_ABORT_D;
if (address < 0x2000000) if (address < 0x2000000)
address += m_pid_offset; address += m_pid_offset;

View File

@ -130,7 +130,7 @@ protected:
// device_memory_interface overrides // device_memory_interface overrides
virtual space_config_vector memory_space_config() const override; virtual space_config_vector memory_space_config() const override;
virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
// device_state_interface overrides // device_state_interface overrides
virtual void state_export(const device_state_entry &entry) override; virtual void state_export(const device_state_entry &entry) override;

View File

@ -309,9 +309,9 @@ device_memory_interface::space_config_vector clipper_device::memory_space_config
}; };
} }
bool clipper_device::memory_translate(int spacenum, int intention, offs_t &address) bool clipper_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{ {
return ((intention & TRANSLATE_TYPE_MASK) == TRANSLATE_FETCH ? get_icammu() : get_dcammu()).memory_translate(m_ssw, spacenum, intention, address); return (intention == TR_FETCH ? get_icammu() : get_dcammu()).memory_translate(m_ssw, spacenum, intention, address, target_space);
} }
void clipper_device::set_exception(u16 data) void clipper_device::set_exception(u16 data)

View File

@ -163,7 +163,7 @@ protected:
// device_memory_interface overrides // device_memory_interface overrides
virtual space_config_vector memory_space_config() const override; virtual space_config_vector memory_space_config() const override;
virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
// device_state_interface overrides // device_state_interface overrides
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;

View File

@ -2606,8 +2606,9 @@ void h6280_device::psg_w(offs_t offset, uint8_t data)
m_psg->c6280_w(offset, data); m_psg->c6280_w(offset, data);
} }
bool h6280_device::memory_translate(int spacenum, int intention, offs_t &address) bool h6280_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{ {
target_space = &space(spacenum);
if (spacenum == AS_PROGRAM) if (spacenum == AS_PROGRAM)
address = translated(address); address = translated(address);

View File

@ -90,7 +90,7 @@ protected:
// device_memory_interface overrides // device_memory_interface overrides
virtual space_config_vector memory_space_config() const override; virtual space_config_vector memory_space_config() const override;
virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
// device_disasm_interface overrides // device_disasm_interface overrides
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;

View File

@ -409,7 +409,7 @@ uint8_t athlonxp_device::READ8PL(uint32_t ea, uint8_t privilege)
{ {
uint32_t address = ea, error; uint32_t address = ea, error;
if(!translate_address(privilege,TRANSLATE_READ,&address,&error)) if(!translate_address(privilege,TR_READ,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -427,7 +427,7 @@ uint16_t athlonxp_device::READ16PL(uint32_t ea, uint8_t privilege)
{ {
case 0: case 0:
default: default:
if(!translate_address(privilege,TRANSLATE_READ,&address,&error)) if(!translate_address(privilege,TR_READ,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -435,7 +435,7 @@ uint16_t athlonxp_device::READ16PL(uint32_t ea, uint8_t privilege)
break; break;
case 1: case 1:
if(!translate_address(privilege,TRANSLATE_READ,&address,&error)) if(!translate_address(privilege,TR_READ,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -443,7 +443,7 @@ uint16_t athlonxp_device::READ16PL(uint32_t ea, uint8_t privilege)
break; break;
case 2: case 2:
if(!translate_address(privilege,TRANSLATE_READ,&address,&error)) if(!translate_address(privilege,TR_READ,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -468,7 +468,7 @@ uint32_t athlonxp_device::READ32PL(uint32_t ea, uint8_t privilege)
{ {
case 0: case 0:
default: default:
if(!translate_address(privilege,TRANSLATE_READ,&address,&error)) if(!translate_address(privilege,TR_READ,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -476,7 +476,7 @@ uint32_t athlonxp_device::READ32PL(uint32_t ea, uint8_t privilege)
break; break;
case 1: case 1:
if(!translate_address(privilege,TRANSLATE_READ,&address,&error)) if(!translate_address(privilege,TR_READ,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -493,7 +493,7 @@ uint32_t athlonxp_device::READ32PL(uint32_t ea, uint8_t privilege)
value = READ8PL(ea, privilege); value = READ8PL(ea, privilege);
address = ea + 1; address = ea + 1;
if(!translate_address(privilege,TRANSLATE_READ,&address,&error)) if(!translate_address(privilege,TR_READ,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -518,7 +518,7 @@ uint64_t athlonxp_device::READ64PL(uint32_t ea, uint8_t privilege)
break; break;
case 1: case 1:
if(!translate_address(privilege,TRANSLATE_READ,&address,&error)) if(!translate_address(privilege,TR_READ,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -538,7 +538,7 @@ uint64_t athlonxp_device::READ64PL(uint32_t ea, uint8_t privilege)
value |= uint64_t(READ32PL(ea + 1, privilege)) << 8; value |= uint64_t(READ32PL(ea + 1, privilege)) << 8;
address = ea + 5; address = ea + 5;
if(!translate_address(privilege,TRANSLATE_READ,&address,&error)) if(!translate_address(privilege,TR_READ,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -552,7 +552,7 @@ uint64_t athlonxp_device::READ64PL(uint32_t ea, uint8_t privilege)
void athlonxp_device::WRITE8PL(uint32_t ea, uint8_t privilege, uint8_t value) void athlonxp_device::WRITE8PL(uint32_t ea, uint8_t privilege, uint8_t value)
{ {
uint32_t address = ea, error; uint32_t address = ea, error;
if(!translate_address(privilege,TRANSLATE_WRITE,&address,&error)) if(!translate_address(privilege,TR_WRITE,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -568,7 +568,7 @@ void athlonxp_device::WRITE16PL(uint32_t ea, uint8_t privilege, uint16_t value)
switch(ea & 3) switch(ea & 3)
{ {
case 0: case 0:
if(!translate_address(privilege,TRANSLATE_WRITE,&address,&error)) if(!translate_address(privilege,TR_WRITE,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -576,7 +576,7 @@ void athlonxp_device::WRITE16PL(uint32_t ea, uint8_t privilege, uint16_t value)
break; break;
case 1: case 1:
if(!translate_address(privilege,TRANSLATE_WRITE,&address,&error)) if(!translate_address(privilege,TR_WRITE,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -584,7 +584,7 @@ void athlonxp_device::WRITE16PL(uint32_t ea, uint8_t privilege, uint16_t value)
break; break;
case 2: case 2:
if(!translate_address(privilege,TRANSLATE_WRITE,&address,&error)) if(!translate_address(privilege,TR_WRITE,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -605,7 +605,7 @@ void athlonxp_device::WRITE32PL(uint32_t ea, uint8_t privilege, uint32_t value)
switch(ea & 3) switch(ea & 3)
{ {
case 0: case 0:
if(!translate_address(privilege,TRANSLATE_WRITE,&address,&error)) if(!translate_address(privilege,TR_WRITE,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -613,7 +613,7 @@ void athlonxp_device::WRITE32PL(uint32_t ea, uint8_t privilege, uint32_t value)
break; break;
case 1: case 1:
if(!translate_address(privilege,TRANSLATE_WRITE,&address,&error)) if(!translate_address(privilege,TR_WRITE,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -630,7 +630,7 @@ void athlonxp_device::WRITE32PL(uint32_t ea, uint8_t privilege, uint32_t value)
WRITE8PL(ea, privilege, value & 0xff); WRITE8PL(ea, privilege, value & 0xff);
address = ea + 1; address = ea + 1;
if(!translate_address(privilege,TRANSLATE_WRITE,&address,&error)) if(!translate_address(privilege,TR_WRITE,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -651,7 +651,7 @@ void athlonxp_device::WRITE64PL(uint32_t ea, uint8_t privilege, uint64_t value)
break; break;
case 1: case 1:
if(!translate_address(privilege,TRANSLATE_WRITE,&address,&error)) if(!translate_address(privilege,TR_WRITE,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -671,7 +671,7 @@ void athlonxp_device::WRITE64PL(uint32_t ea, uint8_t privilege, uint64_t value)
WRITE32PL(ea + 1, privilege, (value >> 8) & 0xffffffff); WRITE32PL(ea + 1, privilege, (value >> 8) & 0xffffffff);
address = ea + 5; address = ea + 5;
if(!translate_address(privilege,TRANSLATE_WRITE,&address,&error)) if(!translate_address(privilege,TR_WRITE,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;

View File

@ -167,17 +167,17 @@ uint32_t i386_device::i386_translate(int segment, uint32_t ip, int rwn)
return m_sreg[segment].base + ip; return m_sreg[segment].base + ip;
} }
vtlb_entry i386_device::get_permissions(uint32_t pte, int wp) device_vtlb_interface::vtlb_entry i386_device::get_permissions(uint32_t pte, int wp)
{ {
vtlb_entry ret = VTLB_READ_ALLOWED | ((pte & 4) ? VTLB_USER_READ_ALLOWED : 0); vtlb_entry ret = READ_ALLOWED | ((pte & 4) ? USER_READ_ALLOWED : 0);
if (!wp) if (!wp)
ret |= VTLB_WRITE_ALLOWED; ret |= WRITE_ALLOWED;
if (pte & 2) if (pte & 2)
ret |= VTLB_WRITE_ALLOWED | ((pte & 4) ? VTLB_USER_WRITE_ALLOWED : 0); ret |= WRITE_ALLOWED | ((pte & 4) ? USER_WRITE_ALLOWED : 0);
return ret; return ret;
} }
bool i386_device::i386_translate_address(int intention, offs_t *address, vtlb_entry *entry) bool i386_device::i386_translate_address(int intention, bool debug, offs_t *address, vtlb_entry *entry)
{ {
uint32_t a = *address; uint32_t a = *address;
uint32_t pdbr = m_cr[3] & 0xfffff000; uint32_t pdbr = m_cr[3] & 0xfffff000;
@ -185,9 +185,8 @@ bool i386_device::i386_translate_address(int intention, offs_t *address, vtlb_en
uint32_t table = (a >> 12) & 0x3ff; uint32_t table = (a >> 12) & 0x3ff;
vtlb_entry perm = 0; vtlb_entry perm = 0;
bool ret; bool ret;
bool user = (intention & TRANSLATE_USER_MASK) ? true : false; bool user = (intention & TR_USER) ? true : false;
bool write = (intention & TRANSLATE_WRITE) ? true : false; bool write = (intention & TR_WRITE) ? true : false;
bool debug = (intention & TRANSLATE_DEBUG_MASK) ? true : false;
if (!(m_cr[0] & 0x80000000)) if (!(m_cr[0] & 0x80000000))
{ {
@ -208,14 +207,14 @@ bool i386_device::i386_translate_address(int intention, offs_t *address, vtlb_en
return true; return true;
} }
perm = get_permissions(page_dir, WP); perm = get_permissions(page_dir, WP);
if (write && (!(perm & VTLB_WRITE_ALLOWED) || (user && !(perm & VTLB_USER_WRITE_ALLOWED)))) if (write && (!(perm & WRITE_ALLOWED) || (user && !(perm & USER_WRITE_ALLOWED))))
ret = false; ret = false;
else if (user && !(perm & VTLB_USER_READ_ALLOWED)) else if (user && !(perm & USER_READ_ALLOWED))
ret = false; ret = false;
else else
{ {
if (write) if (write)
perm |= VTLB_FLAG_DIRTY; perm |= FLAG_DIRTY;
if (!(page_dir & 0x40) && write) if (!(page_dir & 0x40) && write)
m_program->write_dword(pdbr + directory * 4, page_dir | 0x60); m_program->write_dword(pdbr + directory * 4, page_dir | 0x60);
else if (!(page_dir & 0x20)) else if (!(page_dir & 0x20))
@ -237,14 +236,14 @@ bool i386_device::i386_translate_address(int intention, offs_t *address, vtlb_en
return true; return true;
} }
perm = get_permissions(page_entry, WP); perm = get_permissions(page_entry, WP);
if (write && (!(perm & VTLB_WRITE_ALLOWED) || (user && !(perm & VTLB_USER_WRITE_ALLOWED)))) if (write && (!(perm & WRITE_ALLOWED) || (user && !(perm & USER_WRITE_ALLOWED))))
ret = false; ret = false;
else if (user && !(perm & VTLB_USER_READ_ALLOWED)) else if (user && !(perm & USER_READ_ALLOWED))
ret = false; ret = false;
else else
{ {
if (write) if (write)
perm |= VTLB_FLAG_DIRTY; perm |= FLAG_DIRTY;
if (!(page_dir & 0x20)) if (!(page_dir & 0x20))
m_program->write_dword(pdbr + directory * 4, page_dir | 0x20); m_program->write_dword(pdbr + directory * 4, page_dir | 0x20);
if (!(page_entry & 0x40) && write) if (!(page_entry & 0x40) && write)
@ -275,19 +274,19 @@ bool i386_device::translate_address(int pl, int type, uint32_t *address, uint32_
const vtlb_entry *table = vtlb_table(); const vtlb_entry *table = vtlb_table();
uint32_t index = *address >> 12; uint32_t index = *address >> 12;
vtlb_entry entry = table[index]; vtlb_entry entry = table[index];
if (type == TRANSLATE_FETCH) if (type == TR_FETCH)
type = TRANSLATE_READ; type = TR_READ;
if (pl == 3) if (pl == 3)
type |= TRANSLATE_USER_MASK; type |= TR_USER;
#ifdef TEST_TLB #ifdef TEST_TLB
uint32_t test_addr = *address; uint32_t test_addr = *address;
#endif #endif
if (!(entry & VTLB_FLAG_VALID) || ((type & TRANSLATE_WRITE) && !(entry & VTLB_FLAG_DIRTY))) if (!(entry & FLAG_VALID) || ((type & TR_WRITE) && !(entry & FLAG_DIRTY)))
{ {
if (!i386_translate_address(type, address, &entry)) if (!i386_translate_address(type, false, address, &entry))
{ {
*error = ((type & TRANSLATE_WRITE) ? 2 : 0) | ((m_CPL == 3) ? 4 : 0); *error = ((type & TR_WRITE) ? 2 : 0) | ((m_CPL == 3) ? 4 : 0);
if (entry) if (entry)
*error |= 1; *error |= 1;
return false; return false;
@ -297,12 +296,12 @@ bool i386_device::translate_address(int pl, int type, uint32_t *address, uint32_
} }
if (!(entry & (1 << type))) if (!(entry & (1 << type)))
{ {
*error = ((type & TRANSLATE_WRITE) ? 2 : 0) | ((m_CPL == 3) ? 4 : 0) | 1; *error = ((type & TR_WRITE) ? 2 : 0) | ((m_CPL == 3) ? 4 : 0) | 1;
return false; return false;
} }
*address = (entry & 0xfffff000) | (*address & 0xfff); *address = (entry & 0xfffff000) | (*address & 0xfff);
#ifdef TEST_TLB #ifdef TEST_TLB
int test_ret = i386_translate_address(type | TRANSLATE_DEBUG_MASK, &test_addr, nullptr); int test_ret = i386_translate_address(type, true, &test_addr, nullptr);
if (!test_ret || (test_addr != *address)) if (!test_ret || (test_addr != *address))
logerror("TLB-PTE mismatch! %06X %06X %06x\n", *address, test_addr, m_pc); logerror("TLB-PTE mismatch! %06X %06X %06x\n", *address, test_addr, m_pc);
#endif #endif
@ -328,7 +327,7 @@ uint8_t i386_device::FETCH()
uint8_t value; uint8_t value;
uint32_t address = m_pc, error; uint32_t address = m_pc, error;
if(!translate_address(m_CPL,TRANSLATE_FETCH,&address,&error)) if(!translate_address(m_CPL,TR_FETCH,&address,&error))
PF_THROW(error); PF_THROW(error);
value = mem_pr8(address & m_a20_mask); value = mem_pr8(address & m_a20_mask);
@ -349,7 +348,7 @@ uint16_t i386_device::FETCH16()
value = (FETCH() << 0); value = (FETCH() << 0);
value |= (FETCH() << 8); value |= (FETCH() << 8);
} else { } else {
if(!translate_address(m_CPL,TRANSLATE_FETCH,&address,&error)) if(!translate_address(m_CPL,TR_FETCH,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
value = mem_pr16(address); value = mem_pr16(address);
@ -369,7 +368,7 @@ uint32_t i386_device::FETCH32()
value |= (FETCH() << 16); value |= (FETCH() << 16);
value |= (FETCH() << 24); value |= (FETCH() << 24);
} else { } else {
if(!translate_address(m_CPL,TRANSLATE_FETCH,&address,&error)) if(!translate_address(m_CPL,TR_FETCH,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -384,7 +383,7 @@ uint8_t i386_device::READ8PL(uint32_t ea, uint8_t privilege)
{ {
uint32_t address = ea, error; uint32_t address = ea, error;
if(!translate_address(privilege,TRANSLATE_READ,&address,&error)) if(!translate_address(privilege,TR_READ,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -401,7 +400,7 @@ uint16_t i386_device::READ16PL(uint32_t ea, uint8_t privilege)
case 0: case 0:
case 2: case 2:
default: default:
if(!translate_address(privilege,TRANSLATE_READ,&address,&error)) if(!translate_address(privilege,TR_READ,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -409,7 +408,7 @@ uint16_t i386_device::READ16PL(uint32_t ea, uint8_t privilege)
break; break;
case 1: case 1:
if(!translate_address(privilege,TRANSLATE_READ,&address,&error)) if(!translate_address(privilege,TR_READ,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -434,7 +433,7 @@ uint32_t i386_device::READ32PL(uint32_t ea, uint8_t privilege)
{ {
case 0: case 0:
default: default:
if(!translate_address(privilege,TRANSLATE_READ,&address,&error)) if(!translate_address(privilege,TR_READ,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -442,7 +441,7 @@ uint32_t i386_device::READ32PL(uint32_t ea, uint8_t privilege)
break; break;
case 1: case 1:
if(!translate_address(privilege,TRANSLATE_READ,&address,&error)) if(!translate_address(privilege,TR_READ,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -459,7 +458,7 @@ uint32_t i386_device::READ32PL(uint32_t ea, uint8_t privilege)
value = READ8PL(ea, privilege); value = READ8PL(ea, privilege);
address = ea + 1; address = ea + 1;
if(!translate_address(privilege,TRANSLATE_READ,&address,&error)) if(!translate_address(privilege,TR_READ,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -484,7 +483,7 @@ uint64_t i386_device::READ64PL(uint32_t ea, uint8_t privilege)
break; break;
case 1: case 1:
if(!translate_address(privilege,TRANSLATE_READ,&address,&error)) if(!translate_address(privilege,TR_READ,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -504,7 +503,7 @@ uint64_t i386_device::READ64PL(uint32_t ea, uint8_t privilege)
value |= uint64_t(READ32PL(ea + 1, privilege)) << 8; value |= uint64_t(READ32PL(ea + 1, privilege)) << 8;
address = ea + 5; address = ea + 5;
if(!translate_address(privilege,TRANSLATE_READ,&address,&error)) if(!translate_address(privilege,TR_READ,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -522,7 +521,7 @@ uint16_t i386sx_device::READ16PL(uint32_t ea, uint8_t privilege)
if (WORD_ALIGNED(ea)) if (WORD_ALIGNED(ea))
{ {
if(!translate_address(privilege,TRANSLATE_READ,&address,&error)) if(!translate_address(privilege,TR_READ,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -582,14 +581,14 @@ uint64_t i386sx_device::READ64PL(uint32_t ea, uint8_t privilege)
void i386_device::WRITE_TEST(uint32_t ea) void i386_device::WRITE_TEST(uint32_t ea)
{ {
uint32_t address = ea, error; uint32_t address = ea, error;
if(!translate_address(m_CPL,TRANSLATE_WRITE,&address,&error)) if(!translate_address(m_CPL,TR_WRITE,&address,&error))
PF_THROW(error); PF_THROW(error);
} }
void i386_device::WRITE8PL(uint32_t ea, uint8_t privilege, uint8_t value) void i386_device::WRITE8PL(uint32_t ea, uint8_t privilege, uint8_t value)
{ {
uint32_t address = ea, error; uint32_t address = ea, error;
if(!translate_address(privilege,TRANSLATE_WRITE,&address,&error)) if(!translate_address(privilege,TR_WRITE,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -604,7 +603,7 @@ void i386_device::WRITE16PL(uint32_t ea, uint8_t privilege, uint16_t value)
{ {
case 0: case 0:
case 2: case 2:
if(!translate_address(privilege,TRANSLATE_WRITE,&address,&error)) if(!translate_address(privilege,TR_WRITE,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -612,7 +611,7 @@ void i386_device::WRITE16PL(uint32_t ea, uint8_t privilege, uint16_t value)
break; break;
case 1: case 1:
if(!translate_address(privilege,TRANSLATE_WRITE,&address,&error)) if(!translate_address(privilege,TR_WRITE,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -633,7 +632,7 @@ void i386_device::WRITE32PL(uint32_t ea, uint8_t privilege, uint32_t value)
switch(ea & 3) switch(ea & 3)
{ {
case 0: case 0:
if(!translate_address(privilege,TRANSLATE_WRITE,&address,&error)) if(!translate_address(privilege,TR_WRITE,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -641,7 +640,7 @@ void i386_device::WRITE32PL(uint32_t ea, uint8_t privilege, uint32_t value)
break; break;
case 1: case 1:
if(!translate_address(privilege,TRANSLATE_WRITE,&address,&error)) if(!translate_address(privilege,TR_WRITE,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -658,7 +657,7 @@ void i386_device::WRITE32PL(uint32_t ea, uint8_t privilege, uint32_t value)
WRITE8PL(ea, privilege, value & 0xff); WRITE8PL(ea, privilege, value & 0xff);
address = ea + 1; address = ea + 1;
if(!translate_address(privilege,TRANSLATE_WRITE,&address,&error)) if(!translate_address(privilege,TR_WRITE,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -679,7 +678,7 @@ void i386_device::WRITE64PL(uint32_t ea, uint8_t privilege, uint64_t value)
break; break;
case 1: case 1:
if(!translate_address(privilege,TRANSLATE_WRITE,&address,&error)) if(!translate_address(privilege,TR_WRITE,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -699,7 +698,7 @@ void i386_device::WRITE64PL(uint32_t ea, uint8_t privilege, uint64_t value)
WRITE32PL(ea + 1, privilege, (value >> 8) & 0xffffffff); WRITE32PL(ea + 1, privilege, (value >> 8) & 0xffffffff);
address = ea + 5; address = ea + 5;
if(!translate_address(privilege,TRANSLATE_WRITE,&address,&error)) if(!translate_address(privilege,TR_WRITE,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -714,7 +713,7 @@ void i386sx_device::WRITE16PL(uint32_t ea, uint8_t privilege, uint16_t value)
if (WORD_ALIGNED(ea)) if (WORD_ALIGNED(ea))
{ {
if(!translate_address(privilege,TRANSLATE_WRITE,&address,&error)) if(!translate_address(privilege,TR_WRITE,&address,&error))
PF_THROW(error); PF_THROW(error);
address &= m_a20_mask; address &= m_a20_mask;
@ -1728,7 +1727,7 @@ uint8_t i386_device::read8_debug(uint32_t ea, uint8_t *data)
{ {
uint32_t address = ea; uint32_t address = ea;
if(!i386_translate_address(TRANSLATE_DEBUG_MASK,&address,nullptr)) if(!i386_translate_address(TR_READ, true, &address,nullptr))
return 0; return 0;
address &= m_a20_mask; address &= m_a20_mask;
@ -1863,7 +1862,7 @@ uint64_t i386_device::debug_virttophys(int params, const uint64_t *param)
{ {
uint32_t result = param[0]; uint32_t result = param[0];
if(!i386_translate_address(TRANSLATE_DEBUG_MASK,&result,nullptr)) if(!i386_translate_address(TR_READ,true,&result,nullptr))
return 0; return 0;
return result; return result;
} }
@ -2790,7 +2789,7 @@ void i386_device::execute_run()
{ {
uint32_t phys_addr = 0; uint32_t phys_addr = 0;
uint32_t error; uint32_t error;
phys_addr = (m_cr[0] & (1 << 31)) ? translate_address(m_CPL, TRANSLATE_FETCH, &m_dr[i], &error) : m_dr[i]; phys_addr = (m_cr[0] & (1 << 31)) ? translate_address(m_CPL, TR_FETCH, &m_dr[i], &error) : m_dr[i];
if(breakpoint_length != 0) // Not one byte in length? logerror it, I have no idea how this works on real processors. if(breakpoint_length != 0) // Not one byte in length? logerror it, I have no idea how this works on real processors.
{ {
logerror("i386: Breakpoint length not 1 byte on an instruction breakpoint\n"); logerror("i386: Breakpoint length not 1 byte on an instruction breakpoint\n");
@ -2857,11 +2856,12 @@ void i386_device::execute_run()
/*************************************************************************/ /*************************************************************************/
bool i386_device::memory_translate(int spacenum, int intention, offs_t &address) bool i386_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{ {
target_space = &space(spacenum);
bool ret = true; bool ret = true;
if(spacenum == AS_PROGRAM) if(spacenum == AS_PROGRAM)
ret = i386_translate_address(intention, &address, nullptr); ret = i386_translate_address(intention, true, &address, nullptr);
address &= m_a20_mask; address &= m_a20_mask;
return ret; return ret;
} }

View File

@ -59,7 +59,7 @@ protected:
// device_memory_interface overrides // device_memory_interface overrides
virtual space_config_vector memory_space_config() const override; virtual space_config_vector memory_space_config() const override;
virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
// device_state_interface overrides // device_state_interface overrides
virtual void state_import(const device_state_entry &entry) override; virtual void state_import(const device_state_entry &entry) override;
@ -397,7 +397,7 @@ protected:
void register_state_i386_x87_xmm(); void register_state_i386_x87_xmm();
uint32_t i386_translate(int segment, uint32_t ip, int rwn); uint32_t i386_translate(int segment, uint32_t ip, int rwn);
inline vtlb_entry get_permissions(uint32_t pte, int wp); inline vtlb_entry get_permissions(uint32_t pte, int wp);
bool i386_translate_address(int intention, offs_t *address, vtlb_entry *entry); bool i386_translate_address(int intention, bool debug, offs_t *address, vtlb_entry *entry);
bool translate_address(int pl, int type, uint32_t *address, uint32_t *error); bool translate_address(int pl, int type, uint32_t *address, uint32_t *error);
void CHANGE_PC(uint32_t pc); void CHANGE_PC(uint32_t pc);
inline void NEAR_BRANCH(int32_t offs); inline void NEAR_BRANCH(int32_t offs);

View File

@ -3216,7 +3216,7 @@ void i386_device::i386_group0F00_16() // Opcode 0x0f 00
i386_load_protected_mode_segment(&seg,nullptr); i386_load_protected_mode_segment(&seg,nullptr);
uint32_t addr = ((seg.selector & 4) ? m_ldtr.base : m_gdtr.base) + (seg.selector & ~7) + 5; uint32_t addr = ((seg.selector & 4) ? m_ldtr.base : m_gdtr.base) + (seg.selector & ~7) + 5;
i386_translate_address(TRANSLATE_READ, &addr, nullptr); i386_translate_address(TR_READ, false, &addr, nullptr);
m_program->write_byte(addr, (seg.flags & 0xff) | 2); m_program->write_byte(addr, (seg.flags & 0xff) | 2);
m_task.limit = seg.limit; m_task.limit = seg.limit;

View File

@ -3018,7 +3018,7 @@ void i386_device::i386_group0F00_32() // Opcode 0x0f 00
i386_load_protected_mode_segment(&seg,nullptr); i386_load_protected_mode_segment(&seg,nullptr);
uint32_t addr = ((seg.selector & 4) ? m_ldtr.base : m_gdtr.base) + (seg.selector & ~7) + 5; uint32_t addr = ((seg.selector & 4) ? m_ldtr.base : m_gdtr.base) + (seg.selector & ~7) + 5;
i386_translate_address(TRANSLATE_READ, &addr, nullptr); i386_translate_address(TR_READ, false, &addr, nullptr);
m_program->write_byte(addr, (seg.flags & 0xff) | 2); m_program->write_byte(addr, (seg.flags & 0xff) | 2);
m_task.limit = seg.limit; m_task.limit = seg.limit;

View File

@ -327,7 +327,7 @@ extern int i386_parity_table[256];
#define MMX(n) (*((MMX_REG *)(&m_x87_reg[(n)].low))) #define MMX(n) (*((MMX_REG *)(&m_x87_reg[(n)].low)))
#define XMM(n) m_sse_reg[(n)] #define XMM(n) m_sse_reg[(n)]
#define VTLB_FLAG_DIRTY 0x100 #define FLAG_DIRTY 0x100 // VTLB flag
#define CYCLES_NUM(x) (m_cycles -= (x)) #define CYCLES_NUM(x) (m_cycles -= (x))
#define FAULT(fault,error) {m_ext = 1; i386_trap_with_error(fault,0,0,error); return;} #define FAULT(fault,error) {m_ext = 1; i386_trap_with_error(fault,0,0,error); return;}

View File

@ -91,7 +91,7 @@ void i386_device::i386_set_descriptor_accessed(uint16_t selector)
base = m_gdtr.base; base = m_gdtr.base;
addr = base + (selector & ~7) + 5; addr = base + (selector & ~7) + 5;
i386_translate_address(TRANSLATE_READ, &addr, nullptr); i386_translate_address(TR_READ, false, &addr, nullptr);
rights = m_program->read_byte(addr); rights = m_program->read_byte(addr);
// Should a fault be thrown if the table is read only? // Should a fault be thrown if the table is read only?
m_program->write_byte(addr, rights | 1); m_program->write_byte(addr, rights | 1);
@ -2494,7 +2494,7 @@ inline void i386_device::dri_changed()
int breakpoint_length = (m_dr[7] >> ((dr << 2) + 16 + 2)) & 3; int breakpoint_length = (m_dr[7] >> ((dr << 2) + 16 + 2)) & 3;
uint32_t phys_addr = m_dr[dr]; uint32_t phys_addr = m_dr[dr];
uint32_t error; uint32_t error;
if(translate_address(m_CPL, TRANSLATE_READ, &phys_addr, &error)) if(translate_address(m_CPL, TR_READ, &phys_addr, &error))
{ {
phys_addr &= ~3; // According to CUP386, data breakpoints are only reliable on dword-aligned addresses, so align this to a dword. phys_addr &= ~3; // According to CUP386, data breakpoints are only reliable on dword-aligned addresses, so align this to a dword.
uint32_t true_mask = 0; uint32_t true_mask = 0;

View File

@ -369,8 +369,9 @@ void i80286_cpu_device::state_string_export(const device_state_entry &entry, std
} }
} }
bool i80286_cpu_device::memory_translate(int spacenum, int intention, offs_t &address) bool i80286_cpu_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{ {
target_space = &space(spacenum);
if(spacenum == AS_PROGRAM) if(spacenum == AS_PROGRAM)
address &= m_amask; address &= m_amask;

View File

@ -97,7 +97,7 @@ protected:
virtual uint32_t execute_input_lines() const noexcept override { return 1; } virtual uint32_t execute_input_lines() const noexcept override { return 1; }
virtual void execute_set_input(int inputnum, int state) override; virtual void execute_set_input(int inputnum, int state) override;
bool memory_translate(int spacenum, int intention, offs_t &address) override; bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
virtual void interrupt(int int_num, int trap = 1) override { if(trap) throw TRAP(int_num, (uint16_t)-1); else interrupt_descriptor(int_num, 0, 0); } virtual void interrupt(int int_num, int trap = 1) override { if(trap) throw TRAP(int_num, (uint16_t)-1); else interrupt_descriptor(int_num, 0, 0); }
virtual uint8_t read_port_byte(uint16_t port) override; virtual uint8_t read_port_byte(uint16_t port) override;

View File

@ -57,8 +57,9 @@ void m4510_device::device_reset()
m65ce02_device::device_reset(); m65ce02_device::device_reset();
} }
bool m4510_device::memory_translate(int spacenum, int intention, offs_t &address) bool m4510_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{ {
target_space = &space(spacenum);
if (spacenum == AS_PROGRAM) if (spacenum == AS_PROGRAM)
{ {
address = map(address); address = map(address);

View File

@ -45,7 +45,7 @@ protected:
virtual void device_start() override; virtual void device_start() override;
virtual void device_reset() override; virtual void device_reset() override;
virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
inline uint32_t map(uint16_t adr) { inline uint32_t map(uint16_t adr) {
if(map_enable & (1 << (adr >> 13))) { if(map_enable & (1 << (adr >> 13))) {

View File

@ -71,11 +71,12 @@ void m68020pmmu_device::device_start()
init_cpu_m68020pmmu(); init_cpu_m68020pmmu();
} }
bool m68020hmmu_device::memory_translate(int space, int intention, offs_t &address) bool m68020hmmu_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{ {
target_space = &space(spacenum);
/* only applies to the program address space and only does something if the MMU's enabled */ /* only applies to the program address space and only does something if the MMU's enabled */
{ {
if ((space == AS_PROGRAM) && (m_hmmu_enabled)) if ((spacenum == AS_PROGRAM) && (m_hmmu_enabled))
{ {
address = hmmu_translate_addr(address); address = hmmu_translate_addr(address);
} }

View File

@ -78,7 +78,7 @@ public:
virtual u32 execute_min_cycles() const noexcept override { return 2; } virtual u32 execute_min_cycles() const noexcept override { return 2; }
virtual u32 execute_max_cycles() const noexcept override { return 158; } virtual u32 execute_max_cycles() const noexcept override { return 158; }
virtual bool memory_translate(int space, int intention, offs_t &address) override; virtual bool memory_translate(int space, int intention, offs_t &address, address_space *&target_space) override;
// device-level overrides // device-level overrides
virtual void device_start() override; virtual void device_start() override;

View File

@ -794,12 +794,13 @@ void m68000_musashi_device::m68k_cause_bus_error()
m_run_mode = RUN_MODE_BERR_AERR_RESET; m_run_mode = RUN_MODE_BERR_AERR_RESET;
} }
bool m68000_musashi_device::memory_translate(int space, int intention, offs_t &address) bool m68000_musashi_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{ {
target_space = &space(spacenum);
/* only applies to the program address space and only does something if the MMU's enabled */ /* only applies to the program address space and only does something if the MMU's enabled */
{ {
/* 68040 needs to call the MMU even when disabled so transparent translation works */ /* 68040 needs to call the MMU even when disabled so transparent translation works */
if ((space == AS_PROGRAM) && ((m_pmmu_enabled) || (CPU_TYPE_IS_040_PLUS()))) if ((spacenum == AS_PROGRAM) && ((m_pmmu_enabled) || (CPU_TYPE_IS_040_PLUS())))
{ {
// FIXME: m_mmu_tmp_sr will be overwritten in pmmu_translate_addr_with_fc // FIXME: m_mmu_tmp_sr will be overwritten in pmmu_translate_addr_with_fc
u16 temp_mmu_tmp_sr = m_mmu_tmp_sr; u16 temp_mmu_tmp_sr = m_mmu_tmp_sr;

View File

@ -321,7 +321,7 @@ protected:
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
// device_memory_interface overrides // device_memory_interface overrides
virtual bool memory_translate(int space, int intention, offs_t &address) override; virtual bool memory_translate(int space, int intention, offs_t &address, address_space *&target_space) override;
#include "m68kcpu.h" #include "m68kcpu.h"
#include "m68kops.h" #include "m68kops.h"

View File

@ -642,13 +642,21 @@ device_memory_interface::space_config_vector mips1core_device_base::memory_space
}; };
} }
bool mips1core_device_base::memory_translate(int spacenum, int intention, offs_t &address) bool mips1core_device_base::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{
target_space = &space(spacenum);
if(spacenum != AS_PROGRAM)
return true;
return memory_translate(intention, address, true);
}
bool mips1core_device_base::memory_translate(int intention, offs_t &address, bool debug)
{ {
// check for kernel memory address // check for kernel memory address
if (BIT(address, 31)) if (BIT(address, 31))
{ {
// check debug or kernel mode // check debug or kernel mode
if ((intention & TRANSLATE_DEBUG_MASK) || !(SR & SR_KUc)) if (debug || !(SR & SR_KUc))
{ {
switch (address & 0xe0000000) switch (address & 0xe0000000)
{ {
@ -873,13 +881,13 @@ void mips1core_device_base::generate_exception(u32 exception, bool refill)
void mips1core_device_base::address_error(int intention, u32 const address) void mips1core_device_base::address_error(int intention, u32 const address)
{ {
if (!machine().side_effects_disabled() && !(intention & TRANSLATE_DEBUG_MASK)) if (!machine().side_effects_disabled())
{ {
logerror("address_error 0x%08x (%s)\n", address, machine().describe_context()); logerror("address_error 0x%08x (%s)\n", address, machine().describe_context());
m_cop0[COP0_BadVAddr] = address; m_cop0[COP0_BadVAddr] = address;
generate_exception((intention & TRANSLATE_WRITE) ? EXCEPTION_ADDRSTORE : EXCEPTION_ADDRLOAD); generate_exception((intention & TR_WRITE) ? EXCEPTION_ADDRSTORE : EXCEPTION_ADDRLOAD);
// address errors shouldn't typically occur, so a breakpoint is handy // address errors shouldn't typically occur, so a breakpoint is handy
machine().debug_break(); machine().debug_break();
@ -1097,11 +1105,11 @@ template <typename T, bool Aligned, typename U> std::enable_if_t<std::is_convert
// alignment error // alignment error
if (Aligned && (address & (sizeof(T) - 1))) if (Aligned && (address & (sizeof(T) - 1)))
{ {
address_error(TRANSLATE_READ, address); address_error(TR_READ, address);
return; return;
} }
if (memory_translate(m_data_spacenum, TRANSLATE_READ, address)) if (memory_translate(TR_READ, address, false))
{ {
// align address for ld[lr] instructions // align address for ld[lr] instructions
if (!Aligned) if (!Aligned)
@ -1127,11 +1135,11 @@ template <typename T, bool Aligned, typename U> std::enable_if_t<std::is_convert
// alignment error // alignment error
if (Aligned && (address & (sizeof(T) - 1))) if (Aligned && (address & (sizeof(T) - 1)))
{ {
address_error(TRANSLATE_WRITE, address); address_error(TR_WRITE, address);
return; return;
} }
if (memory_translate(m_data_spacenum, TRANSLATE_WRITE, address)) if (memory_translate(TR_WRITE, address, false))
{ {
// align address for sd[lr] instructions // align address for sd[lr] instructions
if (!Aligned) if (!Aligned)
@ -1151,13 +1159,13 @@ bool mips1core_device_base::fetch(u32 address, std::function<void(u32)> &&apply)
// alignment error // alignment error
if (address & 3) if (address & 3)
{ {
address_error(TRANSLATE_FETCH, address); address_error(TR_FETCH, address);
return false; return false;
} }
if (memory_translate(0, TRANSLATE_FETCH, address)) if (memory_translate(TR_FETCH, address, false))
{ {
u32 const data = space(0).read_dword(address); u32 const data = space(AS_PROGRAM).read_dword(address);
if (m_bus_error) if (m_bus_error)
{ {
@ -1271,9 +1279,9 @@ void mips1_device_base::device_reset()
// initialize tlb mru index with identity mapping // initialize tlb mru index with identity mapping
for (unsigned i = 0; i < std::size(m_tlb); i++) for (unsigned i = 0; i < std::size(m_tlb); i++)
{ {
m_tlb_mru[TRANSLATE_READ][i] = i; m_tlb_mru[TR_READ][i] = i;
m_tlb_mru[TRANSLATE_WRITE][i] = i; m_tlb_mru[TR_WRITE][i] = i;
m_tlb_mru[TRANSLATE_FETCH][i] = i; m_tlb_mru[TR_FETCH][i] = i;
} }
} }
@ -1945,13 +1953,21 @@ template <typename T> void mips1_device_base::set_cop1_reg(unsigned const reg, T
m_f[reg] = data; m_f[reg] = data;
} }
bool mips1_device_base::memory_translate(int spacenum, int intention, offs_t &address) bool mips1_device_base::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{
target_space = &space(spacenum);
if(spacenum != AS_PROGRAM)
return true;
return memory_translate(intention, address, true);
}
bool mips1_device_base::memory_translate(int intention, offs_t &address, bool debug)
{ {
// check for kernel memory address // check for kernel memory address
if (BIT(address, 31)) if (BIT(address, 31))
{ {
// check debug or kernel mode // check debug or kernel mode
if ((intention & TRANSLATE_DEBUG_MASK) || !(SR & SR_KUc)) if (debug || !(SR & SR_KUc))
{ {
switch (address & 0xe0000000) switch (address & 0xe0000000)
{ {
@ -1976,7 +1992,7 @@ bool mips1_device_base::memory_translate(int spacenum, int intention, offs_t &ad
// key is a combination of VPN and ASID // key is a combination of VPN and ASID
u32 const key = (address & EH_VPN) | (m_cop0[COP0_EntryHi] & EH_ASID); u32 const key = (address & EH_VPN) | (m_cop0[COP0_EntryHi] & EH_ASID);
unsigned *mru = m_tlb_mru[intention & TRANSLATE_TYPE_MASK]; unsigned *mru = m_tlb_mru[intention];
bool refill = !BIT(address, 31); bool refill = !BIT(address, 31);
bool modify = false; bool modify = false;
@ -1999,7 +2015,7 @@ bool mips1_device_base::memory_translate(int spacenum, int intention, offs_t &ad
} }
// test dirty // test dirty
if ((intention & TRANSLATE_WRITE) && !(entry[1] & EL_D)) if ((intention & TR_WRITE) && !(entry[1] & EL_D))
{ {
refill = false; refill = false;
modify = true; modify = true;
@ -2017,7 +2033,7 @@ bool mips1_device_base::memory_translate(int spacenum, int intention, offs_t &ad
return true; return true;
} }
if (!machine().side_effects_disabled() && !(intention & TRANSLATE_DEBUG_MASK)) if (!machine().side_effects_disabled() && !debug)
{ {
if (VERBOSE & LOG_TLB) if (VERBOSE & LOG_TLB)
{ {
@ -2026,7 +2042,7 @@ bool mips1_device_base::memory_translate(int spacenum, int intention, offs_t &ad
(m_cop0[COP0_EntryHi] & EH_ASID) >> 6, address, machine().describe_context()); (m_cop0[COP0_EntryHi] & EH_ASID) >> 6, address, machine().describe_context());
else else
LOGMASKED(LOG_TLB, "asid %2d tlb miss %c address 0x%08x (%s)\n", LOGMASKED(LOG_TLB, "asid %2d tlb miss %c address 0x%08x (%s)\n",
(m_cop0[COP0_EntryHi] & EH_ASID) >> 6, (intention & TRANSLATE_WRITE) ? 'w' : 'r', address, machine().describe_context()); (m_cop0[COP0_EntryHi] & EH_ASID) >> 6, (intention & TR_WRITE) ? 'w' : 'r', address, machine().describe_context());
} }
// load tlb exception registers // load tlb exception registers
@ -2034,7 +2050,7 @@ bool mips1_device_base::memory_translate(int spacenum, int intention, offs_t &ad
m_cop0[COP0_EntryHi] = key; m_cop0[COP0_EntryHi] = key;
m_cop0[COP0_Context] = (m_cop0[COP0_Context] & PTE_BASE) | ((address >> 10) & BAD_VPN); m_cop0[COP0_Context] = (m_cop0[COP0_Context] & PTE_BASE) | ((address >> 10) & BAD_VPN);
generate_exception(modify ? EXCEPTION_TLBMOD : (intention & TRANSLATE_WRITE) ? EXCEPTION_TLBSTORE : EXCEPTION_TLBLOAD, refill); generate_exception(modify ? EXCEPTION_TLBMOD : (intention & TR_WRITE) ? EXCEPTION_TLBSTORE : EXCEPTION_TLBLOAD, refill);
} }
return false; return false;

View File

@ -164,7 +164,8 @@ protected:
// device_memory_interface overrides // device_memory_interface overrides
virtual space_config_vector memory_space_config() const override; virtual space_config_vector memory_space_config() const override;
virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
bool memory_translate(int intention, offs_t &address, bool debug);
// device_disasm_interface overrides // device_disasm_interface overrides
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
@ -298,7 +299,8 @@ protected:
virtual void device_reset() override; virtual void device_reset() override;
// device_memory_interface overrides // device_memory_interface overrides
virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
bool memory_translate(int intention, offs_t &address, bool debug);
virtual void handle_cop0(u32 const op) override; virtual void handle_cop0(u32 const op) override;
virtual u32 get_cop0_reg(unsigned const reg) override; virtual u32 get_cop0_reg(unsigned const reg) override;

View File

@ -1123,11 +1123,11 @@ void mips3_device::device_reset()
} }
/* load the fixed TLB range */ /* load the fixed TLB range */
vtlb_load(2 * m_tlbentries + 0, (0xa0000000 - 0x80000000) >> MIPS3_MIN_PAGE_SHIFT, 0x80000000, 0x00000000 | VTLB_READ_ALLOWED | VTLB_WRITE_ALLOWED | VTLB_FETCH_ALLOWED | VTLB_FLAG_VALID); vtlb_load(2 * m_tlbentries + 0, (0xa0000000 - 0x80000000) >> MIPS3_MIN_PAGE_SHIFT, 0x80000000, 0x00000000 | READ_ALLOWED | WRITE_ALLOWED | FETCH_ALLOWED | FLAG_VALID);
vtlb_load(2 * m_tlbentries + 1, (0xc0000000 - 0xa0000000) >> MIPS3_MIN_PAGE_SHIFT, 0xa0000000, 0x00000000 | VTLB_READ_ALLOWED | VTLB_WRITE_ALLOWED | VTLB_FETCH_ALLOWED | VTLB_FLAG_VALID); vtlb_load(2 * m_tlbentries + 1, (0xc0000000 - 0xa0000000) >> MIPS3_MIN_PAGE_SHIFT, 0xa0000000, 0x00000000 | READ_ALLOWED | WRITE_ALLOWED | FETCH_ALLOWED | FLAG_VALID);
// TX4925 on-board peripherals pass-through // TX4925 on-board peripherals pass-through
if (m_flavor == MIPS3_TYPE_TX4925) if (m_flavor == MIPS3_TYPE_TX4925)
vtlb_load(2 * m_tlbentries + 2, (0xff200000 - 0xff1f0000) >> MIPS3_MIN_PAGE_SHIFT, 0xff1f0000, 0xff1f0000 | VTLB_READ_ALLOWED | VTLB_WRITE_ALLOWED | VTLB_FETCH_ALLOWED | VTLB_FLAG_VALID); vtlb_load(2 * m_tlbentries + 2, (0xff200000 - 0xff1f0000) >> MIPS3_MIN_PAGE_SHIFT, 0xff1f0000, 0xff1f0000 | READ_ALLOWED | WRITE_ALLOWED | FETCH_ALLOWED | FLAG_VALID);
m_tlb_seed = 0; m_tlb_seed = 0;
m_core->mode = (MODE_KERNEL << 1) | 0; m_core->mode = (MODE_KERNEL << 1) | 0;
@ -1143,14 +1143,16 @@ void mips3_device::device_reset()
} }
bool mips3_device::memory_translate(int spacenum, int intention, offs_t &address) bool mips3_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{ {
target_space = &space(spacenum);
/* only applies to the program address space */ /* only applies to the program address space */
if (spacenum == AS_PROGRAM) if (spacenum == AS_PROGRAM)
{ {
const vtlb_entry *table = vtlb_table(); const vtlb_entry *table = vtlb_table();
vtlb_entry entry = table[address >> MIPS3_MIN_PAGE_SHIFT]; vtlb_entry entry = table[address >> MIPS3_MIN_PAGE_SHIFT];
if ((entry & (1 << (intention & (TRANSLATE_TYPE_MASK | TRANSLATE_USER_MASK)))) == 0) if ((entry & (1 << intention)) == 0)
return false; return false;
address = (entry & ~MIPS3_MIN_PAGE_MASK) | (address & MIPS3_MIN_PAGE_MASK); address = (entry & ~MIPS3_MIN_PAGE_MASK) | (address & MIPS3_MIN_PAGE_MASK);
} }
@ -1176,7 +1178,7 @@ std::unique_ptr<util::disasm_interface> r5900le_device::create_disassembler()
inline bool mips3_device::RBYTE(offs_t address, uint32_t *result) inline bool mips3_device::RBYTE(offs_t address, uint32_t *result)
{ {
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_READ_ALLOWED) if (tlbval & READ_ALLOWED)
{ {
const uint32_t tlbaddress = (tlbval & ~0xfff) | (address & 0xfff); const uint32_t tlbaddress = (tlbval & ~0xfff) | (address & 0xfff);
for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
@ -1192,7 +1194,7 @@ inline bool mips3_device::RBYTE(offs_t address, uint32_t *result)
} }
else else
{ {
if(tlbval & VTLB_FLAG_FIXED) if(tlbval & FLAG_FIXED)
{ {
generate_tlb_exception(EXCEPTION_TLBLOAD, address); generate_tlb_exception(EXCEPTION_TLBLOAD, address);
} }
@ -1209,7 +1211,7 @@ inline bool mips3_device::RBYTE(offs_t address, uint32_t *result)
inline bool mips3_device::RHALF(offs_t address, uint32_t *result) inline bool mips3_device::RHALF(offs_t address, uint32_t *result)
{ {
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_READ_ALLOWED) if (tlbval & READ_ALLOWED)
{ {
const uint32_t tlbaddress = (tlbval & ~0xfff) | (address & 0xfff); const uint32_t tlbaddress = (tlbval & ~0xfff) | (address & 0xfff);
for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
@ -1225,7 +1227,7 @@ inline bool mips3_device::RHALF(offs_t address, uint32_t *result)
} }
else else
{ {
if(tlbval & VTLB_FLAG_FIXED) if(tlbval & FLAG_FIXED)
{ {
generate_tlb_exception(EXCEPTION_TLBLOAD, address); generate_tlb_exception(EXCEPTION_TLBLOAD, address);
} }
@ -1242,7 +1244,7 @@ inline bool mips3_device::RHALF(offs_t address, uint32_t *result)
inline bool mips3_device::RWORD(offs_t address, uint32_t *result, bool insn) inline bool mips3_device::RWORD(offs_t address, uint32_t *result, bool insn)
{ {
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_READ_ALLOWED) if (tlbval & READ_ALLOWED)
{ {
const uint32_t tlbaddress = (tlbval & ~0xfff) | (address & 0xfff); const uint32_t tlbaddress = (tlbval & ~0xfff) | (address & 0xfff);
for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
@ -1258,7 +1260,7 @@ inline bool mips3_device::RWORD(offs_t address, uint32_t *result, bool insn)
} }
else else
{ {
if(tlbval & VTLB_FLAG_FIXED) if(tlbval & FLAG_FIXED)
{ {
generate_tlb_exception(EXCEPTION_TLBLOAD, address); generate_tlb_exception(EXCEPTION_TLBLOAD, address);
} }
@ -1275,13 +1277,13 @@ inline bool mips3_device::RWORD(offs_t address, uint32_t *result, bool insn)
inline bool mips3_device::RWORD_MASKED(offs_t address, uint32_t *result, uint32_t mem_mask) inline bool mips3_device::RWORD_MASKED(offs_t address, uint32_t *result, uint32_t mem_mask)
{ {
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_READ_ALLOWED) if (tlbval & READ_ALLOWED)
{ {
*result = (*m_memory.read_dword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), mem_mask); *result = (*m_memory.read_dword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), mem_mask);
} }
else else
{ {
if(tlbval & VTLB_FLAG_FIXED) if(tlbval & FLAG_FIXED)
{ {
generate_tlb_exception(EXCEPTION_TLBLOAD, address); generate_tlb_exception(EXCEPTION_TLBLOAD, address);
} }
@ -1298,13 +1300,13 @@ inline bool mips3_device::RWORD_MASKED(offs_t address, uint32_t *result, uint32_
inline bool mips3_device::RDOUBLE(offs_t address, uint64_t *result) inline bool mips3_device::RDOUBLE(offs_t address, uint64_t *result)
{ {
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_READ_ALLOWED) if (tlbval & READ_ALLOWED)
{ {
*result = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff)); *result = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff));
} }
else else
{ {
if(tlbval & VTLB_FLAG_FIXED) if(tlbval & FLAG_FIXED)
{ {
generate_tlb_exception(EXCEPTION_TLBLOAD, address); generate_tlb_exception(EXCEPTION_TLBLOAD, address);
} }
@ -1321,13 +1323,13 @@ inline bool mips3_device::RDOUBLE(offs_t address, uint64_t *result)
inline bool mips3_device::RDOUBLE_MASKED(offs_t address, uint64_t *result, uint64_t mem_mask) inline bool mips3_device::RDOUBLE_MASKED(offs_t address, uint64_t *result, uint64_t mem_mask)
{ {
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_READ_ALLOWED) if (tlbval & READ_ALLOWED)
{ {
*result = (*m_memory.read_qword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), mem_mask); *result = (*m_memory.read_qword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), mem_mask);
} }
else else
{ {
if(tlbval & VTLB_FLAG_FIXED) if(tlbval & FLAG_FIXED)
{ {
generate_tlb_exception(EXCEPTION_TLBLOAD, address); generate_tlb_exception(EXCEPTION_TLBLOAD, address);
} }
@ -1344,7 +1346,7 @@ inline bool mips3_device::RDOUBLE_MASKED(offs_t address, uint64_t *result, uint6
inline void mips3_device::WBYTE(offs_t address, uint8_t data) inline void mips3_device::WBYTE(offs_t address, uint8_t data)
{ {
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_WRITE_ALLOWED) if (tlbval & WRITE_ALLOWED)
{ {
const uint32_t tlbaddress = (tlbval & ~0xfff) | (address & 0xfff); const uint32_t tlbaddress = (tlbval & ~0xfff) | (address & 0xfff);
for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
@ -1360,11 +1362,11 @@ inline void mips3_device::WBYTE(offs_t address, uint8_t data)
} }
else else
{ {
if(tlbval & VTLB_READ_ALLOWED) if(tlbval & READ_ALLOWED)
{ {
generate_tlb_exception(EXCEPTION_TLBMOD, address); generate_tlb_exception(EXCEPTION_TLBMOD, address);
} }
else if(tlbval & VTLB_FLAG_FIXED) else if(tlbval & FLAG_FIXED)
{ {
generate_tlb_exception(EXCEPTION_TLBSTORE, address); generate_tlb_exception(EXCEPTION_TLBSTORE, address);
} }
@ -1378,7 +1380,7 @@ inline void mips3_device::WBYTE(offs_t address, uint8_t data)
inline void mips3_device::WHALF(offs_t address, uint16_t data) inline void mips3_device::WHALF(offs_t address, uint16_t data)
{ {
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_WRITE_ALLOWED) if (tlbval & WRITE_ALLOWED)
{ {
const uint32_t tlbaddress = (tlbval & ~0xfff) | (address & 0xfff); const uint32_t tlbaddress = (tlbval & ~0xfff) | (address & 0xfff);
for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
@ -1394,11 +1396,11 @@ inline void mips3_device::WHALF(offs_t address, uint16_t data)
} }
else else
{ {
if(tlbval & VTLB_READ_ALLOWED) if(tlbval & READ_ALLOWED)
{ {
generate_tlb_exception(EXCEPTION_TLBMOD, address); generate_tlb_exception(EXCEPTION_TLBMOD, address);
} }
else if(tlbval & VTLB_FLAG_FIXED) else if(tlbval & FLAG_FIXED)
{ {
generate_tlb_exception(EXCEPTION_TLBSTORE, address); generate_tlb_exception(EXCEPTION_TLBSTORE, address);
} }
@ -1412,7 +1414,7 @@ inline void mips3_device::WHALF(offs_t address, uint16_t data)
inline void mips3_device::WWORD(offs_t address, uint32_t data) inline void mips3_device::WWORD(offs_t address, uint32_t data)
{ {
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_WRITE_ALLOWED) if (tlbval & WRITE_ALLOWED)
{ {
const uint32_t tlbaddress = (tlbval & ~0xfff) | (address & 0xfff); const uint32_t tlbaddress = (tlbval & ~0xfff) | (address & 0xfff);
for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
@ -1428,11 +1430,11 @@ inline void mips3_device::WWORD(offs_t address, uint32_t data)
} }
else else
{ {
if(tlbval & VTLB_READ_ALLOWED) if(tlbval & READ_ALLOWED)
{ {
generate_tlb_exception(EXCEPTION_TLBMOD, address); generate_tlb_exception(EXCEPTION_TLBMOD, address);
} }
else if(tlbval & VTLB_FLAG_FIXED) else if(tlbval & FLAG_FIXED)
{ {
generate_tlb_exception(EXCEPTION_TLBSTORE, address); generate_tlb_exception(EXCEPTION_TLBSTORE, address);
} }
@ -1446,17 +1448,17 @@ inline void mips3_device::WWORD(offs_t address, uint32_t data)
inline void mips3_device::WWORD_MASKED(offs_t address, uint32_t data, uint32_t mem_mask) inline void mips3_device::WWORD_MASKED(offs_t address, uint32_t data, uint32_t mem_mask)
{ {
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_WRITE_ALLOWED) if (tlbval & WRITE_ALLOWED)
{ {
(*m_memory.write_dword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data, mem_mask); (*m_memory.write_dword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data, mem_mask);
} }
else else
{ {
if(tlbval & VTLB_READ_ALLOWED) if(tlbval & READ_ALLOWED)
{ {
generate_tlb_exception(EXCEPTION_TLBMOD, address); generate_tlb_exception(EXCEPTION_TLBMOD, address);
} }
else if(tlbval & VTLB_FLAG_FIXED) else if(tlbval & FLAG_FIXED)
{ {
generate_tlb_exception(EXCEPTION_TLBSTORE, address); generate_tlb_exception(EXCEPTION_TLBSTORE, address);
} }
@ -1470,17 +1472,17 @@ inline void mips3_device::WWORD_MASKED(offs_t address, uint32_t data, uint32_t m
inline void mips3_device::WDOUBLE(offs_t address, uint64_t data) inline void mips3_device::WDOUBLE(offs_t address, uint64_t data)
{ {
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_WRITE_ALLOWED) if (tlbval & WRITE_ALLOWED)
{ {
(*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data); (*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data);
} }
else else
{ {
if(tlbval & VTLB_READ_ALLOWED) if(tlbval & READ_ALLOWED)
{ {
generate_tlb_exception(EXCEPTION_TLBMOD, address); generate_tlb_exception(EXCEPTION_TLBMOD, address);
} }
else if(tlbval & VTLB_FLAG_FIXED) else if(tlbval & FLAG_FIXED)
{ {
generate_tlb_exception(EXCEPTION_TLBSTORE, address); generate_tlb_exception(EXCEPTION_TLBSTORE, address);
} }
@ -1494,17 +1496,17 @@ inline void mips3_device::WDOUBLE(offs_t address, uint64_t data)
inline void mips3_device::WDOUBLE_MASKED(offs_t address, uint64_t data, uint64_t mem_mask) inline void mips3_device::WDOUBLE_MASKED(offs_t address, uint64_t data, uint64_t mem_mask)
{ {
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_WRITE_ALLOWED) if (tlbval & WRITE_ALLOWED)
{ {
(*m_memory.write_qword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data, mem_mask); (*m_memory.write_qword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data, mem_mask);
} }
else else
{ {
if(tlbval & VTLB_READ_ALLOWED) if(tlbval & READ_ALLOWED)
{ {
generate_tlb_exception(EXCEPTION_TLBMOD, address); generate_tlb_exception(EXCEPTION_TLBMOD, address);
} }
else if(tlbval & VTLB_FLAG_FIXED) else if(tlbval & FLAG_FIXED)
{ {
generate_tlb_exception(EXCEPTION_TLBSTORE, address); generate_tlb_exception(EXCEPTION_TLBSTORE, address);
} }
@ -1560,18 +1562,18 @@ inline void r5900le_device::WQUAD(offs_t address, uint64_t data_hi, uint64_t dat
} }
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_WRITE_ALLOWED) if (tlbval & WRITE_ALLOWED)
{ {
(*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data_lo); (*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data_lo);
(*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | ((address + 8) & 0xfff), data_hi); (*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | ((address + 8) & 0xfff), data_hi);
} }
else else
{ {
if(tlbval & VTLB_READ_ALLOWED) if(tlbval & READ_ALLOWED)
{ {
generate_tlb_exception(EXCEPTION_TLBMOD, address); generate_tlb_exception(EXCEPTION_TLBMOD, address);
} }
else if(tlbval & VTLB_FLAG_FIXED) else if(tlbval & FLAG_FIXED)
{ {
generate_tlb_exception(EXCEPTION_TLBSTORE, address); generate_tlb_exception(EXCEPTION_TLBSTORE, address);
} }
@ -1650,14 +1652,14 @@ inline bool r5900le_device::RQUAD(offs_t address, uint64_t *result_hi, uint64_t
} }
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_READ_ALLOWED) if (tlbval & READ_ALLOWED)
{ {
*result_lo = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff)); *result_lo = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff));
*result_hi = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | ((address + 8) & 0xfff)); *result_hi = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | ((address + 8) & 0xfff));
} }
else else
{ {
if(tlbval & VTLB_FLAG_FIXED) if(tlbval & FLAG_FIXED)
{ {
generate_tlb_exception(EXCEPTION_TLBLOAD, address); generate_tlb_exception(EXCEPTION_TLBLOAD, address);
} }

View File

@ -327,7 +327,7 @@ protected:
// device_memory_interface overrides // device_memory_interface overrides
virtual space_config_vector memory_space_config() const override; virtual space_config_vector memory_space_config() const override;
virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
// device_state_interface overrides // device_state_interface overrides
virtual void state_export(const device_state_entry &entry) override; virtual void state_export(const device_state_entry &entry) override;

View File

@ -414,15 +414,15 @@ void mips3_device::tlb_map_entry(int tlbindex)
/* valid? */ /* valid? */
if ((lo & 2) != 0) if ((lo & 2) != 0)
{ {
flags |= VTLB_FLAG_VALID | VTLB_READ_ALLOWED | VTLB_FETCH_ALLOWED; flags |= FLAG_VALID | READ_ALLOWED | FETCH_ALLOWED;
/* writable? */ /* writable? */
if ((lo & 4) != 0) if ((lo & 4) != 0)
flags |= VTLB_WRITE_ALLOWED; flags |= WRITE_ALLOWED;
/* mirror the flags for user mode if the VPN is in user space */ /* mirror the flags for user mode if the VPN is in user space */
if (effvpn < (0x80000000 >> MIPS3_MIN_PAGE_SHIFT)) if (effvpn < (0x80000000 >> MIPS3_MIN_PAGE_SHIFT))
flags |= (flags << 4) & (VTLB_USER_READ_ALLOWED | VTLB_USER_WRITE_ALLOWED | VTLB_USER_FETCH_ALLOWED); flags |= (flags << 4) & (USER_READ_ALLOWED | USER_WRITE_ALLOWED | USER_FETCH_ALLOWED);
} }
/* load the virtual TLB with the corresponding entries */ /* load the virtual TLB with the corresponding entries */

View File

@ -703,9 +703,9 @@ void mips3_device::static_generate_tlb_mismatch()
UML_MOV(block, mem(&m_core->arg1), I1); // mov [arg1],i1 UML_MOV(block, mem(&m_core->arg1), I1); // mov [arg1],i1
UML_CALLC(block, cfunc_printf_debug, this); // callc printf_debug UML_CALLC(block, cfunc_printf_debug, this); // callc printf_debug
} }
UML_TEST(block, I1, VTLB_FETCH_ALLOWED); // test i1,VTLB_FETCH_ALLOWED UML_TEST(block, I1, FETCH_ALLOWED); // test i1,FETCH_ALLOWED
UML_JMPc(block, COND_NZ, 1); // jmp 1,nz UML_JMPc(block, COND_NZ, 1); // jmp 1,nz
UML_TEST(block, I1, VTLB_FLAG_FIXED); // test i1,VTLB_FLAG_FIXED UML_TEST(block, I1, FLAG_FIXED); // test i1,FLAG_FIXED
UML_EXHc(block, COND_NZ, *m_exception[EXCEPTION_TLBLOAD], I0); // exh exception[TLBLOAD],i0,nz UML_EXHc(block, COND_NZ, *m_exception[EXCEPTION_TLBLOAD], I0); // exh exception[TLBLOAD],i0,nz
UML_EXH(block, *m_exception[EXCEPTION_TLBLOAD_FILL], I0); // exh exception[TLBLOAD_FILL],i0 UML_EXH(block, *m_exception[EXCEPTION_TLBLOAD_FILL], I0); // exh exception[TLBLOAD_FILL],i0
UML_LABEL(block, 1); // 1: UML_LABEL(block, 1); // 1:
@ -873,7 +873,7 @@ void mips3_device::static_generate_memory_accessor(int mode, int size, int iswri
/* general case: assume paging and perform a translation */ /* general case: assume paging and perform a translation */
UML_SHR(block, I3, I0, 12); // shr i3,i0,12 UML_SHR(block, I3, I0, 12); // shr i3,i0,12
UML_LOAD(block, I3, (void *)vtlb_table(), I3, SIZE_DWORD, SCALE_x4);// load i3,[vtlb_table],i3,dword UML_LOAD(block, I3, (void *)vtlb_table(), I3, SIZE_DWORD, SCALE_x4);// load i3,[vtlb_table],i3,dword
UML_TEST(block, I3, iswrite ? VTLB_WRITE_ALLOWED : VTLB_READ_ALLOWED);// test i3,iswrite ? VTLB_WRITE_ALLOWED : VTLB_READ_ALLOWED UML_TEST(block, I3, iswrite ? WRITE_ALLOWED : READ_ALLOWED);// test i3,iswrite ? WRITE_ALLOWED : READ_ALLOWED
UML_JMPc(block, COND_Z, tlbmiss = label++); // jmp tlbmiss,z UML_JMPc(block, COND_Z, tlbmiss = label++); // jmp tlbmiss,z
UML_ROLINS(block, I0, I3, 0, 0xfffff000); // rolins i0,i3,0,0xfffff000 UML_ROLINS(block, I0, I3, 0, 0xfffff000); // rolins i0,i3,0,0xfffff000
@ -1022,11 +1022,11 @@ void mips3_device::static_generate_memory_accessor(int mode, int size, int iswri
UML_LABEL(block, tlbmiss); // tlbmiss: UML_LABEL(block, tlbmiss); // tlbmiss:
if (iswrite) if (iswrite)
{ {
UML_TEST(block, I3, VTLB_READ_ALLOWED); // test i3,VTLB_READ_ALLOWED UML_TEST(block, I3, READ_ALLOWED); // test i3,READ_ALLOWED
UML_EXHc(block, COND_NZ, *m_exception[EXCEPTION_TLBMOD], I0); UML_EXHc(block, COND_NZ, *m_exception[EXCEPTION_TLBMOD], I0);
// exh tlbmod,i0,nz // exh tlbmod,i0,nz
} }
UML_TEST(block, I3, VTLB_FLAG_FIXED); // test i3,VTLB_FLAG_FIXED UML_TEST(block, I3, FLAG_FIXED); // test i3,FLAG_FIXED
UML_EXHc(block, COND_NZ, exception_tlb, I0); // exh tlb,i0,nz UML_EXHc(block, COND_NZ, exception_tlb, I0); // exh tlb,i0,nz
UML_EXH(block, exception_tlbfill, I0); // exh tlbfill,i0 UML_EXH(block, exception_tlbfill, I0); // exh tlbfill,i0
} }
@ -1365,7 +1365,7 @@ void mips3_device::generate_sequence_instruction(drcuml_block &block, compiler_s
const vtlb_entry *tlbtable = vtlb_table(); const vtlb_entry *tlbtable = vtlb_table();
/* if we currently have a valid TLB read entry, we just verify */ /* if we currently have a valid TLB read entry, we just verify */
if (tlbtable[desc->pc >> 12] & VTLB_FETCH_ALLOWED) if (tlbtable[desc->pc >> 12] & FETCH_ALLOWED)
{ {
if (PRINTF_MMU) if (PRINTF_MMU)
{ {

View File

@ -40,7 +40,8 @@ bool mips3_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
// compute the physical PC // compute the physical PC
assert((desc.physpc & 3) == 0); assert((desc.physpc & 3) == 0);
if (!m_mips3->memory_translate(AS_PROGRAM, TRANSLATE_FETCH, desc.physpc)) address_space *tspace;
if (!m_mips3->memory_translate(AS_PROGRAM, device_memory_interface::TR_FETCH, desc.physpc, tspace))
{ {
// uh-oh: a page fault; leave the description empty and just if this is the first instruction, leave it empty and // uh-oh: a page fault; leave the description empty and just if this is the first instruction, leave it empty and
// mark as needing to validate; otherwise, just end the sequence here // mark as needing to validate; otherwise, just end the sequence here

View File

@ -27,6 +27,7 @@
*/ */
#include "emu.h" #include "emu.h"
#include "divtlb.h"
#include "debug/debugcpu.h" #include "debug/debugcpu.h"
#include "r4000.h" #include "r4000.h"
#include "mips3dsm.h" #include "mips3dsm.h"
@ -237,9 +238,9 @@ void r4000_base_device::device_reset()
// initialize tlb mru index with identity mapping // initialize tlb mru index with identity mapping
for (unsigned i = 0; i < std::size(m_tlb); i++) for (unsigned i = 0; i < std::size(m_tlb); i++)
{ {
m_tlb_mru[TRANSLATE_READ][i] = i; m_tlb_mru[TR_READ][i] = i;
m_tlb_mru[TRANSLATE_WRITE][i] = i; m_tlb_mru[TR_WRITE][i] = i;
m_tlb_mru[TRANSLATE_FETCH][i] = i; m_tlb_mru[TR_FETCH][i] = i;
} }
// initialize statistics // initialize statistics
@ -266,12 +267,13 @@ device_memory_interface::space_config_vector r4000_base_device::memory_space_con
}; };
} }
bool r4000_base_device::memory_translate(int spacenum, int intention, offs_t &address) bool r4000_base_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{ {
target_space = &space(spacenum);
// FIXME: address truncation // FIXME: address truncation
u64 placeholder = s32(address); u64 placeholder = s32(address);
translate_result const t = translate(intention, placeholder); translate_result const t = translate(intention, true, placeholder);
if (t == ERROR || t == MISS) if (t == ERROR || t == MISS)
return false; return false;
@ -1249,7 +1251,7 @@ void r4000_base_device::cp0_cache(u32 const op)
{ {
// TODO: translation type for CACHE instruction? Read seems reasonable since only the tag is changing here // TODO: translation type for CACHE instruction? Read seems reasonable since only the tag is changing here
u64 physical_address = ADDR(m_r[RSREG], s16(op)); u64 physical_address = ADDR(m_r[RSREG], s16(op));
translate_result const t = translate(TRANSLATE_READ, physical_address); translate_result const t = translate(TR_READ, false, physical_address);
if (t == ERROR || t == MISS) if (t == ERROR || t == MISS)
return; return;
@ -1279,7 +1281,7 @@ void r4000_base_device::cp0_cache(u32 const op)
// TODO: translation type for CACHE instruction? Read seems reasonable since only the tag is changing here // TODO: translation type for CACHE instruction? Read seems reasonable since only the tag is changing here
u64 const virtual_address = ADDR(m_r[RSREG], s16(op)); u64 const virtual_address = ADDR(m_r[RSREG], s16(op));
u64 physical_address = virtual_address; u64 physical_address = virtual_address;
translate_result const t = translate(TRANSLATE_READ, physical_address); translate_result const t = translate(TR_READ, false, physical_address);
if (t == ERROR || t == MISS) if (t == ERROR || t == MISS)
return; return;
@ -3488,7 +3490,7 @@ void r4000_base_device::cp2_execute(u32 const op)
} }
} }
r4000_base_device::translate_result r4000_base_device::translate(int intention, u64 &address) r4000_base_device::translate_result r4000_base_device::translate(int intention, bool debug, u64 &address)
{ {
/* /*
* Decode the program address into one of the following ranges depending on * Decode the program address into one of the following ranges depending on
@ -3642,7 +3644,7 @@ r4000_base_device::translate_result r4000_base_device::translate(int intention,
// address needs translation, using a combination of VPN2 and ASID // address needs translation, using a combination of VPN2 and ASID
u64 const key = (address & (extended ? (EH_R | EH_VPN2_64) : EH_VPN2_32)) | (m_cp0[CP0_EntryHi] & EH_ASID); u64 const key = (address & (extended ? (EH_R | EH_VPN2_64) : EH_VPN2_32)) | (m_cp0[CP0_EntryHi] & EH_ASID);
unsigned *mru = m_tlb_mru[intention & TRANSLATE_TYPE_MASK]; unsigned *mru = m_tlb_mru[intention & device_vtlb_interface::TR_TYPE];
if (VERBOSE & LOG_STATS) if (VERBOSE & LOG_STATS)
m_tlb_scans++; m_tlb_scans++;
@ -3673,7 +3675,7 @@ r4000_base_device::translate_result r4000_base_device::translate(int intention,
} }
// test dirty // test dirty
if ((intention & TRANSLATE_WRITE) && !(pfn & EL_D)) if ((intention & TR_WRITE) && !(pfn & EL_D))
{ {
modify = true; modify = true;
break; break;
@ -3691,7 +3693,7 @@ r4000_base_device::translate_result r4000_base_device::translate(int intention,
} }
// tlb miss, invalid entry, or a store to a non-dirty entry // tlb miss, invalid entry, or a store to a non-dirty entry
if (!machine().side_effects_disabled() && !(intention & TRANSLATE_DEBUG_MASK)) if (!machine().side_effects_disabled() && !debug)
{ {
if (VERBOSE & LOG_TLB) if (VERBOSE & LOG_TLB)
{ {
@ -3702,7 +3704,7 @@ r4000_base_device::translate_result r4000_base_device::translate(int intention,
m_cp0[CP0_EntryHi] & EH_ASID, address, machine().describe_context()); m_cp0[CP0_EntryHi] & EH_ASID, address, machine().describe_context());
else else
LOGMASKED(LOG_TLB, "tlb miss %c asid 0x%02x address 0x%016x (%s)\n", LOGMASKED(LOG_TLB, "tlb miss %c asid 0x%02x address 0x%016x (%s)\n",
mode[intention & TRANSLATE_TYPE_MASK], m_cp0[CP0_EntryHi] & EH_ASID, address, machine().describe_context()); mode[intention & device_vtlb_interface::TR_TYPE], m_cp0[CP0_EntryHi] & EH_ASID, address, machine().describe_context());
} }
// load tlb exception registers // load tlb exception registers
@ -3712,9 +3714,9 @@ r4000_base_device::translate_result r4000_base_device::translate(int intention,
m_cp0[CP0_XContext] = (m_cp0[CP0_XContext] & XCONTEXT_PTEBASE) | ((address >> 31) & XCONTEXT_R) | ((address >> 9) & XCONTEXT_BADVPN2); m_cp0[CP0_XContext] = (m_cp0[CP0_XContext] & XCONTEXT_PTEBASE) | ((address >> 31) & XCONTEXT_R) | ((address >> 9) & XCONTEXT_BADVPN2);
if (invalid || modify || (SR & SR_EXL)) if (invalid || modify || (SR & SR_EXL))
cpu_exception(modify ? EXCEPTION_MOD : (intention & TRANSLATE_WRITE) ? EXCEPTION_TLBS : EXCEPTION_TLBL); cpu_exception(modify ? EXCEPTION_MOD : (intention & TR_WRITE) ? EXCEPTION_TLBS : EXCEPTION_TLBL);
else else
cpu_exception((intention & TRANSLATE_WRITE) ? EXCEPTION_TLBS : EXCEPTION_TLBL, extended ? 0x080 : 0x000); cpu_exception((intention & TR_WRITE) ? EXCEPTION_TLBS : EXCEPTION_TLBL, extended ? 0x080 : 0x000);
} }
return MISS; return MISS;
@ -3722,7 +3724,7 @@ r4000_base_device::translate_result r4000_base_device::translate(int intention,
void r4000_base_device::address_error(int intention, u64 const address) void r4000_base_device::address_error(int intention, u64 const address)
{ {
if (!machine().side_effects_disabled() && !(intention & TRANSLATE_DEBUG_MASK)) if (!machine().side_effects_disabled())
{ {
logerror("address_error 0x%016x (%s)\n", address, machine().describe_context()); logerror("address_error 0x%016x (%s)\n", address, machine().describe_context());
@ -3730,7 +3732,7 @@ void r4000_base_device::address_error(int intention, u64 const address)
if (!(SR & SR_EXL)) if (!(SR & SR_EXL))
m_cp0[CP0_BadVAddr] = address; m_cp0[CP0_BadVAddr] = address;
cpu_exception((intention & TRANSLATE_WRITE) ? EXCEPTION_ADES : EXCEPTION_ADEL); cpu_exception((intention & TR_WRITE) ? EXCEPTION_ADES : EXCEPTION_ADEL);
// address errors shouldn't typically occur, so a breakpoint is handy // address errors shouldn't typically occur, so a breakpoint is handy
machine().debug_break(); machine().debug_break();
@ -3757,16 +3759,16 @@ template <typename T, bool Aligned, typename U> std::enable_if_t<std::is_convert
// alignment error // alignment error
if (Aligned && (address & (sizeof(T) - 1))) if (Aligned && (address & (sizeof(T) - 1)))
{ {
address_error(TRANSLATE_READ, address); address_error(TR_READ, address);
return false; return false;
} }
translate_result const t = translate(TRANSLATE_READ, address); translate_result const t = translate(TR_READ, false, address);
// address error // address error
if (t == ERROR) if (t == ERROR)
{ {
address_error(TRANSLATE_READ, address); address_error(TR_READ, address);
return false; return false;
} }
@ -3820,16 +3822,16 @@ template <typename T, typename U> std::enable_if_t<std::is_convertible<U, std::f
// alignment error // alignment error
if (address & (sizeof(T) - 1)) if (address & (sizeof(T) - 1))
{ {
address_error(TRANSLATE_READ, address); address_error(TR_READ, address);
return false; return false;
} }
translate_result const t = translate(TRANSLATE_READ, address); translate_result const t = translate(TR_READ, false, address);
// address error // address error
if (t == ERROR) if (t == ERROR)
{ {
address_error(TRANSLATE_READ, address); address_error(TR_READ, address);
return false; return false;
} }
@ -3865,16 +3867,16 @@ template <typename T, bool Aligned, typename U> std::enable_if_t<std::is_convert
// alignment error // alignment error
if (Aligned && (address & (sizeof(T) - 1))) if (Aligned && (address & (sizeof(T) - 1)))
{ {
address_error(TRANSLATE_WRITE, address); address_error(TR_WRITE, address);
return false; return false;
} }
translate_result const t = translate(TRANSLATE_WRITE, address); translate_result const t = translate(TR_WRITE, false, address);
// address error // address error
if (t == ERROR) if (t == ERROR)
{ {
address_error(TRANSLATE_WRITE, address); address_error(TR_WRITE, address);
return false; return false;
} }
@ -3918,17 +3920,17 @@ bool r4000_base_device::fetch(u64 address, std::function<void(u32)> &&apply)
// alignment error // alignment error
if (address & 3) if (address & 3)
{ {
address_error(TRANSLATE_FETCH, address); address_error(TR_FETCH, address);
return false; return false;
} }
translate_result const t = translate(TRANSLATE_FETCH, address); translate_result const t = translate(TR_FETCH, false, address);
// address error // address error
if (t == ERROR) if (t == ERROR)
{ {
address_error(TRANSLATE_FETCH, address); address_error(TR_FETCH, address);
return false; return false;
} }

View File

@ -322,7 +322,7 @@ protected:
// device_memory_interface overrides // device_memory_interface overrides
virtual space_config_vector memory_space_config() const override; virtual space_config_vector memory_space_config() const override;
virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
// device_disasm_interface overrides // device_disasm_interface overrides
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
@ -378,7 +378,7 @@ protected:
// address and memory handling // address and memory handling
enum translate_result : unsigned { ERROR, MISS, UNCACHED, CACHED }; enum translate_result : unsigned { ERROR, MISS, UNCACHED, CACHED };
translate_result translate(int intention, u64 &address); translate_result translate(int intention, bool debug, u64 &address);
void address_error(int intention, u64 const address); void address_error(int intention, u64 const address);
template <typename T> void accessors(T &m); template <typename T> void accessors(T &m);

View File

@ -339,8 +339,9 @@ void mn1880_device::device_reset()
m_mmu_enable = 0; m_mmu_enable = 0;
} }
bool mn1880_device::memory_translate(int spacenum, int intention, offs_t &address) bool mn1880_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{ {
target_space = &space(spacenum);
switch (spacenum) switch (spacenum)
{ {
case AS_PROGRAM: case AS_PROGRAM:

View File

@ -45,7 +45,7 @@ protected:
// device_memory_interface overrides // device_memory_interface overrides
virtual space_config_vector memory_space_config() const override; virtual space_config_vector memory_space_config() const override;
virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
// device_state_interface overrides // device_state_interface overrides
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;

View File

@ -196,8 +196,10 @@ offs_t nec_common_device::v33_translate(offs_t addr)
return addr & 0xfffff; return addr & 0xfffff;
} }
bool v33_base_device::memory_translate(int spacenum, int intention, offs_t &address) bool v33_base_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{ {
target_space = &space(spacenum);
if (spacenum == AS_PROGRAM) if (spacenum == AS_PROGRAM)
address = v33_translate(address); address = v33_translate(address);
return true; return true;

View File

@ -689,7 +689,7 @@ protected:
v33_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal_port_map); v33_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal_port_map);
// device_memory_interface overrides // device_memory_interface overrides
virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
void v33_internal_port_map(address_map &map); void v33_internal_port_map(address_map &map);
uint16_t xam_r(); uint16_t xam_r();

View File

@ -3502,9 +3502,10 @@ template <int Width> device_memory_interface::space_config_vector ns32000_device
}; };
} }
template <int Width> bool ns32000_device<Width>::memory_translate(int spacenum, int intention, offs_t &address) template <int Width> bool ns32000_device<Width>::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{ {
return !m_mmu || m_mmu->translate(space(spacenum), spacenum, address, m_psr & PSR_U, intention & TRANSLATE_WRITE, false, intention & TRANSLATE_DEBUG_MASK) == ns32000_mmu_interface::COMPLETE; target_space = &space(spacenum);
return !m_mmu || m_mmu->translate(space(spacenum), spacenum, address, m_psr & PSR_U, intention == TR_WRITE, false, true) == ns32000_mmu_interface::COMPLETE;
} }
template <int Width> std::unique_ptr<util::disasm_interface> ns32000_device<Width>::create_disassembler() template <int Width> std::unique_ptr<util::disasm_interface> ns32000_device<Width>::create_disassembler()

View File

@ -35,7 +35,7 @@ protected:
// device_memory_interface overrides // device_memory_interface overrides
virtual space_config_vector memory_space_config() const override; virtual space_config_vector memory_space_config() const override;
virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
// device_state_interface overrides // device_state_interface overrides
virtual void state_string_export(device_state_entry const &entry, std::string &str) const override; virtual void state_string_export(device_state_entry const &entry, std::string &str) const override;

View File

@ -263,7 +263,7 @@ protected:
// device_memory_interface overrides // device_memory_interface overrides
virtual space_config_vector memory_space_config() const override; virtual space_config_vector memory_space_config() const override;
virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
// device_state_interface overrides // device_state_interface overrides
virtual void state_export(const device_state_entry &entry) override; virtual void state_export(const device_state_entry &entry) override;
@ -635,7 +635,7 @@ protected:
void set_timebase(uint64_t newtb); void set_timebase(uint64_t newtb);
uint32_t get_decrementer(); uint32_t get_decrementer();
void set_decrementer(uint32_t newdec); void set_decrementer(uint32_t newdec);
uint32_t ppccom_translate_address_internal(int intention, offs_t &address); uint32_t ppccom_translate_address_internal(int intention, bool debug, offs_t &address);
void ppc4xx_set_irq_line(uint32_t bitmask, int state); void ppc4xx_set_irq_line(uint32_t bitmask, int state);
int ppc4xx_get_irq_line(uint32_t bitmask); int ppc4xx_get_irq_line(uint32_t bitmask);
void ppc4xx_dma_update_irq_states(); void ppc4xx_dma_update_irq_states();

View File

@ -334,9 +334,9 @@ device_memory_interface::space_config_vector ppc_device::memory_space_config() c
static inline bool page_access_allowed(int transtype, uint8_t key, uint8_t protbits) static inline bool page_access_allowed(int transtype, uint8_t key, uint8_t protbits)
{ {
if (key == 0) if (key == 0)
return (transtype == TRANSLATE_WRITE) ? (protbits != 3) : true; return (transtype == device_memory_interface::TR_WRITE) ? (protbits != 3) : true;
else else
return (transtype == TRANSLATE_WRITE) ? (protbits == 2) : (protbits != 0); return (transtype == device_memory_interface::TR_WRITE) ? (protbits == 2) : (protbits != 0);
} }
@ -1237,10 +1237,10 @@ void ppc_device::ppccom_dcstore_callback()
filling filling
-------------------------------------------------*/ -------------------------------------------------*/
uint32_t ppc_device::ppccom_translate_address_internal(int intention, offs_t &address) uint32_t ppc_device::ppccom_translate_address_internal(int intention, bool debug, offs_t &address)
{ {
int transpriv = ((intention & TRANSLATE_USER_MASK) == 0); // 1 for supervisor, 0 for user int transpriv = ((intention & TR_USER) == 0); // 1 for supervisor, 0 for user
int transtype = intention & TRANSLATE_TYPE_MASK; int transtype = intention & TR_TYPE;
offs_t hash, hashbase, hashmask; offs_t hash, hashbase, hashmask;
int batbase, batnum, hashnum; int batbase, batnum, hashnum;
uint32_t segreg; uint32_t segreg;
@ -1253,7 +1253,7 @@ uint32_t ppc_device::ppccom_translate_address_internal(int intention, offs_t &ad
fatalerror("MMU enabled but not supported!\n"); fatalerror("MMU enabled but not supported!\n");
/* only check if PE is enabled */ /* only check if PE is enabled */
if (transtype == TRANSLATE_WRITE && (m_core->msr & MSR4XX_PE)) if (transtype == TR_WRITE && (m_core->msr & MSR4XX_PE))
{ {
/* are we within one of the protection ranges? */ /* are we within one of the protection ranges? */
int inrange1 = ((address >> 12) >= (m_core->spr[SPR4XX_PBL1] >> 12) && (address >> 12) < (m_core->spr[SPR4XX_PBU1] >> 12)); int inrange1 = ((address >> 12) >= (m_core->spr[SPR4XX_PBL1] >> 12) && (address >> 12) < (m_core->spr[SPR4XX_PBU1] >> 12));
@ -1272,7 +1272,7 @@ uint32_t ppc_device::ppccom_translate_address_internal(int intention, offs_t &ad
return 0x001; return 0x001;
/* also no translation necessary if translation is disabled */ /* also no translation necessary if translation is disabled */
if ((transtype == TRANSLATE_FETCH && (m_core->msr & MSROEA_IR) == 0) || (transtype != TRANSLATE_FETCH && (m_core->msr & MSROEA_DR) == 0)) if ((transtype == TR_FETCH && (m_core->msr & MSROEA_IR) == 0) || (transtype != TR_FETCH && (m_core->msr & MSROEA_DR) == 0))
return 0x001; return 0x001;
/* first scan the appropriate BAT */ /* first scan the appropriate BAT */
@ -1282,7 +1282,7 @@ uint32_t ppc_device::ppccom_translate_address_internal(int intention, offs_t &ad
{ {
uint32_t upper = m_core->spr[SPROEA_IBAT0U + 2*batnum + 0]; uint32_t upper = m_core->spr[SPROEA_IBAT0U + 2*batnum + 0];
uint32_t lower = m_core->spr[SPROEA_IBAT0U + 2*batnum + 1]; uint32_t lower = m_core->spr[SPROEA_IBAT0U + 2*batnum + 1];
int privbit = ((intention & TRANSLATE_USER_MASK) == 0) ? 3 : 2; int privbit = ((intention & TR_USER) == 0) ? 3 : 2;
// printf("bat %d upper = %08x privbit %d\n", batnum, upper, privbit); // printf("bat %d upper = %08x privbit %d\n", batnum, upper, privbit);
@ -1299,7 +1299,7 @@ uint32_t ppc_device::ppccom_translate_address_internal(int intention, offs_t &ad
/* verify protection; if we fail, return false and indicate a protection violation */ /* verify protection; if we fail, return false and indicate a protection violation */
if (!page_access_allowed(transtype, key, upper & 3)) if (!page_access_allowed(transtype, key, upper & 3))
{ {
return DSISR_PROTECTED | ((transtype == TRANSLATE_WRITE) ? DSISR_STORE : 0); return DSISR_PROTECTED | ((transtype == TR_WRITE) ? DSISR_STORE : 0);
} }
/* otherwise we're good */ /* otherwise we're good */
@ -1312,7 +1312,7 @@ uint32_t ppc_device::ppccom_translate_address_internal(int intention, offs_t &ad
} }
else else
{ {
batbase = (transtype == TRANSLATE_FETCH) ? SPROEA_IBAT0U : SPROEA_DBAT0U; batbase = (transtype == TR_FETCH) ? SPROEA_IBAT0U : SPROEA_DBAT0U;
for (batnum = 0; batnum < 4; batnum++) for (batnum = 0; batnum < 4; batnum++)
{ {
@ -1331,7 +1331,7 @@ uint32_t ppc_device::ppccom_translate_address_internal(int intention, offs_t &ad
/* verify protection; if we fail, return false and indicate a protection violation */ /* verify protection; if we fail, return false and indicate a protection violation */
if (!page_access_allowed(transtype, 1, lower & 3)) if (!page_access_allowed(transtype, 1, lower & 3))
{ {
return DSISR_PROTECTED | ((transtype == TRANSLATE_WRITE) ? DSISR_STORE : 0); return DSISR_PROTECTED | ((transtype == TR_WRITE) ? DSISR_STORE : 0);
} }
/* otherwise we're good */ /* otherwise we're good */
@ -1353,13 +1353,13 @@ uint32_t ppc_device::ppccom_translate_address_internal(int intention, offs_t &ad
/* look up the segment register */ /* look up the segment register */
segreg = m_core->sr[address >> 28]; segreg = m_core->sr[address >> 28];
if (transtype == TRANSLATE_FETCH && (segreg & 0x10000000)) if (transtype == TR_FETCH && (segreg & 0x10000000))
return DSISR_PROTECTED | ((transtype == TRANSLATE_WRITE) ? DSISR_STORE : 0); return DSISR_PROTECTED | ((transtype == TR_WRITE) ? DSISR_STORE : 0);
/* check for memory-forced I/O */ /* check for memory-forced I/O */
if (m_cap & PPCCAP_MFIOC) if (m_cap & PPCCAP_MFIOC)
{ {
if ((transtype != TRANSLATE_FETCH) && ((segreg & 0x87f00000) == 0x87f00000)) if ((transtype != TR_FETCH) && ((segreg & 0x87f00000) == 0x87f00000))
{ {
address = ((segreg & 0xf)<<28) | (address & 0x0fffffff); address = ((segreg & 0xf)<<28) | (address & 0x0fffffff);
return 1; return 1;
@ -1382,12 +1382,12 @@ uint32_t ppc_device::ppccom_translate_address_internal(int intention, offs_t &ad
m_core->mmu603_cmp = 0x80000000 | ((segreg & 0xffffff) << 7) | (0 << 6) | ((address >> 22) & 0x3f); m_core->mmu603_cmp = 0x80000000 | ((segreg & 0xffffff) << 7) | (0 << 6) | ((address >> 22) & 0x3f);
m_core->mmu603_hash[0] = hashbase | ((hash << 6) & hashmask); m_core->mmu603_hash[0] = hashbase | ((hash << 6) & hashmask);
m_core->mmu603_hash[1] = hashbase | ((~hash << 6) & hashmask); m_core->mmu603_hash[1] = hashbase | ((~hash << 6) & hashmask);
if ((entry & (VTLB_FLAG_FIXED | VTLB_FLAG_VALID)) == (VTLB_FLAG_FIXED | VTLB_FLAG_VALID)) if ((entry & (FLAG_FIXED | FLAG_VALID)) == (FLAG_FIXED | FLAG_VALID))
{ {
address = (entry & 0xfffff000) | (address & 0x00000fff); address = (entry & 0xfffff000) | (address & 0x00000fff);
return 0x001; return 0x001;
} }
return DSISR_NOT_FOUND | ((transtype == TRANSLATE_WRITE) ? DSISR_STORE : 0); return DSISR_NOT_FOUND | ((transtype == TR_WRITE) ? DSISR_STORE : 0);
} }
/* loop twice over hashes */ /* loop twice over hashes */
@ -1410,13 +1410,13 @@ uint32_t ppc_device::ppccom_translate_address_internal(int intention, offs_t &ad
/* verify protection; if we fail, return false and indicate a protection violation */ /* verify protection; if we fail, return false and indicate a protection violation */
if (!page_access_allowed(transtype, (segreg >> (29 + transpriv)) & 1, pteglower & 3)) if (!page_access_allowed(transtype, (segreg >> (29 + transpriv)) & 1, pteglower & 3))
return DSISR_PROTECTED | ((transtype == TRANSLATE_WRITE) ? DSISR_STORE : 0); return DSISR_PROTECTED | ((transtype == TR_WRITE) ? DSISR_STORE : 0);
/* update page table bits */ /* update page table bits */
if (!(intention & TRANSLATE_DEBUG_MASK)) if (!debug)
{ {
pteglower |= 0x100; pteglower |= 0x100;
if (transtype == TRANSLATE_WRITE) if (transtype == TR_WRITE)
pteglower |= 0x080; pteglower |= 0x080;
ptegptr[BYTE_XOR_BE(ptenum * 2 + 1)] = pteglower; ptegptr[BYTE_XOR_BE(ptenum * 2 + 1)] = pteglower;
} }
@ -1432,7 +1432,7 @@ uint32_t ppc_device::ppccom_translate_address_internal(int intention, offs_t &ad
} }
/* we failed to find any match: not found */ /* we failed to find any match: not found */
return DSISR_NOT_FOUND | ((transtype == TRANSLATE_WRITE) ? DSISR_STORE : 0); return DSISR_NOT_FOUND | ((transtype == TR_WRITE) ? DSISR_STORE : 0);
} }
@ -1441,14 +1441,16 @@ uint32_t ppc_device::ppccom_translate_address_internal(int intention, offs_t &ad
from logical to physical from logical to physical
-------------------------------------------------*/ -------------------------------------------------*/
bool ppc_device::memory_translate(int spacenum, int intention, offs_t &address) bool ppc_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{ {
target_space = &space(spacenum);
/* only applies to the program address space */ /* only applies to the program address space */
if (spacenum != AS_PROGRAM) if (spacenum != AS_PROGRAM)
return true; return true;
/* translation is successful if the internal routine returns 0 or 1 */ /* translation is successful if the internal routine returns 0 or 1 */
return (ppccom_translate_address_internal(intention, address) <= 1); return (ppccom_translate_address_internal(intention, true, address) <= 1);
} }
@ -1458,7 +1460,10 @@ bool ppc_device::memory_translate(int spacenum, int intention, offs_t &address)
void ppc_device::ppccom_tlb_fill() void ppc_device::ppccom_tlb_fill()
{ {
vtlb_fill(m_core->param0, m_core->param1); offs_t address = m_core->param0;
if(ppccom_translate_address_internal(m_core->param1, false, address) > 1)
return;
vtlb_fill(m_core->param0, address, m_core->param1);
} }
@ -1489,14 +1494,14 @@ void ppc_device::ppccom_get_dsisr()
if (m_core->param1 & 1) if (m_core->param1 & 1)
{ {
intent = TRANSLATE_WRITE; intent = TR_WRITE;
} }
else else
{ {
intent = TRANSLATE_READ; intent = TR_READ;
} }
m_core->param1 = ppccom_translate_address_internal(intent, m_core->param0); m_core->param1 = ppccom_translate_address_internal(intent, false, m_core->param0);
} }
/*------------------------------------------------- /*-------------------------------------------------
@ -1540,11 +1545,11 @@ void ppc_device::ppccom_execute_tlbl()
entrynum = ((address >> 12) & 0x1f) | (machine().rand() & 0x20) | (isitlb ? 0x40 : 0); entrynum = ((address >> 12) & 0x1f) | (machine().rand() & 0x20) | (isitlb ? 0x40 : 0);
/* determine the flags */ /* determine the flags */
flags = VTLB_FLAG_VALID | VTLB_READ_ALLOWED | VTLB_FETCH_ALLOWED; flags = FLAG_VALID | READ_ALLOWED | FETCH_ALLOWED;
if (m_core->spr[SPR603_RPA] & 0x80) if (m_core->spr[SPR603_RPA] & 0x80)
flags |= VTLB_WRITE_ALLOWED; flags |= WRITE_ALLOWED;
if (isitlb) if (isitlb)
flags |= VTLB_FETCH_ALLOWED; flags |= FETCH_ALLOWED;
/* load the entry */ /* load the entry */
vtlb_load(entrynum, 1, address, (m_core->spr[SPR603_RPA] & 0xfffff000) | flags); vtlb_load(entrynum, 1, address, (m_core->spr[SPR603_RPA] & 0xfffff000) | flags);

View File

@ -776,11 +776,11 @@ void ppc_device::static_generate_tlb_mismatch()
UML_SHR(block, I1, I0, 12); // shr i1,i0,12 UML_SHR(block, I1, I0, 12); // shr i1,i0,12
UML_LOAD(block, I2, (void *)vtlb_table(), I1, SIZE_DWORD, SCALE_x4); // load i2,[vtlb],i1,dword UML_LOAD(block, I2, (void *)vtlb_table(), I1, SIZE_DWORD, SCALE_x4); // load i2,[vtlb],i1,dword
UML_MOV(block, mem(&m_core->param0), I0); // mov [param0],i0 UML_MOV(block, mem(&m_core->param0), I0); // mov [param0],i0
UML_MOV(block, mem(&m_core->param1), TRANSLATE_FETCH); // mov [param1],TRANSLATE_FETCH UML_MOV(block, mem(&m_core->param1), TR_FETCH); // mov [param1],TR_FETCH
UML_CALLC(block, (c_function)cfunc_ppccom_mismatch, this); UML_CALLC(block, (c_function)cfunc_ppccom_mismatch, this);
UML_CALLC(block, (c_function)cfunc_ppccom_tlb_fill, this); // callc tlbfill,ppc UML_CALLC(block, (c_function)cfunc_ppccom_tlb_fill, this); // callc tlbfill,ppc
UML_LOAD(block, I1, (void *)vtlb_table(), I1, SIZE_DWORD, SCALE_x4); // load i1,[vtlb],i1,dword UML_LOAD(block, I1, (void *)vtlb_table(), I1, SIZE_DWORD, SCALE_x4); // load i1,[vtlb],i1,dword
UML_TEST(block, I1, VTLB_FETCH_ALLOWED); // test i1,VTLB_FETCH_ALLOWED UML_TEST(block, I1, FETCH_ALLOWED); // test i1,FETCH_ALLOWED
UML_JMPc(block, COND_Z, isi = label++); // jmp isi,z UML_JMPc(block, COND_Z, isi = label++); // jmp isi,z
UML_CMP(block, I2, 0); // cmp i2,0 UML_CMP(block, I2, 0); // cmp i2,0
UML_JMPc(block, COND_NZ, exit = label++); // jmp exit,nz UML_JMPc(block, COND_NZ, exit = label++); // jmp exit,nz
@ -1008,9 +1008,9 @@ void ppc_device::static_generate_memory_accessor(int mode, int size, int iswrite
int ramnum; int ramnum;
if (mode & MODE_USER) if (mode & MODE_USER)
translate_type = iswrite ? TRANSLATE_WRITE_USER : TRANSLATE_READ_USER; translate_type = iswrite ? TR_UWRITE : TR_UREAD;
else else
translate_type = iswrite ? TRANSLATE_WRITE : TRANSLATE_READ; translate_type = iswrite ? TR_WRITE : TR_READ;
/* begin generating */ /* begin generating */
drcuml_block &block(m_drcuml->begin_block(1024)); drcuml_block &block(m_drcuml->begin_block(1024));

View File

@ -74,7 +74,7 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
int regnum; int regnum;
// compute the physical PC // compute the physical PC
if (!m_ppc.memory_translate(AS_PROGRAM, TRANSLATE_FETCH, desc.physpc)) if (m_ppc.ppccom_translate_address_internal(TR_FETCH, false, desc.physpc) > 1)
{ {
// uh-oh: a page fault; leave the description empty and just if this is the first instruction, leave it empty and // uh-oh: a page fault; leave the description empty and just if this is the first instruction, leave it empty and
// mark as needing to validate; otherwise, just end the sequence here // mark as needing to validate; otherwise, just end the sequence here

View File

@ -1016,8 +1016,9 @@ device_memory_interface::space_config_vector romp_device::memory_space_config()
return space_config_vector { std::make_pair(AS_PROGRAM, &m_mem_config) }; return space_config_vector { std::make_pair(AS_PROGRAM, &m_mem_config) };
} }
bool romp_device::memory_translate(int spacenum, int intention, offs_t &address) bool romp_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{ {
target_space = &space(spacenum);
return true; return true;
} }

View File

@ -119,7 +119,7 @@ protected:
// device_memory_interface overrides // device_memory_interface overrides
virtual space_config_vector memory_space_config() const override; virtual space_config_vector memory_space_config() const override;
virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
// device_state_interface overrides // device_state_interface overrides
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;

View File

@ -2074,12 +2074,13 @@ void z180_device::execute_set_input(int irqline, int state)
} }
/* logical to physical address translation */ /* logical to physical address translation */
bool z180_device::memory_translate(int spacenum, int intention, offs_t &address) bool z180_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{ {
if (spacenum == AS_PROGRAM) if (spacenum == AS_PROGRAM)
{ {
address = MMU_REMAP_ADDR(address); address = MMU_REMAP_ADDR(address);
} }
target_space = &space(spacenum);
return true; return true;
} }

View File

@ -154,7 +154,7 @@ protected:
// device_memory_interface overrides // device_memory_interface overrides
virtual space_config_vector memory_space_config() const override; virtual space_config_vector memory_space_config() const override;
virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
// device_state_interface overrides // device_state_interface overrides
virtual void state_import(const device_state_entry &entry) override; virtual void state_import(const device_state_entry &entry) override;

View File

@ -193,10 +193,11 @@ void kc82_device::mmu_w(offs_t offset, u8 data)
// physical addresses // physical addresses
//------------------------------------------------- //-------------------------------------------------
bool kc82_device::memory_translate(int spacenum, int intention, offs_t &address) bool kc82_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{ {
if (spacenum == AS_PROGRAM || spacenum == AS_OPCODES) if (spacenum == AS_PROGRAM || spacenum == AS_OPCODES)
address = (address + m_mmu_base[(address & 0xfc00) >> 10]) & 0xfffff; address = (address + m_mmu_base[(address & 0xfc00) >> 10]) & 0xfffff;
target_space = &space(spacenum);
return true; return true;
} }

View File

@ -38,7 +38,7 @@ protected:
// device_memory_interface overrides // device_memory_interface overrides
virtual space_config_vector memory_space_config() const override; virtual space_config_vector memory_space_config() const override;
virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
// z80_device overrides // z80_device overrides
virtual u8 rm(u16 addr) override; virtual u8 rm(u16 addr) override;

View File

@ -261,14 +261,16 @@ void cammu_device::set_spaces(address_space &main_space, address_space &io_space
memory.space->cache(memory.cache); memory.space->cache(memory.cache);
} }
bool cammu_device::memory_translate(const u32 ssw, const int spacenum, const int intention, offs_t &address) bool cammu_device::memory_translate(const u32 ssw, const int spacenum, const int intention, offs_t &address, address_space *&target_space)
{ {
// translate the address // translate the address
translated_t translated = translate_address(ssw, address, BYTE, translated_t translated = translate_address(ssw, address, BYTE,
(intention & TRANSLATE_TYPE_MASK) == TRANSLATE_READ ? READ : intention == device_memory_interface::TR_READ ? READ :
(intention & TRANSLATE_TYPE_MASK) == TRANSLATE_WRITE ? WRITE : intention == device_memory_interface::TR_WRITE ? WRITE :
EXECUTE); EXECUTE);
target_space = &translated.cache->space();
// check that the requested space number matches the mapped space // check that the requested space number matches the mapped space
if (translated.cache && translated.cache->space().spacenum() == spacenum) if (translated.cache && translated.cache->space().spacenum() == spacenum)
{ {

View File

@ -193,7 +193,7 @@ public:
} }
// address translation for debugger // address translation for debugger
bool memory_translate(const u32 ssw, const int spacenum, const int intention, offs_t &address); bool memory_translate(const u32 ssw, const int spacenum, const int intention, offs_t &address, address_space *&target_space);
protected: protected:
cammu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); cammu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);

View File

@ -209,8 +209,9 @@ void debug_disasm_buffer::debug_data_buffer::setup_methods()
u16 *dest = get_ptr<u16>(lstart); u16 *dest = get_ptr<u16>(lstart);
for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) { for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) {
offs_t tpc = m_intf.pc_linear_to_real(lpc); offs_t tpc = m_intf.pc_linear_to_real(lpc);
if (m_space->device().memory().translate(m_space->spacenum(), TRANSLATE_FETCH_DEBUG, tpc)) address_space *space;
*dest++ = m_space->read_word(tpc); if (m_space->device().memory().translate(m_space->spacenum(), device_memory_interface::TR_FETCH, tpc, space))
*dest++ = space->read_word(tpc);
else else
*dest++ = 0; *dest++ = 0;
} }
@ -222,8 +223,9 @@ void debug_disasm_buffer::debug_data_buffer::setup_methods()
u8 *dest = get_ptr<u8>(lstart); u8 *dest = get_ptr<u8>(lstart);
for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) { for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) {
offs_t tpc = m_intf.pc_linear_to_real(lpc); offs_t tpc = m_intf.pc_linear_to_real(lpc);
if (m_space->device().memory().translate(m_space->spacenum(), TRANSLATE_FETCH_DEBUG, tpc)) address_space *space;
*dest++ = m_space->read_byte(tpc); if (m_space->device().memory().translate(m_space->spacenum(), device_memory_interface::TR_FETCH, tpc, space))
*dest++ = space->read_byte(tpc);
else else
*dest++ = 0; *dest++ = 0;
} }
@ -239,8 +241,9 @@ void debug_disasm_buffer::debug_data_buffer::setup_methods()
u64 *dest = get_ptr<u64>(lstart); u64 *dest = get_ptr<u64>(lstart);
for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) { for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) {
offs_t tpc = lpc; offs_t tpc = lpc;
if (m_space->device().memory().translate(m_space->spacenum(), TRANSLATE_FETCH_DEBUG, tpc)) address_space *space;
*dest++ = m_space->read_qword(tpc); if (m_space->device().memory().translate(m_space->spacenum(), device_memory_interface::TR_FETCH, tpc, space))
*dest++ = space->read_qword(tpc);
else else
*dest++ = 0; *dest++ = 0;
} }
@ -253,8 +256,9 @@ void debug_disasm_buffer::debug_data_buffer::setup_methods()
u32 *dest = get_ptr<u32>(lstart); u32 *dest = get_ptr<u32>(lstart);
for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) { for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) {
offs_t tpc = lpc; offs_t tpc = lpc;
if (m_space->device().memory().translate(m_space->spacenum(), TRANSLATE_FETCH_DEBUG, tpc)) address_space *space;
*dest++ = m_space->read_dword(tpc); if (m_space->device().memory().translate(m_space->spacenum(), device_memory_interface::TR_FETCH, tpc, space))
*dest++ = space->read_dword(tpc);
else else
*dest++ = 0; *dest++ = 0;
} }
@ -267,8 +271,9 @@ void debug_disasm_buffer::debug_data_buffer::setup_methods()
u16 *dest = get_ptr<u16>(lstart); u16 *dest = get_ptr<u16>(lstart);
for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) { for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) {
offs_t tpc = lpc; offs_t tpc = lpc;
if (m_space->device().memory().translate(m_space->spacenum(), TRANSLATE_FETCH_DEBUG, tpc)) address_space *space;
*dest++ = m_space->read_word(tpc); if (m_space->device().memory().translate(m_space->spacenum(), device_memory_interface::TR_FETCH, tpc, space))
*dest++ = space->read_word(tpc);
else else
*dest++ = 0; *dest++ = 0;
} }
@ -281,8 +286,9 @@ void debug_disasm_buffer::debug_data_buffer::setup_methods()
u8 *dest = get_ptr<u8>(lstart); u8 *dest = get_ptr<u8>(lstart);
for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) { for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) {
offs_t tpc = lpc; offs_t tpc = lpc;
if (m_space->device().memory().translate(m_space->spacenum(), TRANSLATE_FETCH_DEBUG, tpc)) address_space *space;
*dest++ = m_space->read_byte(tpc); if (m_space->device().memory().translate(m_space->spacenum(), device_memory_interface::TR_FETCH, tpc, space))
*dest++ = space->read_byte(tpc);
else else
*dest++ = 0; *dest++ = 0;
} }
@ -295,8 +301,9 @@ void debug_disasm_buffer::debug_data_buffer::setup_methods()
u16 *dest = reinterpret_cast<u16 *>(&m_buffer[0]) + ((lstart - m_lstart) >> 4); u16 *dest = reinterpret_cast<u16 *>(&m_buffer[0]) + ((lstart - m_lstart) >> 4);
for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 0x10) & m_pc_mask) { for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 0x10) & m_pc_mask) {
offs_t tpc = lpc; offs_t tpc = lpc;
if (m_space->device().memory().translate(m_space->spacenum(), TRANSLATE_FETCH_DEBUG, tpc)) address_space *space;
*dest++ = m_space->read_word(tpc); if (m_space->device().memory().translate(m_space->spacenum(), device_memory_interface::TR_FETCH, tpc, space))
*dest++ = space->read_word(tpc);
else else
*dest++ = 0; *dest++ = 0;
} }

View File

@ -53,7 +53,8 @@ const size_t debugger_commands::MAX_GLOBALS = 1000;
bool debugger_commands::cheat_address_is_valid(address_space &space, offs_t address) bool debugger_commands::cheat_address_is_valid(address_space &space, offs_t address)
{ {
return space.device().memory().translate(space.spacenum(), TRANSLATE_READ, address) && (space.get_write_ptr(address) != nullptr); address_space *tspace;
return space.device().memory().translate(space.spacenum(), device_memory_interface::TR_READ, address, tspace) && (tspace->get_write_ptr(address) != nullptr);
} }
@ -104,14 +105,15 @@ u64 debugger_commands::cheat_system::read_extended(offs_t address) const
{ {
address &= space->logaddrmask(); address &= space->logaddrmask();
u64 value = space->unmap(); u64 value = space->unmap();
if (space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, address)) address_space *tspace;
if (space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, address, tspace))
{ {
switch (width) switch (width)
{ {
case 1: value = space->read_byte(address); break; case 1: value = tspace->read_byte(address); break;
case 2: value = space->read_word_unaligned(address); break; case 2: value = tspace->read_word_unaligned(address); break;
case 4: value = space->read_dword_unaligned(address); break; case 4: value = tspace->read_dword_unaligned(address); break;
case 8: value = space->read_qword_unaligned(address); break; case 8: value = tspace->read_qword_unaligned(address); break;
} }
} }
return sign_extend(byte_swap(value)); return sign_extend(byte_swap(value));
@ -2002,8 +2004,9 @@ void debugger_commands::execute_save(int spacenum, const std::vector<std::string
for (u64 i = offset; i != endoffset; i++) for (u64 i = offset; i != endoffset; i++)
{ {
offs_t curaddr = i; offs_t curaddr = i;
u64 data = space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr) ? address_space *tspace;
space->read_qword(curaddr) : space->unmap(); u64 data = space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, curaddr, tspace) ?
tspace->read_qword(curaddr) : space->unmap();
fwrite(&data, 8, 1, f); fwrite(&data, 8, 1, f);
} }
break; break;
@ -2011,8 +2014,9 @@ void debugger_commands::execute_save(int spacenum, const std::vector<std::string
for (u64 i = offset; i != endoffset; i++) for (u64 i = offset; i != endoffset; i++)
{ {
offs_t curaddr = i; offs_t curaddr = i;
u32 data = space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr) ? address_space *tspace;
space->read_dword(curaddr) : space->unmap(); u32 data = space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, curaddr, tspace) ?
tspace->read_dword(curaddr) : space->unmap();
fwrite(&data, 4, 1, f); fwrite(&data, 4, 1, f);
} }
break; break;
@ -2020,8 +2024,9 @@ void debugger_commands::execute_save(int spacenum, const std::vector<std::string
for (u64 i = offset; i != endoffset; i++) for (u64 i = offset; i != endoffset; i++)
{ {
offs_t curaddr = i; offs_t curaddr = i;
u16 data = space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr) ? address_space *tspace;
space->read_word(curaddr) : space->unmap(); u16 data = space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, curaddr, tspace) ?
tspace->read_word(curaddr) : space->unmap();
fwrite(&data, 2, 1, f); fwrite(&data, 2, 1, f);
} }
break; break;
@ -2029,8 +2034,9 @@ void debugger_commands::execute_save(int spacenum, const std::vector<std::string
for (u64 i = offset; i != endoffset; i++) for (u64 i = offset; i != endoffset; i++)
{ {
offs_t curaddr = i; offs_t curaddr = i;
u8 data = space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr) ? address_space *tspace;
space->read_byte(curaddr) : space->unmap(); u8 data = space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, curaddr, tspace) ?
tspace->read_byte(curaddr) : space->unmap();
fwrite(&data, 1, 1, f); fwrite(&data, 1, 1, f);
} }
break; break;
@ -2040,8 +2046,9 @@ void debugger_commands::execute_save(int spacenum, const std::vector<std::string
for (u64 i = offset; i != endoffset; i+=16) for (u64 i = offset; i != endoffset; i+=16)
{ {
offs_t curaddr = i; offs_t curaddr = i;
u16 data = space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr) ? address_space *tspace;
space->read_word(curaddr) : space->unmap(); u16 data = space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, curaddr, tspace) ?
tspace->read_word(curaddr) : space->unmap();
fwrite(&data, 2, 1, f); fwrite(&data, 2, 1, f);
} }
break; break;
@ -2145,8 +2152,9 @@ void debugger_commands::execute_load(int spacenum, const std::vector<std::string
offs_t curaddr = i; offs_t curaddr = i;
u64 data; u64 data;
f.read((char *)&data, 8); f.read((char *)&data, 8);
if (f && space->device().memory().translate(space->spacenum(), TRANSLATE_WRITE_DEBUG, curaddr)) address_space *tspace;
space->write_qword(curaddr, data); if (f && space->device().memory().translate(space->spacenum(), device_memory_interface::TR_WRITE, curaddr, tspace))
tspace->write_qword(curaddr, data);
} }
break; break;
case -2: case -2:
@ -2155,8 +2163,9 @@ void debugger_commands::execute_load(int spacenum, const std::vector<std::string
offs_t curaddr = i; offs_t curaddr = i;
u32 data; u32 data;
f.read((char *)&data, 4); f.read((char *)&data, 4);
if (f && space->device().memory().translate(space->spacenum(), TRANSLATE_WRITE_DEBUG, curaddr)) address_space *tspace;
space->write_dword(curaddr, data); if (f && space->device().memory().translate(space->spacenum(), device_memory_interface::TR_WRITE, curaddr, tspace))
tspace->write_dword(curaddr, data);
} }
break; break;
case -1: case -1:
@ -2165,8 +2174,9 @@ void debugger_commands::execute_load(int spacenum, const std::vector<std::string
offs_t curaddr = i; offs_t curaddr = i;
u16 data; u16 data;
f.read((char *)&data, 2); f.read((char *)&data, 2);
if (f && space->device().memory().translate(space->spacenum(), TRANSLATE_WRITE_DEBUG, curaddr)) address_space *tspace;
space->write_word(curaddr, data); if (f && space->device().memory().translate(space->spacenum(), device_memory_interface::TR_WRITE, curaddr, tspace))
tspace->write_word(curaddr, data);
} }
break; break;
case 0: case 0:
@ -2175,8 +2185,9 @@ void debugger_commands::execute_load(int spacenum, const std::vector<std::string
offs_t curaddr = i; offs_t curaddr = i;
u8 data; u8 data;
f.read((char *)&data, 1); f.read((char *)&data, 1);
if (f && space->device().memory().translate(space->spacenum(), TRANSLATE_WRITE_DEBUG, curaddr)) address_space *tspace;
space->write_byte(curaddr, data); if (f && space->device().memory().translate(space->spacenum(), device_memory_interface::TR_WRITE, curaddr, tspace))
tspace->write_byte(curaddr, data);
} }
break; break;
case 3: case 3:
@ -2187,8 +2198,9 @@ void debugger_commands::execute_load(int spacenum, const std::vector<std::string
offs_t curaddr = i; offs_t curaddr = i;
u16 data; u16 data;
f.read((char *)&data, 2); f.read((char *)&data, 2);
if (f && space->device().memory().translate(space->spacenum(), TRANSLATE_WRITE_DEBUG, curaddr)) address_space *tspace;
space->write_word(curaddr, data); if (f && space->device().memory().translate(space->spacenum(), device_memory_interface::TR_WRITE, curaddr, tspace))
tspace->write_word(curaddr, data);
} }
break; break;
} }
@ -2338,21 +2350,22 @@ void debugger_commands::execute_dump(int spacenum, const std::vector<std::string
if (i + j <= endoffset) if (i + j <= endoffset)
{ {
offs_t curaddr = i + j; offs_t curaddr = i + j;
if (space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr)) address_space *tspace;
if (space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, curaddr, tspace))
{ {
switch (width) switch (width)
{ {
case 8: case 8:
util::stream_format(output, " %016X", space->read_qword_unaligned(i+j)); util::stream_format(output, " %016X", tspace->read_qword_unaligned(i+j));
break; break;
case 4: case 4:
util::stream_format(output, " %08X", space->read_dword_unaligned(i+j)); util::stream_format(output, " %08X", tspace->read_dword_unaligned(i+j));
break; break;
case 2: case 2:
util::stream_format(output, " %04X", space->read_word_unaligned(i+j)); util::stream_format(output, " %04X", tspace->read_word_unaligned(i+j));
break; break;
case 1: case 1:
util::stream_format(output, " %02X", space->read_byte(i+j)); util::stream_format(output, " %02X", tspace->read_byte(i+j));
break; break;
} }
} }
@ -2372,22 +2385,23 @@ void debugger_commands::execute_dump(int spacenum, const std::vector<std::string
for (u64 j = 0; j < rowsize && (i + j) <= endoffset; j += delta) for (u64 j = 0; j < rowsize && (i + j) <= endoffset; j += delta)
{ {
offs_t curaddr = i + j; offs_t curaddr = i + j;
if (space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr)) address_space *tspace;
if (space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, curaddr, tspace))
{ {
u64 data = 0; u64 data = 0;
switch (width) switch (width)
{ {
case 8: case 8:
data = space->read_qword_unaligned(i+j); data = tspace->read_qword_unaligned(i+j);
break; break;
case 4: case 4:
data = space->read_dword_unaligned(i+j); data = tspace->read_dword_unaligned(i+j);
break; break;
case 2: case 2:
data = space->read_word_unaligned(i+j); data = tspace->read_word_unaligned(i+j);
break; break;
case 1: case 1:
data = space->read_byte(i+j); data = tspace->read_byte(i+j);
break; break;
} }
for (unsigned int b = 0; b != width; b++) { for (unsigned int b = 0; b != width; b++) {
@ -2483,28 +2497,29 @@ void debugger_commands::execute_strdump(int spacenum, const std::vector<std::str
// get the character data // get the character data
u64 data = 0; u64 data = 0;
offs_t curaddr = offset; offs_t curaddr = offset;
if (space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr)) address_space *tspace;
if (space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, curaddr, tspace))
{ {
switch (width) switch (width)
{ {
case 1: case 1:
data = space->read_byte(curaddr); data = tspace->read_byte(curaddr);
break; break;
case 2: case 2:
data = space->read_word(curaddr); data = tspace->read_word(curaddr);
if (be) if (be)
data = swapendian_int16(data); data = swapendian_int16(data);
break; break;
case 4: case 4:
data = space->read_dword(curaddr); data = tspace->read_dword(curaddr);
if (be) if (be)
data = swapendian_int32(data); data = swapendian_int32(data);
break; break;
case 8: case 8:
data = space->read_qword(curaddr); data = tspace->read_qword(curaddr);
if (be) if (be)
data = swapendian_int64(data); data = swapendian_int64(data);
break; break;
@ -3158,36 +3173,37 @@ void debugger_commands::execute_find(int spacenum, const std::vector<std::string
for (int j = 0; j < data_count && match; j++) for (int j = 0; j < data_count && match; j++)
{ {
offs_t address = space->byte_to_address(i + suboffset); offs_t address = space->byte_to_address(i + suboffset);
address_space *tspace;
switch (data_size[j]) switch (data_size[j])
{ {
case 1: case 1:
address &= space->logaddrmask(); address &= space->logaddrmask();
if (memory.translate(space->spacenum(), TRANSLATE_READ_DEBUG, address)) if (memory.translate(space->spacenum(), device_memory_interface::TR_READ, address, tspace))
match = space->read_byte(address) == u8(data_to_find[j]); match = tspace->read_byte(address) == u8(data_to_find[j]);
else else
match = false; match = false;
break; break;
case 2: case 2:
address &= space->logaddrmask(); address &= space->logaddrmask();
if (memory.translate(space->spacenum(), TRANSLATE_READ_DEBUG, address)) if (memory.translate(space->spacenum(), device_memory_interface::TR_READ, address, tspace))
match = space->read_word_unaligned(address) == u16(data_to_find[j]); match = tspace->read_word_unaligned(address) == u16(data_to_find[j]);
else else
match = false; match = false;
break; break;
case 4: case 4:
address &= space->logaddrmask(); address &= space->logaddrmask();
if (memory.translate(space->spacenum(), TRANSLATE_READ_DEBUG, address)) if (memory.translate(space->spacenum(), device_memory_interface::TR_READ, address, tspace))
match = space->read_dword_unaligned(address) == u32(data_to_find[j]); match = tspace->read_dword_unaligned(address) == u32(data_to_find[j]);
else else
match = false; match = false;
break; break;
case 8: case 8:
address &= space->logaddrmask(); address &= space->logaddrmask();
if (memory.translate(space->spacenum(), TRANSLATE_READ_DEBUG, address)) if (memory.translate(space->spacenum(), device_memory_interface::TR_READ, address, tspace))
match = space->read_qword_unaligned(address) == u64(data_to_find[j]); match = tspace->read_qword_unaligned(address) == u64(data_to_find[j]);
else else
match = false; match = false;
break; break;
@ -3284,7 +3300,8 @@ void debugger_commands::execute_fill(int spacenum, const std::vector<std::string
for (int j = 0; j < data_count; j++) for (int j = 0; j < data_count; j++)
{ {
offs_t address = space->byte_to_address(offset) & space->logaddrmask(); offs_t address = space->byte_to_address(offset) & space->logaddrmask();
if (!memory.translate(space->spacenum(), TRANSLATE_WRITE_DEBUG, address)) address_space *tspace;
if (!memory.translate(space->spacenum(), device_memory_interface::TR_WRITE, address, tspace))
{ {
m_console.printf("Fill aborted due to page fault at %0*X\n", space->logaddrchars(), space->byte_to_address(offset) & space->logaddrmask()); m_console.printf("Fill aborted due to page fault at %0*X\n", space->logaddrchars(), space->byte_to_address(offset) & space->logaddrmask());
length = 0; length = 0;
@ -3293,19 +3310,19 @@ void debugger_commands::execute_fill(int spacenum, const std::vector<std::string
switch (fill_data_size[j]) switch (fill_data_size[j])
{ {
case 1: case 1:
space->write_byte(address, fill_data[j]); tspace->write_byte(address, fill_data[j]);
break; break;
case 2: case 2:
space->write_word_unaligned(address, fill_data[j]); tspace->write_word_unaligned(address, fill_data[j]);
break; break;
case 4: case 4:
space->write_dword_unaligned(address, fill_data[j]); tspace->write_dword_unaligned(address, fill_data[j]);
break; break;
case 8: case 8:
space->read_qword_unaligned(address, fill_data[j]); tspace->read_qword_unaligned(address, fill_data[j]);
break; break;
} }
offset += fill_data_size[j]; offset += fill_data_size[j];
@ -3654,7 +3671,8 @@ void debugger_commands::execute_pcatmem(int spacenum, const std::vector<std::str
// Translate the address // Translate the address
offs_t a = address & space->logaddrmask(); offs_t a = address & space->logaddrmask();
if (!space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, a)) address_space *tspace;
if (!space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, a, tspace))
{ {
m_console.printf("Address translation failed\n"); m_console.printf("Address translation failed\n");
return; return;
@ -3666,19 +3684,19 @@ void debugger_commands::execute_pcatmem(int spacenum, const std::vector<std::str
switch (space->data_width()) switch (space->data_width())
{ {
case 8: case 8:
data = space->read_byte(a); data = tspace->read_byte(a);
break; break;
case 16: case 16:
data = space->read_word_unaligned(a); data = tspace->read_word_unaligned(a);
break; break;
case 32: case 32:
data = space->read_dword_unaligned(a); data = tspace->read_dword_unaligned(a);
break; break;
case 64: case 64:
data = space->read_qword_unaligned(a); data = tspace->read_qword_unaligned(a);
break; break;
} }
@ -3762,18 +3780,19 @@ void debugger_commands::execute_map(int spacenum, const std::vector<std::string_
return; return;
// do the translation first // do the translation first
for (int intention = TRANSLATE_READ_DEBUG; intention <= TRANSLATE_FETCH_DEBUG; intention++) for (int intention = device_memory_interface::TR_READ; intention <= device_memory_interface::TR_FETCH; intention++)
{ {
static const char *const intnames[] = { "Read", "Write", "Fetch" }; static const char *const intnames[] = { "Read", "Write", "Fetch" };
offs_t taddress = address & space->addrmask(); offs_t taddress = address & space->addrmask();
if (space->device().memory().translate(space->spacenum(), intention, taddress)) address_space *tspace;
if (space->device().memory().translate(space->spacenum(), intention, taddress, tspace))
{ {
std::string mapname = space->get_handler_string((intention == TRANSLATE_WRITE_DEBUG) ? read_or_write::WRITE : read_or_write::READ, taddress); std::string mapname = tspace->get_handler_string((intention == device_memory_interface::TR_WRITE) ? read_or_write::WRITE : read_or_write::READ, taddress);
m_console.printf( m_console.printf(
"%7s: %0*X logical == %0*X physical -> %s\n", "%7s: %0*X logical == %0*X physical -> %s\n",
intnames[intention & 3], intnames[intention & 3],
space->logaddrchars(), address, tspace->logaddrchars(), address,
space->addrchars(), taddress, tspace->addrchars(), taddress,
mapname); mapname);
} }
else else

View File

@ -862,14 +862,15 @@ bool debug_view_memory::read(u8 size, offs_t offs, u64 &data)
auto dis = machine().disable_side_effects(); auto dis = machine().disable_side_effects();
bool ismapped = offs <= m_maxaddr; bool ismapped = offs <= m_maxaddr;
address_space *tspace;
if (ismapped && !m_no_translation) if (ismapped && !m_no_translation)
{ {
offs_t dummyaddr = offs; offs_t dummyaddr = offs;
ismapped = source.m_memintf->translate(source.m_space->spacenum(), TRANSLATE_READ_DEBUG, dummyaddr); ismapped = source.m_memintf->translate(source.m_space->spacenum(), device_memory_interface::TR_READ, dummyaddr, tspace);
} }
data = ~u64(0); data = ~u64(0);
if (ismapped) if (ismapped)
data = m_expression.context().read_memory(*source.m_space, offs, size, !m_no_translation); data = m_expression.context().read_memory(*tspace, offs, size, !m_no_translation);
return ismapped; return ismapped;
} }

View File

@ -482,23 +482,25 @@ u64 symbol_table::read_memory(address_space &space, offs_t address, int size, bo
{ {
u64 result = ~u64(0) >> (64 - 8*size); u64 result = ~u64(0) >> (64 - 8*size);
address_space *tspace = &space;
if (apply_translation) if (apply_translation)
{ {
// mask against the logical byte mask // mask against the logical byte mask
address &= space.logaddrmask(); address &= space.logaddrmask();
// translate if necessary; if not mapped, return 0xffffffffffffffff // translate if necessary; if not mapped, return 0xffffffffffffffff
if (!space.device().memory().translate(space.spacenum(), TRANSLATE_READ_DEBUG, address)) if (!space.device().memory().translate(space.spacenum(), device_memory_interface::TR_READ, address, tspace))
return result; return result;
} }
// otherwise, call the reading function for the translated address // otherwise, call the reading function for the translated address
switch (size) switch (size)
{ {
case 1: result = space.read_byte(address); break; case 1: result = tspace->read_byte(address); break;
case 2: result = space.read_word_unaligned(address); break; case 2: result = tspace->read_word_unaligned(address); break;
case 4: result = space.read_dword_unaligned(address); break; case 4: result = tspace->read_dword_unaligned(address); break;
case 8: result = space.read_qword_unaligned(address); break; case 8: result = tspace->read_qword_unaligned(address); break;
} }
return result; return result;
} }
@ -511,23 +513,25 @@ u64 symbol_table::read_memory(address_space &space, offs_t address, int size, bo
void symbol_table::write_memory(address_space &space, offs_t address, u64 data, int size, bool apply_translation) void symbol_table::write_memory(address_space &space, offs_t address, u64 data, int size, bool apply_translation)
{ {
address_space *tspace = &space;
if (apply_translation) if (apply_translation)
{ {
// mask against the logical byte mask // mask against the logical byte mask
address &= space.logaddrmask(); address &= space.logaddrmask();
// translate if necessary; if not mapped, we're done // translate if necessary; if not mapped, we're done
if (!space.device().memory().translate(space.spacenum(), TRANSLATE_WRITE_DEBUG, address)) if (!space.device().memory().translate(space.spacenum(), device_memory_interface::TR_WRITE, address, tspace))
return; return;
} }
// otherwise, call the writing function for the translated address // otherwise, call the writing function for the translated address
switch (size) switch (size)
{ {
case 1: space.write_byte(address, data); break; case 1: tspace->write_byte(address, data); break;
case 2: space.write_word_unaligned(address, data); break; case 2: tspace->write_word_unaligned(address, data); break;
case 4: space.write_dword_unaligned(address, data); break; case 4: tspace->write_dword_unaligned(address, data); break;
case 8: space.write_qword_unaligned(address, data); break; case 8: tspace->write_qword_unaligned(address, data); break;
} }
notify_memory_modified(); notify_memory_modified();

View File

@ -66,9 +66,10 @@ void device_memory_interface::set_addrmap(int spacenum, address_map_constructor
// translation is supported // translation is supported
//------------------------------------------------- //-------------------------------------------------
bool device_memory_interface::memory_translate(int spacenum, int intention, offs_t &address) bool device_memory_interface::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{ {
// by default it maps directly // by default it maps directly
target_space = &space(spacenum);
return true; return true;
} }

View File

@ -19,34 +19,6 @@
#include <type_traits> #include <type_traits>
//**************************************************************************
// CONSTANTS
//**************************************************************************
// Translation intentions
constexpr int TRANSLATE_TYPE_MASK = 0x03; // read write or fetch
constexpr int TRANSLATE_USER_MASK = 0x04; // user mode or fully privileged
constexpr int TRANSLATE_DEBUG_MASK = 0x08; // debug mode (no side effects)
constexpr int TRANSLATE_READ = 0; // translate for read
constexpr int TRANSLATE_WRITE = 1; // translate for write
constexpr int TRANSLATE_FETCH = 2; // translate for instruction fetch
constexpr int TRANSLATE_READ_USER = (TRANSLATE_READ | TRANSLATE_USER_MASK);
constexpr int TRANSLATE_WRITE_USER = (TRANSLATE_WRITE | TRANSLATE_USER_MASK);
constexpr int TRANSLATE_FETCH_USER = (TRANSLATE_FETCH | TRANSLATE_USER_MASK);
constexpr int TRANSLATE_READ_DEBUG = (TRANSLATE_READ | TRANSLATE_DEBUG_MASK);
constexpr int TRANSLATE_WRITE_DEBUG = (TRANSLATE_WRITE | TRANSLATE_DEBUG_MASK);
constexpr int TRANSLATE_FETCH_DEBUG = (TRANSLATE_FETCH | TRANSLATE_DEBUG_MASK);
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> device_memory_interface
class device_memory_interface : public device_interface class device_memory_interface : public device_interface
{ {
friend class device_scheduler; friend class device_scheduler;
@ -57,6 +29,13 @@ class device_memory_interface : public device_interface
template <typename T, typename U> using is_unrelated_interface = std::bool_constant<emu::detail::is_device_interface<T>::value && !is_related_class<T, U>::value >; template <typename T, typename U> using is_unrelated_interface = std::bool_constant<emu::detail::is_device_interface<T>::value && !is_related_class<T, U>::value >;
public: public:
// Translation intentions for the translate() call
enum {
TR_READ,
TR_WRITE,
TR_FETCH
};
// construction/destruction // construction/destruction
device_memory_interface(const machine_config &mconfig, device_t &device); device_memory_interface(const machine_config &mconfig, device_t &device);
virtual ~device_memory_interface(); virtual ~device_memory_interface();
@ -85,7 +64,7 @@ public:
address_space &space(int index = 0) const { assert(index >= 0 && index < int(m_addrspace.size()) && m_addrspace[index]); return *m_addrspace[index]; } address_space &space(int index = 0) const { assert(index >= 0 && index < int(m_addrspace.size()) && m_addrspace[index]); return *m_addrspace[index]; }
// address translation // address translation
bool translate(int spacenum, int intention, offs_t &address) { return memory_translate(spacenum, intention, address); } bool translate(int spacenum, int intention, offs_t &address, address_space *&target_space) { return memory_translate(spacenum, intention, address, target_space); }
// deliberately ambiguous functions; if you have the memory interface // deliberately ambiguous functions; if you have the memory interface
// just use it // just use it
@ -110,7 +89,7 @@ protected:
virtual space_config_vector memory_space_config() const = 0; virtual space_config_vector memory_space_config() const = 0;
// optional operation overrides // optional operation overrides
virtual bool memory_translate(int spacenum, int intention, offs_t &address); virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space);
// interface-level overrides // interface-level overrides
virtual void interface_config_complete() override; virtual void interface_config_complete() override;

View File

@ -68,7 +68,7 @@ void device_vtlb_interface::interface_validity_check(validity_checker &valid) co
const address_space_config *spaceconfig = intf->space_config(m_space); const address_space_config *spaceconfig = intf->space_config(m_space);
if (spaceconfig == nullptr) if (spaceconfig == nullptr)
osd_printf_error("No memory address space configuration found for space %d\n", m_space); osd_printf_error("No memory address space configuration found for space %d\n", m_space);
else if ((1 << spaceconfig->page_shift()) <= VTLB_FLAGS_MASK || spaceconfig->logaddr_width() <= spaceconfig->page_shift()) else if ((1 << spaceconfig->page_shift()) <= FLAGS_MASK || spaceconfig->logaddr_width() <= spaceconfig->page_shift())
osd_printf_error("Invalid page shift %d for VTLB\n", spaceconfig->page_shift()); osd_printf_error("Invalid page shift %d for VTLB\n", spaceconfig->page_shift());
} }
} }
@ -142,11 +142,10 @@ void device_vtlb_interface::interface_pre_reset()
// response to an unmapped access // response to an unmapped access
//------------------------------------------------- //-------------------------------------------------
bool device_vtlb_interface::vtlb_fill(offs_t address, int intention) bool device_vtlb_interface::vtlb_fill(offs_t address, offs_t taddress, int intention)
{ {
offs_t tableindex = address >> m_pageshift; offs_t tableindex = address >> m_pageshift;
vtlb_entry entry = m_table[tableindex]; vtlb_entry entry = m_table[tableindex];
offs_t taddress;
#if PRINTF_TLB #if PRINTF_TLB
osd_printf_debug("vtlb_fill: %08X(%X) ... ", address, intention); osd_printf_debug("vtlb_fill: %08X(%X) ... ", address, intention);
@ -164,18 +163,8 @@ bool device_vtlb_interface::vtlb_fill(offs_t address, int intention)
return false; return false;
} }
// ask the CPU core to translate for us
taddress = address;
if (!device().memory().translate(m_space, intention, taddress))
{
#if PRINTF_TLB
osd_printf_debug("failed: no translation\n");
#endif
return false;
}
// if this is the first successful translation for this address, allocate a new entry // if this is the first successful translation for this address, allocate a new entry
if ((entry & VTLB_FLAGS_MASK) == 0) if ((entry & FLAGS_MASK) == 0)
{ {
int liveindex = m_dynindex; int liveindex = m_dynindex;
@ -196,7 +185,7 @@ bool device_vtlb_interface::vtlb_fill(offs_t address, int intention)
// form a new blank entry // form a new blank entry
entry = (taddress >> m_pageshift) << m_pageshift; entry = (taddress >> m_pageshift) << m_pageshift;
entry |= VTLB_FLAG_VALID; entry |= FLAG_VALID;
#if PRINTF_TLB #if PRINTF_TLB
osd_printf_debug("success (%08X), new entry\n", taddress); osd_printf_debug("success (%08X), new entry\n", taddress);
@ -207,7 +196,7 @@ bool device_vtlb_interface::vtlb_fill(offs_t address, int intention)
else else
{ {
assert((entry >> m_pageshift) == (taddress >> m_pageshift)); assert((entry >> m_pageshift) == (taddress >> m_pageshift));
assert(entry & VTLB_FLAG_VALID); assert(entry & FLAG_VALID);
#if PRINTF_TLB #if PRINTF_TLB
osd_printf_debug("success (%08X), existing entry\n", taddress); osd_printf_debug("success (%08X), existing entry\n", taddress);
@ -215,7 +204,7 @@ bool device_vtlb_interface::vtlb_fill(offs_t address, int intention)
} }
// add the intention to the list of valid intentions and store // add the intention to the list of valid intentions and store
entry |= 1 << (intention & (TRANSLATE_TYPE_MASK | TRANSLATE_USER_MASK)); entry |= 1 << intention;
m_table[tableindex] = entry; m_table[tableindex] = entry;
return true; return true;
} }
@ -256,7 +245,7 @@ void device_vtlb_interface::vtlb_load(int entrynum, int numpages, offs_t address
m_refcnt[tableindex]++; m_refcnt[tableindex]++;
// store the raw value, making sure the "fixed" flag is set // store the raw value, making sure the "fixed" flag is set
value |= VTLB_FLAG_FIXED; value |= FLAG_FIXED;
m_fixedpages[entrynum] = numpages; m_fixedpages[entrynum] = numpages;
for (pagenum = 0; pagenum < numpages; pagenum++) for (pagenum = 0; pagenum < numpages; pagenum++)
m_table[tableindex + pagenum] = value + (pagenum << m_pageshift); m_table[tableindex + pagenum] = value + (pagenum << m_pageshift);
@ -283,7 +272,7 @@ void device_vtlb_interface::vtlb_dynload(u32 index, offs_t address, vtlb_entry v
m_dynindex = (m_dynindex + 1) % m_dynamic; m_dynindex = (m_dynindex + 1) % m_dynamic;
// is entry already live? // is entry already live?
if (!(entry & VTLB_FLAG_VALID)) if (!(entry & FLAG_VALID))
{ {
// if an entry already exists at this index, free it // if an entry already exists at this index, free it
if (m_live[liveindex] != 0) if (m_live[liveindex] != 0)
@ -294,7 +283,7 @@ void device_vtlb_interface::vtlb_dynload(u32 index, offs_t address, vtlb_entry v
} }
// form a new blank entry // form a new blank entry
entry = (address >> m_pageshift) << m_pageshift; entry = (address >> m_pageshift) << m_pageshift;
entry |= VTLB_FLAG_VALID | value; entry |= FLAG_VALID | value;
#if PRINTF_TLB #if PRINTF_TLB
osd_printf_debug("success (%08X), new entry\n", address); osd_printf_debug("success (%08X), new entry\n", address);
@ -356,7 +345,7 @@ void device_vtlb_interface::vtlb_flush_address(offs_t address)
// the linear VTLB lookup table // the linear VTLB lookup table
//------------------------------------------------- //-------------------------------------------------
const vtlb_entry *device_vtlb_interface::vtlb_table() const const device_vtlb_interface::vtlb_entry *device_vtlb_interface::vtlb_table() const
{ {
return m_table_base; return m_table_base;
} }

View File

@ -13,38 +13,35 @@
#pragma once #pragma once
/***************************************************************************
CONSTANTS
***************************************************************************/
constexpr u32 VTLB_FLAGS_MASK = 0xff;
constexpr u32 VTLB_READ_ALLOWED = 0x01; /* (1 << TRANSLATE_READ) */
constexpr u32 VTLB_WRITE_ALLOWED = 0x02; /* (1 << TRANSLATE_WRITE) */
constexpr u32 VTLB_FETCH_ALLOWED = 0x04; /* (1 << TRANSLATE_FETCH) */
constexpr u32 VTLB_FLAG_VALID = 0x08;
constexpr u32 VTLB_USER_READ_ALLOWED = 0x10; /* (1 << TRANSLATE_READ_USER) */
constexpr u32 VTLB_USER_WRITE_ALLOWED = 0x20; /* (1 << TRANSLATE_WRITE_USER) */
constexpr u32 VTLB_USER_FETCH_ALLOWED = 0x40; /* (1 << TRANSLATE_FETCH_USER) */
constexpr u32 VTLB_FLAG_FIXED = 0x80;
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
/* represents an entry in the VTLB */
typedef u32 vtlb_entry;
// ======================> device_vtlb_interface
class device_vtlb_interface : public device_interface class device_vtlb_interface : public device_interface
{ {
public: public:
using vtlb_entry = u32;
// Translation type flags
// TR_READ/WRITE/FETCH come from device_memory_interface
enum {
TR_UREAD = 4,
TR_UWRITE = 5,
TR_UFETCH = 6,
TR_TYPE = 3,
TR_USER = 4
};
enum {
FLAGS_MASK = 0xff,
READ_ALLOWED = 0x01, /* (1 << TR_READ) */
WRITE_ALLOWED = 0x02, /* (1 << TR_WRITE) */
FETCH_ALLOWED = 0x04, /* (1 << TR_FETCH) */
FLAG_VALID = 0x08,
USER_READ_ALLOWED = 0x10, /* (1 << TR_UREAD) */
USER_WRITE_ALLOWED = 0x20, /* (1 << TR_UWRITE) */
USER_FETCH_ALLOWED = 0x40, /* (1 << TR_UFETCH) */
FLAG_FIXED = 0x80
};
// construction/destruction // construction/destruction
device_vtlb_interface(const machine_config &mconfig, device_t &device, int space); device_vtlb_interface(const machine_config &mconfig, device_t &device, int space);
virtual ~device_vtlb_interface(); virtual ~device_vtlb_interface();
@ -54,7 +51,7 @@ public:
void set_vtlb_fixed_entries(int entries) { m_fixed = entries; } void set_vtlb_fixed_entries(int entries) { m_fixed = entries; }
// filling // filling
bool vtlb_fill(offs_t address, int intention); bool vtlb_fill(offs_t address, offs_t taddress, int intention);
void vtlb_load(int entrynum, int numpages, offs_t address, vtlb_entry value); void vtlb_load(int entrynum, int numpages, offs_t address, vtlb_entry value);
void vtlb_dynload(u32 index, offs_t address, vtlb_entry value); void vtlb_dynload(u32 index, offs_t address, vtlb_entry value);

View File

@ -394,32 +394,33 @@ void lua_engine::addr_space::mem_write(offs_t address, T val)
template <typename T> template <typename T>
T lua_engine::addr_space::log_mem_read(offs_t address) T lua_engine::addr_space::log_mem_read(offs_t address)
{ {
if (!dev.translate(space.spacenum(), TRANSLATE_READ_DEBUG, address)) address_space *tspace;
if (!dev.translate(space.spacenum(), device_memory_interface::TR_READ, address, tspace))
return 0; return 0;
T mem_content = 0; T mem_content = 0;
switch (sizeof(mem_content) * 8) switch (sizeof(mem_content) * 8)
{ {
case 8: case 8:
mem_content = space.read_byte(address); mem_content = tspace->read_byte(address);
break; break;
case 16: case 16:
if (WORD_ALIGNED(address)) if (WORD_ALIGNED(address))
mem_content = space.read_word(address); mem_content = tspace->read_word(address);
else else
mem_content = space.read_word_unaligned(address); mem_content = tspace->read_word_unaligned(address);
break; break;
case 32: case 32:
if (DWORD_ALIGNED(address)) if (DWORD_ALIGNED(address))
mem_content = space.read_dword(address); mem_content = tspace->read_dword(address);
else else
mem_content = space.read_dword_unaligned(address); mem_content = tspace->read_dword_unaligned(address);
break; break;
case 64: case 64:
if (QWORD_ALIGNED(address)) if (QWORD_ALIGNED(address))
mem_content = space.read_qword(address); mem_content = tspace->read_qword(address);
else else
mem_content = space.read_qword_unaligned(address); mem_content = tspace->read_qword_unaligned(address);
break; break;
default: default:
break; break;
@ -436,31 +437,32 @@ T lua_engine::addr_space::log_mem_read(offs_t address)
template <typename T> template <typename T>
void lua_engine::addr_space::log_mem_write(offs_t address, T val) void lua_engine::addr_space::log_mem_write(offs_t address, T val)
{ {
if (!dev.translate(space.spacenum(), TRANSLATE_WRITE_DEBUG, address)) address_space *tspace;
if (!dev.translate(space.spacenum(), device_memory_interface::TR_WRITE, address, tspace))
return; return;
switch (sizeof(val) * 8) switch (sizeof(val) * 8)
{ {
case 8: case 8:
space.write_byte(address, val); tspace->write_byte(address, val);
break; break;
case 16: case 16:
if (WORD_ALIGNED(address)) if (WORD_ALIGNED(address))
space.write_word(address, val); tspace->write_word(address, val);
else else
space.write_word_unaligned(address, val); tspace->write_word_unaligned(address, val);
break; break;
case 32: case 32:
if (DWORD_ALIGNED(address)) if (DWORD_ALIGNED(address))
space.write_dword(address, val); tspace->write_dword(address, val);
else else
space.write_dword_unaligned(address, val); tspace->write_dword_unaligned(address, val);
break; break;
case 64: case 64:
if (QWORD_ALIGNED(address)) if (QWORD_ALIGNED(address))
space.write_qword(address, val); tspace->write_qword(address, val);
else else
space.write_qword_unaligned(address, val); tspace->write_qword_unaligned(address, val);
break; break;
default: default:
break; break;

View File

@ -282,17 +282,18 @@ void macpdm_state::driver_init()
m_maincpu->space().install_read_tap(0x4000c2e0, 0x4000c2e7, 0, "cuda", [this](offs_t offset, u64 &data, u64 mem_mask) { m_maincpu->space().install_read_tap(0x4000c2e0, 0x4000c2e7, 0, "cuda", [this](offs_t offset, u64 &data, u64 mem_mask) {
if(mem_mask == 0xffff000000000000) { if(mem_mask == 0xffff000000000000) {
address_space *space;
offs_t badr = m_maincpu->state_int(PPC_R16); offs_t badr = m_maincpu->state_int(PPC_R16);
m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, badr); m_maincpu->translate(AS_PROGRAM, device_memory_interface::TR_READ, badr, space);
logerror("cuda packet %08x : type %02x cmd %02x - %02x %02x %02x %02x bytecnt %04x\n", logerror("cuda packet %08x : type %02x cmd %02x - %02x %02x %02x %02x bytecnt %04x\n",
badr, badr,
m_maincpu->space().read_byte(badr), space->read_byte(badr),
m_maincpu->space().read_byte(badr+1), space->read_byte(badr+1),
m_maincpu->space().read_byte(badr+2), space->read_byte(badr+2),
m_maincpu->space().read_byte(badr+3), space->read_byte(badr+3),
m_maincpu->space().read_byte(badr+4), space->read_byte(badr+4),
m_maincpu->space().read_byte(badr+5), space->read_byte(badr+5),
m_maincpu->space().read_word(badr+6)); space->read_word(badr+6));
} }
}); });
} }

View File

@ -121,7 +121,7 @@ protected:
// device_memory_interface overrides // device_memory_interface overrides
virtual space_config_vector memory_space_config() const override; virtual space_config_vector memory_space_config() const override;
//virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; //virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
template <typename T> bool mem_load(u32 address, T &data, rsc_mode const mode); template <typename T> bool mem_load(u32 address, T &data, rsc_mode const mode);
template <typename T> bool mem_store(u32 address, T data, rsc_mode const mode); template <typename T> bool mem_store(u32 address, T data, rsc_mode const mode);

View File

@ -1545,7 +1545,6 @@ void konamim2_state::dump_task_command(const std::vector<std::string_view> &para
}; };
debugger_console &con = machine().debugger().console(); debugger_console &con = machine().debugger().console();
address_space &space = m_ppc1->space();
uint64_t addr; uint64_t addr;
offs_t address; offs_t address;
@ -1557,7 +1556,8 @@ void konamim2_state::dump_task_command(const std::vector<std::string_view> &para
address = (offs_t)addr; address = (offs_t)addr;
address = 0x40FB54E8; address = 0x40FB54E8;
if (!m_ppc1->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) address_space *tspace;
if (!m_ppc1->translate(AS_PROGRAM, device_memory_interface::TR_READ, address, tspace))
{ {
con.printf("Address is unmapped.\n"); con.printf("Address is unmapped.\n");
return; return;
@ -1565,14 +1565,14 @@ void konamim2_state::dump_task_command(const std::vector<std::string_view> &para
Task task; Task task;
task.t.pn_Next = space.read_dword(address + offsetof(ItemNode, pn_Next)); task.t.pn_Next = tspace->read_dword(address + offsetof(ItemNode, pn_Next));
task.t.pn_Prev = space.read_dword(address + offsetof(ItemNode, pn_Prev)); task.t.pn_Prev = tspace->read_dword(address + offsetof(ItemNode, pn_Prev));
task.t.n_SubsysType = space.read_byte(address + offsetof(ItemNode, n_SubsysType)); task.t.n_SubsysType = tspace->read_byte(address + offsetof(ItemNode, n_SubsysType));
task.t.n_Type = space.read_byte(address + offsetof(ItemNode, n_Type)); task.t.n_Type = tspace->read_byte(address + offsetof(ItemNode, n_Type));
task.t.n_Priority = space.read_byte(address + offsetof(ItemNode, n_Priority)); task.t.n_Priority = tspace->read_byte(address + offsetof(ItemNode, n_Priority));
task.t.n_Flags = space.read_byte(address + offsetof(ItemNode, n_Flags)); task.t.n_Flags = tspace->read_byte(address + offsetof(ItemNode, n_Flags));
task.t.n_Size = space.read_dword(address + offsetof(ItemNode, n_Size)); task.t.n_Size = tspace->read_dword(address + offsetof(ItemNode, n_Size));
task.t.pn_Name = space.read_dword(address + offsetof(ItemNode, pn_Name)); task.t.pn_Name = tspace->read_dword(address + offsetof(ItemNode, pn_Name));
char name[128]; char name[128];
char *ptr = name; char *ptr = name;
@ -1580,31 +1580,31 @@ void konamim2_state::dump_task_command(const std::vector<std::string_view> &para
do do
{ {
*ptr = space.read_byte(nameptr++); *ptr = tspace->read_byte(nameptr++);
} while (*ptr++ != 0); } while (*ptr++ != 0);
task.t.n_Version = space.read_byte(address + offsetof(ItemNode, n_Version)); task.t.n_Version = tspace->read_byte(address + offsetof(ItemNode, n_Version));
task.t.n_Revision = space.read_byte(address + offsetof(ItemNode, n_Revision)); task.t.n_Revision = tspace->read_byte(address + offsetof(ItemNode, n_Revision));
task.t.n_Reserved0 = space.read_byte(address + offsetof(ItemNode, n_Reserved0)); task.t.n_Reserved0 = tspace->read_byte(address + offsetof(ItemNode, n_Reserved0));
task.t.n_ItemFlags = space.read_byte(address + offsetof(ItemNode, n_ItemFlags)); task.t.n_ItemFlags = tspace->read_byte(address + offsetof(ItemNode, n_ItemFlags));
task.t.n_Item = space.read_dword(address + offsetof(ItemNode, n_Item)); task.t.n_Item = tspace->read_dword(address + offsetof(ItemNode, n_Item));
task.t.n_Owner = space.read_dword(address + offsetof(ItemNode, n_Owner)); task.t.n_Owner = tspace->read_dword(address + offsetof(ItemNode, n_Owner));
task.t.pn_Reserved1 = space.read_dword(address + offsetof(ItemNode, pn_Reserved1)); task.t.pn_Reserved1 = tspace->read_dword(address + offsetof(ItemNode, pn_Reserved1));
task.pt_ThreadTask = space.read_dword(address + offsetof(Task, pt_ThreadTask)); task.pt_ThreadTask = tspace->read_dword(address + offsetof(Task, pt_ThreadTask));
task.t_WaitBits = space.read_dword(address + offsetof(Task, t_WaitBits)); task.t_WaitBits = tspace->read_dword(address + offsetof(Task, t_WaitBits));
task.t_SigBits = space.read_dword(address + offsetof(Task, t_SigBits)); task.t_SigBits = tspace->read_dword(address + offsetof(Task, t_SigBits));
task.t_AllocatedSigs = space.read_dword(address + offsetof(Task, t_AllocatedSigs)); task.t_AllocatedSigs = tspace->read_dword(address + offsetof(Task, t_AllocatedSigs));
task.pt_StackBase = space.read_dword(address + offsetof(Task, pt_StackBase)); task.pt_StackBase = tspace->read_dword(address + offsetof(Task, pt_StackBase));
task.t_StackSize = space.read_dword(address + offsetof(Task, t_StackSize)); task.t_StackSize = tspace->read_dword(address + offsetof(Task, t_StackSize));
task.t_MaxUSecs = space.read_dword(address + offsetof(Task, t_MaxUSecs)); task.t_MaxUSecs = tspace->read_dword(address + offsetof(Task, t_MaxUSecs));
task.t_ElapsedTime.tt_Hi = space.read_dword(address + offsetof(Task, t_ElapsedTime)+0); task.t_ElapsedTime.tt_Hi = tspace->read_dword(address + offsetof(Task, t_ElapsedTime)+0);
task.t_ElapsedTime.tt_Lo = space.read_dword(address + offsetof(Task, t_ElapsedTime)+4); task.t_ElapsedTime.tt_Lo = tspace->read_dword(address + offsetof(Task, t_ElapsedTime)+4);
task.t_NumTaskLaunch = space.read_dword(address + offsetof(Task, t_NumTaskLaunch)); task.t_NumTaskLaunch = tspace->read_dword(address + offsetof(Task, t_NumTaskLaunch));
task.t_Flags = space.read_dword(address + offsetof(Task, t_Flags)); task.t_Flags = tspace->read_dword(address + offsetof(Task, t_Flags));
task.t_Module = space.read_dword(address + offsetof(Task, t_Module)); task.t_Module = tspace->read_dword(address + offsetof(Task, t_Module));
task.t_DefaultMsgPort = space.read_dword(address + offsetof(Task, t_DefaultMsgPort)); task.t_DefaultMsgPort = tspace->read_dword(address + offsetof(Task, t_DefaultMsgPort));
task.pt_UserData = space.read_dword(address + offsetof(Task, pt_UserData)); task.pt_UserData = tspace->read_dword(address + offsetof(Task, pt_UserData));
// m2ptr pt_ThreadTask; /* I am a thread of what task? */ // m2ptr pt_ThreadTask; /* I am a thread of what task? */
// uint32_t t_WaitBits; /* signals being waited for */ // uint32_t t_WaitBits; /* signals being waited for */

View File

@ -41,7 +41,7 @@ protected:
// device_memory_interface overrides // device_memory_interface overrides
virtual space_config_vector memory_space_config() const override; virtual space_config_vector memory_space_config() const override;
//virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; //virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override;
u32 dma_r(offs_t offset, u32 mem_mask); u32 dma_r(offs_t offset, u32 mem_mask);
void dma_w(offs_t offset, u32 data, u32 mem_mask); void dma_w(offs_t offset, u32 data, u32 mem_mask);

View File

@ -687,7 +687,8 @@ void chihiro_state::jamtable_disasm(address_space &space, uint32_t address, uint
{ {
debugger_console &con = machine().debugger().console(); debugger_console &con = machine().debugger().console();
offs_t addr = (offs_t)address; offs_t addr = (offs_t)address;
if (!space.device().memory().translate(space.spacenum(), TRANSLATE_READ_DEBUG, addr)) address_space *tspace;
if (!space.device().memory().translate(space.spacenum(), device_memory_interface::TR_READ, addr, tspace))
{ {
con.printf("Address is unmapped.\n"); con.printf("Address is unmapped.\n");
return; return;
@ -696,11 +697,11 @@ void chihiro_state::jamtable_disasm(address_space &space, uint32_t address, uint
{ {
offs_t base = addr; offs_t base = addr;
uint32_t opcode = space.read_byte(addr); uint32_t opcode = tspace->read_byte(addr);
addr++; addr++;
uint32_t op1 = space.read_dword_unaligned(addr); uint32_t op1 = tspace->read_dword_unaligned(addr);
addr += 4; addr += 4;
uint32_t op2 = space.read_dword_unaligned(addr); uint32_t op2 = tspace->read_dword_unaligned(addr);
addr += 4; addr += 4;
std::string sop1; std::string sop1;

View File

@ -86,7 +86,6 @@ void xbox_base_state::find_debug_params()
void xbox_base_state::dump_string_command(const std::vector<std::string_view> &params) void xbox_base_state::dump_string_command(const std::vector<std::string_view> &params)
{ {
debugger_console &con = machine().debugger().console(); debugger_console &con = machine().debugger().console();
address_space &space = m_maincpu->space();
uint64_t addr; uint64_t addr;
offs_t address; offs_t address;
@ -97,15 +96,16 @@ void xbox_base_state::dump_string_command(const std::vector<std::string_view> &p
return; return;
address = (offs_t)addr; address = (offs_t)addr;
if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) address_space *tspace;
if (!m_maincpu->translate(AS_PROGRAM, device_memory_interface::TR_READ, address, tspace))
{ {
con.printf("Address is unmapped.\n"); con.printf("Address is unmapped.\n");
return; return;
} }
uint32_t length = space.read_word_unaligned(address); uint32_t length = tspace->read_word_unaligned(address);
uint32_t maximumlength = space.read_word_unaligned(address + 2); uint32_t maximumlength = tspace->read_word_unaligned(address + 2);
offs_t buffer = space.read_dword_unaligned(address + 4); offs_t buffer = tspace->read_dword_unaligned(address + 4);
con.printf("Length %d word\n", length); con.printf("Length %d word\n", length);
con.printf("MaximumLength %d word\n", maximumlength); con.printf("MaximumLength %d word\n", maximumlength);
con.printf("Buffer %08X byte* ", buffer); con.printf("Buffer %08X byte* ", buffer);
@ -114,11 +114,11 @@ void xbox_base_state::dump_string_command(const std::vector<std::string_view> &p
if (length > 256) if (length > 256)
length = 256; length = 256;
if (m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, buffer)) if (m_maincpu->translate(AS_PROGRAM, device_memory_interface::TR_READ, buffer, tspace))
{ {
for (int a = 0; a < length; a++) for (int a = 0; a < length; a++)
{ {
uint8_t c = space.read_byte(buffer + a); uint8_t c = tspace->read_byte(buffer + a);
con.printf("%c", c); con.printf("%c", c);
} }
} }
@ -128,7 +128,6 @@ void xbox_base_state::dump_string_command(const std::vector<std::string_view> &p
void xbox_base_state::dump_process_command(const std::vector<std::string_view> &params) void xbox_base_state::dump_process_command(const std::vector<std::string_view> &params)
{ {
debugger_console &con = machine().debugger().console(); debugger_console &con = machine().debugger().console();
address_space &space = m_maincpu->space();
uint64_t addr; uint64_t addr;
offs_t address; offs_t address;
@ -139,26 +138,26 @@ void xbox_base_state::dump_process_command(const std::vector<std::string_view> &
return; return;
address = (offs_t)addr; address = (offs_t)addr;
if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) address_space *tspace;
if (!m_maincpu->translate(AS_PROGRAM, device_memory_interface::TR_READ, address, tspace))
{ {
con.printf("Address is unmapped.\n"); con.printf("Address is unmapped.\n");
return; return;
} }
con.printf("ReadyListHead {%08X,%08X} _LIST_ENTRY\n", space.read_dword(address), space.read_dword_unaligned(address + 4)); con.printf("ReadyListHead {%08X,%08X} _LIST_ENTRY\n", tspace->read_dword(address), tspace->read_dword_unaligned(address + 4));
con.printf("ThreadListHead {%08X,%08X} _LIST_ENTRY\n", space.read_dword(address + 8), space.read_dword_unaligned(address + 12)); con.printf("ThreadListHead {%08X,%08X} _LIST_ENTRY\n", tspace->read_dword(address + 8), tspace->read_dword_unaligned(address + 12));
con.printf("StackCount %d dword\n", space.read_dword_unaligned(address + 16)); con.printf("StackCount %d dword\n", tspace->read_dword_unaligned(address + 16));
con.printf("ThreadQuantum %d dword\n", space.read_dword_unaligned(address + 20)); con.printf("ThreadQuantum %d dword\n", tspace->read_dword_unaligned(address + 20));
con.printf("BasePriority %d byte\n", space.read_byte(address + 24)); con.printf("BasePriority %d byte\n", tspace->read_byte(address + 24));
con.printf("DisableBoost %d byte\n", space.read_byte(address + 25)); con.printf("DisableBoost %d byte\n", tspace->read_byte(address + 25));
con.printf("DisableQuantum %d byte\n", space.read_byte(address + 26)); con.printf("DisableQuantum %d byte\n", tspace->read_byte(address + 26));
con.printf("_padding %d byte\n", space.read_byte(address + 27)); con.printf("_padding %d byte\n", tspace->read_byte(address + 27));
} }
void xbox_base_state::dump_list_command(const std::vector<std::string_view> &params) void xbox_base_state::dump_list_command(const std::vector<std::string_view> &params)
{ {
debugger_console &con = machine().debugger().console(); debugger_console &con = machine().debugger().console();
address_space &space = m_maincpu->space();
uint64_t addr; uint64_t addr;
offs_t address; offs_t address;
@ -178,8 +177,9 @@ void xbox_base_state::dump_list_command(const std::vector<std::string_view> &par
} }
uint64_t start = addr; uint64_t start = addr;
address_space *tspace;
address = (offs_t)addr; address = (offs_t)addr;
if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) if (!m_maincpu->translate(AS_PROGRAM, device_memory_interface::TR_READ, address, tspace))
{ {
con.printf("Address is unmapped.\n"); con.printf("Address is unmapped.\n");
return; return;
@ -197,13 +197,13 @@ void xbox_base_state::dump_list_command(const std::vector<std::string_view> &par
else else
con.printf("%08X\n", (uint32_t)addr); con.printf("%08X\n", (uint32_t)addr);
old = addr; old = addr;
addr = space.read_dword_unaligned(address); addr = tspace->read_dword_unaligned(address);
if (addr == start) if (addr == start)
break; break;
if (addr == old) if (addr == old)
break; break;
address = (offs_t)addr; address = (offs_t)addr;
if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) if (!m_maincpu->translate(AS_PROGRAM, device_memory_interface::TR_READ, address, tspace))
break; break;
} }
} }
@ -211,9 +211,9 @@ void xbox_base_state::dump_list_command(const std::vector<std::string_view> &par
void xbox_base_state::dump_dpc_command(const std::vector<std::string_view> &params) void xbox_base_state::dump_dpc_command(const std::vector<std::string_view> &params)
{ {
debugger_console &con = machine().debugger().console(); debugger_console &con = machine().debugger().console();
address_space &space = m_maincpu->space();
uint64_t addr; uint64_t addr;
offs_t address; offs_t address;
address_space *tspace;
if (params.size() < 2) if (params.size() < 2)
return; return;
@ -222,25 +222,24 @@ void xbox_base_state::dump_dpc_command(const std::vector<std::string_view> &para
return; return;
address = (offs_t)addr; address = (offs_t)addr;
if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) if (!m_maincpu->translate(AS_PROGRAM, device_memory_interface::TR_READ, address, tspace))
{ {
con.printf("Address is unmapped.\n"); con.printf("Address is unmapped.\n");
return; return;
} }
con.printf("Type %d word\n", space.read_word_unaligned(address)); con.printf("Type %d word\n", tspace->read_word_unaligned(address));
con.printf("Inserted %d byte\n", space.read_byte(address + 2)); con.printf("Inserted %d byte\n", tspace->read_byte(address + 2));
con.printf("Padding %d byte\n", space.read_byte(address + 3)); con.printf("Padding %d byte\n", tspace->read_byte(address + 3));
con.printf("DpcListEntry {%08X,%08X} _LIST_ENTRY\n", space.read_dword_unaligned(address + 4), space.read_dword_unaligned(address + 8, true)); con.printf("DpcListEntry {%08X,%08X} _LIST_ENTRY\n", tspace->read_dword_unaligned(address + 4), tspace->read_dword_unaligned(address + 8, true));
con.printf("DeferredRoutine %08X dword\n", space.read_dword_unaligned(address + 12)); con.printf("DeferredRoutine %08X dword\n", tspace->read_dword_unaligned(address + 12));
con.printf("DeferredContext %08X dword\n", space.read_dword_unaligned(address + 16)); con.printf("DeferredContext %08X dword\n", tspace->read_dword_unaligned(address + 16));
con.printf("SystemArgument1 %08X dword\n", space.read_dword_unaligned(address + 20)); con.printf("SystemArgument1 %08X dword\n", tspace->read_dword_unaligned(address + 20));
con.printf("SystemArgument2 %08X dword\n", space.read_dword_unaligned(address + 24)); con.printf("SystemArgument2 %08X dword\n", tspace->read_dword_unaligned(address + 24));
} }
void xbox_base_state::dump_timer_command(const std::vector<std::string_view> &params) void xbox_base_state::dump_timer_command(const std::vector<std::string_view> &params)
{ {
debugger_console &con = machine().debugger().console(); debugger_console &con = machine().debugger().console();
address_space &space = m_maincpu->space();
uint64_t addr; uint64_t addr;
offs_t address; offs_t address;
@ -251,60 +250,61 @@ void xbox_base_state::dump_timer_command(const std::vector<std::string_view> &pa
return; return;
address = (offs_t)addr; address = (offs_t)addr;
if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) address_space *tspace;
if (!m_maincpu->translate(AS_PROGRAM, device_memory_interface::TR_READ, address, tspace))
{ {
con.printf("Address is unmapped.\n"); con.printf("Address is unmapped.\n");
return; return;
} }
con.printf("Header.Type %d byte\n", space.read_byte(address)); con.printf("Header.Type %d byte\n", tspace->read_byte(address));
con.printf("Header.Absolute %d byte\n", space.read_byte(address + 1)); con.printf("Header.Absolute %d byte\n", tspace->read_byte(address + 1));
con.printf("Header.Size %d byte\n", space.read_byte(address + 2)); con.printf("Header.Size %d byte\n", tspace->read_byte(address + 2));
con.printf("Header.Inserted %d byte\n", space.read_byte(address + 3)); con.printf("Header.Inserted %d byte\n", tspace->read_byte(address + 3));
con.printf("Header.SignalState %08X dword\n", space.read_dword_unaligned(address + 4)); con.printf("Header.SignalState %08X dword\n", tspace->read_dword_unaligned(address + 4));
con.printf("Header.WaitListEntry {%08X,%08X} _LIST_ENTRY\n", space.read_dword_unaligned(address + 8), space.read_dword_unaligned(address + 12)); con.printf("Header.WaitListEntry {%08X,%08X} _LIST_ENTRY\n", tspace->read_dword_unaligned(address + 8), tspace->read_dword_unaligned(address + 12));
con.printf("%s", string_format("DueTime %x qword\n", (int64_t)space.read_qword_unaligned(address + 16)).c_str()); con.printf("%s", string_format("DueTime %x qword\n", (int64_t)tspace->read_qword_unaligned(address + 16)).c_str());
con.printf("TimerListEntry {%08X,%08X} _LIST_ENTRY\n", space.read_dword_unaligned(address + 24), space.read_dword_unaligned(address + 28)); con.printf("TimerListEntry {%08X,%08X} _LIST_ENTRY\n", tspace->read_dword_unaligned(address + 24), tspace->read_dword_unaligned(address + 28));
con.printf("Dpc %08X dword\n", space.read_dword_unaligned(address + 32)); con.printf("Dpc %08X dword\n", tspace->read_dword_unaligned(address + 32));
con.printf("Period %d dword\n", space.read_dword_unaligned(address + 36)); con.printf("Period %d dword\n", tspace->read_dword_unaligned(address + 36));
} }
void xbox_base_state::curthread_command(const std::vector<std::string_view> &params) void xbox_base_state::curthread_command(const std::vector<std::string_view> &params)
{ {
debugger_console &con = machine().debugger().console(); debugger_console &con = machine().debugger().console();
address_space &space = m_maincpu->space();
offs_t address; offs_t address;
uint64_t fsbase = m_maincpu->state_int(44); // base of FS register uint64_t fsbase = m_maincpu->state_int(44); // base of FS register
address = (offs_t)fsbase + (offs_t)debugc_bios->parameter[7-1]; address = (offs_t)fsbase + (offs_t)debugc_bios->parameter[7-1];
if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) address_space *tspace;
if (!m_maincpu->translate(AS_PROGRAM, device_memory_interface::TR_READ, address, tspace))
{ {
con.printf("Address is unmapped.\n"); con.printf("Address is unmapped.\n");
return; return;
} }
uint32_t kthrd = space.read_dword_unaligned(address); uint32_t kthrd = tspace->read_dword_unaligned(address);
con.printf("Current thread is %08X\n", kthrd); con.printf("Current thread is %08X\n", kthrd);
address = (offs_t)(kthrd + debugc_bios->parameter[8-1]); address = (offs_t)(kthrd + debugc_bios->parameter[8-1]);
if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) if (!m_maincpu->translate(AS_PROGRAM, device_memory_interface::TR_READ, address, tspace))
return; return;
uint32_t topstack = space.read_dword_unaligned(address); uint32_t topstack = tspace->read_dword_unaligned(address);
con.printf("Current thread stack top is %08X\n", topstack); con.printf("Current thread stack top is %08X\n", topstack);
address = (offs_t)(kthrd + debugc_bios->parameter[4-1]); address = (offs_t)(kthrd + debugc_bios->parameter[4-1]);
if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) if (!m_maincpu->translate(AS_PROGRAM, device_memory_interface::TR_READ, address, tspace))
return; return;
uint32_t tlsdata = space.read_dword_unaligned(address); uint32_t tlsdata = tspace->read_dword_unaligned(address);
if (tlsdata == 0) if (tlsdata == 0)
address = (offs_t)(topstack - debugc_bios->parameter[5-1] - debugc_bios->parameter[6-1]); address = (offs_t)(topstack - debugc_bios->parameter[5-1] - debugc_bios->parameter[6-1]);
else else
address = (offs_t)(tlsdata - debugc_bios->parameter[6-1]); address = (offs_t)(tlsdata - debugc_bios->parameter[6-1]);
if (m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) if (m_maincpu->translate(AS_PROGRAM, device_memory_interface::TR_READ, address, tspace))
con.printf("Current thread function is %08X\n", space.read_dword_unaligned(address)); con.printf("Current thread function is %08X\n", tspace->read_dword_unaligned(address));
} }
void xbox_base_state::threadlist_command(const std::vector<std::string_view> &params) void xbox_base_state::threadlist_command(const std::vector<std::string_view> &params)
{ {
debugger_console &con = machine().debugger().console(); debugger_console &con = machine().debugger().console();
address_space &space = m_maincpu->space(); address_space *tspace;
con.printf("Pri. _KTHREAD Stack Function\n"); con.printf("Pri. _KTHREAD Stack Function\n");
con.printf("-------------------------------\n"); con.printf("-------------------------------\n");
@ -312,28 +312,28 @@ void xbox_base_state::threadlist_command(const std::vector<std::string_view> &pa
{ {
uint32_t curr = debugc_bios->parameter[1 - 1] + pri * 8; uint32_t curr = debugc_bios->parameter[1 - 1] + pri * 8;
uint32_t addr = curr; uint32_t addr = curr;
if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, addr)) if (!m_maincpu->translate(AS_PROGRAM, device_memory_interface::TR_READ, addr, tspace))
continue; continue;
uint32_t next = space.read_dword_unaligned(addr); uint32_t next = tspace->read_dword_unaligned(addr);
while ((next != curr) && (next != 0)) while ((next != curr) && (next != 0))
{ {
uint32_t kthrd = next - debugc_bios->parameter[2 - 1]; uint32_t kthrd = next - debugc_bios->parameter[2 - 1];
if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, kthrd)) if (!m_maincpu->translate(AS_PROGRAM, device_memory_interface::TR_READ, kthrd, tspace))
break; break;
uint32_t topstack = space.read_dword_unaligned(kthrd + debugc_bios->parameter[3 - 1]); uint32_t topstack = tspace->read_dword_unaligned(kthrd + debugc_bios->parameter[3 - 1]);
uint32_t tlsdata = space.read_dword_unaligned(kthrd + debugc_bios->parameter[4 - 1]); uint32_t tlsdata = tspace->read_dword_unaligned(kthrd + debugc_bios->parameter[4 - 1]);
uint32_t function = 0; uint32_t function = 0;
if (tlsdata == 0) if (tlsdata == 0)
addr = topstack - debugc_bios->parameter[5 - 1] - debugc_bios->parameter[6 - 1]; addr = topstack - debugc_bios->parameter[5 - 1] - debugc_bios->parameter[6 - 1];
else else
addr = tlsdata - debugc_bios->parameter[6 - 1]; addr = tlsdata - debugc_bios->parameter[6 - 1];
if (m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, addr)) if (m_maincpu->translate(AS_PROGRAM, device_memory_interface::TR_READ, addr, tspace))
function = space.read_dword_unaligned(addr); function = tspace->read_dword_unaligned(addr);
con.printf(" %02d %08x %08x %08x\n", pri, kthrd, topstack, function); con.printf(" %02d %08x %08x %08x\n", pri, kthrd, topstack, function);
addr = next; addr = next;
if (m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, addr)) if (m_maincpu->translate(AS_PROGRAM, device_memory_interface::TR_READ, addr, tspace))
next = space.read_dword_unaligned(addr); next = tspace->read_dword_unaligned(addr);
else else
break; break;
} }
@ -422,7 +422,6 @@ void xbox_base_state::grab_vprog_command(const std::vector<std::string_view> &pa
void xbox_base_state::vprogdis_command(const std::vector<std::string_view> &params) void xbox_base_state::vprogdis_command(const std::vector<std::string_view> &params)
{ {
debugger_console &con = machine().debugger().console(); debugger_console &con = machine().debugger().console();
address_space &space = m_maincpu->space();
if (params.size() < 3) if (params.size() < 3)
return; return;
@ -441,18 +440,19 @@ void xbox_base_state::vprogdis_command(const std::vector<std::string_view> &para
return; return;
vertex_program_disassembler vd; vertex_program_disassembler vd;
address_space *tspace;
while (length > 0) while (length > 0)
{ {
uint32_t instruction[4]; uint32_t instruction[4];
if (type == 1) if (type == 1)
{ {
offs_t address = (offs_t)addr; offs_t address = (offs_t)addr;
if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) if (!m_maincpu->translate(AS_PROGRAM, device_memory_interface::TR_READ, address, tspace))
return; return;
instruction[0] = space.read_dword_unaligned(address); instruction[0] = tspace->read_dword_unaligned(address);
instruction[1] = space.read_dword_unaligned(address + 4); instruction[1] = tspace->read_dword_unaligned(address + 4);
instruction[2] = space.read_dword_unaligned(address + 8); instruction[2] = tspace->read_dword_unaligned(address + 8);
instruction[3] = space.read_dword_unaligned(address + 12); instruction[3] = tspace->read_dword_unaligned(address + 12);
} }
else else
{ {
@ -475,7 +475,7 @@ void xbox_base_state::vprogdis_command(const std::vector<std::string_view> &para
void xbox_base_state::vdeclaration_command(const std::vector<std::string_view> &params) void xbox_base_state::vdeclaration_command(const std::vector<std::string_view> &params)
{ {
debugger_console &con = machine().debugger().console(); debugger_console &con = machine().debugger().console();
address_space &space = m_maincpu->space(); address_space *tspace;
if (params.size() < 1) if (params.size() < 1)
return; return;
@ -487,9 +487,9 @@ void xbox_base_state::vdeclaration_command(const std::vector<std::string_view> &
for (int n = 128; n > 0; n--) for (int n = 128; n > 0; n--)
{ {
offs_t address = (offs_t)addr; offs_t address = (offs_t)addr;
if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) if (!m_maincpu->translate(AS_PROGRAM, device_memory_interface::TR_READ, address, tspace))
return; return;
uint32_t w = space.read_dword_unaligned(address); uint32_t w = tspace->read_dword_unaligned(address);
if (w == 0xffffffff) if (w == 0xffffffff)
{ {
@ -539,9 +539,9 @@ void xbox_base_state::vdeclaration_command(const std::vector<std::string_view> &
{ {
addr += 4; addr += 4;
address = (offs_t)addr; address = (offs_t)addr;
if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) if (!m_maincpu->translate(AS_PROGRAM, device_memory_interface::TR_READ, address, tspace))
return; return;
w = space.read_dword_unaligned(address); w = tspace->read_dword_unaligned(address);
con.printf("%08x\n", w); con.printf("%08x\n", w);
} }
break; break;

View File

@ -963,7 +963,8 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_m(const char *buf)
return REPLY_ENN; return REPLY_ENN;
offs_t offset = address; offs_t offset = address;
if ( !m_memory->translate(m_address_space->spacenum(), TRANSLATE_READ_DEBUG, offset) ) address_space *tspace;
if ( !m_memory->translate(m_address_space->spacenum(), device_memory_interface::TR_READ, offset, tspace) )
return REPLY_ENN; return REPLY_ENN;
// Disable side effects while reading memory. // Disable side effects while reading memory.
@ -973,7 +974,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_m(const char *buf)
reply.reserve(length * 2); reply.reserve(length * 2);
for ( int i = 0; i < length; i++ ) for ( int i = 0; i < length; i++ )
{ {
uint8_t value = m_address_space->read_byte(offset + i); uint8_t value = tspace->read_byte(offset + i);
reply += string_format("%02x", value); reply += string_format("%02x", value);
} }
send_reply(reply.c_str()); send_reply(reply.c_str());
@ -1008,7 +1009,8 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_M(const char *buf)
return REPLY_ENN; return REPLY_ENN;
offs_t offset = address; offs_t offset = address;
if ( !m_memory->translate(m_address_space->spacenum(), TRANSLATE_READ_DEBUG, offset) ) address_space *tspace;
if ( !m_memory->translate(m_address_space->spacenum(), device_memory_interface::TR_READ, offset, tspace) )
return REPLY_ENN; return REPLY_ENN;
std::vector<uint8_t> data; std::vector<uint8_t> data;
@ -1016,7 +1018,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_M(const char *buf)
return REPLY_ENN; return REPLY_ENN;
for ( int i = 0; i < length; i++ ) for ( int i = 0; i < length; i++ )
m_address_space->write_byte(offset + i, data[i]); tspace->write_byte(offset + i, data[i]);
return REPLY_OK; return REPLY_OK;
} }
@ -1220,9 +1222,10 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_z(const char *buf)
// watchpoints // watchpoints
offs_t offset = address; offs_t offset = address;
address_space *tspace;
if ( type == 2 || type == 3 || type == 4 ) if ( type == 2 || type == 3 || type == 4 )
{ {
if ( !m_memory->translate(m_address_space->spacenum(), TRANSLATE_READ_DEBUG, offset) ) if ( !m_memory->translate(m_address_space->spacenum(), device_memory_interface::TR_READ, offset, tspace) )
return REPLY_ENN; return REPLY_ENN;
m_address_map.erase(offset); m_address_map.erase(offset);
} }
@ -1261,9 +1264,10 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_Z(const char *buf)
// watchpoints // watchpoints
offs_t offset = address; offs_t offset = address;
address_space *tspace;
if ( type == 2 || type == 3 || type == 4 ) if ( type == 2 || type == 3 || type == 4 )
{ {
if ( !m_memory->translate(m_address_space->spacenum(), TRANSLATE_READ_DEBUG, offset) ) if ( !m_memory->translate(m_address_space->spacenum(), device_memory_interface::TR_READ, offset, tspace) )
return REPLY_ENN; return REPLY_ENN;
m_address_map[offset] = address; m_address_map[offset] = address;
} }

View File

@ -496,29 +496,30 @@ void DebuggerMemView::addItemsToContextMenu(QMenu *menu)
offs_t const address = addressSpace->byte_to_address(memView.addressAtCursorPosition(pos)); offs_t const address = addressSpace->byte_to_address(memView.addressAtCursorPosition(pos));
offs_t a = address & addressSpace->logaddrmask(); offs_t a = address & addressSpace->logaddrmask();
bool good = false; bool good = false;
if (!addressSpace->device().memory().translate(addressSpace->spacenum(), TRANSLATE_READ_DEBUG, a)) address_space *tspace;
if (!addressSpace->device().memory().translate(addressSpace->spacenum(), device_memory_interface::TR_READ, a, tspace))
{ {
m_lastPc = "Bad address"; m_lastPc = "Bad address";
} }
else else
{ {
uint64_t memValue = addressSpace->unmap(); uint64_t memValue = tspace->unmap();
auto dis = addressSpace->device().machine().disable_side_effects(); auto dis = tspace->device().machine().disable_side_effects();
switch (addressSpace->data_width()) switch (tspace->data_width())
{ {
case 8: memValue = addressSpace->read_byte(a); break; case 8: memValue = tspace->read_byte(a); break;
case 16: memValue = addressSpace->read_word_unaligned(a); break; case 16: memValue = tspace->read_word_unaligned(a); break;
case 32: memValue = addressSpace->read_dword_unaligned(a); break; case 32: memValue = tspace->read_dword_unaligned(a); break;
case 64: memValue = addressSpace->read_qword_unaligned(a); break; case 64: memValue = tspace->read_qword_unaligned(a); break;
} }
offs_t const pc = source.device()->debug()->track_mem_pc_from_space_address_data( offs_t const pc = source.device()->debug()->track_mem_pc_from_space_address_data(
addressSpace->spacenum(), tspace->spacenum(),
address, address,
memValue); memValue);
if (pc != offs_t(-1)) if (pc != offs_t(-1))
{ {
if (addressSpace->is_octal()) if (tspace->is_octal())
m_lastPc = QString("Address %1 written at PC=%2").arg(address, 2, 8).arg(pc, 2, 8); m_lastPc = QString("Address %1 written at PC=%2").arg(address, 2, 8).arg(pc, 2, 8);
else else
m_lastPc = QString("Address %1 written at PC=%2").arg(address, 2, 16).arg(pc, 2, 16); m_lastPc = QString("Address %1 written at PC=%2").arg(address, 2, 16).arg(pc, 2, 16);