Merge branch 'master' of https://github.com/project64/project64
This commit is contained in:
commit
0ec052177b
|
@ -1946,6 +1946,12 @@ optimize_texrect=0
|
|||
swapmode=2
|
||||
useless_is_useless=1
|
||||
|
||||
[27C985A8-ED7CE5C6-C:0]
|
||||
Good Name=Mega Man 64 (Proto)
|
||||
Internal Name=Megaman 64
|
||||
depthmode=1
|
||||
increase_texrect_edge=1
|
||||
|
||||
[0EC158F5-FB3E6896-C:45]
|
||||
Good Name=Mega Man 64 (U)
|
||||
Internal Name=Mega Man 64
|
||||
|
|
|
@ -1811,6 +1811,7 @@ Status=Compatible
|
|||
Plugin Note=[Glide64] missing menu effects
|
||||
32bit=No
|
||||
Culling=1
|
||||
Fixed Audio=0
|
||||
|
||||
[B30ED978-3003C9F9-C:45]
|
||||
Good Name=F-ZERO X (U)
|
||||
|
@ -3380,6 +3381,11 @@ Plugin Note=[Glide64] errors:various
|
|||
RDRAM Size=8
|
||||
Save Type=16kbit Eeprom
|
||||
|
||||
[27C985A8-ED7CE5C6-C:0]
|
||||
Good Name=Mega Man 64 (Proto)
|
||||
Internal Name=Megaman 64
|
||||
Status=Compatible
|
||||
|
||||
[0EC158F5-FB3E6896-C:45]
|
||||
Good Name=Mega Man 64 (U)
|
||||
Internal Name=Mega Man 64
|
||||
|
@ -3753,12 +3759,14 @@ Status=Compatible
|
|||
Good Name=NBA Live 2000 (E) (M4)
|
||||
Internal Name=NBA LIVE 2000
|
||||
Status=Compatible
|
||||
32bit=No
|
||||
|
||||
[5F25B0EE-6227C1DB-C:45]
|
||||
Good Name=NBA Live 2000 (U) (M4)
|
||||
Internal Name=NBA LIVE 2000
|
||||
Status=Compatible
|
||||
Culling=1
|
||||
32bit=No
|
||||
|
||||
[CF84F45F-00E4F6EB-C:50]
|
||||
Good Name=NBA Live 99 (E) (M5)
|
||||
|
@ -3813,11 +3821,13 @@ Status=Compatible
|
|||
Good Name=NFL Blitz 2000 (U) (V1.0)
|
||||
Internal Name=blitz2k
|
||||
Status=Compatible
|
||||
32bit=No
|
||||
|
||||
[5B755842-6CA39C7A-C:45]
|
||||
Good Name=NFL Blitz 2000 (U) (V1.1)
|
||||
Internal Name=blitz2k
|
||||
Status=Compatible
|
||||
32bit=No
|
||||
|
||||
[36FA35EB-E85E2E36-C:45]
|
||||
Good Name=NFL Blitz 2001 (U)
|
||||
|
|
|
@ -246,8 +246,9 @@
|
|||
#463# "前回使ったチートを記憶する(&R)"
|
||||
#464# "ロムの実行中はスクリーンセーバーを無効にする"
|
||||
#465# "フレームレートを表示"
|
||||
#466# "表示形式によってフレームレートを変更する:"
|
||||
#466# "フレームレートの表示形式"
|
||||
#467# "Project64がすでに起動しているかチェックする"
|
||||
#468# "ゲーム毎にセーブディレクトリを作成する"
|
||||
|
||||
//ROM Browser Tab
|
||||
#480# "最近開いたロムファイルの表示する数(0~10):"
|
||||
|
|
|
@ -633,11 +633,11 @@ void alist_resample( CHle * hle, bool init, bool flag2, uint16_t dmemo, uint16_t
|
|||
{
|
||||
const int16_t* lut = RESAMPLE_LUT + ((pitch_accu & 0xfc00) >> 8);
|
||||
|
||||
*sample(hle, opos++) = clamp_s16(
|
||||
((*sample(hle, ipos) * lut[0]) >> 15) +
|
||||
((*sample(hle, ipos + 1) * lut[1]) >> 15) +
|
||||
((*sample(hle, ipos + 2) * lut[2]) >> 15) +
|
||||
((*sample(hle, ipos + 3) * lut[3]) >> 15));
|
||||
*sample(hle, opos++) = clamp_s16( (
|
||||
(*sample(hle, ipos ) * lut[0]) +
|
||||
(*sample(hle, ipos + 1) * lut[1]) +
|
||||
(*sample(hle, ipos + 2) * lut[2]) +
|
||||
(*sample(hle, ipos + 3) * lut[3]) ) >> 15);
|
||||
|
||||
pitch_accu += pitch;
|
||||
ipos += (pitch_accu >> 16);
|
||||
|
@ -911,7 +911,7 @@ void alist_polef(CHle * hle, bool init, uint16_t dmemo, uint16_t dmemi, uint16_t
|
|||
count -= 16;
|
||||
} while (count != 0);
|
||||
|
||||
dram_store_u16(hle, (uint16_t*)(dst - 4), address, 4);
|
||||
dram_store_u32(hle, (uint32_t*)(dst - 4), address, 2);
|
||||
}
|
||||
|
||||
void alist_iirf(CHle * hle, bool init, uint16_t dmemo, uint16_t dmemi, uint16_t count, int16_t* table, uint32_t address)
|
||||
|
|
|
@ -81,6 +81,7 @@ enum LanguageStringID
|
|||
MENU_RESUME = 132,
|
||||
MENU_RESET_SOFT = 133, //added in build 1.7.50
|
||||
MENU_RESET_HARD = 134, //added in build 1.7.50
|
||||
MENU_SWAPDISK = 135, //added in build 2.2.????
|
||||
|
||||
//Options Menu
|
||||
MENU_OPTIONS = 140,
|
||||
|
|
|
@ -88,6 +88,7 @@ void CLanguage::LoadDefaultStrings(void)
|
|||
DEF_STR(MENU_RESUME, "R&esume");
|
||||
DEF_STR(MENU_RESET_SOFT, "&Soft Reset");
|
||||
DEF_STR(MENU_RESET_HARD, "&Hard Reset");
|
||||
DEF_STR(MENU_SWAPDISK, "Swap &Disk");
|
||||
|
||||
//Options Menu
|
||||
DEF_STR(MENU_OPTIONS, "&Options");
|
||||
|
|
|
@ -481,7 +481,7 @@ R4300iOp::Func * R4300iOp::BuildInterpreter()
|
|||
Jump_CoP1_S[5] = COP1_S_ABS;
|
||||
Jump_CoP1_S[6] = COP1_S_MOV;
|
||||
Jump_CoP1_S[7] = COP1_S_NEG;
|
||||
Jump_CoP1_S[8] = UnknownOpcode;
|
||||
Jump_CoP1_S[8] = COP1_S_ROUND_L;
|
||||
Jump_CoP1_S[9] = COP1_S_TRUNC_L;
|
||||
Jump_CoP1_S[10] = COP1_S_CEIL_L; //added by Witten
|
||||
Jump_CoP1_S[11] = COP1_S_FLOOR_L; //added by Witten
|
||||
|
@ -546,7 +546,7 @@ R4300iOp::Func * R4300iOp::BuildInterpreter()
|
|||
Jump_CoP1_D[5] = COP1_D_ABS;
|
||||
Jump_CoP1_D[6] = COP1_D_MOV;
|
||||
Jump_CoP1_D[7] = COP1_D_NEG;
|
||||
Jump_CoP1_D[8] = UnknownOpcode;
|
||||
Jump_CoP1_D[8] = COP1_D_ROUND_L;
|
||||
Jump_CoP1_D[9] = COP1_D_TRUNC_L; //added by Witten
|
||||
Jump_CoP1_D[10] = COP1_D_CEIL_L; //added by Witten
|
||||
Jump_CoP1_D[11] = COP1_D_FLOOR_L; //added by Witten
|
||||
|
@ -2461,6 +2461,12 @@ void R4300iOp::COP1_S_NEG()
|
|||
*(float *)_FPR_S[m_Opcode.fd] = (*(float *)_FPR_S[m_Opcode.fs] * -1.0f);
|
||||
}
|
||||
|
||||
void R4300iOp::COP1_S_ROUND_L()
|
||||
{
|
||||
TEST_COP1_USABLE_EXCEPTION();
|
||||
Float_RoundToInteger64(&*(int64_t *)_FPR_D[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_TONEAREST);
|
||||
}
|
||||
|
||||
void R4300iOp::COP1_S_TRUNC_L()
|
||||
{
|
||||
TEST_COP1_USABLE_EXCEPTION();
|
||||
|
@ -2652,6 +2658,12 @@ void R4300iOp::COP1_D_NEG()
|
|||
*(double *)_FPR_D[m_Opcode.fd] = (*(double *)_FPR_D[m_Opcode.fs] * -1.0);
|
||||
}
|
||||
|
||||
void R4300iOp::COP1_D_ROUND_L()
|
||||
{
|
||||
TEST_COP1_USABLE_EXCEPTION();
|
||||
Double_RoundToInteger64(&*(uint64_t *)_FPR_S[m_Opcode.fd], &*(double *)_FPR_D[m_Opcode.fs], FE_TONEAREST);
|
||||
}
|
||||
|
||||
void R4300iOp::COP1_D_TRUNC_L()
|
||||
{ //added by Witten
|
||||
TEST_COP1_USABLE_EXCEPTION();
|
||||
|
|
|
@ -160,6 +160,7 @@ public:
|
|||
static void COP1_S_ABS();
|
||||
static void COP1_S_MOV();
|
||||
static void COP1_S_NEG();
|
||||
static void COP1_S_ROUND_L();
|
||||
static void COP1_S_TRUNC_L();
|
||||
static void COP1_S_CEIL_L(); //added by Witten
|
||||
static void COP1_S_FLOOR_L(); //added by Witten
|
||||
|
@ -181,6 +182,7 @@ public:
|
|||
static void COP1_D_ABS();
|
||||
static void COP1_D_MOV();
|
||||
static void COP1_D_NEG();
|
||||
static void COP1_D_ROUND_L();
|
||||
static void COP1_D_TRUNC_L(); //added by Witten
|
||||
static void COP1_D_CEIL_L(); //added by Witten
|
||||
static void COP1_D_FLOOR_L(); //added by Witten
|
||||
|
|
|
@ -376,7 +376,7 @@ R4300iOp32::Func * R4300iOp32::BuildInterpreter()
|
|||
Jump_CoP1_S[5] = R4300iOp::COP1_S_ABS;
|
||||
Jump_CoP1_S[6] = R4300iOp::COP1_S_MOV;
|
||||
Jump_CoP1_S[7] = R4300iOp::COP1_S_NEG;
|
||||
Jump_CoP1_S[8] = R4300iOp::UnknownOpcode;
|
||||
Jump_CoP1_S[8] = R4300iOp::COP1_S_ROUND_L;
|
||||
Jump_CoP1_S[9] = R4300iOp::COP1_S_TRUNC_L;
|
||||
Jump_CoP1_S[10] = R4300iOp::COP1_S_CEIL_L; //added by Witten
|
||||
Jump_CoP1_S[11] = R4300iOp::COP1_S_FLOOR_L; //added by Witten
|
||||
|
@ -441,7 +441,7 @@ R4300iOp32::Func * R4300iOp32::BuildInterpreter()
|
|||
Jump_CoP1_D[5] = R4300iOp::COP1_D_ABS;
|
||||
Jump_CoP1_D[6] = R4300iOp::COP1_D_MOV;
|
||||
Jump_CoP1_D[7] = R4300iOp::COP1_D_NEG;
|
||||
Jump_CoP1_D[8] = R4300iOp::UnknownOpcode;
|
||||
Jump_CoP1_D[8] = R4300iOp::COP1_D_ROUND_L;
|
||||
Jump_CoP1_D[9] = R4300iOp::COP1_D_TRUNC_L; //added by Witten
|
||||
Jump_CoP1_D[10] = R4300iOp::COP1_D_CEIL_L; //added by Witten
|
||||
Jump_CoP1_D[11] = R4300iOp::COP1_D_FLOOR_L; //added by Witten
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
uint8_t dd_swapdelay;
|
||||
|
||||
bool dd_write;
|
||||
bool dd_reset_hold;
|
||||
uint32_t dd_track_offset, dd_zone;
|
||||
|
@ -29,11 +31,9 @@ uint32_t dd_start_block, dd_current;
|
|||
|
||||
void DiskCommand()
|
||||
{
|
||||
if (g_Disk != NULL)
|
||||
g_Reg->ASIC_STATUS |= DD_STATUS_DISK_PRES;
|
||||
|
||||
//ASIC_CMD_STATUS - Commands
|
||||
uint32_t cmd = g_Reg->ASIC_CMD;
|
||||
WriteTrace(TraceN64System, TraceDebug, "DD CMD %08X", cmd);
|
||||
|
||||
#ifdef _WIN32
|
||||
SYSTEMTIME sysTime;
|
||||
|
@ -81,7 +81,13 @@ void DiskCommand()
|
|||
g_Reg->ASIC_STATUS &= ~DD_STATUS_DISK_CHNG; break;
|
||||
case 0x00090000:
|
||||
//Unset Reset Bit
|
||||
g_Reg->ASIC_STATUS &= ~DD_STATUS_RST_STATE; break;
|
||||
g_Reg->ASIC_STATUS &= ~DD_STATUS_RST_STATE;
|
||||
g_Reg->ASIC_STATUS &= ~DD_STATUS_DISK_CHNG;
|
||||
//F-Zero X + Expansion Kit fix so it doesn't enable "swapping" at boot
|
||||
dd_swapdelay = 0;
|
||||
if (g_Disk != NULL)
|
||||
g_Reg->ASIC_STATUS |= DD_STATUS_DISK_PRES;
|
||||
break;
|
||||
case 0x00120000:
|
||||
//RTC Get Year & Month
|
||||
g_Reg->ASIC_DATA = (year << 24) | (month << 16); break;
|
||||
|
@ -100,7 +106,11 @@ void DiskCommand()
|
|||
void DiskReset(void)
|
||||
{
|
||||
//ASIC_HARD_RESET 0xAAAA0000
|
||||
WriteTrace(TraceN64System, TraceDebug, "DD RESET");
|
||||
g_Reg->ASIC_STATUS |= DD_STATUS_RST_STATE;
|
||||
dd_swapdelay = 0;
|
||||
if (g_Disk != NULL)
|
||||
g_Reg->ASIC_STATUS |= DD_STATUS_DISK_PRES;
|
||||
}
|
||||
|
||||
void DiskBMControl(void)
|
||||
|
@ -159,6 +169,17 @@ void DiskGapSectorCheck()
|
|||
DiskBMUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
if (!(g_Reg->ASIC_STATUS & DD_STATUS_DISK_PRES) && g_Disk != NULL && g_Settings->LoadBool(GameRunning_LoadingInProgress) == false)
|
||||
{
|
||||
dd_swapdelay++;
|
||||
if (dd_swapdelay >= 50)
|
||||
{
|
||||
g_Reg->ASIC_STATUS |= (DD_STATUS_DISK_PRES | DD_STATUS_DISK_CHNG);
|
||||
dd_swapdelay = 0;
|
||||
WriteTrace(TraceN64System, TraceDebug, "DD SWAP DONE");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DiskBMUpdate()
|
||||
|
@ -245,7 +266,7 @@ void DiskBMRead()
|
|||
sector += dd_track_offset;
|
||||
sector += dd_start_block * SECTORS_PER_BLOCK * ddZoneSecSize[dd_zone];
|
||||
sector += (dd_current) * (((g_Reg->ASIC_HOST_SECBYTE & 0x00FF0000) >> 16) + 1);
|
||||
WriteTrace(TraceN64System, TraceDebug, "READ Block %d Sector %02X - %08X", ((g_Reg->ASIC_CUR_TK & 0x0FFF0000) >> 15) | dd_start_block, dd_current, sector);
|
||||
//WriteTrace(TraceN64System, TraceDebug, "READ Block %d Sector %02X - %08X", ((g_Reg->ASIC_CUR_TK & 0x0FFF0000) >> 15) | dd_start_block, dd_current, sector);
|
||||
g_Disk->SetDiskAddressBuffer(sector);
|
||||
return;
|
||||
}
|
||||
|
@ -256,7 +277,7 @@ void DiskBMWrite()
|
|||
sector += dd_track_offset;
|
||||
sector += dd_start_block * SECTORS_PER_BLOCK * ddZoneSecSize[dd_zone];
|
||||
sector += (dd_current) * (((g_Reg->ASIC_HOST_SECBYTE & 0x00FF0000) >> 16) + 1);
|
||||
WriteTrace(TraceN64System, TraceDebug, "WRITE Block %d Sector %02X - %08X", ((g_Reg->ASIC_CUR_TK & 0x0FFF0000) >> 15) | dd_start_block, dd_current, sector);
|
||||
//WriteTrace(TraceN64System, TraceDebug, "WRITE Block %d Sector %02X - %08X", ((g_Reg->ASIC_CUR_TK & 0x0FFF0000) >> 15) | dd_start_block, dd_current, sector);
|
||||
g_Disk->SetDiskAddressBuffer(sector);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -198,12 +198,8 @@ void CDMA::PI_DMA_READ()
|
|||
|
||||
void CDMA::PI_DMA_WRITE()
|
||||
{
|
||||
uint32_t PI_WR_LEN_REG = ((g_Reg->PI_WR_LEN_REG) & 0x00FFFFFFul) + 1;
|
||||
|
||||
if ((PI_WR_LEN_REG & 1) != 0)
|
||||
{
|
||||
PI_WR_LEN_REG += 1; /* fixes AI Shougi 3, Doraemon 3, etc. */
|
||||
}
|
||||
uint32_t PI_WR_LEN_REG = ((g_Reg->PI_WR_LEN_REG) & 0x00FFFFFEul) + 2;
|
||||
/* rounding PI_WR_LEN_REG up to the nearest even number fixes AI Shougi 3, Doraemon 3, etc. */
|
||||
|
||||
g_Reg->PI_STATUS_REG |= PI_STATUS_DMA_BUSY;
|
||||
if (g_Reg->PI_DRAM_ADDR_REG + PI_WR_LEN_REG > g_MMU->RdramSize())
|
||||
|
@ -366,9 +362,63 @@ void CDMA::PI_DMA_WRITE()
|
|||
g_Reg->PI_CART_ADDR_REG -= 0x10000000;
|
||||
if (g_Reg->PI_CART_ADDR_REG + PI_WR_LEN_REG < g_Rom->GetRomSize())
|
||||
{
|
||||
for (i = 0; i < PI_WR_LEN_REG; i++)
|
||||
size_t alignment;
|
||||
RDRAM += g_Reg->PI_DRAM_ADDR_REG;
|
||||
ROM += g_Reg->PI_CART_ADDR_REG;
|
||||
alignment = PI_WR_LEN_REG | (size_t)RDRAM | (size_t)ROM;
|
||||
if ((alignment & 0x3) == 0)
|
||||
{
|
||||
*(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)) = *(ROM + ((g_Reg->PI_CART_ADDR_REG + i) ^ 3));
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (g_Reg->PI_CART_ADDR_REG >= g_Rom->GetRomSize())
|
||||
|
|
|
@ -14,8 +14,9 @@ class Mempak
|
|||
{
|
||||
public:
|
||||
static uint8_t CalculateCrc(uint8_t * DataToCrc);
|
||||
static void Load(int32_t Control);
|
||||
static void Format(int32_t Control);
|
||||
static void ReadFrom(int32_t Control, uint32_t address, uint8_t * data);
|
||||
static void WriteTo(int32_t Control, uint32_t address, uint8_t * data);
|
||||
private:
|
||||
static void LoadMempak(int32_t Control);
|
||||
static void Format(int32_t Control);
|
||||
};
|
|
@ -15,33 +15,37 @@
|
|||
#include <Common/path.h>
|
||||
|
||||
uint8_t Mempaks[4][128 * 256]; /* [CONTROLLERS][PAGES][BYTES_PER_PAGE] */
|
||||
CPath MempakNames[4];
|
||||
CFile MempakHandle[4];
|
||||
|
||||
void Mempak::Load(int32_t Control)
|
||||
void Mempak::LoadMempak(int32_t Control)
|
||||
{
|
||||
stdstr MempakName;
|
||||
|
||||
MempakName.Format("%s_Cont_%d", g_Settings->LoadStringVal(Game_GameName).c_str(), Control + 1);
|
||||
|
||||
MempakNames[Control] = CPath(g_Settings->LoadStringVal(Directory_NativeSave).c_str(), stdstr_f("%s.mpk",MempakName.c_str()).c_str());
|
||||
CPath MempakPath(g_Settings->LoadStringVal(Directory_NativeSave).c_str(), stdstr_f("%s.mpk",MempakName.c_str()).c_str());
|
||||
|
||||
if (g_Settings->LoadBool(Setting_UniqueSaveDir))
|
||||
{
|
||||
MempakNames[Control].AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str());
|
||||
MempakPath.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str());
|
||||
}
|
||||
if (!MempakNames[Control].DirectoryExists())
|
||||
if (!MempakPath.DirectoryExists())
|
||||
{
|
||||
MempakNames[Control].DirectoryCreate();
|
||||
MempakPath.DirectoryCreate();
|
||||
}
|
||||
|
||||
if (MempakNames[Control].Exists())
|
||||
bool formatMempak = !MempakPath.Exists();
|
||||
|
||||
MempakHandle[Control].Open(MempakPath, CFileBase::modeReadWrite | CFileBase::modeNoTruncate | CFileBase::modeCreate);
|
||||
MempakHandle[Control].SeekToBegin();
|
||||
|
||||
if (formatMempak)
|
||||
{
|
||||
FILE *mempak = fopen(MempakNames[Control], "rb");
|
||||
fread(Mempaks[Control], 1, 0x8000, mempak);
|
||||
fclose(mempak);
|
||||
Mempak::Format(Control);
|
||||
MempakHandle[Control].Write(Mempaks[Control], 0x8000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Mempak::Format(Control);
|
||||
MempakHandle[Control].Read(Mempaks[Control], 0x8000);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,6 +117,11 @@ void Mempak::ReadFrom(int32_t Control, uint32_t address, uint8_t * data)
|
|||
{
|
||||
if (address < 0x8000)
|
||||
{
|
||||
if (!MempakHandle[Control].IsOpen())
|
||||
{
|
||||
LoadMempak(Control);
|
||||
}
|
||||
|
||||
memcpy(data, &Mempaks[Control][address], 0x20);
|
||||
}
|
||||
else
|
||||
|
@ -126,11 +135,16 @@ void Mempak::WriteTo(int32_t Control, uint32_t address, uint8_t * data)
|
|||
{
|
||||
if (address < 0x8000)
|
||||
{
|
||||
if (!MempakHandle[Control].IsOpen())
|
||||
{
|
||||
LoadMempak(Control);
|
||||
}
|
||||
|
||||
memcpy(&Mempaks[Control][address], data, 0x20);
|
||||
|
||||
FILE* mempak = fopen(MempakNames[Control], "wb");
|
||||
fwrite(Mempaks[Control], 1, 0x8000, mempak);
|
||||
fclose(mempak);
|
||||
MempakHandle[Control].Seek(address, CFile::begin);
|
||||
MempakHandle[Control].Write(data, 0x20);
|
||||
MempakHandle[Control].Flush();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -118,6 +118,7 @@ void CPifRam::PifRamRead()
|
|||
CurPos = 0x40;
|
||||
}
|
||||
break;
|
||||
case 0xFD: CurPos = 0x40; break;
|
||||
case 0xFE: CurPos = 0x40; break;
|
||||
case 0xFF: break;
|
||||
case 0xB4: case 0x56: case 0xB8: break; /* ??? */
|
||||
|
@ -227,6 +228,7 @@ void CPifRam::PifRamWrite()
|
|||
CurPos = 0x40;
|
||||
}
|
||||
break;
|
||||
case 0xFD: CurPos = 0x40; break;
|
||||
case 0xFE: CurPos = 0x40; break;
|
||||
case 0xFF: break;
|
||||
case 0xB4: case 0x56: case 0xB8: break; /* ??? */
|
||||
|
|
|
@ -307,14 +307,15 @@ void CRegisters::SetAsCurrentSystem()
|
|||
|
||||
void CRegisters::CheckInterrupts()
|
||||
{
|
||||
uint32_t mi_intr_reg = MI_INTR_REG, status_register;
|
||||
if (!m_System->bFixedAudio() && CpuType() != CPU_SyncCores)
|
||||
{
|
||||
MI_INTR_REG &= ~MI_INTR_AI;
|
||||
MI_INTR_REG |= (m_AudioIntrReg & MI_INTR_AI);
|
||||
mi_intr_reg &= ~MI_INTR_AI;
|
||||
mi_intr_reg |= (m_AudioIntrReg & MI_INTR_AI);
|
||||
}
|
||||
MI_INTR_REG |= (m_RspIntrReg & MI_INTR_SP);
|
||||
MI_INTR_REG |= (m_GfxIntrReg & MI_INTR_DP);
|
||||
if ((MI_INTR_MASK_REG & MI_INTR_REG) != 0)
|
||||
mi_intr_reg |= (m_RspIntrReg & MI_INTR_SP);
|
||||
mi_intr_reg |= (m_GfxIntrReg & MI_INTR_DP);
|
||||
if ((MI_INTR_MASK_REG & mi_intr_reg) != 0)
|
||||
{
|
||||
FAKE_CAUSE_REGISTER |= CAUSE_IP2;
|
||||
}
|
||||
|
@ -322,21 +323,23 @@ void CRegisters::CheckInterrupts()
|
|||
{
|
||||
FAKE_CAUSE_REGISTER &= ~CAUSE_IP2;
|
||||
}
|
||||
MI_INTR_REG = mi_intr_reg;
|
||||
status_register = STATUS_REGISTER;
|
||||
|
||||
if ((STATUS_REGISTER & STATUS_IE) == 0)
|
||||
if ((status_register & STATUS_IE) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ((STATUS_REGISTER & STATUS_EXL) != 0)
|
||||
if ((status_register & STATUS_EXL) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ((STATUS_REGISTER & STATUS_ERL) != 0)
|
||||
if ((status_register & STATUS_ERL) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((STATUS_REGISTER & FAKE_CAUSE_REGISTER & 0xFF00) != 0)
|
||||
if ((status_register & FAKE_CAUSE_REGISTER & 0xFF00) != 0)
|
||||
{
|
||||
if (m_FirstInterupt)
|
||||
{
|
||||
|
|
|
@ -161,12 +161,12 @@ void CSystemTimer::UpdateTimers()
|
|||
int TimeTaken = m_LastUpdate - m_NextTimer;
|
||||
if (TimeTaken != 0)
|
||||
{
|
||||
uint32_t random, wired;
|
||||
int32_t random, wired;
|
||||
m_LastUpdate = m_NextTimer;
|
||||
g_Reg->COUNT_REGISTER += TimeTaken;
|
||||
random = g_Reg->RANDOM_REGISTER - (TimeTaken / g_System->CountPerOp());
|
||||
wired = g_Reg->WIRED_REGISTER;
|
||||
if ((int)random < (int)wired)
|
||||
if (random < wired)
|
||||
{
|
||||
if (wired == 0)
|
||||
{
|
||||
|
@ -175,10 +175,7 @@ void CSystemTimer::UpdateTimers()
|
|||
else
|
||||
{
|
||||
uint32_t increment = 32 - wired;
|
||||
do
|
||||
{
|
||||
random += increment;
|
||||
} while ((int)random < (int)wired);
|
||||
random += ((wired - random + increment - 1) / increment) * increment;
|
||||
}
|
||||
}
|
||||
g_Reg->RANDOM_REGISTER = random;
|
||||
|
|
|
@ -32,13 +32,22 @@ void Transferpak::Init()
|
|||
|
||||
void Transferpak::Release()
|
||||
{
|
||||
GBCart::release_gb_cart(&tpak.gb_cart);
|
||||
if (tpak.gb_cart.rom != NULL)
|
||||
{
|
||||
GBCart::release_gb_cart(&tpak.gb_cart);
|
||||
}
|
||||
}
|
||||
|
||||
void Transferpak::ReadFrom(uint16_t address, uint8_t * data)
|
||||
{
|
||||
if ((address >= 0x8000) && (address <= 0x8FFF))
|
||||
{
|
||||
//Ensure we actually have a ROM loaded in first.
|
||||
if (tpak.gb_cart.rom == NULL)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
//Get whether the GB cart is enabled or disabled
|
||||
uint8_t value = (tpak.enabled) ? 0x84 : 0x00;
|
||||
|
||||
|
@ -71,8 +80,15 @@ void Transferpak::ReadFrom(uint16_t address, uint8_t * data)
|
|||
|
||||
void Transferpak::WriteTo(uint16_t address, uint8_t * data)
|
||||
{
|
||||
|
||||
if ((address >= 0x8000) && (address <= 0x8FFF))
|
||||
{
|
||||
//Ensure we actually have a ROM loaded in first.
|
||||
if (tpak.gb_cart.rom == NULL)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
//Set whether the gb cart is enabled or disabled.
|
||||
switch (*data)
|
||||
{
|
||||
|
|
|
@ -385,6 +385,13 @@ bool CN64System::EmulationStarting(CThread * thread)
|
|||
WriteTrace(TraceN64System, TraceDebug, "Game starting");
|
||||
g_BaseSystem->StartEmulation2(false);
|
||||
WriteTrace(TraceN64System, TraceDebug, "Game Done");
|
||||
//PLACE TO ADD 64DD SAVING CODE
|
||||
if (g_Disk != NULL)
|
||||
{
|
||||
g_Disk->SaveDiskImage();
|
||||
//g_Notify->DisplayError(g_Disk->GetError());
|
||||
WriteTrace(TraceN64System, TraceDebug, "64DD Save Done");
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
@ -411,11 +418,11 @@ void CN64System::StartEmulation2(bool NewThread)
|
|||
StartLog();
|
||||
}
|
||||
|
||||
WriteTrace(TraceN64System, TraceDebug, "Setting up system");
|
||||
WriteTrace(TraceN64System, TraceDebug, "Setting up system");
|
||||
CInterpreterCPU::BuildCPU();
|
||||
|
||||
uint32_t CpuType = g_Settings->LoadDword(Game_CpuType);
|
||||
WriteTrace(TraceN64System, TraceDebug, "CpuType = %d",CpuType);
|
||||
WriteTrace(TraceN64System, TraceDebug, "CpuType = %d",CpuType);
|
||||
if (CpuType == CPU_SyncCores && !g_Settings->LoadBool(Debugger_Enabled))
|
||||
{
|
||||
g_Settings->SaveDword(Game_CpuType, CPU_Recompiler);
|
||||
|
@ -440,7 +447,7 @@ void CN64System::StartEmulation2(bool NewThread)
|
|||
m_Recomp = new CRecompiler(m_Reg, m_Profile, m_EndEmulation);
|
||||
}
|
||||
|
||||
WriteTrace(TraceN64System, TraceDebug, "Setting system as active");
|
||||
WriteTrace(TraceN64System, TraceDebug, "Setting system as active");
|
||||
bool bSetActive = true;
|
||||
if (m_SyncCPU)
|
||||
{
|
||||
|
@ -454,13 +461,13 @@ void CN64System::StartEmulation2(bool NewThread)
|
|||
|
||||
if (!bSetActive)
|
||||
{
|
||||
WriteTrace(TraceN64System, TraceWarning, "Failed to set system as active");
|
||||
WriteTrace(TraceN64System, TraceWarning, "Failed to set system as active");
|
||||
g_Settings->SaveBool(GameRunning_LoadingInProgress, false);
|
||||
g_Notify->DisplayError(MSG_PLUGIN_NOT_INIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteTrace(TraceN64System, TraceDebug, "Starting emulation thread");
|
||||
WriteTrace(TraceN64System, TraceDebug, "Starting emulation thread");
|
||||
StartEmulationThead();
|
||||
}
|
||||
}
|
||||
|
@ -468,10 +475,10 @@ void CN64System::StartEmulation2(bool NewThread)
|
|||
{
|
||||
//mark the emulation as starting and fix up menus
|
||||
g_Notify->DisplayMessage(5, MSG_EMULATION_STARTED);
|
||||
WriteTrace(TraceN64System, TraceDebug, "Start Executing CPU");
|
||||
WriteTrace(TraceN64System, TraceDebug, "Start Executing CPU");
|
||||
ExecuteCPU();
|
||||
}
|
||||
WriteTrace(TraceN64System, TraceDebug, "Done");
|
||||
WriteTrace(TraceN64System, TraceDebug, "Done");
|
||||
}
|
||||
|
||||
void CN64System::StartEmulation(bool NewThread)
|
||||
|
@ -687,25 +694,6 @@ bool CN64System::SetActiveSystem(bool bActive)
|
|||
{
|
||||
WriteTrace(TraceN64System, TraceError, "g_Plugins->Initiate Failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
CONTROL * Controllers = g_Plugins->Control()->PluginControllers();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (Controllers[i].Present)
|
||||
{
|
||||
switch (Controllers[i].Plugin)
|
||||
{
|
||||
case PLUGIN_TANSFER_PAK:
|
||||
Transferpak::Init();
|
||||
break;
|
||||
case PLUGIN_MEMPAK:
|
||||
Mempak::Load(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bReset)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "SystemGlobals.h"
|
||||
#include <Common/Platform.h>
|
||||
#include <Common/MemoryManagement.h>
|
||||
#include <Project64-core/N64System/Mips/RegisterClass.h>
|
||||
#include <memory>
|
||||
|
||||
CN64Disk::CN64Disk() :
|
||||
|
@ -31,9 +32,21 @@ bool CN64Disk::LoadDiskImage(const char * FileLoc)
|
|||
{
|
||||
UnallocateDiskImage();
|
||||
|
||||
if (!AllocateAndLoadDiskImage(FileLoc))
|
||||
//Assume the file extension is *.ndd (it is the only case where it is loaded)
|
||||
stdstr ShadowFile = FileLoc;
|
||||
ShadowFile[ShadowFile.length() - 1] = 'r';
|
||||
|
||||
g_Settings->SaveBool(GameRunning_LoadingInProgress, true);
|
||||
|
||||
WriteTrace(TraceN64System, TraceDebug, "Attempt to load shadow file.");
|
||||
if (!AllocateAndLoadDiskImage(ShadowFile.c_str()))
|
||||
{
|
||||
return false;
|
||||
WriteTrace(TraceN64System, TraceDebug, "Loading Shadow file failed");
|
||||
UnallocateDiskImage();
|
||||
if (!AllocateAndLoadDiskImage(FileLoc))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Disk == this)
|
||||
|
@ -41,9 +54,64 @@ bool CN64Disk::LoadDiskImage(const char * FileLoc)
|
|||
g_Settings->SaveBool(GameRunning_LoadingInProgress, false);
|
||||
}
|
||||
|
||||
m_FileName = FileLoc;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CN64Disk::SaveDiskImage()
|
||||
{
|
||||
//NO NEED TO SAVE IF DISK TYPE IS 6
|
||||
uint8_t disktype = m_DiskImage[5] & 0xF;
|
||||
if (disktype == 0x6)
|
||||
{
|
||||
m_DiskFile.Close();
|
||||
WriteTrace(TraceN64System, TraceDebug, "Loaded Disk Type is 0x7. No RAM area. Shadow file is not needed.");
|
||||
return true;
|
||||
}
|
||||
|
||||
//Assume the file extension is *.ndd (it is the only case where it is loaded)
|
||||
stdstr ShadowFile = m_FileName;
|
||||
ShadowFile[ShadowFile.length() - 1] = 'r';
|
||||
|
||||
WriteTrace(TraceN64System, TraceDebug, "Trying to open %s (Shadow File)", ShadowFile.c_str());
|
||||
m_DiskFile.Close();
|
||||
if (!m_DiskFile.Open(ShadowFile.c_str(), CFileBase::modeWrite | CFileBase::modeCreate))
|
||||
{
|
||||
WriteTrace(TraceN64System, TraceError, "Failed to open %s (Shadow File)", ShadowFile.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_DiskFile.SeekToBegin();
|
||||
ForceByteSwapDisk();
|
||||
|
||||
if (m_DiskFormat == DiskFormatMAME)
|
||||
{
|
||||
//If original file was MAME format, just copy
|
||||
WriteTrace(TraceN64System, TraceDebug, "64DD disk is MAME format");
|
||||
if (!m_DiskFile.Write(m_DiskImage, MameFormatSize))
|
||||
{
|
||||
m_DiskFile.Close();
|
||||
WriteTrace(TraceN64System, TraceError, "Failed to write file");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (m_DiskFormat == DiskFormatSDK)
|
||||
{
|
||||
//If original file was SDK format, we need to convert it back
|
||||
WriteTrace(TraceN64System, TraceDebug, "64DD disk is SDK format");
|
||||
ConvertDiskFormatBack();
|
||||
}
|
||||
|
||||
m_DiskFile.Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CN64Disk::SwapDiskImage(const char * FileLoc)
|
||||
{
|
||||
g_Reg->ASIC_STATUS &= ~DD_STATUS_DISK_PRES;
|
||||
LoadDiskImage(FileLoc);
|
||||
}
|
||||
|
||||
bool CN64Disk::IsValidDiskImage(uint8_t Test[4])
|
||||
{
|
||||
if (*((uint32_t *)&Test[0]) == 0x16D348E8) { return true; }
|
||||
|
@ -101,6 +169,7 @@ bool CN64Disk::AllocateAndLoadDiskImage(const char * FileLoc)
|
|||
if (DiskFileSize == MameFormatSize)
|
||||
{
|
||||
//If Disk is MAME Format (size is constant, it should be the same for every file), then continue
|
||||
m_DiskFormat = DiskFormatMAME;
|
||||
WriteTrace(TraceN64System, TraceDebug, "Disk File is MAME Format");
|
||||
|
||||
if (!AllocateDiskImage(DiskFileSize))
|
||||
|
@ -144,6 +213,8 @@ bool CN64Disk::AllocateAndLoadDiskImage(const char * FileLoc)
|
|||
{
|
||||
//If Disk is SDK format (made with SDK based dumpers like LuigiBlood's, or Nintendo's, size is also constant)
|
||||
//We need to convert it.
|
||||
m_DiskFormat = DiskFormatSDK;
|
||||
|
||||
g_Notify->DisplayMessage(5, MSG_LOADING);
|
||||
|
||||
//Allocate supported size
|
||||
|
@ -193,6 +264,21 @@ void CN64Disk::ByteSwapDisk()
|
|||
}
|
||||
}
|
||||
|
||||
void CN64Disk::ForceByteSwapDisk()
|
||||
{
|
||||
uint32_t count;
|
||||
|
||||
for (count = 0; count < m_DiskFileSize; count += 4)
|
||||
{
|
||||
m_DiskImage[count] ^= m_DiskImage[count + 3];
|
||||
m_DiskImage[count + 3] ^= m_DiskImage[count];
|
||||
m_DiskImage[count] ^= m_DiskImage[count + 3];
|
||||
m_DiskImage[count + 1] ^= m_DiskImage[count + 2];
|
||||
m_DiskImage[count + 2] ^= m_DiskImage[count + 1];
|
||||
m_DiskImage[count + 1] ^= m_DiskImage[count + 2];
|
||||
}
|
||||
}
|
||||
|
||||
void CN64Disk::SetError(LanguageStringID ErrorMsg)
|
||||
{
|
||||
m_ErrorMsg = ErrorMsg;
|
||||
|
@ -290,7 +376,7 @@ void CN64Disk::ConvertDiskFormat()
|
|||
atrack = 0;
|
||||
for (track = 0; track < ZoneTracks[zone]; track++)
|
||||
{
|
||||
if (track == SystemData[0x20 + zone * 0xC + atrack])
|
||||
if (atrack < 0xC && track == SystemData[0x20 + zone * 0xC + atrack])
|
||||
{
|
||||
memset((void *)(&BlockData0), 0, BLOCKSIZE(zone));
|
||||
memset((void *)(&BlockData1), 0, BLOCKSIZE(zone));
|
||||
|
@ -327,7 +413,7 @@ void CN64Disk::ConvertDiskFormat()
|
|||
atrack = 0xB;
|
||||
for (track = 1; track < ZoneTracks[zone] + 1; track++)
|
||||
{
|
||||
if ((ZoneTracks[zone] - track) == SystemData[0x20 + (zone)* 0xC + atrack])
|
||||
if (atrack > -1 && (ZoneTracks[zone] - track) == SystemData[0x20 + (zone)* 0xC + atrack])
|
||||
{
|
||||
memset((void *)(&BlockData0), 0, BLOCKSIZE(zone));
|
||||
memset((void *)(&BlockData1), 0, BLOCKSIZE(zone));
|
||||
|
@ -354,4 +440,178 @@ void CN64Disk::ConvertDiskFormat()
|
|||
OutOffset += BLOCKSIZE(zone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CN64Disk::ConvertDiskFormatBack()
|
||||
{
|
||||
//Original code by Happy_
|
||||
const uint32_t ZoneSecSize[16] = { 232, 216, 208, 192, 176, 160, 144, 128,
|
||||
216, 208, 192, 176, 160, 144, 128, 112 };
|
||||
const uint32_t ZoneTracks[16] = { 158, 158, 149, 149, 149, 149, 149, 114,
|
||||
158, 158, 149, 149, 149, 149, 149, 114 };
|
||||
const uint32_t DiskTypeZones[7][16] = {
|
||||
{ 0, 1, 2, 9, 8, 3, 4, 5, 6, 7, 15, 14, 13, 12, 11, 10 },
|
||||
{ 0, 1, 2, 3, 10, 9, 8, 4, 5, 6, 7, 15, 14, 13, 12, 11 },
|
||||
{ 0, 1, 2, 3, 4, 11, 10, 9, 8, 5, 6, 7, 15, 14, 13, 12 },
|
||||
{ 0, 1, 2, 3, 4, 5, 12, 11, 10, 9, 8, 6, 7, 15, 14, 13 },
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 13, 12, 11, 10, 9, 8, 7, 15, 14 },
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8, 15 },
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 15, 14, 13, 12, 11, 10, 9, 8 }
|
||||
};
|
||||
const uint32_t RevDiskTypeZones[7][16] = {
|
||||
{ 0, 1, 2, 5, 6, 7, 8, 9, 4, 3, 15, 14, 13, 12, 11, 10 },
|
||||
{ 0, 1, 2, 3, 7, 8, 9, 10, 6, 5, 4, 15, 14, 13, 12, 11 },
|
||||
{ 0, 1, 2, 3, 4, 9, 10, 11, 8, 7, 6, 5, 15, 14, 13, 12 },
|
||||
{ 0, 1, 2, 3, 4, 5, 11, 12, 10, 9, 8, 7, 6, 15, 14, 13 },
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 13, 12, 11, 10, 9, 8, 7, 15, 14 },
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8, 15 },
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 15, 14, 13, 12, 11, 10, 9, 8 }
|
||||
};
|
||||
const uint32_t StartBlock[7][16] = {
|
||||
{ 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1 },
|
||||
{ 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0 },
|
||||
{ 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1 },
|
||||
{ 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0 },
|
||||
{ 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1 },
|
||||
{ 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 },
|
||||
{ 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 }
|
||||
};
|
||||
|
||||
uint32_t disktype = 0;
|
||||
uint32_t zone, track = 0;
|
||||
int32_t atrack = 0;
|
||||
int32_t block = 0;
|
||||
uint8_t SystemData[0xE8];
|
||||
uint8_t BlockData0[0x100 * SECTORS_PER_BLOCK];
|
||||
uint8_t BlockData1[0x100 * SECTORS_PER_BLOCK];
|
||||
uint32_t InOffset, OutOffset = 0;
|
||||
uint32_t InStart[16];
|
||||
uint32_t OutStart[16];
|
||||
|
||||
//SDK DISK RAM
|
||||
WriteTrace(TraceN64System, TraceDebug, "Allocating memory for disk SDK format");
|
||||
std::auto_ptr<uint8_t> ImageBase(new uint8_t[SDKFormatSize + 0x1000]);
|
||||
if (ImageBase.get() == NULL)
|
||||
{
|
||||
SetError(MSG_MEM_ALLOC_ERROR);
|
||||
WriteTrace(TraceN64System, TraceError, "Failed to allocate memory for disk SDK format (size: 0x%X)", SDKFormatSize);
|
||||
return;
|
||||
}
|
||||
uint8_t * Image = (uint8_t *)(((uint64_t)ImageBase.get() + 0xFFF) & ~0xFFF); // start at begining of memory page
|
||||
WriteTrace(TraceN64System, TraceDebug, "Allocated disk SDK format memory (%p)", Image);
|
||||
|
||||
//save information about the disk loaded
|
||||
uint8_t * s_DiskImageBase = ImageBase.release();
|
||||
uint8_t * s_DiskImage = Image;
|
||||
//END
|
||||
|
||||
InStart[0] = 0;
|
||||
OutStart[0] = 0;
|
||||
|
||||
//Read System Area
|
||||
memcpy(&SystemData, m_DiskImage, 0xE8);
|
||||
|
||||
disktype = SystemData[5] & 0xF;
|
||||
|
||||
//Prepare Input Offsets
|
||||
for (zone = 1; zone < 16; zone++)
|
||||
{
|
||||
InStart[zone] = InStart[zone - 1] +
|
||||
VZONESIZE(DiskTypeZones[disktype][zone - 1]);
|
||||
}
|
||||
|
||||
//Prepare Output Offsets
|
||||
for (zone = 1; zone < 16; zone++)
|
||||
{
|
||||
OutStart[zone] = OutStart[zone - 1] + ZONESIZE(zone - 1);
|
||||
}
|
||||
|
||||
//Copy Head 0
|
||||
for (zone = 0; zone < 8; zone++)
|
||||
{
|
||||
block = StartBlock[disktype][zone];
|
||||
atrack = 0;
|
||||
for (track = 0; track < ZoneTracks[zone]; track++)
|
||||
{
|
||||
InOffset = OutStart[zone] + (track)* TRACKSIZE(zone);
|
||||
OutOffset = InStart[RevDiskTypeZones[disktype][zone]] + (track - atrack) * TRACKSIZE(zone);
|
||||
|
||||
if (atrack < 0xC && track == SystemData[0x20 + zone * 0xC + atrack])
|
||||
{
|
||||
atrack += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((block % 2) == 1)
|
||||
{
|
||||
memcpy(&BlockData1, m_DiskImage + InOffset, BLOCKSIZE(zone));
|
||||
InOffset += BLOCKSIZE(zone);
|
||||
memcpy(&BlockData0, m_DiskImage + InOffset, BLOCKSIZE(zone));
|
||||
InOffset += BLOCKSIZE(zone);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&BlockData0, m_DiskImage + InOffset, BLOCKSIZE(zone));
|
||||
InOffset += BLOCKSIZE(zone);
|
||||
memcpy(&BlockData1, m_DiskImage + InOffset, BLOCKSIZE(zone));
|
||||
InOffset += BLOCKSIZE(zone);
|
||||
}
|
||||
block = 1 - block;
|
||||
memcpy(s_DiskImage + OutOffset, &BlockData0, BLOCKSIZE(zone));
|
||||
OutOffset += BLOCKSIZE(zone);
|
||||
memcpy(s_DiskImage + OutOffset, &BlockData1, BLOCKSIZE(zone));
|
||||
OutOffset += BLOCKSIZE(zone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Copy Head 1
|
||||
for (zone = 8; zone < 16; zone++)
|
||||
{
|
||||
block = StartBlock[disktype][zone];
|
||||
atrack = 0xB;
|
||||
for (track = 1; track < ZoneTracks[zone] + 1; track++)
|
||||
{
|
||||
InOffset = OutStart[zone] + (ZoneTracks[zone] - track) * TRACKSIZE(zone);
|
||||
OutOffset = InStart[RevDiskTypeZones[disktype][zone]] + (track - (0xB - atrack) - 1) * TRACKSIZE(zone);
|
||||
|
||||
if (atrack > -1 && (ZoneTracks[zone] - track) == SystemData[0x20 + (zone)* 0xC + atrack])
|
||||
{
|
||||
atrack -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((block % 2) == 1)
|
||||
{
|
||||
memcpy(&BlockData1, m_DiskImage + InOffset, BLOCKSIZE(zone));
|
||||
InOffset += BLOCKSIZE(zone);
|
||||
memcpy(&BlockData0, m_DiskImage + InOffset, BLOCKSIZE(zone));
|
||||
InOffset += BLOCKSIZE(zone);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&BlockData0, m_DiskImage + InOffset, BLOCKSIZE(zone));
|
||||
InOffset += BLOCKSIZE(zone);
|
||||
memcpy(&BlockData1, m_DiskImage + InOffset, BLOCKSIZE(zone));
|
||||
InOffset += BLOCKSIZE(zone);
|
||||
}
|
||||
block = 1 - block;
|
||||
memcpy(s_DiskImage + OutOffset, &BlockData0, BLOCKSIZE(zone));
|
||||
OutOffset += BLOCKSIZE(zone);
|
||||
memcpy(s_DiskImage + OutOffset, &BlockData1, BLOCKSIZE(zone));
|
||||
OutOffset += BLOCKSIZE(zone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_DiskFile.Write(s_DiskImage, SDKFormatSize))
|
||||
{
|
||||
m_DiskFile.Close();
|
||||
WriteTrace(TraceN64System, TraceError, "Failed to write file");
|
||||
}
|
||||
|
||||
WriteTrace(TraceN64System, TraceDebug, "Unallocating disk SDK format memory");
|
||||
delete[] s_DiskImageBase;
|
||||
s_DiskImageBase = NULL;
|
||||
s_DiskImage = NULL;
|
||||
}
|
|
@ -18,6 +18,8 @@ public:
|
|||
~CN64Disk();
|
||||
|
||||
bool LoadDiskImage(const char * FileLoc);
|
||||
bool SaveDiskImage();
|
||||
void SwapDiskImage(const char * FileLoc);
|
||||
static bool IsValidDiskImage(uint8_t Test[4]);
|
||||
uint8_t * GetDiskAddress() { return m_DiskImage; }
|
||||
uint8_t * GetDiskAddressBuffer() { return m_DiskImage + m_DiskBufAddress; }
|
||||
|
@ -30,11 +32,14 @@ private:
|
|||
bool AllocateDiskImage(uint32_t DiskFileSize);
|
||||
bool AllocateAndLoadDiskImage(const char * FileLoc);
|
||||
void ByteSwapDisk();
|
||||
void ForceByteSwapDisk();
|
||||
void SetError(LanguageStringID ErrorMsg);
|
||||
void ConvertDiskFormat();
|
||||
void ConvertDiskFormatBack();
|
||||
|
||||
//constant values
|
||||
enum { ReadFromRomSection = 0x400000, MameFormatSize = 0x0435B0C0, SDKFormatSize = 0x03DEC800 };
|
||||
enum { ReadFromRomSection = 0x400000, MameFormatSize = 0x0435B0C0, SDKFormatSize = 0x03DEC800,
|
||||
DiskFormatMAME = 0x0, DiskFormatSDK = 0x1 };
|
||||
|
||||
//class variables
|
||||
CFile m_DiskFile;
|
||||
|
@ -44,6 +49,7 @@ private:
|
|||
uint32_t m_DiskBufAddress;
|
||||
LanguageStringID m_ErrorMsg;
|
||||
stdstr m_FileName, m_DiskIdent;
|
||||
uint8_t m_DiskFormat; //0 = MAME, 1 = SDK
|
||||
|
||||
//disk convert
|
||||
#define SECTORS_PER_BLOCK 85
|
||||
|
|
|
@ -1292,6 +1292,7 @@ bool CCodeSection::GenerateX86Code(uint32_t Test)
|
|||
case R4300i_COP1_FUNCT_NEG: COP1_S_NEG(); break;
|
||||
case R4300i_COP1_FUNCT_SQRT: COP1_S_SQRT(); break;
|
||||
case R4300i_COP1_FUNCT_MOV: COP1_S_MOV(); break;
|
||||
case R4300i_COP1_FUNCT_ROUND_L: COP1_S_ROUND_L(); break;
|
||||
case R4300i_COP1_FUNCT_TRUNC_L: COP1_S_TRUNC_L(); break;
|
||||
case R4300i_COP1_FUNCT_CEIL_L: COP1_S_CEIL_L(); break; //added by Witten
|
||||
case R4300i_COP1_FUNCT_FLOOR_L: COP1_S_FLOOR_L(); break; //added by Witten
|
||||
|
@ -1326,6 +1327,7 @@ bool CCodeSection::GenerateX86Code(uint32_t Test)
|
|||
case R4300i_COP1_FUNCT_NEG: COP1_D_NEG(); break;
|
||||
case R4300i_COP1_FUNCT_SQRT: COP1_D_SQRT(); break;
|
||||
case R4300i_COP1_FUNCT_MOV: COP1_D_MOV(); break;
|
||||
case R4300i_COP1_FUNCT_ROUND_L: COP1_D_ROUND_L(); break;
|
||||
case R4300i_COP1_FUNCT_TRUNC_L: COP1_D_TRUNC_L(); break; //added by Witten
|
||||
case R4300i_COP1_FUNCT_CEIL_L: COP1_D_CEIL_L(); break; //added by Witten
|
||||
case R4300i_COP1_FUNCT_FLOOR_L: COP1_D_FLOOR_L(); break; //added by Witten
|
||||
|
|
|
@ -5946,6 +5946,18 @@ void CRecompilerOps::COP1_S_MOV()
|
|||
Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float);
|
||||
}
|
||||
|
||||
void CRecompilerOps::COP1_S_ROUND_L()
|
||||
{
|
||||
CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC));
|
||||
|
||||
m_Section->CompileCop1Test();
|
||||
if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float))
|
||||
{
|
||||
Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float);
|
||||
}
|
||||
ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Qword, CRegInfo::RoundNearest);
|
||||
}
|
||||
|
||||
void CRecompilerOps::COP1_S_TRUNC_L()
|
||||
{
|
||||
CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC));
|
||||
|
@ -6296,6 +6308,22 @@ void CRecompilerOps::COP1_D_MOV()
|
|||
Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
|
||||
}
|
||||
|
||||
void CRecompilerOps::COP1_D_ROUND_L()
|
||||
{
|
||||
CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC));
|
||||
|
||||
m_Section->CompileCop1Test();
|
||||
if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword))
|
||||
{
|
||||
UnMap_FPR(m_Opcode.fs, true);
|
||||
}
|
||||
if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double))
|
||||
{
|
||||
Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
|
||||
}
|
||||
ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Qword, CRegInfo::RoundNearest);
|
||||
}
|
||||
|
||||
void CRecompilerOps::COP1_D_TRUNC_L() //added by Witten
|
||||
{
|
||||
CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC));
|
||||
|
|
|
@ -160,6 +160,7 @@ protected:
|
|||
static void COP1_S_NEG ();
|
||||
static void COP1_S_SQRT ();
|
||||
static void COP1_S_MOV ();
|
||||
static void COP1_S_ROUND_L ();
|
||||
static void COP1_S_TRUNC_L ();
|
||||
static void COP1_S_CEIL_L (); //added by Witten
|
||||
static void COP1_S_FLOOR_L (); //added by Witten
|
||||
|
@ -181,6 +182,7 @@ protected:
|
|||
static void COP1_D_NEG ();
|
||||
static void COP1_D_SQRT ();
|
||||
static void COP1_D_MOV ();
|
||||
static void COP1_D_ROUND_L ();
|
||||
static void COP1_D_TRUNC_L (); //added by Witten
|
||||
static void COP1_D_CEIL_L (); //added by Witten
|
||||
static void COP1_D_FLOOR_L (); //added by Witten
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <Common/memtest.h>
|
||||
#include <Common/MemTest.h>
|
||||
#include <Common/CriticalSection.h>
|
||||
#include <Common/StdString.h>
|
||||
#include <Common/FileClass.h>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "stdafx.h"
|
||||
#include "RomInformationClass.h"
|
||||
#include <Project64-core/N64System/N64DiskClass.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <commdlg.h>
|
||||
|
@ -229,6 +230,31 @@ bool CMainMenu::ProcessMessage(HWND hWnd, DWORD /*FromAccelerator*/, DWORD MenuI
|
|||
g_Settings->SaveBool(GameRunning_LimitFPS, !g_Settings->LoadBool(GameRunning_LimitFPS));
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "ID_SYSTEM_LIMITFPS 1");
|
||||
break;
|
||||
case ID_SYSTEM_SWAPDISK:
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "ID_SYSTEM_SWAPDISK");
|
||||
// Open Disk
|
||||
OPENFILENAME openfilename;
|
||||
char FileName[_MAX_PATH], Directory[_MAX_PATH];
|
||||
|
||||
memset(&FileName, 0, sizeof(FileName));
|
||||
memset(&openfilename, 0, sizeof(openfilename));
|
||||
|
||||
strcpy(Directory, g_Settings->LoadStringVal(RomList_GameDir).c_str());
|
||||
|
||||
openfilename.lStructSize = sizeof(openfilename);
|
||||
openfilename.hwndOwner = (HWND)hWnd;
|
||||
openfilename.lpstrFilter = "N64DD Disk Image (*.ndd)\0*.ndd\0All files (*.*)\0*.*\0";
|
||||
openfilename.lpstrFile = FileName;
|
||||
openfilename.lpstrInitialDir = Directory;
|
||||
openfilename.nMaxFile = MAX_PATH;
|
||||
openfilename.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
|
||||
|
||||
if (GetOpenFileName(&openfilename))
|
||||
{
|
||||
g_Disk->SaveDiskImage();
|
||||
g_Disk->SwapDiskImage(FileName);
|
||||
}
|
||||
break;
|
||||
case ID_SYSTEM_SAVE:
|
||||
WriteTrace(TraceUserInterface, TraceDebug, "ID_SYSTEM_SAVE");
|
||||
g_BaseSystem->ExternalEvent(SysEvent_SaveMachineState);
|
||||
|
@ -868,6 +894,10 @@ void CMainMenu::FillOutMenu(HMENU hMenu)
|
|||
SystemMenu.push_back(Item);
|
||||
SystemMenu.push_back(MENU_ITEM(SPLITER));
|
||||
}
|
||||
Item.Reset(ID_SYSTEM_SWAPDISK, MENU_SWAPDISK, m_ShortCuts.ShortCutString(ID_SYSTEM_SWAPDISK, AccessLevel));
|
||||
if (g_Disk == NULL) { Item.SetItemEnabled(false); }
|
||||
SystemMenu.push_back(Item);
|
||||
SystemMenu.push_back(MENU_ITEM(SPLITER));
|
||||
SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_SAVE, MENU_SAVE, m_ShortCuts.ShortCutString(ID_SYSTEM_SAVE, AccessLevel)));
|
||||
if (!inBasicMode)
|
||||
{
|
||||
|
|
|
@ -18,7 +18,7 @@ enum MainMenuID
|
|||
|
||||
//System Menu
|
||||
ID_SYSTEM_RESET_SOFT, ID_SYSTEM_RESET_HARD, ID_SYSTEM_PAUSE, ID_SYSTEM_BITMAP,
|
||||
ID_SYSTEM_LIMITFPS, ID_SYSTEM_RESTORE, ID_SYSTEM_LOAD, ID_SYSTEM_SAVE,
|
||||
ID_SYSTEM_LIMITFPS, ID_SYSTEM_SWAPDISK, ID_SYSTEM_RESTORE, ID_SYSTEM_LOAD, ID_SYSTEM_SAVE,
|
||||
ID_SYSTEM_SAVEAS, ID_SYSTEM_CHEAT, ID_SYSTEM_GSBUTTON,
|
||||
|
||||
//Current Save Slot
|
||||
|
|
|
@ -316,6 +316,7 @@ void CShortCuts::Load(bool InitialValues)
|
|||
AddShortCut(ID_SYSTEM_PAUSE, STR_SHORTCUT_SYSTEMMENU, MENU_PAUSE, CMenuShortCutKey::GAME_RUNNING);
|
||||
AddShortCut(ID_SYSTEM_BITMAP, STR_SHORTCUT_SYSTEMMENU, MENU_BITMAP, CMenuShortCutKey::GAME_RUNNING);
|
||||
AddShortCut(ID_SYSTEM_LIMITFPS, STR_SHORTCUT_SYSTEMMENU, MENU_LIMIT_FPS, CMenuShortCutKey::GAME_RUNNING);
|
||||
AddShortCut(ID_SYSTEM_SWAPDISK, STR_SHORTCUT_SYSTEMMENU, MENU_SWAPDISK, CMenuShortCutKey::GAME_RUNNING_WINDOW);
|
||||
AddShortCut(ID_SYSTEM_SAVE, STR_SHORTCUT_SYSTEMMENU, MENU_SAVE, CMenuShortCutKey::GAME_RUNNING);
|
||||
AddShortCut(ID_SYSTEM_SAVEAS, STR_SHORTCUT_SYSTEMMENU, MENU_SAVE_AS, CMenuShortCutKey::GAME_RUNNING_WINDOW);
|
||||
AddShortCut(ID_SYSTEM_RESTORE, STR_SHORTCUT_SYSTEMMENU, MENU_RESTORE, CMenuShortCutKey::GAME_RUNNING);
|
||||
|
@ -383,6 +384,7 @@ void CShortCuts::Load(bool InitialValues)
|
|||
m_ShortCuts.find(ID_SYSTEM_PAUSE)->second.AddShortCut(VK_PAUSE, false, false, false, CMenuShortCutKey::GAME_RUNNING);
|
||||
m_ShortCuts.find(ID_SYSTEM_BITMAP)->second.AddShortCut(VK_F3, false, false, false, CMenuShortCutKey::GAME_RUNNING);
|
||||
m_ShortCuts.find(ID_SYSTEM_LIMITFPS)->second.AddShortCut(VK_F4, false, false, false, CMenuShortCutKey::GAME_RUNNING);
|
||||
m_ShortCuts.find(ID_SYSTEM_SWAPDISK)->second.AddShortCut('D', true, false, false, CMenuShortCutKey::GAME_RUNNING_WINDOW);
|
||||
m_ShortCuts.find(ID_SYSTEM_SAVE)->second.AddShortCut(VK_F5, false, false, false, CMenuShortCutKey::GAME_RUNNING);
|
||||
m_ShortCuts.find(ID_SYSTEM_RESTORE)->second.AddShortCut(VK_F7, false, false, false, CMenuShortCutKey::GAME_RUNNING);
|
||||
m_ShortCuts.find(ID_SYSTEM_LOAD)->second.AddShortCut('L', true, false, false, CMenuShortCutKey::GAME_RUNNING_WINDOW);
|
||||
|
|
|
@ -24,7 +24,42 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /
|
|||
if (g_Settings->LoadStringVal(Cmd_RomFile).length() > 0)
|
||||
{
|
||||
MainWindow.Show(true); //Show the main window
|
||||
CN64System::RunFileImage(g_Settings->LoadStringVal(Cmd_RomFile).c_str());
|
||||
//N64 ROM or 64DD Disk
|
||||
stdstr ext = CPath(g_Settings->LoadStringVal(Cmd_RomFile)).GetExtension();
|
||||
if (!(_stricmp(ext.c_str(), "ndd") == 0))
|
||||
{
|
||||
//File Extension is not *.ndd so it should be a N64 ROM
|
||||
CN64System::RunFileImage(g_Settings->LoadStringVal(Cmd_RomFile).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
//Ext is *.ndd, so it should be a disk file.
|
||||
if (CN64System::RunDiskImage(g_Settings->LoadStringVal(Cmd_RomFile).c_str()))
|
||||
{
|
||||
stdstr IPLROM = g_Settings->LoadStringVal(File_DiskIPLPath);
|
||||
if ((IPLROM.length() <= 0) || (!CN64System::RunFileImage(IPLROM.c_str())))
|
||||
{
|
||||
// Open DDROM
|
||||
OPENFILENAME openfilename;
|
||||
char FileName[_MAX_PATH], Directory[_MAX_PATH];
|
||||
memset(&FileName, 0, sizeof(FileName));
|
||||
memset(&openfilename, 0, sizeof(openfilename));
|
||||
|
||||
openfilename.lStructSize = sizeof(openfilename);
|
||||
//openfilename.hwndOwner = (HWND)hWnd;
|
||||
openfilename.lpstrFilter = "64DD IPL ROM Image (*.zip, *.7z, *.?64, *.rom, *.usa, *.jap, *.pal, *.bin)\0*.?64;*.zip;*.7z;*.bin;*.rom;*.usa;*.jap;*.pal\0All files (*.*)\0*.*\0";
|
||||
openfilename.lpstrFile = FileName;
|
||||
openfilename.lpstrInitialDir = Directory;
|
||||
openfilename.nMaxFile = MAX_PATH;
|
||||
openfilename.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
|
||||
|
||||
if (GetOpenFileName(&openfilename))
|
||||
{
|
||||
CN64System::RunFileImage(FileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue