diff options
author | 2017-07-31 23:47:16 -0400 | |
---|---|---|
committer | 2017-08-01 00:21:19 -0400 | |
commit | bb0964f9a284b15851773f5428bd602ca01cc28b (patch) | |
tree | e2c7c0dc17e42a88046cf6de8b357daee868b9d9 | |
parent | d050ba956ed79015389bc2cba7399db9cbd62684 (diff) |
Changes to debugger memory address translation
- memory_translate now returns an address space number rather a boolean flag, permitting addresses in part of one space to map to an entirely different space. This is primarily intended to help MCUs which have blocks of internal memory that can be dynamically remapped, but may also allow for more accurate emulation of MMUs that drive multiple external address spaces, since the old limit of four address spaces per MAME device has been lifted.
- memory_translate has also been made a const method, in spite of a couple of badly behaved CPU cores that can't honestly treat it as one.
- The (read|write)_(byte|word|dword|qword|memory|opcode) accessors have been transferred from debugger_cpu to device_memory_interface, with somewhat modified arguments corresponding to the translate function it calls through to if requested.
34 files changed, 750 insertions, 676 deletions
diff --git a/docs/source/techspecs/device_memory_interface.rst b/docs/source/techspecs/device_memory_interface.rst index d38faf8c996..1b338db94d8 100644 --- a/docs/source/techspecs/device_memory_interface.rst +++ b/docs/source/techspecs/device_memory_interface.rst @@ -102,14 +102,72 @@ version tests for AS_PROGRAM/AS_0. 5. MMU support for disassembler ------------------------------- -| bool **translate**\ (int spacenum, int intention, offs_t &address) +| int **translate**\ (int spacenum, int intention, offs_t &address) Does a logical to physical address translation through the device's MMU. spacenum gives the space number, intention the type of the future access (TRANSLATE_(READ|WRITE|FETCH)(|_USER|_DEBUG)) and address is an inout parameter with the address to translate and its -translated version. Should return true if the translation went -correctly, false if the address is unmapped. +translated version. This returns the translated space number if +the translation went correctly, or AS_INVALID if the address is +unmapped. -Note that for some historical reason the device itself must override -the virtual method **memory_translate** with the same signature. +Note that the device itself must override the virtual method +**memory_translate** with the same signature. + + +| u8 **read_byte**\ (int spacenum, offs_t address, int intention) + +Returns a byte from the specified memory space, doing address +translation if requested. The intention must be specified as either +TRANSLATE_READ(|_USER|_DEBUG) or TRANSLATE_NONE. + +| u16 **read_word**\ (int spacenum, offs_t address, int intention) + +Returns a word from the specified memory space, doing address +translation if requested. The intention must be specified as either +TRANSLATE_READ(|_USER|_DEBUG) or TRANSLATE_NONE. + +| u32 **read_dword**\ (int spacenum, offs_t address, int intention) + +Returns a dword from the specified memory space, doing address +translation if requested. The intention must be specified as either +TRANSLATE_READ(|_USER|_DEBUG) or TRANSLATE_NONE. + +| u64 **read_qword**\ (int spacenum, offs_t address, int intention) +Returns a qword from the specified memory space, doing address +translation if requested. The intention must be specified as either +TRANSLATE_READ(|_USER|_DEBUG) or TRANSLATE_NONE. + +| u64 **read_memory**\ (int spacenum, offs_t address, int size, int intention) +Returns 1, 2, 4 or 8 bytes from the specified memory space, as per +**read_byte**, **read_word**, **read_dword** or **read_qword**. + +| void **write_byte**\ (int spacenum, offs_t address, u8 data, int intention) +Writes a byte to the specified memory space, doing address +translation if requested. The intention must be specified as either +TRANSLATE_WRITE(|_USER|_DEBUG) or TRANSLATE_NONE. + +| void **write_word**\ (int spacenum, offs_t address, u16 data, int intention) +Writes a word to the specified memory space, doing address +translation if requested. The intention must be specified as either +TRANSLATE_WRITE(|_USER|_DEBUG) or TRANSLATE_NONE. + +| void **write_dword**\ (int spacenum, offs_t address, u32 data, int intention) +Writes a dword to the specified memory space, doing address +translation if requested. The intention must be specified as either +TRANSLATE_WRITE(|_USER|_DEBUG) or TRANSLATE_NONE. + +| void **write_qword**\ (int spacenum, offs_t address, u64 data, int intention) +Writes a qword to the specified memory space, doing address +translation if requested. The intention must be specified as either +TRANSLATE_WRITE(|_USER|_DEBUG) or TRANSLATE_NONE. + +| void **write_memory**\ (int spacenum, offs_t address, u64 data, int size, int intention) +Writes 1, 2, 4 or 8 bytes to the specified memory space, as per +**write_byte**, **write_word**, **write_dword** or **write_qword**. + +| u64 read_opcode(int spacenum, offs_t offset, int size) +Reads 1, 2, 4 or 8 bytes at the given offset from the specified +opcode space. This calls **translate** with TRANSLATE_FETCH_DEBUG +as the intention. diff --git a/src/devices/cpu/arm7/arm7.cpp b/src/devices/cpu/arm7/arm7.cpp index 314003c8bdb..734f5513f28 100644 --- a/src/devices/cpu/arm7/arm7.cpp +++ b/src/devices/cpu/arm7/arm7.cpp @@ -443,14 +443,14 @@ bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags) } -bool arm7_cpu_device::memory_translate(int spacenum, int intention, offs_t &address) +int arm7_cpu_device::memory_translate(int spacenum, int intention, offs_t &address) const { /* 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 ) ) { - return arm7_tlb_translate(address, 0); + return const_cast<arm7_cpu_device &>(*this).arm7_tlb_translate(address, 0) ? AS_PROGRAM : AS_INVALID; } - return true; + return spacenum; } diff --git a/src/devices/cpu/arm7/arm7.h b/src/devices/cpu/arm7/arm7.h index 7ee80f91fdd..be9eec4de0c 100644 --- a/src/devices/cpu/arm7/arm7.h +++ b/src/devices/cpu/arm7/arm7.h @@ -68,7 +68,7 @@ protected: // device_memory_interface overrides virtual space_config_vector memory_space_config() const override; - virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; + virtual int memory_translate(int spacenum, int intention, offs_t &address) const override; // device_state_interface overrides virtual void state_export(const device_state_entry &entry) override; diff --git a/src/devices/cpu/h6280/h6280.cpp b/src/devices/cpu/h6280/h6280.cpp index c8a81af0532..5a53243b2d1 100644 --- a/src/devices/cpu/h6280/h6280.cpp +++ b/src/devices/cpu/h6280/h6280.cpp @@ -329,7 +329,7 @@ void h6280_device::device_stop() } -inline uint32_t h6280_device::translated(uint16_t addr) +inline uint32_t h6280_device::translated(uint16_t addr) const { return ((m_mmr[((addr) >> 13) & 7] << 13) | ((addr) & 0x1fff)); } @@ -2571,12 +2571,12 @@ WRITE8_MEMBER( h6280_device::timer_w ) } } -bool h6280_device::memory_translate(int spacenum, int intention, offs_t &address) +int h6280_device::memory_translate(int spacenum, int intention, offs_t &address) const { if (spacenum == AS_PROGRAM) address = translated(address); - return true; + return spacenum; } uint8_t h6280_device::io_get_buffer() diff --git a/src/devices/cpu/h6280/h6280.h b/src/devices/cpu/h6280/h6280.h index dc6a3ddb47f..80b693ccf3a 100644 --- a/src/devices/cpu/h6280/h6280.h +++ b/src/devices/cpu/h6280/h6280.h @@ -86,7 +86,7 @@ protected: // device_memory_interface overrides virtual space_config_vector memory_space_config() const override; - virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; + virtual int memory_translate(int spacenum, int intention, offs_t &address) const override; // device_disasm_interface overrides virtual uint32_t disasm_min_opcode_bytes() const override; @@ -177,7 +177,7 @@ protected: PROTOTYPES(op) - uint32_t translated(uint16_t addr); + uint32_t translated(uint16_t addr) const; void h6280_cycles(int cyc); void set_nz(uint8_t n); void clear_t(); diff --git a/src/devices/cpu/i386/i386.cpp b/src/devices/cpu/i386/i386.cpp index 4b4b8286818..fdbdd82d9d0 100644 --- a/src/devices/cpu/i386/i386.cpp +++ b/src/devices/cpu/i386/i386.cpp @@ -4012,13 +4012,12 @@ void i386_device::execute_run() /*************************************************************************/ -bool i386_device::memory_translate(int spacenum, int intention, offs_t &address) +int i386_device::memory_translate(int spacenum, int intention, offs_t &address) const { - bool ret = true; if(spacenum == AS_PROGRAM) - ret = i386_translate_address(intention, &address, nullptr); + spacenum = i386_translate_address(intention, &address, nullptr) ? AS_PROGRAM : AS_INVALID; address &= m_a20_mask; - return ret; + return spacenum; } offs_t i386_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) diff --git a/src/devices/cpu/i386/i386.h b/src/devices/cpu/i386/i386.h index 3701f6c6704..4712bdfffad 100644 --- a/src/devices/cpu/i386/i386.h +++ b/src/devices/cpu/i386/i386.h @@ -60,7 +60,7 @@ protected: // device_memory_interface overrides virtual space_config_vector memory_space_config() const override; - virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; + virtual int memory_translate(int spacenum, int intention, offs_t &address) const override; // device_state_interface overrides virtual void state_import(const device_state_entry &entry) override; @@ -296,8 +296,8 @@ protected: void register_state_i386_x87(); void register_state_i386_x87_xmm(); inline uint32_t i386_translate(int segment, uint32_t ip, int rwn); - inline vtlb_entry get_permissions(uint32_t pte, int wp); - bool i386_translate_address(int intention, offs_t *address, vtlb_entry *entry); + inline vtlb_entry get_permissions(uint32_t pte, int wp) const; + bool i386_translate_address(int intention, offs_t *address, vtlb_entry *entry) const; inline bool translate_address(int pl, int type, uint32_t *address, uint32_t *error); inline void CHANGE_PC(uint32_t pc); inline void NEAR_BRANCH(int32_t offs); diff --git a/src/devices/cpu/i386/i386priv.h b/src/devices/cpu/i386/i386priv.h index 0a917c631a3..24df4b5f4fb 100644 --- a/src/devices/cpu/i386/i386priv.h +++ b/src/devices/cpu/i386/i386priv.h @@ -381,7 +381,7 @@ uint32_t i386_device::i386_translate(int segment, uint32_t ip, int rwn) #define VTLB_FLAG_DIRTY 0x100 -vtlb_entry i386_device::get_permissions(uint32_t pte, int wp) +vtlb_entry i386_device::get_permissions(uint32_t pte, int wp) const { vtlb_entry ret = VTLB_READ_ALLOWED | ((pte & 4) ? VTLB_USER_READ_ALLOWED : 0); if(!wp) @@ -391,7 +391,7 @@ vtlb_entry i386_device::get_permissions(uint32_t pte, int wp) return ret; } -bool i386_device::i386_translate_address(int intention, offs_t *address, vtlb_entry *entry) +bool i386_device::i386_translate_address(int intention, offs_t *address, vtlb_entry *entry) const { uint32_t a = *address; uint32_t pdbr = m_cr[3] & 0xfffff000; diff --git a/src/devices/cpu/i86/i286.cpp b/src/devices/cpu/i86/i286.cpp index c3418b16efc..8abc3bbf994 100644 --- a/src/devices/cpu/i86/i286.cpp +++ b/src/devices/cpu/i86/i286.cpp @@ -371,12 +371,12 @@ 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) +int i80286_cpu_device::memory_translate(int spacenum, int intention, offs_t &address) const { if(spacenum == AS_PROGRAM) address &= m_amask; - return true; + return spacenum; } void i80286_cpu_device::execute_set_input(int inptnum, int state) diff --git a/src/devices/cpu/i86/i286.h b/src/devices/cpu/i86/i286.h index ad2447b78e7..eb4058d0804 100644 --- a/src/devices/cpu/i86/i286.h +++ b/src/devices/cpu/i86/i286.h @@ -86,7 +86,7 @@ protected: virtual uint32_t execute_input_lines() const override { return 1; } virtual void execute_set_input(int inputnum, int state) override; - bool memory_translate(int spacenum, int intention, offs_t &address) override; + int memory_translate(int spacenum, int intention, offs_t &address) const 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 uint8_t read_port_byte(uint16_t port) override; diff --git a/src/devices/cpu/m6502/m4510.cpp b/src/devices/cpu/m6502/m4510.cpp index 852d3e5807a..71a038435ce 100644 --- a/src/devices/cpu/m6502/m4510.cpp +++ b/src/devices/cpu/m6502/m4510.cpp @@ -56,14 +56,14 @@ void m4510_device::device_reset() m65ce02_device::device_reset(); } -bool m4510_device::memory_translate(int spacenum, int intention, offs_t &address) +int m4510_device::memory_translate(int spacenum, int intention, offs_t &address) const { if (spacenum == AS_PROGRAM) { address = map(address); } - return true; + return spacenum; } m4510_device::mi_4510_normal::mi_4510_normal(m4510_device *_base) diff --git a/src/devices/cpu/m6502/m4510.h b/src/devices/cpu/m6502/m4510.h index b093c8aeb56..26cd6ec1422 100644 --- a/src/devices/cpu/m6502/m4510.h +++ b/src/devices/cpu/m6502/m4510.h @@ -30,7 +30,7 @@ public: protected: uint32_t map_offset[2]; uint8_t map_enable; - bool nomap; + mutable bool nomap; class mi_4510_normal : public memory_interface { public: @@ -54,9 +54,9 @@ protected: virtual void device_start() override; virtual void device_reset() override; - virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; + virtual int memory_translate(int spacenum, int intention, offs_t &address) const override; - inline uint32_t map(uint16_t adr) { + inline uint32_t map(uint16_t adr) const { if(map_enable & (1 << (adr >> 13))) { nomap = false; return adr + map_offset[adr >> 15]; diff --git a/src/devices/cpu/m68000/m68000.h b/src/devices/cpu/m68000/m68000.h index 776f097967c..3a45bea87f3 100644 --- a/src/devices/cpu/m68000/m68000.h +++ b/src/devices/cpu/m68000/m68000.h @@ -395,7 +395,7 @@ public: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_memory_interface overrides - virtual bool memory_translate(int space, int intention, offs_t &address) override; + virtual int memory_translate(int space, int intention, offs_t &address) const override; }; @@ -596,7 +596,7 @@ public: virtual uint32_t execute_default_irq_vector() const override { return -1; }; - virtual bool memory_translate(int space, int intention, offs_t &address) override; + virtual int memory_translate(int space, int intention, offs_t &address) const override; // device-level overrides virtual void device_start() override; diff --git a/src/devices/cpu/m68000/m68kcpu.cpp b/src/devices/cpu/m68000/m68kcpu.cpp index c4199ecdf15..945e9aafce5 100644 --- a/src/devices/cpu/m68000/m68kcpu.cpp +++ b/src/devices/cpu/m68000/m68kcpu.cpp @@ -704,7 +704,7 @@ static void m68k_cause_bus_error(m68000_base_device *m68k) m68ki_jump_vector(m68k, EXCEPTION_BUS_ERROR); } -bool m68000_base_device::memory_translate(int space, int intention, offs_t &address) +int m68000_base_device::memory_translate(int space, int intention, offs_t &address) const { /* only applies to the program address space and only does something if the MMU's enabled */ { @@ -712,28 +712,29 @@ bool m68000_base_device::memory_translate(int space, int intention, offs_t &addr if ((space == AS_PROGRAM) && ((pmmu_enabled) || (CPU_TYPE_IS_040_PLUS(cpu_type)))) { // FIXME: mmu_tmp_sr will be overwritten in pmmu_translate_addr_with_fc - uint16_t temp_mmu_tmp_sr = mmu_tmp_sr; + auto &cpu = const_cast<m68000_base_device &>(*this); + uint16_t temp_mmu_tmp_sr = cpu.mmu_tmp_sr; int mode = s_flag ? FUNCTION_CODE_SUPERVISOR_PROGRAM : FUNCTION_CODE_USER_PROGRAM; // uint32_t va=address; if (CPU_TYPE_IS_040_PLUS(cpu_type)) { - address = pmmu_translate_addr_with_fc_040(this, address, mode, 1); + address = pmmu_translate_addr_with_fc_040(&cpu, address, mode, 1); } else { - address = pmmu_translate_addr_with_fc(this, address, mode, 1); + address = pmmu_translate_addr_with_fc(&cpu, address, mode, 1); } - if ((mmu_tmp_sr & M68K_MMU_SR_INVALID) != 0) { + if ((cpu.mmu_tmp_sr & M68K_MMU_SR_INVALID) != 0) { // logerror("cpu_translate_m68k failed with mmu_sr=%04x va=%08x pa=%08x\n",mmu_tmp_sr,va ,address); address = 0; } - mmu_tmp_sr = temp_mmu_tmp_sr; + cpu.mmu_tmp_sr = temp_mmu_tmp_sr; } } - return true; + return space; } @@ -2627,7 +2628,7 @@ void m68020pmmu_device::device_start() init_cpu_m68020pmmu(); } -bool m68020hmmu_device::memory_translate(int space, int intention, offs_t &address) +int m68020hmmu_device::memory_translate(int space, int intention, offs_t &address) const { /* only applies to the program address space and only does something if the MMU's enabled */ { @@ -2636,7 +2637,7 @@ bool m68020hmmu_device::memory_translate(int space, int intention, offs_t &addre address = hmmu_translate_addr(this, address); } } - return true; + return space; } diff --git a/src/devices/cpu/m68000/m68kmmu.h b/src/devices/cpu/m68000/m68kmmu.h index d477b31f187..7ada8fb69b4 100644 --- a/src/devices/cpu/m68000/m68kmmu.h +++ b/src/devices/cpu/m68000/m68kmmu.h @@ -1111,7 +1111,7 @@ void m68881_mmu_ops(m68000_base_device *m68k) /* Apple HMMU translation is much simpler */ -static inline uint32_t hmmu_translate_addr(m68000_base_device *m68k, uint32_t addr_in) +static inline uint32_t hmmu_translate_addr(const m68000_base_device *m68k, uint32_t addr_in) { uint32_t addr_out; diff --git a/src/devices/cpu/mips/mips3.cpp b/src/devices/cpu/mips/mips3.cpp index d55d26623d1..3e812f73fc9 100644 --- a/src/devices/cpu/mips/mips3.cpp +++ b/src/devices/cpu/mips/mips3.cpp @@ -952,17 +952,22 @@ void mips3_device::device_reset() } -bool mips3_device::memory_translate(int spacenum, int intention, offs_t &address) +int mips3_device::memory_translate(int spacenum, int intention, offs_t &address) const { /* only applies to the program address space */ if (spacenum == AS_PROGRAM) - { - const vtlb_entry *table = vtlb_table(); - vtlb_entry entry = table[address >> MIPS3_MIN_PAGE_SHIFT]; - if ((entry & (1 << (intention & (TRANSLATE_TYPE_MASK | TRANSLATE_USER_MASK)))) == 0) - return false; - address = (entry & ~MIPS3_MIN_PAGE_MASK) | (address & MIPS3_MIN_PAGE_MASK); - } + return translate_address_internal(intention, address) ? AS_PROGRAM : AS_INVALID; + return spacenum; +} + + +bool mips3_device::translate_address_internal(int intention, offs_t &address) const +{ + const vtlb_entry *table = vtlb_table(); + vtlb_entry entry = table[address >> MIPS3_MIN_PAGE_SHIFT]; + if ((entry & (1 << (intention & (TRANSLATE_TYPE_MASK | TRANSLATE_USER_MASK)))) == 0) + return false; + address = (entry & ~MIPS3_MIN_PAGE_MASK) | (address & MIPS3_MIN_PAGE_MASK); return true; } diff --git a/src/devices/cpu/mips/mips3.h b/src/devices/cpu/mips/mips3.h index 6d763c8792b..e7256065baa 100644 --- a/src/devices/cpu/mips/mips3.h +++ b/src/devices/cpu/mips/mips3.h @@ -305,7 +305,7 @@ protected: // device_memory_interface overrides virtual space_config_vector memory_space_config() const override; - virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; + virtual int memory_translate(int spacenum, int intention, offs_t &address) const override; // device_state_interface overrides virtual void state_export(const device_state_entry &entry) override; @@ -575,6 +575,7 @@ private: void log_register_list(drcuml_state *drcuml, const char *string, const uint32_t *reglist, const uint32_t *regnostarlist); void log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, int indent); + bool translate_address_internal(int intention, offs_t &address) const; }; diff --git a/src/devices/cpu/mips/mips3fe.cpp b/src/devices/cpu/mips/mips3fe.cpp index a530d026c75..69ab3c2ca3e 100644 --- a/src/devices/cpu/mips/mips3fe.cpp +++ b/src/devices/cpu/mips/mips3fe.cpp @@ -39,7 +39,7 @@ bool mips3_frontend::describe(opcode_desc &desc, const opcode_desc *prev) // compute the physical PC assert((desc.physpc & 3) == 0); - if (!m_mips3->memory_translate(AS_PROGRAM, TRANSLATE_FETCH, desc.physpc)) + if (!m_mips3->translate_address_internal(TRANSLATE_FETCH, desc.physpc)) { // 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 diff --git a/src/devices/cpu/powerpc/ppc.h b/src/devices/cpu/powerpc/ppc.h index dd09cce15e4..4c808dd9767 100644 --- a/src/devices/cpu/powerpc/ppc.h +++ b/src/devices/cpu/powerpc/ppc.h @@ -260,7 +260,7 @@ protected: // device_memory_interface overrides virtual space_config_vector memory_space_config() const override; - virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; + virtual int memory_translate(int spacenum, int intention, offs_t &address) const override; // device_state_interface overrides virtual void state_export(const device_state_entry &entry) override; @@ -626,7 +626,7 @@ protected: void set_timebase(uint64_t newtb); uint32_t get_decrementer(); 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, offs_t &address) const; void ppc4xx_set_irq_line(uint32_t bitmask, int state); int ppc4xx_get_irq_line(uint32_t bitmask); void ppc4xx_dma_update_irq_states(); diff --git a/src/devices/cpu/powerpc/ppccom.cpp b/src/devices/cpu/powerpc/ppccom.cpp index 56a7325c460..737a29e2568 100644 --- a/src/devices/cpu/powerpc/ppccom.cpp +++ b/src/devices/cpu/powerpc/ppccom.cpp @@ -1272,7 +1272,7 @@ void ppc_device::ppccom_dcstore_callback() filling -------------------------------------------------*/ -uint32_t ppc_device::ppccom_translate_address_internal(int intention, offs_t &address) +uint32_t ppc_device::ppccom_translate_address_internal(int intention, offs_t &address) const { int transpriv = ((intention & TRANSLATE_USER_MASK) == 0); // 1 for supervisor, 0 for user int transtype = intention & TRANSLATE_TYPE_MASK; @@ -1467,14 +1467,14 @@ uint32_t ppc_device::ppccom_translate_address_internal(int intention, offs_t &ad from logical to physical -------------------------------------------------*/ -bool ppc_device::memory_translate(int spacenum, int intention, offs_t &address) +int ppc_device::memory_translate(int spacenum, int intention, offs_t &address) const { /* only applies to the program address space */ if (spacenum != AS_PROGRAM) - return true; + return spacenum; /* 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, address) <= 1) ? AS_PROGRAM : AS_INVALID; } diff --git a/src/devices/cpu/powerpc/ppcfe.cpp b/src/devices/cpu/powerpc/ppcfe.cpp index 956fad03374..2a5967061d5 100644 --- a/src/devices/cpu/powerpc/ppcfe.cpp +++ b/src/devices/cpu/powerpc/ppcfe.cpp @@ -74,7 +74,7 @@ bool ppc_frontend::describe(opcode_desc &desc, const opcode_desc *prev) int regnum; // compute the physical PC - if (!m_ppc->memory_translate(AS_PROGRAM, TRANSLATE_FETCH, desc.physpc)) + if (m_ppc->ppccom_translate_address_internal(TRANSLATE_FETCH, desc.physpc) > 1) { // 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 diff --git a/src/devices/cpu/z180/z180.cpp b/src/devices/cpu/z180/z180.cpp index a1dda238c60..602d094e0bf 100644 --- a/src/devices/cpu/z180/z180.cpp +++ b/src/devices/cpu/z180/z180.cpp @@ -2552,13 +2552,13 @@ void z180_device::execute_set_input(int irqline, int state) } /* logical to physical address translation */ -bool z180_device::memory_translate(int spacenum, int intention, offs_t &address) +int z180_device::memory_translate(int spacenum, int intention, offs_t &address) const { if (spacenum == AS_PROGRAM) { address = MMU_REMAP_ADDR(address); } - return true; + return spacenum; } diff --git a/src/devices/cpu/z180/z180.h b/src/devices/cpu/z180/z180.h index dca5c963539..6c8073cf7de 100644 --- a/src/devices/cpu/z180/z180.h +++ b/src/devices/cpu/z180/z180.h @@ -150,7 +150,7 @@ protected: // device_memory_interface overrides virtual space_config_vector memory_space_config() const override; - virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; + virtual int memory_translate(int spacenum, int intention, offs_t &address) const override; // device_state_interface overrides virtual void state_import(const device_state_entry &entry) override; diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp index f3650bdef92..a8d1b93ca15 100644 --- a/src/emu/debug/debugcmd.cpp +++ b/src/emu/debug/debugcmd.cpp @@ -41,7 +41,9 @@ const size_t debugger_commands::MAX_GLOBALS = 1000; 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); + device_memory_interface &memory = space.device().memory(); + int tspacenum = memory.translate(space.spacenum(), TRANSLATE_READ, address); + return tspacenum != AS_INVALID && memory.space(tspacenum).get_write_ptr(address) != nullptr; } @@ -91,7 +93,7 @@ u64 debugger_commands::cheat_byte_swap(const cheat_system *cheatsys, u64 value) u64 debugger_commands::cheat_read_extended(const cheat_system *cheatsys, address_space &space, offs_t address) { - return cheat_sign_extend(cheatsys, cheat_byte_swap(cheatsys, m_cpu.read_memory(space, address, cheatsys->width, true))); + return cheat_sign_extend(cheatsys, cheat_byte_swap(cheatsys, space.device().memory().read_memory(space.spacenum(), address, cheatsys->width, TRANSLATE_READ_DEBUG))); } debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu, debugger_console& console) @@ -1667,9 +1669,10 @@ void debugger_commands::execute_save(int ref, const std::vector<std::string> &pa } /* now write the data out */ + device_memory_interface &memory = space->device().memory(); for (i = offset; i <= endoffset; i++) { - u8 byte = m_cpu.read_byte(*space, i, true); + u8 byte = memory.read_byte(space->spacenum(), i, TRANSLATE_READ_DEBUG); fwrite(&byte, 1, 1, f); } @@ -1719,12 +1722,13 @@ void debugger_commands::execute_load(int ref, const std::vector<std::string> &pa offset = space->address_to_byte(offset) & space->bytemask(); // now read the data in, ignore endoffset and load entire file if length has been set to zero (offset-1) + device_memory_interface &memory = space->device().memory(); for (i = offset; f.good() && (i <= endoffset || endoffset == offset - 1); i++) { char byte; f.read(&byte, 1); if (f) - m_cpu.write_byte(*space, i, byte, true); + memory.write_byte(space->spacenum(), i, byte, TRANSLATE_WRITE_DEBUG); } if (!f.good()) @@ -1783,6 +1787,7 @@ void debugger_commands::execute_dump(int ref, const std::vector<std::string> &pa return; } + device_memory_interface &memory = space->device().memory(); u64 endoffset = space->address_to_byte(offset + length - 1) & space->bytemask(); offset = space->address_to_byte(offset) & space->bytemask(); @@ -1811,9 +1816,9 @@ void debugger_commands::execute_dump(int ref, const std::vector<std::string> &pa if (i + j <= endoffset) { offs_t curaddr = i + j; - if (space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr)) + if (memory.translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr) != AS_INVALID) { - u64 value = m_cpu.read_memory(*space, i + j, width, true); + u64 value = memory.read_memory(space->spacenum(), i + j, width, TRANSLATE_READ_DEBUG); util::stream_format(output, " %0*X", width * 2, value); } else @@ -1832,9 +1837,9 @@ void debugger_commands::execute_dump(int ref, const std::vector<std::string> &pa for (u64 j = 0; j < rowsize && (i + j) <= endoffset; j++) { offs_t curaddr = i + j; - if (space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr)) + if (memory.translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr) != AS_INVALID) { - u8 byte = m_cpu.read_byte(*space, i + j, true); + u8 byte = memory.read_byte(space->spacenum(), i + j, TRANSLATE_READ_DEBUG); util::stream_format(output, "%c", (byte >= 32 && byte < 127) ? byte : '.'); } else @@ -2363,6 +2368,8 @@ void debugger_commands::execute_find(int ref, const std::vector<std::string> &pa } /* now search */ + device_memory_interface &memory = space->device().memory(); + int spacenum = space->spacenum(); for (u64 i = offset; i <= endoffset; i += data_size[0]) { int suboffset = 0; @@ -2373,10 +2380,10 @@ void debugger_commands::execute_find(int ref, const std::vector<std::string> &pa { switch (data_size[j]) { - case 1: match = (u8(m_cpu.read_byte(*space, i + suboffset, true)) == u8(data_to_find[j])); break; - case 2: match = (u16(m_cpu.read_word(*space, i + suboffset, true)) == u16(data_to_find[j])); break; - case 4: match = (u32(m_cpu.read_dword(*space, i + suboffset, true)) == u32(data_to_find[j])); break; - case 8: match = (u64(m_cpu.read_qword(*space, i + suboffset, true)) == u64(data_to_find[j])); break; + case 1: match = (u8(memory.read_byte(spacenum, i + suboffset, TRANSLATE_READ_DEBUG)) == u8(data_to_find[j])); break; + case 2: match = (u16(memory.read_word(spacenum, i + suboffset, TRANSLATE_READ_DEBUG)) == u16(data_to_find[j])); break; + case 4: match = (u32(memory.read_dword(spacenum, i + suboffset, TRANSLATE_READ_DEBUG)) == u32(data_to_find[j])); break; + case 8: match = (u64(memory.read_qword(spacenum, i + suboffset, TRANSLATE_READ_DEBUG)) == u64(data_to_find[j])); break; default: /* all other cases are wildcards */ break; } suboffset += data_size[j] & 0x0f; @@ -2404,7 +2411,7 @@ void debugger_commands::execute_dasm(int ref, const std::vector<std::string> &pa { u64 offset, length, bytes = 1; int minbytes, maxbytes, byteswidth; - address_space *space, *decrypted_space; + address_space *space; FILE *f; int j; @@ -2417,10 +2424,7 @@ void debugger_commands::execute_dasm(int ref, const std::vector<std::string> &pa return; if (!validate_cpu_space_parameter(params.size() > 4 ? params[4].c_str() : nullptr, AS_PROGRAM, space)) return; - if (space->device().memory().has_space(AS_OPCODES)) - decrypted_space = &space->device().memory().space(AS_OPCODES); - else - decrypted_space = space; + int opcode_spacenum = space->device().memory().has_space(AS_OPCODES) ? AS_OPCODES : space->spacenum(); /* determine the width of the bytes */ device_disasm_interface *dasmintf; @@ -2454,7 +2458,6 @@ void debugger_commands::execute_dasm(int ref, const std::vector<std::string> &pa { int pcbyte = space->address_to_byte(offset + i) & space->bytemask(); const char *comment; - offs_t tempaddr; int numbytes = 0; output.clear(); output.rdbuf()->clear(); @@ -2465,8 +2468,8 @@ void debugger_commands::execute_dasm(int ref, const std::vector<std::string> &pa stream_format(output, "%0*X: ", space->logaddrchars(), u32(space->byte_to_address(pcbyte))); /* make sure we can translate the address */ - tempaddr = pcbyte; - if (space->device().memory().translate(space->spacenum(), TRANSLATE_FETCH_DEBUG, tempaddr)) + offs_t tempaddr = pcbyte; + if (space->device().memory().translate(space->spacenum(), TRANSLATE_FETCH_DEBUG, tempaddr) != AS_INVALID) { { u8 opbuf[64], argbuf[64]; @@ -2474,8 +2477,8 @@ void debugger_commands::execute_dasm(int ref, const std::vector<std::string> &pa /* fetch the bytes up to the maximum */ for (numbytes = 0; numbytes < maxbytes; numbytes++) { - opbuf[numbytes] = m_cpu.read_opcode(*decrypted_space, pcbyte + numbytes, 1); - argbuf[numbytes] = m_cpu.read_opcode(*space, pcbyte + numbytes, 1); + opbuf[numbytes] = space->device().memory().read_opcode(opcode_spacenum, pcbyte + numbytes, 1); + argbuf[numbytes] = space->device().memory().read_opcode(space->spacenum(), pcbyte + numbytes, 1); } /* disassemble the result */ @@ -2488,7 +2491,7 @@ void debugger_commands::execute_dasm(int ref, const std::vector<std::string> &pa auto const startdex = output.tellp(); numbytes = space->address_to_byte(numbytes); for (j = 0; j < numbytes; j += minbytes) - stream_format(output, "%0*X ", minbytes * 2, m_cpu.read_opcode(*decrypted_space, pcbyte + j, minbytes)); + stream_format(output, "%0*X ", minbytes * 2, space->device().memory().read_opcode(opcode_spacenum, pcbyte + j, minbytes)); if ((output.tellp() - startdex) < byteswidth) stream_format(output, "%*s", byteswidth - (output.tellp() - startdex), ""); stream_format(output, " "); @@ -2640,13 +2643,10 @@ void debugger_commands::execute_traceflush(int ref, const std::vector<std::strin void debugger_commands::execute_history(int ref, const std::vector<std::string> ¶ms) { /* validate parameters */ - address_space *space, *decrypted_space; + address_space *space; if (!validate_cpu_space_parameter(!params.empty() ? params[0].c_str() : nullptr, AS_PROGRAM, space)) return; - if (space->device().memory().has_space(AS_OPCODES)) - decrypted_space = &space->device().memory().space(AS_OPCODES); - else - decrypted_space = space; + int opcode_spacenum = space->device().memory().has_space(AS_OPCODES) ? AS_OPCODES : space->spacenum(); u64 count = device_debug::HISTORY_SIZE; if (params.size() > 1 && !validate_number_parameter(params[1], count)) @@ -2675,8 +2675,8 @@ void debugger_commands::execute_history(int ref, const std::vector<std::string> u8 opbuf[64], argbuf[64]; for (int numbytes = 0; numbytes < maxbytes; numbytes++) { - opbuf[numbytes] = m_cpu.read_opcode(*decrypted_space, pcbyte + numbytes, 1); - argbuf[numbytes] = m_cpu.read_opcode(*space, pcbyte + numbytes, 1); + opbuf[numbytes] = space->device().memory().read_opcode(opcode_spacenum, pcbyte + numbytes, 1); + argbuf[numbytes] = space->device().memory().read_opcode(space->spacenum(), pcbyte + numbytes, 1); } util::ovectorstream buffer; @@ -2791,7 +2791,7 @@ void debugger_commands::execute_pcatmem(int ref, const std::vector<std::string> // Get the value of memory at the address const int native_data_width = space->data_width() / 8; - const u64 data = m_cpu.read_memory(*space, space->address_to_byte(address), native_data_width, true); + const u64 data = space->device().memory().read_memory(space->spacenum(), space->address_to_byte(address), native_data_width, TRANSLATE_READ_DEBUG); // Recover the pc & print const int space_num = (int)ref; @@ -2866,7 +2866,6 @@ void debugger_commands::execute_source(int ref, const std::vector<std::string> & void debugger_commands::execute_map(int ref, const std::vector<std::string> ¶ms) { address_space *space; - offs_t taddress; u64 address; int intention; @@ -2882,8 +2881,8 @@ void debugger_commands::execute_map(int ref, const std::vector<std::string> &par for (intention = TRANSLATE_READ_DEBUG; intention <= TRANSLATE_FETCH_DEBUG; intention++) { static const char *const intnames[] = { "Read", "Write", "Fetch" }; - taddress = space->address_to_byte(address) & space->bytemask(); - if (space->device().memory().translate(space->spacenum(), intention, taddress)) + offs_t taddress = space->address_to_byte(address) & space->bytemask(); + if (space->device().memory().translate(space->spacenum(), intention, taddress) != AS_INVALID) { const char *mapname = space->get_handler_string((intention == TRANSLATE_WRITE_DEBUG) ? read_or_write::WRITE : read_or_write::READ, taddress); m_console.printf( diff --git a/src/emu/debug/debugcpu.cpp b/src/emu/debug/debugcpu.cpp index 46ad9e04683..e6f65b7d0c9 100644 --- a/src/emu/debug/debugcpu.cpp +++ b/src/emu/debug/debugcpu.cpp @@ -47,6 +47,9 @@ debugger_cpu::debugger_cpu(running_machine &machine) , m_visiblecpu(nullptr) , m_breakcpu(nullptr) , m_symtable(nullptr) + , m_within_instruction_hook(false) + , m_vblank_occurred(false) + , m_memory_modified(false) , m_execution_state(EXECUTION_STATE_STOPPED) , m_bpindex(1) , m_wpindex(1) @@ -350,408 +353,6 @@ bool debugger_cpu::comment_load(bool is_inline) /*************************************************************************** - DEBUGGER MEMORY ACCESSORS -***************************************************************************/ - -/*------------------------------------------------- - read_byte - return a byte from the specified - memory space --------------------------------------------------*/ - -u8 debugger_cpu::read_byte(address_space &space, offs_t address, bool apply_translation) -{ - device_memory_interface &memory = space.device().memory(); - - /* mask against the logical byte mask */ - address &= space.logbytemask(); - - /* translate if necessary; if not mapped, return 0xff */ - u8 result; - if (apply_translation && !memory.translate(space.spacenum(), TRANSLATE_READ_DEBUG, address)) - { - result = 0xff; - } - else - { /* otherwise, call the byte reading function for the translated address */ - result = space.read_byte(address); - } - - return result; -} - - -/*------------------------------------------------- - read_word - return a word from the specified - memory space --------------------------------------------------*/ - -u16 debugger_cpu::read_word(address_space &space, offs_t address, bool apply_translation) -{ - /* mask against the logical byte mask */ - address &= space.logbytemask(); - - u16 result; - if (!WORD_ALIGNED(address)) - { /* if this is misaligned read, or if there are no word readers, just read two bytes */ - u8 byte0 = read_byte(space, address + 0, apply_translation); - u8 byte1 = read_byte(space, address + 1, apply_translation); - - /* based on the endianness, the result is assembled differently */ - if (space.endianness() == ENDIANNESS_LITTLE) - result = byte0 | (byte1 << 8); - else - result = byte1 | (byte0 << 8); - } - else - { /* otherwise, this proceeds like the byte case */ - device_memory_interface &memory = space.device().memory(); - - /* translate if necessary; if not mapped, return 0xffff */ - if (apply_translation && !memory.translate(space.spacenum(), TRANSLATE_READ_DEBUG, address)) - { - result = 0xffff; - } - else - { /* otherwise, call the byte reading function for the translated address */ - result = space.read_word(address); - } - } - - return result; -} - - -/*------------------------------------------------- - read_dword - return a dword from the specified - memory space --------------------------------------------------*/ - -u32 debugger_cpu::read_dword(address_space &space, offs_t address, bool apply_translation) -{ - /* mask against the logical byte mask */ - address &= space.logbytemask(); - - u32 result; - if (!DWORD_ALIGNED(address)) - { /* if this is a misaligned read, or if there are no dword readers, just read two words */ - u16 word0 = read_word(space, address + 0, apply_translation); - u16 word1 = read_word(space, address + 2, apply_translation); - - /* based on the endianness, the result is assembled differently */ - if (space.endianness() == ENDIANNESS_LITTLE) - result = word0 | (word1 << 16); - else - result = word1 | (word0 << 16); - } - else - { /* otherwise, this proceeds like the byte case */ - device_memory_interface &memory = space.device().memory(); - - if (apply_translation && !memory.translate(space.spacenum(), TRANSLATE_READ_DEBUG, address)) - { /* translate if necessary; if not mapped, return 0xffffffff */ - result = 0xffffffff; - } - else - { /* otherwise, call the byte reading function for the translated address */ - result = space.read_dword(address); - } - } - - return result; -} - - -/*------------------------------------------------- - read_qword - return a qword from the specified - memory space --------------------------------------------------*/ - -u64 debugger_cpu::read_qword(address_space &space, offs_t address, bool apply_translation) -{ - /* mask against the logical byte mask */ - address &= space.logbytemask(); - - u64 result; - if (!QWORD_ALIGNED(address)) - { /* if this is a misaligned read, or if there are no qword readers, just read two dwords */ - u32 dword0 = read_dword(space, address + 0, apply_translation); - u32 dword1 = read_dword(space, address + 4, apply_translation); - - /* based on the endianness, the result is assembled differently */ - if (space.endianness() == ENDIANNESS_LITTLE) - result = dword0 | (u64(dword1) << 32); - else - result = dword1 | (u64(dword0) << 32); - } - else - { /* otherwise, this proceeds like the byte case */ - device_memory_interface &memory = space.device().memory(); - - /* translate if necessary; if not mapped, return 0xffffffffffffffff */ - if (apply_translation && !memory.translate(space.spacenum(), TRANSLATE_READ_DEBUG, address)) - { - result = ~u64(0); - } - else - { /* otherwise, call the byte reading function for the translated address */ - result = space.read_qword(address); - } - } - - return result; -} - - -/*------------------------------------------------- - read_memory - return 1,2,4 or 8 bytes - from the specified memory space --------------------------------------------------*/ - -u64 debugger_cpu::read_memory(address_space &space, offs_t address, int size, bool apply_translation) -{ - u64 result = ~u64(0) >> (64 - 8*size); - switch (size) - { - case 1: result = read_byte(space, address, apply_translation); break; - case 2: result = read_word(space, address, apply_translation); break; - case 4: result = read_dword(space, address, apply_translation); break; - case 8: result = read_qword(space, address, apply_translation); break; - } - return result; -} - - -/*------------------------------------------------- - write_byte - write a byte to the specified - memory space --------------------------------------------------*/ - -void debugger_cpu::write_byte(address_space &space, offs_t address, u8 data, bool apply_translation) -{ - device_memory_interface &memory = space.device().memory(); - - /* mask against the logical byte mask */ - address &= space.logbytemask(); - - /* translate if necessary; if not mapped, we're done */ - if (apply_translation && !memory.translate(space.spacenum(), TRANSLATE_WRITE_DEBUG, address)) - ; - - /* otherwise, call the byte reading function for the translated address */ - else - space.write_byte(address, data); - - m_memory_modified = true; -} - - -/*------------------------------------------------- - write_word - write a word to the specified - memory space --------------------------------------------------*/ - -void debugger_cpu::write_word(address_space &space, offs_t address, u16 data, bool apply_translation) -{ - /* mask against the logical byte mask */ - address &= space.logbytemask(); - - /* if this is a misaligned write, or if there are no word writers, just read two bytes */ - if (!WORD_ALIGNED(address)) - { - if (space.endianness() == ENDIANNESS_LITTLE) - { - write_byte(space, address + 0, data >> 0, apply_translation); - write_byte(space, address + 1, data >> 8, apply_translation); - } - else - { - write_byte(space, address + 0, data >> 8, apply_translation); - write_byte(space, address + 1, data >> 0, apply_translation); - } - } - - /* otherwise, this proceeds like the byte case */ - else - { - device_memory_interface &memory = space.device().memory(); - - /* translate if necessary; if not mapped, we're done */ - if (apply_translation && !memory.translate(space.spacenum(), TRANSLATE_WRITE_DEBUG, address)) - ; - - /* otherwise, call the byte reading function for the translated address */ - else - space.write_word(address, data); - - m_memory_modified = true; - } -} - - -/*------------------------------------------------- - write_dword - write a dword to the specified - memory space --------------------------------------------------*/ - -void debugger_cpu::write_dword(address_space &space, offs_t address, u32 data, bool apply_translation) -{ - /* mask against the logical byte mask */ - address &= space.logbytemask(); - - /* if this is a misaligned write, or if there are no dword writers, just read two words */ - if (!DWORD_ALIGNED(address)) - { - if (space.endianness() == ENDIANNESS_LITTLE) - { - write_word(space, address + 0, data >> 0, apply_translation); - write_word(space, address + 2, data >> 16, apply_translation); - } - else - { - write_word(space, address + 0, data >> 16, apply_translation); - write_word(space, address + 2, data >> 0, apply_translation); - } - } - - /* otherwise, this proceeds like the byte case */ - else - { - device_memory_interface &memory = space.device().memory(); - - /* translate if necessary; if not mapped, we're done */ - if (apply_translation && !memory.translate(space.spacenum(), TRANSLATE_WRITE_DEBUG, address)) - ; - - /* otherwise, call the byte reading function for the translated address */ - else - space.write_dword(address, data); - - m_memory_modified = true; - } -} - - -/*------------------------------------------------- - write_qword - write a qword to the specified - memory space --------------------------------------------------*/ - -void debugger_cpu::write_qword(address_space &space, offs_t address, u64 data, bool apply_translation) -{ - /* mask against the logical byte mask */ - address &= space.logbytemask(); - - /* if this is a misaligned write, or if there are no qword writers, just read two dwords */ - if (!QWORD_ALIGNED(address)) - { - if (space.endianness() == ENDIANNESS_LITTLE) - { - write_dword(space, address + 0, data >> 0, apply_translation); - write_dword(space, address + 4, data >> 32, apply_translation); - } - else - { - write_dword(space, address + 0, data >> 32, apply_translation); - write_dword(space, address + 4, data >> 0, apply_translation); - } - } - - /* otherwise, this proceeds like the byte case */ - else - { - device_memory_interface &memory = space.device().memory(); - - /* translate if necessary; if not mapped, we're done */ - if (apply_translation && !memory.translate(space.spacenum(), TRANSLATE_WRITE_DEBUG, address)) - ; - - /* otherwise, call the byte reading function for the translated address */ - else - space.write_qword(address, data); - - m_memory_modified = true; - } -} - - -/*------------------------------------------------- - write_memory - write 1,2,4 or 8 bytes to the - specified memory space --------------------------------------------------*/ - -void debugger_cpu::write_memory(address_space &space, offs_t address, u64 data, int size, bool apply_translation) -{ - switch (size) - { - case 1: write_byte(space, address, data, apply_translation); break; - case 2: write_word(space, address, data, apply_translation); break; - case 4: write_dword(space, address, data, apply_translation); break; - case 8: write_qword(space, address, data, apply_translation); break; - } -} - - -/*------------------------------------------------- - read_opcode - read 1,2,4 or 8 bytes at the - given offset from opcode space --------------------------------------------------*/ - -u64 debugger_cpu::read_opcode(address_space &space, offs_t address, int size) -{ - device_memory_interface &memory = space.device().memory(); - - u64 result = ~u64(0) & (~u64(0) >> (64 - 8*size)); - - /* keep in logical range */ - address &= space.logbytemask(); - - /* if we're bigger than the address bus, break into smaller pieces */ - if (size > space.data_width() / 8) - { - int halfsize = size / 2; - u64 r0 = read_opcode(space, address + 0, halfsize); - u64 r1 = read_opcode(space, address + halfsize, halfsize); - - if (space.endianness() == ENDIANNESS_LITTLE) - return r0 | (r1 << (8 * halfsize)); - else - return r1 | (r0 << (8 * halfsize)); - } - - /* translate to physical first */ - if (!memory.translate(space.spacenum(), TRANSLATE_FETCH_DEBUG, address)) - return result; - - /* keep in physical range */ - address &= space.bytemask(); - - /* switch off the size and handle unaligned accesses */ - switch (size) - { - case 1: - result = space.read_byte(address); - break; - - case 2: - result = space.read_word_unaligned(address); - break; - - case 4: - result = space.read_dword_unaligned(address); - break; - - case 6: - case 8: - result = space.read_qword_unaligned(address); - break; - } - - return result; -} - - - -/*************************************************************************** INTERNAL HELPERS ***************************************************************************/ @@ -842,9 +443,9 @@ device_t* debugger_cpu::expression_get_device(const char *tag) space -------------------------------------------------*/ -u64 debugger_cpu::expression_read_memory(void *param, const char *name, expression_space spacenum, u32 address, int size, bool disable_se) +u64 debugger_cpu::expression_read_memory(void *param, const char *name, expression_space space, u32 address, int size, bool disable_se) { - switch (spacenum) + switch (space) { case EXPSPACE_PROGRAM_LOGICAL: case EXPSPACE_DATA_LOGICAL: @@ -861,11 +462,11 @@ u64 debugger_cpu::expression_read_memory(void *param, const char *name, expressi device = get_visible_cpu(); memory = &device->memory(); } - if (memory->has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL))) + int spacenum = AS_PROGRAM + (space - EXPSPACE_PROGRAM_LOGICAL); + if (memory->has_space(spacenum)) { - address_space &space = memory->space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL)); auto dis = m_machine.disable_side_effect(disable_se); - return read_memory(space, space.address_to_byte(address), size, true); + return memory->read_memory(spacenum, memory->space(spacenum).address_to_byte(address), size, TRANSLATE_READ_DEBUG); } break; } @@ -885,11 +486,11 @@ u64 debugger_cpu::expression_read_memory(void *param, const char *name, expressi device = get_visible_cpu(); memory = &device->memory(); } - if (memory->has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL))) + int spacenum = AS_PROGRAM + (space - EXPSPACE_PROGRAM_PHYSICAL); + if (memory->has_space(spacenum)) { - address_space &space = memory->space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL)); auto dis = m_machine.disable_side_effect(disable_se); - return read_memory(space, space.address_to_byte(address), size, false); + return memory->read_memory(spacenum, memory->space(spacenum).address_to_byte(address), size, TRANSLATE_NONE); } break; } @@ -907,7 +508,7 @@ u64 debugger_cpu::expression_read_memory(void *param, const char *name, expressi memory = &device->memory(); } auto dis = m_machine.disable_side_effect(disable_se); - return expression_read_program_direct(memory->space(AS_PROGRAM), (spacenum == EXPSPACE_OPCODE), address, size); + return expression_read_program_direct(memory->space(AS_PROGRAM), (space == EXPSPACE_OPCODE), address, size); break; } @@ -924,7 +525,7 @@ u64 debugger_cpu::expression_read_memory(void *param, const char *name, expressi memory = &device->memory(); } auto dis = m_machine.disable_side_effect(disable_se); - return expression_read_program_direct(memory->space(AS_OPCODES), (spacenum == EXPSPACE_OPCODE), address, size); + return expression_read_program_direct(memory->space(AS_OPCODES), (space == EXPSPACE_OPCODE), address, size); break; } @@ -1048,17 +649,18 @@ u64 debugger_cpu::expression_read_memory_region(const char *rgntag, offs_t addre space -------------------------------------------------*/ -void debugger_cpu::expression_write_memory(void *param, const char *name, expression_space spacenum, u32 address, int size, u64 data, bool disable_se) +void debugger_cpu::expression_write_memory(void *param, const char *name, expression_space space, u32 address, int size, u64 data, bool disable_se) { device_t *device = nullptr; device_memory_interface *memory; - switch (spacenum) + switch (space) { case EXPSPACE_PROGRAM_LOGICAL: case EXPSPACE_DATA_LOGICAL: case EXPSPACE_IO_LOGICAL: case EXPSPACE_SPACE3_LOGICAL: + { if (name != nullptr) device = expression_get_device(name); if (device == nullptr || !device->interface(memory)) @@ -1066,18 +668,20 @@ void debugger_cpu::expression_write_memory(void *param, const char *name, expres device = get_visible_cpu(); memory = &device->memory(); } - if (memory->has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL))) + int spacenum = AS_PROGRAM + (space - EXPSPACE_PROGRAM_LOGICAL); + if (memory->has_space(spacenum)) { - address_space &space = memory->space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL)); auto dis = m_machine.disable_side_effect(disable_se); - write_memory(space, space.address_to_byte(address), data, size, true); + memory->write_memory(spacenum, memory->space(spacenum).address_to_byte(address), data, size, TRANSLATE_WRITE_DEBUG); } break; + } case EXPSPACE_PROGRAM_PHYSICAL: case EXPSPACE_DATA_PHYSICAL: case EXPSPACE_IO_PHYSICAL: case EXPSPACE_SPACE3_PHYSICAL: + { if (name != nullptr) device = expression_get_device(name); if (device == nullptr || !device->interface(memory)) @@ -1085,15 +689,17 @@ void debugger_cpu::expression_write_memory(void *param, const char *name, expres device = get_visible_cpu(); memory = &device->memory(); } - if (memory->has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL))) + int spacenum = AS_PROGRAM + (space - EXPSPACE_PROGRAM_PHYSICAL); + if (memory->has_space(spacenum)) { - address_space &space = memory->space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL)); auto dis = m_machine.disable_side_effect(disable_se); - write_memory(space, space.address_to_byte(address), data, size, false); + memory->write_memory(spacenum, memory->space(spacenum).address_to_byte(address), data, size, TRANSLATE_NONE); } break; + } - case EXPSPACE_RAMWRITE: { + case EXPSPACE_RAMWRITE: + { if (name != nullptr) device = expression_get_device(name); if (device == nullptr || !device->interface(memory)) @@ -1102,11 +708,12 @@ void debugger_cpu::expression_write_memory(void *param, const char *name, expres memory = &device->memory(); } auto dis = m_machine.disable_side_effect(disable_se); - expression_write_program_direct(memory->space(AS_PROGRAM), (spacenum == EXPSPACE_OPCODE), address, size, data); + expression_write_program_direct(memory->space(AS_PROGRAM), (space == EXPSPACE_OPCODE), address, size, data); break; } - case EXPSPACE_OPCODE: { + case EXPSPACE_OPCODE: + { if (name != nullptr) device = expression_get_device(name); if (device == nullptr || !device->interface(memory)) @@ -1115,7 +722,7 @@ void debugger_cpu::expression_write_memory(void *param, const char *name, expres memory = &device->memory(); } auto dis = m_machine.disable_side_effect(disable_se); - expression_write_program_direct(memory->space(AS_OPCODES), (spacenum == EXPSPACE_OPCODE), address, size, data); + expression_write_program_direct(memory->space(AS_OPCODES), (space == EXPSPACE_OPCODE), address, size, data); break; } @@ -1182,7 +789,7 @@ void debugger_cpu::expression_write_program_direct(address_space &space, int opc base[BYTE8_XOR_LE(address) & lowmask] = data; else base[BYTE8_XOR_BE(address) & lowmask] = data; - m_memory_modified = true; + set_memory_modified(true); } } } @@ -1240,7 +847,7 @@ void debugger_cpu::expression_write_memory_region(const char *rgntag, offs_t add { base[BYTE8_XOR_BE(address) & lowmask] = data; } - m_memory_modified = true; + set_memory_modified(true); } } } @@ -2487,7 +2094,7 @@ u32 device_debug::compute_opcode_crc32(offs_t pc) const assert(m_memory != nullptr); // determine the adjusted PC - address_space &decrypted_space = m_memory->has_space(AS_OPCODES) ? m_memory->space(AS_OPCODES) : m_memory->space(AS_PROGRAM); + int opcode_spacenum = m_memory->has_space(AS_OPCODES) ? AS_OPCODES : AS_PROGRAM; address_space &space = m_memory->space(AS_PROGRAM); offs_t pcbyte = space.address_to_byte(pc) & space.bytemask(); @@ -2496,8 +2103,8 @@ u32 device_debug::compute_opcode_crc32(offs_t pc) const int maxbytes = (m_disasm != nullptr) ? m_disasm->max_opcode_bytes() : 1; for (int numbytes = 0; numbytes < maxbytes; numbytes++) { - opbuf[numbytes] = m_device.machine().debugger().cpu().read_opcode(decrypted_space, pcbyte + numbytes, 1); - argbuf[numbytes] = m_device.machine().debugger().cpu().read_opcode(space, pcbyte + numbytes, 1); + opbuf[numbytes] = m_memory->read_opcode(opcode_spacenum, pcbyte + numbytes, 1); + argbuf[numbytes] = m_memory->read_opcode(AS_PROGRAM, pcbyte + numbytes, 1); } u32 numbytes = maxbytes; @@ -2891,7 +2498,7 @@ u32 device_debug::dasm_wrapped(std::string &buffer, offs_t pc) assert(m_memory != nullptr && m_disasm != nullptr); // determine the adjusted PC - address_space &decrypted_space = m_memory->has_space(AS_OPCODES) ? m_memory->space(AS_OPCODES) : m_memory->space(AS_PROGRAM); + int opcode_spacenum = m_memory->has_space(AS_OPCODES) ? AS_OPCODES : AS_PROGRAM; address_space &space = m_memory->space(AS_PROGRAM); offs_t pcbyte = space.address_to_byte(pc) & space.bytemask(); @@ -2900,8 +2507,8 @@ u32 device_debug::dasm_wrapped(std::string &buffer, offs_t pc) int maxbytes = m_disasm->max_opcode_bytes(); for (int numbytes = 0; numbytes < maxbytes; numbytes++) { - opbuf[numbytes] = m_device.machine().debugger().cpu().read_opcode(decrypted_space, pcbyte + numbytes, 1); - argbuf[numbytes] = m_device.machine().debugger().cpu().read_opcode(space, pcbyte + numbytes, 1); + opbuf[numbytes] = m_memory->read_opcode(opcode_spacenum, pcbyte + numbytes, 1); + argbuf[numbytes] = m_memory->read_opcode(AS_PROGRAM, pcbyte + numbytes, 1); } // disassemble to our buffer diff --git a/src/emu/debug/debugcpu.h b/src/emu/debug/debugcpu.h index 2ea78c3fe20..09b61633c4b 100644 --- a/src/emu/debug/debugcpu.h +++ b/src/emu/debug/debugcpu.h @@ -509,41 +509,6 @@ public: bool comment_load(bool is_inline); - /* ----- debugger memory accessors ----- */ - - /* return a byte from the specified memory space */ - u8 read_byte(address_space &space, offs_t address, bool apply_translation); - - /* return a word from the specified memory space */ - u16 read_word(address_space &space, offs_t address, bool apply_translation); - - /* return a dword from the specified memory space */ - u32 read_dword(address_space &space, offs_t address, bool apply_translation); - - /* return a qword from the specified memory space */ - u64 read_qword(address_space &space, offs_t address, bool apply_translation); - - /* return 1,2,4 or 8 bytes from the specified memory space */ - u64 read_memory(address_space &space, offs_t address, int size, bool apply_translation); - - /* write a byte to the specified memory space */ - void write_byte(address_space &space, offs_t address, u8 data, bool apply_translation); - - /* write a word to the specified memory space */ - void write_word(address_space &space, offs_t address, u16 data, bool apply_translation); - - /* write a dword to the specified memory space */ - void write_dword(address_space &space, offs_t address, u32 data, bool apply_translation); - - /* write a qword to the specified memory space */ - void write_qword(address_space &space, offs_t address, u64 data, bool apply_translation); - - /* write 1,2,4 or 8 bytes to the specified memory space */ - void write_memory(address_space &space, offs_t address, u64 data, int size, bool apply_translation); - - /* read 1,2,4 or 8 bytes at the given offset from opcode space */ - u64 read_opcode(address_space &space, offs_t offset, int size); - // getters bool within_instruction_hook() const { return m_within_instruction_hook; } bool memory_modified() const { return m_memory_modified; } diff --git a/src/emu/debug/dvdisasm.cpp b/src/emu/debug/dvdisasm.cpp index 1051365c561..39744721a76 100644 --- a/src/emu/debug/dvdisasm.cpp +++ b/src/emu/debug/dvdisasm.cpp @@ -231,6 +231,7 @@ offs_t debug_view_disasm::find_pc_backwards(offs_t targetpc, int numinstrs) { auto dis = machine().disable_side_effect(); const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source); + device_memory_interface &memory = source.m_space.device().memory(); // compute the increment int minlen = source.m_space.byte_to_address(source.m_disasmintf->min_opcode_bytes()); @@ -255,8 +256,8 @@ offs_t debug_view_disasm::find_pc_backwards(offs_t targetpc, int numinstrs) while (curpcbyte < fillpcbyte) { fillpcbyte--; - opbuf[1000 + fillpcbyte - targetpcbyte] = machine().debugger().cpu().read_opcode(source.m_decrypted_space, fillpcbyte, 1); - argbuf[1000 + fillpcbyte - targetpcbyte] = machine().debugger().cpu().read_opcode(source.m_space, fillpcbyte, 1); + opbuf[1000 + fillpcbyte - targetpcbyte] = memory.read_opcode(source.m_decrypted_space.spacenum(), fillpcbyte, 1); + argbuf[1000 + fillpcbyte - targetpcbyte] = memory.read_opcode(source.m_space.spacenum(), fillpcbyte, 1); } // loop until we get past the target instruction @@ -270,7 +271,7 @@ offs_t debug_view_disasm::find_pc_backwards(offs_t targetpc, int numinstrs) // get the disassembly, but only if mapped instlen = 1; - if (source.m_space.device().memory().translate(source.m_space.spacenum(), TRANSLATE_FETCH, physpcbyte)) + if (memory.translate(source.m_space.spacenum(), TRANSLATE_FETCH, physpcbyte) != AS_INVALID) { std::ostringstream dasmbuffer; instlen = source.m_disasmintf->disassemble(dasmbuffer, scanpc, &opbuf[1000 + scanpcbyte - targetpcbyte], &argbuf[1000 + scanpcbyte - targetpcbyte]) & DASMFLAG_LENGTHMASK; @@ -310,13 +311,14 @@ offs_t debug_view_disasm::find_pc_backwards(offs_t targetpc, int numinstrs) std::string debug_view_disasm::generate_bytes(offs_t pcbyte, int numbytes, int granularity, bool encrypted) { const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source); + device_memory_interface &memory = source.m_space.device().memory(); const int char_num = source.m_space.is_octal() ? 3 : 2; std::ostringstream ostr; for (int byte = 0; byte < numbytes; byte += granularity) { if (byte) ostr << ' '; - util::stream_format(ostr, source.m_space.is_octal() ? "%0*o" : "%0*X", granularity * char_num, machine().debugger().cpu().read_opcode(encrypted ? source.m_space : source.m_decrypted_space, pcbyte + byte, granularity)); + util::stream_format(ostr, source.m_space.is_octal() ? "%0*o" : "%0*X", granularity * char_num, memory.read_opcode(encrypted ? source.m_space.spacenum() : source.m_decrypted_space.spacenum(), pcbyte + byte, granularity)); } return ostr.str(); @@ -334,6 +336,7 @@ bool debug_view_disasm::recompute(offs_t pc, int startline, int lines) bool changed = false; const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source); + device_memory_interface &memory = source.m_space.device().memory(); const int char_num = source.m_space.is_octal() ? 3 : 2; // determine how many characters we need for an address and set the divider @@ -389,15 +392,15 @@ bool debug_view_disasm::recompute(offs_t pc, int startline, int lines) std::ostringstream dasm; int numbytes = 0; offs_t physpcbyte = pcbyte; - if (source.m_space.device().memory().translate(source.m_space.spacenum(), TRANSLATE_FETCH_DEBUG, physpcbyte)) + if (memory.translate(source.m_space.spacenum(), TRANSLATE_FETCH_DEBUG, physpcbyte) != AS_INVALID) { u8 opbuf[64], argbuf[64]; // fetch the bytes up to the maximum for (numbytes = 0; numbytes < maxbytes; numbytes++) { - opbuf[numbytes] = machine().debugger().cpu().read_opcode(source.m_decrypted_space, pcbyte + numbytes, 1); - argbuf[numbytes] = machine().debugger().cpu().read_opcode(source.m_space, pcbyte + numbytes, 1); + opbuf[numbytes] = memory.read_opcode(source.m_decrypted_space.spacenum(), pcbyte + numbytes, 1); + argbuf[numbytes] = memory.read_opcode(source.m_space.spacenum(), pcbyte + numbytes, 1); } // disassemble the result diff --git a/src/emu/debug/dvmemory.cpp b/src/emu/debug/dvmemory.cpp index a5de89adb30..bcb694a43fa 100644 --- a/src/emu/debug/dvmemory.cpp +++ b/src/emu/debug/dvmemory.cpp @@ -740,22 +740,25 @@ bool debug_view_memory::read(u8 size, offs_t offs, u64 &data) if (source.m_space != nullptr) { auto dis = machine().disable_side_effect(); + int spacenum = source.m_space->spacenum(); bool ismapped = offs <= m_maxaddr; if (ismapped && !m_no_translation) { offs_t dummyaddr = offs; - ismapped = source.m_memintf->translate(source.m_space->spacenum(), TRANSLATE_READ_DEBUG, dummyaddr); + spacenum = source.m_memintf->translate(spacenum, TRANSLATE_READ_DEBUG, dummyaddr); + ismapped = spacenum != AS_INVALID; } data = ~u64(0); if (ismapped) { + int intention = m_no_translation ? TRANSLATE_NONE : TRANSLATE_READ_DEBUG; switch (size) { - case 1: data = machine().debugger().cpu().read_byte(*source.m_space, offs, !m_no_translation); break; - case 2: data = machine().debugger().cpu().read_word(*source.m_space, offs, !m_no_translation); break; - case 4: data = machine().debugger().cpu().read_dword(*source.m_space, offs, !m_no_translation); break; - case 8: data = machine().debugger().cpu().read_qword(*source.m_space, offs, !m_no_translation); break; + case 1: data = source.m_memintf->read_byte(spacenum, offs, intention); break; + case 2: data = source.m_memintf->read_word(spacenum, offs, intention); break; + case 4: data = source.m_memintf->read_dword(spacenum, offs, intention); break; + case 8: data = source.m_memintf->read_qword(spacenum, offs, intention); break; } } return ismapped; @@ -823,13 +826,16 @@ void debug_view_memory::write(u8 size, offs_t offs, u64 data) if (source.m_space != nullptr) { auto dis = machine().disable_side_effect(); + device_memory_interface &memory = source.m_space->device().memory(); + int spacenum = source.m_space->spacenum(); + int intention = m_no_translation ? TRANSLATE_NONE : TRANSLATE_WRITE_DEBUG; switch (size) { - case 1: machine().debugger().cpu().write_byte(*source.m_space, offs, data, !m_no_translation); break; - case 2: machine().debugger().cpu().write_word(*source.m_space, offs, data, !m_no_translation); break; - case 4: machine().debugger().cpu().write_dword(*source.m_space, offs, data, !m_no_translation); break; - case 8: machine().debugger().cpu().write_qword(*source.m_space, offs, data, !m_no_translation); break; + case 1: memory.write_byte(spacenum, offs, data, intention); break; + case 2: memory.write_word(spacenum, offs, data, intention); break; + case 4: memory.write_dword(spacenum, offs, data, intention); break; + case 8: memory.write_qword(spacenum, offs, data, intention); break; } return; } diff --git a/src/emu/dimemory.cpp b/src/emu/dimemory.cpp index 43f05f6019c..287b65dd6e8 100644 --- a/src/emu/dimemory.cpp +++ b/src/emu/dimemory.cpp @@ -9,6 +9,8 @@ ***************************************************************************/ #include "emu.h" +#include "debugger.h" +#include "debug/debugcpu.h" //************************************************************************** @@ -197,10 +199,10 @@ void device_memory_interface::dump(FILE *file) const // translation is supported //------------------------------------------------- -bool device_memory_interface::memory_translate(int spacenum, int intention, offs_t &address) +int device_memory_interface::memory_translate(int spacenum, int intention, offs_t &address) const { // by default it maps directly - return true; + return spacenum; } @@ -240,3 +242,427 @@ void device_memory_interface::interface_validity_check(validity_checker &valid) } } } + + + +//************************************************************************** +// DEBUGGER MEMORY ACCESSORS +//************************************************************************** + +//------------------------------------------------- +// read_byte - return a byte from the specified +// memory space +//------------------------------------------------- + +u8 device_memory_interface::read_byte(int spacenum, offs_t address, int intention) +{ + // mask against the logical byte mask + address &= space(spacenum).logbytemask(); + + // translate if necessary + if (intention != TRANSLATE_NONE) + { + assert((intention & TRANSLATE_TYPE_MASK) == TRANSLATE_READ); + spacenum = translate(spacenum, intention, address); + + // if not mapped, return 0xff + if (spacenum == AS_INVALID) + return 0xff; + } + + // otherwise, call the byte reading function for the translated address + return space(spacenum).read_byte(address); +} + + +//------------------------------------------------- +// read_word - return a word from the specified +// memory space +//------------------------------------------------- + +u16 device_memory_interface::read_word(int spacenum, offs_t address, int intention) +{ + // mask against the logical byte mask + address &= space(spacenum).logbytemask(); + + if (!WORD_ALIGNED(address)) + { + // if this is misaligned read, or if there are no word readers, just read two bytes + u8 byte0 = read_byte(spacenum, address + 0, intention); + u8 byte1 = read_byte(spacenum, address + 1, intention); + + // based on the endianness, the result is assembled differently + if (space(spacenum).endianness() == ENDIANNESS_LITTLE) + return byte0 | (byte1 << 8); + else + return byte1 | (byte0 << 8); + } + else + { + // otherwise, this proceeds like the byte case + if (intention != TRANSLATE_NONE) + { + // translate if necessary + assert((intention & TRANSLATE_TYPE_MASK) == TRANSLATE_READ); + spacenum = translate(spacenum, intention, address); + + // if not mapped, return 0xffff + if (spacenum == AS_INVALID) + return 0xffff; + } + + // otherwise, call the byte reading function for the translated address + return space(spacenum).read_word(address); + } +} + + +//------------------------------------------------- +// read_dword - return a dword from the specified +// memory space +//------------------------------------------------- + +u32 device_memory_interface::read_dword(int spacenum, offs_t address, int intention) +{ + // mask against the logical byte mask + address &= space(spacenum).logbytemask(); + + if (!DWORD_ALIGNED(address)) + { + // if this is a misaligned read, or if there are no dword readers, just read two words + u16 word0 = read_word(spacenum, address + 0, intention); + u16 word1 = read_word(spacenum, address + 2, intention); + + // based on the endianness, the result is assembled differently + if (space(spacenum).endianness() == ENDIANNESS_LITTLE) + return word0 | (word1 << 16); + else + return word1 | (word0 << 16); + } + else + { + // otherwise, this proceeds like the byte case + if (intention != TRANSLATE_NONE) + { + // translate if necessary + assert((intention & TRANSLATE_TYPE_MASK) == TRANSLATE_READ); + spacenum = translate(spacenum, intention, address); + + // if not mapped, return 0xffffffff + if (spacenum == AS_INVALID) + return 0xffffffff; + } + + // otherwise, call the byte reading function for the translated address + return space(spacenum).read_dword(address); + } +} + + +//------------------------------------------------- +// read_qword - return a qword from the specified +// memory space +//------------------------------------------------- + +u64 device_memory_interface::read_qword(int spacenum, offs_t address, int intention) +{ + // mask against the logical byte mask + address &= space(spacenum).logbytemask(); + + if (!QWORD_ALIGNED(address)) + { + // if this is a misaligned read, or if there are no qword readers, just read two dwords + u32 dword0 = read_dword(spacenum, address + 0, intention); + u32 dword1 = read_dword(spacenum, address + 4, intention); + + // based on the endianness, the result is assembled differently + if (space(spacenum).endianness() == ENDIANNESS_LITTLE) + return dword0 | (u64(dword1) << 32); + else + return dword1 | (u64(dword0) << 32); + } + else + { + // otherwise, this proceeds like the byte case + if (intention != TRANSLATE_NONE) + { + // translate if necessary + assert((intention & TRANSLATE_TYPE_MASK) == TRANSLATE_READ); + spacenum = translate(spacenum, intention, address); + + // if not mapped, return 0xffffffffffffffff + if (spacenum == AS_INVALID) + return ~u64(0); + } + + // otherwise, call the byte reading function for the translated address + return space(spacenum).read_qword(address); + } +} + + +//------------------------------------------------- +// read_memory - return 1,2,4 or 8 bytes +// from the specified memory space +//------------------------------------------------- + +u64 device_memory_interface::read_memory(int spacenum, offs_t address, int size, int intention) +{ + u64 result = ~u64(0) >> (64 - 8*size); + switch (size) + { + case 1: result = read_byte(spacenum, address, intention); break; + case 2: result = read_word(spacenum, address, intention); break; + case 4: result = read_dword(spacenum, address, intention); break; + case 8: result = read_qword(spacenum, address, intention); break; + } + return result; +} + + +//------------------------------------------------- +// write_byte - write a byte to the specified +// memory space +//------------------------------------------------- + +void device_memory_interface::write_byte(int spacenum, offs_t address, u8 data, int intention) +{ + // mask against the logical byte mask + address &= space(spacenum).logbytemask(); + + // translate if necessary + if (intention != TRANSLATE_NONE) + { + assert((intention & TRANSLATE_TYPE_MASK) == TRANSLATE_WRITE); + spacenum = translate(spacenum, intention, address); + + // if not mapped, we're done + if (spacenum == AS_INVALID) + return; + } + + // otherwise, call the byte reading function for the translated address + space(spacenum).write_byte(address, data); + + if ((device().machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) + device().machine().debugger().cpu().set_memory_modified(true); +} + + +//------------------------------------------------- +// write_word - write a word to the specified +// memory space +//------------------------------------------------- + +void device_memory_interface::write_word(int spacenum, offs_t address, u16 data, int intention) +{ + // mask against the logical byte mask + address &= space(spacenum).logbytemask(); + + // if this is a misaligned write, or if there are no word writers, just read two bytes + if (!WORD_ALIGNED(address)) + { + if (space(spacenum).endianness() == ENDIANNESS_LITTLE) + { + write_byte(spacenum, address + 0, data >> 0, intention); + write_byte(spacenum, address + 1, data >> 8, intention); + } + else + { + write_byte(spacenum, address + 0, data >> 8, intention); + write_byte(spacenum, address + 1, data >> 0, intention); + } + } + + // otherwise, this proceeds like the byte case + else + { + // translate if necessary + if (intention != TRANSLATE_NONE) + { + assert((intention & TRANSLATE_TYPE_MASK) == TRANSLATE_WRITE); + spacenum = translate(spacenum, intention, address); + + // if not mapped, we're done + if (spacenum == AS_INVALID) + return; + } + + // otherwise, call the byte reading function for the translated address + space(spacenum).write_word(address, data); + + if ((device().machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) + device().machine().debugger().cpu().set_memory_modified(true); + } +} + + +//------------------------------------------------- +// write_dword - write a dword to the specified +// memory space +//------------------------------------------------- + +void device_memory_interface::write_dword(int spacenum, offs_t address, u32 data, int intention) +{ + // mask against the logical byte mask + address &= space(spacenum).logbytemask(); + + // if this is a misaligned write, or if there are no dword writers, just read two words + if (!DWORD_ALIGNED(address)) + { + if (space(spacenum).endianness() == ENDIANNESS_LITTLE) + { + write_word(spacenum, address + 0, data >> 0, intention); + write_word(spacenum, address + 2, data >> 16, intention); + } + else + { + write_word(spacenum, address + 0, data >> 16, intention); + write_word(spacenum, address + 2, data >> 0, intention); + } + } + + // otherwise, this proceeds like the byte case + else + { + // translate if necessary + if (intention != TRANSLATE_NONE) + { + assert((intention & TRANSLATE_TYPE_MASK) == TRANSLATE_WRITE); + spacenum = translate(spacenum, intention, address); + + // if not mapped, we're done + if (spacenum == AS_INVALID) + return; + } + + // otherwise, call the byte reading function for the translated address + space(spacenum).write_dword(address, data); + + if ((device().machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) + device().machine().debugger().cpu().set_memory_modified(true); + } +} + + +//------------------------------------------------- +// write_qword - write a qword to the specified +// memory space +//------------------------------------------------- + +void device_memory_interface::write_qword(int spacenum, offs_t address, u64 data, int intention) +{ + // mask against the logical byte mask + address &= space(spacenum).logbytemask(); + + // if this is a misaligned write, or if there are no qword writers, just read two dwords + if (!QWORD_ALIGNED(address)) + { + if (space(spacenum).endianness() == ENDIANNESS_LITTLE) + { + write_dword(spacenum, address + 0, data >> 0, intention); + write_dword(spacenum, address + 4, data >> 32, intention); + } + else + { + write_dword(spacenum, address + 0, data >> 32, intention); + write_dword(spacenum, address + 4, data >> 0, intention); + } + } + + // otherwise, this proceeds like the byte case + else + { + // translate if necessary + if (intention != TRANSLATE_NONE) + { + assert((intention & TRANSLATE_TYPE_MASK) == TRANSLATE_WRITE); + spacenum = translate(spacenum, intention, address); + + // if not mapped, we're done + if (spacenum == AS_INVALID) + return; + } + + // otherwise, call the byte reading function for the translated address + space(spacenum).write_qword(address, data); + + if ((device().machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) + device().machine().debugger().cpu().set_memory_modified(true); + } +} + + +//------------------------------------------------- +// write_memory - write 1,2,4 or 8 bytes to the +// specified memory space +//-------------------------------------------------- + +void device_memory_interface::write_memory(int spacenum, offs_t address, u64 data, int size, int intention) +{ + switch (size) + { + case 1: write_byte(spacenum, address, data, intention); break; + case 2: write_word(spacenum, address, data, intention); break; + case 4: write_dword(spacenum, address, data, intention); break; + case 8: write_qword(spacenum, address, data, intention); break; + } +} + + +//------------------------------------------------- +// read_opcode - read 1,2,4 or 8 bytes at the +// given offset from opcode space +//------------------------------------------------- + +u64 device_memory_interface::read_opcode(int spacenum, offs_t address, int size) +{ + u64 result = ~u64(0) & (~u64(0) >> (64 - 8*size)); + + // keep in logical range + address &= space(spacenum).logbytemask(); + + // if we're bigger than the address bus, break into smaller pieces + if (size > space(spacenum).data_width() / 8) + { + int halfsize = size / 2; + u64 r0 = read_opcode(spacenum, address + 0, halfsize); + u64 r1 = read_opcode(spacenum, address + halfsize, halfsize); + + if (space(spacenum).endianness() == ENDIANNESS_LITTLE) + return r0 | (r1 << (8 * halfsize)); + else + return r1 | (r0 << (8 * halfsize)); + } + + // keep in physical range + address &= space(spacenum).bytemask(); + + // translate to physical first + spacenum = translate(spacenum, TRANSLATE_FETCH_DEBUG, address); + if (spacenum == AS_INVALID) + return result; + + // switch off the size and handle unaligned accesses + switch (size) + { + case 1: + result = space(spacenum).read_byte(address); + break; + + case 2: + result = space(spacenum).read_word_unaligned(address); + break; + + case 4: + result = space(spacenum).read_dword_unaligned(address); + break; + + case 6: + case 8: + result = space(spacenum).read_qword_unaligned(address); + break; + } + + return result; +} diff --git a/src/emu/dimemory.h b/src/emu/dimemory.h index 8abc5ff435d..3bf6f848784 100644 --- a/src/emu/dimemory.h +++ b/src/emu/dimemory.h @@ -27,9 +27,10 @@ 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_NONE = 0; // direct read/write without translation +constexpr int TRANSLATE_READ = 1; // translate for read +constexpr int TRANSLATE_WRITE = 2; // translate for write +constexpr int TRANSLATE_FETCH = 3; // 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); @@ -37,6 +38,7 @@ 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); +constexpr int AS_INVALID = -1; // invalid address space (failed translation) //************************************************************************** @@ -93,7 +95,20 @@ public: address_space &space(int index = 0) const { assert(index >= 0 && index < int(m_addrspace.size()) && m_addrspace[index]); return *m_addrspace[index]; } // address translation - bool translate(int spacenum, int intention, offs_t &address) { return memory_translate(spacenum, intention, address); } + int translate(int spacenum, int intention, offs_t &address) const { return memory_translate(spacenum, intention, address); } + + // user/debugger memory accessors + u8 read_byte(int spacenum, offs_t address, int intention); + u16 read_word(int spacenum, offs_t address, int intention); + u32 read_dword(int spacenum, offs_t address, int intention); + u64 read_qword(int spacenum, offs_t address, int intention); + u64 read_memory(int spacenum, offs_t address, int size, int intention); + void write_byte(int spacenum, offs_t address, u8 data, int intention); + void write_word(int spacenum, offs_t address, u16 data, int intention); + void write_dword(int spacenum, offs_t address, u32 data, int intention); + void write_qword(int spacenum, offs_t address, u64 data, int intention); + void write_memory(int spacenum, offs_t address, u64 data, int size, int intention); + u64 read_opcode(int spacenum, offs_t offset, int size); // deliberately ambiguous functions; if you have the memory interface // just use it @@ -123,7 +138,7 @@ protected: virtual space_config_vector memory_space_config() const = 0; // optional operation overrides - virtual bool memory_translate(int spacenum, int intention, offs_t &address); + virtual int memory_translate(int spacenum, int intention, offs_t &address) const; // interface-level overrides virtual void interface_config_complete() override; diff --git a/src/emu/divtlb.cpp b/src/emu/divtlb.cpp index 0689bb9c68a..0b379bc08b4 100644 --- a/src/emu/divtlb.cpp +++ b/src/emu/divtlb.cpp @@ -143,7 +143,6 @@ bool device_vtlb_interface::vtlb_fill(offs_t address, int intention) { offs_t tableindex = address >> m_pageshift; vtlb_entry entry = m_table[tableindex]; - offs_t taddress; #if PRINTF_TLB osd_printf_debug("vtlb_fill: %08X(%X) ... ", address, intention); @@ -162,8 +161,8 @@ bool device_vtlb_interface::vtlb_fill(offs_t address, int intention) } // ask the CPU core to translate for us - taddress = address; - if (!device().memory().translate(m_space, intention, taddress)) + offs_t taddress = address; + if (device().memory().translate(m_space, intention, taddress) != m_space) { #if PRINTF_TLB osd_printf_debug("failed: no translation\n"); diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp index b2ea5e017d2..d95bfe1c7a5 100644 --- a/src/frontend/mame/luaengine.cpp +++ b/src/frontend/mame/luaengine.cpp @@ -315,33 +315,35 @@ template <typename T> T lua_engine::addr_space::log_mem_read(offs_t address) { T mem_content = 0; - if(!dev.translate(space.spacenum(), TRANSLATE_READ_DEBUG, address)) + int tspacenum = dev.translate(space.spacenum(), TRANSLATE_READ_DEBUG, address); + if (tspacenum == AS_INVALID) return 0; - address = space.address_to_byte(address); + address_space &tspace = space.device().memory().space(tspacenum); + address = tspace.address_to_byte(address); switch(sizeof(mem_content) * 8) { case 8: - mem_content = space.read_byte(address); + mem_content = tspace.read_byte(address); break; case 16: if (WORD_ALIGNED(address)) { - mem_content = space.read_word(address); + mem_content = tspace.read_word(address); } else { - mem_content = space.read_word_unaligned(address); + mem_content = tspace.read_word_unaligned(address); } break; case 32: if (DWORD_ALIGNED(address)) { - mem_content = space.read_dword(address); + mem_content = tspace.read_dword(address); } else { - mem_content = space.read_dword_unaligned(address); + mem_content = tspace.read_dword_unaligned(address); } break; case 64: if (QWORD_ALIGNED(address)) { - mem_content = space.read_qword(address); + mem_content = tspace.read_qword(address); } else { - mem_content = space.read_qword_unaligned(address); + mem_content = tspace.read_qword_unaligned(address); } break; default: @@ -359,33 +361,35 @@ T lua_engine::addr_space::log_mem_read(offs_t address) template <typename T> void lua_engine::addr_space::log_mem_write(offs_t address, T val) { - if(!dev.translate(space.spacenum(), TRANSLATE_WRITE_DEBUG, address)) + int tspacenum = dev.translate(space.spacenum(), TRANSLATE_WRITE_DEBUG, address); + if (tspacenum == AS_INVALID) return; - address = space.address_to_byte(address); + address_space &tspace = space.device().memory().space(tspacenum); + address = tspace.address_to_byte(address); switch(sizeof(val) * 8) { case 8: - space.write_byte(address, val); + tspace.write_byte(address, val); break; case 16: if (WORD_ALIGNED(address)) { - space.write_word(address, val); + tspace.write_word(address, val); } else { - space.write_word_unaligned(address, val); + tspace.write_word_unaligned(address, val); } break; case 32: if (DWORD_ALIGNED(address)) { - space.write_dword(address, val); + tspace.write_dword(address, val); } else { - space.write_dword_unaligned(address, val); + tspace.write_dword_unaligned(address, val); } break; case 64: if (QWORD_ALIGNED(address)) { - space.write_qword(address, val); + tspace.write_qword(address, val); } else { - space.write_qword_unaligned(address, val); + tspace.write_qword_unaligned(address, val); } break; default: diff --git a/src/mame/drivers/chihiro.cpp b/src/mame/drivers/chihiro.cpp index dfbd640157d..40795234d2a 100644 --- a/src/mame/drivers/chihiro.cpp +++ b/src/mame/drivers/chihiro.cpp @@ -614,10 +614,10 @@ St. Instr. Comment /* jamtable disassembler */ void chihiro_state::jamtable_disasm(address_space &space, uint32_t address, uint32_t size) // 0xff000080 == fff00080 { - debugger_cpu &cpu = machine().debugger().cpu(); + device_memory_interface &memory = space.device().memory(); debugger_console &con = machine().debugger().console(); offs_t addr = (offs_t)address; - if (!space.device().memory().translate(space.spacenum(), TRANSLATE_READ_DEBUG, addr)) + if (memory.translate(space.spacenum(), TRANSLATE_READ_DEBUG, addr) != space.spacenum()) { con.printf("Address is unmapped.\n"); return; @@ -626,11 +626,11 @@ void chihiro_state::jamtable_disasm(address_space &space, uint32_t address, uint { offs_t base = addr; - uint32_t opcode = cpu.read_byte(space, addr, true); + uint32_t opcode = memory.read_byte(space.spacenum(), addr, TRANSLATE_READ_DEBUG); addr++; - uint32_t op1 = cpu.read_dword(space, addr, true); + uint32_t op1 = memory.read_dword(space.spacenum(), addr, TRANSLATE_READ_DEBUG); addr += 4; - uint32_t op2 = cpu.read_dword(space, addr, true); + uint32_t op2 = memory.read_dword(space.spacenum(), addr, TRANSLATE_READ_DEBUG); addr += 4; char sop1[16]; diff --git a/src/mame/machine/xbox.cpp b/src/mame/machine/xbox.cpp index 301620b112c..506b7f11e82 100644 --- a/src/mame/machine/xbox.cpp +++ b/src/mame/machine/xbox.cpp @@ -69,9 +69,7 @@ void xbox_base_state::find_debug_params(running_machine &mach) void xbox_base_state::dump_string_command(int ref, const std::vector<std::string> ¶ms) { - debugger_cpu &cpu = machine().debugger().cpu(); debugger_console &con = machine().debugger().console(); - address_space &space = m_maincpu->space(); uint64_t addr; offs_t address; @@ -82,16 +80,16 @@ void xbox_base_state::dump_string_command(int ref, const std::vector<std::string return; address = (offs_t)addr; - if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) + if (m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address) == AS_INVALID) { con.printf("Address is unmapped.\n"); return; } address = (offs_t)addr; - uint32_t length = cpu.read_word(space, address, true); - uint32_t maximumlength = cpu.read_word(space, address + 2, true); - offs_t buffer = cpu.read_dword(space, address + 4, true); + uint32_t length = m_maincpu->read_word(AS_PROGRAM, address, TRANSLATE_READ_DEBUG); + uint32_t maximumlength = m_maincpu->read_word(AS_PROGRAM, address + 2, TRANSLATE_READ_DEBUG); + offs_t buffer = m_maincpu->read_dword(AS_PROGRAM, address + 4, TRANSLATE_READ_DEBUG); con.printf("Length %d word\n", length); con.printf("MaximumLength %d word\n", maximumlength); con.printf("Buffer %08X byte* ", buffer); @@ -102,7 +100,7 @@ void xbox_base_state::dump_string_command(int ref, const std::vector<std::string for (int a = 0; a < length; a++) { - uint8_t c = cpu.read_byte(space, buffer + a, true); + uint8_t c = m_maincpu->read_byte(AS_PROGRAM, buffer + a, TRANSLATE_READ_DEBUG); con.printf("%c", c); } con.printf("\n"); @@ -110,9 +108,7 @@ void xbox_base_state::dump_string_command(int ref, const std::vector<std::string void xbox_base_state::dump_process_command(int ref, const std::vector<std::string> ¶ms) { - debugger_cpu &cpu = machine().debugger().cpu(); debugger_console &con = machine().debugger().console(); - address_space &space = m_maincpu->space(); uint64_t addr; offs_t address; @@ -123,28 +119,26 @@ void xbox_base_state::dump_process_command(int ref, const std::vector<std::strin return; address = (offs_t)addr; - if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) + if (m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address) == AS_INVALID) { con.printf("Address is unmapped.\n"); return; } address = (offs_t)addr; - con.printf("ReadyListHead {%08X,%08X} _LIST_ENTRY\n", cpu.read_dword(space, address, true), cpu.read_dword(space, address + 4, true)); - con.printf("ThreadListHead {%08X,%08X} _LIST_ENTRY\n", cpu.read_dword(space, address + 8, true), cpu.read_dword(space, address + 12, true)); - con.printf("StackCount %d dword\n", cpu.read_dword(space, address + 16, true)); - con.printf("ThreadQuantum %d dword\n", cpu.read_dword(space, address + 20, true)); - con.printf("BasePriority %d byte\n", cpu.read_byte(space, address + 24, true)); - con.printf("DisableBoost %d byte\n", cpu.read_byte(space, address + 25, true)); - con.printf("DisableQuantum %d byte\n", cpu.read_byte(space, address + 26, true)); - con.printf("_padding %d byte\n", cpu.read_byte(space, address + 27, true)); + con.printf("ReadyListHead {%08X,%08X} _LIST_ENTRY\n", m_maincpu->read_dword(AS_PROGRAM, address, TRANSLATE_READ_DEBUG), m_maincpu->read_dword(AS_PROGRAM, address + 4, TRANSLATE_READ_DEBUG)); + con.printf("ThreadListHead {%08X,%08X} _LIST_ENTRY\n", m_maincpu->read_dword(AS_PROGRAM, address + 8, TRANSLATE_READ_DEBUG), m_maincpu->read_dword(AS_PROGRAM, address + 12, TRANSLATE_READ_DEBUG)); + con.printf("StackCount %d dword\n", m_maincpu->read_dword(AS_PROGRAM, address + 16, TRANSLATE_READ_DEBUG)); + con.printf("ThreadQuantum %d dword\n", m_maincpu->read_dword(AS_PROGRAM, address + 20, TRANSLATE_READ_DEBUG)); + con.printf("BasePriority %d byte\n", m_maincpu->read_byte(AS_PROGRAM, address + 24, TRANSLATE_READ_DEBUG)); + con.printf("DisableBoost %d byte\n", m_maincpu->read_byte(AS_PROGRAM, address + 25, TRANSLATE_READ_DEBUG)); + con.printf("DisableQuantum %d byte\n", m_maincpu->read_byte(AS_PROGRAM, address + 26, TRANSLATE_READ_DEBUG)); + con.printf("_padding %d byte\n", m_maincpu->read_byte(AS_PROGRAM, address + 27, TRANSLATE_READ_DEBUG)); } void xbox_base_state::dump_list_command(int ref, const std::vector<std::string> ¶ms) { - debugger_cpu &cpu = machine().debugger().cpu(); debugger_console &con = machine().debugger().console(); - address_space &space = m_maincpu->space(); uint64_t addr; offs_t address; @@ -165,7 +159,7 @@ void xbox_base_state::dump_list_command(int ref, const std::vector<std::string> uint64_t start = addr; address = (offs_t)addr; - if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) + if (m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address) == AS_INVALID) { con.printf("Address is unmapped.\n"); return; @@ -184,13 +178,13 @@ void xbox_base_state::dump_list_command(int ref, const std::vector<std::string> else con.printf("%08X\n", (uint32_t)addr); old = addr; - addr = cpu.read_dword(space, address, true); + addr = m_maincpu->read_dword(AS_PROGRAM, address, TRANSLATE_READ_DEBUG); if (addr == start) break; if (addr == old) break; address = (offs_t)addr; - if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) + if (m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address) == AS_INVALID) break; address = (offs_t)addr; } @@ -198,9 +192,7 @@ void xbox_base_state::dump_list_command(int ref, const std::vector<std::string> void xbox_base_state::dump_dpc_command(int ref, const std::vector<std::string> ¶ms) { - debugger_cpu &cpu = machine().debugger().cpu(); debugger_console &con = machine().debugger().console(); - address_space &space = m_maincpu->space(); uint64_t addr; offs_t address; @@ -211,27 +203,25 @@ void xbox_base_state::dump_dpc_command(int ref, const std::vector<std::string> & return; address = (offs_t)addr; - if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) + if (m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address) == AS_INVALID) { con.printf("Address is unmapped.\n"); return; } address = (offs_t)addr; - con.printf("Type %d word\n", cpu.read_word(space, address, true)); - con.printf("Inserted %d byte\n", cpu.read_byte(space, address + 2, true)); - con.printf("Padding %d byte\n", cpu.read_byte(space, address + 3, true)); - con.printf("DpcListEntry {%08X,%08X} _LIST_ENTRY\n", cpu.read_dword(space, address + 4, true), cpu.read_dword(space, address + 8, true)); - con.printf("DeferredRoutine %08X dword\n", cpu.read_dword(space, address + 12, true)); - con.printf("DeferredContext %08X dword\n", cpu.read_dword(space, address + 16, true)); - con.printf("SystemArgument1 %08X dword\n", cpu.read_dword(space, address + 20, true)); - con.printf("SystemArgument2 %08X dword\n", cpu.read_dword(space, address + 24, true)); + con.printf("Type %d word\n", m_maincpu->read_word(AS_PROGRAM, address, TRANSLATE_READ_DEBUG)); + con.printf("Inserted %d byte\n", m_maincpu->read_byte(AS_PROGRAM, address + 2, TRANSLATE_READ_DEBUG)); + con.printf("Padding %d byte\n", m_maincpu->read_byte(AS_PROGRAM, address + 3, TRANSLATE_READ_DEBUG)); + con.printf("DpcListEntry {%08X,%08X} _LIST_ENTRY\n", m_maincpu->read_dword(AS_PROGRAM, address + 4, TRANSLATE_READ_DEBUG), m_maincpu->read_dword(AS_PROGRAM, address + 8, TRANSLATE_READ_DEBUG)); + con.printf("DeferredRoutine %08X dword\n", m_maincpu->read_dword(AS_PROGRAM, address + 12, TRANSLATE_READ_DEBUG)); + con.printf("DeferredContext %08X dword\n", m_maincpu->read_dword(AS_PROGRAM, address + 16, TRANSLATE_READ_DEBUG)); + con.printf("SystemArgument1 %08X dword\n", m_maincpu->read_dword(AS_PROGRAM, address + 20, TRANSLATE_READ_DEBUG)); + con.printf("SystemArgument2 %08X dword\n", m_maincpu->read_dword(AS_PROGRAM, address + 24, TRANSLATE_READ_DEBUG)); } void xbox_base_state::dump_timer_command(int ref, const std::vector<std::string> ¶ms) { - debugger_cpu &cpu = machine().debugger().cpu(); debugger_console &con = machine().debugger().console(); - address_space &space = m_maincpu->space(); uint64_t addr; offs_t address; @@ -242,58 +232,54 @@ void xbox_base_state::dump_timer_command(int ref, const std::vector<std::string> return; address = (offs_t)addr; - if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) + if (m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address) == AS_INVALID) { con.printf("Address is unmapped.\n"); return; } address = (offs_t)addr; - con.printf("Header.Type %d byte\n", cpu.read_byte(space, address, true)); - con.printf("Header.Absolute %d byte\n", cpu.read_byte(space, address + 1, true)); - con.printf("Header.Size %d byte\n", cpu.read_byte(space, address + 2, true)); - con.printf("Header.Inserted %d byte\n", cpu.read_byte(space, address + 3, true)); - con.printf("Header.SignalState %08X dword\n", cpu.read_dword(space, address + 4, true)); - con.printf("Header.WaitListEntry {%08X,%08X} _LIST_ENTRY\n", cpu.read_dword(space, address + 8, true), cpu.read_dword(space, address + 12, true)); - con.printf("%s", string_format("DueTime %I64x qword\n", (int64_t)cpu.read_qword(space, address + 16, true)).c_str()); - con.printf("TimerListEntry {%08X,%08X} _LIST_ENTRY\n", cpu.read_dword(space, address + 24, true), cpu.read_dword(space, address + 28, true)); - con.printf("Dpc %08X dword\n", cpu.read_dword(space, address + 32, true)); - con.printf("Period %d dword\n", cpu.read_dword(space, address + 36, true)); + con.printf("Header.Type %d byte\n", m_maincpu->read_byte(AS_PROGRAM, address, TRANSLATE_READ_DEBUG)); + con.printf("Header.Absolute %d byte\n", m_maincpu->read_byte(AS_PROGRAM, address + 1, TRANSLATE_READ_DEBUG)); + con.printf("Header.Size %d byte\n", m_maincpu->read_byte(AS_PROGRAM, address + 2, TRANSLATE_READ_DEBUG)); + con.printf("Header.Inserted %d byte\n", m_maincpu->read_byte(AS_PROGRAM, address + 3, TRANSLATE_READ_DEBUG)); + con.printf("Header.SignalState %08X dword\n", m_maincpu->read_dword(AS_PROGRAM, address + 4, TRANSLATE_READ_DEBUG)); + con.printf("Header.WaitListEntry {%08X,%08X} _LIST_ENTRY\n", m_maincpu->read_dword(AS_PROGRAM, address + 8, TRANSLATE_READ_DEBUG), m_maincpu->read_dword(AS_PROGRAM, address + 12, TRANSLATE_READ_DEBUG)); + con.printf("%s", string_format("DueTime %I64x qword\n", (int64_t)m_maincpu->read_qword(AS_PROGRAM, address + 16, TRANSLATE_READ_DEBUG)).c_str()); + con.printf("TimerListEntry {%08X,%08X} _LIST_ENTRY\n", m_maincpu->read_dword(AS_PROGRAM, address + 24, TRANSLATE_READ_DEBUG), m_maincpu->read_dword(AS_PROGRAM, address + 28, TRANSLATE_READ_DEBUG)); + con.printf("Dpc %08X dword\n", m_maincpu->read_dword(AS_PROGRAM, address + 32, TRANSLATE_READ_DEBUG)); + con.printf("Period %d dword\n", m_maincpu->read_dword(AS_PROGRAM, address + 36, TRANSLATE_READ_DEBUG)); } void xbox_base_state::curthread_command(int ref, const std::vector<std::string> ¶ms) { - debugger_cpu &cpu = machine().debugger().cpu(); debugger_console &con = machine().debugger().console(); - address_space &space = m_maincpu->space(); offs_t address; uint64_t fsbase = m_maincpu->state_int(44); // base of FS register address = (offs_t)fsbase + (offs_t)debugc_bios->parameter[7-1]; - if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) + if (m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address) == AS_INVALID) { con.printf("Address is unmapped.\n"); return; } address = (offs_t)fsbase + (offs_t)debugc_bios->parameter[7-1]; - uint32_t kthrd = cpu.read_dword(space, address, true); + uint32_t kthrd = m_maincpu->read_dword(AS_PROGRAM, address, TRANSLATE_READ_DEBUG); con.printf("Current thread is %08X\n", kthrd); address = (offs_t)(kthrd + debugc_bios->parameter[8-1]); - uint32_t topstack = cpu.read_dword(space, address, true); + uint32_t topstack = m_maincpu->read_dword(AS_PROGRAM, address, TRANSLATE_READ_DEBUG); con.printf("Current thread stack top is %08X\n", topstack); address = (offs_t)(kthrd + debugc_bios->parameter[4-1]); - uint32_t tlsdata = cpu.read_dword(space, address, true); + uint32_t tlsdata = m_maincpu->read_dword(AS_PROGRAM, address, TRANSLATE_READ_DEBUG); if (tlsdata == 0) address = (offs_t)(topstack - debugc_bios->parameter[5-1] - debugc_bios->parameter[6-1]); else address = (offs_t)(tlsdata - debugc_bios->parameter[6-1]); - con.printf("Current thread function is %08X\n", cpu.read_dword(space, address, true)); + con.printf("Current thread function is %08X\n", m_maincpu->read_dword(AS_PROGRAM, address, TRANSLATE_READ_DEBUG)); } void xbox_base_state::threadlist_command(int ref, const std::vector<std::string> ¶ms) { - address_space &space = m_maincpu->space(); - debugger_cpu &cpu = machine().debugger().cpu(); debugger_console &con = machine().debugger().console(); con.printf("Pri. _KTHREAD Stack Function\n"); @@ -301,20 +287,20 @@ void xbox_base_state::threadlist_command(int ref, const std::vector<std::string> for (int pri = 0; pri < 16; pri++) { uint32_t curr = debugc_bios->parameter[1 - 1] + pri * 8; - uint32_t next = cpu.read_dword(space, curr, true); + uint32_t next = m_maincpu->read_dword(AS_PROGRAM, curr, TRANSLATE_READ_DEBUG); while ((next != curr) && (next != 0)) { uint32_t kthrd = next - debugc_bios->parameter[2 - 1]; - uint32_t topstack = cpu.read_dword(space, kthrd + debugc_bios->parameter[3 - 1], true); - uint32_t tlsdata = cpu.read_dword(space, kthrd + debugc_bios->parameter[4 - 1], true); + uint32_t topstack = m_maincpu->read_dword(AS_PROGRAM, kthrd + debugc_bios->parameter[3 - 1], TRANSLATE_READ_DEBUG); + uint32_t tlsdata = m_maincpu->read_dword(AS_PROGRAM, kthrd + debugc_bios->parameter[4 - 1], TRANSLATE_READ_DEBUG); uint32_t function; if (tlsdata == 0) - function = cpu.read_dword(space, topstack - debugc_bios->parameter[5 - 1] - debugc_bios->parameter[6 - 1], true); + function = m_maincpu->read_dword(AS_PROGRAM, topstack - debugc_bios->parameter[5 - 1] - debugc_bios->parameter[6 - 1], TRANSLATE_READ_DEBUG); else - function = cpu.read_dword(space, tlsdata - debugc_bios->parameter[6 - 1], true); + function = m_maincpu->read_dword(AS_PROGRAM, tlsdata - debugc_bios->parameter[6 - 1], TRANSLATE_READ_DEBUG); con.printf(" %02d %08x %08x %08x\n", pri, kthrd, topstack, function); - next = cpu.read_dword(space, next, true); + next = m_maincpu->read_dword(AS_PROGRAM, next, TRANSLATE_READ_DEBUG); } } } @@ -422,7 +408,7 @@ void xbox_base_state::vprogdis_command(int ref, const std::vector<std::string> & if (type == 1) { offs_t addr = (offs_t)address; - if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, addr)) + if (m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, addr) != AS_PROGRAM) return; instruction[0] = space.read_dword_unaligned(address); instruction[1] = space.read_dword_unaligned(address + 4); |