From 1e8c0b23c37a819d0f2cd3ef3d4f74a4f1a85a17 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Tue, 1 Aug 2017 15:19:44 +1000 Subject: [PATCH] This is too contentious, please put it up for review Revert "Changes to debugger memory address translation" This reverts commit bb0964f9a284b15851773f5428bd602ca01cc28b. --- .../techspecs/device_memory_interface.rst | 68 +-- src/devices/cpu/arm7/arm7.cpp | 6 +- src/devices/cpu/arm7/arm7.h | 2 +- src/devices/cpu/h6280/h6280.cpp | 6 +- src/devices/cpu/h6280/h6280.h | 4 +- src/devices/cpu/i386/i386.cpp | 7 +- src/devices/cpu/i386/i386.h | 6 +- src/devices/cpu/i386/i386priv.h | 4 +- src/devices/cpu/i86/i286.cpp | 4 +- src/devices/cpu/i86/i286.h | 2 +- src/devices/cpu/m6502/m4510.cpp | 4 +- src/devices/cpu/m6502/m4510.h | 6 +- src/devices/cpu/m68000/m68000.h | 4 +- src/devices/cpu/m68000/m68kcpu.cpp | 19 +- src/devices/cpu/m68000/m68kmmu.h | 2 +- src/devices/cpu/mips/mips3.cpp | 21 +- src/devices/cpu/mips/mips3.h | 3 +- src/devices/cpu/mips/mips3fe.cpp | 2 +- src/devices/cpu/powerpc/ppc.h | 4 +- src/devices/cpu/powerpc/ppccom.cpp | 8 +- src/devices/cpu/powerpc/ppcfe.cpp | 2 +- src/devices/cpu/z180/z180.cpp | 4 +- src/devices/cpu/z180/z180.h | 2 +- src/emu/debug/debugcmd.cpp | 67 +-- src/emu/debug/debugcpu.cpp | 471 ++++++++++++++++-- src/emu/debug/debugcpu.h | 35 ++ src/emu/debug/dvdisasm.cpp | 17 +- src/emu/debug/dvmemory.cpp | 24 +- src/emu/dimemory.cpp | 430 +--------------- src/emu/dimemory.h | 25 +- src/emu/divtlb.cpp | 5 +- src/frontend/mame/luaengine.cpp | 40 +- src/mame/drivers/chihiro.cpp | 10 +- src/mame/machine/xbox.cpp | 112 +++-- 34 files changed, 676 insertions(+), 750 deletions(-) diff --git a/docs/source/techspecs/device_memory_interface.rst b/docs/source/techspecs/device_memory_interface.rst index 1b338db94d8..d38faf8c996 100644 --- a/docs/source/techspecs/device_memory_interface.rst +++ b/docs/source/techspecs/device_memory_interface.rst @@ -102,72 +102,14 @@ version tests for AS_PROGRAM/AS_0. 5. MMU support for disassembler ------------------------------- -| int **translate**\ (int spacenum, int intention, offs_t &address) +| bool **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. This returns the translated space number if -the translation went correctly, or AS_INVALID if the address is -unmapped. +translated version. Should return true if the translation went +correctly, false if the address is unmapped. -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. +Note that for some historical reason the device itself must override +the virtual method **memory_translate** with the same signature. diff --git a/src/devices/cpu/arm7/arm7.cpp b/src/devices/cpu/arm7/arm7.cpp index 734f5513f28..314003c8bdb 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) } -int arm7_cpu_device::memory_translate(int spacenum, int intention, offs_t &address) const +bool arm7_cpu_device::memory_translate(int spacenum, int intention, offs_t &address) { /* 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 const_cast(*this).arm7_tlb_translate(address, 0) ? AS_PROGRAM : AS_INVALID; + return arm7_tlb_translate(address, 0); } - return spacenum; + return true; } diff --git a/src/devices/cpu/arm7/arm7.h b/src/devices/cpu/arm7/arm7.h index be9eec4de0c..7ee80f91fdd 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 int memory_translate(int spacenum, int intention, offs_t &address) const override; + virtual bool memory_translate(int spacenum, int intention, offs_t &address) 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 5a53243b2d1..c8a81af0532 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) const +inline uint32_t h6280_device::translated(uint16_t addr) { return ((m_mmr[((addr) >> 13) & 7] << 13) | ((addr) & 0x1fff)); } @@ -2571,12 +2571,12 @@ WRITE8_MEMBER( h6280_device::timer_w ) } } -int h6280_device::memory_translate(int spacenum, int intention, offs_t &address) const +bool h6280_device::memory_translate(int spacenum, int intention, offs_t &address) { if (spacenum == AS_PROGRAM) address = translated(address); - return spacenum; + return true; } uint8_t h6280_device::io_get_buffer() diff --git a/src/devices/cpu/h6280/h6280.h b/src/devices/cpu/h6280/h6280.h index 80b693ccf3a..dc6a3ddb47f 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 int memory_translate(int spacenum, int intention, offs_t &address) const override; + virtual bool memory_translate(int spacenum, int intention, offs_t &address) 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) const; + uint32_t translated(uint16_t addr); 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 fdbdd82d9d0..4b4b8286818 100644 --- a/src/devices/cpu/i386/i386.cpp +++ b/src/devices/cpu/i386/i386.cpp @@ -4012,12 +4012,13 @@ void i386_device::execute_run() /*************************************************************************/ -int i386_device::memory_translate(int spacenum, int intention, offs_t &address) const +bool i386_device::memory_translate(int spacenum, int intention, offs_t &address) { + bool ret = true; if(spacenum == AS_PROGRAM) - spacenum = i386_translate_address(intention, &address, nullptr) ? AS_PROGRAM : AS_INVALID; + ret = i386_translate_address(intention, &address, nullptr); address &= m_a20_mask; - return spacenum; + return ret; } 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 4712bdfffad..3701f6c6704 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 int memory_translate(int spacenum, int intention, offs_t &address) const override; + virtual bool memory_translate(int spacenum, int intention, offs_t &address) 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) const; - bool i386_translate_address(int intention, offs_t *address, vtlb_entry *entry) const; + inline vtlb_entry get_permissions(uint32_t pte, int wp); + bool i386_translate_address(int intention, offs_t *address, vtlb_entry *entry); 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 452af3eb16c..e4a16e5aca6 100644 --- a/src/devices/cpu/i386/i386priv.h +++ b/src/devices/cpu/i386/i386priv.h @@ -380,7 +380,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) const +vtlb_entry i386_device::get_permissions(uint32_t pte, int wp) { vtlb_entry ret = VTLB_READ_ALLOWED | ((pte & 4) ? VTLB_USER_READ_ALLOWED : 0); if(!wp) @@ -390,7 +390,7 @@ vtlb_entry i386_device::get_permissions(uint32_t pte, int wp) const return ret; } -bool i386_device::i386_translate_address(int intention, offs_t *address, vtlb_entry *entry) const +bool i386_device::i386_translate_address(int intention, offs_t *address, vtlb_entry *entry) { 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 8abc3bbf994..c3418b16efc 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 } } -int i80286_cpu_device::memory_translate(int spacenum, int intention, offs_t &address) const +bool i80286_cpu_device::memory_translate(int spacenum, int intention, offs_t &address) { if(spacenum == AS_PROGRAM) address &= m_amask; - return spacenum; + return true; } 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 eb4058d0804..ad2447b78e7 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; - int memory_translate(int spacenum, int intention, offs_t &address) const override; + bool memory_translate(int spacenum, int intention, offs_t &address) 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 71a038435ce..852d3e5807a 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(); } -int m4510_device::memory_translate(int spacenum, int intention, offs_t &address) const +bool m4510_device::memory_translate(int spacenum, int intention, offs_t &address) { if (spacenum == AS_PROGRAM) { address = map(address); } - return spacenum; + return true; } 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 26cd6ec1422..b093c8aeb56 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; - mutable bool nomap; + 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 int memory_translate(int spacenum, int intention, offs_t &address) const override; + virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; - inline uint32_t map(uint16_t adr) const { + inline uint32_t map(uint16_t adr) { 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 3a45bea87f3..776f097967c 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 int memory_translate(int space, int intention, offs_t &address) const override; + virtual bool memory_translate(int space, int intention, offs_t &address) override; }; @@ -596,7 +596,7 @@ public: virtual uint32_t execute_default_irq_vector() const override { return -1; }; - virtual int memory_translate(int space, int intention, offs_t &address) const override; + virtual bool memory_translate(int space, int intention, offs_t &address) 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 945e9aafce5..c4199ecdf15 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); } -int m68000_base_device::memory_translate(int space, int intention, offs_t &address) const +bool m68000_base_device::memory_translate(int space, int intention, offs_t &address) { /* only applies to the program address space and only does something if the MMU's enabled */ { @@ -712,29 +712,28 @@ int m68000_base_device::memory_translate(int space, int intention, offs_t &addre 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 - auto &cpu = const_cast(*this); - uint16_t temp_mmu_tmp_sr = cpu.mmu_tmp_sr; + uint16_t temp_mmu_tmp_sr = 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(&cpu, address, mode, 1); + address = pmmu_translate_addr_with_fc_040(this, address, mode, 1); } else { - address = pmmu_translate_addr_with_fc(&cpu, address, mode, 1); + address = pmmu_translate_addr_with_fc(this, address, mode, 1); } - if ((cpu.mmu_tmp_sr & M68K_MMU_SR_INVALID) != 0) { + if ((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; } - cpu.mmu_tmp_sr = temp_mmu_tmp_sr; + mmu_tmp_sr = temp_mmu_tmp_sr; } } - return space; + return true; } @@ -2628,7 +2627,7 @@ void m68020pmmu_device::device_start() init_cpu_m68020pmmu(); } -int m68020hmmu_device::memory_translate(int space, int intention, offs_t &address) const +bool m68020hmmu_device::memory_translate(int space, int intention, offs_t &address) { /* only applies to the program address space and only does something if the MMU's enabled */ { @@ -2637,7 +2636,7 @@ int m68020hmmu_device::memory_translate(int space, int intention, offs_t &addres address = hmmu_translate_addr(this, address); } } - return space; + return true; } diff --git a/src/devices/cpu/m68000/m68kmmu.h b/src/devices/cpu/m68000/m68kmmu.h index 7ada8fb69b4..d477b31f187 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(const m68000_base_device *m68k, uint32_t addr_in) +static inline uint32_t hmmu_translate_addr(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 3e812f73fc9..d55d26623d1 100644 --- a/src/devices/cpu/mips/mips3.cpp +++ b/src/devices/cpu/mips/mips3.cpp @@ -952,22 +952,17 @@ void mips3_device::device_reset() } -int mips3_device::memory_translate(int spacenum, int intention, offs_t &address) const +bool mips3_device::memory_translate(int spacenum, int intention, offs_t &address) { /* only applies to the program address space */ if (spacenum == AS_PROGRAM) - 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); + { + 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 e7256065baa..6d763c8792b 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 int memory_translate(int spacenum, int intention, offs_t &address) const override; + virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; // device_state_interface overrides virtual void state_export(const device_state_entry &entry) override; @@ -575,7 +575,6 @@ 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 69ab3c2ca3e..a530d026c75 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->translate_address_internal(TRANSLATE_FETCH, desc.physpc)) + if (!m_mips3->memory_translate(AS_PROGRAM, 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 4c808dd9767..dd09cce15e4 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 int memory_translate(int spacenum, int intention, offs_t &address) const override; + virtual bool memory_translate(int spacenum, int intention, offs_t &address) 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) const; + uint32_t ppccom_translate_address_internal(int intention, offs_t &address); 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 737a29e2568..56a7325c460 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) const +uint32_t ppc_device::ppccom_translate_address_internal(int intention, offs_t &address) { 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 -------------------------------------------------*/ -int ppc_device::memory_translate(int spacenum, int intention, offs_t &address) const +bool ppc_device::memory_translate(int spacenum, int intention, offs_t &address) { /* only applies to the program address space */ if (spacenum != AS_PROGRAM) - return spacenum; + return true; /* translation is successful if the internal routine returns 0 or 1 */ - return (ppccom_translate_address_internal(intention, address) <= 1) ? AS_PROGRAM : AS_INVALID; + return (ppccom_translate_address_internal(intention, address) <= 1); } diff --git a/src/devices/cpu/powerpc/ppcfe.cpp b/src/devices/cpu/powerpc/ppcfe.cpp index 2a5967061d5..956fad03374 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->ppccom_translate_address_internal(TRANSLATE_FETCH, desc.physpc) > 1) + if (!m_ppc->memory_translate(AS_PROGRAM, 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/z180/z180.cpp b/src/devices/cpu/z180/z180.cpp index 602d094e0bf..a1dda238c60 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 */ -int z180_device::memory_translate(int spacenum, int intention, offs_t &address) const +bool z180_device::memory_translate(int spacenum, int intention, offs_t &address) { if (spacenum == AS_PROGRAM) { address = MMU_REMAP_ADDR(address); } - return spacenum; + return true; } diff --git a/src/devices/cpu/z180/z180.h b/src/devices/cpu/z180/z180.h index 6c8073cf7de..dca5c963539 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 int memory_translate(int spacenum, int intention, offs_t &address) const override; + virtual bool memory_translate(int spacenum, int intention, offs_t &address) 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 a8d1b93ca15..f3650bdef92 100644 --- a/src/emu/debug/debugcmd.cpp +++ b/src/emu/debug/debugcmd.cpp @@ -41,9 +41,7 @@ const size_t debugger_commands::MAX_GLOBALS = 1000; bool debugger_commands::cheat_address_is_valid(address_space &space, offs_t address) { - 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; + return space.device().memory().translate(space.spacenum(), TRANSLATE_READ, address) && (space.get_write_ptr(address) != nullptr); } @@ -93,7 +91,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, space.device().memory().read_memory(space.spacenum(), address, cheatsys->width, TRANSLATE_READ_DEBUG))); + return cheat_sign_extend(cheatsys, cheat_byte_swap(cheatsys, m_cpu.read_memory(space, address, cheatsys->width, true))); } debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu, debugger_console& console) @@ -1669,10 +1667,9 @@ void debugger_commands::execute_save(int ref, const std::vector &pa } /* now write the data out */ - device_memory_interface &memory = space->device().memory(); for (i = offset; i <= endoffset; i++) { - u8 byte = memory.read_byte(space->spacenum(), i, TRANSLATE_READ_DEBUG); + u8 byte = m_cpu.read_byte(*space, i, true); fwrite(&byte, 1, 1, f); } @@ -1722,13 +1719,12 @@ void debugger_commands::execute_load(int ref, const std::vector &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) - memory.write_byte(space->spacenum(), i, byte, TRANSLATE_WRITE_DEBUG); + m_cpu.write_byte(*space, i, byte, true); } if (!f.good()) @@ -1787,7 +1783,6 @@ void debugger_commands::execute_dump(int ref, const std::vector &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(); @@ -1816,9 +1811,9 @@ void debugger_commands::execute_dump(int ref, const std::vector &pa if (i + j <= endoffset) { offs_t curaddr = i + j; - if (memory.translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr) != AS_INVALID) + if (space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr)) { - u64 value = memory.read_memory(space->spacenum(), i + j, width, TRANSLATE_READ_DEBUG); + u64 value = m_cpu.read_memory(*space, i + j, width, true); util::stream_format(output, " %0*X", width * 2, value); } else @@ -1837,9 +1832,9 @@ void debugger_commands::execute_dump(int ref, const std::vector &pa for (u64 j = 0; j < rowsize && (i + j) <= endoffset; j++) { offs_t curaddr = i + j; - if (memory.translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr) != AS_INVALID) + if (space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr)) { - u8 byte = memory.read_byte(space->spacenum(), i + j, TRANSLATE_READ_DEBUG); + u8 byte = m_cpu.read_byte(*space, i + j, true); util::stream_format(output, "%c", (byte >= 32 && byte < 127) ? byte : '.'); } else @@ -2368,8 +2363,6 @@ void debugger_commands::execute_find(int ref, const std::vector &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; @@ -2380,10 +2373,10 @@ void debugger_commands::execute_find(int ref, const std::vector &pa { switch (data_size[j]) { - 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; + 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; default: /* all other cases are wildcards */ break; } suboffset += data_size[j] & 0x0f; @@ -2411,7 +2404,7 @@ void debugger_commands::execute_dasm(int ref, const std::vector &pa { u64 offset, length, bytes = 1; int minbytes, maxbytes, byteswidth; - address_space *space; + address_space *space, *decrypted_space; FILE *f; int j; @@ -2424,7 +2417,10 @@ void debugger_commands::execute_dasm(int ref, const std::vector &pa return; if (!validate_cpu_space_parameter(params.size() > 4 ? params[4].c_str() : nullptr, AS_PROGRAM, space)) return; - int opcode_spacenum = space->device().memory().has_space(AS_OPCODES) ? AS_OPCODES : space->spacenum(); + if (space->device().memory().has_space(AS_OPCODES)) + decrypted_space = &space->device().memory().space(AS_OPCODES); + else + decrypted_space = space; /* determine the width of the bytes */ device_disasm_interface *dasmintf; @@ -2458,6 +2454,7 @@ void debugger_commands::execute_dasm(int ref, const std::vector &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(); @@ -2468,8 +2465,8 @@ void debugger_commands::execute_dasm(int ref, const std::vector &pa stream_format(output, "%0*X: ", space->logaddrchars(), u32(space->byte_to_address(pcbyte))); /* make sure we can translate the address */ - offs_t tempaddr = pcbyte; - if (space->device().memory().translate(space->spacenum(), TRANSLATE_FETCH_DEBUG, tempaddr) != AS_INVALID) + tempaddr = pcbyte; + if (space->device().memory().translate(space->spacenum(), TRANSLATE_FETCH_DEBUG, tempaddr)) { { u8 opbuf[64], argbuf[64]; @@ -2477,8 +2474,8 @@ void debugger_commands::execute_dasm(int ref, const std::vector &pa /* fetch the bytes up to the maximum */ for (numbytes = 0; numbytes < maxbytes; numbytes++) { - opbuf[numbytes] = space->device().memory().read_opcode(opcode_spacenum, pcbyte + numbytes, 1); - argbuf[numbytes] = space->device().memory().read_opcode(space->spacenum(), pcbyte + numbytes, 1); + opbuf[numbytes] = m_cpu.read_opcode(*decrypted_space, pcbyte + numbytes, 1); + argbuf[numbytes] = m_cpu.read_opcode(*space, pcbyte + numbytes, 1); } /* disassemble the result */ @@ -2491,7 +2488,7 @@ void debugger_commands::execute_dasm(int ref, const std::vector &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, space->device().memory().read_opcode(opcode_spacenum, pcbyte + j, minbytes)); + stream_format(output, "%0*X ", minbytes * 2, m_cpu.read_opcode(*decrypted_space, pcbyte + j, minbytes)); if ((output.tellp() - startdex) < byteswidth) stream_format(output, "%*s", byteswidth - (output.tellp() - startdex), ""); stream_format(output, " "); @@ -2643,10 +2640,13 @@ void debugger_commands::execute_traceflush(int ref, const std::vector ¶ms) { /* validate parameters */ - address_space *space; + address_space *space, *decrypted_space; if (!validate_cpu_space_parameter(!params.empty() ? params[0].c_str() : nullptr, AS_PROGRAM, space)) return; - int opcode_spacenum = space->device().memory().has_space(AS_OPCODES) ? AS_OPCODES : space->spacenum(); + if (space->device().memory().has_space(AS_OPCODES)) + decrypted_space = &space->device().memory().space(AS_OPCODES); + else + decrypted_space = space; 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 u8 opbuf[64], argbuf[64]; for (int numbytes = 0; numbytes < maxbytes; numbytes++) { - opbuf[numbytes] = space->device().memory().read_opcode(opcode_spacenum, pcbyte + numbytes, 1); - argbuf[numbytes] = space->device().memory().read_opcode(space->spacenum(), pcbyte + numbytes, 1); + opbuf[numbytes] = m_cpu.read_opcode(*decrypted_space, pcbyte + numbytes, 1); + argbuf[numbytes] = m_cpu.read_opcode(*space, pcbyte + numbytes, 1); } util::ovectorstream buffer; @@ -2791,7 +2791,7 @@ void debugger_commands::execute_pcatmem(int ref, const std::vector // Get the value of memory at the address const int native_data_width = space->data_width() / 8; - const u64 data = space->device().memory().read_memory(space->spacenum(), space->address_to_byte(address), native_data_width, TRANSLATE_READ_DEBUG); + const u64 data = m_cpu.read_memory(*space, space->address_to_byte(address), native_data_width, true); // Recover the pc & print const int space_num = (int)ref; @@ -2866,6 +2866,7 @@ void debugger_commands::execute_source(int ref, const std::vector & void debugger_commands::execute_map(int ref, const std::vector ¶ms) { address_space *space; + offs_t taddress; u64 address; int intention; @@ -2881,8 +2882,8 @@ void debugger_commands::execute_map(int ref, const std::vector &par for (intention = TRANSLATE_READ_DEBUG; intention <= TRANSLATE_FETCH_DEBUG; intention++) { static const char *const intnames[] = { "Read", "Write", "Fetch" }; - offs_t taddress = space->address_to_byte(address) & space->bytemask(); - if (space->device().memory().translate(space->spacenum(), intention, taddress) != AS_INVALID) + taddress = space->address_to_byte(address) & space->bytemask(); + if (space->device().memory().translate(space->spacenum(), intention, taddress)) { 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 e6f65b7d0c9..46ad9e04683 100644 --- a/src/emu/debug/debugcpu.cpp +++ b/src/emu/debug/debugcpu.cpp @@ -47,9 +47,6 @@ 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) @@ -352,6 +349,408 @@ 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 ***************************************************************************/ @@ -443,9 +842,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 space, u32 address, int size, bool disable_se) +u64 debugger_cpu::expression_read_memory(void *param, const char *name, expression_space spacenum, u32 address, int size, bool disable_se) { - switch (space) + switch (spacenum) { case EXPSPACE_PROGRAM_LOGICAL: case EXPSPACE_DATA_LOGICAL: @@ -462,11 +861,11 @@ u64 debugger_cpu::expression_read_memory(void *param, const char *name, expressi device = get_visible_cpu(); memory = &device->memory(); } - int spacenum = AS_PROGRAM + (space - EXPSPACE_PROGRAM_LOGICAL); - if (memory->has_space(spacenum)) + if (memory->has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL))) { + address_space &space = memory->space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL)); auto dis = m_machine.disable_side_effect(disable_se); - return memory->read_memory(spacenum, memory->space(spacenum).address_to_byte(address), size, TRANSLATE_READ_DEBUG); + return read_memory(space, space.address_to_byte(address), size, true); } break; } @@ -486,11 +885,11 @@ u64 debugger_cpu::expression_read_memory(void *param, const char *name, expressi device = get_visible_cpu(); memory = &device->memory(); } - int spacenum = AS_PROGRAM + (space - EXPSPACE_PROGRAM_PHYSICAL); - if (memory->has_space(spacenum)) + if (memory->has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL))) { + address_space &space = memory->space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL)); auto dis = m_machine.disable_side_effect(disable_se); - return memory->read_memory(spacenum, memory->space(spacenum).address_to_byte(address), size, TRANSLATE_NONE); + return read_memory(space, space.address_to_byte(address), size, false); } break; } @@ -508,7 +907,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), (space == EXPSPACE_OPCODE), address, size); + return expression_read_program_direct(memory->space(AS_PROGRAM), (spacenum == EXPSPACE_OPCODE), address, size); break; } @@ -525,7 +924,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), (space == EXPSPACE_OPCODE), address, size); + return expression_read_program_direct(memory->space(AS_OPCODES), (spacenum == EXPSPACE_OPCODE), address, size); break; } @@ -649,18 +1048,17 @@ 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 space, u32 address, int size, u64 data, bool disable_se) +void debugger_cpu::expression_write_memory(void *param, const char *name, expression_space spacenum, u32 address, int size, u64 data, bool disable_se) { device_t *device = nullptr; device_memory_interface *memory; - switch (space) + switch (spacenum) { 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)) @@ -668,20 +1066,18 @@ void debugger_cpu::expression_write_memory(void *param, const char *name, expres device = get_visible_cpu(); memory = &device->memory(); } - int spacenum = AS_PROGRAM + (space - EXPSPACE_PROGRAM_LOGICAL); - if (memory->has_space(spacenum)) + if (memory->has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL))) { + address_space &space = memory->space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL)); auto dis = m_machine.disable_side_effect(disable_se); - memory->write_memory(spacenum, memory->space(spacenum).address_to_byte(address), data, size, TRANSLATE_WRITE_DEBUG); + write_memory(space, space.address_to_byte(address), data, size, true); } 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)) @@ -689,17 +1085,15 @@ void debugger_cpu::expression_write_memory(void *param, const char *name, expres device = get_visible_cpu(); memory = &device->memory(); } - int spacenum = AS_PROGRAM + (space - EXPSPACE_PROGRAM_PHYSICAL); - if (memory->has_space(spacenum)) + if (memory->has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL))) { + address_space &space = memory->space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL)); auto dis = m_machine.disable_side_effect(disable_se); - memory->write_memory(spacenum, memory->space(spacenum).address_to_byte(address), data, size, TRANSLATE_NONE); + write_memory(space, space.address_to_byte(address), data, size, false); } break; - } - case EXPSPACE_RAMWRITE: - { + case EXPSPACE_RAMWRITE: { if (name != nullptr) device = expression_get_device(name); if (device == nullptr || !device->interface(memory)) @@ -708,12 +1102,11 @@ 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), (space == EXPSPACE_OPCODE), address, size, data); + expression_write_program_direct(memory->space(AS_PROGRAM), (spacenum == 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)) @@ -722,7 +1115,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), (space == EXPSPACE_OPCODE), address, size, data); + expression_write_program_direct(memory->space(AS_OPCODES), (spacenum == EXPSPACE_OPCODE), address, size, data); break; } @@ -789,7 +1182,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; - set_memory_modified(true); + m_memory_modified = true; } } } @@ -847,7 +1240,7 @@ void debugger_cpu::expression_write_memory_region(const char *rgntag, offs_t add { base[BYTE8_XOR_BE(address) & lowmask] = data; } - set_memory_modified(true); + m_memory_modified = true; } } } @@ -2094,7 +2487,7 @@ u32 device_debug::compute_opcode_crc32(offs_t pc) const assert(m_memory != nullptr); // determine the adjusted PC - int opcode_spacenum = m_memory->has_space(AS_OPCODES) ? AS_OPCODES : AS_PROGRAM; + address_space &decrypted_space = m_memory->has_space(AS_OPCODES) ? m_memory->space(AS_OPCODES) : m_memory->space(AS_PROGRAM); address_space &space = m_memory->space(AS_PROGRAM); offs_t pcbyte = space.address_to_byte(pc) & space.bytemask(); @@ -2103,8 +2496,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_memory->read_opcode(opcode_spacenum, pcbyte + numbytes, 1); - argbuf[numbytes] = m_memory->read_opcode(AS_PROGRAM, pcbyte + numbytes, 1); + 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); } u32 numbytes = maxbytes; @@ -2498,7 +2891,7 @@ u32 device_debug::dasm_wrapped(std::string &buffer, offs_t pc) assert(m_memory != nullptr && m_disasm != nullptr); // determine the adjusted PC - int opcode_spacenum = m_memory->has_space(AS_OPCODES) ? AS_OPCODES : AS_PROGRAM; + address_space &decrypted_space = m_memory->has_space(AS_OPCODES) ? m_memory->space(AS_OPCODES) : m_memory->space(AS_PROGRAM); address_space &space = m_memory->space(AS_PROGRAM); offs_t pcbyte = space.address_to_byte(pc) & space.bytemask(); @@ -2507,8 +2900,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_memory->read_opcode(opcode_spacenum, pcbyte + numbytes, 1); - argbuf[numbytes] = m_memory->read_opcode(AS_PROGRAM, pcbyte + numbytes, 1); + 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); } // disassemble to our buffer diff --git a/src/emu/debug/debugcpu.h b/src/emu/debug/debugcpu.h index 09b61633c4b..2ea78c3fe20 100644 --- a/src/emu/debug/debugcpu.h +++ b/src/emu/debug/debugcpu.h @@ -509,6 +509,41 @@ 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 39744721a76..1051365c561 100644 --- a/src/emu/debug/dvdisasm.cpp +++ b/src/emu/debug/dvdisasm.cpp @@ -231,7 +231,6 @@ 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(*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()); @@ -256,8 +255,8 @@ offs_t debug_view_disasm::find_pc_backwards(offs_t targetpc, int numinstrs) while (curpcbyte < fillpcbyte) { fillpcbyte--; - 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); + 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); } // loop until we get past the target instruction @@ -271,7 +270,7 @@ offs_t debug_view_disasm::find_pc_backwards(offs_t targetpc, int numinstrs) // get the disassembly, but only if mapped instlen = 1; - if (memory.translate(source.m_space.spacenum(), TRANSLATE_FETCH, physpcbyte) != AS_INVALID) + if (source.m_space.device().memory().translate(source.m_space.spacenum(), TRANSLATE_FETCH, physpcbyte)) { std::ostringstream dasmbuffer; instlen = source.m_disasmintf->disassemble(dasmbuffer, scanpc, &opbuf[1000 + scanpcbyte - targetpcbyte], &argbuf[1000 + scanpcbyte - targetpcbyte]) & DASMFLAG_LENGTHMASK; @@ -311,14 +310,13 @@ 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(*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, memory.read_opcode(encrypted ? source.m_space.spacenum() : source.m_decrypted_space.spacenum(), pcbyte + byte, granularity)); + 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)); } return ostr.str(); @@ -336,7 +334,6 @@ bool debug_view_disasm::recompute(offs_t pc, int startline, int lines) bool changed = false; const debug_view_disasm_source &source = downcast(*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 @@ -392,15 +389,15 @@ bool debug_view_disasm::recompute(offs_t pc, int startline, int lines) std::ostringstream dasm; int numbytes = 0; offs_t physpcbyte = pcbyte; - if (memory.translate(source.m_space.spacenum(), TRANSLATE_FETCH_DEBUG, physpcbyte) != AS_INVALID) + if (source.m_space.device().memory().translate(source.m_space.spacenum(), TRANSLATE_FETCH_DEBUG, physpcbyte)) { u8 opbuf[64], argbuf[64]; // fetch the bytes up to the maximum for (numbytes = 0; numbytes < maxbytes; numbytes++) { - 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); + 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); } // disassemble the result diff --git a/src/emu/debug/dvmemory.cpp b/src/emu/debug/dvmemory.cpp index bcb694a43fa..a5de89adb30 100644 --- a/src/emu/debug/dvmemory.cpp +++ b/src/emu/debug/dvmemory.cpp @@ -740,25 +740,22 @@ 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; - spacenum = source.m_memintf->translate(spacenum, TRANSLATE_READ_DEBUG, dummyaddr); - ismapped = spacenum != AS_INVALID; + ismapped = source.m_memintf->translate(source.m_space->spacenum(), TRANSLATE_READ_DEBUG, dummyaddr); } data = ~u64(0); if (ismapped) { - int intention = m_no_translation ? TRANSLATE_NONE : TRANSLATE_READ_DEBUG; switch (size) { - 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; + 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; } } return ismapped; @@ -826,16 +823,13 @@ 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: 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; + 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; } return; } diff --git a/src/emu/dimemory.cpp b/src/emu/dimemory.cpp index 287b65dd6e8..43f05f6019c 100644 --- a/src/emu/dimemory.cpp +++ b/src/emu/dimemory.cpp @@ -9,8 +9,6 @@ ***************************************************************************/ #include "emu.h" -#include "debugger.h" -#include "debug/debugcpu.h" //************************************************************************** @@ -199,10 +197,10 @@ void device_memory_interface::dump(FILE *file) const // translation is supported //------------------------------------------------- -int device_memory_interface::memory_translate(int spacenum, int intention, offs_t &address) const +bool device_memory_interface::memory_translate(int spacenum, int intention, offs_t &address) { // by default it maps directly - return spacenum; + return true; } @@ -242,427 +240,3 @@ 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 3bf6f848784..8abc5ff435d 100644 --- a/src/emu/dimemory.h +++ b/src/emu/dimemory.h @@ -27,10 +27,9 @@ 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_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 = 0; // translate for read +constexpr int TRANSLATE_WRITE = 1; // translate for write +constexpr int TRANSLATE_FETCH = 2; // translate for instruction fetch constexpr int TRANSLATE_READ_USER = (TRANSLATE_READ | TRANSLATE_USER_MASK); constexpr int TRANSLATE_WRITE_USER = (TRANSLATE_WRITE | TRANSLATE_USER_MASK); constexpr int TRANSLATE_FETCH_USER = (TRANSLATE_FETCH | TRANSLATE_USER_MASK); @@ -38,7 +37,6 @@ 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) //************************************************************************** @@ -95,20 +93,7 @@ public: address_space &space(int index = 0) const { assert(index >= 0 && index < int(m_addrspace.size()) && m_addrspace[index]); return *m_addrspace[index]; } // address translation - 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); + bool translate(int spacenum, int intention, offs_t &address) { return memory_translate(spacenum, intention, address); } // deliberately ambiguous functions; if you have the memory interface // just use it @@ -138,7 +123,7 @@ protected: virtual space_config_vector memory_space_config() const = 0; // optional operation overrides - virtual int memory_translate(int spacenum, int intention, offs_t &address) const; + virtual bool memory_translate(int spacenum, int intention, offs_t &address); // interface-level overrides virtual void interface_config_complete() override; diff --git a/src/emu/divtlb.cpp b/src/emu/divtlb.cpp index 0b379bc08b4..0689bb9c68a 100644 --- a/src/emu/divtlb.cpp +++ b/src/emu/divtlb.cpp @@ -143,6 +143,7 @@ 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); @@ -161,8 +162,8 @@ bool device_vtlb_interface::vtlb_fill(offs_t address, int intention) } // ask the CPU core to translate for us - offs_t taddress = address; - if (device().memory().translate(m_space, intention, taddress) != m_space) + taddress = address; + if (!device().memory().translate(m_space, intention, taddress)) { #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 d95bfe1c7a5..b2ea5e017d2 100644 --- a/src/frontend/mame/luaengine.cpp +++ b/src/frontend/mame/luaengine.cpp @@ -315,35 +315,33 @@ template T lua_engine::addr_space::log_mem_read(offs_t address) { T mem_content = 0; - int tspacenum = dev.translate(space.spacenum(), TRANSLATE_READ_DEBUG, address); - if (tspacenum == AS_INVALID) + if(!dev.translate(space.spacenum(), TRANSLATE_READ_DEBUG, address)) return 0; - address_space &tspace = space.device().memory().space(tspacenum); - address = tspace.address_to_byte(address); + address = space.address_to_byte(address); switch(sizeof(mem_content) * 8) { case 8: - mem_content = tspace.read_byte(address); + mem_content = space.read_byte(address); break; case 16: if (WORD_ALIGNED(address)) { - mem_content = tspace.read_word(address); + mem_content = space.read_word(address); } else { - mem_content = tspace.read_word_unaligned(address); + mem_content = space.read_word_unaligned(address); } break; case 32: if (DWORD_ALIGNED(address)) { - mem_content = tspace.read_dword(address); + mem_content = space.read_dword(address); } else { - mem_content = tspace.read_dword_unaligned(address); + mem_content = space.read_dword_unaligned(address); } break; case 64: if (QWORD_ALIGNED(address)) { - mem_content = tspace.read_qword(address); + mem_content = space.read_qword(address); } else { - mem_content = tspace.read_qword_unaligned(address); + mem_content = space.read_qword_unaligned(address); } break; default: @@ -361,35 +359,33 @@ T lua_engine::addr_space::log_mem_read(offs_t address) template void lua_engine::addr_space::log_mem_write(offs_t address, T val) { - int tspacenum = dev.translate(space.spacenum(), TRANSLATE_WRITE_DEBUG, address); - if (tspacenum == AS_INVALID) + if(!dev.translate(space.spacenum(), TRANSLATE_WRITE_DEBUG, address)) return; - address_space &tspace = space.device().memory().space(tspacenum); - address = tspace.address_to_byte(address); + address = space.address_to_byte(address); switch(sizeof(val) * 8) { case 8: - tspace.write_byte(address, val); + space.write_byte(address, val); break; case 16: if (WORD_ALIGNED(address)) { - tspace.write_word(address, val); + space.write_word(address, val); } else { - tspace.write_word_unaligned(address, val); + space.write_word_unaligned(address, val); } break; case 32: if (DWORD_ALIGNED(address)) { - tspace.write_dword(address, val); + space.write_dword(address, val); } else { - tspace.write_dword_unaligned(address, val); + space.write_dword_unaligned(address, val); } break; case 64: if (QWORD_ALIGNED(address)) { - tspace.write_qword(address, val); + space.write_qword(address, val); } else { - tspace.write_qword_unaligned(address, val); + space.write_qword_unaligned(address, val); } break; default: diff --git a/src/mame/drivers/chihiro.cpp b/src/mame/drivers/chihiro.cpp index 40795234d2a..dfbd640157d 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 { - device_memory_interface &memory = space.device().memory(); + debugger_cpu &cpu = machine().debugger().cpu(); debugger_console &con = machine().debugger().console(); offs_t addr = (offs_t)address; - if (memory.translate(space.spacenum(), TRANSLATE_READ_DEBUG, addr) != space.spacenum()) + if (!space.device().memory().translate(space.spacenum(), TRANSLATE_READ_DEBUG, addr)) { 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 = memory.read_byte(space.spacenum(), addr, TRANSLATE_READ_DEBUG); + uint32_t opcode = cpu.read_byte(space, addr, true); addr++; - uint32_t op1 = memory.read_dword(space.spacenum(), addr, TRANSLATE_READ_DEBUG); + uint32_t op1 = cpu.read_dword(space, addr, true); addr += 4; - uint32_t op2 = memory.read_dword(space.spacenum(), addr, TRANSLATE_READ_DEBUG); + uint32_t op2 = cpu.read_dword(space, addr, true); addr += 4; char sop1[16]; diff --git a/src/mame/machine/xbox.cpp b/src/mame/machine/xbox.cpp index 506b7f11e82..301620b112c 100644 --- a/src/mame/machine/xbox.cpp +++ b/src/mame/machine/xbox.cpp @@ -69,7 +69,9 @@ void xbox_base_state::find_debug_params(running_machine &mach) void xbox_base_state::dump_string_command(int ref, const std::vector ¶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; @@ -80,16 +82,16 @@ void xbox_base_state::dump_string_command(int ref, const std::vectortranslate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address) == AS_INVALID) + if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) { con.printf("Address is unmapped.\n"); return; } address = (offs_t)addr; - 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); + 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); con.printf("Length %d word\n", length); con.printf("MaximumLength %d word\n", maximumlength); con.printf("Buffer %08X byte* ", buffer); @@ -100,7 +102,7 @@ void xbox_base_state::dump_string_command(int ref, const std::vectorread_byte(AS_PROGRAM, buffer + a, TRANSLATE_READ_DEBUG); + uint8_t c = cpu.read_byte(space, buffer + a, true); con.printf("%c", c); } con.printf("\n"); @@ -108,7 +110,9 @@ void xbox_base_state::dump_string_command(int ref, const std::vector ¶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; @@ -119,26 +123,28 @@ void xbox_base_state::dump_process_command(int ref, const std::vectortranslate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address) == AS_INVALID) + if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) { con.printf("Address is unmapped.\n"); return; } address = (offs_t)addr; - 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)); + 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)); } void xbox_base_state::dump_list_command(int ref, const std::vector ¶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; @@ -159,7 +165,7 @@ void xbox_base_state::dump_list_command(int ref, const std::vector uint64_t start = addr; address = (offs_t)addr; - if (m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address) == AS_INVALID) + if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) { con.printf("Address is unmapped.\n"); return; @@ -178,13 +184,13 @@ void xbox_base_state::dump_list_command(int ref, const std::vector else con.printf("%08X\n", (uint32_t)addr); old = addr; - addr = m_maincpu->read_dword(AS_PROGRAM, address, TRANSLATE_READ_DEBUG); + addr = cpu.read_dword(space, address, true); if (addr == start) break; if (addr == old) break; address = (offs_t)addr; - if (m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address) == AS_INVALID) + if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) break; address = (offs_t)addr; } @@ -192,7 +198,9 @@ void xbox_base_state::dump_list_command(int ref, const std::vector void xbox_base_state::dump_dpc_command(int ref, const std::vector ¶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; @@ -203,25 +211,27 @@ void xbox_base_state::dump_dpc_command(int ref, const std::vector & return; address = (offs_t)addr; - if (m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address) == AS_INVALID) + if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) { con.printf("Address is unmapped.\n"); return; } address = (offs_t)addr; - 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)); + 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)); } void xbox_base_state::dump_timer_command(int ref, const std::vector ¶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; @@ -232,54 +242,58 @@ void xbox_base_state::dump_timer_command(int ref, const std::vector return; address = (offs_t)addr; - if (m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address) == AS_INVALID) + if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) { con.printf("Address is unmapped.\n"); return; } address = (offs_t)addr; - 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)); + 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)); } void xbox_base_state::curthread_command(int ref, const std::vector ¶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) == AS_INVALID) + if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address)) { con.printf("Address is unmapped.\n"); return; } address = (offs_t)fsbase + (offs_t)debugc_bios->parameter[7-1]; - uint32_t kthrd = m_maincpu->read_dword(AS_PROGRAM, address, TRANSLATE_READ_DEBUG); + uint32_t kthrd = cpu.read_dword(space, address, true); con.printf("Current thread is %08X\n", kthrd); address = (offs_t)(kthrd + debugc_bios->parameter[8-1]); - uint32_t topstack = m_maincpu->read_dword(AS_PROGRAM, address, TRANSLATE_READ_DEBUG); + uint32_t topstack = cpu.read_dword(space, address, true); con.printf("Current thread stack top is %08X\n", topstack); address = (offs_t)(kthrd + debugc_bios->parameter[4-1]); - uint32_t tlsdata = m_maincpu->read_dword(AS_PROGRAM, address, TRANSLATE_READ_DEBUG); + uint32_t tlsdata = cpu.read_dword(space, address, true); 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", m_maincpu->read_dword(AS_PROGRAM, address, TRANSLATE_READ_DEBUG)); + con.printf("Current thread function is %08X\n", cpu.read_dword(space, address, true)); } void xbox_base_state::threadlist_command(int ref, const std::vector ¶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"); @@ -287,20 +301,20 @@ void xbox_base_state::threadlist_command(int ref, const std::vector for (int pri = 0; pri < 16; pri++) { uint32_t curr = debugc_bios->parameter[1 - 1] + pri * 8; - uint32_t next = m_maincpu->read_dword(AS_PROGRAM, curr, TRANSLATE_READ_DEBUG); + uint32_t next = cpu.read_dword(space, curr, true); while ((next != curr) && (next != 0)) { uint32_t kthrd = next - debugc_bios->parameter[2 - 1]; - 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 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 function; if (tlsdata == 0) - function = m_maincpu->read_dword(AS_PROGRAM, topstack - debugc_bios->parameter[5 - 1] - debugc_bios->parameter[6 - 1], TRANSLATE_READ_DEBUG); + function = cpu.read_dword(space, topstack - debugc_bios->parameter[5 - 1] - debugc_bios->parameter[6 - 1], true); else - function = m_maincpu->read_dword(AS_PROGRAM, tlsdata - debugc_bios->parameter[6 - 1], TRANSLATE_READ_DEBUG); + function = cpu.read_dword(space, tlsdata - debugc_bios->parameter[6 - 1], true); con.printf(" %02d %08x %08x %08x\n", pri, kthrd, topstack, function); - next = m_maincpu->read_dword(AS_PROGRAM, next, TRANSLATE_READ_DEBUG); + next = cpu.read_dword(space, next, true); } } } @@ -408,7 +422,7 @@ void xbox_base_state::vprogdis_command(int ref, const std::vector & if (type == 1) { offs_t addr = (offs_t)address; - if (m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, addr) != AS_PROGRAM) + if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, addr)) return; instruction[0] = space.read_dword_unaligned(address); instruction[1] = space.read_dword_unaligned(address + 4);