X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=source%2Fmupen64plus-core%2Fsrc%2Fmemory%2Fdma.c;fp=source%2Fmupen64plus-core%2Fsrc%2Fmemory%2Fdma.c;h=8d606d40e4d430f704ea99055ea42adabab1ee54;hb=451ab91e3827a6384981b3300e2a7000d2eaba58;hp=0000000000000000000000000000000000000000;hpb=a2ab25365b5b0dddbee476d695d8a31151407581;p=mupen64plus-pandora.git diff --git a/source/mupen64plus-core/src/memory/dma.c b/source/mupen64plus-core/src/memory/dma.c new file mode 100644 index 0000000..8d606d4 --- /dev/null +++ b/source/mupen64plus-core/src/memory/dma.c @@ -0,0 +1,380 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Mupen64plus - dma.c * + * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * + * Copyright (C) 2002 Hacktarux * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include +#include +#include + +#include "api/m64p_types.h" + +#include "dma.h" +#include "memory.h" +#include "pif.h" +#include "flashram.h" + +#include "r4300/r4300.h" +#include "r4300/interupt.h" +#include "r4300/macros.h" +#include "r4300/ops.h" +#include "../r4300/new_dynarec/new_dynarec.h" + +#define M64P_CORE_PROTOTYPES 1 +#include "api/m64p_config.h" +#include "api/config.h" +#include "api/callbacks.h" +#include "main/main.h" +#include "main/rom.h" +#include "main/util.h" + +static unsigned char sram[0x8000]; + +static char *get_sram_path(void) +{ + return formatstr("%s%s.sra", get_savesrampath(), ROM_SETTINGS.goodname); +} + +static void sram_format(void) +{ + memset(sram, 0, sizeof(sram)); +} + +static void sram_read_file(void) +{ + char *filename = get_sram_path(); + + sram_format(); + switch (read_from_file(filename, sram, sizeof(sram))) + { + case file_open_error: + DebugMessage(M64MSG_VERBOSE, "couldn't open sram file '%s' for reading", filename); + sram_format(); + break; + case file_read_error: + DebugMessage(M64MSG_WARNING, "fread() failed on 32kb read from sram file '%s'", filename); + sram_format(); + break; + default: break; + } + + free(filename); +} + +static void sram_write_file(void) +{ + char *filename = get_sram_path(); + + switch (write_to_file(filename, sram, sizeof(sram))) + { + case file_open_error: + DebugMessage(M64MSG_WARNING, "couldn't open sram file '%s' for writing.", filename); + break; + case file_write_error: + DebugMessage(M64MSG_WARNING, "fwrite() failed on 32kb write to sram file '%s'", filename); + break; + default: break; + } + + free(filename); +} + +void dma_pi_read(void) +{ + unsigned int i; + + if (pi_register.pi_cart_addr_reg >= 0x08000000 + && pi_register.pi_cart_addr_reg < 0x08010000) + { + if (flashram_info.use_flashram != 1) + { + sram_read_file(); + + for (i=0; i < (pi_register.pi_rd_len_reg & 0xFFFFFF)+1; i++) + { + sram[((pi_register.pi_cart_addr_reg-0x08000000)+i)^S8] = + ((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8]; + } + + sram_write_file(); + + flashram_info.use_flashram = -1; + } + else + { + dma_write_flashram(); + } + } + else + { + DebugMessage(M64MSG_WARNING, "Unknown dma read in dma_pi_read()"); + } + + pi_register.read_pi_status_reg |= 1; + update_count(); + add_interupt_event(PI_INT, 0x1000/*pi_register.pi_rd_len_reg*/); +} + +void dma_pi_write(void) +{ + unsigned int longueur; + int i; + + if (pi_register.pi_cart_addr_reg < 0x10000000) + { + if (pi_register.pi_cart_addr_reg >= 0x08000000 + && pi_register.pi_cart_addr_reg < 0x08010000) + { + if (flashram_info.use_flashram != 1) + { + int i; + + sram_read_file(); + + for (i=0; i<(int)(pi_register.pi_wr_len_reg & 0xFFFFFF)+1; i++) + { + ((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8]= + sram[(((pi_register.pi_cart_addr_reg-0x08000000)&0xFFFF)+i)^S8]; + } + + flashram_info.use_flashram = -1; + } + else + { + dma_read_flashram(); + } + } + else if (pi_register.pi_cart_addr_reg >= 0x06000000 + && pi_register.pi_cart_addr_reg < 0x08000000) + { + } + else + { + DebugMessage(M64MSG_WARNING, "Unknown dma write 0x%x in dma_pi_write()", (int)pi_register.pi_cart_addr_reg); + } + + pi_register.read_pi_status_reg |= 1; + update_count(); + add_interupt_event(PI_INT, /*pi_register.pi_wr_len_reg*/0x1000); + + return; + } + + if (pi_register.pi_cart_addr_reg >= 0x1fc00000) // for paper mario + { + pi_register.read_pi_status_reg |= 1; + update_count(); + add_interupt_event(PI_INT, 0x1000); + + return; + } + + longueur = (pi_register.pi_wr_len_reg & 0xFFFFFF)+1; + i = (pi_register.pi_cart_addr_reg-0x10000000)&0x3FFFFFF; + longueur = (i + (int) longueur) > rom_size ? + (rom_size - i) : longueur; + longueur = (pi_register.pi_dram_addr_reg + longueur) > 0x7FFFFF ? + (0x7FFFFF - pi_register.pi_dram_addr_reg) : longueur; + + if (i>rom_size || pi_register.pi_dram_addr_reg > 0x7FFFFF) + { + pi_register.read_pi_status_reg |= 3; + update_count(); + add_interupt_event(PI_INT, longueur/8); + + return; + } + + if (r4300emu != CORE_PURE_INTERPRETER) + { + for (i=0; i<(int)longueur; i++) + { + unsigned long rdram_address1 = pi_register.pi_dram_addr_reg+i+0x80000000; + unsigned long rdram_address2 = pi_register.pi_dram_addr_reg+i+0xa0000000; + ((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8]= + rom[(((pi_register.pi_cart_addr_reg-0x10000000)&0x3FFFFFF)+i)^S8]; + + if (!invalid_code[rdram_address1>>12]) + { + if (!blocks[rdram_address1>>12] || + blocks[rdram_address1>>12]->block[(rdram_address1&0xFFF)/4].ops != + current_instruction_table.NOTCOMPILED) + { + invalid_code[rdram_address1>>12] = 1; + } +#ifdef NEW_DYNAREC + invalidate_block(rdram_address1>>12); +#endif + } + if (!invalid_code[rdram_address2>>12]) + { + if (!blocks[rdram_address1>>12] || + blocks[rdram_address2>>12]->block[(rdram_address2&0xFFF)/4].ops != + current_instruction_table.NOTCOMPILED) + { + invalid_code[rdram_address2>>12] = 1; + } + } + } + } + else + { + for (i=0; i<(int)longueur; i++) + { + ((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8]= + rom[(((pi_register.pi_cart_addr_reg-0x10000000)&0x3FFFFFF)+i)^S8]; + } + } + + // Set the RDRAM memory size when copying main ROM code + // (This is just a convenient way to run this code once at the beginning) + if (pi_register.pi_cart_addr_reg == 0x10001000) + { + switch (CIC_Chip) + { + case 1: + case 2: + case 3: + case 6: + { + if (ConfigGetParamInt(g_CoreConfig, "DisableExtraMem")) + { + rdram[0x318/4] = 0x400000; + } + else + { + rdram[0x318/4] = 0x800000; + } + break; + } + case 5: + { + if (ConfigGetParamInt(g_CoreConfig, "DisableExtraMem")) + { + rdram[0x3F0/4] = 0x400000; + } + else + { + rdram[0x3F0/4] = 0x800000; + } + break; + } + } + } + + pi_register.read_pi_status_reg |= 3; + update_count(); + add_interupt_event(PI_INT, longueur/8); + + return; +} + +void dma_sp_write(void) +{ + unsigned int i,j; + + unsigned int l = sp_register.sp_rd_len_reg; + + unsigned int length = ((l & 0xfff) | 7) + 1; + unsigned int count = ((l >> 12) & 0xff) + 1; + unsigned int skip = ((l >> 20) & 0xfff); + + unsigned int memaddr = sp_register.sp_mem_addr_reg & 0xfff; + unsigned int dramaddr = sp_register.sp_dram_addr_reg & 0xffffff; + + unsigned char *spmem = ((sp_register.sp_mem_addr_reg & 0x1000) != 0) ? (unsigned char*)SP_IMEM : (unsigned char*)SP_DMEM; + unsigned char *dram = (unsigned char*)rdram; + + for(j=0; j> 12) & 0xff) + 1; + unsigned int skip = ((l >> 20) & 0xfff); + + unsigned int memaddr = sp_register.sp_mem_addr_reg & 0xfff; + unsigned int dramaddr = sp_register.sp_dram_addr_reg & 0xffffff; + + unsigned char *spmem = ((sp_register.sp_mem_addr_reg & 0x1000) != 0) ? (unsigned char*)SP_IMEM : (unsigned char*)SP_DMEM; + unsigned char *dram = (unsigned char*)rdram; + + for(j=0; j