X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=source%2Fmupen64plus-core%2Fsrc%2Fmemory%2Fmemory.c;fp=source%2Fmupen64plus-core%2Fsrc%2Fmemory%2Fmemory.c;h=caf65a0e9af99103565e1c86817f771e92272823;hb=451ab91e3827a6384981b3300e2a7000d2eaba58;hp=0000000000000000000000000000000000000000;hpb=a2ab25365b5b0dddbee476d695d8a31151407581;p=mupen64plus-pandora.git diff --git a/source/mupen64plus-core/src/memory/memory.c b/source/mupen64plus-core/src/memory/memory.c new file mode 100644 index 0000000..caf65a0 --- /dev/null +++ b/source/mupen64plus-core/src/memory/memory.c @@ -0,0 +1,3719 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Mupen64plus - memory.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 + +#if !defined(WIN32) +#include +#endif + +#include "api/m64p_types.h" + +#include "memory.h" +#include "dma.h" +#include "pif.h" +#include "flashram.h" + +#include "r4300/r4300.h" +#include "r4300/macros.h" +#include "r4300/interupt.h" +#include "r4300/recomph.h" +#include "r4300/ops.h" + +#include "api/callbacks.h" +#include "main/main.h" +#include "main/rom.h" +#include "osal/preproc.h" +#include "plugin/plugin.h" +#include "r4300/new_dynarec/new_dynarec.h" + +#ifdef DBG +#include "debugger/dbg_types.h" +#include "debugger/dbg_memory.h" +#include "debugger/dbg_breakpoints.h" +#endif + +/* definitions of the rcp's structures and memory area */ +RDRAM_register rdram_register; +mips_register MI_register; +PI_register pi_register; +SP_register sp_register; +RSP_register rsp_register; +SI_register si_register; +VI_register vi_register; +RI_register ri_register; +AI_register ai_register; +DPC_register dpc_register; +DPS_register dps_register; + +ALIGN(16, unsigned int rdram[0x800000/4]); + +unsigned char *rdramb = (unsigned char *)(rdram); +unsigned int SP_DMEM[0x1000/4*2]; +unsigned int *SP_IMEM = SP_DMEM+0x1000/4; +unsigned char *SP_DMEMb = (unsigned char *)(SP_DMEM); +unsigned char *SP_IMEMb = (unsigned char*)(SP_DMEM+0x1000/4); +unsigned int PIF_RAM[0x40/4]; +unsigned char *PIF_RAMb = (unsigned char *)(PIF_RAM); + +#if NEW_DYNAREC != NEW_DYNAREC_ARM +// address : address of the read/write operation being done +unsigned int address = 0; +#endif +// *address_low = the lower 16 bit of the address : +#ifdef M64P_BIG_ENDIAN +static unsigned short *address_low = (unsigned short *)(&address)+1; +#else +static unsigned short *address_low = (unsigned short *)(&address); +#endif + +// values that are being written are stored in these variables +#if NEW_DYNAREC != NEW_DYNAREC_ARM +unsigned int word; +unsigned char cpu_byte; +unsigned short hword; +unsigned long long int dword; +#endif + +// addresse where the read value will be stored +unsigned long long int* rdword; + +// trash : when we write to unmaped memory it is written here +static unsigned int trash; + +// hash tables of read functions +void (*readmem[0x10000])(void); +void (*readmemb[0x10000])(void); +void (*readmemh[0x10000])(void); +void (*readmemd[0x10000])(void); + +// hash tables of write functions +void (*writemem[0x10000])(void); +void (*writememb[0x10000])(void); +void (*writememd[0x10000])(void); +void (*writememh[0x10000])(void); + +// memory sections +unsigned int *readrdramreg[0x10000]; +unsigned int *readrspreg[0x10000]; +unsigned int *readrsp[0x10000]; +unsigned int *readmi[0x10000]; +unsigned int *readvi[0x10000]; +unsigned int *readai[0x10000]; +unsigned int *readpi[0x10000]; +unsigned int *readri[0x10000]; +unsigned int *readsi[0x10000]; +unsigned int *readdp[0x10000]; +unsigned int *readdps[0x10000]; + +// the frameBufferInfos +static FrameBufferInfo frameBufferInfos[6]; +static char framebufferRead[0x800]; +static int firstFrameBufferSetting; + +// uncomment to output count of calls to write_rdram(): +//#define COUNT_WRITE_RDRAM_CALLS 1 + +#if defined( COUNT_WRITE_RDRAM_CALLS ) + int writerdram_count = 1; +#endif + +int init_memory(int DoByteSwap) +{ + int i; + + if (DoByteSwap != 0) + { + //swap rom + unsigned int *roml = (unsigned int *) rom; + for (i=0; i<(rom_size/4); i++) roml[i] = sl(roml[i]); + } + + //init hash tables + for (i=0; i<(0x10000); i++) + { + readmem[i] = read_nomem; + readmemb[i] = read_nomemb; + readmemd[i] = read_nomemd; + readmemh[i] = read_nomemh; + writemem[i] = write_nomem; + writememb[i] = write_nomemb; + writememd[i] = write_nomemd; + writememh[i] = write_nomemh; + } + + //init RDRAM + for (i=0; i<(0x800000/4); i++) rdram[i]=0; + + for (i=0; i> 16); i++) + { + readmem[0x9000+i] = read_rom; + readmem[0xb000+i] = read_rom; + readmemb[0x9000+i] = read_romb; + readmemb[0xb000+i] = read_romb; + readmemh[0x9000+i] = read_romh; + readmemh[0xb000+i] = read_romh; + readmemd[0x9000+i] = read_romd; + readmemd[0xb000+i] = read_romd; + writemem[0x9000+i] = write_nothing; + writemem[0xb000+i] = write_rom; + writememb[0x9000+i] = write_nothingb; + writememb[0xb000+i] = write_nothingb; + writememh[0x9000+i] = write_nothingh; + writememh[0xb000+i] = write_nothingh; + writememd[0x9000+i] = write_nothingd; + writememd[0xb000+i] = write_nothingd; + } + for (i=(rom_size >> 16); i<0xfc0; i++) + { + readmem[0x9000+i] = read_nothing; + readmem[0xb000+i] = read_nothing; + readmemb[0x9000+i] = read_nothingb; + readmemb[0xb000+i] = read_nothingb; + readmemh[0x9000+i] = read_nothingh; + readmemh[0xb000+i] = read_nothingh; + readmemd[0x9000+i] = read_nothingd; + readmemd[0xb000+i] = read_nothingd; + writemem[0x9000+i] = write_nothing; + writemem[0xb000+i] = write_nothing; + writememb[0x9000+i] = write_nothingb; + writememb[0xb000+i] = write_nothingb; + writememh[0x9000+i] = write_nothingh; + writememh[0xb000+i] = write_nothingh; + writememd[0x9000+i] = write_nothingd; + writememd[0xb000+i] = write_nothingd; + } + + //init PIF_RAM + readmem[0x9fc0] = read_pif; + readmem[0xbfc0] = read_pif; + readmemb[0x9fc0] = read_pifb; + readmemb[0xbfc0] = read_pifb; + readmemh[0x9fc0] = read_pifh; + readmemh[0xbfc0] = read_pifh; + readmemd[0x9fc0] = read_pifd; + readmemd[0xbfc0] = read_pifd; + writemem[0x9fc0] = write_pif; + writemem[0xbfc0] = write_pif; + writememb[0x9fc0] = write_pifb; + writememb[0xbfc0] = write_pifb; + writememh[0x9fc0] = write_pifh; + writememh[0xbfc0] = write_pifh; + writememd[0x9fc0] = write_pifd; + writememd[0xbfc0] = write_pifd; + for (i=0; i<(0x40/4); i++) PIF_RAM[i]=0; + + for (i=0xfc1; i<0x1000; i++) + { + readmem[0x9000+i] = read_nothing; + readmem[0xb000+i] = read_nothing; + readmemb[0x9000+i] = read_nothingb; + readmemb[0xb000+i] = read_nothingb; + readmemh[0x9000+i] = read_nothingh; + readmemh[0xb000+i] = read_nothingh; + readmemd[0x9000+i] = read_nothingd; + readmemd[0xb000+i] = read_nothingd; + writemem[0x9000+i] = write_nothing; + writemem[0xb000+i] = write_nothing; + writememb[0x9000+i] = write_nothingb; + writememb[0xb000+i] = write_nothingb; + writememh[0x9000+i] = write_nothingh; + writememh[0xb000+i] = write_nothingh; + writememd[0x9000+i] = write_nothingd; + writememd[0xb000+i] = write_nothingd; + } + + flashram_info.use_flashram = 0; + init_flashram(); + + frameBufferInfos[0].addr = 0; + fast_memory = 1; + firstFrameBufferSetting = 1; + + DebugMessage(M64MSG_VERBOSE, "Memory initialized"); + return 0; +} + +void free_memory(void) +{ +} + +void make_w_mi_init_mode_reg(void) +{ + MI_register.w_mi_init_mode_reg = MI_register.mi_init_mode_reg & 0x7F; + if ((MI_register.mi_init_mode_reg & 0x080) == 0) + MI_register.w_mi_init_mode_reg |= 0x0000080; + else + MI_register.w_mi_init_mode_reg |= 0x0000100; + + if ((MI_register.mi_init_mode_reg & 0x100) == 0) + MI_register.w_mi_init_mode_reg |= 0x0000200; + else + MI_register.w_mi_init_mode_reg |= 0x0000400; + + if ((MI_register.mi_init_mode_reg & 0x200) == 0) + MI_register.w_mi_init_mode_reg |= 0x0001000; + else + MI_register.w_mi_init_mode_reg |= 0x0002000; +} + +static void update_MI_init_mode_reg(void) +{ + MI_register.mi_init_mode_reg &= ~0x7F; // init_length + MI_register.mi_init_mode_reg |= MI_register.w_mi_init_mode_reg & 0x7F; + + if (MI_register.w_mi_init_mode_reg & 0x80) // clear init_mode + MI_register.mi_init_mode_reg &= ~0x80; + if (MI_register.w_mi_init_mode_reg & 0x100) // set init_mode + MI_register.mi_init_mode_reg |= 0x80; + + if (MI_register.w_mi_init_mode_reg & 0x200) // clear ebus_test_mode + MI_register.mi_init_mode_reg &= ~0x100; + if (MI_register.w_mi_init_mode_reg & 0x400) // set ebus_test_mode + MI_register.mi_init_mode_reg |= 0x100; + + if (MI_register.w_mi_init_mode_reg & 0x800) // clear DP interupt + { + MI_register.mi_intr_reg &= ~0x20; + check_interupt(); + } + + if (MI_register.w_mi_init_mode_reg & 0x1000) // clear RDRAM_reg_mode + MI_register.mi_init_mode_reg &= ~0x200; + if (MI_register.w_mi_init_mode_reg & 0x2000) // set RDRAM_reg_mode + MI_register.mi_init_mode_reg |= 0x200; +} + +void make_w_mi_intr_mask_reg(void) +{ + MI_register.w_mi_intr_mask_reg = 0; + if ((MI_register.mi_intr_mask_reg & 0x01) == 0) + MI_register.w_mi_intr_mask_reg |= 0x0000001; + else + MI_register.w_mi_intr_mask_reg |= 0x0000002; + + if ((MI_register.mi_intr_mask_reg & 0x02) == 0) + MI_register.w_mi_intr_mask_reg |= 0x0000004; + else + MI_register.w_mi_intr_mask_reg |= 0x0000008; + + if ((MI_register.mi_intr_mask_reg & 0x04) == 0) + MI_register.w_mi_intr_mask_reg |= 0x0000010; + else + MI_register.w_mi_intr_mask_reg |= 0x0000020; + + if ((MI_register.mi_intr_mask_reg & 0x08) == 0) + MI_register.w_mi_intr_mask_reg |= 0x0000040; + else + MI_register.w_mi_intr_mask_reg |= 0x0000080; + + if ((MI_register.mi_intr_mask_reg & 0x10) == 0) + MI_register.w_mi_intr_mask_reg |= 0x0000100; + else + MI_register.w_mi_intr_mask_reg |= 0x0000200; + + if ((MI_register.mi_intr_mask_reg & 0x20) == 0) + MI_register.w_mi_intr_mask_reg |= 0x0000400; + else + MI_register.w_mi_intr_mask_reg |= 0x0000800; +} + +static void update_MI_intr_mask_reg(void) +{ + if (MI_register.w_mi_intr_mask_reg & 0x1) MI_register.mi_intr_mask_reg &= ~0x1; // clear SP mask + if (MI_register.w_mi_intr_mask_reg & 0x2) MI_register.mi_intr_mask_reg |= 0x1; // set SP mask + if (MI_register.w_mi_intr_mask_reg & 0x4) MI_register.mi_intr_mask_reg &= ~0x2; // clear SI mask + if (MI_register.w_mi_intr_mask_reg & 0x8) MI_register.mi_intr_mask_reg |= 0x2; // set SI mask + if (MI_register.w_mi_intr_mask_reg & 0x10) MI_register.mi_intr_mask_reg &= ~0x4; // clear AI mask + if (MI_register.w_mi_intr_mask_reg & 0x20) MI_register.mi_intr_mask_reg |= 0x4; // set AI mask + if (MI_register.w_mi_intr_mask_reg & 0x40) MI_register.mi_intr_mask_reg &= ~0x8; // clear VI mask + if (MI_register.w_mi_intr_mask_reg & 0x80) MI_register.mi_intr_mask_reg |= 0x8; // set VI mask + if (MI_register.w_mi_intr_mask_reg & 0x100) MI_register.mi_intr_mask_reg &= ~0x10; // clear PI mask + if (MI_register.w_mi_intr_mask_reg & 0x200) MI_register.mi_intr_mask_reg |= 0x10; // set PI mask + if (MI_register.w_mi_intr_mask_reg & 0x400) MI_register.mi_intr_mask_reg &= ~0x20; // clear DP mask + if (MI_register.w_mi_intr_mask_reg & 0x800) MI_register.mi_intr_mask_reg |= 0x20; // set DP mask +} + +void make_w_sp_status_reg(void) +{ + sp_register.w_sp_status_reg = 0; + + if ((sp_register.sp_status_reg & 0x0001) == 0) + sp_register.w_sp_status_reg |= 0x0000001; + else + sp_register.w_sp_status_reg |= 0x0000002; + + if ((sp_register.sp_status_reg & 0x0002) == 0) + sp_register.w_sp_status_reg |= 0x0000004; + + // TODO: should the interupt bits be set under any circumstance? + + if ((sp_register.sp_status_reg & 0x0020) == 0) + sp_register.w_sp_status_reg |= 0x0000020; + else + sp_register.w_sp_status_reg |= 0x0000040; + + if ((sp_register.sp_status_reg & 0x0040) == 0) + sp_register.w_sp_status_reg |= 0x0000080; + else + sp_register.w_sp_status_reg |= 0x0000100; + if ((sp_register.sp_status_reg & 0x0080) == 0) + sp_register.w_sp_status_reg |= 0x0000200; + else + sp_register.w_sp_status_reg |= 0x0000400; + + if ((sp_register.sp_status_reg & 0x0100) == 0) + sp_register.w_sp_status_reg |= 0x0000800; + else + sp_register.w_sp_status_reg |= 0x0001000; + + if ((sp_register.sp_status_reg & 0x0200) == 0) + sp_register.w_sp_status_reg |= 0x0002000; + else + sp_register.w_sp_status_reg |= 0x0004000; + + if ((sp_register.sp_status_reg & 0x0400) == 0) + sp_register.w_sp_status_reg |= 0x0008000; + else + sp_register.w_sp_status_reg |= 0x0010000; + + if ((sp_register.sp_status_reg & 0x0800) == 0) + sp_register.w_sp_status_reg |= 0x0020000; + else + sp_register.w_sp_status_reg |= 0x0040000; + + if ((sp_register.sp_status_reg & 0x1000) == 0) + sp_register.w_sp_status_reg |= 0x0080000; + else + sp_register.w_sp_status_reg |= 0x0100000; + + if ((sp_register.sp_status_reg & 0x2000) == 0) + sp_register.w_sp_status_reg |= 0x0200000; + else + sp_register.w_sp_status_reg |= 0x0400000; + + if ((sp_register.sp_status_reg & 0x4000) == 0) + sp_register.w_sp_status_reg |= 0x0800000; + else + sp_register.w_sp_status_reg |= 0x1000000; +} + +static void do_SP_Task(void) +{ + int save_pc = rsp_register.rsp_pc & ~0xFFF; + if (SP_DMEM[0xFC0/4] == 1) + { + if (dpc_register.dpc_status & 0x2) // DP frozen (DK64, BC) + { + // don't do the task now + // the task will be done when DP is unfreezed (see update_DPC) + return; + } + + // unprotecting old frame buffers + if (gfx.fBGetFrameBufferInfo && gfx.fBRead && gfx.fBWrite && + frameBufferInfos[0].addr) + { + int i; + for (i=0; i<6; i++) + { + if (frameBufferInfos[i].addr) + { + int j; + int start = frameBufferInfos[i].addr & 0x7FFFFF; + int end = start + frameBufferInfos[i].width* + frameBufferInfos[i].height* + frameBufferInfos[i].size - 1; + start = start >> 16; + end = end >> 16; + + for (j=start; j<=end; j++) + { +#ifdef DBG + if (lookup_breakpoint(0x80000000 + j * 0x10000, 0x10000, + BPT_FLAG_ENABLED | BPT_FLAG_READ ) != -1) + { + readmem[0x8000+j] = read_rdram_break; + readmemb[0x8000+j] = read_rdramb_break; + readmemh[0x8000+j] = read_rdramh_break; + readmemd[0xa000+j] = read_rdramd_break; + } + else + { +#endif + readmem[0x8000+j] = read_rdram; + readmemb[0x8000+j] = read_rdramb; + readmemh[0x8000+j] = read_rdramh; + readmemd[0xa000+j] = read_rdramd; +#ifdef DBG + } + if (lookup_breakpoint(0xa0000000 + j * 0x10000, 0x10000, + BPT_FLAG_ENABLED | BPT_FLAG_READ ) != -1) + { + readmem[0xa000+j] = read_rdram_break; + readmemb[0xa000+j] = read_rdramb_break; + readmemh[0xa000+j] = read_rdramh_break; + readmemd[0x8000+j] = read_rdramd_break; + } + else + { +#endif + readmem[0xa000+j] = read_rdram; + readmemb[0xa000+j] = read_rdramb; + readmemh[0xa000+j] = read_rdramh; + readmemd[0x8000+j] = read_rdramd; +#ifdef DBG + } + if (lookup_breakpoint(0x80000000 + j * 0x10000, 0x10000, + BPT_FLAG_ENABLED | BPT_FLAG_WRITE ) != -1) + { + writemem[0x8000+j] = write_rdram_break; + writememb[0x8000+j] = write_rdramb_break; + writememh[0x8000+j] = write_rdramh_break; + writememd[0x8000+j] = write_rdramd_break; + } + else + { +#endif + writemem[0x8000+j] = write_rdram; + writememb[0x8000+j] = write_rdramb; + writememh[0x8000+j] = write_rdramh; + writememd[0x8000+j] = write_rdramd; +#ifdef DBG + } + if (lookup_breakpoint(0xa0000000 + j * 0x10000, 0x10000, + BPT_FLAG_ENABLED | BPT_FLAG_WRITE ) != -1) + { + writemem[0xa000+j] = write_rdram_break; + writememb[0xa000+j] = write_rdramb_break; + writememh[0xa000+j] = write_rdramh_break; + writememd[0xa000+j] = write_rdramd_break; + } + else + { +#endif + writemem[0xa000+j] = write_rdram; + writememb[0xa000+j] = write_rdramb; + writememh[0xa000+j] = write_rdramh; + writememd[0xa000+j] = write_rdramd; +#ifdef DBG + } +#endif + } + } + } + } + + //gfx.processDList(); + rsp_register.rsp_pc &= 0xFFF; + start_section(GFX_SECTION); + rsp.doRspCycles(0xFFFFFFFF); + end_section(GFX_SECTION); + rsp_register.rsp_pc |= save_pc; + new_frame(); + + update_count(); + if (MI_register.mi_intr_reg & 0x1) + add_interupt_event(SP_INT, 1000); + if (MI_register.mi_intr_reg & 0x20) + add_interupt_event(DP_INT, 1000); + MI_register.mi_intr_reg &= ~0x21; + sp_register.sp_status_reg &= ~0x303; + + // protecting new frame buffers + if (gfx.fBGetFrameBufferInfo && gfx.fBRead && gfx.fBWrite) + gfx.fBGetFrameBufferInfo(frameBufferInfos); + if (gfx.fBGetFrameBufferInfo && gfx.fBRead && gfx.fBWrite + && frameBufferInfos[0].addr) + { + int i; + for (i=0; i<6; i++) + { + if (frameBufferInfos[i].addr) + { + int j; + int start = frameBufferInfos[i].addr & 0x7FFFFF; + int end = start + frameBufferInfos[i].width* + frameBufferInfos[i].height* + frameBufferInfos[i].size - 1; + int start1 = start; + int end1 = end; + start >>= 16; + end >>= 16; + for (j=start; j<=end; j++) + { +#ifdef DBG + if (lookup_breakpoint(0x80000000 + j * 0x10000, 0x10000, + BPT_FLAG_ENABLED | BPT_FLAG_READ ) != -1) + { + readmem[0x8000+j] = read_rdramFB_break; + readmemb[0x8000+j] = read_rdramFBb_break; + readmemh[0x8000+j] = read_rdramFBh_break; + readmemd[0xa000+j] = read_rdramFBd_break; + } + else + { +#endif + readmem[0x8000+j] = read_rdramFB; + readmemb[0x8000+j] = read_rdramFBb; + readmemh[0x8000+j] = read_rdramFBh; + readmemd[0xa000+j] = read_rdramFBd; +#ifdef DBG + } + if (lookup_breakpoint(0xa0000000 + j * 0x10000, 0x10000, + BPT_FLAG_ENABLED | BPT_FLAG_READ ) != -1) + { + readmem[0xa000+j] = read_rdramFB_break; + readmemb[0xa000+j] = read_rdramFBb_break; + readmemh[0xa000+j] = read_rdramFBh_break; + readmemd[0x8000+j] = read_rdramFBd_break; + } + else + { +#endif + readmem[0xa000+j] = read_rdramFB; + readmemb[0xa000+j] = read_rdramFBb; + readmemh[0xa000+j] = read_rdramFBh; + readmemd[0x8000+j] = read_rdramFBd; +#ifdef DBG + } + if (lookup_breakpoint(0x80000000 + j * 0x10000, 0x10000, + BPT_FLAG_ENABLED | BPT_FLAG_WRITE ) != -1) + { + writemem[0x8000+j] = write_rdramFB_break; + writememb[0x8000+j] = write_rdramFBb_break; + writememh[0x8000+j] = write_rdramFBh_break; + writememd[0x8000+j] = write_rdramFBd_break; + } + else + { +#endif + writemem[0x8000+j] = write_rdramFB; + writememb[0x8000+j] = write_rdramFBb; + writememh[0x8000+j] = write_rdramFBh; + writememd[0x8000+j] = write_rdramFBd; +#ifdef DBG + } + if (lookup_breakpoint(0xa0000000 + j * 0x10000, 0x10000, + BPT_FLAG_ENABLED | BPT_FLAG_WRITE ) != -1) + { + writemem[0xa000+j] = write_rdramFB_break; + writememb[0xa000+j] = write_rdramFBb_break; + writememh[0xa000+j] = write_rdramFBh_break; + writememd[0xa000+j] = write_rdramFBd_break; + } + else + { +#endif + writemem[0xa000+j] = write_rdramFB; + writememb[0xa000+j] = write_rdramFBb; + writememh[0xa000+j] = write_rdramFBh; + writememd[0xa000+j] = write_rdramFBd; +#ifdef DBG + } +#endif + } + start <<= 4; + end <<= 4; + for (j=start; j<=end; j++) + { + if (j>=start1 && j<=end1) framebufferRead[j]=1; + else framebufferRead[j] = 0; + } + + if (firstFrameBufferSetting) + { + firstFrameBufferSetting = 0; + fast_memory = 0; + for (j=0; j<0x100000; j++) + invalid_code[j] = 1; + } + } + } + } + } + else if (SP_DMEM[0xFC0/4] == 2) + { + //audio.processAList(); + rsp_register.rsp_pc &= 0xFFF; + start_section(AUDIO_SECTION); + rsp.doRspCycles(0xFFFFFFFF); + end_section(AUDIO_SECTION); + rsp_register.rsp_pc |= save_pc; + + update_count(); + if (MI_register.mi_intr_reg & 0x1) + add_interupt_event(SP_INT, 4000/*500*/); + MI_register.mi_intr_reg &= ~0x1; + sp_register.sp_status_reg &= ~0x303; + + } + else + { + rsp_register.rsp_pc &= 0xFFF; + rsp.doRspCycles(0xFFFFFFFF); + rsp_register.rsp_pc |= save_pc; + + update_count(); + if (MI_register.mi_intr_reg & 0x1) + add_interupt_event(SP_INT, 0/*100*/); + MI_register.mi_intr_reg &= ~0x1; + sp_register.sp_status_reg &= ~0x203; + } +} + +static void update_SP(void) +{ + if (sp_register.w_sp_status_reg & 0x1) // clear halt + sp_register.sp_status_reg &= ~0x1; + if (sp_register.w_sp_status_reg & 0x2) // set halt + sp_register.sp_status_reg |= 0x1; + + if (sp_register.w_sp_status_reg & 0x4) // clear broke + sp_register.sp_status_reg &= ~0x2; + + if (sp_register.w_sp_status_reg & 0x8) // clear SP interupt + { + MI_register.mi_intr_reg &= ~1; + check_interupt(); + } + + if (sp_register.w_sp_status_reg & 0x10) // set SP interupt + { + MI_register.mi_intr_reg |= 1; + check_interupt(); + } + + if (sp_register.w_sp_status_reg & 0x20) // clear single step + sp_register.sp_status_reg &= ~0x20; + if (sp_register.w_sp_status_reg & 0x40) // set single step + sp_register.sp_status_reg |= 0x20; + + if (sp_register.w_sp_status_reg & 0x80) // clear interrupt on break + sp_register.sp_status_reg &= ~0x40; + if (sp_register.w_sp_status_reg & 0x100) // set interrupt on break + sp_register.sp_status_reg |= 0x40; + + if (sp_register.w_sp_status_reg & 0x200) // clear signal 0 + sp_register.sp_status_reg &= ~0x80; + if (sp_register.w_sp_status_reg & 0x400) // set signal 0 + sp_register.sp_status_reg |= 0x80; + + if (sp_register.w_sp_status_reg & 0x800) // clear signal 1 + sp_register.sp_status_reg &= ~0x100; + if (sp_register.w_sp_status_reg & 0x1000) // set signal 1 + sp_register.sp_status_reg |= 0x100; + + if (sp_register.w_sp_status_reg & 0x2000) // clear signal 2 + sp_register.sp_status_reg &= ~0x200; + if (sp_register.w_sp_status_reg & 0x4000) // set signal 2 + sp_register.sp_status_reg |= 0x200; + + if (sp_register.w_sp_status_reg & 0x8000) // clear signal 3 + sp_register.sp_status_reg &= ~0x400; + if (sp_register.w_sp_status_reg & 0x10000) // set signal 3 + sp_register.sp_status_reg |= 0x400; + + if (sp_register.w_sp_status_reg & 0x20000) // clear signal 4 + sp_register.sp_status_reg &= ~0x800; + if (sp_register.w_sp_status_reg & 0x40000) // set signal 4 + sp_register.sp_status_reg |= 0x800; + + if (sp_register.w_sp_status_reg & 0x80000) // clear signal 5 + sp_register.sp_status_reg &= ~0x1000; + if (sp_register.w_sp_status_reg & 0x100000) // set signal 5 + sp_register.sp_status_reg |= 0x1000; + + if (sp_register.w_sp_status_reg & 0x200000) // clear signal 6 + sp_register.sp_status_reg &= ~0x2000; + if (sp_register.w_sp_status_reg & 0x400000) // set signal 6 + sp_register.sp_status_reg |= 0x2000; + + if (sp_register.w_sp_status_reg & 0x800000) // clear signal 7 + sp_register.sp_status_reg &= ~0x4000; + if (sp_register.w_sp_status_reg & 0x1000000) // set signal 7 + sp_register.sp_status_reg |= 0x4000; + + //if (get_event(SP_INT)) return; + if (!(sp_register.w_sp_status_reg & 0x1) && + !(sp_register.w_sp_status_reg & 0x4)) return; + if (!(sp_register.sp_status_reg & 0x3)) // !halt && !broke + do_SP_Task(); +} + +void make_w_dpc_status(void) +{ + dpc_register.w_dpc_status = 0; + + if ((dpc_register.dpc_status & 0x0001) == 0) + dpc_register.w_dpc_status |= 0x0000001; + else + dpc_register.w_dpc_status |= 0x0000002; + + if ((dpc_register.dpc_status & 0x0002) == 0) + dpc_register.w_dpc_status |= 0x0000004; + else + dpc_register.w_dpc_status |= 0x0000008; + + if ((dpc_register.dpc_status & 0x0004) == 0) + dpc_register.w_dpc_status |= 0x0000010; + else + dpc_register.w_dpc_status |= 0x0000020; +} + +static void update_DPC(void) +{ + if (dpc_register.w_dpc_status & 0x1) // clear xbus_dmem_dma + dpc_register.dpc_status &= ~0x1; + if (dpc_register.w_dpc_status & 0x2) // set xbus_dmem_dma + dpc_register.dpc_status |= 0x1; + + if (dpc_register.w_dpc_status & 0x4) // clear freeze + { + dpc_register.dpc_status &= ~0x2; + + // see do_SP_task for more info + if (!(sp_register.sp_status_reg & 0x3)) // !halt && !broke + do_SP_Task(); + } + if (dpc_register.w_dpc_status & 0x8) // set freeze + dpc_register.dpc_status |= 0x2; + + if (dpc_register.w_dpc_status & 0x10) // clear flush + dpc_register.dpc_status &= ~0x4; + if (dpc_register.w_dpc_status & 0x20) // set flush + dpc_register.dpc_status |= 0x4; +} + +void read_nothing(void) +{ + if (address == 0xa5000508) *rdword = 0xFFFFFFFF; + else *rdword = 0; +} + +void read_nothingb(void) +{ + *rdword = 0; +} + +void read_nothingh(void) +{ + *rdword = 0; +} + +void read_nothingd(void) +{ + *rdword = 0; +} + +void write_nothing(void) +{ +} + +void write_nothingb(void) +{ +} + +void write_nothingh(void) +{ +} + +void write_nothingd(void) +{ +} + +void read_nomem(void) +{ + address = virtual_to_physical_address(address,0); + if (address == 0x00000000) return; + read_word_in_memory(); +} + +void read_nomemb(void) +{ + address = virtual_to_physical_address(address,0); + if (address == 0x00000000) return; + read_byte_in_memory(); +} + +void read_nomemh(void) +{ + address = virtual_to_physical_address(address,0); + if (address == 0x00000000) return; + read_hword_in_memory(); +} + +void read_nomemd(void) +{ + address = virtual_to_physical_address(address,0); + if (address == 0x00000000) return; + read_dword_in_memory(); +} + +void write_nomem(void) +{ + if (r4300emu != CORE_PURE_INTERPRETER && !invalid_code[address>>12]) + if (blocks[address>>12]->block[(address&0xFFF)/4].ops != + current_instruction_table.NOTCOMPILED) + invalid_code[address>>12] = 1; + address = virtual_to_physical_address(address,1); + if (address == 0x00000000) return; + write_word_in_memory(); +} + +void write_nomemb(void) +{ + if (r4300emu != CORE_PURE_INTERPRETER && !invalid_code[address>>12]) + if (blocks[address>>12]->block[(address&0xFFF)/4].ops != + current_instruction_table.NOTCOMPILED) + invalid_code[address>>12] = 1; + address = virtual_to_physical_address(address,1); + if (address == 0x00000000) return; + write_byte_in_memory(); +} + +void write_nomemh(void) +{ + if (r4300emu != CORE_PURE_INTERPRETER && !invalid_code[address>>12]) + if (blocks[address>>12]->block[(address&0xFFF)/4].ops != + current_instruction_table.NOTCOMPILED) + invalid_code[address>>12] = 1; + address = virtual_to_physical_address(address,1); + if (address == 0x00000000) return; + write_hword_in_memory(); +} + +void write_nomemd(void) +{ + if (r4300emu != CORE_PURE_INTERPRETER && !invalid_code[address>>12]) + if (blocks[address>>12]->block[(address&0xFFF)/4].ops != + current_instruction_table.NOTCOMPILED) + invalid_code[address>>12] = 1; + address = virtual_to_physical_address(address,1); + if (address == 0x00000000) return; + write_dword_in_memory(); +} + +void read_rdram(void) +{ + *rdword = *((unsigned int *)(rdramb + (address & 0xFFFFFF))); +} + +void read_rdramb(void) +{ + *rdword = *(rdramb + ((address & 0xFFFFFF)^S8)); +} + +void read_rdramh(void) +{ + *rdword = *((unsigned short *)(rdramb + ((address & 0xFFFFFF)^S16))); +} + +void read_rdramd(void) +{ + *rdword = ((unsigned long long int)(*(unsigned int *)(rdramb + (address & 0xFFFFFF))) << 32) | + ((*(unsigned int *)(rdramb + (address & 0xFFFFFF) + 4))); +} + +void read_rdramFB(void) +{ + int i; + for (i=0; i<6; i++) + { + if (frameBufferInfos[i].addr) + { + unsigned int start = frameBufferInfos[i].addr & 0x7FFFFF; + unsigned int end = start + frameBufferInfos[i].width* + frameBufferInfos[i].height* + frameBufferInfos[i].size - 1; + if ((address & 0x7FFFFF) >= start && (address & 0x7FFFFF) <= end && + framebufferRead[(address & 0x7FFFFF)>>12]) + { + gfx.fBRead(address); + framebufferRead[(address & 0x7FFFFF)>>12] = 0; + } + } + } + read_rdram(); +} + +void read_rdramFBb(void) +{ + int i; + for (i=0; i<6; i++) + { + if (frameBufferInfos[i].addr) + { + unsigned int start = frameBufferInfos[i].addr & 0x7FFFFF; + unsigned int end = start + frameBufferInfos[i].width* + frameBufferInfos[i].height* + frameBufferInfos[i].size - 1; + if ((address & 0x7FFFFF) >= start && (address & 0x7FFFFF) <= end && + framebufferRead[(address & 0x7FFFFF)>>12]) + { + gfx.fBRead(address); + framebufferRead[(address & 0x7FFFFF)>>12] = 0; + } + } + } + read_rdramb(); +} + +void read_rdramFBh(void) +{ + int i; + for (i=0; i<6; i++) + { + if (frameBufferInfos[i].addr) + { + unsigned int start = frameBufferInfos[i].addr & 0x7FFFFF; + unsigned int end = start + frameBufferInfos[i].width* + frameBufferInfos[i].height* + frameBufferInfos[i].size - 1; + if ((address & 0x7FFFFF) >= start && (address & 0x7FFFFF) <= end && + framebufferRead[(address & 0x7FFFFF)>>12]) + { + gfx.fBRead(address); + framebufferRead[(address & 0x7FFFFF)>>12] = 0; + } + } + } + read_rdramh(); +} + +void read_rdramFBd(void) +{ + int i; + for (i=0; i<6; i++) + { + if (frameBufferInfos[i].addr) + { + unsigned int start = frameBufferInfos[i].addr & 0x7FFFFF; + unsigned int end = start + frameBufferInfos[i].width* + frameBufferInfos[i].height* + frameBufferInfos[i].size - 1; + if ((address & 0x7FFFFF) >= start && (address & 0x7FFFFF) <= end && + framebufferRead[(address & 0x7FFFFF)>>12]) + { + gfx.fBRead(address); + framebufferRead[(address & 0x7FFFFF)>>12] = 0; + } + } + } + read_rdramd(); +} + +void write_rdram(void) +{ +#if defined( COUNT_WRITE_RDRAM_CALLS ) + printf( "write_rdram, word=%i, count: %i", word, writerdram_count ); + writerdram_count++; +#endif + *((unsigned int *)(rdramb + (address & 0xFFFFFF))) = word; +} + +void write_rdramb(void) +{ + *((rdramb + ((address & 0xFFFFFF)^S8))) = cpu_byte; +} + +void write_rdramh(void) +{ + *(unsigned short *)((rdramb + ((address & 0xFFFFFF)^S16))) = hword; +} + +void write_rdramd(void) +{ + *((unsigned int *)(rdramb + (address & 0xFFFFFF))) = (unsigned int) (dword >> 32); + *((unsigned int *)(rdramb + (address & 0xFFFFFF) + 4 )) = (unsigned int) (dword & 0xFFFFFFFF); +} + +void write_rdramFB(void) +{ + int i; + for (i=0; i<6; i++) + { + if (frameBufferInfos[i].addr) + { + unsigned int start = frameBufferInfos[i].addr & 0x7FFFFF; + unsigned int end = start + frameBufferInfos[i].width* + frameBufferInfos[i].height* + frameBufferInfos[i].size - 1; + if ((address & 0x7FFFFF) >= start && (address & 0x7FFFFF) <= end) + gfx.fBWrite(address, 4); + } + } + write_rdram(); +} + +void write_rdramFBb(void) +{ + int i; + for (i=0; i<6; i++) + { + if (frameBufferInfos[i].addr) + { + unsigned int start = frameBufferInfos[i].addr & 0x7FFFFF; + unsigned int end = start + frameBufferInfos[i].width* + frameBufferInfos[i].height* + frameBufferInfos[i].size - 1; + if ((address & 0x7FFFFF) >= start && (address & 0x7FFFFF) <= end) + gfx.fBWrite(address^S8, 1); + } + } + write_rdramb(); +} + +void write_rdramFBh(void) +{ + int i; + for (i=0; i<6; i++) + { + if (frameBufferInfos[i].addr) + { + unsigned int start = frameBufferInfos[i].addr & 0x7FFFFF; + unsigned int end = start + frameBufferInfos[i].width* + frameBufferInfos[i].height* + frameBufferInfos[i].size - 1; + if ((address & 0x7FFFFF) >= start && (address & 0x7FFFFF) <= end) + gfx.fBWrite(address^S16, 2); + } + } + write_rdramh(); +} + +void write_rdramFBd(void) +{ + int i; + for (i=0; i<6; i++) + { + if (frameBufferInfos[i].addr) + { + unsigned int start = frameBufferInfos[i].addr & 0x7FFFFF; + unsigned int end = start + frameBufferInfos[i].width* + frameBufferInfos[i].height* + frameBufferInfos[i].size - 1; + if ((address & 0x7FFFFF) >= start && (address & 0x7FFFFF) <= end) + gfx.fBWrite(address, 8); + } + } + write_rdramd(); +} + +void read_rdramreg(void) +{ + *rdword = *(readrdramreg[*address_low]); +} + +void read_rdramregb(void) +{ + *rdword = *((unsigned char*)readrdramreg[*address_low & 0xfffc] + + ((*address_low&3)^S8) ); +} + +void read_rdramregh(void) +{ + *rdword = *((unsigned short*)((unsigned char*)readrdramreg[*address_low & 0xfffc] + + ((*address_low&3)^S16) )); +} + +void read_rdramregd(void) +{ + *rdword = ((unsigned long long int)(*readrdramreg[*address_low])<<32) | + *readrdramreg[*address_low+4]; +} + +void write_rdramreg(void) +{ + *readrdramreg[*address_low] = word; +} + +void write_rdramregb(void) +{ + *((unsigned char*)readrdramreg[*address_low & 0xfffc] + + ((*address_low&3)^S8) ) = cpu_byte; +} + +void write_rdramregh(void) +{ + *((unsigned short*)((unsigned char*)readrdramreg[*address_low & 0xfffc] + + ((*address_low&3)^S16) )) = hword; +} + +void write_rdramregd(void) +{ + *readrdramreg[*address_low] = (unsigned int) (dword >> 32); + *readrdramreg[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF); +} + +void read_rsp_mem(void) +{ + if (*address_low < 0x1000) + *rdword = *((unsigned int *)(SP_DMEMb + (*address_low))); + else if (*address_low < 0x2000) + *rdword = *((unsigned int *)(SP_IMEMb + (*address_low&0xFFF))); + else + read_nomem(); +} + +void read_rsp_memb(void) +{ + if (*address_low < 0x1000) + *rdword = *(SP_DMEMb + (*address_low^S8)); + else if (*address_low < 0x2000) + *rdword = *(SP_IMEMb + ((*address_low&0xFFF)^S8)); + else + read_nomemb(); +} + +void read_rsp_memh(void) +{ + if (*address_low < 0x1000) + *rdword = *((unsigned short *)(SP_DMEMb + (*address_low^S16))); + else if (*address_low < 0x2000) + *rdword = *((unsigned short *)(SP_IMEMb + ((*address_low&0xFFF)^S16))); + else + read_nomemh(); +} + +void read_rsp_memd(void) +{ + if (*address_low < 0x1000) + { + *rdword = ((unsigned long long int)(*(unsigned int *)(SP_DMEMb + (*address_low))) << 32) | + ((*(unsigned int *)(SP_DMEMb + (*address_low) + 4))); + } + else if (*address_low < 0x2000) + { + *rdword = ((unsigned long long int)(*(unsigned int *)(SP_IMEMb + (*address_low&0xFFF))) << 32) | + ((*(unsigned int *)(SP_IMEMb + (*address_low&0xFFF) + 4))); + } + else + read_nomemd(); +} + +void write_rsp_mem(void) +{ + if (*address_low < 0x1000) + *((unsigned int *)(SP_DMEMb + (*address_low))) = word; + else if (*address_low < 0x2000) + *((unsigned int *)(SP_IMEMb + (*address_low&0xFFF))) = word; + else + write_nomem(); +} + +void write_rsp_memb(void) +{ + if (*address_low < 0x1000) + *(SP_DMEMb + (*address_low^S8)) = cpu_byte; + else if (*address_low < 0x2000) + *(SP_IMEMb + ((*address_low&0xFFF)^S8)) = cpu_byte; + else + write_nomemb(); +} + +void write_rsp_memh(void) +{ + if (*address_low < 0x1000) + *((unsigned short *)(SP_DMEMb + (*address_low^S16))) = hword; + else if (*address_low < 0x2000) + *((unsigned short *)(SP_IMEMb + ((*address_low&0xFFF)^S16))) = hword; + else + write_nomemh(); +} + +void write_rsp_memd(void) +{ + if (*address_low < 0x1000) + { + *((unsigned int *)(SP_DMEMb + *address_low)) = (unsigned int) (dword >> 32); + *((unsigned int *)(SP_DMEMb + *address_low + 4 )) = (unsigned int) (dword & 0xFFFFFFFF); + } + else if (*address_low < 0x2000) + { + *((unsigned int *)(SP_IMEMb + (*address_low&0xFFF))) = (unsigned int) (dword >> 32); + *((unsigned int *)(SP_IMEMb + (*address_low&0xFFF) + 4 )) = (unsigned int) (dword & 0xFFFFFFFF); + } + else + read_nomemd(); +} + +void read_rsp_reg(void) +{ + *rdword = *(readrspreg[*address_low]); + switch (*address_low) + { + case 0x1c: + sp_register.sp_semaphore_reg = 1; + break; + } +} + +void read_rsp_regb(void) +{ + *rdword = *((unsigned char*)readrspreg[*address_low & 0xfffc] + + ((*address_low&3)^S8) ); + switch (*address_low) + { + case 0x1c: + case 0x1d: + case 0x1e: + case 0x1f: + sp_register.sp_semaphore_reg = 1; + break; + } +} + +void read_rsp_regh(void) +{ + *rdword = *((unsigned short*)((unsigned char*)readrspreg[*address_low & 0xfffc] + + ((*address_low&3)^S16) )); + switch (*address_low) + { + case 0x1c: + case 0x1e: + sp_register.sp_semaphore_reg = 1; + break; + } +} + +void read_rsp_regd(void) +{ + *rdword = ((unsigned long long int)(*readrspreg[*address_low])<<32) | + *readrspreg[*address_low+4]; + switch (*address_low) + { + case 0x18: + sp_register.sp_semaphore_reg = 1; + break; + } +} + +void write_rsp_reg(void) +{ + switch (*address_low) + { + case 0x10: + sp_register.w_sp_status_reg = word; + update_SP(); + case 0x14: + case 0x18: + return; + break; + } + *readrspreg[*address_low] = word; + switch (*address_low) + { + case 0x8: + dma_sp_write(); + break; + case 0xc: + dma_sp_read(); + break; + case 0x1c: + sp_register.sp_semaphore_reg = 0; + break; + } +} + +void write_rsp_regb(void) +{ + switch (*address_low) + { + case 0x10: + case 0x11: + case 0x12: + case 0x13: + *((unsigned char*)&sp_register.w_sp_status_reg + + ((*address_low&3)^S8) ) = cpu_byte; + case 0x14: + case 0x15: + case 0x16: + case 0x17: + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + return; + break; + } + *((unsigned char*)readrspreg[*address_low & 0xfffc] + + ((*address_low&3)^S8) ) = cpu_byte; + switch (*address_low) + { + case 0x8: + case 0x9: + case 0xa: + case 0xb: + dma_sp_write(); + break; + case 0xc: + case 0xd: + case 0xe: + case 0xf: + dma_sp_read(); + break; + case 0x1c: + case 0x1d: + case 0x1e: + case 0x1f: + sp_register.sp_semaphore_reg = 0; + break; + } +} + +void write_rsp_regh(void) +{ + switch (*address_low) + { + case 0x10: + case 0x12: + *((unsigned short*)((unsigned char*)&sp_register.w_sp_status_reg + + ((*address_low&3)^S16) )) = hword; + case 0x14: + case 0x16: + case 0x18: + case 0x1a: + return; + break; + } + *((unsigned short*)((unsigned char*)readrspreg[*address_low & 0xfffc] + + ((*address_low&3)^S16) )) = hword; + switch (*address_low) + { + case 0x8: + case 0xa: + dma_sp_write(); + break; + case 0xc: + case 0xe: + dma_sp_read(); + break; + case 0x1c: + case 0x1e: + sp_register.sp_semaphore_reg = 0; + break; + } +} + +void write_rsp_regd(void) +{ + switch (*address_low) + { + case 0x10: + sp_register.w_sp_status_reg = (unsigned int) (dword >> 32); + update_SP(); + return; + break; + case 0x18: + sp_register.sp_semaphore_reg = 0; + return; + break; + } + *readrspreg[*address_low] = (unsigned int) (dword >> 32); + *readrspreg[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF); + switch (*address_low) + { + case 0x8: + dma_sp_write(); + dma_sp_read(); + break; + } +} + +void read_rsp(void) +{ + *rdword = *(readrsp[*address_low]); +} + +void read_rspb(void) +{ + *rdword = *((unsigned char*)readrsp[*address_low & 0xfffc] + + ((*address_low&3)^S8) ); +} + +void read_rsph(void) +{ + *rdword = *((unsigned short*)((unsigned char*)readrsp[*address_low & 0xfffc] + + ((*address_low&3)^S16) )); +} + +void read_rspd(void) +{ + *rdword = ((unsigned long long int)(*readrsp[*address_low])<<32) | + *readrsp[*address_low+4]; +} + +void write_rsp(void) +{ + *readrsp[*address_low] = word; +} + +void write_rspb(void) +{ + *((unsigned char*)readrsp[*address_low & 0xfffc] + + ((*address_low&3)^S8) ) = cpu_byte; +} + +void write_rsph(void) +{ + *((unsigned short*)((unsigned char*)readrsp[*address_low & 0xfffc] + + ((*address_low&3)^S16) )) = hword; +} + +void write_rspd(void) +{ + *readrsp[*address_low] = (unsigned int) (dword >> 32); + *readrsp[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF); +} + +void read_dp(void) +{ + *rdword = *(readdp[*address_low]); +} + +void read_dpb(void) +{ + *rdword = *((unsigned char*)readdp[*address_low & 0xfffc] + + ((*address_low&3)^S8) ); +} + +void read_dph(void) +{ + *rdword = *((unsigned short*)((unsigned char*)readdp[*address_low & 0xfffc] + + ((*address_low&3)^S16) )); +} + +void read_dpd(void) +{ + *rdword = ((unsigned long long int)(*readdp[*address_low])<<32) | + *readdp[*address_low+4]; +} + +void write_dp(void) +{ + switch (*address_low) + { + case 0xc: + dpc_register.w_dpc_status = word; + update_DPC(); + case 0x8: + case 0x10: + case 0x14: + case 0x18: + case 0x1c: + return; + break; + } + *readdp[*address_low] = word; + switch (*address_low) + { + case 0x0: + dpc_register.dpc_current = dpc_register.dpc_start; + break; + case 0x4: + gfx.processRDPList(); + MI_register.mi_intr_reg |= 0x20; + check_interupt(); + break; + } +} + +void write_dpb(void) +{ + switch (*address_low) + { + case 0xc: + case 0xd: + case 0xe: + case 0xf: + *((unsigned char*)&dpc_register.w_dpc_status + + ((*address_low&3)^S8) ) = cpu_byte; + update_DPC(); + case 0x8: + case 0x9: + case 0xa: + case 0xb: + case 0x10: + case 0x11: + case 0x12: + case 0x13: + case 0x14: + case 0x15: + case 0x16: + case 0x17: + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + case 0x1c: + case 0x1d: + case 0x1e: + case 0x1f: + return; + break; + } + *((unsigned char*)readdp[*address_low & 0xfffc] + + ((*address_low&3)^S8) ) = cpu_byte; + switch (*address_low) + { + case 0x0: + case 0x1: + case 0x2: + case 0x3: + dpc_register.dpc_current = dpc_register.dpc_start; + break; + case 0x4: + case 0x5: + case 0x6: + case 0x7: + gfx.processRDPList(); + MI_register.mi_intr_reg |= 0x20; + check_interupt(); + break; + } +} + +void write_dph(void) +{ + switch (*address_low) + { + case 0xc: + case 0xe: + *((unsigned short*)((unsigned char*)&dpc_register.w_dpc_status + + ((*address_low&3)^S16) )) = hword; + update_DPC(); + case 0x8: + case 0xa: + case 0x10: + case 0x12: + case 0x14: + case 0x16: + case 0x18: + case 0x1a: + case 0x1c: + case 0x1e: + return; + break; + } + *((unsigned short*)((unsigned char*)readdp[*address_low & 0xfffc] + + ((*address_low&3)^S16) )) = hword; + switch (*address_low) + { + case 0x0: + case 0x2: + dpc_register.dpc_current = dpc_register.dpc_start; + break; + case 0x4: + case 0x6: + gfx.processRDPList(); + MI_register.mi_intr_reg |= 0x20; + check_interupt(); + break; + } +} + +void write_dpd(void) +{ + switch (*address_low) + { + case 0x8: + dpc_register.w_dpc_status = (unsigned int) (dword & 0xFFFFFFFF); + update_DPC(); + return; + break; + case 0x10: + case 0x18: + return; + break; + } + *readdp[*address_low] = (unsigned int) (dword >> 32); + *readdp[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF); + switch (*address_low) + { + case 0x0: + dpc_register.dpc_current = dpc_register.dpc_start; + gfx.processRDPList(); + MI_register.mi_intr_reg |= 0x20; + check_interupt(); + break; + } +} + +void read_dps(void) +{ + *rdword = *(readdps[*address_low]); +} + +void read_dpsb(void) +{ + *rdword = *((unsigned char*)readdps[*address_low & 0xfffc] + + ((*address_low&3)^S8) ); +} + +void read_dpsh(void) +{ + *rdword = *((unsigned short*)((unsigned char*)readdps[*address_low & 0xfffc] + + ((*address_low&3)^S16) )); +} + +void read_dpsd(void) +{ + *rdword = ((unsigned long long int)(*readdps[*address_low])<<32) | + *readdps[*address_low+4]; +} + +void write_dps(void) +{ + *readdps[*address_low] = word; +} + +void write_dpsb(void) +{ + *((unsigned char*)readdps[*address_low & 0xfffc] + + ((*address_low&3)^S8) ) = cpu_byte; +} + +void write_dpsh(void) +{ + *((unsigned short*)((unsigned char*)readdps[*address_low & 0xfffc] + + ((*address_low&3)^S16) )) = hword; +} + +void write_dpsd(void) +{ + *readdps[*address_low] = (unsigned int) (dword >> 32); + *readdps[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF); +} + +void read_mi(void) +{ + *rdword = *(readmi[*address_low]); +} + +void read_mib(void) +{ + *rdword = *((unsigned char*)readmi[*address_low & 0xfffc] + + ((*address_low&3)^S8) ); +} + +void read_mih(void) +{ + *rdword = *((unsigned short*)((unsigned char*)readmi[*address_low & 0xfffc] + + ((*address_low&3)^S16) )); +} + +void read_mid(void) +{ + *rdword = ((unsigned long long int)(*readmi[*address_low])<<32) | + *readmi[*address_low+4]; +} + +void write_mi(void) +{ + switch (*address_low) + { + case 0x0: + MI_register.w_mi_init_mode_reg = word; + update_MI_init_mode_reg(); + break; + case 0xc: + MI_register.w_mi_intr_mask_reg = word; + update_MI_intr_mask_reg(); + + check_interupt(); + update_count(); + if (next_interupt <= Count) gen_interupt(); + break; + } +} + +void write_mib(void) +{ + switch (*address_low) + { + case 0x0: + case 0x1: + case 0x2: + case 0x3: + *((unsigned char*)&MI_register.w_mi_init_mode_reg + + ((*address_low&3)^S8) ) = cpu_byte; + update_MI_init_mode_reg(); + break; + case 0xc: + case 0xd: + case 0xe: + case 0xf: + *((unsigned char*)&MI_register.w_mi_intr_mask_reg + + ((*address_low&3)^S8) ) = cpu_byte; + update_MI_intr_mask_reg(); + + check_interupt(); + update_count(); + if (next_interupt <= Count) gen_interupt(); + break; + } +} + +void write_mih(void) +{ + switch (*address_low) + { + case 0x0: + case 0x2: + *((unsigned short*)((unsigned char*)&MI_register.w_mi_init_mode_reg + + ((*address_low&3)^S16) )) = hword; + update_MI_init_mode_reg(); + break; + case 0xc: + case 0xe: + *((unsigned short*)((unsigned char*)&MI_register.w_mi_intr_mask_reg + + ((*address_low&3)^S16) )) = hword; + update_MI_intr_mask_reg(); + + check_interupt(); + update_count(); + if (next_interupt <= Count) gen_interupt(); + break; + } +} + +void write_mid(void) +{ + switch (*address_low) + { + case 0x0: + MI_register.w_mi_init_mode_reg = (unsigned int) (dword >> 32); + update_MI_init_mode_reg(); + break; + case 0x8: + MI_register.w_mi_intr_mask_reg = (unsigned int) (dword & 0xFFFFFFFF); + update_MI_intr_mask_reg(); + + check_interupt(); + update_count(); + if (next_interupt <= Count) gen_interupt(); + break; + } +} + +void read_vi(void) +{ + switch (*address_low) + { + case 0x10: + update_count(); + vi_register.vi_current = (vi_register.vi_delay-(next_vi-Count))/1500; + vi_register.vi_current = (vi_register.vi_current&(~1))|vi_field; + break; + } + *rdword = *(readvi[*address_low]); +} + +void read_vib(void) +{ + switch (*address_low) + { + case 0x10: + case 0x11: + case 0x12: + case 0x13: + update_count(); + vi_register.vi_current = (vi_register.vi_delay-(next_vi-Count))/1500; + vi_register.vi_current = (vi_register.vi_current&(~1))|vi_field; + break; + } + *rdword = *((unsigned char*)readvi[*address_low & 0xfffc] + + ((*address_low&3)^S8) ); +} + +void read_vih(void) +{ + switch (*address_low) + { + case 0x10: + case 0x12: + update_count(); + vi_register.vi_current = (vi_register.vi_delay-(next_vi-Count))/1500; + vi_register.vi_current = (vi_register.vi_current&(~1))|vi_field; + break; + } + *rdword = *((unsigned short*)((unsigned char*)readvi[*address_low & 0xfffc] + + ((*address_low&3)^S16) )); +} + +void read_vid(void) +{ + switch (*address_low) + { + case 0x10: + update_count(); + vi_register.vi_current = (vi_register.vi_delay-(next_vi-Count))/1500; + vi_register.vi_current = (vi_register.vi_current&(~1))|vi_field; + break; + } + *rdword = ((unsigned long long int)(*readvi[*address_low])<<32) | + *readvi[*address_low+4]; +} + +void write_vi(void) +{ + switch (*address_low) + { + case 0x0: + if (vi_register.vi_status != word) + { + update_vi_status(word); + } + return; + break; + case 0x8: + if (vi_register.vi_width != word) + { + update_vi_width(word); + } + return; + break; + case 0x10: + MI_register.mi_intr_reg &= ~0x8; + check_interupt(); + return; + break; + } + *readvi[*address_low] = word; +} + +void update_vi_status(unsigned int word) +{ + vi_register.vi_status = word; + gfx.viStatusChanged(); +} + +void update_vi_width(unsigned int word) +{ + vi_register.vi_width = word; + gfx.viWidthChanged(); +} + +void write_vib(void) +{ + int temp; + switch (*address_low) + { + case 0x0: + case 0x1: + case 0x2: + case 0x3: + temp = vi_register.vi_status; + *((unsigned char*)&temp + + ((*address_low&3)^S8) ) = cpu_byte; + if (vi_register.vi_status != temp) + { + update_vi_status(temp); + } + return; + break; + case 0x8: + case 0x9: + case 0xa: + case 0xb: + temp = vi_register.vi_status; + *((unsigned char*)&temp + + ((*address_low&3)^S8) ) = cpu_byte; + if (vi_register.vi_width != temp) + { + update_vi_width(temp); + } + return; + break; + case 0x10: + case 0x11: + case 0x12: + case 0x13: + MI_register.mi_intr_reg &= ~0x8; + check_interupt(); + return; + break; + } + *((unsigned char*)readvi[*address_low & 0xfffc] + + ((*address_low&3)^S8) ) = cpu_byte; +} + +void write_vih(void) +{ + int temp; + switch (*address_low) + { + case 0x0: + case 0x2: + temp = vi_register.vi_status; + *((unsigned short*)((unsigned char*)&temp + + ((*address_low&3)^S16) )) = hword; + if (vi_register.vi_status != temp) + { + update_vi_status(temp); + } + return; + break; + case 0x8: + case 0xa: + temp = vi_register.vi_status; + *((unsigned short*)((unsigned char*)&temp + + ((*address_low&3)^S16) )) = hword; + if (vi_register.vi_width != temp) + { + update_vi_width(temp); + } + return; + break; + case 0x10: + case 0x12: + MI_register.mi_intr_reg &= ~0x8; + check_interupt(); + return; + break; + } + *((unsigned short*)((unsigned char*)readvi[*address_low & 0xfffc] + + ((*address_low&3)^S16) )) = hword; +} + +void write_vid(void) +{ + switch (*address_low) + { + case 0x0: + if (vi_register.vi_status != dword >> 32) + { + update_vi_status((unsigned int) (dword >> 32)); + } + vi_register.vi_origin = (unsigned int) (dword & 0xFFFFFFFF); + return; + break; + case 0x8: + if (vi_register.vi_width != dword >> 32) + { + update_vi_width((unsigned int) (dword >> 32)); + } + vi_register.vi_v_intr = (unsigned int) (dword & 0xFFFFFFFF); + return; + break; + case 0x10: + MI_register.mi_intr_reg &= ~0x8; + check_interupt(); + vi_register.vi_burst = (unsigned int) (dword & 0xFFFFFFFF); + return; + break; + } + *readvi[*address_low] = (unsigned int) (dword >> 32); + *readvi[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF); +} + +void read_ai(void) +{ + switch (*address_low) + { + case 0x4: + update_count(); + if (ai_register.current_delay != 0 && get_event(AI_INT) != 0 && (get_event(AI_INT)-Count) < 0x80000000) + *rdword = ((get_event(AI_INT)-Count)*(long long)ai_register.current_len)/ + ai_register.current_delay; + else + *rdword = 0; + return; + break; + } + *rdword = *(readai[*address_low]); +} + +void read_aib(void) +{ + unsigned int len; + switch (*address_low) + { + case 0x4: + case 0x5: + case 0x6: + case 0x7: + update_count(); + if (ai_register.current_delay != 0 && get_event(AI_INT) != 0) + len = (unsigned int) (((get_event(AI_INT) - Count) * (long long)ai_register.current_len) / ai_register.current_delay); + else + len = 0; + *rdword = *((unsigned char*)&len + ((*address_low&3)^S8) ); + return; + break; + } + *rdword = *((unsigned char*)readai[*address_low & 0xfffc] + + ((*address_low&3)^S8) ); +} + +void read_aih(void) +{ + unsigned int len; + switch (*address_low) + { + case 0x4: + case 0x6: + update_count(); + if (ai_register.current_delay != 0 && get_event(AI_INT) != 0) + len = (unsigned int) (((get_event(AI_INT)-Count) * (long long)ai_register.current_len) / ai_register.current_delay); + else + len = 0; + *rdword = *((unsigned short*)((unsigned char*)&len + + ((*address_low&3)^S16) )); + return; + break; + } + *rdword = *((unsigned short*)((unsigned char*)readai[*address_low & 0xfffc] + + ((*address_low&3)^S16) )); +} + +void read_aid(void) +{ + switch (*address_low) + { + case 0x0: + update_count(); + if (ai_register.current_delay != 0 && get_event(AI_INT) != 0) + *rdword = ((get_event(AI_INT)-Count)*(long long)ai_register.current_len)/ + ai_register.current_delay; + else + *rdword = 0; + *rdword |= (unsigned long long)ai_register.ai_dram_addr << 32; + return; + break; + } + *rdword = ((unsigned long long int)(*readai[*address_low])<<32) | + *readai[*address_low+4]; +} + +void write_ai(void) +{ + unsigned int freq,delay=0; + switch (*address_low) + { + case 0x4: + ai_register.ai_len = word; + audio.aiLenChanged(); + + freq = ROM_PARAMS.aidacrate / (ai_register.ai_dacrate+1); + if (freq) + delay = (unsigned int) (((unsigned long long)ai_register.ai_len*vi_register.vi_delay*ROM_PARAMS.vilimit)/(freq*4)); + + if (ai_register.ai_status & 0x40000000) // busy + { + ai_register.next_delay = delay; + ai_register.next_len = ai_register.ai_len; + ai_register.ai_status |= 0x80000000; + } + else + { + ai_register.current_delay = delay; + ai_register.current_len = ai_register.ai_len; + update_count(); + add_interupt_event(AI_INT, delay); + ai_register.ai_status |= 0x40000000; + } + return; + break; + case 0xc: + MI_register.mi_intr_reg &= ~0x4; + check_interupt(); + return; + break; + case 0x10: + if (ai_register.ai_dacrate != word) + { + update_ai_dacrate(word); + } + return; + break; + } + *readai[*address_low] = word; +} + +void update_ai_dacrate(unsigned int word) +{ + ai_register.ai_dacrate = word; + audio.aiDacrateChanged(ROM_PARAMS.systemtype); +} + +void write_aib(void) +{ + int temp; + unsigned int delay=0; + switch (*address_low) + { + case 0x4: + case 0x5: + case 0x6: + case 0x7: + temp = ai_register.ai_len; + *((unsigned char*)&temp + + ((*address_low&3)^S8) ) = cpu_byte; + ai_register.ai_len = temp; + audio.aiLenChanged(); + + delay = (unsigned int) (((unsigned long long)ai_register.ai_len*(ai_register.ai_dacrate+1)* + vi_register.vi_delay*ROM_PARAMS.vilimit)/ROM_PARAMS.aidacrate); + //delay = 0; + + if (ai_register.ai_status & 0x40000000) // busy + { + ai_register.next_delay = delay; + ai_register.next_len = ai_register.ai_len; + ai_register.ai_status |= 0x80000000; + } + else + { + ai_register.current_delay = delay; + ai_register.current_len = ai_register.ai_len; + update_count(); + add_interupt_event(AI_INT, delay/2); + ai_register.ai_status |= 0x40000000; + } + return; + break; + case 0xc: + case 0xd: + case 0xe: + case 0xf: + MI_register.mi_intr_reg &= ~0x4; + check_interupt(); + return; + break; + case 0x10: + case 0x11: + case 0x12: + case 0x13: + temp = ai_register.ai_dacrate; + *((unsigned char*)&temp + + ((*address_low&3)^S8) ) = cpu_byte; + if (ai_register.ai_dacrate != temp) + { + update_ai_dacrate(temp); + } + return; + break; + } + *((unsigned char*)readai[*address_low & 0xfffc] + + ((*address_low&3)^S8) ) = cpu_byte; +} + +void write_aih(void) +{ + int temp; + unsigned int delay=0; + switch (*address_low) + { + case 0x4: + case 0x6: + temp = ai_register.ai_len; + *((unsigned short*)((unsigned char*)&temp + + ((*address_low&3)^S16) )) = hword; + ai_register.ai_len = temp; + audio.aiLenChanged(); + + delay = (unsigned int) (((unsigned long long)ai_register.ai_len*(ai_register.ai_dacrate+1)* + vi_register.vi_delay*ROM_PARAMS.vilimit)/ROM_PARAMS.aidacrate); + + if (ai_register.ai_status & 0x40000000) // busy + { + ai_register.next_delay = delay; + ai_register.next_len = ai_register.ai_len; + ai_register.ai_status |= 0x80000000; + } + else + { + ai_register.current_delay = delay; + ai_register.current_len = ai_register.ai_len; + update_count(); + add_interupt_event(AI_INT, delay/2); + ai_register.ai_status |= 0x40000000; + } + return; + break; + case 0xc: + case 0xe: + MI_register.mi_intr_reg &= ~0x4; + check_interupt(); + return; + break; + case 0x10: + case 0x12: + temp = ai_register.ai_dacrate; + *((unsigned short*)((unsigned char*)&temp + + ((*address_low&3)^S16) )) = hword; + if (ai_register.ai_dacrate != temp) + { + update_ai_dacrate(temp); + } + return; + break; + } + *((unsigned short*)((unsigned char*)readai[*address_low & 0xfffc] + + ((*address_low&3)^S16) )) = hword; +} + +void write_aid(void) +{ + unsigned int delay=0; + switch (*address_low) + { + case 0x0: + ai_register.ai_dram_addr = (unsigned int) (dword >> 32); + ai_register.ai_len = (unsigned int) (dword & 0xFFFFFFFF); + audio.aiLenChanged(); + + delay = (unsigned int) (((unsigned long long)ai_register.ai_len*(ai_register.ai_dacrate+1)* + vi_register.vi_delay*ROM_PARAMS.vilimit)/ROM_PARAMS.aidacrate); + + if (ai_register.ai_status & 0x40000000) // busy + { + ai_register.next_delay = delay; + ai_register.next_len = ai_register.ai_len; + ai_register.ai_status |= 0x80000000; + } + else + { + ai_register.current_delay = delay; + ai_register.current_len = ai_register.ai_len; + update_count(); + add_interupt_event(AI_INT, delay/2); + ai_register.ai_status |= 0x40000000; + } + return; + break; + case 0x8: + ai_register.ai_control = (unsigned int) (dword >> 32); + MI_register.mi_intr_reg &= ~0x4; + check_interupt(); + return; + break; + case 0x10: + if (ai_register.ai_dacrate != dword >> 32) + { + update_ai_dacrate((unsigned int) (dword >> 32)); + } + ai_register.ai_bitrate = (unsigned int) (dword & 0xFFFFFFFF); + return; + break; + } + *readai[*address_low] = (unsigned int) (dword >> 32); + *readai[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF); +} + +void read_pi(void) +{ + *rdword = *(readpi[*address_low]); +} + +void read_pib(void) +{ + *rdword = *((unsigned char*)readpi[*address_low & 0xfffc] + + ((*address_low&3)^S8) ); +} + +void read_pih(void) +{ + *rdword = *((unsigned short*)((unsigned char*)readpi[*address_low & 0xfffc] + + ((*address_low&3)^S16) )); +} + +void read_pid(void) +{ + *rdword = ((unsigned long long int)(*readpi[*address_low])<<32) | + *readpi[*address_low+4]; +} + +void write_pi(void) +{ + switch (*address_low) + { + case 0x8: + pi_register.pi_rd_len_reg = word; + dma_pi_read(); + return; + break; + case 0xc: + pi_register.pi_wr_len_reg = word; + dma_pi_write(); + return; + break; + case 0x10: + if (word & 2) MI_register.mi_intr_reg &= ~0x10; + check_interupt(); + return; + break; + case 0x14: + case 0x18: + case 0x1c: + case 0x20: + case 0x24: + case 0x28: + case 0x2c: + case 0x30: + *readpi[*address_low] = word & 0xFF; + return; + break; + } + *readpi[*address_low] = word; +} + +void write_pib(void) +{ + switch (*address_low) + { + case 0x8: + case 0x9: + case 0xa: + case 0xb: + *((unsigned char*)&pi_register.pi_rd_len_reg + + ((*address_low&3)^S8) ) = cpu_byte; + dma_pi_read(); + return; + break; + case 0xc: + case 0xd: + case 0xe: + case 0xf: + *((unsigned char*)&pi_register.pi_wr_len_reg + + ((*address_low&3)^S8) ) = cpu_byte; + dma_pi_write(); + return; + break; + case 0x10: + case 0x11: + case 0x12: + case 0x13: + if (word) MI_register.mi_intr_reg &= ~0x10; + check_interupt(); + return; + break; + case 0x14: + case 0x15: + case 0x16: + case 0x18: + case 0x19: + case 0x1a: + case 0x1c: + case 0x1d: + case 0x1e: + case 0x20: + case 0x21: + case 0x22: + case 0x24: + case 0x25: + case 0x26: + case 0x28: + case 0x29: + case 0x2a: + case 0x2c: + case 0x2d: + case 0x2e: + case 0x30: + case 0x31: + case 0x32: + return; + break; + } + *((unsigned char*)readpi[*address_low & 0xfffc] + + ((*address_low&3)^S8) ) = cpu_byte; +} + +void write_pih(void) +{ + switch (*address_low) + { + case 0x8: + case 0xa: + *((unsigned short*)((unsigned char*)&pi_register.pi_rd_len_reg + + ((*address_low&3)^S16) )) = hword; + dma_pi_read(); + return; + break; + case 0xc: + case 0xe: + *((unsigned short*)((unsigned char*)&pi_register.pi_wr_len_reg + + ((*address_low&3)^S16) )) = hword; + dma_pi_write(); + return; + break; + case 0x10: + case 0x12: + if (word) MI_register.mi_intr_reg &= ~0x10; + check_interupt(); + return; + break; + case 0x16: + case 0x1a: + case 0x1e: + case 0x22: + case 0x26: + case 0x2a: + case 0x2e: + case 0x32: + *((unsigned short*)((unsigned char*)readpi[*address_low & 0xfffc] + + ((*address_low&3)^S16) )) = hword & 0xFF; + return; + break; + case 0x14: + case 0x18: + case 0x1c: + case 0x20: + case 0x24: + case 0x28: + case 0x2c: + case 0x30: + return; + break; + } + *((unsigned short*)((unsigned char*)readpi[*address_low & 0xfffc] + + ((*address_low&3)^S16) )) = hword; +} + +void write_pid(void) +{ + switch (*address_low) + { + case 0x8: + pi_register.pi_rd_len_reg = (unsigned int) (dword >> 32); + dma_pi_read(); + pi_register.pi_wr_len_reg = (unsigned int) (dword & 0xFFFFFFFF); + dma_pi_write(); + return; + break; + case 0x10: + if (word) MI_register.mi_intr_reg &= ~0x10; + check_interupt(); + *readpi[*address_low+4] = (unsigned int) (dword & 0xFF); + return; + break; + case 0x18: + case 0x20: + case 0x28: + case 0x30: + *readpi[*address_low] = (unsigned int) (dword >> 32) & 0xFF; + *readpi[*address_low+4] = (unsigned int) (dword & 0xFF); + return; + break; + } + *readpi[*address_low] = (unsigned int) (dword >> 32); + *readpi[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF); +} + +void read_ri(void) +{ + *rdword = *(readri[*address_low]); +} + +void read_rib(void) +{ + *rdword = *((unsigned char*)readri[*address_low & 0xfffc] + + ((*address_low&3)^S8) ); +} + +void read_rih(void) +{ + *rdword = *((unsigned short*)((unsigned char*)readri[*address_low & 0xfffc] + + ((*address_low&3)^S16) )); +} + +void read_rid(void) +{ + *rdword = ((unsigned long long int)(*readri[*address_low])<<32) | + *readri[*address_low+4]; +} + +void write_ri(void) +{ + *readri[*address_low] = word; +} + +void write_rib(void) +{ + *((unsigned char*)readri[*address_low & 0xfffc] + + ((*address_low&3)^S8) ) = cpu_byte; +} + +void write_rih(void) +{ + *((unsigned short*)((unsigned char*)readri[*address_low & 0xfffc] + + ((*address_low&3)^S16) )) = hword; +} + +void write_rid(void) +{ + *readri[*address_low] = (unsigned int) (dword >> 32); + *readri[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF); +} + +void read_si(void) +{ + *rdword = *(readsi[*address_low]); +} + +void read_sib(void) +{ + *rdword = *((unsigned char*)readsi[*address_low & 0xfffc] + + ((*address_low&3)^S8) ); +} + +void read_sih(void) +{ + *rdword = *((unsigned short*)((unsigned char*)readsi[*address_low & 0xfffc] + + ((*address_low&3)^S16) )); +} + +void read_sid(void) +{ + *rdword = ((unsigned long long int)(*readsi[*address_low])<<32) | + *readsi[*address_low+4]; +} + +void write_si(void) +{ + switch (*address_low) + { + case 0x0: + si_register.si_dram_addr = word; + return; + break; + case 0x4: + si_register.si_pif_addr_rd64b = word; + dma_si_read(); + return; + break; + case 0x10: + si_register.si_pif_addr_wr64b = word; + dma_si_write(); + return; + break; + case 0x18: + MI_register.mi_intr_reg &= ~0x2; + si_register.si_stat &= ~0x1000; + check_interupt(); + return; + break; + } +} + +void write_sib(void) +{ + switch (*address_low) + { + case 0x0: + case 0x1: + case 0x2: + case 0x3: + *((unsigned char*)&si_register.si_dram_addr + + ((*address_low&3)^S8) ) = cpu_byte; + return; + break; + case 0x4: + case 0x5: + case 0x6: + case 0x7: + *((unsigned char*)&si_register.si_pif_addr_rd64b + + ((*address_low&3)^S8) ) = cpu_byte; + dma_si_read(); + return; + break; + case 0x10: + case 0x11: + case 0x12: + case 0x13: + *((unsigned char*)&si_register.si_pif_addr_wr64b + + ((*address_low&3)^S8) ) = cpu_byte; + dma_si_write(); + return; + break; + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + MI_register.mi_intr_reg &= ~0x2; + si_register.si_stat &= ~0x1000; + check_interupt(); + return; + break; + } +} + +void write_sih(void) +{ + switch (*address_low) + { + case 0x0: + case 0x2: + *((unsigned short*)((unsigned char*)&si_register.si_dram_addr + + ((*address_low&3)^S16) )) = hword; + return; + break; + case 0x4: + case 0x6: + *((unsigned short*)((unsigned char*)&si_register.si_pif_addr_rd64b + + ((*address_low&3)^S16) )) = hword; + dma_si_read(); + return; + break; + case 0x10: + case 0x12: + *((unsigned short*)((unsigned char*)&si_register.si_pif_addr_wr64b + + ((*address_low&3)^S16) )) = hword; + dma_si_write(); + return; + break; + case 0x18: + case 0x1a: + MI_register.mi_intr_reg &= ~0x2; + si_register.si_stat &= ~0x1000; + check_interupt(); + return; + break; + } +} + +void write_sid(void) +{ + switch (*address_low) + { + case 0x0: + si_register.si_dram_addr = (unsigned int) (dword >> 32); + si_register.si_pif_addr_rd64b = (unsigned int) (dword & 0xFFFFFFFF); + dma_si_read(); + return; + break; + case 0x10: + si_register.si_pif_addr_wr64b = (unsigned int) (dword >> 32); + dma_si_write(); + return; + break; + case 0x18: + MI_register.mi_intr_reg &= ~0x2; + si_register.si_stat &= ~0x1000; + check_interupt(); + return; + break; + } +} + +void read_flashram_status(void) +{ + if (flashram_info.use_flashram != -1 && *address_low == 0) + { + *rdword = flashram_status(); + flashram_info.use_flashram = 1; + } + else + DebugMessage(M64MSG_ERROR, "unknown read in read_flashram_status()"); +} + +void read_flashram_statusb(void) +{ + DebugMessage(M64MSG_ERROR, "read_flashram_statusb() not implemented"); +} + +void read_flashram_statush(void) +{ + DebugMessage(M64MSG_ERROR, "read_flashram_statush() not implemented"); +} + +void read_flashram_statusd(void) +{ + DebugMessage(M64MSG_ERROR, "read_flashram_statusd() not implemented"); +} + +void write_flashram_dummy(void) +{ +} + +void write_flashram_dummyb(void) +{ +} + +void write_flashram_dummyh(void) +{ +} + +void write_flashram_dummyd(void) +{ +} + +void write_flashram_command(void) +{ + if (flashram_info.use_flashram != -1 && *address_low == 0) + { + flashram_command(word); + flashram_info.use_flashram = 1; + } + else + DebugMessage(M64MSG_ERROR, "unknown write in write_flashram_command()"); +} + +void write_flashram_commandb(void) +{ + DebugMessage(M64MSG_ERROR, "write_flashram_commandb() not implemented"); +} + +void write_flashram_commandh(void) +{ + DebugMessage(M64MSG_ERROR, "write_flashram_commandh() not implemented"); +} + +void write_flashram_commandd(void) +{ + DebugMessage(M64MSG_ERROR, "write_flashram_commandd() not implemented"); +} + +static unsigned int lastwrite = 0; + +void read_rom(void) +{ + if (lastwrite) + { + *rdword = lastwrite; + lastwrite = 0; + } + else + *rdword = *((unsigned int *)(rom + (address & 0x03FFFFFF))); +} + +void read_romb(void) +{ + *rdword = *(rom + ((address^S8) & 0x03FFFFFF)); +} + +void read_romh(void) +{ + *rdword = *((unsigned short *)(rom + ((address^S16) & 0x03FFFFFF))); +} + +void read_romd(void) +{ + *rdword = ((unsigned long long)(*((unsigned int *)(rom+(address&0x03FFFFFF))))<<32)| + *((unsigned int *)(rom + ((address+4)&0x03FFFFFF))); +} + +void write_rom(void) +{ + lastwrite = word; +} + +void read_pif(void) +{ + if ((*address_low > 0x7FF) || (*address_low < 0x7C0)) + { + DebugMessage(M64MSG_ERROR, "reading a word in PIF at invalid address 0x%x", address); + *rdword = 0; + return; + } + + *rdword = sl(*((unsigned int *)(PIF_RAMb + (address & 0x7FF) - 0x7C0))); +} + +void read_pifb(void) +{ + if ((*address_low > 0x7FF) || (*address_low < 0x7C0)) + { + DebugMessage(M64MSG_ERROR, "reading a byte in PIF at invalid address 0x%x", address); + *rdword = 0; + return; + } + + *rdword = *(PIF_RAMb + ((address & 0x7FF) - 0x7C0)); +} + +void read_pifh(void) +{ + if ((*address_low > 0x7FF) || (*address_low < 0x7C0)) + { + DebugMessage(M64MSG_ERROR, "reading a hword in PIF at invalid address 0x%x", address); + *rdword = 0; + return; + } + + *rdword = (*(PIF_RAMb + ((address & 0x7FF) - 0x7C0)) << 8) | + *(PIF_RAMb + (((address+1) & 0x7FF) - 0x7C0)); +} + +void read_pifd(void) +{ + if ((*address_low > 0x7FF) || (*address_low < 0x7C0)) + { + DebugMessage(M64MSG_ERROR, "reading a double word in PIF in invalid address 0x%x", address); + *rdword = 0; + return; + } + + *rdword = ((unsigned long long)sl(*((unsigned int *)(PIF_RAMb + (address & 0x7FF) - 0x7C0))) << 32)| + sl(*((unsigned int *)(PIF_RAMb + ((address+4) & 0x7FF) - 0x7C0))); +} + +void write_pif(void) +{ + if ((*address_low > 0x7FF) || (*address_low < 0x7C0)) + { + DebugMessage(M64MSG_ERROR, "writing a word in PIF at invalid address 0x%x", address); + return; + } + + *((unsigned int *)(PIF_RAMb + (address & 0x7FF) - 0x7C0)) = sl(word); + if ((address & 0x7FF) == 0x7FC) + { + if (PIF_RAMb[0x3F] == 0x08) + { + PIF_RAMb[0x3F] = 0; + update_count(); + add_interupt_event(SI_INT, /*0x100*/0x900); + } + else + update_pif_write(); + } +} + +void write_pifb(void) +{ + if ((*address_low > 0x7FF) || (*address_low < 0x7C0)) + { + DebugMessage(M64MSG_ERROR, "writing a byte in PIF at invalid address 0x%x", address); + return; + } + + *(PIF_RAMb + (address & 0x7FF) - 0x7C0) = cpu_byte; + if ((address & 0x7FF) == 0x7FF) + { + if (PIF_RAMb[0x3F] == 0x08) + { + PIF_RAMb[0x3F] = 0; + update_count(); + add_interupt_event(SI_INT, /*0x100*/0x900); + } + else + update_pif_write(); + } +} + +void write_pifh(void) +{ + if ((*address_low > 0x7FF) || (*address_low < 0x7C0)) + { + DebugMessage(M64MSG_ERROR, "writing a hword in PIF at invalid address 0x%x", address); + return; + } + + *(PIF_RAMb + (address & 0x7FF) - 0x7C0) = hword >> 8; + *(PIF_RAMb + ((address+1) & 0x7FF) - 0x7C0) = hword & 0xFF; + if ((address & 0x7FF) == 0x7FE) + { + if (PIF_RAMb[0x3F] == 0x08) + { + PIF_RAMb[0x3F] = 0; + update_count(); + add_interupt_event(SI_INT, /*0x100*/0x900); + } + else + update_pif_write(); + } +} + +void write_pifd(void) +{ + if ((*address_low > 0x7FF) || (*address_low < 0x7C0)) + { + DebugMessage(M64MSG_ERROR, "writing a double word in PIF at 0x%x", address); + return; + } + + *((unsigned int *)(PIF_RAMb + (address & 0x7FF) - 0x7C0)) = + sl((unsigned int)(dword >> 32)); + *((unsigned int *)(PIF_RAMb + (address & 0x7FF) - 0x7C0)) = + sl((unsigned int)(dword & 0xFFFFFFFF)); + if ((address & 0x7FF) == 0x7F8) + { + if (PIF_RAMb[0x3F] == 0x08) + { + PIF_RAMb[0x3F] = 0; + update_count(); + add_interupt_event(SI_INT, /*0x100*/0x900); + } + else + update_pif_write(); + } +} + +unsigned int *fast_mem_access(unsigned int address) +{ + /* This code is performance critical, specially on pure interpreter mode. + * Removing error checking saves some time, but the emulator may crash. */ + if (address < 0x80000000 || address >= 0xc0000000) + address = virtual_to_physical_address(address, 2); + + if ((address & 0x1FFFFFFF) >= 0x10000000) + return (unsigned int *)rom + ((address & 0x1FFFFFFF) - 0x10000000)/4; + else if ((address & 0x1FFFFFFF) < 0x800000) + return (unsigned int *)rdram + (address & 0x1FFFFFFF)/4; + else if (address >= 0xa4000000 && address <= 0xa4001000) + return (unsigned int *)SP_DMEM + (address & 0xFFF)/4; + else if ((address >= 0xa4001000 && address <= 0xa4002000)) + return (unsigned int *)SP_IMEM + (address & 0xFFF)/4; + else + return NULL; +}