diff options
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); |
