2016-12-05 17:02:29 +00:00
|
|
|
/*
|
2022-01-09 01:15:50 +00:00
|
|
|
Copyright 2016-2022 melonDS team
|
2016-12-05 17:02:29 +00:00
|
|
|
|
|
|
|
This file is part of melonDS.
|
|
|
|
|
|
|
|
melonDS is free software: you can redistribute it and/or modify it under
|
|
|
|
the terms of the GNU General Public License as published by the Free
|
|
|
|
Software Foundation, either version 3 of the License, or (at your option)
|
|
|
|
any later version.
|
|
|
|
|
|
|
|
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
|
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License along
|
|
|
|
with melonDS. If not, see http://www.gnu.org/licenses/.
|
|
|
|
*/
|
|
|
|
|
2016-05-16 15:48:40 +00:00
|
|
|
#include <stdio.h>
|
2016-12-03 12:42:27 +00:00
|
|
|
#include <string.h>
|
2021-06-05 01:34:30 +00:00
|
|
|
#include <inttypes.h>
|
2016-05-16 15:48:40 +00:00
|
|
|
#include "NDS.h"
|
2016-11-03 00:38:58 +00:00
|
|
|
#include "ARM.h"
|
2017-01-22 19:34:59 +00:00
|
|
|
#include "NDSCart.h"
|
2019-12-08 18:46:51 +00:00
|
|
|
#include "GBACart.h"
|
2017-01-18 00:33:06 +00:00
|
|
|
#include "DMA.h"
|
2017-01-17 00:58:25 +00:00
|
|
|
#include "FIFO.h"
|
2017-01-18 03:03:19 +00:00
|
|
|
#include "GPU.h"
|
2017-04-06 17:44:34 +00:00
|
|
|
#include "SPU.h"
|
2016-12-04 02:20:50 +00:00
|
|
|
#include "SPI.h"
|
2017-01-20 00:18:30 +00:00
|
|
|
#include "RTC.h"
|
2016-12-06 16:32:51 +00:00
|
|
|
#include "Wifi.h"
|
2020-02-14 18:26:52 +00:00
|
|
|
#include "AREngine.h"
|
2017-09-21 01:59:12 +00:00
|
|
|
#include "Platform.h"
|
2021-10-02 10:06:22 +00:00
|
|
|
#include "FreeBIOS.h"
|
2020-06-30 21:50:41 +00:00
|
|
|
|
|
|
|
#ifdef JIT_ENABLED
|
2019-06-21 23:28:32 +00:00
|
|
|
#include "ARMJIT.h"
|
2020-06-14 19:04:25 +00:00
|
|
|
#include "ARMJIT_Memory.h"
|
2020-06-30 21:50:41 +00:00
|
|
|
#endif
|
2016-05-16 15:48:40 +00:00
|
|
|
|
2019-06-13 12:41:54 +00:00
|
|
|
#include "DSi.h"
|
2019-08-04 09:44:36 +00:00
|
|
|
#include "DSi_SPI_TSC.h"
|
2022-01-07 13:00:43 +00:00
|
|
|
#include "DSi_NWifi.h"
|
|
|
|
#include "DSi_Camera.h"
|
|
|
|
#include "DSi_DSP.h"
|
2019-06-13 12:41:54 +00:00
|
|
|
|
2018-12-11 14:56:34 +00:00
|
|
|
|
2016-05-16 15:48:40 +00:00
|
|
|
namespace NDS
|
|
|
|
{
|
|
|
|
|
2018-12-04 16:54:10 +00:00
|
|
|
// timing notes
|
|
|
|
//
|
|
|
|
// * this implementation is technically wrong for VRAM
|
|
|
|
// each bank is considered a separate region
|
|
|
|
// but this would only matter in specific VRAM->VRAM DMA transfers or
|
|
|
|
// when running code in VRAM, which is way unlikely
|
|
|
|
//
|
|
|
|
// bus/basedelay/nspenalty
|
|
|
|
//
|
|
|
|
// bus types:
|
|
|
|
// * 0 / 32-bit: nothing special
|
|
|
|
// * 1 / 16-bit: 32-bit accesses split into two 16-bit accesses, second is always sequential
|
|
|
|
// * 2 / 8-bit/GBARAM: (presumably) split into multiple 8-bit accesses?
|
|
|
|
// * 3 / ARM9 internal: cache/TCM
|
|
|
|
//
|
|
|
|
// ARM9 always gets 3c nonseq penalty when using the bus (except for mainRAM where the penalty is 7c)
|
2019-01-05 04:28:58 +00:00
|
|
|
// /!\ 3c penalty doesn't apply to DMA!
|
2018-12-04 16:54:10 +00:00
|
|
|
//
|
|
|
|
// ARM7 only gets nonseq penalty when accessing mainRAM (7c as for ARM9)
|
|
|
|
//
|
|
|
|
// timings for GBA slot and wifi are set up at runtime
|
|
|
|
|
2020-06-01 18:36:30 +00:00
|
|
|
int ConsoleType;
|
|
|
|
|
2021-08-31 00:28:34 +00:00
|
|
|
u8 ARM9MemTimings[0x40000][8];
|
|
|
|
u32 ARM9Regions[0x40000];
|
2018-12-08 21:33:41 +00:00
|
|
|
u8 ARM7MemTimings[0x20000][4];
|
2021-08-31 00:28:34 +00:00
|
|
|
u32 ARM7Regions[0x20000];
|
2018-12-04 16:54:10 +00:00
|
|
|
|
|
|
|
ARMv5* ARM9;
|
|
|
|
ARMv4* ARM7;
|
2016-11-03 00:38:58 +00:00
|
|
|
|
2021-11-17 22:23:22 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2021-11-17 17:15:50 +00:00
|
|
|
bool EnableJIT;
|
2021-11-17 22:23:22 +00:00
|
|
|
#endif
|
2021-11-17 17:15:50 +00:00
|
|
|
|
2018-12-12 01:48:37 +00:00
|
|
|
u32 NumFrames;
|
2021-01-21 20:26:27 +00:00
|
|
|
u32 NumLagFrames;
|
|
|
|
bool LagFrameFlag;
|
2018-12-12 01:48:37 +00:00
|
|
|
u64 LastSysClockCycles;
|
2019-01-05 04:28:58 +00:00
|
|
|
u64 FrameStartTimestamp;
|
2018-12-12 01:48:37 +00:00
|
|
|
|
2018-11-09 13:10:06 +00:00
|
|
|
int CurCPU;
|
2017-01-31 02:54:51 +00:00
|
|
|
|
2019-06-25 00:05:48 +00:00
|
|
|
const s32 kMaxIterationCycles = 64;
|
2021-09-27 01:29:54 +00:00
|
|
|
const s32 kIterationCycleMargin = 8;
|
2019-01-05 04:28:58 +00:00
|
|
|
|
|
|
|
u32 ARM9ClockShift;
|
|
|
|
|
|
|
|
// no need to worry about those overflowing, they can keep going for atleast 4350 years
|
|
|
|
u64 ARM9Timestamp, ARM9Target;
|
|
|
|
u64 ARM7Timestamp, ARM7Target;
|
|
|
|
u64 SysTimestamp;
|
|
|
|
|
2017-01-31 02:54:51 +00:00
|
|
|
SchedEvent SchedList[Event_MAX];
|
|
|
|
u32 SchedListMask;
|
2016-11-24 17:31:49 +00:00
|
|
|
|
2017-02-17 04:33:37 +00:00
|
|
|
u32 CPUStop;
|
|
|
|
|
2016-11-03 00:38:58 +00:00
|
|
|
u8 ARM9BIOS[0x1000];
|
|
|
|
u8 ARM7BIOS[0x4000];
|
2016-05-16 15:48:40 +00:00
|
|
|
|
2020-06-14 19:04:25 +00:00
|
|
|
u8* MainRAM;
|
2019-08-05 17:52:03 +00:00
|
|
|
u32 MainRAMMask;
|
2016-12-03 15:13:04 +00:00
|
|
|
|
2020-06-14 19:04:25 +00:00
|
|
|
u8* SharedWRAM;
|
2016-12-03 17:29:19 +00:00
|
|
|
u8 WRAMCnt;
|
|
|
|
|
2020-06-14 19:04:25 +00:00
|
|
|
// putting them together so they're always next to each other
|
|
|
|
MemRegion SWRAM_ARM9;
|
|
|
|
MemRegion SWRAM_ARM7;
|
|
|
|
|
|
|
|
u8* ARM7WRAM;
|
2016-12-03 12:42:27 +00:00
|
|
|
|
2017-01-22 19:34:59 +00:00
|
|
|
u16 ExMemCnt[2];
|
|
|
|
|
2020-02-24 17:31:44 +00:00
|
|
|
// TODO: these belong in NDSCart!
|
2017-01-22 19:34:59 +00:00
|
|
|
u8 ROMSeed0[2*8];
|
|
|
|
u8 ROMSeed1[2*8];
|
|
|
|
|
2016-12-03 15:13:04 +00:00
|
|
|
// IO shit
|
2016-12-04 02:20:50 +00:00
|
|
|
u32 IME[2];
|
|
|
|
u32 IE[2], IF[2];
|
2019-06-16 13:05:18 +00:00
|
|
|
u32 IE2, IF2;
|
2016-12-04 02:20:50 +00:00
|
|
|
|
2017-01-18 01:20:45 +00:00
|
|
|
u8 PostFlag9;
|
|
|
|
u8 PostFlag7;
|
2016-12-06 16:32:51 +00:00
|
|
|
u16 PowerControl9;
|
|
|
|
u16 PowerControl7;
|
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
u16 WifiWaitCnt;
|
|
|
|
|
2017-02-05 16:15:17 +00:00
|
|
|
u16 ARM7BIOSProt;
|
|
|
|
|
2016-12-05 16:08:24 +00:00
|
|
|
Timer Timers[8];
|
2017-04-24 23:14:26 +00:00
|
|
|
u8 TimerCheckMask[2];
|
2019-01-05 04:28:58 +00:00
|
|
|
u64 TimerTimestamp[2];
|
2016-12-05 16:08:24 +00:00
|
|
|
|
2017-01-18 00:33:06 +00:00
|
|
|
DMA* DMAs[8];
|
|
|
|
u32 DMA9Fill[4];
|
|
|
|
|
2016-12-03 15:13:04 +00:00
|
|
|
u16 IPCSync9, IPCSync7;
|
2017-01-17 00:58:25 +00:00
|
|
|
u16 IPCFIFOCnt9, IPCFIFOCnt7;
|
2020-12-30 22:37:46 +00:00
|
|
|
FIFO<u32, 16> IPCFIFO9; // FIFO in which the ARM9 writes
|
|
|
|
FIFO<u32, 16> IPCFIFO7;
|
2016-12-03 15:13:04 +00:00
|
|
|
|
2017-01-18 01:20:45 +00:00
|
|
|
u16 DivCnt;
|
|
|
|
u32 DivNumerator[2];
|
|
|
|
u32 DivDenominator[2];
|
|
|
|
u32 DivQuotient[2];
|
|
|
|
u32 DivRemainder[2];
|
|
|
|
|
2017-01-31 20:53:45 +00:00
|
|
|
u16 SqrtCnt;
|
|
|
|
u32 SqrtVal[2];
|
|
|
|
u32 SqrtRes;
|
|
|
|
|
2016-12-23 20:22:22 +00:00
|
|
|
u32 KeyInput;
|
2017-06-04 20:34:31 +00:00
|
|
|
u16 KeyCnt;
|
|
|
|
u16 RCnt;
|
2016-12-23 20:22:22 +00:00
|
|
|
|
2016-11-24 17:31:49 +00:00
|
|
|
bool Running;
|
|
|
|
|
2020-02-24 17:31:44 +00:00
|
|
|
bool RunningGame;
|
|
|
|
|
2018-10-17 23:38:33 +00:00
|
|
|
void DivDone(u32 param);
|
|
|
|
void SqrtDone(u32 param);
|
2018-11-23 21:21:41 +00:00
|
|
|
void RunTimer(u32 tid, s32 cycles);
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
void UpdateWifiTimings();
|
2018-12-09 00:17:05 +00:00
|
|
|
void SetWifiWaitCnt(u16 val);
|
|
|
|
void SetGBASlotTimings();
|
2018-10-17 23:38:33 +00:00
|
|
|
|
|
|
|
|
2017-02-07 21:23:46 +00:00
|
|
|
bool Init()
|
2016-05-16 15:48:40 +00:00
|
|
|
{
|
2018-12-04 16:54:10 +00:00
|
|
|
ARM9 = new ARMv5();
|
|
|
|
ARM7 = new ARMv4();
|
2016-11-03 00:38:58 +00:00
|
|
|
|
2019-07-14 17:24:00 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2019-06-21 23:28:32 +00:00
|
|
|
ARMJIT::Init();
|
2020-06-14 19:04:25 +00:00
|
|
|
#else
|
2020-06-30 21:50:41 +00:00
|
|
|
MainRAM = new u8[0x1000000];
|
2020-06-14 19:04:25 +00:00
|
|
|
ARM7WRAM = new u8[ARM7WRAMSize];
|
|
|
|
SharedWRAM = new u8[SharedWRAMSize];
|
2019-07-14 17:24:00 +00:00
|
|
|
#endif
|
2019-06-21 23:28:32 +00:00
|
|
|
|
2017-01-18 00:33:06 +00:00
|
|
|
DMAs[0] = new DMA(0, 0);
|
|
|
|
DMAs[1] = new DMA(0, 1);
|
|
|
|
DMAs[2] = new DMA(0, 2);
|
|
|
|
DMAs[3] = new DMA(0, 3);
|
|
|
|
DMAs[4] = new DMA(1, 0);
|
|
|
|
DMAs[5] = new DMA(1, 1);
|
|
|
|
DMAs[6] = new DMA(1, 2);
|
|
|
|
DMAs[7] = new DMA(1, 3);
|
|
|
|
|
2017-02-07 21:23:46 +00:00
|
|
|
if (!NDSCart::Init()) return false;
|
2019-12-08 20:30:56 +00:00
|
|
|
if (!GBACart::Init()) return false;
|
2017-02-07 21:23:46 +00:00
|
|
|
if (!GPU::Init()) return false;
|
2017-04-06 17:44:34 +00:00
|
|
|
if (!SPU::Init()) return false;
|
2017-02-07 21:23:46 +00:00
|
|
|
if (!SPI::Init()) return false;
|
|
|
|
if (!RTC::Init()) return false;
|
2017-05-11 17:57:49 +00:00
|
|
|
if (!Wifi::Init()) return false;
|
2016-12-04 02:20:50 +00:00
|
|
|
|
2019-06-16 15:01:49 +00:00
|
|
|
if (!DSi::Init()) return false;
|
|
|
|
|
2020-02-14 18:26:52 +00:00
|
|
|
if (!AREngine::Init()) return false;
|
|
|
|
|
2017-02-07 21:23:46 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DeInit()
|
|
|
|
{
|
2019-07-14 17:24:00 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2019-06-21 23:28:32 +00:00
|
|
|
ARMJIT::DeInit();
|
2019-07-14 17:24:00 +00:00
|
|
|
#endif
|
2019-06-21 23:28:32 +00:00
|
|
|
|
2020-11-16 16:03:24 +00:00
|
|
|
delete ARM9;
|
|
|
|
delete ARM7;
|
|
|
|
|
2017-02-07 21:23:46 +00:00
|
|
|
for (int i = 0; i < 8; i++)
|
|
|
|
delete DMAs[i];
|
|
|
|
|
|
|
|
NDSCart::DeInit();
|
2019-12-08 20:30:56 +00:00
|
|
|
GBACart::DeInit();
|
2017-02-07 21:23:46 +00:00
|
|
|
GPU::DeInit();
|
2017-04-06 17:44:34 +00:00
|
|
|
SPU::DeInit();
|
2017-02-07 21:23:46 +00:00
|
|
|
SPI::DeInit();
|
|
|
|
RTC::DeInit();
|
2017-05-11 17:57:49 +00:00
|
|
|
Wifi::DeInit();
|
2020-02-14 18:26:52 +00:00
|
|
|
|
2019-06-16 15:01:49 +00:00
|
|
|
DSi::DeInit();
|
2020-05-30 01:12:42 +00:00
|
|
|
|
2020-02-14 18:26:52 +00:00
|
|
|
AREngine::DeInit();
|
2016-05-16 15:48:40 +00:00
|
|
|
}
|
|
|
|
|
2016-12-06 16:32:51 +00:00
|
|
|
|
2021-08-31 00:28:34 +00:00
|
|
|
void SetARM9RegionTimings(u32 addrstart, u32 addrend, u32 region, int buswidth, int nonseq, int seq)
|
2018-12-04 16:54:10 +00:00
|
|
|
{
|
2021-08-31 00:28:34 +00:00
|
|
|
addrstart >>= 2;
|
|
|
|
addrend >>= 2;
|
2018-12-08 21:33:41 +00:00
|
|
|
|
2021-08-31 00:28:34 +00:00
|
|
|
int N16, S16, N32, S32, cpuN;
|
2018-12-08 21:33:41 +00:00
|
|
|
N16 = nonseq;
|
|
|
|
S16 = seq;
|
|
|
|
if (buswidth == 16)
|
2018-12-04 16:54:10 +00:00
|
|
|
{
|
2018-12-08 21:33:41 +00:00
|
|
|
N32 = N16 + S16;
|
|
|
|
S32 = S16 + S16;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
N32 = N16;
|
|
|
|
S32 = S16;
|
|
|
|
}
|
2018-12-04 16:54:10 +00:00
|
|
|
|
2021-08-31 00:28:34 +00:00
|
|
|
// nonseq accesses on the CPU get a 3-cycle penalty for all regions except main RAM
|
|
|
|
cpuN = (region == Mem9_MainRAM) ? 0 : 3;
|
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
for (u32 i = addrstart; i < addrend; i++)
|
|
|
|
{
|
2021-08-31 00:28:34 +00:00
|
|
|
// CPU timings
|
|
|
|
ARM9MemTimings[i][0] = N16 + cpuN;
|
2018-12-08 21:33:41 +00:00
|
|
|
ARM9MemTimings[i][1] = S16;
|
2021-08-31 00:28:34 +00:00
|
|
|
ARM9MemTimings[i][2] = N32 + cpuN;
|
2018-12-08 21:33:41 +00:00
|
|
|
ARM9MemTimings[i][3] = S32;
|
2021-08-31 00:28:34 +00:00
|
|
|
|
|
|
|
// DMA timings
|
|
|
|
ARM9MemTimings[i][4] = N16;
|
|
|
|
ARM9MemTimings[i][5] = S16;
|
|
|
|
ARM9MemTimings[i][6] = N32;
|
|
|
|
ARM9MemTimings[i][7] = S32;
|
|
|
|
|
|
|
|
ARM9Regions[i] = region;
|
2018-12-08 21:33:41 +00:00
|
|
|
}
|
2018-12-09 00:17:05 +00:00
|
|
|
|
2021-08-31 00:28:34 +00:00
|
|
|
ARM9->UpdateRegionTimings(addrstart<<2, addrend<<2);
|
2018-12-08 21:33:41 +00:00
|
|
|
}
|
2018-12-07 13:20:38 +00:00
|
|
|
|
2021-08-31 00:28:34 +00:00
|
|
|
void SetARM7RegionTimings(u32 addrstart, u32 addrend, u32 region, int buswidth, int nonseq, int seq)
|
2018-12-08 21:33:41 +00:00
|
|
|
{
|
2021-08-31 00:28:34 +00:00
|
|
|
addrstart >>= 3;
|
|
|
|
addrend >>= 3;
|
2018-12-04 16:54:10 +00:00
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
int N16, S16, N32, S32;
|
|
|
|
N16 = nonseq;
|
|
|
|
S16 = seq;
|
|
|
|
if (buswidth == 16)
|
|
|
|
{
|
|
|
|
N32 = N16 + S16;
|
|
|
|
S32 = S16 + S16;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
N32 = N16;
|
|
|
|
S32 = S16;
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
for (u32 i = addrstart; i < addrend; i++)
|
2018-12-04 16:54:10 +00:00
|
|
|
{
|
2021-08-31 00:28:34 +00:00
|
|
|
// CPU and DMA timings are the same
|
2018-12-08 21:33:41 +00:00
|
|
|
ARM7MemTimings[i][0] = N16;
|
|
|
|
ARM7MemTimings[i][1] = S16;
|
|
|
|
ARM7MemTimings[i][2] = N32;
|
|
|
|
ARM7MemTimings[i][3] = S32;
|
2021-08-31 00:28:34 +00:00
|
|
|
|
|
|
|
ARM7Regions[i] = region;
|
2018-12-08 21:33:41 +00:00
|
|
|
}
|
|
|
|
}
|
2018-12-04 16:54:10 +00:00
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
void InitTimings()
|
|
|
|
{
|
|
|
|
// TODO, eventually:
|
|
|
|
// VRAM is initially unmapped. The timings should be those of void regions.
|
|
|
|
// Similarly for any unmapped VRAM area.
|
|
|
|
// Need to check whether supporting these timing characteristics would impact performance
|
|
|
|
// (especially wrt VRAM mirroring and overlapping and whatnot).
|
2021-08-31 00:28:34 +00:00
|
|
|
// Also, each VRAM bank is its own memory region. This would matter when DMAing from a VRAM
|
|
|
|
// bank to another (if this is a thing) for example.
|
2018-12-04 16:54:10 +00:00
|
|
|
|
2021-08-31 00:28:34 +00:00
|
|
|
// TODO: check in detail how WRAM works, although it seems to be one region.
|
2018-12-08 21:33:41 +00:00
|
|
|
|
2020-06-01 18:36:30 +00:00
|
|
|
// TODO: DSi-specific timings!!
|
|
|
|
|
2021-08-31 00:28:34 +00:00
|
|
|
SetARM9RegionTimings(0x00000, 0x100000, 0, 32, 1, 1); // void
|
2018-12-08 21:33:41 +00:00
|
|
|
|
2021-08-31 00:28:34 +00:00
|
|
|
SetARM9RegionTimings(0xFFFF0, 0x100000, Mem9_BIOS, 32, 1, 1); // BIOS
|
|
|
|
SetARM9RegionTimings(0x02000, 0x03000, Mem9_MainRAM, 16, 8, 1); // main RAM
|
|
|
|
SetARM9RegionTimings(0x03000, 0x04000, Mem9_WRAM, 32, 1, 1); // ARM9/shared WRAM
|
|
|
|
SetARM9RegionTimings(0x04000, 0x05000, Mem9_IO, 32, 1, 1); // IO
|
|
|
|
SetARM9RegionTimings(0x05000, 0x06000, Mem9_Pal, 16, 1, 1); // palette
|
|
|
|
SetARM9RegionTimings(0x06000, 0x07000, Mem9_VRAM, 16, 1, 1); // VRAM
|
|
|
|
SetARM9RegionTimings(0x07000, 0x08000, Mem9_OAM, 32, 1, 1); // OAM
|
2018-12-08 21:33:41 +00:00
|
|
|
|
|
|
|
// ARM7
|
|
|
|
|
2021-08-31 00:28:34 +00:00
|
|
|
SetARM7RegionTimings(0x00000, 0x100000, 0, 32, 1, 1); // void
|
2018-12-08 21:33:41 +00:00
|
|
|
|
2021-08-31 00:28:34 +00:00
|
|
|
SetARM7RegionTimings(0x00000, 0x00010, Mem7_BIOS, 32, 1, 1); // BIOS
|
|
|
|
SetARM7RegionTimings(0x02000, 0x03000, Mem7_MainRAM, 16, 8, 1); // main RAM
|
|
|
|
SetARM7RegionTimings(0x03000, 0x04000, Mem7_WRAM, 32, 1, 1); // ARM7/shared WRAM
|
|
|
|
SetARM7RegionTimings(0x04000, 0x04800, Mem7_IO, 32, 1, 1); // IO
|
|
|
|
SetARM7RegionTimings(0x06000, 0x07000, Mem7_VRAM, 16, 1, 1); // ARM7 VRAM
|
2018-12-04 16:54:10 +00:00
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
// handled later: GBA slot, wifi
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
|
|
|
|
2022-01-07 13:00:43 +00:00
|
|
|
bool NeedsDirectBoot()
|
|
|
|
{
|
|
|
|
if (ConsoleType == 1)
|
|
|
|
{
|
|
|
|
// for now, DSi mode requires original BIOS/NAND
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// internal BIOS does not support direct boot
|
|
|
|
if (!Platform::GetConfigBool(Platform::ExternalBIOSEnable))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// DSi/3DS firmwares aren't bootable
|
|
|
|
if (SPI_Firmware::GetFirmwareLength() == 0x20000)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetupDirectBoot(std::string romname)
|
2017-02-01 20:35:00 +00:00
|
|
|
{
|
2020-06-01 18:36:30 +00:00
|
|
|
if (ConsoleType == 1)
|
|
|
|
{
|
2021-07-23 10:21:54 +00:00
|
|
|
DSi::SetupDirectBoot();
|
2020-06-01 18:36:30 +00:00
|
|
|
}
|
2021-08-30 18:26:49 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
MapSharedWRAM(3);
|
2020-06-01 18:36:30 +00:00
|
|
|
|
2021-08-30 18:26:49 +00:00
|
|
|
u32 arm9start = 0;
|
2016-12-06 16:32:51 +00:00
|
|
|
|
2021-08-30 18:26:49 +00:00
|
|
|
// load the ARM9 secure area
|
|
|
|
if (NDSCart::Header.ARM9ROMOffset >= 0x4000 && NDSCart::Header.ARM9ROMOffset < 0x8000)
|
|
|
|
{
|
|
|
|
u8 securearea[0x800];
|
|
|
|
NDSCart::DecryptSecureArea(securearea);
|
2016-12-06 16:32:51 +00:00
|
|
|
|
2021-08-30 18:26:49 +00:00
|
|
|
for (u32 i = 0; i < 0x800; i+=4)
|
|
|
|
{
|
|
|
|
ARM9Write32(NDSCart::Header.ARM9RAMAddress+i, *(u32*)&securearea[i]);
|
|
|
|
arm9start += 4;
|
|
|
|
}
|
|
|
|
}
|
2017-01-31 02:54:51 +00:00
|
|
|
|
2021-08-30 18:26:49 +00:00
|
|
|
// CHECKME: firmware seems to load this in 0x200 byte chunks
|
2020-03-30 09:04:50 +00:00
|
|
|
|
2021-08-30 18:26:49 +00:00
|
|
|
for (u32 i = arm9start; i < NDSCart::Header.ARM9Size; i+=4)
|
|
|
|
{
|
|
|
|
u32 tmp = *(u32*)&NDSCart::CartROM[NDSCart::Header.ARM9ROMOffset+i];
|
|
|
|
ARM9Write32(NDSCart::Header.ARM9RAMAddress+i, tmp);
|
|
|
|
}
|
2020-03-30 09:04:50 +00:00
|
|
|
|
2021-08-30 18:26:49 +00:00
|
|
|
for (u32 i = 0; i < NDSCart::Header.ARM7Size; i+=4)
|
2020-03-30 09:04:50 +00:00
|
|
|
{
|
2021-08-30 18:26:49 +00:00
|
|
|
u32 tmp = *(u32*)&NDSCart::CartROM[NDSCart::Header.ARM7ROMOffset+i];
|
|
|
|
ARM7Write32(NDSCart::Header.ARM7RAMAddress+i, tmp);
|
2020-03-30 09:04:50 +00:00
|
|
|
}
|
|
|
|
|
2021-08-30 18:26:49 +00:00
|
|
|
for (u32 i = 0; i < 0x170; i+=4)
|
|
|
|
{
|
|
|
|
u32 tmp = *(u32*)&NDSCart::CartROM[i];
|
|
|
|
ARM9Write32(0x027FFE00+i, tmp);
|
|
|
|
}
|
2020-03-30 09:04:50 +00:00
|
|
|
|
2021-08-30 18:26:49 +00:00
|
|
|
ARM9Write32(0x027FF800, NDSCart::CartID);
|
|
|
|
ARM9Write32(0x027FF804, NDSCart::CartID);
|
|
|
|
ARM9Write16(0x027FF808, NDSCart::Header.HeaderCRC16);
|
|
|
|
ARM9Write16(0x027FF80A, NDSCart::Header.SecureAreaCRC16);
|
2016-12-06 16:32:51 +00:00
|
|
|
|
2021-08-30 18:26:49 +00:00
|
|
|
ARM9Write16(0x027FF850, 0x5835);
|
2016-12-06 16:32:51 +00:00
|
|
|
|
2021-08-30 18:26:49 +00:00
|
|
|
ARM9Write32(0x027FFC00, NDSCart::CartID);
|
|
|
|
ARM9Write32(0x027FFC04, NDSCart::CartID);
|
|
|
|
ARM9Write16(0x027FFC08, NDSCart::Header.HeaderCRC16);
|
|
|
|
ARM9Write16(0x027FFC0A, NDSCart::Header.SecureAreaCRC16);
|
2017-01-31 02:54:51 +00:00
|
|
|
|
2021-08-30 18:26:49 +00:00
|
|
|
ARM9Write16(0x027FFC10, 0x5835);
|
|
|
|
ARM9Write16(0x027FFC30, 0xFFFF);
|
|
|
|
ARM9Write16(0x027FFC40, 0x0001);
|
2017-02-05 15:50:20 +00:00
|
|
|
|
2021-08-30 18:26:49 +00:00
|
|
|
ARM7BIOSProt = 0x1204;
|
2017-02-05 15:50:20 +00:00
|
|
|
|
2021-08-30 18:26:49 +00:00
|
|
|
SPI_Firmware::SetupDirectBoot(false);
|
2017-01-31 02:54:51 +00:00
|
|
|
|
2021-10-28 19:15:12 +00:00
|
|
|
ARM9->CP15Write(0x100, 0x00012078);
|
|
|
|
ARM9->CP15Write(0x200, 0x00000042);
|
|
|
|
ARM9->CP15Write(0x201, 0x00000042);
|
|
|
|
ARM9->CP15Write(0x300, 0x00000002);
|
|
|
|
ARM9->CP15Write(0x502, 0x15111011);
|
|
|
|
ARM9->CP15Write(0x503, 0x05100011);
|
|
|
|
ARM9->CP15Write(0x600, 0x04000033);
|
|
|
|
ARM9->CP15Write(0x601, 0x04000033);
|
|
|
|
ARM9->CP15Write(0x610, 0x0200002B);
|
|
|
|
ARM9->CP15Write(0x611, 0x0200002B);
|
|
|
|
ARM9->CP15Write(0x620, 0x00000000);
|
|
|
|
ARM9->CP15Write(0x621, 0x00000000);
|
|
|
|
ARM9->CP15Write(0x630, 0x08000035);
|
|
|
|
ARM9->CP15Write(0x631, 0x08000035);
|
|
|
|
ARM9->CP15Write(0x640, 0x0300001B);
|
|
|
|
ARM9->CP15Write(0x641, 0x0300001B);
|
|
|
|
ARM9->CP15Write(0x650, 0x00000000);
|
|
|
|
ARM9->CP15Write(0x651, 0x00000000);
|
|
|
|
ARM9->CP15Write(0x660, 0xFFFF001D);
|
|
|
|
ARM9->CP15Write(0x661, 0xFFFF001D);
|
|
|
|
ARM9->CP15Write(0x670, 0x027FF017);
|
|
|
|
ARM9->CP15Write(0x671, 0x027FF017);
|
|
|
|
ARM9->CP15Write(0x910, 0x0300000A);
|
|
|
|
ARM9->CP15Write(0x911, 0x00000020);
|
|
|
|
}
|
2016-12-23 20:22:22 +00:00
|
|
|
|
2022-01-07 13:00:43 +00:00
|
|
|
NDSCart::SetupDirectBoot(romname);
|
|
|
|
|
2021-08-30 18:26:49 +00:00
|
|
|
ARM9->R[12] = NDSCart::Header.ARM9EntryAddress;
|
2017-03-20 23:53:04 +00:00
|
|
|
ARM9->R[13] = 0x03002F7C;
|
2021-08-30 18:26:49 +00:00
|
|
|
ARM9->R[14] = NDSCart::Header.ARM9EntryAddress;
|
2017-03-20 23:53:04 +00:00
|
|
|
ARM9->R_IRQ[0] = 0x03003F80;
|
|
|
|
ARM9->R_SVC[0] = 0x03003FC0;
|
|
|
|
|
2021-08-30 18:26:49 +00:00
|
|
|
ARM7->R[12] = NDSCart::Header.ARM7EntryAddress;
|
2017-03-20 23:53:04 +00:00
|
|
|
ARM7->R[13] = 0x0380FD80;
|
2021-08-30 18:26:49 +00:00
|
|
|
ARM7->R[14] = NDSCart::Header.ARM7EntryAddress;
|
2017-03-20 23:53:04 +00:00
|
|
|
ARM7->R_IRQ[0] = 0x0380FF80;
|
|
|
|
ARM7->R_SVC[0] = 0x0380FFC0;
|
|
|
|
|
2021-08-30 18:26:49 +00:00
|
|
|
ARM9->JumpTo(NDSCart::Header.ARM9EntryAddress);
|
|
|
|
ARM7->JumpTo(NDSCart::Header.ARM7EntryAddress);
|
2017-02-01 20:57:25 +00:00
|
|
|
|
2017-04-26 14:17:03 +00:00
|
|
|
PostFlag9 = 0x01;
|
|
|
|
PostFlag7 = 0x01;
|
|
|
|
|
2017-02-01 20:57:25 +00:00
|
|
|
PowerControl9 = 0x820F;
|
2018-12-18 16:04:42 +00:00
|
|
|
GPU::SetPowerCnt(PowerControl9);
|
2017-02-05 16:15:17 +00:00
|
|
|
|
2017-06-04 23:58:14 +00:00
|
|
|
// checkme
|
|
|
|
RCnt = 0x8000;
|
|
|
|
|
2018-04-26 22:20:18 +00:00
|
|
|
NDSCart::SPICnt = 0x8000;
|
|
|
|
|
2017-04-07 15:37:49 +00:00
|
|
|
SPU::SetBias(0x200);
|
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
SetWifiWaitCnt(0x0030);
|
2016-12-06 16:32:51 +00:00
|
|
|
}
|
|
|
|
|
2016-05-16 15:48:40 +00:00
|
|
|
void Reset()
|
|
|
|
{
|
|
|
|
FILE* f;
|
2017-01-18 00:33:06 +00:00
|
|
|
u32 i;
|
2016-05-16 15:48:40 +00:00
|
|
|
|
2021-11-17 22:23:22 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2021-11-17 17:15:50 +00:00
|
|
|
EnableJIT = Platform::GetConfigBool(Platform::JIT_Enable);
|
2021-11-17 22:23:22 +00:00
|
|
|
#endif
|
2021-11-17 17:15:50 +00:00
|
|
|
|
2020-02-24 17:31:44 +00:00
|
|
|
RunningGame = false;
|
2018-12-12 01:48:37 +00:00
|
|
|
LastSysClockCycles = 0;
|
|
|
|
|
2019-08-05 17:52:03 +00:00
|
|
|
memset(ARM9BIOS, 0, 0x1000);
|
|
|
|
memset(ARM7BIOS, 0, 0x4000);
|
2019-06-13 12:41:54 +00:00
|
|
|
|
2019-08-05 17:52:03 +00:00
|
|
|
// DS BIOSes are always loaded, even in DSi mode
|
|
|
|
// we need them for DS-compatible mode
|
|
|
|
|
2021-11-17 19:42:11 +00:00
|
|
|
if (Platform::GetConfigBool(Platform::ExternalBIOSEnable))
|
2017-05-09 02:52:17 +00:00
|
|
|
{
|
2021-11-17 19:42:11 +00:00
|
|
|
f = Platform::OpenLocalFile(Platform::GetConfigString(Platform::BIOS9Path), "rb");
|
2021-10-02 10:06:22 +00:00
|
|
|
if (!f)
|
|
|
|
{
|
|
|
|
printf("ARM9 BIOS not found\n");
|
2017-05-09 02:52:17 +00:00
|
|
|
|
2021-10-02 10:06:22 +00:00
|
|
|
for (i = 0; i < 16; i++)
|
|
|
|
((u32*)ARM9BIOS)[i] = 0xE7FFDEFF;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fseek(f, 0, SEEK_SET);
|
|
|
|
fread(ARM9BIOS, 0x1000, 1, f);
|
2016-05-16 15:48:40 +00:00
|
|
|
|
2021-10-02 10:06:22 +00:00
|
|
|
printf("ARM9 BIOS loaded\n");
|
|
|
|
fclose(f);
|
|
|
|
}
|
2016-11-03 00:38:58 +00:00
|
|
|
|
2021-11-17 19:42:11 +00:00
|
|
|
f = Platform::OpenLocalFile(Platform::GetConfigString(Platform::BIOS7Path), "rb");
|
2021-10-02 10:06:22 +00:00
|
|
|
if (!f)
|
|
|
|
{
|
|
|
|
printf("ARM7 BIOS not found\n");
|
2017-05-09 02:52:17 +00:00
|
|
|
|
2021-10-02 10:06:22 +00:00
|
|
|
for (i = 0; i < 16; i++)
|
|
|
|
((u32*)ARM7BIOS)[i] = 0xE7FFDEFF;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fseek(f, 0, SEEK_SET);
|
|
|
|
fread(ARM7BIOS, 0x4000, 1, f);
|
|
|
|
|
|
|
|
printf("ARM7 BIOS loaded\n");
|
|
|
|
fclose(f);
|
|
|
|
}
|
2017-05-09 02:52:17 +00:00
|
|
|
}
|
2016-11-03 00:38:58 +00:00
|
|
|
else
|
|
|
|
{
|
2021-10-02 10:06:22 +00:00
|
|
|
memcpy(ARM9BIOS, bios_arm9_bin, bios_arm9_bin_len);
|
|
|
|
memcpy(ARM7BIOS, bios_arm7_bin, bios_arm7_bin_len);
|
2016-11-03 00:38:58 +00:00
|
|
|
}
|
2020-07-23 10:59:19 +00:00
|
|
|
|
2020-06-14 19:04:25 +00:00
|
|
|
#ifdef JIT_ENABLED
|
|
|
|
ARMJIT::Reset();
|
|
|
|
#endif
|
2016-11-24 17:31:49 +00:00
|
|
|
|
2020-06-01 18:36:30 +00:00
|
|
|
if (ConsoleType == 1)
|
2019-08-05 17:52:03 +00:00
|
|
|
{
|
|
|
|
DSi::LoadBIOS();
|
2019-06-15 11:09:11 +00:00
|
|
|
|
2019-08-05 17:52:03 +00:00
|
|
|
ARM9ClockShift = 2;
|
|
|
|
MainRAMMask = 0xFFFFFF;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-06-15 11:09:11 +00:00
|
|
|
ARM9ClockShift = 1;
|
2019-08-05 17:52:03 +00:00
|
|
|
MainRAMMask = 0x3FFFFF;
|
2017-05-09 02:52:17 +00:00
|
|
|
}
|
2019-07-21 21:56:24 +00:00
|
|
|
// has to be called before InitTimings
|
|
|
|
// otherwise some PU settings are completely
|
|
|
|
// unitialised on the first run
|
|
|
|
ARM9->CP15Reset();
|
|
|
|
|
2019-01-05 04:28:58 +00:00
|
|
|
ARM9Timestamp = 0; ARM9Target = 0;
|
|
|
|
ARM7Timestamp = 0; ARM7Target = 0;
|
|
|
|
SysTimestamp = 0;
|
2018-12-09 00:17:05 +00:00
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
InitTimings();
|
|
|
|
|
2020-06-14 19:04:25 +00:00
|
|
|
memset(MainRAM, 0, MainRAMMask + 1);
|
2016-12-03 17:29:19 +00:00
|
|
|
memset(SharedWRAM, 0, 0x8000);
|
2016-12-03 12:42:27 +00:00
|
|
|
memset(ARM7WRAM, 0, 0x10000);
|
2016-12-03 15:13:04 +00:00
|
|
|
|
2016-12-06 16:32:51 +00:00
|
|
|
MapSharedWRAM(0);
|
2016-12-03 17:29:19 +00:00
|
|
|
|
2019-06-15 11:09:11 +00:00
|
|
|
ExMemCnt[0] = 0x4000;
|
|
|
|
ExMemCnt[1] = 0x4000;
|
2017-01-22 19:34:59 +00:00
|
|
|
memset(ROMSeed0, 0, 2*8);
|
|
|
|
memset(ROMSeed1, 0, 2*8);
|
2018-12-08 21:33:41 +00:00
|
|
|
SetGBASlotTimings();
|
2017-01-22 19:34:59 +00:00
|
|
|
|
2016-12-04 02:20:50 +00:00
|
|
|
IME[0] = 0;
|
2017-11-09 15:02:37 +00:00
|
|
|
IE[0] = 0;
|
|
|
|
IF[0] = 0;
|
2016-12-04 02:20:50 +00:00
|
|
|
IME[1] = 0;
|
2017-11-09 15:02:37 +00:00
|
|
|
IE[1] = 0;
|
|
|
|
IF[1] = 0;
|
2019-06-16 13:05:18 +00:00
|
|
|
IE2 = 0;
|
|
|
|
IF2 = 0;
|
2016-12-04 02:20:50 +00:00
|
|
|
|
2017-01-18 01:20:45 +00:00
|
|
|
PostFlag9 = 0x00;
|
|
|
|
PostFlag7 = 0x00;
|
2016-12-06 16:32:51 +00:00
|
|
|
PowerControl9 = 0x0001;
|
|
|
|
PowerControl7 = 0x0001;
|
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
WifiWaitCnt = 0xFFFF; // temp
|
|
|
|
SetWifiWaitCnt(0);
|
|
|
|
|
2017-02-05 16:15:17 +00:00
|
|
|
ARM7BIOSProt = 0;
|
|
|
|
|
2016-12-03 15:13:04 +00:00
|
|
|
IPCSync9 = 0;
|
|
|
|
IPCSync7 = 0;
|
2017-01-17 00:58:25 +00:00
|
|
|
IPCFIFOCnt9 = 0;
|
|
|
|
IPCFIFOCnt7 = 0;
|
2020-12-30 22:37:46 +00:00
|
|
|
IPCFIFO9.Clear();
|
|
|
|
IPCFIFO7.Clear();
|
2016-12-03 12:42:27 +00:00
|
|
|
|
2017-01-18 01:20:45 +00:00
|
|
|
DivCnt = 0;
|
2017-01-31 20:53:45 +00:00
|
|
|
SqrtCnt = 0;
|
2017-01-18 01:20:45 +00:00
|
|
|
|
2016-11-24 17:31:49 +00:00
|
|
|
ARM9->Reset();
|
|
|
|
ARM7->Reset();
|
|
|
|
|
2017-02-17 04:33:37 +00:00
|
|
|
CPUStop = 0;
|
|
|
|
|
2016-12-05 16:08:24 +00:00
|
|
|
memset(Timers, 0, 8*sizeof(Timer));
|
2017-04-24 23:14:26 +00:00
|
|
|
TimerCheckMask[0] = 0;
|
|
|
|
TimerCheckMask[1] = 0;
|
2019-01-05 04:28:58 +00:00
|
|
|
TimerTimestamp[0] = 0;
|
|
|
|
TimerTimestamp[1] = 0;
|
2016-12-05 16:08:24 +00:00
|
|
|
|
2017-01-18 00:33:06 +00:00
|
|
|
for (i = 0; i < 8; i++) DMAs[i]->Reset();
|
|
|
|
memset(DMA9Fill, 0, 4*4);
|
|
|
|
|
2017-01-31 02:54:51 +00:00
|
|
|
memset(SchedList, 0, sizeof(SchedList));
|
|
|
|
SchedListMask = 0;
|
2016-12-05 16:08:24 +00:00
|
|
|
|
2016-12-23 20:22:22 +00:00
|
|
|
KeyInput = 0x007F03FF;
|
2017-06-04 20:34:31 +00:00
|
|
|
KeyCnt = 0;
|
|
|
|
RCnt = 0;
|
2016-12-23 20:22:22 +00:00
|
|
|
|
2017-04-06 17:44:34 +00:00
|
|
|
NDSCart::Reset();
|
2019-12-08 20:30:56 +00:00
|
|
|
GBACart::Reset();
|
2017-04-06 17:44:34 +00:00
|
|
|
GPU::Reset();
|
|
|
|
SPU::Reset();
|
|
|
|
SPI::Reset();
|
|
|
|
RTC::Reset();
|
|
|
|
Wifi::Reset();
|
2020-02-14 18:26:52 +00:00
|
|
|
|
2021-11-18 00:17:51 +00:00
|
|
|
// TODO: move the SOUNDBIAS/degrade logic to SPU?
|
|
|
|
|
2021-08-16 21:47:54 +00:00
|
|
|
// The SOUNDBIAS register does nothing on DSi
|
|
|
|
SPU::SetApplyBias(ConsoleType == 0);
|
|
|
|
|
|
|
|
bool degradeAudio = true;
|
|
|
|
|
2020-06-01 18:36:30 +00:00
|
|
|
if (ConsoleType == 1)
|
|
|
|
{
|
|
|
|
DSi::Reset();
|
|
|
|
KeyInput &= ~(1 << (16+6));
|
2021-08-16 21:47:54 +00:00
|
|
|
degradeAudio = false;
|
2020-06-01 18:36:30 +00:00
|
|
|
}
|
2020-05-30 01:12:42 +00:00
|
|
|
|
2021-11-18 00:17:51 +00:00
|
|
|
int bitrate = Platform::GetConfigInt(Platform::AudioBitrate);
|
|
|
|
if (bitrate == 1) // Always 10-bit
|
2021-08-16 21:47:54 +00:00
|
|
|
degradeAudio = true;
|
2021-11-18 00:17:51 +00:00
|
|
|
else if (bitrate == 2) // Always 16-bit
|
2021-08-16 21:47:54 +00:00
|
|
|
degradeAudio = false;
|
|
|
|
|
|
|
|
SPU::SetDegrade10Bit(degradeAudio);
|
|
|
|
|
2020-02-14 18:26:52 +00:00
|
|
|
AREngine::Reset();
|
2017-03-19 18:07:39 +00:00
|
|
|
}
|
|
|
|
|
2022-01-07 13:00:43 +00:00
|
|
|
void Start()
|
|
|
|
{
|
|
|
|
Running = true;
|
|
|
|
}
|
|
|
|
|
2017-09-21 01:59:12 +00:00
|
|
|
void Stop()
|
|
|
|
{
|
|
|
|
printf("Stopping: shutdown\n");
|
2017-10-01 01:19:39 +00:00
|
|
|
Running = false;
|
2017-09-21 01:59:12 +00:00
|
|
|
Platform::StopEmu();
|
2017-09-21 02:08:03 +00:00
|
|
|
GPU::Stop();
|
2017-09-21 01:59:12 +00:00
|
|
|
SPU::Stop();
|
2022-10-02 21:29:24 +00:00
|
|
|
|
|
|
|
if (ConsoleType == 1)
|
|
|
|
DSi::Stop();
|
2017-09-21 01:59:12 +00:00
|
|
|
}
|
|
|
|
|
2018-10-17 23:38:33 +00:00
|
|
|
bool DoSavestate_Scheduler(Savestate* file)
|
|
|
|
{
|
|
|
|
// this is a bit of a hack
|
|
|
|
// but uh, your local coder realized that the scheduler list contains function pointers
|
|
|
|
// and that storing those as-is is not a very good idea
|
|
|
|
// unless you want it to crash and burn
|
|
|
|
|
|
|
|
// this is the solution your local coder came up with.
|
|
|
|
// it's gross but I think it's the best solution for this problem.
|
|
|
|
// just remember to add here if you add more event callbacks, kay?
|
|
|
|
// atleast until we come up with something more elegant.
|
|
|
|
|
|
|
|
void (*eventfuncs[])(u32) =
|
|
|
|
{
|
|
|
|
GPU::StartScanline, GPU::StartHBlank, GPU::FinishFrame,
|
|
|
|
SPU::Mix,
|
|
|
|
Wifi::USTimer,
|
|
|
|
|
|
|
|
GPU::DisplayFIFO,
|
|
|
|
NDSCart::ROMPrepareData, NDSCart::ROMEndTransfer,
|
|
|
|
NDSCart::SPITransferDone,
|
|
|
|
SPI::TransferDone,
|
|
|
|
DivDone,
|
|
|
|
SqrtDone,
|
|
|
|
|
2022-01-07 13:00:43 +00:00
|
|
|
DSi_SDHost::FinishRX,
|
|
|
|
DSi_SDHost::FinishTX,
|
|
|
|
DSi_NWifi::MSTimer,
|
2022-10-02 14:47:57 +00:00
|
|
|
DSi_CamModule::IRQ,
|
|
|
|
DSi_CamModule::TransferScanline,
|
2022-01-07 13:00:43 +00:00
|
|
|
DSi_DSP::DSPCatchUpU32,
|
|
|
|
|
|
|
|
nullptr
|
2018-10-17 23:38:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
int len = Event_MAX;
|
|
|
|
if (file->Saving)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < len; i++)
|
|
|
|
{
|
|
|
|
SchedEvent* evt = &SchedList[i];
|
|
|
|
|
2022-01-07 13:00:43 +00:00
|
|
|
u32 funcid = 0xFFFFFFFF;
|
2018-10-18 01:09:03 +00:00
|
|
|
if (evt->Func)
|
2018-10-17 23:38:33 +00:00
|
|
|
{
|
2018-10-18 01:09:03 +00:00
|
|
|
for (int j = 0; eventfuncs[j]; j++)
|
2018-10-17 23:38:33 +00:00
|
|
|
{
|
2018-10-18 01:09:03 +00:00
|
|
|
if (evt->Func == eventfuncs[j])
|
|
|
|
{
|
|
|
|
funcid = j;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2021-05-03 12:36:21 +00:00
|
|
|
if (funcid == 0xFFFFFFFF)
|
2018-10-18 01:09:03 +00:00
|
|
|
{
|
2019-08-04 12:34:33 +00:00
|
|
|
printf("savestate: VERY BAD!!!!! FUNCTION POINTER FOR EVENT %d NOT IN HACKY LIST. CANNOT SAVE. SMACK ARISOTURA.\n", i);
|
2018-10-18 01:09:03 +00:00
|
|
|
return false;
|
2018-10-17 23:38:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
file->Var32(&funcid);
|
2019-01-05 04:28:58 +00:00
|
|
|
file->Var64(&evt->Timestamp);
|
2018-10-17 23:38:33 +00:00
|
|
|
file->Var32(&evt->Param);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (int i = 0; i < len; i++)
|
|
|
|
{
|
|
|
|
SchedEvent* evt = &SchedList[i];
|
|
|
|
|
|
|
|
u32 funcid;
|
|
|
|
file->Var32(&funcid);
|
|
|
|
|
2021-05-03 12:36:21 +00:00
|
|
|
if (funcid != 0xFFFFFFFF)
|
2018-10-17 23:38:33 +00:00
|
|
|
{
|
2018-10-18 01:09:03 +00:00
|
|
|
for (int j = 0; ; j++)
|
2018-10-17 23:38:33 +00:00
|
|
|
{
|
2018-10-18 01:09:03 +00:00
|
|
|
if (!eventfuncs[j])
|
|
|
|
{
|
|
|
|
printf("savestate: VERY BAD!!!!!! EVENT FUNCTION POINTER ID %d IS OUT OF RANGE. HAX?????\n", j);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (j == funcid) break;
|
2018-10-17 23:38:33 +00:00
|
|
|
}
|
|
|
|
|
2018-10-18 01:09:03 +00:00
|
|
|
evt->Func = eventfuncs[funcid];
|
|
|
|
}
|
|
|
|
else
|
2022-01-07 13:00:43 +00:00
|
|
|
evt->Func = nullptr;
|
2018-10-17 23:38:33 +00:00
|
|
|
|
2019-01-05 04:28:58 +00:00
|
|
|
file->Var64(&evt->Timestamp);
|
2018-10-17 23:38:33 +00:00
|
|
|
file->Var32(&evt->Param);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool DoSavestate(Savestate* file)
|
2018-09-15 00:47:34 +00:00
|
|
|
{
|
2018-09-15 01:29:36 +00:00
|
|
|
file->Section("NDSG");
|
|
|
|
|
2022-01-07 13:00:43 +00:00
|
|
|
if (file->Saving)
|
|
|
|
{
|
|
|
|
u32 console = ConsoleType;
|
|
|
|
file->Var32(&console);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
u32 console;
|
|
|
|
file->Var32(&console);
|
|
|
|
if (console != ConsoleType)
|
|
|
|
return false;
|
|
|
|
}
|
2020-06-01 18:36:30 +00:00
|
|
|
|
2022-01-07 13:00:43 +00:00
|
|
|
file->VarArray(MainRAM, MainRAMMaxSize);
|
|
|
|
file->VarArray(SharedWRAM, SharedWRAMSize);
|
2020-06-14 19:04:25 +00:00
|
|
|
file->VarArray(ARM7WRAM, ARM7WRAMSize);
|
2018-09-15 01:29:36 +00:00
|
|
|
|
2022-01-07 13:00:43 +00:00
|
|
|
//file->VarArray(ARM9BIOS, 0x1000);
|
|
|
|
//file->VarArray(ARM7BIOS, 0x4000);
|
|
|
|
|
2018-09-15 01:29:36 +00:00
|
|
|
file->VarArray(ExMemCnt, 2*sizeof(u16));
|
|
|
|
file->VarArray(ROMSeed0, 2*8);
|
|
|
|
file->VarArray(ROMSeed1, 2*8);
|
|
|
|
|
2018-12-11 20:50:28 +00:00
|
|
|
file->Var16(&WifiWaitCnt);
|
|
|
|
|
2018-09-15 01:29:36 +00:00
|
|
|
file->VarArray(IME, 2*sizeof(u32));
|
|
|
|
file->VarArray(IE, 2*sizeof(u32));
|
|
|
|
file->VarArray(IF, 2*sizeof(u32));
|
2022-01-07 13:00:43 +00:00
|
|
|
file->Var32(&IE2);
|
|
|
|
file->Var32(&IF2);
|
2018-09-15 01:29:36 +00:00
|
|
|
|
|
|
|
file->Var8(&PostFlag9);
|
|
|
|
file->Var8(&PostFlag7);
|
|
|
|
file->Var16(&PowerControl9);
|
|
|
|
file->Var16(&PowerControl7);
|
|
|
|
|
|
|
|
file->Var16(&ARM7BIOSProt);
|
|
|
|
|
|
|
|
file->Var16(&IPCSync9);
|
|
|
|
file->Var16(&IPCSync7);
|
|
|
|
file->Var16(&IPCFIFOCnt9);
|
|
|
|
file->Var16(&IPCFIFOCnt7);
|
2020-12-30 22:37:46 +00:00
|
|
|
IPCFIFO9.DoSavestate(file);
|
|
|
|
IPCFIFO7.DoSavestate(file);
|
2018-09-15 01:29:36 +00:00
|
|
|
|
|
|
|
file->Var16(&DivCnt);
|
|
|
|
file->Var16(&SqrtCnt);
|
|
|
|
|
|
|
|
file->Var32(&CPUStop);
|
|
|
|
|
2018-10-21 01:16:41 +00:00
|
|
|
for (int i = 0; i < 8; i++)
|
|
|
|
{
|
|
|
|
Timer* timer = &Timers[i];
|
|
|
|
|
|
|
|
file->Var16(&timer->Reload);
|
|
|
|
file->Var16(&timer->Cnt);
|
|
|
|
file->Var32(&timer->Counter);
|
|
|
|
file->Var32(&timer->CycleShift);
|
|
|
|
}
|
2018-09-15 01:29:36 +00:00
|
|
|
file->VarArray(TimerCheckMask, 2*sizeof(u8));
|
2019-01-05 04:28:58 +00:00
|
|
|
file->VarArray(TimerTimestamp, 2*sizeof(u64));
|
2018-09-15 01:29:36 +00:00
|
|
|
|
|
|
|
file->VarArray(DMA9Fill, 4*sizeof(u32));
|
|
|
|
|
2018-10-17 23:38:33 +00:00
|
|
|
if (!DoSavestate_Scheduler(file)) return false;
|
2018-09-15 01:41:09 +00:00
|
|
|
file->Var32(&SchedListMask);
|
2019-01-05 04:28:58 +00:00
|
|
|
file->Var64(&ARM9Timestamp);
|
|
|
|
file->Var64(&ARM9Target);
|
|
|
|
file->Var64(&ARM7Timestamp);
|
|
|
|
file->Var64(&ARM7Target);
|
|
|
|
file->Var64(&SysTimestamp);
|
|
|
|
file->Var64(&LastSysClockCycles);
|
|
|
|
file->Var64(&FrameStartTimestamp);
|
|
|
|
file->Var32(&NumFrames);
|
2022-01-07 13:00:43 +00:00
|
|
|
file->Var32(&NumLagFrames);
|
|
|
|
file->Bool32(&LagFrameFlag);
|
2018-09-15 01:41:09 +00:00
|
|
|
|
|
|
|
// TODO: save KeyInput????
|
|
|
|
file->Var16(&KeyCnt);
|
|
|
|
file->Var16(&RCnt);
|
|
|
|
|
2018-10-18 01:04:39 +00:00
|
|
|
file->Var8(&WRAMCnt);
|
2018-09-15 01:41:09 +00:00
|
|
|
|
2020-09-04 18:37:14 +00:00
|
|
|
file->Bool32(&RunningGame);
|
2020-02-24 17:31:44 +00:00
|
|
|
|
2018-10-18 01:04:39 +00:00
|
|
|
if (!file->Saving)
|
|
|
|
{
|
|
|
|
// 'dept of redundancy dept'
|
|
|
|
// but we do need to update the mappings
|
|
|
|
MapSharedWRAM(WRAMCnt);
|
2018-09-15 01:41:09 +00:00
|
|
|
|
2018-12-11 20:50:28 +00:00
|
|
|
InitTimings();
|
|
|
|
SetGBASlotTimings();
|
|
|
|
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
UpdateWifiTimings();
|
2018-12-11 20:50:28 +00:00
|
|
|
}
|
|
|
|
|
2020-02-24 17:31:44 +00:00
|
|
|
for (int i = 0; i < 8; i++)
|
|
|
|
DMAs[i]->DoSavestate(file);
|
|
|
|
|
2018-10-17 22:27:55 +00:00
|
|
|
ARM9->DoSavestate(file);
|
|
|
|
ARM7->DoSavestate(file);
|
2018-09-15 01:29:36 +00:00
|
|
|
|
2018-10-17 23:38:33 +00:00
|
|
|
NDSCart::DoSavestate(file);
|
2022-01-07 13:00:43 +00:00
|
|
|
if (ConsoleType == 0)
|
|
|
|
GBACart::DoSavestate(file);
|
2018-10-18 00:31:01 +00:00
|
|
|
GPU::DoSavestate(file);
|
2018-10-18 00:45:38 +00:00
|
|
|
SPU::DoSavestate(file);
|
2018-10-18 00:54:48 +00:00
|
|
|
SPI::DoSavestate(file);
|
2018-10-18 01:04:39 +00:00
|
|
|
RTC::DoSavestate(file);
|
2018-10-18 01:22:53 +00:00
|
|
|
Wifi::DoSavestate(file);
|
2018-10-18 00:31:01 +00:00
|
|
|
|
2022-01-07 13:00:43 +00:00
|
|
|
if (ConsoleType == 1)
|
|
|
|
DSi::DoSavestate(file);
|
|
|
|
|
2018-12-18 16:04:42 +00:00
|
|
|
if (!file->Saving)
|
|
|
|
{
|
|
|
|
GPU::SetPowerCnt(PowerControl9);
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
|
|
|
|
SPU::SetPowerCnt(PowerControl7 & 0x0001);
|
|
|
|
Wifi::SetPowerCnt(PowerControl7 & 0x0002);
|
2018-12-18 16:04:42 +00:00
|
|
|
}
|
|
|
|
|
2019-07-14 17:24:00 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2019-07-14 02:33:36 +00:00
|
|
|
if (!file->Saving)
|
|
|
|
{
|
2019-10-02 23:10:59 +00:00
|
|
|
ARMJIT::ResetBlockCache();
|
2020-07-04 16:58:00 +00:00
|
|
|
ARMJIT_Memory::Reset();
|
2019-07-14 02:33:36 +00:00
|
|
|
}
|
2019-07-14 17:24:00 +00:00
|
|
|
#endif
|
2019-07-14 02:33:36 +00:00
|
|
|
|
2018-10-18 00:31:01 +00:00
|
|
|
return true;
|
2018-09-15 00:47:34 +00:00
|
|
|
}
|
|
|
|
|
2020-06-01 18:36:30 +00:00
|
|
|
void SetConsoleType(int type)
|
|
|
|
{
|
|
|
|
ConsoleType = type;
|
|
|
|
}
|
|
|
|
|
2022-01-07 13:00:43 +00:00
|
|
|
bool LoadCart(const u8* romdata, u32 romlen, const u8* savedata, u32 savelen)
|
2021-01-22 10:22:32 +00:00
|
|
|
{
|
2022-01-07 13:00:43 +00:00
|
|
|
if (!NDSCart::LoadROM(romdata, romlen))
|
2021-01-22 10:22:32 +00:00
|
|
|
return false;
|
2022-01-07 13:00:43 +00:00
|
|
|
|
|
|
|
if (savedata && savelen)
|
|
|
|
NDSCart::LoadSave(savedata, savelen);
|
|
|
|
|
|
|
|
return true;
|
2021-01-22 10:22:32 +00:00
|
|
|
}
|
|
|
|
|
2022-01-07 13:00:43 +00:00
|
|
|
void LoadSave(const u8* savedata, u32 savelen)
|
2017-03-19 18:07:39 +00:00
|
|
|
{
|
2022-01-07 13:00:43 +00:00
|
|
|
if (savedata && savelen)
|
|
|
|
NDSCart::LoadSave(savedata, savelen);
|
2017-03-29 16:59:20 +00:00
|
|
|
}
|
|
|
|
|
2022-01-07 13:00:43 +00:00
|
|
|
void EjectCart()
|
2019-12-08 20:30:56 +00:00
|
|
|
{
|
2022-01-07 13:00:43 +00:00
|
|
|
NDSCart::EjectCart();
|
2019-12-08 20:30:56 +00:00
|
|
|
}
|
|
|
|
|
2022-01-07 13:00:43 +00:00
|
|
|
bool CartInserted()
|
2021-01-22 10:22:32 +00:00
|
|
|
{
|
2022-01-07 13:00:43 +00:00
|
|
|
return NDSCart::CartInserted;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LoadGBACart(const u8* romdata, u32 romlen, const u8* savedata, u32 savelen)
|
|
|
|
{
|
|
|
|
if (!GBACart::LoadROM(romdata, romlen))
|
2021-01-22 10:22:32 +00:00
|
|
|
return false;
|
2022-01-07 13:00:43 +00:00
|
|
|
|
|
|
|
if (savedata && savelen)
|
|
|
|
GBACart::LoadSave(savedata, savelen);
|
|
|
|
|
|
|
|
return true;
|
2021-01-22 10:22:32 +00:00
|
|
|
}
|
|
|
|
|
2022-01-07 13:00:43 +00:00
|
|
|
void LoadGBAAddon(int type)
|
2017-03-29 16:59:20 +00:00
|
|
|
{
|
2022-01-07 13:00:43 +00:00
|
|
|
GBACart::LoadAddon(type);
|
2016-11-24 17:31:49 +00:00
|
|
|
}
|
|
|
|
|
2022-01-07 13:00:43 +00:00
|
|
|
void EjectGBACart()
|
2018-10-23 22:24:36 +00:00
|
|
|
{
|
2022-01-07 13:00:43 +00:00
|
|
|
GBACart::EjectCart();
|
2018-10-23 22:24:36 +00:00
|
|
|
}
|
|
|
|
|
2022-01-07 13:00:43 +00:00
|
|
|
void LoadBIOS()
|
|
|
|
{
|
|
|
|
Reset();
|
|
|
|
}
|
2017-01-31 02:54:51 +00:00
|
|
|
|
2019-01-05 04:28:58 +00:00
|
|
|
|
|
|
|
u64 NextTarget()
|
2017-01-31 02:54:51 +00:00
|
|
|
{
|
2021-09-27 01:29:54 +00:00
|
|
|
u64 minEvent = UINT64_MAX;
|
2017-01-31 02:54:51 +00:00
|
|
|
|
2019-01-05 04:28:58 +00:00
|
|
|
u32 mask = SchedListMask;
|
2017-01-31 02:54:51 +00:00
|
|
|
for (int i = 0; i < Event_MAX; i++)
|
|
|
|
{
|
2019-01-05 04:28:58 +00:00
|
|
|
if (!mask) break;
|
|
|
|
if (mask & 0x1)
|
|
|
|
{
|
2021-09-27 01:29:54 +00:00
|
|
|
if (SchedList[i].Timestamp < minEvent)
|
|
|
|
minEvent = SchedList[i].Timestamp;
|
2019-01-05 04:28:58 +00:00
|
|
|
}
|
2017-01-31 02:54:51 +00:00
|
|
|
|
2019-01-05 04:28:58 +00:00
|
|
|
mask >>= 1;
|
2017-01-31 02:54:51 +00:00
|
|
|
}
|
2019-01-05 04:28:58 +00:00
|
|
|
|
2021-09-27 01:29:54 +00:00
|
|
|
u64 max = SysTimestamp + kMaxIterationCycles;
|
|
|
|
|
|
|
|
if (minEvent < max + kIterationCycleMargin)
|
|
|
|
return minEvent;
|
|
|
|
|
|
|
|
return max;
|
2017-01-31 02:54:51 +00:00
|
|
|
}
|
|
|
|
|
2019-01-05 04:28:58 +00:00
|
|
|
void RunSystem(u64 timestamp)
|
2017-01-31 02:54:51 +00:00
|
|
|
{
|
2019-01-05 04:28:58 +00:00
|
|
|
SysTimestamp = timestamp;
|
|
|
|
|
|
|
|
u32 mask = SchedListMask;
|
2017-01-31 02:54:51 +00:00
|
|
|
for (int i = 0; i < Event_MAX; i++)
|
|
|
|
{
|
2019-01-05 04:28:58 +00:00
|
|
|
if (!mask) break;
|
|
|
|
if (mask & 0x1)
|
2017-01-31 02:54:51 +00:00
|
|
|
{
|
2019-01-05 04:28:58 +00:00
|
|
|
if (SchedList[i].Timestamp <= SysTimestamp)
|
|
|
|
{
|
|
|
|
SchedListMask &= ~(1<<i);
|
|
|
|
SchedList[i].Func(SchedList[i].Param);
|
|
|
|
}
|
2017-01-31 02:54:51 +00:00
|
|
|
}
|
2019-01-05 04:28:58 +00:00
|
|
|
|
|
|
|
mask >>= 1;
|
2017-01-31 02:54:51 +00:00
|
|
|
}
|
|
|
|
}
|
2018-11-24 04:23:35 +00:00
|
|
|
|
2020-11-16 16:22:34 +00:00
|
|
|
template <bool EnableJIT, int ConsoleType>
|
2017-05-10 00:21:02 +00:00
|
|
|
u32 RunFrame()
|
2016-11-24 17:31:49 +00:00
|
|
|
{
|
2019-01-05 04:28:58 +00:00
|
|
|
FrameStartTimestamp = SysTimestamp;
|
2018-12-12 15:33:40 +00:00
|
|
|
|
2021-01-21 20:26:27 +00:00
|
|
|
LagFrameFlag = true;
|
|
|
|
bool runFrame = Running && !(CPUStop & 0x40000000);
|
|
|
|
if (runFrame)
|
2017-01-31 02:54:51 +00:00
|
|
|
{
|
2021-01-21 20:26:27 +00:00
|
|
|
GPU::StartFrame();
|
2018-11-23 21:21:41 +00:00
|
|
|
|
2021-01-21 20:26:27 +00:00
|
|
|
while (Running && GPU::TotalScanlines==0)
|
2017-02-17 04:33:37 +00:00
|
|
|
{
|
2021-01-21 20:26:27 +00:00
|
|
|
u64 target = NextTarget();
|
|
|
|
ARM9Target = target << ARM9ClockShift;
|
|
|
|
CurCPU = 0;
|
2018-12-11 02:08:46 +00:00
|
|
|
|
2021-01-21 20:26:27 +00:00
|
|
|
if (CPUStop & 0x80000000)
|
|
|
|
{
|
|
|
|
// GXFIFO stall
|
|
|
|
s32 cycles = GPU3D::CyclesToRunFor();
|
2018-12-11 14:56:34 +00:00
|
|
|
|
2021-01-21 20:26:27 +00:00
|
|
|
ARM9Timestamp = std::min(ARM9Target, ARM9Timestamp+(cycles<<ARM9ClockShift));
|
|
|
|
}
|
|
|
|
else if (CPUStop & 0x0FFF)
|
2019-01-05 04:28:58 +00:00
|
|
|
{
|
2021-01-21 20:26:27 +00:00
|
|
|
DMAs[0]->Run<ConsoleType>();
|
|
|
|
if (!(CPUStop & 0x80000000)) DMAs[1]->Run<ConsoleType>();
|
|
|
|
if (!(CPUStop & 0x80000000)) DMAs[2]->Run<ConsoleType>();
|
|
|
|
if (!(CPUStop & 0x80000000)) DMAs[3]->Run<ConsoleType>();
|
|
|
|
if (ConsoleType == 1) DSi::RunNDMAs(0);
|
2019-01-05 04:28:58 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-07-14 17:24:00 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2019-07-14 02:33:36 +00:00
|
|
|
if (EnableJIT)
|
2021-01-21 20:26:27 +00:00
|
|
|
ARM9->ExecuteJIT();
|
2019-07-14 02:33:36 +00:00
|
|
|
else
|
2019-07-14 17:24:00 +00:00
|
|
|
#endif
|
2021-01-21 20:26:27 +00:00
|
|
|
ARM9->Execute();
|
2019-01-05 04:28:58 +00:00
|
|
|
}
|
2018-12-11 14:56:34 +00:00
|
|
|
|
2021-01-21 20:26:27 +00:00
|
|
|
RunTimers(0);
|
|
|
|
GPU3D::Run();
|
2018-12-12 01:48:37 +00:00
|
|
|
|
2021-01-21 20:26:27 +00:00
|
|
|
target = ARM9Timestamp >> ARM9ClockShift;
|
|
|
|
CurCPU = 1;
|
2018-12-14 01:36:57 +00:00
|
|
|
|
2021-01-21 20:26:27 +00:00
|
|
|
while (ARM7Timestamp < target)
|
|
|
|
{
|
|
|
|
ARM7Target = target; // might be changed by a reschedule
|
|
|
|
|
|
|
|
if (CPUStop & 0x0FFF0000)
|
|
|
|
{
|
|
|
|
DMAs[4]->Run<ConsoleType>();
|
|
|
|
DMAs[5]->Run<ConsoleType>();
|
|
|
|
DMAs[6]->Run<ConsoleType>();
|
|
|
|
DMAs[7]->Run<ConsoleType>();
|
|
|
|
if (ConsoleType == 1) DSi::RunNDMAs(1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef JIT_ENABLED
|
|
|
|
if (EnableJIT)
|
|
|
|
ARM7->ExecuteJIT();
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
ARM7->Execute();
|
|
|
|
}
|
|
|
|
|
|
|
|
RunTimers(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
RunSystem(target);
|
|
|
|
|
|
|
|
if (CPUStop & 0x40000000)
|
|
|
|
{
|
|
|
|
// checkme: when is sleep mode effective?
|
2021-01-26 15:42:27 +00:00
|
|
|
CancelEvent(Event_LCD);
|
|
|
|
GPU::TotalScanlines = 263;
|
2021-01-21 20:26:27 +00:00
|
|
|
break;
|
|
|
|
}
|
2018-12-14 01:36:57 +00:00
|
|
|
}
|
2018-11-24 04:23:35 +00:00
|
|
|
|
2018-12-11 14:56:34 +00:00
|
|
|
#ifdef DEBUG_CHECK_DESYNC
|
2021-01-21 20:26:27 +00:00
|
|
|
printf("[%08X%08X] ARM9=%ld, ARM7=%ld, GPU=%ld\n",
|
|
|
|
(u32)(SysTimestamp>>32), (u32)SysTimestamp,
|
|
|
|
(ARM9Timestamp>>1)-SysTimestamp,
|
|
|
|
ARM7Timestamp-SysTimestamp,
|
|
|
|
GPU3D::Timestamp-SysTimestamp);
|
2018-12-11 14:56:34 +00:00
|
|
|
#endif
|
2021-01-21 20:26:27 +00:00
|
|
|
SPU::TransferOutput();
|
|
|
|
}
|
2018-12-11 02:08:46 +00:00
|
|
|
|
2021-01-21 20:26:27 +00:00
|
|
|
// In the context of TASes, frame count is traditionally the primary measure of emulated time,
|
|
|
|
// so it needs to be tracked even if NDS is powered off.
|
2018-12-12 01:48:37 +00:00
|
|
|
NumFrames++;
|
2021-01-21 20:26:27 +00:00
|
|
|
if (LagFrameFlag)
|
|
|
|
NumLagFrames++;
|
2018-12-12 01:48:37 +00:00
|
|
|
|
2021-01-21 20:26:27 +00:00
|
|
|
if (runFrame)
|
|
|
|
return GPU::TotalScanlines;
|
|
|
|
else
|
|
|
|
return 263;
|
2016-12-05 16:08:24 +00:00
|
|
|
}
|
|
|
|
|
2019-07-14 02:33:36 +00:00
|
|
|
u32 RunFrame()
|
|
|
|
{
|
2019-07-14 17:24:00 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2021-11-17 17:15:50 +00:00
|
|
|
if (EnableJIT)
|
2020-11-16 16:22:34 +00:00
|
|
|
return NDS::ConsoleType == 1
|
|
|
|
? RunFrame<true, 1>()
|
|
|
|
: RunFrame<true, 0>();
|
2019-07-14 02:33:36 +00:00
|
|
|
else
|
2019-07-14 17:24:00 +00:00
|
|
|
#endif
|
2020-11-25 23:04:19 +00:00
|
|
|
return NDS::ConsoleType == 1
|
2020-11-16 16:22:34 +00:00
|
|
|
? RunFrame<false, 1>()
|
|
|
|
: RunFrame<false, 0>();
|
2019-07-14 02:33:36 +00:00
|
|
|
}
|
|
|
|
|
2019-01-05 04:28:58 +00:00
|
|
|
void Reschedule(u64 target)
|
2017-01-31 02:54:51 +00:00
|
|
|
{
|
2019-01-05 04:28:58 +00:00
|
|
|
if (CurCPU == 0)
|
2018-11-09 13:10:06 +00:00
|
|
|
{
|
2019-01-05 04:28:58 +00:00
|
|
|
if (target < (ARM9Target >> ARM9ClockShift))
|
|
|
|
ARM9Target = (target << ARM9ClockShift);
|
2018-11-09 13:10:06 +00:00
|
|
|
}
|
2019-01-05 04:28:58 +00:00
|
|
|
else
|
2018-12-11 14:56:34 +00:00
|
|
|
{
|
2019-01-05 04:28:58 +00:00
|
|
|
if (target < ARM7Target)
|
|
|
|
ARM7Target = target;
|
2018-12-11 14:56:34 +00:00
|
|
|
}
|
2017-01-31 02:54:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ScheduleEvent(u32 id, bool periodic, s32 delay, void (*func)(u32), u32 param)
|
|
|
|
{
|
|
|
|
if (SchedListMask & (1<<id))
|
|
|
|
{
|
|
|
|
printf("!! EVENT %d ALREADY SCHEDULED\n", id);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
SchedEvent* evt = &SchedList[id];
|
|
|
|
|
2018-12-11 02:08:46 +00:00
|
|
|
if (periodic)
|
2019-01-05 04:28:58 +00:00
|
|
|
evt->Timestamp += delay;
|
2018-12-11 02:08:46 +00:00
|
|
|
else
|
|
|
|
{
|
2019-01-05 04:28:58 +00:00
|
|
|
if (CurCPU == 0)
|
|
|
|
evt->Timestamp = (ARM9Timestamp >> ARM9ClockShift) + delay;
|
|
|
|
else
|
|
|
|
evt->Timestamp = ARM7Timestamp + delay;
|
2018-12-11 02:08:46 +00:00
|
|
|
}
|
2017-01-31 02:54:51 +00:00
|
|
|
|
|
|
|
evt->Func = func;
|
|
|
|
evt->Param = param;
|
|
|
|
|
|
|
|
SchedListMask |= (1<<id);
|
2018-12-11 14:56:34 +00:00
|
|
|
|
2019-01-05 04:28:58 +00:00
|
|
|
Reschedule(evt->Timestamp);
|
2017-01-31 02:54:51 +00:00
|
|
|
}
|
|
|
|
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
void ScheduleEvent(u32 id, u64 timestamp, void (*func)(u32), u32 param)
|
|
|
|
{
|
|
|
|
if (SchedListMask & (1<<id))
|
|
|
|
{
|
|
|
|
printf("!! EVENT %d ALREADY SCHEDULED\n", id);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
SchedEvent* evt = &SchedList[id];
|
|
|
|
|
|
|
|
evt->Timestamp = timestamp;
|
|
|
|
evt->Func = func;
|
|
|
|
evt->Param = param;
|
|
|
|
|
|
|
|
SchedListMask |= (1<<id);
|
|
|
|
|
|
|
|
Reschedule(evt->Timestamp);
|
|
|
|
}
|
|
|
|
|
2017-01-31 02:54:51 +00:00
|
|
|
void CancelEvent(u32 id)
|
|
|
|
{
|
|
|
|
SchedListMask &= ~(1<<id);
|
|
|
|
}
|
|
|
|
|
2016-11-24 17:31:49 +00:00
|
|
|
|
2017-01-31 23:24:36 +00:00
|
|
|
void TouchScreen(u16 x, u16 y)
|
|
|
|
{
|
2020-06-01 18:36:30 +00:00
|
|
|
if (ConsoleType == 1)
|
2019-08-04 09:44:36 +00:00
|
|
|
{
|
|
|
|
DSi_SPI_TSC::SetTouchCoords(x, y);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SPI_TSC::SetTouchCoords(x, y);
|
|
|
|
KeyInput &= ~(1 << (16+6));
|
|
|
|
}
|
2017-01-31 23:24:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ReleaseScreen()
|
|
|
|
{
|
2020-06-01 18:36:30 +00:00
|
|
|
if (ConsoleType == 1)
|
2019-08-04 09:44:36 +00:00
|
|
|
{
|
|
|
|
DSi_SPI_TSC::SetTouchCoords(0x000, 0xFFF);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SPI_TSC::SetTouchCoords(0x000, 0xFFF);
|
|
|
|
KeyInput |= (1 << (16+6));
|
|
|
|
}
|
2017-01-31 23:24:36 +00:00
|
|
|
}
|
|
|
|
|
2016-12-23 20:22:22 +00:00
|
|
|
|
2017-09-30 18:05:56 +00:00
|
|
|
void SetKeyMask(u32 mask)
|
|
|
|
{
|
|
|
|
u32 key_lo = mask & 0x3FF;
|
|
|
|
u32 key_hi = (mask >> 10) & 0x3;
|
|
|
|
|
|
|
|
KeyInput &= 0xFFFCFC00;
|
|
|
|
KeyInput |= key_lo | (key_hi << 16);
|
|
|
|
}
|
|
|
|
|
2020-05-19 20:37:48 +00:00
|
|
|
bool IsLidClosed()
|
|
|
|
{
|
|
|
|
if (KeyInput & (1<<23)) return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-12-14 01:36:57 +00:00
|
|
|
void SetLidClosed(bool closed)
|
|
|
|
{
|
|
|
|
if (closed)
|
|
|
|
{
|
|
|
|
KeyInput |= (1<<23);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
KeyInput &= ~(1<<23);
|
|
|
|
SetIRQ(1, IRQ_LidOpen);
|
|
|
|
CPUStop &= ~0x40000000;
|
2021-01-26 15:42:27 +00:00
|
|
|
GPU3D::RestartFrame();
|
2018-12-14 01:36:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-02 14:47:57 +00:00
|
|
|
void CamInputFrame(int cam, u32* data, int width, int height, bool rgb)
|
|
|
|
{
|
|
|
|
// TODO: support things like the GBA-slot camera addon
|
|
|
|
// whenever these are emulated
|
|
|
|
|
|
|
|
if (ConsoleType == 1)
|
|
|
|
{
|
|
|
|
switch (cam)
|
|
|
|
{
|
|
|
|
case 0: return DSi_CamModule::Camera0->InputFrame(data, width, height, rgb);
|
|
|
|
case 1: return DSi_CamModule::Camera1->InputFrame(data, width, height, rgb);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-12 15:33:40 +00:00
|
|
|
void MicInputFrame(s16* data, int samples)
|
|
|
|
{
|
|
|
|
return SPI_TSC::MicInputFrame(data, samples);
|
|
|
|
}
|
|
|
|
|
2022-01-07 13:00:43 +00:00
|
|
|
/*int ImportSRAM(u8* data, u32 length)
|
2020-09-11 01:08:06 +00:00
|
|
|
{
|
|
|
|
return NDSCart::ImportSRAM(data, length);
|
2022-01-07 13:00:43 +00:00
|
|
|
}*/
|
2020-09-11 01:08:06 +00:00
|
|
|
|
2017-09-30 18:05:56 +00:00
|
|
|
|
2016-11-24 17:31:49 +00:00
|
|
|
void Halt()
|
|
|
|
{
|
2016-12-06 16:32:51 +00:00
|
|
|
printf("Halt()\n");
|
2016-11-24 17:31:49 +00:00
|
|
|
Running = false;
|
2016-11-03 00:38:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-12-06 16:32:51 +00:00
|
|
|
void MapSharedWRAM(u8 val)
|
2016-12-03 17:29:19 +00:00
|
|
|
{
|
2020-05-08 22:45:05 +00:00
|
|
|
if (val == WRAMCnt)
|
|
|
|
return;
|
|
|
|
|
2020-07-25 18:59:53 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-14 19:04:25 +00:00
|
|
|
ARMJIT_Memory::RemapSWRAM();
|
2020-07-25 18:59:53 +00:00
|
|
|
#endif
|
2020-06-14 19:04:25 +00:00
|
|
|
|
2016-12-06 16:32:51 +00:00
|
|
|
WRAMCnt = val;
|
|
|
|
|
2016-12-03 17:29:19 +00:00
|
|
|
switch (WRAMCnt & 0x3)
|
|
|
|
{
|
|
|
|
case 0:
|
2020-06-14 19:04:25 +00:00
|
|
|
SWRAM_ARM9.Mem = &SharedWRAM[0];
|
|
|
|
SWRAM_ARM9.Mask = 0x7FFF;
|
|
|
|
SWRAM_ARM7.Mem = NULL;
|
|
|
|
SWRAM_ARM7.Mask = 0;
|
2016-12-03 17:29:19 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
2020-06-14 19:04:25 +00:00
|
|
|
SWRAM_ARM9.Mem = &SharedWRAM[0x4000];
|
|
|
|
SWRAM_ARM9.Mask = 0x3FFF;
|
|
|
|
SWRAM_ARM7.Mem = &SharedWRAM[0];
|
|
|
|
SWRAM_ARM7.Mask = 0x3FFF;
|
2016-12-03 17:29:19 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
2020-06-14 19:04:25 +00:00
|
|
|
SWRAM_ARM9.Mem = &SharedWRAM[0];
|
|
|
|
SWRAM_ARM9.Mask = 0x3FFF;
|
|
|
|
SWRAM_ARM7.Mem = &SharedWRAM[0x4000];
|
|
|
|
SWRAM_ARM7.Mask = 0x3FFF;
|
2016-12-03 17:29:19 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
2020-06-14 19:04:25 +00:00
|
|
|
SWRAM_ARM9.Mem = NULL;
|
|
|
|
SWRAM_ARM9.Mask = 0;
|
|
|
|
SWRAM_ARM7.Mem = &SharedWRAM[0];
|
|
|
|
SWRAM_ARM7.Mask = 0x7FFF;
|
2016-12-03 17:29:19 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
void UpdateWifiTimings()
|
|
|
|
{
|
|
|
|
if (PowerControl7 & 0x0002)
|
|
|
|
{
|
|
|
|
const int ntimings[4] = {10, 8, 6, 18};
|
|
|
|
u16 val = WifiWaitCnt;
|
|
|
|
|
|
|
|
SetARM7RegionTimings(0x04800, 0x04808, Mem7_Wifi0, 16, ntimings[val & 0x3], (val & 0x4) ? 4 : 6);
|
|
|
|
SetARM7RegionTimings(0x04808, 0x04810, Mem7_Wifi1, 16, ntimings[(val>>3) & 0x3], (val & 0x20) ? 4 : 10);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetARM7RegionTimings(0x04800, 0x04808, Mem7_Wifi0, 32, 1, 1);
|
|
|
|
SetARM7RegionTimings(0x04808, 0x04810, Mem7_Wifi1, 32, 1, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
void SetWifiWaitCnt(u16 val)
|
|
|
|
{
|
|
|
|
if (WifiWaitCnt == val) return;
|
|
|
|
|
|
|
|
WifiWaitCnt = val;
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
UpdateWifiTimings();
|
2018-12-08 21:33:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SetGBASlotTimings()
|
|
|
|
{
|
|
|
|
const int ntimings[4] = {10, 8, 6, 18};
|
2021-05-04 10:58:59 +00:00
|
|
|
const u16 openbus[4] = {0xFE08, 0x0000, 0x0000, 0xFFFF};
|
2018-12-08 21:33:41 +00:00
|
|
|
|
2021-08-31 00:28:34 +00:00
|
|
|
u16 curcpu = (ExMemCnt[0] >> 7) & 0x1;
|
|
|
|
u16 curcnt = ExMemCnt[curcpu];
|
|
|
|
int ramN = ntimings[curcnt & 0x3];
|
|
|
|
int romN = ntimings[(curcnt>>2) & 0x3];
|
|
|
|
int romS = (curcnt & 0x10) ? 4 : 6;
|
2018-12-08 21:33:41 +00:00
|
|
|
|
2021-08-31 00:28:34 +00:00
|
|
|
// GBA slot timings only apply on the selected side
|
2018-12-08 21:33:41 +00:00
|
|
|
|
2021-08-31 00:28:34 +00:00
|
|
|
if (curcpu == 0)
|
|
|
|
{
|
|
|
|
SetARM9RegionTimings(0x08000, 0x0A000, Mem9_GBAROM, 16, romN, romS);
|
|
|
|
SetARM9RegionTimings(0x0A000, 0x0B000, Mem9_GBARAM, 8, ramN, ramN);
|
2018-12-08 21:33:41 +00:00
|
|
|
|
2021-08-31 00:28:34 +00:00
|
|
|
SetARM7RegionTimings(0x08000, 0x0A000, 0, 32, 1, 1);
|
|
|
|
SetARM7RegionTimings(0x0A000, 0x0B000, 0, 32, 1, 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetARM9RegionTimings(0x08000, 0x0A000, 0, 32, 1, 1);
|
|
|
|
SetARM9RegionTimings(0x0A000, 0x0B000, 0, 32, 1, 1);
|
2018-12-08 21:33:41 +00:00
|
|
|
|
2021-08-31 00:28:34 +00:00
|
|
|
SetARM7RegionTimings(0x08000, 0x0A000, Mem7_GBAROM, 16, romN, romS);
|
|
|
|
SetARM7RegionTimings(0x0A000, 0x0B000, Mem7_GBARAM, 8, ramN, ramN);
|
|
|
|
}
|
2021-05-04 10:58:59 +00:00
|
|
|
|
|
|
|
// this open-bus implementation is a rough way of simulating the way values
|
|
|
|
// lingering on the bus decay after a while, which is visible at higher waitstates
|
|
|
|
// for example, the Cartridge Construction Kit relies on this to determine that
|
|
|
|
// the GBA slot is empty
|
|
|
|
|
|
|
|
GBACart::SetOpenBusDecay(openbus[(curcnt>>2) & 0x3]);
|
2018-12-08 21:33:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-06-08 20:16:51 +00:00
|
|
|
void UpdateIRQ(u32 cpu)
|
|
|
|
{
|
|
|
|
ARM* arm = cpu ? (ARM*)ARM7 : (ARM*)ARM9;
|
|
|
|
|
|
|
|
if (IME[cpu] & 0x1)
|
|
|
|
{
|
2019-10-18 11:29:17 +00:00
|
|
|
arm->IRQ = !!(IE[cpu] & IF[cpu]);
|
2020-06-01 18:36:30 +00:00
|
|
|
if ((ConsoleType == 1) && cpu)
|
2019-10-18 11:29:17 +00:00
|
|
|
arm->IRQ |= !!(IE2 & IF2);
|
2019-06-08 20:16:51 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
arm->IRQ = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-02 23:48:26 +00:00
|
|
|
void SetIRQ(u32 cpu, u32 irq)
|
2016-12-04 02:20:50 +00:00
|
|
|
{
|
2017-03-02 23:48:26 +00:00
|
|
|
IF[cpu] |= (1 << irq);
|
2019-06-08 20:16:51 +00:00
|
|
|
UpdateIRQ(cpu);
|
2017-03-02 23:48:26 +00:00
|
|
|
}
|
2016-12-06 16:32:51 +00:00
|
|
|
|
2017-03-02 23:48:26 +00:00
|
|
|
void ClearIRQ(u32 cpu, u32 irq)
|
|
|
|
{
|
|
|
|
IF[cpu] &= ~(1 << irq);
|
2019-06-08 20:16:51 +00:00
|
|
|
UpdateIRQ(cpu);
|
2016-12-04 02:20:50 +00:00
|
|
|
}
|
|
|
|
|
2019-06-16 13:05:18 +00:00
|
|
|
void SetIRQ2(u32 irq)
|
|
|
|
{
|
|
|
|
IF2 |= (1 << irq);
|
|
|
|
UpdateIRQ(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ClearIRQ2(u32 irq)
|
|
|
|
{
|
|
|
|
IF2 &= ~(1 << irq);
|
|
|
|
UpdateIRQ(1);
|
|
|
|
}
|
|
|
|
|
2016-12-06 16:32:51 +00:00
|
|
|
bool HaltInterrupted(u32 cpu)
|
|
|
|
{
|
|
|
|
if (cpu == 0)
|
|
|
|
{
|
|
|
|
if (!(IME[0] & 0x1))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IF[cpu] & IE[cpu])
|
|
|
|
return true;
|
|
|
|
|
2020-07-27 21:18:33 +00:00
|
|
|
if ((ConsoleType == 1) && cpu && (IF2 & IE2))
|
|
|
|
return true;
|
|
|
|
|
2016-12-06 16:32:51 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-03-02 23:48:26 +00:00
|
|
|
void StopCPU(u32 cpu, u32 mask)
|
|
|
|
{
|
2017-04-12 15:53:15 +00:00
|
|
|
if (cpu)
|
|
|
|
{
|
|
|
|
CPUStop |= (mask << 16);
|
2017-04-13 02:16:57 +00:00
|
|
|
ARM7->Halt(2);
|
2017-04-12 15:53:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CPUStop |= mask;
|
2017-04-13 02:16:57 +00:00
|
|
|
ARM9->Halt(2);
|
2017-04-12 15:53:15 +00:00
|
|
|
}
|
2017-03-02 23:48:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ResumeCPU(u32 cpu, u32 mask)
|
2017-02-17 04:33:37 +00:00
|
|
|
{
|
2017-03-02 23:48:26 +00:00
|
|
|
if (cpu) mask <<= 16;
|
|
|
|
CPUStop &= ~mask;
|
2017-02-17 04:33:37 +00:00
|
|
|
}
|
|
|
|
|
2018-11-23 21:21:41 +00:00
|
|
|
void GXFIFOStall()
|
|
|
|
{
|
|
|
|
if (CPUStop & 0x80000000) return;
|
2018-12-11 14:56:34 +00:00
|
|
|
|
2018-11-23 21:21:41 +00:00
|
|
|
CPUStop |= 0x80000000;
|
|
|
|
|
|
|
|
if (CurCPU == 1) ARM9->Halt(2);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DMAs[0]->StallIfRunning();
|
|
|
|
DMAs[1]->StallIfRunning();
|
|
|
|
DMAs[2]->StallIfRunning();
|
|
|
|
DMAs[3]->StallIfRunning();
|
2020-06-01 18:36:30 +00:00
|
|
|
if (ConsoleType == 1) DSi::StallNDMAs();
|
2018-11-23 21:21:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GXFIFOUnstall()
|
|
|
|
{
|
|
|
|
CPUStop &= ~0x80000000;
|
|
|
|
}
|
|
|
|
|
2018-12-14 01:36:57 +00:00
|
|
|
void EnterSleepMode()
|
|
|
|
{
|
|
|
|
if (CPUStop & 0x40000000) return;
|
|
|
|
|
|
|
|
CPUStop |= 0x40000000;
|
|
|
|
ARM7->Halt(2);
|
|
|
|
}
|
|
|
|
|
2017-06-25 15:35:45 +00:00
|
|
|
u32 GetPC(u32 cpu)
|
|
|
|
{
|
|
|
|
return cpu ? ARM7->R[15] : ARM9->R[15];
|
|
|
|
}
|
|
|
|
|
2018-12-12 01:48:37 +00:00
|
|
|
u64 GetSysClockCycles(int num)
|
|
|
|
{
|
|
|
|
u64 ret;
|
|
|
|
|
2018-12-12 15:33:40 +00:00
|
|
|
if (num == 0 || num == 2)
|
2018-12-12 01:48:37 +00:00
|
|
|
{
|
2019-01-05 04:28:58 +00:00
|
|
|
if (CurCPU == 0)
|
|
|
|
ret = ARM9Timestamp >> ARM9ClockShift;
|
|
|
|
else
|
|
|
|
ret = ARM7Timestamp;
|
2018-12-12 01:48:37 +00:00
|
|
|
|
2019-01-05 04:28:58 +00:00
|
|
|
if (num == 2) ret -= FrameStartTimestamp;
|
2018-12-12 01:48:37 +00:00
|
|
|
}
|
2018-12-12 15:33:40 +00:00
|
|
|
else if (num == 1)
|
2018-12-12 01:48:37 +00:00
|
|
|
{
|
|
|
|
ret = LastSysClockCycles;
|
2018-12-12 02:09:48 +00:00
|
|
|
LastSysClockCycles = 0;
|
2018-12-12 01:48:37 +00:00
|
|
|
|
2019-01-05 04:28:58 +00:00
|
|
|
if (CurCPU == 0)
|
|
|
|
LastSysClockCycles = ARM9Timestamp >> ARM9ClockShift;
|
|
|
|
else
|
|
|
|
LastSysClockCycles = ARM7Timestamp;
|
2018-12-12 01:48:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void NocashPrint(u32 ncpu, u32 addr)
|
|
|
|
{
|
2021-05-27 10:15:16 +00:00
|
|
|
// addr: debug string
|
2018-12-12 01:48:37 +00:00
|
|
|
|
|
|
|
ARM* cpu = ncpu ? (ARM*)ARM7 : (ARM*)ARM9;
|
|
|
|
u8 (*readfn)(u32) = ncpu ? NDS::ARM7Read8 : NDS::ARM9Read8;
|
|
|
|
|
|
|
|
char output[1024];
|
|
|
|
int ptr = 0;
|
|
|
|
|
|
|
|
for (int i = 0; i < 120 && ptr < 1023; )
|
|
|
|
{
|
|
|
|
char ch = readfn(addr++);
|
|
|
|
i++;
|
|
|
|
|
|
|
|
if (ch == '%')
|
|
|
|
{
|
|
|
|
char cmd[16]; int j;
|
|
|
|
for (j = 0; j < 15; )
|
|
|
|
{
|
|
|
|
char ch2 = readfn(addr++);
|
|
|
|
i++;
|
|
|
|
if (i >= 120) break;
|
|
|
|
if (ch2 == '%') break;
|
|
|
|
cmd[j++] = ch2;
|
|
|
|
}
|
|
|
|
cmd[j] = '\0';
|
|
|
|
|
|
|
|
char subs[64];
|
|
|
|
|
|
|
|
if (cmd[0] == 'r')
|
|
|
|
{
|
|
|
|
if (!strcmp(cmd, "r0")) sprintf(subs, "%08X", cpu->R[0]);
|
|
|
|
else if (!strcmp(cmd, "r1")) sprintf(subs, "%08X", cpu->R[1]);
|
|
|
|
else if (!strcmp(cmd, "r2")) sprintf(subs, "%08X", cpu->R[2]);
|
|
|
|
else if (!strcmp(cmd, "r3")) sprintf(subs, "%08X", cpu->R[3]);
|
|
|
|
else if (!strcmp(cmd, "r4")) sprintf(subs, "%08X", cpu->R[4]);
|
|
|
|
else if (!strcmp(cmd, "r5")) sprintf(subs, "%08X", cpu->R[5]);
|
|
|
|
else if (!strcmp(cmd, "r6")) sprintf(subs, "%08X", cpu->R[6]);
|
|
|
|
else if (!strcmp(cmd, "r7")) sprintf(subs, "%08X", cpu->R[7]);
|
|
|
|
else if (!strcmp(cmd, "r8")) sprintf(subs, "%08X", cpu->R[8]);
|
|
|
|
else if (!strcmp(cmd, "r9")) sprintf(subs, "%08X", cpu->R[9]);
|
|
|
|
else if (!strcmp(cmd, "r10")) sprintf(subs, "%08X", cpu->R[10]);
|
|
|
|
else if (!strcmp(cmd, "r11")) sprintf(subs, "%08X", cpu->R[11]);
|
|
|
|
else if (!strcmp(cmd, "r12")) sprintf(subs, "%08X", cpu->R[12]);
|
|
|
|
else if (!strcmp(cmd, "r13")) sprintf(subs, "%08X", cpu->R[13]);
|
|
|
|
else if (!strcmp(cmd, "r14")) sprintf(subs, "%08X", cpu->R[14]);
|
|
|
|
else if (!strcmp(cmd, "r15")) sprintf(subs, "%08X", cpu->R[15]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!strcmp(cmd, "sp")) sprintf(subs, "%08X", cpu->R[13]);
|
|
|
|
else if (!strcmp(cmd, "lr")) sprintf(subs, "%08X", cpu->R[14]);
|
|
|
|
else if (!strcmp(cmd, "pc")) sprintf(subs, "%08X", cpu->R[15]);
|
2018-12-12 02:09:48 +00:00
|
|
|
else if (!strcmp(cmd, "frame")) sprintf(subs, "%u", NumFrames);
|
|
|
|
else if (!strcmp(cmd, "scanline")) sprintf(subs, "%u", GPU::VCount);
|
2021-05-03 12:36:21 +00:00
|
|
|
else if (!strcmp(cmd, "totalclks")) sprintf(subs, "%" PRIu64, GetSysClockCycles(0));
|
|
|
|
else if (!strcmp(cmd, "lastclks")) sprintf(subs, "%" PRIu64, GetSysClockCycles(1));
|
2018-12-12 01:48:37 +00:00
|
|
|
else if (!strcmp(cmd, "zeroclks"))
|
|
|
|
{
|
2021-05-03 12:36:21 +00:00
|
|
|
sprintf(subs, "%s", "");
|
2018-12-12 01:48:37 +00:00
|
|
|
GetSysClockCycles(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int slen = strlen(subs);
|
|
|
|
if ((ptr+slen) > 1023) slen = 1023-ptr;
|
|
|
|
strncpy(&output[ptr], subs, slen);
|
|
|
|
ptr += slen;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
output[ptr++] = ch;
|
|
|
|
if (ch == '\0') break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
output[ptr] = '\0';
|
|
|
|
printf("%s", output);
|
|
|
|
}
|
|
|
|
|
2016-12-04 02:20:50 +00:00
|
|
|
|
2016-12-03 00:31:33 +00:00
|
|
|
|
2020-02-24 17:31:44 +00:00
|
|
|
void MonitorARM9Jump(u32 addr)
|
|
|
|
{
|
|
|
|
// checkme: can the entrypoint addr be THUMB?
|
2020-06-01 18:36:30 +00:00
|
|
|
// also TODO: make it work in DSi mode
|
2020-02-24 17:31:44 +00:00
|
|
|
|
|
|
|
if ((!RunningGame) && NDSCart::CartROM)
|
|
|
|
{
|
|
|
|
if (addr == *(u32*)&NDSCart::CartROM[0x24])
|
2021-08-30 18:28:51 +00:00
|
|
|
{
|
2020-02-24 17:31:44 +00:00
|
|
|
printf("Game is now booting\n");
|
|
|
|
RunningGame = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-03-20 16:39:42 +00:00
|
|
|
void HandleTimerOverflow(u32 tid)
|
|
|
|
{
|
|
|
|
Timer* timer = &Timers[tid];
|
|
|
|
|
2020-10-27 04:03:17 +00:00
|
|
|
timer->Counter += (timer->Reload << 10);
|
2017-03-20 16:39:42 +00:00
|
|
|
if (timer->Cnt & (1<<6))
|
|
|
|
SetIRQ(tid >> 2, IRQ_Timer0 + (tid & 0x3));
|
2018-12-11 02:08:46 +00:00
|
|
|
|
2017-03-20 16:39:42 +00:00
|
|
|
if ((tid & 0x3) == 3)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
tid++;
|
|
|
|
|
|
|
|
timer = &Timers[tid];
|
|
|
|
|
|
|
|
if ((timer->Cnt & 0x84) != 0x84)
|
|
|
|
break;
|
|
|
|
|
2020-10-27 04:03:17 +00:00
|
|
|
timer->Counter += (1 << 10);
|
|
|
|
if (!(timer->Counter >> 26))
|
2017-03-20 16:39:42 +00:00
|
|
|
break;
|
|
|
|
|
2020-10-27 04:03:17 +00:00
|
|
|
timer->Counter = timer->Reload << 10;
|
2017-03-20 16:39:42 +00:00
|
|
|
if (timer->Cnt & (1<<6))
|
|
|
|
SetIRQ(tid >> 2, IRQ_Timer0 + (tid & 0x3));
|
|
|
|
|
|
|
|
if ((tid & 0x3) == 3)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void RunTimer(u32 tid, s32 cycles)
|
|
|
|
{
|
|
|
|
Timer* timer = &Timers[tid];
|
|
|
|
|
|
|
|
timer->Counter += (cycles << timer->CycleShift);
|
2020-10-27 04:03:17 +00:00
|
|
|
while (timer->Counter >> 26)
|
|
|
|
{
|
|
|
|
timer->Counter -= (1 << 26);
|
2017-03-20 16:39:42 +00:00
|
|
|
HandleTimerOverflow(tid);
|
2020-10-27 04:03:17 +00:00
|
|
|
}
|
2017-03-20 16:39:42 +00:00
|
|
|
}
|
|
|
|
|
2019-01-05 04:28:58 +00:00
|
|
|
void RunTimers(u32 cpu)
|
2017-03-20 16:39:42 +00:00
|
|
|
{
|
2021-02-09 22:38:51 +00:00
|
|
|
u32 timermask = TimerCheckMask[cpu];
|
2019-01-05 04:28:58 +00:00
|
|
|
s32 cycles;
|
|
|
|
|
|
|
|
if (cpu == 0)
|
|
|
|
cycles = (ARM9Timestamp >> ARM9ClockShift) - TimerTimestamp[0];
|
|
|
|
else
|
|
|
|
cycles = ARM7Timestamp - TimerTimestamp[1];
|
2018-12-11 14:56:34 +00:00
|
|
|
|
2017-04-24 23:14:26 +00:00
|
|
|
if (timermask & 0x1) RunTimer((cpu<<2)+0, cycles);
|
|
|
|
if (timermask & 0x2) RunTimer((cpu<<2)+1, cycles);
|
|
|
|
if (timermask & 0x4) RunTimer((cpu<<2)+2, cycles);
|
|
|
|
if (timermask & 0x8) RunTimer((cpu<<2)+3, cycles);
|
2018-12-11 14:56:34 +00:00
|
|
|
|
2019-01-05 04:28:58 +00:00
|
|
|
TimerTimestamp[cpu] += cycles;
|
2017-03-20 16:39:42 +00:00
|
|
|
}
|
|
|
|
|
2021-08-31 00:28:34 +00:00
|
|
|
const s32 TimerPrescaler[4] = {0, 6, 8, 10};
|
|
|
|
|
|
|
|
u16 TimerGetCounter(u32 timer)
|
|
|
|
{
|
|
|
|
RunTimers(timer>>2);
|
|
|
|
u32 ret = Timers[timer].Counter;
|
|
|
|
|
|
|
|
return ret >> 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TimerStart(u32 id, u16 cnt)
|
|
|
|
{
|
|
|
|
Timer* timer = &Timers[id];
|
|
|
|
u16 curstart = timer->Cnt & (1<<7);
|
|
|
|
u16 newstart = cnt & (1<<7);
|
|
|
|
|
|
|
|
RunTimers(id>>2);
|
|
|
|
|
|
|
|
timer->Cnt = cnt;
|
|
|
|
timer->CycleShift = 10 - TimerPrescaler[cnt & 0x03];
|
|
|
|
|
|
|
|
if ((!curstart) && newstart)
|
|
|
|
{
|
|
|
|
timer->Counter = timer->Reload << 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((cnt & 0x84) == 0x80)
|
|
|
|
TimerCheckMask[id>>2] |= 0x01 << (id&0x3);
|
|
|
|
else
|
|
|
|
TimerCheckMask[id>>2] &= ~(0x01 << (id&0x3));
|
|
|
|
}
|
|
|
|
|
2017-03-20 16:39:42 +00:00
|
|
|
|
|
|
|
|
2019-10-19 14:03:59 +00:00
|
|
|
// matching NDMA modes for DSi
|
|
|
|
const u32 NDMAModes[] =
|
|
|
|
{
|
|
|
|
// ARM9
|
|
|
|
|
|
|
|
0x10, // immediate
|
|
|
|
0x06, // VBlank
|
|
|
|
0x07, // HBlank
|
|
|
|
0x08, // scanline start
|
|
|
|
0x09, // mainmem FIFO
|
|
|
|
0x04, // DS cart slot
|
|
|
|
0xFF, // GBA cart slot
|
|
|
|
0x0A, // GX FIFO
|
|
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
|
|
|
|
|
|
// ARM7
|
|
|
|
|
|
|
|
0x30, // immediate
|
|
|
|
0x26, // VBlank
|
|
|
|
0x24, // DS cart slot
|
|
|
|
0xFF, // wifi / GBA cart slot (TODO)
|
|
|
|
};
|
|
|
|
|
2017-06-26 09:02:10 +00:00
|
|
|
bool DMAsInMode(u32 cpu, u32 mode)
|
|
|
|
{
|
|
|
|
cpu <<= 2;
|
|
|
|
if (DMAs[cpu+0]->IsInMode(mode)) return true;
|
|
|
|
if (DMAs[cpu+1]->IsInMode(mode)) return true;
|
|
|
|
if (DMAs[cpu+2]->IsInMode(mode)) return true;
|
|
|
|
if (DMAs[cpu+3]->IsInMode(mode)) return true;
|
2019-10-19 14:03:59 +00:00
|
|
|
|
2020-06-01 18:36:30 +00:00
|
|
|
if (ConsoleType == 1)
|
2019-10-19 14:03:59 +00:00
|
|
|
{
|
|
|
|
cpu >>= 2;
|
|
|
|
return DSi::NDMAsInMode(cpu, NDMAModes[mode]);
|
|
|
|
}
|
|
|
|
|
2017-06-26 09:02:10 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-12-11 02:08:46 +00:00
|
|
|
bool DMAsRunning(u32 cpu)
|
|
|
|
{
|
|
|
|
cpu <<= 2;
|
|
|
|
if (DMAs[cpu+0]->IsRunning()) return true;
|
|
|
|
if (DMAs[cpu+1]->IsRunning()) return true;
|
|
|
|
if (DMAs[cpu+2]->IsRunning()) return true;
|
|
|
|
if (DMAs[cpu+3]->IsRunning()) return true;
|
2020-06-01 18:36:30 +00:00
|
|
|
if (ConsoleType == 1)
|
|
|
|
{
|
|
|
|
if (DSi::NDMAsRunning(cpu>>2)) return true;
|
|
|
|
}
|
2018-12-11 02:08:46 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-01-22 19:34:59 +00:00
|
|
|
void CheckDMAs(u32 cpu, u32 mode)
|
|
|
|
{
|
|
|
|
cpu <<= 2;
|
|
|
|
DMAs[cpu+0]->StartIfNeeded(mode);
|
|
|
|
DMAs[cpu+1]->StartIfNeeded(mode);
|
|
|
|
DMAs[cpu+2]->StartIfNeeded(mode);
|
|
|
|
DMAs[cpu+3]->StartIfNeeded(mode);
|
2019-10-19 14:03:59 +00:00
|
|
|
|
2020-06-01 18:36:30 +00:00
|
|
|
if (ConsoleType == 1)
|
2019-10-19 14:03:59 +00:00
|
|
|
{
|
|
|
|
cpu >>= 2;
|
|
|
|
DSi::CheckNDMAs(cpu, NDMAModes[mode]);
|
|
|
|
}
|
2017-01-22 19:34:59 +00:00
|
|
|
}
|
|
|
|
|
2017-03-20 21:18:35 +00:00
|
|
|
void StopDMAs(u32 cpu, u32 mode)
|
|
|
|
{
|
|
|
|
cpu <<= 2;
|
|
|
|
DMAs[cpu+0]->StopIfNeeded(mode);
|
|
|
|
DMAs[cpu+1]->StopIfNeeded(mode);
|
|
|
|
DMAs[cpu+2]->StopIfNeeded(mode);
|
|
|
|
DMAs[cpu+3]->StopIfNeeded(mode);
|
2019-10-19 14:03:59 +00:00
|
|
|
|
2020-06-01 18:36:30 +00:00
|
|
|
if (ConsoleType == 1)
|
2019-10-19 14:03:59 +00:00
|
|
|
{
|
|
|
|
cpu >>= 2;
|
|
|
|
DSi::StopNDMAs(cpu, NDMAModes[mode]);
|
|
|
|
}
|
2017-03-20 21:18:35 +00:00
|
|
|
}
|
|
|
|
|
2017-01-22 19:34:59 +00:00
|
|
|
|
|
|
|
|
2017-07-15 17:46:27 +00:00
|
|
|
void DivDone(u32 param)
|
2017-01-18 01:20:45 +00:00
|
|
|
{
|
2017-07-15 17:46:27 +00:00
|
|
|
DivCnt &= ~0xC000;
|
2017-01-18 01:20:45 +00:00
|
|
|
|
|
|
|
switch (DivCnt & 0x0003)
|
|
|
|
{
|
|
|
|
case 0x0000:
|
|
|
|
{
|
|
|
|
s32 num = (s32)DivNumerator[0];
|
|
|
|
s32 den = (s32)DivDenominator[0];
|
|
|
|
if (den == 0)
|
|
|
|
{
|
|
|
|
DivQuotient[0] = (num<0) ? 1:-1;
|
2019-08-24 15:52:24 +00:00
|
|
|
DivQuotient[1] = (num<0) ? -1:0;
|
2017-01-18 01:20:45 +00:00
|
|
|
*(s64*)&DivRemainder[0] = num;
|
|
|
|
}
|
|
|
|
else if (num == -0x80000000 && den == -1)
|
|
|
|
{
|
|
|
|
*(s64*)&DivQuotient[0] = 0x80000000;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*(s64*)&DivQuotient[0] = (s64)(num / den);
|
|
|
|
*(s64*)&DivRemainder[0] = (s64)(num % den);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x0001:
|
|
|
|
case 0x0003:
|
|
|
|
{
|
|
|
|
s64 num = *(s64*)&DivNumerator[0];
|
|
|
|
s32 den = (s32)DivDenominator[0];
|
|
|
|
if (den == 0)
|
|
|
|
{
|
|
|
|
*(s64*)&DivQuotient[0] = (num<0) ? 1:-1;
|
|
|
|
*(s64*)&DivRemainder[0] = num;
|
|
|
|
}
|
|
|
|
else if (num == -0x8000000000000000 && den == -1)
|
|
|
|
{
|
|
|
|
*(s64*)&DivQuotient[0] = 0x8000000000000000;
|
2021-02-19 22:58:41 +00:00
|
|
|
*(s64*)&DivRemainder[0] = 0;
|
2017-01-18 01:20:45 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*(s64*)&DivQuotient[0] = (s64)(num / den);
|
|
|
|
*(s64*)&DivRemainder[0] = (s64)(num % den);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x0002:
|
|
|
|
{
|
|
|
|
s64 num = *(s64*)&DivNumerator[0];
|
|
|
|
s64 den = *(s64*)&DivDenominator[0];
|
|
|
|
if (den == 0)
|
|
|
|
{
|
|
|
|
*(s64*)&DivQuotient[0] = (num<0) ? 1:-1;
|
|
|
|
*(s64*)&DivRemainder[0] = num;
|
|
|
|
}
|
|
|
|
else if (num == -0x8000000000000000 && den == -1)
|
|
|
|
{
|
|
|
|
*(s64*)&DivQuotient[0] = 0x8000000000000000;
|
2021-02-19 22:58:41 +00:00
|
|
|
*(s64*)&DivRemainder[0] = 0;
|
2017-01-18 01:20:45 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*(s64*)&DivQuotient[0] = (s64)(num / den);
|
|
|
|
*(s64*)&DivRemainder[0] = (s64)(num % den);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((DivDenominator[0] | DivDenominator[1]) == 0)
|
2017-07-15 17:46:27 +00:00
|
|
|
DivCnt |= 0x4000;
|
2017-01-18 01:20:45 +00:00
|
|
|
}
|
|
|
|
|
2017-07-15 17:46:27 +00:00
|
|
|
void StartDiv()
|
2017-01-31 20:53:45 +00:00
|
|
|
{
|
2017-07-15 17:46:27 +00:00
|
|
|
NDS::CancelEvent(NDS::Event_Div);
|
|
|
|
DivCnt |= 0x8000;
|
|
|
|
NDS::ScheduleEvent(NDS::Event_Div, false, ((DivCnt&0x3)==0) ? 18:34, DivDone, 0);
|
|
|
|
}
|
2017-01-31 20:53:45 +00:00
|
|
|
|
2017-07-15 17:46:27 +00:00
|
|
|
// http://stackoverflow.com/questions/1100090/looking-for-an-efficient-integer-square-root-algorithm-for-arm-thumb2
|
|
|
|
void SqrtDone(u32 param)
|
|
|
|
{
|
2017-01-31 20:53:45 +00:00
|
|
|
u64 val;
|
|
|
|
u32 res = 0;
|
|
|
|
u64 rem = 0;
|
|
|
|
u32 prod = 0;
|
|
|
|
u32 nbits, topshift;
|
|
|
|
|
2017-07-15 17:46:27 +00:00
|
|
|
SqrtCnt &= ~0x8000;
|
|
|
|
|
2017-01-31 20:53:45 +00:00
|
|
|
if (SqrtCnt & 0x0001)
|
|
|
|
{
|
|
|
|
val = *(u64*)&SqrtVal[0];
|
|
|
|
nbits = 32;
|
|
|
|
topshift = 62;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
val = (u64)SqrtVal[0]; // 32bit
|
|
|
|
nbits = 16;
|
|
|
|
topshift = 30;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (u32 i = 0; i < nbits; i++)
|
|
|
|
{
|
|
|
|
rem = (rem << 2) + ((val >> topshift) & 0x3);
|
|
|
|
val <<= 2;
|
|
|
|
res <<= 1;
|
|
|
|
|
|
|
|
prod = (res << 1) + 1;
|
|
|
|
if (rem >= prod)
|
|
|
|
{
|
|
|
|
rem -= prod;
|
|
|
|
res++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SqrtRes = res;
|
|
|
|
}
|
|
|
|
|
2017-07-15 17:46:27 +00:00
|
|
|
void StartSqrt()
|
|
|
|
{
|
|
|
|
NDS::CancelEvent(NDS::Event_Sqrt);
|
|
|
|
SqrtCnt |= 0x8000;
|
|
|
|
NDS::ScheduleEvent(NDS::Event_Sqrt, false, 13, SqrtDone, 0);
|
|
|
|
}
|
|
|
|
|
2017-01-18 01:20:45 +00:00
|
|
|
|
|
|
|
|
2016-12-06 16:32:51 +00:00
|
|
|
void debug(u32 param)
|
|
|
|
{
|
2017-02-03 15:57:31 +00:00
|
|
|
printf("ARM9 PC=%08X LR=%08X %08X\n", ARM9->R[15], ARM9->R[14], ARM9->R_IRQ[1]);
|
|
|
|
printf("ARM7 PC=%08X LR=%08X %08X\n", ARM7->R[15], ARM7->R[14], ARM7->R_IRQ[1]);
|
2017-02-27 23:50:54 +00:00
|
|
|
|
2017-04-10 16:47:11 +00:00
|
|
|
printf("ARM9 IME=%08X IE=%08X IF=%08X\n", IME[0], IE[0], IF[0]);
|
2019-06-19 12:24:49 +00:00
|
|
|
printf("ARM7 IME=%08X IE=%08X IF=%08X IE2=%04X IF2=%04X\n", IME[1], IE[1], IF[1], IE2, IF2);
|
2017-04-10 16:47:11 +00:00
|
|
|
|
|
|
|
//for (int i = 0; i < 9; i++)
|
|
|
|
// printf("VRAM %c: %02X\n", 'A'+i, GPU::VRAMCNT[i]);
|
2017-04-26 14:17:03 +00:00
|
|
|
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
FILE*
|
|
|
|
shit = fopen("debug/inazuma.bin", "wb");
|
2019-07-09 16:39:50 +00:00
|
|
|
fwrite(ARM9->ITCM, 0x8000, 1, shit);
|
2017-06-12 17:00:32 +00:00
|
|
|
for (u32 i = 0x02000000; i < 0x02400000; i+=4)
|
2017-04-26 14:17:03 +00:00
|
|
|
{
|
|
|
|
u32 val = ARM7Read32(i);
|
|
|
|
fwrite(&val, 4, 1, shit);
|
|
|
|
}
|
2017-05-09 01:54:37 +00:00
|
|
|
for (u32 i = 0x037F0000; i < 0x03810000; i+=4)
|
|
|
|
{
|
|
|
|
u32 val = ARM7Read32(i);
|
|
|
|
fwrite(&val, 4, 1, shit);
|
|
|
|
}
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
for (u32 i = 0x06000000; i < 0x06040000; i+=4)
|
|
|
|
{
|
|
|
|
u32 val = ARM7Read32(i);
|
|
|
|
fwrite(&val, 4, 1, shit);
|
|
|
|
}
|
|
|
|
fclose(shit);
|
2020-08-17 17:15:45 +00:00
|
|
|
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
/*FILE*
|
2021-08-30 18:26:49 +00:00
|
|
|
shit = fopen("debug/directboot9.bin", "wb");
|
2019-06-20 00:31:46 +00:00
|
|
|
for (u32 i = 0x02000000; i < 0x04000000; i+=4)
|
|
|
|
{
|
|
|
|
u32 val = DSi::ARM9Read32(i);
|
|
|
|
fwrite(&val, 4, 1, shit);
|
|
|
|
}
|
2020-06-15 11:39:33 +00:00
|
|
|
fclose(shit);
|
2022-10-02 14:47:57 +00:00
|
|
|
shit = fopen("debug/camera7.bin", "wb");
|
2019-06-20 00:31:46 +00:00
|
|
|
for (u32 i = 0x02000000; i < 0x04000000; i+=4)
|
|
|
|
{
|
|
|
|
u32 val = DSi::ARM7Read32(i);
|
|
|
|
fwrite(&val, 4, 1, shit);
|
|
|
|
}
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
fclose(shit);*/
|
2016-12-06 16:32:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
u8 ARM9Read8(u32 addr)
|
2016-12-03 00:31:33 +00:00
|
|
|
{
|
|
|
|
if ((addr & 0xFFFFF000) == 0xFFFF0000)
|
|
|
|
{
|
2018-12-08 21:33:41 +00:00
|
|
|
return *(u8*)&ARM9BIOS[addr & 0xFFF];
|
2016-12-03 00:31:33 +00:00
|
|
|
}
|
|
|
|
|
2016-12-03 12:42:27 +00:00
|
|
|
switch (addr & 0xFF000000)
|
|
|
|
{
|
|
|
|
case 0x02000000:
|
2020-06-30 21:50:41 +00:00
|
|
|
return *(u8*)&MainRAM[addr & MainRAMMask];
|
2016-12-03 17:29:19 +00:00
|
|
|
|
|
|
|
case 0x03000000:
|
2020-06-14 19:04:25 +00:00
|
|
|
if (SWRAM_ARM9.Mem)
|
2018-12-04 16:54:10 +00:00
|
|
|
{
|
2020-06-14 19:04:25 +00:00
|
|
|
return *(u8*)&SWRAM_ARM9.Mem[addr & SWRAM_ARM9.Mask];
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-12-08 21:33:41 +00:00
|
|
|
return 0;
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
2016-12-03 17:29:19 +00:00
|
|
|
|
|
|
|
case 0x04000000:
|
2018-12-08 21:33:41 +00:00
|
|
|
return ARM9IORead8(addr);
|
2016-12-05 22:17:03 +00:00
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x05000000:
|
2018-12-18 16:04:42 +00:00
|
|
|
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
|
2020-12-23 08:23:46 +00:00
|
|
|
return GPU::ReadPalette<u8>(addr);
|
2016-12-06 16:32:51 +00:00
|
|
|
|
2016-12-05 22:17:03 +00:00
|
|
|
case 0x06000000:
|
2018-12-04 16:54:10 +00:00
|
|
|
switch (addr & 0x00E00000)
|
2016-12-05 22:17:03 +00:00
|
|
|
{
|
2018-12-08 21:33:41 +00:00
|
|
|
case 0x00000000: return GPU::ReadVRAM_ABG<u8>(addr);
|
|
|
|
case 0x00200000: return GPU::ReadVRAM_BBG<u8>(addr);
|
|
|
|
case 0x00400000: return GPU::ReadVRAM_AOBJ<u8>(addr);
|
|
|
|
case 0x00600000: return GPU::ReadVRAM_BOBJ<u8>(addr);
|
|
|
|
default: return GPU::ReadVRAM_LCDC<u8>(addr);
|
2016-12-05 22:17:03 +00:00
|
|
|
}
|
2016-12-06 16:32:51 +00:00
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x07000000:
|
2018-12-18 16:04:42 +00:00
|
|
|
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
|
2020-12-23 08:23:46 +00:00
|
|
|
return GPU::ReadOAM<u8>(addr);
|
2017-01-18 16:57:12 +00:00
|
|
|
|
|
|
|
case 0x08000000:
|
|
|
|
case 0x09000000:
|
2019-12-08 17:32:59 +00:00
|
|
|
if (ExMemCnt[0] & (1<<7)) return 0x00; // deselected CPU is 00h-filled
|
2021-04-24 22:48:02 +00:00
|
|
|
if (addr & 0x1) return GBACart::ROMRead(addr-1) >> 8;
|
|
|
|
return GBACart::ROMRead(addr) & 0xFF;
|
2018-12-12 18:43:29 +00:00
|
|
|
|
|
|
|
case 0x0A000000:
|
2019-12-08 17:32:59 +00:00
|
|
|
if (ExMemCnt[0] & (1<<7)) return 0x00; // deselected CPU is 00h-filled
|
2021-04-24 22:48:02 +00:00
|
|
|
return GBACart::SRAMRead(addr);
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
|
|
|
|
2016-12-03 00:31:33 +00:00
|
|
|
printf("unknown arm9 read8 %08X\n", addr);
|
2018-12-08 21:33:41 +00:00
|
|
|
return 0;
|
2016-12-03 00:31:33 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
u16 ARM9Read16(u32 addr)
|
2016-11-03 00:38:58 +00:00
|
|
|
{
|
2016-12-03 00:31:33 +00:00
|
|
|
if ((addr & 0xFFFFF000) == 0xFFFF0000)
|
|
|
|
{
|
2018-12-08 21:33:41 +00:00
|
|
|
return *(u16*)&ARM9BIOS[addr & 0xFFF];
|
2016-12-03 00:31:33 +00:00
|
|
|
}
|
|
|
|
|
2016-12-03 12:42:27 +00:00
|
|
|
switch (addr & 0xFF000000)
|
|
|
|
{
|
|
|
|
case 0x02000000:
|
2020-06-30 21:50:41 +00:00
|
|
|
return *(u16*)&MainRAM[addr & MainRAMMask];
|
2016-12-03 15:13:04 +00:00
|
|
|
|
2016-12-03 17:29:19 +00:00
|
|
|
case 0x03000000:
|
2020-06-14 19:04:25 +00:00
|
|
|
if (SWRAM_ARM9.Mem)
|
2018-12-04 16:54:10 +00:00
|
|
|
{
|
2020-06-14 19:04:25 +00:00
|
|
|
return *(u16*)&SWRAM_ARM9.Mem[addr & SWRAM_ARM9.Mask];
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-12-08 21:33:41 +00:00
|
|
|
return 0;
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
2016-12-03 17:29:19 +00:00
|
|
|
|
2016-12-03 15:13:04 +00:00
|
|
|
case 0x04000000:
|
2018-12-08 21:33:41 +00:00
|
|
|
return ARM9IORead16(addr);
|
2016-12-06 16:32:51 +00:00
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x05000000:
|
2018-12-18 16:04:42 +00:00
|
|
|
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
|
2020-12-23 08:23:46 +00:00
|
|
|
return GPU::ReadPalette<u16>(addr);
|
2016-12-06 16:32:51 +00:00
|
|
|
|
2016-12-05 22:17:03 +00:00
|
|
|
case 0x06000000:
|
2018-12-04 16:54:10 +00:00
|
|
|
switch (addr & 0x00E00000)
|
2016-12-05 22:17:03 +00:00
|
|
|
{
|
2018-12-08 21:33:41 +00:00
|
|
|
case 0x00000000: return GPU::ReadVRAM_ABG<u16>(addr);
|
|
|
|
case 0x00200000: return GPU::ReadVRAM_BBG<u16>(addr);
|
|
|
|
case 0x00400000: return GPU::ReadVRAM_AOBJ<u16>(addr);
|
|
|
|
case 0x00600000: return GPU::ReadVRAM_BOBJ<u16>(addr);
|
|
|
|
default: return GPU::ReadVRAM_LCDC<u16>(addr);
|
2016-12-05 22:17:03 +00:00
|
|
|
}
|
2016-12-06 16:32:51 +00:00
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x07000000:
|
2018-12-18 16:04:42 +00:00
|
|
|
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
|
2020-12-23 08:23:46 +00:00
|
|
|
return GPU::ReadOAM<u16>(addr);
|
2017-01-18 16:57:12 +00:00
|
|
|
|
|
|
|
case 0x08000000:
|
|
|
|
case 0x09000000:
|
2019-12-08 17:32:59 +00:00
|
|
|
if (ExMemCnt[0] & (1<<7)) return 0x0000; // deselected CPU is 00h-filled
|
2021-04-24 22:48:02 +00:00
|
|
|
return GBACart::ROMRead(addr);
|
2018-12-12 18:43:29 +00:00
|
|
|
|
|
|
|
case 0x0A000000:
|
2019-12-08 17:32:59 +00:00
|
|
|
if (ExMemCnt[0] & (1<<7)) return 0x0000; // deselected CPU is 00h-filled
|
2021-04-24 22:48:02 +00:00
|
|
|
return GBACart::SRAMRead(addr) |
|
|
|
|
(GBACart::SRAMRead(addr+1) << 8);
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
|
|
|
|
2021-08-31 00:28:34 +00:00
|
|
|
//if (addr) printf("unknown arm9 read16 %08X %08X\n", addr, ARM9->R[15]);
|
2018-12-08 21:33:41 +00:00
|
|
|
return 0;
|
2016-12-03 00:31:33 +00:00
|
|
|
}
|
2016-11-03 00:38:58 +00:00
|
|
|
|
2018-12-09 00:17:05 +00:00
|
|
|
u32 ARM9Read32(u32 addr)
|
2016-12-03 00:31:33 +00:00
|
|
|
{
|
2016-11-03 00:38:58 +00:00
|
|
|
if ((addr & 0xFFFFF000) == 0xFFFF0000)
|
|
|
|
{
|
2018-12-08 21:33:41 +00:00
|
|
|
return *(u32*)&ARM9BIOS[addr & 0xFFF];
|
2016-11-03 00:38:58 +00:00
|
|
|
}
|
2016-12-05 16:08:24 +00:00
|
|
|
|
2016-12-03 12:42:27 +00:00
|
|
|
switch (addr & 0xFF000000)
|
|
|
|
{
|
|
|
|
case 0x02000000:
|
2019-08-05 17:52:03 +00:00
|
|
|
return *(u32*)&MainRAM[addr & MainRAMMask];
|
2016-12-03 17:29:19 +00:00
|
|
|
|
|
|
|
case 0x03000000:
|
2020-06-14 19:04:25 +00:00
|
|
|
if (SWRAM_ARM9.Mem)
|
2018-12-04 16:54:10 +00:00
|
|
|
{
|
2020-06-14 19:04:25 +00:00
|
|
|
return *(u32*)&SWRAM_ARM9.Mem[addr & SWRAM_ARM9.Mask];
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-12-08 21:33:41 +00:00
|
|
|
return 0;
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
2016-12-04 02:20:50 +00:00
|
|
|
|
|
|
|
case 0x04000000:
|
2018-12-08 21:33:41 +00:00
|
|
|
return ARM9IORead32(addr);
|
2016-12-05 16:08:24 +00:00
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x05000000:
|
2018-12-18 16:04:42 +00:00
|
|
|
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
|
2020-12-23 08:23:46 +00:00
|
|
|
return GPU::ReadPalette<u32>(addr);
|
2016-12-06 16:32:51 +00:00
|
|
|
|
2016-12-05 22:17:03 +00:00
|
|
|
case 0x06000000:
|
2018-12-04 16:54:10 +00:00
|
|
|
switch (addr & 0x00E00000)
|
2016-12-05 22:17:03 +00:00
|
|
|
{
|
2018-12-08 21:33:41 +00:00
|
|
|
case 0x00000000: return GPU::ReadVRAM_ABG<u32>(addr);
|
|
|
|
case 0x00200000: return GPU::ReadVRAM_BBG<u32>(addr);
|
|
|
|
case 0x00400000: return GPU::ReadVRAM_AOBJ<u32>(addr);
|
|
|
|
case 0x00600000: return GPU::ReadVRAM_BOBJ<u32>(addr);
|
|
|
|
default: return GPU::ReadVRAM_LCDC<u32>(addr);
|
2016-12-05 22:17:03 +00:00
|
|
|
}
|
2016-12-06 16:32:51 +00:00
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x07000000:
|
2018-12-18 16:04:42 +00:00
|
|
|
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
|
2020-12-23 08:23:46 +00:00
|
|
|
return GPU::ReadOAM<u32>(addr & 0x7FF);
|
2017-01-18 16:57:12 +00:00
|
|
|
|
|
|
|
case 0x08000000:
|
|
|
|
case 0x09000000:
|
2019-12-08 17:32:59 +00:00
|
|
|
if (ExMemCnt[0] & (1<<7)) return 0x00000000; // deselected CPU is 00h-filled
|
2021-04-24 22:48:02 +00:00
|
|
|
return GBACart::ROMRead(addr) |
|
|
|
|
(GBACart::ROMRead(addr+2) << 16);
|
2018-12-12 18:43:29 +00:00
|
|
|
|
|
|
|
case 0x0A000000:
|
2019-12-08 17:32:59 +00:00
|
|
|
if (ExMemCnt[0] & (1<<7)) return 0x00000000; // deselected CPU is 00h-filled
|
2021-04-24 22:48:02 +00:00
|
|
|
return GBACart::SRAMRead(addr) |
|
|
|
|
(GBACart::SRAMRead(addr+1) << 8) |
|
|
|
|
(GBACart::SRAMRead(addr+2) << 16) |
|
|
|
|
(GBACart::SRAMRead(addr+3) << 24);
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
|
|
|
|
2021-08-31 00:28:34 +00:00
|
|
|
//printf("unknown arm9 read32 %08X | %08X %08X\n", addr, ARM9->R[15], ARM9->R[12]);
|
2018-12-08 21:33:41 +00:00
|
|
|
return 0;
|
2016-05-16 15:48:40 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
void ARM9Write8(u32 addr, u8 val)
|
2016-12-03 00:31:33 +00:00
|
|
|
{
|
2016-12-03 12:42:27 +00:00
|
|
|
switch (addr & 0xFF000000)
|
|
|
|
{
|
|
|
|
case 0x02000000:
|
2020-05-08 22:45:05 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-14 19:04:25 +00:00
|
|
|
ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_MainRAM>(addr);
|
2020-05-08 22:45:05 +00:00
|
|
|
#endif
|
2019-08-05 17:52:03 +00:00
|
|
|
*(u8*)&MainRAM[addr & MainRAMMask] = val;
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2016-12-03 17:29:19 +00:00
|
|
|
|
|
|
|
case 0x03000000:
|
2020-06-14 19:04:25 +00:00
|
|
|
if (SWRAM_ARM9.Mem)
|
2018-12-04 16:54:10 +00:00
|
|
|
{
|
2020-05-08 22:45:05 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-30 21:50:41 +00:00
|
|
|
ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_SharedWRAM>(addr);
|
2020-05-08 22:45:05 +00:00
|
|
|
#endif
|
2020-06-14 19:04:25 +00:00
|
|
|
*(u8*)&SWRAM_ARM9.Mem[addr & SWRAM_ARM9.Mask] = val;
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2016-12-03 17:29:19 +00:00
|
|
|
|
|
|
|
case 0x04000000:
|
2017-01-17 01:29:25 +00:00
|
|
|
ARM9IOWrite8(addr, val);
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2016-12-06 16:32:51 +00:00
|
|
|
|
|
|
|
case 0x05000000:
|
|
|
|
case 0x06000000:
|
|
|
|
case 0x07000000:
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2019-12-08 22:56:22 +00:00
|
|
|
|
2019-12-10 23:44:53 +00:00
|
|
|
case 0x08000000:
|
|
|
|
case 0x09000000:
|
2021-04-24 22:48:02 +00:00
|
|
|
return;
|
2019-12-10 23:44:53 +00:00
|
|
|
|
2019-12-08 22:56:22 +00:00
|
|
|
case 0x0A000000:
|
|
|
|
if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write
|
2021-04-24 22:48:02 +00:00
|
|
|
GBACart::SRAMWrite(addr, val);
|
2019-12-08 22:56:22 +00:00
|
|
|
return;
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
|
|
|
|
2016-12-03 00:31:33 +00:00
|
|
|
printf("unknown arm9 write8 %08X %02X\n", addr, val);
|
|
|
|
}
|
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
void ARM9Write16(u32 addr, u16 val)
|
2016-12-03 00:31:33 +00:00
|
|
|
{
|
2016-12-03 12:42:27 +00:00
|
|
|
switch (addr & 0xFF000000)
|
|
|
|
{
|
|
|
|
case 0x02000000:
|
2020-05-08 22:45:05 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-14 19:04:25 +00:00
|
|
|
ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_MainRAM>(addr);
|
2020-05-08 22:45:05 +00:00
|
|
|
#endif
|
2019-08-05 17:52:03 +00:00
|
|
|
*(u16*)&MainRAM[addr & MainRAMMask] = val;
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2016-12-03 15:13:04 +00:00
|
|
|
|
2016-12-03 17:29:19 +00:00
|
|
|
case 0x03000000:
|
2020-06-14 19:04:25 +00:00
|
|
|
if (SWRAM_ARM9.Mem)
|
2018-12-04 16:54:10 +00:00
|
|
|
{
|
2020-05-08 22:45:05 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-30 21:50:41 +00:00
|
|
|
ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_SharedWRAM>(addr);
|
2020-05-08 22:45:05 +00:00
|
|
|
#endif
|
2020-06-14 19:04:25 +00:00
|
|
|
*(u16*)&SWRAM_ARM9.Mem[addr & SWRAM_ARM9.Mask] = val;
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2016-12-03 17:29:19 +00:00
|
|
|
|
2016-12-03 15:13:04 +00:00
|
|
|
case 0x04000000:
|
2017-01-17 01:29:25 +00:00
|
|
|
ARM9IOWrite16(addr, val);
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2016-12-05 22:17:03 +00:00
|
|
|
|
2016-12-06 16:32:51 +00:00
|
|
|
case 0x05000000:
|
2018-12-18 16:04:42 +00:00
|
|
|
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return;
|
2020-12-23 08:23:46 +00:00
|
|
|
GPU::WritePalette<u16>(addr, val);
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2016-12-06 16:32:51 +00:00
|
|
|
|
2016-12-05 22:17:03 +00:00
|
|
|
case 0x06000000:
|
2020-06-14 19:04:25 +00:00
|
|
|
#ifdef JIT_ENABLED
|
|
|
|
ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_VRAM>(addr);
|
|
|
|
#endif
|
2017-02-27 20:26:11 +00:00
|
|
|
switch (addr & 0x00E00000)
|
2016-12-05 22:17:03 +00:00
|
|
|
{
|
2018-12-08 21:33:41 +00:00
|
|
|
case 0x00000000: GPU::WriteVRAM_ABG<u16>(addr, val); return;
|
|
|
|
case 0x00200000: GPU::WriteVRAM_BBG<u16>(addr, val); return;
|
|
|
|
case 0x00400000: GPU::WriteVRAM_AOBJ<u16>(addr, val); return;
|
|
|
|
case 0x00600000: GPU::WriteVRAM_BOBJ<u16>(addr, val); return;
|
2020-06-14 19:04:25 +00:00
|
|
|
default: GPU::WriteVRAM_LCDC<u16>(addr, val); return;
|
2016-12-05 22:17:03 +00:00
|
|
|
}
|
2016-12-06 16:32:51 +00:00
|
|
|
|
|
|
|
case 0x07000000:
|
2018-12-18 16:04:42 +00:00
|
|
|
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return;
|
2020-12-23 08:23:46 +00:00
|
|
|
GPU::WriteOAM<u16>(addr, val);
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2019-12-08 22:56:22 +00:00
|
|
|
|
2019-12-10 23:44:53 +00:00
|
|
|
case 0x08000000:
|
|
|
|
case 0x09000000:
|
|
|
|
if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write
|
2021-04-24 22:48:02 +00:00
|
|
|
GBACart::ROMWrite(addr, val);
|
|
|
|
return;
|
2019-12-10 23:44:53 +00:00
|
|
|
|
2019-12-08 22:56:22 +00:00
|
|
|
case 0x0A000000:
|
|
|
|
if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write
|
2021-04-24 22:48:02 +00:00
|
|
|
GBACart::SRAMWrite(addr, val & 0xFF);
|
|
|
|
GBACart::SRAMWrite(addr+1, val >> 8);
|
2019-12-08 22:56:22 +00:00
|
|
|
return;
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
|
|
|
|
2021-08-31 00:28:34 +00:00
|
|
|
//if (addr) printf("unknown arm9 write16 %08X %04X\n", addr, val);
|
2016-12-03 00:31:33 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
void ARM9Write32(u32 addr, u32 val)
|
2018-12-18 01:00:50 +00:00
|
|
|
{
|
2016-12-03 12:42:27 +00:00
|
|
|
switch (addr & 0xFF000000)
|
|
|
|
{
|
|
|
|
case 0x02000000:
|
2020-05-08 22:45:05 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-14 19:04:25 +00:00
|
|
|
ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_MainRAM>(addr);
|
2020-05-08 22:45:05 +00:00
|
|
|
#endif
|
2019-08-05 17:52:03 +00:00
|
|
|
*(u32*)&MainRAM[addr & MainRAMMask] = val;
|
2018-12-08 21:33:41 +00:00
|
|
|
return ;
|
2016-12-03 17:29:19 +00:00
|
|
|
|
|
|
|
case 0x03000000:
|
2020-06-14 19:04:25 +00:00
|
|
|
if (SWRAM_ARM9.Mem)
|
2018-12-04 16:54:10 +00:00
|
|
|
{
|
2020-05-08 22:45:05 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-30 21:50:41 +00:00
|
|
|
ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_SharedWRAM>(addr);
|
2020-05-08 22:45:05 +00:00
|
|
|
#endif
|
2020-06-14 19:04:25 +00:00
|
|
|
*(u32*)&SWRAM_ARM9.Mem[addr & SWRAM_ARM9.Mask] = val;
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2016-12-04 02:20:50 +00:00
|
|
|
|
|
|
|
case 0x04000000:
|
2017-01-17 01:29:25 +00:00
|
|
|
ARM9IOWrite32(addr, val);
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2016-12-05 22:17:03 +00:00
|
|
|
|
2016-12-06 16:32:51 +00:00
|
|
|
case 0x05000000:
|
2018-12-18 16:04:42 +00:00
|
|
|
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return;
|
2020-12-23 08:23:46 +00:00
|
|
|
GPU::WritePalette(addr, val);
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2016-12-06 16:32:51 +00:00
|
|
|
|
2016-12-05 22:17:03 +00:00
|
|
|
case 0x06000000:
|
2020-06-14 19:04:25 +00:00
|
|
|
#ifdef JIT_ENABLED
|
|
|
|
ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_VRAM>(addr);
|
|
|
|
#endif
|
2017-02-27 20:26:11 +00:00
|
|
|
switch (addr & 0x00E00000)
|
2016-12-05 22:17:03 +00:00
|
|
|
{
|
2018-12-08 21:33:41 +00:00
|
|
|
case 0x00000000: GPU::WriteVRAM_ABG<u32>(addr, val); return;
|
|
|
|
case 0x00200000: GPU::WriteVRAM_BBG<u32>(addr, val); return;
|
|
|
|
case 0x00400000: GPU::WriteVRAM_AOBJ<u32>(addr, val); return;
|
|
|
|
case 0x00600000: GPU::WriteVRAM_BOBJ<u32>(addr, val); return;
|
2020-06-14 19:04:25 +00:00
|
|
|
default: GPU::WriteVRAM_LCDC<u32>(addr, val); return;
|
2016-12-05 22:17:03 +00:00
|
|
|
}
|
2016-12-06 16:32:51 +00:00
|
|
|
|
|
|
|
case 0x07000000:
|
2018-12-18 16:04:42 +00:00
|
|
|
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return;
|
2020-12-23 08:23:46 +00:00
|
|
|
GPU::WriteOAM<u32>(addr, val);
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2019-12-08 22:56:22 +00:00
|
|
|
|
2019-12-10 23:44:53 +00:00
|
|
|
case 0x08000000:
|
|
|
|
case 0x09000000:
|
|
|
|
if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write
|
2021-04-24 22:48:02 +00:00
|
|
|
GBACart::ROMWrite(addr, val & 0xFFFF);
|
|
|
|
GBACart::ROMWrite(addr+2, val >> 16);
|
|
|
|
return;
|
2019-12-10 23:44:53 +00:00
|
|
|
|
2019-12-08 22:56:22 +00:00
|
|
|
case 0x0A000000:
|
|
|
|
if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write
|
2021-04-24 22:48:02 +00:00
|
|
|
GBACart::SRAMWrite(addr, val & 0xFF);
|
|
|
|
GBACart::SRAMWrite(addr+1, (val >> 8) & 0xFF);
|
|
|
|
GBACart::SRAMWrite(addr+2, (val >> 16) & 0xFF);
|
|
|
|
GBACart::SRAMWrite(addr+3, val >> 24);
|
2019-12-08 22:56:22 +00:00
|
|
|
return;
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
|
|
|
|
2021-08-31 00:28:34 +00:00
|
|
|
//printf("unknown arm9 write32 %08X %08X | %08X\n", addr, val, ARM9->R[15]);
|
2016-12-03 00:31:33 +00:00
|
|
|
}
|
|
|
|
|
2018-11-04 22:21:58 +00:00
|
|
|
bool ARM9GetMemRegion(u32 addr, bool write, MemRegion* region)
|
|
|
|
{
|
|
|
|
switch (addr & 0xFF000000)
|
|
|
|
{
|
|
|
|
case 0x02000000:
|
|
|
|
region->Mem = MainRAM;
|
2019-08-05 17:52:03 +00:00
|
|
|
region->Mask = MainRAMMask;
|
2018-11-04 22:21:58 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
case 0x03000000:
|
2020-06-14 19:04:25 +00:00
|
|
|
if (SWRAM_ARM9.Mem)
|
2018-11-04 22:21:58 +00:00
|
|
|
{
|
2020-06-14 19:04:25 +00:00
|
|
|
region->Mem = SWRAM_ARM9.Mem;
|
|
|
|
region->Mask = SWRAM_ARM9.Mask;
|
2018-11-04 22:21:58 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((addr & 0xFFFFF000) == 0xFFFF0000 && !write)
|
|
|
|
{
|
|
|
|
region->Mem = ARM9BIOS;
|
|
|
|
region->Mask = 0xFFF;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
region->Mem = NULL;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-12-03 00:31:33 +00:00
|
|
|
|
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
u8 ARM7Read8(u32 addr)
|
2016-12-03 00:31:33 +00:00
|
|
|
{
|
|
|
|
if (addr < 0x00004000)
|
|
|
|
{
|
2019-06-13 12:41:54 +00:00
|
|
|
// TODO: check the boundary? is it 4000 or higher on regular DS?
|
2019-08-05 17:52:03 +00:00
|
|
|
if (ARM7->R[15] >= 0x00004000)
|
2018-12-08 21:33:41 +00:00
|
|
|
return 0xFF;
|
2017-02-05 16:15:17 +00:00
|
|
|
if (addr < ARM7BIOSProt && ARM7->R[15] >= ARM7BIOSProt)
|
2018-12-08 21:33:41 +00:00
|
|
|
return 0xFF;
|
2017-02-05 16:15:17 +00:00
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
return *(u8*)&ARM7BIOS[addr];
|
2016-12-03 00:31:33 +00:00
|
|
|
}
|
|
|
|
|
2016-12-03 12:42:27 +00:00
|
|
|
switch (addr & 0xFF800000)
|
|
|
|
{
|
|
|
|
case 0x02000000:
|
2017-02-01 20:35:00 +00:00
|
|
|
case 0x02800000:
|
2019-08-05 17:52:03 +00:00
|
|
|
return *(u8*)&MainRAM[addr & MainRAMMask];
|
2016-12-03 12:42:27 +00:00
|
|
|
|
2016-12-03 17:29:19 +00:00
|
|
|
case 0x03000000:
|
2020-06-14 19:04:25 +00:00
|
|
|
if (SWRAM_ARM7.Mem)
|
2018-12-04 16:54:10 +00:00
|
|
|
{
|
2020-06-14 19:04:25 +00:00
|
|
|
return *(u8*)&SWRAM_ARM7.Mem[addr & SWRAM_ARM7.Mask];
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-06-14 19:04:25 +00:00
|
|
|
return *(u8*)&ARM7WRAM[addr & (ARM7WRAMSize - 1)];
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
2016-12-03 17:29:19 +00:00
|
|
|
|
2016-12-03 12:42:27 +00:00
|
|
|
case 0x03800000:
|
2020-06-14 19:04:25 +00:00
|
|
|
return *(u8*)&ARM7WRAM[addr & (ARM7WRAMSize - 1)];
|
2016-12-03 17:29:19 +00:00
|
|
|
|
|
|
|
case 0x04000000:
|
2018-12-08 21:33:41 +00:00
|
|
|
return ARM7IORead8(addr);
|
2016-12-05 22:17:03 +00:00
|
|
|
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x04800000:
|
|
|
|
if (addr < 0x04810000)
|
|
|
|
{
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
if (!(PowerControl7 & (1<<1))) return 0;
|
2021-04-24 22:48:02 +00:00
|
|
|
if (addr & 0x1) return Wifi::Read(addr-1) >> 8;
|
|
|
|
return Wifi::Read(addr) & 0xFF;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2016-12-05 22:17:03 +00:00
|
|
|
case 0x06000000:
|
|
|
|
case 0x06800000:
|
2018-12-08 21:33:41 +00:00
|
|
|
return GPU::ReadVRAM_ARM7<u8>(addr);
|
2018-12-12 18:43:29 +00:00
|
|
|
|
|
|
|
case 0x08000000:
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x08800000:
|
2018-12-12 18:43:29 +00:00
|
|
|
case 0x09000000:
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x09800000:
|
2019-12-08 17:32:59 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<7))) return 0x00; // deselected CPU is 00h-filled
|
2021-04-24 22:48:02 +00:00
|
|
|
if (addr & 0x1) return GBACart::ROMRead(addr-1) >> 8;
|
|
|
|
return GBACart::ROMRead(addr) & 0xFF;
|
2018-12-12 18:43:29 +00:00
|
|
|
|
|
|
|
case 0x0A000000:
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x0A800000:
|
2019-12-08 17:32:59 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<7))) return 0x00; // deselected CPU is 00h-filled
|
2021-04-24 22:48:02 +00:00
|
|
|
return GBACart::SRAMRead(addr);
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
|
|
|
|
2017-01-18 00:33:06 +00:00
|
|
|
printf("unknown arm7 read8 %08X %08X %08X/%08X\n", addr, ARM7->R[15], ARM7->R[0], ARM7->R[1]);
|
2018-12-08 21:33:41 +00:00
|
|
|
return 0;
|
2016-12-03 00:31:33 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
u16 ARM7Read16(u32 addr)
|
2016-12-03 00:31:33 +00:00
|
|
|
{
|
|
|
|
if (addr < 0x00004000)
|
|
|
|
{
|
2019-08-05 17:52:03 +00:00
|
|
|
if (ARM7->R[15] >= 0x00004000)
|
2018-12-08 21:33:41 +00:00
|
|
|
return 0xFFFF;
|
2017-02-05 16:15:17 +00:00
|
|
|
if (addr < ARM7BIOSProt && ARM7->R[15] >= ARM7BIOSProt)
|
2018-12-08 21:33:41 +00:00
|
|
|
return 0xFFFF;
|
2017-02-05 16:15:17 +00:00
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
return *(u16*)&ARM7BIOS[addr];
|
2016-12-03 00:31:33 +00:00
|
|
|
}
|
|
|
|
|
2016-12-03 12:42:27 +00:00
|
|
|
switch (addr & 0xFF800000)
|
|
|
|
{
|
|
|
|
case 0x02000000:
|
2017-02-01 20:35:00 +00:00
|
|
|
case 0x02800000:
|
2019-08-05 17:52:03 +00:00
|
|
|
return *(u16*)&MainRAM[addr & MainRAMMask];
|
2016-12-03 12:42:27 +00:00
|
|
|
|
2016-12-03 17:29:19 +00:00
|
|
|
case 0x03000000:
|
2020-06-14 19:04:25 +00:00
|
|
|
if (SWRAM_ARM7.Mem)
|
2018-12-04 16:54:10 +00:00
|
|
|
{
|
2020-06-14 19:04:25 +00:00
|
|
|
return *(u16*)&SWRAM_ARM7.Mem[addr & SWRAM_ARM7.Mask];
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-06-14 19:04:25 +00:00
|
|
|
return *(u16*)&ARM7WRAM[addr & (ARM7WRAMSize - 1)];
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
2016-12-03 17:29:19 +00:00
|
|
|
|
2016-12-03 12:42:27 +00:00
|
|
|
case 0x03800000:
|
2020-06-14 19:04:25 +00:00
|
|
|
return *(u16*)&ARM7WRAM[addr & (ARM7WRAMSize - 1)];
|
2016-12-03 15:13:04 +00:00
|
|
|
|
|
|
|
case 0x04000000:
|
2018-12-08 21:33:41 +00:00
|
|
|
return ARM7IORead16(addr);
|
2016-12-05 22:17:03 +00:00
|
|
|
|
|
|
|
case 0x04800000:
|
2018-12-04 16:54:10 +00:00
|
|
|
if (addr < 0x04810000)
|
|
|
|
{
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
if (!(PowerControl7 & (1<<1))) return 0;
|
2018-12-08 21:33:41 +00:00
|
|
|
return Wifi::Read(addr);
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
|
|
|
break;
|
2016-12-05 22:17:03 +00:00
|
|
|
|
|
|
|
case 0x06000000:
|
|
|
|
case 0x06800000:
|
2018-12-08 21:33:41 +00:00
|
|
|
return GPU::ReadVRAM_ARM7<u16>(addr);
|
2018-12-12 18:43:29 +00:00
|
|
|
|
|
|
|
case 0x08000000:
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x08800000:
|
2018-12-12 18:43:29 +00:00
|
|
|
case 0x09000000:
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x09800000:
|
2019-12-08 17:32:59 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<7))) return 0x0000; // deselected CPU is 00h-filled
|
2021-04-24 22:48:02 +00:00
|
|
|
return GBACart::ROMRead(addr);
|
2018-12-12 18:43:29 +00:00
|
|
|
|
|
|
|
case 0x0A000000:
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x0A800000:
|
2019-12-08 17:32:59 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<7))) return 0x0000; // deselected CPU is 00h-filled
|
2021-04-24 22:48:02 +00:00
|
|
|
return GBACart::SRAMRead(addr) |
|
|
|
|
(GBACart::SRAMRead(addr+1) << 8);
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
|
|
|
|
2016-12-05 16:08:24 +00:00
|
|
|
printf("unknown arm7 read16 %08X %08X\n", addr, ARM7->R[15]);
|
2018-12-08 21:33:41 +00:00
|
|
|
return 0;
|
2016-12-03 00:31:33 +00:00
|
|
|
}
|
|
|
|
|
2018-12-09 00:17:05 +00:00
|
|
|
u32 ARM7Read32(u32 addr)
|
2016-11-03 00:38:58 +00:00
|
|
|
{
|
|
|
|
if (addr < 0x00004000)
|
|
|
|
{
|
2019-08-05 17:52:03 +00:00
|
|
|
if (ARM7->R[15] >= 0x00004000)
|
2018-12-08 21:33:41 +00:00
|
|
|
return 0xFFFFFFFF;
|
2017-02-05 16:15:17 +00:00
|
|
|
if (addr < ARM7BIOSProt && ARM7->R[15] >= ARM7BIOSProt)
|
2018-12-08 21:33:41 +00:00
|
|
|
return 0xFFFFFFFF;
|
2017-02-05 16:15:17 +00:00
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
return *(u32*)&ARM7BIOS[addr];
|
2016-11-03 00:38:58 +00:00
|
|
|
}
|
|
|
|
|
2016-12-03 12:42:27 +00:00
|
|
|
switch (addr & 0xFF800000)
|
|
|
|
{
|
|
|
|
case 0x02000000:
|
2017-02-01 20:35:00 +00:00
|
|
|
case 0x02800000:
|
2019-08-05 17:52:03 +00:00
|
|
|
return *(u32*)&MainRAM[addr & MainRAMMask];
|
2016-12-03 12:42:27 +00:00
|
|
|
|
2016-12-03 17:29:19 +00:00
|
|
|
case 0x03000000:
|
2020-06-14 19:04:25 +00:00
|
|
|
if (SWRAM_ARM7.Mem)
|
2018-12-04 16:54:10 +00:00
|
|
|
{
|
2020-06-14 19:04:25 +00:00
|
|
|
return *(u32*)&SWRAM_ARM7.Mem[addr & SWRAM_ARM7.Mask];
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-06-14 19:04:25 +00:00
|
|
|
return *(u32*)&ARM7WRAM[addr & (ARM7WRAMSize - 1)];
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
2016-12-03 17:29:19 +00:00
|
|
|
|
2016-12-03 12:42:27 +00:00
|
|
|
case 0x03800000:
|
2020-06-14 19:04:25 +00:00
|
|
|
return *(u32*)&ARM7WRAM[addr & (ARM7WRAMSize - 1)];
|
2016-12-03 17:29:19 +00:00
|
|
|
|
|
|
|
case 0x04000000:
|
2018-12-08 21:33:41 +00:00
|
|
|
return ARM7IORead32(addr);
|
2016-12-05 22:17:03 +00:00
|
|
|
|
2017-05-01 17:29:25 +00:00
|
|
|
case 0x04800000:
|
2018-12-04 16:54:10 +00:00
|
|
|
if (addr < 0x04810000)
|
|
|
|
{
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
if (!(PowerControl7 & (1<<1))) return 0;
|
2018-12-08 21:33:41 +00:00
|
|
|
return Wifi::Read(addr) | (Wifi::Read(addr+2) << 16);
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
|
|
|
break;
|
2017-05-01 17:29:25 +00:00
|
|
|
|
2016-12-05 22:17:03 +00:00
|
|
|
case 0x06000000:
|
|
|
|
case 0x06800000:
|
2018-12-08 21:33:41 +00:00
|
|
|
return GPU::ReadVRAM_ARM7<u32>(addr);
|
2018-12-12 18:43:29 +00:00
|
|
|
|
|
|
|
case 0x08000000:
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x08800000:
|
2018-12-12 18:43:29 +00:00
|
|
|
case 0x09000000:
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x09800000:
|
2019-12-08 17:32:59 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<7))) return 0x00000000; // deselected CPU is 00h-filled
|
2021-04-24 22:48:02 +00:00
|
|
|
return GBACart::ROMRead(addr) |
|
|
|
|
(GBACart::ROMRead(addr+2) << 16);
|
2018-12-12 18:43:29 +00:00
|
|
|
|
|
|
|
case 0x0A000000:
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x0A800000:
|
2019-12-08 17:32:59 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<7))) return 0x00000000; // deselected CPU is 00h-filled
|
2021-04-24 22:48:02 +00:00
|
|
|
return GBACart::SRAMRead(addr) |
|
|
|
|
(GBACart::SRAMRead(addr+1) << 8) |
|
|
|
|
(GBACart::SRAMRead(addr+2) << 16) |
|
|
|
|
(GBACart::SRAMRead(addr+3) << 24);
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
2016-12-05 16:08:24 +00:00
|
|
|
|
2021-11-25 15:49:43 +00:00
|
|
|
//printf("unknown arm7 read32 %08X | %08X\n", addr, ARM7->R[15]);
|
2018-12-08 21:33:41 +00:00
|
|
|
return 0;
|
2016-11-03 00:38:58 +00:00
|
|
|
}
|
2016-05-16 15:48:40 +00:00
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
void ARM7Write8(u32 addr, u8 val)
|
2016-12-03 00:31:33 +00:00
|
|
|
{
|
2016-12-03 12:42:27 +00:00
|
|
|
switch (addr & 0xFF800000)
|
|
|
|
{
|
|
|
|
case 0x02000000:
|
2017-02-01 20:35:00 +00:00
|
|
|
case 0x02800000:
|
2020-05-08 22:45:05 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-14 19:04:25 +00:00
|
|
|
ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_MainRAM>(addr);
|
2020-05-08 22:45:05 +00:00
|
|
|
#endif
|
2019-08-05 17:52:03 +00:00
|
|
|
*(u8*)&MainRAM[addr & MainRAMMask] = val;
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2016-12-03 12:42:27 +00:00
|
|
|
|
2016-12-03 17:29:19 +00:00
|
|
|
case 0x03000000:
|
2020-06-14 19:04:25 +00:00
|
|
|
if (SWRAM_ARM7.Mem)
|
2018-12-04 16:54:10 +00:00
|
|
|
{
|
2020-05-08 22:45:05 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-30 21:50:41 +00:00
|
|
|
ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_SharedWRAM>(addr);
|
2020-05-08 22:45:05 +00:00
|
|
|
#endif
|
2020-06-14 19:04:25 +00:00
|
|
|
*(u8*)&SWRAM_ARM7.Mem[addr & SWRAM_ARM7.Mask] = val;
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-05-08 22:45:05 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-14 19:04:25 +00:00
|
|
|
ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr);
|
2020-05-08 22:45:05 +00:00
|
|
|
#endif
|
2020-06-14 19:04:25 +00:00
|
|
|
*(u8*)&ARM7WRAM[addr & (ARM7WRAMSize - 1)] = val;
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
2016-12-03 17:29:19 +00:00
|
|
|
|
2016-12-03 12:42:27 +00:00
|
|
|
case 0x03800000:
|
2020-05-08 22:45:05 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-14 19:04:25 +00:00
|
|
|
ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr);
|
2020-05-08 22:45:05 +00:00
|
|
|
#endif
|
2020-06-14 19:04:25 +00:00
|
|
|
*(u8*)&ARM7WRAM[addr & (ARM7WRAMSize - 1)] = val;
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2016-12-04 02:20:50 +00:00
|
|
|
|
|
|
|
case 0x04000000:
|
2017-01-17 01:29:25 +00:00
|
|
|
ARM7IOWrite8(addr, val);
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2016-12-05 22:17:03 +00:00
|
|
|
|
|
|
|
case 0x06000000:
|
|
|
|
case 0x06800000:
|
2020-05-08 22:45:05 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-14 19:04:25 +00:00
|
|
|
ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_VWRAM>(addr);
|
2020-05-08 22:45:05 +00:00
|
|
|
#endif
|
2017-02-27 20:26:11 +00:00
|
|
|
GPU::WriteVRAM_ARM7<u8>(addr, val);
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2019-12-08 22:56:22 +00:00
|
|
|
|
2019-12-10 23:44:53 +00:00
|
|
|
case 0x08000000:
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x08800000:
|
2019-12-10 23:44:53 +00:00
|
|
|
case 0x09000000:
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x09800000:
|
|
|
|
return;
|
2019-12-10 23:44:53 +00:00
|
|
|
|
2019-12-08 22:56:22 +00:00
|
|
|
case 0x0A000000:
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x0A800000:
|
2019-12-08 22:56:22 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write
|
2021-04-24 22:48:02 +00:00
|
|
|
GBACart::SRAMWrite(addr, val);
|
2019-12-08 22:56:22 +00:00
|
|
|
return;
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
|
|
|
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
//if (ARM7->R[15] > 0x00002F30) // ARM7 BIOS bug
|
|
|
|
if (addr >= 0x01000000)
|
2020-09-03 18:28:07 +00:00
|
|
|
printf("unknown arm7 write8 %08X %02X @ %08X\n", addr, val, ARM7->R[15]);
|
2016-12-03 00:31:33 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
void ARM7Write16(u32 addr, u16 val)
|
2017-06-12 23:01:46 +00:00
|
|
|
{
|
2016-12-03 12:42:27 +00:00
|
|
|
switch (addr & 0xFF800000)
|
|
|
|
{
|
|
|
|
case 0x02000000:
|
2017-02-01 20:35:00 +00:00
|
|
|
case 0x02800000:
|
2020-05-08 22:45:05 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-14 19:04:25 +00:00
|
|
|
ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_MainRAM>(addr);
|
2020-05-08 22:45:05 +00:00
|
|
|
#endif
|
2019-08-05 17:52:03 +00:00
|
|
|
*(u16*)&MainRAM[addr & MainRAMMask] = val;
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2016-12-03 12:42:27 +00:00
|
|
|
|
2016-12-03 17:29:19 +00:00
|
|
|
case 0x03000000:
|
2020-06-14 19:04:25 +00:00
|
|
|
if (SWRAM_ARM7.Mem)
|
2018-12-04 16:54:10 +00:00
|
|
|
{
|
2020-05-08 22:45:05 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-30 21:50:41 +00:00
|
|
|
ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_SharedWRAM>(addr);
|
2020-05-08 22:45:05 +00:00
|
|
|
#endif
|
2020-06-14 19:04:25 +00:00
|
|
|
*(u16*)&SWRAM_ARM7.Mem[addr & SWRAM_ARM7.Mask] = val;
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-05-08 22:45:05 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-14 19:04:25 +00:00
|
|
|
ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr);
|
2020-05-08 22:45:05 +00:00
|
|
|
#endif
|
2020-06-14 19:04:25 +00:00
|
|
|
*(u16*)&ARM7WRAM[addr & (ARM7WRAMSize - 1)] = val;
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
2016-12-03 17:29:19 +00:00
|
|
|
|
2016-12-03 12:42:27 +00:00
|
|
|
case 0x03800000:
|
2020-05-08 22:45:05 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-14 19:04:25 +00:00
|
|
|
ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr);
|
2020-05-08 22:45:05 +00:00
|
|
|
#endif
|
2020-06-14 19:04:25 +00:00
|
|
|
*(u16*)&ARM7WRAM[addr & (ARM7WRAMSize - 1)] = val;
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2016-12-03 15:13:04 +00:00
|
|
|
|
|
|
|
case 0x04000000:
|
2017-01-17 01:29:25 +00:00
|
|
|
ARM7IOWrite16(addr, val);
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2016-12-05 22:17:03 +00:00
|
|
|
|
|
|
|
case 0x04800000:
|
2018-12-04 16:54:10 +00:00
|
|
|
if (addr < 0x04810000)
|
|
|
|
{
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
if (!(PowerControl7 & (1<<1))) return;
|
2018-12-04 16:54:10 +00:00
|
|
|
Wifi::Write(addr, val);
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
|
|
|
break;
|
2016-12-05 22:17:03 +00:00
|
|
|
|
|
|
|
case 0x06000000:
|
|
|
|
case 0x06800000:
|
2020-05-08 22:45:05 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-14 19:04:25 +00:00
|
|
|
ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_VWRAM>(addr);
|
2020-05-08 22:45:05 +00:00
|
|
|
#endif
|
2017-02-27 20:26:11 +00:00
|
|
|
GPU::WriteVRAM_ARM7<u16>(addr, val);
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2019-12-08 22:56:22 +00:00
|
|
|
|
2019-12-10 23:44:53 +00:00
|
|
|
case 0x08000000:
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x08800000:
|
2019-12-10 23:44:53 +00:00
|
|
|
case 0x09000000:
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x09800000:
|
2019-12-10 23:44:53 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write
|
2021-04-24 22:48:02 +00:00
|
|
|
GBACart::ROMWrite(addr, val);
|
|
|
|
return;
|
2019-12-10 23:44:53 +00:00
|
|
|
|
2019-12-08 22:56:22 +00:00
|
|
|
case 0x0A000000:
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x0A800000:
|
2019-12-08 22:56:22 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write
|
2021-04-24 22:48:02 +00:00
|
|
|
GBACart::SRAMWrite(addr, val & 0xFF);
|
|
|
|
GBACart::SRAMWrite(addr+1, val >> 8);
|
2019-12-08 22:56:22 +00:00
|
|
|
return;
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
|
|
|
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
if (addr >= 0x01000000)
|
|
|
|
printf("unknown arm7 write16 %08X %04X @ %08X\n", addr, val, ARM7->R[15]);
|
2016-05-16 15:48:40 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
void ARM7Write32(u32 addr, u32 val)
|
2016-05-16 15:48:40 +00:00
|
|
|
{
|
2016-12-03 12:42:27 +00:00
|
|
|
switch (addr & 0xFF800000)
|
|
|
|
{
|
|
|
|
case 0x02000000:
|
2017-02-01 20:35:00 +00:00
|
|
|
case 0x02800000:
|
2020-05-08 22:45:05 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-14 19:04:25 +00:00
|
|
|
ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_MainRAM>(addr);
|
2020-05-08 22:45:05 +00:00
|
|
|
#endif
|
2019-08-05 17:52:03 +00:00
|
|
|
*(u32*)&MainRAM[addr & MainRAMMask] = val;
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2016-12-03 12:42:27 +00:00
|
|
|
|
2016-12-03 17:29:19 +00:00
|
|
|
case 0x03000000:
|
2020-06-14 19:04:25 +00:00
|
|
|
if (SWRAM_ARM7.Mem)
|
2018-12-04 16:54:10 +00:00
|
|
|
{
|
2020-05-08 22:45:05 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-30 21:50:41 +00:00
|
|
|
ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_SharedWRAM>(addr);
|
2020-05-08 22:45:05 +00:00
|
|
|
#endif
|
2020-06-14 19:04:25 +00:00
|
|
|
*(u32*)&SWRAM_ARM7.Mem[addr & SWRAM_ARM7.Mask] = val;
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-05-08 22:45:05 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-14 19:04:25 +00:00
|
|
|
ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr);
|
2020-05-08 22:45:05 +00:00
|
|
|
#endif
|
2020-06-14 19:04:25 +00:00
|
|
|
*(u32*)&ARM7WRAM[addr & (ARM7WRAMSize - 1)] = val;
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
2016-12-03 17:29:19 +00:00
|
|
|
|
2016-12-03 12:42:27 +00:00
|
|
|
case 0x03800000:
|
2020-05-08 22:45:05 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-14 19:04:25 +00:00
|
|
|
ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr);
|
2020-05-08 22:45:05 +00:00
|
|
|
#endif
|
2020-06-14 19:04:25 +00:00
|
|
|
*(u32*)&ARM7WRAM[addr & (ARM7WRAMSize - 1)] = val;
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2016-12-04 02:20:50 +00:00
|
|
|
|
|
|
|
case 0x04000000:
|
2017-01-17 01:29:25 +00:00
|
|
|
ARM7IOWrite32(addr, val);
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2016-12-05 22:17:03 +00:00
|
|
|
|
2017-05-01 17:29:25 +00:00
|
|
|
case 0x04800000:
|
2018-12-04 16:54:10 +00:00
|
|
|
if (addr < 0x04810000)
|
|
|
|
{
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
if (!(PowerControl7 & (1<<1))) return;
|
2018-12-04 16:54:10 +00:00
|
|
|
Wifi::Write(addr, val & 0xFFFF);
|
|
|
|
Wifi::Write(addr+2, val >> 16);
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2018-12-04 16:54:10 +00:00
|
|
|
}
|
2018-12-08 21:33:41 +00:00
|
|
|
break;
|
2017-05-01 17:29:25 +00:00
|
|
|
|
2016-12-05 22:17:03 +00:00
|
|
|
case 0x06000000:
|
|
|
|
case 0x06800000:
|
2020-05-08 22:45:05 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2020-06-14 19:04:25 +00:00
|
|
|
ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_VWRAM>(addr);
|
2020-05-08 22:45:05 +00:00
|
|
|
#endif
|
2017-02-27 20:26:11 +00:00
|
|
|
GPU::WriteVRAM_ARM7<u32>(addr, val);
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2019-12-08 22:56:22 +00:00
|
|
|
|
2019-12-10 23:44:53 +00:00
|
|
|
case 0x08000000:
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x08800000:
|
2019-12-10 23:44:53 +00:00
|
|
|
case 0x09000000:
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x09800000:
|
2019-12-10 23:44:53 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write
|
2021-04-24 22:48:02 +00:00
|
|
|
GBACart::ROMWrite(addr, val & 0xFFFF);
|
|
|
|
GBACart::ROMWrite(addr+2, val >> 16);
|
|
|
|
return;
|
2019-12-10 23:44:53 +00:00
|
|
|
|
2019-12-08 22:56:22 +00:00
|
|
|
case 0x0A000000:
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x0A800000:
|
2019-12-08 22:56:22 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write
|
2021-04-24 22:48:02 +00:00
|
|
|
GBACart::SRAMWrite(addr, val & 0xFF);
|
|
|
|
GBACart::SRAMWrite(addr+1, (val >> 8) & 0xFF);
|
|
|
|
GBACart::SRAMWrite(addr+2, (val >> 16) & 0xFF);
|
|
|
|
GBACart::SRAMWrite(addr+3, val >> 24);
|
2019-12-08 22:56:22 +00:00
|
|
|
return;
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
|
|
|
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
if (addr >= 0x01000000)
|
|
|
|
printf("unknown arm7 write32 %08X %08X @ %08X\n", addr, val, ARM7->R[15]);
|
2016-05-16 15:48:40 +00:00
|
|
|
}
|
|
|
|
|
2018-11-04 22:21:58 +00:00
|
|
|
bool ARM7GetMemRegion(u32 addr, bool write, MemRegion* region)
|
|
|
|
{
|
|
|
|
switch (addr & 0xFF800000)
|
|
|
|
{
|
|
|
|
case 0x02000000:
|
|
|
|
case 0x02800000:
|
|
|
|
region->Mem = MainRAM;
|
2019-08-05 17:52:03 +00:00
|
|
|
region->Mask = MainRAMMask;
|
2018-11-04 22:21:58 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
case 0x03000000:
|
|
|
|
// note on this, and why we can only cover it in one particular case:
|
|
|
|
// it is typical for games to map all shared WRAM to the ARM7
|
|
|
|
// then access all the WRAM as one contiguous block starting at 0x037F8000
|
|
|
|
// this case needs a bit of a hack to cover
|
|
|
|
// it's not really worth bothering anyway
|
2020-06-14 19:04:25 +00:00
|
|
|
if (!SWRAM_ARM7.Mem)
|
2018-11-04 22:21:58 +00:00
|
|
|
{
|
|
|
|
region->Mem = ARM7WRAM;
|
2020-06-14 19:04:25 +00:00
|
|
|
region->Mask = ARM7WRAMSize-1;
|
2018-11-04 22:21:58 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x03800000:
|
|
|
|
region->Mem = ARM7WRAM;
|
2020-06-14 19:04:25 +00:00
|
|
|
region->Mask = ARM7WRAMSize-1;
|
2018-11-04 22:21:58 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// BIOS. ARM7 PC has to be within range.
|
|
|
|
if (addr < 0x00004000 && !write)
|
|
|
|
{
|
|
|
|
if (ARM7->R[15] < 0x4000 && (addr >= ARM7BIOSProt || ARM7->R[15] < ARM7BIOSProt))
|
|
|
|
{
|
|
|
|
region->Mem = ARM7BIOS;
|
|
|
|
region->Mask = 0x3FFF;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
region->Mem = NULL;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2017-10-02 02:27:50 +00:00
|
|
|
#define CASE_READ8_16BIT(addr, val) \
|
|
|
|
case (addr): return (val) & 0xFF; \
|
|
|
|
case (addr+1): return (val) >> 8;
|
|
|
|
|
|
|
|
#define CASE_READ8_32BIT(addr, val) \
|
|
|
|
case (addr): return (val) & 0xFF; \
|
|
|
|
case (addr+1): return ((val) >> 8) & 0xFF; \
|
|
|
|
case (addr+2): return ((val) >> 16) & 0xFF; \
|
|
|
|
case (addr+3): return (val) >> 24;
|
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
u8 ARM9IORead8(u32 addr)
|
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2021-01-21 20:26:27 +00:00
|
|
|
case 0x04000130: LagFrameFlag = false; return KeyInput & 0xFF;
|
|
|
|
case 0x04000131: LagFrameFlag = false; return (KeyInput >> 8) & 0xFF;
|
2017-06-04 20:34:31 +00:00
|
|
|
case 0x04000132: return KeyCnt & 0xFF;
|
|
|
|
case 0x04000133: return KeyCnt >> 8;
|
2017-04-23 23:30:30 +00:00
|
|
|
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001A2:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
return NDSCart::ReadSPIData();
|
|
|
|
return 0;
|
2017-01-31 16:34:17 +00:00
|
|
|
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001A8:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
return NDSCart::ROMCommand[0];
|
|
|
|
return 0;
|
|
|
|
case 0x040001A9:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
return NDSCart::ROMCommand[1];
|
|
|
|
return 0;
|
|
|
|
case 0x040001AA:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
return NDSCart::ROMCommand[2];
|
|
|
|
return 0;
|
|
|
|
case 0x040001AB:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
return NDSCart::ROMCommand[3];
|
|
|
|
return 0;
|
|
|
|
case 0x040001AC:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
return NDSCart::ROMCommand[4];
|
|
|
|
return 0;
|
|
|
|
case 0x040001AD:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
return NDSCart::ROMCommand[5];
|
|
|
|
return 0;
|
|
|
|
case 0x040001AE:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
return NDSCart::ROMCommand[6];
|
|
|
|
return 0;
|
|
|
|
case 0x040001AF:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
return NDSCart::ROMCommand[7];
|
|
|
|
return 0;
|
2017-03-30 23:50:01 +00:00
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04000208: return IME[0];
|
|
|
|
|
2017-01-18 03:03:19 +00:00
|
|
|
case 0x04000240: return GPU::VRAMCNT[0];
|
|
|
|
case 0x04000241: return GPU::VRAMCNT[1];
|
|
|
|
case 0x04000242: return GPU::VRAMCNT[2];
|
|
|
|
case 0x04000243: return GPU::VRAMCNT[3];
|
|
|
|
case 0x04000244: return GPU::VRAMCNT[4];
|
|
|
|
case 0x04000245: return GPU::VRAMCNT[5];
|
|
|
|
case 0x04000246: return GPU::VRAMCNT[6];
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04000247: return WRAMCnt;
|
2017-01-18 03:03:19 +00:00
|
|
|
case 0x04000248: return GPU::VRAMCNT[7];
|
|
|
|
case 0x04000249: return GPU::VRAMCNT[8];
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2017-10-02 02:27:50 +00:00
|
|
|
CASE_READ8_16BIT(0x04000280, DivCnt)
|
|
|
|
CASE_READ8_32BIT(0x04000290, DivNumerator[0])
|
|
|
|
CASE_READ8_32BIT(0x04000294, DivNumerator[1])
|
|
|
|
CASE_READ8_32BIT(0x04000298, DivDenominator[0])
|
|
|
|
CASE_READ8_32BIT(0x0400029C, DivDenominator[1])
|
|
|
|
CASE_READ8_32BIT(0x040002A0, DivQuotient[0])
|
|
|
|
CASE_READ8_32BIT(0x040002A4, DivQuotient[1])
|
|
|
|
CASE_READ8_32BIT(0x040002A8, DivRemainder[0])
|
|
|
|
CASE_READ8_32BIT(0x040002AC, DivRemainder[1])
|
|
|
|
|
|
|
|
CASE_READ8_16BIT(0x040002B0, SqrtCnt)
|
|
|
|
CASE_READ8_32BIT(0x040002B4, SqrtRes)
|
|
|
|
CASE_READ8_32BIT(0x040002B8, SqrtVal[0])
|
|
|
|
CASE_READ8_32BIT(0x040002BC, SqrtVal[1])
|
|
|
|
|
2017-01-18 01:20:45 +00:00
|
|
|
case 0x04000300: return PostFlag9;
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
2017-01-18 03:03:19 +00:00
|
|
|
if (addr >= 0x04000000 && addr < 0x04000060)
|
|
|
|
{
|
2021-02-27 21:25:27 +00:00
|
|
|
return GPU::GPU2D_A.Read8(addr);
|
2017-01-18 03:03:19 +00:00
|
|
|
}
|
|
|
|
if (addr >= 0x04001000 && addr < 0x04001060)
|
|
|
|
{
|
2021-02-27 21:25:27 +00:00
|
|
|
return GPU::GPU2D_B.Read8(addr);
|
2017-01-18 03:03:19 +00:00
|
|
|
}
|
2017-02-07 22:31:21 +00:00
|
|
|
if (addr >= 0x04000320 && addr < 0x040006A4)
|
|
|
|
{
|
|
|
|
return GPU3D::Read8(addr);
|
|
|
|
}
|
2021-05-27 10:15:16 +00:00
|
|
|
// NO$GBA debug register "Emulation ID"
|
|
|
|
if(addr >= 0x04FFFA00 && addr < 0x04FFFA10)
|
|
|
|
{
|
|
|
|
// FIX: GBATek says this should be padded with spaces
|
|
|
|
static char const emuID[16] = "melonDS " MELONDS_VERSION;
|
|
|
|
auto idx = addr - 0x04FFFA00;
|
|
|
|
return (u8)(emuID[idx]);
|
|
|
|
}
|
2017-01-18 03:03:19 +00:00
|
|
|
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
if ((addr & 0xFFFFF000) != 0x04004000)
|
|
|
|
printf("unknown ARM9 IO read8 %08X %08X\n", addr, ARM9->R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
u16 ARM9IORead16(u32 addr)
|
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2017-01-18 03:03:19 +00:00
|
|
|
case 0x04000004: return GPU::DispStat[0];
|
|
|
|
case 0x04000006: return GPU::VCount;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2017-03-07 00:13:00 +00:00
|
|
|
case 0x04000060: return GPU3D::Read16(addr);
|
2017-03-04 13:47:20 +00:00
|
|
|
case 0x04000064:
|
2021-02-27 21:25:27 +00:00
|
|
|
case 0x04000066: return GPU::GPU2D_A.Read16(addr);
|
2017-01-31 23:24:36 +00:00
|
|
|
|
2017-01-31 16:34:17 +00:00
|
|
|
case 0x040000B8: return DMAs[0]->Cnt & 0xFFFF;
|
|
|
|
case 0x040000BA: return DMAs[0]->Cnt >> 16;
|
|
|
|
case 0x040000C4: return DMAs[1]->Cnt & 0xFFFF;
|
|
|
|
case 0x040000C6: return DMAs[1]->Cnt >> 16;
|
|
|
|
case 0x040000D0: return DMAs[2]->Cnt & 0xFFFF;
|
|
|
|
case 0x040000D2: return DMAs[2]->Cnt >> 16;
|
|
|
|
case 0x040000DC: return DMAs[3]->Cnt & 0xFFFF;
|
|
|
|
case 0x040000DE: return DMAs[3]->Cnt >> 16;
|
|
|
|
|
2017-01-18 00:33:06 +00:00
|
|
|
case 0x040000E0: return ((u16*)DMA9Fill)[0];
|
|
|
|
case 0x040000E2: return ((u16*)DMA9Fill)[1];
|
|
|
|
case 0x040000E4: return ((u16*)DMA9Fill)[2];
|
|
|
|
case 0x040000E6: return ((u16*)DMA9Fill)[3];
|
|
|
|
case 0x040000E8: return ((u16*)DMA9Fill)[4];
|
|
|
|
case 0x040000EA: return ((u16*)DMA9Fill)[5];
|
|
|
|
case 0x040000EC: return ((u16*)DMA9Fill)[6];
|
|
|
|
case 0x040000EE: return ((u16*)DMA9Fill)[7];
|
|
|
|
|
2017-01-31 02:54:51 +00:00
|
|
|
case 0x04000100: return TimerGetCounter(0);
|
|
|
|
case 0x04000102: return Timers[0].Cnt;
|
|
|
|
case 0x04000104: return TimerGetCounter(1);
|
|
|
|
case 0x04000106: return Timers[1].Cnt;
|
|
|
|
case 0x04000108: return TimerGetCounter(2);
|
|
|
|
case 0x0400010A: return Timers[2].Cnt;
|
|
|
|
case 0x0400010C: return TimerGetCounter(3);
|
|
|
|
case 0x0400010E: return Timers[3].Cnt;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2021-01-21 20:26:27 +00:00
|
|
|
case 0x04000130: LagFrameFlag = false; return KeyInput & 0xFFFF;
|
2017-06-04 20:34:31 +00:00
|
|
|
case 0x04000132: return KeyCnt;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
|
|
|
case 0x04000180: return IPCSync9;
|
|
|
|
case 0x04000184:
|
|
|
|
{
|
|
|
|
u16 val = IPCFIFOCnt9;
|
2020-12-30 22:37:46 +00:00
|
|
|
if (IPCFIFO9.IsEmpty()) val |= 0x0001;
|
|
|
|
else if (IPCFIFO9.IsFull()) val |= 0x0002;
|
|
|
|
if (IPCFIFO7.IsEmpty()) val |= 0x0100;
|
|
|
|
else if (IPCFIFO7.IsFull()) val |= 0x0200;
|
2017-01-17 01:29:25 +00:00
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001A0:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
return NDSCart::SPICnt;
|
|
|
|
return 0;
|
|
|
|
case 0x040001A2:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
return NDSCart::ReadSPIData();
|
|
|
|
return 0;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001A8:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
return NDSCart::ROMCommand[0] |
|
|
|
|
(NDSCart::ROMCommand[1] << 8);
|
|
|
|
return 0;
|
|
|
|
case 0x040001AA:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
return NDSCart::ROMCommand[2] |
|
|
|
|
(NDSCart::ROMCommand[3] << 8);
|
|
|
|
return 0;
|
|
|
|
case 0x040001AC:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
return NDSCart::ROMCommand[4] |
|
|
|
|
(NDSCart::ROMCommand[5] << 8);
|
|
|
|
return 0;
|
|
|
|
case 0x040001AE:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
return NDSCart::ROMCommand[6] |
|
|
|
|
(NDSCart::ROMCommand[7] << 8);
|
|
|
|
return 0;
|
2017-03-30 23:50:01 +00:00
|
|
|
|
2017-01-22 19:34:59 +00:00
|
|
|
case 0x04000204: return ExMemCnt[0];
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04000208: return IME[0];
|
2017-06-23 23:21:09 +00:00
|
|
|
case 0x04000210: return IE[0] & 0xFFFF;
|
|
|
|
case 0x04000212: return IE[0] >> 16;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2017-03-04 13:47:20 +00:00
|
|
|
case 0x04000240: return GPU::VRAMCNT[0] | (GPU::VRAMCNT[1] << 8);
|
|
|
|
case 0x04000242: return GPU::VRAMCNT[2] | (GPU::VRAMCNT[3] << 8);
|
|
|
|
case 0x04000244: return GPU::VRAMCNT[4] | (GPU::VRAMCNT[5] << 8);
|
|
|
|
case 0x04000246: return GPU::VRAMCNT[6] | (WRAMCnt << 8);
|
|
|
|
case 0x04000248: return GPU::VRAMCNT[7] | (GPU::VRAMCNT[8] << 8);
|
|
|
|
|
2017-01-18 01:20:45 +00:00
|
|
|
case 0x04000280: return DivCnt;
|
2017-07-05 16:46:19 +00:00
|
|
|
case 0x04000290: return DivNumerator[0] & 0xFFFF;
|
|
|
|
case 0x04000292: return DivNumerator[0] >> 16;
|
|
|
|
case 0x04000294: return DivNumerator[1] & 0xFFFF;
|
|
|
|
case 0x04000296: return DivNumerator[1] >> 16;
|
|
|
|
case 0x04000298: return DivDenominator[0] & 0xFFFF;
|
|
|
|
case 0x0400029A: return DivDenominator[0] >> 16;
|
|
|
|
case 0x0400029C: return DivDenominator[1] & 0xFFFF;
|
|
|
|
case 0x0400029E: return DivDenominator[1] >> 16;
|
|
|
|
case 0x040002A0: return DivQuotient[0] & 0xFFFF;
|
|
|
|
case 0x040002A2: return DivQuotient[0] >> 16;
|
|
|
|
case 0x040002A4: return DivQuotient[1] & 0xFFFF;
|
|
|
|
case 0x040002A6: return DivQuotient[1] >> 16;
|
|
|
|
case 0x040002A8: return DivRemainder[0] & 0xFFFF;
|
|
|
|
case 0x040002AA: return DivRemainder[0] >> 16;
|
|
|
|
case 0x040002AC: return DivRemainder[1] & 0xFFFF;
|
|
|
|
case 0x040002AE: return DivRemainder[1] >> 16;
|
2017-01-18 01:20:45 +00:00
|
|
|
|
2017-01-31 20:53:45 +00:00
|
|
|
case 0x040002B0: return SqrtCnt;
|
2017-07-05 16:46:19 +00:00
|
|
|
case 0x040002B4: return SqrtRes & 0xFFFF;
|
|
|
|
case 0x040002B6: return SqrtRes >> 16;
|
|
|
|
case 0x040002B8: return SqrtVal[0] & 0xFFFF;
|
|
|
|
case 0x040002BA: return SqrtVal[0] >> 16;
|
|
|
|
case 0x040002BC: return SqrtVal[1] & 0xFFFF;
|
|
|
|
case 0x040002BE: return SqrtVal[1] >> 16;
|
2017-01-31 20:53:45 +00:00
|
|
|
|
2017-01-18 01:20:45 +00:00
|
|
|
case 0x04000300: return PostFlag9;
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04000304: return PowerControl9;
|
2021-07-17 16:26:56 +00:00
|
|
|
|
|
|
|
case 0x04004000:
|
|
|
|
case 0x04004004:
|
|
|
|
case 0x04004010:
|
|
|
|
// shut up logging for DSi registers
|
|
|
|
return 0;
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
2017-04-09 01:47:47 +00:00
|
|
|
if ((addr >= 0x04000000 && addr < 0x04000060) || (addr == 0x0400006C))
|
2017-01-18 03:03:19 +00:00
|
|
|
{
|
2021-02-27 21:25:27 +00:00
|
|
|
return GPU::GPU2D_A.Read16(addr);
|
2017-01-18 03:03:19 +00:00
|
|
|
}
|
2017-04-09 01:47:47 +00:00
|
|
|
if ((addr >= 0x04001000 && addr < 0x04001060) || (addr == 0x0400106C))
|
2017-01-18 03:03:19 +00:00
|
|
|
{
|
2021-02-27 21:25:27 +00:00
|
|
|
return GPU::GPU2D_B.Read16(addr);
|
2017-01-18 03:03:19 +00:00
|
|
|
}
|
2017-02-07 22:31:21 +00:00
|
|
|
if (addr >= 0x04000320 && addr < 0x040006A4)
|
|
|
|
{
|
|
|
|
return GPU3D::Read16(addr);
|
|
|
|
}
|
2017-01-18 03:03:19 +00:00
|
|
|
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
if ((addr & 0xFFFFF000) != 0x04004000)
|
|
|
|
printf("unknown ARM9 IO read16 %08X %08X\n", addr, ARM9->R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 ARM9IORead32(u32 addr)
|
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2017-01-18 03:03:19 +00:00
|
|
|
case 0x04000004: return GPU::DispStat[0] | (GPU::VCount << 16);
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2017-03-07 00:13:00 +00:00
|
|
|
case 0x04000060: return GPU3D::Read32(addr);
|
2021-02-27 21:25:27 +00:00
|
|
|
case 0x04000064: return GPU::GPU2D_A.Read32(addr);
|
2017-03-04 13:47:20 +00:00
|
|
|
|
2017-01-18 00:33:06 +00:00
|
|
|
case 0x040000B0: return DMAs[0]->SrcAddr;
|
|
|
|
case 0x040000B4: return DMAs[0]->DstAddr;
|
|
|
|
case 0x040000B8: return DMAs[0]->Cnt;
|
|
|
|
case 0x040000BC: return DMAs[1]->SrcAddr;
|
|
|
|
case 0x040000C0: return DMAs[1]->DstAddr;
|
|
|
|
case 0x040000C4: return DMAs[1]->Cnt;
|
|
|
|
case 0x040000C8: return DMAs[2]->SrcAddr;
|
|
|
|
case 0x040000CC: return DMAs[2]->DstAddr;
|
|
|
|
case 0x040000D0: return DMAs[2]->Cnt;
|
|
|
|
case 0x040000D4: return DMAs[3]->SrcAddr;
|
|
|
|
case 0x040000D8: return DMAs[3]->DstAddr;
|
|
|
|
case 0x040000DC: return DMAs[3]->Cnt;
|
|
|
|
|
|
|
|
case 0x040000E0: return DMA9Fill[0];
|
|
|
|
case 0x040000E4: return DMA9Fill[1];
|
|
|
|
case 0x040000E8: return DMA9Fill[2];
|
|
|
|
case 0x040000EC: return DMA9Fill[3];
|
|
|
|
|
2017-11-09 15:02:37 +00:00
|
|
|
case 0x040000F4: return 0; // ???? Golden Sun Dark Dawn keeps reading this
|
|
|
|
|
2017-01-31 02:54:51 +00:00
|
|
|
case 0x04000100: return TimerGetCounter(0) | (Timers[0].Cnt << 16);
|
|
|
|
case 0x04000104: return TimerGetCounter(1) | (Timers[1].Cnt << 16);
|
|
|
|
case 0x04000108: return TimerGetCounter(2) | (Timers[2].Cnt << 16);
|
|
|
|
case 0x0400010C: return TimerGetCounter(3) | (Timers[3].Cnt << 16);
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2021-01-21 20:26:27 +00:00
|
|
|
case 0x04000130: LagFrameFlag = false; return (KeyInput & 0xFFFF) | (KeyCnt << 16);
|
2017-06-04 20:34:31 +00:00
|
|
|
|
2018-04-24 20:31:52 +00:00
|
|
|
case 0x04000180: return IPCSync9;
|
2020-10-25 17:14:40 +00:00
|
|
|
case 0x04000184: return ARM9IORead16(addr);
|
2018-04-24 20:31:52 +00:00
|
|
|
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001A0:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
return NDSCart::SPICnt | (NDSCart::ReadSPIData() << 16);
|
|
|
|
return 0;
|
|
|
|
case 0x040001A4:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
return NDSCart::ROMCnt;
|
|
|
|
return 0;
|
2017-01-22 19:34:59 +00:00
|
|
|
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001A8:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
return NDSCart::ROMCommand[0] |
|
|
|
|
(NDSCart::ROMCommand[1] << 8) |
|
|
|
|
(NDSCart::ROMCommand[2] << 16) |
|
|
|
|
(NDSCart::ROMCommand[3] << 24);
|
|
|
|
return 0;
|
|
|
|
case 0x040001AC:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
return NDSCart::ROMCommand[4] |
|
|
|
|
(NDSCart::ROMCommand[5] << 8) |
|
|
|
|
(NDSCart::ROMCommand[6] << 16) |
|
|
|
|
(NDSCart::ROMCommand[7] << 24);
|
|
|
|
return 0;
|
2017-03-30 23:50:01 +00:00
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04000208: return IME[0];
|
|
|
|
case 0x04000210: return IE[0];
|
|
|
|
case 0x04000214: return IF[0];
|
|
|
|
|
2017-03-04 13:47:20 +00:00
|
|
|
case 0x04000240: return GPU::VRAMCNT[0] | (GPU::VRAMCNT[1] << 8) | (GPU::VRAMCNT[2] << 16) | (GPU::VRAMCNT[3] << 24);
|
|
|
|
case 0x04000244: return GPU::VRAMCNT[4] | (GPU::VRAMCNT[5] << 8) | (GPU::VRAMCNT[6] << 16) | (WRAMCnt << 24);
|
|
|
|
case 0x04000248: return GPU::VRAMCNT[7] | (GPU::VRAMCNT[8] << 8);
|
|
|
|
|
2017-04-07 15:37:49 +00:00
|
|
|
case 0x04000280: return DivCnt;
|
2017-01-18 01:20:45 +00:00
|
|
|
case 0x04000290: return DivNumerator[0];
|
|
|
|
case 0x04000294: return DivNumerator[1];
|
|
|
|
case 0x04000298: return DivDenominator[0];
|
|
|
|
case 0x0400029C: return DivDenominator[1];
|
|
|
|
case 0x040002A0: return DivQuotient[0];
|
|
|
|
case 0x040002A4: return DivQuotient[1];
|
|
|
|
case 0x040002A8: return DivRemainder[0];
|
|
|
|
case 0x040002AC: return DivRemainder[1];
|
|
|
|
|
2017-04-07 15:37:49 +00:00
|
|
|
case 0x040002B0: return SqrtCnt;
|
2017-01-31 20:53:45 +00:00
|
|
|
case 0x040002B4: return SqrtRes;
|
|
|
|
case 0x040002B8: return SqrtVal[0];
|
|
|
|
case 0x040002BC: return SqrtVal[1];
|
|
|
|
|
2018-12-13 14:03:06 +00:00
|
|
|
case 0x04000300: return PostFlag9;
|
|
|
|
case 0x04000304: return PowerControl9;
|
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04100000:
|
|
|
|
if (IPCFIFOCnt9 & 0x8000)
|
|
|
|
{
|
|
|
|
u32 ret;
|
2020-12-30 22:37:46 +00:00
|
|
|
if (IPCFIFO7.IsEmpty())
|
2017-01-17 01:29:25 +00:00
|
|
|
{
|
|
|
|
IPCFIFOCnt9 |= 0x4000;
|
2020-12-30 22:37:46 +00:00
|
|
|
ret = IPCFIFO7.Peek();
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-12-30 22:37:46 +00:00
|
|
|
ret = IPCFIFO7.Read();
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2020-12-30 22:37:46 +00:00
|
|
|
if (IPCFIFO7.IsEmpty() && (IPCFIFOCnt7 & 0x0004))
|
2017-03-02 23:48:26 +00:00
|
|
|
SetIRQ(1, IRQ_IPCSendDone);
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
else
|
2020-12-30 22:37:46 +00:00
|
|
|
return IPCFIFO7.Peek();
|
2017-01-22 19:34:59 +00:00
|
|
|
|
|
|
|
case 0x04100010:
|
2017-01-31 16:34:17 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11))) return NDSCart::ReadROMData();
|
2017-01-22 19:34:59 +00:00
|
|
|
return 0;
|
2021-05-27 10:15:16 +00:00
|
|
|
|
2021-07-17 16:26:56 +00:00
|
|
|
case 0x04004000:
|
|
|
|
case 0x04004004:
|
|
|
|
case 0x04004010:
|
|
|
|
// shut up logging for DSi registers
|
|
|
|
return 0;
|
|
|
|
|
2021-05-27 10:15:16 +00:00
|
|
|
// NO$GBA debug register "Clock Cycles"
|
|
|
|
// Since it's a 64 bit reg. the CPU will access it in two parts:
|
|
|
|
case 0x04FFFA20: return (u32)(GetSysClockCycles(0) & 0xFFFFFFFF);
|
|
|
|
case 0x04FFFA24: return (u32)(GetSysClockCycles(0) >> 32);
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
2017-04-09 01:47:47 +00:00
|
|
|
if ((addr >= 0x04000000 && addr < 0x04000060) || (addr == 0x0400006C))
|
2017-01-18 03:03:19 +00:00
|
|
|
{
|
2021-02-27 21:25:27 +00:00
|
|
|
return GPU::GPU2D_A.Read32(addr);
|
2017-01-18 03:03:19 +00:00
|
|
|
}
|
2017-04-09 01:47:47 +00:00
|
|
|
if ((addr >= 0x04001000 && addr < 0x04001060) || (addr == 0x0400106C))
|
2017-01-18 03:03:19 +00:00
|
|
|
{
|
2021-02-27 21:25:27 +00:00
|
|
|
return GPU::GPU2D_B.Read32(addr);
|
2017-01-18 03:03:19 +00:00
|
|
|
}
|
2017-02-01 20:57:25 +00:00
|
|
|
if (addr >= 0x04000320 && addr < 0x040006A4)
|
|
|
|
{
|
2017-02-07 22:31:21 +00:00
|
|
|
return GPU3D::Read32(addr);
|
2017-02-01 20:57:25 +00:00
|
|
|
}
|
2017-01-18 03:03:19 +00:00
|
|
|
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
if ((addr & 0xFFFFF000) != 0x04004000)
|
|
|
|
printf("unknown ARM9 IO read32 %08X %08X\n", addr, ARM9->R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ARM9IOWrite8(u32 addr, u8 val)
|
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2017-07-23 13:31:09 +00:00
|
|
|
case 0x0400006C:
|
2021-02-27 21:25:27 +00:00
|
|
|
case 0x0400006D: GPU::GPU2D_A.Write8(addr, val); return;
|
2017-07-23 13:31:09 +00:00
|
|
|
case 0x0400106C:
|
2021-02-27 21:25:27 +00:00
|
|
|
case 0x0400106D: GPU::GPU2D_B.Write8(addr, val); return;
|
2017-07-23 13:31:09 +00:00
|
|
|
|
2017-06-04 20:34:31 +00:00
|
|
|
case 0x04000132:
|
|
|
|
KeyCnt = (KeyCnt & 0xFF00) | val;
|
|
|
|
return;
|
|
|
|
case 0x04000133:
|
|
|
|
KeyCnt = (KeyCnt & 0x00FF) | (val << 8);
|
|
|
|
return;
|
|
|
|
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x04000188:
|
|
|
|
ARM9IOWrite32(addr, val | (val << 8) | (val << 16) | (val << 24));
|
|
|
|
return;
|
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x040001A0:
|
2017-01-22 19:34:59 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
2017-01-31 16:34:17 +00:00
|
|
|
NDSCart::WriteSPICnt((NDSCart::SPICnt & 0xFF00) | val);
|
2017-01-17 01:29:25 +00:00
|
|
|
return;
|
|
|
|
case 0x040001A1:
|
2017-01-22 19:34:59 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
2017-01-31 16:34:17 +00:00
|
|
|
NDSCart::WriteSPICnt((NDSCart::SPICnt & 0x00FF) | (val << 8));
|
2017-01-17 01:29:25 +00:00
|
|
|
return;
|
2017-01-31 16:34:17 +00:00
|
|
|
case 0x040001A2:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
NDSCart::WriteSPIData(val);
|
2020-10-29 20:09:25 +00:00
|
|
|
return;
|
|
|
|
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001A8: if (!(ExMemCnt[0] & (1<<11))) NDSCart::ROMCommand[0] = val; return;
|
|
|
|
case 0x040001A9: if (!(ExMemCnt[0] & (1<<11))) NDSCart::ROMCommand[1] = val; return;
|
|
|
|
case 0x040001AA: if (!(ExMemCnt[0] & (1<<11))) NDSCart::ROMCommand[2] = val; return;
|
|
|
|
case 0x040001AB: if (!(ExMemCnt[0] & (1<<11))) NDSCart::ROMCommand[3] = val; return;
|
|
|
|
case 0x040001AC: if (!(ExMemCnt[0] & (1<<11))) NDSCart::ROMCommand[4] = val; return;
|
|
|
|
case 0x040001AD: if (!(ExMemCnt[0] & (1<<11))) NDSCart::ROMCommand[5] = val; return;
|
|
|
|
case 0x040001AE: if (!(ExMemCnt[0] & (1<<11))) NDSCart::ROMCommand[6] = val; return;
|
|
|
|
case 0x040001AF: if (!(ExMemCnt[0] & (1<<11))) NDSCart::ROMCommand[7] = val; return;
|
2017-01-22 19:34:59 +00:00
|
|
|
|
2019-06-08 20:16:51 +00:00
|
|
|
case 0x04000208: IME[0] = val & 0x1; UpdateIRQ(0); return;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2017-01-18 03:03:19 +00:00
|
|
|
case 0x04000240: GPU::MapVRAM_AB(0, val); return;
|
|
|
|
case 0x04000241: GPU::MapVRAM_AB(1, val); return;
|
|
|
|
case 0x04000242: GPU::MapVRAM_CD(2, val); return;
|
|
|
|
case 0x04000243: GPU::MapVRAM_CD(3, val); return;
|
|
|
|
case 0x04000244: GPU::MapVRAM_E(4, val); return;
|
|
|
|
case 0x04000245: GPU::MapVRAM_FG(5, val); return;
|
|
|
|
case 0x04000246: GPU::MapVRAM_FG(6, val); return;
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04000247: MapSharedWRAM(val); return;
|
2017-01-18 03:03:19 +00:00
|
|
|
case 0x04000248: GPU::MapVRAM_H(7, val); return;
|
|
|
|
case 0x04000249: GPU::MapVRAM_I(8, val); return;
|
2017-01-18 01:20:45 +00:00
|
|
|
|
|
|
|
case 0x04000300:
|
|
|
|
if (PostFlag9 & 0x01) val |= 0x01;
|
|
|
|
PostFlag9 = val & 0x03;
|
|
|
|
return;
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
2017-01-18 03:03:19 +00:00
|
|
|
if (addr >= 0x04000000 && addr < 0x04000060)
|
|
|
|
{
|
2021-02-27 21:25:27 +00:00
|
|
|
GPU::GPU2D_A.Write8(addr, val);
|
2017-01-18 03:03:19 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (addr >= 0x04001000 && addr < 0x04001060)
|
|
|
|
{
|
2021-02-27 21:25:27 +00:00
|
|
|
GPU::GPU2D_B.Write8(addr, val);
|
2017-01-18 03:03:19 +00:00
|
|
|
return;
|
|
|
|
}
|
2017-02-07 22:31:21 +00:00
|
|
|
if (addr >= 0x04000320 && addr < 0x040006A4)
|
|
|
|
{
|
|
|
|
GPU3D::Write8(addr, val);
|
|
|
|
return;
|
|
|
|
}
|
2017-01-18 03:03:19 +00:00
|
|
|
|
2018-05-23 23:00:33 +00:00
|
|
|
printf("unknown ARM9 IO write8 %08X %02X %08X\n", addr, val, ARM9->R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ARM9IOWrite16(u32 addr, u16 val)
|
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2017-01-18 03:03:19 +00:00
|
|
|
case 0x04000004: GPU::SetDispStat(0, val); return;
|
2017-05-10 00:21:02 +00:00
|
|
|
case 0x04000006: GPU::SetVCount(val); return;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2017-03-07 00:13:00 +00:00
|
|
|
case 0x04000060: GPU3D::Write16(addr, val); return;
|
2017-01-31 23:24:36 +00:00
|
|
|
|
2017-06-26 09:02:10 +00:00
|
|
|
case 0x04000068:
|
2021-02-27 21:25:27 +00:00
|
|
|
case 0x0400006A: GPU::GPU2D_A.Write16(addr, val); return;
|
2017-06-26 09:02:10 +00:00
|
|
|
|
2021-02-27 21:25:27 +00:00
|
|
|
case 0x0400006C: GPU::GPU2D_A.Write16(addr, val); return;
|
|
|
|
case 0x0400106C: GPU::GPU2D_B.Write16(addr, val); return;
|
2017-07-23 13:31:09 +00:00
|
|
|
|
2017-01-31 16:34:17 +00:00
|
|
|
case 0x040000B8: DMAs[0]->WriteCnt((DMAs[0]->Cnt & 0xFFFF0000) | val); return;
|
|
|
|
case 0x040000BA: DMAs[0]->WriteCnt((DMAs[0]->Cnt & 0x0000FFFF) | (val << 16)); return;
|
|
|
|
case 0x040000C4: DMAs[1]->WriteCnt((DMAs[1]->Cnt & 0xFFFF0000) | val); return;
|
|
|
|
case 0x040000C6: DMAs[1]->WriteCnt((DMAs[1]->Cnt & 0x0000FFFF) | (val << 16)); return;
|
|
|
|
case 0x040000D0: DMAs[2]->WriteCnt((DMAs[2]->Cnt & 0xFFFF0000) | val); return;
|
|
|
|
case 0x040000D2: DMAs[2]->WriteCnt((DMAs[2]->Cnt & 0x0000FFFF) | (val << 16)); return;
|
|
|
|
case 0x040000DC: DMAs[3]->WriteCnt((DMAs[3]->Cnt & 0xFFFF0000) | val); return;
|
|
|
|
case 0x040000DE: DMAs[3]->WriteCnt((DMAs[3]->Cnt & 0x0000FFFF) | (val << 16)); return;
|
|
|
|
|
2017-04-25 14:13:16 +00:00
|
|
|
case 0x040000E0: DMA9Fill[0] = (DMA9Fill[0] & 0xFFFF0000) | val; return;
|
|
|
|
case 0x040000E2: DMA9Fill[0] = (DMA9Fill[0] & 0x0000FFFF) | (val << 16); return;
|
|
|
|
case 0x040000E4: DMA9Fill[1] = (DMA9Fill[1] & 0xFFFF0000) | val; return;
|
|
|
|
case 0x040000E6: DMA9Fill[1] = (DMA9Fill[1] & 0x0000FFFF) | (val << 16); return;
|
|
|
|
case 0x040000E8: DMA9Fill[2] = (DMA9Fill[2] & 0xFFFF0000) | val; return;
|
|
|
|
case 0x040000EA: DMA9Fill[2] = (DMA9Fill[2] & 0x0000FFFF) | (val << 16); return;
|
|
|
|
case 0x040000EC: DMA9Fill[3] = (DMA9Fill[3] & 0xFFFF0000) | val; return;
|
|
|
|
case 0x040000EE: DMA9Fill[3] = (DMA9Fill[3] & 0x0000FFFF) | (val << 16); return;
|
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04000100: Timers[0].Reload = val; return;
|
|
|
|
case 0x04000102: TimerStart(0, val); return;
|
|
|
|
case 0x04000104: Timers[1].Reload = val; return;
|
|
|
|
case 0x04000106: TimerStart(1, val); return;
|
|
|
|
case 0x04000108: Timers[2].Reload = val; return;
|
|
|
|
case 0x0400010A: TimerStart(2, val); return;
|
|
|
|
case 0x0400010C: Timers[3].Reload = val; return;
|
|
|
|
case 0x0400010E: TimerStart(3, val); return;
|
|
|
|
|
2017-06-04 20:34:31 +00:00
|
|
|
case 0x04000132:
|
|
|
|
KeyCnt = val;
|
|
|
|
return;
|
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04000180:
|
|
|
|
IPCSync7 &= 0xFFF0;
|
|
|
|
IPCSync7 |= ((val & 0x0F00) >> 8);
|
|
|
|
IPCSync9 &= 0xB0FF;
|
|
|
|
IPCSync9 |= (val & 0x4F00);
|
|
|
|
if ((val & 0x2000) && (IPCSync7 & 0x4000))
|
|
|
|
{
|
2017-03-02 23:48:26 +00:00
|
|
|
SetIRQ(1, IRQ_IPCSync);
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 0x04000184:
|
|
|
|
if (val & 0x0008)
|
2020-12-30 22:37:46 +00:00
|
|
|
IPCFIFO9.Clear();
|
|
|
|
if ((val & 0x0004) && (!(IPCFIFOCnt9 & 0x0004)) && IPCFIFO9.IsEmpty())
|
2017-03-02 23:48:26 +00:00
|
|
|
SetIRQ(0, IRQ_IPCSendDone);
|
2020-12-30 22:37:46 +00:00
|
|
|
if ((val & 0x0400) && (!(IPCFIFOCnt9 & 0x0400)) && (!IPCFIFO7.IsEmpty()))
|
2017-03-02 23:48:26 +00:00
|
|
|
SetIRQ(0, IRQ_IPCRecv);
|
2017-01-17 01:29:25 +00:00
|
|
|
if (val & 0x4000)
|
|
|
|
IPCFIFOCnt9 &= ~0x4000;
|
2020-12-11 17:06:26 +00:00
|
|
|
IPCFIFOCnt9 = (val & 0x8404) | (IPCFIFOCnt9 & 0x4000);
|
2017-01-17 01:29:25 +00:00
|
|
|
return;
|
|
|
|
|
2020-10-29 20:09:25 +00:00
|
|
|
case 0x04000188:
|
2020-12-10 17:09:11 +00:00
|
|
|
ARM9IOWrite32(addr, val | (val << 16));
|
2020-10-29 20:09:25 +00:00
|
|
|
return;
|
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x040001A0:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
NDSCart::WriteSPICnt(val);
|
2017-01-31 16:34:17 +00:00
|
|
|
return;
|
|
|
|
case 0x040001A2:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
NDSCart::WriteSPIData(val & 0xFF);
|
2017-01-22 19:34:59 +00:00
|
|
|
return;
|
|
|
|
|
2017-03-30 23:50:01 +00:00
|
|
|
case 0x040001A8:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
{
|
|
|
|
NDSCart::ROMCommand[0] = val & 0xFF;
|
|
|
|
NDSCart::ROMCommand[1] = val >> 8;
|
|
|
|
}
|
2017-03-30 23:50:01 +00:00
|
|
|
return;
|
|
|
|
case 0x040001AA:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
{
|
|
|
|
NDSCart::ROMCommand[2] = val & 0xFF;
|
|
|
|
NDSCart::ROMCommand[3] = val >> 8;
|
|
|
|
}
|
2017-03-30 23:50:01 +00:00
|
|
|
return;
|
|
|
|
case 0x040001AC:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
{
|
|
|
|
NDSCart::ROMCommand[4] = val & 0xFF;
|
|
|
|
NDSCart::ROMCommand[5] = val >> 8;
|
|
|
|
}
|
2017-03-30 23:50:01 +00:00
|
|
|
return;
|
|
|
|
case 0x040001AE:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
{
|
|
|
|
NDSCart::ROMCommand[6] = val & 0xFF;
|
|
|
|
NDSCart::ROMCommand[7] = val >> 8;
|
|
|
|
}
|
2017-03-30 23:50:01 +00:00
|
|
|
return;
|
|
|
|
|
2017-01-22 19:34:59 +00:00
|
|
|
case 0x040001B8: ROMSeed0[4] = val & 0x7F; return;
|
|
|
|
case 0x040001BA: ROMSeed1[4] = val & 0x7F; return;
|
|
|
|
|
|
|
|
case 0x04000204:
|
2021-06-26 22:45:12 +00:00
|
|
|
{
|
|
|
|
u16 oldVal = ExMemCnt[0];
|
|
|
|
ExMemCnt[0] = val;
|
|
|
|
ExMemCnt[1] = (ExMemCnt[1] & 0x007F) | (val & 0xFF80);
|
|
|
|
if ((oldVal ^ ExMemCnt[0]) & 0xFF)
|
|
|
|
SetGBASlotTimings();
|
|
|
|
return;
|
|
|
|
}
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2019-06-08 20:16:51 +00:00
|
|
|
case 0x04000208: IME[0] = val & 0x1; UpdateIRQ(0); return;
|
|
|
|
case 0x04000210: IE[0] = (IE[0] & 0xFFFF0000) | val; UpdateIRQ(0); return;
|
|
|
|
case 0x04000212: IE[0] = (IE[0] & 0x0000FFFF) | (val << 16); UpdateIRQ(0); return;
|
2017-06-23 23:21:09 +00:00
|
|
|
// TODO: what happens when writing to IF this way??
|
2017-01-17 01:29:25 +00:00
|
|
|
|
|
|
|
case 0x04000240:
|
2017-01-18 03:03:19 +00:00
|
|
|
GPU::MapVRAM_AB(0, val & 0xFF);
|
|
|
|
GPU::MapVRAM_AB(1, val >> 8);
|
2017-01-17 01:29:25 +00:00
|
|
|
return;
|
|
|
|
case 0x04000242:
|
2017-01-18 03:03:19 +00:00
|
|
|
GPU::MapVRAM_CD(2, val & 0xFF);
|
|
|
|
GPU::MapVRAM_CD(3, val >> 8);
|
2017-01-17 01:29:25 +00:00
|
|
|
return;
|
|
|
|
case 0x04000244:
|
2017-01-18 03:03:19 +00:00
|
|
|
GPU::MapVRAM_E(4, val & 0xFF);
|
|
|
|
GPU::MapVRAM_FG(5, val >> 8);
|
2017-01-17 01:29:25 +00:00
|
|
|
return;
|
|
|
|
case 0x04000246:
|
2017-01-18 03:03:19 +00:00
|
|
|
GPU::MapVRAM_FG(6, val & 0xFF);
|
2017-01-17 01:29:25 +00:00
|
|
|
MapSharedWRAM(val >> 8);
|
|
|
|
return;
|
|
|
|
case 0x04000248:
|
2017-01-18 03:03:19 +00:00
|
|
|
GPU::MapVRAM_H(7, val & 0xFF);
|
|
|
|
GPU::MapVRAM_I(8, val >> 8);
|
2017-01-17 01:29:25 +00:00
|
|
|
return;
|
|
|
|
|
2017-01-18 01:20:45 +00:00
|
|
|
case 0x04000280: DivCnt = val; StartDiv(); return;
|
|
|
|
|
2017-01-31 20:53:45 +00:00
|
|
|
case 0x040002B0: SqrtCnt = val; StartSqrt(); return;
|
|
|
|
|
2017-01-18 01:20:45 +00:00
|
|
|
case 0x04000300:
|
|
|
|
if (PostFlag9 & 0x01) val |= 0x01;
|
|
|
|
PostFlag9 = val & 0x03;
|
|
|
|
return;
|
|
|
|
|
2017-02-01 20:57:25 +00:00
|
|
|
case 0x04000304:
|
2018-12-18 16:04:42 +00:00
|
|
|
PowerControl9 = val & 0x820F;
|
|
|
|
GPU::SetPowerCnt(PowerControl9);
|
2017-02-01 20:57:25 +00:00
|
|
|
return;
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
2017-07-23 13:31:09 +00:00
|
|
|
if (addr >= 0x04000000 && addr < 0x04000060)
|
2017-01-18 03:03:19 +00:00
|
|
|
{
|
2021-02-27 21:25:27 +00:00
|
|
|
GPU::GPU2D_A.Write16(addr, val);
|
2017-01-18 03:03:19 +00:00
|
|
|
return;
|
|
|
|
}
|
2017-07-23 13:31:09 +00:00
|
|
|
if (addr >= 0x04001000 && addr < 0x04001060)
|
2017-01-18 03:03:19 +00:00
|
|
|
{
|
2021-02-27 21:25:27 +00:00
|
|
|
GPU::GPU2D_B.Write16(addr, val);
|
2017-01-18 03:03:19 +00:00
|
|
|
return;
|
|
|
|
}
|
2017-02-01 20:57:25 +00:00
|
|
|
if (addr >= 0x04000320 && addr < 0x040006A4)
|
|
|
|
{
|
2017-02-07 22:31:21 +00:00
|
|
|
GPU3D::Write16(addr, val);
|
2017-02-01 20:57:25 +00:00
|
|
|
return;
|
|
|
|
}
|
2017-01-18 03:03:19 +00:00
|
|
|
|
2018-05-23 23:00:33 +00:00
|
|
|
printf("unknown ARM9 IO write16 %08X %04X %08X\n", addr, val, ARM9->R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ARM9IOWrite32(u32 addr, u32 val)
|
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2019-06-20 11:57:14 +00:00
|
|
|
case 0x04000004:
|
|
|
|
GPU::SetDispStat(0, val & 0xFFFF);
|
|
|
|
GPU::SetVCount(val >> 16);
|
|
|
|
return;
|
|
|
|
|
2017-03-07 00:13:00 +00:00
|
|
|
case 0x04000060: GPU3D::Write32(addr, val); return;
|
2017-06-26 09:02:10 +00:00
|
|
|
case 0x04000064:
|
2021-02-27 21:25:27 +00:00
|
|
|
case 0x04000068: GPU::GPU2D_A.Write32(addr, val); return;
|
2017-01-31 23:24:36 +00:00
|
|
|
|
2021-02-27 21:25:27 +00:00
|
|
|
case 0x0400006C: GPU::GPU2D_A.Write16(addr, val&0xFFFF); return;
|
|
|
|
case 0x0400106C: GPU::GPU2D_B.Write16(addr, val&0xFFFF); return;
|
2017-07-23 13:31:09 +00:00
|
|
|
|
2017-01-18 00:33:06 +00:00
|
|
|
case 0x040000B0: DMAs[0]->SrcAddr = val; return;
|
|
|
|
case 0x040000B4: DMAs[0]->DstAddr = val; return;
|
|
|
|
case 0x040000B8: DMAs[0]->WriteCnt(val); return;
|
|
|
|
case 0x040000BC: DMAs[1]->SrcAddr = val; return;
|
|
|
|
case 0x040000C0: DMAs[1]->DstAddr = val; return;
|
|
|
|
case 0x040000C4: DMAs[1]->WriteCnt(val); return;
|
|
|
|
case 0x040000C8: DMAs[2]->SrcAddr = val; return;
|
|
|
|
case 0x040000CC: DMAs[2]->DstAddr = val; return;
|
|
|
|
case 0x040000D0: DMAs[2]->WriteCnt(val); return;
|
|
|
|
case 0x040000D4: DMAs[3]->SrcAddr = val; return;
|
|
|
|
case 0x040000D8: DMAs[3]->DstAddr = val; return;
|
|
|
|
case 0x040000DC: DMAs[3]->WriteCnt(val); return;
|
|
|
|
|
|
|
|
case 0x040000E0: DMA9Fill[0] = val; return;
|
|
|
|
case 0x040000E4: DMA9Fill[1] = val; return;
|
|
|
|
case 0x040000E8: DMA9Fill[2] = val; return;
|
|
|
|
case 0x040000EC: DMA9Fill[3] = val; return;
|
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04000100:
|
|
|
|
Timers[0].Reload = val & 0xFFFF;
|
|
|
|
TimerStart(0, val>>16);
|
|
|
|
return;
|
|
|
|
case 0x04000104:
|
|
|
|
Timers[1].Reload = val & 0xFFFF;
|
|
|
|
TimerStart(1, val>>16);
|
|
|
|
return;
|
|
|
|
case 0x04000108:
|
|
|
|
Timers[2].Reload = val & 0xFFFF;
|
|
|
|
TimerStart(2, val>>16);
|
|
|
|
return;
|
|
|
|
case 0x0400010C:
|
|
|
|
Timers[3].Reload = val & 0xFFFF;
|
|
|
|
TimerStart(3, val>>16);
|
|
|
|
return;
|
|
|
|
|
2017-06-04 20:34:31 +00:00
|
|
|
case 0x04000130:
|
|
|
|
KeyCnt = val >> 16;
|
|
|
|
return;
|
2020-10-25 17:14:40 +00:00
|
|
|
|
2018-04-24 20:31:52 +00:00
|
|
|
case 0x04000180:
|
2020-10-25 17:14:40 +00:00
|
|
|
case 0x04000184:
|
2018-04-24 20:31:52 +00:00
|
|
|
ARM9IOWrite16(addr, val);
|
|
|
|
return;
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04000188:
|
|
|
|
if (IPCFIFOCnt9 & 0x8000)
|
2017-06-18 14:26:59 +00:00
|
|
|
{
|
2020-12-30 22:37:46 +00:00
|
|
|
if (IPCFIFO9.IsFull())
|
2017-01-17 01:29:25 +00:00
|
|
|
IPCFIFOCnt9 |= 0x4000;
|
|
|
|
else
|
|
|
|
{
|
2020-12-30 22:37:46 +00:00
|
|
|
bool wasempty = IPCFIFO9.IsEmpty();
|
|
|
|
IPCFIFO9.Write(val);
|
2017-01-17 04:29:38 +00:00
|
|
|
if ((IPCFIFOCnt7 & 0x0400) && wasempty)
|
2017-03-02 23:48:26 +00:00
|
|
|
SetIRQ(1, IRQ_IPCRecv);
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 0x040001A0:
|
2017-01-22 19:34:59 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
{
|
2017-01-31 16:34:17 +00:00
|
|
|
NDSCart::WriteSPICnt(val & 0xFFFF);
|
|
|
|
NDSCart::WriteSPIData((val >> 16) & 0xFF);
|
2017-01-22 19:34:59 +00:00
|
|
|
}
|
2017-01-17 01:29:25 +00:00
|
|
|
return;
|
|
|
|
case 0x040001A4:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
NDSCart::WriteROMCnt(val);
|
2017-01-17 01:29:25 +00:00
|
|
|
return;
|
|
|
|
|
2017-03-30 23:50:01 +00:00
|
|
|
case 0x040001A8:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
{
|
|
|
|
NDSCart::ROMCommand[0] = val & 0xFF;
|
|
|
|
NDSCart::ROMCommand[1] = (val >> 8) & 0xFF;
|
|
|
|
NDSCart::ROMCommand[2] = (val >> 16) & 0xFF;
|
|
|
|
NDSCart::ROMCommand[3] = val >> 24;
|
|
|
|
}
|
2017-03-30 23:50:01 +00:00
|
|
|
return;
|
|
|
|
case 0x040001AC:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
{
|
|
|
|
NDSCart::ROMCommand[4] = val & 0xFF;
|
|
|
|
NDSCart::ROMCommand[5] = (val >> 8) & 0xFF;
|
|
|
|
NDSCart::ROMCommand[6] = (val >> 16) & 0xFF;
|
|
|
|
NDSCart::ROMCommand[7] = val >> 24;
|
|
|
|
}
|
2017-03-30 23:50:01 +00:00
|
|
|
return;
|
|
|
|
|
2017-01-22 19:34:59 +00:00
|
|
|
case 0x040001B0: *(u32*)&ROMSeed0[0] = val; return;
|
|
|
|
case 0x040001B4: *(u32*)&ROMSeed1[0] = val; return;
|
|
|
|
|
2019-06-08 20:16:51 +00:00
|
|
|
case 0x04000208: IME[0] = val & 0x1; UpdateIRQ(0); return;
|
|
|
|
case 0x04000210: IE[0] = val; UpdateIRQ(0); return;
|
|
|
|
case 0x04000214: IF[0] &= ~val; GPU3D::CheckFIFOIRQ(); UpdateIRQ(0); return;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
|
|
|
case 0x04000240:
|
2017-01-18 03:03:19 +00:00
|
|
|
GPU::MapVRAM_AB(0, val & 0xFF);
|
|
|
|
GPU::MapVRAM_AB(1, (val >> 8) & 0xFF);
|
|
|
|
GPU::MapVRAM_CD(2, (val >> 16) & 0xFF);
|
|
|
|
GPU::MapVRAM_CD(3, val >> 24);
|
2017-01-17 01:29:25 +00:00
|
|
|
return;
|
|
|
|
case 0x04000244:
|
2017-01-18 03:03:19 +00:00
|
|
|
GPU::MapVRAM_E(4, val & 0xFF);
|
|
|
|
GPU::MapVRAM_FG(5, (val >> 8) & 0xFF);
|
|
|
|
GPU::MapVRAM_FG(6, (val >> 16) & 0xFF);
|
2017-01-17 01:29:25 +00:00
|
|
|
MapSharedWRAM(val >> 24);
|
|
|
|
return;
|
|
|
|
case 0x04000248:
|
2017-01-18 03:03:19 +00:00
|
|
|
GPU::MapVRAM_H(7, val & 0xFF);
|
|
|
|
GPU::MapVRAM_I(8, (val >> 8) & 0xFF);
|
2017-01-17 01:29:25 +00:00
|
|
|
return;
|
2017-01-18 01:20:45 +00:00
|
|
|
|
2017-04-28 15:23:18 +00:00
|
|
|
case 0x04000280: DivCnt = val; StartDiv(); return;
|
|
|
|
|
|
|
|
case 0x040002B0: SqrtCnt = val; StartSqrt(); return;
|
|
|
|
|
2017-01-18 01:20:45 +00:00
|
|
|
case 0x04000290: DivNumerator[0] = val; StartDiv(); return;
|
|
|
|
case 0x04000294: DivNumerator[1] = val; StartDiv(); return;
|
|
|
|
case 0x04000298: DivDenominator[0] = val; StartDiv(); return;
|
|
|
|
case 0x0400029C: DivDenominator[1] = val; StartDiv(); return;
|
2017-01-31 20:53:45 +00:00
|
|
|
|
|
|
|
case 0x040002B8: SqrtVal[0] = val; StartSqrt(); return;
|
|
|
|
case 0x040002BC: SqrtVal[1] = val; StartSqrt(); return;
|
2017-03-23 16:14:48 +00:00
|
|
|
|
|
|
|
case 0x04000304:
|
2018-12-18 16:04:42 +00:00
|
|
|
PowerControl9 = val & 0x820F;
|
|
|
|
GPU::SetPowerCnt(PowerControl9);
|
2017-03-23 16:14:48 +00:00
|
|
|
return;
|
2020-09-03 18:28:07 +00:00
|
|
|
|
|
|
|
case 0x04100010:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11))) NDSCart::WriteROMData(val);
|
2020-09-03 18:28:07 +00:00
|
|
|
return;
|
2021-05-27 10:15:16 +00:00
|
|
|
|
|
|
|
// NO$GBA debug register "String Out (raw)"
|
|
|
|
case 0x04FFFA10:
|
|
|
|
{
|
|
|
|
char output[1024] = { 0 };
|
|
|
|
char ch = '.';
|
|
|
|
for (size_t i = 0; i < 1023 && ch != '\0'; i++)
|
|
|
|
{
|
|
|
|
ch = NDS::ARM9Read8(val + i);
|
|
|
|
output[i] = ch;
|
|
|
|
}
|
|
|
|
printf("%s", output);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// NO$GBA debug registers "String Out (with parameters)" and "String Out (with parameters, plus linefeed)"
|
|
|
|
case 0x04FFFA14:
|
|
|
|
case 0x04FFFA18:
|
|
|
|
{
|
|
|
|
bool appendLF = 0x04FFFA18 == addr;
|
|
|
|
NocashPrint(0, val);
|
|
|
|
if(appendLF)
|
|
|
|
printf("\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// NO$GBA debug register "Char Out"
|
2021-06-07 19:51:51 +00:00
|
|
|
case 0x04FFFA1C: printf("%" PRIu32, val); return;
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
2017-01-18 03:03:19 +00:00
|
|
|
if (addr >= 0x04000000 && addr < 0x04000060)
|
|
|
|
{
|
2021-02-27 21:25:27 +00:00
|
|
|
GPU::GPU2D_A.Write32(addr, val);
|
2017-01-18 03:03:19 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (addr >= 0x04001000 && addr < 0x04001060)
|
|
|
|
{
|
2021-02-27 21:25:27 +00:00
|
|
|
GPU::GPU2D_B.Write32(addr, val);
|
2017-01-18 03:03:19 +00:00
|
|
|
return;
|
|
|
|
}
|
2017-01-31 17:41:31 +00:00
|
|
|
if (addr >= 0x04000320 && addr < 0x040006A4)
|
|
|
|
{
|
2017-02-07 22:31:21 +00:00
|
|
|
GPU3D::Write32(addr, val);
|
2017-01-31 17:41:31 +00:00
|
|
|
return;
|
|
|
|
}
|
2017-01-18 03:03:19 +00:00
|
|
|
|
2018-05-23 23:00:33 +00:00
|
|
|
printf("unknown ARM9 IO write32 %08X %08X %08X\n", addr, val, ARM9->R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
u8 ARM7IORead8(u32 addr)
|
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2017-04-23 23:30:30 +00:00
|
|
|
case 0x04000130: return KeyInput & 0xFF;
|
|
|
|
case 0x04000131: return (KeyInput >> 8) & 0xFF;
|
2017-06-04 20:34:31 +00:00
|
|
|
case 0x04000132: return KeyCnt & 0xFF;
|
|
|
|
case 0x04000133: return KeyCnt >> 8;
|
|
|
|
case 0x04000134: return RCnt & 0xFF;
|
|
|
|
case 0x04000135: return RCnt >> 8;
|
2017-04-23 23:30:30 +00:00
|
|
|
case 0x04000136: return (KeyInput >> 16) & 0xFF;
|
|
|
|
case 0x04000137: return KeyInput >> 24;
|
|
|
|
|
2017-01-20 00:18:30 +00:00
|
|
|
case 0x04000138: return RTC::Read() & 0xFF;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001A2:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
return NDSCart::ReadSPIData();
|
|
|
|
return 0;
|
2017-01-31 16:34:17 +00:00
|
|
|
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001A8:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
return NDSCart::ROMCommand[0];
|
2021-05-03 12:36:21 +00:00
|
|
|
return 0;
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001A9:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
return NDSCart::ROMCommand[1];
|
2021-05-03 12:36:21 +00:00
|
|
|
return 0;
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001AA:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
return NDSCart::ROMCommand[2];
|
2021-05-03 12:36:21 +00:00
|
|
|
return 0;
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001AB:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
return NDSCart::ROMCommand[3];
|
2021-05-03 12:36:21 +00:00
|
|
|
return 0;
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001AC:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
return NDSCart::ROMCommand[4];
|
2021-05-03 12:36:21 +00:00
|
|
|
return 0;
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001AD:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
return NDSCart::ROMCommand[5];
|
2021-05-03 12:36:21 +00:00
|
|
|
return 0;
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001AE:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
return NDSCart::ROMCommand[6];
|
2021-05-03 12:36:21 +00:00
|
|
|
return 0;
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001AF:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
return NDSCart::ROMCommand[7];
|
|
|
|
return 0;
|
2017-03-30 23:50:01 +00:00
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x040001C2: return SPI::ReadData();
|
|
|
|
|
|
|
|
case 0x04000208: return IME[1];
|
|
|
|
|
2017-01-18 03:03:19 +00:00
|
|
|
case 0x04000240: return GPU::VRAMSTAT;
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04000241: return WRAMCnt;
|
|
|
|
|
2017-01-18 01:20:45 +00:00
|
|
|
case 0x04000300: return PostFlag7;
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
case 0x04000304: return PowerControl7;
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
2017-01-20 00:18:30 +00:00
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
if (addr >= 0x04000400 && addr < 0x04000520)
|
|
|
|
{
|
2017-04-06 17:44:34 +00:00
|
|
|
return SPU::Read8(addr);
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
if ((addr & 0xFFFFF000) != 0x04004000)
|
|
|
|
printf("unknown ARM7 IO read8 %08X %08X\n", addr, ARM7->R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
u16 ARM7IORead16(u32 addr)
|
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2017-01-18 03:03:19 +00:00
|
|
|
case 0x04000004: return GPU::DispStat[1];
|
|
|
|
case 0x04000006: return GPU::VCount;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2017-01-31 16:34:17 +00:00
|
|
|
case 0x040000B8: return DMAs[4]->Cnt & 0xFFFF;
|
|
|
|
case 0x040000BA: return DMAs[4]->Cnt >> 16;
|
|
|
|
case 0x040000C4: return DMAs[5]->Cnt & 0xFFFF;
|
|
|
|
case 0x040000C6: return DMAs[5]->Cnt >> 16;
|
|
|
|
case 0x040000D0: return DMAs[6]->Cnt & 0xFFFF;
|
|
|
|
case 0x040000D2: return DMAs[6]->Cnt >> 16;
|
|
|
|
case 0x040000DC: return DMAs[7]->Cnt & 0xFFFF;
|
|
|
|
case 0x040000DE: return DMAs[7]->Cnt >> 16;
|
|
|
|
|
2017-01-31 02:54:51 +00:00
|
|
|
case 0x04000100: return TimerGetCounter(4);
|
|
|
|
case 0x04000102: return Timers[4].Cnt;
|
|
|
|
case 0x04000104: return TimerGetCounter(5);
|
|
|
|
case 0x04000106: return Timers[5].Cnt;
|
|
|
|
case 0x04000108: return TimerGetCounter(6);
|
|
|
|
case 0x0400010A: return Timers[6].Cnt;
|
|
|
|
case 0x0400010C: return TimerGetCounter(7);
|
|
|
|
case 0x0400010E: return Timers[7].Cnt;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
|
|
|
case 0x04000130: return KeyInput & 0xFFFF;
|
2017-06-04 20:34:31 +00:00
|
|
|
case 0x04000132: return KeyCnt;
|
|
|
|
case 0x04000134: return RCnt;
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04000136: return KeyInput >> 16;
|
|
|
|
|
2017-01-20 00:18:30 +00:00
|
|
|
case 0x04000138: return RTC::Read();
|
2017-01-17 01:29:25 +00:00
|
|
|
|
|
|
|
case 0x04000180: return IPCSync7;
|
|
|
|
case 0x04000184:
|
|
|
|
{
|
|
|
|
u16 val = IPCFIFOCnt7;
|
2020-12-30 22:37:46 +00:00
|
|
|
if (IPCFIFO7.IsEmpty()) val |= 0x0001;
|
|
|
|
else if (IPCFIFO7.IsFull()) val |= 0x0002;
|
|
|
|
if (IPCFIFO9.IsEmpty()) val |= 0x0100;
|
|
|
|
else if (IPCFIFO9.IsFull()) val |= 0x0200;
|
2017-01-17 01:29:25 +00:00
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001A0: if (ExMemCnt[0] & (1<<11)) return NDSCart::SPICnt; return 0;
|
|
|
|
case 0x040001A2: if (ExMemCnt[0] & (1<<11)) return NDSCart::ReadSPIData(); return 0;
|
2017-01-22 19:34:59 +00:00
|
|
|
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001A8:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
return NDSCart::ROMCommand[0] |
|
|
|
|
(NDSCart::ROMCommand[1] << 8);
|
|
|
|
return 0;
|
|
|
|
case 0x040001AA:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
return NDSCart::ROMCommand[2] |
|
|
|
|
(NDSCart::ROMCommand[3] << 8);
|
|
|
|
return 0;
|
|
|
|
case 0x040001AC:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
return NDSCart::ROMCommand[4] |
|
|
|
|
(NDSCart::ROMCommand[5] << 8);
|
|
|
|
return 0;
|
|
|
|
case 0x040001AE:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
return NDSCart::ROMCommand[6] |
|
|
|
|
(NDSCart::ROMCommand[7] << 8);
|
|
|
|
return 0;
|
2017-03-30 23:50:01 +00:00
|
|
|
|
2017-01-31 16:34:17 +00:00
|
|
|
case 0x040001C0: return SPI::Cnt;
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x040001C2: return SPI::ReadData();
|
|
|
|
|
2017-01-22 19:34:59 +00:00
|
|
|
case 0x04000204: return ExMemCnt[1];
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
case 0x04000206:
|
|
|
|
if (!(PowerControl7 & (1<<1))) return 0;
|
|
|
|
return WifiWaitCnt;
|
2018-12-08 21:33:41 +00:00
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04000208: return IME[1];
|
2017-06-23 23:21:09 +00:00
|
|
|
case 0x04000210: return IE[1] & 0xFFFF;
|
|
|
|
case 0x04000212: return IE[1] >> 16;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2017-01-18 01:20:45 +00:00
|
|
|
case 0x04000300: return PostFlag7;
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04000304: return PowerControl7;
|
2017-02-05 16:15:17 +00:00
|
|
|
case 0x04000308: return ARM7BIOSProt;
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
2017-01-20 00:18:30 +00:00
|
|
|
if (addr >= 0x04000400 && addr < 0x04000520)
|
|
|
|
{
|
2017-04-06 17:44:34 +00:00
|
|
|
return SPU::Read16(addr);
|
2017-01-20 00:18:30 +00:00
|
|
|
}
|
|
|
|
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
if ((addr & 0xFFFFF000) != 0x04004000)
|
|
|
|
printf("unknown ARM7 IO read16 %08X %08X\n", addr, ARM7->R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 ARM7IORead32(u32 addr)
|
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2017-01-18 03:03:19 +00:00
|
|
|
case 0x04000004: return GPU::DispStat[1] | (GPU::VCount << 16);
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2017-01-18 00:33:06 +00:00
|
|
|
case 0x040000B0: return DMAs[4]->SrcAddr;
|
|
|
|
case 0x040000B4: return DMAs[4]->DstAddr;
|
|
|
|
case 0x040000B8: return DMAs[4]->Cnt;
|
|
|
|
case 0x040000BC: return DMAs[5]->SrcAddr;
|
|
|
|
case 0x040000C0: return DMAs[5]->DstAddr;
|
|
|
|
case 0x040000C4: return DMAs[5]->Cnt;
|
|
|
|
case 0x040000C8: return DMAs[6]->SrcAddr;
|
|
|
|
case 0x040000CC: return DMAs[6]->DstAddr;
|
|
|
|
case 0x040000D0: return DMAs[6]->Cnt;
|
|
|
|
case 0x040000D4: return DMAs[7]->SrcAddr;
|
|
|
|
case 0x040000D8: return DMAs[7]->DstAddr;
|
|
|
|
case 0x040000DC: return DMAs[7]->Cnt;
|
|
|
|
|
2017-01-31 02:54:51 +00:00
|
|
|
case 0x04000100: return TimerGetCounter(4) | (Timers[4].Cnt << 16);
|
|
|
|
case 0x04000104: return TimerGetCounter(5) | (Timers[5].Cnt << 16);
|
|
|
|
case 0x04000108: return TimerGetCounter(6) | (Timers[6].Cnt << 16);
|
|
|
|
case 0x0400010C: return TimerGetCounter(7) | (Timers[7].Cnt << 16);
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2017-06-04 20:34:31 +00:00
|
|
|
case 0x04000130: return (KeyInput & 0xFFFF) | (KeyCnt << 16);
|
|
|
|
case 0x04000134: return RCnt | (KeyCnt & 0xFFFF0000);
|
|
|
|
case 0x04000138: return RTC::Read();
|
|
|
|
|
2018-04-24 20:31:52 +00:00
|
|
|
case 0x04000180: return IPCSync7;
|
2020-10-25 17:14:40 +00:00
|
|
|
case 0x04000184: return ARM7IORead16(addr);
|
2018-04-24 20:31:52 +00:00
|
|
|
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001A0:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
return NDSCart::SPICnt | (NDSCart::ReadSPIData() << 16);
|
|
|
|
return 0;
|
|
|
|
case 0x040001A4:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
return NDSCart::ROMCnt;
|
|
|
|
return 0;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001A8:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
return NDSCart::ROMCommand[0] |
|
|
|
|
(NDSCart::ROMCommand[1] << 8) |
|
|
|
|
(NDSCart::ROMCommand[2] << 16) |
|
|
|
|
(NDSCart::ROMCommand[3] << 24);
|
|
|
|
return 0;
|
|
|
|
case 0x040001AC:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
return NDSCart::ROMCommand[4] |
|
|
|
|
(NDSCart::ROMCommand[5] << 8) |
|
|
|
|
(NDSCart::ROMCommand[6] << 16) |
|
|
|
|
(NDSCart::ROMCommand[7] << 24);
|
|
|
|
return 0;
|
2017-03-30 23:50:01 +00:00
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x040001C0:
|
2017-01-31 16:34:17 +00:00
|
|
|
return SPI::Cnt | (SPI::ReadData() << 16);
|
2017-01-17 01:29:25 +00:00
|
|
|
|
|
|
|
case 0x04000208: return IME[1];
|
|
|
|
case 0x04000210: return IE[1];
|
|
|
|
case 0x04000214: return IF[1];
|
|
|
|
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
case 0x04000304: return PowerControl7;
|
2017-10-02 02:57:23 +00:00
|
|
|
case 0x04000308: return ARM7BIOSProt;
|
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04100000:
|
|
|
|
if (IPCFIFOCnt7 & 0x8000)
|
|
|
|
{
|
|
|
|
u32 ret;
|
2020-12-30 22:37:46 +00:00
|
|
|
if (IPCFIFO9.IsEmpty())
|
2017-01-17 01:29:25 +00:00
|
|
|
{
|
|
|
|
IPCFIFOCnt7 |= 0x4000;
|
2020-12-30 22:37:46 +00:00
|
|
|
ret = IPCFIFO9.Peek();
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-12-30 22:37:46 +00:00
|
|
|
ret = IPCFIFO9.Read();
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2020-12-30 22:37:46 +00:00
|
|
|
if (IPCFIFO9.IsEmpty() && (IPCFIFOCnt9 & 0x0004))
|
2017-03-02 23:48:26 +00:00
|
|
|
SetIRQ(0, IRQ_IPCSendDone);
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
else
|
2020-12-30 22:37:46 +00:00
|
|
|
return IPCFIFO9.Peek();
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2017-01-22 19:34:59 +00:00
|
|
|
case 0x04100010:
|
2017-01-31 16:34:17 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11)) return NDSCart::ReadROMData();
|
2017-01-22 19:34:59 +00:00
|
|
|
return 0;
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
2017-01-20 00:18:30 +00:00
|
|
|
if (addr >= 0x04000400 && addr < 0x04000520)
|
|
|
|
{
|
2017-04-06 17:44:34 +00:00
|
|
|
return SPU::Read32(addr);
|
2017-01-20 00:18:30 +00:00
|
|
|
}
|
|
|
|
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
if ((addr & 0xFFFFF000) != 0x04004000)
|
|
|
|
printf("unknown ARM7 IO read32 %08X %08X\n", addr, ARM7->R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ARM7IOWrite8(u32 addr, u8 val)
|
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2017-06-04 20:34:31 +00:00
|
|
|
case 0x04000132:
|
|
|
|
KeyCnt = (KeyCnt & 0xFF00) | val;
|
|
|
|
return;
|
|
|
|
case 0x04000133:
|
|
|
|
KeyCnt = (KeyCnt & 0x00FF) | (val << 8);
|
|
|
|
return;
|
|
|
|
case 0x04000134:
|
|
|
|
RCnt = (RCnt & 0xFF00) | val;
|
|
|
|
return;
|
|
|
|
case 0x04000135:
|
|
|
|
RCnt = (RCnt & 0x00FF) | (val << 8);
|
|
|
|
return;
|
|
|
|
|
2017-01-20 00:18:30 +00:00
|
|
|
case 0x04000138: RTC::Write(val, true); return;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2020-10-29 20:09:25 +00:00
|
|
|
case 0x04000188:
|
|
|
|
ARM7IOWrite32(addr, val | (val << 8) | (val << 16) | (val << 24));
|
|
|
|
return;
|
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x040001A0:
|
2017-01-22 19:34:59 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
{
|
2017-01-31 16:34:17 +00:00
|
|
|
NDSCart::WriteSPICnt((NDSCart::SPICnt & 0xFF00) | val);
|
2017-01-22 19:34:59 +00:00
|
|
|
}
|
2017-01-17 01:29:25 +00:00
|
|
|
return;
|
|
|
|
case 0x040001A1:
|
2017-01-22 19:34:59 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11))
|
2017-01-31 16:34:17 +00:00
|
|
|
NDSCart::WriteSPICnt((NDSCart::SPICnt & 0x00FF) | (val << 8));
|
2017-01-17 01:29:25 +00:00
|
|
|
return;
|
2017-01-31 02:54:51 +00:00
|
|
|
case 0x040001A2:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
NDSCart::WriteSPIData(val);
|
2017-01-31 02:54:51 +00:00
|
|
|
return;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001A8: if (ExMemCnt[0] & (1<<11)) NDSCart::ROMCommand[0] = val; return;
|
|
|
|
case 0x040001A9: if (ExMemCnt[0] & (1<<11)) NDSCart::ROMCommand[1] = val; return;
|
|
|
|
case 0x040001AA: if (ExMemCnt[0] & (1<<11)) NDSCart::ROMCommand[2] = val; return;
|
|
|
|
case 0x040001AB: if (ExMemCnt[0] & (1<<11)) NDSCart::ROMCommand[3] = val; return;
|
|
|
|
case 0x040001AC: if (ExMemCnt[0] & (1<<11)) NDSCart::ROMCommand[4] = val; return;
|
|
|
|
case 0x040001AD: if (ExMemCnt[0] & (1<<11)) NDSCart::ROMCommand[5] = val; return;
|
|
|
|
case 0x040001AE: if (ExMemCnt[0] & (1<<11)) NDSCart::ROMCommand[6] = val; return;
|
|
|
|
case 0x040001AF: if (ExMemCnt[0] & (1<<11)) NDSCart::ROMCommand[7] = val; return;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
|
|
|
case 0x040001C2:
|
|
|
|
SPI::WriteData(val);
|
|
|
|
return;
|
|
|
|
|
2019-06-08 20:16:51 +00:00
|
|
|
case 0x04000208: IME[1] = val & 0x1; UpdateIRQ(1); return;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2017-01-18 01:20:45 +00:00
|
|
|
case 0x04000300:
|
|
|
|
if (ARM7->R[15] >= 0x4000)
|
|
|
|
return;
|
|
|
|
if (!(PostFlag7 & 0x01))
|
|
|
|
PostFlag7 = val & 0x01;
|
|
|
|
return;
|
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04000301:
|
2020-08-31 21:37:42 +00:00
|
|
|
val &= 0xC0;
|
2018-12-14 01:36:57 +00:00
|
|
|
if (val == 0x40) printf("!! GBA MODE NOT SUPPORTED\n");
|
|
|
|
else if (val == 0x80) ARM7->Halt(1);
|
|
|
|
else if (val == 0xC0) EnterSleepMode();
|
2017-01-17 01:29:25 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-01-20 00:18:30 +00:00
|
|
|
if (addr >= 0x04000400 && addr < 0x04000520)
|
|
|
|
{
|
2017-04-06 17:44:34 +00:00
|
|
|
SPU::Write8(addr, val);
|
2017-01-20 00:18:30 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-05-23 23:00:33 +00:00
|
|
|
printf("unknown ARM7 IO write8 %08X %02X %08X\n", addr, val, ARM7->R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ARM7IOWrite16(u32 addr, u16 val)
|
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2017-01-18 03:03:19 +00:00
|
|
|
case 0x04000004: GPU::SetDispStat(1, val); return;
|
2017-05-10 00:21:02 +00:00
|
|
|
case 0x04000006: GPU::SetVCount(val); return;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2017-01-31 16:34:17 +00:00
|
|
|
case 0x040000B8: DMAs[4]->WriteCnt((DMAs[4]->Cnt & 0xFFFF0000) | val); return;
|
|
|
|
case 0x040000BA: DMAs[4]->WriteCnt((DMAs[4]->Cnt & 0x0000FFFF) | (val << 16)); return;
|
|
|
|
case 0x040000C4: DMAs[5]->WriteCnt((DMAs[5]->Cnt & 0xFFFF0000) | val); return;
|
|
|
|
case 0x040000C6: DMAs[5]->WriteCnt((DMAs[5]->Cnt & 0x0000FFFF) | (val << 16)); return;
|
|
|
|
case 0x040000D0: DMAs[6]->WriteCnt((DMAs[6]->Cnt & 0xFFFF0000) | val); return;
|
|
|
|
case 0x040000D2: DMAs[6]->WriteCnt((DMAs[6]->Cnt & 0x0000FFFF) | (val << 16)); return;
|
|
|
|
case 0x040000DC: DMAs[7]->WriteCnt((DMAs[7]->Cnt & 0xFFFF0000) | val); return;
|
|
|
|
case 0x040000DE: DMAs[7]->WriteCnt((DMAs[7]->Cnt & 0x0000FFFF) | (val << 16)); return;
|
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04000100: Timers[4].Reload = val; return;
|
|
|
|
case 0x04000102: TimerStart(4, val); return;
|
|
|
|
case 0x04000104: Timers[5].Reload = val; return;
|
|
|
|
case 0x04000106: TimerStart(5, val); return;
|
|
|
|
case 0x04000108: Timers[6].Reload = val; return;
|
|
|
|
case 0x0400010A: TimerStart(6, val); return;
|
|
|
|
case 0x0400010C: Timers[7].Reload = val; return;
|
|
|
|
case 0x0400010E: TimerStart(7, val); return;
|
|
|
|
|
2017-06-04 20:34:31 +00:00
|
|
|
case 0x04000132: KeyCnt = val; return;
|
|
|
|
case 0x04000134: RCnt = val; return;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2017-01-20 00:18:30 +00:00
|
|
|
case 0x04000138: RTC::Write(val, false); return;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
|
|
|
case 0x04000180:
|
|
|
|
IPCSync9 &= 0xFFF0;
|
|
|
|
IPCSync9 |= ((val & 0x0F00) >> 8);
|
|
|
|
IPCSync7 &= 0xB0FF;
|
|
|
|
IPCSync7 |= (val & 0x4F00);
|
|
|
|
if ((val & 0x2000) && (IPCSync9 & 0x4000))
|
|
|
|
{
|
2017-03-02 23:48:26 +00:00
|
|
|
SetIRQ(0, IRQ_IPCSync);
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 0x04000184:
|
|
|
|
if (val & 0x0008)
|
2020-12-30 22:37:46 +00:00
|
|
|
IPCFIFO7.Clear();
|
|
|
|
if ((val & 0x0004) && (!(IPCFIFOCnt7 & 0x0004)) && IPCFIFO7.IsEmpty())
|
2017-03-02 23:48:26 +00:00
|
|
|
SetIRQ(1, IRQ_IPCSendDone);
|
2020-12-30 22:37:46 +00:00
|
|
|
if ((val & 0x0400) && (!(IPCFIFOCnt7 & 0x0400)) && (!IPCFIFO9.IsEmpty()))
|
2017-03-02 23:48:26 +00:00
|
|
|
SetIRQ(1, IRQ_IPCRecv);
|
2017-01-17 01:29:25 +00:00
|
|
|
if (val & 0x4000)
|
|
|
|
IPCFIFOCnt7 &= ~0x4000;
|
2020-12-11 17:06:26 +00:00
|
|
|
IPCFIFOCnt7 = (val & 0x8404) | (IPCFIFOCnt7 & 0x4000);
|
2017-01-17 01:29:25 +00:00
|
|
|
return;
|
|
|
|
|
2020-10-29 20:09:25 +00:00
|
|
|
case 0x04000188:
|
|
|
|
ARM7IOWrite32(addr, val | (val << 16));
|
|
|
|
return;
|
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x040001A0:
|
2017-01-22 19:34:59 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11))
|
2017-01-31 16:34:17 +00:00
|
|
|
NDSCart::WriteSPICnt(val);
|
2017-01-17 01:29:25 +00:00
|
|
|
return;
|
2017-01-31 02:54:51 +00:00
|
|
|
case 0x040001A2:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
NDSCart::WriteSPIData(val & 0xFF);
|
2017-01-31 02:54:51 +00:00
|
|
|
return;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2017-03-30 23:50:01 +00:00
|
|
|
case 0x040001A8:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
{
|
|
|
|
NDSCart::ROMCommand[0] = val & 0xFF;
|
|
|
|
NDSCart::ROMCommand[1] = val >> 8;
|
|
|
|
}
|
2017-03-30 23:50:01 +00:00
|
|
|
return;
|
|
|
|
case 0x040001AA:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
{
|
|
|
|
NDSCart::ROMCommand[2] = val & 0xFF;
|
|
|
|
NDSCart::ROMCommand[3] = val >> 8;
|
|
|
|
}
|
2017-03-30 23:50:01 +00:00
|
|
|
return;
|
|
|
|
case 0x040001AC:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
{
|
|
|
|
NDSCart::ROMCommand[4] = val & 0xFF;
|
|
|
|
NDSCart::ROMCommand[5] = val >> 8;
|
|
|
|
}
|
2017-03-30 23:50:01 +00:00
|
|
|
return;
|
|
|
|
case 0x040001AE:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
{
|
|
|
|
NDSCart::ROMCommand[6] = val & 0xFF;
|
|
|
|
NDSCart::ROMCommand[7] = val >> 8;
|
|
|
|
}
|
2017-03-30 23:50:01 +00:00
|
|
|
return;
|
|
|
|
|
2017-01-22 19:34:59 +00:00
|
|
|
case 0x040001B8: ROMSeed0[12] = val & 0x7F; return;
|
|
|
|
case 0x040001BA: ROMSeed1[12] = val & 0x7F; return;
|
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x040001C0:
|
|
|
|
SPI::WriteCnt(val);
|
|
|
|
return;
|
|
|
|
case 0x040001C2:
|
|
|
|
SPI::WriteData(val & 0xFF);
|
|
|
|
return;
|
|
|
|
|
2017-01-22 19:34:59 +00:00
|
|
|
case 0x04000204:
|
2021-06-26 22:45:12 +00:00
|
|
|
{
|
|
|
|
u16 oldVal = ExMemCnt[1];
|
|
|
|
ExMemCnt[1] = (ExMemCnt[1] & 0xFF80) | (val & 0x007F);
|
|
|
|
if ((ExMemCnt[1] ^ oldVal) & 0xFF)
|
|
|
|
SetGBASlotTimings();
|
|
|
|
return;
|
|
|
|
}
|
2018-12-08 21:33:41 +00:00
|
|
|
case 0x04000206:
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
if (!(PowerControl7 & (1<<1))) return;
|
2018-12-08 21:33:41 +00:00
|
|
|
SetWifiWaitCnt(val);
|
2017-01-22 19:34:59 +00:00
|
|
|
return;
|
|
|
|
|
2019-06-08 20:16:51 +00:00
|
|
|
case 0x04000208: IME[1] = val & 0x1; UpdateIRQ(1); return;
|
|
|
|
case 0x04000210: IE[1] = (IE[1] & 0xFFFF0000) | val; UpdateIRQ(1); return;
|
|
|
|
case 0x04000212: IE[1] = (IE[1] & 0x0000FFFF) | (val << 16); UpdateIRQ(1); return;
|
2017-06-23 23:21:09 +00:00
|
|
|
// TODO: what happens when writing to IF this way??
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2017-01-18 01:20:45 +00:00
|
|
|
case 0x04000300:
|
|
|
|
if (ARM7->R[15] >= 0x4000)
|
|
|
|
return;
|
|
|
|
if (!(PostFlag7 & 0x01))
|
|
|
|
PostFlag7 = val & 0x01;
|
|
|
|
return;
|
|
|
|
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
case 0x04000304:
|
|
|
|
{
|
|
|
|
u16 change = PowerControl7 ^ val;
|
|
|
|
PowerControl7 = val & 0x0003;
|
|
|
|
SPU::SetPowerCnt(val & 0x0001);
|
|
|
|
Wifi::SetPowerCnt(val & 0x0002);
|
|
|
|
if (change & 0x0002) UpdateWifiTimings();
|
|
|
|
}
|
|
|
|
return;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2017-02-05 16:15:17 +00:00
|
|
|
case 0x04000308:
|
|
|
|
if (ARM7BIOSProt == 0)
|
2017-10-02 02:57:23 +00:00
|
|
|
ARM7BIOSProt = val & 0xFFFE;
|
2017-02-05 16:15:17 +00:00
|
|
|
return;
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
2017-01-20 00:18:30 +00:00
|
|
|
if (addr >= 0x04000400 && addr < 0x04000520)
|
|
|
|
{
|
2017-04-06 17:44:34 +00:00
|
|
|
SPU::Write16(addr, val);
|
2017-01-20 00:18:30 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-05-23 23:00:33 +00:00
|
|
|
printf("unknown ARM7 IO write16 %08X %04X %08X\n", addr, val, ARM7->R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ARM7IOWrite32(u32 addr, u32 val)
|
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2019-06-20 11:57:14 +00:00
|
|
|
case 0x04000004:
|
|
|
|
GPU::SetDispStat(1, val & 0xFFFF);
|
|
|
|
GPU::SetVCount(val >> 16);
|
|
|
|
return;
|
|
|
|
|
2017-01-18 00:33:06 +00:00
|
|
|
case 0x040000B0: DMAs[4]->SrcAddr = val; return;
|
|
|
|
case 0x040000B4: DMAs[4]->DstAddr = val; return;
|
|
|
|
case 0x040000B8: DMAs[4]->WriteCnt(val); return;
|
|
|
|
case 0x040000BC: DMAs[5]->SrcAddr = val; return;
|
|
|
|
case 0x040000C0: DMAs[5]->DstAddr = val; return;
|
|
|
|
case 0x040000C4: DMAs[5]->WriteCnt(val); return;
|
|
|
|
case 0x040000C8: DMAs[6]->SrcAddr = val; return;
|
|
|
|
case 0x040000CC: DMAs[6]->DstAddr = val; return;
|
|
|
|
case 0x040000D0: DMAs[6]->WriteCnt(val); return;
|
|
|
|
case 0x040000D4: DMAs[7]->SrcAddr = val; return;
|
|
|
|
case 0x040000D8: DMAs[7]->DstAddr = val; return;
|
2017-01-31 02:54:51 +00:00
|
|
|
case 0x040000DC: DMAs[7]->WriteCnt(val); return;
|
2017-01-18 00:33:06 +00:00
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04000100:
|
|
|
|
Timers[4].Reload = val & 0xFFFF;
|
|
|
|
TimerStart(4, val>>16);
|
|
|
|
return;
|
|
|
|
case 0x04000104:
|
|
|
|
Timers[5].Reload = val & 0xFFFF;
|
|
|
|
TimerStart(5, val>>16);
|
|
|
|
return;
|
|
|
|
case 0x04000108:
|
|
|
|
Timers[6].Reload = val & 0xFFFF;
|
|
|
|
TimerStart(6, val>>16);
|
|
|
|
return;
|
|
|
|
case 0x0400010C:
|
|
|
|
Timers[7].Reload = val & 0xFFFF;
|
|
|
|
TimerStart(7, val>>16);
|
|
|
|
return;
|
|
|
|
|
2017-06-04 20:34:31 +00:00
|
|
|
case 0x04000130: KeyCnt = val >> 16; return;
|
|
|
|
case 0x04000134: RCnt = val & 0xFFFF; return;
|
|
|
|
case 0x04000138: RTC::Write(val & 0xFFFF, false); return;
|
|
|
|
|
2018-04-24 20:31:52 +00:00
|
|
|
case 0x04000180:
|
2020-10-25 17:14:40 +00:00
|
|
|
case 0x04000184:
|
2018-04-24 20:31:52 +00:00
|
|
|
ARM7IOWrite16(addr, val);
|
|
|
|
return;
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04000188:
|
|
|
|
if (IPCFIFOCnt7 & 0x8000)
|
2017-06-18 14:26:59 +00:00
|
|
|
{
|
2020-12-30 22:37:46 +00:00
|
|
|
if (IPCFIFO7.IsFull())
|
2017-01-17 01:29:25 +00:00
|
|
|
IPCFIFOCnt7 |= 0x4000;
|
|
|
|
else
|
|
|
|
{
|
2020-12-30 22:37:46 +00:00
|
|
|
bool wasempty = IPCFIFO7.IsEmpty();
|
|
|
|
IPCFIFO7.Write(val);
|
2017-01-17 04:29:38 +00:00
|
|
|
if ((IPCFIFOCnt9 & 0x0400) && wasempty)
|
2017-03-02 23:48:26 +00:00
|
|
|
SetIRQ(0, IRQ_IPCRecv);
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 0x040001A0:
|
2017-01-22 19:34:59 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
{
|
2017-01-31 16:34:17 +00:00
|
|
|
NDSCart::WriteSPICnt(val & 0xFFFF);
|
|
|
|
NDSCart::WriteSPIData((val >> 16) & 0xFF);
|
2017-01-22 19:34:59 +00:00
|
|
|
}
|
2017-01-17 01:29:25 +00:00
|
|
|
return;
|
|
|
|
case 0x040001A4:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
NDSCart::WriteROMCnt(val);
|
2017-01-17 01:29:25 +00:00
|
|
|
return;
|
|
|
|
|
2017-03-30 23:50:01 +00:00
|
|
|
case 0x040001A8:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
{
|
|
|
|
NDSCart::ROMCommand[0] = val & 0xFF;
|
|
|
|
NDSCart::ROMCommand[1] = (val >> 8) & 0xFF;
|
|
|
|
NDSCart::ROMCommand[2] = (val >> 16) & 0xFF;
|
|
|
|
NDSCart::ROMCommand[3] = val >> 24;
|
|
|
|
}
|
2017-03-30 23:50:01 +00:00
|
|
|
return;
|
|
|
|
case 0x040001AC:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
{
|
|
|
|
NDSCart::ROMCommand[4] = val & 0xFF;
|
|
|
|
NDSCart::ROMCommand[5] = (val >> 8) & 0xFF;
|
|
|
|
NDSCart::ROMCommand[6] = (val >> 16) & 0xFF;
|
|
|
|
NDSCart::ROMCommand[7] = val >> 24;
|
|
|
|
}
|
2017-03-30 23:50:01 +00:00
|
|
|
return;
|
|
|
|
|
2017-01-22 19:34:59 +00:00
|
|
|
case 0x040001B0: *(u32*)&ROMSeed0[8] = val; return;
|
|
|
|
case 0x040001B4: *(u32*)&ROMSeed1[8] = val; return;
|
|
|
|
|
2020-10-25 17:14:40 +00:00
|
|
|
case 0x040001C0:
|
|
|
|
SPI::WriteCnt(val & 0xFFFF);
|
|
|
|
SPI::WriteData((val >> 16) & 0xFF);
|
|
|
|
return;
|
|
|
|
|
2019-06-08 20:16:51 +00:00
|
|
|
case 0x04000208: IME[1] = val & 0x1; UpdateIRQ(1); return;
|
|
|
|
case 0x04000210: IE[1] = val; UpdateIRQ(1); return;
|
|
|
|
case 0x04000214: IF[1] &= ~val; UpdateIRQ(1); return;
|
2017-10-02 02:57:23 +00:00
|
|
|
|
merge local_wifi (#1516)
* attempt at betterer wifi
* add preliminary sync mechanism
* fix gaps in wifi implementation
* move local-MP comm to its own module instead of cramping Platform.cpp
* remove some stupid cruft
* as you wish, Sorer
(starting work on shared-memory system)
* shared-memory IPC that actually works (albeit Windows-only for now)
* shut up logging from NULL writes on ARM7 (ffs Nintendo learn to code)
* get this somewhat good
* leave client sync mode when host deauths. makes download play actually work.
* start implementing MP-comm error handling
* * add MP-reply error counters
* feeble attempt at fixing slowdown/desync/etc problems
* somewhat better exchange/sync method
* * when entering power-saving mode, be sure to finish transferring the current frame first
* fix misc bug due to old cruft leftover
makes for a more stable connection
* remove a bunch of cruft
* set wifi time interval to 34 cycles instead of 33. games seem sensitive to the general timing of wifi vs the rest of the system, and this seems to make things run better, atleast until I rewrite this to use a proper scheduler.
* more graceful handling of disconnects
* deal with FIFO overflow more gracefully
* BAHAHAHAHAHAHAHAHHHH
THE SNEAKY BASTARDS
so, when the DS receives a beacon with the right BSSID
that beacon's timestamp is copied to USCOUNTER
* attempt at making the connection process smoother for weird games
* * begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
* implement the shitty timers
* add the RF wakeup thing
* begin work on receiving frames. for now it can just receive melonAP beacons, but hey, it's a start.
* add enough TX functionality that online wifi is a possibility again.
* there are problems with this scheduler thing. committing it anyway
* kind of a rollback... we're gonna work out a compromise on this, I guess
* don't transmit shit if RXCNT.bit15 isn't set
* move RX-finish to its own function. more accurate filtering. implement RXFILTER.
* remove some cruft
* fix some of the shittiness when trying to connect more than two players
* fix some more shittiness
* fix more wifi shittiness (mainly don't try to receive shit while sending a frame)
* run wifi every 8µs. improves performance.
* fix IRQ14/IRQ15
* make this work under Linux
* Make it work on macOS, for now using a custom sem_timedwait
implementation.
If anyone knows anything about mach ports and have an idea for how to
make this work using mach IPC, please do let me know.
* 25ms seems like a good timeout
* begin work on proper multiplayer UI shito.
for now, determine a global instance ID, and derivate the system MAC from it. remove 'randomize MAC' option.
* finish removing RandomizeMAC
* lay groundwork for instance-unique config
* work some on the UI... make it not labelled Fart
* more UI work: make it explicit that some things are instance-unique
* separate firmware files for multiplayer instances
* make instances save to different save files, too
* more UI work, make things somewhat less shitty
* lay base for the multiplayer settings dialog
* actually hook up most of that dialog
* actually implement the fun audio settings
* ensure all the wifi shit is properly savestated and reset. properly update timings for the wifi region when wifi is disabled.
* add more fun labels
* * ignore WEP frames if WEP is off
* implement RX_LEN_CROP
* fake enough of WEP processing to make Inazuma Eleven work
* * do not copy more ROM banner data than actually needed
* avoid trying to read out of bounds if the banner offset is bad
* Fix oversight with the preferences action causing the build to fail on macOS
Co-authored-by: Nadia Holmquist Pedersen <nadia@nhp.sh>
2022-09-22 18:32:27 +00:00
|
|
|
case 0x04000304:
|
|
|
|
{
|
|
|
|
u16 change = PowerControl7 ^ val;
|
|
|
|
PowerControl7 = val & 0x0003;
|
|
|
|
SPU::SetPowerCnt(val & 0x0001);
|
|
|
|
Wifi::SetPowerCnt(val & 0x0002);
|
|
|
|
if (change & 0x0002) UpdateWifiTimings();
|
|
|
|
}
|
|
|
|
return;
|
2019-06-20 11:57:14 +00:00
|
|
|
|
2017-10-02 02:57:23 +00:00
|
|
|
case 0x04000308:
|
|
|
|
if (ARM7BIOSProt == 0)
|
|
|
|
ARM7BIOSProt = val & 0xFFFE;
|
|
|
|
return;
|
2021-04-24 22:48:02 +00:00
|
|
|
|
|
|
|
case 0x04100010:
|
|
|
|
if (ExMemCnt[0] & (1<<11)) NDSCart::WriteROMData(val);
|
|
|
|
return;
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
2017-01-20 00:18:30 +00:00
|
|
|
if (addr >= 0x04000400 && addr < 0x04000520)
|
|
|
|
{
|
2017-04-06 17:44:34 +00:00
|
|
|
SPU::Write32(addr, val);
|
2017-01-20 00:18:30 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-05-23 23:00:33 +00:00
|
|
|
printf("unknown ARM7 IO write32 %08X %08X %08X\n", addr, val, ARM7->R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
2016-05-16 15:48:40 +00:00
|
|
|
}
|