2012-12-19 09:30:18 +00:00
/****************************************************************************
* *
* Project 64 - A Nintendo 64 emulator . *
* 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"
2015-04-28 22:19:02 +00:00
CFlashram : : CFlashram ( bool ReadOnly ) :
2015-09-23 09:00:51 +00:00
m_FlashRamPointer ( NULL ) ,
2010-06-22 20:36:28 +00:00
m_FlashFlag ( FLASHRAM_MODE_NOPES ) ,
m_FlashStatus ( 0 ) ,
m_FlashRAM_Offset ( 0 ) ,
m_ReadOnly ( ReadOnly ) ,
m_hFile ( NULL )
{
2015-03-29 17:19:28 +00:00
2010-06-22 20:36:28 +00:00
}
2015-04-28 22:19:02 +00:00
CFlashram : : ~ CFlashram ( )
2015-03-29 17:19:28 +00:00
{
if ( m_hFile )
{
2010-06-22 20:36:28 +00:00
CloseHandle ( m_hFile ) ;
m_hFile = NULL ;
}
}
void CFlashram : : DmaFromFlashram ( BYTE * dest , int StartOffset , int len )
{
BYTE FlipBuffer [ 0x10000 ] ;
DWORD dwRead , count ;
2015-03-29 17:19:28 +00:00
switch ( m_FlashFlag )
{
2010-06-22 20:36:28 +00:00
case FLASHRAM_MODE_READ :
2015-03-29 17:19:28 +00:00
if ( m_hFile = = NULL )
{
if ( ! LoadFlashram ( ) )
{
return ;
}
2010-06-22 20:36:28 +00:00
}
2013-03-22 05:47:20 +00:00
if ( len > 0x10000 )
{
if ( bHaveDebugger ( ) )
{
2015-10-25 10:50:28 +00:00
g_Notify - > DisplayError ( stdstr_f ( __FUNCTION__ " : DmaFromFlashram FlipBuffer to small (len: %d) " , len ) . ToUTF16 ( ) . c_str ( ) ) ;
2013-03-22 05:47:20 +00:00
}
2010-06-22 20:36:28 +00:00
len = 0x10000 ;
}
2013-03-22 05:47:20 +00:00
if ( ( len & 3 ) ! = 0 )
{
if ( bHaveDebugger ( ) )
{
2015-10-25 10:50:28 +00:00
g_Notify - > DisplayError ( __FUNCTIONW__ L " : Unaligned flash ram read ??? " ) ;
2013-03-22 05:47:20 +00:00
}
2010-06-22 20:36:28 +00:00
return ;
}
memset ( FlipBuffer , 0 , sizeof ( FlipBuffer ) ) ;
StartOffset = StartOffset < < 1 ;
SetFilePointer ( m_hFile , StartOffset , NULL , FILE_BEGIN ) ;
ReadFile ( m_hFile , FlipBuffer , len , & dwRead , NULL ) ;
2015-03-29 17:19:28 +00:00
for ( count = dwRead ; ( int ) count < len ; count + + )
{
2010-06-22 20:36:28 +00:00
FlipBuffer [ count ] = 0xFF ;
}
2015-05-14 22:38:52 +00:00
2015-09-15 22:55:27 +00:00
for ( count = 0 ; ( int ) count < len ; count + = 4 )
2015-03-29 17:19:28 +00:00
{
2015-09-15 22:55:27 +00:00
register DWORD eax ;
eax = * ( unsigned __int32 * ) & FlipBuffer [ count ] ;
// eax = swap32by8(eax); // ; bswap eax
* ( unsigned __int32 * ) ( dest + count ) = eax ;
2010-06-22 20:36:28 +00:00
}
break ;
case FLASHRAM_MODE_STATUS :
2013-03-22 05:47:20 +00:00
if ( StartOffset ! = 0 & & len ! = 8 )
{
if ( bHaveDebugger ( ) )
{
2015-10-25 10:50:28 +00:00
g_Notify - > DisplayError ( stdstr_f ( __FUNCTION__ " : Reading m_FlashStatus not being handled correctly \n Start: %X len: %X " , StartOffset , len ) . ToUTF16 ( ) . c_str ( ) ) ;
2013-03-22 05:47:20 +00:00
}
2010-06-22 20:36:28 +00:00
}
2012-10-04 00:04:08 +00:00
* ( ( DWORD * ) ( dest ) ) = ( DWORD ) ( ( m_FlashStatus > > 32 ) & 0xFFFFFFFF ) ;
* ( ( DWORD * ) ( dest ) + 1 ) = ( DWORD ) ( m_FlashStatus & 0xFFFFFFFF ) ;
2010-06-22 20:36:28 +00:00
break ;
default :
2013-03-22 05:47:20 +00:00
if ( bHaveDebugger ( ) )
{
2015-10-25 10:50:28 +00:00
g_Notify - > DisplayError ( stdstr_f ( __FUNCTION__ " : Start: %X, Offset: %X len: %X " , dest - g_MMU - > Rdram ( ) , StartOffset , len ) . ToUTF16 ( ) . c_str ( ) ) ;
2013-03-22 05:47:20 +00:00
}
2010-06-22 20:36:28 +00:00
}
}
2015-03-29 17:19:28 +00:00
void CFlashram : : DmaToFlashram ( BYTE * Source , int StartOffset , int len )
{
switch ( m_FlashFlag )
{
2010-06-22 20:36:28 +00:00
case FLASHRAM_MODE_WRITE :
m_FlashRamPointer = Source ;
break ;
default :
2013-03-22 05:47:20 +00:00
if ( bHaveDebugger ( ) )
{
2015-10-25 10:50:28 +00:00
g_Notify - > DisplayError ( stdstr_f ( __FUNCTION__ " : Start: %X, Offset: %X len: %X " , Source - g_MMU - > Rdram ( ) , StartOffset , len ) . ToUTF16 ( ) . c_str ( ) ) ;
2013-03-22 05:47:20 +00:00
}
2010-06-22 20:36:28 +00:00
}
}
2010-06-30 21:35:44 +00:00
DWORD CFlashram : : ReadFromFlashStatus ( DWORD PAddr )
2010-06-22 20:36:28 +00:00
{
2015-03-29 17:19:28 +00:00
switch ( PAddr )
{
2010-06-22 20:36:28 +00:00
case 0x08000000 : return ( DWORD ) ( m_FlashStatus > > 32 ) ;
default :
2013-03-22 05:47:20 +00:00
if ( bHaveDebugger ( ) )
{
2015-10-25 10:50:28 +00:00
g_Notify - > DisplayError ( stdstr_f ( __FUNCTION__ " : PAddr (%X) " , PAddr ) . ToUTF16 ( ) . c_str ( ) ) ;
2013-03-22 05:47:20 +00:00
}
2010-06-22 20:36:28 +00:00
break ;
}
return ( DWORD ) ( m_FlashStatus > > 32 ) ;
}
2015-04-28 22:19:02 +00:00
bool CFlashram : : LoadFlashram ( )
2015-03-29 17:19:28 +00:00
{
2010-06-22 20:36:28 +00:00
CPath FileName ;
2015-10-25 10:50:28 +00:00
FileName . SetDriveDirectory ( g_Settings - > LoadStringVal ( Directory_NativeSave ) . c_str ( ) ) ;
FileName . SetName ( g_Settings - > LoadStringVal ( Game_GameName ) . c_str ( ) ) ;
2010-06-22 20:36:28 +00:00
FileName . SetExtension ( " fla " ) ;
if ( ! FileName . DirectoryExists ( ) )
{
FileName . CreateDirectory ( ) ;
}
m_hFile = CreateFile ( FileName , m_ReadOnly ? GENERIC_READ : GENERIC_WRITE | GENERIC_READ , FILE_SHARE_READ | FILE_SHARE_WRITE , NULL , OPEN_ALWAYS ,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS , NULL ) ;
if ( m_hFile = = INVALID_HANDLE_VALUE )
{
2012-12-17 00:21:29 +00:00
WriteTraceF ( TraceError , __FUNCTION__ " : Failed to open (%s), ReadOnly = %d, LastError = %X " , ( LPCTSTR ) FileName , m_ReadOnly , GetLastError ( ) ) ;
2012-11-17 00:58:31 +00:00
g_Notify - > DisplayError ( GS ( MSG_FAIL_OPEN_FLASH ) ) ;
2010-06-22 20:36:28 +00:00
return false ;
}
SetFilePointer ( m_hFile , 0 , NULL , FILE_BEGIN ) ;
return true ;
}
2015-03-29 17:19:28 +00:00
void CFlashram : : WriteToFlashCommand ( DWORD FlashRAM_Command )
{
2010-06-22 20:36:28 +00:00
BYTE EmptyBlock [ 128 ] ;
DWORD dwWritten ;
2015-03-29 17:19:28 +00:00
switch ( FlashRAM_Command & 0xFF000000 )
{
2010-06-22 20:36:28 +00:00
case 0xD2000000 :
2015-03-29 17:19:28 +00:00
switch ( m_FlashFlag )
{
2010-06-22 20:36:28 +00:00
case FLASHRAM_MODE_NOPES : break ;
case FLASHRAM_MODE_READ : break ;
case FLASHRAM_MODE_STATUS : break ;
case FLASHRAM_MODE_ERASE :
memset ( EmptyBlock , 0xFF , sizeof ( EmptyBlock ) ) ;
if ( m_hFile = = NULL ) {
2015-03-29 17:19:28 +00:00
if ( ! LoadFlashram ( ) )
{
return ;
}
2010-06-22 20:36:28 +00:00
}
SetFilePointer ( m_hFile , m_FlashRAM_Offset , NULL , FILE_BEGIN ) ;
WriteFile ( m_hFile , EmptyBlock , 128 , & dwWritten , NULL ) ;
break ;
case FLASHRAM_MODE_WRITE :
if ( m_hFile = = NULL ) {
2015-03-29 17:19:28 +00:00
if ( ! LoadFlashram ( ) )
{
return ;
}
2010-06-22 20:36:28 +00:00
}
{
BYTE FlipBuffer [ 128 ] ;
2015-09-15 22:55:27 +00:00
register size_t edx ;
2010-06-22 20:36:28 +00:00
BYTE * FlashRamPointer = m_FlashRamPointer ;
2015-09-15 22:55:27 +00:00
memset ( FlipBuffer , 0 , sizeof ( FlipBuffer ) ) ;
for ( edx = 0 ; edx < 128 ; edx + = 4 )
2015-03-29 17:19:28 +00:00
{
2015-09-15 22:55:27 +00:00
register DWORD eax ;
eax = * ( unsigned __int32 * ) & FlashRamPointer [ edx ] ;
// eax = swap32by8(eax); // ; bswap eax
* ( unsigned __int32 * ) ( FlipBuffer + edx ) = eax ;
2010-06-22 20:36:28 +00:00
}
SetFilePointer ( m_hFile , m_FlashRAM_Offset , NULL , FILE_BEGIN ) ;
WriteFile ( m_hFile , FlipBuffer , 128 , & dwWritten , NULL ) ;
}
break ;
default :
2015-10-25 10:50:28 +00:00
g_Notify - > DisplayError ( stdstr_f ( " Writing %X to flash ram command register \n m_FlashFlag: %d " , FlashRAM_Command , m_FlashFlag ) . ToUTF16 ( ) . c_str ( ) ) ;
2010-06-22 20:36:28 +00:00
}
m_FlashFlag = FLASHRAM_MODE_NOPES ;
break ;
case 0xE1000000 :
m_FlashFlag = FLASHRAM_MODE_STATUS ;
2015-02-23 11:00:44 +00:00
m_FlashStatus = 0x1111800100C2001E ;
2010-06-22 20:36:28 +00:00
break ;
case 0xF0000000 :
m_FlashFlag = FLASHRAM_MODE_READ ;
m_FlashStatus = 0x11118004F0000000 ;
break ;
case 0x4B000000 :
m_FlashRAM_Offset = ( FlashRAM_Command & 0xffff ) * 128 ;
break ;
case 0x78000000 :
m_FlashFlag = FLASHRAM_MODE_ERASE ;
2015-02-23 11:00:44 +00:00
m_FlashStatus = 0x1111800800C2001E ;
2010-06-22 20:36:28 +00:00
break ;
case 0xB4000000 :
m_FlashFlag = FLASHRAM_MODE_WRITE ; //????
break ;
case 0xA5000000 :
m_FlashRAM_Offset = ( FlashRAM_Command & 0xffff ) * 128 ;
2015-02-23 11:00:44 +00:00
m_FlashStatus = 0x1111800400C2001E ;
2010-06-22 20:36:28 +00:00
break ;
default :
2013-03-22 05:47:20 +00:00
if ( bHaveDebugger ( ) )
{
2015-10-25 10:50:28 +00:00
g_Notify - > DisplayError ( stdstr_f ( " Writing %X to flash ram command register " , FlashRAM_Command ) . ToUTF16 ( ) . c_str ( ) ) ;
2013-03-22 05:47:20 +00:00
}
2010-06-22 20:36:28 +00:00
}
}