From e4777f6563306c495a12f7f5d4521737e121c63f Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 4 Sep 2017 16:18:47 -0400 Subject: [PATCH] Allow PSX memcard creation, dynamic SIO delay type. --- pcsx2/R3000A.cpp | 5 +- pcsx2/Sio.cpp | 80 +++++++++++--------- pcsx2/Sio.h | 5 +- pcsx2/gui/Dialogs/ConfigurationDialog.h | 3 +- pcsx2/gui/Dialogs/CreateMemoryCardDialog.cpp | 45 ++++++++--- pcsx2/gui/Panels/MemoryCardListPanel.cpp | 2 +- 6 files changed, 84 insertions(+), 56 deletions(-) diff --git a/pcsx2/R3000A.cpp b/pcsx2/R3000A.cpp index a2c515ad8f..182ee9a5f3 100644 --- a/pcsx2/R3000A.cpp +++ b/pcsx2/R3000A.cpp @@ -172,9 +172,8 @@ static __fi void _psxTestInterrupts() IopTestEvent(IopEvt_SIF0, sif0Interrupt); // SIF0 IopTestEvent(IopEvt_SIF1, sif1Interrupt); // SIF1 IopTestEvent(IopEvt_SIF2, sif2Interrupt); // SIF2 -#ifndef SIO_INLINE_IRQS - IopTestEvent(IopEvt_SIO, sioInterrupt); -#endif + // Originally controlled by a preprocessor define, now PSX dependent. + if (psxHu32(HW_ICFG) & (1 << 3)) IopTestEvent(IopEvt_SIO, sioInterruptR); IopTestEvent(IopEvt_CdvdRead, cdvdReadInterrupt); // Profile-guided Optimization (sorta) diff --git a/pcsx2/Sio.cpp b/pcsx2/Sio.cpp index 2e765f1a4b..491d4c3065 100644 --- a/pcsx2/Sio.cpp +++ b/pcsx2/Sio.cpp @@ -26,6 +26,7 @@ _mcd *mcd; SIO_MODE siomode = SIO_START; static void sioWrite8inl(u8 data); #define SIO_WRITE void inline +#define SIO_FORCEINLINE __fi // Magic psx values from nocash info static const u8 memcard_psx[] = {0x5A, 0x5D, 0x5C, 0x5D, 0x04, 0x00, 0x00, 0x80}; @@ -79,21 +80,6 @@ void ClearMcdEjectTimeoutNow() } } -// SIO Inline'd IRQs : Calls the SIO interrupt handlers directly instead of -// feeding them through the IOP's branch test. (see SIO.H for details) - -#ifdef SIO_INLINE_IRQS -#define SIO_INT() sioInterrupt() -#define SIO_FORCEINLINE __fi -#else -__fi void SIO_INT() -{ - if( !(psxRegs.interrupt & (1<= (1<< ((sio.CtrlReg & RX_BYTES_INT) >>8))) ? 1:0) ) { SIO_INT(); return; } + //if ((sio.CtrlReg & RX_INT_EN) && ((byteCnt >= (1<< ((sio.CtrlReg & RX_BYTES_INT) >>8))) ? 1:0) ) { sioInterrupt(); return; } return; } @@ -889,7 +895,7 @@ static void sioWrite8inl(u8 data) if (IS_LAST_BYTE_IN_PACKET != 1) //The following should be set after each byte transfer but the last one. sio.StatReg |= ACK_INP; //Signal that Controller (or MC) has brought the /ACK (Acknowledge) line active low. - SIO_INT(); + sioInterrupt(); //chkTriggerInt(); //Console.WriteLn( "SIO0 WR DATA COMMON %02X INT_STAT= %08X IOPpc= %08X " , data, psxHu32(0x1070), psxRegs.pc); byteCnt++; diff --git a/pcsx2/Sio.h b/pcsx2/Sio.h index 88f8b69203..6c0f221c08 100644 --- a/pcsx2/Sio.h +++ b/pcsx2/Sio.h @@ -15,10 +15,6 @@ #pragma once -// Let's enable this to free the IOP event handler of some considerable load. -// Games are highly unlikely to need timed IRQ's for PAD and MemoryCard handling anyway (rama). -#define SIO_INLINE_IRQS - #include "MemoryCardFile.h" struct _mcd @@ -125,6 +121,7 @@ extern u8 sioRead8(); extern void sioWrite8(u8 value); extern void sioWriteCtrl16(u16 value); extern void sioInterrupt(); +extern void sioInterruptR(); extern void InitializeSIO(u8 value); extern void SetForceMcdEjectTimeoutNow(); extern void ClearMcdEjectTimeoutNow(); diff --git a/pcsx2/gui/Dialogs/ConfigurationDialog.h b/pcsx2/gui/Dialogs/ConfigurationDialog.h index 87de156898..3c8fd4a100 100644 --- a/pcsx2/gui/Dialogs/ConfigurationDialog.h +++ b/pcsx2/gui/Dialogs/ConfigurationDialog.h @@ -198,13 +198,14 @@ namespace Dialogs #ifdef __WXMSW__ pxCheckBox* m_check_CompressNTFS; #endif + pxCheckBox* m_check_psx; public: virtual ~CreateMemoryCardDialog() = default; CreateMemoryCardDialog( wxWindow* parent, const wxDirName& mcdpath, const wxString& suggested_mcdfileName); //duplicate of MemoryCardFile::Create. Don't know why the existing method isn't used. - avih - static bool CreateIt( const wxString& mcdFile, uint sizeInMB ); + static bool CreateIt( const wxString& mcdFile, uint sizeInMB, bool isPSX ); wxString result_createdMcdFilename; //wxDirName GetPathToMcds() const; diff --git a/pcsx2/gui/Dialogs/CreateMemoryCardDialog.cpp b/pcsx2/gui/Dialogs/CreateMemoryCardDialog.cpp index c69291b798..be8dfa4b25 100644 --- a/pcsx2/gui/Dialogs/CreateMemoryCardDialog.cpp +++ b/pcsx2/gui/Dialogs/CreateMemoryCardDialog.cpp @@ -87,6 +87,8 @@ Dialogs::CreateMemoryCardDialog::CreateMemoryCardDialog( wxWindow* parent, const s_padding += m_check_CompressNTFS | StdExpand(); #endif + s_padding += m_check_psx; + s_padding += 12; s_padding += s_buttons | StdCenter(); @@ -110,24 +112,44 @@ wxDirName Dialogs::CreateMemoryCardDialog::GetPathToMcds() const // When this GUI is moved into the FileMemoryCard plugin (where it eventually belongs), // this function will be removed and the MemoryCardFile::Create() function will be used // instead. -bool Dialogs::CreateMemoryCardDialog::CreateIt( const wxString& mcdFile, uint sizeInMB ) +bool Dialogs::CreateMemoryCardDialog::CreateIt( const wxString& mcdFile, uint sizeInMB, bool isPSX ) { //int enc[16] = {0x77,0x7f,0x7f,0x77,0x7f,0x7f,0x77,0x7f,0x7f,0x77,0x7f,0x7f,0,0,0,0}; - u8 m_effeffs[528*16]; - memset8<0xff>( m_effeffs ); + // PS2 Memory Card + u8 m_effeffs[528 * 16]; + memset8<0xff>(m_effeffs); - Console.WriteLn( L"(FileMcd) Creating new %uMB memory card: '%s'", sizeInMB, WX_STR(mcdFile) ); + // PSX Memory Card; 8192 is the size in bytes of a single block of a PSX memory card (8 KiB). + u8 m_effeffs_psx[8192]; + memset8<0xff>(m_effeffs_psx); + + // Since isPSX will have a default false state, it makes more sense to check "not PSX" first + if (!isPSX) { + Console.WriteLn(L"(FileMcd) Creating new PS2 %uMB memory card: '%s'", sizeInMB, WX_STR(mcdFile)); + } + else { + Console.WriteLn(L"(FileMcd) Creating new PSX 128 KiB memory card: '%s'", WX_STR(mcdFile)); + } wxFFile fp( mcdFile, L"wb" ); if( !fp.IsOpened() ) return false; static const int MC2_MBSIZE = 1024 * 528 * 2; // Size of a single megabyte of card data - for( uint i=0; i<(MC2_MBSIZE*sizeInMB)/sizeof(m_effeffs); i++ ) - { - if( fp.Write( m_effeffs, sizeof(m_effeffs) ) == 0 ) - return false; + if (!isPSX) { + for (uint i = 0; i<(MC2_MBSIZE*sizeInMB) / sizeof(m_effeffs); i++) { + if (fp.Write(m_effeffs, sizeof(m_effeffs)) == 0) { + return false; + } + } + } else { + // PSX cards consist of 16 blocks, each 8 KiB in size. + for (uint i = 0; i < 16; i++) { + if (fp.Write(m_effeffs_psx, sizeof(m_effeffs_psx)) == 0) { + return false; + } + } } return true; @@ -170,9 +192,10 @@ void Dialogs::CreateMemoryCardDialog::OnOk_Click( wxCommandEvent& evt ) } } else { // otherwise create a file - if ( !CreateIt( + if (!CreateIt( fullPath, - m_radio_CardSize ? m_radio_CardSize->SelectedItem().SomeInt : 8 + m_radio_CardSize ? m_radio_CardSize->SelectedItem().SomeInt : 8, + m_check_psx->GetValue() ) ) { Msgbox::Alert( _( "Error: The memory card could not be created." ), @@ -230,5 +253,7 @@ void Dialogs::CreateMemoryCardDialog::CreateControls() m_radio_CardSize = new pxRadioPanel( this, tbl_CardSizes ); m_radio_CardSize->SetDefaultItem(0); + + m_check_psx = new pxCheckBox(this, "Make this a PSX card (128 KiB only, no folders!)"); } diff --git a/pcsx2/gui/Panels/MemoryCardListPanel.cpp b/pcsx2/gui/Panels/MemoryCardListPanel.cpp index 1ce3925332..983a131349 100644 --- a/pcsx2/gui/Panels/MemoryCardListPanel.cpp +++ b/pcsx2/gui/Panels/MemoryCardListPanel.cpp @@ -551,7 +551,7 @@ void Panels::MemoryCardListPanel_Simple::AppStatusEvent_OnSettingsApplied() wxString errMsg; if (isValidNewFilename(m_Cards[slot].Filename.GetFullName(), GetMcdPath(), errMsg, 5)) { - if ( !Dialogs::CreateMemoryCardDialog::CreateIt(targetFile, 8) ) + if ( !Dialogs::CreateMemoryCardDialog::CreateIt(targetFile, 8, false) ) Console.Error( L"Automatic createion of MCD '%s' failed. Hope for the best...", WX_STR(targetFile) ); else Console.WriteLn( L"memcard created: '%s'.", WX_STR(targetFile) );