From bf992eddfde9fd726cd1491b62d40f91aa0912fc Mon Sep 17 00:00:00 2001 From: David Walters Date: Sun, 5 Nov 2017 22:00:14 +0000 Subject: [PATCH 1/2] Ignore .o files --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..5761abcf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.o From 29bbd9a39746bf37c71df298ec0635299c84976e Mon Sep 17 00:00:00 2001 From: David Walters Date: Mon, 6 Nov 2017 00:12:15 +0000 Subject: [PATCH 2/2] Sync with Mednafen 0.9.46 changes. --- Makefile | 2 +- libretro.cpp | 4 +- mednafen/git.h | 23 ++++---- mednafen/ss/input/3dpad.cpp | 8 +-- mednafen/ss/input/mission.cpp | 22 +++---- mednafen/ss/sh7095.inc | 99 +++++++++++++++++++++++++++++-- mednafen/ss/smpc.cpp | 107 ++++++++++++++++++++++++++++++++-- mednafen/ss/smpc.h | 1 + mednafen/ss/vdp2_render.cpp | 13 +++-- 9 files changed, 237 insertions(+), 42 deletions(-) diff --git a/Makefile b/Makefile index c1616da0..37e66208 100644 --- a/Makefile +++ b/Makefile @@ -355,7 +355,7 @@ LDFLAGS += $(fpic) $(SHARED) FLAGS += $(fpic) $(NEW_GCC_FLAGS) FLAGS += $(INCFLAGS) -FLAGS += $(ENDIANNESS_DEFINES) -DSIZEOF_DOUBLE=8 $(WARNINGS) -DMEDNAFEN_VERSION=\"0.9.44.1\" -DPACKAGE=\"mednafen\" -DMEDNAFEN_VERSION_NUMERIC=9441 -DPSS_STYLE=1 -DMPC_FIXED_POINT $(CORE_DEFINE) -DSTDC_HEADERS -D__STDC_LIMIT_MACROS -D__LIBRETRO__ -D_LOW_ACCURACY_ $(EXTRA_INCLUDES) $(SOUND_DEFINE) -D__STDC_CONSTANT_MACROS +FLAGS += $(ENDIANNESS_DEFINES) -DSIZEOF_DOUBLE=8 $(WARNINGS) -DMEDNAFEN_VERSION=\"0.9.46\" -DPACKAGE=\"mednafen\" -DMEDNAFEN_VERSION_NUMERIC=94600 -DPSS_STYLE=1 -DMPC_FIXED_POINT $(CORE_DEFINE) -DSTDC_HEADERS -D__STDC_LIMIT_MACROS -D__LIBRETRO__ -D_LOW_ACCURACY_ $(EXTRA_INCLUDES) $(SOUND_DEFINE) -D__STDC_CONSTANT_MACROS ifeq ($(HAVE_RUST),1) FLAGS += -DHAVE_RUST diff --git a/libretro.cpp b/libretro.cpp index f7409503..5f34e7db 100644 --- a/libretro.cpp +++ b/libretro.cpp @@ -30,7 +30,7 @@ #define MEDNAFEN_CORE_NAME_MODULE "ss" #define MEDNAFEN_CORE_NAME "Mednafen Saturn" -#define MEDNAFEN_CORE_VERSION "v0.9.45.1" +#define MEDNAFEN_CORE_VERSION "v0.9.46" #define MEDNAFEN_CORE_EXTENSIONS "cue|ccd|chd" #define MEDNAFEN_CORE_TIMING_FPS 59.82 #define MEDNAFEN_CORE_GEOMETRY_BASE_W 320 @@ -1817,7 +1817,9 @@ int StateAction(StateMem *sm, int load, int data_only) CPU[0].StateAction(sm, load, data_only, "SH2-M"); CPU[1].StateAction(sm, load, data_only, "SH2-S"); SCU_StateAction(sm, load, data_only); +*/ SMPC_StateAction(sm, load, data_only); +/* CDB_StateAction(sm, load, data_only); VDP1::StateAction(sm, load, data_only); VDP2_StateAction(sm, load, data_only); diff --git a/mednafen/git.h b/mednafen/git.h index ddb0bee9..2b054f09 100644 --- a/mednafen/git.h +++ b/mednafen/git.h @@ -68,7 +68,8 @@ typedef enum IDIT_RUMBLE } InputDeviceInputType; -#define IDIT_BUTTON_ANALOG_FLAG_SQLR 0x00000001 +#define IDIT_BUTTON_ANALOG_FLAG_SQLR 0x01 // Denotes analog data that may need to be scaled to ensure a more squareish logical range(for emulated analog sticks). +#define IDIT_FLAG_AUX_SETTINGS_UNDOC 0x80 struct IDIIS_StatusState { @@ -77,6 +78,13 @@ struct IDIIS_StatusState int32 Color; // (msb)0RGB(lsb), -1 for unused. }; +struct IDIIS_SwitchPos +{ + const char* SettingName; + const char* Name; + const char* Description; +}; + struct InputDeviceInputInfoStruct { const char *SettingName; // No spaces, shouldbe all a-z0-9 and _. Definitely no ~! @@ -95,7 +103,7 @@ struct InputDeviceInputInfoStruct { struct { - const char** SwitchPosName; // + const IDIIS_SwitchPos* SwitchPos; uint32 SwitchNumPos; }; @@ -118,7 +126,7 @@ extern const IDIISG IDII_Empty; struct IDIIS_Switch : public InputDeviceInputInfoStruct { - IDIIS_Switch(const char* sname, const char* name, int co, const char** spn, const uint32 spn_num) + IDIIS_Switch(const char* sname, const char* name, int co, const IDIIS_SwitchPos* spn, const uint32 spn_num, bool undoc_defpos = true) { SettingName = sname; Name = name; @@ -126,9 +134,8 @@ struct IDIIS_Switch : public InputDeviceInputInfoStruct Type = IDIT_SWITCH; ExcludeName = NULL; - RotateName[0] = RotateName[1] = RotateName[2] = NULL; - Flags = 0; - SwitchPosName = spn; + Flags = undoc_defpos ? IDIT_FLAG_AUX_SETTINGS_UNDOC : 0; + SwitchPos = spn; SwitchNumPos = spn_num; } }; @@ -400,10 +407,6 @@ typedef enum MODPRIO_EXTERNAL_HIGH = 40 } ModPrio; -#define IDIT_BUTTON_ANALOG_FLAG_SQLR 0x00000001 // Denotes analog data that may need to be scaled to ensure a more squareish logical range(for emulated - // analog sticks). - - class CDIF; diff --git a/mednafen/ss/input/3dpad.cpp b/mednafen/ss/input/3dpad.cpp index a6028dbe..dcf2accf 100644 --- a/mednafen/ss/input/3dpad.cpp +++ b/mednafen/ss/input/3dpad.cpp @@ -164,10 +164,10 @@ uint8 IODevice_3DPad::UpdateBus(const sscpu_timestamp_t timestamp, const uint8 s return (smpc_out & (smpc_out_asserted | 0xE0)) | (tmp &~ smpc_out_asserted); } -static const char* ModeSwitchPositions[] = +static const IDIIS_SwitchPos ModeSwitchPositions[] = { - "Digital(+)", - "Analog(○)", + { "digital", "Digital(+)" }, + { "analog", "Analog(○)", "Analog mode is not compatible with all games. For some compatible games, analog mode reportedly must be enabled before the game boots up for the game to recognize it properly." }, }; IDIISG IODevice_3DPad_IDII = @@ -187,7 +187,7 @@ IDIISG IODevice_3DPad_IDII = { "x", "X", 8, IDIT_BUTTON }, { NULL, "empty", 0, IDIT_BUTTON }, - IDIIS_Switch("mode", "Mode", 17, ModeSwitchPositions, sizeof(ModeSwitchPositions) / sizeof(ModeSwitchPositions[0])), + IDIIS_Switch("mode", "Mode", 17, ModeSwitchPositions, sizeof(ModeSwitchPositions) / sizeof(ModeSwitchPositions[0]), false), { "analog_left", "Analog LEFT ←", 15, IDIT_BUTTON_ANALOG }, { "analog_right", "Analog RIGHT →", 16, IDIT_BUTTON_ANALOG }, diff --git a/mednafen/ss/input/mission.cpp b/mednafen/ss/input/mission.cpp index 8fe4f8e7..27e689f9 100644 --- a/mednafen/ss/input/mission.cpp +++ b/mednafen/ss/input/mission.cpp @@ -191,21 +191,21 @@ uint8 IODevice_Mission::UpdateBus(const sscpu_timestamp_t timestamp, const uint8 return (smpc_out & (smpc_out_asserted | 0xE0)) | (tmp &~ smpc_out_asserted); } -static const char* SpeedSwitchPositions[] = +static const IDIIS_SwitchPos SpeedSwitchPositions[] = { - "1/7", - "2/7", - "3/7", - "4/7", - "5/7", - "6/7", - "7/7" + { "1", "1/7", "Slowest" }, + { "2", "2/7" }, + { "3", "3/7" }, + { "4", "4/7" }, + { "5", "5/7" }, + { "6", "6/7" }, + { "7", "7/7", "Fastest" }, }; -static const char* AFSwitchPositions[] = +static const IDIIS_SwitchPos AFSwitchPositions[] = { - "• (Off)", - "•• (On))" + { "off", "• (Off)", }, + { "on", "•• (On)" }, }; IDIISG IODevice_Mission_IDII = diff --git a/mednafen/ss/sh7095.inc b/mednafen/ss/sh7095.inc index 48e9d0c2..c55db0bb 100644 --- a/mednafen/ss/sh7095.inc +++ b/mednafen/ss/sh7095.inc @@ -26,6 +26,8 @@ DMA timing is very rough. DMA burst mode probably isn't handled totally correctly, especially in relation to the other CPU and the SCU(is DMA burst mode even legal on the Saturn?). + DMA channel bus priority handling is not correct(at least not for non-burst mode transfers). + Misaligned memory accesses(that cause address errors) aren't emulated correctly(for future reference, there's a difference between how cache versus external bus is accessed for misaligned addresses, and perhaps a difference between 32-bit and 16-bit spaces as @@ -878,6 +880,7 @@ INLINE void SH7095::DIVU_S64_S32(void) DVDNTL_Shadow = DVDNTL; } +// // // Begin SCI // @@ -905,8 +908,6 @@ void SH7095::SCI_Reset(void) // // -// - // // Misaligned/wrong-sized accesses aren't handled correctly, it's a mess, but probably doesn't matter. // @@ -1065,6 +1066,33 @@ NO_INLINE void SH7095::OnChipRegWrite(uint32 A, uint32 V) SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] Unhandled %zu-byte write to on-chip low register area; address=0x%08x value=0x%08x\n", cpu_name, sizeof(T), A, V); break; +#if 0 + // + // SCI registers. + // + case 0x00: + SCI.SMR = V; + break; + + case 0x01: + SCI.BRR = V; + break; + + case 0x02: + SCI.SCR = V; + RecalcPendingIntPEX(); + break; + + case 0x03: + SCI.TDR = V; + break; + + case 0x04: + SCI.SSR = (SCI.SSR & ~SCI.SSRM & 0xF8) | (SCI.SSR & 0x06) | (V & 0x01); + SCI.SSRM = 0; + RecalcPendingIntPEX(); + break; +#endif // // Free-running timer registers. // @@ -1478,6 +1506,35 @@ INLINE T SH7095::OnChipRegRead(uint32 A) SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] Unhandled %zu-byte read from on-chip low register area; address=0x%08x\n", cpu_name, sizeof(T), A); break; +#if 0 + // + // SCI registers. + // + case 0x00: + ret = SCI.SMR; + break; + + case 0x01: + ret = SCI.BRR; + break; + + case 0x02: + ret = SCI.SCR; + break; + + case 0x03: + ret = SCI.TDR; + break; + + case 0x04: + ret = SCI.SSR; + SCI.SSRM = SCI.SSR & 0xF8; + break; + + case 0x05: + ret = SCI.RDR; + break; +#endif // // FRT registers. Some weirdness with 16-bit reads duplicating the lower 8 bits in the upper 8-bits, but the upper 8-bits are masked // with the last data written to the FRT area or something...not emulated here. @@ -1808,6 +1865,14 @@ INLINE T SH7095::MemReadRT(uint32 A) else timestamp = SH7095_mem_timestamp; } + +#if 0 + if((SH7095_FastMap[A >> SH7095_EXT_MAP_GRAN_BITS] + (A & ((1U << SH7095_EXT_MAP_GRAN_BITS) - 1))) == (uintptr_t)fmap_dummy) + SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] Cacheable %zu-byte read from non-RAM address 0x%08x!\n", cpu_name, sizeof(T), A); + else if(ne16_rbo_be((uint16*)(SH7095_FastMap[A >> SH7095_EXT_MAP_GRAN_BITS] + (A & ~0x3)), A & 0x3) != MDFN_densb(¢->Data[way_match][NE32ASU8_IDX_ADJ(T, A & 0x0F)])) + SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] Cache incoherency for %zu-byte read from address 0x%08x!\n", cpu_name, sizeof(T), A); +#endif + cent->LRU = (cent->LRU & LRU_Update_Tab[way_match].AND) | LRU_Update_Tab[way_match].OR; return MDFN_densb(¢->Data[way_match][NE32ASU8_IDX_ADJ(T, A & 0x0F)]); } @@ -2214,6 +2279,28 @@ uint8 INLINE SH7095::GetPendingInt(uint8* vecnum_out) // // // +#if 0 + { + const uint32 sci_ip_tmp = (SCI.SSR & SCI.SCR & 0xC4) | (SCI.SSR & 0x38); + + if(sci_ip_tmp && (tmp_ipr = ((IPRB >> 12) & 0xF)) > ipr) + { + ipr = tmp_ipr; + + if(sci_ip_tmp & 0x38) // ERI(receive error; ORER, PER, FER) + vecnum = (VCRA >> 8) & 0x7F; + else if(sci_ip_tmp & 0x40)// RXI(receive data full; RDRF) + vecnum = (VCRA >> 0) & 0x7F; + else if(sci_ip_tmp & 0x80)// TXI(transmit data empty; TDRE) + vecnum = (VCRB >> 8) & 0x7F; + else if(sci_ip_tmp & 0x04)// TEI(transmit end; TEND) + vecnum = (VCRB >> 0) & 0x7F; + } + } +#endif + // + // + // const uint32 frt_ip_tmp = (FRT.FTCSR & FRT.TIER & 0x8E); if(frt_ip_tmp && (tmp_ipr = ((IPRB >> 8) & 0xF)) > ipr) { @@ -4227,9 +4314,9 @@ INLINE void SH7095::Step(void) WDT_StandbyReset(); // // - SCI_Reset(); - // - // + SCI_Reset(); + // + // timestamp++; Pipe_ID = (Pipe_ID & 0x00FFFFFF) | (0x7E << 24); @@ -4624,7 +4711,7 @@ INLINE uint32 SH7095::GetRegister(const unsigned id, char* const special, const ret = VCRC; if(special) { - snprintf(special, special_len, "FIC: 0x%02x, FOC: 0x%02x", (ret >> 8) & 0x7F, ret & 0x7F); + snprintf(special, special_len, "FIC: 0x%02x, FOC: 0x%02x", (ret >> 8) & 0x7F, ret & 0x7F); } break; diff --git a/mednafen/ss/smpc.cpp b/mednafen/ss/smpc.cpp index 775ed4e1..db0ad6e5 100644 --- a/mednafen/ss/smpc.cpp +++ b/mednafen/ss/smpc.cpp @@ -184,12 +184,17 @@ static struct uint8 TapCount; uint8 ReadCounter; uint8 ReadCount; - uint8 ReadBuffer[255]; //16]; + uint8 ReadBuffer[256]; // Maybe should only be 255, but +1 for save state sanitization simplification. uint8 WriteCounter; uint8 PDCounter; } JRS; // // +static bool vb; +static bool vsync; +static sscpu_timestamp_t lastts; +// +// static uint8 DataOut[2][2]; static uint8 DataDir[2][2]; static bool DirectModeEn[2]; @@ -235,10 +240,6 @@ void IODevice::LineHook(const sscpu_timestamp_t timestamp, int32 out_line, int32 // // -static bool vb; -static bool vsync; -static sscpu_timestamp_t lastts; - static void UpdateIOBus(unsigned port, const sscpu_timestamp_t timestamp) { IOBusState[port] = IOPorts[port]->UpdateBus(timestamp, (DataOut[port][DirectModeEn[port]] | ~DataDir[port][DirectModeEn[port]]) & 0x7F, DataDir[port][DirectModeEn[port]]); @@ -492,6 +493,100 @@ void SMPC_Reset(bool powering_up) } +void SMPC_StateAction(StateMem* sm, const unsigned load, const bool data_only) +{ + SFORMAT StateRegs[] = + { + SFVAR(RTC.ClockAccum), + SFVAR(RTC.Valid), + SFARRAY(RTC.raw, 7), + + SFARRAY(SaveMem, 4), + + SFARRAY(IREG, 7), + SFARRAY(OREG, 0x20), + SFVAR(SR), + SFVAR(SF), + + SFVAR(ResetNMIEnable), + SFVAR(ResetButtonPhysStatus), + SFVAR(ResetButtonCount), + SFVAR(ResetPending), + SFVAR(PendingCommand), + SFVAR(ExecutingCommand), + SFVAR(PendingClockDivisor), + SFVAR(CurrentClockDivisor), + + SFVAR(PendingVB), + + SFVAR(SubPhase), + SFVAR(ClockCounter), + SFVAR(SMPC_ClockRatio), + + SFVAR(SoundCPUOn), + SFVAR(SlaveSH2On), + SFVAR(CDOn), + + SFVAR(BusBuffer), + + SFVAR(JRS.TimeCounter), + SFVAR(JRS.StartTime), + SFVAR(JRS.OptWaitUntilTime), + SFVAR(JRS.OptEatTime), + SFVAR(JRS.OptReadTime), + + SFARRAY(JRS.Mode, 2), + SFVAR(JRS.TimeOptEn), + SFVAR(JRS.NextContBit), + + SFVAR(JRS.CurPort), + SFVAR(JRS.ID1), + SFVAR(JRS.ID2), + SFVAR(JRS.IDTap), + + SFVAR(JRS.CommMode), + + SFVAR(JRS.OWP), + + SFARRAY(JRS.work, 8), + + SFVAR(JRS.TapCounter), + SFVAR(JRS.TapCount), + SFVAR(JRS.ReadCounter), + SFVAR(JRS.ReadCount), + SFARRAY(JRS.ReadBuffer, 256), + SFVAR(JRS.WriteCounter), + SFVAR(JRS.PDCounter), + + SFARRAY(&DataOut[0][0], 4), + SFARRAY(&DataDir[0][0], 4), + SFARRAYB(DirectModeEn, 2), + SFARRAYB(ExLatchEn, 2), + + SFARRAY(IOBusState, 2), + + SFVAR(vb), + SFVAR(vsync), + + SFEND + }; + + MDFNSS_StateAction(sm, load, data_only, StateRegs, "SMPC"); + + for(unsigned port = 0; port < 2; port++) + { + const char snp[] = { 'S', 'M', 'P', 'C', '_', 'P', (char)('0' + port), 0 }; + + IOPorts[port]->StateAction(sm, load, data_only, snp); + } + + if(load) + { + JRS.CurPort &= 0x1; + JRS.OWP &= 0x3F; + } +} + void SMPC_TransformInput(void) { float gun_x_scale, gun_x_offs; @@ -1306,6 +1401,8 @@ sscpu_timestamp_t SMPC_Update(sscpu_timestamp_t timestamp) JR_TH_TR(-1, -1); } + JRS.CurPort = 0; // For save state sanitization consistency. + SR = (SR & ~SR_NPE); SR = (SR & ~0xF) | (JRS.Mode[0] << 0) | (JRS.Mode[1] << 2); SR = (SR & ~SR_PDL) | ((JRS.PDCounter < 0x2) ? SR_PDL : 0); diff --git a/mednafen/ss/smpc.h b/mednafen/ss/smpc.h index 3dcea1e5..11d9f469 100644 --- a/mednafen/ss/smpc.h +++ b/mednafen/ss/smpc.h @@ -58,6 +58,7 @@ bool SMPC_IsSlaveOn(void); void SMPC_Reset(bool powering_up); void SMPC_LoadNV(Stream* s); void SMPC_SaveNV(Stream* s); +void SMPC_StateAction(StateMem* sm, const unsigned load, const bool data_only); void SMPC_SetRTC(const struct tm* ht, const uint8 lang); diff --git a/mednafen/ss/vdp2_render.cpp b/mednafen/ss/vdp2_render.cpp index 048e8ec9..6e45d88b 100644 --- a/mednafen/ss/vdp2_render.cpp +++ b/mednafen/ss/vdp2_render.cpp @@ -1708,10 +1708,15 @@ static void T_DrawNBG23(const unsigned n, uint64* bgbuf, const unsigned w, const bgbuf -= xscr & 0x7; tx = xscr >> 3; - //if(TA_bpp == 4 && n == 3) - // printf("Goop: %d %d %02x, %016llx %016llx %016llx %016llx\n", n, TA_bpp, VRAM_Mode, MDFN_de64lsb(VCPRegs[0]), MDFN_de64lsb(VCPRegs[1]), MDFN_de64lsb(VCPRegs[2]), MDFN_de64lsb(VCPRegs[3])); - // Kludge for Akumajou Dracula X - if(MDFN_UNLIKELY(TA_bpp == 4 && n == 3 && VRAM_Mode == 0x2 && MDFN_de64lsb(VCPRegs[0]) == 0x0f0f070406060505ULL && MDFN_de64lsb(VCPRegs[2]) == 0x0f0f03000f0f0201ULL && MDFN_de64lsb(VCPRegs[3]) == 0x0f0f0f0f0f0f0f0fULL)) + // + // Layer offset kludges + // + // Note: When/If adding new kludges, check that the NT and CG fetches for the layer each occur only in one bank, to safely handle other cases may require something more complex. + // printf("(TA_bpp == %d && n == %d && VRAM_Mode == 0x%01x && (HRes & 0x6) == 0x%01x && MDFN_de64lsb(VCPRegs[0]) == 0x%016llxULL && MDFN_de64lsb(VCPRegs[1]) == 0x%016llxULL && MDFN_de64lsb(VCPRegs[2]) == 0x%016llxULL && MDFN_de64lsb(VCPRegs[3]) == 0x%016llxULL) || \n", TA_bpp, n, VRAM_Mode, HRes & 0x6, (unsigned long long)MDFN_de64lsb(VCPRegs[0]), (unsigned long long)MDFN_de64lsb(VCPRegs[1]), (unsigned long long)MDFN_de64lsb(VCPRegs[2]), (unsigned long long)MDFN_de64lsb(VCPRegs[3])); + if(MDFN_UNLIKELY( + /* Akumajou Dracula X */ (TA_bpp == 4 && n == 3 && VRAM_Mode == 0x2 && (HRes & 0x6) == 0x0 && MDFN_de64lsb(VCPRegs[0]) == 0x0f0f070406060505ULL && MDFN_de64lsb(VCPRegs[1]) == 0x0f0f0f0f0f0f0f0fULL && MDFN_de64lsb(VCPRegs[2]) == 0x0f0f03000f0f0201ULL && MDFN_de64lsb(VCPRegs[3]) == 0x0f0f0f0f0f0f0f0fULL) || + /* Daytona USA CCE */ (TA_bpp == 4 && n == 2 && VRAM_Mode == 0x3 && (HRes & 0x6) == 0x0 && MDFN_de64lsb(VCPRegs[0]) == 0x0f0f0f0f00000404ULL && MDFN_de64lsb(VCPRegs[1]) == 0x0f0f0f060f0f0f0fULL && MDFN_de64lsb(VCPRegs[2]) == 0x0f0f0f0f0505070fULL && MDFN_de64lsb(VCPRegs[3]) == 0x0f0f03020f010f00ULL) || + 0)) { for(unsigned i = 0; i < 8; i++) *bgbuf++ = 0;