2012-12-19 09:30:18 +00:00
/****************************************************************************
* *
2015-11-10 05:21:49 +00:00
* Project64 - A Nintendo 64 emulator . *
2012-12-19 09:30:18 +00:00
* http : //www.pj64-emu.com/ *
* Copyright ( C ) 2012 Project64 . All rights reserved . *
* *
* License : *
* GNU / GPLv2 http : //www.gnu.org/licenses/gpl-2.0.html *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-06-22 20:36:28 +00:00
# include "stdafx.h"
2016-01-13 11:20:34 +00:00
# include <Common/MemoryManagement.h>
2016-01-13 15:21:58 +00:00
2016-01-13 11:15:30 +00:00
# include <Project64-core/N64System/Mips/Dma.h>
2015-12-06 09:59:58 +00:00
# include <Project64-core/N64System/SystemGlobals.h>
# include <Project64-core/N64System/N64RomClass.h>
2015-12-21 07:35:22 +00:00
# include <Project64-core/N64System/Mips/MemoryVirtualMem.h>
2015-12-06 09:59:58 +00:00
# include <Project64-core/N64System/Mips/RegisterClass.h>
2016-01-20 13:31:29 +00:00
# include <Project64-core/N64System/Mips/Disk.h>
2016-01-20 16:43:23 +00:00
# include <Project64-core/N64System/N64DiskClass.h>
2015-12-06 09:59:58 +00:00
# include <Project64-core/N64System/N64Class.h>
2010-06-22 20:36:28 +00:00
CDMA : : CDMA ( CFlashram & FlashRam , CSram & Sram ) :
2016-01-13 11:20:34 +00:00
m_FlashRam ( FlashRam ) ,
m_Sram ( Sram )
2010-06-22 20:36:28 +00:00
{
}
2015-04-28 22:19:02 +00:00
void CDMA : : OnFirstDMA ( )
2015-03-29 17:19:28 +00:00
{
2015-11-16 15:21:50 +00:00
int16_t offset ;
2015-11-16 15:13:36 +00:00
const uint32_t base = 0x00000000 ;
2015-11-16 15:21:50 +00:00
const uint32_t rt = g_MMU - > RdramSize ( ) ;
2015-11-16 15:13:36 +00:00
2015-11-15 00:52:24 +00:00
switch ( g_Rom - > CicChipID ( ) )
{
2015-11-16 15:21:50 +00:00
case CIC_NUS_6101 : offset = + 0x0318 ; break ;
case CIC_NUS_5167 : offset = + 0x0318 ; break ;
2016-01-18 19:15:01 +00:00
case CIC_NUS_8303 : offset = + 0x0318 ; break ;
2016-08-28 16:36:56 +00:00
case CIC_NUS_DDUS : offset = + 0x0318 ; break ;
2019-08-11 09:45:52 +00:00
case CIC_NUS_DDTL : offset = + 0x0318 ; break ;
2015-11-15 00:52:24 +00:00
case CIC_UNKNOWN :
2015-11-16 15:21:50 +00:00
case CIC_NUS_6102 : offset = + 0x0318 ; break ;
case CIC_NUS_6103 : offset = + 0x0318 ; break ;
case CIC_NUS_6105 : offset = + 0x03F0 ; break ;
case CIC_NUS_6106 : offset = + 0x0318 ; break ;
default :
2015-12-23 20:04:36 +00:00
g_Notify - > DisplayError ( stdstr_f ( " Unhandled CicChip(%d) in first DMA " , g_Rom - > CicChipID ( ) ) . c_str ( ) ) ;
2015-11-16 15:21:50 +00:00
return ;
2015-11-15 00:52:24 +00:00
}
2015-11-16 15:21:50 +00:00
g_MMU - > SW_PAddr ( base + offset , rt ) ;
2010-06-22 20:36:28 +00:00
}
2015-04-28 22:19:02 +00:00
void CDMA : : PI_DMA_READ ( )
2015-03-29 17:19:28 +00:00
{
2015-11-15 00:52:24 +00:00
// PI_STATUS_REG |= PI_STATUS_DMA_BUSY;
uint32_t PI_RD_LEN_REG = ( ( g_Reg - > PI_RD_LEN_REG ) & 0x00FFFFFFul ) + 1 ;
if ( ( PI_RD_LEN_REG & 1 ) ! = 0 )
{
PI_RD_LEN_REG + = 1 ;
}
if ( g_Reg - > PI_DRAM_ADDR_REG + PI_RD_LEN_REG > g_MMU - > RdramSize ( ) )
{
2018-01-15 21:23:21 +00:00
if ( HaveDebugger ( ) )
2015-11-15 00:52:24 +00:00
{
2015-12-23 20:04:36 +00:00
g_Notify - > DisplayError ( stdstr_f ( " PI_DMA_READ not in Memory: %08X " , g_Reg - > PI_DRAM_ADDR_REG + PI_RD_LEN_REG ) . c_str ( ) ) ;
2015-11-15 00:52:24 +00:00
}
g_Reg - > PI_STATUS_REG & = ~ PI_STATUS_DMA_BUSY ;
g_Reg - > MI_INTR_REG | = MI_INTR_PI ;
g_Reg - > CheckInterrupts ( ) ;
return ;
}
2016-01-20 13:31:29 +00:00
//64DD Buffers Write
if ( g_Reg - > PI_CART_ADDR_REG > = 0x05000000 & & g_Reg - > PI_CART_ADDR_REG < = 0x050003FF )
{
//64DD C2 Sectors (don't care)
2016-01-23 21:44:58 +00:00
g_SystemTimer - > SetTimer ( g_SystemTimer - > DDPiTimer , ( PI_RD_LEN_REG * 63 ) / 25 , false ) ;
2016-01-20 13:31:29 +00:00
return ;
}
if ( g_Reg - > PI_CART_ADDR_REG > = 0x05000400 & & g_Reg - > PI_CART_ADDR_REG < = 0x050004FF )
{
//64DD User Sector
uint32_t i ;
uint8_t * RDRAM = g_MMU - > Rdram ( ) ;
2016-01-20 16:43:23 +00:00
uint8_t * DISK = g_Disk - > GetDiskAddressBuffer ( ) ;
2016-01-20 13:31:29 +00:00
for ( i = 0 ; i < PI_RD_LEN_REG ; i + + )
{
2016-01-20 16:43:23 +00:00
* ( DISK + ( i ^ 3 ) ) = * ( RDRAM + ( ( g_Reg - > PI_DRAM_ADDR_REG + i ) ^ 3 ) ) ;
2016-01-20 13:31:29 +00:00
}
2016-01-23 21:44:58 +00:00
g_SystemTimer - > SetTimer ( g_SystemTimer - > DDPiTimer , ( PI_RD_LEN_REG * 63 ) / 25 , false ) ;
2016-01-20 13:31:29 +00:00
return ;
}
if ( g_Reg - > PI_CART_ADDR_REG > = 0x05000580 & & g_Reg - > PI_CART_ADDR_REG < = 0x050005BF )
{
//64DD MSEQ (don't care)
g_Reg - > PI_STATUS_REG & = ~ PI_STATUS_DMA_BUSY ;
g_Reg - > MI_INTR_REG | = MI_INTR_PI ;
g_Reg - > CheckInterrupts ( ) ;
return ;
}
2015-11-15 00:52:24 +00:00
//Write ROM Area (for 64DD Convert)
if ( g_Reg - > PI_CART_ADDR_REG > = 0x10000000 & & g_Reg - > PI_CART_ADDR_REG < = 0x1FBFFFFF & & g_Settings - > LoadBool ( Game_AllowROMWrites ) )
{
uint32_t i ;
uint8_t * ROM = g_Rom - > GetRomAddress ( ) ;
uint8_t * RDRAM = g_MMU - > Rdram ( ) ;
2016-01-18 19:15:01 +00:00
ProtectMemory ( ROM , g_Rom - > GetRomSize ( ) , MEM_READWRITE ) ;
2015-11-15 00:52:24 +00:00
g_Reg - > PI_CART_ADDR_REG - = 0x10000000 ;
if ( g_Reg - > PI_CART_ADDR_REG + PI_RD_LEN_REG < g_Rom - > GetRomSize ( ) )
{
for ( i = 0 ; i < PI_RD_LEN_REG ; i + + )
{
* ( ROM + ( ( g_Reg - > PI_CART_ADDR_REG + i ) ^ 3 ) ) = * ( RDRAM + ( ( g_Reg - > PI_DRAM_ADDR_REG + i ) ^ 3 ) ) ;
}
}
else
{
uint32_t Len ;
Len = g_Rom - > GetRomSize ( ) - g_Reg - > PI_CART_ADDR_REG ;
for ( i = 0 ; i < Len ; i + + )
{
* ( ROM + ( ( g_Reg - > PI_CART_ADDR_REG + i ) ^ 3 ) ) = * ( RDRAM + ( ( g_Reg - > PI_DRAM_ADDR_REG + i ) ^ 3 ) ) ;
}
}
g_Reg - > PI_CART_ADDR_REG + = 0x10000000 ;
if ( ! g_System - > DmaUsed ( ) )
{
g_System - > SetDmaUsed ( true ) ;
OnFirstDMA ( ) ;
}
if ( g_Recompiler & & g_System - > bSMM_PIDMA ( ) )
{
g_Recompiler - > ClearRecompCode_Phys ( g_Reg - > PI_DRAM_ADDR_REG , g_Reg - > PI_WR_LEN_REG , CRecompiler : : Remove_DMA ) ;
}
2016-01-18 19:15:01 +00:00
ProtectMemory ( ROM , g_Rom - > GetRomSize ( ) , MEM_READONLY ) ;
2015-11-15 00:52:24 +00:00
g_Reg - > PI_STATUS_REG & = ~ PI_STATUS_DMA_BUSY ;
g_Reg - > MI_INTR_REG | = MI_INTR_PI ;
g_Reg - > CheckInterrupts ( ) ;
return ;
}
if ( g_Reg - > PI_CART_ADDR_REG > = 0x08000000 & & g_Reg - > PI_CART_ADDR_REG < = 0x08010000 )
{
if ( g_System - > m_SaveUsing = = SaveChip_Auto )
{
g_System - > m_SaveUsing = SaveChip_Sram ;
}
if ( g_System - > m_SaveUsing = = SaveChip_Sram )
{
m_Sram . DmaToSram (
g_MMU - > Rdram ( ) + g_Reg - > PI_DRAM_ADDR_REG ,
g_Reg - > PI_CART_ADDR_REG - 0x08000000 ,
PI_RD_LEN_REG
) ;
g_Reg - > PI_STATUS_REG & = ~ PI_STATUS_DMA_BUSY ;
g_Reg - > MI_INTR_REG | = MI_INTR_PI ;
g_Reg - > CheckInterrupts ( ) ;
return ;
}
if ( g_System - > m_SaveUsing = = SaveChip_FlashRam )
{
m_FlashRam . DmaToFlashram (
g_MMU - > Rdram ( ) + g_Reg - > PI_DRAM_ADDR_REG ,
g_Reg - > PI_CART_ADDR_REG - 0x08000000 ,
PI_RD_LEN_REG
) ;
g_Reg - > PI_STATUS_REG & = ~ PI_STATUS_DMA_BUSY ;
g_Reg - > MI_INTR_REG | = MI_INTR_PI ;
g_Reg - > CheckInterrupts ( ) ;
return ;
}
}
if ( g_System - > m_SaveUsing = = SaveChip_FlashRam )
{
2015-12-23 20:04:36 +00:00
g_Notify - > DisplayError ( stdstr_f ( " **** FLashRam DMA Read address %08X ***** " , g_Reg - > PI_CART_ADDR_REG ) . c_str ( ) ) ;
2015-11-15 00:52:24 +00:00
g_Reg - > PI_STATUS_REG & = ~ PI_STATUS_DMA_BUSY ;
g_Reg - > MI_INTR_REG | = MI_INTR_PI ;
g_Reg - > CheckInterrupts ( ) ;
return ;
}
2018-01-15 21:23:21 +00:00
if ( HaveDebugger ( ) )
2015-11-15 00:52:24 +00:00
{
2015-12-23 20:04:36 +00:00
g_Notify - > DisplayError ( stdstr_f ( " PI_DMA_READ where are you dmaing to ? : %08X " , g_Reg - > PI_CART_ADDR_REG ) . c_str ( ) ) ;
2015-11-15 00:52:24 +00:00
}
g_Reg - > PI_STATUS_REG & = ~ PI_STATUS_DMA_BUSY ;
g_Reg - > MI_INTR_REG | = MI_INTR_PI ;
g_Reg - > CheckInterrupts ( ) ;
return ;
2010-06-22 20:36:28 +00:00
}
2015-04-28 22:19:02 +00:00
void CDMA : : PI_DMA_WRITE ( )
2015-02-12 21:26:17 +00:00
{
2016-02-10 01:21:29 +00:00
/* rounding PI_WR_LEN_REG up to the nearest even number fixes AI Shougi 3, Doraemon 3, etc. */
2018-02-27 06:27:17 +00:00
uint32_t PI_WR_LEN_REG = ( ( g_Reg - > PI_WR_LEN_REG ) & 0x00FFFFFEul ) + 2 ;
2018-12-28 12:09:38 +00:00
uint32_t PI_CART_ADDR_REG = ! g_Settings - > LoadBool ( Game_UnalignedDMA ) ? g_Reg - > PI_CART_ADDR_REG & ~ 1 : g_Reg - > PI_CART_ADDR_REG ;
2015-11-15 00:52:24 +00:00
g_Reg - > PI_STATUS_REG | = PI_STATUS_DMA_BUSY ;
if ( g_Reg - > PI_DRAM_ADDR_REG + PI_WR_LEN_REG > g_MMU - > RdramSize ( ) )
{
2015-12-23 20:04:36 +00:00
if ( g_Settings - > LoadBool ( Debugger_ShowUnhandledMemory ) ) { g_Notify - > DisplayError ( stdstr_f ( " PI_DMA_WRITE not in Memory: %08X " , g_Reg - > PI_DRAM_ADDR_REG + PI_WR_LEN_REG ) . c_str ( ) ) ; }
2015-11-15 00:52:24 +00:00
g_Reg - > PI_STATUS_REG & = ~ PI_STATUS_DMA_BUSY ;
g_Reg - > MI_INTR_REG | = MI_INTR_PI ;
g_Reg - > CheckInterrupts ( ) ;
return ;
}
2016-01-20 13:31:29 +00:00
//64DD Buffers Read
2018-02-27 06:27:17 +00:00
if ( PI_CART_ADDR_REG > = 0x05000000 & & PI_CART_ADDR_REG < = 0x050003FF )
2016-01-18 19:15:01 +00:00
{
2016-01-20 13:31:29 +00:00
//64DD C2 Sectors (just read 0)
2016-01-18 19:15:01 +00:00
uint32_t i ;
2016-01-20 13:31:29 +00:00
uint8_t * RDRAM = g_MMU - > Rdram ( ) ;
for ( i = 0 ; i < PI_WR_LEN_REG ; i + + )
{
* ( RDRAM + ( ( g_Reg - > PI_DRAM_ADDR_REG + i ) ^ 3 ) ) = 0 ;
}
2016-01-23 21:44:58 +00:00
//Timer is needed for Track Read
g_SystemTimer - > SetTimer ( g_SystemTimer - > DDPiTimer , ( PI_WR_LEN_REG * 63 ) / 25 , false ) ;
2016-01-20 13:31:29 +00:00
return ;
}
2016-01-18 19:15:01 +00:00
2018-02-27 06:27:17 +00:00
if ( PI_CART_ADDR_REG > = 0x05000400 & & PI_CART_ADDR_REG < = 0x050004FF )
2016-01-20 13:31:29 +00:00
{
//64DD User Sector
uint32_t i ;
uint8_t * RDRAM = g_MMU - > Rdram ( ) ;
2016-01-20 16:43:23 +00:00
uint8_t * DISK = g_Disk - > GetDiskAddressBuffer ( ) ;
2016-01-20 13:31:29 +00:00
for ( i = 0 ; i < PI_WR_LEN_REG ; i + + )
2016-01-18 19:15:01 +00:00
{
2016-01-20 16:43:23 +00:00
* ( RDRAM + ( ( g_Reg - > PI_DRAM_ADDR_REG + i ) ^ 3 ) ) = * ( DISK + ( i ^ 3 ) ) ;
2016-01-18 19:15:01 +00:00
}
2016-01-23 21:44:58 +00:00
//Timer is needed for Track Read
g_SystemTimer - > SetTimer ( g_SystemTimer - > DDPiTimer , ( PI_WR_LEN_REG * 63 ) / 25 , false ) ;
2016-01-20 13:31:29 +00:00
return ;
}
2018-02-27 06:27:17 +00:00
if ( PI_CART_ADDR_REG > = 0x05000580 & & PI_CART_ADDR_REG < = 0x050005BF )
2016-01-20 13:31:29 +00:00
{
//64DD MSEQ (don't care)
g_Reg - > PI_STATUS_REG & = ~ PI_STATUS_DMA_BUSY ;
g_Reg - > MI_INTR_REG | = MI_INTR_PI ;
g_Reg - > CheckInterrupts ( ) ;
return ;
}
//64DD IPL ROM
2018-02-27 06:27:17 +00:00
if ( PI_CART_ADDR_REG > = 0x06000000 & & PI_CART_ADDR_REG < = 0x063FFFFF )
2016-01-20 13:31:29 +00:00
{
uint32_t i ;
2016-01-18 19:15:01 +00:00
uint8_t * ROM = g_DDRom - > GetRomAddress ( ) ;
uint8_t * RDRAM = g_MMU - > Rdram ( ) ;
2018-02-27 06:27:17 +00:00
PI_CART_ADDR_REG - = 0x06000000 ;
if ( PI_CART_ADDR_REG + PI_WR_LEN_REG < g_DDRom - > GetRomSize ( ) )
2016-01-18 19:15:01 +00:00
{
for ( i = 0 ; i < PI_WR_LEN_REG ; i + + )
{
2018-02-27 06:27:17 +00:00
* ( RDRAM + ( ( g_Reg - > PI_DRAM_ADDR_REG + i ) ^ 3 ) ) = * ( ROM + ( ( PI_CART_ADDR_REG + i ) ^ 3 ) ) ;
2016-01-18 19:15:01 +00:00
}
}
2018-02-27 06:27:17 +00:00
else if ( PI_CART_ADDR_REG > = g_DDRom - > GetRomSize ( ) )
2016-01-18 19:15:01 +00:00
{
2018-02-27 06:27:17 +00:00
uint32_t cart = PI_CART_ADDR_REG - g_DDRom - > GetRomSize ( ) ;
2016-01-18 19:15:01 +00:00
while ( cart > = g_DDRom - > GetRomSize ( ) )
{
cart - = g_DDRom - > GetRomSize ( ) ;
}
for ( i = 0 ; i < PI_WR_LEN_REG ; i + + )
{
* ( RDRAM + ( ( g_Reg - > PI_DRAM_ADDR_REG + i ) ^ 3 ) ) = * ( ROM + ( ( cart + i ) ^ 3 ) ) ;
}
}
else
{
uint32_t Len ;
2018-02-27 06:27:17 +00:00
Len = g_DDRom - > GetRomSize ( ) - PI_CART_ADDR_REG ;
2016-01-18 19:15:01 +00:00
for ( i = 0 ; i < Len ; i + + )
{
2018-02-27 06:27:17 +00:00
* ( RDRAM + ( ( g_Reg - > PI_DRAM_ADDR_REG + i ) ^ 3 ) ) = * ( ROM + ( ( PI_CART_ADDR_REG + i ) ^ 3 ) ) ;
2016-01-18 19:15:01 +00:00
}
for ( i = Len ; i < PI_WR_LEN_REG - Len ; i + + )
{
* ( RDRAM + ( ( g_Reg - > PI_DRAM_ADDR_REG + i ) ^ 3 ) ) = 0 ;
}
}
2018-02-27 06:27:17 +00:00
PI_CART_ADDR_REG + = 0x06000000 ;
2016-01-18 19:15:01 +00:00
if ( ! g_System - > DmaUsed ( ) )
{
g_System - > SetDmaUsed ( true ) ;
OnFirstDMA ( ) ;
}
if ( g_Recompiler & & g_System - > bSMM_PIDMA ( ) )
{
g_Recompiler - > ClearRecompCode_Phys ( g_Reg - > PI_DRAM_ADDR_REG , g_Reg - > PI_WR_LEN_REG , CRecompiler : : Remove_DMA ) ;
}
g_Reg - > PI_STATUS_REG & = ~ PI_STATUS_DMA_BUSY ;
g_Reg - > MI_INTR_REG | = MI_INTR_PI ;
g_Reg - > CheckInterrupts ( ) ;
//ChangeTimer(PiTimer,(int32_t)(PI_WR_LEN_REG * 8.9) + 50);
//ChangeTimer(PiTimer,(int32_t)(PI_WR_LEN_REG * 8.9));
return ;
}
2018-02-27 06:27:17 +00:00
if ( PI_CART_ADDR_REG > = 0x08000000 & & PI_CART_ADDR_REG < = 0x08088000 )
2015-11-15 00:52:24 +00:00
{
if ( g_System - > m_SaveUsing = = SaveChip_Auto )
{
g_System - > m_SaveUsing = SaveChip_Sram ;
}
if ( g_System - > m_SaveUsing = = SaveChip_Sram )
{
m_Sram . DmaFromSram (
g_MMU - > Rdram ( ) + g_Reg - > PI_DRAM_ADDR_REG ,
2018-02-27 06:27:17 +00:00
PI_CART_ADDR_REG - 0x08000000 ,
2015-11-15 00:52:24 +00:00
PI_WR_LEN_REG
) ;
g_Reg - > PI_STATUS_REG & = ~ PI_STATUS_DMA_BUSY ;
g_Reg - > MI_INTR_REG | = MI_INTR_PI ;
g_Reg - > CheckInterrupts ( ) ;
return ;
}
if ( g_System - > m_SaveUsing = = SaveChip_FlashRam )
{
m_FlashRam . DmaFromFlashram (
g_MMU - > Rdram ( ) + g_Reg - > PI_DRAM_ADDR_REG ,
2018-02-27 06:27:17 +00:00
PI_CART_ADDR_REG - 0x08000000 ,
2015-11-15 00:52:24 +00:00
PI_WR_LEN_REG
) ;
g_Reg - > PI_STATUS_REG & = ~ PI_STATUS_DMA_BUSY ;
g_Reg - > MI_INTR_REG | = MI_INTR_PI ;
g_Reg - > CheckInterrupts ( ) ;
}
return ;
}
2018-02-27 06:27:17 +00:00
if ( PI_CART_ADDR_REG > = 0x10000000 & & PI_CART_ADDR_REG < = 0x1FFFFFFF )
2015-11-15 00:52:24 +00:00
{
uint32_t i ;
2015-05-14 12:34:45 +00:00
2015-12-15 06:01:06 +00:00
# ifdef legacycode
2010-06-22 20:36:28 +00:00
# ifdef ROM_IN_MAPSPACE
2015-11-15 00:52:24 +00:00
if ( WrittenToRom )
{
uint32_t OldProtect ;
VirtualProtect ( ROM , m_RomFileSize , PAGE_READONLY , & OldProtect ) ;
}
2010-06-22 20:36:28 +00:00
# endif
# endif
2015-05-14 12:34:45 +00:00
2015-11-15 00:52:24 +00:00
uint8_t * ROM = g_Rom - > GetRomAddress ( ) ;
uint8_t * RDRAM = g_MMU - > Rdram ( ) ;
2018-02-27 06:27:17 +00:00
PI_CART_ADDR_REG - = 0x10000000 ;
if ( PI_CART_ADDR_REG + PI_WR_LEN_REG < g_Rom - > GetRomSize ( ) )
2015-11-15 00:52:24 +00:00
{
2016-02-10 02:13:21 +00:00
size_t alignment ;
RDRAM + = g_Reg - > PI_DRAM_ADDR_REG ;
2018-02-27 06:27:17 +00:00
ROM + = PI_CART_ADDR_REG ;
2016-02-10 02:13:21 +00:00
alignment = PI_WR_LEN_REG | ( size_t ) RDRAM | ( size_t ) ROM ;
if ( ( alignment & 0x3 ) = = 0 )
2015-11-15 00:52:24 +00:00
{
2016-02-10 02:13:21 +00:00
for ( i = 0 ; i < PI_WR_LEN_REG ; i + = 4 )
{
* ( uint32_t * ) ( RDRAM + i ) = * ( uint32_t * ) ( ROM + i ) ;
}
}
else if ( ( alignment & 1 ) = = 0 )
{
if ( ( PI_WR_LEN_REG & 2 ) = = 0 )
{
if ( ( ( size_t ) RDRAM & 2 ) = = 0 )
{
for ( i = 0 ; i < PI_WR_LEN_REG ; i + = 4 )
{
* ( uint16_t * ) ( ( ( size_t ) RDRAM + i ) + 2 ) = * ( uint16_t * ) ( ( ( size_t ) ROM + i ) - 2 ) ;
* ( uint16_t * ) ( ( ( size_t ) RDRAM + i ) + 0 ) = * ( uint16_t * ) ( ( ( size_t ) ROM + i ) + 4 ) ;
}
}
else
{
if ( ( ( size_t ) ROM & 2 ) = = 0 )
{
for ( i = 0 ; i < PI_WR_LEN_REG ; i + = 4 )
{
* ( uint16_t * ) ( ( ( size_t ) RDRAM + i ) - 2 ) = * ( uint16_t * ) ( ( ( size_t ) ROM + i ) + 2 ) ;
* ( uint16_t * ) ( ( ( size_t ) RDRAM + i ) + 4 ) = * ( uint16_t * ) ( ( ( size_t ) ROM + i ) + 0 ) ;
}
}
else
{
for ( i = 0 ; i < PI_WR_LEN_REG ; i + = 4 )
{
* ( uint16_t * ) ( ( ( size_t ) RDRAM + i ) - 2 ) = * ( uint16_t * ) ( ( ( size_t ) ROM + i ) - 2 ) ;
* ( uint16_t * ) ( ( ( size_t ) RDRAM + i ) + 4 ) = * ( uint16_t * ) ( ( ( size_t ) ROM + i ) + 4 ) ;
}
}
}
}
else
{
for ( i = 0 ; i < PI_WR_LEN_REG ; i + = 2 )
{
* ( uint16_t * ) ( ( ( size_t ) RDRAM + i ) ^ 2 ) = * ( uint16_t * ) ( ( ( size_t ) ROM + i ) ^ 2 ) ;
}
}
}
else
{
for ( i = 0 ; i < PI_WR_LEN_REG ; i + + )
{
* ( uint8_t * ) ( ( ( size_t ) RDRAM + i ) ^ 3 ) = * ( uint8_t * ) ( ( ( size_t ) ROM + i ) ^ 3 ) ;
}
2015-11-15 00:52:24 +00:00
}
}
2018-02-27 06:27:17 +00:00
else if ( PI_CART_ADDR_REG > = g_Rom - > GetRomSize ( ) )
2015-11-15 00:52:24 +00:00
{
2018-02-27 06:27:17 +00:00
uint32_t cart = PI_CART_ADDR_REG - g_Rom - > GetRomSize ( ) ;
2015-11-15 00:52:24 +00:00
while ( cart > = g_Rom - > GetRomSize ( ) )
{
cart - = g_Rom - > GetRomSize ( ) ;
}
for ( i = 0 ; i < PI_WR_LEN_REG ; i + + )
{
* ( RDRAM + ( ( g_Reg - > PI_DRAM_ADDR_REG + i ) ^ 3 ) ) = * ( ROM + ( ( cart + i ) ^ 3 ) ) ;
}
}
else
{
uint32_t Len ;
2018-02-27 06:27:17 +00:00
Len = g_Rom - > GetRomSize ( ) - PI_CART_ADDR_REG ;
2015-11-15 00:52:24 +00:00
for ( i = 0 ; i < Len ; i + + )
{
2018-02-27 06:27:17 +00:00
* ( RDRAM + ( ( g_Reg - > PI_DRAM_ADDR_REG + i ) ^ 3 ) ) = * ( ROM + ( ( PI_CART_ADDR_REG + i ) ^ 3 ) ) ;
2015-11-15 00:52:24 +00:00
}
for ( i = Len ; i < PI_WR_LEN_REG - Len ; i + + )
{
* ( RDRAM + ( ( g_Reg - > PI_DRAM_ADDR_REG + i ) ^ 3 ) ) = 0 ;
}
}
2018-02-27 06:27:17 +00:00
PI_CART_ADDR_REG + = 0x10000000 ;
2015-11-15 00:52:24 +00:00
if ( ! g_System - > DmaUsed ( ) )
{
g_System - > SetDmaUsed ( true ) ;
OnFirstDMA ( ) ;
}
if ( g_Recompiler & & g_System - > bSMM_PIDMA ( ) )
{
g_Recompiler - > ClearRecompCode_Phys ( g_Reg - > PI_DRAM_ADDR_REG , g_Reg - > PI_WR_LEN_REG , CRecompiler : : Remove_DMA ) ;
}
2017-10-18 02:38:38 +00:00
g_SystemTimer - > SetTimer ( g_SystemTimer - > PiTimer , PI_WR_LEN_REG / 8 + ( g_Random - > next ( ) % 0x40 ) , false ) ;
//g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
//g_Reg->MI_INTR_REG |= MI_INTR_PI;
//g_Reg->CheckInterrupts();
2015-11-15 00:52:24 +00:00
//ChangeTimer(PiTimer,(int32_t)(PI_WR_LEN_REG * 8.9) + 50);
//ChangeTimer(PiTimer,(int32_t)(PI_WR_LEN_REG * 8.9));
return ;
}
2010-06-22 20:36:28 +00:00
2015-11-15 00:52:24 +00:00
if ( g_Settings - > LoadBool ( Debugger_ShowUnhandledMemory ) )
{
2018-02-27 06:27:17 +00:00
g_Notify - > DisplayError ( stdstr_f ( " PI_DMA_WRITE not in ROM: %08X " , PI_CART_ADDR_REG ) . c_str ( ) ) ;
2015-11-15 00:52:24 +00:00
}
g_Reg - > PI_STATUS_REG & = ~ PI_STATUS_DMA_BUSY ;
g_Reg - > MI_INTR_REG | = MI_INTR_PI ;
g_Reg - > CheckInterrupts ( ) ;
2010-06-22 20:36:28 +00:00
}
2015-04-28 22:19:02 +00:00
void CDMA : : SP_DMA_READ ( )
2015-11-15 00:52:24 +00:00
{
g_Reg - > SP_DRAM_ADDR_REG & = 0x1FFFFFFF ;
if ( g_Reg - > SP_DRAM_ADDR_REG > g_MMU - > RdramSize ( ) )
{
2018-01-15 21:23:21 +00:00
if ( HaveDebugger ( ) )
2015-11-15 00:52:24 +00:00
{
2016-01-13 11:20:34 +00:00
g_Notify - > DisplayError ( stdstr_f ( " %s \n SP_DRAM_ADDR_REG not in RDRam space : % 08X " , __FUNCTION__ , g_Reg - > SP_DRAM_ADDR_REG ) . c_str ( ) ) ;
2015-11-15 00:52:24 +00:00
}
g_Reg - > SP_DMA_BUSY_REG = 0 ;
g_Reg - > SP_STATUS_REG & = ~ SP_STATUS_DMA_BUSY ;
return ;
}
if ( g_Reg - > SP_RD_LEN_REG + 1 + ( g_Reg - > SP_MEM_ADDR_REG & 0xFFF ) > 0x1000 )
{
2018-01-15 21:23:21 +00:00
if ( HaveDebugger ( ) )
2015-11-15 00:52:24 +00:00
{
2016-01-13 11:20:34 +00:00
g_Notify - > DisplayError ( stdstr_f ( " %s \n Could not fit copy in memory segment " , __FUNCTION__ ) . c_str ( ) ) ;
2015-11-15 00:52:24 +00:00
}
return ;
}
2010-06-22 20:36:28 +00:00
2015-11-15 00:52:24 +00:00
if ( ( g_Reg - > SP_MEM_ADDR_REG & 3 ) ! = 0 )
{
2015-12-09 11:37:58 +00:00
g_Notify - > BreakPoint ( __FILE__ , __LINE__ ) ;
2015-11-15 00:52:24 +00:00
}
if ( ( g_Reg - > SP_DRAM_ADDR_REG & 3 ) ! = 0 )
{
2015-12-09 11:37:58 +00:00
g_Notify - > BreakPoint ( __FILE__ , __LINE__ ) ;
2015-11-15 00:52:24 +00:00
}
if ( ( ( g_Reg - > SP_RD_LEN_REG + 1 ) & 3 ) ! = 0 )
{
2015-12-09 11:37:58 +00:00
g_Notify - > BreakPoint ( __FILE__ , __LINE__ ) ;
2015-11-15 00:52:24 +00:00
}
memcpy ( g_MMU - > Dmem ( ) + ( g_Reg - > SP_MEM_ADDR_REG & 0x1FFF ) , g_MMU - > Rdram ( ) + g_Reg - > SP_DRAM_ADDR_REG ,
g_Reg - > SP_RD_LEN_REG + 1 ) ;
g_Reg - > SP_DMA_BUSY_REG = 0 ;
g_Reg - > SP_STATUS_REG & = ~ SP_STATUS_DMA_BUSY ;
2010-06-22 20:36:28 +00:00
}
2015-11-15 00:52:24 +00:00
void CDMA : : SP_DMA_WRITE ( )
{
if ( g_Reg - > SP_DRAM_ADDR_REG > g_MMU - > RdramSize ( ) )
{
2018-01-15 21:23:21 +00:00
if ( HaveDebugger ( ) )
2015-11-15 00:52:24 +00:00
{
2016-01-13 11:20:34 +00:00
g_Notify - > DisplayError ( stdstr_f ( " %s \n SP_DRAM_ADDR_REG not in RDRam space : %08X " , __FUNCTION__ , g_Reg - > SP_DRAM_ADDR_REG ) . c_str ( ) ) ;
2015-11-15 00:52:24 +00:00
}
return ;
}
if ( g_Reg - > SP_WR_LEN_REG + 1 + ( g_Reg - > SP_MEM_ADDR_REG & 0xFFF ) > 0x1000 )
{
2018-01-15 21:23:21 +00:00
if ( HaveDebugger ( ) )
2015-11-15 00:52:24 +00:00
{
2015-12-23 20:04:36 +00:00
g_Notify - > DisplayError ( " SP DMA WRITE \n could not fit copy in memory segement " ) ;
2015-11-15 00:52:24 +00:00
}
return ;
}
if ( ( g_Reg - > SP_MEM_ADDR_REG & 3 ) ! = 0 )
{
2015-12-09 11:37:58 +00:00
g_Notify - > BreakPoint ( __FILE__ , __LINE__ ) ;
2015-11-15 00:52:24 +00:00
}
if ( ( g_Reg - > SP_DRAM_ADDR_REG & 3 ) ! = 0 )
{
2015-12-09 11:37:58 +00:00
g_Notify - > BreakPoint ( __FILE__ , __LINE__ ) ;
2015-11-15 00:52:24 +00:00
}
if ( ( ( g_Reg - > SP_WR_LEN_REG + 1 ) & 3 ) ! = 0 )
{
2015-12-09 11:37:58 +00:00
g_Notify - > BreakPoint ( __FILE__ , __LINE__ ) ;
2015-11-15 00:52:24 +00:00
}
memcpy ( g_MMU - > Rdram ( ) + g_Reg - > SP_DRAM_ADDR_REG , g_MMU - > Dmem ( ) + ( g_Reg - > SP_MEM_ADDR_REG & 0x1FFF ) ,
g_Reg - > SP_WR_LEN_REG + 1 ) ;
g_Reg - > SP_DMA_BUSY_REG = 0 ;
g_Reg - > SP_STATUS_REG & = ~ SP_STATUS_DMA_BUSY ;
}