diff options
author | mooglyguy <therealmogminer@gmail.com> | 2018-01-13 21:59:19 +0100 |
---|---|---|
committer | mooglyguy <therealmogminer@gmail.com> | 2018-01-13 22:13:38 +0100 |
commit | 1905584a6b020a3815159660551d9c41d1b483b2 (patch) | |
tree | 28a47935fc1dba74d1cd740628a53d36e3287bd0 | |
parent | 7f3f8fd245bafd66892fc3adf07aff9d009d0381 (diff) |
-gba: Use correct initial mapping for movie cartridges. Fixes v_sharkt, v_shrek, v_shrek2, probably others. [endrift, Ryan Holtz]
-rw-r--r-- | src/devices/bus/gba/gba_slot.cpp | 16 | ||||
-rw-r--r-- | src/devices/bus/gba/gba_slot.h | 2 | ||||
-rw-r--r-- | src/devices/bus/gba/rom.cpp | 12 | ||||
-rw-r--r-- | src/devices/bus/pce/pce_slot.cpp | 9 | ||||
-rw-r--r-- | src/devices/bus/pce/pce_slot.h | 2 | ||||
-rw-r--r-- | src/devices/cpu/arm7/arm7fe.hxx | 458 |
6 files changed, 473 insertions, 26 deletions
diff --git a/src/devices/bus/gba/gba_slot.cpp b/src/devices/bus/gba/gba_slot.cpp index 07af56d800a..0e926ff1d91 100644 --- a/src/devices/bus/gba/gba_slot.cpp +++ b/src/devices/bus/gba/gba_slot.cpp @@ -671,7 +671,14 @@ image_init_result gba_cart_slot_device::call_load() break; } if (size == 0x4000000) + { memcpy((uint8_t *)m_cart->get_romhlp_base(), ROM, 0x2000000); + for (uint32_t i = 0; i < 16; i++) + { + memcpy((uint8_t *)m_cart->get_romhlp_base() + i * 0x1000, ROM + 0x200, 0x1000); + } + memcpy((uint8_t *)m_cart->get_romhlp_base(), ROM, 0x180); + } if (m_cart->get_nvram_size()) battery_load(m_cart->get_nvram_base(), m_cart->get_nvram_size(), 0x00); @@ -934,12 +941,3 @@ WRITE32_MEMBER(gba_cart_slot_device::write_gpio) if (m_cart) m_cart->write_gpio(space, offset, data, mem_mask); } - - -/*------------------------------------------------- - Internal header logging - -------------------------------------------------*/ - -void gba_cart_slot_device::internal_header_logging(uint8_t *ROM, uint32_t len) -{ -} diff --git a/src/devices/bus/gba/gba_slot.h b/src/devices/bus/gba/gba_slot.h index d2c042b3ba9..c946fd71c57 100644 --- a/src/devices/bus/gba/gba_slot.h +++ b/src/devices/bus/gba/gba_slot.h @@ -98,8 +98,6 @@ public: int get_type() { return m_type; } static int get_cart_type(const uint8_t *ROM, uint32_t len); - void internal_header_logging(uint8_t *ROM, uint32_t len); - void save_nvram() { if (m_cart && m_cart->get_nvram_size()) m_cart->save_nvram(); } uint32_t get_rom_size() { if (m_cart) return m_cart->get_rom_size(); return 0; } diff --git a/src/devices/bus/gba/rom.cpp b/src/devices/bus/gba/rom.cpp index dcf8bb2d1aa..c8e938daa73 100644 --- a/src/devices/bus/gba/rom.cpp +++ b/src/devices/bus/gba/rom.cpp @@ -728,25 +728,29 @@ void gba_rom_boktai_device::gpio_dev_write(uint16_t data, int gpio_dirs) WRITE32_MEMBER(gba_rom_3dmatrix_device::write_mapper) { - //printf("mapper write 0x%.8X - 0x%X\n", offset, data); + //printf("mapper write 0x%.8X - 0x%X\n", offset, data); fflush(stdout); switch (offset & 3) { case 0: - if (data == 0x1) // transfer data + //printf("command: %08x\n", data); fflush(stdout); + if (data & 0x01) // transfer data memcpy((uint8_t *)m_romhlp + m_dst, (uint8_t *)m_rom + m_src, m_nblock * 0x200); else printf("Unknown mapper command 0x%X\n", data); break; case 1: - m_src = data; + //printf("m_src: %08x\n", data); fflush(stdout); + m_src = data & 0x3ffffff; break; case 2: + //printf("m_dst: %08x\n", data); fflush(stdout); if (data >= 0xa000000) - printf("Unknown transfer destination 0x%X\n", data); + printf("Unknown transfer destination 0x%X\n", data); fflush(stdout); m_dst = (data & 0x1ffffff); break; case 3: default: + //printf("m_nblock: %08x\n", data); fflush(stdout); m_nblock = data; break; } diff --git a/src/devices/bus/pce/pce_slot.cpp b/src/devices/bus/pce/pce_slot.cpp index 973d2c58759..912a8cf8c59 100644 --- a/src/devices/bus/pce/pce_slot.cpp +++ b/src/devices/bus/pce/pce_slot.cpp @@ -358,12 +358,3 @@ WRITE8_MEMBER(pce_cart_slot_device::write_cart) if (m_cart) m_cart->write_cart(space, offset, data); } - - -/*------------------------------------------------- - Internal header logging - -------------------------------------------------*/ - -void pce_cart_slot_device::internal_header_logging(uint8_t *ROM, uint32_t len) -{ -} diff --git a/src/devices/bus/pce/pce_slot.h b/src/devices/bus/pce/pce_slot.h index 77d5a82d0b3..658384cb82b 100644 --- a/src/devices/bus/pce/pce_slot.h +++ b/src/devices/bus/pce/pce_slot.h @@ -79,8 +79,6 @@ public: int get_type() { return m_type; } static int get_cart_type(const uint8_t *ROM, uint32_t len); - void internal_header_logging(uint8_t *ROM, uint32_t len); - void set_intf(const char * interface) { m_interface = interface; } virtual iodevice_t image_type() const override { return IO_CARTSLOT; } diff --git a/src/devices/cpu/arm7/arm7fe.hxx b/src/devices/cpu/arm7/arm7fe.hxx new file mode 100644 index 00000000000..9fcb97776aa --- /dev/null +++ b/src/devices/cpu/arm7/arm7fe.hxx @@ -0,0 +1,458 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/*************************************************************************** + + arm7fe.c + + Front-end for ARM7 DRC + +***************************************************************************/ + +#include "emu.h" +#include "arm7.h" + + +//************************************************************************** +// ARM7 FRONTEND +//************************************************************************** + +// register flags 0 +#define REGFLAG_R(n) (((n) == 0) ? 0 : (1 << (n))) + +//------------------------------------------------- +// arm7_frontend - constructor +//------------------------------------------------- + +arm7_frontend::arm7_frontend(arm7_cpu_device *arm7, uint32_t window_start, uint32_t window_end, uint32_t max_sequence) + : drc_frontend(*arm7, window_start, window_end, max_sequence), + m_arm7(arm7) +{ +} + + +//------------------------------------------------- +// describe_thumb - build a description of a +// thumb instruction +//------------------------------------------------- + +bool arm7_frontend::describe_thumb(opcode_desc &desc, const opcode_desc *prev) +{ + return false; +} + +//------------------------------------------------- +// describe_ops_* - build a description of +// an ARM7 instruction +//------------------------------------------------- + +bool arm7_frontend::describe_ops_0123(opcode_desc &desc, const opcode_desc *prev, uint32_t op) +{ + /* Branch and Exchange (BX) */ + if ((op & 0x0ffffff0) == 0x012fff10) // BX + { + } + else if ((op & 0x0ff000f0) == 0x01600010) // CLZ - v5 + { + } + else if ((op & 0x0ff000f0) == 0x01000050) // QADD - v5 + { + } + else if ((op & 0x0ff000f0) == 0x01400050) // QDADD - v5 + { + } + else if ((op & 0x0ff000f0) == 0x01200050) // QSUB - v5 + { + } + else if ((op & 0x0ff000f0) == 0x01600050) // QDSUB - v5 + { + } + else if ((op & 0x0ff00090) == 0x01000080) // SMLAxy - v5 + { + } + else if ((op & 0x0ff00090) == 0x01400080) // SMLALxy - v5 + { + } + else if ((op & 0x0ff00090) == 0x01600080) // SMULxy - v5 + { + } + else if ((op & 0x0ff000b0) == 0x012000a0) // SMULWy - v5 + { + } + else if ((op & 0x0ff000b0) == 0x01200080) // SMLAWy - v5 + { + } + else if ((op & 0x0e000000) == 0 && (op & 0x80) && (op & 0x10)) // Multiply OR Swap OR Half Word Data Transfer + { + if (op & 0x60) // Half Word Data Transfer + { + //HandleHalfWordDT(op); + } + else if (op & 0x01000000) // Swap + { + //HandleSwap(op); + } + else // Multiply Or Multiply Long + { + if (op & 0x800000) // Multiply long + { + if (op & 0x00400000) // Signed multiply + { + //HandleSMulLong(op); + } + else // Unsigned multiply + { + //HandleUMulLong(op); + } + } + else // Multiply + { + //HandleMul(op);// + } + } + } + else if ((op & 0x0c000000) == 0) // Data Processing OR PSR Transfer + { + if (((op & 0x00100000) == 0) && ((op & 0x01800000) == 0x01000000)) // PSR Transfer + + { + //HandlePSRTransfer(insn); + desc.cycles = 1; + } + else // Data processing + { + //HandleALU(insn); + } + } + return true; +} + +bool arm7_frontend::describe_ops_4567(opcode_desc &desc, const opcode_desc *prev, uint32_t op) +{ + if (op & INSN_I) + { + /* Register Shift */ + //off = decodeShift(op, nullptr); + } + else + { + /* Immediate Value */ + //off = op & INSN_SDT_IMM; + } + + uint32_t rn = (op & INSN_RN) >> INSN_RN_SHIFT; + + if (op & INSN_SDT_P) + { + /* Pre-indexed addressing */ + if ((get_mode32()) || (rn != eR15)) + { + //rnv = (GetRegister(rn) + off); + } + else + { + //rnv = (GET_PC + off); + } + + if (op & INSN_SDT_W) + { + //rnv_old = GetRegister(rn); + //SetRegister(rn, rnv); + } + else if (rn == eR15) + { + //rnv = rnv + 8; + } + } + else + { + /* Post-indexed addressing */ + if (rn == eR15) + { + if (get_mode32()) + { + //rnv = R15 + 8; + } + else + { + //rnv = GET_PC + 8; + } + } + else + { + //rnv = GetRegister(rn); + } + } + + /* Do the transfer */ + uint32_t rd = (op & INSN_RD) >> INSN_RD_SHIFT; + if (op & INSN_SDT_L) + { + /* Load */ + if (op & INSN_SDT_B) + { + //uint32_t data = READ8(rnv); + //SetRegister(rd, data); + } + else + { + //uint32_t data = READ32(rnv); + if (rd == eR15) + { + //R15 = data - 4; + // LDR, PC takes 2S + 2N + 1I (5 total cycles) + desc.cycles = 5; + } + else + { + //SetRegister(rd, data); + } + } + } + else + { + /* Store */ + if (op & INSN_SDT_B) + { + //WRITE8(rnv, (uint8_t) GetRegister(rd) & 0xffu); + } + else + { + //WRITE32(rnv, rd == eR15 ? R15 + 8 + 4 : GetRegister(rd)); // manual says STR rd = PC, +12 + } + // Store takes only 2 N Cycles, so add + 1 + desc.cycles = 2; + } + + /* Do post-indexing writeback */ + if (!(op & INSN_SDT_P)/* && (insn & INSN_SDT_W)*/) + { + if (rd == rn) { + //SetRegister(rn, GetRegister(rd)); + } + else { + //SetRegister(rn, (rnv +/- off)); + } + } + return true; +} + +bool arm7_frontend::describe_ops_89(opcode_desc &desc, const opcode_desc *prev, uint32_t op) +{ + if ((op & 0x005f0f00) == 0x004d0500) + { + // unsupported (armv6 onwards only) + //arm9ops_undef(insn); + //R15 += 4; + } + else if ((op & 0x00500f00) == 0x00100a00) /* Return From Exception (RFE) */ + { + // unsupported (armv6 onwards only) + //arm9ops_undef(insn); + //R15 += 4; + } + else + { + //arm9ops_undef(insn); + //R15 += 4; + } + return false; +} + +bool arm7_frontend::describe_ops_ab(opcode_desc &desc, const opcode_desc *prev, uint32_t op) +{ + // BLX + //HandleBranch(insn, true); + //set_cpsr(GET_CPSR|T_MASK); + return true; +} + +bool arm7_frontend::describe_ops_cd(opcode_desc &desc, const opcode_desc *prev, uint32_t op) +{ + /* Additional coprocessor double register transfer */ + if ((op & 0x00e00000) == 0x00400000) + { + // unsupported + //arm9ops_undef(insn); + //R15 += 4; + } + else + { + //arm9ops_undef(insn); + //R15 += 4; + } + return false; +} + +bool arm7_frontend::describe_ops_e(opcode_desc &desc, const opcode_desc *prev, uint32_t op) +{ + /* Additional coprocessor register transfer */ + // unsupported + //arm9ops_undef(insn); + //R15 += 4; + return false; +} + +bool arm7_frontend::describe_ops_f(opcode_desc &desc, const opcode_desc *prev, uint32_t op) +{ + return false; +} + +//------------------------------------------------- +// describe_arm9_ops_* - build a description of +// an ARM9 instruction +//------------------------------------------------- + +bool describe_arm9_ops_1(opcode_desc &desc, const opcode_desc *prev, uint32_t op) +{ + /* Change processor state (CPS) */ + if ((op & 0x00f10020) == 0x00000000) + { + // unsupported (armv6 onwards only) + //arm9ops_undef(insn); + //R15 += 4; + } + else if ((op & 0x00ff00f0) == 0x00010000) /* set endianness (SETEND) */ + { + // unsupported (armv6 onwards only) + //arm9ops_undef(insn); + //R15 += 4; + } + else + { + //arm9ops_undef(insn); + //R15 += 4; + } + return false; +} + +bool describe_arm9_ops_57(opcode_desc &desc, const opcode_desc *prev, uint32_t op) +{ + /* Cache Preload (PLD) */ + if ((op & 0x0070f000) == 0x0050f000) + { + // unsupported (armv6 onwards only) + //arm9ops_undef(insn); + //R15 += 4; + } + else + { + //arm9ops_undef(insn); + //R15 += 4; + } + return false; +} + +bool describe_arm9_ops_89(opcode_desc &desc, const opcode_desc *prev, uint32_t op) +{ + return false; +} + +bool describe_arm9_ops_ab(opcode_desc &desc, const opcode_desc *prev, uint32_t op) +{ + return false; +} + +bool describe_arm9_ops_c(opcode_desc &desc, const opcode_desc *prev, uint32_t op) +{ + return false; +} + +bool describe_arm9_ops_e(opcode_desc &desc, const opcode_desc *prev, uint32_t op) +{ + return false; +} + + +uint32_t arm7_frontend::get_cpsr() +{ + return m_arm7->m_r[eCPSR]; +} + +bool arm7_frontend::get_mode32() +{ + return m_arm7->m_r[eCPSR] & SR_MODE32; +} + +//------------------------------------------------- +// describe - build a description of a single +// instruction +//------------------------------------------------- + +bool arm7_frontend::describe(opcode_desc &desc, const opcode_desc *prev) +{ + // compute the physical PC + const uint32_t cpsr = get_cpsr(); + assert((desc.physpc & (T_IS_SET(cpsr) ? 1 : 3)) == 0); + if (!m_arm7->arm7_tlb_translate(desc.physpc, ARM7_TLB_ABORT_P | ARM7_TLB_READ)) + { + // 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 + desc.flags |= OPFLAG_VALIDATE_TLB | OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_COMPILER_PAGE_FAULT | OPFLAG_VIRTUAL_NOOP | OPFLAG_END_SEQUENCE; + return true; + } + + if (T_IS_SET(cpsr)) + { + return describe_thumb(desc, prev); + } + + // fetch the opcode + uint32_t op = desc.opptr.l[0] = m_arm7->m_direct->read_dword(desc.physpc); + + // all non-THUMB instructions are 4 bytes and default to 3 cycles each + desc.length = 4; + desc.cycles = 3; + + // parse the instruction + + int op_offset = 0; + if ((op >> INSN_COND_SHIFT) == COND_NV && m_arm7->m_archRev >= 5) + { + op_offset = 0x10; + } + + switch (((op & 0xF000000) >> 24) + op_offset) + { + case 0x0: case 0x1: case 0x2: case 0x3: + return describe_ops_0123(desc, prev, op); + + case 0x4: case 0x5: case 0x6: case 0x7: + return describe_ops_4567(desc, prev, op); + + case 0x8: case 0x9: + return describe_ops_89(desc, prev, op); + + case 0xa: case 0xb: + return describe_ops_ab(desc, prev, op); + + case 0xc: case 0xd: + return describe_ops_cd(desc, prev, op); + + case 0xe: + return describe_ops_e(desc, prev, op); + + case 0xf: + return describe_ops_f(desc, prev, op); + + case 0x11: // ARM9 + return describe_arm9_ops_1(desc, prev, op); + + case 0x15: case 0x17: // ARM9 + return describe_arm9_ops_57(desc, prev, op); + + case 0x18: case 0x19: // ARM9 + return describe_arm9_ops_89(desc, prev, op); + + case 0x1a: case 0x1b: // ARM9 + return describe_arm9_ops_ab(desc, prev, op); + + case 0x1c: // ARM9 + return describe_arm9_ops_c(desc, prev, op); + + case 0x1e: // ARM9 + return describe_arm9_ops_e(desc, prev, op); + + default: + return false; + } +} |